mirror of
https://github.com/mermaid-js/mermaid.git
synced 2025-01-28 07:03:17 +08:00
Merge branch 'develop' into UpdateClasstoMatchUmlSpecs
* develop: (56 commits) chore: Fix unit tests chore(deps): update all patch dependencies chore: Update docs Update docs New Mermaid Live Editor for Confluence Cloud (#4814) Update link to Discourse theme component (#4811) Update flowchart.md (#4810) chore: remove unneeded `CommomDB` chore: Update docs "CSS" instead of "css" in flowchart.md (#4797) Update CONTRIBUTING.md Update CONTRIBUTING.md fix: typos (#4801) chore: Align with convention chore: Add JSDoc to apply in sequenceDB refactor: Tidy up direction handling chore: Fix flowchart arrow chore: Add test to verify activate chore: Update tests snapshot fix: #4691 Align arrowheads properly in sequenceDiagram ...
This commit is contained in:
commit
f1a6ef11f0
@ -71,6 +71,8 @@ Documentation is necessary for all non bugfix/refactoring changes.
|
|||||||
|
|
||||||
Only make changes to files that are in [`/packages/mermaid/src/docs`](packages/mermaid/src/docs)
|
Only make changes to files that are in [`/packages/mermaid/src/docs`](packages/mermaid/src/docs)
|
||||||
|
|
||||||
**_DO NOT CHANGE FILES IN `/docs`_**
|
**_DO NOT CHANGE FILES IN `/docs` MANUALLY_**
|
||||||
|
|
||||||
|
The `/docs` folder will be rebuilt and committed as part of a pre-commit hook.
|
||||||
|
|
||||||
[Join our slack community if you want closer contact!](https://join.slack.com/t/mermaid-talk/shared_invite/enQtNzc4NDIyNzk4OTAyLWVhYjQxOTI2OTg4YmE1ZmJkY2Y4MTU3ODliYmIwOTY3NDJlYjA0YjIyZTdkMDMyZTUwOGI0NjEzYmEwODcwOTE)
|
[Join our slack community if you want closer contact!](https://join.slack.com/t/mermaid-talk/shared_invite/enQtNzc4NDIyNzk4OTAyLWVhYjQxOTI2OTg4YmE1ZmJkY2Y4MTU3ODliYmIwOTY3NDJlYjA0YjIyZTdkMDMyZTUwOGI0NjEzYmEwODcwOTE)
|
||||||
|
@ -38,7 +38,10 @@
|
|||||||
"docsy",
|
"docsy",
|
||||||
"doku",
|
"doku",
|
||||||
"dompurify",
|
"dompurify",
|
||||||
|
"dont",
|
||||||
|
"doublecircle",
|
||||||
"edgechromium",
|
"edgechromium",
|
||||||
|
"elems",
|
||||||
"elkjs",
|
"elkjs",
|
||||||
"elle",
|
"elle",
|
||||||
"faber",
|
"faber",
|
||||||
|
@ -386,30 +386,6 @@ describe('Class diagram V2', () => {
|
|||||||
{ logLevel: 1, flowchart: { htmlLabels: false } }
|
{ logLevel: 1, flowchart: { htmlLabels: false } }
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('18: should handle the direction statement with LR', () => {
|
|
||||||
imgSnapshotTest(
|
|
||||||
`
|
|
||||||
classDiagram
|
|
||||||
direction LR
|
|
||||||
class Student {
|
|
||||||
-idCard : IdCard
|
|
||||||
}
|
|
||||||
class IdCard{
|
|
||||||
-id : int
|
|
||||||
-name : string
|
|
||||||
}
|
|
||||||
class Bike{
|
|
||||||
-id : int
|
|
||||||
-name : string
|
|
||||||
}
|
|
||||||
Student "1" --o "1" IdCard : carries
|
|
||||||
Student "1" --o "1" Bike : rides
|
|
||||||
|
|
||||||
`,
|
|
||||||
{ logLevel: 1, flowchart: { htmlLabels: false } }
|
|
||||||
);
|
|
||||||
});
|
|
||||||
it('17a: should handle the direction statement with BT', () => {
|
it('17a: should handle the direction statement with BT', () => {
|
||||||
imgSnapshotTest(
|
imgSnapshotTest(
|
||||||
`
|
`
|
||||||
@ -457,7 +433,31 @@ describe('Class diagram V2', () => {
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('18: should render a simple class diagram with notes', () => {
|
it('18a: should handle the direction statement with LR', () => {
|
||||||
|
imgSnapshotTest(
|
||||||
|
`
|
||||||
|
classDiagram
|
||||||
|
direction LR
|
||||||
|
class Student {
|
||||||
|
-idCard : IdCard
|
||||||
|
}
|
||||||
|
class IdCard{
|
||||||
|
-id : int
|
||||||
|
-name : string
|
||||||
|
}
|
||||||
|
class Bike{
|
||||||
|
-id : int
|
||||||
|
-name : string
|
||||||
|
}
|
||||||
|
Student "1" --o "1" IdCard : carries
|
||||||
|
Student "1" --o "1" Bike : rides
|
||||||
|
|
||||||
|
`,
|
||||||
|
{ logLevel: 1, flowchart: { htmlLabels: false } }
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('18b: should render a simple class diagram with notes', () => {
|
||||||
imgSnapshotTest(
|
imgSnapshotTest(
|
||||||
`
|
`
|
||||||
classDiagram-v2
|
classDiagram-v2
|
||||||
@ -562,4 +562,13 @@ class C13["With Città foreign language"]
|
|||||||
`
|
`
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
it('should render a simple class diagram with no members', () => {
|
||||||
|
imgSnapshotTest(
|
||||||
|
`
|
||||||
|
classDiagram-v2
|
||||||
|
class Class10
|
||||||
|
`,
|
||||||
|
{ logLevel: 1, flowchart: { htmlLabels: false } }
|
||||||
|
);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
@ -38,12 +38,14 @@
|
|||||||
+quack()
|
+quack()
|
||||||
}
|
}
|
||||||
class Fish{
|
class Fish{
|
||||||
-int sizeInFeet
|
-Listint sizeInFeet
|
||||||
-canEat()
|
-canEat()
|
||||||
}
|
}
|
||||||
class Zebra{
|
class Zebra{
|
||||||
+bool is_wild
|
+bool is_wild
|
||||||
+run()
|
+run(List~T~, List~OT~)
|
||||||
|
%% +run-composite(List~T, K~)
|
||||||
|
+run-nested(List~List~OT~~)
|
||||||
}
|
}
|
||||||
|
|
||||||
</pre>
|
</pre>
|
||||||
@ -80,6 +82,7 @@
|
|||||||
Class01 : #size()
|
Class01 : #size()
|
||||||
Class01 : -int chimp
|
Class01 : -int chimp
|
||||||
Class01 : +int gorilla
|
Class01 : +int gorilla
|
||||||
|
Class01 : +abstractAttribute string*
|
||||||
class Class10~T~ {
|
class Class10~T~ {
|
||||||
<<service>>
|
<<service>>
|
||||||
int id
|
int id
|
||||||
@ -122,6 +125,8 @@
|
|||||||
classDiagram
|
classDiagram
|
||||||
direction LR
|
direction LR
|
||||||
Animal ()-- Dog
|
Animal ()-- Dog
|
||||||
|
Animal ()-- Cat
|
||||||
|
note for Cat "should have no members area"
|
||||||
Dog : bark()
|
Dog : bark()
|
||||||
Dog : species()
|
Dog : species()
|
||||||
</pre>
|
</pre>
|
||||||
@ -151,6 +156,7 @@
|
|||||||
~InternalProperty : string
|
~InternalProperty : string
|
||||||
~AnotherInternalProperty : List~List~string~~
|
~AnotherInternalProperty : List~List~string~~
|
||||||
}
|
}
|
||||||
|
class People List~List~Person~~
|
||||||
</pre>
|
</pre>
|
||||||
<hr />
|
<hr />
|
||||||
|
|
||||||
|
@ -125,6 +125,21 @@
|
|||||||
</pre>
|
</pre>
|
||||||
<hr />
|
<hr />
|
||||||
|
|
||||||
|
<pre class="mermaid">
|
||||||
|
erDiagram
|
||||||
|
_customer_order {
|
||||||
|
bigint id PK
|
||||||
|
bigint customer_id FK
|
||||||
|
text shipping_address
|
||||||
|
text delivery_method
|
||||||
|
timestamp_with_time_zone ordered_at
|
||||||
|
numeric total_tax_amount
|
||||||
|
numeric total_price
|
||||||
|
text payment_method
|
||||||
|
}
|
||||||
|
</pre>
|
||||||
|
<hr />
|
||||||
|
|
||||||
<script type="module">
|
<script type="module">
|
||||||
import mermaid from './mermaid.esm.mjs';
|
import mermaid from './mermaid.esm.mjs';
|
||||||
mermaid.initialize({
|
mermaid.initialize({
|
||||||
|
@ -42,7 +42,7 @@ Once the release happens we add a tag to the `release` branch and merge it with
|
|||||||
2. Check out the `develop` branch
|
2. Check out the `develop` branch
|
||||||
3. Create a new branch for your work. Please name the branch following our naming convention below.
|
3. Create a new branch for your work. Please name the branch following our naming convention below.
|
||||||
|
|
||||||
We use the follow naming convention for branches:
|
We use the following naming convention for branches:
|
||||||
|
|
||||||
```txt
|
```txt
|
||||||
[feature | bug | chore | docs]/[issue number]_[short description using dashes ('-') or underscores ('_') instead of spaces]
|
[feature | bug | chore | docs]/[issue number]_[short description using dashes ('-') or underscores ('_') instead of spaces]
|
||||||
|
@ -22,7 +22,7 @@ In GitHub, you first **fork** a repository when you are going to make changes an
|
|||||||
|
|
||||||
Then you **clone** a copy to your local development machine (e.g. where you code) to make a copy with all the files to work with.
|
Then you **clone** a copy to your local development machine (e.g. where you code) to make a copy with all the files to work with.
|
||||||
|
|
||||||
[Fork mermaid](https://github.com/mermaid-js/mermaid/fork) to start contributing to the main project and its documentaion, or [search for other repositories](https://github.com/orgs/mermaid-js/repositories).
|
[Fork mermaid](https://github.com/mermaid-js/mermaid/fork) to start contributing to the main project and its documentation, or [search for other repositories](https://github.com/orgs/mermaid-js/repositories).
|
||||||
|
|
||||||
[Here is a GitHub document that gives an overview of the process.](https://docs.github.com/en/get-started/quickstart/fork-a-repo)
|
[Here is a GitHub document that gives an overview of the process.](https://docs.github.com/en/get-started/quickstart/fork-a-repo)
|
||||||
|
|
||||||
|
@ -22,7 +22,7 @@ In GitHub, you first **fork** a repository when you are going to make changes an
|
|||||||
|
|
||||||
Then you **clone** a copy to your local development machine (e.g. where you code) to make a copy with all the files to work with.
|
Then you **clone** a copy to your local development machine (e.g. where you code) to make a copy with all the files to work with.
|
||||||
|
|
||||||
[Fork mermaid](https://github.com/mermaid-js/mermaid/fork) to start contributing to the main project and its documentaion, or [search for other repositories](https://github.com/orgs/mermaid-js/repositories).
|
[Fork mermaid](https://github.com/mermaid-js/mermaid/fork) to start contributing to the main project and its documentation, or [search for other repositories](https://github.com/orgs/mermaid-js/repositories).
|
||||||
|
|
||||||
[Here is a GitHub document that gives an overview of the process.](https://docs.github.com/en/get-started/quickstart/fork-a-repo)
|
[Here is a GitHub document that gives an overview of the process.](https://docs.github.com/en/get-started/quickstart/fork-a-repo)
|
||||||
|
|
||||||
|
@ -19,7 +19,7 @@ For instance:
|
|||||||
|
|
||||||
#### Store data found during parsing
|
#### Store data found during parsing
|
||||||
|
|
||||||
There are some jison specific sub steps here where the parser stores the data encountered when parsing the diagram, this data is later used by the renderer. You can during the parsing call a object provided to the parser by the user of the parser. This object can be called during parsing for storing data.
|
There are some jison specific sub steps here where the parser stores the data encountered when parsing the diagram, this data is later used by the renderer. You can during the parsing call an object provided to the parser by the user of the parser. This object can be called during parsing for storing data.
|
||||||
|
|
||||||
```jison
|
```jison
|
||||||
statement
|
statement
|
||||||
@ -35,7 +35,7 @@ In the extract of the grammar above, it is defined that a call to the setTitle m
|
|||||||
> **Note**
|
> **Note**
|
||||||
> Make sure that the `parseError` function for the parser is defined and calling `mermaid.parseError`. This way a common way of detecting parse errors is provided for the end-user.
|
> Make sure that the `parseError` function for the parser is defined and calling `mermaid.parseError`. This way a common way of detecting parse errors is provided for the end-user.
|
||||||
|
|
||||||
For more info look in the example diagram type:
|
For more info look at the example diagram type:
|
||||||
|
|
||||||
The `yy` object has the following function:
|
The `yy` object has the following function:
|
||||||
|
|
||||||
@ -54,7 +54,7 @@ parser.yy = db;
|
|||||||
|
|
||||||
### Step 2: Rendering
|
### Step 2: Rendering
|
||||||
|
|
||||||
Write a renderer that given the data found during parsing renders the diagram. To look at an example look at sequenceRenderer.js rather then the flowchart renderer as this is a more generic example.
|
Write a renderer that given the data found during parsing renders the diagram. To look at an example look at sequenceRenderer.js rather than the flowchart renderer as this is a more generic example.
|
||||||
|
|
||||||
Place the renderer in the diagram folder.
|
Place the renderer in the diagram folder.
|
||||||
|
|
||||||
@ -62,7 +62,7 @@ Place the renderer in the diagram folder.
|
|||||||
|
|
||||||
The second thing to do is to add the capability to detect the new diagram to type to the detectType in `diagram-api/detectType.ts`. 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 `diagram-api/detectType.ts`. 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.
|
[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
|
For example, if your new diagram uses 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.
|
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.
|
||||||
|
|
||||||
Note that the diagram type key does not have to be the same as the diagram keyword chosen for the [grammar](#grammar), but it is helpful if they are the same.
|
Note that the diagram type key does not have to be the same as the diagram keyword chosen for the [grammar](#grammar), but it is helpful if they are the same.
|
||||||
@ -122,7 +122,7 @@ There are a few features that are common between the different types of diagrams
|
|||||||
- Themes, there is a common way to modify the styling of diagrams in Mermaid.
|
- Themes, there is a common way to modify the styling of diagrams in Mermaid.
|
||||||
- Comments should follow mermaid standards
|
- Comments should follow mermaid standards
|
||||||
|
|
||||||
Here some pointers on how to handle these different areas.
|
Here are some pointers on how to handle these different areas.
|
||||||
|
|
||||||
## Accessibility
|
## Accessibility
|
||||||
|
|
||||||
@ -140,7 +140,7 @@ See [the definition of aria-roledescription](https://www.w3.org/TR/wai-aria-1.1/
|
|||||||
|
|
||||||
### accessible title and description
|
### accessible title and description
|
||||||
|
|
||||||
The syntax for accessible titles and descriptions is described in [the Accessibility documenation section.](../config/accessibility.md)
|
The syntax for accessible titles and descriptions is described in [the Accessibility documentation section.](../config/accessibility.md)
|
||||||
|
|
||||||
As a design goal, the jison syntax should be similar between the diagrams.
|
As a design goal, the jison syntax should be similar between the diagrams.
|
||||||
|
|
||||||
|
@ -126,7 +126,7 @@ The following code snippet changes `theme` to `forest`:
|
|||||||
|
|
||||||
`%%{init: { "theme": "forest" } }%%`
|
`%%{init: { "theme": "forest" } }%%`
|
||||||
|
|
||||||
Possible theme values are: `default`,`base`, `dark`, `forest` and `neutral`.
|
Possible theme values are: `default`, `base`, `dark`, `forest` and `neutral`.
|
||||||
Default Value is `default`.
|
Default Value is `default`.
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
@ -291,7 +291,7 @@ Let us see an example:
|
|||||||
sequenceDiagram
|
sequenceDiagram
|
||||||
|
|
||||||
Alice->Bob: Hello Bob, how are you?
|
Alice->Bob: Hello Bob, how are you?
|
||||||
Bob->Alice: Fine, how did you mother like the book I suggested? And did you catch the new book about alien invasion?
|
Bob->Alice: Fine, how did your mother like the book I suggested? And did you catch the new book about alien invasion?
|
||||||
Alice->Bob: Good.
|
Alice->Bob: Good.
|
||||||
Bob->Alice: Cool
|
Bob->Alice: Cool
|
||||||
```
|
```
|
||||||
@ -300,7 +300,7 @@ Bob->Alice: Cool
|
|||||||
sequenceDiagram
|
sequenceDiagram
|
||||||
|
|
||||||
Alice->Bob: Hello Bob, how are you?
|
Alice->Bob: Hello Bob, how are you?
|
||||||
Bob->Alice: Fine, how did you mother like the book I suggested? And did you catch the new book about alien invasion?
|
Bob->Alice: Fine, how did your mother like the book I suggested? And did you catch the new book about alien invasion?
|
||||||
Alice->Bob: Good.
|
Alice->Bob: Good.
|
||||||
Bob->Alice: Cool
|
Bob->Alice: Cool
|
||||||
```
|
```
|
||||||
@ -317,7 +317,7 @@ By applying that snippet to the diagram above, `wrap` will be enabled:
|
|||||||
%%{init: { "sequence": { "wrap": true, "width":300 } } }%%
|
%%{init: { "sequence": { "wrap": true, "width":300 } } }%%
|
||||||
sequenceDiagram
|
sequenceDiagram
|
||||||
Alice->Bob: Hello Bob, how are you?
|
Alice->Bob: Hello Bob, how are you?
|
||||||
Bob->Alice: Fine, how did you mother like the book I suggested? And did you catch the new book about alien invasion?
|
Bob->Alice: Fine, how did your mother like the book I suggested? And did you catch the new book about alien invasion?
|
||||||
Alice->Bob: Good.
|
Alice->Bob: Good.
|
||||||
Bob->Alice: Cool
|
Bob->Alice: Cool
|
||||||
```
|
```
|
||||||
@ -326,7 +326,7 @@ Bob->Alice: Cool
|
|||||||
%%{init: { "sequence": { "wrap": true, "width":300 } } }%%
|
%%{init: { "sequence": { "wrap": true, "width":300 } } }%%
|
||||||
sequenceDiagram
|
sequenceDiagram
|
||||||
Alice->Bob: Hello Bob, how are you?
|
Alice->Bob: Hello Bob, how are you?
|
||||||
Bob->Alice: Fine, how did you mother like the book I suggested? And did you catch the new book about alien invasion?
|
Bob->Alice: Fine, how did your mother like the book I suggested? And did you catch the new book about alien invasion?
|
||||||
Alice->Bob: Good.
|
Alice->Bob: Good.
|
||||||
Bob->Alice: Cool
|
Bob->Alice: Cool
|
||||||
```
|
```
|
||||||
|
@ -41,7 +41,7 @@ pnpm add mermaid
|
|||||||
|
|
||||||
**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/getting-started.md)
|
> Note: This topic is explored in greater depth in the [User Guide for Beginners](../intro/getting-started.md)
|
||||||
|
|
||||||
The easiest way to integrate mermaid on a web page requires two elements:
|
The easiest way to integrate mermaid on a web page requires two elements:
|
||||||
|
|
||||||
@ -100,7 +100,7 @@ Mermaid can load multiple diagrams, in the same page.
|
|||||||
|
|
||||||
## Enabling Click Event and Tags in Nodes
|
## Enabling Click Event and Tags in Nodes
|
||||||
|
|
||||||
A `securityLevel` configuration has to first be cleared. `securityLevel` sets the level of trust for the parsed diagrams and limits click functionality. This was introduce in version 8.2 as a security improvement, aimed at preventing malicious use.
|
A `securityLevel` configuration has to first be cleared. `securityLevel` sets the level of trust for the parsed diagrams and limits click functionality. This was introduced in version 8.2 as a security improvement, aimed at preventing malicious use.
|
||||||
|
|
||||||
**It is the site owner's responsibility to discriminate between trustworthy and untrustworthy user-bases and we encourage the use of discretion.**
|
**It is the site owner's responsibility to discriminate between trustworthy and untrustworthy user-bases and we encourage the use of discretion.**
|
||||||
|
|
||||||
@ -115,13 +115,13 @@ Values:
|
|||||||
- **strict**: (**default**) HTML tags in the text are encoded and click functionality is disabled.
|
- **strict**: (**default**) HTML tags in the text are encoded and click functionality is disabled.
|
||||||
- **antiscript**: HTML tags in text are allowed (only script elements are removed) and click functionality is enabled.
|
- **antiscript**: HTML tags in text are allowed (only script elements are removed) and click functionality is enabled.
|
||||||
- **loose**: HTML tags in text are allowed and click functionality is enabled.
|
- **loose**: HTML tags in text are allowed and click functionality is enabled.
|
||||||
- **sandbox**: With this security level, all rendering takes place in a sandboxed iframe. This prevent any JavaScript from running in the context. This may hinder interactive functionality of the diagram, like scripts, popups in the sequence diagram, links to other tabs or targets, etc.
|
- **sandbox**: With this security level, all rendering takes place in a sandboxed iframe. This prevents any JavaScript from running in the context. This may hinder interactive functionality of the diagram, like scripts, popups in the sequence diagram, links to other tabs or targets, etc.
|
||||||
|
|
||||||
> **Note**
|
> **Note**
|
||||||
> This changes the default behaviour of mermaid so that after upgrade to 8.2, unless the `securityLevel` is not changed, tags in flowcharts are encoded as tags and clicking is disabled.
|
> This changes the default behaviour of mermaid so that after upgrade to 8.2, unless the `securityLevel` is not changed, tags in flowcharts are encoded as tags and clicking is disabled.
|
||||||
> **sandbox** security level is still in the beta version.
|
> **sandbox** security level is still in the beta version.
|
||||||
|
|
||||||
**If you are taking responsibility for the diagram source security you can set the `securityLevel` to a value of your choosing . This allows clicks and tags are allowed.**
|
**If you are taking responsibility for the diagram source security you can set the `securityLevel` to a value of your choosing. This allows clicks and tags are allowed.**
|
||||||
|
|
||||||
**To change `securityLevel`, you have to call `mermaid.initialize`:**
|
**To change `securityLevel`, you have to call `mermaid.initialize`:**
|
||||||
|
|
||||||
|
@ -49,6 +49,7 @@ They also serve as proof of concept, for the variety of things that can be built
|
|||||||
- [Mermaid plugin for GitBook](https://github.com/wwformat/gitbook-plugin-mermaid-pdf)
|
- [Mermaid plugin for GitBook](https://github.com/wwformat/gitbook-plugin-mermaid-pdf)
|
||||||
- [LiveBook](https://livebook.dev) (**Native support**)
|
- [LiveBook](https://livebook.dev) (**Native support**)
|
||||||
- [Atlassian Products](https://www.atlassian.com)
|
- [Atlassian Products](https://www.atlassian.com)
|
||||||
|
- [Mermaid Live Editor for Confluence Cloud](https://marketplace.atlassian.com/apps/1231571/mermaid-live-editor-for-confluence?hosting=cloud&tab=overview)
|
||||||
- [Mermaid Plugin for Confluence](https://marketplace.atlassian.com/apps/1214124/mermaid-plugin-for-confluence?hosting=server&tab=overview)
|
- [Mermaid Plugin for Confluence](https://marketplace.atlassian.com/apps/1214124/mermaid-plugin-for-confluence?hosting=server&tab=overview)
|
||||||
- [CloudScript.io Addon](https://marketplace.atlassian.com/apps/1219878/cloudscript-io-mermaid-addon?hosting=cloud&tab=overview)
|
- [CloudScript.io Addon](https://marketplace.atlassian.com/apps/1219878/cloudscript-io-mermaid-addon?hosting=cloud&tab=overview)
|
||||||
- [Auto convert diagrams in Jira](https://github.com/coddingtonbear/jirafs-mermaid)
|
- [Auto convert diagrams in Jira](https://github.com/coddingtonbear/jirafs-mermaid)
|
||||||
|
@ -103,7 +103,7 @@ When writing the .html file, we give two instructions inside the html code to th
|
|||||||
|
|
||||||
a. The mermaid code for the diagram we want to create.
|
a. The mermaid code for the diagram we want to create.
|
||||||
|
|
||||||
b. The importing of mermaid library through the `mermaid.esm.mjs` or `mermaid.esm.min.mjs` and the `mermaid.initialize()` call, which dictates the appearance of diagrams and also starts the rendering process .
|
b. The importing of mermaid library through the `mermaid.esm.mjs` or `mermaid.esm.min.mjs` and the `mermaid.initialize()` call, which dictates the appearance of diagrams and also starts the rendering process.
|
||||||
|
|
||||||
**a. The embedded mermaid diagram definition inside a `<pre class="mermaid">`:**
|
**a. The embedded mermaid diagram definition inside a `<pre class="mermaid">`:**
|
||||||
|
|
||||||
@ -221,4 +221,4 @@ In this example mermaid.js is referenced in `src` as a separate JavaScript file,
|
|||||||
|
|
||||||
**Comments from Knut Sveidqvist, creator of mermaid:**
|
**Comments from Knut Sveidqvist, creator of mermaid:**
|
||||||
|
|
||||||
- In early versions of mermaid, the `<script>` tag was invoked in the `<head>` part of the web page. Nowadays we can place it in the `<body>` as seen above. Older parts of the documentation frequently reflects the previous way which still works.
|
- In early versions of mermaid, the `<script>` tag was invoked in the `<head>` part of the web page. Nowadays we can place it in the `<body>` as seen above. Older parts of the documentation frequently reflect the previous way which still works.
|
||||||
|
@ -90,7 +90,7 @@ Mermaid syntax for ER diagrams is compatible with PlantUML, with an extension to
|
|||||||
|
|
||||||
Where:
|
Where:
|
||||||
|
|
||||||
- `first-entity` is the name of an entity. Names must begin with an alphabetic character and may also contain digits, hyphens, and underscores.
|
- `first-entity` is the name of an entity. Names must begin with an alphabetic character or an underscore (from v\<MERMAID_RELEASE_VERSION>+), and may also contain digits and hyphens.
|
||||||
- `relationship` describes the way that both entities inter-relate. See below.
|
- `relationship` describes the way that both entities inter-relate. See below.
|
||||||
- `second-entity` is the name of the other entity.
|
- `second-entity` is the name of the other entity.
|
||||||
- `relationship-label` describes the relationship from the perspective of the first entity.
|
- `relationship-label` describes the relationship from the perspective of the first entity.
|
||||||
|
@ -1051,9 +1051,9 @@ flowchart LR
|
|||||||
classDef foobar stroke:#00f
|
classDef foobar stroke:#00f
|
||||||
```
|
```
|
||||||
|
|
||||||
### Css classes
|
### CSS classes
|
||||||
|
|
||||||
It is also possible to predefine classes in css styles that can be applied from the graph definition as in the example
|
It is also possible to predefine classes in CSS styles that can be applied from the graph definition as in the example
|
||||||
below:
|
below:
|
||||||
|
|
||||||
**Example style**
|
**Example style**
|
||||||
|
@ -58,7 +58,7 @@ mindmap
|
|||||||
|
|
||||||
The syntax for creating Mindmaps is simple and relies on indentation for setting the levels in the hierarchy.
|
The syntax for creating Mindmaps is simple and relies on indentation for setting the levels in the hierarchy.
|
||||||
|
|
||||||
In the following example you can see how there are 3 different levels. One with starting at the left of the text and another level with two rows starting at the same column, defining the node A. At the end there is one more level where the text is indented further then the previous lines defining the nodes B and C.
|
In the following example you can see how there are 3 different levels. One with starting at the left of the text and another level with two rows starting at the same column, defining the node A. At the end there is one more level where the text is indented further than the previous lines defining the nodes B and C.
|
||||||
|
|
||||||
mindmap
|
mindmap
|
||||||
Root
|
Root
|
||||||
@ -66,7 +66,7 @@ In the following example you can see how there are 3 different levels. One with
|
|||||||
B
|
B
|
||||||
C
|
C
|
||||||
|
|
||||||
In summary is a simple text outline where there are one node at the root level called `Root` which has one child `A`. `A` in turn has two children `B`and `C`. In the diagram below we can see this rendered as a mindmap.
|
In summary is a simple text outline where there is one node at the root level called `Root` which has one child `A`. `A` in turn has two children `B`and `C`. In the diagram below we can see this rendered as a mindmap.
|
||||||
|
|
||||||
```mermaid-example
|
```mermaid-example
|
||||||
mindmap
|
mindmap
|
||||||
@ -228,7 +228,7 @@ _These classes need to be supplied by the site administrator._
|
|||||||
|
|
||||||
## Unclear indentation
|
## Unclear indentation
|
||||||
|
|
||||||
The actual indentation does not really matter only compared with the previous rows. If we take the previous example and disrupt it a little we can se how the calculations are performed. Let us start with placing C with a smaller indentation than `B`but larger then `A`.
|
The actual indentation does not really matter only compared with the previous rows. If we take the previous example and disrupt it a little we can see how the calculations are performed. Let us start with placing C with a smaller indentation than `B` but larger then `A`.
|
||||||
|
|
||||||
mindmap
|
mindmap
|
||||||
Root
|
Root
|
||||||
|
@ -47,8 +47,8 @@ quadrantChart
|
|||||||
## Syntax
|
## Syntax
|
||||||
|
|
||||||
> **Note**
|
> **Note**
|
||||||
> If there is no points available in the chart both **axis** text and **quadrant** will be rendered in the center of the respective quadrant.
|
> If there are no points available in the chart both **axis** text and **quadrant** will be rendered in the center of the respective quadrant.
|
||||||
> If there are points **x-axis** labels will rendered from left of the respective quadrant also they will be displayed in bottom of the chart, and **y-axis** lables will be rendered in bottom of the respective quadrant, the quadrant text will render at top of the respective quadrant.
|
> If there are points **x-axis** labels will rendered from the left of the respective quadrant also they will be displayed at the bottom of the chart, and **y-axis** labels will be rendered at the bottom of the respective quadrant, the quadrant text will render at the top of the respective quadrant.
|
||||||
|
|
||||||
> **Note**
|
> **Note**
|
||||||
> For points x and y value min value is 0 and max value is 1.
|
> For points x and y value min value is 0 and max value is 1.
|
||||||
@ -64,7 +64,7 @@ The title is a short description of the chart and it will always render on top o
|
|||||||
|
|
||||||
### x-axis
|
### x-axis
|
||||||
|
|
||||||
The x-axis determine what text would be displayed in the x-axis. In x-axis there is two part **left** and **right** you can pass **both** or you can pass only **left**. The statement should start with `x-axis` then the `left axis text` followed by the delimiter `-->` then `right axis text`.
|
The x-axis determines what text would be displayed in the x-axis. In x-axis there is two part **left** and **right** you can pass **both** or you can pass only **left**. The statement should start with `x-axis` then the `left axis text` followed by the delimiter `-->` then `right axis text`.
|
||||||
|
|
||||||
#### Example
|
#### Example
|
||||||
|
|
||||||
@ -73,7 +73,7 @@ The x-axis determine what text would be displayed in the x-axis. In x-axis there
|
|||||||
|
|
||||||
### y-axis
|
### y-axis
|
||||||
|
|
||||||
The y-axis determine what text would be displayed in the y-axis. In y-axis there is two part **top** and **bottom** you can pass **both** or you can pass only **bottom**. The statement should start with `y-axis` then the `bottom axis text` followed by the delimiter `-->` then `top axis text`.
|
The y-axis determines what text would be displayed in the y-axis. In y-axis there is two part **top** and **bottom** you can pass **both** or you can pass only **bottom**. The statement should start with `y-axis` then the `bottom axis text` followed by the delimiter `-->` then `top axis text`.
|
||||||
|
|
||||||
#### Example
|
#### Example
|
||||||
|
|
||||||
|
@ -197,7 +197,7 @@ Electricity grid,H2 conversion,27.14
|
|||||||
|
|
||||||
### Empty Lines
|
### Empty Lines
|
||||||
|
|
||||||
CSV does not support empty lines without comma delimeters by default. But you can add them if needed:
|
CSV does not support empty lines without comma delimiters by default. But you can add them if needed:
|
||||||
|
|
||||||
```mermaid-example
|
```mermaid-example
|
||||||
sankey-beta
|
sankey-beta
|
||||||
|
@ -164,7 +164,7 @@ The actor(s) can be grouped in vertical boxes. You can define a color (if not, i
|
|||||||
end
|
end
|
||||||
A->>J: Hello John, how are you?
|
A->>J: Hello John, how are you?
|
||||||
J->>A: Great!
|
J->>A: Great!
|
||||||
A->>B: Hello Bob, how is Charly ?
|
A->>B: Hello Bob, how is Charly?
|
||||||
B->>C: Hello Charly, how are you?
|
B->>C: Hello Charly, how are you?
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -180,7 +180,7 @@ The actor(s) can be grouped in vertical boxes. You can define a color (if not, i
|
|||||||
end
|
end
|
||||||
A->>J: Hello John, how are you?
|
A->>J: Hello John, how are you?
|
||||||
J->>A: Great!
|
J->>A: Great!
|
||||||
A->>B: Hello Bob, how is Charly ?
|
A->>B: Hello Bob, how is Charly?
|
||||||
B->>C: Hello Charly, how are you?
|
B->>C: Hello Charly, how are you?
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
"version": "10.2.4",
|
"version": "10.2.4",
|
||||||
"description": "Markdownish syntax for generating flowcharts, sequence diagrams, class diagrams, gantt charts and git graphs.",
|
"description": "Markdownish syntax for generating flowcharts, sequence diagrams, class diagrams, gantt charts and git graphs.",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"packageManager": "pnpm@8.6.12",
|
"packageManager": "pnpm@8.7.1",
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"diagram",
|
"diagram",
|
||||||
"markdown",
|
"markdown",
|
||||||
|
@ -117,7 +117,7 @@
|
|||||||
"rimraf": "^5.0.0",
|
"rimraf": "^5.0.0",
|
||||||
"start-server-and-test": "^2.0.0",
|
"start-server-and-test": "^2.0.0",
|
||||||
"type-fest": "^4.1.0",
|
"type-fest": "^4.1.0",
|
||||||
"typedoc": "^0.24.5",
|
"typedoc": "^0.25.0",
|
||||||
"typedoc-plugin-markdown": "^3.15.2",
|
"typedoc-plugin-markdown": "^3.15.2",
|
||||||
"typescript": "^5.0.4",
|
"typescript": "^5.0.4",
|
||||||
"unist-util-flatmap": "^1.0.0",
|
"unist-util-flatmap": "^1.0.0",
|
||||||
|
@ -1,47 +0,0 @@
|
|||||||
import { sanitizeText as _sanitizeText } from './diagrams/common/common.js';
|
|
||||||
import { getConfig } from './config.js';
|
|
||||||
let title = '';
|
|
||||||
let diagramTitle = '';
|
|
||||||
let description = '';
|
|
||||||
|
|
||||||
const sanitizeText = (txt: string): string => _sanitizeText(txt, getConfig());
|
|
||||||
|
|
||||||
export const clear = function (): void {
|
|
||||||
title = '';
|
|
||||||
description = '';
|
|
||||||
diagramTitle = '';
|
|
||||||
};
|
|
||||||
|
|
||||||
export const setAccTitle = function (txt: string): void {
|
|
||||||
title = sanitizeText(txt).replace(/^\s+/g, '');
|
|
||||||
};
|
|
||||||
|
|
||||||
export const getAccTitle = function (): string {
|
|
||||||
return title || diagramTitle;
|
|
||||||
};
|
|
||||||
|
|
||||||
export const setAccDescription = function (txt: string): void {
|
|
||||||
description = sanitizeText(txt).replace(/\n\s+/g, '\n');
|
|
||||||
};
|
|
||||||
|
|
||||||
export const getAccDescription = function (): string {
|
|
||||||
return description;
|
|
||||||
};
|
|
||||||
|
|
||||||
export const setDiagramTitle = function (txt: string): void {
|
|
||||||
diagramTitle = sanitizeText(txt);
|
|
||||||
};
|
|
||||||
|
|
||||||
export const getDiagramTitle = function (): string {
|
|
||||||
return diagramTitle;
|
|
||||||
};
|
|
||||||
|
|
||||||
export default {
|
|
||||||
getAccTitle,
|
|
||||||
setAccTitle,
|
|
||||||
getDiagramTitle,
|
|
||||||
setDiagramTitle,
|
|
||||||
getAccDescription,
|
|
||||||
setAccDescription,
|
|
||||||
clear,
|
|
||||||
};
|
|
@ -368,7 +368,20 @@ const cutPathAtIntersect = (_points, boundryNode) => {
|
|||||||
return points;
|
return points;
|
||||||
};
|
};
|
||||||
|
|
||||||
//(edgePaths, e, edge, clusterDb, diagramtype, graph)
|
/**
|
||||||
|
* Calculate the deltas and angle between two points
|
||||||
|
* @param {{x: number, y:number}} point1
|
||||||
|
* @param {{x: number, y:number}} point2
|
||||||
|
* @returns {{angle: number, deltaX: number, deltaY: number}}
|
||||||
|
*/
|
||||||
|
function calculateDeltaAndAngle(point1, point2) {
|
||||||
|
const [x1, y1] = [point1.x, point1.y];
|
||||||
|
const [x2, y2] = [point2.x, point2.y];
|
||||||
|
const deltaX = x2 - x1;
|
||||||
|
const deltaY = y2 - y1;
|
||||||
|
return { angle: Math.atan(deltaY / deltaX), deltaX, deltaY };
|
||||||
|
}
|
||||||
|
|
||||||
export const insertEdge = function (elem, e, edge, clusterDb, diagramType, graph) {
|
export const insertEdge = function (elem, e, edge, clusterDb, diagramType, graph) {
|
||||||
let points = edge.points;
|
let points = edge.points;
|
||||||
let pointsHasChanged = false;
|
let pointsHasChanged = false;
|
||||||
@ -435,22 +448,62 @@ export const insertEdge = function (elem, e, edge, clusterDb, diagramType, graph
|
|||||||
const lineData = points.filter((p) => !Number.isNaN(p.y));
|
const lineData = points.filter((p) => !Number.isNaN(p.y));
|
||||||
|
|
||||||
// This is the accessor function we talked about above
|
// This is the accessor function we talked about above
|
||||||
let curve;
|
let curve = curveBasis;
|
||||||
// Currently only flowcharts get the curve from the settings, perhaps this should
|
// Currently only flowcharts get the curve from the settings, perhaps this should
|
||||||
// be expanded to a common setting? Restricting it for now in order not to cause side-effects that
|
// be expanded to a common setting? Restricting it for now in order not to cause side-effects that
|
||||||
// have not been thought through
|
// have not been thought through
|
||||||
if (diagramType === 'graph' || diagramType === 'flowchart') {
|
if (edge.curve && (diagramType === 'graph' || diagramType === 'flowchart')) {
|
||||||
curve = edge.curve || curveBasis;
|
curve = edge.curve;
|
||||||
} else {
|
|
||||||
curve = curveBasis;
|
|
||||||
}
|
}
|
||||||
// curve = curveLinear;
|
|
||||||
|
// We need to draw the lines a bit shorter to avoid drawing
|
||||||
|
// under any transparent markers.
|
||||||
|
// The offsets are calculated from the markers' dimensions.
|
||||||
|
const markerOffsets = {
|
||||||
|
aggregation: 18,
|
||||||
|
extension: 18,
|
||||||
|
composition: 18,
|
||||||
|
dependency: 6,
|
||||||
|
lollipop: 13.5,
|
||||||
|
arrow_point: 5.3,
|
||||||
|
};
|
||||||
|
|
||||||
const lineFunction = line()
|
const lineFunction = line()
|
||||||
.x(function (d) {
|
.x(function (d, i, data) {
|
||||||
return d.x;
|
let offset = 0;
|
||||||
|
if (i === 0 && Object.hasOwn(markerOffsets, edge.arrowTypeStart)) {
|
||||||
|
// Handle first point
|
||||||
|
// Calculate the angle and delta between the first two points
|
||||||
|
const { angle, deltaX } = calculateDeltaAndAngle(data[0], data[1]);
|
||||||
|
// Calculate the offset based on the angle and the marker's dimensions
|
||||||
|
offset = markerOffsets[edge.arrowTypeStart] * Math.cos(angle) * (deltaX >= 0 ? 1 : -1) || 0;
|
||||||
|
} else if (i === data.length - 1 && Object.hasOwn(markerOffsets, edge.arrowTypeEnd)) {
|
||||||
|
// Handle last point
|
||||||
|
// Calculate the angle and delta between the last two points
|
||||||
|
const { angle, deltaX } = calculateDeltaAndAngle(
|
||||||
|
data[data.length - 1],
|
||||||
|
data[data.length - 2]
|
||||||
|
);
|
||||||
|
offset = markerOffsets[edge.arrowTypeEnd] * Math.cos(angle) * (deltaX >= 0 ? 1 : -1) || 0;
|
||||||
|
}
|
||||||
|
return d.x + offset;
|
||||||
})
|
})
|
||||||
.y(function (d) {
|
.y(function (d, i, data) {
|
||||||
return d.y;
|
// Same handling as X above
|
||||||
|
let offset = 0;
|
||||||
|
if (i === 0 && Object.hasOwn(markerOffsets, edge.arrowTypeStart)) {
|
||||||
|
const { angle, deltaY } = calculateDeltaAndAngle(data[0], data[1]);
|
||||||
|
offset =
|
||||||
|
markerOffsets[edge.arrowTypeStart] * Math.abs(Math.sin(angle)) * (deltaY >= 0 ? 1 : -1);
|
||||||
|
} else if (i === data.length - 1 && Object.hasOwn(markerOffsets, edge.arrowTypeEnd)) {
|
||||||
|
const { angle, deltaY } = calculateDeltaAndAngle(
|
||||||
|
data[data.length - 1],
|
||||||
|
data[data.length - 2]
|
||||||
|
);
|
||||||
|
offset =
|
||||||
|
markerOffsets[edge.arrowTypeEnd] * Math.abs(Math.sin(angle)) * (deltaY >= 0 ? 1 : -1);
|
||||||
|
}
|
||||||
|
return d.y + offset;
|
||||||
})
|
})
|
||||||
.curve(curve);
|
.curve(curve);
|
||||||
|
|
||||||
|
@ -155,9 +155,9 @@ export const render = async (elem, graph, markers, diagramtype, id) => {
|
|||||||
clearClusters();
|
clearClusters();
|
||||||
clearGraphlib();
|
clearGraphlib();
|
||||||
|
|
||||||
log.warn('Graph at first:', graphlibJson.write(graph));
|
log.warn('Graph at first:', JSON.stringify(graphlibJson.write(graph)));
|
||||||
adjustClustersAndEdges(graph);
|
adjustClustersAndEdges(graph);
|
||||||
log.warn('Graph after:', graphlibJson.write(graph));
|
log.warn('Graph after:', JSON.stringify(graphlibJson.write(graph)));
|
||||||
// log.warn('Graph ever after:', graphlibJson.write(graph.node('A').graph));
|
// log.warn('Graph ever after:', graphlibJson.write(graph.node('A').graph));
|
||||||
await recursiveRender(elem, graph, diagramtype);
|
await recursiveRender(elem, graph, diagramtype);
|
||||||
};
|
};
|
||||||
|
@ -71,7 +71,7 @@ const extension = (elem, type, id) => {
|
|||||||
.append('marker')
|
.append('marker')
|
||||||
.attr('id', type + '-extensionStart')
|
.attr('id', type + '-extensionStart')
|
||||||
.attr('class', 'marker extension ' + type)
|
.attr('class', 'marker extension ' + type)
|
||||||
.attr('refX', 0)
|
.attr('refX', 18)
|
||||||
.attr('refY', 7)
|
.attr('refY', 7)
|
||||||
.attr('markerWidth', 190)
|
.attr('markerWidth', 190)
|
||||||
.attr('markerHeight', 240)
|
.attr('markerHeight', 240)
|
||||||
@ -85,7 +85,7 @@ const extension = (elem, type, id) => {
|
|||||||
.append('marker')
|
.append('marker')
|
||||||
.attr('id', type + '-extensionEnd')
|
.attr('id', type + '-extensionEnd')
|
||||||
.attr('class', 'marker extension ' + type)
|
.attr('class', 'marker extension ' + type)
|
||||||
.attr('refX', 19)
|
.attr('refX', 1)
|
||||||
.attr('refY', 7)
|
.attr('refY', 7)
|
||||||
.attr('markerWidth', 20)
|
.attr('markerWidth', 20)
|
||||||
.attr('markerHeight', 28)
|
.attr('markerHeight', 28)
|
||||||
@ -134,7 +134,7 @@ const composition = (elem, type) => {
|
|||||||
.append('marker')
|
.append('marker')
|
||||||
.attr('id', type + '-compositionStart')
|
.attr('id', type + '-compositionStart')
|
||||||
.attr('class', 'marker composition ' + type)
|
.attr('class', 'marker composition ' + type)
|
||||||
.attr('refX', 0)
|
.attr('refX', 18)
|
||||||
.attr('refY', 7)
|
.attr('refY', 7)
|
||||||
.attr('markerWidth', 190)
|
.attr('markerWidth', 190)
|
||||||
.attr('markerHeight', 240)
|
.attr('markerHeight', 240)
|
||||||
@ -147,7 +147,7 @@ const composition = (elem, type) => {
|
|||||||
.append('marker')
|
.append('marker')
|
||||||
.attr('id', type + '-compositionEnd')
|
.attr('id', type + '-compositionEnd')
|
||||||
.attr('class', 'marker composition ' + type)
|
.attr('class', 'marker composition ' + type)
|
||||||
.attr('refX', 19)
|
.attr('refX', 1)
|
||||||
.attr('refY', 7)
|
.attr('refY', 7)
|
||||||
.attr('markerWidth', 20)
|
.attr('markerWidth', 20)
|
||||||
.attr('markerHeight', 28)
|
.attr('markerHeight', 28)
|
||||||
@ -161,7 +161,7 @@ const aggregation = (elem, type) => {
|
|||||||
.append('marker')
|
.append('marker')
|
||||||
.attr('id', type + '-aggregationStart')
|
.attr('id', type + '-aggregationStart')
|
||||||
.attr('class', 'marker aggregation ' + type)
|
.attr('class', 'marker aggregation ' + type)
|
||||||
.attr('refX', 0)
|
.attr('refX', 18)
|
||||||
.attr('refY', 7)
|
.attr('refY', 7)
|
||||||
.attr('markerWidth', 190)
|
.attr('markerWidth', 190)
|
||||||
.attr('markerHeight', 240)
|
.attr('markerHeight', 240)
|
||||||
@ -174,7 +174,7 @@ const aggregation = (elem, type) => {
|
|||||||
.append('marker')
|
.append('marker')
|
||||||
.attr('id', type + '-aggregationEnd')
|
.attr('id', type + '-aggregationEnd')
|
||||||
.attr('class', 'marker aggregation ' + type)
|
.attr('class', 'marker aggregation ' + type)
|
||||||
.attr('refX', 19)
|
.attr('refX', 1)
|
||||||
.attr('refY', 7)
|
.attr('refY', 7)
|
||||||
.attr('markerWidth', 20)
|
.attr('markerWidth', 20)
|
||||||
.attr('markerHeight', 28)
|
.attr('markerHeight', 28)
|
||||||
@ -188,7 +188,7 @@ const dependency = (elem, type) => {
|
|||||||
.append('marker')
|
.append('marker')
|
||||||
.attr('id', type + '-dependencyStart')
|
.attr('id', type + '-dependencyStart')
|
||||||
.attr('class', 'marker dependency ' + type)
|
.attr('class', 'marker dependency ' + type)
|
||||||
.attr('refX', 0)
|
.attr('refX', 6)
|
||||||
.attr('refY', 7)
|
.attr('refY', 7)
|
||||||
.attr('markerWidth', 190)
|
.attr('markerWidth', 190)
|
||||||
.attr('markerHeight', 240)
|
.attr('markerHeight', 240)
|
||||||
@ -201,7 +201,7 @@ const dependency = (elem, type) => {
|
|||||||
.append('marker')
|
.append('marker')
|
||||||
.attr('id', type + '-dependencyEnd')
|
.attr('id', type + '-dependencyEnd')
|
||||||
.attr('class', 'marker dependency ' + type)
|
.attr('class', 'marker dependency ' + type)
|
||||||
.attr('refX', 19)
|
.attr('refX', 13)
|
||||||
.attr('refY', 7)
|
.attr('refY', 7)
|
||||||
.attr('markerWidth', 20)
|
.attr('markerWidth', 20)
|
||||||
.attr('markerHeight', 28)
|
.attr('markerHeight', 28)
|
||||||
@ -215,15 +215,32 @@ const lollipop = (elem, type) => {
|
|||||||
.append('marker')
|
.append('marker')
|
||||||
.attr('id', type + '-lollipopStart')
|
.attr('id', type + '-lollipopStart')
|
||||||
.attr('class', 'marker lollipop ' + type)
|
.attr('class', 'marker lollipop ' + type)
|
||||||
.attr('refX', 0)
|
.attr('refX', 13)
|
||||||
.attr('refY', 7)
|
.attr('refY', 7)
|
||||||
.attr('markerWidth', 190)
|
.attr('markerWidth', 190)
|
||||||
.attr('markerHeight', 240)
|
.attr('markerHeight', 240)
|
||||||
.attr('orient', 'auto')
|
.attr('orient', 'auto')
|
||||||
.append('circle')
|
.append('circle')
|
||||||
.attr('stroke', 'black')
|
.attr('stroke', 'black')
|
||||||
.attr('fill', 'white')
|
.attr('fill', 'transparent')
|
||||||
.attr('cx', 6)
|
.attr('cx', 7)
|
||||||
|
.attr('cy', 7)
|
||||||
|
.attr('r', 6);
|
||||||
|
|
||||||
|
elem
|
||||||
|
.append('defs')
|
||||||
|
.append('marker')
|
||||||
|
.attr('id', type + '-lollipopEnd')
|
||||||
|
.attr('class', 'marker lollipop ' + type)
|
||||||
|
.attr('refX', 1)
|
||||||
|
.attr('refY', 7)
|
||||||
|
.attr('markerWidth', 190)
|
||||||
|
.attr('markerHeight', 240)
|
||||||
|
.attr('orient', 'auto')
|
||||||
|
.append('circle')
|
||||||
|
.attr('stroke', 'black')
|
||||||
|
.attr('fill', 'transparent')
|
||||||
|
.attr('cx', 7)
|
||||||
.attr('cy', 7)
|
.attr('cy', 7)
|
||||||
.attr('r', 6);
|
.attr('r', 6);
|
||||||
};
|
};
|
||||||
@ -233,7 +250,7 @@ const point = (elem, type) => {
|
|||||||
.attr('id', type + '-pointEnd')
|
.attr('id', type + '-pointEnd')
|
||||||
.attr('class', 'marker ' + type)
|
.attr('class', 'marker ' + type)
|
||||||
.attr('viewBox', '0 0 10 10')
|
.attr('viewBox', '0 0 10 10')
|
||||||
.attr('refX', 10)
|
.attr('refX', 6)
|
||||||
.attr('refY', 5)
|
.attr('refY', 5)
|
||||||
.attr('markerUnits', 'userSpaceOnUse')
|
.attr('markerUnits', 'userSpaceOnUse')
|
||||||
.attr('markerWidth', 12)
|
.attr('markerWidth', 12)
|
||||||
|
@ -291,8 +291,8 @@ export const adjustClustersAndEdges = (graph, depth) => {
|
|||||||
shape: 'labelRect',
|
shape: 'labelRect',
|
||||||
style: '',
|
style: '',
|
||||||
});
|
});
|
||||||
const edge1 = JSON.parse(JSON.stringify(edge));
|
const edge1 = structuredClone(edge);
|
||||||
const edge2 = JSON.parse(JSON.stringify(edge));
|
const edge2 = structuredClone(edge);
|
||||||
edge1.label = '';
|
edge1.label = '';
|
||||||
edge1.arrowTypeEnd = 'none';
|
edge1.arrowTypeEnd = 'none';
|
||||||
edge2.label = '';
|
edge2.label = '';
|
||||||
|
@ -5,7 +5,6 @@ import { getConfig } from '../config.js';
|
|||||||
import intersect from './intersect/index.js';
|
import intersect from './intersect/index.js';
|
||||||
import createLabel from './createLabel.js';
|
import createLabel from './createLabel.js';
|
||||||
import note from './shapes/note.js';
|
import note from './shapes/note.js';
|
||||||
import { parseMember } from '../diagrams/class/svgDraw.js';
|
|
||||||
import { evaluate } from '../diagrams/common/common.js';
|
import { evaluate } from '../diagrams/common/common.js';
|
||||||
|
|
||||||
const formatClass = (str) => {
|
const formatClass = (str) => {
|
||||||
@ -880,8 +879,8 @@ const class_box = (parent, node) => {
|
|||||||
maxWidth = classTitleBBox.width;
|
maxWidth = classTitleBBox.width;
|
||||||
}
|
}
|
||||||
const classAttributes = [];
|
const classAttributes = [];
|
||||||
node.classData.members.forEach((str) => {
|
node.classData.members.forEach((member) => {
|
||||||
const parsedInfo = parseMember(str);
|
const parsedInfo = member.getDisplayDetails();
|
||||||
let parsedText = parsedInfo.displayText;
|
let parsedText = parsedInfo.displayText;
|
||||||
if (getConfig().flowchart.htmlLabels) {
|
if (getConfig().flowchart.htmlLabels) {
|
||||||
parsedText = parsedText.replace(/</g, '<').replace(/>/g, '>');
|
parsedText = parsedText.replace(/</g, '<').replace(/>/g, '>');
|
||||||
@ -914,8 +913,8 @@ const class_box = (parent, node) => {
|
|||||||
maxHeight += lineHeight;
|
maxHeight += lineHeight;
|
||||||
|
|
||||||
const classMethods = [];
|
const classMethods = [];
|
||||||
node.classData.methods.forEach((str) => {
|
node.classData.methods.forEach((member) => {
|
||||||
const parsedInfo = parseMember(str);
|
const parsedInfo = member.getDisplayDetails();
|
||||||
let displayText = parsedInfo.displayText;
|
let displayText = parsedInfo.displayText;
|
||||||
if (getConfig().flowchart.htmlLabels) {
|
if (getConfig().flowchart.htmlLabels) {
|
||||||
displayText = displayText.replace(/</g, '<').replace(/>/g, '>');
|
displayText = displayText.replace(/</g, '<').replace(/>/g, '>');
|
||||||
|
@ -5,7 +5,7 @@ import { sanitizeText as _sanitizeText } from '../diagrams/common/common.js';
|
|||||||
import { setupGraphViewbox as _setupGraphViewbox } from '../setupGraphViewbox.js';
|
import { setupGraphViewbox as _setupGraphViewbox } from '../setupGraphViewbox.js';
|
||||||
import { addStylesForDiagram } from '../styles.js';
|
import { addStylesForDiagram } from '../styles.js';
|
||||||
import type { DiagramDefinition, DiagramDetector } from './types.js';
|
import type { DiagramDefinition, DiagramDetector } from './types.js';
|
||||||
import * as _commonDb from '../commonDb.js';
|
import * as _commonDb from '../diagrams/common/commonDb.js';
|
||||||
import { parseDirective as _parseDirective } from '../directiveUtils.js';
|
import { parseDirective as _parseDirective } from '../directiveUtils.js';
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -1,7 +1,12 @@
|
|||||||
import mermaidAPI from '../../mermaidAPI.js';
|
import mermaidAPI from '../../mermaidAPI.js';
|
||||||
import * as configApi from '../../config.js';
|
import * as configApi from '../../config.js';
|
||||||
import { sanitizeText } from '../common/common.js';
|
import { sanitizeText } from '../common/common.js';
|
||||||
import { setAccTitle, getAccTitle, getAccDescription, setAccDescription } from '../../commonDb.js';
|
import {
|
||||||
|
setAccTitle,
|
||||||
|
getAccTitle,
|
||||||
|
getAccDescription,
|
||||||
|
setAccDescription,
|
||||||
|
} from '../common/commonDb.js';
|
||||||
|
|
||||||
let c4ShapeArray = [];
|
let c4ShapeArray = [];
|
||||||
let boundaryParseStack = [''];
|
let boundaryParseStack = [''];
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
// @ts-nocheck - don't check until handle it
|
|
||||||
import type { Selection } from 'd3';
|
import type { Selection } from 'd3';
|
||||||
import { select } from 'd3';
|
import { select } from 'd3';
|
||||||
import { log } from '../../logger.js';
|
import { log } from '../../logger.js';
|
||||||
@ -14,7 +13,8 @@ import {
|
|||||||
clear as commonClear,
|
clear as commonClear,
|
||||||
setDiagramTitle,
|
setDiagramTitle,
|
||||||
getDiagramTitle,
|
getDiagramTitle,
|
||||||
} from '../../commonDb.js';
|
} from '../common/commonDb.js';
|
||||||
|
import { ClassMember } from './classTypes.js';
|
||||||
import type {
|
import type {
|
||||||
ClassRelation,
|
ClassRelation,
|
||||||
ClassNode,
|
ClassNode,
|
||||||
@ -71,21 +71,21 @@ export const setClassLabel = function (id: string, label: string) {
|
|||||||
* @public
|
* @public
|
||||||
*/
|
*/
|
||||||
export const addClass = function (id: string) {
|
export const addClass = function (id: string) {
|
||||||
const classId = splitClassNameAndType(id);
|
const { className, type } = splitClassNameAndType(id);
|
||||||
// Only add class if not exists
|
// Only add class if not exists
|
||||||
if (classes[classId.className] !== undefined) {
|
if (Object.hasOwn(classes, className)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
classes[classId.className] = {
|
classes[className] = {
|
||||||
id: classId.className,
|
id: className,
|
||||||
type: classId.type,
|
type: type,
|
||||||
label: classId.className,
|
label: className,
|
||||||
cssClasses: [],
|
cssClasses: [],
|
||||||
methods: [],
|
methods: [],
|
||||||
members: [],
|
members: [],
|
||||||
annotations: [],
|
annotations: [],
|
||||||
domId: MERMAID_DOM_ID_PREFIX + classId.className + '-' + classCounter,
|
domId: MERMAID_DOM_ID_PREFIX + className + '-' + classCounter,
|
||||||
} as ClassNode;
|
} as ClassNode;
|
||||||
|
|
||||||
classCounter++;
|
classCounter++;
|
||||||
@ -115,11 +115,11 @@ export const clear = function () {
|
|||||||
commonClear();
|
commonClear();
|
||||||
};
|
};
|
||||||
|
|
||||||
export const getClass = function (id: string) {
|
export const getClass = function (id: string): ClassNode {
|
||||||
return classes[id];
|
return classes[id];
|
||||||
};
|
};
|
||||||
|
|
||||||
export const getClasses = function () {
|
export const getClasses = function (): ClassMap {
|
||||||
return classes;
|
return classes;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -175,6 +175,8 @@ export const addAnnotation = function (className: string, annotation: string) {
|
|||||||
* @public
|
* @public
|
||||||
*/
|
*/
|
||||||
export const addMember = function (className: string, member: string) {
|
export const addMember = function (className: string, member: string) {
|
||||||
|
addClass(className);
|
||||||
|
|
||||||
const validatedClassName = splitClassNameAndType(className).className;
|
const validatedClassName = splitClassNameAndType(className).className;
|
||||||
const theClass = classes[validatedClassName];
|
const theClass = classes[validatedClassName];
|
||||||
|
|
||||||
@ -187,9 +189,9 @@ export const addMember = function (className: string, member: string) {
|
|||||||
theClass.annotations.push(sanitizeText(memberString.substring(2, memberString.length - 2)));
|
theClass.annotations.push(sanitizeText(memberString.substring(2, memberString.length - 2)));
|
||||||
} else if (memberString.indexOf(')') > 0) {
|
} else if (memberString.indexOf(')') > 0) {
|
||||||
//its a method
|
//its a method
|
||||||
theClass.methods.push(sanitizeText(memberString));
|
theClass.methods.push(new ClassMember(memberString, 'method'));
|
||||||
} else if (memberString) {
|
} else if (memberString) {
|
||||||
theClass.members.push(sanitizeText(memberString));
|
theClass.members.push(new ClassMember(memberString, 'attribute'));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -256,6 +258,7 @@ export const getTooltip = function (id: string, namespace?: string) {
|
|||||||
|
|
||||||
return classes[id].tooltip;
|
return classes[id].tooltip;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called by parser when a link is found. Adds the URL to the vertex data.
|
* Called by parser when a link is found. Adds the URL to the vertex data.
|
||||||
*
|
*
|
||||||
@ -369,6 +372,7 @@ export const relationType = {
|
|||||||
const setupToolTips = function (element: Element) {
|
const setupToolTips = function (element: Element) {
|
||||||
let tooltipElem: Selection<HTMLDivElement, unknown, HTMLElement, unknown> =
|
let tooltipElem: Selection<HTMLDivElement, unknown, HTMLElement, unknown> =
|
||||||
select('.mermaidTooltip');
|
select('.mermaidTooltip');
|
||||||
|
// @ts-expect-error - Incorrect types
|
||||||
if ((tooltipElem._groups || tooltipElem)[0][0] === null) {
|
if ((tooltipElem._groups || tooltipElem)[0][0] === null) {
|
||||||
tooltipElem = select('body').append('div').attr('class', 'mermaidTooltip').style('opacity', 0);
|
tooltipElem = select('body').append('div').attr('class', 'mermaidTooltip').style('opacity', 0);
|
||||||
}
|
}
|
||||||
@ -378,7 +382,6 @@ const setupToolTips = function (element: Element) {
|
|||||||
const nodes = svg.selectAll('g.node');
|
const nodes = svg.selectAll('g.node');
|
||||||
nodes
|
nodes
|
||||||
.on('mouseover', function () {
|
.on('mouseover', function () {
|
||||||
// @ts-expect-error - select is not part of the d3 type definition
|
|
||||||
const el = select(this);
|
const el = select(this);
|
||||||
const title = el.attr('title');
|
const title = el.attr('title');
|
||||||
// Don't try to draw a tooltip if no data is provided
|
// Don't try to draw a tooltip if no data is provided
|
||||||
@ -388,6 +391,7 @@ const setupToolTips = function (element: Element) {
|
|||||||
// @ts-ignore - getBoundingClientRect is not part of the d3 type definition
|
// @ts-ignore - getBoundingClientRect is not part of the d3 type definition
|
||||||
const rect = this.getBoundingClientRect();
|
const rect = this.getBoundingClientRect();
|
||||||
|
|
||||||
|
// @ts-expect-error - Incorrect types
|
||||||
tooltipElem.transition().duration(200).style('opacity', '.9');
|
tooltipElem.transition().duration(200).style('opacity', '.9');
|
||||||
tooltipElem
|
tooltipElem
|
||||||
.text(el.attr('title'))
|
.text(el.attr('title'))
|
||||||
@ -397,8 +401,8 @@ const setupToolTips = function (element: Element) {
|
|||||||
el.classed('hover', true);
|
el.classed('hover', true);
|
||||||
})
|
})
|
||||||
.on('mouseout', function () {
|
.on('mouseout', function () {
|
||||||
|
// @ts-expect-error - Incorrect types
|
||||||
tooltipElem.transition().duration(500).style('opacity', 0);
|
tooltipElem.transition().duration(500).style('opacity', 0);
|
||||||
// @ts-expect-error - select is not part of the d3 type definition
|
|
||||||
const el = select(this);
|
const el = select(this);
|
||||||
el.classed('hover', false);
|
el.classed('hover', false);
|
||||||
});
|
});
|
||||||
|
@ -4,6 +4,9 @@ import classDb from './classDb.js';
|
|||||||
import { vi, describe, it, expect } from 'vitest';
|
import { vi, describe, it, expect } from 'vitest';
|
||||||
const spyOn = vi.spyOn;
|
const spyOn = vi.spyOn;
|
||||||
|
|
||||||
|
const staticCssStyle = 'text-decoration:underline;';
|
||||||
|
const abstractCssStyle = 'font-style:italic;';
|
||||||
|
|
||||||
describe('given a basic class diagram, ', function () {
|
describe('given a basic class diagram, ', function () {
|
||||||
describe('when parsing class definition', function () {
|
describe('when parsing class definition', function () {
|
||||||
beforeEach(function () {
|
beforeEach(function () {
|
||||||
@ -127,7 +130,7 @@ describe('given a basic class diagram, ', function () {
|
|||||||
const c1 = classDb.getClass('C1');
|
const c1 = classDb.getClass('C1');
|
||||||
expect(c1.label).toBe('Class 1 with text label');
|
expect(c1.label).toBe('Class 1 with text label');
|
||||||
expect(c1.members.length).toBe(1);
|
expect(c1.members.length).toBe(1);
|
||||||
expect(c1.members[0]).toBe('member1');
|
expect(c1.members[0].getDisplayDetails().displayText).toBe('member1');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should parse a class with a text label, member and annotation', () => {
|
it('should parse a class with a text label, member and annotation', () => {
|
||||||
@ -142,7 +145,7 @@ describe('given a basic class diagram, ', function () {
|
|||||||
const c1 = classDb.getClass('C1');
|
const c1 = classDb.getClass('C1');
|
||||||
expect(c1.label).toBe('Class 1 with text label');
|
expect(c1.label).toBe('Class 1 with text label');
|
||||||
expect(c1.members.length).toBe(1);
|
expect(c1.members.length).toBe(1);
|
||||||
expect(c1.members[0]).toBe('int member1');
|
expect(c1.members[0].getDisplayDetails().displayText).toBe('int member1');
|
||||||
expect(c1.annotations.length).toBe(1);
|
expect(c1.annotations.length).toBe(1);
|
||||||
expect(c1.annotations[0]).toBe('interface');
|
expect(c1.annotations[0]).toBe('interface');
|
||||||
});
|
});
|
||||||
@ -168,7 +171,7 @@ describe('given a basic class diagram, ', function () {
|
|||||||
|
|
||||||
const c1 = classDb.getClass('C1');
|
const c1 = classDb.getClass('C1');
|
||||||
expect(c1.label).toBe('Class 1 with text label');
|
expect(c1.label).toBe('Class 1 with text label');
|
||||||
expect(c1.members[0]).toBe('int member1');
|
expect(c1.members[0].getDisplayDetails().displayText).toBe('int member1');
|
||||||
expect(c1.cssClasses[0]).toBe('styleClass');
|
expect(c1.cssClasses[0]).toBe('styleClass');
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -371,6 +374,74 @@ class C13["With Città foreign language"]
|
|||||||
note ${keyword}`;
|
note ${keyword}`;
|
||||||
expect(() => parser.parse(str)).toThrowError(/(Expecting\s'STR'|Unrecognized\stext)/);
|
expect(() => parser.parse(str)).toThrowError(/(Expecting\s'STR'|Unrecognized\stext)/);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should parse diagram with direction', () => {
|
||||||
|
parser.parse(`classDiagram
|
||||||
|
direction TB
|
||||||
|
class Student {
|
||||||
|
-idCard : IdCard
|
||||||
|
}
|
||||||
|
class IdCard{
|
||||||
|
-id : int
|
||||||
|
-name : string
|
||||||
|
}
|
||||||
|
class Bike{
|
||||||
|
-id : int
|
||||||
|
-name : string
|
||||||
|
}
|
||||||
|
Student "1" --o "1" IdCard : carries
|
||||||
|
Student "1" --o "1" Bike : rides`);
|
||||||
|
|
||||||
|
expect(Object.keys(classDb.getClasses()).length).toBe(3);
|
||||||
|
expect(classDb.getClasses().Student).toMatchInlineSnapshot(`
|
||||||
|
{
|
||||||
|
"annotations": [],
|
||||||
|
"cssClasses": [],
|
||||||
|
"domId": "classId-Student-134",
|
||||||
|
"id": "Student",
|
||||||
|
"label": "Student",
|
||||||
|
"members": [
|
||||||
|
ClassMember {
|
||||||
|
"classifier": "",
|
||||||
|
"id": "idCard : IdCard",
|
||||||
|
"memberType": "attribute",
|
||||||
|
"visibility": "-",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
"methods": [],
|
||||||
|
"type": "",
|
||||||
|
}
|
||||||
|
`);
|
||||||
|
expect(classDb.getRelations().length).toBe(2);
|
||||||
|
expect(classDb.getRelations()).toMatchInlineSnapshot(`
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"id1": "Student",
|
||||||
|
"id2": "IdCard",
|
||||||
|
"relation": {
|
||||||
|
"lineType": 0,
|
||||||
|
"type1": "none",
|
||||||
|
"type2": 0,
|
||||||
|
},
|
||||||
|
"relationTitle1": "1",
|
||||||
|
"relationTitle2": "1",
|
||||||
|
"title": "carries",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id1": "Student",
|
||||||
|
"id2": "Bike",
|
||||||
|
"relation": {
|
||||||
|
"lineType": 0,
|
||||||
|
"type1": "none",
|
||||||
|
"type2": 0,
|
||||||
|
},
|
||||||
|
"relationTitle1": "1",
|
||||||
|
"relationTitle2": "1",
|
||||||
|
"title": "rides",
|
||||||
|
},
|
||||||
|
]
|
||||||
|
`);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('when parsing class defined in brackets', function () {
|
describe('when parsing class defined in brackets', function () {
|
||||||
@ -422,8 +493,8 @@ class C13["With Città foreign language"]
|
|||||||
'classDiagram\n' +
|
'classDiagram\n' +
|
||||||
'class Class1 {\n' +
|
'class Class1 {\n' +
|
||||||
'int testMember\n' +
|
'int testMember\n' +
|
||||||
'string fooMember\n' +
|
|
||||||
'test()\n' +
|
'test()\n' +
|
||||||
|
'string fooMember\n' +
|
||||||
'foo()\n' +
|
'foo()\n' +
|
||||||
'}';
|
'}';
|
||||||
parser.parse(str);
|
parser.parse(str);
|
||||||
@ -431,10 +502,10 @@ class C13["With Città foreign language"]
|
|||||||
const actual = parser.yy.getClass('Class1');
|
const actual = parser.yy.getClass('Class1');
|
||||||
expect(actual.members.length).toBe(2);
|
expect(actual.members.length).toBe(2);
|
||||||
expect(actual.methods.length).toBe(2);
|
expect(actual.methods.length).toBe(2);
|
||||||
expect(actual.members[0]).toBe('int testMember');
|
expect(actual.members[0].getDisplayDetails().displayText).toBe('int testMember');
|
||||||
expect(actual.members[1]).toBe('string fooMember');
|
expect(actual.members[1].getDisplayDetails().displayText).toBe('string fooMember');
|
||||||
expect(actual.methods[0]).toBe('test()');
|
expect(actual.methods[0].getDisplayDetails().displayText).toBe('test()');
|
||||||
expect(actual.methods[1]).toBe('foo()');
|
expect(actual.methods[1].getDisplayDetails().displayText).toBe('foo()');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should parse a class with a text label and members', () => {
|
it('should parse a class with a text label and members', () => {
|
||||||
@ -444,7 +515,7 @@ class C13["With Città foreign language"]
|
|||||||
const c1 = classDb.getClass('C1');
|
const c1 = classDb.getClass('C1');
|
||||||
expect(c1.label).toBe('Class 1 with text label');
|
expect(c1.label).toBe('Class 1 with text label');
|
||||||
expect(c1.members.length).toBe(1);
|
expect(c1.members.length).toBe(1);
|
||||||
expect(c1.members[0]).toBe('+member1');
|
expect(c1.members[0].getDisplayDetails().displayText).toBe('+member1');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should parse a class with a text label, members and annotation', () => {
|
it('should parse a class with a text label, members and annotation', () => {
|
||||||
@ -459,7 +530,7 @@ class C13["With Città foreign language"]
|
|||||||
const c1 = classDb.getClass('C1');
|
const c1 = classDb.getClass('C1');
|
||||||
expect(c1.label).toBe('Class 1 with text label');
|
expect(c1.label).toBe('Class 1 with text label');
|
||||||
expect(c1.members.length).toBe(1);
|
expect(c1.members.length).toBe(1);
|
||||||
expect(c1.members[0]).toBe('+member1');
|
expect(c1.members[0].getDisplayDetails().displayText).toBe('+member1');
|
||||||
expect(c1.annotations.length).toBe(1);
|
expect(c1.annotations.length).toBe(1);
|
||||||
expect(c1.annotations[0]).toBe('interface');
|
expect(c1.annotations[0]).toBe('interface');
|
||||||
});
|
});
|
||||||
@ -742,6 +813,20 @@ describe('given a class diagram with members and methods ', function () {
|
|||||||
parser.parse(str);
|
parser.parse(str);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should handle direct member declaration', function () {
|
||||||
|
parser.parse('classDiagram\n' + 'Car : wheels');
|
||||||
|
const car = classDb.getClass('Car');
|
||||||
|
expect(car.members.length).toBe(1);
|
||||||
|
expect(car.members[0].id).toBe('wheels');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should handle direct member declaration with type', function () {
|
||||||
|
parser.parse('classDiagram\n' + 'Car : int wheels');
|
||||||
|
const car = classDb.getClass('Car');
|
||||||
|
expect(car.members.length).toBe(1);
|
||||||
|
expect(car.members[0].id).toBe('int wheels');
|
||||||
|
});
|
||||||
|
|
||||||
it('should handle simple member declaration with type', function () {
|
it('should handle simple member declaration with type', function () {
|
||||||
const str = 'classDiagram\n' + 'class Car\n' + 'Car : int wheels';
|
const str = 'classDiagram\n' + 'class Car\n' + 'Car : int wheels';
|
||||||
|
|
||||||
@ -762,10 +847,10 @@ describe('given a class diagram with members and methods ', function () {
|
|||||||
const actual = parser.yy.getClass('actual');
|
const actual = parser.yy.getClass('actual');
|
||||||
expect(actual.members.length).toBe(4);
|
expect(actual.members.length).toBe(4);
|
||||||
expect(actual.methods.length).toBe(0);
|
expect(actual.methods.length).toBe(0);
|
||||||
expect(actual.members[0]).toBe('-int privateMember');
|
expect(actual.members[0].getDisplayDetails().displayText).toBe('-int privateMember');
|
||||||
expect(actual.members[1]).toBe('+int publicMember');
|
expect(actual.members[1].getDisplayDetails().displayText).toBe('+int publicMember');
|
||||||
expect(actual.members[2]).toBe('#int protectedMember');
|
expect(actual.members[2].getDisplayDetails().displayText).toBe('#int protectedMember');
|
||||||
expect(actual.members[3]).toBe('~int privatePackage');
|
expect(actual.members[3].getDisplayDetails().displayText).toBe('~int privatePackage');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should handle generic types', function () {
|
it('should handle generic types', function () {
|
||||||
@ -818,7 +903,9 @@ describe('given a class diagram with members and methods ', function () {
|
|||||||
expect(actual.annotations.length).toBe(0);
|
expect(actual.annotations.length).toBe(0);
|
||||||
expect(actual.members.length).toBe(0);
|
expect(actual.members.length).toBe(0);
|
||||||
expect(actual.methods.length).toBe(1);
|
expect(actual.methods.length).toBe(1);
|
||||||
expect(actual.methods[0]).toBe('someMethod()*');
|
const method = actual.methods[0];
|
||||||
|
expect(method.getDisplayDetails().displayText).toBe('someMethod()');
|
||||||
|
expect(method.getDisplayDetails().cssStyle).toBe(abstractCssStyle);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should handle static methods', function () {
|
it('should handle static methods', function () {
|
||||||
@ -829,7 +916,9 @@ describe('given a class diagram with members and methods ', function () {
|
|||||||
expect(actual.annotations.length).toBe(0);
|
expect(actual.annotations.length).toBe(0);
|
||||||
expect(actual.members.length).toBe(0);
|
expect(actual.members.length).toBe(0);
|
||||||
expect(actual.methods.length).toBe(1);
|
expect(actual.methods.length).toBe(1);
|
||||||
expect(actual.methods[0]).toBe('someMethod()$');
|
const method = actual.methods[0];
|
||||||
|
expect(method.getDisplayDetails().displayText).toBe('someMethod()');
|
||||||
|
expect(method.getDisplayDetails().cssStyle).toBe(staticCssStyle);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should handle generic types in arguments', function () {
|
it('should handle generic types in arguments', function () {
|
||||||
@ -955,53 +1044,6 @@ foo()
|
|||||||
parser.parse(str);
|
parser.parse(str);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('when parsing invalid generic classes', function () {
|
|
||||||
beforeEach(function () {
|
|
||||||
classDb.clear();
|
|
||||||
parser.yy = classDb;
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should break when another `{`is encountered before closing the first one while defining generic class with brackets', function () {
|
|
||||||
const str =
|
|
||||||
'classDiagram\n' +
|
|
||||||
'class Dummy_Class~T~ {\n' +
|
|
||||||
'String data\n' +
|
|
||||||
' void methods()\n' +
|
|
||||||
'}\n' +
|
|
||||||
'\n' +
|
|
||||||
'class Dummy_Class {\n' +
|
|
||||||
'class Flight {\n' +
|
|
||||||
' flightNumber : Integer\n' +
|
|
||||||
' departureTime : Date\n' +
|
|
||||||
'}';
|
|
||||||
let testPassed = false;
|
|
||||||
try {
|
|
||||||
parser.parse(str);
|
|
||||||
} catch (error) {
|
|
||||||
testPassed = true;
|
|
||||||
}
|
|
||||||
expect(testPassed).toBe(true);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should break when EOF is encountered before closing the first `{` while defining generic class with brackets', function () {
|
|
||||||
const str =
|
|
||||||
'classDiagram\n' +
|
|
||||||
'class Dummy_Class~T~ {\n' +
|
|
||||||
'String data\n' +
|
|
||||||
' void methods()\n' +
|
|
||||||
'}\n' +
|
|
||||||
'\n' +
|
|
||||||
'class Dummy_Class {\n';
|
|
||||||
let testPassed = false;
|
|
||||||
try {
|
|
||||||
parser.parse(str);
|
|
||||||
} catch (error) {
|
|
||||||
testPassed = true;
|
|
||||||
}
|
|
||||||
expect(testPassed).toBe(true);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('given a class diagram with relationships, ', function () {
|
describe('given a class diagram with relationships, ', function () {
|
||||||
@ -1276,10 +1318,10 @@ describe('given a class diagram with relationships, ', function () {
|
|||||||
const testClass = parser.yy.getClass('Class1');
|
const testClass = parser.yy.getClass('Class1');
|
||||||
expect(testClass.members.length).toBe(2);
|
expect(testClass.members.length).toBe(2);
|
||||||
expect(testClass.methods.length).toBe(2);
|
expect(testClass.methods.length).toBe(2);
|
||||||
expect(testClass.members[0]).toBe('int : test');
|
expect(testClass.members[0].getDisplayDetails().displayText).toBe('int : test');
|
||||||
expect(testClass.members[1]).toBe('string : foo');
|
expect(testClass.members[1].getDisplayDetails().displayText).toBe('string : foo');
|
||||||
expect(testClass.methods[0]).toBe('test()');
|
expect(testClass.methods[0].getDisplayDetails().displayText).toBe('test()');
|
||||||
expect(testClass.methods[1]).toBe('foo()');
|
expect(testClass.methods[1].getDisplayDetails().displayText).toBe('foo()');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should handle abstract methods', function () {
|
it('should handle abstract methods', function () {
|
||||||
@ -1290,7 +1332,9 @@ describe('given a class diagram with relationships, ', function () {
|
|||||||
expect(testClass.annotations.length).toBe(0);
|
expect(testClass.annotations.length).toBe(0);
|
||||||
expect(testClass.members.length).toBe(0);
|
expect(testClass.members.length).toBe(0);
|
||||||
expect(testClass.methods.length).toBe(1);
|
expect(testClass.methods.length).toBe(1);
|
||||||
expect(testClass.methods[0]).toBe('someMethod()*');
|
const method = testClass.methods[0];
|
||||||
|
expect(method.getDisplayDetails().displayText).toBe('someMethod()');
|
||||||
|
expect(method.getDisplayDetails().cssStyle).toBe(abstractCssStyle);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should handle static methods', function () {
|
it('should handle static methods', function () {
|
||||||
@ -1301,7 +1345,9 @@ describe('given a class diagram with relationships, ', function () {
|
|||||||
expect(testClass.annotations.length).toBe(0);
|
expect(testClass.annotations.length).toBe(0);
|
||||||
expect(testClass.members.length).toBe(0);
|
expect(testClass.members.length).toBe(0);
|
||||||
expect(testClass.methods.length).toBe(1);
|
expect(testClass.methods.length).toBe(1);
|
||||||
expect(testClass.methods[0]).toBe('someMethod()$');
|
const method = testClass.methods[0];
|
||||||
|
expect(method.getDisplayDetails().displayText).toBe('someMethod()');
|
||||||
|
expect(method.getDisplayDetails().cssStyle).toBe(staticCssStyle);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should associate link and css appropriately', function () {
|
it('should associate link and css appropriately', function () {
|
||||||
@ -1516,11 +1562,19 @@ class Class2
|
|||||||
const testClasses = parser.yy.getClasses();
|
const testClasses = parser.yy.getClasses();
|
||||||
const testRelations = parser.yy.getRelations();
|
const testRelations = parser.yy.getRelations();
|
||||||
expect(Object.keys(testNamespaceA.classes).length).toBe(2);
|
expect(Object.keys(testNamespaceA.classes).length).toBe(2);
|
||||||
expect(testNamespaceA.classes['A1'].members[0]).toBe('+foo : string');
|
expect(testNamespaceA.classes['A1'].members[0].getDisplayDetails().displayText).toBe(
|
||||||
expect(testNamespaceA.classes['A2'].members[0]).toBe('+bar : int');
|
'+foo : string'
|
||||||
|
);
|
||||||
|
expect(testNamespaceA.classes['A2'].members[0].getDisplayDetails().displayText).toBe(
|
||||||
|
'+bar : int'
|
||||||
|
);
|
||||||
expect(Object.keys(testNamespaceB.classes).length).toBe(2);
|
expect(Object.keys(testNamespaceB.classes).length).toBe(2);
|
||||||
expect(testNamespaceB.classes['B1'].members[0]).toBe('+foo : bool');
|
expect(testNamespaceB.classes['B1'].members[0].getDisplayDetails().displayText).toBe(
|
||||||
expect(testNamespaceB.classes['B2'].members[0]).toBe('+bar : float');
|
'+foo : bool'
|
||||||
|
);
|
||||||
|
expect(testNamespaceB.classes['B2'].members[0].getDisplayDetails().displayText).toBe(
|
||||||
|
'+bar : float'
|
||||||
|
);
|
||||||
expect(Object.keys(testClasses).length).toBe(4);
|
expect(Object.keys(testClasses).length).toBe(4);
|
||||||
expect(testClasses['A1'].parent).toBe('A');
|
expect(testClasses['A1'].parent).toBe('A');
|
||||||
expect(testClasses['A2'].parent).toBe('A');
|
expect(testClasses['A2'].parent).toBe('A');
|
||||||
@ -1572,8 +1626,8 @@ class Class2
|
|||||||
const c1 = classDb.getClass('C1');
|
const c1 = classDb.getClass('C1');
|
||||||
expect(c1.label).toBe('Class 1 with text label');
|
expect(c1.label).toBe('Class 1 with text label');
|
||||||
expect(c1.members.length).toBe(1);
|
expect(c1.members.length).toBe(1);
|
||||||
expect(c1.members[0]).toBe('+member1');
|
const member = c1.members[0];
|
||||||
|
expect(member.getDisplayDetails().displayText).toBe('+member1');
|
||||||
const c2 = classDb.getClass('C2');
|
const c2 = classDb.getClass('C2');
|
||||||
expect(c2.label).toBe('C2');
|
expect(c2.label).toBe('C2');
|
||||||
});
|
});
|
||||||
@ -1589,9 +1643,10 @@ class Class2
|
|||||||
const c1 = classDb.getClass('C1');
|
const c1 = classDb.getClass('C1');
|
||||||
expect(c1.label).toBe('Class 1 with text label');
|
expect(c1.label).toBe('Class 1 with text label');
|
||||||
expect(c1.members.length).toBe(1);
|
expect(c1.members.length).toBe(1);
|
||||||
expect(c1.members[0]).toBe('+member1');
|
|
||||||
expect(c1.annotations.length).toBe(1);
|
expect(c1.annotations.length).toBe(1);
|
||||||
expect(c1.annotations[0]).toBe('interface');
|
expect(c1.annotations[0]).toBe('interface');
|
||||||
|
const member = c1.members[0];
|
||||||
|
expect(member.getDisplayDetails().displayText).toBe('+member1');
|
||||||
|
|
||||||
const c2 = classDb.getClass('C2');
|
const c2 = classDb.getClass('C2');
|
||||||
expect(c2.label).toBe('C2');
|
expect(c2.label).toBe('C2');
|
||||||
@ -1608,8 +1663,9 @@ C1 --> C2
|
|||||||
const c1 = classDb.getClass('C1');
|
const c1 = classDb.getClass('C1');
|
||||||
expect(c1.label).toBe('Class 1 with text label');
|
expect(c1.label).toBe('Class 1 with text label');
|
||||||
expect(c1.cssClasses.length).toBe(1);
|
expect(c1.cssClasses.length).toBe(1);
|
||||||
expect(c1.members[0]).toBe('+member1');
|
|
||||||
expect(c1.cssClasses[0]).toBe('styleClass');
|
expect(c1.cssClasses[0]).toBe('styleClass');
|
||||||
|
const member = c1.members[0];
|
||||||
|
expect(member.getDisplayDetails().displayText).toBe('+member1');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should parse a class with text label and css class', () => {
|
it('should parse a class with text label and css class', () => {
|
||||||
@ -1624,8 +1680,9 @@ cssClass "C1" styleClass
|
|||||||
const c1 = classDb.getClass('C1');
|
const c1 = classDb.getClass('C1');
|
||||||
expect(c1.label).toBe('Class 1 with text label');
|
expect(c1.label).toBe('Class 1 with text label');
|
||||||
expect(c1.cssClasses.length).toBe(1);
|
expect(c1.cssClasses.length).toBe(1);
|
||||||
expect(c1.members[0]).toBe('+member1');
|
|
||||||
expect(c1.cssClasses[0]).toBe('styleClass');
|
expect(c1.cssClasses[0]).toBe('styleClass');
|
||||||
|
const member = c1.members[0];
|
||||||
|
expect(member.getDisplayDetails().displayText).toBe('+member1');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should parse two classes with text labels and css classes', () => {
|
it('should parse two classes with text labels and css classes', () => {
|
||||||
|
@ -1,78 +0,0 @@
|
|||||||
import { setConfig } from '../../config.js';
|
|
||||||
import classDB from './classDb.js';
|
|
||||||
// @ts-ignore - no types in jison
|
|
||||||
import classDiagram from './parser/classDiagram.jison';
|
|
||||||
|
|
||||||
setConfig({
|
|
||||||
securityLevel: 'strict',
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('when parsing class diagram', function () {
|
|
||||||
beforeEach(function () {
|
|
||||||
classDiagram.parser.yy = classDB;
|
|
||||||
classDiagram.parser.yy.clear();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should parse diagram with direction', () => {
|
|
||||||
classDiagram.parser.parse(`classDiagram
|
|
||||||
direction TB
|
|
||||||
class Student {
|
|
||||||
-idCard : IdCard
|
|
||||||
}
|
|
||||||
class IdCard{
|
|
||||||
-id : int
|
|
||||||
-name : string
|
|
||||||
}
|
|
||||||
class Bike{
|
|
||||||
-id : int
|
|
||||||
-name : string
|
|
||||||
}
|
|
||||||
Student "1" --o "1" IdCard : carries
|
|
||||||
Student "1" --o "1" Bike : rides`);
|
|
||||||
|
|
||||||
expect(Object.keys(classDB.getClasses()).length).toBe(3);
|
|
||||||
expect(classDB.getClasses().Student).toMatchInlineSnapshot(`
|
|
||||||
{
|
|
||||||
"annotations": [],
|
|
||||||
"cssClasses": [],
|
|
||||||
"domId": "classId-Student-0",
|
|
||||||
"id": "Student",
|
|
||||||
"label": "Student",
|
|
||||||
"members": [
|
|
||||||
"-idCard : IdCard",
|
|
||||||
],
|
|
||||||
"methods": [],
|
|
||||||
"type": "",
|
|
||||||
}
|
|
||||||
`);
|
|
||||||
expect(classDB.getRelations().length).toBe(2);
|
|
||||||
expect(classDB.getRelations()).toMatchInlineSnapshot(`
|
|
||||||
[
|
|
||||||
{
|
|
||||||
"id1": "Student",
|
|
||||||
"id2": "IdCard",
|
|
||||||
"relation": {
|
|
||||||
"lineType": 0,
|
|
||||||
"type1": "none",
|
|
||||||
"type2": 0,
|
|
||||||
},
|
|
||||||
"relationTitle1": "1",
|
|
||||||
"relationTitle2": "1",
|
|
||||||
"title": "carries",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id1": "Student",
|
|
||||||
"id2": "Bike",
|
|
||||||
"relation": {
|
|
||||||
"lineType": 0,
|
|
||||||
"type1": "none",
|
|
||||||
"type2": 0,
|
|
||||||
},
|
|
||||||
"relationTitle1": "1",
|
|
||||||
"relationTitle2": "1",
|
|
||||||
"title": "rides",
|
|
||||||
},
|
|
||||||
]
|
|
||||||
`);
|
|
||||||
});
|
|
||||||
});
|
|
@ -156,24 +156,17 @@ export const addNotes = function (
|
|||||||
) {
|
) {
|
||||||
log.info(notes);
|
log.info(notes);
|
||||||
|
|
||||||
// Iterate through each item in the vertex object (containing all the vertices found) in the graph definition
|
|
||||||
notes.forEach(function (note, i) {
|
notes.forEach(function (note, i) {
|
||||||
const vertex = note;
|
const vertex = note;
|
||||||
|
|
||||||
/**
|
|
||||||
* Variable for storing the classes for the vertex
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
const cssNoteStr = '';
|
const cssNoteStr = '';
|
||||||
|
|
||||||
const styles = { labelStyle: '', style: '' };
|
const styles = { labelStyle: '', style: '' };
|
||||||
|
|
||||||
// Use vertex id as text in the box if no text is provided by the graph definition
|
|
||||||
const vertexText = vertex.text;
|
const vertexText = vertex.text;
|
||||||
|
|
||||||
const radius = 0;
|
const radius = 0;
|
||||||
const shape = 'note';
|
const shape = 'note';
|
||||||
// Add the node
|
|
||||||
const node = {
|
const node = {
|
||||||
labelStyle: styles.labelStyle,
|
labelStyle: styles.labelStyle,
|
||||||
shape: shape,
|
shape: shape,
|
||||||
@ -301,7 +294,7 @@ export const setConf = function (cnf: any) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Draws a flowchart in the tag with id: id based on the graph definition in text.
|
* Draws a class diagram in the tag with id: id based on the definition in text.
|
||||||
*
|
*
|
||||||
* @param text -
|
* @param text -
|
||||||
* @param id -
|
* @param id -
|
||||||
|
683
packages/mermaid/src/diagrams/class/classTypes.spec.ts
Normal file
683
packages/mermaid/src/diagrams/class/classTypes.spec.ts
Normal file
@ -0,0 +1,683 @@
|
|||||||
|
import { ClassMember } from './classTypes.js';
|
||||||
|
import { vi, describe, it, expect } from 'vitest';
|
||||||
|
const spyOn = vi.spyOn;
|
||||||
|
|
||||||
|
const staticCssStyle = 'text-decoration:underline;';
|
||||||
|
const abstractCssStyle = 'font-style:italic;';
|
||||||
|
|
||||||
|
describe('given text representing a method, ', function () {
|
||||||
|
describe('when method has no parameters', function () {
|
||||||
|
it('should parse correctly', function () {
|
||||||
|
const str = `getTime()`;
|
||||||
|
|
||||||
|
const classMember = new ClassMember(str, 'method');
|
||||||
|
expect(classMember.getDisplayDetails().displayText).toBe(str);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should handle public visibility', function () {
|
||||||
|
const str = `+getTime()`;
|
||||||
|
|
||||||
|
const classMember = new ClassMember(str, 'method');
|
||||||
|
expect(classMember.getDisplayDetails().displayText).toBe('+getTime()');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should handle private visibility', function () {
|
||||||
|
const str = `-getTime()`;
|
||||||
|
|
||||||
|
const classMember = new ClassMember(str, 'method');
|
||||||
|
expect(classMember.getDisplayDetails().displayText).toBe('-getTime()');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should handle protected visibility', function () {
|
||||||
|
const str = `#getTime()`;
|
||||||
|
|
||||||
|
const classMember = new ClassMember(str, 'method');
|
||||||
|
expect(classMember.getDisplayDetails().displayText).toBe('#getTime()');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should handle internal visibility', function () {
|
||||||
|
const str = `~getTime()`;
|
||||||
|
|
||||||
|
const classMember = new ClassMember(str, 'method');
|
||||||
|
expect(classMember.getDisplayDetails().displayText).toBe('~getTime()');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return correct css for static classifier', function () {
|
||||||
|
const str = `getTime()$`;
|
||||||
|
|
||||||
|
const classMember = new ClassMember(str, 'method');
|
||||||
|
expect(classMember.getDisplayDetails().displayText).toBe('getTime()');
|
||||||
|
expect(classMember.getDisplayDetails().cssStyle).toBe(staticCssStyle);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return correct css for abstract classifier', function () {
|
||||||
|
const str = `getTime()*`;
|
||||||
|
|
||||||
|
const classMember = new ClassMember(str, 'method');
|
||||||
|
expect(classMember.getDisplayDetails().displayText).toBe('getTime()');
|
||||||
|
expect(classMember.getDisplayDetails().cssStyle).toBe(abstractCssStyle);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('when method has single parameter value', function () {
|
||||||
|
it('should parse correctly', function () {
|
||||||
|
const str = `getTime(int)`;
|
||||||
|
|
||||||
|
const classMember = new ClassMember(str, 'method');
|
||||||
|
expect(classMember.getDisplayDetails().displayText).toBe(str);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should handle public visibility', function () {
|
||||||
|
const str = `+getTime(int)`;
|
||||||
|
|
||||||
|
const classMember = new ClassMember(str, 'method');
|
||||||
|
expect(classMember.getDisplayDetails().displayText).toBe('+getTime(int)');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should handle private visibility', function () {
|
||||||
|
const str = `-getTime(int)`;
|
||||||
|
|
||||||
|
const classMember = new ClassMember(str, 'method');
|
||||||
|
expect(classMember.getDisplayDetails().displayText).toBe('-getTime(int)');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should handle protected visibility', function () {
|
||||||
|
const str = `#getTime(int)`;
|
||||||
|
|
||||||
|
const classMember = new ClassMember(str, 'method');
|
||||||
|
expect(classMember.getDisplayDetails().displayText).toBe('#getTime(int)');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should handle internal visibility', function () {
|
||||||
|
const str = `~getTime(int)`;
|
||||||
|
|
||||||
|
const classMember = new ClassMember(str, 'method');
|
||||||
|
expect(classMember.getDisplayDetails().displayText).toBe('~getTime(int)');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return correct css for static classifier', function () {
|
||||||
|
const str = `getTime(int)$`;
|
||||||
|
|
||||||
|
const classMember = new ClassMember(str, 'method');
|
||||||
|
expect(classMember.getDisplayDetails().displayText).toBe('getTime(int)');
|
||||||
|
expect(classMember.getDisplayDetails().cssStyle).toBe(staticCssStyle);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return correct css for abstract classifier', function () {
|
||||||
|
const str = `getTime(int)*`;
|
||||||
|
|
||||||
|
const classMember = new ClassMember(str, 'method');
|
||||||
|
expect(classMember.getDisplayDetails().displayText).toBe('getTime(int)');
|
||||||
|
expect(classMember.getDisplayDetails().cssStyle).toBe(abstractCssStyle);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('when method has single parameter type and name (type first)', function () {
|
||||||
|
it('should parse correctly', function () {
|
||||||
|
const str = `getTime(int count)`;
|
||||||
|
|
||||||
|
const classMember = new ClassMember(str, 'method');
|
||||||
|
expect(classMember.getDisplayDetails().displayText).toBe(str);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should handle public visibility', function () {
|
||||||
|
const str = `+getTime(int count)`;
|
||||||
|
|
||||||
|
const classMember = new ClassMember(str, 'method');
|
||||||
|
expect(classMember.getDisplayDetails().displayText).toBe('+getTime(int count)');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should handle private visibility', function () {
|
||||||
|
const str = `-getTime(int count)`;
|
||||||
|
|
||||||
|
const classMember = new ClassMember(str, 'method');
|
||||||
|
expect(classMember.getDisplayDetails().displayText).toBe('-getTime(int count)');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should handle protected visibility', function () {
|
||||||
|
const str = `#getTime(int count)`;
|
||||||
|
|
||||||
|
const classMember = new ClassMember(str, 'method');
|
||||||
|
expect(classMember.getDisplayDetails().displayText).toBe('#getTime(int count)');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should handle internal visibility', function () {
|
||||||
|
const str = `~getTime(int count)`;
|
||||||
|
|
||||||
|
const classMember = new ClassMember(str, 'method');
|
||||||
|
expect(classMember.getDisplayDetails().displayText).toBe('~getTime(int count)');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return correct css for static classifier', function () {
|
||||||
|
const str = `getTime(int count)$`;
|
||||||
|
|
||||||
|
const classMember = new ClassMember(str, 'method');
|
||||||
|
expect(classMember.getDisplayDetails().displayText).toBe('getTime(int count)');
|
||||||
|
expect(classMember.getDisplayDetails().cssStyle).toBe(staticCssStyle);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return correct css for abstract classifier', function () {
|
||||||
|
const str = `getTime(int count)*`;
|
||||||
|
|
||||||
|
const classMember = new ClassMember(str, 'method');
|
||||||
|
expect(classMember.getDisplayDetails().displayText).toBe('getTime(int count)');
|
||||||
|
expect(classMember.getDisplayDetails().cssStyle).toBe(abstractCssStyle);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('when method has single parameter type and name (name first)', function () {
|
||||||
|
it('should parse correctly', function () {
|
||||||
|
const str = `getTime(count int)`;
|
||||||
|
|
||||||
|
const classMember = new ClassMember(str, 'method');
|
||||||
|
expect(classMember.getDisplayDetails().displayText).toBe(str);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should handle public visibility', function () {
|
||||||
|
const str = `+getTime(count int)`;
|
||||||
|
|
||||||
|
const classMember = new ClassMember(str, 'method');
|
||||||
|
expect(classMember.getDisplayDetails().displayText).toBe('+getTime(count int)');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should handle private visibility', function () {
|
||||||
|
const str = `-getTime(count int)`;
|
||||||
|
|
||||||
|
const classMember = new ClassMember(str, 'method');
|
||||||
|
expect(classMember.getDisplayDetails().displayText).toBe('-getTime(count int)');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should handle protected visibility', function () {
|
||||||
|
const str = `#getTime(count int)`;
|
||||||
|
|
||||||
|
const classMember = new ClassMember(str, 'method');
|
||||||
|
expect(classMember.getDisplayDetails().displayText).toBe('#getTime(count int)');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should handle internal visibility', function () {
|
||||||
|
const str = `~getTime(count int)`;
|
||||||
|
|
||||||
|
const classMember = new ClassMember(str, 'method');
|
||||||
|
expect(classMember.getDisplayDetails().displayText).toBe('~getTime(count int)');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return correct css for static classifier', function () {
|
||||||
|
const str = `getTime(count int)$`;
|
||||||
|
|
||||||
|
const classMember = new ClassMember(str, 'method');
|
||||||
|
expect(classMember.getDisplayDetails().displayText).toBe('getTime(count int)');
|
||||||
|
expect(classMember.getDisplayDetails().cssStyle).toBe(staticCssStyle);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return correct css for abstract classifier', function () {
|
||||||
|
const str = `getTime(count int)*`;
|
||||||
|
|
||||||
|
const classMember = new ClassMember(str, 'method');
|
||||||
|
expect(classMember.getDisplayDetails().displayText).toBe('getTime(count int)');
|
||||||
|
expect(classMember.getDisplayDetails().cssStyle).toBe(abstractCssStyle);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('when method has multiple parameters', function () {
|
||||||
|
it('should parse correctly', function () {
|
||||||
|
const str = `getTime(string text, int count)`;
|
||||||
|
|
||||||
|
const classMember = new ClassMember(str, 'method');
|
||||||
|
expect(classMember.getDisplayDetails().displayText).toBe(str);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should handle public visibility', function () {
|
||||||
|
const str = `+getTime(string text, int count)`;
|
||||||
|
|
||||||
|
const classMember = new ClassMember(str, 'method');
|
||||||
|
expect(classMember.getDisplayDetails().displayText).toBe(str);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should handle private visibility', function () {
|
||||||
|
const str = `-getTime(string text, int count)`;
|
||||||
|
|
||||||
|
const classMember = new ClassMember(str, 'method');
|
||||||
|
expect(classMember.getDisplayDetails().displayText).toBe(str);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should handle protected visibility', function () {
|
||||||
|
const str = `#getTime(string text, int count)`;
|
||||||
|
|
||||||
|
const classMember = new ClassMember(str, 'method');
|
||||||
|
expect(classMember.getDisplayDetails().displayText).toBe(str);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should handle internal visibility', function () {
|
||||||
|
const str = `~getTime(string text, int count)`;
|
||||||
|
|
||||||
|
const classMember = new ClassMember(str, 'method');
|
||||||
|
expect(classMember.getDisplayDetails().displayText).toBe(str);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return correct css for static classifier', function () {
|
||||||
|
const str = `getTime(string text, int count)$`;
|
||||||
|
|
||||||
|
const classMember = new ClassMember(str, 'method');
|
||||||
|
expect(classMember.getDisplayDetails().displayText).toBe('getTime(string text, int count)');
|
||||||
|
expect(classMember.getDisplayDetails().cssStyle).toBe(staticCssStyle);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return correct css for abstract classifier', function () {
|
||||||
|
const str = `getTime(string text, int count)*`;
|
||||||
|
|
||||||
|
const classMember = new ClassMember(str, 'method');
|
||||||
|
expect(classMember.getDisplayDetails().displayText).toBe('getTime(string text, int count)');
|
||||||
|
expect(classMember.getDisplayDetails().cssStyle).toBe(abstractCssStyle);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('when method has return type', function () {
|
||||||
|
it('should parse correctly', function () {
|
||||||
|
const str = `getTime() DateTime`;
|
||||||
|
|
||||||
|
const classMember = new ClassMember(str, 'method');
|
||||||
|
expect(classMember.getDisplayDetails().displayText).toBe('getTime() : DateTime');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should handle public visibility', function () {
|
||||||
|
const str = `+getTime() DateTime`;
|
||||||
|
|
||||||
|
const classMember = new ClassMember(str, 'method');
|
||||||
|
expect(classMember.getDisplayDetails().displayText).toBe('+getTime() : DateTime');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should handle private visibility', function () {
|
||||||
|
const str = `-getTime() DateTime`;
|
||||||
|
|
||||||
|
const classMember = new ClassMember(str, 'method');
|
||||||
|
expect(classMember.getDisplayDetails().displayText).toBe('-getTime() : DateTime');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should handle protected visibility', function () {
|
||||||
|
const str = `#getTime() DateTime`;
|
||||||
|
|
||||||
|
const classMember = new ClassMember(str, 'method');
|
||||||
|
expect(classMember.getDisplayDetails().displayText).toBe('#getTime() : DateTime');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should handle internal visibility', function () {
|
||||||
|
const str = `~getTime() DateTime`;
|
||||||
|
|
||||||
|
const classMember = new ClassMember(str, 'method');
|
||||||
|
expect(classMember.getDisplayDetails().displayText).toBe('~getTime() : DateTime');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return correct css for static classifier', function () {
|
||||||
|
const str = `getTime() DateTime$`;
|
||||||
|
|
||||||
|
const classMember = new ClassMember(str, 'method');
|
||||||
|
expect(classMember.getDisplayDetails().displayText).toBe('getTime() : DateTime');
|
||||||
|
expect(classMember.getDisplayDetails().cssStyle).toBe(staticCssStyle);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return correct css for abstract classifier', function () {
|
||||||
|
const str = `getTime() DateTime*`;
|
||||||
|
|
||||||
|
const classMember = new ClassMember(str, 'method');
|
||||||
|
expect(classMember.getDisplayDetails().displayText).toBe('getTime() : DateTime');
|
||||||
|
expect(classMember.getDisplayDetails().cssStyle).toBe(abstractCssStyle);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('when method parameter is generic', function () {
|
||||||
|
it('should parse correctly', function () {
|
||||||
|
const str = `getTimes(List~T~)`;
|
||||||
|
|
||||||
|
const classMember = new ClassMember(str, 'method');
|
||||||
|
expect(classMember.getDisplayDetails().displayText).toBe('getTimes(List<T>)');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should handle public visibility', function () {
|
||||||
|
const str = `+getTimes(List~T~)`;
|
||||||
|
|
||||||
|
const classMember = new ClassMember(str, 'method');
|
||||||
|
expect(classMember.getDisplayDetails().displayText).toBe('+getTimes(List<T>)');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should handle private visibility', function () {
|
||||||
|
const str = `-getTimes(List~T~)`;
|
||||||
|
|
||||||
|
const classMember = new ClassMember(str, 'method');
|
||||||
|
expect(classMember.getDisplayDetails().displayText).toBe('-getTimes(List<T>)');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should handle protected visibility', function () {
|
||||||
|
const str = `#getTimes(List~T~)`;
|
||||||
|
|
||||||
|
const classMember = new ClassMember(str, 'method');
|
||||||
|
expect(classMember.getDisplayDetails().displayText).toBe('#getTimes(List<T>)');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should handle internal visibility', function () {
|
||||||
|
const str = `~getTimes(List~T~)`;
|
||||||
|
|
||||||
|
const classMember = new ClassMember(str, 'method');
|
||||||
|
expect(classMember.getDisplayDetails().displayText).toBe('~getTimes(List<T>)');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return correct css for static classifier', function () {
|
||||||
|
const str = `getTimes(List~T~)$`;
|
||||||
|
|
||||||
|
const classMember = new ClassMember(str, 'method');
|
||||||
|
expect(classMember.getDisplayDetails().displayText).toBe('getTimes(List<T>)');
|
||||||
|
expect(classMember.getDisplayDetails().cssStyle).toBe(staticCssStyle);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return correct css for abstract classifier', function () {
|
||||||
|
const str = `getTimes(List~T~)*`;
|
||||||
|
|
||||||
|
const classMember = new ClassMember(str, 'method');
|
||||||
|
expect(classMember.getDisplayDetails().displayText).toBe('getTimes(List<T>)');
|
||||||
|
expect(classMember.getDisplayDetails().cssStyle).toBe(abstractCssStyle);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('when method parameter contains two generic', function () {
|
||||||
|
it('should parse correctly', function () {
|
||||||
|
const str = `getTimes(List~T~, List~OT~)`;
|
||||||
|
|
||||||
|
const classMember = new ClassMember(str, 'method');
|
||||||
|
expect(classMember.getDisplayDetails().displayText).toBe('getTimes(List<T>, List<OT>)');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should handle public visibility', function () {
|
||||||
|
const str = `+getTimes(List~T~, List~OT~)`;
|
||||||
|
|
||||||
|
const classMember = new ClassMember(str, 'method');
|
||||||
|
expect(classMember.getDisplayDetails().displayText).toBe('+getTimes(List<T>, List<OT>)');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should handle private visibility', function () {
|
||||||
|
const str = `-getTimes(List~T~, List~OT~)`;
|
||||||
|
|
||||||
|
const classMember = new ClassMember(str, 'method');
|
||||||
|
expect(classMember.getDisplayDetails().displayText).toBe('-getTimes(List<T>, List<OT>)');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should handle protected visibility', function () {
|
||||||
|
const str = `#getTimes(List~T~, List~OT~)`;
|
||||||
|
|
||||||
|
const classMember = new ClassMember(str, 'method');
|
||||||
|
expect(classMember.getDisplayDetails().displayText).toBe('#getTimes(List<T>, List<OT>)');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should handle internal visibility', function () {
|
||||||
|
const str = `~getTimes(List~T~, List~OT~)`;
|
||||||
|
|
||||||
|
const classMember = new ClassMember(str, 'method');
|
||||||
|
expect(classMember.getDisplayDetails().displayText).toBe('~getTimes(List<T>, List<OT>)');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return correct css for static classifier', function () {
|
||||||
|
const str = `getTimes(List~T~, List~OT~)$`;
|
||||||
|
|
||||||
|
const classMember = new ClassMember(str, 'method');
|
||||||
|
expect(classMember.getDisplayDetails().displayText).toBe('getTimes(List<T>, List<OT>)');
|
||||||
|
expect(classMember.getDisplayDetails().cssStyle).toBe(staticCssStyle);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return correct css for abstract classifier', function () {
|
||||||
|
const str = `getTimes(List~T~, List~OT~)*`;
|
||||||
|
|
||||||
|
const classMember = new ClassMember(str, 'method');
|
||||||
|
expect(classMember.getDisplayDetails().displayText).toBe('getTimes(List<T>, List<OT>)');
|
||||||
|
expect(classMember.getDisplayDetails().cssStyle).toBe(abstractCssStyle);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('when method parameter is a nested generic', function () {
|
||||||
|
it('should parse correctly', function () {
|
||||||
|
const str = `getTimetableList(List~List~T~~)`;
|
||||||
|
|
||||||
|
const classMember = new ClassMember(str, 'method');
|
||||||
|
expect(classMember.getDisplayDetails().displayText).toBe('getTimetableList(List<List<T>>)');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should handle public visibility', function () {
|
||||||
|
const str = `+getTimetableList(List~List~T~~)`;
|
||||||
|
|
||||||
|
const classMember = new ClassMember(str, 'method');
|
||||||
|
expect(classMember.getDisplayDetails().displayText).toBe('+getTimetableList(List<List<T>>)');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should handle private visibility', function () {
|
||||||
|
const str = `-getTimetableList(List~List~T~~)`;
|
||||||
|
|
||||||
|
const classMember = new ClassMember(str, 'method');
|
||||||
|
expect(classMember.getDisplayDetails().displayText).toBe('-getTimetableList(List<List<T>>)');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should handle protected visibility', function () {
|
||||||
|
const str = `#getTimetableList(List~List~T~~)`;
|
||||||
|
|
||||||
|
const classMember = new ClassMember(str, 'method');
|
||||||
|
expect(classMember.getDisplayDetails().displayText).toBe('#getTimetableList(List<List<T>>)');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should handle internal visibility', function () {
|
||||||
|
const str = `~getTimetableList(List~List~T~~)`;
|
||||||
|
|
||||||
|
const classMember = new ClassMember(str, 'method');
|
||||||
|
expect(classMember.getDisplayDetails().displayText).toBe('~getTimetableList(List<List<T>>)');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return correct css for static classifier', function () {
|
||||||
|
const str = `getTimetableList(List~List~T~~)$`;
|
||||||
|
|
||||||
|
const classMember = new ClassMember(str, 'method');
|
||||||
|
expect(classMember.getDisplayDetails().displayText).toBe('getTimetableList(List<List<T>>)');
|
||||||
|
expect(classMember.getDisplayDetails().cssStyle).toBe(staticCssStyle);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return correct css for abstract classifier', function () {
|
||||||
|
const str = `getTimetableList(List~List~T~~)*`;
|
||||||
|
|
||||||
|
const classMember = new ClassMember(str, 'method');
|
||||||
|
expect(classMember.getDisplayDetails().displayText).toBe('getTimetableList(List<List<T>>)');
|
||||||
|
expect(classMember.getDisplayDetails().cssStyle).toBe(abstractCssStyle);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('when method parameter is a composite generic', function () {
|
||||||
|
const methodNameAndParameters = 'getTimes(List~K, V~)';
|
||||||
|
const expectedMethodNameAndParameters = 'getTimes(List<K, V>)';
|
||||||
|
it('should parse correctly', function () {
|
||||||
|
const str = methodNameAndParameters;
|
||||||
|
|
||||||
|
const classMember = new ClassMember(str, 'method');
|
||||||
|
expect(classMember.getDisplayDetails().displayText).toBe(expectedMethodNameAndParameters);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should handle public visibility', function () {
|
||||||
|
const str = '+' + methodNameAndParameters;
|
||||||
|
|
||||||
|
const classMember = new ClassMember(str, 'method');
|
||||||
|
expect(classMember.getDisplayDetails().displayText).toBe(
|
||||||
|
'+' + expectedMethodNameAndParameters
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should handle private visibility', function () {
|
||||||
|
const str = '-' + methodNameAndParameters;
|
||||||
|
const classMember = new ClassMember(str, 'method');
|
||||||
|
expect(classMember.getDisplayDetails().displayText).toBe(
|
||||||
|
'-' + expectedMethodNameAndParameters
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should handle protected visibility', function () {
|
||||||
|
const str = '#' + methodNameAndParameters;
|
||||||
|
const classMember = new ClassMember(str, 'method');
|
||||||
|
expect(classMember.getDisplayDetails().displayText).toBe(
|
||||||
|
'#' + expectedMethodNameAndParameters
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should handle internal visibility', function () {
|
||||||
|
const str = '~' + methodNameAndParameters;
|
||||||
|
|
||||||
|
const classMember = new ClassMember(str, 'method');
|
||||||
|
expect(classMember.getDisplayDetails().displayText).toBe(
|
||||||
|
'~' + expectedMethodNameAndParameters
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return correct css for static classifier', function () {
|
||||||
|
const str = methodNameAndParameters + '$';
|
||||||
|
const classMember = new ClassMember(str, 'method');
|
||||||
|
expect(classMember.getDisplayDetails().displayText).toBe(expectedMethodNameAndParameters);
|
||||||
|
expect(classMember.getDisplayDetails().cssStyle).toBe(staticCssStyle);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return correct css for abstract classifier', function () {
|
||||||
|
const str = methodNameAndParameters + '*';
|
||||||
|
const classMember = new ClassMember(str, 'method');
|
||||||
|
expect(classMember.getDisplayDetails().displayText).toBe(expectedMethodNameAndParameters);
|
||||||
|
expect(classMember.getDisplayDetails().cssStyle).toBe(abstractCssStyle);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('when method return type is generic', function () {
|
||||||
|
it('should parse correctly', function () {
|
||||||
|
const str = `getTimes() List~T~`;
|
||||||
|
|
||||||
|
const classMember = new ClassMember(str, 'method');
|
||||||
|
expect(classMember.getDisplayDetails().displayText).toBe('getTimes() : List<T>');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should handle public visibility', function () {
|
||||||
|
const str = `+getTimes() List~T~`;
|
||||||
|
|
||||||
|
const classMember = new ClassMember(str, 'method');
|
||||||
|
expect(classMember.getDisplayDetails().displayText).toBe('+getTimes() : List<T>');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should handle private visibility', function () {
|
||||||
|
const str = `-getTimes() List~T~`;
|
||||||
|
|
||||||
|
const classMember = new ClassMember(str, 'method');
|
||||||
|
expect(classMember.getDisplayDetails().displayText).toBe('-getTimes() : List<T>');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should handle protected visibility', function () {
|
||||||
|
const str = `#getTimes() List~T~`;
|
||||||
|
|
||||||
|
const classMember = new ClassMember(str, 'method');
|
||||||
|
expect(classMember.getDisplayDetails().displayText).toBe('#getTimes() : List<T>');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should handle internal visibility', function () {
|
||||||
|
const str = `~getTimes() List~T~`;
|
||||||
|
|
||||||
|
const classMember = new ClassMember(str, 'method');
|
||||||
|
expect(classMember.getDisplayDetails().displayText).toBe('~getTimes() : List<T>');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return correct css for static classifier', function () {
|
||||||
|
const str = `getTimes() List~T~$`;
|
||||||
|
|
||||||
|
const classMember = new ClassMember(str, 'method');
|
||||||
|
expect(classMember.getDisplayDetails().displayText).toBe('getTimes() : List<T>');
|
||||||
|
expect(classMember.getDisplayDetails().cssStyle).toBe(staticCssStyle);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return correct css for abstract classifier', function () {
|
||||||
|
const str = `getTimes() List~T~*`;
|
||||||
|
|
||||||
|
const classMember = new ClassMember(str, 'method');
|
||||||
|
expect(classMember.getDisplayDetails().displayText).toBe('getTimes() : List<T>');
|
||||||
|
expect(classMember.getDisplayDetails().cssStyle).toBe(abstractCssStyle);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('when method return type is a nested generic', function () {
|
||||||
|
it('should parse correctly', function () {
|
||||||
|
const str = `getTimetableList() List~List~T~~`;
|
||||||
|
|
||||||
|
const classMember = new ClassMember(str, 'method');
|
||||||
|
expect(classMember.getDisplayDetails().displayText).toBe(
|
||||||
|
'getTimetableList() : List<List<T>>'
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should handle public visibility', function () {
|
||||||
|
const str = `+getTimetableList() List~List~T~~`;
|
||||||
|
|
||||||
|
const classMember = new ClassMember(str, 'method');
|
||||||
|
expect(classMember.getDisplayDetails().displayText).toBe(
|
||||||
|
'+getTimetableList() : List<List<T>>'
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should handle private visibility', function () {
|
||||||
|
const str = `-getTimetableList() List~List~T~~`;
|
||||||
|
|
||||||
|
const classMember = new ClassMember(str, 'method');
|
||||||
|
expect(classMember.getDisplayDetails().displayText).toBe(
|
||||||
|
'-getTimetableList() : List<List<T>>'
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should handle protected visibility', function () {
|
||||||
|
const str = `#getTimetableList() List~List~T~~`;
|
||||||
|
|
||||||
|
const classMember = new ClassMember(str, 'method');
|
||||||
|
expect(classMember.getDisplayDetails().displayText).toBe(
|
||||||
|
'#getTimetableList() : List<List<T>>'
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should handle internal visibility', function () {
|
||||||
|
const str = `~getTimetableList() List~List~T~~`;
|
||||||
|
|
||||||
|
const classMember = new ClassMember(str, 'method');
|
||||||
|
expect(classMember.getDisplayDetails().displayText).toBe(
|
||||||
|
'~getTimetableList() : List<List<T>>'
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return correct css for static classifier', function () {
|
||||||
|
const str = `getTimetableList() List~List~T~~$`;
|
||||||
|
|
||||||
|
const classMember = new ClassMember(str, 'method');
|
||||||
|
expect(classMember.getDisplayDetails().displayText).toBe(
|
||||||
|
'getTimetableList() : List<List<T>>'
|
||||||
|
);
|
||||||
|
expect(classMember.getDisplayDetails().cssStyle).toBe(staticCssStyle);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return correct css for abstract classifier', function () {
|
||||||
|
const str = `getTimetableList() List~List~T~~*`;
|
||||||
|
|
||||||
|
const classMember = new ClassMember(str, 'method');
|
||||||
|
expect(classMember.getDisplayDetails().displayText).toBe(
|
||||||
|
'getTimetableList() : List<List<T>>'
|
||||||
|
);
|
||||||
|
expect(classMember.getDisplayDetails().cssStyle).toBe(abstractCssStyle);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('--uncategorized tests--', function () {
|
||||||
|
it('member name should handle double colons', function () {
|
||||||
|
const str = `std::map ~int,string~ pMap;`;
|
||||||
|
|
||||||
|
const classMember = new ClassMember(str, 'attribute');
|
||||||
|
expect(classMember.getDisplayDetails().displayText).toBe('std::map <int,string> pMap;');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('member name should handle generic type', function () {
|
||||||
|
const str = `getTime~T~(this T, int seconds)$ DateTime`;
|
||||||
|
|
||||||
|
const classMember = new ClassMember(str, 'method');
|
||||||
|
expect(classMember.getDisplayDetails().displayText).toBe(
|
||||||
|
'getTime<T>(this T, int seconds) : DateTime'
|
||||||
|
);
|
||||||
|
expect(classMember.getDisplayDetails().cssStyle).toBe(staticCssStyle);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
@ -1,10 +1,13 @@
|
|||||||
|
import { getConfig } from '../../config.js';
|
||||||
|
import { parseGenericTypes, sanitizeText } from '../common/common.js';
|
||||||
|
|
||||||
export interface ClassNode {
|
export interface ClassNode {
|
||||||
id: string;
|
id: string;
|
||||||
type: string;
|
type: string;
|
||||||
label: string;
|
label: string;
|
||||||
cssClasses: string[];
|
cssClasses: string[];
|
||||||
methods: string[];
|
methods: ClassMember[];
|
||||||
members: string[];
|
members: ClassMember[];
|
||||||
annotations: string[];
|
annotations: string[];
|
||||||
domId: string;
|
domId: string;
|
||||||
parent?: string;
|
parent?: string;
|
||||||
@ -14,6 +17,120 @@ export interface ClassNode {
|
|||||||
tooltip?: string;
|
tooltip?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export type Visibility = '#' | '+' | '~' | '-' | '';
|
||||||
|
export const visibilityValues = ['#', '+', '~', '-', ''];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parses and stores class diagram member variables/methods.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
export class ClassMember {
|
||||||
|
id!: string;
|
||||||
|
cssStyle!: string;
|
||||||
|
memberType!: 'method' | 'attribute';
|
||||||
|
visibility!: Visibility;
|
||||||
|
/**
|
||||||
|
* denote if static or to determine which css class to apply to the node
|
||||||
|
* @defaultValue ''
|
||||||
|
*/
|
||||||
|
classifier!: string;
|
||||||
|
/**
|
||||||
|
* parameters for method
|
||||||
|
* @defaultValue ''
|
||||||
|
*/
|
||||||
|
parameters!: string;
|
||||||
|
/**
|
||||||
|
* return type for method
|
||||||
|
* @defaultValue ''
|
||||||
|
*/
|
||||||
|
returnType!: string;
|
||||||
|
|
||||||
|
constructor(input: string, memberType: 'method' | 'attribute') {
|
||||||
|
this.memberType = memberType;
|
||||||
|
this.visibility = '';
|
||||||
|
this.classifier = '';
|
||||||
|
const sanitizedInput = sanitizeText(input, getConfig());
|
||||||
|
this.parseMember(sanitizedInput);
|
||||||
|
}
|
||||||
|
|
||||||
|
getDisplayDetails() {
|
||||||
|
let displayText = this.visibility + parseGenericTypes(this.id);
|
||||||
|
if (this.memberType === 'method') {
|
||||||
|
displayText += `(${parseGenericTypes(this.parameters.trim())})`;
|
||||||
|
if (this.returnType) {
|
||||||
|
displayText += ' : ' + parseGenericTypes(this.returnType);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
displayText = displayText.trim();
|
||||||
|
const cssStyle = this.parseClassifier();
|
||||||
|
|
||||||
|
return {
|
||||||
|
displayText,
|
||||||
|
cssStyle,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
parseMember(input: string) {
|
||||||
|
let potentialClassifier = '';
|
||||||
|
|
||||||
|
if (this.memberType === 'method') {
|
||||||
|
const methodRegEx = /([#+~-])?(.+)\((.*)\)([\s$*])?(.*)([$*])?/;
|
||||||
|
const match = input.match(methodRegEx);
|
||||||
|
if (match) {
|
||||||
|
const detectedVisibility = match[1] ? match[1].trim() : '';
|
||||||
|
|
||||||
|
if (visibilityValues.includes(detectedVisibility)) {
|
||||||
|
this.visibility = detectedVisibility as Visibility;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.id = match[2].trim();
|
||||||
|
this.parameters = match[3] ? match[3].trim() : '';
|
||||||
|
potentialClassifier = match[4] ? match[4].trim() : '';
|
||||||
|
this.returnType = match[5] ? match[5].trim() : '';
|
||||||
|
|
||||||
|
if (potentialClassifier === '') {
|
||||||
|
const lastChar = this.returnType.substring(this.returnType.length - 1);
|
||||||
|
if (lastChar.match(/[$*]/)) {
|
||||||
|
potentialClassifier = lastChar;
|
||||||
|
this.returnType = this.returnType.substring(0, this.returnType.length - 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
const length = input.length;
|
||||||
|
const firstChar = input.substring(0, 1);
|
||||||
|
const lastChar = input.substring(length - 1);
|
||||||
|
|
||||||
|
if (visibilityValues.includes(firstChar)) {
|
||||||
|
this.visibility = firstChar as Visibility;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (lastChar.match(/[*?]/)) {
|
||||||
|
potentialClassifier = lastChar;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.id = input.substring(
|
||||||
|
this.visibility === '' ? 0 : 1,
|
||||||
|
potentialClassifier === '' ? length : length - 1
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.classifier = potentialClassifier;
|
||||||
|
}
|
||||||
|
|
||||||
|
parseClassifier() {
|
||||||
|
switch (this.classifier) {
|
||||||
|
case '*':
|
||||||
|
return 'font-style:italic;';
|
||||||
|
case '$':
|
||||||
|
return 'text-decoration:underline;';
|
||||||
|
default:
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export interface ClassNote {
|
export interface ClassNote {
|
||||||
id: string;
|
id: string;
|
||||||
class: string;
|
class: string;
|
||||||
|
@ -233,21 +233,14 @@ start
|
|||||||
| statements
|
| statements
|
||||||
;
|
;
|
||||||
|
|
||||||
direction
|
|
||||||
: direction_tb
|
|
||||||
{ yy.setDirection('TB');}
|
|
||||||
| direction_bt
|
|
||||||
{ yy.setDirection('BT');}
|
|
||||||
| direction_rl
|
|
||||||
{ yy.setDirection('RL');}
|
|
||||||
| direction_lr
|
|
||||||
{ yy.setDirection('LR');}
|
|
||||||
;
|
|
||||||
|
|
||||||
mermaidDoc
|
mermaidDoc
|
||||||
: graphConfig
|
: graphConfig
|
||||||
;
|
;
|
||||||
|
|
||||||
|
graphConfig
|
||||||
|
: CLASS_DIAGRAM NEWLINE statements EOF
|
||||||
|
;
|
||||||
|
|
||||||
directive
|
directive
|
||||||
: openDirective typeDirective closeDirective NEWLINE
|
: openDirective typeDirective closeDirective NEWLINE
|
||||||
| openDirective typeDirective ':' argDirective closeDirective NEWLINE
|
| openDirective typeDirective ':' argDirective closeDirective NEWLINE
|
||||||
@ -269,10 +262,6 @@ closeDirective
|
|||||||
: close_directive { yy.parseDirective('}%%', 'close_directive', 'class'); }
|
: close_directive { yy.parseDirective('}%%', 'close_directive', 'class'); }
|
||||||
;
|
;
|
||||||
|
|
||||||
graphConfig
|
|
||||||
: CLASS_DIAGRAM NEWLINE statements EOF
|
|
||||||
;
|
|
||||||
|
|
||||||
statements
|
statements
|
||||||
: statement
|
: statement
|
||||||
| statement NEWLINE
|
| statement NEWLINE
|
||||||
@ -301,7 +290,7 @@ statement
|
|||||||
| relationStatement LABEL { $1.title = yy.cleanupLabel($2); yy.addRelation($1); }
|
| relationStatement LABEL { $1.title = yy.cleanupLabel($2); yy.addRelation($1); }
|
||||||
| namespaceStatement
|
| namespaceStatement
|
||||||
| classStatement
|
| classStatement
|
||||||
| methodStatement
|
| memberStatement
|
||||||
| annotationStatement
|
| annotationStatement
|
||||||
| clickStatement
|
| clickStatement
|
||||||
| cssClassStatement
|
| cssClassStatement
|
||||||
@ -348,7 +337,7 @@ members
|
|||||||
| MEMBER members { $2.push($1);$$=$2;}
|
| MEMBER members { $2.push($1);$$=$2;}
|
||||||
;
|
;
|
||||||
|
|
||||||
methodStatement
|
memberStatement
|
||||||
: className {/*console.log('Rel found',$1);*/}
|
: className {/*console.log('Rel found',$1);*/}
|
||||||
| className LABEL {yy.addMember($1,yy.cleanupLabel($2));}
|
| className LABEL {yy.addMember($1,yy.cleanupLabel($2));}
|
||||||
| MEMBER {/*console.warn('Member',$1);*/}
|
| MEMBER {/*console.warn('Member',$1);*/}
|
||||||
@ -367,6 +356,17 @@ noteStatement
|
|||||||
| NOTE noteText { yy.addNote($2); }
|
| NOTE noteText { yy.addNote($2); }
|
||||||
;
|
;
|
||||||
|
|
||||||
|
direction
|
||||||
|
: direction_tb
|
||||||
|
{ yy.setDirection('TB');}
|
||||||
|
| direction_bt
|
||||||
|
{ yy.setDirection('BT');}
|
||||||
|
| direction_rl
|
||||||
|
{ yy.setDirection('RL');}
|
||||||
|
| direction_lr
|
||||||
|
{ yy.setDirection('LR');}
|
||||||
|
;
|
||||||
|
|
||||||
relation
|
relation
|
||||||
: relationType lineType relationType { $$={type1:$1,type2:$3,lineType:$2}; }
|
: relationType lineType relationType { $$={type1:$1,type2:$3,lineType:$2}; }
|
||||||
| lineType relationType { $$={type1:'none',type2:$2,lineType:$1}; }
|
| lineType relationType { $$={type1:'none',type2:$2,lineType:$1}; }
|
||||||
|
@ -109,25 +109,25 @@ g.classGroup line {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#extensionStart, .extension {
|
#extensionStart, .extension {
|
||||||
fill: ${options.mainBkg} !important;
|
fill: transparent !important;
|
||||||
stroke: ${options.lineColor} !important;
|
stroke: ${options.lineColor} !important;
|
||||||
stroke-width: 1;
|
stroke-width: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
#extensionEnd, .extension {
|
#extensionEnd, .extension {
|
||||||
fill: ${options.mainBkg} !important;
|
fill: transparent !important;
|
||||||
stroke: ${options.lineColor} !important;
|
stroke: ${options.lineColor} !important;
|
||||||
stroke-width: 1;
|
stroke-width: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
#aggregationStart, .aggregation {
|
#aggregationStart, .aggregation {
|
||||||
fill: ${options.mainBkg} !important;
|
fill: transparent !important;
|
||||||
stroke: ${options.lineColor} !important;
|
stroke: ${options.lineColor} !important;
|
||||||
stroke-width: 1;
|
stroke-width: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
#aggregationEnd, .aggregation {
|
#aggregationEnd, .aggregation {
|
||||||
fill: ${options.mainBkg} !important;
|
fill: transparent !important;
|
||||||
stroke: ${options.lineColor} !important;
|
stroke: ${options.lineColor} !important;
|
||||||
stroke-width: 1;
|
stroke-width: 1;
|
||||||
}
|
}
|
||||||
|
@ -174,7 +174,6 @@ export const drawClass = function (elem, classDef, conf, diagObj) {
|
|||||||
// add class group
|
// add class group
|
||||||
const g = elem.append('g').attr('id', diagObj.db.lookUpDomId(id)).attr('class', 'classGroup');
|
const g = elem.append('g').attr('id', diagObj.db.lookUpDomId(id)).attr('class', 'classGroup');
|
||||||
|
|
||||||
// add title
|
|
||||||
let title;
|
let title;
|
||||||
if (classDef.link) {
|
if (classDef.link) {
|
||||||
title = g
|
title = g
|
||||||
@ -211,47 +210,56 @@ export const drawClass = function (elem, classDef, conf, diagObj) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const titleHeight = title.node().getBBox().height;
|
const titleHeight = title.node().getBBox().height;
|
||||||
|
let membersLine;
|
||||||
|
let membersBox;
|
||||||
|
let methodsLine;
|
||||||
|
|
||||||
const membersLine = g
|
// don't draw box if no members
|
||||||
.append('line') // text label for the x axis
|
if (classDef.members.length > 0) {
|
||||||
.attr('x1', 0)
|
membersLine = g
|
||||||
.attr('y1', conf.padding + titleHeight + conf.dividerMargin / 2)
|
.append('line') // text label for the x axis
|
||||||
.attr('y2', conf.padding + titleHeight + conf.dividerMargin / 2);
|
.attr('x1', 0)
|
||||||
|
.attr('y1', conf.padding + titleHeight + conf.dividerMargin / 2)
|
||||||
|
.attr('y2', conf.padding + titleHeight + conf.dividerMargin / 2);
|
||||||
|
|
||||||
const members = g
|
const members = g
|
||||||
.append('text') // text label for the x axis
|
.append('text') // text label for the x axis
|
||||||
.attr('x', conf.padding)
|
.attr('x', conf.padding)
|
||||||
.attr('y', titleHeight + conf.dividerMargin + conf.textHeight)
|
.attr('y', titleHeight + conf.dividerMargin + conf.textHeight)
|
||||||
.attr('fill', 'white')
|
.attr('fill', 'white')
|
||||||
.attr('class', 'classText');
|
.attr('class', 'classText');
|
||||||
|
|
||||||
isFirst = true;
|
isFirst = true;
|
||||||
classDef.members.forEach(function (member) {
|
classDef.members.forEach(function (member) {
|
||||||
addTspan(members, member, isFirst, conf);
|
addTspan(members, member, isFirst, conf);
|
||||||
isFirst = false;
|
isFirst = false;
|
||||||
});
|
});
|
||||||
|
|
||||||
const membersBox = members.node().getBBox();
|
membersBox = members.node().getBBox();
|
||||||
|
}
|
||||||
|
|
||||||
const methodsLine = g
|
// don't draw box if no methods
|
||||||
.append('line') // text label for the x axis
|
if (classDef.methods.length > 0) {
|
||||||
.attr('x1', 0)
|
methodsLine = g
|
||||||
.attr('y1', conf.padding + titleHeight + conf.dividerMargin + membersBox.height)
|
.append('line') // text label for the x axis
|
||||||
.attr('y2', conf.padding + titleHeight + conf.dividerMargin + membersBox.height);
|
.attr('x1', 0)
|
||||||
|
.attr('y1', conf.padding + titleHeight + conf.dividerMargin + membersBox.height)
|
||||||
|
.attr('y2', conf.padding + titleHeight + conf.dividerMargin + membersBox.height);
|
||||||
|
|
||||||
const methods = g
|
const methods = g
|
||||||
.append('text') // text label for the x axis
|
.append('text') // text label for the x axis
|
||||||
.attr('x', conf.padding)
|
.attr('x', conf.padding)
|
||||||
.attr('y', titleHeight + 2 * conf.dividerMargin + membersBox.height + conf.textHeight)
|
.attr('y', titleHeight + 2 * conf.dividerMargin + membersBox.height + conf.textHeight)
|
||||||
.attr('fill', 'white')
|
.attr('fill', 'white')
|
||||||
.attr('class', 'classText');
|
.attr('class', 'classText');
|
||||||
|
|
||||||
isFirst = true;
|
isFirst = true;
|
||||||
|
|
||||||
classDef.methods.forEach(function (method) {
|
classDef.methods.forEach(function (method) {
|
||||||
addTspan(methods, method, isFirst, conf);
|
addTspan(methods, method, isFirst, conf);
|
||||||
isFirst = false;
|
isFirst = false;
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
|
||||||
const classBox = g.node().getBBox();
|
const classBox = g.node().getBBox();
|
||||||
var cssClassStr = ' ';
|
var cssClassStr = ' ';
|
||||||
@ -280,8 +288,12 @@ export const drawClass = function (elem, classDef, conf, diagObj) {
|
|||||||
title.insert('title').text(classDef.tooltip);
|
title.insert('title').text(classDef.tooltip);
|
||||||
}
|
}
|
||||||
|
|
||||||
membersLine.attr('x2', rectWidth);
|
if (membersLine) {
|
||||||
methodsLine.attr('x2', rectWidth);
|
membersLine.attr('x2', rectWidth);
|
||||||
|
}
|
||||||
|
if (methodsLine) {
|
||||||
|
methodsLine.attr('x2', rectWidth);
|
||||||
|
}
|
||||||
|
|
||||||
classInfo.width = rectWidth;
|
classInfo.width = rectWidth;
|
||||||
classInfo.height = classBox.height + conf.padding + 0.5 * conf.dividerMargin;
|
classInfo.height = classBox.height + conf.padding + 0.5 * conf.dividerMargin;
|
||||||
@ -293,7 +305,7 @@ export const getClassTitleString = function (classDef) {
|
|||||||
let classTitleString = classDef.id;
|
let classTitleString = classDef.id;
|
||||||
|
|
||||||
if (classDef.type) {
|
if (classDef.type) {
|
||||||
classTitleString += '<' + classDef.type + '>';
|
classTitleString += '<' + parseGenericTypes(classDef.type) + '>';
|
||||||
}
|
}
|
||||||
|
|
||||||
return classTitleString;
|
return classTitleString;
|
||||||
@ -362,82 +374,19 @@ export const drawNote = function (elem, note, conf, diagObj) {
|
|||||||
return noteInfo;
|
return noteInfo;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const parseMember = function (text) {
|
|
||||||
let displayText = '';
|
|
||||||
let cssStyle = '';
|
|
||||||
let returnType = '';
|
|
||||||
|
|
||||||
let visibility = '';
|
|
||||||
let firstChar = text.substring(0, 1);
|
|
||||||
let lastChar = text.substring(text.length - 1, text.length);
|
|
||||||
|
|
||||||
if (firstChar.match(/[#+~-]/)) {
|
|
||||||
visibility = firstChar;
|
|
||||||
}
|
|
||||||
|
|
||||||
let noClassifierRe = /[\s\w)~]/;
|
|
||||||
if (!lastChar.match(noClassifierRe)) {
|
|
||||||
cssStyle = parseClassifier(lastChar);
|
|
||||||
}
|
|
||||||
|
|
||||||
const startIndex = visibility === '' ? 0 : 1;
|
|
||||||
let endIndex = cssStyle === '' ? text.length : text.length - 1;
|
|
||||||
text = text.substring(startIndex, endIndex);
|
|
||||||
|
|
||||||
const methodStart = text.indexOf('(');
|
|
||||||
const methodEnd = text.indexOf(')');
|
|
||||||
const isMethod = methodStart > 1 && methodEnd > methodStart && methodEnd <= text.length;
|
|
||||||
|
|
||||||
if (isMethod) {
|
|
||||||
let methodName = text.substring(0, methodStart).trim();
|
|
||||||
|
|
||||||
const parameters = text.substring(methodStart + 1, methodEnd);
|
|
||||||
|
|
||||||
displayText = visibility + methodName + '(' + parseGenericTypes(parameters.trim()) + ')';
|
|
||||||
|
|
||||||
if (methodEnd < text.length) {
|
|
||||||
// special case: classifier after the closing parenthesis
|
|
||||||
let potentialClassifier = text.substring(methodEnd + 1, methodEnd + 2);
|
|
||||||
if (cssStyle === '' && !potentialClassifier.match(noClassifierRe)) {
|
|
||||||
cssStyle = parseClassifier(potentialClassifier);
|
|
||||||
returnType = text.substring(methodEnd + 2).trim();
|
|
||||||
} else {
|
|
||||||
returnType = text.substring(methodEnd + 1).trim();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (returnType !== '') {
|
|
||||||
if (returnType.charAt(0) === ':') {
|
|
||||||
returnType = returnType.substring(1).trim();
|
|
||||||
}
|
|
||||||
returnType = ' : ' + parseGenericTypes(returnType);
|
|
||||||
displayText += returnType;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// finally - if all else fails, just send the text back as written (other than parsing for generic types)
|
|
||||||
displayText = visibility + parseGenericTypes(text);
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
displayText,
|
|
||||||
cssStyle,
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds a <tspan> for a member in a diagram
|
* Adds a <tspan> for a member in a diagram
|
||||||
*
|
*
|
||||||
* @param {SVGElement} textEl The element to append to
|
* @param {SVGElement} textEl The element to append to
|
||||||
* @param {string} txt The member
|
* @param {string} member The member
|
||||||
* @param {boolean} isFirst
|
* @param {boolean} isFirst
|
||||||
* @param {{ padding: string; textHeight: string }} conf The configuration for the member
|
* @param {{ padding: string; textHeight: string }} conf The configuration for the member
|
||||||
*/
|
*/
|
||||||
const addTspan = function (textEl, txt, isFirst, conf) {
|
const addTspan = function (textEl, member, isFirst, conf) {
|
||||||
let member = parseMember(txt);
|
const { displayText, cssStyle } = member.getDisplayDetails();
|
||||||
|
const tSpan = textEl.append('tspan').attr('x', conf.padding).text(displayText);
|
||||||
|
|
||||||
const tSpan = textEl.append('tspan').attr('x', conf.padding).text(member.displayText);
|
if (cssStyle !== '') {
|
||||||
|
|
||||||
if (member.cssStyle !== '') {
|
|
||||||
tSpan.attr('style', member.cssStyle);
|
tSpan.attr('style', member.cssStyle);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -446,27 +395,9 @@ const addTspan = function (textEl, txt, isFirst, conf) {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
|
||||||
* Gives the styles for a classifier
|
|
||||||
*
|
|
||||||
* @param {'+' | '-' | '#' | '~' | '*' | '$'} classifier The classifier string
|
|
||||||
* @returns {string} Styling for the classifier
|
|
||||||
*/
|
|
||||||
const parseClassifier = function (classifier) {
|
|
||||||
switch (classifier) {
|
|
||||||
case '*':
|
|
||||||
return 'font-style:italic;';
|
|
||||||
case '$':
|
|
||||||
return 'text-decoration:underline;';
|
|
||||||
default:
|
|
||||||
return '';
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
getClassTitleString,
|
getClassTitleString,
|
||||||
drawClass,
|
drawClass,
|
||||||
drawEdge,
|
drawEdge,
|
||||||
drawNote,
|
drawNote,
|
||||||
parseMember,
|
|
||||||
};
|
};
|
||||||
|
@ -1,330 +1,27 @@
|
|||||||
import svgDraw from './svgDraw.js';
|
import svgDraw from './svgDraw.js';
|
||||||
|
import { JSDOM } from 'jsdom';
|
||||||
|
|
||||||
describe('given a string representing class method, ', function () {
|
describe('given a string representing a class, ', function () {
|
||||||
it('should handle class names with generics', function () {
|
describe('when class name includes generic, ', function () {
|
||||||
const classDef = {
|
it('should return correct text for generic', function () {
|
||||||
id: 'Car',
|
const classDef = {
|
||||||
type: 'T',
|
id: 'Car',
|
||||||
label: 'Car',
|
type: 'T',
|
||||||
};
|
label: 'Car',
|
||||||
|
};
|
||||||
|
|
||||||
let actual = svgDraw.getClassTitleString(classDef);
|
let actual = svgDraw.getClassTitleString(classDef);
|
||||||
expect(actual).toBe('Car<T>');
|
expect(actual).toBe('Car<T>');
|
||||||
});
|
|
||||||
|
|
||||||
describe('when parsing base method declaration', function () {
|
|
||||||
it('should handle simple declaration', function () {
|
|
||||||
const str = 'foo()';
|
|
||||||
let actual = svgDraw.parseMember(str);
|
|
||||||
|
|
||||||
expect(actual.displayText).toBe('foo()');
|
|
||||||
expect(actual.cssStyle).toBe('');
|
|
||||||
});
|
});
|
||||||
|
it('should return correct text for nested generics', function () {
|
||||||
|
const classDef = {
|
||||||
|
id: 'Car',
|
||||||
|
type: 'T~T~',
|
||||||
|
label: 'Car',
|
||||||
|
};
|
||||||
|
|
||||||
it('should handle declaration with parameters', function () {
|
let actual = svgDraw.getClassTitleString(classDef);
|
||||||
const str = 'foo(int id)';
|
expect(actual).toBe('Car<T<T>>');
|
||||||
let actual = svgDraw.parseMember(str);
|
|
||||||
|
|
||||||
expect(actual.displayText).toBe('foo(int id)');
|
|
||||||
expect(actual.cssStyle).toBe('');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should handle declaration with multiple parameters', function () {
|
|
||||||
const str = 'foo(int id, object thing)';
|
|
||||||
let actual = svgDraw.parseMember(str);
|
|
||||||
|
|
||||||
expect(actual.displayText).toBe('foo(int id, object thing)');
|
|
||||||
expect(actual.cssStyle).toBe('');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should handle declaration with single item in parameters', function () {
|
|
||||||
const str = 'foo(id)';
|
|
||||||
let actual = svgDraw.parseMember(str);
|
|
||||||
|
|
||||||
expect(actual.displayText).toBe('foo(id)');
|
|
||||||
expect(actual.cssStyle).toBe('');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should handle declaration with single item in parameters with extra spaces', function () {
|
|
||||||
const str = ' foo ( id) ';
|
|
||||||
let actual = svgDraw.parseMember(str);
|
|
||||||
|
|
||||||
expect(actual.displayText).toBe('foo(id)');
|
|
||||||
expect(actual.cssStyle).toBe('');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should handle method declaration with generic parameter', function () {
|
|
||||||
const str = 'foo(List~int~)';
|
|
||||||
let actual = svgDraw.parseMember(str);
|
|
||||||
|
|
||||||
expect(actual.displayText).toBe('foo(List<int>)');
|
|
||||||
expect(actual.cssStyle).toBe('');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should handle method declaration with normal and generic parameter', function () {
|
|
||||||
const str = 'foo(int, List~int~)';
|
|
||||||
let actual = svgDraw.parseMember(str);
|
|
||||||
|
|
||||||
expect(actual.displayText).toBe('foo(int, List<int>)');
|
|
||||||
expect(actual.cssStyle).toBe('');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should handle declaration with return value', function () {
|
|
||||||
const str = 'foo(id) int';
|
|
||||||
let actual = svgDraw.parseMember(str);
|
|
||||||
|
|
||||||
expect(actual.displayText).toBe('foo(id) : int');
|
|
||||||
expect(actual.cssStyle).toBe('');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should handle declaration with colon return value', function () {
|
|
||||||
const str = 'foo(id) : int';
|
|
||||||
let actual = svgDraw.parseMember(str);
|
|
||||||
|
|
||||||
expect(actual.displayText).toBe('foo(id) : int');
|
|
||||||
expect(actual.cssStyle).toBe('');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should handle declaration with generic return value', function () {
|
|
||||||
const str = 'foo(id) List~int~';
|
|
||||||
let actual = svgDraw.parseMember(str);
|
|
||||||
|
|
||||||
expect(actual.displayText).toBe('foo(id) : List<int>');
|
|
||||||
expect(actual.cssStyle).toBe('');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should handle declaration with colon generic return value', function () {
|
|
||||||
const str = 'foo(id) : List~int~';
|
|
||||||
let actual = svgDraw.parseMember(str);
|
|
||||||
|
|
||||||
expect(actual.displayText).toBe('foo(id) : List<int>');
|
|
||||||
expect(actual.cssStyle).toBe('');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should handle method declaration with all possible markup', function () {
|
|
||||||
const str = '+foo ( List~int~ ids )* List~Item~';
|
|
||||||
let actual = svgDraw.parseMember(str);
|
|
||||||
|
|
||||||
expect(actual.displayText).toBe('+foo(List<int> ids) : List<Item>');
|
|
||||||
expect(actual.cssStyle).toBe('font-style:italic;');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should handle method declaration with nested generics', function () {
|
|
||||||
const str = '+foo ( List~List~int~~ ids )* List~List~Item~~';
|
|
||||||
let actual = svgDraw.parseMember(str);
|
|
||||||
|
|
||||||
expect(actual.displayText).toBe('+foo(List<List<int>> ids) : List<List<Item>>');
|
|
||||||
expect(actual.cssStyle).toBe('font-style:italic;');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('when parsing method visibility', function () {
|
|
||||||
it('should correctly handle public', function () {
|
|
||||||
const str = '+foo()';
|
|
||||||
let actual = svgDraw.parseMember(str);
|
|
||||||
|
|
||||||
expect(actual.displayText).toBe('+foo()');
|
|
||||||
expect(actual.cssStyle).toBe('');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should correctly handle private', function () {
|
|
||||||
const str = '-foo()';
|
|
||||||
let actual = svgDraw.parseMember(str);
|
|
||||||
|
|
||||||
expect(actual.displayText).toBe('-foo()');
|
|
||||||
expect(actual.cssStyle).toBe('');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should correctly handle protected', function () {
|
|
||||||
const str = '#foo()';
|
|
||||||
let actual = svgDraw.parseMember(str);
|
|
||||||
|
|
||||||
expect(actual.displayText).toBe('#foo()');
|
|
||||||
expect(actual.cssStyle).toBe('');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should correctly handle package/internal', function () {
|
|
||||||
const str = '~foo()';
|
|
||||||
let actual = svgDraw.parseMember(str);
|
|
||||||
|
|
||||||
expect(actual.displayText).toBe('~foo()');
|
|
||||||
expect(actual.cssStyle).toBe('');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('when parsing method classifier', function () {
|
|
||||||
it('should handle abstract method', function () {
|
|
||||||
const str = 'foo()*';
|
|
||||||
let actual = svgDraw.parseMember(str);
|
|
||||||
|
|
||||||
expect(actual.displayText).toBe('foo()');
|
|
||||||
expect(actual.cssStyle).toBe('font-style:italic;');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should handle abstract method with return type', function () {
|
|
||||||
const str = 'foo(name: String) int*';
|
|
||||||
let actual = svgDraw.parseMember(str);
|
|
||||||
|
|
||||||
expect(actual.displayText).toBe('foo(name: String) : int');
|
|
||||||
expect(actual.cssStyle).toBe('font-style:italic;');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should handle abstract method classifier after parenthesis with return type', function () {
|
|
||||||
const str = 'foo(name: String)* int';
|
|
||||||
let actual = svgDraw.parseMember(str);
|
|
||||||
|
|
||||||
expect(actual.displayText).toBe('foo(name: String) : int');
|
|
||||||
expect(actual.cssStyle).toBe('font-style:italic;');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should handle static method classifier', function () {
|
|
||||||
const str = 'foo()$';
|
|
||||||
let actual = svgDraw.parseMember(str);
|
|
||||||
|
|
||||||
expect(actual.displayText).toBe('foo()');
|
|
||||||
expect(actual.cssStyle).toBe('text-decoration:underline;');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should handle static method classifier with return type', function () {
|
|
||||||
const str = 'foo(name: String) int$';
|
|
||||||
let actual = svgDraw.parseMember(str);
|
|
||||||
|
|
||||||
expect(actual.displayText).toBe('foo(name: String) : int');
|
|
||||||
expect(actual.cssStyle).toBe('text-decoration:underline;');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should handle static method classifier with colon and return type', function () {
|
|
||||||
const str = 'foo(name: String): int$';
|
|
||||||
let actual = svgDraw.parseMember(str);
|
|
||||||
|
|
||||||
expect(actual.displayText).toBe('foo(name: String) : int');
|
|
||||||
expect(actual.cssStyle).toBe('text-decoration:underline;');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should handle static method classifier after parenthesis with return type', function () {
|
|
||||||
const str = 'foo(name: String)$ int';
|
|
||||||
let actual = svgDraw.parseMember(str);
|
|
||||||
|
|
||||||
expect(actual.displayText).toBe('foo(name: String) : int');
|
|
||||||
expect(actual.cssStyle).toBe('text-decoration:underline;');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should ignore unknown character for classifier', function () {
|
|
||||||
const str = 'foo()!';
|
|
||||||
let actual = svgDraw.parseMember(str);
|
|
||||||
|
|
||||||
expect(actual.displayText).toBe('foo()');
|
|
||||||
expect(actual.cssStyle).toBe('');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('given a string representing class member, ', function () {
|
|
||||||
describe('when parsing member declaration', function () {
|
|
||||||
it('should handle simple field', function () {
|
|
||||||
const str = 'id';
|
|
||||||
let actual = svgDraw.parseMember(str);
|
|
||||||
|
|
||||||
expect(actual.displayText).toBe('id');
|
|
||||||
expect(actual.cssStyle).toBe('');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should handle field with type', function () {
|
|
||||||
const str = 'int id';
|
|
||||||
let actual = svgDraw.parseMember(str);
|
|
||||||
|
|
||||||
expect(actual.displayText).toBe('int id');
|
|
||||||
expect(actual.cssStyle).toBe('');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should handle field with type (name first)', function () {
|
|
||||||
const str = 'id: int';
|
|
||||||
let actual = svgDraw.parseMember(str);
|
|
||||||
|
|
||||||
expect(actual.displayText).toBe('id: int');
|
|
||||||
expect(actual.cssStyle).toBe('');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should handle array field', function () {
|
|
||||||
const str = 'int[] ids';
|
|
||||||
let actual = svgDraw.parseMember(str);
|
|
||||||
|
|
||||||
expect(actual.displayText).toBe('int[] ids');
|
|
||||||
expect(actual.cssStyle).toBe('');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should handle array field (name first)', function () {
|
|
||||||
const str = 'ids: int[]';
|
|
||||||
let actual = svgDraw.parseMember(str);
|
|
||||||
|
|
||||||
expect(actual.displayText).toBe('ids: int[]');
|
|
||||||
expect(actual.cssStyle).toBe('');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should handle field with generic type', function () {
|
|
||||||
const str = 'List~int~ ids';
|
|
||||||
let actual = svgDraw.parseMember(str);
|
|
||||||
|
|
||||||
expect(actual.displayText).toBe('List<int> ids');
|
|
||||||
expect(actual.cssStyle).toBe('');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should handle field with generic type (name first)', function () {
|
|
||||||
const str = 'ids: List~int~';
|
|
||||||
let actual = svgDraw.parseMember(str);
|
|
||||||
|
|
||||||
expect(actual.displayText).toBe('ids: List<int>');
|
|
||||||
expect(actual.cssStyle).toBe('');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('when parsing classifiers', function () {
|
|
||||||
it('should handle static field', function () {
|
|
||||||
const str = 'String foo$';
|
|
||||||
let actual = svgDraw.parseMember(str);
|
|
||||||
|
|
||||||
expect(actual.displayText).toBe('String foo');
|
|
||||||
expect(actual.cssStyle).toBe('text-decoration:underline;');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should handle static field (name first)', function () {
|
|
||||||
const str = 'foo: String$';
|
|
||||||
let actual = svgDraw.parseMember(str);
|
|
||||||
|
|
||||||
expect(actual.displayText).toBe('foo: String');
|
|
||||||
expect(actual.cssStyle).toBe('text-decoration:underline;');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should handle static field with generic type', function () {
|
|
||||||
const str = 'List~String~ foo$';
|
|
||||||
let actual = svgDraw.parseMember(str);
|
|
||||||
|
|
||||||
expect(actual.displayText).toBe('List<String> foo');
|
|
||||||
expect(actual.cssStyle).toBe('text-decoration:underline;');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should handle static field with generic type (name first)', function () {
|
|
||||||
const str = 'foo: List~String~$';
|
|
||||||
let actual = svgDraw.parseMember(str);
|
|
||||||
|
|
||||||
expect(actual.displayText).toBe('foo: List<String>');
|
|
||||||
expect(actual.cssStyle).toBe('text-decoration:underline;');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should handle field with nested generic type', function () {
|
|
||||||
const str = 'List~List~int~~ idLists';
|
|
||||||
let actual = svgDraw.parseMember(str);
|
|
||||||
|
|
||||||
expect(actual.displayText).toBe('List<List<int>> idLists');
|
|
||||||
expect(actual.cssStyle).toBe('');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should handle field with nested generic type (name first)', function () {
|
|
||||||
const str = 'idLists: List~List~int~~';
|
|
||||||
let actual = svgDraw.parseMember(str);
|
|
||||||
|
|
||||||
expect(actual.displayText).toBe('idLists: List<List<int>>');
|
|
||||||
expect(actual.cssStyle).toBe('');
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -69,6 +69,5 @@ describe('generic parser', () => {
|
|||||||
'test <Array<Array<string[]>>>'
|
'test <Array<Array<string[]>>>'
|
||||||
);
|
);
|
||||||
expect(parseGenericTypes('~test')).toEqual('~test');
|
expect(parseGenericTypes('~test')).toEqual('~test');
|
||||||
expect(parseGenericTypes('~test Array~string~')).toEqual('~test Array<string>');
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -178,23 +178,63 @@ export const getMin = function (...values: number[]): number {
|
|||||||
* @param text - The text to convert
|
* @param text - The text to convert
|
||||||
* @returns The converted string
|
* @returns The converted string
|
||||||
*/
|
*/
|
||||||
export const parseGenericTypes = function (text: string): string {
|
export const parseGenericTypes = function (input: string): string {
|
||||||
let cleanedText = text;
|
const inputSets = input.split(/(,)/);
|
||||||
|
const output = [];
|
||||||
|
|
||||||
if (text.split('~').length - 1 >= 2) {
|
for (let i = 0; i < inputSets.length; i++) {
|
||||||
let newCleanedText = cleanedText;
|
let thisSet = inputSets[i];
|
||||||
|
|
||||||
// use a do...while loop instead of replaceAll to detect recursion
|
// if the original input included a value such as "~K, V~"", these will be split into
|
||||||
// e.g. Array~Array~T~~
|
// an array of ["~K",","," V~"].
|
||||||
do {
|
// This means that on each call of processSet, there will only be 1 ~ present
|
||||||
cleanedText = newCleanedText;
|
// To account for this, if we encounter a ",", we are checking the previous and next sets in the array
|
||||||
newCleanedText = cleanedText.replace(/~([^\s,:;]+)~/, '<$1>');
|
// to see if they contain matching ~'s
|
||||||
} while (newCleanedText != cleanedText);
|
// in which case we are assuming that they should be rejoined and sent to be processed
|
||||||
|
if (thisSet === ',' && i > 0 && i + 1 < inputSets.length) {
|
||||||
|
const previousSet = inputSets[i - 1];
|
||||||
|
const nextSet = inputSets[i + 1];
|
||||||
|
|
||||||
return parseGenericTypes(newCleanedText);
|
if (shouldCombineSets(previousSet, nextSet)) {
|
||||||
} else {
|
thisSet = previousSet + ',' + nextSet;
|
||||||
return cleanedText;
|
i++; // Move the index forward to skip the next iteration since we're combining sets
|
||||||
|
output.pop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
output.push(processSet(thisSet));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return output.join('');
|
||||||
|
};
|
||||||
|
|
||||||
|
const shouldCombineSets = (previousSet: string, nextSet: string): boolean => {
|
||||||
|
const prevCount = [...previousSet].reduce((count, char) => (char === '~' ? count + 1 : count), 0);
|
||||||
|
const nextCount = [...nextSet].reduce((count, char) => (char === '~' ? count + 1 : count), 0);
|
||||||
|
|
||||||
|
return prevCount === 1 && nextCount === 1;
|
||||||
|
};
|
||||||
|
|
||||||
|
const processSet = (input: string): string => {
|
||||||
|
const chars = [...input];
|
||||||
|
const tildeCount = chars.reduce((count, char) => (char === '~' ? count + 1 : count), 0);
|
||||||
|
|
||||||
|
if (tildeCount <= 1) {
|
||||||
|
return input;
|
||||||
|
}
|
||||||
|
|
||||||
|
let first = chars.indexOf('~');
|
||||||
|
let last = chars.lastIndexOf('~');
|
||||||
|
|
||||||
|
while (first !== -1 && last !== -1 && first !== last) {
|
||||||
|
chars[first] = '<';
|
||||||
|
chars[last] = '>';
|
||||||
|
|
||||||
|
first = chars.indexOf('~');
|
||||||
|
last = chars.lastIndexOf('~');
|
||||||
|
}
|
||||||
|
|
||||||
|
return chars.join('');
|
||||||
};
|
};
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
32
packages/mermaid/src/diagrams/common/commonDb.ts
Normal file
32
packages/mermaid/src/diagrams/common/commonDb.ts
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
import { sanitizeText as _sanitizeText } from './common.js';
|
||||||
|
import { getConfig } from '../../config.js';
|
||||||
|
|
||||||
|
let accTitle = '';
|
||||||
|
let diagramTitle = '';
|
||||||
|
let accDescription = '';
|
||||||
|
|
||||||
|
const sanitizeText = (txt: string): string => _sanitizeText(txt, getConfig());
|
||||||
|
|
||||||
|
export const clear = (): void => {
|
||||||
|
accTitle = '';
|
||||||
|
accDescription = '';
|
||||||
|
diagramTitle = '';
|
||||||
|
};
|
||||||
|
|
||||||
|
export const setAccTitle = (txt: string): void => {
|
||||||
|
accTitle = sanitizeText(txt).replace(/^\s+/g, '');
|
||||||
|
};
|
||||||
|
|
||||||
|
export const getAccTitle = (): string => accTitle;
|
||||||
|
|
||||||
|
export const setAccDescription = (txt: string): void => {
|
||||||
|
accDescription = sanitizeText(txt).replace(/\n\s+/g, '\n');
|
||||||
|
};
|
||||||
|
|
||||||
|
export const getAccDescription = (): string => accDescription;
|
||||||
|
|
||||||
|
export const setDiagramTitle = (txt: string): void => {
|
||||||
|
diagramTitle = sanitizeText(txt);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const getDiagramTitle = (): string => diagramTitle;
|
@ -10,7 +10,7 @@ import {
|
|||||||
clear as commonClear,
|
clear as commonClear,
|
||||||
setDiagramTitle,
|
setDiagramTitle,
|
||||||
getDiagramTitle,
|
getDiagramTitle,
|
||||||
} from '../../commonDb.js';
|
} from '../common/commonDb.js';
|
||||||
|
|
||||||
let entities = {};
|
let entities = {};
|
||||||
let relationships = [];
|
let relationships = [];
|
||||||
|
@ -66,7 +66,7 @@ o\{ return 'ZERO_OR_MORE';
|
|||||||
"optionally to" return 'NON_IDENTIFYING';
|
"optionally to" return 'NON_IDENTIFYING';
|
||||||
\.\- return 'NON_IDENTIFYING';
|
\.\- return 'NON_IDENTIFYING';
|
||||||
\-\. return 'NON_IDENTIFYING';
|
\-\. return 'NON_IDENTIFYING';
|
||||||
[A-Za-z][A-Za-z0-9\-_]* return 'ALPHANUM';
|
[A-Za-z_][A-Za-z0-9\-_]* return 'ALPHANUM';
|
||||||
. return yytext[0];
|
. return yytext[0];
|
||||||
<<EOF>> return 'EOF';
|
<<EOF>> return 'EOF';
|
||||||
|
|
||||||
|
@ -33,7 +33,7 @@ describe('when parsing ER diagram it...', function () {
|
|||||||
describe('has non A-Za-z0-9_- chars', function () {
|
describe('has non A-Za-z0-9_- chars', function () {
|
||||||
// these were entered using the Mac keyboard utility.
|
// these were entered using the Mac keyboard utility.
|
||||||
const chars =
|
const chars =
|
||||||
"~ ` ! @ # $ ^ & * ( ) - _ = + [ ] { } | / ; : ' . ? ¡ ⁄ ™ € £ ‹ ¢ › ∞ fi § ‡ • ° ª · º ‚ ≠ ± œ Œ ∑ „ ® † ˇ ¥ Á ¨ ˆ ˆ Ø π ∏ “ « » å Å ß Í ∂ Î ƒ Ï © ˙ Ó ∆ Ô ˚ ¬ Ò … Ú æ Æ Ω ¸ ≈ π ˛ ç Ç √ ◊ ∫ ı ˜ µ  ≤ ¯ ≥ ˘ ÷ ¿";
|
"~ ` ! @ # $ ^ & * ( ) - = + [ ] { } | / ; : ' . ? ¡ ⁄ ™ € £ ‹ ¢ › ∞ fi § ‡ • ° ª · º ‚ ≠ ± œ Œ ∑ „ ® † ˇ ¥ Á ¨ ˆ ˆ Ø π ∏ “ « » å Å ß Í ∂ Î ƒ Ï © ˙ Ó ∆ Ô ˚ ¬ Ò … Ú æ Æ Ω ¸ ≈ π ˛ ç Ç √ ◊ ∫ ı ˜ µ  ≤ ¯ ≥ ˘ ÷ ¿";
|
||||||
const allowed = chars.split(' ');
|
const allowed = chars.split(' ');
|
||||||
|
|
||||||
allowed.forEach((allowedChar) => {
|
allowed.forEach((allowedChar) => {
|
||||||
@ -170,6 +170,13 @@ describe('when parsing ER diagram it...', function () {
|
|||||||
expect(entities[firstEntity].alias).toBe(alias);
|
expect(entities[firstEntity].alias).toBe(alias);
|
||||||
expect(entities[secondEntity].alias).toBeUndefined();
|
expect(entities[secondEntity].alias).toBeUndefined();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('can start with an underscore', function () {
|
||||||
|
const entity = '_foo';
|
||||||
|
erDiagram.parser.parse(`erDiagram\n${entity}\n`);
|
||||||
|
const entities = erDb.getEntities();
|
||||||
|
expect(entities.hasOwnProperty(entity)).toBe(true);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('attribute name', () => {
|
describe('attribute name', () => {
|
||||||
|
@ -12,7 +12,7 @@ import {
|
|||||||
clear as commonClear,
|
clear as commonClear,
|
||||||
setDiagramTitle,
|
setDiagramTitle,
|
||||||
getDiagramTitle,
|
getDiagramTitle,
|
||||||
} from '../../commonDb.js';
|
} from '../common/commonDb.js';
|
||||||
|
|
||||||
const MERMAID_DOM_ID_PREFIX = 'flowchart-';
|
const MERMAID_DOM_ID_PREFIX = 'flowchart-';
|
||||||
let vertexCounter = 0;
|
let vertexCounter = 0;
|
||||||
|
@ -16,7 +16,7 @@ import {
|
|||||||
clear as commonClear,
|
clear as commonClear,
|
||||||
setDiagramTitle,
|
setDiagramTitle,
|
||||||
getDiagramTitle,
|
getDiagramTitle,
|
||||||
} from '../../commonDb.js';
|
} from '../common/commonDb.js';
|
||||||
|
|
||||||
dayjs.extend(dayjsIsoWeek);
|
dayjs.extend(dayjsIsoWeek);
|
||||||
dayjs.extend(dayjsCustomParseFormat);
|
dayjs.extend(dayjsCustomParseFormat);
|
||||||
|
@ -12,7 +12,7 @@ import {
|
|||||||
clear as commonClear,
|
clear as commonClear,
|
||||||
setDiagramTitle,
|
setDiagramTitle,
|
||||||
getDiagramTitle,
|
getDiagramTitle,
|
||||||
} from '../../commonDb.js';
|
} from '../common/commonDb.js';
|
||||||
|
|
||||||
let mainBranchName = getConfig().gitGraph.mainBranchName;
|
let mainBranchName = getConfig().gitGraph.mainBranchName;
|
||||||
let mainBranchOrder = getConfig().gitGraph.mainBranchOrder;
|
let mainBranchOrder = getConfig().gitGraph.mainBranchOrder;
|
||||||
|
@ -10,7 +10,7 @@ import {
|
|||||||
getAccDescription,
|
getAccDescription,
|
||||||
setAccDescription,
|
setAccDescription,
|
||||||
clear as commonClear,
|
clear as commonClear,
|
||||||
} from '../../commonDb.js';
|
} from '../common/commonDb.js';
|
||||||
import type { ParseDirectiveDefinition } from '../../diagram-api/types.js';
|
import type { ParseDirectiveDefinition } from '../../diagram-api/types.js';
|
||||||
import type { PieFields, PieDB, Sections } from './pieTypes.js';
|
import type { PieFields, PieDB, Sections } from './pieTypes.js';
|
||||||
import type { RequiredDeep } from 'type-fest';
|
import type { RequiredDeep } from 'type-fest';
|
||||||
|
@ -10,7 +10,7 @@ import {
|
|||||||
getAccDescription,
|
getAccDescription,
|
||||||
setAccDescription,
|
setAccDescription,
|
||||||
clear as commonClear,
|
clear as commonClear,
|
||||||
} from '../../commonDb.js';
|
} from '../common/commonDb.js';
|
||||||
import { QuadrantBuilder } from './quadrantBuilder.js';
|
import { QuadrantBuilder } from './quadrantBuilder.js';
|
||||||
|
|
||||||
const config = configApi.getConfig();
|
const config = configApi.getConfig();
|
||||||
|
@ -8,7 +8,7 @@ import {
|
|||||||
getAccDescription,
|
getAccDescription,
|
||||||
setAccDescription,
|
setAccDescription,
|
||||||
clear as commonClear,
|
clear as commonClear,
|
||||||
} from '../../commonDb.js';
|
} from '../common/commonDb.js';
|
||||||
|
|
||||||
let relations = [];
|
let relations = [];
|
||||||
let latestRequirement = {};
|
let latestRequirement = {};
|
||||||
|
@ -8,7 +8,7 @@ import {
|
|||||||
setDiagramTitle,
|
setDiagramTitle,
|
||||||
getDiagramTitle,
|
getDiagramTitle,
|
||||||
clear as commonClear,
|
clear as commonClear,
|
||||||
} from '../../commonDb.js';
|
} from '../common/commonDb.js';
|
||||||
|
|
||||||
// Sankey diagram represented by nodes and links between those nodes
|
// Sankey diagram represented by nodes and links between those nodes
|
||||||
let links: SankeyLink[] = [];
|
let links: SankeyLink[] = [];
|
||||||
|
@ -301,7 +301,7 @@ placement
|
|||||||
|
|
||||||
signal
|
signal
|
||||||
: actor signaltype '+' actor text2
|
: actor signaltype '+' actor text2
|
||||||
{ $$ = [$1,$4,{type: 'addMessage', from:$1.actor, to:$4.actor, signalType:$2, msg:$5},
|
{ $$ = [$1,$4,{type: 'addMessage', from:$1.actor, to:$4.actor, signalType:$2, msg:$5, activate: true},
|
||||||
{type: 'activeStart', signalType: yy.LINETYPE.ACTIVE_START, actor: $4}
|
{type: 'activeStart', signalType: yy.LINETYPE.ACTIVE_START, actor: $4}
|
||||||
]}
|
]}
|
||||||
| actor signaltype '-' actor text2
|
| actor signaltype '-' actor text2
|
||||||
|
@ -10,7 +10,7 @@ import {
|
|||||||
getAccDescription,
|
getAccDescription,
|
||||||
setAccDescription,
|
setAccDescription,
|
||||||
clear as commonClear,
|
clear as commonClear,
|
||||||
} from '../../commonDb.js';
|
} from '../common/commonDb.js';
|
||||||
|
|
||||||
let prevActor = undefined;
|
let prevActor = undefined;
|
||||||
let actors = {};
|
let actors = {};
|
||||||
@ -124,7 +124,8 @@ export const addSignal = function (
|
|||||||
idFrom,
|
idFrom,
|
||||||
idTo,
|
idTo,
|
||||||
message = { text: undefined, wrap: undefined },
|
message = { text: undefined, wrap: undefined },
|
||||||
messageType
|
messageType,
|
||||||
|
activate = false
|
||||||
) {
|
) {
|
||||||
if (messageType === LINETYPE.ACTIVE_END) {
|
if (messageType === LINETYPE.ACTIVE_END) {
|
||||||
const cnt = activationCount(idFrom.actor);
|
const cnt = activationCount(idFrom.actor);
|
||||||
@ -147,6 +148,7 @@ export const addSignal = function (
|
|||||||
message: message.text,
|
message: message.text,
|
||||||
wrap: (message.wrap === undefined && autoWrap()) || !!message.wrap,
|
wrap: (message.wrap === undefined && autoWrap()) || !!message.wrap,
|
||||||
type: messageType,
|
type: messageType,
|
||||||
|
activate,
|
||||||
});
|
});
|
||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
@ -450,6 +452,19 @@ export const getActorProperty = function (actor, key) {
|
|||||||
return undefined;
|
return undefined;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @typedef {object} AddMessageParams A message from one actor to another.
|
||||||
|
* @property {string} from - The id of the actor sending the message.
|
||||||
|
* @property {string} to - The id of the actor receiving the message.
|
||||||
|
* @property {string} msg - The message text.
|
||||||
|
* @property {number} signalType - The type of signal.
|
||||||
|
* @property {"addMessage"} type - Set to `"addMessage"` if this is an `AddMessageParams`.
|
||||||
|
* @property {boolean} [activate] - If `true`, this signal starts an activation.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {object | object[] | AddMessageParams} param - Object of parameters.
|
||||||
|
*/
|
||||||
export const apply = function (param) {
|
export const apply = function (param) {
|
||||||
if (Array.isArray(param)) {
|
if (Array.isArray(param)) {
|
||||||
param.forEach(function (item) {
|
param.forEach(function (item) {
|
||||||
@ -530,7 +545,7 @@ export const apply = function (param) {
|
|||||||
lastDestroyed = undefined;
|
lastDestroyed = undefined;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
addSignal(param.from, param.to, param.msg, param.signalType);
|
addSignal(param.from, param.to, param.msg, param.signalType, param.activate);
|
||||||
break;
|
break;
|
||||||
case 'boxStart':
|
case 'boxStart':
|
||||||
addBox(param.boxData);
|
addBox(param.boxData);
|
||||||
|
@ -104,6 +104,7 @@ describe('more than one sequence diagram', () => {
|
|||||||
expect(diagram1.db.getMessages()).toMatchInlineSnapshot(`
|
expect(diagram1.db.getMessages()).toMatchInlineSnapshot(`
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
|
"activate": false,
|
||||||
"from": "Alice",
|
"from": "Alice",
|
||||||
"message": "Hello Bob, how are you?",
|
"message": "Hello Bob, how are you?",
|
||||||
"to": "Bob",
|
"to": "Bob",
|
||||||
@ -111,6 +112,7 @@ describe('more than one sequence diagram', () => {
|
|||||||
"wrap": false,
|
"wrap": false,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
"activate": false,
|
||||||
"from": "Bob",
|
"from": "Bob",
|
||||||
"message": "I am good thanks!",
|
"message": "I am good thanks!",
|
||||||
"to": "Alice",
|
"to": "Alice",
|
||||||
@ -127,6 +129,7 @@ describe('more than one sequence diagram', () => {
|
|||||||
expect(diagram2.db.getMessages()).toMatchInlineSnapshot(`
|
expect(diagram2.db.getMessages()).toMatchInlineSnapshot(`
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
|
"activate": false,
|
||||||
"from": "Alice",
|
"from": "Alice",
|
||||||
"message": "Hello Bob, how are you?",
|
"message": "Hello Bob, how are you?",
|
||||||
"to": "Bob",
|
"to": "Bob",
|
||||||
@ -134,6 +137,7 @@ describe('more than one sequence diagram', () => {
|
|||||||
"wrap": false,
|
"wrap": false,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
"activate": false,
|
||||||
"from": "Bob",
|
"from": "Bob",
|
||||||
"message": "I am good thanks!",
|
"message": "I am good thanks!",
|
||||||
"to": "Alice",
|
"to": "Alice",
|
||||||
@ -152,6 +156,7 @@ describe('more than one sequence diagram', () => {
|
|||||||
expect(diagram3.db.getMessages()).toMatchInlineSnapshot(`
|
expect(diagram3.db.getMessages()).toMatchInlineSnapshot(`
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
|
"activate": false,
|
||||||
"from": "Alice",
|
"from": "Alice",
|
||||||
"message": "Hello John, how are you?",
|
"message": "Hello John, how are you?",
|
||||||
"to": "John",
|
"to": "John",
|
||||||
@ -159,6 +164,7 @@ describe('more than one sequence diagram', () => {
|
|||||||
"wrap": false,
|
"wrap": false,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
"activate": false,
|
||||||
"from": "John",
|
"from": "John",
|
||||||
"message": "I am good thanks!",
|
"message": "I am good thanks!",
|
||||||
"to": "Alice",
|
"to": "Alice",
|
||||||
@ -548,6 +554,7 @@ deactivate Bob`;
|
|||||||
|
|
||||||
expect(messages.length).toBe(4);
|
expect(messages.length).toBe(4);
|
||||||
expect(messages[0].type).toBe(diagram.db.LINETYPE.DOTTED);
|
expect(messages[0].type).toBe(diagram.db.LINETYPE.DOTTED);
|
||||||
|
expect(messages[0].activate).toBeTruthy();
|
||||||
expect(messages[1].type).toBe(diagram.db.LINETYPE.ACTIVE_START);
|
expect(messages[1].type).toBe(diagram.db.LINETYPE.ACTIVE_START);
|
||||||
expect(messages[1].from.actor).toBe('Bob');
|
expect(messages[1].from.actor).toBe('Bob');
|
||||||
expect(messages[2].type).toBe(diagram.db.LINETYPE.DOTTED);
|
expect(messages[2].type).toBe(diagram.db.LINETYPE.DOTTED);
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
// @ts-nocheck TODO: fix file
|
// @ts-nocheck TODO: fix file
|
||||||
import { select, selectAll } from 'd3';
|
import { select } from 'd3';
|
||||||
import svgDraw, { ACTOR_TYPE_WIDTH, drawText, fixLifeLineHeights } from './svgDraw.js';
|
import svgDraw, { ACTOR_TYPE_WIDTH, drawText, fixLifeLineHeights } from './svgDraw.js';
|
||||||
import { log } from '../../logger.js';
|
import { log } from '../../logger.js';
|
||||||
import common from '../common/common.js';
|
import common from '../common/common.js';
|
||||||
@ -622,10 +622,10 @@ const activationBounds = function (actor, actors) {
|
|||||||
|
|
||||||
const left = activations.reduce(function (acc, activation) {
|
const left = activations.reduce(function (acc, activation) {
|
||||||
return common.getMin(acc, activation.startx);
|
return common.getMin(acc, activation.startx);
|
||||||
}, actorObj.x + actorObj.width / 2);
|
}, actorObj.x + actorObj.width / 2 - 1);
|
||||||
const right = activations.reduce(function (acc, activation) {
|
const right = activations.reduce(function (acc, activation) {
|
||||||
return common.getMax(acc, activation.stopx);
|
return common.getMax(acc, activation.stopx);
|
||||||
}, actorObj.x + actorObj.width / 2);
|
}, actorObj.x + actorObj.width / 2 + 1);
|
||||||
return [left, right];
|
return [left, right];
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -1389,9 +1389,8 @@ const buildNoteModel = function (msg, actors, diagObj) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const buildMessageModel = function (msg, actors, diagObj) {
|
const buildMessageModel = function (msg, actors, diagObj) {
|
||||||
let process = false;
|
|
||||||
if (
|
if (
|
||||||
[
|
![
|
||||||
diagObj.db.LINETYPE.SOLID_OPEN,
|
diagObj.db.LINETYPE.SOLID_OPEN,
|
||||||
diagObj.db.LINETYPE.DOTTED_OPEN,
|
diagObj.db.LINETYPE.DOTTED_OPEN,
|
||||||
diagObj.db.LINETYPE.SOLID,
|
diagObj.db.LINETYPE.SOLID,
|
||||||
@ -1402,17 +1401,47 @@ const buildMessageModel = function (msg, actors, diagObj) {
|
|||||||
diagObj.db.LINETYPE.DOTTED_POINT,
|
diagObj.db.LINETYPE.DOTTED_POINT,
|
||||||
].includes(msg.type)
|
].includes(msg.type)
|
||||||
) {
|
) {
|
||||||
process = true;
|
|
||||||
}
|
|
||||||
if (!process) {
|
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
const fromBounds = activationBounds(msg.from, actors);
|
const [fromLeft, fromRight] = activationBounds(msg.from, actors);
|
||||||
const toBounds = activationBounds(msg.to, actors);
|
const [toLeft, toRight] = activationBounds(msg.to, actors);
|
||||||
const fromIdx = fromBounds[0] <= toBounds[0] ? 1 : 0;
|
const isArrowToRight = fromLeft <= toLeft;
|
||||||
const toIdx = fromBounds[0] < toBounds[0] ? 0 : 1;
|
const startx = isArrowToRight ? fromRight : fromLeft;
|
||||||
const allBounds = [...fromBounds, ...toBounds];
|
let stopx = isArrowToRight ? toLeft : toRight;
|
||||||
const boundedWidth = Math.abs(toBounds[toIdx] - fromBounds[fromIdx]);
|
|
||||||
|
// As the line width is considered, the left and right values will be off by 2.
|
||||||
|
const isArrowToActivation = Math.abs(toLeft - toRight) > 2;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adjust the value based on the arrow direction
|
||||||
|
* @param value - The value to adjust
|
||||||
|
* @returns The adjustment with correct sign to be added to the actual value.
|
||||||
|
*/
|
||||||
|
const adjustValue = (value: number) => {
|
||||||
|
return isArrowToRight ? -value : value;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This is an edge case for the first activation.
|
||||||
|
* Proper fix would require significant changes.
|
||||||
|
* So, we set an activate flag in the message, and cross check that with isToActivation
|
||||||
|
* In cases where the message is to an activation that was properly detected, we don't want to move the arrow head
|
||||||
|
* The activation will not be detected on the first message, so we need to move the arrow head
|
||||||
|
*/
|
||||||
|
if (msg.activate && !isArrowToActivation) {
|
||||||
|
stopx += adjustValue(conf.activationWidth / 2 - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Shorten the length of arrow at the end and move the marker forward (using refX) to have a clean arrowhead
|
||||||
|
* This is not required for open arrows that don't have arrowheads
|
||||||
|
*/
|
||||||
|
if (![diagObj.db.LINETYPE.SOLID_OPEN, diagObj.db.LINETYPE.DOTTED_OPEN].includes(msg.type)) {
|
||||||
|
stopx += adjustValue(3);
|
||||||
|
}
|
||||||
|
|
||||||
|
const allBounds = [fromLeft, fromRight, toLeft, toRight];
|
||||||
|
const boundedWidth = Math.abs(startx - stopx);
|
||||||
if (msg.wrap && msg.message) {
|
if (msg.wrap && msg.message) {
|
||||||
msg.message = utils.wrapLabel(
|
msg.message = utils.wrapLabel(
|
||||||
msg.message,
|
msg.message,
|
||||||
@ -1429,8 +1458,8 @@ const buildMessageModel = function (msg, actors, diagObj) {
|
|||||||
conf.width
|
conf.width
|
||||||
),
|
),
|
||||||
height: 0,
|
height: 0,
|
||||||
startx: fromBounds[fromIdx],
|
startx,
|
||||||
stopx: toBounds[toIdx],
|
stopx,
|
||||||
starty: 0,
|
starty: 0,
|
||||||
stopy: 0,
|
stopy: 0,
|
||||||
message: msg.message,
|
message: msg.message,
|
||||||
|
@ -703,7 +703,7 @@ export const insertArrowHead = function (elem) {
|
|||||||
.append('defs')
|
.append('defs')
|
||||||
.append('marker')
|
.append('marker')
|
||||||
.attr('id', 'arrowhead')
|
.attr('id', 'arrowhead')
|
||||||
.attr('refX', 9)
|
.attr('refX', 7.9)
|
||||||
.attr('refY', 5)
|
.attr('refY', 5)
|
||||||
.attr('markerUnits', 'userSpaceOnUse')
|
.attr('markerUnits', 'userSpaceOnUse')
|
||||||
.attr('markerWidth', 12)
|
.attr('markerWidth', 12)
|
||||||
@ -723,7 +723,7 @@ export const insertArrowFilledHead = function (elem) {
|
|||||||
.append('defs')
|
.append('defs')
|
||||||
.append('marker')
|
.append('marker')
|
||||||
.attr('id', 'filled-head')
|
.attr('id', 'filled-head')
|
||||||
.attr('refX', 18)
|
.attr('refX', 15.5)
|
||||||
.attr('refY', 7)
|
.attr('refY', 7)
|
||||||
.attr('markerWidth', 20)
|
.attr('markerWidth', 20)
|
||||||
.attr('markerHeight', 28)
|
.attr('markerHeight', 28)
|
||||||
@ -768,7 +768,7 @@ export const insertArrowCrossHead = function (elem) {
|
|||||||
.attr('markerHeight', 8)
|
.attr('markerHeight', 8)
|
||||||
.attr('orient', 'auto')
|
.attr('orient', 'auto')
|
||||||
.attr('refX', 4)
|
.attr('refX', 4)
|
||||||
.attr('refY', 5);
|
.attr('refY', 4.5);
|
||||||
// The cross
|
// The cross
|
||||||
marker
|
marker
|
||||||
.append('path')
|
.append('path')
|
||||||
|
@ -11,7 +11,7 @@ import {
|
|||||||
clear as commonClear,
|
clear as commonClear,
|
||||||
setDiagramTitle,
|
setDiagramTitle,
|
||||||
getDiagramTitle,
|
getDiagramTitle,
|
||||||
} from '../../commonDb.js';
|
} from '../common/commonDb.js';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
DEFAULT_DIAGRAM_DIRECTION,
|
DEFAULT_DIAGRAM_DIRECTION,
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
import { parser as timeline } from './parser/timeline.jison';
|
import { parser as timeline } from './parser/timeline.jison';
|
||||||
import * as timelineDB from './timelineDb.js';
|
import * as timelineDB from './timelineDb.js';
|
||||||
// import { injectUtils } from './mermaidUtils.js';
|
// import { injectUtils } from './mermaidUtils.js';
|
||||||
import * as _commonDb from '../../commonDb.js';
|
|
||||||
import { parseDirective as _parseDirective } from '../../directiveUtils.js';
|
import { parseDirective as _parseDirective } from '../../directiveUtils.js';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
@ -18,7 +17,6 @@ import {
|
|||||||
// getConfig,
|
// getConfig,
|
||||||
// sanitizeText,
|
// sanitizeText,
|
||||||
// setupGraphViewBox,
|
// setupGraphViewBox,
|
||||||
// _commonDb,
|
|
||||||
// _parseDirective
|
// _parseDirective
|
||||||
// );
|
// );
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { parseDirective as _parseDirective } from '../../directiveUtils.js';
|
import { parseDirective as _parseDirective } from '../../directiveUtils.js';
|
||||||
import * as commonDb from '../../commonDb.js';
|
import * as commonDb from '../common/commonDb.js';
|
||||||
let currentSection = '';
|
let currentSection = '';
|
||||||
let currentTaskId = 0;
|
let currentTaskId = 0;
|
||||||
|
|
||||||
|
@ -8,7 +8,7 @@ import {
|
|||||||
getAccDescription,
|
getAccDescription,
|
||||||
setAccDescription,
|
setAccDescription,
|
||||||
clear as commonClear,
|
clear as commonClear,
|
||||||
} from '../../commonDb.js';
|
} from '../common/commonDb.js';
|
||||||
|
|
||||||
let currentSection = '';
|
let currentSection = '';
|
||||||
|
|
||||||
|
@ -31,7 +31,7 @@ Once the release happens we add a tag to the `release` branch and merge it with
|
|||||||
2. Check out the `develop` branch
|
2. Check out the `develop` branch
|
||||||
3. Create a new branch for your work. Please name the branch following our naming convention below.
|
3. Create a new branch for your work. Please name the branch following our naming convention below.
|
||||||
|
|
||||||
We use the follow naming convention for branches:
|
We use the following naming convention for branches:
|
||||||
|
|
||||||
```txt
|
```txt
|
||||||
[feature | bug | chore | docs]/[issue number]_[short description using dashes ('-') or underscores ('_') instead of spaces]
|
[feature | bug | chore | docs]/[issue number]_[short description using dashes ('-') or underscores ('_') instead of spaces]
|
||||||
|
@ -16,7 +16,7 @@ In GitHub, you first **fork** a repository when you are going to make changes an
|
|||||||
|
|
||||||
Then you **clone** a copy to your local development machine (e.g. where you code) to make a copy with all the files to work with.
|
Then you **clone** a copy to your local development machine (e.g. where you code) to make a copy with all the files to work with.
|
||||||
|
|
||||||
[Fork mermaid](https://github.com/mermaid-js/mermaid/fork) to start contributing to the main project and its documentaion, or [search for other repositories](https://github.com/orgs/mermaid-js/repositories).
|
[Fork mermaid](https://github.com/mermaid-js/mermaid/fork) to start contributing to the main project and its documentation, or [search for other repositories](https://github.com/orgs/mermaid-js/repositories).
|
||||||
|
|
||||||
[Here is a GitHub document that gives an overview of the process.](https://docs.github.com/en/get-started/quickstart/fork-a-repo)
|
[Here is a GitHub document that gives an overview of the process.](https://docs.github.com/en/get-started/quickstart/fork-a-repo)
|
||||||
|
|
||||||
|
@ -16,7 +16,7 @@ In GitHub, you first **fork** a repository when you are going to make changes an
|
|||||||
|
|
||||||
Then you **clone** a copy to your local development machine (e.g. where you code) to make a copy with all the files to work with.
|
Then you **clone** a copy to your local development machine (e.g. where you code) to make a copy with all the files to work with.
|
||||||
|
|
||||||
[Fork mermaid](https://github.com/mermaid-js/mermaid/fork) to start contributing to the main project and its documentaion, or [search for other repositories](https://github.com/orgs/mermaid-js/repositories).
|
[Fork mermaid](https://github.com/mermaid-js/mermaid/fork) to start contributing to the main project and its documentation, or [search for other repositories](https://github.com/orgs/mermaid-js/repositories).
|
||||||
|
|
||||||
[Here is a GitHub document that gives an overview of the process.](https://docs.github.com/en/get-started/quickstart/fork-a-repo)
|
[Here is a GitHub document that gives an overview of the process.](https://docs.github.com/en/get-started/quickstart/fork-a-repo)
|
||||||
|
|
||||||
|
@ -13,7 +13,7 @@ For instance:
|
|||||||
|
|
||||||
#### Store data found during parsing
|
#### Store data found during parsing
|
||||||
|
|
||||||
There are some jison specific sub steps here where the parser stores the data encountered when parsing the diagram, this data is later used by the renderer. You can during the parsing call a object provided to the parser by the user of the parser. This object can be called during parsing for storing data.
|
There are some jison specific sub steps here where the parser stores the data encountered when parsing the diagram, this data is later used by the renderer. You can during the parsing call an object provided to the parser by the user of the parser. This object can be called during parsing for storing data.
|
||||||
|
|
||||||
```jison
|
```jison
|
||||||
statement
|
statement
|
||||||
@ -30,7 +30,7 @@ In the extract of the grammar above, it is defined that a call to the setTitle m
|
|||||||
Make sure that the `parseError` function for the parser is defined and calling `mermaid.parseError`. This way a common way of detecting parse errors is provided for the end-user.
|
Make sure that the `parseError` function for the parser is defined and calling `mermaid.parseError`. This way a common way of detecting parse errors is provided for the end-user.
|
||||||
```
|
```
|
||||||
|
|
||||||
For more info look in the example diagram type:
|
For more info look at the example diagram type:
|
||||||
|
|
||||||
The `yy` object has the following function:
|
The `yy` object has the following function:
|
||||||
|
|
||||||
@ -49,7 +49,7 @@ parser.yy = db;
|
|||||||
|
|
||||||
### Step 2: Rendering
|
### Step 2: Rendering
|
||||||
|
|
||||||
Write a renderer that given the data found during parsing renders the diagram. To look at an example look at sequenceRenderer.js rather then the flowchart renderer as this is a more generic example.
|
Write a renderer that given the data found during parsing renders the diagram. To look at an example look at sequenceRenderer.js rather than the flowchart renderer as this is a more generic example.
|
||||||
|
|
||||||
Place the renderer in the diagram folder.
|
Place the renderer in the diagram folder.
|
||||||
|
|
||||||
@ -57,7 +57,7 @@ Place the renderer in the diagram folder.
|
|||||||
|
|
||||||
The second thing to do is to add the capability to detect the new diagram to type to the detectType in `diagram-api/detectType.ts`. 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 `diagram-api/detectType.ts`. 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.
|
[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
|
For example, if your new diagram uses 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.
|
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.
|
||||||
|
|
||||||
Note that the diagram type key does not have to be the same as the diagram keyword chosen for the [grammar](#grammar), but it is helpful if they are the same.
|
Note that the diagram type key does not have to be the same as the diagram keyword chosen for the [grammar](#grammar), but it is helpful if they are the same.
|
||||||
@ -117,7 +117,7 @@ There are a few features that are common between the different types of diagrams
|
|||||||
- Themes, there is a common way to modify the styling of diagrams in Mermaid.
|
- Themes, there is a common way to modify the styling of diagrams in Mermaid.
|
||||||
- Comments should follow mermaid standards
|
- Comments should follow mermaid standards
|
||||||
|
|
||||||
Here some pointers on how to handle these different areas.
|
Here are some pointers on how to handle these different areas.
|
||||||
|
|
||||||
## Accessibility
|
## Accessibility
|
||||||
|
|
||||||
@ -135,7 +135,7 @@ See [the definition of aria-roledescription](https://www.w3.org/TR/wai-aria-1.1/
|
|||||||
|
|
||||||
### accessible title and description
|
### accessible title and description
|
||||||
|
|
||||||
The syntax for accessible titles and descriptions is described in [the Accessibility documenation section.](../config/accessibility.md)
|
The syntax for accessible titles and descriptions is described in [the Accessibility documentation section.](../config/accessibility.md)
|
||||||
|
|
||||||
As a design goal, the jison syntax should be similar between the diagrams.
|
As a design goal, the jison syntax should be similar between the diagrams.
|
||||||
|
|
||||||
|
@ -116,7 +116,7 @@ The following code snippet changes `theme` to `forest`:
|
|||||||
|
|
||||||
`%%{init: { "theme": "forest" } }%%`
|
`%%{init: { "theme": "forest" } }%%`
|
||||||
|
|
||||||
Possible theme values are: `default`,`base`, `dark`, `forest` and `neutral`.
|
Possible theme values are: `default`, `base`, `dark`, `forest` and `neutral`.
|
||||||
Default Value is `default`.
|
Default Value is `default`.
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
@ -235,7 +235,7 @@ Let us see an example:
|
|||||||
sequenceDiagram
|
sequenceDiagram
|
||||||
|
|
||||||
Alice->Bob: Hello Bob, how are you?
|
Alice->Bob: Hello Bob, how are you?
|
||||||
Bob->Alice: Fine, how did you mother like the book I suggested? And did you catch the new book about alien invasion?
|
Bob->Alice: Fine, how did your mother like the book I suggested? And did you catch the new book about alien invasion?
|
||||||
Alice->Bob: Good.
|
Alice->Bob: Good.
|
||||||
Bob->Alice: Cool
|
Bob->Alice: Cool
|
||||||
```
|
```
|
||||||
@ -252,7 +252,7 @@ By applying that snippet to the diagram above, `wrap` will be enabled:
|
|||||||
%%{init: { "sequence": { "wrap": true, "width":300 } } }%%
|
%%{init: { "sequence": { "wrap": true, "width":300 } } }%%
|
||||||
sequenceDiagram
|
sequenceDiagram
|
||||||
Alice->Bob: Hello Bob, how are you?
|
Alice->Bob: Hello Bob, how are you?
|
||||||
Bob->Alice: Fine, how did you mother like the book I suggested? And did you catch the new book about alien invasion?
|
Bob->Alice: Fine, how did your mother like the book I suggested? And did you catch the new book about alien invasion?
|
||||||
Alice->Bob: Good.
|
Alice->Bob: Good.
|
||||||
Bob->Alice: Cool
|
Bob->Alice: Cool
|
||||||
```
|
```
|
||||||
|
@ -35,7 +35,7 @@ pnpm add mermaid
|
|||||||
|
|
||||||
**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/getting-started.md)
|
> Note: This topic is explored in greater depth in the [User Guide for Beginners](../intro/getting-started.md)
|
||||||
|
|
||||||
The easiest way to integrate mermaid on a web page requires two elements:
|
The easiest way to integrate mermaid on a web page requires two elements:
|
||||||
|
|
||||||
@ -94,7 +94,7 @@ Mermaid can load multiple diagrams, in the same page.
|
|||||||
|
|
||||||
## Enabling Click Event and Tags in Nodes
|
## Enabling Click Event and Tags in Nodes
|
||||||
|
|
||||||
A `securityLevel` configuration has to first be cleared. `securityLevel` sets the level of trust for the parsed diagrams and limits click functionality. This was introduce in version 8.2 as a security improvement, aimed at preventing malicious use.
|
A `securityLevel` configuration has to first be cleared. `securityLevel` sets the level of trust for the parsed diagrams and limits click functionality. This was introduced in version 8.2 as a security improvement, aimed at preventing malicious use.
|
||||||
|
|
||||||
**It is the site owner's responsibility to discriminate between trustworthy and untrustworthy user-bases and we encourage the use of discretion.**
|
**It is the site owner's responsibility to discriminate between trustworthy and untrustworthy user-bases and we encourage the use of discretion.**
|
||||||
|
|
||||||
@ -109,14 +109,14 @@ Values:
|
|||||||
- **strict**: (**default**) HTML tags in the text are encoded and click functionality is disabled.
|
- **strict**: (**default**) HTML tags in the text are encoded and click functionality is disabled.
|
||||||
- **antiscript**: HTML tags in text are allowed (only script elements are removed) and click functionality is enabled.
|
- **antiscript**: HTML tags in text are allowed (only script elements are removed) and click functionality is enabled.
|
||||||
- **loose**: HTML tags in text are allowed and click functionality is enabled.
|
- **loose**: HTML tags in text are allowed and click functionality is enabled.
|
||||||
- **sandbox**: With this security level, all rendering takes place in a sandboxed iframe. This prevent any JavaScript from running in the context. This may hinder interactive functionality of the diagram, like scripts, popups in the sequence diagram, links to other tabs or targets, etc.
|
- **sandbox**: With this security level, all rendering takes place in a sandboxed iframe. This prevents any JavaScript from running in the context. This may hinder interactive functionality of the diagram, like scripts, popups in the sequence diagram, links to other tabs or targets, etc.
|
||||||
|
|
||||||
```note
|
```note
|
||||||
This changes the default behaviour of mermaid so that after upgrade to 8.2, unless the `securityLevel` is not changed, tags in flowcharts are encoded as tags and clicking is disabled.
|
This changes the default behaviour of mermaid so that after upgrade to 8.2, unless the `securityLevel` is not changed, tags in flowcharts are encoded as tags and clicking is disabled.
|
||||||
**sandbox** security level is still in the beta version.
|
**sandbox** security level is still in the beta version.
|
||||||
```
|
```
|
||||||
|
|
||||||
**If you are taking responsibility for the diagram source security you can set the `securityLevel` to a value of your choosing . This allows clicks and tags are allowed.**
|
**If you are taking responsibility for the diagram source security you can set the `securityLevel` to a value of your choosing. This allows clicks and tags are allowed.**
|
||||||
|
|
||||||
**To change `securityLevel`, you have to call `mermaid.initialize`:**
|
**To change `securityLevel`, you have to call `mermaid.initialize`:**
|
||||||
|
|
||||||
|
@ -43,6 +43,7 @@ They also serve as proof of concept, for the variety of things that can be built
|
|||||||
- [Mermaid plugin for GitBook](https://github.com/wwformat/gitbook-plugin-mermaid-pdf)
|
- [Mermaid plugin for GitBook](https://github.com/wwformat/gitbook-plugin-mermaid-pdf)
|
||||||
- [LiveBook](https://livebook.dev) (**Native support**)
|
- [LiveBook](https://livebook.dev) (**Native support**)
|
||||||
- [Atlassian Products](https://www.atlassian.com)
|
- [Atlassian Products](https://www.atlassian.com)
|
||||||
|
- [Mermaid Live Editor for Confluence Cloud](https://marketplace.atlassian.com/apps/1231571/mermaid-live-editor-for-confluence?hosting=cloud&tab=overview)
|
||||||
- [Mermaid Plugin for Confluence](https://marketplace.atlassian.com/apps/1214124/mermaid-plugin-for-confluence?hosting=server&tab=overview)
|
- [Mermaid Plugin for Confluence](https://marketplace.atlassian.com/apps/1214124/mermaid-plugin-for-confluence?hosting=server&tab=overview)
|
||||||
- [CloudScript.io Addon](https://marketplace.atlassian.com/apps/1219878/cloudscript-io-mermaid-addon?hosting=cloud&tab=overview)
|
- [CloudScript.io Addon](https://marketplace.atlassian.com/apps/1219878/cloudscript-io-mermaid-addon?hosting=cloud&tab=overview)
|
||||||
- [Auto convert diagrams in Jira](https://github.com/coddingtonbear/jirafs-mermaid)
|
- [Auto convert diagrams in Jira](https://github.com/coddingtonbear/jirafs-mermaid)
|
||||||
|
@ -86,7 +86,7 @@ When writing the .html file, we give two instructions inside the html code to th
|
|||||||
|
|
||||||
a. The mermaid code for the diagram we want to create.
|
a. The mermaid code for the diagram we want to create.
|
||||||
|
|
||||||
b. The importing of mermaid library through the `mermaid.esm.mjs` or `mermaid.esm.min.mjs` and the `mermaid.initialize()` call, which dictates the appearance of diagrams and also starts the rendering process .
|
b. The importing of mermaid library through the `mermaid.esm.mjs` or `mermaid.esm.min.mjs` and the `mermaid.initialize()` call, which dictates the appearance of diagrams and also starts the rendering process.
|
||||||
|
|
||||||
**a. The embedded mermaid diagram definition inside a `<pre class="mermaid">`:**
|
**a. The embedded mermaid diagram definition inside a `<pre class="mermaid">`:**
|
||||||
|
|
||||||
@ -204,4 +204,4 @@ In this example mermaid.js is referenced in `src` as a separate JavaScript file,
|
|||||||
|
|
||||||
**Comments from Knut Sveidqvist, creator of mermaid:**
|
**Comments from Knut Sveidqvist, creator of mermaid:**
|
||||||
|
|
||||||
- In early versions of mermaid, the `<script>` tag was invoked in the `<head>` part of the web page. Nowadays we can place it in the `<body>` as seen above. Older parts of the documentation frequently reflects the previous way which still works.
|
- In early versions of mermaid, the `<script>` tag was invoked in the `<head>` part of the web page. Nowadays we can place it in the `<body>` as seen above. Older parts of the documentation frequently reflect the previous way which still works.
|
||||||
|
@ -32,7 +32,7 @@
|
|||||||
"unplugin-vue-components": "^0.25.0",
|
"unplugin-vue-components": "^0.25.0",
|
||||||
"vite": "^4.3.9",
|
"vite": "^4.3.9",
|
||||||
"vite-plugin-pwa": "^0.16.0",
|
"vite-plugin-pwa": "^0.16.0",
|
||||||
"vitepress": "1.0.0-rc.4",
|
"vitepress": "1.0.0-rc.10",
|
||||||
"workbox-window": "^7.0.0"
|
"workbox-window": "^7.0.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -56,7 +56,7 @@ Mermaid syntax for ER diagrams is compatible with PlantUML, with an extension to
|
|||||||
|
|
||||||
Where:
|
Where:
|
||||||
|
|
||||||
- `first-entity` is the name of an entity. Names must begin with an alphabetic character and may also contain digits, hyphens, and underscores.
|
- `first-entity` is the name of an entity. Names must begin with an alphabetic character or an underscore (from v<MERMAID_RELEASE_VERSION>+), and may also contain digits and hyphens.
|
||||||
- `relationship` describes the way that both entities inter-relate. See below.
|
- `relationship` describes the way that both entities inter-relate. See below.
|
||||||
- `second-entity` is the name of the other entity.
|
- `second-entity` is the name of the other entity.
|
||||||
- `relationship-label` describes the relationship from the perspective of the first entity.
|
- `relationship-label` describes the relationship from the perspective of the first entity.
|
||||||
|
@ -709,9 +709,9 @@ flowchart LR
|
|||||||
classDef foobar stroke:#00f
|
classDef foobar stroke:#00f
|
||||||
```
|
```
|
||||||
|
|
||||||
### Css classes
|
### CSS classes
|
||||||
|
|
||||||
It is also possible to predefine classes in css styles that can be applied from the graph definition as in the example
|
It is also possible to predefine classes in CSS styles that can be applied from the graph definition as in the example
|
||||||
below:
|
below:
|
||||||
|
|
||||||
**Example style**
|
**Example style**
|
||||||
|
@ -31,7 +31,7 @@ mindmap
|
|||||||
|
|
||||||
The syntax for creating Mindmaps is simple and relies on indentation for setting the levels in the hierarchy.
|
The syntax for creating Mindmaps is simple and relies on indentation for setting the levels in the hierarchy.
|
||||||
|
|
||||||
In the following example you can see how there are 3 different levels. One with starting at the left of the text and another level with two rows starting at the same column, defining the node A. At the end there is one more level where the text is indented further then the previous lines defining the nodes B and C.
|
In the following example you can see how there are 3 different levels. One with starting at the left of the text and another level with two rows starting at the same column, defining the node A. At the end there is one more level where the text is indented further than the previous lines defining the nodes B and C.
|
||||||
|
|
||||||
```
|
```
|
||||||
mindmap
|
mindmap
|
||||||
@ -41,7 +41,7 @@ mindmap
|
|||||||
C
|
C
|
||||||
```
|
```
|
||||||
|
|
||||||
In summary is a simple text outline where there are one node at the root level called `Root` which has one child `A`. `A` in turn has two children `B`and `C`. In the diagram below we can see this rendered as a mindmap.
|
In summary is a simple text outline where there is one node at the root level called `Root` which has one child `A`. `A` in turn has two children `B`and `C`. In the diagram below we can see this rendered as a mindmap.
|
||||||
|
|
||||||
```mermaid
|
```mermaid
|
||||||
mindmap
|
mindmap
|
||||||
@ -142,7 +142,7 @@ _These classes need to be supplied by the site administrator._
|
|||||||
|
|
||||||
## Unclear indentation
|
## Unclear indentation
|
||||||
|
|
||||||
The actual indentation does not really matter only compared with the previous rows. If we take the previous example and disrupt it a little we can se how the calculations are performed. Let us start with placing C with a smaller indentation than `B`but larger then `A`.
|
The actual indentation does not really matter only compared with the previous rows. If we take the previous example and disrupt it a little we can see how the calculations are performed. Let us start with placing C with a smaller indentation than `B` but larger then `A`.
|
||||||
|
|
||||||
```
|
```
|
||||||
mindmap
|
mindmap
|
||||||
|
@ -24,8 +24,8 @@ quadrantChart
|
|||||||
## Syntax
|
## Syntax
|
||||||
|
|
||||||
```note
|
```note
|
||||||
If there is no points available in the chart both **axis** text and **quadrant** will be rendered in the center of the respective quadrant.
|
If there are no points available in the chart both **axis** text and **quadrant** will be rendered in the center of the respective quadrant.
|
||||||
If there are points **x-axis** labels will rendered from left of the respective quadrant also they will be displayed in bottom of the chart, and **y-axis** lables will be rendered in bottom of the respective quadrant, the quadrant text will render at top of the respective quadrant.
|
If there are points **x-axis** labels will rendered from the left of the respective quadrant also they will be displayed at the bottom of the chart, and **y-axis** labels will be rendered at the bottom of the respective quadrant, the quadrant text will render at the top of the respective quadrant.
|
||||||
```
|
```
|
||||||
|
|
||||||
```note
|
```note
|
||||||
@ -45,7 +45,7 @@ quadrantChart
|
|||||||
|
|
||||||
### x-axis
|
### x-axis
|
||||||
|
|
||||||
The x-axis determine what text would be displayed in the x-axis. In x-axis there is two part **left** and **right** you can pass **both** or you can pass only **left**. The statement should start with `x-axis` then the `left axis text` followed by the delimiter `-->` then `right axis text`.
|
The x-axis determines what text would be displayed in the x-axis. In x-axis there is two part **left** and **right** you can pass **both** or you can pass only **left**. The statement should start with `x-axis` then the `left axis text` followed by the delimiter `-->` then `right axis text`.
|
||||||
|
|
||||||
#### Example
|
#### Example
|
||||||
|
|
||||||
@ -54,7 +54,7 @@ The x-axis determine what text would be displayed in the x-axis. In x-axis there
|
|||||||
|
|
||||||
### y-axis
|
### y-axis
|
||||||
|
|
||||||
The y-axis determine what text would be displayed in the y-axis. In y-axis there is two part **top** and **bottom** you can pass **both** or you can pass only **bottom**. The statement should start with `y-axis` then the `bottom axis text` followed by the delimiter `-->` then `top axis text`.
|
The y-axis determines what text would be displayed in the y-axis. In y-axis there is two part **top** and **bottom** you can pass **both** or you can pass only **bottom**. The statement should start with `y-axis` then the `bottom axis text` followed by the delimiter `-->` then `top axis text`.
|
||||||
|
|
||||||
#### Example
|
#### Example
|
||||||
|
|
||||||
|
@ -109,7 +109,7 @@ Electricity grid,H2 conversion,27.14
|
|||||||
|
|
||||||
### Empty Lines
|
### Empty Lines
|
||||||
|
|
||||||
CSV does not support empty lines without comma delimeters by default. But you can add them if needed:
|
CSV does not support empty lines without comma delimiters by default. But you can add them if needed:
|
||||||
|
|
||||||
```mermaid-example
|
```mermaid-example
|
||||||
sankey-beta
|
sankey-beta
|
||||||
|
@ -121,7 +121,7 @@ end
|
|||||||
end
|
end
|
||||||
A->>J: Hello John, how are you?
|
A->>J: Hello John, how are you?
|
||||||
J->>A: Great!
|
J->>A: Great!
|
||||||
A->>B: Hello Bob, how is Charly ?
|
A->>B: Hello Bob, how is Charly?
|
||||||
B->>C: Hello Charly, how are you?
|
B->>C: Hello Charly, how are you?
|
||||||
```
|
```
|
||||||
|
|
||||||
|
284
pnpm-lock.yaml
generated
284
pnpm-lock.yaml
generated
@ -358,11 +358,11 @@ importers:
|
|||||||
specifier: ^4.1.0
|
specifier: ^4.1.0
|
||||||
version: 4.1.0
|
version: 4.1.0
|
||||||
typedoc:
|
typedoc:
|
||||||
specifier: ^0.24.5
|
specifier: ^0.25.0
|
||||||
version: 0.24.5(typescript@5.0.4)
|
version: 0.25.0(typescript@5.0.4)
|
||||||
typedoc-plugin-markdown:
|
typedoc-plugin-markdown:
|
||||||
specifier: ^3.15.2
|
specifier: ^3.15.2
|
||||||
version: 3.15.2(typedoc@0.24.5)
|
version: 3.15.2(typedoc@0.25.0)
|
||||||
typescript:
|
typescript:
|
||||||
specifier: ^5.0.4
|
specifier: ^5.0.4
|
||||||
version: 5.0.4
|
version: 5.0.4
|
||||||
@ -374,7 +374,7 @@ importers:
|
|||||||
version: 4.1.2
|
version: 4.1.2
|
||||||
vitepress:
|
vitepress:
|
||||||
specifier: ^1.0.0-alpha.72
|
specifier: ^1.0.0-alpha.72
|
||||||
version: 1.0.0-alpha.72(@algolia/client-search@4.14.2)(@types/node@18.16.0)
|
version: 1.0.0-alpha.72(@algolia/client-search@4.19.1)(@types/node@18.16.0)
|
||||||
vitepress-plugin-search:
|
vitepress-plugin-search:
|
||||||
specifier: ^1.0.4-alpha.20
|
specifier: ^1.0.4-alpha.20
|
||||||
version: 1.0.4-alpha.20(flexsearch@0.7.31)(vitepress@1.0.0-alpha.72)(vue@3.3.4)
|
version: 1.0.4-alpha.20(flexsearch@0.7.31)(vitepress@1.0.0-alpha.72)(vue@3.3.4)
|
||||||
@ -475,8 +475,8 @@ importers:
|
|||||||
specifier: ^0.16.0
|
specifier: ^0.16.0
|
||||||
version: 0.16.0(vite@4.3.9)(workbox-build@7.0.0)(workbox-window@7.0.0)
|
version: 0.16.0(vite@4.3.9)(workbox-build@7.0.0)(workbox-window@7.0.0)
|
||||||
vitepress:
|
vitepress:
|
||||||
specifier: 1.0.0-rc.4
|
specifier: 1.0.0-rc.10
|
||||||
version: 1.0.0-rc.4(@algolia/client-search@4.14.2)(@types/node@18.16.0)(search-insights@2.6.0)
|
version: 1.0.0-rc.10(@algolia/client-search@4.19.1)(@types/node@18.16.0)(search-insights@2.6.0)
|
||||||
workbox-window:
|
workbox-window:
|
||||||
specifier: ^7.0.0
|
specifier: ^7.0.0
|
||||||
version: 7.0.0
|
version: 7.0.0
|
||||||
@ -545,63 +545,63 @@ packages:
|
|||||||
'@algolia/autocomplete-shared': 1.8.2
|
'@algolia/autocomplete-shared': 1.8.2
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
/@algolia/autocomplete-core@1.9.3(@algolia/client-search@4.14.2)(algoliasearch@4.14.2)(search-insights@2.6.0):
|
/@algolia/autocomplete-core@1.9.3(@algolia/client-search@4.19.1)(algoliasearch@4.19.1)(search-insights@2.6.0):
|
||||||
resolution: {integrity: sha512-009HdfugtGCdC4JdXUbVJClA0q0zh24yyePn+KUGk3rP7j8FEe/m5Yo/z65gn6nP/cM39PxpzqKrL7A6fP6PPw==}
|
resolution: {integrity: sha512-009HdfugtGCdC4JdXUbVJClA0q0zh24yyePn+KUGk3rP7j8FEe/m5Yo/z65gn6nP/cM39PxpzqKrL7A6fP6PPw==}
|
||||||
dependencies:
|
dependencies:
|
||||||
'@algolia/autocomplete-plugin-algolia-insights': 1.9.3(@algolia/client-search@4.14.2)(algoliasearch@4.14.2)(search-insights@2.6.0)
|
'@algolia/autocomplete-plugin-algolia-insights': 1.9.3(@algolia/client-search@4.19.1)(algoliasearch@4.19.1)(search-insights@2.6.0)
|
||||||
'@algolia/autocomplete-shared': 1.9.3(@algolia/client-search@4.14.2)(algoliasearch@4.14.2)
|
'@algolia/autocomplete-shared': 1.9.3(@algolia/client-search@4.19.1)(algoliasearch@4.19.1)
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- '@algolia/client-search'
|
- '@algolia/client-search'
|
||||||
- algoliasearch
|
- algoliasearch
|
||||||
- search-insights
|
- search-insights
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
/@algolia/autocomplete-plugin-algolia-insights@1.9.3(@algolia/client-search@4.14.2)(algoliasearch@4.14.2)(search-insights@2.6.0):
|
/@algolia/autocomplete-plugin-algolia-insights@1.9.3(@algolia/client-search@4.19.1)(algoliasearch@4.19.1)(search-insights@2.6.0):
|
||||||
resolution: {integrity: sha512-a/yTUkcO/Vyy+JffmAnTWbr4/90cLzw+CC3bRbhnULr/EM0fGNvM13oQQ14f2moLMcVDyAx/leczLlAOovhSZg==}
|
resolution: {integrity: sha512-a/yTUkcO/Vyy+JffmAnTWbr4/90cLzw+CC3bRbhnULr/EM0fGNvM13oQQ14f2moLMcVDyAx/leczLlAOovhSZg==}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
search-insights: '>= 1 < 3'
|
search-insights: '>= 1 < 3'
|
||||||
dependencies:
|
dependencies:
|
||||||
'@algolia/autocomplete-shared': 1.9.3(@algolia/client-search@4.14.2)(algoliasearch@4.14.2)
|
'@algolia/autocomplete-shared': 1.9.3(@algolia/client-search@4.19.1)(algoliasearch@4.19.1)
|
||||||
search-insights: 2.6.0
|
search-insights: 2.6.0
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- '@algolia/client-search'
|
- '@algolia/client-search'
|
||||||
- algoliasearch
|
- algoliasearch
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
/@algolia/autocomplete-preset-algolia@1.8.2(@algolia/client-search@4.14.2)(algoliasearch@4.14.2):
|
/@algolia/autocomplete-preset-algolia@1.8.2(@algolia/client-search@4.19.1)(algoliasearch@4.14.2):
|
||||||
resolution: {integrity: sha512-J0oTx4me6ZM9kIKPuL3lyU3aB8DEvpVvR6xWmHVROx5rOYJGQcZsdG4ozxwcOyiiu3qxMkIbzntnV1S1VWD8yA==}
|
resolution: {integrity: sha512-J0oTx4me6ZM9kIKPuL3lyU3aB8DEvpVvR6xWmHVROx5rOYJGQcZsdG4ozxwcOyiiu3qxMkIbzntnV1S1VWD8yA==}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
'@algolia/client-search': '>= 4.9.1 < 6'
|
'@algolia/client-search': '>= 4.9.1 < 6'
|
||||||
algoliasearch: '>= 4.9.1 < 6'
|
algoliasearch: '>= 4.9.1 < 6'
|
||||||
dependencies:
|
dependencies:
|
||||||
'@algolia/autocomplete-shared': 1.8.2
|
'@algolia/autocomplete-shared': 1.8.2
|
||||||
'@algolia/client-search': 4.14.2
|
'@algolia/client-search': 4.19.1
|
||||||
algoliasearch: 4.14.2
|
algoliasearch: 4.14.2
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
/@algolia/autocomplete-preset-algolia@1.9.3(@algolia/client-search@4.14.2)(algoliasearch@4.14.2):
|
/@algolia/autocomplete-preset-algolia@1.9.3(@algolia/client-search@4.19.1)(algoliasearch@4.19.1):
|
||||||
resolution: {integrity: sha512-d4qlt6YmrLMYy95n5TB52wtNDr6EgAIPH81dvvvW8UmuWRgxEtY0NJiPwl/h95JtG2vmRM804M0DSwMCNZlzRA==}
|
resolution: {integrity: sha512-d4qlt6YmrLMYy95n5TB52wtNDr6EgAIPH81dvvvW8UmuWRgxEtY0NJiPwl/h95JtG2vmRM804M0DSwMCNZlzRA==}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
'@algolia/client-search': '>= 4.9.1 < 6'
|
'@algolia/client-search': '>= 4.9.1 < 6'
|
||||||
algoliasearch: '>= 4.9.1 < 6'
|
algoliasearch: '>= 4.9.1 < 6'
|
||||||
dependencies:
|
dependencies:
|
||||||
'@algolia/autocomplete-shared': 1.9.3(@algolia/client-search@4.14.2)(algoliasearch@4.14.2)
|
'@algolia/autocomplete-shared': 1.9.3(@algolia/client-search@4.19.1)(algoliasearch@4.19.1)
|
||||||
'@algolia/client-search': 4.14.2
|
'@algolia/client-search': 4.19.1
|
||||||
algoliasearch: 4.14.2
|
algoliasearch: 4.19.1
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
/@algolia/autocomplete-shared@1.8.2:
|
/@algolia/autocomplete-shared@1.8.2:
|
||||||
resolution: {integrity: sha512-b6Z/X4MczChMcfhk6kfRmBzPgjoPzuS9KGR4AFsiLulLNRAAqhP+xZTKtMnZGhLuc61I20d5WqlId02AZvcO6g==}
|
resolution: {integrity: sha512-b6Z/X4MczChMcfhk6kfRmBzPgjoPzuS9KGR4AFsiLulLNRAAqhP+xZTKtMnZGhLuc61I20d5WqlId02AZvcO6g==}
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
/@algolia/autocomplete-shared@1.9.3(@algolia/client-search@4.14.2)(algoliasearch@4.14.2):
|
/@algolia/autocomplete-shared@1.9.3(@algolia/client-search@4.19.1)(algoliasearch@4.19.1):
|
||||||
resolution: {integrity: sha512-Wnm9E4Ye6Rl6sTTqjoymD+l8DjSTHsHboVRYrKgEt8Q7UHm9nYbqhN/i0fhUYA3OAEH7WA8x3jfpnmJm3rKvaQ==}
|
resolution: {integrity: sha512-Wnm9E4Ye6Rl6sTTqjoymD+l8DjSTHsHboVRYrKgEt8Q7UHm9nYbqhN/i0fhUYA3OAEH7WA8x3jfpnmJm3rKvaQ==}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
'@algolia/client-search': '>= 4.9.1 < 6'
|
'@algolia/client-search': '>= 4.9.1 < 6'
|
||||||
algoliasearch: '>= 4.9.1 < 6'
|
algoliasearch: '>= 4.9.1 < 6'
|
||||||
dependencies:
|
dependencies:
|
||||||
'@algolia/client-search': 4.14.2
|
'@algolia/client-search': 4.19.1
|
||||||
algoliasearch: 4.14.2
|
algoliasearch: 4.19.1
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
/@algolia/cache-browser-local-storage@4.14.2:
|
/@algolia/cache-browser-local-storage@4.14.2:
|
||||||
@ -610,16 +610,32 @@ packages:
|
|||||||
'@algolia/cache-common': 4.14.2
|
'@algolia/cache-common': 4.14.2
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/@algolia/cache-browser-local-storage@4.19.1:
|
||||||
|
resolution: {integrity: sha512-FYAZWcGsFTTaSAwj9Std8UML3Bu8dyWDncM7Ls8g+58UOe4XYdlgzXWbrIgjaguP63pCCbMoExKr61B+ztK3tw==}
|
||||||
|
dependencies:
|
||||||
|
'@algolia/cache-common': 4.19.1
|
||||||
|
dev: true
|
||||||
|
|
||||||
/@algolia/cache-common@4.14.2:
|
/@algolia/cache-common@4.14.2:
|
||||||
resolution: {integrity: sha512-SbvAlG9VqNanCErr44q6lEKD2qoK4XtFNx9Qn8FK26ePCI8I9yU7pYB+eM/cZdS9SzQCRJBbHUumVr4bsQ4uxg==}
|
resolution: {integrity: sha512-SbvAlG9VqNanCErr44q6lEKD2qoK4XtFNx9Qn8FK26ePCI8I9yU7pYB+eM/cZdS9SzQCRJBbHUumVr4bsQ4uxg==}
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/@algolia/cache-common@4.19.1:
|
||||||
|
resolution: {integrity: sha512-XGghi3l0qA38HiqdoUY+wvGyBsGvKZ6U3vTiMBT4hArhP3fOGLXpIINgMiiGjTe4FVlTa5a/7Zf2bwlIHfRqqg==}
|
||||||
|
dev: true
|
||||||
|
|
||||||
/@algolia/cache-in-memory@4.14.2:
|
/@algolia/cache-in-memory@4.14.2:
|
||||||
resolution: {integrity: sha512-HrOukWoop9XB/VFojPv1R5SVXowgI56T9pmezd/djh2JnVN/vXswhXV51RKy4nCpqxyHt/aGFSq2qkDvj6KiuQ==}
|
resolution: {integrity: sha512-HrOukWoop9XB/VFojPv1R5SVXowgI56T9pmezd/djh2JnVN/vXswhXV51RKy4nCpqxyHt/aGFSq2qkDvj6KiuQ==}
|
||||||
dependencies:
|
dependencies:
|
||||||
'@algolia/cache-common': 4.14.2
|
'@algolia/cache-common': 4.14.2
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/@algolia/cache-in-memory@4.19.1:
|
||||||
|
resolution: {integrity: sha512-+PDWL+XALGvIginigzu8oU6eWw+o76Z8zHbBovWYcrtWOEtinbl7a7UTt3x3lthv+wNuFr/YD1Gf+B+A9V8n5w==}
|
||||||
|
dependencies:
|
||||||
|
'@algolia/cache-common': 4.19.1
|
||||||
|
dev: true
|
||||||
|
|
||||||
/@algolia/client-account@4.14.2:
|
/@algolia/client-account@4.14.2:
|
||||||
resolution: {integrity: sha512-WHtriQqGyibbb/Rx71YY43T0cXqyelEU0lB2QMBRXvD2X0iyeGl4qMxocgEIcbHyK7uqE7hKgjT8aBrHqhgc1w==}
|
resolution: {integrity: sha512-WHtriQqGyibbb/Rx71YY43T0cXqyelEU0lB2QMBRXvD2X0iyeGl4qMxocgEIcbHyK7uqE7hKgjT8aBrHqhgc1w==}
|
||||||
dependencies:
|
dependencies:
|
||||||
@ -628,6 +644,14 @@ packages:
|
|||||||
'@algolia/transporter': 4.14.2
|
'@algolia/transporter': 4.14.2
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/@algolia/client-account@4.19.1:
|
||||||
|
resolution: {integrity: sha512-Oy0ritA2k7AMxQ2JwNpfaEcgXEDgeyKu0V7E7xt/ZJRdXfEpZcwp9TOg4TJHC7Ia62gIeT2Y/ynzsxccPw92GA==}
|
||||||
|
dependencies:
|
||||||
|
'@algolia/client-common': 4.19.1
|
||||||
|
'@algolia/client-search': 4.19.1
|
||||||
|
'@algolia/transporter': 4.19.1
|
||||||
|
dev: true
|
||||||
|
|
||||||
/@algolia/client-analytics@4.14.2:
|
/@algolia/client-analytics@4.14.2:
|
||||||
resolution: {integrity: sha512-yBvBv2mw+HX5a+aeR0dkvUbFZsiC4FKSnfqk9rrfX+QrlNOKEhCG0tJzjiOggRW4EcNqRmaTULIYvIzQVL2KYQ==}
|
resolution: {integrity: sha512-yBvBv2mw+HX5a+aeR0dkvUbFZsiC4FKSnfqk9rrfX+QrlNOKEhCG0tJzjiOggRW4EcNqRmaTULIYvIzQVL2KYQ==}
|
||||||
dependencies:
|
dependencies:
|
||||||
@ -637,6 +661,15 @@ packages:
|
|||||||
'@algolia/transporter': 4.14.2
|
'@algolia/transporter': 4.14.2
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/@algolia/client-analytics@4.19.1:
|
||||||
|
resolution: {integrity: sha512-5QCq2zmgdZLIQhHqwl55ZvKVpLM3DNWjFI4T+bHr3rGu23ew2bLO4YtyxaZeChmDb85jUdPDouDlCumGfk6wOg==}
|
||||||
|
dependencies:
|
||||||
|
'@algolia/client-common': 4.19.1
|
||||||
|
'@algolia/client-search': 4.19.1
|
||||||
|
'@algolia/requester-common': 4.19.1
|
||||||
|
'@algolia/transporter': 4.19.1
|
||||||
|
dev: true
|
||||||
|
|
||||||
/@algolia/client-common@4.14.2:
|
/@algolia/client-common@4.14.2:
|
||||||
resolution: {integrity: sha512-43o4fslNLcktgtDMVaT5XwlzsDPzlqvqesRi4MjQz2x4/Sxm7zYg5LRYFol1BIhG6EwxKvSUq8HcC/KxJu3J0Q==}
|
resolution: {integrity: sha512-43o4fslNLcktgtDMVaT5XwlzsDPzlqvqesRi4MjQz2x4/Sxm7zYg5LRYFol1BIhG6EwxKvSUq8HcC/KxJu3J0Q==}
|
||||||
dependencies:
|
dependencies:
|
||||||
@ -644,6 +677,13 @@ packages:
|
|||||||
'@algolia/transporter': 4.14.2
|
'@algolia/transporter': 4.14.2
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/@algolia/client-common@4.19.1:
|
||||||
|
resolution: {integrity: sha512-3kAIVqTcPrjfS389KQvKzliC559x+BDRxtWamVJt8IVp7LGnjq+aVAXg4Xogkur1MUrScTZ59/AaUd5EdpyXgA==}
|
||||||
|
dependencies:
|
||||||
|
'@algolia/requester-common': 4.19.1
|
||||||
|
'@algolia/transporter': 4.19.1
|
||||||
|
dev: true
|
||||||
|
|
||||||
/@algolia/client-personalization@4.14.2:
|
/@algolia/client-personalization@4.14.2:
|
||||||
resolution: {integrity: sha512-ACCoLi0cL8CBZ1W/2juehSltrw2iqsQBnfiu/Rbl9W2yE6o2ZUb97+sqN/jBqYNQBS+o0ekTMKNkQjHHAcEXNw==}
|
resolution: {integrity: sha512-ACCoLi0cL8CBZ1W/2juehSltrw2iqsQBnfiu/Rbl9W2yE6o2ZUb97+sqN/jBqYNQBS+o0ekTMKNkQjHHAcEXNw==}
|
||||||
dependencies:
|
dependencies:
|
||||||
@ -652,6 +692,14 @@ packages:
|
|||||||
'@algolia/transporter': 4.14.2
|
'@algolia/transporter': 4.14.2
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/@algolia/client-personalization@4.19.1:
|
||||||
|
resolution: {integrity: sha512-8CWz4/H5FA+krm9HMw2HUQenizC/DxUtsI5oYC0Jxxyce1vsr8cb1aEiSJArQT6IzMynrERif1RVWLac1m36xw==}
|
||||||
|
dependencies:
|
||||||
|
'@algolia/client-common': 4.19.1
|
||||||
|
'@algolia/requester-common': 4.19.1
|
||||||
|
'@algolia/transporter': 4.19.1
|
||||||
|
dev: true
|
||||||
|
|
||||||
/@algolia/client-search@4.14.2:
|
/@algolia/client-search@4.14.2:
|
||||||
resolution: {integrity: sha512-L5zScdOmcZ6NGiVbLKTvP02UbxZ0njd5Vq9nJAmPFtjffUSOGEp11BmD2oMJ5QvARgx2XbX4KzTTNS5ECYIMWw==}
|
resolution: {integrity: sha512-L5zScdOmcZ6NGiVbLKTvP02UbxZ0njd5Vq9nJAmPFtjffUSOGEp11BmD2oMJ5QvARgx2XbX4KzTTNS5ECYIMWw==}
|
||||||
dependencies:
|
dependencies:
|
||||||
@ -660,32 +708,66 @@ packages:
|
|||||||
'@algolia/transporter': 4.14.2
|
'@algolia/transporter': 4.14.2
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/@algolia/client-search@4.19.1:
|
||||||
|
resolution: {integrity: sha512-mBecfMFS4N+yK/p0ZbK53vrZbL6OtWMk8YmnOv1i0LXx4pelY8TFhqKoTit3NPVPwoSNN0vdSN9dTu1xr1XOVw==}
|
||||||
|
dependencies:
|
||||||
|
'@algolia/client-common': 4.19.1
|
||||||
|
'@algolia/requester-common': 4.19.1
|
||||||
|
'@algolia/transporter': 4.19.1
|
||||||
|
dev: true
|
||||||
|
|
||||||
/@algolia/logger-common@4.14.2:
|
/@algolia/logger-common@4.14.2:
|
||||||
resolution: {integrity: sha512-/JGlYvdV++IcMHBnVFsqEisTiOeEr6cUJtpjz8zc0A9c31JrtLm318Njc72p14Pnkw3A/5lHHh+QxpJ6WFTmsA==}
|
resolution: {integrity: sha512-/JGlYvdV++IcMHBnVFsqEisTiOeEr6cUJtpjz8zc0A9c31JrtLm318Njc72p14Pnkw3A/5lHHh+QxpJ6WFTmsA==}
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/@algolia/logger-common@4.19.1:
|
||||||
|
resolution: {integrity: sha512-i6pLPZW/+/YXKis8gpmSiNk1lOmYCmRI6+x6d2Qk1OdfvX051nRVdalRbEcVTpSQX6FQAoyeaui0cUfLYW5Elw==}
|
||||||
|
dev: true
|
||||||
|
|
||||||
/@algolia/logger-console@4.14.2:
|
/@algolia/logger-console@4.14.2:
|
||||||
resolution: {integrity: sha512-8S2PlpdshbkwlLCSAB5f8c91xyc84VM9Ar9EdfE9UmX+NrKNYnWR1maXXVDQQoto07G1Ol/tYFnFVhUZq0xV/g==}
|
resolution: {integrity: sha512-8S2PlpdshbkwlLCSAB5f8c91xyc84VM9Ar9EdfE9UmX+NrKNYnWR1maXXVDQQoto07G1Ol/tYFnFVhUZq0xV/g==}
|
||||||
dependencies:
|
dependencies:
|
||||||
'@algolia/logger-common': 4.14.2
|
'@algolia/logger-common': 4.14.2
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/@algolia/logger-console@4.19.1:
|
||||||
|
resolution: {integrity: sha512-jj72k9GKb9W0c7TyC3cuZtTr0CngLBLmc8trzZlXdfvQiigpUdvTi1KoWIb2ZMcRBG7Tl8hSb81zEY3zI2RlXg==}
|
||||||
|
dependencies:
|
||||||
|
'@algolia/logger-common': 4.19.1
|
||||||
|
dev: true
|
||||||
|
|
||||||
/@algolia/requester-browser-xhr@4.14.2:
|
/@algolia/requester-browser-xhr@4.14.2:
|
||||||
resolution: {integrity: sha512-CEh//xYz/WfxHFh7pcMjQNWgpl4wFB85lUMRyVwaDPibNzQRVcV33YS+63fShFWc2+42YEipFGH2iPzlpszmDw==}
|
resolution: {integrity: sha512-CEh//xYz/WfxHFh7pcMjQNWgpl4wFB85lUMRyVwaDPibNzQRVcV33YS+63fShFWc2+42YEipFGH2iPzlpszmDw==}
|
||||||
dependencies:
|
dependencies:
|
||||||
'@algolia/requester-common': 4.14.2
|
'@algolia/requester-common': 4.14.2
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/@algolia/requester-browser-xhr@4.19.1:
|
||||||
|
resolution: {integrity: sha512-09K/+t7lptsweRTueHnSnmPqIxbHMowejAkn9XIcJMLdseS3zl8ObnS5GWea86mu3vy4+8H+ZBKkUN82Zsq/zg==}
|
||||||
|
dependencies:
|
||||||
|
'@algolia/requester-common': 4.19.1
|
||||||
|
dev: true
|
||||||
|
|
||||||
/@algolia/requester-common@4.14.2:
|
/@algolia/requester-common@4.14.2:
|
||||||
resolution: {integrity: sha512-73YQsBOKa5fvVV3My7iZHu1sUqmjjfs9TteFWwPwDmnad7T0VTCopttcsM3OjLxZFtBnX61Xxl2T2gmG2O4ehg==}
|
resolution: {integrity: sha512-73YQsBOKa5fvVV3My7iZHu1sUqmjjfs9TteFWwPwDmnad7T0VTCopttcsM3OjLxZFtBnX61Xxl2T2gmG2O4ehg==}
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/@algolia/requester-common@4.19.1:
|
||||||
|
resolution: {integrity: sha512-BisRkcWVxrDzF1YPhAckmi2CFYK+jdMT60q10d7z3PX+w6fPPukxHRnZwooiTUrzFe50UBmLItGizWHP5bDzVQ==}
|
||||||
|
dev: true
|
||||||
|
|
||||||
/@algolia/requester-node-http@4.14.2:
|
/@algolia/requester-node-http@4.14.2:
|
||||||
resolution: {integrity: sha512-oDbb02kd1o5GTEld4pETlPZLY0e+gOSWjWMJHWTgDXbv9rm/o2cF7japO6Vj1ENnrqWvLBmW1OzV9g6FUFhFXg==}
|
resolution: {integrity: sha512-oDbb02kd1o5GTEld4pETlPZLY0e+gOSWjWMJHWTgDXbv9rm/o2cF7japO6Vj1ENnrqWvLBmW1OzV9g6FUFhFXg==}
|
||||||
dependencies:
|
dependencies:
|
||||||
'@algolia/requester-common': 4.14.2
|
'@algolia/requester-common': 4.14.2
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/@algolia/requester-node-http@4.19.1:
|
||||||
|
resolution: {integrity: sha512-6DK52DHviBHTG2BK/Vv2GIlEw7i+vxm7ypZW0Z7vybGCNDeWzADx+/TmxjkES2h15+FZOqVf/Ja677gePsVItA==}
|
||||||
|
dependencies:
|
||||||
|
'@algolia/requester-common': 4.19.1
|
||||||
|
dev: true
|
||||||
|
|
||||||
/@algolia/transporter@4.14.2:
|
/@algolia/transporter@4.14.2:
|
||||||
resolution: {integrity: sha512-t89dfQb2T9MFQHidjHcfhh6iGMNwvuKUvojAj+JsrHAGbuSy7yE4BylhLX6R0Q1xYRoC4Vvv+O5qIw/LdnQfsQ==}
|
resolution: {integrity: sha512-t89dfQb2T9MFQHidjHcfhh6iGMNwvuKUvojAj+JsrHAGbuSy7yE4BylhLX6R0Q1xYRoC4Vvv+O5qIw/LdnQfsQ==}
|
||||||
dependencies:
|
dependencies:
|
||||||
@ -694,6 +776,14 @@ packages:
|
|||||||
'@algolia/requester-common': 4.14.2
|
'@algolia/requester-common': 4.14.2
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/@algolia/transporter@4.19.1:
|
||||||
|
resolution: {integrity: sha512-nkpvPWbpuzxo1flEYqNIbGz7xhfhGOKGAZS7tzC+TELgEmi7z99qRyTfNSUlW7LZmB3ACdnqAo+9A9KFBENviQ==}
|
||||||
|
dependencies:
|
||||||
|
'@algolia/cache-common': 4.19.1
|
||||||
|
'@algolia/logger-common': 4.19.1
|
||||||
|
'@algolia/requester-common': 4.19.1
|
||||||
|
dev: true
|
||||||
|
|
||||||
/@alloc/quick-lru@5.2.0:
|
/@alloc/quick-lru@5.2.0:
|
||||||
resolution: {integrity: sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==}
|
resolution: {integrity: sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==}
|
||||||
engines: {node: '>=10'}
|
engines: {node: '>=10'}
|
||||||
@ -1403,6 +1493,7 @@ packages:
|
|||||||
/@babel/plugin-proposal-async-generator-functions@7.20.7(@babel/core@7.12.3):
|
/@babel/plugin-proposal-async-generator-functions@7.20.7(@babel/core@7.12.3):
|
||||||
resolution: {integrity: sha512-xMbiLsn/8RK7Wq7VeVytytS2L6qE69bXPB10YCmMdDZbKF4okCqY74pI/jJQ/8U0b/F6NrT2+14b8/P9/3AMGA==}
|
resolution: {integrity: sha512-xMbiLsn/8RK7Wq7VeVytytS2L6qE69bXPB10YCmMdDZbKF4okCqY74pI/jJQ/8U0b/F6NrT2+14b8/P9/3AMGA==}
|
||||||
engines: {node: '>=6.9.0'}
|
engines: {node: '>=6.9.0'}
|
||||||
|
deprecated: This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-async-generator-functions instead.
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
'@babel/core': ^7.0.0-0
|
'@babel/core': ^7.0.0-0
|
||||||
dependencies:
|
dependencies:
|
||||||
@ -1418,6 +1509,7 @@ packages:
|
|||||||
/@babel/plugin-proposal-class-properties@7.18.6(@babel/core@7.12.3):
|
/@babel/plugin-proposal-class-properties@7.18.6(@babel/core@7.12.3):
|
||||||
resolution: {integrity: sha512-cumfXOF0+nzZrrN8Rf0t7M+tF6sZc7vhQwYQck9q1/5w2OExlD+b4v4RpMJFaV1Z7WcDRgO6FqvxqxGlwo+RHQ==}
|
resolution: {integrity: sha512-cumfXOF0+nzZrrN8Rf0t7M+tF6sZc7vhQwYQck9q1/5w2OExlD+b4v4RpMJFaV1Z7WcDRgO6FqvxqxGlwo+RHQ==}
|
||||||
engines: {node: '>=6.9.0'}
|
engines: {node: '>=6.9.0'}
|
||||||
|
deprecated: This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-class-properties instead.
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
'@babel/core': ^7.0.0-0
|
'@babel/core': ^7.0.0-0
|
||||||
dependencies:
|
dependencies:
|
||||||
@ -1431,6 +1523,7 @@ packages:
|
|||||||
/@babel/plugin-proposal-class-static-block@7.21.0(@babel/core@7.12.3):
|
/@babel/plugin-proposal-class-static-block@7.21.0(@babel/core@7.12.3):
|
||||||
resolution: {integrity: sha512-XP5G9MWNUskFuP30IfFSEFB0Z6HzLIUcjYM4bYOPHXl7eiJ9HFv8tWj6TXTN5QODiEhDZAeI4hLok2iHFFV4hw==}
|
resolution: {integrity: sha512-XP5G9MWNUskFuP30IfFSEFB0Z6HzLIUcjYM4bYOPHXl7eiJ9HFv8tWj6TXTN5QODiEhDZAeI4hLok2iHFFV4hw==}
|
||||||
engines: {node: '>=6.9.0'}
|
engines: {node: '>=6.9.0'}
|
||||||
|
deprecated: This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-class-static-block instead.
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
'@babel/core': ^7.12.0
|
'@babel/core': ^7.12.0
|
||||||
dependencies:
|
dependencies:
|
||||||
@ -1445,6 +1538,7 @@ packages:
|
|||||||
/@babel/plugin-proposal-dynamic-import@7.18.6(@babel/core@7.12.3):
|
/@babel/plugin-proposal-dynamic-import@7.18.6(@babel/core@7.12.3):
|
||||||
resolution: {integrity: sha512-1auuwmK+Rz13SJj36R+jqFPMJWyKEDd7lLSdOj4oJK0UTgGueSAtkrCvz9ewmgyU/P941Rv2fQwZJN8s6QruXw==}
|
resolution: {integrity: sha512-1auuwmK+Rz13SJj36R+jqFPMJWyKEDd7lLSdOj4oJK0UTgGueSAtkrCvz9ewmgyU/P941Rv2fQwZJN8s6QruXw==}
|
||||||
engines: {node: '>=6.9.0'}
|
engines: {node: '>=6.9.0'}
|
||||||
|
deprecated: This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-dynamic-import instead.
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
'@babel/core': ^7.0.0-0
|
'@babel/core': ^7.0.0-0
|
||||||
dependencies:
|
dependencies:
|
||||||
@ -1456,6 +1550,7 @@ packages:
|
|||||||
/@babel/plugin-proposal-export-namespace-from@7.18.9(@babel/core@7.12.3):
|
/@babel/plugin-proposal-export-namespace-from@7.18.9(@babel/core@7.12.3):
|
||||||
resolution: {integrity: sha512-k1NtHyOMvlDDFeb9G5PhUXuGj8m/wiwojgQVEhJ/fsVsMCpLyOP4h0uGEjYJKrRI+EVPlb5Jk+Gt9P97lOGwtA==}
|
resolution: {integrity: sha512-k1NtHyOMvlDDFeb9G5PhUXuGj8m/wiwojgQVEhJ/fsVsMCpLyOP4h0uGEjYJKrRI+EVPlb5Jk+Gt9P97lOGwtA==}
|
||||||
engines: {node: '>=6.9.0'}
|
engines: {node: '>=6.9.0'}
|
||||||
|
deprecated: This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-export-namespace-from instead.
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
'@babel/core': ^7.0.0-0
|
'@babel/core': ^7.0.0-0
|
||||||
dependencies:
|
dependencies:
|
||||||
@ -1467,6 +1562,7 @@ packages:
|
|||||||
/@babel/plugin-proposal-json-strings@7.18.6(@babel/core@7.12.3):
|
/@babel/plugin-proposal-json-strings@7.18.6(@babel/core@7.12.3):
|
||||||
resolution: {integrity: sha512-lr1peyn9kOdbYc0xr0OdHTZ5FMqS6Di+H0Fz2I/JwMzGmzJETNeOFq2pBySw6X/KFL5EWDjlJuMsUGRFb8fQgQ==}
|
resolution: {integrity: sha512-lr1peyn9kOdbYc0xr0OdHTZ5FMqS6Di+H0Fz2I/JwMzGmzJETNeOFq2pBySw6X/KFL5EWDjlJuMsUGRFb8fQgQ==}
|
||||||
engines: {node: '>=6.9.0'}
|
engines: {node: '>=6.9.0'}
|
||||||
|
deprecated: This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-json-strings instead.
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
'@babel/core': ^7.0.0-0
|
'@babel/core': ^7.0.0-0
|
||||||
dependencies:
|
dependencies:
|
||||||
@ -1478,6 +1574,7 @@ packages:
|
|||||||
/@babel/plugin-proposal-logical-assignment-operators@7.20.7(@babel/core@7.12.3):
|
/@babel/plugin-proposal-logical-assignment-operators@7.20.7(@babel/core@7.12.3):
|
||||||
resolution: {integrity: sha512-y7C7cZgpMIjWlKE5T7eJwp+tnRYM89HmRvWM5EQuB5BoHEONjmQ8lSNmBUwOyy/GFRsohJED51YBF79hE1djug==}
|
resolution: {integrity: sha512-y7C7cZgpMIjWlKE5T7eJwp+tnRYM89HmRvWM5EQuB5BoHEONjmQ8lSNmBUwOyy/GFRsohJED51YBF79hE1djug==}
|
||||||
engines: {node: '>=6.9.0'}
|
engines: {node: '>=6.9.0'}
|
||||||
|
deprecated: This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-logical-assignment-operators instead.
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
'@babel/core': ^7.0.0-0
|
'@babel/core': ^7.0.0-0
|
||||||
dependencies:
|
dependencies:
|
||||||
@ -1489,6 +1586,7 @@ packages:
|
|||||||
/@babel/plugin-proposal-nullish-coalescing-operator@7.18.6(@babel/core@7.12.3):
|
/@babel/plugin-proposal-nullish-coalescing-operator@7.18.6(@babel/core@7.12.3):
|
||||||
resolution: {integrity: sha512-wQxQzxYeJqHcfppzBDnm1yAY0jSRkUXR2z8RePZYrKwMKgMlE8+Z6LUno+bd6LvbGh8Gltvy74+9pIYkr+XkKA==}
|
resolution: {integrity: sha512-wQxQzxYeJqHcfppzBDnm1yAY0jSRkUXR2z8RePZYrKwMKgMlE8+Z6LUno+bd6LvbGh8Gltvy74+9pIYkr+XkKA==}
|
||||||
engines: {node: '>=6.9.0'}
|
engines: {node: '>=6.9.0'}
|
||||||
|
deprecated: This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-nullish-coalescing-operator instead.
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
'@babel/core': ^7.0.0-0
|
'@babel/core': ^7.0.0-0
|
||||||
dependencies:
|
dependencies:
|
||||||
@ -1500,6 +1598,7 @@ packages:
|
|||||||
/@babel/plugin-proposal-numeric-separator@7.18.6(@babel/core@7.12.3):
|
/@babel/plugin-proposal-numeric-separator@7.18.6(@babel/core@7.12.3):
|
||||||
resolution: {integrity: sha512-ozlZFogPqoLm8WBr5Z8UckIoE4YQ5KESVcNudyXOR8uqIkliTEgJ3RoketfG6pmzLdeZF0H/wjE9/cCEitBl7Q==}
|
resolution: {integrity: sha512-ozlZFogPqoLm8WBr5Z8UckIoE4YQ5KESVcNudyXOR8uqIkliTEgJ3RoketfG6pmzLdeZF0H/wjE9/cCEitBl7Q==}
|
||||||
engines: {node: '>=6.9.0'}
|
engines: {node: '>=6.9.0'}
|
||||||
|
deprecated: This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-numeric-separator instead.
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
'@babel/core': ^7.0.0-0
|
'@babel/core': ^7.0.0-0
|
||||||
dependencies:
|
dependencies:
|
||||||
@ -1511,6 +1610,7 @@ packages:
|
|||||||
/@babel/plugin-proposal-object-rest-spread@7.20.7(@babel/core@7.12.3):
|
/@babel/plugin-proposal-object-rest-spread@7.20.7(@babel/core@7.12.3):
|
||||||
resolution: {integrity: sha512-d2S98yCiLxDVmBmE8UjGcfPvNEUbA1U5q5WxaWFUGRzJSVAZqm5W6MbPct0jxnegUZ0niLeNX+IOzEs7wYg9Dg==}
|
resolution: {integrity: sha512-d2S98yCiLxDVmBmE8UjGcfPvNEUbA1U5q5WxaWFUGRzJSVAZqm5W6MbPct0jxnegUZ0niLeNX+IOzEs7wYg9Dg==}
|
||||||
engines: {node: '>=6.9.0'}
|
engines: {node: '>=6.9.0'}
|
||||||
|
deprecated: This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-object-rest-spread instead.
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
'@babel/core': ^7.0.0-0
|
'@babel/core': ^7.0.0-0
|
||||||
dependencies:
|
dependencies:
|
||||||
@ -1525,6 +1625,7 @@ packages:
|
|||||||
/@babel/plugin-proposal-optional-catch-binding@7.18.6(@babel/core@7.12.3):
|
/@babel/plugin-proposal-optional-catch-binding@7.18.6(@babel/core@7.12.3):
|
||||||
resolution: {integrity: sha512-Q40HEhs9DJQyaZfUjjn6vE8Cv4GmMHCYuMGIWUnlxH6400VGxOuwWsPt4FxXxJkC/5eOzgn0z21M9gMT4MOhbw==}
|
resolution: {integrity: sha512-Q40HEhs9DJQyaZfUjjn6vE8Cv4GmMHCYuMGIWUnlxH6400VGxOuwWsPt4FxXxJkC/5eOzgn0z21M9gMT4MOhbw==}
|
||||||
engines: {node: '>=6.9.0'}
|
engines: {node: '>=6.9.0'}
|
||||||
|
deprecated: This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-optional-catch-binding instead.
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
'@babel/core': ^7.0.0-0
|
'@babel/core': ^7.0.0-0
|
||||||
dependencies:
|
dependencies:
|
||||||
@ -1536,6 +1637,7 @@ packages:
|
|||||||
/@babel/plugin-proposal-optional-chaining@7.21.0(@babel/core@7.12.3):
|
/@babel/plugin-proposal-optional-chaining@7.21.0(@babel/core@7.12.3):
|
||||||
resolution: {integrity: sha512-p4zeefM72gpmEe2fkUr/OnOXpWEf8nAgk7ZYVqqfFiyIG7oFfVZcCrU64hWn5xp4tQ9LkV4bTIa5rD0KANpKNA==}
|
resolution: {integrity: sha512-p4zeefM72gpmEe2fkUr/OnOXpWEf8nAgk7ZYVqqfFiyIG7oFfVZcCrU64hWn5xp4tQ9LkV4bTIa5rD0KANpKNA==}
|
||||||
engines: {node: '>=6.9.0'}
|
engines: {node: '>=6.9.0'}
|
||||||
|
deprecated: This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-optional-chaining instead.
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
'@babel/core': ^7.0.0-0
|
'@babel/core': ^7.0.0-0
|
||||||
dependencies:
|
dependencies:
|
||||||
@ -1548,6 +1650,7 @@ packages:
|
|||||||
/@babel/plugin-proposal-private-methods@7.18.6(@babel/core@7.12.3):
|
/@babel/plugin-proposal-private-methods@7.18.6(@babel/core@7.12.3):
|
||||||
resolution: {integrity: sha512-nutsvktDItsNn4rpGItSNV2sz1XwS+nfU0Rg8aCx3W3NOKVzdMjJRu0O5OkgDp3ZGICSTbgRpxZoWsxoKRvbeA==}
|
resolution: {integrity: sha512-nutsvktDItsNn4rpGItSNV2sz1XwS+nfU0Rg8aCx3W3NOKVzdMjJRu0O5OkgDp3ZGICSTbgRpxZoWsxoKRvbeA==}
|
||||||
engines: {node: '>=6.9.0'}
|
engines: {node: '>=6.9.0'}
|
||||||
|
deprecated: This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-private-methods instead.
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
'@babel/core': ^7.0.0-0
|
'@babel/core': ^7.0.0-0
|
||||||
dependencies:
|
dependencies:
|
||||||
@ -1561,6 +1664,7 @@ packages:
|
|||||||
/@babel/plugin-proposal-private-property-in-object@7.21.0(@babel/core@7.12.3):
|
/@babel/plugin-proposal-private-property-in-object@7.21.0(@babel/core@7.12.3):
|
||||||
resolution: {integrity: sha512-ha4zfehbJjc5MmXBlHec1igel5TJXXLDDRbuJ4+XT2TJcyD9/V1919BA8gMvsdHcNMBy4WBUBiRb3nw/EQUtBw==}
|
resolution: {integrity: sha512-ha4zfehbJjc5MmXBlHec1igel5TJXXLDDRbuJ4+XT2TJcyD9/V1919BA8gMvsdHcNMBy4WBUBiRb3nw/EQUtBw==}
|
||||||
engines: {node: '>=6.9.0'}
|
engines: {node: '>=6.9.0'}
|
||||||
|
deprecated: This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-private-property-in-object instead.
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
'@babel/core': ^7.0.0-0
|
'@babel/core': ^7.0.0-0
|
||||||
dependencies:
|
dependencies:
|
||||||
@ -1576,6 +1680,7 @@ packages:
|
|||||||
/@babel/plugin-proposal-unicode-property-regex@7.18.6(@babel/core@7.12.3):
|
/@babel/plugin-proposal-unicode-property-regex@7.18.6(@babel/core@7.12.3):
|
||||||
resolution: {integrity: sha512-2BShG/d5yoZyXZfVePH91urL5wTG6ASZU9M4o03lKK8u8UW1y08OMttBSOADTcJrnPMpvDXRG3G8fyLh4ovs8w==}
|
resolution: {integrity: sha512-2BShG/d5yoZyXZfVePH91urL5wTG6ASZU9M4o03lKK8u8UW1y08OMttBSOADTcJrnPMpvDXRG3G8fyLh4ovs8w==}
|
||||||
engines: {node: '>=4'}
|
engines: {node: '>=4'}
|
||||||
|
deprecated: This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-unicode-property-regex instead.
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
'@babel/core': ^7.0.0-0
|
'@babel/core': ^7.0.0-0
|
||||||
dependencies:
|
dependencies:
|
||||||
@ -2827,14 +2932,14 @@ packages:
|
|||||||
resolution: {integrity: sha512-NaXVp3I8LdmJ54fn038KHgG7HmbIzZlKS2FkVf6mKcW5bYMJovkx4947joQyZk5yubxOZ+ddHSh79y39Aevufg==}
|
resolution: {integrity: sha512-NaXVp3I8LdmJ54fn038KHgG7HmbIzZlKS2FkVf6mKcW5bYMJovkx4947joQyZk5yubxOZ+ddHSh79y39Aevufg==}
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
/@docsearch/css@3.5.1:
|
/@docsearch/css@3.5.2:
|
||||||
resolution: {integrity: sha512-2Pu9HDg/uP/IT10rbQ+4OrTQuxIWdKVUEdcw9/w7kZJv9NeHS6skJx1xuRiFyoGKwAzcHXnLp7csE99sj+O1YA==}
|
resolution: {integrity: sha512-SPiDHaWKQZpwR2siD0KQUwlStvIAnEyK6tAE2h2Wuoq8ue9skzhlyVQ1ddzOxX6khULnAALDiR/isSF3bnuciA==}
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
/@docsearch/js@3.3.5(@algolia/client-search@4.14.2):
|
/@docsearch/js@3.3.5(@algolia/client-search@4.19.1):
|
||||||
resolution: {integrity: sha512-nZi074OCryZnzva2LNcbQkwBJIND6cvuFI4s1FIe6Ygf6n9g6B/IYUULXNx05rpoCZ+KEoEt3taROpsHBliuSw==}
|
resolution: {integrity: sha512-nZi074OCryZnzva2LNcbQkwBJIND6cvuFI4s1FIe6Ygf6n9g6B/IYUULXNx05rpoCZ+KEoEt3taROpsHBliuSw==}
|
||||||
dependencies:
|
dependencies:
|
||||||
'@docsearch/react': 3.3.5(@algolia/client-search@4.14.2)
|
'@docsearch/react': 3.3.5(@algolia/client-search@4.19.1)
|
||||||
preact: 10.11.0
|
preact: 10.11.0
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- '@algolia/client-search'
|
- '@algolia/client-search'
|
||||||
@ -2843,10 +2948,10 @@ packages:
|
|||||||
- react-dom
|
- react-dom
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
/@docsearch/js@3.5.1(@algolia/client-search@4.14.2)(search-insights@2.6.0):
|
/@docsearch/js@3.5.2(@algolia/client-search@4.19.1)(search-insights@2.6.0):
|
||||||
resolution: {integrity: sha512-EXi8de5njxgP6TV3N9ytnGRLG9zmBNTEZjR4VzwPcpPLbZxxTLG2gaFyJyKiFVQxHW/DPlMrDJA3qoRRGEkgZw==}
|
resolution: {integrity: sha512-p1YFTCDflk8ieHgFJYfmyHBki1D61+U9idwrLh+GQQMrBSP3DLGKpy0XUJtPjAOPltcVbqsTjiPFfH7JImjUNg==}
|
||||||
dependencies:
|
dependencies:
|
||||||
'@docsearch/react': 3.5.1(@algolia/client-search@4.14.2)(search-insights@2.6.0)
|
'@docsearch/react': 3.5.2(@algolia/client-search@4.19.1)(search-insights@2.6.0)
|
||||||
preact: 10.11.0
|
preact: 10.11.0
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- '@algolia/client-search'
|
- '@algolia/client-search'
|
||||||
@ -2856,7 +2961,7 @@ packages:
|
|||||||
- search-insights
|
- search-insights
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
/@docsearch/react@3.3.5(@algolia/client-search@4.14.2):
|
/@docsearch/react@3.3.5(@algolia/client-search@4.19.1):
|
||||||
resolution: {integrity: sha512-Zuxf4z5PZ9eIQkVCNu76v1H+KAztKItNn3rLzZa7kpBS+++TgNARITnZeUS7C1DKoAhJZFr6T/H+Lvc6h/iiYg==}
|
resolution: {integrity: sha512-Zuxf4z5PZ9eIQkVCNu76v1H+KAztKItNn3rLzZa7kpBS+++TgNARITnZeUS7C1DKoAhJZFr6T/H+Lvc6h/iiYg==}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
'@types/react': '>= 16.8.0 < 19.0.0'
|
'@types/react': '>= 16.8.0 < 19.0.0'
|
||||||
@ -2871,19 +2976,20 @@ packages:
|
|||||||
optional: true
|
optional: true
|
||||||
dependencies:
|
dependencies:
|
||||||
'@algolia/autocomplete-core': 1.8.2
|
'@algolia/autocomplete-core': 1.8.2
|
||||||
'@algolia/autocomplete-preset-algolia': 1.8.2(@algolia/client-search@4.14.2)(algoliasearch@4.14.2)
|
'@algolia/autocomplete-preset-algolia': 1.8.2(@algolia/client-search@4.19.1)(algoliasearch@4.14.2)
|
||||||
'@docsearch/css': 3.3.5
|
'@docsearch/css': 3.3.5
|
||||||
algoliasearch: 4.14.2
|
algoliasearch: 4.14.2
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- '@algolia/client-search'
|
- '@algolia/client-search'
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
/@docsearch/react@3.5.1(@algolia/client-search@4.14.2)(search-insights@2.6.0):
|
/@docsearch/react@3.5.2(@algolia/client-search@4.19.1)(search-insights@2.6.0):
|
||||||
resolution: {integrity: sha512-t5mEODdLzZq4PTFAm/dvqcvZFdPDMdfPE5rJS5SC8OUq9mPzxEy6b+9THIqNM9P0ocCb4UC5jqBrxKclnuIbzQ==}
|
resolution: {integrity: sha512-9Ahcrs5z2jq/DcAvYtvlqEBHImbm4YJI8M9y0x6Tqg598P40HTEkX7hsMcIuThI+hTFxRGZ9hll0Wygm2yEjng==}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
'@types/react': '>= 16.8.0 < 19.0.0'
|
'@types/react': '>= 16.8.0 < 19.0.0'
|
||||||
react: '>= 16.8.0 < 19.0.0'
|
react: '>= 16.8.0 < 19.0.0'
|
||||||
react-dom: '>= 16.8.0 < 19.0.0'
|
react-dom: '>= 16.8.0 < 19.0.0'
|
||||||
|
search-insights: '>= 1 < 3'
|
||||||
peerDependenciesMeta:
|
peerDependenciesMeta:
|
||||||
'@types/react':
|
'@types/react':
|
||||||
optional: true
|
optional: true
|
||||||
@ -2891,14 +2997,16 @@ packages:
|
|||||||
optional: true
|
optional: true
|
||||||
react-dom:
|
react-dom:
|
||||||
optional: true
|
optional: true
|
||||||
|
search-insights:
|
||||||
|
optional: true
|
||||||
dependencies:
|
dependencies:
|
||||||
'@algolia/autocomplete-core': 1.9.3(@algolia/client-search@4.14.2)(algoliasearch@4.14.2)(search-insights@2.6.0)
|
'@algolia/autocomplete-core': 1.9.3(@algolia/client-search@4.19.1)(algoliasearch@4.19.1)(search-insights@2.6.0)
|
||||||
'@algolia/autocomplete-preset-algolia': 1.9.3(@algolia/client-search@4.14.2)(algoliasearch@4.14.2)
|
'@algolia/autocomplete-preset-algolia': 1.9.3(@algolia/client-search@4.19.1)(algoliasearch@4.19.1)
|
||||||
'@docsearch/css': 3.5.1
|
'@docsearch/css': 3.5.2
|
||||||
algoliasearch: 4.14.2
|
algoliasearch: 4.19.1
|
||||||
|
search-insights: 2.6.0
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- '@algolia/client-search'
|
- '@algolia/client-search'
|
||||||
- search-insights
|
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
/@es-joy/jsdoccomment@0.39.4:
|
/@es-joy/jsdoccomment@0.39.4:
|
||||||
@ -5378,8 +5486,20 @@ packages:
|
|||||||
- vue
|
- vue
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
/@vueuse/integrations@10.3.0(focus-trap@7.5.2)(vue@3.3.4):
|
/@vueuse/core@10.4.1(vue@3.3.4):
|
||||||
resolution: {integrity: sha512-Jgiv7oFyIgC6BxmDtiyG/fxyGysIds00YaY7sefwbhCZ2/tjEx1W/1WcsISSJPNI30in28+HC2J4uuU8184ekg==}
|
resolution: {integrity: sha512-DkHIfMIoSIBjMgRRvdIvxsyboRZQmImofLyOHADqiVbQVilP8VVHDhBX2ZqoItOgu7dWa8oXiNnScOdPLhdEXg==}
|
||||||
|
dependencies:
|
||||||
|
'@types/web-bluetooth': 0.0.17
|
||||||
|
'@vueuse/metadata': 10.4.1
|
||||||
|
'@vueuse/shared': 10.4.1(vue@3.3.4)
|
||||||
|
vue-demi: 0.14.5(vue@3.3.4)
|
||||||
|
transitivePeerDependencies:
|
||||||
|
- '@vue/composition-api'
|
||||||
|
- vue
|
||||||
|
dev: true
|
||||||
|
|
||||||
|
/@vueuse/integrations@10.4.1(focus-trap@7.5.2)(vue@3.3.4):
|
||||||
|
resolution: {integrity: sha512-uRBPyG5Lxoh1A/J+boiioPT3ELEAPEo4t8W6Mr4yTKIQBeW/FcbsotZNPr4k9uz+3QEksMmflWloS9wCnypM7g==}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
async-validator: '*'
|
async-validator: '*'
|
||||||
axios: '*'
|
axios: '*'
|
||||||
@ -5419,8 +5539,8 @@ packages:
|
|||||||
universal-cookie:
|
universal-cookie:
|
||||||
optional: true
|
optional: true
|
||||||
dependencies:
|
dependencies:
|
||||||
'@vueuse/core': 10.3.0(vue@3.3.4)
|
'@vueuse/core': 10.4.1(vue@3.3.4)
|
||||||
'@vueuse/shared': 10.3.0(vue@3.3.4)
|
'@vueuse/shared': 10.4.1(vue@3.3.4)
|
||||||
focus-trap: 7.5.2
|
focus-trap: 7.5.2
|
||||||
vue-demi: 0.14.5(vue@3.3.4)
|
vue-demi: 0.14.5(vue@3.3.4)
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
@ -5436,6 +5556,10 @@ packages:
|
|||||||
resolution: {integrity: sha512-Ema3YhNOa4swDsV0V7CEY5JXvK19JI/o1szFO1iWxdFg3vhdFtCtSTP26PCvbUpnUtNHBY2wx5y3WDXND5Pvnw==}
|
resolution: {integrity: sha512-Ema3YhNOa4swDsV0V7CEY5JXvK19JI/o1szFO1iWxdFg3vhdFtCtSTP26PCvbUpnUtNHBY2wx5y3WDXND5Pvnw==}
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/@vueuse/metadata@10.4.1:
|
||||||
|
resolution: {integrity: sha512-2Sc8X+iVzeuMGHr6O2j4gv/zxvQGGOYETYXEc41h0iZXIRnRbJZGmY/QP8dvzqUelf8vg0p/yEA5VpCEu+WpZg==}
|
||||||
|
dev: true
|
||||||
|
|
||||||
/@vueuse/shared@10.1.0(vue@3.3.4):
|
/@vueuse/shared@10.1.0(vue@3.3.4):
|
||||||
resolution: {integrity: sha512-2X52ogu12i9DkKOQ01yeb/BKg9UO87RNnpm5sXkQvyORlbq8ONS5l39MYkjkeVWWjdT0teJru7a2S41dmHmqjQ==}
|
resolution: {integrity: sha512-2X52ogu12i9DkKOQ01yeb/BKg9UO87RNnpm5sXkQvyORlbq8ONS5l39MYkjkeVWWjdT0teJru7a2S41dmHmqjQ==}
|
||||||
dependencies:
|
dependencies:
|
||||||
@ -5454,6 +5578,15 @@ packages:
|
|||||||
- vue
|
- vue
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/@vueuse/shared@10.4.1(vue@3.3.4):
|
||||||
|
resolution: {integrity: sha512-vz5hbAM4qA0lDKmcr2y3pPdU+2EVw/yzfRsBdu+6+USGa4PxqSQRYIUC9/NcT06y+ZgaTsyURw2I9qOFaaXHAg==}
|
||||||
|
dependencies:
|
||||||
|
vue-demi: 0.14.5(vue@3.3.4)
|
||||||
|
transitivePeerDependencies:
|
||||||
|
- '@vue/composition-api'
|
||||||
|
- vue
|
||||||
|
dev: true
|
||||||
|
|
||||||
/@wdio/config@7.30.0(typescript@5.1.3):
|
/@wdio/config@7.30.0(typescript@5.1.3):
|
||||||
resolution: {integrity: sha512-/38rol9WCfFTMtXyd/C856/aexxIZnfVvXg7Fw2WXpqZ9qadLA+R4N35S2703n/RByjK/5XAYtHoljtvh3727w==}
|
resolution: {integrity: sha512-/38rol9WCfFTMtXyd/C856/aexxIZnfVvXg7Fw2WXpqZ9qadLA+R4N35S2703n/RByjK/5XAYtHoljtvh3727w==}
|
||||||
engines: {node: '>=12.0.0'}
|
engines: {node: '>=12.0.0'}
|
||||||
@ -5856,6 +5989,25 @@ packages:
|
|||||||
'@algolia/transporter': 4.14.2
|
'@algolia/transporter': 4.14.2
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/algoliasearch@4.19.1:
|
||||||
|
resolution: {integrity: sha512-IJF5b93b2MgAzcE/tuzW0yOPnuUyRgGAtaPv5UUywXM8kzqfdwZTO4sPJBzoGz1eOy6H9uEchsJsBFTELZSu+g==}
|
||||||
|
dependencies:
|
||||||
|
'@algolia/cache-browser-local-storage': 4.19.1
|
||||||
|
'@algolia/cache-common': 4.19.1
|
||||||
|
'@algolia/cache-in-memory': 4.19.1
|
||||||
|
'@algolia/client-account': 4.19.1
|
||||||
|
'@algolia/client-analytics': 4.19.1
|
||||||
|
'@algolia/client-common': 4.19.1
|
||||||
|
'@algolia/client-personalization': 4.19.1
|
||||||
|
'@algolia/client-search': 4.19.1
|
||||||
|
'@algolia/logger-common': 4.19.1
|
||||||
|
'@algolia/logger-console': 4.19.1
|
||||||
|
'@algolia/requester-browser-xhr': 4.19.1
|
||||||
|
'@algolia/requester-common': 4.19.1
|
||||||
|
'@algolia/requester-node-http': 4.19.1
|
||||||
|
'@algolia/transporter': 4.19.1
|
||||||
|
dev: true
|
||||||
|
|
||||||
/amdefine@1.0.1:
|
/amdefine@1.0.1:
|
||||||
resolution: {integrity: sha512-S2Hw0TtNkMJhIabBwIojKL9YHO5T0n5eNqWJ7Lrlel/zDbftQpxpapi8tZs3X1HWa+u+QeydGmzzNU0m09+Rcg==}
|
resolution: {integrity: sha512-S2Hw0TtNkMJhIabBwIojKL9YHO5T0n5eNqWJ7Lrlel/zDbftQpxpapi8tZs3X1HWa+u+QeydGmzzNU0m09+Rcg==}
|
||||||
engines: {node: '>=0.4.2'}
|
engines: {node: '>=0.4.2'}
|
||||||
@ -9350,7 +9502,7 @@ packages:
|
|||||||
dependencies:
|
dependencies:
|
||||||
foreground-child: 3.1.1
|
foreground-child: 3.1.1
|
||||||
jackspeak: 2.1.1
|
jackspeak: 2.1.1
|
||||||
minimatch: 9.0.0
|
minimatch: 9.0.1
|
||||||
minipass: 5.0.0
|
minipass: 5.0.0
|
||||||
path-scurry: 1.7.0
|
path-scurry: 1.7.0
|
||||||
dev: true
|
dev: true
|
||||||
@ -11974,15 +12126,15 @@ packages:
|
|||||||
brace-expansion: 2.0.1
|
brace-expansion: 2.0.1
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
/minimatch@9.0.0:
|
/minimatch@9.0.1:
|
||||||
resolution: {integrity: sha512-0jJj8AvgKqWN05mrwuqi8QYKx1WmYSUoKSxu5Qhs9prezTz10sxAHGNZe9J9cqIJzta8DWsleh2KaVaLl6Ru2w==}
|
resolution: {integrity: sha512-0jWhJpD/MdhPXwPuiRkCbfYfSKp2qnn2eOc279qI7f+osl/l+prKSrvhg157zSYvx/1nmgn2NqdT6k2Z7zSH9w==}
|
||||||
engines: {node: '>=16 || 14 >=14.17'}
|
engines: {node: '>=16 || 14 >=14.17'}
|
||||||
dependencies:
|
dependencies:
|
||||||
brace-expansion: 2.0.1
|
brace-expansion: 2.0.1
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
/minimatch@9.0.1:
|
/minimatch@9.0.3:
|
||||||
resolution: {integrity: sha512-0jWhJpD/MdhPXwPuiRkCbfYfSKp2qnn2eOc279qI7f+osl/l+prKSrvhg157zSYvx/1nmgn2NqdT6k2Z7zSH9w==}
|
resolution: {integrity: sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==}
|
||||||
engines: {node: '>=16 || 14 >=14.17'}
|
engines: {node: '>=16 || 14 >=14.17'}
|
||||||
dependencies:
|
dependencies:
|
||||||
brace-expansion: 2.0.1
|
brace-expansion: 2.0.1
|
||||||
@ -14764,35 +14916,35 @@ packages:
|
|||||||
is-typedarray: 1.0.0
|
is-typedarray: 1.0.0
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
/typedoc-plugin-markdown@3.15.2(typedoc@0.24.5):
|
/typedoc-plugin-markdown@3.15.2(typedoc@0.25.0):
|
||||||
resolution: {integrity: sha512-OPXAL9hhdoVJzH/UaKAz6CBS/s8KlYyLWwnxF7ap0fQCuaMMWShA1JBq4n1SXbiGjx+7DOhOfTKQ5OzwryN3Vw==}
|
resolution: {integrity: sha512-OPXAL9hhdoVJzH/UaKAz6CBS/s8KlYyLWwnxF7ap0fQCuaMMWShA1JBq4n1SXbiGjx+7DOhOfTKQ5OzwryN3Vw==}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
typedoc: '>=0.24.0'
|
typedoc: '>=0.24.0'
|
||||||
dependencies:
|
dependencies:
|
||||||
handlebars: 4.7.7
|
handlebars: 4.7.7
|
||||||
typedoc: 0.24.5(typescript@5.0.4)
|
typedoc: 0.25.0(typescript@5.0.4)
|
||||||
typedoc-plugin-mdn-links: 3.0.3(typedoc@0.24.5)
|
typedoc-plugin-mdn-links: 3.0.3(typedoc@0.25.0)
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
/typedoc-plugin-mdn-links@3.0.3(typedoc@0.24.5):
|
/typedoc-plugin-mdn-links@3.0.3(typedoc@0.25.0):
|
||||||
resolution: {integrity: sha512-NXhIpwQnsg7BcyMCHVqj3tUK+DL4g3Bt96JbFl4APzTGFkA+iM6GfZ/fn3TAqJ8O0CXG5R9BfWxolw1m1omNuQ==}
|
resolution: {integrity: sha512-NXhIpwQnsg7BcyMCHVqj3tUK+DL4g3Bt96JbFl4APzTGFkA+iM6GfZ/fn3TAqJ8O0CXG5R9BfWxolw1m1omNuQ==}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
typedoc: '>= 0.23.14 || 0.24.x'
|
typedoc: '>= 0.23.14 || 0.24.x'
|
||||||
dependencies:
|
dependencies:
|
||||||
typedoc: 0.24.5(typescript@5.0.4)
|
typedoc: 0.25.0(typescript@5.0.4)
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
/typedoc@0.24.5(typescript@5.0.4):
|
/typedoc@0.25.0(typescript@5.0.4):
|
||||||
resolution: {integrity: sha512-tE1YDRxOTwJ33HltVazKiADqy/CasUmd2UVMnGOS2kX5Oj7q4rDVsIlcC0j03K1h3lEkGtvEyusBF7Psz4F4kA==}
|
resolution: {integrity: sha512-FvCYWhO1n5jACE0C32qg6b3dSfQ8f2VzExnnRboowHtqUD6ARzM2r8YJeZFYXhcm2hI4C2oCRDgNPk/yaQUN9g==}
|
||||||
engines: {node: '>= 14.14'}
|
engines: {node: '>= 16'}
|
||||||
hasBin: true
|
hasBin: true
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
typescript: 4.6.x || 4.7.x || 4.8.x || 4.9.x || 5.0.x
|
typescript: 4.6.x || 4.7.x || 4.8.x || 4.9.x || 5.0.x || 5.1.x || 5.2.x
|
||||||
dependencies:
|
dependencies:
|
||||||
lunr: 2.3.9
|
lunr: 2.3.9
|
||||||
marked: 4.3.0
|
marked: 4.3.0
|
||||||
minimatch: 9.0.0
|
minimatch: 9.0.3
|
||||||
shiki: 0.14.1
|
shiki: 0.14.3
|
||||||
typescript: 5.0.4
|
typescript: 5.0.4
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
@ -15270,16 +15422,16 @@ packages:
|
|||||||
flexsearch: 0.7.31
|
flexsearch: 0.7.31
|
||||||
glob-to-regexp: 0.4.1
|
glob-to-regexp: 0.4.1
|
||||||
markdown-it: 13.0.1
|
markdown-it: 13.0.1
|
||||||
vitepress: 1.0.0-alpha.72(@algolia/client-search@4.14.2)(@types/node@18.16.0)
|
vitepress: 1.0.0-alpha.72(@algolia/client-search@4.19.1)(@types/node@18.16.0)
|
||||||
vue: 3.3.4
|
vue: 3.3.4
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
/vitepress@1.0.0-alpha.72(@algolia/client-search@4.14.2)(@types/node@18.16.0):
|
/vitepress@1.0.0-alpha.72(@algolia/client-search@4.19.1)(@types/node@18.16.0):
|
||||||
resolution: {integrity: sha512-Ou7fNE/OVYLrKGQMHSTVG6AcNsdv7tm4ACrdhx93SPMzEDj8UgIb4RFa5CTTowaYf3jeDGi2EAJlzXVC+IE3dg==}
|
resolution: {integrity: sha512-Ou7fNE/OVYLrKGQMHSTVG6AcNsdv7tm4ACrdhx93SPMzEDj8UgIb4RFa5CTTowaYf3jeDGi2EAJlzXVC+IE3dg==}
|
||||||
hasBin: true
|
hasBin: true
|
||||||
dependencies:
|
dependencies:
|
||||||
'@docsearch/css': 3.3.3
|
'@docsearch/css': 3.3.3
|
||||||
'@docsearch/js': 3.3.5(@algolia/client-search@4.14.2)
|
'@docsearch/js': 3.3.5(@algolia/client-search@4.19.1)
|
||||||
'@vitejs/plugin-vue': 4.2.3(vite@4.4.9)(vue@3.3.4)
|
'@vitejs/plugin-vue': 4.2.3(vite@4.4.9)(vue@3.3.4)
|
||||||
'@vue/devtools-api': 6.5.0
|
'@vue/devtools-api': 6.5.0
|
||||||
'@vueuse/core': 10.3.0(vue@3.3.4)
|
'@vueuse/core': 10.3.0(vue@3.3.4)
|
||||||
@ -15304,17 +15456,15 @@ packages:
|
|||||||
- terser
|
- terser
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
/vitepress@1.0.0-rc.4(@algolia/client-search@4.14.2)(@types/node@18.16.0)(search-insights@2.6.0):
|
/vitepress@1.0.0-rc.10(@algolia/client-search@4.19.1)(@types/node@18.16.0)(search-insights@2.6.0):
|
||||||
resolution: {integrity: sha512-JCQ89Bm6ECUTnyzyas3JENo00UDJeK8q1SUQyJYou+4Yz5BKEc/F3O21cu++DnUT2zXc0kvQ2Aj4BZCc/nioXQ==}
|
resolution: {integrity: sha512-+MsahIWqq5WUEmj6MR4obcKYbT7im07jZPCQPdNJExkeOSbOAJ4xypSLx88x7rvtzWHhHc5aXbOhCRvGEGjFrw==}
|
||||||
hasBin: true
|
hasBin: true
|
||||||
dependencies:
|
dependencies:
|
||||||
'@docsearch/css': 3.5.1
|
'@docsearch/css': 3.5.2
|
||||||
'@docsearch/js': 3.5.1(@algolia/client-search@4.14.2)(search-insights@2.6.0)
|
'@docsearch/js': 3.5.2(@algolia/client-search@4.19.1)(search-insights@2.6.0)
|
||||||
'@vitejs/plugin-vue': 4.2.3(vite@4.4.9)(vue@3.3.4)
|
|
||||||
'@vue/devtools-api': 6.5.0
|
'@vue/devtools-api': 6.5.0
|
||||||
'@vueuse/core': 10.3.0(vue@3.3.4)
|
'@vueuse/core': 10.4.1(vue@3.3.4)
|
||||||
'@vueuse/integrations': 10.3.0(focus-trap@7.5.2)(vue@3.3.4)
|
'@vueuse/integrations': 10.4.1(focus-trap@7.5.2)(vue@3.3.4)
|
||||||
body-scroll-lock: 4.0.0-beta.0
|
|
||||||
focus-trap: 7.5.2
|
focus-trap: 7.5.2
|
||||||
mark.js: 8.11.1
|
mark.js: 8.11.1
|
||||||
minisearch: 6.1.0
|
minisearch: 6.1.0
|
||||||
|
Loading…
x
Reference in New Issue
Block a user