diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index 41d9c4cff..3574c3599 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -14,4 +14,5 @@ Make sure you - [ ] :book: have read the [contribution guidelines](https://github.com/mermaid-js/mermaid/blob/develop/CONTRIBUTING.md) - [ ] :computer: have added unit/e2e tests (if appropriate) +- [ ] :notebook: have added documentation (if appropriate) - [ ] :bookmark: targeted `develop` branch diff --git a/.github/workflows/link-checker.yml b/.github/workflows/link-checker.yml index fbf03cb39..566548ecf 100644 --- a/.github/workflows/link-checker.yml +++ b/.github/workflows/link-checker.yml @@ -13,11 +13,10 @@ on: - master pull_request: branches: - - develop - master schedule: # * is a special character in YAML so you have to quote this string - - cron: '30 8 * * 5' + - cron: '30 8 * * *' jobs: linkChecker: diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index d67144540..95e4256b1 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -7,6 +7,7 @@ on: - opened - synchronize - ready_for_review + workflow_dispatch: permissions: contents: write diff --git a/.lycheeignore b/.lycheeignore index 767906b16..79cf4428b 100644 --- a/.lycheeignore +++ b/.lycheeignore @@ -9,5 +9,8 @@ https://mkdocs.org/ https://osawards.com/javascript/#nominees https://osawards.com/javascript/2019 +# Timeout error, maybe Twitter has anti-bot defences against GitHub's CI servers? +https://twitter.com/mermaidjs_ + # Don't check files that are generated during the build via `pnpm docs:code` packages/mermaid/src/docs/config/setup/* diff --git a/.vite/build.ts b/.vite/build.ts index 45c96cb2f..549ac3b0b 100644 --- a/.vite/build.ts +++ b/.vite/build.ts @@ -162,7 +162,7 @@ const main = async () => { }; if (watch) { - build(getBuildConfig({ minify: false, watch, core: true, entryName: 'mermaid' })); + build(getBuildConfig({ minify: false, watch, core: false, entryName: 'mermaid' })); if (!mermaidOnly) { build(getBuildConfig({ minify: false, watch, entryName: 'mermaid-mindmap' })); // build(getBuildConfig({ minify: false, watch, entryName: 'mermaid-example-diagram' })); diff --git a/README.md b/README.md index 059940a02..9a500283c 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,7 @@ English | [简体中文](./README.zh-CN.md) **Thanks to all involved, people committing pull requests, people answering questions! 🙏** -Explore Mermaid.js in depth, with real-world examples, tips & tricks from the creator... The first official book on Mermaid is available for purchase. Check it out! +Explore Mermaid.js in depth, with real-world examples, tips & tricks from the creator... The first official book on Mermaid is available for purchase. Check it out! ## About diff --git a/README.zh-CN.md b/README.zh-CN.md index 4bdbc4ae7..6b3e28b19 100644 --- a/README.zh-CN.md +++ b/README.zh-CN.md @@ -10,7 +10,7 @@ **感谢所有参与进来提交 PR,解答疑问的人们! 🙏** -Explore Mermaid.js in depth, with real-world examples, tips & tricks from the creator... The first official book on Mermaid is available for purchase. Check it out! +Explore Mermaid.js in depth, with real-world examples, tips & tricks from the creator... The first official book on Mermaid is available for purchase. Check it out! ## 关于 Mermaid diff --git a/cSpell.json b/cSpell.json index 45e7fe99a..49cb8ada1 100644 --- a/cSpell.json +++ b/cSpell.json @@ -14,6 +14,7 @@ "bilkent", "bisheng", "braintree", + "brkt", "brolin", "brotli", "classdef", @@ -60,12 +61,14 @@ "mindmaps", "mitigations", "mkdocs", + "mult", "orlandoni", "phpbb", "plantuml", "playfair", "pnpm", "podlite", + "quence", "ranksep", "rect", "rects", @@ -80,7 +83,10 @@ "stylis", "substate", "sveidqvist", + "swimm", "techn", + "teststr", + "textlength", "treemap", "ts-nocheck", "tuleap", diff --git a/cypress/integration/other/external-diagrams.spec.js b/cypress/integration/other/external-diagrams.spec.js index 3a6c37e88..be69dfc98 100644 --- a/cypress/integration/other/external-diagrams.spec.js +++ b/cypress/integration/other/external-diagrams.spec.js @@ -1,13 +1,10 @@ +import { urlSnapshotTest } from '../../helpers/util'; + describe('mermaid', () => { describe('registerDiagram', () => { it('should work on @mermaid-js/mermaid-mindmap and mermaid-example-diagram', () => { const url = 'http://localhost:9000/external-diagrams-mindmap.html'; - cy.visit(url); - - cy.get('svg', { - // may be a bit slower than normal, since vite might need to re-compile mermaid/mermaid-mindmap/mermaid-example-diagram - timeout: 10000, - }).matchImageSnapshot(); + urlSnapshotTest(url, {}, false, false); }); }); }); diff --git a/cypress/integration/other/ghsa.spec.js b/cypress/integration/other/ghsa.spec.js index 5b168a8a8..4fadc7855 100644 --- a/cypress/integration/other/ghsa.spec.js +++ b/cypress/integration/other/ghsa.spec.js @@ -7,4 +7,10 @@ describe('CSS injections', () => { flowchart: { htmlLabels: false }, }); }); + it('should not allow adding styletags affecting the page', () => { + urlSnapshotTest('http://localhost:9000/ghsa3.html', { + logLevel: 1, + flowchart: { htmlLabels: false }, + }); + }); }); diff --git a/cypress/integration/rendering/c4.spec.js b/cypress/integration/rendering/c4.spec.js new file mode 100644 index 000000000..0cf128ff6 --- /dev/null +++ b/cypress/integration/rendering/c4.spec.js @@ -0,0 +1,122 @@ +import { imgSnapshotTest, renderGraph } from '../../helpers/util.js'; + +describe('C4 diagram', () => { + it('should render a simple C4Context diagram', () => { + imgSnapshotTest( + ` + C4Context + accTitle: C4 context demo + accDescr: Many large C4 diagrams + + title System Context diagram for Internet Banking System + + Enterprise_Boundary(b0, "BankBoundary0") { + Person(customerA, "Banking Customer A", "A customer of the bank, with personal bank accounts.") + + System(SystemAA, "Internet Banking System", "Allows customers to view information about their bank accounts, and make payments.") + + Enterprise_Boundary(b1, "BankBoundary") { + System_Ext(SystemC, "E-mail system", "The internal Microsoft Exchange e-mail system.") + } + } + + BiRel(customerA, SystemAA, "Uses") + Rel(SystemAA, SystemC, "Sends e-mails", "SMTP") + Rel(SystemC, customerA, "Sends e-mails to") + + UpdateElementStyle(customerA, $fontColor="red", $bgColor="grey", $borderColor="red") + UpdateRelStyle(customerA, SystemAA, $textColor="blue", $lineColor="blue", $offsetX="5") + UpdateRelStyle(SystemC, customerA, $textColor="red", $lineColor="red", $offsetX="-50", $offsetY="20") + `, + {} + ); + cy.get('svg'); + }); + it('should render a simple C4Container diagram', () => { + imgSnapshotTest( + ` + C4Container + title Container diagram for Internet Banking System + + System_Ext(email_system, "E-Mail System", "The internal Microsoft Exchange system", $tags="v1.0") + Person(customer, Customer, "A customer of the bank, with personal bank accounts", $tags="v1.0") + + Container_Boundary(c1, "Internet Banking") { + Container(spa, "Single-Page App", "JavaScript, Angular", "Provides all the Internet banking functionality to customers via their web browser") + } + + Rel(customer, spa, "Uses", "HTTPS") + Rel(email_system, customer, "Sends e-mails to") + `, + {} + ); + cy.get('svg'); + }); + it('should render a simple C4Component diagram', () => { + imgSnapshotTest( + ` + C4Component + title Component diagram for Internet Banking System - API Application + + Container(spa, "Single Page Application", "javascript and angular", "Provides all the internet banking functionality to customers via their web browser.") + + Container_Boundary(api, "API Application") { + Component(sign, "Sign In Controller", "MVC Rest Controller", "Allows users to sign in to the internet banking system") + } + + Rel_Back(spa, sign, "Uses", "JSON/HTTPS") + UpdateRelStyle(spa, sign, $offsetY="-40") + `, + {} + ); + cy.get('svg'); + }); + it('should render a simple C4Dynamic diagram', () => { + imgSnapshotTest( + ` + C4Dynamic + title Dynamic diagram for Internet Banking System - API Application + + ContainerDb(c4, "Database", "Relational Database Schema", "Stores user registration information, hashed authentication credentials, access logs, etc.") + Container(c1, "Single-Page Application", "JavaScript and Angular", "Provides all of the Internet banking functionality to customers via their web browser.") + Container_Boundary(b, "API Application") { + Component(c3, "Security Component", "Spring Bean", "Provides functionality Related to signing in, changing passwords, etc.") + Component(c2, "Sign In Controller", "Spring MVC Rest Controller", "Allows users to sign in to the Internet Banking System.") + } + Rel(c1, c2, "Submits credentials to", "JSON/HTTPS") + Rel(c2, c3, "Calls isAuthenticated() on") + Rel(c3, c4, "select * from users where username = ?", "JDBC") + + UpdateRelStyle(c1, c2, $textColor="red", $offsetY="-40") + UpdateRelStyle(c2, c3, $textColor="red", $offsetX="-40", $offsetY="60") + UpdateRelStyle(c3, c4, $textColor="red", $offsetY="-40", $offsetX="10") + `, + {} + ); + cy.get('svg'); + }); + it('should render a simple C4Deployment diagram', () => { + imgSnapshotTest( + ` + C4Deployment + title Deployment Diagram for Internet Banking System - Live + + Deployment_Node(mob, "Customer's mobile device", "Apple IOS or Android"){ + Container(mobile, "Mobile App", "Xamarin", "Provides a limited subset of the Internet Banking functionality to customers via their mobile device.") + } + + Deployment_Node(plc, "Big Bank plc", "Big Bank plc data center"){ + Deployment_Node(dn, "bigbank-api*** x8", "Ubuntu 16.04 LTS"){ + Deployment_Node(apache, "Apache Tomcat", "Apache Tomcat 8.x"){ + Container(api, "API Application", "Java and Spring MVC", "Provides Internet Banking functionality via a JSON/HTTPS API.") + } + } + } + + Rel(mobile, api, "Makes API calls to", "json/HTTPS") + `, + {} + ); + cy.get('svg'); + }); +}); diff --git a/cypress/integration/rendering/classDiagram-v2.spec.js b/cypress/integration/rendering/classDiagram-v2.spec.js index f97458857..9536a074d 100644 --- a/cypress/integration/rendering/classDiagram-v2.spec.js +++ b/cypress/integration/rendering/classDiagram-v2.spec.js @@ -485,8 +485,7 @@ describe('Class diagram V2', () => { classDiagram-v2 note "I love this diagram!\nDo you love it?" class Class10 { - <> - int id + int id size() } note for Class10 "Cool class\nI said it's very cool class!" diff --git a/cypress/integration/rendering/classDiagram.spec.js b/cypress/integration/rendering/classDiagram.spec.js index 16601652d..e21be67ec 100644 --- a/cypress/integration/rendering/classDiagram.spec.js +++ b/cypress/integration/rendering/classDiagram.spec.js @@ -414,7 +414,6 @@ describe('Class diagram', () => { classDiagram note "I love this diagram!\nDo you love it?" class Class10 { - <> int id size() } diff --git a/cypress/integration/rendering/current.spec.js b/cypress/integration/rendering/current.spec.js index 56b5f774b..033752c66 100644 --- a/cypress/integration/rendering/current.spec.js +++ b/cypress/integration/rendering/current.spec.js @@ -1,6 +1,6 @@ import { imgSnapshotTest } from '../../helpers/util'; -describe('State diagram', () => { +describe('Current diagram', () => { it('should render a state with states in it', () => { imgSnapshotTest( ` diff --git a/cypress/integration/rendering/erDiagram.spec.js b/cypress/integration/rendering/erDiagram.spec.js index 8e8946170..c72df49b6 100644 --- a/cypress/integration/rendering/erDiagram.spec.js +++ b/cypress/integration/rendering/erDiagram.spec.js @@ -182,6 +182,20 @@ describe('Entity Relationship Diagram', () => { cy.get('svg'); }); + it('should render entities with length in attributes type', () => { + renderGraph( + ` + erDiagram + CLUSTER { + varchar(99) name + string(255) description + } + `, + { logLevel: 1 } + ); + cy.get('svg'); + }); + it('should render entities and attributes with big and small entity names', () => { renderGraph( ` diff --git a/cypress/platform/ghsa1.html b/cypress/platform/ghsa1.html index c54358862..890a8e0dd 100644 --- a/cypress/platform/ghsa1.html +++ b/cypress/platform/ghsa1.html @@ -4,7 +4,7 @@
-

This element does not belong to the SVG but we can style it

+

Background should be yellow!!!

diff --git a/cypress/platform/ghsa3.html b/cypress/platform/ghsa3.html new file mode 100644 index 000000000..63dfa0d01 --- /dev/null +++ b/cypress/platform/ghsa3.html @@ -0,0 +1,100 @@ + + + + + + + + + +

PAGE SHOULD NOT BE RED

+
+
+
+
+ + + + diff --git a/cypress/platform/knsv3.html b/cypress/platform/knsv3.html index 0c1afadb7..e5ca66c87 100644 --- a/cypress/platform/knsv3.html +++ b/cypress/platform/knsv3.html @@ -6,6 +6,10 @@ rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css" /> + -
info below
-
-
-flowchart TB;subgraph "number as labels";1;end;
-      
-
-flowchart TB;a[APA];
-      
-
-graph TD
-      work --> sleep
-      sleep --> work
-      eat --> sleep
-      work --> eat
-      
-
-flowchart TD
-      work --> sleep
-      sleep --> work
-      eat --> sleep
-      work --> eat
-      
-
- graph TB
-      A
-      B
-      subgraph foo[Foo SubGraph]
-        C
-        D
-      end
-      subgraph bar[Bar SubGraph]
-        E
-        F
-      end
-      G
-
-      A-->B
-      B-->C
-      C-->D
-      B-->D
-      D-->E
-      E-->A
-      E-->F
-      F-->D
-      F-->G
-      B-->G
-      G-->D
-
-      style foo fill:#F99,stroke-width:2px,stroke:#F0F,color:darkred
-      style bar fill:#999,stroke-width:2px,stroke:#0F0,color:blue
-      
-
-      graph TB
-%%{init: { "logLevel": 1, "flowchart": {"htmlLabels":true }} }%%
-      A
-      B
-      subgraph foo[Foo SubGraph]
-        C
-        D
-      end
-      subgraph bar[Bar SubGraph]
-        E
-        F
-      end
-      G
-
-      A-->B
-      B-->C
-      C-->D
-      B-->D
-      D-->E
-      E-->A
-      E-->F
-      F-->D
-      F-->G
-      B-->G
-      G-->D
-
-      style foo fill:#F99,stroke-width:2px,stroke:#F0F,color:darkred
-      style bar fill:#999,stroke-width:10px,stroke:#0F0,color:blue
-      
-
+    
Security check
+
       graph TD
-        A[Christmas] ==> D
-        A[Christmas] -->|Get money| B(Go shopping)
-        A[Christmas] ==> C
-      
-
-      graph TD
-%%{init: { "logLevel": 1, "flowchart": {"htmlLabels":true }} }%%
-        A[Christmas] ==> D
-        A[Christmas] -->|Get money| B(Go shopping)
-        A[Christmas] ==> C
-      
-
-      flowchart TD
-        A[Christmas] ==> D
-        A[Christmas] -->|Get money| B(Go shopping)
-        A[Christmas] ==> C
-      
-
-      flowchart TD
-%%{init: { "logLevel": 1, "flowchart": {"htmlLabels":true }} }%%
-        A[Christmas] ==> D
-        A[Christmas] -->|Get money| B(Go shopping)
-        A[Christmas] ==> C
-      
-
-flowchart LR
-        a["Haiya"]---->b
-      
-
-flowchart LR
-%%{init: { "logLevel": 1, "flowchart": {"htmlLabels":true }} }%%
-        a["Haiya"]---->b
-      
-
-      flowchart TD
-        A[Christmas] ==> D
-        A[Christmas] -->|Get money| B(Go shopping)
-        A[Christmas] ==> C
-      
-
-      flowchart TD
-%%{init: { "logLevel": 1, "flowchart": {"htmlLabels":true }} }%%
-        A[Christmas] ==> D
-        A[Christmas] -->|Get money| B(Go shopping)
-        A[Christmas] ==> C
-      
-
-      %%{init: { "logLevel": 1, "flowchart": {"htmlLabels":true }} }%%
-classDiagram-v2
-      Class01 <|-- AveryLongClass : Cool
-      <<interface>> Class01
-      Class03 *-- Class04
-      Class05 o-- Class06
-      Class07 .. Class08
-      Class09 --> C2 : Where am i?
-      Class09 --* C3
-      Class09 --|> Class07
-      Class12 <|.. Class08
-      Class11 ..>Class12
-      Class07 : equals()
-      Class07 : Object[] elementData
-      Class01 : size()
-      Class01 : int chimp
-      Class01 : int gorilla
-      Class01 : -int privateChimp
-      Class01 : +int publicGorilla
-      Class01 : #int protectedMarmoset
-      Class08 <--> C2: Cool label
-      class Class10 {
-        <<service>>
-        int id
-        test()
-      }
-      
-
-classDiagram-v2
-      Class01 <|-- AveryLongClass : Cool
-      <<interface>> Class01
-      Class03 *-- Class04
-      Class05 o-- Class06
-      Class07 .. Class08
-      Class09 --> C2 : Where am i?
-      Class09 --* C3
-      Class09 --|> Class07
-      Class12 <|.. Class08
-      Class11 ..>Class12
-      Class07 : equals()
-      Class07 : Object[] elementData
-      Class01 : size()
-      Class01 : int chimp
-      Class01 : int gorilla
-      Class01 : -int privateChimp
-      Class01 : +int publicGorilla
-      Class01 : #int protectedMarmoset
-      Class08 <--> C2: Cool label
-      class Class10 {
-        <<service>>
-        int id
-        test()
-      }
-      
-
-flowchart BT
-   subgraph S1
-    sub1 -->sub2
-   end
-  subgraph S2
-    sub4
-   end
-   S1 --> S2
-   sub1 --> sub4
-      
-
- - diff --git a/demos/classchart.html b/demos/classchart.html index 031f3b608..e8e48e482 100644 --- a/demos/classchart.html +++ b/demos/classchart.html @@ -17,10 +17,10 @@

Class diagram demos

----
-title: Demo Class Diagram
----
-		classDiagram
+    ---
+    title: Demo Class Diagram
+    ---
+    classDiagram
       accTitle: Demo Class Diagram
       accDescr: This class diagram show the abstract Animal class, and 3 classes that inherit from it: Duck, Fish, and Zebra.
 
@@ -138,7 +138,20 @@ title: Demo Class Diagram
     Pineapple : -int leafCount()
     Pineapple : -int spikeCount()
     
+
+
+    classDiagram
+      class Person {
+        +Id : Guid
+        +FirstName : string
+        +LastName : string
+        -privateProperty : string
+        #ProtectedProperty : string
+        ~InternalProperty : string
+        ~AnotherInternalProperty : List~List~string~~
+      }
+    

diff --git a/demos/er.html b/demos/er.html index 06fbf020e..34e06acf8 100644 --- a/demos/er.html +++ b/demos/er.html @@ -19,44 +19,57 @@
+      ---
+      title: This is a title
+      ---
+      erDiagram
+        %% title This is a title
+        %% accDescription Test a description
 
----
-title: This is a title
----
-erDiagram
-  %% title This is a title
-  %% accDescription Test a description
+        "Person . CUSTOMER"||--o{ ORDER : places
 
-  "Person . CUSTOMER"||--o{ ORDER : places
+        ORDER ||--|{ "€£LINE_ITEM ¥" : contains
 
-  ORDER ||--|{ "€£LINE_ITEM ¥" : contains
+        "Person . CUSTOMER" }|..|{ "Address//StreetAddress::[DELIVERY ADDRESS]" : uses
 
-  "Person . CUSTOMER" }|..|{ "Address//StreetAddress::[DELIVERY ADDRESS]" : uses
+        "Address//StreetAddress::[DELIVERY ADDRESS]" {
+          int customerID FK
+          string line1 "this is the first address line comment"
+          string line2
+          string city
+          string region
+          string state
+          string(5) postal_code
+          string country
+        }
 
-  "Address//StreetAddress::[DELIVERY ADDRESS]" {
-      int customerID FK
-      string line1 "this is the first address line comment"
-      string line2
-      string city
-      string region
-      string state
-      string postal_code
-      string country
-      }
+        "a_~`!@#$^&*()-_=+[]{}|/;:'.?¡⁄™€£‹¢›∞fi§‡•°ª·º‚≠±œŒ∑„®†ˇ¥Á¨ˆˆØπ∏“«»åÅßÍ∂΃ϩ˙Ó∆Ô˚¬Ò…ÚæÆΩ¸≈π˛çÇ√◊∫ı˜µÂ≤¯≥˘÷¿" {
+          string name "this is an entity with an absurd name just to show characters that are now acceptable as long as the name is in double quotes"
+        }
 
-      "a_~`!@#$^&*()-_=+[]{}|/;:'.?¡⁄™€£‹¢›∞fi§‡•°ª·º‚≠±œŒ∑„®†ˇ¥Á¨ˆˆØπ∏“«»åÅßÍ∂΃ϩ˙Ó∆Ô˚¬Ò…ÚæÆΩ¸≈π˛çÇ√◊∫ı˜µÂ≤¯≥˘÷¿" {
-        string name "this is an entity with an absurd name just to show characters that are now acceptable as long as the name is in double quotes"
-      }
+        "€£LINE_ITEM ¥" {
+          int orderID FK
+          int currencyId FK
+          number price
+          number quantity
+          number adjustment
+          number final_price
+        }
+    
+
- "€£LINE_ITEM ¥" { - int orderID FK - int currencyId FK - number price - number quantity - number adjustment - number final_price +
+    erDiagram
+      "HOSPITAL" {
+        int id PK
+        int doctor_id FK
+        string address UK
+        string name
+        string phone_number
+        string fax_number
       }
     
+
+``` + +You can also refer the implementation in the live editor [here](https://github.com/mermaid-js/mermaid-live-editor/blob/fcf53c98c25604c90a218104268c339be53035a6/src/lib/util/mermaid.ts) to see how the async loading is done. diff --git a/package.json b/package.json index 11dcaa236..596cac22b 100644 --- a/package.json +++ b/package.json @@ -1,10 +1,10 @@ { "name": "mermaid-monorepo", "private": true, - "version": "9.2.2", + "version": "9.3.0-rc1", "description": "Markdownish syntax for generating flowcharts, sequence diagrams, class diagrams, gantt charts and git graphs.", "type": "module", - "packageManager": "pnpm@7.18.1", + "packageManager": "pnpm@7.18.2", "keywords": [ "diagram", "markdown", diff --git a/packages/mermaid-mindmap/package.json b/packages/mermaid-mindmap/package.json index 852c0871b..0f1a98303 100644 --- a/packages/mermaid-mindmap/package.json +++ b/packages/mermaid-mindmap/package.json @@ -1,7 +1,7 @@ { "name": "@mermaid-js/mermaid-mindmap", - "version": "9.2.2", - "description": "Markdownish syntax for generating flowcharts, sequence diagrams, class diagrams, gantt charts and git graphs.", + "version": "9.3.0", + "description": "Mindmap diagram module for MermaidJS.", "module": "dist/mermaid-mindmap.core.mjs", "types": "dist/detector.d.ts", "type": "module", diff --git a/packages/mermaid/README.md b/packages/mermaid/README.md index 91c2d1640..e6c7db608 100644 --- a/packages/mermaid/README.md +++ b/packages/mermaid/README.md @@ -10,7 +10,7 @@ English | [简体中文](./README.zh-CN.md) **Thanks to all involved, people committing pull requests, people answering questions! 🙏** -Explore Mermaid.js in depth, with real-world examples, tips & tricks from the creator... The first official book on Mermaid is available for purchase. Check it out! +Explore Mermaid.js in depth, with real-world examples, tips & tricks from the creator... The first official book on Mermaid is available for purchase. Check it out! ## About diff --git a/packages/mermaid/README.zh-CN.md b/packages/mermaid/README.zh-CN.md index 0ccef27e4..f34c7a647 100644 --- a/packages/mermaid/README.zh-CN.md +++ b/packages/mermaid/README.zh-CN.md @@ -10,7 +10,7 @@ **感谢所有参与进来提交 PR,解答疑问的人们! 🙏** -Explore Mermaid.js in depth, with real-world examples, tips & tricks from the creator... The first official book on Mermaid is available for purchase. Check it out! +Explore Mermaid.js in depth, with real-world examples, tips & tricks from the creator... The first official book on Mermaid is available for purchase. Check it out! ## 关于 Mermaid diff --git a/packages/mermaid/package.json b/packages/mermaid/package.json index 66fa4f224..dd88a4441 100644 --- a/packages/mermaid/package.json +++ b/packages/mermaid/package.json @@ -1,6 +1,6 @@ { "name": "mermaid", - "version": "9.2.3-rc.1", + "version": "9.3.0", "description": "Markdown-ish syntax for generating flowcharts, sequence diagrams, class diagrams, gantt charts and git graphs.", "main": "./dist/mermaid.min.js", "module": "./dist/mermaid.core.mjs", @@ -28,7 +28,7 @@ "docs:build": "rimraf ../../docs && pnpm docs:spellcheck && pnpm docs:code && ts-node-esm src/docs.mts", "docs:verify": "pnpm docs:spellcheck && pnpm docs:code && ts-node-esm src/docs.mts --verify", "docs:pre:vitepress": "rimraf src/vitepress && pnpm docs:code && ts-node-esm src/docs.mts --vitepress", - "docs:build:vitepress": "pnpm docs:pre:vitepress && vitepress build src/vitepress", + "docs:build:vitepress": "pnpm docs:pre:vitepress && vitepress build src/vitepress && cpy --flat src/docs/landing/ ./src/vitepress/.vitepress/dist/landing", "docs:dev": "pnpm docs:pre:vitepress && concurrently \"vitepress dev src/vitepress\" \"ts-node-esm src/docs.mts --watch --vitepress\"", "docs:serve": "pnpm docs:build:vitepress && vitepress serve src/vitepress", "docs:spellcheck": "cspell --config ../../cSpell.json \"src/docs/**/*.md\"", @@ -54,13 +54,14 @@ "dependencies": { "@braintree/sanitize-url": "^6.0.0", "d3": "^7.0.0", - "dagre-d3-es": "7.0.4", - "dompurify": "2.4.1", + "dagre-d3-es": "7.0.6", + "dompurify": "2.4.3", "khroma": "^2.0.0", "lodash-es": "^4.17.21", "moment-mini": "^2.24.0", "non-layered-tidy-tree-layout": "^2.0.2", "stylis": "^4.1.2", + "ts-dedent": "^2.2.0", "uuid": "^9.0.0" }, "devDependencies": { @@ -77,6 +78,7 @@ "chokidar": "^3.5.3", "concurrently": "^7.5.0", "coveralls": "^3.1.1", + "cpy-cli": "^4.2.0", "cspell": "^6.14.3", "globby": "^13.1.2", "jison": "^0.4.18", @@ -93,8 +95,8 @@ "typedoc-plugin-markdown": "^3.13.6", "typescript": "^4.8.4", "unist-util-flatmap": "^1.0.0", - "vitepress": "^1.0.0-alpha.28", - "vitepress-plugin-search": "^1.0.4-alpha.15" + "vitepress": "^1.0.0-alpha.31", + "vitepress-plugin-search": "^1.0.4-alpha.16" }, "files": [ "dist", diff --git a/packages/mermaid/src/Diagram.ts b/packages/mermaid/src/Diagram.ts index e509962f6..f4cce4bf6 100644 --- a/packages/mermaid/src/Diagram.ts +++ b/packages/mermaid/src/Diagram.ts @@ -102,7 +102,6 @@ export const getDiagramFromText = ( try { // Trying to find the diagram getDiagram(type); - return new Diagram(txt, parseError); } catch (error) { const loader = getDiagramLoader(type); if (!loader) { @@ -118,6 +117,7 @@ export const getDiagramFromText = ( return new Diagram(txt, parseError); }); } + return new Diagram(txt, parseError); }; export default Diagram; diff --git a/packages/mermaid/src/accessibility.spec.ts b/packages/mermaid/src/accessibility.spec.ts index c633d0e15..60415ea37 100644 --- a/packages/mermaid/src/accessibility.spec.ts +++ b/packages/mermaid/src/accessibility.spec.ts @@ -6,6 +6,13 @@ describe('accessibility', () => { const fauxSvgNode = new MockedD3(); describe('setA11yDiagramInfo', () => { + it('sets the svg element role to "graphics-document document"', () => { + // @ts-ignore Required to easily handle the d3 select types + const svgAttrSpy = vi.spyOn(fauxSvgNode, 'attr').mockReturnValue(fauxSvgNode); + setA11yDiagramInfo(fauxSvgNode, 'flowchart'); + expect(svgAttrSpy).toHaveBeenCalledWith('role', 'graphics-document document'); + }); + it('sets the aria-roledescription to the diagram type', () => { // @ts-ignore Required to easily handle the d3 select types const svgAttrSpy = vi.spyOn(fauxSvgNode, 'attr').mockReturnValue(fauxSvgNode); @@ -13,11 +20,12 @@ describe('accessibility', () => { expect(svgAttrSpy).toHaveBeenCalledWith('aria-roledescription', 'flowchart'); }); - it('does nothing if the diagram type is empty', () => { + it('does not set the aria-roledescription if the diagram type is empty', () => { // @ts-ignore Required to easily handle the d3 select types const svgAttrSpy = vi.spyOn(fauxSvgNode, 'attr').mockReturnValue(fauxSvgNode); setA11yDiagramInfo(fauxSvgNode, ''); - expect(svgAttrSpy).not.toHaveBeenCalled(); + expect(svgAttrSpy).toHaveBeenCalledTimes(1); + expect(svgAttrSpy).toHaveBeenCalledWith('role', expect.anything()); // only called to set the role }); }); diff --git a/packages/mermaid/src/accessibility.ts b/packages/mermaid/src/accessibility.ts index b9e088e0b..8e073aa76 100644 --- a/packages/mermaid/src/accessibility.ts +++ b/packages/mermaid/src/accessibility.ts @@ -1,18 +1,33 @@ /** * Accessibility (a11y) functions, types, helpers + * @see https://www.w3.org/WAI/ + * @see https://www.w3.org/TR/wai-aria-1.1/ + * @see https://www.w3.org/TR/svg-aam-1.0/ * */ import { D3Element } from './mermaidAPI'; -import isEmpty from 'lodash-es/isEmpty'; +import isEmpty from 'lodash-es/isEmpty.js'; /** - * Add aria-roledescription to the svg element to the diagramType + * SVG element role: + * The SVG element role _should_ be set to 'graphics-document' per SVG standard + * but in practice is not always done by browsers, etc. (As of 2022-12-08). + * A fallback role of 'document' should be set for those browsers, etc., that only support ARIA 1.0. + * + * @see https://www.w3.org/TR/svg-aam-1.0/#roleMappingGeneralRules + * @see https://www.w3.org/TR/graphics-aria-1.0/#graphics-document + */ +const SVG_ROLE = 'graphics-document document'; + +/** + * Add role and aria-roledescription to the svg element * * @param svg - d3 object that contains the SVG HTML element * @param diagramType - diagram name for to the aria-roledescription */ export function setA11yDiagramInfo(svg: D3Element, diagramType: string | null | undefined) { + svg.attr('role', SVG_ROLE); if (!isEmpty(diagramType)) { svg.attr('aria-roledescription', diagramType); } diff --git a/packages/mermaid/src/dagre-wrapper/index.js b/packages/mermaid/src/dagre-wrapper/index.js index e2d7d51f4..ce3ef6014 100644 --- a/packages/mermaid/src/dagre-wrapper/index.js +++ b/packages/mermaid/src/dagre-wrapper/index.js @@ -1,5 +1,5 @@ import { layout as dagreLayout } from 'dagre-d3-es/src/dagre/index.js'; -import * as graphlibJson from 'dagre-d3-es/src/graphlib/json'; +import * as graphlibJson from 'dagre-d3-es/src/graphlib/json.js'; import insertMarkers from './markers'; import { updateNodeBounds } from './shapes/util'; import { diff --git a/packages/mermaid/src/dagre-wrapper/mermaid-graphlib.js b/packages/mermaid/src/dagre-wrapper/mermaid-graphlib.js index 5722f7cc0..875ac4def 100644 --- a/packages/mermaid/src/dagre-wrapper/mermaid-graphlib.js +++ b/packages/mermaid/src/dagre-wrapper/mermaid-graphlib.js @@ -1,7 +1,7 @@ /** Decorates with functions required by mermaids dagre-wrapper. */ import { log } from '../logger'; -import * as graphlibJson from 'dagre-d3-es/src/graphlib/json'; -import * as graphlib from 'dagre-d3-es/src/graphlib'; +import * as graphlibJson from 'dagre-d3-es/src/graphlib/json.js'; +import * as graphlib from 'dagre-d3-es/src/graphlib/index.js'; export let clusterDb = {}; let descendants = {}; diff --git a/packages/mermaid/src/dagre-wrapper/mermaid-graphlib.spec.js b/packages/mermaid/src/dagre-wrapper/mermaid-graphlib.spec.js index f594e3430..25fb75d64 100644 --- a/packages/mermaid/src/dagre-wrapper/mermaid-graphlib.spec.js +++ b/packages/mermaid/src/dagre-wrapper/mermaid-graphlib.spec.js @@ -1,5 +1,5 @@ -import * as graphlibJson from 'dagre-d3-es/src/graphlib/json'; -import * as graphlib from 'dagre-d3-es/src/graphlib'; +import * as graphlibJson from 'dagre-d3-es/src/graphlib/json.js'; +import * as graphlib from 'dagre-d3-es/src/graphlib/index.js'; import { validate, adjustClustersAndEdges, diff --git a/packages/mermaid/src/diagram-api/diagram-orchestration.ts b/packages/mermaid/src/diagram-api/diagram-orchestration.ts index a26edb303..6c7ab6907 100644 --- a/packages/mermaid/src/diagram-api/diagram-orchestration.ts +++ b/packages/mermaid/src/diagram-api/diagram-orchestration.ts @@ -125,6 +125,33 @@ export const addDiagrams = () => { }, (text) => text.toLowerCase().trim() === 'error' ); + registerDiagram( + '---', + // --- diagram type may appear if YAML front-matter is not parsed correctly + { + db: { + clear: () => { + // Quite ok, clear needs to be there for --- to work as a regular diagram + }, + }, + styles: errorStyles, // should never be used + renderer: errorRenderer, // should never be used + parser: { + parser: { yy: {} }, + parse: () => { + throw new Error( + 'Diagrams beginning with --- are not valid. ' + + 'If you were trying to use a YAML front-matter, please ensure that ' + + "you've correctly opened and closed the YAML front-matter with unindented `---` blocks" + ); + }, + }, + init: () => null, // no op + }, + (text) => { + return text.toLowerCase().trimStart().startsWith('---'); + } + ); registerDiagram( 'c4', diff --git a/packages/mermaid/src/diagram.spec.ts b/packages/mermaid/src/diagram.spec.ts new file mode 100644 index 000000000..ebe088a86 --- /dev/null +++ b/packages/mermaid/src/diagram.spec.ts @@ -0,0 +1,67 @@ +import { describe, test, expect } from 'vitest'; +import Diagram, { getDiagramFromText } from './Diagram'; +import { addDetector } from './diagram-api/detectType'; +import { addDiagrams } from './diagram-api/diagram-orchestration'; + +addDiagrams(); + +describe('diagram detection', () => { + test('should detect inbuilt diagrams', () => { + const graph = getDiagramFromText('graph TD; A-->B') as Diagram; + expect(graph).toBeInstanceOf(Diagram); + expect(graph.type).toBe('flowchart-v2'); + const sequence = getDiagramFromText( + 'sequenceDiagram; Alice->>+John: Hello John, how are you?' + ) as Diagram; + expect(sequence).toBeInstanceOf(Diagram); + expect(sequence.type).toBe('sequence'); + }); + + test('should detect external diagrams', async () => { + addDetector( + 'loki', + (str) => str.startsWith('loki'), + () => + Promise.resolve({ + id: 'loki', + diagram: { + db: {}, + parser: { + parse: () => { + // no-op + }, + parser: { + yy: {}, + }, + }, + renderer: {}, + styles: {}, + }, + }) + ); + const diagram = (await getDiagramFromText('loki TD; A-->B')) as Diagram; + expect(diagram).toBeInstanceOf(Diagram); + expect(diagram.type).toBe('loki'); + }); + + test('should throw the right error for incorrect diagram', () => { + expect(() => getDiagramFromText('graph TD; A-->')).toThrowErrorMatchingInlineSnapshot(` +"Parse error on line 3: +graph TD; A--> +--------------^ +Expecting 'AMP', 'ALPHA', 'COLON', 'PIPE', 'TESTSTR', 'DOWN', 'DEFAULT', 'NUM', 'COMMA', 'MINUS', 'BRKT', 'DOT', 'PUNCTUATION', 'UNICODE_TEXT', 'PLUS', 'EQUALS', 'MULT', 'UNDERSCORE', got 'EOF'" + `); + expect(() => getDiagramFromText('sequenceDiagram; A-->B')).toThrowErrorMatchingInlineSnapshot(` +"Parse error on line 1: +...quenceDiagram; A-->B +-----------------------^ +Expecting 'TXT', got 'NEWLINE'" + `); + }); + + test('should throw the right error for unregistered diagrams', () => { + expect(() => getDiagramFromText('thor TD; A-->B')).toThrowError( + 'No diagram type detected for text: thor TD; A-->B' + ); + }); +}); diff --git a/packages/mermaid/src/diagrams/c4/svgDraw.js b/packages/mermaid/src/diagrams/c4/svgDraw.js index d3d66a80d..690dd26ad 100644 --- a/packages/mermaid/src/diagrams/c4/svgDraw.js +++ b/packages/mermaid/src/diagrams/c4/svgDraw.js @@ -234,7 +234,7 @@ export const drawC4Shape = function (elem, c4Shape, conf) { const c4ShapeElem = elem.append('g'); c4ShapeElem.attr('class', 'person-man'); - // + // // draw rect of c4Shape const rect = getNoteRect(); switch (c4Shape.typeC4Shape.text) { @@ -251,9 +251,10 @@ export const drawC4Shape = function (elem, c4Shape, conf) { rect.fill = fillColor; rect.width = c4Shape.width; rect.height = c4Shape.height; - rect.style = 'stroke:' + strokeColor + ';stroke-width:0.5;'; + rect.stroke = strokeColor; rect.rx = 2.5; rect.ry = 2.5; + rect.attrs = { 'stroke-width': 0.5 }; drawRect(c4ShapeElem, rect); break; case 'system_db': @@ -371,12 +372,12 @@ export const drawC4Shape = function (elem, c4Shape, conf) { textFontConf = conf[c4Shape.typeC4Shape.text + 'Font'](); textFontConf.fontColor = fontColor; - if (c4Shape.thchn && c4Shape.thchn.text !== '') { + if (c4Shape.techn && c4Shape.techn?.text !== '') { _drawTextCandidateFunc(conf)( - c4Shape.thchn.text, + c4Shape.techn.text, c4ShapeElem, c4Shape.x, - c4Shape.y + c4Shape.thchn.Y, + c4Shape.y + c4Shape.techn.Y, c4Shape.width, c4Shape.height, { fill: fontColor, 'font-style': 'italic' }, diff --git a/packages/mermaid/src/diagrams/class/classRenderer-v2.js b/packages/mermaid/src/diagrams/class/classRenderer-v2.js index 3fecfcb9f..d95c29fd5 100644 --- a/packages/mermaid/src/diagrams/class/classRenderer-v2.js +++ b/packages/mermaid/src/diagrams/class/classRenderer-v2.js @@ -1,5 +1,5 @@ import { select } from 'd3'; -import * as graphlib from 'dagre-d3-es/src/graphlib'; +import * as graphlib from 'dagre-d3-es/src/graphlib/index.js'; import { log } from '../../logger'; import { getConfig } from '../../config'; import { render } from '../../dagre-wrapper/index.js'; diff --git a/packages/mermaid/src/diagrams/common/common.spec.js b/packages/mermaid/src/diagrams/common/common.spec.js index 68f5138e7..8fd6229da 100644 --- a/packages/mermaid/src/diagrams/common/common.spec.js +++ b/packages/mermaid/src/diagrams/common/common.spec.js @@ -68,5 +68,7 @@ describe('generic parser', function () { expect(parseGenericTypes('test ~Array~Array~string[]~~~')).toEqual( 'test >>' ); + expect(parseGenericTypes('~test')).toEqual('~test'); + expect(parseGenericTypes('~test Array~string~')).toEqual('~test Array'); }); }); diff --git a/packages/mermaid/src/diagrams/common/common.ts b/packages/mermaid/src/diagrams/common/common.ts index 194a9a4c0..d34a2df68 100644 --- a/packages/mermaid/src/diagrams/common/common.ts +++ b/packages/mermaid/src/diagrams/common/common.ts @@ -47,7 +47,9 @@ export const sanitizeText = (text: string, config: MermaidConfig): string => { if (config.dompurifyConfig) { text = DOMPurify.sanitize(sanitizeMore(text, config), config.dompurifyConfig).toString(); } else { - text = DOMPurify.sanitize(sanitizeMore(text, config)); + text = DOMPurify.sanitize(sanitizeMore(text, config), { + FORBID_TAGS: ['style'], + }).toString(); } return text; }; @@ -152,11 +154,17 @@ export const evaluate = (val?: string | boolean): boolean => export const parseGenericTypes = function (text: string): string { let cleanedText = text; - if (text.includes('~')) { - cleanedText = cleanedText.replace(/~([^~].*)/, '<$1'); - cleanedText = cleanedText.replace(/~([^~]*)$/, '>$1'); + if (text.split('~').length - 1 >= 2) { + let newCleanedText = cleanedText; - return parseGenericTypes(cleanedText); + // use a do...while loop instead of replaceAll to detect recursion + // e.g. Array~Array~T~~ + do { + cleanedText = newCleanedText; + newCleanedText = cleanedText.replace(/~([^\s,:;]+)~/, '<$1>'); + } while (newCleanedText != cleanedText); + + return parseGenericTypes(newCleanedText); } else { return cleanedText; } diff --git a/packages/mermaid/src/diagrams/er/erRenderer.js b/packages/mermaid/src/diagrams/er/erRenderer.js index ebf338ae1..e3b12d087 100644 --- a/packages/mermaid/src/diagrams/er/erRenderer.js +++ b/packages/mermaid/src/diagrams/er/erRenderer.js @@ -1,4 +1,4 @@ -import * as graphlib from 'dagre-d3-es/src/graphlib'; +import * as graphlib from 'dagre-d3-es/src/graphlib/index.js'; import { line, curveBasis, select } from 'd3'; import { layout as dagreLayout } from 'dagre-d3-es/src/dagre/index.js'; import { getConfig } from '../../config'; @@ -7,7 +7,7 @@ import utils from '../../utils'; import erMarkers from './erMarkers'; import { configureSvgSize } from '../../setupGraphViewbox'; import { parseGenericTypes } from '../common/common'; -import { v4 as uuid4 } from 'uuid'; +import { v5 as uuid5 } from 'uuid'; /** Regex used to remove chars from the entity name so the result can be used in an id */ const BAD_ID_CHARS_REGEXP = /[^\dA-Za-z](\W)*/g; @@ -643,9 +643,24 @@ export const draw = function (text, id, _version, diagObj) { svg.attr('viewBox', `${svgBounds.x - padding} ${svgBounds.y - padding} ${width} ${height}`); }; // draw +/** + * UUID namespace for ER diagram IDs + * + * This can be generated via running: + * + * ```js + * const { v5: uuid5 } = await import('uuid'); + * uuid5( + * 'https://mermaid-js.github.io/mermaid/syntax/entityRelationshipDiagram.html', + * uuid5.URL + * ); + * ``` + */ +const MERMAID_ERDIAGRAM_UUID = '28e9f9db-3c8d-5aa5-9faf-44286ae5937c'; + /** * Return a unique id based on the given string. Start with the prefix, then a hyphen, then the - * simplified str, then a hyphen, then a unique uuid. (Hyphens are only included if needed.) + * simplified str, then a hyphen, then a unique uuid based on the str. (Hyphens are only included if needed.) * Although the official XML standard for ids says that many more characters are valid in the id, * this keeps things simple by accepting only A-Za-z0-9. * @@ -656,7 +671,11 @@ export const draw = function (text, id, _version, diagObj) { */ export function generateId(str = '', prefix = '') { const simplifiedStr = str.replace(BAD_ID_CHARS_REGEXP, ''); - return `${strWithHyphen(prefix)}${strWithHyphen(simplifiedStr)}${uuid4()}`; + // we use `uuid v5` so that UUIDs are consistent given a string. + return `${strWithHyphen(prefix)}${strWithHyphen(simplifiedStr)}${uuid5( + str, + MERMAID_ERDIAGRAM_UUID + )}`; } /** diff --git a/packages/mermaid/src/diagrams/er/erRenderer.spec.ts b/packages/mermaid/src/diagrams/er/erRenderer.spec.ts new file mode 100644 index 000000000..ca0f62bd2 --- /dev/null +++ b/packages/mermaid/src/diagrams/er/erRenderer.spec.ts @@ -0,0 +1,12 @@ +import { generateId } from './erRenderer'; + +describe('erRenderer', () => { + describe('generateId', () => { + it('should be deterministic', () => { + const id1 = generateId('hello world', 'my-prefix'); + const id2 = generateId('hello world', 'my-prefix'); + + expect(id1).toBe(id2); + }); + }); +}); diff --git a/packages/mermaid/src/diagrams/er/parser/erDiagram.jison b/packages/mermaid/src/diagrams/er/parser/erDiagram.jison index f0411fd72..ada176a8d 100644 --- a/packages/mermaid/src/diagrams/er/parser/erDiagram.jison +++ b/packages/mermaid/src/diagrams/er/parser/erDiagram.jison @@ -29,9 +29,9 @@ accDescr\s*"{"\s* { this.begin("acc_descr_multili "erDiagram" return 'ER_DIAGRAM'; "{" { this.begin("block"); return 'BLOCK_START'; } \s+ /* skip whitespace in block */ -\b((?:PK)|(?:FK))\b return 'ATTRIBUTE_KEY' +\b((?:PK)|(?:FK)|(?:UK))\b return 'ATTRIBUTE_KEY' (.*?)[~](.*?)*[~] return 'ATTRIBUTE_WORD'; -[A-Za-z][A-Za-z0-9\-_\[\]]* return 'ATTRIBUTE_WORD' +[A-Za-z][A-Za-z0-9\-_\[\]\(\)]* return 'ATTRIBUTE_WORD' \"[^"]*\" return 'COMMENT'; [\n]+ /* nothing */ "}" { this.popState(); return 'BLOCK_STOP'; } diff --git a/packages/mermaid/src/diagrams/er/parser/erDiagram.spec.js b/packages/mermaid/src/diagrams/er/parser/erDiagram.spec.js index 43bc13e6d..ba00c602e 100644 --- a/packages/mermaid/src/diagrams/er/parser/erDiagram.spec.js +++ b/packages/mermaid/src/diagrams/er/parser/erDiagram.spec.js @@ -176,17 +176,18 @@ describe('when parsing ER diagram it...', function () { expect(entities[entity].attributes.length).toBe(1); }); - it('should allow an entity with attribute starting with fk or pk and a comment', function () { + it('should allow an entity with attribute starting with fk, pk or uk and a comment', function () { const entity = 'BOOK'; const attribute1 = 'int fk_title FK'; const attribute2 = 'string pk_author PK'; - const attribute3 = 'float pk_price PK "comment"'; + const attribute3 = 'string uk_address UK'; + const attribute4 = 'float pk_price PK "comment"'; erDiagram.parser.parse( - `erDiagram\n${entity} {\n${attribute1} \n\n${attribute2}\n${attribute3}\n}` + `erDiagram\n${entity} {\n${attribute1} \n\n${attribute2}\n${attribute3}\n${attribute4}\n}` ); const entities = erDb.getEntities(); - expect(entities[entity].attributes.length).toBe(3); + expect(entities[entity].attributes.length).toBe(4); }); it('should allow an entity with attribute that has a generic type', function () { @@ -214,6 +215,19 @@ describe('when parsing ER diagram it...', function () { expect(entities[entity].attributes.length).toBe(2); }); + it('should allow an entity with attribute that is a limited length string', function () { + const entity = 'BOOK'; + const attribute1 = 'character(10) isbn FK'; + const attribute2 = 'varchar(5) postal_code "Five digits"'; + + erDiagram.parser.parse(`erDiagram\n${entity} {\n${attribute1}\n${attribute2}\n}`); + const entities = erDb.getEntities(); + expect(Object.keys(entities).length).toBe(1); + expect(entities[entity].attributes.length).toBe(2); + expect(entities[entity].attributes[0].attributeType).toBe('character(10)'); + expect(entities[entity].attributes[1].attributeType).toBe('varchar(5)'); + }); + it('should allow an entity with multiple attributes to be defined', function () { const entity = 'BOOK'; const attribute1 = 'string title'; diff --git a/packages/mermaid/src/diagrams/flowchart/flowRenderer-v2.js b/packages/mermaid/src/diagrams/flowchart/flowRenderer-v2.js index 3e46aaaa5..29c7ba07a 100644 --- a/packages/mermaid/src/diagrams/flowchart/flowRenderer-v2.js +++ b/packages/mermaid/src/diagrams/flowchart/flowRenderer-v2.js @@ -1,4 +1,4 @@ -import * as graphlib from 'dagre-d3-es/src/graphlib'; +import * as graphlib from 'dagre-d3-es/src/graphlib/index.js'; import { select, curveLinear, selectAll } from 'd3'; import flowDb from './flowDb'; diff --git a/packages/mermaid/src/diagrams/flowchart/flowRenderer.js b/packages/mermaid/src/diagrams/flowchart/flowRenderer.js index 6cbc65532..63234b57c 100644 --- a/packages/mermaid/src/diagrams/flowchart/flowRenderer.js +++ b/packages/mermaid/src/diagrams/flowchart/flowRenderer.js @@ -1,4 +1,4 @@ -import * as graphlib from 'dagre-d3-es/src/graphlib'; +import * as graphlib from 'dagre-d3-es/src/graphlib/index.js'; import { select, curveLinear, selectAll } from 'd3'; import { getConfig } from '../../config'; import { render as Render } from 'dagre-d3-es'; diff --git a/packages/mermaid/src/diagrams/flowchart/parser/flow-direction.spec.js b/packages/mermaid/src/diagrams/flowchart/parser/flow-direction.spec.js index 5c2094737..7726ce0f7 100644 --- a/packages/mermaid/src/diagrams/flowchart/parser/flow-direction.spec.js +++ b/packages/mermaid/src/diagrams/flowchart/parser/flow-direction.spec.js @@ -1,6 +1,5 @@ import flowDb from '../flowDb'; import flow from './flow'; -import filter from 'lodash-es/filter'; import { setConfig } from '../../../config'; setConfig({ diff --git a/packages/mermaid/src/diagrams/flowchart/parser/subgraph.spec.js b/packages/mermaid/src/diagrams/flowchart/parser/subgraph.spec.js index 5ba6a5361..ae6f178b8 100644 --- a/packages/mermaid/src/diagrams/flowchart/parser/subgraph.spec.js +++ b/packages/mermaid/src/diagrams/flowchart/parser/subgraph.spec.js @@ -1,6 +1,5 @@ import flowDb from '../flowDb'; import flow from './flow'; -import filter from 'lodash-es/filter'; import { setConfig } from '../../../config'; setConfig({ diff --git a/packages/mermaid/src/diagrams/state/stateRenderer-v2.js b/packages/mermaid/src/diagrams/state/stateRenderer-v2.js index fa2470d6b..ebe18535d 100644 --- a/packages/mermaid/src/diagrams/state/stateRenderer-v2.js +++ b/packages/mermaid/src/diagrams/state/stateRenderer-v2.js @@ -1,4 +1,4 @@ -import * as graphlib from 'dagre-d3-es/src/graphlib'; +import * as graphlib from 'dagre-d3-es/src/graphlib/index.js'; import { select } from 'd3'; import { getConfig } from '../../config'; import { render } from '../../dagre-wrapper/index.js'; diff --git a/packages/mermaid/src/docs.mts b/packages/mermaid/src/docs.mts index 313d1f2de..1833d8be7 100644 --- a/packages/mermaid/src/docs.mts +++ b/packages/mermaid/src/docs.mts @@ -146,9 +146,22 @@ const readSyncedUTF8file = (filename: string): string => { return readFileSync(filename, 'utf8'); }; -const transformToBlockQuote = (content: string, type: string) => { - const title = type === 'warning' ? 'Warning' : 'Note'; - return `> **${title}** \n> ${content.replace(/\n/g, '\n> ')}`; +const blockIcons: Record = { + tip: '💡 ', + danger: '‼️ ', +}; + +const capitalize = (word: string) => word[0].toUpperCase() + word.slice(1); + +const transformToBlockQuote = (content: string, type: string, customTitle?: string | null) => { + if (vitepress) { + const vitepressType = type === 'note' ? 'info' : type; + return `::: ${vitepressType} ${customTitle || ''}\n${content}\n:::`; + } else { + const icon = blockIcons[type] || ''; + const title = `${icon}${customTitle || capitalize(type)}`; + return `> **${title}** \n> ${content.replace(/\n/g, '\n> ')}`; + } }; const injectPlaceholders = (text: string): string => @@ -194,8 +207,8 @@ const transformMarkdown = (file: string) => { } // Transform codeblocks into block quotes. - if (['note', 'tip', 'warning'].includes(c.lang)) { - return [remark.parse(transformToBlockQuote(c.value, c.lang))]; + if (['note', 'tip', 'warning', 'danger'].includes(c.lang)) { + return [remark.parse(transformToBlockQuote(c.value, c.lang, c.meta))]; } return [c]; @@ -260,7 +273,7 @@ const transformHtml = (filename: string) => { }; const getGlobs = (globs: string[]): string[] => { - globs.push('!**/dist', '!**/redirect.spec.ts'); + globs.push('!**/dist', '!**/redirect.spec.ts', '!**/landing'); if (!vitepress) { globs.push('!**/.vitepress', '!**/vite.config.ts', '!src/docs/index.md'); } diff --git a/packages/mermaid/src/docs/.vitepress/config.ts b/packages/mermaid/src/docs/.vitepress/config.ts index 74ed5e42c..fcceb1490 100644 --- a/packages/mermaid/src/docs/.vitepress/config.ts +++ b/packages/mermaid/src/docs/.vitepress/config.ts @@ -14,37 +14,34 @@ export default defineConfig({ lang: 'en-US', title: 'Mermaid', description: 'Create diagrams and visualizations using text and code.', - base: '/mermaid/', + base: '/', markdown: allMarkdownTransformers, - head: [['link', { rel: 'icon', type: 'image/x-icon', href: '/mermaid/favicon.ico' }]], + head: [['link', { rel: 'icon', type: 'image/x-icon', href: '/favicon.ico' }]], themeConfig: { nav: nav(), editLink: { pattern: 'https://github.com/mermaid-js/mermaid/edit/develop/packages/mermaid/src/docs/:path', text: 'Edit this page on GitHub', }, - sidebar: { '/': sidebarAll(), }, + socialLinks: [ + { icon: 'github', link: 'https://github.com/mermaid-js/mermaid' }, + { icon: 'slack', link: 'https://mermaid-talk.slack.com' }, + ], }, }); function nav() { return [ - { text: 'Intro', link: '/intro/', activeMatch: '/intro/' }, + { text: 'Docs', link: '/intro/', activeMatch: '/intro/' }, { - text: 'Configuration', - link: '/config/configuration', + text: 'Tutorials', + link: '/config/Tutorials', activeMatch: '/config/', }, - { text: 'Syntax', link: '/syntax/classDiagram', activeMatch: '/syntax/' }, - { text: 'Misc', link: '/misc/integrations', activeMatch: '/misc/' }, - { - text: 'Community', - link: '/community/n00b-overview', - activeMatch: '/community/', - }, + { text: 'Integrations', link: '/misc/integrations', activeMatch: '/misc/' }, { text: version, items: [ diff --git a/packages/mermaid/src/docs/.vitepress/theme/custom.css b/packages/mermaid/src/docs/.vitepress/theme/custom.css index e1ef049cd..28ef8d338 100644 --- a/packages/mermaid/src/docs/.vitepress/theme/custom.css +++ b/packages/mermaid/src/docs/.vitepress/theme/custom.css @@ -1,3 +1,6 @@ +@import url('https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css'); +@import url('https://cdn.jsdelivr.net/npm/@mdi/font@6.9.96/css/materialdesignicons.min.css'); + :root { --vp-c-brand: #ff3670; --vp-c-brand-light: #ff5e8c; diff --git a/packages/mermaid/src/docs/.vitepress/theme/index.ts b/packages/mermaid/src/docs/.vitepress/theme/index.ts index efb065fea..ef929aa5d 100644 --- a/packages/mermaid/src/docs/.vitepress/theme/index.ts +++ b/packages/mermaid/src/docs/.vitepress/theme/index.ts @@ -18,7 +18,7 @@ export default { if (newPath) { console.log(`Redirecting to ${newPath} from ${window.location}`); // router.go isn't loading the ID properly. - window.location.href = `/mermaid/${newPath}`; + window.location.href = `/${newPath}`; } } catch (e) {} }; diff --git a/packages/mermaid/src/docs/.vitepress/theme/mermaid.ts b/packages/mermaid/src/docs/.vitepress/theme/mermaid.ts index 556eac4f5..f10aa8168 100644 --- a/packages/mermaid/src/docs/.vitepress/theme/mermaid.ts +++ b/packages/mermaid/src/docs/.vitepress/theme/mermaid.ts @@ -2,13 +2,16 @@ import mermaid, { type MermaidConfig } from 'mermaid'; import mindmap from '@mermaid-js/mermaid-mindmap'; import timeline from '@mermaid-js/mermaid-timeline'; -try { - await mermaid.registerExternalDiagrams([mindmap,timeline]); -} catch (e) { - console.error(e); -} +const init = (async () => { + try { + await mermaid.registerExternalDiagrams([mindmap,timeline]); + } catch (e) { + console.error(e); + } +})(); export const render = async (id: string, code: string, config: MermaidConfig): Promise => { + await init; mermaid.initialize(config); const svg = await mermaid.renderAsync(id, code); return svg; diff --git a/packages/mermaid/src/docs/.vitepress/theme/redirect.spec.ts b/packages/mermaid/src/docs/.vitepress/theme/redirect.spec.ts index c26364108..6070abee4 100644 --- a/packages/mermaid/src/docs/.vitepress/theme/redirect.spec.ts +++ b/packages/mermaid/src/docs/.vitepress/theme/redirect.spec.ts @@ -8,6 +8,7 @@ test.each([ ['http://localhost:1234/mermaid/#/flowchart.md', 'syntax/flowchart.html'], ['http://localhost/mermaid/#/flowchart.md', 'syntax/flowchart.html'], ['https://mermaid-js.github.io/mermaid/#/flowchart.md', 'syntax/flowchart.html'], + ['https://mermaid.js.org/#/flowchart.md', 'syntax/flowchart.html'], ['https://mermaid-js.github.io/mermaid/#/./flowchart', 'syntax/flowchart.html'], ['https://mermaid-js.github.io/mermaid/#/flowchart', 'syntax/flowchart.html'], ['https://mermaid-js.github.io/mermaid/#flowchart', 'syntax/flowchart.html'], @@ -31,7 +32,4 @@ test.each([ test('should throw for invalid URL', () => { // Not mermaid domain expect(() => getRedirect('https://www.google.com')).toThrowError(); - - // Not `/mermaid/` path - expect(() => getRedirect('http://localhost/#/flowchart.md')).toThrowError(); }); diff --git a/packages/mermaid/src/docs/.vitepress/theme/redirect.ts b/packages/mermaid/src/docs/.vitepress/theme/redirect.ts index ca4606be0..58537b0ef 100644 --- a/packages/mermaid/src/docs/.vitepress/theme/redirect.ts +++ b/packages/mermaid/src/docs/.vitepress/theme/redirect.ts @@ -10,8 +10,9 @@ export interface Redirect { const getBaseFile = (link: string): Redirect => { const url = new URL(link); if ( - (url.hostname !== 'mermaid-js.github.io' && url.hostname !== 'localhost') || - url.pathname !== '/mermaid/' + url.hostname !== 'mermaid-js.github.io' && + url.hostname !== 'mermaid.js.org' && + url.hostname !== 'localhost' ) { throw new Error('Not mermaidjs url'); } diff --git a/packages/mermaid/src/docs/community/newDiagram.md b/packages/mermaid/src/docs/community/newDiagram.md index 57a454671..75e17e4c9 100644 --- a/packages/mermaid/src/docs/community/newDiagram.md +++ b/packages/mermaid/src/docs/community/newDiagram.md @@ -55,7 +55,7 @@ Place the renderer in the diagram folder. ### Step 3: Detection of the new diagram type -The second thing to do is to add the capability to detect the new new diagram to type to the detectType in utils.js. The detection should return a key for the new diagram type. +The second thing to do is to add the capability to detect the new diagram to type to the detectType in utils.js. The detection should return a key for the new diagram type. [This key will be used to as the aria roledescription](#aria-roledescription), so it should be a word that clearly describes the diagram type. For example, if your new diagram use a UML deployment diagram, a good key would be "UMLDeploymentDiagram" because assistive technologies such as a screen reader would voice that as "U-M-L Deployment diagram." Another good key would be "deploymentDiagram" because that would be voiced as "Deployment Diagram." A bad key would be "deployment" because that would not sufficiently describe the diagram. diff --git a/packages/mermaid/src/docs/config/accessibility.md b/packages/mermaid/src/docs/config/accessibility.md index e7947adec..67fb090b8 100644 --- a/packages/mermaid/src/docs/config/accessibility.md +++ b/packages/mermaid/src/docs/config/accessibility.md @@ -74,10 +74,11 @@ A **multiple line accessible description** _does not have a colon (`:`) after th Ex: -``` -accDescr { The official Bob's Burgers corporate processes that are used - for making very, very big decisions. - This is actually a very simple flow: see the big decision and then make the big decision.} +```markdown +accDescr { +This is a multiple line accessible description. +It does not have a colon and is surrounded by curly brackets. +} ``` See [the accTitle and accDescr usage examples](#acctitle-and-accdescr-usage-examples) for how this can be used in a diagram and the resulting HTML generated. diff --git a/packages/mermaid/src/docs/config/directives.md b/packages/mermaid/src/docs/config/directives.md index bc74ad309..ac57e6d21 100644 --- a/packages/mermaid/src/docs/config/directives.md +++ b/packages/mermaid/src/docs/config/directives.md @@ -26,8 +26,8 @@ Mermaid basically supports two types of configuration options to be overridden b **NOTE:** These options listed here are not all the configuration options. To get hold of all the configuration options, please refer to the [defaultConfig.ts](https://github.com/mermaid-js/mermaid/blob/develop/packages/mermaid/src/defaultConfig.ts) in the source code. -``` -Soon we plan to publish a complete list of top-level configurations & all the diagram specific configurations, with their possible values in the docs +```note +We plan to publish a complete list of top-level configurations & all the diagram specific configurations, with their possible values in the docs soon. ``` ## Declaring directives diff --git a/packages/mermaid/src/docs/config/n00b-advanced.md b/packages/mermaid/src/docs/config/n00b-advanced.md index 1e6546f5c..2932faa48 100644 --- a/packages/mermaid/src/docs/config/n00b-advanced.md +++ b/packages/mermaid/src/docs/config/n00b-advanced.md @@ -4,8 +4,8 @@ A more condensed html code can be achieved by embedding the mermaid code in its own .js file, which is referenced like so: -``` -stuff stuff +```html +... @@ -13,12 +13,12 @@ stuff stuff The actual mermaid file could for example look like this: +```javascript +mermaid content ... ``` -mermaid content... -``` - ---- ## mermaid configuration options -... +```markdown +(coming soon) +``` diff --git a/packages/mermaid/src/docs/config/theming.md b/packages/mermaid/src/docs/config/theming.md index 2d4da9530..fb3026fec 100644 --- a/packages/mermaid/src/docs/config/theming.md +++ b/packages/mermaid/src/docs/config/theming.md @@ -6,15 +6,15 @@ Themes can now be customized at the site-wide level, or on individual Mermaid di ## Available Themes -1. **default** - This is the default theme for all diagrams. +1. [**default**](https://github.com/mermaid-js/mermaid/blob/develop/packages/mermaid/src/themes/theme-default.js) - This is the default theme for all diagrams. -1. **neutral** - This theme is great for black and white documents that will be printed. +2. [**neutral**](https://github.com/mermaid-js/mermaid/blob/develop/packages/mermaid/src/themes/theme-neutral.js) - This theme is great for black and white documents that will be printed. -1. **dark** - This theme goes well with dark-colored elements or dark-mode. +3. [**dark**](https://github.com/mermaid-js/mermaid/blob/develop/packages/mermaid/src/themes/theme-dark.js) - This theme goes well with dark-colored elements or dark-mode. -1. **forest** - This theme contains shades of green. +4. [**forest**](https://github.com/mermaid-js/mermaid/blob/develop/packages/mermaid/src/themes/theme-forest.js) - This theme contains shades of green. -1. **base** - This is the only theme that can be modified. Use this theme as the base for customizations. +5. [**base**](https://github.com/mermaid-js/mermaid/blob/develop/packages/mermaid/src/themes/theme-base.js) - This is the only theme that can be modified. Use this theme as the base for customizations. ## Site-wide Theme @@ -35,7 +35,13 @@ To customize the theme of an individual diagram, use the `init` directive. Example of `init` directive setting the `theme` to `forest`: -```mmd +```mermaid-example +%%{init: {'theme':'forest'}}%% + graph TD + a --> b +``` + +```mermaid %%{init: {'theme':'forest'}}%% graph TD a --> b @@ -85,6 +91,36 @@ Example of modifying `themeVariables` using the `init` directive: end ``` +```mermaid +%%{ + init: { + 'theme': 'base', + 'themeVariables': { + 'primaryColor': '#BB2528', + 'primaryTextColor': '#fff', + 'primaryBorderColor': '#7C0000', + 'lineColor': '#F8B229', + 'secondaryColor': '#006100', + 'tertiaryColor': '#fff' + } + } +}%% + graph TD + A[Christmas] -->|Get money| B(Go shopping) + B --> C{Let me think} + B --> G[/Another/] + C ==>|One| D[Laptop] + C -->|Two| E[iPhone] + C -->|Three| F[fa:fa-car Car] + subgraph section + C + D + E + F + G + end +``` + ## Color and Color Calculation To ensure diagram readability, the default value of certain variables is calculated or derived from other variables. For example, `primaryBorderColor` is derived from the `primaryColor` variable. So if the `primaryColor` variable is customized, Mermaid will adjust `primaryBorderColor` automatically. Adjustments can mean a color inversion, a hue change, a darkening/lightening by 10%, etc. diff --git a/packages/mermaid/src/docs/config/usage.md b/packages/mermaid/src/docs/config/usage.md index 3eac4ad6f..bbfc192c7 100644 --- a/packages/mermaid/src/docs/config/usage.md +++ b/packages/mermaid/src/docs/config/usage.md @@ -16,26 +16,21 @@ For the majority of users, Using the [Live Editor](https://mermaid.live/) would We have compiled some Video [Tutorials](./Tutorials.md) on how to use the mermaid Live Editor. -**Installing and Hosting Mermaid on a Webpage** +### Installing and Hosting Mermaid on a Webpage -**Using the npm package** +**Using the npm package:** -``` -1. You will need to install node v16, which would have npm. +1. You will need to install `node v16`, which would have npm. -2. download yarn using npm. +2. Download `yarn` using npm. -3. enter the following command: - yarn add mermaid +3. Enter the following command: `yarn add mermaid`. -4. At this point, you can add mermaid as a dev dependency using this command: - yarn add --dev mermaid +4. At this point, you can add mermaid as a dev dependency using this command: `yarn add --dev mermaid`. -5. Alternatively, you can also deploy mermaid using the script tag in an HTML file with mermaid diagram descriptions. - as is shown in the example below -``` +5. Alternatively, you can also deploy mermaid using the script tag in an HTML file with mermaid diagram descriptions as is shown in the example below. -**Hosting mermaid on a web page.** +**Hosting mermaid on a web page:** > Note:This topic explored in greater depth in the [User Guide for Beginners](../intro/n00b-gettingStarted.md) diff --git a/packages/mermaid/src/docs/index.md b/packages/mermaid/src/docs/index.md index 6c2763904..59a4c03f9 100644 --- a/packages/mermaid/src/docs/index.md +++ b/packages/mermaid/src/docs/index.md @@ -21,13 +21,17 @@ hero: features: - title: ➕ Easy to use! - details: Mermaid allows even non-programmers to easily create detailed and diagrams through the Mermaid Live Editor. + details: Easily create and render detailed diagrams and charts with the Mermaid Live Editor. + link: https://mermaid.live/ - title: 🎥 Video Tutorials! - details: Has video tutorials for beginners and advanced users. - - title: 🏆 Award winner! - details: Mermaid was nominated and won the JS Open Source Awards (2019) in the category "The most exciting use of technology"!!! + details: Curated list of video tutorials and examples created by the community. + link: ../../config/Tutorials.html - title: 🧩 Integrations available! - details: Use Mermaid with your favorite applications, check out the list of Integrations and Usages of Mermaid. + details: Use Mermaid with your favorite applications, check out the integrations list. + link: ../../misc/integrations.md + - title: 🏆 Award winning! + details: 2019 JavaScript Open Source Award winner for "The Most Exciting Use of Technology". + link: https://osawards.com/javascript/2019 --- + + + + + + +
+
+ +
+
+
+

MermaidPress

+

+ The Official Guide to Mermaid.js +

+

+ Learn to create complex diagrams and beautiful flowcharts easily using text and code + using Mermaid.js. +

+ + + +
+
+
+ +
+ +
+
+
+
+ + + + + + + + + + + + +
+
+
+

+ Get up to speed with using Mermaid diagrams along with real-world examples and expert tips + from the authors to facilitate a seamless development workflow +

+
+
+
+
+
+

+ Flowcharts is a diagram type that visualizes a process or an algorithm by showing the + steps in order, as well as the different paths the execution can take. +

+
+
+ +
+
+
+
+ +
+
+
+

+ Sequence diagrams lets you model and visualize interactions between different actors + or objects in a system, as well as the order of those interactions +

+
+
+
+
+
+

+ A class diagram is a graphical representation that is used to visualize and describe + an object-oriented system. +

+
+
+ +
+
+
+
+ +
+
+
+

+ An entity-relationship diagram is a graphical representation that is used to + visualize the different types of entities that exist within a system. +

+
+
+
+
+
+

+ Use State diagrams to model and document state machines, an abstract way of + representing a system or an algorithm. +

+
+
+ +
+
+
+
+ +
+
+
+

+ A Gantt chart is a graphical representation that is used to visualize and describe + tasks (events or activities) over time. +

+
+
+
+
+

+ These were a few of the diagrams supported by Mermaid. +

+
+ +
+
+

+ Book description +

+
+

+ Mermaid lets you represent diagrams using text and code which simplifies the maintenance + of complex diagrams. This is a great option for developers as they’re more familiar with + code, rather than special tools for generating diagrams. Besides, diagrams in code + simplify maintenance and ensure that the code is supported by version control systems. + In some cases, Mermaid makes refactoring support for name changes possible while also + enabling team collaboration for review distribution and updates. +

+

+ Developers working with any system will be able to put their knowledge to work with this + practical guide to using Mermaid for documentation. The book is also a great reference + for looking up the syntax for specific diagrams when authoring diagrams. +

+

+ You’ll start by getting up to speed with the importance of accurate and visual + documentation. Next, the book introduces Mermaid and establishes how to use it to create + effective documentation. By using different tools, editors, or a custom documentation + platform, you’ll also learn how to use Mermaid syntax for various diagrams. Later + chapters cover advanced configuration settings and theme options to manipulate your + diagram as per your needs. +

+

+ By the end of this Mermaid book, you’ll have become well-versed with the different types + of Mermaid diagrams and how they can be used in your workflows. +

+
+
+
+
+
+

+ What you will learn +

+
+
+
+
+
+
+
    +
  • + Understand good and bad documentation, and the art of effective documentation +
  • +
  • + Become well-versed with maintaining complex diagrams with ease +
  • +
  • + Learn how to set up a custom documentation system +
  • +
  • + Learn how to implement Mermaid diagrams in your workflows +
  • +
  • + Understand how to set up themes for a Mermaid diagram for an entire site +
  • +
  • + Discover how to draw different types of diagrams such as flowcharts, class + diagrams, Gantt charts, and more +
  • +
+
+
+
+
+
+ + + + + + + + + + + + + + + + + +
+

+ Purchase The Official Guide to Mermaid.js +

+
+
+
+

+

Written by Knut Sveidqvist and Ashish Jain.

+

+ Knut is the creator of Mermaid and both authors are active core team members of the + Mermaid open-source project. +

+

+ + + +
+ + + diff --git a/packages/mermaid/src/docs/landing/sequence-diagram.png b/packages/mermaid/src/docs/landing/sequence-diagram.png new file mode 100644 index 000000000..8c51ac1c5 Binary files /dev/null and b/packages/mermaid/src/docs/landing/sequence-diagram.png differ diff --git a/packages/mermaid/src/docs/landing/state.png b/packages/mermaid/src/docs/landing/state.png new file mode 100644 index 000000000..2ef66ea2f Binary files /dev/null and b/packages/mermaid/src/docs/landing/state.png differ diff --git a/packages/mermaid/src/docs/misc/integrations.md b/packages/mermaid/src/docs/misc/integrations.md index 55d0e5b20..e16375872 100644 --- a/packages/mermaid/src/docs/misc/integrations.md +++ b/packages/mermaid/src/docs/misc/integrations.md @@ -15,6 +15,7 @@ They also serve as proof of concept, for the variety of things that can be built - [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) (**Native support**) - [Tuleap](https://docs.tuleap.org/user-guide/writing-in-tuleap.html#graphs) (**Native support**) - [Joplin](https://joplinapp.org) (**Native support**) +- [Swimm](https://swimm.io) (**Native support**) - [Notion](https://notion.so) (**Native support**) - [Observable](https://observablehq.com/@observablehq/mermaid) (**Native support**) - [Obsidian](https://help.obsidian.md/How+to/Format+your+notes#Diagram) (**Native support**) diff --git a/packages/mermaid/src/docs/syntax/classDiagram.md b/packages/mermaid/src/docs/syntax/classDiagram.md index 8cd5796ff..10ccc3522 100644 --- a/packages/mermaid/src/docs/syntax/classDiagram.md +++ b/packages/mermaid/src/docs/syntax/classDiagram.md @@ -123,7 +123,7 @@ class BankAccount{ #### Generic Types -Members can be defined using generic types, such as `List`, for fields, parameters, and return types by enclosing the type within `~` (**tilde**). Note: **nested** type declarations such as `List>` are not currently supported. +Members can be defined using generic types, such as `List`, for fields, parameters, and return types by enclosing the type within `~` (**tilde**). **Nested** type declarations such as `List>` are supported. Generics can be represented as part of a class definition and also in the parameters or the return value of a method/function: @@ -139,6 +139,7 @@ class Square~Shape~{ Square : -List~string~ messages Square : +setMessages(List~string~ messages) Square : +getMessages() List~string~ +Square : +getDistanceMatrix() List~List~int~~ ``` #### Visibility @@ -172,7 +173,7 @@ There are eight different types of relations defined for classes under UML which | Type | Description | | ------- | ------------- | | `<\|--` | Inheritance | -| `\*--` | Composition | +| `*--` | Composition | | `o--` | Aggregation | | `-->` | Association | | `--` | Link (Solid) | diff --git a/packages/mermaid/src/docs/syntax/entityRelationshipDiagram.md b/packages/mermaid/src/docs/syntax/entityRelationshipDiagram.md index c666877c5..a670c6837 100644 --- a/packages/mermaid/src/docs/syntax/entityRelationshipDiagram.md +++ b/packages/mermaid/src/docs/syntax/entityRelationshipDiagram.md @@ -124,7 +124,7 @@ erDiagram ### Attributes -Attributes can be defined for entities by specifying the entity name followed by a block containing multiple `type name` pairs, where a block is delimited by an opening `{` and a closing `}`. For example: +Attributes can be defined for entities by specifying the entity name followed by a block containing multiple `type name` pairs, where a block is delimited by an opening `{` and a closing `}`. The attributes are rendered inside the entity boxes. For example: ```mermaid-example erDiagram @@ -142,43 +142,26 @@ erDiagram } ``` -The attributes are rendered inside the entity boxes: - -```mermaid-example -erDiagram - CAR ||--o{ NAMED-DRIVER : allows - CAR { - string registrationNumber - string make - string model - } - PERSON ||--o{ NAMED-DRIVER : is - PERSON { - string firstName - string lastName - int age - } -``` - -The `type` and `name` values must begin with an alphabetic character and may contain digits, hyphens or underscores. Other than that, there are no restrictions, and there is no implicit set of valid data types. +The `type` and `name` values must begin with an alphabetic character and may contain digits, hyphens, underscores, parentheses and square brackets. Other than that, there are no restrictions, and there is no implicit set of valid data types. #### Attribute Keys and Comments -Attributes may also have a `key` or comment defined. Keys can be "PK" or "FK", for Primary Key or Foreign Key. And a `comment` is defined by double quotes at the end of an attribute. Comments themselves cannot have double-quote characters in them. +Attributes may also have a `key` or comment defined. Keys can be "PK", "FK" or "UK", for Primary Key, Foreign Key or Unique Key. And a `comment` is defined by double quotes at the end of an attribute. Comments themselves cannot have double-quote characters in them. ```mermaid-example erDiagram CAR ||--o{ NAMED-DRIVER : allows CAR { string allowedDriver FK "The license of the allowed driver" - string registrationNumber + string registrationNumber UK string make string model + string[] parts } PERSON ||--o{ NAMED-DRIVER : is PERSON { string driversLicense PK "The license #" - string firstName + string(99) firstName "Only 99 characters are allowed" string lastName int age } diff --git a/packages/mermaid/src/docs/syntax/gantt.md b/packages/mermaid/src/docs/syntax/gantt.md index c9301bfee..0cc915ca1 100644 --- a/packages/mermaid/src/docs/syntax/gantt.md +++ b/packages/mermaid/src/docs/syntax/gantt.md @@ -104,34 +104,33 @@ Final milestone : milestone, m2, 18:14, 2min The default input date format is `YYYY-MM-DD`. You can define your custom `dateFormat`. -``` +```markdown dateFormat YYYY-MM-DD ``` The following formatting options are supported: -``` -Input Example Description: -YYYY 2014 4 digit year -YY 14 2 digit year -Q 1..4 Quarter of year. Sets month to first month in quarter. -M MM 1..12 Month number -MMM MMMM January..Dec Month name in locale set by moment.locale() -D DD 1..31 Day of month -Do 1st..31st Day of month with ordinal -DDD DDDD 1..365 Day of year -X 1410715640.579 Unix timestamp -x 1410715640579 Unix ms timestamp -H HH 0..23 24 hour time -h hh 1..12 12 hour time used with a A. -a A am pm Post or ante meridiem -m mm 0..59 Minutes -s ss 0..59 Seconds -S 0..9 Tenths of a second -SS 0..99 Hundreds of a second -SSS 0..999 Thousandths of a second -Z ZZ +12:00 Offset from UTC as +-HH:mm, +-HHmm, or Z -``` +| Input | Example | Description | +| ---------- | -------------- | ------------------------------------------------------ | +| `YYYY` | 2014 | 4 digit year | +| `YY` | 14 | 2 digit year | +| `Q` | 1..4 | Quarter of year. Sets month to first month in quarter. | +| `M MM` | 1..12 | Month number | +| `MMM MMMM` | January..Dec | Month name in locale set by `moment.locale()` | +| `D DD` | 1..31 | Day of month | +| `Do` | 1st..31st | Day of month with ordinal | +| `DDD DDDD` | 1..365 | Day of year | +| `X` | 1410715640.579 | Unix timestamp | +| `x` | 1410715640579 | Unix ms timestamp | +| `H HH` | 0..23 | 24 hour time | +| `h hh` | 1..12 | 12 hour time used with `a A`. | +| `a A` | am pm | Post or ante meridiem | +| `m mm` | 0..59 | Minutes | +| `s ss` | 0..59 | Seconds | +| `S` | 0..9 | Tenths of a second | +| `SS` | 0..99 | Hundreds of a second | +| `SSS` | 0..999 | Thousandths of a second | +| `Z ZZ` | +12:00 | Offset from UTC as +-HH:mm, +-HHmm, or Z | More info in: https://momentjs.com/docs/#/parsing/string-format/ @@ -139,38 +138,38 @@ More info in: https://momentjs.com/docs/#/parsing/string-format/ The default output date format is `YYYY-MM-DD`. You can define your custom `axisFormat`, like `2020-Q1` for the first quarter of the year 2020. -``` -axisFormat %Y-%m-%d +```markdown +axisFormat %Y-%m-%d ``` The following formatting strings are supported: -``` -%a - abbreviated weekday name. -%A - full weekday name. -%b - abbreviated month name. -%B - full month name. -%c - date and time, as "%a %b %e %H:%M:%S %Y". -%d - zero-padded day of the month as a decimal number [01,31]. -%e - space-padded day of the month as a decimal number [ 1,31]; equivalent to %_d. -%H - hour (24-hour clock) as a decimal number [00,23]. -%I - hour (12-hour clock) as a decimal number [01,12]. -%j - day of the year as a decimal number [001,366]. -%m - month as a decimal number [01,12]. -%M - minute as a decimal number [00,59]. -%L - milliseconds as a decimal number [000, 999]. -%p - either AM or PM. -%S - second as a decimal number [00,61]. -%U - week number of the year (Sunday as the first day of the week) as a decimal number [00,53]. -%w - weekday as a decimal number [0(Sunday),6]. -%W - week number of the year (Monday as the first day of the week) as a decimal number [00,53]. -%x - date, as "%m/%d/%Y". -%X - time, as "%H:%M:%S". -%y - year without century as a decimal number [00,99]. -%Y - year with century as a decimal number. -%Z - time zone offset, such as "-0700". -%% - a literal "%" character. -``` +| Format | Definition | +| ------ | ----------------------------------------------------------------------------------------- | +| %a | abbreviated weekday name | +| %A | full weekday name | +| %b | abbreviated month name | +| %B | full month name | +| %c | date and time, as "%a %b %e %H:%M:%S %Y" | +| %d | zero-padded day of the month as a decimal number [01,31] | +| %e | space-padded day of the month as a decimal number [ 1,31]; equivalent to %\_d | +| %H | hour (24-hour clock) as a decimal number [00,23] | +| %I | hour (12-hour clock) as a decimal number [01,12] | +| %j | day of the year as a decimal number [001,366] | +| %m | month as a decimal number [01,12] | +| %M | minute as a decimal number [00,59] | +| %L | milliseconds as a decimal number [000, 999] | +| %p | either AM or PM | +| %S | second as a decimal number [00,61] | +| %U | week number of the year (Sunday as the first day of the week) as a decimal number [00,53] | +| %w | weekday as a decimal number [0(Sunday),6] | +| %W | week number of the year (Monday as the first day of the week) as a decimal number [00,53] | +| %x | date, as "%m/%d/%Y" | +| %X | time, as "%H:%M:%S" | +| %y | year without century as a decimal number [00,99] | +| %Y | year with century as a decimal number | +| %Z | time zone offset, such as "-0700" | +| %% | a literal "%" character | More info in: [https://github.com/d3/d3-time-format/tree/v4.0.0#locale_format](https://github.com/d3/d3-time-format/tree/v4.0.0#locale_format) @@ -178,14 +177,14 @@ More info in: [https://github.com/d3/d3-time-format/tree/v4.0.0#locale_format](h The default output ticks are auto. You can custom your `tickInterval`, like `1day` or `1week`. -``` +```markdown tickInterval 1day ``` The pattern is: -``` -/^([1-9][0-9]*)(minute|hour|day|week|month)$/ +```javascript +/^([1-9][0-9]*)(minute|hour|day|week|month)$/; ``` More info in: [https://github.com/d3/d3-time#interval_every](https://github.com/d3/d3-time#interval_every) diff --git a/packages/mermaid/src/docs/syntax/mindmap.md b/packages/mermaid/src/docs/syntax/mindmap.md index beaae7ad5..3b737a572 100644 --- a/packages/mermaid/src/docs/syntax/mindmap.md +++ b/packages/mermaid/src/docs/syntax/mindmap.md @@ -112,7 +112,7 @@ More shapes will be added, beginning with the shapes available in flowcharts. # Icons and classes -## icons +## Icons As with flowcharts you can add icons to your nodes but with an updated syntax. The styling for the font based icons are added during the integration so that they are available for the web page. _This is not something a diagram author can do but has to be done with the site administrator or the integrator_. Once the icon fonts are in place you add them to the mind map nodes using the `::icon()` syntax. You place the classes for the icon within the parenthesis like in the following example where icons for material design and fontawesome 4 are displayed. The intention is that this approach should be used for all diagrams supporting icons. **Experimental feature:** This wider scope is also the reason Mindmaps are experimental as this syntax and approach could change. diff --git a/packages/mermaid/src/docs/syntax/sequenceDiagram.md b/packages/mermaid/src/docs/syntax/sequenceDiagram.md index 9c28883c9..facb43a49 100644 --- a/packages/mermaid/src/docs/syntax/sequenceDiagram.md +++ b/packages/mermaid/src/docs/syntax/sequenceDiagram.md @@ -130,6 +130,14 @@ sequenceDiagram Note over Alice,John: A typical interaction ``` +It is also possible to add a line break (applies to text input in general): + +```mermaid-example +sequenceDiagram + Alice->John: Hello John, how are you? + Note over Alice,John: A typical interaction
But now in two lines +``` + ## Loops It is possible to express loops in a sequence diagram. This is done by the notation diff --git a/packages/mermaid/src/mermaid.ts b/packages/mermaid/src/mermaid.ts index 7a4d744e4..6217d514e 100644 --- a/packages/mermaid/src/mermaid.ts +++ b/packages/mermaid/src/mermaid.ts @@ -2,6 +2,8 @@ * Web page integration module for the mermaid framework. It uses the mermaidAPI for mermaid * functionality and to render the diagrams to svg code! */ +import dedent from 'ts-dedent'; + import { MermaidConfig } from './config.type'; import { log } from './logger'; import utils from './utils'; @@ -148,8 +150,7 @@ const initThrowsErrors = function ( txt = element.innerHTML; // transforms the html to pure text - txt = utils - .entityDecode(txt) + txt = dedent(utils.entityDecode(txt)) // removes indentation, required for YAML parsing .trim() .replace(//gi, '
'); @@ -290,8 +291,7 @@ const initThrowsErrorsAsync = async function ( txt = element.innerHTML; // transforms the html to pure text - txt = utils - .entityDecode(txt) + txt = dedent(utils.entityDecode(txt)) // removes indentation, required for YAML parsing .trim() .replace(//gi, '
'); diff --git a/packages/mermaid/src/mermaidAPI.spec.ts b/packages/mermaid/src/mermaidAPI.spec.ts index f9bad66d7..67138435e 100644 --- a/packages/mermaid/src/mermaidAPI.spec.ts +++ b/packages/mermaid/src/mermaidAPI.spec.ts @@ -470,61 +470,48 @@ describe('mermaidAPI', function () { svgElement.id = svgId; const tempDivElement = givenDocument.createElement('div'); // doesn't matter what the tag is in the test tempDivElement.id = tempDivId; - const tempiFrameElement = givenDocument.createElement('div'); // doesn't matter what the tag is in the test + const tempiFrameElement = givenDocument.createElement('iframe'); // doesn't matter what the tag is in the test tempiFrameElement.id = tempIframeId; it('removes an existing element with given id', () => { rootHtml.appendChild(svgElement); + rootHtml.append(tempDivElement); + rootHtml.append(tempiFrameElement); + expect(givenDocument.getElementById(svgElement.id)).toEqual(svgElement); - removeExistingElements(givenDocument, false, svgId, tempDivId, tempIframeId); + expect(givenDocument.getElementById(tempDivElement.id)).toEqual(tempDivElement); + expect(givenDocument.getElementById(tempiFrameElement.id)).toEqual(tempiFrameElement); + removeExistingElements(givenDocument, svgId, tempDivId, tempIframeId); expect(givenDocument.getElementById(svgElement.id)).toBeNull(); + expect(givenDocument.getElementById(tempDivElement.id)).toBeNull(); + expect(givenDocument.getElementById(tempiFrameElement.id)).toBeNull(); }); - describe('is in sandboxed mode', () => { - const inSandboxedMode = true; + it('removes an existing iframe element even if div element is absent', () => { + tempiFrameElement.append(svgElement); + rootHtml.append(tempiFrameElement); - it('removes an existing element with the given iFrame selector', () => { - tempiFrameElement.append(svgElement); - rootHtml.append(tempiFrameElement); - rootHtml.append(tempDivElement); - - expect(givenDocument.getElementById(tempIframeId)).toEqual(tempiFrameElement); - expect(givenDocument.getElementById(tempDivId)).toEqual(tempDivElement); - expect(givenDocument.getElementById(svgId)).toEqual(svgElement); - removeExistingElements( - givenDocument, - inSandboxedMode, - svgId, - '#' + tempDivId, - '#' + tempIframeId - ); - expect(givenDocument.getElementById(tempDivId)).toEqual(tempDivElement); - expect(givenDocument.getElementById(tempIframeId)).toBeNull(); - expect(givenDocument.getElementById(svgId)).toBeNull(); - }); + expect(givenDocument.getElementById(tempIframeId)).toEqual(tempiFrameElement); + expect(givenDocument.getElementById(tempDivId)).toBeNull(); + expect(givenDocument.getElementById(svgId)).toEqual(svgElement); + removeExistingElements(givenDocument, svgId, tempDivId, tempIframeId); + expect(givenDocument.getElementById(tempDivId)).toBeNull(); + expect(givenDocument.getElementById(tempIframeId)).toBeNull(); + expect(givenDocument.getElementById(svgId)).toBeNull(); }); - describe('not in sandboxed mode', () => { - const inSandboxedMode = false; - it('removes an existing element with the given enclosing div selector', () => { - tempDivElement.append(svgElement); - rootHtml.append(tempDivElement); - rootHtml.append(tempiFrameElement); + it('removes both existing div and iframe elements when both are present', () => { + tempDivElement.append(svgElement); + rootHtml.append(tempDivElement); + rootHtml.append(tempiFrameElement); - expect(givenDocument.getElementById(tempIframeId)).toEqual(tempiFrameElement); - expect(givenDocument.getElementById(tempDivId)).toEqual(tempDivElement); - expect(givenDocument.getElementById(svgId)).toEqual(svgElement); - removeExistingElements( - givenDocument, - inSandboxedMode, - svgId, - '#' + tempDivId, - '#' + tempIframeId - ); - expect(givenDocument.getElementById(tempIframeId)).toEqual(tempiFrameElement); - expect(givenDocument.getElementById(tempDivId)).toBeNull(); - expect(givenDocument.getElementById(svgId)).toBeNull(); - }); + expect(givenDocument.getElementById(tempIframeId)).toEqual(tempiFrameElement); + expect(givenDocument.getElementById(tempDivId)).toEqual(tempDivElement); + expect(givenDocument.getElementById(svgId)).toEqual(svgElement); + removeExistingElements(givenDocument, svgId, tempDivId, tempIframeId); + expect(givenDocument.getElementById(tempIframeId)).toBeNull(); + expect(givenDocument.getElementById(tempDivId)).toBeNull(); + expect(givenDocument.getElementById(svgId)).toBeNull(); }); }); @@ -667,6 +654,19 @@ describe('mermaidAPI', function () { expect(mermaid.parseError).toEqual(undefined); expect(() => mermaidAPI.parse('this is not a mermaid diagram definition')).toThrow(); }); + it('throws for a nicer error for a invalid definition starting with `---`', function () { + expect(mermaid.parseError).toEqual(undefined); + expect(() => + mermaidAPI.parse(` + --- + title: a malformed YAML front-matter + `) + ).toThrow( + 'Diagrams beginning with --- are not valid. ' + + 'If you were trying to use a YAML front-matter, please ensure that ' + + "you've correctly opened and closed the YAML front-matter with unindented `---` blocks" + ); + }); it('does not throw for a valid definition', function () { expect(() => mermaidAPI.parse('graph TD;A--x|text including URL space|B;')).not.toThrow(); }); diff --git a/packages/mermaid/src/mermaidAPI.ts b/packages/mermaid/src/mermaidAPI.ts index a77aed96d..5bf11fad1 100644 --- a/packages/mermaid/src/mermaidAPI.ts +++ b/packages/mermaid/src/mermaidAPI.ts @@ -29,7 +29,7 @@ import utils, { directiveSanitizer } from './utils'; import DOMPurify from 'dompurify'; import { MermaidConfig } from './config.type'; import { evaluate } from './diagrams/common/common'; -import isEmpty from 'lodash-es/isEmpty'; +import isEmpty from 'lodash-es/isEmpty.js'; import { setA11yDiagramInfo, addSVGa11yTitleDescription } from './accessibility'; // diagram names that support classDef statements @@ -55,8 +55,8 @@ const IFRAME_SANDBOX_OPTS = 'allow-top-navigation-by-user-activation allow-popup const IFRAME_NOT_SUPPORTED_MSG = 'The "iframe" tag is not supported by your browser.'; // DOMPurify settings for svgCode -const DOMPURE_TAGS = ['foreignobject']; -const DOMPURE_ATTR = ['dominant-baseline']; +const DOMPURIFY_TAGS = ['foreignobject']; +const DOMPURIFY_ATTR = ['dominant-baseline']; // This is what is returned from getClasses(...) methods. // It is slightly renamed to ..StyleClassDef instead of just ClassDef because "class" is a greatly ambiguous and overloaded word. @@ -328,29 +328,22 @@ function sandboxedIframe(parentNode: D3Element, iFrameId: string): D3Element { * Remove any existing elements from the given document * * @param doc - the document to removed elements from - * @param isSandboxed - whether or not we are in sandboxed mode * @param id - id for any existing SVG element * @param divSelector - selector for any existing enclosing div element * @param iFrameSelector - selector for any existing iFrame element */ export const removeExistingElements = ( doc: Document, - isSandboxed: boolean, id: string, - divSelector: string, - iFrameSelector: string + divId: string, + iFrameId: string ) => { // Remove existing SVG element if it exists - const existingSvg = doc.getElementById(id); - if (existingSvg) { - existingSvg.remove(); - } - + doc.getElementById(id)?.remove(); // Remove previous temporary element if it exists - const element = isSandboxed ? doc.querySelector(iFrameSelector) : doc.querySelector(divSelector); - if (element) { - element.remove(); - } + // Both div and iframe needs to be cleared in case there is a config change happening between renders. + doc.getElementById(divId)?.remove(); + doc.getElementById(iFrameId)?.remove(); }; /** @@ -443,7 +436,7 @@ const render = function ( // No svgContainingElement was provided // If there is an existing element with the id, we remove it. This likely a previously rendered diagram - removeExistingElements(document, isSandboxed, id, iFrameID_selector, enclosingDivID_selector); + removeExistingElements(document, id, enclosingDivID, iFrameID); // Add the temporary div used for rendering with the enclosingDivID. // This temporary div will contain a svg with the id == id @@ -536,11 +529,11 @@ const render = function ( if (isSandboxed) { const svgEl = root.select(enclosingDivID_selector + ' svg').node(); svgCode = putIntoIFrame(svgCode, svgEl); - } else if (isLooseSecurityLevel) { + } else if (!isLooseSecurityLevel) { // Sanitize the svgCode using DOMPurify svgCode = DOMPurify.sanitize(svgCode, { - ADD_TAGS: DOMPURE_TAGS, - ADD_ATTR: DOMPURE_ATTR, + ADD_TAGS: DOMPURIFY_TAGS, + ADD_ATTR: DOMPURIFY_ATTR, }); } @@ -650,7 +643,7 @@ const renderAsync = async function ( // No svgContainingElement was provided // If there is an existing element with the id, we remove it. This likely a previously rendered diagram - removeExistingElements(document, isSandboxed, id, iFrameID_selector, enclosingDivID_selector); + removeExistingElements(document, id, enclosingDivID, iFrameID); // Add the temporary div used for rendering with the enclosingDivID. // This temporary div will contain a svg with the id == id @@ -738,11 +731,11 @@ const renderAsync = async function ( if (isSandboxed) { const svgEl = root.select(enclosingDivID_selector + ' svg').node(); svgCode = putIntoIFrame(svgCode, svgEl); - } else if (isLooseSecurityLevel) { + } else if (!isLooseSecurityLevel) { // Sanitize the svgCode using DOMPurify svgCode = DOMPurify.sanitize(svgCode, { - ADD_TAGS: DOMPURE_TAGS, - ADD_ATTR: DOMPURE_ATTR, + ADD_TAGS: DOMPURIFY_TAGS, + ADD_ATTR: DOMPURIFY_ATTR, }); } diff --git a/packages/mermaid/src/utils.spec.js b/packages/mermaid/src/utils.spec.js index e983d21c8..7ee6aa000 100644 --- a/packages/mermaid/src/utils.spec.js +++ b/packages/mermaid/src/utils.spec.js @@ -3,7 +3,7 @@ import utils from './utils'; import assignWithDepth from './assignWithDepth'; import { detectType } from './diagram-api/detectType'; import { addDiagrams } from './diagram-api/diagram-orchestration'; -import memoize from 'lodash-es/memoize'; +import memoize from 'lodash-es/memoize.js'; import { MockedD3 } from './tests/MockedD3'; addDiagrams(); @@ -239,9 +239,9 @@ Alice->Bob: hi`; const type = detectType(str); expect(type).toBe('gitGraph'); }); - it('should not allow frontmatter with leading spaces', function () { + it('should handle malformed frontmatter (with leading spaces) with `---` error graphtype', function () { const str = ' ---\ntitle: foo\n---\n gitGraph TB:\nbfs1:queue'; - expect(() => detectType(str)).toThrow('No diagram type detected for text'); + expect(detectType(str)).toBe('---'); }); }); describe('when finding substring in array ', function () { diff --git a/packages/mermaid/src/utils.ts b/packages/mermaid/src/utils.ts index 767fdaa7d..4c2f844e2 100644 --- a/packages/mermaid/src/utils.ts +++ b/packages/mermaid/src/utils.ts @@ -21,7 +21,7 @@ import { log } from './logger'; import { detectType } from './diagram-api/detectType'; import assignWithDepth from './assignWithDepth'; import { MermaidConfig } from './config.type'; -import memoize from 'lodash-es/memoize'; +import memoize from 'lodash-es/memoize.js'; // Effectively an enum of the supported curve types, accessible by name const d3CurveTypes = { @@ -194,7 +194,10 @@ export const isSubstringInArray = function (str: string, arr: string[]): number * @param defaultCurve - The default curve to return * @returns The curve factory to use */ -export function interpolateToCurve(interpolate?: string, defaultCurve: CurveFactory): CurveFactory { +export function interpolateToCurve( + interpolate: string | undefined, + defaultCurve: CurveFactory +): CurveFactory { if (!interpolate) { return defaultCurve; } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 270da02e7..8e8e0623f 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -69,7 +69,7 @@ importers: version: 4.0.1_bg25yee4qeg7mpleuvd346a3tq esbuild: specifier: ^0.16.0 - version: 0.16.4 + version: 0.16.7 eslint: specifier: ^8.27.0 version: 8.27.0 @@ -173,11 +173,11 @@ importers: specifier: ^7.0.0 version: 7.6.1 dagre-d3-es: - specifier: 7.0.4 - version: 7.0.4 + specifier: 7.0.6 + version: 7.0.6 dompurify: - specifier: 2.4.1 - version: 2.4.1 + specifier: 2.4.3 + version: 2.4.3 khroma: specifier: ^2.0.0 version: 2.0.0 @@ -193,6 +193,9 @@ importers: stylis: specifier: ^4.1.2 version: 4.1.2 + ts-dedent: + specifier: ^2.2.0 + version: 2.2.0 uuid: specifier: ^9.0.0 version: 9.0.0 @@ -236,6 +239,9 @@ importers: coveralls: specifier: ^3.1.1 version: 3.1.1 + cpy-cli: + specifier: ^4.2.0 + version: 4.2.0 cspell: specifier: ^6.14.3 version: 6.14.3 @@ -285,11 +291,11 @@ importers: specifier: ^1.0.0 version: 1.0.0 vitepress: - specifier: ^1.0.0-alpha.28 - version: 1.0.0-alpha.28_tbpndr44ulefs3hehwpi2mkf2y + specifier: ^1.0.0-alpha.31 + version: 1.0.0-alpha.31_tbpndr44ulefs3hehwpi2mkf2y vitepress-plugin-search: - specifier: ^1.0.4-alpha.15 - version: 1.0.4-alpha.15_s3edpouswd4dgoi2en7bdlrp54 + specifier: ^1.0.4-alpha.16 + version: 1.0.4-alpha.16_ifjhkyx3os4sbm7zdnvthc52am packages/mermaid-example-diagram: devDependencies: @@ -1743,8 +1749,8 @@ packages: dev: true optional: true - /@esbuild/android-arm/0.16.4: - resolution: {integrity: sha512-rZzb7r22m20S1S7ufIc6DC6W659yxoOrl7sKP1nCYhuvUlnCFHVSbATG4keGUtV8rDz11sRRDbWkvQZpzPaHiw==} + /@esbuild/android-arm/0.16.7: + resolution: {integrity: sha512-yhzDbiVcmq6T1/XEvdcJIVcXHdLjDJ5cQ0Dp9R9p9ERMBTeO1dR5tc8YYv8zwDeBw1xZm+Eo3MRo8cwclhBS0g==} engines: {node: '>=12'} cpu: [arm] os: [android] @@ -1752,8 +1758,8 @@ packages: dev: true optional: true - /@esbuild/android-arm64/0.16.4: - resolution: {integrity: sha512-VPuTzXFm/m2fcGfN6CiwZTlLzxrKsWbPkG7ArRFpuxyaHUm/XFHQPD4xNwZT6uUmpIHhnSjcaCmcla8COzmZ5Q==} + /@esbuild/android-arm64/0.16.7: + resolution: {integrity: sha512-tYFw0lBJSEvLoGzzYh1kXuzoX1iPkbOk3O29VqzQb0HbOy7t/yw1hGkvwoJhXHwzQUPsShyYcTgRf6bDBcfnTw==} engines: {node: '>=12'} cpu: [arm64] os: [android] @@ -1761,8 +1767,8 @@ packages: dev: true optional: true - /@esbuild/android-x64/0.16.4: - resolution: {integrity: sha512-MW+B2O++BkcOfMWmuHXB15/l1i7wXhJFqbJhp82IBOais8RBEQv2vQz/jHrDEHaY2X0QY7Wfw86SBL2PbVOr0g==} + /@esbuild/android-x64/0.16.7: + resolution: {integrity: sha512-3P2OuTxwAtM3k/yEWTNUJRjMPG1ce8rXs51GTtvEC5z1j8fC1plHeVVczdeHECU7aM2/Buc0MwZ6ciM/zysnWg==} engines: {node: '>=12'} cpu: [x64] os: [android] @@ -1770,8 +1776,8 @@ packages: dev: true optional: true - /@esbuild/darwin-arm64/0.16.4: - resolution: {integrity: sha512-a28X1O//aOfxwJVZVs7ZfM8Tyih2Za4nKJrBwW5Wm4yKsnwBy9aiS/xwpxiiTRttw3EaTg4Srerhcm6z0bu9Wg==} + /@esbuild/darwin-arm64/0.16.7: + resolution: {integrity: sha512-VUb9GK23z8jkosHU9yJNUgQpsfJn+7ZyBm6adi2Ec5/U241eR1tAn82QicnUzaFDaffeixiHwikjmnec/YXEZg==} engines: {node: '>=12'} cpu: [arm64] os: [darwin] @@ -1779,8 +1785,8 @@ packages: dev: true optional: true - /@esbuild/darwin-x64/0.16.4: - resolution: {integrity: sha512-e3doCr6Ecfwd7VzlaQqEPrnbvvPjE9uoTpxG5pyLzr2rI2NMjDHmvY1E5EO81O/e9TUOLLkXA5m6T8lfjK9yAA==} + /@esbuild/darwin-x64/0.16.7: + resolution: {integrity: sha512-duterlv3tit3HI9vhzMWnSVaB1B6YsXpFq1Ntd6Fou82BB1l4tucYy3FI9dHv3tvtDuS0NiGf/k6XsdBqPZ01w==} engines: {node: '>=12'} cpu: [x64] os: [darwin] @@ -1788,8 +1794,8 @@ packages: dev: true optional: true - /@esbuild/freebsd-arm64/0.16.4: - resolution: {integrity: sha512-Oup3G/QxBgvvqnXWrBed7xxkFNwAwJVHZcklWyQt7YCAL5bfUkaa6FVWnR78rNQiM8MqqLiT6ZTZSdUFuVIg1w==} + /@esbuild/freebsd-arm64/0.16.7: + resolution: {integrity: sha512-9kkycpBFes/vhi7B7o0cf+q2WdJi+EpVzpVTqtWFNiutARWDFFLcB93J8PR1cG228sucsl3B+7Ts27izE6qiaQ==} engines: {node: '>=12'} cpu: [arm64] os: [freebsd] @@ -1797,8 +1803,8 @@ packages: dev: true optional: true - /@esbuild/freebsd-x64/0.16.4: - resolution: {integrity: sha512-vAP+eYOxlN/Bpo/TZmzEQapNS8W1njECrqkTpNgvXskkkJC2AwOXwZWai/Kc2vEFZUXQttx6UJbj9grqjD/+9Q==} + /@esbuild/freebsd-x64/0.16.7: + resolution: {integrity: sha512-5Ahf6jzWXJ4J2uh9dpy5DKOO+PeRUE/9DMys6VuYfwgQzd6n5+pVFm58L2Z2gRe611RX6SdydnNaiIKM3svY7g==} engines: {node: '>=12'} cpu: [x64] os: [freebsd] @@ -1806,8 +1812,8 @@ packages: dev: true optional: true - /@esbuild/linux-arm/0.16.4: - resolution: {integrity: sha512-A47ZmtpIPyERxkSvIv+zLd6kNIOtJH03XA0Hy7jaceRDdQaQVGSDt4mZqpWqJYgDk9rg96aglbF6kCRvPGDSUA==} + /@esbuild/linux-arm/0.16.7: + resolution: {integrity: sha512-QqJnyCfu5OF78Olt7JJSZ7OSv/B4Hf+ZJWp4kkq9xwMsgu7yWq3crIic8gGOpDYTqVKKMDAVDgRXy5Wd/nWZyQ==} engines: {node: '>=12'} cpu: [arm] os: [linux] @@ -1815,8 +1821,8 @@ packages: dev: true optional: true - /@esbuild/linux-arm64/0.16.4: - resolution: {integrity: sha512-2zXoBhv4r5pZiyjBKrOdFP4CXOChxXiYD50LRUU+65DkdS5niPFHbboKZd/c81l0ezpw7AQnHeoCy5hFrzzs4g==} + /@esbuild/linux-arm64/0.16.7: + resolution: {integrity: sha512-2wv0xYDskk2+MzIm/AEprDip39a23Chptc4mL7hsHg26P0gD8RUhzmDu0KCH2vMThUI1sChXXoK9uH0KYQKaDg==} engines: {node: '>=12'} cpu: [arm64] os: [linux] @@ -1824,8 +1830,8 @@ packages: dev: true optional: true - /@esbuild/linux-ia32/0.16.4: - resolution: {integrity: sha512-uxdSrpe9wFhz4yBwt2kl2TxS/NWEINYBUFIxQtaEVtglm1eECvsj1vEKI0KX2k2wCe17zDdQ3v+jVxfwVfvvjw==} + /@esbuild/linux-ia32/0.16.7: + resolution: {integrity: sha512-APVYbEilKbD5ptmKdnIcXej2/+GdV65TfTjxR2Uk8t1EsOk49t6HapZW6DS/Bwlvh5hDwtLapdSumIVNGxgqLg==} engines: {node: '>=12'} cpu: [ia32] os: [linux] @@ -1842,8 +1848,8 @@ packages: dev: true optional: true - /@esbuild/linux-loong64/0.16.4: - resolution: {integrity: sha512-peDrrUuxbZ9Jw+DwLCh/9xmZAk0p0K1iY5d2IcwmnN+B87xw7kujOkig6ZRcZqgrXgeRGurRHn0ENMAjjD5DEg==} + /@esbuild/linux-loong64/0.16.7: + resolution: {integrity: sha512-5wPUAGclplQrAW7EFr3F84Y/d++7G0KykohaF4p54+iNWhUnMVU8Bh2sxiEOXUy4zKIdpHByMgJ5/Ko6QhtTUw==} engines: {node: '>=12'} cpu: [loong64] os: [linux] @@ -1851,8 +1857,8 @@ packages: dev: true optional: true - /@esbuild/linux-mips64el/0.16.4: - resolution: {integrity: sha512-sD9EEUoGtVhFjjsauWjflZklTNr57KdQ6xfloO4yH1u7vNQlOfAlhEzbyBKfgbJlW7rwXYBdl5/NcZ+Mg2XhQA==} + /@esbuild/linux-mips64el/0.16.7: + resolution: {integrity: sha512-hxzlXtWF6yWfkE/SMTscNiVqLOAn7fOuIF3q/kiZaXxftz1DhZW/HpnTmTTWrzrS7zJWQxHHT4QSxyAj33COmA==} engines: {node: '>=12'} cpu: [mips64el] os: [linux] @@ -1860,8 +1866,8 @@ packages: dev: true optional: true - /@esbuild/linux-ppc64/0.16.4: - resolution: {integrity: sha512-X1HSqHUX9D+d0l6/nIh4ZZJ94eQky8d8z6yxAptpZE3FxCWYWvTDd9X9ST84MGZEJx04VYUD/AGgciddwO0b8g==} + /@esbuild/linux-ppc64/0.16.7: + resolution: {integrity: sha512-WM83Dac0LdXty5xPhlOuCD5Egfk1xLND/oRLYeB7Jb/tY4kzFSDgLlq91wYbHua/s03tQGA9iXvyjgymMw62Vw==} engines: {node: '>=12'} cpu: [ppc64] os: [linux] @@ -1869,8 +1875,8 @@ packages: dev: true optional: true - /@esbuild/linux-riscv64/0.16.4: - resolution: {integrity: sha512-97ANpzyNp0GTXCt6SRdIx1ngwncpkV/z453ZuxbnBROCJ5p/55UjhbaG23UdHj88fGWLKPFtMoU4CBacz4j9FA==} + /@esbuild/linux-riscv64/0.16.7: + resolution: {integrity: sha512-3nkNnNg4Ax6MS/l8O8Ynq2lGEVJYyJ2EoY3PHjNJ4PuZ80EYLMrFTFZ4L/Hc16AxgtXKwmNP9TM0YKNiBzBiJQ==} engines: {node: '>=12'} cpu: [riscv64] os: [linux] @@ -1878,8 +1884,8 @@ packages: dev: true optional: true - /@esbuild/linux-s390x/0.16.4: - resolution: {integrity: sha512-pUvPQLPmbEeJRPjP0DYTC1vjHyhrnCklQmCGYbipkep+oyfTn7GTBJXoPodR7ZS5upmEyc8lzAkn2o29wD786A==} + /@esbuild/linux-s390x/0.16.7: + resolution: {integrity: sha512-3SA/2VJuv0o1uD7zuqxEP+RrAyRxnkGddq0bwHQ98v1KNlzXD/JvxwTO3T6GM5RH6JUd29RTVQTOJfyzMkkppA==} engines: {node: '>=12'} cpu: [s390x] os: [linux] @@ -1887,8 +1893,8 @@ packages: dev: true optional: true - /@esbuild/linux-x64/0.16.4: - resolution: {integrity: sha512-N55Q0mJs3Sl8+utPRPBrL6NLYZKBCLLx0bme/+RbjvMforTGGzFvsRl4xLTZMUBFC1poDzBEPTEu5nxizQ9Nlw==} + /@esbuild/linux-x64/0.16.7: + resolution: {integrity: sha512-xi/tbqCqvPIzU+zJVyrpz12xqciTAPMi2fXEWGnapZymoGhuL2GIWIRXg4O2v5BXaYA5TSaiKYE14L0QhUTuQg==} engines: {node: '>=12'} cpu: [x64] os: [linux] @@ -1896,8 +1902,8 @@ packages: dev: true optional: true - /@esbuild/netbsd-x64/0.16.4: - resolution: {integrity: sha512-LHSJLit8jCObEQNYkgsDYBh2JrJT53oJO2HVdkSYLa6+zuLJh0lAr06brXIkljrlI+N7NNW1IAXGn/6IZPi3YQ==} + /@esbuild/netbsd-x64/0.16.7: + resolution: {integrity: sha512-NUsYbq3B+JdNKn8SXkItFvdes9qTwEoS3aLALtiWciW/ystiCKM20Fgv9XQBOXfhUHyh5CLEeZDXzLOrwBXuCQ==} engines: {node: '>=12'} cpu: [x64] os: [netbsd] @@ -1905,8 +1911,8 @@ packages: dev: true optional: true - /@esbuild/openbsd-x64/0.16.4: - resolution: {integrity: sha512-nLgdc6tWEhcCFg/WVFaUxHcPK3AP/bh+KEwKtl69Ay5IBqUwKDaq/6Xk0E+fh/FGjnLwqFSsarsbPHeKM8t8Sw==} + /@esbuild/openbsd-x64/0.16.7: + resolution: {integrity: sha512-qjwzsgeve9I8Tbsko2FEkdSk2iiezuNGFgipQxY/736NePXDaDZRodIejYGWOlbYXugdxb0nif5yvypH6lKBmA==} engines: {node: '>=12'} cpu: [x64] os: [openbsd] @@ -1914,8 +1920,8 @@ packages: dev: true optional: true - /@esbuild/sunos-x64/0.16.4: - resolution: {integrity: sha512-08SluG24GjPO3tXKk95/85n9kpyZtXCVwURR2i4myhrOfi3jspClV0xQQ0W0PYWHioJj+LejFMt41q+PG3mlAQ==} + /@esbuild/sunos-x64/0.16.7: + resolution: {integrity: sha512-mFWDz4RoBTzPphTCkM7Kc7Qpa0o/Z01acajR+Ai7LdfKgcP/C6jYOaKwv7nKzD0+MjOT20j7You9g4ozYy1dKQ==} engines: {node: '>=12'} cpu: [x64] os: [sunos] @@ -1923,8 +1929,8 @@ packages: dev: true optional: true - /@esbuild/win32-arm64/0.16.4: - resolution: {integrity: sha512-yYiRDQcqLYQSvNQcBKN7XogbrSvBE45FEQdH8fuXPl7cngzkCvpsG2H9Uey39IjQ6gqqc+Q4VXYHsQcKW0OMjQ==} + /@esbuild/win32-arm64/0.16.7: + resolution: {integrity: sha512-m39UmX19RvEIuC8sYZ0M+eQtdXw4IePDSZ78ZQmYyFaXY9krq4YzQCK2XWIJomNLtg4q+W5aXr8bW3AbqWNoVg==} engines: {node: '>=12'} cpu: [arm64] os: [win32] @@ -1932,8 +1938,8 @@ packages: dev: true optional: true - /@esbuild/win32-ia32/0.16.4: - resolution: {integrity: sha512-5rabnGIqexekYkh9zXG5waotq8mrdlRoBqAktjx2W3kb0zsI83mdCwrcAeKYirnUaTGztR5TxXcXmQrEzny83w==} + /@esbuild/win32-ia32/0.16.7: + resolution: {integrity: sha512-1cbzSEZA1fANwmT6rjJ4G1qQXHxCxGIcNYFYR9ctI82/prT38lnwSRZ0i5p/MVXksw9eMlHlet6pGu2/qkXFCg==} engines: {node: '>=12'} cpu: [ia32] os: [win32] @@ -1941,8 +1947,8 @@ packages: dev: true optional: true - /@esbuild/win32-x64/0.16.4: - resolution: {integrity: sha512-sN/I8FMPtmtT2Yw+Dly8Ur5vQ5a/RmC8hW7jO9PtPSQUPkowxWpcUZnqOggU7VwyT3Xkj6vcXWd3V/qTXwultQ==} + /@esbuild/win32-x64/0.16.7: + resolution: {integrity: sha512-QaQ8IH0JLacfGf5cf0HCCPnQuCTd/dAI257vXBgb/cccKGbH/6pVtI1gwhdAQ0Y48QSpTIFrh9etVyNdZY+zzw==} engines: {node: '>=12'} cpu: [x64] os: [win32] @@ -3067,15 +3073,15 @@ packages: eslint-visitor-keys: 3.3.0 dev: true - /@vitejs/plugin-vue/3.2.0_vite@3.2.3+vue@3.2.41: - resolution: {integrity: sha512-E0tnaL4fr+qkdCNxJ+Xd0yM31UwMkQje76fsDVBBUCoGOUPexu2VDUYHL8P4CwV+zMvWw6nlRw19OnRKmYAJpw==} + /@vitejs/plugin-vue/4.0.0_vite@4.0.1+vue@3.2.45: + resolution: {integrity: sha512-e0X4jErIxAB5oLtDqbHvHpJe/uWNkdpYV83AOG2xo2tEVSzCzewgJMtREZM30wXnM5ls90hxiOtAuVU6H5JgbA==} engines: {node: ^14.18.0 || >=16.0.0} peerDependencies: - vite: ^3.0.0 + vite: ^4.0.0 vue: ^3.2.25 dependencies: - vite: 3.2.3 - vue: 3.2.41 + vite: 4.0.1 + vue: 3.2.45 dev: true /@vitest/coverage-c8/0.25.1_oullksb5ic6y72oh2wekoaiuii: @@ -3103,114 +3109,113 @@ packages: sirv: 2.0.2 dev: true - /@vue/compiler-core/3.2.41: - resolution: {integrity: sha512-oA4mH6SA78DT+96/nsi4p9DX97PHcNROxs51lYk7gb9Z4BPKQ3Mh+BLn6CQZBw857Iuhu28BfMSRHAlPvD4vlw==} + /@vue/compiler-core/3.2.45: + resolution: {integrity: sha512-rcMj7H+PYe5wBV3iYeUgbCglC+pbpN8hBLTJvRiK2eKQiWqu+fG9F+8sW99JdL4LQi7Re178UOxn09puSXvn4A==} dependencies: '@babel/parser': 7.19.1 - '@vue/shared': 3.2.41 + '@vue/shared': 3.2.45 estree-walker: 2.0.2 source-map: 0.6.1 dev: true - /@vue/compiler-dom/3.2.41: - resolution: {integrity: sha512-xe5TbbIsonjENxJsYRbDJvthzqxLNk+tb3d/c47zgREDa/PCp6/Y4gC/skM4H6PIuX5DAxm7fFJdbjjUH2QTMw==} + /@vue/compiler-dom/3.2.45: + resolution: {integrity: sha512-tyYeUEuKqqZO137WrZkpwfPCdiiIeXYCcJ8L4gWz9vqaxzIQRccTSwSWZ/Axx5YR2z+LvpUbmPNXxuBU45lyRw==} dependencies: - '@vue/compiler-core': 3.2.41 - '@vue/shared': 3.2.41 + '@vue/compiler-core': 3.2.45 + '@vue/shared': 3.2.45 dev: true - /@vue/compiler-sfc/3.2.41: - resolution: {integrity: sha512-+1P2m5kxOeaxVmJNXnBskAn3BenbTmbxBxWOtBq3mQTCokIreuMULFantBUclP0+KnzNCMOvcnKinqQZmiOF8w==} - requiresBuild: true + /@vue/compiler-sfc/3.2.45: + resolution: {integrity: sha512-1jXDuWah1ggsnSAOGsec8cFjT/K6TMZ0sPL3o3d84Ft2AYZi2jWJgRMjw4iaK0rBfA89L5gw427H4n1RZQBu6Q==} dependencies: '@babel/parser': 7.19.1 - '@vue/compiler-core': 3.2.41 - '@vue/compiler-dom': 3.2.41 - '@vue/compiler-ssr': 3.2.41 - '@vue/reactivity-transform': 3.2.41 - '@vue/shared': 3.2.41 + '@vue/compiler-core': 3.2.45 + '@vue/compiler-dom': 3.2.45 + '@vue/compiler-ssr': 3.2.45 + '@vue/reactivity-transform': 3.2.45 + '@vue/shared': 3.2.45 estree-walker: 2.0.2 magic-string: 0.25.9 postcss: 8.4.18 source-map: 0.6.1 dev: true - /@vue/compiler-ssr/3.2.41: - resolution: {integrity: sha512-Y5wPiNIiaMz/sps8+DmhaKfDm1xgj6GrH99z4gq2LQenfVQcYXmHIOBcs5qPwl7jaW3SUQWjkAPKMfQemEQZwQ==} + /@vue/compiler-ssr/3.2.45: + resolution: {integrity: sha512-6BRaggEGqhWht3lt24CrIbQSRD5O07MTmd+LjAn5fJj568+R9eUD2F7wMQJjX859seSlrYog7sUtrZSd7feqrQ==} dependencies: - '@vue/compiler-dom': 3.2.41 - '@vue/shared': 3.2.41 + '@vue/compiler-dom': 3.2.45 + '@vue/shared': 3.2.45 dev: true /@vue/devtools-api/6.4.5: resolution: {integrity: sha512-JD5fcdIuFxU4fQyXUu3w2KpAJHzTVdN+p4iOX2lMWSHMOoQdMAcpFLZzm9Z/2nmsoZ1a96QEhZ26e50xLBsgOQ==} dev: true - /@vue/reactivity-transform/3.2.41: - resolution: {integrity: sha512-mK5+BNMsL4hHi+IR3Ft/ho6Za+L3FA5j8WvreJ7XzHrqkPq8jtF/SMo7tuc9gHjLDwKZX1nP1JQOKo9IEAn54A==} + /@vue/reactivity-transform/3.2.45: + resolution: {integrity: sha512-BHVmzYAvM7vcU5WmuYqXpwaBHjsS8T63jlKGWVtHxAHIoMIlmaMyurUSEs1Zcg46M4AYT5MtB1U274/2aNzjJQ==} dependencies: '@babel/parser': 7.19.1 - '@vue/compiler-core': 3.2.41 - '@vue/shared': 3.2.41 + '@vue/compiler-core': 3.2.45 + '@vue/shared': 3.2.45 estree-walker: 2.0.2 magic-string: 0.25.9 dev: true - /@vue/reactivity/3.2.41: - resolution: {integrity: sha512-9JvCnlj8uc5xRiQGZ28MKGjuCoPhhTwcoAdv3o31+cfGgonwdPNuvqAXLhlzu4zwqavFEG5tvaoINQEfxz+l6g==} + /@vue/reactivity/3.2.45: + resolution: {integrity: sha512-PRvhCcQcyEVohW0P8iQ7HDcIOXRjZfAsOds3N99X/Dzewy8TVhTCT4uXpAHfoKjVTJRA0O0K+6QNkDIZAxNi3A==} dependencies: - '@vue/shared': 3.2.41 + '@vue/shared': 3.2.45 dev: true - /@vue/runtime-core/3.2.41: - resolution: {integrity: sha512-0LBBRwqnI0p4FgIkO9q2aJBBTKDSjzhnxrxHYengkAF6dMOjeAIZFDADAlcf2h3GDALWnblbeprYYpItiulSVQ==} + /@vue/runtime-core/3.2.45: + resolution: {integrity: sha512-gzJiTA3f74cgARptqzYswmoQx0fIA+gGYBfokYVhF8YSXjWTUA2SngRzZRku2HbGbjzB6LBYSbKGIaK8IW+s0A==} dependencies: - '@vue/reactivity': 3.2.41 - '@vue/shared': 3.2.41 + '@vue/reactivity': 3.2.45 + '@vue/shared': 3.2.45 dev: true - /@vue/runtime-dom/3.2.41: - resolution: {integrity: sha512-U7zYuR1NVIP8BL6jmOqmapRAHovEFp7CSw4pR2FacqewXNGqZaRfHoNLQsqQvVQ8yuZNZtxSZy0FFyC70YXPpA==} + /@vue/runtime-dom/3.2.45: + resolution: {integrity: sha512-cy88YpfP5Ue2bDBbj75Cb4bIEZUMM/mAkDMfqDTpUYVgTf/kuQ2VQ8LebuZ8k6EudgH8pYhsGWHlY0lcxlvTwA==} dependencies: - '@vue/runtime-core': 3.2.41 - '@vue/shared': 3.2.41 + '@vue/runtime-core': 3.2.45 + '@vue/shared': 3.2.45 csstype: 2.6.21 dev: true - /@vue/server-renderer/3.2.41_vue@3.2.41: - resolution: {integrity: sha512-7YHLkfJdTlsZTV0ae5sPwl9Gn/EGr2hrlbcS/8naXm2CDpnKUwC68i1wGlrYAfIgYWL7vUZwk2GkYLQH5CvFig==} + /@vue/server-renderer/3.2.45_vue@3.2.45: + resolution: {integrity: sha512-ebiMq7q24WBU1D6uhPK//2OTR1iRIyxjF5iVq/1a5I1SDMDyDu4Ts6fJaMnjrvD3MqnaiFkKQj+LKAgz5WIK3g==} peerDependencies: - vue: 3.2.41 + vue: 3.2.45 dependencies: - '@vue/compiler-ssr': 3.2.41 - '@vue/shared': 3.2.41 - vue: 3.2.41 + '@vue/compiler-ssr': 3.2.45 + '@vue/shared': 3.2.45 + vue: 3.2.45 dev: true - /@vue/shared/3.2.41: - resolution: {integrity: sha512-W9mfWLHmJhkfAmV+7gDjcHeAWALQtgGT3JErxULl0oz6R6+3ug91I7IErs93eCFhPCZPHBs4QJS7YWEV7A3sxw==} + /@vue/shared/3.2.45: + resolution: {integrity: sha512-Ewzq5Yhimg7pSztDV+RH1UDKBzmtqieXQlpTVm2AwraoRL/Rks96mvd8Vgi7Lj+h+TH8dv7mXD3FRZR3TUvbSg==} dev: true - /@vueuse/core/9.4.0_vue@3.2.41: - resolution: {integrity: sha512-JzgenGj1ZF2BHOen5rsFiAyyI9sXAv7aKhNLlm9b7SwYQeKTcxTWdhudonURCSP3Egl9NQaRBzes2lv/1JUt/Q==} + /@vueuse/core/9.6.0_vue@3.2.45: + resolution: {integrity: sha512-qGUcjKQXHgN+jqXEgpeZGoxdCbIDCdVPz3QiF1uyecVGbMuM63o96I1GjYx5zskKgRI0FKSNsVWM7rwrRMTf6A==} dependencies: '@types/web-bluetooth': 0.0.16 - '@vueuse/metadata': 9.4.0 - '@vueuse/shared': 9.4.0_vue@3.2.41 - vue-demi: 0.13.11_vue@3.2.41 + '@vueuse/metadata': 9.6.0 + '@vueuse/shared': 9.6.0_vue@3.2.45 + vue-demi: 0.13.11_vue@3.2.45 transitivePeerDependencies: - '@vue/composition-api' - vue dev: true - /@vueuse/metadata/9.4.0: - resolution: {integrity: sha512-7GKMdGAsJyQJl35MYOz/RDpP0FxuiZBRDSN79QIPbdqYx4Sd0sVTnIC68KJ6Oln0t0SouvSUMvRHuno216Ud2Q==} + /@vueuse/metadata/9.6.0: + resolution: {integrity: sha512-sIC8R+kWkIdpi5X2z2Gk8TRYzmczDwHRhEFfCu2P+XW2JdPoXrziqsGpDDsN7ykBx4ilwieS7JUIweVGhvZ93w==} dev: true - /@vueuse/shared/9.4.0_vue@3.2.41: - resolution: {integrity: sha512-fTuem51KwMCnqUKkI8B57qAIMcFovtGgsCtAeqxIzH3i6nE9VYge+gVfneNHAAy7lj8twbkNfqQSygOPJTm4tQ==} + /@vueuse/shared/9.6.0_vue@3.2.45: + resolution: {integrity: sha512-/eDchxYYhkHnFyrb00t90UfjCx94kRHxc7J1GtBCqCG4HyPMX+krV9XJgVtWIsAMaxKVU4fC8NSUviG1JkwhUQ==} dependencies: - vue-demi: 0.13.11_vue@3.2.41 + vue-demi: 0.13.11_vue@3.2.45 transitivePeerDependencies: - '@vue/composition-api' - vue @@ -3509,6 +3514,14 @@ packages: indent-string: 4.0.0 dev: true + /aggregate-error/4.0.1: + resolution: {integrity: sha512-0poP0T7el6Vq3rstR8Mn4V/IQrpBLO6POkUSrN7RhyY+GF/InCFShQzsQ39T25gkHhLgSLByyAz+Kjb+c2L98w==} + engines: {node: '>=12'} + dependencies: + clean-stack: 4.2.0 + indent-string: 5.0.0 + dev: true + /ajv-formats/2.1.1_ajv@8.11.0: resolution: {integrity: sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==} peerDependencies: @@ -3701,6 +3714,11 @@ packages: engines: {node: '>=0.10.0'} dev: true + /arrify/3.0.0: + resolution: {integrity: sha512-tLkvA81vQG/XqE2mjDkGQHoOINtMHtysSnemrmoGe6PydDPMRbVugqyk4A6V/WDWEfm3l+0d8anA9r8cv/5Jaw==} + engines: {node: '>=12'} + dev: true + /asn1/0.2.6: resolution: {integrity: sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==} dependencies: @@ -4035,6 +4053,16 @@ packages: quick-lru: 4.0.1 dev: true + /camelcase-keys/7.0.2: + resolution: {integrity: sha512-Rjs1H+A9R+Ig+4E/9oyB66UC5Mj9Xq3N//vcLf2WzgdTi/3gUu3Z9KoqmlrEG4VuuLK8wJHofxzdQXz/knhiYg==} + engines: {node: '>=12'} + dependencies: + camelcase: 6.3.0 + map-obj: 4.3.0 + quick-lru: 5.1.1 + type-fest: 1.4.0 + dev: true + /camelcase/5.3.1: resolution: {integrity: sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==} engines: {node: '>=6'} @@ -4180,6 +4208,13 @@ packages: engines: {node: '>=6'} dev: true + /clean-stack/4.2.0: + resolution: {integrity: sha512-LYv6XPxoyODi36Dp976riBtSY27VmFo+MKqEU9QCCWyTrdEPDog+RWA7xQWHi6Vbp61j5c4cdzzX1NidnwtUWg==} + engines: {node: '>=12'} + dependencies: + escape-string-regexp: 5.0.0 + dev: true + /clear-module/4.1.2: resolution: {integrity: sha512-LWAxzHqdHsAZlPlEyJ2Poz6AIs384mPeqLVCru2p0BrP9G/kVGuhNyZYClLO6cXlnuJjzC8xtsJIuMjKqLXoAw==} engines: {node: '>=8'} @@ -4529,6 +4564,39 @@ packages: request: 2.88.2 dev: true + /cp-file/9.1.0: + resolution: {integrity: sha512-3scnzFj/94eb7y4wyXRWwvzLFaQp87yyfTnChIjlfYrVqp5lVO3E2hIJMeQIltUT0K2ZAB3An1qXcBmwGyvuwA==} + engines: {node: '>=10'} + dependencies: + graceful-fs: 4.2.10 + make-dir: 3.1.0 + nested-error-stacks: 2.1.1 + p-event: 4.2.0 + dev: true + + /cpy-cli/4.2.0: + resolution: {integrity: sha512-b04b+cbdr29CdpREPKw/itrfjO43Ty0Aj7wRM6M6LoE4GJxZJCk9Xp+Eu1IqztkKh3LxIBt1tDplENsa6KYprg==} + engines: {node: '>=12.20'} + hasBin: true + dependencies: + cpy: 9.0.1 + meow: 10.1.5 + dev: true + + /cpy/9.0.1: + resolution: {integrity: sha512-D9U0DR5FjTCN3oMTcFGktanHnAG5l020yvOCR1zKILmAyPP7I/9pl6NFgRbDcmSENtbK1sQLBz1p9HIOlroiNg==} + engines: {node: ^12.20.0 || ^14.17.0 || >=16.0.0} + dependencies: + arrify: 3.0.0 + cp-file: 9.1.0 + globby: 13.1.2 + junk: 4.0.0 + micromatch: 4.0.5 + nested-error-stacks: 2.1.1 + p-filter: 3.0.0 + p-map: 5.5.0 + dev: true + /create-require/1.1.1: resolution: {integrity: sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==} dev: true @@ -5113,10 +5181,46 @@ packages: d3-zoom: 3.0.0 dev: false - /dagre-d3-es/7.0.4: - resolution: {integrity: sha512-fQL8ldFR9UYpecz48d1smrXNJ9zGUK38Vl5OzX6Fhn9LR+oQh0GzHRPQylP5kWawmMTKm1QtqcHMVySMJ5CYaQ==} + /d3/7.7.0: + resolution: {integrity: sha512-VEwHCMgMjD2WBsxeRGUE18RmzxT9Bn7ghDpzvTEvkLSBAKgTMydJjouZTjspgQfRHpPt/PB3EHWBa6SSyFQq4g==} + engines: {node: '>=12'} dependencies: - d3: 7.6.1 + d3-array: 3.2.0 + d3-axis: 3.0.0 + d3-brush: 3.0.0 + d3-chord: 3.0.1 + d3-color: 3.1.0 + d3-contour: 4.0.0 + d3-delaunay: 6.0.2 + d3-dispatch: 3.0.1 + d3-drag: 3.0.0 + d3-dsv: 3.0.1 + d3-ease: 3.0.1 + d3-fetch: 3.0.1 + d3-force: 3.0.0 + d3-format: 3.1.0 + d3-geo: 3.0.1 + d3-hierarchy: 3.1.2 + d3-interpolate: 3.0.1 + d3-path: 3.0.1 + d3-polygon: 3.0.1 + d3-quadtree: 3.0.1 + d3-random: 3.0.1 + d3-scale: 4.0.2 + d3-scale-chromatic: 3.0.0 + d3-selection: 3.0.0 + d3-shape: 3.1.0 + d3-time: 3.0.0 + d3-time-format: 4.1.0 + d3-timer: 3.0.1 + d3-transition: 3.0.1_d3-selection@3.0.0 + d3-zoom: 3.0.0 + dev: false + + /dagre-d3-es/7.0.6: + resolution: {integrity: sha512-CaaE/nZh205ix+Up4xsnlGmpog5GGm81Upi2+/SBHxwNwrccBb3K51LzjZ1U6hgvOlAEUsVWf1xSTzCyKpJ6+Q==} + dependencies: + d3: 7.7.0 lodash-es: 4.17.21 dev: false @@ -5228,6 +5332,11 @@ packages: engines: {node: '>=0.10.0'} dev: true + /decamelize/5.0.1: + resolution: {integrity: sha512-VfxadyCECXgQlkoEAjeghAr5gY3Hf+IKjKb+X8tGVDtveCjN+USwprd2q3QXBR9T1+x2DG0XZF5/w+7HAtSaXA==} + engines: {node: '>=10'} + dev: true + /decimal.js/10.4.1: resolution: {integrity: sha512-F29o+vci4DodHYT9UrR5IEbfBw9pE5eSapIJdTqXK5+6hq+t8VRxwQyKlW2i+KDKFkkJQRvFyI/QXD83h8LyQw==} dev: true @@ -5398,8 +5507,8 @@ packages: domelementtype: 2.3.0 dev: true - /dompurify/2.4.1: - resolution: {integrity: sha512-ewwFzHzrrneRjxzmK6oVz/rZn9VWspGFRDb4/rRtIsM1n36t9AKma/ye8syCpcw+XJ25kOK/hOG7t1j2I2yBqA==} + /dompurify/2.4.3: + resolution: {integrity: sha512-q6QaLcakcRjebxjg8/+NP+h0rPfatOgOzc46Fst9VAA3jF2ApfKBNKMzdP4DYTqtUMXSCd5pRS/8Po/OmoCHZQ==} dev: false /domutils/3.0.1: @@ -5719,34 +5828,34 @@ packages: esbuild-windows-arm64: 0.15.13 dev: true - /esbuild/0.16.4: - resolution: {integrity: sha512-qQrPMQpPTWf8jHugLWHoGqZjApyx3OEm76dlTXobHwh/EBbavbRdjXdYi/GWr43GyN0sfpap14GPkb05NH3ROA==} + /esbuild/0.16.7: + resolution: {integrity: sha512-P6OBFYFSQOGzfApqCeYKqfKRRbCIRsdppTXFo4aAvtiW3o8TTyiIplBvHJI171saPAiy3WlawJHCveJVIOIx1A==} engines: {node: '>=12'} hasBin: true requiresBuild: true optionalDependencies: - '@esbuild/android-arm': 0.16.4 - '@esbuild/android-arm64': 0.16.4 - '@esbuild/android-x64': 0.16.4 - '@esbuild/darwin-arm64': 0.16.4 - '@esbuild/darwin-x64': 0.16.4 - '@esbuild/freebsd-arm64': 0.16.4 - '@esbuild/freebsd-x64': 0.16.4 - '@esbuild/linux-arm': 0.16.4 - '@esbuild/linux-arm64': 0.16.4 - '@esbuild/linux-ia32': 0.16.4 - '@esbuild/linux-loong64': 0.16.4 - '@esbuild/linux-mips64el': 0.16.4 - '@esbuild/linux-ppc64': 0.16.4 - '@esbuild/linux-riscv64': 0.16.4 - '@esbuild/linux-s390x': 0.16.4 - '@esbuild/linux-x64': 0.16.4 - '@esbuild/netbsd-x64': 0.16.4 - '@esbuild/openbsd-x64': 0.16.4 - '@esbuild/sunos-x64': 0.16.4 - '@esbuild/win32-arm64': 0.16.4 - '@esbuild/win32-ia32': 0.16.4 - '@esbuild/win32-x64': 0.16.4 + '@esbuild/android-arm': 0.16.7 + '@esbuild/android-arm64': 0.16.7 + '@esbuild/android-x64': 0.16.7 + '@esbuild/darwin-arm64': 0.16.7 + '@esbuild/darwin-x64': 0.16.7 + '@esbuild/freebsd-arm64': 0.16.7 + '@esbuild/freebsd-x64': 0.16.7 + '@esbuild/linux-arm': 0.16.7 + '@esbuild/linux-arm64': 0.16.7 + '@esbuild/linux-ia32': 0.16.7 + '@esbuild/linux-loong64': 0.16.7 + '@esbuild/linux-mips64el': 0.16.7 + '@esbuild/linux-ppc64': 0.16.7 + '@esbuild/linux-riscv64': 0.16.7 + '@esbuild/linux-s390x': 0.16.7 + '@esbuild/linux-x64': 0.16.7 + '@esbuild/netbsd-x64': 0.16.7 + '@esbuild/openbsd-x64': 0.16.7 + '@esbuild/sunos-x64': 0.16.7 + '@esbuild/win32-arm64': 0.16.7 + '@esbuild/win32-ia32': 0.16.7 + '@esbuild/win32-x64': 0.16.7 dev: true /escalade/3.1.1: @@ -5773,6 +5882,11 @@ packages: engines: {node: '>=10'} dev: true + /escape-string-regexp/5.0.0: + resolution: {integrity: sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==} + engines: {node: '>=12'} + dev: true + /escodegen/1.14.3: resolution: {integrity: sha512-qFcX0XJkdg+PB3xjZZG/wKSuT1PnQWx57+TVSjIMmILd2yC/6ByYElPwJnslDsuWuSAp4AwJGumarAAmJch5Kw==} engines: {node: '>=4.0'} @@ -7059,6 +7173,11 @@ packages: engines: {node: '>=8'} dev: true + /indent-string/5.0.0: + resolution: {integrity: sha512-m6FAo/spmsW2Ab2fU35JTYwtOKa2yAwXSwgjSv1TJzh4Mh7mC3lzAOVLBprb72XsTrgkEIsl7YrFNAiDiRhIGg==} + engines: {node: '>=12'} + dev: true + /inflight/1.0.6: resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==} dependencies: @@ -8020,6 +8139,11 @@ packages: verror: 1.10.0 dev: true + /junk/4.0.0: + resolution: {integrity: sha512-ojtSU++zLJ3jQG9bAYjg94w+/DOJtRyD7nPaerMFrBhmdVmiV5/exYH5t4uHga4G/95nT6hr1OJoKIFbYbrW5w==} + engines: {node: '>=12.20'} + dev: true + /keyv/4.5.0: resolution: {integrity: sha512-2YvuMsA+jnFGtBareKqgANOEKe1mk3HKiXu2fRmAfyxG0MJAywNhi5ttWA3PMjl4NmpyjZNbFifR2vNjW1znfA==} dependencies: @@ -8406,6 +8530,24 @@ packages: fs-monkey: 1.0.3 dev: true + /meow/10.1.5: + resolution: {integrity: sha512-/d+PQ4GKmGvM9Bee/DPa8z3mXs/pkvJE2KEThngVNOqtmljC6K7NMPxtc2JeZYTmpWb9k/TmxjeL18ez3h7vCw==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + dependencies: + '@types/minimist': 1.2.2 + camelcase-keys: 7.0.2 + decamelize: 5.0.1 + decamelize-keys: 1.1.0 + hard-rejection: 2.1.0 + minimist-options: 4.1.0 + normalize-package-data: 3.0.3 + read-pkg-up: 8.0.0 + redent: 4.0.0 + trim-newlines: 4.0.2 + type-fest: 1.4.0 + yargs-parser: 20.2.9 + dev: true + /meow/8.1.2: resolution: {integrity: sha512-r85E3NdZ+mpYk1C6RjPFEMSE+s1iZMuHtsHAqY0DT3jZczl0diWUZ8g6oU7h0M9cD2EL+PzaYghhCLzR0ZNn5Q==} engines: {node: '>=10'} @@ -8775,6 +8917,10 @@ packages: resolution: {integrity: sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==} dev: true + /nested-error-stacks/2.1.1: + resolution: {integrity: sha512-9iN1ka/9zmX1ZvLV9ewJYEk9h7RyRRtqdK0woXcqohu8EWIerfPUjYJPg0ULy0UqP7cslmdGc8xKDJcojlKiaw==} + dev: true + /netmask/2.0.2: resolution: {integrity: sha512-dBpDMdxv9Irdq66304OLfEmQ9tbNRFnFTuZiLo+bD+r332bBmMJ8GBLXklIXXgxd3+v9+KUnZaUR5PJMa75Gsg==} engines: {node: '>= 0.4.0'} @@ -8961,6 +9107,20 @@ packages: engines: {node: '>=8'} dev: true + /p-event/4.2.0: + resolution: {integrity: sha512-KXatOjCRXXkSePPb1Nbi0p0m+gQAwdlbhi4wQKJPI1HsMQS9g+Sqp2o+QHziPr7eYJyOZet836KoHEVM1mwOrQ==} + engines: {node: '>=8'} + dependencies: + p-timeout: 3.2.0 + dev: true + + /p-filter/3.0.0: + resolution: {integrity: sha512-QtoWLjXAW++uTX67HZQz1dbTpqBfiidsB6VtQUC9iR85S120+s0T5sO6s+B5MLzFcZkrEd/DGMmCjR+f2Qpxwg==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + dependencies: + p-map: 5.5.0 + dev: true + /p-finally/1.0.0: resolution: {integrity: sha512-LICb2p9CB7FS+0eR1oqWnHhp0FljGLZCWBE9aix0Uye9W8LTQPwMTYVGWQWIw9RdQiDg4+epXQODwIYJtSJaow==} engines: {node: '>=4'} @@ -9013,6 +9173,13 @@ packages: aggregate-error: 3.1.0 dev: true + /p-map/5.5.0: + resolution: {integrity: sha512-VFqfGDHlx87K66yZrNdI4YGtD70IRyd+zSvgks6mzHPRNkoKy+9EKP4SFC77/vTTQYmRmti7dvqC+m5jBrBAcg==} + engines: {node: '>=12'} + dependencies: + aggregate-error: 4.0.1 + dev: true + /p-retry/4.6.2: resolution: {integrity: sha512-312Id396EbJdvRONlngUx0NydfrIQ5lsYu0znKVUzVvArzEIt08V1qhtyESbGVd1FGX7UKtiFp5uwKZdM8wIuQ==} engines: {node: '>=8'} @@ -9021,6 +9188,13 @@ packages: retry: 0.13.1 dev: true + /p-timeout/3.2.0: + resolution: {integrity: sha512-rhIwUycgwwKcP9yTOOFK/AKsAopjjCakVqLHePO3CC6Mir1Z99xT+R63jZxAT5lFZLa2inS5h+ZS2GvR99/FBg==} + engines: {node: '>=8'} + dependencies: + p-finally: 1.0.0 + dev: true + /p-try/2.2.0: resolution: {integrity: sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==} engines: {node: '>=6'} @@ -9263,6 +9437,15 @@ packages: source-map-js: 1.0.2 dev: true + /postcss/8.4.20: + resolution: {integrity: sha512-6Q04AXR1212bXr5fh03u8aAwbLxAQNGQ/Q1LNa0VfOI06ZAlhPHtQvE4OIdpj4kLThXilalPnmDSOD65DcHt+g==} + engines: {node: ^10 || ^12 || >=14} + dependencies: + nanoid: 3.3.4 + picocolors: 1.0.0 + source-map-js: 1.0.2 + dev: true + /preact/10.11.0: resolution: {integrity: sha512-Fk6+vB2kb6mSJfDgODq0YDhMfl0HNtK5+Uc9QqECO4nlyPAQwCI+BKyWO//idA7ikV7o+0Fm6LQmNuQi1wXI1w==} dev: true @@ -9448,6 +9631,15 @@ packages: type-fest: 0.8.1 dev: true + /read-pkg-up/8.0.0: + resolution: {integrity: sha512-snVCqPczksT0HS2EC+SxUndvSzn6LRCwpfSvLrIfR5BKDQQZMaI6jPRC9dYvYFDRAuFEAnkwww8kBBNE/3VvzQ==} + engines: {node: '>=12'} + dependencies: + find-up: 5.0.0 + read-pkg: 6.0.0 + type-fest: 1.4.0 + dev: true + /read-pkg/5.2.0: resolution: {integrity: sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==} engines: {node: '>=8'} @@ -9458,6 +9650,16 @@ packages: type-fest: 0.6.0 dev: true + /read-pkg/6.0.0: + resolution: {integrity: sha512-X1Fu3dPuk/8ZLsMhEj5f4wFAF0DWoK7qhGJvgaijocXxBmSToKfbFtqbxMO7bVjNA1dmE5huAzjXj/ey86iw9Q==} + engines: {node: '>=12'} + dependencies: + '@types/normalize-package-data': 2.4.1 + normalize-package-data: 3.0.3 + parse-json: 5.2.0 + type-fest: 1.4.0 + dev: true + /readable-stream/1.1.14: resolution: {integrity: sha512-+MeVjFf4L44XUkhM1eYbD8fyEsxcV81pqMSR5gblfcLCHfZvbrqy4/qYHE+/R5HoBUT11WV5O08Cr1n3YXkWVQ==} dependencies: @@ -9510,6 +9712,14 @@ packages: strip-indent: 3.0.0 dev: true + /redent/4.0.0: + resolution: {integrity: sha512-tYkDkVVtYkSVhuQ4zBgfvciymHaeuel+zFKXShfDnFP5SyVEP7qo70Rf1jTOTCx3vGNAbnEi/xFkcfQVMIBWag==} + engines: {node: '>=12'} + dependencies: + indent-string: 5.0.0 + strip-indent: 4.0.0 + dev: true + /regexp-tree/0.1.24: resolution: {integrity: sha512-s2aEVuLhvnVJW6s/iPgEGK6R+/xngd2jNQ+xy4bXNDKxZKJH6jpPHY6kVeVv1IeLCHgswRj+Kl3ELaDjG6V1iw==} hasBin: true @@ -9726,6 +9936,14 @@ packages: fsevents: 2.3.2 dev: true + /rollup/3.7.4: + resolution: {integrity: sha512-jN9rx3k5pfg9H9al0r0y1EYKSeiRANZRYX32SuNXAnKzh6cVyf4LZVto1KAuDnbHT03E1CpsgqDKaqQ8FZtgxw==} + engines: {node: '>=14.18.0', npm: '>=8.0.0'} + hasBin: true + optionalDependencies: + fsevents: 2.3.2 + dev: true + /run-parallel/1.2.0: resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} dependencies: @@ -10079,6 +10297,7 @@ packages: /sourcemap-codec/1.4.8: resolution: {integrity: sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==} + deprecated: Please use @jridgewell/sourcemap-codec instead dev: true /spawn-command/0.0.2-1: @@ -10303,6 +10522,13 @@ packages: min-indent: 1.0.1 dev: true + /strip-indent/4.0.0: + resolution: {integrity: sha512-mnVSV2l+Zv6BLpSD/8V87CW/y9EmmbYzGCIavsnsI6/nwn26DwffM/yztm30Z/I2DY9wdS3vXVCMnHDgZaVNoA==} + engines: {node: '>=12'} + dependencies: + min-indent: 1.0.1 + dev: true + /strip-json-comments/3.1.1: resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} engines: {node: '>=8'} @@ -10527,10 +10753,20 @@ packages: engines: {node: '>=8'} dev: true + /trim-newlines/4.0.2: + resolution: {integrity: sha512-GJtWyq9InR/2HRiLZgpIKv+ufIKrVrvjQWEj7PxAXNc5dwbNJkqhAUoAGgzRmULAnoOM5EIpveYd3J2VeSAIew==} + engines: {node: '>=12'} + dev: true + /trough/2.1.0: resolution: {integrity: sha512-AqTiAOLcj85xS7vQ8QkAV41hPDIJ71XJB4RCUrzo/1GM2CQwhkJGaf9Hgr7BOugMRpgGUrqRg/DrBDl4H40+8g==} dev: true + /ts-dedent/2.2.0: + resolution: {integrity: sha512-q5W7tVM71e2xjHZTlgfTDoPF/SmqKG5hddq9SzR49CH2hayqRKJtQ4mtRlSxKaJlR/+9rEM+mnBHf7I2/BQcpQ==} + engines: {node: '>=6.10'} + dev: false + /ts-node/10.9.1_cbe7ovvae6zqfnmtgctpgpys54: resolution: {integrity: sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==} hasBin: true @@ -10665,6 +10901,11 @@ packages: engines: {node: '>=8'} dev: true + /type-fest/1.4.0: + resolution: {integrity: sha512-yGSza74xk0UG8k+pLh5oeoYirvIiWo5t0/o3zHHAO2tRDiZcxWP7fywNlXhqb6/r6sWvwi+RsyQMWhVLe4BVuA==} + engines: {node: '>=10'} + dev: true + /type-is/1.6.18: resolution: {integrity: sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==} engines: {node: '>= 0.6'} @@ -10980,8 +11221,41 @@ packages: fsevents: 2.3.2 dev: true - /vitepress-plugin-search/1.0.4-alpha.15_s3edpouswd4dgoi2en7bdlrp54: - resolution: {integrity: sha512-Ef/VkhTVYlECVI0H9Ck6745UNPfYFppAqnlxVSMJXdxP2vjOZ5TYNczlTTQ2p9dh16MFw/IurbL1/GrG4nXdNw==} + /vite/4.0.1: + resolution: {integrity: sha512-kZQPzbDau35iWOhy3CpkrRC7It+HIHtulAzBhMqzGHKRf/4+vmh8rPDDdv98SWQrFWo6//3ozwsRmwQIPZsK9g==} + engines: {node: ^14.18.0 || >=16.0.0} + hasBin: true + peerDependencies: + '@types/node': '>= 14' + less: '*' + sass: '*' + stylus: '*' + sugarss: '*' + terser: ^5.4.0 + peerDependenciesMeta: + '@types/node': + optional: true + less: + optional: true + sass: + optional: true + stylus: + optional: true + sugarss: + optional: true + terser: + optional: true + dependencies: + esbuild: 0.16.7 + postcss: 8.4.20 + resolve: 1.22.1 + rollup: 3.7.4 + optionalDependencies: + fsevents: 2.3.2 + dev: true + + /vitepress-plugin-search/1.0.4-alpha.16_ifjhkyx3os4sbm7zdnvthc52am: + resolution: {integrity: sha512-D+rs7bwzH+IO+7T9NlxvqSOqmSKbN1yHxUoqClTy5JH+DomL3CcrH2TgSvXc2s58ztlc1dC07c7THo4cNjlUAg==} engines: {node: ^14.13.1 || ^16.7.0 || >=18} peerDependencies: flexsearch: ^0.7.31 @@ -10994,23 +11268,23 @@ packages: flexsearch: 0.7.31 markdown-it: 13.0.1 vite: 3.2.3 - vitepress: 1.0.0-alpha.28_tbpndr44ulefs3hehwpi2mkf2y - vue: 3.2.41 + vitepress: 1.0.0-alpha.31_tbpndr44ulefs3hehwpi2mkf2y + vue: 3.2.45 dev: true - /vitepress/1.0.0-alpha.28_tbpndr44ulefs3hehwpi2mkf2y: - resolution: {integrity: sha512-pvbLssDMgLUN1terajmPlFBxHSDGO4DqwexKbjFyr7LeELerVuwGrG6F2J1hxmwOlbpLd1kHXEDqGm9JX/kTDQ==} + /vitepress/1.0.0-alpha.31_tbpndr44ulefs3hehwpi2mkf2y: + resolution: {integrity: sha512-FWFXLs7WLbFbemxjBWo2S2+qUZCIoeLLyAKfVUpIu3LUB8oQ8cyIANRGO6f6zsM51u2bvJU9Sm+V6Z0WjOWS2Q==} hasBin: true dependencies: '@docsearch/css': 3.3.0 '@docsearch/js': 3.3.0_tbpndr44ulefs3hehwpi2mkf2y - '@vitejs/plugin-vue': 3.2.0_vite@3.2.3+vue@3.2.41 + '@vitejs/plugin-vue': 4.0.0_vite@4.0.1+vue@3.2.45 '@vue/devtools-api': 6.4.5 - '@vueuse/core': 9.4.0_vue@3.2.41 + '@vueuse/core': 9.6.0_vue@3.2.45 body-scroll-lock: 4.0.0-beta.0 shiki: 0.11.1 - vite: 3.2.3 - vue: 3.2.41 + vite: 4.0.1 + vue: 3.2.45 transitivePeerDependencies: - '@algolia/client-search' - '@types/node' @@ -11162,7 +11436,7 @@ packages: resolution: {integrity: sha512-fmL7V1eiDBFRRnu+gfRWTzyPpNIHJTc4mWnFkwBUmO9U3KPgJAmTx7oxi2bl/Rh6HLdU7+4C9wlj0k2E4AdKFQ==} dev: true - /vue-demi/0.13.11_vue@3.2.41: + /vue-demi/0.13.11_vue@3.2.45: resolution: {integrity: sha512-IR8HoEEGM65YY3ZJYAjMlKygDQn25D5ajNFNoKh9RSDMQtlzCxtfQjdQgv9jjK+m3377SsJXY8ysq8kLCZL25A==} engines: {node: '>=12'} hasBin: true @@ -11174,17 +11448,17 @@ packages: '@vue/composition-api': optional: true dependencies: - vue: 3.2.41 + vue: 3.2.45 dev: true - /vue/3.2.41: - resolution: {integrity: sha512-uuuvnrDXEeZ9VUPljgHkqB5IaVO8SxhPpqF2eWOukVrBnRBx2THPSGQBnVRt0GrIG1gvCmFXMGbd7FqcT1ixNQ==} + /vue/3.2.45: + resolution: {integrity: sha512-9Nx/Mg2b2xWlXykmCwiTUCWHbWIj53bnkizBxKai1g61f2Xit700A1ljowpTIM11e3uipOeiPcSqnmBg6gyiaA==} dependencies: - '@vue/compiler-dom': 3.2.41 - '@vue/compiler-sfc': 3.2.41 - '@vue/runtime-dom': 3.2.41 - '@vue/server-renderer': 3.2.41_vue@3.2.41 - '@vue/shared': 3.2.41 + '@vue/compiler-dom': 3.2.45 + '@vue/compiler-sfc': 3.2.45 + '@vue/runtime-dom': 3.2.45 + '@vue/server-renderer': 3.2.45_vue@3.2.45 + '@vue/shared': 3.2.45 dev: true /w3c-hr-time/1.0.2: