1 line
50 KiB
Plaintext
1 line
50 KiB
Plaintext
{"version":3,"file":"flowchart-elk-definition-c9fc5e04.js","sources":["../src/diagrams/flowchart/elk/render-utils.ts","../src/diagrams/flowchart/elk/flowRenderer-elk.js","../src/diagrams/flowchart/elk/styles.ts","../src/diagrams/flowchart/elk/flowchart-elk-definition.ts"],"sourcesContent":["export interface TreeData {\n parentById: Record<string, string>;\n childrenById: Record<string, string[]>;\n}\n\nexport const findCommonAncestor = (id1: string, id2: string, treeData: TreeData) => {\n const { parentById } = treeData;\n const visited = new Set();\n let currentId = id1;\n while (currentId) {\n visited.add(currentId);\n if (currentId === id2) {\n return currentId;\n }\n currentId = parentById[currentId];\n }\n currentId = id2;\n while (currentId) {\n if (visited.has(currentId)) {\n return currentId;\n }\n currentId = parentById[currentId];\n }\n return 'root';\n};\n","import { select, line, curveLinear } from 'd3';\nimport { insertNode } from '../../../dagre-wrapper/nodes.js';\nimport insertMarkers from '../../../dagre-wrapper/markers.js';\nimport { insertEdgeLabel } from '../../../dagre-wrapper/edges.js';\nimport { findCommonAncestor } from './render-utils';\nimport { addHtmlLabel } from 'dagre-d3-es/src/dagre-js/label/add-html-label.js';\nimport { getConfig } from '../../../config';\nimport { log } from '../../../logger';\nimport { setupGraphViewbox } from '../../../setupGraphViewbox';\nimport common, { evaluate } from '../../common/common';\nimport { interpolateToCurve, getStylesFromArray } from '../../../utils';\nimport ELK from 'elkjs/lib/elk.bundled.js';\nconst elk = new ELK();\n\nconst portPos = {};\n\nconst conf = {};\nexport const setConf = function (cnf) {\n const keys = Object.keys(cnf);\n for (const key of keys) {\n conf[key] = cnf[key];\n }\n};\n\nlet nodeDb = {};\n\n// /**\n// * Function that adds the vertices found during parsing to the graph to be rendered.\n// *\n// * @param vert Object containing the vertices.\n// * @param g The graph that is to be drawn.\n// * @param svgId\n// * @param root\n// * @param doc\n// * @param diagObj\n// */\nexport const addVertices = function (vert, svgId, root, doc, diagObj, parentLookupDb, graph) {\n const svg = root.select(`[id=\"${svgId}\"]`);\n const nodes = svg.insert('g').attr('class', 'nodes');\n const keys = Object.keys(vert);\n\n // Iterate through each item in the vertex object (containing all the vertices found) in the graph definition\n keys.forEach(function (id) {\n const vertex = vert[id];\n\n /**\n * Variable for storing the classes for the vertex\n *\n * @type {string}\n */\n let classStr = 'default';\n if (vertex.classes.length > 0) {\n classStr = vertex.classes.join(' ');\n }\n\n const styles = getStylesFromArray(vertex.styles);\n\n // Use vertex id as text in the box if no text is provided by the graph definition\n let vertexText = vertex.text !== undefined ? vertex.text : vertex.id;\n\n // We create a SVG label, either by delegating to addHtmlLabel or manually\n let vertexNode;\n const labelData = { width: 0, height: 0 };\n if (evaluate(getConfig().flowchart.htmlLabels)) {\n // TODO: addHtmlLabel accepts a labelStyle. Do we possibly have that?\n const node = {\n label: vertexText.replace(\n /fa[blrs]?:fa-[\\w-]+/g,\n (s) => `<i class='${s.replace(':', ' ')}'></i>`\n ),\n };\n vertexNode = addHtmlLabel(svg, node).node();\n const bbox = vertexNode.getBBox();\n labelData.width = bbox.width;\n labelData.height = bbox.height;\n labelData.labelNode = vertexNode;\n vertexNode.parentNode.removeChild(vertexNode);\n } else {\n const svgLabel = doc.createElementNS('http://www.w3.org/2000/svg', 'text');\n svgLabel.setAttribute('style', styles.labelStyle.replace('color:', 'fill:'));\n\n const rows = vertexText.split(common.lineBreakRegex);\n\n for (const row of rows) {\n const tspan = doc.createElementNS('http://www.w3.org/2000/svg', 'tspan');\n tspan.setAttributeNS('http://www.w3.org/XML/1998/namespace', 'xml:space', 'preserve');\n tspan.setAttribute('dy', '1em');\n tspan.setAttribute('x', '1');\n tspan.textContent = row;\n svgLabel.appendChild(tspan);\n }\n vertexNode = svgLabel;\n const bbox = vertexNode.getBBox();\n labelData.width = bbox.width;\n labelData.height = bbox.height;\n labelData.labelNode = vertexNode;\n }\n\n const ports = [\n {\n id: vertex.id + '-west',\n layoutOptions: {\n 'port.side': 'WEST',\n },\n },\n {\n id: vertex.id + '-east',\n layoutOptions: {\n 'port.side': 'EAST',\n },\n },\n {\n id: vertex.id + '-south',\n layoutOptions: {\n 'port.side': 'SOUTH',\n },\n },\n {\n id: vertex.id + '-north',\n layoutOptions: {\n 'port.side': 'NORTH',\n },\n },\n ];\n\n let radious = 0;\n let _shape = '';\n let layoutOptions = {};\n // Set the shape based parameters\n switch (vertex.type) {\n case 'round':\n radious = 5;\n _shape = 'rect';\n break;\n case 'square':\n _shape = 'rect';\n break;\n case 'diamond':\n _shape = 'question';\n layoutOptions = {\n portConstraints: 'FIXED_SIDE',\n };\n break;\n case 'hexagon':\n _shape = 'hexagon';\n break;\n case 'odd':\n _shape = 'rect_left_inv_arrow';\n break;\n case 'lean_right':\n _shape = 'lean_right';\n break;\n case 'lean_left':\n _shape = 'lean_left';\n break;\n case 'trapezoid':\n _shape = 'trapezoid';\n break;\n case 'inv_trapezoid':\n _shape = 'inv_trapezoid';\n break;\n case 'odd_right':\n _shape = 'rect_left_inv_arrow';\n break;\n case 'circle':\n _shape = 'circle';\n break;\n case 'ellipse':\n _shape = 'ellipse';\n break;\n case 'stadium':\n _shape = 'stadium';\n break;\n case 'subroutine':\n _shape = 'subroutine';\n break;\n case 'cylinder':\n _shape = 'cylinder';\n break;\n case 'group':\n _shape = 'rect';\n break;\n case 'doublecircle':\n _shape = 'doublecircle';\n break;\n default:\n _shape = 'rect';\n }\n // Add the node\n const node = {\n labelStyle: styles.labelStyle,\n shape: _shape,\n labelText: vertexText,\n rx: radious,\n ry: radious,\n class: classStr,\n style: styles.style,\n id: vertex.id,\n link: vertex.link,\n linkTarget: vertex.linkTarget,\n tooltip: diagObj.db.getTooltip(vertex.id) || '',\n domId: diagObj.db.lookUpDomId(vertex.id),\n haveCallback: vertex.haveCallback,\n width: vertex.type === 'group' ? 500 : undefined,\n dir: vertex.dir,\n type: vertex.type,\n props: vertex.props,\n padding: getConfig().flowchart.padding,\n };\n let boundingBox;\n let nodeEl;\n if (node.type !== 'group') {\n nodeEl = insertNode(nodes, node, vertex.dir);\n boundingBox = nodeEl.node().getBBox();\n }\n\n const data = {\n id: vertex.id,\n ports: vertex.type === 'diamond' ? ports : [],\n // labelStyle: styles.labelStyle,\n // shape: _shape,\n layoutOptions,\n labelText: vertexText,\n labelData,\n // labels: [{ text: vertexText }],\n // rx: radius,\n // ry: radius,\n // class: classStr,\n // style: styles.style,\n // link: vertex.link,\n // linkTarget: vertex.linkTarget,\n // tooltip: diagObj.db.getTooltip(vertex.id) || '',\n domId: diagObj.db.lookUpDomId(vertex.id),\n // haveCallback: vertex.haveCallback,\n width: boundingBox?.width,\n height: boundingBox?.height,\n // dir: vertex.dir,\n type: vertex.type,\n // props: vertex.props,\n // padding: getConfig().flowchart.padding,\n // boundingBox,\n el: nodeEl,\n parent: parentLookupDb.parentById[vertex.id],\n };\n // if (!Object.keys(parentLookupDb.childrenById).includes(vertex.id)) {\n // graph.children.push({\n // ...data,\n // });\n // }\n nodeDb[node.id] = data;\n // log.trace('setNode', {\n // labelStyle: styles.labelStyle,\n // shape: _shape,\n // labelText: vertexText,\n // rx: radius,\n // ry: radius,\n // class: classStr,\n // style: styles.style,\n // id: vertex.id,\n // domId: diagObj.db.lookUpDomId(vertex.id),\n // width: vertex.type === 'group' ? 500 : undefined,\n // type: vertex.type,\n // dir: vertex.dir,\n // props: vertex.props,\n // padding: getConfig().flowchart.padding,\n // parent: parentLookupDb.parentById[vertex.id],\n // });\n });\n return graph;\n};\n\nconst getNextPosition = (position, edgeDirection, graphDirection) => {\n const portPos = {\n TB: {\n in: {\n north: 'north',\n },\n out: {\n south: 'west',\n west: 'east',\n east: 'south',\n },\n },\n LR: {\n in: {\n west: 'west',\n },\n out: {\n east: 'south',\n south: 'north',\n north: 'east',\n },\n },\n RL: {\n in: {\n east: 'east',\n },\n out: {\n west: 'north',\n north: 'south',\n south: 'west',\n },\n },\n BT: {\n in: {\n south: 'south',\n },\n out: {\n north: 'east',\n east: 'west',\n west: 'north',\n },\n },\n };\n portPos.TD = portPos.TB;\n log.info('abc88', graphDirection, edgeDirection, position);\n return portPos[graphDirection][edgeDirection][position];\n // return 'south';\n};\n\nconst getNextPort = (node, edgeDirection, graphDirection) => {\n log.info('getNextPort abc88', { node, edgeDirection, graphDirection });\n if (!portPos[node]) {\n switch (graphDirection) {\n case 'TB':\n case 'TD':\n portPos[node] = {\n inPosition: 'north',\n outPosition: 'south',\n };\n break;\n case 'BT':\n portPos[node] = {\n inPosition: 'south',\n outPosition: 'north',\n };\n break;\n case 'RL':\n portPos[node] = {\n inPosition: 'east',\n outPosition: 'west',\n };\n break;\n case 'LR':\n portPos[node] = {\n inPosition: 'west',\n outPosition: 'east',\n };\n break;\n }\n }\n const result = edgeDirection === 'in' ? portPos[node].inPosition : portPos[node].outPosition;\n\n if (edgeDirection === 'in') {\n portPos[node].inPosition = getNextPosition(\n portPos[node].inPosition,\n edgeDirection,\n graphDirection\n );\n } else {\n portPos[node].outPosition = getNextPosition(\n portPos[node].outPosition,\n edgeDirection,\n graphDirection\n );\n }\n return result;\n};\n\nconst getEdgeStartEndPoint = (edge, dir) => {\n let source = edge.start;\n let target = edge.end;\n\n // Save the original source and target\n const sourceId = source;\n const targetId = target;\n\n const startNode = nodeDb[source];\n const endNode = nodeDb[target];\n\n if (!startNode || !endNode) {\n return { source, target };\n }\n\n if (startNode.type === 'diamond') {\n source = `${source}-${getNextPort(source, 'out', dir)}`;\n }\n\n if (endNode.type === 'diamond') {\n target = `${target}-${getNextPort(target, 'in', dir)}`;\n }\n\n // Add the edge to the graph\n return { source, target, sourceId, targetId };\n};\n\n/**\n * Add edges to graph based on parsed graph definition\n *\n * @param {object} edges The edges to add to the graph\n * @param {object} g The graph object\n * @param cy\n * @param diagObj\n * @param graph\n * @param svg\n */\nexport const addEdges = function (edges, diagObj, graph, svg) {\n log.info('abc78 edges = ', edges);\n const labelsEl = svg.insert('g').attr('class', 'edgeLabels');\n let linkIdCnt = {};\n let dir = diagObj.db.getDirection();\n let defaultStyle;\n let defaultLabelStyle;\n\n if (edges.defaultStyle !== undefined) {\n const defaultStyles = getStylesFromArray(edges.defaultStyle);\n defaultStyle = defaultStyles.style;\n defaultLabelStyle = defaultStyles.labelStyle;\n }\n\n edges.forEach(function (edge) {\n // Identify Link\n var linkIdBase = 'L-' + edge.start + '-' + edge.end;\n // count the links from+to the same node to give unique id\n if (linkIdCnt[linkIdBase] === undefined) {\n linkIdCnt[linkIdBase] = 0;\n log.info('abc78 new entry', linkIdBase, linkIdCnt[linkIdBase]);\n } else {\n linkIdCnt[linkIdBase]++;\n log.info('abc78 new entry', linkIdBase, linkIdCnt[linkIdBase]);\n }\n let linkId = linkIdBase + '-' + linkIdCnt[linkIdBase];\n log.info('abc78 new link id to be used is', linkIdBase, linkId, linkIdCnt[linkIdBase]);\n var linkNameStart = 'LS-' + edge.start;\n var linkNameEnd = 'LE-' + edge.end;\n\n const edgeData = { style: '', labelStyle: '' };\n edgeData.minlen = edge.length || 1;\n //edgeData.id = 'id' + cnt;\n\n // Set link type for rendering\n if (edge.type === 'arrow_open') {\n edgeData.arrowhead = 'none';\n } else {\n edgeData.arrowhead = 'normal';\n }\n\n // Check of arrow types, placed here in order not to break old rendering\n edgeData.arrowTypeStart = 'arrow_open';\n edgeData.arrowTypeEnd = 'arrow_open';\n\n /* eslint-disable no-fallthrough */\n switch (edge.type) {\n case 'double_arrow_cross':\n edgeData.arrowTypeStart = 'arrow_cross';\n case 'arrow_cross':\n edgeData.arrowTypeEnd = 'arrow_cross';\n break;\n case 'double_arrow_point':\n edgeData.arrowTypeStart = 'arrow_point';\n case 'arrow_point':\n edgeData.arrowTypeEnd = 'arrow_point';\n break;\n case 'double_arrow_circle':\n edgeData.arrowTypeStart = 'arrow_circle';\n case 'arrow_circle':\n edgeData.arrowTypeEnd = 'arrow_circle';\n break;\n }\n\n let style = '';\n let labelStyle = '';\n\n switch (edge.stroke) {\n case 'normal':\n style = 'fill:none;';\n if (defaultStyle !== undefined) {\n style = defaultStyle;\n }\n if (defaultLabelStyle !== undefined) {\n labelStyle = defaultLabelStyle;\n }\n edgeData.thickness = 'normal';\n edgeData.pattern = 'solid';\n break;\n case 'dotted':\n edgeData.thickness = 'normal';\n edgeData.pattern = 'dotted';\n edgeData.style = 'fill:none;stroke-width:2px;stroke-dasharray:3;';\n break;\n case 'thick':\n edgeData.thickness = 'thick';\n edgeData.pattern = 'solid';\n edgeData.style = 'stroke-width: 3.5px;fill:none;';\n break;\n }\n if (edge.style !== undefined) {\n const styles = getStylesFromArray(edge.style);\n style = styles.style;\n labelStyle = styles.labelStyle;\n }\n\n edgeData.style = edgeData.style += style;\n edgeData.labelStyle = edgeData.labelStyle += labelStyle;\n\n if (edge.interpolate !== undefined) {\n edgeData.curve = interpolateToCurve(edge.interpolate, curveLinear);\n } else if (edges.defaultInterpolate !== undefined) {\n edgeData.curve = interpolateToCurve(edges.defaultInterpolate, curveLinear);\n } else {\n edgeData.curve = interpolateToCurve(conf.curve, curveLinear);\n }\n\n if (edge.text === undefined) {\n if (edge.style !== undefined) {\n edgeData.arrowheadStyle = 'fill: #333';\n }\n } else {\n edgeData.arrowheadStyle = 'fill: #333';\n edgeData.labelpos = 'c';\n }\n\n edgeData.labelType = 'text';\n edgeData.label = edge.text.replace(common.lineBreakRegex, '\\n');\n\n if (edge.style === undefined) {\n edgeData.style = edgeData.style || 'stroke: #333; stroke-width: 1.5px;fill:none;';\n }\n\n edgeData.labelStyle = edgeData.labelStyle.replace('color:', 'fill:');\n\n edgeData.id = linkId;\n edgeData.classes = 'flowchart-link ' + linkNameStart + ' ' + linkNameEnd;\n\n const labelEl = insertEdgeLabel(labelsEl, edgeData);\n\n // calculate start and end points of the edge, note that the source and target\n // can be modified for shapes that have ports\n const { source, target, sourceId, targetId } = getEdgeStartEndPoint(edge, dir);\n log.debug('abc78 source and target', source, target);\n // Add the edge to the graph\n graph.edges.push({\n id: 'e' + edge.start + edge.end,\n sources: [source],\n targets: [target],\n sourceId,\n targetId,\n labelEl: labelEl,\n labels: [\n {\n width: edgeData.width,\n height: edgeData.height,\n orgWidth: edgeData.width,\n orgHeight: edgeData.height,\n text: edgeData.label,\n layoutOptions: {\n 'edgeLabels.inline': 'true',\n 'edgeLabels.placement': 'CENTER',\n },\n },\n ],\n edgeData,\n });\n });\n return graph;\n};\n\n// TODO: break out and share with dagre wrapper. The current code in dagre wrapper also adds\n// adds the line to the graph, but we don't need that here. This is why we cant use the dagre\n// wrapper directly for this\n/**\n * Add the markers to the edge depending on the type of arrow is\n * @param svgPath\n * @param edgeData\n * @param diagramType\n * @param arrowMarkerAbsolute\n */\nconst addMarkersToEdge = function (svgPath, edgeData, diagramType, arrowMarkerAbsolute) {\n let url = '';\n // Check configuration for absolute path\n if (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 // look in edge data and decide which marker to use\n switch (edgeData.arrowTypeStart) {\n case 'arrow_cross':\n svgPath.attr('marker-start', 'url(' + url + '#' + diagramType + '-crossStart' + ')');\n break;\n case 'arrow_point':\n svgPath.attr('marker-start', 'url(' + url + '#' + diagramType + '-pointStart' + ')');\n break;\n case 'arrow_barb':\n svgPath.attr('marker-start', 'url(' + url + '#' + diagramType + '-barbStart' + ')');\n break;\n case 'arrow_circle':\n svgPath.attr('marker-start', 'url(' + url + '#' + diagramType + '-circleStart' + ')');\n break;\n case 'aggregation':\n svgPath.attr('marker-start', 'url(' + url + '#' + diagramType + '-aggregationStart' + ')');\n break;\n case 'extension':\n svgPath.attr('marker-start', 'url(' + url + '#' + diagramType + '-extensionStart' + ')');\n break;\n case 'composition':\n svgPath.attr('marker-start', 'url(' + url + '#' + diagramType + '-compositionStart' + ')');\n break;\n case 'dependency':\n svgPath.attr('marker-start', 'url(' + url + '#' + diagramType + '-dependencyStart' + ')');\n break;\n case 'lollipop':\n svgPath.attr('marker-start', 'url(' + url + '#' + diagramType + '-lollipopStart' + ')');\n break;\n default:\n }\n switch (edgeData.arrowTypeEnd) {\n case 'arrow_cross':\n svgPath.attr('marker-end', 'url(' + url + '#' + diagramType + '-crossEnd' + ')');\n break;\n case 'arrow_point':\n svgPath.attr('marker-end', 'url(' + url + '#' + diagramType + '-pointEnd' + ')');\n break;\n case 'arrow_barb':\n svgPath.attr('marker-end', 'url(' + url + '#' + diagramType + '-barbEnd' + ')');\n break;\n case 'arrow_circle':\n svgPath.attr('marker-end', 'url(' + url + '#' + diagramType + '-circleEnd' + ')');\n break;\n case 'aggregation':\n svgPath.attr('marker-end', 'url(' + url + '#' + diagramType + '-aggregationEnd' + ')');\n break;\n case 'extension':\n svgPath.attr('marker-end', 'url(' + url + '#' + diagramType + '-extensionEnd' + ')');\n break;\n case 'composition':\n svgPath.attr('marker-end', 'url(' + url + '#' + diagramType + '-compositionEnd' + ')');\n break;\n case 'dependency':\n svgPath.attr('marker-end', 'url(' + url + '#' + diagramType + '-dependencyEnd' + ')');\n break;\n case 'lollipop':\n svgPath.attr('marker-end', 'url(' + url + '#' + diagramType + '-lollipopEnd' + ')');\n break;\n default:\n }\n};\n\n/**\n * Returns the all the styles from classDef statements in the graph definition.\n *\n * @param text\n * @param diagObj\n * @returns {object} ClassDef styles\n */\nexport const getClasses = function (text, diagObj) {\n log.info('Extracting classes');\n diagObj.db.clear('ver-2');\n try {\n // Parse the graph definition\n diagObj.parse(text);\n return diagObj.db.getClasses();\n } catch (e) {\n return {};\n }\n};\n\nconst addSubGraphs = function (db) {\n const parentLookupDb = { parentById: {}, childrenById: {} };\n const subgraphs = db.getSubGraphs();\n log.info('Subgraphs - ', subgraphs);\n subgraphs.forEach(function (subgraph) {\n subgraph.nodes.forEach(function (node) {\n parentLookupDb.parentById[node] = subgraph.id;\n if (parentLookupDb.childrenById[subgraph.id] === undefined) {\n parentLookupDb.childrenById[subgraph.id] = [];\n }\n parentLookupDb.childrenById[subgraph.id].push(node);\n });\n });\n\n subgraphs.forEach(function (subgraph) {\n const data = { id: subgraph.id };\n if (parentLookupDb.parentById[subgraph.id] !== undefined) {\n data.parent = parentLookupDb.parentById[subgraph.id];\n }\n });\n return parentLookupDb;\n};\n\nconst calcOffset = function (src, dest, parentLookupDb) {\n const ancestor = findCommonAncestor(src, dest, parentLookupDb);\n if (ancestor === undefined || ancestor === 'root') {\n return { x: 0, y: 0 };\n }\n\n const ancestorOffset = nodeDb[ancestor].offset;\n return { x: ancestorOffset.posX, y: ancestorOffset.posY };\n};\n\nconst insertEdge = function (edgesEl, edge, edgeData, diagObj, parentLookupDb) {\n const offset = calcOffset(edge.sourceId, edge.targetId, parentLookupDb);\n\n const src = edge.sections[0].startPoint;\n const dest = edge.sections[0].endPoint;\n const segments = edge.sections[0].bendPoints ? edge.sections[0].bendPoints : [];\n\n const segPoints = segments.map((segment) => [segment.x + offset.x, segment.y + offset.y]);\n const points = [\n [src.x + offset.x, src.y + offset.y],\n ...segPoints,\n [dest.x + offset.x, dest.y + offset.y],\n ];\n\n // const curve = line().curve(curveBasis);\n const curve = line().curve(curveLinear);\n const edgePath = edgesEl\n .insert('path')\n .attr('d', curve(points))\n .attr('class', 'path')\n .attr('fill', 'none');\n const edgeG = edgesEl.insert('g').attr('class', 'edgeLabel');\n const edgeWithLabel = select(edgeG.node().appendChild(edge.labelEl));\n const box = edgeWithLabel.node().firstChild.getBoundingClientRect();\n edgeWithLabel.attr('width', box.width);\n edgeWithLabel.attr('height', box.height);\n\n edgeG.attr(\n 'transform',\n `translate(${edge.labels[0].x + offset.x}, ${edge.labels[0].y + offset.y})`\n );\n addMarkersToEdge(edgePath, edgeData, diagObj.type, diagObj.arrowMarkerAbsolute);\n};\n\n/**\n * Recursive function that iterates over an array of nodes and inserts the children of each node.\n * It also recursively populates the inserts the children of the children and so on.\n * @param {*} graph\n * @param nodeArray\n * @param parentLookupDb\n */\nconst insertChildren = (nodeArray, parentLookupDb) => {\n nodeArray.forEach((node) => {\n // Check if we have reached the end of the tree\n if (!node.children) {\n node.children = [];\n }\n // Check if the node has children\n const childIds = parentLookupDb.childrenById[node.id];\n // If the node has children, add them to the node\n if (childIds) {\n childIds.forEach((childId) => {\n node.children.push(nodeDb[childId]);\n });\n }\n // Recursive call\n insertChildren(node.children, parentLookupDb);\n });\n};\n\n/**\n * Draws a flowchart in the tag with id: id based on the graph definition in text.\n *\n * @param text\n * @param id\n */\n\nexport const draw = async function (text, id, _version, diagObj) {\n // Add temporary render element\n diagObj.db.clear();\n nodeDb = {};\n diagObj.db.setGen('gen-2');\n // Parse the graph definition\n diagObj.parser.parse(text);\n\n const renderEl = select('body').append('div').attr('style', 'height:400px').attr('id', 'cy');\n let graph = {\n id: 'root',\n layoutOptions: {\n 'elk.hierarchyHandling': 'INCLUDE_CHILDREN',\n 'org.eclipse.elk.padding': '[top=100, left=100, bottom=110, right=110]',\n 'elk.layered.spacing.edgeNodeBetweenLayers': '30',\n // 'elk.layered.mergeEdges': 'true',\n 'elk.direction': 'DOWN',\n // 'elk.ports.sameLayerEdges': true,\n // 'nodePlacement.strategy': 'SIMPLE',\n },\n children: [],\n edges: [],\n };\n log.info('Drawing flowchart using v3 renderer', elk);\n\n // Set the direction,\n // Fetch the default direction, use TD if none was found\n let dir = diagObj.db.getDirection();\n switch (dir) {\n case 'BT':\n graph.layoutOptions['elk.direction'] = 'UP';\n break;\n case 'TB':\n graph.layoutOptions['elk.direction'] = 'DOWN';\n break;\n case 'LR':\n graph.layoutOptions['elk.direction'] = 'RIGHT';\n break;\n case 'RL':\n graph.layoutOptions['elk.direction'] = 'LEFT';\n break;\n }\n const { securityLevel, flowchart: conf } = getConfig();\n\n // Find the root dom node to ne used in rendering\n // Handle root and document for when rendering in sandbox mode\n let sandboxElement;\n if (securityLevel === 'sandbox') {\n sandboxElement = select('#i' + id);\n }\n const root =\n securityLevel === 'sandbox'\n ? select(sandboxElement.nodes()[0].contentDocument.body)\n : select('body');\n const doc = securityLevel === 'sandbox' ? sandboxElement.nodes()[0].contentDocument : document;\n\n const svg = root.select(`[id=\"${id}\"]`);\n\n // Define the supported markers for the diagram\n const markers = ['point', 'circle', 'cross'];\n\n // Add the marker definitions to the svg as marker tags\n insertMarkers(svg, markers, diagObj.type, diagObj.arrowMarkerAbsolute);\n\n // Fetch the vertices/nodes and edges/links from the parsed graph definition\n const vert = diagObj.db.getVertices();\n\n // Setup nodes from the subgraphs with type group, these will be used\n // as nodes with children in the subgraph\n let subG;\n const subGraphs = diagObj.db.getSubGraphs();\n log.info('Subgraphs - ', subGraphs);\n for (let i = subGraphs.length - 1; i >= 0; i--) {\n subG = subGraphs[i];\n diagObj.db.addVertex(subG.id, subG.title, 'group', undefined, subG.classes, subG.dir);\n }\n\n // Add an element in the svg to be used to hold the subgraphs container\n // elements\n const subGraphsEl = svg.insert('g').attr('class', 'subgraphs');\n\n // Create the lookup db for the subgraphs and their children to used when creating\n // the tree structured graph\n const parentLookupDb = addSubGraphs(diagObj.db);\n\n // Add the nodes to the graph, this will entail creating the actual nodes\n // in order to get the size of the node. You can't get the size of a node\n // that is not in the dom so we need to add it to the dom, get the size\n // we will position the nodes when we get the layout from elkjs\n graph = addVertices(vert, id, root, doc, diagObj, parentLookupDb, graph);\n\n // Time for the edges, we start with adding an element in the node to hold the edges\n const edgesEl = svg.insert('g').attr('class', 'edges edgePath');\n // Fetch the edges form the parsed graph definition\n const edges = diagObj.db.getEdges();\n\n // Add the edges to the graph, this will entail creating the actual edges\n graph = addEdges(edges, diagObj, graph, svg);\n\n // Iterate through all nodes and add the top level nodes to the graph\n const nodes = Object.keys(nodeDb);\n nodes.forEach((nodeId) => {\n const node = nodeDb[nodeId];\n if (!node.parent) {\n graph.children.push(node);\n }\n // Subgraph\n if (parentLookupDb.childrenById[nodeId] !== undefined) {\n node.labels = [\n {\n text: node.labelText,\n layoutOptions: {\n 'nodeLabels.placement': '[H_CENTER, V_TOP, INSIDE]',\n },\n width: node.labelData.width,\n height: node.labelData.height,\n },\n ];\n delete node.x;\n delete node.y;\n delete node.width;\n delete node.height;\n }\n });\n insertChildren(graph.children, parentLookupDb);\n log.info('after layout', JSON.stringify(graph, null, 2));\n const g = await elk.layout(graph);\n drawNodes(0, 0, g.children, svg, subGraphsEl, diagObj, 0);\n log.info('after layout', g);\n g.edges?.map((edge) => {\n insertEdge(edgesEl, edge, edge.edgeData, diagObj, parentLookupDb);\n });\n setupGraphViewbox({}, svg, conf.diagramPadding, conf.useMaxWidth);\n // Remove element after layout\n renderEl.remove();\n};\n\nconst drawNodes = (relX, relY, nodeArray, svg, subgraphsEl, diagObj, depth) => {\n nodeArray.forEach(function (node) {\n if (node) {\n nodeDb[node.id].offset = {\n posX: node.x + relX,\n posY: node.y + relY,\n x: relX,\n y: relY,\n depth,\n width: node.width,\n height: node.height,\n };\n if (node.type === 'group') {\n const subgraphEl = subgraphsEl.insert('g').attr('class', 'subgraph');\n subgraphEl\n .insert('rect')\n .attr('class', 'subgraph subgraph-lvl-' + (depth % 5) + ' node')\n .attr('x', node.x + relX)\n .attr('y', node.y + relY)\n .attr('width', node.width)\n .attr('height', node.height);\n const label = subgraphEl.insert('g').attr('class', 'label');\n label.attr(\n 'transform',\n `translate(${node.labels[0].x + relX + node.x}, ${node.labels[0].y + relY + node.y})`\n );\n label.node().appendChild(node.labelData.labelNode);\n\n log.info('Id (UGH)= ', node.type, node.labels);\n } else {\n log.info('Id (UGH)= ', node.id);\n node.el.attr(\n 'transform',\n `translate(${node.x + relX + node.width / 2}, ${node.y + relY + node.height / 2})`\n );\n }\n }\n });\n nodeArray.forEach(function (node) {\n if (node && node.type === 'group') {\n drawNodes(relX + node.x, relY + node.y, node.children, svg, subgraphsEl, diagObj, depth + 1);\n }\n });\n};\n\nexport default {\n getClasses,\n draw,\n};\n","/** Returns the styles given options */\nexport interface FlowChartStyleOptions {\n arrowheadColor: string;\n border2: string;\n clusterBkg: string;\n clusterBorder: string;\n edgeLabelBackground: string;\n fontFamily: string;\n lineColor: string;\n mainBkg: string;\n nodeBorder: string;\n nodeTextColor: string;\n tertiaryColor: string;\n textColor: string;\n titleColor: string;\n [key: string]: string;\n}\n\nconst genSections = (options: FlowChartStyleOptions) => {\n let sections = '';\n\n for (let i = 0; i < 5; i++) {\n sections += `\n .subgraph-lvl-${i} {\n fill: ${options[`surface${i}`]};\n stroke: ${options[`surfacePeer${i}`]};\n }\n `;\n }\n return sections;\n};\n\nconst getStyles = (options: FlowChartStyleOptions) =>\n `.label {\n font-family: ${options.fontFamily};\n color: ${options.nodeTextColor || options.textColor};\n }\n .cluster-label text {\n fill: ${options.titleColor};\n }\n .cluster-label span {\n color: ${options.titleColor};\n }\n\n .label text,span {\n fill: ${options.nodeTextColor || options.textColor};\n color: ${options.nodeTextColor || options.textColor};\n }\n\n .node rect,\n .node circle,\n .node ellipse,\n .node polygon,\n .node path {\n fill: ${options.mainBkg};\n stroke: ${options.nodeBorder};\n stroke-width: 1px;\n }\n\n .node .label {\n text-align: center;\n }\n .node.clickable {\n cursor: pointer;\n }\n\n .arrowheadPath {\n fill: ${options.arrowheadColor};\n }\n\n .edgePath .path {\n stroke: ${options.lineColor};\n stroke-width: 2.0px;\n }\n\n .flowchart-link {\n stroke: ${options.lineColor};\n fill: none;\n }\n\n .edgeLabel {\n background-color: ${options.edgeLabelBackground};\n rect {\n opacity: 0.5;\n background-color: ${options.edgeLabelBackground};\n fill: ${options.edgeLabelBackground};\n }\n text-align: center;\n }\n\n .cluster rect {\n fill: ${options.clusterBkg};\n stroke: ${options.clusterBorder};\n stroke-width: 1px;\n }\n\n .cluster text {\n fill: ${options.titleColor};\n }\n\n .cluster span {\n color: ${options.titleColor};\n }\n /* .cluster div {\n color: ${options.titleColor};\n } */\n\n div.mermaidTooltip {\n position: absolute;\n text-align: center;\n max-width: 200px;\n padding: 2px;\n font-family: ${options.fontFamily};\n font-size: 12px;\n background: ${options.tertiaryColor};\n border: 1px solid ${options.border2};\n border-radius: 2px;\n pointer-events: none;\n z-index: 100;\n }\n\n .flowchartTitleText {\n text-anchor: middle;\n font-size: 18px;\n fill: ${options.textColor};\n }\n .subgraph {\n stroke-width:2;\n rx:3;\n }\n // .subgraph-lvl-1 {\n // fill:#ccc;\n // // stroke:black;\n // }\n ${genSections(options)}\n`;\n\nexport default getStyles;\n","// @ts-ignore: JISON typing missing\nimport parser from '../parser/flow';\n\nimport * as db from '../flowDb';\nimport renderer from './flowRenderer-elk';\nimport styles from './styles';\n\nexport const diagram = {\n db,\n renderer,\n parser,\n styles,\n};\n"],"names":["styles","node","portPos","db","conf"],"mappings":";;;;;;;;;;;;;;;;;;;AAKO,MAAM,qBAAqB,CAAC,KAAa,KAAa,aAAuB;AAC5E,QAAA,EAAE,WAAe,IAAA;AACjB,QAAA,8BAAc;AACpB,MAAI,YAAY;AAChB,SAAO,WAAW;AAChB,YAAQ,IAAI,SAAS;AACrB,QAAI,cAAc,KAAK;AACd,aAAA;AAAA,IACT;AACA,gBAAY,WAAW,SAAS;AAAA,EAClC;AACY,cAAA;AACZ,SAAO,WAAW;AACZ,QAAA,QAAQ,IAAI,SAAS,GAAG;AACnB,aAAA;AAAA,IACT;AACA,gBAAY,WAAW,SAAS;AAAA,EAClC;AACO,SAAA;AACT;ACZA,MAAM,MAAM,IAAI;AAEhB,MAAM,UAAU,CAAA;AAEhB,MAAM,OAAO,CAAA;AAQb,IAAI,SAAS,CAAA;AAYN,MAAM,cAAc,SAAU,MAAM,OAAO,MAAM,KAAK,SAAS,gBAAgB,OAAO;AAC3F,QAAM,MAAM,KAAK,OAAO,QAAQ,SAAS;AACzC,QAAM,QAAQ,IAAI,OAAO,GAAG,EAAE,KAAK,SAAS,OAAO;AACnD,QAAM,OAAO,OAAO,KAAK,IAAI;AAG7B,OAAK,QAAQ,SAAU,IAAI;AACzB,UAAM,SAAS,KAAK,EAAE;AAOtB,QAAI,WAAW;AACf,QAAI,OAAO,QAAQ,SAAS,GAAG;AAC7B,iBAAW,OAAO,QAAQ,KAAK,GAAG;AAAA,IACnC;AAED,UAAMA,UAAS,mBAAmB,OAAO,MAAM;AAG/C,QAAI,aAAa,OAAO,SAAS,SAAY,OAAO,OAAO,OAAO;AAGlE,QAAI;AACJ,UAAM,YAAY,EAAE,OAAO,GAAG,QAAQ,EAAC;AACvC,QAAI,SAAS,UAAS,EAAG,UAAU,UAAU,GAAG;AAE9C,YAAMC,QAAO;AAAA,QACX,OAAO,WAAW;AAAA,UAChB;AAAA,UACA,CAAC,MAAM,aAAa,EAAE,QAAQ,KAAK,GAAG;AAAA,QACvC;AAAA,MACT;AACM,mBAAa,aAAa,KAAKA,KAAI,EAAE,KAAI;AACzC,YAAM,OAAO,WAAW;AACxB,gBAAU,QAAQ,KAAK;AACvB,gBAAU,SAAS,KAAK;AACxB,gBAAU,YAAY;AACtB,iBAAW,WAAW,YAAY,UAAU;AAAA,IAClD,OAAW;AACL,YAAM,WAAW,IAAI,gBAAgB,8BAA8B,MAAM;AACzE,eAAS,aAAa,SAASD,QAAO,WAAW,QAAQ,UAAU,OAAO,CAAC;AAE3E,YAAM,OAAO,WAAW,MAAM,OAAO,cAAc;AAEnD,iBAAW,OAAO,MAAM;AACtB,cAAM,QAAQ,IAAI,gBAAgB,8BAA8B,OAAO;AACvE,cAAM,eAAe,wCAAwC,aAAa,UAAU;AACpF,cAAM,aAAa,MAAM,KAAK;AAC9B,cAAM,aAAa,KAAK,GAAG;AAC3B,cAAM,cAAc;AACpB,iBAAS,YAAY,KAAK;AAAA,MAC3B;AACD,mBAAa;AACb,YAAM,OAAO,WAAW;AACxB,gBAAU,QAAQ,KAAK;AACvB,gBAAU,SAAS,KAAK;AACxB,gBAAU,YAAY;AAAA,IACvB;AAED,UAAM,QAAQ;AAAA,MACZ;AAAA,QACE,IAAI,OAAO,KAAK;AAAA,QAChB,eAAe;AAAA,UACb,aAAa;AAAA,QACd;AAAA,MACF;AAAA,MACD;AAAA,QACE,IAAI,OAAO,KAAK;AAAA,QAChB,eAAe;AAAA,UACb,aAAa;AAAA,QACd;AAAA,MACF;AAAA,MACD;AAAA,QACE,IAAI,OAAO,KAAK;AAAA,QAChB,eAAe;AAAA,UACb,aAAa;AAAA,QACd;AAAA,MACF;AAAA,MACD;AAAA,QACE,IAAI,OAAO,KAAK;AAAA,QAChB,eAAe;AAAA,UACb,aAAa;AAAA,QACd;AAAA,MACF;AAAA,IACP;AAEI,QAAI,UAAU;AACd,QAAI,SAAS;AACb,QAAI,gBAAgB,CAAA;AAEpB,YAAQ,OAAO,MAAI;AAAA,MACjB,KAAK;AACH,kBAAU;AACV,iBAAS;AACT;AAAA,MACF,KAAK;AACH,iBAAS;AACT;AAAA,MACF,KAAK;AACH,iBAAS;AACT,wBAAgB;AAAA,UACd,iBAAiB;AAAA,QAC3B;AACQ;AAAA,MACF,KAAK;AACH,iBAAS;AACT;AAAA,MACF,KAAK;AACH,iBAAS;AACT;AAAA,MACF,KAAK;AACH,iBAAS;AACT;AAAA,MACF,KAAK;AACH,iBAAS;AACT;AAAA,MACF,KAAK;AACH,iBAAS;AACT;AAAA,MACF,KAAK;AACH,iBAAS;AACT;AAAA,MACF,KAAK;AACH,iBAAS;AACT;AAAA,MACF,KAAK;AACH,iBAAS;AACT;AAAA,MACF,KAAK;AACH,iBAAS;AACT;AAAA,MACF,KAAK;AACH,iBAAS;AACT;AAAA,MACF,KAAK;AACH,iBAAS;AACT;AAAA,MACF,KAAK;AACH,iBAAS;AACT;AAAA,MACF,KAAK;AACH,iBAAS;AACT;AAAA,MACF,KAAK;AACH,iBAAS;AACT;AAAA,MACF;AACE,iBAAS;AAAA,IACZ;AAED,UAAM,OAAO;AAAA,MACX,YAAYA,QAAO;AAAA,MACnB,OAAO;AAAA,MACP,WAAW;AAAA,MACX,IAAI;AAAA,MACJ,IAAI;AAAA,MACJ,OAAO;AAAA,MACP,OAAOA,QAAO;AAAA,MACd,IAAI,OAAO;AAAA,MACX,MAAM,OAAO;AAAA,MACb,YAAY,OAAO;AAAA,MACnB,SAAS,QAAQ,GAAG,WAAW,OAAO,EAAE,KAAK;AAAA,MAC7C,OAAO,QAAQ,GAAG,YAAY,OAAO,EAAE;AAAA,MACvC,cAAc,OAAO;AAAA,MACrB,OAAO,OAAO,SAAS,UAAU,MAAM;AAAA,MACvC,KAAK,OAAO;AAAA,MACZ,MAAM,OAAO;AAAA,MACb,OAAO,OAAO;AAAA,MACd,SAAS,YAAY,UAAU;AAAA,IACrC;AACI,QAAI;AACJ,QAAI;AACJ,QAAI,KAAK,SAAS,SAAS;AACzB,eAAS,WAAW,OAAO,MAAM,OAAO,GAAG;AAC3C,oBAAc,OAAO,KAAM,EAAC,QAAO;AAAA,IACpC;AAED,UAAM,OAAO;AAAA,MACX,IAAI,OAAO;AAAA,MACX,OAAO,OAAO,SAAS,YAAY,QAAQ,CAAE;AAAA;AAAA;AAAA,MAG7C;AAAA,MACA,WAAW;AAAA,MACX;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MASA,OAAO,QAAQ,GAAG,YAAY,OAAO,EAAE;AAAA;AAAA,MAEvC,OAAO,2CAAa;AAAA,MACpB,QAAQ,2CAAa;AAAA;AAAA,MAErB,MAAM,OAAO;AAAA;AAAA;AAAA;AAAA,MAIb,IAAI;AAAA,MACJ,QAAQ,eAAe,WAAW,OAAO,EAAE;AAAA,IACjD;AAMI,WAAO,KAAK,EAAE,IAAI;AAAA,EAkBtB,CAAG;AACD,SAAO;AACT;AAEA,MAAM,kBAAkB,CAAC,UAAU,eAAe,mBAAmB;AACnE,QAAME,WAAU;AAAA,IACd,IAAI;AAAA,MACF,IAAI;AAAA,QACF,OAAO;AAAA,MACR;AAAA,MACD,KAAK;AAAA,QACH,OAAO;AAAA,QACP,MAAM;AAAA,QACN,MAAM;AAAA,MACP;AAAA,IACF;AAAA,IACD,IAAI;AAAA,MACF,IAAI;AAAA,QACF,MAAM;AAAA,MACP;AAAA,MACD,KAAK;AAAA,QACH,MAAM;AAAA,QACN,OAAO;AAAA,QACP,OAAO;AAAA,MACR;AAAA,IACF;AAAA,IACD,IAAI;AAAA,MACF,IAAI;AAAA,QACF,MAAM;AAAA,MACP;AAAA,MACD,KAAK;AAAA,QACH,MAAM;AAAA,QACN,OAAO;AAAA,QACP,OAAO;AAAA,MACR;AAAA,IACF;AAAA,IACD,IAAI;AAAA,MACF,IAAI;AAAA,QACF,OAAO;AAAA,MACR;AAAA,MACD,KAAK;AAAA,QACH,OAAO;AAAA,QACP,MAAM;AAAA,QACN,MAAM;AAAA,MACP;AAAA,IACF;AAAA,EACL;AACE,EAAAA,SAAQ,KAAKA,SAAQ;AACrB,MAAI,KAAK,SAAS,gBAAgB,eAAe,QAAQ;AACzD,SAAOA,SAAQ,cAAc,EAAE,aAAa,EAAE,QAAQ;AAExD;AAEA,MAAM,cAAc,CAAC,MAAM,eAAe,mBAAmB;AAC3D,MAAI,KAAK,qBAAqB,EAAE,MAAM,eAAe,eAAc,CAAE;AACrE,MAAI,CAAC,QAAQ,IAAI,GAAG;AAClB,YAAQ,gBAAc;AAAA,MACpB,KAAK;AAAA,MACL,KAAK;AACH,gBAAQ,IAAI,IAAI;AAAA,UACd,YAAY;AAAA,UACZ,aAAa;AAAA,QACvB;AACQ;AAAA,MACF,KAAK;AACH,gBAAQ,IAAI,IAAI;AAAA,UACd,YAAY;AAAA,UACZ,aAAa;AAAA,QACvB;AACQ;AAAA,MACF,KAAK;AACH,gBAAQ,IAAI,IAAI;AAAA,UACd,YAAY;AAAA,UACZ,aAAa;AAAA,QACvB;AACQ;AAAA,MACF,KAAK;AACH,gBAAQ,IAAI,IAAI;AAAA,UACd,YAAY;AAAA,UACZ,aAAa;AAAA,QACvB;AACQ;AAAA,IACH;AAAA,EACF;AACD,QAAM,SAAS,kBAAkB,OAAO,QAAQ,IAAI,EAAE,aAAa,QAAQ,IAAI,EAAE;AAEjF,MAAI,kBAAkB,MAAM;AAC1B,YAAQ,IAAI,EAAE,aAAa;AAAA,MACzB,QAAQ,IAAI,EAAE;AAAA,MACd;AAAA,MACA;AAAA,IACN;AAAA,EACA,OAAS;AACL,YAAQ,IAAI,EAAE,cAAc;AAAA,MAC1B,QAAQ,IAAI,EAAE;AAAA,MACd;AAAA,MACA;AAAA,IACN;AAAA,EACG;AACD,SAAO;AACT;AAEA,MAAM,uBAAuB,CAAC,MAAM,QAAQ;AAC1C,MAAI,SAAS,KAAK;AAClB,MAAI,SAAS,KAAK;AAGlB,QAAM,WAAW;AACjB,QAAM,WAAW;AAEjB,QAAM,YAAY,OAAO,MAAM;AAC/B,QAAM,UAAU,OAAO,MAAM;AAE7B,MAAI,CAAC,aAAa,CAAC,SAAS;AAC1B,WAAO,EAAE,QAAQ;EAClB;AAED,MAAI,UAAU,SAAS,WAAW;AAChC,aAAS,GAAG,UAAU,YAAY,QAAQ,OAAO,GAAG;AAAA,EACrD;AAED,MAAI,QAAQ,SAAS,WAAW;AAC9B,aAAS,GAAG,UAAU,YAAY,QAAQ,MAAM,GAAG;AAAA,EACpD;AAGD,SAAO,EAAE,QAAQ,QAAQ,UAAU,SAAQ;AAC7C;AAYO,MAAM,WAAW,SAAU,OAAO,SAAS,OAAO,KAAK;AAC5D,MAAI,KAAK,kBAAkB,KAAK;AAChC,QAAM,WAAW,IAAI,OAAO,GAAG,EAAE,KAAK,SAAS,YAAY;AAC3D,MAAI,YAAY,CAAA;AAChB,MAAI,MAAM,QAAQ,GAAG,aAAY;AACjC,MAAI;AACJ,MAAI;AAEJ,MAAI,MAAM,iBAAiB,QAAW;AACpC,UAAM,gBAAgB,mBAAmB,MAAM,YAAY;AAC3D,mBAAe,cAAc;AAC7B,wBAAoB,cAAc;AAAA,EACnC;AAED,QAAM,QAAQ,SAAU,MAAM;AAE5B,QAAI,aAAa,OAAO,KAAK,QAAQ,MAAM,KAAK;AAEhD,QAAI,UAAU,UAAU,MAAM,QAAW;AACvC,gBAAU,UAAU,IAAI;AACxB,UAAI,KAAK,mBAAmB,YAAY,UAAU,UAAU,CAAC;AAAA,IACnE,OAAW;AACL,gBAAU,UAAU;AACpB,UAAI,KAAK,mBAAmB,YAAY,UAAU,UAAU,CAAC;AAAA,IAC9D;AACD,QAAI,SAAS,aAAa,MAAM,UAAU,UAAU;AACpD,QAAI,KAAK,mCAAmC,YAAY,QAAQ,UAAU,UAAU,CAAC;AACrF,QAAI,gBAAgB,QAAQ,KAAK;AACjC,QAAI,cAAc,QAAQ,KAAK;AAE/B,UAAM,WAAW,EAAE,OAAO,IAAI,YAAY,GAAE;AAC5C,aAAS,SAAS,KAAK,UAAU;AAIjC,QAAI,KAAK,SAAS,cAAc;AAC9B,eAAS,YAAY;AAAA,IAC3B,OAAW;AACL,eAAS,YAAY;AAAA,IACtB;AAGD,aAAS,iBAAiB;AAC1B,aAAS,eAAe;AAGxB,YAAQ,KAAK,MAAI;AAAA,MACf,KAAK;AACH,iBAAS,iBAAiB;AAAA,MAC5B,KAAK;AACH,iBAAS,eAAe;AACxB;AAAA,MACF,KAAK;AACH,iBAAS,iBAAiB;AAAA,MAC5B,KAAK;AACH,iBAAS,eAAe;AACxB;AAAA,MACF,KAAK;AACH,iBAAS,iBAAiB;AAAA,MAC5B,KAAK;AACH,iBAAS,eAAe;AACxB;AAAA,IACH;AAED,QAAI,QAAQ;AACZ,QAAI,aAAa;AAEjB,YAAQ,KAAK,QAAM;AAAA,MACjB,KAAK;AACH,gBAAQ;AACR,YAAI,iBAAiB,QAAW;AAC9B,kBAAQ;AAAA,QACT;AACD,YAAI,sBAAsB,QAAW;AACnC,uBAAa;AAAA,QACd;AACD,iBAAS,YAAY;AACrB,iBAAS,UAAU;AACnB;AAAA,MACF,KAAK;AACH,iBAAS,YAAY;AACrB,iBAAS,UAAU;AACnB,iBAAS,QAAQ;AACjB;AAAA,MACF,KAAK;AACH,iBAAS,YAAY;AACrB,iBAAS,UAAU;AACnB,iBAAS,QAAQ;AACjB;AAAA,IACH;AACD,QAAI,KAAK,UAAU,QAAW;AAC5B,YAAMF,UAAS,mBAAmB,KAAK,KAAK;AAC5C,cAAQA,QAAO;AACf,mBAAaA,QAAO;AAAA,IACrB;AAED,aAAS,QAAQ,SAAS,SAAS;AACnC,aAAS,aAAa,SAAS,cAAc;AAE7C,QAAI,KAAK,gBAAgB,QAAW;AAClC,eAAS,QAAQ,mBAAmB,KAAK,aAAa,WAAW;AAAA,IACvE,WAAe,MAAM,uBAAuB,QAAW;AACjD,eAAS,QAAQ,mBAAmB,MAAM,oBAAoB,WAAW;AAAA,IAC/E,OAAW;AACL,eAAS,QAAQ,mBAAmB,KAAK,OAAO,WAAW;AAAA,IAC5D;AAED,QAAI,KAAK,SAAS,QAAW;AAC3B,UAAI,KAAK,UAAU,QAAW;AAC5B,iBAAS,iBAAiB;AAAA,MAC3B;AAAA,IACP,OAAW;AACL,eAAS,iBAAiB;AAC1B,eAAS,WAAW;AAAA,IACrB;AAED,aAAS,YAAY;AACrB,aAAS,QAAQ,KAAK,KAAK,QAAQ,OAAO,gBAAgB,IAAI;AAE9D,QAAI,KAAK,UAAU,QAAW;AAC5B,eAAS,QAAQ,SAAS,SAAS;AAAA,IACpC;AAED,aAAS,aAAa,SAAS,WAAW,QAAQ,UAAU,OAAO;AAEnE,aAAS,KAAK;AACd,aAAS,UAAU,oBAAoB,gBAAgB,MAAM;AAE7D,UAAM,UAAU,gBAAgB,UAAU,QAAQ;AAIlD,UAAM,EAAE,QAAQ,QAAQ,UAAU,SAAQ,IAAK,qBAAqB,MAAM,GAAG;AAC7E,QAAI,MAAM,2BAA2B,QAAQ,MAAM;AAEnD,UAAM,MAAM,KAAK;AAAA,MACf,IAAI,MAAM,KAAK,QAAQ,KAAK;AAAA,MAC5B,SAAS,CAAC,MAAM;AAAA,MAChB,SAAS,CAAC,MAAM;AAAA,MAChB;AAAA,MACA;AAAA,MACA;AAAA,MACA,QAAQ;AAAA,QACN;AAAA,UACE,OAAO,SAAS;AAAA,UAChB,QAAQ,SAAS;AAAA,UACjB,UAAU,SAAS;AAAA,UACnB,WAAW,SAAS;AAAA,UACpB,MAAM,SAAS;AAAA,UACf,eAAe;AAAA,YACb,qBAAqB;AAAA,YACrB,wBAAwB;AAAA,UACzB;AAAA,QACF;AAAA,MACF;AAAA,MACD;AAAA,IACN,CAAK;AAAA,EACL,CAAG;AACD,SAAO;AACT;AAYA,MAAM,mBAAmB,SAAU,SAAS,UAAU,aAAa,qBAAqB;AACtF,MAAI,MAAM;AAEV,MAAI,qBAAqB;AACvB,UACE,OAAO,SAAS,WAChB,OACA,OAAO,SAAS,OAChB,OAAO,SAAS,WAChB,OAAO,SAAS;AAClB,UAAM,IAAI,QAAQ,OAAO,KAAK;AAC9B,UAAM,IAAI,QAAQ,OAAO,KAAK;AAAA,EAC/B;AAGD,UAAQ,SAAS,gBAAc;AAAA,IAC7B,KAAK;AACH,cAAQ,KAAK,gBAAgB,SAAS,MAAM,MAAM,cAAc,cAAmB;AACnF;AAAA,IACF,KAAK;AACH,cAAQ,KAAK,gBAAgB,SAAS,MAAM,MAAM,cAAc,cAAmB;AACnF;AAAA,IACF,KAAK;AACH,cAAQ,KAAK,gBAAgB,SAAS,MAAM,MAAM,cAAc,aAAkB;AAClF;AAAA,IACF,KAAK;AACH,cAAQ,KAAK,gBAAgB,SAAS,MAAM,MAAM,cAAc,eAAoB;AACpF;AAAA,IACF,KAAK;AACH,cAAQ,KAAK,gBAAgB,SAAS,MAAM,MAAM,cAAc,oBAAyB;AACzF;AAAA,IACF,KAAK;AACH,cAAQ,KAAK,gBAAgB,SAAS,MAAM,MAAM,cAAc,kBAAuB;AACvF;AAAA,IACF,KAAK;AACH,cAAQ,KAAK,gBAAgB,SAAS,MAAM,MAAM,cAAc,oBAAyB;AACzF;AAAA,IACF,KAAK;AACH,cAAQ,KAAK,gBAAgB,SAAS,MAAM,MAAM,cAAc,mBAAwB;AACxF;AAAA,IACF,KAAK;AACH,cAAQ,KAAK,gBAAgB,SAAS,MAAM,MAAM,cAAc,iBAAsB;AACtF;AAAA,EAEH;AACD,UAAQ,SAAS,cAAY;AAAA,IAC3B,KAAK;AACH,cAAQ,KAAK,cAAc,SAAS,MAAM,MAAM,cAAc,YAAiB;AAC/E;AAAA,IACF,KAAK;AACH,cAAQ,KAAK,cAAc,SAAS,MAAM,MAAM,cAAc,YAAiB;AAC/E;AAAA,IACF,KAAK;AACH,cAAQ,KAAK,cAAc,SAAS,MAAM,MAAM,cAAc,WAAgB;AAC9E;AAAA,IACF,KAAK;AACH,cAAQ,KAAK,cAAc,SAAS,MAAM,MAAM,cAAc,aAAkB;AAChF;AAAA,IACF,KAAK;AACH,cAAQ,KAAK,cAAc,SAAS,MAAM,MAAM,cAAc,kBAAuB;AACrF;AAAA,IACF,KAAK;AACH,cAAQ,KAAK,cAAc,SAAS,MAAM,MAAM,cAAc,gBAAqB;AACnF;AAAA,IACF,KAAK;AACH,cAAQ,KAAK,cAAc,SAAS,MAAM,MAAM,cAAc,kBAAuB;AACrF;AAAA,IACF,KAAK;AACH,cAAQ,KAAK,cAAc,SAAS,MAAM,MAAM,cAAc,iBAAsB;AACpF;AAAA,IACF,KAAK;AACH,cAAQ,KAAK,cAAc,SAAS,MAAM,MAAM,cAAc,eAAoB;AAClF;AAAA,EAEH;AACH;AASO,MAAM,aAAa,SAAU,MAAM,SAAS;AACjD,MAAI,KAAK,oBAAoB;AAC7B,UAAQ,GAAG,MAAM,OAAO;AACxB,MAAI;AAEF,YAAQ,MAAM,IAAI;AAClB,WAAO,QAAQ,GAAG;EACnB,SAAQ,GAAP;AACA,WAAO;EACR;AACH;AAEA,MAAM,eAAe,SAAUG,KAAI;AACjC,QAAM,iBAAiB,EAAE,YAAY,CAAE,GAAE,cAAc,CAAE,EAAA;AACzD,QAAM,YAAYA,IAAG;AACrB,MAAI,KAAK,gBAAgB,SAAS;AAClC,YAAU,QAAQ,SAAU,UAAU;AACpC,aAAS,MAAM,QAAQ,SAAU,MAAM;AACrC,qBAAe,WAAW,IAAI,IAAI,SAAS;AAC3C,UAAI,eAAe,aAAa,SAAS,EAAE,MAAM,QAAW;AAC1D,uBAAe,aAAa,SAAS,EAAE,IAAI,CAAA;AAAA,MAC5C;AACD,qBAAe,aAAa,SAAS,EAAE,EAAE,KAAK,IAAI;AAAA,IACxD,CAAK;AAAA,EACL,CAAG;AAED,YAAU,QAAQ,SAAU,UAAU;AACxC,KAAiB,EAAE,IAAI,SAAS,GAAK;AACjC,QAAI,eAAe,WAAW,SAAS,EAAE,MAAM,QAAW;AAC1C,qBAAe,WAAW,SAAS,EAAE;AAAA,IACpD;AAAA,EACL,CAAG;AACD,SAAO;AACT;AAEA,MAAM,aAAa,SAAU,KAAK,MAAM,gBAAgB;AACtD,QAAM,WAAW,mBAAmB,KAAK,MAAM,cAAc;AAC7D,MAAI,aAAa,UAAa,aAAa,QAAQ;AACjD,WAAO,EAAE,GAAG,GAAG,GAAG,EAAC;AAAA,EACpB;AAED,QAAM,iBAAiB,OAAO,QAAQ,EAAE;AACxC,SAAO,EAAE,GAAG,eAAe,MAAM,GAAG,eAAe;AACrD;AAEA,MAAM,aAAa,SAAU,SAAS,MAAM,UAAU,SAAS,gBAAgB;AAC7E,QAAM,SAAS,WAAW,KAAK,UAAU,KAAK,UAAU,cAAc;AAEtE,QAAM,MAAM,KAAK,SAAS,CAAC,EAAE;AAC7B,QAAM,OAAO,KAAK,SAAS,CAAC,EAAE;AAC9B,QAAM,WAAW,KAAK,SAAS,CAAC,EAAE,aAAa,KAAK,SAAS,CAAC,EAAE,aAAa,CAAA;AAE7E,QAAM,YAAY,SAAS,IAAI,CAAC,YAAY,CAAC,QAAQ,IAAI,OAAO,GAAG,QAAQ,IAAI,OAAO,CAAC,CAAC;AACxF,QAAM,SAAS;AAAA,IACb,CAAC,IAAI,IAAI,OAAO,GAAG,IAAI,IAAI,OAAO,CAAC;AAAA,IACnC,GAAG;AAAA,IACH,CAAC,KAAK,IAAI,OAAO,GAAG,KAAK,IAAI,OAAO,CAAC;AAAA,EACzC;AAGE,QAAM,QAAQ,KAAI,EAAG,MAAM,WAAW;AACtC,QAAM,WAAW,QACd,OAAO,MAAM,EACb,KAAK,KAAK,MAAM,MAAM,CAAC,EACvB,KAAK,SAAS,MAAM,EACpB,KAAK,QAAQ,MAAM;AACtB,QAAM,QAAQ,QAAQ,OAAO,GAAG,EAAE,KAAK,SAAS,WAAW;AAC3D,QAAM,gBAAgB,OAAO,MAAM,KAAM,EAAC,YAAY,KAAK,OAAO,CAAC;AACnE,QAAM,MAAM,cAAc,KAAM,EAAC,WAAW,sBAAqB;AACjE,gBAAc,KAAK,SAAS,IAAI,KAAK;AACrC,gBAAc,KAAK,UAAU,IAAI,MAAM;AAEvC,QAAM;AAAA,IACJ;AAAA,IACA,aAAa,KAAK,OAAO,CAAC,EAAE,IAAI,OAAO,MAAM,KAAK,OAAO,CAAC,EAAE,IAAI,OAAO;AAAA,EAC3E;AACE,mBAAiB,UAAU,UAAU,QAAQ,MAAM,QAAQ,mBAAmB;AAChF;AASA,MAAM,iBAAiB,CAAC,WAAW,mBAAmB;AACpD,YAAU,QAAQ,CAAC,SAAS;AAE1B,QAAI,CAAC,KAAK,UAAU;AAClB,WAAK,WAAW;IACjB;AAED,UAAM,WAAW,eAAe,aAAa,KAAK,EAAE;AAEpD,QAAI,UAAU;AACZ,eAAS,QAAQ,CAAC,YAAY;AAC5B,aAAK,SAAS,KAAK,OAAO,OAAO,CAAC;AAAA,MAC1C,CAAO;AAAA,IACF;AAED,mBAAe,KAAK,UAAU,cAAc;AAAA,EAChD,CAAG;AACH;AASO,MAAM,OAAO,eAAgB,MAAM,IAAI,UAAU,SAAS;;AAE/D,UAAQ,GAAG;AACX,WAAS,CAAA;AACT,UAAQ,GAAG,OAAO,OAAO;AAEzB,UAAQ,OAAO,MAAM,IAAI;AAEzB,QAAM,WAAW,OAAO,MAAM,EAAE,OAAO,KAAK,EAAE,KAAK,SAAS,cAAc,EAAE,KAAK,MAAM,IAAI;AAC3F,MAAI,QAAQ;AAAA,IACV,IAAI;AAAA,IACJ,eAAe;AAAA,MACb,yBAAyB;AAAA,MACzB,2BAA2B;AAAA,MAC3B,6CAA6C;AAAA;AAAA,MAE7C,iBAAiB;AAAA;AAAA;AAAA,IAGlB;AAAA,IACD,UAAU,CAAE;AAAA,IACZ,OAAO,CAAE;AAAA,EACb;AACE,MAAI,KAAK,uCAAuC,GAAG;AAInD,MAAI,MAAM,QAAQ,GAAG,aAAY;AACjC,UAAQ,KAAG;AAAA,IACT,KAAK;AACH,YAAM,cAAc,eAAe,IAAI;AACvC;AAAA,IACF,KAAK;AACH,YAAM,cAAc,eAAe,IAAI;AACvC;AAAA,IACF,KAAK;AACH,YAAM,cAAc,eAAe,IAAI;AACvC;AAAA,IACF,KAAK;AACH,YAAM,cAAc,eAAe,IAAI;AACvC;AAAA,EACH;AACD,QAAM,EAAE,eAAe,WAAWC,MAAM,IAAG,UAAS;AAIpD,MAAI;AACJ,MAAI,kBAAkB,WAAW;AAC/B,qBAAiB,OAAO,OAAO,EAAE;AAAA,EAClC;AACD,QAAM,OACJ,kBAAkB,YACd,OAAO,eAAe,MAAK,EAAG,CAAC,EAAE,gBAAgB,IAAI,IACrD,OAAO,MAAM;AACnB,QAAM,MAAM,kBAAkB,YAAY,eAAe,MAAK,EAAG,CAAC,EAAE,kBAAkB;AAEtF,QAAM,MAAM,KAAK,OAAO,QAAQ,MAAM;AAGtC,QAAM,UAAU,CAAC,SAAS,UAAU,OAAO;AAG3C,gBAAc,KAAK,SAAS,QAAQ,MAAM,QAAQ,mBAAmB;AAGrE,QAAM,OAAO,QAAQ,GAAG,YAAW;AAInC,MAAI;AACJ,QAAM,YAAY,QAAQ,GAAG,aAAY;AACzC,MAAI,KAAK,gBAAgB,SAAS;AAClC,WAAS,IAAI,UAAU,SAAS,GAAG,KAAK,GAAG,KAAK;AAC9C,WAAO,UAAU,CAAC;AAClB,YAAQ,GAAG,UAAU,KAAK,IAAI,KAAK,OAAO,SAAS,QAAW,KAAK,SAAS,KAAK,GAAG;AAAA,EACrF;AAID,QAAM,cAAc,IAAI,OAAO,GAAG,EAAE,KAAK,SAAS,WAAW;AAI7D,QAAM,iBAAiB,aAAa,QAAQ,EAAE;AAM9C,UAAQ,YAAY,MAAM,IAAI,MAAM,KAAK,SAAS,gBAAgB,KAAK;AAGvE,QAAM,UAAU,IAAI,OAAO,GAAG,EAAE,KAAK,SAAS,gBAAgB;AAE9D,QAAM,QAAQ,QAAQ,GAAG,SAAQ;AAGjC,UAAQ,SAAS,OAAO,SAAS,OAAO,GAAG;AAG3C,QAAM,QAAQ,OAAO,KAAK,MAAM;AAChC,QAAM,QAAQ,CAAC,WAAW;AACxB,UAAM,OAAO,OAAO,MAAM;AAC1B,QAAI,CAAC,KAAK,QAAQ;AAChB,YAAM,SAAS,KAAK,IAAI;AAAA,IACzB;AAED,QAAI,eAAe,aAAa,MAAM,MAAM,QAAW;AACrD,WAAK,SAAS;AAAA,QACZ;AAAA,UACE,MAAM,KAAK;AAAA,UACX,eAAe;AAAA,YACb,wBAAwB;AAAA,UACzB;AAAA,UACD,OAAO,KAAK,UAAU;AAAA,UACtB,QAAQ,KAAK,UAAU;AAAA,QACxB;AAAA,MACT;AACM,aAAO,KAAK;AACZ,aAAO,KAAK;AACZ,aAAO,KAAK;AACZ,aAAO,KAAK;AAAA,IACb;AAAA,EACL,CAAG;AACD,iBAAe,MAAM,UAAU,cAAc;AAC7C,MAAI,KAAK,gBAAgB,KAAK,UAAU,OAAO,MAAM,CAAC,CAAC;AACvD,QAAM,IAAI,MAAM,IAAI,OAAO,KAAK;AAChC,YAAU,GAAG,GAAG,EAAE,UAAU,KAAK,aAAa,SAAS,CAAC;AACxD,MAAI,KAAK,gBAAgB,CAAC;AAC1B,UAAE,UAAF,mBAAS,IAAI,CAAC,SAAS;AACrB,eAAW,SAAS,MAAM,KAAK,UAAU,SAAS,cAAc;AAAA,EACpE;AACE,oBAAkB,CAAE,GAAE,KAAKA,MAAK,gBAAgBA,MAAK,WAAW;AAEhE,WAAS,OAAM;AACjB;AAEA,MAAM,YAAY,CAAC,MAAM,MAAM,WAAW,KAAK,aAAa,SAAS,UAAU;AAC7E,YAAU,QAAQ,SAAU,MAAM;AAChC,QAAI,MAAM;AACR,aAAO,KAAK,EAAE,EAAE,SAAS;AAAA,QACvB,MAAM,KAAK,IAAI;AAAA,QACf,MAAM,KAAK,IAAI;AAAA,QACf,GAAG;AAAA,QACH,GAAG;AAAA,QACH;AAAA,QACA,OAAO,KAAK;AAAA,QACZ,QAAQ,KAAK;AAAA,MACrB;AACM,UAAI,KAAK,SAAS,SAAS;AACzB,cAAM,aAAa,YAAY,OAAO,GAAG,EAAE,KAAK,SAAS,UAAU;AACnE,mBACG,OAAO,MAAM,EACb,KAAK,SAAS,2BAA4B,QAAQ,IAAK,OAAO,EAC9D,KAAK,KAAK,KAAK,IAAI,IAAI,EACvB,KAAK,KAAK,KAAK,IAAI,IAAI,EACvB,KAAK,SAAS,KAAK,KAAK,EACxB,KAAK,UAAU,KAAK,MAAM;AAC7B,cAAM,QAAQ,WAAW,OAAO,GAAG,EAAE,KAAK,SAAS,OAAO;AAC1D,cAAM;AAAA,UACJ;AAAA,UACA,aAAa,KAAK,OAAO,CAAC,EAAE,IAAI,OAAO,KAAK,MAAM,KAAK,OAAO,CAAC,EAAE,IAAI,OAAO,KAAK;AAAA,QAC3F;AACQ,cAAM,KAAI,EAAG,YAAY,KAAK,UAAU,SAAS;AAEjD,YAAI,KAAK,cAAc,KAAK,MAAM,KAAK,MAAM;AAAA,MACrD,OAAa;AACL,YAAI,KAAK,cAAc,KAAK,EAAE;AAC9B,aAAK,GAAG;AAAA,UACN;AAAA,UACA,aAAa,KAAK,IAAI,OAAO,KAAK,QAAQ,MAAM,KAAK,IAAI,OAAO,KAAK,SAAS;AAAA,QACxF;AAAA,MACO;AAAA,IACF;AAAA,EACL,CAAG;AACD,YAAU,QAAQ,SAAU,MAAM;AAChC,QAAI,QAAQ,KAAK,SAAS,SAAS;AACjC,gBAAU,OAAO,KAAK,GAAG,OAAO,KAAK,GAAG,KAAK,UAAU,KAAK,aAAa,SAAS,QAAQ,CAAC;AAAA,IAC5F;AAAA,EACL,CAAG;AACH;AAEA,MAAe,WAAA;AAAA,EACb;AAAA,EACA;AACF;AC56BA,MAAM,cAAc,CAAC,YAAmC;AACtD,MAAI,WAAW;AAEf,WAAS,IAAI,GAAG,IAAI,GAAG,KAAK;AACd,gBAAA;AAAA,sBACM;AAAA,gBACN,QAAQ,UAAU,GAAG;AAAA,kBACnB,QAAQ,cAAc,GAAG;AAAA;AAAA;AAAA,EAGzC;AACO,SAAA;AACT;AAEA,MAAM,YAAY,CAAC,YACjB;AAAA,mBACiB,QAAQ;AAAA,aACd,QAAQ,iBAAiB,QAAQ;AAAA;AAAA;AAAA,YAGlC,QAAQ;AAAA;AAAA;AAAA,aAGP,QAAQ;AAAA;AAAA;AAAA;AAAA,YAIT,QAAQ,iBAAiB,QAAQ;AAAA,aAChC,QAAQ,iBAAiB,QAAQ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,YAQlC,QAAQ;AAAA,cACN,QAAQ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,YAYV,QAAQ;AAAA;AAAA;AAAA;AAAA,cAIN,QAAQ;AAAA;AAAA;AAAA;AAAA;AAAA,cAKR,QAAQ;AAAA;AAAA;AAAA;AAAA;AAAA,wBAKE,QAAQ;AAAA;AAAA;AAAA,0BAGN,QAAQ;AAAA,cACpB,QAAQ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,YAMV,QAAQ;AAAA,cACN,QAAQ;AAAA;AAAA;AAAA;AAAA;AAAA,YAKV,QAAQ;AAAA;AAAA;AAAA;AAAA,aAIP,QAAQ;AAAA;AAAA;AAAA,aAGR,QAAQ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,mBAQF,QAAQ;AAAA;AAAA,kBAET,QAAQ;AAAA,wBACF,QAAQ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,YASpB,QAAQ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAUhB,YAAY,OAAO;AAAA;AAGvB,MAAA,SAAe;AClIR,MAAM,UAAU;AAAA,EACrB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;"} |