>)/i,/^(?:.*\\[\\[fork\\]\\])/i,/^(?:.*\\[\\[join\\]\\])/i,/^(?:[\"])/i,/^(?:\\s*as\\s+)/i,/^(?:[^\\n\\{]*)/i,/^(?:[\"])/i,/^(?:[^\"]*)/i,/^(?:[^\\n\\s\\{]+)/i,/^(?:\\n)/i,/^(?:\\{)/i,/^(?:\\})/i,/^(?:[\\n])/i,/^(?:note\\s+)/i,/^(?:left of\\b)/i,/^(?:right of\\b)/i,/^(?:\")/i,/^(?:\\s*as\\s*)/i,/^(?:[\"])/i,/^(?:[^\"]*)/i,/^(?:[^\\n]*)/i,/^(?:\\s*[^:\\n\\s\\-]+)/i,/^(?:\\s*:[^:\\n;]+)/i,/^(?:\\s*[^:;]+end note\\b)/i,/^(?:stateDiagram\\s+)/i,/^(?:stateDiagram-v2\\s+)/i,/^(?:hide empty description\\b)/i,/^(?:\\[\\*\\])/i,/^(?:[^:\\n\\s\\-\\{]+)/i,/^(?:\\s*:[^:\\n;]+)/i,/^(?:-->)/i,/^(?:--)/i,/^(?:$)/i,/^(?:.)/i],\nconditions: {\"LINE\":{\"rules\":[2,3],\"inclusive\":false},\"struct\":{\"rules\":[2,3,8,21,22,23,37,38,39,40,41],\"inclusive\":false},\"FLOATING_NOTE_ID\":{\"rules\":[30],\"inclusive\":false},\"FLOATING_NOTE\":{\"rules\":[27,28,29],\"inclusive\":false},\"NOTE_TEXT\":{\"rules\":[32,33],\"inclusive\":false},\"NOTE_ID\":{\"rules\":[31],\"inclusive\":false},\"NOTE\":{\"rules\":[24,25,26],\"inclusive\":false},\"SCALE\":{\"rules\":[6,7],\"inclusive\":false},\"ALIAS\":{\"rules\":[],\"inclusive\":false},\"STATE_ID\":{\"rules\":[15],\"inclusive\":false},\"STATE_STRING\":{\"rules\":[16,17],\"inclusive\":false},\"FORK_STATE\":{\"rules\":[],\"inclusive\":false},\"STATE\":{\"rules\":[2,3,9,10,11,12,13,14,18,19,20],\"inclusive\":false},\"ID\":{\"rules\":[2,3],\"inclusive\":false},\"INITIAL\":{\"rules\":[0,1,3,4,5,8,20,23,34,35,36,37,38,39,40,42,43],\"inclusive\":true}}\n});\nreturn lexer;\n})();\nparser.lexer = lexer;\nfunction Parser () {\n this.yy = {};\n}\nParser.prototype = parser;parser.Parser = Parser;\nreturn new Parser;\n})();\n\n\nif (typeof require !== 'undefined' && typeof exports !== 'undefined') {\nexports.parser = parser;\nexports.Parser = parser.Parser;\nexports.parse = function () { return parser.parse.apply(parser, arguments); };\nexports.main = function commonjsMain (args) {\n if (!args[1]) {\n console.log('Usage: '+args[0]+' FILE');\n process.exit(1);\n }\n var source = require('fs').readFileSync(require('path').normalize(args[1]), \"utf8\");\n return exports.parser.parse(source);\n};\nif (typeof module !== 'undefined' && require.main === module) {\n exports.main(process.argv.slice(1));\n}\n}","import { line, curveBasis } from 'd3';\nimport idCache from './id-cache.js';\nimport stateDb from './stateDb';\nimport utils from '../../utils';\nimport common from '../common/common';\nimport { getConfig } from '../../config';\nimport { logger } from '../../logger';\n\n// let conf;\n\n/**\n * Draws a start state as a black circle\n */\nexport const drawStartState = g =>\n g\n .append('circle')\n .style('stroke', 'black')\n .style('fill', 'black')\n .attr('r', getConfig().state.sizeUnit)\n .attr('cx', getConfig().state.padding + getConfig().state.sizeUnit)\n .attr('cy', getConfig().state.padding + getConfig().state.sizeUnit);\n\n/**\n * Draws a start state as a black circle\n */\nexport const drawDivider = g =>\n g\n .append('line')\n .style('stroke', 'grey')\n .style('stroke-dasharray', '3')\n .attr('x1', getConfig().state.textHeight)\n .attr('class', 'divider')\n .attr('x2', getConfig().state.textHeight * 2)\n .attr('y1', 0)\n .attr('y2', 0);\n\n/**\n * Draws a an end state as a black circle\n */\nexport const drawSimpleState = (g, stateDef) => {\n const state = g\n .append('text')\n .attr('x', 2 * getConfig().state.padding)\n .attr('y', getConfig().state.textHeight + 2 * getConfig().state.padding)\n .attr('font-size', getConfig().state.fontSize)\n .attr('class', 'state-title')\n .text(stateDef.id);\n\n const classBox = state.node().getBBox();\n g.insert('rect', ':first-child')\n .attr('x', getConfig().state.padding)\n .attr('y', getConfig().state.padding)\n .attr('width', classBox.width + 2 * getConfig().state.padding)\n .attr('height', classBox.height + 2 * getConfig().state.padding)\n .attr('rx', getConfig().state.radius);\n\n return state;\n};\n\n/**\n * Draws a state with descriptions\n * @param {*} g\n * @param {*} stateDef\n */\nexport const drawDescrState = (g, stateDef) => {\n const addTspan = function(textEl, txt, isFirst) {\n const tSpan = textEl\n .append('tspan')\n .attr('x', 2 * getConfig().state.padding)\n .text(txt);\n if (!isFirst) {\n tSpan.attr('dy', getConfig().state.textHeight);\n }\n };\n const title = g\n .append('text')\n .attr('x', 2 * getConfig().state.padding)\n .attr('y', getConfig().state.textHeight + 1.3 * getConfig().state.padding)\n .attr('font-size', getConfig().state.fontSize)\n .attr('class', 'state-title')\n .text(stateDef.descriptions[0]);\n\n const titleBox = title.node().getBBox();\n const titleHeight = titleBox.height;\n\n const description = g\n .append('text') // text label for the x axis\n .attr('x', getConfig().state.padding)\n .attr(\n 'y',\n titleHeight +\n getConfig().state.padding * 0.4 +\n getConfig().state.dividerMargin +\n getConfig().state.textHeight\n )\n .attr('class', 'state-description');\n\n let isFirst = true;\n let isSecond = true;\n stateDef.descriptions.forEach(function(descr) {\n if (!isFirst) {\n addTspan(description, descr, isSecond);\n isSecond = false;\n }\n isFirst = false;\n });\n\n const descrLine = g\n .append('line') // text label for the x axis\n .attr('x1', getConfig().state.padding)\n .attr('y1', getConfig().state.padding + titleHeight + getConfig().state.dividerMargin / 2)\n .attr('y2', getConfig().state.padding + titleHeight + getConfig().state.dividerMargin / 2)\n .attr('class', 'descr-divider');\n const descrBox = description.node().getBBox();\n const width = Math.max(descrBox.width, titleBox.width);\n\n descrLine.attr('x2', width + 3 * getConfig().state.padding);\n // const classBox = title.node().getBBox();\n\n g.insert('rect', ':first-child')\n .attr('x', getConfig().state.padding)\n .attr('y', getConfig().state.padding)\n .attr('width', width + 2 * getConfig().state.padding)\n .attr('height', descrBox.height + titleHeight + 2 * getConfig().state.padding)\n .attr('rx', getConfig().state.radius);\n\n return g;\n};\n\n/**\n * Adds the creates a box around the existing content and adds a\n * panel for the id on top of the content.\n */\n/**\n * Function that creates an title row and a frame around a substate for a composit state diagram.\n * The function returns a new d3 svg object with updated width and height properties;\n * @param {*} g The d3 svg object for the substate to framed\n * @param {*} stateDef The info about the\n */\nexport const addTitleAndBox = (g, stateDef, altBkg) => {\n const pad = getConfig().state.padding;\n const dblPad = 2 * getConfig().state.padding;\n const orgBox = g.node().getBBox();\n const orgWidth = orgBox.width;\n const orgX = orgBox.x;\n\n const title = g\n .append('text')\n .attr('x', 0)\n .attr('y', getConfig().state.titleShift)\n .attr('font-size', getConfig().state.fontSize)\n .attr('class', 'state-title')\n .text(stateDef.id);\n\n const titleBox = title.node().getBBox();\n const titleWidth = titleBox.width + dblPad;\n let width = Math.max(titleWidth, orgWidth); // + dblPad;\n if (width === orgWidth) {\n width = width + dblPad;\n }\n let startX;\n // const lineY = 1 - getConfig().state.textHeight;\n // const descrLine = g\n // .append('line') // text label for the x axis\n // .attr('x1', 0)\n // .attr('y1', lineY)\n // .attr('y2', lineY)\n // .attr('class', 'descr-divider');\n\n const graphBox = g.node().getBBox();\n // console.warn(width / 2, titleWidth / 2, getConfig().state.padding, orgBox);\n // descrLine.attr('x2', graphBox.width + getConfig().state.padding);\n\n if (stateDef.doc) {\n // cnsole.warn(\n // stateDef.id,\n // 'orgX: ',\n // orgX,\n // 'width: ',\n // width,\n // 'titleWidth: ',\n // titleWidth,\n // 'orgWidth: ',\n // orgWidth,\n // 'width',\n // width\n // );\n }\n\n startX = orgX - pad;\n if (titleWidth > orgWidth) {\n startX = (orgWidth - width) / 2 + pad;\n }\n if (Math.abs(orgX - graphBox.x) < pad) {\n if (titleWidth > orgWidth) {\n startX = orgX - (titleWidth - orgWidth) / 2;\n }\n }\n\n const lineY = 1 - getConfig().state.textHeight;\n // White color\n g.insert('rect', ':first-child')\n .attr('x', startX)\n .attr('y', lineY)\n .attr('class', altBkg ? 'alt-composit' : 'composit')\n .attr('width', width)\n .attr(\n 'height',\n graphBox.height + getConfig().state.textHeight + getConfig().state.titleShift + 1\n )\n .attr('rx', '0');\n\n title.attr('x', startX + pad);\n if (titleWidth <= orgWidth) title.attr('x', orgX + (width - dblPad) / 2 - titleWidth / 2 + pad);\n\n // Title background\n g.insert('rect', ':first-child')\n .attr('x', startX)\n .attr(\n 'y',\n getConfig().state.titleShift - getConfig().state.textHeight - getConfig().state.padding\n )\n .attr('width', width)\n // Just needs to be higher then the descr line, will be clipped by the white color box\n .attr('height', getConfig().state.textHeight * 3)\n .attr('rx', getConfig().state.radius);\n\n // Full background\n g.insert('rect', ':first-child')\n .attr('x', startX)\n .attr(\n 'y',\n getConfig().state.titleShift - getConfig().state.textHeight - getConfig().state.padding\n )\n .attr('width', width)\n .attr('height', graphBox.height + 3 + 2 * getConfig().state.textHeight)\n .attr('rx', getConfig().state.radius);\n\n return g;\n};\n\nconst drawEndState = g => {\n g.append('circle')\n .style('stroke', 'black')\n .style('fill', 'white')\n .attr('r', getConfig().state.sizeUnit + getConfig().state.miniPadding)\n .attr(\n 'cx',\n getConfig().state.padding + getConfig().state.sizeUnit + getConfig().state.miniPadding\n )\n .attr(\n 'cy',\n getConfig().state.padding + getConfig().state.sizeUnit + getConfig().state.miniPadding\n );\n\n return g\n .append('circle')\n .style('stroke', 'black')\n .style('fill', 'black')\n .attr('r', getConfig().state.sizeUnit)\n .attr('cx', getConfig().state.padding + getConfig().state.sizeUnit + 2)\n .attr('cy', getConfig().state.padding + getConfig().state.sizeUnit + 2);\n};\nconst drawForkJoinState = (g, stateDef) => {\n let width = getConfig().state.forkWidth;\n let height = getConfig().state.forkHeight;\n\n if (stateDef.parentId) {\n let tmp = width;\n width = height;\n height = tmp;\n }\n return g\n .append('rect')\n .style('stroke', 'black')\n .style('fill', 'black')\n .attr('width', width)\n .attr('height', height)\n .attr('x', getConfig().state.padding)\n .attr('y', getConfig().state.padding);\n};\n\nexport const drawText = function(elem, textData) {\n // Remove and ignore br:s\n const nText = textData.text.replace(common.lineBreakRegex, ' ');\n\n const textElem = elem.append('text');\n textElem.attr('x', textData.x);\n textElem.attr('y', textData.y);\n textElem.style('text-anchor', textData.anchor);\n textElem.attr('fill', textData.fill);\n if (typeof textData.class !== 'undefined') {\n textElem.attr('class', textData.class);\n }\n\n const span = textElem.append('tspan');\n span.attr('x', textData.x + textData.textMargin * 2);\n span.attr('fill', textData.fill);\n span.text(nText);\n\n return textElem;\n};\n\nconst _drawLongText = (_text, x, y, g) => {\n let textHeight = 0;\n\n const textElem = g.append('text');\n textElem.style('text-anchor', 'start');\n textElem.attr('class', 'noteText');\n\n let text = _text.replace(/\\r\\n/g, '
');\n text = text.replace(/\\n/g, '
');\n const lines = text.split(common.lineBreakRegex);\n\n let tHeight = 1.25 * getConfig().state.noteMargin;\n for (const line of lines) {\n const txt = line.trim();\n\n if (txt.length > 0) {\n const span = textElem.append('tspan');\n span.text(txt);\n if (tHeight === 0) {\n const textBounds = span.node().getBBox();\n tHeight += textBounds.height;\n }\n // console.warn('textBounds', textBounds);\n textHeight += tHeight;\n span.attr('x', x + getConfig().state.noteMargin);\n span.attr('y', y + textHeight + 1.25 * getConfig().state.noteMargin);\n }\n }\n return { textWidth: textElem.node().getBBox().width, textHeight };\n};\n\n/**\n * Draws a note to the diagram\n * @param text - The text of the given note.\n * @param g - The element the note is attached to.\n */\n\nexport const drawNote = (text, g) => {\n g.attr('class', 'state-note');\n const note = g\n .append('rect')\n .attr('x', 0)\n .attr('y', getConfig().state.padding);\n const rectElem = g.append('g');\n\n const { textWidth, textHeight } = _drawLongText(text, 0, 0, rectElem);\n note.attr('height', textHeight + 2 * getConfig().state.noteMargin);\n note.attr('width', textWidth + getConfig().state.noteMargin * 2);\n\n return note;\n};\n\n/**\n * Starting point for drawing a state. The function finds out the specifics\n * about the state and renders with approprtiate function.\n * @param {*} elem\n * @param {*} stateDef\n */\n\nexport const drawState = function(elem, stateDef) {\n const id = stateDef.id;\n const stateInfo = {\n id: id,\n label: stateDef.id,\n width: 0,\n height: 0\n };\n\n const g = elem\n .append('g')\n .attr('id', id)\n .attr('class', 'stateGroup');\n\n if (stateDef.type === 'start') drawStartState(g);\n if (stateDef.type === 'end') drawEndState(g);\n if (stateDef.type === 'fork' || stateDef.type === 'join') drawForkJoinState(g, stateDef);\n if (stateDef.type === 'note') drawNote(stateDef.note.text, g);\n if (stateDef.type === 'divider') drawDivider(g);\n if (stateDef.type === 'default' && stateDef.descriptions.length === 0)\n drawSimpleState(g, stateDef);\n if (stateDef.type === 'default' && stateDef.descriptions.length > 0) drawDescrState(g, stateDef);\n\n const stateBox = g.node().getBBox();\n stateInfo.width = stateBox.width + 2 * getConfig().state.padding;\n stateInfo.height = stateBox.height + 2 * getConfig().state.padding;\n\n idCache.set(id, stateInfo);\n // stateCnt++;\n return stateInfo;\n};\n\nlet edgeCount = 0;\nexport const drawEdge = function(elem, path, relation) {\n const getRelationType = function(type) {\n switch (type) {\n case stateDb.relationType.AGGREGATION:\n return 'aggregation';\n case stateDb.relationType.EXTENSION:\n return 'extension';\n case stateDb.relationType.COMPOSITION:\n return 'composition';\n case stateDb.relationType.DEPENDENCY:\n return 'dependency';\n }\n };\n\n path.points = path.points.filter(p => !Number.isNaN(p.y));\n\n // The data for our line\n const lineData = path.points;\n\n // This is the accessor function we talked about above\n const lineFunction = line()\n .x(function(d) {\n return d.x;\n })\n .y(function(d) {\n return d.y;\n })\n .curve(curveBasis);\n\n const svgPath = elem\n .append('path')\n .attr('d', lineFunction(lineData))\n .attr('id', 'edge' + edgeCount)\n .attr('class', 'transition');\n let url = '';\n if (getConfig().state.arrowMarkerAbsolute) {\n url =\n window.location.protocol +\n '//' +\n window.location.host +\n window.location.pathname +\n window.location.search;\n url = url.replace(/\\(/g, '\\\\(');\n url = url.replace(/\\)/g, '\\\\)');\n }\n\n svgPath.attr(\n 'marker-end',\n 'url(' + url + '#' + getRelationType(stateDb.relationType.DEPENDENCY) + 'End' + ')'\n );\n\n if (typeof relation.title !== 'undefined') {\n const label = elem.append('g').attr('class', 'stateLabel');\n\n const { x, y } = utils.calcLabelPosition(path.points);\n\n const rows = common.getRows(relation.title);\n\n // console.warn(rows);\n\n let titleHeight = 0;\n const titleRows = [];\n let maxWidth = 0;\n let minX = 0;\n\n for (let i = 0; i <= rows.length; i++) {\n const title = label\n .append('text')\n .attr('text-anchor', 'middle')\n .text(rows[i])\n .attr('x', x)\n .attr('y', y + titleHeight);\n\n const boundstmp = title.node().getBBox();\n maxWidth = Math.max(maxWidth, boundstmp.width);\n minX = Math.min(minX, boundstmp.x);\n\n logger.info(boundstmp.x, x, y + titleHeight);\n\n if (titleHeight === 0) {\n const titleBox = title.node().getBBox();\n titleHeight = titleBox.height;\n logger.info('Title height', titleHeight, y);\n }\n titleRows.push(title);\n }\n\n let boxHeight = titleHeight * rows.length;\n if (rows.length > 1) {\n const heightAdj = (rows.length - 1) * titleHeight * 0.5;\n\n titleRows.forEach((title, i) => title.attr('y', y + i * titleHeight - heightAdj));\n boxHeight = titleHeight * rows.length;\n }\n\n const bounds = label.node().getBBox();\n\n label\n .insert('rect', ':first-child')\n .attr('class', 'box')\n .attr('x', x - maxWidth / 2 - getConfig().state.padding / 2)\n .attr('y', y - boxHeight / 2 - getConfig().state.padding / 2 - 3.5)\n .attr('width', maxWidth + getConfig().state.padding)\n .attr('height', boxHeight + getConfig().state.padding);\n\n logger.info(bounds);\n\n //label.attr('transform', '0 -' + (bounds.y / 2));\n\n // Debug points\n // path.points.forEach(point => {\n // g.append('circle')\n // .style('stroke', 'red')\n // .style('fill', 'red')\n // .attr('r', 1)\n // .attr('cx', point.x)\n // .attr('cy', point.y);\n // });\n // g.append('circle')\n // .style('stroke', 'blue')\n // .style('fill', 'blue')\n // .attr('r', 1)\n // .attr('cx', x)\n // .attr('cy', y);\n }\n\n edgeCount++;\n};\n","import { logger } from '../../logger';\nimport { generateId } from '../../utils';\n\nconst clone = o => JSON.parse(JSON.stringify(o));\n\nlet rootDoc = [];\nconst setRootDoc = o => {\n logger.info('Setting root doc', o);\n // rootDoc = { id: 'root', doc: o };\n rootDoc = o;\n};\n\nconst getRootDoc = () => rootDoc;\n\nconst docTranslator = (parent, node, first) => {\n if (node.stmt === 'relation') {\n docTranslator(parent, node.state1, true);\n docTranslator(parent, node.state2, false);\n } else {\n if (node.stmt === 'state') {\n if (node.id === '[*]') {\n node.id = first ? parent.id + '_start' : parent.id + '_end';\n node.start = first;\n }\n }\n\n if (node.doc) {\n const doc = [];\n // Check for concurrency\n let i = 0;\n let currentDoc = [];\n for (i = 0; i < node.doc.length; i++) {\n if (node.doc[i].type === 'divider') {\n // debugger;\n const newNode = clone(node.doc[i]);\n newNode.doc = clone(currentDoc);\n doc.push(newNode);\n currentDoc = [];\n } else {\n currentDoc.push(node.doc[i]);\n }\n }\n\n // If any divider was encountered\n if (doc.length > 0 && currentDoc.length > 0) {\n const newNode = {\n stmt: 'state',\n id: generateId(),\n type: 'divider',\n doc: clone(currentDoc)\n };\n doc.push(clone(newNode));\n node.doc = doc;\n }\n\n node.doc.forEach(docNode => docTranslator(node, docNode, true));\n }\n }\n};\nconst getRootDocV2 = () => {\n docTranslator({ id: 'root' }, { id: 'root', doc: rootDoc }, true);\n return { id: 'root', doc: rootDoc };\n};\n\nconst extract = _doc => {\n // const res = { states: [], relations: [] };\n let doc;\n if (_doc.doc) {\n doc = _doc.doc;\n } else {\n doc = _doc;\n }\n // let doc = root.doc;\n // if (!doc) {\n // doc = root;\n // }\n logger.info(doc);\n clear();\n\n logger.info('Extract', doc);\n\n doc.forEach(item => {\n if (item.stmt === 'state') {\n addState(item.id, item.type, item.doc, item.description, item.note);\n }\n if (item.stmt === 'relation') {\n addRelation(item.state1.id, item.state2.id, item.description);\n }\n });\n};\n\nconst newDoc = () => {\n return {\n relations: [],\n states: {},\n documents: {}\n };\n};\n\nlet documents = {\n root: newDoc()\n};\n\nlet currentDocument = documents.root;\n\nlet startCnt = 0;\nlet endCnt = 0; // eslint-disable-line\n// let stateCnt = 0;\n\n/**\n * Function called by parser when a node definition has been found.\n * @param id\n * @param text\n * @param type\n * @param style\n */\nexport const addState = function(id, type, doc, descr, note) {\n if (typeof currentDocument.states[id] === 'undefined') {\n currentDocument.states[id] = {\n id: id,\n descriptions: [],\n type,\n doc,\n note\n };\n } else {\n if (!currentDocument.states[id].doc) {\n currentDocument.states[id].doc = doc;\n }\n if (!currentDocument.states[id].type) {\n currentDocument.states[id].type = type;\n }\n }\n if (descr) {\n logger.info('Adding state ', id, descr);\n if (typeof descr === 'string') addDescription(id, descr.trim());\n\n if (typeof descr === 'object') {\n descr.forEach(des => addDescription(id, des.trim()));\n }\n }\n\n if (note) currentDocument.states[id].note = note;\n};\n\nexport const clear = function() {\n documents = {\n root: newDoc()\n };\n currentDocument = documents.root;\n\n currentDocument = documents.root;\n\n startCnt = 0;\n endCnt = 0; // eslint-disable-line\n classes = [];\n};\n\nexport const getState = function(id) {\n return currentDocument.states[id];\n};\n\nexport const getStates = function() {\n return currentDocument.states;\n};\nexport const logDocuments = function() {\n logger.info('Documents = ', documents);\n};\nexport const getRelations = function() {\n return currentDocument.relations;\n};\n\nexport const addRelation = function(_id1, _id2, title) {\n let id1 = _id1;\n let id2 = _id2;\n let type1 = 'default';\n let type2 = 'default';\n if (_id1 === '[*]') {\n startCnt++;\n id1 = 'start' + startCnt;\n type1 = 'start';\n }\n if (_id2 === '[*]') {\n endCnt++;\n id2 = 'end' + startCnt;\n type2 = 'end';\n }\n addState(id1, type1);\n addState(id2, type2);\n currentDocument.relations.push({ id1, id2, title });\n};\n\nconst addDescription = function(id, _descr) {\n const theState = currentDocument.states[id];\n let descr = _descr;\n if (descr[0] === ':') {\n descr = descr.substr(1).trim();\n }\n\n theState.descriptions.push(descr);\n};\n\nexport const cleanupLabel = function(label) {\n if (label.substring(0, 1) === ':') {\n return label.substr(2).trim();\n } else {\n return label.trim();\n }\n};\n\nexport const lineType = {\n LINE: 0,\n DOTTED_LINE: 1\n};\n\nlet dividerCnt = 0;\nconst getDividerId = () => {\n dividerCnt++;\n return 'divider-id-' + dividerCnt;\n};\n\nlet classes = [];\n\nconst getClasses = () => classes;\n\nconst getDirection = () => 'TB';\n\nexport const relationType = {\n AGGREGATION: 0,\n EXTENSION: 1,\n COMPOSITION: 2,\n DEPENDENCY: 3\n};\n\nconst trimColon = str => (str && str[0] === ':' ? str.substr(1).trim() : str.trim());\n\nexport default {\n addState,\n clear,\n getState,\n getStates,\n getRelations,\n getClasses,\n getDirection,\n addRelation,\n getDividerId,\n // addDescription,\n cleanupLabel,\n lineType,\n relationType,\n logDocuments,\n getRootDoc,\n setRootDoc,\n getRootDocV2,\n extract,\n trimColon\n};\n","import graphlib from 'graphlib';\nimport { select } from 'd3';\nimport stateDb from './stateDb';\nimport state from './parser/stateDiagram';\nimport { getConfig } from '../../config';\n\nimport { render } from '../../dagre-wrapper/index.js';\nimport { logger } from '../../logger';\n\nconst conf = {};\nexport const setConf = function(cnf) {\n const keys = Object.keys(cnf);\n for (let i = 0; i < keys.length; i++) {\n conf[keys[i]] = cnf[keys[i]];\n }\n};\n\nlet nodeDb = {};\n\n/**\n * Returns the all the styles from classDef statements in the graph definition.\n * @returns {object} classDef styles\n */\nexport const getClasses = function(text) {\n logger.trace('Extracting classes');\n stateDb.clear();\n const parser = state.parser;\n parser.yy = stateDb;\n\n // Parse the graph definition\n parser.parse(text);\n return stateDb.getClasses();\n};\n\nconst setupNode = (g, parent, node, altFlag) => {\n // Add the node\n if (node.id !== 'root') {\n let shape = 'rect';\n if (node.start === true) {\n shape = 'start';\n }\n if (node.start === false) {\n shape = 'end';\n }\n if (node.type !== 'default') {\n shape = node.type;\n }\n\n if (!nodeDb[node.id]) {\n nodeDb[node.id] = {\n id: node.id,\n shape,\n description: node.id,\n classes: 'statediagram-state'\n };\n }\n\n // Build of the array of description strings accordinging\n if (node.description) {\n if (Array.isArray(nodeDb[node.id].description)) {\n // There already is an array of strings,add to it\n nodeDb[node.id].shape = 'rectWithTitle';\n nodeDb[node.id].description.push(node.description);\n } else {\n if (nodeDb[node.id].description.length > 0) {\n // if there is a description already transformit to an array\n nodeDb[node.id].shape = 'rectWithTitle';\n if (nodeDb[node.id].description === node.id) {\n // If the previous description was the is, remove it\n nodeDb[node.id].description = [node.description];\n } else {\n nodeDb[node.id].description = [nodeDb[node.id].description, node.description];\n }\n } else {\n nodeDb[node.id].shape = 'rect';\n nodeDb[node.id].description = node.description;\n }\n }\n }\n\n // Save data for description and group so that for instance a statement without description overwrites\n // one with description\n\n // group\n if (!nodeDb[node.id].type && node.doc) {\n logger.info('Setting cluser for ', node.id);\n nodeDb[node.id].type = 'group';\n nodeDb[node.id].shape = node.type === 'divider' ? 'divider' : 'roundedWithTitle';\n nodeDb[node.id].classes =\n nodeDb[node.id].classes +\n ' ' +\n (altFlag ? 'statediagram-cluster statediagram-cluster-alt' : 'statediagram-cluster');\n }\n\n const nodeData = {\n labelStyle: '',\n shape: nodeDb[node.id].shape,\n labelText: nodeDb[node.id].description,\n classes: nodeDb[node.id].classes, //classStr,\n style: '', //styles.style,\n id: node.id,\n type: nodeDb[node.id].type,\n padding: 15 //getConfig().flowchart.padding\n };\n\n if (node.note) {\n // Todo: set random id\n const noteData = {\n labelStyle: '',\n shape: 'note',\n labelText: node.note.text,\n classes: 'statediagram-note', //classStr,\n style: '', //styles.style,\n id: node.id + '----note',\n type: nodeDb[node.id].type,\n padding: 15 //getConfig().flowchart.padding\n };\n const groupData = {\n labelStyle: '',\n shape: 'noteGroup',\n labelText: node.note.text,\n classes: nodeDb[node.id].classes, //classStr,\n style: '', //styles.style,\n id: node.id + '----parent',\n type: 'group',\n padding: 0 //getConfig().flowchart.padding\n };\n g.setNode(node.id + '----parent', groupData);\n\n g.setNode(noteData.id, noteData);\n g.setNode(node.id, nodeData);\n\n g.setParent(node.id, node.id + '----parent');\n g.setParent(noteData.id, node.id + '----parent');\n\n let from = node.id;\n let to = noteData.id;\n\n if (node.note.position === 'left of') {\n from = noteData.id;\n to = node.id;\n }\n g.setEdge(from, to, {\n arrowhead: 'none',\n arrowType: '',\n style: 'fill:none',\n labelStyle: '',\n classes: 'note-edge',\n arrowheadStyle: 'fill: #333',\n labelpos: 'c',\n labelType: 'text'\n });\n } else {\n g.setNode(node.id, nodeData);\n }\n }\n\n if (parent) {\n if (parent.id !== 'root') {\n logger.info('Setting node ', node.id, ' to be child of its parent ', parent.id);\n g.setParent(node.id, parent.id);\n }\n }\n if (node.doc) {\n logger.info('Adding nodes children ');\n setupDoc(g, node, node.doc, !altFlag);\n }\n};\nlet cnt = 0;\nconst setupDoc = (g, parent, doc, altFlag) => {\n logger.trace('items', doc);\n doc.forEach(item => {\n if (item.stmt === 'state' || item.stmt === 'default') {\n setupNode(g, parent, item, altFlag);\n } else if (item.stmt === 'relation') {\n setupNode(g, parent, item.state1, altFlag);\n setupNode(g, parent, item.state2, altFlag);\n const edgeData = {\n id: 'edge' + cnt,\n arrowhead: 'normal',\n arrowType: 'arrow_barb',\n style: 'fill:none',\n labelStyle: '',\n label: item.description,\n arrowheadStyle: 'fill: #333',\n labelpos: 'c',\n labelType: 'text'\n };\n let startId = item.state1.id;\n let endId = item.state2.id;\n\n g.setEdge(startId, endId, edgeData, cnt);\n cnt++;\n }\n });\n};\n\n/**\n * Draws a flowchart in the tag with id: id based on the graph definition in text.\n * @param text\n * @param id\n */\nexport const draw = function(text, id) {\n logger.info('Drawing state diagram (v2)', id);\n stateDb.clear();\n nodeDb = {};\n const parser = state.parser;\n parser.yy = stateDb;\n\n // Parse the graph definition\n try {\n parser.parse(text);\n } catch (err) {\n logger.debug('Parsing failed');\n }\n\n // Fetch the default direction, use TD if none was found\n let dir = stateDb.getDirection();\n if (typeof dir === 'undefined') {\n dir = 'LR';\n }\n\n const conf = getConfig().state;\n const nodeSpacing = conf.nodeSpacing || 50;\n const rankSpacing = conf.rankSpacing || 50;\n\n // Create the input mermaid.graph\n const g = new graphlib.Graph({\n multigraph: true,\n compound: true\n })\n .setGraph({\n rankdir: 'TB',\n nodesep: nodeSpacing,\n ranksep: rankSpacing,\n marginx: 8,\n marginy: 8\n })\n .setDefaultEdgeLabel(function() {\n return {};\n });\n\n logger.info(stateDb.getRootDocV2());\n stateDb.extract(stateDb.getRootDocV2());\n logger.info(stateDb.getRootDocV2());\n setupNode(g, undefined, stateDb.getRootDocV2(), true);\n\n // Set up an SVG group so that we can translate the final graph.\n const svg = select(`[id=\"${id}\"]`);\n\n // Run the renderer. This is what draws the final graph.\n const element = select('#' + id + ' g');\n render(element, g, ['barb'], 'statediagram', id);\n\n const padding = 8;\n // const svgBounds = svg.node().getBBox();\n // const width = svgBounds.width + padding * 2;\n // const height = svgBounds.height + padding * 2;\n // logger.debug(\n // `new ViewBox 0 0 ${width} ${height}`,\n // `translate(${padding + g._label.marginx}, ${padding + g._label.marginy})`\n // );\n\n // if (conf.useMaxWidth) {\n // svg.attr('width', '100%');\n // svg.attr('style', `max-width: ${width}px;`);\n // } else {\n // svg.attr('height', height);\n // svg.attr('width', width);\n // }\n\n // svg.attr('viewBox', `0 0 ${width} ${height}`);\n // svg\n // .select('g')\n // .attr('transform', `translate(${padding - g._label.marginx}, ${padding - svgBounds.y})`);\n\n const bounds = svg.node().getBBox();\n\n const width = bounds.width + padding * 2;\n const height = bounds.height + padding * 2;\n\n // diagram.attr('height', '100%');\n // diagram.attr('style', `width: ${bounds.width * 3 + conf.padding * 2};`);\n // diagram.attr('height', height);\n\n // Zoom in a bit\n svg.attr('width', width * 1.75);\n svg.attr('class', 'statediagram');\n // diagram.attr('height', bounds.height * 3 + conf.padding * 2);\n // svg.attr(\n // 'viewBox',\n // `${bounds.x - conf.padding} ${bounds.y - conf.padding} ` + width + ' ' + height\n // );\n\n const svgBounds = svg.node().getBBox();\n\n if (conf.useMaxWidth) {\n svg.attr('width', '100%');\n svg.attr('style', `max-width: ${width}px;`);\n } else {\n svg.attr('height', height);\n svg.attr('width', width);\n }\n\n // Ensure the viewBox includes the whole svgBounds area with extra space for padding\n const vBox = `${svgBounds.x - padding} ${svgBounds.y - padding} ${width} ${height}`;\n logger.debug(`viewBox ${vBox}`);\n svg.attr('viewBox', vBox);\n\n // Add label rects for non html labels\n if (!conf.htmlLabels) {\n const labels = document.querySelectorAll('[id=\"' + id + '\"] .edgeLabel .label');\n for (let k = 0; k < labels.length; k++) {\n const label = labels[k];\n\n // Get dimensions of label\n const dim = label.getBBox();\n\n const rect = document.createElementNS('http://www.w3.org/2000/svg', 'rect');\n rect.setAttribute('rx', 0);\n rect.setAttribute('ry', 0);\n rect.setAttribute('width', dim.width);\n rect.setAttribute('height', dim.height);\n rect.setAttribute('style', 'fill:#e8e8e8;');\n\n label.insertBefore(rect, label.firstChild);\n }\n }\n};\n\nexport default {\n setConf,\n getClasses,\n draw\n};\n","import { select } from 'd3';\nimport dagre from 'dagre';\nimport graphlib from 'graphlib';\nimport { logger } from '../../logger';\nimport stateDb from './stateDb';\nimport common from '../common/common';\nimport { parser } from './parser/stateDiagram';\n// import idCache from './id-cache';\nimport { drawState, addTitleAndBox, drawEdge } from './shapes';\nimport { getConfig } from '../../config';\n\nparser.yy = stateDb;\n\n// TODO Move conf object to main conf in mermaidAPI\nlet conf;\n\nconst transformationLog = {};\n\nexport const setConf = function() {};\n\n// Todo optimize\n\n/**\n * Setup arrow head and define the marker. The result is appended to the svg.\n */\nconst insertMarkers = function(elem) {\n elem\n .append('defs')\n .append('marker')\n .attr('id', 'dependencyEnd')\n .attr('refX', 19)\n .attr('refY', 7)\n .attr('markerWidth', 20)\n .attr('markerHeight', 28)\n .attr('orient', 'auto')\n .append('path')\n .attr('d', 'M 19,7 L9,13 L14,7 L9,1 Z');\n};\n\n/**\n * Draws a flowchart in the tag with id: id based on the graph definition in text.\n * @param text\n * @param id\n */\nexport const draw = function(text, id) {\n conf = getConfig().state;\n parser.yy.clear();\n parser.parse(text);\n logger.debug('Rendering diagram ' + text);\n\n // Fetch the default direction, use TD if none was found\n const diagram = select(`[id='${id}']`);\n insertMarkers(diagram);\n\n // Layout graph, Create a new directed graph\n const graph = new graphlib.Graph({\n multigraph: true,\n compound: true,\n // acyclicer: 'greedy',\n rankdir: 'RL'\n // ranksep: '20'\n });\n\n // Default to assigning a new object as a label for each new edge.\n graph.setDefaultEdgeLabel(function() {\n return {};\n });\n\n const rootDoc = stateDb.getRootDoc();\n renderDoc(rootDoc, diagram, undefined, false);\n\n const padding = conf.padding;\n const bounds = diagram.node().getBBox();\n\n const width = bounds.width + padding * 2;\n const height = bounds.height + padding * 2;\n\n if (conf.useMaxWidth) {\n diagram.attr('width', '100%');\n diagram.attr('style', `max-width: ${width * 1.75}px;`);\n } else {\n // Zoom in a bit\n diagram.attr('width', width * 1.75);\n }\n // diagram.attr('height', bounds.height * 3 + conf.padding * 2);\n diagram.attr(\n 'viewBox',\n `${bounds.x - conf.padding} ${bounds.y - conf.padding} ` + width + ' ' + height\n );\n};\nconst getLabelWidth = text => {\n return text ? text.length * conf.fontSizeFactor : 1;\n};\n\nconst renderDoc = (doc, diagram, parentId, altBkg) => {\n // // Layout graph, Create a new directed graph\n const graph = new graphlib.Graph({\n compound: true,\n multigraph: true\n });\n\n let i;\n let edgeFreeDoc = true;\n for (i = 0; i < doc.length; i++) {\n if (doc[i].stmt === 'relation') {\n edgeFreeDoc = false;\n break;\n }\n }\n\n // Set an object for the graph label\n if (parentId)\n graph.setGraph({\n rankdir: 'LR',\n multigraph: true,\n compound: true,\n // acyclicer: 'greedy',\n ranker: 'tight-tree',\n ranksep: edgeFreeDoc ? 1 : conf.edgeLengthFactor,\n nodeSep: edgeFreeDoc ? 1 : 50,\n isMultiGraph: true\n // ranksep: 5,\n // nodesep: 1\n });\n else {\n graph.setGraph({\n rankdir: 'TB',\n multigraph: true,\n compound: true,\n // isCompound: true,\n // acyclicer: 'greedy',\n // ranker: 'longest-path'\n ranksep: edgeFreeDoc ? 1 : conf.edgeLengthFactor,\n nodeSep: edgeFreeDoc ? 1 : 50,\n ranker: 'tight-tree',\n // ranker: 'network-simplex'\n isMultiGraph: true\n });\n }\n\n // Default to assigning a new object as a label for each new edge.\n graph.setDefaultEdgeLabel(function() {\n return {};\n });\n\n stateDb.extract(doc);\n const states = stateDb.getStates();\n const relations = stateDb.getRelations();\n\n const keys = Object.keys(states);\n\n let first = true;\n\n for (let i = 0; i < keys.length; i++) {\n const stateDef = states[keys[i]];\n\n if (parentId) {\n stateDef.parentId = parentId;\n }\n\n let node;\n if (stateDef.doc) {\n let sub = diagram\n .append('g')\n .attr('id', stateDef.id)\n .attr('class', 'stateGroup');\n node = renderDoc(stateDef.doc, sub, stateDef.id, !altBkg);\n\n if (first) {\n // first = false;\n sub = addTitleAndBox(sub, stateDef, altBkg);\n let boxBounds = sub.node().getBBox();\n node.width = boxBounds.width;\n node.height = boxBounds.height + conf.padding / 2;\n transformationLog[stateDef.id] = { y: conf.compositTitleSize };\n } else {\n // sub = addIdAndBox(sub, stateDef);\n let boxBounds = sub.node().getBBox();\n node.width = boxBounds.width;\n node.height = boxBounds.height;\n // transformationLog[stateDef.id] = { y: conf.compositTitleSize };\n }\n } else {\n node = drawState(diagram, stateDef, graph);\n }\n\n if (stateDef.note) {\n // Draw note note\n const noteDef = {\n descriptions: [],\n id: stateDef.id + '-note',\n note: stateDef.note,\n type: 'note'\n };\n const note = drawState(diagram, noteDef, graph);\n\n // graph.setNode(node.id, node);\n if (stateDef.note.position === 'left of') {\n graph.setNode(node.id + '-note', note);\n graph.setNode(node.id, node);\n } else {\n graph.setNode(node.id, node);\n graph.setNode(node.id + '-note', note);\n }\n // graph.setNode(node.id);\n graph.setParent(node.id, node.id + '-group');\n graph.setParent(node.id + '-note', node.id + '-group');\n } else {\n // Add nodes to the graph. The first argument is the node id. The second is\n // metadata about the node. In this case we're going to add labels to each of\n // our nodes.\n graph.setNode(node.id, node);\n }\n }\n\n logger.debug('Count=', graph.nodeCount(), graph);\n let cnt = 0;\n relations.forEach(function(relation) {\n cnt++;\n logger.debug('Setting edge', relation);\n graph.setEdge(\n relation.id1,\n relation.id2,\n {\n relation: relation,\n width: getLabelWidth(relation.title),\n height: conf.labelHeight * common.getRows(relation.title).length,\n labelpos: 'c'\n },\n 'id' + cnt\n );\n });\n\n dagre.layout(graph);\n\n logger.debug('Graph after layout', graph.nodes());\n const svgElem = diagram.node();\n\n graph.nodes().forEach(function(v) {\n if (typeof v !== 'undefined' && typeof graph.node(v) !== 'undefined') {\n logger.warn('Node ' + v + ': ' + JSON.stringify(graph.node(v)));\n select('#' + svgElem.id + ' #' + v).attr(\n 'transform',\n 'translate(' +\n (graph.node(v).x - graph.node(v).width / 2) +\n ',' +\n (graph.node(v).y +\n (transformationLog[v] ? transformationLog[v].y : 0) -\n graph.node(v).height / 2) +\n ' )'\n );\n select('#' + svgElem.id + ' #' + v).attr(\n 'data-x-shift',\n graph.node(v).x - graph.node(v).width / 2\n );\n const dividers = document.querySelectorAll('#' + svgElem.id + ' #' + v + ' .divider');\n dividers.forEach(divider => {\n const parent = divider.parentElement;\n let pWidth = 0;\n let pShift = 0;\n if (parent) {\n if (parent.parentElement) pWidth = parent.parentElement.getBBox().width;\n pShift = parseInt(parent.getAttribute('data-x-shift'), 10);\n if (Number.isNaN(pShift)) {\n pShift = 0;\n }\n }\n divider.setAttribute('x1', 0 - pShift + 8);\n divider.setAttribute('x2', pWidth - pShift - 8);\n });\n } else {\n logger.debug('No Node ' + v + ': ' + JSON.stringify(graph.node(v)));\n }\n });\n\n let stateBox = svgElem.getBBox();\n\n graph.edges().forEach(function(e) {\n if (typeof e !== 'undefined' && typeof graph.edge(e) !== 'undefined') {\n logger.debug('Edge ' + e.v + ' -> ' + e.w + ': ' + JSON.stringify(graph.edge(e)));\n drawEdge(diagram, graph.edge(e), graph.edge(e).relation);\n }\n });\n\n stateBox = svgElem.getBBox();\n\n const stateInfo = {\n id: parentId ? parentId : 'root',\n label: parentId ? parentId : 'root',\n width: 0,\n height: 0\n };\n\n stateInfo.width = stateBox.width + 2 * conf.padding;\n stateInfo.height = stateBox.height + 2 * conf.padding;\n\n logger.debug('Doc rendered', stateInfo, graph);\n return stateInfo;\n};\n\nexport default {\n setConf,\n draw\n};\n","let title = '';\nlet currentSection = '';\n\nconst sections = [];\nconst tasks = [];\nconst rawTasks = [];\n\nexport const clear = function() {\n sections.length = 0;\n tasks.length = 0;\n currentSection = '';\n title = '';\n rawTasks.length = 0;\n};\n\nexport const setTitle = function(txt) {\n title = txt;\n};\n\nexport const getTitle = function() {\n return title;\n};\n\nexport const addSection = function(txt) {\n currentSection = txt;\n sections.push(txt);\n};\n\nexport const getSections = function() {\n return sections;\n};\n\nexport const getTasks = function() {\n let allItemsProcessed = compileTasks();\n const maxDepth = 100;\n let iterationCount = 0;\n while (!allItemsProcessed && iterationCount < maxDepth) {\n allItemsProcessed = compileTasks();\n iterationCount++;\n }\n\n tasks.push(...rawTasks);\n\n return tasks;\n};\n\nconst updateActors = function() {\n const tempActors = [];\n tasks.forEach(task => {\n if (task.people) {\n tempActors.push(...task.people);\n }\n });\n\n const unique = new Set(tempActors);\n return [...unique].sort();\n};\n\nexport const addTask = function(descr, taskData) {\n const pieces = taskData.substr(1).split(':');\n\n let score = 0;\n let peeps = [];\n if (pieces.length === 1) {\n score = Number(pieces[0]);\n peeps = [];\n } else {\n score = Number(pieces[0]);\n peeps = pieces[1].split(',');\n }\n const peopleList = peeps.map(s => s.trim());\n\n const rawTask = {\n section: currentSection,\n type: currentSection,\n people: peopleList,\n task: descr,\n score\n };\n\n rawTasks.push(rawTask);\n};\n\nexport const addTaskOrg = function(descr) {\n const newTask = {\n section: currentSection,\n type: currentSection,\n description: descr,\n task: descr,\n classes: []\n };\n tasks.push(newTask);\n};\n\nconst compileTasks = function() {\n const compileTask = function(pos) {\n return rawTasks[pos].processed;\n };\n\n let allProcessed = true;\n for (let i = 0; i < rawTasks.length; i++) {\n compileTask(i);\n\n allProcessed = allProcessed && rawTasks[i].processed;\n }\n return allProcessed;\n};\n\nconst getActors = function() {\n return updateActors();\n};\n\nexport default {\n clear,\n setTitle,\n getTitle,\n addSection,\n getSections,\n getTasks,\n addTask,\n addTaskOrg,\n getActors\n};\n","import { select } from 'd3';\nimport { parser } from './parser/journey';\nimport journeyDb from './journeyDb';\nimport svgDraw from './svgDraw';\n\nparser.yy = journeyDb;\n\nconst conf = {\n leftMargin: 150,\n diagramMarginX: 50,\n diagramMarginY: 20,\n // Margin between tasks\n taskMargin: 50,\n // Width of task boxes\n width: 150,\n // Height of task boxes\n height: 50,\n taskFontSize: 14,\n taskFontFamily: '\"Open-Sans\", \"sans-serif\"',\n // Margin around loop boxes\n boxMargin: 10,\n boxTextMargin: 5,\n noteMargin: 10,\n // Space between messages\n messageMargin: 35,\n // Multiline message alignment\n messageAlign: 'center',\n // Depending on css styling this might need adjustment\n // Projects the edge of the diagram downwards\n bottomMarginAdj: 1,\n\n // width of activation box\n activationWidth: 10,\n\n // text placement as: tspan | fo | old only text as before\n textPlacement: 'fo',\n\n actorColours: ['#8FBC8F', '#7CFC00', '#00FFFF', '#20B2AA', '#B0E0E6', '#FFFFE0'],\n\n sectionFills: ['#191970', '#8B008B', '#4B0082', '#2F4F4F', '#800000', '#8B4513', '#00008B'],\n sectionColours: ['#fff']\n};\n\nexport const setConf = function(cnf) {\n const keys = Object.keys(cnf);\n\n keys.forEach(function(key) {\n conf[key] = cnf[key];\n });\n};\n\nconst actors = {};\n\nfunction drawActorLegend(diagram) {\n // Draw the actors\n let yPos = 60;\n Object.keys(actors).forEach(person => {\n const colour = actors[person];\n\n const circleData = {\n cx: 20,\n cy: yPos,\n r: 7,\n fill: colour,\n stroke: '#000'\n };\n svgDraw.drawCircle(diagram, circleData);\n\n const labelData = {\n x: 40,\n y: yPos + 7,\n fill: '#666',\n text: person\n };\n svgDraw.drawText(diagram, labelData);\n\n yPos += 20;\n });\n}\n\nconst LEFT_MARGIN = conf.leftMargin;\nexport const draw = function(text, id) {\n parser.yy.clear();\n parser.parse(text + '\\n');\n\n bounds.init();\n const diagram = select('#' + id);\n diagram.attr('xmlns:xlink', 'http://www.w3.org/1999/xlink');\n\n svgDraw.initGraphics(diagram);\n\n const tasks = parser.yy.getTasks();\n const title = parser.yy.getTitle();\n\n const actorNames = parser.yy.getActors();\n for (let member in actors) delete actors[member];\n let actorPos = 0;\n actorNames.forEach(actorName => {\n actors[actorName] = conf.actorColours[actorPos % conf.actorColours.length];\n actorPos++;\n });\n\n drawActorLegend(diagram);\n bounds.insert(0, 0, LEFT_MARGIN, Object.keys(actors).length * 50);\n\n drawTasks(diagram, tasks, 0);\n\n const box = bounds.getBounds();\n if (title) {\n diagram\n .append('text')\n .text(title)\n .attr('x', LEFT_MARGIN)\n .attr('font-size', '4ex')\n .attr('font-weight', 'bold')\n .attr('y', 25);\n }\n const height = box.stopy - box.starty + 2 * conf.diagramMarginY;\n const width = LEFT_MARGIN + box.stopx + 2 * conf.diagramMarginX;\n if (conf.useMaxWidth) {\n diagram.attr('height', '100%');\n diagram.attr('width', '100%');\n diagram.attr('style', 'max-width:' + width + 'px;');\n } else {\n diagram.attr('height', height);\n diagram.attr('width', width);\n }\n\n // Draw activity line\n diagram\n .append('line')\n .attr('x1', LEFT_MARGIN)\n .attr('y1', conf.height * 4) // One section head + one task + margins\n .attr('x2', width - LEFT_MARGIN - 4) // Subtract stroke width so arrow point is retained\n .attr('y2', conf.height * 4)\n .attr('stroke-width', 4)\n .attr('stroke', 'black')\n .attr('marker-end', 'url(#arrowhead)');\n\n const extraVertForTitle = title ? 70 : 0;\n diagram.attr('viewBox', `${box.startx} -25 ${width} ${height + extraVertForTitle}`);\n diagram.attr('preserveAspectRatio', 'xMinYMin meet');\n};\n\nexport const bounds = {\n data: {\n startx: undefined,\n stopx: undefined,\n starty: undefined,\n stopy: undefined\n },\n verticalPos: 0,\n\n sequenceItems: [],\n init: function() {\n this.sequenceItems = [];\n this.data = {\n startx: undefined,\n stopx: undefined,\n starty: undefined,\n stopy: undefined\n };\n this.verticalPos = 0;\n },\n updateVal: function(obj, key, val, fun) {\n if (typeof obj[key] === 'undefined') {\n obj[key] = val;\n } else {\n obj[key] = fun(val, obj[key]);\n }\n },\n updateBounds: function(startx, starty, stopx, stopy) {\n const _self = this;\n let cnt = 0;\n function updateFn(type) {\n return function updateItemBounds(item) {\n cnt++;\n // The loop sequenceItems is a stack so the biggest margins in the beginning of the sequenceItems\n const n = _self.sequenceItems.length - cnt + 1;\n\n _self.updateVal(item, 'starty', starty - n * conf.boxMargin, Math.min);\n _self.updateVal(item, 'stopy', stopy + n * conf.boxMargin, Math.max);\n\n _self.updateVal(bounds.data, 'startx', startx - n * conf.boxMargin, Math.min);\n _self.updateVal(bounds.data, 'stopx', stopx + n * conf.boxMargin, Math.max);\n\n if (!(type === 'activation')) {\n _self.updateVal(item, 'startx', startx - n * conf.boxMargin, Math.min);\n _self.updateVal(item, 'stopx', stopx + n * conf.boxMargin, Math.max);\n\n _self.updateVal(bounds.data, 'starty', starty - n * conf.boxMargin, Math.min);\n _self.updateVal(bounds.data, 'stopy', stopy + n * conf.boxMargin, Math.max);\n }\n };\n }\n\n this.sequenceItems.forEach(updateFn());\n },\n insert: function(startx, starty, stopx, stopy) {\n const _startx = Math.min(startx, stopx);\n const _stopx = Math.max(startx, stopx);\n const _starty = Math.min(starty, stopy);\n const _stopy = Math.max(starty, stopy);\n\n this.updateVal(bounds.data, 'startx', _startx, Math.min);\n this.updateVal(bounds.data, 'starty', _starty, Math.min);\n this.updateVal(bounds.data, 'stopx', _stopx, Math.max);\n this.updateVal(bounds.data, 'stopy', _stopy, Math.max);\n\n this.updateBounds(_startx, _starty, _stopx, _stopy);\n },\n bumpVerticalPos: function(bump) {\n this.verticalPos = this.verticalPos + bump;\n this.data.stopy = this.verticalPos;\n },\n getVerticalPos: function() {\n return this.verticalPos;\n },\n getBounds: function() {\n return this.data;\n }\n};\n\nconst fills = conf.sectionFills;\nconst textColours = conf.sectionColours;\n\nexport const drawTasks = function(diagram, tasks, verticalPos) {\n let lastSection = '';\n const sectionVHeight = conf.height * 2 + conf.diagramMarginY;\n const taskPos = verticalPos + sectionVHeight;\n\n let sectionNumber = 0;\n let fill = '#CCC';\n let colour = 'black';\n\n // Draw the tasks\n for (let i = 0; i < tasks.length; i++) {\n let task = tasks[i];\n if (lastSection !== task.section) {\n fill = fills[sectionNumber % fills.length];\n colour = textColours[sectionNumber % textColours.length];\n\n const section = {\n x: i * conf.taskMargin + i * conf.width + LEFT_MARGIN,\n y: 50,\n text: task.section,\n fill,\n colour\n };\n\n svgDraw.drawSection(diagram, section, conf);\n lastSection = task.section;\n sectionNumber++;\n }\n\n // Collect the actors involved in the task\n const taskActors = task.people.reduce((acc, actorName) => {\n if (actors[actorName]) {\n acc[actorName] = actors[actorName];\n }\n\n return acc;\n }, {});\n\n // Add some rendering data to the object\n task.x = i * conf.taskMargin + i * conf.width + LEFT_MARGIN;\n task.y = taskPos;\n task.width = conf.diagramMarginX;\n task.height = conf.diagramMarginY;\n task.colour = colour;\n task.fill = fill;\n task.actors = taskActors;\n\n // Draw the box with the attached line\n svgDraw.drawTask(diagram, task, conf);\n bounds.insert(task.x, task.y, task.x + task.width + conf.taskMargin, 300 + 5 * 30); // stopy is the length of the descenders.\n }\n};\n\nexport default {\n setConf,\n draw\n};\n","/* parser generated by jison 0.4.18 */\n/*\n Returns a Parser object of the following structure:\n\n Parser: {\n yy: {}\n }\n\n Parser.prototype: {\n yy: {},\n trace: function(),\n symbols_: {associative list: name ==> number},\n terminals_: {associative list: number ==> name},\n productions_: [...],\n performAction: function anonymous(yytext, yyleng, yylineno, yy, yystate, $$, _$),\n table: [...],\n defaultActions: {...},\n parseError: function(str, hash),\n parse: function(input),\n\n lexer: {\n EOF: 1,\n parseError: function(str, hash),\n setInput: function(input),\n input: function(),\n unput: function(str),\n more: function(),\n less: function(n),\n pastInput: function(),\n upcomingInput: function(),\n showPosition: function(),\n test_match: function(regex_match_array, rule_index),\n next: function(),\n lex: function(),\n begin: function(condition),\n popState: function(),\n _currentRules: function(),\n topState: function(),\n pushState: function(condition),\n\n options: {\n ranges: boolean (optional: true ==> token location info will include a .range[] member)\n flex: boolean (optional: true ==> flex-like lexing behaviour where the rules are tested exhaustively to find the longest match)\n backtrack_lexer: boolean (optional: true ==> lexer regexes are tested in order and for each matching regex the action code is invoked; the lexer terminates the scan when a token is returned by the action code)\n },\n\n performAction: function(yy, yy_, $avoiding_name_collisions, YY_START),\n rules: [...],\n conditions: {associative list: name ==> set},\n }\n }\n\n\n token location info (@$, _$, etc.): {\n first_line: n,\n last_line: n,\n first_column: n,\n last_column: n,\n range: [start_number, end_number] (where the numbers are indexes into the input string, regular zero-based)\n }\n\n\n the parseError function receives a 'hash' object with these members for lexer and parser errors: {\n text: (matched text)\n token: (the produced terminal token, if any)\n line: (yylineno)\n }\n while parser (grammar) errors will also provide these members, i.e. parser errors deliver a superset of attributes: {\n loc: (yylloc)\n expected: (string describing the set of expected tokens)\n recoverable: (boolean: TRUE when the parser has a error recovery rule available for this particular error)\n }\n*/\nvar parser = (function(){\nvar o=function(k,v,o,l){for(o=o||{},l=k.length;l--;o[k[l]]=v);return o},$V0=[6,8,10,11,12,13],$V1=[1,9],$V2=[1,10],$V3=[1,11];\nvar parser = {trace: function trace () { },\nyy: {},\nsymbols_: {\"error\":2,\"start\":3,\"journey\":4,\"document\":5,\"EOF\":6,\"line\":7,\"SPACE\":8,\"statement\":9,\"NL\":10,\"title\":11,\"section\":12,\"taskName\":13,\"taskData\":14,\"$accept\":0,\"$end\":1},\nterminals_: {2:\"error\",4:\"journey\",6:\"EOF\",8:\"SPACE\",10:\"NL\",11:\"title\",12:\"section\",13:\"taskName\",14:\"taskData\"},\nproductions_: [0,[3,3],[5,0],[5,2],[7,2],[7,1],[7,1],[7,1],[9,1],[9,1],[9,2]],\nperformAction: function anonymous(yytext, yyleng, yylineno, yy, yystate /* action[1] */, $$ /* vstack */, _$ /* lstack */) {\n/* this == yyval */\n\nvar $0 = $$.length - 1;\nswitch (yystate) {\ncase 1:\n return $$[$0-1]; \nbreak;\ncase 2:\n this.$ = [] \nbreak;\ncase 3:\n$$[$0-1].push($$[$0]);this.$ = $$[$0-1]\nbreak;\ncase 4: case 5:\n this.$ = $$[$0] \nbreak;\ncase 6: case 7:\n this.$=[];\nbreak;\ncase 8:\nyy.setTitle($$[$0].substr(6));this.$=$$[$0].substr(6);\nbreak;\ncase 9:\nyy.addSection($$[$0].substr(8));this.$=$$[$0].substr(8);\nbreak;\ncase 10:\nyy.addTask($$[$0-1], $$[$0]);this.$='task';\nbreak;\n}\n},\ntable: [{3:1,4:[1,2]},{1:[3]},o($V0,[2,2],{5:3}),{6:[1,4],7:5,8:[1,6],9:7,10:[1,8],11:$V1,12:$V2,13:$V3},o($V0,[2,7],{1:[2,1]}),o($V0,[2,3]),{9:12,11:$V1,12:$V2,13:$V3},o($V0,[2,5]),o($V0,[2,6]),o($V0,[2,8]),o($V0,[2,9]),{14:[1,13]},o($V0,[2,4]),o($V0,[2,10])],\ndefaultActions: {},\nparseError: function parseError (str, hash) {\n if (hash.recoverable) {\n this.trace(str);\n } else {\n var error = new Error(str);\n error.hash = hash;\n throw error;\n }\n},\nparse: function parse(input) {\n var self = this, stack = [0], tstack = [], vstack = [null], lstack = [], table = this.table, yytext = '', yylineno = 0, yyleng = 0, recovering = 0, TERROR = 2, EOF = 1;\n var args = lstack.slice.call(arguments, 1);\n var lexer = Object.create(this.lexer);\n var sharedState = { yy: {} };\n for (var k in this.yy) {\n if (Object.prototype.hasOwnProperty.call(this.yy, k)) {\n sharedState.yy[k] = this.yy[k];\n }\n }\n lexer.setInput(input, sharedState.yy);\n sharedState.yy.lexer = lexer;\n sharedState.yy.parser = this;\n if (typeof lexer.yylloc == 'undefined') {\n lexer.yylloc = {};\n }\n var yyloc = lexer.yylloc;\n lstack.push(yyloc);\n var ranges = lexer.options && lexer.options.ranges;\n if (typeof sharedState.yy.parseError === 'function') {\n this.parseError = sharedState.yy.parseError;\n } else {\n this.parseError = Object.getPrototypeOf(this).parseError;\n }\n function popStack(n) {\n stack.length = stack.length - 2 * n;\n vstack.length = vstack.length - n;\n lstack.length = lstack.length - n;\n }\n function lex() {\n var token;\n token = tstack.pop() || lexer.lex() || EOF;\n if (typeof token !== 'number') {\n if (token instanceof Array) {\n tstack = token;\n token = tstack.pop();\n }\n token = self.symbols_[token] || token;\n }\n return token;\n }\n var symbol, preErrorSymbol, state, action, a, r, yyval = {}, p, len, newState, expected;\n while (true) {\n state = stack[stack.length - 1];\n if (this.defaultActions[state]) {\n action = this.defaultActions[state];\n } else {\n if (symbol === null || typeof symbol == 'undefined') {\n symbol = lex();\n }\n action = table[state] && table[state][symbol];\n }\n if (typeof action === 'undefined' || !action.length || !action[0]) {\n var errStr = '';\n expected = [];\n for (p in table[state]) {\n if (this.terminals_[p] && p > TERROR) {\n expected.push('\\'' + this.terminals_[p] + '\\'');\n }\n }\n if (lexer.showPosition) {\n errStr = 'Parse error on line ' + (yylineno + 1) + ':\\n' + lexer.showPosition() + '\\nExpecting ' + expected.join(', ') + ', got \\'' + (this.terminals_[symbol] || symbol) + '\\'';\n } else {\n errStr = 'Parse error on line ' + (yylineno + 1) + ': Unexpected ' + (symbol == EOF ? 'end of input' : '\\'' + (this.terminals_[symbol] || symbol) + '\\'');\n }\n this.parseError(errStr, {\n text: lexer.match,\n token: this.terminals_[symbol] || symbol,\n line: lexer.yylineno,\n loc: yyloc,\n expected: expected\n });\n }\n if (action[0] instanceof Array && action.length > 1) {\n throw new Error('Parse Error: multiple actions possible at state: ' + state + ', token: ' + symbol);\n }\n switch (action[0]) {\n case 1:\n stack.push(symbol);\n vstack.push(lexer.yytext);\n lstack.push(lexer.yylloc);\n stack.push(action[1]);\n symbol = null;\n if (!preErrorSymbol) {\n yyleng = lexer.yyleng;\n yytext = lexer.yytext;\n yylineno = lexer.yylineno;\n yyloc = lexer.yylloc;\n if (recovering > 0) {\n recovering--;\n }\n } else {\n symbol = preErrorSymbol;\n preErrorSymbol = null;\n }\n break;\n case 2:\n len = this.productions_[action[1]][1];\n yyval.$ = vstack[vstack.length - len];\n yyval._$ = {\n first_line: lstack[lstack.length - (len || 1)].first_line,\n last_line: lstack[lstack.length - 1].last_line,\n first_column: lstack[lstack.length - (len || 1)].first_column,\n last_column: lstack[lstack.length - 1].last_column\n };\n if (ranges) {\n yyval._$.range = [\n lstack[lstack.length - (len || 1)].range[0],\n lstack[lstack.length - 1].range[1]\n ];\n }\n r = this.performAction.apply(yyval, [\n yytext,\n yyleng,\n yylineno,\n sharedState.yy,\n action[1],\n vstack,\n lstack\n ].concat(args));\n if (typeof r !== 'undefined') {\n return r;\n }\n if (len) {\n stack = stack.slice(0, -1 * len * 2);\n vstack = vstack.slice(0, -1 * len);\n lstack = lstack.slice(0, -1 * len);\n }\n stack.push(this.productions_[action[1]][0]);\n vstack.push(yyval.$);\n lstack.push(yyval._$);\n newState = table[stack[stack.length - 2]][stack[stack.length - 1]];\n stack.push(newState);\n break;\n case 3:\n return true;\n }\n }\n return true;\n}};\n/* generated by jison-lex 0.3.4 */\nvar lexer = (function(){\nvar lexer = ({\n\nEOF:1,\n\nparseError:function parseError(str, hash) {\n if (this.yy.parser) {\n this.yy.parser.parseError(str, hash);\n } else {\n throw new Error(str);\n }\n },\n\n// resets the lexer, sets new input\nsetInput:function (input, yy) {\n this.yy = yy || this.yy || {};\n this._input = input;\n this._more = this._backtrack = this.done = false;\n this.yylineno = this.yyleng = 0;\n this.yytext = this.matched = this.match = '';\n this.conditionStack = ['INITIAL'];\n this.yylloc = {\n first_line: 1,\n first_column: 0,\n last_line: 1,\n last_column: 0\n };\n if (this.options.ranges) {\n this.yylloc.range = [0,0];\n }\n this.offset = 0;\n return this;\n },\n\n// consumes and returns one char from the input\ninput:function () {\n var ch = this._input[0];\n this.yytext += ch;\n this.yyleng++;\n this.offset++;\n this.match += ch;\n this.matched += ch;\n var lines = ch.match(/(?:\\r\\n?|\\n).*/g);\n if (lines) {\n this.yylineno++;\n this.yylloc.last_line++;\n } else {\n this.yylloc.last_column++;\n }\n if (this.options.ranges) {\n this.yylloc.range[1]++;\n }\n\n this._input = this._input.slice(1);\n return ch;\n },\n\n// unshifts one char (or a string) into the input\nunput:function (ch) {\n var len = ch.length;\n var lines = ch.split(/(?:\\r\\n?|\\n)/g);\n\n this._input = ch + this._input;\n this.yytext = this.yytext.substr(0, this.yytext.length - len);\n //this.yyleng -= len;\n this.offset -= len;\n var oldLines = this.match.split(/(?:\\r\\n?|\\n)/g);\n this.match = this.match.substr(0, this.match.length - 1);\n this.matched = this.matched.substr(0, this.matched.length - 1);\n\n if (lines.length - 1) {\n this.yylineno -= lines.length - 1;\n }\n var r = this.yylloc.range;\n\n this.yylloc = {\n first_line: this.yylloc.first_line,\n last_line: this.yylineno + 1,\n first_column: this.yylloc.first_column,\n last_column: lines ?\n (lines.length === oldLines.length ? this.yylloc.first_column : 0)\n + oldLines[oldLines.length - lines.length].length - lines[0].length :\n this.yylloc.first_column - len\n };\n\n if (this.options.ranges) {\n this.yylloc.range = [r[0], r[0] + this.yyleng - len];\n }\n this.yyleng = this.yytext.length;\n return this;\n },\n\n// When called from action, caches matched text and appends it on next action\nmore:function () {\n this._more = true;\n return this;\n },\n\n// When called from action, signals the lexer that this rule fails to match the input, so the next matching rule (regex) should be tested instead.\nreject:function () {\n if (this.options.backtrack_lexer) {\n this._backtrack = true;\n } else {\n return this.parseError('Lexical error on line ' + (this.yylineno + 1) + '. You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).\\n' + this.showPosition(), {\n text: \"\",\n token: null,\n line: this.yylineno\n });\n\n }\n return this;\n },\n\n// retain first n characters of the match\nless:function (n) {\n this.unput(this.match.slice(n));\n },\n\n// displays already matched input, i.e. for error messages\npastInput:function () {\n var past = this.matched.substr(0, this.matched.length - this.match.length);\n return (past.length > 20 ? '...':'') + past.substr(-20).replace(/\\n/g, \"\");\n },\n\n// displays upcoming input, i.e. for error messages\nupcomingInput:function () {\n var next = this.match;\n if (next.length < 20) {\n next += this._input.substr(0, 20-next.length);\n }\n return (next.substr(0,20) + (next.length > 20 ? '...' : '')).replace(/\\n/g, \"\");\n },\n\n// displays the character position where the lexing error occurred, i.e. for error messages\nshowPosition:function () {\n var pre = this.pastInput();\n var c = new Array(pre.length + 1).join(\"-\");\n return pre + this.upcomingInput() + \"\\n\" + c + \"^\";\n },\n\n// test the lexed token: return FALSE when not a match, otherwise return token\ntest_match:function(match, indexed_rule) {\n var token,\n lines,\n backup;\n\n if (this.options.backtrack_lexer) {\n // save context\n backup = {\n yylineno: this.yylineno,\n yylloc: {\n first_line: this.yylloc.first_line,\n last_line: this.last_line,\n first_column: this.yylloc.first_column,\n last_column: this.yylloc.last_column\n },\n yytext: this.yytext,\n match: this.match,\n matches: this.matches,\n matched: this.matched,\n yyleng: this.yyleng,\n offset: this.offset,\n _more: this._more,\n _input: this._input,\n yy: this.yy,\n conditionStack: this.conditionStack.slice(0),\n done: this.done\n };\n if (this.options.ranges) {\n backup.yylloc.range = this.yylloc.range.slice(0);\n }\n }\n\n lines = match[0].match(/(?:\\r\\n?|\\n).*/g);\n if (lines) {\n this.yylineno += lines.length;\n }\n this.yylloc = {\n first_line: this.yylloc.last_line,\n last_line: this.yylineno + 1,\n first_column: this.yylloc.last_column,\n last_column: lines ?\n lines[lines.length - 1].length - lines[lines.length - 1].match(/\\r?\\n?/)[0].length :\n this.yylloc.last_column + match[0].length\n };\n this.yytext += match[0];\n this.match += match[0];\n this.matches = match;\n this.yyleng = this.yytext.length;\n if (this.options.ranges) {\n this.yylloc.range = [this.offset, this.offset += this.yyleng];\n }\n this._more = false;\n this._backtrack = false;\n this._input = this._input.slice(match[0].length);\n this.matched += match[0];\n token = this.performAction.call(this, this.yy, this, indexed_rule, this.conditionStack[this.conditionStack.length - 1]);\n if (this.done && this._input) {\n this.done = false;\n }\n if (token) {\n return token;\n } else if (this._backtrack) {\n // recover context\n for (var k in backup) {\n this[k] = backup[k];\n }\n return false; // rule action called reject() implying the next rule should be tested instead.\n }\n return false;\n },\n\n// return next match in input\nnext:function () {\n if (this.done) {\n return this.EOF;\n }\n if (!this._input) {\n this.done = true;\n }\n\n var token,\n match,\n tempMatch,\n index;\n if (!this._more) {\n this.yytext = '';\n this.match = '';\n }\n var rules = this._currentRules();\n for (var i = 0; i < rules.length; i++) {\n tempMatch = this._input.match(this.rules[rules[i]]);\n if (tempMatch && (!match || tempMatch[0].length > match[0].length)) {\n match = tempMatch;\n index = i;\n if (this.options.backtrack_lexer) {\n token = this.test_match(tempMatch, rules[i]);\n if (token !== false) {\n return token;\n } else if (this._backtrack) {\n match = false;\n continue; // rule action called reject() implying a rule MISmatch.\n } else {\n // else: this is a lexer rule which consumes input without producing a token (e.g. whitespace)\n return false;\n }\n } else if (!this.options.flex) {\n break;\n }\n }\n }\n if (match) {\n token = this.test_match(match, rules[index]);\n if (token !== false) {\n return token;\n }\n // else: this is a lexer rule which consumes input without producing a token (e.g. whitespace)\n return false;\n }\n if (this._input === \"\") {\n return this.EOF;\n } else {\n return this.parseError('Lexical error on line ' + (this.yylineno + 1) + '. Unrecognized text.\\n' + this.showPosition(), {\n text: \"\",\n token: null,\n line: this.yylineno\n });\n }\n },\n\n// return next match that has a token\nlex:function lex () {\n var r = this.next();\n if (r) {\n return r;\n } else {\n return this.lex();\n }\n },\n\n// activates a new lexer condition state (pushes the new lexer condition state onto the condition stack)\nbegin:function begin (condition) {\n this.conditionStack.push(condition);\n },\n\n// pop the previously active lexer condition state off the condition stack\npopState:function popState () {\n var n = this.conditionStack.length - 1;\n if (n > 0) {\n return this.conditionStack.pop();\n } else {\n return this.conditionStack[0];\n }\n },\n\n// produce the lexer rule set which is active for the currently active lexer condition state\n_currentRules:function _currentRules () {\n if (this.conditionStack.length && this.conditionStack[this.conditionStack.length - 1]) {\n return this.conditions[this.conditionStack[this.conditionStack.length - 1]].rules;\n } else {\n return this.conditions[\"INITIAL\"].rules;\n }\n },\n\n// return the currently active lexer condition state; when an index argument is provided it produces the N-th previous condition state, if available\ntopState:function topState (n) {\n n = this.conditionStack.length - 1 - Math.abs(n || 0);\n if (n >= 0) {\n return this.conditionStack[n];\n } else {\n return \"INITIAL\";\n }\n },\n\n// alias for begin(condition)\npushState:function pushState (condition) {\n this.begin(condition);\n },\n\n// return the number of states currently on the stack\nstateStackSize:function stateStackSize() {\n return this.conditionStack.length;\n },\noptions: {\"case-insensitive\":true},\nperformAction: function anonymous(yy,yy_,$avoiding_name_collisions,YY_START) {\nvar YYSTATE=YY_START;\nswitch($avoiding_name_collisions) {\ncase 0:return 10;\nbreak;\ncase 1:/* skip whitespace */\nbreak;\ncase 2:/* skip comments */\nbreak;\ncase 3:/* skip comments */\nbreak;\ncase 4:return 4;\nbreak;\ncase 5:return 11;\nbreak;\ncase 6:return 12;\nbreak;\ncase 7:return 13;\nbreak;\ncase 8:return 14;\nbreak;\ncase 9:return ':';\nbreak;\ncase 10:return 6;\nbreak;\ncase 11:return 'INVALID';\nbreak;\n}\n},\nrules: [/^(?:[\\n]+)/i,/^(?:\\s+)/i,/^(?:#[^\\n]*)/i,/^(?:%[^\\n]*)/i,/^(?:journey\\b)/i,/^(?:title\\s[^#\\n;]+)/i,/^(?:section\\s[^#:\\n;]+)/i,/^(?:[^#:\\n;]+)/i,/^(?::[^#\\n;]+)/i,/^(?::)/i,/^(?:$)/i,/^(?:.)/i],\nconditions: {\"INITIAL\":{\"rules\":[0,1,2,3,4,5,6,7,8,9,10,11],\"inclusive\":true}}\n});\nreturn lexer;\n})();\nparser.lexer = lexer;\nfunction Parser () {\n this.yy = {};\n}\nParser.prototype = parser;parser.Parser = Parser;\nreturn new Parser;\n})();\n\n\nif (typeof require !== 'undefined' && typeof exports !== 'undefined') {\nexports.parser = parser;\nexports.Parser = parser.Parser;\nexports.parse = function () { return parser.parse.apply(parser, arguments); };\nexports.main = function commonjsMain (args) {\n if (!args[1]) {\n console.log('Usage: '+args[0]+' FILE');\n process.exit(1);\n }\n var source = require('fs').readFileSync(require('path').normalize(args[1]), \"utf8\");\n return exports.parser.parse(source);\n};\nif (typeof module !== 'undefined' && require.main === module) {\n exports.main(process.argv.slice(1));\n}\n}","import { arc as d3arc } from 'd3';\n\nexport const drawRect = function(elem, rectData) {\n const rectElem = elem.append('rect');\n rectElem.attr('x', rectData.x);\n rectElem.attr('y', rectData.y);\n rectElem.attr('fill', rectData.fill);\n rectElem.attr('stroke', rectData.stroke);\n rectElem.attr('width', rectData.width);\n rectElem.attr('height', rectData.height);\n rectElem.attr('rx', rectData.rx);\n rectElem.attr('ry', rectData.ry);\n\n if (typeof rectData.class !== 'undefined') {\n rectElem.attr('class', rectData.class);\n }\n\n return rectElem;\n};\n\nexport const drawFace = function(element, faceData) {\n const radius = 15;\n const circleElement = element\n .append('circle')\n .attr('cx', faceData.cx)\n .attr('cy', faceData.cy)\n .attr('fill', '#FFF8DC')\n .attr('stroke', '#999')\n .attr('r', radius)\n .attr('stroke-width', 2)\n .attr('overflow', 'visible');\n\n const face = element.append('g');\n\n //left eye\n face\n .append('circle')\n .attr('cx', faceData.cx - radius / 3)\n .attr('cy', faceData.cy - radius / 3)\n .attr('r', 1.5)\n .attr('stroke-width', 2)\n .attr('fill', '#666')\n .attr('stroke', '#666');\n\n //right eye\n face\n .append('circle')\n .attr('cx', faceData.cx + radius / 3)\n .attr('cy', faceData.cy - radius / 3)\n .attr('r', 1.5)\n .attr('stroke-width', 2)\n .attr('fill', '#666')\n .attr('stroke', '#666');\n\n function smile(face) {\n const arc = d3arc()\n .startAngle(Math.PI / 2)\n .endAngle(3 * (Math.PI / 2))\n .innerRadius(radius / 2)\n .outerRadius(radius / 2.2);\n //mouth\n face\n .append('path')\n .attr('d', arc)\n .attr('transform', 'translate(' + faceData.cx + ',' + (faceData.cy + 2) + ')');\n }\n\n function sad(face) {\n const arc = d3arc()\n .startAngle((3 * Math.PI) / 2)\n .endAngle(5 * (Math.PI / 2))\n .innerRadius(radius / 2)\n .outerRadius(radius / 2.2);\n //mouth\n face\n .append('path')\n .attr('d', arc)\n .attr('transform', 'translate(' + faceData.cx + ',' + (faceData.cy + 7) + ')');\n }\n\n function ambivalent(face) {\n face\n .append('line')\n .attr('stroke', 2)\n .attr('x1', faceData.cx - 5)\n .attr('y1', faceData.cy + 7)\n .attr('x2', faceData.cx + 5)\n .attr('y2', faceData.cy + 7)\n .attr('class', 'task-line')\n .attr('stroke-width', '1px')\n .attr('stroke', '#666');\n }\n\n if (faceData.score > 3) {\n smile(face);\n } else if (faceData.score < 3) {\n sad(face);\n } else {\n ambivalent(face);\n }\n\n return circleElement;\n};\n\nexport const drawCircle = function(element, circleData) {\n const circleElement = element.append('circle');\n circleElement.attr('cx', circleData.cx);\n circleElement.attr('cy', circleData.cy);\n circleElement.attr('fill', circleData.fill);\n circleElement.attr('stroke', circleData.stroke);\n circleElement.attr('r', circleData.r);\n\n if (typeof circleElement.class !== 'undefined') {\n circleElement.attr('class', circleElement.class);\n }\n\n if (typeof circleData.title !== 'undefined') {\n circleElement.append('title').text(circleData.title);\n }\n\n return circleElement;\n};\n\nexport const drawText = function(elem, textData) {\n // Remove and ignore br:s\n const nText = textData.text.replace(/
/gi, ' ');\n\n const textElem = elem.append('text');\n textElem.attr('x', textData.x);\n textElem.attr('y', textData.y);\n textElem.attr('fill', textData.fill);\n textElem.style('text-anchor', textData.anchor);\n\n if (typeof textData.class !== 'undefined') {\n textElem.attr('class', textData.class);\n }\n\n const span = textElem.append('tspan');\n span.attr('x', textData.x + textData.textMargin * 2);\n span.text(nText);\n\n return textElem;\n};\n\nexport const drawLabel = function(elem, txtObject) {\n function genPoints(x, y, width, height, cut) {\n return (\n x +\n ',' +\n y +\n ' ' +\n (x + width) +\n ',' +\n y +\n ' ' +\n (x + width) +\n ',' +\n (y + height - cut) +\n ' ' +\n (x + width - cut * 1.2) +\n ',' +\n (y + height) +\n ' ' +\n x +\n ',' +\n (y + height)\n );\n }\n const polygon = elem.append('polygon');\n polygon.attr('points', genPoints(txtObject.x, txtObject.y, 50, 20, 7));\n polygon.attr('class', 'labelBox');\n\n txtObject.y = txtObject.y + txtObject.labelMargin;\n txtObject.x = txtObject.x + 0.5 * txtObject.labelMargin;\n drawText(elem, txtObject);\n};\n\nexport const drawSection = function(elem, section, conf) {\n const g = elem.append('g');\n\n const rect = getNoteRect();\n rect.x = section.x;\n rect.y = section.y;\n rect.fill = section.fill;\n rect.width = conf.width;\n rect.height = conf.height;\n rect.class = 'journey-section';\n rect.rx = 3;\n rect.ry = 3;\n drawRect(g, rect);\n\n _drawTextCandidateFunc(conf)(\n section.text,\n g,\n rect.x,\n rect.y,\n rect.width,\n rect.height,\n { class: 'journey-section' },\n conf,\n section.colour\n );\n};\n\nlet taskCount = -1;\n/**\n * Draws an actor in the diagram with the attaced line\n * @param elem The HTML element\n * @param task The task to render\n * @param conf The global configuration\n */\nexport const drawTask = function(elem, task, conf) {\n const center = task.x + conf.width / 2;\n const g = elem.append('g');\n taskCount++;\n const maxHeight = 300 + 5 * 30;\n g.append('line')\n .attr('id', 'task' + taskCount)\n .attr('x1', center)\n .attr('y1', task.y)\n .attr('x2', center)\n .attr('y2', maxHeight)\n .attr('class', 'task-line')\n .attr('stroke-width', '1px')\n .attr('stroke-dasharray', '4 2')\n .attr('stroke', '#666');\n\n drawFace(g, {\n cx: center,\n cy: 300 + (5 - task.score) * 30,\n score: task.score\n });\n\n const rect = getNoteRect();\n rect.x = task.x;\n rect.y = task.y;\n rect.fill = task.fill;\n rect.width = conf.width;\n rect.height = conf.height;\n rect.class = 'task';\n rect.rx = 3;\n rect.ry = 3;\n drawRect(g, rect);\n\n let xPos = task.x + 14;\n task.people.forEach(person => {\n const colour = task.actors[person];\n\n const circle = {\n cx: xPos,\n cy: task.y,\n r: 7,\n fill: colour,\n stroke: '#000',\n title: person\n };\n\n drawCircle(g, circle);\n xPos += 10;\n });\n\n _drawTextCandidateFunc(conf)(\n task.task,\n g,\n rect.x,\n rect.y,\n rect.width,\n rect.height,\n { class: 'task' },\n conf,\n task.colour\n );\n};\n\n/**\n * Draws a background rectangle\n * @param elem The html element\n * @param bounds The bounds of the drawing\n */\nexport const drawBackgroundRect = function(elem, bounds) {\n const rectElem = drawRect(elem, {\n x: bounds.startx,\n y: bounds.starty,\n width: bounds.stopx - bounds.startx,\n height: bounds.stopy - bounds.starty,\n fill: bounds.fill,\n class: 'rect'\n });\n rectElem.lower();\n};\n\nexport const getTextObj = function() {\n return {\n x: 0,\n y: 0,\n fill: undefined,\n 'text-anchor': 'start',\n width: 100,\n height: 100,\n textMargin: 0,\n rx: 0,\n ry: 0\n };\n};\n\nexport const getNoteRect = function() {\n return {\n x: 0,\n y: 0,\n width: 100,\n anchor: 'start',\n height: 100,\n rx: 0,\n ry: 0\n };\n};\n\nconst _drawTextCandidateFunc = (function() {\n function byText(content, g, x, y, width, height, textAttrs, colour) {\n const text = g\n .append('text')\n .attr('x', x + width / 2)\n .attr('y', y + height / 2 + 5)\n .style('font-color', colour)\n .style('text-anchor', 'middle')\n .text(content);\n _setTextAttrs(text, textAttrs);\n }\n\n function byTspan(content, g, x, y, width, height, textAttrs, conf, colour) {\n const { taskFontSize, taskFontFamily } = conf;\n\n const lines = content.split(/
/gi);\n for (let i = 0; i < lines.length; i++) {\n const dy = i * taskFontSize - (taskFontSize * (lines.length - 1)) / 2;\n const text = g\n .append('text')\n .attr('x', x + width / 2)\n .attr('y', y)\n .attr('fill', colour)\n .style('text-anchor', 'middle')\n .style('font-size', taskFontSize)\n .style('font-family', taskFontFamily);\n text\n .append('tspan')\n .attr('x', x + width / 2)\n .attr('dy', dy)\n .text(lines[i]);\n\n text\n .attr('y', y + height / 2.0)\n .attr('dominant-baseline', 'central')\n .attr('alignment-baseline', 'central');\n\n _setTextAttrs(text, textAttrs);\n }\n }\n\n function byFo(content, g, x, y, width, height, textAttrs, conf, colour) {\n const body = g.append('switch');\n const f = body\n .append('foreignObject')\n .attr('x', x)\n .attr('y', y)\n .attr('width', width)\n .attr('height', height)\n .attr('position', 'fixed');\n\n const text = f\n .append('div')\n .style('display', 'table')\n .style('height', '100%')\n .style('width', '100%');\n\n text\n .append('div')\n .style('display', 'table-cell')\n .style('text-align', 'center')\n .style('vertical-align', 'middle')\n .style('color', colour)\n .text(content);\n\n byTspan(content, body, x, y, width, height, textAttrs, conf);\n _setTextAttrs(text, textAttrs);\n }\n\n function _setTextAttrs(toText, fromTextAttrsDict) {\n for (const key in fromTextAttrsDict) {\n if (key in fromTextAttrsDict) {\n // eslint-disable-line\n // noinspection JSUnfilteredForInLoop\n toText.attr(key, fromTextAttrsDict[key]);\n }\n }\n }\n\n return function(conf) {\n return conf.textPlacement === 'fo' ? byFo : conf.textPlacement === 'old' ? byText : byTspan;\n };\n})();\n\nconst initGraphics = function(graphics) {\n graphics\n .append('defs')\n .append('marker')\n .attr('id', 'arrowhead')\n .attr('refX', 5)\n .attr('refY', 2)\n .attr('markerWidth', 6)\n .attr('markerHeight', 4)\n .attr('orient', 'auto')\n .append('path')\n .attr('d', 'M 0,0 V 4 L6,2 Z'); // this is actual shape for arrowhead\n};\n\nexport default {\n drawRect,\n drawCircle,\n drawSection,\n drawText,\n drawLabel,\n drawTask,\n drawBackgroundRect,\n getTextObj,\n getNoteRect,\n initGraphics\n};\n","import moment from 'moment-mini';\n//\nexport const LEVELS = {\n debug: 1,\n info: 2,\n warn: 3,\n error: 4,\n fatal: 5\n};\n\nexport const logger = {\n debug: () => {},\n info: () => {},\n warn: () => {},\n error: () => {},\n fatal: () => {}\n};\n\nexport const setLogLevel = function(level) {\n logger.trace = () => {};\n logger.debug = () => {};\n logger.info = () => {};\n logger.warn = () => {};\n logger.error = () => {};\n logger.fatal = () => {};\n if (level <= LEVELS.fatal) {\n logger.fatal = console.error\n ? console.error.bind(console, format('FATAL'), 'color: orange')\n : console.log.bind(console, '\\x1b[35m', format('FATAL'));\n }\n if (level <= LEVELS.error) {\n logger.error = console.error\n ? console.error.bind(console, format('ERROR'), 'color: orange')\n : console.log.bind(console, '\\x1b[31m', format('ERROR'));\n }\n if (level <= LEVELS.warn) {\n logger.warn = console.warn\n ? console.warn.bind(console, format('WARN'), 'color: orange')\n : console.log.bind(console, `\\x1b[33m`, format('WARN'));\n }\n if (level <= LEVELS.info) {\n logger.info = console.info\n ? // ? console.info.bind(console, '\\x1b[34m', format('INFO'), 'color: blue')\n console.info.bind(console, format('INFO'), 'color: lightblue')\n : console.log.bind(console, '\\x1b[34m', format('INFO'));\n }\n if (level <= LEVELS.debug) {\n logger.debug = console.debug\n ? console.debug.bind(console, format('DEBUG'), 'color: lightgreen')\n : console.log.bind(console, '\\x1b[32m', format('DEBUG'));\n }\n};\n\nconst format = level => {\n const time = moment().format('ss.SSS');\n return `%c${time} : ${level} : `;\n};\n","/**\n * Web page integration module for the mermaid framework. It uses the mermaidAPI for mermaid functionality and to render\n * the diagrams to svg code.\n */\n// import { decode } from 'he';\nimport decode from 'entity-decode/browser';\nimport mermaidAPI from './mermaidAPI';\nimport { logger } from './logger';\n/**\n * ## init\n * Function that goes through the document to find the chart definitions in there and render them.\n *\n * The function tags the processed attributes with the attribute data-processed and ignores found elements with the\n * attribute already set. This way the init function can be triggered several times.\n *\n * Optionally, `init` can accept in the second argument one of the following:\n * - a DOM Node\n * - an array of DOM nodes (as would come from a jQuery selector)\n * - a W3C selector, a la `.mermaid`\n *\n * ```mermaid\n * graph LR;\n * a(Find elements)-->b{Processed}\n * b-->|Yes|c(Leave element)\n * b-->|No |d(Transform)\n * ```\n * Renders the mermaid diagrams\n * @param nodes a css selector or an array of nodes\n */\nconst init = function() {\n const conf = mermaidAPI.getConfig();\n logger.debug('Starting rendering diagrams');\n let nodes;\n if (arguments.length >= 2) {\n /*! sequence config was passed as #1 */\n if (typeof arguments[0] !== 'undefined') {\n mermaid.sequenceConfig = arguments[0];\n }\n\n nodes = arguments[1];\n } else {\n nodes = arguments[0];\n }\n\n // if last argument is a function this is the callback function\n let callback;\n if (typeof arguments[arguments.length - 1] === 'function') {\n callback = arguments[arguments.length - 1];\n logger.debug('Callback function found');\n } else {\n if (typeof conf.mermaid !== 'undefined') {\n if (typeof conf.mermaid.callback === 'function') {\n callback = conf.mermaid.callback;\n logger.debug('Callback function found');\n } else {\n logger.debug('No Callback function found');\n }\n }\n }\n nodes =\n nodes === undefined\n ? document.querySelectorAll('.mermaid')\n : typeof nodes === 'string'\n ? document.querySelectorAll(nodes)\n : nodes instanceof window.Node\n ? [nodes]\n : nodes; // Last case - sequence config was passed pick next\n\n logger.debug('Start On Load before: ' + mermaid.startOnLoad);\n if (typeof mermaid.startOnLoad !== 'undefined') {\n logger.debug('Start On Load inner: ' + mermaid.startOnLoad);\n mermaidAPI.initialize({ startOnLoad: mermaid.startOnLoad });\n }\n\n if (typeof mermaid.ganttConfig !== 'undefined') {\n mermaidAPI.initialize({ gantt: mermaid.ganttConfig });\n }\n\n let txt;\n\n for (let i = 0; i < nodes.length; i++) {\n const element = nodes[i];\n\n /*! Check if previously processed */\n if (!element.getAttribute('data-processed')) {\n element.setAttribute('data-processed', true);\n } else {\n continue;\n }\n\n const id = `mermaid-${Date.now()}`;\n\n // Fetch the graph definition including tags\n txt = element.innerHTML;\n\n // transforms the html to pure text\n txt = decode(txt)\n .trim()\n .replace(/
/gi, '
');\n\n mermaidAPI.render(\n id,\n txt,\n (svgCode, bindFunctions) => {\n element.innerHTML = svgCode;\n if (typeof callback !== 'undefined') {\n callback(id);\n }\n if (bindFunctions) bindFunctions(element);\n },\n element\n );\n }\n};\n\nconst initialize = function(config) {\n if (typeof config.mermaid !== 'undefined') {\n if (typeof config.mermaid.startOnLoad !== 'undefined') {\n mermaid.startOnLoad = config.mermaid.startOnLoad;\n }\n if (typeof config.mermaid.htmlLabels !== 'undefined') {\n mermaid.htmlLabels = config.mermaid.htmlLabels;\n }\n }\n mermaidAPI.initialize(config);\n logger.debug('Initializing mermaid ');\n};\n\n/**\n * ##contentLoaded\n * Callback function that is called when page is loaded. This functions fetches configuration for mermaid rendering and\n * calls init for rendering the mermaid diagrams on the page.\n */\nconst contentLoaded = function() {\n let config;\n\n if (mermaid.startOnLoad) {\n // No config found, do check API config\n config = mermaidAPI.getConfig();\n if (config.startOnLoad) {\n mermaid.init();\n }\n } else {\n if (typeof mermaid.startOnLoad === 'undefined') {\n logger.debug('In start, no config');\n config = mermaidAPI.getConfig();\n if (config.startOnLoad) {\n mermaid.init();\n }\n }\n }\n};\n\nif (typeof document !== 'undefined') {\n /*!\n * Wait for document loaded before starting the execution\n */\n window.addEventListener(\n 'load',\n function() {\n contentLoaded();\n },\n false\n );\n}\n\nconst mermaid = {\n startOnLoad: true,\n htmlLabels: true,\n\n mermaidAPI,\n parse: mermaidAPI.parse,\n render: mermaidAPI.render,\n\n init,\n initialize,\n\n contentLoaded\n};\n\nexport default mermaid;\n","/**\n * This is the api to be used when optionally handling the integration with the web page, instead of using the default integration provided by mermaid.js.\n *\n * The core of this api is the [**render**](https://github.com/knsv/mermaid/blob/master/docs/mermaidAPI.md#render) function which, given a graph\n * definition as text, renders the graph/diagram and returns an svg element for the graph.\n *\n * It is is then up to the user of the API to make use of the svg, either insert it somewhere in the page or do something completely different.\n *\n * In addition to the render function, a number of behavioral configuration options are available.\n *\n * @name mermaidAPI\n */\nimport { select } from 'd3';\nimport scope from 'scope-css';\nimport pkg from '../package.json';\nimport { setConfig, getConfig } from './config';\nimport { logger, setLogLevel } from './logger';\nimport utils from './utils';\nimport flowRenderer from './diagrams/flowchart/flowRenderer';\nimport flowRendererV2 from './diagrams/flowchart/flowRenderer-v2';\nimport flowParser from './diagrams/flowchart/parser/flow';\nimport flowDb from './diagrams/flowchart/flowDb';\nimport sequenceRenderer from './diagrams/sequence/sequenceRenderer';\nimport sequenceParser from './diagrams/sequence/parser/sequenceDiagram';\nimport sequenceDb from './diagrams/sequence/sequenceDb';\nimport ganttRenderer from './diagrams/gantt/ganttRenderer';\nimport ganttParser from './diagrams/gantt/parser/gantt';\nimport ganttDb from './diagrams/gantt/ganttDb';\nimport classRenderer from './diagrams/class/classRenderer';\nimport classParser from './diagrams/class/parser/classDiagram';\nimport classDb from './diagrams/class/classDb';\nimport stateRenderer from './diagrams/state/stateRenderer';\nimport stateRendererV2 from './diagrams/state/stateRenderer-v2';\nimport stateParser from './diagrams/state/parser/stateDiagram';\nimport stateDb from './diagrams/state/stateDb';\nimport gitGraphRenderer from './diagrams/git/gitGraphRenderer';\nimport gitGraphParser from './diagrams/git/parser/gitGraph';\nimport gitGraphAst from './diagrams/git/gitGraphAst';\nimport infoRenderer from './diagrams/info/infoRenderer';\nimport infoParser from './diagrams/info/parser/info';\nimport infoDb from './diagrams/info/infoDb';\nimport pieRenderer from './diagrams/pie/pieRenderer';\nimport pieParser from './diagrams/pie/parser/pie';\nimport pieDb from './diagrams/pie/pieDb';\nimport erDb from './diagrams/er/erDb';\nimport erParser from './diagrams/er/parser/erDiagram';\nimport erRenderer from './diagrams/er/erRenderer';\nimport journeyParser from './diagrams/user-journey/parser/journey';\nimport journeyDb from './diagrams/user-journey/journeyDb';\nimport journeyRenderer from './diagrams/user-journey/journeyRenderer';\n\nconst themes = {};\nfor (const themeName of ['default', 'forest', 'dark', 'neutral']) {\n themes[themeName] = require(`./themes/${themeName}/index.scss`);\n}\n\n/**\n * These are the default options which can be overridden with the initialization call like so:\n * **Example 1:**\n * \n * mermaid.initialize({\n * flowchart:{\n * htmlLabels: false\n * }\n * });\n *
\n *\n * **Example 2:**\n * \n * <script>\n * var config = {\n * startOnLoad:true,\n * flowchart:{\n * useMaxWidth:true,\n * htmlLabels:true,\n * curve:'cardinal',\n * },\n *\n * securityLevel:'loose',\n * };\n * mermaid.initialize(config);\n * </script>\n *
\n * A summary of all options and their defaults is found [here](https://github.com/knsv/mermaid/blob/master/docs/mermaidAPI.md#mermaidapi-configuration-defaults). A description of each option follows below.\n *\n * @name Configuration\n */\nconst config = {\n /** theme , the CSS style sheet\n *\n * **theme** - Choose one of the built-in themes:\n * * default\n * * forest\n * * dark\n * * neutral.\n * To disable any pre-defined mermaid theme, use \"null\".\n *\n * **themeCSS** - Use your own CSS. This overrides **theme**.\n * \n * \"theme\": \"forest\",\n * \"themeCSS\": \".node rect { fill: red; }\"\n *
\n */\n theme: 'default',\n themeCSS: undefined,\n /* **maxTextSize** - The maximum allowed size of the users text diamgram */\n maxTextSize: 50000,\n\n /**\n * **fontFamily** The font to be used for the rendered diagrams. Default value is \\\"trebuchet ms\\\", verdana, arial;\n */\n fontFamily: '\"trebuchet ms\", verdana, arial;',\n\n /**\n * This option decides the amount of logging to be used.\n * * debug: 1\n * * info: 2\n * * warn: 3\n * * error: 4\n * * fatal: (**default**) 5\n */\n logLevel: 5,\n\n /**\n * Sets the level of trust to be used on the parsed diagrams.\n * * **strict**: (**default**) tags in text are encoded, click functionality is disabeled\n * * **loose**: tags in text are allowed, click functionality is enabled\n */\n securityLevel: 'strict',\n\n /**\n * This options controls whether or mermaid starts when the page loads\n * **Default value true**.\n */\n startOnLoad: true,\n\n /**\n * This options controls whether or arrow markers in html code will be absolute paths or\n * an anchor, #. This matters if you are using base tag settings.\n * **Default value false**.\n */\n arrowMarkerAbsolute: false,\n\n /**\n * The object containing configurations specific for flowcharts\n */\n flowchart: {\n /**\n * Flag for setting whether or not a html tag should be used for rendering labels\n * on the edges.\n * **Default value true**.\n */\n htmlLabels: true,\n\n /**\n * Defines the spacing between nodes on the same level (meaning horizontal spacing for\n * TB or BT graphs, and the vertical spacing for LR as well as RL graphs).\n * **Default value 50**.\n */\n nodeSpacing: 50,\n\n /**\n * Defines the spacing between nodes on different levels (meaning vertical spacing for\n * TB or BT graphs, and the horizontal spacing for LR as well as RL graphs).\n * **Default value 50**.\n */\n rankSpacing: 50,\n\n /**\n * How mermaid renders curves for flowcharts. Possible values are\n * * basis\n * * linear **default**\n * * cardinal\n */\n curve: 'linear',\n // Only used in new experimental rendering\n // repreesents the padding between the labels and the shape\n padding: 15\n },\n\n /**\n * The object containing configurations specific for sequence diagrams\n */\n sequence: {\n /**\n * margin to the right and left of the sequence diagram.\n * **Default value 50**.\n */\n diagramMarginX: 50,\n\n /**\n * margin to the over and under the sequence diagram.\n * **Default value 10**.\n */\n diagramMarginY: 10,\n\n /**\n * Margin between actors.\n * **Default value 50**.\n */\n actorMargin: 50,\n\n /**\n * Width of actor boxes\n * **Default value 150**.\n */\n width: 150,\n\n /**\n * Height of actor boxes\n * **Default value 65**.\n */\n height: 65,\n\n /**\n * Margin around loop boxes\n * **Default value 10**.\n */\n boxMargin: 10,\n\n /**\n * margin around the text in loop/alt/opt boxes\n * **Default value 5**.\n */\n boxTextMargin: 5,\n\n /**\n * margin around notes.\n * **Default value 10**.\n */\n noteMargin: 10,\n\n /**\n * Space between messages.\n * **Default value 35**.\n */\n messageMargin: 35,\n\n /**\n * Multiline message alignment. Possible values are:\n * * left\n * * center **default**\n * * right\n */\n messageAlign: 'center',\n\n /**\n * mirror actors under diagram.\n * **Default value true**.\n */\n mirrorActors: true,\n\n /**\n * Depending on css styling this might need adjustment.\n * Prolongs the edge of the diagram downwards.\n * **Default value 1**.\n */\n bottomMarginAdj: 1,\n\n /**\n * when this flag is set the height and width is set to 100% and is then scaling with the\n * available space if not the absolute space required is used.\n * **Default value true**.\n */\n useMaxWidth: true,\n\n /**\n * This will display arrows that start and begin at the same node as right angles, rather than a curve\n * **Default value false**.\n */\n rightAngles: false,\n /**\n * This will show the node numbers\n * **Default value false**.\n */\n showSequenceNumbers: false,\n /**\n * This sets the font size of the actor's description\n * **Default value 14**.\n */\n actorFontSize: 14,\n /**\n * This sets the font family of the actor's description\n * **Default value \"Open-Sans\", \"sans-serif\"**.\n */\n actorFontFamily: '\"Open-Sans\", \"sans-serif\"',\n /**\n * This sets the font size of actor-attached notes.\n * **Default value 14**.\n */\n noteFontSize: 14,\n /**\n * This sets the font family of actor-attached notes.\n * **Default value \"trebuchet ms\", verdana, arial**.\n */\n noteFontFamily: '\"trebuchet ms\", verdana, arial',\n /**\n * This sets the text alignment of actor-attached notes.\n * **Default value center**.\n */\n noteAlign: 'center',\n /**\n * This sets the font size of actor messages.\n * **Default value 16**.\n */\n messageFontSize: 16,\n /**\n * This sets the font family of actor messages.\n * **Default value \"trebuchet ms\", verdana, arial**.\n */\n messageFontFamily: '\"trebuchet ms\", verdana, arial'\n },\n\n /**\n * The object containing configurations specific for gantt diagrams*\n */\n gantt: {\n /**\n * Margin top for the text over the gantt diagram\n * **Default value 25**.\n */\n titleTopMargin: 25,\n\n /**\n * The height of the bars in the graph\n * **Default value 20**.\n */\n barHeight: 20,\n\n /**\n * The margin between the different activities in the gantt diagram.\n * **Default value 4**.\n */\n barGap: 4,\n\n /**\n * Margin between title and gantt diagram and between axis and gantt diagram.\n * **Default value 50**.\n */\n topPadding: 50,\n\n /**\n * The space allocated for the section name to the left of the activities.\n * **Default value 75**.\n */\n leftPadding: 75,\n\n /**\n * Vertical starting position of the grid lines.\n * **Default value 35**.\n */\n gridLineStartPadding: 35,\n\n /**\n * Font size ...\n * **Default value 11**.\n */\n fontSize: 11,\n\n /**\n * font family ...\n * **Default value '\"Open-Sans\", \"sans-serif\"'**.\n */\n fontFamily: '\"Open-Sans\", \"sans-serif\"',\n\n /**\n * The number of alternating section styles.\n * **Default value 4**.\n */\n numberSectionStyles: 4,\n\n /**\n * Datetime format of the axis. This might need adjustment to match your locale and preferences\n * **Default value '%Y-%m-%d'**.\n */\n axisFormat: '%Y-%m-%d'\n },\n /**\n * The object containing configurations specific for sequence diagrams\n */\n journey: {\n /**\n * margin to the right and left of the sequence diagram.\n * **Default value 50**.\n */\n diagramMarginX: 50,\n\n /**\n * margin to the over and under the sequence diagram.\n * **Default value 10**.\n */\n diagramMarginY: 10,\n\n /**\n * Margin between actors.\n * **Default value 50**.\n */\n actorMargin: 50,\n\n /**\n * Width of actor boxes\n * **Default value 150**.\n */\n width: 150,\n\n /**\n * Height of actor boxes\n * **Default value 65**.\n */\n height: 65,\n\n /**\n * Margin around loop boxes\n * **Default value 10**.\n */\n boxMargin: 10,\n\n /**\n * margin around the text in loop/alt/opt boxes\n * **Default value 5**.\n */\n boxTextMargin: 5,\n\n /**\n * margin around notes.\n * **Default value 10**.\n */\n noteMargin: 10,\n\n /**\n * Space between messages.\n * **Default value 35**.\n */\n messageMargin: 35,\n\n /**\n * Multiline message alignment. Possible values are:\n * * left\n * * center **default**\n * * right\n */\n messageAlign: 'center',\n\n /**\n * Depending on css styling this might need adjustment.\n * Prolongs the edge of the diagram downwards.\n * **Default value 1**.\n */\n bottomMarginAdj: 1,\n\n /**\n * when this flag is set the height and width is set to 100% and is then scaling with the\n * available space if not the absolute space required is used.\n * **Default value true**.\n */\n useMaxWidth: true,\n\n /**\n * This will display arrows that start and begin at the same node as right angles, rather than a curve\n * **Default value false**.\n */\n rightAngles: false\n },\n class: {},\n git: {},\n state: {\n dividerMargin: 10,\n sizeUnit: 5,\n padding: 8,\n textHeight: 10,\n titleShift: -15,\n noteMargin: 10,\n forkWidth: 70,\n forkHeight: 7,\n // Used\n miniPadding: 2,\n // Font size factor, this is used to guess the width of the edges labels before rendering by dagre\n // layout. This might need updating if/when switching font\n fontSizeFactor: 5.02,\n fontSize: 24,\n labelHeight: 16,\n edgeLengthFactor: '20',\n compositTitleSize: 35,\n radius: 5\n },\n\n /**\n * The object containing configurations specific for entity relationship diagrams\n */\n er: {\n /**\n * The amount of padding around the diagram as a whole so that embedded diagrams have margins, expressed in pixels\n */\n diagramPadding: 20,\n\n /**\n * Directional bias for layout of entities. Can be either 'TB', 'BT', 'LR', or 'RL',\n * where T = top, B = bottom, L = left, and R = right.\n */\n layoutDirection: 'TB',\n\n /**\n * The mimimum width of an entity box, expressed in pixels\n */\n minEntityWidth: 100,\n\n /**\n * The minimum height of an entity box, expressed in pixels\n */\n minEntityHeight: 75,\n\n /**\n * The minimum internal padding between the text in an entity box and the enclosing box borders, expressed in pixels\n */\n entityPadding: 15,\n\n /**\n * Stroke color of box edges and lines\n */\n stroke: 'gray',\n\n /**\n * Fill color of entity boxes\n */\n fill: 'honeydew',\n\n /**\n * Font size (expressed as an integer representing a number of pixels)\n */\n fontSize: 12\n }\n};\n\nsetLogLevel(config.logLevel);\nsetConfig(config);\n\nfunction parse(text) {\n const graphType = utils.detectType(text);\n let parser;\n\n logger.debug('Type ' + graphType);\n switch (graphType) {\n case 'git':\n parser = gitGraphParser;\n parser.parser.yy = gitGraphAst;\n break;\n case 'flowchart':\n flowDb.clear();\n parser = flowParser;\n parser.parser.yy = flowDb;\n break;\n case 'flowchart-v2':\n flowDb.clear();\n parser = flowParser;\n parser.parser.yy = flowDb;\n break;\n case 'sequence':\n parser = sequenceParser;\n parser.parser.yy = sequenceDb;\n break;\n case 'gantt':\n parser = ganttParser;\n parser.parser.yy = ganttDb;\n break;\n case 'class':\n parser = classParser;\n parser.parser.yy = classDb;\n break;\n case 'state':\n parser = stateParser;\n parser.parser.yy = stateDb;\n break;\n case 'stateDiagram':\n parser = stateParser;\n parser.parser.yy = stateDb;\n break;\n case 'info':\n logger.debug('info info info');\n parser = infoParser;\n parser.parser.yy = infoDb;\n break;\n case 'pie':\n logger.debug('pie');\n parser = pieParser;\n parser.parser.yy = pieDb;\n break;\n case 'er':\n logger.debug('er');\n parser = erParser;\n parser.parser.yy = erDb;\n break;\n case 'journey':\n logger.debug('Journey');\n parser = journeyParser;\n parser.parser.yy = journeyDb;\n break;\n }\n\n parser.parser.yy.parseError = (str, hash) => {\n const error = { str, hash };\n throw error;\n };\n\n parser.parse(text);\n}\n\nexport const encodeEntities = function(text) {\n let txt = text;\n\n txt = txt.replace(/style.*:\\S*#.*;/g, function(s) {\n const innerTxt = s.substring(0, s.length - 1);\n return innerTxt;\n });\n txt = txt.replace(/classDef.*:\\S*#.*;/g, function(s) {\n const innerTxt = s.substring(0, s.length - 1);\n return innerTxt;\n });\n\n txt = txt.replace(/#\\w+;/g, function(s) {\n const innerTxt = s.substring(1, s.length - 1);\n\n const isInt = /^\\+?\\d+$/.test(innerTxt);\n if (isInt) {\n return 'fl°°' + innerTxt + '¶ß';\n } else {\n return 'fl°' + innerTxt + '¶ß';\n }\n });\n\n return txt;\n};\n\nexport const decodeEntities = function(text) {\n let txt = text;\n\n txt = txt.replace(/fl°°/g, function() {\n return '';\n });\n txt = txt.replace(/fl°/g, function() {\n return '&';\n });\n txt = txt.replace(/¶ß/g, function() {\n return ';';\n });\n\n return txt;\n};\n/**\n * Function that renders an svg with a graph from a chart definition. Usage example below.\n *\n * ```js\n * mermaidAPI.initialize({\n * startOnLoad:true\n * });\n * $(function(){\n * const graphDefinition = 'graph TB\\na-->b';\n * const cb = function(svgGraph){\n * console.log(svgGraph);\n * };\n * mermaidAPI.render('id1',graphDefinition,cb);\n * });\n *```\n * @param id the id of the element to be rendered\n * @param txt the graph definition\n * @param cb callback which is called after rendering is finished with the svg code as inparam.\n * @param container selector to element in which a div with the graph temporarily will be inserted. In one is\n * provided a hidden div will be inserted in the body of the page instead. The element will be removed when rendering is\n * completed.\n */\nconst render = function(id, _txt, cb, container) {\n // Check the maximum allowed text size\n let txt = _txt;\n if (_txt.length > config.maxTextSize) {\n txt = 'graph TB;a[Maximum text size in diagram exceeded];style a fill:#faa';\n }\n\n if (typeof container !== 'undefined') {\n container.innerHTML = '';\n\n select(container)\n .append('div')\n .attr('id', 'd' + id)\n .attr('style', 'font-family: ' + config.fontFamily)\n .append('svg')\n .attr('id', id)\n .attr('width', '100%')\n .attr('xmlns', 'http://www.w3.org/2000/svg')\n .append('g');\n } else {\n const existingSvg = document.getElementById(id);\n if (existingSvg) {\n existingSvg.remove();\n }\n const element = document.querySelector('#' + 'd' + id);\n if (element) {\n element.innerHTML = '';\n }\n\n select('body')\n .append('div')\n .attr('id', 'd' + id)\n .append('svg')\n .attr('id', id)\n .attr('width', '100%')\n .attr('xmlns', 'http://www.w3.org/2000/svg')\n .append('g');\n }\n\n window.txt = txt;\n txt = encodeEntities(txt);\n\n const element = select('#d' + id).node();\n const graphType = utils.detectType(txt);\n\n // insert inline style into svg\n const svg = element.firstChild;\n const firstChild = svg.firstChild;\n\n // pre-defined theme\n let style = themes[config.theme];\n if (style === undefined) {\n style = '';\n }\n\n // user provided theme CSS\n if (config.themeCSS !== undefined) {\n style += `\\n${config.themeCSS}`;\n }\n // user provided theme CSS\n if (config.fontFamily !== undefined) {\n style += `\\n:root { --mermaid-font-family: ${config.fontFamily}}`;\n }\n // user provided theme CSS\n if (config.altFontFamily !== undefined) {\n style += `\\n:root { --mermaid-alt-font-family: ${config.altFontFamily}}`;\n }\n\n // classDef\n if (graphType === 'flowchart' || graphType === 'flowchart-v2') {\n const classes = flowRenderer.getClasses(txt);\n for (const className in classes) {\n style += `\\n.${className} > * { ${classes[className].styles.join(\n ' !important; '\n )} !important; }`;\n if (classes[className].textStyles) {\n style += `\\n.${className} tspan { ${classes[className].textStyles.join(\n ' !important; '\n )} !important; }`;\n }\n }\n }\n\n const style1 = document.createElement('style');\n style1.innerHTML = scope(style, `#${id}`);\n svg.insertBefore(style1, firstChild);\n\n const style2 = document.createElement('style');\n const cs = window.getComputedStyle(svg);\n style2.innerHTML = `#${id} {\n color: ${cs.color};\n font: ${cs.font};\n }`;\n svg.insertBefore(style2, firstChild);\n\n switch (graphType) {\n case 'git':\n config.flowchart.arrowMarkerAbsolute = config.arrowMarkerAbsolute;\n gitGraphRenderer.setConf(config.git);\n gitGraphRenderer.draw(txt, id, false);\n break;\n case 'flowchart':\n config.flowchart.arrowMarkerAbsolute = config.arrowMarkerAbsolute;\n flowRenderer.setConf(config.flowchart);\n flowRenderer.draw(txt, id, false);\n break;\n case 'flowchart-v2':\n config.flowchart.arrowMarkerAbsolute = config.arrowMarkerAbsolute;\n flowRendererV2.setConf(config.flowchart);\n flowRendererV2.draw(txt, id, false);\n break;\n case 'sequence':\n config.sequence.arrowMarkerAbsolute = config.arrowMarkerAbsolute;\n if (config.sequenceDiagram) {\n // backwards compatibility\n sequenceRenderer.setConf(Object.assign(config.sequence, config.sequenceDiagram));\n console.error(\n '`mermaid config.sequenceDiagram` has been renamed to `config.sequence`. Please update your mermaid config.'\n );\n } else {\n sequenceRenderer.setConf(config.sequence);\n }\n sequenceRenderer.draw(txt, id);\n break;\n case 'gantt':\n config.gantt.arrowMarkerAbsolute = config.arrowMarkerAbsolute;\n ganttRenderer.setConf(config.gantt);\n ganttRenderer.draw(txt, id);\n break;\n case 'class':\n config.class.arrowMarkerAbsolute = config.arrowMarkerAbsolute;\n classRenderer.setConf(config.class);\n classRenderer.draw(txt, id);\n break;\n case 'state':\n // config.class.arrowMarkerAbsolute = config.arrowMarkerAbsolute;\n stateRenderer.setConf(config.state);\n stateRenderer.draw(txt, id);\n break;\n case 'stateDiagram':\n // config.class.arrowMarkerAbsolute = config.arrowMarkerAbsolute;\n stateRendererV2.setConf(config.state);\n stateRendererV2.draw(txt, id);\n break;\n case 'info':\n config.class.arrowMarkerAbsolute = config.arrowMarkerAbsolute;\n infoRenderer.setConf(config.class);\n infoRenderer.draw(txt, id, pkg.version);\n break;\n case 'pie':\n config.class.arrowMarkerAbsolute = config.arrowMarkerAbsolute;\n pieRenderer.setConf(config.class);\n pieRenderer.draw(txt, id, pkg.version);\n break;\n case 'er':\n erRenderer.setConf(config.er);\n erRenderer.draw(txt, id, pkg.version);\n break;\n case 'journey':\n journeyRenderer.setConf(config.journey);\n journeyRenderer.draw(txt, id, pkg.version);\n break;\n }\n\n select(`[id=\"${id}\"]`)\n .selectAll('foreignobject > *')\n .attr('xmlns', 'http://www.w3.org/1999/xhtml');\n\n // if (config.arrowMarkerAbsolute) {\n // url =\n // window.location.protocol +\n // '//' +\n // window.location.host +\n // window.location.pathname +\n // window.location.search;\n // url = url.replace(/\\(/g, '\\\\(');\n // url = url.replace(/\\)/g, '\\\\)');\n // }\n\n // Fix for when the base tag is used\n let svgCode = select('#d' + id).node().innerHTML;\n\n if (!config.arrowMarkerAbsolute || config.arrowMarkerAbsolute === 'false') {\n svgCode = svgCode.replace(/marker-end=\"url\\(.*?#/g, 'marker-end=\"url(#', 'g');\n }\n\n svgCode = decodeEntities(svgCode);\n\n if (typeof cb !== 'undefined') {\n switch (graphType) {\n case 'flowchart':\n case 'flowchart-v2':\n cb(svgCode, flowDb.bindFunctions);\n break;\n case 'gantt':\n cb(svgCode, ganttDb.bindFunctions);\n break;\n case 'class':\n cb(svgCode, classDb.bindFunctions);\n break;\n default:\n cb(svgCode);\n }\n } else {\n logger.debug('CB = undefined!');\n }\n\n const node = select('#d' + id).node();\n if (node !== null && typeof node.remove === 'function') {\n select('#d' + id)\n .node()\n .remove();\n }\n\n return svgCode;\n};\n\nconst setConf = function(cnf) {\n // Top level initially mermaid, gflow, sequenceDiagram and gantt\n const lvl1Keys = Object.keys(cnf);\n for (let i = 0; i < lvl1Keys.length; i++) {\n if (typeof cnf[lvl1Keys[i]] === 'object' && cnf[lvl1Keys[i]] != null) {\n const lvl2Keys = Object.keys(cnf[lvl1Keys[i]]);\n\n for (let j = 0; j < lvl2Keys.length; j++) {\n logger.debug('Setting conf ', lvl1Keys[i], '-', lvl2Keys[j]);\n if (typeof config[lvl1Keys[i]] === 'undefined') {\n config[lvl1Keys[i]] = {};\n }\n logger.debug(\n 'Setting config: ' +\n lvl1Keys[i] +\n ' ' +\n lvl2Keys[j] +\n ' to ' +\n cnf[lvl1Keys[i]][lvl2Keys[j]]\n );\n config[lvl1Keys[i]][lvl2Keys[j]] = cnf[lvl1Keys[i]][lvl2Keys[j]];\n }\n } else {\n config[lvl1Keys[i]] = cnf[lvl1Keys[i]];\n }\n }\n};\n\nfunction initialize(options) {\n logger.debug('Initializing mermaidAPI ', pkg.version);\n\n // Update default config with options supplied at initialization\n if (typeof options === 'object') {\n setConf(options);\n }\n setConfig(config);\n setLogLevel(config.logLevel);\n}\n\n// function getConfig () {\n// console.warn('get config')\n// return config\n// }\n\nconst mermaidAPI = {\n render,\n parse,\n initialize,\n getConfig\n};\n\nexport default mermaidAPI;\n/**\n * ## mermaidAPI configuration defaults\n * \n *\n * <script>\n * var config = {\n * theme:'default',\n * logLevel:'fatal',\n * securityLevel:'strict',\n * startOnLoad:true,\n * arrowMarkerAbsolute:false,\n *\n * flowchart:{\n * htmlLabels:true,\n * curve:'linear',\n * },\n * sequence:{\n * diagramMarginX:50,\n * diagramMarginY:10,\n * actorMargin:50,\n * width:150,\n * height:65,\n * boxMargin:10,\n * boxTextMargin:5,\n * noteMargin:10,\n * messageMargin:35,\n * messageAlign:'center',\n * mirrorActors:true,\n * bottomMarginAdj:1,\n * useMaxWidth:true,\n * rightAngles:false,\n * showSequenceNumbers:false,\n * },\n * gantt:{\n * titleTopMargin:25,\n * barHeight:20,\n * barGap:4,\n * topPadding:50,\n * leftPadding:75,\n * gridLineStartPadding:35,\n * fontSize:11,\n * fontFamily:'\"Open-Sans\", \"sans-serif\"',\n * numberSectionStyles:4,\n * axisFormat:'%Y-%m-%d',\n * }\n * };\n * mermaid.initialize(config);\n * </script>\n *
\n */\n","var map = {\n\t\"./dark/index.scss\": \"./src/themes/dark/index.scss\",\n\t\"./default/index.scss\": \"./src/themes/default/index.scss\",\n\t\"./forest/index.scss\": \"./src/themes/forest/index.scss\",\n\t\"./neutral/index.scss\": \"./src/themes/neutral/index.scss\"\n};\n\n\nfunction webpackContext(req) {\n\tvar id = webpackContextResolve(req);\n\treturn __webpack_require__(id);\n}\nfunction webpackContextResolve(req) {\n\tif(!__webpack_require__.o(map, req)) {\n\t\tvar e = new Error(\"Cannot find module '\" + req + \"'\");\n\t\te.code = 'MODULE_NOT_FOUND';\n\t\tthrow e;\n\t}\n\treturn map[req];\n}\nwebpackContext.keys = function webpackContextKeys() {\n\treturn Object.keys(map);\n};\nwebpackContext.resolve = webpackContextResolve;\nmodule.exports = webpackContext;\nwebpackContext.id = \"./src/themes sync recursive ^\\\\.\\\\/.*\\\\/index\\\\.scss$\";","// css-to-string-loader: transforms styles from css-loader to a string output\n\n// Get the styles\nvar styles = require(\"!!../../../node_modules/css-loader/dist/cjs.js!../../../node_modules/sass-loader/dist/cjs.js!./index.scss\");\n\nif (typeof styles === 'string') {\n // Return an existing string\n module.exports = styles;\n} else {\n // Call the custom toString method from css-loader module\n module.exports = styles.toString();\n}","// css-to-string-loader: transforms styles from css-loader to a string output\n\n// Get the styles\nvar styles = require(\"!!../../../node_modules/css-loader/dist/cjs.js!../../../node_modules/sass-loader/dist/cjs.js!./index.scss\");\n\nif (typeof styles === 'string') {\n // Return an existing string\n module.exports = styles;\n} else {\n // Call the custom toString method from css-loader module\n module.exports = styles.toString();\n}","// css-to-string-loader: transforms styles from css-loader to a string output\n\n// Get the styles\nvar styles = require(\"!!../../../node_modules/css-loader/dist/cjs.js!../../../node_modules/sass-loader/dist/cjs.js!./index.scss\");\n\nif (typeof styles === 'string') {\n // Return an existing string\n module.exports = styles;\n} else {\n // Call the custom toString method from css-loader module\n module.exports = styles.toString();\n}","// css-to-string-loader: transforms styles from css-loader to a string output\n\n// Get the styles\nvar styles = require(\"!!../../../node_modules/css-loader/dist/cjs.js!../../../node_modules/sass-loader/dist/cjs.js!./index.scss\");\n\nif (typeof styles === 'string') {\n // Return an existing string\n module.exports = styles;\n} else {\n // Call the custom toString method from css-loader module\n module.exports = styles.toString();\n}","import {\n curveBasis,\n curveBasisClosed,\n curveBasisOpen,\n curveLinear,\n curveLinearClosed,\n curveMonotoneX,\n curveMonotoneY,\n curveNatural,\n curveStep,\n curveStepAfter,\n curveStepBefore\n} from 'd3';\nimport { logger } from './logger';\nimport { sanitizeUrl } from '@braintree/sanitize-url';\n\n// Effectively an enum of the supported curve types, accessible by name\nconst d3CurveTypes = {\n curveBasis: curveBasis,\n curveBasisClosed: curveBasisClosed,\n curveBasisOpen: curveBasisOpen,\n curveLinear: curveLinear,\n curveLinearClosed: curveLinearClosed,\n curveMonotoneX: curveMonotoneX,\n curveMonotoneY: curveMonotoneY,\n curveNatural: curveNatural,\n curveStep: curveStep,\n curveStepAfter: curveStepAfter,\n curveStepBefore: curveStepBefore\n};\n\n/**\n * @function detectType\n * Detects the type of the graph text.\n * ```mermaid\n * graph LR\n * a-->b\n * b-->c\n * c-->d\n * d-->e\n * e-->f\n * f-->g\n * g-->h\n * ```\n *\n * @param {string} text The text defining the graph\n * @returns {string} A graph definition key\n */\nexport const detectType = function(text) {\n text = text.replace(/^\\s*%%.*\\n/g, '\\n');\n logger.debug('Detecting diagram type based on the text ' + text);\n if (text.match(/^\\s*sequenceDiagram/)) {\n return 'sequence';\n }\n\n if (text.match(/^\\s*gantt/)) {\n return 'gantt';\n }\n\n if (text.match(/^\\s*classDiagram/)) {\n return 'class';\n }\n if (text.match(/^\\s*stateDiagram-v2/)) {\n return 'stateDiagram';\n }\n\n if (text.match(/^\\s*stateDiagram/)) {\n return 'state';\n }\n\n if (text.match(/^\\s*gitGraph/)) {\n return 'git';\n }\n if (text.match(/^\\s*flowchart/)) {\n return 'flowchart-v2';\n }\n\n if (text.match(/^\\s*info/)) {\n return 'info';\n }\n if (text.match(/^\\s*pie/)) {\n return 'pie';\n }\n\n if (text.match(/^\\s*erDiagram/)) {\n return 'er';\n }\n\n if (text.match(/^\\s*journey/)) {\n return 'journey';\n }\n\n return 'flowchart';\n};\n\n/**\n * @function isSubstringInArray\n * Detects whether a substring in present in a given array\n * @param {string} str The substring to detect\n * @param {array} arr The array to search\n * @returns {number} the array index containing the substring or -1 if not present\n **/\nexport const isSubstringInArray = function(str, arr) {\n for (let i = 0; i < arr.length; i++) {\n if (arr[i].match(str)) return i;\n }\n return -1;\n};\n\nexport const interpolateToCurve = (interpolate, defaultCurve) => {\n if (!interpolate) {\n return defaultCurve;\n }\n const curveName = `curve${interpolate.charAt(0).toUpperCase() + interpolate.slice(1)}`;\n return d3CurveTypes[curveName] || defaultCurve;\n};\n\nexport const formatUrl = (linkStr, config) => {\n let url = linkStr.trim();\n\n if (url) {\n if (config.securityLevel !== 'loose') {\n return sanitizeUrl(url);\n }\n\n return url;\n }\n};\n\nconst distance = (p1, p2) =>\n p1 && p2 ? Math.sqrt(Math.pow(p2.x - p1.x, 2) + Math.pow(p2.y - p1.y, 2)) : 0;\n\nconst traverseEdge = points => {\n let prevPoint;\n let totalDistance = 0;\n\n points.forEach(point => {\n totalDistance += distance(point, prevPoint);\n prevPoint = point;\n });\n\n // Traverse half of total distance along points\n const distanceToLabel = totalDistance / 2;\n\n let remainingDistance = distanceToLabel;\n let center;\n prevPoint = undefined;\n points.forEach(point => {\n if (prevPoint && !center) {\n const vectorDistance = distance(point, prevPoint);\n if (vectorDistance < remainingDistance) {\n remainingDistance -= vectorDistance;\n } else {\n // The point is remainingDistance from prevPoint in the vector between prevPoint and point\n // Calculate the coordinates\n const distanceRatio = remainingDistance / vectorDistance;\n if (distanceRatio <= 0) center = prevPoint;\n if (distanceRatio >= 1) center = { x: point.x, y: point.y };\n if (distanceRatio > 0 && distanceRatio < 1) {\n center = {\n x: (1 - distanceRatio) * prevPoint.x + distanceRatio * point.x,\n y: (1 - distanceRatio) * prevPoint.y + distanceRatio * point.y\n };\n }\n }\n }\n prevPoint = point;\n });\n return center;\n};\n\nconst calcLabelPosition = points => {\n const p = traverseEdge(points);\n return p;\n};\n\nconst calcCardinalityPosition = (isRelationTypePresent, points, initialPosition) => {\n let prevPoint;\n let totalDistance = 0; // eslint-disable-line\n if (points[0] !== initialPosition) {\n points = points.reverse();\n }\n points.forEach(point => {\n totalDistance += distance(point, prevPoint);\n prevPoint = point;\n });\n\n // Traverse only 25 total distance along points to find cardinality point\n const distanceToCardinalityPoint = 25;\n\n let remainingDistance = distanceToCardinalityPoint;\n let center;\n prevPoint = undefined;\n points.forEach(point => {\n if (prevPoint && !center) {\n const vectorDistance = distance(point, prevPoint);\n if (vectorDistance < remainingDistance) {\n remainingDistance -= vectorDistance;\n } else {\n // The point is remainingDistance from prevPoint in the vector between prevPoint and point\n // Calculate the coordinates\n const distanceRatio = remainingDistance / vectorDistance;\n if (distanceRatio <= 0) center = prevPoint;\n if (distanceRatio >= 1) center = { x: point.x, y: point.y };\n if (distanceRatio > 0 && distanceRatio < 1) {\n center = {\n x: (1 - distanceRatio) * prevPoint.x + distanceRatio * point.x,\n y: (1 - distanceRatio) * prevPoint.y + distanceRatio * point.y\n };\n }\n }\n }\n prevPoint = point;\n });\n // if relation is present (Arrows will be added), change cardinality point off-set distance (d)\n let d = isRelationTypePresent ? 10 : 5;\n //Calculate Angle for x and y axis\n let angle = Math.atan2(points[0].y - center.y, points[0].x - center.x);\n let cardinalityPosition = { x: 0, y: 0 };\n //Calculation cardinality position using angle, center point on the line/curve but pendicular and with offset-distance\n cardinalityPosition.x = Math.sin(angle) * d + (points[0].x + center.x) / 2;\n cardinalityPosition.y = -Math.cos(angle) * d + (points[0].y + center.y) / 2;\n return cardinalityPosition;\n};\n\nexport const getStylesFromArray = arr => {\n let style = '';\n let labelStyle = '';\n\n for (let i = 0; i < arr.length; i++) {\n if (typeof arr[i] !== 'undefined') {\n // add text properties to label style definition\n if (arr[i].startsWith('color:') || arr[i].startsWith('text-align:')) {\n labelStyle = labelStyle + arr[i] + ';';\n } else {\n style = style + arr[i] + ';';\n }\n }\n }\n\n return { style: style, labelStyle: labelStyle };\n};\n\nlet cnt = 0;\nexport const generateId = () => {\n cnt++;\n return (\n 'id-' +\n Math.random()\n .toString(36)\n .substr(2, 12) +\n '-' +\n cnt\n );\n};\n\nexport default {\n detectType,\n isSubstringInArray,\n interpolateToCurve,\n calcLabelPosition,\n calcCardinalityPosition,\n formatUrl,\n getStylesFromArray,\n generateId\n};\n","module.exports = require(\"@braintree/sanitize-url\");","module.exports = require(\"d3\");","module.exports = require(\"dagre\");","module.exports = require(\"dagre-d3\");","module.exports = require(\"dagre-d3/lib/label/add-html-label.js\");","module.exports = require(\"entity-decode/browser\");","module.exports = require(\"graphlib\");","module.exports = require(\"moment-mini\");","module.exports = require(\"scope-css\");"],"sourceRoot":""}