diff --git a/.gitignore b/.gitignore
index 78e5cae..ba9f817 100644
--- a/.gitignore
+++ b/.gitignore
@@ -2,3 +2,4 @@
.DS_Store
xcuserdata
xcshareddata
+ephemeral
diff --git a/SequenceDiagram.xcworkspace/contents.xcworkspacedata b/SequenceDiagram.xcworkspace/contents.xcworkspacedata
index a8431d6..0ed3e16 100644
--- a/SequenceDiagram.xcworkspace/contents.xcworkspacedata
+++ b/SequenceDiagram.xcworkspace/contents.xcworkspacedata
@@ -7,18 +7,18 @@
+
+
+
+
-
-
-
-
diff --git a/docs/CONTRIBUTING.md b/docs/CONTRIBUTING.md
index cf0e7d1..3bcfac2 100644
--- a/docs/CONTRIBUTING.md
+++ b/docs/CONTRIBUTING.md
@@ -40,10 +40,10 @@ web modules unless a flag is set (FireFox 60 will support them fully).
The editor and library page do not require web modules, so should have
wider support.
-To run the linter, run the command:
+To run the non-browser tests and linter, run the command:
```shell
-npm run lint;
+npm test;
```
And to rebuild the minified sources, run:
@@ -52,7 +52,18 @@ And to rebuild the minified sources, run:
npm run minify;
```
-Currently there are no command-line tests; only the browser tests.
+## Commands
+
+The available commands are:
+
+* `npm start`: runs a webserver on
+ [localhost:8080](http://localhost:8080)
+* `npm test`: runs the `unit-test` and `lint` commands
+* `npm run unit-test`: runs non-browser-based unit tests in NodeJS
+* `npm run lint`: runs the linter against all source and test files
+* `npm run minify`: runs the `minify-lib` and `minify-web` commands
+* `npm run minify-lib`: minifies the library code in `/lib`
+* `npm run minify-web`: minifies the web code in `/weblib`
## Project Structure
@@ -78,18 +89,19 @@ Useful helpers can also be found in `/scripts/core/*` and
`/scripts/svg/*`.
The live editor (index.htm & editor-dev.htm) uses the source in
-`/scripts/editor.js` and `/scripts/interface/*`. Other pages use
-sources in the root of `/scripts` as their entry-points.
+`/web/editor.mjs` and `/web/interface/*`. Other pages use sources in
+the root of `/web` as their entry-points.
## Testing
The testing library used here is [Jasmine](https://jasmine.github.io/).
-All test files follow the naming convention of `_spec.js`,
-and must be listed in `/scripts/spec.js`. Linting automatically applies
-to all files with a `.js` extension.
+All test files follow the naming convention of `_spec.mjs`
+(commandline and browser) or `_webspec.mjs` (browser-only). Browser
+tests must be listed in `/spec/support/browser_specs.mjs`. Linting
+automatically applies to all files with a `.js` or `.mjs` extension.
-You can run the tests by opening `test.htm` in a browser.
+You can run the browser tests by opening `test.htm` in a browser.
The current state of automated testing is:
@@ -97,12 +109,12 @@ The current state of automated testing is:
* `Parser` and `Generator` stages have a good level of testing
* Rendering methods (SVG generation) have a minimal level of testing;
there are some high-level tests in
- `/scripts/sequence/SequenceDiagram_spec.js`, and a series of image
- comparison tests in `/scripts/sequence/Readme_spec.js` (testing that
+ `/scripts/sequence/SequenceDiagram_spec.mjs`, and a series of image
+ comparison tests in `/scripts/sequence/Readme_spec.mjs` (testing that
the readme screenshots roughly match the current behaviour). Finally
- `/scripts/sequence/SequenceDiagram_visual_spec.js` uses coarse image
+ `/scripts/sequence/SequenceDiagram_visual_spec.mjs` uses coarse image
comparison to test components and interactions using baseline SVGs
- from `test-images`.
+ from `spec/images`.
* The editor has a minimal level of testing.
If you suspect a failing test is not related to your changes, you can
@@ -129,7 +141,7 @@ polyfils are included.
### Testing & Linting
Ensure that all unit tests are passing and files pass linting. This can
-be done by opening `test.htm` in a browser and running `npm run lint`
+be done by opening `test.htm` in a browser and running `npm test`
in a command window. At a minimum, you should ensure that tests are
passing in Google Chrome, but testing in other supported browsers is
even better.
@@ -150,7 +162,7 @@ npm run minify;
```
This will update the files in `/lib` and `/weblib`. The minified code
-is a self-contained copy of the `/scripts/sequence/SequenceDiagram.js`
+is a self-contained copy of the `/scripts/sequence/SequenceDiagram.mjs`
script, with some boiler-plate added to allow loading into a page in a
variety of ways.
diff --git a/docs/PULL_REQUEST_TEMPLATE.md b/docs/PULL_REQUEST_TEMPLATE.md
index 46ce4cd..ea15337 100644
--- a/docs/PULL_REQUEST_TEMPLATE.md
+++ b/docs/PULL_REQUEST_TEMPLATE.md
@@ -3,7 +3,7 @@ reference it with #issue-number.
Checklist: (tick with [x])
-- [ ] Any new spec files are listed in `scripts/specs.js`.
+- [ ] Any new spec files are listed in `spec/support/browser_specs.mjs`.
- [ ] Tests are passing in Google Chrome.
- [ ] Linting is passing (`npm run lint`)
- [ ] No dead code is left behind.
diff --git a/editor-dev.htm b/editor-dev.htm
index bf366b4..934bff6 100644
--- a/editor-dev.htm
+++ b/editor-dev.htm
@@ -67,7 +67,7 @@
data-integrity="sha256-HYX1RusN7a369vYuOd1mGvxLcNL4z/MihkahAI2CH8k="
>
-
+
diff --git a/lib/sequence-diagram.js b/lib/sequence-diagram.js
index fc2030d..8cb854e 100644
--- a/lib/sequence-diagram.js
+++ b/lib/sequence-diagram.js
@@ -1239,8 +1239,19 @@
}
}
+ const nodejs = (typeof window === 'undefined');
+
// Thanks, https://stackoverflow.com/a/23522755/1180785
- const safari = (/^((?!chrome|android).)*safari/i).test(navigator.userAgent);
+ const safari = (
+ !nodejs &&
+ (/^((?!chrome|android).)*safari/i).test(window.navigator.userAgent)
+ );
+
+ // Thanks, https://stackoverflow.com/a/9851769/1180785
+ const firefox = (
+ !nodejs &&
+ typeof window.InstallTrigger !== 'undefined'
+ );
class Exporter {
constructor() {
@@ -6620,9 +6631,6 @@
}
}
- // Thanks, https://stackoverflow.com/a/9851769/1180785
- const firefox = (typeof window.InstallTrigger !== 'undefined');
-
function merge(state, newState) {
for(const k in state) {
if(Object.prototype.hasOwnProperty.call(state, k)) {
@@ -7115,16 +7123,16 @@
return this.dom.el(tag, namespace);
}
- box(attrs, position) {
- return this.el('rect').attrs(attrs).attrs(position);
+ box(attrs, {height, width, x, y}) {
+ return this.el('rect').attrs(attrs).attrs({height, width, x, y});
}
boxFactory(attrs) {
return this.box.bind(this, attrs);
}
- line(attrs, position) {
- return this.el('line').attrs(attrs).attrs(position);
+ line(attrs, {x1, x2, y1, y2}) {
+ return this.el('line').attrs(attrs).attrs({x1, x2, y1, y2});
}
lineFactory(attrs) {
@@ -7160,11 +7168,11 @@
return this.cross.bind(this, attrs);
}
- note(attrs, flickAttrs, position) {
- const x0 = position.x;
- const x1 = position.x + position.width;
- const y0 = position.y;
- const y1 = position.y + position.height;
+ note(attrs, flickAttrs, {height, width, x, y}) {
+ const x0 = x;
+ const x1 = x + width;
+ const y0 = y;
+ const y1 = y + height;
const flick = 7;
return this.el('g').add(
@@ -7191,13 +7199,13 @@
return this.note.bind(this, attrs, flickAttrs);
}
- formattedText(attrs = {}, formatted = [], position = {}) {
+ formattedText(attrs = {}, formatted = [], {x, y} = {}) {
const container = this.el('g');
const txt = new SVGTextBlock(container, this, {
attrs,
formatted,
- x: position.x,
- y: position.y,
+ x,
+ y,
});
return Object.assign(container, {
set: (state) => txt.set(state),
@@ -9544,7 +9552,9 @@
function pickDocument(container) {
if(container) {
- return container.ownerDocument;
+ return container.ownerDocument || null;
+ } else if(typeof window === 'undefined') {
+ return null;
} else {
return window.document;
}
@@ -9921,6 +9931,10 @@
convert(els);
}
+ function getDefaultThemeNames() {
+ return themes.map((theme) => theme.name);
+ }
+
Object.assign(SequenceDiagram, {
Exporter,
Generator,
@@ -9930,6 +9944,7 @@
convert,
convertAll,
extractCodeFromSVG,
+ getDefaultThemeNames,
registerCodeMirrorMode,
renderAll,
themes,
diff --git a/lib/sequence-diagram.min.js b/lib/sequence-diagram.min.js
index 39b5c6b..8e10225 100644
--- a/lib/sequence-diagram.min.js
+++ b/lib/sequence-diagram.min.js
@@ -1 +1 @@
-!function(){"use strict";function t(t,e,n=null){if(null===n)return t.indexOf(e);for(let s=0;s=t.length)return void s.push(n.slice());const r=t[e];if(!Array.isArray(r))return n.push(r),i(t,e+1,n,s),void n.pop();for(let a=0;a{n.push(...e(t))}),n}function o(t,e){const n=Ft[t.type];return!(!n||t.type!==e.type)&&!n.check.some(n=>t[n]!==e[n])}function h(t,n){Ft[t.type].merge.forEach(s=>{e(t[s],n[s])})}function l(t,e){for(let n=0;n{for(let s=0;st);return n.forEach(t=>{const s=Ft[t];s&&n.every(e=>t===e||s.siblings.has(e))&&e.add(t)}),e}function c(t,e,n,s){l(s,s=>{if(!t.has(s.type)||!e.has(s.type))return!1;for(let t=0;t{"agent begin"===t.type&&(t.mode=e,n=!0)}),n}return!1}function p(t,e,n,r=null){s(t,e,wt.equals),s(t,n,wt.equals);let i=0,a=t.length;if(r){const e=r.map(e=>wt.indexOf(t,e)).filter(t=>-1!==t);i=e.reduce((t,e)=>Math.min(t,e),t.length),a=e.reduce((t,e)=>Math.max(t,e),i)+1}return t.splice(i,0,e),t.splice(a+1,0,n),{indexL:i,indexR:a+1}}function f(t,e=!1){return{type:"string",suggest:e,then:Object.assign({"":0},t)}}function m(t,e){return t.v===e.v&&t.prefix===e.prefix&&t.suffix===e.suffix&&t.q===e.q}function b(t,e,n){let s=n.suggest;return Array.isArray(s)||(s=[s]),a(s,s=>!1===s?[]:"object"==typeof s?s.known?t["known"+s.known]||[]:[s]:"string"==typeof s&&s?[{v:s,q:""===e}]:[function(t,e){return Object.keys(e.then).length>0?{v:t,suffix:" ",q:!1}:{v:t,suffix:"\n",q:!1}}(e,n)])}function y(t,n){const s=[],i=r(n);return Object.keys(i.then).forEach(r=>{let a=i.then[r];"number"==typeof a&&(a=n[n.length-a-1]),e(s,b(t,r,a),m)}),s}function x(t,n,s,{suggest:r,override:i}){let a=null;"object"==typeof r&&r.known&&(a=r.known),n.type&&a!==n.type&&(i&&(n.type=i),e(t["known"+n.type],[{v:n.value,suffix:" ",q:!0}],m),n.type="",n.value=""),a&&(n.type=a,n.value&&(n.value+=s.s),n.value+=s.v)}function k(t,e,n){const s={type:"",value:""};let i=n;const a=[i];return t.line.forEach((e,n)=>{n===t.line.length-1&&(t.completions=y(t,a));const o=e.q?"":e.v;let h=i.then[o];void 0===h?(h=i.then[""],t.isVar=!0):t.isVar=e.q,"number"==typeof h?a.length-=h:a.push(h||Dt),i=r(a),x(t,s,e,i)}),e&&x(t,s,null,{}),t.nextCompletions=y(t,a),t.valid=Boolean(i.then["\n"])||0===Object.keys(i.then).length,i.type}function w(t){const e=t.baseToken||{};return{value:e.v||"",quoted:e.q||!1}}function v(t,e,n){return e.lastIndex=n,e.exec(t)}function A(t,e,n){return n?function(t,e,n){if(n.escape){const s=v(t,n.escape,e);if(s)return{appendSpace:"",appendValue:n.escapeWith(s),end:!1,newBlock:null,skip:s[0].length}}const s=v(t,n.end,e);return s?{appendSpace:"",appendValue:n.includeEnd?s[0]:"",end:!0,newBlock:null,skip:s[0].length}:{appendSpace:"",appendValue:t[e],end:!1,newBlock:null,skip:1}}(t,e,n):function(t,e){for(let n=0;n"}function R(t,e,n){const s=" "+t+" ";let r=-1,i=s.length,a=0;return Pt.forEach(({begin:t,end:o},h)=>{const l=n[h]?o:t;l.lastIndex=e;const d=l.exec(s);d&&(d.indexa)&&(r=h,i=d.index,a=l.lastIndex)}),{end:a-1,start:i,styleIndex:r}}function C(t,e){if(!t)return null;const n={};return e.forEach((t,e)=>{t&&Object.assign(n,Pt[e].attrs)}),n}function E(t){if(!t)return[];const e=Pt.map(()=>!1);let n=0,s=null;const r=[];return t.split("\n").forEach(t=>{const i=[];let a=0;for(;;){const{styleIndex:r,start:o,end:h}=R(t,a,e);if(-1===r)break;e[r]?(e[r]=!1,--n):(e[r]=!0,++n),o>a&&i.push({attrs:s,text:t.substring(a,o)}),s=C(n,e),a=h}a=n)&&(a=n),e>=a&&!i){let n=t[e];throw n||(n={b:r(t).e}),G("Missing agent name",n)}return{name:I(t,e,a),alias:I(t,a+1,n)}}(t,h,n,{enableAlias:i,allowBlankName:l});return{name:d,alias:g,flags:d?a:o}}function O(t,e,n,s){const r=[];let i=-1;for(let a=e;a{const r=t.get(e);(null===n||r.indexs.index)&&(s=r)}),{left:n.id,right:s.id}}function P(t=null,e=null){return null===t?e:null===e?t:Math.max(t,e)}function j(t,n){return e(t.agentIDs,n.agentIDs),{agentIDs:t.agentIDs,asynchronousY:P(t.asynchronousY,n.asynchronousY),topShift:Math.max(t.topShift,n.topShift),y:P(t.y,n.y)}}function q(t){return null===t?null:t.element?t.element:t}function Y(t,e,n){if(!Array.isArray(n))throw new Error("Invalid formatted text line: "+n);n.forEach(({text:n,attrs:s})=>{s?e.add(t.el("tspan").attrs(s).add(n)):e.add(n)})}function W(t,e){let n=null,s=null;return e.forEach(e=>{const r=t.get(e);(null===n||r.indexs.index)&&(s=r)}),{left:n.id,right:s.id}}function U(t,e){return t.v===e.v&&t.prefix===e.prefix&&t.suffix===e.suffix&&t.q===e.q}function X(t,e,n){const s=t.getLine(e),r={squash:{ch:n,line:e},word:{ch:n,line:e}};return n>0&&" "===s[n-1]&&($e.after.includes(s[n-2])&&r.word.ch--,r.squash.ch--),r}function Q(t,e,n){const s=function({v:t,q:e,prefix:n="",suffix:s=""},r){const i=r||!en.test(t)?r:'"';return n+(i&&e?i+t.replace(nn,"\\$&")+i:t)+s}(t,n),r=t.q?e.fromVar:e.fromKey;return"\n"===s?{className:"pick-virtual",displayFrom:null,displayText:"",from:r.squash,text:"\n",to:e.to.squash}:{className:null,displayFrom:r.word,displayText:s.trim(),from:$e.start.test(s)?r.squash:r.word,text:s,to:$e.end.test(s)?e.to.squash:e.to.word}}function J({global:t,prefix:e="",suffix:n=""},s){const r=s[t];return r?r.map(t=>({prefix:e,q:!0,suffix:n,v:t})):[]}function Z(t,n){const s=t.getCursor(),i=function(t,e){const n=t.getLineTokens(e.line);for(let t=0;t=e.ch){n.length=t+1;break}return n}(t,s),a=r(i)||t.getTokenAt(s),o=function(t,e){let n="",s=0,r=0;t.forEach(t=>{t.state.isVar?(n+=t.string,r=t.end):(n="",s=t.end)}),r>e.ch&&(n=n.substr(0,e.ch-s));const i=_e.exec(n);n=i[2];let a="";return tn.test(n)&&(a=n.charAt(0),n=n.substr(1)),{from:s+i[1].length,partial:n,quote:a,valid:r>=s}}(i,s),h=function(t,e){let n=t.string;t.end>e.ch&&(n=n.substr(0,e.ch-t.start));const s=_e.exec(n);return{from:t.start+s[1].length,partial:s[2],valid:!0}}(a,s),l=s.ch>0&&a.state.line.length>0;let d=l?a.state.completions:a.state.beginCompletions;l||(d=d.concat(a.state.knownAgent)),function(t,n={}){for(let s=0;s(t.q||!o.quote)&&function(t,e){return e.valid&&t.startsWith(e.partial)}(t.v,t.q?o:h)).map(t=>n.completeSingle||t.v!==(t.q?o:h).partial?Q(t,g,o.quote):(c=t,null)).filter(t=>null!==t);return c&&u.length>0&&u.unshift(Q(c,g,o.quote)),{from:function(t,e){let n=null;return t.forEach(({displayFrom:t})=>{t&&(!n||t.line>n.line||t.line===n.line&&t.ch>n.ch)&&(n=t)}),n||e.word}(u,g.fromKey),list:u,to:g.to.word}}function K(t,e="sequence"){const n=t||window.CodeMirror;n.defineMode(e,()=>on),n.registerHelper("hint",e,Z)}function _(t){const e=(new DOMParser).parseFromString(t,"image/svg+xml").querySelector("metadata");return e?e.textContent:""}function $(t){function e(t,e){n.push(e)}const n=[];if(t.forEach(t=>{t.addEventListener("error",e),t.optimisedRenderPreReflow()}),t.forEach(t=>{t.optimisedRenderReflow()}),t.forEach(t=>{t.optimisedRenderPostReflow(),t.removeEventListener("error",e)}),n.length>0)throw n}function tt(t,e=null,n={}){if("svg"===t.tagName)return null;const s=function(t){return{interactive:function(t){return void 0!==t&&"false"!==t}(t.dataset.sdInteractive),namespace:t.dataset.sdNamespace||null}}(t),r=new hn(null===e?t.textContent:e,Object.assign(s,n)),i=r.dom(),a=t.attributes;for(let t=0;ttt(t,s,e));return!1!==r.render&&$(n),n}return tt(t,s,r)}class nt{constructor(t,e){Array.isArray(e)?this.deltas=e:this.deltas=[0,2*-e/3,-e,2*-e/3,0,2*e/3,e,2*e/3],this.partWidth=t/this.deltas.length}getDelta(t){return this.deltas[t%this.deltas.length]}}class st{constructor(t){this.svg=t}reset(){}addDefs(){}getBlock(t){return this.blocks[t]||this.blocks[""]}getNote(t){return this.notes[t]||this.notes[""]}getDivider(t){return this.dividers[t]||this.dividers[""]}optionsAttributes(t,e){return function(t,e){const n=Object.assign({},t[""]);return e.forEach(e=>{Object.assign(n,t[e]||{})}),n}(t,e)}renderAgentLine({x:t,y0:e,y1:n,width:s,className:r,options:i}){const a=this.optionsAttributes(this.agentLineAttrs,i);return s>0?this.svg.box(a,{x:t-s/2,y:e,width:s,height:n-e}).addClass(r):this.svg.line(a,{x1:t,x2:t,y1:e,y2:n}).addClass(r)}renderArrowHead(t,{x:e,y:n,width:s,height:r,dir:i}){const a=s*i.dx,o=s*i.dy,h=.5*r*i.dx,l=.5*-r*i.dy;return this.svg.el("none"===t.fill?"polyline":"polygon").attr("points",e+a-l+" "+(n+o-h)+" "+e+" "+n+" "+(e+a+l)+" "+(n+o+h)).attrs(t)}renderTag(t,{x:e,y:n,width:s,height:r}){const{rx:i,ry:a}=t,o=e+s,h=n+r,l="M"+o+" "+n+"L"+o+" "+(h-a)+"L"+(o-i)+" "+h+"L"+e+" "+h,d=this.svg.el("g");return"none"!==t.fill&&d.add(this.svg.el("path").attr("d",l+"L"+e+" "+n).attrs(t).attr("stroke","none")),"none"!==t.stroke&&d.add(this.svg.el("path").attr("d",l).attrs(t).attr("fill","none")),d}renderDB(t,e){const n=t["db-z"];return this.svg.el("g").add(this.svg.box({rx:e.width/2,ry:n},e).attrs(t),this.svg.el("path").attr("d","M"+e.x+" "+(e.y+n)+"a"+e.width/2+" "+n+" 0 0 0 "+e.width+" 0").attrs(t).attr("fill","none"))}renderRef(t,e){return{shape:this.svg.box(t,e).attrs({fill:"none"}),mask:this.svg.box(t,e).attrs({fill:"#000000",stroke:"none"}),fill:this.svg.box(t,e).attrs({stroke:"none"})}}renderFlatConnect(t,e,{x1:n,y1:s,x2:r,y2:i}){return{shape:this.svg.el("path").attr("d",this.svg.patternedLine(t).move(n,s).line(r,i).cap().asPath()).attrs(e),p1:{x:n,y:s},p2:{x:r,y:i}}}renderRevConnect(t,e,{x1:n,y1:s,x2:r,y2:i,xR:a,rad:o}){const h=(i-s)/2,l=this.svg.patternedLine(t).move(n,s).line(a,s);return o0?this.svg.el("g").add(this.svg.line({fill:"none"},{x1:e,x2:e+(r-s)/2,y1:o,y2:o}).attrs(t),this.svg.line({fill:"none"},{x1:e+(r+s)/2,x2:e+r,y1:o,y2:o}).attrs(t)):this.svg.line({fill:"none"},{x1:e,x2:e+r,y1:o,y2:o}).attrs(t),{shape:a}}renderDelayDivider({dotSize:t,gapSize:e},{x:n,y:s,width:r,height:i}){const a=this.svg.el("g");for(let o=0;o+e<=i;o+=t+e)a.add(this.svg.box({fill:"#000000"},{x:n,y:s+o,width:r,height:e}));return{mask:a}}renderTearDivider({fadeBegin:t,fadeSize:e,pattern:n,zigWidth:s,zigHeight:r,lineAttrs:i},{x:a,y:o,labelWidth:h,labelHeight:l,width:d,height:g,env:c}){const u=c.addDef("tear-grad",()=>{const n=100/d;return this.svg.linearGradient({},[{offset:t*n+"%","stop-color":"#000000"},{offset:(t+e)*n+"%","stop-color":"#FFFFFF"},{offset:100-(t+e)*n+"%","stop-color":"#FFFFFF"},{offset:100-t*n+"%","stop-color":"#000000"}])}),p=this.svg.el("mask").attr("maskUnits","userSpaceOnUse").add(this.svg.box({fill:"url(#"+u+")"},{x:a,y:o-5,width:d,height:g+10})),f=c.addDef(p);h>0&&p.add(this.svg.box({rx:2,ry:2,fill:"#000000"},{x:a+(d-h)/2,y:o+(g-l)/2-1,width:h,height:l+2}));const m=n||new nt(s,[r,-r]);let b=null;const y=this.svg.patternedLine(m).move(a,o).line(a+d,o),x=this.svg.el("g").attr("mask","url(#"+f+")").add(this.svg.el("path").attrs({d:y.asPath(),fill:"none"}).attrs(i));if(g>0){const t=this.svg.patternedLine(m).move(a,o+g).line(a+d,o+g);x.add(this.svg.el("path").attrs({d:t.asPath(),fill:"none"}).attrs(i)),y.line(t.x,t.y,{patterned:!1}).cap(),y.points.push(...t.points.reverse()),b=this.svg.el("path").attrs({d:y.asPath(),fill:"#000000"})}return{shape:x,mask:b}}}const rt="sans-serif",it=new nt(6,.5),at={"font-family":rt,"font-size":8,"line-height":1.3},ot={"font-family":rt,"font-size":8,"line-height":1.3,"text-anchor":"middle"};class ht extends st{constructor(t){super(t);const e={padding:{top:3,bottom:2},tag:{padding:{top:1,left:3,right:3,bottom:0},boxRenderer:this.renderTag.bind(this,{fill:"#FFFFFF",stroke:"#000000","stroke-width":1,rx:2,ry:2}),labelAttrs:{"font-family":rt,"font-weight":"bold","font-size":9,"line-height":1.3,"text-anchor":"left"}},label:{minHeight:4,padding:{top:1,left:5,right:3,bottom:1},labelAttrs:{"font-family":rt,"font-size":8,"line-height":1.3,"text-anchor":"left"}}};Object.assign(this,{titleMargin:10,outerMargin:5,agentMargin:10,actionMargin:10,minActionMargin:3,agentLineHighlightRadius:4,agentCap:{box:{padding:{top:5,left:10,right:10,bottom:5},arrowBottom:12.8,boxAttrs:{fill:"#FFFFFF",stroke:"#000000","stroke-width":1},labelAttrs:{"font-family":rt,"font-size":12,"line-height":1.3,"text-anchor":"middle"}},database:{padding:{top:12,left:10,right:10,bottom:3},arrowBottom:12.8,boxRenderer:this.renderDB.bind(this,{fill:"#FFFFFF",stroke:"#000000","stroke-width":1,"db-z":5}),labelAttrs:{"font-family":rt,"font-size":12,"line-height":1.3,"text-anchor":"middle"}},cross:{size:20,render:t.crossFactory({fill:"none",stroke:"#000000","stroke-width":1})},bar:{height:4,render:t.boxFactory({fill:"#000000",stroke:"#000000","stroke-width":1})},fade:{width:5,height:6,extend:1},none:{height:10}},connect:{loopbackRadius:6,line:{solid:{attrs:{fill:"none",stroke:"#000000","stroke-width":1},renderFlat:this.renderFlatConnect.bind(this,null),renderRev:this.renderRevConnect.bind(this,null)},dash:{attrs:{fill:"none",stroke:"#000000","stroke-width":1,"stroke-dasharray":"4, 2"},renderFlat:this.renderFlatConnect.bind(this,null),renderRev:this.renderRevConnect.bind(this,null)},wave:{attrs:{fill:"none",stroke:"#000000","stroke-width":1,"stroke-linejoin":"round","stroke-linecap":"round"},renderFlat:this.renderFlatConnect.bind(this,it),renderRev:this.renderRevConnect.bind(this,it)}},arrow:{single:{width:5,height:10,render:this.renderArrowHead.bind(this),attrs:{fill:"#000000","stroke-width":0,"stroke-linejoin":"miter"}},double:{width:4,height:6,render:this.renderArrowHead.bind(this),attrs:{fill:"none",stroke:"#000000","stroke-width":1,"stroke-linejoin":"miter"}},cross:{short:7,radius:3,render:t.crossFactory({fill:"none",stroke:"#000000","stroke-width":1})}},label:{padding:6,margin:{top:2,bottom:1},attrs:{"font-family":rt,"font-size":8,"line-height":1.3,"text-anchor":"middle"},loopbackAttrs:{"font-family":rt,"font-size":8,"line-height":1.3}},source:{radius:2,render:t.circleFactory({fill:"#000000",stroke:"#000000","stroke-width":1})},mask:{padding:{top:0,left:3,right:3,bottom:1}}},titleAttrs:{"font-family":rt,"font-size":20,"line-height":1.3,"text-anchor":"middle",class:"title"},agentLineAttrs:{"":{fill:"none",stroke:"#000000","stroke-width":1},red:{stroke:"#CC0000"}},blocks:{ref:{margin:{top:0,bottom:0},boxRenderer:this.renderRef.bind(this,{fill:"#FFFFFF",stroke:"#000000","stroke-width":1.5,rx:2,ry:2}),section:e},"":{margin:{top:0,bottom:0},boxRenderer:t.boxFactory({fill:"none",stroke:"#000000","stroke-width":1.5,rx:2,ry:2}),collapsedBoxRenderer:this.renderRef.bind(this,{fill:"#FFFFFF",stroke:"#000000","stroke-width":1.5,rx:2,ry:2}),section:e,sepRenderer:t.lineFactory({stroke:"#000000","stroke-width":1.5,"stroke-dasharray":"4, 2"})}},notes:{text:{margin:{top:0,left:2,right:2,bottom:0},padding:{top:2,left:2,right:2,bottom:2},overlap:{left:10,right:10},boxRenderer:t.boxFactory({fill:"#FFFFFF"}),labelAttrs:at},note:{margin:{top:0,left:5,right:5,bottom:0},padding:{top:5,left:5,right:10,bottom:5},overlap:{left:10,right:10},boxRenderer:t.noteFactory({fill:"#FFFFFF",stroke:"#000000","stroke-width":1},{fill:"none",stroke:"#000000","stroke-width":1}),labelAttrs:at},state:{margin:{top:0,left:5,right:5,bottom:0},padding:{top:7,left:7,right:7,bottom:7},overlap:{left:10,right:10},boxRenderer:t.boxFactory({fill:"#FFFFFF",stroke:"#000000","stroke-width":1,rx:10,ry:10}),labelAttrs:at}},dividers:{"":{labelAttrs:ot,padding:{top:2,left:5,right:5,bottom:2},extend:0,margin:0,render:()=>({})},line:{labelAttrs:ot,padding:{top:2,left:5,right:5,bottom:2},extend:10,margin:0,render:this.renderLineDivider.bind(this,{lineAttrs:{stroke:"#000000"}})},delay:{labelAttrs:ot,padding:{top:2,left:5,right:5,bottom:2},extend:0,margin:0,render:this.renderDelayDivider.bind(this,{dotSize:1,gapSize:2})},tear:{labelAttrs:ot,padding:{top:2,left:5,right:5,bottom:2},extend:10,margin:10,render:this.renderTearDivider.bind(this,{fadeBegin:5,fadeSize:10,zigWidth:6,zigHeight:1,lineAttrs:{stroke:"#000000"}})}}})}}class lt{constructor(){this.name="basic"}build(t){return new ht(t)}}const dt="sans-serif",gt=new nt(10,1),ct={"font-family":dt,"font-size":8,"line-height":1.3},ut={"font-family":dt,"font-size":8,"line-height":1.3,"text-anchor":"middle"};class pt extends st{constructor(t){super(t);const e={padding:{top:3,bottom:4},tag:{padding:{top:2,left:5,right:5,bottom:1},boxRenderer:this.renderTag.bind(this,{fill:"#FFFFFF",stroke:"#000000","stroke-width":2,rx:3,ry:3}),labelAttrs:{"font-family":dt,"font-weight":"bold","font-size":9,"line-height":1.3,"text-anchor":"left"}},label:{minHeight:5,padding:{top:2,left:5,right:3,bottom:1},labelAttrs:{"font-family":dt,"font-size":8,"line-height":1.3,"text-anchor":"left"}}};Object.assign(this,{titleMargin:12,outerMargin:5,agentMargin:8,actionMargin:5,minActionMargin:5,agentLineHighlightRadius:4,agentCap:{box:{padding:{top:1,left:3,right:3,bottom:1},arrowBottom:11.1,boxAttrs:{fill:"#FFFFFF",stroke:"#000000","stroke-width":3,rx:4,ry:4},labelAttrs:{"font-family":dt,"font-weight":"bold","font-size":14,"line-height":1.3,"text-anchor":"middle"}},database:{padding:{top:4,left:3,right:3,bottom:0},arrowBottom:11.1,boxRenderer:this.renderDB.bind(this,{fill:"#FFFFFF",stroke:"#000000","stroke-width":3,"db-z":2}),labelAttrs:{"font-family":dt,"font-weight":"bold","font-size":14,"line-height":1.3,"text-anchor":"middle"}},cross:{size:20,render:t.crossFactory({fill:"none",stroke:"#000000","stroke-width":3,"stroke-linecap":"round"})},bar:{height:4,render:t.boxFactory({fill:"#000000",stroke:"#000000","stroke-width":3,rx:2,ry:2})},fade:{width:5,height:10,extend:1},none:{height:10}},connect:{loopbackRadius:8,line:{solid:{attrs:{fill:"none",stroke:"#000000","stroke-width":3},renderFlat:this.renderFlatConnect.bind(this,null),renderRev:this.renderRevConnect.bind(this,null)},dash:{attrs:{fill:"none",stroke:"#000000","stroke-width":3,"stroke-dasharray":"10, 4"},renderFlat:this.renderFlatConnect.bind(this,null),renderRev:this.renderRevConnect.bind(this,null)},wave:{attrs:{fill:"none",stroke:"#000000","stroke-width":3,"stroke-linejoin":"round","stroke-linecap":"round"},renderFlat:this.renderFlatConnect.bind(this,gt),renderRev:this.renderRevConnect.bind(this,gt)}},arrow:{single:{width:10,height:12,render:this.renderArrowHead.bind(this),attrs:{fill:"#000000",stroke:"#000000","stroke-width":3,"stroke-linejoin":"round"}},double:{width:10,height:12,render:this.renderArrowHead.bind(this),attrs:{fill:"none",stroke:"#000000","stroke-width":3,"stroke-linejoin":"round","stroke-linecap":"round"}},cross:{short:10,radius:5,render:t.crossFactory({fill:"none",stroke:"#000000","stroke-width":3,"stroke-linejoin":"round","stroke-linecap":"round"})}},label:{padding:7,margin:{top:2,bottom:3},attrs:{"font-family":dt,"font-size":8,"line-height":1.3,"text-anchor":"middle"},loopbackAttrs:{"font-family":dt,"font-size":8,"line-height":1.3}},source:{radius:5,render:t.circleFactory({fill:"#000000",stroke:"#000000","stroke-width":3})},mask:{padding:{top:1,left:5,right:5,bottom:3}}},titleAttrs:{"font-family":dt,"font-weight":"bolder","font-size":20,"line-height":1.3,"text-anchor":"middle",class:"title"},agentLineAttrs:{"":{fill:"none",stroke:"#000000","stroke-width":3},red:{stroke:"#DD0000"}},blocks:{ref:{margin:{top:0,bottom:0},boxRenderer:this.renderRef.bind(this,{fill:"#FFFFFF",stroke:"#000000","stroke-width":4,rx:5,ry:5}),section:e},"":{margin:{top:0,bottom:0},boxRenderer:t.boxFactory({fill:"none",stroke:"#000000","stroke-width":4,rx:5,ry:5}),collapsedBoxRenderer:this.renderRef.bind(this,{fill:"#FFFFFF",stroke:"#000000","stroke-width":4,rx:5,ry:5}),section:e,sepRenderer:t.lineFactory({stroke:"#000000","stroke-width":2,"stroke-dasharray":"5, 3"})}},notes:{text:{margin:{top:0,left:2,right:2,bottom:0},padding:{top:2,left:2,right:2,bottom:2},overlap:{left:10,right:10},boxRenderer:t.boxFactory({fill:"#FFFFFF"}),labelAttrs:ct},note:{margin:{top:0,left:5,right:5,bottom:0},padding:{top:3,left:3,right:10,bottom:3},overlap:{left:10,right:10},boxRenderer:t.noteFactory({fill:"#FFFFFF",stroke:"#000000","stroke-width":2,"stroke-linejoin":"round"},{fill:"none",stroke:"#000000","stroke-width":1}),labelAttrs:ct},state:{margin:{top:0,left:5,right:5,bottom:0},padding:{top:5,left:7,right:7,bottom:5},overlap:{left:10,right:10},boxRenderer:t.boxFactory({fill:"#FFFFFF",stroke:"#000000","stroke-width":3,rx:10,ry:10}),labelAttrs:ct}},dividers:{"":{labelAttrs:ut,padding:{top:2,left:5,right:5,bottom:2},extend:0,margin:0,render:()=>({})},line:{labelAttrs:ut,padding:{top:2,left:5,right:5,bottom:2},extend:10,margin:0,render:this.renderLineDivider.bind(this,{lineAttrs:{stroke:"#000000","stroke-width":2,"stroke-linecap":"round"}})},delay:{labelAttrs:ut,padding:{top:2,left:5,right:5,bottom:2},extend:0,margin:0,render:this.renderDelayDivider.bind(this,{dotSize:3,gapSize:3})},tear:{labelAttrs:ut,padding:{top:2,left:5,right:5,bottom:2},extend:10,margin:10,render:this.renderTearDivider.bind(this,{fadeBegin:5,fadeSize:10,zigWidth:6,zigHeight:1,lineAttrs:{stroke:"#000000","stroke-width":2,"stroke-linejoin":"round"}})}}})}}class ft{constructor(){this.name="chunky"}build(t){return new pt(t)}}class mt{constructor(){this.listeners=new Map,this.forwards=new Set}addEventListener(t,e){const n=this.listeners.get(t);n?n.push(e):this.listeners.set(t,[e])}removeEventListener(t,e){const n=this.listeners.get(t);if(!n)return;const s=n.indexOf(e);-1!==s&&n.splice(s,1)}on(t,e){return this.addEventListener(t,e),this}off(t,e){return this.removeEventListener(t,e),this}countEventListeners(t){return(this.listeners.get(t)||[]).length}removeAllEventListeners(t){t?this.listeners.delete(t):this.listeners.clear()}addEventForwarding(t){this.forwards.add(t)}removeEventForwarding(t){this.forwards.delete(t)}removeAllEventForwardings(){this.forwards.clear()}trigger(t,e=[]){(this.listeners.get(t)||[]).forEach(t=>t(...e)),this.forwards.forEach(n=>n.trigger(t,e))}}const bt=/^((?!chrome|android).)*safari/i.test(navigator.userAgent);class yt{constructor(){this.latestSVG=null,this.latestInternalSVG=null,this.canvas=null,this.context=null,this.indexPNG=0,this.latestPNGIndex=0,this.latestPNG=null}getSVGContent(t){let e=t.dom().outerHTML;return e=e.replace(/^{this.canvas.width=s,this.canvas.height=r,this.context.drawImage(i,0,0,s,r),a&&document.body.removeChild(a),n(this.canvas)};i.addEventListener("load",()=>{a?setTimeout(o,50):o()},{once:!0}),i.src=this.getSVGURL(t)}getPNGBlob(t,e,n){this.getCanvas(t,e,t=>{t.toBlob(n,"image/png")})}getPNGURL(t,e,n){++this.indexPNG;const s=this.indexPNG;this.getPNGBlob(t,e,t=>{const e=URL.createObjectURL(t);s>=this.latestPNGIndex?(this.latestPNG&&URL.revokeObjectURL(this.latestPNG),this.latestPNG=e,this.latestPNGIndex=s,n(e,!0)):(n(e,!1),URL.revokeObjectURL(e))})}}class xt{constructor({visible:t=!1,locked:e=!1,blocked:n=!1,highlighted:s=!1,group:r=null,covered:i=!1}={}){this.visible=t,this.locked=e,this.blocked=n,this.highlighted=s,this.group=r,this.covered=i}}xt.LOCKED=new xt({locked:!0}),xt.DEFAULT=new xt;const kt={equals:(t,e)=>t.name===e.name,hasFlag:(t,e=!0)=>n=>n.flags.includes(t)===e},wt={equals:(t,e)=>t.id===e.id,make:(t,{anchorRight:e=!1,isVirtualSource:n=!1}={})=>({anchorRight:e,id:t,isVirtualSource:n,options:[]}),indexOf:(e,n)=>t(e,n,wt.equals),hasIntersection:(e,n)=>(function(e,n,s=null){for(let r=0;r{const i=t(e,n,wt.equals);-1===i?e.push(s):e.splice(i+r,0,s)}},vt={"note over":[wt.make("["),wt.make("]")],"note left":[wt.make("[")],"note right":[wt.make("]")]},At=["[","]"],Ft={"agent begin":{check:["mode"],merge:["agentIDs"],siblings:new Set(["agent highlight"])},"agent end":{check:["mode"],merge:["agentIDs"],siblings:new Set(["agent highlight"])},"agent highlight":{check:["highlighted"],merge:["agentIDs"],siblings:new Set(["agent begin","agent end"])}};class Mt{constructor(){this.agentStates=new Map,this.agentAliases=new Map,this.activeGroups=new Map,this.gAgents=[],this.labelPattern=null,this.nextID=0,this.nesting=[],this.markers=new Set,this.currentSection=null,this.currentNest=null,this.stageHandlers={"block begin":this.handleBlockBegin.bind(this),"block split":this.handleBlockSplit.bind(this),"block end":this.handleBlockEnd.bind(this),"group begin":this.handleGroupBegin.bind(this),mark:this.handleMark.bind(this),async:this.handleAsync.bind(this),"agent define":this.handleAgentDefine.bind(this),"agent options":this.handleAgentOptions.bind(this),"agent begin":this.handleAgentBegin.bind(this),"agent end":this.handleAgentEnd.bind(this),divider:this.handleDivider.bind(this),"label pattern":this.handleLabelPattern.bind(this),connect:this.handleConnect.bind(this),"connect-delay-begin":this.handleConnectDelayBegin.bind(this),"connect-delay-end":this.handleConnectDelayEnd.bind(this),"note over":this.handleNote.bind(this),"note left":this.handleNote.bind(this),"note right":this.handleNote.bind(this),"note between":this.handleNote.bind(this)},this.expandGroupedGAgent=this.expandGroupedGAgent.bind(this),this.handleStage=this.handleStage.bind(this),this.toGAgent=this.toGAgent.bind(this),this.endGroup=this.endGroup.bind(this)}toGAgent({name:t,alias:e,flags:n}){if(e){if(this.agentAliases.has(t))throw new Error("Cannot alias "+t+"; it is already an alias");const n=this.agentAliases.get(e);if(n&&n!==e||this.gAgents.some(t=>t.id===e))throw new Error("Cannot use "+e+" as an alias; it is already in use");this.agentAliases.set(e,t)}return wt.make(this.agentAliases.get(t)||t,{isVirtualSource:n.includes("source")})}addStage(t,e=!0){t&&(void 0===t.ln&&(t.ln=this.latestLine),this.currentSection.stages.push(t),e&&(this.currentNest.hasContent=!0))}addParallelStages(t){const e=t.filter(t=>Boolean(t));0!==e.length&&(1!==e.length?(e.forEach(t=>{void 0===t.ln&&(t.ln=this.latestLine)}),this.addStage({type:"parallel",stages:e})):this.addStage(e[0]))}defineGAgents(t){e(this.currentNest.gAgents,t.filter(t=>!At.includes(t.id)),wt.equals),e(this.gAgents,t,wt.equals)}getGAgentState(t){return this.agentStates.get(t.id)||xt.DEFAULT}updateGAgentState(t,e){const n=this.agentStates.get(t.id);n?Object.assign(n,e):this.agentStates.set(t.id,new xt(e))}replaceGAgentState(t,e){this.agentStates.set(t.id,e)}validateGAgents(t,{allowGrouped:e=!1,allowCovered:n=!1,allowVirtual:s=!1}={}){t.forEach(t=>{const r=this.getGAgentState(t);if(r.blocked&&null===r.group)throw new Error("Duplicate agent name: "+t.id);if(!n&&r.covered)throw new Error("Agent "+t.id+" is hidden behind group");if(!e&&null!==r.group)throw new Error("Agent "+t.id+" is in a group");if(!s&&t.isVirtualSource)throw new Error("cannot use message source here");if(t.id.startsWith("__"))throw new Error(t.id+" is a reserved name")})}setGAgentVis(t,e,n,s=!1){const r=new Set,i=t.filter(t=>{if(r.has(t.id))return!1;r.add(t.id);const n=this.getGAgentState(t);if(n.locked||n.blocked){if(s)throw new Error("Cannot begin/end agent: "+t.id);return!1}return n.visible!==e});return 0===i.length?null:(i.forEach(t=>{this.updateGAgentState(t,{visible:e})}),this.defineGAgents(i),{type:e?"agent begin":"agent end",agentIDs:i.map(t=>t.id),mode:n})}setGAgentHighlight(t,e,n=!1){const s=t.filter(t=>{const s=this.getGAgentState(t);if(s.locked||s.blocked){if(n)throw new Error("Cannot highlight agent: "+t.id);return!1}return s.visible&&s.highlighted!==e});return 0===s.length?null:(s.forEach(t=>{this.updateGAgentState(t,{highlighted:e})}),{type:"agent highlight",agentIDs:s.map(t=>t.id),highlighted:e})}_makeSection(t,e){return{header:t,delayedConnections:new Map,stages:e}}_checkSectionEnd(){const t=this.currentSection.delayedConnections;if(t.size>0){const e=t.values().next().value;throw new Error('Unused delayed connection "'+e.tag+'" at line '+(e.ln+1))}}beginNested(t,{tag:e,label:n,name:s,ln:r}){const i=wt.make(s+"[",{anchorRight:!0}),a=wt.make(s+"]"),o=[i,a],h=[];return this.currentSection=this._makeSection({type:"block begin",blockType:t,tag:this.textFormatter(e),label:this.textFormatter(n),canHide:!0,left:i.id,right:a.id,ln:r},h),this.currentNest={blockType:t,gAgents:o,leftGAgent:i,rightGAgent:a,hasContent:!1,sections:[this.currentSection]},this.replaceGAgentState(i,xt.LOCKED),this.replaceGAgentState(a,xt.LOCKED),this.nesting.push(this.currentNest),{stages:h}}nextBlockName(){const t="__BLOCK"+this.nextID;return++this.nextID,t}nextVirtualAgentName(){const t="__"+this.nextID;return++this.nextID,t}handleBlockBegin({ln:t,blockType:e,tag:n,label:s}){this.beginNested(e,{tag:n,label:s,name:this.nextBlockName(),ln:t})}handleBlockSplit({ln:t,blockType:e,tag:n,label:s}){if("if"!==this.currentNest.blockType)throw new Error('Invalid block nesting ("else" inside '+this.currentNest.blockType+")");this._checkSectionEnd(),this.currentSection=this._makeSection({type:"block split",blockType:e,tag:this.textFormatter(n),label:this.textFormatter(s),left:this.currentNest.leftGAgent.id,right:this.currentNest.rightGAgent.id,ln:t},[]),this.currentNest.sections.push(this.currentSection)}handleBlockEnd(){if(this.nesting.length<=1)throw new Error('Invalid block nesting (too many "end"s)');this._checkSectionEnd();const t=this.nesting.pop();if(this.currentNest=r(this.nesting),this.currentSection=r(this.currentNest.sections),!t.hasContent)throw new Error("Empty block");this.defineGAgents(t.gAgents),p(this.gAgents,t.leftGAgent,t.rightGAgent,t.gAgents),t.sections.forEach(t=>{this.currentSection.stages.push(t.header),this.currentSection.stages.push(...t.stages)}),this.addStage({type:"block end",left:t.leftGAgent.id,right:t.rightGAgent.id})}makeGroupDetails(t,e){const s=t.map(this.toGAgent);if(this.validateGAgents(s),this.agentStates.has(e))throw new Error("Duplicate agent name: "+e);const r=this.nextBlockName(),i=wt.make(r+"[",{anchorRight:!0}),a=wt.make(r+"]");this.replaceGAgentState(i,xt.LOCKED),this.replaceGAgentState(a,xt.LOCKED),this.updateGAgentState(wt.make(e),{blocked:!0,group:e}),this.defineGAgents([...s,i,a]);const{indexL:o,indexR:h}=p(this.gAgents,i,a,s),l=[],d=s.slice();for(let t=o+1;t{this.updateGAgentState(t,{group:r})}),i.gAgentsCovered.forEach(t=>{this.updateGAgentState(t,{covered:!0})}),this.activeGroups.set(r,i),this.addStage(this.setGAgentVis(i.gAgents,!0,"box")),this.addStage({type:"block begin",blockType:e,tag:this.textFormatter(n),canHide:!1,label:this.textFormatter(s),left:i.leftGAgent.id,right:i.rightGAgent.id})}endGroup({name:t}){const e=this.activeGroups.get(t);return e?(this.activeGroups.delete(t),e.gAgentsContained.forEach(t=>{this.updateGAgentState(t,{group:null})}),e.gAgentsCovered.forEach(t=>{this.updateGAgentState(t,{covered:!1})}),this.updateGAgentState(wt.make(t),{group:null}),{type:"block end",left:e.leftGAgent.id,right:e.rightGAgent.id}):null}handleMark({name:t}){this.markers.add(t),this.addStage({type:"mark",name:t},!1)}handleDivider({mode:t,height:e,label:n}){this.addStage({type:"divider",mode:t,height:e,formattedLabel:this.textFormatter(n)},!1)}handleAsync({target:t}){if(""!==t&&!this.markers.has(t))throw new Error("Unknown marker: "+t);this.addStage({type:"async",target:t},!1)}handleLabelPattern({pattern:t}){this.labelPattern=t.slice();for(let t=0;t{"string"==typeof t?e+=t:void 0!==t.token?e+=n[t.token]:void 0!==t.current&&(e+=t.current.toFixed(t.dp),t.current+=t.inc)}),e}expandGroupedGAgent(t){const{group:e}=this.getGAgentState(t);if(!e)return[t];const n=this.activeGroups.get(e);return[n.leftGAgent,n.rightGAgent]}expandGroupedGAgentConnection(t){const e=this.expandGroupedGAgent(t[0]),n=this.expandGroupedGAgent(t[1]);let s=wt.indexOf(this.gAgents,e[0]),i=wt.indexOf(this.gAgents,n[0]);return-1===s&&(s=e[0].isVirtualSource?-1:this.gAgents.length),-1===i&&(i=this.gAgents.length),s===i?[r(e),r(n)]:s!t.isVirtualSource));const s=t.filter(kt.hasFlag("begin",!1)).map(this.toGAgent).filter(t=>!t.isVirtualSource);return this.addStage(this.setGAgentVis(s,!0,"box")),{flags:e,gAgents:n}}_makeConnectParallelStages(t,e){return[this.setGAgentVis(t.beginGAgents,!0,"box",!0),this.setGAgentHighlight(t.startGAgents,!0,!0),e,this.setGAgentHighlight(t.stopGAgents,!1,!0),this.setGAgentVis(t.endGAgents,!1,"cross",!0)]}_isSelfConnect(t){const e=t.map(this.toGAgent),n=this.expandGroupedGAgentConnection(e);return n[0].id===n[1].id&&!n.some(t=>t.isVirtualSource)}handleConnect({agents:t,label:e,options:n}){if(this._isSelfConnect(t)){const s={};return this.handleConnectDelayBegin({agent:t[0],tag:s,options:n,ln:0}),void this.handleConnectDelayEnd({agent:t[1],tag:s,label:e,options:n})}let{flags:s,gAgents:r}=this._handlePartialConnect(t);r=this.expandGroupedGAgentConnection(r);const i={type:"connect",agentIDs:(r=this.expandVirtualSourceAgents(r)).map(t=>t.id),label:this.textFormatter(this.applyLabelPattern(e)),options:n};this.addParallelStages(this._makeConnectParallelStages(s,i))}handleConnectDelayBegin({agent:t,tag:e,options:n,ln:s}){const r=this.currentSection.delayedConnections;if(r.has(e))throw new Error('Duplicate delayed connection "'+e+'"');const{flags:i,gAgents:a}=this._handlePartialConnect([t]),o=this.nextVirtualAgentName(),h={type:"connect-delay-begin",tag:o,agentIDs:null,label:null,options:n};r.set(e,{tag:e,uniqueTag:o,ln:s,gAgents:a,connectStage:h}),this.addParallelStages(this._makeConnectParallelStages(i,h))}handleConnectDelayEnd({agent:t,tag:e,label:n,options:s}){const r=this.currentSection.delayedConnections,i=r.get(e);if(!i)throw new Error('Unknown delayed connection "'+e+'"');let{flags:a,gAgents:o}=this._handlePartialConnect([t]);o=this.expandGroupedGAgentConnection([...i.gAgents,...o]),o=this.expandVirtualSourceAgents(o);let h=i.connectStage.options;if(h.line!==s.line)throw new Error("Mismatched delayed connection arrows");s.right&&(h=Object.assign({},h,{right:s.right})),Object.assign(i.connectStage,{agentIDs:o.map(t=>t.id),label:this.textFormatter(this.applyLabelPattern(n)),options:h});const l={type:"connect-delay-end",tag:i.uniqueTag};this.addParallelStages(this._makeConnectParallelStages(a,l)),r.delete(e)}handleNote({type:t,agents:e,mode:n,label:s}){let r=null;r=0===e.length?vt[t]||[]:e.map(this.toGAgent),this.validateGAgents(r,{allowGrouped:!0});const i=(r=a(r,this.expandGroupedGAgent)).map(t=>t.id),o=new Set(i).size;if("note between"===t&&o<2)throw new Error("note between requires at least 2 agents");this.addStage(this.setGAgentVis(r,!0,"box")),this.defineGAgents(r),this.addStage({type:t,agentIDs:i,mode:n,label:this.textFormatter(s)})}handleAgentDefine({agents:t}){const n=t.map(this.toGAgent);this.validateGAgents(n,{allowGrouped:!0,allowCovered:!0}),e(this.gAgents,n,wt.equals)}handleAgentOptions({agent:t,options:n}){const s=this.toGAgent(t),r=[s];this.validateGAgents(r,{allowGrouped:!0,allowCovered:!0}),e(this.gAgents,r,wt.equals),this.gAgents.filter(({id:t})=>t===s.id).forEach(t=>{e(t.options,n)})}handleAgentBegin({agents:t,mode:e}){const n=t.map(this.toGAgent);this.validateGAgents(n),this.addStage(this.setGAgentVis(n,!0,e,!0))}handleAgentEnd({agents:t,mode:e}){const n=t.filter(t=>this.activeGroups.has(t.name)),s=t.filter(t=>!this.activeGroups.has(t.name)).map(this.toGAgent);this.validateGAgents(s),this.addParallelStages([this.setGAgentHighlight(s,!1),this.setGAgentVis(s,!1,e,!0),...n.map(this.endGroup)])}handleStage(t){this.latestLine=t.ln;try{const e=this.stageHandlers[t.type];if(!e)throw new Error("Unknown command: "+t.type);e(t)}catch(e){if("object"==typeof e&&e.message)throw e.message+=" at line "+(t.ln+1),e}}_reset(){this.agentStates.clear(),this.markers.clear(),this.agentAliases.clear(),this.activeGroups.clear(),this.gAgents.length=0,this.nextID=0,this.nesting.length=0,this.labelPattern=[{token:"label"}]}_finalise(t){p(this.gAgents,this.currentNest.leftGAgent,this.currentNest.rightGAgent),function(t){let e=[],n=new Set;for(let s=0;s{t.formattedLabel=this.textFormatter(t.id)})}generate({stages:t,meta:e={}}){this._reset(),this.textFormatter=e.textFormatter;const n=this.beginNested("global",{tag:"",label:"",name:"",ln:0});if(t.forEach(this.handleStage),1!==this.nesting.length)throw new Error("Unterminated section at line "+(this.currentSection.header.ln+1));if(this.activeGroups.size>0)throw new Error("Unterminated group");this._checkSectionEnd();const s=e.terminators||"none";return this.addParallelStages([this.setGAgentHighlight(this.gAgents,!1),this.setGAgentVis(this.gAgents,!1,s)]),this._finalise(n),function(t,e){for(let n=0;n({})},line:{labelAttrs:Et,padding:{top:2,left:5,right:5,bottom:2},extend:8,margin:0,render:this.renderLineDivider.bind(this,{lineAttrs:{stroke:"#000000"}})},delay:{labelAttrs:Et,padding:{top:2,left:5,right:5,bottom:2},extend:0,margin:0,render:this.renderDelayDivider.bind(this,{dotSize:2,gapSize:2})},tear:{labelAttrs:Et,padding:{top:2,left:5,right:5,bottom:2},extend:8,margin:8,render:this.renderTearDivider.bind(this,{fadeBegin:4,fadeSize:4,zigWidth:4,zigHeight:1,lineAttrs:{stroke:"#000000"}})}}})}}class It{constructor(){this.name="monospace"}build(t){return new Gt(t)}}const Dt={type:"error line-error",suggest:!1,then:{"":0}},Lt=["database","red"],Nt=(()=>{function t(t,e=1){return{type:"variable",suggest:{known:"Agent"},then:Object.assign({},t,{"":0,",":{type:"operator",then:{"":e}}})}}function e(t){return{type:"keyword",suggest:[t+" of ",t+": "],then:{of:{type:"keyword",then:{"":h}},":":{type:"operator",then:{"":i}},"":h}}}function n({exit:t,sourceExit:e,blankExit:n}){const s={type:"operator",then:{"+":Dt,"-":Dt,"*":Dt,"!":Dt,"":t}};return{"+":{type:"operator",then:{"+":Dt,"-":Dt,"*":s,"!":Dt,"":t}},"-":{type:"operator",then:{"+":Dt,"-":Dt,"*":s,"!":{type:"operator",then:{"+":Dt,"-":Dt,"*":Dt,"!":Dt,"":t}},"":t}},"*":{type:"operator",then:Object.assign({"+":s,"-":s,"*":Dt,"!":Dt,"":t},e||t)},"!":s,"":n||t}}const s={type:"",suggest:"\n",then:{}},r={type:"",suggest:!1,then:{}},i=f({"\n":s}),a={type:"operator",then:{"":i,"\n":r}},o=t({"\n":s,as:{type:"keyword",then:{"":{type:"variable",suggest:{known:"Agent"},then:{"":0,",":{type:"operator",then:{"":3}},"\n":s}}}}}),h=t({":":a}),l={type:"variable",suggest:{known:"Agent"},then:{"":0,":":{type:"operator",then:{"":i,"\n":r}},"\n":s}},d={":":{type:"operator",then:{"":f({as:{type:"keyword",then:{"":{type:"variable",suggest:{known:"Agent"},then:{"":0,"\n":s}}}}})}}},g={type:"keyword",then:Object.assign({over:{type:"keyword",then:{"":t(d)}}},d)},c={"\n":s,":":{type:"operator",then:{"":i,"\n":r}},with:{type:"keyword",suggest:["with height "],then:{height:{type:"keyword",then:{"":{type:"number",suggest:["6 ","30 "],then:{"\n":s,":":{type:"operator",then:{"":i,"\n":r}}}}}}}}},u=function(t,e,n){const s=Object.assign({},n);return e.forEach(e=>{s[e]={type:t,then:n}}),s}("keyword",["a","an"],function(t,e,n){const s={},r=Object.assign({},n);return e.forEach(e=>{s[e]={type:t,then:r},r[e]=0}),s}("keyword",Lt,{"\n":s})),p={type:"keyword",then:{"":i,":":{type:"operator",then:{"":i}},"\n":s}},m={title:{type:"keyword",then:{"":i}},theme:{type:"keyword",then:{"":{type:"string",suggest:{global:"themes",suffix:"\n"},then:{"":0,"\n":s}}}},headers:{type:"keyword",then:{none:{type:"keyword",then:{}},cross:{type:"keyword",then:{}},box:{type:"keyword",then:{}},fade:{type:"keyword",then:{}},bar:{type:"keyword",then:{}}}},terminators:{type:"keyword",then:{none:{type:"keyword",then:{}},cross:{type:"keyword",then:{}},box:{type:"keyword",then:{}},fade:{type:"keyword",then:{}},bar:{type:"keyword",then:{}}}},divider:{type:"keyword",then:Object.assign({line:{type:"keyword",then:c},space:{type:"keyword",then:c},delay:{type:"keyword",then:c},tear:{type:"keyword",then:c}},c)},define:{type:"keyword",then:{"":o,as:Dt}},begin:{type:"keyword",then:{"":o,reference:g,as:Dt}},end:{type:"keyword",then:{"":o,as:Dt,"\n":s}},if:p,else:{type:"keyword",suggest:["else\n","else if: "],then:{if:{type:"keyword",suggest:"if: ",then:{"":i,":":{type:"operator",then:{"":i}}}},"\n":s}},repeat:p,group:p,note:{type:"keyword",then:{over:{type:"keyword",then:{"":h}},left:e("left"),right:e("right"),between:{type:"keyword",then:{"":t({":":Dt},h)}}}},state:{type:"keyword",suggest:"state over ",then:{over:{type:"keyword",then:{"":{type:"variable",suggest:{known:"Agent"},then:{"":0,",":Dt,":":a}}}}}},text:{type:"keyword",then:{left:e("left"),right:e("right")}},autolabel:{type:"keyword",then:{off:{type:"keyword",then:{}},"":f({"\n":s},[{v:"",suffix:"\n",q:!0},{v:"[] ",suffix:"\n",q:!0},{v:"[] ",suffix:"\n",q:!0}])}},simultaneously:{type:"keyword",then:{":":{type:"operator",then:{}},with:{type:"keyword",then:{"":{type:"variable",suggest:{known:"Label"},then:{"":0,":":{type:"operator",then:{}}}}}}}}};return t=>({type:"error line-error",then:Object.assign({},m,function(t){const e={type:"keyword",then:Object.assign({},n({exit:l,sourceExit:{":":a,"\n":r}}),{"...":{type:"operator",then:{"":{type:"variable",suggest:{known:"DelayedAgent"},then:{"":0,":":Dt,"\n":s}}}}})},i={};t.forEach(t=>i[t]=e);const o={type:"operator",suggest:!1,override:"Label",then:{}},h={type:"variable",suggest:{known:"Agent"},then:Object.assign({"":0},i,{":":{type:"operator",override:"Label",then:{}}})},d={type:"variable",suggest:{known:"DelayedAgent"},then:Object.assign({"":0,":":o},i)},g=Object.assign({},h,{then:Object.assign({},h.then,{is:{type:"keyword",then:u}})});return Object.assign({"...":{type:"operator",then:{"":d}}},n({exit:h,sourceExit:Object.assign({"":h,":":o},i),blankExit:g}))}(t))})})();class zt{constructor(t,e){this.tokenDefinitions=t,this.commands=Nt(e),this.lineComment="#"}startState(){return{currentType:-1,current:"",currentSpace:"",currentQuoted:!1,knownAgent:[],knownDelayedAgent:[],knownLabel:[],beginCompletions:y({},[this.commands]),completions:[],nextCompletions:[],valid:!0,isVar:!0,line:[],indent:0}}_matchPattern(t,e,n){return e?(e.lastIndex=0,t.match(e,n)):null}_tokenBegin(t,e){e.currentSpace="";for(let n="";!t.eol();n=t.next()){e.currentSpace+=n;for(let n=0;n,])|$/y,start:/(?=[^ \t\r\n:+~\-*!<>,])/y},{end:/(?=[^~\-<>x])|[-~]x|[<>](?=x)|$/y,includeEnd:!0,start:/(?=[~\-<])/y},{baseToken:{v:","},start:/,/y},{baseToken:{v:":"},start:/:/y},{baseToken:{v:"!"},start:/!/y},{baseToken:{v:"+"},start:/\+/y},{baseToken:{v:"*"},start:/\*/y},{baseToken:{v:"\n"},start:/\n/y}];class Bt{constructor(t){this.src=t,this.block=null,this.token=null,this.pos={ch:0,i:0,ln:0},this.reset()}isOver(){return this.pos.i>this.src.length}reset(){this.token={b:null,e:null,q:!1,s:"",v:""},this.block=null}beginToken(t){this.block=t.newBlock,Object.assign(this.token,this.block.baseToken),this.token.b=F(this.pos)}endToken(){let t=null;return this.block.omit||(this.token.e=F(this.pos),t=this.token),this.reset(),t}advance(){const t=A(this.src,this.pos.i,this.block);return t.newBlock&&this.beginToken(t),this.token.s+=t.appendSpace,this.token.v+=t.appendValue,function(t,e,n){for(let s=0;s{t.q||"\n"!==t.v?n.push(t):n.length>0&&(e.push(n),n=[])}),n.length>0&&e.push(n),e}}const Ht=/(.*?)<([^<>]*)>/g,Tt=/\.([0-9]*)/,Pt=[{attrs:{"font-style":"italic"},begin:/[\s_~`]\*(?=\S)/g,end:/\S\*(?=[\s_~`])/g},{attrs:{"font-style":"italic"},begin:/[\s*~`]_(?=\S)/g,end:/\S_(?=[\s*~`])/g},{attrs:{"font-weight":"bolder"},begin:/[\s_~`]\*\*(?=\S)/g,end:/\S\*\*(?=[\s_~`])/g},{attrs:{"font-weight":"bolder"},begin:/[\s*~`]__(?=\S)/g,end:/\S__(?=[\s*~`])/g},{attrs:{"text-decoration":"line-through"},begin:/[\s_*`]~(?=\S)/g,end:/\S~(?=[\s_*`])/g},{attrs:{"font-family":"monospace"},begin:/[\s_*~.]`(?=\S)/g,end:/\S`(?=[\s_*~.])/g}],jt={if:{type:"block begin",blockType:"if",tag:"if",skip:[]},else:{type:"block split",blockType:"else",tag:"else",skip:["if"]},repeat:{type:"block begin",blockType:"repeat",tag:"repeat",skip:[]},group:{type:"block begin",blockType:"group",tag:"",skip:[]}},qt={types:(()=>{const t=function(t){const e=[];return i(t,0,[],e),e}([[{tok:"",type:0},{tok:"<",type:1},{tok:"<<",type:2}],[{tok:"-",type:"solid"},{tok:"--",type:"dash"},{tok:"~",type:"wave"}],[{tok:"",type:0},{tok:">",type:1},{tok:">>",type:2},{tok:"x",type:3}]]).filter(t=>0!==t[0].type||0!==t[2].type),e=new Map;return t.forEach(t=>{e.set(t.map(t=>t.tok).join(""),{line:t[1].type,left:t[0].type,right:t[2].type})}),e})(),agentFlags:{"*":{flag:"begin",allowBlankName:!0,blankNameFlag:"source"},"+":{flag:"start"},"-":{flag:"stop"},"!":{flag:"end"}}},Yt=["none","box","cross","fade","bar"],Wt={text:{mode:"text",types:{left:{type:"note left",skip:["of"],min:0,max:null},right:{type:"note right",skip:["of"],min:0,max:null}}},note:{mode:"note",types:{over:{type:"note over",skip:[],min:0,max:null},left:{type:"note left",skip:["of"],min:0,max:null},right:{type:"note right",skip:["of"],min:0,max:null},between:{type:"note between",skip:[],min:2,max:null}}},state:{mode:"state",types:{over:{type:"note over",skip:[],min:1,max:1}}}},Ut={line:{defaultHeight:6},space:{defaultHeight:6},delay:{defaultHeight:30},tear:{defaultHeight:6}},Xt={define:{type:"agent define"},begin:{type:"agent begin",mode:"box"},end:{type:"agent end",mode:"cross"}},Qt=[(t,e)=>"title"!==D(t[0])?null:(e.title=I(t,1),!0),(t,e)=>"theme"!==D(t[0])?null:(e.theme=I(t,1),!0),(t,e)=>{if("terminators"!==D(t[0]))return null;const n=D(t[1]);if(!n)throw G("Unspecified termination",t[0]);if(-1===Yt.indexOf(n))throw G('Unknown termination "'+n+'"',t[1]);return e.terminators=n,!0},(t,e)=>{if("headers"!==D(t[0]))return null;const n=D(t[1]);if(!n)throw G("Unspecified header",t[0]);if(-1===Yt.indexOf(n))throw G('Unknown header "'+n+'"',t[1]);return e.headers=n,!0},t=>{if("divider"!==D(t[0]))return null;const e=N(t,":",{orEnd:!0}),n=N(t,["with","height"],{limit:e,orEnd:!0}),s=I(t,1,n)||"line";if(!Ut[s])throw G("Unknown divider type",t[1]);const r=function(t,e=0,n=null,s=Number.NAN){const r=I(t,e,n);return Number(r||s)}(t,n+2,e,Ut[s].defaultHeight);if(Number.isNaN(r)||r<0)throw G("Invalid divider height",t[n+2]);return{type:"divider",mode:s,height:r,label:I(t,e+1)}},t=>{if("autolabel"!==D(t[0]))return null;let e=null;return e="off"===D(t[1])?"":I(t,1),{type:"label pattern",pattern:function(t){const e=[];let n=null,s=0;for(Ht.lastIndex=0;n=Ht.exec(t);)n[1]&&e.push(n[1]),n[2]&&e.push(S(n[2])),s=Ht.lastIndex;const r=t.substr(s);return r&&e.push(r),e}(e)}},t=>{if("end"===D(t[0])&&1===t.length)return{type:"block end"};const e=jt[D(t[0])];if(!e)return null;let n=1;return t.length>n&&(n=L(t,n,e.skip,"Invalid block command")),n=L(t,n,[":"]),{type:e.type,blockType:e.blockType,tag:e.tag,label:I(t,n)}},t=>{if("begin"!==D(t[0])||"reference"!==D(t[1]))return null;let e=[];const n=N(t,":");if("over"===D(t[2])&&n>3)e=O(t,3,n);else if(2!==n)throw G('Expected ":" or "over"',t[2]);const s=z(t,n+1,t.length,{aliases:!0});if(!s.alias)throw G("Reference must have an alias",t[n]);return{type:"group begin",agents:e,blockType:"ref",tag:"ref",label:s.name,alias:s.alias}},t=>{const e=Xt[D(t[0])];return!e||t.length<=1?null:Object.assign({agents:O(t,1,t.length,{aliases:!0})},e)},t=>{if("simultaneously"!==D(t[0]))return null;if(":"!==D(r(t)))return null;let e="";if(t.length>2){if("with"!==D(t[1]))return null;e=I(t,2,t.length-1)}return{type:"async",target:e}},t=>{const e=Wt[D(t[0])],n=N(t,":");if(!e||-1===n)return null;const s=e.types[D(t[1])];if(!s)return null;let r=2;const i=O(t,r=L(t,r,s.skip),n);if(i.lengths.max)throw G("Too many agents for "+e.mode,t[0]);return{type:s.type,agents:i,mode:e.mode,label:I(t,n+1)}},t=>{const e=N(t,":",{orEnd:!0}),n=function(t,e,{start:n=0,limit:s=null}={}){null===s&&(s=t.length);for(let r=n;rt.length<2||":"!==D(r(t))?null:{type:"mark",name:I(t,0,t.length-1)},t=>{const e=N(t,"is");if(e<1)return null;let n=e+1;if(["a","an"].includes(D(t[n]))&&++n,n===t.length)throw G("Empty agent options",{b:r(t).e});const s=z(t,0,e),i=[];for(let e=n;e(function(t,{meta:e,stages:n}){let s=null;for(let n=0;nn.svg.linearGradient({x1:"0%",x2:"0%",y1:s?"100%":"0%",y2:s?"0%":"100%"},[{offset:"0%","stop-color":"#FFFFFF"},{offset:(100*i).toFixed(3)+"%","stop-color":"#000000"}]));return n.lineMaskLayer.add(n.svg.box({fill:"url(#"+a+")"},{height:r.height+r.extend,width:r.width,x:e-r.width/2,y:t-(s?r.extend:0)})),n.makeRegion().add(n.svg.box($t,{height:r.height,width:r.width,x:e-r.width/2,y:t})),{height:r.height,lineBottom:0,lineTop:r.height}}}class re{prepareMeasurements(){}separation({currentRad:t}){return{left:t,radius:t,right:t}}topShift(t,e){return e.theme.agentCap.none.height}render(t,{x:e},n){const s=n.theme.agentCap.none;return n.makeRegion().add(n.svg.box($t,{height:s.height,width:10,x:e-5,y:t})),{height:s.height,lineBottom:0,lineTop:s.height}}}const ie={bar:new ne,box:new te,cross:new ee,fade:new se,none:new re};class ae extends Kt{constructor(t){super(),this.begin=t}prepareMeasurements({mode:t,agentIDs:e},n){e.forEach(e=>{const s=n.agentInfos.get(e);ie[t].prepareMeasurements(s,n,this.begin)})}separationPre({mode:t,agentIDs:e},n){e.forEach(e=>{const s=n.agentInfos.get(e),r=ie[t].separation(s,n,this.begin);n.addSpacing(e,r),s.currentMaxRad=Math.max(s.currentMaxRad,r.radius)})}separation({agentIDs:t},s){this.begin?e(s.visibleAgentIDs,t):n(s.visibleAgentIDs,t)}renderPre({mode:t,agentIDs:e},n){let s=0;return e.forEach(e=>{const r=n.agentInfos.get(e),i=ie[t],a=i.topShift(r,n,this.begin);s=Math.max(s,a);const o=i.separation(r,n,this.begin).radius;r.currentMaxRad=Math.max(r.currentMaxRad,o)}),{agentIDs:e,topShift:s}}render({mode:t,agentIDs:e},n){let s=0;return e.forEach(e=>{const r=n.agentInfos.get(e),i=ie[t],a=i.topShift(r,n,this.begin),o=n.primaryY-a,h=i.render(o,r,n,this.begin);s=Math.max(s,o+h.height),this.begin?n.drawAgentLine(e,o+h.lineBottom):n.drawAgentLine(e,o+h.lineTop,!0)}),s+n.theme.actionMargin}renderHidden({agentIDs:t},e){t.forEach(t=>{e.drawAgentLine(t,e.topY,!this.begin)})}}V("agent begin",new ae(!0)),V("agent end",new ae(!1));class oe extends Kt{radius(t,e){return t?e.theme.agentLineHighlightRadius:0}separationPre({agentIDs:t,highlighted:e},n){const s=this.radius(e,n);t.forEach(t=>{const e=n.agentInfos.get(t);e.currentRad=s,e.currentMaxRad=Math.max(e.currentMaxRad,s)})}renderPre({agentIDs:t,highlighted:e},n){const s=this.radius(e,n);t.forEach(t=>{const e=n.agentInfos.get(t);e.currentMaxRad=Math.max(e.currentMaxRad,s)})}render({agentIDs:t,highlighted:e},n){const s=this.radius(e,n);return t.forEach(t=>{n.drawAgentLine(t,n.primaryY),n.agentInfos.get(t).currentRad=s}),n.primaryY+n.theme.actionMargin}renderHidden(t,e){this.render(t,e)}}V("agent highlight",new oe);const he={class:"outline",fill:"transparent"};class le extends Kt{prepareMeasurements({left:t,tag:e,label:n},s){const r=s.state.blocks.get(t),i=s.theme.getBlock(r.type).section;s.textSizer.expectMeasure(i.tag.labelAttrs,e),s.textSizer.expectMeasure(i.label.labelAttrs,n)}separation({left:t,right:e,tag:n,label:s},r){const i=r.state.blocks.get(t),a=r.theme.getBlock(i.type).section,o=r.textSizer.measure(a.tag.labelAttrs,n).width+a.tag.padding.left+a.tag.padding.right+r.textSizer.measure(a.label.labelAttrs,s).width+a.label.padding.left+a.label.padding.right;r.addSeparation(t,e,o)}renderPre({left:t,right:e}){return{agentIDs:[t,e]}}render({left:t,right:e,tag:n,label:s},r,i=!1){const a=r.state.blocks.get(t),o=r.theme.getBlock(a.type),h=r.agentInfos.get(t),l=r.agentInfos.get(e);let d=r.primaryY;i||(d+=o.section.padding.bottom);const g=r.makeRegion(),c=r.svg.boxedText({boxAttrs:o.section.tag.boxAttrs,boxRenderer:o.section.tag.boxRenderer,labelAttrs:o.section.tag.labelAttrs,padding:o.section.tag.padding},n,{x:h.x,y:d}),u=r.svg.boxedText({boxAttrs:{fill:"#000000"},labelAttrs:o.section.label.labelAttrs,padding:o.section.label.padding},s,{x:h.x+c.width,y:d}),p=Math.max(Math.max(c.height,u.height),o.section.label.minHeight);return a.hold.add(c.box),r.lineMaskLayer.add(u.box),g.add(r.svg.box(he,{height:p,width:l.x-h.x,x:h.x,y:d}),c.label,u.label),i?a.canHide&&g.addClass(a.hide?"collapsed":"expanded"):a.hold.add(o.sepRenderer({x1:h.x,x2:l.x,y1:d,y2:d})),d+p+o.section.padding.top}}class de extends le{makeState(t){t.blocks=new Map}resetState(t){t.blocks.clear()}storeBlockInfo(t,e){const{canHide:n}=t,s={canHide:n,hide:n&&e.renderer.isCollapsed(t.ln),hold:null,startY:null,type:t.blockType};return e.state.blocks.set(t.left,s),s}prepareMeasurements(t,e){this.storeBlockInfo(t,e),super.prepareMeasurements(t,e)}separationPre(t,e){this.storeBlockInfo(t,e),super.separationPre(t,e)}separation(t,n){e(n.visibleAgentIDs,[t.left,t.right]),super.separation(t,n)}renderPre(t,e){const n=this.storeBlockInfo(t,e),s=e.theme.getBlock(n.type);return{agentIDs:[t.left,t.right],topShift:s.margin.top}}render(t,e){const n=e.svg.el("g");e.blockLayer.add(n);const s=e.state.blocks.get(t.left);return s.hold=n,s.startY=e.primaryY,super.render(t,e,!0)}shouldHide({left:t},e){return{nest:e.state.blocks.get(t).hide?1:0,self:!1}}}class ge extends Kt{separation({left:t,right:e},s){n(s.visibleAgentIDs,[t,e])}renderPre({left:t,right:e},n){const s=n.state.blocks.get(t);return{agentIDs:[t,e],topShift:n.theme.getBlock(s.type).section.padding.bottom}}render({left:t,right:e},n){const s=n.state.blocks.get(t),r=n.theme.getBlock(s.type),i=n.agentInfos.get(t),a=n.agentInfos.get(e);let o=r.boxRenderer;s.hide&&(o=r.collapsedBoxRenderer||o);let h=o({height:n.primaryY-s.startY,width:a.x-i.x,x:i.x,y:s.startY});return h.shape||(h={shape:h}),s.hold.add(h.shape),n.fillLayer.add(h.fill),n.lineMaskLayer.add(h.mask),n.primaryY+r.margin.bottom+n.theme.actionMargin}shouldHide({left:t},e){return{nest:e.state.blocks.get(t).hide?-1:0,self:!1}}}V("block begin",new de),V("block split",new le),V("block end",new ge);const ce={class:"outline",fill:"transparent"};class ue{constructor(t){this.propName=t}getConfig(t){return t.connect.arrow[this.propName]}short(t){const e=this.getConfig(t),n=e.attrs["stroke-linejoin"]||"miter",s=.5*e.attrs["stroke-width"],r=.5*t.agentLineAttrs[""]["stroke-width"];if("round"===n)return r+s;{const t=e.height/2,n=e.width;return r+s*Math.sqrt(n*n/(t*t)+1)}}render(t,e,n,s){const r=this.getConfig(e),i=this.short(e);t.add(r.render(r.attrs,{x:n.x+i*s.dx,y:n.y+i*s.dy,width:r.width,height:r.height,dir:s}))}width(t){return this.short(t)+this.getConfig(t).width}height(t){return this.getConfig(t).height}lineGap(t,e){const n=this.getConfig(t),s=this.short(t);if("none"===n.attrs.fill){const t=n.height/2,r=n.width;return(s+(s+e["stroke-width"]/2*(r/t)))/2}return s+n.width/2}}class pe{getConfig(t){return t.connect.arrow.cross}render(t,e,n,s){const r=this.getConfig(e);t.add(r.render({x:n.x+r.short*s.dx,y:n.y+r.short*s.dy,radius:r.radius}))}width(t){const e=this.getConfig(t);return e.short+e.radius}height(t){return 2*this.getConfig(t).radius}lineGap(t){return this.getConfig(t).short}}const fe=[{render:()=>null,width:()=>0,height:()=>0,lineGap:()=>0},new ue("single"),new ue("double"),new pe];class me extends Kt{prepareMeasurements({agentIDs:t,label:e},n){const s=n.theme.connect,r=t[0]===t[1]?s.label.loopbackAttrs:s.label.attrs;n.textSizer.expectMeasure(r,e)}separationPre({agentIDs:t},e){const n=e.theme.connect.source.radius;t.forEach(t=>{const s=e.agentInfos.get(t);s.isVirtualSource&&(s.currentRad=n,s.currentMaxRad=Math.max(s.currentMaxRad,n))})}separation({label:t,agentIDs:n,options:s},r){const i=r.theme.connect,a=fe[s.left],o=fe[s.right],h=n[0]===n[1],l=h?i.label.loopbackAttrs:i.label.attrs;let d=r.textSizer.measure(l,t).width;d>0&&(d+=2*i.label.padding);const g=r.agentInfos.get(n[0]);if(h)r.addSpacing(n[0],{left:0,right:g.currentMaxRad+Math.max(d+a.width(r.theme),o.width(r.theme))+i.loopbackRadius});else{const t=r.agentInfos.get(n[1]);r.addSeparation(n[0],n[1],g.currentMaxRad+t.currentMaxRad+d+2*Math.max(a.width(r.theme),o.width(r.theme)))}e(r.momentaryAgentIDs,n)}renderRevArrowLine({x1:t,y1:e,x2:n,y2:s,xR:r},i,a,o){const h=a.theme.connect,l=h.line[i.line],d=fe[i.left],g=fe[i.right],c=d.lineGap(a.theme,l.attrs),u=g.lineGap(a.theme,l.attrs),p=l.renderRev(l.attrs,{x1:t+c,y1:e,x2:n+u,y2:s,xR:r,rad:h.loopbackRadius});o.add(p.shape),d.render(o,a.theme,{x:p.p1.x-c,y:p.p1.y},{dx:1,dy:0}),g.render(o,a.theme,{x:p.p2.x-u,y:p.p2.y},{dx:1,dy:0})}renderSelfConnect({label:t,agentIDs:e,options:n},s,r,i){const a=s.theme.connect,o=fe[n.left],h=fe[n.right],l=s.agentInfos.get(e[1]),d=t?s.textSizer.measureHeight(a.label.attrs,t)+a.label.margin.top+a.label.margin.bottom:0,g=r.x+r.currentMaxRad+o.width(s.theme)+(t?a.label.padding:0),c=s.svg.boxedText({padding:a.mask.padding,boxAttrs:{fill:"#000000"},labelAttrs:a.label.loopbackAttrs},t,{x:g-a.mask.padding.left,y:i-d+a.label.margin.top}),u=t?c.width+a.label.padding-a.mask.padding.left-a.mask.padding.right:0,p=Math.max(l.x+l.currentMaxRad+h.width(s.theme),g+u),f=Math.max(d,o.height(s.theme)/2),m=h.height(s.theme)/2;s.lineMaskLayer.add(c.box);const b=s.makeRegion().add(s.svg.box(ce,{x:r.x,y:i-f,width:p+a.loopbackRadius-r.x,height:f+s.primaryY-i+m}),c.label);return this.renderRevArrowLine({x1:r.x+r.currentMaxRad,y1:i,x2:l.x+l.currentMaxRad,y2:s.primaryY,xR:p},n,s,b),s.primaryY+Math.max(m,0)+s.theme.actionMargin}renderArrowLine({x1:t,y1:e,x2:n,y2:s},r,i,a){const o=i.theme.connect.line[r.line],h=fe[r.left],l=fe[r.right],d=Math.sqrt((n-t)*(n-t)+(s-e)*(s-e)),g=h.lineGap(i.theme,o.attrs),c=l.lineGap(i.theme,o.attrs),u=(n-t)/d,p=(s-e)/d,f=o.renderFlat(o.attrs,{x1:t+g*u,y1:e+g*p,x2:n-c*u,y2:s-c*p});a.add(f.shape);const m={x:f.p1.x-g*u,y:f.p1.y-g*p},b={x:f.p2.x+c*u,y:f.p2.y+c*p};return h.render(a,i.theme,m,{dx:u,dy:p}),l.render(a,i.theme,b,{dx:-u,dy:-p}),{p1:m,p2:b,lArrow:h,rArrow:l}}renderVirtualSources({from:t,to:e,rendered:n},s,r){const i=s.theme.connect.source;t.isVirtualSource&&r.add(i.render({x:n.p1.x-i.radius,y:n.p1.y,radius:i.radius})),e.isVirtualSource&&r.add(i.render({x:n.p2.x+i.radius,y:n.p2.y,radius:i.radius}))}renderSimpleLabel(t,{layer:e,x1:n,x2:s,y1:r,y2:i,height:a},o){const h=o.theme.connect,l=(n+s)/2,d=(r+i)/2;let g=e;const c={fill:"#000000"};if(r!==i){const t="rotate("+180*Math.atan((i-r)/(s-n))/Math.PI+" "+l+","+d+")";c.transform=t,g=o.svg.el("g").attr("transform",t),e.add(g)}const u=o.svg.boxedText({padding:h.mask.padding,boxAttrs:c,labelAttrs:h.label.attrs},t,{x:l,y:d+h.label.margin.top-a});o.lineMaskLayer.add(u.box),g.add(u.label)}renderSimpleConnect({label:t,agentIDs:e,options:n},s,r,i){const a=s.theme.connect,o=s.agentInfos.get(e[1]),h=r.x{return e.components.get(t.type)[n](t,e)})}prepareMeasurements(t,e){this.invokeChildren(t,e,"prepareMeasurements")}separationPre(t,e){this.invokeChildren(t,e,"separationPre")}separation(t,e){this.invokeChildren(t,e,"separation")}renderPre(t,e){return this.invokeChildren(t,e,"renderPre").map(t=>B(t)).reduce(j,{agentIDs:[],asynchronousY:null,topShift:0})}render(t,e){const n=e.makeRegion;let s=0;return t.stages.forEach(t=>{e.makeRegion=((e={})=>n(Object.assign({stageOverride:t},e)));const r=e.components.get(t.type).render(t,e)||0;s=Math.max(s,r)}),e.makeRegion=n,s}renderHidden(t,e){this.invokeChildren(t,e,"renderHidden")}shouldHide(t,e){return this.invokeChildren(t,e,"shouldHide").reduce((t,{self:e=!1,nest:n=0}={})=>({nest:t.nest+n,self:t.self||Boolean(e)}),{nest:0,self:!1})}}V("parallel",new Ce);class Ee{constructor(t){this.element=t}addBefore(t=null,e=null){if(null===t)return this;if(Array.isArray(t))for(const n of t)this.addBefore(n,e);else{const n=function(t,e){return"string"==typeof t?e.createTextNode(t):"number"==typeof t?e.createTextNode(t.toString(10)):"object"==typeof t&&t.element?t.element:t}(t,this.element.ownerDocument);this.element.insertBefore(n,q(e))}return this}add(...t){return this.addBefore(t,null)}del(t=null){return null!==t&&this.element.removeChild(q(t)),this}attr(t,e){return this.element.setAttribute(t,e),this}attrs(t){for(const e in t)Object.prototype.hasOwnProperty.call(t,e)&&this.element.setAttribute(e,t[e]);return this}styles(t){for(const e in t)Object.prototype.hasOwnProperty.call(t,e)&&(this.element.style[e]=t[e]);return this}setClass(t){return this.attr("class",t)}addClass(t){const e=this.element.getAttribute("class");if(!e)return this.setClass(t);const n=e.split(" ");return n.includes(t)?this:(n.push(t),this.attr("class",n.join(" ")))}delClass(t){const e=this.element.getAttribute("class");if(!e)return this;const n=e.split(" "),s=n.indexOf(t);return-1!==s&&(n.splice(s,1),this.attr("class",n.join(" "))),this}text(t){return this.element.textContent=t,this}on(t,e,n={}){if(Array.isArray(t))for(const s of t)this.on(s,e,n);else this.element.addEventListener(t,e,n);return this}off(t,e,n={}){if(Array.isArray(t))for(const s of t)this.off(s,e,n);else this.element.removeEventListener(t,e,n);return this}val(t){return this.element.value=t,this}select(t,e=null){return this.element.selectionStart=t,this.element.selectionEnd=null===e?t:e,this}focus(){return this.element.focus(),this}focussed(){return this.element===this.element.ownerDocument.activeElement}empty(){for(;this.element.childNodes.length>0;)this.element.removeChild(this.element.lastChild);return this}attach(t){return q(t).appendChild(this.element),this}detach(){return this.element.parentNode.removeChild(this.element),this}}class Ge{constructor(t){if(!t)throw new Error("Missing document!");this.document=t,this.wrap=this.wrap.bind(this),this.el=this.el.bind(this),this.txt=this.txt.bind(this)}wrap(t){return t.element?t:new Ee(t)}el(t,e=null){let n=null;return n=null===e?this.document.createElement(t):this.document.createElementNS(e,t),new Ee(n)}txt(t=""){return this.document.createTextNode(t)}}const Ie=void 0!==window.InstallTrigger,De=[];class Le{constructor(t,e,n={}){this.container=t,this.svg=e,this.state={attrs:{},formatted:De,x:0,y:0},this.lines=[],this.set(n)}_rebuildLines(t){if(t>this.lines.length)for(;this.lines.lengtht;)this.lines.pop().node.detach()}_reset(){this._rebuildLines(0)}_renderText(){const{formatted:t}=this.state;if(t&&t.length){if(!Array.isArray(t))throw new Error("Invalid formatted text: "+t);this._rebuildLines(t.length),this.lines.forEach((e,n)=>{const s=JSON.stringify(t[n]);s!==e.latest&&(e.node.empty(),Y(this.svg,e.node,t[n]),e.latest=s)})}else this._reset()}_updateX(){this.lines.forEach(({node:t})=>{t.attr("x",this.state.x)})}_updateY(){const t=this.svg.textSizer;let e=this.state.y;for(let n=0;n0&&(this.points.push(this.x+" "+this.y),this.disconnect=0),this}move(t,e){return this.cap(),this.x=t,this.y=e,this.disconnect=2,this}line(t,e,{patterned:n=!0}={}){if(this.pattern&&n){const n=Math.sqrt((t-this.x)*(t-this.x)+(e-this.y)*(e-this.y)),s=(t-this.x)/n,r=(e-this.y)/n,i=-r,a=s;for(let t=0;t+this.dw<=n;t+=this.dw){const e=this._nextDelta();this.points.push(this.x+t*s+e*i+" "+(this.y+t*r+e*a))}this.disconnect=1}else this._link(),this.disconnect=2;return this.x=t,this.y=e,this}arc(t,e,n){const s=Math.sqrt((t-this.x)*(t-this.x)+(e-this.y)*(e-this.y)),r=Math.atan2(this.x-t,e-this.y),i=t+Math.sin(r+n)*s,a=e-Math.cos(r+n)*s;if(this.pattern){const i=n<0?1:-1,a=this.dw/s;for(let o=r;o+a<=r+n;o+=a){const n=this._nextDelta()*i;this.points.push(t+Math.sin(o)*(s+n)+" "+(e-Math.cos(o)*(s+n)))}this.disconnect=1}else this.points.push(this.x+" "+this.y+"A"+s+" "+s+" 0 "+(Math.abs(n)>=Math.PI?"1 ":"0 ")+(n<0?"0 ":"1 ")+i+" "+a),this.disconnect=0;return this.x=i,this.y=a,this}asPath(){return this._link(),"M"+this.points.join("L")}}const Oe="http://www.w3.org/2000/svg";class Be{constructor(t){this.sizer=t,this.cache=new Map,this.active=null}_expectMeasure({attrs:t,formatted:e}){if(!e.length)return null;const n=JSON.stringify(t);let s=this.cache.get(n);return s||(s={attrs:t,lines:new Map},this.cache.set(n,s)),e.forEach(t=>{if(!t.length)return;const e=JSON.stringify(t);s.lines.has(e)||s.lines.set(e,{formatted:t,width:null})}),s}_measureLine(t,e){if(!e.length)return 0;const n=JSON.stringify(e),s=t.lines.get(n);return null===s.width&&(window.console.warn("Performing unexpected measurement",e),this.performMeasurements()),s.width}_measureWidth(t){if(!t.formatted.length)return 0;const e=this._expectMeasure(t);return t.formatted.map(t=>this._measureLine(e,t)).reduce((t,e)=>Math.max(t,e),0)}_getMeasurementOpts(t,e){const n={attrs:t,formatted:e};if(e||(t.textBlock?(n.attrs=t.textBlock.state.attrs,n.formatted=t.textBlock.state.formatted):t.state&&(n.attrs=t.state.attrs,n.formatted=t.state.formatted),n.formatted=n.formatted||[]),!Array.isArray(n.formatted))throw new Error("Invalid formatted text: "+n.formatted);return n}expectMeasure(t,e){const n=this._getMeasurementOpts(t,e);this._expectMeasure(n)}performMeasurementsPre(){this.active=[],this.cache.forEach(({attrs:t,lines:e})=>{e.forEach(e=>{null===e.width&&this.active.push({cacheLine:e,data:this.sizer.prepMeasurement(t,e.formatted)})})}),this.active.length&&this.sizer.prepComplete()}performMeasurementsAct(){this.active.forEach(({data:t,cacheLine:e})=>{e.width=this.sizer.performMeasurement(t)})}performMeasurementsPost(){this.active.length&&this.sizer.teardown(),this.active=null}performMeasurements(){try{this.performMeasurementsPre(),this.performMeasurementsAct()}finally{this.performMeasurementsPost()}}measure(t,e){const n=this._getMeasurementOpts(t,e);return{height:this.sizer.measureHeight(n),width:this._measureWidth(n)}}baseline(t,e){const n=this._getMeasurementOpts(t,e);return this.sizer.baseline(n)}measureHeight(t,e){const n=this._getMeasurementOpts(t,e);return this.sizer.measureHeight(n)}resetCache(){this.cache.clear()}}class Ve{constructor(t,e=null){this.dom=t,this.body=this.el("svg").attr("xmlns",Oe).attr("version","1.1");const n=e||(t=>new Ne(t));this.textSizer=new Be(n(this)),this.txt=this.txt.bind(this),this.el=this.el.bind(this)}linearGradient(t,e){return this.el("linearGradient").attrs(t).add(e.map(t=>this.el("stop").attrs(t)))}patternedLine(t=null,e=0){return new ze(t,e)}txt(t){return this.dom.txt(t)}el(t,e=Oe){return this.dom.el(t,e)}box(t,e){return this.el("rect").attrs(t).attrs(e)}boxFactory(t){return this.box.bind(this,t)}line(t,e){return this.el("line").attrs(t).attrs(e)}lineFactory(t){return this.line.bind(this,t)}circle(t,{x:e,y:n,radius:s}){return this.el("circle").attrs({cx:e,cy:n,r:s}).attrs(t)}circleFactory(t){return this.circle.bind(this,t)}cross(t,{x:e,y:n,radius:s}){return this.el("path").attr("d","M"+(e-s)+" "+(n-s)+"l"+2*s+" "+2*s+"m0 "+2*-s+"l"+2*-s+" "+2*s).attrs(t)}crossFactory(t){return this.cross.bind(this,t)}note(t,e,n){const s=n.x,r=n.x+n.width,i=n.y,a=n.y+n.height;return this.el("g").add(this.el("polygon").attr("points",s+" "+i+" "+(r-7)+" "+i+" "+r+" "+(i+7)+" "+r+" "+a+" "+s+" "+a).attrs(t),this.el("polyline").attr("points",r-7+" "+i+" "+(r-7)+" "+(i+7)+" "+r+" "+(i+7)).attrs(e))}noteFactory(t,e){return this.note.bind(this,t,e)}formattedText(t={},e=[],n={}){const s=this.el("g"),r=new Le(s,this,{attrs:t,formatted:e,x:n.x,y:n.y});return Object.assign(s,{set:t=>r.set(t),textBlock:r})}formattedTextFactory(t){return this.formattedText.bind(this,t)}boxedText({padding:t,labelAttrs:e,boxAttrs:n={},boxRenderer:s=null},r,{x:i,y:a}){if(!r||!r.length)return Object.assign(this.el("g"),{box:null,height:0,label:null,width:0});const{shift:o,anchorX:h}=function(t,e,n){let s=0,r=t;switch(e["text-anchor"]){case"middle":s=.5,r+=(n.left-n.right)/2;break;case"end":s=1,r-=n.right;break;default:s=0,r+=n.left}return{anchorX:r,shift:s}}(i,e,t),l=this.formattedText(e,r,{x:h,y:a+t.top}),d=this.textSizer.measure(l),g=d.width+t.left+t.right,c=d.height+t.top+t.bottom,u=(s||this.boxFactory(n))({height:c,width:g,x:h-d.width*o-t.left,y:a});return Object.assign(this.el("g").add(u,l),{box:u,height:c,label:l,width:g})}boxedTextFactory(t){return this.boxedText.bind(this,t)}}let He=0;class Te extends mt{constructor({themes:t=[],namespace:e=null,components:n=null,document:s,textSizerFactory:r=null}={}){super(),this._bindMethods(),this.state={},this.width=0,this.height=0,this.themes=function(t){if(0===t.length)throw new Error("Cannot render without a theme");const e=new Map;return t.forEach(t=>{e.set(t.name,t)}),e.set("",t[0]),e}(t),this.themeBuilder=null,this.theme=null,this.namespace=function(t){return null===t?"R"+He++:t}(e),this.components=n||H(),this.svg=new Ve(new Ge(s),r),this.knownThemeDefs=new Set,this.knownDefs=new Set,this.highlights=new Map,this.collapsed=new Set,this.currentHighlight=-1,this.buildStaticElements(),this.components.forEach(t=>{t.makeState(this.state)})}_bindMethods(){this.separationStage=this.separationStage.bind(this),this.prepareMeasurementsStage=this.prepareMeasurementsStage.bind(this),this.renderStage=this.renderStage.bind(this),this.addThemeDef=this.addThemeDef.bind(this),this.addDef=this.addDef.bind(this)}addTheme(t){this.themes.set(t.name,t)}buildStaticElements(){const{el:t}=this.svg;this.metaCode=this.svg.txt(),this.themeDefs=t("defs"),this.defs=t("defs"),this.fullMask=t("mask").attrs({id:this.namespace+"FullMask",maskUnits:"userSpaceOnUse"}),this.lineMask=t("mask").attrs({id:this.namespace+"LineMask",maskUnits:"userSpaceOnUse"}),this.fullMaskReveal=t("rect").attr("fill","#FFFFFF"),this.lineMaskReveal=t("rect").attr("fill","#FFFFFF"),this.backgroundFills=t("g"),this.agentLines=t("g").attr("mask","url(#"+this.namespace+"LineMask)"),this.blocks=t("g"),this.shapes=t("g"),this.unmaskedShapes=t("g"),this.title=this.svg.formattedText(),this.svg.body.add(this.svg.el("metadata").add(this.metaCode),this.themeDefs,this.defs,this.backgroundFills,t("g").attr("mask","url(#"+this.namespace+"FullMask)").add(this.agentLines,this.blocks,this.shapes),this.unmaskedShapes,this.title)}addThemeDef(t,e){const n=this.namespace+t;return this.knownThemeDefs.has(t)||(this.knownThemeDefs.add(t),this.themeDefs.add(e().attr("id",n))),n}addDef(t,e){let n=t,s=e;"function"!=typeof e&&(n="P"+this.knownDefs.size,s=(()=>t));const r=this.namespace+n;return this.knownDefs.has(n)||(this.knownDefs.add(n),this.defs.add(s().attr("id",r))),r}addSeparation(t,e,n){const s=this.agentInfos.get(t),r=this.agentInfos.get(e),i=s.separations.get(e)||0;s.separations.set(e,Math.max(i,n));const a=r.separations.get(t)||0;r.separations.set(t,Math.max(a,n))}checkHidden(t){const e=this.components.get(t.type),n={agentInfos:this.agentInfos,components:this.components,renderer:this,state:this.state,textSizer:this.svg.textSizer,theme:this.theme},s=e.shouldHide(t,n)||{},r=this.hideNest>0;this.hideNest+=s.nest||0;const i=this.hideNest>0;if(this.hideNest<0)throw new Error("Unexpected nesting in "+t.type);return r===i?i:Boolean(s.self)}separationStage(t){const n=new Map,s=this.visibleAgentIDs.slice(),r=[];this.agentInfos.forEach(t=>{const e=t.currentRad;t.currentMaxRad=e,n.set(t.id,{left:e,right:e})});const i={addSeparation:(t,e,n)=>{r.push({agentID1:t,agentID2:e,dist:n})},addSpacing:(t,{left:e,right:s})=>{const r=n.get(t);r.left=Math.max(r.left,e),r.right=Math.max(r.right,s)},agentInfos:this.agentInfos,components:this.components,momentaryAgentIDs:s,renderer:this,state:this.state,textSizer:this.svg.textSizer,theme:this.theme,visibleAgentIDs:this.visibleAgentIDs},a=this.components.get(t.type);if(!a)throw new Error("Unknown component: "+t.type);a.separationPre(t,i),a.separation(t,i),this.checkHidden(t)||(e(s,this.visibleAgentIDs),r.forEach(({agentID1:t,agentID2:e,dist:n})=>{this.addSeparation(t,e,n)}),s.forEach(t=>{const e=this.agentInfos.get(t),r=n.get(t);e.maxRPad=Math.max(e.maxRPad,r.right),e.maxLPad=Math.max(e.maxLPad,r.left),s.forEach(s=>{if(this.agentInfos.get(s).index>=e.index)return;const i=n.get(s);this.addSeparation(t,s,r.left+i.right+this.theme.agentMargin)})}))}prepareMeasurementsStage(t){const e={agentInfos:this.agentInfos,components:this.components,renderer:this,state:this.state,textSizer:this.svg.textSizer,theme:this.theme},n=this.components.get(t.type);if(!n)throw new Error("Unknown component: "+t.type);n.prepareMeasurements(t,e)}checkAgentRange(t,e=0){if(0===t.length)return e;const{left:n,right:s}=W(this.agentInfos,t),r=this.agentInfos.get(n).x,i=this.agentInfos.get(s).x;let a=e;return this.agentInfos.forEach(t=>{t.x>=r&&t.x<=i&&(a=Math.max(a,t.latestY))}),a}markAgentRange(t,e){if(0===t.length)return;const{left:n,right:s}=W(this.agentInfos,t),r=this.agentInfos.get(n).x,i=this.agentInfos.get(s).x;this.agentInfos.forEach(t=>{t.x>=r&&t.x<=i&&(t.latestY=e)})}drawAgentLine(t,e){null!==t.latestYStart&&e>t.latestYStart&&this.agentLines.add(this.theme.renderAgentLine({className:"agent-"+t.index+"-line",options:t.options,width:2*t.currentRad,x:t.x,y0:t.latestYStart,y1:e}))}addHighlightObject(t,e){let n=this.highlights.get(t);n||(n=[],this.highlights.set(t,n)),n.push(e)}forwardEvent(t,e,n,s){t.on(e,this.trigger.bind(this,n,s))}renderStage(t){this.agentInfos.forEach(t=>{const e=t.currentRad;t.currentMaxRad=e});const e={agentInfos:this.agentInfos,components:this.components,renderer:this,state:this.state,textSizer:this.svg.textSizer,theme:this.theme},n=this.components.get(t.type),s=n.renderPre(t,e),{agentIDs:r,topShift:i,asynchronousY:a}=B(s,this.currentY),o=this.checkAgentRange(r,a),h={addDef:this.addDef,agentInfos:this.agentInfos,blockLayer:this.blocks,components:this.components,drawAgentLine:(t,e,n=!1)=>{const s=this.agentInfos.get(t);this.drawAgentLine(s,e),s.latestYStart=n?null:e},fillLayer:this.backgroundFills,fullMaskLayer:this.fullMask,lineMaskLayer:this.lineMask,makeRegion:({stageOverride:e=null,unmasked:n=!1}={})=>{const s=this.svg.el("g").setClass("region"),r=e||t;return this.addHighlightObject(r.ln,s),this.forwardEvent(s,"mouseenter","mouseover",[r]),this.forwardEvent(s,"mouseleave","mouseout",[r]),this.forwardEvent(s,"click","click",[r]),this.forwardEvent(s,"dblclick","dblclick",[r]),s.attach(n?this.unmaskedShapes:this.shapes)},primaryY:o+i,renderer:this,state:this.state,svg:this.svg,textSizer:this.svg.textSizer,theme:this.theme,topY:o};let l=o;this.checkHidden(t)?(h.primaryY=o,n.renderHidden(t,h)):l=Math.max(l,n.render(t,h)||0),this.markAgentRange(r,l),this.currentY=l}positionAgents(){const t=[];this.agentInfos.forEach(e=>{let n=0;e.separations.forEach((t,s)=>{const r=this.agentInfos.get(s);r.index{let n=e.x;e=t,t.anchorRight&&(t.separations.forEach((e,s)=>{const r=this.agentInfos.get(s);r.index>t.index&&(n=Math.min(n,r.x-e))}),t.x=n)}),this.agentInfos.forEach(({x:t,maxRPad:e,maxLPad:n})=>{this.minX=Math.min(this.minX,t-n),this.maxX=Math.max(this.maxX,t+e)})}buildAgentInfos(t){this.agentInfos=new Map,t.forEach((t,e)=>{this.agentInfos.set(t.id,{anchorRight:t.anchorRight,currentMaxRad:0,currentRad:0,formattedLabel:t.formattedLabel,id:t.id,index:e,isVirtualSource:t.isVirtualSource,latestY:0,latestYStart:null,maxLPad:0,maxRPad:0,options:t.options,separations:new Map,x:null})})}updateBounds(t){const e=(this.minX+this.maxX)/2,n=this.svg.textSizer.measure(this.title),s=n.height>0?-this.theme.titleMargin-n.height:0;this.title.set({x:e,y:s});const r=n.width/2,i=this.theme.outerMargin,a=Math.min(this.minX,e-r)-i,o=Math.max(this.maxX,e+r)+i,h=s-i,l=t+i;this.width=o-a,this.height=l-h;const d={height:this.height,width:this.width,x:a,y:h};this.fullMaskReveal.attrs(d),this.lineMaskReveal.attrs(d),this.svg.body.attr("viewBox",a+" "+h+" "+this.width+" "+this.height)}_resetState(){this.components.forEach(t=>{t.resetState(this.state)}),this.currentY=0,this.hideNest=0}_reset(t){t&&(this.knownThemeDefs.clear(),this.themeDefs.empty()),this.knownDefs.clear(),this.highlights.clear(),this.defs.empty(),this.fullMask.empty(),this.lineMask.empty(),this.backgroundFills.empty(),this.agentLines.empty(),this.blocks.empty(),this.shapes.empty(),this.unmaskedShapes.empty(),this.defs.add(this.fullMask.add(this.fullMaskReveal),this.lineMask.add(this.lineMaskReveal)),this._resetState()}setHighlight(t=null){const e=null===t?-1:t;this.currentHighlight!==e&&(this.highlights.has(this.currentHighlight)&&this.highlights.get(this.currentHighlight).forEach(t=>{t.delClass("focus")}),this.highlights.has(e)&&this.highlights.get(e).forEach(t=>{t.addClass("focus")}),this.currentHighlight=e)}isCollapsed(t){return this.collapsed.has(t)}setCollapseAll(t){if(t)throw new Error("Cannot collapse all");return 0!==this.collapsed.size&&(this.collapsed.clear(),!0)}_setCollapsed(t,e){return"number"==typeof t&&(e!==this.isCollapsed(t)&&(e?this.collapsed.add(t):this.collapsed.delete(t),!0))}setCollapsed(t,e=!0){return null===t?this.setCollapseAll(e):Array.isArray(t)?t.map(t=>this._setCollapsed(t,e)).some(t=>t):this._setCollapsed(t,e)}_switchTheme(t){const e=this.themeBuilder;return this.themeBuilder=this.getThemeNamed(t),this.themeBuilder!==e&&(this.theme=this.themeBuilder.build(this.svg)),this.theme.reset(),this.themeBuilder!==e}optimisedRenderPreReflow(t){const e=this._switchTheme(t.meta.theme);this._reset(e),this.metaCode.nodeValue=t.meta.code,this.theme.addDefs(this.addThemeDef),this.title.set({attrs:this.theme.titleAttrs,formatted:t.meta.title}),this.svg.textSizer.expectMeasure(this.title),this.minX=0,this.maxX=0,this.buildAgentInfos(t.agents),t.stages.forEach(this.prepareMeasurementsStage),this._resetState(),this.svg.textSizer.performMeasurementsPre()}optimisedRenderReflow(){this.svg.textSizer.performMeasurementsAct()}optimisedRenderPostReflow(t){this.visibleAgentIDs=["[","]"],t.stages.forEach(this.separationStage),this._resetState(),this.positionAgents(),t.stages.forEach(this.renderStage);const e=this.checkAgentRange(["[","]"],this.currentY),n=Math.max(e-this.theme.actionMargin,0);this.updateBounds(n);const s=this.currentHighlight;this.currentHighlight=-1,this.setHighlight(s),this.svg.textSizer.performMeasurementsPost(),this.svg.textSizer.resetCache()}render(t){this.optimisedRenderPreReflow(t),this.optimisedRenderReflow(),this.optimisedRenderPostReflow(t)}getThemeNames(){return Array.from(this.themes.keys()).filter(t=>""!==t)}getThemes(){return this.getThemeNames().map(t=>this.themes.get(t))}getThemeNamed(t){const e=this.themes.get(t);return e||this.themes.get("")}getAgentX(t){return this.agentInfos.get(t).x}dom(){return this.svg.body.element}}var Pe={name:"Handlee",woff2:"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"};class je{constructor(){this.s=new Uint32Array(4)}reset(){this.s[0]=394173556,this.s[1]=2926575054,this.s[2]=1022685995,this.s[3]=1178902408}nextFloat(){let t=this.s[0],e=this.s[1];const n=this.s[2],s=this.s[3];return this.s[0]=n,this.s[1]=s,t^=t<<23|e>>>9,e^=e<<23,this.s[2]=t^n^t>>>17^n>>>26,this.s[3]=e^s^(t<<15|e>>>17)^(n<<6|s>>>26),(this.s[3]+s>>>0)%4294967296/4294967296}}const qe=Pe.name,Ye="'"+qe+"',cursive",We={normal:{stroke:"rgba(0,0,0,0.7)","stroke-width":.8,"stroke-linejoin":"round","stroke-linecap":"round"},thick:{stroke:"rgba(0,0,0,0.8)","stroke-width":1.2,"stroke-linejoin":"round","stroke-linecap":"round"}},Ue={"font-family":Ye,"font-size":8,"line-height":1.5},Xe={"font-family":Ye,"font-size":8,"line-height":1.5,"text-anchor":"middle"},Qe={};class Je{constructor(t,e){this.deltas=[0,-.3,-.6,-.75,-.45,0,.45,.75,.6,.3],e!==Qe&&this.deltas.reverse(),this.partWidth=6/this.deltas.length}getDelta(t){return this.deltas[t%this.deltas.length]+.5*Math.sin(.03*t)}}class Ze extends st{constructor(t,e=Qe){super(t),this.handedness=e===Qe?1:-1,this.random=new je,this.wave=new Je(4,e);const n={padding:{top:3,bottom:2},tag:{padding:{top:2,left:3,right:5,bottom:0},boxRenderer:this.renderTag.bind(this),labelAttrs:{"font-family":Ye,"font-weight":"bold","font-size":9,"line-height":1.5,"text-anchor":"left"}},label:{minHeight:6,padding:{top:2,left:5,right:3,bottom:1},labelAttrs:{"font-family":Ye,"font-size":8,"line-height":1.5,"text-anchor":"left"}}};Object.assign(this,{titleMargin:10,outerMargin:5,agentMargin:10,actionMargin:10,minActionMargin:3,agentLineHighlightRadius:4,agentCap:{box:{padding:{top:5,left:10,right:10,bottom:5},arrowBottom:12.8,labelAttrs:{"font-family":Ye,"font-size":12,"line-height":1.5,"text-anchor":"middle"},boxRenderer:this.renderBox.bind(this)},database:{padding:{top:12,left:10,right:10,bottom:2},arrowBottom:12.8,boxRenderer:this.renderDB.bind(this,Object.assign({fill:"#FFFFFF","db-z":5},We.normal)),labelAttrs:{"font-family":qe,"font-size":12,"line-height":1.5,"text-anchor":"middle"}},cross:{size:15,render:this.renderCross.bind(this)},bar:{height:6,render:this.renderBar.bind(this)},fade:{width:Math.ceil(12),height:6,extend:Math.ceil(2.5)},none:{height:10}},connect:{loopbackRadius:6,line:{solid:{attrs:Object.assign({fill:"none"},We.normal),renderFlat:this.renderFlatConnect.bind(this),renderRev:this.renderRevConnect.bind(this)},dash:{attrs:Object.assign({fill:"none","stroke-dasharray":"4, 2"},We.normal),renderFlat:this.renderFlatConnect.bind(this),renderRev:this.renderRevConnect.bind(this)},wave:{attrs:Object.assign({fill:"none","stroke-linejoin":"round","stroke-linecap":"round"},We.normal),renderFlat:this.renderFlatConnectWave.bind(this),renderRev:this.renderRevConnectWave.bind(this)}},arrow:{single:{width:5,height:6,attrs:Object.assign({fill:"rgba(0,0,0,0.9)"},We.normal),render:this.renderArrowHead.bind(this)},double:{width:4,height:8,attrs:Object.assign({fill:"none"},We.normal),render:this.renderArrowHead.bind(this)},cross:{short:5,radius:3,render:this.renderCross.bind(this)}},label:{padding:6,margin:{top:2,bottom:1},attrs:{"font-family":Ye,"font-size":8,"line-height":1.5,"text-anchor":"middle"},loopbackAttrs:{"font-family":Ye,"font-size":8,"line-height":1.5}},source:{radius:1,render:t.circleFactory({fill:"#000000",stroke:"#000000","stroke-width":1})},mask:{padding:{top:0,left:3,right:3,bottom:1}}},titleAttrs:{"font-family":Ye,"font-size":20,"line-height":1.5,"text-anchor":"middle",class:"title"},agentLineAttrs:{"":Object.assign({fill:"none"},We.normal),red:{stroke:"rgba(200,40,0,0.8)"}},blocks:{ref:{margin:{top:0,bottom:0},boxRenderer:this.renderRefBlock.bind(this),section:n},"":{margin:{top:0,bottom:0},boxRenderer:this.renderBlock.bind(this),collapsedBoxRenderer:this.renderMinBlock.bind(this),section:n,sepRenderer:this.renderSeparator.bind(this)}},notes:{text:{margin:{top:0,left:6,right:6,bottom:0},padding:{top:2,left:2,right:2,bottom:2},overlap:{left:10,right:10},boxRenderer:t.boxFactory({fill:"#FFFFFF"}),labelAttrs:Ue},note:{margin:{top:0,left:5,right:5,bottom:0},padding:{top:5,left:5,right:10,bottom:5},overlap:{left:10,right:10},boxRenderer:this.renderNote.bind(this),labelAttrs:Ue},state:{margin:{top:0,left:5,right:5,bottom:0},padding:{top:7,left:7,right:7,bottom:7},overlap:{left:10,right:10},boxRenderer:this.renderState.bind(this),labelAttrs:Ue}},dividers:{"":{labelAttrs:Xe,padding:{top:2,left:5,right:5,bottom:2},extend:0,margin:0,render:()=>({})},line:{labelAttrs:Xe,padding:{top:2,left:5,right:5,bottom:2},extend:10,margin:0,render:this.renderLineDivider.bind(this)},delay:{labelAttrs:Xe,padding:{top:2,left:5,right:5,bottom:2},extend:0,margin:0,render:this.renderDelayDivider.bind(this,{dotSize:1,gapSize:2})},tear:{labelAttrs:Xe,padding:{top:2,left:5,right:5,bottom:2},extend:10,margin:10,render:this.renderTearDivider.bind(this,{fadeBegin:5,fadeSize:10,pattern:this.wave,lineAttrs:We.normal})}}})}reset(){this.random.reset()}addDefs(t){t("sketch_font",()=>{const t=this.svg.el("style",null);return t.text('@font-face{font-family:"'+Pe.name+'";src:url("data:font/woff2;base64,'+Pe.woff2+'");}'),t})}vary(t,e=0){if(!t)return e;const n=this.random.nextFloat();return e+2*Math.asin(2*n-1)*t/Math.PI}lineNodes(t,e,{var1:n=1,var2:s=1,varX:r=1,varY:i=1,move:a=!0}){const o=Math.sqrt((e.x-t.x)*(e.x-t.x)+(e.y-t.y)*(e.y-t.y)),h=Math.min(.2*Math.sqrt(o),5),l=this.vary(n*r*h,t.x),d=this.vary(n*i*h,t.y),g=this.vary(s*r*h,e.x),c=this.vary(s*i*h,e.y),u=function(t,e,n){return Math.max(e,Math.min(n,t))}((d-c)/(Math.abs(l-g)+.001),-1,1)/6+.5,p=this.vary(.5,.5)*h,f=this.vary(.5,.5)*h,m=l*(1-u)+g*u-p*this.handedness;return{nodes:(a?"M"+l+" "+d:"")+"C"+m+" "+(d*(1-u)+c*u-f)+","+g+" "+c+","+g+" "+c,p1:{x:l,y:d},p2:{x:g,y:c}}}renderLine(t,e,n){const s=this.lineNodes(t,e,n);return this.svg.el("path").attrs({d:s.nodes,fill:"none","stroke-dasharray":n.dash?"6, 5":"none"}).attrs(n.attrs||(n.thick?We.thick:We.normal))}boxNodes({x:t,y:e,width:n,height:s}){const r=this.lineNodes({x:t,y:e},{x:t+n,y:e},{}),i=this.lineNodes({x:t+n,y:e+s},{x:t,y:e+s},{move:!1}),a=this.lineNodes(r.p2,i.p1,{var1:0,var2:0,move:!1}),o=this.lineNodes(i.p2,r.p1,{var1:0,var2:.3,move:!1});return r.nodes+a.nodes+i.nodes+o.nodes}renderBox(t,{fill:e=null,thick:n=!1,attrs:s=null}={}){return this.svg.el("path").attrs({d:this.boxNodes(t),fill:e||"#FFFFFF"}).attrs(s||(n?We.thick:We.normal))}renderNote({x:t,y:e,width:n,height:s}){const r=this.lineNodes({x:t,y:e},{x:t+n-5,y:e},{}),i=this.lineNodes(r.p2,{x:t+n,y:e+5},{move:!1,var1:0}),a=this.lineNodes({x:t+n,y:e+s},{x:t,y:e+s},{move:!1}),o=this.lineNodes(i.p2,a.p1,{var1:0,var2:0,move:!1}),h=this.lineNodes(a.p2,r.p1,{var1:0,var2:.3,move:!1}),l=this.lineNodes(i.p1,{x:t+n-5,y:e+5},{var1:.3}),d=this.lineNodes(l.p2,i.p2,{var1:0,move:!1});return this.svg.el("g").add(this.svg.el("path").attrs({d:r.nodes+i.nodes+o.nodes+a.nodes+h.nodes,fill:"#FFFFFF"}).attrs(We.normal),this.svg.el("path").attrs({d:l.nodes+d.nodes,fill:"none"}).attrs(We.normal))}renderLineDivider({x:t,y:e,labelWidth:n,width:s,height:r}){let i=null;const a=e+r/2;return i=n>0?this.svg.el("g").add(this.renderLine({x:t,y:a},{x:t+(s-n)/2,y:a},{}),this.renderLine({x:t+(s+n)/2,y:a},{x:t+s,y:a},{})):this.renderLine({x:t,y:a},{x:t+s,y:a},{}),{shape:i}}renderFlatConnect(t,{x1:e,y1:n,x2:s,y2:r}){const i=this.lineNodes({x:e,y:n},{x:s,y:r},{varX:.3});return{shape:this.svg.el("path").attr("d",i.nodes).attrs(t),p1:i.p1,p2:i.p2}}renderRevConnect(t,{x1:e,y1:n,x2:s,y2:r,xR:i}){const a=Math.min(.06*(i-e),3),o=Math.min(.5*(i-e),6),h=e+this.vary(a,-1),l=n+this.vary(a,-1),d=i-o*this.vary(.2,1),g=n-this.vary(1,2),c=i,u=n+this.vary(1,1),p=i,f=r+this.vary(2),m=s+this.vary(a,-1),b=r+this.vary(a,-1);return{shape:this.svg.el("path").attr("d","M"+h+" "+l+"C"+h+" "+l+","+d+" "+g+","+c+" "+u+"S"+p+" "+f+","+m+" "+b).attrs(t),p1:{x:h,y:l},p2:{x:m,y:b}}}renderFlatConnectWave(t,{x1:e,y1:n,x2:s,y2:r}){const i=e+this.vary(.3),a=s+this.vary(.3),o=n+this.vary(1),h=r+this.vary(1);return{shape:this.svg.el("path").attr("d",this.svg.patternedLine(this.wave).move(i,o).line(a,h).cap().asPath()).attrs(t),p1:{x:i,y:o},p2:{x:a,y:h}}}renderRevConnectWave(t,{x1:e,y1:n,x2:s,y2:r,xR:i}){const a=e+this.vary(.3),o=s+this.vary(.3),h=n+this.vary(1),l=r+this.vary(1);return{shape:this.svg.el("path").attr("d",this.svg.patternedLine(this.wave).move(a,h).line(i,n).arc(i,(n+r)/2,Math.PI).line(o,l).cap().asPath()).attrs(t),p1:{x:a,y:h},p2:{x:o,y:l}}}renderArrowHead(t,{x:e,y:n,width:s,height:r,dir:i}){const a=s*this.vary(.2,1),o=r*this.vary(.3,1),h=a*i.dx,l=a*i.dy,d=.5*o*i.dx,g=.5*-o*i.dy,c=this.lineNodes({x:e+h-g,y:n+l-d},{x:e,y:n},{var1:2,var2:.2}),u=this.lineNodes(c.p2,{x:e+h+g,y:n+l+d},{var1:0,var2:2,move:!1}),p="none"===t.fill?{nodes:""}:this.lineNodes(u.p2,c.p1,{var1:0,var2:0,move:!1});return this.svg.el("path").attr("d",c.nodes+u.nodes+p.nodes).attrs(t)}renderState({x:t,y:e,width:n,height:s}){const r=Math.min(.06*n,3),i=Math.min(.06*s,3),a=t+r*this.vary(.6,1),o=e+i*this.vary(.6,1),h=t+n-r*this.vary(.6,1),l=e+i*this.vary(.6,1),d=t+r*this.vary(.6,1),g=e+s-i*this.vary(.6,1),c=t+n-r*this.vary(.6,1),u=e+s-i*this.vary(.6,1),p=t+n/2,f=e+s/2,m=r*this.vary(.2,1.2),b=i*this.vary(.2,1.2),y=e-Math.min(.005*n,1),x=e+s-Math.min(.01*n,2),k=t-Math.min(.01*s,2)*this.handedness,w=k+n;return this.svg.el("path").attr("d","M"+a+" "+o+"C"+(a+m)+" "+(o-b)+","+(p-n*this.vary(.03,.3))+" "+y+","+p+" "+y+"S"+(h-m)+" "+(l-b)+","+h+" "+l+"S"+w+" "+(f-s*this.vary(.03,.3))+","+w+" "+f+"S"+(c+m)+" "+(u-b)+","+c+" "+u+"S"+(p+n*this.vary(.03,.3))+" "+x+","+p+" "+x+"S"+(d+m)+" "+(g+b)+","+d+" "+g+"S"+k+" "+(f+s*this.vary(.03,.3))+","+k+" "+f+"S"+(a-m)+" "+(o+b)+","+a+" "+o+"Z").attr("fill","#FFFFFF").attrs(We.normal)}renderRefBlock(t){const e=this.boxNodes(t);return{shape:this.svg.el("path").attrs({d:e,fill:"none"}).attrs(We.thick),mask:this.svg.el("path").attrs({d:e,fill:"#000000"}),fill:this.svg.el("path").attrs({d:e,fill:"#FFFFFF"})}}renderBlock(t){return this.renderBox(t,{fill:"none",thick:!0})}renderMinBlock(t){return this.renderRefBlock(t)}renderTag({x:t,y:e,width:n,height:s}){const r=t+n,i=e+s,a=this.lineNodes({x:r+3,y:e},{x:r-2,y:i},{}),o=this.lineNodes(a.p2,{x:t,y:i+1},{var1:0,move:!1}),h=a.nodes+o.nodes;return this.svg.el("g").add(this.svg.el("path").attrs({d:h+"L"+t+" "+e,fill:"#FFFFFF"}),this.svg.el("path").attrs({d:h,fill:"#FFFFFF"}).attrs(We.normal))}renderSeparator({x1:t,y1:e,x2:n,y2:s}){return this.renderLine({x:t,y:e},{x:n,y:s},{thick:!0,dash:!0})}renderBar({x:t,y:e,width:n,height:s}){return this.renderBox({x:t,y:e,width:n,height:s},{fill:"#000000"})}renderCross({x:t,y:e,radius:n}){const s=this.vary(.2,1)*n,r=this.lineNodes({x:t-s,y:e-s},{x:t+s,y:e+s},{}),i=this.vary(.2,1)*n,a=this.lineNodes({x:t+i,y:e-i},{x:t-i,y:e+i},{});return this.svg.el("path").attrs({d:r.nodes+a.nodes,fill:"none"}).attrs(We.normal)}renderAgentLine({x:t,y0:e,y1:n,width:s,className:r,options:i}){const a=this.optionsAttributes(this.agentLineAttrs,i);return s>0?this.renderBox({x:t-s/2,y:e,width:s,height:n-e},{fill:"none",attrs:a}).setClass(r):this.renderLine({x:t,y:e},{x:t,y:n},{varY:.3,attrs:a}).setClass(r)}}class Ke{constructor(t=Qe){const e=t===Qe;this.name=e?"sketch":"sketch left handed",this.handedness=t}build(t){return new Ze(t,this.handedness)}}Object.assign(Ke,{RIGHT:Qe,LEFT:{}});const _e=/^([ \t]*)(.*)$/,$e={after:".!+",end:/[ \t\r\n]$/,start:/^[ \t\r\n:,]/},tn=/^"(\\.|[^"])*$/,en=/[\r\n:,"<>\-~]/,nn=/["\\]/g,sn=[new lt,new It,new ft,new Ke(Ke.RIGHT),new Ke(Ke.LEFT)],rn=new Zt,an=new Mt,on=rn.getCodeMirrorMode();class hn extends mt{constructor(t=null,e={}){super();let n=null;t&&"object"==typeof t?(n=t,this.code=n.code):(n=e,this.code=t),Object.assign(this,{exporter:new yt,generator:an,isInteractive:!1,latestProcessed:null,parser:rn,registerCodeMirrorMode:K,renderer:new Te(Object.assign({document:function(t){return t?t.ownerDocument:window.document}(n.container),themes:sn},n)),textSizerFactory:n.textSizerFactory||null}),this.renderer.addEventForwarding(this),n.container&&n.container.appendChild(this.dom()),n.interactive&&this.addInteractivity(),"string"==typeof this.code&&!1!==n.render&&this.render()}clone(t={}){const e=t.container||this.renderer.dom();return new hn(Object.assign({code:this.code,components:this.renderer.components,container:null,document:e.ownerDocument,interactive:this.isInteractive,namespace:null,textSizerFactory:this.textSizerFactory,themes:this.renderer.getThemes()},t))}set(t="",{render:e=!0}={}){this.code!==t&&(this.code=t,e&&this.render())}process(t){const e=this.parser.parse(t);return this.generator.generate(e)}addTheme(t){this.renderer.addTheme(t)}setHighlight(t){this.renderer.setHighlight(t)}isCollapsed(t){return this.renderer.isCollapsed(t)}setCollapsed(t,e=!0,{render:n=!0}={}){return!!this.renderer.setCollapsed(t,e)&&(n&&this.latestProcessed&&this.render(this.latestProcessed),!0)}collapse(t,e){return this.setCollapsed(t,!0,e)}expand(t,e){return this.setCollapsed(t,!1,e)}toggleCollapsed(t,e){return this.setCollapsed(t,!this.isCollapsed(t),e)}expandAll(t){return this.setCollapsed(null,!1,t)}getThemeNames(){return this.renderer.getThemeNames()}getThemes(){return this.renderer.getThemes()}getSVGSynchronous(){return this.exporter.getSVGURL(this.renderer)}getSVG(){return Promise.resolve({latest:!0,url:this.getSVGSynchronous()})}getCanvas({resolution:t=1,size:e=null}={}){return e&&(this.renderer.width=e.width,this.renderer.height=e.height),new Promise(e=>{this.exporter.getCanvas(this.renderer,t,e)})}getPNG({resolution:t=1,size:e=null}={}){return e&&(this.renderer.width=e.width,this.renderer.height=e.height),new Promise(e=>{this.exporter.getPNGURL(this.renderer,t,(t,n)=>{e({latest:n,url:t})})})}getSize(){return{height:this.renderer.height,width:this.renderer.width}}_revertParent(t){const e=this.renderer.dom();e.parentNode!==t.originalParent&&(e.parentNode.removeChild(e),t.originalParent&&t.originalParent.appendChild(e))}_sendRenderError(t){this._revertParent(this.renderState),this.renderState.error=!0,this.trigger("error",[this,t])}optimisedRenderPreReflow(t=null){const e=this.renderer.dom();this.renderState={error:!1,originalParent:e.parentNode,processed:t};const n=this.renderState;e.isConnected||(n.originalParent&&n.originalParent.removeChild(e),e.ownerDocument.body.appendChild(e));try{n.processed||(n.processed=this.process(this.code)),this.renderer.optimisedRenderPreReflow(n.processed)}catch(t){this._sendRenderError(t)}}optimisedRenderReflow(){try{this.renderState.error||this.renderer.optimisedRenderReflow()}catch(t){this._sendRenderError(t)}}optimisedRenderPostReflow(){const t=this.renderState;try{t.error||this.renderer.optimisedRenderPostReflow(t.processed)}catch(t){this._sendRenderError(t)}this.renderState=null,t.error||(this._revertParent(t),this.latestProcessed=t.processed,this.trigger("render",[this]))}render(t=null){function e(t,e){n=e}let n=null;if(this.addEventListener("error",e),this.optimisedRenderPreReflow(t),this.optimisedRenderReflow(),this.optimisedRenderPostReflow(),this.removeEventListener("error",e),n)throw n}setContainer(t=null){const e=this.dom();e.parentNode&&e.parentNode.removeChild(e),t&&t.appendChild(e)}addInteractivity(){this.isInteractive||(this.isInteractive=!0,this.addEventListener("click",t=>{this.toggleCollapsed(t.ln)}))}extractCodeFromSVG(t){return _(t)}renderAll(t){return $(t)}dom(){return this.renderer.dom()}}Object.assign(hn,{Exporter:yt,Generator:Mt,Parser:Zt,Renderer:Te,addTheme:function(t){sn.push(t)},convert:et,convertAll:function(t=null,e="sequence-diagram"){let n=null,s=null;"string"==typeof t?(n=null,s=t):(n=t,s=e);let r=null;r=n&&void 0!==n.length?n:(n||window.document).getElementsByClassName(s);const i=[];for(let t=0;thn):(window.document.addEventListener("DOMContentLoaded",()=>{hn.convertAll()},{once:!0}),window.CodeMirror&&hn.registerCodeMirrorMode(window.CodeMirror),window.SequenceDiagram=hn)}();
\ No newline at end of file
+!function(){"use strict";function t(t,e,n=null){if(null===n)return t.indexOf(e);for(let s=0;s=t.length)return void s.push(n.slice());const r=t[e];if(!Array.isArray(r))return n.push(r),i(t,e+1,n,s),void n.pop();for(let a=0;a{n.push(...e(t))}),n}function o(t,e){const n=St[t.type];return!(!n||t.type!==e.type)&&!n.check.some(n=>t[n]!==e[n])}function h(t,n){St[t.type].merge.forEach(s=>{e(t[s],n[s])})}function l(t,e){for(let n=0;n{for(let s=0;st);return n.forEach(t=>{const s=St[t];s&&n.every(e=>t===e||s.siblings.has(e))&&e.add(t)}),e}function c(t,e,n,s){l(s,s=>{if(!t.has(s.type)||!e.has(s.type))return!1;for(let t=0;t{"agent begin"===t.type&&(t.mode=e,n=!0)}),n}return!1}function p(t,e,n,r=null){s(t,e,At.equals),s(t,n,At.equals);let i=0,a=t.length;if(r){const e=r.map(e=>At.indexOf(t,e)).filter(t=>-1!==t);i=e.reduce((t,e)=>Math.min(t,e),t.length),a=e.reduce((t,e)=>Math.max(t,e),i)+1}return t.splice(i,0,e),t.splice(a+1,0,n),{indexL:i,indexR:a+1}}function f(t,e=!1){return{type:"string",suggest:e,then:Object.assign({"":0},t)}}function m(t,e){return t.v===e.v&&t.prefix===e.prefix&&t.suffix===e.suffix&&t.q===e.q}function b(t,e,n){let s=n.suggest;return Array.isArray(s)||(s=[s]),a(s,s=>!1===s?[]:"object"==typeof s?s.known?t["known"+s.known]||[]:[s]:"string"==typeof s&&s?[{v:s,q:""===e}]:[function(t,e){return Object.keys(e.then).length>0?{v:t,suffix:" ",q:!1}:{v:t,suffix:"\n",q:!1}}(e,n)])}function y(t,n){const s=[],i=r(n);return Object.keys(i.then).forEach(r=>{let a=i.then[r];"number"==typeof a&&(a=n[n.length-a-1]),e(s,b(t,r,a),m)}),s}function x(t,n,s,{suggest:r,override:i}){let a=null;"object"==typeof r&&r.known&&(a=r.known),n.type&&a!==n.type&&(i&&(n.type=i),e(t["known"+n.type],[{v:n.value,suffix:" ",q:!0}],m),n.type="",n.value=""),a&&(n.type=a,n.value&&(n.value+=s.s),n.value+=s.v)}function k(t,e,n){const s={type:"",value:""};let i=n;const a=[i];return t.line.forEach((e,n)=>{n===t.line.length-1&&(t.completions=y(t,a));const o=e.q?"":e.v;let h=i.then[o];void 0===h?(h=i.then[""],t.isVar=!0):t.isVar=e.q,"number"==typeof h?a.length-=h:a.push(h||Nt),i=r(a),x(t,s,e,i)}),e&&x(t,s,null,{}),t.nextCompletions=y(t,a),t.valid=Boolean(i.then["\n"])||0===Object.keys(i.then).length,i.type}function w(t){const e=t.baseToken||{};return{value:e.v||"",quoted:e.q||!1}}function v(t,e,n){return e.lastIndex=n,e.exec(t)}function A(t,e,n){return n?function(t,e,n){if(n.escape){const s=v(t,n.escape,e);if(s)return{appendSpace:"",appendValue:n.escapeWith(s),end:!1,newBlock:null,skip:s[0].length}}const s=v(t,n.end,e);return s?{appendSpace:"",appendValue:n.includeEnd?s[0]:"",end:!0,newBlock:null,skip:s[0].length}:{appendSpace:"",appendValue:t[e],end:!1,newBlock:null,skip:1}}(t,e,n):function(t,e){for(let n=0;n"}function R(t,e,n){const s=" "+t+" ";let r=-1,i=s.length,a=0;return qt.forEach(({begin:t,end:o},h)=>{const l=n[h]?o:t;l.lastIndex=e;const d=l.exec(s);d&&(d.indexa)&&(r=h,i=d.index,a=l.lastIndex)}),{end:a-1,start:i,styleIndex:r}}function C(t,e){if(!t)return null;const n={};return e.forEach((t,e)=>{t&&Object.assign(n,qt[e].attrs)}),n}function E(t){if(!t)return[];const e=qt.map(()=>!1);let n=0,s=null;const r=[];return t.split("\n").forEach(t=>{const i=[];let a=0;for(;;){const{styleIndex:r,start:o,end:h}=R(t,a,e);if(-1===r)break;e[r]?(e[r]=!1,--n):(e[r]=!0,++n),o>a&&i.push({attrs:s,text:t.substring(a,o)}),s=C(n,e),a=h}a=n)&&(a=n),e>=a&&!i){let n=t[e];throw n||(n={b:r(t).e}),G("Missing agent name",n)}return{name:I(t,e,a),alias:I(t,a+1,n)}}(t,h,n,{enableAlias:i,allowBlankName:l});return{name:d,alias:g,flags:d?a:o}}function O(t,e,n,s){const r=[];let i=-1;for(let a=e;a{const r=t.get(e);(null===n||r.indexs.index)&&(s=r)}),{left:n.id,right:s.id}}function P(t=null,e=null){return null===t?e:null===e?t:Math.max(t,e)}function j(t,n){return e(t.agentIDs,n.agentIDs),{agentIDs:t.agentIDs,asynchronousY:P(t.asynchronousY,n.asynchronousY),topShift:Math.max(t.topShift,n.topShift),y:P(t.y,n.y)}}function q(t){return null===t?null:t.element?t.element:t}function Y(t,e,n){if(!Array.isArray(n))throw new Error("Invalid formatted text line: "+n);n.forEach(({text:n,attrs:s})=>{s?e.add(t.el("tspan").attrs(s).add(n)):e.add(n)})}function W(t,e){let n=null,s=null;return e.forEach(e=>{const r=t.get(e);(null===n||r.indexs.index)&&(s=r)}),{left:n.id,right:s.id}}function U(t,e){return t.v===e.v&&t.prefix===e.prefix&&t.suffix===e.suffix&&t.q===e.q}function X(t,e,n){const s=t.getLine(e),r={squash:{ch:n,line:e},word:{ch:n,line:e}};return n>0&&" "===s[n-1]&&(tn.after.includes(s[n-2])&&r.word.ch--,r.squash.ch--),r}function Q(t,e,n){const s=function({v:t,q:e,prefix:n="",suffix:s=""},r){const i=r||!nn.test(t)?r:'"';return n+(i&&e?i+t.replace(sn,"\\$&")+i:t)+s}(t,n),r=t.q?e.fromVar:e.fromKey;return"\n"===s?{className:"pick-virtual",displayFrom:null,displayText:"",from:r.squash,text:"\n",to:e.to.squash}:{className:null,displayFrom:r.word,displayText:s.trim(),from:tn.start.test(s)?r.squash:r.word,text:s,to:tn.end.test(s)?e.to.squash:e.to.word}}function J({global:t,prefix:e="",suffix:n=""},s){const r=s[t];return r?r.map(t=>({prefix:e,q:!0,suffix:n,v:t})):[]}function Z(t,n){const s=t.getCursor(),i=function(t,e){const n=t.getLineTokens(e.line);for(let t=0;t=e.ch){n.length=t+1;break}return n}(t,s),a=r(i)||t.getTokenAt(s),o=function(t,e){let n="",s=0,r=0;t.forEach(t=>{t.state.isVar?(n+=t.string,r=t.end):(n="",s=t.end)}),r>e.ch&&(n=n.substr(0,e.ch-s));const i=$e.exec(n);n=i[2];let a="";return en.test(n)&&(a=n.charAt(0),n=n.substr(1)),{from:s+i[1].length,partial:n,quote:a,valid:r>=s}}(i,s),h=function(t,e){let n=t.string;t.end>e.ch&&(n=n.substr(0,e.ch-t.start));const s=$e.exec(n);return{from:t.start+s[1].length,partial:s[2],valid:!0}}(a,s),l=s.ch>0&&a.state.line.length>0;let d=l?a.state.completions:a.state.beginCompletions;l||(d=d.concat(a.state.knownAgent)),function(t,n={}){for(let s=0;s(t.q||!o.quote)&&function(t,e){return e.valid&&t.startsWith(e.partial)}(t.v,t.q?o:h)).map(t=>n.completeSingle||t.v!==(t.q?o:h).partial?Q(t,g,o.quote):(c=t,null)).filter(t=>null!==t);return c&&u.length>0&&u.unshift(Q(c,g,o.quote)),{from:function(t,e){let n=null;return t.forEach(({displayFrom:t})=>{t&&(!n||t.line>n.line||t.line===n.line&&t.ch>n.ch)&&(n=t)}),n||e.word}(u,g.fromKey),list:u,to:g.to.word}}function K(t,e="sequence"){const n=t||window.CodeMirror;n.defineMode(e,()=>hn),n.registerHelper("hint",e,Z)}function _(t){const e=(new DOMParser).parseFromString(t,"image/svg+xml").querySelector("metadata");return e?e.textContent:""}function $(t){function e(t,e){n.push(e)}const n=[];if(t.forEach(t=>{t.addEventListener("error",e),t.optimisedRenderPreReflow()}),t.forEach(t=>{t.optimisedRenderReflow()}),t.forEach(t=>{t.optimisedRenderPostReflow(),t.removeEventListener("error",e)}),n.length>0)throw n}function tt(t,e=null,n={}){if("svg"===t.tagName)return null;const s=function(t){return{interactive:function(t){return void 0!==t&&"false"!==t}(t.dataset.sdInteractive),namespace:t.dataset.sdNamespace||null}}(t),r=new ln(null===e?t.textContent:e,Object.assign(s,n)),i=r.dom(),a=t.attributes;for(let t=0;ttt(t,s,e));return!1!==r.render&&$(n),n}return tt(t,s,r)}class nt{constructor(t,e){Array.isArray(e)?this.deltas=e:this.deltas=[0,2*-e/3,-e,2*-e/3,0,2*e/3,e,2*e/3],this.partWidth=t/this.deltas.length}getDelta(t){return this.deltas[t%this.deltas.length]}}class st{constructor(t){this.svg=t}reset(){}addDefs(){}getBlock(t){return this.blocks[t]||this.blocks[""]}getNote(t){return this.notes[t]||this.notes[""]}getDivider(t){return this.dividers[t]||this.dividers[""]}optionsAttributes(t,e){return function(t,e){const n=Object.assign({},t[""]);return e.forEach(e=>{Object.assign(n,t[e]||{})}),n}(t,e)}renderAgentLine({x:t,y0:e,y1:n,width:s,className:r,options:i}){const a=this.optionsAttributes(this.agentLineAttrs,i);return s>0?this.svg.box(a,{x:t-s/2,y:e,width:s,height:n-e}).addClass(r):this.svg.line(a,{x1:t,x2:t,y1:e,y2:n}).addClass(r)}renderArrowHead(t,{x:e,y:n,width:s,height:r,dir:i}){const a=s*i.dx,o=s*i.dy,h=.5*r*i.dx,l=.5*-r*i.dy;return this.svg.el("none"===t.fill?"polyline":"polygon").attr("points",e+a-l+" "+(n+o-h)+" "+e+" "+n+" "+(e+a+l)+" "+(n+o+h)).attrs(t)}renderTag(t,{x:e,y:n,width:s,height:r}){const{rx:i,ry:a}=t,o=e+s,h=n+r,l="M"+o+" "+n+"L"+o+" "+(h-a)+"L"+(o-i)+" "+h+"L"+e+" "+h,d=this.svg.el("g");return"none"!==t.fill&&d.add(this.svg.el("path").attr("d",l+"L"+e+" "+n).attrs(t).attr("stroke","none")),"none"!==t.stroke&&d.add(this.svg.el("path").attr("d",l).attrs(t).attr("fill","none")),d}renderDB(t,e){const n=t["db-z"];return this.svg.el("g").add(this.svg.box({rx:e.width/2,ry:n},e).attrs(t),this.svg.el("path").attr("d","M"+e.x+" "+(e.y+n)+"a"+e.width/2+" "+n+" 0 0 0 "+e.width+" 0").attrs(t).attr("fill","none"))}renderRef(t,e){return{shape:this.svg.box(t,e).attrs({fill:"none"}),mask:this.svg.box(t,e).attrs({fill:"#000000",stroke:"none"}),fill:this.svg.box(t,e).attrs({stroke:"none"})}}renderFlatConnect(t,e,{x1:n,y1:s,x2:r,y2:i}){return{shape:this.svg.el("path").attr("d",this.svg.patternedLine(t).move(n,s).line(r,i).cap().asPath()).attrs(e),p1:{x:n,y:s},p2:{x:r,y:i}}}renderRevConnect(t,e,{x1:n,y1:s,x2:r,y2:i,xR:a,rad:o}){const h=(i-s)/2,l=this.svg.patternedLine(t).move(n,s).line(a,s);return o0?this.svg.el("g").add(this.svg.line({fill:"none"},{x1:e,x2:e+(r-s)/2,y1:o,y2:o}).attrs(t),this.svg.line({fill:"none"},{x1:e+(r+s)/2,x2:e+r,y1:o,y2:o}).attrs(t)):this.svg.line({fill:"none"},{x1:e,x2:e+r,y1:o,y2:o}).attrs(t),{shape:a}}renderDelayDivider({dotSize:t,gapSize:e},{x:n,y:s,width:r,height:i}){const a=this.svg.el("g");for(let o=0;o+e<=i;o+=t+e)a.add(this.svg.box({fill:"#000000"},{x:n,y:s+o,width:r,height:e}));return{mask:a}}renderTearDivider({fadeBegin:t,fadeSize:e,pattern:n,zigWidth:s,zigHeight:r,lineAttrs:i},{x:a,y:o,labelWidth:h,labelHeight:l,width:d,height:g,env:c}){const u=c.addDef("tear-grad",()=>{const n=100/d;return this.svg.linearGradient({},[{offset:t*n+"%","stop-color":"#000000"},{offset:(t+e)*n+"%","stop-color":"#FFFFFF"},{offset:100-(t+e)*n+"%","stop-color":"#FFFFFF"},{offset:100-t*n+"%","stop-color":"#000000"}])}),p=this.svg.el("mask").attr("maskUnits","userSpaceOnUse").add(this.svg.box({fill:"url(#"+u+")"},{x:a,y:o-5,width:d,height:g+10})),f=c.addDef(p);h>0&&p.add(this.svg.box({rx:2,ry:2,fill:"#000000"},{x:a+(d-h)/2,y:o+(g-l)/2-1,width:h,height:l+2}));const m=n||new nt(s,[r,-r]);let b=null;const y=this.svg.patternedLine(m).move(a,o).line(a+d,o),x=this.svg.el("g").attr("mask","url(#"+f+")").add(this.svg.el("path").attrs({d:y.asPath(),fill:"none"}).attrs(i));if(g>0){const t=this.svg.patternedLine(m).move(a,o+g).line(a+d,o+g);x.add(this.svg.el("path").attrs({d:t.asPath(),fill:"none"}).attrs(i)),y.line(t.x,t.y,{patterned:!1}).cap(),y.points.push(...t.points.reverse()),b=this.svg.el("path").attrs({d:y.asPath(),fill:"#000000"})}return{shape:x,mask:b}}}const rt="sans-serif",it=new nt(6,.5),at={"font-family":rt,"font-size":8,"line-height":1.3},ot={"font-family":rt,"font-size":8,"line-height":1.3,"text-anchor":"middle"};class ht extends st{constructor(t){super(t);const e={padding:{top:3,bottom:2},tag:{padding:{top:1,left:3,right:3,bottom:0},boxRenderer:this.renderTag.bind(this,{fill:"#FFFFFF",stroke:"#000000","stroke-width":1,rx:2,ry:2}),labelAttrs:{"font-family":rt,"font-weight":"bold","font-size":9,"line-height":1.3,"text-anchor":"left"}},label:{minHeight:4,padding:{top:1,left:5,right:3,bottom:1},labelAttrs:{"font-family":rt,"font-size":8,"line-height":1.3,"text-anchor":"left"}}};Object.assign(this,{titleMargin:10,outerMargin:5,agentMargin:10,actionMargin:10,minActionMargin:3,agentLineHighlightRadius:4,agentCap:{box:{padding:{top:5,left:10,right:10,bottom:5},arrowBottom:12.8,boxAttrs:{fill:"#FFFFFF",stroke:"#000000","stroke-width":1},labelAttrs:{"font-family":rt,"font-size":12,"line-height":1.3,"text-anchor":"middle"}},database:{padding:{top:12,left:10,right:10,bottom:3},arrowBottom:12.8,boxRenderer:this.renderDB.bind(this,{fill:"#FFFFFF",stroke:"#000000","stroke-width":1,"db-z":5}),labelAttrs:{"font-family":rt,"font-size":12,"line-height":1.3,"text-anchor":"middle"}},cross:{size:20,render:t.crossFactory({fill:"none",stroke:"#000000","stroke-width":1})},bar:{height:4,render:t.boxFactory({fill:"#000000",stroke:"#000000","stroke-width":1})},fade:{width:5,height:6,extend:1},none:{height:10}},connect:{loopbackRadius:6,line:{solid:{attrs:{fill:"none",stroke:"#000000","stroke-width":1},renderFlat:this.renderFlatConnect.bind(this,null),renderRev:this.renderRevConnect.bind(this,null)},dash:{attrs:{fill:"none",stroke:"#000000","stroke-width":1,"stroke-dasharray":"4, 2"},renderFlat:this.renderFlatConnect.bind(this,null),renderRev:this.renderRevConnect.bind(this,null)},wave:{attrs:{fill:"none",stroke:"#000000","stroke-width":1,"stroke-linejoin":"round","stroke-linecap":"round"},renderFlat:this.renderFlatConnect.bind(this,it),renderRev:this.renderRevConnect.bind(this,it)}},arrow:{single:{width:5,height:10,render:this.renderArrowHead.bind(this),attrs:{fill:"#000000","stroke-width":0,"stroke-linejoin":"miter"}},double:{width:4,height:6,render:this.renderArrowHead.bind(this),attrs:{fill:"none",stroke:"#000000","stroke-width":1,"stroke-linejoin":"miter"}},cross:{short:7,radius:3,render:t.crossFactory({fill:"none",stroke:"#000000","stroke-width":1})}},label:{padding:6,margin:{top:2,bottom:1},attrs:{"font-family":rt,"font-size":8,"line-height":1.3,"text-anchor":"middle"},loopbackAttrs:{"font-family":rt,"font-size":8,"line-height":1.3}},source:{radius:2,render:t.circleFactory({fill:"#000000",stroke:"#000000","stroke-width":1})},mask:{padding:{top:0,left:3,right:3,bottom:1}}},titleAttrs:{"font-family":rt,"font-size":20,"line-height":1.3,"text-anchor":"middle",class:"title"},agentLineAttrs:{"":{fill:"none",stroke:"#000000","stroke-width":1},red:{stroke:"#CC0000"}},blocks:{ref:{margin:{top:0,bottom:0},boxRenderer:this.renderRef.bind(this,{fill:"#FFFFFF",stroke:"#000000","stroke-width":1.5,rx:2,ry:2}),section:e},"":{margin:{top:0,bottom:0},boxRenderer:t.boxFactory({fill:"none",stroke:"#000000","stroke-width":1.5,rx:2,ry:2}),collapsedBoxRenderer:this.renderRef.bind(this,{fill:"#FFFFFF",stroke:"#000000","stroke-width":1.5,rx:2,ry:2}),section:e,sepRenderer:t.lineFactory({stroke:"#000000","stroke-width":1.5,"stroke-dasharray":"4, 2"})}},notes:{text:{margin:{top:0,left:2,right:2,bottom:0},padding:{top:2,left:2,right:2,bottom:2},overlap:{left:10,right:10},boxRenderer:t.boxFactory({fill:"#FFFFFF"}),labelAttrs:at},note:{margin:{top:0,left:5,right:5,bottom:0},padding:{top:5,left:5,right:10,bottom:5},overlap:{left:10,right:10},boxRenderer:t.noteFactory({fill:"#FFFFFF",stroke:"#000000","stroke-width":1},{fill:"none",stroke:"#000000","stroke-width":1}),labelAttrs:at},state:{margin:{top:0,left:5,right:5,bottom:0},padding:{top:7,left:7,right:7,bottom:7},overlap:{left:10,right:10},boxRenderer:t.boxFactory({fill:"#FFFFFF",stroke:"#000000","stroke-width":1,rx:10,ry:10}),labelAttrs:at}},dividers:{"":{labelAttrs:ot,padding:{top:2,left:5,right:5,bottom:2},extend:0,margin:0,render:()=>({})},line:{labelAttrs:ot,padding:{top:2,left:5,right:5,bottom:2},extend:10,margin:0,render:this.renderLineDivider.bind(this,{lineAttrs:{stroke:"#000000"}})},delay:{labelAttrs:ot,padding:{top:2,left:5,right:5,bottom:2},extend:0,margin:0,render:this.renderDelayDivider.bind(this,{dotSize:1,gapSize:2})},tear:{labelAttrs:ot,padding:{top:2,left:5,right:5,bottom:2},extend:10,margin:10,render:this.renderTearDivider.bind(this,{fadeBegin:5,fadeSize:10,zigWidth:6,zigHeight:1,lineAttrs:{stroke:"#000000"}})}}})}}class lt{constructor(){this.name="basic"}build(t){return new ht(t)}}const dt="sans-serif",gt=new nt(10,1),ct={"font-family":dt,"font-size":8,"line-height":1.3},ut={"font-family":dt,"font-size":8,"line-height":1.3,"text-anchor":"middle"};class pt extends st{constructor(t){super(t);const e={padding:{top:3,bottom:4},tag:{padding:{top:2,left:5,right:5,bottom:1},boxRenderer:this.renderTag.bind(this,{fill:"#FFFFFF",stroke:"#000000","stroke-width":2,rx:3,ry:3}),labelAttrs:{"font-family":dt,"font-weight":"bold","font-size":9,"line-height":1.3,"text-anchor":"left"}},label:{minHeight:5,padding:{top:2,left:5,right:3,bottom:1},labelAttrs:{"font-family":dt,"font-size":8,"line-height":1.3,"text-anchor":"left"}}};Object.assign(this,{titleMargin:12,outerMargin:5,agentMargin:8,actionMargin:5,minActionMargin:5,agentLineHighlightRadius:4,agentCap:{box:{padding:{top:1,left:3,right:3,bottom:1},arrowBottom:11.1,boxAttrs:{fill:"#FFFFFF",stroke:"#000000","stroke-width":3,rx:4,ry:4},labelAttrs:{"font-family":dt,"font-weight":"bold","font-size":14,"line-height":1.3,"text-anchor":"middle"}},database:{padding:{top:4,left:3,right:3,bottom:0},arrowBottom:11.1,boxRenderer:this.renderDB.bind(this,{fill:"#FFFFFF",stroke:"#000000","stroke-width":3,"db-z":2}),labelAttrs:{"font-family":dt,"font-weight":"bold","font-size":14,"line-height":1.3,"text-anchor":"middle"}},cross:{size:20,render:t.crossFactory({fill:"none",stroke:"#000000","stroke-width":3,"stroke-linecap":"round"})},bar:{height:4,render:t.boxFactory({fill:"#000000",stroke:"#000000","stroke-width":3,rx:2,ry:2})},fade:{width:5,height:10,extend:1},none:{height:10}},connect:{loopbackRadius:8,line:{solid:{attrs:{fill:"none",stroke:"#000000","stroke-width":3},renderFlat:this.renderFlatConnect.bind(this,null),renderRev:this.renderRevConnect.bind(this,null)},dash:{attrs:{fill:"none",stroke:"#000000","stroke-width":3,"stroke-dasharray":"10, 4"},renderFlat:this.renderFlatConnect.bind(this,null),renderRev:this.renderRevConnect.bind(this,null)},wave:{attrs:{fill:"none",stroke:"#000000","stroke-width":3,"stroke-linejoin":"round","stroke-linecap":"round"},renderFlat:this.renderFlatConnect.bind(this,gt),renderRev:this.renderRevConnect.bind(this,gt)}},arrow:{single:{width:10,height:12,render:this.renderArrowHead.bind(this),attrs:{fill:"#000000",stroke:"#000000","stroke-width":3,"stroke-linejoin":"round"}},double:{width:10,height:12,render:this.renderArrowHead.bind(this),attrs:{fill:"none",stroke:"#000000","stroke-width":3,"stroke-linejoin":"round","stroke-linecap":"round"}},cross:{short:10,radius:5,render:t.crossFactory({fill:"none",stroke:"#000000","stroke-width":3,"stroke-linejoin":"round","stroke-linecap":"round"})}},label:{padding:7,margin:{top:2,bottom:3},attrs:{"font-family":dt,"font-size":8,"line-height":1.3,"text-anchor":"middle"},loopbackAttrs:{"font-family":dt,"font-size":8,"line-height":1.3}},source:{radius:5,render:t.circleFactory({fill:"#000000",stroke:"#000000","stroke-width":3})},mask:{padding:{top:1,left:5,right:5,bottom:3}}},titleAttrs:{"font-family":dt,"font-weight":"bolder","font-size":20,"line-height":1.3,"text-anchor":"middle",class:"title"},agentLineAttrs:{"":{fill:"none",stroke:"#000000","stroke-width":3},red:{stroke:"#DD0000"}},blocks:{ref:{margin:{top:0,bottom:0},boxRenderer:this.renderRef.bind(this,{fill:"#FFFFFF",stroke:"#000000","stroke-width":4,rx:5,ry:5}),section:e},"":{margin:{top:0,bottom:0},boxRenderer:t.boxFactory({fill:"none",stroke:"#000000","stroke-width":4,rx:5,ry:5}),collapsedBoxRenderer:this.renderRef.bind(this,{fill:"#FFFFFF",stroke:"#000000","stroke-width":4,rx:5,ry:5}),section:e,sepRenderer:t.lineFactory({stroke:"#000000","stroke-width":2,"stroke-dasharray":"5, 3"})}},notes:{text:{margin:{top:0,left:2,right:2,bottom:0},padding:{top:2,left:2,right:2,bottom:2},overlap:{left:10,right:10},boxRenderer:t.boxFactory({fill:"#FFFFFF"}),labelAttrs:ct},note:{margin:{top:0,left:5,right:5,bottom:0},padding:{top:3,left:3,right:10,bottom:3},overlap:{left:10,right:10},boxRenderer:t.noteFactory({fill:"#FFFFFF",stroke:"#000000","stroke-width":2,"stroke-linejoin":"round"},{fill:"none",stroke:"#000000","stroke-width":1}),labelAttrs:ct},state:{margin:{top:0,left:5,right:5,bottom:0},padding:{top:5,left:7,right:7,bottom:5},overlap:{left:10,right:10},boxRenderer:t.boxFactory({fill:"#FFFFFF",stroke:"#000000","stroke-width":3,rx:10,ry:10}),labelAttrs:ct}},dividers:{"":{labelAttrs:ut,padding:{top:2,left:5,right:5,bottom:2},extend:0,margin:0,render:()=>({})},line:{labelAttrs:ut,padding:{top:2,left:5,right:5,bottom:2},extend:10,margin:0,render:this.renderLineDivider.bind(this,{lineAttrs:{stroke:"#000000","stroke-width":2,"stroke-linecap":"round"}})},delay:{labelAttrs:ut,padding:{top:2,left:5,right:5,bottom:2},extend:0,margin:0,render:this.renderDelayDivider.bind(this,{dotSize:3,gapSize:3})},tear:{labelAttrs:ut,padding:{top:2,left:5,right:5,bottom:2},extend:10,margin:10,render:this.renderTearDivider.bind(this,{fadeBegin:5,fadeSize:10,zigWidth:6,zigHeight:1,lineAttrs:{stroke:"#000000","stroke-width":2,"stroke-linejoin":"round"}})}}})}}class ft{constructor(){this.name="chunky"}build(t){return new pt(t)}}class mt{constructor(){this.listeners=new Map,this.forwards=new Set}addEventListener(t,e){const n=this.listeners.get(t);n?n.push(e):this.listeners.set(t,[e])}removeEventListener(t,e){const n=this.listeners.get(t);if(!n)return;const s=n.indexOf(e);-1!==s&&n.splice(s,1)}on(t,e){return this.addEventListener(t,e),this}off(t,e){return this.removeEventListener(t,e),this}countEventListeners(t){return(this.listeners.get(t)||[]).length}removeAllEventListeners(t){t?this.listeners.delete(t):this.listeners.clear()}addEventForwarding(t){this.forwards.add(t)}removeEventForwarding(t){this.forwards.delete(t)}removeAllEventForwardings(){this.forwards.clear()}trigger(t,e=[]){(this.listeners.get(t)||[]).forEach(t=>t(...e)),this.forwards.forEach(n=>n.trigger(t,e))}}const bt="undefined"==typeof window,yt=!bt&&/^((?!chrome|android).)*safari/i.test(window.navigator.userAgent),xt=!bt&&void 0!==window.InstallTrigger;class kt{constructor(){this.latestSVG=null,this.latestInternalSVG=null,this.canvas=null,this.context=null,this.indexPNG=0,this.latestPNGIndex=0,this.latestPNG=null}getSVGContent(t){let e=t.dom().outerHTML;return e=e.replace(/^{this.canvas.width=s,this.canvas.height=r,this.context.drawImage(i,0,0,s,r),a&&document.body.removeChild(a),n(this.canvas)};i.addEventListener("load",()=>{a?setTimeout(o,50):o()},{once:!0}),i.src=this.getSVGURL(t)}getPNGBlob(t,e,n){this.getCanvas(t,e,t=>{t.toBlob(n,"image/png")})}getPNGURL(t,e,n){++this.indexPNG;const s=this.indexPNG;this.getPNGBlob(t,e,t=>{const e=URL.createObjectURL(t);s>=this.latestPNGIndex?(this.latestPNG&&URL.revokeObjectURL(this.latestPNG),this.latestPNG=e,this.latestPNGIndex=s,n(e,!0)):(n(e,!1),URL.revokeObjectURL(e))})}}class wt{constructor({visible:t=!1,locked:e=!1,blocked:n=!1,highlighted:s=!1,group:r=null,covered:i=!1}={}){this.visible=t,this.locked=e,this.blocked=n,this.highlighted=s,this.group=r,this.covered=i}}wt.LOCKED=new wt({locked:!0}),wt.DEFAULT=new wt;const vt={equals:(t,e)=>t.name===e.name,hasFlag:(t,e=!0)=>n=>n.flags.includes(t)===e},At={equals:(t,e)=>t.id===e.id,make:(t,{anchorRight:e=!1,isVirtualSource:n=!1}={})=>({anchorRight:e,id:t,isVirtualSource:n,options:[]}),indexOf:(e,n)=>t(e,n,At.equals),hasIntersection:(e,n)=>(function(e,n,s=null){for(let r=0;r{const i=t(e,n,At.equals);-1===i?e.push(s):e.splice(i+r,0,s)}},Ft={"note over":[At.make("["),At.make("]")],"note left":[At.make("[")],"note right":[At.make("]")]},Mt=["[","]"],St={"agent begin":{check:["mode"],merge:["agentIDs"],siblings:new Set(["agent highlight"])},"agent end":{check:["mode"],merge:["agentIDs"],siblings:new Set(["agent highlight"])},"agent highlight":{check:["highlighted"],merge:["agentIDs"],siblings:new Set(["agent begin","agent end"])}};class Rt{constructor(){this.agentStates=new Map,this.agentAliases=new Map,this.activeGroups=new Map,this.gAgents=[],this.labelPattern=null,this.nextID=0,this.nesting=[],this.markers=new Set,this.currentSection=null,this.currentNest=null,this.stageHandlers={"block begin":this.handleBlockBegin.bind(this),"block split":this.handleBlockSplit.bind(this),"block end":this.handleBlockEnd.bind(this),"group begin":this.handleGroupBegin.bind(this),mark:this.handleMark.bind(this),async:this.handleAsync.bind(this),"agent define":this.handleAgentDefine.bind(this),"agent options":this.handleAgentOptions.bind(this),"agent begin":this.handleAgentBegin.bind(this),"agent end":this.handleAgentEnd.bind(this),divider:this.handleDivider.bind(this),"label pattern":this.handleLabelPattern.bind(this),connect:this.handleConnect.bind(this),"connect-delay-begin":this.handleConnectDelayBegin.bind(this),"connect-delay-end":this.handleConnectDelayEnd.bind(this),"note over":this.handleNote.bind(this),"note left":this.handleNote.bind(this),"note right":this.handleNote.bind(this),"note between":this.handleNote.bind(this)},this.expandGroupedGAgent=this.expandGroupedGAgent.bind(this),this.handleStage=this.handleStage.bind(this),this.toGAgent=this.toGAgent.bind(this),this.endGroup=this.endGroup.bind(this)}toGAgent({name:t,alias:e,flags:n}){if(e){if(this.agentAliases.has(t))throw new Error("Cannot alias "+t+"; it is already an alias");const n=this.agentAliases.get(e);if(n&&n!==e||this.gAgents.some(t=>t.id===e))throw new Error("Cannot use "+e+" as an alias; it is already in use");this.agentAliases.set(e,t)}return At.make(this.agentAliases.get(t)||t,{isVirtualSource:n.includes("source")})}addStage(t,e=!0){t&&(void 0===t.ln&&(t.ln=this.latestLine),this.currentSection.stages.push(t),e&&(this.currentNest.hasContent=!0))}addParallelStages(t){const e=t.filter(t=>Boolean(t));0!==e.length&&(1!==e.length?(e.forEach(t=>{void 0===t.ln&&(t.ln=this.latestLine)}),this.addStage({type:"parallel",stages:e})):this.addStage(e[0]))}defineGAgents(t){e(this.currentNest.gAgents,t.filter(t=>!Mt.includes(t.id)),At.equals),e(this.gAgents,t,At.equals)}getGAgentState(t){return this.agentStates.get(t.id)||wt.DEFAULT}updateGAgentState(t,e){const n=this.agentStates.get(t.id);n?Object.assign(n,e):this.agentStates.set(t.id,new wt(e))}replaceGAgentState(t,e){this.agentStates.set(t.id,e)}validateGAgents(t,{allowGrouped:e=!1,allowCovered:n=!1,allowVirtual:s=!1}={}){t.forEach(t=>{const r=this.getGAgentState(t);if(r.blocked&&null===r.group)throw new Error("Duplicate agent name: "+t.id);if(!n&&r.covered)throw new Error("Agent "+t.id+" is hidden behind group");if(!e&&null!==r.group)throw new Error("Agent "+t.id+" is in a group");if(!s&&t.isVirtualSource)throw new Error("cannot use message source here");if(t.id.startsWith("__"))throw new Error(t.id+" is a reserved name")})}setGAgentVis(t,e,n,s=!1){const r=new Set,i=t.filter(t=>{if(r.has(t.id))return!1;r.add(t.id);const n=this.getGAgentState(t);if(n.locked||n.blocked){if(s)throw new Error("Cannot begin/end agent: "+t.id);return!1}return n.visible!==e});return 0===i.length?null:(i.forEach(t=>{this.updateGAgentState(t,{visible:e})}),this.defineGAgents(i),{type:e?"agent begin":"agent end",agentIDs:i.map(t=>t.id),mode:n})}setGAgentHighlight(t,e,n=!1){const s=t.filter(t=>{const s=this.getGAgentState(t);if(s.locked||s.blocked){if(n)throw new Error("Cannot highlight agent: "+t.id);return!1}return s.visible&&s.highlighted!==e});return 0===s.length?null:(s.forEach(t=>{this.updateGAgentState(t,{highlighted:e})}),{type:"agent highlight",agentIDs:s.map(t=>t.id),highlighted:e})}_makeSection(t,e){return{header:t,delayedConnections:new Map,stages:e}}_checkSectionEnd(){const t=this.currentSection.delayedConnections;if(t.size>0){const e=t.values().next().value;throw new Error('Unused delayed connection "'+e.tag+'" at line '+(e.ln+1))}}beginNested(t,{tag:e,label:n,name:s,ln:r}){const i=At.make(s+"[",{anchorRight:!0}),a=At.make(s+"]"),o=[i,a],h=[];return this.currentSection=this._makeSection({type:"block begin",blockType:t,tag:this.textFormatter(e),label:this.textFormatter(n),canHide:!0,left:i.id,right:a.id,ln:r},h),this.currentNest={blockType:t,gAgents:o,leftGAgent:i,rightGAgent:a,hasContent:!1,sections:[this.currentSection]},this.replaceGAgentState(i,wt.LOCKED),this.replaceGAgentState(a,wt.LOCKED),this.nesting.push(this.currentNest),{stages:h}}nextBlockName(){const t="__BLOCK"+this.nextID;return++this.nextID,t}nextVirtualAgentName(){const t="__"+this.nextID;return++this.nextID,t}handleBlockBegin({ln:t,blockType:e,tag:n,label:s}){this.beginNested(e,{tag:n,label:s,name:this.nextBlockName(),ln:t})}handleBlockSplit({ln:t,blockType:e,tag:n,label:s}){if("if"!==this.currentNest.blockType)throw new Error('Invalid block nesting ("else" inside '+this.currentNest.blockType+")");this._checkSectionEnd(),this.currentSection=this._makeSection({type:"block split",blockType:e,tag:this.textFormatter(n),label:this.textFormatter(s),left:this.currentNest.leftGAgent.id,right:this.currentNest.rightGAgent.id,ln:t},[]),this.currentNest.sections.push(this.currentSection)}handleBlockEnd(){if(this.nesting.length<=1)throw new Error('Invalid block nesting (too many "end"s)');this._checkSectionEnd();const t=this.nesting.pop();if(this.currentNest=r(this.nesting),this.currentSection=r(this.currentNest.sections),!t.hasContent)throw new Error("Empty block");this.defineGAgents(t.gAgents),p(this.gAgents,t.leftGAgent,t.rightGAgent,t.gAgents),t.sections.forEach(t=>{this.currentSection.stages.push(t.header),this.currentSection.stages.push(...t.stages)}),this.addStage({type:"block end",left:t.leftGAgent.id,right:t.rightGAgent.id})}makeGroupDetails(t,e){const s=t.map(this.toGAgent);if(this.validateGAgents(s),this.agentStates.has(e))throw new Error("Duplicate agent name: "+e);const r=this.nextBlockName(),i=At.make(r+"[",{anchorRight:!0}),a=At.make(r+"]");this.replaceGAgentState(i,wt.LOCKED),this.replaceGAgentState(a,wt.LOCKED),this.updateGAgentState(At.make(e),{blocked:!0,group:e}),this.defineGAgents([...s,i,a]);const{indexL:o,indexR:h}=p(this.gAgents,i,a,s),l=[],d=s.slice();for(let t=o+1;t{this.updateGAgentState(t,{group:r})}),i.gAgentsCovered.forEach(t=>{this.updateGAgentState(t,{covered:!0})}),this.activeGroups.set(r,i),this.addStage(this.setGAgentVis(i.gAgents,!0,"box")),this.addStage({type:"block begin",blockType:e,tag:this.textFormatter(n),canHide:!1,label:this.textFormatter(s),left:i.leftGAgent.id,right:i.rightGAgent.id})}endGroup({name:t}){const e=this.activeGroups.get(t);return e?(this.activeGroups.delete(t),e.gAgentsContained.forEach(t=>{this.updateGAgentState(t,{group:null})}),e.gAgentsCovered.forEach(t=>{this.updateGAgentState(t,{covered:!1})}),this.updateGAgentState(At.make(t),{group:null}),{type:"block end",left:e.leftGAgent.id,right:e.rightGAgent.id}):null}handleMark({name:t}){this.markers.add(t),this.addStage({type:"mark",name:t},!1)}handleDivider({mode:t,height:e,label:n}){this.addStage({type:"divider",mode:t,height:e,formattedLabel:this.textFormatter(n)},!1)}handleAsync({target:t}){if(""!==t&&!this.markers.has(t))throw new Error("Unknown marker: "+t);this.addStage({type:"async",target:t},!1)}handleLabelPattern({pattern:t}){this.labelPattern=t.slice();for(let t=0;t{"string"==typeof t?e+=t:void 0!==t.token?e+=n[t.token]:void 0!==t.current&&(e+=t.current.toFixed(t.dp),t.current+=t.inc)}),e}expandGroupedGAgent(t){const{group:e}=this.getGAgentState(t);if(!e)return[t];const n=this.activeGroups.get(e);return[n.leftGAgent,n.rightGAgent]}expandGroupedGAgentConnection(t){const e=this.expandGroupedGAgent(t[0]),n=this.expandGroupedGAgent(t[1]);let s=At.indexOf(this.gAgents,e[0]),i=At.indexOf(this.gAgents,n[0]);return-1===s&&(s=e[0].isVirtualSource?-1:this.gAgents.length),-1===i&&(i=this.gAgents.length),s===i?[r(e),r(n)]:s!t.isVirtualSource));const s=t.filter(vt.hasFlag("begin",!1)).map(this.toGAgent).filter(t=>!t.isVirtualSource);return this.addStage(this.setGAgentVis(s,!0,"box")),{flags:e,gAgents:n}}_makeConnectParallelStages(t,e){return[this.setGAgentVis(t.beginGAgents,!0,"box",!0),this.setGAgentHighlight(t.startGAgents,!0,!0),e,this.setGAgentHighlight(t.stopGAgents,!1,!0),this.setGAgentVis(t.endGAgents,!1,"cross",!0)]}_isSelfConnect(t){const e=t.map(this.toGAgent),n=this.expandGroupedGAgentConnection(e);return n[0].id===n[1].id&&!n.some(t=>t.isVirtualSource)}handleConnect({agents:t,label:e,options:n}){if(this._isSelfConnect(t)){const s={};return this.handleConnectDelayBegin({agent:t[0],tag:s,options:n,ln:0}),void this.handleConnectDelayEnd({agent:t[1],tag:s,label:e,options:n})}let{flags:s,gAgents:r}=this._handlePartialConnect(t);r=this.expandGroupedGAgentConnection(r);const i={type:"connect",agentIDs:(r=this.expandVirtualSourceAgents(r)).map(t=>t.id),label:this.textFormatter(this.applyLabelPattern(e)),options:n};this.addParallelStages(this._makeConnectParallelStages(s,i))}handleConnectDelayBegin({agent:t,tag:e,options:n,ln:s}){const r=this.currentSection.delayedConnections;if(r.has(e))throw new Error('Duplicate delayed connection "'+e+'"');const{flags:i,gAgents:a}=this._handlePartialConnect([t]),o=this.nextVirtualAgentName(),h={type:"connect-delay-begin",tag:o,agentIDs:null,label:null,options:n};r.set(e,{tag:e,uniqueTag:o,ln:s,gAgents:a,connectStage:h}),this.addParallelStages(this._makeConnectParallelStages(i,h))}handleConnectDelayEnd({agent:t,tag:e,label:n,options:s}){const r=this.currentSection.delayedConnections,i=r.get(e);if(!i)throw new Error('Unknown delayed connection "'+e+'"');let{flags:a,gAgents:o}=this._handlePartialConnect([t]);o=this.expandGroupedGAgentConnection([...i.gAgents,...o]),o=this.expandVirtualSourceAgents(o);let h=i.connectStage.options;if(h.line!==s.line)throw new Error("Mismatched delayed connection arrows");s.right&&(h=Object.assign({},h,{right:s.right})),Object.assign(i.connectStage,{agentIDs:o.map(t=>t.id),label:this.textFormatter(this.applyLabelPattern(n)),options:h});const l={type:"connect-delay-end",tag:i.uniqueTag};this.addParallelStages(this._makeConnectParallelStages(a,l)),r.delete(e)}handleNote({type:t,agents:e,mode:n,label:s}){let r=null;r=0===e.length?Ft[t]||[]:e.map(this.toGAgent),this.validateGAgents(r,{allowGrouped:!0});const i=(r=a(r,this.expandGroupedGAgent)).map(t=>t.id),o=new Set(i).size;if("note between"===t&&o<2)throw new Error("note between requires at least 2 agents");this.addStage(this.setGAgentVis(r,!0,"box")),this.defineGAgents(r),this.addStage({type:t,agentIDs:i,mode:n,label:this.textFormatter(s)})}handleAgentDefine({agents:t}){const n=t.map(this.toGAgent);this.validateGAgents(n,{allowGrouped:!0,allowCovered:!0}),e(this.gAgents,n,At.equals)}handleAgentOptions({agent:t,options:n}){const s=this.toGAgent(t),r=[s];this.validateGAgents(r,{allowGrouped:!0,allowCovered:!0}),e(this.gAgents,r,At.equals),this.gAgents.filter(({id:t})=>t===s.id).forEach(t=>{e(t.options,n)})}handleAgentBegin({agents:t,mode:e}){const n=t.map(this.toGAgent);this.validateGAgents(n),this.addStage(this.setGAgentVis(n,!0,e,!0))}handleAgentEnd({agents:t,mode:e}){const n=t.filter(t=>this.activeGroups.has(t.name)),s=t.filter(t=>!this.activeGroups.has(t.name)).map(this.toGAgent);this.validateGAgents(s),this.addParallelStages([this.setGAgentHighlight(s,!1),this.setGAgentVis(s,!1,e,!0),...n.map(this.endGroup)])}handleStage(t){this.latestLine=t.ln;try{const e=this.stageHandlers[t.type];if(!e)throw new Error("Unknown command: "+t.type);e(t)}catch(e){if("object"==typeof e&&e.message)throw e.message+=" at line "+(t.ln+1),e}}_reset(){this.agentStates.clear(),this.markers.clear(),this.agentAliases.clear(),this.activeGroups.clear(),this.gAgents.length=0,this.nextID=0,this.nesting.length=0,this.labelPattern=[{token:"label"}]}_finalise(t){p(this.gAgents,this.currentNest.leftGAgent,this.currentNest.rightGAgent),function(t){let e=[],n=new Set;for(let s=0;s{t.formattedLabel=this.textFormatter(t.id)})}generate({stages:t,meta:e={}}){this._reset(),this.textFormatter=e.textFormatter;const n=this.beginNested("global",{tag:"",label:"",name:"",ln:0});if(t.forEach(this.handleStage),1!==this.nesting.length)throw new Error("Unterminated section at line "+(this.currentSection.header.ln+1));if(this.activeGroups.size>0)throw new Error("Unterminated group");this._checkSectionEnd();const s=e.terminators||"none";return this.addParallelStages([this.setGAgentHighlight(this.gAgents,!1),this.setGAgentVis(this.gAgents,!1,s)]),this._finalise(n),function(t,e){for(let n=0;n({})},line:{labelAttrs:It,padding:{top:2,left:5,right:5,bottom:2},extend:8,margin:0,render:this.renderLineDivider.bind(this,{lineAttrs:{stroke:"#000000"}})},delay:{labelAttrs:It,padding:{top:2,left:5,right:5,bottom:2},extend:0,margin:0,render:this.renderDelayDivider.bind(this,{dotSize:2,gapSize:2})},tear:{labelAttrs:It,padding:{top:2,left:5,right:5,bottom:2},extend:8,margin:8,render:this.renderTearDivider.bind(this,{fadeBegin:4,fadeSize:4,zigWidth:4,zigHeight:1,lineAttrs:{stroke:"#000000"}})}}})}}class Lt{constructor(){this.name="monospace"}build(t){return new Dt(t)}}const Nt={type:"error line-error",suggest:!1,then:{"":0}},zt=["database","red"],Ot=(()=>{function t(t,e=1){return{type:"variable",suggest:{known:"Agent"},then:Object.assign({},t,{"":0,",":{type:"operator",then:{"":e}}})}}function e(t){return{type:"keyword",suggest:[t+" of ",t+": "],then:{of:{type:"keyword",then:{"":h}},":":{type:"operator",then:{"":i}},"":h}}}function n({exit:t,sourceExit:e,blankExit:n}){const s={type:"operator",then:{"+":Nt,"-":Nt,"*":Nt,"!":Nt,"":t}};return{"+":{type:"operator",then:{"+":Nt,"-":Nt,"*":s,"!":Nt,"":t}},"-":{type:"operator",then:{"+":Nt,"-":Nt,"*":s,"!":{type:"operator",then:{"+":Nt,"-":Nt,"*":Nt,"!":Nt,"":t}},"":t}},"*":{type:"operator",then:Object.assign({"+":s,"-":s,"*":Nt,"!":Nt,"":t},e||t)},"!":s,"":n||t}}const s={type:"",suggest:"\n",then:{}},r={type:"",suggest:!1,then:{}},i=f({"\n":s}),a={type:"operator",then:{"":i,"\n":r}},o=t({"\n":s,as:{type:"keyword",then:{"":{type:"variable",suggest:{known:"Agent"},then:{"":0,",":{type:"operator",then:{"":3}},"\n":s}}}}}),h=t({":":a}),l={type:"variable",suggest:{known:"Agent"},then:{"":0,":":{type:"operator",then:{"":i,"\n":r}},"\n":s}},d={":":{type:"operator",then:{"":f({as:{type:"keyword",then:{"":{type:"variable",suggest:{known:"Agent"},then:{"":0,"\n":s}}}}})}}},g={type:"keyword",then:Object.assign({over:{type:"keyword",then:{"":t(d)}}},d)},c={"\n":s,":":{type:"operator",then:{"":i,"\n":r}},with:{type:"keyword",suggest:["with height "],then:{height:{type:"keyword",then:{"":{type:"number",suggest:["6 ","30 "],then:{"\n":s,":":{type:"operator",then:{"":i,"\n":r}}}}}}}}},u=function(t,e,n){const s=Object.assign({},n);return e.forEach(e=>{s[e]={type:t,then:n}}),s}("keyword",["a","an"],function(t,e,n){const s={},r=Object.assign({},n);return e.forEach(e=>{s[e]={type:t,then:r},r[e]=0}),s}("keyword",zt,{"\n":s})),p={type:"keyword",then:{"":i,":":{type:"operator",then:{"":i}},"\n":s}},m={title:{type:"keyword",then:{"":i}},theme:{type:"keyword",then:{"":{type:"string",suggest:{global:"themes",suffix:"\n"},then:{"":0,"\n":s}}}},headers:{type:"keyword",then:{none:{type:"keyword",then:{}},cross:{type:"keyword",then:{}},box:{type:"keyword",then:{}},fade:{type:"keyword",then:{}},bar:{type:"keyword",then:{}}}},terminators:{type:"keyword",then:{none:{type:"keyword",then:{}},cross:{type:"keyword",then:{}},box:{type:"keyword",then:{}},fade:{type:"keyword",then:{}},bar:{type:"keyword",then:{}}}},divider:{type:"keyword",then:Object.assign({line:{type:"keyword",then:c},space:{type:"keyword",then:c},delay:{type:"keyword",then:c},tear:{type:"keyword",then:c}},c)},define:{type:"keyword",then:{"":o,as:Nt}},begin:{type:"keyword",then:{"":o,reference:g,as:Nt}},end:{type:"keyword",then:{"":o,as:Nt,"\n":s}},if:p,else:{type:"keyword",suggest:["else\n","else if: "],then:{if:{type:"keyword",suggest:"if: ",then:{"":i,":":{type:"operator",then:{"":i}}}},"\n":s}},repeat:p,group:p,note:{type:"keyword",then:{over:{type:"keyword",then:{"":h}},left:e("left"),right:e("right"),between:{type:"keyword",then:{"":t({":":Nt},h)}}}},state:{type:"keyword",suggest:"state over ",then:{over:{type:"keyword",then:{"":{type:"variable",suggest:{known:"Agent"},then:{"":0,",":Nt,":":a}}}}}},text:{type:"keyword",then:{left:e("left"),right:e("right")}},autolabel:{type:"keyword",then:{off:{type:"keyword",then:{}},"":f({"\n":s},[{v:"",suffix:"\n",q:!0},{v:"[] ",suffix:"\n",q:!0},{v:"[] ",suffix:"\n",q:!0}])}},simultaneously:{type:"keyword",then:{":":{type:"operator",then:{}},with:{type:"keyword",then:{"":{type:"variable",suggest:{known:"Label"},then:{"":0,":":{type:"operator",then:{}}}}}}}}};return t=>({type:"error line-error",then:Object.assign({},m,function(t){const e={type:"keyword",then:Object.assign({},n({exit:l,sourceExit:{":":a,"\n":r}}),{"...":{type:"operator",then:{"":{type:"variable",suggest:{known:"DelayedAgent"},then:{"":0,":":Nt,"\n":s}}}}})},i={};t.forEach(t=>i[t]=e);const o={type:"operator",suggest:!1,override:"Label",then:{}},h={type:"variable",suggest:{known:"Agent"},then:Object.assign({"":0},i,{":":{type:"operator",override:"Label",then:{}}})},d={type:"variable",suggest:{known:"DelayedAgent"},then:Object.assign({"":0,":":o},i)},g=Object.assign({},h,{then:Object.assign({},h.then,{is:{type:"keyword",then:u}})});return Object.assign({"...":{type:"operator",then:{"":d}}},n({exit:h,sourceExit:Object.assign({"":h,":":o},i),blankExit:g}))}(t))})})();class Bt{constructor(t,e){this.tokenDefinitions=t,this.commands=Ot(e),this.lineComment="#"}startState(){return{currentType:-1,current:"",currentSpace:"",currentQuoted:!1,knownAgent:[],knownDelayedAgent:[],knownLabel:[],beginCompletions:y({},[this.commands]),completions:[],nextCompletions:[],valid:!0,isVar:!0,line:[],indent:0}}_matchPattern(t,e,n){return e?(e.lastIndex=0,t.match(e,n)):null}_tokenBegin(t,e){e.currentSpace="";for(let n="";!t.eol();n=t.next()){e.currentSpace+=n;for(let n=0;n,])|$/y,start:/(?=[^ \t\r\n:+~\-*!<>,])/y},{end:/(?=[^~\-<>x])|[-~]x|[<>](?=x)|$/y,includeEnd:!0,start:/(?=[~\-<])/y},{baseToken:{v:","},start:/,/y},{baseToken:{v:":"},start:/:/y},{baseToken:{v:"!"},start:/!/y},{baseToken:{v:"+"},start:/\+/y},{baseToken:{v:"*"},start:/\*/y},{baseToken:{v:"\n"},start:/\n/y}];class Ht{constructor(t){this.src=t,this.block=null,this.token=null,this.pos={ch:0,i:0,ln:0},this.reset()}isOver(){return this.pos.i>this.src.length}reset(){this.token={b:null,e:null,q:!1,s:"",v:""},this.block=null}beginToken(t){this.block=t.newBlock,Object.assign(this.token,this.block.baseToken),this.token.b=F(this.pos)}endToken(){let t=null;return this.block.omit||(this.token.e=F(this.pos),t=this.token),this.reset(),t}advance(){const t=A(this.src,this.pos.i,this.block);return t.newBlock&&this.beginToken(t),this.token.s+=t.appendSpace,this.token.v+=t.appendValue,function(t,e,n){for(let s=0;s{t.q||"\n"!==t.v?n.push(t):n.length>0&&(e.push(n),n=[])}),n.length>0&&e.push(n),e}}const Pt=/(.*?)<([^<>]*)>/g,jt=/\.([0-9]*)/,qt=[{attrs:{"font-style":"italic"},begin:/[\s_~`]\*(?=\S)/g,end:/\S\*(?=[\s_~`])/g},{attrs:{"font-style":"italic"},begin:/[\s*~`]_(?=\S)/g,end:/\S_(?=[\s*~`])/g},{attrs:{"font-weight":"bolder"},begin:/[\s_~`]\*\*(?=\S)/g,end:/\S\*\*(?=[\s_~`])/g},{attrs:{"font-weight":"bolder"},begin:/[\s*~`]__(?=\S)/g,end:/\S__(?=[\s*~`])/g},{attrs:{"text-decoration":"line-through"},begin:/[\s_*`]~(?=\S)/g,end:/\S~(?=[\s_*`])/g},{attrs:{"font-family":"monospace"},begin:/[\s_*~.]`(?=\S)/g,end:/\S`(?=[\s_*~.])/g}],Yt={if:{type:"block begin",blockType:"if",tag:"if",skip:[]},else:{type:"block split",blockType:"else",tag:"else",skip:["if"]},repeat:{type:"block begin",blockType:"repeat",tag:"repeat",skip:[]},group:{type:"block begin",blockType:"group",tag:"",skip:[]}},Wt={types:(()=>{const t=function(t){const e=[];return i(t,0,[],e),e}([[{tok:"",type:0},{tok:"<",type:1},{tok:"<<",type:2}],[{tok:"-",type:"solid"},{tok:"--",type:"dash"},{tok:"~",type:"wave"}],[{tok:"",type:0},{tok:">",type:1},{tok:">>",type:2},{tok:"x",type:3}]]).filter(t=>0!==t[0].type||0!==t[2].type),e=new Map;return t.forEach(t=>{e.set(t.map(t=>t.tok).join(""),{line:t[1].type,left:t[0].type,right:t[2].type})}),e})(),agentFlags:{"*":{flag:"begin",allowBlankName:!0,blankNameFlag:"source"},"+":{flag:"start"},"-":{flag:"stop"},"!":{flag:"end"}}},Ut=["none","box","cross","fade","bar"],Xt={text:{mode:"text",types:{left:{type:"note left",skip:["of"],min:0,max:null},right:{type:"note right",skip:["of"],min:0,max:null}}},note:{mode:"note",types:{over:{type:"note over",skip:[],min:0,max:null},left:{type:"note left",skip:["of"],min:0,max:null},right:{type:"note right",skip:["of"],min:0,max:null},between:{type:"note between",skip:[],min:2,max:null}}},state:{mode:"state",types:{over:{type:"note over",skip:[],min:1,max:1}}}},Qt={line:{defaultHeight:6},space:{defaultHeight:6},delay:{defaultHeight:30},tear:{defaultHeight:6}},Jt={define:{type:"agent define"},begin:{type:"agent begin",mode:"box"},end:{type:"agent end",mode:"cross"}},Zt=[(t,e)=>"title"!==D(t[0])?null:(e.title=I(t,1),!0),(t,e)=>"theme"!==D(t[0])?null:(e.theme=I(t,1),!0),(t,e)=>{if("terminators"!==D(t[0]))return null;const n=D(t[1]);if(!n)throw G("Unspecified termination",t[0]);if(-1===Ut.indexOf(n))throw G('Unknown termination "'+n+'"',t[1]);return e.terminators=n,!0},(t,e)=>{if("headers"!==D(t[0]))return null;const n=D(t[1]);if(!n)throw G("Unspecified header",t[0]);if(-1===Ut.indexOf(n))throw G('Unknown header "'+n+'"',t[1]);return e.headers=n,!0},t=>{if("divider"!==D(t[0]))return null;const e=N(t,":",{orEnd:!0}),n=N(t,["with","height"],{limit:e,orEnd:!0}),s=I(t,1,n)||"line";if(!Qt[s])throw G("Unknown divider type",t[1]);const r=function(t,e=0,n=null,s=Number.NAN){const r=I(t,e,n);return Number(r||s)}(t,n+2,e,Qt[s].defaultHeight);if(Number.isNaN(r)||r<0)throw G("Invalid divider height",t[n+2]);return{type:"divider",mode:s,height:r,label:I(t,e+1)}},t=>{if("autolabel"!==D(t[0]))return null;let e=null;return e="off"===D(t[1])?"":I(t,1),{type:"label pattern",pattern:function(t){const e=[];let n=null,s=0;for(Pt.lastIndex=0;n=Pt.exec(t);)n[1]&&e.push(n[1]),n[2]&&e.push(S(n[2])),s=Pt.lastIndex;const r=t.substr(s);return r&&e.push(r),e}(e)}},t=>{if("end"===D(t[0])&&1===t.length)return{type:"block end"};const e=Yt[D(t[0])];if(!e)return null;let n=1;return t.length>n&&(n=L(t,n,e.skip,"Invalid block command")),n=L(t,n,[":"]),{type:e.type,blockType:e.blockType,tag:e.tag,label:I(t,n)}},t=>{if("begin"!==D(t[0])||"reference"!==D(t[1]))return null;let e=[];const n=N(t,":");if("over"===D(t[2])&&n>3)e=O(t,3,n);else if(2!==n)throw G('Expected ":" or "over"',t[2]);const s=z(t,n+1,t.length,{aliases:!0});if(!s.alias)throw G("Reference must have an alias",t[n]);return{type:"group begin",agents:e,blockType:"ref",tag:"ref",label:s.name,alias:s.alias}},t=>{const e=Jt[D(t[0])];return!e||t.length<=1?null:Object.assign({agents:O(t,1,t.length,{aliases:!0})},e)},t=>{if("simultaneously"!==D(t[0]))return null;if(":"!==D(r(t)))return null;let e="";if(t.length>2){if("with"!==D(t[1]))return null;e=I(t,2,t.length-1)}return{type:"async",target:e}},t=>{const e=Xt[D(t[0])],n=N(t,":");if(!e||-1===n)return null;const s=e.types[D(t[1])];if(!s)return null;let r=2;const i=O(t,r=L(t,r,s.skip),n);if(i.lengths.max)throw G("Too many agents for "+e.mode,t[0]);return{type:s.type,agents:i,mode:e.mode,label:I(t,n+1)}},t=>{const e=N(t,":",{orEnd:!0}),n=function(t,e,{start:n=0,limit:s=null}={}){null===s&&(s=t.length);for(let r=n;rt.length<2||":"!==D(r(t))?null:{type:"mark",name:I(t,0,t.length-1)},t=>{const e=N(t,"is");if(e<1)return null;let n=e+1;if(["a","an"].includes(D(t[n]))&&++n,n===t.length)throw G("Empty agent options",{b:r(t).e});const s=z(t,0,e),i=[];for(let e=n;e(function(t,{meta:e,stages:n}){let s=null;for(let n=0;nn.svg.linearGradient({x1:"0%",x2:"0%",y1:s?"100%":"0%",y2:s?"0%":"100%"},[{offset:"0%","stop-color":"#FFFFFF"},{offset:(100*i).toFixed(3)+"%","stop-color":"#000000"}]));return n.lineMaskLayer.add(n.svg.box({fill:"url(#"+a+")"},{height:r.height+r.extend,width:r.width,x:e-r.width/2,y:t-(s?r.extend:0)})),n.makeRegion().add(n.svg.box(ee,{height:r.height,width:r.width,x:e-r.width/2,y:t})),{height:r.height,lineBottom:0,lineTop:r.height}}}class ae{prepareMeasurements(){}separation({currentRad:t}){return{left:t,radius:t,right:t}}topShift(t,e){return e.theme.agentCap.none.height}render(t,{x:e},n){const s=n.theme.agentCap.none;return n.makeRegion().add(n.svg.box(ee,{height:s.height,width:10,x:e-5,y:t})),{height:s.height,lineBottom:0,lineTop:s.height}}}const oe={bar:new re,box:new ne,cross:new se,fade:new ie,none:new ae};class he extends $t{constructor(t){super(),this.begin=t}prepareMeasurements({mode:t,agentIDs:e},n){e.forEach(e=>{const s=n.agentInfos.get(e);oe[t].prepareMeasurements(s,n,this.begin)})}separationPre({mode:t,agentIDs:e},n){e.forEach(e=>{const s=n.agentInfos.get(e),r=oe[t].separation(s,n,this.begin);n.addSpacing(e,r),s.currentMaxRad=Math.max(s.currentMaxRad,r.radius)})}separation({agentIDs:t},s){this.begin?e(s.visibleAgentIDs,t):n(s.visibleAgentIDs,t)}renderPre({mode:t,agentIDs:e},n){let s=0;return e.forEach(e=>{const r=n.agentInfos.get(e),i=oe[t],a=i.topShift(r,n,this.begin);s=Math.max(s,a);const o=i.separation(r,n,this.begin).radius;r.currentMaxRad=Math.max(r.currentMaxRad,o)}),{agentIDs:e,topShift:s}}render({mode:t,agentIDs:e},n){let s=0;return e.forEach(e=>{const r=n.agentInfos.get(e),i=oe[t],a=i.topShift(r,n,this.begin),o=n.primaryY-a,h=i.render(o,r,n,this.begin);s=Math.max(s,o+h.height),this.begin?n.drawAgentLine(e,o+h.lineBottom):n.drawAgentLine(e,o+h.lineTop,!0)}),s+n.theme.actionMargin}renderHidden({agentIDs:t},e){t.forEach(t=>{e.drawAgentLine(t,e.topY,!this.begin)})}}V("agent begin",new he(!0)),V("agent end",new he(!1));class le extends $t{radius(t,e){return t?e.theme.agentLineHighlightRadius:0}separationPre({agentIDs:t,highlighted:e},n){const s=this.radius(e,n);t.forEach(t=>{const e=n.agentInfos.get(t);e.currentRad=s,e.currentMaxRad=Math.max(e.currentMaxRad,s)})}renderPre({agentIDs:t,highlighted:e},n){const s=this.radius(e,n);t.forEach(t=>{const e=n.agentInfos.get(t);e.currentMaxRad=Math.max(e.currentMaxRad,s)})}render({agentIDs:t,highlighted:e},n){const s=this.radius(e,n);return t.forEach(t=>{n.drawAgentLine(t,n.primaryY),n.agentInfos.get(t).currentRad=s}),n.primaryY+n.theme.actionMargin}renderHidden(t,e){this.render(t,e)}}V("agent highlight",new le);const de={class:"outline",fill:"transparent"};class ge extends $t{prepareMeasurements({left:t,tag:e,label:n},s){const r=s.state.blocks.get(t),i=s.theme.getBlock(r.type).section;s.textSizer.expectMeasure(i.tag.labelAttrs,e),s.textSizer.expectMeasure(i.label.labelAttrs,n)}separation({left:t,right:e,tag:n,label:s},r){const i=r.state.blocks.get(t),a=r.theme.getBlock(i.type).section,o=r.textSizer.measure(a.tag.labelAttrs,n).width+a.tag.padding.left+a.tag.padding.right+r.textSizer.measure(a.label.labelAttrs,s).width+a.label.padding.left+a.label.padding.right;r.addSeparation(t,e,o)}renderPre({left:t,right:e}){return{agentIDs:[t,e]}}render({left:t,right:e,tag:n,label:s},r,i=!1){const a=r.state.blocks.get(t),o=r.theme.getBlock(a.type),h=r.agentInfos.get(t),l=r.agentInfos.get(e);let d=r.primaryY;i||(d+=o.section.padding.bottom);const g=r.makeRegion(),c=r.svg.boxedText({boxAttrs:o.section.tag.boxAttrs,boxRenderer:o.section.tag.boxRenderer,labelAttrs:o.section.tag.labelAttrs,padding:o.section.tag.padding},n,{x:h.x,y:d}),u=r.svg.boxedText({boxAttrs:{fill:"#000000"},labelAttrs:o.section.label.labelAttrs,padding:o.section.label.padding},s,{x:h.x+c.width,y:d}),p=Math.max(Math.max(c.height,u.height),o.section.label.minHeight);return a.hold.add(c.box),r.lineMaskLayer.add(u.box),g.add(r.svg.box(de,{height:p,width:l.x-h.x,x:h.x,y:d}),c.label,u.label),i?a.canHide&&g.addClass(a.hide?"collapsed":"expanded"):a.hold.add(o.sepRenderer({x1:h.x,x2:l.x,y1:d,y2:d})),d+p+o.section.padding.top}}class ce extends ge{makeState(t){t.blocks=new Map}resetState(t){t.blocks.clear()}storeBlockInfo(t,e){const{canHide:n}=t,s={canHide:n,hide:n&&e.renderer.isCollapsed(t.ln),hold:null,startY:null,type:t.blockType};return e.state.blocks.set(t.left,s),s}prepareMeasurements(t,e){this.storeBlockInfo(t,e),super.prepareMeasurements(t,e)}separationPre(t,e){this.storeBlockInfo(t,e),super.separationPre(t,e)}separation(t,n){e(n.visibleAgentIDs,[t.left,t.right]),super.separation(t,n)}renderPre(t,e){const n=this.storeBlockInfo(t,e),s=e.theme.getBlock(n.type);return{agentIDs:[t.left,t.right],topShift:s.margin.top}}render(t,e){const n=e.svg.el("g");e.blockLayer.add(n);const s=e.state.blocks.get(t.left);return s.hold=n,s.startY=e.primaryY,super.render(t,e,!0)}shouldHide({left:t},e){return{nest:e.state.blocks.get(t).hide?1:0,self:!1}}}class ue extends $t{separation({left:t,right:e},s){n(s.visibleAgentIDs,[t,e])}renderPre({left:t,right:e},n){const s=n.state.blocks.get(t);return{agentIDs:[t,e],topShift:n.theme.getBlock(s.type).section.padding.bottom}}render({left:t,right:e},n){const s=n.state.blocks.get(t),r=n.theme.getBlock(s.type),i=n.agentInfos.get(t),a=n.agentInfos.get(e);let o=r.boxRenderer;s.hide&&(o=r.collapsedBoxRenderer||o);let h=o({height:n.primaryY-s.startY,width:a.x-i.x,x:i.x,y:s.startY});return h.shape||(h={shape:h}),s.hold.add(h.shape),n.fillLayer.add(h.fill),n.lineMaskLayer.add(h.mask),n.primaryY+r.margin.bottom+n.theme.actionMargin}shouldHide({left:t},e){return{nest:e.state.blocks.get(t).hide?-1:0,self:!1}}}V("block begin",new ce),V("block split",new ge),V("block end",new ue);const pe={class:"outline",fill:"transparent"};class fe{constructor(t){this.propName=t}getConfig(t){return t.connect.arrow[this.propName]}short(t){const e=this.getConfig(t),n=e.attrs["stroke-linejoin"]||"miter",s=.5*e.attrs["stroke-width"],r=.5*t.agentLineAttrs[""]["stroke-width"];if("round"===n)return r+s;{const t=e.height/2,n=e.width;return r+s*Math.sqrt(n*n/(t*t)+1)}}render(t,e,n,s){const r=this.getConfig(e),i=this.short(e);t.add(r.render(r.attrs,{x:n.x+i*s.dx,y:n.y+i*s.dy,width:r.width,height:r.height,dir:s}))}width(t){return this.short(t)+this.getConfig(t).width}height(t){return this.getConfig(t).height}lineGap(t,e){const n=this.getConfig(t),s=this.short(t);if("none"===n.attrs.fill){const t=n.height/2,r=n.width;return(s+(s+e["stroke-width"]/2*(r/t)))/2}return s+n.width/2}}class me{getConfig(t){return t.connect.arrow.cross}render(t,e,n,s){const r=this.getConfig(e);t.add(r.render({x:n.x+r.short*s.dx,y:n.y+r.short*s.dy,radius:r.radius}))}width(t){const e=this.getConfig(t);return e.short+e.radius}height(t){return 2*this.getConfig(t).radius}lineGap(t){return this.getConfig(t).short}}const be=[{render:()=>null,width:()=>0,height:()=>0,lineGap:()=>0},new fe("single"),new fe("double"),new me];class ye extends $t{prepareMeasurements({agentIDs:t,label:e},n){const s=n.theme.connect,r=t[0]===t[1]?s.label.loopbackAttrs:s.label.attrs;n.textSizer.expectMeasure(r,e)}separationPre({agentIDs:t},e){const n=e.theme.connect.source.radius;t.forEach(t=>{const s=e.agentInfos.get(t);s.isVirtualSource&&(s.currentRad=n,s.currentMaxRad=Math.max(s.currentMaxRad,n))})}separation({label:t,agentIDs:n,options:s},r){const i=r.theme.connect,a=be[s.left],o=be[s.right],h=n[0]===n[1],l=h?i.label.loopbackAttrs:i.label.attrs;let d=r.textSizer.measure(l,t).width;d>0&&(d+=2*i.label.padding);const g=r.agentInfos.get(n[0]);if(h)r.addSpacing(n[0],{left:0,right:g.currentMaxRad+Math.max(d+a.width(r.theme),o.width(r.theme))+i.loopbackRadius});else{const t=r.agentInfos.get(n[1]);r.addSeparation(n[0],n[1],g.currentMaxRad+t.currentMaxRad+d+2*Math.max(a.width(r.theme),o.width(r.theme)))}e(r.momentaryAgentIDs,n)}renderRevArrowLine({x1:t,y1:e,x2:n,y2:s,xR:r},i,a,o){const h=a.theme.connect,l=h.line[i.line],d=be[i.left],g=be[i.right],c=d.lineGap(a.theme,l.attrs),u=g.lineGap(a.theme,l.attrs),p=l.renderRev(l.attrs,{x1:t+c,y1:e,x2:n+u,y2:s,xR:r,rad:h.loopbackRadius});o.add(p.shape),d.render(o,a.theme,{x:p.p1.x-c,y:p.p1.y},{dx:1,dy:0}),g.render(o,a.theme,{x:p.p2.x-u,y:p.p2.y},{dx:1,dy:0})}renderSelfConnect({label:t,agentIDs:e,options:n},s,r,i){const a=s.theme.connect,o=be[n.left],h=be[n.right],l=s.agentInfos.get(e[1]),d=t?s.textSizer.measureHeight(a.label.attrs,t)+a.label.margin.top+a.label.margin.bottom:0,g=r.x+r.currentMaxRad+o.width(s.theme)+(t?a.label.padding:0),c=s.svg.boxedText({padding:a.mask.padding,boxAttrs:{fill:"#000000"},labelAttrs:a.label.loopbackAttrs},t,{x:g-a.mask.padding.left,y:i-d+a.label.margin.top}),u=t?c.width+a.label.padding-a.mask.padding.left-a.mask.padding.right:0,p=Math.max(l.x+l.currentMaxRad+h.width(s.theme),g+u),f=Math.max(d,o.height(s.theme)/2),m=h.height(s.theme)/2;s.lineMaskLayer.add(c.box);const b=s.makeRegion().add(s.svg.box(pe,{x:r.x,y:i-f,width:p+a.loopbackRadius-r.x,height:f+s.primaryY-i+m}),c.label);return this.renderRevArrowLine({x1:r.x+r.currentMaxRad,y1:i,x2:l.x+l.currentMaxRad,y2:s.primaryY,xR:p},n,s,b),s.primaryY+Math.max(m,0)+s.theme.actionMargin}renderArrowLine({x1:t,y1:e,x2:n,y2:s},r,i,a){const o=i.theme.connect.line[r.line],h=be[r.left],l=be[r.right],d=Math.sqrt((n-t)*(n-t)+(s-e)*(s-e)),g=h.lineGap(i.theme,o.attrs),c=l.lineGap(i.theme,o.attrs),u=(n-t)/d,p=(s-e)/d,f=o.renderFlat(o.attrs,{x1:t+g*u,y1:e+g*p,x2:n-c*u,y2:s-c*p});a.add(f.shape);const m={x:f.p1.x-g*u,y:f.p1.y-g*p},b={x:f.p2.x+c*u,y:f.p2.y+c*p};return h.render(a,i.theme,m,{dx:u,dy:p}),l.render(a,i.theme,b,{dx:-u,dy:-p}),{p1:m,p2:b,lArrow:h,rArrow:l}}renderVirtualSources({from:t,to:e,rendered:n},s,r){const i=s.theme.connect.source;t.isVirtualSource&&r.add(i.render({x:n.p1.x-i.radius,y:n.p1.y,radius:i.radius})),e.isVirtualSource&&r.add(i.render({x:n.p2.x+i.radius,y:n.p2.y,radius:i.radius}))}renderSimpleLabel(t,{layer:e,x1:n,x2:s,y1:r,y2:i,height:a},o){const h=o.theme.connect,l=(n+s)/2,d=(r+i)/2;let g=e;const c={fill:"#000000"};if(r!==i){const t="rotate("+180*Math.atan((i-r)/(s-n))/Math.PI+" "+l+","+d+")";c.transform=t,g=o.svg.el("g").attr("transform",t),e.add(g)}const u=o.svg.boxedText({padding:h.mask.padding,boxAttrs:c,labelAttrs:h.label.attrs},t,{x:l,y:d+h.label.margin.top-a});o.lineMaskLayer.add(u.box),g.add(u.label)}renderSimpleConnect({label:t,agentIDs:e,options:n},s,r,i){const a=s.theme.connect,o=s.agentInfos.get(e[1]),h=r.x{return e.components.get(t.type)[n](t,e)})}prepareMeasurements(t,e){this.invokeChildren(t,e,"prepareMeasurements")}separationPre(t,e){this.invokeChildren(t,e,"separationPre")}separation(t,e){this.invokeChildren(t,e,"separation")}renderPre(t,e){return this.invokeChildren(t,e,"renderPre").map(t=>B(t)).reduce(j,{agentIDs:[],asynchronousY:null,topShift:0})}render(t,e){const n=e.makeRegion;let s=0;return t.stages.forEach(t=>{e.makeRegion=((e={})=>n(Object.assign({stageOverride:t},e)));const r=e.components.get(t.type).render(t,e)||0;s=Math.max(s,r)}),e.makeRegion=n,s}renderHidden(t,e){this.invokeChildren(t,e,"renderHidden")}shouldHide(t,e){return this.invokeChildren(t,e,"shouldHide").reduce((t,{self:e=!1,nest:n=0}={})=>({nest:t.nest+n,self:t.self||Boolean(e)}),{nest:0,self:!1})}}V("parallel",new Ge);class Ie{constructor(t){this.element=t}addBefore(t=null,e=null){if(null===t)return this;if(Array.isArray(t))for(const n of t)this.addBefore(n,e);else{const n=function(t,e){return"string"==typeof t?e.createTextNode(t):"number"==typeof t?e.createTextNode(t.toString(10)):"object"==typeof t&&t.element?t.element:t}(t,this.element.ownerDocument);this.element.insertBefore(n,q(e))}return this}add(...t){return this.addBefore(t,null)}del(t=null){return null!==t&&this.element.removeChild(q(t)),this}attr(t,e){return this.element.setAttribute(t,e),this}attrs(t){for(const e in t)Object.prototype.hasOwnProperty.call(t,e)&&this.element.setAttribute(e,t[e]);return this}styles(t){for(const e in t)Object.prototype.hasOwnProperty.call(t,e)&&(this.element.style[e]=t[e]);return this}setClass(t){return this.attr("class",t)}addClass(t){const e=this.element.getAttribute("class");if(!e)return this.setClass(t);const n=e.split(" ");return n.includes(t)?this:(n.push(t),this.attr("class",n.join(" ")))}delClass(t){const e=this.element.getAttribute("class");if(!e)return this;const n=e.split(" "),s=n.indexOf(t);return-1!==s&&(n.splice(s,1),this.attr("class",n.join(" "))),this}text(t){return this.element.textContent=t,this}on(t,e,n={}){if(Array.isArray(t))for(const s of t)this.on(s,e,n);else this.element.addEventListener(t,e,n);return this}off(t,e,n={}){if(Array.isArray(t))for(const s of t)this.off(s,e,n);else this.element.removeEventListener(t,e,n);return this}val(t){return this.element.value=t,this}select(t,e=null){return this.element.selectionStart=t,this.element.selectionEnd=null===e?t:e,this}focus(){return this.element.focus(),this}focussed(){return this.element===this.element.ownerDocument.activeElement}empty(){for(;this.element.childNodes.length>0;)this.element.removeChild(this.element.lastChild);return this}attach(t){return q(t).appendChild(this.element),this}detach(){return this.element.parentNode.removeChild(this.element),this}}class De{constructor(t){if(!t)throw new Error("Missing document!");this.document=t,this.wrap=this.wrap.bind(this),this.el=this.el.bind(this),this.txt=this.txt.bind(this)}wrap(t){return t.element?t:new Ie(t)}el(t,e=null){let n=null;return n=null===e?this.document.createElement(t):this.document.createElementNS(e,t),new Ie(n)}txt(t=""){return this.document.createTextNode(t)}}const Le=[];class Ne{constructor(t,e,n={}){this.container=t,this.svg=e,this.state={attrs:{},formatted:Le,x:0,y:0},this.lines=[],this.set(n)}_rebuildLines(t){if(t>this.lines.length)for(;this.lines.lengtht;)this.lines.pop().node.detach()}_reset(){this._rebuildLines(0)}_renderText(){const{formatted:t}=this.state;if(t&&t.length){if(!Array.isArray(t))throw new Error("Invalid formatted text: "+t);this._rebuildLines(t.length),this.lines.forEach((e,n)=>{const s=JSON.stringify(t[n]);s!==e.latest&&(e.node.empty(),Y(this.svg,e.node,t[n]),e.latest=s)})}else this._reset()}_updateX(){this.lines.forEach(({node:t})=>{t.attr("x",this.state.x)})}_updateY(){const t=this.svg.textSizer;let e=this.state.y;for(let n=0;n0&&(this.points.push(this.x+" "+this.y),this.disconnect=0),this}move(t,e){return this.cap(),this.x=t,this.y=e,this.disconnect=2,this}line(t,e,{patterned:n=!0}={}){if(this.pattern&&n){const n=Math.sqrt((t-this.x)*(t-this.x)+(e-this.y)*(e-this.y)),s=(t-this.x)/n,r=(e-this.y)/n,i=-r,a=s;for(let t=0;t+this.dw<=n;t+=this.dw){const e=this._nextDelta();this.points.push(this.x+t*s+e*i+" "+(this.y+t*r+e*a))}this.disconnect=1}else this._link(),this.disconnect=2;return this.x=t,this.y=e,this}arc(t,e,n){const s=Math.sqrt((t-this.x)*(t-this.x)+(e-this.y)*(e-this.y)),r=Math.atan2(this.x-t,e-this.y),i=t+Math.sin(r+n)*s,a=e-Math.cos(r+n)*s;if(this.pattern){const i=n<0?1:-1,a=this.dw/s;for(let o=r;o+a<=r+n;o+=a){const n=this._nextDelta()*i;this.points.push(t+Math.sin(o)*(s+n)+" "+(e-Math.cos(o)*(s+n)))}this.disconnect=1}else this.points.push(this.x+" "+this.y+"A"+s+" "+s+" 0 "+(Math.abs(n)>=Math.PI?"1 ":"0 ")+(n<0?"0 ":"1 ")+i+" "+a),this.disconnect=0;return this.x=i,this.y=a,this}asPath(){return this._link(),"M"+this.points.join("L")}}const Be="http://www.w3.org/2000/svg";class Ve{constructor(t){this.sizer=t,this.cache=new Map,this.active=null}_expectMeasure({attrs:t,formatted:e}){if(!e.length)return null;const n=JSON.stringify(t);let s=this.cache.get(n);return s||(s={attrs:t,lines:new Map},this.cache.set(n,s)),e.forEach(t=>{if(!t.length)return;const e=JSON.stringify(t);s.lines.has(e)||s.lines.set(e,{formatted:t,width:null})}),s}_measureLine(t,e){if(!e.length)return 0;const n=JSON.stringify(e),s=t.lines.get(n);return null===s.width&&(window.console.warn("Performing unexpected measurement",e),this.performMeasurements()),s.width}_measureWidth(t){if(!t.formatted.length)return 0;const e=this._expectMeasure(t);return t.formatted.map(t=>this._measureLine(e,t)).reduce((t,e)=>Math.max(t,e),0)}_getMeasurementOpts(t,e){const n={attrs:t,formatted:e};if(e||(t.textBlock?(n.attrs=t.textBlock.state.attrs,n.formatted=t.textBlock.state.formatted):t.state&&(n.attrs=t.state.attrs,n.formatted=t.state.formatted),n.formatted=n.formatted||[]),!Array.isArray(n.formatted))throw new Error("Invalid formatted text: "+n.formatted);return n}expectMeasure(t,e){const n=this._getMeasurementOpts(t,e);this._expectMeasure(n)}performMeasurementsPre(){this.active=[],this.cache.forEach(({attrs:t,lines:e})=>{e.forEach(e=>{null===e.width&&this.active.push({cacheLine:e,data:this.sizer.prepMeasurement(t,e.formatted)})})}),this.active.length&&this.sizer.prepComplete()}performMeasurementsAct(){this.active.forEach(({data:t,cacheLine:e})=>{e.width=this.sizer.performMeasurement(t)})}performMeasurementsPost(){this.active.length&&this.sizer.teardown(),this.active=null}performMeasurements(){try{this.performMeasurementsPre(),this.performMeasurementsAct()}finally{this.performMeasurementsPost()}}measure(t,e){const n=this._getMeasurementOpts(t,e);return{height:this.sizer.measureHeight(n),width:this._measureWidth(n)}}baseline(t,e){const n=this._getMeasurementOpts(t,e);return this.sizer.baseline(n)}measureHeight(t,e){const n=this._getMeasurementOpts(t,e);return this.sizer.measureHeight(n)}resetCache(){this.cache.clear()}}class He{constructor(t,e=null){this.dom=t,this.body=this.el("svg").attr("xmlns",Be).attr("version","1.1");const n=e||(t=>new ze(t));this.textSizer=new Ve(n(this)),this.txt=this.txt.bind(this),this.el=this.el.bind(this)}linearGradient(t,e){return this.el("linearGradient").attrs(t).add(e.map(t=>this.el("stop").attrs(t)))}patternedLine(t=null,e=0){return new Oe(t,e)}txt(t){return this.dom.txt(t)}el(t,e=Be){return this.dom.el(t,e)}box(t,{height:e,width:n,x:s,y:r}){return this.el("rect").attrs(t).attrs({height:e,width:n,x:s,y:r})}boxFactory(t){return this.box.bind(this,t)}line(t,{x1:e,x2:n,y1:s,y2:r}){return this.el("line").attrs(t).attrs({x1:e,x2:n,y1:s,y2:r})}lineFactory(t){return this.line.bind(this,t)}circle(t,{x:e,y:n,radius:s}){return this.el("circle").attrs({cx:e,cy:n,r:s}).attrs(t)}circleFactory(t){return this.circle.bind(this,t)}cross(t,{x:e,y:n,radius:s}){return this.el("path").attr("d","M"+(e-s)+" "+(n-s)+"l"+2*s+" "+2*s+"m0 "+2*-s+"l"+2*-s+" "+2*s).attrs(t)}crossFactory(t){return this.cross.bind(this,t)}note(t,e,{height:n,width:s,x:r,y:i}){const a=r,o=r+s,h=i,l=i+n;return this.el("g").add(this.el("polygon").attr("points",a+" "+h+" "+(o-7)+" "+h+" "+o+" "+(h+7)+" "+o+" "+l+" "+a+" "+l).attrs(t),this.el("polyline").attr("points",o-7+" "+h+" "+(o-7)+" "+(h+7)+" "+o+" "+(h+7)).attrs(e))}noteFactory(t,e){return this.note.bind(this,t,e)}formattedText(t={},e=[],{x:n,y:s}={}){const r=this.el("g"),i=new Ne(r,this,{attrs:t,formatted:e,x:n,y:s});return Object.assign(r,{set:t=>i.set(t),textBlock:i})}formattedTextFactory(t){return this.formattedText.bind(this,t)}boxedText({padding:t,labelAttrs:e,boxAttrs:n={},boxRenderer:s=null},r,{x:i,y:a}){if(!r||!r.length)return Object.assign(this.el("g"),{box:null,height:0,label:null,width:0});const{shift:o,anchorX:h}=function(t,e,n){let s=0,r=t;switch(e["text-anchor"]){case"middle":s=.5,r+=(n.left-n.right)/2;break;case"end":s=1,r-=n.right;break;default:s=0,r+=n.left}return{anchorX:r,shift:s}}(i,e,t),l=this.formattedText(e,r,{x:h,y:a+t.top}),d=this.textSizer.measure(l),g=d.width+t.left+t.right,c=d.height+t.top+t.bottom,u=(s||this.boxFactory(n))({height:c,width:g,x:h-d.width*o-t.left,y:a});return Object.assign(this.el("g").add(u,l),{box:u,height:c,label:l,width:g})}boxedTextFactory(t){return this.boxedText.bind(this,t)}}let Te=0;class Pe extends mt{constructor({themes:t=[],namespace:e=null,components:n=null,document:s,textSizerFactory:r=null}={}){super(),this._bindMethods(),this.state={},this.width=0,this.height=0,this.themes=function(t){if(0===t.length)throw new Error("Cannot render without a theme");const e=new Map;return t.forEach(t=>{e.set(t.name,t)}),e.set("",t[0]),e}(t),this.themeBuilder=null,this.theme=null,this.namespace=function(t){return null===t?"R"+Te++:t}(e),this.components=n||H(),this.svg=new He(new De(s),r),this.knownThemeDefs=new Set,this.knownDefs=new Set,this.highlights=new Map,this.collapsed=new Set,this.currentHighlight=-1,this.buildStaticElements(),this.components.forEach(t=>{t.makeState(this.state)})}_bindMethods(){this.separationStage=this.separationStage.bind(this),this.prepareMeasurementsStage=this.prepareMeasurementsStage.bind(this),this.renderStage=this.renderStage.bind(this),this.addThemeDef=this.addThemeDef.bind(this),this.addDef=this.addDef.bind(this)}addTheme(t){this.themes.set(t.name,t)}buildStaticElements(){const{el:t}=this.svg;this.metaCode=this.svg.txt(),this.themeDefs=t("defs"),this.defs=t("defs"),this.fullMask=t("mask").attrs({id:this.namespace+"FullMask",maskUnits:"userSpaceOnUse"}),this.lineMask=t("mask").attrs({id:this.namespace+"LineMask",maskUnits:"userSpaceOnUse"}),this.fullMaskReveal=t("rect").attr("fill","#FFFFFF"),this.lineMaskReveal=t("rect").attr("fill","#FFFFFF"),this.backgroundFills=t("g"),this.agentLines=t("g").attr("mask","url(#"+this.namespace+"LineMask)"),this.blocks=t("g"),this.shapes=t("g"),this.unmaskedShapes=t("g"),this.title=this.svg.formattedText(),this.svg.body.add(this.svg.el("metadata").add(this.metaCode),this.themeDefs,this.defs,this.backgroundFills,t("g").attr("mask","url(#"+this.namespace+"FullMask)").add(this.agentLines,this.blocks,this.shapes),this.unmaskedShapes,this.title)}addThemeDef(t,e){const n=this.namespace+t;return this.knownThemeDefs.has(t)||(this.knownThemeDefs.add(t),this.themeDefs.add(e().attr("id",n))),n}addDef(t,e){let n=t,s=e;"function"!=typeof e&&(n="P"+this.knownDefs.size,s=(()=>t));const r=this.namespace+n;return this.knownDefs.has(n)||(this.knownDefs.add(n),this.defs.add(s().attr("id",r))),r}addSeparation(t,e,n){const s=this.agentInfos.get(t),r=this.agentInfos.get(e),i=s.separations.get(e)||0;s.separations.set(e,Math.max(i,n));const a=r.separations.get(t)||0;r.separations.set(t,Math.max(a,n))}checkHidden(t){const e=this.components.get(t.type),n={agentInfos:this.agentInfos,components:this.components,renderer:this,state:this.state,textSizer:this.svg.textSizer,theme:this.theme},s=e.shouldHide(t,n)||{},r=this.hideNest>0;this.hideNest+=s.nest||0;const i=this.hideNest>0;if(this.hideNest<0)throw new Error("Unexpected nesting in "+t.type);return r===i?i:Boolean(s.self)}separationStage(t){const n=new Map,s=this.visibleAgentIDs.slice(),r=[];this.agentInfos.forEach(t=>{const e=t.currentRad;t.currentMaxRad=e,n.set(t.id,{left:e,right:e})});const i={addSeparation:(t,e,n)=>{r.push({agentID1:t,agentID2:e,dist:n})},addSpacing:(t,{left:e,right:s})=>{const r=n.get(t);r.left=Math.max(r.left,e),r.right=Math.max(r.right,s)},agentInfos:this.agentInfos,components:this.components,momentaryAgentIDs:s,renderer:this,state:this.state,textSizer:this.svg.textSizer,theme:this.theme,visibleAgentIDs:this.visibleAgentIDs},a=this.components.get(t.type);if(!a)throw new Error("Unknown component: "+t.type);a.separationPre(t,i),a.separation(t,i),this.checkHidden(t)||(e(s,this.visibleAgentIDs),r.forEach(({agentID1:t,agentID2:e,dist:n})=>{this.addSeparation(t,e,n)}),s.forEach(t=>{const e=this.agentInfos.get(t),r=n.get(t);e.maxRPad=Math.max(e.maxRPad,r.right),e.maxLPad=Math.max(e.maxLPad,r.left),s.forEach(s=>{if(this.agentInfos.get(s).index>=e.index)return;const i=n.get(s);this.addSeparation(t,s,r.left+i.right+this.theme.agentMargin)})}))}prepareMeasurementsStage(t){const e={agentInfos:this.agentInfos,components:this.components,renderer:this,state:this.state,textSizer:this.svg.textSizer,theme:this.theme},n=this.components.get(t.type);if(!n)throw new Error("Unknown component: "+t.type);n.prepareMeasurements(t,e)}checkAgentRange(t,e=0){if(0===t.length)return e;const{left:n,right:s}=W(this.agentInfos,t),r=this.agentInfos.get(n).x,i=this.agentInfos.get(s).x;let a=e;return this.agentInfos.forEach(t=>{t.x>=r&&t.x<=i&&(a=Math.max(a,t.latestY))}),a}markAgentRange(t,e){if(0===t.length)return;const{left:n,right:s}=W(this.agentInfos,t),r=this.agentInfos.get(n).x,i=this.agentInfos.get(s).x;this.agentInfos.forEach(t=>{t.x>=r&&t.x<=i&&(t.latestY=e)})}drawAgentLine(t,e){null!==t.latestYStart&&e>t.latestYStart&&this.agentLines.add(this.theme.renderAgentLine({className:"agent-"+t.index+"-line",options:t.options,width:2*t.currentRad,x:t.x,y0:t.latestYStart,y1:e}))}addHighlightObject(t,e){let n=this.highlights.get(t);n||(n=[],this.highlights.set(t,n)),n.push(e)}forwardEvent(t,e,n,s){t.on(e,this.trigger.bind(this,n,s))}renderStage(t){this.agentInfos.forEach(t=>{const e=t.currentRad;t.currentMaxRad=e});const e={agentInfos:this.agentInfos,components:this.components,renderer:this,state:this.state,textSizer:this.svg.textSizer,theme:this.theme},n=this.components.get(t.type),s=n.renderPre(t,e),{agentIDs:r,topShift:i,asynchronousY:a}=B(s,this.currentY),o=this.checkAgentRange(r,a),h={addDef:this.addDef,agentInfos:this.agentInfos,blockLayer:this.blocks,components:this.components,drawAgentLine:(t,e,n=!1)=>{const s=this.agentInfos.get(t);this.drawAgentLine(s,e),s.latestYStart=n?null:e},fillLayer:this.backgroundFills,fullMaskLayer:this.fullMask,lineMaskLayer:this.lineMask,makeRegion:({stageOverride:e=null,unmasked:n=!1}={})=>{const s=this.svg.el("g").setClass("region"),r=e||t;return this.addHighlightObject(r.ln,s),this.forwardEvent(s,"mouseenter","mouseover",[r]),this.forwardEvent(s,"mouseleave","mouseout",[r]),this.forwardEvent(s,"click","click",[r]),this.forwardEvent(s,"dblclick","dblclick",[r]),s.attach(n?this.unmaskedShapes:this.shapes)},primaryY:o+i,renderer:this,state:this.state,svg:this.svg,textSizer:this.svg.textSizer,theme:this.theme,topY:o};let l=o;this.checkHidden(t)?(h.primaryY=o,n.renderHidden(t,h)):l=Math.max(l,n.render(t,h)||0),this.markAgentRange(r,l),this.currentY=l}positionAgents(){const t=[];this.agentInfos.forEach(e=>{let n=0;e.separations.forEach((t,s)=>{const r=this.agentInfos.get(s);r.index{let n=e.x;e=t,t.anchorRight&&(t.separations.forEach((e,s)=>{const r=this.agentInfos.get(s);r.index>t.index&&(n=Math.min(n,r.x-e))}),t.x=n)}),this.agentInfos.forEach(({x:t,maxRPad:e,maxLPad:n})=>{this.minX=Math.min(this.minX,t-n),this.maxX=Math.max(this.maxX,t+e)})}buildAgentInfos(t){this.agentInfos=new Map,t.forEach((t,e)=>{this.agentInfos.set(t.id,{anchorRight:t.anchorRight,currentMaxRad:0,currentRad:0,formattedLabel:t.formattedLabel,id:t.id,index:e,isVirtualSource:t.isVirtualSource,latestY:0,latestYStart:null,maxLPad:0,maxRPad:0,options:t.options,separations:new Map,x:null})})}updateBounds(t){const e=(this.minX+this.maxX)/2,n=this.svg.textSizer.measure(this.title),s=n.height>0?-this.theme.titleMargin-n.height:0;this.title.set({x:e,y:s});const r=n.width/2,i=this.theme.outerMargin,a=Math.min(this.minX,e-r)-i,o=Math.max(this.maxX,e+r)+i,h=s-i,l=t+i;this.width=o-a,this.height=l-h;const d={height:this.height,width:this.width,x:a,y:h};this.fullMaskReveal.attrs(d),this.lineMaskReveal.attrs(d),this.svg.body.attr("viewBox",a+" "+h+" "+this.width+" "+this.height)}_resetState(){this.components.forEach(t=>{t.resetState(this.state)}),this.currentY=0,this.hideNest=0}_reset(t){t&&(this.knownThemeDefs.clear(),this.themeDefs.empty()),this.knownDefs.clear(),this.highlights.clear(),this.defs.empty(),this.fullMask.empty(),this.lineMask.empty(),this.backgroundFills.empty(),this.agentLines.empty(),this.blocks.empty(),this.shapes.empty(),this.unmaskedShapes.empty(),this.defs.add(this.fullMask.add(this.fullMaskReveal),this.lineMask.add(this.lineMaskReveal)),this._resetState()}setHighlight(t=null){const e=null===t?-1:t;this.currentHighlight!==e&&(this.highlights.has(this.currentHighlight)&&this.highlights.get(this.currentHighlight).forEach(t=>{t.delClass("focus")}),this.highlights.has(e)&&this.highlights.get(e).forEach(t=>{t.addClass("focus")}),this.currentHighlight=e)}isCollapsed(t){return this.collapsed.has(t)}setCollapseAll(t){if(t)throw new Error("Cannot collapse all");return 0!==this.collapsed.size&&(this.collapsed.clear(),!0)}_setCollapsed(t,e){return"number"==typeof t&&(e!==this.isCollapsed(t)&&(e?this.collapsed.add(t):this.collapsed.delete(t),!0))}setCollapsed(t,e=!0){return null===t?this.setCollapseAll(e):Array.isArray(t)?t.map(t=>this._setCollapsed(t,e)).some(t=>t):this._setCollapsed(t,e)}_switchTheme(t){const e=this.themeBuilder;return this.themeBuilder=this.getThemeNamed(t),this.themeBuilder!==e&&(this.theme=this.themeBuilder.build(this.svg)),this.theme.reset(),this.themeBuilder!==e}optimisedRenderPreReflow(t){const e=this._switchTheme(t.meta.theme);this._reset(e),this.metaCode.nodeValue=t.meta.code,this.theme.addDefs(this.addThemeDef),this.title.set({attrs:this.theme.titleAttrs,formatted:t.meta.title}),this.svg.textSizer.expectMeasure(this.title),this.minX=0,this.maxX=0,this.buildAgentInfos(t.agents),t.stages.forEach(this.prepareMeasurementsStage),this._resetState(),this.svg.textSizer.performMeasurementsPre()}optimisedRenderReflow(){this.svg.textSizer.performMeasurementsAct()}optimisedRenderPostReflow(t){this.visibleAgentIDs=["[","]"],t.stages.forEach(this.separationStage),this._resetState(),this.positionAgents(),t.stages.forEach(this.renderStage);const e=this.checkAgentRange(["[","]"],this.currentY),n=Math.max(e-this.theme.actionMargin,0);this.updateBounds(n);const s=this.currentHighlight;this.currentHighlight=-1,this.setHighlight(s),this.svg.textSizer.performMeasurementsPost(),this.svg.textSizer.resetCache()}render(t){this.optimisedRenderPreReflow(t),this.optimisedRenderReflow(),this.optimisedRenderPostReflow(t)}getThemeNames(){return Array.from(this.themes.keys()).filter(t=>""!==t)}getThemes(){return this.getThemeNames().map(t=>this.themes.get(t))}getThemeNamed(t){const e=this.themes.get(t);return e||this.themes.get("")}getAgentX(t){return this.agentInfos.get(t).x}dom(){return this.svg.body.element}}var je={name:"Handlee",woff2:"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"};class qe{constructor(){this.s=new Uint32Array(4)}reset(){this.s[0]=394173556,this.s[1]=2926575054,this.s[2]=1022685995,this.s[3]=1178902408}nextFloat(){let t=this.s[0],e=this.s[1];const n=this.s[2],s=this.s[3];return this.s[0]=n,this.s[1]=s,t^=t<<23|e>>>9,e^=e<<23,this.s[2]=t^n^t>>>17^n>>>26,this.s[3]=e^s^(t<<15|e>>>17)^(n<<6|s>>>26),(this.s[3]+s>>>0)%4294967296/4294967296}}const Ye=je.name,We="'"+Ye+"',cursive",Ue={normal:{stroke:"rgba(0,0,0,0.7)","stroke-width":.8,"stroke-linejoin":"round","stroke-linecap":"round"},thick:{stroke:"rgba(0,0,0,0.8)","stroke-width":1.2,"stroke-linejoin":"round","stroke-linecap":"round"}},Xe={"font-family":We,"font-size":8,"line-height":1.5},Qe={"font-family":We,"font-size":8,"line-height":1.5,"text-anchor":"middle"},Je={};class Ze{constructor(t,e){this.deltas=[0,-.3,-.6,-.75,-.45,0,.45,.75,.6,.3],e!==Je&&this.deltas.reverse(),this.partWidth=6/this.deltas.length}getDelta(t){return this.deltas[t%this.deltas.length]+.5*Math.sin(.03*t)}}class Ke extends st{constructor(t,e=Je){super(t),this.handedness=e===Je?1:-1,this.random=new qe,this.wave=new Ze(4,e);const n={padding:{top:3,bottom:2},tag:{padding:{top:2,left:3,right:5,bottom:0},boxRenderer:this.renderTag.bind(this),labelAttrs:{"font-family":We,"font-weight":"bold","font-size":9,"line-height":1.5,"text-anchor":"left"}},label:{minHeight:6,padding:{top:2,left:5,right:3,bottom:1},labelAttrs:{"font-family":We,"font-size":8,"line-height":1.5,"text-anchor":"left"}}};Object.assign(this,{titleMargin:10,outerMargin:5,agentMargin:10,actionMargin:10,minActionMargin:3,agentLineHighlightRadius:4,agentCap:{box:{padding:{top:5,left:10,right:10,bottom:5},arrowBottom:12.8,labelAttrs:{"font-family":We,"font-size":12,"line-height":1.5,"text-anchor":"middle"},boxRenderer:this.renderBox.bind(this)},database:{padding:{top:12,left:10,right:10,bottom:2},arrowBottom:12.8,boxRenderer:this.renderDB.bind(this,Object.assign({fill:"#FFFFFF","db-z":5},Ue.normal)),labelAttrs:{"font-family":Ye,"font-size":12,"line-height":1.5,"text-anchor":"middle"}},cross:{size:15,render:this.renderCross.bind(this)},bar:{height:6,render:this.renderBar.bind(this)},fade:{width:Math.ceil(12),height:6,extend:Math.ceil(2.5)},none:{height:10}},connect:{loopbackRadius:6,line:{solid:{attrs:Object.assign({fill:"none"},Ue.normal),renderFlat:this.renderFlatConnect.bind(this),renderRev:this.renderRevConnect.bind(this)},dash:{attrs:Object.assign({fill:"none","stroke-dasharray":"4, 2"},Ue.normal),renderFlat:this.renderFlatConnect.bind(this),renderRev:this.renderRevConnect.bind(this)},wave:{attrs:Object.assign({fill:"none","stroke-linejoin":"round","stroke-linecap":"round"},Ue.normal),renderFlat:this.renderFlatConnectWave.bind(this),renderRev:this.renderRevConnectWave.bind(this)}},arrow:{single:{width:5,height:6,attrs:Object.assign({fill:"rgba(0,0,0,0.9)"},Ue.normal),render:this.renderArrowHead.bind(this)},double:{width:4,height:8,attrs:Object.assign({fill:"none"},Ue.normal),render:this.renderArrowHead.bind(this)},cross:{short:5,radius:3,render:this.renderCross.bind(this)}},label:{padding:6,margin:{top:2,bottom:1},attrs:{"font-family":We,"font-size":8,"line-height":1.5,"text-anchor":"middle"},loopbackAttrs:{"font-family":We,"font-size":8,"line-height":1.5}},source:{radius:1,render:t.circleFactory({fill:"#000000",stroke:"#000000","stroke-width":1})},mask:{padding:{top:0,left:3,right:3,bottom:1}}},titleAttrs:{"font-family":We,"font-size":20,"line-height":1.5,"text-anchor":"middle",class:"title"},agentLineAttrs:{"":Object.assign({fill:"none"},Ue.normal),red:{stroke:"rgba(200,40,0,0.8)"}},blocks:{ref:{margin:{top:0,bottom:0},boxRenderer:this.renderRefBlock.bind(this),section:n},"":{margin:{top:0,bottom:0},boxRenderer:this.renderBlock.bind(this),collapsedBoxRenderer:this.renderMinBlock.bind(this),section:n,sepRenderer:this.renderSeparator.bind(this)}},notes:{text:{margin:{top:0,left:6,right:6,bottom:0},padding:{top:2,left:2,right:2,bottom:2},overlap:{left:10,right:10},boxRenderer:t.boxFactory({fill:"#FFFFFF"}),labelAttrs:Xe},note:{margin:{top:0,left:5,right:5,bottom:0},padding:{top:5,left:5,right:10,bottom:5},overlap:{left:10,right:10},boxRenderer:this.renderNote.bind(this),labelAttrs:Xe},state:{margin:{top:0,left:5,right:5,bottom:0},padding:{top:7,left:7,right:7,bottom:7},overlap:{left:10,right:10},boxRenderer:this.renderState.bind(this),labelAttrs:Xe}},dividers:{"":{labelAttrs:Qe,padding:{top:2,left:5,right:5,bottom:2},extend:0,margin:0,render:()=>({})},line:{labelAttrs:Qe,padding:{top:2,left:5,right:5,bottom:2},extend:10,margin:0,render:this.renderLineDivider.bind(this)},delay:{labelAttrs:Qe,padding:{top:2,left:5,right:5,bottom:2},extend:0,margin:0,render:this.renderDelayDivider.bind(this,{dotSize:1,gapSize:2})},tear:{labelAttrs:Qe,padding:{top:2,left:5,right:5,bottom:2},extend:10,margin:10,render:this.renderTearDivider.bind(this,{fadeBegin:5,fadeSize:10,pattern:this.wave,lineAttrs:Ue.normal})}}})}reset(){this.random.reset()}addDefs(t){t("sketch_font",()=>{const t=this.svg.el("style",null);return t.text('@font-face{font-family:"'+je.name+'";src:url("data:font/woff2;base64,'+je.woff2+'");}'),t})}vary(t,e=0){if(!t)return e;const n=this.random.nextFloat();return e+2*Math.asin(2*n-1)*t/Math.PI}lineNodes(t,e,{var1:n=1,var2:s=1,varX:r=1,varY:i=1,move:a=!0}){const o=Math.sqrt((e.x-t.x)*(e.x-t.x)+(e.y-t.y)*(e.y-t.y)),h=Math.min(.2*Math.sqrt(o),5),l=this.vary(n*r*h,t.x),d=this.vary(n*i*h,t.y),g=this.vary(s*r*h,e.x),c=this.vary(s*i*h,e.y),u=function(t,e,n){return Math.max(e,Math.min(n,t))}((d-c)/(Math.abs(l-g)+.001),-1,1)/6+.5,p=this.vary(.5,.5)*h,f=this.vary(.5,.5)*h,m=l*(1-u)+g*u-p*this.handedness;return{nodes:(a?"M"+l+" "+d:"")+"C"+m+" "+(d*(1-u)+c*u-f)+","+g+" "+c+","+g+" "+c,p1:{x:l,y:d},p2:{x:g,y:c}}}renderLine(t,e,n){const s=this.lineNodes(t,e,n);return this.svg.el("path").attrs({d:s.nodes,fill:"none","stroke-dasharray":n.dash?"6, 5":"none"}).attrs(n.attrs||(n.thick?Ue.thick:Ue.normal))}boxNodes({x:t,y:e,width:n,height:s}){const r=this.lineNodes({x:t,y:e},{x:t+n,y:e},{}),i=this.lineNodes({x:t+n,y:e+s},{x:t,y:e+s},{move:!1}),a=this.lineNodes(r.p2,i.p1,{var1:0,var2:0,move:!1}),o=this.lineNodes(i.p2,r.p1,{var1:0,var2:.3,move:!1});return r.nodes+a.nodes+i.nodes+o.nodes}renderBox(t,{fill:e=null,thick:n=!1,attrs:s=null}={}){return this.svg.el("path").attrs({d:this.boxNodes(t),fill:e||"#FFFFFF"}).attrs(s||(n?Ue.thick:Ue.normal))}renderNote({x:t,y:e,width:n,height:s}){const r=this.lineNodes({x:t,y:e},{x:t+n-5,y:e},{}),i=this.lineNodes(r.p2,{x:t+n,y:e+5},{move:!1,var1:0}),a=this.lineNodes({x:t+n,y:e+s},{x:t,y:e+s},{move:!1}),o=this.lineNodes(i.p2,a.p1,{var1:0,var2:0,move:!1}),h=this.lineNodes(a.p2,r.p1,{var1:0,var2:.3,move:!1}),l=this.lineNodes(i.p1,{x:t+n-5,y:e+5},{var1:.3}),d=this.lineNodes(l.p2,i.p2,{var1:0,move:!1});return this.svg.el("g").add(this.svg.el("path").attrs({d:r.nodes+i.nodes+o.nodes+a.nodes+h.nodes,fill:"#FFFFFF"}).attrs(Ue.normal),this.svg.el("path").attrs({d:l.nodes+d.nodes,fill:"none"}).attrs(Ue.normal))}renderLineDivider({x:t,y:e,labelWidth:n,width:s,height:r}){let i=null;const a=e+r/2;return i=n>0?this.svg.el("g").add(this.renderLine({x:t,y:a},{x:t+(s-n)/2,y:a},{}),this.renderLine({x:t+(s+n)/2,y:a},{x:t+s,y:a},{})):this.renderLine({x:t,y:a},{x:t+s,y:a},{}),{shape:i}}renderFlatConnect(t,{x1:e,y1:n,x2:s,y2:r}){const i=this.lineNodes({x:e,y:n},{x:s,y:r},{varX:.3});return{shape:this.svg.el("path").attr("d",i.nodes).attrs(t),p1:i.p1,p2:i.p2}}renderRevConnect(t,{x1:e,y1:n,x2:s,y2:r,xR:i}){const a=Math.min(.06*(i-e),3),o=Math.min(.5*(i-e),6),h=e+this.vary(a,-1),l=n+this.vary(a,-1),d=i-o*this.vary(.2,1),g=n-this.vary(1,2),c=i,u=n+this.vary(1,1),p=i,f=r+this.vary(2),m=s+this.vary(a,-1),b=r+this.vary(a,-1);return{shape:this.svg.el("path").attr("d","M"+h+" "+l+"C"+h+" "+l+","+d+" "+g+","+c+" "+u+"S"+p+" "+f+","+m+" "+b).attrs(t),p1:{x:h,y:l},p2:{x:m,y:b}}}renderFlatConnectWave(t,{x1:e,y1:n,x2:s,y2:r}){const i=e+this.vary(.3),a=s+this.vary(.3),o=n+this.vary(1),h=r+this.vary(1);return{shape:this.svg.el("path").attr("d",this.svg.patternedLine(this.wave).move(i,o).line(a,h).cap().asPath()).attrs(t),p1:{x:i,y:o},p2:{x:a,y:h}}}renderRevConnectWave(t,{x1:e,y1:n,x2:s,y2:r,xR:i}){const a=e+this.vary(.3),o=s+this.vary(.3),h=n+this.vary(1),l=r+this.vary(1);return{shape:this.svg.el("path").attr("d",this.svg.patternedLine(this.wave).move(a,h).line(i,n).arc(i,(n+r)/2,Math.PI).line(o,l).cap().asPath()).attrs(t),p1:{x:a,y:h},p2:{x:o,y:l}}}renderArrowHead(t,{x:e,y:n,width:s,height:r,dir:i}){const a=s*this.vary(.2,1),o=r*this.vary(.3,1),h=a*i.dx,l=a*i.dy,d=.5*o*i.dx,g=.5*-o*i.dy,c=this.lineNodes({x:e+h-g,y:n+l-d},{x:e,y:n},{var1:2,var2:.2}),u=this.lineNodes(c.p2,{x:e+h+g,y:n+l+d},{var1:0,var2:2,move:!1}),p="none"===t.fill?{nodes:""}:this.lineNodes(u.p2,c.p1,{var1:0,var2:0,move:!1});return this.svg.el("path").attr("d",c.nodes+u.nodes+p.nodes).attrs(t)}renderState({x:t,y:e,width:n,height:s}){const r=Math.min(.06*n,3),i=Math.min(.06*s,3),a=t+r*this.vary(.6,1),o=e+i*this.vary(.6,1),h=t+n-r*this.vary(.6,1),l=e+i*this.vary(.6,1),d=t+r*this.vary(.6,1),g=e+s-i*this.vary(.6,1),c=t+n-r*this.vary(.6,1),u=e+s-i*this.vary(.6,1),p=t+n/2,f=e+s/2,m=r*this.vary(.2,1.2),b=i*this.vary(.2,1.2),y=e-Math.min(.005*n,1),x=e+s-Math.min(.01*n,2),k=t-Math.min(.01*s,2)*this.handedness,w=k+n;return this.svg.el("path").attr("d","M"+a+" "+o+"C"+(a+m)+" "+(o-b)+","+(p-n*this.vary(.03,.3))+" "+y+","+p+" "+y+"S"+(h-m)+" "+(l-b)+","+h+" "+l+"S"+w+" "+(f-s*this.vary(.03,.3))+","+w+" "+f+"S"+(c+m)+" "+(u-b)+","+c+" "+u+"S"+(p+n*this.vary(.03,.3))+" "+x+","+p+" "+x+"S"+(d+m)+" "+(g+b)+","+d+" "+g+"S"+k+" "+(f+s*this.vary(.03,.3))+","+k+" "+f+"S"+(a-m)+" "+(o+b)+","+a+" "+o+"Z").attr("fill","#FFFFFF").attrs(Ue.normal)}renderRefBlock(t){const e=this.boxNodes(t);return{shape:this.svg.el("path").attrs({d:e,fill:"none"}).attrs(Ue.thick),mask:this.svg.el("path").attrs({d:e,fill:"#000000"}),fill:this.svg.el("path").attrs({d:e,fill:"#FFFFFF"})}}renderBlock(t){return this.renderBox(t,{fill:"none",thick:!0})}renderMinBlock(t){return this.renderRefBlock(t)}renderTag({x:t,y:e,width:n,height:s}){const r=t+n,i=e+s,a=this.lineNodes({x:r+3,y:e},{x:r-2,y:i},{}),o=this.lineNodes(a.p2,{x:t,y:i+1},{var1:0,move:!1}),h=a.nodes+o.nodes;return this.svg.el("g").add(this.svg.el("path").attrs({d:h+"L"+t+" "+e,fill:"#FFFFFF"}),this.svg.el("path").attrs({d:h,fill:"#FFFFFF"}).attrs(Ue.normal))}renderSeparator({x1:t,y1:e,x2:n,y2:s}){return this.renderLine({x:t,y:e},{x:n,y:s},{thick:!0,dash:!0})}renderBar({x:t,y:e,width:n,height:s}){return this.renderBox({x:t,y:e,width:n,height:s},{fill:"#000000"})}renderCross({x:t,y:e,radius:n}){const s=this.vary(.2,1)*n,r=this.lineNodes({x:t-s,y:e-s},{x:t+s,y:e+s},{}),i=this.vary(.2,1)*n,a=this.lineNodes({x:t+i,y:e-i},{x:t-i,y:e+i},{});return this.svg.el("path").attrs({d:r.nodes+a.nodes,fill:"none"}).attrs(Ue.normal)}renderAgentLine({x:t,y0:e,y1:n,width:s,className:r,options:i}){const a=this.optionsAttributes(this.agentLineAttrs,i);return s>0?this.renderBox({x:t-s/2,y:e,width:s,height:n-e},{fill:"none",attrs:a}).setClass(r):this.renderLine({x:t,y:e},{x:t,y:n},{varY:.3,attrs:a}).setClass(r)}}class _e{constructor(t=Je){const e=t===Je;this.name=e?"sketch":"sketch left handed",this.handedness=t}build(t){return new Ke(t,this.handedness)}}Object.assign(_e,{RIGHT:Je,LEFT:{}});const $e=/^([ \t]*)(.*)$/,tn={after:".!+",end:/[ \t\r\n]$/,start:/^[ \t\r\n:,]/},en=/^"(\\.|[^"])*$/,nn=/[\r\n:,"<>\-~]/,sn=/["\\]/g,rn=[new lt,new Lt,new ft,new _e(_e.RIGHT),new _e(_e.LEFT)],an=new _t,on=new Rt,hn=an.getCodeMirrorMode();class ln extends mt{constructor(t=null,e={}){super();let n=null;t&&"object"==typeof t?(n=t,this.code=n.code):(n=e,this.code=t),Object.assign(this,{exporter:new kt,generator:on,isInteractive:!1,latestProcessed:null,parser:an,registerCodeMirrorMode:K,renderer:new Pe(Object.assign({document:function(t){return t?t.ownerDocument||null:"undefined"==typeof window?null:window.document}(n.container),themes:rn},n)),textSizerFactory:n.textSizerFactory||null}),this.renderer.addEventForwarding(this),n.container&&n.container.appendChild(this.dom()),n.interactive&&this.addInteractivity(),"string"==typeof this.code&&!1!==n.render&&this.render()}clone(t={}){const e=t.container||this.renderer.dom();return new ln(Object.assign({code:this.code,components:this.renderer.components,container:null,document:e.ownerDocument,interactive:this.isInteractive,namespace:null,textSizerFactory:this.textSizerFactory,themes:this.renderer.getThemes()},t))}set(t="",{render:e=!0}={}){this.code!==t&&(this.code=t,e&&this.render())}process(t){const e=this.parser.parse(t);return this.generator.generate(e)}addTheme(t){this.renderer.addTheme(t)}setHighlight(t){this.renderer.setHighlight(t)}isCollapsed(t){return this.renderer.isCollapsed(t)}setCollapsed(t,e=!0,{render:n=!0}={}){return!!this.renderer.setCollapsed(t,e)&&(n&&this.latestProcessed&&this.render(this.latestProcessed),!0)}collapse(t,e){return this.setCollapsed(t,!0,e)}expand(t,e){return this.setCollapsed(t,!1,e)}toggleCollapsed(t,e){return this.setCollapsed(t,!this.isCollapsed(t),e)}expandAll(t){return this.setCollapsed(null,!1,t)}getThemeNames(){return this.renderer.getThemeNames()}getThemes(){return this.renderer.getThemes()}getSVGSynchronous(){return this.exporter.getSVGURL(this.renderer)}getSVG(){return Promise.resolve({latest:!0,url:this.getSVGSynchronous()})}getCanvas({resolution:t=1,size:e=null}={}){return e&&(this.renderer.width=e.width,this.renderer.height=e.height),new Promise(e=>{this.exporter.getCanvas(this.renderer,t,e)})}getPNG({resolution:t=1,size:e=null}={}){return e&&(this.renderer.width=e.width,this.renderer.height=e.height),new Promise(e=>{this.exporter.getPNGURL(this.renderer,t,(t,n)=>{e({latest:n,url:t})})})}getSize(){return{height:this.renderer.height,width:this.renderer.width}}_revertParent(t){const e=this.renderer.dom();e.parentNode!==t.originalParent&&(e.parentNode.removeChild(e),t.originalParent&&t.originalParent.appendChild(e))}_sendRenderError(t){this._revertParent(this.renderState),this.renderState.error=!0,this.trigger("error",[this,t])}optimisedRenderPreReflow(t=null){const e=this.renderer.dom();this.renderState={error:!1,originalParent:e.parentNode,processed:t};const n=this.renderState;e.isConnected||(n.originalParent&&n.originalParent.removeChild(e),e.ownerDocument.body.appendChild(e));try{n.processed||(n.processed=this.process(this.code)),this.renderer.optimisedRenderPreReflow(n.processed)}catch(t){this._sendRenderError(t)}}optimisedRenderReflow(){try{this.renderState.error||this.renderer.optimisedRenderReflow()}catch(t){this._sendRenderError(t)}}optimisedRenderPostReflow(){const t=this.renderState;try{t.error||this.renderer.optimisedRenderPostReflow(t.processed)}catch(t){this._sendRenderError(t)}this.renderState=null,t.error||(this._revertParent(t),this.latestProcessed=t.processed,this.trigger("render",[this]))}render(t=null){function e(t,e){n=e}let n=null;if(this.addEventListener("error",e),this.optimisedRenderPreReflow(t),this.optimisedRenderReflow(),this.optimisedRenderPostReflow(),this.removeEventListener("error",e),n)throw n}setContainer(t=null){const e=this.dom();e.parentNode&&e.parentNode.removeChild(e),t&&t.appendChild(e)}addInteractivity(){this.isInteractive||(this.isInteractive=!0,this.addEventListener("click",t=>{this.toggleCollapsed(t.ln)}))}extractCodeFromSVG(t){return _(t)}renderAll(t){return $(t)}dom(){return this.renderer.dom()}}Object.assign(ln,{Exporter:kt,Generator:Rt,Parser:_t,Renderer:Pe,addTheme:function(t){rn.push(t)},convert:et,convertAll:function(t=null,e="sequence-diagram"){let n=null,s=null;"string"==typeof t?(n=null,s=t):(n=t,s=e);let r=null;r=n&&void 0!==n.length?n:(n||window.document).getElementsByClassName(s);const i=[];for(let t=0;tt.name)},registerCodeMirrorMode:K,renderAll:$,themes:rn});const dn=window.define;dn&&dn.amd?dn(()=>ln):(window.document.addEventListener("DOMContentLoaded",()=>{ln.convertAll()},{once:!0}),window.CodeMirror&&ln.registerCodeMirrorMode(window.CodeMirror),window.SequenceDiagram=ln)}();
\ No newline at end of file
diff --git a/package-lock.json b/package-lock.json
index a5f29ef..e88d60e 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -111,6 +111,12 @@
"integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==",
"dev": true
},
+ "arr-union": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz",
+ "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=",
+ "dev": true
+ },
"array-union": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz",
@@ -144,6 +150,12 @@
"integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=",
"dev": true
},
+ "async-array-reduce": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/async-array-reduce/-/async-array-reduce-0.2.1.tgz",
+ "integrity": "sha1-yL4BCitc0A3qlsgRFgNGk9/dgtE=",
+ "dev": true
+ },
"babel-code-frame": {
"version": "6.26.0",
"resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz",
@@ -580,6 +592,24 @@
"fill-range": "2.2.3"
}
},
+ "expand-tilde": {
+ "version": "1.2.2",
+ "resolved": "https://registry.npmjs.org/expand-tilde/-/expand-tilde-1.2.2.tgz",
+ "integrity": "sha1-C4HrqJflo9MdHD0QL48BRB5VlEk=",
+ "dev": true,
+ "requires": {
+ "os-homedir": "1.0.2"
+ }
+ },
+ "extend-shallow": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+ "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+ "dev": true,
+ "requires": {
+ "is-extendable": "0.1.1"
+ }
+ },
"external-editor": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/external-editor/-/external-editor-2.2.0.tgz",
@@ -683,6 +713,12 @@
"for-in": "1.0.2"
}
},
+ "fs-exists-sync": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/fs-exists-sync/-/fs-exists-sync-0.1.0.tgz",
+ "integrity": "sha1-mC1ok6+RjnLQjeyehnP/K1qNat0=",
+ "dev": true
+ },
"fs.realpath": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
@@ -728,6 +764,28 @@
"is-glob": "2.0.1"
}
},
+ "global-modules": {
+ "version": "0.2.3",
+ "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-0.2.3.tgz",
+ "integrity": "sha1-6lo77ULG1s6ZWk+KEmm12uIjgo0=",
+ "dev": true,
+ "requires": {
+ "global-prefix": "0.1.5",
+ "is-windows": "0.2.0"
+ }
+ },
+ "global-prefix": {
+ "version": "0.1.5",
+ "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-0.1.5.tgz",
+ "integrity": "sha1-jTvGuNo8qBEqFg2NSW/wRiv+948=",
+ "dev": true,
+ "requires": {
+ "homedir-polyfill": "1.0.1",
+ "ini": "1.3.5",
+ "is-windows": "0.2.0",
+ "which": "1.3.0"
+ }
+ },
"globals": {
"version": "11.4.0",
"resolved": "https://registry.npmjs.org/globals/-/globals-11.4.0.tgz",
@@ -769,12 +827,30 @@
"integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
"dev": true
},
+ "has-glob": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/has-glob/-/has-glob-0.1.1.tgz",
+ "integrity": "sha1-omHEwqbGZ+DHe3AKfyl8Oe86pYk=",
+ "dev": true,
+ "requires": {
+ "is-glob": "2.0.1"
+ }
+ },
"he": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/he/-/he-1.1.1.tgz",
"integrity": "sha1-k0EP0hsAlzUVH4howvJx80J+I/0=",
"dev": true
},
+ "homedir-polyfill": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/homedir-polyfill/-/homedir-polyfill-1.0.1.tgz",
+ "integrity": "sha1-TCu8inWJmP7r9e1oWA921GdotLw=",
+ "dev": true,
+ "requires": {
+ "parse-passwd": "1.0.0"
+ }
+ },
"http-proxy": {
"version": "1.16.2",
"resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.16.2.tgz",
@@ -838,6 +914,12 @@
"integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=",
"dev": true
},
+ "ini": {
+ "version": "1.3.5",
+ "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz",
+ "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==",
+ "dev": true
+ },
"inquirer": {
"version": "3.3.0",
"resolved": "https://registry.npmjs.org/inquirer/-/inquirer-3.3.0.tgz",
@@ -980,6 +1062,18 @@
"integrity": "sha512-qgDYXFSR5WvEfuS5dMj6oTMEbrrSaM0CrFk2Yiq/gXnBvD9pMa2jGXxyhGLfvhZpuMZe18CJpFxAt3CRs42NMg==",
"dev": true
},
+ "is-valid-glob": {
+ "version": "0.3.0",
+ "resolved": "https://registry.npmjs.org/is-valid-glob/-/is-valid-glob-0.3.0.tgz",
+ "integrity": "sha1-1LVcafUYhvm2XHDWwmItN+KfSP4=",
+ "dev": true
+ },
+ "is-windows": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-0.2.0.tgz",
+ "integrity": "sha1-3hqm1j6indJIc3tp8f+LgALSEIw=",
+ "dev": true
+ },
"isarray": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
@@ -1001,6 +1095,22 @@
"isarray": "1.0.0"
}
},
+ "jasmine": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/jasmine/-/jasmine-3.1.0.tgz",
+ "integrity": "sha1-K9Wf1+xuwOistk4J9Fpo7SrRlSo=",
+ "dev": true,
+ "requires": {
+ "glob": "7.1.2",
+ "jasmine-core": "3.1.0"
+ }
+ },
+ "jasmine-core": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/jasmine-core/-/jasmine-core-3.1.0.tgz",
+ "integrity": "sha1-pHheE11d9lAk38kiSVPfWFvSdmw=",
+ "dev": true
+ },
"js-tokens": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz",
@@ -1038,6 +1148,15 @@
"is-buffer": "1.1.6"
}
},
+ "lazy-cache": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/lazy-cache/-/lazy-cache-2.0.2.tgz",
+ "integrity": "sha1-uRkKT5EzVGlIQIWfio9whNiCImQ=",
+ "dev": true,
+ "requires": {
+ "set-getter": "0.1.0"
+ }
+ },
"levn": {
"version": "0.3.0",
"resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz",
@@ -1070,6 +1189,23 @@
"yallist": "2.1.2"
}
},
+ "matched": {
+ "version": "0.4.4",
+ "resolved": "https://registry.npmjs.org/matched/-/matched-0.4.4.tgz",
+ "integrity": "sha1-Vte36xgDPwz5vFLrIJD6x9weifo=",
+ "dev": true,
+ "requires": {
+ "arr-union": "3.1.0",
+ "async-array-reduce": "0.2.1",
+ "extend-shallow": "2.0.1",
+ "fs-exists-sync": "0.1.0",
+ "glob": "7.1.2",
+ "has-glob": "0.1.1",
+ "is-valid-glob": "0.3.0",
+ "lazy-cache": "2.0.2",
+ "resolve-dir": "0.1.1"
+ }
+ },
"micromatch": {
"version": "2.3.11",
"resolved": "https://registry.npmjs.org/micromatch/-/micromatch-2.3.11.tgz",
@@ -1242,6 +1378,12 @@
}
}
},
+ "os-homedir": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz",
+ "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=",
+ "dev": true
+ },
"os-tmpdir": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz",
@@ -1266,6 +1408,12 @@
"integrity": "sha1-VjRtR0nXjyNDDKDHE4UK75GqNh0=",
"dev": true
},
+ "parse-passwd": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/parse-passwd/-/parse-passwd-1.0.0.tgz",
+ "integrity": "sha1-bVuTSkVpk7I9N/QKOC1vFmao5cY=",
+ "dev": true
+ },
"path-is-absolute": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
@@ -1488,6 +1636,16 @@
"integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=",
"dev": true
},
+ "resolve-dir": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/resolve-dir/-/resolve-dir-0.1.1.tgz",
+ "integrity": "sha1-shklmlYC+sXFxJatiUpujMQwJh4=",
+ "dev": true,
+ "requires": {
+ "expand-tilde": "1.2.2",
+ "global-modules": "0.2.3"
+ }
+ },
"resolve-from": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-1.0.1.tgz",
@@ -1538,6 +1696,15 @@
"integrity": "sha512-MlxPQTkMtiRUtyhIJ7FpBvTzWtar8eFBA+V7/J6Deg9fSgIIHwL6bJKK1Wl1uWSWtOrWhOmtsMwb9F6aagP/Pg==",
"dev": true
},
+ "rollup-plugin-multi-entry": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/rollup-plugin-multi-entry/-/rollup-plugin-multi-entry-2.0.2.tgz",
+ "integrity": "sha512-TY72fCVJvcEAQBpBzkXykoYQx2fz0B20EVtcbh0WZaYr5eBu3U1dRPzgMt6aO8MePWWOdcmgoBtG6PhmYJr4Ew==",
+ "dev": true,
+ "requires": {
+ "matched": "0.4.4"
+ }
+ },
"rollup-pluginutils": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/rollup-pluginutils/-/rollup-pluginutils-2.0.1.tgz",
@@ -1590,6 +1757,15 @@
"integrity": "sha512-4SJ3dm0WAwWy/NVeioZh5AntkdJoWKxHxcmyP622fOkgHa4z3R0TdBJICINyaSDE6uNwVc8gZr+ZinwZAH4xIA==",
"dev": true
},
+ "set-getter": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/set-getter/-/set-getter-0.1.0.tgz",
+ "integrity": "sha1-12nBgsnVpR9AkUXy+6guXoboA3Y=",
+ "dev": true,
+ "requires": {
+ "to-object-path": "0.3.0"
+ }
+ },
"shebang-command": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz",
@@ -1626,6 +1802,15 @@
"integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
"dev": true
},
+ "source-map-support": {
+ "version": "0.5.4",
+ "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.4.tgz",
+ "integrity": "sha512-PETSPG6BjY1AHs2t64vS2aqAgu6dMIMXJULWFBGbh2Gr8nVLbCFDo6i/RMMvviIQ2h1Z8+5gQhVKSn2je9nmdg==",
+ "dev": true,
+ "requires": {
+ "source-map": "0.6.1"
+ }
+ },
"sourcemap-codec": {
"version": "1.4.1",
"resolved": "https://registry.npmjs.org/sourcemap-codec/-/sourcemap-codec-1.4.1.tgz",
@@ -1727,6 +1912,15 @@
"os-tmpdir": "1.0.2"
}
},
+ "to-object-path": {
+ "version": "0.3.0",
+ "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz",
+ "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=",
+ "dev": true,
+ "requires": {
+ "kind-of": "3.2.2"
+ }
+ },
"type-check": {
"version": "0.3.2",
"resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz",
diff --git a/package.json b/package.json
index 6f19b61..b0647a2 100644
--- a/package.json
+++ b/package.json
@@ -15,19 +15,26 @@
"lib/sequence-diagram.js"
],
"main": "lib/sequence-diagram",
- "module": "source/standalone",
+ "module": "scripts/standalone",
"scripts": {
- "lint": "eslint scripts --ext .js --ignore-pattern '!.eslintrc.js' --ignore-pattern '*FontData.js'",
- "minify": "rollup --config rollup.config.js && uglifyjs --compress --mangle --warn --output lib/sequence-diagram.min.js -- lib/sequence-diagram.js && uglifyjs --compress --mangle --warn --output weblib/editor.min.js -- weblib/editor.js",
- "start": "http-server"
+ "lint": "eslint . --config spec/support/eslintrc.js --ignore-path spec/support/eslintignore --ext .js --ext .mjs",
+ "minify-lib": "rollup --config scripts/rollup.config.js && uglifyjs --compress --mangle --warn --output lib/sequence-diagram.min.js -- lib/sequence-diagram.js",
+ "minify-web": "rollup --config web/rollup.config.js && uglifyjs --compress --mangle --warn --output weblib/editor.min.js -- weblib/editor.js",
+ "minify": "npm run minify-lib && npm run minify-web",
+ "start": "http-server",
+ "test": "npm run unit-test && npm run lint",
+ "unit-test": "rollup --config spec/support/rollup.config.js && node -r source-map-support/register node_modules/.bin/jasmine --config=spec/support/jasmine.json"
},
"devDependencies": {
"eslint": "^4.19.1",
"eslint-plugin-jasmine": "^2.9.3",
"http-server": "^0.10.0",
+ "jasmine": "^3.1.0",
"requirejs": "2.3.5",
"rollup": "^0.57.1",
"rollup-plugin-hypothetical": "^2.1.0",
+ "rollup-plugin-multi-entry": "^2.0.2",
+ "source-map-support": "^0.5.4",
"uglify-es": "^3.1.10"
}
}
diff --git a/readme-images.htm b/readme-images.htm
index a3bea21..012391c 100644
--- a/readme-images.htm
+++ b/readme-images.htm
@@ -19,7 +19,7 @@
-
+
diff --git a/scripts/core/ArrayUtilities.js b/scripts/core/ArrayUtilities.mjs
similarity index 100%
rename from scripts/core/ArrayUtilities.js
rename to scripts/core/ArrayUtilities.mjs
diff --git a/scripts/core/ArrayUtilities_spec.js b/scripts/core/ArrayUtilities_spec.mjs
similarity index 99%
rename from scripts/core/ArrayUtilities_spec.js
rename to scripts/core/ArrayUtilities_spec.mjs
index 7f5bffe..6df91c3 100644
--- a/scripts/core/ArrayUtilities_spec.js
+++ b/scripts/core/ArrayUtilities_spec.mjs
@@ -7,7 +7,7 @@ import {
mergeSets,
remove,
removeAll,
-} from './ArrayUtilities.js';
+} from './ArrayUtilities.mjs';
describe('ArrayUtilities', () => {
function ignoreCase(a, b) {
diff --git a/scripts/core/DOMWrapper.js b/scripts/core/DOMWrapper.mjs
similarity index 100%
rename from scripts/core/DOMWrapper.js
rename to scripts/core/DOMWrapper.mjs
diff --git a/scripts/core/EventObject.js b/scripts/core/EventObject.mjs
similarity index 100%
rename from scripts/core/EventObject.js
rename to scripts/core/EventObject.mjs
diff --git a/scripts/core/EventObject_spec.js b/scripts/core/EventObject_spec.mjs
similarity index 98%
rename from scripts/core/EventObject_spec.js
rename to scripts/core/EventObject_spec.mjs
index 8039d6c..6cf1fca 100644
--- a/scripts/core/EventObject_spec.js
+++ b/scripts/core/EventObject_spec.mjs
@@ -1,4 +1,4 @@
-import EventObject from './EventObject.js';
+import EventObject from './EventObject.mjs';
describe('EventObject', () => {
let o = null;
diff --git a/scripts/core/Random.js b/scripts/core/Random.mjs
similarity index 100%
rename from scripts/core/Random.js
rename to scripts/core/Random.mjs
diff --git a/scripts/core/Random_spec.js b/scripts/core/Random_spec.mjs
similarity index 96%
rename from scripts/core/Random_spec.js
rename to scripts/core/Random_spec.mjs
index 37a2c23..33fcda3 100644
--- a/scripts/core/Random_spec.js
+++ b/scripts/core/Random_spec.mjs
@@ -1,4 +1,4 @@
-import Random from './Random.js';
+import Random from './Random.mjs';
describe('Random', () => {
let random = null;
diff --git a/scripts/core/browser.mjs b/scripts/core/browser.mjs
new file mode 100644
index 0000000..30a821b
--- /dev/null
+++ b/scripts/core/browser.mjs
@@ -0,0 +1,15 @@
+export const nodejs = (typeof window === 'undefined');
+
+export const headless = nodejs;
+
+// Thanks, https://stackoverflow.com/a/23522755/1180785
+export const safari = (
+ !nodejs &&
+ (/^((?!chrome|android).)*safari/i).test(window.navigator.userAgent)
+);
+
+// Thanks, https://stackoverflow.com/a/9851769/1180785
+export const firefox = (
+ !nodejs &&
+ typeof window.InstallTrigger !== 'undefined'
+);
diff --git a/scripts/core/documents/VirtualDocument.js b/scripts/core/documents/VirtualDocument.mjs
similarity index 84%
rename from scripts/core/documents/VirtualDocument.js
rename to scripts/core/documents/VirtualDocument.mjs
index 45026e1..480cb1c 100644
--- a/scripts/core/documents/VirtualDocument.js
+++ b/scripts/core/documents/VirtualDocument.mjs
@@ -104,6 +104,39 @@ class ElementNode {
return false;
}
+ getElementsByTagName(tag) {
+ const result = [];
+ this.traverseDescendants((o) => {
+ if(o.tagName === tag) {
+ result.push(o);
+ }
+ });
+ return result;
+ }
+
+ getElementsByClassName(className) {
+ const result = [];
+ const check = ' ' + className + ' ';
+ this.traverseDescendants((o) => {
+ const cls = ' ' + (o.getAttribute('class') || '') + ' ';
+ if(cls.indexOf(check) !== -1) {
+ result.push(o);
+ }
+ });
+ return result;
+ }
+
+ traverseDescendants(fn) {
+ if(fn(this) === false) {
+ return;
+ }
+ for(const child of this.childNodes) {
+ if(child.traverseDescendants) {
+ child.traverseDescendants(fn);
+ }
+ }
+ }
+
get firstChild() {
return this.childNodes[0] || null;
}
@@ -195,7 +228,7 @@ class ElementNode {
}
}
-export default class VirtualDocument {
+export class VirtualDocument {
createElement(tag) {
return new ElementNode(this, tag, '');
}
@@ -208,3 +241,9 @@ export default class VirtualDocument {
return new TextNode(content);
}
}
+
+export class Event {
+ constructor(type) {
+ this.type = type;
+ }
+}
diff --git a/scripts/core/documents/VirtualDocument_spec.js b/scripts/core/documents/VirtualDocument_spec.mjs
similarity index 99%
rename from scripts/core/documents/VirtualDocument_spec.js
rename to scripts/core/documents/VirtualDocument_spec.mjs
index a9919a9..9d6940b 100644
--- a/scripts/core/documents/VirtualDocument_spec.js
+++ b/scripts/core/documents/VirtualDocument_spec.mjs
@@ -1,4 +1,4 @@
-import VirtualDocument from './VirtualDocument.js';
+import {Event, VirtualDocument} from './VirtualDocument.mjs';
describe('VirtualDocument', () => {
const doc = new VirtualDocument();
diff --git a/scripts/image/Blur.js b/scripts/image/Blur.mjs
similarity index 96%
rename from scripts/image/Blur.js
rename to scripts/image/Blur.mjs
index dc067bf..f40fd1d 100644
--- a/scripts/image/Blur.js
+++ b/scripts/image/Blur.mjs
@@ -1,4 +1,4 @@
-import ImageRegion from './ImageRegion.js';
+import ImageRegion from './ImageRegion.mjs';
export function makeGaussianKernel(size) {
const sz = Math.ceil(size * 3);
diff --git a/scripts/image/Blur_spec.js b/scripts/image/Blur_spec.mjs
similarity index 96%
rename from scripts/image/Blur_spec.js
rename to scripts/image/Blur_spec.mjs
index 72cdff6..1b5d262 100644
--- a/scripts/image/Blur_spec.js
+++ b/scripts/image/Blur_spec.mjs
@@ -1,5 +1,5 @@
-import ImageRegion from './ImageRegion.js';
-import {blur2D} from './Blur.js';
+import ImageRegion from './ImageRegion.mjs';
+import {blur2D} from './Blur.mjs';
describe('Blur', () => {
const PRECISION = 0.01;
diff --git a/scripts/image/Composition.js b/scripts/image/Composition.mjs
similarity index 95%
rename from scripts/image/Composition.js
rename to scripts/image/Composition.mjs
index 87d3dab..c35c643 100644
--- a/scripts/image/Composition.js
+++ b/scripts/image/Composition.mjs
@@ -1,4 +1,4 @@
-import ImageRegion from './ImageRegion.js';
+import ImageRegion from './ImageRegion.mjs';
function compose(input1, input2, fn, {target = null} = {}) {
input1.checkCompatible(input2);
diff --git a/scripts/image/Composition_spec.js b/scripts/image/Composition_spec.mjs
similarity index 95%
rename from scripts/image/Composition_spec.js
rename to scripts/image/Composition_spec.mjs
index e5bb9aa..202aaf4 100644
--- a/scripts/image/Composition_spec.js
+++ b/scripts/image/Composition_spec.mjs
@@ -1,5 +1,5 @@
-import ImageRegion from './ImageRegion.js';
-import {subtract} from './Composition.js';
+import ImageRegion from './ImageRegion.mjs';
+import {subtract} from './Composition.mjs';
describe('Composition', () => {
let inputA = null;
diff --git a/scripts/image/ImageRegion.js b/scripts/image/ImageRegion.mjs
similarity index 100%
rename from scripts/image/ImageRegion.js
rename to scripts/image/ImageRegion.mjs
diff --git a/scripts/image/ImageRegion_spec.js b/scripts/image/ImageRegion_spec.mjs
similarity index 97%
rename from scripts/image/ImageRegion_spec.js
rename to scripts/image/ImageRegion_spec.mjs
index 7482f58..a62d93c 100644
--- a/scripts/image/ImageRegion_spec.js
+++ b/scripts/image/ImageRegion_spec.mjs
@@ -1,9 +1,13 @@
/* eslint-disable max-statements */
-import ImageRegion from './ImageRegion.js';
+import ImageRegion from './ImageRegion.mjs';
+import {nodejs} from '../core/browser.mjs';
describe('ImageRegion', () => {
function makeCanvas(w, h) {
+ if(nodejs) {
+ return pending('No canvas support in NodeJS');
+ }
const canvas = document.createElement('canvas');
canvas.width = w;
canvas.height = h;
diff --git a/scripts/image/ImageSimilarity.js b/scripts/image/ImageSimilarity.mjs
similarity index 74%
rename from scripts/image/ImageSimilarity.js
rename to scripts/image/ImageSimilarity.mjs
index 3215edc..40ff3f0 100644
--- a/scripts/image/ImageSimilarity.js
+++ b/scripts/image/ImageSimilarity.mjs
@@ -1,6 +1,7 @@
-import './Blur.js';
-import './Composition.js';
-import ImageRegion from './ImageRegion.js';
+import './Blur.mjs';
+import './Composition.mjs';
+import ImageRegion from './ImageRegion.mjs';
+import {headless} from '../core/browser.mjs';
function getThresholds({
pixelThresh = 2,
@@ -74,20 +75,22 @@ export const matchers = {
return {pass: true};
}
- document.body.appendChild(makeImageComparison(
- actual,
- expected,
- options,
- 'Image comparison (expected similar)'
- ));
-
- const details = (options.details ?
+ let message = 'Expected images to be similar';
+ if(!headless) {
+ document.body.appendChild(makeImageComparison(
+ actual,
+ expected,
+ options,
+ 'Image comparison (expected similar)'
+ ));
+ message += ' (see below for comparison)';
+ }
+ message += '.' + (options.details ?
' Details: ' + options.details : ''
);
return {
- message: 'Expected images to be similar ' +
- '(see below for comparison).' + details,
+ message,
pass: false,
};
},
@@ -97,20 +100,22 @@ export const matchers = {
return {pass: true};
}
- document.body.appendChild(makeImageComparison(
- actual,
- expected,
- options,
- 'Image comparison (expected different)'
- ));
-
- const details = (options.details ?
+ let message = 'Expected images to differ';
+ if(!headless) {
+ document.body.appendChild(makeImageComparison(
+ actual,
+ expected,
+ options,
+ 'Image comparison (expected different)'
+ ));
+ message += ' (see below for comparison)';
+ }
+ message += '.' + (options.details ?
' Details: ' + options.details : ''
);
return {
- message: 'Expected images to differ ' +
- '(see below for comparison).' + details,
+ message,
pass: false,
};
},
diff --git a/scripts/image/ImageSimilarity_spec.js b/scripts/image/ImageSimilarity_spec.mjs
similarity index 92%
rename from scripts/image/ImageSimilarity_spec.js
rename to scripts/image/ImageSimilarity_spec.mjs
index 424cab6..dd1b10b 100644
--- a/scripts/image/ImageSimilarity_spec.js
+++ b/scripts/image/ImageSimilarity_spec.mjs
@@ -1,5 +1,5 @@
-import {isSimilar, matchers} from './ImageSimilarity.js';
-import ImageRegion from './ImageRegion.js';
+import {isSimilar, matchers} from './ImageSimilarity.mjs';
+import ImageRegion from './ImageRegion.mjs';
describe('ImageSimilarity', () => {
let inputA = null;
diff --git a/scripts/interface/ComponentsLibrary_spec.js b/scripts/interface/ComponentsLibrary_spec.js
deleted file mode 100644
index adf6839..0000000
--- a/scripts/interface/ComponentsLibrary_spec.js
+++ /dev/null
@@ -1,26 +0,0 @@
-import ComponentsLibrary from './ComponentsLibrary.js';
-import SequenceDiagram from '../sequence/SequenceDiagram.js';
-
-const themes = new SequenceDiagram().getThemeNames().slice(1);
-
-function checkSample(src) {
- it('renders without error', () => {
- expect(() => new SequenceDiagram(src)).not.toThrow();
- });
-
- themes.forEach((themeName) => {
- it('renders without error in ' + themeName + ' theme', () => {
- expect(() => new SequenceDiagram(
- 'theme ' + themeName + '\n' + src
- )).not.toThrow();
- });
- });
-}
-
-describe('Components Library', () => {
- ComponentsLibrary.forEach(({title, code, preview}) => {
- describe(title, () => {
- checkSample(preview || code);
- });
- });
-});
diff --git a/scripts/jasmineConfig.js b/scripts/jasmineConfig.js
deleted file mode 100644
index e10bd30..0000000
--- a/scripts/jasmineConfig.js
+++ /dev/null
@@ -1,31 +0,0 @@
-// Jasmine test configuration.
-// See specs.js for the list of spec files
-
-jasmine.executeAllTests = window.onload;
-window.onload = null;
-
-const matchers = {
- toBeNear: () => ({
- compare: (actual, expected, range) => {
- if(
- typeof expected !== 'number' ||
- typeof range !== 'number' ||
- range < 0
- ) {
- throw new Error(
- 'Invalid toBeNear(' + expected + ',' + range + ')'
- );
- }
- if(typeof actual !== 'number') {
- throw new Error('Expected a number, got ' + actual);
- }
- return {
- pass: Math.abs(actual - expected) <= range,
- };
- },
- }),
-};
-
-beforeAll(() => {
- jasmine.addMatchers(matchers);
-});
diff --git a/scripts/rollup.config.js b/scripts/rollup.config.js
new file mode 100644
index 0000000..f1c4cdd
--- /dev/null
+++ b/scripts/rollup.config.js
@@ -0,0 +1,10 @@
+export default [
+ {
+ input: 'scripts/standalone.mjs',
+ output: {
+ file: 'lib/sequence-diagram.js',
+ format: 'iife',
+ name: 'SequenceDiagram',
+ },
+ },
+];
diff --git a/scripts/sequence/CodeMirrorHints.js b/scripts/sequence/CodeMirrorHints.mjs
similarity index 98%
rename from scripts/sequence/CodeMirrorHints.js
rename to scripts/sequence/CodeMirrorHints.mjs
index dab2820..6a17d15 100644
--- a/scripts/sequence/CodeMirrorHints.js
+++ b/scripts/sequence/CodeMirrorHints.mjs
@@ -1,6 +1,6 @@
/* eslint-disable complexity */ // Temporary ignore while switching linter
-import {last, mergeSets} from '../core/ArrayUtilities.js';
+import {last, mergeSets} from '../core/ArrayUtilities.mjs';
const TRIMMER = /^([ \t]*)(.*)$/;
const SQUASH = {
diff --git a/scripts/sequence/CodeMirrorMode.js b/scripts/sequence/CodeMirrorMode.mjs
similarity index 99%
rename from scripts/sequence/CodeMirrorMode.js
rename to scripts/sequence/CodeMirrorMode.mjs
index 6326816..c6972c9 100644
--- a/scripts/sequence/CodeMirrorMode.js
+++ b/scripts/sequence/CodeMirrorMode.mjs
@@ -2,7 +2,7 @@
/* eslint-disable sort-keys */ // Maybe later
/* eslint-disable complexity */ // Temporary ignore while switching linter
-import {flatMap, last, mergeSets} from '../core/ArrayUtilities.js';
+import {flatMap, last, mergeSets} from '../core/ArrayUtilities.mjs';
const CM_ERROR = {type: 'error line-error', suggest: false, then: {'': 0}};
diff --git a/scripts/sequence/CodeMirrorMode_spec.js b/scripts/sequence/CodeMirrorMode_webspec.mjs
similarity index 99%
rename from scripts/sequence/CodeMirrorMode_spec.js
rename to scripts/sequence/CodeMirrorMode_webspec.mjs
index 3acc7e1..47b2b75 100644
--- a/scripts/sequence/CodeMirrorMode_spec.js
+++ b/scripts/sequence/CodeMirrorMode_webspec.mjs
@@ -2,7 +2,7 @@
/* eslint-disable max-statements */
/* eslint-disable sort-keys */ // Maybe later
-import SequenceDiagram from './SequenceDiagram.js';
+import SequenceDiagram from './SequenceDiagram.mjs';
const CM = window.CodeMirror;
diff --git a/scripts/sequence/Exporter.js b/scripts/sequence/Exporter.mjs
similarity index 95%
rename from scripts/sequence/Exporter.js
rename to scripts/sequence/Exporter.mjs
index 606c152..8b46bdd 100644
--- a/scripts/sequence/Exporter.js
+++ b/scripts/sequence/Exporter.mjs
@@ -1,5 +1,4 @@
-// Thanks, https://stackoverflow.com/a/23522755/1180785
-const safari = (/^((?!chrome|android).)*safari/i).test(navigator.userAgent);
+import {safari} from '../core/browser.mjs';
export default class Exporter {
constructor() {
diff --git a/scripts/sequence/Generator.js b/scripts/sequence/Generator.mjs
similarity index 99%
rename from scripts/sequence/Generator.js
rename to scripts/sequence/Generator.mjs
index d7f9102..9696c2c 100644
--- a/scripts/sequence/Generator.js
+++ b/scripts/sequence/Generator.mjs
@@ -10,7 +10,7 @@ import {
mergeSets,
remove,
removeAll,
-} from '../core/ArrayUtilities.js';
+} from '../core/ArrayUtilities.mjs';
class AgentState {
constructor({
diff --git a/scripts/sequence/Generator_spec.js b/scripts/sequence/Generator_spec.mjs
similarity index 99%
rename from scripts/sequence/Generator_spec.js
rename to scripts/sequence/Generator_spec.mjs
index 3cfe296..6e69c91 100644
--- a/scripts/sequence/Generator_spec.js
+++ b/scripts/sequence/Generator_spec.mjs
@@ -2,7 +2,7 @@
/* eslint-disable max-statements */
/* eslint-disable sort-keys */ // Maybe later
-import Generator from './Generator.js';
+import Generator from './Generator.mjs';
describe('Sequence Generator', () => {
const generator = new Generator();
diff --git a/scripts/sequence/LabelPatternParser.js b/scripts/sequence/LabelPatternParser.mjs
similarity index 100%
rename from scripts/sequence/LabelPatternParser.js
rename to scripts/sequence/LabelPatternParser.mjs
diff --git a/scripts/sequence/LabelPatternParser_spec.js b/scripts/sequence/LabelPatternParser_spec.mjs
similarity index 97%
rename from scripts/sequence/LabelPatternParser_spec.js
rename to scripts/sequence/LabelPatternParser_spec.mjs
index 7236d01..51d2d73 100644
--- a/scripts/sequence/LabelPatternParser_spec.js
+++ b/scripts/sequence/LabelPatternParser_spec.mjs
@@ -1,4 +1,4 @@
-import parser from './LabelPatternParser.js';
+import parser from './LabelPatternParser.mjs';
describe('Label Pattern Parser', () => {
it('converts simple text', () => {
diff --git a/scripts/sequence/MarkdownParser.js b/scripts/sequence/MarkdownParser.mjs
similarity index 100%
rename from scripts/sequence/MarkdownParser.js
rename to scripts/sequence/MarkdownParser.mjs
diff --git a/scripts/sequence/MarkdownParser_spec.js b/scripts/sequence/MarkdownParser_spec.mjs
similarity index 96%
rename from scripts/sequence/MarkdownParser_spec.js
rename to scripts/sequence/MarkdownParser_spec.mjs
index d10d8ab..2bf9cda 100644
--- a/scripts/sequence/MarkdownParser_spec.js
+++ b/scripts/sequence/MarkdownParser_spec.mjs
@@ -1,8 +1,8 @@
/* eslint-disable sort-keys */ // Maybe later
-import {dom, textSizerFactory} from '../stubs/TestDOM.js';
-import SVG from '../svg/SVG.js';
-import parser from './MarkdownParser.js';
+import {dom, textSizerFactory} from '../../spec/stubs/TestDOM.mjs';
+import SVG from '../svg/SVG.mjs';
+import parser from './MarkdownParser.mjs';
describe('Markdown Parser', () => {
it('converts simple text', () => {
diff --git a/scripts/sequence/Parser.js b/scripts/sequence/Parser.mjs
similarity index 98%
rename from scripts/sequence/Parser.js
rename to scripts/sequence/Parser.mjs
index e443026..28bb511 100644
--- a/scripts/sequence/Parser.js
+++ b/scripts/sequence/Parser.mjs
@@ -3,10 +3,10 @@
/* eslint-disable complexity */ // Temporary ignore while switching linter
/* eslint-disable no-param-reassign */ // Also temporary
-import {combine, last} from '../core/ArrayUtilities.js';
-import Tokeniser from './Tokeniser.js';
-import labelPatternParser from './LabelPatternParser.js';
-import markdownParser from './MarkdownParser.js';
+import {combine, last} from '../core/ArrayUtilities.mjs';
+import Tokeniser from './Tokeniser.mjs';
+import labelPatternParser from './LabelPatternParser.mjs';
+import markdownParser from './MarkdownParser.mjs';
const BLOCK_TYPES = {
'if': {
diff --git a/scripts/sequence/Parser_spec.js b/scripts/sequence/Parser_spec.mjs
similarity index 99%
rename from scripts/sequence/Parser_spec.js
rename to scripts/sequence/Parser_spec.mjs
index 581867c..829d2d6 100644
--- a/scripts/sequence/Parser_spec.js
+++ b/scripts/sequence/Parser_spec.mjs
@@ -2,7 +2,7 @@
/* eslint-disable max-statements */
/* eslint-disable sort-keys */ // Maybe later
-import Parser from './Parser.js';
+import Parser from './Parser.mjs';
describe('Sequence Parser', () => {
const parser = new Parser();
diff --git a/scripts/sequence/Readme_spec.js b/scripts/sequence/Readme_webspec.mjs
similarity index 90%
rename from scripts/sequence/Readme_spec.js
rename to scripts/sequence/Readme_webspec.mjs
index 025bf98..c7009f9 100644
--- a/scripts/sequence/Readme_spec.js
+++ b/scripts/sequence/Readme_webspec.mjs
@@ -1,6 +1,6 @@
-import ImageRegion from '../image/ImageRegion.js';
-import SequenceDiagram from './SequenceDiagram.js';
-import {matchers} from '../image/ImageSimilarity.js';
+import ImageRegion from '../image/ImageRegion.mjs';
+import SequenceDiagram from './SequenceDiagram.mjs';
+import {matchers} from '../image/ImageSimilarity.mjs';
const RESOLUTION = 4;
diff --git a/scripts/sequence/Renderer.js b/scripts/sequence/Renderer.mjs
similarity index 97%
rename from scripts/sequence/Renderer.js
rename to scripts/sequence/Renderer.mjs
index 21e6fdb..0697e6b 100644
--- a/scripts/sequence/Renderer.js
+++ b/scripts/sequence/Renderer.mjs
@@ -1,21 +1,21 @@
/* eslint-disable max-lines */
-import './components/AgentCap.js';
-import './components/AgentHighlight.js';
-import './components/Block.js';
-import './components/Connect.js';
-import './components/Divider.js';
-import './components/Marker.js';
-import './components/Note.js';
-import './components/Parallel.js';
+import './components/AgentCap.mjs';
+import './components/AgentHighlight.mjs';
+import './components/Block.mjs';
+import './components/Connect.mjs';
+import './components/Divider.mjs';
+import './components/Marker.mjs';
+import './components/Note.mjs';
+import './components/Parallel.mjs';
import {
cleanRenderPreResult,
getComponents,
-} from './components/BaseComponent.js';
-import DOMWrapper from '../core/DOMWrapper.js';
-import EventObject from '../core/EventObject.js';
-import SVG from '../svg/SVG.js';
-import {mergeSets} from '../core/ArrayUtilities.js';
+} from './components/BaseComponent.mjs';
+import DOMWrapper from '../core/DOMWrapper.mjs';
+import EventObject from '../core/EventObject.mjs';
+import SVG from '../svg/SVG.mjs';
+import {mergeSets} from '../core/ArrayUtilities.mjs';
function findExtremes(agentInfos, agentIDs) {
let min = null;
diff --git a/scripts/sequence/Renderer_spec.js b/scripts/sequence/Renderer_spec.mjs
similarity index 96%
rename from scripts/sequence/Renderer_spec.js
rename to scripts/sequence/Renderer_spec.mjs
index 89f7758..d040f3c 100644
--- a/scripts/sequence/Renderer_spec.js
+++ b/scripts/sequence/Renderer_spec.mjs
@@ -1,21 +1,18 @@
/* eslint-disable sort-keys */ // Maybe later
-import {Factory as BasicThemeFactory} from './themes/Basic.js';
-import Renderer from './Renderer.js';
+import {VirtualDocument, textSizerFactory} from '../../spec/stubs/TestDOM.mjs';
+import {Factory as BasicThemeFactory} from './themes/Basic.mjs';
+import Renderer from './Renderer.mjs';
describe('Sequence Renderer', () => {
let renderer = null;
beforeEach(() => {
renderer = new Renderer({
+ document: new VirtualDocument(),
themes: [new BasicThemeFactory()],
- document: window.document,
+ textSizerFactory,
});
- document.body.appendChild(renderer.dom());
- });
-
- afterEach(() => {
- document.body.removeChild(renderer.dom());
});
describe('.dom', () => {
diff --git a/scripts/sequence/SequenceDiagram.js b/scripts/sequence/SequenceDiagram.mjs
similarity index 93%
rename from scripts/sequence/SequenceDiagram.js
rename to scripts/sequence/SequenceDiagram.mjs
index 098c42b..e1ecf30 100644
--- a/scripts/sequence/SequenceDiagram.js
+++ b/scripts/sequence/SequenceDiagram.mjs
@@ -1,13 +1,13 @@
-import {Factory as BasicThemeFactory} from './themes/Basic.js';
-import {Factory as ChunkyThemeFactory} from './themes/Chunky.js';
-import EventObject from '../core/EventObject.js';
-import Exporter from './Exporter.js';
-import Generator from './Generator.js';
-import {Factory as MonospaceThemeFactory} from './themes/Monospace.js';
-import Parser from './Parser.js';
-import Renderer from './Renderer.js';
-import {Factory as SketchThemeFactory} from './themes/Sketch.js';
-import {getHints} from './CodeMirrorHints.js';
+import {Factory as BasicThemeFactory} from './themes/Basic.mjs';
+import {Factory as ChunkyThemeFactory} from './themes/Chunky.mjs';
+import EventObject from '../core/EventObject.mjs';
+import Exporter from './Exporter.mjs';
+import Generator from './Generator.mjs';
+import {Factory as MonospaceThemeFactory} from './themes/Monospace.mjs';
+import Parser from './Parser.mjs';
+import Renderer from './Renderer.mjs';
+import {Factory as SketchThemeFactory} from './themes/Sketch.mjs';
+import {getHints} from './CodeMirrorHints.mjs';
const themes = [
new BasicThemeFactory(),
@@ -65,7 +65,9 @@ function renderAll(diagrams) {
function pickDocument(container) {
if(container) {
- return container.ownerDocument;
+ return container.ownerDocument || null;
+ } else if(typeof window === 'undefined') {
+ return null;
} else {
return window.document;
}
@@ -442,6 +444,10 @@ function convertAll(root = null, className = 'sequence-diagram') {
convert(els);
}
+function getDefaultThemeNames() {
+ return themes.map((theme) => theme.name);
+}
+
Object.assign(SequenceDiagram, {
Exporter,
Generator,
@@ -451,6 +457,7 @@ Object.assign(SequenceDiagram, {
convert,
convertAll,
extractCodeFromSVG,
+ getDefaultThemeNames,
registerCodeMirrorMode,
renderAll,
themes,
diff --git a/scripts/sequence/SequenceDiagram_spec.js b/scripts/sequence/SequenceDiagram_spec.mjs
similarity index 89%
rename from scripts/sequence/SequenceDiagram_spec.js
rename to scripts/sequence/SequenceDiagram_spec.mjs
index 90f4f90..8a75282 100644
--- a/scripts/sequence/SequenceDiagram_spec.js
+++ b/scripts/sequence/SequenceDiagram_spec.mjs
@@ -1,9 +1,10 @@
-import Exporter from './Exporter.js';
-import Generator from './Generator.js';
-import Parser from './Parser.js';
-import Renderer from './Renderer.js';
-import SequenceDiagram from './SequenceDiagram.js';
-import {textSizerFactory} from '../stubs/TestDOM.js';
+import {VirtualDocument, textSizerFactory} from '../../spec/stubs/TestDOM.mjs';
+import Exporter from './Exporter.mjs';
+import Generator from './Generator.mjs';
+import Parser from './Parser.mjs';
+import Renderer from './Renderer.mjs';
+import SequenceDiagram from './SequenceDiagram.mjs';
+import {nodejs} from '../core/browser.mjs';
describe('SequenceDiagram', () => {
function getSimplifiedContent(d) {
@@ -18,6 +19,7 @@ describe('SequenceDiagram', () => {
beforeEach(() => {
diagram = new SequenceDiagram({
+ document: new VirtualDocument(),
namespace: '',
textSizerFactory,
});
@@ -167,6 +169,11 @@ describe('SequenceDiagram', () => {
});
it('measures OS fonts correctly on the first render', (done) => {
+ if(nodejs) {
+ pending('NodeJS font rendering not implemented yet');
+ return;
+ }
+
const code = 'title message';
const sd = new SequenceDiagram(code);
const widthImmediate = sd.getSize().width;
@@ -187,6 +194,11 @@ describe('SequenceDiagram', () => {
});
it('measures embedded fonts correctly on the first render', (done) => {
+ if(nodejs) {
+ pending('NodeJS font rendering not implemented yet');
+ return;
+ }
+
const code = 'theme sketch\ntitle message';
const sd = new SequenceDiagram(code);
const widthImmediate = sd.getSize().width;
diff --git a/scripts/sequence/SequenceDiagram_visual_spec.js b/scripts/sequence/SequenceDiagram_visual_webspec.mjs
similarity index 85%
rename from scripts/sequence/SequenceDiagram_visual_spec.js
rename to scripts/sequence/SequenceDiagram_visual_webspec.mjs
index 09aeee1..2ee2b37 100644
--- a/scripts/sequence/SequenceDiagram_visual_spec.js
+++ b/scripts/sequence/SequenceDiagram_visual_webspec.mjs
@@ -1,12 +1,12 @@
-import ImageRegion from '../image/ImageRegion.js';
-import SequenceDiagram from './SequenceDiagram.js';
-import TESTS from './test-images/list.js';
-import {matchers} from '../image/ImageSimilarity.js';
+import ImageRegion from '../image/ImageRegion.mjs';
+import SequenceDiagram from './SequenceDiagram.mjs';
+import TESTS from '../../spec/images/list.mjs';
+import {matchers} from '../image/ImageSimilarity.mjs';
describe('SequenceDiagram Visuals', () => {
const RESOLUTION = 4;
- const IMAGE_BASE_PATH = 'scripts/sequence/test-images/';
+ const IMAGE_BASE_PATH = 'spec/images/';
const COLLAPSE_REGEX = new RegExp(/# collapse/g);
diff --git a/scripts/sequence/Tokeniser.js b/scripts/sequence/Tokeniser.mjs
similarity index 98%
rename from scripts/sequence/Tokeniser.js
rename to scripts/sequence/Tokeniser.mjs
index ea3d1cb..e65513c 100644
--- a/scripts/sequence/Tokeniser.js
+++ b/scripts/sequence/Tokeniser.mjs
@@ -1,4 +1,4 @@
-import CMMode from './CodeMirrorMode.js';
+import CMMode from './CodeMirrorMode.mjs';
function execAt(str, reg, i) {
reg.lastIndex = i;
diff --git a/scripts/sequence/Tokeniser_spec.js b/scripts/sequence/Tokeniser_spec.mjs
similarity index 99%
rename from scripts/sequence/Tokeniser_spec.js
rename to scripts/sequence/Tokeniser_spec.mjs
index 0ea746e..4dbaaca 100644
--- a/scripts/sequence/Tokeniser_spec.js
+++ b/scripts/sequence/Tokeniser_spec.mjs
@@ -1,4 +1,4 @@
-import Tokeniser from './Tokeniser.js';
+import Tokeniser from './Tokeniser.mjs';
describe('Sequence Tokeniser', () => {
const tokeniser = new Tokeniser();
diff --git a/scripts/sequence/components/AgentCap.js b/scripts/sequence/components/AgentCap.mjs
similarity index 98%
rename from scripts/sequence/components/AgentCap.js
rename to scripts/sequence/components/AgentCap.mjs
index b36569e..6c158f5 100644
--- a/scripts/sequence/components/AgentCap.js
+++ b/scripts/sequence/components/AgentCap.mjs
@@ -1,5 +1,5 @@
-import BaseComponent, {register} from './BaseComponent.js';
-import {mergeSets, removeAll} from '../../core/ArrayUtilities.js';
+import BaseComponent, {register} from './BaseComponent.mjs';
+import {mergeSets, removeAll} from '../../core/ArrayUtilities.mjs';
const OUTLINE_ATTRS = {
'class': 'outline',
diff --git a/scripts/sequence/components/AgentCap_spec.js b/scripts/sequence/components/AgentCap_spec.mjs
similarity index 75%
rename from scripts/sequence/components/AgentCap_spec.js
rename to scripts/sequence/components/AgentCap_spec.mjs
index 5e42bc1..238e19b 100644
--- a/scripts/sequence/components/AgentCap_spec.js
+++ b/scripts/sequence/components/AgentCap_spec.mjs
@@ -1,5 +1,5 @@
-import AgentCap from './AgentCap.js';
-import {getComponents} from './BaseComponent.js';
+import AgentCap from './AgentCap.mjs';
+import {getComponents} from './BaseComponent.mjs';
describe('AgentCap', () => {
it('registers itself with the component store', () => {
diff --git a/scripts/sequence/components/AgentHighlight.js b/scripts/sequence/components/AgentHighlight.mjs
similarity index 94%
rename from scripts/sequence/components/AgentHighlight.js
rename to scripts/sequence/components/AgentHighlight.mjs
index d81510a..ef5cf59 100644
--- a/scripts/sequence/components/AgentHighlight.js
+++ b/scripts/sequence/components/AgentHighlight.mjs
@@ -1,4 +1,4 @@
-import BaseComponent, {register} from './BaseComponent.js';
+import BaseComponent, {register} from './BaseComponent.mjs';
export default class AgentHighlight extends BaseComponent {
radius(highlighted, env) {
diff --git a/scripts/sequence/components/AgentHighlight_spec.js b/scripts/sequence/components/AgentHighlight_spec.mjs
similarity index 93%
rename from scripts/sequence/components/AgentHighlight_spec.js
rename to scripts/sequence/components/AgentHighlight_spec.mjs
index 69dba27..cc9ea9b 100644
--- a/scripts/sequence/components/AgentHighlight_spec.js
+++ b/scripts/sequence/components/AgentHighlight_spec.mjs
@@ -1,5 +1,5 @@
-import AgentHighlight from './AgentHighlight.js';
-import {getComponents} from './BaseComponent.js';
+import AgentHighlight from './AgentHighlight.mjs';
+import {getComponents} from './BaseComponent.mjs';
describe('AgentHighlight', () => {
const highlight = new AgentHighlight();
diff --git a/scripts/sequence/components/BaseComponent.js b/scripts/sequence/components/BaseComponent.mjs
similarity index 100%
rename from scripts/sequence/components/BaseComponent.js
rename to scripts/sequence/components/BaseComponent.mjs
diff --git a/scripts/sequence/components/Block.js b/scripts/sequence/components/Block.mjs
similarity index 97%
rename from scripts/sequence/components/Block.js
rename to scripts/sequence/components/Block.mjs
index f5697ee..a1795da 100644
--- a/scripts/sequence/components/Block.js
+++ b/scripts/sequence/components/Block.mjs
@@ -1,5 +1,5 @@
-import BaseComponent, {register} from './BaseComponent.js';
-import {mergeSets, removeAll} from '../../core/ArrayUtilities.js';
+import BaseComponent, {register} from './BaseComponent.mjs';
+import {mergeSets, removeAll} from '../../core/ArrayUtilities.mjs';
const OUTLINE_ATTRS = {
'class': 'outline',
diff --git a/scripts/sequence/components/Block_spec.js b/scripts/sequence/components/Block_spec.mjs
similarity index 75%
rename from scripts/sequence/components/Block_spec.js
rename to scripts/sequence/components/Block_spec.mjs
index 1f36c95..e556cb7 100644
--- a/scripts/sequence/components/Block_spec.js
+++ b/scripts/sequence/components/Block_spec.mjs
@@ -1,5 +1,5 @@
-import {BlockBegin, BlockEnd, BlockSplit} from './Block.js';
-import {getComponents} from './BaseComponent.js';
+import {BlockBegin, BlockEnd, BlockSplit} from './Block.mjs';
+import {getComponents} from './BaseComponent.mjs';
describe('Block', () => {
it('registers itself with the component store', () => {
diff --git a/scripts/sequence/components/Connect.js b/scripts/sequence/components/Connect.mjs
similarity index 99%
rename from scripts/sequence/components/Connect.js
rename to scripts/sequence/components/Connect.mjs
index d546f5f..e83e1a3 100644
--- a/scripts/sequence/components/Connect.js
+++ b/scripts/sequence/components/Connect.mjs
@@ -1,7 +1,7 @@
/* eslint-disable sort-keys */ // Maybe later
-import BaseComponent, {register} from './BaseComponent.js';
-import {mergeSets} from '../../core/ArrayUtilities.js';
+import BaseComponent, {register} from './BaseComponent.mjs';
+import {mergeSets} from '../../core/ArrayUtilities.mjs';
const OUTLINE_ATTRS = {
'class': 'outline',
diff --git a/scripts/sequence/components/Connect_spec.js b/scripts/sequence/components/Connect_spec.mjs
similarity index 87%
rename from scripts/sequence/components/Connect_spec.js
rename to scripts/sequence/components/Connect_spec.mjs
index bf9bfef..96ea19d 100644
--- a/scripts/sequence/components/Connect_spec.js
+++ b/scripts/sequence/components/Connect_spec.mjs
@@ -1,5 +1,5 @@
-import {Connect, ConnectDelayBegin, ConnectDelayEnd} from './Connect.js';
-import {getComponents} from './BaseComponent.js';
+import {Connect, ConnectDelayBegin, ConnectDelayEnd} from './Connect.mjs';
+import {getComponents} from './BaseComponent.mjs';
describe('Connect', () => {
it('registers itself with the component store', () => {
diff --git a/scripts/sequence/components/Divider.js b/scripts/sequence/components/Divider.mjs
similarity index 97%
rename from scripts/sequence/components/Divider.js
rename to scripts/sequence/components/Divider.mjs
index a745667..f6d9fdb 100644
--- a/scripts/sequence/components/Divider.js
+++ b/scripts/sequence/components/Divider.mjs
@@ -1,4 +1,4 @@
-import BaseComponent, {register} from './BaseComponent.js';
+import BaseComponent, {register} from './BaseComponent.mjs';
const OUTLINE_ATTRS = {
'class': 'outline',
diff --git a/scripts/sequence/components/Divider_spec.js b/scripts/sequence/components/Divider_spec.mjs
similarity index 73%
rename from scripts/sequence/components/Divider_spec.js
rename to scripts/sequence/components/Divider_spec.mjs
index ecd9d78..63fcd3d 100644
--- a/scripts/sequence/components/Divider_spec.js
+++ b/scripts/sequence/components/Divider_spec.mjs
@@ -1,5 +1,5 @@
-import Divider from './Divider.js';
-import {getComponents} from './BaseComponent.js';
+import Divider from './Divider.mjs';
+import {getComponents} from './BaseComponent.mjs';
describe('Divider', () => {
describe('Divider', () => {
diff --git a/scripts/sequence/components/Marker.js b/scripts/sequence/components/Marker.mjs
similarity index 89%
rename from scripts/sequence/components/Marker.js
rename to scripts/sequence/components/Marker.mjs
index d9e8ace..bc073ab 100644
--- a/scripts/sequence/components/Marker.js
+++ b/scripts/sequence/components/Marker.mjs
@@ -1,4 +1,4 @@
-import BaseComponent, {register} from './BaseComponent.js';
+import BaseComponent, {register} from './BaseComponent.mjs';
export class Mark extends BaseComponent {
makeState(state) {
diff --git a/scripts/sequence/components/Marker_spec.js b/scripts/sequence/components/Marker_spec.mjs
similarity index 93%
rename from scripts/sequence/components/Marker_spec.js
rename to scripts/sequence/components/Marker_spec.mjs
index faedc08..9fa5b0b 100644
--- a/scripts/sequence/components/Marker_spec.js
+++ b/scripts/sequence/components/Marker_spec.mjs
@@ -1,5 +1,5 @@
-import {Async, Mark} from './Marker.js';
-import {getComponents} from './BaseComponent.js';
+import {Async, Mark} from './Marker.mjs';
+import {getComponents} from './BaseComponent.mjs';
const mark = new Mark();
const async = new Async();
diff --git a/scripts/sequence/components/Note.js b/scripts/sequence/components/Note.mjs
similarity index 98%
rename from scripts/sequence/components/Note.js
rename to scripts/sequence/components/Note.mjs
index de6f2b0..5608897 100644
--- a/scripts/sequence/components/Note.js
+++ b/scripts/sequence/components/Note.mjs
@@ -1,7 +1,7 @@
/* eslint-disable complexity */ // Temporary ignore while switching linter
/* eslint-disable no-param-reassign */ // Also temporary
-import BaseComponent, {register} from './BaseComponent.js';
+import BaseComponent, {register} from './BaseComponent.mjs';
const OUTLINE_ATTRS = {
'class': 'outline',
diff --git a/scripts/sequence/components/Note_spec.js b/scripts/sequence/components/Note_spec.mjs
similarity index 86%
rename from scripts/sequence/components/Note_spec.js
rename to scripts/sequence/components/Note_spec.mjs
index 700f637..bc96705 100644
--- a/scripts/sequence/components/Note_spec.js
+++ b/scripts/sequence/components/Note_spec.mjs
@@ -1,5 +1,5 @@
-import {NoteBetween, NoteOver, NoteSide} from './Note.js';
-import {getComponents} from './BaseComponent.js';
+import {NoteBetween, NoteOver, NoteSide} from './Note.mjs';
+import {getComponents} from './BaseComponent.mjs';
describe('NoteOver', () => {
it('registers itself with the component store', () => {
diff --git a/scripts/sequence/components/Parallel.js b/scripts/sequence/components/Parallel.mjs
similarity index 96%
rename from scripts/sequence/components/Parallel.js
rename to scripts/sequence/components/Parallel.mjs
index 37b278d..225524f 100644
--- a/scripts/sequence/components/Parallel.js
+++ b/scripts/sequence/components/Parallel.mjs
@@ -1,8 +1,8 @@
import BaseComponent, {
cleanRenderPreResult,
register,
-} from './BaseComponent.js';
-import {mergeSets} from '../../core/ArrayUtilities.js';
+} from './BaseComponent.mjs';
+import {mergeSets} from '../../core/ArrayUtilities.mjs';
function nullableMax(a = null, b = null) {
if(a === null) {
diff --git a/scripts/sequence/components/Parallel_spec.js b/scripts/sequence/components/Parallel_spec.mjs
similarity index 69%
rename from scripts/sequence/components/Parallel_spec.js
rename to scripts/sequence/components/Parallel_spec.mjs
index c0dbb7e..2e0ebd1 100644
--- a/scripts/sequence/components/Parallel_spec.js
+++ b/scripts/sequence/components/Parallel_spec.mjs
@@ -1,5 +1,5 @@
-import Parallel from './Parallel.js';
-import {getComponents} from './BaseComponent.js';
+import Parallel from './Parallel.mjs';
+import {getComponents} from './BaseComponent.mjs';
describe('Parallel', () => {
it('registers itself with the component store', () => {
diff --git a/scripts/sequence/themes/BaseTheme.js b/scripts/sequence/themes/BaseTheme.mjs
similarity index 100%
rename from scripts/sequence/themes/BaseTheme.js
rename to scripts/sequence/themes/BaseTheme.mjs
diff --git a/scripts/sequence/themes/Basic.js b/scripts/sequence/themes/Basic.mjs
similarity index 99%
rename from scripts/sequence/themes/Basic.js
rename to scripts/sequence/themes/Basic.mjs
index 254481c..955ff8e 100644
--- a/scripts/sequence/themes/Basic.js
+++ b/scripts/sequence/themes/Basic.mjs
@@ -1,6 +1,6 @@
/* eslint-disable sort-keys */ // Maybe later
-import BaseTheme, {WavePattern} from './BaseTheme.js';
+import BaseTheme, {WavePattern} from './BaseTheme.mjs';
const FONT = 'sans-serif';
const LINE_HEIGHT = 1.3;
diff --git a/scripts/sequence/themes/Basic_spec.js b/scripts/sequence/themes/Basic_spec.mjs
similarity index 69%
rename from scripts/sequence/themes/Basic_spec.js
rename to scripts/sequence/themes/Basic_spec.mjs
index 0aba8a2..863995b 100644
--- a/scripts/sequence/themes/Basic_spec.js
+++ b/scripts/sequence/themes/Basic_spec.mjs
@@ -1,6 +1,6 @@
-import {dom, textSizerFactory} from '../../stubs/TestDOM.js';
-import {Factory} from './Basic.js';
-import SVG from '../../svg/SVG.js';
+import {dom, textSizerFactory} from '../../../spec/stubs/TestDOM.mjs';
+import {Factory} from './Basic.mjs';
+import SVG from '../../svg/SVG.mjs';
describe('Basic Theme', () => {
const svg = new SVG(dom, textSizerFactory);
diff --git a/scripts/sequence/themes/Chunky.js b/scripts/sequence/themes/Chunky.mjs
similarity index 99%
rename from scripts/sequence/themes/Chunky.js
rename to scripts/sequence/themes/Chunky.mjs
index c8026a5..ca66ea1 100644
--- a/scripts/sequence/themes/Chunky.js
+++ b/scripts/sequence/themes/Chunky.mjs
@@ -1,6 +1,6 @@
/* eslint-disable sort-keys */ // Maybe later
-import BaseTheme, {WavePattern} from './BaseTheme.js';
+import BaseTheme, {WavePattern} from './BaseTheme.mjs';
const FONT = 'sans-serif';
const LINE_HEIGHT = 1.3;
diff --git a/scripts/sequence/themes/Chunky_spec.js b/scripts/sequence/themes/Chunky_spec.mjs
similarity index 69%
rename from scripts/sequence/themes/Chunky_spec.js
rename to scripts/sequence/themes/Chunky_spec.mjs
index 4a83bfd..84ac46f 100644
--- a/scripts/sequence/themes/Chunky_spec.js
+++ b/scripts/sequence/themes/Chunky_spec.mjs
@@ -1,6 +1,6 @@
-import {dom, textSizerFactory} from '../../stubs/TestDOM.js';
-import {Factory} from './Chunky.js';
-import SVG from '../../svg/SVG.js';
+import {dom, textSizerFactory} from '../../../spec/stubs/TestDOM.mjs';
+import {Factory} from './Chunky.mjs';
+import SVG from '../../svg/SVG.mjs';
describe('Chunky Theme', () => {
const svg = new SVG(dom, textSizerFactory);
diff --git a/scripts/sequence/themes/HandleeFontData.js b/scripts/sequence/themes/HandleeFontData.mjs
similarity index 100%
rename from scripts/sequence/themes/HandleeFontData.js
rename to scripts/sequence/themes/HandleeFontData.mjs
diff --git a/scripts/sequence/themes/Monospace.js b/scripts/sequence/themes/Monospace.mjs
similarity index 99%
rename from scripts/sequence/themes/Monospace.js
rename to scripts/sequence/themes/Monospace.mjs
index 139d21e..9402568 100644
--- a/scripts/sequence/themes/Monospace.js
+++ b/scripts/sequence/themes/Monospace.mjs
@@ -1,6 +1,6 @@
/* eslint-disable sort-keys */ // Maybe later
-import BaseTheme, {WavePattern} from './BaseTheme.js';
+import BaseTheme, {WavePattern} from './BaseTheme.mjs';
const FONT = 'monospace';
const LINE_HEIGHT = 1.3;
diff --git a/scripts/sequence/themes/Monospace_spec.js b/scripts/sequence/themes/Monospace_spec.mjs
similarity index 69%
rename from scripts/sequence/themes/Monospace_spec.js
rename to scripts/sequence/themes/Monospace_spec.mjs
index 45a6f42..c9decbe 100644
--- a/scripts/sequence/themes/Monospace_spec.js
+++ b/scripts/sequence/themes/Monospace_spec.mjs
@@ -1,6 +1,6 @@
-import {dom, textSizerFactory} from '../../stubs/TestDOM.js';
-import {Factory} from './Monospace.js';
-import SVG from '../../svg/SVG.js';
+import {dom, textSizerFactory} from '../../../spec/stubs/TestDOM.mjs';
+import {Factory} from './Monospace.mjs';
+import SVG from '../../svg/SVG.mjs';
describe('Monospace Theme', () => {
const svg = new SVG(dom, textSizerFactory);
diff --git a/scripts/sequence/themes/Sketch.js b/scripts/sequence/themes/Sketch.mjs
similarity index 99%
rename from scripts/sequence/themes/Sketch.js
rename to scripts/sequence/themes/Sketch.mjs
index c27f0c8..a9839a1 100644
--- a/scripts/sequence/themes/Sketch.js
+++ b/scripts/sequence/themes/Sketch.mjs
@@ -1,9 +1,9 @@
/* eslint-disable max-lines */
/* eslint-disable sort-keys */ // Maybe later
-import BaseTheme from './BaseTheme.js';
-import Handlee from './HandleeFontData.js';
-import Random from '../../core/Random.js';
+import BaseTheme from './BaseTheme.mjs';
+import Handlee from './HandleeFontData.mjs';
+import Random from '../../core/Random.mjs';
const FONT = Handlee.name;
const FONT_FAMILY = '\'' + FONT + '\',cursive';
diff --git a/scripts/sequence/themes/Sketch_spec.js b/scripts/sequence/themes/Sketch_spec.mjs
similarity index 80%
rename from scripts/sequence/themes/Sketch_spec.js
rename to scripts/sequence/themes/Sketch_spec.mjs
index f3e8f48..e0ed867 100644
--- a/scripts/sequence/themes/Sketch_spec.js
+++ b/scripts/sequence/themes/Sketch_spec.mjs
@@ -1,6 +1,6 @@
-import {dom, textSizerFactory} from '../../stubs/TestDOM.js';
-import {Factory} from './Sketch.js';
-import SVG from '../../svg/SVG.js';
+import {dom, textSizerFactory} from '../../../spec/stubs/TestDOM.mjs';
+import {Factory} from './Sketch.mjs';
+import SVG from '../../svg/SVG.mjs';
describe('Sketch Theme', () => {
const svg = new SVG(dom, textSizerFactory);
diff --git a/scripts/specs.js b/scripts/specs.js
deleted file mode 100644
index 715fea1..0000000
--- a/scripts/specs.js
+++ /dev/null
@@ -1,37 +0,0 @@
-import './core/ArrayUtilities_spec.js';
-import './core/EventObject_spec.js';
-import './core/Random_spec.js';
-import './core/documents/VirtualDocument_spec.js';
-import './svg/SVG_spec.js';
-import './svg/SVGTextBlock_spec.js';
-import './svg/PatternedLine_spec.js';
-import './interface/Interface_spec.js';
-import './interface/ComponentsLibrary_spec.js';
-import './image/ImageRegion_spec.js';
-import './image/Blur_spec.js';
-import './image/Composition_spec.js';
-import './image/ImageSimilarity_spec.js';
-import './sequence/SequenceDiagram_spec.js';
-import './sequence/SequenceDiagram_visual_spec.js';
-import './sequence/Readme_spec.js';
-import './sequence/Tokeniser_spec.js';
-import './sequence/Parser_spec.js';
-import './sequence/MarkdownParser_spec.js';
-import './sequence/LabelPatternParser_spec.js';
-import './sequence/Generator_spec.js';
-import './sequence/Renderer_spec.js';
-import './sequence/CodeMirrorMode_spec.js';
-import './sequence/themes/Basic_spec.js';
-import './sequence/themes/Monospace_spec.js';
-import './sequence/themes/Chunky_spec.js';
-import './sequence/themes/Sketch_spec.js';
-import './sequence/components/AgentCap_spec.js';
-import './sequence/components/AgentHighlight_spec.js';
-import './sequence/components/Block_spec.js';
-import './sequence/components/Connect_spec.js';
-import './sequence/components/Divider_spec.js';
-import './sequence/components/Marker_spec.js';
-import './sequence/components/Note_spec.js';
-import './sequence/components/Parallel_spec.js';
-
-jasmine.executeAllTests();
diff --git a/scripts/standalone.js b/scripts/standalone.mjs
similarity index 84%
rename from scripts/standalone.js
rename to scripts/standalone.mjs
index e0c5cc3..3af24dd 100644
--- a/scripts/standalone.js
+++ b/scripts/standalone.mjs
@@ -1,4 +1,4 @@
-import SequenceDiagram from './sequence/SequenceDiagram.js';
+import SequenceDiagram from './sequence/SequenceDiagram.mjs';
const def = window.define;
if(def && def.amd) {
diff --git a/scripts/svg/PatternedLine.js b/scripts/svg/PatternedLine.mjs
similarity index 100%
rename from scripts/svg/PatternedLine.js
rename to scripts/svg/PatternedLine.mjs
diff --git a/scripts/svg/PatternedLine_spec.js b/scripts/svg/PatternedLine_spec.mjs
similarity index 98%
rename from scripts/svg/PatternedLine_spec.js
rename to scripts/svg/PatternedLine_spec.mjs
index b616593..76190e6 100644
--- a/scripts/svg/PatternedLine_spec.js
+++ b/scripts/svg/PatternedLine_spec.mjs
@@ -1,4 +1,4 @@
-import PatternedLine from './PatternedLine.js';
+import PatternedLine from './PatternedLine.mjs';
describe('PatternedLine', () => {
function simplify(path, dp) {
diff --git a/scripts/svg/SVG.js b/scripts/svg/SVG.mjs
similarity index 92%
rename from scripts/svg/SVG.js
rename to scripts/svg/SVG.mjs
index 427e295..c9571ac 100644
--- a/scripts/svg/SVG.js
+++ b/scripts/svg/SVG.mjs
@@ -1,5 +1,5 @@
-import {SVGTextBlock, TextSizer} from './SVGTextBlock.js';
-import PatternedLine from './PatternedLine.js';
+import {SVGTextBlock, TextSizer} from './SVGTextBlock.mjs';
+import PatternedLine from './PatternedLine.mjs';
const NS = 'http://www.w3.org/2000/svg';
@@ -214,16 +214,16 @@ export default class SVG {
return this.dom.el(tag, namespace);
}
- box(attrs, position) {
- return this.el('rect').attrs(attrs).attrs(position);
+ box(attrs, {height, width, x, y}) {
+ return this.el('rect').attrs(attrs).attrs({height, width, x, y});
}
boxFactory(attrs) {
return this.box.bind(this, attrs);
}
- line(attrs, position) {
- return this.el('line').attrs(attrs).attrs(position);
+ line(attrs, {x1, x2, y1, y2}) {
+ return this.el('line').attrs(attrs).attrs({x1, x2, y1, y2});
}
lineFactory(attrs) {
@@ -259,11 +259,11 @@ export default class SVG {
return this.cross.bind(this, attrs);
}
- note(attrs, flickAttrs, position) {
- const x0 = position.x;
- const x1 = position.x + position.width;
- const y0 = position.y;
- const y1 = position.y + position.height;
+ note(attrs, flickAttrs, {height, width, x, y}) {
+ const x0 = x;
+ const x1 = x + width;
+ const y0 = y;
+ const y1 = y + height;
const flick = 7;
return this.el('g').add(
@@ -290,13 +290,13 @@ export default class SVG {
return this.note.bind(this, attrs, flickAttrs);
}
- formattedText(attrs = {}, formatted = [], position = {}) {
+ formattedText(attrs = {}, formatted = [], {x, y} = {}) {
const container = this.el('g');
const txt = new SVGTextBlock(container, this, {
attrs,
formatted,
- x: position.x,
- y: position.y,
+ x,
+ y,
});
return Object.assign(container, {
set: (state) => txt.set(state),
diff --git a/scripts/svg/SVGTextBlock.js b/scripts/svg/SVGTextBlock.mjs
similarity index 96%
rename from scripts/svg/SVGTextBlock.js
rename to scripts/svg/SVGTextBlock.mjs
index c5accbf..0e935bc 100644
--- a/scripts/svg/SVGTextBlock.js
+++ b/scripts/svg/SVGTextBlock.mjs
@@ -1,5 +1,4 @@
-// Thanks, https://stackoverflow.com/a/9851769/1180785
-const firefox = (typeof window.InstallTrigger !== 'undefined');
+import {firefox} from '../core/browser.mjs';
function merge(state, newState) {
for(const k in state) {
diff --git a/scripts/svg/SVGTextBlock_spec.js b/scripts/svg/SVGTextBlock_spec.mjs
similarity index 95%
rename from scripts/svg/SVGTextBlock_spec.js
rename to scripts/svg/SVGTextBlock_spec.mjs
index b1eb1ed..d3f8f68 100644
--- a/scripts/svg/SVGTextBlock_spec.js
+++ b/scripts/svg/SVGTextBlock_spec.mjs
@@ -1,6 +1,7 @@
-import {DOMWrapper, dom, textSizerFactory} from '../stubs/TestDOM.js';
-import {SVGTextBlock, TextSizer} from './SVGTextBlock.js';
-import SVG from './SVG.js';
+import {DOMWrapper, dom, textSizerFactory} from '../../spec/stubs/TestDOM.mjs';
+import {SVGTextBlock, TextSizer} from './SVGTextBlock.mjs';
+import SVG from './SVG.mjs';
+import {nodejs} from '../core/browser.mjs';
describe('SVGTextBlock', () => {
const attrs = {'font-size': 10, 'line-height': 1.5};
@@ -128,6 +129,11 @@ describe('SVGTextBlock', () => {
});
describe('TextSizer', () => {
+ if(nodejs) {
+ // TextSizer is for browsers only
+ return;
+ }
+
beforeEach(() => {
svg = new SVG(
new DOMWrapper(window.document),
diff --git a/scripts/svg/SVG_spec.js b/scripts/svg/SVG_spec.mjs
similarity index 97%
rename from scripts/svg/SVG_spec.js
rename to scripts/svg/SVG_spec.mjs
index 593e05a..67e447a 100644
--- a/scripts/svg/SVG_spec.js
+++ b/scripts/svg/SVG_spec.mjs
@@ -1,5 +1,5 @@
-import {dom, textSizerFactory} from '../stubs/TestDOM.js';
-import SVG from './SVG.js';
+import {dom, textSizerFactory} from '../../spec/stubs/TestDOM.mjs';
+import SVG from './SVG.mjs';
describe('SVG', () => {
const expectedNS = 'http://www.w3.org/2000/svg';
diff --git a/spec/helpers/toBeNear.mjs b/spec/helpers/toBeNear.mjs
new file mode 100644
index 0000000..c4c851c
--- /dev/null
+++ b/spec/helpers/toBeNear.mjs
@@ -0,0 +1,23 @@
+beforeAll(() => {
+ jasmine.addMatchers({
+ toBeNear: () => ({
+ compare: (actual, expected, range) => {
+ if(
+ typeof expected !== 'number' ||
+ typeof range !== 'number' ||
+ range < 0
+ ) {
+ throw new Error(
+ 'Invalid toBeNear(' + expected + ',' + range + ')'
+ );
+ }
+ if(typeof actual !== 'number') {
+ throw new Error('Expected a number, got ' + actual);
+ }
+ return {
+ pass: Math.abs(actual - expected) <= range,
+ };
+ },
+ }),
+ });
+});
diff --git a/scripts/sequence/test-images/AgentOptions.svg b/spec/images/AgentOptions.svg
similarity index 100%
rename from scripts/sequence/test-images/AgentOptions.svg
rename to spec/images/AgentOptions.svg
diff --git a/scripts/sequence/test-images/Asynchronous.svg b/spec/images/Asynchronous.svg
similarity index 100%
rename from scripts/sequence/test-images/Asynchronous.svg
rename to spec/images/Asynchronous.svg
diff --git a/scripts/sequence/test-images/Block.svg b/spec/images/Block.svg
similarity index 100%
rename from scripts/sequence/test-images/Block.svg
rename to spec/images/Block.svg
diff --git a/scripts/sequence/test-images/CollapsedBlocks.svg b/spec/images/CollapsedBlocks.svg
similarity index 100%
rename from scripts/sequence/test-images/CollapsedBlocks.svg
rename to spec/images/CollapsedBlocks.svg
diff --git a/scripts/sequence/test-images/Connect.svg b/spec/images/Connect.svg
similarity index 100%
rename from scripts/sequence/test-images/Connect.svg
rename to spec/images/Connect.svg
diff --git a/scripts/sequence/test-images/Divider.svg b/spec/images/Divider.svg
similarity index 100%
rename from scripts/sequence/test-images/Divider.svg
rename to spec/images/Divider.svg
diff --git a/scripts/sequence/test-images/DividerMasking.svg b/spec/images/DividerMasking.svg
similarity index 100%
rename from scripts/sequence/test-images/DividerMasking.svg
rename to spec/images/DividerMasking.svg
diff --git a/scripts/sequence/test-images/Markdown.svg b/spec/images/Markdown.svg
similarity index 100%
rename from scripts/sequence/test-images/Markdown.svg
rename to spec/images/Markdown.svg
diff --git a/scripts/sequence/test-images/Reference.svg b/spec/images/Reference.svg
similarity index 100%
rename from scripts/sequence/test-images/Reference.svg
rename to spec/images/Reference.svg
diff --git a/scripts/sequence/test-images/ReferenceLayering.svg b/spec/images/ReferenceLayering.svg
similarity index 100%
rename from scripts/sequence/test-images/ReferenceLayering.svg
rename to spec/images/ReferenceLayering.svg
diff --git a/scripts/sequence/test-images/SelfConnect.svg b/spec/images/SelfConnect.svg
similarity index 100%
rename from scripts/sequence/test-images/SelfConnect.svg
rename to spec/images/SelfConnect.svg
diff --git a/spec/images/Sketch.svg b/spec/images/Sketch.svg
new file mode 100644
index 0000000..8fd474f
--- /dev/null
+++ b/spec/images/Sketch.svg
@@ -0,0 +1,6 @@
+theme sketch
+
+A -> +B
+B -> B: self
+-B -x A
+ A B self
\ No newline at end of file
diff --git a/scripts/sequence/test-images/list.js b/spec/images/list.mjs
similarity index 100%
rename from scripts/sequence/test-images/list.js
rename to spec/images/list.mjs
diff --git a/scripts/stubs/TestDOM.js b/spec/stubs/TestDOM.mjs
similarity index 80%
rename from scripts/stubs/TestDOM.js
rename to spec/stubs/TestDOM.mjs
index d4f33c3..1c0fb12 100644
--- a/scripts/stubs/TestDOM.js
+++ b/spec/stubs/TestDOM.mjs
@@ -1,5 +1,8 @@
-import DOMWrapper from '../core/DOMWrapper.js';
-import VirtualDocument from '../core/documents/VirtualDocument.js';
+import {
+ Event,
+ VirtualDocument,
+} from '../../scripts/core/documents/VirtualDocument.mjs';
+import DOMWrapper from '../../scripts/core/DOMWrapper.mjs';
export class UnitaryTextSizer {
// Simplified text sizer, which assumes all characters render as
@@ -37,6 +40,7 @@ export function textSizerFactory() {
export const dom = new DOMWrapper(new VirtualDocument());
export {
+ Event,
VirtualDocument,
DOMWrapper,
};
diff --git a/scripts/stubs/codemirror.js b/spec/stubs/codemirror.mjs
similarity index 100%
rename from scripts/stubs/codemirror.js
rename to spec/stubs/codemirror.mjs
diff --git a/scripts/stubs/require.js b/spec/stubs/require.mjs
similarity index 72%
rename from scripts/stubs/require.js
rename to spec/stubs/require.mjs
index 7b1747d..d3e52e6 100644
--- a/scripts/stubs/require.js
+++ b/spec/stubs/require.mjs
@@ -1,5 +1,5 @@
-import CodeMirror from './codemirror.js';
-import Split from './split.js';
+import CodeMirror from './codemirror.mjs';
+import Split from './split.mjs';
const stubLibs = new Map();
stubLibs.set('cm/lib/codemirror', CodeMirror);
diff --git a/scripts/stubs/split.js b/spec/stubs/split.mjs
similarity index 100%
rename from scripts/stubs/split.js
rename to spec/stubs/split.mjs
diff --git a/spec/support/browser_specs.mjs b/spec/support/browser_specs.mjs
new file mode 100644
index 0000000..6bc8356
--- /dev/null
+++ b/spec/support/browser_specs.mjs
@@ -0,0 +1,44 @@
+/*
+ * All spec files imported here will be tested in the browser
+ * when opening test.htm
+ */
+
+import '../helpers/toBeNear.mjs';
+
+import '../../scripts/core/ArrayUtilities_spec.mjs';
+import '../../scripts/core/EventObject_spec.mjs';
+import '../../scripts/core/Random_spec.mjs';
+import '../../scripts/core/documents/VirtualDocument_spec.mjs';
+import '../../scripts/svg/SVG_spec.mjs';
+import '../../scripts/svg/SVGTextBlock_spec.mjs';
+import '../../scripts/svg/PatternedLine_spec.mjs';
+import '../../scripts/image/ImageRegion_spec.mjs';
+import '../../scripts/image/Blur_spec.mjs';
+import '../../scripts/image/Composition_spec.mjs';
+import '../../scripts/image/ImageSimilarity_spec.mjs';
+import '../../scripts/sequence/SequenceDiagram_spec.mjs';
+import '../../scripts/sequence/Tokeniser_spec.mjs';
+import '../../scripts/sequence/Parser_spec.mjs';
+import '../../scripts/sequence/MarkdownParser_spec.mjs';
+import '../../scripts/sequence/LabelPatternParser_spec.mjs';
+import '../../scripts/sequence/Generator_spec.mjs';
+import '../../scripts/sequence/Renderer_spec.mjs';
+import '../../scripts/sequence/themes/Basic_spec.mjs';
+import '../../scripts/sequence/themes/Monospace_spec.mjs';
+import '../../scripts/sequence/themes/Chunky_spec.mjs';
+import '../../scripts/sequence/themes/Sketch_spec.mjs';
+import '../../scripts/sequence/components/AgentCap_spec.mjs';
+import '../../scripts/sequence/components/AgentHighlight_spec.mjs';
+import '../../scripts/sequence/components/Block_spec.mjs';
+import '../../scripts/sequence/components/Connect_spec.mjs';
+import '../../scripts/sequence/components/Divider_spec.mjs';
+import '../../scripts/sequence/components/Marker_spec.mjs';
+import '../../scripts/sequence/components/Note_spec.mjs';
+import '../../scripts/sequence/components/Parallel_spec.mjs';
+
+import '../../web/interface/Interface_spec.mjs';
+import '../../web/interface/ComponentsLibrary_spec.mjs';
+
+import '../../scripts/sequence/CodeMirrorMode_webspec.mjs';
+import '../../scripts/sequence/SequenceDiagram_visual_webspec.mjs';
+import '../../scripts/sequence/Readme_webspec.mjs';
diff --git a/spec/support/eslintignore b/spec/support/eslintignore
new file mode 100644
index 0000000..bc6dbb4
--- /dev/null
+++ b/spec/support/eslintignore
@@ -0,0 +1,6 @@
+node_modules
+lib
+weblib
+ephemeral
+
+*FontData.mjs
diff --git a/.eslintrc.js b/spec/support/eslintrc.js
similarity index 99%
rename from .eslintrc.js
rename to spec/support/eslintrc.js
index 11beccb..36bcbfe 100644
--- a/.eslintrc.js
+++ b/spec/support/eslintrc.js
@@ -1,5 +1,3 @@
-'use strict';
-
module.exports = {
'env': {
'browser': true,
@@ -208,13 +206,13 @@ module.exports = {
'prefer-destructuring': [
'error',
{
- 'VariableDeclarator': {
- 'array': true,
- 'object': true
- },
'AssignmentExpression': {
'array': false,
- 'object': false
+ 'object': false,
+ },
+ 'VariableDeclarator': {
+ 'array': true,
+ 'object': true,
},
},
],
diff --git a/spec/support/jasmine.json b/spec/support/jasmine.json
new file mode 100644
index 0000000..1b54708
--- /dev/null
+++ b/spec/support/jasmine.json
@@ -0,0 +1,6 @@
+{
+ "spec_dir": "ephemeral",
+ "spec_files": ["spec_bundle.js"],
+ "stopSpecOnExpectationFailure": false,
+ "random": true
+}
diff --git a/spec/support/rollup.config.js b/spec/support/rollup.config.js
new file mode 100644
index 0000000..a46a903
--- /dev/null
+++ b/spec/support/rollup.config.js
@@ -0,0 +1,19 @@
+import multiEntry from 'rollup-plugin-multi-entry';
+
+export default [
+ {
+ input: [
+ 'spec/helpers/**/*.js',
+ 'spec/helpers/**/*.mjs',
+ '**/*_spec.js',
+ '**/*_spec.mjs',
+ ],
+ output: {
+ file: 'ephemeral/spec_bundle.js',
+ format: 'iife',
+ name: 'Tests',
+ sourcemap: true,
+ },
+ plugins: [multiEntry()],
+ },
+];
diff --git a/test.htm b/test.htm
index 75681cf..d35fe28 100644
--- a/test.htm
+++ b/test.htm
@@ -47,10 +47,7 @@
crossorigin="anonymous"
>
-
-
-
-
+
diff --git a/scripts/editor.js b/web/editor.mjs
similarity index 83%
rename from scripts/editor.js
rename to web/editor.mjs
index 05af256..80b3ff1 100644
--- a/scripts/editor.js
+++ b/web/editor.mjs
@@ -1,7 +1,7 @@
-import ComponentsLibrary from './interface/ComponentsLibrary.js';
-import Interface from './interface/Interface.js';
-import SequenceDiagram from './sequence/SequenceDiagram.js';
-import {require} from './requireCDN.js';
+import ComponentsLibrary from './interface/ComponentsLibrary.mjs';
+import Interface from './interface/Interface.mjs';
+import SequenceDiagram from '../scripts/sequence/SequenceDiagram.mjs';
+import {require} from './requireCDN.mjs';
const defaultCode = (
'title Labyrinth\n' +
diff --git a/scripts/interface/ComponentsLibrary.js b/web/interface/ComponentsLibrary.mjs
similarity index 100%
rename from scripts/interface/ComponentsLibrary.js
rename to web/interface/ComponentsLibrary.mjs
diff --git a/web/interface/ComponentsLibrary_spec.mjs b/web/interface/ComponentsLibrary_spec.mjs
new file mode 100644
index 0000000..9ce3eb2
--- /dev/null
+++ b/web/interface/ComponentsLibrary_spec.mjs
@@ -0,0 +1,34 @@
+import {VirtualDocument, textSizerFactory} from '../../spec/stubs/TestDOM.mjs';
+import ComponentsLibrary from './ComponentsLibrary.mjs';
+import SequenceDiagram from '../../scripts/sequence/SequenceDiagram.mjs';
+import {nodejs} from '../../scripts/core/browser.mjs';
+
+const themes = SequenceDiagram.getDefaultThemeNames().slice(1);
+
+const opts = nodejs ? {
+ document: new VirtualDocument(),
+ textSizerFactory,
+} : {};
+
+function checkSample(src) {
+ it('renders without error', () => {
+ expect(() => new SequenceDiagram(src, opts)).not.toThrow();
+ });
+
+ themes.forEach((themeName) => {
+ it('renders without error in ' + themeName + ' theme', () => {
+ expect(() => new SequenceDiagram(
+ 'theme ' + themeName + '\n' + src,
+ opts
+ )).not.toThrow();
+ });
+ });
+}
+
+describe('Components Library', () => {
+ ComponentsLibrary.forEach(({title, code, preview}) => {
+ describe(title, () => {
+ checkSample(preview || code);
+ });
+ });
+});
diff --git a/scripts/interface/Interface.js b/web/interface/Interface.mjs
similarity index 92%
rename from scripts/interface/Interface.js
rename to web/interface/Interface.mjs
index b11f415..bed4d8c 100644
--- a/scripts/interface/Interface.js
+++ b/web/interface/Interface.mjs
@@ -1,13 +1,11 @@
/* eslint-disable max-lines */
-import DOMWrapper from '../core/DOMWrapper.js';
+import DOMWrapper from '../../scripts/core/DOMWrapper.mjs';
const DELAY_AGENTCHANGE = 500;
const DELAY_STAGECHANGE = 250;
const PNG_RESOLUTION = 4;
-const dom = new DOMWrapper(document);
-
function addNewline(value) {
if(value.length > 0 && value.charAt(value.length - 1) !== '\n') {
return value + '\n';
@@ -200,7 +198,7 @@ export default class Interface {
}
buildOptionsDownloads() {
- this.downloadPNG = dom.el('a')
+ this.downloadPNG = this.dom.el('a')
.text('Download PNG')
.attrs({
'download': 'SequenceDiagram.png',
@@ -209,7 +207,7 @@ export default class Interface {
.on(['focus', 'mouseover', 'mousedown'], this._downloadPNGFocus)
.on('click', this._downloadPNGClick);
- this.downloadSVG = dom.el('a')
+ this.downloadSVG = this.dom.el('a')
.text('SVG')
.attrs({
'download': 'SequenceDiagram.svg',
@@ -217,16 +215,16 @@ export default class Interface {
})
.on('click', this._downloadSVGClick);
- return dom.el('div').setClass('options downloads')
+ return this.dom.el('div').setClass('options downloads')
.add(this.downloadPNG, this.downloadSVG);
}
buildLibrary(container) {
const diagrams = this.library.map((lib) => {
- const holdInner = dom.el('div')
+ const holdInner = this.dom.el('div')
.attr('title', lib.title || lib.code);
- const hold = dom.el('div')
+ const hold = this.dom.el('div')
.setClass('library-item')
.add(holdInner)
.on('click', this.addCodeBlock.bind(this, lib.code))
@@ -253,36 +251,36 @@ export default class Interface {
}
buildViewPane() {
- this.viewPaneInner = dom.el('div').setClass('pane-view-inner')
+ this.viewPaneInner = this.dom.el('div').setClass('pane-view-inner')
.add(this.diagram.dom());
- this.errorMsg = dom.el('div').setClass('msg-error');
+ this.errorMsg = this.dom.el('div').setClass('msg-error');
- return dom.el('div').setClass('pane-view')
+ return this.dom.el('div').setClass('pane-view')
.add(
- dom.el('div').setClass('pane-view-scroller')
+ this.dom.el('div').setClass('pane-view-scroller')
.add(this.viewPaneInner),
this.errorMsg
);
}
buildLeftPanes() {
- const container = dom.el('div').setClass('pane-side');
+ const container = this.dom.el('div').setClass('pane-side');
- this.code = dom.el('textarea')
+ this.code = this.dom.el('textarea')
.setClass('editor-simple')
.val(this.loadCode() || this.defaultCode)
.on('input', () => this.update(false));
- const codePane = dom.el('div').setClass('pane-code')
+ const codePane = this.dom.el('div').setClass('pane-code')
.add(this.code)
.attach(container);
if(this.library.length > 0) {
- const libPane = dom.el('div').setClass('pane-library')
- .add(dom.el('div').setClass('pane-library-scroller')
+ const libPane = this.dom.el('div').setClass('pane-library')
+ .add(this.dom.el('div').setClass('pane-library-scroller')
.add(this.buildLibrary(
- dom.el('div').setClass('pane-library-inner')
+ this.dom.el('div').setClass('pane-library-inner')
)))
.attach(container);
@@ -298,16 +296,17 @@ export default class Interface {
}
build(container) {
+ this.dom = new DOMWrapper(container.ownerDocument);
const lPane = this.buildLeftPanes();
const viewPane = this.buildViewPane();
- this.container = dom.wrap(container)
- .add(dom.el('div').setClass('pane-hold')
+ this.container = this.dom.wrap(container)
+ .add(this.dom.el('div').setClass('pane-hold')
.add(
lPane,
viewPane,
- dom.el('div').setClass('options links')
- .add(this.links.map((link) => dom.el('a')
+ this.dom.el('div').setClass('options links')
+ .add(this.links.map((link) => this.dom.el('a')
.attrs({'href': link.href, 'target': '_blank'})
.text(link.label))),
this.buildOptionsDownloads()
diff --git a/scripts/interface/Interface_spec.js b/web/interface/Interface_spec.mjs
similarity index 70%
rename from scripts/interface/Interface_spec.js
rename to web/interface/Interface_spec.mjs
index 85a8d49..fe1ee5f 100644
--- a/scripts/interface/Interface_spec.js
+++ b/web/interface/Interface_spec.mjs
@@ -1,16 +1,15 @@
-import Interface from './Interface.js';
-import stubRequire from '../stubs/require.js';
+import {Event, VirtualDocument} from '../../spec/stubs/TestDOM.mjs';
+import Interface from './Interface.mjs';
+import stubRequire from '../../spec/stubs/require.mjs';
describe('Interface', () => {
- // Thanks, https://stackoverflow.com/a/23522755/1180785
- const safari = (/^((?!chrome|android).)*safari/i).test(navigator.userAgent);
-
const defaultCode = 'my default code';
let sequenceDiagram = null;
let container = null;
let ui = null;
beforeEach(() => {
+ const dom = new VirtualDocument();
sequenceDiagram = jasmine.createSpyObj('sequenceDiagram', [
'dom',
'render',
@@ -29,11 +28,8 @@ describe('Interface', () => {
});
sequenceDiagram.on.and.returnValue(sequenceDiagram);
sequenceDiagram.getSize.and.returnValue({height: 20, width: 10});
- sequenceDiagram.dom.and.returnValue(document.createElement('svg'));
- container = jasmine.createSpyObj('container', [
- 'insertBefore',
- 'addEventListener',
- ]);
+ sequenceDiagram.dom.and.returnValue(dom.createElement('svg'));
+ container = dom.createElement('div');
ui = new Interface({
defaultCode,
@@ -46,10 +42,7 @@ describe('Interface', () => {
it('adds elements to the given container', () => {
ui.build(container);
- expect(container.insertBefore).toHaveBeenCalledWith(
- jasmine.anything(),
- null
- );
+ expect(container.childNodes.length).toBeGreaterThan(0);
});
it('creates a code mirror instance with the given code', (done) => {
@@ -76,13 +69,6 @@ describe('Interface', () => {
expect(el.getAttribute('href')).toEqual('#');
- if(safari) {
- /*
- * Safari actually starts a download if we do this, which
- * doesn't seem to fit its usual security vibe
- */
- return;
- }
el.dispatchEvent(new Event('click'));
expect(el.getAttribute('href')).toEqual('mySVGURL');
diff --git a/scripts/readmeImages.js b/web/readmeImages.mjs
similarity index 96%
rename from scripts/readmeImages.js
rename to web/readmeImages.mjs
index d87206a..32be5ee 100644
--- a/scripts/readmeImages.js
+++ b/web/readmeImages.mjs
@@ -1,4 +1,4 @@
-import SequenceDiagram from './sequence/SequenceDiagram.js';
+import SequenceDiagram from '../scripts/sequence/SequenceDiagram.mjs';
function makeText(text = '') {
return document.createTextNode(text);
diff --git a/scripts/requireCDN.js b/web/requireCDN.mjs
similarity index 88%
rename from scripts/requireCDN.js
rename to web/requireCDN.mjs
index 844871e..c8c6591 100644
--- a/scripts/requireCDN.js
+++ b/web/requireCDN.mjs
@@ -10,7 +10,9 @@ for(let i = 0; i < metaTags.length; ++ i) {
if(name && name.startsWith('cdn-')) {
const module = name.substr('cdn-'.length);
let src = metaTag.getAttribute('content');
- if(src.endsWith('.js')) {
+ if(src.endsWith('.mjs')) {
+ src = src.substr(0, src.length - '.mjs'.length);
+ } else if(src.endsWith('.js')) {
src = src.substr(0, src.length - '.js'.length);
}
paths[module] = src;
diff --git a/rollup.config.js b/web/rollup.config.js
similarity index 50%
rename from rollup.config.js
rename to web/rollup.config.js
index be55d41..64abbb9 100644
--- a/rollup.config.js
+++ b/web/rollup.config.js
@@ -2,28 +2,20 @@ import hypothetical from 'rollup-plugin-hypothetical';
export default [
{
- input: 'scripts/standalone.js',
+ input: 'web/editor.mjs',
output: {
+ file: 'weblib/editor.js',
format: 'iife',
- file: 'lib/sequence-diagram.js',
- name: 'SequenceDiagram',
+ name: 'SequenceDiagramEditor',
},
- },
- {
- input: 'scripts/editor.js',
plugins: [
hypothetical({
allowFallthrough: true,
files: {
- './scripts/sequence/SequenceDiagram.js':
- 'export default window.SequenceDiagram;'
+ './scripts/sequence/SequenceDiagram.mjs':
+ 'export default window.SequenceDiagram;',
},
}),
],
- output: {
- format: 'iife',
- file: 'weblib/editor.js',
- name: 'SequenceDiagramEditor',
- },
},
-]
+];
diff --git a/weblib/editor.js b/weblib/editor.js
index 87033f6..4a453b1 100644
--- a/weblib/editor.js
+++ b/weblib/editor.js
@@ -510,8 +510,6 @@
const DELAY_STAGECHANGE = 250;
const PNG_RESOLUTION = 4;
- const dom = new DOMWrapper(document);
-
function addNewline(value) {
if(value.length > 0 && value.charAt(value.length - 1) !== '\n') {
return value + '\n';
@@ -704,7 +702,7 @@
}
buildOptionsDownloads() {
- this.downloadPNG = dom.el('a')
+ this.downloadPNG = this.dom.el('a')
.text('Download PNG')
.attrs({
'download': 'SequenceDiagram.png',
@@ -713,7 +711,7 @@
.on(['focus', 'mouseover', 'mousedown'], this._downloadPNGFocus)
.on('click', this._downloadPNGClick);
- this.downloadSVG = dom.el('a')
+ this.downloadSVG = this.dom.el('a')
.text('SVG')
.attrs({
'download': 'SequenceDiagram.svg',
@@ -721,16 +719,16 @@
})
.on('click', this._downloadSVGClick);
- return dom.el('div').setClass('options downloads')
+ return this.dom.el('div').setClass('options downloads')
.add(this.downloadPNG, this.downloadSVG);
}
buildLibrary(container) {
const diagrams = this.library.map((lib) => {
- const holdInner = dom.el('div')
+ const holdInner = this.dom.el('div')
.attr('title', lib.title || lib.code);
- const hold = dom.el('div')
+ const hold = this.dom.el('div')
.setClass('library-item')
.add(holdInner)
.on('click', this.addCodeBlock.bind(this, lib.code))
@@ -757,36 +755,36 @@
}
buildViewPane() {
- this.viewPaneInner = dom.el('div').setClass('pane-view-inner')
+ this.viewPaneInner = this.dom.el('div').setClass('pane-view-inner')
.add(this.diagram.dom());
- this.errorMsg = dom.el('div').setClass('msg-error');
+ this.errorMsg = this.dom.el('div').setClass('msg-error');
- return dom.el('div').setClass('pane-view')
+ return this.dom.el('div').setClass('pane-view')
.add(
- dom.el('div').setClass('pane-view-scroller')
+ this.dom.el('div').setClass('pane-view-scroller')
.add(this.viewPaneInner),
this.errorMsg
);
}
buildLeftPanes() {
- const container = dom.el('div').setClass('pane-side');
+ const container = this.dom.el('div').setClass('pane-side');
- this.code = dom.el('textarea')
+ this.code = this.dom.el('textarea')
.setClass('editor-simple')
.val(this.loadCode() || this.defaultCode)
.on('input', () => this.update(false));
- const codePane = dom.el('div').setClass('pane-code')
+ const codePane = this.dom.el('div').setClass('pane-code')
.add(this.code)
.attach(container);
if(this.library.length > 0) {
- const libPane = dom.el('div').setClass('pane-library')
- .add(dom.el('div').setClass('pane-library-scroller')
+ const libPane = this.dom.el('div').setClass('pane-library')
+ .add(this.dom.el('div').setClass('pane-library-scroller')
.add(this.buildLibrary(
- dom.el('div').setClass('pane-library-inner')
+ this.dom.el('div').setClass('pane-library-inner')
)))
.attach(container);
@@ -802,16 +800,17 @@
}
build(container) {
+ this.dom = new DOMWrapper(container.ownerDocument);
const lPane = this.buildLeftPanes();
const viewPane = this.buildViewPane();
- this.container = dom.wrap(container)
- .add(dom.el('div').setClass('pane-hold')
+ this.container = this.dom.wrap(container)
+ .add(this.dom.el('div').setClass('pane-hold')
.add(
lPane,
viewPane,
- dom.el('div').setClass('options links')
- .add(this.links.map((link) => dom.el('a')
+ this.dom.el('div').setClass('options links')
+ .add(this.links.map((link) => this.dom.el('a')
.attrs({'href': link.href, 'target': '_blank'})
.text(link.label))),
this.buildOptionsDownloads()
@@ -1134,7 +1133,9 @@
if(name && name.startsWith('cdn-')) {
const module = name.substr('cdn-'.length);
let src = metaTag.getAttribute('content');
- if(src.endsWith('.js')) {
+ if(src.endsWith('.mjs')) {
+ src = src.substr(0, src.length - '.mjs'.length);
+ } else if(src.endsWith('.js')) {
src = src.substr(0, src.length - '.js'.length);
}
paths[module] = src;
diff --git a/weblib/editor.min.js b/weblib/editor.min.js
index 151e6a9..d09cec8 100644
--- a/weblib/editor.min.js
+++ b/weblib/editor.min.js
@@ -1 +1 @@
-!function(){"use strict";function e(e){return null===e?null:e.element?e.element:e}function t(e){return e.length>0&&"\n"!==e.charAt(e.length-1)?e+"\n":e}function n(e,t){let n=0,i=0;for(;;){const s=e.indexOf("\n",n)+1;if(t{const i=t[0].parentNode,s=i.addEventListener,r=i.removeEventListener;i.addEventListener=((e,t)=>{"mousemove"===e||"touchmove"===e?window.addEventListener(e,t,{passive:!0}):s.call(i,e,t)}),i.removeEventListener=((e,t)=>{"mousemove"===e||"touchmove"===e?window.removeEventListener(e,t):r.call(i,e,t)});let o=null;const a=Object.assign({cursor:"vertical"===n.direction?"row-resize":"col-resize",direction:"vertical",gutterSize:0,onDragEnd:()=>{document.body.style.cursor=o,o=null},onDragStart:()=>{o=document.body.style.cursor,document.body.style.cursor=a.cursor}},n);return new e(t,a)})}var s=[{code:"{Agent1} -> {Agent2}: {Message}",title:"Simple arrow (synchronous)"},{code:"{Agent1} --\x3e {Agent2}: {Message}",title:"Arrow with dotted line (response)"},{code:"{Agent1} ->> {Agent2}: {Message}",title:"Open arrow (asynchronous)"},{code:"{Agent1} -x {Agent2}: {Message}",title:"Lost message"},{code:"{Agent1} ~> {Agent2}: {Message}",title:"Wavy line"},{code:"{Agent1} -> {Agent1}: {Message}",title:"Self-connection"},{code:"{Agent1} -> ...{id}\n...{id} -> {Agent2}: {Message}",preview:"begin A, B\nA -> ...x\n...x -> B: Message",title:"Asynchronous message"},{code:"* -> {Agent1}: {Message}",title:"Found message"},{code:"{Agent1} -> +{Agent2}: {Request}\n{Agent1} <-- -{Agent2}: {Response}",title:"Request/response pair"},{code:"{Agent1} -> *{Agent2}: {Request}\n{Agent1} <-- !{Agent2}: {Response}",title:"Inline agent creation / destruction"},{code:"{Agent1} -> {Agent2}: {Request}\n{Agent1} <-- {Agent2}: {Response}\nend {Agent2}",preview:"begin A\n::\nA -> B: Request\nA <-- B: Response\nend B",title:"Agent creation / destruction"},{code:'autolabel "[] "',preview:'autolabel "[] "\nA -> B: Foo\nA <- B: Bar\nA -> B: Baz',title:"Numbered labels"},{code:"if {Condition1}\n {Agent1} -> {Agent2}\nelse if {Condition2}\n {Agent1} -> {Agent2}\nelse\n {Agent1} -> {Agent2}\nend",preview:"begin A, B\nif Condition1\n A -> B\nelse if Condition2\n A -> B\nelse\n A -> B\nend",title:"Conditional blocks"},{code:"repeat {Condition}\n {Agent1} -> {Agent2}\nend",preview:"begin A, B\nrepeat Condition\n A -> B\nend",title:"Repeated block"},{code:"begin reference: {Label} as {Name}\n{Agent1} -> {Name}\nend {Name}",preview:'begin A\nbegin reference: "See 1.3" as myRef\nA -> myRef\nmyRef -> A\nend myRef',title:"Reference"},{code:"begin reference over {Covered}: {Label} as {Name}\n{Agent1} -> {Name}\nend {Name}",preview:'begin A, B, C\nbegin reference over B, C: "See 1.3" as myRef\nA -> myRef\nmyRef -> A\nend myRef',title:"Reference over agents"},{code:"group {Label}\n {Agent1} -> {Agent2}\nend",preview:"begin A, B\ngroup Label\n A -> B\nend",title:"Group"},{code:"note over {Agent1}: {Message}",title:"Note over agent"},{code:"note over {Agent1}, {Agent2}: {Message}",title:"Note over multiple agents"},{code:"note left of {Agent1}: {Message}",title:"Note left of agent"},{code:"note right of {Agent1}: {Message}",title:"Note right of agent"},{code:"note between {Agent1}, {Agent2}: {Message}",title:"Note between agents"},{code:"state over {Agent1}: {State}",title:"State over agent"},{code:"[ -> {Agent1}: {Message1}\n{Agent1} -> ]: {Message2}",title:"Arrows to/from the sides"},{code:"text right: {Message}",preview:'A -> B\nsimultaneously:\ntext right: "Message\\non the\\nside"',title:"Text beside the diagram"},{code:"divider space with height 10: {message}",preview:"begin A, B, C, D, E, F\ndivider space with height 30: message",title:"Vertical space divider"},{code:"divider line with height 10: {message}",preview:"begin A, B, C, D, E, F\ndivider line with height 30: message",title:"Line divider"},{code:"divider delay with height 10: {message}",preview:"begin A, B, C, D, E, F\ndivider delay with height 30: message",title:"Delay divider"},{code:"divider tear with height 10: {message}",preview:"begin A, B, C, D, E, F\ndivider tear with height 30: message",title:"Tear divider"},{code:"title {Title}",preview:"headers box\ntitle Title\nA -> B",title:"Title"},{code:"**{text}**",preview:"A -> B: **bold**",title:"Bold markdown"},{code:"_{text}_",preview:"A -> B: _italic_",title:"Italic markdown"},{code:"~{text}~",preview:"A -> B: ~strikeout~",title:"Strikeout markdown"},{code:"`{text}`",preview:"A -> B: `mono`",title:"Monospace markdown"},{code:"{Agent} is red",preview:"headers box\nA is red\nbegin A",title:"Red agent line"},{code:"{Agent} is a database",preview:"headers box\nA is a database\nbegin A",title:"Database indicator"},{code:"theme monospace",preview:"headers box\ntitle mono\ntheme monospace\nA -> B",title:"Monospace theme"},{code:"theme chunky",preview:"headers box\ntitle chunky\ntheme chunky\nA -> B",title:"Chunky theme"},{code:"theme sketch",preview:"headers box\ntitle sketch\ntheme sketch\nA -> B",title:"Sketch theme"},{code:"terminators cross",preview:"begin A\nterminators cross",title:"Cross terminators"},{code:"terminators fade",preview:"begin A\nterminators fade",title:"Fade terminators"},{code:"terminators bar",preview:"begin A\nterminators bar",title:"Bar terminators"},{code:"terminators box",preview:"begin A\nterminators box",title:"Box terminators"}];class r{constructor(e){this.element=e}addBefore(t=null,n=null){if(null===t)return this;if(Array.isArray(t))for(const e of t)this.addBefore(e,n);else{const i=function(e,t){return"string"==typeof e?t.createTextNode(e):"number"==typeof e?t.createTextNode(e.toString(10)):"object"==typeof e&&e.element?e.element:e}(t,this.element.ownerDocument);this.element.insertBefore(i,e(n))}return this}add(...e){return this.addBefore(e,null)}del(t=null){return null!==t&&this.element.removeChild(e(t)),this}attr(e,t){return this.element.setAttribute(e,t),this}attrs(e){for(const t in e)Object.prototype.hasOwnProperty.call(e,t)&&this.element.setAttribute(t,e[t]);return this}styles(e){for(const t in e)Object.prototype.hasOwnProperty.call(e,t)&&(this.element.style[t]=e[t]);return this}setClass(e){return this.attr("class",e)}addClass(e){const t=this.element.getAttribute("class");if(!t)return this.setClass(e);const n=t.split(" ");return n.includes(e)?this:(n.push(e),this.attr("class",n.join(" ")))}delClass(e){const t=this.element.getAttribute("class");if(!t)return this;const n=t.split(" "),i=n.indexOf(e);return-1!==i&&(n.splice(i,1),this.attr("class",n.join(" "))),this}text(e){return this.element.textContent=e,this}on(e,t,n={}){if(Array.isArray(e))for(const i of e)this.on(i,t,n);else this.element.addEventListener(e,t,n);return this}off(e,t,n={}){if(Array.isArray(e))for(const i of e)this.off(i,t,n);else this.element.removeEventListener(e,t,n);return this}val(e){return this.element.value=e,this}select(e,t=null){return this.element.selectionStart=e,this.element.selectionEnd=null===t?e:t,this}focus(){return this.element.focus(),this}focussed(){return this.element===this.element.ownerDocument.activeElement}empty(){for(;this.element.childNodes.length>0;)this.element.removeChild(this.element.lastChild);return this}attach(t){return e(t).appendChild(this.element),this}detach(){return this.element.parentNode.removeChild(this.element),this}}class o{constructor(e){if(!e)throw new Error("Missing document!");this.document=e,this.wrap=this.wrap.bind(this),this.el=this.el.bind(this),this.txt=this.txt.bind(this)}wrap(e){return e.element?e:new r(e)}el(e,t=null){let n=null;return n=null===t?this.document.createElement(e):this.document.createElementNS(t,e),new r(n)}txt(e=""){return this.document.createTextNode(e)}}const a=new o(document);class l{constructor({sequenceDiagram:e,defaultCode:t="",localStorage:n="",library:i=[],links:s=[],require:r=null}){this.diagram=e,this.defaultCode=t,this.localStorage=n,this.library=i,this.links=s,this.minScale=1.5,this.require=r||(()=>null),this.debounced=null,this.latestSeq=null,this.renderedSeq=null,this.pngDirty=!0,this.updatingPNG=!1,this.marker=null,this._downloadSVGClick=this._downloadSVGClick.bind(this),this._downloadPNGClick=this._downloadPNGClick.bind(this),this._downloadPNGFocus=this._downloadPNGFocus.bind(this),this._showDropStyle=this._showDropStyle.bind(this),this._hideDropStyle=this._hideDropStyle.bind(this),this.diagram.on("render",()=>{this.updateMinSize(this.diagram.getSize()),this.pngDirty=!0}).on("mouseover",e=>{this.marker&&this.marker.clear(),void 0!==e.ln&&this.code.markText&&(this.marker=this.code.markText({ch:0,line:e.ln},{ch:0,line:e.ln+1},{className:"hover",clearOnEnter:!0,inclusiveLeft:!1,inclusiveRight:!1}))}).on("mouseout",()=>{this.marker&&(this.marker.clear(),this.marker=null)}).on("click",e=>{this.marker&&(this.marker.clear(),this.marker=null),void 0!==e.ln&&this.code.setSelection&&(this.code.setSelection({ch:0,line:e.ln},{ch:0,line:e.ln+1},{bias:-1,origin:"+focus"}),this.code.focus())}).on("dblclick",e=>{this.diagram.toggleCollapsed(e.ln)})}buildOptionsDownloads(){return this.downloadPNG=a.el("a").text("Download PNG").attrs({download:"SequenceDiagram.png",href:"#"}).on(["focus","mouseover","mousedown"],this._downloadPNGFocus).on("click",this._downloadPNGClick),this.downloadSVG=a.el("a").text("SVG").attrs({download:"SequenceDiagram.svg",href:"#"}).on("click",this._downloadSVGClick),a.el("div").setClass("options downloads").add(this.downloadPNG,this.downloadSVG)}buildLibrary(e){const t=this.library.map(t=>{const n=a.el("div").attr("title",t.title||t.code),i=a.el("div").setClass("library-item").add(n).on("click",this.addCodeBlock.bind(this,t.code)).attach(e);return this.diagram.clone({code:function(e){return"headers fade\nterminators fade\n"+e.replace(/\{Agent([0-9]*)\}/g,(e,t)=>void 0===t?"A":String.fromCharCode("A".charCodeAt(0)+Number(t)-1)).replace(/[{}]/g,"")}(t.preview||t.code),container:n.element,render:!1}).on("error",(e,s)=>{window.console.warn("Failed to render preview",s),i.attr("class","library-item broken"),n.text(t.code)})});try{this.diagram.renderAll(t)}catch(e){}return e}buildViewPane(){return this.viewPaneInner=a.el("div").setClass("pane-view-inner").add(this.diagram.dom()),this.errorMsg=a.el("div").setClass("msg-error"),a.el("div").setClass("pane-view").add(a.el("div").setClass("pane-view-scroller").add(this.viewPaneInner),this.errorMsg)}buildLeftPanes(){const e=a.el("div").setClass("pane-side");this.code=a.el("textarea").setClass("editor-simple").val(this.loadCode()||this.defaultCode).on("input",()=>this.update(!1));const t=a.el("div").setClass("pane-code").add(this.code).attach(e);if(this.library.length>0){const n=a.el("div").setClass("pane-library").add(a.el("div").setClass("pane-library-scroller").add(this.buildLibrary(a.el("div").setClass("pane-library-inner")))).attach(e);i(this.require,[t.element,n.element],{direction:"vertical",minSize:[100,5],sizes:[70,30],snapOffset:5})}return e}build(e){const t=this.buildLeftPanes(),n=this.buildViewPane();this.container=a.wrap(e).add(a.el("div").setClass("pane-hold").add(t,n,a.el("div").setClass("options links").add(this.links.map(e=>a.el("a").attrs({href:e.href,target:"_blank"}).text(e.label))),this.buildOptionsDownloads())).on("dragover",e=>{e.preventDefault(),!function(e,t){if(!e.dataTransfer.items&&0===e.dataTransfer.files.length)return[...e.dataTransfer.types].includes("Files");const n=e.dataTransfer.items||e.dataTransfer.files;return 1===n.length&&n[0].type===t}(e,"image/svg+xml")?e.dataTransfer.dropEffect="none":(e.dataTransfer.dropEffect="copy",this._showDropStyle())}).on("dragleave",this._hideDropStyle).on("dragend",this._hideDropStyle).on("drop",e=>{e.preventDefault(),this._hideDropStyle();const t=function(e,t){const n=e.dataTransfer.items||e.dataTransfer.files;if(1!==n.length||n[0].type!==t)return null;const[i]=n;return i.getAsFile?i.getAsFile():i}(e,"image/svg+xml");t&&this.loadFile(t)}),i(this.require,[t.element,n.element],{direction:"horizontal",minSize:[10,10],sizes:[30,70],snapOffset:70}),setTimeout(this.update.bind(this),0),this._enhanceEditor()}addCodeBlock(e){const n=e.split("\n").length;if(this.code.getCursor){const i=this.code.getCursor("head"),s={ch:0,line:i.line+(i.ch>0?1:0)};this.code.replaceRange(t(e),s,null,"library"),this.code.setCursor({ch:0,line:s.line+n})}else{const n=this.value(),i=this.code.element.selectionStart,s=("\n"+n+"\n").indexOf("\n",i),r=t(n.substr(0,s))+t(e);this.code.val(r+n.substr(s)).select(r.length),this.update(!1)}this.code.focus()}updateMinSize({width:e,height:t}){this.viewPaneInner.styles({minHeight:Math.ceil(t*this.minScale)+"px",minWidth:Math.ceil(e*this.minScale)+"px"})}redrawDebounced(e,t){t<=0?this.redraw(e):(clearTimeout(this.debounced),this.latestSeq=e,this.debounced=setTimeout(()=>this.redraw(e),t))}redraw(e){clearTimeout(this.debounced),this.debounced=null,this.renderedSeq=e,this.diagram.render(e)}saveCode(e){if(this.localStorage)try{window.localStorage.setItem(this.localStorage,e)}catch(e){}}loadCode(){if(!this.localStorage)return"";try{return window.localStorage.getItem(this.localStorage)||""}catch(e){return""}}markError(e){"object"==typeof e&&e.message?this.errorMsg.text(e.message):this.errorMsg.text(e),this.errorMsg.addClass("error")}markOK(){this.errorMsg.text("").delClass("error")}value(){return this.code.getDoc?this.code.getDoc().getValue():this.code.element.value}setValue(e){if(this.code.getDoc){const t=this.code.getDoc();t.setValue(e),t.clearHistory()}else this.code.val(e);this.diagram.expandAll({render:!1}),this.update(!0),this.diagram.setHighlight(null)}loadFile(e){return function(e){return new Promise(t=>{const n=new FileReader;n.addEventListener("loadend",()=>{t(n.result)},{once:!0}),n.readAsText(e)})}(e).then(e=>{const t=this.diagram.extractCodeFromSVG(e);t&&this.setValue(t)})}update(e=!0){const t=this.value();this.saveCode(t);let n=null;try{n=this.diagram.process(t)}catch(e){return void this.markError(e)}this.markOK();let i=0;if(!e&&this.renderedSeq){const e=this.renderedSeq;n.agents.length!==e.agents.length?i=500:n.stages.length!==e.stages.length&&(i=250)}this.redrawDebounced(n,i)}forceRender(){this.debounced&&(clearTimeout(this.debounced),this.redraw(this.latestSeq))}updatePNGLink(){return this.forceRender(),!(this.updatingPNG||!this.pngDirty)&&(this.pngDirty=!1,this.updatingPNG=!0,this.diagram.getPNG({resolution:4}).then(({url:e,latest:t})=>{t&&(this.downloadPNG.attr("href",e),this.updatingPNG=!1)}),!0)}_showDropStyle(){this.container.addClass("drop-target")}_hideDropStyle(){this.container.delClass("drop-target")}_downloadPNGFocus(){this.updatePNGLink()}_downloadPNGClick(e){this.updatingPNG?e.preventDefault():this.updatePNGLink()&&e.preventDefault()}_downloadSVGClick(){this.forceRender();const e=this.diagram.getSVGSynchronous();this.downloadSVG.attr("href",e)}_enhanceEditor(){this.require(["cm/lib/codemirror","cm/addon/hint/show-hint","cm/addon/edit/trailingspace","cm/addon/comment/comment"],e=>{this.diagram.registerCodeMirrorMode(e);const t=this.code.element.selectionStart,i=this.code.element.selectionEnd,s=this.code.element.value,r=this.code.focussed(),o=new e(this.code.element.parentNode,{extraKeys:{"Cmd-/":e=>e.toggleComment({padding:""}),"Cmd-Enter":"autocomplete","Ctrl-/":e=>e.toggleComment({padding:""}),"Ctrl-Enter":"autocomplete","Ctrl-Space":"autocomplete","Shift-Tab":e=>e.execCommand("indentLess"),Tab:e=>e.execCommand("indentMore")},globals:{themes:this.diagram.getThemeNames()},lineNumbers:!0,mode:"sequence",showTrailingSpace:!0,value:s});this.code.detach(),o.getDoc().setSelection(n(s,t),n(s,i));let a=0;o.on("keydown",(e,t)=>{a=t.keyCode}),o.on("change",(t,n)=>{if(this.update(!1),"+input"===n.origin){if(13===a)return void(a=0)}else if("complete"!==n.origin)return;e.commands.autocomplete(t,null,{completeSingle:!1})}),o.on("cursorActivity",()=>{const e=o.getCursor("from").line,t=o.getCursor("to").line;this.diagram.setHighlight(Math.min(e,t))}),r&&o.focus(),this.code=o})}}var d=window.SequenceDiagram;const h=window.requirejs,c={},g={},u=window.document.getElementsByTagName("meta");for(let e=0;e{t.hashes[n]&&(e.setAttribute("integrity",t.hashes[n]),e.setAttribute("crossorigin","anonymous"))},paths:c});window.addEventListener("load",()=>{const e=window.document.getElementById("loader"),[t]=e.getElementsByTagName("nav"),n=t.getElementsByTagName("a"),i=[];for(let e=0;e Goblin: You remind me of the babe\nGoblin -> Bowie: What babe?\nBowie -> Goblin: The babe with the power\nGoblin -> Bowie: What power?\nnote right of Bowie, Goblin: Most people get muddled here!\nBowie -> Goblin: "The power of voodoo"\nGoblin -> Bowie: "Who-do?"\nBowie -> Goblin: You do!\nGoblin -> Bowie: Do what?\nBowie -> Goblin: Remind me of the babe!\n\nBowie -> Audience: Sings\n\nterminators box\n',library:s,links:i,localStorage:"src",require:h,sequenceDiagram:new d});e.parentNode.removeChild(e),r.build(window.document.body)})}();
\ No newline at end of file
+!function(){"use strict";function e(e){return null===e?null:e.element?e.element:e}function t(e){return e.length>0&&"\n"!==e.charAt(e.length-1)?e+"\n":e}function n(e,t){let n=0,i=0;for(;;){const s=e.indexOf("\n",n)+1;if(t{const i=t[0].parentNode,s=i.addEventListener,r=i.removeEventListener;i.addEventListener=((e,t)=>{"mousemove"===e||"touchmove"===e?window.addEventListener(e,t,{passive:!0}):s.call(i,e,t)}),i.removeEventListener=((e,t)=>{"mousemove"===e||"touchmove"===e?window.removeEventListener(e,t):r.call(i,e,t)});let o=null;const a=Object.assign({cursor:"vertical"===n.direction?"row-resize":"col-resize",direction:"vertical",gutterSize:0,onDragEnd:()=>{document.body.style.cursor=o,o=null},onDragStart:()=>{o=document.body.style.cursor,document.body.style.cursor=a.cursor}},n);return new e(t,a)})}var s=[{code:"{Agent1} -> {Agent2}: {Message}",title:"Simple arrow (synchronous)"},{code:"{Agent1} --\x3e {Agent2}: {Message}",title:"Arrow with dotted line (response)"},{code:"{Agent1} ->> {Agent2}: {Message}",title:"Open arrow (asynchronous)"},{code:"{Agent1} -x {Agent2}: {Message}",title:"Lost message"},{code:"{Agent1} ~> {Agent2}: {Message}",title:"Wavy line"},{code:"{Agent1} -> {Agent1}: {Message}",title:"Self-connection"},{code:"{Agent1} -> ...{id}\n...{id} -> {Agent2}: {Message}",preview:"begin A, B\nA -> ...x\n...x -> B: Message",title:"Asynchronous message"},{code:"* -> {Agent1}: {Message}",title:"Found message"},{code:"{Agent1} -> +{Agent2}: {Request}\n{Agent1} <-- -{Agent2}: {Response}",title:"Request/response pair"},{code:"{Agent1} -> *{Agent2}: {Request}\n{Agent1} <-- !{Agent2}: {Response}",title:"Inline agent creation / destruction"},{code:"{Agent1} -> {Agent2}: {Request}\n{Agent1} <-- {Agent2}: {Response}\nend {Agent2}",preview:"begin A\n::\nA -> B: Request\nA <-- B: Response\nend B",title:"Agent creation / destruction"},{code:'autolabel "[] "',preview:'autolabel "[] "\nA -> B: Foo\nA <- B: Bar\nA -> B: Baz',title:"Numbered labels"},{code:"if {Condition1}\n {Agent1} -> {Agent2}\nelse if {Condition2}\n {Agent1} -> {Agent2}\nelse\n {Agent1} -> {Agent2}\nend",preview:"begin A, B\nif Condition1\n A -> B\nelse if Condition2\n A -> B\nelse\n A -> B\nend",title:"Conditional blocks"},{code:"repeat {Condition}\n {Agent1} -> {Agent2}\nend",preview:"begin A, B\nrepeat Condition\n A -> B\nend",title:"Repeated block"},{code:"begin reference: {Label} as {Name}\n{Agent1} -> {Name}\nend {Name}",preview:'begin A\nbegin reference: "See 1.3" as myRef\nA -> myRef\nmyRef -> A\nend myRef',title:"Reference"},{code:"begin reference over {Covered}: {Label} as {Name}\n{Agent1} -> {Name}\nend {Name}",preview:'begin A, B, C\nbegin reference over B, C: "See 1.3" as myRef\nA -> myRef\nmyRef -> A\nend myRef',title:"Reference over agents"},{code:"group {Label}\n {Agent1} -> {Agent2}\nend",preview:"begin A, B\ngroup Label\n A -> B\nend",title:"Group"},{code:"note over {Agent1}: {Message}",title:"Note over agent"},{code:"note over {Agent1}, {Agent2}: {Message}",title:"Note over multiple agents"},{code:"note left of {Agent1}: {Message}",title:"Note left of agent"},{code:"note right of {Agent1}: {Message}",title:"Note right of agent"},{code:"note between {Agent1}, {Agent2}: {Message}",title:"Note between agents"},{code:"state over {Agent1}: {State}",title:"State over agent"},{code:"[ -> {Agent1}: {Message1}\n{Agent1} -> ]: {Message2}",title:"Arrows to/from the sides"},{code:"text right: {Message}",preview:'A -> B\nsimultaneously:\ntext right: "Message\\non the\\nside"',title:"Text beside the diagram"},{code:"divider space with height 10: {message}",preview:"begin A, B, C, D, E, F\ndivider space with height 30: message",title:"Vertical space divider"},{code:"divider line with height 10: {message}",preview:"begin A, B, C, D, E, F\ndivider line with height 30: message",title:"Line divider"},{code:"divider delay with height 10: {message}",preview:"begin A, B, C, D, E, F\ndivider delay with height 30: message",title:"Delay divider"},{code:"divider tear with height 10: {message}",preview:"begin A, B, C, D, E, F\ndivider tear with height 30: message",title:"Tear divider"},{code:"title {Title}",preview:"headers box\ntitle Title\nA -> B",title:"Title"},{code:"**{text}**",preview:"A -> B: **bold**",title:"Bold markdown"},{code:"_{text}_",preview:"A -> B: _italic_",title:"Italic markdown"},{code:"~{text}~",preview:"A -> B: ~strikeout~",title:"Strikeout markdown"},{code:"`{text}`",preview:"A -> B: `mono`",title:"Monospace markdown"},{code:"{Agent} is red",preview:"headers box\nA is red\nbegin A",title:"Red agent line"},{code:"{Agent} is a database",preview:"headers box\nA is a database\nbegin A",title:"Database indicator"},{code:"theme monospace",preview:"headers box\ntitle mono\ntheme monospace\nA -> B",title:"Monospace theme"},{code:"theme chunky",preview:"headers box\ntitle chunky\ntheme chunky\nA -> B",title:"Chunky theme"},{code:"theme sketch",preview:"headers box\ntitle sketch\ntheme sketch\nA -> B",title:"Sketch theme"},{code:"terminators cross",preview:"begin A\nterminators cross",title:"Cross terminators"},{code:"terminators fade",preview:"begin A\nterminators fade",title:"Fade terminators"},{code:"terminators bar",preview:"begin A\nterminators bar",title:"Bar terminators"},{code:"terminators box",preview:"begin A\nterminators box",title:"Box terminators"}];class r{constructor(e){this.element=e}addBefore(t=null,n=null){if(null===t)return this;if(Array.isArray(t))for(const e of t)this.addBefore(e,n);else{const i=function(e,t){return"string"==typeof e?t.createTextNode(e):"number"==typeof e?t.createTextNode(e.toString(10)):"object"==typeof e&&e.element?e.element:e}(t,this.element.ownerDocument);this.element.insertBefore(i,e(n))}return this}add(...e){return this.addBefore(e,null)}del(t=null){return null!==t&&this.element.removeChild(e(t)),this}attr(e,t){return this.element.setAttribute(e,t),this}attrs(e){for(const t in e)Object.prototype.hasOwnProperty.call(e,t)&&this.element.setAttribute(t,e[t]);return this}styles(e){for(const t in e)Object.prototype.hasOwnProperty.call(e,t)&&(this.element.style[t]=e[t]);return this}setClass(e){return this.attr("class",e)}addClass(e){const t=this.element.getAttribute("class");if(!t)return this.setClass(e);const n=t.split(" ");return n.includes(e)?this:(n.push(e),this.attr("class",n.join(" ")))}delClass(e){const t=this.element.getAttribute("class");if(!t)return this;const n=t.split(" "),i=n.indexOf(e);return-1!==i&&(n.splice(i,1),this.attr("class",n.join(" "))),this}text(e){return this.element.textContent=e,this}on(e,t,n={}){if(Array.isArray(e))for(const i of e)this.on(i,t,n);else this.element.addEventListener(e,t,n);return this}off(e,t,n={}){if(Array.isArray(e))for(const i of e)this.off(i,t,n);else this.element.removeEventListener(e,t,n);return this}val(e){return this.element.value=e,this}select(e,t=null){return this.element.selectionStart=e,this.element.selectionEnd=null===t?e:t,this}focus(){return this.element.focus(),this}focussed(){return this.element===this.element.ownerDocument.activeElement}empty(){for(;this.element.childNodes.length>0;)this.element.removeChild(this.element.lastChild);return this}attach(t){return e(t).appendChild(this.element),this}detach(){return this.element.parentNode.removeChild(this.element),this}}class o{constructor(e){if(!e)throw new Error("Missing document!");this.document=e,this.wrap=this.wrap.bind(this),this.el=this.el.bind(this),this.txt=this.txt.bind(this)}wrap(e){return e.element?e:new r(e)}el(e,t=null){let n=null;return n=null===t?this.document.createElement(e):this.document.createElementNS(t,e),new r(n)}txt(e=""){return this.document.createTextNode(e)}}class a{constructor({sequenceDiagram:e,defaultCode:t="",localStorage:n="",library:i=[],links:s=[],require:r=null}){this.diagram=e,this.defaultCode=t,this.localStorage=n,this.library=i,this.links=s,this.minScale=1.5,this.require=r||(()=>null),this.debounced=null,this.latestSeq=null,this.renderedSeq=null,this.pngDirty=!0,this.updatingPNG=!1,this.marker=null,this._downloadSVGClick=this._downloadSVGClick.bind(this),this._downloadPNGClick=this._downloadPNGClick.bind(this),this._downloadPNGFocus=this._downloadPNGFocus.bind(this),this._showDropStyle=this._showDropStyle.bind(this),this._hideDropStyle=this._hideDropStyle.bind(this),this.diagram.on("render",()=>{this.updateMinSize(this.diagram.getSize()),this.pngDirty=!0}).on("mouseover",e=>{this.marker&&this.marker.clear(),void 0!==e.ln&&this.code.markText&&(this.marker=this.code.markText({ch:0,line:e.ln},{ch:0,line:e.ln+1},{className:"hover",clearOnEnter:!0,inclusiveLeft:!1,inclusiveRight:!1}))}).on("mouseout",()=>{this.marker&&(this.marker.clear(),this.marker=null)}).on("click",e=>{this.marker&&(this.marker.clear(),this.marker=null),void 0!==e.ln&&this.code.setSelection&&(this.code.setSelection({ch:0,line:e.ln},{ch:0,line:e.ln+1},{bias:-1,origin:"+focus"}),this.code.focus())}).on("dblclick",e=>{this.diagram.toggleCollapsed(e.ln)})}buildOptionsDownloads(){return this.downloadPNG=this.dom.el("a").text("Download PNG").attrs({download:"SequenceDiagram.png",href:"#"}).on(["focus","mouseover","mousedown"],this._downloadPNGFocus).on("click",this._downloadPNGClick),this.downloadSVG=this.dom.el("a").text("SVG").attrs({download:"SequenceDiagram.svg",href:"#"}).on("click",this._downloadSVGClick),this.dom.el("div").setClass("options downloads").add(this.downloadPNG,this.downloadSVG)}buildLibrary(e){const t=this.library.map(t=>{const n=this.dom.el("div").attr("title",t.title||t.code),i=this.dom.el("div").setClass("library-item").add(n).on("click",this.addCodeBlock.bind(this,t.code)).attach(e);return this.diagram.clone({code:function(e){return"headers fade\nterminators fade\n"+e.replace(/\{Agent([0-9]*)\}/g,(e,t)=>void 0===t?"A":String.fromCharCode("A".charCodeAt(0)+Number(t)-1)).replace(/[{}]/g,"")}(t.preview||t.code),container:n.element,render:!1}).on("error",(e,s)=>{window.console.warn("Failed to render preview",s),i.attr("class","library-item broken"),n.text(t.code)})});try{this.diagram.renderAll(t)}catch(e){}return e}buildViewPane(){return this.viewPaneInner=this.dom.el("div").setClass("pane-view-inner").add(this.diagram.dom()),this.errorMsg=this.dom.el("div").setClass("msg-error"),this.dom.el("div").setClass("pane-view").add(this.dom.el("div").setClass("pane-view-scroller").add(this.viewPaneInner),this.errorMsg)}buildLeftPanes(){const e=this.dom.el("div").setClass("pane-side");this.code=this.dom.el("textarea").setClass("editor-simple").val(this.loadCode()||this.defaultCode).on("input",()=>this.update(!1));const t=this.dom.el("div").setClass("pane-code").add(this.code).attach(e);if(this.library.length>0){const n=this.dom.el("div").setClass("pane-library").add(this.dom.el("div").setClass("pane-library-scroller").add(this.buildLibrary(this.dom.el("div").setClass("pane-library-inner")))).attach(e);i(this.require,[t.element,n.element],{direction:"vertical",minSize:[100,5],sizes:[70,30],snapOffset:5})}return e}build(e){this.dom=new o(e.ownerDocument);const t=this.buildLeftPanes(),n=this.buildViewPane();this.container=this.dom.wrap(e).add(this.dom.el("div").setClass("pane-hold").add(t,n,this.dom.el("div").setClass("options links").add(this.links.map(e=>this.dom.el("a").attrs({href:e.href,target:"_blank"}).text(e.label))),this.buildOptionsDownloads())).on("dragover",e=>{e.preventDefault(),!function(e,t){if(!e.dataTransfer.items&&0===e.dataTransfer.files.length)return[...e.dataTransfer.types].includes("Files");const n=e.dataTransfer.items||e.dataTransfer.files;return 1===n.length&&n[0].type===t}(e,"image/svg+xml")?e.dataTransfer.dropEffect="none":(e.dataTransfer.dropEffect="copy",this._showDropStyle())}).on("dragleave",this._hideDropStyle).on("dragend",this._hideDropStyle).on("drop",e=>{e.preventDefault(),this._hideDropStyle();const t=function(e,t){const n=e.dataTransfer.items||e.dataTransfer.files;if(1!==n.length||n[0].type!==t)return null;const[i]=n;return i.getAsFile?i.getAsFile():i}(e,"image/svg+xml");t&&this.loadFile(t)}),i(this.require,[t.element,n.element],{direction:"horizontal",minSize:[10,10],sizes:[30,70],snapOffset:70}),setTimeout(this.update.bind(this),0),this._enhanceEditor()}addCodeBlock(e){const n=e.split("\n").length;if(this.code.getCursor){const i=this.code.getCursor("head"),s={ch:0,line:i.line+(i.ch>0?1:0)};this.code.replaceRange(t(e),s,null,"library"),this.code.setCursor({ch:0,line:s.line+n})}else{const n=this.value(),i=this.code.element.selectionStart,s=("\n"+n+"\n").indexOf("\n",i),r=t(n.substr(0,s))+t(e);this.code.val(r+n.substr(s)).select(r.length),this.update(!1)}this.code.focus()}updateMinSize({width:e,height:t}){this.viewPaneInner.styles({minHeight:Math.ceil(t*this.minScale)+"px",minWidth:Math.ceil(e*this.minScale)+"px"})}redrawDebounced(e,t){t<=0?this.redraw(e):(clearTimeout(this.debounced),this.latestSeq=e,this.debounced=setTimeout(()=>this.redraw(e),t))}redraw(e){clearTimeout(this.debounced),this.debounced=null,this.renderedSeq=e,this.diagram.render(e)}saveCode(e){if(this.localStorage)try{window.localStorage.setItem(this.localStorage,e)}catch(e){}}loadCode(){if(!this.localStorage)return"";try{return window.localStorage.getItem(this.localStorage)||""}catch(e){return""}}markError(e){"object"==typeof e&&e.message?this.errorMsg.text(e.message):this.errorMsg.text(e),this.errorMsg.addClass("error")}markOK(){this.errorMsg.text("").delClass("error")}value(){return this.code.getDoc?this.code.getDoc().getValue():this.code.element.value}setValue(e){if(this.code.getDoc){const t=this.code.getDoc();t.setValue(e),t.clearHistory()}else this.code.val(e);this.diagram.expandAll({render:!1}),this.update(!0),this.diagram.setHighlight(null)}loadFile(e){return function(e){return new Promise(t=>{const n=new FileReader;n.addEventListener("loadend",()=>{t(n.result)},{once:!0}),n.readAsText(e)})}(e).then(e=>{const t=this.diagram.extractCodeFromSVG(e);t&&this.setValue(t)})}update(e=!0){const t=this.value();this.saveCode(t);let n=null;try{n=this.diagram.process(t)}catch(e){return void this.markError(e)}this.markOK();let i=0;if(!e&&this.renderedSeq){const e=this.renderedSeq;n.agents.length!==e.agents.length?i=500:n.stages.length!==e.stages.length&&(i=250)}this.redrawDebounced(n,i)}forceRender(){this.debounced&&(clearTimeout(this.debounced),this.redraw(this.latestSeq))}updatePNGLink(){return this.forceRender(),!(this.updatingPNG||!this.pngDirty)&&(this.pngDirty=!1,this.updatingPNG=!0,this.diagram.getPNG({resolution:4}).then(({url:e,latest:t})=>{t&&(this.downloadPNG.attr("href",e),this.updatingPNG=!1)}),!0)}_showDropStyle(){this.container.addClass("drop-target")}_hideDropStyle(){this.container.delClass("drop-target")}_downloadPNGFocus(){this.updatePNGLink()}_downloadPNGClick(e){this.updatingPNG?e.preventDefault():this.updatePNGLink()&&e.preventDefault()}_downloadSVGClick(){this.forceRender();const e=this.diagram.getSVGSynchronous();this.downloadSVG.attr("href",e)}_enhanceEditor(){this.require(["cm/lib/codemirror","cm/addon/hint/show-hint","cm/addon/edit/trailingspace","cm/addon/comment/comment"],e=>{this.diagram.registerCodeMirrorMode(e);const t=this.code.element.selectionStart,i=this.code.element.selectionEnd,s=this.code.element.value,r=this.code.focussed(),o=new e(this.code.element.parentNode,{extraKeys:{"Cmd-/":e=>e.toggleComment({padding:""}),"Cmd-Enter":"autocomplete","Ctrl-/":e=>e.toggleComment({padding:""}),"Ctrl-Enter":"autocomplete","Ctrl-Space":"autocomplete","Shift-Tab":e=>e.execCommand("indentLess"),Tab:e=>e.execCommand("indentMore")},globals:{themes:this.diagram.getThemeNames()},lineNumbers:!0,mode:"sequence",showTrailingSpace:!0,value:s});this.code.detach(),o.getDoc().setSelection(n(s,t),n(s,i));let a=0;o.on("keydown",(e,t)=>{a=t.keyCode}),o.on("change",(t,n)=>{if(this.update(!1),"+input"===n.origin){if(13===a)return void(a=0)}else if("complete"!==n.origin)return;e.commands.autocomplete(t,null,{completeSingle:!1})}),o.on("cursorActivity",()=>{const e=o.getCursor("from").line,t=o.getCursor("to").line;this.diagram.setHighlight(Math.min(e,t))}),r&&o.focus(),this.code=o})}}var l=window.SequenceDiagram;const d=window.requirejs,h={},c={},g=window.document.getElementsByTagName("meta");for(let e=0;e{t.hashes[n]&&(e.setAttribute("integrity",t.hashes[n]),e.setAttribute("crossorigin","anonymous"))},paths:h});window.addEventListener("load",()=>{const e=window.document.getElementById("loader"),[t]=e.getElementsByTagName("nav"),n=t.getElementsByTagName("a"),i=[];for(let e=0;e Goblin: You remind me of the babe\nGoblin -> Bowie: What babe?\nBowie -> Goblin: The babe with the power\nGoblin -> Bowie: What power?\nnote right of Bowie, Goblin: Most people get muddled here!\nBowie -> Goblin: "The power of voodoo"\nGoblin -> Bowie: "Who-do?"\nBowie -> Goblin: You do!\nGoblin -> Bowie: Do what?\nBowie -> Goblin: Remind me of the babe!\n\nBowie -> Audience: Sings\n\nterminators box\n',library:s,links:i,localStorage:"src",require:d,sequenceDiagram:new l});e.parentNode.removeChild(e),r.build(window.document.body)})}();
\ No newline at end of file