From 86e1bb38eecfd4179fe9b296f111d8e53d586fb6 Mon Sep 17 00:00:00 2001 From: Knut Sveidqvist Date: Wed, 5 Jul 2023 12:01:37 +0200 Subject: [PATCH 001/217] #3358 First commit with basic grammar and 1st test --- packages/mermaid/src/config.type.ts | 4 + .../src/diagrams/blockDiagram/blockDB.ts | 35 ++++ .../src/diagrams/blockDiagram/blockDiagram.ts | 15 ++ .../blockDiagram/blockDiagramDetector.ts | 20 ++ .../blockDiagram/blockDiagramRenderer.ts | 63 ++++++ .../blockDiagram/blockDiagramUtils.ts | 8 + .../blockDiagram/parser/blockDiagram.jison | 195 ++++++++++++++++++ .../blockDiagram/parser/blockDiagram.spec.ts | 85 ++++++++ .../mermaid/src/docs/.vitepress/block.mmd | 33 +++ 9 files changed, 458 insertions(+) create mode 100644 packages/mermaid/src/diagrams/blockDiagram/blockDB.ts create mode 100644 packages/mermaid/src/diagrams/blockDiagram/blockDiagram.ts create mode 100644 packages/mermaid/src/diagrams/blockDiagram/blockDiagramDetector.ts create mode 100644 packages/mermaid/src/diagrams/blockDiagram/blockDiagramRenderer.ts create mode 100644 packages/mermaid/src/diagrams/blockDiagram/blockDiagramUtils.ts create mode 100644 packages/mermaid/src/diagrams/blockDiagram/parser/blockDiagram.jison create mode 100644 packages/mermaid/src/diagrams/blockDiagram/parser/blockDiagram.spec.ts create mode 100644 packages/mermaid/src/docs/.vitepress/block.mmd diff --git a/packages/mermaid/src/config.type.ts b/packages/mermaid/src/config.type.ts index 138eee44f3..a784b9d300 100644 --- a/packages/mermaid/src/config.type.ts +++ b/packages/mermaid/src/config.type.ts @@ -33,6 +33,7 @@ export interface MermaidConfig { gitGraph?: GitGraphDiagramConfig; c4?: C4DiagramConfig; sankey?: SankeyDiagramConfig; + blockDiagram?: BlockDiagramConfig; dompurifyConfig?: DOMPurify.Config; wrap?: boolean; fontSize?: number; @@ -421,6 +422,9 @@ export interface SankeyDiagramConfig extends BaseDiagramConfig { linkColor?: SankeyLinkColor | string; nodeAlignment?: SankeyNodeAlignment; } +export interface BlockDiagramConfig extends BaseDiagramConfig { + padding?: number; +} export interface FontConfig { fontSize?: string | number; diff --git a/packages/mermaid/src/diagrams/blockDiagram/blockDB.ts b/packages/mermaid/src/diagrams/blockDiagram/blockDB.ts new file mode 100644 index 0000000000..265835cd7d --- /dev/null +++ b/packages/mermaid/src/diagrams/blockDiagram/blockDB.ts @@ -0,0 +1,35 @@ +import * as configApi from '../../config.js'; +import common from '../common/common.js'; +import { + setAccTitle, + getAccTitle, + getAccDescription, + setAccDescription, + setDiagramTitle, + getDiagramTitle, + clear as commonClear, +} from '../../commonDb.js'; + +type Block = { + ID: string; +}; + +// Array of nodes guarantees their order +let blocks: Block[] = []; + +const clear = (): void => { + blocks = []; + commonClear(); +}; + +export default { + getConfig: () => configApi.getConfig().blockDiagram, + + getAccTitle, + setAccTitle, + getAccDescription, + setAccDescription, + getDiagramTitle, + setDiagramTitle, + clear, +}; diff --git a/packages/mermaid/src/diagrams/blockDiagram/blockDiagram.ts b/packages/mermaid/src/diagrams/blockDiagram/blockDiagram.ts new file mode 100644 index 0000000000..c3913a7f29 --- /dev/null +++ b/packages/mermaid/src/diagrams/blockDiagram/blockDiagram.ts @@ -0,0 +1,15 @@ +import { DiagramDefinition } from '../../diagram-api/types.js'; +// @ts-ignore: jison doesn't export types +import parser from './parser/sankey.jison'; +import db from './blockDB.js'; +import renderer from './blockDiagramRenderer.js'; +import { prepareTextForParsing } from './blockDiagramUtils.js'; + +const originalParse = parser.parse.bind(parser); +parser.parse = (text: string) => originalParse(prepareTextForParsing(text)); + +export const diagram: DiagramDefinition = { + parser, + db, + renderer, +}; diff --git a/packages/mermaid/src/diagrams/blockDiagram/blockDiagramDetector.ts b/packages/mermaid/src/diagrams/blockDiagram/blockDiagramDetector.ts new file mode 100644 index 0000000000..41dc911275 --- /dev/null +++ b/packages/mermaid/src/diagrams/blockDiagram/blockDiagramDetector.ts @@ -0,0 +1,20 @@ +import type { DiagramDetector, ExternalDiagramDefinition } from '../../diagram-api/types.js'; + +const id = 'sankey'; + +const detector: DiagramDetector = (txt) => { + return /^\s*blockDiagram-beta/.test(txt); +}; + +const loader = async () => { + const { diagram } = await import('./blockDiagram.js'); + return { id, diagram }; +}; + +const plugin: ExternalDiagramDefinition = { + id, + detector, + loader, +}; + +export default plugin; diff --git a/packages/mermaid/src/diagrams/blockDiagram/blockDiagramRenderer.ts b/packages/mermaid/src/diagrams/blockDiagram/blockDiagramRenderer.ts new file mode 100644 index 0000000000..5a2f595bcf --- /dev/null +++ b/packages/mermaid/src/diagrams/blockDiagram/blockDiagramRenderer.ts @@ -0,0 +1,63 @@ +import { Diagram } from '../../Diagram.js'; +import * as configApi from '../../config.js'; + +import { + select as d3select, + scaleOrdinal as d3scaleOrdinal, + schemeTableau10 as d3schemeTableau10, +} from 'd3'; + +import { configureSvgSize } from '../../setupGraphViewbox.js'; +import { Uid } from '../../rendering-util/uid.js'; +import type { SankeyLinkColor, SankeyNodeAlignment } from '../../config.type.js'; + +export const draw = function (text: string, id: string, _version: string, diagObj: Diagram): void { + // Get the config + const { securityLevel, sankey: conf } = configApi.getConfig(); + const defaultSankeyConfig = configApi!.defaultConfig!.blockDiagram!; + + // TODO: + // This code repeats for every diagram + // Figure out what is happening there, probably it should be separated + // The main thing is svg object that is a d3 wrapper for svg operations + // + let sandboxElement: any; + if (securityLevel === 'sandbox') { + sandboxElement = d3select('#i' + id); + } + const root = + securityLevel === 'sandbox' + ? d3select(sandboxElement.nodes()[0].contentDocument.body) + : d3select('body'); + // @ts-ignore TODO root.select is not callable + const svg = securityLevel === 'sandbox' ? root.select(`[id="${id}"]`) : d3select(`[id="${id}"]`); + + // Establish svg dimensions and get width and height + // + + // FIX: using max width prevents height from being set, is it intended? + // to add height directly one can use `svg.attr('height', height)` + // + // @ts-ignore TODO: svg type vs selection mismatch + configureSvgSize(svg, height, width, useMaxWidth); + + // Prepare data for construction based on diagObj.db + // This must be a mutable object with `nodes` and `links` properties: + // + // { + // "nodes": [ { "id": "Alice" }, { "id": "Bob" }, { "id": "Carol" } ], + // "links": [ { "source": "Alice", "target": "Bob", "value": 23 }, { "source": "Bob", "target": "Carol", "value": 43 } ] + // } + // + // @ts-ignore TODO: db type + const graph = diagObj.db.getGraph(); + + const nodeWidth = 10; + + // Get color scheme for the graph + const colorScheme = d3scaleOrdinal(d3schemeTableau10); +}; + +export default { + draw, +}; diff --git a/packages/mermaid/src/diagrams/blockDiagram/blockDiagramUtils.ts b/packages/mermaid/src/diagrams/blockDiagram/blockDiagramUtils.ts new file mode 100644 index 0000000000..45ecf21dda --- /dev/null +++ b/packages/mermaid/src/diagrams/blockDiagram/blockDiagramUtils.ts @@ -0,0 +1,8 @@ +export const prepareTextForParsing = (text: string): string => { + const textToParse = text + .replaceAll(/^[^\S\n\r]+|[^\S\n\r]+$/g, '') // remove all trailing spaces for each row + .replaceAll(/([\n\r])+/g, '\n') // remove empty lines duplicated + .trim(); + + return textToParse; +}; diff --git a/packages/mermaid/src/diagrams/blockDiagram/parser/blockDiagram.jison b/packages/mermaid/src/diagrams/blockDiagram/parser/blockDiagram.jison new file mode 100644 index 0000000000..aced2c0237 --- /dev/null +++ b/packages/mermaid/src/diagrams/blockDiagram/parser/blockDiagram.jison @@ -0,0 +1,195 @@ +/** mermaid */ + +//--------------------------------------------------------- +// We support csv format as defined here: +// https://www.ietf.org/rfc/rfc4180.txt +// There are some minor changes for compliance with jison +// We also parse only 3 columns: source,target,value +// And allow blank lines for visual purposes +//--------------------------------------------------------- + +%lex +%x acc_title +%x acc_descr +%x acc_descr_multiline +%x string +%x md_string +%x NODE +%options easy_keword_rules + + +// as per section 6.1 of RFC 2234 [2] +COMMA \u002C +CR \u000D +LF \u000A +CRLF \u000D\u000A + + +%% + +"blockDiagram-beta" { return 'BLOCK_DIAGRAM_KEY'; } +// \s*\%\%.* { yy.getLogger().info('Found comment',yytext); } +[\s]+ { yy.getLogger().info('.', yytext); /* skip all whitespace */ } +[\n]+ {yy.getLogger().info('_', yytext); /* skip all whitespace */ } +// [\n] return 'NL'; +({CRLF}|{LF}) { return 'NL' } +["][`] { this.begin("md_string");} +[^`"]+ { return "MD_STR";} +[`]["] { this.popState();} +["] this.begin("string"); +["] this.popState(); +[^"]* return "STR"; +"style" return 'STYLE'; +"default" return 'DEFAULT'; +"linkStyle" return 'LINKSTYLE'; +"interpolate" return 'INTERPOLATE'; +"classDef" return 'CLASSDEF'; +"class" return 'CLASS'; +accTitle\s*":"\s* { this.begin("acc_title");return 'acc_title'; } +(?!\n|;|#)*[^\n]* { this.popState(); return "acc_title_value"; } +accDescr\s*":"\s* { this.begin("acc_descr");return 'acc_descr'; } +(?!\n|;|#)*[^\n]* { this.popState(); return "acc_descr_value"; } +accDescr\s*"{"\s* { this.begin("acc_descr_multiline");} +[\}] { this.popState(); } +[^\}]* return "acc_descr_multiline_value"; +"subgraph" return 'subgraph'; +"end"\b\s* return 'end'; +.*direction\s+TB[^\n]* return 'direction_tb'; +.*direction\s+BT[^\n]* return 'direction_bt'; +.*direction\s+RL[^\n]* return 'direction_rl'; +.*direction\s+LR[^\n]* return 'direction_lr'; + +// Start of nodes with shapes and description +"-)" { yy.getLogger().info('Lex: -)'); this.begin('NODE');return 'NODE_D START'; } +"(-" { yy.getLogger().info('Lex: (-'); this.begin('NODE');return 'NODE_DSTART'; } +"))" { yy.getLogger().info('Lex: ))'); this.begin('NODE');return 'NODE_DSTART'; } +")" { yy.getLogger().info('Lex: )'); this.begin('NODE');return 'NODE_DSTART'; } +"((" { yy.getLogger().info('Lex: )'); this.begin('NODE');return 'NODE_DSTART'; } +"{{" { yy.getLogger().info('Lex: )'); this.begin('NODE');return 'NODE_DSTART'; } +"(" { yy.getLogger().info('Lex: )'); this.begin('NODE');return 'NODE_DSTART'; } +"[" { yy.getLogger().info('Lex: ['); this.begin('NODE');return 'NODE_DSTART'; } +"([" { yy.getLogger().info('Lex: )'); this.begin('NODE');return 'NODE_DSTART'; } +"[[" { this.begin('NODE');return 'NODE_DSTART'; } +"[|" { this.begin('NODE');return 'NODE_DSTART'; } +"[(" { this.begin('NODE');return 'NODE_DSTART'; } +"(((" { this.begin('NODE');return 'NODE_DSTART'; } +")))" { this.begin('NODE');return 'NODE_DSTART'; } +"[/" { this.begin('NODE');return 'NODE_DSTART'; } +"[\\" { this.begin('NODE');return 'NODE_DSTART'; } + + +[^\(\[\n\-\)\{\}]+ { yy.getLogger().info('Lex: NODE_ID', yytext);return 'NODE_ID'; } +<> { yy.getLogger().info('Lex: EOF', yytext);return 'EOF'; } + +// Handling of strings in node +["][`] { this.begin("md_string");} +[^`"]+ { return "NODE_DESCR";} +[`]["] { this.popState();} +["] { yy.getLogger().info('Lex: Starting string');this.begin("string");} +[^"]+ { yy.getLogger().info('Lex: NODE_DESCR:', yytext); return "NODE_DESCR";} +["] {this.popState();} + +// Node end of shape +[\)]\) { this.popState();yy.getLogger().info('Lex: ))'); return "NODE_DEND"; } +[\)] { this.popState();yy.getLogger().info('Lex: )'); return "NODE_DEND"; } +[\]] { this.popState();yy.getLogger().info('Lex: ]'); return "NODE_DEND"; } +"}}" { this.popState();yy.getLogger().info('Lex: (('); return "NODE_DEND"; } +"(-" { this.popState();yy.getLogger().info('Lex: (-'); return "NODE_DEND"; } +"-)" { this.popState();yy.getLogger().info('Lex: -)'); return "NODE_DEND"; } +"((" { this.popState();yy.getLogger().info('Lex: (('); return "NODE_DEND"; } +"(" { this.popState();yy.getLogger().info('Lex: ('); return "NODE_DEND"; } +"])" { this.popState();yy.getLogger().info('Lex: ])'); return "NODE_DEND"; } +"]]" { this.popState();yy.getLogger().info('Lex: ]]'); return "NODE_DEND"; } +"/]" { this.popState();yy.getLogger().info('Lex: /]'); return "NODE_DEND"; } +")]" { this.popState();yy.getLogger().info('Lex: )]'); return "NODE_DEND"; } + +// Edges +\s*[xo<]?\-\-+[-xo>]\s* { yy.getLogger().info('Lex: LINK', '#'+yytext+'#'); return 'LINK'; } +\s*[xo<]?\=\=+[=xo>]\s* { yy.getLogger().info('Lex: LINK', yytext); return 'LINK'; } +\s*[xo<]?\-?\.+\-[xo>]?\s* { yy.getLogger().info('Lex: LINK', yytext); return 'LINK'; } +\s*\~\~[\~]+\s* { yy.getLogger().info('Lex: LINK', yytext); return 'LINK'; } +\s*[xo<]?\-\-\s* { yy.getLogger().info('Lex: START_LINK', yytext); return 'START_LINK'; } +\s*[xo<]?\=\=\s* { yy.getLogger().info('Lex: START_LINK', yytext); return 'START_LINK'; } +\s*[xo<]?\-\.\s* { yy.getLogger().info('Lex: START_LINK', yytext); return 'START_LINK'; } + +/lex + +%start start + +%% // language grammar + +spaceLines + : SPACELINE + | spaceLines SPACELINE + | spaceLines NL + ; + +seperator + : NL + {yy.getLogger().info('Rule: seperator (NL) ');} + | SPACE + {yy.getLogger().info('Rule: seperator (Space) ');} + | EOF + {yy.getLogger().info('Rule: seperator (EOF) ');} + ; + +start: BLOCK_DIAGRAM_KEY document; + +blockDiagram + : blockDiagram document { return yy; } + | blockDiagram NL document { return yy; } + ; + +stop + : NL {yy.getLogger().info('Stop NL ');} + | EOF {yy.getLogger().info('Stop EOF ');} + // | SPACELINE + | stop NL {yy.getLogger().info('Stop NL2 ');} + | stop EOF {yy.getLogger().info('Stop EOF2 ');} + ; + +document + : document statement + | statement + ; + +link + : LINK + { yy.getLogger().info("Rule: link: ", $1); } + | START_LINK + { yy.getLogger().info("Rule: link: ", $1); } + ; + +statement + : nodeStatement +// SPACELIST node { yy.getLogger().info('Node: ',$2.id);yy.addNode($1.length, $2.id, $2.descr, $2.type); } +// | SPACELIST ICON { yy.getLogger().info('Icon: ',$2);yy.decorateNode({icon: $2}); } +// | SPACELIST CLASS { yy.decorateNode({class: $2}); } +// | SPACELINE { yy.getLogger().info('SPACELIST');} +// | +// node { yy.getLogger().info('Node: ',$1.id);yy.addNode(0, $1.id, $1.descr, $1.type); } +// | ICON { yy.decorateNode({icon: $1}); } +// | CLASS { yy.decorateNode({class: $1}); } +// // | SPACELIST + | EOF + ; + +nodeStatement: nodeStatement link node { yy.getLogger().info('Rule: nodeStatement (nodeStatement link node) ');} + |node { yy.getLogger().info('Rule: nodeStatement (node) ');} + ; + +node + : NODE_ID + { yy.getLogger().info("Rule: node (NODE_ID seperator): ", $1); } + |NODE_ID nodeShapeNLabel + { yy.getLogger().info("Rule: node (NODE_ID nodeShapeNLabel seperator): ", $1, $2); } + // |nodeShapeNLabel seperator + // { yy.getLogger().info("Rule: node (nodeShapeNLabel seperator): ", $1, $2, $3); } + ; + +nodeShapeNLabel + : NODE_DSTART STR NODE_DEND + { yy.getLogger().info("Rule: nodeShapeNLabel: ", $1, $2, $3); $$ = { type: $1 + $3, descr: $2 }; } + ; + +%% diff --git a/packages/mermaid/src/diagrams/blockDiagram/parser/blockDiagram.spec.ts b/packages/mermaid/src/diagrams/blockDiagram/parser/blockDiagram.spec.ts new file mode 100644 index 0000000000..3c076c04fd --- /dev/null +++ b/packages/mermaid/src/diagrams/blockDiagram/parser/blockDiagram.spec.ts @@ -0,0 +1,85 @@ +// @ts-ignore: jison doesn't export types +import blockDiagram from './blockDiagram.jison'; +import db from '../blockDB.js'; +import { cleanupComments } from '../../../diagram-api/comments.js'; +import { prepareTextForParsing } from '../blockDiagramUtils.js'; +import * as fs from 'fs'; +import * as path from 'path'; + +describe('Sankey diagram', function () { + describe('when parsing an block diagram graph it should handle > ', function () { + beforeEach(function () { + blockDiagram.parser.yy = db; + blockDiagram.parser.yy.clear(); + blockDiagram.parser.yy.getLogger = () => console; + }); + + it('a diagram with a node', async () => { + const str = `blockDiagram-beta + id + `; + + blockDiagram.parse(str); + }); + it('a diagram with multiple nodes', async () => { + const str = `blockDiagram-beta + id1 + id2 + `; + + blockDiagram.parse(str); + }); + it('a node with a square shape and a label', async () => { + const str = `blockDiagram-beta + id["A label"] + id2`; + + blockDiagram.parse(str); + }); + it('a diagram with multiple nodes with edges', async () => { + const str = `blockDiagram-beta + id1["first"] --> id2["second"] + `; + + blockDiagram.parse(str); + }); + // it('a diagram with column statements', async () => { + // const str = `blockDiagram-beta + // columns 1 + // block1["Block 1"] + // `; + + // blockDiagram.parse(str); + // }); + // it('a diagram with block hierarchies', async () => { + // const str = `blockDiagram-beta + // columns 1 + // block1[Block 1] + + // block + // columns 2 + // block2[Block 2] + // block3[Block 3] + // end %% End the compound block + // `; + + // blockDiagram.parse(str); + // }); + // it('a diagram with differernt column values in different blocks', async () => { + // const str = `blockDiagram-beta + // columns 1 + // block1[Block 1] + + // block + // columns 2 + // block2[Block 2] + // block3[Block 3] + // end %% End the compound block + // `; + + // blockDiagram.parse(str); + + // // Todo check that the different blocks have different column values + // }); + }); +}); diff --git a/packages/mermaid/src/docs/.vitepress/block.mmd b/packages/mermaid/src/docs/.vitepress/block.mmd new file mode 100644 index 0000000000..7ce628f446 --- /dev/null +++ b/packages/mermaid/src/docs/.vitepress/block.mmd @@ -0,0 +1,33 @@ +block + columns 3 + Block1 + Block2["Block 2"] + block + columns 2 + Block2.1 + Block2.2 + end + Block3 + + +---- + +block + columns 2 + Block[Frontend]:vertical + + block "Document management System" + columns 3 + MO[Manager Operation]:vertical + block + columns 2 + block "Security and User Manager" + end + + +---- +block frontend:vertical +move right +block "Document Management System" +move down + From 791e67641eafe845b243ace394749f9fc2b2602c Mon Sep 17 00:00:00 2001 From: Nikolay Rozhkov Date: Fri, 7 Jul 2023 13:58:30 +0300 Subject: [PATCH 002/217] Rename BlockDiagram to Block --- packages/mermaid/src/config.type.ts | 2 +- .../src/diagram-api/diagram-orchestration.ts | 4 +- .../{blockDiagram => block}/blockDB.ts | 2 +- .../blockDetector.ts} | 4 +- .../{blockDiagram => block}/blockDiagram.ts | 6 +-- .../blockRenderer.ts} | 0 .../mermaid/src/diagrams/block/blockTypes.ts | 5 +++ .../blockUtils.ts} | 0 .../parser/block.jison} | 2 +- .../parser/block.spec.ts} | 38 +++++++++---------- 10 files changed, 35 insertions(+), 28 deletions(-) rename packages/mermaid/src/diagrams/{blockDiagram => block}/blockDB.ts (91%) rename packages/mermaid/src/diagrams/{blockDiagram/blockDiagramDetector.ts => block/blockDetector.ts} (84%) rename packages/mermaid/src/diagrams/{blockDiagram => block}/blockDiagram.ts (68%) rename packages/mermaid/src/diagrams/{blockDiagram/blockDiagramRenderer.ts => block/blockRenderer.ts} (100%) create mode 100644 packages/mermaid/src/diagrams/block/blockTypes.ts rename packages/mermaid/src/diagrams/{blockDiagram/blockDiagramUtils.ts => block/blockUtils.ts} (100%) rename packages/mermaid/src/diagrams/{blockDiagram/parser/blockDiagram.jison => block/parser/block.jison} (98%) rename packages/mermaid/src/diagrams/{blockDiagram/parser/blockDiagram.spec.ts => block/parser/block.spec.ts} (68%) diff --git a/packages/mermaid/src/config.type.ts b/packages/mermaid/src/config.type.ts index a784b9d300..fdb2450ba0 100644 --- a/packages/mermaid/src/config.type.ts +++ b/packages/mermaid/src/config.type.ts @@ -33,7 +33,7 @@ export interface MermaidConfig { gitGraph?: GitGraphDiagramConfig; c4?: C4DiagramConfig; sankey?: SankeyDiagramConfig; - blockDiagram?: BlockDiagramConfig; + block?: BlockDiagramConfig; dompurifyConfig?: DOMPurify.Config; wrap?: boolean; fontSize?: number; diff --git a/packages/mermaid/src/diagram-api/diagram-orchestration.ts b/packages/mermaid/src/diagram-api/diagram-orchestration.ts index 9c03e27f31..470a13fa0a 100644 --- a/packages/mermaid/src/diagram-api/diagram-orchestration.ts +++ b/packages/mermaid/src/diagram-api/diagram-orchestration.ts @@ -19,6 +19,7 @@ import flowchartElk from '../diagrams/flowchart/elk/detector.js'; import timeline from '../diagrams/timeline/detector.js'; import mindmap from '../diagrams/mindmap/detector.js'; import sankey from '../diagrams/sankey/sankeyDetector.js'; +import block from '../diagrams/block/blockDetector.js'; import { registerLazyLoadedDiagrams } from './detectType.js'; import { registerDiagram } from './diagramAPI.js'; @@ -81,6 +82,7 @@ export const addDiagrams = () => { state, journey, quadrantChart, - sankey + sankey, + block ); }; diff --git a/packages/mermaid/src/diagrams/blockDiagram/blockDB.ts b/packages/mermaid/src/diagrams/block/blockDB.ts similarity index 91% rename from packages/mermaid/src/diagrams/blockDiagram/blockDB.ts rename to packages/mermaid/src/diagrams/block/blockDB.ts index 265835cd7d..4cb611b177 100644 --- a/packages/mermaid/src/diagrams/blockDiagram/blockDB.ts +++ b/packages/mermaid/src/diagrams/block/blockDB.ts @@ -23,7 +23,7 @@ const clear = (): void => { }; export default { - getConfig: () => configApi.getConfig().blockDiagram, + getConfig: () => configApi.getConfig().block, getAccTitle, setAccTitle, diff --git a/packages/mermaid/src/diagrams/blockDiagram/blockDiagramDetector.ts b/packages/mermaid/src/diagrams/block/blockDetector.ts similarity index 84% rename from packages/mermaid/src/diagrams/blockDiagram/blockDiagramDetector.ts rename to packages/mermaid/src/diagrams/block/blockDetector.ts index 41dc911275..c4da643f03 100644 --- a/packages/mermaid/src/diagrams/blockDiagram/blockDiagramDetector.ts +++ b/packages/mermaid/src/diagrams/block/blockDetector.ts @@ -1,9 +1,9 @@ import type { DiagramDetector, ExternalDiagramDefinition } from '../../diagram-api/types.js'; -const id = 'sankey'; +const id = 'block'; const detector: DiagramDetector = (txt) => { - return /^\s*blockDiagram-beta/.test(txt); + return /^\s*block-beta/.test(txt); }; const loader = async () => { diff --git a/packages/mermaid/src/diagrams/blockDiagram/blockDiagram.ts b/packages/mermaid/src/diagrams/block/blockDiagram.ts similarity index 68% rename from packages/mermaid/src/diagrams/blockDiagram/blockDiagram.ts rename to packages/mermaid/src/diagrams/block/blockDiagram.ts index c3913a7f29..1cd619749e 100644 --- a/packages/mermaid/src/diagrams/blockDiagram/blockDiagram.ts +++ b/packages/mermaid/src/diagrams/block/blockDiagram.ts @@ -1,9 +1,9 @@ import { DiagramDefinition } from '../../diagram-api/types.js'; // @ts-ignore: jison doesn't export types -import parser from './parser/sankey.jison'; +import parser from './parser/blockDiagram.jison'; import db from './blockDB.js'; -import renderer from './blockDiagramRenderer.js'; -import { prepareTextForParsing } from './blockDiagramUtils.js'; +import renderer from './blockRenderer.js'; +import { prepareTextForParsing } from './blockUtils.js'; const originalParse = parser.parse.bind(parser); parser.parse = (text: string) => originalParse(prepareTextForParsing(text)); diff --git a/packages/mermaid/src/diagrams/blockDiagram/blockDiagramRenderer.ts b/packages/mermaid/src/diagrams/block/blockRenderer.ts similarity index 100% rename from packages/mermaid/src/diagrams/blockDiagram/blockDiagramRenderer.ts rename to packages/mermaid/src/diagrams/block/blockRenderer.ts diff --git a/packages/mermaid/src/diagrams/block/blockTypes.ts b/packages/mermaid/src/diagrams/block/blockTypes.ts new file mode 100644 index 0000000000..28e5cd1679 --- /dev/null +++ b/packages/mermaid/src/diagrams/block/blockTypes.ts @@ -0,0 +1,5 @@ +import type { DiagramDB } from '../../diagram-api/types.js'; + +export interface BlockDB extends DiagramDB { + clear: () => void; +} diff --git a/packages/mermaid/src/diagrams/blockDiagram/blockDiagramUtils.ts b/packages/mermaid/src/diagrams/block/blockUtils.ts similarity index 100% rename from packages/mermaid/src/diagrams/blockDiagram/blockDiagramUtils.ts rename to packages/mermaid/src/diagrams/block/blockUtils.ts diff --git a/packages/mermaid/src/diagrams/blockDiagram/parser/blockDiagram.jison b/packages/mermaid/src/diagrams/block/parser/block.jison similarity index 98% rename from packages/mermaid/src/diagrams/blockDiagram/parser/blockDiagram.jison rename to packages/mermaid/src/diagrams/block/parser/block.jison index aced2c0237..ba58a60971 100644 --- a/packages/mermaid/src/diagrams/blockDiagram/parser/blockDiagram.jison +++ b/packages/mermaid/src/diagrams/block/parser/block.jison @@ -27,7 +27,7 @@ CRLF \u000D\u000A %% -"blockDiagram-beta" { return 'BLOCK_DIAGRAM_KEY'; } +"block-beta" { return 'BLOCK_DIAGRAM_KEY'; } // \s*\%\%.* { yy.getLogger().info('Found comment',yytext); } [\s]+ { yy.getLogger().info('.', yytext); /* skip all whitespace */ } [\n]+ {yy.getLogger().info('_', yytext); /* skip all whitespace */ } diff --git a/packages/mermaid/src/diagrams/blockDiagram/parser/blockDiagram.spec.ts b/packages/mermaid/src/diagrams/block/parser/block.spec.ts similarity index 68% rename from packages/mermaid/src/diagrams/blockDiagram/parser/blockDiagram.spec.ts rename to packages/mermaid/src/diagrams/block/parser/block.spec.ts index 3c076c04fd..08b36c7449 100644 --- a/packages/mermaid/src/diagrams/blockDiagram/parser/blockDiagram.spec.ts +++ b/packages/mermaid/src/diagrams/block/parser/block.spec.ts @@ -1,58 +1,58 @@ // @ts-ignore: jison doesn't export types -import blockDiagram from './blockDiagram.jison'; +import block from './block.jison'; import db from '../blockDB.js'; import { cleanupComments } from '../../../diagram-api/comments.js'; -import { prepareTextForParsing } from '../blockDiagramUtils.js'; +import { prepareTextForParsing } from '../blockUtils.js'; import * as fs from 'fs'; import * as path from 'path'; describe('Sankey diagram', function () { describe('when parsing an block diagram graph it should handle > ', function () { beforeEach(function () { - blockDiagram.parser.yy = db; - blockDiagram.parser.yy.clear(); - blockDiagram.parser.yy.getLogger = () => console; + block.parser.yy = db; + block.parser.yy.clear(); + block.parser.yy.getLogger = () => console; }); it('a diagram with a node', async () => { - const str = `blockDiagram-beta + const str = `block-beta id `; - blockDiagram.parse(str); + block.parse(str); }); it('a diagram with multiple nodes', async () => { - const str = `blockDiagram-beta + const str = `block-beta id1 id2 `; - blockDiagram.parse(str); + block.parse(str); }); it('a node with a square shape and a label', async () => { - const str = `blockDiagram-beta + const str = `block-beta id["A label"] id2`; - blockDiagram.parse(str); + block.parse(str); }); it('a diagram with multiple nodes with edges', async () => { - const str = `blockDiagram-beta + const str = `block-beta id1["first"] --> id2["second"] `; - blockDiagram.parse(str); + block.parse(str); }); // it('a diagram with column statements', async () => { - // const str = `blockDiagram-beta + // const str = `block-beta // columns 1 // block1["Block 1"] // `; - // blockDiagram.parse(str); + // block.parse(str); // }); // it('a diagram with block hierarchies', async () => { - // const str = `blockDiagram-beta + // const str = `block-beta // columns 1 // block1[Block 1] @@ -63,10 +63,10 @@ describe('Sankey diagram', function () { // end %% End the compound block // `; - // blockDiagram.parse(str); + // block.parse(str); // }); // it('a diagram with differernt column values in different blocks', async () => { - // const str = `blockDiagram-beta + // const str = `block-beta // columns 1 // block1[Block 1] @@ -77,7 +77,7 @@ describe('Sankey diagram', function () { // end %% End the compound block // `; - // blockDiagram.parse(str); + // block.parse(str); // // Todo check that the different blocks have different column values // }); From fee2b244a1796bbcb07661062830160d6cc06821 Mon Sep 17 00:00:00 2001 From: Nikolay Rozhkov Date: Fri, 7 Jul 2023 14:12:18 +0300 Subject: [PATCH 003/217] Small cleanup --- packages/mermaid/src/config.type.ts | 6 ++-- .../mermaid/src/diagrams/block/blockDB.ts | 33 ++++++++++--------- .../src/diagrams/block/blockRenderer.ts | 11 +------ .../mermaid/src/diagrams/block/blockTypes.ts | 6 ++++ 4 files changed, 27 insertions(+), 29 deletions(-) diff --git a/packages/mermaid/src/config.type.ts b/packages/mermaid/src/config.type.ts index fdb2450ba0..becfc90e63 100644 --- a/packages/mermaid/src/config.type.ts +++ b/packages/mermaid/src/config.type.ts @@ -1,6 +1,7 @@ // TODO: This was auto generated from defaultConfig. Needs to be verified. import DOMPurify from 'dompurify'; +import { BlockConfig } from './diagrams/block/blockTypes.js'; export interface MermaidConfig { theme?: string; @@ -33,7 +34,7 @@ export interface MermaidConfig { gitGraph?: GitGraphDiagramConfig; c4?: C4DiagramConfig; sankey?: SankeyDiagramConfig; - block?: BlockDiagramConfig; + block?: BlockConfig; dompurifyConfig?: DOMPurify.Config; wrap?: boolean; fontSize?: number; @@ -422,9 +423,6 @@ export interface SankeyDiagramConfig extends BaseDiagramConfig { linkColor?: SankeyLinkColor | string; nodeAlignment?: SankeyNodeAlignment; } -export interface BlockDiagramConfig extends BaseDiagramConfig { - padding?: number; -} export interface FontConfig { fontSize?: string | number; diff --git a/packages/mermaid/src/diagrams/block/blockDB.ts b/packages/mermaid/src/diagrams/block/blockDB.ts index 4cb611b177..db216160af 100644 --- a/packages/mermaid/src/diagrams/block/blockDB.ts +++ b/packages/mermaid/src/diagrams/block/blockDB.ts @@ -1,12 +1,14 @@ +import type { BlockDB } from './blockTypes.js'; + import * as configApi from '../../config.js'; -import common from '../common/common.js'; +// import common from '../common/common.js'; import { - setAccTitle, - getAccTitle, - getAccDescription, - setAccDescription, - setDiagramTitle, - getDiagramTitle, + // setAccTitle, + // getAccTitle, + // getAccDescription, + // setAccDescription, + // setDiagramTitle, + // getDiagramTitle, clear as commonClear, } from '../../commonDb.js'; @@ -14,7 +16,6 @@ type Block = { ID: string; }; -// Array of nodes guarantees their order let blocks: Block[] = []; const clear = (): void => { @@ -22,14 +23,16 @@ const clear = (): void => { commonClear(); }; -export default { +const db: BlockDB = { getConfig: () => configApi.getConfig().block, - getAccTitle, - setAccTitle, - getAccDescription, - setAccDescription, - getDiagramTitle, - setDiagramTitle, + // getAccTitle, + // setAccTitle, + // getAccDescription, + // setAccDescription, + // getDiagramTitle, + // setDiagramTitle, clear, }; + +export default db; \ No newline at end of file diff --git a/packages/mermaid/src/diagrams/block/blockRenderer.ts b/packages/mermaid/src/diagrams/block/blockRenderer.ts index 5a2f595bcf..cfa9cc522d 100644 --- a/packages/mermaid/src/diagrams/block/blockRenderer.ts +++ b/packages/mermaid/src/diagrams/block/blockRenderer.ts @@ -9,18 +9,14 @@ import { import { configureSvgSize } from '../../setupGraphViewbox.js'; import { Uid } from '../../rendering-util/uid.js'; -import type { SankeyLinkColor, SankeyNodeAlignment } from '../../config.type.js'; export const draw = function (text: string, id: string, _version: string, diagObj: Diagram): void { - // Get the config - const { securityLevel, sankey: conf } = configApi.getConfig(); - const defaultSankeyConfig = configApi!.defaultConfig!.blockDiagram!; - // TODO: // This code repeats for every diagram // Figure out what is happening there, probably it should be separated // The main thing is svg object that is a d3 wrapper for svg operations // + const { securityLevel } = configApi.getConfig(); let sandboxElement: any; if (securityLevel === 'sandbox') { sandboxElement = d3select('#i' + id); @@ -44,11 +40,6 @@ export const draw = function (text: string, id: string, _version: string, diagOb // Prepare data for construction based on diagObj.db // This must be a mutable object with `nodes` and `links` properties: // - // { - // "nodes": [ { "id": "Alice" }, { "id": "Bob" }, { "id": "Carol" } ], - // "links": [ { "source": "Alice", "target": "Bob", "value": 23 }, { "source": "Bob", "target": "Carol", "value": 43 } ] - // } - // // @ts-ignore TODO: db type const graph = diagObj.db.getGraph(); diff --git a/packages/mermaid/src/diagrams/block/blockTypes.ts b/packages/mermaid/src/diagrams/block/blockTypes.ts index 28e5cd1679..014e6b7cb8 100644 --- a/packages/mermaid/src/diagrams/block/blockTypes.ts +++ b/packages/mermaid/src/diagrams/block/blockTypes.ts @@ -1,5 +1,11 @@ import type { DiagramDB } from '../../diagram-api/types.js'; +import type { BaseDiagramConfig } from '../../config.type.js'; + +export interface BlockConfig extends BaseDiagramConfig { + padding?: number; +} export interface BlockDB extends DiagramDB { clear: () => void; + getConfig: () => BlockConfig | undefined; } From 975f36c7db44d859e873c9349f6282dc367befdc Mon Sep 17 00:00:00 2001 From: Nikolay Rozhkov Date: Fri, 7 Jul 2023 14:14:30 +0300 Subject: [PATCH 004/217] Fixed block diagram parser import --- packages/mermaid/src/diagrams/block/blockDiagram.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/mermaid/src/diagrams/block/blockDiagram.ts b/packages/mermaid/src/diagrams/block/blockDiagram.ts index 1cd619749e..667783f492 100644 --- a/packages/mermaid/src/diagrams/block/blockDiagram.ts +++ b/packages/mermaid/src/diagrams/block/blockDiagram.ts @@ -1,6 +1,6 @@ import { DiagramDefinition } from '../../diagram-api/types.js'; // @ts-ignore: jison doesn't export types -import parser from './parser/blockDiagram.jison'; +import parser from './parser/block.jison'; import db from './blockDB.js'; import renderer from './blockRenderer.js'; import { prepareTextForParsing } from './blockUtils.js'; From c10f76580fa7919a5f259b4c8a3587697ecf124d Mon Sep 17 00:00:00 2001 From: Knut Sveidqvist Date: Sun, 9 Jul 2023 12:28:14 +0200 Subject: [PATCH 005/217] Adding some more tests --- .../src/diagrams/block/parser/block.spec.ts | 200 ++++++++++++++---- 1 file changed, 162 insertions(+), 38 deletions(-) diff --git a/packages/mermaid/src/diagrams/block/parser/block.spec.ts b/packages/mermaid/src/diagrams/block/parser/block.spec.ts index 08b36c7449..4713b57c07 100644 --- a/packages/mermaid/src/diagrams/block/parser/block.spec.ts +++ b/packages/mermaid/src/diagrams/block/parser/block.spec.ts @@ -28,7 +28,19 @@ describe('Sankey diagram', function () { `; block.parse(str); + // Todo: DB check that the we have two nodes and that the root block has two columns }); + it('a diagram with multiple nodes', async () => { + const str = `block-beta + id1 + id2 + id3 + `; + + block.parse(str); + // Todo: DB check that the we have two nodes and that the root block has three columns + }); + it('a node with a square shape and a label', async () => { const str = `block-beta id["A label"] @@ -43,43 +55,155 @@ describe('Sankey diagram', function () { block.parse(str); }); - // it('a diagram with column statements', async () => { - // const str = `block-beta - // columns 1 - // block1["Block 1"] - // `; - - // block.parse(str); - // }); - // it('a diagram with block hierarchies', async () => { - // const str = `block-beta - // columns 1 - // block1[Block 1] - - // block - // columns 2 - // block2[Block 2] - // block3[Block 3] - // end %% End the compound block - // `; - - // block.parse(str); - // }); - // it('a diagram with differernt column values in different blocks', async () => { - // const str = `block-beta - // columns 1 - // block1[Block 1] - - // block - // columns 2 - // block2[Block 2] - // block3[Block 3] - // end %% End the compound block - // `; - - // block.parse(str); - - // // Todo check that the different blocks have different column values - // }); + it.skip('a diagram with column statements', async () => { + const str = `block-beta + columns 1 + block1["Block 1"] + `; + + block.parse(str); + // Todo: DB check that the we have one block and that the root block has one column + }); + + it.skip('blocks next to each other', async () => { + const str = `block-beta + block + columns 2 + block1["Block 1"] + block2["Block 2"] + `; + + block.parse(str); + + // Todo: DB check that the we have two blocks and that the root block has two columns + }); + + it.skip('blocks on top of each other', async () => { + const str = `block-beta + block + columns 1 + block1["Block 1"] + block2["Block 2"] + `; + + block.parse(str); + + // Todo: DB check that the we have two blocks and that the root block has one column + }); + + it.skip('compound blocks', async () => { + const str = `block + block + columns 2 + block2["Block 2"] + block3["Block 3"] + end %% End the compound block + `; + + block.parse(str); + }); + it.skip('compound blocks with title', async () => { + const str = `block + block compoundBlock["Compound block"] + columns 1 + block2["Block 1"] + end + `; + + block.parse(str); + }); + it.skip('blocks mixed with compound blocks', async () => { + const str = `block + columns 1 + block1["Block 1"] + + block + columns 2 + block2["Block 2"] + block3["Block 3"] + end %% End the compound block + `; + + block.parse(str); + }); + + it.skip('Arrow blocks', async () => { + const str = `block + columns 3 + block1["Block 1"] + blockArrow + block2["Block 2"]`; + + block.parse(str); + }); + it.skip('Arrow blocks with multiple points', async () => { + const str = `block-beta + columns 1 + A + blockArrow(1,3) + block + columns 3 + B + C + D + end`; + + block.parse(str); + }); + it.skip('blocks with different widths', async () => { + const str = `block-beta + columns 3 + one["One Slot"] + two["Two slots"]:2 + `; + + block.parse(str); + }); + it.skip('empty blocks', async () => { + const str = `block-beta + columns 3 + space + middle["In the middle"] + `; + + block.parse(str); + }); + it.skip('classDef statements applied to a block', async () => { + const str = `block-beta + classDef black color:#ffffff, fill:#000000; + + mc["Memcache"]:::black + `; + + block.parse(str); + }); + it.skip('classDef statements applied to a block with a width', async () => { + const str = `block-beta + classDef black color:#ffffff, fill:#000000; + columns 2 + mc["Memcache"]:2::black + `; + + block.parse(str); + }); + + it.skip('classDef statements', async () => { + const str = `block-beta + classDef black color:#ffffff, fill:#000000; + + block DataServices["Data Services"] + columns H + block Relational + mssql["Microsoft SQL
Server"] + end + block Tabular + columns 3 + gds["Google Data Store"]:1 + mc["Memcache"]:2:::black + end + end`; + + block.parse(str); + }); }); }); From d165e8a642bf11426f99adaab20a770d2dcca62f Mon Sep 17 00:00:00 2001 From: Nikolay Rozhkov Date: Mon, 10 Jul 2023 23:33:11 +0300 Subject: [PATCH 006/217] Started block diag db development --- demos/block.html | 93 +++++++++++++++++++ demos/index.html | 3 + .../mermaid/src/diagrams/block/blockDB.ts | 46 ++++++++- .../src/diagrams/block/blockDiagram.ts | 8 +- .../src/diagrams/block/blockRenderer.ts | 22 ++--- .../mermaid/src/diagrams/block/blockTypes.ts | 6 -- .../src/diagrams/block/parser/block.jison | 46 ++++----- .../src/diagrams/block/parser/block.spec.ts | 2 +- 8 files changed, 174 insertions(+), 52 deletions(-) create mode 100644 demos/block.html diff --git a/demos/block.html b/demos/block.html new file mode 100644 index 0000000000..141d139700 --- /dev/null +++ b/demos/block.html @@ -0,0 +1,93 @@ + + + + + + States Mermaid Quick Test Page + + + + + +

Block diagram demos

+

TCI IP

+
+      block-beta
+
+      block TCP_IP["TCP/IP"]
+    
+ + + + + + diff --git a/demos/index.html b/demos/index.html index 24c4fbf3b0..113d674337 100644 --- a/demos/index.html +++ b/demos/index.html @@ -78,6 +78,9 @@

ZenUML

  • Sankey

  • +
  • +

    Layered Blocks

    +
  • diff --git a/packages/mermaid/src/diagrams/block/blockDB.ts b/packages/mermaid/src/diagrams/block/blockDB.ts index db216160af..de332e19b1 100644 --- a/packages/mermaid/src/diagrams/block/blockDB.ts +++ b/packages/mermaid/src/diagrams/block/blockDB.ts @@ -1,4 +1,6 @@ -import type { BlockDB } from './blockTypes.js'; +// import type { BlockDB } from './blockTypes.js'; +import type { DiagramDB } from '../../diagram-api/types.js'; +import { BlockConfig } from './blockTypes.js'; import * as configApi from '../../config.js'; // import common from '../common/common.js'; @@ -12,20 +14,54 @@ import { clear as commonClear, } from '../../commonDb.js'; -type Block = { +export type TBlockColumnsDefaultValue = 'H'; // Do we support something else, like 'auto' | 0? + +interface Block { ID: string; -}; + label?: string; + parent?: Block; + children?: Block[]; + columns: number | TBlockColumnsDefaultValue; +} + +interface Link { + source: Block; + target: Block; +} let blocks: Block[] = []; +let links: Link[] = []; const clear = (): void => { blocks = []; commonClear(); }; +type IAddBlock = (block: Block) => Block; +const addBlock: IAddBlock = (block: Block): Block => { + blocks.push(block); + return block; +}; + +type IAddLink = (link: Link) => Link; +const addLink: IAddLink = (link: Link): Link => { + links.push(link); + return link; +}; + +export interface BlockDB extends DiagramDB { + clear: () => void; + getConfig: () => BlockConfig | undefined; + addBlock: IAddBlock; + addLink: IAddLink; + getLogger: () => Console; +} + const db: BlockDB = { getConfig: () => configApi.getConfig().block, - + addBlock: addBlock, + addLink: addLink, + getLogger: () => console, // TODO: remove // getAccTitle, // setAccTitle, // getAccDescription, @@ -35,4 +71,4 @@ const db: BlockDB = { clear, }; -export default db; \ No newline at end of file +export default db; diff --git a/packages/mermaid/src/diagrams/block/blockDiagram.ts b/packages/mermaid/src/diagrams/block/blockDiagram.ts index 667783f492..e098360f43 100644 --- a/packages/mermaid/src/diagrams/block/blockDiagram.ts +++ b/packages/mermaid/src/diagrams/block/blockDiagram.ts @@ -3,10 +3,12 @@ import { DiagramDefinition } from '../../diagram-api/types.js'; import parser from './parser/block.jison'; import db from './blockDB.js'; import renderer from './blockRenderer.js'; -import { prepareTextForParsing } from './blockUtils.js'; -const originalParse = parser.parse.bind(parser); -parser.parse = (text: string) => originalParse(prepareTextForParsing(text)); +// TODO: do we need this? +// import { prepareTextForParsing } from './blockUtils.js'; +// const originalParse = parser.parse.bind(parser); +// parser.parse = (text: string) => originalParse(prepareTextForParsing(text)); +// parser.yy.getLogger = () => console; export const diagram: DiagramDefinition = { parser, diff --git a/packages/mermaid/src/diagrams/block/blockRenderer.ts b/packages/mermaid/src/diagrams/block/blockRenderer.ts index cfa9cc522d..8896b272db 100644 --- a/packages/mermaid/src/diagrams/block/blockRenderer.ts +++ b/packages/mermaid/src/diagrams/block/blockRenderer.ts @@ -11,11 +11,6 @@ import { configureSvgSize } from '../../setupGraphViewbox.js'; import { Uid } from '../../rendering-util/uid.js'; export const draw = function (text: string, id: string, _version: string, diagObj: Diagram): void { - // TODO: - // This code repeats for every diagram - // Figure out what is happening there, probably it should be separated - // The main thing is svg object that is a d3 wrapper for svg operations - // const { securityLevel } = configApi.getConfig(); let sandboxElement: any; if (securityLevel === 'sandbox') { @@ -25,28 +20,27 @@ export const draw = function (text: string, id: string, _version: string, diagOb securityLevel === 'sandbox' ? d3select(sandboxElement.nodes()[0].contentDocument.body) : d3select('body'); + // @ts-ignore TODO root.select is not callable const svg = securityLevel === 'sandbox' ? root.select(`[id="${id}"]`) : d3select(`[id="${id}"]`); // Establish svg dimensions and get width and height - // - - // FIX: using max width prevents height from being set, is it intended? - // to add height directly one can use `svg.attr('height', height)` - // - // @ts-ignore TODO: svg type vs selection mismatch + // + const height = 400; + const width = 600; + const useMaxWidth = false; configureSvgSize(svg, height, width, useMaxWidth); // Prepare data for construction based on diagObj.db // This must be a mutable object with `nodes` and `links` properties: // // @ts-ignore TODO: db type - const graph = diagObj.db.getGraph(); + // const graph = diagObj.db.getGraph(); - const nodeWidth = 10; + // const nodeWidth = 10; // Get color scheme for the graph - const colorScheme = d3scaleOrdinal(d3schemeTableau10); + // const colorScheme = d3scaleOrdinal(d3schemeTableau10); }; export default { diff --git a/packages/mermaid/src/diagrams/block/blockTypes.ts b/packages/mermaid/src/diagrams/block/blockTypes.ts index 014e6b7cb8..c190c5779c 100644 --- a/packages/mermaid/src/diagrams/block/blockTypes.ts +++ b/packages/mermaid/src/diagrams/block/blockTypes.ts @@ -1,11 +1,5 @@ -import type { DiagramDB } from '../../diagram-api/types.js'; import type { BaseDiagramConfig } from '../../config.type.js'; export interface BlockConfig extends BaseDiagramConfig { padding?: number; } - -export interface BlockDB extends DiagramDB { - clear: () => void; - getConfig: () => BlockConfig | undefined; -} diff --git a/packages/mermaid/src/diagrams/block/parser/block.jison b/packages/mermaid/src/diagrams/block/parser/block.jison index ba58a60971..6870859391 100644 --- a/packages/mermaid/src/diagrams/block/parser/block.jison +++ b/packages/mermaid/src/diagrams/block/parser/block.jison @@ -33,10 +33,10 @@ CRLF \u000D\u000A [\n]+ {yy.getLogger().info('_', yytext); /* skip all whitespace */ } // [\n] return 'NL'; ({CRLF}|{LF}) { return 'NL' } -["][`] { this.begin("md_string");} +["][`] { this.pushState("md_string");} [^`"]+ { return "MD_STR";} [`]["] { this.popState();} -["] this.begin("string"); +["] this.pushState("string"); ["] this.popState(); [^"]* return "STR"; "style" return 'STYLE'; @@ -45,11 +45,11 @@ CRLF \u000D\u000A "interpolate" return 'INTERPOLATE'; "classDef" return 'CLASSDEF'; "class" return 'CLASS'; -accTitle\s*":"\s* { this.begin("acc_title");return 'acc_title'; } +accTitle\s*":"\s* { this.pushState("acc_title");return 'acc_title'; } (?!\n|;|#)*[^\n]* { this.popState(); return "acc_title_value"; } -accDescr\s*":"\s* { this.begin("acc_descr");return 'acc_descr'; } +accDescr\s*":"\s* { this.pushState("acc_descr");return 'acc_descr'; } (?!\n|;|#)*[^\n]* { this.popState(); return "acc_descr_value"; } -accDescr\s*"{"\s* { this.begin("acc_descr_multiline");} +accDescr\s*"{"\s* { this.pushState("acc_descr_multiline");} [\}] { this.popState(); } [^\}]* return "acc_descr_multiline_value"; "subgraph" return 'subgraph'; @@ -60,32 +60,32 @@ accDescr\s*"{"\s* { this.begin("acc_descr_multili .*direction\s+LR[^\n]* return 'direction_lr'; // Start of nodes with shapes and description -"-)" { yy.getLogger().info('Lex: -)'); this.begin('NODE');return 'NODE_D START'; } -"(-" { yy.getLogger().info('Lex: (-'); this.begin('NODE');return 'NODE_DSTART'; } -"))" { yy.getLogger().info('Lex: ))'); this.begin('NODE');return 'NODE_DSTART'; } -")" { yy.getLogger().info('Lex: )'); this.begin('NODE');return 'NODE_DSTART'; } -"((" { yy.getLogger().info('Lex: )'); this.begin('NODE');return 'NODE_DSTART'; } -"{{" { yy.getLogger().info('Lex: )'); this.begin('NODE');return 'NODE_DSTART'; } -"(" { yy.getLogger().info('Lex: )'); this.begin('NODE');return 'NODE_DSTART'; } -"[" { yy.getLogger().info('Lex: ['); this.begin('NODE');return 'NODE_DSTART'; } -"([" { yy.getLogger().info('Lex: )'); this.begin('NODE');return 'NODE_DSTART'; } -"[[" { this.begin('NODE');return 'NODE_DSTART'; } -"[|" { this.begin('NODE');return 'NODE_DSTART'; } -"[(" { this.begin('NODE');return 'NODE_DSTART'; } -"(((" { this.begin('NODE');return 'NODE_DSTART'; } -")))" { this.begin('NODE');return 'NODE_DSTART'; } -"[/" { this.begin('NODE');return 'NODE_DSTART'; } -"[\\" { this.begin('NODE');return 'NODE_DSTART'; } +"-)" { yy.getLogger().info('Lex: -)'); this.pushState('NODE');return 'NODE_D START'; } +"(-" { yy.getLogger().info('Lex: (-'); this.pushState('NODE');return 'NODE_DSTART'; } +"))" { yy.getLogger().info('Lex: ))'); this.pushState('NODE');return 'NODE_DSTART'; } +")" { yy.getLogger().info('Lex: )'); this.pushState('NODE');return 'NODE_DSTART'; } +"((" { yy.getLogger().info('Lex: )'); this.pushState('NODE');return 'NODE_DSTART'; } +"{{" { yy.getLogger().info('Lex: )'); this.pushState('NODE');return 'NODE_DSTART'; } +"(" { yy.getLogger().info('Lex: )'); this.pushState('NODE');return 'NODE_DSTART'; } +"[" { yy.getLogger().info('Lex: ['); this.pushState('NODE');return 'NODE_DSTART'; } +"([" { yy.getLogger().info('Lex: )'); this.pushState('NODE');return 'NODE_DSTART'; } +"[[" { this.pushState('NODE');return 'NODE_DSTART'; } +"[|" { this.pushState('NODE');return 'NODE_DSTART'; } +"[(" { this.pushState('NODE');return 'NODE_DSTART'; } +"(((" { this.pushState('NODE');return 'NODE_DSTART'; } +")))" { this.pushState('NODE');return 'NODE_DSTART'; } +"[/" { this.pushState('NODE');return 'NODE_DSTART'; } +"[\\" { this.pushState('NODE');return 'NODE_DSTART'; } [^\(\[\n\-\)\{\}]+ { yy.getLogger().info('Lex: NODE_ID', yytext);return 'NODE_ID'; } <> { yy.getLogger().info('Lex: EOF', yytext);return 'EOF'; } // Handling of strings in node -["][`] { this.begin("md_string");} +["][`] { this.pushState("md_string");} [^`"]+ { return "NODE_DESCR";} [`]["] { this.popState();} -["] { yy.getLogger().info('Lex: Starting string');this.begin("string");} +["] { yy.getLogger().info('Lex: Starting string');this.pushState("string");} [^"]+ { yy.getLogger().info('Lex: NODE_DESCR:', yytext); return "NODE_DESCR";} ["] {this.popState();} diff --git a/packages/mermaid/src/diagrams/block/parser/block.spec.ts b/packages/mermaid/src/diagrams/block/parser/block.spec.ts index 4713b57c07..2c575aeba3 100644 --- a/packages/mermaid/src/diagrams/block/parser/block.spec.ts +++ b/packages/mermaid/src/diagrams/block/parser/block.spec.ts @@ -6,7 +6,7 @@ import { prepareTextForParsing } from '../blockUtils.js'; import * as fs from 'fs'; import * as path from 'path'; -describe('Sankey diagram', function () { +describe('Block diagram', function () { describe('when parsing an block diagram graph it should handle > ', function () { beforeEach(function () { block.parser.yy = db; From e251baa61c50d429f1a2d17ba67f04f8bfebf5f0 Mon Sep 17 00:00:00 2001 From: Nikolay Rozhkov Date: Tue, 11 Jul 2023 02:51:10 +0300 Subject: [PATCH 007/217] Started layout and rendering --- demos/block.html | 10 +- .../mermaid/src/diagrams/block/blockDB.ts | 37 ++++-- .../src/diagrams/block/blockRenderer.ts | 115 +++++++++++++++++- 3 files changed, 150 insertions(+), 12 deletions(-) diff --git a/demos/block.html b/demos/block.html index 141d139700..3e8769ecc4 100644 --- a/demos/block.html +++ b/demos/block.html @@ -18,14 +18,18 @@

    TCI IP

           block-beta
     
    -      block TCP_IP["TCP/IP"]
         
    - Still - Still --> [*] - Still --> Moving - Moving --> Still - Moving --> Crash - Crash --> [*]
     flowchart RL
    diff --git a/packages/mermaid/src/diagrams/block/blockDB.ts b/packages/mermaid/src/diagrams/block/blockDB.ts
    index a0c97fc0fa..bec5c33c3f 100644
    --- a/packages/mermaid/src/diagrams/block/blockDB.ts
    +++ b/packages/mermaid/src/diagrams/block/blockDB.ts
    @@ -1,6 +1,6 @@
     // import type { BlockDB } from './blockTypes.js';
     import type { DiagramDB } from '../../diagram-api/types.js';
    -import { BlockConfig } from './blockTypes.js';
    +import { BlockConfig, BlockType, Block, Link } from './blockTypes.js';
     
     import * as configApi from '../../config.js';
     // import common from '../common/common.js';
    @@ -13,47 +13,78 @@ import {
       // getDiagramTitle,
       clear as commonClear,
     } from '../../commonDb.js';
    +import { log } from '../../logger.js';
     
     // export type TBlockColumnsDefaultValue = 'H'; // Do we support something else, like 'auto' | 0?
     
    -// TODO: Convert to generic TreeNode type? Convert to class?
    -export interface Block {
    -  ID: string;
    -  label?: string;
    -  parent?: Block;
    -  children?: Block[];
    -  columns?: number; // | TBlockColumnsDefaultValue;
    -}
    +// Initialize the node database for simple lookups
    +let nodeDatabase: Record = {};
    +const blockDatabase: Record = {};
     
    -export interface Link {
    -  source: Block;
    -  target: Block;
    -}
    +// Function to get a node by its ID
    +export const getNodeById = (id: string): Node | undefined => {
    +  return nodeDatabase[id];
    +};
    +
    +// TODO: Convert to generic TreeNode type? Convert to class?
     
    -let rootBlocks: Block[] = [];
    +let rootBlock = { ID: 'root', children: [] as Block[], columns: -1 };
     let blocks: Block[] = [];
     const links: Link[] = [];
    -let rootBlock = { ID: 'root', children: [], columns: -1 } as Block;
    -let currentBlock: Block | undefined;
    +// let rootBlock = { ID: 'root', children: [], columns: -1 } as Block;
    +let currentBlock = rootBlock;
     
     const clear = (): void => {
    -  rootBlocks = [];
    -  blocks = [];
    +  log.info('Clear called');
    +  // rootBlocks = [];
    +  blocks = [] as Block[];
       commonClear();
       rootBlock = { ID: 'root', children: [], columns: -1 };
       currentBlock = rootBlock;
    +  nodeDatabase = {};
    +  blockDatabase[rootBlock.ID] = rootBlock;
     };
     
    -type IAddBlock = (block: Block) => Block;
    -const addBlock: IAddBlock = (block: Block, parent?: Block): Block => {
    -  if (parent) {
    -    parent.children ??= [];
    -    parent.children.push(block);
    -  } else {
    -    rootBlocks.push(block);
    +// type IAddBlock = (block: Block) => Block;
    +// const addBlock: IAddBlock = (block: Block, parent?: Block): Block => {
    +//   log.info('addBlock', block, parent);
    +//   if (parent) {
    +//     parent.children ??= [];
    +//     parent.children.push(block);
    +//   } else {
    +//     rootBlock.children.push(block);
    +//   }
    +//   blocks.push(block);
    +//   return block;
    +// };
    +
    +type ITypeStr2Type = (typeStr: string) => BlockType;
    +export function typeStr2Type(typeStr: string) {
    +  // TODO: add all types
    +  switch (typeStr) {
    +    case '[]':
    +      return 'square';
    +    case '()':
    +      return 'round';
    +    default:
    +      return 'square';
       }
    -  blocks.push(block);
    -  return block;
    +}
    +
    +type IAddBlock = (id: string, label: string, type: BlockType) => Block;
    +// Function to add a node to the database
    +export const addBlock = (id: string, _label?: string, type?: BlockType) => {
    +  log.info('addNode called:', id, _label, type);
    +  const label = _label || id;
    +  const node: Block = {
    +    ID: id,
    +    label,
    +    type: type || 'square',
    +  };
    +  blockDatabase[node.ID] = node;
    +  currentBlock.children ??= [];
    +  currentBlock.children.push(node);
    +  return node;
     };
     
     type IAddLink = (link: Link) => Link;
    @@ -84,16 +115,21 @@ const getBlock = (id: string, blocks: Block[]): Block | undefined => {
     
     type IGetColumns = (blockID: string) => number;
     const getColumns = (blockID: string): number => {
    -  const blocks = [rootBlock];
    -  const block = getBlock(blockID, blocks);
    +  const block = blockDatabase[blockID];
       if (!block) {
         return -1;
       }
    -  return block.columns || -1;
    +  if (block.columns) {
    +    return block.columns;
    +  }
    +  if (!block.children) {
    +    return -1;
    +  }
    +  return block.children.length;
     };
     
     type IGetBlocks = () => Block[];
    -const getBlocks: IGetBlocks = () => blocks;
    +const getBlocks: IGetBlocks = () => rootBlock.children || [];
     
     type IGetLinks = () => Link[];
     const getLinks: IGetLinks = () => links;
    @@ -111,12 +147,14 @@ export interface BlockDB extends DiagramDB {
       getLinks: IGetLinks;
       setColumns: ISetColumns;
       getColumns: IGetColumns;
    +  typeStr2Type: ITypeStr2Type;
     }
     
     const db: BlockDB = {
       getConfig: () => configApi.getConfig().block,
       addBlock: addBlock,
       addLink: addLink,
    +  typeStr2Type: typeStr2Type,
       getLogger, // TODO: remove
       getBlocks,
       getLinks,
    diff --git a/packages/mermaid/src/diagrams/block/blockTypes.ts b/packages/mermaid/src/diagrams/block/blockTypes.ts
    index c190c5779c..b373d6b9cc 100644
    --- a/packages/mermaid/src/diagrams/block/blockTypes.ts
    +++ b/packages/mermaid/src/diagrams/block/blockTypes.ts
    @@ -3,3 +3,36 @@ import type { BaseDiagramConfig } from '../../config.type.js';
     export interface BlockConfig extends BaseDiagramConfig {
       padding?: number;
     }
    +
    +export type BlockType =
    +  | 'round'
    +  | 'square'
    +  | 'diamond'
    +  | 'hexagon'
    +  | 'odd'
    +  | 'lean_right'
    +  | 'lean_left'
    +  | 'trapezoid'
    +  | 'inv_trapezoid'
    +  | 'odd_right'
    +  | 'circle'
    +  | 'ellipse'
    +  | 'stadium'
    +  | 'subroutine'
    +  | 'cylinder'
    +  | 'group'
    +  | 'doublecircle';
    +
    +export interface Block {
    +  ID: string;
    +  label?: string;
    +  parent?: Block;
    +  type?: BlockType;
    +  children?: Block[];
    +  columns?: number; // | TBlockColumnsDefaultValue;
    +}
    +
    +export interface Link {
    +  source: Block;
    +  target: Block;
    +}
    diff --git a/packages/mermaid/src/diagrams/block/parser/block.jison b/packages/mermaid/src/diagrams/block/parser/block.jison
    index afd645d96f..9422d8ee3a 100644
    --- a/packages/mermaid/src/diagrams/block/parser/block.jison
    +++ b/packages/mermaid/src/diagrams/block/parser/block.jison
    @@ -64,7 +64,7 @@ accDescr\s*"{"\s*                                { this.pushState("acc_descr_mul
     
     // Start of nodes with shapes and description
     "-)"                   { yy.getLogger().info('Lex: -)'); this.pushState('NODE');return 'NODE_D START'; }
    -"(-"                   { yy.getLogger().info('Lex: (-'); this.pushState('NODE');return 'NODE_DSTART';           }
    +"(-"                   { yy.getLogger().info('Lex: (-'); this.pushState('NODE');return 'NODE_DSTART'; }
     "))"                   { yy.getLogger().info('Lex: ))'); this.pushState('NODE');return 'NODE_DSTART';  }
     ")"                    { yy.getLogger().info('Lex: )'); this.pushState('NODE');return 'NODE_DSTART';      }
     "(("                   { yy.getLogger().info('Lex: )'); this.pushState('NODE');return 'NODE_DSTART'; }
    @@ -177,8 +177,8 @@ statement
     	;
     
     nodeStatement
    -  : nodeStatement link node { yy.getLogger().info('Rule: nodeStatement (nodeStatement link node) ');}
    -  | node { yy.getLogger().info('Rule: nodeStatement (node) ', $1);}
    +  : nodeStatement link node { yy.getLogger().info('Rule: nodeStatement (nodeStatement link node) '); yy.addBlock($1.id);}
    +  | node { yy.getLogger().info('Rule: nodeStatement (node) ', $1); yy.addBlock($1.id, $1.label, yy.typeStr2Type($1)); }
       ;
     
     columnsStatement
    @@ -192,16 +192,16 @@ blockStatement
     
     node
       : NODE_ID
    -  { yy.getLogger().info("Rule: node (NODE_ID seperator): ", $1); }
    +  { yy.getLogger().info("Rule: node (NODE_ID seperator): ", $1); $$ = { id: $1 }; }
       |NODE_ID nodeShapeNLabel
    -    { yy.getLogger().info("Rule: node (NODE_ID nodeShapeNLabel seperator): ", $1, $2); }
    +    { yy.getLogger().info("Rule: node (NODE_ID nodeShapeNLabel seperator): ", $1, $2); $$ = { id: $1, label: $2.label, typeStr: $2.typeStr };}
       // |nodeShapeNLabel seperator
       // { yy.getLogger().info("Rule: node (nodeShapeNLabel seperator): ", $1, $2, $3); }
       ;
     
     nodeShapeNLabel
       :   NODE_DSTART STR NODE_DEND
    -	      { yy.getLogger().info("Rule: nodeShapeNLabel: ", $1, $2, $3); $$ = { type: $1 + $3, descr: $2 }; }
    +	      { yy.getLogger().info("Rule: nodeShapeNLabel: ", $1, $2, $3); $$ = { typeStr: $1 + $3, label: $2 }; }
       ;
     
     %%
    diff --git a/packages/mermaid/src/diagrams/block/parser/block.spec.ts b/packages/mermaid/src/diagrams/block/parser/block.spec.ts
    index 75cd76b82a..ded6db4684 100644
    --- a/packages/mermaid/src/diagrams/block/parser/block.spec.ts
    +++ b/packages/mermaid/src/diagrams/block/parser/block.spec.ts
    @@ -3,8 +3,7 @@ import block from './block.jison';
     import db from '../blockDB.js';
     import { cleanupComments } from '../../../diagram-api/comments.js';
     import { prepareTextForParsing } from '../blockUtils.js';
    -import * as fs from 'fs';
    -import * as path from 'path';
    +import { setConfig } from '../../../config.js';
     
     describe('Block diagram', function () {
       describe('when parsing an block diagram graph it should handle > ', function () {
    @@ -20,6 +19,22 @@ describe('Block diagram', function () {
           `;
     
           block.parse(str);
    +      const blocks = db.getBlocks();
    +      expect(blocks.length).toBe(1);
    +      expect(blocks[0].ID).toBe('id');
    +      expect(blocks[0].label).toBe('id');
    +    });
    +    it('a node with a square shape and a label', async () => {
    +      const str = `block-beta
    +          id["A label"]
    +          `;
    +
    +      block.parse(str);
    +      const blocks = db.getBlocks();
    +      expect(blocks.length).toBe(1);
    +      expect(blocks[0].ID).toBe('id');
    +      expect(blocks[0].label).toBe('A label');
    +      expect(blocks[0].type).toBe('square');
         });
         it('a diagram with multiple nodes', async () => {
           const str = `block-beta
    diff --git a/packages/mermaid/src/diagrams/flowchart/parser/flow.spec.js b/packages/mermaid/src/diagrams/flowchart/parser/flow.spec.js
    index 3852c4f92c..8d0aec789e 100644
    --- a/packages/mermaid/src/diagrams/flowchart/parser/flow.spec.js
    +++ b/packages/mermaid/src/diagrams/flowchart/parser/flow.spec.js
    @@ -1,7 +1,7 @@
     import flowDb from '../flowDb.js';
     import flow from './flow.jison';
    -import { setConfig } from '../../../config.js';
     import { cleanupComments } from '../../../diagram-api/comments.js';
    +import { setConfig } from '../../../config.js';
     
     setConfig({
       securityLevel: 'strict',
    
    From aa7f5a83879df60ff2316149ae80f179cac20d97 Mon Sep 17 00:00:00 2001
    From: Knut Sveidqvist 
    Date: Fri, 1 Sep 2023 14:06:13 +0200
    Subject: [PATCH 010/217] before refactoring
    
    ---
     .../mermaid/src/diagrams/block/blockDB.ts     | 65 +++++++++++-----
     .../mermaid/src/diagrams/block/blockTypes.ts  |  7 +-
     .../src/diagrams/block/parser/block.jison     | 15 ++--
     .../src/diagrams/block/parser/block.spec.ts   | 76 ++++++++++++++++++-
     4 files changed, 132 insertions(+), 31 deletions(-)
    
    diff --git a/packages/mermaid/src/diagrams/block/blockDB.ts b/packages/mermaid/src/diagrams/block/blockDB.ts
    index bec5c33c3f..2ef2044306 100644
    --- a/packages/mermaid/src/diagrams/block/blockDB.ts
    +++ b/packages/mermaid/src/diagrams/block/blockDB.ts
    @@ -21,17 +21,19 @@ import { log } from '../../logger.js';
     let nodeDatabase: Record = {};
     const blockDatabase: Record = {};
     
    -// Function to get a node by its ID
    -export const getNodeById = (id: string): Node | undefined => {
    -  return nodeDatabase[id];
    +// Function to get a node by its id
    +type IGetNodeById = (id: string) => Block | undefined;
    +export const getNodeById = (id: string): Block | undefined => {
    +  console.log(id, nodeDatabase);
    +  return blockDatabase[id];
     };
     
     // TODO: Convert to generic TreeNode type? Convert to class?
     
    -let rootBlock = { ID: 'root', children: [] as Block[], columns: -1 };
    +let rootBlock = { id: 'root', children: [] as Block[], columns: -1 };
     let blocks: Block[] = [];
     const links: Link[] = [];
    -// let rootBlock = { ID: 'root', children: [], columns: -1 } as Block;
    +// let rootBlock = { id: 'root', children: [], columns: -1 } as Block;
     let currentBlock = rootBlock;
     
     const clear = (): void => {
    @@ -39,10 +41,10 @@ const clear = (): void => {
       // rootBlocks = [];
       blocks = [] as Block[];
       commonClear();
    -  rootBlock = { ID: 'root', children: [], columns: -1 };
    +  rootBlock = { id: 'root', children: [], columns: -1 };
       currentBlock = rootBlock;
       nodeDatabase = {};
    -  blockDatabase[rootBlock.ID] = rootBlock;
    +  blockDatabase[rootBlock.id] = rootBlock;
     };
     
     // type IAddBlock = (block: Block) => Block;
    @@ -71,22 +73,39 @@ export function typeStr2Type(typeStr: string) {
       }
     }
     
    -type IAddBlock = (id: string, label: string, type: BlockType) => Block;
    +let cnt = 0;
    +export const generateId = () => {
    +  cnt++;
    +  return 'id-' + Math.random().toString(36).substr(2, 12) + '-' + cnt;
    +};
    +
    +type IAddBlock = (_id: string, label: string, type: BlockType) => Block;
     // Function to add a node to the database
    -export const addBlock = (id: string, _label?: string, type?: BlockType) => {
    -  log.info('addNode called:', id, _label, type);
    +export const addBlock = (_id: string, _label?: string, type?: BlockType) => {
    +  let id = _id;
    +  if (!_id) {
    +    id = generateId();
    +  }
       const label = _label || id;
       const node: Block = {
    -    ID: id,
    +    id: id,
         label,
         type: type || 'square',
    +    children: [],
       };
    -  blockDatabase[node.ID] = node;
    -  currentBlock.children ??= [];
    -  currentBlock.children.push(node);
    +  blockDatabase[node.id] = node;
    +  // currentBlock.children ??= [];
    +  // currentBlock.children.push(node);
    +  // console.log('currentBlock', currentBlock.children, nodeDatabase);
    +  console.log('addNode called:', id, label, type, node);
       return node;
     };
     
    +type ISetHierarchy = (block: Block[]) => void;
    +const setHierarchy = (block: Block[]): void => {
    +  blocks = block;
    +};
    +
     type IAddLink = (link: Link) => Link;
     const addLink: IAddLink = (link: Link): Link => {
       links.push(link);
    @@ -101,7 +120,7 @@ const setColumns = (columnsStr: string): void => {
     
     const getBlock = (id: string, blocks: Block[]): Block | undefined => {
       for (const block of blocks) {
    -    if (block.ID === id) {
    +    if (block.id === id) {
           return block;
         }
         if (block.children) {
    @@ -113,9 +132,9 @@ const getBlock = (id: string, blocks: Block[]): Block | undefined => {
       }
     };
     
    -type IGetColumns = (blockID: string) => number;
    -const getColumns = (blockID: string): number => {
    -  const block = blockDatabase[blockID];
    +type IGetColumns = (blockid: string) => number;
    +const getColumns = (blockid: string): number => {
    +  const block = blockDatabase[blockid];
       if (!block) {
         return -1;
       }
    @@ -129,7 +148,11 @@ const getColumns = (blockID: string): number => {
     };
     
     type IGetBlocks = () => Block[];
    -const getBlocks: IGetBlocks = () => rootBlock.children || [];
    +const getBlocks: IGetBlocks = () => {
    +  // console.log('Block in test', rootBlock.children || []);
    +  console.log('Block in test', blocks, blocks[0].id);
    +  return blocks || [];
    +};
     
     type IGetLinks = () => Link[];
     const getLinks: IGetLinks = () => links;
    @@ -148,6 +171,8 @@ export interface BlockDB extends DiagramDB {
       setColumns: ISetColumns;
       getColumns: IGetColumns;
       typeStr2Type: ITypeStr2Type;
    +  setHierarchy: ISetHierarchy;
    +  getNodeById: IGetNodeById;
     }
     
     const db: BlockDB = {
    @@ -158,6 +183,8 @@ const db: BlockDB = {
       getLogger, // TODO: remove
       getBlocks,
       getLinks,
    +  setHierarchy,
    +  getNodeById,
       // getAccTitle,
       // setAccTitle,
       // getAccDescription,
    diff --git a/packages/mermaid/src/diagrams/block/blockTypes.ts b/packages/mermaid/src/diagrams/block/blockTypes.ts
    index b373d6b9cc..4afbe43519 100644
    --- a/packages/mermaid/src/diagrams/block/blockTypes.ts
    +++ b/packages/mermaid/src/diagrams/block/blockTypes.ts
    @@ -21,14 +21,15 @@ export type BlockType =
       | 'subroutine'
       | 'cylinder'
       | 'group'
    -  | 'doublecircle';
    +  | 'doublecircle'
    +  | 'composite';
     
     export interface Block {
    -  ID: string;
    +  id: string;
       label?: string;
       parent?: Block;
       type?: BlockType;
    -  children?: Block[];
    +  children: Block[];
       columns?: number; // | TBlockColumnsDefaultValue;
     }
     
    diff --git a/packages/mermaid/src/diagrams/block/parser/block.jison b/packages/mermaid/src/diagrams/block/parser/block.jison
    index 9422d8ee3a..309dbfdeaf 100644
    --- a/packages/mermaid/src/diagrams/block/parser/block.jison
    +++ b/packages/mermaid/src/diagrams/block/parser/block.jison
    @@ -137,7 +137,9 @@ seperator
         {yy.getLogger().info('Rule: seperator (EOF) ');}
       ;
     
    -start: BLOCK_DIAGRAM_KEY document EOF;
    +start: BLOCK_DIAGRAM_KEY document EOF
    +  {console.log('This is the hierarchy ', JSON.stringify($2, null, 2)); yy.setHierarchy($2); }
    +  ;
     
     
     stop
    @@ -148,9 +150,10 @@ stop
       | stop EOF {yy.getLogger().info('Stop EOF2 ');}
       ;
     
    +//array of statements
     document
    -	: statement { yy.getLogger().info("Rule: statement: ", $1);}
    -	| statement document { yy.getLogger().info("Rule: document statement: ", $1);}
    +	: statement { yy.getLogger().info("Rule: statement: ", $1); $$ = [$1]; }
    +	| statement document { yy.getLogger().info("Rule: document statement: ", $1, $2); $$ = [$1].concat($2); }
     	;
     
     link
    @@ -177,8 +180,8 @@ statement
     	;
     
     nodeStatement
    -  : nodeStatement link node { yy.getLogger().info('Rule: nodeStatement (nodeStatement link node) '); yy.addBlock($1.id);}
    -  | node { yy.getLogger().info('Rule: nodeStatement (node) ', $1); yy.addBlock($1.id, $1.label, yy.typeStr2Type($1)); }
    +  : nodeStatement link node { yy.getLogger().info('Rule: nodeStatement (nodeStatement link node) '); yy.addBlock($1.id); $$ = {id: $1.id}; }
    +  | node { yy.getLogger().info('Rule: nodeStatement (node) ', $1); yy.addBlock($1.id, $1.label, yy.typeStr2Type($1)); $$ = {id: $1.id}; }
       ;
     
     columnsStatement
    @@ -186,7 +189,7 @@ columnsStatement
       ;
     
     blockStatement
    -  : block document end { yy.getLogger().info('Rule: blockStatement : ', $1); }
    +  : block document end { console.log('Rule: blockStatement : ', $1, $2, $3); const block = yy.addBlock(undefined, undefined, 'composite'); $$ = { id: block.id, children: $2 }; }
       ;
     
     
    diff --git a/packages/mermaid/src/diagrams/block/parser/block.spec.ts b/packages/mermaid/src/diagrams/block/parser/block.spec.ts
    index ded6db4684..584a817b55 100644
    --- a/packages/mermaid/src/diagrams/block/parser/block.spec.ts
    +++ b/packages/mermaid/src/diagrams/block/parser/block.spec.ts
    @@ -43,7 +43,14 @@ describe('Block diagram', function () {
           `;
     
           block.parse(str);
    -      // Todo: DB check that the we have two nodes and that the root block has two columns
    +      const blocks = db.getBlocks();
    +      expect(blocks.length).toBe(2);
    +      expect(blocks[0].ID).toBe('id1');
    +      expect(blocks[0].label).toBe('id1');
    +      expect(blocks[0].type).toBe('square');
    +      expect(blocks[1].ID).toBe('id2');
    +      expect(blocks[1].label).toBe('id2');
    +      expect(blocks[1].type).toBe('square');
         });
         it('a diagram with multiple nodes', async () => {
           const str = `block-beta
    @@ -53,7 +60,17 @@ describe('Block diagram', function () {
           `;
     
           block.parse(str);
    -      // Todo: DB check that the we have two nodes and that the root block has three columns
    +      const blocks = db.getBlocks();
    +      expect(blocks.length).toBe(3);
    +      expect(blocks[0].ID).toBe('id1');
    +      expect(blocks[0].label).toBe('id1');
    +      expect(blocks[0].type).toBe('square');
    +      expect(blocks[1].ID).toBe('id2');
    +      expect(blocks[1].label).toBe('id2');
    +      expect(blocks[1].type).toBe('square');
    +      expect(blocks[2].ID).toBe('id3');
    +      expect(blocks[2].label).toBe('id3');
    +      expect(blocks[2].type).toBe('square');
         });
     
         it('a node with a square shape and a label', async () => {
    @@ -62,6 +79,14 @@ describe('Block diagram', function () {
               id2`;
     
           block.parse(str);
    +      const blocks = db.getBlocks();
    +      expect(blocks.length).toBe(2);
    +      expect(blocks[0].ID).toBe('id');
    +      expect(blocks[0].label).toBe('A label');
    +      expect(blocks[0].type).toBe('square');
    +      expect(blocks[1].ID).toBe('id2');
    +      expect(blocks[1].label).toBe('id2');
    +      expect(blocks[1].type).toBe('square');
         });
         it('a diagram with multiple nodes with edges', async () => {
           const str = `block-beta
    @@ -124,14 +149,59 @@ describe('Block diagram', function () {
           // Todo: DB check that the we have two blocks and that the root block has one column
         });
     
    -    it('compound blocks', async () => {
    +    it('compound blocks 2', async () => {
           const str = `block-beta
               block
                 aBlock["Block"]
    +            bBlock["Block"]
    +          end
    +        `;
    +
    +      block.parse(str);
    +      const blocks = db.getBlocks();
    +      console.log('blocks', blocks);
    +      expect(blocks.length).toBe(1);
    +      expect(blocks[0].children.length).toBe(2);
    +      expect(blocks[0].id).toBe('id');
    +      expect(blocks[0].label).toBe('A label');
    +      expect(blocks[0].type).toBe('square');
    +      // expect(blocks[1].ID).toBe('id2');
    +      // expect(blocks[1].label).toBe('id2');
    +      // expect(blocks[1].type).toBe('square');
    +    });
    +    it.only('compound blocks', async () => {
    +      const str = `block-beta
    +          block
    +            aBlock["ABlock"]
    +            block
    +              bBlock["BBlock"]
    +            end
               end
             `;
     
           block.parse(str);
    +      const blocks = db.getBlocks();
    +
    +      const aBlockPos = blocks[0].children[0];
    +      const bBlockPos = blocks[0].children[1].children[0];
    +
    +      const root = db.getNodeById(blocks[0].id);
    +      expect(blocks.length).toBe(1);
    +      expect(blocks[0].id).not.toBe(undefined);
    +      expect(root?.label).toBe(blocks[0].id);
    +      expect(blocks[0].children.length).toBe(2);
    +      expect(root?.type).toBe('composite');
    +
    +      const aBlock = db.getNodeById(aBlockPos.id);
    +      console.log('aBlock', aBlock);
    +      expect(aBlock?.label).toBe('ABlock');
    +      expect(aBlock?.type).toBe('square');
    +
    +      const bBlock = db.getNodeById(bBlockPos.id);
    +
    +      expect(bBlock.id).toBe('bBlock');
    +      expect(bBlock.label).toBe('BBlock');
    +      expect(bBlock.type).toBe('square');
         });
         it.skip('compound blocks with title', async () => {
           const str = `block
    
    From 8a55b212a227c970fda4030d5e94e668dc9d17ad Mon Sep 17 00:00:00 2001
    From: Knut Sveidqvist 
    Date: Fri, 1 Sep 2023 15:33:38 +0200
    Subject: [PATCH 011/217] Saving data from compound blocks
    
    ---
     .../mermaid/src/diagrams/block/blockDB.ts     | 68 ++++++++--------
     .../mermaid/src/diagrams/block/blockTypes.ts  |  3 +-
     .../src/diagrams/block/parser/block.jison     | 10 +--
     .../src/diagrams/block/parser/block.spec.ts   | 77 +++++++++++--------
     4 files changed, 85 insertions(+), 73 deletions(-)
    
    diff --git a/packages/mermaid/src/diagrams/block/blockDB.ts b/packages/mermaid/src/diagrams/block/blockDB.ts
    index 2ef2044306..9717bc348b 100644
    --- a/packages/mermaid/src/diagrams/block/blockDB.ts
    +++ b/packages/mermaid/src/diagrams/block/blockDB.ts
    @@ -18,48 +18,46 @@ import { log } from '../../logger.js';
     // export type TBlockColumnsDefaultValue = 'H'; // Do we support something else, like 'auto' | 0?
     
     // Initialize the node database for simple lookups
    -let nodeDatabase: Record = {};
    -const blockDatabase: Record = {};
    +let blockDatabase: Record = {};
    +
    +const populateBlockDatabase = (blockList: Block[], parent: Block): void => {
    +  for (const block of blockList) {
    +    if (block.type === 'column-setting') {
    +      const columns = block.columns || -1;
    +      parent.columns = columns;
    +    } else {
    +      if (!block.label) {
    +        block.label = block.id;
    +      }
    +      blockDatabase[block.id] = block;
    +
    +      if (block.children) {
    +        populateBlockDatabase(block.children, block);
    +      }
    +    }
    +  }
    +};
     
     // Function to get a node by its id
     type IGetNodeById = (id: string) => Block | undefined;
    -export const getNodeById = (id: string): Block | undefined => {
    -  console.log(id, nodeDatabase);
    +export const getBlockById = (id: string): Block | undefined => {
       return blockDatabase[id];
     };
     
     // TODO: Convert to generic TreeNode type? Convert to class?
     
    -let rootBlock = { id: 'root', children: [] as Block[], columns: -1 };
     let blocks: Block[] = [];
     const links: Link[] = [];
    -// let rootBlock = { id: 'root', children: [], columns: -1 } as Block;
    -let currentBlock = rootBlock;
    +let rootBlock = { id: 'root', type: 'composite', children: [], columns: -1 } as Block;
     
     const clear = (): void => {
       log.info('Clear called');
    -  // rootBlocks = [];
    -  blocks = [] as Block[];
       commonClear();
    -  rootBlock = { id: 'root', children: [], columns: -1 };
    -  currentBlock = rootBlock;
    -  nodeDatabase = {};
    -  blockDatabase[rootBlock.id] = rootBlock;
    +  rootBlock = { id: 'root', type: 'composite', children: [], columns: -1 } as Block;
    +  blockDatabase = { root: rootBlock };
    +  blocks = [] as Block[];
     };
     
    -// type IAddBlock = (block: Block) => Block;
    -// const addBlock: IAddBlock = (block: Block, parent?: Block): Block => {
    -//   log.info('addBlock', block, parent);
    -//   if (parent) {
    -//     parent.children ??= [];
    -//     parent.children.push(block);
    -//   } else {
    -//     rootBlock.children.push(block);
    -//   }
    -//   blocks.push(block);
    -//   return block;
    -// };
    -
     type ITypeStr2Type = (typeStr: string) => BlockType;
     export function typeStr2Type(typeStr: string) {
       // TODO: add all types
    @@ -74,6 +72,7 @@ export function typeStr2Type(typeStr: string) {
     }
     
     let cnt = 0;
    +type IGenerateId = () => string;
     export const generateId = () => {
       cnt++;
       return 'id-' + Math.random().toString(36).substr(2, 12) + '-' + cnt;
    @@ -96,13 +95,15 @@ export const addBlock = (_id: string, _label?: string, type?: BlockType) => {
       blockDatabase[node.id] = node;
       // currentBlock.children ??= [];
       // currentBlock.children.push(node);
    -  // console.log('currentBlock', currentBlock.children, nodeDatabase);
    -  console.log('addNode called:', id, label, type, node);
    +  // log.info('currentBlock', currentBlock.children, nodeDatabase);
    +  log.info('addNode called:', id, label, type, node);
       return node;
     };
     
     type ISetHierarchy = (block: Block[]) => void;
     const setHierarchy = (block: Block[]): void => {
    +  populateBlockDatabase(block, rootBlock);
    +  log.info('blockdb', JSON.stringify(blockDatabase, null, 2));
       blocks = block;
     };
     
    @@ -115,7 +116,6 @@ const addLink: IAddLink = (link: Link): Link => {
     type ISetColumns = (columnsStr: string) => void;
     const setColumns = (columnsStr: string): void => {
       const columns = columnsStr === 'auto' ? -1 : parseInt(columnsStr);
    -  currentBlock!.columns = columns;
     };
     
     const getBlock = (id: string, blocks: Block[]): Block | undefined => {
    @@ -149,8 +149,8 @@ const getColumns = (blockid: string): number => {
     
     type IGetBlocks = () => Block[];
     const getBlocks: IGetBlocks = () => {
    -  // console.log('Block in test', rootBlock.children || []);
    -  console.log('Block in test', blocks, blocks[0].id);
    +  // log.info('Block in test', rootBlock.children || []);
    +  log.info('Block in test', blocks, blocks[0].id);
       return blocks || [];
     };
     
    @@ -172,7 +172,8 @@ export interface BlockDB extends DiagramDB {
       getColumns: IGetColumns;
       typeStr2Type: ITypeStr2Type;
       setHierarchy: ISetHierarchy;
    -  getNodeById: IGetNodeById;
    +  getBlockById: IGetNodeById;
    +  generateId: IGenerateId;
     }
     
     const db: BlockDB = {
    @@ -184,7 +185,7 @@ const db: BlockDB = {
       getBlocks,
       getLinks,
       setHierarchy,
    -  getNodeById,
    +  getBlockById,
       // getAccTitle,
       // setAccTitle,
       // getAccDescription,
    @@ -194,6 +195,7 @@ const db: BlockDB = {
       setColumns,
       getColumns,
       clear,
    +  generateId,
     };
     
     export default db;
    diff --git a/packages/mermaid/src/diagrams/block/blockTypes.ts b/packages/mermaid/src/diagrams/block/blockTypes.ts
    index 4afbe43519..a695b4ec78 100644
    --- a/packages/mermaid/src/diagrams/block/blockTypes.ts
    +++ b/packages/mermaid/src/diagrams/block/blockTypes.ts
    @@ -22,7 +22,8 @@ export type BlockType =
       | 'cylinder'
       | 'group'
       | 'doublecircle'
    -  | 'composite';
    +  | 'composite'
    +  | 'column-setting';
     
     export interface Block {
       id: string;
    diff --git a/packages/mermaid/src/diagrams/block/parser/block.jison b/packages/mermaid/src/diagrams/block/parser/block.jison
    index 309dbfdeaf..829ccd300c 100644
    --- a/packages/mermaid/src/diagrams/block/parser/block.jison
    +++ b/packages/mermaid/src/diagrams/block/parser/block.jison
    @@ -138,7 +138,7 @@ seperator
       ;
     
     start: BLOCK_DIAGRAM_KEY document EOF
    -  {console.log('This is the hierarchy ', JSON.stringify($2, null, 2)); yy.setHierarchy($2); }
    +  {yy.getLogger().info('This is the hierarchy ', JSON.stringify($2, null, 2)); yy.setHierarchy($2); }
       ;
     
     
    @@ -180,16 +180,16 @@ statement
     	;
     
     nodeStatement
    -  : nodeStatement link node { yy.getLogger().info('Rule: nodeStatement (nodeStatement link node) '); yy.addBlock($1.id); $$ = {id: $1.id}; }
    -  | node { yy.getLogger().info('Rule: nodeStatement (node) ', $1); yy.addBlock($1.id, $1.label, yy.typeStr2Type($1)); $$ = {id: $1.id}; }
    +  : nodeStatement link node { yy.getLogger().info('Rule: nodeStatement (nodeStatement link node) '); $$ = {id: $1.id}; }
    +  | node { yy.getLogger().info('Rule: nodeStatement (node) ', $1); $$ = {id: $1.id, label: $1.label, type: yy.typeStr2Type($1)}; }
       ;
     
     columnsStatement
    -  : COLUMNS { yy.getLogger().info("COLUMNS: ", $1);yy.setColumns($1); }
    +  : COLUMNS { yy.getLogger().info("COLUMNS: ", $1); $$ = {type: 'column-setting', columns: $1 === 'auto'?-1:parseInt($1) } }
       ;
     
     blockStatement
    -  : block document end { console.log('Rule: blockStatement : ', $1, $2, $3); const block = yy.addBlock(undefined, undefined, 'composite'); $$ = { id: block.id, children: $2 }; }
    +  : block document end { yy.getLogger().info('Rule: blockStatement : ', $1, $2, $3); const id = yy.generateId(); $$ = { id, type:'composite', label:id, children: $2 }; }
       ;
     
     
    diff --git a/packages/mermaid/src/diagrams/block/parser/block.spec.ts b/packages/mermaid/src/diagrams/block/parser/block.spec.ts
    index 584a817b55..eea9bb65bb 100644
    --- a/packages/mermaid/src/diagrams/block/parser/block.spec.ts
    +++ b/packages/mermaid/src/diagrams/block/parser/block.spec.ts
    @@ -21,7 +21,7 @@ describe('Block diagram', function () {
           block.parse(str);
           const blocks = db.getBlocks();
           expect(blocks.length).toBe(1);
    -      expect(blocks[0].ID).toBe('id');
    +      expect(blocks[0].id).toBe('id');
           expect(blocks[0].label).toBe('id');
         });
         it('a node with a square shape and a label', async () => {
    @@ -32,7 +32,7 @@ describe('Block diagram', function () {
           block.parse(str);
           const blocks = db.getBlocks();
           expect(blocks.length).toBe(1);
    -      expect(blocks[0].ID).toBe('id');
    +      expect(blocks[0].id).toBe('id');
           expect(blocks[0].label).toBe('A label');
           expect(blocks[0].type).toBe('square');
         });
    @@ -45,10 +45,10 @@ describe('Block diagram', function () {
           block.parse(str);
           const blocks = db.getBlocks();
           expect(blocks.length).toBe(2);
    -      expect(blocks[0].ID).toBe('id1');
    +      expect(blocks[0].id).toBe('id1');
           expect(blocks[0].label).toBe('id1');
           expect(blocks[0].type).toBe('square');
    -      expect(blocks[1].ID).toBe('id2');
    +      expect(blocks[1].id).toBe('id2');
           expect(blocks[1].label).toBe('id2');
           expect(blocks[1].type).toBe('square');
         });
    @@ -62,13 +62,13 @@ describe('Block diagram', function () {
           block.parse(str);
           const blocks = db.getBlocks();
           expect(blocks.length).toBe(3);
    -      expect(blocks[0].ID).toBe('id1');
    +      expect(blocks[0].id).toBe('id1');
           expect(blocks[0].label).toBe('id1');
           expect(blocks[0].type).toBe('square');
    -      expect(blocks[1].ID).toBe('id2');
    +      expect(blocks[1].id).toBe('id2');
           expect(blocks[1].label).toBe('id2');
           expect(blocks[1].type).toBe('square');
    -      expect(blocks[2].ID).toBe('id3');
    +      expect(blocks[2].id).toBe('id3');
           expect(blocks[2].label).toBe('id3');
           expect(blocks[2].type).toBe('square');
         });
    @@ -81,10 +81,10 @@ describe('Block diagram', function () {
           block.parse(str);
           const blocks = db.getBlocks();
           expect(blocks.length).toBe(2);
    -      expect(blocks[0].ID).toBe('id');
    +      expect(blocks[0].id).toBe('id');
           expect(blocks[0].label).toBe('A label');
           expect(blocks[0].type).toBe('square');
    -      expect(blocks[1].ID).toBe('id2');
    +      expect(blocks[1].id).toBe('id2');
           expect(blocks[1].label).toBe('id2');
           expect(blocks[1].type).toBe('square');
         });
    @@ -152,24 +152,32 @@ describe('Block diagram', function () {
         it('compound blocks 2', async () => {
           const str = `block-beta
               block
    -            aBlock["Block"]
    -            bBlock["Block"]
    +            aBlock["ABlock"]
    +            bBlock["BBlock"]
               end
             `;
     
           block.parse(str);
           const blocks = db.getBlocks();
    -      console.log('blocks', blocks);
           expect(blocks.length).toBe(1);
    +
           expect(blocks[0].children.length).toBe(2);
    -      expect(blocks[0].id).toBe('id');
    -      expect(blocks[0].label).toBe('A label');
    -      expect(blocks[0].type).toBe('square');
    -      // expect(blocks[1].ID).toBe('id2');
    -      // expect(blocks[1].label).toBe('id2');
    -      // expect(blocks[1].type).toBe('square');
    +      expect(blocks[0].id).not.toBe(undefined);
    +      expect(blocks[0].label).toBe(blocks[0].id);
    +      expect(blocks[0].type).toBe('composite');
    +
    +      const aBlock = blocks[0].children[0];
    +
    +      expect(aBlock.id).not.toBe(aBlock);
    +      expect(aBlock.label).toBe('ABlock');
    +      expect(aBlock.type).toBe('square');
    +
    +      const bBlock = blocks[0].children[1];
    +      expect(bBlock.id).not.toBe(bBlock);
    +      expect(bBlock.label).toBe('BBlock');
    +      expect(bBlock.type).toBe('square');
         });
    -    it.only('compound blocks', async () => {
    +    it('compound blocks of compound blocks', async () => {
           const str = `block-beta
               block
                 aBlock["ABlock"]
    @@ -182,29 +190,30 @@ describe('Block diagram', function () {
           block.parse(str);
           const blocks = db.getBlocks();
     
    -      const aBlockPos = blocks[0].children[0];
    -      const bBlockPos = blocks[0].children[1].children[0];
    +      const aBlock = blocks[0].children[0];
    +      const secondComposite = blocks[0].children[1];
    +      const bBlock = blocks[0].children[1].children[0];
     
    -      const root = db.getNodeById(blocks[0].id);
    -      expect(blocks.length).toBe(1);
    -      expect(blocks[0].id).not.toBe(undefined);
    -      expect(root?.label).toBe(blocks[0].id);
           expect(blocks[0].children.length).toBe(2);
    -      expect(root?.type).toBe('composite');
    +      expect(blocks[0].id).not.toBe(undefined);
    +      expect(blocks[0].label).toBe(blocks[0].id);
    +      expect(blocks[0].type).toBe('composite');
     
    -      const aBlock = db.getNodeById(aBlockPos.id);
    -      console.log('aBlock', aBlock);
    -      expect(aBlock?.label).toBe('ABlock');
    -      expect(aBlock?.type).toBe('square');
    +      expect(secondComposite.children.length).toBe(1);
    +      expect(secondComposite.id).not.toBe(undefined);
    +      expect(secondComposite.label).toBe(secondComposite.id);
    +      expect(secondComposite.type).toBe('composite');
     
    -      const bBlock = db.getNodeById(bBlockPos.id);
    +      expect(aBlock.id).not.toBe(aBlock);
    +      expect(aBlock.label).toBe('ABlock');
    +      expect(aBlock.type).toBe('square');
     
    -      expect(bBlock.id).toBe('bBlock');
    +      expect(bBlock.id).not.toBe(bBlock);
           expect(bBlock.label).toBe('BBlock');
           expect(bBlock.type).toBe('square');
         });
    -    it.skip('compound blocks with title', async () => {
    -      const str = `block
    +    it('compound blocks with title', async () => {
    +      const str = `block-beta
               block compoundBlock["Compound block"]
                 columns 1
                 block2["Block 1"]
    
    From e52de6c27982fd8b1cedb8e2c00fb137e0081ed9 Mon Sep 17 00:00:00 2001
    From: Knut Sveidqvist 
    Date: Fri, 1 Sep 2023 15:40:49 +0200
    Subject: [PATCH 012/217] Some cleanup
    
    ---
     .../mermaid/src/diagrams/block/blockDB.ts     | 58 -------------------
     1 file changed, 58 deletions(-)
    
    diff --git a/packages/mermaid/src/diagrams/block/blockDB.ts b/packages/mermaid/src/diagrams/block/blockDB.ts
    index 9717bc348b..b0a7c20c16 100644
    --- a/packages/mermaid/src/diagrams/block/blockDB.ts
    +++ b/packages/mermaid/src/diagrams/block/blockDB.ts
    @@ -15,8 +15,6 @@ import {
     } from '../../commonDb.js';
     import { log } from '../../logger.js';
     
    -// export type TBlockColumnsDefaultValue = 'H'; // Do we support something else, like 'auto' | 0?
    -
     // Initialize the node database for simple lookups
     let blockDatabase: Record = {};
     
    @@ -38,14 +36,6 @@ const populateBlockDatabase = (blockList: Block[], parent: Block): void => {
       }
     };
     
    -// Function to get a node by its id
    -type IGetNodeById = (id: string) => Block | undefined;
    -export const getBlockById = (id: string): Block | undefined => {
    -  return blockDatabase[id];
    -};
    -
    -// TODO: Convert to generic TreeNode type? Convert to class?
    -
     let blocks: Block[] = [];
     const links: Link[] = [];
     let rootBlock = { id: 'root', type: 'composite', children: [], columns: -1 } as Block;
    @@ -78,28 +68,6 @@ export const generateId = () => {
       return 'id-' + Math.random().toString(36).substr(2, 12) + '-' + cnt;
     };
     
    -type IAddBlock = (_id: string, label: string, type: BlockType) => Block;
    -// Function to add a node to the database
    -export const addBlock = (_id: string, _label?: string, type?: BlockType) => {
    -  let id = _id;
    -  if (!_id) {
    -    id = generateId();
    -  }
    -  const label = _label || id;
    -  const node: Block = {
    -    id: id,
    -    label,
    -    type: type || 'square',
    -    children: [],
    -  };
    -  blockDatabase[node.id] = node;
    -  // currentBlock.children ??= [];
    -  // currentBlock.children.push(node);
    -  // log.info('currentBlock', currentBlock.children, nodeDatabase);
    -  log.info('addNode called:', id, label, type, node);
    -  return node;
    -};
    -
     type ISetHierarchy = (block: Block[]) => void;
     const setHierarchy = (block: Block[]): void => {
       populateBlockDatabase(block, rootBlock);
    @@ -113,25 +81,6 @@ const addLink: IAddLink = (link: Link): Link => {
       return link;
     };
     
    -type ISetColumns = (columnsStr: string) => void;
    -const setColumns = (columnsStr: string): void => {
    -  const columns = columnsStr === 'auto' ? -1 : parseInt(columnsStr);
    -};
    -
    -const getBlock = (id: string, blocks: Block[]): Block | undefined => {
    -  for (const block of blocks) {
    -    if (block.id === id) {
    -      return block;
    -    }
    -    if (block.children) {
    -      const foundBlock = getBlock(id, block.children);
    -      if (foundBlock) {
    -        return foundBlock;
    -      }
    -    }
    -  }
    -};
    -
     type IGetColumns = (blockid: string) => number;
     const getColumns = (blockid: string): number => {
       const block = blockDatabase[blockid];
    @@ -149,7 +98,6 @@ const getColumns = (blockid: string): number => {
     
     type IGetBlocks = () => Block[];
     const getBlocks: IGetBlocks = () => {
    -  // log.info('Block in test', rootBlock.children || []);
       log.info('Block in test', blocks, blocks[0].id);
       return blocks || [];
     };
    @@ -163,36 +111,30 @@ const getLogger: IGetLogger = () => console;
     export interface BlockDB extends DiagramDB {
       clear: () => void;
       getConfig: () => BlockConfig | undefined;
    -  addBlock: IAddBlock;
       addLink: IAddLink;
       getLogger: IGetLogger;
       getBlocks: IGetBlocks;
       getLinks: IGetLinks;
    -  setColumns: ISetColumns;
       getColumns: IGetColumns;
       typeStr2Type: ITypeStr2Type;
       setHierarchy: ISetHierarchy;
    -  getBlockById: IGetNodeById;
       generateId: IGenerateId;
     }
     
     const db: BlockDB = {
       getConfig: () => configApi.getConfig().block,
    -  addBlock: addBlock,
       addLink: addLink,
       typeStr2Type: typeStr2Type,
       getLogger, // TODO: remove
       getBlocks,
       getLinks,
       setHierarchy,
    -  getBlockById,
       // getAccTitle,
       // setAccTitle,
       // getAccDescription,
       // setAccDescription,
       // getDiagramTitle,
       // setDiagramTitle,
    -  setColumns,
       getColumns,
       clear,
       generateId,
    
    From 5f1cfc7519031f92ccdbca3dde85736a979a08bc Mon Sep 17 00:00:00 2001
    From: Knut Sveidqvist 
    Date: Fri, 1 Sep 2023 16:22:23 +0200
    Subject: [PATCH 013/217] Support for compound blocks with id, title and type
    
    ---
     .../mermaid/src/diagrams/block/blockDB.ts     |  7 ++++++-
     .../mermaid/src/diagrams/block/blockTypes.ts  |  4 ++--
     .../src/diagrams/block/parser/block.jison     |  6 ++++--
     .../src/diagrams/block/parser/block.spec.ts   | 19 +++++++++++++++++--
     4 files changed, 29 insertions(+), 7 deletions(-)
    
    diff --git a/packages/mermaid/src/diagrams/block/blockDB.ts b/packages/mermaid/src/diagrams/block/blockDB.ts
    index b0a7c20c16..7c90ad2dbc 100644
    --- a/packages/mermaid/src/diagrams/block/blockDB.ts
    +++ b/packages/mermaid/src/diagrams/block/blockDB.ts
    @@ -19,6 +19,7 @@ import { log } from '../../logger.js';
     let blockDatabase: Record = {};
     
     const populateBlockDatabase = (blockList: Block[], parent: Block): void => {
    +  const children = [];
       for (const block of blockList) {
         if (block.type === 'column-setting') {
           const columns = block.columns || -1;
    @@ -32,8 +33,12 @@ const populateBlockDatabase = (blockList: Block[], parent: Block): void => {
           if (block.children) {
             populateBlockDatabase(block.children, block);
           }
    +      if (block.type !== 'column-setting') {
    +        children.push(block);
    +      }
         }
       }
    +  parent.children = children;
     };
     
     let blocks: Block[] = [];
    @@ -71,7 +76,7 @@ export const generateId = () => {
     type ISetHierarchy = (block: Block[]) => void;
     const setHierarchy = (block: Block[]): void => {
       populateBlockDatabase(block, rootBlock);
    -  log.info('blockdb', JSON.stringify(blockDatabase, null, 2));
    +  log.debug('The hierarchy', JSON.stringify(block, null, 2));
       blocks = block;
     };
     
    diff --git a/packages/mermaid/src/diagrams/block/blockTypes.ts b/packages/mermaid/src/diagrams/block/blockTypes.ts
    index a695b4ec78..aca83f4212 100644
    --- a/packages/mermaid/src/diagrams/block/blockTypes.ts
    +++ b/packages/mermaid/src/diagrams/block/blockTypes.ts
    @@ -5,6 +5,7 @@ export interface BlockConfig extends BaseDiagramConfig {
     }
     
     export type BlockType =
    +  | 'column-setting'
       | 'round'
       | 'square'
       | 'diamond'
    @@ -22,8 +23,7 @@ export type BlockType =
       | 'cylinder'
       | 'group'
       | 'doublecircle'
    -  | 'composite'
    -  | 'column-setting';
    +  | 'composite';
     
     export interface Block {
       id: string;
    diff --git a/packages/mermaid/src/diagrams/block/parser/block.jison b/packages/mermaid/src/diagrams/block/parser/block.jison
    index 829ccd300c..9cc220ff40 100644
    --- a/packages/mermaid/src/diagrams/block/parser/block.jison
    +++ b/packages/mermaid/src/diagrams/block/parser/block.jison
    @@ -29,6 +29,7 @@ CRLF \u000D\u000A
     "block-beta"                                             { return 'BLOCK_DIAGRAM_KEY'; }
     "block"\s+            { yy.getLogger().info('Found space-block'); return 'block';}
     "block"\n+            { yy.getLogger().info('Found nl-block'); return 'block';}
    +"block:"            { yy.getLogger().info('Found space-block'); return 'id-block';}
     // \s*\%\%.*                                                       { yy.getLogger().info('Found comment',yytext); }
     [\s]+                                                           { yy.getLogger().info('.', yytext); /* skip all whitespace */  }
     [\n]+ {yy.getLogger().info('_', yytext);                 /* skip all whitespace */   }
    @@ -138,7 +139,7 @@ seperator
       ;
     
     start: BLOCK_DIAGRAM_KEY document EOF
    -  {yy.getLogger().info('This is the hierarchy ', JSON.stringify($2, null, 2)); yy.setHierarchy($2); }
    +  { yy.setHierarchy($2); }
       ;
     
     
    @@ -189,7 +190,8 @@ columnsStatement
       ;
     
     blockStatement
    -  : block document end { yy.getLogger().info('Rule: blockStatement : ', $1, $2, $3); const id = yy.generateId(); $$ = { id, type:'composite', label:id, children: $2 }; }
    +  : id-block nodeStatement document end { yy.getLogger().info('Rule: id-block statement : ', $2, $3); const id2 = yy.generateId(); $$ = { ...$2, children: $3 }; }
    +  | block document end { yy.getLogger().info('Rule: blockStatement : ', $1, $2, $3); const id = yy.generateId(); $$ = { id, type:'composite', label:id, children: $2 }; }
       ;
     
     
    diff --git a/packages/mermaid/src/diagrams/block/parser/block.spec.ts b/packages/mermaid/src/diagrams/block/parser/block.spec.ts
    index eea9bb65bb..adb814be22 100644
    --- a/packages/mermaid/src/diagrams/block/parser/block.spec.ts
    +++ b/packages/mermaid/src/diagrams/block/parser/block.spec.ts
    @@ -214,13 +214,28 @@ describe('Block diagram', function () {
         });
         it('compound blocks with title', async () => {
           const str = `block-beta
    -          block compoundBlock["Compound block"]
    +          block:compoundBlock["Compound block"]
                 columns 1
    -            block2["Block 1"]
    +            block2["Block 2"]
               end
             `;
     
           block.parse(str);
    +
    +      const blocks = db.getBlocks();
    +      expect(blocks.length).toBe(1);
    +
    +      const compoundBlock = blocks[0];
    +      const block2 = compoundBlock.children[0];
    +
    +      expect(compoundBlock.children.length).toBe(1);
    +      expect(compoundBlock.id).toBe('compoundBlock');
    +      expect(compoundBlock.label).toBe('Compound block');
    +      expect(compoundBlock.type).toBe('square');
    +
    +      expect(block2.id).toBe('block2');
    +      expect(block2.label).toBe('Block 2');
    +      expect(block2.type).toBe('square');
         });
         it.skip('blocks mixed with compound blocks', async () => {
           const str = `block
    
    From 1e864a508d7f030b79e9bf58667354057694b1fc Mon Sep 17 00:00:00 2001
    From: Knut Sveidqvist 
    Date: Tue, 5 Sep 2023 11:13:27 +0200
    Subject: [PATCH 014/217] Rendering, tmp commit before refactoring
    
    ---
     cypress/platform/knsv2.html                   |  24 +-
     packages/mermaid/src/dagre-wrapper/nodes.js   |  16 +-
     .../mermaid/src/diagrams/block/blockDB.ts     |  14 +
     .../src/diagrams/block/blockDiagram.ts        |   2 +
     .../src/diagrams/block/blockRenderer.ts       | 126 +++---
     .../mermaid/src/diagrams/block/blockTypes.ts  |   7 +
     packages/mermaid/src/diagrams/block/layout.ts | 108 +++++
     .../src/diagrams/block/renderHelpers.ts       | 270 ++++++++++++
     packages/mermaid/src/diagrams/block/styles.ts | 144 +++++++
     .../flowchart/swimlane/swimlaneRenderer.js    | 400 ++++++++++++++++++
     10 files changed, 1033 insertions(+), 78 deletions(-)
     create mode 100644 packages/mermaid/src/diagrams/block/layout.ts
     create mode 100644 packages/mermaid/src/diagrams/block/renderHelpers.ts
     create mode 100644 packages/mermaid/src/diagrams/block/styles.ts
     create mode 100644 packages/mermaid/src/diagrams/flowchart/swimlane/swimlaneRenderer.js
    
    diff --git a/cypress/platform/knsv2.html b/cypress/platform/knsv2.html
    index e19d53ae47..4609331dd5 100644
    --- a/cypress/platform/knsv2.html
    +++ b/cypress/platform/knsv2.html
    @@ -24,6 +24,9 @@
           h1 {
             color: grey;
           }
    +      .mermaid {
    +        border: 1px solid #ddd;
    +      }
           .mermaid2 {
             display: none;
           }
    @@ -59,16 +62,17 @@
       
         
     block-beta
    -          id
    + id1("Wide 1") + id2("2") + id3("3") + id4("A final one") + +
     flowchart RL
    -    subgraph "`one`"
    -      a1 -- l1 --> a2
    -      a1 -- l2 --> a2
    -    end
    +    id
         
    -
    +    
     flowchart RL
         subgraph "`one`"
           a1 -- l1 --> a2
    @@ -93,11 +97,11 @@
             way`"]
       
    -
    +    
           classDiagram-v2
             note "I love this diagram!\nDo you love it?"
         
    -
    +    
         stateDiagram-v2
         State1: The state with a note with minus - and plus + in it
         note left of State1
    @@ -142,7 +146,7 @@
           शान्तिः سلام  和平 `"]
     
         
    -
    +    
     %%{init: {"flowchart": {"defaultRenderer": "elk"}} }%%
     flowchart TB
       %% I could not figure out how to use double quotes in labels in Mermaid
    diff --git a/packages/mermaid/src/dagre-wrapper/nodes.js b/packages/mermaid/src/dagre-wrapper/nodes.js
    index 6c67333585..e6a9d982a2 100644
    --- a/packages/mermaid/src/dagre-wrapper/nodes.js
    +++ b/packages/mermaid/src/dagre-wrapper/nodes.js
    @@ -1037,14 +1037,14 @@ export const positionNode = (node) => {
       const padding = 8;
       const diff = node.diff || 0;
       if (node.clusterNode) {
    -    el.attr(
    -      'transform',
    -      'translate(' +
    -        (node.x + diff - node.width / 2) +
    -        ', ' +
    -        (node.y - node.height / 2 - padding) +
    -        ')'
    -    );
    +      el.attr(
    +        'transform',
    +        'translate(' +
    +          (node.x + diff - node.width / 2) +
    +          ', ' +
    +          (node.y - node.height / 2 - padding) +
    +          ')'
    +      );
       } else {
         el.attr('transform', 'translate(' + node.x + ', ' + node.y + ')');
       }
    diff --git a/packages/mermaid/src/diagrams/block/blockDB.ts b/packages/mermaid/src/diagrams/block/blockDB.ts
    index 7c90ad2dbc..039353830e 100644
    --- a/packages/mermaid/src/diagrams/block/blockDB.ts
    +++ b/packages/mermaid/src/diagrams/block/blockDB.ts
    @@ -106,6 +106,16 @@ const getBlocks: IGetBlocks = () => {
       log.info('Block in test', blocks, blocks[0].id);
       return blocks || [];
     };
    +type IGetBlock = (id: string) => Block | undefined;
    +const getBlock: IGetBlock = (id: string) => {
    +  log.info('Block in test', blocks, blocks[0].id);
    +  return blockDatabase[id];
    +};
    +type ISetBlock = (block: Block) => void;
    +const setBlock: ISetBlock = (block: Block) => {
    +  log.info('Block in test', blocks, blocks[0].id);
    +  blockDatabase[block.id] = block;
    +};
     
     type IGetLinks = () => Link[];
     const getLinks: IGetLinks = () => links;
    @@ -119,6 +129,8 @@ export interface BlockDB extends DiagramDB {
       addLink: IAddLink;
       getLogger: IGetLogger;
       getBlocks: IGetBlocks;
    +  getBlock: IGetBlock;
    +  setBlock: ISetBlock;
       getLinks: IGetLinks;
       getColumns: IGetColumns;
       typeStr2Type: ITypeStr2Type;
    @@ -134,6 +146,8 @@ const db: BlockDB = {
       getBlocks,
       getLinks,
       setHierarchy,
    +  getBlock,
    +  setBlock,
       // getAccTitle,
       // setAccTitle,
       // getAccDescription,
    diff --git a/packages/mermaid/src/diagrams/block/blockDiagram.ts b/packages/mermaid/src/diagrams/block/blockDiagram.ts
    index e098360f43..b3071cb0b3 100644
    --- a/packages/mermaid/src/diagrams/block/blockDiagram.ts
    +++ b/packages/mermaid/src/diagrams/block/blockDiagram.ts
    @@ -2,6 +2,7 @@ import { DiagramDefinition } from '../../diagram-api/types.js';
     // @ts-ignore: jison doesn't export types
     import parser from './parser/block.jison';
     import db from './blockDB.js';
    +import flowStyles from './styles.js';
     import renderer from './blockRenderer.js';
     
     // TODO: do we need this?
    @@ -14,4 +15,5 @@ export const diagram: DiagramDefinition = {
       parser,
       db,
       renderer,
    +  styles: flowStyles,
     };
    diff --git a/packages/mermaid/src/diagrams/block/blockRenderer.ts b/packages/mermaid/src/diagrams/block/blockRenderer.ts
    index 84acdaf3f9..0dac714d42 100644
    --- a/packages/mermaid/src/diagrams/block/blockRenderer.ts
    +++ b/packages/mermaid/src/diagrams/block/blockRenderer.ts
    @@ -1,20 +1,30 @@
     import { Diagram } from '../../Diagram.js';
     import * as configApi from '../../config.js';
    -
    +import { calculateBlockSizes } from './renderHelpers.js';
    +import { layout } from './layout.js';
    +import { setupGraphViewbox } from '../../setupGraphViewbox.js';
     import {
       select as d3select,
       scaleOrdinal as d3scaleOrdinal,
       schemeTableau10 as d3schemeTableau10,
    +  ContainerElement,
     } from 'd3';
     
    -import { BlockDB, Block } from './blockDB.js';
    +import { BlockDB } from './blockDB.js';
    +import type { Block } from './blockTypes.js';
     
     // import { diagram as BlockDiagram } from './blockDiagram.js';
     import { configureSvgSize } from '../../setupGraphViewbox.js';
     import { Uid } from '../../rendering-util/uid.js';
     
    -export const draw = function (text: string, id: string, _version: string, diagObj: Diagram): void {
    -  const { securityLevel } = configApi.getConfig();
    +export const draw = async function (
    +  text: string,
    +  id: string,
    +  _version: string,
    +  diagObj: Diagram
    +): Promise {
    +  const { securityLevel, flowchart: conf } = configApi.getConfig();
    +  const db = diagObj.db as BlockDB;
       let sandboxElement: any;
       if (securityLevel === 'sandbox') {
         sandboxElement = d3select('#i' + id);
    @@ -27,12 +37,23 @@ export const draw = function (text: string, id: string, _version: string, diagOb
       // @ts-ignore TODO root.select is not callable
       const svg = securityLevel === 'sandbox' ? root.select(`[id="${id}"]`) : d3select(`[id="${id}"]`);
     
    +  const bl = db.getBlocks();
    +
    +  const nodes = svg.insert('g').attr('class', 'block');
    +  await calculateBlockSizes(nodes, bl, db);
    +  const bounds = layout(db);
    +
    +  console.log('Here', bl);
    +
       // Establish svg dimensions and get width and height
    -  //  
    -  const height = 400;
    -  const width = 600;
    +  //
    +  // const bounds = nodes.node().getBoundingClientRect();
    +  const height = bounds.height;
    +  const width = bounds.width;
       const useMaxWidth = false;
       configureSvgSize(svg, height, width, useMaxWidth);
    +  console.log('Here Bounds', bounds);
    +  svg.attr('viewBox', `${bounds.x} ${bounds.y} ${bounds.width} ${bounds.height}`);
     
       // Prepare data for construction based on diagObj.db
       // This must be a mutable object with `nodes` and `links` properties:
    @@ -53,107 +74,92 @@ export const draw = function (text: string, id: string, _version: string, diagOb
     
       const blocks: LayedBlock[] = [
         {
    -      ID: "ApplicationLayer",
    -      label: "Application Layer",
    +      ID: 'ApplicationLayer',
    +      label: 'Application Layer',
           x: 0,
           y: 0,
           children: [
             {
    -          ID: "UserInterface",
    -          label: "User Interface (WPF, HTML5/CSS3, Swing)",
    +          ID: 'UserInterface',
    +          label: 'User Interface (WPF, HTML5/CSS3, Swing)',
               x: 0,
    -          y: 50,    
    -        }
    +          y: 50,
    +        },
           ],
         },
         {
    -      ID: "PresentationLayer",
    -      label: "Presentation Layer",
    +      ID: 'PresentationLayer',
    +      label: 'Presentation Layer',
           x: 0,
           y: 50,
           children: [
             {
    -          ID: "Smack",
    -          label: "J2SE Mobil App (Smack)"
    +          ID: 'Smack',
    +          label: 'J2SE Mobil App (Smack)',
             },
             {
    -          ID: "JsJAC",
    -          label: "Java Script Browser App (JsJAC)",
    +          ID: 'JsJAC',
    +          label: 'Java Script Browser App (JsJAC)',
             },
             {
    -          ID: "babelim",
    -          label: ".NET Windows App (Babel-im)",
    +          ID: 'babelim',
    +          label: '.NET Windows App (Babel-im)',
             },
    -      ]
    +      ],
         },
         {
    -      ID: "SessionLayer",
    -      label: "Session Layer",
    +      ID: 'SessionLayer',
    +      label: 'Session Layer',
           x: 0,
           y: 100,
           children: [
             {
    -          ID: "XMPP",
    -          label: "XMPP Component"
    +          ID: 'XMPP',
    +          label: 'XMPP Component',
             },
             {
               children: [
                 {
    -              ID: "Authentication",
    -              label: "Authentication",
    +              ID: 'Authentication',
    +              label: 'Authentication',
                 },
                 {
    -              ID: "Authorization",
    -              label: "Authorization",
    +              ID: 'Authorization',
    +              label: 'Authorization',
                 },
    -          ]
    +          ],
             },
             {
    -          ID: "LDAP",
    -          label: "LDAP, DB, POP",
    +          ID: 'LDAP',
    +          label: 'LDAP, DB, POP',
             },
    -      ]
    +      ],
         },
         {
    -      ID: "NetworkLayer",
    -      label: "Network Layer",
    +      ID: 'NetworkLayer',
    +      label: 'Network Layer',
           x: 0,
           y: 150,
           children: [
    -        { ID: "HTTP", label: "HTTP" },
    -        { ID: "SOCK", label: "SOCK" },
    -      ]
    +        { ID: 'HTTP', label: 'HTTP' },
    +        { ID: 'SOCK', label: 'SOCK' },
    +      ],
         },
         {
    -      ID: "DataLayer",
    -      label: "Data Layer",
    +      ID: 'DataLayer',
    +      label: 'Data Layer',
           x: 0,
           y: 200,
           children: [
    -        { ID: "XMPP", label: "XMPP" },
    -        { ID: "BDB", label: "Business DB" },
    -        { ID: "AD", label: "Active Directory" },
    -      ]
    +        { ID: 'XMPP', label: 'XMPP' },
    +        { ID: 'BDB', label: 'Business DB' },
    +        { ID: 'AD', label: 'Active Directory' },
    +      ],
         },
       ];
     
       // Get color scheme for the graph
       const colorScheme = d3scaleOrdinal(d3schemeTableau10);
    -
    -  svg
    -    .append('g')
    -    .attr('class', 'block')
    -    .selectAll('.block')
    -    .data(blocks)
    -    .join('rect')
    -    .attr('x', (d: any) => d.x || 0)
    -    .attr('y', (d: any) => d.y || 0)
    -    .attr('class', 'block')
    -    .attr('stroke', 'black')
    -    .attr('height', (d: any) => 50)
    -    .attr('width', (d: any) => 100)
    -    .attr('fill', (d: any) => colorScheme(d.ID));
    -
     };
     
     export default {
    diff --git a/packages/mermaid/src/diagrams/block/blockTypes.ts b/packages/mermaid/src/diagrams/block/blockTypes.ts
    index aca83f4212..5a4431c0ae 100644
    --- a/packages/mermaid/src/diagrams/block/blockTypes.ts
    +++ b/packages/mermaid/src/diagrams/block/blockTypes.ts
    @@ -31,6 +31,13 @@ export interface Block {
       parent?: Block;
       type?: BlockType;
       children: Block[];
    +  size?: {
    +    width: number;
    +    height: number;
    +    x: number;
    +    y: number;
    +  };
    +  node?: any;
       columns?: number; // | TBlockColumnsDefaultValue;
     }
     
    diff --git a/packages/mermaid/src/diagrams/block/layout.ts b/packages/mermaid/src/diagrams/block/layout.ts
    new file mode 100644
    index 0000000000..65b99c1543
    --- /dev/null
    +++ b/packages/mermaid/src/diagrams/block/layout.ts
    @@ -0,0 +1,108 @@
    +import { BlockDB } from './blockDB.js';
    +import type { Block } from './blockTypes.js';
    +
    +function layoutBLock(block: Block, db: BlockDB) {
    +  if (block.children) {
    +    for (const child of block.children) {
    +      layoutBLock(child, db);
    +    }
    +    // find max width of children
    +    let maxWidth = 0;
    +    let maxHeight = 0;
    +    for (const child of block.children) {
    +      const { width, height, x, y } = child.size || { width: 0, height: 0, x: 0, y: 0 };
    +      if (width > maxWidth) {
    +        maxWidth = width;
    +      }
    +      if (height > maxHeight) {
    +        maxHeight = height;
    +      }
    +    }
    +
    +    // set width of block to max width of children
    +    for (const child of block.children) {
    +      if (child.size) {
    +        child.size.width = maxWidth;
    +        child.size.height = maxHeight;
    +      }
    +    }
    +
    +    // Position items
    +    let x = 0;
    +    let y = 0;
    +    const padding = 10;
    +    for (const child of block.children) {
    +      if (child.size) {
    +        child.size.x = x;
    +        child.size.y = y;
    +        x += maxWidth + padding;
    +      }
    +    }
    +  }
    +}
    +
    +function positionBlock(block: Block, db: BlockDB) {
    +  console.log('Here Positioning', block?.size?.node);
    +  // const o = db.getBlock(block.id);
    +  // const node;
    +  if (block?.size?.node) {
    +    const node = block?.size?.node;
    +    const size = block?.size;
    +    console.log('Here as well', node);
    +    if (node) {
    +      node.attr(
    +        'transform',
    +        'translate(' + (size.x - size.width / 2) + ', ' + (size.y - size.height / 2) + ')'
    +      );
    +    }
    +  }
    +  if (block.children) {
    +    for (const child of block.children) {
    +      positionBlock(child, db);
    +    }
    +  }
    +}
    +let minX = 0;
    +let minY = 0;
    +let maxX = 0;
    +let maxY = 0;
    +
    +function findBounds(block: Block) {
    +  if (block.size) {
    +    const { x, y, width, height } = block.size;
    +    console.log('Here', minX, minY, x, y, width, height);
    +    if (x - width < minX) {
    +      minX = x - width;
    +    }
    +    if (y - height < minY) {
    +      minY = y - height;
    +    }
    +    if (x > maxX) {
    +      maxX = x;
    +    }
    +    if (y > maxY) {
    +      maxY = y;
    +    }
    +  }
    +  if (block.children) {
    +    for (const child of block.children) {
    +      findBounds(child);
    +    }
    +  }
    +}
    +
    +export function layout(db: BlockDB) {
    +  const blocks = db.getBlocks();
    +  const root = { id: 'root', type: 'composite', children: blocks } as Block;
    +  layoutBLock(root, db);
    +  positionBlock(root, db);
    +
    +  minX = 0;
    +  minY = 0;
    +  maxX = 0;
    +  maxY = 0;
    +  findBounds(root);
    +  const height = maxY - minY;
    +  const width = maxX - minX;
    +  return { x: minX, y: minY, width, height };
    +}
    diff --git a/packages/mermaid/src/diagrams/block/renderHelpers.ts b/packages/mermaid/src/diagrams/block/renderHelpers.ts
    new file mode 100644
    index 0000000000..34d8baa054
    --- /dev/null
    +++ b/packages/mermaid/src/diagrams/block/renderHelpers.ts
    @@ -0,0 +1,270 @@
    +import { getStylesFromArray } from '../../utils.js';
    +import { insertNode } from '../../dagre-wrapper/nodes.js';
    +import { getConfig } from '../../config.js';
    +import { ContainerElement } from 'd3';
    +import type { Block } from './blockTypes.js';
    +import { BlockDB } from './blockDB.js';
    +
    +function getNodeFromBlock(block: Block, db: BlockDB) {
    +  const vertex = block;
    +
    +  /**
    +   * Variable for storing the classes for the vertex
    +   *
    +   * @type {string}
    +   */
    +  let classStr = 'default';
    +  if ((vertex?.classes?.length || []) > 0) {
    +    classStr = vertex.classes.join(' ');
    +  }
    +  classStr = classStr + ' flowchart-label';
    +
    +  // We create a SVG label, either by delegating to addHtmlLabel or manually
    +  let vertexNode;
    +  const labelData = { width: 0, height: 0 };
    +
    +  let radious = 0;
    +  let _shape = '';
    +  let layoutOptions = {};
    +  // Set the shape based parameters
    +  switch (vertex.type) {
    +    case 'round':
    +      radious = 5;
    +      _shape = 'rect';
    +      break;
    +    case 'square':
    +      _shape = 'rect';
    +      break;
    +    case 'diamond':
    +      _shape = 'question';
    +      layoutOptions = {
    +        portConstraints: 'FIXED_SIDE',
    +      };
    +      break;
    +    case 'hexagon':
    +      _shape = 'hexagon';
    +      break;
    +    case 'odd':
    +      _shape = 'rect_left_inv_arrow';
    +      break;
    +    case 'lean_right':
    +      _shape = 'lean_right';
    +      break;
    +    case 'lean_left':
    +      _shape = 'lean_left';
    +      break;
    +    case 'trapezoid':
    +      _shape = 'trapezoid';
    +      break;
    +    case 'inv_trapezoid':
    +      _shape = 'inv_trapezoid';
    +      break;
    +    case 'odd_right':
    +      _shape = 'rect_left_inv_arrow';
    +      break;
    +    case 'circle':
    +      _shape = 'circle';
    +      break;
    +    case 'ellipse':
    +      _shape = 'ellipse';
    +      break;
    +    case 'stadium':
    +      _shape = 'stadium';
    +      break;
    +    case 'subroutine':
    +      _shape = 'subroutine';
    +      break;
    +    case 'cylinder':
    +      _shape = 'cylinder';
    +      break;
    +    case 'group':
    +      _shape = 'rect';
    +      break;
    +    case 'doublecircle':
    +      _shape = 'doublecircle';
    +      break;
    +    default:
    +      _shape = 'rect';
    +  }
    +
    +  // const styles = getStylesFromArray(vertex.styles);
    +  const styles = getStylesFromArray([]);
    +
    +  // Use vertex id as text in the box if no text is provided by the graph definition
    +  const vertexText = vertex.label;
    +
    +  // Add the node
    +  const node = {
    +    labelStyle: styles.labelStyle,
    +    shape: _shape,
    +    labelText: vertexText,
    +    // labelType: vertex.labelType,
    +    rx: radious,
    +    ry: radious,
    +    class: classStr,
    +    style: styles.style,
    +    id: vertex.id,
    +    // link: vertex.link,
    +    // linkTarget: vertex.linkTarget,
    +    // tooltip: diagObj.db.getTooltip(vertex.id) || '',
    +    // domId: diagObj.db.lookUpDomId(vertex.id),
    +    // haveCallback: vertex.haveCallback,
    +    // width: vertex.type === 'group' ? 500 : undefined,
    +    // dir: vertex.dir,
    +    type: vertex.type,
    +    // props: vertex.props,
    +    padding: getConfig()?.flowchart?.padding || 0,
    +  };
    +  return node;
    +}
    +
    +async function calculateBlockSize(elem: any, block: any, db: any) {
    +  console.log('Here befoire 3');
    +  const node = getNodeFromBlock(block, db);
    +  if (node.type === 'group') return;
    +
    +  // Add the element to the DOM to size it
    +  const nodeEl = await insertNode(elem, node);
    +  const boundingBox = nodeEl.node().getBBox();
    +  const obj = db.getBlock(node.id);
    +  console.log('Here el', nodeEl);
    +  obj.size = { width: boundingBox.width, height: boundingBox.height, x: 0, y: 0, node: nodeEl };
    +  db.setBlock(obj);
    +  // nodeEl.remove();
    +}
    +
    +export async function calculateBlockSizes(elem: ContainerElement, blocks: Block[], db: BlockDB) {
    +  console.log('Here before 2');
    +  for (const block of blocks) {
    +    await calculateBlockSize(elem, block, db);
    +    if (block.children) {
    +      await calculateBlockSizes(elem, block.children, db);
    +    }
    +  }
    +}
    +export async function insertBlockPositioned(elem: any, block: any, db: any) {
    +  const vertex = block;
    +
    +  /**
    +   * Variable for storing the classes for the vertex
    +   *
    +   * @type {string}
    +   */
    +  let classStr = 'default';
    +  if ((vertex?.classes?.length || []) > 0) {
    +    classStr = vertex.classes.join(' ');
    +  }
    +  classStr = classStr + ' flowchart-label';
    +
    +  // We create a SVG label, either by delegating to addHtmlLabel or manually
    +  let vertexNode;
    +  const labelData = { width: 0, height: 0 };
    +
    +  let radious = 0;
    +  let _shape = '';
    +  let layoutOptions = {};
    +  // Set the shape based parameters
    +  switch (vertex.type) {
    +    case 'round':
    +      radious = 5;
    +      _shape = 'rect';
    +      break;
    +    case 'square':
    +      _shape = 'rect';
    +      break;
    +    case 'diamond':
    +      _shape = 'question';
    +      layoutOptions = {
    +        portConstraints: 'FIXED_SIDE',
    +      };
    +      break;
    +    case 'hexagon':
    +      _shape = 'hexagon';
    +      break;
    +    case 'odd':
    +      _shape = 'rect_left_inv_arrow';
    +      break;
    +    case 'lean_right':
    +      _shape = 'lean_right';
    +      break;
    +    case 'lean_left':
    +      _shape = 'lean_left';
    +      break;
    +    case 'trapezoid':
    +      _shape = 'trapezoid';
    +      break;
    +    case 'inv_trapezoid':
    +      _shape = 'inv_trapezoid';
    +      break;
    +    case 'odd_right':
    +      _shape = 'rect_left_inv_arrow';
    +      break;
    +    case 'circle':
    +      _shape = 'circle';
    +      break;
    +    case 'ellipse':
    +      _shape = 'ellipse';
    +      break;
    +    case 'stadium':
    +      _shape = 'stadium';
    +      break;
    +    case 'subroutine':
    +      _shape = 'subroutine';
    +      break;
    +    case 'cylinder':
    +      _shape = 'cylinder';
    +      break;
    +    case 'group':
    +      _shape = 'rect';
    +      break;
    +    case 'doublecircle':
    +      _shape = 'doublecircle';
    +      break;
    +    default:
    +      _shape = 'rect';
    +  }
    +
    +  // const styles = getStylesFromArray(vertex.styles);
    +  const styles = getStylesFromArray([]);
    +
    +  // Use vertex id as text in the box if no text is provided by the graph definition
    +  const vertexText = vertex.label;
    +
    +  // Add the node
    +  const node = {
    +    labelStyle: styles.labelStyle,
    +    shape: _shape,
    +    labelText: vertexText,
    +    labelType: vertex.labelType,
    +    rx: radious,
    +    ry: radious,
    +    class: classStr,
    +    style: styles.style,
    +    id: vertex.id,
    +    link: vertex.link,
    +    linkTarget: vertex.linkTarget,
    +    // tooltip: diagObj.db.getTooltip(vertex.id) || '',
    +    // domId: diagObj.db.lookUpDomId(vertex.id),
    +    haveCallback: vertex.haveCallback,
    +    width: vertex.width,
    +    height: vertex.height,
    +    dir: vertex.dir,
    +    type: vertex.type,
    +    props: vertex.props,
    +    padding: getConfig()?.flowchart?.padding || 0,
    +  };
    +  let boundingBox;
    +  let nodeEl;
    +
    +  // Add the element to the DOM
    +  if (node.type !== 'group') {
    +    nodeEl = await insertNode(elem, node, vertex.dir);
    +    // nodeEl.remove();
    +    boundingBox = nodeEl.node().getBBox();
    +    if (node.id) {
    +      const obj = db.getBlock(node.id);
    +      obj.size = { width: boundingBox.width, height: boundingBox.height, x: 0, y: 0, node: nodeEl };
    +      db.setBlock(obj);
    +    }
    +  }
    +}
    diff --git a/packages/mermaid/src/diagrams/block/styles.ts b/packages/mermaid/src/diagrams/block/styles.ts
    new file mode 100644
    index 0000000000..a4af4f1283
    --- /dev/null
    +++ b/packages/mermaid/src/diagrams/block/styles.ts
    @@ -0,0 +1,144 @@
    +// import khroma from 'khroma';
    +import * as khroma from 'khroma';
    +
    +/** Returns the styles given options */
    +export interface FlowChartStyleOptions {
    +  arrowheadColor: string;
    +  border2: string;
    +  clusterBkg: string;
    +  clusterBorder: string;
    +  edgeLabelBackground: string;
    +  fontFamily: string;
    +  lineColor: string;
    +  mainBkg: string;
    +  nodeBorder: string;
    +  nodeTextColor: string;
    +  tertiaryColor: string;
    +  textColor: string;
    +  titleColor: string;
    +}
    +
    +const fade = (color: string, opacity: number) => {
    +  // @ts-ignore TODO: incorrect types from khroma
    +  const channel = khroma.channel;
    +
    +  const r = channel(color, 'r');
    +  const g = channel(color, 'g');
    +  const b = channel(color, 'b');
    +
    +  // @ts-ignore incorrect types from khroma
    +  return khroma.rgba(r, g, b, opacity);
    +};
    +
    +const getStyles = (options: FlowChartStyleOptions) =>
    +  `.label {
    +    font-family: ${options.fontFamily};
    +    color: ${options.nodeTextColor || options.textColor};
    +  }
    +  .cluster-label text {
    +    fill: ${options.titleColor};
    +  }
    +  .cluster-label span,p {
    +    color: ${options.titleColor};
    +  }
    +
    +  .label text,span,p {
    +    fill: ${options.nodeTextColor || options.textColor};
    +    color: ${options.nodeTextColor || options.textColor};
    +  }
    +
    +  .node rect,
    +  .node circle,
    +  .node ellipse,
    +  .node polygon,
    +  .node path {
    +    fill: ${options.mainBkg};
    +    stroke: ${options.nodeBorder};
    +    stroke-width: 1px;
    +  }
    +  .flowchart-label text {
    +    text-anchor: middle;
    +  }
    +  // .flowchart-label .text-outer-tspan {
    +  //   text-anchor: middle;
    +  // }
    +  // .flowchart-label .text-inner-tspan {
    +  //   text-anchor: start;
    +  // }
    +
    +  .node .label {
    +    text-align: center;
    +  }
    +  .node.clickable {
    +    cursor: pointer;
    +  }
    +
    +  .arrowheadPath {
    +    fill: ${options.arrowheadColor};
    +  }
    +
    +  .edgePath .path {
    +    stroke: ${options.lineColor};
    +    stroke-width: 2.0px;
    +  }
    +
    +  .flowchart-link {
    +    stroke: ${options.lineColor};
    +    fill: none;
    +  }
    +
    +  .edgeLabel {
    +    background-color: ${options.edgeLabelBackground};
    +    rect {
    +      opacity: 0.5;
    +      background-color: ${options.edgeLabelBackground};
    +      fill: ${options.edgeLabelBackground};
    +    }
    +    text-align: center;
    +  }
    +
    +  /* For html labels only */
    +  .labelBkg {
    +    background-color: ${fade(options.edgeLabelBackground, 0.5)};
    +    // background-color:
    +  }
    +
    +  .cluster rect {
    +    fill: ${options.clusterBkg};
    +    stroke: ${options.clusterBorder};
    +    stroke-width: 1px;
    +  }
    +
    +  .cluster text {
    +    fill: ${options.titleColor};
    +  }
    +
    +  .cluster span,p {
    +    color: ${options.titleColor};
    +  }
    +  /* .cluster div {
    +    color: ${options.titleColor};
    +  } */
    +
    +  div.mermaidTooltip {
    +    position: absolute;
    +    text-align: center;
    +    max-width: 200px;
    +    padding: 2px;
    +    font-family: ${options.fontFamily};
    +    font-size: 12px;
    +    background: ${options.tertiaryColor};
    +    border: 1px solid ${options.border2};
    +    border-radius: 2px;
    +    pointer-events: none;
    +    z-index: 100;
    +  }
    +
    +  .flowchartTitleText {
    +    text-anchor: middle;
    +    font-size: 18px;
    +    fill: ${options.textColor};
    +  }
    +`;
    +
    +export default getStyles;
    diff --git a/packages/mermaid/src/diagrams/flowchart/swimlane/swimlaneRenderer.js b/packages/mermaid/src/diagrams/flowchart/swimlane/swimlaneRenderer.js
    new file mode 100644
    index 0000000000..5b7d5976f1
    --- /dev/null
    +++ b/packages/mermaid/src/diagrams/flowchart/swimlane/swimlaneRenderer.js
    @@ -0,0 +1,400 @@
    +import * as graphlib from 'dagre-d3-es/src/graphlib/index.js';
    +import { select, curveLinear, selectAll } from 'd3';
    +import { swimlaneLayout } from './swimlane-layout.js';
    +import { insertNode } from '../../../dagre-wrapper/nodes.js';
    +import flowDb from '../flowDb.js';
    +import { getConfig } from '../../../config.js';
    +import { getStylesFromArray } from '../../../utils.js';
    +import setupGraph, { addEdges, addVertices } from './setup-graph.js';
    +import { render } from '../../../dagre-wrapper/index.js';
    +import { log } from '../../../logger.js';
    +import { setupGraphViewbox } from '../../../setupGraphViewbox.js';
    +import common, { evaluate } from '../../common/common.js';
    +import { addHtmlLabel } from 'dagre-d3-es/src/dagre-js/label/add-html-label.js';
    +import { insertEdge, positionEdgeLabel } from '../../../dagre-wrapper/edges.js';
    +import {
    +  clear as clearGraphlib,
    +  clusterDb,
    +  adjustClustersAndEdges,
    +  findNonClusterChild,
    +  sortNodesByHierarchy,
    +} from '../../../dagre-wrapper/mermaid-graphlib.js';
    +
    +const conf = {};
    +export const setConf = function (cnf) {
    +  const keys = Object.keys(cnf);
    +  for (const key of keys) {
    +    conf[key] = cnf[key];
    +  }
    +};
    +
    +/**
    + *
    + * @param element
    + * @param graph
    + * @param layout
    + * @param elem
    + * @param conf
    + */
    +async function swimlaneRender(layout, vert, elem, g, id, conf) {
    +  let max;
    +  // draw nodes from layout.graph to element
    +  const nodes = layout.graph.nodes();
    +
    +  // lanes are the swimlanes
    +  const lanes = layout.lanes;
    +
    +  const nodesElements = elem.insert('g').attr('class', 'nodes');
    +  // for each node, draw a rect, with a child text inside as label
    +  for (const node of nodes) {
    +    const nodeFromLayout = layout.graph.node(node);
    +    const vertex = vert[node];
    +    //Initialise the node
    +    /**
    +     * Variable for storing the classes for the vertex
    +     *
    +     * @type {string}
    +     */
    +    let classStr = 'default';
    +    if (vertex.classes.length > 0) {
    +      classStr = vertex.classes.join(' ');
    +    }
    +    classStr = classStr + ' swimlane-label';
    +    const styles = getStylesFromArray(vertex.styles);
    +
    +    // Use vertex id as text in the box if no text is provided by the graph definition
    +    let vertexText = vertex.text !== undefined ? vertex.text : vertex.id;
    +
    +    // We create a SVG label, either by delegating to addHtmlLabel or manually
    +    let vertexNode;
    +    log.info('vertex', vertex, vertex.labelType);
    +    if (vertex.labelType === 'markdown') {
    +      log.info('vertex', vertex, vertex.labelType);
    +    } else {
    +      if (evaluate(getConfig().flowchart.htmlLabels)) {
    +        // TODO: addHtmlLabel accepts a labelStyle. Do we possibly have that?
    +        const node = {
    +          label: vertexText.replace(
    +            /fa[blrs]?:fa-[\w-]+/g,
    +            (s) => ``
    +          ),
    +        };
    +        vertexNode = addHtmlLabel(elem, node).node();
    +        vertexNode.parentNode.removeChild(vertexNode);
    +      } else {
    +        const svgLabel = doc.createElementNS('http://www.w3.org/2000/svg', 'text');
    +        svgLabel.setAttribute('style', styles.labelStyle.replace('color:', 'fill:'));
    +
    +        const rows = vertexText.split(common.lineBreakRegex);
    +
    +        for (const row of rows) {
    +          const tspan = doc.createElementNS('http://www.w3.org/2000/svg', 'tspan');
    +          tspan.setAttributeNS('http://www.w3.org/XML/1998/namespace', 'xml:space', 'preserve');
    +          tspan.setAttribute('dy', '1em');
    +          tspan.setAttribute('x', '1');
    +          tspan.textContent = row;
    +          svgLabel.appendChild(tspan);
    +        }
    +        vertexNode = svgLabel;
    +      }
    +    }
    +
    +    let radious = 0;
    +    let _shape = '';
    +    // Set the shape based parameters
    +    switch (vertex.type) {
    +      case 'round':
    +        radious = 5;
    +        _shape = 'rect';
    +        break;
    +      case 'square':
    +        _shape = 'rect';
    +        break;
    +      case 'diamond':
    +        _shape = 'question';
    +        break;
    +      case 'hexagon':
    +        _shape = 'hexagon';
    +        break;
    +      case 'odd':
    +        _shape = 'rect_left_inv_arrow';
    +        break;
    +      case 'lean_right':
    +        _shape = 'lean_right';
    +        break;
    +      case 'lean_left':
    +        _shape = 'lean_left';
    +        break;
    +      case 'trapezoid':
    +        _shape = 'trapezoid';
    +        break;
    +      case 'inv_trapezoid':
    +        _shape = 'inv_trapezoid';
    +        break;
    +      case 'odd_right':
    +        _shape = 'rect_left_inv_arrow';
    +        break;
    +      case 'circle':
    +        _shape = 'circle';
    +        break;
    +      case 'ellipse':
    +        _shape = 'ellipse';
    +        break;
    +      case 'stadium':
    +        _shape = 'stadium';
    +        break;
    +      case 'subroutine':
    +        _shape = 'subroutine';
    +        break;
    +      case 'cylinder':
    +        _shape = 'cylinder';
    +        break;
    +      case 'group':
    +        _shape = 'rect';
    +        break;
    +      case 'doublecircle':
    +        _shape = 'doublecircle';
    +        break;
    +      default:
    +        _shape = 'rect';
    +    }
    +    // Add the node
    +    let nodeObj = {
    +      labelStyle: styles.labelStyle,
    +      shape: _shape,
    +      labelText: vertexText,
    +      labelType: vertex.labelType,
    +      rx: radious,
    +      ry: radious,
    +      class: classStr,
    +      style: styles.style,
    +      id: vertex.id,
    +      link: vertex.link,
    +      linkTarget: vertex.linkTarget,
    +      // tooltip: diagObj.db.getTooltip(vertex.id) || '',
    +      // domId: diagObj.db.lookUpDomId(vertex.id),
    +      haveCallback: vertex.haveCallback,
    +      width: vertex.type === 'group' ? 500 : undefined,
    +      dir: vertex.dir,
    +      type: vertex.type,
    +      props: vertex.props,
    +      padding: getConfig().flowchart.padding,
    +      x: nodeFromLayout.x,
    +      y: nodeFromLayout.y,
    +    };
    +
    +    let boundingBox;
    +    let nodeEl;
    +
    +    // Add the element to the DOM
    +
    +    nodeEl = await insertNode(nodesElements, nodeObj, vertex.dir);
    +    boundingBox = nodeEl.node().getBBox();
    +    nodeEl.attr('transform', `translate(${nodeObj.x}, ${nodeObj.y / 2})`);
    +  }
    +
    +  return elem;
    +}
    +
    +/**
    + * Returns the all the styles from classDef statements in the graph definition.
    + *
    + * @param text
    + * @param diagObj
    + * @returns {object} ClassDef styles
    + */
    +export const getClasses = function (text, diagObj) {
    +  log.info('Extracting classes');
    +  diagObj.db.clear();
    +  try {
    +    // Parse the graph definition
    +    diagObj.parse(text);
    +    return diagObj.db.getClasses();
    +  } catch (e) {
    +    return;
    +  }
    +};
    +
    +/**
    + * Draws a flowchart in the tag with id: id based on the graph definition in text.
    + *
    + * @param text
    + * @param id
    + */
    +
    +export const draw = async function (text, id, _version, diagObj) {
    +  log.info('Drawing flowchart');
    +  diagObj.db.clear();
    +  flowDb.setGen('gen-2');
    +  // Parse the graph definition
    +  diagObj.parser.parse(text);
    +
    +  const { securityLevel, flowchart: conf } = getConfig();
    +
    +  // Handle root and document for when rendering in sandbox mode
    +  let sandboxElement;
    +  if (securityLevel === 'sandbox') {
    +    sandboxElement = select('#i' + id);
    +  }
    +  const root =
    +    securityLevel === 'sandbox'
    +      ? select(sandboxElement.nodes()[0].contentDocument.body)
    +      : select('body');
    +  const doc = securityLevel === 'sandbox' ? sandboxElement.nodes()[0].contentDocument : document;
    +
    +  // create g as a graphlib graph using setupGraph from setup-graph.js
    +  const g = setupGraph(diagObj, id, root, doc);
    +
    +  let subG;
    +  const subGraphs = diagObj.db.getSubGraphs();
    +  log.info('Subgraphs - ', subGraphs);
    +  for (let i = subGraphs.length - 1; i >= 0; i--) {
    +    subG = subGraphs[i];
    +    log.info('Subgraph - ', subG);
    +    diagObj.db.addVertex(
    +      subG.id,
    +      { text: subG.title, type: subG.labelType },
    +      'group',
    +      undefined,
    +      subG.classes,
    +      subG.dir
    +    );
    +  }
    +
    +  // Fetch the vertices/nodes and edges/links from the parsed graph definition
    +  const vert = diagObj.db.getVertices();
    +
    +  const edges = diagObj.db.getEdges();
    +
    +  log.info('Edges', edges);
    +
    +  const svg = root.select('#' + id);
    +
    +  svg.append('g');
    +
    +  // Run the renderer. This is what draws the final graph.
    +  // const element = root.select('#' + id + ' g');
    +  console.log('diagObj', diagObj);
    +  console.log('subGraphs', diagObj.db.getSubGraphs());
    +  const layout = swimlaneLayout(g, diagObj);
    +  console.log('custom layout', layout);
    +
    +  // draw lanes as vertical lines
    +  const lanesElements = svg.insert('g').attr('class', 'lanes');
    +
    +  let laneCount = 0;
    +
    +  for (const lane of layout.lanes) {
    +    laneCount++;
    +
    +    //draw lane header as rectangle with lane title centered in it
    +    const laneHeader = document.createElementNS('http://www.w3.org/2000/svg', 'rect');
    +
    +    // Set attributes for the rectangle
    +    laneHeader.setAttribute('x', lane.x); // x-coordinate of the top-left corner
    +    laneHeader.setAttribute('y', -50); // y-coordinate of the top-left corner
    +    laneHeader.setAttribute('width', lane.width); // width of the rectangle
    +    laneHeader.setAttribute('height', '50'); // height of the rectangle
    +    if (laneCount % 2 == 0) {
    +      //set light blue color for even lanes
    +      laneHeader.setAttribute('fill', 'blue'); // fill color of the rectangle
    +    } else {
    +      //set white color odd lanes
    +      laneHeader.setAttribute('fill', 'grey'); // fill color of the rectangle
    +    }
    +
    +    laneHeader.setAttribute('stroke', 'black'); // color of the stroke/border
    +    laneHeader.setAttribute('stroke-width', '2'); // width of the stroke/border
    +
    +    // Append the rectangle to the SVG element
    +    lanesElements.node().appendChild(laneHeader);
    +
    +    //draw lane title
    +    const laneTitle = document.createElementNS('http://www.w3.org/2000/svg', 'text');
    +
    +    // Set attributes for the rectangle
    +    laneTitle.setAttribute('x', lane.x + lane.width / 2); // x-coordinate of the top-left corner
    +    laneTitle.setAttribute('y', -50 + 50 / 2); // y-coordinate of the top-left corner
    +    laneTitle.setAttribute('width', lane.width); // width of the rectangle
    +    laneTitle.setAttribute('height', '50'); // height of the rectangle
    +    laneTitle.setAttribute('fill', 'white'); // fill color of the rectangle
    +    laneTitle.setAttribute('stroke-width', '1'); // width of the stroke/border
    +    laneTitle.setAttribute('text-anchor', 'middle'); // width of the stroke/border
    +    laneTitle.setAttribute('alignment-baseline', 'middle'); // width of the stroke/border
    +    laneTitle.setAttribute('font-size', '20'); // width of the stroke/border
    +    laneTitle.textContent = lane.title;
    +
    +    // Append the rectangle to the SVG element
    +    lanesElements.node().appendChild(laneTitle);
    +
    +    //draw lane
    +
    +    // Create a  element
    +    const rectangle = document.createElementNS('http://www.w3.org/2000/svg', 'rect');
    +
    +    // Set attributes for the rectangle
    +    rectangle.setAttribute('x', lane.x); // x-coordinate of the top-left corner
    +    rectangle.setAttribute('y', 0); // y-coordinate of the top-left corner
    +    rectangle.setAttribute('width', lane.width); // width of the rectangle
    +    rectangle.setAttribute('height', '500'); // height of the rectangle
    +
    +    if (laneCount % 2 == 0) {
    +      //set light blue color for even lanes
    +      rectangle.setAttribute('fill', 'lightblue'); // fill color of the rectangle
    +    } else {
    +      //set white color odd lanes
    +      rectangle.setAttribute('fill', '#ffffff'); // fill color of the rectangle
    +    }
    +
    +    rectangle.setAttribute('stroke', 'black'); // color of the stroke/border
    +    rectangle.setAttribute('stroke-width', '2'); // width of the stroke/border
    +
    +    // Append the rectangle to the SVG element
    +    lanesElements.node().appendChild(rectangle);
    +  }
    +
    +  // append lanesElements to elem
    +  svg.node().appendChild(lanesElements.node());
    +
    +  // add lane headers
    +  const laneHeaders = svg.insert('g').attr('class', 'laneHeaders');
    +
    +  addEdges(edges, g, diagObj);
    +
    +  g.edges().forEach(function (e) {
    +    const edge = g.edge(e);
    +    log.info('Edge ' + e.v + ' -> ' + e.w + ': ' + JSON.stringify(edge), edge);
    +    const edgePaths = svg.insert('g').attr('class', 'edgePaths');
    +    //create edge points based on start and end node
    +
    +    //get start node x, y coordinates
    +    const sourceNode = layout.graph.node(e.v);
    +    //get end node x, y coordinates
    +    sourceNode.x = sourceNode.x;
    +    sourceNode.y = sourceNode.y;
    +
    +    const targetNode = layout.graph.node(e.w);
    +    targetNode.x = targetNode.x;
    +    targetNode.y = targetNode.y;
    +
    +    edge.points = [];
    +    edge.points.push({ x: sourceNode.x, y: sourceNode.y / 2 });
    +    edge.points.push({ x: targetNode.x, y: targetNode.y / 2 });
    +
    +    const paths = insertEdge(edgePaths, e, edge, clusterDb, 'flowchart', g);
    +    //positionEdgeLabel(edge, paths);
    +  });
    +  await swimlaneRender(layout, vert, svg, g, id, conf);
    +
    +  // utils.insertTitle(svg, 'flowchartTitleText', conf.titleTopMargin, diagObj.db.getDiagramTitle());
    +
    +  setupGraphViewbox(g, svg, conf.diagramPadding, conf.useMaxWidth);
    +};
    +
    +export default {
    +  setConf,
    +  addVertices,
    +  addEdges,
    +  getClasses,
    +  draw,
    +};
    
    From ccdb8035012b221317d3804c54f3354c0517989d Mon Sep 17 00:00:00 2001
    From: Knut Sveidqvist 
    Date: Tue, 5 Sep 2023 15:15:08 +0200
    Subject: [PATCH 015/217] Rendering, interim
    
    ---
     packages/mermaid/src/dagre-wrapper/nodes.js   |  28 +--
     .../mermaid/src/dagre-wrapper/shapes/util.js  |   3 +
     .../mermaid/src/diagrams/block/blockDB.ts     |   3 -
     .../src/diagrams/block/blockRenderer.ts       |   7 +-
     packages/mermaid/src/diagrams/block/layout.ts |   5 -
     .../src/diagrams/block/renderHelpers.ts       | 167 ++++--------------
     6 files changed, 57 insertions(+), 156 deletions(-)
    
    diff --git a/packages/mermaid/src/dagre-wrapper/nodes.js b/packages/mermaid/src/dagre-wrapper/nodes.js
    index e6a9d982a2..e9324171b9 100644
    --- a/packages/mermaid/src/dagre-wrapper/nodes.js
    +++ b/packages/mermaid/src/dagre-wrapper/nodes.js
    @@ -323,8 +323,12 @@ const rect = async (parent, node) => {
     
       // const totalWidth = bbox.width + node.padding * 2;
       // const totalHeight = bbox.height + node.padding * 2;
    -  const totalWidth = bbox.width + node.padding;
    -  const totalHeight = bbox.height + node.padding;
    +  const totalWidth = node.positioned ? node.width : bbox.width + node.padding;
    +  const totalHeight = node.positioned ? node.height : bbox.height + node.padding;
    +  const x = node.positioned ? node.x - node.width / 2 - halfPadding : -bbox.width / 2 - halfPadding;
    +  const y = node.positioned
    +    ? node.y - node.height / 2 - halfPadding
    +    : -bbox.height / 2 - halfPadding;
       rect
         .attr('class', 'basic label-container')
         .attr('style', node.style)
    @@ -332,8 +336,8 @@ const rect = async (parent, node) => {
         .attr('ry', node.ry)
         // .attr('x', -bbox.width / 2 - node.padding)
         // .attr('y', -bbox.height / 2 - node.padding)
    -    .attr('x', -bbox.width / 2 - halfPadding)
    -    .attr('y', -bbox.height / 2 - halfPadding)
    +    .attr('x', x)
    +    .attr('y', y)
         .attr('width', totalWidth)
         .attr('height', totalHeight);
     
    @@ -1037,14 +1041,14 @@ export const positionNode = (node) => {
       const padding = 8;
       const diff = node.diff || 0;
       if (node.clusterNode) {
    -      el.attr(
    -        'transform',
    -        'translate(' +
    -          (node.x + diff - node.width / 2) +
    -          ', ' +
    -          (node.y - node.height / 2 - padding) +
    -          ')'
    -      );
    +    el.attr(
    +      'transform',
    +      'translate(' +
    +        (node.x + diff - node.width / 2) +
    +        ', ' +
    +        (node.y - node.height / 2 - padding) +
    +        ')'
    +    );
       } else {
         el.attr('transform', 'translate(' + node.x + ', ' + node.y + ')');
       }
    diff --git a/packages/mermaid/src/dagre-wrapper/shapes/util.js b/packages/mermaid/src/dagre-wrapper/shapes/util.js
    index 3eaedb4b9f..2230547fff 100644
    --- a/packages/mermaid/src/dagre-wrapper/shapes/util.js
    +++ b/packages/mermaid/src/dagre-wrapper/shapes/util.js
    @@ -113,6 +113,9 @@ export const labelHelper = async (parent, node, _classes, isNode) => {
         label.attr('transform', 'translate(' + -bbox.width / 2 + ', ' + -bbox.height / 2 + ')');
       }
       label.insert('rect', ':first-child');
    +  // if (node.positioned) {
    +  //   shapeSvg.attr('transform', 'translate(' + node.x + ', ' + node.y + ')');
    +  // }
       return { shapeSvg, bbox, halfPadding, label };
     };
     
    diff --git a/packages/mermaid/src/diagrams/block/blockDB.ts b/packages/mermaid/src/diagrams/block/blockDB.ts
    index 039353830e..84c6536050 100644
    --- a/packages/mermaid/src/diagrams/block/blockDB.ts
    +++ b/packages/mermaid/src/diagrams/block/blockDB.ts
    @@ -103,17 +103,14 @@ const getColumns = (blockid: string): number => {
     
     type IGetBlocks = () => Block[];
     const getBlocks: IGetBlocks = () => {
    -  log.info('Block in test', blocks, blocks[0].id);
       return blocks || [];
     };
     type IGetBlock = (id: string) => Block | undefined;
     const getBlock: IGetBlock = (id: string) => {
    -  log.info('Block in test', blocks, blocks[0].id);
       return blockDatabase[id];
     };
     type ISetBlock = (block: Block) => void;
     const setBlock: ISetBlock = (block: Block) => {
    -  log.info('Block in test', blocks, blocks[0].id);
       blockDatabase[block.id] = block;
     };
     
    diff --git a/packages/mermaid/src/diagrams/block/blockRenderer.ts b/packages/mermaid/src/diagrams/block/blockRenderer.ts
    index 0dac714d42..932537786b 100644
    --- a/packages/mermaid/src/diagrams/block/blockRenderer.ts
    +++ b/packages/mermaid/src/diagrams/block/blockRenderer.ts
    @@ -1,6 +1,6 @@
     import { Diagram } from '../../Diagram.js';
     import * as configApi from '../../config.js';
    -import { calculateBlockSizes } from './renderHelpers.js';
    +import { calculateBlockSizes, insertBlocks } from './renderHelpers.js';
     import { layout } from './layout.js';
     import { setupGraphViewbox } from '../../setupGraphViewbox.js';
     import {
    @@ -42,14 +42,15 @@ export const draw = async function (
       const nodes = svg.insert('g').attr('class', 'block');
       await calculateBlockSizes(nodes, bl, db);
       const bounds = layout(db);
    +  await insertBlocks(nodes, bl, db);
     
       console.log('Here', bl);
     
       // Establish svg dimensions and get width and height
       //
       // const bounds = nodes.node().getBoundingClientRect();
    -  const height = bounds.height;
    -  const width = bounds.width;
    +  const height = bounds.height + 600;
    +  const width = bounds.width + 699;
       const useMaxWidth = false;
       configureSvgSize(svg, height, width, useMaxWidth);
       console.log('Here Bounds', bounds);
    diff --git a/packages/mermaid/src/diagrams/block/layout.ts b/packages/mermaid/src/diagrams/block/layout.ts
    index 65b99c1543..2d61002295 100644
    --- a/packages/mermaid/src/diagrams/block/layout.ts
    +++ b/packages/mermaid/src/diagrams/block/layout.ts
    @@ -42,13 +42,9 @@ function layoutBLock(block: Block, db: BlockDB) {
     }
     
     function positionBlock(block: Block, db: BlockDB) {
    -  console.log('Here Positioning', block?.size?.node);
    -  // const o = db.getBlock(block.id);
    -  // const node;
       if (block?.size?.node) {
         const node = block?.size?.node;
         const size = block?.size;
    -    console.log('Here as well', node);
         if (node) {
           node.attr(
             'transform',
    @@ -70,7 +66,6 @@ let maxY = 0;
     function findBounds(block: Block) {
       if (block.size) {
         const { x, y, width, height } = block.size;
    -    console.log('Here', minX, minY, x, y, width, height);
         if (x - width < minX) {
           minX = x - width;
         }
    diff --git a/packages/mermaid/src/diagrams/block/renderHelpers.ts b/packages/mermaid/src/diagrams/block/renderHelpers.ts
    index 34d8baa054..1b29b45363 100644
    --- a/packages/mermaid/src/diagrams/block/renderHelpers.ts
    +++ b/packages/mermaid/src/diagrams/block/renderHelpers.ts
    @@ -5,7 +5,7 @@ import { ContainerElement } from 'd3';
     import type { Block } from './blockTypes.js';
     import { BlockDB } from './blockDB.js';
     
    -function getNodeFromBlock(block: Block, db: BlockDB) {
    +function getNodeFromBlock(block: Block, db: BlockDB, positioned: boolean = false) {
       const vertex = block;
     
       /**
    @@ -93,6 +93,7 @@ function getNodeFromBlock(block: Block, db: BlockDB) {
       // Use vertex id as text in the box if no text is provided by the graph definition
       const vertexText = vertex.label;
     
    +  const bounds = vertex.size || { width: 0, height: 0, x: 0, y: 0 };
       // Add the node
       const node = {
         labelStyle: styles.labelStyle,
    @@ -111,160 +112,60 @@ function getNodeFromBlock(block: Block, db: BlockDB) {
         // haveCallback: vertex.haveCallback,
         // width: vertex.type === 'group' ? 500 : undefined,
         // dir: vertex.dir,
    +    width: bounds.width,
    +    height: bounds.height,
    +    x: bounds.x,
    +    y: bounds.y,
    +    positioned,
         type: vertex.type,
         // props: vertex.props,
         padding: getConfig()?.flowchart?.padding || 0,
       };
       return node;
     }
    -
    +type IOperation = (elem: any, block: any, db: any) => Promise;
     async function calculateBlockSize(elem: any, block: any, db: any) {
    -  console.log('Here befoire 3');
    -  const node = getNodeFromBlock(block, db);
    +  const node = getNodeFromBlock(block, db, false);
       if (node.type === 'group') return;
     
       // Add the element to the DOM to size it
       const nodeEl = await insertNode(elem, node);
       const boundingBox = nodeEl.node().getBBox();
       const obj = db.getBlock(node.id);
    -  console.log('Here el', nodeEl);
       obj.size = { width: boundingBox.width, height: boundingBox.height, x: 0, y: 0, node: nodeEl };
    +  console.log('Here boundsíng', boundingBox.width);
       db.setBlock(obj);
    -  // nodeEl.remove();
    +  nodeEl.remove();
     }
     
    -export async function calculateBlockSizes(elem: ContainerElement, blocks: Block[], db: BlockDB) {
    -  console.log('Here before 2');
    +export async function insertBlockPositioned(elem: any, block: any, db: any) {
    +  console.log('Here insertBlockPositioned');
    +  const node = getNodeFromBlock(block, db, true);
    +  if (node.type === 'group') return;
    +
    +  // Add the element to the DOM to size it
    +  const obj = db.getBlock(node.id);
    +  const nodeEl = await insertNode(elem, node);
    +}
    +
    +export async function performOperations(
    +  elem: ContainerElement,
    +  blocks: Block[],
    +  db: BlockDB,
    +  operation: IOperation
    +) {
       for (const block of blocks) {
    -    await calculateBlockSize(elem, block, db);
    +    await operation(elem, block, db);
         if (block.children) {
    -      await calculateBlockSizes(elem, block.children, db);
    +      await performOperations(elem, block.children, db, operation);
         }
       }
     }
    -export async function insertBlockPositioned(elem: any, block: any, db: any) {
    -  const vertex = block;
    -
    -  /**
    -   * Variable for storing the classes for the vertex
    -   *
    -   * @type {string}
    -   */
    -  let classStr = 'default';
    -  if ((vertex?.classes?.length || []) > 0) {
    -    classStr = vertex.classes.join(' ');
    -  }
    -  classStr = classStr + ' flowchart-label';
    -
    -  // We create a SVG label, either by delegating to addHtmlLabel or manually
    -  let vertexNode;
    -  const labelData = { width: 0, height: 0 };
    -
    -  let radious = 0;
    -  let _shape = '';
    -  let layoutOptions = {};
    -  // Set the shape based parameters
    -  switch (vertex.type) {
    -    case 'round':
    -      radious = 5;
    -      _shape = 'rect';
    -      break;
    -    case 'square':
    -      _shape = 'rect';
    -      break;
    -    case 'diamond':
    -      _shape = 'question';
    -      layoutOptions = {
    -        portConstraints: 'FIXED_SIDE',
    -      };
    -      break;
    -    case 'hexagon':
    -      _shape = 'hexagon';
    -      break;
    -    case 'odd':
    -      _shape = 'rect_left_inv_arrow';
    -      break;
    -    case 'lean_right':
    -      _shape = 'lean_right';
    -      break;
    -    case 'lean_left':
    -      _shape = 'lean_left';
    -      break;
    -    case 'trapezoid':
    -      _shape = 'trapezoid';
    -      break;
    -    case 'inv_trapezoid':
    -      _shape = 'inv_trapezoid';
    -      break;
    -    case 'odd_right':
    -      _shape = 'rect_left_inv_arrow';
    -      break;
    -    case 'circle':
    -      _shape = 'circle';
    -      break;
    -    case 'ellipse':
    -      _shape = 'ellipse';
    -      break;
    -    case 'stadium':
    -      _shape = 'stadium';
    -      break;
    -    case 'subroutine':
    -      _shape = 'subroutine';
    -      break;
    -    case 'cylinder':
    -      _shape = 'cylinder';
    -      break;
    -    case 'group':
    -      _shape = 'rect';
    -      break;
    -    case 'doublecircle':
    -      _shape = 'doublecircle';
    -      break;
    -    default:
    -      _shape = 'rect';
    -  }
     
    -  // const styles = getStylesFromArray(vertex.styles);
    -  const styles = getStylesFromArray([]);
    -
    -  // Use vertex id as text in the box if no text is provided by the graph definition
    -  const vertexText = vertex.label;
    -
    -  // Add the node
    -  const node = {
    -    labelStyle: styles.labelStyle,
    -    shape: _shape,
    -    labelText: vertexText,
    -    labelType: vertex.labelType,
    -    rx: radious,
    -    ry: radious,
    -    class: classStr,
    -    style: styles.style,
    -    id: vertex.id,
    -    link: vertex.link,
    -    linkTarget: vertex.linkTarget,
    -    // tooltip: diagObj.db.getTooltip(vertex.id) || '',
    -    // domId: diagObj.db.lookUpDomId(vertex.id),
    -    haveCallback: vertex.haveCallback,
    -    width: vertex.width,
    -    height: vertex.height,
    -    dir: vertex.dir,
    -    type: vertex.type,
    -    props: vertex.props,
    -    padding: getConfig()?.flowchart?.padding || 0,
    -  };
    -  let boundingBox;
    -  let nodeEl;
    +export async function calculateBlockSizes(elem: ContainerElement, blocks: Block[], db: BlockDB) {
    +  await performOperations(elem, blocks, db, calculateBlockSize);
    +}
     
    -  // Add the element to the DOM
    -  if (node.type !== 'group') {
    -    nodeEl = await insertNode(elem, node, vertex.dir);
    -    // nodeEl.remove();
    -    boundingBox = nodeEl.node().getBBox();
    -    if (node.id) {
    -      const obj = db.getBlock(node.id);
    -      obj.size = { width: boundingBox.width, height: boundingBox.height, x: 0, y: 0, node: nodeEl };
    -      db.setBlock(obj);
    -    }
    -  }
    +export async function insertBlocks(elem: ContainerElement, blocks: Block[], db: BlockDB) {
    +  await performOperations(elem, blocks, db, insertBlockPositioned);
     }
    
    From 836d3a87beb2b585fad9ac6e5b90f835fb876222 Mon Sep 17 00:00:00 2001
    From: Knut Sveidqvist 
    Date: Thu, 14 Sep 2023 10:11:43 +0200
    Subject: [PATCH 016/217] WIP
    
    ---
     cypress/platform/knsv2.html                   | 12 ++-
     packages/mermaid/src/dagre-wrapper/nodes.js   | 98 +++++++++----------
     .../src/diagrams/block/blockRenderer.ts       | 22 +++--
     packages/mermaid/src/diagrams/block/layout.ts | 19 ++--
     .../src/diagrams/block/renderHelpers.ts       |  3 +-
     5 files changed, 84 insertions(+), 70 deletions(-)
    
    diff --git a/cypress/platform/knsv2.html b/cypress/platform/knsv2.html
    index 4609331dd5..36afc1d035 100644
    --- a/cypress/platform/knsv2.html
    +++ b/cypress/platform/knsv2.html
    @@ -26,6 +26,8 @@
           }
           .mermaid {
             border: 1px solid #ddd;
    +        margin: 10px;
    +        background: pink;
           }
           .mermaid2 {
             display: none;
    @@ -38,6 +40,7 @@
             background-size: 20px 20px;
             background-position: 0 0, 10px 10px;
             background-repeat: repeat;
    +        border: 1px solid red;
           }
           .malware {
             position: fixed;
    @@ -62,10 +65,13 @@
       
         
     block-beta
    -  id1("Wide 1")
    +  %% id1("Wide 1")
       id2("2")
    -  id3("3")
    -  id4("A final one")
    +  block
    +      id3
    +      id4
    +  end
    +  %% id4("A final one")
     
         
    diff --git a/packages/mermaid/src/dagre-wrapper/nodes.js b/packages/mermaid/src/dagre-wrapper/nodes.js
    index e9324171b9..9e57fb2b0c 100644
    --- a/packages/mermaid/src/dagre-wrapper/nodes.js
    +++ b/packages/mermaid/src/dagre-wrapper/nodes.js
    @@ -27,7 +27,7 @@ const question = async (parent, node) => {
       questionElem.attr('style', node.style);
       updateNodeBounds(node, questionElem);
     
    -  node.intersect = function (point) {
    +  node.intersect = function(point) {
         log.warn('Intersect called');
         return intersect.polygon(node, points, point);
       };
    @@ -52,7 +52,7 @@ const choice = (parent, node) => {
       const choice = shapeSvg.insert('polygon', ':first-child').attr(
         'points',
         points
    -      .map(function (d) {
    +      .map(function(d) {
             return d.x + ',' + d.y;
           })
           .join(' ')
    @@ -62,7 +62,7 @@ const choice = (parent, node) => {
       node.width = 28;
       node.height = 28;
     
    -  node.intersect = function (point) {
    +  node.intersect = function(point) {
         return intersect.circle(node, 14, point);
       };
     
    @@ -89,7 +89,7 @@ const hexagon = async (parent, node) => {
       hex.attr('style', node.style);
       updateNodeBounds(node, hex);
     
    -  node.intersect = function (point) {
    +  node.intersect = function(point) {
         return intersect.polygon(node, points, point);
       };
     
    @@ -115,7 +115,7 @@ const rect_left_inv_arrow = async (parent, node) => {
       node.width = w + h;
       node.height = h;
     
    -  node.intersect = function (point) {
    +  node.intersect = function(point) {
         return intersect.polygon(node, points, point);
       };
     
    @@ -138,7 +138,7 @@ const lean_right = async (parent, node) => {
       el.attr('style', node.style);
       updateNodeBounds(node, el);
     
    -  node.intersect = function (point) {
    +  node.intersect = function(point) {
         return intersect.polygon(node, points, point);
       };
     
    @@ -161,7 +161,7 @@ const lean_left = async (parent, node) => {
       el.attr('style', node.style);
       updateNodeBounds(node, el);
     
    -  node.intersect = function (point) {
    +  node.intersect = function(point) {
         return intersect.polygon(node, points, point);
       };
     
    @@ -184,7 +184,7 @@ const trapezoid = async (parent, node) => {
       el.attr('style', node.style);
       updateNodeBounds(node, el);
     
    -  node.intersect = function (point) {
    +  node.intersect = function(point) {
         return intersect.polygon(node, points, point);
       };
     
    @@ -207,7 +207,7 @@ const inv_trapezoid = async (parent, node) => {
       el.attr('style', node.style);
       updateNodeBounds(node, el);
     
    -  node.intersect = function (point) {
    +  node.intersect = function(point) {
         return intersect.polygon(node, points, point);
       };
     
    @@ -231,7 +231,7 @@ const rect_right_inv_arrow = async (parent, node) => {
       el.attr('style', node.style);
       updateNodeBounds(node, el);
     
    -  node.intersect = function (point) {
    +  node.intersect = function(point) {
         return intersect.polygon(node, points, point);
       };
     
    @@ -281,7 +281,7 @@ const cylinder = async (parent, node) => {
     
       updateNodeBounds(node, el);
     
    -  node.intersect = function (point) {
    +  node.intersect = function(point) {
         const pos = intersect.rect(node, point);
         const x = pos.x - node.x;
     
    @@ -325,17 +325,13 @@ const rect = async (parent, node) => {
       // const totalHeight = bbox.height + node.padding * 2;
       const totalWidth = node.positioned ? node.width : bbox.width + node.padding;
       const totalHeight = node.positioned ? node.height : bbox.height + node.padding;
    -  const x = node.positioned ? node.x - node.width / 2 - halfPadding : -bbox.width / 2 - halfPadding;
    -  const y = node.positioned
    -    ? node.y - node.height / 2 - halfPadding
    -    : -bbox.height / 2 - halfPadding;
    +  const x = node.positioned ? -totalWidth / 2 : -bbox.width / 2 - halfPadding;
    +  const y = node.positioned ? -totalHeight / 2 : -bbox.height / 2 - halfPadding;
       rect
         .attr('class', 'basic label-container')
         .attr('style', node.style)
         .attr('rx', node.rx)
         .attr('ry', node.ry)
    -    // .attr('x', -bbox.width / 2 - node.padding)
    -    // .attr('y', -bbox.height / 2 - node.padding)
         .attr('x', x)
         .attr('y', y)
         .attr('width', totalWidth)
    @@ -354,7 +350,7 @@ const rect = async (parent, node) => {
     
       updateNodeBounds(node, rect);
     
    -  node.intersect = function (point) {
    +  node.intersect = function(point) {
         return intersect.rect(node, point);
       };
     
    @@ -387,7 +383,7 @@ const labelRect = async (parent, node) => {
     
       updateNodeBounds(node, rect);
     
    -  node.intersect = function (point) {
    +  node.intersect = function(point) {
         return intersect.rect(node, point);
       };
     
    @@ -499,20 +495,20 @@ const rectWithTitle = (parent, node) => {
       select(descr).attr(
         'transform',
         'translate( ' +
    -      // (titleBox.width - bbox.width) / 2 +
    -      (bbox.width > titleBox.width ? 0 : (titleBox.width - bbox.width) / 2) +
    -      ', ' +
    -      (titleBox.height + halfPadding + 5) +
    -      ')'
    +    // (titleBox.width - bbox.width) / 2 +
    +    (bbox.width > titleBox.width ? 0 : (titleBox.width - bbox.width) / 2) +
    +    ', ' +
    +    (titleBox.height + halfPadding + 5) +
    +    ')'
       );
       select(text).attr(
         'transform',
         'translate( ' +
    -      // (titleBox.width - bbox.width) / 2 +
    -      (bbox.width < titleBox.width ? 0 : -(titleBox.width - bbox.width) / 2) +
    -      ', ' +
    -      0 +
    -      ')'
    +    // (titleBox.width - bbox.width) / 2 +
    +    (bbox.width < titleBox.width ? 0 : -(titleBox.width - bbox.width) / 2) +
    +    ', ' +
    +    0 +
    +    ')'
       );
       // Get the size of the label
     
    @@ -541,7 +537,7 @@ const rectWithTitle = (parent, node) => {
     
       updateNodeBounds(node, rect);
     
    -  node.intersect = function (point) {
    +  node.intersect = function(point) {
         return intersect.rect(node, point);
       };
     
    @@ -567,7 +563,7 @@ const stadium = async (parent, node) => {
     
       updateNodeBounds(node, rect);
     
    -  node.intersect = function (point) {
    +  node.intersect = function(point) {
         return intersect.rect(node, point);
       };
     
    @@ -591,7 +587,7 @@ const circle = async (parent, node) => {
     
       updateNodeBounds(node, circle);
     
    -  node.intersect = function (point) {
    +  node.intersect = function(point) {
         log.info('Circle intersect', node, bbox.width / 2 + halfPadding, point);
         return intersect.circle(node, bbox.width / 2 + halfPadding, point);
       };
    @@ -629,7 +625,7 @@ const doublecircle = async (parent, node) => {
     
       updateNodeBounds(node, outerCircle);
     
    -  node.intersect = function (point) {
    +  node.intersect = function(point) {
         log.info('DoubleCircle intersect', node, bbox.width / 2 + halfPadding + gap, point);
         return intersect.circle(node, bbox.width / 2 + halfPadding + gap, point);
       };
    @@ -659,7 +655,7 @@ const subroutine = async (parent, node) => {
       el.attr('style', node.style);
       updateNodeBounds(node, el);
     
    -  node.intersect = function (point) {
    +  node.intersect = function(point) {
         return intersect.polygon(node, points, point);
       };
     
    @@ -678,7 +674,7 @@ const start = (parent, node) => {
     
       updateNodeBounds(node, circle);
     
    -  node.intersect = function (point) {
    +  node.intersect = function(point) {
         return intersect.circle(node, 7, point);
       };
     
    @@ -710,7 +706,7 @@ const forkJoin = (parent, node, dir) => {
       updateNodeBounds(node, shape);
       node.height = node.height + node.padding / 2;
       node.width = node.width + node.padding / 2;
    -  node.intersect = function (point) {
    +  node.intersect = function(point) {
         return intersect.rect(node, point);
       };
     
    @@ -731,7 +727,7 @@ const end = (parent, node) => {
     
       updateNodeBounds(node, circle);
     
    -  node.intersect = function (point) {
    +  node.intersect = function(point) {
         return intersect.circle(node, 7, point);
       };
     
    @@ -896,10 +892,10 @@ const class_box = (parent, node) => {
       select(classTitleLabel).attr(
         'transform',
         'translate( ' +
    -      ((-1 * maxWidth) / 2 + diffX) +
    -      ', ' +
    -      ((-1 * maxHeight) / 2 + verticalPos) +
    -      ')'
    +    ((-1 * maxWidth) / 2 + diffX) +
    +    ', ' +
    +    ((-1 * maxHeight) / 2 + verticalPos) +
    +    ')'
       );
       verticalPos += classTitleBBox.height + rowPadding;
     
    @@ -916,10 +912,10 @@ const class_box = (parent, node) => {
         select(lbl).attr(
           'transform',
           'translate( ' +
    -        -maxWidth / 2 +
    -        ', ' +
    -        ((-1 * maxHeight) / 2 + verticalPos + lineHeight / 2) +
    -        ')'
    +      -maxWidth / 2 +
    +      ', ' +
    +      ((-1 * maxHeight) / 2 + verticalPos + lineHeight / 2) +
    +      ')'
         );
         //get the height of the bounding box of each member if exists
         const memberBBox = lbl?.getBBox();
    @@ -954,7 +950,7 @@ const class_box = (parent, node) => {
     
       updateNodeBounds(node, rect);
     
    -  node.intersect = function (point) {
    +  node.intersect = function(point) {
         return intersect.rect(node, point);
       };
     
    @@ -1030,8 +1026,8 @@ export const clear = () => {
     };
     
     export const positionNode = (node) => {
    +  console.log('Node id = ', node.id);
       const el = nodeElems[node.id];
    -
       log.trace(
         'Transforming node',
         node.diff,
    @@ -1044,10 +1040,10 @@ export const positionNode = (node) => {
         el.attr(
           'transform',
           'translate(' +
    -        (node.x + diff - node.width / 2) +
    -        ', ' +
    -        (node.y - node.height / 2 - padding) +
    -        ')'
    +      (node.x + diff - node.width / 2) +
    +      ', ' +
    +      (node.y - node.height / 2 - padding) +
    +      ')'
         );
       } else {
         el.attr('transform', 'translate(' + node.x + ', ' + node.y + ')');
    diff --git a/packages/mermaid/src/diagrams/block/blockRenderer.ts b/packages/mermaid/src/diagrams/block/blockRenderer.ts
    index 932537786b..a8bf1fe49a 100644
    --- a/packages/mermaid/src/diagrams/block/blockRenderer.ts
    +++ b/packages/mermaid/src/diagrams/block/blockRenderer.ts
    @@ -16,6 +16,7 @@ import type { Block } from './blockTypes.js';
     // import { diagram as BlockDiagram } from './blockDiagram.js';
     import { configureSvgSize } from '../../setupGraphViewbox.js';
     import { Uid } from '../../rendering-util/uid.js';
    +import { pad } from 'lodash';
     
     export const draw = async function (
       text: string,
    @@ -42,19 +43,28 @@ export const draw = async function (
       const nodes = svg.insert('g').attr('class', 'block');
       await calculateBlockSizes(nodes, bl, db);
       const bounds = layout(db);
    +  console.log('Here blocks', bl);
       await insertBlocks(nodes, bl, db);
     
    -  console.log('Here', bl);
    +  // console.log('Here', bl);
     
       // Establish svg dimensions and get width and height
       //
    -  // const bounds = nodes.node().getBoundingClientRect();
    -  const height = bounds.height + 600;
    -  const width = bounds.width + 699;
    +  // const bounds2 = nodes.node().getBoundingClientRect();
    +  const bounds2 = bounds;
    +  const padding = 10;
    +  // Why, oh why ????
    +  const magicFactor = Math.max(1, Math.round(0.125 * (bounds2.width / bounds2.height)));
    +  const height = bounds2.height + magicFactor + 10;
    +  const width = bounds2.width + 10;
       const useMaxWidth = false;
       configureSvgSize(svg, height, width, useMaxWidth);
    -  console.log('Here Bounds', bounds);
    -  svg.attr('viewBox', `${bounds.x} ${bounds.y} ${bounds.width} ${bounds.height}`);
    +  console.log('Here Bounds', bounds, bounds2);
    +  svg.attr(
    +    'viewBox',
    +    `${bounds2.x - 5} ${bounds2.y - 5} ${bounds2.width + 10} ${bounds2.height + 10}`
    +  );
    +  // svg.attr('viewBox', `${-200} ${-200} ${400} ${400}`);
     
       // Prepare data for construction based on diagObj.db
       // This must be a mutable object with `nodes` and `links` properties:
    diff --git a/packages/mermaid/src/diagrams/block/layout.ts b/packages/mermaid/src/diagrams/block/layout.ts
    index 2d61002295..b745ce1b9f 100644
    --- a/packages/mermaid/src/diagrams/block/layout.ts
    +++ b/packages/mermaid/src/diagrams/block/layout.ts
    @@ -66,17 +66,17 @@ let maxY = 0;
     function findBounds(block: Block) {
       if (block.size) {
         const { x, y, width, height } = block.size;
    -    if (x - width < minX) {
    -      minX = x - width;
    +    if (x - width / 2 < minX) {
    +      minX = x - width / 2;
         }
    -    if (y - height < minY) {
    -      minY = y - height;
    +    if (y - height / 2 < minY) {
    +      minY = y - height / 2;
         }
    -    if (x > maxX) {
    -      maxX = x;
    +    if (x + width / 2 > maxX) {
    +      maxX = x + width / 2;
         }
    -    if (y > maxY) {
    -      maxY = y;
    +    if (y + height / 2 > maxY) {
    +      maxY = y + height / 2;
         }
       }
       if (block.children) {
    @@ -90,13 +90,14 @@ export function layout(db: BlockDB) {
       const blocks = db.getBlocks();
       const root = { id: 'root', type: 'composite', children: blocks } as Block;
       layoutBLock(root, db);
    -  positionBlock(root, db);
    +  // positionBlock(root, db);
     
       minX = 0;
       minY = 0;
       maxX = 0;
       maxY = 0;
       findBounds(root);
    +  console.log('Here maxX', maxX);
       const height = maxY - minY;
       const width = maxX - minX;
       return { x: minX, y: minY, width, height };
    diff --git a/packages/mermaid/src/diagrams/block/renderHelpers.ts b/packages/mermaid/src/diagrams/block/renderHelpers.ts
    index 1b29b45363..cb7833050d 100644
    --- a/packages/mermaid/src/diagrams/block/renderHelpers.ts
    +++ b/packages/mermaid/src/diagrams/block/renderHelpers.ts
    @@ -1,5 +1,5 @@
     import { getStylesFromArray } from '../../utils.js';
    -import { insertNode } from '../../dagre-wrapper/nodes.js';
    +import { insertNode, positionNode } from '../../dagre-wrapper/nodes.js';
     import { getConfig } from '../../config.js';
     import { ContainerElement } from 'd3';
     import type { Block } from './blockTypes.js';
    @@ -146,6 +146,7 @@ export async function insertBlockPositioned(elem: any, block: any, db: any) {
       // Add the element to the DOM to size it
       const obj = db.getBlock(node.id);
       const nodeEl = await insertNode(elem, node);
    +  positionNode(node);
     }
     
     export async function performOperations(
    
    From b4e32542e8ad26a39605603051302f0adf6a679d Mon Sep 17 00:00:00 2001
    From: Knut Sveidqvist 
    Date: Tue, 3 Oct 2023 12:56:47 +0200
    Subject: [PATCH 017/217] #3358 Recursive positioning
    
    ---
     cypress/platform/knsv2.html                   | 10 +++-
     .../mermaid/src/diagrams/block/blockDB.ts     |  6 ++-
     packages/mermaid/src/diagrams/block/layout.ts | 50 ++++++++++++-------
     .../src/diagrams/block/parser/block.jison     |  2 +-
     .../src/diagrams/block/renderHelpers.ts       | 11 ++--
     5 files changed, 55 insertions(+), 24 deletions(-)
    
    diff --git a/cypress/platform/knsv2.html b/cypress/platform/knsv2.html
    index 36afc1d035..786ee26927 100644
    --- a/cypress/platform/knsv2.html
    +++ b/cypress/platform/knsv2.html
    @@ -68,11 +68,19 @@
       %% id1("Wide 1")
       id2("2")
       block
    -      id3
    +      id3["I am a wide one"]
           id4
       end
       %% id4("A final one")
     
    +    
    +
    +block-beta
    +
    +      id3["I am a wide one"]
    +      id4
    +
    +
         
     flowchart RL
    diff --git a/packages/mermaid/src/diagrams/block/blockDB.ts b/packages/mermaid/src/diagrams/block/blockDB.ts
    index 84c6536050..50af7965fa 100644
    --- a/packages/mermaid/src/diagrams/block/blockDB.ts
    +++ b/packages/mermaid/src/diagrams/block/blockDB.ts
    @@ -26,7 +26,11 @@ const populateBlockDatabase = (blockList: Block[], parent: Block): void => {
           parent.columns = columns;
         } else {
           if (!block.label) {
    -        block.label = block.id;
    +        if (block.type === 'composite') {
    +          block.label = 'x';
    +        } else {
    +          block.label = block.id;
    +        }
           }
           blockDatabase[block.id] = block;
     
    diff --git a/packages/mermaid/src/diagrams/block/layout.ts b/packages/mermaid/src/diagrams/block/layout.ts
    index b745ce1b9f..e008d78827 100644
    --- a/packages/mermaid/src/diagrams/block/layout.ts
    +++ b/packages/mermaid/src/diagrams/block/layout.ts
    @@ -1,10 +1,12 @@
     import { BlockDB } from './blockDB.js';
     import type { Block } from './blockTypes.js';
     
    -function layoutBLock(block: Block, db: BlockDB) {
    +function calcBlockSizes(block: Block, db: BlockDB) {
    +  let totalWidth = 0;
    +  let totalHeight = 0;
       if (block.children) {
         for (const child of block.children) {
    -      layoutBLock(child, db);
    +      calcBlockSizes(child, db);
         }
         // find max width of children
         let maxWidth = 0;
    @@ -27,9 +29,9 @@ function layoutBLock(block: Block, db: BlockDB) {
           }
         }
     
    -    // Position items
    +    // Position items relative to self
         let x = 0;
    -    let y = 0;
    +    const y = 0;
         const padding = 10;
         for (const child of block.children) {
           if (child.size) {
    @@ -37,26 +39,38 @@ function layoutBLock(block: Block, db: BlockDB) {
             child.size.y = y;
             x += maxWidth + padding;
           }
    +      if (x > totalWidth) {
    +        totalWidth = x;
    +      }
    +      if (y > totalHeight) {
    +        totalHeight = y;
    +      }
         }
       }
    +  if (block.children?.length > 0) {
    +    block.size = { width: totalWidth, height: totalHeight, x: 0, y: 0 };
    +  }
    +  console.log('layoutBlock (done)', block);
     }
     
    -function positionBlock(block: Block, db: BlockDB) {
    -  if (block?.size?.node) {
    -    const node = block?.size?.node;
    -    const size = block?.size;
    -    if (node) {
    -      node.attr(
    -        'transform',
    -        'translate(' + (size.x - size.width / 2) + ', ' + (size.y - size.height / 2) + ')'
    -      );
    -    }
    +function positionBlock(parent: Block, block: Block, db: BlockDB) {
    +  console.log('layout position block', parent.id, parent?.size?.x, block.id, block?.size?.x);
    +  let x = 0;
    +  let y = 0;
    +  if (parent) {
    +    x = parent?.size?.x || 0;
    +    y = parent?.size?.y || 0;
    +  }
    +  if (block.size) {
    +    block.size.x = block.size.x + x - block.size.width / 2;
    +    block.size.y = block.size.y + y;
       }
       if (block.children) {
         for (const child of block.children) {
    -      positionBlock(child, db);
    +      positionBlock(block, child, db);
         }
       }
    +  // console.log('layout position block', block);
     }
     let minX = 0;
     let minY = 0;
    @@ -89,8 +103,10 @@ function findBounds(block: Block) {
     export function layout(db: BlockDB) {
       const blocks = db.getBlocks();
       const root = { id: 'root', type: 'composite', children: blocks } as Block;
    -  layoutBLock(root, db);
    -  // positionBlock(root, db);
    +  calcBlockSizes(root, db);
    +  console.log('layout getBlocks', db.getBlocks());
    +  // Position blocks relative to parents
    +  positionBlock(root, root, db);
     
       minX = 0;
       minY = 0;
    diff --git a/packages/mermaid/src/diagrams/block/parser/block.jison b/packages/mermaid/src/diagrams/block/parser/block.jison
    index 9cc220ff40..32b7c28e25 100644
    --- a/packages/mermaid/src/diagrams/block/parser/block.jison
    +++ b/packages/mermaid/src/diagrams/block/parser/block.jison
    @@ -191,7 +191,7 @@ columnsStatement
     
     blockStatement
       : id-block nodeStatement document end { yy.getLogger().info('Rule: id-block statement : ', $2, $3); const id2 = yy.generateId(); $$ = { ...$2, children: $3 }; }
    -  | block document end { yy.getLogger().info('Rule: blockStatement : ', $1, $2, $3); const id = yy.generateId(); $$ = { id, type:'composite', label:id, children: $2 }; }
    +  | block document end { yy.getLogger().info('Rule: blockStatement : ', $1, $2, $3); const id = yy.generateId(); $$ = { id, type:'composite', label:'', children: $2 }; }
       ;
     
     
    diff --git a/packages/mermaid/src/diagrams/block/renderHelpers.ts b/packages/mermaid/src/diagrams/block/renderHelpers.ts
    index cb7833050d..a17cda607d 100644
    --- a/packages/mermaid/src/diagrams/block/renderHelpers.ts
    +++ b/packages/mermaid/src/diagrams/block/renderHelpers.ts
    @@ -5,7 +5,7 @@ import { ContainerElement } from 'd3';
     import type { Block } from './blockTypes.js';
     import { BlockDB } from './blockDB.js';
     
    -function getNodeFromBlock(block: Block, db: BlockDB, positioned: boolean = false) {
    +function getNodeFromBlock(block: Block, db: BlockDB, positioned = false) {
       const vertex = block;
     
       /**
    @@ -126,7 +126,9 @@ function getNodeFromBlock(block: Block, db: BlockDB, positioned: boolean = false
     type IOperation = (elem: any, block: any, db: any) => Promise;
     async function calculateBlockSize(elem: any, block: any, db: any) {
       const node = getNodeFromBlock(block, db, false);
    -  if (node.type === 'group') return;
    +  if (node.type === 'group') {
    +    return;
    +  }
     
       // Add the element to the DOM to size it
       const nodeEl = await insertNode(elem, node);
    @@ -141,8 +143,9 @@ async function calculateBlockSize(elem: any, block: any, db: any) {
     export async function insertBlockPositioned(elem: any, block: any, db: any) {
       console.log('Here insertBlockPositioned');
       const node = getNodeFromBlock(block, db, true);
    -  if (node.type === 'group') return;
    -
    +  // if (node.type === 'composite') {
    +  //   return;
    +  // }
       // Add the element to the DOM to size it
       const obj = db.getBlock(node.id);
       const nodeEl = await insertNode(elem, node);
    
    From f00871a6b467b9a77cf794924378a0656d3858d8 Mon Sep 17 00:00:00 2001
    From: Knut Sveidqvist 
    Date: Tue, 3 Oct 2023 14:19:08 +0200
    Subject: [PATCH 018/217] #3358 Recursive positioning
    
    ---
     cypress/platform/knsv2.html                   |  11 +-
     packages/mermaid/src/dagre-wrapper/nodes.js   | 137 +++++++++----
     .../mermaid/src/diagrams/block/blockDB.ts     |   2 +-
     packages/mermaid/src/diagrams/block/layout.ts |  40 ++--
     .../src/diagrams/block/renderHelpers.ts       |   5 +
     packages/mermaid/src/diagrams/block/styles.ts |  10 +-
     ....timestamp-1696335530501-05072b5e79635.mjs | 190 ++++++++++++++++++
     7 files changed, 326 insertions(+), 69 deletions(-)
     create mode 100644 vite.config.ts.timestamp-1696335530501-05072b5e79635.mjs
    
    diff --git a/cypress/platform/knsv2.html b/cypress/platform/knsv2.html
    index 786ee26927..6e69533eb6 100644
    --- a/cypress/platform/knsv2.html
    +++ b/cypress/platform/knsv2.html
    @@ -69,12 +69,15 @@
       id2("2")
       block
           id3["I am a wide one"]
    -      id4
    +      block
    +        id44("A final one")
    +        id45("B final one")
    +      end
       end
    -  %% id4("A final one")
    +  id4("Another final one")
     
         
    -
    +    
     block-beta
     
           id3["I am a wide one"]
    @@ -84,7 +87,9 @@
         
     flowchart RL
    +  subgraph "`one`"
         id
    +  end
         
     flowchart RL
    diff --git a/packages/mermaid/src/dagre-wrapper/nodes.js b/packages/mermaid/src/dagre-wrapper/nodes.js
    index 9e57fb2b0c..b95265f311 100644
    --- a/packages/mermaid/src/dagre-wrapper/nodes.js
    +++ b/packages/mermaid/src/dagre-wrapper/nodes.js
    @@ -27,7 +27,7 @@ const question = async (parent, node) => {
       questionElem.attr('style', node.style);
       updateNodeBounds(node, questionElem);
     
    -  node.intersect = function(point) {
    +  node.intersect = function (point) {
         log.warn('Intersect called');
         return intersect.polygon(node, points, point);
       };
    @@ -52,7 +52,7 @@ const choice = (parent, node) => {
       const choice = shapeSvg.insert('polygon', ':first-child').attr(
         'points',
         points
    -      .map(function(d) {
    +      .map(function (d) {
             return d.x + ',' + d.y;
           })
           .join(' ')
    @@ -62,7 +62,7 @@ const choice = (parent, node) => {
       node.width = 28;
       node.height = 28;
     
    -  node.intersect = function(point) {
    +  node.intersect = function (point) {
         return intersect.circle(node, 14, point);
       };
     
    @@ -89,7 +89,7 @@ const hexagon = async (parent, node) => {
       hex.attr('style', node.style);
       updateNodeBounds(node, hex);
     
    -  node.intersect = function(point) {
    +  node.intersect = function (point) {
         return intersect.polygon(node, points, point);
       };
     
    @@ -115,7 +115,7 @@ const rect_left_inv_arrow = async (parent, node) => {
       node.width = w + h;
       node.height = h;
     
    -  node.intersect = function(point) {
    +  node.intersect = function (point) {
         return intersect.polygon(node, points, point);
       };
     
    @@ -138,7 +138,7 @@ const lean_right = async (parent, node) => {
       el.attr('style', node.style);
       updateNodeBounds(node, el);
     
    -  node.intersect = function(point) {
    +  node.intersect = function (point) {
         return intersect.polygon(node, points, point);
       };
     
    @@ -161,7 +161,7 @@ const lean_left = async (parent, node) => {
       el.attr('style', node.style);
       updateNodeBounds(node, el);
     
    -  node.intersect = function(point) {
    +  node.intersect = function (point) {
         return intersect.polygon(node, points, point);
       };
     
    @@ -184,7 +184,7 @@ const trapezoid = async (parent, node) => {
       el.attr('style', node.style);
       updateNodeBounds(node, el);
     
    -  node.intersect = function(point) {
    +  node.intersect = function (point) {
         return intersect.polygon(node, points, point);
       };
     
    @@ -207,7 +207,7 @@ const inv_trapezoid = async (parent, node) => {
       el.attr('style', node.style);
       updateNodeBounds(node, el);
     
    -  node.intersect = function(point) {
    +  node.intersect = function (point) {
         return intersect.polygon(node, points, point);
       };
     
    @@ -231,7 +231,7 @@ const rect_right_inv_arrow = async (parent, node) => {
       el.attr('style', node.style);
       updateNodeBounds(node, el);
     
    -  node.intersect = function(point) {
    +  node.intersect = function (point) {
         return intersect.polygon(node, points, point);
       };
     
    @@ -281,7 +281,7 @@ const cylinder = async (parent, node) => {
     
       updateNodeBounds(node, el);
     
    -  node.intersect = function(point) {
    +  node.intersect = function (point) {
         const pos = intersect.rect(node, point);
         const x = pos.x - node.x;
     
    @@ -350,7 +350,55 @@ const rect = async (parent, node) => {
     
       updateNodeBounds(node, rect);
     
    -  node.intersect = function(point) {
    +  node.intersect = function (point) {
    +    return intersect.rect(node, point);
    +  };
    +
    +  return shapeSvg;
    +};
    +
    +const composite = async (parent, node) => {
    +  console.log('This got called');
    +  const { shapeSvg, bbox, halfPadding } = await labelHelper(
    +    parent,
    +    node,
    +    'node ' + node.classes,
    +    true
    +  );
    +
    +  // add the rect
    +  const rect = shapeSvg.insert('rect', ':first-child');
    +
    +  // const totalWidth = bbox.width + node.padding * 2;
    +  // const totalHeight = bbox.height + node.padding * 2;
    +  const totalWidth = node.positioned ? node.width : bbox.width + node.padding;
    +  const totalHeight = node.positioned ? node.height : bbox.height + node.padding;
    +  const x = node.positioned ? -totalWidth / 2 : -bbox.width / 2 - halfPadding;
    +  const y = node.positioned ? -totalHeight / 2 : -bbox.height / 2 - halfPadding;
    +  rect
    +    .attr('class', 'basic cluster composite label-container')
    +    .attr('style', node.style)
    +    .attr('rx', node.rx)
    +    .attr('ry', node.ry)
    +    .attr('x', x)
    +    .attr('y', y)
    +    .attr('width', totalWidth)
    +    .attr('height', totalHeight);
    +
    +  if (node.props) {
    +    const propKeys = new Set(Object.keys(node.props));
    +    if (node.props.borders) {
    +      applyNodePropertyBorders(rect, node.props.borders, totalWidth, totalHeight);
    +      propKeys.delete('borders');
    +    }
    +    propKeys.forEach((propKey) => {
    +      log.warn(`Unknown node property ${propKey}`);
    +    });
    +  }
    +
    +  updateNodeBounds(node, rect);
    +
    +  node.intersect = function (point) {
         return intersect.rect(node, point);
       };
     
    @@ -383,7 +431,7 @@ const labelRect = async (parent, node) => {
     
       updateNodeBounds(node, rect);
     
    -  node.intersect = function(point) {
    +  node.intersect = function (point) {
         return intersect.rect(node, point);
       };
     
    @@ -495,20 +543,20 @@ const rectWithTitle = (parent, node) => {
       select(descr).attr(
         'transform',
         'translate( ' +
    -    // (titleBox.width - bbox.width) / 2 +
    -    (bbox.width > titleBox.width ? 0 : (titleBox.width - bbox.width) / 2) +
    -    ', ' +
    -    (titleBox.height + halfPadding + 5) +
    -    ')'
    +      // (titleBox.width - bbox.width) / 2 +
    +      (bbox.width > titleBox.width ? 0 : (titleBox.width - bbox.width) / 2) +
    +      ', ' +
    +      (titleBox.height + halfPadding + 5) +
    +      ')'
       );
       select(text).attr(
         'transform',
         'translate( ' +
    -    // (titleBox.width - bbox.width) / 2 +
    -    (bbox.width < titleBox.width ? 0 : -(titleBox.width - bbox.width) / 2) +
    -    ', ' +
    -    0 +
    -    ')'
    +      // (titleBox.width - bbox.width) / 2 +
    +      (bbox.width < titleBox.width ? 0 : -(titleBox.width - bbox.width) / 2) +
    +      ', ' +
    +      0 +
    +      ')'
       );
       // Get the size of the label
     
    @@ -537,7 +585,7 @@ const rectWithTitle = (parent, node) => {
     
       updateNodeBounds(node, rect);
     
    -  node.intersect = function(point) {
    +  node.intersect = function (point) {
         return intersect.rect(node, point);
       };
     
    @@ -563,7 +611,7 @@ const stadium = async (parent, node) => {
     
       updateNodeBounds(node, rect);
     
    -  node.intersect = function(point) {
    +  node.intersect = function (point) {
         return intersect.rect(node, point);
       };
     
    @@ -587,7 +635,7 @@ const circle = async (parent, node) => {
     
       updateNodeBounds(node, circle);
     
    -  node.intersect = function(point) {
    +  node.intersect = function (point) {
         log.info('Circle intersect', node, bbox.width / 2 + halfPadding, point);
         return intersect.circle(node, bbox.width / 2 + halfPadding, point);
       };
    @@ -625,7 +673,7 @@ const doublecircle = async (parent, node) => {
     
       updateNodeBounds(node, outerCircle);
     
    -  node.intersect = function(point) {
    +  node.intersect = function (point) {
         log.info('DoubleCircle intersect', node, bbox.width / 2 + halfPadding + gap, point);
         return intersect.circle(node, bbox.width / 2 + halfPadding + gap, point);
       };
    @@ -655,7 +703,7 @@ const subroutine = async (parent, node) => {
       el.attr('style', node.style);
       updateNodeBounds(node, el);
     
    -  node.intersect = function(point) {
    +  node.intersect = function (point) {
         return intersect.polygon(node, points, point);
       };
     
    @@ -674,7 +722,7 @@ const start = (parent, node) => {
     
       updateNodeBounds(node, circle);
     
    -  node.intersect = function(point) {
    +  node.intersect = function (point) {
         return intersect.circle(node, 7, point);
       };
     
    @@ -706,7 +754,7 @@ const forkJoin = (parent, node, dir) => {
       updateNodeBounds(node, shape);
       node.height = node.height + node.padding / 2;
       node.width = node.width + node.padding / 2;
    -  node.intersect = function(point) {
    +  node.intersect = function (point) {
         return intersect.rect(node, point);
       };
     
    @@ -727,7 +775,7 @@ const end = (parent, node) => {
     
       updateNodeBounds(node, circle);
     
    -  node.intersect = function(point) {
    +  node.intersect = function (point) {
         return intersect.circle(node, 7, point);
       };
     
    @@ -892,10 +940,10 @@ const class_box = (parent, node) => {
       select(classTitleLabel).attr(
         'transform',
         'translate( ' +
    -    ((-1 * maxWidth) / 2 + diffX) +
    -    ', ' +
    -    ((-1 * maxHeight) / 2 + verticalPos) +
    -    ')'
    +      ((-1 * maxWidth) / 2 + diffX) +
    +      ', ' +
    +      ((-1 * maxHeight) / 2 + verticalPos) +
    +      ')'
       );
       verticalPos += classTitleBBox.height + rowPadding;
     
    @@ -912,10 +960,10 @@ const class_box = (parent, node) => {
         select(lbl).attr(
           'transform',
           'translate( ' +
    -      -maxWidth / 2 +
    -      ', ' +
    -      ((-1 * maxHeight) / 2 + verticalPos + lineHeight / 2) +
    -      ')'
    +        -maxWidth / 2 +
    +        ', ' +
    +        ((-1 * maxHeight) / 2 + verticalPos + lineHeight / 2) +
    +        ')'
         );
         //get the height of the bounding box of each member if exists
         const memberBBox = lbl?.getBBox();
    @@ -950,7 +998,7 @@ const class_box = (parent, node) => {
     
       updateNodeBounds(node, rect);
     
    -  node.intersect = function(point) {
    +  node.intersect = function (point) {
         return intersect.rect(node, point);
       };
     
    @@ -959,6 +1007,7 @@ const class_box = (parent, node) => {
     
     const shapes = {
       rhombus: question,
    +  composite,
       question,
       rect,
       labelRect,
    @@ -1040,10 +1089,10 @@ export const positionNode = (node) => {
         el.attr(
           'transform',
           'translate(' +
    -      (node.x + diff - node.width / 2) +
    -      ', ' +
    -      (node.y - node.height / 2 - padding) +
    -      ')'
    +        (node.x + diff - node.width / 2) +
    +        ', ' +
    +        (node.y - node.height / 2 - padding) +
    +        ')'
         );
       } else {
         el.attr('transform', 'translate(' + node.x + ', ' + node.y + ')');
    diff --git a/packages/mermaid/src/diagrams/block/blockDB.ts b/packages/mermaid/src/diagrams/block/blockDB.ts
    index 50af7965fa..2dce9e323e 100644
    --- a/packages/mermaid/src/diagrams/block/blockDB.ts
    +++ b/packages/mermaid/src/diagrams/block/blockDB.ts
    @@ -27,7 +27,7 @@ const populateBlockDatabase = (blockList: Block[], parent: Block): void => {
         } else {
           if (!block.label) {
             if (block.type === 'composite') {
    -          block.label = 'x';
    +          block.label = '';
             } else {
               block.label = block.id;
             }
    diff --git a/packages/mermaid/src/diagrams/block/layout.ts b/packages/mermaid/src/diagrams/block/layout.ts
    index e008d78827..8756646ef5 100644
    --- a/packages/mermaid/src/diagrams/block/layout.ts
    +++ b/packages/mermaid/src/diagrams/block/layout.ts
    @@ -2,15 +2,17 @@ import { BlockDB } from './blockDB.js';
     import type { Block } from './blockTypes.js';
     
     function calcBlockSizes(block: Block, db: BlockDB) {
    -  let totalWidth = 0;
    -  let totalHeight = 0;
    +  const totalWidth = 0;
    +  const totalHeight = 0;
    +  let maxWidth = 0;
    +  let maxHeight = 0;
    +  const padding = 20;
    +
       if (block.children) {
         for (const child of block.children) {
           calcBlockSizes(child, db);
         }
         // find max width of children
    -    let maxWidth = 0;
    -    let maxHeight = 0;
         for (const child of block.children) {
           const { width, height, x, y } = child.size || { width: 0, height: 0, x: 0, y: 0 };
           if (width > maxWidth) {
    @@ -30,39 +32,41 @@ function calcBlockSizes(block: Block, db: BlockDB) {
         }
     
         // Position items relative to self
    -    let x = 0;
    +    let x = -padding / 2;
         const y = 0;
    -    const padding = 10;
    +
    +    let accumulatedPaddingX = 0;
         for (const child of block.children) {
           if (child.size) {
             child.size.x = x;
             child.size.y = y;
             x += maxWidth + padding;
           }
    -      if (x > totalWidth) {
    -        totalWidth = x;
    -      }
    -      if (y > totalHeight) {
    -        totalHeight = y;
    -      }
    +      accumulatedPaddingX += padding;
         }
       }
       if (block.children?.length > 0) {
    -    block.size = { width: totalWidth, height: totalHeight, x: 0, y: 0 };
    +    const numChildren = block.children.length;
    +    block.size = {
    +      width: numChildren * (maxWidth + padding) + padding,
    +      height: totalHeight + 4 * padding,
    +      x: 0,
    +      y: 0,
    +    };
       }
       console.log('layoutBlock (done)', block);
     }
     
     function positionBlock(parent: Block, block: Block, db: BlockDB) {
       console.log('layout position block', parent.id, parent?.size?.x, block.id, block?.size?.x);
    -  let x = 0;
    +  let parentX = 0;
       let y = 0;
       if (parent) {
    -    x = parent?.size?.x || 0;
    +    parentX = parent?.size?.x || 0;
         y = parent?.size?.y || 0;
       }
    -  if (block.size) {
    -    block.size.x = block.size.x + x - block.size.width / 2;
    +  if (block.size && block.id !== 'root') {
    +    block.size.x = parentX + block.size.x + -block.size.width / 2;
         block.size.y = block.size.y + y;
       }
       if (block.children) {
    @@ -104,9 +108,9 @@ export function layout(db: BlockDB) {
       const blocks = db.getBlocks();
       const root = { id: 'root', type: 'composite', children: blocks } as Block;
       calcBlockSizes(root, db);
    -  console.log('layout getBlocks', db.getBlocks());
       // Position blocks relative to parents
       positionBlock(root, root, db);
    +  console.log('getBlocks', JSON.stringify(db.getBlocks(), null, 2));
     
       minX = 0;
       minY = 0;
    diff --git a/packages/mermaid/src/diagrams/block/renderHelpers.ts b/packages/mermaid/src/diagrams/block/renderHelpers.ts
    index a17cda607d..5bbe279e7f 100644
    --- a/packages/mermaid/src/diagrams/block/renderHelpers.ts
    +++ b/packages/mermaid/src/diagrams/block/renderHelpers.ts
    @@ -26,12 +26,17 @@ function getNodeFromBlock(block: Block, db: BlockDB, positioned = false) {
       let radious = 0;
       let _shape = '';
       let layoutOptions = {};
    +  console.log('This is the type:', vertex.type);
       // Set the shape based parameters
       switch (vertex.type) {
         case 'round':
           radious = 5;
           _shape = 'rect';
           break;
    +    case 'composite':
    +      radious = 4;
    +      _shape = 'composite';
    +      break;
         case 'square':
           _shape = 'rect';
           break;
    diff --git a/packages/mermaid/src/diagrams/block/styles.ts b/packages/mermaid/src/diagrams/block/styles.ts
    index a4af4f1283..e1194f0d11 100644
    --- a/packages/mermaid/src/diagrams/block/styles.ts
    +++ b/packages/mermaid/src/diagrams/block/styles.ts
    @@ -42,6 +42,8 @@ const getStyles = (options: FlowChartStyleOptions) =>
         color: ${options.titleColor};
       }
     
    +
    +
       .label text,span,p {
         fill: ${options.nodeTextColor || options.textColor};
         color: ${options.nodeTextColor || options.textColor};
    @@ -103,9 +105,11 @@ const getStyles = (options: FlowChartStyleOptions) =>
         // background-color:
       }
     
    -  .cluster rect {
    -    fill: ${options.clusterBkg};
    -    stroke: ${options.clusterBorder};
    +  .node .cluster {
    +    // fill: ${fade(options.mainBkg, 0.5)};
    +    fill: ${fade(options.clusterBkg, 0.5)};
    +    stroke: ${fade(options.clusterBorder, 0.2)};
    +    box-shadow: rgba(50, 50, 93, 0.25) 0px 13px 27px -5px, rgba(0, 0, 0, 0.3) 0px 8px 16px -8px;
         stroke-width: 1px;
       }
     
    diff --git a/vite.config.ts.timestamp-1696335530501-05072b5e79635.mjs b/vite.config.ts.timestamp-1696335530501-05072b5e79635.mjs
    new file mode 100644
    index 0000000000..e020937df9
    --- /dev/null
    +++ b/vite.config.ts.timestamp-1696335530501-05072b5e79635.mjs
    @@ -0,0 +1,190 @@
    +// .vite/jisonTransformer.ts
    +import jison from "file:///Users/knsv/source/git/mermaid/node_modules/.pnpm/jison@0.4.18/node_modules/jison/lib/jison.js";
    +var transformJison = (src) => {
    +  const parser = new jison.Generator(src, {
    +    moduleType: "js",
    +    "token-stack": true
    +  });
    +  const source = parser.generate({ moduleMain: "() => {}" });
    +  const exporter = `
    +	parser.parser = parser;
    +	export { parser };
    +	export default parser;
    +	`;
    +  return `${source} ${exporter}`;
    +};
    +
    +// .vite/jisonPlugin.ts
    +var fileRegex = /\.(jison)$/;
    +function jison2() {
    +  return {
    +    name: "jison",
    +    transform(src, id) {
    +      if (fileRegex.test(id)) {
    +        return {
    +          code: transformJison(src),
    +          map: null
    +          // provide source map if available
    +        };
    +      }
    +    }
    +  };
    +}
    +
    +// .vite/jsonSchemaPlugin.ts
    +import { load, JSON_SCHEMA } from "file:///Users/knsv/source/git/mermaid/node_modules/.pnpm/js-yaml@4.1.0/node_modules/js-yaml/dist/js-yaml.mjs";
    +import assert from "node:assert";
    +import Ajv2019 from "file:///Users/knsv/source/git/mermaid/node_modules/.pnpm/ajv@8.12.0/node_modules/ajv/dist/2019.js";
    +var MERMAID_CONFIG_DIAGRAM_KEYS = [
    +  "flowchart",
    +  "sequence",
    +  "gantt",
    +  "journey",
    +  "class",
    +  "state",
    +  "er",
    +  "pie",
    +  "quadrantChart",
    +  "requirement",
    +  "mindmap",
    +  "timeline",
    +  "gitGraph",
    +  "c4",
    +  "sankey"
    +];
    +function generateDefaults(mermaidConfigSchema) {
    +  const ajv = new Ajv2019({
    +    useDefaults: true,
    +    allowUnionTypes: true,
    +    strict: true
    +  });
    +  ajv.addKeyword({
    +    keyword: "meta:enum",
    +    // used by jsonschema2md
    +    errors: false
    +  });
    +  ajv.addKeyword({
    +    keyword: "tsType",
    +    // used by json-schema-to-typescript
    +    errors: false
    +  });
    +  const mermaidDefaultConfig = {};
    +  assert.ok(mermaidConfigSchema.$defs);
    +  const baseDiagramConfig = mermaidConfigSchema.$defs.BaseDiagramConfig;
    +  for (const key of MERMAID_CONFIG_DIAGRAM_KEYS) {
    +    const subSchemaRef = mermaidConfigSchema.properties[key].$ref;
    +    const [root, defs, defName] = subSchemaRef.split("/");
    +    assert.strictEqual(root, "#");
    +    assert.strictEqual(defs, "$defs");
    +    const subSchema = {
    +      $schema: mermaidConfigSchema.$schema,
    +      $defs: mermaidConfigSchema.$defs,
    +      ...mermaidConfigSchema.$defs[defName]
    +    };
    +    const validate2 = ajv.compile(subSchema);
    +    mermaidDefaultConfig[key] = {};
    +    for (const required of subSchema.required ?? []) {
    +      if (subSchema.properties[required] === void 0 && baseDiagramConfig.properties[required]) {
    +        mermaidDefaultConfig[key][required] = baseDiagramConfig.properties[required].default;
    +      }
    +    }
    +    if (!validate2(mermaidDefaultConfig[key])) {
    +      throw new Error(
    +        `schema for subconfig ${key} does not have valid defaults! Errors were ${JSON.stringify(
    +          validate2.errors,
    +          void 0,
    +          2
    +        )}`
    +      );
    +    }
    +  }
    +  const validate = ajv.compile(mermaidConfigSchema);
    +  if (!validate(mermaidDefaultConfig)) {
    +    throw new Error(
    +      `Mermaid config JSON Schema does not have valid defaults! Errors were ${JSON.stringify(
    +        validate.errors,
    +        void 0,
    +        2
    +      )}`
    +    );
    +  }
    +  return mermaidDefaultConfig;
    +}
    +function jsonSchemaPlugin() {
    +  return {
    +    name: "json-schema-plugin",
    +    transform(src, id) {
    +      const idAsUrl = new URL(id, "file:///");
    +      if (!idAsUrl.pathname.endsWith("schema.yaml")) {
    +        return;
    +      }
    +      if (idAsUrl.searchParams.get("only-defaults")) {
    +        const jsonSchema = load(src, {
    +          filename: idAsUrl.pathname,
    +          // only allow JSON types in our YAML doc (will probably be default in YAML 1.3)
    +          // e.g. `true` will be parsed a boolean `true`, `True` will be parsed as string `"True"`.
    +          schema: JSON_SCHEMA
    +        });
    +        return {
    +          code: `export default ${JSON.stringify(generateDefaults(jsonSchema), void 0, 2)};`,
    +          map: null
    +          // no source map
    +        };
    +      } else {
    +        return {
    +          code: `export default ${JSON.stringify(
    +            load(src, {
    +              filename: idAsUrl.pathname,
    +              // only allow JSON types in our YAML doc (will probably be default in YAML 1.3)
    +              // e.g. `true` will be parsed a boolean `true`, `True` will be parsed as string `"True"`.
    +              schema: JSON_SCHEMA
    +            }),
    +            void 0,
    +            2
    +          )};`,
    +          map: null
    +          // provide source map if available
    +        };
    +      }
    +    }
    +  };
    +}
    +
    +// vite.config.ts
    +import typescript from "file:///Users/knsv/source/git/mermaid/node_modules/.pnpm/@rollup+plugin-typescript@11.1.1_typescript@5.1.3/node_modules/@rollup/plugin-typescript/dist/es/index.js";
    +import { defineConfig } from "file:///Users/knsv/source/git/mermaid/node_modules/.pnpm/vitest@0.33.0_@vitest+ui@0.33.0_jsdom@22.0.0/node_modules/vitest/dist/config.js";
    +var vite_config_default = defineConfig({
    +  resolve: {
    +    extensions: [".js"]
    +  },
    +  plugins: [
    +    jison2(),
    +    jsonSchemaPlugin(),
    +    // handles .schema.yaml JSON Schema files
    +    // @ts-expect-error According to the type definitions, rollup plugins are incompatible with vite
    +    typescript({ compilerOptions: { declaration: false } })
    +  ],
    +  test: {
    +    environment: "jsdom",
    +    globals: true,
    +    // TODO: should we move this to a mermaid-core package?
    +    setupFiles: ["packages/mermaid/src/tests/setup.ts"],
    +    coverage: {
    +      provider: "v8",
    +      reporter: ["text", "json", "html", "lcov"],
    +      reportsDirectory: "./coverage/vitest",
    +      exclude: ["**/node_modules/**", "**/tests/**", "**/__mocks__/**"]
    +    }
    +  },
    +  build: {
    +    /** If you set esmExternals to true, this plugins assumes that
    +     all external dependencies are ES modules */
    +    commonjsOptions: {
    +      esmExternals: true
    +    }
    +  }
    +});
    +export {
    +  vite_config_default as default
    +};
    +//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLnZpdGUvamlzb25UcmFuc2Zvcm1lci50cyIsICIudml0ZS9qaXNvblBsdWdpbi50cyIsICIudml0ZS9qc29uU2NoZW1hUGx1Z2luLnRzIiwgInZpdGUuY29uZmlnLnRzIl0sCiAgInNvdXJjZXNDb250ZW50IjogWyJjb25zdCBfX3ZpdGVfaW5qZWN0ZWRfb3JpZ2luYWxfZGlybmFtZSA9IFwiL1VzZXJzL2tuc3Yvc291cmNlL2dpdC9tZXJtYWlkLy52aXRlXCI7Y29uc3QgX192aXRlX2luamVjdGVkX29yaWdpbmFsX2ZpbGVuYW1lID0gXCIvVXNlcnMva25zdi9zb3VyY2UvZ2l0L21lcm1haWQvLnZpdGUvamlzb25UcmFuc2Zvcm1lci50c1wiO2NvbnN0IF9fdml0ZV9pbmplY3RlZF9vcmlnaW5hbF9pbXBvcnRfbWV0YV91cmwgPSBcImZpbGU6Ly8vVXNlcnMva25zdi9zb3VyY2UvZ2l0L21lcm1haWQvLnZpdGUvamlzb25UcmFuc2Zvcm1lci50c1wiO2ltcG9ydCBqaXNvbiBmcm9tICdqaXNvbic7XG5cbmV4cG9ydCBjb25zdCB0cmFuc2Zvcm1KaXNvbiA9IChzcmM6IHN0cmluZyk6IHN0cmluZyA9PiB7XG4gIGNvbnN0IHBhcnNlciA9IG5ldyBqaXNvbi5HZW5lcmF0b3Ioc3JjLCB7XG4gICAgbW9kdWxlVHlwZTogJ2pzJyxcbiAgICAndG9rZW4tc3RhY2snOiB0cnVlLFxuICB9KTtcbiAgY29uc3Qgc291cmNlID0gcGFyc2VyLmdlbmVyYXRlKHsgbW9kdWxlTWFpbjogJygpID0+IHt9JyB9KTtcbiAgY29uc3QgZXhwb3J0ZXIgPSBgXG5cdHBhcnNlci5wYXJzZXIgPSBwYXJzZXI7XG5cdGV4cG9ydCB7IHBhcnNlciB9O1xuXHRleHBvcnQgZGVmYXVsdCBwYXJzZXI7XG5cdGA7XG4gIHJldHVybiBgJHtzb3VyY2V9ICR7ZXhwb3J0ZXJ9YDtcbn07XG4iLCAiY29uc3QgX192aXRlX2luamVjdGVkX29yaWdpbmFsX2Rpcm5hbWUgPSBcIi9Vc2Vycy9rbnN2L3NvdXJjZS9naXQvbWVybWFpZC8udml0ZVwiO2NvbnN0IF9fdml0ZV9pbmplY3RlZF9vcmlnaW5hbF9maWxlbmFtZSA9IFwiL1VzZXJzL2tuc3Yvc291cmNlL2dpdC9tZXJtYWlkLy52aXRlL2ppc29uUGx1Z2luLnRzXCI7Y29uc3QgX192aXRlX2luamVjdGVkX29yaWdpbmFsX2ltcG9ydF9tZXRhX3VybCA9IFwiZmlsZTovLy9Vc2Vycy9rbnN2L3NvdXJjZS9naXQvbWVybWFpZC8udml0ZS9qaXNvblBsdWdpbi50c1wiO2ltcG9ydCB7IHRyYW5zZm9ybUppc29uIH0gZnJvbSAnLi9qaXNvblRyYW5zZm9ybWVyLmpzJztcbmNvbnN0IGZpbGVSZWdleCA9IC9cXC4oamlzb24pJC87XG5cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIGppc29uKCkge1xuICByZXR1cm4ge1xuICAgIG5hbWU6ICdqaXNvbicsXG5cbiAgICB0cmFuc2Zvcm0oc3JjOiBzdHJpbmcsIGlkOiBzdHJpbmcpIHtcbiAgICAgIGlmIChmaWxlUmVnZXgudGVzdChpZCkpIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICBjb2RlOiB0cmFuc2Zvcm1KaXNvbihzcmMpLFxuICAgICAgICAgIG1hcDogbnVsbCwgLy8gcHJvdmlkZSBzb3VyY2UgbWFwIGlmIGF2YWlsYWJsZVxuICAgICAgICB9O1xuICAgICAgfVxuICAgIH0sXG4gIH07XG59XG4iLCAiY29uc3QgX192aXRlX2luamVjdGVkX29yaWdpbmFsX2Rpcm5hbWUgPSBcIi9Vc2Vycy9rbnN2L3NvdXJjZS9naXQvbWVybWFpZC8udml0ZVwiO2NvbnN0IF9fdml0ZV9pbmplY3RlZF9vcmlnaW5hbF9maWxlbmFtZSA9IFwiL1VzZXJzL2tuc3Yvc291cmNlL2dpdC9tZXJtYWlkLy52aXRlL2pzb25TY2hlbWFQbHVnaW4udHNcIjtjb25zdCBfX3ZpdGVfaW5qZWN0ZWRfb3JpZ2luYWxfaW1wb3J0X21ldGFfdXJsID0gXCJmaWxlOi8vL1VzZXJzL2tuc3Yvc291cmNlL2dpdC9tZXJtYWlkLy52aXRlL2pzb25TY2hlbWFQbHVnaW4udHNcIjtpbXBvcnQgeyBsb2FkLCBKU09OX1NDSEVNQSB9IGZyb20gJ2pzLXlhbWwnO1xuaW1wb3J0IGFzc2VydCBmcm9tICdub2RlOmFzc2VydCc7XG5pbXBvcnQgQWp2MjAxOSwgeyB0eXBlIEpTT05TY2hlbWFUeXBlIH0gZnJvbSAnYWp2L2Rpc3QvMjAxOS5qcyc7XG5pbXBvcnQgeyBQbHVnaW5PcHRpb24gfSBmcm9tICd2aXRlJztcblxuaW1wb3J0IHR5cGUgeyBNZXJtYWlkQ29uZmlnLCBCYXNlRGlhZ3JhbUNvbmZpZyB9IGZyb20gJy4uL3BhY2thZ2VzL21lcm1haWQvc3JjL2NvbmZpZy50eXBlLmpzJztcblxuLyoqXG4gKiBBbGwgb2YgdGhlIGtleXMgaW4gdGhlIG1lcm1haWQgY29uZmlnIHRoYXQgaGF2ZSBhIG1lcm1haWQgZGlhZ3JhbSBjb25maWcuXG4gKi9cbmNvbnN0IE1FUk1BSURfQ09ORklHX0RJQUdSQU1fS0VZUyA9IFtcbiAgJ2Zsb3djaGFydCcsXG4gICdzZXF1ZW5jZScsXG4gICdnYW50dCcsXG4gICdqb3VybmV5JyxcbiAgJ2NsYXNzJyxcbiAgJ3N0YXRlJyxcbiAgJ2VyJyxcbiAgJ3BpZScsXG4gICdxdWFkcmFudENoYXJ0JyxcbiAgJ3JlcXVpcmVtZW50JyxcbiAgJ21pbmRtYXAnLFxuICAndGltZWxpbmUnLFxuICAnZ2l0R3JhcGgnLFxuICAnYzQnLFxuICAnc2Fua2V5Jyxcbl0gYXMgY29uc3Q7XG5cbi8qKlxuICogR2VuZXJhdGUgZGVmYXVsdCB2YWx1ZXMgZnJvbSB0aGUgSlNPTiBTY2hlbWEuXG4gKlxuICogQUpWIGRvZXMgbm90IHN1cHBvcnQgbmVzdGVkIGRlZmF1bHQgdmFsdWVzIHlldCAob3IgZGVmYXVsdCB2YWx1ZXMgd2l0aCAkcmVmKSxcbiAqIHNvIHdlIG5lZWQgdG8gbWFudWFsbHkgZmluZCB0aGVtICh0aGlzIG1heSBiZSBmaXhlZCBpbiBhanYgdjkpLlxuICpcbiAqIEBwYXJhbSBtZXJtYWlkQ29uZmlnU2NoZW1hIC0gVGhlIE1lcm1haWQgSlNPTiBTY2hlbWEgdG8gdXNlLlxuICogQHJldHVybnMgVGhlIGRlZmF1bHQgbWVybWFpZCBjb25maWcgb2JqZWN0LlxuICovXG5mdW5jdGlvbiBnZW5lcmF0ZURlZmF1bHRzKG1lcm1haWRDb25maWdTY2hlbWE6IEpTT05TY2hlbWFUeXBlPE1lcm1haWRDb25maWc+KSB7XG4gIGNvbnN0IGFqdiA9IG5ldyBBanYyMDE5KHtcbiAgICB1c2VEZWZhdWx0czogdHJ1ZSxcbiAgICBhbGxvd1VuaW9uVHlwZXM6IHRydWUsXG4gICAgc3RyaWN0OiB0cnVlLFxuICB9KTtcblxuICBhanYuYWRkS2V5d29yZCh7XG4gICAga2V5d29yZDogJ21ldGE6ZW51bScsIC8vIHVzZWQgYnkganNvbnNjaGVtYTJtZFxuICAgIGVycm9yczogZmFsc2UsXG4gIH0pO1xuICBhanYuYWRkS2V5d29yZCh7XG4gICAga2V5d29yZDogJ3RzVHlwZScsIC8vIHVzZWQgYnkganNvbi1zY2hlbWEtdG8tdHlwZXNjcmlwdFxuICAgIGVycm9yczogZmFsc2UsXG4gIH0pO1xuXG4gIC8vIGFqdiBjdXJyZW50bHkgZG9lc24ndCBzdXBwb3J0IG5lc3RlZCBkZWZhdWx0IHZhbHVlcywgc2VlIGh0dHBzOi8vZ2l0aHViLmNvbS9hanYtdmFsaWRhdG9yL2Fqdi9pc3N1ZXMvMTcxOFxuICAvLyAobWF5IGJlIGZpeGVkIGluIHY5KSBzbyB3ZSBuZWVkIHRvIG1hbnVhbGx5IHVzZSBzdWItc2NoZW1hc1xuICBjb25zdCBtZXJtYWlkRGVmYXVsdENvbmZpZyA9IHt9O1xuXG4gIGFzc2VydC5vayhtZXJtYWlkQ29uZmlnU2NoZW1hLiRkZWZzKTtcbiAgY29uc3QgYmFzZURpYWdyYW1Db25maWcgPSBtZXJtYWlkQ29uZmlnU2NoZW1hLiRkZWZzLkJhc2VEaWFncmFtQ29uZmlnO1xuXG4gIGZvciAoY29uc3Qga2V5IG9mIE1FUk1BSURfQ09ORklHX0RJQUdSQU1fS0VZUykge1xuICAgIGNvbnN0IHN1YlNjaGVtYVJlZiA9IG1lcm1haWRDb25maWdTY2hlbWEucHJvcGVydGllc1trZXldLiRyZWY7XG4gICAgY29uc3QgW3Jvb3QsIGRlZnMsIGRlZk5hbWVdID0gc3ViU2NoZW1hUmVmLnNwbGl0KCcvJyk7XG4gICAgYXNzZXJ0LnN0cmljdEVxdWFsKHJvb3QsICcjJyk7XG4gICAgYXNzZXJ0LnN0cmljdEVxdWFsKGRlZnMsICckZGVmcycpO1xuICAgIGNvbnN0IHN1YlNjaGVtYSA9IHtcbiAgICAgICRzY2hlbWE6IG1lcm1haWRDb25maWdTY2hlbWEuJHNjaGVtYSxcbiAgICAgICRkZWZzOiBtZXJtYWlkQ29uZmlnU2NoZW1hLiRkZWZzLFxuICAgICAgLi4ubWVybWFpZENvbmZpZ1NjaGVtYS4kZGVmc1tkZWZOYW1lXSxcbiAgICB9IGFzIEpTT05TY2hlbWFUeXBlPEJhc2VEaWFncmFtQ29uZmlnPjtcblxuICAgIGNvbnN0IHZhbGlkYXRlID0gYWp2LmNvbXBpbGUoc3ViU2NoZW1hKTtcblxuICAgIG1lcm1haWREZWZhdWx0Q29uZmlnW2tleV0gPSB7fTtcblxuICAgIGZvciAoY29uc3QgcmVxdWlyZWQgb2Ygc3ViU2NoZW1hLnJlcXVpcmVkID8/IFtdKSB7XG4gICAgICBpZiAoc3ViU2NoZW1hLnByb3BlcnRpZXNbcmVxdWlyZWRdID09PSB1bmRlZmluZWQgJiYgYmFzZURpYWdyYW1Db25maWcucHJvcGVydGllc1tyZXF1aXJlZF0pIHtcbiAgICAgICAgbWVybWFpZERlZmF1bHRDb25maWdba2V5XVtyZXF1aXJlZF0gPSBiYXNlRGlhZ3JhbUNvbmZpZy5wcm9wZXJ0aWVzW3JlcXVpcmVkXS5kZWZhdWx0O1xuICAgICAgfVxuICAgIH1cbiAgICBpZiAoIXZhbGlkYXRlKG1lcm1haWREZWZhdWx0Q29uZmlnW2tleV0pKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgIGBzY2hlbWEgZm9yIHN1YmNvbmZpZyAke2tleX0gZG9lcyBub3QgaGF2ZSB2YWxpZCBkZWZhdWx0cyEgRXJyb3JzIHdlcmUgJHtKU09OLnN0cmluZ2lmeShcbiAgICAgICAgICB2YWxpZGF0ZS5lcnJvcnMsXG4gICAgICAgICAgdW5kZWZpbmVkLFxuICAgICAgICAgIDJcbiAgICAgICAgKX1gXG4gICAgICApO1xuICAgIH1cbiAgfVxuXG4gIGNvbnN0IHZhbGlkYXRlID0gYWp2LmNvbXBpbGUobWVybWFpZENvbmZpZ1NjaGVtYSk7XG5cbiAgaWYgKCF2YWxpZGF0ZShtZXJtYWlkRGVmYXVsdENvbmZpZykpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICBgTWVybWFpZCBjb25maWcgSlNPTiBTY2hlbWEgZG9lcyBub3QgaGF2ZSB2YWxpZCBkZWZhdWx0cyEgRXJyb3JzIHdlcmUgJHtKU09OLnN0cmluZ2lmeShcbiAgICAgICAgdmFsaWRhdGUuZXJyb3JzLFxuICAgICAgICB1bmRlZmluZWQsXG4gICAgICAgIDJcbiAgICAgICl9YFxuICAgICk7XG4gIH1cblxuICByZXR1cm4gbWVybWFpZERlZmF1bHRDb25maWc7XG59XG5cbi8qKlxuICogVml0ZSBwbHVnaW4gdGhhdCBoYW5kbGVzIEpTT04gU2NoZW1hcyBzYXZlZCBhcyBhIGAuc2NoZW1hLnlhbWxgIGZpbGUuXG4gKlxuICogVXNlIGBteS1leGFtcGxlLnNjaGVtYS55YW1sP29ubHktZGVmYXVsdHM9dHJ1ZWAgdG8gb25seSBsb2FkIHRoZSBkZWZhdWx0IHZhbHVlcy5cbiAqL1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24ganNvblNjaGVtYVBsdWdpbigpOiBQbHVnaW5PcHRpb24ge1xuICByZXR1cm4ge1xuICAgIG5hbWU6ICdqc29uLXNjaGVtYS1wbHVnaW4nLFxuICAgIHRyYW5zZm9ybShzcmM6IHN0cmluZywgaWQ6IHN0cmluZykge1xuICAgICAgY29uc3QgaWRBc1VybCA9IG5ldyBVUkwoaWQsICdmaWxlOi8vLycpO1xuXG4gICAgICBpZiAoIWlkQXNVcmwucGF0aG5hbWUuZW5kc1dpdGgoJ3NjaGVtYS55YW1sJykpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICBpZiAoaWRBc1VybC5zZWFyY2hQYXJhbXMuZ2V0KCdvbmx5LWRlZmF1bHRzJykpIHtcbiAgICAgICAgY29uc3QganNvblNjaGVtYSA9IGxvYWQoc3JjLCB7XG4gICAgICAgICAgZmlsZW5hbWU6IGlkQXNVcmwucGF0aG5hbWUsXG4gICAgICAgICAgLy8gb25seSBhbGxvdyBKU09OIHR5cGVzIGluIG91ciBZQU1MIGRvYyAod2lsbCBwcm9iYWJseSBiZSBkZWZhdWx0IGluIFlBTUwgMS4zKVxuICAgICAgICAgIC8vIGUuZy4gYHRydWVgIHdpbGwgYmUgcGFyc2VkIGEgYm9vbGVhbiBgdHJ1ZWAsIGBUcnVlYCB3aWxsIGJlIHBhcnNlZCBhcyBzdHJpbmcgYFwiVHJ1ZVwiYC5cbiAgICAgICAgICBzY2hlbWE6IEpTT05fU0NIRU1BLFxuICAgICAgICB9KSBhcyBKU09OU2NoZW1hVHlwZTxNZXJtYWlkQ29uZmlnPjtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICBjb2RlOiBgZXhwb3J0IGRlZmF1bHQgJHtKU09OLnN0cmluZ2lmeShnZW5lcmF0ZURlZmF1bHRzKGpzb25TY2hlbWEpLCB1bmRlZmluZWQsIDIpfTtgLFxuICAgICAgICAgIG1hcDogbnVsbCwgLy8gbm8gc291cmNlIG1hcFxuICAgICAgICB9O1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICBjb2RlOiBgZXhwb3J0IGRlZmF1bHQgJHtKU09OLnN0cmluZ2lmeShcbiAgICAgICAgICAgIGxvYWQoc3JjLCB7XG4gICAgICAgICAgICAgIGZpbGVuYW1lOiBpZEFzVXJsLnBhdGhuYW1lLFxuICAgICAgICAgICAgICAvLyBvbmx5IGFsbG93IEpTT04gdHlwZXMgaW4gb3VyIFlBTUwgZG9jICh3aWxsIHByb2JhYmx5IGJlIGRlZmF1bHQgaW4gWUFNTCAxLjMpXG4gICAgICAgICAgICAgIC8vIGUuZy4gYHRydWVgIHdpbGwgYmUgcGFyc2VkIGEgYm9vbGVhbiBgdHJ1ZWAsIGBUcnVlYCB3aWxsIGJlIHBhcnNlZCBhcyBzdHJpbmcgYFwiVHJ1ZVwiYC5cbiAgICAgICAgICAgICAgc2NoZW1hOiBKU09OX1NDSEVNQSxcbiAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAgdW5kZWZpbmVkLFxuICAgICAgICAgICAgMlxuICAgICAgICAgICl9O2AsXG4gICAgICAgICAgbWFwOiBudWxsLCAvLyBwcm92aWRlIHNvdXJjZSBtYXAgaWYgYXZhaWxhYmxlXG4gICAgICAgIH07XG4gICAgICB9XG4gICAgfSxcbiAgfTtcbn1cbiIsICJjb25zdCBfX3ZpdGVfaW5qZWN0ZWRfb3JpZ2luYWxfZGlybmFtZSA9IFwiL1VzZXJzL2tuc3Yvc291cmNlL2dpdC9tZXJtYWlkXCI7Y29uc3QgX192aXRlX2luamVjdGVkX29yaWdpbmFsX2ZpbGVuYW1lID0gXCIvVXNlcnMva25zdi9zb3VyY2UvZ2l0L21lcm1haWQvdml0ZS5jb25maWcudHNcIjtjb25zdCBfX3ZpdGVfaW5qZWN0ZWRfb3JpZ2luYWxfaW1wb3J0X21ldGFfdXJsID0gXCJmaWxlOi8vL1VzZXJzL2tuc3Yvc291cmNlL2dpdC9tZXJtYWlkL3ZpdGUuY29uZmlnLnRzXCI7aW1wb3J0IGppc29uIGZyb20gJy4vLnZpdGUvamlzb25QbHVnaW4uanMnO1xuaW1wb3J0IGpzb25TY2hlbWFQbHVnaW4gZnJvbSAnLi8udml0ZS9qc29uU2NoZW1hUGx1Z2luLmpzJztcbmltcG9ydCB0eXBlc2NyaXB0IGZyb20gJ0Byb2xsdXAvcGx1Z2luLXR5cGVzY3JpcHQnO1xuaW1wb3J0IHsgZGVmaW5lQ29uZmlnIH0gZnJvbSAndml0ZXN0L2NvbmZpZyc7XG5cbmV4cG9ydCBkZWZhdWx0IGRlZmluZUNvbmZpZyh7XG4gIHJlc29sdmU6IHtcbiAgICBleHRlbnNpb25zOiBbJy5qcyddLFxuICB9LFxuICBwbHVnaW5zOiBbXG4gICAgamlzb24oKSxcbiAgICBqc29uU2NoZW1hUGx1Z2luKCksIC8vIGhhbmRsZXMgLnNjaGVtYS55YW1sIEpTT04gU2NoZW1hIGZpbGVzXG4gICAgLy8gQHRzLWV4cGVjdC1lcnJvciBBY2NvcmRpbmcgdG8gdGhlIHR5cGUgZGVmaW5pdGlvbnMsIHJvbGx1cCBwbHVnaW5zIGFyZSBpbmNvbXBhdGlibGUgd2l0aCB2aXRlXG4gICAgdHlwZXNjcmlwdCh7IGNvbXBpbGVyT3B0aW9uczogeyBkZWNsYXJhdGlvbjogZmFsc2UgfSB9KSxcbiAgXSxcbiAgdGVzdDoge1xuICAgIGVudmlyb25tZW50OiAnanNkb20nLFxuICAgIGdsb2JhbHM6IHRydWUsXG4gICAgLy8gVE9ETzogc2hvdWxkIHdlIG1vdmUgdGhpcyB0byBhIG1lcm1haWQtY29yZSBwYWNrYWdlP1xuICAgIHNldHVwRmlsZXM6IFsncGFja2FnZXMvbWVybWFpZC9zcmMvdGVzdHMvc2V0dXAudHMnXSxcbiAgICBjb3ZlcmFnZToge1xuICAgICAgcHJvdmlkZXI6ICd2OCcsXG4gICAgICByZXBvcnRlcjogWyd0ZXh0JywgJ2pzb24nLCAnaHRtbCcsICdsY292J10sXG4gICAgICByZXBvcnRzRGlyZWN0b3J5OiAnLi9jb3ZlcmFnZS92aXRlc3QnLFxuICAgICAgZXhjbHVkZTogWycqKi9ub2RlX21vZHVsZXMvKionLCAnKiovdGVzdHMvKionLCAnKiovX19tb2Nrc19fLyoqJ10sXG4gICAgfSxcbiAgfSxcbiAgYnVpbGQ6IHtcbiAgICAvKiogSWYgeW91IHNldCBlc21FeHRlcm5hbHMgdG8gdHJ1ZSwgdGhpcyBwbHVnaW5zIGFzc3VtZXMgdGhhdFxuICAgICBhbGwgZXh0ZXJuYWwgZGVwZW5kZW5jaWVzIGFyZSBFUyBtb2R1bGVzICovXG5cbiAgICBjb21tb25qc09wdGlvbnM6IHtcbiAgICAgIGVzbUV4dGVybmFsczogdHJ1ZSxcbiAgICB9LFxuICB9LFxufSk7XG4iXSwKICAibWFwcGluZ3MiOiAiO0FBQXdTLE9BQU8sV0FBVztBQUVuVCxJQUFNLGlCQUFpQixDQUFDLFFBQXdCO0FBQ3JELFFBQU0sU0FBUyxJQUFJLE1BQU0sVUFBVSxLQUFLO0FBQUEsSUFDdEMsWUFBWTtBQUFBLElBQ1osZUFBZTtBQUFBLEVBQ2pCLENBQUM7QUFDRCxRQUFNLFNBQVMsT0FBTyxTQUFTLEVBQUUsWUFBWSxXQUFXLENBQUM7QUFDekQsUUFBTSxXQUFXO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFLakIsU0FBTyxHQUFHLFVBQVU7QUFDdEI7OztBQ2JBLElBQU0sWUFBWTtBQUVILFNBQVJBLFNBQXlCO0FBQzlCLFNBQU87QUFBQSxJQUNMLE1BQU07QUFBQSxJQUVOLFVBQVUsS0FBYSxJQUFZO0FBQ2pDLFVBQUksVUFBVSxLQUFLLEVBQUUsR0FBRztBQUN0QixlQUFPO0FBQUEsVUFDTCxNQUFNLGVBQWUsR0FBRztBQUFBLFVBQ3hCLEtBQUs7QUFBQTtBQUFBLFFBQ1A7QUFBQSxNQUNGO0FBQUEsSUFDRjtBQUFBLEVBQ0Y7QUFDRjs7O0FDaEJ3UyxTQUFTLE1BQU0sbUJBQW1CO0FBQzFVLE9BQU8sWUFBWTtBQUNuQixPQUFPLGFBQXNDO0FBUTdDLElBQU0sOEJBQThCO0FBQUEsRUFDbEM7QUFBQSxFQUNBO0FBQUEsRUFDQTtBQUFBLEVBQ0E7QUFBQSxFQUNBO0FBQUEsRUFDQTtBQUFBLEVBQ0E7QUFBQSxFQUNBO0FBQUEsRUFDQTtBQUFBLEVBQ0E7QUFBQSxFQUNBO0FBQUEsRUFDQTtBQUFBLEVBQ0E7QUFBQSxFQUNBO0FBQUEsRUFDQTtBQUNGO0FBV0EsU0FBUyxpQkFBaUIscUJBQW9EO0FBQzVFLFFBQU0sTUFBTSxJQUFJLFFBQVE7QUFBQSxJQUN0QixhQUFhO0FBQUEsSUFDYixpQkFBaUI7QUFBQSxJQUNqQixRQUFRO0FBQUEsRUFDVixDQUFDO0FBRUQsTUFBSSxXQUFXO0FBQUEsSUFDYixTQUFTO0FBQUE7QUFBQSxJQUNULFFBQVE7QUFBQSxFQUNWLENBQUM7QUFDRCxNQUFJLFdBQVc7QUFBQSxJQUNiLFNBQVM7QUFBQTtBQUFBLElBQ1QsUUFBUTtBQUFBLEVBQ1YsQ0FBQztBQUlELFFBQU0sdUJBQXVCLENBQUM7QUFFOUIsU0FBTyxHQUFHLG9CQUFvQixLQUFLO0FBQ25DLFFBQU0sb0JBQW9CLG9CQUFvQixNQUFNO0FBRXBELGFBQVcsT0FBTyw2QkFBNkI7QUFDN0MsVUFBTSxlQUFlLG9CQUFvQixXQUFXLEdBQUcsRUFBRTtBQUN6RCxVQUFNLENBQUMsTUFBTSxNQUFNLE9BQU8sSUFBSSxhQUFhLE1BQU0sR0FBRztBQUNwRCxXQUFPLFlBQVksTUFBTSxHQUFHO0FBQzVCLFdBQU8sWUFBWSxNQUFNLE9BQU87QUFDaEMsVUFBTSxZQUFZO0FBQUEsTUFDaEIsU0FBUyxvQkFBb0I7QUFBQSxNQUM3QixPQUFPLG9CQUFvQjtBQUFBLE1BQzNCLEdBQUcsb0JBQW9CLE1BQU0sT0FBTztBQUFBLElBQ3RDO0FBRUEsVUFBTUMsWUFBVyxJQUFJLFFBQVEsU0FBUztBQUV0Qyx5QkFBcUIsR0FBRyxJQUFJLENBQUM7QUFFN0IsZUFBVyxZQUFZLFVBQVUsWUFBWSxDQUFDLEdBQUc7QUFDL0MsVUFBSSxVQUFVLFdBQVcsUUFBUSxNQUFNLFVBQWEsa0JBQWtCLFdBQVcsUUFBUSxHQUFHO0FBQzFGLDZCQUFxQixHQUFHLEVBQUUsUUFBUSxJQUFJLGtCQUFrQixXQUFXLFFBQVEsRUFBRTtBQUFBLE1BQy9FO0FBQUEsSUFDRjtBQUNBLFFBQUksQ0FBQ0EsVUFBUyxxQkFBcUIsR0FBRyxDQUFDLEdBQUc7QUFDeEMsWUFBTSxJQUFJO0FBQUEsUUFDUix3QkFBd0IsaURBQWlELEtBQUs7QUFBQSxVQUM1RUEsVUFBUztBQUFBLFVBQ1Q7QUFBQSxVQUNBO0FBQUEsUUFDRjtBQUFBLE1BQ0Y7QUFBQSxJQUNGO0FBQUEsRUFDRjtBQUVBLFFBQU0sV0FBVyxJQUFJLFFBQVEsbUJBQW1CO0FBRWhELE1BQUksQ0FBQyxTQUFTLG9CQUFvQixHQUFHO0FBQ25DLFVBQU0sSUFBSTtBQUFBLE1BQ1Isd0VBQXdFLEtBQUs7QUFBQSxRQUMzRSxTQUFTO0FBQUEsUUFDVDtBQUFBLFFBQ0E7QUFBQSxNQUNGO0FBQUEsSUFDRjtBQUFBLEVBQ0Y7QUFFQSxTQUFPO0FBQ1Q7QUFPZSxTQUFSLG1CQUFrRDtBQUN2RCxTQUFPO0FBQUEsSUFDTCxNQUFNO0FBQUEsSUFDTixVQUFVLEtBQWEsSUFBWTtBQUNqQyxZQUFNLFVBQVUsSUFBSSxJQUFJLElBQUksVUFBVTtBQUV0QyxVQUFJLENBQUMsUUFBUSxTQUFTLFNBQVMsYUFBYSxHQUFHO0FBQzdDO0FBQUEsTUFDRjtBQUVBLFVBQUksUUFBUSxhQUFhLElBQUksZUFBZSxHQUFHO0FBQzdDLGNBQU0sYUFBYSxLQUFLLEtBQUs7QUFBQSxVQUMzQixVQUFVLFFBQVE7QUFBQTtBQUFBO0FBQUEsVUFHbEIsUUFBUTtBQUFBLFFBQ1YsQ0FBQztBQUNELGVBQU87QUFBQSxVQUNMLE1BQU0sa0JBQWtCLEtBQUssVUFBVSxpQkFBaUIsVUFBVSxHQUFHLFFBQVcsQ0FBQztBQUFBLFVBQ2pGLEtBQUs7QUFBQTtBQUFBLFFBQ1A7QUFBQSxNQUNGLE9BQU87QUFDTCxlQUFPO0FBQUEsVUFDTCxNQUFNLGtCQUFrQixLQUFLO0FBQUEsWUFDM0IsS0FBSyxLQUFLO0FBQUEsY0FDUixVQUFVLFFBQVE7QUFBQTtBQUFBO0FBQUEsY0FHbEIsUUFBUTtBQUFBLFlBQ1YsQ0FBQztBQUFBLFlBQ0Q7QUFBQSxZQUNBO0FBQUEsVUFDRjtBQUFBLFVBQ0EsS0FBSztBQUFBO0FBQUEsUUFDUDtBQUFBLE1BQ0Y7QUFBQSxJQUNGO0FBQUEsRUFDRjtBQUNGOzs7QUNuSkEsT0FBTyxnQkFBZ0I7QUFDdkIsU0FBUyxvQkFBb0I7QUFFN0IsSUFBTyxzQkFBUSxhQUFhO0FBQUEsRUFDMUIsU0FBUztBQUFBLElBQ1AsWUFBWSxDQUFDLEtBQUs7QUFBQSxFQUNwQjtBQUFBLEVBQ0EsU0FBUztBQUFBLElBQ1BDLE9BQU07QUFBQSxJQUNOLGlCQUFpQjtBQUFBO0FBQUE7QUFBQSxJQUVqQixXQUFXLEVBQUUsaUJBQWlCLEVBQUUsYUFBYSxNQUFNLEVBQUUsQ0FBQztBQUFBLEVBQ3hEO0FBQUEsRUFDQSxNQUFNO0FBQUEsSUFDSixhQUFhO0FBQUEsSUFDYixTQUFTO0FBQUE7QUFBQSxJQUVULFlBQVksQ0FBQyxxQ0FBcUM7QUFBQSxJQUNsRCxVQUFVO0FBQUEsTUFDUixVQUFVO0FBQUEsTUFDVixVQUFVLENBQUMsUUFBUSxRQUFRLFFBQVEsTUFBTTtBQUFBLE1BQ3pDLGtCQUFrQjtBQUFBLE1BQ2xCLFNBQVMsQ0FBQyxzQkFBc0IsZUFBZSxpQkFBaUI7QUFBQSxJQUNsRTtBQUFBLEVBQ0Y7QUFBQSxFQUNBLE9BQU87QUFBQTtBQUFBO0FBQUEsSUFJTCxpQkFBaUI7QUFBQSxNQUNmLGNBQWM7QUFBQSxJQUNoQjtBQUFBLEVBQ0Y7QUFDRixDQUFDOyIsCiAgIm5hbWVzIjogWyJqaXNvbiIsICJ2YWxpZGF0ZSIsICJqaXNvbiJdCn0K
    
    From c8d155c455d95e28ee55b4a9913a8a9125f49139 Mon Sep 17 00:00:00 2001
    From: Knut Sveidqvist 
    Date: Tue, 3 Oct 2023 20:12:33 +0200
    Subject: [PATCH 019/217] #3358 Recursive positioning
    
    ---
     cypress/platform/knsv2.html                   |  27 +++-
     packages/mermaid/src/diagrams/block/layout.ts | 116 +++++++++++++++---
     2 files changed, 118 insertions(+), 25 deletions(-)
    
    diff --git a/cypress/platform/knsv2.html b/cypress/platform/knsv2.html
    index 6e69533eb6..205db1c78d 100644
    --- a/cypress/platform/knsv2.html
    +++ b/cypress/platform/knsv2.html
    @@ -65,8 +65,8 @@
       
         
     block-beta
    -  %% id1("Wide 1")
    -  id2("2")
    +  id1("Wide 1")
    +  %%id2("2")
       block
           id3["I am a wide one"]
           block
    @@ -79,9 +79,26 @@
         
     block-beta
    -
    -      id3["I am a wide one"]
    -      id4
    +  id1
    +  block
    +  id2
    +  end
    +    
    +
    +block-beta
    +  id1["Hello"]
    +  block
    +    id2["to"]
    +    id3["the"]
    +    id4["World"]
    +  end
    +    
    +
    +block-beta
    +  block
    +    id2["I am a wide one"]
    +    id1
    +  end
     
     
         
    diff --git a/packages/mermaid/src/diagrams/block/layout.ts b/packages/mermaid/src/diagrams/block/layout.ts index 8756646ef5..31810693b6 100644 --- a/packages/mermaid/src/diagrams/block/layout.ts +++ b/packages/mermaid/src/diagrams/block/layout.ts @@ -1,12 +1,14 @@ import { BlockDB } from './blockDB.js'; import type { Block } from './blockTypes.js'; +const padding = 10; + function calcBlockSizes(block: Block, db: BlockDB) { + console.log('calculateSize (start)', block.id, block?.size?.x, block?.size?.width); const totalWidth = 0; const totalHeight = 0; let maxWidth = 0; let maxHeight = 0; - const padding = 20; if (block.children) { for (const child of block.children) { @@ -15,6 +17,7 @@ function calcBlockSizes(block: Block, db: BlockDB) { // find max width of children for (const child of block.children) { const { width, height, x, y } = child.size || { width: 0, height: 0, x: 0, y: 0 }; + // console.log('APA', child.id, width, height, x, y); if (width > maxWidth) { maxWidth = width; } @@ -28,22 +31,24 @@ function calcBlockSizes(block: Block, db: BlockDB) { if (child.size) { child.size.width = maxWidth; child.size.height = maxHeight; + child.size.x = 0; + child.size.y = 0; } } - // Position items relative to self - let x = -padding / 2; - const y = 0; + // // Position items relative to self + // let x = -padding / 2; + // const y = 0; - let accumulatedPaddingX = 0; - for (const child of block.children) { - if (child.size) { - child.size.x = x; - child.size.y = y; - x += maxWidth + padding; - } - accumulatedPaddingX += padding; - } + // let accumulatedPaddingX = 0; + // for (const child of block.children) { + // if (child.size) { + // child.size.x = x; + // child.size.y = y; + // x += maxWidth + padding; + // } + // accumulatedPaddingX += padding; + // } } if (block.children?.length > 0) { const numChildren = block.children.length; @@ -54,19 +59,88 @@ function calcBlockSizes(block: Block, db: BlockDB) { y: 0, }; } - console.log('layoutBlock (done)', block); + console.log('calculateSize APA (done)', block.id, block.size.x, block.size.width); +} + +function layoutBlocks(block: Block, db: BlockDB) { + console.log('layout blocks (block)', block.id, 'x:', block.size.x, 'width:', block.size.width); + if ( + block.children && // find max width of children + block.children.length > 0 + ) { + const width = block?.children[0]?.size?.width || 0; + const widthOfChildren = block.children.length * width + (block.children.length - 1) * padding; + let posX = (block?.size?.x || 0) - widthOfChildren / 2; + const posY = 0; + const parentX = block?.size?.x || 0 - block.children.length; + const parentWidth = block?.size?.width || 0; + + console.log('widthOfChildren', widthOfChildren, 'posX', posX, 'parentX', parentX); + + // let first = true; + for (const child of block.children) { + console.log( + 'layout blocks (child)', + child.id, + 'x:', + child?.size?.x, + 'width:', + child?.size?.width, + 'posX:', + posX, + block?.size?.x, + widthOfChildren / 2, + widthOfChildren / 2 + ); + + if (!child.size) { + continue; + } + const { width, height } = child.size; + child.size.x = posX + width / 2; + posX += width + padding; + child.size.y = posY; + // posY += height + padding; + if (child.children) { + layoutBlocks(child, db); + } + } + } } function positionBlock(parent: Block, block: Block, db: BlockDB) { - console.log('layout position block', parent.id, parent?.size?.x, block.id, block?.size?.x); + console.log( + 'layout position block', + parent.id, + parent?.size?.x, + block.id, + block?.size?.x, + 'width:', + block?.size?.width + ); let parentX = 0; + let parentWidth = 0; let y = 0; - if (parent) { + if (parent.id !== 'root') { parentX = parent?.size?.x || 0; + parentWidth = parent?.size?.width || 0; y = parent?.size?.y || 0; } if (block.size && block.id !== 'root') { - block.size.x = parentX + block.size.x + -block.size.width / 2; + console.log( + 'layout position block (calc)', + 'x:', + parentX, + parentWidth / 2, + block.id, + 'x:', + block.size.x, + block.size.width + ); + // block.size.x = parentX + block.size.x + -block.size.width / 2; + block.size.x = + parentX < 0 ? parentX + block.size.x : parentX + block.size.x + -block.size.width / 2; + // block.size.x = parentX - parentWidth + Math.abs(block.size.x) / 2; block.size.y = block.size.y + y; } if (block.children) { @@ -82,10 +156,11 @@ let maxX = 0; let maxY = 0; function findBounds(block: Block) { - if (block.size) { + if (block.size && block.id !== 'root') { const { x, y, width, height } = block.size; if (x - width / 2 < minX) { minX = x - width / 2; + // console.log('Here APA minX', block.id, x, width, minX); } if (y - height / 2 < minY) { minY = y - height / 2; @@ -108,8 +183,9 @@ export function layout(db: BlockDB) { const blocks = db.getBlocks(); const root = { id: 'root', type: 'composite', children: blocks } as Block; calcBlockSizes(root, db); + layoutBlocks(root, db); // Position blocks relative to parents - positionBlock(root, root, db); + // positionBlock(root, root, db); console.log('getBlocks', JSON.stringify(db.getBlocks(), null, 2)); minX = 0; @@ -117,7 +193,7 @@ export function layout(db: BlockDB) { maxX = 0; maxY = 0; findBounds(root); - console.log('Here maxX', maxX); + // console.log('Here maxX', minX, '--', maxX); const height = maxY - minY; const width = maxX - minX; return { x: minX, y: minY, width, height }; From da79b371fe1d45a36637dec21d2ab3781079b6d8 Mon Sep 17 00:00:00 2001 From: Knut Sveidqvist Date: Wed, 4 Oct 2023 10:44:29 +0200 Subject: [PATCH 020/217] #3358 Recursive positioning paddings --- cypress/platform/knsv2.html | 7 ++++++- packages/mermaid/src/diagrams/block/layout.ts | 2 +- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/cypress/platform/knsv2.html b/cypress/platform/knsv2.html index 205db1c78d..fb68469a57 100644 --- a/cypress/platform/knsv2.html +++ b/cypress/platform/knsv2.html @@ -77,6 +77,7 @@ id4("Another final one")
    +
     block-beta
       id1
    @@ -88,17 +89,21 @@
     block-beta
       id1["Hello"]
       block
    +    columns 2
         id2["to"]
         id3["the"]
         id4["World"]
    +    id5["World"]
       end
         
    -
    +    
     block-beta
    +  columns 2
       block
         id2["I am a wide one"]
         id1
       end
    +  id[Next row]
     
     
         
    diff --git a/packages/mermaid/src/diagrams/block/layout.ts b/packages/mermaid/src/diagrams/block/layout.ts index 31810693b6..9c9b1bd7e9 100644 --- a/packages/mermaid/src/diagrams/block/layout.ts +++ b/packages/mermaid/src/diagrams/block/layout.ts @@ -54,7 +54,7 @@ function calcBlockSizes(block: Block, db: BlockDB) { const numChildren = block.children.length; block.size = { width: numChildren * (maxWidth + padding) + padding, - height: totalHeight + 4 * padding, + height: maxHeight + 2 * padding, x: 0, y: 0, }; From a641fd51e8c06ba313dd4272ea6a799b9ed0f49a Mon Sep 17 00:00:00 2001 From: Knut Sveidqvist Date: Sun, 15 Oct 2023 22:21:25 +0200 Subject: [PATCH 021/217] #3358 Adding support for column statements --- cypress/platform/knsv2.html | 59 +++-- .../mermaid/src/diagrams/block/blockDB.ts | 13 +- .../src/diagrams/block/blockRenderer.ts | 119 ++-------- .../mermaid/src/diagrams/block/blockTypes.ts | 1 + .../mermaid/src/diagrams/block/layout.spec.ts | 13 ++ packages/mermaid/src/diagrams/block/layout.ts | 203 ++++++++++++------ .../src/diagrams/block/renderHelpers.ts | 23 +- 7 files changed, 223 insertions(+), 208 deletions(-) create mode 100644 packages/mermaid/src/diagrams/block/layout.spec.ts diff --git a/cypress/platform/knsv2.html b/cypress/platform/knsv2.html index fb68469a57..0325eb659e 100644 --- a/cypress/platform/knsv2.html +++ b/cypress/platform/knsv2.html @@ -65,27 +65,62 @@
     block-beta
    -  id1("Wide 1")
    -  %%id2("2")
       block
    -      id3["I am a wide one"]
    -      block
    -        id44("A final one")
    -        id45("B final one")
    -      end
    +  columns 1
    +    id1
    +    id2
    +    id3("Wider then")
       end
    -  id4("Another final one")
    -
    +  id4
         
    -
    +    
    +block-beta
    +  block
    +  columns 1
    +  block
    +    columns 3
    +    id1
    +    id2
    +    id2.1
    +    %%id2.2
    +  end
    +  id48
    +  end
    +  id3
    +%%  id3
    +%%  id4
    +  %% block
    +    %% columns 2
    +    %% id2
    +    %% id3
    +  %% end
    +    
    +
    +block-beta
    +  block
    +    columns 1
    +    id1
    +    id2
    +    %%id2.1
    +  end
    +  id3
    +%%  id3
    +%%  id4
    +  %% block
    +    %% columns 2
    +    %% id2
    +    %% id3
    +  %% end
    +    
    +
     block-beta
       id1
       block
       id2
       end
         
    -
    +    
     block-beta
       id1["Hello"]
       block
    @@ -96,7 +131,7 @@
         id5["World"]
       end
         
    -
    +    
     block-beta
       columns 2
       block
    diff --git a/packages/mermaid/src/diagrams/block/blockDB.ts b/packages/mermaid/src/diagrams/block/blockDB.ts
    index 2dce9e323e..f9578a4e78 100644
    --- a/packages/mermaid/src/diagrams/block/blockDB.ts
    +++ b/packages/mermaid/src/diagrams/block/blockDB.ts
    @@ -1,9 +1,8 @@
     // import type { BlockDB } from './blockTypes.js';
     import type { DiagramDB } from '../../diagram-api/types.js';
    -import { BlockConfig, BlockType, Block, Link } from './blockTypes.js';
    +import type { BlockConfig, BlockType, Block, Link } from './blockTypes.js';
     
     import * as configApi from '../../config.js';
    -// import common from '../common/common.js';
     import {
       // setAccTitle,
       // getAccTitle,
    @@ -37,9 +36,8 @@ const populateBlockDatabase = (blockList: Block[], parent: Block): void => {
           if (block.children) {
             populateBlockDatabase(block.children, block);
           }
    -      if (block.type !== 'column-setting') {
    -        children.push(block);
    -      }
    +
    +      children.push(block);
         }
       }
       parent.children = children;
    @@ -79,9 +77,10 @@ export const generateId = () => {
     
     type ISetHierarchy = (block: Block[]) => void;
     const setHierarchy = (block: Block[]): void => {
    +  rootBlock.children = block;
       populateBlockDatabase(block, rootBlock);
    -  log.debug('The hierarchy', JSON.stringify(block, null, 2));
    -  blocks = block;
    +  log.debug('The hierarchy', JSON.stringify(rootBlock, null, 2));
    +  blocks = rootBlock.children;
     };
     
     type IAddLink = (link: Link) => Link;
    diff --git a/packages/mermaid/src/diagrams/block/blockRenderer.ts b/packages/mermaid/src/diagrams/block/blockRenderer.ts
    index a8bf1fe49a..2b691358cc 100644
    --- a/packages/mermaid/src/diagrams/block/blockRenderer.ts
    +++ b/packages/mermaid/src/diagrams/block/blockRenderer.ts
    @@ -7,16 +7,14 @@ import {
       select as d3select,
       scaleOrdinal as d3scaleOrdinal,
       schemeTableau10 as d3schemeTableau10,
    -  ContainerElement,
     } from 'd3';
    +import { log } from '../../logger.js';
     
     import { BlockDB } from './blockDB.js';
     import type { Block } from './blockTypes.js';
     
     // import { diagram as BlockDiagram } from './blockDiagram.js';
     import { configureSvgSize } from '../../setupGraphViewbox.js';
    -import { Uid } from '../../rendering-util/uid.js';
    -import { pad } from 'lodash';
     
     export const draw = async function (
       text: string,
    @@ -43,27 +41,28 @@ export const draw = async function (
       const nodes = svg.insert('g').attr('class', 'block');
       await calculateBlockSizes(nodes, bl, db);
       const bounds = layout(db);
    -  console.log('Here blocks', bl);
    +  log.debug('Here blocks', bl);
       await insertBlocks(nodes, bl, db);
     
    -  // console.log('Here', bl);
    +  // log.debug('Here', bl);
     
       // Establish svg dimensions and get width and height
       //
       // const bounds2 = nodes.node().getBoundingClientRect();
    -  const bounds2 = bounds;
    -  const padding = 10;
       // Why, oh why ????
    -  const magicFactor = Math.max(1, Math.round(0.125 * (bounds2.width / bounds2.height)));
    -  const height = bounds2.height + magicFactor + 10;
    -  const width = bounds2.width + 10;
    -  const useMaxWidth = false;
    -  configureSvgSize(svg, height, width, useMaxWidth);
    -  console.log('Here Bounds', bounds, bounds2);
    -  svg.attr(
    -    'viewBox',
    -    `${bounds2.x - 5} ${bounds2.y - 5} ${bounds2.width + 10} ${bounds2.height + 10}`
    -  );
    +  if (bounds) {
    +    const bounds2 = bounds;
    +    const magicFactor = Math.max(1, Math.round(0.125 * (bounds2.width / bounds2.height)));
    +    const height = bounds2.height + magicFactor + 10;
    +    const width = bounds2.width + 10;
    +    const useMaxWidth = false;
    +    configureSvgSize(svg, height, width, useMaxWidth);
    +    log.debug('Here Bounds', bounds, bounds2);
    +    svg.attr(
    +      'viewBox',
    +      `${bounds2.x - 5} ${bounds2.y - 5} ${bounds2.width + 10} ${bounds2.height + 10}`
    +    );
    +  }
       // svg.attr('viewBox', `${-200} ${-200} ${400} ${400}`);
     
       // Prepare data for construction based on diagObj.db
    @@ -83,92 +82,6 @@ export const draw = async function (
         y?: number;
       }
     
    -  const blocks: LayedBlock[] = [
    -    {
    -      ID: 'ApplicationLayer',
    -      label: 'Application Layer',
    -      x: 0,
    -      y: 0,
    -      children: [
    -        {
    -          ID: 'UserInterface',
    -          label: 'User Interface (WPF, HTML5/CSS3, Swing)',
    -          x: 0,
    -          y: 50,
    -        },
    -      ],
    -    },
    -    {
    -      ID: 'PresentationLayer',
    -      label: 'Presentation Layer',
    -      x: 0,
    -      y: 50,
    -      children: [
    -        {
    -          ID: 'Smack',
    -          label: 'J2SE Mobil App (Smack)',
    -        },
    -        {
    -          ID: 'JsJAC',
    -          label: 'Java Script Browser App (JsJAC)',
    -        },
    -        {
    -          ID: 'babelim',
    -          label: '.NET Windows App (Babel-im)',
    -        },
    -      ],
    -    },
    -    {
    -      ID: 'SessionLayer',
    -      label: 'Session Layer',
    -      x: 0,
    -      y: 100,
    -      children: [
    -        {
    -          ID: 'XMPP',
    -          label: 'XMPP Component',
    -        },
    -        {
    -          children: [
    -            {
    -              ID: 'Authentication',
    -              label: 'Authentication',
    -            },
    -            {
    -              ID: 'Authorization',
    -              label: 'Authorization',
    -            },
    -          ],
    -        },
    -        {
    -          ID: 'LDAP',
    -          label: 'LDAP, DB, POP',
    -        },
    -      ],
    -    },
    -    {
    -      ID: 'NetworkLayer',
    -      label: 'Network Layer',
    -      x: 0,
    -      y: 150,
    -      children: [
    -        { ID: 'HTTP', label: 'HTTP' },
    -        { ID: 'SOCK', label: 'SOCK' },
    -      ],
    -    },
    -    {
    -      ID: 'DataLayer',
    -      label: 'Data Layer',
    -      x: 0,
    -      y: 200,
    -      children: [
    -        { ID: 'XMPP', label: 'XMPP' },
    -        { ID: 'BDB', label: 'Business DB' },
    -        { ID: 'AD', label: 'Active Directory' },
    -      ],
    -    },
    -  ];
    -
       // Get color scheme for the graph
       const colorScheme = d3scaleOrdinal(d3schemeTableau10);
     };
    diff --git a/packages/mermaid/src/diagrams/block/blockTypes.ts b/packages/mermaid/src/diagrams/block/blockTypes.ts
    index 5a4431c0ae..f26d83fcc7 100644
    --- a/packages/mermaid/src/diagrams/block/blockTypes.ts
    +++ b/packages/mermaid/src/diagrams/block/blockTypes.ts
    @@ -39,6 +39,7 @@ export interface Block {
       };
       node?: any;
       columns?: number; // | TBlockColumnsDefaultValue;
    +  classes?: string[];
     }
     
     export interface Link {
    diff --git a/packages/mermaid/src/diagrams/block/layout.spec.ts b/packages/mermaid/src/diagrams/block/layout.spec.ts
    new file mode 100644
    index 0000000000..1de79c880c
    --- /dev/null
    +++ b/packages/mermaid/src/diagrams/block/layout.spec.ts
    @@ -0,0 +1,13 @@
    +// @ts-ignore: jison doesn't export types
    +import { calculateBlockPosition } from './layout.js';
    +
    +describe('Layout', function () {
    +  it('It shoud calulatepositions correctly', () => {
    +    expect(calculateBlockPosition(2, 0)).toEqual({ px: 0, py: 0 });
    +    expect(calculateBlockPosition(2, 1)).toEqual({ px: 1, py: 0 });
    +    expect(calculateBlockPosition(2, 2)).toEqual({ px: 0, py: 1 });
    +    expect(calculateBlockPosition(2, 3)).toEqual({ px: 1, py: 1 });
    +    expect(calculateBlockPosition(2, 4)).toEqual({ px: 0, py: 2 });
    +    expect(calculateBlockPosition(1, 3)).toEqual({ px: 0, py: 2 });
    +  });
    +});
    diff --git a/packages/mermaid/src/diagrams/block/layout.ts b/packages/mermaid/src/diagrams/block/layout.ts
    index 9c9b1bd7e9..741445806e 100644
    --- a/packages/mermaid/src/diagrams/block/layout.ts
    +++ b/packages/mermaid/src/diagrams/block/layout.ts
    @@ -1,10 +1,41 @@
     import { BlockDB } from './blockDB.js';
     import type { Block } from './blockTypes.js';
    +import { log } from '../../logger.js';
    +const padding = 8;
     
    -const padding = 10;
    +interface BlockPosition {
    +  px: number;
    +  py: number;
    +}
    +
    +export function calculateBlockPosition(columns: number, position: number): BlockPosition {
    +  // Ensure that columns is a positive integer
    +  if (columns === 0 || !Number.isInteger(columns)) {
    +    throw new Error('Columns must be an integer !== 0.');
    +  }
    +
    +  // Ensure that position is a non-negative integer
    +  if (position < 0 || !Number.isInteger(position)) {
    +    throw new Error('Position must be a non-negative integer.');
    +  }
    +
    +  if (columns < 0) {
    +    // Auto coulumns is set
    +    return { px: position, py: 0 };
    +  }
    +  if (columns === 1) {
    +    // Auto coulumns is set
    +    return { px: 0, py: position };
    +  }
    +  // Calculate posX and posY
    +  const px = position % columns;
    +  const py = Math.floor(position / columns);
    +
    +  return { px, py };
    +}
     
     function calcBlockSizes(block: Block, db: BlockDB) {
    -  console.log('calculateSize (start)', block.id, block?.size?.x, block?.size?.width);
    +  log.debug('calculateSize (start)', block.id, block?.size?.x, block?.size?.width);
       const totalWidth = 0;
       const totalHeight = 0;
       let maxWidth = 0;
    @@ -17,7 +48,7 @@ function calcBlockSizes(block: Block, db: BlockDB) {
         // find max width of children
         for (const child of block.children) {
           const { width, height, x, y } = child.size || { width: 0, height: 0, x: 0, y: 0 };
    -      // console.log('APA', child.id, width, height, x, y);
    +      // log.debug('APA', child.id, width, height, x, y);
           if (width > maxWidth) {
             maxWidth = width;
           }
    @@ -51,105 +82,133 @@ function calcBlockSizes(block: Block, db: BlockDB) {
         // }
       }
       if (block.children?.length > 0) {
    +    const columns = block.columns || -1;
    +    const numItems = block.children.length;
    +
    +    // The width and height in number blocks
    +    let xSize = block.children?.length;
    +    if (columns > 0 && columns < numItems) {
    +      xSize = columns;
    +    }
    +    const ySize = Math.ceil(numItems / xSize);
    +
    +    log.debug(
    +      '(calc)',
    +      block.id,
    +      'xSize',
    +      xSize,
    +      'ySize',
    +      ySize,
    +      'columns',
    +      columns,
    +      block.children.length
    +    );
    +
         const numChildren = block.children.length;
         block.size = {
    -      width: numChildren * (maxWidth + padding) + padding,
    -      height: maxHeight + 2 * padding,
    +      // width: numChildren * (maxWidth + padding) + padding,
    +      width: xSize * (maxWidth + padding) + padding,
    +      // height: maxHeight + 2 * padding,
    +      height: ySize * (maxHeight + padding) + padding,
           x: 0,
           y: 0,
         };
       }
    -  console.log('calculateSize APA (done)', block.id, block.size.x, block.size.width);
    +  log.debug('calculateSize APA (done)', block.id, block?.size?.x, block?.size?.width);
     }
     
     function layoutBlocks(block: Block, db: BlockDB) {
    -  console.log('layout blocks (block)', block.id, 'x:', block.size.x, 'width:', block.size.width);
    +  log.debug(
    +    'layout blocks (=>layoutBlocks)',
    +    block.id,
    +    'x:',
    +    block?.size?.x,
    +    'width:',
    +    block?.size?.width
    +  );
    +  const columns = block.columns || -1;
    +  log.debug('layoutBlocks columns', block.id, '=>', columns);
       if (
         block.children && // find max width of children
         block.children.length > 0
       ) {
         const width = block?.children[0]?.size?.width || 0;
         const widthOfChildren = block.children.length * width + (block.children.length - 1) * padding;
    -    let posX = (block?.size?.x || 0) - widthOfChildren / 2;
    -    const posY = 0;
    -    const parentX = block?.size?.x || 0 - block.children.length;
    -    const parentWidth = block?.size?.width || 0;
     
    -    console.log('widthOfChildren', widthOfChildren, 'posX', posX, 'parentX', parentX);
    +    log.debug('widthOfChildren', widthOfChildren, 'posX');
     
         // let first = true;
    +    let columnPos = -1;
         for (const child of block.children) {
    -      console.log(
    -        'layout blocks (child)',
    -        child.id,
    -        'x:',
    -        child?.size?.x,
    -        'width:',
    -        child?.size?.width,
    -        'posX:',
    -        posX,
    -        block?.size?.x,
    -        widthOfChildren / 2,
    -        widthOfChildren / 2
    -      );
    +      columnPos++;
    +
    +      // log.debug(
    +      //   'layout blocks (child)',
    +      //   child.id,
    +      //   'x:',
    +      //   child?.size?.x,
    +      //   'width:',
    +      //   child?.size?.width,
    +      //   'posX:',
    +      //   posX,
    +      //   block?.size?.x,
    +      //   widthOfChildren / 2,
    +      //   widthOfChildren / 2
    +      // );
     
           if (!child.size) {
             continue;
           }
           const { width, height } = child.size;
    -      child.size.x = posX + width / 2;
    -      posX += width + padding;
    -      child.size.y = posY;
    +      const { px, py } = calculateBlockPosition(columns, columnPos);
    +      log.debug(
    +        'layout blocks (child) px, py (',
    +        block?.size?.x,
    +        ',',
    +        block?.size?.y,
    +        ')',
    +        'parent:',
    +        block.id,
    +        width / 2,
    +        padding
    +      );
    +      if (block.size) {
    +        child.size.x =
    +          block.size.x - block.size.width / 2 + px * (width + padding) + width / 2 + padding;
    +        // child.size.x = px * (width + padding) - block.size.width / 2;
    +        // posX += width + padding;
    +        // child.size.y = py * (height + padding) + height / 2 + padding;
    +        child.size.y =
    +          block.size.y - block.size.height / 2 + py * (height + padding) + height / 2 + padding;
    +
    +        log.debug(
    +          'layout blocks (calc) px, py',
    +          'id:',
    +          child.id,
    +          '=>',
    +          'x:',
    +          child.size.x,
    +          'y:',
    +          child.size.y
    +        );
    +      }
    +
           // posY += height + padding;
           if (child.children) {
             layoutBlocks(child, db);
           }
         }
       }
    -}
    -
    -function positionBlock(parent: Block, block: Block, db: BlockDB) {
    -  console.log(
    -    'layout position block',
    -    parent.id,
    -    parent?.size?.x,
    +  log.debug(
    +    'layout blocks (<==layoutBlocks)',
         block.id,
    +    'x:',
         block?.size?.x,
         'width:',
         block?.size?.width
       );
    -  let parentX = 0;
    -  let parentWidth = 0;
    -  let y = 0;
    -  if (parent.id !== 'root') {
    -    parentX = parent?.size?.x || 0;
    -    parentWidth = parent?.size?.width || 0;
    -    y = parent?.size?.y || 0;
    -  }
    -  if (block.size && block.id !== 'root') {
    -    console.log(
    -      'layout position block (calc)',
    -      'x:',
    -      parentX,
    -      parentWidth / 2,
    -      block.id,
    -      'x:',
    -      block.size.x,
    -      block.size.width
    -    );
    -    // block.size.x = parentX + block.size.x + -block.size.width / 2;
    -    block.size.x =
    -      parentX < 0 ? parentX + block.size.x : parentX + block.size.x + -block.size.width / 2;
    -    // block.size.x = parentX - parentWidth + Math.abs(block.size.x) / 2;
    -    block.size.y = block.size.y + y;
    -  }
    -  if (block.children) {
    -    for (const child of block.children) {
    -      positionBlock(block, child, db);
    -    }
    -  }
    -  // console.log('layout position block', block);
     }
    +
     let minX = 0;
     let minY = 0;
     let maxX = 0;
    @@ -160,7 +219,7 @@ function findBounds(block: Block) {
         const { x, y, width, height } = block.size;
         if (x - width / 2 < minX) {
           minX = x - width / 2;
    -      // console.log('Here APA minX', block.id, x, width, minX);
    +      // log.debug('Here APA minX', block.id, x, width, minX);
         }
         if (y - height / 2 < minY) {
           minY = y - height / 2;
    @@ -180,20 +239,22 @@ function findBounds(block: Block) {
     }
     
     export function layout(db: BlockDB) {
    -  const blocks = db.getBlocks();
    -  const root = { id: 'root', type: 'composite', children: blocks } as Block;
    +  const root = db.getBlock('root');
    +  if (!root) {
    +    return;
    +  }
       calcBlockSizes(root, db);
       layoutBlocks(root, db);
       // Position blocks relative to parents
       // positionBlock(root, root, db);
    -  console.log('getBlocks', JSON.stringify(db.getBlocks(), null, 2));
    +  log.debug('getBlocks', JSON.stringify(root, null, 2));
     
       minX = 0;
       minY = 0;
       maxX = 0;
       maxY = 0;
       findBounds(root);
    -  // console.log('Here maxX', minX, '--', maxX);
    +  // log.debug('Here maxX', minX, '--', maxX);
       const height = maxY - minY;
       const width = maxX - minX;
       return { x: minX, y: minY, width, height };
    diff --git a/packages/mermaid/src/diagrams/block/renderHelpers.ts b/packages/mermaid/src/diagrams/block/renderHelpers.ts
    index 5bbe279e7f..04832d97fb 100644
    --- a/packages/mermaid/src/diagrams/block/renderHelpers.ts
    +++ b/packages/mermaid/src/diagrams/block/renderHelpers.ts
    @@ -5,28 +5,23 @@ import { ContainerElement } from 'd3';
     import type { Block } from './blockTypes.js';
     import { BlockDB } from './blockDB.js';
     
    +interface Node {
    +  classes: string;
    +}
    +
     function getNodeFromBlock(block: Block, db: BlockDB, positioned = false) {
       const vertex = block;
     
    -  /**
    -   * Variable for storing the classes for the vertex
    -   *
    -   * @type {string}
    -   */
       let classStr = 'default';
    -  if ((vertex?.classes?.length || []) > 0) {
    -    classStr = vertex.classes.join(' ');
    +  if ((vertex?.classes?.length || 0) > 0) {
    +    classStr = (vertex?.classes || []).join(' ');
       }
       classStr = classStr + ' flowchart-label';
     
       // We create a SVG label, either by delegating to addHtmlLabel or manually
    -  let vertexNode;
    -  const labelData = { width: 0, height: 0 };
    -
       let radious = 0;
       let _shape = '';
       let layoutOptions = {};
    -  console.log('This is the type:', vertex.type);
       // Set the shape based parameters
       switch (vertex.type) {
         case 'round':
    @@ -140,20 +135,18 @@ async function calculateBlockSize(elem: any, block: any, db: any) {
       const boundingBox = nodeEl.node().getBBox();
       const obj = db.getBlock(node.id);
       obj.size = { width: boundingBox.width, height: boundingBox.height, x: 0, y: 0, node: nodeEl };
    -  console.log('Here boundsíng', boundingBox.width);
       db.setBlock(obj);
       nodeEl.remove();
     }
     
     export async function insertBlockPositioned(elem: any, block: any, db: any) {
    -  console.log('Here insertBlockPositioned');
       const node = getNodeFromBlock(block, db, true);
       // if (node.type === 'composite') {
       //   return;
       // }
       // Add the element to the DOM to size it
    -  const obj = db.getBlock(node.id);
    -  const nodeEl = await insertNode(elem, node);
    +  // const obj = db.getBlock(node.id);
    +  // const nodeEl = await insertNode(elem, node);
       positionNode(node);
     }
     
    
    From 74a9e86e747de8ebf93a149428a806a442dc746f Mon Sep 17 00:00:00 2001
    From: Knut Sveidqvist 
    Date: Sun, 15 Oct 2023 22:55:29 +0200
    Subject: [PATCH 022/217] #3358 Putting the elements back in
    
    ---
     packages/mermaid/src/diagrams/block/renderHelpers.ts | 4 ++--
     1 file changed, 2 insertions(+), 2 deletions(-)
    
    diff --git a/packages/mermaid/src/diagrams/block/renderHelpers.ts b/packages/mermaid/src/diagrams/block/renderHelpers.ts
    index 04832d97fb..7c1f7c6f92 100644
    --- a/packages/mermaid/src/diagrams/block/renderHelpers.ts
    +++ b/packages/mermaid/src/diagrams/block/renderHelpers.ts
    @@ -145,8 +145,8 @@ export async function insertBlockPositioned(elem: any, block: any, db: any) {
       //   return;
       // }
       // Add the element to the DOM to size it
    -  // const obj = db.getBlock(node.id);
    -  // const nodeEl = await insertNode(elem, node);
    +  const obj = db.getBlock(node.id);
    +  const nodeEl = await insertNode(elem, node);
       positionNode(node);
     }
     
    
    From 5619f8771bd40db0f07045b47345d717a5b87b00 Mon Sep 17 00:00:00 2001
    From: Knut Sveidqvist 
    Date: Fri, 20 Oct 2023 12:13:49 +0200
    Subject: [PATCH 023/217] #3358 Adding support for space blocks and different
     shapes
    
    ---
     cypress/platform/knsv2.html | 49 +++++++++++++++++++++++++++----------
     1 file changed, 36 insertions(+), 13 deletions(-)
    
    diff --git a/cypress/platform/knsv2.html b/cypress/platform/knsv2.html
    index 0325eb659e..6d5c9846b6 100644
    --- a/cypress/platform/knsv2.html
    +++ b/cypress/platform/knsv2.html
    @@ -27,7 +27,6 @@
           .mermaid {
             border: 1px solid #ddd;
             margin: 10px;
    -        background: pink;
           }
           .mermaid2 {
             display: none;
    @@ -40,7 +39,7 @@
             background-size: 20px 20px;
             background-position: 0 0, 10px 10px;
             background-repeat: repeat;
    -        border: 1px solid red;
    +        border: 2px solid rgb(131, 142, 205);
           }
           .malware {
             position: fixed;
    @@ -63,29 +62,53 @@
         
       
       
    -    
    +    
     block-beta
       block
    +    id3("Wider then")
    +  end
    +    
    +
    +block-beta
    +    columns 3
    +    space:2
    +    id1("Wider then")
    +    space:9
    +    space
    +    id2{{"Wider then"}}
    +    space
    +    id3("Wider then")
    +    space
    +    space
    +    
    +
    +block-beta
       columns 1
    +  block
         id1
         id2
    -    id3("Wider then")
    +    block
    +      columns 1
    +      id3("Wider then")
    +      id5(("id5"))
    +    end
       end
       id4
         
     block-beta
    -  block
       columns 1
       block
    -    columns 3
    -    id1
    -    id2
    -    id2.1
    -    %%id2.2
    -  end
    -  id48
    +    columns 1
    +    block
    +      columns 3
    +      id1
    +      id2
    +      id2.1(("XYZ"))
    +      %%id2.2
    +    end
    +    id48
       end
       id3
     %%  id3
    @@ -124,7 +147,7 @@
     block-beta
       id1["Hello"]
       block
    -    columns 2
    +    columns 3
         id2["to"]
         id3["the"]
         id4["World"]
    
    From f3f25c7874d879b7d607d63abef481e8c1b591fc Mon Sep 17 00:00:00 2001
    From: Knut Sveidqvist 
    Date: Fri, 20 Oct 2023 12:30:25 +0200
    Subject: [PATCH 024/217] #3358 Adding support for space blocks and different
     shapes
    
    ---
     packages/mermaid/src/dagre-wrapper/nodes.js   |  2 -
     .../mermaid/src/diagrams/block/blockDB.ts     | 38 ++++++++++++++++++-
     packages/mermaid/src/diagrams/block/layout.ts |  3 --
     .../src/diagrams/block/parser/block.jison     | 10 ++++-
     .../src/diagrams/block/parser/block.spec.ts   | 10 ++---
     .../src/diagrams/block/renderHelpers.ts       | 18 ++++++---
     6 files changed, 63 insertions(+), 18 deletions(-)
    
    diff --git a/packages/mermaid/src/dagre-wrapper/nodes.js b/packages/mermaid/src/dagre-wrapper/nodes.js
    index b95265f311..78bcfea999 100644
    --- a/packages/mermaid/src/dagre-wrapper/nodes.js
    +++ b/packages/mermaid/src/dagre-wrapper/nodes.js
    @@ -358,7 +358,6 @@ const rect = async (parent, node) => {
     };
     
     const composite = async (parent, node) => {
    -  console.log('This got called');
       const { shapeSvg, bbox, halfPadding } = await labelHelper(
         parent,
         node,
    @@ -1075,7 +1074,6 @@ export const clear = () => {
     };
     
     export const positionNode = (node) => {
    -  console.log('Node id = ', node.id);
       const el = nodeElems[node.id];
       log.trace(
         'Transforming node',
    diff --git a/packages/mermaid/src/diagrams/block/blockDB.ts b/packages/mermaid/src/diagrams/block/blockDB.ts
    index f9578a4e78..6b787009d9 100644
    --- a/packages/mermaid/src/diagrams/block/blockDB.ts
    +++ b/packages/mermaid/src/diagrams/block/blockDB.ts
    @@ -13,6 +13,7 @@ import {
       clear as commonClear,
     } from '../../commonDb.js';
     import { log } from '../../logger.js';
    +import clone from 'lodash-es/clone.js';
     
     // Initialize the node database for simple lookups
     let blockDatabase: Record = {};
    @@ -37,7 +38,16 @@ const populateBlockDatabase = (blockList: Block[], parent: Block): void => {
             populateBlockDatabase(block.children, block);
           }
     
    -      children.push(block);
    +      if (block.type === 'space') {
    +        for (let j = 0; j < block.width; j++) {
    +          const newBlock = clone(block);
    +          newBlock.id = newBlock.id + '-' + j;
    +          blockDatabase[newBlock.id] = newBlock;
    +          children.push(newBlock);
    +        }
    +      } else {
    +        children.push(block);
    +      }
         }
       }
       parent.children = children;
    @@ -57,12 +67,38 @@ const clear = (): void => {
     
     type ITypeStr2Type = (typeStr: string) => BlockType;
     export function typeStr2Type(typeStr: string) {
    +  log.debug('typeStr2Type', typeStr);
       // TODO: add all types
       switch (typeStr) {
         case '[]':
           return 'square';
         case '()':
    +      log.debug('we have a round');
           return 'round';
    +    case '(())':
    +      return 'circle';
    +    case '>]':
    +      return 'rect_left_inv_arrow';
    +    case '{}':
    +      return 'question';
    +    case '{{}}':
    +      return 'hexagon';
    +    case '([])':
    +      return 'stadium';
    +    case '[[]]':
    +      return 'subroutine';
    +    case '[()]':
    +      return 'cylinder';
    +    case '((()))':
    +      return 'doublecircle';
    +    case '[//]':
    +      return 'lean_right';
    +    case '[\\\\]':
    +      return 'lean_left';
    +    case '[/\\]':
    +      return 'trapezoid';
    +    case '[\\/]':
    +      return 'inv_trapezoid';
         default:
           return 'square';
       }
    diff --git a/packages/mermaid/src/diagrams/block/layout.ts b/packages/mermaid/src/diagrams/block/layout.ts
    index 741445806e..f9a6cd3f9e 100644
    --- a/packages/mermaid/src/diagrams/block/layout.ts
    +++ b/packages/mermaid/src/diagrams/block/layout.ts
    @@ -104,11 +104,8 @@ function calcBlockSizes(block: Block, db: BlockDB) {
           block.children.length
         );
     
    -    const numChildren = block.children.length;
         block.size = {
    -      // width: numChildren * (maxWidth + padding) + padding,
           width: xSize * (maxWidth + padding) + padding,
    -      // height: maxHeight + 2 * padding,
           height: ySize * (maxHeight + padding) + padding,
           x: 0,
           y: 0,
    diff --git a/packages/mermaid/src/diagrams/block/parser/block.jison b/packages/mermaid/src/diagrams/block/parser/block.jison
    index 32b7c28e25..b2975b610d 100644
    --- a/packages/mermaid/src/diagrams/block/parser/block.jison
    +++ b/packages/mermaid/src/diagrams/block/parser/block.jison
    @@ -13,6 +13,7 @@
     %x acc_descr
     %x acc_descr_multiline
     %x string
    +%x space
     %x md_string
     %x NODE
     
    @@ -43,6 +44,9 @@ CRLF \u000D\u000A
     ["]                     this.pushState("string");
     ["]             this.popState();
     [^"]*           return "STR";
    +space[:]\d+            {  yytext = yytext.replace(/space\:/,'');yy.getLogger().info('SPACE NUM (LEX)', yytext); return 'SPACE_BLOCK'; }
    +space                  { yytext = '1'; yy.getLogger().info('COLUMNS (LEX)', yytext); return 'SPACE_BLOCK'; }
    +[^"]*           return "STR";
     "style"               return 'STYLE';
     "default"             return 'DEFAULT';
     "linkStyle"           return 'LINKSTYLE';
    @@ -64,7 +68,7 @@ accDescr\s*"{"\s*                                { this.pushState("acc_descr_mul
     .*direction\s+LR[^\n]*                                      return 'direction_lr';
     
     // Start of nodes with shapes and description
    -"-)"                   { yy.getLogger().info('Lex: -)'); this.pushState('NODE');return 'NODE_D START'; }
    +"-)"                   { yy.getLogger().info('Lex: -)'); this.pushState('NODE');return 'NODE_DSTART'; }
     "(-"                   { yy.getLogger().info('Lex: (-'); this.pushState('NODE');return 'NODE_DSTART'; }
     "))"                   { yy.getLogger().info('Lex: ))'); this.pushState('NODE');return 'NODE_DSTART';  }
     ")"                    { yy.getLogger().info('Lex: )'); this.pushState('NODE');return 'NODE_DSTART';      }
    @@ -167,6 +171,8 @@ link
     statement
       : nodeStatement
       | columnsStatement
    +  | SPACE_BLOCK
    +    { const num=parseInt($1); const spaceId = yy.generateId(); $$ = { id: spaceId, type:'space', label:'', width: num, children: [] }}
       | blockStatement
     //   SPACELIST node       { yy.getLogger().info('Node: ',$2.id);yy.addNode($1.length, $2.id, $2.descr, $2.type);  }
     // 	| SPACELIST ICON       { yy.getLogger().info('Icon: ',$2);yy.decorateNode({icon: $2}); }
    @@ -182,7 +188,7 @@ statement
     
     nodeStatement
       : nodeStatement link node { yy.getLogger().info('Rule: nodeStatement (nodeStatement link node) '); $$ = {id: $1.id}; }
    -  | node { yy.getLogger().info('Rule: nodeStatement (node) ', $1); $$ = {id: $1.id, label: $1.label, type: yy.typeStr2Type($1)}; }
    +  | node { yy.getLogger().info('Rule: nodeStatement (node) ', $1); $$ = {id: $1.id, label: $1.label, type: yy.typeStr2Type($1.typeStr)}; }
       ;
     
     columnsStatement
    diff --git a/packages/mermaid/src/diagrams/block/parser/block.spec.ts b/packages/mermaid/src/diagrams/block/parser/block.spec.ts
    index adb814be22..bf32afc5e6 100644
    --- a/packages/mermaid/src/diagrams/block/parser/block.spec.ts
    +++ b/packages/mermaid/src/diagrams/block/parser/block.spec.ts
    @@ -163,7 +163,7 @@ describe('Block diagram', function () {
     
           expect(blocks[0].children.length).toBe(2);
           expect(blocks[0].id).not.toBe(undefined);
    -      expect(blocks[0].label).toBe(blocks[0].id);
    +      expect(blocks[0].label).toBe('');
           expect(blocks[0].type).toBe('composite');
     
           const aBlock = blocks[0].children[0];
    @@ -196,12 +196,12 @@ describe('Block diagram', function () {
     
           expect(blocks[0].children.length).toBe(2);
           expect(blocks[0].id).not.toBe(undefined);
    -      expect(blocks[0].label).toBe(blocks[0].id);
    +      expect(blocks[0].label).toBe('');
           expect(blocks[0].type).toBe('composite');
     
           expect(secondComposite.children.length).toBe(1);
           expect(secondComposite.id).not.toBe(undefined);
    -      expect(secondComposite.label).toBe(secondComposite.id);
    +      expect(secondComposite.label).toBe('');
           expect(secondComposite.type).toBe('composite');
     
           expect(aBlock.id).not.toBe(aBlock);
    @@ -284,7 +284,7 @@ describe('Block diagram', function () {
     
           block.parse(str);
         });
    -    it.skip('empty blocks', async () => {
    +    it('empty blocks', async () => {
           const str = `block-beta
             columns 3
             space
    @@ -308,7 +308,7 @@ describe('Block diagram', function () {
             columns 2
             mc["Memcache"]:2::black
             `;
    -
    +      const apa = 'apan hopar i träden';
           block.parse(str);
         });
     
    diff --git a/packages/mermaid/src/diagrams/block/renderHelpers.ts b/packages/mermaid/src/diagrams/block/renderHelpers.ts
    index 7c1f7c6f92..78cce974c3 100644
    --- a/packages/mermaid/src/diagrams/block/renderHelpers.ts
    +++ b/packages/mermaid/src/diagrams/block/renderHelpers.ts
    @@ -22,15 +22,21 @@ function getNodeFromBlock(block: Block, db: BlockDB, positioned = false) {
       let radious = 0;
       let _shape = '';
       let layoutOptions = {};
    +  let padding;
       // Set the shape based parameters
       switch (vertex.type) {
         case 'round':
           radious = 5;
           _shape = 'rect';
           break;
    +    // case 'composite-subgraph':
    +    //   radious = 0;
    +    //   _shape = 'composite';
    +    //   break;
         case 'composite':
    -      radious = 4;
    +      radious = 0;
           _shape = 'composite';
    +      padding = 0;
           break;
         case 'square':
           _shape = 'rect';
    @@ -119,7 +125,7 @@ function getNodeFromBlock(block: Block, db: BlockDB, positioned = false) {
         positioned,
         type: vertex.type,
         // props: vertex.props,
    -    padding: getConfig()?.flowchart?.padding || 0,
    +    padding: padding ?? (getConfig()?.flowchart?.padding || 0),
       };
       return node;
     }
    @@ -139,15 +145,17 @@ async function calculateBlockSize(elem: any, block: any, db: any) {
       nodeEl.remove();
     }
     
    -export async function insertBlockPositioned(elem: any, block: any, db: any) {
    +export async function insertBlockPositioned(elem: any, block: Block, db: any) {
       const node = getNodeFromBlock(block, db, true);
       // if (node.type === 'composite') {
       //   return;
       // }
       // Add the element to the DOM to size it
       const obj = db.getBlock(node.id);
    -  const nodeEl = await insertNode(elem, node);
    -  positionNode(node);
    +  if (obj.type !== 'space') {
    +    const nodeEl = await insertNode(elem, node);
    +    positionNode(node);
    +  }
     }
     
     export async function performOperations(
    
    From 7198fe55a9312f12fdf810b9538585fe5f0d8d49 Mon Sep 17 00:00:00 2001
    From: Knut Sveidqvist 
    Date: Thu, 26 Oct 2023 22:01:44 +0200
    Subject: [PATCH 025/217] Parsing of block arrows with directions, creating a
     dedicated new node for this.
    
    ---
     cypress/platform/knsv2.html                   | 27 ++++----
     packages/mermaid/src/dagre-wrapper/nodes.js   | 27 ++++++++
     .../mermaid/src/diagrams/block/blockDB.ts     |  2 +
     .../mermaid/src/diagrams/block/blockTypes.ts  |  3 +
     .../src/diagrams/block/parser/block.jison     | 61 +++++++++++--------
     .../src/diagrams/block/renderHelpers.ts       |  3 +
     6 files changed, 83 insertions(+), 40 deletions(-)
    
    diff --git a/cypress/platform/knsv2.html b/cypress/platform/knsv2.html
    index 6d5c9846b6..315c33b210 100644
    --- a/cypress/platform/knsv2.html
    +++ b/cypress/platform/knsv2.html
    @@ -62,24 +62,23 @@
         
       
       
    -    
    +    
     block-beta
    -  block
    -    id3("Wider then")
    -  end
    +      blockArrowId<["Label"]>(right, down)
         
    -
    +    
     block-beta
         columns 3
    -    space:2
    -    id1("Wider then")
    -    space:9
    -    space
    -    id2{{"Wider then"}}
    -    space
    -    id3("Wider then")
    -    space
    -    space
    +    space:3
    +    ida idb idc
    +    id1  id2
    +      blockArrowId<["Label"]>(right)
    +      blockArrowId2<["Label"]>(left)
    +      blockArrowId3<["Label"]>(up)
    +      blockArrowId4<["Label"]>(down)
    +      blockArrowId5<["Label"]>(x)
    +      blockArrowId6<["Label"]>(y)
    +      blockArrowId6<["Label"]>(x, down)
         
     block-beta
    diff --git a/packages/mermaid/src/dagre-wrapper/nodes.js b/packages/mermaid/src/dagre-wrapper/nodes.js
    index 78bcfea999..41578f5849 100644
    --- a/packages/mermaid/src/dagre-wrapper/nodes.js
    +++ b/packages/mermaid/src/dagre-wrapper/nodes.js
    @@ -95,6 +95,32 @@ const hexagon = async (parent, node) => {
     
       return shapeSvg;
     };
    +const block_arrow = async (parent, node) => {
    +  const { shapeSvg, bbox } = await labelHelper(parent, node, undefined, true);
    +
    +  const f = 2;
    +  const h = bbox.height + node.padding;
    +  const m = h / f;
    +  const w = bbox.width + 2 * m + node.padding;
    +  const points = [
    +    { x: m, y: 0 },
    +    { x: w - m, y: 0 },
    +    { x: w, y: -h / 2 },
    +    { x: w - m, y: -h },
    +    { x: m, y: -h },
    +    { x: 0, y: -h / 2 },
    +  ];
    +
    +  const hex = insertPolygonShape(shapeSvg, w, h, points);
    +  hex.attr('style', node.style);
    +  updateNodeBounds(node, hex);
    +
    +  node.intersect = function (point) {
    +    return intersect.polygon(node, points, point);
    +  };
    +
    +  return shapeSvg;
    +};
     
     const rect_left_inv_arrow = async (parent, node) => {
       const { shapeSvg, bbox } = await labelHelper(parent, node, undefined, true);
    @@ -1016,6 +1042,7 @@ const shapes = {
       doublecircle,
       stadium,
       hexagon,
    +  block_arrow,
       rect_left_inv_arrow,
       lean_right,
       lean_left,
    diff --git a/packages/mermaid/src/diagrams/block/blockDB.ts b/packages/mermaid/src/diagrams/block/blockDB.ts
    index 6b787009d9..a3ef97e247 100644
    --- a/packages/mermaid/src/diagrams/block/blockDB.ts
    +++ b/packages/mermaid/src/diagrams/block/blockDB.ts
    @@ -99,6 +99,8 @@ export function typeStr2Type(typeStr: string) {
           return 'trapezoid';
         case '[\\/]':
           return 'inv_trapezoid';
    +    case '<[]>':
    +      return 'block_arrow';
         default:
           return 'square';
       }
    diff --git a/packages/mermaid/src/diagrams/block/blockTypes.ts b/packages/mermaid/src/diagrams/block/blockTypes.ts
    index f26d83fcc7..001cd7bdaf 100644
    --- a/packages/mermaid/src/diagrams/block/blockTypes.ts
    +++ b/packages/mermaid/src/diagrams/block/blockTypes.ts
    @@ -7,6 +7,8 @@ export interface BlockConfig extends BaseDiagramConfig {
     export type BlockType =
       | 'column-setting'
       | 'round'
    +  | 'block_arrow'
    +  | 'space'
       | 'square'
       | 'diamond'
       | 'hexagon'
    @@ -40,6 +42,7 @@ export interface Block {
       node?: any;
       columns?: number; // | TBlockColumnsDefaultValue;
       classes?: string[];
    +  directions?: string[];
     }
     
     export interface Link {
    diff --git a/packages/mermaid/src/diagrams/block/parser/block.jison b/packages/mermaid/src/diagrams/block/parser/block.jison
    index b2975b610d..91d26faf37 100644
    --- a/packages/mermaid/src/diagrams/block/parser/block.jison
    +++ b/packages/mermaid/src/diagrams/block/parser/block.jison
    @@ -16,6 +16,8 @@
     %x space
     %x md_string
     %x NODE
    +%x BLOCK_ARROW
    +%x ARROW_DIR
     
     
     // as per section 6.1 of RFC 2234 [2]
    @@ -42,11 +44,10 @@ CRLF \u000D\u000A
     [^`"]+        { return "MD_STR";}
     [`]["]          { this.popState();}
     ["]                     this.pushState("string");
    -["]             this.popState();
    -[^"]*           return "STR";
    +["]             { log.debug('LEX: POPPING STR:', yytext);this.popState();}
    +[^"]*           { log.debug('LEX: STR ebd:', yytext); return "STR";}
     space[:]\d+            {  yytext = yytext.replace(/space\:/,'');yy.getLogger().info('SPACE NUM (LEX)', yytext); return 'SPACE_BLOCK'; }
     space                  { yytext = '1'; yy.getLogger().info('COLUMNS (LEX)', yytext); return 'SPACE_BLOCK'; }
    -[^"]*           return "STR";
     "style"               return 'STYLE';
     "default"             return 'DEFAULT';
     "linkStyle"           return 'LINKSTYLE';
    @@ -68,15 +69,15 @@ accDescr\s*"{"\s*                                { this.pushState("acc_descr_mul
     .*direction\s+LR[^\n]*                                      return 'direction_lr';
     
     // Start of nodes with shapes and description
    -"-)"                   { yy.getLogger().info('Lex: -)'); this.pushState('NODE');return 'NODE_DSTART'; }
    -"(-"                   { yy.getLogger().info('Lex: (-'); this.pushState('NODE');return 'NODE_DSTART'; }
    -"))"                   { yy.getLogger().info('Lex: ))'); this.pushState('NODE');return 'NODE_DSTART';  }
    -")"                    { yy.getLogger().info('Lex: )'); this.pushState('NODE');return 'NODE_DSTART';      }
    -"(("                   { yy.getLogger().info('Lex: )'); this.pushState('NODE');return 'NODE_DSTART'; }
    -"{{"                   { yy.getLogger().info('Lex: )'); this.pushState('NODE');return 'NODE_DSTART'; }
    -"("                    { yy.getLogger().info('Lex: )'); this.pushState('NODE');return 'NODE_DSTART'; }
    -"["                    { yy.getLogger().info('Lex: ['); this.pushState('NODE');return 'NODE_DSTART'; }
    -"(["                   { yy.getLogger().info('Lex: )'); this.pushState('NODE');return 'NODE_DSTART'; }
    +"-)"                   { yy.getLogger().info('Lexa: -)'); this.pushState('NODE');return 'NODE_DSTART'; }
    +"(-"                   { yy.getLogger().info('Lexa: (-'); this.pushState('NODE');return 'NODE_DSTART'; }
    +"))"                   { yy.getLogger().info('Lexa: ))'); this.pushState('NODE');return 'NODE_DSTART';  }
    +")"                    { yy.getLogger().info('Lexa: )'); this.pushState('NODE');return 'NODE_DSTART';      }
    +"(("                   { yy.getLogger().info('Lexa: )'); this.pushState('NODE');return 'NODE_DSTART'; }
    +"{{"                   { yy.getLogger().info('Lexa: )'); this.pushState('NODE');return 'NODE_DSTART'; }
    +"("                    { yy.getLogger().info('Lexa: )'); this.pushState('NODE');return 'NODE_DSTART'; }
    +"["                    { yy.getLogger().info('Lexa: ['); this.pushState('NODE');return 'NODE_DSTART'; }
    +"(["                   { yy.getLogger().info('Lexa: (['); this.pushState('NODE');return 'NODE_DSTART'; }
     "[["                   { this.pushState('NODE');return 'NODE_DSTART'; }
     "[|"                   { this.pushState('NODE');return 'NODE_DSTART'; }
     "[("                   { this.pushState('NODE');return 'NODE_DSTART'; }
    @@ -85,19 +86,23 @@ accDescr\s*"{"\s*                                { this.pushState("acc_descr_mul
     "[/"                   { this.pushState('NODE');return 'NODE_DSTART'; }
     "[\\"                  { this.pushState('NODE');return 'NODE_DSTART'; }
     
    +"<["                   { this.pushState('BLOCK_ARROW');log.debug('LEX ARR START');return 'BLOCK_ARROW_START'; }
     
    -[^\(\[\n\-\)\{\}]+     { yy.getLogger().info('Lex: NODE_ID', yytext);return 'NODE_ID'; }
    +[^\(\[\n\-\)\{\}\s\<]+     { yy.getLogger().info('Lex: NODE_ID', yytext);return 'NODE_ID'; }
     <>                { yy.getLogger().info('Lex: EOF', yytext);return 'EOF'; }
     
     // Handling of strings in node
    +["][`]           { this.pushState("md_string");}
     ["][`]           { this.pushState("md_string");}
     [^`"]+      { return "NODE_DESCR";}
     [`]["]      { this.popState();}
     ["]              { yy.getLogger().info('Lex: Starting string');this.pushState("string");}
    -[^"]+          { yy.getLogger().info('Lex: NODE_DESCR:', yytext); return "NODE_DESCR";}
    -["]            {this.popState();}
    +["]              { yy.getLogger().info('LEX ARR: Starting string');this.pushState("string");}
    +[^"]+          { log.debug('LEX: NODE_DESCR:', yytext); return "NODE_DESCR";}
    +["]            {log.debug('LEX POPPING');this.popState();}
     
     // Node end of shape
    +\]\>             { this.popState();yy.getLogger().info('Lex: ]>'); return "NODE_DEND"; }
     [\)]\)           { this.popState();yy.getLogger().info('Lex: ))'); return "NODE_DEND"; }
     [\)]             { this.popState();yy.getLogger().info('Lex: )');  return "NODE_DEND"; }
     [\]]             { this.popState();yy.getLogger().info('Lex: ]'); return "NODE_DEND"; }
    @@ -111,6 +116,15 @@ accDescr\s*"{"\s*                                { this.pushState("acc_descr_mul
     "/]"             { this.popState();yy.getLogger().info('Lex: /]'); return "NODE_DEND"; }
     ")]"             { this.popState();yy.getLogger().info('Lex: )]'); return "NODE_DEND"; }
     
    +"]>"\s*"("       { log.debug('Lex: =>BAE');  this.pushState('ARROW_DIR');  }
    +","?right\s*           { log.debug('Lex (right): dir:',yytext);return "DIR"; }
    +","?left\s*            { log.debug('Lex (left):',yytext);return "DIR"; }
    +","?x\s*               { log.debug('Lex (x):',yytext); return "DIR"; }
    +","?y\s*               { log.debug('Lex (y):',yytext); return "DIR"; }
    +","?up\s*              { log.debug('Lex (up):',yytext); return "DIR"; }
    +","?\s*down\s*     { yytext = yytext.replace(/^,\s*/, ''); log.debug('Lex (down):',yytext); return "DIR"; }
    +")"\s*             { yytext=']>';log.debug('Lex (ARROW_DIR end):',yytext);this.popState();this.popState();return "BLOCK_ARROW_END"; }
    +
     // Edges
     \s*[xo<]?\-\-+[-xo>]\s*                 { yy.getLogger().info('Lex: LINK', '#'+yytext+'#'); return 'LINK'; }
     \s*[xo<]?\=\=+[=xo>]\s*                 { yy.getLogger().info('Lex: LINK', yytext); return 'LINK'; }
    @@ -174,16 +188,6 @@ statement
       | SPACE_BLOCK
         { const num=parseInt($1); const spaceId = yy.generateId(); $$ = { id: spaceId, type:'space', label:'', width: num, children: [] }}
       | blockStatement
    -//   SPACELIST node       { yy.getLogger().info('Node: ',$2.id);yy.addNode($1.length, $2.id, $2.descr, $2.type);  }
    -// 	| SPACELIST ICON       { yy.getLogger().info('Icon: ',$2);yy.decorateNode({icon: $2}); }
    -// 	| SPACELIST CLASS      { yy.decorateNode({class: $2}); }
    -//   | SPACELINE { yy.getLogger().info('SPACELIST');}
    -// 	|
    -//    node					       { yy.getLogger().info('Node: ',$1.id);yy.addNode(0, $1.id, $1.descr, $1.type);  }
    -// 	| ICON                 { yy.decorateNode({icon: $1}); }
    -// 	| CLASS                { yy.decorateNode({class: $1}); }
    -//   // | SPACELIST
    -
     	;
     
     nodeStatement
    @@ -200,7 +204,6 @@ blockStatement
       | block document end { yy.getLogger().info('Rule: blockStatement : ', $1, $2, $3); const id = yy.generateId(); $$ = { id, type:'composite', label:'', children: $2 }; }
       ;
     
    -
     node
       : NODE_ID
       { yy.getLogger().info("Rule: node (NODE_ID seperator): ", $1); $$ = { id: $1 }; }
    @@ -210,9 +213,15 @@ node
       // { yy.getLogger().info("Rule: node (nodeShapeNLabel seperator): ", $1, $2, $3); }
       ;
     
    +dirList: DIR { yy.getLogger().info("Rule: dirList: ", $1); $$ = [$1]; }
    +  | DIR dirList { yy.getLogger().info("Rule: dirList: ", $1, $2); $$ = [$1].concat($2); }
    +  ;
    +
     nodeShapeNLabel
       :   NODE_DSTART STR NODE_DEND
     	      { yy.getLogger().info("Rule: nodeShapeNLabel: ", $1, $2, $3); $$ = { typeStr: $1 + $3, label: $2 }; }
    +	|    BLOCK_ARROW_START STR dirList BLOCK_ARROW_END
    +    	      { yy.getLogger().info("Rule: BLOCK_ARROW nodeShapeNLabel: ", $1, $2, $3, $4); $$ = { typeStr: $1 + $4, label: $2, directions: $3}; }
       ;
     
     %%
    diff --git a/packages/mermaid/src/diagrams/block/renderHelpers.ts b/packages/mermaid/src/diagrams/block/renderHelpers.ts
    index 78cce974c3..142de0c5cd 100644
    --- a/packages/mermaid/src/diagrams/block/renderHelpers.ts
    +++ b/packages/mermaid/src/diagrams/block/renderHelpers.ts
    @@ -50,6 +50,9 @@ function getNodeFromBlock(block: Block, db: BlockDB, positioned = false) {
         case 'hexagon':
           _shape = 'hexagon';
           break;
    +    case 'block_arrow':
    +      _shape = 'block_arrow';
    +      break;
         case 'odd':
           _shape = 'rect_left_inv_arrow';
           break;
    
    From 03c59adaede3cc0ce5dac3d81683fe5820a90cc6 Mon Sep 17 00:00:00 2001
    From: Knut Sveidqvist 
    Date: Thu, 26 Oct 2023 22:02:16 +0200
    Subject: [PATCH 026/217] Parsing of block arrows with directions, creating a
     dedicated new node for this.
    
    ---
     packages/mermaid/src/diagrams/block/blockDB.ts    | 6 +++---
     packages/mermaid/src/diagrams/block/blockTypes.ts | 2 ++
     2 files changed, 5 insertions(+), 3 deletions(-)
    
    diff --git a/packages/mermaid/src/diagrams/block/blockDB.ts b/packages/mermaid/src/diagrams/block/blockDB.ts
    index a3ef97e247..3cc9ec11d7 100644
    --- a/packages/mermaid/src/diagrams/block/blockDB.ts
    +++ b/packages/mermaid/src/diagrams/block/blockDB.ts
    @@ -22,8 +22,7 @@ const populateBlockDatabase = (blockList: Block[], parent: Block): void => {
       const children = [];
       for (const block of blockList) {
         if (block.type === 'column-setting') {
    -      const columns = block.columns || -1;
    -      parent.columns = columns;
    +      parent.columns = block.columns || -1;
         } else {
           if (!block.label) {
             if (block.type === 'composite') {
    @@ -39,7 +38,8 @@ const populateBlockDatabase = (blockList: Block[], parent: Block): void => {
           }
     
           if (block.type === 'space') {
    -        for (let j = 0; j < block.width; j++) {
    +        const w = block.width || 1;
    +        for (let j = 0; j < w; j++) {
               const newBlock = clone(block);
               newBlock.id = newBlock.id + '-' + j;
               blockDatabase[newBlock.id] = newBlock;
    diff --git a/packages/mermaid/src/diagrams/block/blockTypes.ts b/packages/mermaid/src/diagrams/block/blockTypes.ts
    index 001cd7bdaf..a65e5db324 100644
    --- a/packages/mermaid/src/diagrams/block/blockTypes.ts
    +++ b/packages/mermaid/src/diagrams/block/blockTypes.ts
    @@ -17,6 +17,7 @@ export type BlockType =
       | 'lean_left'
       | 'trapezoid'
       | 'inv_trapezoid'
    +  | 'rect_left_inv_arrow'
       | 'odd_right'
       | 'circle'
       | 'ellipse'
    @@ -28,6 +29,7 @@ export type BlockType =
       | 'composite';
     
     export interface Block {
    +  width?: number;
       id: string;
       label?: string;
       parent?: Block;
    
    From df858dc7b61272621a4f4c9c4fc3c1f2d146c500 Mon Sep 17 00:00:00 2001
    From: Knut Sveidqvist 
    Date: Mon, 20 Nov 2023 14:00:25 +0100
    Subject: [PATCH 027/217] #3358 Adding arrows to syntax
    
    ---
     cypress/platform/knsv2.html                   |  10 +-
     .../src/dagre-wrapper/blockArrowHelper.js     | 218 ++++++++++++++++++
     packages/mermaid/src/dagre-wrapper/nodes.js   |  35 ++-
     .../mermaid/src/diagrams/block/blockDB.ts     |   8 +-
     .../src/diagrams/block/parser/block.jison     |  49 ++--
     .../src/diagrams/block/renderHelpers.ts       |   1 +
     .../src/diagrams/flowchart/flowRenderer-v2.js |   4 +-
     .../src/diagrams/flowchart/parser/flow.jison  |   8 +-
     8 files changed, 290 insertions(+), 43 deletions(-)
     create mode 100644 packages/mermaid/src/dagre-wrapper/blockArrowHelper.js
    
    diff --git a/cypress/platform/knsv2.html b/cypress/platform/knsv2.html
    index 315c33b210..ab5c0aa3cc 100644
    --- a/cypress/platform/knsv2.html
    +++ b/cypress/platform/knsv2.html
    @@ -62,9 +62,17 @@
         
       
       
    +    
    +block-beta
    +      columns 3
    +      space blockArrowId1<["down"]>(down) space
    +      blockArrowId2<["right"]>(right) blockArrowId3<["Sync"]>(x, y) blockArrowId4<["left"]>(left)
    +      space blockArrowId5<["up"]>(up) space
    +      blockArrowId6<["x"]>(x) space blockArrowId7<["y"]>(y)
    +    
     block-beta
    -      blockArrowId<["Label"]>(right, down)
    +      A("APA") --> B("GORILLA")
         
     block-beta
    diff --git a/packages/mermaid/src/dagre-wrapper/blockArrowHelper.js b/packages/mermaid/src/dagre-wrapper/blockArrowHelper.js
    new file mode 100644
    index 0000000000..60ff77a57a
    --- /dev/null
    +++ b/packages/mermaid/src/dagre-wrapper/blockArrowHelper.js
    @@ -0,0 +1,218 @@
    +const expandAndDeduplicateDirections = (directions) => {
    +  const uniqueDirections = new Set();
    +
    +  for (const direction of directions) {
    +    switch (direction) {
    +      case 'x':
    +        uniqueDirections.add('right');
    +        uniqueDirections.add('left');
    +        break;
    +      case 'y':
    +        uniqueDirections.add('up');
    +        uniqueDirections.add('down');
    +        break;
    +      default:
    +        uniqueDirections.add(direction);
    +        break;
    +    }
    +  }
    +
    +  return uniqueDirections;
    +};
    +export const getArrowPoints = (directions, bbox, node) => {
    +  const ud = expandAndDeduplicateDirections(directions);
    +
    +  // console.log('block_arrow abc123', node.id, node.directions, ud);
    +
    +  const f = 2;
    +  const h = bbox.height + 2 * node.padding;
    +  const m = h / f;
    +  const w = bbox.width + 2 * m + node.padding;
    +  const p = node.padding / 2;
    +
    +  let points = [];
    +
    +  if (ud.has('right') && ud.has('left') && ud.has('up') && ud.has('down')) {
    +    // SQUARE
    +    points = [
    +      // Bottom
    +      { x: 0, y: 0 },
    +      { x: m, y: 0 },
    +      { x: w / 2, y: 2 * p },
    +      { x: w - m, y: 0 },
    +      { x: w, y: 0 },
    +
    +      // Right
    +      { x: w, y: -h / 3 },
    +      { x: w + 2 * p, y: -h / 2 },
    +      { x: w, y: (-2 * h) / 3 },
    +      { x: w, y: -h },
    +
    +      // Top
    +      { x: w - m, y: -h },
    +      { x: w / 2, y: -h - 2 * p },
    +      { x: m, y: -h },
    +
    +      // Left
    +      { x: 0, y: -h },
    +      { x: 0, y: (-2 * h) / 3 },
    +      { x: -2 * p, y: -h / 2 },
    +      { x: 0, y: -h / 3 },
    +    ];
    +  } else if (ud.has('right') && ud.has('left') && ud.has('up')) {
    +    // RECTANGLE_VERTICAL (Top Open)
    +    points = [
    +      { x: m, y: 0 },
    +      { x: w - m, y: 0 },
    +      { x: w, y: -h / 2 },
    +      { x: w - m, y: -h },
    +      { x: m, y: -h },
    +      { x: 0, y: -h / 2 },
    +    ];
    +  } else if (ud.has('right') && ud.has('left') && ud.has('down')) {
    +    // RECTANGLE_VERTICAL (Bottom Open)
    +    points = [
    +      { x: 0, y: 0 },
    +      { x: m, y: -h },
    +      { x: w - m, y: -h },
    +      { x: w, y: 0 },
    +    ];
    +  } else if (ud.has('right') && ud.has('up') && ud.has('down')) {
    +    // RECTANGLE_HORIZONTAL (Right Open)
    +    points = [
    +      { x: 0, y: 0 },
    +      { x: w, y: -m },
    +      { x: w, y: -h + m },
    +      { x: 0, y: -h },
    +    ];
    +  } else if (ud.has('left') && ud.has('up') && ud.has('down')) {
    +    // RECTANGLE_HORIZONTAL (Left Open)
    +    points = [
    +      { x: w, y: 0 },
    +      { x: 0, y: -m },
    +      { x: 0, y: -h + m },
    +      { x: w, y: -h },
    +    ];
    +  } else if (ud.has('right') && ud.has('left')) {
    +    // HORIZONTAL_LINE
    +    points = [
    +      { x: m, y: 0 },
    +      { x: m, y: -p },
    +      { x: w - m, y: -p },
    +      { x: w - m, y: 0 },
    +      { x: w, y: -h / 2 },
    +      { x: w - m, y: -h },
    +      { x: w - m, y: -h + p },
    +      { x: m, y: -h + p },
    +      { x: m, y: -h },
    +      { x: 0, y: -h / 2 },
    +    ];
    +  } else if (ud.has('up') && ud.has('down')) {
    +    // VERTICAL_LINE
    +    points = [
    +      // Bottom center
    +      { x: w / 2, y: 0 },
    +      // Left pont of bottom arrow
    +      { x: 0, y: -p },
    +      { x: m, y: -p },
    +      // Left top over vertical section
    +      { x: m, y: -h + p },
    +      { x: 0, y: -h + p },
    +      // Top of arrow
    +      { x: w / 2, y: -h },
    +      { x: w, y: -h + p },
    +      // Top of right vertical bar
    +      { x: w - m, y: -h + p },
    +      { x: w - m, y: -p },
    +      { x: w, y: -p },
    +    ];
    +  } else if (ud.has('right') && ud.has('up')) {
    +    // ANGLE_RT
    +    points = [
    +      { x: 0, y: 0 },
    +      { x: w, y: -m },
    +      { x: 0, y: -h },
    +    ];
    +  } else if (ud.has('right') && ud.has('down')) {
    +    // ANGLE_RB
    +    points = [
    +      { x: 0, y: 0 },
    +      { x: w, y: 0 },
    +      { x: 0, y: -h },
    +    ];
    +  } else if (ud.has('left') && ud.has('up')) {
    +    // ANGLE_LT
    +    points = [
    +      { x: w, y: 0 },
    +      { x: 0, y: -m },
    +      { x: w, y: -h },
    +    ];
    +  } else if (ud.has('left') && ud.has('down')) {
    +    // ANGLE_LB
    +    points = [
    +      { x: w, y: 0 },
    +      { x: 0, y: 0 },
    +      { x: w, y: -h },
    +    ];
    +  } else if (ud.has('right')) {
    +    // ARROW_RIGHT
    +    points = [
    +      { x: m, y: -p },
    +      { x: m, y: -p },
    +      { x: w - m, y: -p },
    +      { x: w - m, y: 0 },
    +      { x: w, y: -h / 2 },
    +      { x: w - m, y: -h },
    +      { x: w - m, y: -h + p },
    +      // top left corner of arrow
    +      { x: m, y: -h + p },
    +      { x: m, y: -h + p },
    +    ];
    +  } else if (ud.has('left')) {
    +    // ARROW_LEFT
    +    points = [
    +      { x: m, y: 0 },
    +      { x: m, y: -p },
    +      // Two points, the right corners
    +      { x: w - m, y: -p },
    +      { x: w - m, y: -h + p },
    +      { x: m, y: -h + p },
    +      { x: m, y: -h },
    +      { x: 0, y: -h / 2 },
    +    ];
    +  } else if (ud.has('up')) {
    +    // ARROW_TOP
    +    points = [
    +      // Bottom center
    +      { x: m, y: -p },
    +      // Left top over vertical section
    +      { x: m, y: -h + p },
    +      { x: 0, y: -h + p },
    +      // Top of arrow
    +      { x: w / 2, y: -h },
    +      { x: w, y: -h + p },
    +      // Top of right vertical bar
    +      { x: w - m, y: -h + p },
    +      { x: w - m, y: -p },
    +    ];
    +  } else if (ud.has('down')) {
    +    // ARROW_BOTTOM
    +    points = [
    +      // Bottom center
    +      { x: w / 2, y: 0 },
    +      // Left pont of bottom arrow
    +      { x: 0, y: -p },
    +      { x: m, y: -p },
    +      // Left top over vertical section
    +      { x: m, y: -h + p },
    +      { x: w - m, y: -h + p },
    +      { x: w - m, y: -p },
    +      { x: w, y: -p },
    +    ];
    +  } else {
    +    // POINT
    +    points = [{ x: 0, y: 0 }];
    +  }
    +
    +  return points;
    +};
    diff --git a/packages/mermaid/src/dagre-wrapper/nodes.js b/packages/mermaid/src/dagre-wrapper/nodes.js
    index 41578f5849..afe1b3a3fe 100644
    --- a/packages/mermaid/src/dagre-wrapper/nodes.js
    +++ b/packages/mermaid/src/dagre-wrapper/nodes.js
    @@ -7,6 +7,7 @@ import createLabel from './createLabel.js';
     import note from './shapes/note.js';
     import { parseMember } from '../diagrams/class/svgDraw.js';
     import { evaluate } from '../diagrams/common/common.js';
    +import { getArrowPoints } from './blockArrowHelper.js';
     
     const question = async (parent, node) => {
       const { shapeSvg, bbox } = await labelHelper(parent, node, undefined, true);
    @@ -14,6 +15,7 @@ const question = async (parent, node) => {
       const w = bbox.width + node.padding;
       const h = bbox.height + node.padding;
       const s = w + h;
    +
       const points = [
         { x: s / 2, y: 0 },
         { x: s, y: -s / 2 },
    @@ -95,21 +97,33 @@ const hexagon = async (parent, node) => {
     
       return shapeSvg;
     };
    +
     const block_arrow = async (parent, node) => {
       const { shapeSvg, bbox } = await labelHelper(parent, node, undefined, true);
     
       const f = 2;
    -  const h = bbox.height + node.padding;
    +  const h = bbox.height + 2 * node.padding;
       const m = h / f;
       const w = bbox.width + 2 * m + node.padding;
    -  const points = [
    -    { x: m, y: 0 },
    -    { x: w - m, y: 0 },
    -    { x: w, y: -h / 2 },
    -    { x: w - m, y: -h },
    -    { x: m, y: -h },
    -    { x: 0, y: -h / 2 },
    -  ];
    +
    +  const p = node.padding / 2;
    +  //
    +  // const points = [
    +  //   { x: m, y: 0 },
    +  //   { x: m, y: -p },
    +  //   { x: w - m, y: -p },
    +  //   { x: w - m, y: 0 },
    +  //   // Right point
    +  //   { x: w, y: -h / 2 },
    +  //   // Point moving left and up from right point
    +  //   { x: w - m, y: -h },
    +  //   { x: w - m, y: -h + p },
    +  //   { x: m, y: -h + p },
    +  //   { x: m, y: -h },
    +  //   { x: 0, y: -h / 2 },
    +  // ];
    +
    +  const points = getArrowPoints(node.directions, bbox, node);
     
       const hex = insertPolygonShape(shapeSvg, w, h, points);
       hex.attr('style', node.style);
    @@ -1085,6 +1099,9 @@ export const insertNode = async (elem, node, dir) => {
       if (node.class) {
         el.attr('class', 'node default ' + node.class);
       }
    +  // MC Special
    +  newEl.attr('data-node', 'true');
    +  newEl.attr('data-id', node.id);
     
       nodeElems[node.id] = newEl;
     
    diff --git a/packages/mermaid/src/diagrams/block/blockDB.ts b/packages/mermaid/src/diagrams/block/blockDB.ts
    index 3cc9ec11d7..86f0b78bbb 100644
    --- a/packages/mermaid/src/diagrams/block/blockDB.ts
    +++ b/packages/mermaid/src/diagrams/block/blockDB.ts
    @@ -66,9 +66,8 @@ const clear = (): void => {
     };
     
     type ITypeStr2Type = (typeStr: string) => BlockType;
    -export function typeStr2Type(typeStr: string) {
    +export function typeStr2Type(typeStr: string): BlockType {
       log.debug('typeStr2Type', typeStr);
    -  // TODO: add all types
       switch (typeStr) {
         case '[]':
           return 'square';
    @@ -80,7 +79,7 @@ export function typeStr2Type(typeStr: string) {
         case '>]':
           return 'rect_left_inv_arrow';
         case '{}':
    -      return 'question';
    +      return 'diamond';
         case '{{}}':
           return 'hexagon';
         case '([])':
    @@ -115,9 +114,10 @@ export const generateId = () => {
     
     type ISetHierarchy = (block: Block[]) => void;
     const setHierarchy = (block: Block[]): void => {
    +  // log.debug('The hierarchy', JSON.stringify(block, null, 2));
       rootBlock.children = block;
       populateBlockDatabase(block, rootBlock);
    -  log.debug('The hierarchy', JSON.stringify(rootBlock, null, 2));
    +  // log.debug('The hierarchy', JSON.stringify(rootBlock, null, 2));
       blocks = rootBlock.children;
     };
     
    diff --git a/packages/mermaid/src/diagrams/block/parser/block.jison b/packages/mermaid/src/diagrams/block/parser/block.jison
    index 91d26faf37..448ce0f415 100644
    --- a/packages/mermaid/src/diagrams/block/parser/block.jison
    +++ b/packages/mermaid/src/diagrams/block/parser/block.jison
    @@ -44,8 +44,8 @@ CRLF \u000D\u000A
     [^`"]+        { return "MD_STR";}
     [`]["]          { this.popState();}
     ["]                     this.pushState("string");
    -["]             { log.debug('LEX: POPPING STR:', yytext);this.popState();}
    -[^"]*           { log.debug('LEX: STR ebd:', yytext); return "STR";}
    +["]             { yy.getLogger().debug('LEX: POPPING STR:', yytext);this.popState();}
    +[^"]*           { yy.getLogger().debug('LEX: STR ebd:', yytext); return "STR";}
     space[:]\d+            {  yytext = yytext.replace(/space\:/,'');yy.getLogger().info('SPACE NUM (LEX)', yytext); return 'SPACE_BLOCK'; }
     space                  { yytext = '1'; yy.getLogger().info('COLUMNS (LEX)', yytext); return 'SPACE_BLOCK'; }
     "style"               return 'STYLE';
    @@ -86,7 +86,7 @@ accDescr\s*"{"\s*                                { this.pushState("acc_descr_mul
     "[/"                   { this.pushState('NODE');return 'NODE_DSTART'; }
     "[\\"                  { this.pushState('NODE');return 'NODE_DSTART'; }
     
    -"<["                   { this.pushState('BLOCK_ARROW');log.debug('LEX ARR START');return 'BLOCK_ARROW_START'; }
    +"<["                   { this.pushState('BLOCK_ARROW');yy.getLogger().debug('LEX ARR START');return 'BLOCK_ARROW_START'; }
     
     [^\(\[\n\-\)\{\}\s\<]+     { yy.getLogger().info('Lex: NODE_ID', yytext);return 'NODE_ID'; }
     <>                { yy.getLogger().info('Lex: EOF', yytext);return 'EOF'; }
    @@ -98,8 +98,8 @@ accDescr\s*"{"\s*                                { this.pushState("acc_descr_mul
     [`]["]      { this.popState();}
     ["]              { yy.getLogger().info('Lex: Starting string');this.pushState("string");}
     ["]              { yy.getLogger().info('LEX ARR: Starting string');this.pushState("string");}
    -[^"]+          { log.debug('LEX: NODE_DESCR:', yytext); return "NODE_DESCR";}
    -["]            {log.debug('LEX POPPING');this.popState();}
    +[^"]+          { yy.getLogger().debug('LEX: NODE_DESCR:', yytext); return "NODE_DESCR";}
    +["]            {yy.getLogger().debug('LEX POPPING');this.popState();}
     
     // Node end of shape
     \]\>             { this.popState();yy.getLogger().info('Lex: ]>'); return "NODE_DEND"; }
    @@ -116,14 +116,14 @@ accDescr\s*"{"\s*                                { this.pushState("acc_descr_mul
     "/]"             { this.popState();yy.getLogger().info('Lex: /]'); return "NODE_DEND"; }
     ")]"             { this.popState();yy.getLogger().info('Lex: )]'); return "NODE_DEND"; }
     
    -"]>"\s*"("       { log.debug('Lex: =>BAE');  this.pushState('ARROW_DIR');  }
    -","?right\s*           { log.debug('Lex (right): dir:',yytext);return "DIR"; }
    -","?left\s*            { log.debug('Lex (left):',yytext);return "DIR"; }
    -","?x\s*               { log.debug('Lex (x):',yytext); return "DIR"; }
    -","?y\s*               { log.debug('Lex (y):',yytext); return "DIR"; }
    -","?up\s*              { log.debug('Lex (up):',yytext); return "DIR"; }
    -","?\s*down\s*     { yytext = yytext.replace(/^,\s*/, ''); log.debug('Lex (down):',yytext); return "DIR"; }
    -")"\s*             { yytext=']>';log.debug('Lex (ARROW_DIR end):',yytext);this.popState();this.popState();return "BLOCK_ARROW_END"; }
    +"]>"\s*"("       { yy.getLogger().debug('Lex: =>BAE');  this.pushState('ARROW_DIR');  }
    +","?\s*right\s*           { yytext = yytext.replace(/^,\s*/, ''); yy.getLogger().debug('Lex (right): dir:',yytext);return "DIR"; }
    +","?\s*left\s*            { yytext = yytext.replace(/^,\s*/, ''); yy.getLogger().debug('Lex (left):',yytext);return "DIR"; }
    +","?\s*x\s*               { yytext = yytext.replace(/^,\s*/, ''); yy.getLogger().debug('Lex (x):',yytext); return "DIR"; }
    +","?\s*y\s*               { yytext = yytext.replace(/^,\s*/, ''); yy.getLogger().debug('Lex (y):',yytext); return "DIR"; }
    +","?\s*up\s*              { yytext = yytext.replace(/^,\s*/, ''); yy.getLogger().debug('Lex (up):',yytext); return "DIR"; }
    +","?\s*down\s*     { yytext = yytext.replace(/^,\s*/, ''); yy.getLogger().debug('Lex (down):',yytext); return "DIR"; }
    +")"\s*             { yytext=']>';yy.getLogger().debug('Lex (ARROW_DIR end):',yytext);this.popState();this.popState();return "BLOCK_ARROW_END"; }
     
     // Edges
     \s*[xo<]?\-\-+[-xo>]\s*                 { yy.getLogger().info('Lex: LINK', '#'+yytext+'#'); return 'LINK'; }
    @@ -157,7 +157,7 @@ seperator
       ;
     
     start: BLOCK_DIAGRAM_KEY document EOF
    -  { yy.setHierarchy($2); }
    +  { yy.getLogger().info("Rule: hierarchy: ", $2); yy.setHierarchy($2); }
       ;
     
     
    @@ -171,8 +171,8 @@ stop
     
     //array of statements
     document
    -	: statement { yy.getLogger().info("Rule: statement: ", $1); $$ = [$1]; }
    -	| statement document { yy.getLogger().info("Rule: document statement: ", $1, $2); $$ = [$1].concat($2); }
    +	: statement { yy.getLogger().info("Rule: statement: ", $1); typeof $1.length === 'number'?$$ = $1:$$ = [$1]; }
    +	| statement document { yy.getLogger().info("Rule: statement #2: ", $1); $$ = [$1].concat($2); }
     	;
     
     link
    @@ -191,12 +191,12 @@ statement
     	;
     
     nodeStatement
    -  : nodeStatement link node { yy.getLogger().info('Rule: nodeStatement (nodeStatement link node) '); $$ = {id: $1.id}; }
    -  | node { yy.getLogger().info('Rule: nodeStatement (node) ', $1); $$ = {id: $1.id, label: $1.label, type: yy.typeStr2Type($1.typeStr)}; }
    +  : nodeStatement link node { yy.getLogger().info('Rule: (nodeStatement link node) ', $1, $2, $3); $$ = [{id: $1.id, label: $1.label, type:$1.type, directions: $1.directions}, {id: $3.id, label: $3.label, type: yy.typeStr2Type($3.typeStr), directions: $3.directions}]; }
    +  | node { yy.getLogger().info('Rule: nodeStatement (node) ', $1); $$ = {id: $1.id, label: $1.label, type: yy.typeStr2Type($1.typeStr), directions: $1.directions}; }
       ;
     
     columnsStatement
    -  : COLUMNS { yy.getLogger().info("COLUMNS: ", $1); $$ = {type: 'column-setting', columns: $1 === 'auto'?-1:parseInt($1) } }
    +  : COLUMNS { yy.getLogger().info('APA123', this? this:'na'); yy.getLogger().info("COLUMNS: ", $1); $$ = {type: 'column-setting', columns: $1 === 'auto'?-1:parseInt($1) } }
       ;
     
     blockStatement
    @@ -207,10 +207,11 @@ blockStatement
     node
       : NODE_ID
       { yy.getLogger().info("Rule: node (NODE_ID seperator): ", $1); $$ = { id: $1 }; }
    -  |NODE_ID nodeShapeNLabel
    -    { yy.getLogger().info("Rule: node (NODE_ID nodeShapeNLabel seperator): ", $1, $2); $$ = { id: $1, label: $2.label, typeStr: $2.typeStr };}
    -  // |nodeShapeNLabel seperator
    -  // { yy.getLogger().info("Rule: node (nodeShapeNLabel seperator): ", $1, $2, $3); }
    +  | NODE_ID nodeShapeNLabel
    +  {
    +    yy.getLogger().info("Rule: node (NODE_ID nodeShapeNLabel seperator): ", $1, $2);
    +    $$ = { id: $1, label: $2.label, typeStr: $2.typeStr, directions: $2.directions };
    +  }
       ;
     
     dirList: DIR { yy.getLogger().info("Rule: dirList: ", $1); $$ = [$1]; }
    @@ -221,7 +222,7 @@ nodeShapeNLabel
       :   NODE_DSTART STR NODE_DEND
     	      { yy.getLogger().info("Rule: nodeShapeNLabel: ", $1, $2, $3); $$ = { typeStr: $1 + $3, label: $2 }; }
     	|    BLOCK_ARROW_START STR dirList BLOCK_ARROW_END
    -    	      { yy.getLogger().info("Rule: BLOCK_ARROW nodeShapeNLabel: ", $1, $2, $3, $4); $$ = { typeStr: $1 + $4, label: $2, directions: $3}; }
    +    	      { yy.getLogger().info("Rule: BLOCK_ARROW nodeShapeNLabel: ", $1, $2, " #3:",$3, $4); $$ = { typeStr: $1 + $4, label: $2, directions: $3}; }
       ;
     
     %%
    diff --git a/packages/mermaid/src/diagrams/block/renderHelpers.ts b/packages/mermaid/src/diagrams/block/renderHelpers.ts
    index 142de0c5cd..125cd29978 100644
    --- a/packages/mermaid/src/diagrams/block/renderHelpers.ts
    +++ b/packages/mermaid/src/diagrams/block/renderHelpers.ts
    @@ -114,6 +114,7 @@ function getNodeFromBlock(block: Block, db: BlockDB, positioned = false) {
         class: classStr,
         style: styles.style,
         id: vertex.id,
    +    directions: vertex.directions,
         // link: vertex.link,
         // linkTarget: vertex.linkTarget,
         // tooltip: diagObj.db.getTooltip(vertex.id) || '',
    diff --git a/packages/mermaid/src/diagrams/flowchart/flowRenderer-v2.js b/packages/mermaid/src/diagrams/flowchart/flowRenderer-v2.js
    index 23f94942c2..a887511d57 100644
    --- a/packages/mermaid/src/diagrams/flowchart/flowRenderer-v2.js
    +++ b/packages/mermaid/src/diagrams/flowchart/flowRenderer-v2.js
    @@ -360,8 +360,10 @@ export const getClasses = function (text, diagObj) {
      *
      * @param text
      * @param id
    + * @param _version
    + * @param diagObj
      */
    -
    +// [MermaidChart: 33a97b35-1f95-4ce9-81b5-3038669bc170]
     export const draw = async function (text, id, _version, diagObj) {
       log.info('Drawing flowchart');
       diagObj.db.clear();
    diff --git a/packages/mermaid/src/diagrams/flowchart/parser/flow.jison b/packages/mermaid/src/diagrams/flowchart/parser/flow.jison
    index 70fb491625..1957b4555c 100644
    --- a/packages/mermaid/src/diagrams/flowchart/parser/flow.jison
    +++ b/packages/mermaid/src/diagrams/flowchart/parser/flow.jison
    @@ -332,7 +332,7 @@ spaceList
     
     statement
         : verticeStatement separator
    -    { /* console.warn('finat vs', $1.nodes); */ $$=$1.nodes}
    +    { $$=$1.nodes}
         | styleStatement separator
         {$$=[];}
         | linkStyleStatement separator
    @@ -359,9 +359,9 @@ statement
     
     separator: NEWLINE | SEMI | EOF ;
     
    - 
    +
     verticeStatement: verticeStatement link node
    -        { /* console.warn('vs',$1.stmt,$3); */ yy.addLink($1.stmt,$3,$2); $$ = { stmt: $3, nodes: $3.concat($1.nodes) } }
    +        {/* console.warn('vs',$1.stmt,$3); */ yy.addLink($1.stmt,$3,$2); $$ = { stmt: $3, nodes: $3.concat($1.nodes) } }
         |  verticeStatement link node spaceList
             { /* console.warn('vs',$1.stmt,$3); */ yy.addLink($1.stmt,$3,$2); $$ = { stmt: $3, nodes: $3.concat($1.nodes) } }
         |node spaceList {/*console.warn('noda', $1);*/ $$ = {stmt: $1, nodes:$1 }}
    @@ -377,7 +377,7 @@ node: styledVertex
     styledVertex: vertex
             { /* console.warn('nod', $1); */ $$ = $1;}
         | vertex STYLE_SEPARATOR idString
    -        {$$ = $1;yy.setClass($1,$3)}
    +        { $$ = $1;yy.setClass($1,$3)}
         ;
     
     vertex:  idString SQS text SQE
    
    From 3e098ab73b320626e0b48b542e420ad6311cc427 Mon Sep 17 00:00:00 2001
    From: Ronid1 
    Date: Wed, 22 Nov 2023 18:27:47 -0800
    Subject: [PATCH 028/217] sort links alphabetically
    
    ---
     docs/ecosystem/integrations-community.md      | 182 +++++++++---------
     .../docs/ecosystem/integrations-community.md  | 182 +++++++++---------
     2 files changed, 182 insertions(+), 182 deletions(-)
    
    diff --git a/docs/ecosystem/integrations-community.md b/docs/ecosystem/integrations-community.md
    index 846ec51ac6..d74918e613 100644
    --- a/docs/ecosystem/integrations-community.md
    +++ b/docs/ecosystem/integrations-community.md
    @@ -18,48 +18,48 @@ Below are a list of community plugins and integrations created with Mermaid.
     
     ✅ = Native support
     
    +- [Atlassian Products](https://www.atlassian.com)
    +  - [Mermaid for Confluence](https://marketplace.atlassian.com/apps/1224722/mermaid-for-confluence?hosting=cloud&tab=overview)
    +  - [Mermaid Integration for Confluence](https://marketplace.atlassian.com/apps/1222792/mermaid-integration-for-confluence?hosting=cloud&tab=overview)
    +  - [Mermaid Charts & Diagrams for Confluence](https://marketplace.atlassian.com/apps/1222572/)
    +  - [Mermaid Diagrams for Confluence](https://marketplace.atlassian.com/apps/1226945/mermaid-diagrams-for-confluence?hosting=cloud&tab=overview)
    +  - [Mermaid Macro for Confluence](https://marketplace.atlassian.com/apps/1231150/mermaid-macro-for-confluence?hosting=cloud&tab=overview)
    +  - [Mermaid Live Editor for Confluence Cloud](https://marketplace.atlassian.com/apps/1231571/mermaid-live-editor-for-confluence?hosting=cloud&tab=overview)
    +  - [Mermaid Plugin for Confluence](https://marketplace.atlassian.com/apps/1214124/mermaid-plugin-for-confluence?hosting=server&tab=overview)
    +  - [EliteSoft Mermaid Charts and Diagrams](https://marketplace.atlassian.com/apps/1227286/elitesoft-mermaid-charts-and-diagrams?hosting=cloud&tab=overview)
    +  - [Auto convert diagrams in Jira](https://github.com/coddingtonbear/jirafs-mermaid)
    +  - [Mermaid for Jira Cloud - Draw UML diagrams easily](https://marketplace.atlassian.com/apps/1223053/mermaid-for-jira-cloud-draw-uml-diagrams-easily?hosting=cloud&tab=overview)
    +  - [Mermaid Charts & Diagrams for Jira](https://marketplace.atlassian.com/apps/1224537/)
    +  - [CloudScript.io Addon](https://marketplace.atlassian.com/apps/1219878/cloudscript-io-mermaid-addon?hosting=cloud&tab=overview)
    +- [Azure Devops](https://docs.microsoft.com/en-us/azure/devops/project/wiki/wiki-markdown-guidance?view=azure-devops#add-mermaid-diagrams-to-a-wiki-page) ✅
    +- [Deepdwn](https://billiam.itch.io/deepdwn) ✅
    +- [GitBook](https://gitbook.com)
    +  - [Mermaid Plugin](https://github.com/JozoVilcek/gitbook-plugin-mermaid)
    +  - [Markdown with Mermaid CLI](https://github.com/miao1007/gitbook-plugin-mermaid-cli)
    +  - [Mermaid plugin for GitBook](https://github.com/wwformat/gitbook-plugin-mermaid-pdf)
    +- [Gitea](https://gitea.io) ✅
     - [GitHub](https://github.com) ✅
       - [Using code blocks](https://github.blog/2022-02-14-include-diagrams-markdown-files-mermaid/) ✅
       - [GitHub action: Compile mermaid to image](https://github.com/neenjaw/compile-mermaid-markdown-action)
       - [svg-generator](https://github.com/SimonKenyonShepard/mermaidjs-github-svg-generator)
       - [GitHub Writer](https://github.com/ckeditor/github-writer)
     - [GitLab](https://docs.gitlab.com/ee/user/markdown.html#diagrams-and-flowcharts) ✅
    -- [Gitea](https://gitea.io) ✅
    -- [Azure Devops](https://docs.microsoft.com/en-us/azure/devops/project/wiki/wiki-markdown-guidance?view=azure-devops#add-mermaid-diagrams-to-a-wiki-page) ✅
    +- [Mermaid Plugin for JetBrains IDEs](https://plugins.jetbrains.com/plugin/20146-mermaid)
    +- [Joplin](https://joplinapp.org) ✅
    +- [LiveBook](https://livebook.dev) ✅
     - [Tuleap](https://docs.tuleap.org/user-guide/writing-in-tuleap.html#graphs) ✅
     - [Mermaid Flow Visual Editor](https://www.mermaidflow.app) ✅
    -- [Deepdwn](https://billiam.itch.io/deepdwn) ✅
    -- [Joplin](https://joplinapp.org) ✅
    +- [mermerd](https://github.com/KarnerTh/mermerd)
     - [Slab](https://slab.com) ✅
     - [Swimm](https://swimm.io) ✅
    +- [NotesHub](https://noteshub.app) ✅
     - [Notion](https://notion.so) ✅
     - [Observable](https://observablehq.com/@observablehq/mermaid) ✅
     - [Obsidian](https://help.obsidian.md/Editing+and+formatting/Advanced+formatting+syntax#Diagram) ✅
    -- [NotesHub](https://noteshub.app) ✅
    -- [GitBook](https://gitbook.com)
    -  - [Mermaid Plugin](https://github.com/JozoVilcek/gitbook-plugin-mermaid)
    -  - [Markdown with Mermaid CLI](https://github.com/miao1007/gitbook-plugin-mermaid-cli)
    -  - [Mermaid plugin for GitBook](https://github.com/wwformat/gitbook-plugin-mermaid-pdf)
    -- [LiveBook](https://livebook.dev) ✅
    -- [Atlassian Products](https://www.atlassian.com)
    -  - [Mermaid for Confluence](https://marketplace.atlassian.com/apps/1224722/mermaid-for-confluence?hosting=cloud&tab=overview)
    -  - [Mermaid Integration for Confluence](https://marketplace.atlassian.com/apps/1222792/mermaid-integration-for-confluence?hosting=cloud&tab=overview)
    -  - [Mermaid Diagrams for Confluence](https://marketplace.atlassian.com/apps/1226945/mermaid-diagrams-for-confluence?hosting=cloud&tab=overview)
    -  - [Mermaid Macro for Confluence](https://marketplace.atlassian.com/apps/1231150/mermaid-macro-for-confluence?hosting=cloud&tab=overview)
    -  - [EliteSoft Mermaid Charts and Diagrams](https://marketplace.atlassian.com/apps/1227286/elitesoft-mermaid-charts-and-diagrams?hosting=cloud&tab=overview)
    -  - [Mermaid for Jira Cloud - Draw UML diagrams easily](https://marketplace.atlassian.com/apps/1223053/mermaid-for-jira-cloud-draw-uml-diagrams-easily?hosting=cloud&tab=overview)
    -  - [Mermaid Charts & Diagrams for Confluence](https://marketplace.atlassian.com/apps/1222572/)
    -  - [Mermaid Charts & Diagrams for Jira](https://marketplace.atlassian.com/apps/1224537/)
    -  - [Mermaid Live Editor for Confluence Cloud](https://marketplace.atlassian.com/apps/1231571/mermaid-live-editor-for-confluence?hosting=cloud&tab=overview)
    -  - [Mermaid Plugin for Confluence](https://marketplace.atlassian.com/apps/1214124/mermaid-plugin-for-confluence?hosting=server&tab=overview)
    -  - [CloudScript.io Addon](https://marketplace.atlassian.com/apps/1219878/cloudscript-io-mermaid-addon?hosting=cloud&tab=overview)
    -  - [Auto convert diagrams in Jira](https://github.com/coddingtonbear/jirafs-mermaid)
     - [Redmine](https://redmine.org)
       - [Mermaid Macro](https://www.redmine.org/plugins/redmine_mermaid_macro)
       - [redmine-mermaid](https://github.com/styz/redmine_mermaid)
       - [markdown-for-mermaid-plugin](https://github.com/jamieh-mongolian/markdown-for-mermaid-plugin)
    -- [Mermaid Plugin for JetBrains IDEs](https://plugins.jetbrains.com/plugin/20146-mermaid)
    -- [mermerd](https://github.com/KarnerTh/mermerd)
     - Visual Studio Code [Polyglot Interactive Notebooks](https://github.com/dotnet/interactive#net-interactive)
     
     ### CRM/ERP
    @@ -72,27 +72,27 @@ Customer Relationship Management/Enterprise Resource Planning
     
     Blogging frameworks and platforms
     
    -- [WordPress](https://wordpress.org)
    -  - [WordPress Markdown Editor](https://wordpress.org/plugins/wp-githuber-md)
    -  - [WP-ReliableMD](https://wordpress.org/plugins/wp-reliablemd/)
     - [Hexo](https://hexo.io)
       - [hexo-filter-mermaid-diagrams](https://github.com/webappdevelp/hexo-filter-mermaid-diagrams)
       - [hexo-tag-mermaid](https://github.com/JameChou/hexo-tag-mermaid)
       - [hexo-mermaid-diagrams](https://github.com/mslxl/hexo-mermaid-diagrams)
     - [Nextra](https://nextra.site/)
       - [Mermaid](https://nextra.site/docs/guide/mermaid)
    +- [WordPress](https://wordpress.org)
    +  - [WordPress Markdown Editor](https://wordpress.org/plugins/wp-githuber-md)
    +  - [WP-ReliableMD](https://wordpress.org/plugins/wp-reliablemd/)
     
     ### CMS/ECM
     
     Content Management Systems/Enterprise Content Management
     
    +- [Grav CMS](https://getgrav.org/)
    +  - [Mermaid Diagrams](https://github.com/DanielFlaum/grav-plugin-mermaid-diagrams)
    +  - [GitLab Markdown Adapter](https://github.com/Goutte/grav-plugin-gitlab-markdown-adapter)
     - [VitePress](https://vitepress.vuejs.org/)
       - [Plugin for Mermaid.js](https://emersonbottero.github.io/vitepress-plugin-mermaid/)
     - [VuePress](https://vuepress.vuejs.org/)
       - [Plugin for Mermaid.js](https://github.com/eFrane/vuepress-plugin-mermaidjs)
    -- [Grav CMS](https://getgrav.org/)
    -  - [Mermaid Diagrams](https://github.com/DanielFlaum/grav-plugin-mermaid-diagrams)
    -  - [GitLab Markdown Adapter](https://github.com/Goutte/grav-plugin-gitlab-markdown-adapter)
     
     ### Communication
     
    @@ -102,105 +102,105 @@ Communication tools and platforms
       - [Mermaid Plugin](https://github.com/pnewell/discourse-mermaid), [And](https://github.com/unfoldingWord-dev/discourse-mermaid)
     - [Mattermost](https://mattermost.com/)
       - [Mermaid Plugin](https://github.com/SpikeTings/Mermaid)
    -- [phpBB](https://phpbb.com)
    -  - [phpbb-ext-mermaid](https://github.com/AlfredoRamos/phpbb-ext-mermaid)
     - [NodeBB](https://nodebb.org)
       - [Mermaid Plugin](https://www.npmjs.com/package/nodebb-plugin-mermaid)
    +- [phpBB](https://phpbb.com)
    +  - [phpbb-ext-mermaid](https://github.com/AlfredoRamos/phpbb-ext-mermaid)
     - [Slack](https://slack.com)
       - [Mermaid for Slack](https://github.com/JackuB/mermaid-for-slack)
     
     ### Wikis
     
    +- [DokuWiki](https://dokuwiki.org)
    +  - [Mermaid Plugin](https://www.dokuwiki.org/plugin:mermaid)
    +  - [ComboStrap](https://combostrap.com/mermaid)
    +- [Foswiki](https://foswiki.org)
    +  - [Mermaid Plugin](https://foswiki.org/Extensions/MermaidPlugin)
     - [MediaWiki](https://www.mediawiki.org)
       - [Mermaid Extension](https://www.mediawiki.org/wiki/Extension:Mermaid)
       - [Flex Diagrams Extension](https://www.mediawiki.org/wiki/Extension:Flex_Diagrams)
     - [Semantic Media Wiki](https://semantic-mediawiki.org)
       - [Mermaid Plugin](https://github.com/SemanticMediaWiki/Mermaid)
    -- [Foswiki](https://foswiki.org)
    -  - [Mermaid Plugin](https://foswiki.org/Extensions/MermaidPlugin)
    -- [DokuWiki](https://dokuwiki.org)
    -  - [Mermaid Plugin](https://www.dokuwiki.org/plugin:mermaid)
    -  - [ComboStrap](https://combostrap.com/mermaid)
     - [TiddlyWiki](https://tiddlywiki.com/)
       - [mermaid-tw5: full js library](https://github.com/efurlanm/mermaid-tw5)
       - [tw5-mermaid: wrapper for Mermaid Live](https://github.com/jasonmhoule/tw5-mermaid)
     
     ### Editor Plugins
     
    -- [VS Code](https://code.visualstudio.com/)
    -  - [Markdown Preview Mermaid Support](https://marketplace.visualstudio.com/items?itemName=bierner.markdown-mermaid)
    -  - [Mermaid Preview](https://marketplace.visualstudio.com/items?itemName=vstirbu.vscode-mermaid-preview)
    -  - [Markdown Preview Enhanced](https://marketplace.visualstudio.com/items?itemName=shd101wyy.markdown-preview-enhanced)
    -  - [Mermaid Markdown Syntax Highlighting](https://marketplace.visualstudio.com/items?itemName=bpruitt-goddard.mermaid-markdown-syntax-highlighting)
    -  - [Mermaid Editor](https://marketplace.visualstudio.com/items?itemName=tomoyukim.vscode-mermaid-editor)
    -  - [Mermaid Export](https://marketplace.visualstudio.com/items?itemName=Gruntfuggly.mermaid-export)
    -  - [Markdown PDF](https://marketplace.visualstudio.com/items?itemName=yzane.markdown-pdf)
    -  - [Preview](https://marketplace.visualstudio.com/items?itemName=searKing.preview-vscode)
    -  - [Preview Sequence Diagrams](https://marketplace.visualstudio.com/items?itemName=arichika.previewseqdiag-vscode)
    -- [Markdown-It](https://github.com/markdown-it/markdown-it)
    -  - [Textual UML Parser](https://github.com/manastalukdar/markdown-it-textual-uml)
    -  - [Mermaid Plugin](https://github.com/tylingsoft/markdown-it-mermaid)
    -  - [md-it-mermaid](https://github.com/iamcco/md-it-mermaid)
    -  - [markdown-it-mermaid-fence-new](https://github.com/Revomatico/markdown-it-mermaid-fence-new)
    -  - [markdown-it-mermaid-less](https://github.com/searKing/markdown-it-mermaid-less)
     - Atom _(Atom has been [archived.](https://github.blog/2022-06-08-sunsetting-atom/))_
       - [Markdown Preview Enhanced](https://github.com/shd101wyy/markdown-preview-enhanced)
       - [Atom Mermaid](https://github.com/y-takey/atom-mermaid)
       - [Language Mermaid Syntax Highlighter](https://github.com/ytisf/language-mermaid)
    -- [Sublime Text 3](https://sublimetext.com)
    -  - [Mermaid Package](https://packagecontrol.io/packages/Mermaid)
     - [Astah](https://astah.net)
       - [Export to Mermaid](https://github.com/Avens666/Astah_Jude_UML_export_to_Markdown-mermaid-Plantuml-)
    -- [Light Table](http://lighttable.com/)
    -  - [Mermaid Plugin](https://github.com/cldwalker/Mermaid)
    +- [Brackets](https://brackets.io/)
    +  - [Mermaid Preview](https://github.com/AlanHohn/mermaid-preview)
    +- [CKEditor](https://github.com/ckeditor/ckeditor5)
    +  - [CKEditor 5 Mermaid plugin](https://github.com/ckeditor/ckeditor5-mermaid)
     - [Draw.io](https://draw.io) - [Plugin](https://github.com/nopeslide/drawio_mermaid_plugin)
    -- [Inkdrop](https://www.inkdrop.app) - [Plugin](https://github.com/inkdropapp/inkdrop-mermaid)
    -- [Vim](https://www.vim.org)
    -  - [Official Vim Syntax and ftplugin](https://github.com/craigmac/vim-mermaid)
    -  - [Vim Diagram Syntax](https://github.com/zhaozg/vim-diagram)
     - [GNU Emacs](https://www.gnu.org/software/emacs/)
       - [Major mode for .mmd files](https://github.com/abrochard/mermaid-mode)
       - [Org-Mode integration](https://github.com/arnm/ob-mermaid)
    -- [Brackets](https://brackets.io/)
    -  - [Mermaid Preview](https://github.com/AlanHohn/mermaid-preview)
    -- [Iodide](https://github.com/iodide-project/iodide)
    -  - [iodide-mermaid-plugin](https://github.com/iodide-project/iodide-mermaid-plugin)
    +- [GNU Nano](https://www.nano-editor.org/)
    +  - [Nano Mermaid](https://github.com/Yash-Singh1/nano-mermaid)
     - [Google docs](https://docs.google.com/)
       - [Mermaid plugin for google docs](https://workspace.google.com/marketplace/app/mermaid/636321283856)
    +- [Inkdrop](https://www.inkdrop.app) - [Plugin](https://github.com/inkdropapp/inkdrop-mermaid)
    +- [Iodide](https://github.com/iodide-project/iodide)
    +  - [iodide-mermaid-plugin](https://github.com/iodide-project/iodide-mermaid-plugin)
    +- [Light Table](http://lighttable.com/)
    +  - [Mermaid Plugin](https://github.com/cldwalker/Mermaid)
    +- [Markdown-It](https://github.com/markdown-it/markdown-it)
    +  - [Textual UML Parser](https://github.com/manastalukdar/markdown-it-textual-uml)
    +  - [Mermaid Plugin](https://github.com/tylingsoft/markdown-it-mermaid)
    +  - [md-it-mermaid](https://github.com/iamcco/md-it-mermaid)
    +  - [markdown-it-mermaid-fence-new](https://github.com/Revomatico/markdown-it-mermaid-fence-new)
    +  - [markdown-it-mermaid-less](https://github.com/searKing/markdown-it-mermaid-less)
     - [Podlite](https://github.com/zag/podlite-desktop)
       - [Named block =Diagram](https://github.com/zag/podlite/tree/main/packages/podlite-diagrams)
    -- [GNU Nano](https://www.nano-editor.org/)
    -  - [Nano Mermaid](https://github.com/Yash-Singh1/nano-mermaid)
    -- [CKEditor](https://github.com/ckeditor/ckeditor5)
    -  - [CKEditor 5 Mermaid plugin](https://github.com/ckeditor/ckeditor5-mermaid)
     - [Standard Notes](https://standardnotes.com/)
       - [sn-mermaid](https://github.com/nienow/sn-mermaid)
    +- [Sublime Text 3](https://sublimetext.com)
    +  - [Mermaid Package](https://packagecontrol.io/packages/Mermaid)
    +- [VS Code](https://code.visualstudio.com/)
    +  - [Markdown Preview Mermaid Support](https://marketplace.visualstudio.com/items?itemName=bierner.markdown-mermaid)
    +  - [Mermaid Preview](https://marketplace.visualstudio.com/items?itemName=vstirbu.vscode-mermaid-preview)
    +  - [Markdown Preview Enhanced](https://marketplace.visualstudio.com/items?itemName=shd101wyy.markdown-preview-enhanced)
    +  - [Mermaid Markdown Syntax Highlighting](https://marketplace.visualstudio.com/items?itemName=bpruitt-goddard.mermaid-markdown-syntax-highlighting)
    +  - [Mermaid Editor](https://marketplace.visualstudio.com/items?itemName=tomoyukim.vscode-mermaid-editor)
    +  - [Mermaid Export](https://marketplace.visualstudio.com/items?itemName=Gruntfuggly.mermaid-export)
    +  - [Markdown PDF](https://marketplace.visualstudio.com/items?itemName=yzane.markdown-pdf)
    +  - [Preview](https://marketplace.visualstudio.com/items?itemName=searKing.preview-vscode)
    +  - [Preview Sequence Diagrams](https://marketplace.visualstudio.com/items?itemName=arichika.previewseqdiag-vscode)
    +- [Vim](https://www.vim.org)
    +  - [Official Vim Syntax and ftplugin](https://github.com/craigmac/vim-mermaid)
    +  - [Vim Diagram Syntax](https://github.com/zhaozg/vim-diagram)
     
     ### Document Generation
     
    +- [Codedoc](https://codedoc.cc/)
    +  - [codedoc-mermaid-plugin](https://www.npmjs.com/package/codedoc-mermaid-plugin)
    +- [Docsy Hugo Theme](https://www.docsy.dev/docs/adding-content/lookandfeel/#diagrams-with-mermaid) (native support in theme)
     - [Docusaurus](https://docusaurus.io/docs/markdown-features/diagrams) ✅
    -- [Swimm - Up-to-date diagrams with Swimm, the knowledge management tool for code](https://docs.swimm.io/features/diagrams-and-charts/#mermaid--swimm--up-to-date-diagrams-)
    -- [Sphinx](https://www.sphinx-doc.org/en/master/)
    -  - [sphinxcontrib-mermaid](https://github.com/mgaitan/sphinxcontrib-mermaid)
    -- [remark](https://remark.js.org/)
    -  - [remark-mermaidjs](https://github.com/remcohaszing/remark-mermaidjs)
    -- [rehype](https://github.com/rehypejs/rehype)
    -  - [rehype-mermaid](https://github.com/remcohaszing/rehype-mermaid)
     - [Gatsby](https://www.gatsbyjs.com/)
       - [gatsby-remark-mermaid](https://github.com/remcohaszing/gatsby-remark-mermaid)
     - [JSDoc](https://jsdoc.app/)
       - [jsdoc-mermaid](https://github.com/Jellyvision/jsdoc-mermaid)
    +- [mdbook](https://rust-lang.github.io/mdBook/index.html)
    +  - [mdbook-mermaid](https://github.com/badboy/mdbook-mermaid)
     - [MkDocs](https://www.mkdocs.org)
       - [mkdocs-mermaid2-plugin](https://github.com/fralau/mkdocs-mermaid2-plugin)
       - [mkdocs-material](https://github.com/squidfunk/mkdocs-material), check the [docs](https://squidfunk.github.io/mkdocs-material/reference/diagrams/)
    +  - [Quarto](https://quarto.org/)
    +- [rehype](https://github.com/rehypejs/rehype)
    +  - [rehype-mermaid](https://github.com/remcohaszing/rehype-mermaid)
    +- [remark](https://remark.js.org/)
    +  - [remark-mermaidjs](https://github.com/remcohaszing/remark-mermaidjs)
    +- [Sphinx](https://www.sphinx-doc.org/en/master/)
    +  - [sphinxcontrib-mermaid](https://github.com/mgaitan/sphinxcontrib-mermaid)
    +- [Swimm - Up-to-date diagrams with Swimm, the knowledge management tool for code](https://docs.swimm.io/features/diagrams-and-charts/#mermaid--swimm--up-to-date-diagrams-)
     - [Type Doc](https://typedoc.org/)
       - [typedoc-plugin-mermaid](https://www.npmjs.com/package/typedoc-plugin-mermaid)
    -- [Docsy Hugo Theme](https://www.docsy.dev/docs/adding-content/lookandfeel/#diagrams-with-mermaid) (native support in theme)
    -- [Codedoc](https://codedoc.cc/)
    -  - [codedoc-mermaid-plugin](https://www.npmjs.com/package/codedoc-mermaid-plugin)
    -- [mdbook](https://rust-lang.github.io/mdBook/index.html)
    -  - [mdbook-mermaid](https://github.com/badboy/mdbook-mermaid)
    -- [Quarto](https://quarto.org/)
     - [Typora](https://typora.io/) ([native support](https://support.typora.io/Draw-Diagrams-With-Markdown/#mermaid))
     
     ### Browser Extensions
    @@ -220,19 +220,19 @@ Communication tools and platforms
     
     ### Other
     
    +- [Bisheng](https://www.npmjs.com/package/bisheng)
    +  - [bisheng-plugin-mermaid](https://github.com/yct21/bisheng-plugin-mermaid)
    +- [ExDoc](https://github.com/elixir-lang/ex_doc)
    +  - [Rendering Mermaid graphs](https://github.com/elixir-lang/ex_doc#rendering-mermaid-graphs)
     - [Jekyll](https://jekyllrb.com/)
       - [jekyll-mermaid](https://rubygems.org/gems/jekyll-mermaid)
       - [jekyll-mermaid-diagrams](https://github.com/fuzhibo/jekyll-mermaid-diagrams)
    -- [Reveal.js](https://github.com/hakimel/reveal.js)
    -  - [reveal.js-mermaid-plugin](https://github.com/ludwick/reveal.js-mermaid-plugin)
    -- [Bisheng](https://www.npmjs.com/package/bisheng)
    -  - [bisheng-plugin-mermaid](https://github.com/yct21/bisheng-plugin-mermaid)
    -- [Reveal CK](https://github.com/jedcn/reveal-ck)
    -  - [reveal-ck-mermaid-plugin](https://github.com/tmtm/reveal-ck-mermaid-plugin)
     - [mermaid-isomorphic](https://github.com/remcohaszing/mermaid-isomorphic)
     - [mermaid-server: Generate diagrams using a HTTP request](https://github.com/TomWright/mermaid-server)
    -- [ExDoc](https://github.com/elixir-lang/ex_doc)
    -  - [Rendering Mermaid graphs](https://github.com/elixir-lang/ex_doc#rendering-mermaid-graphs)
     - [NiceGUI: Let any browser be the frontend of your Python code](https://nicegui.io)
       - [ui.mermaid(...)](https://nicegui.io/reference#mermaid_diagrams)
       - [ui.markdown(..., extras=\['mermaid'\])](https://nicegui.io/reference#markdown_element)
    +- [Reveal.js](https://github.com/hakimel/reveal.js)
    +  - [reveal.js-mermaid-plugin](https://github.com/ludwick/reveal.js-mermaid-plugin)
    +- [Reveal CK](https://github.com/jedcn/reveal-ck)
    +  - [reveal-ck-mermaid-plugin](https://github.com/tmtm/reveal-ck-mermaid-plugin)
    diff --git a/packages/mermaid/src/docs/ecosystem/integrations-community.md b/packages/mermaid/src/docs/ecosystem/integrations-community.md
    index b3f7213046..b48746bc41 100644
    --- a/packages/mermaid/src/docs/ecosystem/integrations-community.md
    +++ b/packages/mermaid/src/docs/ecosystem/integrations-community.md
    @@ -16,48 +16,48 @@ Below are a list of community plugins and integrations created with Mermaid.
     
     ✅ = Native support
     
    +- [Atlassian Products](https://www.atlassian.com)
    +  - [Mermaid for Confluence](https://marketplace.atlassian.com/apps/1224722/mermaid-for-confluence?hosting=cloud&tab=overview)
    +  - [Mermaid Integration for Confluence](https://marketplace.atlassian.com/apps/1222792/mermaid-integration-for-confluence?hosting=cloud&tab=overview)
    +  - [Mermaid Charts & Diagrams for Confluence](https://marketplace.atlassian.com/apps/1222572/)
    +  - [Mermaid Diagrams for Confluence](https://marketplace.atlassian.com/apps/1226945/mermaid-diagrams-for-confluence?hosting=cloud&tab=overview)
    +  - [Mermaid Macro for Confluence](https://marketplace.atlassian.com/apps/1231150/mermaid-macro-for-confluence?hosting=cloud&tab=overview)
    +  - [Mermaid Live Editor for Confluence Cloud](https://marketplace.atlassian.com/apps/1231571/mermaid-live-editor-for-confluence?hosting=cloud&tab=overview)
    +  - [Mermaid Plugin for Confluence](https://marketplace.atlassian.com/apps/1214124/mermaid-plugin-for-confluence?hosting=server&tab=overview)
    +  - [EliteSoft Mermaid Charts and Diagrams](https://marketplace.atlassian.com/apps/1227286/elitesoft-mermaid-charts-and-diagrams?hosting=cloud&tab=overview)
    +  - [Auto convert diagrams in Jira](https://github.com/coddingtonbear/jirafs-mermaid)
    +  - [Mermaid for Jira Cloud - Draw UML diagrams easily](https://marketplace.atlassian.com/apps/1223053/mermaid-for-jira-cloud-draw-uml-diagrams-easily?hosting=cloud&tab=overview)
    +  - [Mermaid Charts & Diagrams for Jira](https://marketplace.atlassian.com/apps/1224537/)
    +  - [CloudScript.io Addon](https://marketplace.atlassian.com/apps/1219878/cloudscript-io-mermaid-addon?hosting=cloud&tab=overview)
    +- [Azure Devops](https://docs.microsoft.com/en-us/azure/devops/project/wiki/wiki-markdown-guidance?view=azure-devops#add-mermaid-diagrams-to-a-wiki-page) ✅
    +- [Deepdwn](https://billiam.itch.io/deepdwn) ✅
    +- [GitBook](https://gitbook.com)
    +  - [Mermaid Plugin](https://github.com/JozoVilcek/gitbook-plugin-mermaid)
    +  - [Markdown with Mermaid CLI](https://github.com/miao1007/gitbook-plugin-mermaid-cli)
    +  - [Mermaid plugin for GitBook](https://github.com/wwformat/gitbook-plugin-mermaid-pdf)
    +- [Gitea](https://gitea.io) ✅
     - [GitHub](https://github.com) ✅
       - [Using code blocks](https://github.blog/2022-02-14-include-diagrams-markdown-files-mermaid/) ✅
       - [GitHub action: Compile mermaid to image](https://github.com/neenjaw/compile-mermaid-markdown-action)
       - [svg-generator](https://github.com/SimonKenyonShepard/mermaidjs-github-svg-generator)
       - [GitHub Writer](https://github.com/ckeditor/github-writer)
     - [GitLab](https://docs.gitlab.com/ee/user/markdown.html#diagrams-and-flowcharts) ✅
    -- [Gitea](https://gitea.io) ✅
    -- [Azure Devops](https://docs.microsoft.com/en-us/azure/devops/project/wiki/wiki-markdown-guidance?view=azure-devops#add-mermaid-diagrams-to-a-wiki-page) ✅
    +- [Mermaid Plugin for JetBrains IDEs](https://plugins.jetbrains.com/plugin/20146-mermaid)
    +- [Joplin](https://joplinapp.org) ✅
    +- [LiveBook](https://livebook.dev) ✅
     - [Tuleap](https://docs.tuleap.org/user-guide/writing-in-tuleap.html#graphs) ✅
     - [Mermaid Flow Visual Editor](https://www.mermaidflow.app) ✅
    -- [Deepdwn](https://billiam.itch.io/deepdwn) ✅
    -- [Joplin](https://joplinapp.org) ✅
    +- [mermerd](https://github.com/KarnerTh/mermerd)
     - [Slab](https://slab.com) ✅
     - [Swimm](https://swimm.io) ✅
    +- [NotesHub](https://noteshub.app) ✅
     - [Notion](https://notion.so) ✅
     - [Observable](https://observablehq.com/@observablehq/mermaid) ✅
     - [Obsidian](https://help.obsidian.md/Editing+and+formatting/Advanced+formatting+syntax#Diagram) ✅
    -- [NotesHub](https://noteshub.app) ✅
    -- [GitBook](https://gitbook.com)
    -  - [Mermaid Plugin](https://github.com/JozoVilcek/gitbook-plugin-mermaid)
    -  - [Markdown with Mermaid CLI](https://github.com/miao1007/gitbook-plugin-mermaid-cli)
    -  - [Mermaid plugin for GitBook](https://github.com/wwformat/gitbook-plugin-mermaid-pdf)
    -- [LiveBook](https://livebook.dev) ✅
    -- [Atlassian Products](https://www.atlassian.com)
    -  - [Mermaid for Confluence](https://marketplace.atlassian.com/apps/1224722/mermaid-for-confluence?hosting=cloud&tab=overview)
    -  - [Mermaid Integration for Confluence](https://marketplace.atlassian.com/apps/1222792/mermaid-integration-for-confluence?hosting=cloud&tab=overview)
    -  - [Mermaid Diagrams for Confluence](https://marketplace.atlassian.com/apps/1226945/mermaid-diagrams-for-confluence?hosting=cloud&tab=overview)
    -  - [Mermaid Macro for Confluence](https://marketplace.atlassian.com/apps/1231150/mermaid-macro-for-confluence?hosting=cloud&tab=overview)
    -  - [EliteSoft Mermaid Charts and Diagrams](https://marketplace.atlassian.com/apps/1227286/elitesoft-mermaid-charts-and-diagrams?hosting=cloud&tab=overview)
    -  - [Mermaid for Jira Cloud - Draw UML diagrams easily](https://marketplace.atlassian.com/apps/1223053/mermaid-for-jira-cloud-draw-uml-diagrams-easily?hosting=cloud&tab=overview)
    -  - [Mermaid Charts & Diagrams for Confluence](https://marketplace.atlassian.com/apps/1222572/)
    -  - [Mermaid Charts & Diagrams for Jira](https://marketplace.atlassian.com/apps/1224537/)
    -  - [Mermaid Live Editor for Confluence Cloud](https://marketplace.atlassian.com/apps/1231571/mermaid-live-editor-for-confluence?hosting=cloud&tab=overview)
    -  - [Mermaid Plugin for Confluence](https://marketplace.atlassian.com/apps/1214124/mermaid-plugin-for-confluence?hosting=server&tab=overview)
    -  - [CloudScript.io Addon](https://marketplace.atlassian.com/apps/1219878/cloudscript-io-mermaid-addon?hosting=cloud&tab=overview)
    -  - [Auto convert diagrams in Jira](https://github.com/coddingtonbear/jirafs-mermaid)
     - [Redmine](https://redmine.org)
       - [Mermaid Macro](https://www.redmine.org/plugins/redmine_mermaid_macro)
       - [redmine-mermaid](https://github.com/styz/redmine_mermaid)
       - [markdown-for-mermaid-plugin](https://github.com/jamieh-mongolian/markdown-for-mermaid-plugin)
    -- [Mermaid Plugin for JetBrains IDEs](https://plugins.jetbrains.com/plugin/20146-mermaid)
    -- [mermerd](https://github.com/KarnerTh/mermerd)
     - Visual Studio Code [Polyglot Interactive Notebooks](https://github.com/dotnet/interactive#net-interactive)
     
     ### CRM/ERP
    @@ -70,27 +70,27 @@ Customer Relationship Management/Enterprise Resource Planning
     
     Blogging frameworks and platforms
     
    -- [WordPress](https://wordpress.org)
    -  - [WordPress Markdown Editor](https://wordpress.org/plugins/wp-githuber-md)
    -  - [WP-ReliableMD](https://wordpress.org/plugins/wp-reliablemd/)
     - [Hexo](https://hexo.io)
       - [hexo-filter-mermaid-diagrams](https://github.com/webappdevelp/hexo-filter-mermaid-diagrams)
       - [hexo-tag-mermaid](https://github.com/JameChou/hexo-tag-mermaid)
       - [hexo-mermaid-diagrams](https://github.com/mslxl/hexo-mermaid-diagrams)
     - [Nextra](https://nextra.site/)
       - [Mermaid](https://nextra.site/docs/guide/mermaid)
    +- [WordPress](https://wordpress.org)
    +  - [WordPress Markdown Editor](https://wordpress.org/plugins/wp-githuber-md)
    +  - [WP-ReliableMD](https://wordpress.org/plugins/wp-reliablemd/)
     
     ### CMS/ECM
     
     Content Management Systems/Enterprise Content Management
     
    +- [Grav CMS](https://getgrav.org/)
    +  - [Mermaid Diagrams](https://github.com/DanielFlaum/grav-plugin-mermaid-diagrams)
    +  - [GitLab Markdown Adapter](https://github.com/Goutte/grav-plugin-gitlab-markdown-adapter)
     - [VitePress](https://vitepress.vuejs.org/)
       - [Plugin for Mermaid.js](https://emersonbottero.github.io/vitepress-plugin-mermaid/)
     - [VuePress](https://vuepress.vuejs.org/)
       - [Plugin for Mermaid.js](https://github.com/eFrane/vuepress-plugin-mermaidjs)
    -- [Grav CMS](https://getgrav.org/)
    -  - [Mermaid Diagrams](https://github.com/DanielFlaum/grav-plugin-mermaid-diagrams)
    -  - [GitLab Markdown Adapter](https://github.com/Goutte/grav-plugin-gitlab-markdown-adapter)
     
     ### Communication
     
    @@ -100,105 +100,105 @@ Communication tools and platforms
       - [Mermaid Plugin](https://github.com/pnewell/discourse-mermaid), [And](https://github.com/unfoldingWord-dev/discourse-mermaid)
     - [Mattermost](https://mattermost.com/)
       - [Mermaid Plugin](https://github.com/SpikeTings/Mermaid)
    -- [phpBB](https://phpbb.com)
    -  - [phpbb-ext-mermaid](https://github.com/AlfredoRamos/phpbb-ext-mermaid)
     - [NodeBB](https://nodebb.org)
       - [Mermaid Plugin](https://www.npmjs.com/package/nodebb-plugin-mermaid)
    +- [phpBB](https://phpbb.com)
    +  - [phpbb-ext-mermaid](https://github.com/AlfredoRamos/phpbb-ext-mermaid)
     - [Slack](https://slack.com)
       - [Mermaid for Slack](https://github.com/JackuB/mermaid-for-slack)
     
     ### Wikis
     
    +- [DokuWiki](https://dokuwiki.org)
    +  - [Mermaid Plugin](https://www.dokuwiki.org/plugin:mermaid)
    +  - [ComboStrap](https://combostrap.com/mermaid)
    +- [Foswiki](https://foswiki.org)
    +  - [Mermaid Plugin](https://foswiki.org/Extensions/MermaidPlugin)
     - [MediaWiki](https://www.mediawiki.org)
       - [Mermaid Extension](https://www.mediawiki.org/wiki/Extension:Mermaid)
       - [Flex Diagrams Extension](https://www.mediawiki.org/wiki/Extension:Flex_Diagrams)
     - [Semantic Media Wiki](https://semantic-mediawiki.org)
       - [Mermaid Plugin](https://github.com/SemanticMediaWiki/Mermaid)
    -- [Foswiki](https://foswiki.org)
    -  - [Mermaid Plugin](https://foswiki.org/Extensions/MermaidPlugin)
    -- [DokuWiki](https://dokuwiki.org)
    -  - [Mermaid Plugin](https://www.dokuwiki.org/plugin:mermaid)
    -  - [ComboStrap](https://combostrap.com/mermaid)
     - [TiddlyWiki](https://tiddlywiki.com/)
       - [mermaid-tw5: full js library](https://github.com/efurlanm/mermaid-tw5)
       - [tw5-mermaid: wrapper for Mermaid Live](https://github.com/jasonmhoule/tw5-mermaid)
     
     ### Editor Plugins
     
    -- [VS Code](https://code.visualstudio.com/)
    -  - [Markdown Preview Mermaid Support](https://marketplace.visualstudio.com/items?itemName=bierner.markdown-mermaid)
    -  - [Mermaid Preview](https://marketplace.visualstudio.com/items?itemName=vstirbu.vscode-mermaid-preview)
    -  - [Markdown Preview Enhanced](https://marketplace.visualstudio.com/items?itemName=shd101wyy.markdown-preview-enhanced)
    -  - [Mermaid Markdown Syntax Highlighting](https://marketplace.visualstudio.com/items?itemName=bpruitt-goddard.mermaid-markdown-syntax-highlighting)
    -  - [Mermaid Editor](https://marketplace.visualstudio.com/items?itemName=tomoyukim.vscode-mermaid-editor)
    -  - [Mermaid Export](https://marketplace.visualstudio.com/items?itemName=Gruntfuggly.mermaid-export)
    -  - [Markdown PDF](https://marketplace.visualstudio.com/items?itemName=yzane.markdown-pdf)
    -  - [Preview](https://marketplace.visualstudio.com/items?itemName=searKing.preview-vscode)
    -  - [Preview Sequence Diagrams](https://marketplace.visualstudio.com/items?itemName=arichika.previewseqdiag-vscode)
    -- [Markdown-It](https://github.com/markdown-it/markdown-it)
    -  - [Textual UML Parser](https://github.com/manastalukdar/markdown-it-textual-uml)
    -  - [Mermaid Plugin](https://github.com/tylingsoft/markdown-it-mermaid)
    -  - [md-it-mermaid](https://github.com/iamcco/md-it-mermaid)
    -  - [markdown-it-mermaid-fence-new](https://github.com/Revomatico/markdown-it-mermaid-fence-new)
    -  - [markdown-it-mermaid-less](https://github.com/searKing/markdown-it-mermaid-less)
     - Atom _(Atom has been [archived.](https://github.blog/2022-06-08-sunsetting-atom/))_
       - [Markdown Preview Enhanced](https://github.com/shd101wyy/markdown-preview-enhanced)
       - [Atom Mermaid](https://github.com/y-takey/atom-mermaid)
       - [Language Mermaid Syntax Highlighter](https://github.com/ytisf/language-mermaid)
    -- [Sublime Text 3](https://sublimetext.com)
    -  - [Mermaid Package](https://packagecontrol.io/packages/Mermaid)
     - [Astah](https://astah.net)
       - [Export to Mermaid](https://github.com/Avens666/Astah_Jude_UML_export_to_Markdown-mermaid-Plantuml-)
    -- [Light Table](http://lighttable.com/)
    -  - [Mermaid Plugin](https://github.com/cldwalker/Mermaid)
    +- [Brackets](https://brackets.io/)
    +  - [Mermaid Preview](https://github.com/AlanHohn/mermaid-preview)
    +- [CKEditor](https://github.com/ckeditor/ckeditor5)
    +  - [CKEditor 5 Mermaid plugin](https://github.com/ckeditor/ckeditor5-mermaid)
     - [Draw.io](https://draw.io) - [Plugin](https://github.com/nopeslide/drawio_mermaid_plugin)
    -- [Inkdrop](https://www.inkdrop.app) - [Plugin](https://github.com/inkdropapp/inkdrop-mermaid)
    -- [Vim](https://www.vim.org)
    -  - [Official Vim Syntax and ftplugin](https://github.com/craigmac/vim-mermaid)
    -  - [Vim Diagram Syntax](https://github.com/zhaozg/vim-diagram)
     - [GNU Emacs](https://www.gnu.org/software/emacs/)
       - [Major mode for .mmd files](https://github.com/abrochard/mermaid-mode)
       - [Org-Mode integration](https://github.com/arnm/ob-mermaid)
    -- [Brackets](https://brackets.io/)
    -  - [Mermaid Preview](https://github.com/AlanHohn/mermaid-preview)
    -- [Iodide](https://github.com/iodide-project/iodide)
    -  - [iodide-mermaid-plugin](https://github.com/iodide-project/iodide-mermaid-plugin)
    +- [GNU Nano](https://www.nano-editor.org/)
    +  - [Nano Mermaid](https://github.com/Yash-Singh1/nano-mermaid)
     - [Google docs](https://docs.google.com/)
       - [Mermaid plugin for google docs](https://workspace.google.com/marketplace/app/mermaid/636321283856)
    +- [Inkdrop](https://www.inkdrop.app) - [Plugin](https://github.com/inkdropapp/inkdrop-mermaid)
    +- [Iodide](https://github.com/iodide-project/iodide)
    +  - [iodide-mermaid-plugin](https://github.com/iodide-project/iodide-mermaid-plugin)
    +- [Light Table](http://lighttable.com/)
    +  - [Mermaid Plugin](https://github.com/cldwalker/Mermaid)
    +- [Markdown-It](https://github.com/markdown-it/markdown-it)
    +  - [Textual UML Parser](https://github.com/manastalukdar/markdown-it-textual-uml)
    +  - [Mermaid Plugin](https://github.com/tylingsoft/markdown-it-mermaid)
    +  - [md-it-mermaid](https://github.com/iamcco/md-it-mermaid)
    +  - [markdown-it-mermaid-fence-new](https://github.com/Revomatico/markdown-it-mermaid-fence-new)
    +  - [markdown-it-mermaid-less](https://github.com/searKing/markdown-it-mermaid-less)
     - [Podlite](https://github.com/zag/podlite-desktop)
       - [Named block =Diagram](https://github.com/zag/podlite/tree/main/packages/podlite-diagrams)
    -- [GNU Nano](https://www.nano-editor.org/)
    -  - [Nano Mermaid](https://github.com/Yash-Singh1/nano-mermaid)
    -- [CKEditor](https://github.com/ckeditor/ckeditor5)
    -  - [CKEditor 5 Mermaid plugin](https://github.com/ckeditor/ckeditor5-mermaid)
     - [Standard Notes](https://standardnotes.com/)
       - [sn-mermaid](https://github.com/nienow/sn-mermaid)
    +- [Sublime Text 3](https://sublimetext.com)
    +  - [Mermaid Package](https://packagecontrol.io/packages/Mermaid)
    +- [VS Code](https://code.visualstudio.com/)
    +  - [Markdown Preview Mermaid Support](https://marketplace.visualstudio.com/items?itemName=bierner.markdown-mermaid)
    +  - [Mermaid Preview](https://marketplace.visualstudio.com/items?itemName=vstirbu.vscode-mermaid-preview)
    +  - [Markdown Preview Enhanced](https://marketplace.visualstudio.com/items?itemName=shd101wyy.markdown-preview-enhanced)
    +  - [Mermaid Markdown Syntax Highlighting](https://marketplace.visualstudio.com/items?itemName=bpruitt-goddard.mermaid-markdown-syntax-highlighting)
    +  - [Mermaid Editor](https://marketplace.visualstudio.com/items?itemName=tomoyukim.vscode-mermaid-editor)
    +  - [Mermaid Export](https://marketplace.visualstudio.com/items?itemName=Gruntfuggly.mermaid-export)
    +  - [Markdown PDF](https://marketplace.visualstudio.com/items?itemName=yzane.markdown-pdf)
    +  - [Preview](https://marketplace.visualstudio.com/items?itemName=searKing.preview-vscode)
    +  - [Preview Sequence Diagrams](https://marketplace.visualstudio.com/items?itemName=arichika.previewseqdiag-vscode)
    +- [Vim](https://www.vim.org)
    +  - [Official Vim Syntax and ftplugin](https://github.com/craigmac/vim-mermaid)
    +  - [Vim Diagram Syntax](https://github.com/zhaozg/vim-diagram)
     
     ### Document Generation
     
    +- [Codedoc](https://codedoc.cc/)
    +  - [codedoc-mermaid-plugin](https://www.npmjs.com/package/codedoc-mermaid-plugin)
    +- [Docsy Hugo Theme](https://www.docsy.dev/docs/adding-content/lookandfeel/#diagrams-with-mermaid) (native support in theme)
     - [Docusaurus](https://docusaurus.io/docs/markdown-features/diagrams) ✅
    -- [Swimm - Up-to-date diagrams with Swimm, the knowledge management tool for code](https://docs.swimm.io/features/diagrams-and-charts/#mermaid--swimm--up-to-date-diagrams-)
    -- [Sphinx](https://www.sphinx-doc.org/en/master/)
    -  - [sphinxcontrib-mermaid](https://github.com/mgaitan/sphinxcontrib-mermaid)
    -- [remark](https://remark.js.org/)
    -  - [remark-mermaidjs](https://github.com/remcohaszing/remark-mermaidjs)
    -- [rehype](https://github.com/rehypejs/rehype)
    -  - [rehype-mermaid](https://github.com/remcohaszing/rehype-mermaid)
     - [Gatsby](https://www.gatsbyjs.com/)
       - [gatsby-remark-mermaid](https://github.com/remcohaszing/gatsby-remark-mermaid)
     - [JSDoc](https://jsdoc.app/)
       - [jsdoc-mermaid](https://github.com/Jellyvision/jsdoc-mermaid)
    +- [mdbook](https://rust-lang.github.io/mdBook/index.html)
    +  - [mdbook-mermaid](https://github.com/badboy/mdbook-mermaid)
     - [MkDocs](https://www.mkdocs.org)
       - [mkdocs-mermaid2-plugin](https://github.com/fralau/mkdocs-mermaid2-plugin)
       - [mkdocs-material](https://github.com/squidfunk/mkdocs-material), check the [docs](https://squidfunk.github.io/mkdocs-material/reference/diagrams/)
    +  - [Quarto](https://quarto.org/)
    +- [rehype](https://github.com/rehypejs/rehype)
    +  - [rehype-mermaid](https://github.com/remcohaszing/rehype-mermaid)
    +- [remark](https://remark.js.org/)
    +  - [remark-mermaidjs](https://github.com/remcohaszing/remark-mermaidjs)
    +- [Sphinx](https://www.sphinx-doc.org/en/master/)
    +  - [sphinxcontrib-mermaid](https://github.com/mgaitan/sphinxcontrib-mermaid)
    +- [Swimm - Up-to-date diagrams with Swimm, the knowledge management tool for code](https://docs.swimm.io/Features/diagrams-and-charts#mermaid--swimm--up-to-date-diagrams-)
     - [Type Doc](https://typedoc.org/)
       - [typedoc-plugin-mermaid](https://www.npmjs.com/package/typedoc-plugin-mermaid)
    -- [Docsy Hugo Theme](https://www.docsy.dev/docs/adding-content/lookandfeel/#diagrams-with-mermaid) (native support in theme)
    -- [Codedoc](https://codedoc.cc/)
    -  - [codedoc-mermaid-plugin](https://www.npmjs.com/package/codedoc-mermaid-plugin)
    -- [mdbook](https://rust-lang.github.io/mdBook/index.html)
    -  - [mdbook-mermaid](https://github.com/badboy/mdbook-mermaid)
    -- [Quarto](https://quarto.org/)
     - [Typora](https://typora.io/) ([native support](https://support.typora.io/Draw-Diagrams-With-Markdown/#mermaid))
     
     ### Browser Extensions
    @@ -218,19 +218,19 @@ Communication tools and platforms
     
     ### Other
     
    +- [Bisheng](https://www.npmjs.com/package/bisheng)
    +  - [bisheng-plugin-mermaid](https://github.com/yct21/bisheng-plugin-mermaid)
    +- [ExDoc](https://github.com/elixir-lang/ex_doc)
    +  - [Rendering Mermaid graphs](https://github.com/elixir-lang/ex_doc#rendering-mermaid-graphs)
     - [Jekyll](https://jekyllrb.com/)
       - [jekyll-mermaid](https://rubygems.org/gems/jekyll-mermaid)
       - [jekyll-mermaid-diagrams](https://github.com/fuzhibo/jekyll-mermaid-diagrams)
    -- [Reveal.js](https://github.com/hakimel/reveal.js)
    -  - [reveal.js-mermaid-plugin](https://github.com/ludwick/reveal.js-mermaid-plugin)
    -- [Bisheng](https://www.npmjs.com/package/bisheng)
    -  - [bisheng-plugin-mermaid](https://github.com/yct21/bisheng-plugin-mermaid)
    -- [Reveal CK](https://github.com/jedcn/reveal-ck)
    -  - [reveal-ck-mermaid-plugin](https://github.com/tmtm/reveal-ck-mermaid-plugin)
     - [mermaid-isomorphic](https://github.com/remcohaszing/mermaid-isomorphic)
     - [mermaid-server: Generate diagrams using a HTTP request](https://github.com/TomWright/mermaid-server)
    -- [ExDoc](https://github.com/elixir-lang/ex_doc)
    -  - [Rendering Mermaid graphs](https://github.com/elixir-lang/ex_doc#rendering-mermaid-graphs)
     - [NiceGUI: Let any browser be the frontend of your Python code](https://nicegui.io)
       - [ui.mermaid(...)](https://nicegui.io/reference#mermaid_diagrams)
       - [ui.markdown(..., extras=['mermaid'])](https://nicegui.io/reference#markdown_element)
    +- [Reveal.js](https://github.com/hakimel/reveal.js)
    +  - [reveal.js-mermaid-plugin](https://github.com/ludwick/reveal.js-mermaid-plugin)
    +- [Reveal CK](https://github.com/jedcn/reveal-ck)
    +  - [reveal-ck-mermaid-plugin](https://github.com/tmtm/reveal-ck-mermaid-plugin)
    
    From 783becebf626d165d78a053f127a5fee0f2a1712 Mon Sep 17 00:00:00 2001
    From: Ronid1 
    Date: Wed, 22 Nov 2023 18:48:52 -0800
    Subject: [PATCH 029/217] alphabetically order sub categories
    
    ---
     docs/ecosystem/integrations-community.md      | 26 +++++++++----------
     .../docs/ecosystem/integrations-community.md  | 26 +++++++++----------
     2 files changed, 26 insertions(+), 26 deletions(-)
    
    diff --git a/docs/ecosystem/integrations-community.md b/docs/ecosystem/integrations-community.md
    index d74918e613..0b560cc912 100644
    --- a/docs/ecosystem/integrations-community.md
    +++ b/docs/ecosystem/integrations-community.md
    @@ -23,26 +23,26 @@ Below are a list of community plugins and integrations created with Mermaid.
       - [Mermaid Integration for Confluence](https://marketplace.atlassian.com/apps/1222792/mermaid-integration-for-confluence?hosting=cloud&tab=overview)
       - [Mermaid Charts & Diagrams for Confluence](https://marketplace.atlassian.com/apps/1222572/)
       - [Mermaid Diagrams for Confluence](https://marketplace.atlassian.com/apps/1226945/mermaid-diagrams-for-confluence?hosting=cloud&tab=overview)
    -  - [Mermaid Macro for Confluence](https://marketplace.atlassian.com/apps/1231150/mermaid-macro-for-confluence?hosting=cloud&tab=overview)
       - [Mermaid Live Editor for Confluence Cloud](https://marketplace.atlassian.com/apps/1231571/mermaid-live-editor-for-confluence?hosting=cloud&tab=overview)
    +  - [Mermaid Macro for Confluence](https://marketplace.atlassian.com/apps/1231150/mermaid-macro-for-confluence?hosting=cloud&tab=overview)
       - [Mermaid Plugin for Confluence](https://marketplace.atlassian.com/apps/1214124/mermaid-plugin-for-confluence?hosting=server&tab=overview)
       - [EliteSoft Mermaid Charts and Diagrams](https://marketplace.atlassian.com/apps/1227286/elitesoft-mermaid-charts-and-diagrams?hosting=cloud&tab=overview)
       - [Auto convert diagrams in Jira](https://github.com/coddingtonbear/jirafs-mermaid)
    -  - [Mermaid for Jira Cloud - Draw UML diagrams easily](https://marketplace.atlassian.com/apps/1223053/mermaid-for-jira-cloud-draw-uml-diagrams-easily?hosting=cloud&tab=overview)
       - [Mermaid Charts & Diagrams for Jira](https://marketplace.atlassian.com/apps/1224537/)
    +  - [Mermaid for Jira Cloud - Draw UML diagrams easily](https://marketplace.atlassian.com/apps/1223053/mermaid-for-jira-cloud-draw-uml-diagrams-easily?hosting=cloud&tab=overview)
       - [CloudScript.io Addon](https://marketplace.atlassian.com/apps/1219878/cloudscript-io-mermaid-addon?hosting=cloud&tab=overview)
     - [Azure Devops](https://docs.microsoft.com/en-us/azure/devops/project/wiki/wiki-markdown-guidance?view=azure-devops#add-mermaid-diagrams-to-a-wiki-page) ✅
     - [Deepdwn](https://billiam.itch.io/deepdwn) ✅
     - [GitBook](https://gitbook.com)
       - [Mermaid Plugin](https://github.com/JozoVilcek/gitbook-plugin-mermaid)
    -  - [Markdown with Mermaid CLI](https://github.com/miao1007/gitbook-plugin-mermaid-cli)
       - [Mermaid plugin for GitBook](https://github.com/wwformat/gitbook-plugin-mermaid-pdf)
    +  - [Markdown with Mermaid CLI](https://github.com/miao1007/gitbook-plugin-mermaid-cli)
     - [Gitea](https://gitea.io) ✅
     - [GitHub](https://github.com) ✅
       - [Using code blocks](https://github.blog/2022-02-14-include-diagrams-markdown-files-mermaid/) ✅
       - [GitHub action: Compile mermaid to image](https://github.com/neenjaw/compile-mermaid-markdown-action)
    -  - [svg-generator](https://github.com/SimonKenyonShepard/mermaidjs-github-svg-generator)
       - [GitHub Writer](https://github.com/ckeditor/github-writer)
    +  - [svg-generator](https://github.com/SimonKenyonShepard/mermaidjs-github-svg-generator)
     - [GitLab](https://docs.gitlab.com/ee/user/markdown.html#diagrams-and-flowcharts) ✅
     - [Mermaid Plugin for JetBrains IDEs](https://plugins.jetbrains.com/plugin/20146-mermaid)
     - [Joplin](https://joplinapp.org) ✅
    @@ -58,8 +58,8 @@ Below are a list of community plugins and integrations created with Mermaid.
     - [Obsidian](https://help.obsidian.md/Editing+and+formatting/Advanced+formatting+syntax#Diagram) ✅
     - [Redmine](https://redmine.org)
       - [Mermaid Macro](https://www.redmine.org/plugins/redmine_mermaid_macro)
    -  - [redmine-mermaid](https://github.com/styz/redmine_mermaid)
       - [markdown-for-mermaid-plugin](https://github.com/jamieh-mongolian/markdown-for-mermaid-plugin)
    +  - [redmine-mermaid](https://github.com/styz/redmine_mermaid)
     - Visual Studio Code [Polyglot Interactive Notebooks](https://github.com/dotnet/interactive#net-interactive)
     
     ### CRM/ERP
    @@ -112,13 +112,13 @@ Communication tools and platforms
     ### Wikis
     
     - [DokuWiki](https://dokuwiki.org)
    -  - [Mermaid Plugin](https://www.dokuwiki.org/plugin:mermaid)
       - [ComboStrap](https://combostrap.com/mermaid)
    +  - [Mermaid Plugin](https://www.dokuwiki.org/plugin:mermaid)
     - [Foswiki](https://foswiki.org)
       - [Mermaid Plugin](https://foswiki.org/Extensions/MermaidPlugin)
     - [MediaWiki](https://www.mediawiki.org)
    -  - [Mermaid Extension](https://www.mediawiki.org/wiki/Extension:Mermaid)
       - [Flex Diagrams Extension](https://www.mediawiki.org/wiki/Extension:Flex_Diagrams)
    +  - [Mermaid Extension](https://www.mediawiki.org/wiki/Extension:Mermaid)
     - [Semantic Media Wiki](https://semantic-mediawiki.org)
       - [Mermaid Plugin](https://github.com/SemanticMediaWiki/Mermaid)
     - [TiddlyWiki](https://tiddlywiki.com/)
    @@ -163,18 +163,18 @@ Communication tools and platforms
     - [Sublime Text 3](https://sublimetext.com)
       - [Mermaid Package](https://packagecontrol.io/packages/Mermaid)
     - [VS Code](https://code.visualstudio.com/)
    -  - [Markdown Preview Mermaid Support](https://marketplace.visualstudio.com/items?itemName=bierner.markdown-mermaid)
    -  - [Mermaid Preview](https://marketplace.visualstudio.com/items?itemName=vstirbu.vscode-mermaid-preview)
    -  - [Markdown Preview Enhanced](https://marketplace.visualstudio.com/items?itemName=shd101wyy.markdown-preview-enhanced)
    -  - [Mermaid Markdown Syntax Highlighting](https://marketplace.visualstudio.com/items?itemName=bpruitt-goddard.mermaid-markdown-syntax-highlighting)
       - [Mermaid Editor](https://marketplace.visualstudio.com/items?itemName=tomoyukim.vscode-mermaid-editor)
       - [Mermaid Export](https://marketplace.visualstudio.com/items?itemName=Gruntfuggly.mermaid-export)
       - [Markdown PDF](https://marketplace.visualstudio.com/items?itemName=yzane.markdown-pdf)
    +  - [Markdown Preview Mermaid Support](https://marketplace.visualstudio.com/items?itemName=bierner.markdown-mermaid)
    +  - [Markdown Preview Enhanced](https://marketplace.visualstudio.com/items?itemName=shd101wyy.markdown-preview-enhanced)
    +  - [Mermaid Preview](https://marketplace.visualstudio.com/items?itemName=vstirbu.vscode-mermaid-preview)
       - [Preview](https://marketplace.visualstudio.com/items?itemName=searKing.preview-vscode)
       - [Preview Sequence Diagrams](https://marketplace.visualstudio.com/items?itemName=arichika.previewseqdiag-vscode)
    +  - [Mermaid Markdown Syntax Highlighting](https://marketplace.visualstudio.com/items?itemName=bpruitt-goddard.mermaid-markdown-syntax-highlighting)
     - [Vim](https://www.vim.org)
    -  - [Official Vim Syntax and ftplugin](https://github.com/craigmac/vim-mermaid)
       - [Vim Diagram Syntax](https://github.com/zhaozg/vim-diagram)
    +  - [Official Vim Syntax and ftplugin](https://github.com/craigmac/vim-mermaid)
     
     ### Document Generation
     
    @@ -230,8 +230,8 @@ Communication tools and platforms
     - [mermaid-isomorphic](https://github.com/remcohaszing/mermaid-isomorphic)
     - [mermaid-server: Generate diagrams using a HTTP request](https://github.com/TomWright/mermaid-server)
     - [NiceGUI: Let any browser be the frontend of your Python code](https://nicegui.io)
    -  - [ui.mermaid(...)](https://nicegui.io/reference#mermaid_diagrams)
       - [ui.markdown(..., extras=\['mermaid'\])](https://nicegui.io/reference#markdown_element)
    +  - [ui.mermaid(...)](https://nicegui.io/reference#mermaid_diagrams)
     - [Reveal.js](https://github.com/hakimel/reveal.js)
       - [reveal.js-mermaid-plugin](https://github.com/ludwick/reveal.js-mermaid-plugin)
     - [Reveal CK](https://github.com/jedcn/reveal-ck)
    diff --git a/packages/mermaid/src/docs/ecosystem/integrations-community.md b/packages/mermaid/src/docs/ecosystem/integrations-community.md
    index b48746bc41..d64f06875d 100644
    --- a/packages/mermaid/src/docs/ecosystem/integrations-community.md
    +++ b/packages/mermaid/src/docs/ecosystem/integrations-community.md
    @@ -21,26 +21,26 @@ Below are a list of community plugins and integrations created with Mermaid.
       - [Mermaid Integration for Confluence](https://marketplace.atlassian.com/apps/1222792/mermaid-integration-for-confluence?hosting=cloud&tab=overview)
       - [Mermaid Charts & Diagrams for Confluence](https://marketplace.atlassian.com/apps/1222572/)
       - [Mermaid Diagrams for Confluence](https://marketplace.atlassian.com/apps/1226945/mermaid-diagrams-for-confluence?hosting=cloud&tab=overview)
    -  - [Mermaid Macro for Confluence](https://marketplace.atlassian.com/apps/1231150/mermaid-macro-for-confluence?hosting=cloud&tab=overview)
       - [Mermaid Live Editor for Confluence Cloud](https://marketplace.atlassian.com/apps/1231571/mermaid-live-editor-for-confluence?hosting=cloud&tab=overview)
    +  - [Mermaid Macro for Confluence](https://marketplace.atlassian.com/apps/1231150/mermaid-macro-for-confluence?hosting=cloud&tab=overview)
       - [Mermaid Plugin for Confluence](https://marketplace.atlassian.com/apps/1214124/mermaid-plugin-for-confluence?hosting=server&tab=overview)
       - [EliteSoft Mermaid Charts and Diagrams](https://marketplace.atlassian.com/apps/1227286/elitesoft-mermaid-charts-and-diagrams?hosting=cloud&tab=overview)
       - [Auto convert diagrams in Jira](https://github.com/coddingtonbear/jirafs-mermaid)
    -  - [Mermaid for Jira Cloud - Draw UML diagrams easily](https://marketplace.atlassian.com/apps/1223053/mermaid-for-jira-cloud-draw-uml-diagrams-easily?hosting=cloud&tab=overview)
       - [Mermaid Charts & Diagrams for Jira](https://marketplace.atlassian.com/apps/1224537/)
    +  - [Mermaid for Jira Cloud - Draw UML diagrams easily](https://marketplace.atlassian.com/apps/1223053/mermaid-for-jira-cloud-draw-uml-diagrams-easily?hosting=cloud&tab=overview)
       - [CloudScript.io Addon](https://marketplace.atlassian.com/apps/1219878/cloudscript-io-mermaid-addon?hosting=cloud&tab=overview)
     - [Azure Devops](https://docs.microsoft.com/en-us/azure/devops/project/wiki/wiki-markdown-guidance?view=azure-devops#add-mermaid-diagrams-to-a-wiki-page) ✅
     - [Deepdwn](https://billiam.itch.io/deepdwn) ✅
     - [GitBook](https://gitbook.com)
       - [Mermaid Plugin](https://github.com/JozoVilcek/gitbook-plugin-mermaid)
    -  - [Markdown with Mermaid CLI](https://github.com/miao1007/gitbook-plugin-mermaid-cli)
       - [Mermaid plugin for GitBook](https://github.com/wwformat/gitbook-plugin-mermaid-pdf)
    +  - [Markdown with Mermaid CLI](https://github.com/miao1007/gitbook-plugin-mermaid-cli)
     - [Gitea](https://gitea.io) ✅
     - [GitHub](https://github.com) ✅
       - [Using code blocks](https://github.blog/2022-02-14-include-diagrams-markdown-files-mermaid/) ✅
       - [GitHub action: Compile mermaid to image](https://github.com/neenjaw/compile-mermaid-markdown-action)
    -  - [svg-generator](https://github.com/SimonKenyonShepard/mermaidjs-github-svg-generator)
       - [GitHub Writer](https://github.com/ckeditor/github-writer)
    +  - [svg-generator](https://github.com/SimonKenyonShepard/mermaidjs-github-svg-generator)
     - [GitLab](https://docs.gitlab.com/ee/user/markdown.html#diagrams-and-flowcharts) ✅
     - [Mermaid Plugin for JetBrains IDEs](https://plugins.jetbrains.com/plugin/20146-mermaid)
     - [Joplin](https://joplinapp.org) ✅
    @@ -56,8 +56,8 @@ Below are a list of community plugins and integrations created with Mermaid.
     - [Obsidian](https://help.obsidian.md/Editing+and+formatting/Advanced+formatting+syntax#Diagram) ✅
     - [Redmine](https://redmine.org)
       - [Mermaid Macro](https://www.redmine.org/plugins/redmine_mermaid_macro)
    -  - [redmine-mermaid](https://github.com/styz/redmine_mermaid)
       - [markdown-for-mermaid-plugin](https://github.com/jamieh-mongolian/markdown-for-mermaid-plugin)
    +  - [redmine-mermaid](https://github.com/styz/redmine_mermaid)
     - Visual Studio Code [Polyglot Interactive Notebooks](https://github.com/dotnet/interactive#net-interactive)
     
     ### CRM/ERP
    @@ -110,13 +110,13 @@ Communication tools and platforms
     ### Wikis
     
     - [DokuWiki](https://dokuwiki.org)
    -  - [Mermaid Plugin](https://www.dokuwiki.org/plugin:mermaid)
       - [ComboStrap](https://combostrap.com/mermaid)
    +  - [Mermaid Plugin](https://www.dokuwiki.org/plugin:mermaid)
     - [Foswiki](https://foswiki.org)
       - [Mermaid Plugin](https://foswiki.org/Extensions/MermaidPlugin)
     - [MediaWiki](https://www.mediawiki.org)
    -  - [Mermaid Extension](https://www.mediawiki.org/wiki/Extension:Mermaid)
       - [Flex Diagrams Extension](https://www.mediawiki.org/wiki/Extension:Flex_Diagrams)
    +  - [Mermaid Extension](https://www.mediawiki.org/wiki/Extension:Mermaid)
     - [Semantic Media Wiki](https://semantic-mediawiki.org)
       - [Mermaid Plugin](https://github.com/SemanticMediaWiki/Mermaid)
     - [TiddlyWiki](https://tiddlywiki.com/)
    @@ -161,18 +161,18 @@ Communication tools and platforms
     - [Sublime Text 3](https://sublimetext.com)
       - [Mermaid Package](https://packagecontrol.io/packages/Mermaid)
     - [VS Code](https://code.visualstudio.com/)
    -  - [Markdown Preview Mermaid Support](https://marketplace.visualstudio.com/items?itemName=bierner.markdown-mermaid)
    -  - [Mermaid Preview](https://marketplace.visualstudio.com/items?itemName=vstirbu.vscode-mermaid-preview)
    -  - [Markdown Preview Enhanced](https://marketplace.visualstudio.com/items?itemName=shd101wyy.markdown-preview-enhanced)
    -  - [Mermaid Markdown Syntax Highlighting](https://marketplace.visualstudio.com/items?itemName=bpruitt-goddard.mermaid-markdown-syntax-highlighting)
       - [Mermaid Editor](https://marketplace.visualstudio.com/items?itemName=tomoyukim.vscode-mermaid-editor)
       - [Mermaid Export](https://marketplace.visualstudio.com/items?itemName=Gruntfuggly.mermaid-export)
       - [Markdown PDF](https://marketplace.visualstudio.com/items?itemName=yzane.markdown-pdf)
    +  - [Markdown Preview Mermaid Support](https://marketplace.visualstudio.com/items?itemName=bierner.markdown-mermaid)
    +  - [Markdown Preview Enhanced](https://marketplace.visualstudio.com/items?itemName=shd101wyy.markdown-preview-enhanced)
    +  - [Mermaid Preview](https://marketplace.visualstudio.com/items?itemName=vstirbu.vscode-mermaid-preview)
       - [Preview](https://marketplace.visualstudio.com/items?itemName=searKing.preview-vscode)
       - [Preview Sequence Diagrams](https://marketplace.visualstudio.com/items?itemName=arichika.previewseqdiag-vscode)
    +  - [Mermaid Markdown Syntax Highlighting](https://marketplace.visualstudio.com/items?itemName=bpruitt-goddard.mermaid-markdown-syntax-highlighting)
     - [Vim](https://www.vim.org)
    -  - [Official Vim Syntax and ftplugin](https://github.com/craigmac/vim-mermaid)
       - [Vim Diagram Syntax](https://github.com/zhaozg/vim-diagram)
    +  - [Official Vim Syntax and ftplugin](https://github.com/craigmac/vim-mermaid)
     
     ### Document Generation
     
    @@ -228,8 +228,8 @@ Communication tools and platforms
     - [mermaid-isomorphic](https://github.com/remcohaszing/mermaid-isomorphic)
     - [mermaid-server: Generate diagrams using a HTTP request](https://github.com/TomWright/mermaid-server)
     - [NiceGUI: Let any browser be the frontend of your Python code](https://nicegui.io)
    -  - [ui.mermaid(...)](https://nicegui.io/reference#mermaid_diagrams)
       - [ui.markdown(..., extras=['mermaid'])](https://nicegui.io/reference#markdown_element)
    +  - [ui.mermaid(...)](https://nicegui.io/reference#mermaid_diagrams)
     - [Reveal.js](https://github.com/hakimel/reveal.js)
       - [reveal.js-mermaid-plugin](https://github.com/ludwick/reveal.js-mermaid-plugin)
     - [Reveal CK](https://github.com/jedcn/reveal-ck)
    
    From aaf9fd5f03d55d7389d4a1afbeb978dafeeeecb8 Mon Sep 17 00:00:00 2001
    From: Ronid1 
    Date: Thu, 23 Nov 2023 16:21:12 -0800
    Subject: [PATCH 030/217] update and verify links
    
    ---
     docs/ecosystem/integrations-community.md      | 47 +++++++++---------
     .../docs/ecosystem/integrations-community.md  | 48 +++++++++----------
     2 files changed, 46 insertions(+), 49 deletions(-)
    
    diff --git a/docs/ecosystem/integrations-community.md b/docs/ecosystem/integrations-community.md
    index 0b560cc912..2db6b00e1e 100644
    --- a/docs/ecosystem/integrations-community.md
    +++ b/docs/ecosystem/integrations-community.md
    @@ -30,8 +30,8 @@ Below are a list of community plugins and integrations created with Mermaid.
       - [Auto convert diagrams in Jira](https://github.com/coddingtonbear/jirafs-mermaid)
       - [Mermaid Charts & Diagrams for Jira](https://marketplace.atlassian.com/apps/1224537/)
       - [Mermaid for Jira Cloud - Draw UML diagrams easily](https://marketplace.atlassian.com/apps/1223053/mermaid-for-jira-cloud-draw-uml-diagrams-easily?hosting=cloud&tab=overview)
    -  - [CloudScript.io Addon](https://marketplace.atlassian.com/apps/1219878/cloudscript-io-mermaid-addon?hosting=cloud&tab=overview)
    -- [Azure Devops](https://docs.microsoft.com/en-us/azure/devops/project/wiki/wiki-markdown-guidance?view=azure-devops#add-mermaid-diagrams-to-a-wiki-page) ✅
    +  - [CloudScript.io Mermaid Addon](https://marketplace.atlassian.com/apps/1219878/cloudscript-io-mermaid-addon?hosting=cloud&tab=overview)
    +- [Azure Devops](https://learn.microsoft.com/en-us/azure/devops/project/wiki/markdown-guidance?view=azure-devops#add-mermaid-diagrams-to-a-wiki-page) ✅
     - [Deepdwn](https://billiam.itch.io/deepdwn) ✅
     - [GitBook](https://gitbook.com)
       - [Mermaid Plugin](https://github.com/JozoVilcek/gitbook-plugin-mermaid)
    @@ -42,23 +42,23 @@ Below are a list of community plugins and integrations created with Mermaid.
       - [Using code blocks](https://github.blog/2022-02-14-include-diagrams-markdown-files-mermaid/) ✅
       - [GitHub action: Compile mermaid to image](https://github.com/neenjaw/compile-mermaid-markdown-action)
       - [GitHub Writer](https://github.com/ckeditor/github-writer)
    -  - [svg-generator](https://github.com/SimonKenyonShepard/mermaidjs-github-svg-generator)
    +  - [SVG diagram generator](https://github.com/SimonKenyonShepard/mermaidjs-github-svg-generator)
     - [GitLab](https://docs.gitlab.com/ee/user/markdown.html#diagrams-and-flowcharts) ✅
     - [Mermaid Plugin for JetBrains IDEs](https://plugins.jetbrains.com/plugin/20146-mermaid)
     - [Joplin](https://joplinapp.org) ✅
     - [LiveBook](https://livebook.dev) ✅
     - [Tuleap](https://docs.tuleap.org/user-guide/writing-in-tuleap.html#graphs) ✅
     - [Mermaid Flow Visual Editor](https://www.mermaidflow.app) ✅
    -- [mermerd](https://github.com/KarnerTh/mermerd)
    +- [Mermerd](https://github.com/KarnerTh/mermerd)
     - [Slab](https://slab.com) ✅
    -- [Swimm](https://swimm.io) ✅
    +- [Swimm](https://docs.swimm.io/Features/diagrams-and-charts) ✅
     - [NotesHub](https://noteshub.app) ✅
     - [Notion](https://notion.so) ✅
     - [Observable](https://observablehq.com/@observablehq/mermaid) ✅
     - [Obsidian](https://help.obsidian.md/Editing+and+formatting/Advanced+formatting+syntax#Diagram) ✅
     - [Redmine](https://redmine.org)
       - [Mermaid Macro](https://www.redmine.org/plugins/redmine_mermaid_macro)
    -  - [markdown-for-mermaid-plugin](https://github.com/jamieh-mongolian/markdown-for-mermaid-plugin)
    +  - [Markdown for mermaid plugin](https://github.com/jamieh-mongolian/markdown-for-mermaid-plugin)
       - [redmine-mermaid](https://github.com/styz/redmine_mermaid)
     - Visual Studio Code [Polyglot Interactive Notebooks](https://github.com/dotnet/interactive#net-interactive)
     
    @@ -87,7 +87,7 @@ Blogging frameworks and platforms
     Content Management Systems/Enterprise Content Management
     
     - [Grav CMS](https://getgrav.org/)
    -  - [Mermaid Diagrams](https://github.com/DanielFlaum/grav-plugin-mermaid-diagrams)
    +  - [Mermaid Diagrams Plugin](https://github.com/DanielFlaum/grav-plugin-mermaid-diagrams)
       - [GitLab Markdown Adapter](https://github.com/Goutte/grav-plugin-gitlab-markdown-adapter)
     - [VitePress](https://vitepress.vuejs.org/)
       - [Plugin for Mermaid.js](https://emersonbottero.github.io/vitepress-plugin-mermaid/)
    @@ -99,15 +99,15 @@ Content Management Systems/Enterprise Content Management
     Communication tools and platforms
     
     - [Discourse](https://discourse.org)
    -  - [Mermaid Plugin](https://github.com/pnewell/discourse-mermaid), [And](https://github.com/unfoldingWord-dev/discourse-mermaid)
    +  - [Mermaid Plugin](https://github.com/pnewell/discourse-mermaid)
     - [Mattermost](https://mattermost.com/)
       - [Mermaid Plugin](https://github.com/SpikeTings/Mermaid)
     - [NodeBB](https://nodebb.org)
    -  - [Mermaid Plugin](https://www.npmjs.com/package/nodebb-plugin-mermaid)
    +  - [Mermaid Parser Plugin](https://www.npmjs.com/package/nodebb-plugin-mermaid)
     - [phpBB](https://phpbb.com)
       - [phpbb-ext-mermaid](https://github.com/AlfredoRamos/phpbb-ext-mermaid)
     - [Slack](https://slack.com)
    -  - [Mermaid for Slack](https://github.com/JackuB/mermaid-for-slack)
    +  - [Mermaid Preview](https://github.com/JackuB/mermaid-for-slack)
     
     ### Wikis
     
    @@ -122,8 +122,8 @@ Communication tools and platforms
     - [Semantic Media Wiki](https://semantic-mediawiki.org)
       - [Mermaid Plugin](https://github.com/SemanticMediaWiki/Mermaid)
     - [TiddlyWiki](https://tiddlywiki.com/)
    -  - [mermaid-tw5: full js library](https://github.com/efurlanm/mermaid-tw5)
    -  - [tw5-mermaid: wrapper for Mermaid Live](https://github.com/jasonmhoule/tw5-mermaid)
    +  - [mermaid-tw5: wrapper for Mermaid Live](https://github.com/efurlanm/mermaid-tw5)
    +  - [tw5-mermaid: plugin for managing Mermaid.js tiddlers](https://github.com/jasonmhoule/tw5-mermaid)
     
     ### Editor Plugins
     
    @@ -137,7 +137,8 @@ Communication tools and platforms
       - [Mermaid Preview](https://github.com/AlanHohn/mermaid-preview)
     - [CKEditor](https://github.com/ckeditor/ckeditor5)
       - [CKEditor 5 Mermaid plugin](https://github.com/ckeditor/ckeditor5-mermaid)
    -- [Draw.io](https://draw.io) - [Plugin](https://github.com/nopeslide/drawio_mermaid_plugin)
    +- [Draw.io](https://draw.io)
    +  - [Mermaid Plugin](https://github.com/nopeslide/drawio_mermaid_plugin)
     - [GNU Emacs](https://www.gnu.org/software/emacs/)
       - [Major mode for .mmd files](https://github.com/abrochard/mermaid-mode)
       - [Org-Mode integration](https://github.com/arnm/ob-mermaid)
    @@ -145,9 +146,8 @@ Communication tools and platforms
       - [Nano Mermaid](https://github.com/Yash-Singh1/nano-mermaid)
     - [Google docs](https://docs.google.com/)
       - [Mermaid plugin for google docs](https://workspace.google.com/marketplace/app/mermaid/636321283856)
    -- [Inkdrop](https://www.inkdrop.app) - [Plugin](https://github.com/inkdropapp/inkdrop-mermaid)
    -- [Iodide](https://github.com/iodide-project/iodide)
    -  - [iodide-mermaid-plugin](https://github.com/iodide-project/iodide-mermaid-plugin)
    +- [Inkdrop](https://www.inkdrop.app)
    +  - [Mermaid Plugin](https://github.com/inkdropapp/inkdrop-mermaid)
     - [Light Table](http://lighttable.com/)
       - [Mermaid Plugin](https://github.com/cldwalker/Mermaid)
     - [Markdown-It](https://github.com/markdown-it/markdown-it)
    @@ -157,9 +157,9 @@ Communication tools and platforms
       - [markdown-it-mermaid-fence-new](https://github.com/Revomatico/markdown-it-mermaid-fence-new)
       - [markdown-it-mermaid-less](https://github.com/searKing/markdown-it-mermaid-less)
     - [Podlite](https://github.com/zag/podlite-desktop)
    -  - [Named block =Diagram](https://github.com/zag/podlite/tree/main/packages/podlite-diagrams)
    +  - [=Diagram block](https://github.com/zag/podlite/tree/main/packages/podlite-diagrams)
     - [Standard Notes](https://standardnotes.com/)
    -  - [sn-mermaid](https://github.com/nienow/sn-mermaid)
    +  - [Mermaid Extension](https://github.com/nienow/sn-mermaid)
     - [Sublime Text 3](https://sublimetext.com)
       - [Mermaid Package](https://packagecontrol.io/packages/Mermaid)
     - [VS Code](https://code.visualstudio.com/)
    @@ -174,7 +174,7 @@ Communication tools and platforms
       - [Mermaid Markdown Syntax Highlighting](https://marketplace.visualstudio.com/items?itemName=bpruitt-goddard.mermaid-markdown-syntax-highlighting)
     - [Vim](https://www.vim.org)
       - [Vim Diagram Syntax](https://github.com/zhaozg/vim-diagram)
    -  - [Official Vim Syntax and ftplugin](https://github.com/craigmac/vim-mermaid)
    +  - [Official Vim Syntax and ft plugin](https://github.com/craigmac/vim-mermaid)
     
     ### Document Generation
     
    @@ -186,7 +186,7 @@ Communication tools and platforms
       - [gatsby-remark-mermaid](https://github.com/remcohaszing/gatsby-remark-mermaid)
     - [JSDoc](https://jsdoc.app/)
       - [jsdoc-mermaid](https://github.com/Jellyvision/jsdoc-mermaid)
    -- [mdbook](https://rust-lang.github.io/mdBook/index.html)
    +- [mdBook](https://rust-lang.github.io/mdBook/index.html)
       - [mdbook-mermaid](https://github.com/badboy/mdbook-mermaid)
     - [MkDocs](https://www.mkdocs.org)
       - [mkdocs-mermaid2-plugin](https://github.com/fralau/mkdocs-mermaid2-plugin)
    @@ -201,7 +201,7 @@ Communication tools and platforms
     - [Swimm - Up-to-date diagrams with Swimm, the knowledge management tool for code](https://docs.swimm.io/features/diagrams-and-charts/#mermaid--swimm--up-to-date-diagrams-)
     - [Type Doc](https://typedoc.org/)
       - [typedoc-plugin-mermaid](https://www.npmjs.com/package/typedoc-plugin-mermaid)
    -- [Typora](https://typora.io/) ([native support](https://support.typora.io/Draw-Diagrams-With-Markdown/#mermaid))
    +- [Typora](https://support.typora.io/Draw-Diagrams-With-Markdown/#mermaid) ✅
     
     ### Browser Extensions
     
    @@ -212,7 +212,7 @@ Communication tools and platforms
     | Diagram Tab              | -                                                                                                            | -                                                                              | -                                                                              | -                                                                                                                            | [🐙🔗](https://github.com/khafast/diagramtab)                                                        |
     | Markdown Diagrams        | [🎡🔗](https://chrome.google.com/webstore/detail/markdown-diagrams/pmoglnmodacnbbofbgcagndelmgaclel/)        | [🦊🔗](https://addons.mozilla.org/en-US/firefox/addon/markdown-diagrams/)      | [🔴🔗](https://addons.opera.com/en/extensions/details/markdown-diagrams/)      | [🌀🔗](https://microsoftedge.microsoft.com/addons/detail/markdown-diagrams/hceenoomhhdkjjijnmlclkpenkapfihe)                 | [🐙🔗](https://github.com/marcozaccari/markdown-diagrams-browser-extension/tree/master/doc/examples) |
     | Markdown Viewer          | -                                                                                                            | [🦊🔗](https://addons.mozilla.org/en-US/firefox/addon/markdown-viewer-chrome/) | -                                                                              | -                                                                                                                            | [🐙🔗](https://github.com/simov/markdown-viewer)                                                     |
    -| Extensions for Mermaid   | -                                                                                                            | [🦊🔗](https://addons.mozilla.org/en-US/firefox/addon/markdown-viewer-chrome/) | [🔴🔗](https://addons.opera.com/en/extensions/details/extensions-for-mermaid/) | -                                                                                                                            | [🐙🔗](https://github.com/Stefan-S/mermaid-extension)                                                |
    +| Extensions for Mermaid   | -                                                                                                            | -                                                                              | [🔴🔗](https://addons.opera.com/en/extensions/details/extensions-for-mermaid/) | -                                                                                                                            | [🐙🔗](https://github.com/Stefan-S/mermaid-extension)                                                |
     | Chrome Diagrammer        | [🎡🔗](https://chrome.google.com/webstore/detail/chrome-diagrammer/bkpbgjmkomfoakfklcjeoegkklgjnnpk)         | -                                                                              | -                                                                              | -                                                                                                                            | -                                                                                                    |
     | Mermaid Diagrams         | [🎡🔗](https://chrome.google.com/webstore/detail/mermaid-diagrams/phfcghedmopjadpojhmmaffjmfiakfil)          | -                                                                              | -                                                                              | -                                                                                                                            | -                                                                                                    |
     | Monkeys                  | [🎡🔗](https://chrome.google.com/webstore/detail/monkeys-mermaid-for-githu/cplfdpoajbclbgphaphphcldamfkjlgi) | -                                                                              | -                                                                              | -                                                                                                                            | -                                                                                                    |
    @@ -230,8 +230,7 @@ Communication tools and platforms
     - [mermaid-isomorphic](https://github.com/remcohaszing/mermaid-isomorphic)
     - [mermaid-server: Generate diagrams using a HTTP request](https://github.com/TomWright/mermaid-server)
     - [NiceGUI: Let any browser be the frontend of your Python code](https://nicegui.io)
    -  - [ui.markdown(..., extras=\['mermaid'\])](https://nicegui.io/reference#markdown_element)
    -  - [ui.mermaid(...)](https://nicegui.io/reference#mermaid_diagrams)
    +  - [ui.mermaid(...)](https://nicegui.io/documentation/mermaid)
     - [Reveal.js](https://github.com/hakimel/reveal.js)
       - [reveal.js-mermaid-plugin](https://github.com/ludwick/reveal.js-mermaid-plugin)
     - [Reveal CK](https://github.com/jedcn/reveal-ck)
    diff --git a/packages/mermaid/src/docs/ecosystem/integrations-community.md b/packages/mermaid/src/docs/ecosystem/integrations-community.md
    index d64f06875d..8fab1daa8b 100644
    --- a/packages/mermaid/src/docs/ecosystem/integrations-community.md
    +++ b/packages/mermaid/src/docs/ecosystem/integrations-community.md
    @@ -28,8 +28,8 @@ Below are a list of community plugins and integrations created with Mermaid.
       - [Auto convert diagrams in Jira](https://github.com/coddingtonbear/jirafs-mermaid)
       - [Mermaid Charts & Diagrams for Jira](https://marketplace.atlassian.com/apps/1224537/)
       - [Mermaid for Jira Cloud - Draw UML diagrams easily](https://marketplace.atlassian.com/apps/1223053/mermaid-for-jira-cloud-draw-uml-diagrams-easily?hosting=cloud&tab=overview)
    -  - [CloudScript.io Addon](https://marketplace.atlassian.com/apps/1219878/cloudscript-io-mermaid-addon?hosting=cloud&tab=overview)
    -- [Azure Devops](https://docs.microsoft.com/en-us/azure/devops/project/wiki/wiki-markdown-guidance?view=azure-devops#add-mermaid-diagrams-to-a-wiki-page) ✅
    +  - [CloudScript.io Mermaid Addon](https://marketplace.atlassian.com/apps/1219878/cloudscript-io-mermaid-addon?hosting=cloud&tab=overview)
    +- [Azure Devops](https://learn.microsoft.com/en-us/azure/devops/project/wiki/markdown-guidance?view=azure-devops#add-mermaid-diagrams-to-a-wiki-page) ✅
     - [Deepdwn](https://billiam.itch.io/deepdwn) ✅
     - [GitBook](https://gitbook.com)
       - [Mermaid Plugin](https://github.com/JozoVilcek/gitbook-plugin-mermaid)
    @@ -40,23 +40,23 @@ Below are a list of community plugins and integrations created with Mermaid.
       - [Using code blocks](https://github.blog/2022-02-14-include-diagrams-markdown-files-mermaid/) ✅
       - [GitHub action: Compile mermaid to image](https://github.com/neenjaw/compile-mermaid-markdown-action)
       - [GitHub Writer](https://github.com/ckeditor/github-writer)
    -  - [svg-generator](https://github.com/SimonKenyonShepard/mermaidjs-github-svg-generator)
    +  - [SVG diagram generator](https://github.com/SimonKenyonShepard/mermaidjs-github-svg-generator)
     - [GitLab](https://docs.gitlab.com/ee/user/markdown.html#diagrams-and-flowcharts) ✅
     - [Mermaid Plugin for JetBrains IDEs](https://plugins.jetbrains.com/plugin/20146-mermaid)
     - [Joplin](https://joplinapp.org) ✅
     - [LiveBook](https://livebook.dev) ✅
     - [Tuleap](https://docs.tuleap.org/user-guide/writing-in-tuleap.html#graphs) ✅
     - [Mermaid Flow Visual Editor](https://www.mermaidflow.app) ✅
    -- [mermerd](https://github.com/KarnerTh/mermerd)
    +- [Mermerd](https://github.com/KarnerTh/mermerd)
     - [Slab](https://slab.com) ✅
    -- [Swimm](https://swimm.io) ✅
    +- [Swimm](https://docs.swimm.io/Features/diagrams-and-charts#mermaid--swimm--up-to-date-diagrams-) ✅
     - [NotesHub](https://noteshub.app) ✅
     - [Notion](https://notion.so) ✅
     - [Observable](https://observablehq.com/@observablehq/mermaid) ✅
     - [Obsidian](https://help.obsidian.md/Editing+and+formatting/Advanced+formatting+syntax#Diagram) ✅
     - [Redmine](https://redmine.org)
       - [Mermaid Macro](https://www.redmine.org/plugins/redmine_mermaid_macro)
    -  - [markdown-for-mermaid-plugin](https://github.com/jamieh-mongolian/markdown-for-mermaid-plugin)
    +  - [Markdown for mermaid plugin](https://github.com/jamieh-mongolian/markdown-for-mermaid-plugin)
       - [redmine-mermaid](https://github.com/styz/redmine_mermaid)
     - Visual Studio Code [Polyglot Interactive Notebooks](https://github.com/dotnet/interactive#net-interactive)
     
    @@ -85,7 +85,7 @@ Blogging frameworks and platforms
     Content Management Systems/Enterprise Content Management
     
     - [Grav CMS](https://getgrav.org/)
    -  - [Mermaid Diagrams](https://github.com/DanielFlaum/grav-plugin-mermaid-diagrams)
    +  - [Mermaid Diagrams Plugin](https://github.com/DanielFlaum/grav-plugin-mermaid-diagrams)
       - [GitLab Markdown Adapter](https://github.com/Goutte/grav-plugin-gitlab-markdown-adapter)
     - [VitePress](https://vitepress.vuejs.org/)
       - [Plugin for Mermaid.js](https://emersonbottero.github.io/vitepress-plugin-mermaid/)
    @@ -97,15 +97,15 @@ Content Management Systems/Enterprise Content Management
     Communication tools and platforms
     
     - [Discourse](https://discourse.org)
    -  - [Mermaid Plugin](https://github.com/pnewell/discourse-mermaid), [And](https://github.com/unfoldingWord-dev/discourse-mermaid)
    +  - [Mermaid Plugin](https://github.com/pnewell/discourse-mermaid)
     - [Mattermost](https://mattermost.com/)
       - [Mermaid Plugin](https://github.com/SpikeTings/Mermaid)
     - [NodeBB](https://nodebb.org)
    -  - [Mermaid Plugin](https://www.npmjs.com/package/nodebb-plugin-mermaid)
    +  - [Mermaid Parser Plugin](https://www.npmjs.com/package/nodebb-plugin-mermaid)
     - [phpBB](https://phpbb.com)
       - [phpbb-ext-mermaid](https://github.com/AlfredoRamos/phpbb-ext-mermaid)
     - [Slack](https://slack.com)
    -  - [Mermaid for Slack](https://github.com/JackuB/mermaid-for-slack)
    +  - [Mermaid Preview](https://github.com/JackuB/mermaid-for-slack)
     
     ### Wikis
     
    @@ -120,8 +120,8 @@ Communication tools and platforms
     - [Semantic Media Wiki](https://semantic-mediawiki.org)
       - [Mermaid Plugin](https://github.com/SemanticMediaWiki/Mermaid)
     - [TiddlyWiki](https://tiddlywiki.com/)
    -  - [mermaid-tw5: full js library](https://github.com/efurlanm/mermaid-tw5)
    -  - [tw5-mermaid: wrapper for Mermaid Live](https://github.com/jasonmhoule/tw5-mermaid)
    +  - [mermaid-tw5: wrapper for Mermaid Live](https://github.com/efurlanm/mermaid-tw5)
    +  - [tw5-mermaid: plugin for managing Mermaid.js tiddlers](https://github.com/jasonmhoule/tw5-mermaid)
     
     ### Editor Plugins
     
    @@ -135,7 +135,8 @@ Communication tools and platforms
       - [Mermaid Preview](https://github.com/AlanHohn/mermaid-preview)
     - [CKEditor](https://github.com/ckeditor/ckeditor5)
       - [CKEditor 5 Mermaid plugin](https://github.com/ckeditor/ckeditor5-mermaid)
    -- [Draw.io](https://draw.io) - [Plugin](https://github.com/nopeslide/drawio_mermaid_plugin)
    +- [Draw.io](https://draw.io)
    +  - [Mermaid Plugin](https://github.com/nopeslide/drawio_mermaid_plugin)
     - [GNU Emacs](https://www.gnu.org/software/emacs/)
       - [Major mode for .mmd files](https://github.com/abrochard/mermaid-mode)
       - [Org-Mode integration](https://github.com/arnm/ob-mermaid)
    @@ -143,9 +144,8 @@ Communication tools and platforms
       - [Nano Mermaid](https://github.com/Yash-Singh1/nano-mermaid)
     - [Google docs](https://docs.google.com/)
       - [Mermaid plugin for google docs](https://workspace.google.com/marketplace/app/mermaid/636321283856)
    -- [Inkdrop](https://www.inkdrop.app) - [Plugin](https://github.com/inkdropapp/inkdrop-mermaid)
    -- [Iodide](https://github.com/iodide-project/iodide)
    -  - [iodide-mermaid-plugin](https://github.com/iodide-project/iodide-mermaid-plugin)
    +- [Inkdrop](https://www.inkdrop.app)
    +  - [Mermaid Plugin](https://github.com/inkdropapp/inkdrop-mermaid)
     - [Light Table](http://lighttable.com/)
       - [Mermaid Plugin](https://github.com/cldwalker/Mermaid)
     - [Markdown-It](https://github.com/markdown-it/markdown-it)
    @@ -155,9 +155,9 @@ Communication tools and platforms
       - [markdown-it-mermaid-fence-new](https://github.com/Revomatico/markdown-it-mermaid-fence-new)
       - [markdown-it-mermaid-less](https://github.com/searKing/markdown-it-mermaid-less)
     - [Podlite](https://github.com/zag/podlite-desktop)
    -  - [Named block =Diagram](https://github.com/zag/podlite/tree/main/packages/podlite-diagrams)
    +  - [=Diagram block](https://github.com/zag/podlite/tree/main/packages/podlite-diagrams)
     - [Standard Notes](https://standardnotes.com/)
    -  - [sn-mermaid](https://github.com/nienow/sn-mermaid)
    +  - [Mermaid Extension](https://github.com/nienow/sn-mermaid)
     - [Sublime Text 3](https://sublimetext.com)
       - [Mermaid Package](https://packagecontrol.io/packages/Mermaid)
     - [VS Code](https://code.visualstudio.com/)
    @@ -172,7 +172,7 @@ Communication tools and platforms
       - [Mermaid Markdown Syntax Highlighting](https://marketplace.visualstudio.com/items?itemName=bpruitt-goddard.mermaid-markdown-syntax-highlighting)
     - [Vim](https://www.vim.org)
       - [Vim Diagram Syntax](https://github.com/zhaozg/vim-diagram)
    -  - [Official Vim Syntax and ftplugin](https://github.com/craigmac/vim-mermaid)
    +  - [Official Vim Syntax and ft plugin](https://github.com/craigmac/vim-mermaid)
     
     ### Document Generation
     
    @@ -184,7 +184,7 @@ Communication tools and platforms
       - [gatsby-remark-mermaid](https://github.com/remcohaszing/gatsby-remark-mermaid)
     - [JSDoc](https://jsdoc.app/)
       - [jsdoc-mermaid](https://github.com/Jellyvision/jsdoc-mermaid)
    -- [mdbook](https://rust-lang.github.io/mdBook/index.html)
    +- [mdBook](https://rust-lang.github.io/mdBook/index.html)
       - [mdbook-mermaid](https://github.com/badboy/mdbook-mermaid)
     - [MkDocs](https://www.mkdocs.org)
       - [mkdocs-mermaid2-plugin](https://github.com/fralau/mkdocs-mermaid2-plugin)
    @@ -196,10 +196,9 @@ Communication tools and platforms
       - [remark-mermaidjs](https://github.com/remcohaszing/remark-mermaidjs)
     - [Sphinx](https://www.sphinx-doc.org/en/master/)
       - [sphinxcontrib-mermaid](https://github.com/mgaitan/sphinxcontrib-mermaid)
    -- [Swimm - Up-to-date diagrams with Swimm, the knowledge management tool for code](https://docs.swimm.io/Features/diagrams-and-charts#mermaid--swimm--up-to-date-diagrams-)
     - [Type Doc](https://typedoc.org/)
       - [typedoc-plugin-mermaid](https://www.npmjs.com/package/typedoc-plugin-mermaid)
    -- [Typora](https://typora.io/) ([native support](https://support.typora.io/Draw-Diagrams-With-Markdown/#mermaid))
    +- [Typora](https://support.typora.io/Draw-Diagrams-With-Markdown/#mermaid) ✅
     
     ### Browser Extensions
     
    @@ -210,7 +209,7 @@ Communication tools and platforms
     | Diagram Tab              | -                                                                                                            | -                                                                              | -                                                                              | -                                                                                                                            | [🐙🔗](https://github.com/khafast/diagramtab)                                                        |
     | Markdown Diagrams        | [🎡🔗](https://chrome.google.com/webstore/detail/markdown-diagrams/pmoglnmodacnbbofbgcagndelmgaclel/)        | [🦊🔗](https://addons.mozilla.org/en-US/firefox/addon/markdown-diagrams/)      | [🔴🔗](https://addons.opera.com/en/extensions/details/markdown-diagrams/)      | [🌀🔗](https://microsoftedge.microsoft.com/addons/detail/markdown-diagrams/hceenoomhhdkjjijnmlclkpenkapfihe)                 | [🐙🔗](https://github.com/marcozaccari/markdown-diagrams-browser-extension/tree/master/doc/examples) |
     | Markdown Viewer          | -                                                                                                            | [🦊🔗](https://addons.mozilla.org/en-US/firefox/addon/markdown-viewer-chrome/) | -                                                                              | -                                                                                                                            | [🐙🔗](https://github.com/simov/markdown-viewer)                                                     |
    -| Extensions for Mermaid   | -                                                                                                            | [🦊🔗](https://addons.mozilla.org/en-US/firefox/addon/markdown-viewer-chrome/) | [🔴🔗](https://addons.opera.com/en/extensions/details/extensions-for-mermaid/) | -                                                                                                                            | [🐙🔗](https://github.com/Stefan-S/mermaid-extension)                                                |
    +| Extensions for Mermaid   | -                                                                                                            | -                                                                              | [🔴🔗](https://addons.opera.com/en/extensions/details/extensions-for-mermaid/) | -                                                                                                                            | [🐙🔗](https://github.com/Stefan-S/mermaid-extension)                                                |
     | Chrome Diagrammer        | [🎡🔗](https://chrome.google.com/webstore/detail/chrome-diagrammer/bkpbgjmkomfoakfklcjeoegkklgjnnpk)         | -                                                                              | -                                                                              | -                                                                                                                            | -                                                                                                    |
     | Mermaid Diagrams         | [🎡🔗](https://chrome.google.com/webstore/detail/mermaid-diagrams/phfcghedmopjadpojhmmaffjmfiakfil)          | -                                                                              | -                                                                              | -                                                                                                                            | -                                                                                                    |
     | Monkeys                  | [🎡🔗](https://chrome.google.com/webstore/detail/monkeys-mermaid-for-githu/cplfdpoajbclbgphaphphcldamfkjlgi) | -                                                                              | -                                                                              | -                                                                                                                            | -                                                                                                    |
    @@ -228,8 +227,7 @@ Communication tools and platforms
     - [mermaid-isomorphic](https://github.com/remcohaszing/mermaid-isomorphic)
     - [mermaid-server: Generate diagrams using a HTTP request](https://github.com/TomWright/mermaid-server)
     - [NiceGUI: Let any browser be the frontend of your Python code](https://nicegui.io)
    -  - [ui.markdown(..., extras=['mermaid'])](https://nicegui.io/reference#markdown_element)
    -  - [ui.mermaid(...)](https://nicegui.io/reference#mermaid_diagrams)
    +  - [ui.mermaid(...)](https://nicegui.io/documentation/mermaid)
     - [Reveal.js](https://github.com/hakimel/reveal.js)
       - [reveal.js-mermaid-plugin](https://github.com/ludwick/reveal.js-mermaid-plugin)
     - [Reveal CK](https://github.com/jedcn/reveal-ck)
    
    From 201016ccc5bfa73e13577702369caffef6fb56a1 Mon Sep 17 00:00:00 2001
    From: Ronid1 
    Date: Thu, 23 Nov 2023 20:57:43 -0800
    Subject: [PATCH 031/217] update build docs
    
    ---
     docs/ecosystem/integrations-community.md | 3 +--
     1 file changed, 1 insertion(+), 2 deletions(-)
    
    diff --git a/docs/ecosystem/integrations-community.md b/docs/ecosystem/integrations-community.md
    index 2db6b00e1e..8046417666 100644
    --- a/docs/ecosystem/integrations-community.md
    +++ b/docs/ecosystem/integrations-community.md
    @@ -51,7 +51,7 @@ Below are a list of community plugins and integrations created with Mermaid.
     - [Mermaid Flow Visual Editor](https://www.mermaidflow.app) ✅
     - [Mermerd](https://github.com/KarnerTh/mermerd)
     - [Slab](https://slab.com) ✅
    -- [Swimm](https://docs.swimm.io/Features/diagrams-and-charts) ✅
    +- [Swimm](https://docs.swimm.io/Features/diagrams-and-charts#mermaid--swimm--up-to-date-diagrams-) ✅
     - [NotesHub](https://noteshub.app) ✅
     - [Notion](https://notion.so) ✅
     - [Observable](https://observablehq.com/@observablehq/mermaid) ✅
    @@ -198,7 +198,6 @@ Communication tools and platforms
       - [remark-mermaidjs](https://github.com/remcohaszing/remark-mermaidjs)
     - [Sphinx](https://www.sphinx-doc.org/en/master/)
       - [sphinxcontrib-mermaid](https://github.com/mgaitan/sphinxcontrib-mermaid)
    -- [Swimm - Up-to-date diagrams with Swimm, the knowledge management tool for code](https://docs.swimm.io/features/diagrams-and-charts/#mermaid--swimm--up-to-date-diagrams-)
     - [Type Doc](https://typedoc.org/)
       - [typedoc-plugin-mermaid](https://www.npmjs.com/package/typedoc-plugin-mermaid)
     - [Typora](https://support.typora.io/Draw-Diagrams-With-Markdown/#mermaid) ✅
    
    From f02dfe60afb84cd7b3b482c8c37e4ff7c9080d43 Mon Sep 17 00:00:00 2001
    From: futzmonitor 
    Date: Sat, 2 Dec 2023 10:18:58 -0500
    Subject: [PATCH 032/217] Changes to gnatt.jison 1. Removed the hash and
     semicolon symbols from the title regex to allow for their use. 2. Removed the
     hash and semicolon symbols from the section regex to allow for their use. 3.
     Removed the hash and semicolon symbols for the taskTxt regex to allow for
     their use. I did not remove the colon because the parser fails to recognize
     when the actual taskData begins if that distinctions isn't kept. 4. Removed
     the regex \#[^\n]* which skipped comments to fix some bugs with hash symbols
     in the taskTxt. I tested this changed by putting it back and using the
     comment  to see if it was recognized as a comment, but I would receive a
     syntax error and the diagram would not be rendered. So, I think we can safely
     remove that line, BUT it would be best practice if someone else tested this
     change to ensure that this will not break anyone's Gantt diagrams.
    
    ---
     packages/mermaid/src/diagrams/gantt/parser/gantt.jison | 9 ++++-----
     1 file changed, 4 insertions(+), 5 deletions(-)
    
    diff --git a/packages/mermaid/src/diagrams/gantt/parser/gantt.jison b/packages/mermaid/src/diagrams/gantt/parser/gantt.jison
    index b4daab5dca..5479629ff8 100644
    --- a/packages/mermaid/src/diagrams/gantt/parser/gantt.jison
    +++ b/packages/mermaid/src/diagrams/gantt/parser/gantt.jison
    @@ -5,7 +5,7 @@
      */
     %lex
     
    -%options case-insensitive
    +%options case-insensitivegit
     
     %x click
     %x href
    @@ -31,7 +31,6 @@ accDescr\s*"{"\s*                                { this.begin("acc_descr_multili
     
     [\n]+                   return 'NL';
     \s+                     /* skip whitespace */
    -\#[^\n]*                /* skip comments */
     \%%[^\n]*               /* skip comments */
     
     /*
    @@ -86,10 +85,10 @@ weekday\s+friday                return 'weekday_friday'
     weekday\s+saturday              return 'weekday_saturday'
     weekday\s+sunday                return 'weekday_sunday'
     \d\d\d\d"-"\d\d"-"\d\d          return 'date';
    -"title"\s[^#\n;]+               return 'title';
    +"title"\s[^\n]+               return 'title';
     "accDescription"\s[^#\n;]+      return 'accDescription'
    -"section"\s[^#:\n;]+            return 'section';
    -[^#:\n;]+                       return 'taskTxt';
    +"section"\s[^\n]+            return 'section';
    +[^:\n]+                       return 'taskTxt';
     ":"[^#\n;]+                     return 'taskData';
     ":"                             return ':';
     <>                         return 'EOF';
    
    From 68ff352f2db2a3d2b696ee494ee808b807817d34 Mon Sep 17 00:00:00 2001
    From: futzmonitor 
    Date: Sat, 2 Dec 2023 10:26:46 -0500
    Subject: [PATCH 033/217] Changes to gantt.jison 1. Removed typo
    
    ---
     packages/mermaid/src/diagrams/gantt/parser/gantt.jison | 2 +-
     1 file changed, 1 insertion(+), 1 deletion(-)
    
    diff --git a/packages/mermaid/src/diagrams/gantt/parser/gantt.jison b/packages/mermaid/src/diagrams/gantt/parser/gantt.jison
    index 5479629ff8..9866e8ba0c 100644
    --- a/packages/mermaid/src/diagrams/gantt/parser/gantt.jison
    +++ b/packages/mermaid/src/diagrams/gantt/parser/gantt.jison
    @@ -5,7 +5,7 @@
      */
     %lex
     
    -%options case-insensitivegit
    +%options case-insensitive
     
     %x click
     %x href
    
    From 8e95cdb8832722c0b646b5db3455bb2555c37a0d Mon Sep 17 00:00:00 2001
    From: futzmonitor 
    Date: Sat, 2 Dec 2023 12:56:58 -0500
    Subject: [PATCH 034/217] Changes to gantt.jison 1. Consistent spacing on line
     30
    
    ---
     packages/mermaid/src/diagrams/gantt/parser/gantt.jison | 2 +-
     1 file changed, 1 insertion(+), 1 deletion(-)
    
    diff --git a/packages/mermaid/src/diagrams/gantt/parser/gantt.jison b/packages/mermaid/src/diagrams/gantt/parser/gantt.jison
    index 9866e8ba0c..d6027fee98 100644
    --- a/packages/mermaid/src/diagrams/gantt/parser/gantt.jison
    +++ b/packages/mermaid/src/diagrams/gantt/parser/gantt.jison
    @@ -27,7 +27,7 @@ accDescr\s*"{"\s*                                { this.begin("acc_descr_multili
     
     \%\%(?!\{)*[^\n]*                                               /* skip comments */
     [^\}]\%\%*[^\n]*                                                /* skip comments */
    -\%\%*[^\n]*[\n]*           /* do nothing */
    +\%\%*[^\n]*[\n]*                                                /* do nothing */
     
     [\n]+                   return 'NL';
     \s+                     /* skip whitespace */
    
    From 8bff32adabfdc97022eb22a3bc4b4924d8e503fb Mon Sep 17 00:00:00 2001
    From: Matheus B 
    Date: Fri, 8 Dec 2023 13:08:13 -0300
    Subject: [PATCH 035/217] Modify algorithm to re-check for external connections
     after defining anchor nodes
    
    ---
     .../mermaid/src/dagre-wrapper/mermaid-graphlib.js  | 14 ++++++++++++++
     1 file changed, 14 insertions(+)
    
    diff --git a/packages/mermaid/src/dagre-wrapper/mermaid-graphlib.js b/packages/mermaid/src/dagre-wrapper/mermaid-graphlib.js
    index f42cc34633..81081e1b66 100644
    --- a/packages/mermaid/src/dagre-wrapper/mermaid-graphlib.js
    +++ b/packages/mermaid/src/dagre-wrapper/mermaid-graphlib.js
    @@ -254,6 +254,16 @@ export const adjustClustersAndEdges = (graph, depth) => {
         }
       });
     
    +  for (let id of Object.keys(clusterDb)) {
    +    const nonClusterChild = clusterDb[id].id;
    +    const parent = graph.parent(nonClusterChild);
    +
    +    // Change replacement node of id to parent of current replacement node if valid
    +    if (parent !== id && clusterDb[parent] && !clusterDb[parent].externalConnections) {
    +      clusterDb[id].id = parent;
    +    }
    +  }
    +
       // For clusters with incoming and/or outgoing edges translate those edges to a real node
       // in the cluster in order to fake the edge
       graph.edges().forEach(function (e) {
    @@ -307,9 +317,13 @@ export const adjustClustersAndEdges = (graph, depth) => {
           w = getAnchorId(e.w);
           graph.removeEdge(e.v, e.w, e.name);
           if (v !== e.v) {
    +        const parent = graph.parent(v);
    +        clusterDb[parent].externalConnections = true;
             edge.fromCluster = e.v;
           }
           if (w !== e.w) {
    +        const parent = graph.parent(w);
    +        clusterDb[parent].externalConnections = true;
             edge.toCluster = e.w;
           }
           log.warn('Fix Replacing with XXX', v, w, e.name);
    
    From c8f0b390751838af8290419c38da2aecb336ba07 Mon Sep 17 00:00:00 2001
    From: Matheus B 
    Date: Fri, 8 Dec 2023 13:39:53 -0300
    Subject: [PATCH 036/217] Add e2e test for edge case
    
    ---
     .../rendering/flowchart-v2.spec.js            | 19 +++++++++++++++++++
     1 file changed, 19 insertions(+)
    
    diff --git a/cypress/integration/rendering/flowchart-v2.spec.js b/cypress/integration/rendering/flowchart-v2.spec.js
    index e23820ffa3..857d395be7 100644
    --- a/cypress/integration/rendering/flowchart-v2.spec.js
    +++ b/cypress/integration/rendering/flowchart-v2.spec.js
    @@ -741,6 +741,25 @@ A ~~~ B
         );
       });
     
    +  it('5059: Should render when subgraph contains only subgraphs, has link to outside and itself is part of a link', () => {
    +    imgSnapshotTest(
    +      `flowchart
    +
    +      subgraph Main
    +        subgraph Child1
    +          Node1
    +          Node2
    +        end
    +        subgraph Child2
    +          Node3
    +          Node4
    +        end
    +      end
    +      Main --> Out1
    +      Child2 --> Out2`
    +    );
    +  });
    +
       describe('Markdown strings flowchart (#4220)', () => {
         describe('html labels', () => {
           it('With styling and classes', () => {
    
    From 57f0a3aa8e0afe79b582dc13c10129ee181cb091 Mon Sep 17 00:00:00 2001
    From: Nikolay Rozhkov 
    Date: Mon, 11 Dec 2023 05:08:42 +0300
    Subject: [PATCH 037/217] Contribution documentation improvements
    
    ---
     .gitignore                                    |   1 +
     docker-compose.yml                            |   4 +-
     packages/mermaid/scripts/docs.mts             |   4 +-
     .../mermaid/src/docs/.vitepress/config.ts     |  34 ++-
     packages/mermaid/src/docs/community/code.md   |  13 +-
     ...{docker-development.md => docker-setup.md} |  30 +--
     .../src/docs/community/documentation.md       |  27 +--
     packages/mermaid/src/docs/community/intro.md  |  49 +++++
     .../{newDiagram.md => new-diagram.md}         |   0
     .../mermaid/src/docs/community/quick-start.md |   1 +
     .../community/{development.md => setup.md}    |  30 +--
     .../mermaid/src/docs/community/workflow.md    | 130 ++++++++++++
     packages/mermaid/src/docs/config/advanced.md  |  24 ---
     packages/mermaid/src/docs/contributing        |   1 +
     .../Tutorials.md => ecosystem/tutorials.md}   |   0
     pnpm-lock.yaml                                | 196 +++++++++++++++---
     16 files changed, 425 insertions(+), 119 deletions(-)
     rename packages/mermaid/src/docs/community/{docker-development.md => docker-setup.md} (75%)
     create mode 100644 packages/mermaid/src/docs/community/intro.md
     rename packages/mermaid/src/docs/community/{newDiagram.md => new-diagram.md} (100%)
     create mode 100644 packages/mermaid/src/docs/community/quick-start.md
     rename packages/mermaid/src/docs/community/{development.md => setup.md} (78%)
     create mode 100644 packages/mermaid/src/docs/community/workflow.md
     delete mode 100644 packages/mermaid/src/docs/config/advanced.md
     create mode 120000 packages/mermaid/src/docs/contributing
     rename packages/mermaid/src/docs/{config/Tutorials.md => ecosystem/tutorials.md} (100%)
    
    diff --git a/.gitignore b/.gitignore
    index 6a1cc85e51..e6728b03f7 100644
    --- a/.gitignore
    +++ b/.gitignore
    @@ -46,3 +46,4 @@ stats/
     
     demos/dev/**
     !/demos/dev/example.html
    +tsx-0/**
    diff --git a/docker-compose.yml b/docker-compose.yml
    index e2484bdc52..a48cf5b8a2 100644
    --- a/docker-compose.yml
    +++ b/docker-compose.yml
    @@ -5,9 +5,9 @@ services:
         stdin_open: true
         tty: true
         working_dir: /mermaid
    -    mem_limit: '4G'
    +    mem_limit: '6G'
         environment:
    -      - NODE_OPTIONS=--max_old_space_size=4096
    +      - NODE_OPTIONS=--max_old_space_size=6096
         volumes:
           - ./:/mermaid
           - root_cache:/root/.cache
    diff --git a/packages/mermaid/scripts/docs.mts b/packages/mermaid/scripts/docs.mts
    index 3689cb68ba..42e299c54f 100644
    --- a/packages/mermaid/scripts/docs.mts
    +++ b/packages/mermaid/scripts/docs.mts
    @@ -60,13 +60,11 @@ const CDN_URL = 'https://cdn.jsdelivr.net/npm'; // 'https://unpkg.com';
     
     const MERMAID_KEYWORD = 'mermaid';
     const MERMAID_CODE_ONLY_KEYWORD = 'mermaid-example';
    +const MERMAID_DIAGRAM_ONLY = 'mermaid-nocode';
     
     // These keywords will produce both a mermaid diagram and a code block with the diagram source
     const MERMAID_EXAMPLE_KEYWORDS = [MERMAID_KEYWORD, 'mmd', MERMAID_CODE_ONLY_KEYWORD]; // 'mmd' is an old keyword that used to be used
     
    -// This keyword will only produce a mermaid diagram
    -const MERMAID_DIAGRAM_ONLY = 'mermaid-nocode';
    -
     // These will be transformed into block quotes
     const BLOCK_QUOTE_KEYWORDS = ['note', 'tip', 'warning', 'danger'];
     
    diff --git a/packages/mermaid/src/docs/.vitepress/config.ts b/packages/mermaid/src/docs/.vitepress/config.ts
    index 8601664fa5..db1fdfef07 100644
    --- a/packages/mermaid/src/docs/.vitepress/config.ts
    +++ b/packages/mermaid/src/docs/.vitepress/config.ts
    @@ -71,8 +71,8 @@ function nav() {
         { text: 'Docs', link: '/intro/', activeMatch: '/intro/' },
         {
           text: 'Tutorials',
    -      link: '/config/Tutorials',
    -      activeMatch: '/config/',
    +      link: '/ecosystem/tutorials',
    +      activeMatch: '/ecosystem/',
         },
         {
           text: 'Integrations',
    @@ -81,8 +81,8 @@ function nav() {
         },
         {
           text: 'Contributing',
    -      link: '/community/development.html',
    -      activeMatch: '/community/',
    +      link: '/contributing/intro',
    +      activeMatch: '/contributing/',
         },
         {
           text: 'Latest News',
    @@ -95,11 +95,7 @@ function nav() {
             {
               text: 'Changelog',
               link: 'https://github.com/mermaid-js/mermaid/releases',
    -        },
    -        {
    -          text: 'Contributing',
    -          link: '/community/development',
    -        },
    +        }
           ],
         },
         {
    @@ -167,7 +163,6 @@ function sidebarConfig() {
           collapsed: false,
           items: [
             { text: 'Configuration', link: '/config/configuration' },
    -        { text: 'Tutorials', link: '/config/Tutorials' },
             { text: 'API-Usage', link: '/config/usage' },
             { text: 'Mermaid API Configuration', link: '/config/setup/README' },
             { text: 'Mermaid Configuration Options', link: '/config/schema-docs/config' },
    @@ -175,7 +170,6 @@ function sidebarConfig() {
             { text: 'Theming', link: '/config/theming' },
             { text: 'Accessibility', link: '/config/accessibility' },
             { text: 'Mermaid CLI', link: '/config/mermaidCLI' },
    -        { text: 'Advanced usage', link: '/config/advanced' },
             { text: 'FAQ', link: '/config/faq' },
           ],
         },
    @@ -189,6 +183,7 @@ function sidebarEcosystem() {
           collapsed: false,
           items: [
             { text: 'Mermaid Chart', link: '/ecosystem/mermaid-chart' },
    +        { text: 'Tutorials', link: '/ecosystem/tutorials' },
             { text: 'Integrations - Community', link: '/ecosystem/integrations-community' },
             { text: 'Integrations - Create', link: '/ecosystem/integrations-create' },
           ],
    @@ -199,15 +194,18 @@ function sidebarEcosystem() {
     function sidebarCommunity() {
       return [
         {
    -      text: '🙌 Contributions and Community',
    +      text: '🙌 Contributing',
           collapsed: false,
           items: [
    -        { text: 'Contributing to Mermaid', link: '/community/development' },
    -        { text: 'Contributing Code', link: '/community/code' },
    -        { text: 'Contributing Documentation', link: '/community/documentation' },
    -        { text: 'Questions and Suggestions', link: '/community/questions-and-suggestions' },
    -        { text: 'Adding Diagrams', link: '/community/newDiagram' },
    -        { text: 'Security', link: '/community/security' },
    +        { text: 'Contributing to Mermaid', link: '/contributing/intro' },
    +        { text: 'Quick start guide', link: '/contributing/quick-start' },
    +        { text: 'Initial setup', link: '/contributing/setup' },
    +        { text: 'Workflow', link: '/contributing/workflow' },
    +        { text: 'Code', link: '/contributing/code' },
    +        { text: 'Documentation', link: '/contributing/documentation' },
    +        { text: 'Questions and Suggestions', link: '/contributing/questions-and-suggestions' },
    +        { text: 'Adding Diagrams', link: '/contributing/new-diagram' },
    +        { text: 'Security', link: '/contributing/security' },
           ],
         },
       ];
    diff --git a/packages/mermaid/src/docs/community/code.md b/packages/mermaid/src/docs/community/code.md
    index 93a5fcd953..b1f225d50b 100644
    --- a/packages/mermaid/src/docs/community/code.md
    +++ b/packages/mermaid/src/docs/community/code.md
    @@ -4,7 +4,13 @@ The basic steps for contributing code are:
     
     ```mermaid
     graph LR
    -    git[1. Checkout a  git branch] --> codeTest[2. Write tests and code] --> doc[3. Update documentation] --> submit[4. Submit a PR] --> review[5. Review and merge]
    +  git --> codeTest --> doc --> submit --> review
    +
    +  git[1. Checkout a  git branch]
    +  codeTest[2. Write tests and code]
    +  doc[3. Update documentation]
    +  submit[4. Submit a PR]
    +  review[5. Review and merge]
     ```
     
     1. **Create** and checkout a git branch and work on your code in the branch
    @@ -47,12 +53,17 @@ You can always check current [configuration of labelling and branch prefixes](ht
     
     If your work is specific to a single diagram type, it is a good idea to put the diagram type at the start of the description. This will help us keep release notes organized: it will help us keep changes for a diagram type together.
     
    +```tip
     **Ex: A new feature described in issue 2945 that adds a new arrow type called 'florbs' to state diagrams**
     
     `feature/2945_state-diagram-new-arrow-florbs`
    +```
     
    +```tip
     **Ex: A bug described in issue 1123 that causes random ugly red text in multiple diagram types**
    +
     `bug/1123_fix_random_ugly_red_text`
    +```
     
     ## 2. Write Tests
     
    diff --git a/packages/mermaid/src/docs/community/docker-development.md b/packages/mermaid/src/docs/community/docker-setup.md
    similarity index 75%
    rename from packages/mermaid/src/docs/community/docker-development.md
    rename to packages/mermaid/src/docs/community/docker-setup.md
    index 89e08b3f70..753c1d4b9d 100644
    --- a/packages/mermaid/src/docs/community/docker-development.md
    +++ b/packages/mermaid/src/docs/community/docker-setup.md
    @@ -1,14 +1,20 @@
    -# Contributing to Mermaid via Docker
    +# Initial setup with Docker
     
     > The following documentation describes how to work with Mermaid in a Docker environment.
    -> There's also a [host installation guide](../community/development.md)
    +> There's also a [host installation guide](../community/setup.md)
     > if you prefer to work without a Docker environment.
     
    -So you want to help? That's great!
    +Initial setup consists of 3 main steps::
     
    -![Image of happy people jumping with excitement](https://media.giphy.com/media/BlVnrxJgTGsUw/giphy.gif)
    +```mermaid-nocode
    +flowchart LR
    +  source --> requirements --> setup
    +  
    +  source[Get the source code]
    +  requirements[Install the requirements]
    +  setup[Setup and launch]
     
    -Here are a few things to get you started on the right path.
    +```
     
     ## Get the Source Code
     
    @@ -23,7 +29,7 @@ Then you **clone** a copy to your local development machine (e.g. where you code
     ## Technical Requirements
     
     > The following documentation describes how to work with Mermaid in a Docker environment.
    -> There's also a [host installation guide](../community/development.md)
    +> There's also a [host installation guide](../community/setup.md)
     > if you prefer to work without a Docker environment.
     
     [Install Docker](https://docs.docker.com/engine/install/). And that is pretty much all you need.
    @@ -87,18 +93,16 @@ After making code changes, the dev server will rebuild the mermaid library. You
     
     ## Verify Everything is Working
     
    +This step is optional, but it helps to make sure that everything in development branch was OK before you started making any changes.
    +
    +You can run the `test` script to verify that pnpm is working _and_ that the repository has been cloned correctly:
    +
     ```bash
    -./run pnpm test
    +pnpm test
     ```
     
     The `test` script and others are in the top-level `package.json` file.
     
     All tests should run successfully without any errors or failures. (You might see _lint_ or _formatting_ warnings; those are ok during this step.)
     
    -## Last Words
    -
    -Don't get daunted if it is hard in the beginning. We have a great community with only encouraging words. So, if you get stuck, ask for help and hints in the Slack forum. If you want to show off something good, show it off there.
    -
    -[Join our Slack community if you want closer contact!](https://join.slack.com/t/mermaid-talk/shared_invite/enQtNzc4NDIyNzk4OTAyLWVhYjQxOTI2OTg4YmE1ZmJkY2Y4MTU3ODliYmIwOTY3NDJlYjA0YjIyZTdkMDMyZTUwOGI0NjEzYmEwODcwOTE)
     
    -![Image of superhero wishing you good luck](https://media.giphy.com/media/l49JHz7kJvl6MCj3G/giphy.gif)
    diff --git a/packages/mermaid/src/docs/community/documentation.md b/packages/mermaid/src/docs/community/documentation.md
    index 6a0df983d1..2c33af410c 100644
    --- a/packages/mermaid/src/docs/community/documentation.md
    +++ b/packages/mermaid/src/docs/community/documentation.md
    @@ -1,21 +1,18 @@
     # Contributing Documentation
     
    -**_[TODO: This section is still a WIP. It still needs MAJOR revision.]_**
    -
     If it is not in the documentation, it's like it never happened. Wouldn't that be sad? With all the effort that was put into the feature?
     
    -The docs are located in the `packages/mermaid/src/docs` folder and are written in Markdown. Just pick the right section and start typing.
    +The documentation is written in Markdown. It is located in the [`packages/mermaid/src/docs`](https://github.com/mermaid-js/mermaid/tree/develop/packages/mermaid/src/docs) folder and organized according to relevant subfolder. Just pick the right section and start typing.
     
    -The contents of [mermaid.js.org](https://mermaid.js.org/) are based on the docs from the `master` branch.
    -Updates committed to the `master` branch are reflected in the [Mermaid Docs](https://mermaid.js.org/) once published.
    +The contents of [mermaid.js.org](https://mermaid.js.org/) are based on the docs from the `master` branch. Updates committed to the `master` branch are reflected in the [Mermaid Docs](https://mermaid.js.org/) once published.
     
     ## How to Contribute to Documentation
     
    -We are a little less strict here, it is OK to commit directly in the `develop` branch if you are a collaborator.
    -
    -The documentation is located in the `packages/mermaid/src/docs` directory and organized according to relevant subfolder.
    +```warning
    +DO NOT CHANGE FILES IN `/docs`
     
     The `docs` folder will be automatically generated when committing to `packages/mermaid/src/docs` and **should not** be edited manually.
    +```
     
     ```mermaid
     flowchart LR
    @@ -25,6 +22,12 @@ flowchart LR
     
     ```
     
    +It is OK to commit directly in the `develop` branch if you are a collaborator.
    +
    +```tip
    +If the change is **only** to the documentation, you can get your changes published to the site quicker by making a PR to the `master` branch. In that case, your branch should be based on master, not develop.
    +```
    +
     You can use `note`, `tip`, `warning` and `danger` in triple backticks to add a note, tip, warning or danger box.
     Do not use vitepress specific markdown syntax `::: warning` as it will not be processed correctly.
     
    @@ -46,14 +49,6 @@ Danger content
     ```
     ````
     
    -```note
    -If the change is _only_ to the documentation, you can get your changes published to the site quicker by making a PR to the `master` branch. In that case, your branch should be based on master, not develop.
    -```
    -
    -We encourage contributions to the documentation at [packages/mermaid/src/docs in the _develop_ branch](https://github.com/mermaid-js/mermaid/tree/develop/packages/mermaid/src/docs).
    -
    -**_DO NOT CHANGE FILES IN `/docs`_**
    -
     ## The official documentation site
     
     **[The mermaid documentation site](https://mermaid.js.org/) is powered by [Vitepress](https://vitepress.vuejs.org/).**
    diff --git a/packages/mermaid/src/docs/community/intro.md b/packages/mermaid/src/docs/community/intro.md
    new file mode 100644
    index 0000000000..953f98e671
    --- /dev/null
    +++ b/packages/mermaid/src/docs/community/intro.md
    @@ -0,0 +1,49 @@
    +# Contributing to Mermaid
    +
    +So you want to help? That's great!
    +
    +![Image of happy people jumping with excitement](https://media.giphy.com/media/BlVnrxJgTGsUw/giphy.gif)
    +
    +Here are a few things to get you started on the right path.
    +
    +## How can I help?
    +
    +```mermaid-nocode
    +mindmap
    +  root)Contribution(
    +    Development
    +      Solving issues
    +      Adding new diagrams
    +      Handling pull requests
    +      Updating tooling
    +    Testing
    +      Verification of fixed issues
    +      Regression testing in connection with releases
    +      Testing pull requests
    +    Management
    +      Coordinating the work
    +      Classification and monitoring of incoming issues
    +```
    +
    +## Join the development
    +
    +[Join our slack community if you want closer contact!](https://join.slack.com/t/mermaid-talk/shared_invite/enQtNzc4NDIyNzk4OTAyLWVhYjQxOTI2OTg4YmE1ZmJkY2Y4MTU3ODliYmIwOTY3NDJlYjA0YjIyZTdkMDMyZTUwOGI0NjEzYmEwODcwOTE)
    +
    +## Where do I start?
    +
    +* You could confirm the bugs in [these issues](https://github.com/knsv/mermaid/issues?utf8=%E2%9C%93&q=is%3Aissue+is%3Aopen+label%3A%22Type%3A+Bug+%2F+Error%22+label%3A%22Status%3A+Pending%22).
    +* You could help write and improve the documentation! [Here's ](https://github.com/knsv/mermaid/issues?utf8=%E2%9C%93&q=is%3Aissue+is%3Aopen+label%3A%22Help+wanted%21%22+label%3A%22Area%3A+Documentation%22)some inspiration.
    +* You could start getting some knowledge of the code base by working on [these "good first issues"](https://github.com/knsv/mermaid/issues?utf8=%E2%9C%93&q=is%3Aissue+is%3Aopen+label%3A%22Good+first+issue%21%22+).
    +* You could jump right in and help us fix any of [these bugs](https://github.com/knsv/mermaid/issues?utf8=%E2%9C%93&q=is%3Aissue+is%3Aopen+label%3A%22Type%3A+Bug+%2F+Error%22+label%3A%22Help+wanted%21%22+label%3A%22Area%3A+Development%22)!
    +* You could work on a new feature! [These](https://github.com/knsv/mermaid/issues?utf8=%E2%9C%93&q=is%3Aissue+is%3Aopen+label%3A%22Area%3A+Development%22+label%3A%22Help+wanted%21%22+label%3A%22Type%3A+Enhancement%22+label%3A%22Status%3A+Approved%22) are some ideas!
    +
    +Detailed information about contributing can be found in the [contribution guide](https://github.com/mermaid-js/mermaid/blob/master/CONTRIBUTING.md).
    +
    +
    +## Last Words
    +
    +Don't get daunted if it is hard in the beginning. We have a great community with only encouraging words. So, if you get stuck, ask for help and hints in the Slack forum. If you want to show off something good, show it off there.
    +
    +[Join our Slack community if you want closer contact!](https://join.slack.com/t/mermaid-talk/shared_invite/enQtNzc4NDIyNzk4OTAyLWVhYjQxOTI2OTg4YmE1ZmJkY2Y4MTU3ODliYmIwOTY3NDJlYjA0YjIyZTdkMDMyZTUwOGI0NjEzYmEwODcwOTE)
    +
    +![Image of superhero wishing you good luck](https://media.giphy.com/media/l49JHz7kJvl6MCj3G/giphy.gif)
    diff --git a/packages/mermaid/src/docs/community/newDiagram.md b/packages/mermaid/src/docs/community/new-diagram.md
    similarity index 100%
    rename from packages/mermaid/src/docs/community/newDiagram.md
    rename to packages/mermaid/src/docs/community/new-diagram.md
    diff --git a/packages/mermaid/src/docs/community/quick-start.md b/packages/mermaid/src/docs/community/quick-start.md
    new file mode 100644
    index 0000000000..84ae492eaa
    --- /dev/null
    +++ b/packages/mermaid/src/docs/community/quick-start.md
    @@ -0,0 +1 @@
    +quick start contributing guide
    \ No newline at end of file
    diff --git a/packages/mermaid/src/docs/community/development.md b/packages/mermaid/src/docs/community/setup.md
    similarity index 78%
    rename from packages/mermaid/src/docs/community/development.md
    rename to packages/mermaid/src/docs/community/setup.md
    index fc11a1f6c0..2545d315a8 100644
    --- a/packages/mermaid/src/docs/community/development.md
    +++ b/packages/mermaid/src/docs/community/setup.md
    @@ -1,12 +1,20 @@
    -# Contributing to Mermaid
    +# Initial setup
     
     > The following documentation describes how to work with Mermaid in your host environment.
    -> There's also a [Docker installation guide](../community/docker-development.md)
    +> There's also a [Docker installation guide](../community/docker-setup.md)
     > if you prefer to work in a Docker environment.
     
    -So you want to help? That's great!
    +Initial setup consists of 3 main steps:
     
    -![Image of happy people jumping with excitement](https://media.giphy.com/media/BlVnrxJgTGsUw/giphy.gif)
    +```mermaid-nocode
    +flowchart LR
    +  source --> requirements --> setup
    +  
    +  source[Get the source code]
    +  requirements[Install the requirements]
    +  setup[Setup and launch]
    +
    +```
     
     Here are a few things to get you started on the right path.
     
    @@ -18,12 +26,12 @@ Then you **clone** a copy to your local development machine (e.g. where you code
     
     [Fork mermaid](https://github.com/mermaid-js/mermaid/fork) to start contributing to the main project and its documentation, or [search for other repositories](https://github.com/orgs/mermaid-js/repositories).
     
    -[Here is a GitHub document that gives an overview of the process.](https://docs.github.com/en/get-started/quickstart/fork-a-repo)
    +[Here is a GitHub document that gives an overview of the process](https://docs.github.com/en/get-started/quickstart/fork-a-repo).
     
     ## Technical Requirements
     
     > The following documentation describes how to work with Mermaid in your host environment.
    -> There's also a [Docker installation guide](../community/docker-development.md)
    +> There's also a [Docker installation guide](../community/docker-setup.md)
     > if you prefer to work in a Docker environment.
     
     These are the tools we use for working with the code and documentation:
    @@ -71,6 +79,8 @@ After making code changes, the dev server will rebuild the mermaid library. You
     
     ## Verify Everything is Working
     
    +This step is optional, but it helps to make sure that everything in development branch was OK before you started making any changes.
    +
     You can run the `test` script to verify that pnpm is working _and_ that the repository has been cloned correctly:
     
     ```bash
    @@ -80,11 +90,3 @@ pnpm test
     The `test` script and others are in the top-level `package.json` file.
     
     All tests should run successfully without any errors or failures. (You might see _lint_ or _formatting_ warnings; those are ok during this step.)
    -
    -## Last Words
    -
    -Don't get daunted if it is hard in the beginning. We have a great community with only encouraging words. So, if you get stuck, ask for help and hints in the Slack forum. If you want to show off something good, show it off there.
    -
    -[Join our Slack community if you want closer contact!](https://join.slack.com/t/mermaid-talk/shared_invite/enQtNzc4NDIyNzk4OTAyLWVhYjQxOTI2OTg4YmE1ZmJkY2Y4MTU3ODliYmIwOTY3NDJlYjA0YjIyZTdkMDMyZTUwOGI0NjEzYmEwODcwOTE)
    -
    -![Image of superhero wishing you good luck](https://media.giphy.com/media/l49JHz7kJvl6MCj3G/giphy.gif)
    diff --git a/packages/mermaid/src/docs/community/workflow.md b/packages/mermaid/src/docs/community/workflow.md
    new file mode 100644
    index 0000000000..313fd10787
    --- /dev/null
    +++ b/packages/mermaid/src/docs/community/workflow.md
    @@ -0,0 +1,130 @@
    +# Workflow
    +
    +Mermaid uses a [Git Flow](https://guides.github.com/introduction/flow/)–inspired approach to branching.
    +
    +Development is done in the `develop` branch.
    +
    +Once development is done we create a `release/vX.X.X` branch from `develop` for testing.
    +
    +Once the release happens we add a tag to the `release` branch and merge it with `master`. The live product and on-line documentation are what is in the `master` branch.
    +
    +The basic steps to start contributing code and documentation are:
    +
    +```mermaid-nocode
    +  flowchart TB
    +
    +  fetch --> branch --> update --> submit --> review --> fetch
    +  fetch[Fetch development branch]
    +  branch[Checkout a new branch]
    +  update[Make changes]
    +  submit[Submit a PR]
    +  review[Review and merge]
    +```
    +
    +## Fech latest code
    +
    +```tip
    +All new work should be based on the `develop` branch.
    +```
    +
    +Make sure you have the most up-to-date version of the `develop` branch.
    +
    +Check out the `develop` branch, then `fetch` or `pull` to update it:
    +
    +```bash
    +git checkout develop
    +git fetch # or `git pull`
    +```
    +
    +## Checkout new branch
    +
    +Create a new branch for your work:
    +
    +```bash
    +git checkout develop # make sure you are on development branch
    +git checkout -b docs/2910_update-contributing-guidelines
    +```
    +
    +We use the following naming convention for branches:
    +
    +```txt
    +[feature | bug | chore | docs]/[issue number]_[short-description]
    +```
    +
    +You can always check current [configuration of labelling and branch prefixes](https://github.com/mermaid-js/mermaid/blob/develop/.github/pr-labeler.yml)
    +
    +- The first part is the **type** of change: a `feature`, `bug`, `chore`, `docs`
    +- followed by a **slash** (`/`),which helps to group like types together in many git tools
    +- followed by the **issue number**, e.g. `2910`
    +- followed by an **underscore** (`_`)
    +- followed by a **short description** with dashes (`-`) or underscores (`_`) instead of spaces
    +
    +```mermaid-nocode
    +flowchart LR
    +  feature --> slash
    +  bug --> slash
    +  chore --> slash
    +  docs --> slash
    +  slash --> 2945 --> underscore
    +  slash --> 1123 --> underscore
    +  underscore --> short_description_1
    +  underscore --> short_description_2
    +  
    +  underscore["_"]
    +  slash["/"]
    +  
    +  short_description_1["state-diagram-new-arrow-florbs"]
    +  short_description_2["fix_random_ugly_red_text"]
    +```
    +
    +
    +If your work is specific to a single diagram type, it is a good idea to put the diagram type at the start of the description. This will help us keep release notes organized by a diagram type.
    +
    +```note
    +A new feature described in issue 2945 that adds a new arrow type called 'florbs' to state diagrams
    +
    +`feature/2945_state-diagram-new-arrow-florbs`
    +```
    +
    +```tip
    +A bug described in issue 1123 that causes random ugly red text in multiple diagram types
    +
    +`bug/1123_fix_random_ugly_red_text`
    +```
    +
    +## Make changes
    +
    +Source code along with the documentation is located in packages [`packages/mermaid`](https://github.com/mermaid-js/mermaid/tree/develop/packages/mermaid/src/docs) folder.
    +You may need to update both, depending on your task.
    +
    +## Submit your pull request
    +
    +````note
    +Do not forget to push your changes
    +
    +```bash
    +git push -u origin docs/2910_update-contributing-guidelines
    +```
    +````
    +
    +We make all changes via Pull Requests (PRs). Open a new one.
    +
    +Right now we are not following any strict rules about naming PRs. Give it a representative title and short description. There is also a [pull_request_template](https://github.com/mermaid-js/mermaid/blob/develop/.github/pull_request_template.md) which will help you with it.
    +
    +In case in its description contains a [magic comment](https://docs.github.com/en/issues/tracking-your-work-with-issues/linking-a-pull-request-to-an-issue) your PR will be automatically attached to the issue:
    +
    +```
    +Resolves #
    +```
    +You can edit it if needed.
    +
    +## Congratulations
    +
    +You have successfully submitted your improvements! What is next?
    +
    +- PRs will be reviewed by active maintainers, who will provide feedback and request changes as needed.
    +- The maintainers will request a review from _knsv_, if necessary.
    +- Once the PR is approved, the maintainers will merge the PR into the `develop` branch.
    +- When a release is ready, the `release/x.x.x` branch will be created, extensively tested and knsv will be in charge of the release process.
    +
    +_knsv, Knut Sveidqvist_ is in charge of the final release process and the active maintainers are in charge of reviewing and merging most PRs.
    diff --git a/packages/mermaid/src/docs/config/advanced.md b/packages/mermaid/src/docs/config/advanced.md
    deleted file mode 100644
    index 4ab4774285..0000000000
    --- a/packages/mermaid/src/docs/config/advanced.md
    +++ /dev/null
    @@ -1,24 +0,0 @@
    -# Advanced mermaid (Coming soon..)
    -
    -## splitting mermaid code from html
    -
    -A more condensed html code can be achieved by embedding the mermaid code in its own .js file, which is referenced like so:
    -
    -```html
    -...
    -  
    -  
    -
    -```
    -
    -The actual mermaid file could for example look like this:
    -
    -```javascript
    -mermaid content ...
    -```
    -
    -## mermaid configuration options
    -
    -```markdown
    -(coming soon)
    -```
    diff --git a/packages/mermaid/src/docs/contributing b/packages/mermaid/src/docs/contributing
    new file mode 120000
    index 0000000000..013cf3ce01
    --- /dev/null
    +++ b/packages/mermaid/src/docs/contributing
    @@ -0,0 +1 @@
    +community/
    \ No newline at end of file
    diff --git a/packages/mermaid/src/docs/config/Tutorials.md b/packages/mermaid/src/docs/ecosystem/tutorials.md
    similarity index 100%
    rename from packages/mermaid/src/docs/config/Tutorials.md
    rename to packages/mermaid/src/docs/ecosystem/tutorials.md
    diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
    index 1a872627cc..0df111ebd8 100644
    --- a/pnpm-lock.yaml
    +++ b/pnpm-lock.yaml
    @@ -481,6 +481,61 @@ importers:
             specifier: ^7.0.0
             version: 7.0.0
     
    +  packages/mermaid/src/vitepress:
    +    dependencies:
    +      '@vueuse/core':
    +        specifier: ^10.1.0
    +        version: 10.1.0(vue@3.3.4)
    +      jiti:
    +        specifier: ^1.18.2
    +        version: 1.18.2
    +      mermaid:
    +        specifier: workspace:^
    +        version: link:../..
    +      vue:
    +        specifier: ^3.3
    +        version: 3.3.4
    +    devDependencies:
    +      '@iconify-json/carbon':
    +        specifier: ^1.1.16
    +        version: 1.1.16
    +      '@unocss/reset':
    +        specifier: ^0.58.0
    +        version: 0.58.0
    +      '@vite-pwa/vitepress':
    +        specifier: ^0.3.0
    +        version: 0.3.0(vite-plugin-pwa@0.17.0)
    +      '@vitejs/plugin-vue':
    +        specifier: ^4.2.1
    +        version: 4.2.1(vite@4.4.12)(vue@3.3.4)
    +      fast-glob:
    +        specifier: ^3.2.12
    +        version: 3.2.12
    +      https-localhost:
    +        specifier: ^4.7.1
    +        version: 4.7.1
    +      pathe:
    +        specifier: ^1.1.0
    +        version: 1.1.0
    +      unocss:
    +        specifier: ^0.58.0
    +        version: 0.58.0(postcss@8.4.31)(rollup@2.79.1)(vite@4.4.12)
    +      unplugin-vue-components:
    +        specifier: ^0.26.0
    +        version: 0.26.0(rollup@2.79.1)(vue@3.3.4)
    +      vite:
    +        specifier: ^4.4.12
    +        version: 4.4.12(@types/node@18.17.5)
    +      vite-plugin-pwa:
    +        specifier: ^0.17.0
    +        version: 0.17.0(vite@4.4.12)(workbox-build@7.0.0)(workbox-window@7.0.0)
    +      vitepress:
    +        specifier: 1.0.0-rc.31
    +        version: 1.0.0-rc.31(@algolia/client-search@4.19.1)(@types/node@18.17.5)(postcss@8.4.31)(search-insights@2.7.0)(typescript@5.1.6)
    +      workbox-window:
    +        specifier: ^7.0.0
    +        version: 7.0.0
    +
       tests/webpack:
         dependencies:
           '@mermaid-js/mermaid-example-diagram':
    @@ -1372,7 +1427,6 @@ packages:
       /@babel/helper-string-parser@7.23.4:
         resolution: {integrity: sha512-803gmbQdqwdf4olxrX4AJyFBV/RTr3rSmOj0rKwesmzlfhYNDEs+/iOcznzpNWlJlIlTJC2QfPFcHB6DlzdVLQ==}
         engines: {node: '>=6.9.0'}
    -    dev: true
     
       /@babel/helper-validator-identifier@7.22.20:
         resolution: {integrity: sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==}
    @@ -1455,7 +1509,6 @@ packages:
         hasBin: true
         dependencies:
           '@babel/types': 7.23.5
    -    dev: true
     
       /@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@7.22.5(@babel/core@7.23.5):
         resolution: {integrity: sha512-NP1M5Rf+u2Gw9qfSO4ihjcTGW5zXTi36ITLd4/EoAcEhIZ0yjMqmftDNl3QC19CX7olhrjpyU454g/2W7X0jvQ==}
    @@ -2547,7 +2600,6 @@ packages:
           '@babel/helper-string-parser': 7.23.4
           '@babel/helper-validator-identifier': 7.22.20
           to-fast-properties: 2.0.0
    -    dev: true
     
       /@bcherny/json-schema-ref-parser@9.0.9:
         resolution: {integrity: sha512-vmEmnJCfpkLdas++9OYg6riIezTYqTHpqUTODJzHLzs5UnXujbOJW9VwcVCnyo1mVRt32FRr23iXBx/sX8YbeQ==}
    @@ -4397,21 +4449,6 @@ packages:
           picomatch: 2.3.1
         dev: true
     
    -  /@rollup/pluginutils@5.0.5(rollup@2.79.1):
    -    resolution: {integrity: sha512-6aEYR910NyP73oHiJglti74iRyOwgFU4x3meH/H8OJx6Ry0j6cOVZ5X/wTvub7G7Ao6qaHBEaNsV3GLJkSsF+Q==}
    -    engines: {node: '>=14.0.0'}
    -    peerDependencies:
    -      rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0
    -    peerDependenciesMeta:
    -      rollup:
    -        optional: true
    -    dependencies:
    -      '@types/estree': 1.0.1
    -      estree-walker: 2.0.2
    -      picomatch: 2.3.1
    -      rollup: 2.79.1
    -    dev: true
    -
       /@rollup/pluginutils@5.1.0(rollup@2.79.1):
         resolution: {integrity: sha512-XTIWOPPcpvyKI6L1NHo0lFlCyznUEyPmPY1mc3KpPVDYulHSTvyeLNVW00QTLIAFNhR3kYnJTQHeGqU4M3n09g==}
         engines: {node: '>=14.0.0'}
    @@ -4598,7 +4635,7 @@ packages:
       /@types/babel__core@7.20.1:
         resolution: {integrity: sha512-aACu/U/omhdk15O4Nfb+fHgH/z3QsfQzpnvRZhYhThms83ZnAOZz7zZAWO7mn2yyNQaA4xTO8GLK3uqFU4bYYw==}
         dependencies:
    -      '@babel/parser': 7.23.0
    +      '@babel/parser': 7.23.5
           '@babel/types': 7.23.0
           '@types/babel__generator': 7.6.4
           '@types/babel__template': 7.4.1
    @@ -4614,7 +4651,7 @@ packages:
       /@types/babel__template@7.4.1:
         resolution: {integrity: sha512-azBFKemX6kMg5Io+/rdGT0dkGreboUVR0Cdm3fz9QJWpaQGJRQXl7C+6hOTCZcMll7KFyEQpgbYI2lHdsS4U7g==}
         dependencies:
    -      '@babel/parser': 7.23.0
    +      '@babel/parser': 7.23.5
           '@babel/types': 7.23.0
         dev: true
     
    @@ -5558,6 +5595,22 @@ packages:
         resolution: {integrity: sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==}
         dev: true
     
    +  /@unocss/astro@0.58.0(rollup@2.79.1)(vite@4.4.12):
    +    resolution: {integrity: sha512-df+tEFO5eKXjQOwSWQhS9IdjD0sfLHLtn8U09sEKR2Nmh5CvpwyBxmvLQgOCilPou7ehmyKfsyGRLZg7IMp+Ew==}
    +    peerDependencies:
    +      vite: ^2.9.0 || ^3.0.0-0 || ^4.0.0 || ^5.0.0-0
    +    peerDependenciesMeta:
    +      vite:
    +        optional: true
    +    dependencies:
    +      '@unocss/core': 0.58.0
    +      '@unocss/reset': 0.58.0
    +      '@unocss/vite': 0.58.0(rollup@2.79.1)(vite@4.4.12)
    +      vite: 4.4.12(@types/node@18.17.5)
    +    transitivePeerDependencies:
    +      - rollup
    +    dev: true
    +
       /@unocss/astro@0.58.0(rollup@2.79.1)(vite@4.5.0):
         resolution: {integrity: sha512-df+tEFO5eKXjQOwSWQhS9IdjD0sfLHLtn8U09sEKR2Nmh5CvpwyBxmvLQgOCilPou7ehmyKfsyGRLZg7IMp+Ew==}
         peerDependencies:
    @@ -5752,6 +5805,26 @@ packages:
           '@unocss/core': 0.58.0
         dev: true
     
    +  /@unocss/vite@0.58.0(rollup@2.79.1)(vite@4.4.12):
    +    resolution: {integrity: sha512-OCUOLMSOBEtXOEyBbAvMI3/xdR175BWRzmvV9Wc34ANZclEvCdVH8+WU725ibjY4VT0gVIuX68b13fhXdHV41A==}
    +    peerDependencies:
    +      vite: ^2.9.0 || ^3.0.0-0 || ^4.0.0 || ^5.0.0-0
    +    dependencies:
    +      '@ampproject/remapping': 2.2.1
    +      '@rollup/pluginutils': 5.1.0(rollup@2.79.1)
    +      '@unocss/config': 0.58.0
    +      '@unocss/core': 0.58.0
    +      '@unocss/inspector': 0.58.0
    +      '@unocss/scope': 0.58.0
    +      '@unocss/transformer-directives': 0.58.0
    +      chokidar: 3.5.3
    +      fast-glob: 3.3.2
    +      magic-string: 0.30.5
    +      vite: 4.4.12(@types/node@18.17.5)
    +    transitivePeerDependencies:
    +      - rollup
    +    dev: true
    +
       /@unocss/vite@0.58.0(rollup@2.79.1)(vite@4.5.0):
         resolution: {integrity: sha512-OCUOLMSOBEtXOEyBbAvMI3/xdR175BWRzmvV9Wc34ANZclEvCdVH8+WU725ibjY4VT0gVIuX68b13fhXdHV41A==}
         peerDependencies:
    @@ -5777,7 +5850,18 @@ packages:
         peerDependencies:
           vite-plugin-pwa: '>=0.17.0 <1'
         dependencies:
    -      vite-plugin-pwa: 0.17.0(vite@4.5.0)(workbox-build@7.0.0)(workbox-window@7.0.0)
    +      vite-plugin-pwa: 0.17.0(vite@4.4.12)(workbox-build@7.0.0)(workbox-window@7.0.0)
    +    dev: true
    +
    +  /@vitejs/plugin-vue@4.2.1(vite@4.4.12)(vue@3.3.4):
    +    resolution: {integrity: sha512-ZTZjzo7bmxTRTkb8GSTwkPOYDIP7pwuyV+RV53c9PYUouwcbkIZIvWvNWlX2b1dYZqtOv7D6iUAnJLVNGcLrSw==}
    +    engines: {node: ^14.18.0 || >=16.0.0}
    +    peerDependencies:
    +      vite: ^4.0.0
    +      vue: ^3.2.25
    +    dependencies:
    +      vite: 4.4.12(@types/node@18.17.5)
    +      vue: 3.3.4
         dev: true
     
       /@vitejs/plugin-vue@4.2.1(vite@4.5.0)(vue@3.3.4):
    @@ -5909,7 +5993,7 @@ packages:
       /@vue/compiler-core@3.3.8:
         resolution: {integrity: sha512-hN/NNBUECw8SusQvDSqqcVv6gWq8L6iAktUR0UF3vGu2OhzRqcOiAno0FmBJWwxhYEXRlQJT5XnoKsVq1WZx4g==}
         dependencies:
    -      '@babel/parser': 7.23.0
    +      '@babel/parser': 7.23.5
           '@vue/shared': 3.3.8
           estree-walker: 2.0.2
           source-map-js: 1.0.2
    @@ -5945,7 +6029,7 @@ packages:
       /@vue/compiler-sfc@3.3.8:
         resolution: {integrity: sha512-WMzbUrlTjfYF8joyT84HfwwXo+8WPALuPxhy+BZ6R4Aafls+jDBnSz8PDz60uFhuqFbl3HxRfxvDzrUf3THwpA==}
         dependencies:
    -      '@babel/parser': 7.23.0
    +      '@babel/parser': 7.23.5
           '@vue/compiler-core': 3.3.8
           '@vue/compiler-dom': 3.3.8
           '@vue/compiler-ssr': 3.3.8
    @@ -5980,7 +6064,7 @@ packages:
       /@vue/reactivity-transform@3.3.4:
         resolution: {integrity: sha512-MXgwjako4nu5WFLAjpBnCj/ieqcjE2aJBINUNQzkZQfzIZA4xn+0fV1tIYBJvvva3N3OvKGofRLvQIwEQPpaXw==}
         dependencies:
    -      '@babel/parser': 7.23.0
    +      '@babel/parser': 7.23.5
           '@vue/compiler-core': 3.3.4
           '@vue/shared': 3.3.4
           estree-walker: 2.0.2
    @@ -5989,7 +6073,7 @@ packages:
       /@vue/reactivity-transform@3.3.8:
         resolution: {integrity: sha512-49CvBzmZNtcHua0XJ7GdGifM8GOXoUMOX4dD40Y5DxI3R8OUhMlvf2nvgUAcPxaXiV5MQQ1Nwy09ADpnLQUqRw==}
         dependencies:
    -      '@babel/parser': 7.23.0
    +      '@babel/parser': 7.23.5
           '@vue/compiler-core': 3.3.8
           '@vue/shared': 3.3.8
           estree-walker: 2.0.2
    @@ -6067,7 +6151,7 @@ packages:
           '@types/web-bluetooth': 0.0.16
           '@vueuse/metadata': 10.1.0
           '@vueuse/shared': 10.1.0(vue@3.3.4)
    -      vue-demi: 0.14.5(vue@3.3.4)
    +      vue-demi: 0.14.6(vue@3.3.4)
         transitivePeerDependencies:
           - '@vue/composition-api'
           - vue
    @@ -16295,6 +16379,45 @@ packages:
         engines: {node: '>= 10.0.0'}
         dev: true
     
    +  /unocss@0.58.0(postcss@8.4.31)(rollup@2.79.1)(vite@4.4.12):
    +    resolution: {integrity: sha512-MSPRHxBqWN+1AHGV+J5uUy4//e6ZBK6O+ISzD0qrXcCD/GNtxk1+lYjOK2ltkUiKX539+/KF91vNxzhhwEf+xA==}
    +    engines: {node: '>=14'}
    +    peerDependencies:
    +      '@unocss/webpack': 0.58.0
    +      vite: ^2.9.0 || ^3.0.0-0 || ^4.0.0 || ^5.0.0-0
    +    peerDependenciesMeta:
    +      '@unocss/webpack':
    +        optional: true
    +      vite:
    +        optional: true
    +    dependencies:
    +      '@unocss/astro': 0.58.0(rollup@2.79.1)(vite@4.4.12)
    +      '@unocss/cli': 0.58.0(rollup@2.79.1)
    +      '@unocss/core': 0.58.0
    +      '@unocss/extractor-arbitrary-variants': 0.58.0
    +      '@unocss/postcss': 0.58.0(postcss@8.4.31)
    +      '@unocss/preset-attributify': 0.58.0
    +      '@unocss/preset-icons': 0.58.0
    +      '@unocss/preset-mini': 0.58.0
    +      '@unocss/preset-tagify': 0.58.0
    +      '@unocss/preset-typography': 0.58.0
    +      '@unocss/preset-uno': 0.58.0
    +      '@unocss/preset-web-fonts': 0.58.0
    +      '@unocss/preset-wind': 0.58.0
    +      '@unocss/reset': 0.58.0
    +      '@unocss/transformer-attributify-jsx': 0.58.0
    +      '@unocss/transformer-attributify-jsx-babel': 0.58.0
    +      '@unocss/transformer-compile-class': 0.58.0
    +      '@unocss/transformer-directives': 0.58.0
    +      '@unocss/transformer-variant-group': 0.58.0
    +      '@unocss/vite': 0.58.0(rollup@2.79.1)(vite@4.4.12)
    +      vite: 4.4.12(@types/node@18.17.5)
    +    transitivePeerDependencies:
    +      - postcss
    +      - rollup
    +      - supports-color
    +    dev: true
    +
       /unocss@0.58.0(postcss@8.4.31)(rollup@2.79.1)(vite@4.5.0):
         resolution: {integrity: sha512-MSPRHxBqWN+1AHGV+J5uUy4//e6ZBK6O+ISzD0qrXcCD/GNtxk1+lYjOK2ltkUiKX539+/KF91vNxzhhwEf+xA==}
         engines: {node: '>=14'}
    @@ -16353,7 +16476,7 @@ packages:
             optional: true
         dependencies:
           '@antfu/utils': 0.7.6
    -      '@rollup/pluginutils': 5.0.5(rollup@2.79.1)
    +      '@rollup/pluginutils': 5.1.0(rollup@2.79.1)
           chokidar: 3.5.3
           debug: 4.3.4(supports-color@8.1.1)
           fast-glob: 3.3.2
    @@ -16546,6 +16669,24 @@ packages:
           - supports-color
         dev: true
     
    +  /vite-plugin-pwa@0.17.0(vite@4.4.12)(workbox-build@7.0.0)(workbox-window@7.0.0):
    +    resolution: {integrity: sha512-cOyEG8EEc7JHmyMapTnjK2j0g2BIC3ErlmOHyGzVu8hqjyF9Jt6yWMmVNFtpA6v/NNyzP28ARf3vwzIAzR1kaw==}
    +    engines: {node: '>=16.0.0'}
    +    peerDependencies:
    +      vite: ^3.1.0 || ^4.0.0 || ^5.0.0
    +      workbox-build: ^7.0.0
    +      workbox-window: ^7.0.0
    +    dependencies:
    +      debug: 4.3.4(supports-color@8.1.1)
    +      fast-glob: 3.3.2
    +      pretty-bytes: 6.1.1
    +      vite: 4.4.12(@types/node@18.17.5)
    +      workbox-build: 7.0.0
    +      workbox-window: 7.0.0
    +    transitivePeerDependencies:
    +      - supports-color
    +    dev: true
    +
       /vite-plugin-pwa@0.17.0(vite@4.5.0)(workbox-build@7.0.0)(workbox-window@7.0.0):
         resolution: {integrity: sha512-cOyEG8EEc7JHmyMapTnjK2j0g2BIC3ErlmOHyGzVu8hqjyF9Jt6yWMmVNFtpA6v/NNyzP28ARf3vwzIAzR1kaw==}
         engines: {node: '>=16.0.0'}
    @@ -16905,7 +17046,6 @@ packages:
             optional: true
         dependencies:
           vue: 3.3.4
    -    dev: true
     
       /vue-demi@0.14.6(vue@3.3.8):
         resolution: {integrity: sha512-8QA7wrYSHKaYgUxDA5ZC24w+eHm3sYCbp0EzcDwKqN3p6HqtTCGR/GVsPyZW92unff4UlcSh++lmqDWN3ZIq4w==}
    
    From 01908b127897336dd81f037108795dda52d107a5 Mon Sep 17 00:00:00 2001
    From: Nikolay Rozhkov 
    Date: Mon, 11 Dec 2023 05:22:58 +0300
    Subject: [PATCH 038/217] Development Into planning
    
    ---
     packages/mermaid/src/docs/community/intro.md | 4 ++++
     1 file changed, 4 insertions(+)
    
    diff --git a/packages/mermaid/src/docs/community/intro.md b/packages/mermaid/src/docs/community/intro.md
    index 953f98e671..633282b145 100644
    --- a/packages/mermaid/src/docs/community/intro.md
    +++ b/packages/mermaid/src/docs/community/intro.md
    @@ -29,6 +29,10 @@ mindmap
     
     [Join our slack community if you want closer contact!](https://join.slack.com/t/mermaid-talk/shared_invite/enQtNzc4NDIyNzk4OTAyLWVhYjQxOTI2OTg4YmE1ZmJkY2Y4MTU3ODliYmIwOTY3NDJlYjA0YjIyZTdkMDMyZTUwOGI0NjEzYmEwODcwOTE)
     
    +## Help with testing
    +
    +## Manage tasks
    +
     ## Where do I start?
     
     * You could confirm the bugs in [these issues](https://github.com/knsv/mermaid/issues?utf8=%E2%9C%93&q=is%3Aissue+is%3Aopen+label%3A%22Type%3A+Bug+%2F+Error%22+label%3A%22Status%3A+Pending%22).
    
    From 5e1f0c620a275db71a0a97357ee1ed89f0c0b681 Mon Sep 17 00:00:00 2001
    From: Scott Blomquist 
    Date: Tue, 12 Dec 2023 12:48:07 -0800
    Subject: [PATCH 039/217] Fix typos in timeline syntax samples
    
    ---
     packages/mermaid/src/docs/syntax/timeline.md | 4 ++--
     1 file changed, 2 insertions(+), 2 deletions(-)
    
    diff --git a/packages/mermaid/src/docs/syntax/timeline.md b/packages/mermaid/src/docs/syntax/timeline.md
    index eeff9b1353..0d8f2ed912 100644
    --- a/packages/mermaid/src/docs/syntax/timeline.md
    +++ b/packages/mermaid/src/docs/syntax/timeline.md
    @@ -112,11 +112,11 @@ timeline
     timeline
             title MermaidChart 2023 Timeline
             section 2023 Q1 
    Release Personal Tier - Buttet 1 : sub-point 1a : sub-point 1b + Bullet 1 : sub-point 1a : sub-point 1b : sub-point 1c Bullet 2 : sub-point 2a : sub-point 2b section 2023 Q2
    Release XYZ Tier - Buttet 3 : sub-point
    3a : sub-point 3b + Bullet 3 : sub-point
    3a : sub-point 3b : sub-point 3c Bullet 4 : sub-point 4a : sub-point 4b ``` From 7e6fd1ebe227c8b534f361e478ccc4930b353518 Mon Sep 17 00:00:00 2001 From: William Jennings Date: Tue, 12 Dec 2023 13:53:25 -0800 Subject: [PATCH 040/217] Update pie.html demo --- demos/pie.html | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/demos/pie.html b/demos/pie.html index 3c315ab63e..76b8fdf0f9 100644 --- a/demos/pie.html +++ b/demos/pie.html @@ -15,7 +15,7 @@

    Pie chart demos

    -      pie title Pets adopted by volunteers
    +      pie title Default text position: Animal adoption
             accTitle: simple pie char demo
             accDescr: pie chart with 3 sections: dogs, cats, rats. Most are dogs.
             "Dogs": 386
    @@ -27,7 +27,7 @@ 

    Pie chart demos

           %%{init: {"pie": {"textPosition": 0.9}, "themeVariables": {"pieOuterStrokeWidth": "5px"}}}%%
           pie
    -        title Key elements in Product X
    +        title Offset labels close to border: Produxt X
             accTitle: Key elements in Product X
             accDescr: This is a pie chart showing the key elements in Product X.
             "Calcium": 42.96
    @@ -36,6 +36,19 @@ 

    Pie chart demos

    "Iron": 5
    +
    +      %%{init: {"pie": {"textPosition": 0.45}, "themeVariables": {"pieOuterStrokeWidth": "5px"}}}%%
    +      pie
    +        title Centralized labels: Languages
    +        accTitle: Key elements in Product X
    +        accDescr: This is a pie chart showing the key elements in Product X.
    +        "JavaScript": 30
    +        "Python": 25
    +        "Java": 20
    +        "C#": 15
    +        "Others": 10
    +    
    + +``` + +The tooltip text is surrounded in double quotes. The styles of the tooltip are set by the class `.mermaidTooltip`. + +```mermaid-example +block-beta + A-->B + B-->C + C-->D + click A callback "Tooltip for a callback" + click B "https://www.github.com" "This is a tooltip for a link" + click A call callback() "Tooltip for a callback" + click B href "https://www.github.com" "This is a tooltip for a link" +``` + +> **Success** The tooltip functionality and the ability to link to urls are available from version 0.5.2. + +?> Due to limitations with how Docsify handles JavaScript callback functions, an alternate working demo for the above code can be viewed at [this jsfiddle](https://jsfiddle.net/s37cjoau/3/). + +Links are opened in the same browser tab/window by default. It is possible to change this by adding a link target to the click definition (`_self`, `_blank`, `_parent` and `_top` are supported): + +```mermaid-example +block-beta + A-->B + B-->C + C-->D + D-->E + click A "https://www.github.com" _blank + click B "https://www.github.com" "Open this in a new tab" _blank + click C href "https://www.github.com" _blank + click D href "https://www.github.com" "Open this in a new tab" _blank +``` + +Beginner's tip—a full example using interactive links in a html context: + +```html + +
    +    block-beta
    +        A-->B
    +        B-->C
    +        C-->D
    +        click A callback "Tooltip"
    +        click B "https://www.github.com" "This is a link"
    +        click C call callback() "Tooltip"
    +        click D href "https://www.github.com" "This is a link"
    +  
    + + + +``` + +### Comments + +Comments can be entered within a flow diagram, which will be ignored by the parser. Comments need to be on their own line, and must be prefaced with `%%` (double percent signs). Any text after the start of the comment to the next newline will be treated as a comment, including any flow syntax + +```mermaid +block-beta +%% this is a comment A -- text --> B{block} + A -- text --> B -- text2 --> C +``` + +## Styling and classes + +### Styling links + +It is possible to style links. For instance, you might want to style a link that is going backwards in the flow. As links +have no ids in the same way as blocks, some other way of deciding what style the links should be attached to is required. +Instead of ids, the order number of when the link was defined in the graph is used, or use default to apply to all links. +In the example below the style defined in the linkStyle statement will belong to the fourth link in the graph: + +``` +linkStyle 3 stroke:#ff3,stroke-width:4px,color:red; +``` + +It is also possible to add style to multiple links in a single statement, by separating link numbers with commas: + +``` +linkStyle 1,2,7 color:blue; +``` + +### Styling line curves + +It is possible to style the type of curve used for lines between items, if the default method does not meet your needs. +Available curve styles include `basis`, `bumpX`, `bumpY`, `cardinal`, `catmullRom`, `linear`, `monotoneX`, `monotoneY`, +`natural`, `step`, `stepAfter`, and `stepBefore`. + +In this example, a left-to-right graph uses the `stepBefore` curve style: + +``` +%%{ init: { 'flowchart': { 'curve': 'stepBefore' } } }%% +graph LR +``` + +For a full list of available curves, including an explanation of custom curves, refer to +the [Shapes](https://github.com/d3/d3-shape/blob/main/README.md#curves) documentation in the +[d3-shape](https://github.com/d3/d3-shape/) project. + +### Styling a block + +It is possible to apply specific styles such as a thicker border or a different background color to a block. + +```mermaid-example +block-beta + id1(Start)-->id2(Stop) + style id1 fill:#f9f,stroke:#333,stroke-width:4px + style id2 fill:#bbf,stroke:#f66,stroke-width:2px,color:#fff,stroke-dasharray: 5 5 +``` + +#### Classes + +More convenient than defining the style every time is to define a class of styles and attach this class to the blocks that +should have a different look. + +A class definition looks like the example below: + +``` + classDef className fill:#f9f,stroke:#333,stroke-width:4px; +``` + +Also, it is possible to define style to multiple classes in one statement: + +``` + classDef firstClassName,secondClassName font-size:12pt; +``` + +Attachment of a class to a block is done as per below: + +``` + class blockId1 className; +``` + +It is also possible to attach a class to a list of blocks in one statement: + +``` + class blockId1,blockId2 className; +``` + +A shorter form of adding a class is to attach the classname to the block using the `:::`operator as per below: + +```mermaid-example +block-beta + A:::someclass --> B + classDef someclass fill:#f96 +``` + +This form can be used when declaring multiple links between blocks: + +```mermaid-example +block-beta + A:::foo & B:::bar --> C:::foobar + classDef foo stroke:#f00 + classDef bar stroke:#0f0 + classDef foobar stroke:#00f +``` + +### Css classes + +It is also possible to predefine classes in css styles that can be applied from the graph definition as in the example +below: + +**Example style** + +```html + +``` + +**Example definition** + +```mermaid-example +block-beta + A-->B[AAABBB] + B-->D + class A cssClass +``` + +### Default class + +If a class is named default it will be assigned to all classes without specific class definitions. + +``` + classDef default fill:#f9f,stroke:#333,stroke-width:4px; +``` + +## Basic support for fontawesome + +It is possible to add icons from fontawesome. + +The icons are accessed via the syntax fa:#icon class name#. + +```mermaid-example +flowchart TD + B["fab:fa-twitter for peace"] + B-->C[fa:fa-ban forbidden] + B-->D(fa:fa-spinner) + B-->E(A fa:fa-camera-retro perhaps?) +``` + +Mermaid is compatible with Font Awesome up to verion 5, Free icons only. Check that the icons you use are from the [supported set of icons](https://fontawesome.com/v5/search?o=r&m=free). + +## Graph declarations with spaces between vertices and link and without semicolon + +- In graph declarations, the statements also can now end without a semicolon. After release 0.2.16, ending a graph statement with semicolon is just optional. So the below graph declaration is also valid along with the old declarations of the graph. + +- A single space is allowed between vertices and the link. However there should not be any space between a vertex and its text and a link and its text. The old syntax of graph declaration will also work and hence this new feature is optional and is introduced to improve readability. + +Below is the new declaration of the graph edges which is also valid along with the old declaration of the graph edges. + +```mermaid-example +block-beta + A[Hard edge] -->|Link text| B(Round edge) + B --> C{Decision} + C -->|One| D[Result one] + C -->|Two| E[Result two] +``` + +## Configuration + +### Renderer + +The layout of the diagram is done with the renderer. The default renderer is dagre. + +Starting with Mermaid version 9.4, you can use an alternate renderer named elk. The elk renderer is better for larger and/or more complex diagrams. + +The _elk_ renderer is an experimenal feature. +You can change the renderer to elk by adding this directive: + +``` +%%{init: {"flowchart": {"defaultRenderer": "elk"}} }%% +``` + +```note +Note that the site needs to use mermaid version 9.4+ for this to work and have this featured enabled in the lazy-loading configuration. +``` + +### Width + +It is possible to adjust the width of the rendered flowchart. + +This is done by defining **mermaid.flowchartConfig** or by the CLI to use a JSON file with the configuration. How to use the CLI is described in the mermaidCLI page. +mermaid.flowchartConfig can be set to a JSON string with config parameters or the corresponding object. + +```javascript +mermaid.flowchartConfig = { + width: 100% +} +``` From a0d328d73465929fd98b19bda0c7b39670d7065d Mon Sep 17 00:00:00 2001 From: Knut Sveidqvist Date: Thu, 18 Jan 2024 14:28:14 +0100 Subject: [PATCH 107/217] #3358 Removed logging, fixed som tests --- cypress/platform/knsv2.html | 29 +- .../mermaid/src/dagre-wrapper/createLabel.js | 2 +- .../mermaid/src/diagrams/block/blockDB.ts | 10 +- .../src/diagrams/block/blockRenderer.ts | 2 +- .../mermaid/src/diagrams/block/layout.spec.ts | 2 +- packages/mermaid/src/diagrams/block/layout.ts | 80 +- .../src/diagrams/block/parser/block.jison | 158 ++-- .../src/diagrams/block/parser/block.spec.ts | 60 +- packages/mermaid/src/docs/syntax/block-old.md | 346 +++++++++ packages/mermaid/src/docs/syntax/block.md | 694 +++++++----------- packages/mermaid/src/mermaidAPI.ts | 2 - 11 files changed, 814 insertions(+), 571 deletions(-) create mode 100644 packages/mermaid/src/docs/syntax/block-old.md diff --git a/cypress/platform/knsv2.html b/cypress/platform/knsv2.html index 75b4418bd2..b2af1f5f9b 100644 --- a/cypress/platform/knsv2.html +++ b/cypress/platform/knsv2.html @@ -64,11 +64,24 @@
    +block-beta
    +        columns 3
    +        block1["Block 1"]
    +        blockArrow<["   "]>(right)
    +        block2["Block 2"]
    +    
    +
    +block-beta
    +columns 5
    +   A space B
    +   A --x B
    +    
    +
     block-beta
     columns 3
       a["A wide one"] b:2 c:2 d
         
    -
    +    
     block-beta
       block:e
           f
    @@ -96,7 +109,7 @@
       j
     
         
    -
    +    
     block-beta
     columns 3
       a b:2
    @@ -105,14 +118,14 @@
       end
       g h i
         
    -
    +    
     block-beta
     columns 3
       a b c
       e:3
       f g h
         
    -
    +    
     block-beta
     columns 1
       db(("DB"))
    @@ -128,14 +141,14 @@
       C --> D
       style B fill:#f9F,stroke:#333,stroke-width:4px
         
    -
    +    
     block-beta
     
       A1:3
       A2:1
       A3
         
    -
    +    
     block-beta
       block
         D
    @@ -143,7 +156,7 @@
       end
       db("This is the text in the box")
         
    -
    +    
     block-beta
     
           block
    @@ -151,7 +164,7 @@
           end
           A["A: I am a wide one"]
         
    -
    +    
     block-beta
         A["square"]
         B("rounded")
    diff --git a/packages/mermaid/src/dagre-wrapper/createLabel.js b/packages/mermaid/src/dagre-wrapper/createLabel.js
    index a8351c812f..adf5635f0e 100644
    --- a/packages/mermaid/src/dagre-wrapper/createLabel.js
    +++ b/packages/mermaid/src/dagre-wrapper/createLabel.js
    @@ -56,7 +56,7 @@ const createLabel = (_vertexText, style, isTitle, isNode) => {
       if (evaluate(getConfig().flowchart.htmlLabels)) {
         // TODO: addHtmlLabel accepts a labelStyle. Do we possibly have that?
         vertexText = vertexText.replace(/\\n|\n/g, '
    '); - log.info('vertexText' + vertexText); + log.debug('vertexText' + vertexText); const node = { isNode, label: decodeEntities(vertexText).replace( diff --git a/packages/mermaid/src/diagrams/block/blockDB.ts b/packages/mermaid/src/diagrams/block/blockDB.ts index b410c238e4..7e7bd7528f 100644 --- a/packages/mermaid/src/diagrams/block/blockDB.ts +++ b/packages/mermaid/src/diagrams/block/blockDB.ts @@ -153,7 +153,7 @@ const populateBlockDatabase = (_blockList: Block[], parent: Block): void => { if (!block.label) { if (block.type === 'composite') { block.label = ''; - console.log('abc89 composite', block); + // log.debug('abc89 composite', block); } else { block.label = block.id; } @@ -175,6 +175,7 @@ const populateBlockDatabase = (_blockList: Block[], parent: Block): void => { populateBlockDatabase(block.children, block); } if (block.type === 'space') { + // log.debug('abc95 space', block); const w = block.width || 1; for (let j = 0; j < w; j++) { const newBlock = clone(block); @@ -182,6 +183,7 @@ const populateBlockDatabase = (_blockList: Block[], parent: Block): void => { blockDatabase[newBlock.id] = newBlock; children.push(newBlock); } + // log.debug('abc95 space2', children); } else { if (newBlock) { children.push(block); @@ -205,7 +207,7 @@ const links: Link[] = []; let rootBlock = { id: 'root', type: 'composite', children: [], columns: -1 } as Block; const clear = (): void => { - log.info('Clear called'); + log.debug('Clear called'); commonClear(); rootBlock = { id: 'root', type: 'composite', children: [], columns: -1 } as Block; blockDatabase = { root: rootBlock }; @@ -290,7 +292,7 @@ const setHierarchy = (block: Block[]): void => { log.debug('The document from parsing', JSON.stringify(block, null, 2)); rootBlock.children = block; populateBlockDatabase(block, rootBlock); - log.debug('abc88 The document after popuplation', JSON.stringify(rootBlock, null, 2)); + // log.debug('abc95 The document after popuplation', JSON.stringify(rootBlock, null, 2)); blocks = rootBlock.children; }; @@ -322,7 +324,7 @@ type IGetBlocks = () => Block[]; */ const getBlocksFlat: IGetBlocks = () => { const result: Block[] = []; - console.log('abc88 getBlocksFlat', blockDatabase); + // log.debug('abc88 getBlocksFlat', blockDatabase); const keys = Object.keys(blockDatabase); for (const key of keys) { result.push(blockDatabase[key]); diff --git a/packages/mermaid/src/diagrams/block/blockRenderer.ts b/packages/mermaid/src/diagrams/block/blockRenderer.ts index 10d2f29066..8bc5275746 100644 --- a/packages/mermaid/src/diagrams/block/blockRenderer.ts +++ b/packages/mermaid/src/diagrams/block/blockRenderer.ts @@ -25,7 +25,7 @@ import { configureSvgSize } from '../../setupGraphViewbox.js'; * @returns {object} ClassDef styles */ export const getClasses = function (text: any, diagObj: any) { - log.info('Extracting classes', diagObj.db.getClasses()); + log.debug('Extracting classes', diagObj.db.getClasses()); try { return diagObj.db.getClasses(); } catch (e) { diff --git a/packages/mermaid/src/diagrams/block/layout.spec.ts b/packages/mermaid/src/diagrams/block/layout.spec.ts index 1de79c880c..6c77c8fd19 100644 --- a/packages/mermaid/src/diagrams/block/layout.spec.ts +++ b/packages/mermaid/src/diagrams/block/layout.spec.ts @@ -8,6 +8,6 @@ describe('Layout', function () { expect(calculateBlockPosition(2, 2)).toEqual({ px: 0, py: 1 }); expect(calculateBlockPosition(2, 3)).toEqual({ px: 1, py: 1 }); expect(calculateBlockPosition(2, 4)).toEqual({ px: 0, py: 2 }); - expect(calculateBlockPosition(1, 3)).toEqual({ px: 0, py: 2 }); + expect(calculateBlockPosition(1, 3)).toEqual({ px: 0, py: 3 }); }); }); diff --git a/packages/mermaid/src/diagrams/block/layout.ts b/packages/mermaid/src/diagrams/block/layout.ts index 205e03747c..e06d6ff10d 100644 --- a/packages/mermaid/src/diagrams/block/layout.ts +++ b/packages/mermaid/src/diagrams/block/layout.ts @@ -9,7 +9,7 @@ interface BlockPosition { } export function calculateBlockPosition(columns: number, position: number): BlockPosition { - console.log('calculateBlockPosition abc89', columns, position); + // log.debug('calculateBlockPosition abc89', columns, position); // Ensure that columns is a positive integer if (columns === 0 || !Number.isInteger(columns)) { throw new Error('Columns must be an integer !== 0.'); @@ -31,7 +31,7 @@ export function calculateBlockPosition(columns: number, position: number): Block // Calculate posX and posY const px = position % columns; const py = Math.floor(position / columns); - console.log('calculateBlockPosition abc89', columns, position, '=> (', px, py, ')'); + // log.debug('calculateBlockPosition abc89', columns, position, '=> (', px, py, ')'); return { px, py }; } @@ -39,10 +39,10 @@ const getMaxChildSize = (block: Block) => { let maxWidth = 0; let maxHeight = 0; // find max width of children - console.log('getMaxChildSize abc95 (start) parent:', block.id); + // log.debug('getMaxChildSize abc95 (start) parent:', block.id); for (const child of block.children) { const { width, height, x, y } = child.size || { width: 0, height: 0, x: 0, y: 0 }; - console.log( + log.debug( 'getMaxChildSize abc95 child:', child.id, 'width:', @@ -52,8 +52,12 @@ const getMaxChildSize = (block: Block) => { 'x:', x, 'y:', - y + y, + child.type ); + if (child.type === 'space') { + continue; + } if (width > maxWidth) { maxWidth = width / (block.w || 1); } @@ -70,15 +74,23 @@ function setBlockSizes( sieblingWidth: number = 0, sieblingHeight: number = 0 ) { - console.log( + log.debug( 'setBlockSizes abc95 (start)', block.id, block?.size?.x, 'block width =', - block?.size?.width, + block?.size, 'sieblingWidth', sieblingWidth ); + if (!block?.size?.width) { + block.size = { + width: sieblingWidth, + height: sieblingHeight, + x: 0, + y: 0, + }; + } const totalWidth = 0; const totalHeight = 0; let maxWidth = 0; @@ -92,31 +104,25 @@ function setBlockSizes( const childSize = getMaxChildSize(block); maxWidth = childSize.width; maxHeight = childSize.height; - console.log( - 'setBlockSizes abc95 maxWidth of', - block.id, - ':s children is ', - maxWidth, - maxHeight - ); + log.debug('setBlockSizes abc95 maxWidth of', block.id, ':s children is ', maxWidth, maxHeight); // set width of block to max width of children for (const child of block.children) { if (child.size) { - // console.log( - // 'abc95 Setting size of children of', - // block.id, - // 'id=', - // child.id, - // maxWidth, - // maxHeight, - // child.size - // ); + log.debug( + 'abc95 Setting size of children of', + block.id, + 'id=', + child.id, + maxWidth, + maxHeight, + child.size + ); child.size.width = maxWidth * child.w + padding * (child.w - 1); child.size.height = maxHeight; child.size.x = 0; child.size.y = 0; - console.log( + log.debug( 'abc95 updating size of ', block.id, ' children child:', @@ -129,9 +135,9 @@ function setBlockSizes( } } for (const child of block.children) { - // console.log('abc95 fin 2 Setting size', child.id, maxWidth, maxHeight, child.size); + // log.debug('abc95 fin 2 Setting size', child.id, maxWidth, maxHeight, child.size); setBlockSizes(child, db, maxWidth, maxHeight); - // console.log('abc95 fin 3 Setting size', child.id, maxWidth, maxHeight, child.size); + // log.debug('abc95 fin 3 Setting size', child.id, maxWidth, maxHeight, child.size); } const columns = block.columns || -1; @@ -151,7 +157,7 @@ function setBlockSizes( let height = ySize * (maxHeight + padding) + padding; // If maxWidth if (width < sieblingWidth) { - console.log( + log.debug( 'Detected to small siebling: abc95', block.id, 'sieblingWidth', @@ -180,7 +186,7 @@ function setBlockSizes( } } - console.log( + log.debug( 'abc95 (finale calc)', block.id, 'xSize', @@ -200,7 +206,7 @@ function setBlockSizes( const num = block.children.length; if (num > 0) { const childWidth = (width - num * padding - padding) / num; - // console.log('abc95 (finale calc) width', block.id, width, block.size?.width, childWidth); + // log.debug('abc95 (finale calc) width', block.id, width, block.size?.width, childWidth); for (const child of block.children) { if (child.size) { child.size.width = childWidth; @@ -216,7 +222,7 @@ function setBlockSizes( }; } - console.log( + log.debug( 'setBlockSizes abc94 (done)', block.id, block?.size?.x, @@ -228,7 +234,7 @@ function setBlockSizes( function layoutBlocks(block: Block, db: BlockDB) { log.debug( - 'abc89 layout blocks (=>layoutBlocks)', + 'abc85 layout blocks (=>layoutBlocks)', block.id, 'x:', block?.size?.x, @@ -238,7 +244,7 @@ function layoutBlocks(block: Block, db: BlockDB) { block?.size?.width ); const columns = block.columns || -1; - console.log('layoutBlocks columns abc91', block.id, '=>', columns, block); + log.debug('layoutBlocks columns abc95', block.id, '=>', columns, block); if ( block.children && // find max width of children block.children.length > 0 @@ -250,7 +256,7 @@ function layoutBlocks(block: Block, db: BlockDB) { // let first = true; let columnPos = 0; - console.log('abc91 block?.size?.x', block.id, block?.size?.x); + log.debug('abc91 block?.size?.x', block.id, block?.size?.x); let startingPosX = block?.size?.x ? block?.size?.x + (-block?.size?.width / 2 || 0) : -padding; let rowPos = 0; for (const child of block.children) { @@ -265,7 +271,7 @@ function layoutBlocks(block: Block, db: BlockDB) { rowPos = py; startingPosX = block?.size?.x || -padding; } - console.log( + log.debug( 'abc89 layout blocks (child) id:', child.id, 'Pos:', @@ -294,7 +300,7 @@ function layoutBlocks(block: Block, db: BlockDB) { const halfWidth = width / 2; child.size.x = startingPosX + padding + halfWidth; - console.log( + log.debug( 'abc91 layout blocks (calc) px, py', 'id:', child.id, @@ -323,7 +329,7 @@ function layoutBlocks(block: Block, db: BlockDB) { child.size.y = parent.size.y - parent.size.height / 2 + py * (height + padding) + height / 2 + padding; - console.log( + log.debug( 'abc88 layout blocks (calc) px, py', 'id:', child.id, @@ -347,7 +353,7 @@ function layoutBlocks(block: Block, db: BlockDB) { layoutBlocks(child, db); } columnPos += child?.w || 1; - console.log('abc88 columnsPos', child, columnPos); + log.debug('abc88 columnsPos', child, columnPos); } } log.debug( diff --git a/packages/mermaid/src/diagrams/block/parser/block.jison b/packages/mermaid/src/diagrams/block/parser/block.jison index 9020cb7617..066b7be0fc 100644 --- a/packages/mermaid/src/diagrams/block/parser/block.jison +++ b/packages/mermaid/src/diagrams/block/parser/block.jison @@ -37,24 +37,24 @@ CRLF \u000D\u000A %% "block-beta" { return 'BLOCK_DIAGRAM_KEY'; } -"block"\s+ { yy.getLogger().info('Found space-block'); return 'block';} -"block"\n+ { yy.getLogger().info('Found nl-block'); return 'block';} -"block:" { yy.getLogger().info('Found space-block'); return 'id-block';} -// \s*\%\%.* { yy.getLogger().info('Found comment',yytext); } -[\s]+ { yy.getLogger().info('.', yytext); /* skip all whitespace */ } -[\n]+ {yy.getLogger().info('_', yytext); /* skip all whitespace */ } +"block"\s+ { yy.getLogger().debug('Found space-block'); return 'block';} +"block"\n+ { yy.getLogger().debug('Found nl-block'); return 'block';} +"block:" { yy.getLogger().debug('Found space-block'); return 'id-block';} +// \s*\%\%.* { yy.getLogger().debug('Found comment',yytext); } +[\s]+ { yy.getLogger().debug('.', yytext); /* skip all whitespace */ } +[\n]+ {yy.getLogger().debug('_', yytext); /* skip all whitespace */ } // [\n] return 'NL'; ({CRLF}|{LF}) { return 'NL' } "columns"\s+"auto" { yytext=-1; return 'COLUMNS'; } -"columns"\s+[\d]+ { yytext = yytext.replace(/columns\s+/,''); yy.getLogger().info('COLUMNS (LEX)', yytext); return 'COLUMNS'; } +"columns"\s+[\d]+ { yytext = yytext.replace(/columns\s+/,''); yy.getLogger().debug('COLUMNS (LEX)', yytext); return 'COLUMNS'; } ["][`] { this.pushState("md_string");} [^`"]+ { return "MD_STR";} [`]["] { this.popState();} ["] this.pushState("string"); ["] { yy.getLogger().debug('LEX: POPPING STR:', yytext);this.popState();} [^"]* { yy.getLogger().debug('LEX: STR end:', yytext); return "STR";} -space[:]\d+ { yytext = yytext.replace(/space\:/,'');yy.getLogger().info('SPACE NUM (LEX)', yytext); return 'SPACE_BLOCK'; } -space { yytext = '1'; yy.getLogger().info('COLUMNS (LEX)', yytext); return 'SPACE_BLOCK'; } +space[:]\d+ { yytext = yytext.replace(/space\:/,'');yy.getLogger().debug('SPACE NUM (LEX)', yytext); return 'SPACE_BLOCK'; } +space { yytext = '1'; yy.getLogger().debug('COLUMNS (LEX)', yytext); return 'SPACE_BLOCK'; } "default" return 'DEFAULT'; "linkStyle" return 'LINKSTYLE'; "interpolate" return 'INTERPOLATE'; @@ -87,36 +87,36 @@ accDescr\s*"{"\s* { this.pushState("acc_descr_mul .*direction\s+LR[^\n]* return 'direction_lr'; // Node end of shape -"(((" { this.popState();yy.getLogger().info('Lex: (('); return "NODE_DEND"; } -")))" { this.popState();yy.getLogger().info('Lex: (('); return "NODE_DEND"; } -[\)]\) { this.popState();yy.getLogger().info('Lex: ))'); return "NODE_DEND"; } -"}}" { this.popState();yy.getLogger().info('Lex: (('); return "NODE_DEND"; } -"}" { this.popState();yy.getLogger().info('Lex: (('); return "NODE_DEND"; } -"(-" { this.popState();yy.getLogger().info('Lex: (-'); return "NODE_DEND"; } -"-)" { this.popState();yy.getLogger().info('Lex: -)'); return "NODE_DEND"; } -"((" { this.popState();yy.getLogger().info('Lex: (('); return "NODE_DEND"; } -"]]" { this.popState();yy.getLogger().info('Lex: ]]'); return "NODE_DEND"; } -"(" { this.popState();yy.getLogger().info('Lex: ('); return "NODE_DEND"; } -"])" { this.popState();yy.getLogger().info('Lex: ])'); return "NODE_DEND"; } -"\\]" { this.popState();yy.getLogger().info('Lex: /]'); return "NODE_DEND"; } -"/]" { this.popState();yy.getLogger().info('Lex: /]'); return "NODE_DEND"; } -")]" { this.popState();yy.getLogger().info('Lex: )]'); return "NODE_DEND"; } -[\)] { this.popState();yy.getLogger().info('Lex: )'); return "NODE_DEND"; } -\]\> { this.popState();yy.getLogger().info('Lex: ]>'); return "NODE_DEND"; } -[\]] { this.popState();yy.getLogger().info('Lex: ]'); return "NODE_DEND"; } +"(((" { this.popState();yy.getLogger().debug('Lex: (('); return "NODE_DEND"; } +")))" { this.popState();yy.getLogger().debug('Lex: (('); return "NODE_DEND"; } +[\)]\) { this.popState();yy.getLogger().debug('Lex: ))'); return "NODE_DEND"; } +"}}" { this.popState();yy.getLogger().debug('Lex: (('); return "NODE_DEND"; } +"}" { this.popState();yy.getLogger().debug('Lex: (('); return "NODE_DEND"; } +"(-" { this.popState();yy.getLogger().debug('Lex: (-'); return "NODE_DEND"; } +"-)" { this.popState();yy.getLogger().debug('Lex: -)'); return "NODE_DEND"; } +"((" { this.popState();yy.getLogger().debug('Lex: (('); return "NODE_DEND"; } +"]]" { this.popState();yy.getLogger().debug('Lex: ]]'); return "NODE_DEND"; } +"(" { this.popState();yy.getLogger().debug('Lex: ('); return "NODE_DEND"; } +"])" { this.popState();yy.getLogger().debug('Lex: ])'); return "NODE_DEND"; } +"\\]" { this.popState();yy.getLogger().debug('Lex: /]'); return "NODE_DEND"; } +"/]" { this.popState();yy.getLogger().debug('Lex: /]'); return "NODE_DEND"; } +")]" { this.popState();yy.getLogger().debug('Lex: )]'); return "NODE_DEND"; } +[\)] { this.popState();yy.getLogger().debug('Lex: )'); return "NODE_DEND"; } +\]\> { this.popState();yy.getLogger().debug('Lex: ]>'); return "NODE_DEND"; } +[\]] { this.popState();yy.getLogger().debug('Lex: ]'); return "NODE_DEND"; } // Start of nodes with shapes and description -"-)" { yy.getLogger().info('Lexa: -)'); this.pushState('NODE');return 'NODE_DSTART'; } -"(-" { yy.getLogger().info('Lexa: (-'); this.pushState('NODE');return 'NODE_DSTART'; } -"))" { yy.getLogger().info('Lexa: ))'); this.pushState('NODE');return 'NODE_DSTART'; } -")" { yy.getLogger().info('Lexa: )'); this.pushState('NODE');return 'NODE_DSTART'; } -"(((" { yy.getLogger().info('Lex: ((('); this.pushState('NODE');return 'NODE_DSTART'; } -"((" { yy.getLogger().info('Lexa: )'); this.pushState('NODE');return 'NODE_DSTART'; } -"{{" { yy.getLogger().info('Lexa: )'); this.pushState('NODE');return 'NODE_DSTART'; } -"{" { yy.getLogger().info('Lexa: )'); this.pushState('NODE');return 'NODE_DSTART'; } -">" { yy.getLogger().info('Lexc: >'); this.pushState('NODE');return 'NODE_DSTART'; } -"([" { yy.getLogger().info('Lexa: (['); this.pushState('NODE');return 'NODE_DSTART'; } -"(" { yy.getLogger().info('Lexa: )'); this.pushState('NODE');return 'NODE_DSTART'; } +"-)" { yy.getLogger().debug('Lexa: -)'); this.pushState('NODE');return 'NODE_DSTART'; } +"(-" { yy.getLogger().debug('Lexa: (-'); this.pushState('NODE');return 'NODE_DSTART'; } +"))" { yy.getLogger().debug('Lexa: ))'); this.pushState('NODE');return 'NODE_DSTART'; } +")" { yy.getLogger().debug('Lexa: )'); this.pushState('NODE');return 'NODE_DSTART'; } +"(((" { yy.getLogger().debug('Lex: ((('); this.pushState('NODE');return 'NODE_DSTART'; } +"((" { yy.getLogger().debug('Lexa: )'); this.pushState('NODE');return 'NODE_DSTART'; } +"{{" { yy.getLogger().debug('Lexa: )'); this.pushState('NODE');return 'NODE_DSTART'; } +"{" { yy.getLogger().debug('Lexa: )'); this.pushState('NODE');return 'NODE_DSTART'; } +">" { yy.getLogger().debug('Lexc: >'); this.pushState('NODE');return 'NODE_DSTART'; } +"([" { yy.getLogger().debug('Lexa: (['); this.pushState('NODE');return 'NODE_DSTART'; } +"(" { yy.getLogger().debug('Lexa: )'); this.pushState('NODE');return 'NODE_DSTART'; } "[[" { this.pushState('NODE');return 'NODE_DSTART'; } "[|" { this.pushState('NODE');return 'NODE_DSTART'; } "[(" { this.pushState('NODE');return 'NODE_DSTART'; } @@ -124,20 +124,20 @@ accDescr\s*"{"\s* { this.pushState("acc_descr_mul "[\\" { this.pushState('NODE');return 'NODE_DSTART'; } "[/" { this.pushState('NODE');return 'NODE_DSTART'; } "[\\" { this.pushState('NODE');return 'NODE_DSTART'; } -"[" { yy.getLogger().info('Lexa: ['); this.pushState('NODE');return 'NODE_DSTART'; } +"[" { yy.getLogger().debug('Lexa: ['); this.pushState('NODE');return 'NODE_DSTART'; } "<[" { this.pushState('BLOCK_ARROW');yy.getLogger().debug('LEX ARR START');return 'BLOCK_ARROW_START'; } -[^\(\[\n\-\)\{\}\s\<\>:]+ { yy.getLogger().info('Lex: NODE_ID', yytext);return 'NODE_ID'; } -<> { yy.getLogger().info('Lex: EOF', yytext);return 'EOF'; } +[^\(\[\n\-\)\{\}\s\<\>:]+ { yy.getLogger().debug('Lex: NODE_ID', yytext);return 'NODE_ID'; } +<> { yy.getLogger().debug('Lex: EOF', yytext);return 'EOF'; } // Handling of strings in node ["][`] { this.pushState("md_string");} ["][`] { this.pushState("md_string");} [^`"]+ { return "NODE_DESCR";} [`]["] { this.popState();} -["] { yy.getLogger().info('Lex: Starting string');this.pushState("string");} -["] { yy.getLogger().info('LEX ARR: Starting string');this.pushState("string");} +["] { yy.getLogger().debug('Lex: Starting string');this.pushState("string");} +["] { yy.getLogger().debug('LEX ARR: Starting string');this.pushState("string");} [^"]+ { yy.getLogger().debug('LEX: NODE_DESCR:', yytext); return "NODE_DESCR";} ["] {yy.getLogger().debug('LEX POPPING');this.popState();} @@ -151,19 +151,19 @@ accDescr\s*"{"\s* { this.pushState("acc_descr_mul ")"\s* { yytext=']>';yy.getLogger().debug('Lex (ARROW_DIR end):',yytext);this.popState();this.popState();return "BLOCK_ARROW_END"; } // Edges -\s*[xo<]?\-\-+[-xo>]\s* { yy.getLogger().info('Lex: LINK', '#'+yytext+'#'); return 'LINK'; } -\s*[xo<]?\=\=+[=xo>]\s* { yy.getLogger().info('Lex: LINK', yytext); return 'LINK'; } -\s*[xo<]?\-?\.+\-[xo>]?\s* { yy.getLogger().info('Lex: LINK', yytext); return 'LINK'; } -\s*\~\~[\~]+\s* { yy.getLogger().info('Lex: LINK', yytext); return 'LINK'; } -\s*[xo<]?\-\-\s* { yy.getLogger().info('Lex: START_LINK', yytext);this.pushState("LLABEL");return 'START_LINK'; } -\s*[xo<]?\=\=\s* { yy.getLogger().info('Lex: START_LINK', yytext);this.pushState("LLABEL");return 'START_LINK'; } -\s*[xo<]?\-\.\s* { yy.getLogger().info('Lex: START_LINK', yytext);this.pushState("LLABEL");return 'START_LINK'; } +\s*[xo<]?\-\-+[-xo>]\s* { yy.getLogger().debug('Lex: LINK', '#'+yytext+'#'); return 'LINK'; } +\s*[xo<]?\=\=+[=xo>]\s* { yy.getLogger().debug('Lex: LINK', yytext); return 'LINK'; } +\s*[xo<]?\-?\.+\-[xo>]?\s* { yy.getLogger().debug('Lex: LINK', yytext); return 'LINK'; } +\s*\~\~[\~]+\s* { yy.getLogger().debug('Lex: LINK', yytext); return 'LINK'; } +\s*[xo<]?\-\-\s* { yy.getLogger().debug('Lex: START_LINK', yytext);this.pushState("LLABEL");return 'START_LINK'; } +\s*[xo<]?\=\=\s* { yy.getLogger().debug('Lex: START_LINK', yytext);this.pushState("LLABEL");return 'START_LINK'; } +\s*[xo<]?\-\.\s* { yy.getLogger().debug('Lex: START_LINK', yytext);this.pushState("LLABEL");return 'START_LINK'; } ["][`] { this.pushState("md_string");} -["] { yy.getLogger().info('Lex: Starting string');this.pushState("string"); return "LINK_LABEL";} -\s*[xo<]?\-\-+[-xo>]\s* { this.popState(); yy.getLogger().info('Lex: LINK', '#'+yytext+'#'); return 'LINK'; } -\s*[xo<]?\=\=+[=xo>]\s* { this.popState(); yy.getLogger().info('Lex: LINK', yytext); return 'LINK'; } -\s*[xo<]?\-?\.+\-[xo>]?\s* { this.popState(); yy.getLogger().info('Lex: LINK', yytext); return 'LINK'; } -':'\d+ { yy.getLogger().info('Lex: COLON', yytext); yytext=yytext.slice(1);return 'SIZE'; } +["] { yy.getLogger().debug('Lex: Starting string');this.pushState("string"); return "LINK_LABEL";} +\s*[xo<]?\-\-+[-xo>]\s* { this.popState(); yy.getLogger().debug('Lex: LINK', '#'+yytext+'#'); return 'LINK'; } +\s*[xo<]?\=\=+[=xo>]\s* { this.popState(); yy.getLogger().debug('Lex: LINK', yytext); return 'LINK'; } +\s*[xo<]?\-?\.+\-[xo>]?\s* { this.popState(); yy.getLogger().debug('Lex: LINK', yytext); return 'LINK'; } +':'\d+ { yy.getLogger().debug('Lex: COLON', yytext); yytext=yytext.slice(1);return 'SIZE'; } /lex @@ -180,37 +180,37 @@ spaceLines seperator : NL - {yy.getLogger().info('Rule: seperator (NL) ');} + {yy.getLogger().debug('Rule: seperator (NL) ');} | SPACE - {yy.getLogger().info('Rule: seperator (Space) ');} + {yy.getLogger().debug('Rule: seperator (Space) ');} | EOF - {yy.getLogger().info('Rule: seperator (EOF) ');} + {yy.getLogger().debug('Rule: seperator (EOF) ');} ; start: BLOCK_DIAGRAM_KEY document EOF - { yy.getLogger().info("Rule: hierarchy: ", $2); yy.setHierarchy($2); } + { yy.getLogger().debug("Rule: hierarchy: ", $2); yy.setHierarchy($2); } ; stop - : NL {yy.getLogger().info('Stop NL ');} - | EOF {yy.getLogger().info('Stop EOF ');} + : NL {yy.getLogger().debug('Stop NL ');} + | EOF {yy.getLogger().debug('Stop EOF ');} // | SPACELINE - | stop NL {yy.getLogger().info('Stop NL2 ');} - | stop EOF {yy.getLogger().info('Stop EOF2 ');} + | stop NL {yy.getLogger().debug('Stop NL2 ');} + | stop EOF {yy.getLogger().debug('Stop EOF2 ');} ; //array of statements document - : statement { yy.getLogger().info("Rule: statement: ", $1); typeof $1.length === 'number'?$$ = $1:$$ = [$1]; } - | statement document { yy.getLogger().info("Rule: statement #2: ", $1); $$ = [$1].concat($2); } + : statement { yy.getLogger().debug("Rule: statement: ", $1); typeof $1.length === 'number'?$$ = $1:$$ = [$1]; } + | statement document { yy.getLogger().debug("Rule: statement #2: ", $1); $$ = [$1].concat($2); } ; link : LINK - { yy.getLogger().info("Rule: link: ", $1, yytext); $$={edgeTypeStr: $1, label:''}; } + { yy.getLogger().debug("Rule: link: ", $1, yytext); $$={edgeTypeStr: $1, label:''}; } | START_LINK LINK_LABEL STR LINK - { yy.getLogger().info("Rule: LABEL link: ", $1, $3, $4); $$={edgeTypeStr: $4, label:$3}; } + { yy.getLogger().debug("Rule: LABEL link: ", $1, $3, $4); $$={edgeTypeStr: $4, label:$3}; } ; statement @@ -226,7 +226,7 @@ statement nodeStatement : nodeStatement link node { - yy.getLogger().info('Rule: (nodeStatement link node) ', $1, $2, $3, ' typestr: ',$2.edgeTypeStr); + yy.getLogger().debug('Rule: (nodeStatement link node) ', $1, $2, $3, ' typestr: ',$2.edgeTypeStr); const edgeData = yy.edgeStrToEdgeData($2.edgeTypeStr) $$ = [ {id: $1.id, label: $1.label, type:$1.type, directions: $1.directions}, @@ -234,39 +234,39 @@ nodeStatement {id: $3.id, label: $3.label, type: yy.typeStr2Type($3.typeStr), directions: $3.directions} ]; } - | node SIZE { yy.getLogger().info('Rule: nodeStatement (abc88 node size) ', $1, $2); $$ = {id: $1.id, label: $1.label, type: yy.typeStr2Type($1.typeStr), directions: $1.directions, w: parseInt($2,10)}; } - | node { yy.getLogger().info('Rule: nodeStatement (node) ', $1); $$ = {id: $1.id, label: $1.label, type: yy.typeStr2Type($1.typeStr), directions: $1.directions, w:1}; } + | node SIZE { yy.getLogger().debug('Rule: nodeStatement (abc88 node size) ', $1, $2); $$ = {id: $1.id, label: $1.label, type: yy.typeStr2Type($1.typeStr), directions: $1.directions, w: parseInt($2,10)}; } + | node { yy.getLogger().debug('Rule: nodeStatement (node) ', $1); $$ = {id: $1.id, label: $1.label, type: yy.typeStr2Type($1.typeStr), directions: $1.directions, w:1}; } ; columnsStatement - : COLUMNS { yy.getLogger().info('APA123', this? this:'na'); yy.getLogger().info("COLUMNS: ", $1); $$ = {type: 'column-setting', columns: $1 === 'auto'?-1:parseInt($1) } } + : COLUMNS { yy.getLogger().debug('APA123', this? this:'na'); yy.getLogger().debug("COLUMNS: ", $1); $$ = {type: 'column-setting', columns: $1 === 'auto'?-1:parseInt($1) } } ; blockStatement - : id-block nodeStatement document end { yy.getLogger().info('Rule: id-block statement : ', $2, $3); const id2 = yy.generateId(); $$ = { ...$2, type:'composite', children: $3 }; } - | block document end { yy.getLogger().info('Rule: blockStatement : ', $1, $2, $3); const id = yy.generateId(); $$ = { id, type:'composite', label:'', children: $2 }; } + : id-block nodeStatement document end { yy.getLogger().debug('Rule: id-block statement : ', $2, $3); const id2 = yy.generateId(); $$ = { ...$2, type:'composite', children: $3 }; } + | block document end { yy.getLogger().debug('Rule: blockStatement : ', $1, $2, $3); const id = yy.generateId(); $$ = { id, type:'composite', label:'', children: $2 }; } ; node : NODE_ID - { yy.getLogger().info("Rule: node (NODE_ID seperator): ", $1); $$ = { id: $1 }; } + { yy.getLogger().debug("Rule: node (NODE_ID seperator): ", $1); $$ = { id: $1 }; } | NODE_ID nodeShapeNLabel { - yy.getLogger().info("Rule: node (NODE_ID nodeShapeNLabel seperator): ", $1, $2); + yy.getLogger().debug("Rule: node (NODE_ID nodeShapeNLabel seperator): ", $1, $2); $$ = { id: $1, label: $2.label, typeStr: $2.typeStr, directions: $2.directions }; } ; -dirList: DIR { yy.getLogger().info("Rule: dirList: ", $1); $$ = [$1]; } - | DIR dirList { yy.getLogger().info("Rule: dirList: ", $1, $2); $$ = [$1].concat($2); } +dirList: DIR { yy.getLogger().debug("Rule: dirList: ", $1); $$ = [$1]; } + | DIR dirList { yy.getLogger().debug("Rule: dirList: ", $1, $2); $$ = [$1].concat($2); } ; nodeShapeNLabel : NODE_DSTART STR NODE_DEND - { yy.getLogger().info("Rule: nodeShapeNLabel: ", $1, $2, $3); $$ = { typeStr: $1 + $3, label: $2 }; } + { yy.getLogger().debug("Rule: nodeShapeNLabel: ", $1, $2, $3); $$ = { typeStr: $1 + $3, label: $2 }; } | BLOCK_ARROW_START STR dirList BLOCK_ARROW_END - { yy.getLogger().info("Rule: BLOCK_ARROW nodeShapeNLabel: ", $1, $2, " #3:",$3, $4); $$ = { typeStr: $1 + $4, label: $2, directions: $3}; } + { yy.getLogger().debug("Rule: BLOCK_ARROW nodeShapeNLabel: ", $1, $2, " #3:",$3, $4); $$ = { typeStr: $1 + $4, label: $2, directions: $3}; } ; @@ -281,7 +281,7 @@ classDefStatement cssClassStatement : class CLASSENTITY_IDS STYLECLASS { - //console.log('apply class: id(s): ',$2, ' style class: ', $3); + //log.debug('apply class: id(s): ',$2, ' style class: ', $3); $$={ type: 'applyClass', id: $2.trim(), styleClass: $3.trim() }; } ; diff --git a/packages/mermaid/src/diagrams/block/parser/block.spec.ts b/packages/mermaid/src/diagrams/block/parser/block.spec.ts index bf32afc5e6..367edb8426 100644 --- a/packages/mermaid/src/diagrams/block/parser/block.spec.ts +++ b/packages/mermaid/src/diagrams/block/parser/block.spec.ts @@ -47,10 +47,10 @@ describe('Block diagram', function () { expect(blocks.length).toBe(2); expect(blocks[0].id).toBe('id1'); expect(blocks[0].label).toBe('id1'); - expect(blocks[0].type).toBe('square'); + expect(blocks[0].type).toBe('na'); expect(blocks[1].id).toBe('id2'); expect(blocks[1].label).toBe('id2'); - expect(blocks[1].type).toBe('square'); + expect(blocks[1].type).toBe('na'); }); it('a diagram with multiple nodes', async () => { const str = `block-beta @@ -64,13 +64,13 @@ describe('Block diagram', function () { expect(blocks.length).toBe(3); expect(blocks[0].id).toBe('id1'); expect(blocks[0].label).toBe('id1'); - expect(blocks[0].type).toBe('square'); + expect(blocks[0].type).toBe('na'); expect(blocks[1].id).toBe('id2'); expect(blocks[1].label).toBe('id2'); - expect(blocks[1].type).toBe('square'); + expect(blocks[1].type).toBe('na'); expect(blocks[2].id).toBe('id3'); expect(blocks[2].label).toBe('id3'); - expect(blocks[2].type).toBe('square'); + expect(blocks[2].type).toBe('na'); }); it('a node with a square shape and a label', async () => { @@ -86,7 +86,7 @@ describe('Block diagram', function () { expect(blocks[0].type).toBe('square'); expect(blocks[1].id).toBe('id2'); expect(blocks[1].label).toBe('id2'); - expect(blocks[1].type).toBe('square'); + expect(blocks[1].type).toBe('na'); }); it('a diagram with multiple nodes with edges', async () => { const str = `block-beta @@ -231,14 +231,14 @@ describe('Block diagram', function () { expect(compoundBlock.children.length).toBe(1); expect(compoundBlock.id).toBe('compoundBlock'); expect(compoundBlock.label).toBe('Compound block'); - expect(compoundBlock.type).toBe('square'); + expect(compoundBlock.type).toBe('composite'); expect(block2.id).toBe('block2'); expect(block2.label).toBe('Block 2'); expect(block2.type).toBe('square'); }); - it.skip('blocks mixed with compound blocks', async () => { - const str = `block + it('blocks mixed with compound blocks', async () => { + const str = `block-beta columns 1 block1["Block 1"] @@ -250,16 +250,43 @@ describe('Block diagram', function () { `; block.parse(str); + + const blocks = db.getBlocks(); + expect(blocks.length).toBe(2); + + const compoundBlock = blocks[1]; + const block2 = compoundBlock.children[0]; + + expect(compoundBlock.children.length).toBe(2); + + expect(block2.id).toBe('block2'); + expect(block2.label).toBe('Block 2'); + expect(block2.type).toBe('square'); }); - it.skip('Arrow blocks', async () => { - const str = `block + it('Arrow blocks', async () => { + const str = `block-beta columns 3 block1["Block 1"] - blockArrow + blockArrow<["   "]>(right) block2["Block 2"]`; block.parse(str); + + const blocks = db.getBlocks(); + expect(blocks.length).toBe(3); + + const block1 = blocks[0]; + const blockArrow = blocks[1]; + const block2 = blocks[2]; + + expect(block1.id).toBe('block1'); + expect(blockArrow.id).toBe('blockArrow'); + expect(block2.id).toBe('block2'); + expect(block2.label).toBe('Block 2'); + expect(block2.type).toBe('square'); + expect(blockArrow.type).toBe('block_arrow'); + console.log('blockArrow', blockArrow); }); it.skip('Arrow blocks with multiple points', async () => { const str = `block-beta @@ -275,7 +302,7 @@ describe('Block diagram', function () { block.parse(str); }); - it.skip('blocks with different widths', async () => { + it('blocks with different widths', async () => { const str = `block-beta columns 3 one["One Slot"] @@ -283,6 +310,13 @@ describe('Block diagram', function () { `; block.parse(str); + + const blocks = db.getBlocks(); + expect(blocks.length).toBe(2); + const one = blocks[0]; + const two = blocks[1]; + console.log('Obe and Two', one, two); + expect(two.w).toBe(2); }); it('empty blocks', async () => { const str = `block-beta diff --git a/packages/mermaid/src/docs/syntax/block-old.md b/packages/mermaid/src/docs/syntax/block-old.md new file mode 100644 index 0000000000..d2fd0b717a --- /dev/null +++ b/packages/mermaid/src/docs/syntax/block-old.md @@ -0,0 +1,346 @@ +--- +title: Block Diagram Syntax +outline: 'deep' # shows all h3 headings in outline in Vitepress +--- + +# Block Diagrams - Basic Syntax + +Block diagrams are a fundamental tool in technical and engineering documentation, offering a straightforward way to represent complex systems and processes. + +A block diagram, at its core, is a graphical representation of a system that uses blocks to depict different components or functions and arrows to show the relationship or flow between them. This form of diagram is invaluable in simplifying the understanding of large-scale systems, breaking them down into individual, easily digestible components. + +With block diagrams you can create clear, concise, and visually appealing representations of systems. This is particularly beneficial for technical teams and stakeholders who need to document, analyze, or communicate complex processes without getting entangled in the intricacies of detailed schematics. Whether it's for software architecture, network systems, or process management, Mermaid's block diagrams offer an accessible and efficient way to visualize and convey crucial information. + +```warning +If you are using the word "end" in a Flowchart block, capitalize the entire word or any of the letters (e.g., "End" or "END"), or apply this [workaround](https://github.com/mermaid-js/mermaid/issues/1444#issuecomment-639528897). Typing "end" in all lowercase letters will break the Flowchart. +``` + +### A block (default) + +```mermaid-example +--- +title: Block +--- +block-beta + id +``` + +```note +The id is what is displayed in the box. +``` + +### A block with text + +It is also possible to set text in the box that differs from the id. If this is done several times, it is the last text +found for the block that will be used. Also if you define edges for the block later on, you can omit text definitions. The +one previously defined will be used when rendering the box. + +```mermaid-example +--- +title: Node with text +--- +block-beta + id1[This is the text in the box] +``` + +#### Unicode text + +Use `"` to enclose the unicode text. + +```mermaid-example +block-beta + id["This ❤ Unicode"] +``` + +#### Markdown formatting + +Use double quotes and backticks "\` text \`" to enclose the markdown text. + +```mermaid-example +%%{init: {"flowchart": {"htmlLabels": false}} }%% +block-beta + markdown["`This **is** _Markdown_`"] + newLines["`Line1 + Line 2 + Line 3`"] + markdown --> newLines +``` + +## Block shapes + +### A block with round edges + +```mermaid-example +block-beta + id1(This is the text in the box) +``` + +### A stadium-shaped block + +```mermaid-example +block-beta + id1([This is the text in the box]) +``` + +### A block in a subroutine shape + +```mermaid-example +block-beta + id1[[This is the text in the box]] +``` + +### A block in a cylindrical shape + +```mermaid-example +block-beta + id1[(Database)] +``` + +### A block in the form of a circle + +```mermaid-example +block-beta + id1((This is the text in the circle)) +``` + +### A block in an asymmetric shape + +```mermaid-example +block-beta + id1>This is the text in the box] +``` + +### A block (rhombus) + +```mermaid-example +block-beta + id1{This is the text in the box} +``` + +### A hexagon block + +```mermaid-example +block-beta + id1{{This is the text in the box}} +``` + +### Parallelogram + +```mermaid-example +flowchart TD + id1[/This is the text in the box/] +``` + +### Parallelogram alt + +```mermaid-example +flowchart TD + id1[\This is the text in the box\] +``` + +### Trapezoid + +```mermaid-example +flowchart TD + A[/Christmas\] +``` + +### Trapezoid alt + +```mermaid-example +flowchart TD + B[\Go shopping/] +``` + +### Double circle + +```mermaid-example +flowchart TD + id1(((This is the text in the circle))) +``` + +## Links between blocks + +Blocks can be connected with links/edges. It is possible to have different types of links or attach a text string to a link. + +### A link with arrow head + +```mermaid-example +block-beta + A-->B +``` + +### An open link + +```mermaid-example +block-beta + A --- B +``` + +### Text on links + +```mermaid-example +block-beta + A-- This is the text! ---B +``` + +or + +```mermaid-example +block-beta + A---|This is the text|B +``` + +### A link with arrow head and text + +```mermaid-example +block-beta + A-->|text|B +``` + +or + +```mermaid-example +block-beta + A-- text -->B +``` + +### Dotted link + +```mermaid-example +block-beta + A-.->B; +``` + +### Dotted link with text + +```mermaid-example +block-beta + A-. text .-> B +``` + +### Thick link + +```mermaid-example +block-beta + A ==> B +``` + +### Thick link with text + +```mermaid-example +block-beta + A == text ==> B +``` + +### Different types of links + +There are new types of arrows supported as per below: + +```mermaid-example +block-beta + A --o B + B --x C +``` + +### Multi directional arrows + +There is the possibility to use multidirectional arrows. + +```mermaid-example +block-beta + A o--o B + B <--> C + C x--x D +``` + +## Special characters that break syntax + +It is possible to put text within quotes in order to render more troublesome characters. As in the example below: + +```mermaid-example +block-beta + id1["This is the (text) in the box"] +``` + +### Entity codes to escape characters + +It is possible to escape characters using the syntax exemplified here. + +```mermaid-example + block-beta + A["A double quote:#quot;"] -->B["A dec char:#9829;"] +``` + +Numbers given are base 10, so `#` can be encoded as `#35;`. It is also supported to use HTML character names. + +## Blocks in blocks + +``` +block-beta + block definition +end +``` + +An example below: + +```mermaid-example +block-beta + block + A["square"] + B("rounded") + end + C(("circle")) +``` + +### Comments + +Comments can be entered within a flow diagram, which will be ignored by the parser. Comments need to be on their own line, and must be prefaced with `%%` (double percent signs). Any text after the start of the comment to the next newline will be treated as a comment, including any flow syntax + +```mermaid +block-beta +%% this is a comment A -- text --> B{block} + A -- text --> B -- text2 --> C +``` + +## Styling and classes + +### Styling a block + +It is possible to apply specific styles such as a thicker border or a different background color to a block. + +```mermaid-example +block-beta + id1(Start)-->id2(Stop) + style id1 fill:#f9f,stroke:#333,stroke-width:4px + style id2 fill:#bbf,stroke:#f66,stroke-width:2px,color:#fff,stroke-dasharray: 5 5 +``` + +#### Classes + +More convenient than defining the style every time is to define a class of styles and attach this class to the blocks that +should have a different look. + +A class definition looks like the example below: + +``` + classDef className fill:#f9f,stroke:#333,stroke-width:4px; +``` + +Also, it is possible to define style to multiple classes in one statement: + +``` + classDef firstClassName,secondClassName font-size:12pt; +``` + +Attachment of a class to a block is done as per below: + +``` + class blockId1 className; +``` + +It is also possible to attach a class to a list of blocks in one statement: + +``` + class blockId1,blockId2 className; +``` diff --git a/packages/mermaid/src/docs/syntax/block.md b/packages/mermaid/src/docs/syntax/block.md index 20dc1c6c99..b1067d5b36 100644 --- a/packages/mermaid/src/docs/syntax/block.md +++ b/packages/mermaid/src/docs/syntax/block.md @@ -3,657 +3,501 @@ title: Block Diagram Syntax outline: 'deep' # shows all h3 headings in outline in Vitepress --- -# Block Diagrams - Basic Syntax +# Block Diagrams Documentation -Block diagrams are a fundamental tool in technical and engineering documentation, offering a straightforward way to represent complex systems and processes. +## 1. Introduction to Block Diagrams -A block diagram, at its core, is a graphical representation of a system that uses blocks to depict different components or functions and arrows to show the relationship or flow between them. This form of diagram is invaluable in simplifying the understanding of large-scale systems, breaking them down into individual, easily digestible components. +### Definition and Purpose -With block diagrams you can create clear, concise, and visually appealing representations of systems. This is particularly beneficial for technical teams and stakeholders who need to document, analyze, or communicate complex processes without getting entangled in the intricacies of detailed schematics. Whether it's for software architecture, network systems, or process management, Mermaid's block diagrams offer an accessible and efficient way to visualize and convey crucial information. +Block diagrams are an intuitive and efficient way to represent complex systems, processes, or architectures visually. They are composed of blocks and connectors, where blocks represent the fundamental components or functions, and connectors show the relationship or flow between these components. This method of diagramming is essential in various fields such as engineering, software development, and process management. -```warning -If you are using the word "end" in a Flowchart block, capitalize the entire word or any of the letters (e.g., "End" or "END"), or apply this [workaround](https://github.com/mermaid-js/mermaid/issues/1444#issuecomment-639528897). Typing "end" in all lowercase letters will break the Flowchart. -``` +The primary purpose of block diagrams is to provide a high-level view of a system, allowing for easy understanding and analysis without delving into the intricate details of each component. This makes them particularly useful for simplifying complex systems and for explaining the overall structure and interaction of components within a system. -### A block (default) +### General Use Cases -```mermaid-example ---- -title: Block ---- -block-beta - id -``` +Block diagrams have a wide range of applications across various industries and disciplines. Some of the key use cases include: -```note -The id is what is displayed in the box. -``` +- **Software Architecture**: In software development, block diagrams can be used to illustrate the architecture of a software application. This includes showing how different modules or services interact, data flow, and high-level component interaction. -### A block with text +- **Network Diagrams**: Block diagrams are ideal for representing network architectures in IT and telecommunications. They can depict how different network devices and services are interconnected, including routers, switches, firewalls, and the flow of data across the network. -It is also possible to set text in the box that differs from the id. If this is done several times, it is the last text -found for the block that will be used. Also if you define edges for the block later on, you can omit text definitions. The -one previously defined will be used when rendering the box. +- **Process Flowcharts**: In business and manufacturing, block diagrams can be employed to create process flowcharts. These flowcharts represent various stages of a business or manufacturing process, helping to visualize the sequence of steps, decision points, and the flow of control. -```mermaid-example ---- -title: Node with text ---- -block-beta - id1[This is the text in the box] -``` +- **Electrical Systems**: Engineers use block diagrams to represent electrical systems and circuitry. They can illustrate the high-level structure of an electrical system, the interaction between different electrical components, and the flow of electrical currents. -#### Unicode text +- **Educational Purposes**: Block diagrams are also extensively used in educational materials to explain complex concepts and systems in a simplified manner. They help in breaking down and visualizing scientific theories, engineering principles, and technological systems. -Use `"` to enclose the unicode text. +These examples demonstrate the versatility of block diagrams in providing clear and concise representations of complex systems. Their simplicity and clarity make them a valuable tool for professionals across various fields to communicate complex ideas effectively. -```mermaid-example -block-beta - id["This ❤ Unicode"] -``` +In the following sections, we will delve into the specifics of creating and manipulating block diagrams using Mermaid, covering everything from basic syntax to advanced configurations and styling. -#### Markdown formatting +Creating block diagrams with Mermaid is straightforward and accessible. This section introduces the basic syntax and structure needed to start building simple diagrams. Understanding these foundational concepts is key to efficiently utilizing Mermaid for more complex diagramming tasks. -Use double quotes and backticks "\` text \`" to enclose the markdown text. +### Simple Block Diagrams -```mermaid-example -%%{init: {"flowchart": {"htmlLabels": false}} }%% -block-beta - markdown["`This **is** _Markdown_`"] - newLines["`Line1 - Line 2 - Line 3`"] - markdown --> newLines -``` +#### Basic Structure -## Block shapes +At its core, a block diagram consists of blocks representing different entities or components. In Mermaid, these blocks are easily created using simple text labels. The most basic form of a block diagram can be a series of blocks without any connectors. -### A block with round edges +**Example - Simple Block Diagram**: +To create a simple block diagram with three blocks labeled 'a', 'b', and 'c', the syntax is as follows: ```mermaid-example block-beta - id1(This is the text in the box) + a b c ``` -### A stadium-shaped block +This example will produce a horizontal sequence of three blocks. Each block is automatically spaced and aligned for optimal readability. -```mermaid-example -block-beta - id1([This is the text in the box]) -``` +### Diagrams with Multiple Columns -### A block in a subroutine shape +#### Column Usage -```mermaid-example -block-beta - id1[[This is the text in the box]] -``` +While simple block diagrams are linear and straightforward, more complex systems may require a structured layout. Mermaid allows for the organization of blocks into multiple columns, facilitating the creation of more intricate and detailed diagrams. -### A block in a cylindrical shape +**Example - Multi-Column Diagram:** +In scenarios where you need to distribute blocks across multiple columns, you can specify the number of columns and arrange the blocks accordingly. Here's how to create a block diagram with three columns and four blocks, where the fourth block appears in a second row: ```mermaid-example block-beta - id1[(Database)] + columns 3 + a b c d ``` -### A block in the form of a circle +This syntax instructs Mermaid to arrange the blocks 'a', 'b', 'c', and 'd' across three columns, wrapping to the next row as needed. This feature is particularly useful for representing layered or multi-tiered systems, such as network layers or hierarchical structures. -```mermaid-example -block-beta - id1((This is the text in the circle)) -``` +These basic building blocks of Mermaid's block diagrams provide a foundation for more complex diagramming. The simplicity of the syntax allows for quick creation and iteration of diagrams, making it an efficient tool for visualizing ideas and concepts. In the next section, we'll explore advanced block configuration options, including setting block widths and creating composite blocks. -### A block in an asymmetric shape +## 3. Advanced Block Configuration -```mermaid-example -block-beta - id1>This is the text in the box] -``` +Building upon the basics, this section delves into more advanced features of block diagramming in Mermaid. These features allow for greater flexibility and complexity in diagram design, accommodating a wider range of use cases and scenarios. -### A block (rhombus) +### Setting Block Width -```mermaid-example -block-beta - id1{This is the text in the box} -``` +#### Spanning Multiple Columns + +In more complex diagrams, you may need blocks that span multiple columns to emphasize certain components or to represent larger entities. Mermaid allows for the adjustment of block widths to cover multiple columns, enhancing the diagram's readability and structure. -### A hexagon block +**Example - Block Spanning Multiple Columns**: +To create a block diagram where one block spans across two columns, you can specify the desired width for each block: ```mermaid-example block-beta - id1{{This is the text in the box}} + columns 3 + a["A wide one"] b:2 c:2 d ``` -### Parallelogram +In this example, the block labeled "A wide one" spans two columns, while blocks 'b', 'c', and 'd' are allocated their own columns. This flexibility in block sizing is crucial for accurately representing systems with components of varying significance or size. -```mermaid-example -flowchart TD - id1[/This is the text in the box/] -``` +### Creating Composite Blocks -### Parallelogram alt +#### Nested Blocks -```mermaid-example -flowchart TD - id1[\This is the text in the box\] -``` +Composite blocks, or blocks within blocks, are an advanced feature in Mermaid's block diagram syntax. They allow for the representation of nested or hierarchical systems, where one component encompasses several subcomponents. -### Trapezoid +**Example - Composite Blocks:** +Creating a composite block involves defining a parent block and then nesting other blocks within it. Here's how to define a composite block with nested elements: ```mermaid-example -flowchart TD - A[/Christmas\] +block-beta + block + D + end + A["A: I am a wide one"] ``` -### Trapezoid alt +In this syntax, 'D' is a nested block within a larger parent block. This feature is particularly useful for depicting complex structures, such as a server with multiple services or a department within a larger organizational framework. -```mermaid-example -flowchart TD - B[\Go shopping/] -``` +### Column Width Dynamics -### Double circle +#### Adjusting Widths + +Mermaid also allows for dynamic adjustment of column widths based on the content of the blocks. The width of the columns is determined by the widest block in the column, ensuring that the diagram remains balanced and readable. + +**Example - Dynamic Column Widths:** +In diagrams with varying block sizes, Mermaid automatically adjusts the column widths to fit the largest block in each column. Here's an example: ```mermaid-example -flowchart TD - id1(((This is the text in the circle))) +block-beta +columns 3 +a:3 +block:e:3 +f +end +g ``` -## Links between blocks +This example demonstrates how Mermaid dynamically adjusts the width of the columns to accommodate the widest block, in this case, 'a' and the composite block 'e'. This dynamic adjustment is essential for creating visually balanced and easy-to-understand diagrams. -Blocks can be connected with links/edges. It is possible to have different types of links or attach a text string to a link. +With these advanced configuration options, Mermaid's block diagrams can be tailored to represent a wide array of complex systems and structures. The flexibility offered by these features enables users to create diagrams that are both informative and visually appealing. In the following sections, we will explore further capabilities, including different block shapes and linking options. -### A link with arrow head +## 4. Block Varieties and Shapes -```mermaid-example -block-beta - A-->B -``` +Mermaid's block diagrams are not limited to standard rectangular shapes. A variety of block shapes are available, allowing for a more nuanced and tailored representation of different types of information or entities. This section outlines the different block shapes you can use in Mermaid and their specific applications. -### An open link +### Standard and Special Block Shapes -```mermaid-example -block-beta - A --- B -``` +Mermaid supports a range of block shapes to suit different diagramming needs, from basic geometric shapes to more specialized forms. + +#### Example - Round Edged Block -### Text on links +To create a block with round edges, which can be used to represent a softer or more flexible component: ```mermaid-example block-beta - A-- This is the text! ---B + id1(This is the text in the box) ``` -or +#### Example - Stadium-Shaped Block + +A stadium-shaped block, resembling an elongated circle, can be used for components that are process-oriented: ```mermaid-example block-beta - A---|This is the text|B + id1([This is the text in the box]) ``` -### A link with arrow head and text +#### Example - Subroutine Shape + +For representing subroutines or contained processes, a block with double vertical lines is useful: ```mermaid-example block-beta - A-->|text|B + id1[[This is the text in the box]] ``` -or +#### Example - Cylindrical Shape + +The cylindrical shape is ideal for representing databases or storage components: ```mermaid-example block-beta - A-- text -->B + id1[(Database)] ``` -### Dotted link +#### Example - Circle Shape + +A circle can be used for centralized or pivotal components: ```mermaid-example block-beta - A-.->B; + id1((This is the text in the circle)) ``` -### Dotted link with text +#### Example - Asymmetric, Rhombus, and Hexagon Shapes + +For decision points, use a rhombus, and for unique or specialized processes, asymmetric and hexagon shapes can be utilized: + +**Asymmetric** ```mermaid-example block-beta - A-. text .-> B + id1>This is the text in the box] ``` -### Thick link +**Rhombus** ```mermaid-example block-beta - A ==> B + id1{This is the text in the box} ``` -### Thick link with text +**Hexagon** ```mermaid-example block-beta - A == text ==> B + id1{{This is the text in the box}} ``` -### Different types of links +#### Example - Parallelogram and Trapezoid Shapes -There are new types of arrows supported as per below: +Parallelogram and trapezoid shapes are perfect for inputs/outputs and transitional processes: ```mermaid-example -block-beta - A --o B - B --x C +flowchart TD + id1[/This is the text in the box/] + id2[\This is the text in the box\] + A[/Christmas\] + B[\Go shopping/] ``` -### Multi directional arrows +#### Example - Double Circle -There is the possibility to use multidirectional arrows. +For highlighting critical or high-priority components, a double circle can be effective: ```mermaid-example -block-beta - A o--o B - B <--> C - C x--x D +flowchart TD + id1(((This is the text in the circle))) ``` -## Special characters that break syntax +### Block Arrows and Space Blocks + +Mermaid also offers unique shapes like block arrows and space blocks for directional flow and spacing. -It is possible to put text within quotes in order to render more troublesome characters. As in the example below: +#### Example - Block Arrows + +Block arrows can visually indicate direction or flow within a process: ```mermaid-example block-beta - id1["This is the (text) in the box"] + blockArrowId<["Label"]>(right) + blockArrowId2<["Label"]>(left) + blockArrowId3<["Label"]>(up) + blockArrowId4<["Label"]>(down) + blockArrowId5<["Label"]>(x) + blockArrowId6<["Label"]>(y) + blockArrowId6<["Label"]>(x, down) ``` -### Entity codes to escape characters +#### Example - Space Blocks -It is possible to escape characters using the syntax exemplified here. +Space blocks can be used to create intentional empty spaces in the diagram, which is useful for layout and readability: ```mermaid-example - block-beta - A["A double quote:#quot;"] -->B["A dec char:#9829;"] +block-beta + space:3 + ida idb idc ``` -Numbers given are base 10, so `#` can be encoded as `#35;`. It is also supported to use HTML character names. +Note that you can set how many columns the spece block occupied using the number notaion `space:num` where num is a number indicating the num columns width. You can alsio use `space` which defaults to one column. -## Blocks in blocks +The variety of shapes and special blocks in Mermaid enhances the expressive power of block diagrams, allowing for more accurate and context-specific representations. These options give users the flexibility to create diagrams that are both informative and visually appealing. In the next sections, we will explore the ways to connect these blocks and customize their appearance. -``` -block-beta - block definition -end -``` +### Standard and Special Block Shapes -An example below: +Discuss the various shapes available for blocks, including standard shapes and special forms like block arrows and space blocks. -```mermaid-example -block-beta - block - A["square"] - B("rounded") - end - C(("circle")) -``` +## 5. Connecting Blocks with Edges -You can also set an explicit id for the subgraph. +One of the key features of block diagrams in Mermaid is the ability to connect blocks using various types of edges or links. This section explores the different ways blocks can be interconnected to represent relationships and flows between components. -```mermaid-example -flowchart TB - c1-->a2 - subgraph ide1 [one] - a1-->a2 - end -``` +### Basic Linking and Arrow Types -### flowcharts +The most fundamental aspect of connecting blocks is the use of arrows or links. These connectors depict the relationships or the flow of information between the blocks. Mermaid offers a range of arrow types to suit different diagramming needs. -With the graphtype flowchart it is also possible to set edges to and from subgraphs as in the flowchart below. +**Example - Basic Links** + +A simple link with an arrow can be created to show direction or flow from one block to another: ```mermaid-example -flowchart TB - c1-->a2 - subgraph one - a1-->a2 - end - subgraph two - b1-->b2 - end - subgraph three - c1-->c2 - end - one --> two - three --> two - two --> c2 +block-beta + A-->B ``` -### Direction in subgraphs +This example illustrates a direct connection from block 'A' to block 'B', using a straightforward arrow. -With the graphtype flowcharts you can use the direction statement to set the direction which the subgraph will render like in this example. +**Example - Open Link:** +For connections that are less direct or to represent a different type of relationship, an open link (without an arrowhead) can be used: ```mermaid-example block-beta - subgraph TOP - direction TB - subgraph B1 - direction RL - i1 -->f1 - end - subgraph B2 - direction BT - i2 -->f2 - end - end - A --> TOP --> B - B1 --> B2 + A --- B ``` -## Markdown Strings +This syntax creates a line connecting 'A' and 'B', implying a relationship or connection without indicating a specific direction. -The "Markdown Strings" feature enhances flowcharts and mind maps by offering a more versatile string type, which supports text formatting options such as bold and italics, and automatically wraps text within labels. +### Text on Links + +In addition to connecting blocks, it's often necessary to describe or label the relationship. Mermaid allows for the inclusion of text on links, providing context to the connections. + +Example - Text with Links +To add text to a link, the syntax includes the text within the link definition: ```mermaid-example -%%{init: {"flowchart": {"htmlLabels": false}} }%% block-beta -subgraph "One" - a("`The **cat** - in the hat`") -- "edge label" --> b{{"`The **dog** in the hog`"}} -end -subgraph "`**Two**`" - c("`The **cat** - in the hat`") -- "`Bold **edge label**`" --> d("The dog in the hog") -end + A-- This is the text! ---B ``` -Formatting: - -- For bold text, use double asterisks (`**`) before and after the text. -- For italics, use single asterisks (`*`) before and after the text. -- With traditional strings, you needed to add `
    ` tags for text to wrap in blocks. However, markdown strings automatically wrap text when it becomes too long and allows you to start a new line by simply using a newline character instead of a `
    ` tag. +This example show how to add descriptive text to the links, enhancing the information conveyed by the diagram. -This feature is applicable to block labels, edge labels, and subgraph labels. +### Advanced Link Types -## Interaction +Mermaid also supports various advanced link types, such as dotted lines, thick links, and different arrowheads, to represent different kinds of relationships or interactions. -It is possible to bind a click event to a block, the click can lead to either a javascript callback or to a link which will be opened in a new browser tab. +**Example - Dotted and Thick Links** +A dotted link can be used to represent a weaker or less formal relationship: -```note -This functionality is disabled when using `securityLevel='strict'` and enabled when using `securityLevel='loose'`. -``` - -``` -click blockId callback -click blockId call callback() +```mermaid-example +block-beta + A-.->B ``` -- blockId is the id of the block -- callback is the name of a javascript function defined on the page displaying the graph, the function will be called with the blockId as parameter. - -Examples of tooltip usage below: +For a more pronounced connection, a thick link can be used: -```html - +```mermaid-example +block-beta + A==>B ``` -The tooltip text is surrounded in double quotes. The styles of the tooltip are set by the class `.mermaidTooltip`. +Example - Edges and Styles: ```mermaid-example block-beta - A-->B - B-->C - C-->D - click A callback "Tooltip for a callback" - click B "https://www.github.com" "This is a tooltip for a link" - click A call callback() "Tooltip for a callback" - click B href "https://www.github.com" "This is a tooltip for a link" +columns 1 + db(("DB")) + blockArrowId6<["   "]>(down) + block:ID + A + B["A wide one in the middle"] + C + end + space + D + ID --> D + C --> D + style B fill:#f9F,stroke:#333,stroke-width:4px ``` -> **Success** The tooltip functionality and the ability to link to urls are available from version 0.5.2. +## 6. Styling and Customization -?> Due to limitations with how Docsify handles JavaScript callback functions, an alternate working demo for the above code can be viewed at [this jsfiddle](https://jsfiddle.net/s37cjoau/3/). +Beyond the structure and layout of block diagrams, Mermaid offers extensive styling options. These customization features allow for the creation of more visually distinctive and informative diagrams. This section covers how to apply individual styles to blocks and how to use classes for consistent styling across multiple elements. -Links are opened in the same browser tab/window by default. It is possible to change this by adding a link target to the click definition (`_self`, `_blank`, `_parent` and `_top` are supported): +### Individual Block Styling -```mermaid-example -block-beta - A-->B - B-->C - C-->D - D-->E - click A "https://www.github.com" _blank - click B "https://www.github.com" "Open this in a new tab" _blank - click C href "https://www.github.com" _blank - click D href "https://www.github.com" "Open this in a new tab" _blank -``` - -Beginner's tip—a full example using interactive links in a html context: - -```html - -
    -    block-beta
    -        A-->B
    -        B-->C
    -        C-->D
    -        click A callback "Tooltip"
    -        click B "https://www.github.com" "This is a link"
    -        click C call callback() "Tooltip"
    -        click D href "https://www.github.com" "This is a link"
    -  
    - - - -``` - -### Comments - -Comments can be entered within a flow diagram, which will be ignored by the parser. Comments need to be on their own line, and must be prefaced with `%%` (double percent signs). Any text after the start of the comment to the next newline will be treated as a comment, including any flow syntax +Mermaid enables detailed styling of individual blocks, allowing you to apply various CSS properties such as color, stroke, and border thickness. This feature is especially useful for highlighting specific parts of a diagram or for adhering to certain visual themes. -```mermaid +#### Example - Styling a Single Block + +To apply custom styles to a block, you can use the `style` keyword followed by the block identifier and the desired CSS properties: + +```mermaid-example block-beta -%% this is a comment A -- text --> B{block} - A -- text --> B -- text2 --> C + id1(Start)-->id2(Stop) + style id1 fill:#f9f,stroke:#333,stroke-width:4px + style id2 fill:#bbf,stroke:#f66,stroke-width:2px,color:#fff,stroke-dasharray: 5 5 ``` -## Styling and classes - -### Styling links +In this example, a class named 'blue' is defined and applied to block 'A', while block 'B' receives individual styling. This demonstrates the flexibility of Mermaid in applying both shared and unique styles within the same diagram. -It is possible to style links. For instance, you might want to style a link that is going backwards in the flow. As links -have no ids in the same way as blocks, some other way of deciding what style the links should be attached to is required. -Instead of ids, the order number of when the link was defined in the graph is used, or use default to apply to all links. -In the example below the style defined in the linkStyle statement will belong to the fourth link in the graph: +The ability to style blocks individually or through classes provides a powerful tool for enhancing the visual impact and clarity of block diagrams. Whether emphasizing certain elements or maintaining a cohesive design across the diagram, these styling capabilities are central to effective diagramming. The next sections will present practical examples and use cases, followed by tips for troubleshooting common issues. -``` -linkStyle 3 stroke:#ff3,stroke-width:4px,color:red; -``` +### 7. Practical Examples and Use Cases -It is also possible to add style to multiple links in a single statement, by separating link numbers with commas: +The versatility of Mermaid's block diagrams becomes evident when applied to real-world scenarios. This section provides practical examples demonstrating the application of various features discussed in previous sections. These examples showcase how block diagrams can be used to represent complex systems and processes in an accessible and informative manner. -``` -linkStyle 1,2,7 color:blue; -``` +### Detailed Examples Illustrating Various Features -### Styling line curves +Combining the elements of structure, linking, and styling, we can create comprehensive diagrams that serve specific purposes in different contexts. -It is possible to style the type of curve used for lines between items, if the default method does not meet your needs. -Available curve styles include `basis`, `bumpX`, `bumpY`, `cardinal`, `catmullRom`, `linear`, `monotoneX`, `monotoneY`, -`natural`, `step`, `stepAfter`, and `stepBefore`. +#### Example - System Architecture -In this example, a left-to-right graph uses the `stepBefore` curve style: +Illustrating a simple software system architecture with interconnected components: -``` -%%{ init: { 'flowchart': { 'curve': 'stepBefore' } } }%% -graph LR +```mermaid +block-beta + columns 2 + Frontend Backend + Frontend-->Backend + Database[(Database)] + Backend-->Database + class Frontend,Backend fill:#f96,stroke:#333; + class Database fill:#9f9,stroke:#333; ``` -For a full list of available curves, including an explanation of custom curves, refer to -the [Shapes](https://github.com/d3/d3-shape/blob/main/README.md#curves) documentation in the -[d3-shape](https://github.com/d3/d3-shape/) project. +This example shows a basic architecture with a frontend, backend, and database. The blocks are styled to differentiate between types of components. -### Styling a block +#### Example - Business Process Flow -It is possible to apply specific styles such as a thicker border or a different background color to a block. +Representing a business process flow with decision points and multiple stages: ```mermaid-example block-beta - id1(Start)-->id2(Stop) - style id1 fill:#f9f,stroke:#333,stroke-width:4px - style id2 fill:#bbf,stroke:#f66,stroke-width:2px,color:#fff,stroke-dasharray: 5 5 + Start{Start} + Decision{Make Decision} + Process1[Process A] + Process2[Process B] + End((End)) + Start --> Decision + Decision -- Yes --> Process1 + Decision -- No --> Process2 + Process1 --> End + Process2 --> End + style Start fill:#f9f; + style End fill:#bbf; + ``` -#### Classes +This diagram depicts a simple decision-making process with two possible paths leading to an endpoint, demonstrating the use of different shapes and directional arrows. -More convenient than defining the style every time is to define a class of styles and attach this class to the blocks that -should have a different look. +### Real works Application Scenarios -A class definition looks like the example below: +Block diagrams can be employed in a variety of real-world scenarios. Here are a few examples: -``` - classDef className fill:#f9f,stroke:#333,stroke-width:4px; -``` +- **IT Network Layouts**: Visualize the structure of IT networks, showing how different devices and services are connected. +- **Educational Diagrams**: Explain complex scientific concepts, engineering systems, or historical timelines. +- **Organizational Charts**: Represent the hierarchy and relationships within an organization or department. -Also, it is possible to define style to multiple classes in one statement: +These practical examples and scenarios underscore the utility of Mermaid block diagrams in simplifying and effectively communicating complex information across various domains. -``` - classDef firstClassName,secondClassName font-size:12pt; -``` +The next section, 'Troubleshooting and Common Issues', will provide insights into resolving common challenges encountered when working with Mermaid block diagrams, ensuring a smooth diagramming experience. -Attachment of a class to a block is done as per below: +```mermaid-example -``` - class blockId1 className; ``` -It is also possible to attach a class to a list of blocks in one statement: +```mermaid-example -``` - class blockId1,blockId2 className; ``` -A shorter form of adding a class is to attach the classname to the block using the `:::`operator as per below: +## 8. Troubleshooting and Common Issues -```mermaid-example -block-beta - A:::someclass --> B - classDef someclass fill:#f96 -``` +Working with Mermaid block diagrams can sometimes present challenges, especially as the complexity of the diagrams increases. This section aims to provide guidance on resolving common issues and offers tips for managing more intricate diagram structures. -This form can be used when declaring multiple links between blocks: +### Common Syntax Errors -```mermaid-example -block-beta - A:::foo & B:::bar --> C:::foobar - classDef foo stroke:#f00 - classDef bar stroke:#0f0 - classDef foobar stroke:#00f -``` +Understanding and avoiding common syntax errors is key to a smooth experience with Mermaid diagrams. -### Css classes +#### Example - Incorrect Linking -It is also possible to predefine classes in css styles that can be applied from the graph definition as in the example -below: +A common mistake is incorrect linking syntax, which can lead to unexpected results or broken diagrams: -**Example style** - -```html - ``` - -**Example definition** - -```mermaid-example block-beta - A-->B[AAABBB] - B-->D - class A cssClass + A - B ``` -### Default class - -If a class is named default it will be assigned to all classes without specific class definitions. +**Correction**: +Ensure that links between blocks are correctly specified with arrows (--> or ---) to define the direction and type of connection: +```mermaid-example +block-beta + A --> B ``` - classDef default fill:#f9f,stroke:#333,stroke-width:4px; -``` - -## Basic support for fontawesome -It is possible to add icons from fontawesome. +#### Example - Misplaced Styling -The icons are accessed via the syntax fa:#icon class name#. +Applying styles in the wrong context or with incorrect syntax can lead to blocks not being styled as intended: ```mermaid-example -flowchart TD - B["fab:fa-twitter for peace"] - B-->C[fa:fa-ban forbidden] - B-->D(fa:fa-spinner) - B-->E(A fa:fa-camera-retro perhaps?) + block-beta + A + style A fill#f9f; ``` -Mermaid is compatible with Font Awesome up to verion 5, Free icons only. Check that the icons you use are from the [supported set of icons](https://fontawesome.com/v5/search?o=r&m=free). - -## Graph declarations with spaces between vertices and link and without semicolon - -- In graph declarations, the statements also can now end without a semicolon. After release 0.2.16, ending a graph statement with semicolon is just optional. So the below graph declaration is also valid along with the old declarations of the graph. - -- A single space is allowed between vertices and the link. However there should not be any space between a vertex and its text and a link and its text. The old syntax of graph declaration will also work and hence this new feature is optional and is introduced to improve readability. - -Below is the new declaration of the graph edges which is also valid along with the old declaration of the graph edges. +**Correction:** +Correct the syntax by ensuring proper separation of style properties with commas and using the correct CSS property format: ```mermaid-example block-beta - A[Hard edge] -->|Link text| B(Round edge) - B --> C{Decision} - C -->|One| D[Result one] - C -->|Two| E[Result two] -``` - -## Configuration + A + style A fill:#f9f,stroke:#333; -### Renderer +``` -The layout of the diagram is done with the renderer. The default renderer is dagre. +### Tips for Complex Diagram Structures -Starting with Mermaid version 9.4, you can use an alternate renderer named elk. The elk renderer is better for larger and/or more complex diagrams. +Managing complexity in Mermaid diagrams involves planning and employing best practices. -The _elk_ renderer is an experimenal feature. -You can change the renderer to elk by adding this directive: +#### Modular Design -``` -%%{init: {"flowchart": {"defaultRenderer": "elk"}} }%% -``` +Break down complex diagrams into smaller, more manageable components. This approach not only makes the diagram easier to understand but also simplifies the creation and maintenance process. -```note -Note that the site needs to use mermaid version 9.4+ for this to work and have this featured enabled in the lazy-loading configuration. -``` +#### Consistent Styling -### Width +Use classes to maintain consistent styling across similar elements. This not only saves time but also ensures a cohesive and professional appearance. -It is possible to adjust the width of the rendered flowchart. +#### Comments and Documentation -This is done by defining **mermaid.flowchartConfig** or by the CLI to use a JSON file with the configuration. How to use the CLI is described in the mermaidCLI page. -mermaid.flowchartConfig can be set to a JSON string with config parameters or the corresponding object. +Use comments within the Mermaid syntax to document the purpose of various parts of the diagram. This practice is invaluable for maintaining clarity, especially when working in teams or returning to a diagram after some time. -```javascript -mermaid.flowchartConfig = { - width: 100% -} -``` +With these troubleshooting tips and best practices, you can effectively manage and resolve common issues in Mermaid block diagrams. The final section, 'Conclusion', will summarize the key points covered in this documentation and invite user feedback for continuous improvement. diff --git a/packages/mermaid/src/mermaidAPI.ts b/packages/mermaid/src/mermaidAPI.ts index aa5c1edeb9..a4686be573 100644 --- a/packages/mermaid/src/mermaidAPI.ts +++ b/packages/mermaid/src/mermaidAPI.ts @@ -204,8 +204,6 @@ export const createCssStyles = ( cssStyles += `\n:root { --mermaid-alt-font-family: ${config.altFontFamily}}`; } - console.log('expr check', !isEmpty(classDefs), classDefs); - // classDefs defined in the diagram text if (!isEmpty(classDefs) && CLASSDEF_DIAGRAMS.includes(graphType)) { const htmlLabels = config.htmlLabels || config.flowchart?.htmlLabels; // TODO why specifically check the Flowchart diagram config? From 1230da7fc79e27476c5dd403a786ea86e79b5ab4 Mon Sep 17 00:00:00 2001 From: Knut Sveidqvist Date: Thu, 18 Jan 2024 15:31:14 +0100 Subject: [PATCH 108/217] #3358 Some cleanup --- cypress/integration/rendering/block.spec.ts | 60 ++++++++- cypress/platform/knsv2.html | 9 +- .../mermaid/src/diagrams/block/blockDB.ts | 9 +- .../mermaid/src/diagrams/block/blockTypes.ts | 1 + .../src/diagrams/block/parser/block.jison | 2 +- .../src/diagrams/block/parser/block.spec.ts | 115 ++++++++++++------ .../src/diagrams/block/renderHelpers.ts | 9 +- packages/mermaid/src/utils.ts | 1 + 8 files changed, 149 insertions(+), 57 deletions(-) diff --git a/cypress/integration/rendering/block.spec.ts b/cypress/integration/rendering/block.spec.ts index 7856f534d7..51d78444fc 100644 --- a/cypress/integration/rendering/block.spec.ts +++ b/cypress/integration/rendering/block.spec.ts @@ -313,7 +313,7 @@ describe('Block diagram', () => { ); }); - it('BL23: sizing - it should be possieble to make a composite block wider', () => { + it('BL23: sizing - it should be possible to make a composite block wider', () => { imgSnapshotTest( `block-beta block:2 @@ -325,13 +325,61 @@ describe('Block diagram', () => { ); }); - it('BL23: sizing - it should be possieble to make a composite block wider', () => { + it('BL24: block in the middle with space on each side', () => { imgSnapshotTest( `block-beta - block:2 - A - end - B + columns 3 + space + middle["In the middle"] + space + `, + {} + ); + }); + it('BL25: space and an edge', () => { + imgSnapshotTest( + `block-beta + columns 5 + A space B + A --x B + `, + {} + ); + }); + it('BL26: block sizes for regular blocks', () => { + imgSnapshotTest( + `block-beta + columns 3 + a["A wide one"] b:2 c:2 d + `, + {} + ); + }); + it('BL27: composite block with a set width - f should use the available space', () => { + imgSnapshotTest( + `block-beta + columns 3 + a:3 + block:e:3 + f + end + g + `, + {} + ); + }); + it('BL23: composite block with a set width - f and g should split the available space', () => { + imgSnapshotTest( + `block-beta + columns 3 + a:3 + block:e:3 + f + g + end + h + i + j `, {} ); diff --git a/cypress/platform/knsv2.html b/cypress/platform/knsv2.html index b2af1f5f9b..67776fe1bd 100644 --- a/cypress/platform/knsv2.html +++ b/cypress/platform/knsv2.html @@ -65,10 +65,9 @@
     block-beta
    -        columns 3
    -        block1["Block 1"]
    -        blockArrow<["   "]>(right)
    -        block2["Block 2"]
    +columns 1
    +    B["A wide one in the middle"]
    +  style B fill:#f9F,stroke:#333,stroke-width:4px
         
     block-beta
    @@ -96,7 +95,7 @@
       end
       g
         
    -
    +    
     block-beta
       columns 3
       a:3
    diff --git a/packages/mermaid/src/diagrams/block/blockDB.ts b/packages/mermaid/src/diagrams/block/blockDB.ts
    index 7e7bd7528f..34d2b5d10b 100644
    --- a/packages/mermaid/src/diagrams/block/blockDB.ts
    +++ b/packages/mermaid/src/diagrams/block/blockDB.ts
    @@ -136,8 +136,11 @@ const populateBlockDatabase = (_blockList: Block[], parent: Block): void => {
           continue;
         }
         if (block.type === 'applyStyles') {
    -      addStyle2Node(block.id, block?.styles);
    -      continue;
    +      console.log('applyStyles', block.stylesStr);
    +      if (block?.stylesStr) {
    +        addStyle2Node(block.id, block?.stylesStr);
    +        continue;
    +      }
         }
         if (block.type === 'column-setting') {
           parent.columns = block.columns || -1;
    @@ -289,7 +292,7 @@ export const generateId = () => {
     
     type ISetHierarchy = (block: Block[]) => void;
     const setHierarchy = (block: Block[]): void => {
    -  log.debug('The document from parsing', JSON.stringify(block, null, 2));
    +  console.log('The document from parsing', JSON.stringify(block, null, 2));
       rootBlock.children = block;
       populateBlockDatabase(block, rootBlock);
       // log.debug('abc95 The document after popuplation', JSON.stringify(rootBlock, null, 2));
    diff --git a/packages/mermaid/src/diagrams/block/blockTypes.ts b/packages/mermaid/src/diagrams/block/blockTypes.ts
    index d2fd8d1222..7bbba93b86 100644
    --- a/packages/mermaid/src/diagrams/block/blockTypes.ts
    +++ b/packages/mermaid/src/diagrams/block/blockTypes.ts
    @@ -59,6 +59,7 @@ export interface Block {
       css?: string;
       styleClass?: string;
       styles?: string[];
    +  stylesStr?: string;
       w?: number;
     }
     
    diff --git a/packages/mermaid/src/diagrams/block/parser/block.jison b/packages/mermaid/src/diagrams/block/parser/block.jison
    index 066b7be0fc..751f8381be 100644
    --- a/packages/mermaid/src/diagrams/block/parser/block.jison
    +++ b/packages/mermaid/src/diagrams/block/parser/block.jison
    @@ -288,7 +288,7 @@ cssClassStatement
     
     styleStatement
         : style STYLE_ENTITY_IDS STYLE_DEFINITION_DATA {
    -        $$={ type: 'applyStyles', id: $2.trim(), styles: $3.trim() };
    +        $$={ type: 'applyStyles', id: $2.trim(), stylesStr: $3.trim() };
             }
         ;
     
    diff --git a/packages/mermaid/src/diagrams/block/parser/block.spec.ts b/packages/mermaid/src/diagrams/block/parser/block.spec.ts
    index 367edb8426..3028a6c3ca 100644
    --- a/packages/mermaid/src/diagrams/block/parser/block.spec.ts
    +++ b/packages/mermaid/src/diagrams/block/parser/block.spec.ts
    @@ -4,6 +4,7 @@ import db from '../blockDB.js';
     import { cleanupComments } from '../../../diagram-api/comments.js';
     import { prepareTextForParsing } from '../blockUtils.js';
     import { setConfig } from '../../../config.js';
    +import getStyles from '../../../../dist/diagrams/pie/styles';
     
     describe('Block diagram', function () {
       describe('when parsing an block diagram graph it should handle > ', function () {
    @@ -88,12 +89,34 @@ describe('Block diagram', function () {
           expect(blocks[1].label).toBe('id2');
           expect(blocks[1].type).toBe('na');
         });
    -    it('a diagram with multiple nodes with edges', async () => {
    +    it('a diagram with multiple nodes with edges abc123', async () => {
           const str = `block-beta
               id1["first"]  -->   id2["second"]
           `;
     
           block.parse(str);
    +      const blocks = db.getBlocks();
    +      const edges = db.getEdges();
    +      expect(blocks.length).toBe(2);
    +      expect(edges.length).toBe(1);
    +      expect(edges[0].start).toBe('id1');
    +      expect(edges[0].end).toBe('id2');
    +      expect(edges[0].arrowTypeEnd).toBe('arrow_point');
    +    });
    +    it('a diagram with multiple nodes with edges abc123', async () => {
    +      const str = `block-beta
    +          id1["first"]  -- "a label" -->   id2["second"]
    +      `;
    +
    +      block.parse(str);
    +      const blocks = db.getBlocks();
    +      const edges = db.getEdges();
    +      expect(blocks.length).toBe(2);
    +      expect(edges.length).toBe(1);
    +      expect(edges[0].start).toBe('id1');
    +      expect(edges[0].end).toBe('id2');
    +      expect(edges[0].arrowTypeEnd).toBe('arrow_point');
    +      expect(edges[0].label).toBe('a label');
         });
         it('a diagram with column statements', async () => {
           const str = `block-beta
    @@ -103,7 +126,8 @@ describe('Block diagram', function () {
     
           block.parse(str);
           expect(db.getColumns('root')).toBe(2);
    -      // Todo: DB check that the we have one block and that the root block has one column
    +      const blocks = db.getBlocks();
    +      expect(blocks.length).toBe(1);
         });
         it('a diagram withput column statements', async () => {
           const str = `block-beta
    @@ -112,7 +136,8 @@ describe('Block diagram', function () {
     
           block.parse(str);
           expect(db.getColumns('root')).toBe(-1);
    -      // Todo: DB check that the we have one block and that the root block has one column
    +      const blocks = db.getBlocks();
    +      expect(blocks.length).toBe(1);
         });
         it('a diagram with auto column statements', async () => {
           const str = `block-beta
    @@ -122,7 +147,8 @@ describe('Block diagram', function () {
     
           block.parse(str);
           expect(db.getColumns('root')).toBe(-1);
    -      // Todo: DB check that the we have one block and that the root block has one column
    +      const blocks = db.getBlocks();
    +      expect(blocks.length).toBe(1);
         });
     
         it('blocks next to each other', async () => {
    @@ -134,7 +160,9 @@ describe('Block diagram', function () {
     
           block.parse(str);
     
    -      // Todo: DB check that the we have two blocks and that the root block has two columns
    +      const blocks = db.getBlocks();
    +      expect(db.getColumns('root')).toBe(2);
    +      expect(blocks.length).toBe(2);
         });
     
         it('blocks on top of each other', async () => {
    @@ -146,7 +174,9 @@ describe('Block diagram', function () {
     
           block.parse(str);
     
    -      // Todo: DB check that the we have two blocks and that the root block has one column
    +      const blocks = db.getBlocks();
    +      expect(db.getColumns('root')).toBe(1);
    +      expect(blocks.length).toBe(2);
         });
     
         it('compound blocks 2', async () => {
    @@ -287,12 +317,13 @@ describe('Block diagram', function () {
           expect(block2.type).toBe('square');
           expect(blockArrow.type).toBe('block_arrow');
           console.log('blockArrow', blockArrow);
    +      expect(blockArrow.directions).toContain('right');
         });
    -    it.skip('Arrow blocks with multiple points', async () => {
    +    it('Arrow blocks with multiple points', async () => {
           const str = `block-beta
             columns 1
             A
    -        blockArrow(1,3)
    +        blockArrow<["   "]>(up, down)
             block
               columns 3
                 B
    @@ -301,6 +332,16 @@ describe('Block diagram', function () {
             end`;
     
           block.parse(str);
    +
    +      const blocks = db.getBlocks();
    +      expect(blocks.length).toBe(3);
    +
    +      const blockArrow = blocks[1];
    +      expect(blockArrow.type).toBe('block_arrow');
    +      console.log('blockArrow', blockArrow);
    +      expect(blockArrow.directions).toContain('up');
    +      expect(blockArrow.directions).toContain('down');
    +      expect(blockArrow.directions).not.toContain('right');
         });
         it('blocks with different widths', async () => {
           const str = `block-beta
    @@ -315,7 +356,7 @@ describe('Block diagram', function () {
           expect(blocks.length).toBe(2);
           const one = blocks[0];
           const two = blocks[1];
    -      console.log('Obe and Two', one, two);
    +      console.log('One and Two', one, two);
           expect(two.w).toBe(2);
         });
         it('empty blocks', async () => {
    @@ -323,46 +364,52 @@ describe('Block diagram', function () {
             columns 3
             space
             middle["In the middle"]
    +        space
             `;
     
           block.parse(str);
    +
    +      const blocks = db.getBlocks();
    +      expect(blocks.length).toBe(3);
    +      const sp1 = blocks[0];
    +      const middle = blocks[1];
    +      const sp2 = blocks[2];
    +      expect(sp1.type).toBe('space');
    +      expect(sp2.type).toBe('space');
    +      expect(middle.label).toBe('In the middle');
         });
    -    it.skip('classDef statements applied to a block', async () => {
    +    it('classDef statements applied to a block', async () => {
           const str = `block-beta
             classDef black color:#ffffff, fill:#000000;
     
    -        mc["Memcache"]:::black
    +        mc["Memcache"]
    +        class mc black
             `;
     
           block.parse(str);
    +      const blocks = db.getBlocks();
    +      expect(blocks.length).toBe(1);
    +      const mc = blocks[0];
    +      expect(mc.classes).toContain('black');
    +      const classes = db.getClasses();
    +      console.log(classes);
    +      const black = classes.black;
    +      expect(black.id).toBe('black');
    +      expect(black.styles[0]).toEqual('color:#ffffff');
         });
    -    it.skip('classDef statements applied to a block with a width', async () => {
    +    it('style statements applied to a block', async () => {
           const str = `block-beta
    -        classDef black color:#ffffff, fill:#000000;
    -        columns 2
    -        mc["Memcache"]:2::black
    +columns 1
    +    B["A wide one in the middle"]
    +  style B fill:#f9F,stroke:#333,stroke-width:4px
             `;
    -      const apa = 'apan hopar i träden';
    -      block.parse(str);
    -    });
    -
    -    it.skip('classDef statements', async () => {
    -      const str = `block-beta
    -        classDef black color:#ffffff, fill:#000000;
    -
    -        block DataServices["Data Services"]
    -          columns H
    -          block Relational
    -            mssql["Microsoft SQL
    Server"] - end - block Tabular - columns 3 - gds["Google Data Store"]:1 - mc["Memcache"]:2:::black - end - end`; block.parse(str); + const blocks = db.getBlocks(); + expect(blocks.length).toBe(1); + const B = blocks[0]; + console.log(B); + expect(B.styles).toContain('fill:#f9F'); }); }); }); diff --git a/packages/mermaid/src/diagrams/block/renderHelpers.ts b/packages/mermaid/src/diagrams/block/renderHelpers.ts index 757bbadb9b..34f249315f 100644 --- a/packages/mermaid/src/diagrams/block/renderHelpers.ts +++ b/packages/mermaid/src/diagrams/block/renderHelpers.ts @@ -98,7 +98,7 @@ function getNodeFromBlock(block: Block, db: BlockDB, positioned = false) { _shape = 'rect'; } - const styles = getStylesFromArray(vertex?.styles || ''); + const styles = getStylesFromArray(vertex?.styles || []); // const styles = getStylesFromArray([]); // Use vertex id as text in the box if no text is provided by the graph definition @@ -117,13 +117,6 @@ function getNodeFromBlock(block: Block, db: BlockDB, positioned = false) { style: styles.style, // + 'fill:#9f9;stroke:#333;stroke-width:4px;', id: vertex.id, directions: vertex.directions, - // link: vertex.link, - // linkTarget: vertex.linkTarget, - // tooltip: diagObj.db.getTooltip(vertex.id) || '', - // domId: diagObj.db.lookUpDomId(vertex.id), - // haveCallback: vertex.haveCallback, - // width: vertex.type === 'group' ? 500 : undefined, - // dir: vertex.dir, width: bounds.width, height: bounds.height, x: bounds.x, diff --git a/packages/mermaid/src/utils.ts b/packages/mermaid/src/utils.ts index e48b49fcda..6ea93aaa24 100644 --- a/packages/mermaid/src/utils.ts +++ b/packages/mermaid/src/utils.ts @@ -492,6 +492,7 @@ export function getStylesFromArray(arr: string[]): { style: string; labelStyle: } } } + console.log(arr, style, labelStyle); return { style: style, labelStyle: labelStyle }; } From 8e147206d8a02daa68b0d42d3b60f6e92d71d8ae Mon Sep 17 00:00:00 2001 From: Knut Sveidqvist Date: Thu, 18 Jan 2024 15:44:16 +0100 Subject: [PATCH 109/217] #3358 Removed logging som type fixes --- .../mermaid/src/diagrams/block/blockDB.ts | 58 ++++--------------- packages/mermaid/src/diagrams/block/layout.ts | 9 +-- .../src/diagrams/block/parser/block.spec.ts | 6 -- 3 files changed, 13 insertions(+), 60 deletions(-) diff --git a/packages/mermaid/src/diagrams/block/blockDB.ts b/packages/mermaid/src/diagrams/block/blockDB.ts index 34d2b5d10b..2ba5e80a0b 100644 --- a/packages/mermaid/src/diagrams/block/blockDB.ts +++ b/packages/mermaid/src/diagrams/block/blockDB.ts @@ -31,8 +31,8 @@ let classes = {} as Record; * Called when the parser comes across a (style) class definition * @example classDef my-style fill:#f96; * - * @param {string} id - the id of this (style) class - * @param {string | null} styleAttributes - the string with 1 or more style attributes (each separated by a comma) + * @param id - the id of this (style) class + * @param styleAttributes - the string with 1 or more style attributes (each separated by a comma) */ export const addStyleClass = function (id: string, styleAttributes = '') { // create a new style class object with this id @@ -60,11 +60,11 @@ export const addStyleClass = function (id: string, styleAttributes = '') { * Called when the parser comes across a (style) class definition * @example classDef my-style fill:#f96; * - * @param {string} id - the id of this (style) class - * @param {string | null} styles - the string with 1 or more style attributes (each separated by a comma) + * @param id - the id of this (style) class + * @param styles - the string with 1 or more style attributes (each separated by a comma) */ export const addStyle2Node = function (id: string, styles = '') { - let foundBlock = blockDatabase[id]; + const foundBlock = blockDatabase[id]; if (styles !== undefined && styles !== null) { foundBlock.styles = styles.split(STYLECLASS_SEP); } @@ -75,8 +75,8 @@ export const addStyle2Node = function (id: string, styles = '') { * If the state isn't already in the list of known states, add it. * Might be called by parser when a style class or CSS class should be applied to a state * - * @param {string | string[]} itemIds The id or a list of ids of the item(s) to apply the css class to - * @param {string} cssClassName CSS class name + * @param itemIds - The id or a list of ids of the item(s) to apply the css class to + * @param cssClassName - CSS class name */ export const setCssClass = function (itemIds: string, cssClassName: string) { itemIds.split(',').forEach(function (id: string) { @@ -93,36 +93,6 @@ export const setCssClass = function (itemIds: string, cssClassName: string) { }); }; -// /** -// * Add a style to a state with the given id. -// * @example style stateId fill:#f9f,stroke:#333,stroke-width:4px -// * where 'style' is the keyword -// * stateId is the id of a state -// * the rest of the string is the styleText (all of the attributes to be applied to the state) -// * -// * @param itemId The id of item to apply the style to -// * @param styleText - the text of the attributes for the style -// */ -// export const setStyle = function (itemId, styleText) { -// const item = getState(itemId); -// if (item !== undefined) { -// item.textStyles.push(styleText); -// } -// }; - -// /** -// * Add a text style to a state with the given id -// * -// * @param itemId The id of item to apply the css class to -// * @param cssClassName CSS class name -// */ -// export const setTextStyle = function (itemId, cssClassName) { -// const item = getState(itemId); -// if (item !== undefined) { -// item.textStyles.push(cssClassName); -// } -// }; - const populateBlockDatabase = (_blockList: Block[], parent: Block): void => { const blockList = _blockList.flat(); const children = []; @@ -135,12 +105,9 @@ const populateBlockDatabase = (_blockList: Block[], parent: Block): void => { setCssClass(block.id, block?.styleClass || ''); continue; } - if (block.type === 'applyStyles') { - console.log('applyStyles', block.stylesStr); - if (block?.stylesStr) { - addStyle2Node(block.id, block?.stylesStr); - continue; - } + if (block.type === 'applyStyles' && block?.stylesStr) { + addStyle2Node(block.id, block?.stylesStr); + continue; } if (block.type === 'column-setting') { parent.columns = block.columns || -1; @@ -292,10 +259,8 @@ export const generateId = () => { type ISetHierarchy = (block: Block[]) => void; const setHierarchy = (block: Block[]): void => { - console.log('The document from parsing', JSON.stringify(block, null, 2)); rootBlock.children = block; populateBlockDatabase(block, rootBlock); - // log.debug('abc95 The document after popuplation', JSON.stringify(rootBlock, null, 2)); blocks = rootBlock.children; }; @@ -335,7 +300,7 @@ const getBlocksFlat: IGetBlocks = () => { return result; }; /** - * Returns the the hirarchy of blocks + * Returns the the hierarchy of blocks * @returns */ const getBlocks: IGetBlocks = () => { @@ -363,7 +328,6 @@ const getLogger: IGetLogger = () => console; type IGetClasses = () => Record; /** * Return all of the style classes - * @returns {{} | any | classes} */ export const getClasses = function () { return classes; diff --git a/packages/mermaid/src/diagrams/block/layout.ts b/packages/mermaid/src/diagrams/block/layout.ts index e06d6ff10d..b5dc63b343 100644 --- a/packages/mermaid/src/diagrams/block/layout.ts +++ b/packages/mermaid/src/diagrams/block/layout.ts @@ -68,12 +68,7 @@ const getMaxChildSize = (block: Block) => { return { width: maxWidth, height: maxHeight }; }; -function setBlockSizes( - block: Block, - db: BlockDB, - sieblingWidth: number = 0, - sieblingHeight: number = 0 -) { +function setBlockSizes(block: Block, db: BlockDB, sieblingWidth = 0, sieblingHeight = 0) { log.debug( 'setBlockSizes abc95 (start)', block.id, @@ -118,7 +113,7 @@ function setBlockSizes( maxHeight, child.size ); - child.size.width = maxWidth * child.w + padding * (child.w - 1); + child.size.width = maxWidth * (child.w || 1) + padding * ((child.w || 1) - 1); child.size.height = maxHeight; child.size.x = 0; child.size.y = 0; diff --git a/packages/mermaid/src/diagrams/block/parser/block.spec.ts b/packages/mermaid/src/diagrams/block/parser/block.spec.ts index 3028a6c3ca..aec14cc08d 100644 --- a/packages/mermaid/src/diagrams/block/parser/block.spec.ts +++ b/packages/mermaid/src/diagrams/block/parser/block.spec.ts @@ -4,7 +4,6 @@ import db from '../blockDB.js'; import { cleanupComments } from '../../../diagram-api/comments.js'; import { prepareTextForParsing } from '../blockUtils.js'; import { setConfig } from '../../../config.js'; -import getStyles from '../../../../dist/diagrams/pie/styles'; describe('Block diagram', function () { describe('when parsing an block diagram graph it should handle > ', function () { @@ -316,7 +315,6 @@ describe('Block diagram', function () { expect(block2.label).toBe('Block 2'); expect(block2.type).toBe('square'); expect(blockArrow.type).toBe('block_arrow'); - console.log('blockArrow', blockArrow); expect(blockArrow.directions).toContain('right'); }); it('Arrow blocks with multiple points', async () => { @@ -338,7 +336,6 @@ describe('Block diagram', function () { const blockArrow = blocks[1]; expect(blockArrow.type).toBe('block_arrow'); - console.log('blockArrow', blockArrow); expect(blockArrow.directions).toContain('up'); expect(blockArrow.directions).toContain('down'); expect(blockArrow.directions).not.toContain('right'); @@ -356,7 +353,6 @@ describe('Block diagram', function () { expect(blocks.length).toBe(2); const one = blocks[0]; const two = blocks[1]; - console.log('One and Two', one, two); expect(two.w).toBe(2); }); it('empty blocks', async () => { @@ -392,7 +388,6 @@ describe('Block diagram', function () { const mc = blocks[0]; expect(mc.classes).toContain('black'); const classes = db.getClasses(); - console.log(classes); const black = classes.black; expect(black.id).toBe('black'); expect(black.styles[0]).toEqual('color:#ffffff'); @@ -408,7 +403,6 @@ columns 1 const blocks = db.getBlocks(); expect(blocks.length).toBe(1); const B = blocks[0]; - console.log(B); expect(B.styles).toContain('fill:#f9F'); }); }); From 173ba2ecf5db8c9e29bf84e98496bcc77be95adb Mon Sep 17 00:00:00 2001 From: Knut Sveidqvist Date: Thu, 18 Jan 2024 15:48:40 +0100 Subject: [PATCH 110/217] Final console.log removed --- packages/mermaid/src/utils.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/packages/mermaid/src/utils.ts b/packages/mermaid/src/utils.ts index 6ea93aaa24..35d01a60e7 100644 --- a/packages/mermaid/src/utils.ts +++ b/packages/mermaid/src/utils.ts @@ -492,8 +492,6 @@ export function getStylesFromArray(arr: string[]): { style: string; labelStyle: } } } - console.log(arr, style, labelStyle); - return { style: style, labelStyle: labelStyle }; } From 5553cbbb228ba499568dd2a08c34917b2f53ff72 Mon Sep 17 00:00:00 2001 From: knsv Date: Thu, 18 Jan 2024 16:10:57 +0000 Subject: [PATCH 111/217] Update docs --- docs/config/setup/modules/defaultConfig.md | 2 +- docs/config/setup/modules/mermaidAPI.md | 2 +- docs/intro/examples.md | 247 --------------------- 3 files changed, 2 insertions(+), 249 deletions(-) delete mode 100644 docs/intro/examples.md diff --git a/docs/config/setup/modules/defaultConfig.md b/docs/config/setup/modules/defaultConfig.md index 7a9b891c43..3d94055bea 100644 --- a/docs/config/setup/modules/defaultConfig.md +++ b/docs/config/setup/modules/defaultConfig.md @@ -14,7 +14,7 @@ #### Defined in -[defaultConfig.ts:272](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/defaultConfig.ts#L272) +[defaultConfig.ts:278](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/defaultConfig.ts#L278) --- diff --git a/docs/config/setup/modules/mermaidAPI.md b/docs/config/setup/modules/mermaidAPI.md index a1992c2254..9516d2b460 100644 --- a/docs/config/setup/modules/mermaidAPI.md +++ b/docs/config/setup/modules/mermaidAPI.md @@ -96,7 +96,7 @@ mermaid.initialize(config); #### Defined in -[mermaidAPI.ts:608](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L608) +[mermaidAPI.ts:607](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L607) ## Functions diff --git a/docs/intro/examples.md b/docs/intro/examples.md deleted file mode 100644 index a7089ea9df..0000000000 --- a/docs/intro/examples.md +++ /dev/null @@ -1,247 +0,0 @@ -> **Warning** -> -> ## THIS IS AN AUTOGENERATED FILE. DO NOT EDIT. -> -> ## Please edit the corresponding file in [/packages/mermaid/src/docs/intro/examples.md](../../packages/mermaid/src/docs/intro/examples.md). - -## Diagram Types - -### [Flowchart](../syntax/flowchart.md?id=flowcharts-basic-syntax) - -```mermaid-example -graph TD; - A-->B; - A-->C; - B-->D; - C-->D; -``` - -```mermaid -graph TD; - A-->B; - A-->C; - B-->D; - C-->D; -``` - -### [Sequence diagram](../syntax/sequenceDiagram.md) - -```mermaid-example -sequenceDiagram - participant Alice - participant Bob - Alice->>John: Hello John, how are you? - loop Healthcheck - John->>John: Fight against hypochondria - end - Note right of John: Rational thoughts
    prevail! - John-->>Alice: Great! - John->>Bob: How about you? - Bob-->>John: Jolly good! -``` - -```mermaid -sequenceDiagram - participant Alice - participant Bob - Alice->>John: Hello John, how are you? - loop Healthcheck - John->>John: Fight against hypochondria - end - Note right of John: Rational thoughts
    prevail! - John-->>Alice: Great! - John->>Bob: How about you? - Bob-->>John: Jolly good! -``` - -### [Gantt diagram](../syntax/gantt.md) - -```mermaid-example -gantt -dateFormat YYYY-MM-DD -title Adding GANTT diagram to mermaid -excludes weekdays 2014-01-10 - -section A section -Completed task :done, des1, 2014-01-06,2014-01-08 -Active task :active, des2, 2014-01-09, 3d -Future task : des3, after des2, 5d -Future task2 : des4, after des3, 5d -``` - -```mermaid -gantt -dateFormat YYYY-MM-DD -title Adding GANTT diagram to mermaid -excludes weekdays 2014-01-10 - -section A section -Completed task :done, des1, 2014-01-06,2014-01-08 -Active task :active, des2, 2014-01-09, 3d -Future task : des3, after des2, 5d -Future task2 : des4, after des3, 5d -``` - -### [Class diagram](../syntax/classDiagram.md) - -```mermaid-example -classDiagram -Class01 <|-- AveryLongClass : Cool -Class03 *-- Class04 -Class05 o-- Class06 -Class07 .. Class08 -Class09 --> C2 : Where am i? -Class09 --* C3 -Class09 --|> Class07 -Class07 : equals() -Class07 : Object[] elementData -Class01 : size() -Class01 : int chimp -Class01 : int gorilla -Class08 <--> C2: Cool label -``` - -```mermaid -classDiagram -Class01 <|-- AveryLongClass : Cool -Class03 *-- Class04 -Class05 o-- Class06 -Class07 .. Class08 -Class09 --> C2 : Where am i? -Class09 --* C3 -Class09 --|> Class07 -Class07 : equals() -Class07 : Object[] elementData -Class01 : size() -Class01 : int chimp -Class01 : int gorilla -Class08 <--> C2: Cool label -``` - -### [Git graph](../syntax/gitgraph.md) - -```mermaid-example - gitGraph - commit - commit - branch develop - commit - commit - commit - checkout main - commit - commit -``` - -```mermaid - gitGraph - commit - commit - branch develop - commit - commit - commit - checkout main - commit - commit -``` - -### [Entity Relationship Diagram - :exclamation: experimental](../syntax/entityRelationshipDiagram.md) - -```mermaid-example -erDiagram - CUSTOMER ||--o{ ORDER : places - ORDER ||--|{ LINE-ITEM : contains - CUSTOMER }|..|{ DELIVERY-ADDRESS : uses - -``` - -```mermaid -erDiagram - CUSTOMER ||--o{ ORDER : places - ORDER ||--|{ LINE-ITEM : contains - CUSTOMER }|..|{ DELIVERY-ADDRESS : uses - -``` - -### [User Journey Diagram](../syntax/userJourney.md) - -```mermaid-example -journey - title My working day - section Go to work - Make tea: 5: Me - Go upstairs: 3: Me - Do work: 1: Me, Cat - section Go home - Go downstairs: 5: Me - Sit down: 5: Me -``` - -```mermaid -journey - title My working day - section Go to work - Make tea: 5: Me - Go upstairs: 3: Me - Do work: 1: Me, Cat - section Go home - Go downstairs: 5: Me - Sit down: 5: Me -``` - -### [Quadrant Chart](../syntax/quadrantChart.md) - -```mermaid-example -quadrantChart - title Reach and engagement of campaigns - x-axis Low Reach --> High Reach - y-axis Low Engagement --> High Engagement - quadrant-1 We should expand - quadrant-2 Need to promote - quadrant-3 Re-evaluate - quadrant-4 May be improved - Campaign A: [0.3, 0.6] - Campaign B: [0.45, 0.23] - Campaign C: [0.57, 0.69] - Campaign D: [0.78, 0.34] - Campaign E: [0.40, 0.34] - Campaign F: [0.35, 0.78] -``` - -```mermaid -quadrantChart - title Reach and engagement of campaigns - x-axis Low Reach --> High Reach - y-axis Low Engagement --> High Engagement - quadrant-1 We should expand - quadrant-2 Need to promote - quadrant-3 Re-evaluate - quadrant-4 May be improved - Campaign A: [0.3, 0.6] - Campaign B: [0.45, 0.23] - Campaign C: [0.57, 0.69] - Campaign D: [0.78, 0.34] - Campaign E: [0.40, 0.34] - Campaign F: [0.35, 0.78] -``` - -### [XY Chart](../syntax/xyChart.md) - -```mermaid-example -xychart-beta - title "Sales Revenue" - x-axis [jan, feb, mar, apr, may, jun, jul, aug, sep, oct, nov, dec] - y-axis "Revenue (in $)" 4000 --> 11000 - bar [5000, 6000, 7500, 8200, 9500, 10500, 11000, 10200, 9200, 8500, 7000, 6000] - line [5000, 6000, 7500, 8200, 9500, 10500, 11000, 10200, 9200, 8500, 7000, 6000] -``` - -```mermaid -xychart-beta - title "Sales Revenue" - x-axis [jan, feb, mar, apr, may, jun, jul, aug, sep, oct, nov, dec] - y-axis "Revenue (in $)" 4000 --> 11000 - bar [5000, 6000, 7500, 8200, 9500, 10500, 11000, 10200, 9200, 8500, 7000, 6000] - line [5000, 6000, 7500, 8200, 9500, 10500, 11000, 10200, 9200, 8500, 7000, 6000] -``` From fb7cd9ca407c8fa68fe54ac8430e331f32cca979 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 18 Jan 2024 16:17:34 +0000 Subject: [PATCH 112/217] chore(deps): update all patch dependencies --- packages/mermaid/src/docs/package.json | 2 +- pnpm-lock.yaml | 651 +++++++------------------ 2 files changed, 178 insertions(+), 475 deletions(-) diff --git a/packages/mermaid/src/docs/package.json b/packages/mermaid/src/docs/package.json index dd33207c03..e867842125 100644 --- a/packages/mermaid/src/docs/package.json +++ b/packages/mermaid/src/docs/package.json @@ -32,7 +32,7 @@ "unplugin-vue-components": "^0.26.0", "vite": "^4.4.12", "vite-plugin-pwa": "^0.17.0", - "vitepress": "1.0.0-rc.31", + "vitepress": "1.0.0-rc.39", "workbox-window": "^7.0.0" } } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index c0f20ed87d..b9c49e0a09 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -475,63 +475,8 @@ importers: specifier: ^0.17.0 version: 0.17.0(vite@4.5.0)(workbox-build@7.0.0)(workbox-window@7.0.0) vitepress: - specifier: 1.0.0-rc.31 - version: 1.0.0-rc.31(@algolia/client-search@4.19.1)(@types/node@18.17.5)(postcss@8.4.31)(search-insights@2.7.0)(typescript@5.1.6) - workbox-window: - specifier: ^7.0.0 - version: 7.0.0 - - packages/mermaid/src/vitepress: - dependencies: - '@vueuse/core': - specifier: ^10.1.0 - version: 10.1.0(vue@3.3.4) - jiti: - specifier: ^1.18.2 - version: 1.18.2 - mermaid: - specifier: workspace:^ - version: link:../.. - vue: - specifier: ^3.3 - version: 3.3.4 - devDependencies: - '@iconify-json/carbon': - specifier: ^1.1.16 - version: 1.1.16 - '@unocss/reset': - specifier: ^0.58.0 - version: 0.58.0 - '@vite-pwa/vitepress': - specifier: ^0.3.0 - version: 0.3.0(vite-plugin-pwa@0.17.0) - '@vitejs/plugin-vue': - specifier: ^4.2.1 - version: 4.2.1(vite@4.4.12)(vue@3.3.4) - fast-glob: - specifier: ^3.2.12 - version: 3.2.12 - https-localhost: - specifier: ^4.7.1 - version: 4.7.1 - pathe: - specifier: ^1.1.0 - version: 1.1.0 - unocss: - specifier: ^0.58.0 - version: 0.58.0(postcss@8.4.31)(rollup@2.79.1)(vite@4.4.12) - unplugin-vue-components: - specifier: ^0.26.0 - version: 0.26.0(rollup@2.79.1)(vue@3.3.4) - vite: - specifier: ^4.4.12 - version: 4.4.12(@types/node@18.17.5) - vite-plugin-pwa: - specifier: ^0.17.0 - version: 0.17.0(vite@4.4.12)(workbox-build@7.0.0)(workbox-window@7.0.0) - vitepress: - specifier: 1.0.0-rc.31 - version: 1.0.0-rc.31(@algolia/client-search@4.19.1)(@types/node@18.17.5)(postcss@8.4.31)(search-insights@2.7.0)(typescript@5.1.6) + specifier: 1.0.0-rc.39 + version: 1.0.0-rc.39(@algolia/client-search@4.19.1)(@types/node@18.17.5)(postcss@8.4.31)(search-insights@2.7.0)(typescript@5.1.6) workbox-window: specifier: ^7.0.0 version: 7.0.0 @@ -1147,10 +1092,10 @@ packages: '@babel/helper-compilation-targets': 7.22.10 '@babel/helper-module-transforms': 7.22.9(@babel/core@7.22.10) '@babel/helpers': 7.22.10 - '@babel/parser': 7.23.0 + '@babel/parser': 7.23.5 '@babel/template': 7.22.5 '@babel/traverse': 7.23.2 - '@babel/types': 7.23.0 + '@babel/types': 7.23.5 convert-source-map: 1.9.0 debug: 4.3.4(supports-color@8.1.1) gensync: 1.0.0-beta.2 @@ -1187,7 +1132,7 @@ packages: resolution: {integrity: sha512-79KIf7YiWjjdZ81JnLujDRApWtl7BxTqWD88+FFdQEIOG8LJ0etDOM7CXuIgGJa55sGOwZVwuEsaLEm0PJ5/+A==} engines: {node: '>=6.9.0'} dependencies: - '@babel/types': 7.23.0 + '@babel/types': 7.23.5 '@jridgewell/gen-mapping': 0.3.3 '@jridgewell/trace-mapping': 0.3.19 jsesc: 2.5.2 @@ -1197,7 +1142,7 @@ packages: resolution: {integrity: sha512-lN85QRR+5IbYrMWM6Y4pE/noaQtg4pNiqeNGX60eqOfo6gtEj6uw/JagelB8vVztSd7R6M5n1+PQkDbHbBRU4g==} engines: {node: '>=6.9.0'} dependencies: - '@babel/types': 7.23.0 + '@babel/types': 7.23.5 '@jridgewell/gen-mapping': 0.3.3 '@jridgewell/trace-mapping': 0.3.19 jsesc: 2.5.2 @@ -1217,7 +1162,7 @@ packages: resolution: {integrity: sha512-LvBTxu8bQSQkcyKOU+a1btnNFQ1dMAd0R6PyW3arXes06F6QLWLIrd681bxRPIXlrMGR3XYnW9JyML7dP3qgxg==} engines: {node: '>=6.9.0'} dependencies: - '@babel/types': 7.23.0 + '@babel/types': 7.23.5 dev: true /@babel/helper-builder-binary-assignment-operator-visitor@7.22.10: @@ -1318,7 +1263,7 @@ packages: resolution: {integrity: sha512-6gfrPwh7OuT6gZyJZvd6WbTfrqAo7vm4xCzAXOusKqq/vWdKXphTpj5klHKNmRUU6/QRGlBsyU9mAIPaWHlqJA==} engines: {node: '>=6.9.0'} dependencies: - '@babel/types': 7.23.0 + '@babel/types': 7.23.5 dev: true /@babel/helper-module-imports@7.22.15: @@ -1332,7 +1277,7 @@ packages: resolution: {integrity: sha512-8Dl6+HD/cKifutF5qGd/8ZJi84QeAKh+CEe1sBzz8UayBBGg1dAIJrdHOcOM5b2MpzWL2yuotJTtGjETq0qjXg==} engines: {node: '>=6.9.0'} dependencies: - '@babel/types': 7.23.0 + '@babel/types': 7.23.5 dev: true /@babel/helper-module-transforms@7.22.9(@babel/core@7.22.10): @@ -1367,7 +1312,7 @@ packages: resolution: {integrity: sha512-HBwaojN0xFRx4yIvpwGqxiV2tUfl7401jlok564NgB9EHS1y6QT17FmKWm4ztqjeVdXLuC4fSvHc5ePpQjoTbw==} engines: {node: '>=6.9.0'} dependencies: - '@babel/types': 7.23.0 + '@babel/types': 7.23.5 dev: true /@babel/helper-plugin-utils@7.22.5: @@ -1410,7 +1355,7 @@ packages: resolution: {integrity: sha512-tK14r66JZKiC43p8Ki33yLBVJKlQDFoA8GYN67lWCDCqoL6EMMSuM9b+Iff2jHaM/RRFYl7K+iiru7hbRqNx8Q==} engines: {node: '>=6.9.0'} dependencies: - '@babel/types': 7.23.0 + '@babel/types': 7.23.5 dev: true /@babel/helper-split-export-declaration@7.22.6: @@ -1462,7 +1407,7 @@ packages: dependencies: '@babel/template': 7.22.15 '@babel/traverse': 7.23.2 - '@babel/types': 7.23.0 + '@babel/types': 7.23.5 transitivePeerDependencies: - supports-color dev: true @@ -1510,6 +1455,14 @@ packages: dependencies: '@babel/types': 7.23.5 + /@babel/parser@7.23.6: + resolution: {integrity: sha512-Z2uID7YJ7oNvAI20O9X0bblw7Qqs8Q2hFy0R9tAfnfLkp5MW0UH9eUvnDSnFwKZ0AvgS1ucqR4KzvVHgnke1VQ==} + engines: {node: '>=6.0.0'} + hasBin: true + dependencies: + '@babel/types': 7.23.5 + dev: true + /@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@7.22.5(@babel/core@7.23.5): resolution: {integrity: sha512-NP1M5Rf+u2Gw9qfSO4ihjcTGW5zXTi36ITLd4/EoAcEhIZ0yjMqmftDNl3QC19CX7olhrjpyU454g/2W7X0jvQ==} engines: {node: '>=6.9.0'} @@ -2545,8 +2498,8 @@ packages: engines: {node: '>=6.9.0'} dependencies: '@babel/code-frame': 7.22.13 - '@babel/parser': 7.23.0 - '@babel/types': 7.23.0 + '@babel/parser': 7.23.5 + '@babel/types': 7.23.5 dev: true /@babel/traverse@7.23.2: @@ -2559,8 +2512,8 @@ packages: '@babel/helper-function-name': 7.23.0 '@babel/helper-hoist-variables': 7.22.5 '@babel/helper-split-export-declaration': 7.22.6 - '@babel/parser': 7.23.0 - '@babel/types': 7.23.0 + '@babel/parser': 7.23.5 + '@babel/types': 7.23.5 debug: 4.3.4(supports-color@8.1.1) globals: 11.12.0 transitivePeerDependencies: @@ -4636,7 +4589,7 @@ packages: resolution: {integrity: sha512-aACu/U/omhdk15O4Nfb+fHgH/z3QsfQzpnvRZhYhThms83ZnAOZz7zZAWO7mn2yyNQaA4xTO8GLK3uqFU4bYYw==} dependencies: '@babel/parser': 7.23.5 - '@babel/types': 7.23.0 + '@babel/types': 7.23.5 '@types/babel__generator': 7.6.4 '@types/babel__template': 7.4.1 '@types/babel__traverse': 7.20.1 @@ -4645,20 +4598,20 @@ packages: /@types/babel__generator@7.6.4: resolution: {integrity: sha512-tFkciB9j2K755yrTALxD44McOrk+gfpIpvC3sxHjRawj6PfnQxrse4Clq5y/Rq+G3mrBurMax/lG8Qn2t9mSsg==} dependencies: - '@babel/types': 7.23.0 + '@babel/types': 7.23.5 dev: true /@types/babel__template@7.4.1: resolution: {integrity: sha512-azBFKemX6kMg5Io+/rdGT0dkGreboUVR0Cdm3fz9QJWpaQGJRQXl7C+6hOTCZcMll7KFyEQpgbYI2lHdsS4U7g==} dependencies: '@babel/parser': 7.23.5 - '@babel/types': 7.23.0 + '@babel/types': 7.23.5 dev: true /@types/babel__traverse@7.20.1: resolution: {integrity: sha512-MitHFXnhtgwsGZWtT68URpOvLN4EREih1u3QtQiN4VdAxWKRVvGCSvw/Qth0M0Qq3pJpnGOu5JaM/ydK7OGbqg==} dependencies: - '@babel/types': 7.23.0 + '@babel/types': 7.23.5 dev: true /@types/body-parser@1.19.2: @@ -4984,12 +4937,6 @@ packages: '@types/node': 18.17.5 dev: true - /@types/hast@3.0.3: - resolution: {integrity: sha512-2fYGlaDy/qyLlhidX42wAH0KBi2TCjKMH8CHmBXgRlJ3Y+OXTiqsPQ6IWarZKwF1JoUcAJdPogv1d4b0COTpmQ==} - dependencies: - '@types/unist': 3.0.2 - dev: true - /@types/http-cache-semantics@4.0.1: resolution: {integrity: sha512-SZs7ekbP8CN0txVG2xVRH6EgKmEm31BOxA07vkFaETzZz1xh+cbt8BcI0slpymvwhx5dlFnQG2rTlPVQn+iRPQ==} dev: true @@ -5075,12 +5022,6 @@ packages: dependencies: '@types/unist': 2.0.7 - /@types/mdast@4.0.3: - resolution: {integrity: sha512-LsjtqsyF+d2/yFOYaN22dHZI1Cpwkrj+g06G8+qtUKlhovPW89YhqSnfKtMbkgmEtYpH2gydRNULd6y8mciAFg==} - dependencies: - '@types/unist': 3.0.2 - dev: true - /@types/mdurl@1.0.2: resolution: {integrity: sha512-eC4U9MlIcu2q0KQmXszyn5Akca/0jrQmwDRgpAMJai7qBWq4amIQhZyNau4VYGtCeALvW1/NtjzJJ567aZxfKA==} dev: true @@ -5224,10 +5165,6 @@ packages: /@types/unist@2.0.7: resolution: {integrity: sha512-cputDpIbFgLUaGQn6Vqg3/YsJwxUwHLO13v3i5ouxT4lat0khip9AEWxtERujXV9wxIB1EyF97BSJFt6vpdI8g==} - /@types/unist@3.0.2: - resolution: {integrity: sha512-dqId9J8K/vGi5Zr7oo212BGii5m3q5Hxlkwy3WpYuKPklmBEvsbMYYyLxAQpSffdLl/gdW0XUpKWFvYmyoWCoQ==} - dev: true - /@types/uuid@9.0.1: resolution: {integrity: sha512-rFT3ak0/2trgvp4yYZo5iKFEPsET7vKydKF+VRCxlQ9bpheehyAJH89dAkaLEq/j/RZXJIqcgsmPJKUP1Z28HA==} dev: true @@ -5591,26 +5528,6 @@ packages: eslint-visitor-keys: 3.4.3 dev: true - /@ungap/structured-clone@1.2.0: - resolution: {integrity: sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==} - dev: true - - /@unocss/astro@0.58.0(rollup@2.79.1)(vite@4.4.12): - resolution: {integrity: sha512-df+tEFO5eKXjQOwSWQhS9IdjD0sfLHLtn8U09sEKR2Nmh5CvpwyBxmvLQgOCilPou7ehmyKfsyGRLZg7IMp+Ew==} - peerDependencies: - vite: ^2.9.0 || ^3.0.0-0 || ^4.0.0 || ^5.0.0-0 - peerDependenciesMeta: - vite: - optional: true - dependencies: - '@unocss/core': 0.58.0 - '@unocss/reset': 0.58.0 - '@unocss/vite': 0.58.0(rollup@2.79.1)(vite@4.4.12) - vite: 4.4.12(@types/node@18.17.5) - transitivePeerDependencies: - - rollup - dev: true - /@unocss/astro@0.58.0(rollup@2.79.1)(vite@4.5.0): resolution: {integrity: sha512-df+tEFO5eKXjQOwSWQhS9IdjD0sfLHLtn8U09sEKR2Nmh5CvpwyBxmvLQgOCilPou7ehmyKfsyGRLZg7IMp+Ew==} peerDependencies: @@ -5805,26 +5722,6 @@ packages: '@unocss/core': 0.58.0 dev: true - /@unocss/vite@0.58.0(rollup@2.79.1)(vite@4.4.12): - resolution: {integrity: sha512-OCUOLMSOBEtXOEyBbAvMI3/xdR175BWRzmvV9Wc34ANZclEvCdVH8+WU725ibjY4VT0gVIuX68b13fhXdHV41A==} - peerDependencies: - vite: ^2.9.0 || ^3.0.0-0 || ^4.0.0 || ^5.0.0-0 - dependencies: - '@ampproject/remapping': 2.2.1 - '@rollup/pluginutils': 5.1.0(rollup@2.79.1) - '@unocss/config': 0.58.0 - '@unocss/core': 0.58.0 - '@unocss/inspector': 0.58.0 - '@unocss/scope': 0.58.0 - '@unocss/transformer-directives': 0.58.0 - chokidar: 3.5.3 - fast-glob: 3.3.2 - magic-string: 0.30.5 - vite: 4.4.12(@types/node@18.17.5) - transitivePeerDependencies: - - rollup - dev: true - /@unocss/vite@0.58.0(rollup@2.79.1)(vite@4.5.0): resolution: {integrity: sha512-OCUOLMSOBEtXOEyBbAvMI3/xdR175BWRzmvV9Wc34ANZclEvCdVH8+WU725ibjY4VT0gVIuX68b13fhXdHV41A==} peerDependencies: @@ -5850,18 +5747,7 @@ packages: peerDependencies: vite-plugin-pwa: '>=0.17.0 <1' dependencies: - vite-plugin-pwa: 0.17.0(vite@4.4.12)(workbox-build@7.0.0)(workbox-window@7.0.0) - dev: true - - /@vitejs/plugin-vue@4.2.1(vite@4.4.12)(vue@3.3.4): - resolution: {integrity: sha512-ZTZjzo7bmxTRTkb8GSTwkPOYDIP7pwuyV+RV53c9PYUouwcbkIZIvWvNWlX2b1dYZqtOv7D6iUAnJLVNGcLrSw==} - engines: {node: ^14.18.0 || >=16.0.0} - peerDependencies: - vite: ^4.0.0 - vue: ^3.2.25 - dependencies: - vite: 4.4.12(@types/node@18.17.5) - vue: 3.3.4 + vite-plugin-pwa: 0.17.0(vite@4.5.0)(workbox-build@7.0.0)(workbox-window@7.0.0) dev: true /@vitejs/plugin-vue@4.2.1(vite@4.5.0)(vue@3.3.4): @@ -5886,15 +5772,15 @@ packages: vue: 3.3.4 dev: true - /@vitejs/plugin-vue@4.5.0(vite@5.0.2)(vue@3.3.8): - resolution: {integrity: sha512-a2WSpP8X8HTEww/U00bU4mX1QpLINNuz/2KMNpLsdu3BzOpak3AGI1CJYBTXcc4SPhaD0eNRUp7IyQK405L5dQ==} - engines: {node: ^14.18.0 || >=16.0.0} + /@vitejs/plugin-vue@5.0.3(vite@5.0.11)(vue@3.4.15): + resolution: {integrity: sha512-b8S5dVS40rgHdDrw+DQi/xOM9ed+kSRZzfm1T74bMmBDCd8XO87NKlFYInzCtwvtWwXZvo1QxE2OSspTATWrbA==} + engines: {node: ^18.0.0 || >=20.0.0} peerDependencies: - vite: ^4.0.0 || ^5.0.0 + vite: ^5.0.0 vue: ^3.2.25 dependencies: - vite: 5.0.2(@types/node@18.17.5) - vue: 3.3.8(typescript@5.1.6) + vite: 5.0.11(@types/node@18.17.5) + vue: 3.4.15(typescript@5.1.6) dev: true /@vitest/coverage-v8@0.34.0(vitest@0.34.0): @@ -5999,6 +5885,16 @@ packages: source-map-js: 1.0.2 dev: true + /@vue/compiler-core@3.4.15: + resolution: {integrity: sha512-XcJQVOaxTKCnth1vCxEChteGuwG6wqnUHxAm1DO3gCz0+uXKaJNx8/digSz4dLALCy8n2lKq24jSUs8segoqIw==} + dependencies: + '@babel/parser': 7.23.6 + '@vue/shared': 3.4.15 + entities: 4.5.0 + estree-walker: 2.0.2 + source-map-js: 1.0.2 + dev: true + /@vue/compiler-dom@3.3.4: resolution: {integrity: sha512-wyM+OjOVpuUukIq6p5+nwHYtj9cFroz9cwkfmP9O1nzH68BenTTv0u7/ndggT8cIQlnBeOo6sUT/gvHcIkLA5w==} dependencies: @@ -6012,6 +5908,13 @@ packages: '@vue/shared': 3.3.8 dev: true + /@vue/compiler-dom@3.4.15: + resolution: {integrity: sha512-wox0aasVV74zoXyblarOM3AZQz/Z+OunYcIHe1OsGclCHt8RsRm04DObjefaI82u6XDzv+qGWZ24tIsRAIi5MQ==} + dependencies: + '@vue/compiler-core': 3.4.15 + '@vue/shared': 3.4.15 + dev: true + /@vue/compiler-sfc@3.3.4: resolution: {integrity: sha512-6y/d8uw+5TkCuzBkgLS0v3lSM3hJDntFEiUORM11pQ/hKvkhSKZrXW6i69UyXlJQisJxuUEJKAWEqWbWsLeNKQ==} dependencies: @@ -6041,6 +5944,20 @@ packages: source-map-js: 1.0.2 dev: true + /@vue/compiler-sfc@3.4.15: + resolution: {integrity: sha512-LCn5M6QpkpFsh3GQvs2mJUOAlBQcCco8D60Bcqmf3O3w5a+KWS5GvYbrrJBkgvL1BDnTp+e8q0lXCLgHhKguBA==} + dependencies: + '@babel/parser': 7.23.6 + '@vue/compiler-core': 3.4.15 + '@vue/compiler-dom': 3.4.15 + '@vue/compiler-ssr': 3.4.15 + '@vue/shared': 3.4.15 + estree-walker: 2.0.2 + magic-string: 0.30.5 + postcss: 8.4.33 + source-map-js: 1.0.2 + dev: true + /@vue/compiler-ssr@3.3.4: resolution: {integrity: sha512-m0v6oKpup2nMSehwA6Uuu+j+wEwcy7QmwMkVNVfrV9P2qE5KshC6RwOCq8fjGS/Eak/uNb8AaWekfiXxbBB6gQ==} dependencies: @@ -6054,6 +5971,13 @@ packages: '@vue/shared': 3.3.8 dev: true + /@vue/compiler-ssr@3.4.15: + resolution: {integrity: sha512-1jdeQyiGznr8gjFDadVmOJqZiLNSsMa5ZgqavkPZ8O2wjHv0tVuAEsw5hTdUoUW4232vpBbL/wJhzVW/JwY1Uw==} + dependencies: + '@vue/compiler-dom': 3.4.15 + '@vue/shared': 3.4.15 + dev: true + /@vue/devtools-api@6.5.0: resolution: {integrity: sha512-o9KfBeaBmCKl10usN4crU53fYtC1r7jJwdGKjPT24t348rHxgfpZ0xL3Xm/gLUYnc0oTp8LAmrxOeLyu6tbk2Q==} dev: true @@ -6091,6 +6015,12 @@ packages: '@vue/shared': 3.3.8 dev: true + /@vue/reactivity@3.4.15: + resolution: {integrity: sha512-55yJh2bsff20K5O84MxSvXKPHHt17I2EomHznvFiJCAZpJTNW8IuLj1xZWMLELRhBK3kkFV/1ErZGHJfah7i7w==} + dependencies: + '@vue/shared': 3.4.15 + dev: true + /@vue/runtime-core@3.3.4: resolution: {integrity: sha512-R+bqxMN6pWO7zGI4OMlmvePOdP2c93GsHFM/siJI7O2nxFRzj55pLwkpCedEY+bTMgp5miZ8CxfIZo3S+gFqvA==} dependencies: @@ -6104,6 +6034,13 @@ packages: '@vue/shared': 3.3.8 dev: true + /@vue/runtime-core@3.4.15: + resolution: {integrity: sha512-6E3by5m6v1AkW0McCeAyhHTw+3y17YCOKG0U0HDKDscV4Hs0kgNT5G+GCHak16jKgcCDHpI9xe5NKb8sdLCLdw==} + dependencies: + '@vue/reactivity': 3.4.15 + '@vue/shared': 3.4.15 + dev: true + /@vue/runtime-dom@3.3.4: resolution: {integrity: sha512-Aj5bTJ3u5sFsUckRghsNjVTtxZQ1OyMWCr5dZRAPijF/0Vy4xEoRCwLyHXcj4D0UFbJ4lbx3gPTgg06K/GnPnQ==} dependencies: @@ -6119,6 +6056,14 @@ packages: csstype: 3.1.2 dev: true + /@vue/runtime-dom@3.4.15: + resolution: {integrity: sha512-EVW8D6vfFVq3V/yDKNPBFkZKGMFSvZrUQmx196o/v2tHKdwWdiZjYUBS+0Ez3+ohRyF8Njwy/6FH5gYJ75liUw==} + dependencies: + '@vue/runtime-core': 3.4.15 + '@vue/shared': 3.4.15 + csstype: 3.1.3 + dev: true + /@vue/server-renderer@3.3.4(vue@3.3.4): resolution: {integrity: sha512-Q6jDDzR23ViIb67v+vM1Dqntu+HUexQcsWKhhQa4ARVzxOY2HbC7QRW/ggkDBd5BU+uM1sV6XOAP0b216o34JQ==} peerDependencies: @@ -6138,6 +6083,16 @@ packages: vue: 3.3.8(typescript@5.0.4) dev: true + /@vue/server-renderer@3.4.15(vue@3.4.15): + resolution: {integrity: sha512-3HYzaidu9cHjrT+qGUuDhFYvF/j643bHC6uUN9BgM11DVy+pM6ATsG6uPBLnkwOgs7BpJABReLmpL3ZPAsUaqw==} + peerDependencies: + vue: 3.4.15 + dependencies: + '@vue/compiler-ssr': 3.4.15 + '@vue/shared': 3.4.15 + vue: 3.4.15(typescript@5.1.6) + dev: true + /@vue/shared@3.3.4: resolution: {integrity: sha512-7OjdcV8vQ74eiz1TZLzZP4JwqM5fA94K6yntPS5Z25r9HDuGNzaGdgvwKYq6S+MxwF0TFRwe50fIR/MYnakdkQ==} @@ -6145,6 +6100,10 @@ packages: resolution: {integrity: sha512-8PGwybFwM4x8pcfgqEQFy70NaQxASvOC5DJwLQfpArw1UDfUXrJkdxD3BhVTMS+0Lef/TU7YO0Jvr0jJY8T+mw==} dev: true + /@vue/shared@3.4.15: + resolution: {integrity: sha512-KzfPTxVaWfB+eGcGdbSf4CWdaXcGDqckoeXUh7SB3fZdEtzPCK2Vq9B/lRRL3yutax/LWITz+SwvgyOxz5V75g==} + dev: true + /@vueuse/core@10.1.0(vue@3.3.4): resolution: {integrity: sha512-3Znoa5m5RO+z4/C9w6DRaKTR3wCVJvD5rav8HTDGsr+7rOZRHtcgFJ8NcCs0ZvIpmev2kExTa311ns5j2RbzDQ==} dependencies: @@ -6169,20 +6128,20 @@ packages: - vue dev: true - /@vueuse/core@10.6.1(vue@3.3.8): - resolution: {integrity: sha512-Pc26IJbqgC9VG1u6VY/xrXXfxD33hnvxBnKrLlA2LJlyHII+BSrRoTPJgGYq7qZOu61itITFUnm6QbacwZ4H8Q==} + /@vueuse/core@10.7.2(vue@3.4.15): + resolution: {integrity: sha512-AOyAL2rK0By62Hm+iqQn6Rbu8bfmbgaIMXcE3TSr7BdQ42wnSFlwIdPjInO62onYsEMK/yDMU8C6oGfDAtZ2qQ==} dependencies: '@types/web-bluetooth': 0.0.20 - '@vueuse/metadata': 10.6.1 - '@vueuse/shared': 10.6.1(vue@3.3.8) - vue-demi: 0.14.6(vue@3.3.8) + '@vueuse/metadata': 10.7.2 + '@vueuse/shared': 10.7.2(vue@3.4.15) + vue-demi: 0.14.6(vue@3.4.15) transitivePeerDependencies: - '@vue/composition-api' - vue dev: true - /@vueuse/integrations@10.6.1(focus-trap@7.5.4)(vue@3.3.8): - resolution: {integrity: sha512-mPDupuofMJ4DPmtX/FfP1MajmWRzYDv8WSaTCo8LQ5kFznjWgmUQ16ApjYqgMquqffNY6+IRMdMgosLDRZOSZA==} + /@vueuse/integrations@10.7.2(focus-trap@7.5.4)(vue@3.4.15): + resolution: {integrity: sha512-+u3RLPFedjASs5EKPc69Ge49WNgqeMfSxFn+qrQTzblPXZg6+EFzhjarS5edj2qAf6xQ93f95TUxRwKStXj/sQ==} peerDependencies: async-validator: '*' axios: '*' @@ -6222,10 +6181,10 @@ packages: universal-cookie: optional: true dependencies: - '@vueuse/core': 10.6.1(vue@3.3.8) - '@vueuse/shared': 10.6.1(vue@3.3.8) + '@vueuse/core': 10.7.2(vue@3.4.15) + '@vueuse/shared': 10.7.2(vue@3.4.15) focus-trap: 7.5.4 - vue-demi: 0.14.6(vue@3.3.8) + vue-demi: 0.14.6(vue@3.4.15) transitivePeerDependencies: - '@vue/composition-api' - vue @@ -6239,8 +6198,8 @@ packages: resolution: {integrity: sha512-Ema3YhNOa4swDsV0V7CEY5JXvK19JI/o1szFO1iWxdFg3vhdFtCtSTP26PCvbUpnUtNHBY2wx5y3WDXND5Pvnw==} dev: true - /@vueuse/metadata@10.6.1: - resolution: {integrity: sha512-qhdwPI65Bgcj23e5lpGfQsxcy0bMjCAsUGoXkJ7DsoeDUdasbZ2DBa4dinFCOER3lF4gwUv+UD2AlA11zdzMFw==} + /@vueuse/metadata@10.7.2: + resolution: {integrity: sha512-kCWPb4J2KGrwLtn1eJwaJD742u1k5h6v/St5wFe8Quih90+k2a0JP8BS4Zp34XUuJqS2AxFYMb1wjUL8HfhWsQ==} dev: true /@vueuse/shared@10.1.0(vue@3.3.4): @@ -6261,10 +6220,10 @@ packages: - vue dev: true - /@vueuse/shared@10.6.1(vue@3.3.8): - resolution: {integrity: sha512-TECVDTIedFlL0NUfHWncf3zF9Gc4VfdxfQc8JFwoVZQmxpONhLxFrlm0eHQeidHj4rdTPL3KXJa0TZCk1wnc5Q==} + /@vueuse/shared@10.7.2(vue@3.4.15): + resolution: {integrity: sha512-qFbXoxS44pi2FkgFjPvF4h7c9oMDutpyBdcJdMYIMg9XyXli2meFMuaKn+UMgsClo//Th6+beeCgqweT/79BVA==} dependencies: - vue-demi: 0.14.6(vue@3.3.8) + vue-demi: 0.14.6(vue@3.4.15) transitivePeerDependencies: - '@vue/composition-api' - vue @@ -6990,7 +6949,7 @@ packages: engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: '@babel/template': 7.22.15 - '@babel/types': 7.23.0 + '@babel/types': 7.23.5 '@types/babel__core': 7.20.1 '@types/babel__traverse': 7.20.1 dev: true @@ -7433,18 +7392,10 @@ packages: engines: {node: '>=10'} dev: true - /character-entities-html4@2.1.0: - resolution: {integrity: sha512-1v7fgQRj6hnSwFpq1Eu0ynr/CDEw0rXo2B61qXrLNdHZmPKgb7fqS1a2JwF0rISo9q77jDI8VMEHoApn8qDoZA==} - dev: true - /character-entities-legacy@1.1.4: resolution: {integrity: sha512-3Xnr+7ZFS1uxeiUDvV02wQ+QDbc55o97tIV5zHScSPJpcLm/r0DFPcoY3tYRp+VZukxuMeKgXYmsXQHO05zQeA==} dev: true - /character-entities-legacy@3.0.0: - resolution: {integrity: sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ==} - dev: true - /character-entities@1.2.4: resolution: {integrity: sha512-iBMyeEHxfVnIakwOuDXpVkc54HijNgCyQB2w0VfGQThle6NXn50zU6V/u+LDhxHcDUPojn6Kpga3PTAD8W1bQw==} dev: true @@ -7666,10 +7617,6 @@ packages: delayed-stream: 1.0.0 dev: true - /comma-separated-tokens@2.0.3: - resolution: {integrity: sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==} - dev: true - /commander@10.0.1: resolution: {integrity: sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==} engines: {node: '>=14'} @@ -8230,6 +8177,10 @@ packages: /csstype@3.1.2: resolution: {integrity: sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ==} + /csstype@3.1.3: + resolution: {integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==} + dev: true + /cuint@0.2.2: resolution: {integrity: sha512-d4ZVpCW31eWwCMe1YT3ur7mUDnTXbgwyzaL320DrcRT45rfjYxkt5QWLrmOJ+/UEAI2+fQgKe/fCjR8l4TpRgw==} dev: true @@ -8949,12 +8900,6 @@ packages: resolution: {integrity: sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==} dev: true - /devlop@1.1.0: - resolution: {integrity: sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==} - dependencies: - dequal: 2.0.3 - dev: true - /didyoumean@1.2.2: resolution: {integrity: sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==} dev: false @@ -10730,88 +10675,6 @@ packages: type-fest: 0.8.1 dev: true - /hast-util-from-parse5@8.0.1: - resolution: {integrity: sha512-Er/Iixbc7IEa7r/XLtuG52zoqn/b3Xng/w6aZQ0xGVxzhw5xUFxcRqdPzP6yFi/4HBYRaifaI5fQ1RH8n0ZeOQ==} - dependencies: - '@types/hast': 3.0.3 - '@types/unist': 3.0.2 - devlop: 1.1.0 - hastscript: 8.0.0 - property-information: 6.4.0 - vfile: 6.0.1 - vfile-location: 5.0.2 - web-namespaces: 2.0.1 - dev: true - - /hast-util-parse-selector@4.0.0: - resolution: {integrity: sha512-wkQCkSYoOGCRKERFWcxMVMOcYE2K1AaNLU8DXS9arxnLOUEWbOXKXiJUNzEpqZ3JOKpnha3jkFrumEjVliDe7A==} - dependencies: - '@types/hast': 3.0.3 - dev: true - - /hast-util-raw@9.0.1: - resolution: {integrity: sha512-5m1gmba658Q+lO5uqL5YNGQWeh1MYWZbZmWrM5lncdcuiXuo5E2HT/CIOp0rLF8ksfSwiCVJ3twlgVRyTGThGA==} - dependencies: - '@types/hast': 3.0.3 - '@types/unist': 3.0.2 - '@ungap/structured-clone': 1.2.0 - hast-util-from-parse5: 8.0.1 - hast-util-to-parse5: 8.0.0 - html-void-elements: 3.0.0 - mdast-util-to-hast: 13.0.2 - parse5: 7.1.2 - unist-util-position: 5.0.0 - unist-util-visit: 5.0.0 - vfile: 6.0.1 - web-namespaces: 2.0.1 - zwitch: 2.0.4 - dev: true - - /hast-util-to-html@9.0.0: - resolution: {integrity: sha512-IVGhNgg7vANuUA2XKrT6sOIIPgaYZnmLx3l/CCOAK0PtgfoHrZwX7jCSYyFxHTrGmC6S9q8aQQekjp4JPZF+cw==} - dependencies: - '@types/hast': 3.0.3 - '@types/unist': 3.0.2 - ccount: 2.0.1 - comma-separated-tokens: 2.0.3 - hast-util-raw: 9.0.1 - hast-util-whitespace: 3.0.0 - html-void-elements: 3.0.0 - mdast-util-to-hast: 13.0.2 - property-information: 6.4.0 - space-separated-tokens: 2.0.2 - stringify-entities: 4.0.3 - zwitch: 2.0.4 - dev: true - - /hast-util-to-parse5@8.0.0: - resolution: {integrity: sha512-3KKrV5ZVI8if87DVSi1vDeByYrkGzg4mEfeu4alwgmmIeARiBLKCZS2uw5Gb6nU9x9Yufyj3iudm6i7nl52PFw==} - dependencies: - '@types/hast': 3.0.3 - comma-separated-tokens: 2.0.3 - devlop: 1.1.0 - property-information: 6.4.0 - space-separated-tokens: 2.0.2 - web-namespaces: 2.0.1 - zwitch: 2.0.4 - dev: true - - /hast-util-whitespace@3.0.0: - resolution: {integrity: sha512-88JUN06ipLwsnv+dVn+OIYOvAuvBMy/Qoi6O7mQHxdPXpjy+Cd6xRkWwux7DKO+4sYILtLBRIKgsdpS2gQc7qw==} - dependencies: - '@types/hast': 3.0.3 - dev: true - - /hastscript@8.0.0: - resolution: {integrity: sha512-dMOtzCEd3ABUeSIISmrETiKuyydk1w0pa+gE/uormcTpSYuaNJPbX1NU3JLyscSLjwAQM8bWMhhIlnCqnRvDTw==} - dependencies: - '@types/hast': 3.0.3 - comma-separated-tokens: 2.0.3 - hast-util-parse-selector: 4.0.0 - property-information: 6.4.0 - space-separated-tokens: 2.0.2 - dev: true - /heap@0.2.7: resolution: {integrity: sha512-2bsegYkkHO+h/9MGbn6KWcE45cHZgPANo5LXF7EvWdT0yT2EguSVO1nDgU5c8+ZOPwp2vMNa7YFsJhVcDR9Sdg==} dev: false @@ -10859,10 +10722,6 @@ packages: resolution: {integrity: sha512-9gux8QhvjRO/erSnDPv28noDZcPZmYE7e1vFsBLKLlRlKDSqNJYebj6Qz1TGd5lsRV+X+xYyjCKjuZdABinWjA==} dev: false - /html-void-elements@3.0.0: - resolution: {integrity: sha512-bEqo66MRXsUGxWHV5IP0PUiAWwoEjba4VCzg0LjFJBpchPaTfyfCKTG6bc5F8ucKec3q5y6qOdGyYTSBEvhCrg==} - dev: true - /htmlparser2@8.0.2: resolution: {integrity: sha512-GYdjWKDkbRLkZ5geuHs5NY1puJ+PXwP7+fHPRz06Eirsb9ugf6d8kkXav6ADhcODhFFPMIXyxkxSuMf3D6NCFA==} dependencies: @@ -11903,7 +11762,7 @@ packages: '@babel/generator': 7.23.0 '@babel/plugin-syntax-jsx': 7.22.5(@babel/core@7.22.10) '@babel/plugin-syntax-typescript': 7.22.5(@babel/core@7.22.10) - '@babel/types': 7.23.0 + '@babel/types': 7.23.5 '@jest/expect-utils': 29.6.2 '@jest/transform': 29.6.2 '@jest/types': 29.6.1 @@ -12838,19 +12697,6 @@ packages: unist-util-is: 5.2.1 dev: true - /mdast-util-to-hast@13.0.2: - resolution: {integrity: sha512-U5I+500EOOw9e3ZrclN3Is3fRpw8c19SMyNZlZ2IS+7vLsNzb2Om11VpIVOR+/0137GhZsFEF6YiKD5+0Hr2Og==} - dependencies: - '@types/hast': 3.0.3 - '@types/mdast': 4.0.3 - '@ungap/structured-clone': 1.2.0 - devlop: 1.1.0 - micromark-util-sanitize-uri: 2.0.0 - trim-lines: 3.0.1 - unist-util-position: 5.0.0 - unist-util-visit: 5.0.0 - dev: true - /mdast-util-to-markdown@1.5.0: resolution: {integrity: sha512-bbv7TPv/WC49thZPg3jXuqzuvI45IL2EVAr/KxF0BSdHsU0ceFHOmwQn6evxAh1GaoK/6GQ1wp4R4oW2+LFL/A==} dependencies: @@ -13106,13 +12952,6 @@ packages: micromark-util-symbol: 1.1.0 micromark-util-types: 1.1.0 - /micromark-util-character@2.0.1: - resolution: {integrity: sha512-3wgnrmEAJ4T+mGXAUfMvMAbxU9RDG43XmGce4j6CwPtVxB3vfwXSZ6KhFwDzZ3mZHhmPimMAXg71veiBGzeAZw==} - dependencies: - micromark-util-symbol: 2.0.0 - micromark-util-types: 2.0.0 - dev: true - /micromark-util-chunked@1.1.0: resolution: {integrity: sha512-Ye01HXpkZPNcV6FiyoW2fGZDUw4Yc7vT0E9Sad83+bEDiCJ1uXu0S3mr8WLpsz3HaG3x2q0HM6CTuPdcZcluFQ==} dependencies: @@ -13147,10 +12986,6 @@ packages: /micromark-util-encode@1.1.0: resolution: {integrity: sha512-EuEzTWSTAj9PA5GOAs992GzNh2dGQO52UvAbtSOMvXTxv3Criqb6IOzJUBCmEqrrXSblJIJBbFFv6zPxpreiJw==} - /micromark-util-encode@2.0.0: - resolution: {integrity: sha512-pS+ROfCXAGLWCOc8egcBvT0kf27GoWMqtdarNfDcjb6YLuV5cM3ioG45Ys2qOVqeqSbjaKg72vU+Wby3eddPsA==} - dev: true - /micromark-util-html-tag-name@1.2.0: resolution: {integrity: sha512-VTQzcuQgFUD7yYztuQFKXT49KghjtETQ+Wv/zUjGSGBioZnkA4P1XXZPT1FHeJA6RwRXSF47yvJ1tsJdoxwO+Q==} @@ -13171,14 +13006,6 @@ packages: micromark-util-encode: 1.1.0 micromark-util-symbol: 1.1.0 - /micromark-util-sanitize-uri@2.0.0: - resolution: {integrity: sha512-WhYv5UEcZrbAtlsnPuChHUAsu/iBPOVaEVsntLBIdpibO0ddy8OzavZz3iL2xVvBZOpolujSliP65Kq0/7KIYw==} - dependencies: - micromark-util-character: 2.0.1 - micromark-util-encode: 2.0.0 - micromark-util-symbol: 2.0.0 - dev: true - /micromark-util-subtokenize@1.1.0: resolution: {integrity: sha512-kUQHyzRoxvZO2PuLzMt2P/dwVsTiivCK8icYTeR+3WgbuPqfHgPPy7nFKbeqRivBvn/3N3GBiNC+JRTMSxEC7A==} dependencies: @@ -13190,17 +13017,9 @@ packages: /micromark-util-symbol@1.1.0: resolution: {integrity: sha512-uEjpEYY6KMs1g7QfJ2eX1SQEV+ZT4rUD3UcF6l57acZvLNK7PBZL+ty82Z1qhK1/yXIY4bdx04FKMgR0g4IAag==} - /micromark-util-symbol@2.0.0: - resolution: {integrity: sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==} - dev: true - /micromark-util-types@1.1.0: resolution: {integrity: sha512-ukRBgie8TIAcacscVHSiddHjO4k/q3pnedmzMQ4iwDcK0FtFCohKOlFbaOL/mPgfnPsL3C1ZyxJa4sbWrBl3jg==} - /micromark-util-types@2.0.0: - resolution: {integrity: sha512-oNh6S2WMHWRZrmutsRmDDfkzKtxF+bc2VxLC9dvtrDIRFln627VsFP6fLMgTryGDljgLPjkrzQSDcPrjPyDJ5w==} - dev: true - /micromark@2.11.4: resolution: {integrity: sha512-+WoovN/ppKolQOFIAajxi7Lu9kInbPxFuTBVEavFcL8eAfVstoc5MocPmqBeAdBOJV00uaVjegzH4+MA0DN/uA==} dependencies: @@ -13394,6 +13213,12 @@ packages: engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} hasBin: true + /nanoid@3.3.7: + resolution: {integrity: sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==} + engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} + hasBin: true + dev: true + /natural-compare-lite@1.4.0: resolution: {integrity: sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g==} dev: true @@ -14205,6 +14030,15 @@ packages: picocolors: 1.0.0 source-map-js: 1.0.2 + /postcss@8.4.33: + resolution: {integrity: sha512-Kkpbhhdjw2qQs2O2DGX+8m5OVqEcbB9HRBvuYM9pgrjEFUg30A9LmXNlTAUj4S9kgtGyrMbTzVjH7E+s5Re2yg==} + engines: {node: ^10 || ^12 || >=14} + dependencies: + nanoid: 3.3.7 + picocolors: 1.0.0 + source-map-js: 1.0.2 + dev: true + /preact@10.16.0: resolution: {integrity: sha512-XTSj3dJ4roKIC93pald6rWuB2qQJO9gO2iLLyTe87MrjQN+HklueLsmskbywEWqCHlclgz3/M4YLL2iBr9UmMA==} dev: true @@ -14285,10 +14119,6 @@ packages: sisteransi: 1.0.5 dev: true - /property-information@6.4.0: - resolution: {integrity: sha512-9t5qARVofg2xQqKtytzt+lZ4d1Qvj8t5B8fEwXK6qOfgRLgH/b13QlgEyDh033NOS31nXeFbYv7CLUDG1CeifQ==} - dev: true - /proxy-addr@2.0.7: resolution: {integrity: sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==} engines: {node: '>= 0.10'} @@ -15121,16 +14951,20 @@ packages: vscode-textmate: 8.0.0 dev: true - /shikiji-transformers@0.7.4: - resolution: {integrity: sha512-oykilNekcW2FnRGbvZm+RNWHYroSeCVMOaMMwAbxozZgpTdcJtHoA+1+MDFw6/o2hCkX88kKbxG6FwAZoUZ6WQ==} + /shikiji-core@0.9.19: + resolution: {integrity: sha512-AFJu/vcNT21t0e6YrfadZ+9q86gvPum6iywRyt1OtIPjPFe25RQnYJyxHQPMLKCCWA992TPxmEmbNcOZCAJclw==} + dev: true + + /shikiji-transformers@0.9.19: + resolution: {integrity: sha512-lGLI7Z8frQrIBbhZ74/eiJtxMoCQRbpaHEB+gcfvdIy+ZFaAtXncJGnc52932/UET+Y4GyKtwwC/vjWUCp+c/Q==} dependencies: - shikiji: 0.7.4 + shikiji: 0.9.19 dev: true - /shikiji@0.7.4: - resolution: {integrity: sha512-N5dmPvyhH/zfcsuWysUEAMwRJDMz26LUns2VEUs5y4Ozbf5jkAODU0Yswjcf/tZAwpFnk5x3y34dupFMnF2+NA==} + /shikiji@0.9.19: + resolution: {integrity: sha512-Kw2NHWktdcdypCj1GkKpXH4o6Vxz8B8TykPlPuLHOGSV8VkhoCLcFOH4k19K4LXAQYRQmxg+0X/eM+m2sLhAkg==} dependencies: - hast-util-to-html: 9.0.0 + shikiji-core: 0.9.19 dev: true /side-channel@1.0.4: @@ -15279,10 +15113,6 @@ packages: deprecated: Please use @jridgewell/sourcemap-codec instead dev: true - /space-separated-tokens@2.0.2: - resolution: {integrity: sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==} - dev: true - /spawn-command@0.0.2-1: resolution: {integrity: sha512-n98l9E2RMSJ9ON1AKisHzz7V42VDiBQGY6PB1BwRglz99wpVsSuGzQ+jOi6lFXBGVTCrRpltvjm+/XA+tpeJrg==} dev: true @@ -15521,13 +15351,6 @@ packages: dependencies: safe-buffer: 5.2.1 - /stringify-entities@4.0.3: - resolution: {integrity: sha512-BP9nNHMhhfcMbiuQKCqMjhDP5yBCAxsPu4pHFFzJ6Alo9dZgY4VLDPutXqIjpRiMoKdp7Av85Gr73Q5uH9k7+g==} - dependencies: - character-entities-html4: 2.1.0 - character-entities-legacy: 3.0.0 - dev: true - /stringify-object@3.3.0: resolution: {integrity: sha512-rHqiFh1elqCQ9WPLIC8I0Q/g/wj5J1eMkyoiD6eoQApWHP0FtlK7rqnhmabL5VUY9JQCcqwwvlOaSuutekgyrw==} engines: {node: '>=4'} @@ -15940,10 +15763,6 @@ packages: hasBin: true dev: true - /trim-lines@3.0.1: - resolution: {integrity: sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg==} - dev: true - /trim-newlines@3.0.1: resolution: {integrity: sha512-c1PTsA3tYrIsLGkJkzHF+w9F2EyxfXGo4UyJc4pFL++FMjnq0HJS69T3M7d//gKrFKwy429bouPescbjecU+Zw==} engines: {node: '>=8'} @@ -16315,18 +16134,6 @@ packages: '@types/unist': 2.0.7 dev: true - /unist-util-is@6.0.0: - resolution: {integrity: sha512-2qCTHimwdxLfz+YzdGfkqNlH0tLi9xjTnHddPmJwtIG9MGsdbutfTc4P+haPD7l7Cjxf/WZj+we5qfVPvvxfYw==} - dependencies: - '@types/unist': 3.0.2 - dev: true - - /unist-util-position@5.0.0: - resolution: {integrity: sha512-fucsC7HjXvkB5R3kTCO7kUjRdrS0BJt3M/FPxmHMBOm8JQi2BsHAHFsy27E0EolP8rp0NzXsJ+jNPyDWvOJZPA==} - dependencies: - '@types/unist': 3.0.2 - dev: true - /unist-util-stringify-position@2.0.3: resolution: {integrity: sha512-3faScn5I+hy9VleOq/qNbAd6pAx7iH5jYBMS9I1HgQVijz/4mv5Bvw5iw1sC/90CODiKo81G/ps8AJrISn687g==} dependencies: @@ -16338,12 +16145,6 @@ packages: dependencies: '@types/unist': 2.0.7 - /unist-util-stringify-position@4.0.0: - resolution: {integrity: sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==} - dependencies: - '@types/unist': 3.0.2 - dev: true - /unist-util-visit-parents@5.1.3: resolution: {integrity: sha512-x6+y8g7wWMyQhL1iZfhIPhDAs7Xwbn9nRosDXl7qoPTSCy0yNxnKc+hWokFifWQIDGi154rdUqKvbCa4+1kLhg==} dependencies: @@ -16351,13 +16152,6 @@ packages: unist-util-is: 5.2.1 dev: true - /unist-util-visit-parents@6.0.1: - resolution: {integrity: sha512-L/PqWzfTP9lzzEa6CKs0k2nARxTdZduw3zyh8d2NVBnsyvHjSX4TWse388YrrQKbvI8w20fGjGlhgT96WwKykw==} - dependencies: - '@types/unist': 3.0.2 - unist-util-is: 6.0.0 - dev: true - /unist-util-visit@4.1.2: resolution: {integrity: sha512-MSd8OUGISqHdVvfY9TPhyK2VdUrPgxkUtWSuMHF6XAAFuL4LokseigBnZtPnJMu+FbynTkFNnFlyjxpVKujMRg==} dependencies: @@ -16366,14 +16160,6 @@ packages: unist-util-visit-parents: 5.1.3 dev: true - /unist-util-visit@5.0.0: - resolution: {integrity: sha512-MR04uvD+07cwl/yhVuVWAtw+3GOR/knlL55Nd/wAdblk27GCVt3lqpTivy/tkJcZoNPzTwS1Y+KMojlLDhoTzg==} - dependencies: - '@types/unist': 3.0.2 - unist-util-is: 6.0.0 - unist-util-visit-parents: 6.0.1 - dev: true - /universalify@0.1.2: resolution: {integrity: sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==} engines: {node: '>= 4.0.0'} @@ -16389,45 +16175,6 @@ packages: engines: {node: '>= 10.0.0'} dev: true - /unocss@0.58.0(postcss@8.4.31)(rollup@2.79.1)(vite@4.4.12): - resolution: {integrity: sha512-MSPRHxBqWN+1AHGV+J5uUy4//e6ZBK6O+ISzD0qrXcCD/GNtxk1+lYjOK2ltkUiKX539+/KF91vNxzhhwEf+xA==} - engines: {node: '>=14'} - peerDependencies: - '@unocss/webpack': 0.58.0 - vite: ^2.9.0 || ^3.0.0-0 || ^4.0.0 || ^5.0.0-0 - peerDependenciesMeta: - '@unocss/webpack': - optional: true - vite: - optional: true - dependencies: - '@unocss/astro': 0.58.0(rollup@2.79.1)(vite@4.4.12) - '@unocss/cli': 0.58.0(rollup@2.79.1) - '@unocss/core': 0.58.0 - '@unocss/extractor-arbitrary-variants': 0.58.0 - '@unocss/postcss': 0.58.0(postcss@8.4.31) - '@unocss/preset-attributify': 0.58.0 - '@unocss/preset-icons': 0.58.0 - '@unocss/preset-mini': 0.58.0 - '@unocss/preset-tagify': 0.58.0 - '@unocss/preset-typography': 0.58.0 - '@unocss/preset-uno': 0.58.0 - '@unocss/preset-web-fonts': 0.58.0 - '@unocss/preset-wind': 0.58.0 - '@unocss/reset': 0.58.0 - '@unocss/transformer-attributify-jsx': 0.58.0 - '@unocss/transformer-attributify-jsx-babel': 0.58.0 - '@unocss/transformer-compile-class': 0.58.0 - '@unocss/transformer-directives': 0.58.0 - '@unocss/transformer-variant-group': 0.58.0 - '@unocss/vite': 0.58.0(rollup@2.79.1)(vite@4.4.12) - vite: 4.4.12(@types/node@18.17.5) - transitivePeerDependencies: - - postcss - - rollup - - supports-color - dev: true - /unocss@0.58.0(postcss@8.4.31)(rollup@2.79.1)(vite@4.5.0): resolution: {integrity: sha512-MSPRHxBqWN+1AHGV+J5uUy4//e6ZBK6O+ISzD0qrXcCD/GNtxk1+lYjOK2ltkUiKX539+/KF91vNxzhhwEf+xA==} engines: {node: '>=14'} @@ -16605,13 +16352,6 @@ packages: extsprintf: 1.3.0 dev: true - /vfile-location@5.0.2: - resolution: {integrity: sha512-NXPYyxyBSH7zB5U6+3uDdd6Nybz6o6/od9rk8bp9H8GR3L+cm/fC0uUTbqBmUTnMCUDslAGBOIKNfvvb+gGlDg==} - dependencies: - '@types/unist': 3.0.2 - vfile: 6.0.1 - dev: true - /vfile-message@3.1.4: resolution: {integrity: sha512-fa0Z6P8HUrQN4BZaX05SIVXic+7kE3b05PWAtPuYP9QLHsLKYR7/AlLW3NtOrpXRLeawpDLMsVkmk5DG0NXgWw==} dependencies: @@ -16619,13 +16359,6 @@ packages: unist-util-stringify-position: 3.0.3 dev: true - /vfile-message@4.0.2: - resolution: {integrity: sha512-jRDZ1IMLttGj41KcZvlrYAaI3CfqpLpfpf+Mfig13viT6NKvRzWZ+lXz0Y5D60w6uJIBAOGq9mSHf0gktF0duw==} - dependencies: - '@types/unist': 3.0.2 - unist-util-stringify-position: 4.0.0 - dev: true - /vfile@5.3.7: resolution: {integrity: sha512-r7qlzkgErKjobAmyNIkkSpizsFPYiUPuJb5pNW1RB4JcYVZhs4lIbVqk8XPk033CV/1z8ss5pkax8SuhGpcG8g==} dependencies: @@ -16635,14 +16368,6 @@ packages: vfile-message: 3.1.4 dev: true - /vfile@6.0.1: - resolution: {integrity: sha512-1bYqc7pt6NIADBJ98UiG0Bn/CHIVOoZ/IyEkqIruLg0mE1BKzkOXY2D6CSqQIcKqgadppE5lrxgWXJmXd7zZJw==} - dependencies: - '@types/unist': 3.0.2 - unist-util-stringify-position: 4.0.0 - vfile-message: 4.0.2 - dev: true - /vite-node@0.34.0(@types/node@18.17.5): resolution: {integrity: sha512-rGZMvpb052rjUwJA/a17xMfOibzNF7byMdRSTcN2Lw8uxX08s5EfjWW5mBkm3MSFTPctMSVtT2yC+8ShrZbT5g==} engines: {node: '>=v14.18.0'} @@ -16679,24 +16404,6 @@ packages: - supports-color dev: true - /vite-plugin-pwa@0.17.0(vite@4.4.12)(workbox-build@7.0.0)(workbox-window@7.0.0): - resolution: {integrity: sha512-cOyEG8EEc7JHmyMapTnjK2j0g2BIC3ErlmOHyGzVu8hqjyF9Jt6yWMmVNFtpA6v/NNyzP28ARf3vwzIAzR1kaw==} - engines: {node: '>=16.0.0'} - peerDependencies: - vite: ^3.1.0 || ^4.0.0 || ^5.0.0 - workbox-build: ^7.0.0 - workbox-window: ^7.0.0 - dependencies: - debug: 4.3.4(supports-color@8.1.1) - fast-glob: 3.3.2 - pretty-bytes: 6.1.1 - vite: 4.4.12(@types/node@18.17.5) - workbox-build: 7.0.0 - workbox-window: 7.0.0 - transitivePeerDependencies: - - supports-color - dev: true - /vite-plugin-pwa@0.17.0(vite@4.5.0)(workbox-build@7.0.0)(workbox-window@7.0.0): resolution: {integrity: sha512-cOyEG8EEc7JHmyMapTnjK2j0g2BIC3ErlmOHyGzVu8hqjyF9Jt6yWMmVNFtpA6v/NNyzP28ARf3vwzIAzR1kaw==} engines: {node: '>=16.0.0'} @@ -16787,8 +16494,8 @@ packages: fsevents: 2.3.3 dev: true - /vite@5.0.2(@types/node@18.17.5): - resolution: {integrity: sha512-6CCq1CAJCNM1ya2ZZA7+jS2KgnhbzvxakmlIjN24cF/PXhRMzpM/z8QgsVJA/Dm5fWUWnVEsmtBoMhmerPxT0g==} + /vite@5.0.11(@types/node@18.17.5): + resolution: {integrity: sha512-XBMnDjZcNAw/G1gEiskiM1v6yzM4GE5aMGvhWTlHAYYhxb7S3/V1s3m2LDHa8Vh6yIWYYB0iJwsEaS523c4oYA==} engines: {node: ^18.0.0 || >=20.0.0} hasBin: true peerDependencies: @@ -16817,7 +16524,7 @@ packages: dependencies: '@types/node': 18.17.5 esbuild: 0.19.6 - postcss: 8.4.31 + postcss: 8.4.33 rollup: 4.5.0 optionalDependencies: fsevents: 2.3.3 @@ -16871,12 +16578,12 @@ packages: - terser dev: true - /vitepress@1.0.0-rc.31(@algolia/client-search@4.19.1)(@types/node@18.17.5)(postcss@8.4.31)(search-insights@2.7.0)(typescript@5.1.6): - resolution: {integrity: sha512-ikH9pIjOOAbyoYAGBVfTz8TzuXp+UoWaIRMU4bw/oiTg8R65SbAaGKY84xx6TuL+f4VqUJ8lhzW82YyxSLvstA==} + /vitepress@1.0.0-rc.39(@algolia/client-search@4.19.1)(@types/node@18.17.5)(postcss@8.4.31)(search-insights@2.7.0)(typescript@5.1.6): + resolution: {integrity: sha512-EcgoRlAAp37WOxUOYv45oxyhLrcy3Upey+mKpqW3ldsg6Ol4trPndRBk2GO0QiSvEKlb9BMerk49D/bFICN6kg==} hasBin: true peerDependencies: markdown-it-mathjax3: ^4.3.2 - postcss: ^8.4.31 + postcss: ^8.4.33 peerDependenciesMeta: markdown-it-mathjax3: optional: true @@ -16886,19 +16593,19 @@ packages: '@docsearch/css': 3.5.2 '@docsearch/js': 3.5.2(@algolia/client-search@4.19.1)(search-insights@2.7.0) '@types/markdown-it': 13.0.7 - '@vitejs/plugin-vue': 4.5.0(vite@5.0.2)(vue@3.3.8) + '@vitejs/plugin-vue': 5.0.3(vite@5.0.11)(vue@3.4.15) '@vue/devtools-api': 6.5.1 - '@vueuse/core': 10.6.1(vue@3.3.8) - '@vueuse/integrations': 10.6.1(focus-trap@7.5.4)(vue@3.3.8) + '@vueuse/core': 10.7.2(vue@3.4.15) + '@vueuse/integrations': 10.7.2(focus-trap@7.5.4)(vue@3.4.15) focus-trap: 7.5.4 mark.js: 8.11.1 minisearch: 6.3.0 - mrmime: 1.0.1 postcss: 8.4.31 - shikiji: 0.7.4 - shikiji-transformers: 0.7.4 - vite: 5.0.2(@types/node@18.17.5) - vue: 3.3.8(typescript@5.1.6) + shikiji: 0.9.19 + shikiji-core: 0.9.19 + shikiji-transformers: 0.9.19 + vite: 5.0.11(@types/node@18.17.5) + vue: 3.4.15(typescript@5.1.6) transitivePeerDependencies: - '@algolia/client-search' - '@types/node' @@ -17057,7 +16764,7 @@ packages: dependencies: vue: 3.3.4 - /vue-demi@0.14.6(vue@3.3.8): + /vue-demi@0.14.6(vue@3.4.15): resolution: {integrity: sha512-8QA7wrYSHKaYgUxDA5ZC24w+eHm3sYCbp0EzcDwKqN3p6HqtTCGR/GVsPyZW92unff4UlcSh++lmqDWN3ZIq4w==} engines: {node: '>=12'} hasBin: true @@ -17069,7 +16776,7 @@ packages: '@vue/composition-api': optional: true dependencies: - vue: 3.3.8(typescript@5.1.6) + vue: 3.4.15(typescript@5.1.6) dev: true /vue@3.3.4: @@ -17097,19 +16804,19 @@ packages: typescript: 5.0.4 dev: true - /vue@3.3.8(typescript@5.1.6): - resolution: {integrity: sha512-5VSX/3DabBikOXMsxzlW8JyfeLKlG9mzqnWgLQLty88vdZL7ZJgrdgBOmrArwxiLtmS+lNNpPcBYqrhE6TQW5w==} + /vue@3.4.15(typescript@5.1.6): + resolution: {integrity: sha512-jC0GH4KkWLWJOEQjOpkqU1bQsBwf4R1rsFtw5GQJbjHVKWDzO6P0nWWBTmjp1xSemAioDFj1jdaK1qa3DnMQoQ==} peerDependencies: typescript: '*' peerDependenciesMeta: typescript: optional: true dependencies: - '@vue/compiler-dom': 3.3.8 - '@vue/compiler-sfc': 3.3.8 - '@vue/runtime-dom': 3.3.8 - '@vue/server-renderer': 3.3.8(vue@3.3.8) - '@vue/shared': 3.3.8 + '@vue/compiler-dom': 3.4.15 + '@vue/compiler-sfc': 3.4.15 + '@vue/runtime-dom': 3.4.15 + '@vue/server-renderer': 3.4.15(vue@3.4.15) + '@vue/shared': 3.4.15 typescript: 5.1.6 dev: true @@ -17177,10 +16884,6 @@ packages: minimalistic-assert: 1.0.1 dev: true - /web-namespaces@2.0.1: - resolution: {integrity: sha512-bKr1DkiNa2krS7qxNtdrtHAmzuYGFQLiQ13TsorsdT6ULTkPLKuu5+GsFpDlg6JFjUTwX2DyhMPG2be8uPrqsQ==} - dev: true - /web-streams-polyfill@3.2.1: resolution: {integrity: sha512-e0MO3wdXWKrLbL0DgGnUV7WHVuw9OUvL4hjgnPkIeEvESk74gAITi5G606JtZPp39cd8HA9VQzCIvA49LpPN5Q==} engines: {node: '>= 8'} From d07576676055064960c407d5eb135a7184ae6df2 Mon Sep 17 00:00:00 2001 From: Knut Sveidqvist Date: Thu, 18 Jan 2024 18:03:37 +0100 Subject: [PATCH 113/217] #3358 Doc updates after viewing the page --- cypress/platform/knsv2.html | 9 +- docs/config/setup/modules/defaultConfig.md | 2 +- docs/config/setup/modules/mermaidAPI.md | 2 +- docs/intro/examples.md | 247 ------------------ docs/syntax/block.md | 232 ++++++++-------- .../flowchart/swimlane/swimlaneRenderer.js | 3 + packages/mermaid/src/docs/syntax/block.md | 121 +++++---- pnpm-lock.yaml | 199 ++++++-------- ....timestamp-1696335530501-05072b5e79635.mjs | 10 + 9 files changed, 297 insertions(+), 528 deletions(-) delete mode 100644 docs/intro/examples.md diff --git a/cypress/platform/knsv2.html b/cypress/platform/knsv2.html index 1127a492f6..f8722e580e 100644 --- a/cypress/platform/knsv2.html +++ b/cypress/platform/knsv2.html @@ -65,9 +65,12 @@
     block-beta
    -columns 1
    -    B["A wide one in the middle"]
    -  style B fill:#f9F,stroke:#333,stroke-width:4px
    +  A space:2 B
    +  A-- "X" -->B
    +    
    +
    +flowchart LR
    +  A-- "X" -->B
         
     block-beta
    diff --git a/docs/config/setup/modules/defaultConfig.md b/docs/config/setup/modules/defaultConfig.md
    index 7a9b891c43..3d94055bea 100644
    --- a/docs/config/setup/modules/defaultConfig.md
    +++ b/docs/config/setup/modules/defaultConfig.md
    @@ -14,7 +14,7 @@
     
     #### Defined in
     
    -[defaultConfig.ts:272](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/defaultConfig.ts#L272)
    +[defaultConfig.ts:278](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/defaultConfig.ts#L278)
     
     ---
     
    diff --git a/docs/config/setup/modules/mermaidAPI.md b/docs/config/setup/modules/mermaidAPI.md
    index a1992c2254..9516d2b460 100644
    --- a/docs/config/setup/modules/mermaidAPI.md
    +++ b/docs/config/setup/modules/mermaidAPI.md
    @@ -96,7 +96,7 @@ mermaid.initialize(config);
     
     #### Defined in
     
    -[mermaidAPI.ts:608](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L608)
    +[mermaidAPI.ts:607](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L607)
     
     ## Functions
     
    diff --git a/docs/intro/examples.md b/docs/intro/examples.md
    deleted file mode 100644
    index a7089ea9df..0000000000
    --- a/docs/intro/examples.md
    +++ /dev/null
    @@ -1,247 +0,0 @@
    -> **Warning**
    ->
    -> ## THIS IS AN AUTOGENERATED FILE. DO NOT EDIT.
    ->
    -> ## Please edit the corresponding file in [/packages/mermaid/src/docs/intro/examples.md](../../packages/mermaid/src/docs/intro/examples.md).
    -
    -## Diagram Types
    -
    -### [Flowchart](../syntax/flowchart.md?id=flowcharts-basic-syntax)
    -
    -```mermaid-example
    -graph TD;
    -    A-->B;
    -    A-->C;
    -    B-->D;
    -    C-->D;
    -```
    -
    -```mermaid
    -graph TD;
    -    A-->B;
    -    A-->C;
    -    B-->D;
    -    C-->D;
    -```
    -
    -### [Sequence diagram](../syntax/sequenceDiagram.md)
    -
    -```mermaid-example
    -sequenceDiagram
    -    participant Alice
    -    participant Bob
    -    Alice->>John: Hello John, how are you?
    -    loop Healthcheck
    -        John->>John: Fight against hypochondria
    -    end
    -    Note right of John: Rational thoughts 
    prevail! - John-->>Alice: Great! - John->>Bob: How about you? - Bob-->>John: Jolly good! -``` - -```mermaid -sequenceDiagram - participant Alice - participant Bob - Alice->>John: Hello John, how are you? - loop Healthcheck - John->>John: Fight against hypochondria - end - Note right of John: Rational thoughts
    prevail! - John-->>Alice: Great! - John->>Bob: How about you? - Bob-->>John: Jolly good! -``` - -### [Gantt diagram](../syntax/gantt.md) - -```mermaid-example -gantt -dateFormat YYYY-MM-DD -title Adding GANTT diagram to mermaid -excludes weekdays 2014-01-10 - -section A section -Completed task :done, des1, 2014-01-06,2014-01-08 -Active task :active, des2, 2014-01-09, 3d -Future task : des3, after des2, 5d -Future task2 : des4, after des3, 5d -``` - -```mermaid -gantt -dateFormat YYYY-MM-DD -title Adding GANTT diagram to mermaid -excludes weekdays 2014-01-10 - -section A section -Completed task :done, des1, 2014-01-06,2014-01-08 -Active task :active, des2, 2014-01-09, 3d -Future task : des3, after des2, 5d -Future task2 : des4, after des3, 5d -``` - -### [Class diagram](../syntax/classDiagram.md) - -```mermaid-example -classDiagram -Class01 <|-- AveryLongClass : Cool -Class03 *-- Class04 -Class05 o-- Class06 -Class07 .. Class08 -Class09 --> C2 : Where am i? -Class09 --* C3 -Class09 --|> Class07 -Class07 : equals() -Class07 : Object[] elementData -Class01 : size() -Class01 : int chimp -Class01 : int gorilla -Class08 <--> C2: Cool label -``` - -```mermaid -classDiagram -Class01 <|-- AveryLongClass : Cool -Class03 *-- Class04 -Class05 o-- Class06 -Class07 .. Class08 -Class09 --> C2 : Where am i? -Class09 --* C3 -Class09 --|> Class07 -Class07 : equals() -Class07 : Object[] elementData -Class01 : size() -Class01 : int chimp -Class01 : int gorilla -Class08 <--> C2: Cool label -``` - -### [Git graph](../syntax/gitgraph.md) - -```mermaid-example - gitGraph - commit - commit - branch develop - commit - commit - commit - checkout main - commit - commit -``` - -```mermaid - gitGraph - commit - commit - branch develop - commit - commit - commit - checkout main - commit - commit -``` - -### [Entity Relationship Diagram - :exclamation: experimental](../syntax/entityRelationshipDiagram.md) - -```mermaid-example -erDiagram - CUSTOMER ||--o{ ORDER : places - ORDER ||--|{ LINE-ITEM : contains - CUSTOMER }|..|{ DELIVERY-ADDRESS : uses - -``` - -```mermaid -erDiagram - CUSTOMER ||--o{ ORDER : places - ORDER ||--|{ LINE-ITEM : contains - CUSTOMER }|..|{ DELIVERY-ADDRESS : uses - -``` - -### [User Journey Diagram](../syntax/userJourney.md) - -```mermaid-example -journey - title My working day - section Go to work - Make tea: 5: Me - Go upstairs: 3: Me - Do work: 1: Me, Cat - section Go home - Go downstairs: 5: Me - Sit down: 5: Me -``` - -```mermaid -journey - title My working day - section Go to work - Make tea: 5: Me - Go upstairs: 3: Me - Do work: 1: Me, Cat - section Go home - Go downstairs: 5: Me - Sit down: 5: Me -``` - -### [Quadrant Chart](../syntax/quadrantChart.md) - -```mermaid-example -quadrantChart - title Reach and engagement of campaigns - x-axis Low Reach --> High Reach - y-axis Low Engagement --> High Engagement - quadrant-1 We should expand - quadrant-2 Need to promote - quadrant-3 Re-evaluate - quadrant-4 May be improved - Campaign A: [0.3, 0.6] - Campaign B: [0.45, 0.23] - Campaign C: [0.57, 0.69] - Campaign D: [0.78, 0.34] - Campaign E: [0.40, 0.34] - Campaign F: [0.35, 0.78] -``` - -```mermaid -quadrantChart - title Reach and engagement of campaigns - x-axis Low Reach --> High Reach - y-axis Low Engagement --> High Engagement - quadrant-1 We should expand - quadrant-2 Need to promote - quadrant-3 Re-evaluate - quadrant-4 May be improved - Campaign A: [0.3, 0.6] - Campaign B: [0.45, 0.23] - Campaign C: [0.57, 0.69] - Campaign D: [0.78, 0.34] - Campaign E: [0.40, 0.34] - Campaign F: [0.35, 0.78] -``` - -### [XY Chart](../syntax/xyChart.md) - -```mermaid-example -xychart-beta - title "Sales Revenue" - x-axis [jan, feb, mar, apr, may, jun, jul, aug, sep, oct, nov, dec] - y-axis "Revenue (in $)" 4000 --> 11000 - bar [5000, 6000, 7500, 8200, 9500, 10500, 11000, 10200, 9200, 8500, 7000, 6000] - line [5000, 6000, 7500, 8200, 9500, 10500, 11000, 10200, 9200, 8500, 7000, 6000] -``` - -```mermaid -xychart-beta - title "Sales Revenue" - x-axis [jan, feb, mar, apr, may, jun, jul, aug, sep, oct, nov, dec] - y-axis "Revenue (in $)" 4000 --> 11000 - bar [5000, 6000, 7500, 8200, 9500, 10500, 11000, 10200, 9200, 8500, 7000, 6000] - line [5000, 6000, 7500, 8200, 9500, 10500, 11000, 10200, 9200, 8500, 7000, 6000] -``` diff --git a/docs/syntax/block.md b/docs/syntax/block.md index 29c5d7674a..c33f31301d 100644 --- a/docs/syntax/block.md +++ b/docs/syntax/block.md @@ -6,7 +6,41 @@ # Block Diagrams Documentation -## 1. Introduction to Block Diagrams +## Introduction to Block Diagrams + +```mermaid-example +block-beta +columns 1 + db(("DB")) + blockArrowId6<["   "]>(down) + block:ID + A + B["A wide one in the middle"] + C + end + space + D + ID --> D + C --> D + style B fill:#969,stroke:#333,stroke-width:4px +``` + +```mermaid +block-beta +columns 1 + db(("DB")) + blockArrowId6<["   "]>(down) + block:ID + A + B["A wide one in the middle"] + C + end + space + D + ID --> D + C --> D + style B fill:#969,stroke:#333,stroke-width:4px +``` ### Definition and Purpose @@ -14,6 +48,8 @@ Block diagrams are an intuitive and efficient way to represent complex systems, The primary purpose of block diagrams is to provide a high-level view of a system, allowing for easy understanding and analysis without delving into the intricate details of each component. This makes them particularly useful for simplifying complex systems and for explaining the overall structure and interaction of components within a system. +Many people use mermaid flowcharts for this purpose. A side-effect of this is that the automatic layout sometimes move shapes to positions that the diagram maker does not want. Block diagrams use a different approach. In this diagram we give the author full control over where the shapes are positioned. + ### General Use Cases Block diagrams have a wide range of applications across various industries and disciplines. Some of the key use cases include: @@ -181,12 +217,12 @@ To create a block with round edges, which can be used to represent a softer or m ```mermaid-example block-beta - id1(This is the text in the box) + id1("This is the text in the box") ``` ```mermaid block-beta - id1(This is the text in the box) + id1("This is the text in the box") ``` #### Example - Stadium-Shaped Block @@ -195,12 +231,12 @@ A stadium-shaped block, resembling an elongated circle, can be used for componen ```mermaid-example block-beta - id1([This is the text in the box]) + id1(["This is the text in the box"]) ``` ```mermaid block-beta - id1([This is the text in the box]) + id1(["This is the text in the box"]) ``` #### Example - Subroutine Shape @@ -209,12 +245,12 @@ For representing subroutines or contained processes, a block with double vertica ```mermaid-example block-beta - id1[[This is the text in the box]] + id1[["This is the text in the box"]] ``` ```mermaid block-beta - id1[[This is the text in the box]] + id1[["This is the text in the box"]] ``` #### Example - Cylindrical Shape @@ -223,12 +259,12 @@ The cylindrical shape is ideal for representing databases or storage components: ```mermaid-example block-beta - id1[(Database)] + id1[("Database")] ``` ```mermaid block-beta - id1[(Database)] + id1[("Database")] ``` #### Example - Circle Shape @@ -237,12 +273,12 @@ A circle can be used for centralized or pivotal components: ```mermaid-example block-beta - id1((This is the text in the circle)) + id1(("This is the text in the circle")) ``` ```mermaid block-beta - id1((This is the text in the circle)) + id1(("This is the text in the circle")) ``` #### Example - Asymmetric, Rhombus, and Hexagon Shapes @@ -253,36 +289,36 @@ For decision points, use a rhombus, and for unique or specialized processes, asy ```mermaid-example block-beta - id1>This is the text in the box] + id1>"This is the text in the box"] ``` ```mermaid block-beta - id1>This is the text in the box] + id1>"This is the text in the box"] ``` **Rhombus** ```mermaid-example block-beta - id1{This is the text in the box} + id1{"This is the text in the box"} ``` ```mermaid block-beta - id1{This is the text in the box} + id1{"This is the text in the box"} ``` **Hexagon** ```mermaid-example block-beta - id1{{This is the text in the box}} + id1{{"This is the text in the box"}} ``` ```mermaid block-beta - id1{{This is the text in the box}} + id1{{"This is the text in the box"}} ``` #### Example - Parallelogram and Trapezoid Shapes @@ -291,18 +327,18 @@ Parallelogram and trapezoid shapes are perfect for inputs/outputs and transition ```mermaid-example flowchart TD - id1[/This is the text in the box/] - id2[\This is the text in the box\] - A[/Christmas\] - B[\Go shopping/] + id1[/"This is the text in the box"/] + id2[\"This is the text in the box"\] + A[/"Christmas"\] + B[\"Go shopping"/] ``` ```mermaid flowchart TD - id1[/This is the text in the box/] - id2[\This is the text in the box\] - A[/Christmas\] - B[\Go shopping/] + id1[/"This is the text in the box"/] + id2[\"This is the text in the box"\] + A[/"Christmas"\] + B[\"Go shopping"/] ``` #### Example - Double Circle @@ -311,12 +347,12 @@ For highlighting critical or high-priority components, a double circle can be ef ```mermaid-example flowchart TD - id1(((This is the text in the circle))) + id1((("This is the text in the circle"))) ``` ```mermaid flowchart TD - id1(((This is the text in the circle))) + id1((("This is the text in the circle"))) ``` ### Block Arrows and Space Blocks @@ -387,11 +423,13 @@ A simple link with an arrow can be created to show direction or flow from one bl ```mermaid-example block-beta + A space B A-->B ``` ```mermaid block-beta + A space B A-->B ``` @@ -402,11 +440,13 @@ For connections that are less direct or to represent a different type of relatio ```mermaid-example block-beta + A space B A --- B ``` ```mermaid block-beta + A space B A --- B ``` @@ -421,12 +461,14 @@ To add text to a link, the syntax includes the text within the link definition: ```mermaid-example block-beta - A-- This is the text! ---B + A space:2 B + A-- "X" -->B ``` ```mermaid block-beta - A-- This is the text! ---B + A space:2 B + A-- "X" -->B ``` This example show how to add descriptive text to the links, enhancing the information conveyed by the diagram. @@ -440,26 +482,16 @@ A dotted link can be used to represent a weaker or less formal relationship: ```mermaid-example block-beta + A space:2 B A-.->B ``` ```mermaid block-beta + A space:2 B A-.->B ``` -For a more pronounced connection, a thick link can be used: - -```mermaid-example -block-beta - A==>B -``` - -```mermaid -block-beta - A==>B -``` - Example - Edges and Styles: ```mermaid-example @@ -476,7 +508,7 @@ columns 1 D ID --> D C --> D - style B fill:#f9F,stroke:#333,stroke-width:4px + style B fill:#939,stroke:#333,stroke-width:4px ``` ```mermaid @@ -493,7 +525,7 @@ columns 1 D ID --> D C --> D - style B fill:#f9F,stroke:#333,stroke-width:4px + style B fill:#939,stroke:#333,stroke-width:4px ``` ## 6. Styling and Customization @@ -510,15 +542,17 @@ To apply custom styles to a block, you can use the `style` keyword followed by t ```mermaid-example block-beta - id1(Start)-->id2(Stop) - style id1 fill:#f9f,stroke:#333,stroke-width:4px + id1 space id2 + id1("Start")-->id2("Stop") + style id1 fill:#636,stroke:#333,stroke-width:4px style id2 fill:#bbf,stroke:#f66,stroke-width:2px,color:#fff,stroke-dasharray: 5 5 ``` ```mermaid block-beta - id1(Start)-->id2(Stop) - style id1 fill:#f9f,stroke:#333,stroke-width:4px + id1 space id2 + id1("Start")-->id2("Stop") + style id1 fill:#636,stroke:#333,stroke-width:4px style id2 fill:#bbf,stroke:#f66,stroke-width:2px,color:#fff,stroke-dasharray: 5 5 ``` @@ -540,24 +574,28 @@ Illustrating a simple software system architecture with interconnected component ```mermaid-example block-beta - columns 2 - Frontend Backend - Frontend-->Backend - Database[(Database)] - Backend-->Database - class Frontend,Backend fill:#f96,stroke:#333; - class Database fill:#9f9,stroke:#333; + columns 3 + Frontend blockArrowId6<["  "]>(right) Backend + space:2 down<["  "]>(down) + Disk left<["  "]>(left) Database[("Database")] + + classDef front fill:#696,stroke:#333; + classDef back fill:#969,stroke:#333; + class Frontend front + class Backend,Database back ``` ```mermaid block-beta - columns 2 - Frontend Backend - Frontend-->Backend - Database[(Database)] - Backend-->Database - class Frontend,Backend fill:#f96,stroke:#333; - class Database fill:#9f9,stroke:#333; + columns 3 + Frontend blockArrowId6<["  "]>(right) Backend + space:2 down<["  "]>(down) + Disk left<["  "]>(left) Database[("Database")] + + classDef front fill:#696,stroke:#333; + classDef back fill:#969,stroke:#333; + class Frontend front + class Backend,Database back ``` This example shows a basic architecture with a frontend, backend, and database. The blocks are styled to differentiate between types of components. @@ -568,41 +606,35 @@ Representing a business process flow with decision points and multiple stages: ```mermaid-example block-beta - Start{Start} - Decision{Make Decision} - Process1[Process A] - Process2[Process B] - End((End)) - Start --> Decision - Decision -- Yes --> Process1 - Decision -- No --> Process2 - Process1 --> End - Process2 --> End - style Start fill:#f9f; - style End fill:#bbf; + columns 3 + Start(("Start")) space:2 + down<["  "]>(down) space:2 + Decision{{"Make Decision"}} right<["Yes"]>(right) Process1["Process A"] + downAgain<["No"]>(down) space r3<["Done"]>(down) + Process2["Process B"] r2<["Done"]>(right) End(("End")) + + style Start fill:#969; + style End fill:#696; ``` ```mermaid block-beta - Start{Start} - Decision{Make Decision} - Process1[Process A] - Process2[Process B] - End((End)) - Start --> Decision - Decision -- Yes --> Process1 - Decision -- No --> Process2 - Process1 --> End - Process2 --> End - style Start fill:#f9f; - style End fill:#bbf; + columns 3 + Start(("Start")) space:2 + down<["  "]>(down) space:2 + Decision{{"Make Decision"}} right<["Yes"]>(right) Process1["Process A"] + downAgain<["No"]>(down) space r3<["Done"]>(down) + Process2["Process B"] r2<["Done"]>(right) End(("End")) + + style Start fill:#969; + style End fill:#696; ``` This diagram depicts a simple decision-making process with two possible paths leading to an endpoint, demonstrating the use of different shapes and directional arrows. -### Real works Application Scenarios +### Real world Scenarios Block diagrams can be employed in a variety of real-world scenarios. Here are a few examples: @@ -614,22 +646,6 @@ These practical examples and scenarios underscore the utility of Mermaid block d The next section, 'Troubleshooting and Common Issues', will provide insights into resolving common challenges encountered when working with Mermaid block diagrams, ensuring a smooth diagramming experience. -```mermaid-example - -``` - -```mermaid - -``` - -```mermaid-example - -``` - -```mermaid - -``` - ## 8. Troubleshooting and Common Issues Working with Mermaid block diagrams can sometimes present challenges, especially as the complexity of the diagrams increases. This section aims to provide guidance on resolving common issues and offers tips for managing more intricate diagram structures. @@ -646,15 +662,17 @@ A common mistake is incorrect linking syntax, which can lead to unexpected resul A - B **Correction**: -Ensure that links between blocks are correctly specified with arrows (--> or ---) to define the direction and type of connection: +Ensure that links between blocks are correctly specified with arrows (--> or ---) to define the direction and type of connection. Also rememeber that one of the fundaments for block diagram is to give the author full control of where the boxes are positioned so in the example you need to add a space between the boxes: ```mermaid-example block-beta + A space B A --> B ``` ```mermaid block-beta + A space B A --> B ``` @@ -665,13 +683,13 @@ Applying styles in the wrong context or with incorrect syntax can lead to blocks ```mermaid-example block-beta A - style A fill#f9f; + style A fill#969; ``` ```mermaid block-beta A - style A fill#f9f; + style A fill#969; ``` **Correction:** @@ -680,14 +698,14 @@ Correct the syntax by ensuring proper separation of style properties with commas ```mermaid-example block-beta A - style A fill:#f9f,stroke:#333; + style A fill:#969,stroke:#333; ``` ```mermaid block-beta A - style A fill:#f9f,stroke:#333; + style A fill:#969,stroke:#333; ``` diff --git a/packages/mermaid/src/diagrams/flowchart/swimlane/swimlaneRenderer.js b/packages/mermaid/src/diagrams/flowchart/swimlane/swimlaneRenderer.js index c49c30f4ec..a34ba02dd7 100644 --- a/packages/mermaid/src/diagrams/flowchart/swimlane/swimlaneRenderer.js +++ b/packages/mermaid/src/diagrams/flowchart/swimlane/swimlaneRenderer.js @@ -27,7 +27,10 @@ export const setConf = function (cnf) { * @param element * @param graph * @param layout + * @param vert * @param elem + * @param g + * @param id * @param conf */ async function swimlaneRender(layout, vert, elem, g, id, conf) { diff --git a/packages/mermaid/src/docs/syntax/block.md b/packages/mermaid/src/docs/syntax/block.md index b1067d5b36..9186d68c6a 100644 --- a/packages/mermaid/src/docs/syntax/block.md +++ b/packages/mermaid/src/docs/syntax/block.md @@ -5,7 +5,24 @@ outline: 'deep' # shows all h3 headings in outline in Vitepress # Block Diagrams Documentation -## 1. Introduction to Block Diagrams +## Introduction to Block Diagrams + +```mermaid +block-beta +columns 1 + db(("DB")) + blockArrowId6<["   "]>(down) + block:ID + A + B["A wide one in the middle"] + C + end + space + D + ID --> D + C --> D + style B fill:#969,stroke:#333,stroke-width:4px +``` ### Definition and Purpose @@ -13,6 +30,8 @@ Block diagrams are an intuitive and efficient way to represent complex systems, The primary purpose of block diagrams is to provide a high-level view of a system, allowing for easy understanding and analysis without delving into the intricate details of each component. This makes them particularly useful for simplifying complex systems and for explaining the overall structure and interaction of components within a system. +Many people use mermaid flowcharts for this purpose. A side-effect of this is that the automatic layout sometimes move shapes to positions that the diagram maker does not want. Block diagrams use a different approach. In this diagram we give the author full control over where the shapes are positioned. + ### General Use Cases Block diagrams have a wide range of applications across various industries and disciplines. Some of the key use cases include: @@ -145,7 +164,7 @@ To create a block with round edges, which can be used to represent a softer or m ```mermaid-example block-beta - id1(This is the text in the box) + id1("This is the text in the box") ``` #### Example - Stadium-Shaped Block @@ -154,7 +173,7 @@ A stadium-shaped block, resembling an elongated circle, can be used for componen ```mermaid-example block-beta - id1([This is the text in the box]) + id1(["This is the text in the box"]) ``` #### Example - Subroutine Shape @@ -163,7 +182,7 @@ For representing subroutines or contained processes, a block with double vertica ```mermaid-example block-beta - id1[[This is the text in the box]] + id1[["This is the text in the box"]] ``` #### Example - Cylindrical Shape @@ -172,7 +191,7 @@ The cylindrical shape is ideal for representing databases or storage components: ```mermaid-example block-beta - id1[(Database)] + id1[("Database")] ``` #### Example - Circle Shape @@ -181,7 +200,7 @@ A circle can be used for centralized or pivotal components: ```mermaid-example block-beta - id1((This is the text in the circle)) + id1(("This is the text in the circle")) ``` #### Example - Asymmetric, Rhombus, and Hexagon Shapes @@ -192,21 +211,21 @@ For decision points, use a rhombus, and for unique or specialized processes, asy ```mermaid-example block-beta - id1>This is the text in the box] + id1>"This is the text in the box"] ``` **Rhombus** ```mermaid-example block-beta - id1{This is the text in the box} + id1{"This is the text in the box"} ``` **Hexagon** ```mermaid-example block-beta - id1{{This is the text in the box}} + id1{{"This is the text in the box"}} ``` #### Example - Parallelogram and Trapezoid Shapes @@ -215,10 +234,10 @@ Parallelogram and trapezoid shapes are perfect for inputs/outputs and transition ```mermaid-example flowchart TD - id1[/This is the text in the box/] - id2[\This is the text in the box\] - A[/Christmas\] - B[\Go shopping/] + id1[/"This is the text in the box"/] + id2[\"This is the text in the box"\] + A[/"Christmas"\] + B[\"Go shopping"/] ``` #### Example - Double Circle @@ -227,7 +246,7 @@ For highlighting critical or high-priority components, a double circle can be ef ```mermaid-example flowchart TD - id1(((This is the text in the circle))) + id1((("This is the text in the circle"))) ``` ### Block Arrows and Space Blocks @@ -281,6 +300,7 @@ A simple link with an arrow can be created to show direction or flow from one bl ```mermaid-example block-beta + A space B A-->B ``` @@ -291,6 +311,7 @@ For connections that are less direct or to represent a different type of relatio ```mermaid-example block-beta + A space B A --- B ``` @@ -305,7 +326,8 @@ To add text to a link, the syntax includes the text within the link definition: ```mermaid-example block-beta - A-- This is the text! ---B + A space:2 B + A-- "X" -->B ``` This example show how to add descriptive text to the links, enhancing the information conveyed by the diagram. @@ -319,16 +341,10 @@ A dotted link can be used to represent a weaker or less formal relationship: ```mermaid-example block-beta + A space:2 B A-.->B ``` -For a more pronounced connection, a thick link can be used: - -```mermaid-example -block-beta - A==>B -``` - Example - Edges and Styles: ```mermaid-example @@ -345,7 +361,7 @@ columns 1 D ID --> D C --> D - style B fill:#f9F,stroke:#333,stroke-width:4px + style B fill:#939,stroke:#333,stroke-width:4px ``` ## 6. Styling and Customization @@ -362,8 +378,9 @@ To apply custom styles to a block, you can use the `style` keyword followed by t ```mermaid-example block-beta - id1(Start)-->id2(Stop) - style id1 fill:#f9f,stroke:#333,stroke-width:4px + id1 space id2 + id1("Start")-->id2("Stop") + style id1 fill:#636,stroke:#333,stroke-width:4px style id2 fill:#bbf,stroke:#f66,stroke-width:2px,color:#fff,stroke-dasharray: 5 5 ``` @@ -385,13 +402,15 @@ Illustrating a simple software system architecture with interconnected component ```mermaid block-beta - columns 2 - Frontend Backend - Frontend-->Backend - Database[(Database)] - Backend-->Database - class Frontend,Backend fill:#f96,stroke:#333; - class Database fill:#9f9,stroke:#333; + columns 3 + Frontend blockArrowId6<["  "]>(right) Backend + space:2 down<["  "]>(down) + Disk left<["  "]>(left) Database[("Database")] + + classDef front fill:#696,stroke:#333; + classDef back fill:#969,stroke:#333; + class Frontend front + class Backend,Database back ``` This example shows a basic architecture with a frontend, backend, and database. The blocks are styled to differentiate between types of components. @@ -402,24 +421,21 @@ Representing a business process flow with decision points and multiple stages: ```mermaid-example block-beta - Start{Start} - Decision{Make Decision} - Process1[Process A] - Process2[Process B] - End((End)) - Start --> Decision - Decision -- Yes --> Process1 - Decision -- No --> Process2 - Process1 --> End - Process2 --> End - style Start fill:#f9f; - style End fill:#bbf; + columns 3 + Start(("Start")) space:2 + down<["  "]>(down) space:2 + Decision{{"Make Decision"}} right<["Yes"]>(right) Process1["Process A"] + downAgain<["No"]>(down) space r3<["Done"]>(down) + Process2["Process B"] r2<["Done"]>(right) End(("End")) + + style Start fill:#969; + style End fill:#696; ``` This diagram depicts a simple decision-making process with two possible paths leading to an endpoint, demonstrating the use of different shapes and directional arrows. -### Real works Application Scenarios +### Real world Scenarios Block diagrams can be employed in a variety of real-world scenarios. Here are a few examples: @@ -431,14 +447,6 @@ These practical examples and scenarios underscore the utility of Mermaid block d The next section, 'Troubleshooting and Common Issues', will provide insights into resolving common challenges encountered when working with Mermaid block diagrams, ensuring a smooth diagramming experience. -```mermaid-example - -``` - -```mermaid-example - -``` - ## 8. Troubleshooting and Common Issues Working with Mermaid block diagrams can sometimes present challenges, especially as the complexity of the diagrams increases. This section aims to provide guidance on resolving common issues and offers tips for managing more intricate diagram structures. @@ -457,10 +465,11 @@ block-beta ``` **Correction**: -Ensure that links between blocks are correctly specified with arrows (--> or ---) to define the direction and type of connection: +Ensure that links between blocks are correctly specified with arrows (--> or ---) to define the direction and type of connection. Also rememeber that one of the fundaments for block diagram is to give the author full control of where the boxes are positioned so in the example you need to add a space between the boxes: ```mermaid-example block-beta + A space B A --> B ``` @@ -471,7 +480,7 @@ Applying styles in the wrong context or with incorrect syntax can lead to blocks ```mermaid-example block-beta A - style A fill#f9f; + style A fill#969; ``` **Correction:** @@ -480,7 +489,7 @@ Correct the syntax by ensuring proper separation of style properties with commas ```mermaid-example block-beta A - style A fill:#f9f,stroke:#333; + style A fill:#969,stroke:#333; ``` diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index f6f1897f66..e39424af00 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -374,7 +374,7 @@ importers: version: 4.1.2 vitepress: specifier: ^1.0.0-alpha.72 - version: 1.0.0-alpha.72(@algolia/client-search@4.19.1)(@types/node@18.17.5)(search-insights@2.7.0) + version: 1.0.0-alpha.72(@algolia/client-search@4.19.1)(@types/node@18.17.5)(search-insights@2.7.0)(typescript@5.0.4) vitepress-plugin-search: specifier: ^1.0.4-alpha.20 version: 1.0.4-alpha.20(flexsearch@0.7.31)(vitepress@1.0.0-alpha.72)(vue@3.3.8) @@ -420,7 +420,7 @@ importers: dependencies: '@zenuml/core': specifier: ^3.0.6 - version: 3.0.6(ts-node@10.9.1) + version: 3.0.6(ts-node@10.9.1)(typescript@5.1.6) devDependencies: mermaid: specifier: workspace:^ @@ -481,6 +481,61 @@ importers: specifier: ^7.0.0 version: 7.0.0 + packages/mermaid/src/vitepress: + dependencies: + '@vueuse/core': + specifier: ^10.1.0 + version: 10.1.0(vue@3.3.4) + jiti: + specifier: ^1.18.2 + version: 1.18.2 + mermaid: + specifier: workspace:^ + version: link:../.. + vue: + specifier: ^3.3 + version: 3.3.4 + devDependencies: + '@iconify-json/carbon': + specifier: ^1.1.16 + version: 1.1.16 + '@unocss/reset': + specifier: ^0.58.0 + version: 0.58.0 + '@vite-pwa/vitepress': + specifier: ^0.3.0 + version: 0.3.0(vite-plugin-pwa@0.17.0) + '@vitejs/plugin-vue': + specifier: ^4.2.1 + version: 4.2.1(vite@4.5.0)(vue@3.3.4) + fast-glob: + specifier: ^3.2.12 + version: 3.2.12 + https-localhost: + specifier: ^4.7.1 + version: 4.7.1 + pathe: + specifier: ^1.1.0 + version: 1.1.0 + unocss: + specifier: ^0.58.0 + version: 0.58.0(postcss@8.4.31)(rollup@2.79.1)(vite@4.5.0) + unplugin-vue-components: + specifier: ^0.26.0 + version: 0.26.0(rollup@2.79.1)(vue@3.3.4) + vite: + specifier: ^4.4.12 + version: 4.5.0(@types/node@18.17.5) + vite-plugin-pwa: + specifier: ^0.17.0 + version: 0.17.0(vite@4.5.0)(workbox-build@7.0.0)(workbox-window@7.0.0) + vitepress: + specifier: 1.0.0-rc.31 + version: 1.0.0-rc.31(@algolia/client-search@4.19.1)(@types/node@18.17.5)(postcss@8.4.31)(search-insights@2.7.0)(typescript@5.1.6) + workbox-window: + specifier: ^7.0.0 + version: 7.0.0 + tests/webpack: dependencies: '@mermaid-js/mermaid-example-diagram': @@ -1372,7 +1427,6 @@ packages: /@babel/helper-string-parser@7.23.4: resolution: {integrity: sha512-803gmbQdqwdf4olxrX4AJyFBV/RTr3rSmOj0rKwesmzlfhYNDEs+/iOcznzpNWlJlIlTJC2QfPFcHB6DlzdVLQ==} engines: {node: '>=6.9.0'} - dev: true /@babel/helper-validator-identifier@7.22.20: resolution: {integrity: sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==} @@ -1455,7 +1509,6 @@ packages: hasBin: true dependencies: '@babel/types': 7.23.5 - dev: true /@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@7.22.5(@babel/core@7.23.5): resolution: {integrity: sha512-NP1M5Rf+u2Gw9qfSO4ihjcTGW5zXTi36ITLd4/EoAcEhIZ0yjMqmftDNl3QC19CX7olhrjpyU454g/2W7X0jvQ==} @@ -2547,7 +2600,6 @@ packages: '@babel/helper-string-parser': 7.23.4 '@babel/helper-validator-identifier': 7.22.20 to-fast-properties: 2.0.0 - dev: true /@bcherny/json-schema-ref-parser@9.0.9: resolution: {integrity: sha512-vmEmnJCfpkLdas++9OYg6riIezTYqTHpqUTODJzHLzs5UnXujbOJW9VwcVCnyo1mVRt32FRr23iXBx/sX8YbeQ==} @@ -4397,21 +4449,6 @@ packages: picomatch: 2.3.1 dev: true - /@rollup/pluginutils@5.0.5(rollup@2.79.1): - resolution: {integrity: sha512-6aEYR910NyP73oHiJglti74iRyOwgFU4x3meH/H8OJx6Ry0j6cOVZ5X/wTvub7G7Ao6qaHBEaNsV3GLJkSsF+Q==} - engines: {node: '>=14.0.0'} - peerDependencies: - rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0 - peerDependenciesMeta: - rollup: - optional: true - dependencies: - '@types/estree': 1.0.1 - estree-walker: 2.0.2 - picomatch: 2.3.1 - rollup: 2.79.1 - dev: true - /@rollup/pluginutils@5.1.0(rollup@2.79.1): resolution: {integrity: sha512-XTIWOPPcpvyKI6L1NHo0lFlCyznUEyPmPY1mc3KpPVDYulHSTvyeLNVW00QTLIAFNhR3kYnJTQHeGqU4M3n09g==} engines: {node: '>=14.0.0'} @@ -5199,10 +5236,6 @@ packages: resolution: {integrity: sha512-oh8q2Zc32S6gd/j50GowEjKLoOVOwHP/bWVjKJInBwQqdOYMdPrf1oVlelTlyfFK3CKxL1uahMDAr+vy8T7yMQ==} dev: false - /@types/web-bluetooth@0.0.17: - resolution: {integrity: sha512-4p9vcSmxAayx72yn70joFoL44c9MO/0+iVEBIQXe3v2h2SiAsEIo/G5v6ObFWvNKRFjbrVadNf9LqEEZeQPzdA==} - dev: true - /@types/web-bluetooth@0.0.20: resolution: {integrity: sha512-g9gZnnXVq7gM7v3tJCWV/qw7w+KeOlSHAhgF9RytFyifW6AF61hdT2ucrYhPq9hLs5JIryeupHV3qGk95dH9ow==} dev: true @@ -5791,15 +5824,15 @@ packages: vue: 3.3.4 dev: true - /@vitejs/plugin-vue@4.2.3(vite@4.5.0)(vue@3.3.4): - resolution: {integrity: sha512-R6JDUfiZbJA9cMiguQ7jxALsgiprjBeHL5ikpXfJCH62pPHtI+JdJ5xWj6Ev73yXSlYl86+blXn1kZHQ7uElxw==} + /@vitejs/plugin-vue@4.5.0(vite@4.5.0)(vue@3.3.8): + resolution: {integrity: sha512-a2WSpP8X8HTEww/U00bU4mX1QpLINNuz/2KMNpLsdu3BzOpak3AGI1CJYBTXcc4SPhaD0eNRUp7IyQK405L5dQ==} engines: {node: ^14.18.0 || >=16.0.0} peerDependencies: - vite: ^4.0.0 + vite: ^4.0.0 || ^5.0.0 vue: ^3.2.25 dependencies: vite: 4.5.0(@types/node@18.17.5) - vue: 3.3.4 + vue: 3.3.8(typescript@5.0.4) dev: true /@vitejs/plugin-vue@4.5.0(vite@5.0.2)(vue@3.3.8): @@ -5887,7 +5920,7 @@ packages: pretty-format: 29.6.2 dev: true - /@vue/compat@3.3.4(vue@3.3.4): + /@vue/compat@3.3.4(vue@3.3.8): resolution: {integrity: sha512-VwAsPqUqRJVxeLQPUC03Sa5d+T8UG2Qv4VItq74KmNvtQlRXICpa/sqq12BcyBB4Tz1U5paOEZxWCUoXkrZ9QQ==} peerDependencies: vue: 3.3.4 @@ -5895,7 +5928,7 @@ packages: '@babel/parser': 7.23.0 estree-walker: 2.0.2 source-map-js: 1.0.2 - vue: 3.3.4 + vue: 3.3.8(typescript@5.1.6) dev: false /@vue/compiler-core@3.3.4: @@ -5909,11 +5942,10 @@ packages: /@vue/compiler-core@3.3.8: resolution: {integrity: sha512-hN/NNBUECw8SusQvDSqqcVv6gWq8L6iAktUR0UF3vGu2OhzRqcOiAno0FmBJWwxhYEXRlQJT5XnoKsVq1WZx4g==} dependencies: - '@babel/parser': 7.23.0 + '@babel/parser': 7.23.5 '@vue/shared': 3.3.8 estree-walker: 2.0.2 source-map-js: 1.0.2 - dev: true /@vue/compiler-dom@3.3.4: resolution: {integrity: sha512-wyM+OjOVpuUukIq6p5+nwHYtj9cFroz9cwkfmP9O1nzH68BenTTv0u7/ndggT8cIQlnBeOo6sUT/gvHcIkLA5w==} @@ -5926,12 +5958,11 @@ packages: dependencies: '@vue/compiler-core': 3.3.8 '@vue/shared': 3.3.8 - dev: true /@vue/compiler-sfc@3.3.4: resolution: {integrity: sha512-6y/d8uw+5TkCuzBkgLS0v3lSM3hJDntFEiUORM11pQ/hKvkhSKZrXW6i69UyXlJQisJxuUEJKAWEqWbWsLeNKQ==} dependencies: - '@babel/parser': 7.23.0 + '@babel/parser': 7.23.5 '@vue/compiler-core': 3.3.4 '@vue/compiler-dom': 3.3.4 '@vue/compiler-ssr': 3.3.4 @@ -5945,7 +5976,7 @@ packages: /@vue/compiler-sfc@3.3.8: resolution: {integrity: sha512-WMzbUrlTjfYF8joyT84HfwwXo+8WPALuPxhy+BZ6R4Aafls+jDBnSz8PDz60uFhuqFbl3HxRfxvDzrUf3THwpA==} dependencies: - '@babel/parser': 7.23.0 + '@babel/parser': 7.23.5 '@vue/compiler-core': 3.3.8 '@vue/compiler-dom': 3.3.8 '@vue/compiler-ssr': 3.3.8 @@ -5955,7 +5986,6 @@ packages: magic-string: 0.30.5 postcss: 8.4.31 source-map-js: 1.0.2 - dev: true /@vue/compiler-ssr@3.3.4: resolution: {integrity: sha512-m0v6oKpup2nMSehwA6Uuu+j+wEwcy7QmwMkVNVfrV9P2qE5KshC6RwOCq8fjGS/Eak/uNb8AaWekfiXxbBB6gQ==} @@ -5968,7 +5998,6 @@ packages: dependencies: '@vue/compiler-dom': 3.3.8 '@vue/shared': 3.3.8 - dev: true /@vue/devtools-api@6.5.0: resolution: {integrity: sha512-o9KfBeaBmCKl10usN4crU53fYtC1r7jJwdGKjPT24t348rHxgfpZ0xL3Xm/gLUYnc0oTp8LAmrxOeLyu6tbk2Q==} @@ -5994,7 +6023,6 @@ packages: '@vue/shared': 3.3.8 estree-walker: 2.0.2 magic-string: 0.30.5 - dev: true /@vue/reactivity@3.3.4: resolution: {integrity: sha512-kLTDLwd0B1jG08NBF3R5rqULtv/f8x3rOFByTDz4J53ttIQEDmALqKqXY0J+XQeN0aV2FBxY8nJDf88yvOPAqQ==} @@ -6005,7 +6033,6 @@ packages: resolution: {integrity: sha512-ctLWitmFBu6mtddPyOKpHg8+5ahouoTCRtmAHZAXmolDtuZXfjL2T3OJ6DL6ezBPQB1SmMnpzjiWjCiMYmpIuw==} dependencies: '@vue/shared': 3.3.8 - dev: true /@vue/runtime-core@3.3.4: resolution: {integrity: sha512-R+bqxMN6pWO7zGI4OMlmvePOdP2c93GsHFM/siJI7O2nxFRzj55pLwkpCedEY+bTMgp5miZ8CxfIZo3S+gFqvA==} @@ -6018,7 +6045,6 @@ packages: dependencies: '@vue/reactivity': 3.3.8 '@vue/shared': 3.3.8 - dev: true /@vue/runtime-dom@3.3.4: resolution: {integrity: sha512-Aj5bTJ3u5sFsUckRghsNjVTtxZQ1OyMWCr5dZRAPijF/0Vy4xEoRCwLyHXcj4D0UFbJ4lbx3gPTgg06K/GnPnQ==} @@ -6033,7 +6059,6 @@ packages: '@vue/runtime-core': 3.3.8 '@vue/shared': 3.3.8 csstype: 3.1.2 - dev: true /@vue/server-renderer@3.3.4(vue@3.3.4): resolution: {integrity: sha512-Q6jDDzR23ViIb67v+vM1Dqntu+HUexQcsWKhhQa4ARVzxOY2HbC7QRW/ggkDBd5BU+uM1sV6XOAP0b216o34JQ==} @@ -6051,15 +6076,13 @@ packages: dependencies: '@vue/compiler-ssr': 3.3.8 '@vue/shared': 3.3.8 - vue: 3.3.8(typescript@5.0.4) - dev: true + vue: 3.3.8(typescript@5.1.6) /@vue/shared@3.3.4: resolution: {integrity: sha512-7OjdcV8vQ74eiz1TZLzZP4JwqM5fA94K6yntPS5Z25r9HDuGNzaGdgvwKYq6S+MxwF0TFRwe50fIR/MYnakdkQ==} /@vue/shared@3.3.8: resolution: {integrity: sha512-8PGwybFwM4x8pcfgqEQFy70NaQxASvOC5DJwLQfpArw1UDfUXrJkdxD3BhVTMS+0Lef/TU7YO0Jvr0jJY8T+mw==} - dev: true /@vueuse/core@10.1.0(vue@3.3.4): resolution: {integrity: sha512-3Znoa5m5RO+z4/C9w6DRaKTR3wCVJvD5rav8HTDGsr+7rOZRHtcgFJ8NcCs0ZvIpmev2kExTa311ns5j2RbzDQ==} @@ -6067,23 +6090,11 @@ packages: '@types/web-bluetooth': 0.0.16 '@vueuse/metadata': 10.1.0 '@vueuse/shared': 10.1.0(vue@3.3.4) - vue-demi: 0.14.5(vue@3.3.4) - transitivePeerDependencies: - - '@vue/composition-api' - - vue - dev: false - - /@vueuse/core@10.3.0(vue@3.3.4): - resolution: {integrity: sha512-BEM5yxcFKb5btFjTSAFjTu5jmwoW66fyV9uJIP4wUXXU8aR5Hl44gndaaXp7dC5HSObmgbnR2RN+Un1p68Mf5Q==} - dependencies: - '@types/web-bluetooth': 0.0.17 - '@vueuse/metadata': 10.3.0 - '@vueuse/shared': 10.3.0(vue@3.3.4) vue-demi: 0.14.6(vue@3.3.4) transitivePeerDependencies: - '@vue/composition-api' - vue - dev: true + dev: false /@vueuse/core@10.6.1(vue@3.3.8): resolution: {integrity: sha512-Pc26IJbqgC9VG1u6VY/xrXXfxD33hnvxBnKrLlA2LJlyHII+BSrRoTPJgGYq7qZOu61itITFUnm6QbacwZ4H8Q==} @@ -6151,31 +6162,18 @@ packages: resolution: {integrity: sha512-cM28HjDEw5FIrPE9rgSPFZvQ0ZYnOLAOr8hl1XM6tFl80U3WAR5ROdnAqiYybniwP5gt9MKKAJAqd/ab2aHkqg==} dev: false - /@vueuse/metadata@10.3.0: - resolution: {integrity: sha512-Ema3YhNOa4swDsV0V7CEY5JXvK19JI/o1szFO1iWxdFg3vhdFtCtSTP26PCvbUpnUtNHBY2wx5y3WDXND5Pvnw==} - dev: true - /@vueuse/metadata@10.6.1: resolution: {integrity: sha512-qhdwPI65Bgcj23e5lpGfQsxcy0bMjCAsUGoXkJ7DsoeDUdasbZ2DBa4dinFCOER3lF4gwUv+UD2AlA11zdzMFw==} dev: true /@vueuse/shared@10.1.0(vue@3.3.4): resolution: {integrity: sha512-2X52ogu12i9DkKOQ01yeb/BKg9UO87RNnpm5sXkQvyORlbq8ONS5l39MYkjkeVWWjdT0teJru7a2S41dmHmqjQ==} - dependencies: - vue-demi: 0.14.5(vue@3.3.4) - transitivePeerDependencies: - - '@vue/composition-api' - - vue - dev: false - - /@vueuse/shared@10.3.0(vue@3.3.4): - resolution: {integrity: sha512-kGqCTEuFPMK4+fNWy6dUOiYmxGcUbtznMwBZLC1PubidF4VZY05B+Oht7Jh7/6x4VOWGpvu3R37WHi81cKpiqg==} dependencies: vue-demi: 0.14.6(vue@3.3.4) transitivePeerDependencies: - '@vue/composition-api' - vue - dev: true + dev: false /@vueuse/shared@10.6.1(vue@3.3.8): resolution: {integrity: sha512-TECVDTIedFlL0NUfHWncf3zF9Gc4VfdxfQc8JFwoVZQmxpONhLxFrlm0eHQeidHj4rdTPL3KXJa0TZCk1wnc5Q==} @@ -6390,13 +6388,13 @@ packages: resolution: {integrity: sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==} dev: true - /@zenuml/core@3.0.6(ts-node@10.9.1): + /@zenuml/core@3.0.6(ts-node@10.9.1)(typescript@5.1.6): resolution: {integrity: sha512-azEBVrl+ClCPhII92TbzBUFcWhIjlOPdEHVzF6eZXs5Oy4JlrfldS5pAZBHCFL4riOBsjZ5sHHmQLQg9V07T4Q==} engines: {node: '>=12.0.0'} dependencies: '@types/assert': 1.5.6 '@types/ramda': 0.28.25 - '@vue/compat': 3.3.4(vue@3.3.4) + '@vue/compat': 3.3.4(vue@3.3.8) antlr4: 4.11.0 color-string: 1.9.1 dom-to-image-more: 2.16.0 @@ -6409,10 +6407,11 @@ packages: postcss: 8.4.27 ramda: 0.28.0 tailwindcss: 3.3.3(ts-node@10.9.1) - vue: 3.3.4 - vuex: 4.1.0(vue@3.3.4) + vue: 3.3.8(typescript@5.1.6) + vuex: 4.1.0(vue@3.3.8) transitivePeerDependencies: - ts-node + - typescript dev: false /JSONSelect@0.4.0: @@ -8085,7 +8084,7 @@ packages: cspell-glob: 6.31.1 cspell-io: 6.31.1 cspell-lib: 6.31.1 - fast-glob: 3.3.1 + fast-glob: 3.3.2 fast-json-stable-stringify: 2.1.0 file-entry-cache: 6.0.1 get-stdin: 8.0.0 @@ -9821,17 +9820,6 @@ packages: micromatch: 4.0.5 dev: true - /fast-glob@3.3.1: - resolution: {integrity: sha512-kNFPyjhh5cKjrUltxs+wFx+ZkbRaxxmZ+X0ZU31SOsxCEtP9VPgtq2teZw1DebupL5GmDaNQ6yKMMVcM41iqDg==} - engines: {node: '>=8.6.0'} - dependencies: - '@nodelib/fs.stat': 2.0.5 - '@nodelib/fs.walk': 1.2.8 - glob-parent: 5.1.2 - merge2: 1.4.1 - micromatch: 4.0.5 - dev: true - /fast-glob@3.3.2: resolution: {integrity: sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==} engines: {node: '>=8.6.0'} @@ -10489,7 +10477,7 @@ packages: engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} dependencies: dir-glob: 3.0.1 - fast-glob: 3.3.1 + fast-glob: 3.3.2 ignore: 5.2.4 merge2: 1.4.1 slash: 4.0.0 @@ -16353,7 +16341,7 @@ packages: optional: true dependencies: '@antfu/utils': 0.7.6 - '@rollup/pluginutils': 5.0.5(rollup@2.79.1) + '@rollup/pluginutils': 5.1.0(rollup@2.79.1) chokidar: 3.5.3 debug: 4.3.4(supports-color@8.1.1) fast-glob: 3.3.2 @@ -16685,25 +16673,25 @@ packages: flexsearch: 0.7.31 glob-to-regexp: 0.4.1 markdown-it: 13.0.1 - vitepress: 1.0.0-alpha.72(@algolia/client-search@4.19.1)(@types/node@18.17.5)(search-insights@2.7.0) + vitepress: 1.0.0-alpha.72(@algolia/client-search@4.19.1)(@types/node@18.17.5)(search-insights@2.7.0)(typescript@5.0.4) vue: 3.3.8(typescript@5.0.4) dev: true - /vitepress@1.0.0-alpha.72(@algolia/client-search@4.19.1)(@types/node@18.17.5)(search-insights@2.7.0): + /vitepress@1.0.0-alpha.72(@algolia/client-search@4.19.1)(@types/node@18.17.5)(search-insights@2.7.0)(typescript@5.0.4): resolution: {integrity: sha512-Ou7fNE/OVYLrKGQMHSTVG6AcNsdv7tm4ACrdhx93SPMzEDj8UgIb4RFa5CTTowaYf3jeDGi2EAJlzXVC+IE3dg==} hasBin: true dependencies: '@docsearch/css': 3.5.1 '@docsearch/js': 3.5.1(@algolia/client-search@4.19.1)(search-insights@2.7.0) - '@vitejs/plugin-vue': 4.2.3(vite@4.5.0)(vue@3.3.4) + '@vitejs/plugin-vue': 4.5.0(vite@4.5.0)(vue@3.3.8) '@vue/devtools-api': 6.5.0 - '@vueuse/core': 10.3.0(vue@3.3.4) + '@vueuse/core': 10.6.1(vue@3.3.8) body-scroll-lock: 4.0.0-beta.0 mark.js: 8.11.1 minisearch: 6.1.0 shiki: 0.14.3 vite: 4.5.0(@types/node@18.17.5) - vue: 3.3.4 + vue: 3.3.8(typescript@5.0.4) transitivePeerDependencies: - '@algolia/client-search' - '@types/node' @@ -16718,6 +16706,7 @@ packages: - stylus - sugarss - terser + - typescript dev: true /vitepress@1.0.0-rc.31(@algolia/client-search@4.19.1)(@types/node@18.17.5)(postcss@8.4.31)(search-insights@2.7.0)(typescript@5.1.6): @@ -16877,21 +16866,6 @@ packages: resolution: {integrity: sha512-eOpPHogvorZRobNqJGhapa0JdwaxpjVvyBp0QIUMRMSf8ZAlqOdEquKuRmw9Qwu0qXtJIWqFtMkmvJjUZmMjVA==} dev: true - /vue-demi@0.14.5(vue@3.3.4): - resolution: {integrity: sha512-o9NUVpl/YlsGJ7t+xuqJKx8EBGf1quRhCiT6D/J0pfwmk9zUwYkC7yrF4SZCe6fETvSM3UNL2edcbYrSyc4QHA==} - engines: {node: '>=12'} - hasBin: true - requiresBuild: true - peerDependencies: - '@vue/composition-api': ^1.0.0-rc.1 - vue: ^3.0.0-0 || ^2.6.0 - peerDependenciesMeta: - '@vue/composition-api': - optional: true - dependencies: - vue: 3.3.4 - dev: false - /vue-demi@0.14.6(vue@3.3.4): resolution: {integrity: sha512-8QA7wrYSHKaYgUxDA5ZC24w+eHm3sYCbp0EzcDwKqN3p6HqtTCGR/GVsPyZW92unff4UlcSh++lmqDWN3ZIq4w==} engines: {node: '>=12'} @@ -16905,7 +16879,7 @@ packages: optional: true dependencies: vue: 3.3.4 - dev: true + dev: false /vue-demi@0.14.6(vue@3.3.8): resolution: {integrity: sha512-8QA7wrYSHKaYgUxDA5ZC24w+eHm3sYCbp0EzcDwKqN3p6HqtTCGR/GVsPyZW92unff4UlcSh++lmqDWN3ZIq4w==} @@ -16961,15 +16935,14 @@ packages: '@vue/server-renderer': 3.3.8(vue@3.3.8) '@vue/shared': 3.3.8 typescript: 5.1.6 - dev: true - /vuex@4.1.0(vue@3.3.4): + /vuex@4.1.0(vue@3.3.8): resolution: {integrity: sha512-hmV6UerDrPcgbSy9ORAtNXDr9M4wlNP4pEFKye4ujJF8oqgFFuxDCdOLS3eNoRTtq5O3hoBDh9Doj1bQMYHRbQ==} peerDependencies: vue: ^3.2.0 dependencies: '@vue/devtools-api': 6.5.1 - vue: 3.3.4 + vue: 3.3.8(typescript@5.1.6) dev: false /w3c-hr-time@1.0.2: diff --git a/vite.config.ts.timestamp-1696335530501-05072b5e79635.mjs b/vite.config.ts.timestamp-1696335530501-05072b5e79635.mjs index a08d96e7f1..7896fdd2c0 100644 --- a/vite.config.ts.timestamp-1696335530501-05072b5e79635.mjs +++ b/vite.config.ts.timestamp-1696335530501-05072b5e79635.mjs @@ -16,6 +16,9 @@ var transformJison = (src) => { // .vite/jisonPlugin.ts var fileRegex = /\.(jison)$/; +/** + * + */ function jison2() { return { name: 'jison', @@ -55,6 +58,10 @@ var MERMAID_CONFIG_DIAGRAM_KEYS = [ 'c4', 'sankey', ]; +/** + * + * @param mermaidConfigSchema + */ function generateDefaults(mermaidConfigSchema) { const ajv = new Ajv2019({ useDefaults: true, @@ -113,6 +120,9 @@ function generateDefaults(mermaidConfigSchema) { } return mermaidDefaultConfig; } +/** + * + */ function jsonSchemaPlugin() { return { name: 'json-schema-plugin', From d2c82c18022957f8743d656b0e6017be05ba0b53 Mon Sep 17 00:00:00 2001 From: Sidharth Vinod Date: Fri, 19 Jan 2024 12:06:53 +0530 Subject: [PATCH 114/217] Use cache to store snapshots --- .github/workflows/e2e.yml | 49 +++++++++++++++++++ cSpell.json | 1 + cypress.config.cjs | 11 ++++- .../integration/other/configuration.spec.js | 1 - cypress/integration/other/rerender.spec.js | 2 - cypress/integration/rendering/gantt.spec.js | 13 +++-- cypress/support/commands.js | 12 +++-- 7 files changed, 77 insertions(+), 12 deletions(-) diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e.yml index 71806a9c46..09e8546ff7 100644 --- a/.github/workflows/e2e.yml +++ b/.github/workflows/e2e.yml @@ -9,8 +9,44 @@ permissions: contents: read jobs: + cache: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: pnpm/action-setup@v2 + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: 18.x + + - name: Cache snapshots + id: cache-snapshot + uses: actions/cache@v4 + with: + save-always: true + path: ./cypress/snapshots + key: ${{ runner.os }}-snapshots + + - name: Switch to base branch + if: ${{ steps.cache-snapshot.outputs.cache-hit != 'true' }} + uses: actions/checkout@v4 + with: + ref: ${{ github.event_name == 'pull_request' && github.event.pull_request.base.sha || github.event_name == 'merge_group' && github.event.merge_group.base.sha || 'develop' }} + + - name: Cypress run + uses: cypress-io/github-action@v4 + id: cypress-snapshot-gen + if: ${{ steps.cache-snapshot.outputs.cache-hit != 'true' }} + with: + start: pnpm run dev + wait-on: 'http://localhost:9000' + browser: chrome + spec: | + cypress/integration/rendering/flowchart-v2.spec.js + e2e: runs-on: ubuntu-latest + needs: cache strategy: fail-fast: false matrix: @@ -27,6 +63,13 @@ jobs: with: node-version: ${{ matrix.node-version }} + - name: Cache snapshots + id: cache-snapshot + uses: actions/cache/restore@v3 + with: + path: ./cypress/snapshots + key: ${{ runner.os }}-snapshots + # Install NPM dependencies, cache them correctly # and run all Cypress tests - name: Cypress run @@ -38,14 +81,19 @@ jobs: with: start: pnpm run dev:coverage wait-on: 'http://localhost:9000' + browser: chrome # Disable recording if we don't have an API key # e.g. if this action was run from a fork record: ${{ secrets.CYPRESS_RECORD_KEY != '' }} parallel: ${{ secrets.CYPRESS_RECORD_KEY != '' }} + # TODO: Remove + spec: | + cypress/integration/rendering/flowchart-v2.spec.js env: CYPRESS_RECORD_KEY: ${{ secrets.CYPRESS_RECORD_KEY }} VITEST_COVERAGE: true CYPRESS_COMMIT: ${{ github.sha }} + - name: Upload Coverage to Codecov uses: codecov/codecov-action@v3 # Run step only pushes to develop and pull_requests @@ -57,6 +105,7 @@ jobs: fail_ci_if_error: false verbose: true token: 6845cc80-77ee-4e17-85a1-026cd95e0766 + - name: Upload Artifacts uses: actions/upload-artifact@v3 if: ${{ failure() && steps.cypress.conclusion == 'failure' }} diff --git a/cSpell.json b/cSpell.json index 3ea9594f75..82c1c81c41 100644 --- a/cSpell.json +++ b/cSpell.json @@ -124,6 +124,7 @@ "sidharth", "sidharthv", "sphinxcontrib", + "ssim", "startx", "starty", "statediagram", diff --git a/cypress.config.cjs b/cypress.config.cjs index 30076c56ef..c754b465f9 100644 --- a/cypress.config.cjs +++ b/cypress.config.cjs @@ -4,12 +4,21 @@ const { defineConfig } = require('cypress'); const { addMatchImageSnapshotPlugin } = require('cypress-image-snapshot/plugin'); const coverage = require('@cypress/code-coverage/task'); + module.exports = defineConfig({ projectId: 'n2sma2', + viewportWidth: 1440, + viewportHeight: 1024, e2e: { - specPattern: 'cypress/integration/**/*.{js,jsx,ts,tsx}', + specPattern: 'cypress/integration/**/*.{js,ts}', setupNodeEvents(on, config) { coverage(on, config); + on('before:browser:launch', (browser = {}, launchOptions) => { + if (browser.name === 'chrome' && browser.isHeadless) { + launchOptions.args.push('--window-size=1440,1024', '--force-device-scale-factor=1'); + } + return launchOptions; + }); addMatchImageSnapshotPlugin(on, config); // copy any needed variables from process.env to config.env config.env.useAppli = process.env.USE_APPLI ? true : false; diff --git a/cypress/integration/other/configuration.spec.js b/cypress/integration/other/configuration.spec.js index 7cbc5d1059..23338271f5 100644 --- a/cypress/integration/other/configuration.spec.js +++ b/cypress/integration/other/configuration.spec.js @@ -117,7 +117,6 @@ describe('Configuration', () => { }); it('should not taint the initial configuration when using multiple directives', () => { const url = 'http://localhost:9000/regression/issue-1874.html'; - cy.viewport(1440, 1024); cy.visit(url); cy.get('svg'); diff --git a/cypress/integration/other/rerender.spec.js b/cypress/integration/other/rerender.spec.js index f160a2e273..d14c6257e0 100644 --- a/cypress/integration/other/rerender.spec.js +++ b/cypress/integration/other/rerender.spec.js @@ -1,14 +1,12 @@ describe('Rerendering', () => { it('should be able to render after an error has occurred', () => { const url = 'http://localhost:9000/render-after-error.html'; - cy.viewport(1440, 1024); cy.visit(url); cy.get('#graphDiv').should('exist'); }); it('should be able to render and rerender a graph via API', () => { const url = 'http://localhost:9000/rerender.html'; - cy.viewport(1440, 1024); cy.visit(url); cy.get('#graph [id^=flowchart-A]').should('have.text', 'XMas'); diff --git a/cypress/integration/rendering/gantt.spec.js b/cypress/integration/rendering/gantt.spec.js index 998a092c24..73ff4ee005 100644 --- a/cypress/integration/rendering/gantt.spec.js +++ b/cypress/integration/rendering/gantt.spec.js @@ -245,7 +245,10 @@ describe('Gantt diagram', () => { const style = svg.attr('style'); expect(style).to.match(/^max-width: [\d.]+px;$/); const maxWidthValue = parseFloat(style.match(/[\d.]+/g).join('')); - expect(maxWidthValue).to.be.within(984 * 0.95, 984 * 1.05); + expect(maxWidthValue).to.be.within( + Cypress.config().viewportWidth * 0.95, + Cypress.config().viewportWidth * 1.05 + ); }); }); @@ -285,11 +288,11 @@ describe('Gantt diagram', () => { { gantt: { useMaxWidth: false } } ); cy.get('svg').should((svg) => { - // const height = parseFloat(svg.attr('height')); const width = parseFloat(svg.attr('width')); - // use within because the absolute value can be slightly different depending on the environment ±5% - // expect(height).to.be.within(484 * 0.95, 484 * 1.05); - expect(width).to.be.within(984 * 0.95, 984 * 1.05); + expect(width).to.be.within( + Cypress.config().viewportWidth * 0.95, + Cypress.config().viewportWidth * 1.05 + ); expect(svg).to.not.have.attr('style'); }); }); diff --git a/cypress/support/commands.js b/cypress/support/commands.js index 3589640d98..7a77b3ba61 100644 --- a/cypress/support/commands.js +++ b/cypress/support/commands.js @@ -24,8 +24,14 @@ // -- This is will overwrite an existing command -- // Cypress.Commands.overwrite("visit", (originalFn, url, options) => { ... }) -// import '@percy/cypress'; - import { addMatchImageSnapshotCommand } from 'cypress-image-snapshot/command'; -addMatchImageSnapshotCommand(); +addMatchImageSnapshotCommand({ + comparisonMethod: 'ssim', + failureThreshold: 0.01, + failureThresholdType: 'percent', + customDiffConfig: { + ssim: 'fast', + }, + blur: 1, +}); From 76dacf8e90388042cf6171b5aa5aac704d34c7e3 Mon Sep 17 00:00:00 2001 From: Sidharth Vinod Date: Fri, 19 Jan 2024 12:10:39 +0530 Subject: [PATCH 115/217] E2E test --- cypress/integration/rendering/flowchart-v2.spec.js | 1 - 1 file changed, 1 deletion(-) diff --git a/cypress/integration/rendering/flowchart-v2.spec.js b/cypress/integration/rendering/flowchart-v2.spec.js index e23820ffa3..fa625159d2 100644 --- a/cypress/integration/rendering/flowchart-v2.spec.js +++ b/cypress/integration/rendering/flowchart-v2.spec.js @@ -6,7 +6,6 @@ describe('Flowchart v2', () => { `flowchart TD A[Christmas] -->|Get money| B(Go shopping) B --> C{Let me think} - C -->|One| D[Laptop] C -->|Two| E[iPhone] C -->|Three| F[fa:fa-car Car] `, From 7805e054957b019efa138ba2bece6889ac62ecf3 Mon Sep 17 00:00:00 2001 From: Sidharth Vinod Date: Fri, 19 Jan 2024 12:15:01 +0530 Subject: [PATCH 116/217] Update lockfile --- pnpm-lock.yaml | 121 ++++++++----------------------------------------- 1 file changed, 19 insertions(+), 102 deletions(-) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index b9c49e0a09..2484f63123 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -377,7 +377,7 @@ importers: version: 1.0.0-alpha.72(@algolia/client-search@4.19.1)(@types/node@18.17.5)(search-insights@2.7.0) vitepress-plugin-search: specifier: ^1.0.4-alpha.20 - version: 1.0.4-alpha.20(flexsearch@0.7.31)(vitepress@1.0.0-alpha.72)(vue@3.3.8) + version: 1.0.4-alpha.20(flexsearch@0.7.31)(vitepress@1.0.0-alpha.72)(vue@3.4.15) packages/mermaid-example-diagram: dependencies: @@ -464,7 +464,7 @@ importers: version: 1.1.0 unocss: specifier: ^0.58.0 - version: 0.58.0(postcss@8.4.31)(rollup@2.79.1)(vite@4.5.0) + version: 0.58.0(postcss@8.4.33)(rollup@2.79.1)(vite@4.5.0) unplugin-vue-components: specifier: ^0.26.0 version: 0.26.0(rollup@2.79.1)(vue@3.3.4) @@ -476,7 +476,7 @@ importers: version: 0.17.0(vite@4.5.0)(workbox-build@7.0.0)(workbox-window@7.0.0) vitepress: specifier: 1.0.0-rc.39 - version: 1.0.0-rc.39(@algolia/client-search@4.19.1)(@types/node@18.17.5)(postcss@8.4.31)(search-insights@2.7.0)(typescript@5.1.6) + version: 1.0.0-rc.39(@algolia/client-search@4.19.1)(@types/node@18.17.5)(postcss@8.4.33)(search-insights@2.7.0)(typescript@5.1.6) workbox-window: specifier: ^7.0.0 version: 7.0.0 @@ -5593,7 +5593,7 @@ packages: sirv: 2.0.3 dev: true - /@unocss/postcss@0.58.0(postcss@8.4.31): + /@unocss/postcss@0.58.0(postcss@8.4.33): resolution: {integrity: sha512-2hAwLbfUFqysi8FN1cn3xkHy5GhLMlYy6W4NrAZ2ws7F2MKpsCT2xCj7dT5cI2tW8ulD2YoVbKH15dBhNsMNUA==} engines: {node: '>=14'} peerDependencies: @@ -5605,7 +5605,7 @@ packages: css-tree: 2.3.1 fast-glob: 3.3.2 magic-string: 0.30.5 - postcss: 8.4.31 + postcss: 8.4.33 dev: true /@unocss/preset-attributify@0.58.0: @@ -5876,15 +5876,6 @@ packages: estree-walker: 2.0.2 source-map-js: 1.0.2 - /@vue/compiler-core@3.3.8: - resolution: {integrity: sha512-hN/NNBUECw8SusQvDSqqcVv6gWq8L6iAktUR0UF3vGu2OhzRqcOiAno0FmBJWwxhYEXRlQJT5XnoKsVq1WZx4g==} - dependencies: - '@babel/parser': 7.23.5 - '@vue/shared': 3.3.8 - estree-walker: 2.0.2 - source-map-js: 1.0.2 - dev: true - /@vue/compiler-core@3.4.15: resolution: {integrity: sha512-XcJQVOaxTKCnth1vCxEChteGuwG6wqnUHxAm1DO3gCz0+uXKaJNx8/digSz4dLALCy8n2lKq24jSUs8segoqIw==} dependencies: @@ -5901,13 +5892,6 @@ packages: '@vue/compiler-core': 3.3.4 '@vue/shared': 3.3.4 - /@vue/compiler-dom@3.3.8: - resolution: {integrity: sha512-+PPtv+p/nWDd0AvJu3w8HS0RIm/C6VGBIRe24b9hSyNWOAPEUosFZ5diwawwP8ip5sJ8n0Pe87TNNNHnvjs0FQ==} - dependencies: - '@vue/compiler-core': 3.3.8 - '@vue/shared': 3.3.8 - dev: true - /@vue/compiler-dom@3.4.15: resolution: {integrity: sha512-wox0aasVV74zoXyblarOM3AZQz/Z+OunYcIHe1OsGclCHt8RsRm04DObjefaI82u6XDzv+qGWZ24tIsRAIi5MQ==} dependencies: @@ -5929,21 +5913,6 @@ packages: postcss: 8.4.31 source-map-js: 1.0.2 - /@vue/compiler-sfc@3.3.8: - resolution: {integrity: sha512-WMzbUrlTjfYF8joyT84HfwwXo+8WPALuPxhy+BZ6R4Aafls+jDBnSz8PDz60uFhuqFbl3HxRfxvDzrUf3THwpA==} - dependencies: - '@babel/parser': 7.23.5 - '@vue/compiler-core': 3.3.8 - '@vue/compiler-dom': 3.3.8 - '@vue/compiler-ssr': 3.3.8 - '@vue/reactivity-transform': 3.3.8 - '@vue/shared': 3.3.8 - estree-walker: 2.0.2 - magic-string: 0.30.5 - postcss: 8.4.31 - source-map-js: 1.0.2 - dev: true - /@vue/compiler-sfc@3.4.15: resolution: {integrity: sha512-LCn5M6QpkpFsh3GQvs2mJUOAlBQcCco8D60Bcqmf3O3w5a+KWS5GvYbrrJBkgvL1BDnTp+e8q0lXCLgHhKguBA==} dependencies: @@ -5964,13 +5933,6 @@ packages: '@vue/compiler-dom': 3.3.4 '@vue/shared': 3.3.4 - /@vue/compiler-ssr@3.3.8: - resolution: {integrity: sha512-hXCqQL/15kMVDBuoBYpUnSYT8doDNwsjvm3jTefnXr+ytn294ySnT8NlsFHmTgKNjwpuFy7XVV8yTeLtNl/P6w==} - dependencies: - '@vue/compiler-dom': 3.3.8 - '@vue/shared': 3.3.8 - dev: true - /@vue/compiler-ssr@3.4.15: resolution: {integrity: sha512-1jdeQyiGznr8gjFDadVmOJqZiLNSsMa5ZgqavkPZ8O2wjHv0tVuAEsw5hTdUoUW4232vpBbL/wJhzVW/JwY1Uw==} dependencies: @@ -5994,27 +5956,11 @@ packages: estree-walker: 2.0.2 magic-string: 0.30.5 - /@vue/reactivity-transform@3.3.8: - resolution: {integrity: sha512-49CvBzmZNtcHua0XJ7GdGifM8GOXoUMOX4dD40Y5DxI3R8OUhMlvf2nvgUAcPxaXiV5MQQ1Nwy09ADpnLQUqRw==} - dependencies: - '@babel/parser': 7.23.5 - '@vue/compiler-core': 3.3.8 - '@vue/shared': 3.3.8 - estree-walker: 2.0.2 - magic-string: 0.30.5 - dev: true - /@vue/reactivity@3.3.4: resolution: {integrity: sha512-kLTDLwd0B1jG08NBF3R5rqULtv/f8x3rOFByTDz4J53ttIQEDmALqKqXY0J+XQeN0aV2FBxY8nJDf88yvOPAqQ==} dependencies: '@vue/shared': 3.3.4 - /@vue/reactivity@3.3.8: - resolution: {integrity: sha512-ctLWitmFBu6mtddPyOKpHg8+5ahouoTCRtmAHZAXmolDtuZXfjL2T3OJ6DL6ezBPQB1SmMnpzjiWjCiMYmpIuw==} - dependencies: - '@vue/shared': 3.3.8 - dev: true - /@vue/reactivity@3.4.15: resolution: {integrity: sha512-55yJh2bsff20K5O84MxSvXKPHHt17I2EomHznvFiJCAZpJTNW8IuLj1xZWMLELRhBK3kkFV/1ErZGHJfah7i7w==} dependencies: @@ -6027,13 +5973,6 @@ packages: '@vue/reactivity': 3.3.4 '@vue/shared': 3.3.4 - /@vue/runtime-core@3.3.8: - resolution: {integrity: sha512-qurzOlb6q26KWQ/8IShHkMDOuJkQnQcTIp1sdP4I9MbCf9FJeGVRXJFr2mF+6bXh/3Zjr9TDgURXrsCr9bfjUw==} - dependencies: - '@vue/reactivity': 3.3.8 - '@vue/shared': 3.3.8 - dev: true - /@vue/runtime-core@3.4.15: resolution: {integrity: sha512-6E3by5m6v1AkW0McCeAyhHTw+3y17YCOKG0U0HDKDscV4Hs0kgNT5G+GCHak16jKgcCDHpI9xe5NKb8sdLCLdw==} dependencies: @@ -6048,14 +5987,6 @@ packages: '@vue/shared': 3.3.4 csstype: 3.1.2 - /@vue/runtime-dom@3.3.8: - resolution: {integrity: sha512-Noy5yM5UIf9UeFoowBVgghyGGPIDPy1Qlqt0yVsUdAVbqI8eeMSsTqBtauaEoT2UFXUk5S64aWVNJN4MJ2vRdA==} - dependencies: - '@vue/runtime-core': 3.3.8 - '@vue/shared': 3.3.8 - csstype: 3.1.2 - dev: true - /@vue/runtime-dom@3.4.15: resolution: {integrity: sha512-EVW8D6vfFVq3V/yDKNPBFkZKGMFSvZrUQmx196o/v2tHKdwWdiZjYUBS+0Ez3+ohRyF8Njwy/6FH5gYJ75liUw==} dependencies: @@ -6073,16 +6004,6 @@ packages: '@vue/shared': 3.3.4 vue: 3.3.4 - /@vue/server-renderer@3.3.8(vue@3.3.8): - resolution: {integrity: sha512-zVCUw7RFskvPuNlPn/8xISbrf0zTWsTSdYTsUTN1ERGGZGVnRxM2QZ3x1OR32+vwkkCm0IW6HmJ49IsPm7ilLg==} - peerDependencies: - vue: 3.3.8 - dependencies: - '@vue/compiler-ssr': 3.3.8 - '@vue/shared': 3.3.8 - vue: 3.3.8(typescript@5.0.4) - dev: true - /@vue/server-renderer@3.4.15(vue@3.4.15): resolution: {integrity: sha512-3HYzaidu9cHjrT+qGUuDhFYvF/j643bHC6uUN9BgM11DVy+pM6ATsG6uPBLnkwOgs7BpJABReLmpL3ZPAsUaqw==} peerDependencies: @@ -6090,16 +6011,12 @@ packages: dependencies: '@vue/compiler-ssr': 3.4.15 '@vue/shared': 3.4.15 - vue: 3.4.15(typescript@5.1.6) + vue: 3.4.15(typescript@5.0.4) dev: true /@vue/shared@3.3.4: resolution: {integrity: sha512-7OjdcV8vQ74eiz1TZLzZP4JwqM5fA94K6yntPS5Z25r9HDuGNzaGdgvwKYq6S+MxwF0TFRwe50fIR/MYnakdkQ==} - /@vue/shared@3.3.8: - resolution: {integrity: sha512-8PGwybFwM4x8pcfgqEQFy70NaQxASvOC5DJwLQfpArw1UDfUXrJkdxD3BhVTMS+0Lef/TU7YO0Jvr0jJY8T+mw==} - dev: true - /@vue/shared@3.4.15: resolution: {integrity: sha512-KzfPTxVaWfB+eGcGdbSf4CWdaXcGDqckoeXUh7SB3fZdEtzPCK2Vq9B/lRRL3yutax/LWITz+SwvgyOxz5V75g==} dev: true @@ -16175,7 +16092,7 @@ packages: engines: {node: '>= 10.0.0'} dev: true - /unocss@0.58.0(postcss@8.4.31)(rollup@2.79.1)(vite@4.5.0): + /unocss@0.58.0(postcss@8.4.33)(rollup@2.79.1)(vite@4.5.0): resolution: {integrity: sha512-MSPRHxBqWN+1AHGV+J5uUy4//e6ZBK6O+ISzD0qrXcCD/GNtxk1+lYjOK2ltkUiKX539+/KF91vNxzhhwEf+xA==} engines: {node: '>=14'} peerDependencies: @@ -16191,7 +16108,7 @@ packages: '@unocss/cli': 0.58.0(rollup@2.79.1) '@unocss/core': 0.58.0 '@unocss/extractor-arbitrary-variants': 0.58.0 - '@unocss/postcss': 0.58.0(postcss@8.4.31) + '@unocss/postcss': 0.58.0(postcss@8.4.33) '@unocss/preset-attributify': 0.58.0 '@unocss/preset-icons': 0.58.0 '@unocss/preset-mini': 0.58.0 @@ -16530,7 +16447,7 @@ packages: fsevents: 2.3.3 dev: true - /vitepress-plugin-search@1.0.4-alpha.20(flexsearch@0.7.31)(vitepress@1.0.0-alpha.72)(vue@3.3.8): + /vitepress-plugin-search@1.0.4-alpha.20(flexsearch@0.7.31)(vitepress@1.0.0-alpha.72)(vue@3.4.15): resolution: {integrity: sha512-zG+ev9pw1Mg7htABlFCNXb8XwnKN+qfTKw+vU0Ers6RIrABx+45EAAFBoaL1mEpl1FRFn1o/dQ7F4b8GP6HdGQ==} engines: {node: ^14.13.1 || ^16.7.0 || >=18} peerDependencies: @@ -16544,7 +16461,7 @@ packages: glob-to-regexp: 0.4.1 markdown-it: 13.0.1 vitepress: 1.0.0-alpha.72(@algolia/client-search@4.19.1)(@types/node@18.17.5)(search-insights@2.7.0) - vue: 3.3.8(typescript@5.0.4) + vue: 3.4.15(typescript@5.0.4) dev: true /vitepress@1.0.0-alpha.72(@algolia/client-search@4.19.1)(@types/node@18.17.5)(search-insights@2.7.0): @@ -16578,7 +16495,7 @@ packages: - terser dev: true - /vitepress@1.0.0-rc.39(@algolia/client-search@4.19.1)(@types/node@18.17.5)(postcss@8.4.31)(search-insights@2.7.0)(typescript@5.1.6): + /vitepress@1.0.0-rc.39(@algolia/client-search@4.19.1)(@types/node@18.17.5)(postcss@8.4.33)(search-insights@2.7.0)(typescript@5.1.6): resolution: {integrity: sha512-EcgoRlAAp37WOxUOYv45oxyhLrcy3Upey+mKpqW3ldsg6Ol4trPndRBk2GO0QiSvEKlb9BMerk49D/bFICN6kg==} hasBin: true peerDependencies: @@ -16600,7 +16517,7 @@ packages: focus-trap: 7.5.4 mark.js: 8.11.1 minisearch: 6.3.0 - postcss: 8.4.31 + postcss: 8.4.33 shikiji: 0.9.19 shikiji-core: 0.9.19 shikiji-transformers: 0.9.19 @@ -16788,19 +16705,19 @@ packages: '@vue/server-renderer': 3.3.4(vue@3.3.4) '@vue/shared': 3.3.4 - /vue@3.3.8(typescript@5.0.4): - resolution: {integrity: sha512-5VSX/3DabBikOXMsxzlW8JyfeLKlG9mzqnWgLQLty88vdZL7ZJgrdgBOmrArwxiLtmS+lNNpPcBYqrhE6TQW5w==} + /vue@3.4.15(typescript@5.0.4): + resolution: {integrity: sha512-jC0GH4KkWLWJOEQjOpkqU1bQsBwf4R1rsFtw5GQJbjHVKWDzO6P0nWWBTmjp1xSemAioDFj1jdaK1qa3DnMQoQ==} peerDependencies: typescript: '*' peerDependenciesMeta: typescript: optional: true dependencies: - '@vue/compiler-dom': 3.3.8 - '@vue/compiler-sfc': 3.3.8 - '@vue/runtime-dom': 3.3.8 - '@vue/server-renderer': 3.3.8(vue@3.3.8) - '@vue/shared': 3.3.8 + '@vue/compiler-dom': 3.4.15 + '@vue/compiler-sfc': 3.4.15 + '@vue/runtime-dom': 3.4.15 + '@vue/server-renderer': 3.4.15(vue@3.4.15) + '@vue/shared': 3.4.15 typescript: 5.0.4 dev: true From 448756ab54480e5e82b5290c00ec3350c6f34879 Mon Sep 17 00:00:00 2001 From: Sidharth Vinod Date: Fri, 19 Jan 2024 12:17:20 +0530 Subject: [PATCH 117/217] Fix lint --- .github/workflows/e2e.yml | 4 ++-- cypress.config.cjs | 1 - 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e.yml index 09e8546ff7..a357c1c995 100644 --- a/.github/workflows/e2e.yml +++ b/.github/workflows/e2e.yml @@ -32,7 +32,7 @@ jobs: uses: actions/checkout@v4 with: ref: ${{ github.event_name == 'pull_request' && github.event.pull_request.base.sha || github.event_name == 'merge_group' && github.event.merge_group.base.sha || 'develop' }} - + - name: Cypress run uses: cypress-io/github-action@v4 id: cypress-snapshot-gen @@ -43,7 +43,7 @@ jobs: browser: chrome spec: | cypress/integration/rendering/flowchart-v2.spec.js - + e2e: runs-on: ubuntu-latest needs: cache diff --git a/cypress.config.cjs b/cypress.config.cjs index c754b465f9..33633920ac 100644 --- a/cypress.config.cjs +++ b/cypress.config.cjs @@ -4,7 +4,6 @@ const { defineConfig } = require('cypress'); const { addMatchImageSnapshotPlugin } = require('cypress-image-snapshot/plugin'); const coverage = require('@cypress/code-coverage/task'); - module.exports = defineConfig({ projectId: 'n2sma2', viewportWidth: 1440, From d6e738ac4cf2e208326b0ca3a8702d940cb846ec Mon Sep 17 00:00:00 2001 From: Sidharth Vinod Date: Fri, 19 Jan 2024 12:21:51 +0530 Subject: [PATCH 118/217] Run all tests --- .github/workflows/e2e.yml | 5 ----- cypress/integration/rendering/flowchart-v2.spec.js | 1 + 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e.yml index a357c1c995..996fc6673e 100644 --- a/.github/workflows/e2e.yml +++ b/.github/workflows/e2e.yml @@ -41,8 +41,6 @@ jobs: start: pnpm run dev wait-on: 'http://localhost:9000' browser: chrome - spec: | - cypress/integration/rendering/flowchart-v2.spec.js e2e: runs-on: ubuntu-latest @@ -86,9 +84,6 @@ jobs: # e.g. if this action was run from a fork record: ${{ secrets.CYPRESS_RECORD_KEY != '' }} parallel: ${{ secrets.CYPRESS_RECORD_KEY != '' }} - # TODO: Remove - spec: | - cypress/integration/rendering/flowchart-v2.spec.js env: CYPRESS_RECORD_KEY: ${{ secrets.CYPRESS_RECORD_KEY }} VITEST_COVERAGE: true diff --git a/cypress/integration/rendering/flowchart-v2.spec.js b/cypress/integration/rendering/flowchart-v2.spec.js index fa625159d2..e23820ffa3 100644 --- a/cypress/integration/rendering/flowchart-v2.spec.js +++ b/cypress/integration/rendering/flowchart-v2.spec.js @@ -6,6 +6,7 @@ describe('Flowchart v2', () => { `flowchart TD A[Christmas] -->|Get money| B(Go shopping) B --> C{Let me think} + C -->|One| D[Laptop] C -->|Two| E[iPhone] C -->|Three| F[fa:fa-car Car] `, From cb0ee5aa419849427b4de5b553ef734d22840cae Mon Sep 17 00:00:00 2001 From: Sidharth Vinod Date: Fri, 19 Jan 2024 13:17:14 +0530 Subject: [PATCH 119/217] Use pixelmatch for image comparison --- cSpell.json | 1 + cypress/support/commands.js | 22 +++++++++++++--------- 2 files changed, 14 insertions(+), 9 deletions(-) diff --git a/cSpell.json b/cSpell.json index 82c1c81c41..4b8772347e 100644 --- a/cSpell.json +++ b/cSpell.json @@ -102,6 +102,7 @@ "pathe", "pbrolin", "phpbb", + "pixelmatch", "plantuml", "playfair", "pnpm", diff --git a/cypress/support/commands.js b/cypress/support/commands.js index 7a77b3ba61..6fc1fe17db 100644 --- a/cypress/support/commands.js +++ b/cypress/support/commands.js @@ -26,12 +26,16 @@ import { addMatchImageSnapshotCommand } from 'cypress-image-snapshot/command'; -addMatchImageSnapshotCommand({ - comparisonMethod: 'ssim', - failureThreshold: 0.01, - failureThresholdType: 'percent', - customDiffConfig: { - ssim: 'fast', - }, - blur: 1, -}); +// The SSIM comparison method can be used if the pixelmatch is throwing lots of false positives. +// SSIM actually does not catch minute changes in the image, so it is not as accurate as pixelmatch. +// addMatchImageSnapshotCommand({ +// comparisonMethod: 'ssim', +// failureThreshold: 0.01, +// failureThresholdType: 'percent', +// customDiffConfig: { +// ssim: 'fast', +// }, +// blur: 1, +// }); + +addMatchImageSnapshotCommand(); From 658af081ee2781cc159dbc2826857def3765f281 Mon Sep 17 00:00:00 2001 From: Sidharth Vinod Date: Fri, 19 Jan 2024 14:42:51 +0530 Subject: [PATCH 120/217] Flatten uploaded images --- .github/workflows/e2e.yml | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e.yml index 996fc6673e..436624968c 100644 --- a/.github/workflows/e2e.yml +++ b/.github/workflows/e2e.yml @@ -102,8 +102,30 @@ jobs: token: 6845cc80-77ee-4e17-85a1-026cd95e0766 - name: Upload Artifacts - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 if: ${{ failure() && steps.cypress.conclusion == 'failure' }} with: - name: error-snapshots + name: error-snapshots-${{ matrix.containers }} + retention-days: 1 path: cypress/snapshots/**/__diff_output__/* + + combineArtifacts: + needs: e2e + runs-on: ubuntu-latest + steps: + - name: Download All Artifacts + uses: actions/download-artifact@v4 + with: + path: snapshots + pattern: error-snapshots-* + merge-multiple: true + - run: | + mkdir errors + cd snapshots + find . -mindepth 2 -type f -print -exec mv {} ../errors/ \; + - name: Upload Artifacts + uses: actions/upload-artifact@v4 + with: + name: error-snapshots + retention-days: 10 + path: errors/ \ No newline at end of file From 4ce5d071250ec7b281ad9009e557551bc68ceeca Mon Sep 17 00:00:00 2001 From: Sidharth Vinod Date: Fri, 19 Jan 2024 14:46:21 +0530 Subject: [PATCH 121/217] Flatten uploaded images --- .github/workflows/e2e.yml | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e.yml index 436624968c..29bd6eab56 100644 --- a/.github/workflows/e2e.yml +++ b/.github/workflows/e2e.yml @@ -113,19 +113,19 @@ jobs: needs: e2e runs-on: ubuntu-latest steps: - - name: Download All Artifacts - uses: actions/download-artifact@v4 - with: - path: snapshots - pattern: error-snapshots-* - merge-multiple: true - - run: | - mkdir errors - cd snapshots - find . -mindepth 2 -type f -print -exec mv {} ../errors/ \; - - name: Upload Artifacts - uses: actions/upload-artifact@v4 - with: - name: error-snapshots - retention-days: 10 - path: errors/ \ No newline at end of file + - name: Download All Artifacts + uses: actions/download-artifact@v4 + with: + path: snapshots + pattern: error-snapshots-* + merge-multiple: true + - run: | + mkdir errors + cd snapshots + find . -mindepth 2 -type f -print -exec mv {} ../errors/ \; + - name: Upload Artifacts + uses: actions/upload-artifact@v4 + with: + name: error-snapshots + retention-days: 10 + path: errors/ From f58a86d747ab5a773fddf905e23176ebf8581c5e Mon Sep 17 00:00:00 2001 From: Sidharth Vinod Date: Fri, 19 Jan 2024 15:30:18 +0530 Subject: [PATCH 122/217] Notify users --- .github/workflows/e2e.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e.yml index 29bd6eab56..cfc8a45d2c 100644 --- a/.github/workflows/e2e.yml +++ b/.github/workflows/e2e.yml @@ -111,6 +111,7 @@ jobs: combineArtifacts: needs: e2e + if: ${{ failure() }} runs-on: ubuntu-latest steps: - name: Download All Artifacts @@ -125,7 +126,12 @@ jobs: find . -mindepth 2 -type f -print -exec mv {} ../errors/ \; - name: Upload Artifacts uses: actions/upload-artifact@v4 + id: upload-artifacts with: name: error-snapshots retention-days: 10 path: errors/ + - name: Notify Users + run: | + echo "::error,title=Visual tests failed::You can view images that failed by downloading the error-snapshots artifact: ${{ steps.upload-artifacts.outputs.artifact-url }}" + From a9a8a208a6dc011db8c737cbee4c0eb228af2abb Mon Sep 17 00:00:00 2001 From: Sidharth Vinod Date: Fri, 19 Jan 2024 15:50:40 +0530 Subject: [PATCH 123/217] Update cache key --- .github/workflows/e2e.yml | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e.yml index cfc8a45d2c..3b983589d8 100644 --- a/.github/workflows/e2e.yml +++ b/.github/workflows/e2e.yml @@ -8,6 +8,9 @@ on: permissions: contents: read +env: + targetHash: ${{ github.event_name == 'pull_request' && github.event.pull_request.base.sha || github.event_name == 'merge_group' && github.event.merge_group.base.sha || github.event.before }} + jobs: cache: runs-on: ubuntu-latest @@ -25,13 +28,13 @@ jobs: with: save-always: true path: ./cypress/snapshots - key: ${{ runner.os }}-snapshots + key: ${{ runner.os }}-snapshots-${{ env.targetHash }} - name: Switch to base branch if: ${{ steps.cache-snapshot.outputs.cache-hit != 'true' }} uses: actions/checkout@v4 with: - ref: ${{ github.event_name == 'pull_request' && github.event.pull_request.base.sha || github.event_name == 'merge_group' && github.event.merge_group.base.sha || 'develop' }} + ref: ${{ env.targetHash }} - name: Cypress run uses: cypress-io/github-action@v4 @@ -66,7 +69,7 @@ jobs: uses: actions/cache/restore@v3 with: path: ./cypress/snapshots - key: ${{ runner.os }}-snapshots + key: ${{ runner.os }}-snapshots-${{ env.targetHash }} # Install NPM dependencies, cache them correctly # and run all Cypress tests @@ -109,6 +112,14 @@ jobs: retention-days: 1 path: cypress/snapshots/**/__diff_output__/* + - name: Save snapshots cache + id: cache-upload + if: ${{ github.event_name == 'push' }} + uses: actions/cache/save@v3 + with: + path: ./cypress/snapshots + key: ${{ runner.os }}-snapshots-${{ github.event.after }} + combineArtifacts: needs: e2e if: ${{ failure() }} From be4721b24db004317f451ac406bb094379ce0f59 Mon Sep 17 00:00:00 2001 From: Sidharth Vinod Date: Fri, 19 Jan 2024 16:18:07 +0530 Subject: [PATCH 124/217] Fix cache save --- .github/workflows/e2e.yml | 33 +++++++++++++++++++-------------- 1 file changed, 19 insertions(+), 14 deletions(-) diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e.yml index 3b983589d8..9f4fd86b2f 100644 --- a/.github/workflows/e2e.yml +++ b/.github/workflows/e2e.yml @@ -108,34 +108,38 @@ jobs: uses: actions/upload-artifact@v4 if: ${{ failure() && steps.cypress.conclusion == 'failure' }} with: - name: error-snapshots-${{ matrix.containers }} + name: snapshots-${{ matrix.containers }} retention-days: 1 - path: cypress/snapshots/**/__diff_output__/* - - - name: Save snapshots cache - id: cache-upload - if: ${{ github.event_name == 'push' }} - uses: actions/cache/save@v3 - with: path: ./cypress/snapshots - key: ${{ runner.os }}-snapshots-${{ github.event.after }} combineArtifacts: needs: e2e - if: ${{ failure() }} runs-on: ubuntu-latest steps: - name: Download All Artifacts uses: actions/download-artifact@v4 with: path: snapshots - pattern: error-snapshots-* + pattern: snapshots-* merge-multiple: true - - run: | + + - name: Save snapshots cache + id: cache-upload + if: ${{ github.event_name == 'push' }} + uses: actions/cache/save@v3 + with: + path: | + ./cypress/snapshots + !./**/__diff_output__/* + key: ${{ runner.os }}-snapshots-${{ github.event.after }} + + - if: ${{ failure() }} + run: | mkdir errors cd snapshots - find . -mindepth 2 -type f -print -exec mv {} ../errors/ \; - - name: Upload Artifacts + find . -mindepth 2 -type d -name "*__diff_output__*" -exec sh -c 'mv "$0"/*.png ../errors/' {} \; + - name: Upload Error snapshots + if: ${{ failure() }} uses: actions/upload-artifact@v4 id: upload-artifacts with: @@ -143,6 +147,7 @@ jobs: retention-days: 10 path: errors/ - name: Notify Users + if: ${{ failure() }} run: | echo "::error,title=Visual tests failed::You can view images that failed by downloading the error-snapshots artifact: ${{ steps.upload-artifacts.outputs.artifact-url }}" From 35b3192c2bf69cd3d15e35cb4422ab5c5f7afbd5 Mon Sep 17 00:00:00 2001 From: Sidharth Vinod Date: Fri, 19 Jan 2024 16:23:26 +0530 Subject: [PATCH 125/217] Fix error message --- .github/workflows/e2e.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e.yml index 9f4fd86b2f..5326cb4575 100644 --- a/.github/workflows/e2e.yml +++ b/.github/workflows/e2e.yml @@ -149,5 +149,5 @@ jobs: - name: Notify Users if: ${{ failure() }} run: | - echo "::error,title=Visual tests failed::You can view images that failed by downloading the error-snapshots artifact: ${{ steps.upload-artifacts.outputs.artifact-url }}" + echo "::error title=Visual tests failed::You can view images that failed by downloading the error-snapshots artifact: ${{ steps.upload-artifacts.outputs.artifact-url }}" From 6f205f89b22d82af5d56fb1613307e2b7b50db69 Mon Sep 17 00:00:00 2001 From: Sidharth Vinod Date: Fri, 19 Jan 2024 16:24:42 +0530 Subject: [PATCH 126/217] Always run combineArtifacts --- .github/workflows/e2e.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e.yml index 5326cb4575..754f9ada13 100644 --- a/.github/workflows/e2e.yml +++ b/.github/workflows/e2e.yml @@ -115,6 +115,7 @@ jobs: combineArtifacts: needs: e2e runs-on: ubuntu-latest + if: ${{ always() }} steps: - name: Download All Artifacts uses: actions/download-artifact@v4 From a964af67ec5f1954342cd0b2711b97ee26a7c963 Mon Sep 17 00:00:00 2001 From: Sidharth Vinod Date: Fri, 19 Jan 2024 19:04:25 +0530 Subject: [PATCH 127/217] Handle edge cases in E2E --- .github/workflows/e2e.yml | 38 +++++++++++++++------ cypress/integration/rendering/debug.spec.js | 12 ------- 2 files changed, 27 insertions(+), 23 deletions(-) delete mode 100644 cypress/integration/rendering/debug.spec.js diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e.yml index 754f9ada13..90769858e0 100644 --- a/.github/workflows/e2e.yml +++ b/.github/workflows/e2e.yml @@ -1,3 +1,9 @@ +# We use github cache to save snapshots between runs. +# For PRs and MergeQueues, the target commit is used, and for push events, github.event.previous is used. +# If a snapshot for a given Hash is not found, we checkout that commit, run the tests and cache the snapshots. +# These are then downloaded before running the E2E, providing the reference snapshots. +# If there are any errors, the diff image is uploaded to artifacts, and the user is notified. + name: E2E on: @@ -9,7 +15,8 @@ permissions: contents: read env: - targetHash: ${{ github.event_name == 'pull_request' && github.event.pull_request.base.sha || github.event_name == 'merge_group' && github.event.merge_group.base.sha || github.event.before }} + # For PRs and MergeQueues, the target commit is used, and for push events, github.event.previous is used. + targetHash: ${{ github.event.pull_request.base.sha || github.event.merge_group.base_sha || github.event.before }} jobs: cache: @@ -30,6 +37,7 @@ jobs: path: ./cypress/snapshots key: ${{ runner.os }}-snapshots-${{ env.targetHash }} + # If a snapshot for a given Hash is not found, we checkout that commit, run the tests and cache the snapshots. - name: Switch to base branch if: ${{ steps.cache-snapshot.outputs.cache-hit != 'true' }} uses: actions/checkout@v4 @@ -44,6 +52,8 @@ jobs: start: pnpm run dev wait-on: 'http://localhost:9000' browser: chrome + spec: + cypress/integration/rendering/sequencediagram.spec.js e2e: runs-on: ubuntu-latest @@ -64,6 +74,7 @@ jobs: with: node-version: ${{ matrix.node-version }} + # These cached snapshots are downloaded, providing the reference snapshots. - name: Cache snapshots id: cache-snapshot uses: actions/cache/restore@v3 @@ -87,6 +98,8 @@ jobs: # e.g. if this action was run from a fork record: ${{ secrets.CYPRESS_RECORD_KEY != '' }} parallel: ${{ secrets.CYPRESS_RECORD_KEY != '' }} + spec: + cypress/integration/rendering/sequencediagram.spec.js env: CYPRESS_RECORD_KEY: ${{ secrets.CYPRESS_RECORD_KEY }} VITEST_COVERAGE: true @@ -104,9 +117,10 @@ jobs: verbose: true token: 6845cc80-77ee-4e17-85a1-026cd95e0766 + # We upload the artifacts into numbered archives to prevent overwriting - name: Upload Artifacts uses: actions/upload-artifact@v4 - if: ${{ failure() && steps.cypress.conclusion == 'failure' }} + if: ${{ always() }} with: name: snapshots-${{ matrix.containers }} retention-days: 1 @@ -117,38 +131,40 @@ jobs: runs-on: ubuntu-latest if: ${{ always() }} steps: + # Download all snapshot artifacts and merge them into a single folder - name: Download All Artifacts uses: actions/download-artifact@v4 with: path: snapshots pattern: snapshots-* merge-multiple: true - + + # For successful push events, we save the snapshots cache - name: Save snapshots cache id: cache-upload - if: ${{ github.event_name == 'push' }} + if: ${{ github.event_name == 'push' && needs.e2e.result != 'failure' }} uses: actions/cache/save@v3 with: - path: | - ./cypress/snapshots - !./**/__diff_output__/* + path: ./snapshots key: ${{ runner.os }}-snapshots-${{ github.event.after }} - - if: ${{ failure() }} + - name: Flatten images to a folder + if: ${{ needs.e2e.result == 'failure' }} run: | mkdir errors cd snapshots find . -mindepth 2 -type d -name "*__diff_output__*" -exec sh -c 'mv "$0"/*.png ../errors/' {} \; + - name: Upload Error snapshots - if: ${{ failure() }} + if: ${{ needs.e2e.result == 'failure' }} uses: actions/upload-artifact@v4 id: upload-artifacts with: name: error-snapshots retention-days: 10 path: errors/ + - name: Notify Users - if: ${{ failure() }} + if: ${{ needs.e2e.result == 'failure' }} run: | echo "::error title=Visual tests failed::You can view images that failed by downloading the error-snapshots artifact: ${{ steps.upload-artifacts.outputs.artifact-url }}" - diff --git a/cypress/integration/rendering/debug.spec.js b/cypress/integration/rendering/debug.spec.js deleted file mode 100644 index 56ad0f15f8..0000000000 --- a/cypress/integration/rendering/debug.spec.js +++ /dev/null @@ -1,12 +0,0 @@ -import { imgSnapshotTest } from '../../helpers/util.ts'; - -describe('Flowchart', () => { - it('34: testing the label width in percy', () => { - imgSnapshotTest( - `graph TD - A[Christmas] - `, - { theme: 'forest', fontFamily: '"Noto Sans SC", sans-serif' } - ); - }); -}); From a871a68f3c8bce5419bcd6f04deaeddd0defa473 Mon Sep 17 00:00:00 2001 From: Sidharth Vinod Date: Fri, 19 Jan 2024 19:05:06 +0530 Subject: [PATCH 128/217] Remove spec selector --- .github/workflows/e2e.yml | 4 ---- 1 file changed, 4 deletions(-) diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e.yml index 90769858e0..817635cbf6 100644 --- a/.github/workflows/e2e.yml +++ b/.github/workflows/e2e.yml @@ -52,8 +52,6 @@ jobs: start: pnpm run dev wait-on: 'http://localhost:9000' browser: chrome - spec: - cypress/integration/rendering/sequencediagram.spec.js e2e: runs-on: ubuntu-latest @@ -98,8 +96,6 @@ jobs: # e.g. if this action was run from a fork record: ${{ secrets.CYPRESS_RECORD_KEY != '' }} parallel: ${{ secrets.CYPRESS_RECORD_KEY != '' }} - spec: - cypress/integration/rendering/sequencediagram.spec.js env: CYPRESS_RECORD_KEY: ${{ secrets.CYPRESS_RECORD_KEY }} VITEST_COVERAGE: true From f1fc874da8d4bdef88add516c7e6c046fdb9b755 Mon Sep 17 00:00:00 2001 From: Sidharth Vinod Date: Fri, 19 Jan 2024 19:20:39 +0530 Subject: [PATCH 129/217] Debug --- .github/workflows/e2e.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e.yml index 817635cbf6..56bdd30a01 100644 --- a/.github/workflows/e2e.yml +++ b/.github/workflows/e2e.yml @@ -16,12 +16,13 @@ permissions: env: # For PRs and MergeQueues, the target commit is used, and for push events, github.event.previous is used. - targetHash: ${{ github.event.pull_request.base.sha || github.event.merge_group.base_sha || github.event.before }} + targetHash: ${{ github.event_name == 'pull_request' && github.event.pull_request.base.sha || github.event_name == 'merge_group' && github.event.merge_group.base_sha || github.event.before }} jobs: cache: runs-on: ubuntu-latest steps: + - run: echo "${{ github.event }}" - uses: actions/checkout@v4 - uses: pnpm/action-setup@v2 - name: Setup Node.js From 279e31bc559caade5d63ce0712273f02a77f244d Mon Sep 17 00:00:00 2001 From: Sidharth Vinod Date: Fri, 19 Jan 2024 19:23:13 +0530 Subject: [PATCH 130/217] Debug --- .github/workflows/e2e.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e.yml index 56bdd30a01..674f276727 100644 --- a/.github/workflows/e2e.yml +++ b/.github/workflows/e2e.yml @@ -22,7 +22,7 @@ jobs: cache: runs-on: ubuntu-latest steps: - - run: echo "${{ github.event }}" + - run: echo "${{ toJSON(github) }}" - uses: actions/checkout@v4 - uses: pnpm/action-setup@v2 - name: Setup Node.js From d96425d19e7dc4a493b0eaf45670949e3a26091d Mon Sep 17 00:00:00 2001 From: Knut Sveidqvist Date: Fri, 19 Jan 2024 14:57:45 +0100 Subject: [PATCH 131/217] #3358 Reviving arrow heads after merging develop --- cypress/platform/knsv2.html | 6 +++--- packages/mermaid/src/dagre-wrapper/edges.js | 6 +++--- .../mermaid/src/diagrams/block/blockRenderer.ts | 5 +++-- .../mermaid/src/diagrams/block/renderHelpers.ts | 14 +++++++++++--- 4 files changed, 20 insertions(+), 11 deletions(-) diff --git a/cypress/platform/knsv2.html b/cypress/platform/knsv2.html index f8722e580e..22820680db 100644 --- a/cypress/platform/knsv2.html +++ b/cypress/platform/knsv2.html @@ -65,12 +65,12 @@
     block-beta
    -  A space:2 B
    -  A-- "X" -->B
    +  a space:2 c
    +  a-- "b" --> c
         
     flowchart LR
    -  A-- "X" -->B
    +  X-- "y" -->z
         
     block-beta
    diff --git a/packages/mermaid/src/dagre-wrapper/edges.js b/packages/mermaid/src/dagre-wrapper/edges.js
    index ef96a3269c..36a4e25538 100644
    --- a/packages/mermaid/src/dagre-wrapper/edges.js
    +++ b/packages/mermaid/src/dagre-wrapper/edges.js
    @@ -134,7 +134,7 @@ function setTerminalWidth(fo, value) {
     }
     
     export const positionEdgeLabel = (edge, paths) => {
    -  log.info('Moving label abc78 ', edge.id, edge.label, edgeLabels[edge.id]);
    +  log.info('Moving label abc88 ', edge.id, edge.label, edgeLabels[edge.id], paths);
       let path = paths.updatedPath ? paths.updatedPath : paths.originalPath;
       if (edge.label) {
         const el = edgeLabels[edge.id];
    @@ -152,7 +152,7 @@ export const positionEdgeLabel = (edge, paths) => {
             pos.x,
             ',',
             pos.y,
    -        ') abc78'
    +        ') abc88'
           );
           if (paths.updatedPath) {
             x = pos.x;
    @@ -376,7 +376,7 @@ export const insertEdge = function (elem, e, edge, clusterDb, diagramType, graph
       let pointsHasChanged = false;
       const tail = graph.node(e.v);
       var head = graph.node(e.w);
    -  log.info('abc88 InsertEdge (head & tail): ', e.v, head, ' --- ', e.w, tail);
    +  log.info('abc88 InsertEdge (head & tail) fin: ', e.v, head, ' --- ', e.w, tail);
     
       if (head?.intersect && tail?.intersect) {
         points = points.slice(1, edge.points.length - 1);
    diff --git a/packages/mermaid/src/diagrams/block/blockRenderer.ts b/packages/mermaid/src/diagrams/block/blockRenderer.ts
    index c47671b88b..31790de6e9 100644
    --- a/packages/mermaid/src/diagrams/block/blockRenderer.ts
    +++ b/packages/mermaid/src/diagrams/block/blockRenderer.ts
    @@ -58,7 +58,8 @@ export const draw = async function (
     
       // Add the marker definitions to the svg as marker tags
       // insertMarkers(svg, markers, diagObj.type, diagObj.arrowMarkerAbsolute);
    -  insertMarkers(svg, markers, diagObj.type, true);
    +  // insertMarkers(svg, markers, diagObj.type, true);
    +  insertMarkers(svg, markers, diagObj.type, id);
     
       const bl = db.getBlocks();
       const blArr = db.getBlocksFlat();
    @@ -69,7 +70,7 @@ export const draw = async function (
       const bounds = layout(db);
       // log.debug('Here be blocks', bl);
       await insertBlocks(nodes, bl, db);
    -  await insertEdges(nodes, edges, blArr, db);
    +  await insertEdges(nodes, edges, blArr, db, id);
     
       // log.debug('Here', bl);
     
    diff --git a/packages/mermaid/src/diagrams/block/renderHelpers.ts b/packages/mermaid/src/diagrams/block/renderHelpers.ts
    index 588bca786f..2215e9e3ec 100644
    --- a/packages/mermaid/src/diagrams/block/renderHelpers.ts
    +++ b/packages/mermaid/src/diagrams/block/renderHelpers.ts
    @@ -1,6 +1,6 @@
     import { getStylesFromArray } from '../../utils.js';
     import { insertNode, positionNode } from '../../dagre-wrapper/nodes.js';
    -import { insertEdge, insertEdgeLabel } from '../../dagre-wrapper/edges.js';
    +import { insertEdge, insertEdgeLabel, positionEdgeLabel } from '../../dagre-wrapper/edges.js';
     import * as graphlib from 'dagre-d3-es/src/graphlib/index.js';
     import { getConfig } from '../../config.js';
     import type { ContainerElement } from 'd3';
    @@ -185,7 +185,8 @@ export async function insertEdges(
       elem: ContainerElement,
       edges: Block[],
       blocks: Block[],
    -  db: BlockDB
    +  db: BlockDB,
    +  id: string
     ) {
       const g = new graphlib.Graph({
         multigraph: true,
    @@ -238,7 +239,8 @@ export async function insertEdges(
               },
               undefined,
               'block',
    -          g
    +          g,
    +          id
             );
             if (edge.label) {
               await insertEdgeLabel(elem, {
    @@ -250,6 +252,12 @@ export async function insertEdges(
                 points,
                 classes: 'edge-thickness-normal edge-pattern-solid flowchart-link LS-a1 LE-b1',
               });
    +          await positionEdgeLabel(
    +            { ...edge, x: points[1].x, y: points[1].y },
    +            {
    +              originalPath: points,
    +            }
    +          );
             }
           }
         }
    
    From f5dd24bce4488cb636f384b949c0ea5583eda860 Mon Sep 17 00:00:00 2001
    From: Sidharth Vinod 
    Date: Fri, 19 Jan 2024 19:29:45 +0530
    Subject: [PATCH 132/217] Remove ::
    
    ---
     .github/workflows/e2e.yml | 2 +-
     1 file changed, 1 insertion(+), 1 deletion(-)
    
    diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e.yml
    index 674f276727..30c25cb914 100644
    --- a/.github/workflows/e2e.yml
    +++ b/.github/workflows/e2e.yml
    @@ -22,7 +22,7 @@ jobs:
       cache:
         runs-on: ubuntu-latest
         steps:
    -      - run: echo "${{ toJSON(github) }}"
    +      - run: echo "${{ toJSON(github) }}" | sed 's/::/:/g'
           - uses: actions/checkout@v4
           - uses: pnpm/action-setup@v2
           - name: Setup Node.js
    
    From 3935f6b389e715382c0701c499ca6825fe34b299 Mon Sep 17 00:00:00 2001
    From: Sidharth Vinod 
    Date: Fri, 19 Jan 2024 19:31:25 +0530
    Subject: [PATCH 133/217] Remove ::
    
    ---
     .github/workflows/e2e.yml | 3 ++-
     1 file changed, 2 insertions(+), 1 deletion(-)
    
    diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e.yml
    index 30c25cb914..7d3bd3628f 100644
    --- a/.github/workflows/e2e.yml
    +++ b/.github/workflows/e2e.yml
    @@ -22,7 +22,8 @@ jobs:
       cache:
         runs-on: ubuntu-latest
         steps:
    -      - run: echo "${{ toJSON(github) }}" | sed 's/::/:/g'
    +      - run: |
    +          echo "${{ toJSON(github) }}" | sed 's/::/:/g'
           - uses: actions/checkout@v4
           - uses: pnpm/action-setup@v2
           - name: Setup Node.js
    
    From 8bfb269b373611d3b4884177c47f1c9ed71289ce Mon Sep 17 00:00:00 2001
    From: Sidharth Vinod 
    Date: Fri, 19 Jan 2024 19:33:59 +0530
    Subject: [PATCH 134/217] Remove ::
    
    ---
     .github/workflows/e2e.yml | 2 +-
     1 file changed, 1 insertion(+), 1 deletion(-)
    
    diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e.yml
    index 7d3bd3628f..aab0e1facd 100644
    --- a/.github/workflows/e2e.yml
    +++ b/.github/workflows/e2e.yml
    @@ -23,7 +23,7 @@ jobs:
         runs-on: ubuntu-latest
         steps:
           - run: |
    -          echo "${{ toJSON(github) }}" | sed 's/::/:/g'
    +          echo '${{ toJSON(github) }}' | sed 's/::/:/g'
           - uses: actions/checkout@v4
           - uses: pnpm/action-setup@v2
           - name: Setup Node.js
    
    From aadf32ab3edfc48ba48445e828349cb7b74f3be8 Mon Sep 17 00:00:00 2001
    From: Sidharth Vinod 
    Date: Fri, 19 Jan 2024 19:45:55 +0530
    Subject: [PATCH 135/217] Ignore push events on merge queue
    
    ---
     .github/workflows/e2e.yml | 4 +++-
     1 file changed, 3 insertions(+), 1 deletion(-)
    
    diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e.yml
    index aab0e1facd..36ec672a28 100644
    --- a/.github/workflows/e2e.yml
    +++ b/.github/workflows/e2e.yml
    @@ -8,6 +8,8 @@ name: E2E
     
     on:
       push:
    +    branches-ignore:
    +      - 'gh-readonly-queue/**'
       pull_request:
       merge_group:
     
    @@ -16,7 +18,7 @@ permissions:
     
     env:
       # For PRs and MergeQueues, the target commit is used, and for push events, github.event.previous is used.
    -  targetHash: ${{ github.event_name == 'pull_request' && github.event.pull_request.base.sha || github.event_name == 'merge_group' && github.event.merge_group.base_sha || github.event.before }}
    +  targetHash: ${{ github.event.pull_request.base.sha || github.event.merge_group.base_sha || github.event.before }}
     
     jobs:
       cache:
    
    From d0224b23b0e112c37debff62d685510117e226a5 Mon Sep 17 00:00:00 2001
    From: Sidharth Vinod 
    Date: Fri, 19 Jan 2024 19:47:42 +0530
    Subject: [PATCH 136/217] Cleanup e2e.yml
    
    ---
     .github/workflows/e2e.yml | 2 --
     1 file changed, 2 deletions(-)
    
    diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e.yml
    index 36ec672a28..c23dc88baf 100644
    --- a/.github/workflows/e2e.yml
    +++ b/.github/workflows/e2e.yml
    @@ -24,8 +24,6 @@ jobs:
       cache:
         runs-on: ubuntu-latest
         steps:
    -      - run: |
    -          echo '${{ toJSON(github) }}' | sed 's/::/:/g'
           - uses: actions/checkout@v4
           - uses: pnpm/action-setup@v2
           - name: Setup Node.js
    
    From 1f37b6c91bc410c25968f7b7bda87debf966f38a Mon Sep 17 00:00:00 2001
    From: Sidharth Vinod 
    Date: Fri, 19 Jan 2024 23:28:43 +0530
    Subject: [PATCH 137/217] Fix lint
    
    ---
     packages/mermaid/src/docs/ecosystem/integrations-community.md | 1 -
     1 file changed, 1 deletion(-)
    
    diff --git a/packages/mermaid/src/docs/ecosystem/integrations-community.md b/packages/mermaid/src/docs/ecosystem/integrations-community.md
    index 5587253661..73c4b9ef0a 100644
    --- a/packages/mermaid/src/docs/ecosystem/integrations-community.md
    +++ b/packages/mermaid/src/docs/ecosystem/integrations-community.md
    @@ -245,4 +245,3 @@ Communication tools and platforms
     - [mermaid-server: Generate diagrams using a HTTP request](https://github.com/TomWright/mermaid-server)
     - [ExDoc](https://github.com/elixir-lang/ex_doc)
       - [Rendering Mermaid graphs](https://github.com/elixir-lang/ex_doc#rendering-mermaid-graphs)
    -
    
    From 1e70b3817e3c3fcb414af8c217196d916b0564b7 Mon Sep 17 00:00:00 2001
    From: Sidharth Vinod 
    Date: Fri, 19 Jan 2024 23:38:27 +0530
    Subject: [PATCH 138/217] Use pnpm/action-setup@v2
    
    ---
     .github/workflows/update-browserlist.yml | 3 ++-
     1 file changed, 2 insertions(+), 1 deletion(-)
    
    diff --git a/.github/workflows/update-browserlist.yml b/.github/workflows/update-browserlist.yml
    index 463160256d..7c376e3bdf 100644
    --- a/.github/workflows/update-browserlist.yml
    +++ b/.github/workflows/update-browserlist.yml
    @@ -9,7 +9,8 @@ jobs:
         runs-on: ubuntu-latest
         steps:
           - uses: actions/checkout@v4
    -      - run: npm install pnpm -g && npx update-browserslist-db@latest
    +      - uses: pnpm/action-setup@v2
    +      - run: npx update-browserslist-db@latest
           - name: Commit changes
             uses: EndBug/add-and-commit@v9
             with:
    
    From 84a18a1858a47f547022922fb30252328f4a77ee Mon Sep 17 00:00:00 2001
    From: Sidharth Vinod 
    Date: Fri, 19 Jan 2024 23:47:07 +0530
    Subject: [PATCH 139/217] Fix Update Browserslist
    
    ---
     .github/workflows/update-browserlist.yml | 9 ++++++++-
     1 file changed, 8 insertions(+), 1 deletion(-)
    
    diff --git a/.github/workflows/update-browserlist.yml b/.github/workflows/update-browserlist.yml
    index 0a83df795d..f4fa2a982f 100644
    --- a/.github/workflows/update-browserlist.yml
    +++ b/.github/workflows/update-browserlist.yml
    @@ -9,10 +9,17 @@ jobs:
         runs-on: ubuntu-latest
         steps:
           - uses: actions/checkout@v4
    -      - run: npx browserslist@latest --update-db
    +      - uses: pnpm/action-setup@v2
    +      - run: npx update-browserslist-db@latest
           - name: Commit changes
             uses: EndBug/add-and-commit@v9
             with:
               author_name: ${{ github.actor }}
               author_email: ${{ github.actor }}@users.noreply.github.com
               message: 'chore: update browsers list'
    +          push: false
    +      - name: Create Pull Request
    +        uses: peter-evans/create-pull-request@v5
    +        with:
    +          branch: update-browserslist
    +          title: Update Browserslist
    
    From 8fd268d59be6c0bc7d4d25eb5fae6abe6bc9320b Mon Sep 17 00:00:00 2001
    From: Vitor Soares Silva 
    Date: Fri, 19 Jan 2024 16:10:23 -0300
    Subject: [PATCH 140/217] add sequenceDiagram link e2e test
    
    ---
     .../rendering/sequencediagram.spec.js         | 28 +++++++++++++++++++
     1 file changed, 28 insertions(+)
    
    diff --git a/cypress/integration/rendering/sequencediagram.spec.js b/cypress/integration/rendering/sequencediagram.spec.js
    index 27e03da9c0..10432f057f 100644
    --- a/cypress/integration/rendering/sequencediagram.spec.js
    +++ b/cypress/integration/rendering/sequencediagram.spec.js
    @@ -792,6 +792,34 @@ context('Sequence diagram', () => {
         });
       });
       context('links', () => {
    +    it('should support actor links', () => {
    +      renderGraph(
    +        `
    +      sequenceDiagram
    +        link Alice: Dashboard @ https://dashboard.contoso.com/alice
    +        link Alice: Wiki @ https://wiki.contoso.com/alice
    +        link John: Dashboard @ https://dashboard.contoso.com/john
    +        link John: Wiki @ https://wiki.contoso.com/john
    +        Alice->>John: Hello John
    + John-->>Alice: Great

    day! + `, + { securityLevel: 'loose' } + ); + cy.get('#actor0_popup').should((popupMenu) => { + const style = popupMenu.attr('style'); + expect(style).to.undefined; + }); + cy.get('#root-0').click(); + cy.get('#actor0_popup').should((popupMenu) => { + const style = popupMenu.attr('style'); + expect(style).to.match(/^display: block;$/); + }); + cy.get('#root-0').click(); + cy.get('#actor0_popup').should((popupMenu) => { + const style = popupMenu.attr('style'); + expect(style).to.match(/^display: none;$/); + }); + }); it('should support actor links and properties EXPERIMENTAL: USE WITH CAUTION', () => { //Be aware that the syntax for "properties" is likely to be changed. imgSnapshotTest( From 2bbdd15031722cf4689526f48015b36ae1c7e594 Mon Sep 17 00:00:00 2001 From: Reda Al Sulais Date: Sat, 20 Jan 2024 13:30:49 +0300 Subject: [PATCH 141/217] docs: fix swimm link --- docs/ecosystem/integrations-community.md | 2 +- packages/mermaid/src/docs/ecosystem/integrations-community.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/ecosystem/integrations-community.md b/docs/ecosystem/integrations-community.md index a9174d8aa9..6ad02f6b69 100644 --- a/docs/ecosystem/integrations-community.md +++ b/docs/ecosystem/integrations-community.md @@ -60,7 +60,7 @@ To add an integration to this list, see the [Integrations - create page](./integ - [Mermaid Flow Visual Editor](https://www.mermaidflow.app) ✅ - [Mermerd](https://github.com/KarnerTh/mermerd) - [Slab](https://slab.com) ✅ -- [Swimm](https://docs.swimm.io/Features/diagrams-and-charts#mermaid--swimm--up-to-date-diagrams-) ✅ +- [Swimm](https://docs.swimm.io/features/diagrams-and-charts/#mermaid--swimm--up-to-date-diagrams-) ✅ - [NotesHub](https://noteshub.app) ✅ - [Notion](https://notion.so) ✅ - [Observable](https://observablehq.com/@observablehq/mermaid) ✅ diff --git a/packages/mermaid/src/docs/ecosystem/integrations-community.md b/packages/mermaid/src/docs/ecosystem/integrations-community.md index 73c4b9ef0a..a567e67888 100644 --- a/packages/mermaid/src/docs/ecosystem/integrations-community.md +++ b/packages/mermaid/src/docs/ecosystem/integrations-community.md @@ -55,7 +55,7 @@ To add an integration to this list, see the [Integrations - create page](./integ - [Mermaid Flow Visual Editor](https://www.mermaidflow.app) ✅ - [Mermerd](https://github.com/KarnerTh/mermerd) - [Slab](https://slab.com) ✅ -- [Swimm](https://docs.swimm.io/Features/diagrams-and-charts#mermaid--swimm--up-to-date-diagrams-) ✅ +- [Swimm](https://docs.swimm.io/features/diagrams-and-charts/#mermaid--swimm--up-to-date-diagrams-) ✅ - [NotesHub](https://noteshub.app) ✅ - [Notion](https://notion.so) ✅ - [Observable](https://observablehq.com/@observablehq/mermaid) ✅ From 4f60a2747256f11902b5dc3bf19d55654205c772 Mon Sep 17 00:00:00 2001 From: Matheus B Date: Sat, 20 Jan 2024 20:57:58 -0300 Subject: [PATCH 142/217] Change repetitive values into consts --- .../src/diagrams/git/gitGraphRenderer.js | 40 +++++++++++-------- 1 file changed, 23 insertions(+), 17 deletions(-) diff --git a/packages/mermaid/src/diagrams/git/gitGraphRenderer.js b/packages/mermaid/src/diagrams/git/gitGraphRenderer.js index 4790949b57..6124d72c68 100644 --- a/packages/mermaid/src/diagrams/git/gitGraphRenderer.js +++ b/packages/mermaid/src/diagrams/git/gitGraphRenderer.js @@ -112,8 +112,11 @@ const drawCommits = (svg, commits, modifyGraph) => { }); const isParallelCommits = gitGraphConfig.parallelCommits; + const layoutOffset = 10; + const commitStep = 40; sortedKeys.forEach((key) => { const commit = commits[key]; + const posWithOffset = pos + layoutOffset; if (isParallelCommits) { if (!commit.parents.length) { @@ -123,12 +126,15 @@ const drawCommits = (svg, commits, modifyGraph) => { } } else { const closestParent = findClosestParent(commit.parents); - pos = dir === 'TB' ? commitPos[closestParent].y + 40 : commitPos[closestParent].x + 40; + pos = + dir === 'TB' + ? commitPos[closestParent].y + commitStep + : commitPos[closestParent].x + commitStep; } } - const y = dir === 'TB' ? pos + 10 : branchPos[commit.branch].pos; - const x = dir === 'TB' ? branchPos[commit.branch].pos : pos + 10; + const y = dir === 'TB' ? posWithOffset : branchPos[commit.branch].pos; + const x = dir === 'TB' ? branchPos[commit.branch].pos : posWithOffset; // Don't draw the commits now but calculate the positioning which is used by the branch lines etc. if (modifyGraph) { @@ -253,9 +259,9 @@ const drawCommits = (svg, commits, modifyGraph) => { } } if (dir === 'TB') { - commitPos[commit.id] = { x: x, y: pos + 10 }; + commitPos[commit.id] = { x: x, y: posWithOffset }; } else { - commitPos[commit.id] = { x: pos + 10, y: y }; + commitPos[commit.id] = { x: posWithOffset, y: y }; } // The first iteration over the commits are for positioning purposes, this @@ -284,7 +290,7 @@ const drawCommits = (svg, commits, modifyGraph) => { // Now we have the label, lets position the background labelBkg - .attr('x', pos + 10 - bbox.width / 2 - py) + .attr('x', posWithOffset - bbox.width / 2 - py) .attr('y', y + 13.5) .attr('width', bbox.width + 2 * py) .attr('height', bbox.height + 2 * py); @@ -295,7 +301,7 @@ const drawCommits = (svg, commits, modifyGraph) => { } if (dir !== 'TB') { - text.attr('x', pos + 10 - bbox.width / 2); + text.attr('x', posWithOffset - bbox.width / 2); } if (gitGraphConfig.rotateCommitLabel) { if (dir === 'TB') { @@ -321,7 +327,7 @@ const drawCommits = (svg, commits, modifyGraph) => { .attr('class', 'tag-label') .text(commit.tag); let tagBbox = tag.node().getBBox(); - tag.attr('x', pos + 10 - tagBbox.width / 2); + tag.attr('x', posWithOffset - tagBbox.width / 2); const h2 = tagBbox.height / 2; const ly = y - 19.2; @@ -330,10 +336,10 @@ const drawCommits = (svg, commits, modifyGraph) => { ` ${pos - tagBbox.width / 2 - px / 2},${ly + py} ${pos - tagBbox.width / 2 - px / 2},${ly - py} - ${pos + 10 - tagBbox.width / 2 - px},${ly - h2 - py} - ${pos + 10 + tagBbox.width / 2 + px},${ly - h2 - py} - ${pos + 10 + tagBbox.width / 2 + px},${ly + h2 + py} - ${pos + 10 - tagBbox.width / 2 - px},${ly + h2 + py}` + ${posWithOffset - tagBbox.width / 2 - px},${ly - h2 - py} + ${posWithOffset + tagBbox.width / 2 + px},${ly - h2 - py} + ${posWithOffset + tagBbox.width / 2 + px},${ly + h2 + py} + ${posWithOffset - tagBbox.width / 2 - px},${ly + h2 + py}` ); hole @@ -350,10 +356,10 @@ const drawCommits = (svg, commits, modifyGraph) => { ` ${x},${pos + py} ${x},${pos - py} - ${x + 10},${pos - h2 - py} - ${x + 10 + tagBbox.width + px},${pos - h2 - py} - ${x + 10 + tagBbox.width + px},${pos + h2 + py} - ${x + 10},${pos + h2 + py}` + ${x + layoutOffset},${pos - h2 - py} + ${x + layoutOffset + tagBbox.width + px},${pos - h2 - py} + ${x + layoutOffset + tagBbox.width + px},${pos + h2 + py} + ${x + layoutOffset},${pos + h2 + py}` ) .attr('transform', 'translate(12,12) rotate(45, ' + x + ',' + pos + ')'); hole @@ -367,7 +373,7 @@ const drawCommits = (svg, commits, modifyGraph) => { } } } - pos += 50; + pos += commitStep + layoutOffset; if (pos > maxPos) { maxPos = pos; } From fe89b9510da2267e80f71028cf8fd5b705813e87 Mon Sep 17 00:00:00 2001 From: Knut Sveidqvist Date: Mon, 22 Jan 2024 14:14:54 +0100 Subject: [PATCH 143/217] #3358 Adjusting docs and a bug fix for nested blocks --- cypress/platform/knsv2.html | 41 +++++++- docs/syntax/block.md | 98 ++++++++----------- packages/mermaid/src/diagrams/block/layout.ts | 7 +- .../mermaid/src/docs/.vitepress/config.ts | 11 ++- packages/mermaid/src/docs/syntax/block.md | 55 ++++------- 5 files changed, 110 insertions(+), 102 deletions(-) diff --git a/cypress/platform/knsv2.html b/cypress/platform/knsv2.html index 22820680db..8c6bf8a63b 100644 --- a/cypress/platform/knsv2.html +++ b/cypress/platform/knsv2.html @@ -65,10 +65,47 @@
     block-beta
    -  a space:2 c
    -  a-- "b" --> c
    +columns 3
    +a:3
    +block:e:3
    +f
    +end
    +g
    +
    +    
    +
    +block-beta
    +  block:e:4
    +    columns 2
    +      f
    +      g
    +  end
    +
         
    +block-beta
    +  block:e:4
    +    columns 2
    +      f
    +      g
    +      h
    +  end
    +
    +    
    +
    +block-beta
    +  columns 4
    +  a b c d
    +  block:e:4
    +    columns 2
    +      f
    +      g
    +      h
    +  end
    +  i:4
    +
    +    
    +
     flowchart LR
       X-- "y" -->z
         
    diff --git a/docs/syntax/block.md b/docs/syntax/block.md index c33f31301d..638aa34b68 100644 --- a/docs/syntax/block.md +++ b/docs/syntax/block.md @@ -181,22 +181,22 @@ In diagrams with varying block sizes, Mermaid automatically adjusts the column w ```mermaid-example block-beta -columns 3 -a:3 -block:e:3 -f -end -g + columns 3 + a:3 + block:e:3 + f + end + g ``` ```mermaid block-beta -columns 3 -a:3 -block:e:3 -f -end -g + columns 3 + a:3 + block:e:3 + f + end + g ``` This example demonstrates how Mermaid dynamically adjusts the width of the columns to accommodate the widest block, in this case, 'a' and the composite block 'e'. This dynamic adjustment is essential for creating visually balanced and easy-to-understand diagrams. @@ -326,7 +326,7 @@ block-beta Parallelogram and trapezoid shapes are perfect for inputs/outputs and transitional processes: ```mermaid-example -flowchart TD +block-beta id1[/"This is the text in the box"/] id2[\"This is the text in the box"\] A[/"Christmas"\] @@ -334,7 +334,7 @@ flowchart TD ``` ```mermaid -flowchart TD +block-beta id1[/"This is the text in the box"/] id2[\"This is the text in the box"\] A[/"Christmas"\] @@ -346,12 +346,12 @@ flowchart TD For highlighting critical or high-priority components, a double circle can be effective: ```mermaid-example -flowchart TD +block-beta id1((("This is the text in the circle"))) ``` ```mermaid -flowchart TD +block-beta id1((("This is the text in the circle"))) ``` @@ -389,6 +389,22 @@ block-beta Space blocks can be used to create intentional empty spaces in the diagram, which is useful for layout and readability: +```mermaid-example +block-beta + columns 3 + a space b + c d e +``` + +```mermaid +block-beta + columns 3 + a space b + c d e +``` + +or + ```mermaid-example block-beta space:3 @@ -435,21 +451,6 @@ block-beta This example illustrates a direct connection from block 'A' to block 'B', using a straightforward arrow. -**Example - Open Link:** -For connections that are less direct or to represent a different type of relationship, an open link (without an arrowhead) can be used: - -```mermaid-example -block-beta - A space B - A --- B -``` - -```mermaid -block-beta - A space B - A --- B -``` - This syntax creates a line connecting 'A' and 'B', implying a relationship or connection without indicating a specific direction. ### Text on Links @@ -473,25 +474,6 @@ block-beta This example show how to add descriptive text to the links, enhancing the information conveyed by the diagram. -### Advanced Link Types - -Mermaid also supports various advanced link types, such as dotted lines, thick links, and different arrowheads, to represent different kinds of relationships or interactions. - -**Example - Dotted and Thick Links** -A dotted link can be used to represent a weaker or less formal relationship: - -```mermaid-example -block-beta - A space:2 B - A-.->B -``` - -```mermaid -block-beta - A space:2 B - A-.->B -``` - Example - Edges and Styles: ```mermaid-example @@ -575,9 +557,9 @@ Illustrating a simple software system architecture with interconnected component ```mermaid-example block-beta columns 3 - Frontend blockArrowId6<["  "]>(right) Backend - space:2 down<["  "]>(down) - Disk left<["  "]>(left) Database[("Database")] + Frontend blockArrowId6<[" "]>(right) Backend + space:2 down<[" "]>(down) + Disk left<[" "]>(left) Database[("Database")] classDef front fill:#696,stroke:#333; classDef back fill:#969,stroke:#333; @@ -588,9 +570,9 @@ block-beta ```mermaid block-beta columns 3 - Frontend blockArrowId6<["  "]>(right) Backend - space:2 down<["  "]>(down) - Disk left<["  "]>(left) Database[("Database")] + Frontend blockArrowId6<[" "]>(right) Backend + space:2 down<[" "]>(down) + Disk left<[" "]>(left) Database[("Database")] classDef front fill:#696,stroke:#333; classDef back fill:#969,stroke:#333; @@ -608,7 +590,7 @@ Representing a business process flow with decision points and multiple stages: block-beta columns 3 Start(("Start")) space:2 - down<["  "]>(down) space:2 + down<[" "]>(down) space:2 Decision{{"Make Decision"}} right<["Yes"]>(right) Process1["Process A"] downAgain<["No"]>(down) space r3<["Done"]>(down) Process2["Process B"] r2<["Done"]>(right) End(("End")) @@ -622,7 +604,7 @@ block-beta block-beta columns 3 Start(("Start")) space:2 - down<["  "]>(down) space:2 + down<[" "]>(down) space:2 Decision{{"Make Decision"}} right<["Yes"]>(right) Process1["Process A"] downAgain<["No"]>(down) space r3<["Done"]>(down) Process2["Process B"] r2<["Done"]>(right) End(("End")) diff --git a/packages/mermaid/src/diagrams/block/layout.ts b/packages/mermaid/src/diagrams/block/layout.ts index f3ecd02549..629d87083b 100644 --- a/packages/mermaid/src/diagrams/block/layout.ts +++ b/packages/mermaid/src/diagrams/block/layout.ts @@ -198,10 +198,10 @@ function setBlockSizes(block: Block, db: BlockDB, sieblingWidth = 0, sieblingHei width = block?.size?.width || 0; // Grow children to fit - const num = block.children.length; + const num = columns > 0 ? Math.min(block.children.length, columns) : block.children.length; if (num > 0) { const childWidth = (width - num * padding - padding) / num; - // log.debug('abc95 (finale calc) width', block.id, width, block.size?.width, childWidth); + log.debug('abc95 (growing to fit) width', block.id, width, block.size?.width, childWidth); for (const child of block.children) { if (child.size) { child.size.width = childWidth; @@ -264,7 +264,8 @@ function layoutBlocks(block: Block, db: BlockDB) { const { px, py } = calculateBlockPosition(columns, columnPos); if (py != rowPos) { rowPos = py; - startingPosX = block?.size?.x || -padding; + startingPosX = block?.size?.x ? block?.size?.x + (-block?.size?.width / 2 || 0) : -padding; + log.debug('New row in layout for block', block.id, ' and child ', child.id, rowPos); } log.debug( 'abc89 layout blocks (child) id:', diff --git a/packages/mermaid/src/docs/.vitepress/config.ts b/packages/mermaid/src/docs/.vitepress/config.ts index f5647e3c37..4a383b68d8 100644 --- a/packages/mermaid/src/docs/.vitepress/config.ts +++ b/packages/mermaid/src/docs/.vitepress/config.ts @@ -147,13 +147,14 @@ function sidebarSyntax() { { text: 'Pie Chart', link: '/syntax/pie' }, { text: 'Quadrant Chart', link: '/syntax/quadrantChart' }, { text: 'Requirement Diagram', link: '/syntax/requirementDiagram' }, - { text: 'Gitgraph (Git) Diagram 🔥', link: '/syntax/gitgraph' }, + { text: 'Gitgraph (Git) Diagram', link: '/syntax/gitgraph' }, { text: 'C4 Diagram 🦺⚠️', link: '/syntax/c4' }, - { text: 'Mindmaps 🔥', link: '/syntax/mindmap' }, - { text: 'Timeline 🔥', link: '/syntax/timeline' }, - { text: 'Zenuml 🔥', link: '/syntax/zenuml' }, - { text: 'Sankey 🔥', link: '/syntax/sankey' }, + { text: 'Mindmaps', link: '/syntax/mindmap' }, + { text: 'Timeline', link: '/syntax/timeline' }, + { text: 'Zenuml', link: '/syntax/zenuml' }, + { text: 'Sankey', link: '/syntax/sankey' }, { text: 'XYChart 🔥', link: '/syntax/xyChart' }, + { text: 'Block Diagram 🔥', link: '/syntax/block' }, { text: 'Other Examples', link: '/syntax/examples' }, ], }, diff --git a/packages/mermaid/src/docs/syntax/block.md b/packages/mermaid/src/docs/syntax/block.md index 9186d68c6a..c80492a2fd 100644 --- a/packages/mermaid/src/docs/syntax/block.md +++ b/packages/mermaid/src/docs/syntax/block.md @@ -138,12 +138,12 @@ In diagrams with varying block sizes, Mermaid automatically adjusts the column w ```mermaid-example block-beta -columns 3 -a:3 -block:e:3 -f -end -g + columns 3 + a:3 + block:e:3 + f + end + g ``` This example demonstrates how Mermaid dynamically adjusts the width of the columns to accommodate the widest block, in this case, 'a' and the composite block 'e'. This dynamic adjustment is essential for creating visually balanced and easy-to-understand diagrams. @@ -233,7 +233,7 @@ block-beta Parallelogram and trapezoid shapes are perfect for inputs/outputs and transitional processes: ```mermaid-example -flowchart TD +block-beta id1[/"This is the text in the box"/] id2[\"This is the text in the box"\] A[/"Christmas"\] @@ -245,7 +245,7 @@ flowchart TD For highlighting critical or high-priority components, a double circle can be effective: ```mermaid-example -flowchart TD +block-beta id1((("This is the text in the circle"))) ``` @@ -272,6 +272,15 @@ block-beta Space blocks can be used to create intentional empty spaces in the diagram, which is useful for layout and readability: +```mermaid-example +block-beta + columns 3 + a space b + c d e +``` + +or + ```mermaid-example block-beta space:3 @@ -306,15 +315,6 @@ block-beta This example illustrates a direct connection from block 'A' to block 'B', using a straightforward arrow. -**Example - Open Link:** -For connections that are less direct or to represent a different type of relationship, an open link (without an arrowhead) can be used: - -```mermaid-example -block-beta - A space B - A --- B -``` - This syntax creates a line connecting 'A' and 'B', implying a relationship or connection without indicating a specific direction. ### Text on Links @@ -332,19 +332,6 @@ block-beta This example show how to add descriptive text to the links, enhancing the information conveyed by the diagram. -### Advanced Link Types - -Mermaid also supports various advanced link types, such as dotted lines, thick links, and different arrowheads, to represent different kinds of relationships or interactions. - -**Example - Dotted and Thick Links** -A dotted link can be used to represent a weaker or less formal relationship: - -```mermaid-example -block-beta - A space:2 B - A-.->B -``` - Example - Edges and Styles: ```mermaid-example @@ -403,9 +390,9 @@ Illustrating a simple software system architecture with interconnected component ```mermaid block-beta columns 3 - Frontend blockArrowId6<["  "]>(right) Backend - space:2 down<["  "]>(down) - Disk left<["  "]>(left) Database[("Database")] + Frontend blockArrowId6<[" "]>(right) Backend + space:2 down<[" "]>(down) + Disk left<[" "]>(left) Database[("Database")] classDef front fill:#696,stroke:#333; classDef back fill:#969,stroke:#333; @@ -423,7 +410,7 @@ Representing a business process flow with decision points and multiple stages: block-beta columns 3 Start(("Start")) space:2 - down<["  "]>(down) space:2 + down<[" "]>(down) space:2 Decision{{"Make Decision"}} right<["Yes"]>(right) Process1["Process A"] downAgain<["No"]>(down) space r3<["Done"]>(down) Process2["Process B"] r2<["Done"]>(right) End(("End")) From 1629a91a25a075cbb0e2ee1ddd06173843a6604a Mon Sep 17 00:00:00 2001 From: Knut Sveidqvist Date: Mon, 22 Jan 2024 14:52:02 +0100 Subject: [PATCH 144/217] Updated lockfile --- pnpm-lock.yaml | 756 +++++++++++++++++++++++++------------------------ 1 file changed, 387 insertions(+), 369 deletions(-) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index d09113a2ca..8daca235a9 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -519,7 +519,7 @@ importers: version: 1.1.0 unocss: specifier: ^0.58.0 - version: 0.58.0(postcss@8.4.31)(rollup@2.79.1)(vite@4.5.0) + version: 0.58.0(postcss@8.4.33)(rollup@2.79.1)(vite@4.5.0) unplugin-vue-components: specifier: ^0.26.0 version: 0.26.0(rollup@2.79.1)(vue@3.3.4) @@ -531,7 +531,7 @@ importers: version: 0.17.0(vite@4.5.0)(workbox-build@7.0.0)(workbox-window@7.0.0) vitepress: specifier: 1.0.0-rc.31 - version: 1.0.0-rc.31(@algolia/client-search@4.19.1)(@types/node@18.17.5)(postcss@8.4.31)(search-insights@2.7.0)(typescript@5.1.6) + version: 1.0.0-rc.31(@algolia/client-search@4.19.1)(@types/node@18.17.5)(postcss@8.4.33)(search-insights@2.7.0)(typescript@5.1.6) workbox-window: specifier: ^7.0.0 version: 7.0.0 @@ -1108,22 +1108,6 @@ packages: engines: {node: '>=4'} dev: true - /@babel/code-frame@7.22.10: - resolution: {integrity: sha512-/KKIMG4UEL35WmI9OlvMhurwtytjvXoFcGNrOvyG9zIzA8YmPjVtIZUf7b05+TPO7G7/GEmLHDaoCgACHl9hhA==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/highlight': 7.22.20 - chalk: 2.4.2 - dev: true - - /@babel/code-frame@7.22.13: - resolution: {integrity: sha512-XktuhWlJ5g+3TJXc5upd9Ks1HutSArik6jf2eAjYFyIOf4ej3RN+184cZbzDvbPnuTJIUhPKKJE3cIsYTiAT3w==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/highlight': 7.22.20 - chalk: 2.4.2 - dev: true - /@babel/code-frame@7.23.5: resolution: {integrity: sha512-CgH3s1a96LipHCmSUmYFPwY7MNx8C3avkq7i4Wl3cfa662ldtUe4VM1TPXX70pfmrlWTb6jLqTYrZyT2ZTJBgA==} engines: {node: '>=6.9.0'} @@ -1137,29 +1121,6 @@ packages: engines: {node: '>=6.9.0'} dev: true - /@babel/core@7.22.10: - resolution: {integrity: sha512-fTmqbbUBAwCcre6zPzNngvsI0aNrPZe77AeqvDxWM9Nm+04RrJ3CAmGHA9f7lJQY6ZMhRztNemy4uslDxTX4Qw==} - engines: {node: '>=6.9.0'} - dependencies: - '@ampproject/remapping': 2.2.1 - '@babel/code-frame': 7.22.10 - '@babel/generator': 7.22.10 - '@babel/helper-compilation-targets': 7.22.10 - '@babel/helper-module-transforms': 7.22.9(@babel/core@7.22.10) - '@babel/helpers': 7.22.10 - '@babel/parser': 7.23.5 - '@babel/template': 7.22.5 - '@babel/traverse': 7.23.2 - '@babel/types': 7.23.5 - convert-source-map: 1.9.0 - debug: 4.3.4(supports-color@8.1.1) - gensync: 1.0.0-beta.2 - json5: 2.2.3 - semver: 6.3.1 - transitivePeerDependencies: - - supports-color - dev: true - /@babel/core@7.23.5: resolution: {integrity: sha512-Cwc2XjUrG4ilcfOw4wBAK+enbdgwAcAJCfGUItPBKR7Mjw4aEfAFYrLxeRp4jWgtNIKn3n2AlBOfwwafl+42/g==} engines: {node: '>=6.9.0'} @@ -1170,7 +1131,7 @@ packages: '@babel/helper-compilation-targets': 7.22.15 '@babel/helper-module-transforms': 7.23.3(@babel/core@7.23.5) '@babel/helpers': 7.23.5 - '@babel/parser': 7.23.5 + '@babel/parser': 7.23.6 '@babel/template': 7.22.15 '@babel/traverse': 7.23.5 '@babel/types': 7.23.5 @@ -1183,26 +1144,6 @@ packages: - supports-color dev: true - /@babel/generator@7.22.10: - resolution: {integrity: sha512-79KIf7YiWjjdZ81JnLujDRApWtl7BxTqWD88+FFdQEIOG8LJ0etDOM7CXuIgGJa55sGOwZVwuEsaLEm0PJ5/+A==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/types': 7.23.5 - '@jridgewell/gen-mapping': 0.3.3 - '@jridgewell/trace-mapping': 0.3.19 - jsesc: 2.5.2 - dev: true - - /@babel/generator@7.23.0: - resolution: {integrity: sha512-lN85QRR+5IbYrMWM6Y4pE/noaQtg4pNiqeNGX60eqOfo6gtEj6uw/JagelB8vVztSd7R6M5n1+PQkDbHbBRU4g==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/types': 7.23.5 - '@jridgewell/gen-mapping': 0.3.3 - '@jridgewell/trace-mapping': 0.3.19 - jsesc: 2.5.2 - dev: true - /@babel/generator@7.23.5: resolution: {integrity: sha512-BPssCHrBD+0YrxviOa3QzpqwhNIXKEtOa2jQrm4FlmkC2apYgRnQcmPWiGZDlGxiNtltnUFolMe8497Esry+jA==} engines: {node: '>=6.9.0'} @@ -1227,17 +1168,6 @@ packages: '@babel/types': 7.23.5 dev: true - /@babel/helper-compilation-targets@7.22.10: - resolution: {integrity: sha512-JMSwHD4J7SLod0idLq5PKgI+6g/hLD/iuWBq08ZX49xE14VpVEojJ5rHWptpirV2j020MvypRLAXAO50igCJ5Q==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/compat-data': 7.22.9 - '@babel/helper-validator-option': 7.22.5 - browserslist: 4.21.10 - lru-cache: 5.1.1 - semver: 6.3.1 - dev: true - /@babel/helper-compilation-targets@7.22.15: resolution: {integrity: sha512-y6EEzULok0Qvz8yyLkCvVX+02ic+By2UdOhylwUOvOn9dvYc9mKICJuuU1n1XBI02YWsNsnrY1kc6DVbjcXbtw==} engines: {node: '>=6.9.0'} @@ -1328,27 +1258,6 @@ packages: '@babel/types': 7.23.5 dev: true - /@babel/helper-module-imports@7.22.5: - resolution: {integrity: sha512-8Dl6+HD/cKifutF5qGd/8ZJi84QeAKh+CEe1sBzz8UayBBGg1dAIJrdHOcOM5b2MpzWL2yuotJTtGjETq0qjXg==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/types': 7.23.5 - dev: true - - /@babel/helper-module-transforms@7.22.9(@babel/core@7.22.10): - resolution: {integrity: sha512-t+WA2Xn5K+rTeGtC8jCsdAH52bjggG5TKRuRrAGNM/mjIbO4GxvlLMFOEz9wXY5I2XQ60PMFsAG2WIcG82dQMQ==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0 - dependencies: - '@babel/core': 7.22.10 - '@babel/helper-environment-visitor': 7.22.20 - '@babel/helper-module-imports': 7.22.5 - '@babel/helper-simple-access': 7.22.5 - '@babel/helper-split-export-declaration': 7.22.6 - '@babel/helper-validator-identifier': 7.22.20 - dev: true - /@babel/helper-module-transforms@7.23.3(@babel/core@7.23.5): resolution: {integrity: sha512-7bBs4ED9OmswdfDzpz4MpWgSrV7FXlc3zIagvLFjS5H+Mk7Snr21vQ6QwrsoCGMfNC4e4LQPdoULEt4ykz0SRQ==} engines: {node: '>=6.9.0'} @@ -1420,10 +1329,6 @@ packages: '@babel/types': 7.23.5 dev: true - /@babel/helper-string-parser@7.22.5: - resolution: {integrity: sha512-mM4COjgZox8U+JcXQwPijIZLElkgEpO5rsERVDJTc2qfCDfERyob6k5WegS14SX18IIjv+XD+GrqNumY5JRCDw==} - engines: {node: '>=6.9.0'} - /@babel/helper-string-parser@7.23.4: resolution: {integrity: sha512-803gmbQdqwdf4olxrX4AJyFBV/RTr3rSmOj0rKwesmzlfhYNDEs+/iOcznzpNWlJlIlTJC2QfPFcHB6DlzdVLQ==} engines: {node: '>=6.9.0'} @@ -1437,11 +1342,6 @@ packages: engines: {node: '>=6.9.0'} dev: true - /@babel/helper-validator-option@7.22.5: - resolution: {integrity: sha512-R3oB6xlIVKUnxNUxbmgq7pKjxpru24zlimpE8WK47fACIlM0II/Hm1RS8IaOI7NgCr6LNS+jl5l75m20npAziw==} - engines: {node: '>=6.9.0'} - dev: true - /@babel/helper-validator-option@7.23.5: resolution: {integrity: sha512-85ttAOMLsr53VgXkTbkx8oA6YTfT4q7/HzXSLEYmjcSTJPMPQtvq1BD79Byep5xMUYbGRzEpDsjUf3dyp54IKw==} engines: {node: '>=6.9.0'} @@ -1456,17 +1356,6 @@ packages: '@babel/types': 7.23.5 dev: true - /@babel/helpers@7.22.10: - resolution: {integrity: sha512-a41J4NW8HyZa1I1vAndrraTlPZ/eZoga2ZgS7fEr0tZJGVU4xqdE80CEm0CcNjha5EZ8fTBYLKHF0kqDUuAwQw==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/template': 7.22.15 - '@babel/traverse': 7.23.2 - '@babel/types': 7.23.5 - transitivePeerDependencies: - - supports-color - dev: true - /@babel/helpers@7.23.5: resolution: {integrity: sha512-oO7us8FzTEsG3U6ag9MfdF1iA/7Z6dz+MtFhifZk8C8o453rGJFFWUP1t+ULM9TUIAzC9uxXEiXjOiVMyd7QPg==} engines: {node: '>=6.9.0'} @@ -1478,15 +1367,6 @@ packages: - supports-color dev: true - /@babel/highlight@7.22.20: - resolution: {integrity: sha512-dkdMCN3py0+ksCgYmGG8jKeGA/8Tk+gJwSYYlFGxG5lmhfKNoAy004YpLxpS1W2J8m/EK2Ew+yOs9pVRwO89mg==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/helper-validator-identifier': 7.22.20 - chalk: 2.4.2 - js-tokens: 4.0.0 - dev: true - /@babel/highlight@7.23.4: resolution: {integrity: sha512-acGdbYSfp2WheJoJm/EBBBLh/ID8KDc64ISZ9DYtBmC8/Q204PZJLHyzeB5qMzJ5trcOkybd78M4x2KWsUq++A==} engines: {node: '>=6.9.0'} @@ -1501,7 +1381,7 @@ packages: engines: {node: '>=6.0.0'} hasBin: true dependencies: - '@babel/types': 7.23.0 + '@babel/types': 7.23.5 /@babel/parser@7.23.5: resolution: {integrity: sha512-hOOqoiNXrmGdFbhgCzu6GiURxUgM27Xwd/aPuu8RfHEZPBzL1Z54okAHAQjXfcQNwvrlkAmAp4SlRTZ45vlthQ==} @@ -1515,8 +1395,7 @@ packages: engines: {node: '>=6.0.0'} hasBin: true dependencies: - '@babel/types': 7.23.5 - dev: true + '@babel/types': 7.23.0 /@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@7.22.5(@babel/core@7.23.5): resolution: {integrity: sha512-NP1M5Rf+u2Gw9qfSO4ihjcTGW5zXTi36ITLd4/EoAcEhIZ0yjMqmftDNl3QC19CX7olhrjpyU454g/2W7X0jvQ==} @@ -1549,15 +1428,6 @@ packages: '@babel/core': 7.23.5 dev: true - /@babel/plugin-syntax-async-generators@7.8.4(@babel/core@7.22.10): - resolution: {integrity: sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.22.10 - '@babel/helper-plugin-utils': 7.22.5 - dev: true - /@babel/plugin-syntax-async-generators@7.8.4(@babel/core@7.23.5): resolution: {integrity: sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==} peerDependencies: @@ -1567,21 +1437,12 @@ packages: '@babel/helper-plugin-utils': 7.22.5 dev: true - /@babel/plugin-syntax-bigint@7.8.3(@babel/core@7.22.10): + /@babel/plugin-syntax-bigint@7.8.3(@babel/core@7.23.5): resolution: {integrity: sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.22.10 - '@babel/helper-plugin-utils': 7.22.5 - dev: true - - /@babel/plugin-syntax-class-properties@7.12.13(@babel/core@7.22.10): - resolution: {integrity: sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.22.10 + '@babel/core': 7.23.5 '@babel/helper-plugin-utils': 7.22.5 dev: true @@ -1642,15 +1503,6 @@ packages: '@babel/helper-plugin-utils': 7.22.5 dev: true - /@babel/plugin-syntax-import-meta@7.10.4(@babel/core@7.22.10): - resolution: {integrity: sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.22.10 - '@babel/helper-plugin-utils': 7.22.5 - dev: true - /@babel/plugin-syntax-import-meta@7.10.4(@babel/core@7.23.5): resolution: {integrity: sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==} peerDependencies: @@ -1660,15 +1512,6 @@ packages: '@babel/helper-plugin-utils': 7.22.5 dev: true - /@babel/plugin-syntax-json-strings@7.8.3(@babel/core@7.22.10): - resolution: {integrity: sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.22.10 - '@babel/helper-plugin-utils': 7.22.5 - dev: true - /@babel/plugin-syntax-json-strings@7.8.3(@babel/core@7.23.5): resolution: {integrity: sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==} peerDependencies: @@ -1678,16 +1521,6 @@ packages: '@babel/helper-plugin-utils': 7.22.5 dev: true - /@babel/plugin-syntax-jsx@7.22.5(@babel/core@7.22.10): - resolution: {integrity: sha512-gvyP4hZrgrs/wWMaocvxZ44Hw0b3W8Pe+cMxc8V1ULQ07oh8VNbIRaoD1LRZVTvD+0nieDKjfgKg89sD7rrKrg==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.22.10 - '@babel/helper-plugin-utils': 7.22.5 - dev: true - /@babel/plugin-syntax-jsx@7.23.3(@babel/core@7.23.5): resolution: {integrity: sha512-EB2MELswq55OHUoRZLGg/zC7QWUKfNLpE57m/S2yr1uEneIgsTgrSzXP3NXEsMkVn76OlaVVnzN+ugObuYGwhg==} engines: {node: '>=6.9.0'} @@ -1698,15 +1531,6 @@ packages: '@babel/helper-plugin-utils': 7.22.5 dev: true - /@babel/plugin-syntax-logical-assignment-operators@7.10.4(@babel/core@7.22.10): - resolution: {integrity: sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.22.10 - '@babel/helper-plugin-utils': 7.22.5 - dev: true - /@babel/plugin-syntax-logical-assignment-operators@7.10.4(@babel/core@7.23.5): resolution: {integrity: sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==} peerDependencies: @@ -1716,15 +1540,6 @@ packages: '@babel/helper-plugin-utils': 7.22.5 dev: true - /@babel/plugin-syntax-nullish-coalescing-operator@7.8.3(@babel/core@7.22.10): - resolution: {integrity: sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.22.10 - '@babel/helper-plugin-utils': 7.22.5 - dev: true - /@babel/plugin-syntax-nullish-coalescing-operator@7.8.3(@babel/core@7.23.5): resolution: {integrity: sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==} peerDependencies: @@ -1734,15 +1549,6 @@ packages: '@babel/helper-plugin-utils': 7.22.5 dev: true - /@babel/plugin-syntax-numeric-separator@7.10.4(@babel/core@7.22.10): - resolution: {integrity: sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.22.10 - '@babel/helper-plugin-utils': 7.22.5 - dev: true - /@babel/plugin-syntax-numeric-separator@7.10.4(@babel/core@7.23.5): resolution: {integrity: sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==} peerDependencies: @@ -1752,15 +1558,6 @@ packages: '@babel/helper-plugin-utils': 7.22.5 dev: true - /@babel/plugin-syntax-object-rest-spread@7.8.3(@babel/core@7.22.10): - resolution: {integrity: sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.22.10 - '@babel/helper-plugin-utils': 7.22.5 - dev: true - /@babel/plugin-syntax-object-rest-spread@7.8.3(@babel/core@7.23.5): resolution: {integrity: sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==} peerDependencies: @@ -1770,15 +1567,6 @@ packages: '@babel/helper-plugin-utils': 7.22.5 dev: true - /@babel/plugin-syntax-optional-catch-binding@7.8.3(@babel/core@7.22.10): - resolution: {integrity: sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.22.10 - '@babel/helper-plugin-utils': 7.22.5 - dev: true - /@babel/plugin-syntax-optional-catch-binding@7.8.3(@babel/core@7.23.5): resolution: {integrity: sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==} peerDependencies: @@ -1788,15 +1576,6 @@ packages: '@babel/helper-plugin-utils': 7.22.5 dev: true - /@babel/plugin-syntax-optional-chaining@7.8.3(@babel/core@7.22.10): - resolution: {integrity: sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.22.10 - '@babel/helper-plugin-utils': 7.22.5 - dev: true - /@babel/plugin-syntax-optional-chaining@7.8.3(@babel/core@7.23.5): resolution: {integrity: sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==} peerDependencies: @@ -1816,16 +1595,6 @@ packages: '@babel/helper-plugin-utils': 7.22.5 dev: true - /@babel/plugin-syntax-top-level-await@7.14.5(@babel/core@7.22.10): - resolution: {integrity: sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.22.10 - '@babel/helper-plugin-utils': 7.22.5 - dev: true - /@babel/plugin-syntax-top-level-await@7.14.5(@babel/core@7.23.5): resolution: {integrity: sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==} engines: {node: '>=6.9.0'} @@ -1836,16 +1605,6 @@ packages: '@babel/helper-plugin-utils': 7.22.5 dev: true - /@babel/plugin-syntax-typescript@7.22.5(@babel/core@7.22.10): - resolution: {integrity: sha512-1mS2o03i7t1c6VzH6fdQ3OA8tcEIxwG18zIPRp+UY1Ihv6W+XZzBCVxExF9upussPXJ0xE9XRHwMoNs1ep/nRQ==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.22.10 - '@babel/helper-plugin-utils': 7.22.5 - dev: true - /@babel/plugin-syntax-typescript@7.23.3(@babel/core@7.23.5): resolution: {integrity: sha512-9EiNjVJOMwCO+43TqoTrgQ8jMwcAd0sWyXi9RPfIsLTj4R2MADDDQXELhffaUx/uJv2AYcxBgPwH6j4TIA4ytQ==} engines: {node: '>=6.9.0'} @@ -2544,35 +2303,8 @@ packages: engines: {node: '>=6.9.0'} dependencies: '@babel/code-frame': 7.23.5 - '@babel/parser': 7.23.5 - '@babel/types': 7.23.5 - dev: true - - /@babel/template@7.22.5: - resolution: {integrity: sha512-X7yV7eiwAxdj9k94NEylvbVHLiVG1nvzCV2EAowhxLTwODV1jl9UzZ48leOC0sH7OnuHrIkllaBgneUykIcZaw==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/code-frame': 7.22.13 - '@babel/parser': 7.23.5 - '@babel/types': 7.23.5 - dev: true - - /@babel/traverse@7.23.2: - resolution: {integrity: sha512-azpe59SQ48qG6nu2CzcMLbxUudtN+dOM9kDbUqGq3HXUJRlo7i8fvPoxQUzYgLZ4cMVmuZgm8vvBpNeRhd6XSw==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/code-frame': 7.22.13 - '@babel/generator': 7.23.0 - '@babel/helper-environment-visitor': 7.22.20 - '@babel/helper-function-name': 7.23.0 - '@babel/helper-hoist-variables': 7.22.5 - '@babel/helper-split-export-declaration': 7.22.6 - '@babel/parser': 7.23.5 + '@babel/parser': 7.23.6 '@babel/types': 7.23.5 - debug: 4.3.4(supports-color@8.1.1) - globals: 11.12.0 - transitivePeerDependencies: - - supports-color dev: true /@babel/traverse@7.23.5: @@ -2585,7 +2317,7 @@ packages: '@babel/helper-function-name': 7.23.0 '@babel/helper-hoist-variables': 7.22.5 '@babel/helper-split-export-declaration': 7.22.6 - '@babel/parser': 7.23.5 + '@babel/parser': 7.23.6 '@babel/types': 7.23.5 debug: 4.3.4(supports-color@8.1.1) globals: 11.12.0 @@ -2597,7 +2329,7 @@ packages: resolution: {integrity: sha512-0oIyUfKoI3mSqMvsxBdclDwxXKXAUA8v/apZbc+iSyARYou1o8ZGDxbUYyLFoW2arqS2jDGqJuZvv1d/io1axg==} engines: {node: '>=6.9.0'} dependencies: - '@babel/helper-string-parser': 7.22.5 + '@babel/helper-string-parser': 7.23.4 '@babel/helper-validator-identifier': 7.22.20 to-fast-properties: 2.0.0 @@ -4236,7 +3968,7 @@ packages: resolution: {integrity: sha512-ZqCqEISr58Ce3U+buNFJYUktLJZOggfyvR+bZMaiV1e8B1SIvJbwZMrYz3gx/KAPn9EXmOmN+uB08yLCjWkQQg==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: - '@babel/core': 7.22.10 + '@babel/core': 7.23.5 '@jest/types': 29.6.1 '@jridgewell/trace-mapping': 0.3.19 babel-plugin-istanbul: 6.1.1 @@ -4643,7 +4375,7 @@ packages: /@types/babel__core@7.20.1: resolution: {integrity: sha512-aACu/U/omhdk15O4Nfb+fHgH/z3QsfQzpnvRZhYhThms83ZnAOZz7zZAWO7mn2yyNQaA4xTO8GLK3uqFU4bYYw==} dependencies: - '@babel/parser': 7.23.5 + '@babel/parser': 7.23.6 '@babel/types': 7.23.5 '@types/babel__generator': 7.6.4 '@types/babel__template': 7.4.1 @@ -4659,7 +4391,7 @@ packages: /@types/babel__template@7.4.1: resolution: {integrity: sha512-azBFKemX6kMg5Io+/rdGT0dkGreboUVR0Cdm3fz9QJWpaQGJRQXl7C+6hOTCZcMll7KFyEQpgbYI2lHdsS4U7g==} dependencies: - '@babel/parser': 7.23.5 + '@babel/parser': 7.23.6 '@babel/types': 7.23.5 dev: true @@ -4992,6 +4724,12 @@ packages: '@types/node': 18.17.5 dev: true + /@types/hast@3.0.3: + resolution: {integrity: sha512-2fYGlaDy/qyLlhidX42wAH0KBi2TCjKMH8CHmBXgRlJ3Y+OXTiqsPQ6IWarZKwF1JoUcAJdPogv1d4b0COTpmQ==} + dependencies: + '@types/unist': 3.0.2 + dev: true + /@types/http-cache-semantics@4.0.1: resolution: {integrity: sha512-SZs7ekbP8CN0txVG2xVRH6EgKmEm31BOxA07vkFaETzZz1xh+cbt8BcI0slpymvwhx5dlFnQG2rTlPVQn+iRPQ==} dev: true @@ -5077,6 +4815,12 @@ packages: dependencies: '@types/unist': 2.0.7 + /@types/mdast@4.0.3: + resolution: {integrity: sha512-LsjtqsyF+d2/yFOYaN22dHZI1Cpwkrj+g06G8+qtUKlhovPW89YhqSnfKtMbkgmEtYpH2gydRNULd6y8mciAFg==} + dependencies: + '@types/unist': 3.0.2 + dev: true + /@types/mdurl@1.0.2: resolution: {integrity: sha512-eC4U9MlIcu2q0KQmXszyn5Akca/0jrQmwDRgpAMJai7qBWq4amIQhZyNau4VYGtCeALvW1/NtjzJJ567aZxfKA==} dev: true @@ -5220,6 +4964,10 @@ packages: /@types/unist@2.0.7: resolution: {integrity: sha512-cputDpIbFgLUaGQn6Vqg3/YsJwxUwHLO13v3i5ouxT4lat0khip9AEWxtERujXV9wxIB1EyF97BSJFt6vpdI8g==} + /@types/unist@3.0.2: + resolution: {integrity: sha512-dqId9J8K/vGi5Zr7oo212BGii5m3q5Hxlkwy3WpYuKPklmBEvsbMYYyLxAQpSffdLl/gdW0XUpKWFvYmyoWCoQ==} + dev: true + /@types/uuid@9.0.1: resolution: {integrity: sha512-rFT3ak0/2trgvp4yYZo5iKFEPsET7vKydKF+VRCxlQ9bpheehyAJH89dAkaLEq/j/RZXJIqcgsmPJKUP1Z28HA==} dev: true @@ -5579,6 +5327,10 @@ packages: eslint-visitor-keys: 3.4.3 dev: true + /@ungap/structured-clone@1.2.0: + resolution: {integrity: sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==} + dev: true + /@unocss/astro@0.58.0(rollup@2.79.1)(vite@4.5.0): resolution: {integrity: sha512-df+tEFO5eKXjQOwSWQhS9IdjD0sfLHLtn8U09sEKR2Nmh5CvpwyBxmvLQgOCilPou7ehmyKfsyGRLZg7IMp+Ew==} peerDependencies: @@ -5812,7 +5564,7 @@ packages: vue: 3.3.4 dev: true - /@vitejs/plugin-vue@4.5.0(vite@4.5.0)(vue@3.3.8): + /@vitejs/plugin-vue@4.5.0(vite@4.5.0)(vue@3.4.15): resolution: {integrity: sha512-a2WSpP8X8HTEww/U00bU4mX1QpLINNuz/2KMNpLsdu3BzOpak3AGI1CJYBTXcc4SPhaD0eNRUp7IyQK405L5dQ==} engines: {node: ^14.18.0 || >=16.0.0} peerDependencies: @@ -5820,7 +5572,18 @@ packages: vue: ^3.2.25 dependencies: vite: 4.5.0(@types/node@18.17.5) - vue: 3.3.8(typescript@5.0.4) + vue: 3.4.15(typescript@5.0.4) + dev: true + + /@vitejs/plugin-vue@4.5.0(vite@5.0.11)(vue@3.4.15): + resolution: {integrity: sha512-a2WSpP8X8HTEww/U00bU4mX1QpLINNuz/2KMNpLsdu3BzOpak3AGI1CJYBTXcc4SPhaD0eNRUp7IyQK405L5dQ==} + engines: {node: ^14.18.0 || >=16.0.0} + peerDependencies: + vite: ^4.0.0 || ^5.0.0 + vue: ^3.2.25 + dependencies: + vite: 5.0.11(@types/node@18.17.5) + vue: 3.4.15(typescript@5.1.6) dev: true /@vitejs/plugin-vue@5.0.3(vite@5.0.11)(vue@3.4.15): @@ -5908,7 +5671,7 @@ packages: pretty-format: 29.6.2 dev: true - /@vue/compat@3.3.4(vue@3.3.8): + /@vue/compat@3.3.4(vue@3.4.15): resolution: {integrity: sha512-VwAsPqUqRJVxeLQPUC03Sa5d+T8UG2Qv4VItq74KmNvtQlRXICpa/sqq12BcyBB4Tz1U5paOEZxWCUoXkrZ9QQ==} peerDependencies: vue: 3.3.4 @@ -5916,7 +5679,7 @@ packages: '@babel/parser': 7.23.0 estree-walker: 2.0.2 source-map-js: 1.0.2 - vue: 3.3.8(typescript@5.1.6) + vue: 3.4.15(typescript@5.1.6) dev: false /@vue/compiler-core@3.3.4: @@ -5947,7 +5710,6 @@ packages: dependencies: '@vue/compiler-core': 3.4.15 '@vue/shared': 3.4.15 - dev: true /@vue/compiler-sfc@3.3.4: resolution: {integrity: sha512-6y/d8uw+5TkCuzBkgLS0v3lSM3hJDntFEiUORM11pQ/hKvkhSKZrXW6i69UyXlJQisJxuUEJKAWEqWbWsLeNKQ==} @@ -5987,7 +5749,6 @@ packages: dependencies: '@vue/compiler-dom': 3.4.15 '@vue/shared': 3.4.15 - dev: true /@vue/devtools-api@6.5.0: resolution: {integrity: sha512-o9KfBeaBmCKl10usN4crU53fYtC1r7jJwdGKjPT24t348rHxgfpZ0xL3Xm/gLUYnc0oTp8LAmrxOeLyu6tbk2Q==} @@ -5999,7 +5760,7 @@ packages: /@vue/reactivity-transform@3.3.4: resolution: {integrity: sha512-MXgwjako4nu5WFLAjpBnCj/ieqcjE2aJBINUNQzkZQfzIZA4xn+0fV1tIYBJvvva3N3OvKGofRLvQIwEQPpaXw==} dependencies: - '@babel/parser': 7.23.5 + '@babel/parser': 7.23.6 '@vue/compiler-core': 3.3.4 '@vue/shared': 3.3.4 estree-walker: 2.0.2 @@ -6014,7 +5775,6 @@ packages: resolution: {integrity: sha512-55yJh2bsff20K5O84MxSvXKPHHt17I2EomHznvFiJCAZpJTNW8IuLj1xZWMLELRhBK3kkFV/1ErZGHJfah7i7w==} dependencies: '@vue/shared': 3.4.15 - dev: true /@vue/runtime-core@3.3.4: resolution: {integrity: sha512-R+bqxMN6pWO7zGI4OMlmvePOdP2c93GsHFM/siJI7O2nxFRzj55pLwkpCedEY+bTMgp5miZ8CxfIZo3S+gFqvA==} @@ -6027,7 +5787,6 @@ packages: dependencies: '@vue/reactivity': 3.4.15 '@vue/shared': 3.4.15 - dev: true /@vue/runtime-dom@3.3.4: resolution: {integrity: sha512-Aj5bTJ3u5sFsUckRghsNjVTtxZQ1OyMWCr5dZRAPijF/0Vy4xEoRCwLyHXcj4D0UFbJ4lbx3gPTgg06K/GnPnQ==} @@ -6042,7 +5801,6 @@ packages: '@vue/runtime-core': 3.4.15 '@vue/shared': 3.4.15 csstype: 3.1.3 - dev: true /@vue/server-renderer@3.3.4(vue@3.3.4): resolution: {integrity: sha512-Q6jDDzR23ViIb67v+vM1Dqntu+HUexQcsWKhhQa4ARVzxOY2HbC7QRW/ggkDBd5BU+uM1sV6XOAP0b216o34JQ==} @@ -6061,14 +5819,12 @@ packages: '@vue/compiler-ssr': 3.4.15 '@vue/shared': 3.4.15 vue: 3.4.15(typescript@5.0.4) - dev: true /@vue/shared@3.3.4: resolution: {integrity: sha512-7OjdcV8vQ74eiz1TZLzZP4JwqM5fA94K6yntPS5Z25r9HDuGNzaGdgvwKYq6S+MxwF0TFRwe50fIR/MYnakdkQ==} /@vue/shared@3.4.15: resolution: {integrity: sha512-KzfPTxVaWfB+eGcGdbSf4CWdaXcGDqckoeXUh7SB3fZdEtzPCK2Vq9B/lRRL3yutax/LWITz+SwvgyOxz5V75g==} - dev: true /@vueuse/core@10.1.0(vue@3.3.4): resolution: {integrity: sha512-3Znoa5m5RO+z4/C9w6DRaKTR3wCVJvD5rav8HTDGsr+7rOZRHtcgFJ8NcCs0ZvIpmev2kExTa311ns5j2RbzDQ==} @@ -6082,18 +5838,6 @@ packages: - vue dev: false - /@vueuse/core@10.3.0(vue@3.3.4): - resolution: {integrity: sha512-BEM5yxcFKb5btFjTSAFjTu5jmwoW66fyV9uJIP4wUXXU8aR5Hl44gndaaXp7dC5HSObmgbnR2RN+Un1p68Mf5Q==} - dependencies: - '@types/web-bluetooth': 0.0.17 - '@vueuse/metadata': 10.3.0 - '@vueuse/shared': 10.3.0(vue@3.3.4) - vue-demi: 0.14.6(vue@3.3.4) - transitivePeerDependencies: - - '@vue/composition-api' - - vue - dev: true - /@vueuse/core@10.7.2(vue@3.4.15): resolution: {integrity: sha512-AOyAL2rK0By62Hm+iqQn6Rbu8bfmbgaIMXcE3TSr7BdQ42wnSFlwIdPjInO62onYsEMK/yDMU8C6oGfDAtZ2qQ==} dependencies: @@ -6160,10 +5904,6 @@ packages: resolution: {integrity: sha512-cM28HjDEw5FIrPE9rgSPFZvQ0ZYnOLAOr8hl1XM6tFl80U3WAR5ROdnAqiYybniwP5gt9MKKAJAqd/ab2aHkqg==} dev: false - /@vueuse/metadata@10.3.0: - resolution: {integrity: sha512-Ema3YhNOa4swDsV0V7CEY5JXvK19JI/o1szFO1iWxdFg3vhdFtCtSTP26PCvbUpnUtNHBY2wx5y3WDXND5Pvnw==} - dev: true - /@vueuse/metadata@10.7.2: resolution: {integrity: sha512-kCWPb4J2KGrwLtn1eJwaJD742u1k5h6v/St5wFe8Quih90+k2a0JP8BS4Zp34XUuJqS2AxFYMb1wjUL8HfhWsQ==} dev: true @@ -6177,15 +5917,6 @@ packages: - vue dev: false - /@vueuse/shared@10.3.0(vue@3.3.4): - resolution: {integrity: sha512-kGqCTEuFPMK4+fNWy6dUOiYmxGcUbtznMwBZLC1PubidF4VZY05B+Oht7Jh7/6x4VOWGpvu3R37WHi81cKpiqg==} - dependencies: - vue-demi: 0.14.6(vue@3.3.4) - transitivePeerDependencies: - - '@vue/composition-api' - - vue - dev: true - /@vueuse/shared@10.7.2(vue@3.4.15): resolution: {integrity: sha512-qFbXoxS44pi2FkgFjPvF4h7c9oMDutpyBdcJdMYIMg9XyXli2meFMuaKn+UMgsClo//Th6+beeCgqweT/79BVA==} dependencies: @@ -6405,7 +6136,7 @@ packages: dependencies: '@types/assert': 1.5.6 '@types/ramda': 0.28.25 - '@vue/compat': 3.3.4(vue@3.3.8) + '@vue/compat': 3.3.4(vue@3.4.15) antlr4: 4.11.0 color-string: 1.9.1 dom-to-image-more: 2.16.0 @@ -6418,8 +6149,8 @@ packages: postcss: 8.4.27 ramda: 0.28.0 tailwindcss: 3.3.3(ts-node@10.9.1) - vue: 3.3.8(typescript@5.1.6) - vuex: 4.1.0(vue@3.3.8) + vue: 3.4.15(typescript@5.1.6) + vuex: 4.1.0(vue@3.4.15) transitivePeerDependencies: - ts-node - typescript @@ -6867,17 +6598,17 @@ packages: - debug dev: true - /babel-jest@29.6.2(@babel/core@7.22.10): + /babel-jest@29.6.2(@babel/core@7.23.5): resolution: {integrity: sha512-BYCzImLos6J3BH/+HvUCHG1dTf2MzmAB4jaVxHV+29RZLjR29XuYTmsf2sdDwkrb+FczkGo3kOhE7ga6sI0P4A==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} peerDependencies: '@babel/core': ^7.8.0 dependencies: - '@babel/core': 7.22.10 + '@babel/core': 7.23.5 '@jest/transform': 29.6.2 '@types/babel__core': 7.20.1 babel-plugin-istanbul: 6.1.1 - babel-preset-jest: 29.5.0(@babel/core@7.22.10) + babel-preset-jest: 29.5.0(@babel/core@7.23.5) chalk: 4.1.2 graceful-fs: 4.2.11 slash: 3.0.0 @@ -6957,35 +6688,35 @@ packages: - supports-color dev: true - /babel-preset-current-node-syntax@1.0.1(@babel/core@7.22.10): + /babel-preset-current-node-syntax@1.0.1(@babel/core@7.23.5): resolution: {integrity: sha512-M7LQ0bxarkxQoN+vz5aJPsLBn77n8QgTFmo8WK0/44auK2xlCXrYcUxHFxgU7qW5Yzw/CjmLRK2uJzaCd7LvqQ==} peerDependencies: '@babel/core': ^7.0.0 dependencies: - '@babel/core': 7.22.10 - '@babel/plugin-syntax-async-generators': 7.8.4(@babel/core@7.22.10) - '@babel/plugin-syntax-bigint': 7.8.3(@babel/core@7.22.10) - '@babel/plugin-syntax-class-properties': 7.12.13(@babel/core@7.22.10) - '@babel/plugin-syntax-import-meta': 7.10.4(@babel/core@7.22.10) - '@babel/plugin-syntax-json-strings': 7.8.3(@babel/core@7.22.10) - '@babel/plugin-syntax-logical-assignment-operators': 7.10.4(@babel/core@7.22.10) - '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3(@babel/core@7.22.10) - '@babel/plugin-syntax-numeric-separator': 7.10.4(@babel/core@7.22.10) - '@babel/plugin-syntax-object-rest-spread': 7.8.3(@babel/core@7.22.10) - '@babel/plugin-syntax-optional-catch-binding': 7.8.3(@babel/core@7.22.10) - '@babel/plugin-syntax-optional-chaining': 7.8.3(@babel/core@7.22.10) - '@babel/plugin-syntax-top-level-await': 7.14.5(@babel/core@7.22.10) - dev: true - - /babel-preset-jest@29.5.0(@babel/core@7.22.10): + '@babel/core': 7.23.5 + '@babel/plugin-syntax-async-generators': 7.8.4(@babel/core@7.23.5) + '@babel/plugin-syntax-bigint': 7.8.3(@babel/core@7.23.5) + '@babel/plugin-syntax-class-properties': 7.12.13(@babel/core@7.23.5) + '@babel/plugin-syntax-import-meta': 7.10.4(@babel/core@7.23.5) + '@babel/plugin-syntax-json-strings': 7.8.3(@babel/core@7.23.5) + '@babel/plugin-syntax-logical-assignment-operators': 7.10.4(@babel/core@7.23.5) + '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3(@babel/core@7.23.5) + '@babel/plugin-syntax-numeric-separator': 7.10.4(@babel/core@7.23.5) + '@babel/plugin-syntax-object-rest-spread': 7.8.3(@babel/core@7.23.5) + '@babel/plugin-syntax-optional-catch-binding': 7.8.3(@babel/core@7.23.5) + '@babel/plugin-syntax-optional-chaining': 7.8.3(@babel/core@7.23.5) + '@babel/plugin-syntax-top-level-await': 7.14.5(@babel/core@7.23.5) + dev: true + + /babel-preset-jest@29.5.0(@babel/core@7.23.5): resolution: {integrity: sha512-JOMloxOqdiBSxMAzjRaH023/vvcaSaec49zvg+2LmNsktC7ei39LTJGw02J+9uUtTZUq6xbLyJ4dxe9sSmIuAg==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} peerDependencies: '@babel/core': ^7.0.0 dependencies: - '@babel/core': 7.22.10 + '@babel/core': 7.23.5 babel-plugin-jest-hoist: 29.5.0 - babel-preset-current-node-syntax: 1.0.1(@babel/core@7.22.10) + babel-preset-current-node-syntax: 1.0.1(@babel/core@7.23.5) dev: true /bail@2.0.2: @@ -7359,10 +7090,18 @@ packages: engines: {node: '>=10'} dev: true + /character-entities-html4@2.1.0: + resolution: {integrity: sha512-1v7fgQRj6hnSwFpq1Eu0ynr/CDEw0rXo2B61qXrLNdHZmPKgb7fqS1a2JwF0rISo9q77jDI8VMEHoApn8qDoZA==} + dev: true + /character-entities-legacy@1.1.4: resolution: {integrity: sha512-3Xnr+7ZFS1uxeiUDvV02wQ+QDbc55o97tIV5zHScSPJpcLm/r0DFPcoY3tYRp+VZukxuMeKgXYmsXQHO05zQeA==} dev: true + /character-entities-legacy@3.0.0: + resolution: {integrity: sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ==} + dev: true + /character-entities@1.2.4: resolution: {integrity: sha512-iBMyeEHxfVnIakwOuDXpVkc54HijNgCyQB2w0VfGQThle6NXn50zU6V/u+LDhxHcDUPojn6Kpga3PTAD8W1bQw==} dev: true @@ -7584,6 +7323,10 @@ packages: delayed-stream: 1.0.0 dev: true + /comma-separated-tokens@2.0.3: + resolution: {integrity: sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==} + dev: true + /commander@10.0.1: resolution: {integrity: sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==} engines: {node: '>=14'} @@ -8146,7 +7889,6 @@ packages: /csstype@3.1.3: resolution: {integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==} - dev: true /cuint@0.2.2: resolution: {integrity: sha512-d4ZVpCW31eWwCMe1YT3ur7mUDnTXbgwyzaL320DrcRT45rfjYxkt5QWLrmOJ+/UEAI2+fQgKe/fCjR8l4TpRgw==} @@ -8867,6 +8609,12 @@ packages: resolution: {integrity: sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==} dev: true + /devlop@1.1.0: + resolution: {integrity: sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==} + dependencies: + dequal: 2.0.3 + dev: true + /didyoumean@1.2.2: resolution: {integrity: sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==} dev: false @@ -9060,7 +8808,6 @@ packages: /entities@4.5.0: resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==} engines: {node: '>=0.12'} - dev: true /envinfo@7.10.0: resolution: {integrity: sha512-ZtUjZO6l5mwTHvc1L9+1q5p/R3wTopcfqMW8r5t8SJSKqeVI/LtajORwRFEKpEFuekjD0VBjwu1HMxL4UalIRw==} @@ -10631,6 +10378,88 @@ packages: type-fest: 0.8.1 dev: true + /hast-util-from-parse5@8.0.1: + resolution: {integrity: sha512-Er/Iixbc7IEa7r/XLtuG52zoqn/b3Xng/w6aZQ0xGVxzhw5xUFxcRqdPzP6yFi/4HBYRaifaI5fQ1RH8n0ZeOQ==} + dependencies: + '@types/hast': 3.0.3 + '@types/unist': 3.0.2 + devlop: 1.1.0 + hastscript: 8.0.0 + property-information: 6.4.0 + vfile: 6.0.1 + vfile-location: 5.0.2 + web-namespaces: 2.0.1 + dev: true + + /hast-util-parse-selector@4.0.0: + resolution: {integrity: sha512-wkQCkSYoOGCRKERFWcxMVMOcYE2K1AaNLU8DXS9arxnLOUEWbOXKXiJUNzEpqZ3JOKpnha3jkFrumEjVliDe7A==} + dependencies: + '@types/hast': 3.0.3 + dev: true + + /hast-util-raw@9.0.2: + resolution: {integrity: sha512-PldBy71wO9Uq1kyaMch9AHIghtQvIwxBUkv823pKmkTM3oV1JxtsTNYdevMxvUHqcnOAuO65JKU2+0NOxc2ksA==} + dependencies: + '@types/hast': 3.0.3 + '@types/unist': 3.0.2 + '@ungap/structured-clone': 1.2.0 + hast-util-from-parse5: 8.0.1 + hast-util-to-parse5: 8.0.0 + html-void-elements: 3.0.0 + mdast-util-to-hast: 13.1.0 + parse5: 7.1.2 + unist-util-position: 5.0.0 + unist-util-visit: 5.0.0 + vfile: 6.0.1 + web-namespaces: 2.0.1 + zwitch: 2.0.4 + dev: true + + /hast-util-to-html@9.0.0: + resolution: {integrity: sha512-IVGhNgg7vANuUA2XKrT6sOIIPgaYZnmLx3l/CCOAK0PtgfoHrZwX7jCSYyFxHTrGmC6S9q8aQQekjp4JPZF+cw==} + dependencies: + '@types/hast': 3.0.3 + '@types/unist': 3.0.2 + ccount: 2.0.1 + comma-separated-tokens: 2.0.3 + hast-util-raw: 9.0.2 + hast-util-whitespace: 3.0.0 + html-void-elements: 3.0.0 + mdast-util-to-hast: 13.1.0 + property-information: 6.4.0 + space-separated-tokens: 2.0.2 + stringify-entities: 4.0.3 + zwitch: 2.0.4 + dev: true + + /hast-util-to-parse5@8.0.0: + resolution: {integrity: sha512-3KKrV5ZVI8if87DVSi1vDeByYrkGzg4mEfeu4alwgmmIeARiBLKCZS2uw5Gb6nU9x9Yufyj3iudm6i7nl52PFw==} + dependencies: + '@types/hast': 3.0.3 + comma-separated-tokens: 2.0.3 + devlop: 1.1.0 + property-information: 6.4.0 + space-separated-tokens: 2.0.2 + web-namespaces: 2.0.1 + zwitch: 2.0.4 + dev: true + + /hast-util-whitespace@3.0.0: + resolution: {integrity: sha512-88JUN06ipLwsnv+dVn+OIYOvAuvBMy/Qoi6O7mQHxdPXpjy+Cd6xRkWwux7DKO+4sYILtLBRIKgsdpS2gQc7qw==} + dependencies: + '@types/hast': 3.0.3 + dev: true + + /hastscript@8.0.0: + resolution: {integrity: sha512-dMOtzCEd3ABUeSIISmrETiKuyydk1w0pa+gE/uormcTpSYuaNJPbX1NU3JLyscSLjwAQM8bWMhhIlnCqnRvDTw==} + dependencies: + '@types/hast': 3.0.3 + comma-separated-tokens: 2.0.3 + hast-util-parse-selector: 4.0.0 + property-information: 6.4.0 + space-separated-tokens: 2.0.2 + dev: true + /heap@0.2.7: resolution: {integrity: sha512-2bsegYkkHO+h/9MGbn6KWcE45cHZgPANo5LXF7EvWdT0yT2EguSVO1nDgU5c8+ZOPwp2vMNa7YFsJhVcDR9Sdg==} dev: false @@ -10678,6 +10507,10 @@ packages: resolution: {integrity: sha512-9gux8QhvjRO/erSnDPv28noDZcPZmYE7e1vFsBLKLlRlKDSqNJYebj6Qz1TGd5lsRV+X+xYyjCKjuZdABinWjA==} dev: false + /html-void-elements@3.0.0: + resolution: {integrity: sha512-bEqo66MRXsUGxWHV5IP0PUiAWwoEjba4VCzg0LjFJBpchPaTfyfCKTG6bc5F8ucKec3q5y6qOdGyYTSBEvhCrg==} + dev: true + /htmlparser2@8.0.2: resolution: {integrity: sha512-GYdjWKDkbRLkZ5geuHs5NY1puJ+PXwP7+fHPRz06Eirsb9ugf6d8kkXav6ADhcODhFFPMIXyxkxSuMf3D6NCFA==} dependencies: @@ -11289,7 +11122,7 @@ packages: resolution: {integrity: sha512-BXgQl9kf4WTCPCCpmFGoJkz/+uhvm7h7PFKUYxh7qarQd3ER33vHG//qaE8eN25l07YqZPpHXU9I09l/RD5aGQ==} engines: {node: '>=8'} dependencies: - '@babel/core': 7.22.10 + '@babel/core': 7.23.5 '@istanbuljs/schema': 0.1.3 istanbul-lib-coverage: 3.2.0 semver: 6.3.1 @@ -11301,8 +11134,8 @@ packages: resolution: {integrity: sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==} engines: {node: '>=8'} dependencies: - '@babel/core': 7.22.10 - '@babel/parser': 7.23.0 + '@babel/core': 7.23.5 + '@babel/parser': 7.23.6 '@istanbuljs/schema': 0.1.3 istanbul-lib-coverage: 3.2.0 semver: 6.3.1 @@ -11456,11 +11289,11 @@ packages: ts-node: optional: true dependencies: - '@babel/core': 7.22.10 + '@babel/core': 7.23.5 '@jest/test-sequencer': 29.6.2 '@jest/types': 29.6.1 '@types/node': 18.17.5 - babel-jest: 29.6.2(@babel/core@7.22.10) + babel-jest: 29.6.2(@babel/core@7.23.5) chalk: 4.1.2 ci-info: 3.8.0 deepmerge: 4.3.1 @@ -11589,7 +11422,7 @@ packages: resolution: {integrity: sha512-vnIGYEjoPSuRqV8W9t+Wow95SDp6KPX2Uf7EoeG9G99J2OVh7OSwpS4B6J0NfpEIpfkBNHlBZpA2rblEuEFhZQ==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: - '@babel/code-frame': 7.22.13 + '@babel/code-frame': 7.23.5 '@jest/types': 29.6.1 '@types/stack-utils': 2.0.1 chalk: 4.1.2 @@ -11714,15 +11547,15 @@ packages: resolution: {integrity: sha512-1OdjqvqmRdGNvWXr/YZHuyhh5DeaLp1p/F8Tht/MrMw4Kr1Uu/j4lRG+iKl1DAqUJDWxtQBMk41Lnf/JETYBRA==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: - '@babel/core': 7.22.10 - '@babel/generator': 7.23.0 - '@babel/plugin-syntax-jsx': 7.22.5(@babel/core@7.22.10) - '@babel/plugin-syntax-typescript': 7.22.5(@babel/core@7.22.10) + '@babel/core': 7.23.5 + '@babel/generator': 7.23.5 + '@babel/plugin-syntax-jsx': 7.23.3(@babel/core@7.23.5) + '@babel/plugin-syntax-typescript': 7.23.3(@babel/core@7.23.5) '@babel/types': 7.23.5 '@jest/expect-utils': 29.6.2 '@jest/transform': 29.6.2 '@jest/types': 29.6.1 - babel-preset-current-node-syntax: 1.0.1(@babel/core@7.22.10) + babel-preset-current-node-syntax: 1.0.1(@babel/core@7.23.5) chalk: 4.1.2 expect: 29.6.2 graceful-fs: 4.2.11 @@ -12653,6 +12486,20 @@ packages: unist-util-is: 5.2.1 dev: true + /mdast-util-to-hast@13.1.0: + resolution: {integrity: sha512-/e2l/6+OdGp/FB+ctrJ9Avz71AN/GRH3oi/3KAx/kMnoUsD6q0woXlDT8lLEeViVKE7oZxE7RXzvO3T8kF2/sA==} + dependencies: + '@types/hast': 3.0.3 + '@types/mdast': 4.0.3 + '@ungap/structured-clone': 1.2.0 + devlop: 1.1.0 + micromark-util-sanitize-uri: 2.0.0 + trim-lines: 3.0.1 + unist-util-position: 5.0.0 + unist-util-visit: 5.0.0 + vfile: 6.0.1 + dev: true + /mdast-util-to-markdown@1.5.0: resolution: {integrity: sha512-bbv7TPv/WC49thZPg3jXuqzuvI45IL2EVAr/KxF0BSdHsU0ceFHOmwQn6evxAh1GaoK/6GQ1wp4R4oW2+LFL/A==} dependencies: @@ -12908,6 +12755,13 @@ packages: micromark-util-symbol: 1.1.0 micromark-util-types: 1.1.0 + /micromark-util-character@2.0.1: + resolution: {integrity: sha512-3wgnrmEAJ4T+mGXAUfMvMAbxU9RDG43XmGce4j6CwPtVxB3vfwXSZ6KhFwDzZ3mZHhmPimMAXg71veiBGzeAZw==} + dependencies: + micromark-util-symbol: 2.0.0 + micromark-util-types: 2.0.0 + dev: true + /micromark-util-chunked@1.1.0: resolution: {integrity: sha512-Ye01HXpkZPNcV6FiyoW2fGZDUw4Yc7vT0E9Sad83+bEDiCJ1uXu0S3mr8WLpsz3HaG3x2q0HM6CTuPdcZcluFQ==} dependencies: @@ -12942,6 +12796,10 @@ packages: /micromark-util-encode@1.1.0: resolution: {integrity: sha512-EuEzTWSTAj9PA5GOAs992GzNh2dGQO52UvAbtSOMvXTxv3Criqb6IOzJUBCmEqrrXSblJIJBbFFv6zPxpreiJw==} + /micromark-util-encode@2.0.0: + resolution: {integrity: sha512-pS+ROfCXAGLWCOc8egcBvT0kf27GoWMqtdarNfDcjb6YLuV5cM3ioG45Ys2qOVqeqSbjaKg72vU+Wby3eddPsA==} + dev: true + /micromark-util-html-tag-name@1.2.0: resolution: {integrity: sha512-VTQzcuQgFUD7yYztuQFKXT49KghjtETQ+Wv/zUjGSGBioZnkA4P1XXZPT1FHeJA6RwRXSF47yvJ1tsJdoxwO+Q==} @@ -12962,6 +12820,14 @@ packages: micromark-util-encode: 1.1.0 micromark-util-symbol: 1.1.0 + /micromark-util-sanitize-uri@2.0.0: + resolution: {integrity: sha512-WhYv5UEcZrbAtlsnPuChHUAsu/iBPOVaEVsntLBIdpibO0ddy8OzavZz3iL2xVvBZOpolujSliP65Kq0/7KIYw==} + dependencies: + micromark-util-character: 2.0.1 + micromark-util-encode: 2.0.0 + micromark-util-symbol: 2.0.0 + dev: true + /micromark-util-subtokenize@1.1.0: resolution: {integrity: sha512-kUQHyzRoxvZO2PuLzMt2P/dwVsTiivCK8icYTeR+3WgbuPqfHgPPy7nFKbeqRivBvn/3N3GBiNC+JRTMSxEC7A==} dependencies: @@ -12973,9 +12839,17 @@ packages: /micromark-util-symbol@1.1.0: resolution: {integrity: sha512-uEjpEYY6KMs1g7QfJ2eX1SQEV+ZT4rUD3UcF6l57acZvLNK7PBZL+ty82Z1qhK1/yXIY4bdx04FKMgR0g4IAag==} + /micromark-util-symbol@2.0.0: + resolution: {integrity: sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==} + dev: true + /micromark-util-types@1.1.0: resolution: {integrity: sha512-ukRBgie8TIAcacscVHSiddHjO4k/q3pnedmzMQ4iwDcK0FtFCohKOlFbaOL/mPgfnPsL3C1ZyxJa4sbWrBl3jg==} + /micromark-util-types@2.0.0: + resolution: {integrity: sha512-oNh6S2WMHWRZrmutsRmDDfkzKtxF+bc2VxLC9dvtrDIRFln627VsFP6fLMgTryGDljgLPjkrzQSDcPrjPyDJ5w==} + dev: true + /micromark@2.11.4: resolution: {integrity: sha512-+WoovN/ppKolQOFIAajxi7Lu9kInbPxFuTBVEavFcL8eAfVstoc5MocPmqBeAdBOJV00uaVjegzH4+MA0DN/uA==} dependencies: @@ -13168,12 +13042,12 @@ packages: resolution: {integrity: sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==} engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} hasBin: true + dev: false /nanoid@3.3.7: resolution: {integrity: sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==} engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} hasBin: true - dev: true /natural-compare-lite@1.4.0: resolution: {integrity: sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g==} @@ -13648,7 +13522,7 @@ packages: resolution: {integrity: sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==} engines: {node: '>=8'} dependencies: - '@babel/code-frame': 7.22.10 + '@babel/code-frame': 7.23.5 error-ex: 1.3.2 json-parse-even-better-errors: 2.3.1 lines-and-columns: 1.2.4 @@ -13982,7 +13856,7 @@ packages: resolution: {integrity: sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==} engines: {node: ^10 || ^12 || >=14} dependencies: - nanoid: 3.3.6 + nanoid: 3.3.7 picocolors: 1.0.0 source-map-js: 1.0.2 @@ -13993,7 +13867,6 @@ packages: nanoid: 3.3.7 picocolors: 1.0.0 source-map-js: 1.0.2 - dev: true /preact@10.16.0: resolution: {integrity: sha512-XTSj3dJ4roKIC93pald6rWuB2qQJO9gO2iLLyTe87MrjQN+HklueLsmskbywEWqCHlclgz3/M4YLL2iBr9UmMA==} @@ -14075,6 +13948,10 @@ packages: sisteransi: 1.0.5 dev: true + /property-information@6.4.0: + resolution: {integrity: sha512-9t5qARVofg2xQqKtytzt+lZ4d1Qvj8t5B8fEwXK6qOfgRLgH/b13QlgEyDh033NOS31nXeFbYv7CLUDG1CeifQ==} + dev: true + /proxy-addr@2.0.7: resolution: {integrity: sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==} engines: {node: '>= 0.10'} @@ -14911,12 +14788,24 @@ packages: resolution: {integrity: sha512-AFJu/vcNT21t0e6YrfadZ+9q86gvPum6iywRyt1OtIPjPFe25RQnYJyxHQPMLKCCWA992TPxmEmbNcOZCAJclw==} dev: true + /shikiji-transformers@0.7.6: + resolution: {integrity: sha512-yTp+7JMD/aXbV9ndn14eo9IK/UNt8iDsLNyqlOmCtcldlkqWE9T2YKAlOHOTVaeDfYWUWZa2EgSXb/CBfepBrw==} + dependencies: + shikiji: 0.7.6 + dev: true + /shikiji-transformers@0.9.19: resolution: {integrity: sha512-lGLI7Z8frQrIBbhZ74/eiJtxMoCQRbpaHEB+gcfvdIy+ZFaAtXncJGnc52932/UET+Y4GyKtwwC/vjWUCp+c/Q==} dependencies: shikiji: 0.9.19 dev: true + /shikiji@0.7.6: + resolution: {integrity: sha512-KzEtvSGQtBvfwVIB70kOmIfl/5rz1LC8j+tvlHXsJKAIdONNQvG1at7ivUUq3xUctqgO6fsO3AGomUSh0F+wsQ==} + dependencies: + hast-util-to-html: 9.0.0 + dev: true + /shikiji@0.9.19: resolution: {integrity: sha512-Kw2NHWktdcdypCj1GkKpXH4o6Vxz8B8TykPlPuLHOGSV8VkhoCLcFOH4k19K4LXAQYRQmxg+0X/eM+m2sLhAkg==} dependencies: @@ -15069,6 +14958,10 @@ packages: deprecated: Please use @jridgewell/sourcemap-codec instead dev: true + /space-separated-tokens@2.0.2: + resolution: {integrity: sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==} + dev: true + /spawn-command@0.0.2-1: resolution: {integrity: sha512-n98l9E2RMSJ9ON1AKisHzz7V42VDiBQGY6PB1BwRglz99wpVsSuGzQ+jOi6lFXBGVTCrRpltvjm+/XA+tpeJrg==} dev: true @@ -15307,6 +15200,13 @@ packages: dependencies: safe-buffer: 5.2.1 + /stringify-entities@4.0.3: + resolution: {integrity: sha512-BP9nNHMhhfcMbiuQKCqMjhDP5yBCAxsPu4pHFFzJ6Alo9dZgY4VLDPutXqIjpRiMoKdp7Av85Gr73Q5uH9k7+g==} + dependencies: + character-entities-html4: 2.1.0 + character-entities-legacy: 3.0.0 + dev: true + /stringify-object@3.3.0: resolution: {integrity: sha512-rHqiFh1elqCQ9WPLIC8I0Q/g/wj5J1eMkyoiD6eoQApWHP0FtlK7rqnhmabL5VUY9JQCcqwwvlOaSuutekgyrw==} engines: {node: '>=4'} @@ -15719,6 +15619,10 @@ packages: hasBin: true dev: true + /trim-lines@3.0.1: + resolution: {integrity: sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg==} + dev: true + /trim-newlines@3.0.1: resolution: {integrity: sha512-c1PTsA3tYrIsLGkJkzHF+w9F2EyxfXGo4UyJc4pFL++FMjnq0HJS69T3M7d//gKrFKwy429bouPescbjecU+Zw==} engines: {node: '>=8'} @@ -15989,7 +15893,6 @@ packages: resolution: {integrity: sha512-cW9T5W9xY37cc+jfEnaUvX91foxtHkza3Nw3wkoF4sSlKn0MONdkdEndig/qPBWXNkmplh3NzayQzCiHM4/hqw==} engines: {node: '>=12.20'} hasBin: true - dev: true /typescript@5.1.6: resolution: {integrity: sha512-zaWCozRZ6DLEWAWFrVDz1H6FVXzUSfTy5FUMWsQlU8Ym5JP9eO4xkTIROFCQvhQf61z6O/G6ugw3SgAnvvm+HA==} @@ -16090,6 +15993,18 @@ packages: '@types/unist': 2.0.7 dev: true + /unist-util-is@6.0.0: + resolution: {integrity: sha512-2qCTHimwdxLfz+YzdGfkqNlH0tLi9xjTnHddPmJwtIG9MGsdbutfTc4P+haPD7l7Cjxf/WZj+we5qfVPvvxfYw==} + dependencies: + '@types/unist': 3.0.2 + dev: true + + /unist-util-position@5.0.0: + resolution: {integrity: sha512-fucsC7HjXvkB5R3kTCO7kUjRdrS0BJt3M/FPxmHMBOm8JQi2BsHAHFsy27E0EolP8rp0NzXsJ+jNPyDWvOJZPA==} + dependencies: + '@types/unist': 3.0.2 + dev: true + /unist-util-stringify-position@2.0.3: resolution: {integrity: sha512-3faScn5I+hy9VleOq/qNbAd6pAx7iH5jYBMS9I1HgQVijz/4mv5Bvw5iw1sC/90CODiKo81G/ps8AJrISn687g==} dependencies: @@ -16101,6 +16016,12 @@ packages: dependencies: '@types/unist': 2.0.7 + /unist-util-stringify-position@4.0.0: + resolution: {integrity: sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==} + dependencies: + '@types/unist': 3.0.2 + dev: true + /unist-util-visit-parents@5.1.3: resolution: {integrity: sha512-x6+y8g7wWMyQhL1iZfhIPhDAs7Xwbn9nRosDXl7qoPTSCy0yNxnKc+hWokFifWQIDGi154rdUqKvbCa4+1kLhg==} dependencies: @@ -16108,6 +16029,13 @@ packages: unist-util-is: 5.2.1 dev: true + /unist-util-visit-parents@6.0.1: + resolution: {integrity: sha512-L/PqWzfTP9lzzEa6CKs0k2nARxTdZduw3zyh8d2NVBnsyvHjSX4TWse388YrrQKbvI8w20fGjGlhgT96WwKykw==} + dependencies: + '@types/unist': 3.0.2 + unist-util-is: 6.0.0 + dev: true + /unist-util-visit@4.1.2: resolution: {integrity: sha512-MSd8OUGISqHdVvfY9TPhyK2VdUrPgxkUtWSuMHF6XAAFuL4LokseigBnZtPnJMu+FbynTkFNnFlyjxpVKujMRg==} dependencies: @@ -16116,6 +16044,14 @@ packages: unist-util-visit-parents: 5.1.3 dev: true + /unist-util-visit@5.0.0: + resolution: {integrity: sha512-MR04uvD+07cwl/yhVuVWAtw+3GOR/knlL55Nd/wAdblk27GCVt3lqpTivy/tkJcZoNPzTwS1Y+KMojlLDhoTzg==} + dependencies: + '@types/unist': 3.0.2 + unist-util-is: 6.0.0 + unist-util-visit-parents: 6.0.1 + dev: true + /universalify@0.1.2: resolution: {integrity: sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==} engines: {node: '>= 4.0.0'} @@ -16308,6 +16244,13 @@ packages: extsprintf: 1.3.0 dev: true + /vfile-location@5.0.2: + resolution: {integrity: sha512-NXPYyxyBSH7zB5U6+3uDdd6Nybz6o6/od9rk8bp9H8GR3L+cm/fC0uUTbqBmUTnMCUDslAGBOIKNfvvb+gGlDg==} + dependencies: + '@types/unist': 3.0.2 + vfile: 6.0.1 + dev: true + /vfile-message@3.1.4: resolution: {integrity: sha512-fa0Z6P8HUrQN4BZaX05SIVXic+7kE3b05PWAtPuYP9QLHsLKYR7/AlLW3NtOrpXRLeawpDLMsVkmk5DG0NXgWw==} dependencies: @@ -16315,6 +16258,13 @@ packages: unist-util-stringify-position: 3.0.3 dev: true + /vfile-message@4.0.2: + resolution: {integrity: sha512-jRDZ1IMLttGj41KcZvlrYAaI3CfqpLpfpf+Mfig13viT6NKvRzWZ+lXz0Y5D60w6uJIBAOGq9mSHf0gktF0duw==} + dependencies: + '@types/unist': 3.0.2 + unist-util-stringify-position: 4.0.0 + dev: true + /vfile@5.3.7: resolution: {integrity: sha512-r7qlzkgErKjobAmyNIkkSpizsFPYiUPuJb5pNW1RB4JcYVZhs4lIbVqk8XPk033CV/1z8ss5pkax8SuhGpcG8g==} dependencies: @@ -16324,6 +16274,14 @@ packages: vfile-message: 3.1.4 dev: true + /vfile@6.0.1: + resolution: {integrity: sha512-1bYqc7pt6NIADBJ98UiG0Bn/CHIVOoZ/IyEkqIruLg0mE1BKzkOXY2D6CSqQIcKqgadppE5lrxgWXJmXd7zZJw==} + dependencies: + '@types/unist': 3.0.2 + unist-util-stringify-position: 4.0.0 + vfile-message: 4.0.2 + dev: true + /vite-node@0.34.0(@types/node@18.17.5): resolution: {integrity: sha512-rGZMvpb052rjUwJA/a17xMfOibzNF7byMdRSTcN2Lw8uxX08s5EfjWW5mBkm3MSFTPctMSVtT2yC+8ShrZbT5g==} engines: {node: '>=v14.18.0'} @@ -16499,7 +16457,7 @@ packages: flexsearch: 0.7.31 glob-to-regexp: 0.4.1 markdown-it: 13.0.1 - vitepress: 1.0.0-alpha.72(@algolia/client-search@4.19.1)(@types/node@18.17.5)(search-insights@2.7.0) + vitepress: 1.0.0-alpha.72(@algolia/client-search@4.19.1)(@types/node@18.17.5)(search-insights@2.7.0)(typescript@5.0.4) vue: 3.4.15(typescript@5.0.4) dev: true @@ -16509,30 +16467,86 @@ packages: dependencies: '@docsearch/css': 3.5.1 '@docsearch/js': 3.5.1(@algolia/client-search@4.19.1)(search-insights@2.7.0) - '@vitejs/plugin-vue': 4.5.0(vite@4.5.0)(vue@3.3.8) + '@vitejs/plugin-vue': 4.5.0(vite@4.5.0)(vue@3.4.15) '@vue/devtools-api': 6.5.0 - '@vueuse/core': 10.6.1(vue@3.3.8) + '@vueuse/core': 10.7.2(vue@3.4.15) body-scroll-lock: 4.0.0-beta.0 mark.js: 8.11.1 minisearch: 6.1.0 shiki: 0.14.3 vite: 4.5.0(@types/node@18.17.5) - vue: 3.3.8(typescript@5.0.4) + vue: 3.4.15(typescript@5.0.4) + transitivePeerDependencies: + - '@algolia/client-search' + - '@types/node' + - '@types/react' + - '@vue/composition-api' + - less + - lightningcss + - react + - react-dom + - sass + - search-insights + - stylus + - sugarss + - terser + - typescript + dev: true + + /vitepress@1.0.0-rc.31(@algolia/client-search@4.19.1)(@types/node@18.17.5)(postcss@8.4.33)(search-insights@2.7.0)(typescript@5.1.6): + resolution: {integrity: sha512-ikH9pIjOOAbyoYAGBVfTz8TzuXp+UoWaIRMU4bw/oiTg8R65SbAaGKY84xx6TuL+f4VqUJ8lhzW82YyxSLvstA==} + hasBin: true + peerDependencies: + markdown-it-mathjax3: ^4.3.2 + postcss: ^8.4.31 + peerDependenciesMeta: + markdown-it-mathjax3: + optional: true + postcss: + optional: true + dependencies: + '@docsearch/css': 3.5.2 + '@docsearch/js': 3.5.2(@algolia/client-search@4.19.1)(search-insights@2.7.0) + '@types/markdown-it': 13.0.7 + '@vitejs/plugin-vue': 4.5.0(vite@5.0.11)(vue@3.4.15) + '@vue/devtools-api': 6.5.1 + '@vueuse/core': 10.7.2(vue@3.4.15) + '@vueuse/integrations': 10.7.2(focus-trap@7.5.4)(vue@3.4.15) + focus-trap: 7.5.4 + mark.js: 8.11.1 + minisearch: 6.3.0 + mrmime: 1.0.1 + postcss: 8.4.33 + shikiji: 0.7.6 + shikiji-transformers: 0.7.6 + vite: 5.0.11(@types/node@18.17.5) + vue: 3.4.15(typescript@5.1.6) transitivePeerDependencies: - '@algolia/client-search' - '@types/node' - '@types/react' - '@vue/composition-api' + - async-validator + - axios + - change-case + - drauu + - fuse.js + - idb-keyval + - jwt-decode - less - lightningcss + - nprogress + - qrcode - react - react-dom - sass - search-insights + - sortablejs - stylus - sugarss - terser - typescript + - universal-cookie dev: true /vitepress@1.0.0-rc.39(@algolia/client-search@4.19.1)(@types/node@18.17.5)(postcss@8.4.33)(search-insights@2.7.0)(typescript@5.1.6): @@ -16705,6 +16719,7 @@ packages: optional: true dependencies: vue: 3.3.4 + dev: false /vue-demi@0.14.6(vue@3.4.15): resolution: {integrity: sha512-8QA7wrYSHKaYgUxDA5ZC24w+eHm3sYCbp0EzcDwKqN3p6HqtTCGR/GVsPyZW92unff4UlcSh++lmqDWN3ZIq4w==} @@ -16718,7 +16733,7 @@ packages: '@vue/composition-api': optional: true dependencies: - vue: 3.4.15(typescript@5.1.6) + vue: 3.4.15(typescript@5.0.4) dev: true /vue@3.3.4: @@ -16744,7 +16759,6 @@ packages: '@vue/server-renderer': 3.4.15(vue@3.4.15) '@vue/shared': 3.4.15 typescript: 5.0.4 - dev: true /vue@3.4.15(typescript@5.1.6): resolution: {integrity: sha512-jC0GH4KkWLWJOEQjOpkqU1bQsBwf4R1rsFtw5GQJbjHVKWDzO6P0nWWBTmjp1xSemAioDFj1jdaK1qa3DnMQoQ==} @@ -16761,13 +16775,13 @@ packages: '@vue/shared': 3.4.15 typescript: 5.1.6 - /vuex@4.1.0(vue@3.3.8): + /vuex@4.1.0(vue@3.4.15): resolution: {integrity: sha512-hmV6UerDrPcgbSy9ORAtNXDr9M4wlNP4pEFKye4ujJF8oqgFFuxDCdOLS3eNoRTtq5O3hoBDh9Doj1bQMYHRbQ==} peerDependencies: vue: ^3.2.0 dependencies: '@vue/devtools-api': 6.5.1 - vue: 3.3.8(typescript@5.1.6) + vue: 3.4.15(typescript@5.1.6) dev: false /w3c-hr-time@1.0.2: @@ -16825,6 +16839,10 @@ packages: minimalistic-assert: 1.0.1 dev: true + /web-namespaces@2.0.1: + resolution: {integrity: sha512-bKr1DkiNa2krS7qxNtdrtHAmzuYGFQLiQ13TsorsdT6ULTkPLKuu5+GsFpDlg6JFjUTwX2DyhMPG2be8uPrqsQ==} + dev: true + /web-streams-polyfill@3.2.1: resolution: {integrity: sha512-e0MO3wdXWKrLbL0DgGnUV7WHVuw9OUvL4hjgnPkIeEvESk74gAITi5G606JtZPp39cd8HA9VQzCIvA49LpPN5Q==} engines: {node: '>= 8'} From e668698b5c5510c2f1ff9a6cc875d0dbdf413de2 Mon Sep 17 00:00:00 2001 From: Matheus B Date: Mon, 22 Jan 2024 19:56:25 -0300 Subject: [PATCH 145/217] Reposition const declaration to ideal place --- packages/mermaid/src/diagrams/git/gitGraphRenderer.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/mermaid/src/diagrams/git/gitGraphRenderer.js b/packages/mermaid/src/diagrams/git/gitGraphRenderer.js index 6124d72c68..cefbe89c14 100644 --- a/packages/mermaid/src/diagrams/git/gitGraphRenderer.js +++ b/packages/mermaid/src/diagrams/git/gitGraphRenderer.js @@ -116,7 +116,6 @@ const drawCommits = (svg, commits, modifyGraph) => { const commitStep = 40; sortedKeys.forEach((key) => { const commit = commits[key]; - const posWithOffset = pos + layoutOffset; if (isParallelCommits) { if (!commit.parents.length) { @@ -133,6 +132,7 @@ const drawCommits = (svg, commits, modifyGraph) => { } } + const posWithOffset = pos + layoutOffset; const y = dir === 'TB' ? posWithOffset : branchPos[commit.branch].pos; const x = dir === 'TB' ? branchPos[commit.branch].pos : posWithOffset; From 81825f22f508eee53a9ab809361935d52bc3caf0 Mon Sep 17 00:00:00 2001 From: Matheus B Date: Mon, 22 Jan 2024 20:09:20 -0300 Subject: [PATCH 146/217] Swap condition blocks to avoid using negation --- .../mermaid/src/diagrams/git/gitGraphRenderer.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/packages/mermaid/src/diagrams/git/gitGraphRenderer.js b/packages/mermaid/src/diagrams/git/gitGraphRenderer.js index cefbe89c14..84b8f41a16 100644 --- a/packages/mermaid/src/diagrams/git/gitGraphRenderer.js +++ b/packages/mermaid/src/diagrams/git/gitGraphRenderer.js @@ -118,17 +118,17 @@ const drawCommits = (svg, commits, modifyGraph) => { const commit = commits[key]; if (isParallelCommits) { - if (!commit.parents.length) { - pos = 0; - if (dir === 'TB') { - pos = 30; - } - } else { + if (commit.parents.length) { const closestParent = findClosestParent(commit.parents); pos = dir === 'TB' ? commitPos[closestParent].y + commitStep : commitPos[closestParent].x + commitStep; + } else { + pos = 0; + if (dir === 'TB') { + pos = 30; + } } } From 493f238319ffcebc10570a390d2bbacc121eb715 Mon Sep 17 00:00:00 2001 From: Sidharth Vinod Date: Tue, 23 Jan 2024 20:28:11 +0530 Subject: [PATCH 147/217] Fix applitools --- applitools.config.js | 19 ------------------- cypress.config.cjs | 32 -------------------------------- cypress.config.ts | 30 ++++++++++++++++++++++++++++++ 3 files changed, 30 insertions(+), 51 deletions(-) delete mode 100644 applitools.config.js delete mode 100644 cypress.config.cjs create mode 100644 cypress.config.ts diff --git a/applitools.config.js b/applitools.config.js deleted file mode 100644 index 4cf02220ac..0000000000 --- a/applitools.config.js +++ /dev/null @@ -1,19 +0,0 @@ -// eslint-disable-next-line @typescript-eslint/no-var-requires -const { defineConfig } = require('cypress'); - -module.exports = defineConfig({ - testConcurrency: 1, - browser: [ - // Add browsers with different viewports - // { width: 800, height: 600, name: 'chrome' }, - // { width: 700, height: 500, name: 'firefox' }, - // { width: 1600, height: 1200, name: 'ie11' }, - // { width: 1024, height: 768, name: 'edgechromium' }, - // { width: 800, height: 600, name: 'safari' }, - // // Add mobile emulation devices in Portrait mode - // { deviceName: 'iPhone X', screenOrientation: 'portrait' }, - // { deviceName: 'Pixel 2', screenOrientation: 'portrait' }, - ], - // set batch name to the configuration - // batchName: `Mermaid ${process.env.APPLI_BRANCH ?? "'no APPLI_BRANCH set'"}`, -}); diff --git a/cypress.config.cjs b/cypress.config.cjs deleted file mode 100644 index 33633920ac..0000000000 --- a/cypress.config.cjs +++ /dev/null @@ -1,32 +0,0 @@ -/* eslint-disable @typescript-eslint/no-var-requires */ - -const { defineConfig } = require('cypress'); -const { addMatchImageSnapshotPlugin } = require('cypress-image-snapshot/plugin'); -const coverage = require('@cypress/code-coverage/task'); - -module.exports = defineConfig({ - projectId: 'n2sma2', - viewportWidth: 1440, - viewportHeight: 1024, - e2e: { - specPattern: 'cypress/integration/**/*.{js,ts}', - setupNodeEvents(on, config) { - coverage(on, config); - on('before:browser:launch', (browser = {}, launchOptions) => { - if (browser.name === 'chrome' && browser.isHeadless) { - launchOptions.args.push('--window-size=1440,1024', '--force-device-scale-factor=1'); - } - return launchOptions; - }); - addMatchImageSnapshotPlugin(on, config); - // copy any needed variables from process.env to config.env - config.env.useAppli = process.env.USE_APPLI ? true : false; - - // do not forget to return the changed config object! - return config; - }, - }, - video: false, -}); - -require('@applitools/eyes-cypress')(module); diff --git a/cypress.config.ts b/cypress.config.ts new file mode 100644 index 0000000000..4182d92a87 --- /dev/null +++ b/cypress.config.ts @@ -0,0 +1,30 @@ +import { defineConfig } from 'cypress'; +import { addMatchImageSnapshotPlugin } from 'cypress-image-snapshot/plugin'; +import coverage from '@cypress/code-coverage/task'; +import eyesPlugin from '@applitools/eyes-cypress'; +export default eyesPlugin( + defineConfig({ + projectId: 'n2sma2', + viewportWidth: 1440, + viewportHeight: 1024, + e2e: { + specPattern: 'cypress/integration/**/*.{js,ts}', + setupNodeEvents(on, config) { + coverage(on, config); + on('before:browser:launch', (browser, launchOptions) => { + if (browser.name === 'chrome' && browser.isHeadless) { + launchOptions.args.push('--window-size=1440,1024', '--force-device-scale-factor=1'); + } + return launchOptions; + }); + addMatchImageSnapshotPlugin(on, config); + // copy any needed variables from process.env to config.env + config.env.useAppli = process.env.USE_APPLI ? true : false; + + // do not forget to return the changed config object! + return config; + }, + }, + video: false, + }) +); From 5c6c8d113562ea99e3d8445310a42fc3134610c7 Mon Sep 17 00:00:00 2001 From: Sidharth Vinod Date: Tue, 23 Jan 2024 20:36:29 +0530 Subject: [PATCH 148/217] Update cypress --- package.json | 6 +- pnpm-lock.yaml | 501 +++++++++++++++++-------------------------------- 2 files changed, 170 insertions(+), 337 deletions(-) diff --git a/package.json b/package.json index a60f6f67f0..441484218d 100644 --- a/package.json +++ b/package.json @@ -61,11 +61,11 @@ ] }, "devDependencies": { - "@applitools/eyes-cypress": "^3.33.1", + "@applitools/eyes-cypress": "^3.40.6", "@commitlint/cli": "^17.6.1", "@commitlint/config-conventional": "^17.6.1", "@cspell/eslint-plugin": "^6.31.1", - "@cypress/code-coverage": "^3.10.7", + "@cypress/code-coverage": "^3.12.18", "@rollup/plugin-typescript": "^11.1.1", "@types/cors": "^2.8.13", "@types/eslint": "^8.37.0", @@ -85,7 +85,7 @@ "ajv": "^8.12.0", "concurrently": "^8.0.1", "cors": "^2.8.5", - "cypress": "^12.10.0", + "cypress": "^12.17.4", "cypress-image-snapshot": "^4.0.1", "esbuild": "^0.19.0", "eslint": "^8.47.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 2484f63123..5d950edefc 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -9,8 +9,8 @@ importers: .: devDependencies: '@applitools/eyes-cypress': - specifier: ^3.33.1 - version: 3.36.2(typescript@5.1.6) + specifier: ^3.40.6 + version: 3.40.6(typescript@5.1.6) '@commitlint/cli': specifier: ^17.6.1 version: 17.7.1 @@ -21,8 +21,8 @@ importers: specifier: ^6.31.1 version: 6.31.3 '@cypress/code-coverage': - specifier: ^3.10.7 - version: 3.11.0(@babel/core@7.23.5)(@babel/preset-env@7.22.10)(babel-loader@9.1.3)(cypress@12.17.3)(webpack@5.88.2) + specifier: ^3.12.18 + version: 3.12.18(@babel/core@7.23.5)(@babel/preset-env@7.22.10)(babel-loader@9.1.3)(cypress@12.17.4)(webpack@5.88.2) '@rollup/plugin-typescript': specifier: ^11.1.1 version: 11.1.2(typescript@5.1.6) @@ -81,11 +81,11 @@ importers: specifier: ^2.8.5 version: 2.8.5 cypress: - specifier: ^12.10.0 - version: 12.17.3 + specifier: ^12.17.4 + version: 12.17.4 cypress-image-snapshot: specifier: ^4.0.1 - version: 4.0.1(cypress@12.17.3)(jest@29.6.2) + version: 4.0.1(cypress@12.17.4)(jest@29.6.2) esbuild: specifier: ^0.19.0 version: 0.19.0 @@ -714,110 +714,105 @@ packages: leven: 3.1.0 dev: true - /@applitools/core-base@1.5.0: - resolution: {integrity: sha512-fYK8a4GH0oTmdYYGx8rYCWjl6VH6Mt4iAukhOU6l502rBYAF8mChmwyTxXu8t6oh6ejX3YQ2I+WcAf2q9XIYvg==} + /@applitools/core-base@1.9.0: + resolution: {integrity: sha512-vicerOYUzDycn0Bf41FmLvGPBwuiTHP5EW7LqQowa38DAgXZLljoLo0IS68HV22HlMHHbzoRglMK3CPAGuNaqA==} engines: {node: '>=12.13.0'} dependencies: - '@applitools/image': 1.1.2 - '@applitools/logger': 2.0.7 - '@applitools/req': 1.5.2 - '@applitools/utils': 1.5.0 + '@applitools/image': 1.1.9 + '@applitools/logger': 2.0.14 + '@applitools/req': 1.6.4 + '@applitools/utils': 1.7.0 abort-controller: 3.0.0 throat: 6.0.2 transitivePeerDependencies: - supports-color dev: true - /@applitools/core@3.9.0(typescript@5.1.6): - resolution: {integrity: sha512-fKea8ew6iyLhZskUtngcyCdlJ59Nrb+8R9fU6Y6fXT0xMBQESkU1r9Z+Dt3XUL/CzRE9NW4DWenhd52EFApxYg==} + /@applitools/core@4.6.0(typescript@5.1.6): + resolution: {integrity: sha512-YLxg4TnIEdYPTOQpeqCbjUKfJBDfjKqwieMVnLKp7Loxwvfh16C4SvsCzLSLHyqfPgsE+zRdt6uoIK0uVWM94g==} engines: {node: '>=12.13.0'} hasBin: true dependencies: - '@applitools/core-base': 1.5.0 - '@applitools/dom-capture': 11.2.2 - '@applitools/dom-snapshot': 4.7.10 - '@applitools/driver': 1.13.4 - '@applitools/ec-client': 1.7.4(typescript@5.1.6) - '@applitools/logger': 2.0.7 - '@applitools/nml-client': 1.5.7 - '@applitools/req': 1.5.2 - '@applitools/screenshoter': 3.8.7 - '@applitools/snippets': 2.4.22 - '@applitools/socket': 1.1.7 - '@applitools/spec-driver-webdriver': 1.0.41(webdriver@7.30.0) - '@applitools/ufg-client': 1.7.0 - '@applitools/utils': 1.5.0 + '@applitools/core-base': 1.9.0 + '@applitools/dom-capture': 11.2.5 + '@applitools/dom-snapshot': 4.7.16 + '@applitools/driver': 1.16.1 + '@applitools/ec-client': 1.7.22(typescript@5.1.6) + '@applitools/logger': 2.0.14 + '@applitools/nml-client': 1.6.4 + '@applitools/req': 1.6.4 + '@applitools/screenshoter': 3.8.20 + '@applitools/snippets': 2.4.24 + '@applitools/socket': 1.1.14 + '@applitools/spec-driver-webdriver': 1.0.54(webdriver@7.31.1) + '@applitools/ufg-client': 1.9.9 + '@applitools/utils': 1.7.0 '@types/ws': 8.5.5 abort-controller: 3.0.0 chalk: 4.1.2 node-fetch: 2.6.7 - webdriver: 7.30.0(typescript@5.1.6) + semver: 7.5.4 + webdriver: 7.31.1(typescript@5.1.6) ws: 8.13.0 yargs: 17.7.2 transitivePeerDependencies: - bufferutil - - canvas - encoding - supports-color - typescript - utf-8-validate dev: true - /@applitools/dom-capture@11.2.2: - resolution: {integrity: sha512-omSH+c8+ij/mUPKVwRp7ulCOz33EHMnG8Q3s7XuwaB9m04onEAg82/25otOrntqMKmO2doGWN3E97qUstZJiPQ==} - engines: {node: '>=8.9.0'} + /@applitools/dom-capture@11.2.5: + resolution: {integrity: sha512-bjVduGCBOdDyGSkXs8sH47wRpuwBt6f1FvzbATumIFp0V6xGAB1ehpO+j3Ss1SajwlDl8WQkyS6/85nTFyW3eA==} + engines: {node: '>=12.13.0'} dependencies: - '@applitools/dom-shared': 1.0.5 + '@applitools/dom-shared': 1.0.12 '@applitools/functional-commons': 1.6.0 dev: true - /@applitools/dom-shared@1.0.10: - resolution: {integrity: sha512-1k0CUQRm+38n6aTg/8IIppndYPDJLc/dU8Regbi/miP3xZmOG4Wwd5fBiu/MI5lgQm6RZU+at18lpCLFwU+Nng==} - engines: {node: '>=8.9.0'} - dev: true - - /@applitools/dom-shared@1.0.5: - resolution: {integrity: sha512-O2zgnnqVi3/Atq7EQjURLa73XNaDFJCj8wHht6WQtxIv1EWYnPutNTmnJSKwK7FnbJAg65OVjZylcz4EezyYZA==} - engines: {node: '>=8.9.0'} + /@applitools/dom-shared@1.0.12: + resolution: {integrity: sha512-GFyVHOUFjaS2WhUPjaELn1yBAK9hmRqv031RRQjYkf+3aD9GfzKHj/ZUVcSsZydid+0VAtHVQFwZGH79bGhd7w==} + engines: {node: '>=12.13.0'} dev: true - /@applitools/dom-snapshot@4.7.10: - resolution: {integrity: sha512-QhX0p6irvQE48eeauNHIfEm76L8QY8mDO8Tk4YOzzBRKcGpKphQUR/5GRCR9S3jx5wwJAwjF/aMW/W7Cwdaztw==} - engines: {node: '>=8.9.0'} + /@applitools/dom-snapshot@4.7.16: + resolution: {integrity: sha512-GXWrMOkpHlnpo0tonhxfmDFOiCaT//ZDexB9vGKLgBBF0QDFpdy9BgvasLvy8I0PuVegXsgJbZS3gS053N7SHQ==} + engines: {node: '>=12.13.0'} dependencies: - '@applitools/dom-shared': 1.0.10 + '@applitools/dom-shared': 1.0.12 '@applitools/functional-commons': 1.6.0 css-tree: 2.3.1 pako: 1.0.11 dev: true - /@applitools/driver@1.13.4: - resolution: {integrity: sha512-LdATkjMoTZKUDHmuIfV0uh0ZiRe+yNNIehTqmjV6LnQrNvm73ddzF2Tn+LM8Vg/CflwFhw+TVKPaywTmi35wUg==} + /@applitools/driver@1.16.1: + resolution: {integrity: sha512-DfSbcKopOIPl1Wfet3Uib2bDSl64Wh51772MPM7A/xrwJrLOY5NvfT71PqMIQd4eZAd6k5hRg5gbGL5zTzktLQ==} engines: {node: '>=12.13.0'} dependencies: - '@applitools/logger': 2.0.7 - '@applitools/snippets': 2.4.22 - '@applitools/utils': 1.5.0 + '@applitools/logger': 2.0.14 + '@applitools/snippets': 2.4.24 + '@applitools/utils': 1.7.0 semver: 7.5.4 transitivePeerDependencies: - supports-color dev: true - /@applitools/ec-client@1.7.4(typescript@5.1.6): - resolution: {integrity: sha512-vFY5O9WXQ905hUcw4ot1BuKAAFq6F+hyQfX/obsQsUPUvJXqHhiFjMiI/x3cyrPr40EVLQM8edZCa71m4k2WyQ==} + /@applitools/ec-client@1.7.22(typescript@5.1.6): + resolution: {integrity: sha512-zhkYIW8bUpwc+TmvQyxL12kIt2TnAwB30XHke1ApmcPxGk9P8lfjm/AzwnKHqDBJxN2V/TSUfuRvseZq5b4TRA==} engines: {node: '>=12.13.0'} hasBin: true dependencies: - '@applitools/core-base': 1.5.0 - '@applitools/driver': 1.13.4 - '@applitools/logger': 2.0.7 - '@applitools/req': 1.5.2 - '@applitools/socket': 1.1.7 - '@applitools/spec-driver-webdriver': 1.0.41(webdriver@7.30.0) - '@applitools/tunnel-client': 1.1.3 - '@applitools/utils': 1.5.0 + '@applitools/core-base': 1.9.0 + '@applitools/driver': 1.16.1 + '@applitools/logger': 2.0.14 + '@applitools/req': 1.6.4 + '@applitools/socket': 1.1.14 + '@applitools/spec-driver-webdriver': 1.0.54(webdriver@7.31.1) + '@applitools/tunnel-client': 1.4.0 + '@applitools/utils': 1.7.0 abort-controller: 3.0.0 - webdriver: 7.30.0(typescript@5.1.6) + webdriver: 7.31.1(typescript@5.1.6) yargs: 17.7.2 transitivePeerDependencies: - supports-color @@ -859,40 +854,38 @@ packages: - supports-color dev: true - /@applitools/eyes-cypress@3.36.2(typescript@5.1.6): - resolution: {integrity: sha512-GA1KP7i3Zr7sbc8yscw7fay1XbQ46LxEAH4dLqjJhOmvvpZuDlmgRyVMuvTmobDXKKHtdVpfoXtJQURrxs7fvA==} + /@applitools/eyes-cypress@3.40.6(typescript@5.1.6): + resolution: {integrity: sha512-Klqt3y2U9pl+btLKQJB6e6UtzOv4wdAKxD9V6VCjLF8DqQeBukinAG3kBgpDRQVEVCYMeQXdQZrRTRJvZOkpIg==} engines: {node: '>=12.13.0'} hasBin: true dependencies: - '@applitools/core': 3.9.0(typescript@5.1.6) - '@applitools/eyes': 1.7.2(typescript@5.1.6) + '@applitools/core': 4.6.0(typescript@5.1.6) + '@applitools/eyes': 1.13.5(typescript@5.1.6) '@applitools/functional-commons': 1.6.0 - '@applitools/logger': 2.0.7 - '@applitools/utils': 1.5.0 + '@applitools/logger': 2.0.14 + '@applitools/utils': 1.7.0 boxen: 5.1.2 chalk: 3.0.0 - semver: 7.3.8 + semver: 7.5.4 uuid: 8.3.2 ws: 8.5.0 transitivePeerDependencies: - bufferutil - - canvas - encoding - supports-color - typescript - utf-8-validate dev: true - /@applitools/eyes@1.7.2(typescript@5.1.6): - resolution: {integrity: sha512-RNwPMp19xmQ+oEEZH66wGbnBbOqsrHaLBwnCZ9qJ9294aN4DuYHJNXdzHtLFSwjHNc8UmyDRU2Enn4825hqV6w==} + /@applitools/eyes@1.13.5(typescript@5.1.6): + resolution: {integrity: sha512-FXFH5D78UMcqG0No5FgvISlfGM9DrXTCnRsEXhEw+dbQneG7siKRY6BQci3QDgrh0sI0yfVaZbZrpXIKuDF1ug==} engines: {node: '>=12.13.0'} dependencies: - '@applitools/core': 3.9.0(typescript@5.1.6) - '@applitools/logger': 2.0.7 - '@applitools/utils': 1.5.0 + '@applitools/core': 4.6.0(typescript@5.1.6) + '@applitools/logger': 2.0.14 + '@applitools/utils': 1.7.0 transitivePeerDependencies: - bufferutil - - canvas - encoding - supports-color - typescript @@ -904,11 +897,11 @@ packages: engines: {node: '>=8.0.0'} dev: true - /@applitools/image@1.1.2: - resolution: {integrity: sha512-Cy1oKCB2vIpHT47Y1tictsRS2RLBVI4XzxYWvKnXx+ZsbL364IiDzwWxYKgvA7/6t1Ako648n4+BWKoUi5Ewbg==} + /@applitools/image@1.1.9: + resolution: {integrity: sha512-R86re+yofXSBamTuzSLwFB57fzaf7aiKvyx675uw8e/XfqQy3vhGbp8Bh23lUZX9y7ngf2ldrpnQ7nQrvmtJuA==} engines: {node: '>=12.13.0'} dependencies: - '@applitools/utils': 1.5.0 + '@applitools/utils': 1.7.0 bmpimagejs: 1.0.4 jpeg-js: 0.4.4 omggif: 1.0.10 @@ -926,33 +919,33 @@ packages: - supports-color dev: true - /@applitools/logger@2.0.7: - resolution: {integrity: sha512-dmX2nWWixMYsOdhl1MANv7wr8cKzYUOaHxQp9CdokVbJy+NGwWAzK6qVeKjogn7D6eXHzgn3R3OzplYSq/fK/g==} + /@applitools/logger@2.0.14: + resolution: {integrity: sha512-oq/RPjs/3BjR3EdLohHhzzVufBYEMMhOUmZlCnvgmCJIhUsa3ceq8Ta2E99TUzSny9xkl962JoRDfLQg/vS+Ww==} engines: {node: '>=12.13.0'} dependencies: - '@applitools/utils': 1.5.0 + '@applitools/utils': 1.7.0 chalk: 4.1.2 debug: 4.3.4(supports-color@8.1.1) transitivePeerDependencies: - supports-color dev: true - /@applitools/nml-client@1.5.7: - resolution: {integrity: sha512-jAG2/4JSqX7FSrdyIyjdXcPy2l2/t8KRlw554nL1ABgtqTV8yCI3DxVUk7RCNi39f1uY5pA2pfiZVGFImnSFKg==} + /@applitools/nml-client@1.6.4: + resolution: {integrity: sha512-mbLnwpXbM2MkB+bP9+Hluywi4OAFWDr+FvjHkk/9TcvcM9EYbmD8deGuTC5kFt5WDDS568WQDRj+G2tT1JfLEA==} engines: {node: '>=12.13.0'} dependencies: - '@applitools/logger': 2.0.7 - '@applitools/req': 1.5.2 - '@applitools/utils': 1.5.0 + '@applitools/logger': 2.0.14 + '@applitools/req': 1.6.4 + '@applitools/utils': 1.7.0 transitivePeerDependencies: - supports-color dev: true - /@applitools/req@1.5.2: - resolution: {integrity: sha512-evuikeiCYudhxSQ2kisO7DdywPqshaaN+BiDu4P3eTz5R9VmqhXwWP9bS88G8bzzz0FeNQMY9a7TjQ7d5jMRrA==} - engines: {node: '>=12.13.0'} + /@applitools/req@1.6.4: + resolution: {integrity: sha512-yKTga1QHzIk7ECHgC8JEgYxV91PdIHWRa02ZpsK2FAk6GjTefPK6WZsj1vGKeVi/dGxHuZT8sjvtJHc275osug==} + engines: {node: '>=16.13.0'} dependencies: - '@applitools/utils': 1.5.0 + '@applitools/utils': 1.7.0 abort-controller: 3.0.0 http-proxy-agent: 5.0.0 https-proxy-agent: 5.0.1 @@ -961,81 +954,78 @@ packages: - supports-color dev: true - /@applitools/screenshoter@3.8.7: - resolution: {integrity: sha512-G576fLyTTAJEnhFZBeD57+1JDXGTDcTlrg0n32ujtYTFswUAf5XnXmeO6s2WqeHKQl74e2xwhBmdtU/CrVOkig==} + /@applitools/screenshoter@3.8.20: + resolution: {integrity: sha512-k7t4cdJ5vpgYvsLLrenSvPNkUZ25uUs7Q54X0tGtkgQ/C+pQ8GLaIXQQwyVaEYbnF6WuAnrjTXMpdPJ2uUvpAg==} engines: {node: '>=12.13.0'} dependencies: - '@applitools/image': 1.1.2 - '@applitools/logger': 2.0.7 - '@applitools/snippets': 2.4.22 - '@applitools/utils': 1.5.0 + '@applitools/image': 1.1.9 + '@applitools/logger': 2.0.14 + '@applitools/snippets': 2.4.24 + '@applitools/utils': 1.7.0 transitivePeerDependencies: - supports-color dev: true - /@applitools/snippets@2.4.22: - resolution: {integrity: sha512-bv4GzMf6k4mAyMxo3PVR3HKEPkf4h0O6+xNo6UO78cw+MpkT4Sr7JDk3mLq8H/WRDKk7x4VKpJeoDHd5dBxT3g==} + /@applitools/snippets@2.4.24: + resolution: {integrity: sha512-T/cfYA15K+gR2Xc/cEnn2hR7XBJ9vCcH/Jcp7Hoor14j7nzldR+u69HaQe/sa4ChDU4eZyTiTggek52+MqX7FQ==} engines: {node: '>=12.13.0'} dev: true - /@applitools/socket@1.1.7: - resolution: {integrity: sha512-SpP+Zw5B9VJ3K+xW+wSYDwfrOQ1U9/95h5G3rszKaVleX2FTUW0JgmASuSlwgr7veU3qlcNzt3vas/tQM3/z/g==} + /@applitools/socket@1.1.14: + resolution: {integrity: sha512-o43hNnD/PN5T5MFR3cZ5OC+b5PpkV/PeTk8z844sNtGyziS9GEpO0vYfG2XLq/mZg0YQurrXtYupUMndV+0wDg==} engines: {node: '>=12.13.0'} dependencies: - '@applitools/logger': 2.0.7 - '@applitools/utils': 1.5.0 + '@applitools/logger': 2.0.14 + '@applitools/utils': 1.7.0 transitivePeerDependencies: - supports-color dev: true - /@applitools/spec-driver-webdriver@1.0.41(webdriver@7.30.0): - resolution: {integrity: sha512-0kUHiFmr3FiOlfTnfS1k8pvJXgnEM8bP36teiDJvmAJnk8aJG5nmqaQj1KkeLUVVZ1wfYlg/+iDtGUdP4a4Zxw==} + /@applitools/spec-driver-webdriver@1.0.54(webdriver@7.31.1): + resolution: {integrity: sha512-ZpwUBWu5kUil5E+r+NdhdB8SzWwGv56+sZSGyPlgN0w2krmIudeyBKuJKYMfqdXSu0lATSgKJSCJXmkb/q4DNQ==} engines: {node: '>=12.13.0'} peerDependencies: - webdriver: '>=7.27.0' + webdriver: '>=6.0.0' dependencies: - '@applitools/driver': 1.13.4 - '@applitools/utils': 1.5.0 + '@applitools/driver': 1.16.1 + '@applitools/utils': 1.7.0 http-proxy-agent: 5.0.0 https-proxy-agent: 5.0.1 - webdriver: 7.30.0(typescript@5.1.6) + webdriver: 7.31.1(typescript@5.1.6) transitivePeerDependencies: - supports-color dev: true - /@applitools/tunnel-client@1.1.3: - resolution: {integrity: sha512-xe0HqznqnuhsZYIY//NnjszEkIcYgdZkwVR4GOwzVCOCcxIGoi+kMpDUuC2Xcd8+UiVbfZfZTeo7rXITlzzqAw==} + /@applitools/tunnel-client@1.4.0: + resolution: {integrity: sha512-vgQoEN81Mhqjf74+9JAUvGK8t8Dzm0p8nNrqsqeHekuTva6Jh92sNK40j96z7jrMoSo+JHOeb/7mIOicU9o/0A==} engines: {node: '>=12.13.0'} hasBin: true dependencies: '@applitools/execution-grid-tunnel': 2.1.8 - '@applitools/logger': 2.0.7 - '@applitools/req': 1.5.2 - '@applitools/socket': 1.1.7 - '@applitools/utils': 1.5.0 + '@applitools/logger': 2.0.14 + '@applitools/req': 1.6.4 + '@applitools/socket': 1.1.14 + '@applitools/utils': 1.7.0 abort-controller: 3.0.0 yargs: 17.7.2 transitivePeerDependencies: - supports-color dev: true - /@applitools/ufg-client@1.7.0: - resolution: {integrity: sha512-BMFLuWGq8YVs0/z5VBl8CAKzOMXbagHFxyR4oGdg31nDsuKgKfhlnbGji5qek243ex8vEbEqFwsH2K0ZXYGIeQ==} + /@applitools/ufg-client@1.9.9: + resolution: {integrity: sha512-J/k6C1JYPr4ohcE64AvVHIeTMZ83bXnhuIryxvOWJDSyr6Yh4hvtrbCviUyYMaKj7WCMYeDEESt6auiyBMxVGw==} engines: {node: '>=12.13.0'} dependencies: - '@applitools/image': 1.1.2 - '@applitools/logger': 2.0.7 - '@applitools/req': 1.5.2 - '@applitools/utils': 1.5.0 + '@applitools/image': 1.1.9 + '@applitools/logger': 2.0.14 + '@applitools/req': 1.6.4 + '@applitools/utils': 1.7.0 + '@xmldom/xmldom': 0.8.10 abort-controller: 3.0.0 css-tree: 2.3.1 - jsdom: 19.0.0 throat: 6.0.2 transitivePeerDependencies: - - bufferutil - - canvas - supports-color - - utf-8-validate dev: true /@applitools/utils@1.3.36: @@ -1043,8 +1033,8 @@ packages: engines: {node: '>=12.13.0'} dev: true - /@applitools/utils@1.5.0: - resolution: {integrity: sha512-BZk8YolP0G+/Srjkhf+pFp4zY7bU41L63hDN9gtwrD1xZOfWXJbOCD3gFQAGRB2qsozHMkPNTt+xw7RJjIjGQg==} + /@applitools/utils@1.7.0: + resolution: {integrity: sha512-CvBxdfPZ3ss1hOD8Yr9y2SzVfqLKBA/0N3gfQd5qafMrBhI0wuCycQmiclpAQNEVNkbhqn8/t6dOeeYgapjyDw==} engines: {node: '>=12.13.0'} dev: true @@ -3104,27 +3094,31 @@ packages: dependencies: '@jridgewell/trace-mapping': 0.3.9 - /@cypress/code-coverage@3.11.0(@babel/core@7.23.5)(@babel/preset-env@7.22.10)(babel-loader@9.1.3)(cypress@12.17.3)(webpack@5.88.2): - resolution: {integrity: sha512-ihSO1s03gmLRE224oIjrbdG1ey63vw/UY+VSqQ5m/TKkAvyz6GIiniq6juk3AV/+0vQC1Eb4UWFu8ndtji4M1g==} + /@cypress/code-coverage@3.12.18(@babel/core@7.23.5)(@babel/preset-env@7.22.10)(babel-loader@9.1.3)(cypress@12.17.4)(webpack@5.88.2): + resolution: {integrity: sha512-RTOyCVr5CWaJ7cW1gOvlXSLDr0HNXZ7xSVfLSZEGsTODbaxeUV01Z1k93spnbVT7ri9UkxCEffPcsZsZi1oDng==} peerDependencies: + '@babel/core': ^7.0.1 + '@babel/preset-env': ^7.0.0 + babel-loader: ^8.3 || ^9 cypress: '*' + webpack: ^4 || ^5 dependencies: - '@cypress/webpack-preprocessor': 5.17.1(@babel/core@7.23.5)(@babel/preset-env@7.22.10)(babel-loader@9.1.3)(webpack@5.88.2) + '@babel/core': 7.23.5 + '@babel/preset-env': 7.22.10(@babel/core@7.23.5) + '@cypress/webpack-preprocessor': 6.0.1(@babel/core@7.23.5)(@babel/preset-env@7.22.10)(babel-loader@9.1.3)(webpack@5.88.2) + babel-loader: 9.1.3(@babel/core@7.23.5)(webpack@5.88.2) chalk: 4.1.2 - cypress: 12.17.3 - dayjs: 1.11.9 + cypress: 12.17.4 + dayjs: 1.11.10 debug: 4.3.4(supports-color@8.1.1) execa: 4.1.0 - globby: 11.0.4 - istanbul-lib-coverage: 3.0.0 + globby: 11.1.0 + istanbul-lib-coverage: 3.2.0 js-yaml: 4.1.0 nyc: 15.1.0 + webpack: 5.88.2(esbuild@0.19.0)(webpack-cli@4.10.0) transitivePeerDependencies: - - '@babel/core' - - '@babel/preset-env' - - babel-loader - supports-color - - webpack dev: true /@cypress/request@2.88.12: @@ -3151,12 +3145,12 @@ packages: uuid: 8.3.2 dev: true - /@cypress/webpack-preprocessor@5.17.1(@babel/core@7.23.5)(@babel/preset-env@7.22.10)(babel-loader@9.1.3)(webpack@5.88.2): - resolution: {integrity: sha512-FE/e8ikPc8z4EVopJCaior3RGy0jd2q9Xcp5NtiwNG4XnLfEnUFTZlAGwXe75sEh4fNMPrBJW1KIz77PX5vGAw==} + /@cypress/webpack-preprocessor@6.0.1(@babel/core@7.23.5)(@babel/preset-env@7.22.10)(babel-loader@9.1.3)(webpack@5.88.2): + resolution: {integrity: sha512-WVNeFVSnFKxE3WZNRIriduTgqJRpevaiJIPlfqYTTzfXRD7X1Pv4woDE+G4caPV9bJqVKmVFiwzrXMRNeJxpxA==} peerDependencies: '@babel/core': ^7.0.1 '@babel/preset-env': ^7.0.0 - babel-loader: ^8.0.2 || ^9 + babel-loader: ^8.3 || ^9 webpack: ^4 || ^5 dependencies: '@babel/core': 7.23.5 @@ -4931,6 +4925,13 @@ packages: '@types/node': 18.17.5 dev: true + /@types/glob@8.1.0: + resolution: {integrity: sha512-IO+MJPVhoqz+28h1qLAcBEH2+xHMK6MTyHJc7MTnnYb6wsoLR29POVGJ7LycmVXIqyy/4/2ShP5sUwTXuOwb/w==} + dependencies: + '@types/minimatch': 5.1.2 + '@types/node': 18.17.5 + dev: true + /@types/graceful-fs@4.1.6: resolution: {integrity: sha512-Sig0SNORX9fdW+bQuTEovKj3uHcUL6LQKbCrrqb1X7J6/ReAbhCXRAhc+SMejhLELFj2QcyuxmUooZ4bt5ReSw==} dependencies: @@ -6146,13 +6147,14 @@ packages: - vue dev: true - /@wdio/config@7.30.0(typescript@5.1.6): - resolution: {integrity: sha512-/38rol9WCfFTMtXyd/C856/aexxIZnfVvXg7Fw2WXpqZ9qadLA+R4N35S2703n/RByjK/5XAYtHoljtvh3727w==} + /@wdio/config@7.31.1(typescript@5.1.6): + resolution: {integrity: sha512-WAfswbCatwiaDVqy6kfF/5T8/WS/US/SRhBGUFrfBuGMIe+RRoHgy7jURFWSvUIE7CNHj8yvs46fLUcxhXjzcQ==} engines: {node: '>=12.0.0'} dependencies: + '@types/glob': 8.1.0 '@wdio/logger': 7.26.0 - '@wdio/types': 7.26.0(typescript@5.1.6) - '@wdio/utils': 7.26.0(typescript@5.1.6) + '@wdio/types': 7.30.2(typescript@5.1.6) + '@wdio/utils': 7.30.2(typescript@5.1.6) deepmerge: 4.3.1 glob: 8.1.0 transitivePeerDependencies: @@ -6174,8 +6176,8 @@ packages: engines: {node: '>=12.0.0'} dev: true - /@wdio/types@7.26.0(typescript@5.1.6): - resolution: {integrity: sha512-mOTfWAGQ+iT58iaZhJMwlUkdEn3XEWE4jthysMLXFnSuZ2eaODVAiK31SmlS/eUqgSIaupeGqYUrtCuSNbLefg==} + /@wdio/types@7.30.2(typescript@5.1.6): + resolution: {integrity: sha512-uZ8o7FX8RyBsaXiOWa59UKTCHTtADNvOArYTcHNEIzt+rh4JdB/uwqfc8y4TCNA2kYm7PWaQpUFwpStLeg0H1Q==} engines: {node: '>=12.0.0'} peerDependencies: typescript: ^4.6.2 @@ -6188,12 +6190,12 @@ packages: typescript: 5.1.6 dev: true - /@wdio/utils@7.26.0(typescript@5.1.6): - resolution: {integrity: sha512-pVq2MPXZAYLkKGKIIHktHejnHqg4TYKoNYSi2EDv+I3GlT8VZKXHazKhci82ov0tD+GdF27+s4DWNDCfGYfBdQ==} + /@wdio/utils@7.30.2(typescript@5.1.6): + resolution: {integrity: sha512-np7I+smszFUennbQKdzbMN/zUL3s3EZq9pCCUcTRjjs9TE4tnn0wfmGdoz2o7REYu6kn9NfFFJyVIM2VtBbKEA==} engines: {node: '>=12.0.0'} dependencies: '@wdio/logger': 7.26.0 - '@wdio/types': 7.26.0(typescript@5.1.6) + '@wdio/types': 7.30.2(typescript@5.1.6) p-iteration: 1.1.8 transitivePeerDependencies: - typescript @@ -6414,13 +6416,6 @@ packages: negotiator: 0.6.3 dev: true - /acorn-globals@6.0.0: - resolution: {integrity: sha512-ZQl7LOWaF5ePqqcX4hLuv/bLXYQNfNWw2c0/yX/TsPRKamzHcTGQnlCjHT3TsmkOUVEPS3crCxiPfdzE/Trlhg==} - dependencies: - acorn: 7.4.1 - acorn-walk: 7.2.0 - dev: true - /acorn-import-assertions@1.9.0(acorn@8.10.0): resolution: {integrity: sha512-cmMwop9x+8KFhxvKrKfPYmN6/pKTYYHBqLa0DfvVZcKMJWNyWLnaqND7dx/qn66R7ewM1UX5XMaDVP5wlVTaVA==} peerDependencies: @@ -6437,21 +6432,10 @@ packages: acorn: 8.10.0 dev: true - /acorn-walk@7.2.0: - resolution: {integrity: sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA==} - engines: {node: '>=0.4.0'} - dev: true - /acorn-walk@8.2.0: resolution: {integrity: sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==} engines: {node: '>=0.4.0'} - /acorn@7.4.1: - resolution: {integrity: sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==} - engines: {node: '>=0.4.0'} - hasBin: true - dev: true - /acorn@8.10.0: resolution: {integrity: sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw==} engines: {node: '>=0.4.0'} @@ -7070,10 +7054,6 @@ packages: dependencies: fill-range: 7.0.1 - /browser-process-hrtime@1.0.0: - resolution: {integrity: sha512-9o5UecI3GhkpM6DrXr69PblIuWxPKk9Y0jHBRhdocZ2y7YECBFCsHm79Pr3OyR2AvjhDkabFJaDJMYRazHgsow==} - dev: true - /browserslist@4.21.10: resolution: {integrity: sha512-bipEBdZfVH5/pwrvqc+Ub0kUPVfGUhlKxbvfD+z1BDnPEO/X98ruXGA1WP5ASpAFKan7Qr6j736IacbZQuAlKQ==} engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} @@ -8059,21 +8039,6 @@ packages: hasBin: true dev: false - /cssom@0.3.8: - resolution: {integrity: sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==} - dev: true - - /cssom@0.5.0: - resolution: {integrity: sha512-iKuQcq+NdHqlAcwUY0o/HL69XQrUaQdMjmStJ8JFmUaiiQErlhrmuigkg/CU4E2J0IyUKUrMAgl36TvN67MqTw==} - dev: true - - /cssstyle@2.3.0: - resolution: {integrity: sha512-AZL67abkUzIuvcHqk7c09cezpGNcxUxU4Ioi/05xHk4DQeTkWmGYftIE6ctU6AEt+Gn4n1lDStOtj7FKycP71A==} - engines: {node: '>=8'} - dependencies: - cssom: 0.3.8 - dev: true - /cssstyle@3.0.0: resolution: {integrity: sha512-N4u2ABATi3Qplzf0hWbVCdjenim8F3ojEXpBDF5hBpjzW182MjNGLqfmQ0SkSPeQ+V86ZXgeH8aXj6kayd4jgg==} engines: {node: '>=14'} @@ -8102,14 +8067,14 @@ packages: resolution: {integrity: sha512-d4ZVpCW31eWwCMe1YT3ur7mUDnTXbgwyzaL320DrcRT45rfjYxkt5QWLrmOJ+/UEAI2+fQgKe/fCjR8l4TpRgw==} dev: true - /cypress-image-snapshot@4.0.1(cypress@12.17.3)(jest@29.6.2): + /cypress-image-snapshot@4.0.1(cypress@12.17.4)(jest@29.6.2): resolution: {integrity: sha512-PBpnhX/XItlx3/DAk5ozsXQHUi72exybBNH5Mpqj1DVmjq+S5Jd9WE5CRa4q5q0zuMZb2V2VpXHth6MjFpgj9Q==} engines: {node: '>=8'} peerDependencies: cypress: ^4.5.0 dependencies: chalk: 2.4.2 - cypress: 12.17.3 + cypress: 12.17.4 fs-extra: 7.0.1 glob: 7.2.3 jest-image-snapshot: 4.2.0(jest@29.6.2) @@ -8119,8 +8084,8 @@ packages: - jest dev: true - /cypress@12.17.3: - resolution: {integrity: sha512-/R4+xdIDjUSLYkiQfwJd630S81KIgicmQOLXotFxVXkl+eTeVO+3bHXxdi5KBh/OgC33HWN33kHX+0tQR/ZWpg==} + /cypress@12.17.4: + resolution: {integrity: sha512-gAN8Pmns9MA5eCDFSDJXWKUpaL3IDd89N9TtIupjYnzLSmlpVr+ZR+vb4U/qaMp+lB6tBvAmt7504c3Z4RU5KQ==} engines: {node: ^14.0.0 || ^16.0.0 || >=18.0.0} hasBin: true requiresBuild: true @@ -8160,6 +8125,7 @@ packages: minimist: 1.2.8 ospath: 1.2.2 pretty-bytes: 5.6.0 + process: 0.11.10 proxy-from-env: 1.0.0 request-progress: 3.0.0 semver: 7.5.4 @@ -8576,15 +8542,6 @@ packages: engines: {node: '>= 12'} dev: true - /data-urls@3.0.2: - resolution: {integrity: sha512-Jy/tj3ldjZJo63sVAvg6LHt2mHvl4V6AgRAmNDtLdm7faqtsx+aJG42rsyCo9JCoRVKwPFzKlIPx3DIibwSIaQ==} - engines: {node: '>=12'} - dependencies: - abab: 2.0.6 - whatwg-mimetype: 3.0.0 - whatwg-url: 11.0.0 - dev: true - /data-urls@4.0.0: resolution: {integrity: sha512-/mMTei/JXPqvFqQtfyTowxmJVwr2PVAeCcDxyFf6LhoOu/09TX2OX3kb2wzi4DMXcfj4OItwDOnhl5oziPnT6g==} engines: {node: '>=14'} @@ -8601,6 +8558,10 @@ packages: '@babel/runtime': 7.22.10 dev: true + /dayjs@1.11.10: + resolution: {integrity: sha512-vjAczensTgRcqDERK0SR2XMwsF/tSvnvlv6VcF2GIhg6Sx4yOIt/irsr1RDJsKiIyBzJDpCoXiWWq28MqH2cnQ==} + dev: true + /dayjs@1.11.7: resolution: {integrity: sha512-+Yw9U6YO5TQohxLcIkrXBeY73WP3ejHWVvx8XCk3gxvQDCTEmS48ZrSZCKciI7Bhl/uCMyxYtE9UqRILmFphkQ==} dev: false @@ -9265,18 +9226,6 @@ packages: source-map: 0.1.43 dev: true - /escodegen@2.1.0: - resolution: {integrity: sha512-2NlIDTwUWJN0mRPQOdtQBzbUHvdGY2P1VXSyU83Q3xKxM7WHX2Ql8dKq782Q9TgQUNOLEzEYu9bzLNj1q88I5w==} - engines: {node: '>=6.0'} - hasBin: true - dependencies: - esprima: 4.0.1 - estraverse: 5.3.0 - esutils: 2.0.3 - optionalDependencies: - source-map: 0.6.1 - dev: true - /eslint-config-prettier@8.10.0(eslint@8.47.0): resolution: {integrity: sha512-SM8AMJdeQqRYT9O9zguiruQZaN7+z+E4eAP9oiLNGKMtomwaB1E9dcgUD6ZAn/eQAb52USbvezbiljfZUhbJcg==} hasBin: true @@ -10416,18 +10365,6 @@ packages: define-properties: 1.2.0 dev: true - /globby@11.0.4: - resolution: {integrity: sha512-9O4MVG9ioZJ08ffbcyVYyLOJLk5JQ688pJ4eMGLpdWLHq/Wr1D9BlriLQyL0E+jbkuePVZXYFj47QM/v093wHg==} - engines: {node: '>=10'} - dependencies: - array-union: 2.1.0 - dir-glob: 3.0.1 - fast-glob: 3.3.2 - ignore: 5.2.4 - merge2: 1.4.1 - slash: 3.0.0 - dev: true - /globby@11.1.0: resolution: {integrity: sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==} engines: {node: '>=10'} @@ -11229,11 +11166,6 @@ packages: resolution: {integrity: sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g==} dev: true - /istanbul-lib-coverage@3.0.0: - resolution: {integrity: sha512-UiUIqxMgRDET6eR+o5HbfRYP1l0hqkWOs7vNxC/mggutCMUIhWMm8gAHb8tHlyfD3/l6rlgNA5cKdDzEAf6hEg==} - engines: {node: '>=8'} - dev: true - /istanbul-lib-coverage@3.2.0: resolution: {integrity: sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw==} engines: {node: '>=8'} @@ -11869,48 +11801,6 @@ packages: engines: {node: '>=12.0.0'} dev: true - /jsdom@19.0.0: - resolution: {integrity: sha512-RYAyjCbxy/vri/CfnjUWJQQtZ3LKlLnDqj+9XLNnJPgEGeirZs3hllKR20re8LUZ6o1b1X4Jat+Qd26zmP41+A==} - engines: {node: '>=12'} - peerDependencies: - canvas: ^2.5.0 - peerDependenciesMeta: - canvas: - optional: true - dependencies: - abab: 2.0.6 - acorn: 8.10.0 - acorn-globals: 6.0.0 - cssom: 0.5.0 - cssstyle: 2.3.0 - data-urls: 3.0.2 - decimal.js: 10.4.3 - domexception: 4.0.0 - escodegen: 2.1.0 - form-data: 4.0.0 - html-encoding-sniffer: 3.0.0 - http-proxy-agent: 5.0.0 - https-proxy-agent: 5.0.1 - is-potential-custom-element-name: 1.0.1 - nwsapi: 2.2.7 - parse5: 6.0.1 - saxes: 5.0.1 - symbol-tree: 3.2.4 - tough-cookie: 4.1.3 - w3c-hr-time: 1.0.2 - w3c-xmlserializer: 3.0.0 - webidl-conversions: 7.0.0 - whatwg-encoding: 2.0.0 - whatwg-mimetype: 3.0.0 - whatwg-url: 10.0.0 - ws: 8.13.0 - xml-name-validator: 4.0.0 - transitivePeerDependencies: - - bufferutil - - supports-color - - utf-8-validate - dev: true - /jsdom@22.0.0: resolution: {integrity: sha512-p5ZTEb5h+O+iU02t0GfEjAnkdYPrQSkfuTSMkMYyIoMvUNEHsbG0bHHbfXIcfTqD2UfvjQX7mmgiFsyRwGscVw==} engines: {node: '>=16'} @@ -13615,10 +13505,6 @@ packages: lines-and-columns: 1.2.4 dev: true - /parse5@6.0.1: - resolution: {integrity: sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==} - dev: true - /parse5@7.1.2: resolution: {integrity: sha512-Czj1WaSVpaoj0wbhMzLmWD69anp2WH7FXMB9n1Sy8/ZFF9jolSQVMu1Ij5WIyGmcBmhk7EOndpO4mIpihVqAXw==} dependencies: @@ -14026,7 +13912,6 @@ packages: /process@0.11.10: resolution: {integrity: sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==} engines: {node: '>= 0.6.0'} - dev: false /prompts@2.4.2: resolution: {integrity: sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==} @@ -14665,13 +14550,6 @@ packages: /safer-buffer@2.1.2: resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} - /saxes@5.0.1: - resolution: {integrity: sha512-5LBh1Tls8c9xgGjw3QrMwETmTMVk0oFgvrFSvWx62llR2hcEInrKNZ2GZCCuuy2lvWrdl5jhbpeqc5hRYKFOcw==} - engines: {node: '>=10'} - dependencies: - xmlchars: 2.2.0 - dev: true - /saxes@6.0.0: resolution: {integrity: sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA==} engines: {node: '>=v12.22.7'} @@ -14732,14 +14610,6 @@ packages: hasBin: true dev: true - /semver@7.3.8: - resolution: {integrity: sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==} - engines: {node: '>=10'} - hasBin: true - dependencies: - lru-cache: 6.0.0 - dev: true - /semver@7.5.4: resolution: {integrity: sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==} engines: {node: '>=10'} @@ -15657,13 +15527,6 @@ packages: punycode: 2.3.0 dev: true - /tr46@3.0.0: - resolution: {integrity: sha512-l7FvfAHlcmulp8kr+flpQZmVwtu7nfRV7NZujtN0OqES8EL4O4e0qqzL0DC5gAvx/ZC/9lk6rhcUwYvkBnBnYA==} - engines: {node: '>=12'} - dependencies: - punycode: 2.3.0 - dev: true - /tr46@4.1.1: resolution: {integrity: sha512-2lv/66T7e5yNyhAAC4NaKe5nVavzuGJQVVtRYLyQ2OI8tsJ61PMLlelehb0wi2Hx6+hT/OJUWZcw8MjlSRnxvw==} engines: {node: '>=14'} @@ -16746,20 +16609,6 @@ packages: vue: 3.3.4 dev: false - /w3c-hr-time@1.0.2: - resolution: {integrity: sha512-z8P5DvDNjKDoFIHK7q8r8lackT6l+jo/Ye3HOle7l9nICP9lf1Ci25fy9vHd0JOWewkIFzXIEig3TdKT7JQ5fQ==} - deprecated: Use your platform's native performance.now() and performance.timeOrigin. - dependencies: - browser-process-hrtime: 1.0.0 - dev: true - - /w3c-xmlserializer@3.0.0: - resolution: {integrity: sha512-3WFqGEgSXIyGhOmAFtlicJNMjEps8b1MG31NCA0/vOF9+nKMUW1ckhi9cnNHmf88Rzw5V+dwIwsm2C7X8k9aQg==} - engines: {node: '>=12'} - dependencies: - xml-name-validator: 4.0.0 - dev: true - /w3c-xmlserializer@4.0.0: resolution: {integrity: sha512-d+BFHzbiCx6zGfz0HyQ6Rg69w9k19nviJspaj4yNscGjrHu94sVP+aRm75yEbCh+r2/yR+7q6hux9LVtbuTGBw==} engines: {node: '>=14'} @@ -16810,16 +16659,16 @@ packages: resolution: {integrity: sha512-PgF341avzqyx60neE9DD+XS26MMNMoUQRz9NOZwW32nPQrF6p77f1htcnjBSEV8BGMKZ16choqUG4hyI0Hx7mA==} dev: false - /webdriver@7.30.0(typescript@5.1.6): - resolution: {integrity: sha512-bQE4oVgjjg5sb3VkCD+Eb8mscEvf3TioP0mnEZK0f5OJUNI045gMCJgpX8X4J8ScGyEhzlhn1KvlAn3yzxjxog==} + /webdriver@7.31.1(typescript@5.1.6): + resolution: {integrity: sha512-nCdJLxRnYvOMFqTEX7sqQtF/hV/Jgov0Y6ICeOm1DMTlZSRRDaUsBMlEAPkEwif9uBJYdM0znv8qzfX358AGqQ==} engines: {node: '>=12.0.0'} dependencies: '@types/node': 18.17.5 - '@wdio/config': 7.30.0(typescript@5.1.6) + '@wdio/config': 7.31.1(typescript@5.1.6) '@wdio/logger': 7.26.0 '@wdio/protocols': 7.27.0 - '@wdio/types': 7.26.0(typescript@5.1.6) - '@wdio/utils': 7.26.0(typescript@5.1.6) + '@wdio/types': 7.30.2(typescript@5.1.6) + '@wdio/utils': 7.30.2(typescript@5.1.6) got: 11.8.6 ky: 0.30.0 lodash.merge: 4.6.2 @@ -17023,22 +16872,6 @@ packages: engines: {node: '>=12'} dev: true - /whatwg-url@10.0.0: - resolution: {integrity: sha512-CLxxCmdUby142H5FZzn4D8ikO1cmypvXVQktsgosNy4a4BHrDHeciBBGZhb0bNoR5/MltoCatso+vFjjGx8t0w==} - engines: {node: '>=12'} - dependencies: - tr46: 3.0.0 - webidl-conversions: 7.0.0 - dev: true - - /whatwg-url@11.0.0: - resolution: {integrity: sha512-RKT8HExMpoYx4igMiVMY83lN6UeITKJlBQ+vR/8ZJ8OCdSiN3RwCq+9gH0+Xzj0+5IrM6i4j/6LuvzbZIQgEcQ==} - engines: {node: '>=12'} - dependencies: - tr46: 3.0.0 - webidl-conversions: 7.0.0 - dev: true - /whatwg-url@12.0.1: resolution: {integrity: sha512-Ed/LrqB8EPlGxjS+TrsXcpUond1mhccS3pchLhzSgPCnTimUCKj3IZE75pAs5m6heB2U2TMerKFUXheyHY+VDQ==} engines: {node: '>=14'} From a01be16d27ffd38e50a2c55f9dfef3f43c18e7da Mon Sep 17 00:00:00 2001 From: Sidharth Vinod Date: Tue, 23 Jan 2024 23:38:21 +0530 Subject: [PATCH 149/217] Echo event --- .github/workflows/e2e.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e.yml index c23dc88baf..a4087cd196 100644 --- a/.github/workflows/e2e.yml +++ b/.github/workflows/e2e.yml @@ -30,7 +30,8 @@ jobs: uses: actions/setup-node@v4 with: node-version: 18.x - + - run: | + echo '${{ toJson(github.event) }}' - name: Cache snapshots id: cache-snapshot uses: actions/cache@v4 From 42ad1f4fe458c8ac79daf1c98bb5b9ae7760316f Mon Sep 17 00:00:00 2001 From: Sidharth Vinod Date: Tue, 23 Jan 2024 23:49:52 +0530 Subject: [PATCH 150/217] RefTest --- .github/workflows/e2e.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e.yml index a4087cd196..3b3b849bc8 100644 --- a/.github/workflows/e2e.yml +++ b/.github/workflows/e2e.yml @@ -18,7 +18,7 @@ permissions: env: # For PRs and MergeQueues, the target commit is used, and for push events, github.event.previous is used. - targetHash: ${{ github.event.pull_request.base.sha || github.event.merge_group.base_sha || github.event.before }} + targetHash: ${{ github.event.pull_request.base.sha || github.event.merge_group.base_sha || (github.event.before == '0000000000000000000000000000000000000000' && 'develop' || github.event.before) }} jobs: cache: @@ -31,6 +31,7 @@ jobs: with: node-version: 18.x - run: | + echo '${{ env.targetHash }}' echo '${{ toJson(github.event) }}' - name: Cache snapshots id: cache-snapshot From de03a017db5895679e2a781781ce58592524b7bf Mon Sep 17 00:00:00 2001 From: Sidharth Vinod Date: Tue, 23 Jan 2024 23:51:48 +0530 Subject: [PATCH 151/217] Remove echo --- .github/workflows/e2e.yml | 3 --- 1 file changed, 3 deletions(-) diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e.yml index 3b3b849bc8..b8232b8c0e 100644 --- a/.github/workflows/e2e.yml +++ b/.github/workflows/e2e.yml @@ -30,9 +30,6 @@ jobs: uses: actions/setup-node@v4 with: node-version: 18.x - - run: | - echo '${{ env.targetHash }}' - echo '${{ toJson(github.event) }}' - name: Cache snapshots id: cache-snapshot uses: actions/cache@v4 From ec79ac200c7714276a374988741dc58375c47f04 Mon Sep 17 00:00:00 2001 From: Sidharth Vinod Date: Tue, 23 Jan 2024 23:53:48 +0530 Subject: [PATCH 152/217] Lint --- packages/mermaid/src/docs/syntax/flowchart.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/packages/mermaid/src/docs/syntax/flowchart.md b/packages/mermaid/src/docs/syntax/flowchart.md index 95cc962c7d..540f820f77 100644 --- a/packages/mermaid/src/docs/syntax/flowchart.md +++ b/packages/mermaid/src/docs/syntax/flowchart.md @@ -775,12 +775,13 @@ flowchart TD B-->E(A fa:fa-camera-retro perhaps?) ``` -Mermaid supports Font Awesome if the CSS is included on the website. -Mermaid does not have any restriction on the version of Font Awesome that can be used. +Mermaid supports Font Awesome if the CSS is included on the website. +Mermaid does not have any restriction on the version of Font Awesome that can be used. Please refer the [Official Font Awesome Documentation](https://fontawesome.com/start) on how to include it in your website. Adding this snippet in the `` would add support for Font Awesome v6.5.1 + ```html Date: Thu, 25 Jan 2024 23:28:42 +0530 Subject: [PATCH 153/217] perf: prevent adding multiple DOMPurify hooks Currently, everytime `removeScript()` is called, the same DOMPurify hooks are getting added again and again. Co-authored-by: Alois Klink --- .../mermaid/src/diagrams/common/common.ts | 33 ++++++++++++++----- 1 file changed, 24 insertions(+), 9 deletions(-) diff --git a/packages/mermaid/src/diagrams/common/common.ts b/packages/mermaid/src/diagrams/common/common.ts index caf43bc682..8609a175ae 100644 --- a/packages/mermaid/src/diagrams/common/common.ts +++ b/packages/mermaid/src/diagrams/common/common.ts @@ -18,13 +18,18 @@ export const getRows = (s?: string): string[] => { return str.split('#br#'); }; -/** - * Removes script tags from a text - * - * @param txt - The text to sanitize - * @returns The safer text - */ -export const removeScript = (txt: string): string => { +const setupDompurifyHooksIfNotSetup = (() => { + let setup = false; + + return () => { + if (!setup) { + setupDompurifyHooks(); + setup = true; + } + }; +})(); + +function setupDompurifyHooks() { const TEMPORARY_ATTRIBUTE = 'data-temp-href-target'; DOMPurify.addHook('beforeSanitizeAttributes', (node: Element) => { @@ -33,8 +38,6 @@ export const removeScript = (txt: string): string => { } }); - const sanitizedText = DOMPurify.sanitize(txt); - DOMPurify.addHook('afterSanitizeAttributes', (node: Element) => { if (node.tagName === 'A' && node.hasAttribute(TEMPORARY_ATTRIBUTE)) { node.setAttribute('target', node.getAttribute(TEMPORARY_ATTRIBUTE) || ''); @@ -44,6 +47,18 @@ export const removeScript = (txt: string): string => { } } }); +} + +/** + * Removes script tags from a text + * + * @param txt - The text to sanitize + * @returns The safer text + */ +export const removeScript = (txt: string): string => { + setupDompurifyHooksIfNotSetup(); + + const sanitizedText = DOMPurify.sanitize(txt); return sanitizedText; }; From f2f8d89a2870ec28b1a84afcfc3ce907816c71d3 Mon Sep 17 00:00:00 2001 From: Ronid1 Date: Thu, 25 Jan 2024 17:16:09 -0800 Subject: [PATCH 154/217] add actor-top class to rectangle actor and man actor --- packages/mermaid/src/diagrams/sequence/svgDraw.js | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/packages/mermaid/src/diagrams/sequence/svgDraw.js b/packages/mermaid/src/diagrams/sequence/svgDraw.js index f81147c10c..953e5b0833 100644 --- a/packages/mermaid/src/diagrams/sequence/svgDraw.js +++ b/packages/mermaid/src/diagrams/sequence/svgDraw.js @@ -356,6 +356,9 @@ const drawActorTypeParticipant = function (elem, actor, conf, isFooter) { } else { rect.fill = '#eaeaea'; } + if (!isFooter) { + cssclass += ' actor-top'; + } rect.x = actor.x; rect.y = actorY; rect.width = actor.width; @@ -420,7 +423,11 @@ const drawActorTypeActor = function (elem, actor, conf, isFooter) { actor.actorCnt = actorCnt; } const actElem = elem.append('g'); - actElem.attr('class', 'actor-man'); + let cssClass = 'actor-man'; + if (!isFooter) { + cssClass += ' actor-top'; + } + actElem.attr('class', cssClass); const rect = svgDrawCommon.getNoteRect(); rect.x = actor.x; From b253cd65d436e40e6fd7f1301a3db2a27112ef5d Mon Sep 17 00:00:00 2001 From: Ronid1 Date: Thu, 25 Jan 2024 13:32:03 -0800 Subject: [PATCH 155/217] update docs --- docs/syntax/sequenceDiagram.md | 5 +++-- packages/mermaid/src/docs/syntax/sequenceDiagram.md | 5 +++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/docs/syntax/sequenceDiagram.md b/docs/syntax/sequenceDiagram.md index 6e419fbc5c..7557fef671 100644 --- a/docs/syntax/sequenceDiagram.md +++ b/docs/syntax/sequenceDiagram.md @@ -742,8 +742,9 @@ Styling of a sequence diagram is done by defining a number of css classes. Durin | Class | Description | | ------------ | ----------------------------------------------------------- | -| actor | Style for the actor box at the top of the diagram. | -| text.actor | Styles for text in the actor box at the top of the diagram. | +| actor | Styles for the actor box. | +| actor-top | Styles for the actor figure/ box at the top of the diagram. | +| text.actor | Styles for text in the actor box. | | actor-line | The vertical line for an actor. | | messageLine0 | Styles for the solid message line. | | messageLine1 | Styles for the dotted message line. | diff --git a/packages/mermaid/src/docs/syntax/sequenceDiagram.md b/packages/mermaid/src/docs/syntax/sequenceDiagram.md index 5e4731eede..ed36906204 100644 --- a/packages/mermaid/src/docs/syntax/sequenceDiagram.md +++ b/packages/mermaid/src/docs/syntax/sequenceDiagram.md @@ -520,8 +520,9 @@ Styling of a sequence diagram is done by defining a number of css classes. Durin | Class | Description | | ------------ | ----------------------------------------------------------- | -| actor | Style for the actor box at the top of the diagram. | -| text.actor | Styles for text in the actor box at the top of the diagram. | +| actor | Styles for the actor box. | +| actor-top | Styles for the actor figure/ box at the top of the diagram. | +| text.actor | Styles for text in the actor box. | | actor-line | The vertical line for an actor. | | messageLine0 | Styles for the solid message line. | | messageLine1 | Styles for the dotted message line. | From 70d9f50fc9fc3fc5d8e65f3be8812851799b7cf7 Mon Sep 17 00:00:00 2001 From: Ronid1 Date: Thu, 25 Jan 2024 17:59:46 -0800 Subject: [PATCH 156/217] add const for class name --- packages/mermaid/src/diagrams/sequence/svgDraw.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/packages/mermaid/src/diagrams/sequence/svgDraw.js b/packages/mermaid/src/diagrams/sequence/svgDraw.js index 953e5b0833..c319501607 100644 --- a/packages/mermaid/src/diagrams/sequence/svgDraw.js +++ b/packages/mermaid/src/diagrams/sequence/svgDraw.js @@ -5,6 +5,7 @@ import { ZERO_WIDTH_SPACE, parseFontSize } from '../../utils.js'; import { sanitizeUrl } from '@braintree/sanitize-url'; export const ACTOR_TYPE_WIDTH = 18 * 2; +const TOP_ACTOR_CLASS = 'actor-top'; export const drawRect = function (elem, rectData) { return svgDrawCommon.drawRect(elem, rectData); @@ -357,7 +358,7 @@ const drawActorTypeParticipant = function (elem, actor, conf, isFooter) { rect.fill = '#eaeaea'; } if (!isFooter) { - cssclass += ' actor-top'; + cssclass += ` ${TOP_ACTOR_CLASS}`; } rect.x = actor.x; rect.y = actorY; @@ -425,7 +426,7 @@ const drawActorTypeActor = function (elem, actor, conf, isFooter) { const actElem = elem.append('g'); let cssClass = 'actor-man'; if (!isFooter) { - cssClass += ' actor-top'; + cssClass += ` ${TOP_ACTOR_CLASS}`; } actElem.attr('class', cssClass); From 59264a33d7306441193cd6c68ceb4ff4ab3d7fd1 Mon Sep 17 00:00:00 2001 From: FutzMonitor Date: Fri, 26 Jan 2024 11:48:48 -0500 Subject: [PATCH 157/217] Changes to gantt.html 1. Added a Gantt diagram that demonstrates to users that hashtages and semicolons can be added to titles, sections, and task data. Changes to gantt.spec.js 1. Added unit tests to ensure that semicolons and hashtags didn't break the functionality of the gantt diagram when used in titles, sections or task data. Changes to /parser/gantt.spec.js 1. Added rendering tests to ensure that semicolons and hashtags in titles, sections, and task data didn't break the rendering of Gantt diagrams. --- cypress/integration/rendering/gantt.spec.js | 102 ++++++++++++++++++ demos/gantt.html | 15 +++ .../src/diagrams/gantt/parser/gantt.spec.js | 36 +++++++ 3 files changed, 153 insertions(+) diff --git a/cypress/integration/rendering/gantt.spec.js b/cypress/integration/rendering/gantt.spec.js index 73ff4ee005..4abde9d446 100644 --- a/cypress/integration/rendering/gantt.spec.js +++ b/cypress/integration/rendering/gantt.spec.js @@ -583,4 +583,106 @@ describe('Gantt diagram', () => { {} ); }); + + it("should render when there's a semicolon in the title", () => { + imgSnapshotTest( + ` + gantt + title ;Gantt With a Semicolon in the Title + dateFormat YYYY-MM-DD + section Section + A task :a1, 2014-01-01, 30d + Another task :after a1 , 20d + section Another + Task in sec :2014-01-12 , 12d + another task : 24d + `, + {} + ); + }); + + it("should render when there's a semicolon in a section is true", () => { + imgSnapshotTest( + ` + gantt + title Gantt Digram + dateFormat YYYY-MM-DD + section ;Section With a Semicolon + A task :a1, 2014-01-01, 30d + Another task :after a1 , 20d + section Another + Task in sec :2014-01-12 , 12d + another task : 24d + `, + {} + ); + }); + + it("should render when there's a semicolon in the task data", () => { + imgSnapshotTest( + ` + gantt + title Gantt Digram + dateFormat YYYY-MM-DD + section Section + ;A task with a semiclon :a1, 2014-01-01, 30d + Another task :after a1 , 20d + section Another + Task in sec :2014-01-12 , 12d + another task : 24d + `, + {} + ); + }); + + it("should render when there's a hashtag in the title", () => { + imgSnapshotTest( + ` + gantt + title #Gantt With a Hashtag in the Title + dateFormat YYYY-MM-DD + section Section + A task :a1, 2014-01-01, 30d + Another task :after a1 , 20d + section Another + Task in sec :2014-01-12 , 12d + another task : 24d + `, + {} + ); + }); + + it("should render when there's a hashtag in a section is true", () => { + imgSnapshotTest( + ` + gantt + title Gantt Digram + dateFormat YYYY-MM-DD + section #Section With a Hashtag + A task :a1, 2014-01-01, 30d + Another task :after a1 , 20d + section Another + Task in sec :2014-01-12 , 12d + another task : 24d + `, + {} + ); + }); + + it("should render when there's a hashtag in the task data", () => { + imgSnapshotTest( + ` + gantt + title Gantt Digram + dateFormat YYYY-MM-DD + section Section + #A task with a hashtag :a1, 2014-01-01, 30d + Another task :after a1 , 20d + section Another + Task in sec :2014-01-12 , 12d + another task : 24d + `, + {} + ); + }); }); diff --git a/demos/gantt.html b/demos/gantt.html index 88f52ef5c9..9c82371abe 100644 --- a/demos/gantt.html +++ b/demos/gantt.html @@ -30,6 +30,21 @@

    Gantt chart diagram demos


    +
    +      gantt
    +        title #; Gantt Diagrams Allow Semicolons and Hashtags #;!
    +        accTitle: A simple sample gantt diagram
    +        accDescr: 2 sections with 2 tasks each, from 2014
    +        dateFormat  YYYY-MM-DD
    +        section #;Section
    +        #;A task           :a1, 2014-01-01, 30d
    +        #;Another task     :after a1  , 20d
    +        section #;Another
    +        Task in sec      :2014-01-12  , 12d
    +        another task      : 24d
    +    
    +
    +
         gantt
           title Airworks roadmap
    diff --git a/packages/mermaid/src/diagrams/gantt/parser/gantt.spec.js b/packages/mermaid/src/diagrams/gantt/parser/gantt.spec.js
    index e7ce1ffa4f..ae5f74249c 100644
    --- a/packages/mermaid/src/diagrams/gantt/parser/gantt.spec.js
    +++ b/packages/mermaid/src/diagrams/gantt/parser/gantt.spec.js
    @@ -28,8 +28,12 @@ describe('when parsing a gantt diagram it', function () {
       });
       it('should handle a title definition', function () {
         const str = 'gantt\ndateFormat yyyy-mm-dd\ntitle Adding gantt diagram functionality to mermaid';
    +    const semi = 'gantt\ndateFormat yyyy-mm-dd\ntitle ;Gantt diagram titles support semicolons';
    +    const hash = 'gantt\ndateFormat yyyy-mm-dd\ntitle #Gantt diagram titles support hashtags';
     
         expect(parserFnConstructor(str)).not.toThrow();
    +    expect(parserFnConstructor(semi)).not.toThrow();
    +    expect(parserFnConstructor(hash)).not.toThrow();
       });
       it('should handle an excludes definition', function () {
         const str =
    @@ -53,7 +57,23 @@ describe('when parsing a gantt diagram it', function () {
           'excludes weekdays 2019-02-01\n' +
           'section Documentation';
     
    +    const semi =
    +      'gantt\n' +
    +      'dateFormat yyyy-mm-dd\n' +
    +      'title Adding gantt diagram functionality to mermaid\n' +
    +      'excludes weekdays 2019-02-01\n' +
    +      'section ;Documentation';
    +
    +    const hash =
    +      'gantt\n' +
    +      'dateFormat yyyy-mm-dd\n' +
    +      'title Adding gantt diagram functionality to mermaid\n' +
    +      'excludes weekdays 2019-02-01\n' +
    +      'section #Documentation';
    +
         expect(parserFnConstructor(str)).not.toThrow();
    +    expect(parserFnConstructor(semi)).not.toThrow();
    +    expect(parserFnConstructor(hash)).not.toThrow();
       });
       it('should handle multiline section titles with different line breaks', function () {
         const str =
    @@ -73,7 +93,23 @@ describe('when parsing a gantt diagram it', function () {
           'section Documentation\n' +
           'Design jison grammar:des1, 2014-01-01, 2014-01-04';
     
    +    const semi =
    +      'gantt\n' +
    +      'dateFormat YYYY-MM-DD\n' +
    +      'title Adding gantt diagram functionality to mermaid\n' +
    +      'section Documentation\n' +
    +      ';Design jison grammar:des1, 2014-01-01, 2014-01-04';
    +
    +    const hash =
    +      'gantt\n' +
    +      'dateFormat YYYY-MM-DD\n' +
    +      'title Adding gantt diagram functionality to mermaid\n' +
    +      'section Documentation\n' +
    +      '#Design jison grammar:des1, 2014-01-01, 2014-01-04';
    +
         expect(parserFnConstructor(str)).not.toThrow();
    +    expect(parserFnConstructor(semi)).not.toThrow();
    +    expect(parserFnConstructor(hash)).not.toThrow();
     
         const tasks = parser.yy.getTasks();
     
    
    From 8619a53a9cab35fd552d1663d33e327c70b28889 Mon Sep 17 00:00:00 2001
    From: Sidharth Vinod 
    Date: Fri, 26 Jan 2024 22:48:12 +0530
    Subject: [PATCH 158/217] Update demos/pie.html
    
    ---
     demos/pie.html | 2 +-
     1 file changed, 1 insertion(+), 1 deletion(-)
    
    diff --git a/demos/pie.html b/demos/pie.html
    index 76b8fdf0f9..823f61716c 100644
    --- a/demos/pie.html
    +++ b/demos/pie.html
    @@ -27,7 +27,7 @@ 

    Pie chart demos

           %%{init: {"pie": {"textPosition": 0.9}, "themeVariables": {"pieOuterStrokeWidth": "5px"}}}%%
           pie
    -        title Offset labels close to border: Produxt X
    +        title Offset labels close to border: Product X
             accTitle: Key elements in Product X
             accDescr: This is a pie chart showing the key elements in Product X.
             "Calcium": 42.96
    
    From 6bf5571f962f07404adeb09d0bf68887e32b80ca Mon Sep 17 00:00:00 2001
    From: Sidharth Vinod 
    Date: Fri, 26 Jan 2024 22:50:17 +0530
    Subject: [PATCH 159/217] chore: Update docs
    
    ---
     docs/syntax/timeline.md | 8 ++++----
     1 file changed, 4 insertions(+), 4 deletions(-)
    
    diff --git a/docs/syntax/timeline.md b/docs/syntax/timeline.md
    index 610ad98c7c..3e984eac61 100644
    --- a/docs/syntax/timeline.md
    +++ b/docs/syntax/timeline.md
    @@ -163,11 +163,11 @@ timeline
     timeline
             title MermaidChart 2023 Timeline
             section 2023 Q1 
    Release Personal Tier - Buttet 1 : sub-point 1a : sub-point 1b + Bullet 1 : sub-point 1a : sub-point 1b : sub-point 1c Bullet 2 : sub-point 2a : sub-point 2b section 2023 Q2
    Release XYZ Tier - Buttet 3 : sub-point
    3a : sub-point 3b + Bullet 3 : sub-point
    3a : sub-point 3b : sub-point 3c Bullet 4 : sub-point 4a : sub-point 4b ``` @@ -176,11 +176,11 @@ timeline timeline title MermaidChart 2023 Timeline section 2023 Q1
    Release Personal Tier - Buttet 1 : sub-point 1a : sub-point 1b + Bullet 1 : sub-point 1a : sub-point 1b : sub-point 1c Bullet 2 : sub-point 2a : sub-point 2b section 2023 Q2
    Release XYZ Tier - Buttet 3 : sub-point
    3a : sub-point 3b + Bullet 3 : sub-point
    3a : sub-point 3b : sub-point 3c Bullet 4 : sub-point 4a : sub-point 4b ``` From 36c196e80b2cf386ba5a560de30848b7cbc0f104 Mon Sep 17 00:00:00 2001 From: Ronid1 Date: Fri, 26 Jan 2024 14:07:12 -0800 Subject: [PATCH 160/217] add test --- .../integration/rendering/sequencediagram.spec.js | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/cypress/integration/rendering/sequencediagram.spec.js b/cypress/integration/rendering/sequencediagram.spec.js index 27e03da9c0..d5f352b3a1 100644 --- a/cypress/integration/rendering/sequencediagram.spec.js +++ b/cypress/integration/rendering/sequencediagram.spec.js @@ -375,6 +375,19 @@ context('Sequence diagram', () => { {} ); }); + it('should have actor-top class on top actor box and symbol', () => { + imgSnapshotTest( + ` + sequenceDiagram + actor Bob + Alice->>Bob: Hi Bob + Bob->>Alice: Hi Alice + `, + {} + ); + cy.get('.actor').should('have.class', 'actor-top'); + cy.get('.actor-man').should('have.class', 'actor-top'); + }); it('should render long notes left of actor', () => { imgSnapshotTest( ` From 12dc3d8373259f2caaacb7cea7c300c2c7ee8599 Mon Sep 17 00:00:00 2001 From: Sidharth Vinod Date: Sun, 28 Jan 2024 15:52:37 +0530 Subject: [PATCH 161/217] Rename files to TS --- .../src/diagrams/mindmap/{mindmap.spec.js => mindmap.spec.ts} | 0 .../mermaid/src/diagrams/mindmap/{mindmapDb.js => mindmapDb.ts} | 0 .../diagrams/mindmap/{mindmapRenderer.js => mindmapRenderer.ts} | 0 3 files changed, 0 insertions(+), 0 deletions(-) rename packages/mermaid/src/diagrams/mindmap/{mindmap.spec.js => mindmap.spec.ts} (100%) rename packages/mermaid/src/diagrams/mindmap/{mindmapDb.js => mindmapDb.ts} (100%) rename packages/mermaid/src/diagrams/mindmap/{mindmapRenderer.js => mindmapRenderer.ts} (100%) diff --git a/packages/mermaid/src/diagrams/mindmap/mindmap.spec.js b/packages/mermaid/src/diagrams/mindmap/mindmap.spec.ts similarity index 100% rename from packages/mermaid/src/diagrams/mindmap/mindmap.spec.js rename to packages/mermaid/src/diagrams/mindmap/mindmap.spec.ts diff --git a/packages/mermaid/src/diagrams/mindmap/mindmapDb.js b/packages/mermaid/src/diagrams/mindmap/mindmapDb.ts similarity index 100% rename from packages/mermaid/src/diagrams/mindmap/mindmapDb.js rename to packages/mermaid/src/diagrams/mindmap/mindmapDb.ts diff --git a/packages/mermaid/src/diagrams/mindmap/mindmapRenderer.js b/packages/mermaid/src/diagrams/mindmap/mindmapRenderer.ts similarity index 100% rename from packages/mermaid/src/diagrams/mindmap/mindmapRenderer.js rename to packages/mermaid/src/diagrams/mindmap/mindmapRenderer.ts From e046da10c2913938435c05370bc4729e69184726 Mon Sep 17 00:00:00 2001 From: Sidharth Vinod Date: Sun, 28 Jan 2024 15:55:22 +0530 Subject: [PATCH 162/217] Convert mindmap.spec.js --- .../src/diagrams/mindmap/mindmap.spec.ts | 78 ++++++++----------- 1 file changed, 33 insertions(+), 45 deletions(-) diff --git a/packages/mermaid/src/diagrams/mindmap/mindmap.spec.ts b/packages/mermaid/src/diagrams/mindmap/mindmap.spec.ts index c0b72060d9..f6cc4304f8 100644 --- a/packages/mermaid/src/diagrams/mindmap/mindmap.spec.ts +++ b/packages/mermaid/src/diagrams/mindmap/mindmap.spec.ts @@ -1,3 +1,4 @@ +// @ts-expect-error No types available for JISON import { parser as mindmap } from './parser/mindmap.jison'; import * as mindmapDB from './mindmapDb.js'; // Todo fix utils functions for tests @@ -11,7 +12,7 @@ describe('when parsing a mindmap ', function () { }); describe('hiearchy', function () { it('MMP-1 should handle a simple root definition abc122', function () { - let str = `mindmap + const str = `mindmap root`; mindmap.parse(str); @@ -19,7 +20,7 @@ describe('when parsing a mindmap ', function () { expect(mindmap.yy.getMindmap().descr).toEqual('root'); }); it('MMP-2 should handle a hierachial mindmap definition', function () { - let str = `mindmap + const str = `mindmap root child1 child2 @@ -34,7 +35,7 @@ describe('when parsing a mindmap ', function () { }); it('3 should handle a simple root definition with a shape and without an id abc123', function () { - let str = `mindmap + const str = `mindmap (root)`; mindmap.parse(str); @@ -43,7 +44,7 @@ describe('when parsing a mindmap ', function () { }); it('MMP-4 should handle a deeper hierachial mindmap definition', function () { - let str = `mindmap + const str = `mindmap root child1 leaf1 @@ -58,40 +59,27 @@ describe('when parsing a mindmap ', function () { expect(mm.children[1].descr).toEqual('child2'); }); it('5 Multiple roots are illegal', function () { - let str = `mindmap + const str = `mindmap root fakeRoot`; - try { - mindmap.parse(str); - // Fail test if above expression doesn't throw anything. - expect(true).toBe(false); - } catch (e) { - expect(e.message).toBe( - 'There can be only one root. No parent could be found for ("fakeRoot")' - ); - } + expect(() => mindmap.parse(str)).toThrow( + 'There can be only one root. No parent could be found for ("fakeRoot")' + ); }); it('MMP-6 real root in wrong place', function () { - let str = `mindmap + const str = `mindmap root fakeRoot realRootWrongPlace`; - - try { - mindmap.parse(str); - // Fail test if above expression doesn't throw anything. - expect(true).toBe(false); - } catch (e) { - expect(e.message).toBe( - 'There can be only one root. No parent could be found for ("fakeRoot")' - ); - } + expect(() => mindmap.parse(str)).toThrow( + 'There can be only one root. No parent could be found for ("fakeRoot")' + ); }); }); describe('nodes', function () { it('MMP-7 should handle an id and type for a node definition', function () { - let str = `mindmap + const str = `mindmap root[The root] `; @@ -102,7 +90,7 @@ describe('when parsing a mindmap ', function () { expect(mm.type).toEqual(mindmap.yy.nodeType.RECT); }); it('MMP-8 should handle an id and type for a node definition', function () { - let str = `mindmap + const str = `mindmap root theId(child1)`; @@ -116,7 +104,7 @@ describe('when parsing a mindmap ', function () { expect(child.type).toEqual(mindmap.yy.nodeType.ROUNDED_RECT); }); it('MMP-9 should handle an id and type for a node definition', function () { - let str = `mindmap + const str = `mindmap root theId(child1)`; @@ -130,7 +118,7 @@ root expect(child.type).toEqual(mindmap.yy.nodeType.ROUNDED_RECT); }); it('MMP-10 multiple types (circle)', function () { - let str = `mindmap + const str = `mindmap root((the root)) `; @@ -142,7 +130,7 @@ root }); it('MMP-11 multiple types (cloud)', function () { - let str = `mindmap + const str = `mindmap root)the root( `; @@ -153,7 +141,7 @@ root expect(mm.type).toEqual(mindmap.yy.nodeType.CLOUD); }); it('MMP-12 multiple types (bang)', function () { - let str = `mindmap + const str = `mindmap root))the root(( `; @@ -165,7 +153,7 @@ root }); it('MMP-12-a multiple types (hexagon)', function () { - let str = `mindmap + const str = `mindmap root{{the root}} `; @@ -178,7 +166,7 @@ root }); describe('decorations', function () { it('MMP-13 should be possible to set an icon for the node', function () { - let str = `mindmap + const str = `mindmap root[The root] ::icon(bomb) `; @@ -192,7 +180,7 @@ root expect(mm.icon).toEqual('bomb'); }); it('MMP-14 should be possible to set classes for the node', function () { - let str = `mindmap + const str = `mindmap root[The root] :::m-4 p-8 `; @@ -206,7 +194,7 @@ root expect(mm.class).toEqual('m-4 p-8'); }); it('MMP-15 should be possible to set both classes and icon for the node', function () { - let str = `mindmap + const str = `mindmap root[The root] :::m-4 p-8 ::icon(bomb) @@ -222,7 +210,7 @@ root expect(mm.icon).toEqual('bomb'); }); it('MMP-16 should be possible to set both classes and icon for the node', function () { - let str = `mindmap + const str = `mindmap root[The root] ::icon(bomb) :::m-4 p-8 @@ -240,7 +228,7 @@ root }); describe('descriptions', function () { it('MMP-17 should be possible to use node syntax in the descriptions', function () { - let str = `mindmap + const str = `mindmap root["String containing []"] `; mindmap.parse(str); @@ -249,7 +237,7 @@ root expect(mm.descr).toEqual('String containing []'); }); it('MMP-18 should be possible to use node syntax in the descriptions in children', function () { - let str = `mindmap + const str = `mindmap root["String containing []"] child1["String containing ()"] `; @@ -261,7 +249,7 @@ root expect(mm.children[0].descr).toEqual('String containing ()'); }); it('MMP-19 should be possible to have a child after a class assignment', function () { - let str = `mindmap + const str = `mindmap root(Root) Child(Child) :::hot @@ -281,7 +269,7 @@ root }); }); it('MMP-20 should be possible to have meaningless empty rows in a mindmap abc124', function () { - let str = `mindmap + const str = `mindmap root(Root) Child(Child) a(a) @@ -300,7 +288,7 @@ root expect(child.children[1].nodeId).toEqual('b'); }); it('MMP-21 should be possible to have comments in a mindmap', function () { - let str = `mindmap + const str = `mindmap root(Root) Child(Child) a(a) @@ -321,7 +309,7 @@ root }); it('MMP-22 should be possible to have comments at the end of a line', function () { - let str = `mindmap + const str = `mindmap root(Root) Child(Child) a(a) %% This is a comment @@ -339,7 +327,7 @@ root expect(child.children[1].nodeId).toEqual('b'); }); it('MMP-23 Rows with only spaces should not interfere', function () { - let str = 'mindmap\nroot\n A\n \n\n B'; + const str = 'mindmap\nroot\n A\n \n\n B'; mindmap.parse(str); const mm = mindmap.yy.getMindmap(); expect(mm.nodeId).toEqual('root'); @@ -351,7 +339,7 @@ root expect(child2.nodeId).toEqual('B'); }); it('MMP-24 Handle rows above the mindmap declarations', function () { - let str = '\n \nmindmap\nroot\n A\n \n\n B'; + const str = '\n \nmindmap\nroot\n A\n \n\n B'; mindmap.parse(str); const mm = mindmap.yy.getMindmap(); expect(mm.nodeId).toEqual('root'); @@ -363,7 +351,7 @@ root expect(child2.nodeId).toEqual('B'); }); it('MMP-25 Handle rows above the mindmap declarations, no space', function () { - let str = '\n\n\nmindmap\nroot\n A\n \n\n B'; + const str = '\n\n\nmindmap\nroot\n A\n \n\n B'; mindmap.parse(str); const mm = mindmap.yy.getMindmap(); expect(mm.nodeId).toEqual('root'); From b71f4c7e5446b0512a56455f695349779e9123f3 Mon Sep 17 00:00:00 2001 From: Sidharth Vinod Date: Sun, 28 Jan 2024 15:56:30 +0530 Subject: [PATCH 163/217] Add MindmapDB type --- packages/mermaid/src/diagrams/mindmap/mindmap-definition.ts | 3 ++- packages/mermaid/src/diagrams/mindmap/mindmapTypes.ts | 3 +++ 2 files changed, 5 insertions(+), 1 deletion(-) create mode 100644 packages/mermaid/src/diagrams/mindmap/mindmapTypes.ts diff --git a/packages/mermaid/src/diagrams/mindmap/mindmap-definition.ts b/packages/mermaid/src/diagrams/mindmap/mindmap-definition.ts index b352144359..c5c7303c30 100644 --- a/packages/mermaid/src/diagrams/mindmap/mindmap-definition.ts +++ b/packages/mermaid/src/diagrams/mindmap/mindmap-definition.ts @@ -3,8 +3,9 @@ import mindmapParser from './parser/mindmap.jison'; import * as mindmapDb from './mindmapDb.js'; import mindmapRenderer from './mindmapRenderer.js'; import mindmapStyles from './styles.js'; +import type { DiagramDefinition } from '../../diagram-api/types.js'; -export const diagram = { +export const diagram: DiagramDefinition = { db: mindmapDb, renderer: mindmapRenderer, parser: mindmapParser, diff --git a/packages/mermaid/src/diagrams/mindmap/mindmapTypes.ts b/packages/mermaid/src/diagrams/mindmap/mindmapTypes.ts new file mode 100644 index 0000000000..caec37d2c0 --- /dev/null +++ b/packages/mermaid/src/diagrams/mindmap/mindmapTypes.ts @@ -0,0 +1,3 @@ +import type * as mindmapDb from './mindmapDb.js'; + +export type MindmapDB = typeof mindmapDb; From f30c26485e02cbd697e2c8ac21967a57cece768d Mon Sep 17 00:00:00 2001 From: Sidharth Vinod Date: Sun, 28 Jan 2024 15:58:07 +0530 Subject: [PATCH 164/217] Cleanup svgDraw.js --- .../mermaid/src/diagrams/mindmap/svgDraw.js | 51 ------------------- 1 file changed, 51 deletions(-) diff --git a/packages/mermaid/src/diagrams/mindmap/svgDraw.js b/packages/mermaid/src/diagrams/mindmap/svgDraw.js index 2a4fc4b671..b065e8010f 100644 --- a/packages/mermaid/src/diagrams/mindmap/svgDraw.js +++ b/packages/mermaid/src/diagrams/mindmap/svgDraw.js @@ -1,54 +1,7 @@ -import { select } from 'd3'; import * as db from './mindmapDb.js'; import { createText } from '../../rendering-util/createText.js'; const MAX_SECTIONS = 12; -/** - * @param {string} text The text to be wrapped - * @param {number} width The max width of the text - */ -function wrap(text, width) { - text.each(function () { - var text = select(this), - words = text - .text() - .split(/(\s+|)/) - .reverse(), - word, - line = [], - lineHeight = 1.1, // ems - y = text.attr('y'), - dy = parseFloat(text.attr('dy')), - tspan = text - .text(null) - .append('tspan') - .attr('x', 0) - .attr('y', y) - .attr('dy', dy + 'em'); - for (let j = 0; j < words.length; j++) { - word = words[words.length - 1 - j]; - line.push(word); - tspan.text(line.join(' ').trim()); - if (tspan.node().getComputedTextLength() > width || word === '
    ') { - line.pop(); - tspan.text(line.join(' ').trim()); - if (word === '
    ') { - line = ['']; - } else { - line = [word]; - } - - tspan = text - .append('tspan') - .attr('x', 0) - .attr('y', y) - .attr('dy', lineHeight + 'em') - .text(word); - } - } - }); -} - const defaultBkg = function (elem, node, section) { const rd = 5; elem @@ -317,10 +270,6 @@ export const drawNode = function (elem, node, fullSection, conf) { break; } - // Position the node to its coordinate - // if (typeof node.x !== 'undefined' && typeof node.y !== 'undefined') { - // nodeElem.attr('transform', 'translate(' + node.x + ',' + node.y + ')'); - // } db.setElementForId(node.id, nodeElem); return node.height; }; From ba0bddf4178e1d48de5cc3c73ac52db5a23f05e8 Mon Sep 17 00:00:00 2001 From: Sidharth Vinod Date: Sun, 28 Jan 2024 16:02:28 +0530 Subject: [PATCH 165/217] Add MermaidConfigWithDefaults --- packages/mermaid/src/config.ts | 4 ++-- packages/mermaid/src/config.type.ts | 5 +++++ packages/mermaid/src/diagrams/sankey/sankeyRenderer.ts | 1 - 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/packages/mermaid/src/config.ts b/packages/mermaid/src/config.ts index ede3a568df..f1dccd251d 100644 --- a/packages/mermaid/src/config.ts +++ b/packages/mermaid/src/config.ts @@ -2,7 +2,7 @@ import assignWithDepth from './assignWithDepth.js'; import { log } from './logger.js'; import theme from './themes/index.js'; import config from './defaultConfig.js'; -import type { MermaidConfig } from './config.type.js'; +import type { MermaidConfig, MermaidConfigWithDefaults } from './config.type.js'; import { sanitizeDirective } from './utils/sanitizeDirective.js'; export const defaultConfig: MermaidConfig = Object.freeze(config); @@ -128,7 +128,7 @@ export const setConfig = (conf: MermaidConfig): MermaidConfig => { * * @returns The currentConfig */ -export const getConfig = (): MermaidConfig => { +export const getConfig = (): MermaidConfigWithDefaults => { return assignWithDepth({}, currentConfig); }; /** diff --git a/packages/mermaid/src/config.type.ts b/packages/mermaid/src/config.type.ts index 575f428ddd..7ca4b89d67 100644 --- a/packages/mermaid/src/config.type.ts +++ b/packages/mermaid/src/config.type.ts @@ -5,6 +5,8 @@ * and run json-schema-to-typescript to regenerate this file. */ +import { RequiredDeep } from 'type-fest'; + /** * Configuration options to pass to the `dompurify` library. */ @@ -165,6 +167,9 @@ export interface MermaidConfig { wrap?: boolean; fontSize?: number; } + +// I'd prefer this to be named MermaidConfig, so all the functions can use the shorter name. +export type MermaidConfigWithDefaults = RequiredDeep; /** * This interface was referenced by `MermaidConfig`'s JSON-Schema * via the `definition` "BaseDiagramConfig". diff --git a/packages/mermaid/src/diagrams/sankey/sankeyRenderer.ts b/packages/mermaid/src/diagrams/sankey/sankeyRenderer.ts index 7433f2b9ce..51f808ff44 100644 --- a/packages/mermaid/src/diagrams/sankey/sankeyRenderer.ts +++ b/packages/mermaid/src/diagrams/sankey/sankeyRenderer.ts @@ -1,6 +1,5 @@ import type { Diagram } from '../../Diagram.js'; import { getConfig, defaultConfig } from '../../diagram-api/diagramAPI.js'; - import { select as d3select, scaleOrdinal as d3scaleOrdinal, From f069de54878637762a99bb4e787220e287e23940 Mon Sep 17 00:00:00 2001 From: Sidharth Vinod Date: Sun, 28 Jan 2024 16:03:20 +0530 Subject: [PATCH 166/217] Convert MindmapDB.ts --- .../mermaid/src/diagrams/mindmap/mindmapDb.ts | 99 ++++++++++--------- 1 file changed, 52 insertions(+), 47 deletions(-) diff --git a/packages/mermaid/src/diagrams/mindmap/mindmapDb.ts b/packages/mermaid/src/diagrams/mindmap/mindmapDb.ts index 4206a4a260..72c9968b62 100644 --- a/packages/mermaid/src/diagrams/mindmap/mindmapDb.ts +++ b/packages/mermaid/src/diagrams/mindmap/mindmapDb.ts @@ -1,19 +1,36 @@ import { getConfig } from '../../diagram-api/diagramAPI.js'; -import { sanitizeText as _sanitizeText } from '../../diagrams/common/common.js'; +import { sanitizeText } from '../../diagrams/common/common.js'; import { log } from '../../logger.js'; +import type { D3Element } from '../../mermaidAPI.js'; -export const sanitizeText = (text) => _sanitizeText(text, getConfig()); +export interface MindMapNode { + id: number; + nodeId: string; + level: number; + descr: string; + type: number; + children: MindMapNode[]; + width: number; + padding: number; + section?: number; + height?: number; + class?: string; + icon?: string; + x?: number; + y?: number; +} -let nodes = []; +let nodes: MindMapNode[] = []; let cnt = 0; -let elements = {}; +let elements: Record = {}; + export const clear = () => { nodes = []; cnt = 0; elements = {}; }; -const getParent = function (level) { +const getParent = function (level: number) { for (let i = nodes.length - 1; i >= 0; i--) { if (nodes[i].level < level) { return nodes[i]; @@ -26,31 +43,29 @@ const getParent = function (level) { export const getMindmap = () => { return nodes.length > 0 ? nodes[0] : null; }; -export const addNode = (level, id, descr, type) => { + +export const addNode = (level: number, id: string, descr: string, type: number) => { log.info('addNode', level, id, descr, type); const conf = getConfig(); + let padding: number = conf.mindmap?.padding ?? 10; + switch (type) { + case nodeType.ROUNDED_RECT: + case nodeType.RECT: + case nodeType.HEXAGON: + padding *= 2; + } + const node = { id: cnt++, - nodeId: sanitizeText(id), + nodeId: sanitizeText(id, conf), level, - descr: sanitizeText(descr), + descr: sanitizeText(descr, conf), type, children: [], - width: getConfig().mindmap.maxNodeWidth, - }; - switch (node.type) { - case nodeType.ROUNDED_RECT: - node.padding = 2 * conf.mindmap.padding; - break; - case nodeType.RECT: - node.padding = 2 * conf.mindmap.padding; - break; - case nodeType.HEXAGON: - node.padding = 2 * conf.mindmap.padding; - break; - default: - node.padding = conf.mindmap.padding; - } + width: conf.mindmap?.maxNodeWidth ?? 200, + padding, + } satisfies MindMapNode; + const parent = getParent(level); if (parent) { parent.children.push(node); @@ -62,16 +77,9 @@ export const addNode = (level, id, descr, type) => { nodes.push(node); } else { // Syntax error ... there can only bee one root - let error = new Error( + const error = new Error( 'There can be only one root. No parent could be found for ("' + node.descr + '")' ); - error.hash = { - text: 'branch ' + name, - token: 'branch ' + name, - line: '1', - loc: { first_line: 1, last_line: 1, first_column: 1, last_column: 1 }, - expected: ['"checkout ' + name + '"'], - }; throw error; } } @@ -88,7 +96,7 @@ export const nodeType = { HEXAGON: 6, }; -export const getType = (startStr, endStr) => { +export const getType = (startStr: string, endStr: string): number => { log.debug('In get type', startStr, endStr); switch (startStr) { case '[': @@ -108,21 +116,25 @@ export const getType = (startStr, endStr) => { } }; -export const setElementForId = (id, element) => { +export const setElementForId = (id: string, element: D3Element) => { elements[id] = element; }; -export const decorateNode = (decoration) => { +export const decorateNode = (decoration?: { class?: string; icon?: string }) => { + if (!decoration) { + return; + } + const config = getConfig(); const node = nodes[nodes.length - 1]; - if (decoration && decoration.icon) { - node.icon = sanitizeText(decoration.icon); + if (decoration.icon) { + node.icon = sanitizeText(decoration.icon, config); } - if (decoration && decoration.class) { - node.class = sanitizeText(decoration.class); + if (decoration.class) { + node.class = sanitizeText(decoration.class, config); } }; -export const type2Str = (type) => { +export const type2Str = (type: number) => { switch (type) { case nodeType.DEFAULT: return 'no-border'; @@ -143,13 +155,6 @@ export const type2Str = (type) => { } }; -export let parseError; -export const setErrorHandler = (handler) => { - parseError = handler; -}; - // Expose logger to grammar export const getLogger = () => log; - -export const getNodeById = (id) => nodes[id]; -export const getElementById = (id) => elements[id]; +export const getElementById = (id: string) => elements[id]; From d346a77e3c72e36a441bf271700744a0e381bedf Mon Sep 17 00:00:00 2001 From: Sidharth Vinod Date: Sun, 28 Jan 2024 16:03:37 +0530 Subject: [PATCH 167/217] Convert MindmapRenderer.ts --- .../src/diagrams/mindmap/mindmapRenderer.ts | 104 ++++++++---------- 1 file changed, 48 insertions(+), 56 deletions(-) diff --git a/packages/mermaid/src/diagrams/mindmap/mindmapRenderer.ts b/packages/mermaid/src/diagrams/mindmap/mindmapRenderer.ts index 3fe9e1d510..6d0dc6067e 100644 --- a/packages/mermaid/src/diagrams/mindmap/mindmapRenderer.ts +++ b/packages/mermaid/src/diagrams/mindmap/mindmapRenderer.ts @@ -1,23 +1,21 @@ -/** Created by knut on 14-12-11. */ import { select } from 'd3'; import { log } from '../../logger.js'; import { getConfig } from '../../diagram-api/diagramAPI.js'; import { setupGraphViewbox } from '../../setupGraphViewbox.js'; import svgDraw from './svgDraw.js'; -import cytoscape from 'cytoscape/dist/cytoscape.umd.js'; +import cytoscape from 'cytoscape'; +// @ts-expect-error No types available import coseBilkent from 'cytoscape-cose-bilkent'; import * as db from './mindmapDb.js'; +import type { MermaidConfig, MermaidConfigWithDefaults } from '../../config.type.js'; +import type { Diagram } from '../../Diagram.js'; +import type { MindmapDB } from './mindmapTypes.js'; +import type { D3Element } from '../../mermaidAPI.js'; // Inject the layout algorithm into cytoscape cytoscape.use(coseBilkent); -/** - * @param {any} svg The svg element to draw the diagram onto - * @param {object} mindmap The mindmap data and hierarchy - * @param section - * @param {object} conf The configuration object - */ -function drawNodes(svg, mindmap, section, conf) { +function drawNodes(svg: D3Element, mindmap: db.MindMapNode, section: number, conf: MermaidConfig) { svgDraw.drawNode(svg, mindmap, section, conf); if (mindmap.children) { mindmap.children.forEach((child, index) => { @@ -26,11 +24,23 @@ function drawNodes(svg, mindmap, section, conf) { } } -/** - * @param edgesEl - * @param cy - */ -function drawEdges(edgesEl, cy) { +declare module 'cytoscape' { + interface EdgeSingular { + _private: { + bodyBounds: unknown; + rscratch: { + startX: number; + startY: number; + midX: number; + midY: number; + endX: number; + endY: number; + }; + }; + } +} + +function drawEdges(edgesEl: D3Element, cy: cytoscape.Core) { cy.edges().map((edge, id) => { const data = edge.data(); if (edge[0]._private.bodyBounds) { @@ -47,17 +57,11 @@ function drawEdges(edgesEl, cy) { }); } -/** - * @param mindmap The mindmap data and hierarchy - * @param cy - * @param conf The configuration object - * @param level - */ -function addNodes(mindmap, cy, conf, level) { +function addNodes(mindmap: db.MindMapNode, cy: cytoscape.Core, conf: MermaidConfig, level: number) { cy.add({ group: 'nodes', data: { - id: mindmap.id, + id: mindmap.id.toString(), labelText: mindmap.descr, height: mindmap.height, width: mindmap.width, @@ -67,8 +71,8 @@ function addNodes(mindmap, cy, conf, level) { type: mindmap.type, }, position: { - x: mindmap.x, - y: mindmap.y, + x: mindmap.x!, + y: mindmap.y!, }, }); if (mindmap.children) { @@ -88,12 +92,10 @@ function addNodes(mindmap, cy, conf, level) { } } -/** - * @param node - * @param conf - * @param cy - */ -function layoutMindmap(node, conf) { +function layoutMindmap( + node: db.MindMapNode, + conf: MermaidConfigWithDefaults +): Promise { return new Promise((resolve) => { // Add temporary render element const renderEl = select('body').append('div').attr('id', 'cy').attr('style', 'display:none'); @@ -122,8 +124,8 @@ function layoutMindmap(node, conf) { cy.layout({ name: 'cose-bilkent', + // @ts-ignore Types for cose-bilkent are not correct? quality: 'proof', - // headless: true, styleEnabled: false, animate: false, }).run(); @@ -133,13 +135,8 @@ function layoutMindmap(node, conf) { }); }); } -/** - * @param node - * @param cy - * @param positionedMindmap - * @param conf - */ -function positionNodes(cy) { + +function positionNodes(cy: cytoscape.Core) { cy.nodes().map((node, id) => { const data = node.data(); data.x = node.position().x; @@ -155,38 +152,33 @@ function positionNodes(cy) { }); } -/** - * Draws a an info picture in the tag with id: id based on the graph definition in text. - * - * @param {any} text - * @param {any} id - * @param {any} version - * @param diagObj - */ - -export const draw = async (text, id, version, diagObj) => { +export const draw = async (text: string, id: string, version: string, diagObj: Diagram) => { const conf = getConfig(); conf.htmlLabels = false; log.debug('Rendering mindmap diagram\n' + text, diagObj.parser); - const securityLevel = getConfig().securityLevel; + const securityLevel = conf.securityLevel; // Handle root and Document for when rendering in sandbox mode - let sandboxElement; + // eslint-disable-next-line @typescript-eslint/no-explicit-any + let sandboxElement: any; if (securityLevel === 'sandbox') { sandboxElement = select('#i' + id); } - const root = + // eslint-disable-next-line @typescript-eslint/no-explicit-any + const root: any = securityLevel === 'sandbox' ? select(sandboxElement.nodes()[0].contentDocument.body) : select('body'); - // Parse the graph definition const svg = root.select('#' + id); svg.append('g'); - const mm = diagObj.db.getMindmap(); + const mm = (diagObj.db as MindmapDB).getMindmap(); + if (!mm) { + return; + } // Draw the graph and start with drawing the nodes without proper position // this gives us the size of the nodes and we can set the positions later @@ -201,9 +193,9 @@ export const draw = async (text, id, version, diagObj) => { const cy = await layoutMindmap(mm, conf); - // // After this we can draw, first the edges and the then nodes with the correct position - drawEdges(edgesElem, cy, conf); - positionNodes(cy, conf); + // After this we can draw, first the edges and the then nodes with the correct position + drawEdges(edgesElem, cy); + positionNodes(cy); // Setup the view box and size of the svg element setupGraphViewbox(undefined, svg, conf.mindmap.padding, conf.mindmap.useMaxWidth); From e1a23f10df548a13844c600540d4ae9d0e9df7d5 Mon Sep 17 00:00:00 2001 From: Sidharth Vinod Date: Sun, 28 Jan 2024 21:43:03 +0530 Subject: [PATCH 168/217] chore: Fix config type --- docs/config/setup/modules/config.md | 36 ++++++++++++------- docs/config/setup/modules/mermaidAPI.md | 2 +- packages/mermaid/src/config.ts | 6 +++- packages/mermaid/src/config.type.ts | 5 --- .../src/diagrams/mindmap/mindmapRenderer.ts | 3 +- 5 files changed, 31 insertions(+), 21 deletions(-) diff --git a/docs/config/setup/modules/config.md b/docs/config/setup/modules/config.md index f1de64e2df..afe0af4567 100644 --- a/docs/config/setup/modules/config.md +++ b/docs/config/setup/modules/config.md @@ -6,6 +6,16 @@ # Module: config +## Type Aliases + +### MermaidConfigWithDefaults + +Ƭ **MermaidConfigWithDefaults**: `RequiredDeep`<`MermaidConfig`> + +#### Defined in + +[config.ts:10](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.ts#L10) + ## Variables ### defaultConfig @@ -14,7 +24,7 @@ #### Defined in -[config.ts:8](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.ts#L8) +[config.ts:12](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.ts#L12) ## Functions @@ -36,13 +46,13 @@ Pushes in a directive to the configuration #### Defined in -[config.ts:188](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.ts#L188) +[config.ts:192](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.ts#L192) --- ### getConfig -▸ **getConfig**(): `MermaidConfig` +▸ **getConfig**(): `RequiredObjectDeep`<`MermaidConfig`> ## getConfig @@ -54,13 +64,13 @@ Pushes in a directive to the configuration #### Returns -`MermaidConfig` +`RequiredObjectDeep`<`MermaidConfig`> The currentConfig #### Defined in -[config.ts:131](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.ts#L131) +[config.ts:135](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.ts#L135) --- @@ -84,7 +94,7 @@ The siteConfig #### Defined in -[config.ts:96](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.ts#L96) +[config.ts:100](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.ts#L100) --- @@ -118,7 +128,7 @@ The siteConfig #### Defined in -[config.ts:218](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.ts#L218) +[config.ts:222](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.ts#L222) --- @@ -147,7 +157,7 @@ options in-place #### Defined in -[config.ts:146](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.ts#L146) +[config.ts:150](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.ts#L150) --- @@ -167,7 +177,7 @@ options in-place #### Defined in -[config.ts:75](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.ts#L75) +[config.ts:79](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.ts#L79) --- @@ -199,7 +209,7 @@ The currentConfig merged with the sanitized conf #### Defined in -[config.ts:113](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.ts#L113) +[config.ts:117](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.ts#L117) --- @@ -232,7 +242,7 @@ The new siteConfig #### Defined in -[config.ts:61](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.ts#L61) +[config.ts:65](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.ts#L65) --- @@ -253,7 +263,7 @@ The new siteConfig #### Defined in -[config.ts:15](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.ts#L15) +[config.ts:19](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.ts#L19) --- @@ -273,4 +283,4 @@ The new siteConfig #### Defined in -[config.ts:79](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.ts#L79) +[config.ts:83](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.ts#L83) diff --git a/docs/config/setup/modules/mermaidAPI.md b/docs/config/setup/modules/mermaidAPI.md index a1992c2254..0fa7dec02c 100644 --- a/docs/config/setup/modules/mermaidAPI.md +++ b/docs/config/setup/modules/mermaidAPI.md @@ -31,7 +31,7 @@ Renames and re-exports [mermaidAPI](mermaidAPI.md#mermaidapi) ### mermaidAPI -• `Const` **mermaidAPI**: `Readonly`<{ `defaultConfig`: `MermaidConfig` = configApi.defaultConfig; `getConfig`: () => `MermaidConfig` = configApi.getConfig; `getDiagramFromText`: (`text`: `string`, `metadata`: `Pick`<`DiagramMetadata`, `"title"`>) => `Promise`<`Diagram`> ; `getSiteConfig`: () => `MermaidConfig` = configApi.getSiteConfig; `globalReset`: () => `void` ; `initialize`: (`options`: `MermaidConfig`) => `void` ; `parse`: (`text`: `string`, `parseOptions?`: [`ParseOptions`](../interfaces/mermaidAPI.ParseOptions.md)) => `Promise`<`boolean`> ; `render`: (`id`: `string`, `text`: `string`, `svgContainingElement?`: `Element`) => `Promise`<[`RenderResult`](../interfaces/mermaidAPI.RenderResult.md)> ; `reset`: () => `void` ; `setConfig`: (`conf`: `MermaidConfig`) => `MermaidConfig` = configApi.setConfig; `updateSiteConfig`: (`conf`: `MermaidConfig`) => `MermaidConfig` = configApi.updateSiteConfig }> +• `Const` **mermaidAPI**: `Readonly`<{ `defaultConfig`: `MermaidConfig` = configApi.defaultConfig; `getConfig`: () => `RequiredObjectDeep`<`MermaidConfig`> = configApi.getConfig; `getDiagramFromText`: (`text`: `string`, `metadata`: `Pick`<`DiagramMetadata`, `"title"`>) => `Promise`<`Diagram`> ; `getSiteConfig`: () => `MermaidConfig` = configApi.getSiteConfig; `globalReset`: () => `void` ; `initialize`: (`options`: `MermaidConfig`) => `void` ; `parse`: (`text`: `string`, `parseOptions?`: [`ParseOptions`](../interfaces/mermaidAPI.ParseOptions.md)) => `Promise`<`boolean`> ; `render`: (`id`: `string`, `text`: `string`, `svgContainingElement?`: `Element`) => `Promise`<[`RenderResult`](../interfaces/mermaidAPI.RenderResult.md)> ; `reset`: () => `void` ; `setConfig`: (`conf`: `MermaidConfig`) => `MermaidConfig` = configApi.setConfig; `updateSiteConfig`: (`conf`: `MermaidConfig`) => `MermaidConfig` = configApi.updateSiteConfig }> ## mermaidAPI configuration defaults diff --git a/packages/mermaid/src/config.ts b/packages/mermaid/src/config.ts index f1dccd251d..f117881265 100644 --- a/packages/mermaid/src/config.ts +++ b/packages/mermaid/src/config.ts @@ -2,8 +2,12 @@ import assignWithDepth from './assignWithDepth.js'; import { log } from './logger.js'; import theme from './themes/index.js'; import config from './defaultConfig.js'; -import type { MermaidConfig, MermaidConfigWithDefaults } from './config.type.js'; +import type { MermaidConfig } from './config.type.js'; import { sanitizeDirective } from './utils/sanitizeDirective.js'; +import type { RequiredDeep } from 'type-fest'; + +// I'd prefer this to be named MermaidConfig, so all the functions can use the shorter name. +export type MermaidConfigWithDefaults = RequiredDeep; export const defaultConfig: MermaidConfig = Object.freeze(config); diff --git a/packages/mermaid/src/config.type.ts b/packages/mermaid/src/config.type.ts index 7ca4b89d67..575f428ddd 100644 --- a/packages/mermaid/src/config.type.ts +++ b/packages/mermaid/src/config.type.ts @@ -5,8 +5,6 @@ * and run json-schema-to-typescript to regenerate this file. */ -import { RequiredDeep } from 'type-fest'; - /** * Configuration options to pass to the `dompurify` library. */ @@ -167,9 +165,6 @@ export interface MermaidConfig { wrap?: boolean; fontSize?: number; } - -// I'd prefer this to be named MermaidConfig, so all the functions can use the shorter name. -export type MermaidConfigWithDefaults = RequiredDeep; /** * This interface was referenced by `MermaidConfig`'s JSON-Schema * via the `definition` "BaseDiagramConfig". diff --git a/packages/mermaid/src/diagrams/mindmap/mindmapRenderer.ts b/packages/mermaid/src/diagrams/mindmap/mindmapRenderer.ts index 6d0dc6067e..2a8fabd4f3 100644 --- a/packages/mermaid/src/diagrams/mindmap/mindmapRenderer.ts +++ b/packages/mermaid/src/diagrams/mindmap/mindmapRenderer.ts @@ -7,10 +7,11 @@ import cytoscape from 'cytoscape'; // @ts-expect-error No types available import coseBilkent from 'cytoscape-cose-bilkent'; import * as db from './mindmapDb.js'; -import type { MermaidConfig, MermaidConfigWithDefaults } from '../../config.type.js'; +import type { MermaidConfig } from '../../config.type.js'; import type { Diagram } from '../../Diagram.js'; import type { MindmapDB } from './mindmapTypes.js'; import type { D3Element } from '../../mermaidAPI.js'; +import type { MermaidConfigWithDefaults } from '../../config.js'; // Inject the layout algorithm into cytoscape cytoscape.use(coseBilkent); From 9651d0c2da4799713fbbded20e34550cc9f2af44 Mon Sep 17 00:00:00 2001 From: Sidharth Vinod Date: Mon, 29 Jan 2024 10:45:47 +0530 Subject: [PATCH 169/217] refactor: Fix types and imports --- package.json | 5 ++ packages/mermaid-example-diagram/package.json | 7 +-- packages/mermaid/package.json | 3 +- .../diagrams/mindmap/mindmap-definition.ts | 16 +++--- .../src/diagrams/mindmap/mindmap.spec.ts | 2 +- .../mermaid/src/diagrams/mindmap/mindmapDb.ts | 32 +++++------ .../src/diagrams/mindmap/mindmapRenderer.ts | 17 +++--- .../src/diagrams/mindmap/mindmapTypes.ts | 19 ++++++- patches/cytoscape@3.28.1.patch | 20 +++++++ pnpm-lock.yaml | 57 +++++-------------- 10 files changed, 90 insertions(+), 88 deletions(-) create mode 100644 patches/cytoscape@3.28.1.patch diff --git a/package.json b/package.json index 441484218d..4a5a56aaef 100644 --- a/package.json +++ b/package.json @@ -127,5 +127,10 @@ }, "nyc": { "report-dir": "coverage/cypress" + }, + "pnpm": { + "patchedDependencies": { + "cytoscape@3.28.1": "patches/cytoscape@3.28.1.patch" + } } } diff --git a/packages/mermaid-example-diagram/package.json b/packages/mermaid-example-diagram/package.json index dc468a6c73..63e8aadea9 100644 --- a/packages/mermaid-example-diagram/package.json +++ b/packages/mermaid-example-diagram/package.json @@ -39,15 +39,10 @@ }, "dependencies": { "@braintree/sanitize-url": "^6.0.1", - "cytoscape": "^3.23.0", - "cytoscape-cose-bilkent": "^4.1.0", - "cytoscape-fcose": "^2.1.0", "d3": "^7.0.0", - "khroma": "^2.0.0", - "non-layered-tidy-tree-layout": "^2.0.2" + "khroma": "^2.0.0" }, "devDependencies": { - "@types/cytoscape": "^3.19.9", "concurrently": "^8.0.0", "rimraf": "^5.0.0", "mermaid": "workspace:*" diff --git a/packages/mermaid/package.json b/packages/mermaid/package.json index 4557506afd..471a11fd32 100644 --- a/packages/mermaid/package.json +++ b/packages/mermaid/package.json @@ -62,9 +62,8 @@ "@braintree/sanitize-url": "^6.0.1", "@types/d3-scale": "^4.0.3", "@types/d3-scale-chromatic": "^3.0.0", - "cytoscape": "^3.23.0", + "cytoscape": "^3.28.1", "cytoscape-cose-bilkent": "^4.1.0", - "cytoscape-fcose": "^2.1.0", "d3": "^7.4.0", "d3-sankey": "^0.12.3", "dagre-d3-es": "7.0.10", diff --git a/packages/mermaid/src/diagrams/mindmap/mindmap-definition.ts b/packages/mermaid/src/diagrams/mindmap/mindmap-definition.ts index c5c7303c30..66b44b4f9f 100644 --- a/packages/mermaid/src/diagrams/mindmap/mindmap-definition.ts +++ b/packages/mermaid/src/diagrams/mindmap/mindmap-definition.ts @@ -1,13 +1,13 @@ // @ts-ignore: JISON doesn't support types -import mindmapParser from './parser/mindmap.jison'; -import * as mindmapDb from './mindmapDb.js'; -import mindmapRenderer from './mindmapRenderer.js'; -import mindmapStyles from './styles.js'; +import parser from './parser/mindmap.jison'; +import db from './mindmapDb.js'; +import renderer from './mindmapRenderer.js'; +import styles from './styles.js'; import type { DiagramDefinition } from '../../diagram-api/types.js'; export const diagram: DiagramDefinition = { - db: mindmapDb, - renderer: mindmapRenderer, - parser: mindmapParser, - styles: mindmapStyles, + db, + renderer, + parser, + styles, }; diff --git a/packages/mermaid/src/diagrams/mindmap/mindmap.spec.ts b/packages/mermaid/src/diagrams/mindmap/mindmap.spec.ts index f6cc4304f8..2d67fc600a 100644 --- a/packages/mermaid/src/diagrams/mindmap/mindmap.spec.ts +++ b/packages/mermaid/src/diagrams/mindmap/mindmap.spec.ts @@ -1,6 +1,6 @@ // @ts-expect-error No types available for JISON import { parser as mindmap } from './parser/mindmap.jison'; -import * as mindmapDB from './mindmapDb.js'; +import mindmapDB from './mindmapDb.js'; // Todo fix utils functions for tests import { setLogLevel } from '../../diagram-api/diagramAPI.js'; diff --git a/packages/mermaid/src/diagrams/mindmap/mindmapDb.ts b/packages/mermaid/src/diagrams/mindmap/mindmapDb.ts index 72c9968b62..eceabc52b9 100644 --- a/packages/mermaid/src/diagrams/mindmap/mindmapDb.ts +++ b/packages/mermaid/src/diagrams/mindmap/mindmapDb.ts @@ -2,23 +2,7 @@ import { getConfig } from '../../diagram-api/diagramAPI.js'; import { sanitizeText } from '../../diagrams/common/common.js'; import { log } from '../../logger.js'; import type { D3Element } from '../../mermaidAPI.js'; - -export interface MindMapNode { - id: number; - nodeId: string; - level: number; - descr: string; - type: number; - children: MindMapNode[]; - width: number; - padding: number; - section?: number; - height?: number; - class?: string; - icon?: string; - x?: number; - y?: number; -} +import type { MindMapNode } from './mindmapTypes.js'; let nodes: MindMapNode[] = []; let cnt = 0; @@ -158,3 +142,17 @@ export const type2Str = (type: number) => { // Expose logger to grammar export const getLogger = () => log; export const getElementById = (id: string) => elements[id]; + +const db = { + clear, + addNode, + getMindmap, + nodeType, + setElementForId, + decorateNode, + type2Str, + getLogger, + getElementById, +} as const; + +export default db; diff --git a/packages/mermaid/src/diagrams/mindmap/mindmapRenderer.ts b/packages/mermaid/src/diagrams/mindmap/mindmapRenderer.ts index 2a8fabd4f3..f4471b01da 100644 --- a/packages/mermaid/src/diagrams/mindmap/mindmapRenderer.ts +++ b/packages/mermaid/src/diagrams/mindmap/mindmapRenderer.ts @@ -6,17 +6,16 @@ import svgDraw from './svgDraw.js'; import cytoscape from 'cytoscape'; // @ts-expect-error No types available import coseBilkent from 'cytoscape-cose-bilkent'; -import * as db from './mindmapDb.js'; +import type { MindMapNode, MindmapDB } from './mindmapTypes.js'; import type { MermaidConfig } from '../../config.type.js'; import type { Diagram } from '../../Diagram.js'; -import type { MindmapDB } from './mindmapTypes.js'; import type { D3Element } from '../../mermaidAPI.js'; import type { MermaidConfigWithDefaults } from '../../config.js'; // Inject the layout algorithm into cytoscape cytoscape.use(coseBilkent); -function drawNodes(svg: D3Element, mindmap: db.MindMapNode, section: number, conf: MermaidConfig) { +function drawNodes(svg: D3Element, mindmap: MindMapNode, section: number, conf: MermaidConfig) { svgDraw.drawNode(svg, mindmap, section, conf); if (mindmap.children) { mindmap.children.forEach((child, index) => { @@ -58,7 +57,7 @@ function drawEdges(edgesEl: D3Element, cy: cytoscape.Core) { }); } -function addNodes(mindmap: db.MindMapNode, cy: cytoscape.Core, conf: MermaidConfig, level: number) { +function addNodes(mindmap: MindMapNode, cy: cytoscape.Core, conf: MermaidConfig, level: number) { cy.add({ group: 'nodes', data: { @@ -94,7 +93,7 @@ function addNodes(mindmap: db.MindMapNode, cy: cytoscape.Core, conf: MermaidConf } function layoutMindmap( - node: db.MindMapNode, + node: MindMapNode, conf: MermaidConfigWithDefaults ): Promise { return new Promise((resolve) => { @@ -137,7 +136,7 @@ function layoutMindmap( }); } -function positionNodes(cy: cytoscape.Core) { +function positionNodes(db: MindmapDB, cy: cytoscape.Core) { cy.nodes().map((node, id) => { const data = node.data(); data.x = node.position().x; @@ -155,7 +154,7 @@ function positionNodes(cy: cytoscape.Core) { export const draw = async (text: string, id: string, version: string, diagObj: Diagram) => { const conf = getConfig(); - + const db = diagObj.db as MindmapDB; conf.htmlLabels = false; log.debug('Rendering mindmap diagram\n' + text, diagObj.parser); @@ -176,7 +175,7 @@ export const draw = async (text: string, id: string, version: string, diagObj: D const svg = root.select('#' + id); svg.append('g'); - const mm = (diagObj.db as MindmapDB).getMindmap(); + const mm = db.getMindmap(); if (!mm) { return; } @@ -196,7 +195,7 @@ export const draw = async (text: string, id: string, version: string, diagObj: D // After this we can draw, first the edges and the then nodes with the correct position drawEdges(edgesElem, cy); - positionNodes(cy); + positionNodes(db, cy); // Setup the view box and size of the svg element setupGraphViewbox(undefined, svg, conf.mindmap.padding, conf.mindmap.useMaxWidth); diff --git a/packages/mermaid/src/diagrams/mindmap/mindmapTypes.ts b/packages/mermaid/src/diagrams/mindmap/mindmapTypes.ts index caec37d2c0..28ec37c391 100644 --- a/packages/mermaid/src/diagrams/mindmap/mindmapTypes.ts +++ b/packages/mermaid/src/diagrams/mindmap/mindmapTypes.ts @@ -1,3 +1,20 @@ -import type * as mindmapDb from './mindmapDb.js'; +import type mindmapDb from './mindmapDb.js'; + +export interface MindMapNode { + id: number; + nodeId: string; + level: number; + descr: string; + type: number; + children: MindMapNode[]; + width: number; + padding: number; + section?: number; + height?: number; + class?: string; + icon?: string; + x?: number; + y?: number; +} export type MindmapDB = typeof mindmapDb; diff --git a/patches/cytoscape@3.28.1.patch b/patches/cytoscape@3.28.1.patch new file mode 100644 index 0000000000..d92163a318 --- /dev/null +++ b/patches/cytoscape@3.28.1.patch @@ -0,0 +1,20 @@ +diff --git a/package.json b/package.json +index f2f77fa79c99382b079f4051ed51eafe8d2379c8..0bfddf55394e86f3a386eb7ab681369d410bae07 100644 +--- a/package.json ++++ b/package.json +@@ -30,7 +30,15 @@ + "engines": { + "node": ">=0.10" + }, ++ "exports": { ++ ".": { ++ "import": "./dist/cytoscape.umd.js", ++ "default": "./dist/cytoscape.cjs.js" ++ }, ++ "./*": "./*" ++ }, + "main": "dist/cytoscape.cjs.js", ++ "module": "dist/cytoscape.umd.js", + "unpkg": "dist/cytoscape.min.js", + "jsdelivr": "dist/cytoscape.min.js", + "scripts": { diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 5d950edefc..1312ff7c52 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -4,6 +4,11 @@ settings: autoInstallPeers: true excludeLinksFromLockfile: false +patchedDependencies: + cytoscape@3.28.1: + hash: claipxynndhyqyu2csninuoh5e + path: patches/cytoscape@3.28.1.patch + importers: .: @@ -201,14 +206,11 @@ importers: specifier: ^3.0.0 version: 3.0.0 cytoscape: - specifier: ^3.23.0 - version: 3.23.0 + specifier: ^3.28.1 + version: 3.28.1(patch_hash=claipxynndhyqyu2csninuoh5e) cytoscape-cose-bilkent: specifier: ^4.1.0 - version: 4.1.0(cytoscape@3.23.0) - cytoscape-fcose: - specifier: ^2.1.0 - version: 2.1.0(cytoscape@3.23.0) + version: 4.1.0(cytoscape@3.28.1) d3: specifier: ^7.4.0 version: 7.4.0 @@ -384,28 +386,13 @@ importers: '@braintree/sanitize-url': specifier: ^6.0.1 version: 6.0.2 - cytoscape: - specifier: ^3.23.0 - version: 3.23.0 - cytoscape-cose-bilkent: - specifier: ^4.1.0 - version: 4.1.0(cytoscape@3.23.0) - cytoscape-fcose: - specifier: ^2.1.0 - version: 2.1.0(cytoscape@3.23.0) d3: specifier: ^7.0.0 version: 7.0.0 khroma: specifier: ^2.0.0 version: 2.0.0 - non-layered-tidy-tree-layout: - specifier: ^2.0.2 - version: 2.0.2 devDependencies: - '@types/cytoscape': - specifier: ^3.19.9 - version: 3.19.9 concurrently: specifier: ^8.0.0 version: 8.0.0 @@ -7739,12 +7726,6 @@ packages: layout-base: 1.0.2 dev: false - /cose-base@2.2.0: - resolution: {integrity: sha512-AzlgcsCbUMymkADOJtQm3wO9S3ltPfYOFD5033keQn9NJzIbtnZj+UdBJe7DYml/8TdbtHJW3j58SOnKhWY/5g==} - dependencies: - layout-base: 2.0.1 - dev: false - /cosmiconfig-typescript-loader@4.4.0(@types/node@20.4.7)(cosmiconfig@8.2.0)(ts-node@10.9.1)(typescript@5.1.6): resolution: {integrity: sha512-BabizFdC3wBHhbI4kJh0VkQP9GkBfoHPydD0COMce1nJ1kJAB3F2TmJ/I7diULBKtmEWSwEbuN/KDtgnmUUVmw==} engines: {node: '>=v14.21.3'} @@ -8135,31 +8116,23 @@ packages: yauzl: 2.10.0 dev: true - /cytoscape-cose-bilkent@4.1.0(cytoscape@3.23.0): + /cytoscape-cose-bilkent@4.1.0(cytoscape@3.28.1): resolution: {integrity: sha512-wgQlVIUJF13Quxiv5e1gstZ08rnZj2XaLHGoFMYXz7SkNfCDOOteKBE6SYRfA9WxxI/iBc3ajfDoc6hb/MRAHQ==} peerDependencies: cytoscape: ^3.2.0 dependencies: cose-base: 1.0.3 - cytoscape: 3.23.0 - dev: false - - /cytoscape-fcose@2.1.0(cytoscape@3.23.0): - resolution: {integrity: sha512-Q3apPl66jf8/2sMsrCjNP247nbDkyIPjA9g5iPMMWNLZgP3/mn9aryF7EFY/oRPEpv7bKJ4jYmCoU5r5/qAc1Q==} - peerDependencies: - cytoscape: ^3.2.0 - dependencies: - cose-base: 2.2.0 - cytoscape: 3.23.0 + cytoscape: 3.28.1(patch_hash=claipxynndhyqyu2csninuoh5e) dev: false - /cytoscape@3.23.0: - resolution: {integrity: sha512-gRZqJj/1kiAVPkrVFvz/GccxsXhF3Qwpptl32gKKypO4IlqnKBjTOu+HbXtEggSGzC5KCaHp3/F7GgENrtsFkA==} + /cytoscape@3.28.1(patch_hash=claipxynndhyqyu2csninuoh5e): + resolution: {integrity: sha512-xyItz4O/4zp9/239wCcH8ZcFuuZooEeF8KHRmzjDfGdXsj3OG9MFSMA0pJE0uX3uCN/ygof6hHf4L7lst+JaDg==} engines: {node: '>=0.10'} dependencies: heap: 0.2.7 lodash: 4.17.21 dev: false + patched: true /d3-array@2.12.1: resolution: {integrity: sha512-B0ErZK/66mHtEsR1TkPEEkwdy+WDesimkM5gpZr5Dsg54BiTA5RXtYW5qTLIAcekaS9xfZrzBLF/OAkB3Qn1YQ==} @@ -12000,10 +11973,6 @@ packages: resolution: {integrity: sha512-8h2oVEZNktL4BH2JCOI90iD1yXwL6iNW7KcCKT2QZgQJR2vbqDsldCTPRU9NifTCqHZci57XvQQ15YTu+sTYPg==} dev: false - /layout-base@2.0.1: - resolution: {integrity: sha512-dp3s92+uNI1hWIpPGH3jK2kxE2lMjdXdr+DH8ynZHpd6PUlH6x6cbuXnoMmiNumznqaNO31xu9e79F0uuZ0JFg==} - dev: false - /lazy-ass@1.6.0: resolution: {integrity: sha512-cc8oEVoctTvsFZ/Oje/kGnHbpWHYBe8IAJe4C0QNc3t8uM/0Y8+erSz/7Y1ALuXTEZTMvxXwO6YbX1ey3ujiZw==} engines: {node: '> 0.8'} From cffac848ead7cc3250db2f79cd09bce7a99739c1 Mon Sep 17 00:00:00 2001 From: Sidharth Vinod Date: Mon, 29 Jan 2024 10:52:58 +0530 Subject: [PATCH 170/217] chore: Fix mindmapDb exports --- .../mermaid/src/diagrams/mindmap/mindmapDb.ts | 21 ++++++++++--------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/packages/mermaid/src/diagrams/mindmap/mindmapDb.ts b/packages/mermaid/src/diagrams/mindmap/mindmapDb.ts index eceabc52b9..f5303ac29c 100644 --- a/packages/mermaid/src/diagrams/mindmap/mindmapDb.ts +++ b/packages/mermaid/src/diagrams/mindmap/mindmapDb.ts @@ -8,7 +8,7 @@ let nodes: MindMapNode[] = []; let cnt = 0; let elements: Record = {}; -export const clear = () => { +const clear = () => { nodes = []; cnt = 0; elements = {}; @@ -24,11 +24,11 @@ const getParent = function (level: number) { return null; }; -export const getMindmap = () => { +const getMindmap = () => { return nodes.length > 0 ? nodes[0] : null; }; -export const addNode = (level: number, id: string, descr: string, type: number) => { +const addNode = (level: number, id: string, descr: string, type: number) => { log.info('addNode', level, id, descr, type); const conf = getConfig(); let padding: number = conf.mindmap?.padding ?? 10; @@ -69,7 +69,7 @@ export const addNode = (level: number, id: string, descr: string, type: number) } }; -export const nodeType = { +const nodeType = { DEFAULT: 0, NO_BORDER: 0, ROUNDED_RECT: 1, @@ -80,7 +80,7 @@ export const nodeType = { HEXAGON: 6, }; -export const getType = (startStr: string, endStr: string): number => { +const getType = (startStr: string, endStr: string): number => { log.debug('In get type', startStr, endStr); switch (startStr) { case '[': @@ -100,11 +100,11 @@ export const getType = (startStr: string, endStr: string): number => { } }; -export const setElementForId = (id: string, element: D3Element) => { +const setElementForId = (id: string, element: D3Element) => { elements[id] = element; }; -export const decorateNode = (decoration?: { class?: string; icon?: string }) => { +const decorateNode = (decoration?: { class?: string; icon?: string }) => { if (!decoration) { return; } @@ -118,7 +118,7 @@ export const decorateNode = (decoration?: { class?: string; icon?: string }) => } }; -export const type2Str = (type: number) => { +const type2Str = (type: number) => { switch (type) { case nodeType.DEFAULT: return 'no-border'; @@ -140,14 +140,15 @@ export const type2Str = (type: number) => { }; // Expose logger to grammar -export const getLogger = () => log; -export const getElementById = (id: string) => elements[id]; +const getLogger = () => log; +const getElementById = (id: string) => elements[id]; const db = { clear, addNode, getMindmap, nodeType, + getType, setElementForId, decorateNode, type2Str, From 23d843b6d381aa42caf1ebb7f5f908e2c187608d Mon Sep 17 00:00:00 2001 From: Sidharth Vinod Date: Mon, 29 Jan 2024 11:21:12 +0530 Subject: [PATCH 171/217] refactor: Remove db import from svgDraw --- .../src/diagrams/mindmap/mindmapRenderer.ts | 18 ++++-- .../mermaid/src/diagrams/mindmap/svgDraw.js | 58 ++++++------------- 2 files changed, 29 insertions(+), 47 deletions(-) diff --git a/packages/mermaid/src/diagrams/mindmap/mindmapRenderer.ts b/packages/mermaid/src/diagrams/mindmap/mindmapRenderer.ts index f4471b01da..04eed6b5a1 100644 --- a/packages/mermaid/src/diagrams/mindmap/mindmapRenderer.ts +++ b/packages/mermaid/src/diagrams/mindmap/mindmapRenderer.ts @@ -2,7 +2,7 @@ import { select } from 'd3'; import { log } from '../../logger.js'; import { getConfig } from '../../diagram-api/diagramAPI.js'; import { setupGraphViewbox } from '../../setupGraphViewbox.js'; -import svgDraw from './svgDraw.js'; +import { drawNode, positionNode } from './svgDraw.js'; import cytoscape from 'cytoscape'; // @ts-expect-error No types available import coseBilkent from 'cytoscape-cose-bilkent'; @@ -15,11 +15,17 @@ import type { MermaidConfigWithDefaults } from '../../config.js'; // Inject the layout algorithm into cytoscape cytoscape.use(coseBilkent); -function drawNodes(svg: D3Element, mindmap: MindMapNode, section: number, conf: MermaidConfig) { - svgDraw.drawNode(svg, mindmap, section, conf); +function drawNodes( + db: MindmapDB, + svg: D3Element, + mindmap: MindMapNode, + section: number, + conf: MermaidConfig +) { + drawNode(db, svg, mindmap, section, conf); if (mindmap.children) { mindmap.children.forEach((child, index) => { - drawNodes(svg, child, section < 0 ? index : section, conf); + drawNodes(db, svg, child, section < 0 ? index : section, conf); }); } } @@ -141,7 +147,7 @@ function positionNodes(db: MindmapDB, cy: cytoscape.Core) { const data = node.data(); data.x = node.position().x; data.y = node.position().y; - svgDraw.positionNode(data); + positionNode(db, data); const el = db.getElementById(data.nodeId); log.info('Id:', id, 'Position: (', node.position().x, ', ', node.position().y, ')', data); el.attr( @@ -187,7 +193,7 @@ export const draw = async (text: string, id: string, version: string, diagObj: D edgesElem.attr('class', 'mindmap-edges'); const nodesElem = svg.append('g'); nodesElem.attr('class', 'mindmap-nodes'); - drawNodes(nodesElem, mm, -1, conf); + drawNodes(db, nodesElem, mm, -1, conf); // Next step is to layout the mindmap, giving each node a position diff --git a/packages/mermaid/src/diagrams/mindmap/svgDraw.js b/packages/mermaid/src/diagrams/mindmap/svgDraw.js index b065e8010f..8d3340c6e6 100644 --- a/packages/mermaid/src/diagrams/mindmap/svgDraw.js +++ b/packages/mermaid/src/diagrams/mindmap/svgDraw.js @@ -1,8 +1,7 @@ -import * as db from './mindmapDb.js'; import { createText } from '../../rendering-util/createText.js'; const MAX_SECTIONS = 12; -const defaultBkg = function (elem, node, section) { +const defaultBkg = function (db, elem, node, section) { const rd = 5; elem .append('path') @@ -24,7 +23,7 @@ const defaultBkg = function (elem, node, section) { .attr('y2', node.height); }; -const rectBkg = function (elem, node) { +const rectBkg = function (db, elem, node) { elem .append('rect') .attr('id', 'node-' + node.id) @@ -33,7 +32,7 @@ const rectBkg = function (elem, node) { .attr('width', node.width); }; -const cloudBkg = function (elem, node) { +const cloudBkg = function (db, elem, node) { const w = node.width; const h = node.height; const r1 = 0.15 * w; @@ -64,7 +63,7 @@ const cloudBkg = function (elem, node) { ); }; -const bangBkg = function (elem, node) { +const bangBkg = function (db, elem, node) { const w = node.width; const h = node.height; const r = 0.15 * w; @@ -96,7 +95,7 @@ const bangBkg = function (elem, node) { ); }; -const circleBkg = function (elem, node) { +const circleBkg = function (db, elem, node) { elem .append('circle') .attr('id', 'node-' + node.id) @@ -126,7 +125,7 @@ function insertPolygonShape(parent, w, h, points, node) { .attr('transform', 'translate(' + (node.width - w) / 2 + ', ' + h + ')'); } -const hexagonBkg = function (elem, node) { +const hexagonBkg = function (db, elem, node) { const h = node.height; const f = 4; const m = h / f; @@ -142,7 +141,7 @@ const hexagonBkg = function (elem, node) { const shapeSvg = insertPolygonShape(elem, w, h, points, node); }; -const roundedRectBkg = function (elem, node) { +const roundedRectBkg = function (db, elem, node) { elem .append('rect') .attr('id', 'node-' + node.id) @@ -154,13 +153,14 @@ const roundedRectBkg = function (elem, node) { }; /** + * @param {import('./mindmapTypes.js').MindmapDB} db The database * @param {object} elem The D3 dom element in which the node is to be added * @param {object} node The node to be added * @param fullSection * @param {object} conf The configuration object * @returns {number} The height nodes dom element */ -export const drawNode = function (elem, node, fullSection, conf) { +export const drawNode = function (db, elem, node, fullSection, conf) { const htmlLabels = conf.htmlLabels; const section = fullSection % (MAX_SECTIONS - 1); const nodeElem = elem.append('g'); @@ -247,26 +247,26 @@ export const drawNode = function (elem, node, fullSection, conf) { switch (node.type) { case db.nodeType.DEFAULT: - defaultBkg(bkgElem, node, section, conf); + defaultBkg(db, bkgElem, node, section, conf); break; case db.nodeType.ROUNDED_RECT: - roundedRectBkg(bkgElem, node, section, conf); + roundedRectBkg(db, bkgElem, node, section, conf); break; case db.nodeType.RECT: - rectBkg(bkgElem, node, section, conf); + rectBkg(db, bkgElem, node, section, conf); break; case db.nodeType.CIRCLE: bkgElem.attr('transform', 'translate(' + node.width / 2 + ', ' + +node.height / 2 + ')'); - circleBkg(bkgElem, node, section, conf); + circleBkg(db, bkgElem, node, section, conf); break; case db.nodeType.CLOUD: - cloudBkg(bkgElem, node, section, conf); + cloudBkg(db, bkgElem, node, section, conf); break; case db.nodeType.BANG: - bangBkg(bkgElem, node, section, conf); + bangBkg(db, bkgElem, node, section, conf); break; case db.nodeType.HEXAGON: - hexagonBkg(bkgElem, node, section, conf); + hexagonBkg(db, bkgElem, node, section, conf); break; } @@ -274,29 +274,7 @@ export const drawNode = function (elem, node, fullSection, conf) { return node.height; }; -export const drawEdge = function drawEdge(edgesElem, mindmap, parent, depth, fullSection) { - const section = fullSection % (MAX_SECTIONS - 1); - const sx = parent.x + parent.width / 2; - const sy = parent.y + parent.height / 2; - const ex = mindmap.x + mindmap.width / 2; - const ey = mindmap.y + mindmap.height / 2; - const mx = ex > sx ? sx + Math.abs(sx - ex) / 2 : sx - Math.abs(sx - ex) / 2; - const my = ey > sy ? sy + Math.abs(sy - ey) / 2 : sy - Math.abs(sy - ey) / 2; - const qx = ex > sx ? Math.abs(sx - mx) / 2 + sx : -Math.abs(sx - mx) / 2 + sx; - const qy = ey > sy ? Math.abs(sy - my) / 2 + sy : -Math.abs(sy - my) / 2 + sy; - - edgesElem - .append('path') - .attr( - 'd', - parent.direction === 'TB' || parent.direction === 'BT' - ? `M${sx},${sy} Q${sx},${qy} ${mx},${my} T${ex},${ey}` - : `M${sx},${sy} Q${qx},${sy} ${mx},${my} T${ex},${ey}` - ) - .attr('class', 'edge section-edge-' + section + ' edge-depth-' + depth); -}; - -export const positionNode = function (node) { +export const positionNode = function (db, node) { const nodeElem = db.getElementById(node.id); const x = node.x || 0; @@ -304,5 +282,3 @@ export const positionNode = function (node) { // Position the node to its coordinate nodeElem.attr('transform', 'translate(' + x + ',' + y + ')'); }; - -export default { drawNode, positionNode, drawEdge }; From bde6a9ff4f3fc636d2ad0df7e9076b6b1b7eedc5 Mon Sep 17 00:00:00 2001 From: Sidharth Vinod Date: Mon, 29 Jan 2024 11:21:42 +0530 Subject: [PATCH 172/217] Rename styles.js --- packages/mermaid/src/diagrams/mindmap/{styles.js => styles.ts} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename packages/mermaid/src/diagrams/mindmap/{styles.js => styles.ts} (100%) diff --git a/packages/mermaid/src/diagrams/mindmap/styles.js b/packages/mermaid/src/diagrams/mindmap/styles.ts similarity index 100% rename from packages/mermaid/src/diagrams/mindmap/styles.js rename to packages/mermaid/src/diagrams/mindmap/styles.ts From 13e052ff8175bb8a10899b77e6b246846f0f9284 Mon Sep 17 00:00:00 2001 From: Sidharth Vinod Date: Mon, 29 Jan 2024 11:26:10 +0530 Subject: [PATCH 173/217] Fix styles.ts --- packages/mermaid/src/diagrams/mindmap/styles.ts | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/packages/mermaid/src/diagrams/mindmap/styles.ts b/packages/mermaid/src/diagrams/mindmap/styles.ts index 863522fdf7..cf435a721a 100644 --- a/packages/mermaid/src/diagrams/mindmap/styles.ts +++ b/packages/mermaid/src/diagrams/mindmap/styles.ts @@ -1,6 +1,7 @@ +// @ts-expect-error Incorrect khroma types import { darken, lighten, isDark } from 'khroma'; -const genSections = (options) => { +const genSections = (options: any) => { let sections = ''; for (let i = 0; i < options.THEME_COLOR_LIMIT; i++) { @@ -49,7 +50,8 @@ const genSections = (options) => { return sections; }; -const getStyles = (options) => +// TODO: These options seem incorrect. +const getStyles = (options: any) => ` .edge { stroke-width: 3; From 75ec719257b58f930b7ae33138fff94501608638 Mon Sep 17 00:00:00 2001 From: Sidharth Vinod Date: Mon, 29 Jan 2024 11:31:22 +0530 Subject: [PATCH 174/217] Rename svgDraw.js --- packages/mermaid/src/diagrams/mindmap/{svgDraw.js => svgDraw.ts} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename packages/mermaid/src/diagrams/mindmap/{svgDraw.js => svgDraw.ts} (100%) diff --git a/packages/mermaid/src/diagrams/mindmap/svgDraw.js b/packages/mermaid/src/diagrams/mindmap/svgDraw.ts similarity index 100% rename from packages/mermaid/src/diagrams/mindmap/svgDraw.js rename to packages/mermaid/src/diagrams/mindmap/svgDraw.ts From b51d8ff7ba4cf9714903a60d8c703b10b0f6ca59 Mon Sep 17 00:00:00 2001 From: Sidharth Vinod Date: Mon, 29 Jan 2024 12:16:21 +0530 Subject: [PATCH 175/217] Convert svgDraw.ts --- .../mermaid/src/diagrams/mindmap/mindmapDb.ts | 16 ++--- .../src/diagrams/mindmap/mindmapRenderer.ts | 12 ++-- .../src/diagrams/mindmap/mindmapTypes.ts | 6 +- .../mermaid/src/diagrams/mindmap/svgDraw.ts | 60 ++++++++++--------- 4 files changed, 51 insertions(+), 43 deletions(-) diff --git a/packages/mermaid/src/diagrams/mindmap/mindmapDb.ts b/packages/mermaid/src/diagrams/mindmap/mindmapDb.ts index f5303ac29c..c0fdd12574 100644 --- a/packages/mermaid/src/diagrams/mindmap/mindmapDb.ts +++ b/packages/mermaid/src/diagrams/mindmap/mindmapDb.ts @@ -1,12 +1,12 @@ import { getConfig } from '../../diagram-api/diagramAPI.js'; +import type { D3Element } from '../../mermaidAPI.js'; import { sanitizeText } from '../../diagrams/common/common.js'; import { log } from '../../logger.js'; -import type { D3Element } from '../../mermaidAPI.js'; -import type { MindMapNode } from './mindmapTypes.js'; +import type { MindmapNode } from './mindmapTypes.js'; -let nodes: MindMapNode[] = []; +let nodes: MindmapNode[] = []; let cnt = 0; -let elements: Record = {}; +let elements: Record = {}; const clear = () => { nodes = []; @@ -14,7 +14,7 @@ const clear = () => { elements = {}; }; -const getParent = function (level: number) { +const getParent = function(level: number) { for (let i = nodes.length - 1; i >= 0; i--) { if (nodes[i].level < level) { return nodes[i]; @@ -48,7 +48,7 @@ const addNode = (level: number, id: string, descr: string, type: number) => { children: [], width: conf.mindmap?.maxNodeWidth ?? 200, padding, - } satisfies MindMapNode; + } satisfies MindmapNode; const parent = getParent(level); if (parent) { @@ -100,7 +100,7 @@ const getType = (startStr: string, endStr: string): number => { } }; -const setElementForId = (id: string, element: D3Element) => { +const setElementForId = (id: number, element: D3Element) => { elements[id] = element; }; @@ -141,7 +141,7 @@ const type2Str = (type: number) => { // Expose logger to grammar const getLogger = () => log; -const getElementById = (id: string) => elements[id]; +const getElementById = (id: number) => elements[id]; const db = { clear, diff --git a/packages/mermaid/src/diagrams/mindmap/mindmapRenderer.ts b/packages/mermaid/src/diagrams/mindmap/mindmapRenderer.ts index 04eed6b5a1..6b98715675 100644 --- a/packages/mermaid/src/diagrams/mindmap/mindmapRenderer.ts +++ b/packages/mermaid/src/diagrams/mindmap/mindmapRenderer.ts @@ -6,7 +6,7 @@ import { drawNode, positionNode } from './svgDraw.js'; import cytoscape from 'cytoscape'; // @ts-expect-error No types available import coseBilkent from 'cytoscape-cose-bilkent'; -import type { MindMapNode, MindmapDB } from './mindmapTypes.js'; +import type { MindmapNode, MindmapDB, FilledMindMapNode } from './mindmapTypes.js'; import type { MermaidConfig } from '../../config.type.js'; import type { Diagram } from '../../Diagram.js'; import type { D3Element } from '../../mermaidAPI.js'; @@ -18,9 +18,9 @@ cytoscape.use(coseBilkent); function drawNodes( db: MindmapDB, svg: D3Element, - mindmap: MindMapNode, + mindmap: FilledMindMapNode, section: number, - conf: MermaidConfig + conf: MermaidConfigWithDefaults ) { drawNode(db, svg, mindmap, section, conf); if (mindmap.children) { @@ -63,7 +63,7 @@ function drawEdges(edgesEl: D3Element, cy: cytoscape.Core) { }); } -function addNodes(mindmap: MindMapNode, cy: cytoscape.Core, conf: MermaidConfig, level: number) { +function addNodes(mindmap: MindmapNode, cy: cytoscape.Core, conf: MermaidConfig, level: number) { cy.add({ group: 'nodes', data: { @@ -99,7 +99,7 @@ function addNodes(mindmap: MindMapNode, cy: cytoscape.Core, conf: MermaidConfig, } function layoutMindmap( - node: MindMapNode, + node: MindmapNode, conf: MermaidConfigWithDefaults ): Promise { return new Promise((resolve) => { @@ -193,7 +193,7 @@ export const draw = async (text: string, id: string, version: string, diagObj: D edgesElem.attr('class', 'mindmap-edges'); const nodesElem = svg.append('g'); nodesElem.attr('class', 'mindmap-nodes'); - drawNodes(db, nodesElem, mm, -1, conf); + drawNodes(db, nodesElem, mm as FilledMindMapNode, -1, conf); // Next step is to layout the mindmap, giving each node a position diff --git a/packages/mermaid/src/diagrams/mindmap/mindmapTypes.ts b/packages/mermaid/src/diagrams/mindmap/mindmapTypes.ts index 28ec37c391..ced93ecacb 100644 --- a/packages/mermaid/src/diagrams/mindmap/mindmapTypes.ts +++ b/packages/mermaid/src/diagrams/mindmap/mindmapTypes.ts @@ -1,12 +1,13 @@ +import { RequiredDeep } from 'type-fest'; import type mindmapDb from './mindmapDb.js'; -export interface MindMapNode { +export interface MindmapNode { id: number; nodeId: string; level: number; descr: string; type: number; - children: MindMapNode[]; + children: MindmapNode[]; width: number; padding: number; section?: number; @@ -17,4 +18,5 @@ export interface MindMapNode { y?: number; } +export type FilledMindMapNode = RequiredDeep; export type MindmapDB = typeof mindmapDb; diff --git a/packages/mermaid/src/diagrams/mindmap/svgDraw.ts b/packages/mermaid/src/diagrams/mindmap/svgDraw.ts index 8d3340c6e6..5670a8f6c5 100644 --- a/packages/mermaid/src/diagrams/mindmap/svgDraw.ts +++ b/packages/mermaid/src/diagrams/mindmap/svgDraw.ts @@ -1,7 +1,13 @@ +import type { D3Element } from '../../mermaidAPI.js'; import { createText } from '../../rendering-util/createText.js'; +import type { FilledMindMapNode, MindmapDB } from './mindmapTypes.js'; +import { MermaidConfigWithDefaults } from '../../config.js'; +import { Point } from '../../types.js'; const MAX_SECTIONS = 12; -const defaultBkg = function (db, elem, node, section) { +type ShapeFunction = (db: MindmapDB, elem: D3Element, node: FilledMindMapNode, section?: number) => void; + +const defaultBkg: ShapeFunction = function(db, elem, node, section) { const rd = 5; elem .append('path') @@ -9,8 +15,7 @@ const defaultBkg = function (db, elem, node, section) { .attr('class', 'node-bkg node-' + db.type2Str(node.type)) .attr( 'd', - `M0 ${node.height - rd} v${-node.height + 2 * rd} q0,-5 5,-5 h${ - node.width - 2 * rd + `M0 ${node.height - rd} v${-node.height + 2 * rd} q0,-5 5,-5 h${node.width - 2 * rd } q5,0 5,5 v${node.height - rd} H0 Z` ); @@ -23,7 +28,7 @@ const defaultBkg = function (db, elem, node, section) { .attr('y2', node.height); }; -const rectBkg = function (db, elem, node) { +const rectBkg: ShapeFunction = function(db, elem, node) { elem .append('rect') .attr('id', 'node-' + node.id) @@ -32,7 +37,7 @@ const rectBkg = function (db, elem, node) { .attr('width', node.width); }; -const cloudBkg = function (db, elem, node) { +const cloudBkg: ShapeFunction = function(db, elem, node) { const w = node.width; const h = node.height; const r1 = 0.15 * w; @@ -63,7 +68,7 @@ const cloudBkg = function (db, elem, node) { ); }; -const bangBkg = function (db, elem, node) { +const bangBkg: ShapeFunction = function(db, elem, node) { const w = node.width; const h = node.height; const r = 0.15 * w; @@ -95,7 +100,7 @@ const bangBkg = function (db, elem, node) { ); }; -const circleBkg = function (db, elem, node) { +const circleBkg: ShapeFunction = function(db, elem, node) { elem .append('circle') .attr('id', 'node-' + node.id) @@ -111,13 +116,13 @@ const circleBkg = function (db, elem, node) { * @param points * @param node */ -function insertPolygonShape(parent, w, h, points, node) { +function insertPolygonShape(parent: D3Element, w: number, h: number, points: Point[], node: FilledMindMapNode) { return parent .insert('polygon', ':first-child') .attr( 'points', points - .map(function (d) { + .map(function(d) { return d.x + ',' + d.y; }) .join(' ') @@ -125,12 +130,12 @@ function insertPolygonShape(parent, w, h, points, node) { .attr('transform', 'translate(' + (node.width - w) / 2 + ', ' + h + ')'); } -const hexagonBkg = function (db, elem, node) { +const hexagonBkg: ShapeFunction = function(_db: MindmapDB, elem: D3Element, node: FilledMindMapNode) { const h = node.height; const f = 4; const m = h / f; const w = node.width - node.padding + 2 * m; - const points = [ + const points: Point[] = [ { x: m, y: 0 }, { x: w - m, y: 0 }, { x: w, y: -h / 2 }, @@ -138,10 +143,10 @@ const hexagonBkg = function (db, elem, node) { { x: m, y: -h }, { x: 0, y: -h / 2 }, ]; - const shapeSvg = insertPolygonShape(elem, w, h, points, node); + insertPolygonShape(elem, w, h, points, node); }; -const roundedRectBkg = function (db, elem, node) { +const roundedRectBkg: ShapeFunction = function(db, elem, node) { elem .append('rect') .attr('id', 'node-' + node.id) @@ -153,14 +158,14 @@ const roundedRectBkg = function (db, elem, node) { }; /** - * @param {import('./mindmapTypes.js').MindmapDB} db The database - * @param {object} elem The D3 dom element in which the node is to be added - * @param {object} node The node to be added + * @param db The database + * @param elem The D3 dom element in which the node is to be added + * @param node The node to be added * @param fullSection - * @param {object} conf The configuration object - * @returns {number} The height nodes dom element + * @param conf The configuration object + * @returns The height nodes dom element */ -export const drawNode = function (db, elem, node, fullSection, conf) { +export const drawNode = function(db: MindmapDB, elem: D3Element, node: FilledMindMapNode, fullSection: number, conf: MermaidConfigWithDefaults): number { const htmlLabels = conf.htmlLabels; const section = fullSection % (MAX_SECTIONS - 1); const nodeElem = elem.append('g'); @@ -190,6 +195,7 @@ export const drawNode = function (db, elem, node, fullSection, conf) { } // .call(wrap, node.width); const bbox = textElem.node().getBBox(); + // @ts-expect-error TODO: Check if fontSize can be string? const fontSize = conf.fontSize.replace ? conf.fontSize.replace('px', '') : conf.fontSize; node.height = bbox.height + fontSize * 1.1 * 0.5 + node.padding; node.width = bbox.width + 2 * node.padding; @@ -247,26 +253,26 @@ export const drawNode = function (db, elem, node, fullSection, conf) { switch (node.type) { case db.nodeType.DEFAULT: - defaultBkg(db, bkgElem, node, section, conf); + defaultBkg(db, bkgElem, node, section); break; case db.nodeType.ROUNDED_RECT: - roundedRectBkg(db, bkgElem, node, section, conf); + roundedRectBkg(db, bkgElem, node, section); break; case db.nodeType.RECT: - rectBkg(db, bkgElem, node, section, conf); + rectBkg(db, bkgElem, node, section); break; case db.nodeType.CIRCLE: bkgElem.attr('transform', 'translate(' + node.width / 2 + ', ' + +node.height / 2 + ')'); - circleBkg(db, bkgElem, node, section, conf); + circleBkg(db, bkgElem, node, section); break; case db.nodeType.CLOUD: - cloudBkg(db, bkgElem, node, section, conf); + cloudBkg(db, bkgElem, node, section); break; case db.nodeType.BANG: - bangBkg(db, bkgElem, node, section, conf); + bangBkg(db, bkgElem, node, section); break; case db.nodeType.HEXAGON: - hexagonBkg(db, bkgElem, node, section, conf); + hexagonBkg(db, bkgElem, node, section); break; } @@ -274,7 +280,7 @@ export const drawNode = function (db, elem, node, fullSection, conf) { return node.height; }; -export const positionNode = function (db, node) { +export const positionNode = function(db: MindmapDB, node: FilledMindMapNode) { const nodeElem = db.getElementById(node.id); const x = node.x || 0; From d21461fba03dcd01ec82d7b152b2bb1ac786d4b4 Mon Sep 17 00:00:00 2001 From: Sidharth Vinod Date: Mon, 29 Jan 2024 12:27:17 +0530 Subject: [PATCH 176/217] Lint --- .../mermaid/src/diagrams/mindmap/mindmapDb.ts | 2 +- .../mermaid/src/diagrams/mindmap/svgDraw.ts | 48 ++++++++++++++----- 2 files changed, 36 insertions(+), 14 deletions(-) diff --git a/packages/mermaid/src/diagrams/mindmap/mindmapDb.ts b/packages/mermaid/src/diagrams/mindmap/mindmapDb.ts index c0fdd12574..e2b453a0d5 100644 --- a/packages/mermaid/src/diagrams/mindmap/mindmapDb.ts +++ b/packages/mermaid/src/diagrams/mindmap/mindmapDb.ts @@ -14,7 +14,7 @@ const clear = () => { elements = {}; }; -const getParent = function(level: number) { +const getParent = function (level: number) { for (let i = nodes.length - 1; i >= 0; i--) { if (nodes[i].level < level) { return nodes[i]; diff --git a/packages/mermaid/src/diagrams/mindmap/svgDraw.ts b/packages/mermaid/src/diagrams/mindmap/svgDraw.ts index 5670a8f6c5..8fe47468b0 100644 --- a/packages/mermaid/src/diagrams/mindmap/svgDraw.ts +++ b/packages/mermaid/src/diagrams/mindmap/svgDraw.ts @@ -5,9 +5,14 @@ import { MermaidConfigWithDefaults } from '../../config.js'; import { Point } from '../../types.js'; const MAX_SECTIONS = 12; -type ShapeFunction = (db: MindmapDB, elem: D3Element, node: FilledMindMapNode, section?: number) => void; +type ShapeFunction = ( + db: MindmapDB, + elem: D3Element, + node: FilledMindMapNode, + section?: number +) => void; -const defaultBkg: ShapeFunction = function(db, elem, node, section) { +const defaultBkg: ShapeFunction = function (db, elem, node, section) { const rd = 5; elem .append('path') @@ -15,7 +20,8 @@ const defaultBkg: ShapeFunction = function(db, elem, node, section) { .attr('class', 'node-bkg node-' + db.type2Str(node.type)) .attr( 'd', - `M0 ${node.height - rd} v${-node.height + 2 * rd} q0,-5 5,-5 h${node.width - 2 * rd + `M0 ${node.height - rd} v${-node.height + 2 * rd} q0,-5 5,-5 h${ + node.width - 2 * rd } q5,0 5,5 v${node.height - rd} H0 Z` ); @@ -28,7 +34,7 @@ const defaultBkg: ShapeFunction = function(db, elem, node, section) { .attr('y2', node.height); }; -const rectBkg: ShapeFunction = function(db, elem, node) { +const rectBkg: ShapeFunction = function (db, elem, node) { elem .append('rect') .attr('id', 'node-' + node.id) @@ -37,7 +43,7 @@ const rectBkg: ShapeFunction = function(db, elem, node) { .attr('width', node.width); }; -const cloudBkg: ShapeFunction = function(db, elem, node) { +const cloudBkg: ShapeFunction = function (db, elem, node) { const w = node.width; const h = node.height; const r1 = 0.15 * w; @@ -68,7 +74,7 @@ const cloudBkg: ShapeFunction = function(db, elem, node) { ); }; -const bangBkg: ShapeFunction = function(db, elem, node) { +const bangBkg: ShapeFunction = function (db, elem, node) { const w = node.width; const h = node.height; const r = 0.15 * w; @@ -100,7 +106,7 @@ const bangBkg: ShapeFunction = function(db, elem, node) { ); }; -const circleBkg: ShapeFunction = function(db, elem, node) { +const circleBkg: ShapeFunction = function (db, elem, node) { elem .append('circle') .attr('id', 'node-' + node.id) @@ -116,13 +122,19 @@ const circleBkg: ShapeFunction = function(db, elem, node) { * @param points * @param node */ -function insertPolygonShape(parent: D3Element, w: number, h: number, points: Point[], node: FilledMindMapNode) { +function insertPolygonShape( + parent: D3Element, + w: number, + h: number, + points: Point[], + node: FilledMindMapNode +) { return parent .insert('polygon', ':first-child') .attr( 'points', points - .map(function(d) { + .map(function (d) { return d.x + ',' + d.y; }) .join(' ') @@ -130,7 +142,11 @@ function insertPolygonShape(parent: D3Element, w: number, h: number, points: Poi .attr('transform', 'translate(' + (node.width - w) / 2 + ', ' + h + ')'); } -const hexagonBkg: ShapeFunction = function(_db: MindmapDB, elem: D3Element, node: FilledMindMapNode) { +const hexagonBkg: ShapeFunction = function ( + _db: MindmapDB, + elem: D3Element, + node: FilledMindMapNode +) { const h = node.height; const f = 4; const m = h / f; @@ -146,7 +162,7 @@ const hexagonBkg: ShapeFunction = function(_db: MindmapDB, elem: D3Element, node insertPolygonShape(elem, w, h, points, node); }; -const roundedRectBkg: ShapeFunction = function(db, elem, node) { +const roundedRectBkg: ShapeFunction = function (db, elem, node) { elem .append('rect') .attr('id', 'node-' + node.id) @@ -165,7 +181,13 @@ const roundedRectBkg: ShapeFunction = function(db, elem, node) { * @param conf The configuration object * @returns The height nodes dom element */ -export const drawNode = function(db: MindmapDB, elem: D3Element, node: FilledMindMapNode, fullSection: number, conf: MermaidConfigWithDefaults): number { +export const drawNode = function ( + db: MindmapDB, + elem: D3Element, + node: FilledMindMapNode, + fullSection: number, + conf: MermaidConfigWithDefaults +): number { const htmlLabels = conf.htmlLabels; const section = fullSection % (MAX_SECTIONS - 1); const nodeElem = elem.append('g'); @@ -280,7 +302,7 @@ export const drawNode = function(db: MindmapDB, elem: D3Element, node: FilledMin return node.height; }; -export const positionNode = function(db: MindmapDB, node: FilledMindMapNode) { +export const positionNode = function (db: MindmapDB, node: FilledMindMapNode) { const nodeElem = db.getElementById(node.id); const x = node.x || 0; From 4c551b2acacff1648c1cf982b79edc7d72bc589e Mon Sep 17 00:00:00 2001 From: Sidharth Vinod Date: Mon, 29 Jan 2024 12:35:39 +0530 Subject: [PATCH 177/217] Lint --- .../src/diagrams/mindmap/mindmapTypes.ts | 2 +- .../mermaid/src/diagrams/mindmap/svgDraw.ts | 22 ++++++------------- 2 files changed, 8 insertions(+), 16 deletions(-) diff --git a/packages/mermaid/src/diagrams/mindmap/mindmapTypes.ts b/packages/mermaid/src/diagrams/mindmap/mindmapTypes.ts index ced93ecacb..e8350477a9 100644 --- a/packages/mermaid/src/diagrams/mindmap/mindmapTypes.ts +++ b/packages/mermaid/src/diagrams/mindmap/mindmapTypes.ts @@ -1,4 +1,4 @@ -import { RequiredDeep } from 'type-fest'; +import type { RequiredDeep } from 'type-fest'; import type mindmapDb from './mindmapDb.js'; export interface MindmapNode { diff --git a/packages/mermaid/src/diagrams/mindmap/svgDraw.ts b/packages/mermaid/src/diagrams/mindmap/svgDraw.ts index 8fe47468b0..797a3fd990 100644 --- a/packages/mermaid/src/diagrams/mindmap/svgDraw.ts +++ b/packages/mermaid/src/diagrams/mindmap/svgDraw.ts @@ -1,8 +1,8 @@ import type { D3Element } from '../../mermaidAPI.js'; import { createText } from '../../rendering-util/createText.js'; import type { FilledMindMapNode, MindmapDB } from './mindmapTypes.js'; -import { MermaidConfigWithDefaults } from '../../config.js'; -import { Point } from '../../types.js'; +import type { MermaidConfigWithDefaults } from '../../config.js'; +import type { Point } from '../../types.js'; const MAX_SECTIONS = 12; type ShapeFunction = ( @@ -114,14 +114,6 @@ const circleBkg: ShapeFunction = function (db, elem, node) { .attr('r', node.width / 2); }; -/** - * - * @param parent - * @param w - * @param h - * @param points - * @param node - */ function insertPolygonShape( parent: D3Element, w: number, @@ -174,11 +166,11 @@ const roundedRectBkg: ShapeFunction = function (db, elem, node) { }; /** - * @param db The database - * @param elem The D3 dom element in which the node is to be added - * @param node The node to be added - * @param fullSection - * @param conf The configuration object + * @param db - The database + * @param elem - The D3 dom element in which the node is to be added + * @param node - The node to be added + * @param fullSection - ? + * @param conf - The configuration object * @returns The height nodes dom element */ export const drawNode = function ( From a4a94fd6e2e913c09688acec4170e99de3e33a39 Mon Sep 17 00:00:00 2001 From: Sidharth Vinod Date: Mon, 29 Jan 2024 13:55:51 +0530 Subject: [PATCH 178/217] Update to Node v20 --- .github/workflows/build.yml | 2 +- .github/workflows/e2e-applitools.yml | 2 +- .github/workflows/e2e.yml | 4 ++-- .github/workflows/lint.yml | 2 +- .github/workflows/release-preview-publish.yml | 2 +- .github/workflows/release-publish.yml | 2 +- .github/workflows/test.yml | 2 +- Dockerfile | 2 +- package.json | 5 +---- 9 files changed, 10 insertions(+), 13 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 605dea9ab3..0b3197df74 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -17,7 +17,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - node-version: [18.x] + node-version: [20.x] steps: - uses: actions/checkout@v4 diff --git a/.github/workflows/e2e-applitools.yml b/.github/workflows/e2e-applitools.yml index fd32e59adf..6be95bd515 100644 --- a/.github/workflows/e2e-applitools.yml +++ b/.github/workflows/e2e-applitools.yml @@ -23,7 +23,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - node-version: [18.x] + node-version: [20.x] steps: - if: ${{ ! env.USE_APPLI }} name: Warn if not using Applitools diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e.yml index b8232b8c0e..0d94de7bd2 100644 --- a/.github/workflows/e2e.yml +++ b/.github/workflows/e2e.yml @@ -29,7 +29,7 @@ jobs: - name: Setup Node.js uses: actions/setup-node@v4 with: - node-version: 18.x + node-version: 20.x - name: Cache snapshots id: cache-snapshot uses: actions/cache@v4 @@ -60,7 +60,7 @@ jobs: strategy: fail-fast: false matrix: - node-version: [18.x] + node-version: [20.x] containers: [1, 2, 3, 4] steps: - uses: actions/checkout@v4 diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index f0c5560a1e..3255977ee0 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -18,7 +18,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - node-version: [18.x] + node-version: [20.x] steps: - uses: actions/checkout@v4 diff --git a/.github/workflows/release-preview-publish.yml b/.github/workflows/release-preview-publish.yml index c6503847d9..3c97ce9c5d 100644 --- a/.github/workflows/release-preview-publish.yml +++ b/.github/workflows/release-preview-publish.yml @@ -19,7 +19,7 @@ jobs: uses: actions/setup-node@v4 with: cache: pnpm - node-version: 18.x + node-version: 20.x - name: Install Packages run: | diff --git a/.github/workflows/release-publish.yml b/.github/workflows/release-publish.yml index 69ef749402..abf05ea6a7 100644 --- a/.github/workflows/release-publish.yml +++ b/.github/workflows/release-publish.yml @@ -18,7 +18,7 @@ jobs: uses: actions/setup-node@v4 with: cache: pnpm - node-version: 18.x + node-version: 20.x - name: Install Packages run: | diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index a18b31c9cd..fd390d0023 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -10,7 +10,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - node-version: [18.x] + node-version: [20.x] steps: - uses: actions/checkout@v4 diff --git a/Dockerfile b/Dockerfile index a62800109c..33a1ebd377 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,2 +1,2 @@ -FROM node:18.19.0-alpine3.18 AS base +FROM node:20.11.0-alpine3.19 AS base RUN wget -qO- https://get.pnpm.io/install.sh | ENV="$HOME/.shrc" SHELL="$(which sh)" sh - diff --git a/package.json b/package.json index 441484218d..82dcccd548 100644 --- a/package.json +++ b/package.json @@ -74,7 +74,7 @@ "@types/jsdom": "^21.1.1", "@types/lodash": "^4.14.194", "@types/mdast": "^3.0.11", - "@types/node": "^18.16.0", + "@types/node": "^20.11.10", "@types/prettier": "^2.7.2", "@types/rollup-plugin-visualizer": "^4.2.1", "@typescript-eslint/eslint-plugin": "^6.7.2", @@ -122,9 +122,6 @@ "vite-plugin-istanbul": "^4.1.0", "vitest": "^0.34.0" }, - "volta": { - "node": "18.19.0" - }, "nyc": { "report-dir": "coverage/cypress" } From 52bb31b98aea9359138c00e7480830976e40a2e7 Mon Sep 17 00:00:00 2001 From: Sidharth Vinod Date: Mon, 29 Jan 2024 13:56:03 +0530 Subject: [PATCH 179/217] Update to Node v20 --- .node-version | 1 + pnpm-lock.yaml | 177 ++++++++++++++++++++++++++----------------------- 2 files changed, 94 insertions(+), 84 deletions(-) create mode 100644 .node-version diff --git a/.node-version b/.node-version new file mode 100644 index 0000000000..7ea6a59d34 --- /dev/null +++ b/.node-version @@ -0,0 +1 @@ +v20.11.0 diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 5d950edefc..583f5f1232 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -48,8 +48,8 @@ importers: specifier: ^3.0.11 version: 3.0.12 '@types/node': - specifier: ^18.16.0 - version: 18.17.5 + specifier: ^20.11.10 + version: 20.11.10 '@types/prettier': specifier: ^2.7.2 version: 2.7.2 @@ -136,7 +136,7 @@ importers: version: 8.0.3 jest: specifier: ^29.5.0 - version: 29.6.2(@types/node@18.17.5)(ts-node@10.9.1) + version: 29.6.2(@types/node@20.11.10)(ts-node@10.9.1) jison: specifier: ^0.4.18 version: 0.4.18 @@ -181,7 +181,7 @@ importers: version: 5.1.6 vite: specifier: ^4.4.12 - version: 4.4.12(@types/node@18.17.5) + version: 4.4.12(@types/node@20.11.10) vite-plugin-istanbul: specifier: ^4.1.0 version: 4.1.0(vite@4.4.12) @@ -374,7 +374,7 @@ importers: version: 4.1.2 vitepress: specifier: ^1.0.0-alpha.72 - version: 1.0.0-alpha.72(@algolia/client-search@4.19.1)(@types/node@18.17.5)(search-insights@2.7.0) + version: 1.0.0-alpha.72(@algolia/client-search@4.19.1)(@types/node@20.11.10)(search-insights@2.7.0) vitepress-plugin-search: specifier: ^1.0.4-alpha.20 version: 1.0.4-alpha.20(flexsearch@0.7.31)(vitepress@1.0.0-alpha.72)(vue@3.4.15) @@ -470,13 +470,13 @@ importers: version: 0.26.0(rollup@2.79.1)(vue@3.3.4) vite: specifier: ^4.4.12 - version: 4.5.0(@types/node@18.17.5) + version: 4.5.0(@types/node@20.11.10) vite-plugin-pwa: specifier: ^0.17.0 version: 0.17.0(vite@4.5.0)(workbox-build@7.0.0)(workbox-window@7.0.0) vitepress: specifier: 1.0.0-rc.39 - version: 1.0.0-rc.39(@algolia/client-search@4.19.1)(@types/node@18.17.5)(postcss@8.4.33)(search-insights@2.7.0)(typescript@5.1.6) + version: 1.0.0-rc.39(@algolia/client-search@4.19.1)(@types/node@20.11.10)(postcss@8.4.33)(search-insights@2.7.0)(typescript@5.1.6) workbox-window: specifier: ^7.0.0 version: 7.0.0 @@ -2662,7 +2662,7 @@ packages: lodash.merge: 4.6.2 lodash.uniq: 4.5.0 resolve-from: 5.0.0 - ts-node: 10.9.1(@types/node@18.17.5)(typescript@5.1.6) + ts-node: 10.9.1(@types/node@20.11.10)(typescript@5.1.6) typescript: 5.1.6 transitivePeerDependencies: - '@swc/core' @@ -3997,7 +3997,7 @@ packages: engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: '@jest/types': 29.6.1 - '@types/node': 18.17.5 + '@types/node': 20.11.10 chalk: 4.1.2 jest-message-util: 29.6.2 jest-util: 29.6.2 @@ -4018,14 +4018,14 @@ packages: '@jest/test-result': 29.6.2 '@jest/transform': 29.6.2 '@jest/types': 29.6.1 - '@types/node': 18.17.5 + '@types/node': 20.11.10 ansi-escapes: 4.3.2 chalk: 4.1.2 ci-info: 3.8.0 exit: 0.1.2 graceful-fs: 4.2.11 jest-changed-files: 29.5.0 - jest-config: 29.6.2(@types/node@18.17.5)(ts-node@10.9.1) + jest-config: 29.6.2(@types/node@20.11.10)(ts-node@10.9.1) jest-haste-map: 29.6.2 jest-message-util: 29.6.2 jest-regex-util: 29.4.3 @@ -4053,7 +4053,7 @@ packages: dependencies: '@jest/fake-timers': 29.6.2 '@jest/types': 29.6.1 - '@types/node': 18.17.5 + '@types/node': 20.11.10 jest-mock: 29.6.2 dev: true @@ -4080,7 +4080,7 @@ packages: dependencies: '@jest/types': 29.6.1 '@sinonjs/fake-timers': 10.3.0 - '@types/node': 18.17.5 + '@types/node': 20.11.10 jest-message-util: 29.6.2 jest-mock: 29.6.2 jest-util: 29.6.2 @@ -4113,7 +4113,7 @@ packages: '@jest/transform': 29.6.2 '@jest/types': 29.6.1 '@jridgewell/trace-mapping': 0.3.19 - '@types/node': 18.17.5 + '@types/node': 20.11.10 chalk: 4.1.2 collect-v8-coverage: 1.0.2 exit: 0.1.2 @@ -4201,7 +4201,7 @@ packages: '@jest/schemas': 29.6.0 '@types/istanbul-lib-coverage': 2.0.4 '@types/istanbul-reports': 3.0.1 - '@types/node': 18.17.5 + '@types/node': 20.11.10 '@types/yargs': 17.0.24 chalk: 4.1.2 dev: true @@ -4612,13 +4612,13 @@ packages: resolution: {integrity: sha512-ALYone6pm6QmwZoAgeyNksccT9Q4AWZQ6PvfwR37GT6r6FWUPguq6sUmNGSMV2Wr761oQoBxwGGa6DR5o1DC9g==} dependencies: '@types/connect': 3.4.35 - '@types/node': 18.17.5 + '@types/node': 20.11.10 dev: true /@types/bonjour@3.5.10: resolution: {integrity: sha512-p7ienRMiS41Nu2/igbJxxLDWrSZ0WxM8UQgCeO9KhoVF7cOVFkrKsiDr1EsJIla8vV3oEEjGcz11jc5yimhzZw==} dependencies: - '@types/node': 18.17.5 + '@types/node': 20.11.10 dev: true /@types/braces@3.0.2: @@ -4630,7 +4630,7 @@ packages: dependencies: '@types/http-cache-semantics': 4.0.1 '@types/keyv': 3.1.4 - '@types/node': 18.17.5 + '@types/node': 20.11.10 '@types/responselike': 1.0.0 dev: true @@ -4648,19 +4648,19 @@ packages: resolution: {integrity: sha512-4x5FkPpLipqwthjPsF7ZRbOv3uoLUFkTA9G9v583qi4pACvq0uTELrB8OLUzPWUI4IJIyvM85vzkV1nyiI2Lig==} dependencies: '@types/express-serve-static-core': 4.17.35 - '@types/node': 18.17.5 + '@types/node': 20.11.10 dev: true /@types/connect@3.4.35: resolution: {integrity: sha512-cdeYyv4KWoEgpBISTxWvqYsVy444DOqehiF3fM3ne10AmJ62RSyNkUnxMJXHQWRQQX2eR94m5y1IZyDwBjV9FQ==} dependencies: - '@types/node': 18.17.5 + '@types/node': 20.11.10 dev: true /@types/cors@2.8.13: resolution: {integrity: sha512-RG8AStHlUiV5ysZQKq97copd2UmVYw3/pRMLefISZ3S1hK104Cwm7iLQ3fTKx+lsUH2CE8FlLaYeEA2LSeqYUA==} dependencies: - '@types/node': 18.17.5 + '@types/node': 20.11.10 dev: true /@types/cytoscape@3.19.9: @@ -4895,7 +4895,7 @@ packages: /@types/express-serve-static-core@4.17.35: resolution: {integrity: sha512-wALWQwrgiB2AWTT91CB62b6Yt0sNHpznUXeZEcnPU3DRdlDIz74x8Qg1UUYKSVFi+va5vKOLYRBI1bRKiLLKIg==} dependencies: - '@types/node': 18.17.5 + '@types/node': 20.11.10 '@types/qs': 6.9.7 '@types/range-parser': 1.2.4 '@types/send': 0.17.1 @@ -4922,20 +4922,20 @@ packages: resolution: {integrity: sha512-ZUxbzKl0IfJILTS6t7ip5fQQM/J3TJYubDm3nMbgubNNYS62eXeUpoLUC8/7fJNiFYHTrGPQn7hspDUzIHX3UA==} dependencies: '@types/minimatch': 5.1.2 - '@types/node': 18.17.5 + '@types/node': 20.11.10 dev: true /@types/glob@8.1.0: resolution: {integrity: sha512-IO+MJPVhoqz+28h1qLAcBEH2+xHMK6MTyHJc7MTnnYb6wsoLR29POVGJ7LycmVXIqyy/4/2ShP5sUwTXuOwb/w==} dependencies: '@types/minimatch': 5.1.2 - '@types/node': 18.17.5 + '@types/node': 20.11.10 dev: true /@types/graceful-fs@4.1.6: resolution: {integrity: sha512-Sig0SNORX9fdW+bQuTEovKj3uHcUL6LQKbCrrqb1X7J6/ReAbhCXRAhc+SMejhLELFj2QcyuxmUooZ4bt5ReSw==} dependencies: - '@types/node': 18.17.5 + '@types/node': 20.11.10 dev: true /@types/http-cache-semantics@4.0.1: @@ -4949,7 +4949,7 @@ packages: /@types/http-proxy@1.17.11: resolution: {integrity: sha512-HC8G7c1WmaF2ekqpnFq626xd3Zz0uvaqFmBJNRZCGEZCXkvSdJoNFn/8Ygbd9fKNQj8UzLdCETaI0UWPAjK7IA==} dependencies: - '@types/node': 18.17.5 + '@types/node': 20.11.10 dev: true /@types/istanbul-lib-coverage@2.0.4: @@ -4987,7 +4987,7 @@ packages: /@types/keyv@3.1.4: resolution: {integrity: sha512-BQ5aZNSCpj7D6K2ksrRCTmKRLEpnPvWDiLPfoGyhZ++8YtiK9d/3DBKPJgry359X/P1PfruyYwvnvwFjuEiEIg==} dependencies: - '@types/node': 18.17.5 + '@types/node': 20.11.10 dev: true /@types/linkify-it@3.0.2: @@ -5058,6 +5058,12 @@ packages: /@types/node@18.17.5: resolution: {integrity: sha512-xNbS75FxH6P4UXTPUJp/zNPq6/xsfdJKussCWNOnz4aULWIRwMgP1LgaB5RiBnMX1DPCYenuqGZfnIAx5mbFLA==} + dev: true + + /@types/node@20.11.10: + resolution: {integrity: sha512-rZEfe/hJSGYmdfX9tvcPMYeYPW2sNl50nsw4jZmRcaG0HIAb0WYEpsB05GOb53vjqpyE9GUhlDQ4jLSoB5q9kg==} + dependencies: + undici-types: 5.26.5 /@types/node@20.4.7: resolution: {integrity: sha512-bUBrPjEry2QUTsnuEjzjbS7voGWCc30W0qzgMf90GPeDGFRakvrz47ju+oqDAKCXLUCe39u57/ORMl/O/04/9g==} @@ -5088,13 +5094,13 @@ packages: /@types/resolve@1.17.1: resolution: {integrity: sha512-yy7HuzQhj0dhGpD8RLXSZWEkLsV9ibvxvi6EiJ3bkqLAO1RGo0WbkWQiwpRlSFymTJRz0d3k5LM3kkx8ArDbLw==} dependencies: - '@types/node': 18.17.5 + '@types/node': 20.11.10 dev: true /@types/responselike@1.0.0: resolution: {integrity: sha512-85Y2BjiufFzaMIlvJDvTTB8Fxl2xfLo4HgmHzVBz08w4wDePCTjYw66PdrolO0kzli3yam/YCgRufyo1DdQVTA==} dependencies: - '@types/node': 18.17.5 + '@types/node': 20.11.10 dev: true /@types/retry@0.12.0: @@ -5104,7 +5110,7 @@ packages: /@types/rollup-plugin-visualizer@4.2.1: resolution: {integrity: sha512-Fk4y0EgmsSbvbayYhtSI9+cGvgw1rcQ9RlbExkQt4ivXRdiEwFKuRpxNuJCr0JktXIvOPUuPR7GSmtyZu0dujQ==} dependencies: - '@types/node': 18.17.5 + '@types/node': 20.11.10 rollup: 2.79.1 dev: true @@ -5116,7 +5122,7 @@ packages: resolution: {integrity: sha512-Cwo8LE/0rnvX7kIIa3QHCkcuF21c05Ayb0ZfxPiv0W8VRiZiNW/WuRupHKpqqGVGf7SUA44QSOUKaEd9lIrd/Q==} dependencies: '@types/mime': 1.3.2 - '@types/node': 18.17.5 + '@types/node': 20.11.10 dev: true /@types/serve-index@1.9.1: @@ -5130,7 +5136,7 @@ packages: dependencies: '@types/http-errors': 2.0.1 '@types/mime': 3.0.1 - '@types/node': 18.17.5 + '@types/node': 20.11.10 dev: true /@types/sinonjs__fake-timers@8.1.1: @@ -5144,7 +5150,7 @@ packages: /@types/sockjs@0.3.33: resolution: {integrity: sha512-f0KEEe05NvUnat+boPTZ0dgaLZ4SfSouXUgv5noUiefG2ajgKjmETo9ZJyuqsl7dfl2aHlLJUiki6B4ZYldiiw==} dependencies: - '@types/node': 18.17.5 + '@types/node': 20.11.10 dev: true /@types/stack-utils@2.0.1: @@ -5185,7 +5191,7 @@ packages: /@types/ws@8.5.5: resolution: {integrity: sha512-lwhs8hktwxSjf9UaZ9tG5M03PGogvFaH8gUgLNbN9HKIg0dvv6q+gkSuJ8HN4/VbyxkuLzCjlN7GquQ0gUJfIg==} dependencies: - '@types/node': 18.17.5 + '@types/node': 20.11.10 dev: true /@types/yargs-parser@21.0.0: @@ -5202,7 +5208,7 @@ packages: resolution: {integrity: sha512-Cn6WYCm0tXv8p6k+A8PvbDG763EDpBoTzHdA+Q/MF6H3sapGjCm9NzoaJncJS9tUKSuCoDs9XHxYYsQDgxR6kw==} requiresBuild: true dependencies: - '@types/node': 18.17.5 + '@types/node': 20.11.10 dev: true optional: true @@ -5540,7 +5546,7 @@ packages: '@unocss/core': 0.58.0 '@unocss/reset': 0.58.0 '@unocss/vite': 0.58.0(rollup@2.79.1)(vite@4.5.0) - vite: 4.5.0(@types/node@18.17.5) + vite: 4.5.0(@types/node@20.11.10) transitivePeerDependencies: - rollup dev: true @@ -5738,7 +5744,7 @@ packages: chokidar: 3.5.3 fast-glob: 3.3.2 magic-string: 0.30.5 - vite: 4.5.0(@types/node@18.17.5) + vite: 4.5.0(@types/node@20.11.10) transitivePeerDependencies: - rollup dev: true @@ -5758,7 +5764,7 @@ packages: vite: ^4.0.0 vue: ^3.2.25 dependencies: - vite: 4.5.0(@types/node@18.17.5) + vite: 4.5.0(@types/node@20.11.10) vue: 3.3.4 dev: true @@ -5769,7 +5775,7 @@ packages: vite: ^4.0.0 vue: ^3.2.25 dependencies: - vite: 4.5.0(@types/node@18.17.5) + vite: 4.5.0(@types/node@20.11.10) vue: 3.3.4 dev: true @@ -5780,7 +5786,7 @@ packages: vite: ^5.0.0 vue: ^3.2.25 dependencies: - vite: 5.0.11(@types/node@18.17.5) + vite: 5.0.11(@types/node@20.11.10) vue: 3.4.15(typescript@5.1.6) dev: true @@ -7756,7 +7762,7 @@ packages: dependencies: '@types/node': 20.4.7 cosmiconfig: 8.2.0 - ts-node: 10.9.1(@types/node@18.17.5)(typescript@5.1.6) + ts-node: 10.9.1(@types/node@20.11.10)(typescript@5.1.6) typescript: 5.1.6 dev: true @@ -9266,7 +9272,7 @@ packages: '@typescript-eslint/eslint-plugin': 6.7.2(@typescript-eslint/parser@6.7.2)(eslint@8.47.0)(typescript@5.1.6) '@typescript-eslint/utils': 5.62.0(eslint@8.47.0)(typescript@5.1.6) eslint: 8.47.0 - jest: 29.6.2(@types/node@18.17.5)(ts-node@10.9.1) + jest: 29.6.2(@types/node@20.11.10)(ts-node@10.9.1) transitivePeerDependencies: - supports-color - typescript @@ -9614,7 +9620,7 @@ packages: engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: '@jest/expect-utils': 29.6.2 - '@types/node': 18.17.5 + '@types/node': 20.11.10 jest-get-type: 29.4.3 jest-matcher-utils: 29.6.2 jest-message-util: 29.6.2 @@ -11287,7 +11293,7 @@ packages: '@jest/expect': 29.6.2 '@jest/test-result': 29.6.2 '@jest/types': 29.6.1 - '@types/node': 18.17.5 + '@types/node': 20.11.10 chalk: 4.1.2 co: 4.6.0 dedent: 1.5.1 @@ -11308,7 +11314,7 @@ packages: - supports-color dev: true - /jest-cli@29.6.2(@types/node@18.17.5)(ts-node@10.9.1): + /jest-cli@29.6.2(@types/node@20.11.10)(ts-node@10.9.1): resolution: {integrity: sha512-TT6O247v6dCEX2UGHGyflMpxhnrL0DNqP2fRTKYm3nJJpCTfXX3GCMQPGFjXDoj0i5/Blp3jriKXFgdfmbYB6Q==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} hasBin: true @@ -11325,7 +11331,7 @@ packages: exit: 0.1.2 graceful-fs: 4.2.11 import-local: 3.1.0 - jest-config: 29.6.2(@types/node@18.17.5)(ts-node@10.9.1) + jest-config: 29.6.2(@types/node@20.11.10)(ts-node@10.9.1) jest-util: 29.6.2 jest-validate: 29.6.2 prompts: 2.4.2 @@ -11337,7 +11343,7 @@ packages: - ts-node dev: true - /jest-config@29.6.2(@types/node@18.17.5)(ts-node@10.9.1): + /jest-config@29.6.2(@types/node@20.11.10)(ts-node@10.9.1): resolution: {integrity: sha512-VxwFOC8gkiJbuodG9CPtMRjBUNZEHxwfQXmIudSTzFWxaci3Qub1ddTRbFNQlD/zUeaifLndh/eDccFX4wCMQw==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} peerDependencies: @@ -11352,7 +11358,7 @@ packages: '@babel/core': 7.22.10 '@jest/test-sequencer': 29.6.2 '@jest/types': 29.6.1 - '@types/node': 18.17.5 + '@types/node': 20.11.10 babel-jest: 29.6.2(@babel/core@7.22.10) chalk: 4.1.2 ci-info: 3.8.0 @@ -11372,7 +11378,7 @@ packages: pretty-format: 29.6.2 slash: 3.0.0 strip-json-comments: 3.1.1 - ts-node: 10.9.1(@types/node@18.17.5)(typescript@5.1.6) + ts-node: 10.9.1(@types/node@20.11.10)(typescript@5.1.6) transitivePeerDependencies: - babel-plugin-macros - supports-color @@ -11413,7 +11419,7 @@ packages: '@jest/environment': 29.6.2 '@jest/fake-timers': 29.6.2 '@jest/types': 29.6.1 - '@types/node': 18.17.5 + '@types/node': 20.11.10 jest-mock: 29.6.2 jest-util: 29.6.2 dev: true @@ -11429,7 +11435,7 @@ packages: dependencies: '@jest/types': 29.6.1 '@types/graceful-fs': 4.1.6 - '@types/node': 18.17.5 + '@types/node': 20.11.10 anymatch: 3.1.3 fb-watchman: 2.0.2 graceful-fs: 4.2.11 @@ -11451,7 +11457,7 @@ packages: chalk: 1.1.3 get-stdin: 5.0.1 glur: 1.1.2 - jest: 29.6.2(@types/node@18.17.5)(ts-node@10.9.1) + jest: 29.6.2(@types/node@20.11.10)(ts-node@10.9.1) lodash: 4.17.21 mkdirp: 0.5.6 pixelmatch: 5.3.0 @@ -11498,7 +11504,7 @@ packages: engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: '@jest/types': 29.6.1 - '@types/node': 18.17.5 + '@types/node': 20.11.10 jest-util: 29.6.2 dev: true @@ -11553,7 +11559,7 @@ packages: '@jest/test-result': 29.6.2 '@jest/transform': 29.6.2 '@jest/types': 29.6.1 - '@types/node': 18.17.5 + '@types/node': 20.11.10 chalk: 4.1.2 emittery: 0.13.1 graceful-fs: 4.2.11 @@ -11584,7 +11590,7 @@ packages: '@jest/test-result': 29.6.2 '@jest/transform': 29.6.2 '@jest/types': 29.6.1 - '@types/node': 18.17.5 + '@types/node': 20.11.10 chalk: 4.1.2 cjs-module-lexer: 1.2.3 collect-v8-coverage: 1.0.2 @@ -11636,7 +11642,7 @@ packages: engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: '@jest/types': 29.6.1 - '@types/node': 18.17.5 + '@types/node': 20.11.10 chalk: 4.1.2 ci-info: 3.8.0 graceful-fs: 4.2.11 @@ -11661,7 +11667,7 @@ packages: dependencies: '@jest/test-result': 29.6.2 '@jest/types': 29.6.1 - '@types/node': 18.17.5 + '@types/node': 20.11.10 ansi-escapes: 4.3.2 chalk: 4.1.2 emittery: 0.13.1 @@ -11673,7 +11679,7 @@ packages: resolution: {integrity: sha512-KWYVV1c4i+jbMpaBC+U++4Va0cp8OisU185o73T1vo99hqi7w8tSJfUXYswwqqrjzwxa6KpRK54WhPvwf5w6PQ==} engines: {node: '>= 10.13.0'} dependencies: - '@types/node': 18.17.5 + '@types/node': 20.11.10 merge-stream: 2.0.0 supports-color: 7.2.0 dev: true @@ -11682,7 +11688,7 @@ packages: resolution: {integrity: sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==} engines: {node: '>= 10.13.0'} dependencies: - '@types/node': 18.17.5 + '@types/node': 20.11.10 merge-stream: 2.0.0 supports-color: 8.1.1 dev: true @@ -11691,13 +11697,13 @@ packages: resolution: {integrity: sha512-l3ccBOabTdkng8I/ORCkADz4eSMKejTYv1vB/Z83UiubqhC1oQ5Li6dWCyqOIvSifGjUBxuvxvlm6KGK2DtuAQ==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: - '@types/node': 18.17.5 + '@types/node': 20.11.10 jest-util: 29.6.2 merge-stream: 2.0.0 supports-color: 8.1.1 dev: true - /jest@29.6.2(@types/node@18.17.5)(ts-node@10.9.1): + /jest@29.6.2(@types/node@20.11.10)(ts-node@10.9.1): resolution: {integrity: sha512-8eQg2mqFbaP7CwfsTpCxQ+sHzw1WuNWL5UUvjnWP4hx2riGz9fPSzYOaU5q8/GqWn1TfgZIVTqYJygbGbWAANg==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} hasBin: true @@ -11710,7 +11716,7 @@ packages: '@jest/core': 29.6.2(ts-node@10.9.1) '@jest/types': 29.6.1 import-local: 3.1.0 - jest-cli: 29.6.2(@types/node@18.17.5)(ts-node@10.9.1) + jest-cli: 29.6.2(@types/node@20.11.10)(ts-node@10.9.1) transitivePeerDependencies: - '@types/node' - babel-plugin-macros @@ -13790,7 +13796,7 @@ packages: dependencies: lilconfig: 2.1.0 postcss: 8.4.31 - ts-node: 10.9.1(@types/node@18.17.5)(typescript@5.1.6) + ts-node: 10.9.1(@types/node@20.11.10)(typescript@5.1.6) yaml: 2.3.1 dev: false @@ -15582,7 +15588,7 @@ packages: resolution: {integrity: sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==} dev: false - /ts-node@10.9.1(@types/node@18.17.5)(typescript@5.1.6): + /ts-node@10.9.1(@types/node@20.11.10)(typescript@5.1.6): resolution: {integrity: sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==} hasBin: true peerDependencies: @@ -15601,7 +15607,7 @@ packages: '@tsconfig/node12': 1.0.11 '@tsconfig/node14': 1.0.3 '@tsconfig/node16': 1.0.4 - '@types/node': 18.17.5 + '@types/node': 20.11.10 acorn: 8.10.0 acorn-walk: 8.2.0 arg: 4.1.3 @@ -15856,6 +15862,9 @@ packages: resolution: {integrity: sha512-w4QtCHoLBXw1mjofIDoMyexaEdWGMedWNDhlWTtT1V1lCRqi65Pnoygkh6+WRdr+Bm8ldkBNkNeCsXGMlQS9HQ==} dev: true + /undici-types@5.26.5: + resolution: {integrity: sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==} + /unicode-canonical-property-names-ecmascript@2.0.0: resolution: {integrity: sha512-yY5PpDlfVIU5+y/BSCxAJRBIS1Zc2dDG3Ujq+sR0U+JjUevW2JhocOF+soROYDSaAezOzOKuyyixhD6mBknSmQ==} engines: {node: '>=4'} @@ -15987,7 +15996,7 @@ packages: '@unocss/transformer-directives': 0.58.0 '@unocss/transformer-variant-group': 0.58.0 '@unocss/vite': 0.58.0(rollup@2.79.1)(vite@4.5.0) - vite: 4.5.0(@types/node@18.17.5) + vite: 4.5.0(@types/node@20.11.10) transitivePeerDependencies: - postcss - rollup @@ -16148,7 +16157,7 @@ packages: vfile-message: 3.1.4 dev: true - /vite-node@0.34.0(@types/node@18.17.5): + /vite-node@0.34.0(@types/node@20.11.10): resolution: {integrity: sha512-rGZMvpb052rjUwJA/a17xMfOibzNF7byMdRSTcN2Lw8uxX08s5EfjWW5mBkm3MSFTPctMSVtT2yC+8ShrZbT5g==} engines: {node: '>=v14.18.0'} hasBin: true @@ -16158,7 +16167,7 @@ packages: mlly: 1.4.2 pathe: 1.1.1 picocolors: 1.0.0 - vite: 4.5.0(@types/node@18.17.5) + vite: 4.5.0(@types/node@20.11.10) transitivePeerDependencies: - '@types/node' - less @@ -16179,7 +16188,7 @@ packages: istanbul-lib-instrument: 5.2.1 picocolors: 1.0.0 test-exclude: 6.0.0 - vite: 4.4.12(@types/node@18.17.5) + vite: 4.4.12(@types/node@20.11.10) transitivePeerDependencies: - supports-color dev: true @@ -16195,14 +16204,14 @@ packages: debug: 4.3.4(supports-color@8.1.1) fast-glob: 3.3.2 pretty-bytes: 6.1.1 - vite: 4.5.0(@types/node@18.17.5) + vite: 4.5.0(@types/node@20.11.10) workbox-build: 7.0.0 workbox-window: 7.0.0 transitivePeerDependencies: - supports-color dev: true - /vite@4.4.12(@types/node@18.17.5): + /vite@4.4.12(@types/node@20.11.10): resolution: {integrity: sha512-KtPlUbWfxzGVul8Nut8Gw2Qe8sBzWY+8QVc5SL8iRFnpnrcoCaNlzO40c1R6hPmcdTwIPEDkq0Y9+27a5tVbdQ==} engines: {node: ^14.18.0 || >=16.0.0} hasBin: true @@ -16230,7 +16239,7 @@ packages: terser: optional: true dependencies: - '@types/node': 18.17.5 + '@types/node': 20.11.10 esbuild: 0.18.20 postcss: 8.4.31 rollup: 3.28.0 @@ -16238,7 +16247,7 @@ packages: fsevents: 2.3.3 dev: true - /vite@4.5.0(@types/node@18.17.5): + /vite@4.5.0(@types/node@20.11.10): resolution: {integrity: sha512-ulr8rNLA6rkyFAlVWw2q5YJ91v098AFQ2R0PRFwPzREXOUJQPtFUG0t+/ZikhaOCDqFoDhN6/v8Sq0o4araFAw==} engines: {node: ^14.18.0 || >=16.0.0} hasBin: true @@ -16266,7 +16275,7 @@ packages: terser: optional: true dependencies: - '@types/node': 18.17.5 + '@types/node': 20.11.10 esbuild: 0.18.20 postcss: 8.4.31 rollup: 3.28.0 @@ -16274,7 +16283,7 @@ packages: fsevents: 2.3.3 dev: true - /vite@5.0.11(@types/node@18.17.5): + /vite@5.0.11(@types/node@20.11.10): resolution: {integrity: sha512-XBMnDjZcNAw/G1gEiskiM1v6yzM4GE5aMGvhWTlHAYYhxb7S3/V1s3m2LDHa8Vh6yIWYYB0iJwsEaS523c4oYA==} engines: {node: ^18.0.0 || >=20.0.0} hasBin: true @@ -16302,7 +16311,7 @@ packages: terser: optional: true dependencies: - '@types/node': 18.17.5 + '@types/node': 20.11.10 esbuild: 0.19.6 postcss: 8.4.33 rollup: 4.5.0 @@ -16323,11 +16332,11 @@ packages: flexsearch: 0.7.31 glob-to-regexp: 0.4.1 markdown-it: 13.0.1 - vitepress: 1.0.0-alpha.72(@algolia/client-search@4.19.1)(@types/node@18.17.5)(search-insights@2.7.0) + vitepress: 1.0.0-alpha.72(@algolia/client-search@4.19.1)(@types/node@20.11.10)(search-insights@2.7.0) vue: 3.4.15(typescript@5.0.4) dev: true - /vitepress@1.0.0-alpha.72(@algolia/client-search@4.19.1)(@types/node@18.17.5)(search-insights@2.7.0): + /vitepress@1.0.0-alpha.72(@algolia/client-search@4.19.1)(@types/node@20.11.10)(search-insights@2.7.0): resolution: {integrity: sha512-Ou7fNE/OVYLrKGQMHSTVG6AcNsdv7tm4ACrdhx93SPMzEDj8UgIb4RFa5CTTowaYf3jeDGi2EAJlzXVC+IE3dg==} hasBin: true dependencies: @@ -16340,7 +16349,7 @@ packages: mark.js: 8.11.1 minisearch: 6.1.0 shiki: 0.14.3 - vite: 4.5.0(@types/node@18.17.5) + vite: 4.5.0(@types/node@20.11.10) vue: 3.3.4 transitivePeerDependencies: - '@algolia/client-search' @@ -16358,7 +16367,7 @@ packages: - terser dev: true - /vitepress@1.0.0-rc.39(@algolia/client-search@4.19.1)(@types/node@18.17.5)(postcss@8.4.33)(search-insights@2.7.0)(typescript@5.1.6): + /vitepress@1.0.0-rc.39(@algolia/client-search@4.19.1)(@types/node@20.11.10)(postcss@8.4.33)(search-insights@2.7.0)(typescript@5.1.6): resolution: {integrity: sha512-EcgoRlAAp37WOxUOYv45oxyhLrcy3Upey+mKpqW3ldsg6Ol4trPndRBk2GO0QiSvEKlb9BMerk49D/bFICN6kg==} hasBin: true peerDependencies: @@ -16384,7 +16393,7 @@ packages: shikiji: 0.9.19 shikiji-core: 0.9.19 shikiji-transformers: 0.9.19 - vite: 5.0.11(@types/node@18.17.5) + vite: 5.0.11(@types/node@20.11.10) vue: 3.4.15(typescript@5.1.6) transitivePeerDependencies: - '@algolia/client-search' @@ -16447,7 +16456,7 @@ packages: dependencies: '@types/chai': 4.3.5 '@types/chai-subset': 1.3.3 - '@types/node': 18.17.5 + '@types/node': 20.11.10 '@vitest/expect': 0.34.0 '@vitest/runner': 0.34.0 '@vitest/snapshot': 0.34.0 @@ -16468,8 +16477,8 @@ packages: strip-literal: 1.3.0 tinybench: 2.5.0 tinypool: 0.7.0 - vite: 4.5.0(@types/node@18.17.5) - vite-node: 0.34.0(@types/node@18.17.5) + vite: 4.5.0(@types/node@20.11.10) + vite-node: 0.34.0(@types/node@20.11.10) why-is-node-running: 2.2.2 transitivePeerDependencies: - less From dd553cb28f2825ee0d4134ac055e42eadb950c91 Mon Sep 17 00:00:00 2001 From: Sidharth Vinod Date: Mon, 29 Jan 2024 16:44:44 +0530 Subject: [PATCH 180/217] Remove node version from matrix --- .github/workflows/build.yml | 10 +++++----- .github/workflows/e2e.yml | 6 +++--- .github/workflows/lint.yml | 10 +++++----- .github/workflows/test.yml | 10 +++++----- 4 files changed, 18 insertions(+), 18 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 0b3197df74..b7589aee1b 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -12,23 +12,23 @@ on: permissions: contents: read +env: + node-version: 20.x + jobs: build-mermaid: runs-on: ubuntu-latest - strategy: - matrix: - node-version: [20.x] steps: - uses: actions/checkout@v4 - uses: pnpm/action-setup@v2 # uses version from "packageManager" field in package.json - - name: Setup Node.js ${{ matrix.node-version }} + - name: Setup Node.js ${{ env.node-version }} uses: actions/setup-node@v4 with: cache: pnpm - node-version: ${{ matrix.node-version }} + node-version: ${{ env.node-version }} - name: Install Packages run: | diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e.yml index 0d94de7bd2..3334fdcb67 100644 --- a/.github/workflows/e2e.yml +++ b/.github/workflows/e2e.yml @@ -17,6 +17,7 @@ permissions: contents: read env: + node-version: 20.x # For PRs and MergeQueues, the target commit is used, and for push events, github.event.previous is used. targetHash: ${{ github.event.pull_request.base.sha || github.event.merge_group.base_sha || (github.event.before == '0000000000000000000000000000000000000000' && 'develop' || github.event.before) }} @@ -60,7 +61,6 @@ jobs: strategy: fail-fast: false matrix: - node-version: [20.x] containers: [1, 2, 3, 4] steps: - uses: actions/checkout@v4 @@ -68,10 +68,10 @@ jobs: - uses: pnpm/action-setup@v2 # uses version from "packageManager" field in package.json - - name: Setup Node.js ${{ matrix.node-version }} + - name: Setup Node.js ${{ env.node-version }} uses: actions/setup-node@v4 with: - node-version: ${{ matrix.node-version }} + node-version: ${{ env.node-version }} # These cached snapshots are downloaded, providing the reference snapshots. - name: Cache snapshots diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 3255977ee0..3c9316dd76 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -13,23 +13,23 @@ on: permissions: contents: write +env: + node-version: 20.x + jobs: lint: runs-on: ubuntu-latest - strategy: - matrix: - node-version: [20.x] steps: - uses: actions/checkout@v4 - uses: pnpm/action-setup@v2 # uses version from "packageManager" field in package.json - - name: Setup Node.js ${{ matrix.node-version }} + - name: Setup Node.js ${{ env.node-version }} uses: actions/setup-node@v4 with: cache: pnpm - node-version: ${{ matrix.node-version }} + node-version: ${{ env.node-version }} - name: Install Packages run: | diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index fd390d0023..6217192fe5 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -5,23 +5,23 @@ on: [push, pull_request, merge_group] permissions: contents: read +env: + node-version: 20.x + jobs: unit-test: runs-on: ubuntu-latest - strategy: - matrix: - node-version: [20.x] steps: - uses: actions/checkout@v4 - uses: pnpm/action-setup@v2 # uses version from "packageManager" field in package.json - - name: Setup Node.js ${{ matrix.node-version }} + - name: Setup Node.js ${{ env.node-version }} uses: actions/setup-node@v4 with: cache: pnpm - node-version: ${{ matrix.node-version }} + node-version: ${{ env.node-version }} - name: Install Packages run: | From c84c7f52f9c5d49c0b1960b4b207295ef96c24bc Mon Sep 17 00:00:00 2001 From: Sidharth Vinod Date: Mon, 29 Jan 2024 16:46:48 +0530 Subject: [PATCH 181/217] Remove node version from matrix --- .github/workflows/build.yml | 10 +++++----- .github/workflows/e2e.yml | 6 +++--- .github/workflows/lint.yml | 10 +++++----- .github/workflows/test.yml | 10 +++++----- 4 files changed, 18 insertions(+), 18 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 605dea9ab3..8901ec345c 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -12,23 +12,23 @@ on: permissions: contents: read +env: + node-version: 18.x + jobs: build-mermaid: runs-on: ubuntu-latest - strategy: - matrix: - node-version: [18.x] steps: - uses: actions/checkout@v4 - uses: pnpm/action-setup@v2 # uses version from "packageManager" field in package.json - - name: Setup Node.js ${{ matrix.node-version }} + - name: Setup Node.js ${{ env.node-version }} uses: actions/setup-node@v4 with: cache: pnpm - node-version: ${{ matrix.node-version }} + node-version: ${{ env.node-version }} - name: Install Packages run: | diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e.yml index b8232b8c0e..cdd2e27a2d 100644 --- a/.github/workflows/e2e.yml +++ b/.github/workflows/e2e.yml @@ -17,6 +17,7 @@ permissions: contents: read env: + node-version: 18.x # For PRs and MergeQueues, the target commit is used, and for push events, github.event.previous is used. targetHash: ${{ github.event.pull_request.base.sha || github.event.merge_group.base_sha || (github.event.before == '0000000000000000000000000000000000000000' && 'develop' || github.event.before) }} @@ -60,7 +61,6 @@ jobs: strategy: fail-fast: false matrix: - node-version: [18.x] containers: [1, 2, 3, 4] steps: - uses: actions/checkout@v4 @@ -68,10 +68,10 @@ jobs: - uses: pnpm/action-setup@v2 # uses version from "packageManager" field in package.json - - name: Setup Node.js ${{ matrix.node-version }} + - name: Setup Node.js ${{ env.node-version }} uses: actions/setup-node@v4 with: - node-version: ${{ matrix.node-version }} + node-version: ${{ env.node-version }} # These cached snapshots are downloaded, providing the reference snapshots. - name: Cache snapshots diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index f0c5560a1e..babae3fda8 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -13,23 +13,23 @@ on: permissions: contents: write +env: + node-version: 18.x + jobs: lint: runs-on: ubuntu-latest - strategy: - matrix: - node-version: [18.x] steps: - uses: actions/checkout@v4 - uses: pnpm/action-setup@v2 # uses version from "packageManager" field in package.json - - name: Setup Node.js ${{ matrix.node-version }} + - name: Setup Node.js ${{ env.node-version }} uses: actions/setup-node@v4 with: cache: pnpm - node-version: ${{ matrix.node-version }} + node-version: ${{ env.node-version }} - name: Install Packages run: | diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index a18b31c9cd..5ca235b0da 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -5,23 +5,23 @@ on: [push, pull_request, merge_group] permissions: contents: read +env: + node-version: 18.x + jobs: unit-test: runs-on: ubuntu-latest - strategy: - matrix: - node-version: [18.x] steps: - uses: actions/checkout@v4 - uses: pnpm/action-setup@v2 # uses version from "packageManager" field in package.json - - name: Setup Node.js ${{ matrix.node-version }} + - name: Setup Node.js ${{ env.node-version }} uses: actions/setup-node@v4 with: cache: pnpm - node-version: ${{ matrix.node-version }} + node-version: ${{ env.node-version }} - name: Install Packages run: | From 1965f69a10f8c41863065e22e5fb1551762024ad Mon Sep 17 00:00:00 2001 From: Knut Sveidqvist Date: Mon, 29 Jan 2024 15:29:26 +0100 Subject: [PATCH 182/217] Update packages/mermaid/src/schemas/config.schema.yaml Co-authored-by: Alois Klink --- packages/mermaid/src/schemas/config.schema.yaml | 2 -- 1 file changed, 2 deletions(-) diff --git a/packages/mermaid/src/schemas/config.schema.yaml b/packages/mermaid/src/schemas/config.schema.yaml index 7278d5a796..b7925d042f 100644 --- a/packages/mermaid/src/schemas/config.schema.yaml +++ b/packages/mermaid/src/schemas/config.schema.yaml @@ -2034,8 +2034,6 @@ $defs: # JSON Schema definition (maybe we should move these to a separate file) type: object unevaluatedProperties: false properties: - useMaxWidth: - default: false padding: default: 8 From 37d7c7e2ddbc61d7473f2870f321e28df8513dbd Mon Sep 17 00:00:00 2001 From: Knut Sveidqvist Date: Mon, 29 Jan 2024 16:22:48 +0100 Subject: [PATCH 183/217] #3358 Second set of changes after review --- cypress/platform/knsv2.html | 16 +- demos/block.html | 126 +++++- docs/syntax/block.md | 44 +- .../src/dagre-wrapper/blockArrowHelper.js | 288 +++++++------ packages/mermaid/src/dagre-wrapper/edges.js | 95 +---- packages/mermaid/src/dagre-wrapper/nodes.js | 23 +- .../mermaid/src/dagre-wrapper/shapes/util.js | 4 +- .../mermaid/src/diagrams/block/blockDB.ts | 110 ++--- packages/mermaid/src/docs/syntax/block.md | 29 +- pnpm-lock.yaml | 398 +----------------- 10 files changed, 377 insertions(+), 756 deletions(-) diff --git a/cypress/platform/knsv2.html b/cypress/platform/knsv2.html index 8c6bf8a63b..847a8bf242 100644 --- a/cypress/platform/knsv2.html +++ b/cypress/platform/knsv2.html @@ -64,14 +64,14 @@
    -block-beta
    -columns 3
    -a:3
    -block:e:3
    -f
    -end
    -g
    -
    +      block-beta
    +  blockArrowId<["Label"]>(right)
    +  blockArrowId2<["Label"]>(left)
    +  blockArrowId3<["Label"]>(up)
    +  blockArrowId4<["Label"]>(down)
    +  blockArrowId5<["Label"]>(x)
    +  blockArrowId6<["Label"]>(y)
    +  blockArrowId6<["Label"]>(x, down)
         
     block-beta
    diff --git a/demos/block.html b/demos/block.html
    index 406350611a..03db61fad0 100644
    --- a/demos/block.html
    +++ b/demos/block.html
    @@ -3,23 +3,125 @@
       
         
         
    -    States Mermaid Quick Test Page
    +    Mermaid Block diagram demo page
         
    -    
       
     
       
         

    Block diagram demos

    -

    TCI IP

    -
    -  block-beta
    -      A>"rect_left_inv_arrow"]
    -      B{"diamond"}
    -      C{{"hexagon"}}
    +    
    +block-beta
    +columns 1
    +  db(("DB"))
    +  blockArrowId6<["   "]>(down)
    +  block:ID
    +    A
    +    B["A wide one in the middle"]
    +    C
    +  end
    +  space
    +  D
    +  ID --> D
    +  C --> D
    +  style B fill:#f9F,stroke:#333,stroke-width:4px
    +    
    +
    +block-beta
    +    A1["square"]
    +    B1("rounded")
    +    C1(("circle"))
    +    A2>"rect_left_inv_arrow"]
    +    B2{"diamond"}
    +    C2{{"hexagon"}}
    +    
    + +
    +block-beta
    +    A1(["stadium"])
    +    A2[["subroutine"]]
    +    B1[("cylinder")]
    +    C1>"surprise"]
    +    A3[/"lean right"/]
    +    B2[\"lean left"\]
    +    C2[/"trapezoid"\]
    +    D2[\"trapezoid"/]
    +    
    + +
    +block-beta
    +  block:e:4
    +    columns 2
    +      f
    +      g
    +  end
    +
    +    
    +
    +block-beta
    +  block:e:4
    +    columns 2
    +      f
    +      g
    +      h
    +  end
    +
    +    
    +
    +block-beta
    +  columns 3
    +  a:3
    +  block:e:3
    +      f
    +      g
    +  end
    +  h
    +  i
    +  j
    +
    +    
    +
    +block-beta
    +  columns 4
    +  a b c d
    +  block:e:4
    +    columns 2
    +      f
    +      g
    +      h
    +  end
    +  i:4
    +
    +    
    +
    +flowchart LR
    +  X-- "a label" -->z
    +    
    +
    +block-beta
    +columns 5
    +   A space B
    +   A --x B
    +    
    +
    +block-beta
    +columns 3
    +  a["A wide one"] b:2 c:2 d
    +    
    + +
    +block-beta
    +columns 3
    +  a b c
    +  e:3
    +  f g h
    +    
    + +
    +block-beta
    +
    +  A1:3
    +  A2:1
    +  A3