likec4 1.53.0 → 1.55.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/__app__/src/likec4.js +9 -5
- package/__app__/src/routes/index.js +2 -2
- package/__app__/src/style.css +1 -1
- package/__app__/src/vendors.js +4023 -2281
- package/config/schema.json +77 -92
- package/dist/THIRD-PARTY-LICENSES.md +3 -69
- package/dist/_chunks/index.d.mts +1 -1
- package/dist/_chunks/index2.d.mts +10 -20
- package/dist/_chunks/libs/@chevrotain/cst-dts-gen.mjs +7 -7
- package/dist/_chunks/libs/@hono/mcp.mjs +35 -24
- package/dist/_chunks/libs/@hono/node-server.mjs +1 -1
- package/dist/_chunks/libs/@logtape/logtape.d.mts +3 -3
- package/dist/_chunks/libs/@logtape/logtape.mjs +3 -3
- package/dist/_chunks/libs/@modelcontextprotocol/sdk.mjs +8 -8
- package/dist/_chunks/libs/@nanostores/react.d.mts +22 -17
- package/dist/_chunks/libs/@nanostores/react.mjs +1 -1
- package/dist/_chunks/libs/ajv.mjs +1 -1
- package/dist/_chunks/libs/atomically.mjs +1 -1
- package/dist/_chunks/libs/conf.mjs +1 -1
- package/dist/_chunks/libs/defu.mjs +1 -1
- package/dist/_chunks/libs/find-up-simple.mjs +1 -1
- package/dist/_chunks/libs/p-timeout.mjs +1 -0
- package/dist/_chunks/libs/package-manager-detector.mjs +1 -1
- package/dist/_chunks/libs/pathe.mjs +1 -1
- package/dist/_chunks/libs/picomatch.mjs +1 -1
- package/dist/_chunks/libs/tinyrainbow.mjs +1 -1
- package/dist/_chunks/libs/zod.d.mts +2091 -0
- package/dist/_chunks/node.mjs +76 -1
- package/dist/_chunks/src2.mjs +69 -69
- package/dist/cli/index.mjs +1228 -97
- package/dist/config/index.d.mts +1 -1
- package/dist/index.d.mts +1 -1
- package/dist/index.mjs +1 -1
- package/dist/vite-plugin/index.d.mts +1 -1
- package/dist/vite-plugin/index.mjs +1 -1
- package/dist/vite-plugin/internal.mjs +1 -1
- package/package.json +32 -31
- package/react/index.d.mts +6 -0
- package/react/index.mjs +55 -37
- package/dist/_chunks/filesystem.mjs +0 -1231
- package/dist/_chunks/libs/@modelcontextprotocol/sdk.d.mts +0 -8725
|
@@ -1,1231 +0,0 @@
|
|
|
1
|
-
import{s as e}from"./rolldown-runtime.mjs";import{$ as t,A as n,B as r,C as i,D as a,E as o,F as s,G as c,H as l,J as u,K as d,M as f,N as p,O as m,P as h,Q as g,R as _,S as ee,T as te,V as ne,W as re,X as ie,Y as v,Z as y,_ as ae,a as oe,b as se,c as ce,d as le,et as ue,f as de,g as fe,h as pe,i as me,j as he,k as ge,l as _e,m as ve,n as ye,nt as be,o as xe,p as Se,q as b,r as Ce,s as we,t as Te,tt as Ee,u as De,v as Oe,w as ke,x as Ae,y as x,z as je}from"./libs/remeda.mjs";import{a as Me,i as Ne,n as Pe,r as Fe,t as Ie}from"./libs/@logtape/logtape.mjs";import{n as Le,t as Re}from"./libs/merge-error-cause.mjs";import{t as ze}from"./libs/safe-stringify.mjs";import{t as Be}from"./libs/defu.mjs";import{n as Ve}from"./libs/pathe.mjs";import{t as He}from"./libs/tinyrainbow.mjs";import{t as Ue}from"./libs/json5.mjs";import{J as We,i as Ge,n as Ke,r as qe,t as Je}from"./libs/@hono/mcp.mjs";import{c as Ye,d as Xe,l as Ze,o as Qe,s as $e,u as et}from"./src.mjs";import{$ as tt,A as nt,B as S,C as rt,D as it,E as at,F as ot,G as st,H as C,I as ct,J as w,K as lt,L as ut,M as dt,N as ft,O as pt,P as mt,Q as ht,R as gt,S as _t,T as vt,U as yt,V as T,W as bt,X as E,Y as xt,Z as St,_ as Ct,_t as wt,at as Tt,b as Et,bt as Dt,c as Ot,ct as kt,d as At,dt as jt,et as Mt,f as Nt,ft as Pt,g as Ft,gt as It,h as Lt,ht as Rt,it as zt,j as Bt,k as Vt,l as Ht,lt as Ut,m as Wt,mt as Gt,nt as Kt,o as qt,ot as Jt,p as Yt,pt as Xt,q as Zt,rt as Qt,s as $t,st as en,tt as tn,u as nn,ut as rn,v as an,vt as on,w as sn,x as cn,y as ln,yt as un,z as dn}from"./libs/langium.mjs";import{t as fn}from"./sequence.mjs";import{n as pn,r as mn,t as D}from"./libs/ts-graphviz.mjs";import{t as hn}from"./libs/word-wrap.mjs";import{n as gn,r as _n,t as vn}from"./libs/khroma.mjs";import{t as yn}from"./libs/p-limit.mjs";import{t as bn}from"./libs/p-queue.mjs";import{t as xn}from"./libs/which.mjs";import{t as Sn}from"./libs/pretty-ms.mjs";import{t as Cn}from"./libs/picomatch.mjs";import{a as wn,d as Tn,f as En,i as Dn,l as On,n as kn,o as An,p as jn,r as Mn,t as Nn,u as Pn}from"./libs/ufo.mjs";import{A as Fn,C as In,D as Ln,E as O,O as k,S as Rn,T as A,b as j,k as zn,n as Bn,t as Vn,w as Hn,x as Un}from"./libs/@modelcontextprotocol/sdk.mjs";import{t as Wn}from"./libs/@hono/node-server.mjs";import{t as Gn}from"./libs/strip-indent.mjs";import{n as Kn,t as qn}from"./libs/unstorage.mjs";import{LikeC4Model as Jn,isDeploymentNodeModel as Yn,modelConnection as Xn}from"@likec4/core/model";import*as Zn from"@likec4/core";import{DefaultMap as Qn,Fqn as $n,FqnExpr as er,FqnRef as M,GlobalFqn as tr,LikeC4Styles as nr,LinkedList as rr,RelationExpr as ir,RichText as ar,_layout as or,_stage as sr,_type as cr,ancestorsFqn as lr,applyCachedLayout as ur,applyManualLayout as dr,calcDriftsFromSnapshot as fr,exact as pr,extractStep as mr,invariant as N,isAncestor as hr,isAndOperator as gr,isAnyOf as _r,isDeploymentNode as vr,isDeploymentView as yr,isDynamicView as br,isElementView as xr,isGlobalFqn as Sr,isNonEmptyArray as Cr,isOrOperator as wr,isSameHierarchy as Tr,nameFromFqn as Er,nonNullable as Dr,nonexhaustive as P,preferSummary as Or,splitGlobalFqn as kr}from"@likec4/core";import{LikeC4Styles as Ar,ThemeColors as jr,assignTagColors as Mr,computeColorValues as Nr}from"@likec4/core/styles";import{Fqn as Pr,FqnExpr as Fr,FqnRef as F,_stage as Ir,_type as Lr,exact as Rr,isAnyOf as zr,isExtendsElementView as Br}from"@likec4/core/types";import{DefaultMap as Vr,DefaultWeakMap as Hr,MultiMap as Ur,ancestorsFqn as Wr,compareFqnHierarchically as Gr,compareNatural as Kr,compareNaturalHierarchically as qr,delay as Jr,hierarchyDistance as Yr,ifilter as Xr,invariant as I,isNonEmptyArray as Zr,isSameHierarchy as Qr,isString as $r,memoizeProp as ei,nameFromFqn as ti,nonNullable as ni,nonexhaustive as ri,objectHash as ii,onNextTick as ai,parentFqn as oi,promiseNextTick as si,sortNaturalByFqn as ci,sortParentsFirst as li,stringHash as ui,toArray as di}from"@likec4/core/utils";import{Graph as fi}from"@likec4/core/utils/graphology";import{Graphviz as pi}from"@hpcc-js/wasm-graphviz";import mi,{SubprocessError as hi}from"nano-spawn";import gi from"node:os";import{isColorSupported as _i,isDevelopment as vi}from"std-env";import{bundleRequire as yi}from"bundle-require";import{formatMessagesSync as bi}from"esbuild";import*as xi from"node:fs/promises";import{unlink as Si,writeFile as Ci}from"node:fs/promises";import{basename as wi,dirname as Ti,resolve as Ei}from"node:path";import{fdir as Di}from"fdir";import{mkdirSync as Oi,statSync as ki}from"node:fs";import Ai from"chokidar";import{computeAdhocView as ji,computeProjectsView as Mi,computeView as Ni,resolveRulesExtendedViews as Pi}from"@likec4/core/compute-view";const Fi=e=>e.split(`
|
|
2
|
-
`).map(e=>e.trim().replace(`file://`,``));function Ii(e,t=2){e=Array.isArray(e)?e:e.split(`
|
|
3
|
-
`);let n=` `.repeat(t);return e.map(e=>`${n}${e}`).join(`
|
|
4
|
-
`)}function L(e){if(typeof e==`string`)return e;if(e instanceof Error){let t=Re(e);if(t.stack){let e=Fi(t.stack);return t.message+`
|
|
5
|
-
`+Ii(e.slice(1))}return t.message}return ze(e,{indentation:` `})}function Li(e,t){return Le(e,t)}function Ri(e){let t=Object.entries(e.properties).flatMap(([e,t])=>{if(t instanceof Error){let e=Re(t);return e.stack&&=Fi(e.stack).join(`
|
|
6
|
-
`),[e]}return e===`error`||e===`err`?[Error(L(t))]:[]});return t.length===0?null:t.length===1?t[0]:AggregateError(t)}function zi(e){let t=Ri(e);return t&&typeof e.rawMessage==`string`?Le(t,e.rawMessage+`
|
|
7
|
-
`):t}function Bi(e,t=!1){let n=Ri(e.record);if(n){let r=n.message;return n.stack&&(r=r+`
|
|
8
|
-
`+Ii(n.stack.split(`
|
|
9
|
-
`).slice(1))),t&&(r=`${Ki.red}${r}${Gi}`),{...e,message:e.message+`
|
|
10
|
-
`+Ii(r)}}return e}const Vi={trace:`TRACE`,debug:`DEBUG`,info:`INFO `,warning:`WARN `,error:`ERROR`,fatal:`FATAL`};function Hi(){return Wi({format:({message:e})=>e})}const Ui=e=>Vi[e];function Wi(e){let t=e?.format??(({timestamp:e,level:t,category:n,message:r})=>`${e} ${t} ${n} ${r}`);return Ne({timestamp:`time`,level:Ui,category:`.`,...e,format:e=>t(Bi(e))})}const Gi=`\x1B[0m`,Ki={red:`\x1B[31m`};function qi(e){let t=e?.format??(({timestamp:e,level:t,category:n,message:r})=>`${e} ${t} ${n} ${r}`);return Fe({timestamp:`time`,level:Ui,categoryStyle:`bold`,categoryColor:`cyan`,category:`.`,...e,format:e=>t(Bi(e,!0))})}function Ji(e){let t=e?.messageFormatter;return t?e=>{let{properties:n}=e;return n&&Object.keys(n).length>0?[t(e),n]:[t(e)]}:e=>{let{message:t,properties:n}=e;return n&&Object.keys(n).length>0?[...t,n]:t}}function Yi(e){return Pe({formatter:Ji(),...e})}function Xi(e){let t=e?.formatter??Ji();return e=>{let n=t(e);if(typeof n==`string`){let e=n.replace(/\r?\n$/,``);console.error(e)}else console.error(...n)}}const Zi=Me(`likec4`);function Qi(e){return Zi.getChild(e)}function $i(e){try{let{sinks:t={},loggers:n,...r}=e??{},i={console:Yi(),...t};Ie({reset:!0,...r,sinks:i,loggers:[{category:[`logtape`,`meta`],sinks:[`console`],lowestLevel:`warning`},...e?.loggers??[{category:`likec4`,sinks:[`console`],lowestLevel:`debug`}]]})}catch(e){console.error(e)}}const ea=e=>e.severity===1,ta=e=>{let t=e.split(`
|
|
11
|
-
`);return t.length>5&&(t.length=5,t.push(`...`)),t.join(`
|
|
12
|
-
`)};var na=class{langium;logger;constructor(e,t=Zi){this.langium=e,this.logger=t}get workspace(){return this.langium.shared.workspace.WorkspaceManager.workspaceUri.fsPath}get workspaceURI(){return this.langium.shared.workspace.WorkspaceManager.workspaceUri}get workspaceURL(){return this.langium.shared.workspace.WorkspaceManager.workspaceURL}get languageServices(){return this.langium.likec4.likec4.LanguageServices}get projectsManager(){return this.langium.shared.workspace.ProjectsManager}get viewsService(){return this.langium.likec4.likec4.Views}get modelBuilder(){return this.langium.likec4.likec4.ModelBuilder}get LangiumDocuments(){return this.langium.shared.workspace.LangiumDocuments}ensureSingleProject(){let e=this.languageServices.projects();if(e.length>1)throw this.logger.error(`Multiple projects found:
|
|
13
|
-
${e.map(e=>` - ${e.folder.fsPath}`).join(`
|
|
14
|
-
`)}
|
|
15
|
-
|
|
16
|
-
Please specify a project folder`),Error(`Multiple projects found`)}async diagrams(e){let t=this.projectsManager.ensureProjectId(e);return await this.viewsService.diagrams(t)}syncComputedModel(e){let t=this.projectsManager.ensureProjectId(e);return this.modelBuilder.unsafeSyncComputeModel(t)}async computedModel(e){let t=this.projectsManager.ensureProjectId(e);return await this.modelBuilder.computeModel(t)}projects(){return x(this.languageServices.projects(),De(`id`))}async layoutedModel(e){let t=this.projectsManager.ensureProjectId(e);return await this.languageServices.layoutedModel(t)}getErrors(){return[...this.LangiumDocuments.userDocuments].flatMap(e=>(e.diagnostics?.filter(ea)??[]).map(({message:t,range:n})=>({message:ta(t),line:n.start.line,range:n,sourceFsPath:e.uri.fsPath})))}hasErrors(){return this.LangiumDocuments.userDocuments.some(e=>e.diagnostics&&e.diagnostics.some(ea))}printErrors(){let e=!1;for(let t of this.LangiumDocuments.userDocuments){let n=t.diagnostics?.filter(ea)??[];if(!v(n,1))continue;e=!0;let r=y(n,l(e=>{let t=e.range.start.line;return ta(e.message).split(`
|
|
17
|
-
`).map((e,n)=>n===0?` `+He.dim(`Line ${t}: `)+He.red(e):` `.repeat(10)+He.red(e))}),ee(`
|
|
18
|
-
`));this.logger.error(`Invalid ${t.uri.fsPath}\n${r}`)}return e}documentCount(){return[...this.LangiumDocuments.userDocuments].length}onModelUpdate(e){let t=this.modelBuilder.onModelParsed(()=>e());return()=>{t.dispose()}}async format(e){let{projects:t,...n}=e??{},r={...n,...t&&{projectIds:t.map(e=>this.projectsManager.ensureProjectId(e))}};return await this.languageServices.format(r)}async dispose(){await this.languageServices.dispose()}async[Symbol.asyncDispose](){await this.dispose()}};const ra={printErrors:!0,throwIfInvalid:!1,graphviz:`wasm`,mcp:!1,configureLogger:!1,logLevel:void 0},ia=e=>Error(`Invalid model:\n${e.getErrors().map(e=>` ${e.sourceFsPath}:${e.line} ${e.message.slice(0,200)}`).join(`
|
|
19
|
-
`)}`);async function aa(e,t=Zi,n){let r=new na(e,t);return(n?.throwIfInvalid??ra.throwIfInvalid)===!0&&r.hasErrors()?(await r.dispose(),Promise.reject(ia(r))):((n?.printErrors??ra.printErrors)&&r.hasErrors()&&r.printErrors(),r)}async function oa(e,t,n,r){let i=C.from({scheme:`virtual`,path:`/workspace`}),a={name:`virtual`,uri:i.toString()},o=e.shared.workspace.WorkspaceManager;o.initialize({capabilities:{},processId:null,rootUri:a.uri,workspaceFolders:[a]}),await o.initializeWorkspace([a]);let s=e.shared.ServiceRegistry.all.flatMap(e=>e.LanguageMetaData.fileExtensions),[c,l]=de(u(n),([e])=>$e(e));for(let[n,r]of c){let a=T.joinPath(i,n);try{await e.shared.workspace.ProjectsManager.registerProject({configUri:a,config:Ze.parse(r)})}catch(e){t.error(L(e))}}let d=y(l,x(([t,n])=>{s.includes(Ve(t))||(t+=`.c4`);let r=T.joinPath(i,t);return e.shared.workspace.LangiumDocuments.createDocument(r,n)}));return await e.shared.workspace.DocumentBuilder.build(d,{validation:!0}),aa(e,t,r)}function sa(e){return e.children.length>0}function R(e){switch(e){case`open`:return`vee`;default:return e}}function ca(e){return Array.isArray(e)?[ca(e[0]),ca(e[1])]:(I(isFinite(e),`Invalid not finite point value ${e}`),Math.round(e))}const la=e=>(I(isFinite(e),`Invalid not finite inch value ${e}`),Math.floor(e*72)),z=e=>Math.ceil(e/72*1e3)/1e3,ua=e=>Math.ceil(e);ua(40).toString();function da(e,t){return _n(vn(e,{l:-35-5*t,s:-15-5*t}))}function fa(e){return _n(gn(e,.3))}var pa=e(hn(),1);function ma(e){return e.trim().replaceAll(`&`,`&`).replaceAll(`<`,`<`).replaceAll(`>`,`>`)}function ha(e,{maxchars:t,maxLines:n,sanitize:r=s()}){let i=(0,pa.default)(e,{width:t,indent:``,escape:r}).split(`
|
|
20
|
-
`);return he(n)&&n>0&&i.length>n&&(i=i.slice(0,n)),i}function ga({text:e,maxchars:t,fontsize:n,maxLines:r,bold:i,color:a}){let o=ha(e,{maxchars:t,maxLines:r,sanitize:ma}).join(`<BR/>`);i&&(o=`<B>${o}</B>`);let s=a?` COLOR="${a}"`:``;return`<FONT POINT-SIZE="${ua(n)}"${s}>${o}</FONT>`}function _a(e){switch(e){case`xs`:case`sm`:return 30;case`md`:return 40;case`lg`:case`xl`:return 55;default:ri(e)}}function va(e,t){let{sizes:{size:n},values:r}=t.nodeSizes(e.style),a=t.colors(e.color).elements,o=[`sm`,`xs`].includes(n),s=i(e.icon),c=e.style.iconPosition??`left`,l=s&&(c===`left`||c===`right`),u=[ga({text:e.title,fontsize:r.textSize,maxchars:_a(n),maxLines:o?1:3})];if(n!==`xs`){i(e.technology?.trim())&&u.push(ga({text:e.technology,fontsize:Math.ceil(r.textSize*.65),maxchars:l?35:45,maxLines:1,color:a.loContrast}));let t=ar.from(e.description).text;t&&u.push(ga({text:t,fontsize:Math.ceil(r.textSize*.75),maxchars:l?35:45,maxLines:o?3:5,color:a.loContrast}))}if(u.length===1&&s===!1)return`<${u[0]}>`;let d=l?(t,n,i)=>{let a=`<TD ALIGN="TEXT" BALIGN="LEFT">${t}</TD>`;if(n===0){let t=i.length>1?` ROWSPAN="${i.length}"`:``,n=Math.ceil(r.iconSize+16);(e.shape===`queue`||e.shape===`mobile`)&&(n+=20),c===`right`?(a=`<TD${t} WIDTH="16"> </TD>${a}`,a=`${a}<TD${t} WIDTH="${n}"> </TD>`):(a=`<TD${t} WIDTH="${n}"> </TD>${a}`,a=`${a}<TD${t} WIDTH="16"> </TD>`)}return`<TR>${a}</TR>`}:e=>`<TR><TD>${e}</TD></TR>`,f=u.map(d).join(``);if(s&&(c===`top`||c===`bottom`)){let e=`<TR><TD HEIGHT="${Math.ceil(r.iconSize+8)}"> </TD></TR>`;f=c===`top`?`${e}${f}`:`${f}${e}`}return`<<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="4">${f}</TABLE>>`}function ya(e,t){let n=ga({text:e.title.toUpperCase(),maxchars:50,fontsize:11,maxLines:1,bold:!0,color:t});return n.includes(`<BR/>`)?`<<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="0"><TR><TD ALIGN="TEXT" BALIGN="LEFT">${n}</TD></TR></TABLE>>`:`<${n}>`}const ba=`BGCOLOR="${nr.DEFAULT.relationshipColors.labelBg}A0"`;function xa({label:e,technology:t}){let n=[];return i(e?.trim())&&n.push(ga({text:e,maxchars:40,fontsize:14,maxLines:5,bold:e===`[...]`})),i(t?.trim())&&n.push(ga({text:`[ ${t} ]`,fontsize:12,maxLines:1,maxchars:40})),n.length===0?null:`<<TABLE BORDER="0" CELLPADDING="3" CELLSPACING="0" ${ba}>${n.map(e=>`<TR><TD ALIGN="TEXT" BALIGN="LEFT">${e}</TD></TR>`).join(``)}</TABLE>>`}function Sa(e,t){let n=`<TABLE BORDER="0" CELLPADDING="6" ${ba}><TR><TD WIDTH="20" HEIGHT="20"><FONT POINT-SIZE="${ua(14)}"><B>${e}</B></FONT></TD></TR></TABLE>`;return i(t?.trim())?`<${[`<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">`,`<TR>`,`<TD>${n}</TD>`,`<TD ${ba} CELLPADDING="3">`,ga({text:t,maxchars:40,fontsize:14,maxLines:5}),`</TD>`,`</TR>`,`</TABLE>`].join(``)}>`:`<${n}>`}const Ca=`dashed`,wa=`Arial`,Ta=Qi(`dot`),Ea=50.1;var Da=class{ids=new Set;subgraphs=new Map;nodes=new Map;edges=new Map;compoundIds;edgesWithCompounds;graphology=new fi({allowSelfLoops:!0,multi:!0,type:`directed`});graphvizModel;constructor(e,t){this.view=e,this.styles=t,this.compoundIds=new Set(e.nodes.filter(sa).map(e=>e.id)),this.edgesWithCompounds=new Set(this.compoundIds.size>0?e.edges.filter(e=>this.compoundIds.has(e.source)||this.compoundIds.has(e.target)).map(e=>e.id):[]);for(let t of e.nodes)this.graphology.addNode(t.id,{origin:t,level:t.level,depth:t.depth??0,modelRef:t.modelRef??null,deploymentRef:t.deploymentRef??null,maxConnectedHierarchyDistance:0});for(let t of e.edges){let e=this.graphology.getNodeAttribute(t.source,`deploymentRef`),n=this.graphology.getNodeAttribute(t.target,`deploymentRef`);(e===null||n===null)&&(e=this.graphology.getNodeAttribute(t.source,`modelRef`),n=this.graphology.getNodeAttribute(t.target,`modelRef`));let r=-1;e!==null&&n!==null&&(r=Yr(e,n)),this.graphology.addEdgeWithKey(t.id,t.source,t.target,{origin:t,hierarchyDistance:r,weight:1}),r>this.graphology.getNodeAttribute(t.source,`maxConnectedHierarchyDistance`)&&this.graphology.mergeNodeAttributes(t.source,{maxConnectedHierarchyDistance:r}),r>this.graphology.getNodeAttribute(t.target,`maxConnectedHierarchyDistance`)&&this.graphology.mergeNodeAttributes(t.target,{maxConnectedHierarchyDistance:r})}this.graphology.forEachEdge((e,{hierarchyDistance:t},n,r,i,a)=>{let o=Math.max(i.maxConnectedHierarchyDistance,a.maxConnectedHierarchyDistance);if(o>t)this.graphology.mergeEdgeAttributes(e,{weight:o-t+1});else{let i=this.graphology.directedDegree(n),a=this.graphology.directedDegree(r);i===1&&a===1&&t>1&&this.graphology.mergeEdgeAttributes(e,{weight:t})}});let n=this.graphvizModel=this.createGraph();this.applyNodeAttributes(n.attributes.node),this.applyEdgeAttributes(n.attributes.edge),this.build(n),this.postBuild(n)}get $defaults(){return this.styles.defaults}get hasEdgesWithCompounds(){return this.edgesWithCompounds.size>0}get defaultRelationshipColors(){let e=this.styles.relationshipColors;return{line:e.line,label:e.label,labelBg:e.labelBg}}postBuild(e){}build(e){let t=(e,n)=>{let r=this.generateGraphvizId(e),i=this.elementToSubgraph(e,n.subgraph(r));this.subgraphs.set(e.id,i);for(let n of e.children){let e=this.computedNode(n);if(sa(e))t(e,i);else{let t=ni(this.getGraphNode(e.id),`Graphviz Node not found for ${e.id}`);i.node(t.id)}}},n=[];for(let t of this.view.nodes)if(sa(t))a(t.parent)&&n.push(t);else{let n=this.generateGraphvizId(t),r=this.elementToNode(t,e.node(n));this.nodes.set(t.id,r)}for(let r of n)t(r,e);for(let t of this.view.edges){let n=this.addEdge(t,e);n&&this.edges.set(t.id,n)}}print(){return mn(this.graphvizModel,{print:{indentStyle:`space`,indentSize:2}})}createGraph(){let e=this.view.autoLayout,t=pn({[D.likec4_viewId]:this.view.id,[D.bgcolor]:`transparent`,[D.layout]:`dot`,[D.compound]:!0,[D.rankdir]:e.direction,[D.TBbalance]:`min`,[D.splines]:`spline`,[D.outputorder]:`nodesfirst`,[D.nodesep]:z(e.nodeSep??110),[D.ranksep]:z(e.rankSep??120),[D.pad]:z(15),[D.fontname]:wa});return t.attributes.graph.apply({[D.fontsize]:ua(this.styles.fontSize()),[D.labeljust]:e.direction===`RL`?`r`:`l`,[D.labelloc]:e.direction===`BT`?`b`:`t`,[D.margin]:Ea}),t}applyNodeAttributes(e){let t=this.styles.elementColors;e.apply({[D.fontname]:wa,[D.shape]:`rect`,[D.fillcolor]:t.fill,[D.fontcolor]:t.hiContrast,[D.color]:t.stroke,[D.style]:`filled`,[D.penwidth]:0})}applyEdgeAttributes(e){let t=this.defaultRelationshipColors;e.apply({[D.arrowsize]:.75,[D.fontname]:wa,[D.fontsize]:ua(14),[D.penwidth]:ua(2),[D.color]:t.line,[D.fontcolor]:t.label})}checkNodeId(e,t=!1){return t?e=`cluster_`+e:e.toLowerCase().startsWith(`cluster`)&&(e=`nd_`+e),this.ids.has(e)?null:(this.ids.add(e),e)}generateGraphvizId(e){let t=sa(e),n=ti(e.id).toLowerCase(),r=this.checkNodeId(n,t);if(r!==null)return r;n=ti(e.id).toLowerCase();let i=1;do r=this.checkNodeId(n+`_`+ i++,t);while(r===null);return r}elementToSubgraph(e,t){I(sa(e),`node should be compound`),I(o(e.depth),`node.depth should be defined`);let r=this.styles.colors(e.color).elements,i=fa(r.loContrast);return t.apply({[D.likec4_id]:e.id,[D.likec4_level]:e.level,[D.likec4_depth]:e.depth,[D.fillcolor]:da(r.fill,e.depth),[D.color]:da(r.stroke,e.depth),[D.style]:`filled`,[D.margin]:ua(e.children.length>1?40:32)}),n(e.title.trim())||t.set(D.label,ya(e,i)),t}elementToNode(e,t){I(!sa(e),`node should not be compound`);let n=i(e.icon),r=this.styles.colors(e.color).elements,{values:{padding:a,sizes:{width:o,height:s}}}=this.styles.nodeSizes(e.style),c=n?8:a;switch(t.attributes.apply({[D.likec4_id]:e.id,[D.likec4_level]:e.level,[D.label]:va(e,this.styles),[D.margin]:`${z(c)},${z(a)}`}),t.attributes.set(D.width,z(o)),t.attributes.set(D.height,z(s)),this.styles.isDefaultColor(e.color)||t.attributes.apply({[D.fillcolor]:r.fill,[D.fontcolor]:r.hiContrast,[D.color]:r.stroke}),e.shape){case`cylinder`:case`storage`:t.attributes.apply({[D.margin]:`${z(c)},${z(0)}`,[D.penwidth]:ua(2),[D.shape]:`cylinder`});break;case`browser`:t.attributes.apply({[D.margin]:`${z(n?c:c+4)},${z(a+6)}`});break;case`mobile`:t.attributes.apply({[D.margin]:`${z(n?c:c+4)},${z(a)}`});break;case`queue`:t.attributes.apply({[D.width]:z(o),[D.height]:z(s-8),[D.margin]:`${z(n?c:c+4)},${z(a)}`});break;case`component`:t.attributes.apply({[D.width]:z(o+10),[D.margin]:`${z(c+20)},${z(a)}`});break;default:break}return t}leafElements(e){return e===null?this.view.nodes.filter(e=>!sa(e)):this.computedNode(e).children.flatMap(e=>{let t=this.computedNode(e);return sa(t)?this.leafElements(t.id):t})}descendants(e){return e===null?this.view.nodes.slice():this.computedNode(e).children.flatMap(e=>{let t=this.computedNode(e);return[t,...this.descendants(t.id)]})}computedNode(e){return ni(this.view.nodes.find(t=>t.id===e),`Node ${e} not found`)}getGraphNode(e){return this.nodes.get(e)??null}getSubgraph(e){return this.subgraphs.get(e)??null}edgeEndpoint(e,t){let n=this.computedNode(e),r=this.getGraphNode(e),i;return r?[n,r,void 0]:(I(sa(n),`endpoint node should be compound`),i=this.getSubgraph(e)?.id,I(i,`subgraph ${e} not found`),n=ni(t(this.leafElements(e)),`leaf element in ${e} not found`),r=ni(this.getGraphNode(n.id),`source graphviz node ${n.id} not found`),[n,r,i])}findInternalEdges(e){if(e===null)return this.view.edges.slice();let t=this.computedNode(e);return y(this.descendants(e),l(e=>g(e.inEdges,e.outEdges)),Ce(),ie(g(t.inEdges,t.outEdges)),x(e=>this.view.edges.find(t=>t.id===e)),b(i))}withoutCompoundEdges(e){return this.edgesWithCompounds.size===0?e:{...e,inEdges:e.inEdges.filter(e=>!this.edgesWithCompounds.has(e)),outEdges:e.outEdges.filter(e=>!this.edgesWithCompounds.has(e))}}assignGroups(){let e=y(this.view.nodes,b(sa),x(e=>e.id),xe(Gr),we(),x(e=>({id:e,edges:this.findInternalEdges(e).filter(e=>e.source!==e.target&&!this.compoundIds.has(e.source)&&!this.compoundIds.has(e.target))})),b(({edges:e})=>e.length>1&&e.length<8),oe(4)),t=new Set;for(let n of e){let e=n.edges.filter(e=>!t.has(e.source)&&!t.has(e.target));for(let r of e)try{let e=ni(this.getGraphNode(r.source),`Graphviz Node not found for ${r.source}`),i=ni(this.getGraphNode(r.target),`Graphviz Node not found for ${r.target}`);t.add(r.source),t.add(r.target),e.attributes.set(D.group,n.id),i.attributes.set(D.group,n.id)}catch(e){Ta.error(`Failed to assign group to edge ${r.id}`,{error:e})}}}applyManualLayout({height:e,...t}){let n=t.x<0?-t.x:0;t.y<0&&-t.y;for(let{id:r,...i}of t.nodes){let t=this.getGraphNode(r);if(!t)continue;let a=z(i.center.x)+n,o=z(e-i.center.y);i.fixedsize?t.attributes.apply({[D.pos]:`${a},${o}!`,[D.pin]:!0,[D.width]:z(i.fixedsize.width),[D.height]:z(i.fixedsize.height),[D.fixedsize]:!0}):t.attributes.set(D.pos,`${a},${o}`)}for(let[,e]of this.edges.entries())e.attributes.delete(D.weight),e.attributes.delete(D.minlen),e.attributes.delete(D.constraint);return this.graphvizModel.apply({[D.layout]:`fdp`,[D.overlap]:`vpsc`,[D.sep]:`+50,50`,[D.esep]:`+10,10`,[D.start]:`random2`,[D.splines]:`compound`,[D.K]:10}),this.graphvizModel.delete(D.compound),this.graphvizModel.delete(D.rankdir),this.graphvizModel.delete(D.nodesep),this.graphvizModel.delete(D.ranksep),this.graphvizModel.delete(D.pack),this.graphvizModel.delete(D.pad),this.graphvizModel.delete(D.packmode),this.graphvizModel.attributes.graph.delete(D.margin),this}},Oa=class extends Da{createGraph(){let e=super.createGraph(),t=this.view.autoLayout;return e.delete(D.TBbalance),e.apply({[D.nodesep]:z(t.nodeSep??130),[D.ranksep]:z(t.rankSep??130)}),e}postBuild(e){y(this.view.nodes,x(e=>({node:e,graphvizNode:this.getGraphNode(e.id)})),_(({node:e,graphvizNode:t})=>{if(t!=null)return e.modelRef}),Te(),x(e=>e),ne(t=>{t.length<2||e.subgraph({[D.rank]:`same`},e=>{for(let{graphvizNode:n}of t)e.node(ni(n).id)})}),me(()=>{e.set(D.newrank,!0),e.set(D.clusterrank,`global`),e.delete(D.pack),e.delete(D.packmode)}))}elementToSubgraph(e,t){let n=super.elementToSubgraph(e,t);return e.children.length>1&&n.set(D.margin,ua(50)),n}addEdge(e,t){let[n,r]=[e.source,e.target],[i,a,o]=this.edgeEndpoint(n,e=>se(e)),[s,c,l]=this.edgeEndpoint(r,re),u=m(l)||m(o),d=t.edge([a,c],{[D.likec4_id]:e.id,[D.style]:e.line??Ca});l&&d.attributes.set(D.lhead,l),o&&d.attributes.set(D.ltail,o);let f=this.graphology.getEdgeAttribute(e.id,`weight`);f>1&&!this.graphology.hasDirectedEdge(e.target,e.source)&&d.attributes.set(D.weight,f);let p=xa(e);if(p&&d.attributes.set(u?D.xlabel:D.label,p),e.color&&e.color!==this.$defaults.relationship.color){let t=this.styles.colors(e.color).relationships;d.attributes.apply({[D.color]:t.line,[D.fontcolor]:t.label})}let[h,g]=[e.head??this.$defaults.relationship.arrow,e.tail??`none`];return h===`none`&&g===`none`?(d.attributes.apply({[D.arrowtail]:`none`,[D.arrowhead]:`none`,[D.dir]:`none`}),d):e.dir===`both`?(d.attributes.apply({[D.arrowhead]:R(h),[D.arrowtail]:R(e.tail??h),[D.dir]:`both`}),!u&&i.modelRef!==s.modelRef&&d.attributes.set(D.constraint,!1),d):(h&&d.attributes.set(D.arrowhead,R(h)),g!==`none`&&d.attributes.set(D.arrowtail,R(g)),d)}},ka=class extends Da{postBuild(e){e.delete(D.TBbalance),e.set(D.ordering,`in`)}addEdge(e,t){let{nodes:n}=this.view,[r,a]=e.dir===`back`?[e.target,e.source]:[e.source,e.target],[o,s,c]=this.edgeEndpoint(r,e=>se(e)),[l,u,d]=this.edgeEndpoint(a,re),f=t.edge([s,u],{[D.likec4_id]:e.id,[D.style]:e.line??Ca});if(d&&f.attributes.set(D.lhead,d),c&&f.attributes.set(D.ltail,c),e.color&&e.color!==this.$defaults.relationship.color){let t=this.styles.colors(e.color).relationships;f.attributes.apply({[D.color]:t.line,[D.fontcolor]:t.label})}let p=[e.label?.trim(),e.technology?.trim()].filter(i).join(`
|
|
21
|
-
`),m=Sa(mr(e.id),p);f.attributes.set(D.label,m);let h=n.findIndex(e=>e.id===r);n.findIndex(e=>e.id===a)<h&&e.dir!==`back`&&f.attributes.apply({[D.minlen]:0});let[g,_]=[e.head??this.$defaults.relationship.arrow,e.tail??`none`];return e.dir===`back`?(f.attributes.apply({[D.arrowtail]:R(g),[D.dir]:`back`}),_!==`none`&&f.attributes.apply({[D.arrowhead]:R(_),[D.minlen]:0}),f):g===`none`&&_===`none`||g!==`none`&&_!==`none`?(f.attributes.apply({[D.arrowhead]:R(g),[D.arrowtail]:R(_),[D.dir]:`both`}),f):g===`none`?(f.attributes.delete(D.arrowhead),f.attributes.apply({[D.arrowtail]:R(_),[D.minlen]:0,[D.dir]:`back`}),f):(f.attributes.set(D.arrowhead,R(g)),f)}};const Aa=Qi(`dot.rank`);var ja=class extends Da{postBuild(e){this.assignGroups();let t=new Set,n=this.view.nodes.reduce((e,n)=>(sa(n)&&(t.add(n.id),e.push(n)),e),[]),r=!1;for(let e of n){let t=y(e.children,b(e=>!this.compoundIds.has(e)),x(e=>this.computedNode(e)),b(e=>e.inEdges.length===0&&e.outEdges.length===0));if(t.length<=2)continue;let n=2;switch(!0){case t.length>11:n=4;break;case t.length>4:n=3;break}let i=ni(this.getSubgraph(e.id),`Subgraph not found for ${e.id}`),a=null;ue(t,n).forEach(e=>{let t=e.length>1?i.createSubgraph({[D.rank]:`same`}):null;e.forEach((e,n)=>{let r=this.getGraphNode(e.id);r&&(t?.node(r.id),n===0&&(a&&i.edge([a,r],{[D.style]:`invis`}),a=r))}),r||=!!t})}let i=this.applyExplicitRankBlocks(e);r&&(e.set(D.newrank,!0),e.set(D.clusterrank,`global`)),i>0&&e.set(`likec4_rankBlocks`,i)}applyExplicitRankBlocks(e){let t=this.view.ranks??[];if(t.length===0)return 0;let n=0;for(let r of t){let t=[...new Set(r.nodes)].map(e=>this.getGraphNode(e)).filter(e=>!!e);if(t.length===0)continue;let i=e.createSubgraph({[D.rank]:r.type});t.forEach(e=>i.node(e.id)),n+=1,Aa.debug`rank ${r.type} => ${t.map(e=>e.id).join(`, `)}`}return n}addEdge(e,t){let[n,r]=e.dir===`back`?[e.target,e.source]:[e.source,e.target],[i,a,o]=this.edgeEndpoint(n,e=>se(e)),[s,c,l]=this.edgeEndpoint(r,re),u=e.parent,d=this.graphology.getEdgeAttributes(e.id),f=t.edge([a,c],{[D.likec4_id]:e.id,[D.style]:e.line??Ca});l&&f.attributes.set(D.lhead,l),o&&f.attributes.set(D.ltail,o);let p=m(l)||m(o);!this.graphology.hasDirectedEdge(e.target,e.source)&&d.weight>1&&f.attributes.set(D.weight,d.weight);let h=xa(e);if(h&&f.attributes.set(p?D.xlabel:D.label,h),e.color&&e.color!==this.$defaults.relationship.color){let t=this.styles.colors(e.color).relationships;f.attributes.apply({[D.color]:t.line,[D.fontcolor]:t.label})}let[g,_]=[e.head??this.$defaults.relationship.arrow,e.tail??`none`];if(e.dir===`back`)return f.attributes.apply({[D.arrowtail]:R(g),[D.dir]:`back`}),_!==`none`&&f.attributes.apply({[D.arrowhead]:R(_),[D.dir]:`both`,[D.minlen]:0}),f;if(g===`none`&&_===`none`)return f.attributes.apply({[D.arrowtail]:`none`,[D.arrowhead]:`none`,[D.dir]:`none`,[D.minlen]:0,[D.constraint]:!1}),f;if(g!==`none`&&_!==`none`)return f.attributes.apply({[D.arrowhead]:R(g),[D.arrowtail]:R(_),[D.dir]:`both`}),f;if(f.attributes.set(D.arrowhead,R(g)),_!==`none`&&f.attributes.set(D.arrowtail,R(_)),this.view.edges.length===1)return f;let ee;return ee=u===null&&i.parent==null&&s.parent==null?this.view.edges.filter(t=>{if(t.id===e.id||t.parent!==null||t.source===e.source&&t.target===e.target||t.source===e.target&&t.target===e.source)return!1;let n=this.computedNode(t.source),r=this.computedNode(t.target);return sa(n)||sa(r)?!1:n.parent==null&&r.parent==null}):this.findInternalEdges(u).filter(t=>!(t.id===e.id||t.source===e.source&&t.target===e.target||t.source===e.target&&t.target===e.source)),ee.length===0&&(u===null||this.leafElements(u).length<=3)&&f.attributes.set(D.minlen,0),f}};function Ma(e){let[t,n,r,i]=e?e.split(`,`).map(e=>ca(+e)):[0,0,0,0],a=Math.round(r-t),o=Math.round(n-i);return{x:Math.round(t),y:Math.round(i),width:a,height:o}}function Na(e){try{let[t,n]=e.split(`,`);return{x:ca(parseFloat(t)),y:ca(parseFloat(n))}}catch(t){throw Error(`Failed on parsing pos: ${e}`,{cause:t})}}function Pa(e){let{x:t,y:n}=Na(e.pos),r=la(parseFloat(e.width)),i=la(parseFloat(e.height));return{x:t-Math.round(r/2),y:n-Math.round(i/2),width:r,height:i}}function Fa(e,[t,n]=[0,0]){if(!e||e.length===0)return null;let r=1/0,i=1/0,a=-1/0,o=-1/0,s=13;try{for(let c of e){if(c.op===`F`){s=ca(c.size);continue}if(c.op===`T`){let e=ca(c.pt[0])-t,l=ca(c.width);switch(c.align){case`r`:e-=l;break;case`c`:e-=Math.round(l/2);break}r=Math.min(r,e),a=Math.max(a,e+l);let u=ca(c.pt[1])-n;i=Math.min(i,Math.round(u-s)),o=Math.max(o,u)}}}catch(t){return Zi.warn(`Failed on parsing label draw ops:
|
|
22
|
-
{labelDrawOps}`,{e:t,labelDrawOps:e}),null}return r===1/0?null:{x:r-2,y:i-2,width:a-r+4,height:o-i+4}}function Ia({_draw_:e,likec4_id:t=`???`},n=`<unknown view>`){try{let r=e.filter(e=>e.op.toLowerCase()===`b`);I(v(r,1),`view ${n} edge ${t} should have at least one bezier draw op`),r.length>1&&Zi.warn(`view ${n} edge ${t} has more than one bezier draw op, using the first one only`);let i=r[0].points.map(e=>ca(e));return I(v(i,2),`view ${n} edge ${t} should have at least two points`),i}catch(r){throw Error(`failed on parsing view ${n} edge ${t} _draw_:\n${JSON.stringify(e,null,2)}`,{cause:r})}}function La(e,{id:t,source:n,target:r,dir:a,label:o,description:s,...c},l){let u=Fa(e._ldraw_??e._tldraw_??e._hldraw_),d=e.dir===`back`||a===`back`;return o=o&&u?ha(o,{maxchars:40,maxLines:5}).join(`
|
|
23
|
-
`):null,{id:t,source:n,target:r,label:o,...i(s)&&{description:s},points:Ia(e,l),labelBBox:u,...d?{dir:`back`}:{},...c}}function Ra(e,t){let n=Ma(e.bb),{nodes:r,edges:i,hasManualLayout:a,...o}=t,s=[],c=[],l;if(l=o._type===`dynamic`?{...o,sequenceLayout:{actors:[],compounds:[],parallelAreas:[],steps:[],bounds:n},[sr]:`layouted`,bounds:n,nodes:s,edges:c}:{...o,[sr]:`layouted`,bounds:n,nodes:s,edges:c},a){let e=l;e[or]=`auto`}let u=e.objects??[];for(let e of r){let t=u.find(t=>t.likec4_id===e.id);I(t,`View ${o.id} node ${e.id} not found in graphviz output`);try{let{x:n,y:r,width:i,height:a}=`bb`in t?Ma(t.bb):Pa(t),o=[n,r];s.push({...e,x:n,y:r,width:i,height:a,labelBBox:Fa(t._ldraw_,o)??{x:n,y:r,width:i,height:a}})}catch(n){throw Error(`Failed on parsing node ${e.id}:\n${JSON.stringify(t,null,2)}`,{cause:n})}}let d=e.edges??[];for(let e of i){let t=d.find(t=>t.likec4_id===e.id);if(!t){Zi.warn`View ${o.id} edge ${e.id} not found in graphviz output, skipping`;continue}c.push(La(t,e,o.id))}return l}function za(e,t){return Ra(e,t)}var Ba=class e extends Da{static toDot(t){return new e(t).print()}constructor(e){super(e,Ar.DEFAULT)}createGraph(){let e=super.createGraph();return e.apply({[D.nodesep]:z(100),[D.ranksep]:z(100)}),e.delete(D.TBbalance),e}elementToNode(e,t){return t.attributes.apply({[D.likec4_id]:e.id,[D.likec4_project]:e.projectId}),super.elementToNode(e,t)}addEdge(e,t){let n=ni(this.getGraphNode(e.source),`Node not found for ${e.source}`),r=ni(this.getGraphNode(e.target),`Node not found for ${e.target}`),i=this.graphology.getEdgeAttributes(e.id),a=t.edge([n,r],{[D.likec4_id]:e.id,[D.likec4_project]:e.projectId,[D.style]:e.line??Ca});!this.graphology.hasDirectedEdge(e.target,e.source)&&i.weight>1&&a.attributes.set(D.weight,i.weight);let o=xa(e);if(o&&a.attributes.set(D.label,o),e.color&&e.color!==this.$defaults.relationship.color){let t=this.styles.colors(e.color).relationships;a.attributes.apply({[D.color]:t.line,[D.fontcolor]:t.label})}return a}};const Va=yn(1);var Ha=class e{static opsCount=0;get name(){return`wasm`}get concurrency(){return 1}dispose(){pi.unload()}[Symbol.dispose](){this.dispose()}async attempt(t,n,r){return await Va(async()=>{let i=Zi.getChild([`graphviz`,`wasm`,t,_e(4)]);try{i.trace`execute`;let t=await r();return++e.opsCount>=20&&(e.opsCount=0,i.trace`reached 20 operations, unloading wasm`,pi.unload()),t}catch(t){i.debug(`FAILED DOT`,{dot:n}),i.error(L(t)),e.opsCount=0,pi.unload()}i.warn(`Retrying...`);try{return await Jr(30,300),await r()}catch(e){return i.error(L(e)),Promise.reject(e)}})}async unflatten(e){return await this.attempt(`unflatten`,e,async()=>(await pi.load()).unflatten(e,1,!1,3).replaceAll(/\t\[/g,` [`).replaceAll(/\t/g,` `))}async acyclic(e){return await this.attempt(`acyclic`,e,async()=>{let t=(await pi.load()).acyclic(e,!0);return t.acyclic&&t.outFile||e})}async layoutJson(e){return await this.attempt(`layout`,e,async()=>(await pi.load()).layout(e,`json`,void 0,{yInvert:!0}))}async svg(e){return await this.attempt(`svg`,e,async()=>(await pi.load()).layout(e,`svg`))}};const Ua=({view:e,styles:t})=>{switch(!0){case br(e):return new ka(e,t);case yr(e):return new Oa(e,t);case xr(e):return new ja(e,t);default:ri(e)}},Wa=Zi.getChild(`layouter`);var Ga=class{graphviz;constructor(e){this.graphviz=e??new Ha,Wa.trace`created with port ${this.graphviz.name}`}dispose(){this.graphviz.dispose()}[Symbol.dispose](){this.dispose()}get graphvizPort(){return this.graphviz}changePort(e){this.graphviz.dispose(),this.graphviz=e,Wa.trace`change port to ${this.graphviz.name}`}printToDot(e){return Ua(e).print()}async dotToJson(e){let t=Wa.getChild([`dotToJson`,_e(3)]),n;try{n=await this.graphviz.layoutJson(e)}catch(n){throw t.error(L(n)),t.error`Failed to convert DOT to JSON:\n${e}`,n}try{return JSON.parse(n)}catch(r){throw t.error(L(r)),t.error`Failed to parse JSON:\n${n}\n. Generated from DOT:\n${e}`,r}}async layout(e){let t=Wa.getChild([`layout`,_e(3)]);try{t.debug`layouting view ${e.view.id}...`;let n=await this.dot(e),{view:r}=e,i=Ra(await this.dotToJson(n),r);return br(i)&&Object.assign(i,{sequenceLayout:fn(i)}),n=n.split(`
|
|
24
|
-
`).filter(e=>!(e.includes(`margin`)&&e.includes(`${Ea}`))).join(`
|
|
25
|
-
`),t.debug`layouting view ${e.view.id} done`,{dot:n,diagram:i}}catch(n){throw t.warn(L(n)),Li(n,`Error during layout: ${e.view.id}`)}}async svg(e){let t=await this.dot(e);return t=t.split(`
|
|
26
|
-
`).filter(e=>!(e.includes(`margin`)&&e.includes(`${Ea}`))).join(`
|
|
27
|
-
`),{svg:await this.graphviz.svg(t),dot:t}}async dot(e){let t=Wa.getChild([`dot`,_e(3)]);t.trace`generating dot for view ${e.view.id}`;let n=Ua(e).print();if(!xr(e.view))return n;try{return t.trace`unflattening dot`,await this.graphviz.unflatten(n)}catch(r){return t.warn(`Error during unflatten: ${e.view.id}`,{error:r}),n}}async layoutProjectsView(e){let t=Wa.getChild([`layoutProjectsView`,_e(3)]);t.debug`layouting projects overview...`;let n=new Ba(e).print();try{n=await this.graphviz.unflatten(n)}catch(e){t.warn(`Error during unflatten of projects view`,{error:e})}let r=await this.dotToJson(n);return t.debug`layouting projects overview done`,za(r,e)}};const Ka=Zi.getChild([`layouter-queue`]);var qa=class extends Ga{queue;isProcessingBatch=!1;constructor(e){super(e?.graphviz),this.queue=new bn({concurrency:e?.concurrency??this.graphvizPort.concurrency,timeout:e?.timeout??2e4,throwOnTimeout:e?.throwOnTimeout??!0})}async runInQueue(e){let t=Ka.getChild([`run`,_e(3)]);return this.isProcessingBatch?(t.debug`waiting for batch to finish`,await this.queue.onIdle(),await si(),t.trace`try runInQueue again`,await this.runInQueue(e)):(await this.waitForQueueToShrink(this.queue.concurrency,t),Ka.trace`add task to queue`,await this.queue.add(e))}changePort(e){super.changePort(e),this.queue.concurrency!==e.concurrency&&(this.queue.concurrency=this.graphvizPort.concurrency,Ka.debug`set queue concurrency to ${this.graphvizPort.concurrency}`)}async layout(e){let t=await this.runInQueue(async()=>await super.layout(e));if(!t)throw Error(`QueueGraphvizLayoter: layout failed`);return t}async layoutProjectsView(e){let t=await this.runInQueue(async()=>await super.layoutProjectsView(e));if(!t)throw Error(`QueueGraphvizLayoter: layoutProjectsView failed`);return t}async batchLayout(e){let t=Ka.getChild([`batch`,_e(3)]);if(this.isProcessingBatch)return t.debug`wait for previous layouts to finish`,await this.queue.onIdle(),await si(),e.cancelToken?.isCancellationRequested?(t.debug`cancellation requested`,[]):(t.debug`retry`,await this.batchLayout(e));let n=this.queue.concurrency;t.debug`starting, batch size: ${e.batch.length}, concurrency: ${n}`,this.isProcessingBatch=!0;let r=[];try{for(let i of e.batch)if(t.debug`add task for view ${i.view.id}`,this.queue.add(async()=>(n<=2&&await si(),await super.layout(i))).then(t=>{if(!t){e.onError?.(i,Error(`Layout queue returned null for view ${i.view.id}`));return}r.push(t),e.onSuccess?.(i,t)}).catch(n=>{t.error(`Fail layout view ${i.view.id}`,{err:n}),e.onError?.(i,n)}),await this.waitForQueueToShrink(n,t),e.cancelToken?.isCancellationRequested){t.debug`cancellation requested`;break}}finally{let e=this.queue.pending+this.queue.size;e>0&&(t.trace`waiting ${e} tasks to finish`,await this.queue.onIdle()),t.debug`batch layout done`,this.isProcessingBatch=!1}return r}async waitForQueueToShrink(e=this.queue.concurrency,t=Ka){this.queue.size>e+2&&(t.debug`limit reached. queue size: ${this.queue.size}, running: ${this.queue.pending}, waiting shrink to ${e}`,await this.queue.onSizeLessThan(e+1))}dispose(){this.queue.clear(),super.dispose()}},Ja=e(xn(),1);const Ya=Zi.getChild([`graphviz`,`binary`]);var Xa=class{_dotpath;_unflattenpath;constructor(e,t){this._dotpath=e,this._unflattenpath=t}get name(){return`binary`}dispose(){}[Symbol.dispose](){}get concurrency(){return Math.max(1,gi.availableParallelism()-2)}get dotpath(){return this._dotpath??ei(this,`_dotpath`,()=>{let e=Ja.default.sync(`dot`);return Ya.debug`Found ${e}`,e})}get unflattenpath(){return this._unflattenpath??ei(this,`_unflattenpath`,()=>{let e=Ja.default.sync(`unflatten`);return Ya.debug`Found ${e}`,e})}async unflatten(e){let t,r=Ya.getChild([`unflatten`,_e(4)]);try{let i=await mi(this.unflattenpath,[`-l`,`1`,`-c`,`3`],{timeout:1e4,stdin:{string:e}});t=i.stdout,n(i.stderr)?r.trace(`{command} succeeded in {durationMs}ms`,{command:i.command,durationMs:Math.round(i.durationMs)}):r.warn(`{command} has stderr:
|
|
28
|
-
`+i.stderr,{command:i.command})}catch(i){r.debug(`FAILED DOT`,{dot:e}),r.error(L(i)),i instanceof hi&&!n(i.stdout)&&(r.warn(`{command} returned result but failed with exitcode {exitCode}:
|
|
29
|
-
{stderr}`,{command:i.command,exitCode:i.exitCode,stderr:i.stderr}),t=i.stdout)}return t&&(e=t.replaceAll(/\t\[/g,` [`).replaceAll(/\t/g,` `)),e}async layoutJson(e){let t=Ya.getChild([`layoutJson`,_e(4)]),r;try{let i=await mi(this.dotpath,[`-Tjson`,`-y`],{timeout:1e4,stdin:{string:e}});r=i.stdout,n(i.stderr)?t.trace(`{command} succeeded in {durationMs}ms`,{command:i.command,durationMs:Math.round(i.durationMs)}):t.warn(`{command} has stderr:
|
|
30
|
-
`+i.stderr,{command:i.command})}catch(i){if(t.debug(`FAILED DOT`,{dot:e}),t.error(L(i)),i instanceof hi&&!n(i.stdout))t.warn(`{command} returned result but failed with exitcode {exitCode}:
|
|
31
|
-
{stderr}`,{command:i.command,exitCode:i.exitCode,stderr:i.stderr}),r=i.stdout;else throw i}return r}async acyclic(e){return Promise.reject(Error(`Method not implemented.`))}async svg(e){let t=Ya.getChild([`svg`,_e(4)]),r;try{let i=await mi(this.dotpath,[`-Tsvg`,`-y`],{timeout:1e4,stdin:{string:e}});r=i.stdout,n(i.stderr)?t.trace(`{command} succeeded in {durationMs}ms`,{command:i.command,durationMs:Math.round(i.durationMs)}):t.warn(`{command} has stderr:
|
|
32
|
-
`+i.stderr,{command:i.command})}catch(i){if(t.debug(`FAILED DOT`,{dot:e}),t.error(L(i)),i instanceof hi&&!n(i.stdout))t.warn(`{command} returned result but failed with exitcode {exitCode}:
|
|
33
|
-
{stderr}`,{command:i.command,exitCode:i.exitCode,stderr:i.stderr}),r=i.stdout;else throw i}return r}};const B=Zi.getChild(`server`);function V(e){B.warn(L(e))}function Za(e){let t=Hi();return n=>{try{switch(n.level){case`error`:case`fatal`:{let r=n.category.join(`.`);if(r===`likec4.config`)break;let i=zi(n);i?e.telemetry.logEvent({eventName:`error`,message:`${i.name}: ${i.message}`,category:r,...i.stack&&{stack:i.stack}}):e.telemetry.logEvent({eventName:`error`,message:t(n),category:r});break}}}catch(e){console.error(`Error while logging to LSP connection:`,e)}}}function Qa({lspConnection:e,enableTelemetry:t=!!e,useStdErr:n=!1,logLevel:r=vi?`debug`:`warning`,nonBlocking:i=!1,colors:a=!1}={}){let o=!!e&&t&&!vi;$i({reset:!0,sinks:{console:n?Xi({formatter:Wi()}):Yi({formatter:a?qi():Wi(),nonBlocking:i}),...o&&{telemetry:Za(e)}},loggers:[{category:[`likec4`],sinks:[`console`,...o?[`telemetry`]:[]],lowestLevel:r}]}),B.trace(`logger configured`)}const $a=et.pick({extends:!0,styles:!0}).loose(),eo=e=>e?Array.isArray(e)?e:[e]:[],to=async e=>{let t=await xi.readFile(e,`utf-8`),n;try{n=Ue.parse(t.trim()||`{}`)}catch(t){throw Li(t,`${e}:`)}if(!n||typeof n!=`object`||Array.isArray(n))throw Error(`${e}: Config must be a JSON object`);let r=$a.safeParse(n);if(!r.success)throw Error(`${e}: Invalid config\n`+We.prettifyError(r.error));return r.data},no=async(e,t)=>{if(t.includes(e)){let n=t.indexOf(e),r=[...t.slice(n),e].join(` -> `);throw Error(`Config extends cycle detected: ${r}`)}let n=await to(e),r=eo(n.extends),i=[...t,e],a=[];for(let t of r){let n=Ei(Ti(e),t);a.push(...await no(n,i))}return[...a,n]};async function ro(e){e=typeof e==`string`?e:e.fsPath,Zi.getChild(`config`).debug`Loading config: ${e}`;let t=Ti(e),n=wi(e),r={name:wi(t)};if($e(n)){let t=await no(Ei(e),[]);N(v(t,1),`Expect at least one config`);let n=fe(se(t),[`extends`,`styles`]),i=t.map(e=>e.styles).filter(m),a=i.length>0?Be({},...i.reverse()):void 0;return Xe({...r,...n,...a?{styles:a}:{}})}N(Ye(n),`Invalid name for config file: ${e}`);let{mod:i}=await yi({filepath:e,cwd:t,esbuildOptions:{resolveExtensions:[`.ts`,`.mts`,`.cts`,`.mjs`,`.js`,`.cjs`],plugins:[{name:`likec4-config`,setup(e){e.onResolve({filter:/^@?likec4\/config$/},e=>({path:e.path,namespace:`likec4-config`})),e.onEnd(e=>{let t=bi(e.errors,{kind:`error`});for(let e of t)Zi.error(e)}),e.onLoad({filter:/.*/,namespace:`likec4-config`},e=>({contents:`
|
|
34
|
-
// Mock implementation to allow loading config files without bundling @likec4/config
|
|
35
|
-
function mock(x) { return x }
|
|
36
|
-
export {
|
|
37
|
-
mock as defineConfig,
|
|
38
|
-
mock as defineGenerators,
|
|
39
|
-
mock as defineStyle,
|
|
40
|
-
mock as defineTheme,
|
|
41
|
-
mock as defineThemeColor,
|
|
42
|
-
}`,loader:`js`}))}}]}});return Xe(Object.assign(r,i?.default??i))}const io=[`likec4lib {`,` icons {`,...[...Object.entries({aws:`activate.alexa-for-business.amplify.apache-mxnet-on-aws.api-gateway.app-config.app-flow.app-mesh.app-runner.app-stream.app-sync.application-auto-scaling.application-composer.application-cost-profiler.application-discovery-service.application-migration-service.artifact.athena.audit-manager.augmented-ai-a2i.aurora.auto-scaling.backint-agent.backup.batch.billing-conductor.bottlerocket.braket.budgets.certificate-manager.chatbot.chime-sdk.chime-voice-connector.chime.clean-rooms.client-vpn.cloud-control-api.cloud-development-kit.cloud-directory.cloud-formation.cloud-front.cloud-hsm.cloud-map.cloud-search.cloud-shell.cloud-trail.cloud-wan.cloud-watch.cloud9.code-artifact.code-build.code-catalyst.code-commit.code-deploy.code-guru.code-pipeline.code-star.code-whisperer.cognito.command-line-interface.comprehend-medical.comprehend.compute-optimizer.config.connect.console-mobile-application.control-tower.corretto.cost-and-usage-report.cost-explorer.data-exchange.data-pipeline.data-sync.data-zone.database-migration-service.deep-composer.deep-learning-amis.deep-learning-containers.deep-lens.deep-racer.detective.dev-ops-guru.device-farm.direct-connect.directory-service.distro-for-open-telemetry.document-db.dynamo-db.ec2-auto-scaling.ec2-image-builder.ec2.ecs-anywhere.efs.eks-anywhere.eks-cloud.eks-distro.elasti-cache.elastic-beanstalk.elastic-block-store.elastic-container-registry.elastic-container-service.elastic-disaster-recovery.elastic-fabric-adapter.elastic-inference.elastic-kubernetes-service.elastic-load-balancing.elastic-transcoder.elemental-appliances-software.elemental-conductor.elemental-delta.elemental-link.elemental-live.elemental-media-connect.elemental-media-convert.elemental-media-live.elemental-media-package.elemental-media-store.elemental-media-tailor.elemental-server.emr.event-bridge.express-workflows.fargate.fault-injection-simulator.file-cache.fin-space.firewall-manager.forecast.fraud-detector.free-rtos.fsx-for-lustre.fsx-for-net-app-ontap.fsx-for-open-zfs.fsx-for-wfs.fsx.game-kit.game-lift.game-sparks.genomics-cli.global-accelerator.glue-data-brew.glue-elastic-views.glue.ground-station.guard-duty.health-lake.honeycode.iam-identity-center.identity-and-access-management.inspector.interactive-video-service.io-t-1-click.io-t-analytics.io-t-button.io-t-core.io-t-device-defender.io-t-device-management.io-t-edu-kit.io-t-events.io-t-express-link.io-t-fleet-wise.io-t-greengrass.io-t-robo-runner.io-t-site-wise.io-t-things-graph.io-t-twin-maker.iq.kendra.key-management-service.keyspaces.kinesis-data-analytics.kinesis-data-streams.kinesis-firehose.kinesis-video-streams.kinesis.lake-formation.lambda.launch-wizard.lex.license-manager.lightsail.local-zones.location-service.lookout-for-equipment.lookout-for-metrics.lookout-for-vision.lumberyard.macie.mainframe-modernization.managed-blockchain.managed-grafana.managed-service-for-prometheus.managed-services.managed-streaming-for-apache-kafka.managed-workflows-for-apache-airflow.management-console.marketplace-dark.marketplace-light.memory-db-for-redis.migration-evaluator.migration-hub.monitron.mq.neptune.network-firewall.neuron.nice-dcv.nice-engin-frame.nimble-studio.nitro-enclaves.omics.open-3d-engine.open-search-service.ops-works.organizations.outposts-family.outposts-rack.outposts-servers.panorama.parallel-cluster.personal-health-dashboard.personalize.pinpoint-apis.pinpoint.polly.private-5g.private-certificate-authority.private-link.professional-services.proton.quantum-ledger-database.quick-sight.rds-on-vmware.rds.re-post.red-hat-open-shift-service-on-aws.redshift.rekognition.reserved-instance-reporting.resilience-hub.resource-access-manager.resource-explorer.robo-maker.route-53.s3-on-outposts.sage-maker-ground-truth.sage-maker-studio-lab.sage-maker.savings-plans.secrets-manager.security-hub.security-lake.server-migration-service.serverless-application-repository.service-catalog.service-management-connector.shield.signer.sim-space-weaver.simple-email-service.simple-notification-service.simple-queue-service.simple-storage-service-glacier.simple-storage-service.site-to-site-vpn.snowball-edge.snowball.snowcone.snowmobile.step-functions.storage-gateway.sumerian.supply-chain.support.systems-manager.tensor-flow-on-aws.textract.thinkbox-deadline.thinkbox-frost.thinkbox-krakatoa.thinkbox-sequoia.thinkbox-stoke.thinkbox-xmesh.timestream.tools-and-sdks.torch-serve.training-certification.transcribe.transfer-family.transit-gateway.translate.trusted-advisor.verified-access.verified-permissions.virtual-private-cloud.vmware-cloud-on-aws.vpc-lattice.waf.wavelength.well-architected-tool.wickr.work-docs-sdk.work-docs.work-link.work-mail.work-spaces-family.x-ray`.split(`.`),azure:`abs-member.active-directory-connect-health.activity-log.administrative-units.advisor.ai-at-edge.ai-studio.aks-automatic.aks-istio.alerts.all-resources.analysis-services.anomaly-detector.api-center.api-connections.api-management-services.api-proxy.app-compliance-automation.app-configuration.app-registrations.app-service-certificates.app-service-domains.app-service-environments.app-service-plans.app-services.app-space-component.app-space.applens.application-gateway-containers.application-gateways.application-group.application-insights.application-security-groups.aquila.arc-data-services.arc-kubernetes.arc-machines.arc-postgre-sql.arc-sql-managed-instance.arc-sql-server.atm-multistack.auto-scale.automanaged-vm.automation-accounts.availability-sets.avs-vm.azure-a.azure-ad-b2c.azure-api-for-fhir.azure-applied-ai-services.azure-arc.azure-attestation.azure-backup-center.azure-blockchain-service.azure-center-for-sap.azure-chaos-studio.azure-cloud-shell.azure-communication-services.azure-communications-gateway.azure-compute-galleries.azure-consumption-commitment.azure-cosmos-db.azure-data-catalog.azure-data-explorer-clusters.azure-database-maria-db-server.azure-database-migration-services.azure-database-my-sql-server.azure-database-postgre-sql-server-group.azure-database-postgre-sql-server.azure-databox-gateway.azure-databricks.azure-deployment-environments.azure-dev-ops.azure-dev-tunnels.azure-edge-hardware-center.azure-experimentation-studio.azure-fileshares.azure-firewall-manager.azure-firewall-policy.azure-hcp-cache.azure-hpc-workbenches.azure-hybrid-center.azure-information-protection.azure-io-t-operations.azure-lighthouse.azure-load-testing.azure-managed-grafana.azure-managed-redis.azure-maps-accounts.azure-media-service.azure-migrate.azure-monitor-dashboard.azure-monitor-pipeline.azure-monitors-for-sap-solutions.azure-net-app-files.azure-network-function-manager-functions.azure-network-function-manager.azure-object-understanding.azure-open-ai.azure-operator-5g-core.azure-operator-insights.azure-operator-nexus.azure-operator-service-manager.azure-orbital.azure-programmable-connectivity.azure-purview-accounts.azure-quotas.azure-red-hat-open-shift.azure-sentinel.azure-service-bus.azure-sphere.azure-spring-apps.azure-sql-edge.azure-sql-server-stretch-databases.azure-sql-vm.azure-sql.azure-stack-edge.azure-stack-hci-sizer.azure-stack.azure-storage-mover.azure-support-center-blue.azure-sustainability.azure-synapse-analytics.azure-token-service.azure-video-indexer.azure-virtual-desktop.azure-vmware-solution.azure-workbooks.azurite.backlog.backup-vault.bare-metal-infrastructure.bastions.batch-accounts.batch-ai.biz-talk.blob-block.blob-page.blockchain-applications.blueprints.bonsai.bot-services.branch.breeze.browser.bug.builds.business-process-tracking.cache-redis.cache.capacity-reservation-groups.capacity.cdn-profiles.central-service-instance-for-sap.ceres.change-analysis.client-apps.cloud-services-classic.cloud-services-extended-support.cloud-test.code-optimization.code.cognitive-search.cognitive-services-decisions.cognitive-services.collaborative-service.commit.community-images.compliance-center.compliance.compute-fleet.computer-vision.conditional-access.confidential-ledgers.connected-cache.connected-vehicle-platform.connections.consortium.container-apps-environments.container-instances.container-registries.container-services-deprecated.content-moderators.content-safety.controls-horizontal.controls.cost-alerts.cost-analysis.cost-budgets.cost-export.cost-management-and-billing.cost-management.counter.cubes.custom-ip-prefix.custom-vision.customer-lockbox-for-microsoft-azure.dashboard-hub.dashboard.data-box.data-collection-rules.data-factories.data-lake-analytics.data-lake-storage-gen1.data-lake-store-gen1.data-share-invitations.data-shares.data-virtualization.database-instance-for-sap.ddo-s-protection-plans.dedicated-hsm.defender-cm-local-manager.defender-dcs-controller.defender-distributer-control-system.defender-engineering-station.defender-external-management.defender-freezer-monitor.defender-historian.defender-hmi.defender-industrial-packaging-system.defender-industrial-printer.defender-industrial-robot.defender-industrial-scale-system.defender-marquee.defender-meter.defender-plc.defender-pneumatic-device.defender-programable-board.defender-relay.defender-robot-controller.defender-rtu.defender-sensor.defender-slot.defender-web-guiding-system.detonation.dev-console.dev-ops-starter.dev-test-labs.device-compliance.device-configuration.device-enrollment.device-provisioning-services.device-security-apple.device-security-google.device-security-windows.device-update-io-t-hub.devices.diagnostics-settings.digital-twins.disk-encryption-sets.disk-pool.disks-classic.disks-snapshots.disks.dns-multistack.dns-private-resolver.dns-security-policy.dns-zones.download.e-books.edge-actions.edge-management.edge-storage-accelerator.education.elastic-job-agents.elastic-san.endpoint-analytics.engage-center-connect.enterprise-applications.entra-connect-health.entra-connect-sync.entra-connect.entra-domain-services.entra-global-secure-access.entra-id-protection.entra-identity-custom-roles.entra-identity-licenses.entra-identity-risky-signins.entra-identity-risky-users.entra-identity-roles-and-administrators.entra-internet-access.entra-managed-identities.entra-private-access.entra-privleged-identity-management.entra-verified-id.error.event-grid-domains.event-grid-subscriptions.event-grid-topics.event-hub-clusters.event-hubs.exchange-access.exchange-on-premises-access.express-route-circuits.express-route-direct.express-route-traffic-collector.extended-security-updates.extensions.external-id-modified.external-id.external-identities.face-apis.feature-previews.fhir-service.fiji.file.files.firewalls.folder-blank.folder-website.form-recognizers.frd-qa.free-services.front-door-and-cdn-profiles.ftp.function-apps.gear.genomics-accounts.genomics.globe-error.globe-success.globe-warning.groups.guide.hd-insight-clusters.hdi-aks-cluster.heart.help-and-support.host-groups.host-pools.hosts.hybrid-connectivity-hub.ic-m-troubleshooting.identity-governance.identity-multi-factor-authentication.identity-secure-score.image-definitions.image-templates.image-versions.image.images.immersive-readers.import-export-jobs.industrial-io-t.information.infrastructure-backup.input-output.instance-pools.integration-accounts.integration-environments.integration-service-environments.internet-analyzer-profiles.intune-app-protection.intune-for-education.intune-trends.intune.io-t-central-applications.io-t-edge.io-t-hub.ip-address-manager.ip-groups.journey-hub.key-vaults.keys.kubernetes-fleet-manager.kubernetes-services.lab-accounts.lab-services.landing-zone.language-understanding.language.launch-portal.learn.load-balancer-hub.load-balancers.load-test.load-testing.local-network-gateways.location.log-analytics-query-pack.log-analytics-workspaces.log-streaming.logic-apps-custom-connector.logic-apps-template.logic-apps.machine-learning-studio-classic-web-services.machine-learning-studio-web-service-plans.machine-learning-studio-workspaces.machine-learning.machines-azure-arc.maintenance-configuration.managed-applications-center.managed-database.managed-desktop.managed-dev-ops-pools.managed-file-shares.managed-identities.managed-instance-apache-cassandra.managed-service-fabric.management-groups.management-portal.marketplace-management.marketplace.med-tech-service.media-file.media.mesh-applications.metrics-advisor.metrics.microsoft-defender-easm.microsoft-defender-for-cloud.microsoft-defender-for-io-t.microsoft-dev-box.mindaro.mission-landing-zone.mobile-engagement.mobile-networks.mobile.modular-data-center.module.monitor-health-models.monitor.multi-tenancy.multifactor-authentication.my-customers.nat.network-foundation-hub.network-interfaces.network-managers.network-security-groups.network-security-hub.network-security-perimeters.network-watcher.notification-hub-namespaces.notification-hubs.offers.on-premises-data-gateways.open-supply-chain-platform.operation-log-classic.oracle-database.os-images-classic.osconfig.outbound-connection.partner-namespace.partner-registration.partner-topic.peering-service.peerings.personalizers.planetary-computer-pro.plans.policy.power-bi-embedded.power-platform.power-up.power.powershell.preview-features.private-endpoints.private-link-service.private-link-services.private-link.process-explorer.production-ready-database.promethus.proximity-placement-groups.public-ip-addresses-classic.public-ip-addresses.public-ip-prefixes.qn-a-makers.quickstart-center.recent.recovery-services-vaults.region-management.relays.remote-rendering.reservations.reserved-capacity.reserved-ip-addresses-classic.resource-explorer.resource-graph-explorer.resource-group-list.resource-groups.resource-guard.resource-linked.resource-management-private-link.resource-mover.resources-provider.restore-points-collections.restore-points.route-filters.route-tables.rtos.savings-plans.scheduler-job-collections.scheduler.scvmm-management-servers.search-grid.search.security-baselines.security.send-grid-accounts.server-farm.serverless-search.service-catalog-mad.service-endpoint-policies.service-fabric-clusters.service-group-relationships.service-groups.service-health.service-providers.shared-image-galleries.signal-r.software-as-a-service.software-updates.solutions.sonic-dash.spatial-anchor-accounts.speech-services.spot-vm.spot-vmss.sql-data-warehouses.sql-database-fleet-manager.sql-database.sql-elastic-pools.sql-managed-instance.sql-server-registries.sql-server.ssd.ssh-keys.ssis-lift-and-shift-ir.stack-hci-premium.static-apps.stor-simple-data-managers.stor-simple-device-managers.storage-accounts-classic.storage-accounts.storage-actions.storage-azure-files.storage-container.storage-explorer.storage-functions.storage-hubs.storage-queue.storage-sync-services.stream-analytics-jobs.subnet.subscriptions.system-topic.table.tag.tags.targets-management.template-specs.templates.tenant-properties.tenant-status.test-base.tfs-vc-repository.time-series-data-sets.time-series-insights-access-policies.time-series-insights-environments.time-series-insights-event-sources.toolbox.toolchain-orchestrator.traffic-manager-profiles.translator-text.troubleshoot.universal-print.update-management-center.updates.user-privacy.user-settings.user-subscriptions.users.verifiable-credentials.verification-as-a-service.versions.video-analyzers.virtual-clusters.virtual-enclaves.virtual-instance-for-sap.virtual-machine.virtual-machines-classic.virtual-network-gateways.virtual-networks-classic.virtual-networks.virtual-router.virtual-visits-builder.virtual-wan-hub.virtual-wans.vm-app-definitions.vm-app-versions.vm-image-version.vm-images-classic.vm-scale-sets.vpnclient-windows.wac-installer.wac.web-app-database.web-application-firewall-policies-waf.web-jobs.web-slots.web-test.website-power.website-staging.windows-notification-services.windows10-core-services.workbooks.worker-container-app.workflow.workload-orchestration.workspace-gateway.workspaces`.split(`.`),gcp:`access-context-manager.administration.advanced-agent-modeling.advanced-solutions-lab.agent-assist.ai-hub.ai-platform-unified.ai-platform.analytics-hub.anthos-config-management.anthos-service-mesh.anthos.api-analytics.api-monetization.api.apigee-api-platform.apigee-sense.app-engine.artifact-registry.asset-inventory.assured-workloads.auto-ml-natural-language.auto-ml-tables.auto-ml-translation.auto-ml-video-intelligence.auto-ml-vision.auto-ml.bare-metal-solutions.batch.beyondcorp.big-query.bigtable.billing.binary-authorization.catalog.certificate-authority-service.certificate-manager.cloud-api-gateway.cloud-apis.cloud-armor.cloud-asset-inventory.cloud-audit-logs.cloud-build.cloud-cdn.cloud-code.cloud-composer.cloud-data-fusion.cloud-deploy.cloud-deployment-manager.cloud-dns.cloud-domains.cloud-ekm.cloud-endpoints.cloud-external-ip-addresses.cloud-firewall-rules.cloud-for-marketing.cloud-functions.cloud-generic.cloud-gpu.cloud-healthcare-api.cloud-healthcare-marketplace.cloud-hsm.cloud-ids.cloud-inference-api.cloud-interconnect.cloud-jobs-api.cloud-load-balancing.cloud-logging.cloud-media-edge.cloud-monitoring.cloud-nat.cloud-natural-language-api.cloud-network.cloud-ops.cloud-optimization-ai-fleet-routing-api.cloud-optimization-ai.cloud-router.cloud-routes.cloud-run-for-anthos.cloud-run.cloud-scheduler.cloud-security-scanner.cloud-shell.cloud-spanner.cloud-sql.cloud-storage.cloud-tasks.cloud-test-lab.cloud-tpu.cloud-translation-api.cloud-vision-api.cloud-vpn.compute-engine.configuration-management.connectivity-test.connectors.contact-center-ai.container-optimized-os.container-registry.data-catalog.data-labeling.data-layers.data-loss-prevention-api.data-qn-a.data-studio.data-transfer.database-migration-service.dataflow.datalab.dataplex.datapol.dataprep.dataproc-metastore.dataproc.datashare.datastore.datastream.debugger.developer-portal.dialogflow-cx.dialogflow-insights.dialogflow.document-ai.early-access-center.error-reporting.eventarc.filestore.financial-services-marketplace.firestore.fleet-engine.free-trial.game-servers.gce-systems-management.genomics.gke-on-prem.google-cloud-marketplace.google-kubernetes-engine.google-maps-platform.healthcare-nlp-api.home.identity-and-access-management.identity-aware-proxy.identity-platform.iot-core.iot-edge.key-access-justifications.key-management-service.kuberun.launcher.local-ssd.looker.managed-service-for-microsoft-active-directory.media-translation-api.memorystore.migrate-for-anthos.migrate-for-compute-engine.my-cloud.network-connectivity-center.network-intelligence-center.network-security.network-tiers.network-topology.onboarding.os-configuration-management.os-inventory-management.os-patch-management.partner-interconnect.partner-portal.performance-dashboard.permissions.persistent-disk.phishing-protection.policy-analyzer.premium-network-tier.private-connectivity.private-service-connect.producer-portal.profiler.project.pub-sub.quantum-engine.quotas.real-world-insights.recommendations-ai.release-notes.retail-api.risk-manager.runtime-config.secret-manager.security-command-center.security-health-advisor.security-key-enforcement.security.service-discovery.speech-to-text.stackdriver.standard-network-tier.stream-suite.support.tensorflow-enterprise.text-to-speech.tools-for-powershell.trace.traffic-director.transfer-appliance.transfer.user-preferences.vertex-ai.video-intelligence-api.virtual-private-cloud.visual-inspection.vmware-engine.web-risk.web-security-scanner.workflows.workload-identity-pool`.split(`.`),tech:`100tb.500px.aarch64.active-campaign-icon.active-campaign.adobe-after-effects.adobe-animate.adobe-dreamweaver.adobe-icon.adobe-illustrator.adobe-incopy.adobe-indesign.adobe-lightroom.adobe-photoshop.adobe-premiere-pro.adobe-premiere.adobe-xd.adobe.adonis-js.adonisjs-icon.adroll.adyen.aerogear.aerospike-icon.aerospike.after-effects.aha.airbnb-icon.airbnb.airbrake.airflow-icon.airflow.airtable.aix.akamai.akka.alfresco.algolia.alpinejs-icon.alpinejs.altair.amazon-chime.amazon-connect.amazon-web-services.amd.amex-digital.amex.amp-icon.amp.ampersand.amplication-icon.amplication.amplitude-icon.amplitude.anaconda.analog.android-icon.android-studio.android-vertical.android.angellist.angular-icon.angular-js.angular.ansible.ant-design.anthropic-icon.anthropic.apache-camel.apache-cloudstack.apache-flink-icon.apache-flink.apache-spark.apache-superset-icon.apache-superset.apache.apiary.apidog-icon.apidog.apl.apollostack.apostrophe.appbaseio-icon.appbaseio.appcelerator.appcenter-icon.appcenter.appcircle-icon.appcircle.appcode.appdynamics-icon.appdynamics.appium.apple-app-store.apple-pay.apple-safari.apple.applitools-icon.applitools.appsignal-icon.appsignal.apptentive.appveyor.appwrite-icon.appwrite.arangodb-icon.arangodb.arc.architect-icon.architect.archlinux.arduino.argo-icon.argo.argocd.arm.armory-icon.armory.asana-icon.asana.asciidoctor.assembla-icon.assembla.astro-icon.astro.astronomer.async-api-icon.async-api.atlassian.atom-icon.atom.atomic-icon.atomic.atomicojs-icon.atomicojs.aurelia.aurora.auth0-icon.auth0.authy.autodesk-maya.autodesk-shot-grid.autoit.autoprefixer.ava.awesome.awk.aws-amplify.aws-api-gateway.aws-app-mesh.aws-appflow.aws-appsync.aws-athena.aws-aurora.aws-backup.aws-batch.aws-certificate-manager.aws-cloudformation.aws-cloudfront.aws-cloudsearch.aws-cloudtrail.aws-cloudwatch.aws-codebuild.aws-codecommit.aws-codedeploy.aws-codepipeline.aws-codestar.aws-cognito.aws-config.aws-documentdb.aws-dynamodb.aws-ec2.aws-ecs.aws-eks.aws-elastic-beanstalk.aws-elasticache.aws-elb.aws-eventbridge.aws-fargate.aws-glacier.aws-glue.aws-iam.aws-keyspaces.aws-kinesis.aws-kms.aws-lake-formation.aws-lambda.aws-lightsail.aws-mq.aws-msk.aws-neptune.aws-open-search.aws-opsworks.aws-quicksight.aws-rds.aws-redshift.aws-route53.aws-s3.aws-secrets-manager.aws-ses.aws-shield.aws-sns.aws-sqs.aws-step-functions.aws-systems-manager.aws-timestream.aws-vpc.aws-waf.aws-xray.aws.axios.azios.azure-devops.azure-sql-database.azure.babel.backbone-icon.backbone-js.backbone.backerkit.baker-street.balena.ballerina.bamboo.basecamp-icon.basecamp.basekit.baseline.bash-icon.bash.batch.beats.behance.bem-2.bem.bigpanda.bing.biomejs-icon.biomejs.bitbar.bitbucket.bitcoin.bitnami.bitrise-icon.bitrise.blender.blitzjs-icon.blitzjs.blocs.blogger.blossom.blueprint.bluesky.bluetooth.booqable-icon.booqable.bootstrap.bosun.botanalytics.bourbon.bower.box.brackets.brainjs.branch-icon.branch.brandfolder-icon.brandfolder.brave.braze-icon.braze.broadcom-icon.broadcom.broccoli.brotli.browserify-icon.browserify.browserling.browserslist.browserstack.browsersync.brunch.bubble-icon.bubble.buck.buddy.buffer.bugherd-icon.bugherd.bugsee.bugsnag.builder-io-icon.builder-io.buildkite-icon.buildkite.bulma.bun.bunny-net-icon.bunny-net.c.cachet.cairo-graphics.cake-php.cakephp-icon.calibre-icon.calibre.campaignmonitor-icon.campaignmonitor.canjs.canva.capacitor.capacitorjs-icon.capacitorjs.capistrano.carbide.cardano-icon.cardano.cassandra.cent-os.centos-icon.certbot.ceylon.chai.chalk.chargebee-icon.chargebee.chartjs.chef.chevereto.chroma.chromatic-icon.chromatic.chrome-web-store.chrome.cinder.circle-ci.cirrus-ci.cirrus.clarity.claude-icon.claude.clio-lang.clion.cljs.clojure-script.clojure.close.cloud9.cloudacademy-icon.cloudacademy.cloudcraft.cloudflare-icon.cloudflare-workers-icon.cloudflare-workers.cloudflare.cloudinary-icon.cloudinary.cloudlinux.cmake.cobalt.cockpit.cocoapods.coda-icon.coda.codacy.code-igniter.code-pen.codeac.codebase.codebeat.codecademy.codeception.codeclimate-icon.codeclimate.codecov-icon.codecov.codefactor-icon.codefactor.codeigniter-icon.codepen-icon.codersrank-icon.codersrank.coderwall.codesandbox-icon.codesandbox.codesee-icon.codesee.codio.codium-icon.codium.coffee-script.commitizen.compass.componentkit.compose-multiplatform.compose.composer.conan-io.concourse.concretecms-icon.concretecms.conda.confluence.consul.contao.contentful.convox-icon.convox.copyleft-pirate.copyleft.corda.cordova.cosmosdb.couchbase.couchdb-icon.couchdb.coursera.coveralls.cpanel.cplusplus.craftcms.crashlytics.crateio.create-react-app.createjs.crossplane-icon.crossplane.crucible.crystal.csharp.css3-official.css3.cssnext.cube-icon.cube.cucumber.curl.customerio-icon.customerio.cyclejs.cypress-icon.cypress.d3.d3js.dailydev-icon.dailydev.daisy-ui-icon.daisy-ui.danfo.dart.dashlane-icon.dashlane.data-grip.data-spell.data-station.database-labs.datadog-icon.datadog.datasette-icon.datasette.datocms-icon.datocms.dbeaver.dbt-icon.dbt.dcos-icon.dcos.debian.delighted-icon.delighted.deno.dependabot.deployhq-icon.deployhq.derby.descript-icon.descript.designernews.deviantart-icon.deviantart.devicon.dgraph-icon.dgraph.dialogflow.digital-ocean-icon.digital-ocean.dimer.dinersclub.discord-icon.discord-js.discord.discourse-icon.discourse.discover.disqus.django-icon.django-rest.django.dockbit.docker-icon.docker.doctrine.docusaurus.dojo-icon.dojo-toolkit.dojo.dolt.dotnet.dovetail-icon.dovetail.dreamhost.dribbble-icon.dribbble.drift.drip.drizzle-icon.drizzle.drone-icon.drone.drools-icon.drools.dropbox.dropmark.dropwizard.dropzone.drupal-icon.drupal.duckduckgo.dynatrace-icon.dynatrace.dyndns.ebanx.eclipse-ceylon.eclipse-icon.eclipse-ide.eclipse-vert-x.eclipse.ecma.edgedb.edgio-icon.edgio.editorconfig.effect-icon.effect.effector.egghead.elasticbeats.elasticpath-icon.elasticpath.elasticsearch.electron.element.elemental-ui.elementary.eleventy-11ty.eleventy.elixir.ello.elm-classic.elm.elo.emacs-classic.emacs.embedded-c.embedly.ember-js.ember-tomster.ember.emmet.enact.engine-yard-icon.engine-yard.envato.envoy-icon.envoy.envoyer.eraser-icon.eraser.erlang.esbuild.esdoc.eslint-old.eslint.eta-icon.eta.etcd.ethereum-color.ethereum.ethers.ethnio.eventbrite-icon.eventbrite.eventsentry.evergreen-icon.evergreen.expo-icon.expo.express.fabric.facebook.faker.falcor.fast-api.fastapi-icon.fastify-icon.fastify.fastlane.fastly.fauna-icon.fauna.feathers.feathersjs.fedora.fetch.ffmpeg-icon.ffmpeg.figma.file-zilla.firebase-icon.firebase.firefox.flannel.flarum.flask.flat-ui.flattr-icon.flattr.fleep.flickr-icon.flickr.flight.floodio.flow.flowxo.floydhub.flutter.flux.fluxxor.fly-icon.fly.fogbugz-icon.fogbugz.fomo-icon.fomo.font-awesome.forestadmin-icon.forestadmin.forever.formkeep.fortran.foundation.foundationdb-icon.foundationdb.framer.framework7-icon.framework7.freebsd.freedcamp-icon.freedcamp.freedomdefined.fresh.frontapp.fsharp.fuchsia.galliumos.game-analytics-icon.game-analytics.ganache-icon.ganache.gatling.gatsby.gazebo.gcc.geekbot.geetest-icon.geetest.gentoo.getyourguide.ghost.giantswarm.gimp.gin.git-icon.git.gitboard.gitbook.github-actions.github-codespaces.github-copilot.github-icon.github-octocat.github.gitkraken.gitlab-icon.gitlab.gitpod.gitter.gitup.glamorous-icon.glamorous.gleam.glimmerjs.glint.glitch-icon.glitch.gnome-icon.gnome.gnu-emacs.gnu-net.gnu.gnupg-icon.gnupg.go-land.go.gocd.godot-engine.godot-icon.godot.gohorse.google-360suite.google-admob.google-ads.google-adsense.google-analytics.google-bard-icon.google-bard.google-calendar.google-cloud-functions.google-cloud-run.google-cloud.google-data-studio.google-developers.google-domains-icon.google-domains.google-drive.google-fit.google-gemini.google-gmail.google-home.google-icon.google-keep.google-maps.google-marketing-platform.google-meet.google-one.google-optimize.google-palm.google-pay.google-photos.google-play-console-icon.google-play-console.google-play-icon.google-play.google-search-console.google-tag-manager.google-workspace.google.gopher.gradio-icon.gradio.gradle.grafana.grails.grammarly-icon.grammarly.graphene.graphql.grav.gravatar-icon.gravatar.graylog-icon.graylog.greensock-icon.greensock.gridsome-icon.gridsome.grommet.groovehq.groovy.grove.growth-book-icon.growth-book.grpc.grunt.gruntjs.gulp.gulpjs.gunicorn.gunjs.gusto.gwt.hack.hacker-one.hadoop.haiku-icon.haiku.haml.hanami.handlebars.hapi.hardhat-icon.hardhat.harness-icon.harness.harvester.hashicorp-icon.hashicorp-vault.hashicorp.hashnode-icon.hashnode.haskell-icon.haskell.hasura-icon.hasura.haxe.haxl.hbase.hcaptcha-icon.hcaptcha.headlessui-icon.headlessui.heap-icon.heap.helm.helpscout-icon.helpscout.hermes.heroku-icon.heroku-redis.heroku.hexo.hhvm.hibernate.highcharts.hipercard.homebrew.hono.hookstate.hootsuite-icon.hootsuite.hosted-graphite.hostgator-icon.hostgator.hotjar-icon.hotjar.houndci.html5-boilerplate.html5.htmx-icon.htmx.httpie-icon.httpie.hubspot.hugging-face-icon.hugging-face.huggy.hugo.humongous.hyper.hyperapp.ibm-spss-statistics.ibm.ie10.ieee.ietf.ifttt.imagemin.imba-icon.imba.immer-icon.immer.immutable.impala.importio-icon.importio.incident-icon.incident.infer.inferno.influxdb-icon.influxdb.ink.inkscape.insomnia.instagram-icon.instagram.intel.intellij-idea.intercom-icon.intercom.internet-computer-icon.internet-computer.internetexplorer.invision-icon.invision.ionic-icon.ionic.ios.iron-icon.iron.itsalive-icon.itsalive.jade.jaeger.jamstack-icon.jamstack.jasmine.java.javascript.jcb.jeet.jekyll.jenkins.jest.jetbrains-icon.jetbrains-space-icon.jetbrains-space.jetbrains.jfrog.jhipster-icon.jhipster.jira-align.jira.joomla.jotai.jquery-mobile.jquery.jruby.jsbin.jsdelivr.jsdom.jsfiddle.json-ld.json-schema-icon.json-schema.json.jspm.jss.juju.jule.julia.junit.jupyter.jwt-icon.jwt.k3os.k3s.kafka-icon.kafka.kaggle.kaios.kallithea.karate.karma.katalon-icon.katalon.kde.keen.kemal.keras.keycdn-icon.keycdn.keydb-icon.keydb.keystonejs.khan-academy-icon.khan-academy.kibana.kickstarter-icon.kickstarter.kinto-icon.kinto.kirby-icon.kirby.knex-js.knex.knockout.koa.kong-icon.kong.kops.koreio.kotlin-icon.kotlin.kraken.krakenjs.ktor-icon.ktor.kubernetes.kustomer.labview.languagetool.laravel.lastfm.lateral-icon.lateral.latex.launchdarkly-icon.launchdarkly.launchrock.leaflet.leankit-icon.leankit.lerna.less-js.less.lets-cloud.letsencrypt.leveldb.lexical-icon.lexical.liftweb.lighthouse.lightstep-icon.lightstep.lighttpd.linear-icon.linear.linkedin-icon.linkedin.linkerd.linode.linux-mint.linux-tux.linux.liquibase.lit-icon.lit.litmus.livewire.llvm.loader.lodash.logentries.logstash.lookback.looker-icon.looker.loom-icon.loom.loopback-icon.loopback.losant.lua.lucene-net.lucene.lumen.mac-os.madge.maestro.mageia.magento.mailchimp-freddie.mailchimp.maildeveloper.mailgun-icon.mailgun.mailjet-icon.mailjet.malinajs.manjaro.mantine-icon.mantine.mapbox-icon.mapbox.maps-me.mapzen-icon.mapzen.mariadb-icon.mariadb.marionette.markdown.marko.marvel.mastercard.mastodon-icon.mastodon.material-ui.materialize.materializecss.matlab.matomo-icon.matomo.matplotlib-icon.matplotlib.matter-icon.matter.mattermost-icon.mattermost.mautic-icon.mautic.maven.mdn.mdx.medium-icon.medium.medusa-icon.medusa.meilisearch.memcached.memgraph.mention.mercurial.mesos.messenger.meta-icon.meta.metabase.metamask-icon.metamask.meteor-icon.meteor-js.meteor.micro-icon.micro-python.micro.microcosm.micron-icon.micron.microsoft-azure.microsoft-edge.microsoft-icon.microsoft-onedrive.microsoft-power-bi.microsoft-sql-server.microsoft-teams.microsoft-windows-icon.microsoft-windows.microsoft.mida-icon.mida.middleman.midjourney.milligram.million-icon.million.milvus-icon.milvus.mindsdb-icon.mindsdb.minitab.mint-lang.mio.miro-icon.miro.mist.mistral-ai-icon.mistral-ai.mithril.mixmax.mixpanel.mlab.mob-x.mocha.mockflow-icon.mockflow.modernizr.modx-icon.modx.moleculer.momentjs.monday-icon.monday.monero.mongodb-icon.mongodb.mongoose-js.mono.moodle.moon.mootools.morpheus-icon.morpheus.mozilla.mparticle-icon.mparticle.mps-icon.mps.ms-dos.msw-icon.msw.multipass.mysql-icon.mysql.naiveui.namecheap.nano.nanonets.nasm.nativescript.nats-icon.nats.neat.neo4j.neon-icon.neon.neovim.nerog.nestjs.net-core.net.netbeans.netflix-icon.netflix.netlify-icon.netlify.network-x.neverinstall-icon.neverinstall.new-relic-icon.new-relic.new4j.nextjs-icon.nextjs.nginx.ngrok.nhibernate.nhost-icon.nhost.nightwatch.nim-lang.nim.nimble.nix.nocodb.nodal.node-sass.nodebots.nodejs-icon-alt.nodejs-icon.nodejs.nodemon.nodeos.nodewebkit.nomad-icon.nomad.notion-icon.notion.noysi.npm-icon.npm.nuclide.nuget.num-py.nuxt-icon.nuxt-js.nuxt.nvidia.nvm.nx.oauth.objective-c.observablehq.obsidian-icon.obsidian.ocaml.octodns.octopus-deploy.oh-my-zsh.okta-icon.okta.olark.onesignal.open-al.open-api.open-cl.open-cv.open-gl.open-graph.open-stack.open-suse.open-telemetry.open-zeppelin-icon.open-zeppelin.openai-icon.openai.openapi-icon.opencart.opencollective.openframeworks.openjs-foundation-icon.openjs-foundation.openlayers.opensearch-icon.opensearch.openshift.opensource.openstack-icon.opentelemetry-icon.opera.opsgenie.optimizely-icon.optimizely.oracle.oreilly.origami.origin.oshw.osquery.overloop-icon.overloop.p5js.packer.pagekit.pagekite.pagerduty-icon.pagerduty.panda.pandacss-icon.pandacss.pandas-icon.pandas.parcel-icon.parcel.parse.parsehub.partytown-icon.partytown.passbolt-icon.passbolt.passport.patreon.payload.paypal.peer5.pepperoni.percona.percy-icon.percy.perf-rocks.perl.perplexity-icon.perplexity.pf-sense.phalcon.phoenix-framework.phoenix.photon-engine.php-alt.php-storm.php.pinecone-icon.pinecone.pinia.pinterest.pipedream.pipedrive.pipefy.pivotal-tracker.pixijs.pkg.planetscale.planless-icon.planless.plasmic.plastic-scm.platformio.play.playwright.playwrite.ploty.pluralsight-icon.pluralsight.pm2-icon.pm2.pnpm.pocket-base.podman.poeditor.polygon.polymer.portainer.postcss.postgraphile.postgresql.posthog-icon.posthog.postman-icon.postman.pouchdb.powershell.preact.precursor.prerender-icon.prerender.prestashop-icon.prestashop.presto-icon.presto.prettier.prisma.prismic-icon.prismic.processing.processwire-icon.processwire.productboard-icon.productboard.producthunt.progress.prometheus.promises.proofy.protoio.protonet.protractor.prott.pug.pulumi-icon.pulumi.pumpkindb.puppet-icon.puppet.puppeteer.purescript-icon.purescript.pushbullet.pusher-icon.pusher.putty.pwa.pycharm.pypi.pyscript.pytest.python-poetry.python.pytorch-icon.pytorch.pyup.q.qdrant-icon.qdrant.qlik.qodana.qt.qualcomm.quarkus-icon.quarkus.quasar.quay.quobyte.quora.qwik-icon.qwik.r-lang.r.rabbitmq-icon.rabbitmq.rackspace-icon.rackspace.rails.ramda.raml.rancher-icon.rancher.raphael.raspberry-pi.rax.reach.react-bootstrap.react-query-icon.react-query.react-router.react-spring.react-styleguidist.react.reactivex.realm.reapp.reasonml-icon.reasonml.recaptcha.recoil-icon.recoil.red-cube-s-epic-compiler-thingy-programming-re-ct.reddit-icon.reddit.redhat-icon.redhat.redis.redsmin.redux-observable.redux-saga.redux.redwoodjs.reindex.relay.release.remix-icon.remix.ren-py.renovatebot.replay-icon.replay.replit-icon.replit.require.rescript-icon.rescript.rest-li.rethinkdb.retool-icon.retool.riak.rider.riot.risingwave-icon.risingwave.robot-operating-system-ros.rocket-chat-icon.rocket-chat.rocksdb.rocky-linux-icon.rocky-linux.rollbar-icon.rollbar.rollupjs.rome-icon.rome.ros.rsa.rsmq.rspec.rstudio.rubocop.ruby-mine.ruby-on-rails.ruby.rubygems.rum.runscope.rush-icon.rush.rust.rxdb.safari.sagui.sails.salesforce.sameroom.samsung.sanity.sap.sass-doc.sass.saucelabs.scala.scaledrone.scalingo.scribd-icon.scribd.sdl.seaborn-icon.seaborn.section-icon.section.segment-icon.segment.selenium.sema-software.semantic-release.semantic-ui.semaphoreci.sencha.sendgrid-icon.sendgrid.seneca.sensu-icon.sensu.sentry-icon.sentry.sequelize.serverless.sherlock-icon.sherlock.shields.shipit.shogun.shopify.shopware.shortcut-icon.shortcut.sidekiq-icon.sidekiq.signal.sigstore-icon.sigstore.sinatra.singlestore-icon.singlestore.sitepoint.sk-hynix.skaffolder.sketch.skylight.skype.slack-icon.slack.slides.slidev.slim.smartling.smashingmagazine.snap-svg.snaplet-icon.snaplet.snowflake-icon.snowflake.snowpack.snyk.socket-io.solarwinds.solid.solidity.solidjs-icon.solidjs.solr.sonarcloud-icon.sonarcloud.sonarlint-icon.sonarlint.sonarqube.soundcloud.sourcegraph.sourcetree.spark.sparkpost.speakerdeck.speedcurve.spidermonkey-icon.spidermonkey.spinnaker.splunk.spotify-icon.spotify.spree.spring-icon.spring.sql-developer.sqlalchemy.sqlite.square.squarespace.ssh.sst-icon.sst.stability-ai-icon.stability-ai.stackbit-icon.stackbit.stackblitz-icon.stackblitz.stackoverflow-icon.stackoverflow.stackshare.stata.stately-icon.stately.statuspage.stdlib-icon.stdlib.steam.stenciljs-icon.stenciljs.stetho.stickermule.stigg-icon.stigg.stimulus-icon.stimulus.stitch.stoplight.storyblocks-icon.storyblocks.storyblok-icon.storyblok.storybook-icon.storybook.strapi-icon.strapi.streamlit.strider.stripe.struts.styleci.stylefmt.stylelint.stylis.stylus.stytch.sublimetext-icon.sublimetext.subversion.sugarss.supabase-icon.supabase.supertokens-icon.supertokens.surge.surrealdb-icon.surrealdb.survicate-icon.survicate.suse.susy.svelte-icon.svelte-kit.svelte.svg.svgator.swagger.swc.swift.swiftype.swimm.swr.symfony.sysdig-icon.sysdig.t3.tableau-icon.tableau.taiga.tailwindcss-icon.tailwindcss.tapcart-icon.tapcart.taskade-icon.taskade.tastejs.tauri.tealium.teamcity.teamgrid.teamwork-icon.teamwork.telegram.tensorflow.terminal.terraform-icon.terraform.terser-icon.terser.testcafe.testing-library.testlodge.tex.the-algorithms.threejs.thymeleaf-icon.thymeleaf.tidal-icon.tidal.tiktok-icon.tiktok.titanium-sdk.tnw.todoist-icon.todoist.todomvc.tomcat.toml.tor-browser.tor.tortoise-git.tower.traackr.trac.traefik-mesh.traefik-proxy.travis-ci-monochrome.travis-ci.treasuredata-icon.treasuredata.treehouse-icon.treehouse.trello.trpc.truffle-icon.truffle.tsmc.tsnode.tsuru.tumblr-icon.tumblr.tunein.tuple.turbopack-icon.turbopack.turborepo-icon.turborepo.turret.twilio-icon.twilio.twitch.twitter.typeform-icon.typeform.typeorm.typescript-icon-round.typescript-icon.typescript.typesense-icon.typesense.typo3-icon.typo3.ubuntu.udacity-icon.udacity.udemy-icon.udemy.uikit.uml.umu.unbounce-icon.unbounce.undertow.unionpay.unitjs.unito-icon.unito.unity.unix.unjs.unocss.unrealengine-icon.unrealengine.upcase.upstash-icon.upstash.upwork.user-testing-icon.user-testing.uservoice-icon.uservoice.uwsgi.v8-ignition.v8-turbofan.v8.vaadin.vaddy.vagrant-icon.vagrant.vala.vault-icon.vault.vector.vercel-icon.vercel.verdaccio-icon.verdaccio.vernemq.veutify.vim.vimeo-icon.vimeo.visa.visaelectron.visual-studio-code.visual-studio.vite.vitejs.vitess.vitest.vivaldi-icon.vivaldi.vlang.vmware.void.volar.vorejs.vscode.vsphere.vue-storefront.vue.vuetifyjs.vueuse.vulkan.vultr-icon.vultr.vwo.vyper.w3c.waffle-icon.waffle.wagtail.wakatime.walkme.watchman.waypoint-icon.waypoint.wayscript-icon.wayscript.wearos.weave.web-dev-icon.web-dev.web3js.webassembly.webcomponents.webdriverio.webflow.webgpu.webhint-icon.webhint.webhooks.webix-icon.webix.webkit.weblate.webmin.webpack.webplatform.webrtc.websocket.webstorm.webtorrent.weebly.whalar-icon.whalar.whatsapp-icon.whatsapp-monochrome-icon.whatsapp.whatwg.wicket-icon.wicket.wifi.wildfly.windi-css.windows11.windows8.winglang-icon.winglang.wire.wix.wmr.woo-commerce.woocommerce-icon.woopra.wordpress-icon-alt.wordpress-icon.wordpress.workboard.workos-icon.workos.workplace-icon.workplace.wpengine.wufoo.x.xamarin.xampp.xata-icon.xata.xcart.xcode.xero.xml.xray-for-jira.xstate.xtend.xwiki-icon.xwiki.yahoo.yaml.yammer.yandex-ru.yarn.ycombinator.yeoman.yii-framework.yii.youtrack.youtube-icon.youtube.yugabyte-icon.yugabyte.yuno-host.zabbix.zapier.zend-framework.zendesk-icon.zendesk.zenhub-icon.zenhub.zeplin.zeroheight-icon.zeroheight.zig.zod.zoho.zoom-icon.zoom.zorin-os.zsh.zube.zulip-icon.zulip.zwave`.split(`.`),bootstrap:`0-circle-fill.0-circle.0-square-fill.0-square.1-circle-fill.1-circle.1-square-fill.1-square.123.2-circle-fill.2-circle.2-square-fill.2-square.3-circle-fill.3-circle.3-square-fill.3-square.4-circle-fill.4-circle.4-square-fill.4-square.5-circle-fill.5-circle.5-square-fill.5-square.6-circle-fill.6-circle.6-square-fill.6-square.7-circle-fill.7-circle.7-square-fill.7-square.8-circle-fill.8-circle.8-square-fill.8-square.9-circle-fill.9-circle.9-square-fill.9-square.activity.airplane-engines-fill.airplane-engines.airplane-fill.airplane.alarm-fill.alarm.alexa.align-bottom.align-center.align-end.align-middle.align-start.align-top.alipay.alphabet-uppercase.alphabet.alt.amazon.amd.android.android2.app-indicator.app.apple.archive-fill.archive.arrow-90deg-down.arrow-90deg-left.arrow-90deg-right.arrow-90deg-up.arrow-bar-down.arrow-bar-left.arrow-bar-right.arrow-bar-up.arrow-clockwise.arrow-counterclockwise.arrow-down-circle-fill.arrow-down-circle.arrow-down-left-circle-fill.arrow-down-left-circle.arrow-down-left-square-fill.arrow-down-left-square.arrow-down-left.arrow-down-right-circle-fill.arrow-down-right-circle.arrow-down-right-square-fill.arrow-down-right-square.arrow-down-right.arrow-down-short.arrow-down-square-fill.arrow-down-square.arrow-down-up.arrow-down.arrow-left-circle-fill.arrow-left-circle.arrow-left-right.arrow-left-short.arrow-left-square-fill.arrow-left-square.arrow-left.arrow-repeat.arrow-return-left.arrow-return-right.arrow-right-circle-fill.arrow-right-circle.arrow-right-short.arrow-right-square-fill.arrow-right-square.arrow-right.arrow-through-heart-fill.arrow-through-heart.arrow-up-circle-fill.arrow-up-circle.arrow-up-left-circle-fill.arrow-up-left-circle.arrow-up-left-square-fill.arrow-up-left-square.arrow-up-left.arrow-up-right-circle-fill.arrow-up-right-circle.arrow-up-right-square-fill.arrow-up-right-square.arrow-up-right.arrow-up-short.arrow-up-square-fill.arrow-up-square.arrow-up.arrows-angle-contract.arrows-angle-expand.arrows-collapse-vertical.arrows-collapse.arrows-expand-vertical.arrows-expand.arrows-fullscreen.arrows-move.arrows-vertical.arrows.aspect-ratio-fill.aspect-ratio.asterisk.at.award-fill.award.back.backpack-fill.backpack.backpack2-fill.backpack2.backpack3-fill.backpack3.backpack4-fill.backpack4.backspace-fill.backspace-reverse-fill.backspace-reverse.backspace.badge-3d-fill.badge-3d.badge-4k-fill.badge-4k.badge-8k-fill.badge-8k.badge-ad-fill.badge-ad.badge-ar-fill.badge-ar.badge-cc-fill.badge-cc.badge-hd-fill.badge-hd.badge-sd-fill.badge-sd.badge-tm-fill.badge-tm.badge-vo-fill.badge-vo.badge-vr-fill.badge-vr.badge-wc-fill.badge-wc.bag-check-fill.bag-check.bag-dash-fill.bag-dash.bag-fill.bag-heart-fill.bag-heart.bag-plus-fill.bag-plus.bag-x-fill.bag-x.bag.balloon-fill.balloon-heart-fill.balloon-heart.balloon.ban-fill.ban.bandaid-fill.bandaid.bank.bank2.bar-chart-fill.bar-chart-line-fill.bar-chart-line.bar-chart-steps.bar-chart.basket-fill.basket.basket2-fill.basket2.basket3-fill.basket3.battery-charging.battery-full.battery-half.battery.behance.bell-fill.bell-slash-fill.bell-slash.bell.bezier.bezier2.bicycle.bing.binoculars-fill.binoculars.blockquote-left.blockquote-right.bluetooth.body-text.book-fill.book-half.book.bookmark-check-fill.bookmark-check.bookmark-dash-fill.bookmark-dash.bookmark-fill.bookmark-heart-fill.bookmark-heart.bookmark-plus-fill.bookmark-plus.bookmark-star-fill.bookmark-star.bookmark-x-fill.bookmark-x.bookmark.bookmarks-fill.bookmarks.bookshelf.boombox-fill.boombox.bootstrap-fill.bootstrap-icons.bootstrap-reboot.bootstrap.border-all.border-bottom.border-center.border-inner.border-left.border-middle.border-outer.border-right.border-style.border-top.border-width.border.bounding-box-circles.bounding-box.box-arrow-down-left.box-arrow-down-right.box-arrow-down.box-arrow-in-down-left.box-arrow-in-down-right.box-arrow-in-down.box-arrow-in-left.box-arrow-in-right.box-arrow-in-up-left.box-arrow-in-up-right.box-arrow-in-up.box-arrow-left.box-arrow-right.box-arrow-up-left.box-arrow-up-right.box-arrow-up.box-fill.box-seam-fill.box-seam.box.box2-fill.box2-heart-fill.box2-heart.box2.boxes.braces-asterisk.braces.bricks.briefcase-fill.briefcase.brightness-alt-high-fill.brightness-alt-high.brightness-alt-low-fill.brightness-alt-low.brightness-high-fill.brightness-high.brightness-low-fill.brightness-low.brilliance.broadcast-pin.broadcast.browser-chrome.browser-edge.browser-firefox.browser-safari.brush-fill.brush.bucket-fill.bucket.bug-fill.bug.building-add.building-check.building-dash.building-down.building-exclamation.building-fill-add.building-fill-check.building-fill-dash.building-fill-down.building-fill-exclamation.building-fill-gear.building-fill-lock.building-fill-slash.building-fill-up.building-fill-x.building-fill.building-gear.building-lock.building-slash.building-up.building-x.building.buildings-fill.buildings.bullseye.bus-front-fill.bus-front.c-circle-fill.c-circle.c-square-fill.c-square.cake-fill.cake.cake2-fill.cake2.calculator-fill.calculator.calendar-check-fill.calendar-check.calendar-date-fill.calendar-date.calendar-day-fill.calendar-day.calendar-event-fill.calendar-event.calendar-fill.calendar-heart-fill.calendar-heart.calendar-minus-fill.calendar-minus.calendar-month-fill.calendar-month.calendar-plus-fill.calendar-plus.calendar-range-fill.calendar-range.calendar-week-fill.calendar-week.calendar-x-fill.calendar-x.calendar.calendar2-check-fill.calendar2-check.calendar2-date-fill.calendar2-date.calendar2-day-fill.calendar2-day.calendar2-event-fill.calendar2-event.calendar2-fill.calendar2-heart-fill.calendar2-heart.calendar2-minus-fill.calendar2-minus.calendar2-month-fill.calendar2-month.calendar2-plus-fill.calendar2-plus.calendar2-range-fill.calendar2-range.calendar2-week-fill.calendar2-week.calendar2-x-fill.calendar2-x.calendar2.calendar3-event-fill.calendar3-event.calendar3-fill.calendar3-range-fill.calendar3-range.calendar3-week-fill.calendar3-week.calendar3.calendar4-event.calendar4-range.calendar4-week.calendar4.camera-fill.camera-reels-fill.camera-reels.camera-video-fill.camera-video-off-fill.camera-video-off.camera-video.camera.camera2.capslock-fill.capslock.capsule-pill.capsule.car-front-fill.car-front.card-checklist.card-heading.card-image.card-list.card-text.caret-down-fill.caret-down-square-fill.caret-down-square.caret-down.caret-left-fill.caret-left-square-fill.caret-left-square.caret-left.caret-right-fill.caret-right-square-fill.caret-right-square.caret-right.caret-up-fill.caret-up-square-fill.caret-up-square.caret-up.cart-check-fill.cart-check.cart-dash-fill.cart-dash.cart-fill.cart-plus-fill.cart-plus.cart-x-fill.cart-x.cart.cart2.cart3.cart4.cash-coin.cash-stack.cash.cassette-fill.cassette.cast.cc-circle-fill.cc-circle.cc-square-fill.cc-square.chat-dots-fill.chat-dots.chat-fill.chat-heart-fill.chat-heart.chat-left-dots-fill.chat-left-dots.chat-left-fill.chat-left-heart-fill.chat-left-heart.chat-left-quote-fill.chat-left-quote.chat-left-text-fill.chat-left-text.chat-left.chat-quote-fill.chat-quote.chat-right-dots-fill.chat-right-dots.chat-right-fill.chat-right-heart-fill.chat-right-heart.chat-right-quote-fill.chat-right-quote.chat-right-text-fill.chat-right-text.chat-right.chat-square-dots-fill.chat-square-dots.chat-square-fill.chat-square-heart-fill.chat-square-heart.chat-square-quote-fill.chat-square-quote.chat-square-text-fill.chat-square-text.chat-square.chat-text-fill.chat-text.chat.check-all.check-circle-fill.check-circle.check-lg.check-square-fill.check-square.check.check2-all.check2-circle.check2-square.check2.chevron-bar-contract.chevron-bar-down.chevron-bar-expand.chevron-bar-left.chevron-bar-right.chevron-bar-up.chevron-compact-down.chevron-compact-left.chevron-compact-right.chevron-compact-up.chevron-contract.chevron-double-down.chevron-double-left.chevron-double-right.chevron-double-up.chevron-down.chevron-expand.chevron-left.chevron-right.chevron-up.circle-fill.circle-half.circle-square.circle.clipboard-check-fill.clipboard-check.clipboard-data-fill.clipboard-data.clipboard-fill.clipboard-heart-fill.clipboard-heart.clipboard-minus-fill.clipboard-minus.clipboard-plus-fill.clipboard-plus.clipboard-pulse.clipboard-x-fill.clipboard-x.clipboard.clipboard2-check-fill.clipboard2-check.clipboard2-data-fill.clipboard2-data.clipboard2-fill.clipboard2-heart-fill.clipboard2-heart.clipboard2-minus-fill.clipboard2-minus.clipboard2-plus-fill.clipboard2-plus.clipboard2-pulse-fill.clipboard2-pulse.clipboard2-x-fill.clipboard2-x.clipboard2.clock-fill.clock-history.clock.cloud-arrow-down-fill.cloud-arrow-down.cloud-arrow-up-fill.cloud-arrow-up.cloud-check-fill.cloud-check.cloud-download-fill.cloud-download.cloud-drizzle-fill.cloud-drizzle.cloud-fill.cloud-fog-fill.cloud-fog.cloud-fog2-fill.cloud-fog2.cloud-hail-fill.cloud-hail.cloud-haze-fill.cloud-haze.cloud-haze2-fill.cloud-haze2.cloud-lightning-fill.cloud-lightning-rain-fill.cloud-lightning-rain.cloud-lightning.cloud-minus-fill.cloud-minus.cloud-moon-fill.cloud-moon.cloud-plus-fill.cloud-plus.cloud-rain-fill.cloud-rain-heavy-fill.cloud-rain-heavy.cloud-rain.cloud-slash-fill.cloud-slash.cloud-sleet-fill.cloud-sleet.cloud-snow-fill.cloud-snow.cloud-sun-fill.cloud-sun.cloud-upload-fill.cloud-upload.cloud.clouds-fill.clouds.cloudy-fill.cloudy.code-slash.code-square.code.coin.collection-fill.collection-play-fill.collection-play.collection.columns-gap.columns.command.compass-fill.compass.cone-striped.cone.controller.cookie.copy.cpu-fill.cpu.credit-card-2-back-fill.credit-card-2-back.credit-card-2-front-fill.credit-card-2-front.credit-card-fill.credit-card.crop.crosshair.crosshair2.cup-fill.cup-hot-fill.cup-hot.cup-straw.cup.currency-bitcoin.currency-dollar.currency-euro.currency-exchange.currency-pound.currency-rupee.currency-yen.cursor-fill.cursor-text.cursor.dash-circle-dotted.dash-circle-fill.dash-circle.dash-lg.dash-square-dotted.dash-square-fill.dash-square.dash.database-add.database-check.database-dash.database-down.database-exclamation.database-fill-add.database-fill-check.database-fill-dash.database-fill-down.database-fill-exclamation.database-fill-gear.database-fill-lock.database-fill-slash.database-fill-up.database-fill-x.database-fill.database-gear.database-lock.database-slash.database-up.database-x.database.device-hdd-fill.device-hdd.device-ssd-fill.device-ssd.diagram-2-fill.diagram-2.diagram-3-fill.diagram-3.diamond-fill.diamond-half.diamond.dice-1-fill.dice-1.dice-2-fill.dice-2.dice-3-fill.dice-3.dice-4-fill.dice-4.dice-5-fill.dice-5.dice-6-fill.dice-6.disc-fill.disc.discord.display-fill.display.displayport-fill.displayport.distribute-horizontal.distribute-vertical.door-closed-fill.door-closed.door-open-fill.door-open.dot.download.dpad-fill.dpad.dribbble.dropbox.droplet-fill.droplet-half.droplet.duffle-fill.duffle.ear-fill.ear.earbuds.easel-fill.easel.easel2-fill.easel2.easel3-fill.easel3.egg-fill.egg-fried.egg.eject-fill.eject.emoji-angry-fill.emoji-angry.emoji-astonished-fill.emoji-astonished.emoji-dizzy-fill.emoji-dizzy.emoji-expressionless-fill.emoji-expressionless.emoji-frown-fill.emoji-frown.emoji-grimace-fill.emoji-grimace.emoji-grin-fill.emoji-grin.emoji-heart-eyes-fill.emoji-heart-eyes.emoji-kiss-fill.emoji-kiss.emoji-laughing-fill.emoji-laughing.emoji-neutral-fill.emoji-neutral.emoji-smile-fill.emoji-smile-upside-down-fill.emoji-smile-upside-down.emoji-smile.emoji-sunglasses-fill.emoji-sunglasses.emoji-surprise-fill.emoji-surprise.emoji-tear-fill.emoji-tear.emoji-wink-fill.emoji-wink.envelope-arrow-down-fill.envelope-arrow-down.envelope-arrow-up-fill.envelope-arrow-up.envelope-at-fill.envelope-at.envelope-check-fill.envelope-check.envelope-dash-fill.envelope-dash.envelope-exclamation-fill.envelope-exclamation.envelope-fill.envelope-heart-fill.envelope-heart.envelope-open-fill.envelope-open-heart-fill.envelope-open-heart.envelope-open.envelope-paper-fill.envelope-paper-heart-fill.envelope-paper-heart.envelope-paper.envelope-plus-fill.envelope-plus.envelope-slash-fill.envelope-slash.envelope-x-fill.envelope-x.envelope.eraser-fill.eraser.escape.ethernet.ev-front-fill.ev-front.ev-station-fill.ev-station.exclamation-circle-fill.exclamation-circle.exclamation-diamond-fill.exclamation-diamond.exclamation-lg.exclamation-octagon-fill.exclamation-octagon.exclamation-square-fill.exclamation-square.exclamation-triangle-fill.exclamation-triangle.exclamation.exclude.explicit-fill.explicit.exposure.eye-fill.eye-slash-fill.eye-slash.eye.eyedropper.eyeglasses.facebook.fan.fast-forward-btn-fill.fast-forward-btn.fast-forward-circle-fill.fast-forward-circle.fast-forward-fill.fast-forward.feather.feather2.file-arrow-down-fill.file-arrow-down.file-arrow-up-fill.file-arrow-up.file-bar-graph-fill.file-bar-graph.file-binary-fill.file-binary.file-break-fill.file-break.file-check-fill.file-check.file-code-fill.file-code.file-diff-fill.file-diff.file-earmark-arrow-down-fill.file-earmark-arrow-down.file-earmark-arrow-up-fill.file-earmark-arrow-up.file-earmark-bar-graph-fill.file-earmark-bar-graph.file-earmark-binary-fill.file-earmark-binary.file-earmark-break-fill.file-earmark-break.file-earmark-check-fill.file-earmark-check.file-earmark-code-fill.file-earmark-code.file-earmark-diff-fill.file-earmark-diff.file-earmark-easel-fill.file-earmark-easel.file-earmark-excel-fill.file-earmark-excel.file-earmark-fill.file-earmark-font-fill.file-earmark-font.file-earmark-image-fill.file-earmark-image.file-earmark-lock-fill.file-earmark-lock.file-earmark-lock2-fill.file-earmark-lock2.file-earmark-medical-fill.file-earmark-medical.file-earmark-minus-fill.file-earmark-minus.file-earmark-music-fill.file-earmark-music.file-earmark-pdf-fill.file-earmark-pdf.file-earmark-person-fill.file-earmark-person.file-earmark-play-fill.file-earmark-play.file-earmark-plus-fill.file-earmark-plus.file-earmark-post-fill.file-earmark-post.file-earmark-ppt-fill.file-earmark-ppt.file-earmark-richtext-fill.file-earmark-richtext.file-earmark-ruled-fill.file-earmark-ruled.file-earmark-slides-fill.file-earmark-slides.file-earmark-spreadsheet-fill.file-earmark-spreadsheet.file-earmark-text-fill.file-earmark-text.file-earmark-word-fill.file-earmark-word.file-earmark-x-fill.file-earmark-x.file-earmark-zip-fill.file-earmark-zip.file-earmark.file-easel-fill.file-easel.file-excel-fill.file-excel.file-fill.file-font-fill.file-font.file-image-fill.file-image.file-lock-fill.file-lock.file-lock2-fill.file-lock2.file-medical-fill.file-medical.file-minus-fill.file-minus.file-music-fill.file-music.file-pdf-fill.file-pdf.file-person-fill.file-person.file-play-fill.file-play.file-plus-fill.file-plus.file-post-fill.file-post.file-ppt-fill.file-ppt.file-richtext-fill.file-richtext.file-ruled-fill.file-ruled.file-slides-fill.file-slides.file-spreadsheet-fill.file-spreadsheet.file-text-fill.file-text.file-word-fill.file-word.file-x-fill.file-x.file-zip-fill.file-zip.file.files-alt.files.filetype-aac.filetype-ai.filetype-bmp.filetype-cs.filetype-css.filetype-csv.filetype-doc.filetype-docx.filetype-exe.filetype-gif.filetype-heic.filetype-html.filetype-java.filetype-jpg.filetype-js.filetype-json.filetype-jsx.filetype-key.filetype-m4p.filetype-md.filetype-mdx.filetype-mov.filetype-mp3.filetype-mp4.filetype-otf.filetype-pdf.filetype-php.filetype-png.filetype-ppt.filetype-pptx.filetype-psd.filetype-py.filetype-raw.filetype-rb.filetype-sass.filetype-scss.filetype-sh.filetype-sql.filetype-svg.filetype-tiff.filetype-tsx.filetype-ttf.filetype-txt.filetype-wav.filetype-woff.filetype-xls.filetype-xlsx.filetype-xml.filetype-yml.film.filter-circle-fill.filter-circle.filter-left.filter-right.filter-square-fill.filter-square.filter.fingerprint.fire.flag-fill.flag.floppy-fill.floppy.floppy2-fill.floppy2.flower1.flower2.flower3.folder-check.folder-fill.folder-minus.folder-plus.folder-symlink-fill.folder-symlink.folder-x.folder.folder2-open.folder2.fonts.forward-fill.forward.front.fuel-pump-diesel-fill.fuel-pump-diesel.fuel-pump-fill.fuel-pump.fullscreen-exit.fullscreen.funnel-fill.funnel.gear-fill.gear-wide-connected.gear-wide.gear.gem.gender-ambiguous.gender-female.gender-male.gender-neuter.gender-trans.geo-alt-fill.geo-alt.geo-fill.geo.gift-fill.gift.git.github.gitlab.globe-americas.globe-asia-australia.globe-central-south-asia.globe-europe-africa.globe.globe2.google-play.google.gpu-card.graph-down-arrow.graph-down.graph-up-arrow.graph-up.grid-1x2-fill.grid-1x2.grid-3x2-gap-fill.grid-3x2-gap.grid-3x2.grid-3x3-gap-fill.grid-3x3-gap.grid-3x3.grid-fill.grid.grip-horizontal.grip-vertical.h-circle-fill.h-circle.h-square-fill.h-square.hammer.hand-index-fill.hand-index-thumb-fill.hand-index-thumb.hand-index.hand-thumbs-down-fill.hand-thumbs-down.hand-thumbs-up-fill.hand-thumbs-up.handbag-fill.handbag.hash.hdd-fill.hdd-network-fill.hdd-network.hdd-rack-fill.hdd-rack.hdd-stack-fill.hdd-stack.hdd.hdmi-fill.hdmi.headphones.headset-vr.headset.heart-arrow.heart-fill.heart-half.heart-pulse-fill.heart-pulse.heart.heartbreak-fill.heartbreak.hearts.heptagon-fill.heptagon-half.heptagon.hexagon-fill.hexagon-half.hexagon.highlighter.highlights.hospital-fill.hospital.hourglass-bottom.hourglass-split.hourglass-top.hourglass.house-add-fill.house-add.house-check-fill.house-check.house-dash-fill.house-dash.house-door-fill.house-door.house-down-fill.house-down.house-exclamation-fill.house-exclamation.house-fill.house-gear-fill.house-gear.house-heart-fill.house-heart.house-lock-fill.house-lock.house-slash-fill.house-slash.house-up-fill.house-up.house-x-fill.house-x.house.houses-fill.houses.hr.hurricane.hypnotize.image-alt.image-fill.image.images.inbox-fill.inbox.inboxes-fill.inboxes.incognito.indent.infinity.info-circle-fill.info-circle.info-lg.info-square-fill.info-square.info.input-cursor-text.input-cursor.instagram.intersect.journal-album.journal-arrow-down.journal-arrow-up.journal-bookmark-fill.journal-bookmark.journal-check.journal-code.journal-medical.journal-minus.journal-plus.journal-richtext.journal-text.journal-x.journal.journals.joystick.justify-left.justify-right.justify.kanban-fill.kanban.key-fill.key.keyboard-fill.keyboard.ladder.lamp-fill.lamp.laptop-fill.laptop.layer-backward.layer-forward.layers-fill.layers-half.layers.layout-sidebar-inset-reverse.layout-sidebar-inset.layout-sidebar-reverse.layout-sidebar.layout-split.layout-text-sidebar-reverse.layout-text-sidebar.layout-text-window-reverse.layout-text-window.layout-three-columns.layout-wtf.life-preserver.lightbulb-fill.lightbulb-off-fill.lightbulb-off.lightbulb.lightning-charge-fill.lightning-charge.lightning-fill.lightning.line.link-45deg.link.linkedin.list-check.list-columns-reverse.list-columns.list-nested.list-ol.list-stars.list-task.list-ul.list.lock-fill.lock.luggage-fill.luggage.lungs-fill.lungs.magic.magnet-fill.magnet.mailbox-flag.mailbox.mailbox2-flag.mailbox2.map-fill.map.markdown-fill.markdown.marker-tip.mask.mastodon.medium.megaphone-fill.megaphone.memory.menu-app-fill.menu-app.menu-button-fill.menu-button-wide-fill.menu-button-wide.menu-button.menu-down.menu-up.messenger.meta.mic-fill.mic-mute-fill.mic-mute.mic.microsoft-teams.microsoft.minecart-loaded.minecart.modem-fill.modem.moisture.moon-fill.moon-stars-fill.moon-stars.moon.mortarboard-fill.mortarboard.motherboard-fill.motherboard.mouse-fill.mouse.mouse2-fill.mouse2.mouse3-fill.mouse3.music-note-beamed.music-note-list.music-note.music-player-fill.music-player.newspaper.nintendo-switch.node-minus-fill.node-minus.node-plus-fill.node-plus.noise-reduction.nut-fill.nut.nvidia.nvme-fill.nvme.octagon-fill.octagon-half.octagon.opencollective.optical-audio-fill.optical-audio.option.outlet.p-circle-fill.p-circle.p-square-fill.p-square.paint-bucket.palette-fill.palette.palette2.paperclip.paragraph.pass-fill.pass.passport-fill.passport.patch-check-fill.patch-check.patch-exclamation-fill.patch-exclamation.patch-minus-fill.patch-minus.patch-plus-fill.patch-plus.patch-question-fill.patch-question.pause-btn-fill.pause-btn.pause-circle-fill.pause-circle.pause-fill.pause.paypal.pc-display-horizontal.pc-display.pc-horizontal.pc.pci-card-network.pci-card-sound.pci-card.peace-fill.peace.pen-fill.pen.pencil-fill.pencil-square.pencil.pentagon-fill.pentagon-half.pentagon.people-fill.people.percent.person-add.person-arms-up.person-badge-fill.person-badge.person-bounding-box.person-check-fill.person-check.person-circle.person-dash-fill.person-dash.person-down.person-exclamation.person-fill-add.person-fill-check.person-fill-dash.person-fill-down.person-fill-exclamation.person-fill-gear.person-fill-lock.person-fill-slash.person-fill-up.person-fill-x.person-fill.person-gear.person-heart.person-hearts.person-lines-fill.person-lock.person-plus-fill.person-plus.person-raised-hand.person-rolodex.person-slash.person-square.person-standing-dress.person-standing.person-up.person-vcard-fill.person-vcard.person-video.person-video2.person-video3.person-walking.person-wheelchair.person-workspace.person-x-fill.person-x.person.phone-fill.phone-flip.phone-landscape-fill.phone-landscape.phone-vibrate-fill.phone-vibrate.phone.pie-chart-fill.pie-chart.piggy-bank-fill.piggy-bank.pin-angle-fill.pin-angle.pin-fill.pin-map-fill.pin-map.pin.pinterest.pip-fill.pip.play-btn-fill.play-btn.play-circle-fill.play-circle.play-fill.play.playstation.plug-fill.plug.plugin.plus-circle-dotted.plus-circle-fill.plus-circle.plus-lg.plus-slash-minus.plus-square-dotted.plus-square-fill.plus-square.plus.postage-fill.postage-heart-fill.postage-heart.postage.postcard-fill.postcard-heart-fill.postcard-heart.postcard.power.prescription.prescription2.printer-fill.printer.projector-fill.projector.puzzle-fill.puzzle.qr-code-scan.qr-code.question-circle-fill.question-circle.question-diamond-fill.question-diamond.question-lg.question-octagon-fill.question-octagon.question-square-fill.question-square.question.quora.quote.r-circle-fill.r-circle.r-square-fill.r-square.radar.radioactive.rainbow.receipt-cutoff.receipt.reception-0.reception-1.reception-2.reception-3.reception-4.record-btn-fill.record-btn.record-circle-fill.record-circle.record-fill.record.record2-fill.record2.recycle.reddit.regex.repeat-1.repeat.reply-all-fill.reply-all.reply-fill.reply.rewind-btn-fill.rewind-btn.rewind-circle-fill.rewind-circle.rewind-fill.rewind.robot.rocket-fill.rocket-takeoff-fill.rocket-takeoff.rocket.router-fill.router.rss-fill.rss.rulers.safe-fill.safe.safe2-fill.safe2.save-fill.save.save2-fill.save2.scissors.scooter.screwdriver.sd-card-fill.sd-card.search-heart-fill.search-heart.search.segmented-nav.send-arrow-down-fill.send-arrow-down.send-arrow-up-fill.send-arrow-up.send-check-fill.send-check.send-dash-fill.send-dash.send-exclamation-fill.send-exclamation.send-fill.send-plus-fill.send-plus.send-slash-fill.send-slash.send-x-fill.send-x.send.server.shadows.share-fill.share.shield-check.shield-exclamation.shield-fill-check.shield-fill-exclamation.shield-fill-minus.shield-fill-plus.shield-fill-x.shield-fill.shield-lock-fill.shield-lock.shield-minus.shield-plus.shield-shaded.shield-slash-fill.shield-slash.shield-x.shield.shift-fill.shift.shop-window.shop.shuffle.sign-dead-end-fill.sign-dead-end.sign-do-not-enter-fill.sign-do-not-enter.sign-intersection-fill.sign-intersection-side-fill.sign-intersection-side.sign-intersection-t-fill.sign-intersection-t.sign-intersection-y-fill.sign-intersection-y.sign-intersection.sign-merge-left-fill.sign-merge-left.sign-merge-right-fill.sign-merge-right.sign-no-left-turn-fill.sign-no-left-turn.sign-no-parking-fill.sign-no-parking.sign-no-right-turn-fill.sign-no-right-turn.sign-railroad-fill.sign-railroad.sign-stop-fill.sign-stop-lights-fill.sign-stop-lights.sign-stop.sign-turn-left-fill.sign-turn-left.sign-turn-right-fill.sign-turn-right.sign-turn-slight-left-fill.sign-turn-slight-left.sign-turn-slight-right-fill.sign-turn-slight-right.sign-yield-fill.sign-yield.signal.signpost-2-fill.signpost-2.signpost-fill.signpost-split-fill.signpost-split.signpost.sim-fill.sim-slash-fill.sim-slash.sim.sina-weibo.skip-backward-btn-fill.skip-backward-btn.skip-backward-circle-fill.skip-backward-circle.skip-backward-fill.skip-backward.skip-end-btn-fill.skip-end-btn.skip-end-circle-fill.skip-end-circle.skip-end-fill.skip-end.skip-forward-btn-fill.skip-forward-btn.skip-forward-circle-fill.skip-forward-circle.skip-forward-fill.skip-forward.skip-start-btn-fill.skip-start-btn.skip-start-circle-fill.skip-start-circle.skip-start-fill.skip-start.skype.slack.slash-circle-fill.slash-circle.slash-lg.slash-square-fill.slash-square.slash.sliders.sliders2-vertical.sliders2.smartwatch.snapchat.snow.snow2.snow3.sort-alpha-down-alt.sort-alpha-down.sort-alpha-up-alt.sort-alpha-up.sort-down-alt.sort-down.sort-numeric-down-alt.sort-numeric-down.sort-numeric-up-alt.sort-numeric-up.sort-up-alt.sort-up.soundwave.sourceforge.speaker-fill.speaker.speedometer.speedometer2.spellcheck.spotify.square-fill.square-half.square.stack-overflow.stack.star-fill.star-half.star.stars.steam.stickies-fill.stickies.sticky-fill.sticky.stop-btn-fill.stop-btn.stop-circle-fill.stop-circle.stop-fill.stop.stoplights-fill.stoplights.stopwatch-fill.stopwatch.strava.stripe.subscript.substack.subtract.suit-club-fill.suit-club.suit-diamond-fill.suit-diamond.suit-heart-fill.suit-heart.suit-spade-fill.suit-spade.suitcase-fill.suitcase-lg-fill.suitcase-lg.suitcase.suitcase2-fill.suitcase2.sun-fill.sun.sunglasses.sunrise-fill.sunrise.sunset-fill.sunset.superscript.symmetry-horizontal.symmetry-vertical.table.tablet-fill.tablet-landscape-fill.tablet-landscape.tablet.tag-fill.tag.tags-fill.tags.taxi-front-fill.taxi-front.telegram.telephone-fill.telephone-forward-fill.telephone-forward.telephone-inbound-fill.telephone-inbound.telephone-minus-fill.telephone-minus.telephone-outbound-fill.telephone-outbound.telephone-plus-fill.telephone-plus.telephone-x-fill.telephone-x.telephone.tencent-qq.terminal-dash.terminal-fill.terminal-plus.terminal-split.terminal-x.terminal.text-center.text-indent-left.text-indent-right.text-left.text-paragraph.text-right.text-wrap.textarea-resize.textarea-t.textarea.thermometer-half.thermometer-high.thermometer-low.thermometer-snow.thermometer-sun.thermometer.threads-fill.threads.three-dots-vertical.three-dots.thunderbolt-fill.thunderbolt.ticket-detailed-fill.ticket-detailed.ticket-fill.ticket-perforated-fill.ticket-perforated.ticket.tiktok.toggle-off.toggle-on.toggle2-off.toggle2-on.toggles.toggles2.tools.tornado.train-freight-front-fill.train-freight-front.train-front-fill.train-front.train-lightrail-front-fill.train-lightrail-front.translate.transparency.trash-fill.trash.trash2-fill.trash2.trash3-fill.trash3.tree-fill.tree.trello.triangle-fill.triangle-half.triangle.trophy-fill.trophy.tropical-storm.truck-flatbed.truck-front-fill.truck-front.truck.tsunami.tv-fill.tv.twitch.twitter-x.twitter.type-bold.type-h1.type-h2.type-h3.type-h4.type-h5.type-h6.type-italic.type-strikethrough.type-underline.type.ubuntu.ui-checks-grid.ui-checks.ui-radios-grid.ui-radios.umbrella-fill.umbrella.unindent.union.unity.universal-access-circle.universal-access.unlock-fill.unlock.upc-scan.upc.upload.usb-c-fill.usb-c.usb-drive-fill.usb-drive.usb-fill.usb-micro-fill.usb-micro.usb-mini-fill.usb-mini.usb-plug-fill.usb-plug.usb-symbol.usb.valentine.valentine2.vector-pen.view-list.view-stacked.vignette.vimeo.vinyl-fill.vinyl.virus.virus2.voicemail.volume-down-fill.volume-down.volume-mute-fill.volume-mute.volume-off-fill.volume-off.volume-up-fill.volume-up.vr.wallet-fill.wallet.wallet2.watch.water.webcam-fill.webcam.wechat.whatsapp.wifi-1.wifi-2.wifi-off.wifi.wikipedia.wind.window-dash.window-desktop.window-dock.window-fullscreen.window-plus.window-sidebar.window-split.window-stack.window-x.window.windows.wordpress.wrench-adjustable-circle-fill.wrench-adjustable-circle.wrench-adjustable.wrench.x-circle-fill.x-circle.x-diamond-fill.x-diamond.x-lg.x-octagon-fill.x-octagon.x-square-fill.x-square.x.xbox.yelp.yin-yang.youtube.zoom-in.zoom-out`.split(`.`)})].flatMap(([e,t])=>t.map(t=>e+`:`+t)).map(e=>` `+e),` }`,`}`].join(`
|
|
43
|
-
`),ao=`likec4builtin`,oo=`${ao}:///likec4/lib/icons.c4`;function so(e){return(`uri`in e?e.uri:e).scheme===ao}function co(e){return!so(e)}var lo=class{toDispose=[];isDisposed=!1;onDispose(...e){this.toDispose.push(...e)}dispose(){this.throwIfDisposed(),this.isDisposed=!0;let e;for(;e=this.toDispose.pop();)try{e.dispose()}catch(e){V(e)}}throwIfDisposed(){if(this.isDisposed)throw Error(`This has already been disposed`)}};const uo=`AnyProperty`;function fo(e){return U.isInstance(e,uo)}const po=`ColorLiteral`;function mo(e){return U.isInstance(e,po)}const ho=`DeploymentElement`;function go(e){return U.isInstance(e,ho)}const _o=`DeploymentNodeOrElementKind`,vo=`DeploymentViewRule`;function yo(e){return U.isInstance(e,vo)}const bo=`DynamicViewProperty`,xo=`DynamicViewRule`;function So(e){return U.isInstance(e,xo)}const Co=`DynamicViewStep`;function wo(e){return U.isInstance(e,Co)}const To=`ElementProperty`;function Eo(e){return U.isInstance(e,To)}const Do=`ExpressionV2`;function Oo(e){return U.isInstance(e,Do)}const ko=`ExtendElementProperty`,Ao=`ExtendRelationProperty`,jo=`FqnExpr`;function Mo(e){return U.isInstance(e,jo)}const No=`FqnExprOrWhere`;function Po(e){return U.isInstance(e,No)}const Fo=`FqnExprOrWith`;function Io(e){return U.isInstance(e,Fo)}const Lo=`FqnReferenceable`,Ro=`LikeC4View`;function zo(e){return U.isInstance(e,Ro)}const Bo=`MetadataProperty`;function Vo(e){return U.isInstance(e,Bo)}const Ho=`MetadataValue`,Uo=`ModelReferenceable`,Wo=`Referenceable`,Go=`RelationExpr`;function Ko(e){return U.isInstance(e,Go)}const qo=`RelationExprOrWhere`;function Jo(e){return U.isInstance(e,qo)}const Yo=`RelationExprOrWith`;function Xo(e){return U.isInstance(e,Yo)}const Zo=`RelationProperty`,Qo=`RelationshipStyleProperty`;function $o(e){return U.isInstance(e,Qo)}const es=`SizeProperty`;function ts(e){return U.isInstance(e,es)}const ns=`StringProperty`;function rs(e){return U.isInstance(e,ns)}const is=`StyleProperty`;function as(e){return U.isInstance(e,is)}const os=`ViewProperty`;function ss(e){return U.isInstance(e,os)}const cs=`ViewRule`;function ls(e){return U.isInstance(e,cs)}const us=`ViewRuleStyleOrGlobalRef`;function ds(e){return U.isInstance(e,us)}const fs=`WhereElement`;function ps(e){return U.isInstance(e,fs)}const ms=`WhereElementExpression`;function hs(e){return U.isInstance(e,ms)}const gs=`WhereExpression`,_s=`WhereKindEqual`;function vs(e){return U.isInstance(e,_s)}const ys=`WhereMetadataEqual`;function bs(e){return U.isInstance(e,ys)}const xs=`WhereRelation`;function Ss(e){return U.isInstance(e,xs)}const Cs=`WhereRelationExpression`;function ws(e){return U.isInstance(e,Cs)}const Ts=`WhereTagEqual`;function Es(e){return U.isInstance(e,Ts)}const Ds=`AbstractDynamicStep`,Os=`ArrowProperty`;function ks(e){return U.isInstance(e,Os)}const As=`BorderProperty`;function js(e){return U.isInstance(e,As)}const Ms=`ColorProperty`;function Ns(e){return U.isInstance(e,Ms)}const Ps=`CustomColor`,Fs=`CustomElementProperties`;function Is(e){return U.isInstance(e,Fs)}const Ls=`CustomRelationProperties`;function Rs(e){return U.isInstance(e,Ls)}const zs=`DeployedInstance`;function Bs(e){return U.isInstance(e,zs)}const Vs=`DeployedInstanceBody`;function Hs(e){return U.isInstance(e,Vs)}const Us=`DeploymentNode`;function Ws(e){return U.isInstance(e,Us)}const Gs=`DeploymentNodeBody`;function Ks(e){return U.isInstance(e,Gs)}const qs=`DeploymentNodeKind`;function Js(e){return U.isInstance(e,qs)}const Ys=`DeploymentRelation`;function Xs(e){return U.isInstance(e,Ys)}const Zs=`DeploymentRelationBody`;function Qs(e){return U.isInstance(e,Zs)}const $s=`DeploymentView`;function ec(e){return U.isInstance(e,$s)}const tc=`DeploymentViewBody`;function nc(e){return U.isInstance(e,tc)}const rc=`DeploymentViewRulePredicate`;function ic(e){return U.isInstance(e,rc)}const ac=`DeploymentViewRuleStyle`;function oc(e){return U.isInstance(e,ac)}const sc=`DirectedRelationExpr`;function cc(e){return U.isInstance(e,sc)}const lc=`DynamicView`;function uc(e){return U.isInstance(e,lc)}const dc=`DynamicViewBody`;function fc(e){return U.isInstance(e,dc)}const pc=`DynamicViewDisplayVariantProperty`;function mc(e){return U.isInstance(e,pc)}const hc=`DynamicViewGlobalPredicateRef`;function gc(e){return U.isInstance(e,hc)}const _c=`DynamicViewIncludePredicate`;function vc(e){return U.isInstance(e,_c)}const yc=`DynamicViewParallelSteps`;function bc(e){return U.isInstance(e,yc)}const xc=`DynamicViewRef`,Sc=`Element`;function H(e){return U.isInstance(e,Sc)}const Cc=`ElementBody`;function wc(e){return U.isInstance(e,Cc)}const Tc=`ElementKind`;function Ec(e){return U.isInstance(e,Tc)}const Dc=`ElementKindExpression`;function Oc(e){return U.isInstance(e,Dc)}const kc=`ElementRef`;function Ac(e){return U.isInstance(e,kc)}const jc=`ElementStringProperty`;function Mc(e){return U.isInstance(e,jc)}const Nc=`ElementStyleProperty`;function Pc(e){return U.isInstance(e,Nc)}const Fc=`ElementTagExpression`;function Ic(e){return U.isInstance(e,Fc)}const Lc=`ElementView`;function Rc(e){return U.isInstance(e,Lc)}const zc=`ElementViewBody`;function Bc(e){return U.isInstance(e,zc)}const Vc=`ElementViewRef`,Hc=`Expressions`;function Uc(e){return U.isInstance(e,Hc)}const Wc=`ExtendDeployment`;function Gc(e){return U.isInstance(e,Wc)}const Kc=`ExtendDeploymentBody`;function qc(e){return U.isInstance(e,Kc)}const Jc=`ExtendElement`;function Yc(e){return U.isInstance(e,Jc)}const Xc=`ExtendElementBody`;function Zc(e){return U.isInstance(e,Xc)}const Qc=`ExtendRelation`;function $c(e){return U.isInstance(e,Qc)}const el=`ExtendRelationBody`;function tl(e){return U.isInstance(e,el)}const nl=`FqnExpressions`;function rl(e){return U.isInstance(e,nl)}const il=`FqnExprWhere`;function al(e){return U.isInstance(e,il)}const ol=`FqnExprWith`;function sl(e){return U.isInstance(e,ol)}const cl=`FqnRef`;function ll(e){return U.isInstance(e,cl)}const ul=`FqnRefExpr`;function dl(e){return U.isInstance(e,ul)}const fl=`GlobalDynamicPredicateGroup`;function pl(e){return U.isInstance(e,fl)}const ml=`GlobalPredicateGroup`;function hl(e){return U.isInstance(e,ml)}const gl=`Globals`;function _l(e){return U.isInstance(e,gl)}const vl=`GlobalStyle`;function yl(e){return U.isInstance(e,vl)}const bl=`GlobalStyleGroup`;function xl(e){return U.isInstance(e,bl)}const Sl=`GlobalStyleId`,Cl=`HexColor`;function wl(e){return U.isInstance(e,Cl)}const Tl=`IconColorProperty`;function El(e){return U.isInstance(e,Tl)}const Dl=`IconPositionProperty`;function Ol(e){return U.isInstance(e,Dl)}const kl=`IconProperty`;function Al(e){return U.isInstance(e,kl)}const jl=`IconSizeProperty`;function Ml(e){return U.isInstance(e,jl)}const Nl=`Imported`;function Pl(e){return U.isInstance(e,Nl)}const Fl=`ImportsFromPoject`;function Il(e){return U.isInstance(e,Fl)}const Ll=`IncomingRelationExpr`;function Rl(e){return U.isInstance(e,Ll)}const zl=`InOutRelationExpr`;function Bl(e){return U.isInstance(e,zl)}const Vl=`LibIcon`;function Hl(e){return U.isInstance(e,Vl)}const Ul=`LikeC4Grammar`;function Wl(e){return U.isInstance(e,Ul)}const Gl=`LikeC4Lib`;function Kl(e){return U.isInstance(e,Gl)}const ql=`LineProperty`;function Jl(e){return U.isInstance(e,ql)}const Yl=`LinkProperty`;function Xl(e){return U.isInstance(e,Yl)}const Zl=`MarkdownOrString`;function Ql(e){return U.isInstance(e,Zl)}const $l=`MetadataArray`;function eu(e){return U.isInstance(e,$l)}const tu=`MetadataAttribute`;function nu(e){return U.isInstance(e,tu)}const ru=`MetadataBody`;function iu(e){return U.isInstance(e,ru)}const au=`Model`;function ou(e){return U.isInstance(e,au)}const su=`ModelDeployments`;function cu(e){return U.isInstance(e,su)}const lu=`ModelViews`;function uu(e){return U.isInstance(e,lu)}const du=`MultipleProperty`;function fu(e){return U.isInstance(e,du)}const pu=`NavigateToProperty`;function mu(e){return U.isInstance(e,pu)}const hu=`NotationProperty`;function gu(e){return U.isInstance(e,hu)}const _u=`NotesProperty`;function vu(e){return U.isInstance(e,_u)}const yu=`OpacityProperty`;function bu(e){return U.isInstance(e,yu)}const xu=`OutgoingRelationExpr`;function Su(e){return U.isInstance(e,xu)}const Cu=`PaddingSizeProperty`;function wu(e){return U.isInstance(e,Cu)}const Tu=`Relation`;function Eu(e){return U.isInstance(e,Tu)}const Du=`RelationBody`;function Ou(e){return U.isInstance(e,Du)}const ku=`RelationExprWhere`;function Au(e){return U.isInstance(e,ku)}const ju=`RelationExprWith`;function Mu(e){return U.isInstance(e,ju)}const Nu=`RelationKindDotRef`;function Pu(e){return U.isInstance(e,Nu)}const Fu=`RelationNavigateToProperty`;function Iu(e){return U.isInstance(e,Fu)}const Lu=`RelationshipKind`;function Ru(e){return U.isInstance(e,Lu)}const zu=`RelationStringProperty`;function Bu(e){return U.isInstance(e,zu)}const Vu=`RelationStyleProperty`;function Hu(e){return U.isInstance(e,Vu)}const Uu=`RGBAColor`;function Wu(e){return U.isInstance(e,Uu)}const Gu=`ShapeProperty`;function Ku(e){return U.isInstance(e,Gu)}const qu=`ShapeSizeProperty`;function Ju(e){return U.isInstance(e,qu)}const Yu=`SpecificationColor`;function Xu(e){return U.isInstance(e,Yu)}const Zu=`SpecificationDeploymentNodeKind`;function Qu(e){return U.isInstance(e,Zu)}const $u=`SpecificationElementKind`;function ed(e){return U.isInstance(e,$u)}const td=`SpecificationElementStringProperty`;function nd(e){return U.isInstance(e,td)}const rd=`SpecificationRelationshipKind`;function id(e){return U.isInstance(e,rd)}const ad=`SpecificationRelationshipStringProperty`;function od(e){return U.isInstance(e,ad)}const sd=`SpecificationRule`;function cd(e){return U.isInstance(e,sd)}const ld=`SpecificationTag`;function ud(e){return U.isInstance(e,ld)}const dd=`StrictFqnElementRef`;function fd(e){return U.isInstance(e,dd)}const pd=`StrictFqnRef`;function md(e){return U.isInstance(e,pd)}function hd(e){return U.isInstance(e,`Tag`)}const gd=`TagRef`;function _d(e){return U.isInstance(e,gd)}const vd=`Tags`;function yd(e){return U.isInstance(e,vd)}const bd=`TextSizeProperty`;function xd(e){return U.isInstance(e,bd)}const Sd=`ViewRef`,Cd=`ViewRuleAutoLayout`;function wd(e){return U.isInstance(e,Cd)}const Td=`ViewRuleGlobalPredicateRef`;function Ed(e){return U.isInstance(e,Td)}const Dd=`ViewRuleGlobalStyle`;function Od(e){return U.isInstance(e,Dd)}const kd=`ViewRuleGroup`;function Ad(e){return U.isInstance(e,kd)}const jd=`ViewRulePredicate`;function Md(e){return U.isInstance(e,jd)}const Nd=`ViewRuleRank`;function Pd(e){return U.isInstance(e,Nd)}const Fd=`ViewRuleStyle`;function Id(e){return U.isInstance(e,Fd)}const Ld=`ViewStringProperty`;function Rd(e){return U.isInstance(e,Ld)}const zd=`WhereBinaryExpression`;function Bd(e){return U.isInstance(e,zd)}const Vd=`WhereElementKind`;function Hd(e){return U.isInstance(e,Vd)}const Ud=`WhereElementMetadata`;function Wd(e){return U.isInstance(e,Ud)}const Gd=`WhereElementNegation`;function Kd(e){return U.isInstance(e,Gd)}const qd=`WhereElementTag`;function Jd(e){return U.isInstance(e,qd)}const Yd=`WhereRelationKind`;function Xd(e){return U.isInstance(e,Yd)}const Zd=`WhereRelationMetadata`;function Qd(e){return U.isInstance(e,Zd)}const $d=`WhereRelationNegation`;function ef(e){return U.isInstance(e,$d)}const tf=`WhereRelationParticipantKind`;function nf(e){return U.isInstance(e,tf)}const rf=`WhereRelationParticipantMetadata`;function af(e){return U.isInstance(e,rf)}const of=`WhereRelationParticipantTag`;function sf(e){return U.isInstance(e,of)}const cf=`WhereRelationTag`;function lf(e){return U.isInstance(e,cf)}const uf=`WildcardExpression`;function df(e){return U.isInstance(e,uf)}const ff=`DynamicStepChain`;function pf(e){return U.isInstance(e,ff)}const mf=`DynamicStepSingle`;function hf(e){return U.isInstance(e,mf)}var gf=class extends un{getAllTypes(){return[Ds,uo,Os,As,po,Ms,Ps,Fs,Ls,zs,Vs,ho,Us,Gs,qs,_o,Ys,Zs,$s,tc,vo,rc,ac,sc,ff,mf,lc,dc,pc,hc,_c,yc,bo,xc,xo,Co,Sc,Cc,Tc,Dc,To,kc,jc,Nc,Fc,Lc,zc,Vc,Do,Hc,Wc,Kc,Jc,Xc,ko,Qc,el,Ao,jo,No,Fo,il,ol,nl,cl,ul,Lo,fl,ml,vl,bl,Sl,gl,Cl,Tl,Dl,kl,jl,Nl,Fl,zl,Ll,Vl,Ul,Gl,Ro,ql,Yl,Zl,$l,tu,ru,Bo,Ho,au,su,Uo,lu,du,pu,hu,_u,yu,xu,Cu,Uu,Wo,Tu,Du,Go,qo,Yo,ku,ju,Nu,Fu,Zo,zu,Vu,Lu,Qo,Gu,qu,es,Yu,Zu,$u,td,rd,ad,sd,ld,dd,pd,ns,is,`Tag`,gd,vd,bd,os,Sd,cs,Cd,Td,Dd,kd,jd,Nd,Fd,us,Ld,zd,fs,ms,Vd,Ud,Gd,qd,gs,_s,ys,xs,Cs,Yd,Zd,$d,tf,rf,of,cf,Ts,uf]}computeIsSubtype(e,t){switch(e){case Os:case ql:return this.isSubtype(Qo,t);case As:case Tl:case Dl:case du:case yu:case Gu:return this.isSubtype(is,t);case Ms:return this.isSubtype(Qo,t)||this.isSubtype(is,t);case zs:case Us:return this.isSubtype(ho,t)||this.isSubtype(Wo,t);case qs:case Tc:return this.isSubtype(_o,t);case $s:case lc:case Lc:return this.isSubtype(Ro,t);case rc:case ac:return this.isSubtype(vo,t);case sc:case Ll:case zl:case xu:return this.isSubtype(Go,t);case ff:case mf:return this.isSubtype(Ds,t)||this.isSubtype(Co,t);case pc:return this.isSubtype(bo,t);case hc:case _c:return this.isSubtype(xo,t);case bo:case To:case pu:case Zo:case Qo:case ns:case is:return this.isSubtype(uo,t);case Sc:return this.isSubtype(Lo,t)||this.isSubtype(Uo,t)||this.isSubtype(Wo,t);case Dc:case Fc:case ul:case uf:return this.isSubtype(jo,t);case jc:return this.isSubtype(To,t)||this.isSubtype(ns,t);case Nc:return this.isSubtype(To,t);case Wc:case Jc:case Wo:return this.isSubtype(Lo,t);case jo:case il:return this.isSubtype(No,t);case No:case ol:return this.isSubtype(Fo,t);case Fo:case Yo:return this.isSubtype(Do,t);case Cl:case Uu:return this.isSubtype(po,t);case kl:return this.isSubtype(To,t)||this.isSubtype(is,t);case jl:case Cu:case qu:case bd:return this.isSubtype(es,t)||this.isSubtype(is,t);case Nl:return this.isSubtype(Uo,t)||this.isSubtype(Wo,t);case Yl:return this.isSubtype(To,t)||this.isSubtype(ko,t)||this.isSubtype(Ao,t)||this.isSubtype(Zo,t)||this.isSubtype(os,t);case Zl:case $l:return this.isSubtype(Ho,t);case tu:case td:case ad:return this.isSubtype(ns,t);case ru:return this.isSubtype(Bo,t);case Bo:return this.isSubtype(To,t)||this.isSubtype(ko,t)||this.isSubtype(Ao,t)||this.isSubtype(Zo,t);case hu:case _u:return this.isSubtype(uo,t)||this.isSubtype(ns,t);case Go:case ku:return this.isSubtype(qo,t);case qo:case ju:return this.isSubtype(Yo,t);case Fu:case Vu:return this.isSubtype(Zo,t);case zu:return this.isSubtype(Zo,t)||this.isSubtype(ns,t);case os:return this.isSubtype(uo,t)||this.isSubtype(bo,t);case Cd:return this.isSubtype(vo,t)||this.isSubtype(xo,t)||this.isSubtype(cs,t);case Td:case kd:case jd:case Nd:return this.isSubtype(cs,t);case Dd:case Fd:return this.isSubtype(us,t);case us:return this.isSubtype(xo,t)||this.isSubtype(cs,t);case Ld:return this.isSubtype(ns,t)||this.isSubtype(os,t);case zd:return this.isSubtype(ms,t)||this.isSubtype(Cs,t);case fs:case Gd:return this.isSubtype(ms,t);case ms:case Cs:return this.isSubtype(gs,t);case Vd:return this.isSubtype(fs,t)||this.isSubtype(_s,t);case Ud:return this.isSubtype(fs,t)||this.isSubtype(ys,t);case qd:return this.isSubtype(fs,t)||this.isSubtype(Ts,t);case xs:case $d:return this.isSubtype(Cs,t);case Yd:case tf:return this.isSubtype(_s,t)||this.isSubtype(xs,t);case Zd:case rf:return this.isSubtype(ys,t)||this.isSubtype(xs,t);case of:case cf:return this.isSubtype(xs,t)||this.isSubtype(Ts,t);default:return!1}}getReferenceType(e){let t=`${e.container.$type}:${e.property}`;switch(t){case`AbstractDynamicStep:kind`:case`DeploymentRelation:kind`:case`DynamicStepChain:kind`:case`DynamicStepSingle:kind`:case`ExtendRelation:kind`:case`OutgoingRelationExpr:kind`:case`Relation:kind`:case`RelationKindDotRef:kind`:case`WhereRelationKind:value`:return Lu;case`ColorProperty:customColor`:case`IconColorProperty:customColor`:return Ps;case`DeploymentNode:kind`:return qs;case`DynamicViewGlobalPredicateRef:predicate`:return fl;case`DynamicViewRef:view`:return lc;case`Element:kind`:case`ElementKindExpression:kind`:return Tc;case`ElementViewRef:view`:return Lc;case`FqnRef:value`:case`StrictFqnRef:value`:return Wo;case`IconProperty:libicon`:return Vl;case`Imported:imported`:case`StrictFqnElementRef:el`:return Sc;case`TagRef:tag`:return`Tag`;case`ViewRef:view`:return Ro;case`ViewRuleGlobalPredicateRef:predicate`:return ml;case`ViewRuleGlobalStyle:style`:return Sl;case`WhereElementKind:value`:case`WhereRelationParticipantKind:value`:return _o;default:throw Error(`${t} is not a valid reference id.`)}}getTypeMetaData(e){switch(e){case Ds:return{name:Ds,properties:[{name:`custom`},{name:`dotKind`},{name:`kind`},{name:`target`},{name:`title`}]};case Os:return{name:Os,properties:[{name:`key`},{name:`value`}]};case As:return{name:As,properties:[{name:`key`},{name:`value`}]};case Ms:return{name:Ms,properties:[{name:`customColor`},{name:`key`},{name:`themeColor`}]};case Ps:return{name:Ps,properties:[{name:`name`}]};case Fs:return{name:Fs,properties:[{name:`props`,defaultValue:[]}]};case Ls:return{name:Ls,properties:[{name:`props`,defaultValue:[]}]};case zs:return{name:zs,properties:[{name:`body`},{name:`name`},{name:`summary`},{name:`target`},{name:`title`}]};case Vs:return{name:Vs,properties:[{name:`elements`,defaultValue:[]},{name:`props`,defaultValue:[]},{name:`tags`}]};case Us:return{name:Us,properties:[{name:`body`},{name:`kind`},{name:`name`},{name:`summary`},{name:`title`}]};case Gs:return{name:Gs,properties:[{name:`elements`,defaultValue:[]},{name:`props`,defaultValue:[]},{name:`tags`}]};case qs:return{name:qs,properties:[{name:`name`}]};case Ys:return{name:Ys,properties:[{name:`body`},{name:`description`},{name:`dotKind`},{name:`kind`},{name:`source`},{name:`tags`},{name:`target`},{name:`technology`},{name:`title`}]};case Zs:return{name:Zs,properties:[{name:`props`,defaultValue:[]},{name:`tags`}]};case $s:return{name:$s,properties:[{name:`body`},{name:`name`}]};case tc:return{name:tc,properties:[{name:`props`,defaultValue:[]},{name:`rules`,defaultValue:[]},{name:`tags`}]};case rc:return{name:rc,properties:[{name:`expr`},{name:`isInclude`,defaultValue:!1}]};case ac:return{name:ac,properties:[{name:`props`,defaultValue:[]},{name:`targets`}]};case sc:return{name:sc,properties:[{name:`source`},{name:`target`}]};case lc:return{name:lc,properties:[{name:`body`},{name:`name`}]};case dc:return{name:dc,properties:[{name:`props`,defaultValue:[]},{name:`rules`,defaultValue:[]},{name:`steps`,defaultValue:[]},{name:`tags`}]};case pc:return{name:pc,properties:[{name:`key`},{name:`value`}]};case hc:return{name:hc,properties:[{name:`predicate`}]};case _c:return{name:_c,properties:[{name:`exprs`}]};case yc:return{name:yc,properties:[{name:`steps`,defaultValue:[]}]};case xc:return{name:xc,properties:[{name:`view`}]};case Sc:return{name:Sc,properties:[{name:`body`},{name:`kind`},{name:`name`},{name:`props`,defaultValue:[]}]};case Cc:return{name:Cc,properties:[{name:`elements`,defaultValue:[]},{name:`props`,defaultValue:[]},{name:`tags`}]};case Tc:return{name:Tc,properties:[{name:`name`}]};case Dc:return{name:Dc,properties:[{name:`isEqual`,defaultValue:!1},{name:`kind`}]};case kc:return{name:kc,properties:[{name:`modelElement`}]};case jc:return{name:jc,properties:[{name:`key`},{name:`value`}]};case Nc:return{name:Nc,properties:[{name:`key`},{name:`props`,defaultValue:[]}]};case Fc:return{name:Fc,properties:[{name:`isEqual`,defaultValue:!1},{name:`tag`}]};case Lc:return{name:Lc,properties:[{name:`body`},{name:`extends`},{name:`name`},{name:`viewOf`}]};case zc:return{name:zc,properties:[{name:`props`,defaultValue:[]},{name:`rules`,defaultValue:[]},{name:`tags`}]};case Vc:return{name:Vc,properties:[{name:`view`}]};case Hc:return{name:Hc,properties:[{name:`prev`},{name:`value`}]};case Wc:return{name:Wc,properties:[{name:`body`},{name:`deploymentNode`}]};case Kc:return{name:Kc,properties:[{name:`elements`,defaultValue:[]},{name:`props`,defaultValue:[]},{name:`tags`}]};case Jc:return{name:Jc,properties:[{name:`body`},{name:`element`}]};case Xc:return{name:Xc,properties:[{name:`elements`,defaultValue:[]},{name:`props`,defaultValue:[]},{name:`tags`}]};case Qc:return{name:Qc,properties:[{name:`body`},{name:`dotKind`},{name:`kind`},{name:`source`},{name:`target`},{name:`title`}]};case el:return{name:el,properties:[{name:`props`,defaultValue:[]},{name:`tags`}]};case nl:return{name:nl,properties:[{name:`prev`},{name:`value`}]};case il:return{name:il,properties:[{name:`subject`},{name:`where`}]};case ol:return{name:ol,properties:[{name:`custom`},{name:`subject`}]};case cl:return{name:cl,properties:[{name:`parent`},{name:`value`}]};case ul:return{name:ul,properties:[{name:`ref`},{name:`selector`}]};case fl:return{name:fl,properties:[{name:`name`},{name:`predicates`,defaultValue:[]}]};case ml:return{name:ml,properties:[{name:`name`},{name:`predicates`,defaultValue:[]}]};case gl:return{name:gl,properties:[{name:`name`},{name:`predicates`,defaultValue:[]},{name:`styles`,defaultValue:[]}]};case vl:return{name:vl,properties:[{name:`id`},{name:`props`,defaultValue:[]},{name:`targets`}]};case bl:return{name:bl,properties:[{name:`id`},{name:`styles`,defaultValue:[]}]};case Sl:return{name:Sl,properties:[{name:`name`}]};case Cl:return{name:Cl,properties:[{name:`hex`}]};case Tl:return{name:Tl,properties:[{name:`customColor`},{name:`key`},{name:`themeColor`}]};case Dl:return{name:Dl,properties:[{name:`key`},{name:`value`}]};case kl:return{name:kl,properties:[{name:`key`},{name:`libicon`},{name:`value`}]};case jl:return{name:jl,properties:[{name:`key`},{name:`value`}]};case Nl:return{name:Nl,properties:[{name:`imported`},{name:`prev`}]};case Fl:return{name:Fl,properties:[{name:`imports`},{name:`project`}]};case Ll:return{name:Ll,properties:[{name:`to`}]};case zl:return{name:zl,properties:[{name:`inout`}]};case Vl:return{name:Vl,properties:[{name:`name`}]};case Ul:return{name:Ul,properties:[{name:`deployments`,defaultValue:[]},{name:`globals`,defaultValue:[]},{name:`imports`,defaultValue:[]},{name:`likec4lib`,defaultValue:[]},{name:`models`,defaultValue:[]},{name:`specifications`,defaultValue:[]},{name:`views`,defaultValue:[]}]};case Gl:return{name:Gl,properties:[{name:`icons`,defaultValue:[]}]};case ql:return{name:ql,properties:[{name:`key`},{name:`value`}]};case Yl:return{name:Yl,properties:[{name:`key`},{name:`title`},{name:`value`}]};case Zl:return{name:Zl,properties:[{name:`markdown`},{name:`text`}]};case $l:return{name:$l,properties:[{name:`values`,defaultValue:[]}]};case tu:return{name:tu,properties:[{name:`boolValue`,defaultValue:!1},{name:`key`},{name:`value`}]};case ru:return{name:ru,properties:[{name:`props`,defaultValue:[]}]};case au:return{name:au,properties:[{name:`elements`,defaultValue:[]},{name:`name`}]};case su:return{name:su,properties:[{name:`elements`,defaultValue:[]},{name:`name`}]};case lu:return{name:lu,properties:[{name:`folder`},{name:`name`},{name:`styles`,defaultValue:[]},{name:`views`,defaultValue:[]}]};case du:return{name:du,properties:[{name:`key`},{name:`value`,defaultValue:!1}]};case pu:return{name:pu,properties:[{name:`key`},{name:`value`}]};case hu:return{name:hu,properties:[{name:`key`},{name:`value`}]};case _u:return{name:_u,properties:[{name:`key`},{name:`value`}]};case yu:return{name:yu,properties:[{name:`key`},{name:`value`}]};case xu:return{name:xu,properties:[{name:`dotKind`},{name:`from`},{name:`isBidirectional`,defaultValue:!1},{name:`kind`}]};case Cu:return{name:Cu,properties:[{name:`key`},{name:`value`}]};case Tu:return{name:Tu,properties:[{name:`body`},{name:`description`},{name:`dotKind`},{name:`kind`},{name:`source`},{name:`tags`},{name:`target`},{name:`technology`},{name:`title`}]};case Du:return{name:Du,properties:[{name:`props`,defaultValue:[]},{name:`tags`}]};case ku:return{name:ku,properties:[{name:`subject`},{name:`where`}]};case ju:return{name:ju,properties:[{name:`custom`},{name:`subject`}]};case Nu:return{name:Nu,properties:[{name:`kind`}]};case Fu:return{name:Fu,properties:[{name:`key`},{name:`value`}]};case Lu:return{name:Lu,properties:[{name:`name`}]};case zu:return{name:zu,properties:[{name:`key`},{name:`value`}]};case Vu:return{name:Vu,properties:[{name:`key`},{name:`props`,defaultValue:[]}]};case Uu:return{name:Uu,properties:[{name:`alpha`},{name:`blue`},{name:`green`},{name:`red`}]};case Gu:return{name:Gu,properties:[{name:`key`},{name:`value`}]};case qu:return{name:qu,properties:[{name:`key`},{name:`value`}]};case Yu:return{name:Yu,properties:[{name:`color`},{name:`name`}]};case Zu:return{name:Zu,properties:[{name:`kind`},{name:`props`,defaultValue:[]},{name:`tags`}]};case $u:return{name:$u,properties:[{name:`kind`},{name:`props`,defaultValue:[]},{name:`tags`}]};case td:return{name:td,properties:[{name:`key`},{name:`value`}]};case rd:return{name:rd,properties:[{name:`kind`},{name:`props`,defaultValue:[]}]};case ad:return{name:ad,properties:[{name:`key`},{name:`value`}]};case sd:return{name:sd,properties:[{name:`colors`,defaultValue:[]},{name:`deploymentNodes`,defaultValue:[]},{name:`elements`,defaultValue:[]},{name:`name`},{name:`relationships`,defaultValue:[]},{name:`tags`,defaultValue:[]}]};case ld:return{name:ld,properties:[{name:`color`},{name:`tag`}]};case dd:return{name:dd,properties:[{name:`el`},{name:`parent`}]};case pd:return{name:pd,properties:[{name:`parent`},{name:`value`}]};case`Tag`:return{name:`Tag`,properties:[{name:`name`}]};case gd:return{name:gd,properties:[{name:`tag`}]};case vd:return{name:vd,properties:[{name:`prev`},{name:`values`,defaultValue:[]}]};case bd:return{name:bd,properties:[{name:`key`},{name:`value`}]};case Sd:return{name:Sd,properties:[{name:`view`}]};case Cd:return{name:Cd,properties:[{name:`direction`},{name:`nodeSep`},{name:`rankSep`}]};case Td:return{name:Td,properties:[{name:`predicate`}]};case Dd:return{name:Dd,properties:[{name:`style`}]};case kd:return{name:kd,properties:[{name:`groupRules`,defaultValue:[]},{name:`props`,defaultValue:[]},{name:`title`}]};case jd:return{name:jd,properties:[{name:`exprs`},{name:`isInclude`,defaultValue:!1}]};case Nd:return{name:Nd,properties:[{name:`targets`},{name:`value`}]};case Fd:return{name:Fd,properties:[{name:`props`,defaultValue:[]},{name:`targets`}]};case Ld:return{name:Ld,properties:[{name:`key`},{name:`value`}]};case zd:return{name:zd,properties:[{name:`left`},{name:`operator`},{name:`right`}]};case Vd:return{name:Vd,properties:[{name:`not`,defaultValue:!1},{name:`operator`},{name:`value`}]};case Ud:return{name:Ud,properties:[{name:`key`},{name:`not`,defaultValue:!1},{name:`operator`},{name:`value`}]};case Gd:return{name:Gd,properties:[{name:`value`}]};case qd:return{name:qd,properties:[{name:`not`,defaultValue:!1},{name:`operator`},{name:`value`}]};case Yd:return{name:Yd,properties:[{name:`not`,defaultValue:!1},{name:`operator`},{name:`value`}]};case Zd:return{name:Zd,properties:[{name:`key`},{name:`not`,defaultValue:!1},{name:`operator`},{name:`value`}]};case $d:return{name:$d,properties:[{name:`value`}]};case tf:return{name:tf,properties:[{name:`not`,defaultValue:!1},{name:`operator`},{name:`participant`},{name:`value`}]};case rf:return{name:rf,properties:[{name:`key`},{name:`not`,defaultValue:!1},{name:`operator`},{name:`participant`},{name:`value`}]};case of:return{name:of,properties:[{name:`not`,defaultValue:!1},{name:`operator`},{name:`participant`},{name:`value`}]};case cf:return{name:cf,properties:[{name:`not`,defaultValue:!1},{name:`operator`},{name:`value`}]};case uf:return{name:uf,properties:[{name:`isWildcard`,defaultValue:!1}]};case ff:return{name:ff,properties:[{name:`custom`},{name:`dotKind`},{name:`kind`},{name:`source`},{name:`target`},{name:`title`}]};case mf:return{name:mf,properties:[{name:`custom`},{name:`dotKind`},{name:`isBackward`,defaultValue:!1},{name:`kind`},{name:`source`},{name:`target`},{name:`title`}]};default:return{name:e,properties:[]}}}};const U=new gf;let _f;const vf=()=>_f??=Et(`{"$type":"Grammar","isDeclared":true,"name":"LikeC4","rules":[{"$type":"ParserRule","entry":true,"name":"LikeC4Grammar","definition":{"$type":"Alternatives","elements":[{"$type":"Assignment","feature":"imports","operator":"+=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@16"},"arguments":[]}},{"$type":"Assignment","feature":"specifications","operator":"+=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@8"},"arguments":[]}},{"$type":"Assignment","feature":"models","operator":"+=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@19"},"arguments":[]}},{"$type":"Assignment","feature":"views","operator":"+=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@44"},"arguments":[]}},{"$type":"Assignment","feature":"globals","operator":"+=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@123"},"arguments":[]}},{"$type":"Assignment","feature":"deployments","operator":"+=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@109"},"arguments":[]}},{"$type":"Assignment","feature":"likec4lib","operator":"+=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@1"},"arguments":[]}}],"cardinality":"*"},"definesHiddenTokens":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"LikeC4Lib","definition":{"$type":"Group","elements":[{"$type":"Keyword","value":"likec4lib"},{"$type":"Keyword","value":"{"},{"$type":"Keyword","value":"icons"},{"$type":"Keyword","value":"{"},{"$type":"Assignment","feature":"icons","operator":"+=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@2"},"arguments":[]},"cardinality":"+"},{"$type":"Keyword","value":"}"},{"$type":"Keyword","value":"}"}]},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"LibIcon","definition":{"$type":"Assignment","feature":"name","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@161"},"arguments":[]}},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"ElementKind","definition":{"$type":"Assignment","feature":"name","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@165"},"arguments":[]}},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"Tag","definition":{"$type":"Assignment","feature":"name","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@165"},"arguments":[]}},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"RelationshipKind","definition":{"$type":"Assignment","feature":"name","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@165"},"arguments":[]}},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"CustomColor","definition":{"$type":"Assignment","feature":"name","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@164"},"arguments":[]}},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"DeploymentNodeKind","definition":{"$type":"Assignment","feature":"name","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@165"},"arguments":[]}},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"SpecificationRule","definition":{"$type":"Group","elements":[{"$type":"Assignment","feature":"name","operator":"=","terminal":{"$type":"Keyword","value":"specification"}},{"$type":"Keyword","value":"{"},{"$type":"Alternatives","elements":[{"$type":"Assignment","feature":"elements","operator":"+=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@9"},"arguments":[]}},{"$type":"Assignment","feature":"tags","operator":"+=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@12"},"arguments":[]}},{"$type":"Assignment","feature":"relationships","operator":"+=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@14"},"arguments":[]}},{"$type":"Assignment","feature":"colors","operator":"+=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@13"},"arguments":[]}},{"$type":"Assignment","feature":"deploymentNodes","operator":"+=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@11"},"arguments":[]}}],"cardinality":"*"},{"$type":"Keyword","value":"}"}]},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"SpecificationElementKind","definition":{"$type":"Group","elements":[{"$type":"Keyword","value":"element"},{"$type":"Assignment","feature":"kind","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@3"},"arguments":[]}},{"$type":"Group","elements":[{"$type":"Keyword","value":"{"},{"$type":"Assignment","feature":"tags","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@18"},"arguments":[]},"cardinality":"?"},{"$type":"Assignment","feature":"props","operator":"+=","terminal":{"$type":"Alternatives","elements":[{"$type":"RuleCall","rule":{"$ref":"#/rules@10"},"arguments":[]},{"$type":"RuleCall","rule":{"$ref":"#/rules@129"},"arguments":[]},{"$type":"RuleCall","rule":{"$ref":"#/rules@146"},"arguments":[]}]},"cardinality":"*"},{"$type":"Keyword","value":"}"}],"cardinality":"?"}]},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"SpecificationElementStringProperty","definition":{"$type":"Group","elements":[{"$type":"Assignment","feature":"key","operator":"=","terminal":{"$type":"Alternatives","elements":[{"$type":"Keyword","value":"title"},{"$type":"Keyword","value":"description"},{"$type":"Keyword","value":"technology"},{"$type":"Keyword","value":"notation"},{"$type":"Keyword","value":"summary"}]}},{"$type":"Keyword","value":":","cardinality":"?"},{"$type":"Assignment","feature":"value","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@163"},"arguments":[]}},{"$type":"Keyword","value":";","cardinality":"?"}]},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"SpecificationDeploymentNodeKind","definition":{"$type":"Group","elements":[{"$type":"Keyword","value":"deploymentNode"},{"$type":"Assignment","feature":"kind","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@7"},"arguments":[]}},{"$type":"Group","elements":[{"$type":"Keyword","value":"{"},{"$type":"Assignment","feature":"tags","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@18"},"arguments":[]},"cardinality":"?"},{"$type":"Assignment","feature":"props","operator":"+=","terminal":{"$type":"Alternatives","elements":[{"$type":"RuleCall","rule":{"$ref":"#/rules@10"},"arguments":[]},{"$type":"RuleCall","rule":{"$ref":"#/rules@129"},"arguments":[]},{"$type":"RuleCall","rule":{"$ref":"#/rules@146"},"arguments":[]}]},"cardinality":"*"},{"$type":"Keyword","value":"}"}],"cardinality":"?"}]},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"SpecificationTag","definition":{"$type":"Group","elements":[{"$type":"Keyword","value":"tag"},{"$type":"Assignment","feature":"tag","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@4"},"arguments":[]}},{"$type":"Group","elements":[{"$type":"Keyword","value":"{"},{"$type":"Group","elements":[{"$type":"Keyword","value":"color"},{"$type":"Assignment","feature":"color","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@158"},"arguments":[]}}],"cardinality":"?"},{"$type":"Keyword","value":"}"}],"cardinality":"?"}]},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"SpecificationColor","definition":{"$type":"Group","elements":[{"$type":"Keyword","value":"color"},{"$type":"Assignment","feature":"name","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@6"},"arguments":[]}},{"$type":"Assignment","feature":"color","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@158"},"arguments":[]}}]},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"SpecificationRelationshipKind","definition":{"$type":"Group","elements":[{"$type":"Keyword","value":"relationship"},{"$type":"Assignment","feature":"kind","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@5"},"arguments":[]}},{"$type":"Group","elements":[{"$type":"Keyword","value":"{"},{"$type":"Assignment","feature":"props","operator":"+=","terminal":{"$type":"Alternatives","elements":[{"$type":"RuleCall","rule":{"$ref":"#/rules@149"},"arguments":[]},{"$type":"RuleCall","rule":{"$ref":"#/rules@15"},"arguments":[]}]},"cardinality":"*"},{"$type":"Keyword","value":"}"}],"cardinality":"?"}]},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"SpecificationRelationshipStringProperty","definition":{"$type":"Group","elements":[{"$type":"Assignment","feature":"key","operator":"=","terminal":{"$type":"Alternatives","elements":[{"$type":"Keyword","value":"technology"},{"$type":"Keyword","value":"notation"}]}},{"$type":"Keyword","value":":","cardinality":"?"},{"$type":"Assignment","feature":"value","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@163"},"arguments":[]}},{"$type":"Keyword","value":";","cardinality":"?"}]},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"ImportsFromPoject","definition":{"$type":"Group","elements":[{"$type":"Keyword","value":"import"},{"$type":"Alternatives","elements":[{"$type":"Group","elements":[{"$type":"Keyword","value":"{"},{"$type":"Assignment","feature":"imports","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@17"},"arguments":[]}},{"$type":"Keyword","value":"}"}]},{"$type":"Assignment","feature":"imports","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@17"},"arguments":[]}}]},{"$type":"Keyword","value":"from"},{"$type":"Assignment","feature":"project","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@186"},"arguments":[]}},{"$type":"Keyword","value":";","cardinality":"?"}]},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"Imported","definition":{"$type":"Group","elements":[{"$type":"Assignment","feature":"imported","operator":"=","terminal":{"$type":"CrossReference","type":{"$ref":"#/rules@20"},"terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@165"},"arguments":[]},"deprecatedSyntax":false}},{"$type":"Group","elements":[{"$type":"Action","inferredType":{"$type":"InferredType","name":"Imported"},"feature":"prev","operator":"="},{"$type":"Keyword","value":","},{"$type":"Assignment","feature":"imported","operator":"=","terminal":{"$type":"CrossReference","type":{"$ref":"#/rules@20"},"terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@165"},"arguments":[]},"deprecatedSyntax":false}}],"cardinality":"*"},{"$type":"Keyword","value":";","cardinality":"?"}]},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"Tags","definition":{"$type":"Group","elements":[{"$type":"Assignment","feature":"values","operator":"+=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@150"},"arguments":[]},"cardinality":"+"},{"$type":"Group","elements":[{"$type":"Action","inferredType":{"$type":"InferredType","name":"Tags"},"feature":"prev","operator":"="},{"$type":"Keyword","value":","},{"$type":"Assignment","feature":"values","operator":"+=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@150"},"arguments":[]},"cardinality":"*"}],"cardinality":"*"},{"$type":"Keyword","value":";","cardinality":"?"}]},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"Model","definition":{"$type":"Group","elements":[{"$type":"Assignment","feature":"name","operator":"=","terminal":{"$type":"Keyword","value":"model"}},{"$type":"Keyword","value":"{"},{"$type":"Assignment","feature":"elements","operator":"+=","terminal":{"$type":"Alternatives","elements":[{"$type":"RuleCall","rule":{"$ref":"#/rules@24"},"arguments":[]},{"$type":"RuleCall","rule":{"$ref":"#/rules@27"},"arguments":[]},{"$type":"RuleCall","rule":{"$ref":"#/rules@34"},"arguments":[{"$type":"NamedArgument","value":{"$type":"BooleanLiteral","true":true},"calledByName":false}]},{"$type":"RuleCall","rule":{"$ref":"#/rules@20"},"arguments":[]}]},"cardinality":"*"},{"$type":"Keyword","value":"}"}]},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"Element","definition":{"$type":"Group","elements":[{"$type":"Alternatives","elements":[{"$type":"Group","elements":[{"$type":"Assignment","feature":"kind","operator":"=","terminal":{"$type":"CrossReference","type":{"$ref":"#/rules@3"},"deprecatedSyntax":false}},{"$type":"Assignment","feature":"name","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@165"},"arguments":[]}}]},{"$type":"Group","elements":[{"$type":"Assignment","feature":"name","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@165"},"arguments":[]}},{"$type":"RuleCall","rule":{"$ref":"#/rules@183"},"arguments":[]},{"$type":"Assignment","feature":"kind","operator":"=","terminal":{"$type":"CrossReference","type":{"$ref":"#/rules@3"},"deprecatedSyntax":false}}]}]},{"$type":"Group","elements":[{"$type":"Assignment","feature":"props","operator":"+=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@186"},"arguments":[]}},{"$type":"Group","elements":[{"$type":"Assignment","feature":"props","operator":"+=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@186"},"arguments":[]}},{"$type":"Group","elements":[{"$type":"Assignment","feature":"props","operator":"+=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@186"},"arguments":[]}},{"$type":"Assignment","feature":"props","operator":"+=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@186"},"arguments":[]},"cardinality":"?"}],"cardinality":"?"}],"cardinality":"?"}],"cardinality":"?"},{"$type":"Assignment","feature":"body","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@21"},"arguments":[]},"cardinality":"?"}]},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"ElementBody","definition":{"$type":"Group","elements":[{"$type":"Keyword","value":"{"},{"$type":"Assignment","feature":"tags","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@18"},"arguments":[]},"cardinality":"?"},{"$type":"Assignment","feature":"props","operator":"+=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@22"},"arguments":[]},"cardinality":"*"},{"$type":"Assignment","feature":"elements","operator":"+=","terminal":{"$type":"Alternatives","elements":[{"$type":"RuleCall","rule":{"$ref":"#/rules@34"},"arguments":[{"$type":"NamedArgument","value":{"$type":"BooleanLiteral","true":false},"calledByName":false}]},{"$type":"RuleCall","rule":{"$ref":"#/rules@20"},"arguments":[]}]},"cardinality":"*"},{"$type":"Keyword","value":"}"}]},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"ElementProperty","definition":{"$type":"Alternatives","elements":[{"$type":"RuleCall","rule":{"$ref":"#/rules@23"},"arguments":[]},{"$type":"RuleCall","rule":{"$ref":"#/rules@146"},"arguments":[]},{"$type":"RuleCall","rule":{"$ref":"#/rules@129"},"arguments":[]},{"$type":"RuleCall","rule":{"$ref":"#/rules@133"},"arguments":[]},{"$type":"RuleCall","rule":{"$ref":"#/rules@39"},"arguments":[]}]},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"ElementStringProperty","definition":{"$type":"Group","elements":[{"$type":"Assignment","feature":"key","operator":"=","terminal":{"$type":"Alternatives","elements":[{"$type":"Keyword","value":"title"},{"$type":"Keyword","value":"description"},{"$type":"Keyword","value":"technology"},{"$type":"Keyword","value":"summary"}]}},{"$type":"Keyword","value":":","cardinality":"?"},{"$type":"Assignment","feature":"value","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@163"},"arguments":[]}},{"$type":"Keyword","value":";","cardinality":"?"}]},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"ExtendElement","definition":{"$type":"Group","elements":[{"$type":"Keyword","value":"extend"},{"$type":"Assignment","feature":"element","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@31"},"arguments":[]}},{"$type":"Assignment","feature":"body","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@25"},"arguments":[]}}]},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"ExtendElementBody","definition":{"$type":"Group","elements":[{"$type":"Keyword","value":"{"},{"$type":"Assignment","feature":"tags","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@18"},"arguments":[]},"cardinality":"?"},{"$type":"Assignment","feature":"props","operator":"+=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@26"},"arguments":[]},"cardinality":"*"},{"$type":"Assignment","feature":"elements","operator":"+=","terminal":{"$type":"Alternatives","elements":[{"$type":"RuleCall","rule":{"$ref":"#/rules@34"},"arguments":[{"$type":"NamedArgument","value":{"$type":"BooleanLiteral","true":false},"calledByName":false}]},{"$type":"RuleCall","rule":{"$ref":"#/rules@20"},"arguments":[]}]},"cardinality":"*"},{"$type":"Keyword","value":"}"}]},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"ExtendElementProperty","definition":{"$type":"Alternatives","elements":[{"$type":"RuleCall","rule":{"$ref":"#/rules@129"},"arguments":[]},{"$type":"RuleCall","rule":{"$ref":"#/rules@39"},"arguments":[]}]},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"ExtendRelation","definition":{"$type":"Group","elements":[{"$type":"Keyword","value":"extend"},{"$type":"Assignment","feature":"source","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@32"},"arguments":[]}},{"$type":"Alternatives","elements":[{"$type":"Assignment","feature":"dotKind","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@151"},"arguments":[]}},{"$type":"Group","elements":[{"$type":"Keyword","value":"-["},{"$type":"Assignment","feature":"kind","operator":"=","terminal":{"$type":"CrossReference","type":{"$ref":"#/rules@5"},"deprecatedSyntax":false}},{"$type":"Keyword","value":"]->"}]},{"$type":"Keyword","value":"->"}]},{"$type":"Assignment","feature":"target","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@32"},"arguments":[]}},{"$type":"Assignment","feature":"title","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@186"},"arguments":[]},"cardinality":"?"},{"$type":"Assignment","feature":"body","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@28"},"arguments":[]}}]},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"ExtendRelationBody","definition":{"$type":"Group","elements":[{"$type":"Keyword","value":"{"},{"$type":"Assignment","feature":"tags","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@18"},"arguments":[]},"cardinality":"?"},{"$type":"Assignment","feature":"props","operator":"+=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@29"},"arguments":[]},"cardinality":"*"},{"$type":"Keyword","value":"}"}]},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"ExtendRelationProperty","definition":{"$type":"Alternatives","elements":[{"$type":"RuleCall","rule":{"$ref":"#/rules@129"},"arguments":[]},{"$type":"RuleCall","rule":{"$ref":"#/rules@39"},"arguments":[]}]},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"ElementRef","definition":{"$type":"Assignment","feature":"modelElement","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@32"},"arguments":[]}},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"StrictFqnElementRef","definition":{"$type":"Group","elements":[{"$type":"Assignment","feature":"el","operator":"=","terminal":{"$type":"CrossReference","type":{"$ref":"#/rules@20"},"terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@165"},"arguments":[]},"deprecatedSyntax":false}},{"$type":"Group","elements":[{"$type":"Action","inferredType":{"$type":"InferredType","name":"StrictFqnElementRef"},"feature":"parent","operator":"="},{"$type":"RuleCall","rule":{"$ref":"#/rules@180"},"arguments":[]},{"$type":"Assignment","feature":"el","operator":"=","terminal":{"$type":"CrossReference","type":{"$ref":"#/rules@20"},"terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@165"},"arguments":[]},"deprecatedSyntax":false}}],"cardinality":"*"}]},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"FqnRef","definition":{"$type":"Group","elements":[{"$type":"Assignment","feature":"value","operator":"=","terminal":{"$type":"CrossReference","type":{"$ref":"#/types@1"},"terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@165"},"arguments":[]},"deprecatedSyntax":false}},{"$type":"Group","elements":[{"$type":"Action","inferredType":{"$type":"InferredType","name":"FqnRef"},"feature":"parent","operator":"="},{"$type":"RuleCall","rule":{"$ref":"#/rules@180"},"arguments":[]},{"$type":"Assignment","feature":"value","operator":"=","terminal":{"$type":"CrossReference","type":{"$ref":"#/types@1"},"terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@165"},"arguments":[]},"deprecatedSyntax":false}}],"cardinality":"*"}]},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"StrictFqnRef","definition":{"$type":"Group","elements":[{"$type":"Assignment","feature":"value","operator":"=","terminal":{"$type":"CrossReference","type":{"$ref":"#/types@1"},"terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@165"},"arguments":[]},"deprecatedSyntax":false}},{"$type":"Group","elements":[{"$type":"Action","inferredType":{"$type":"InferredType","name":"StrictFqnRef"},"feature":"parent","operator":"="},{"$type":"RuleCall","rule":{"$ref":"#/rules@180"},"arguments":[]},{"$type":"Assignment","feature":"value","operator":"=","terminal":{"$type":"CrossReference","type":{"$ref":"#/types@1"},"terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@165"},"arguments":[]},"deprecatedSyntax":false}}],"cardinality":"*"}]},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"Relation","parameters":[{"$type":"Parameter","name":"isExplicit"}],"definition":{"$type":"Group","elements":[{"$type":"Alternatives","elements":[{"$type":"Group","guardCondition":{"$type":"ParameterReference","parameter":{"$ref":"#/rules@34/parameters@0"}},"elements":[{"$type":"Assignment","feature":"source","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@32"},"arguments":[]}}]},{"$type":"Group","guardCondition":{"$type":"Negation","value":{"$type":"ParameterReference","parameter":{"$ref":"#/rules@34/parameters@0"}}},"elements":[{"$type":"Assignment","feature":"source","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@32"},"arguments":[]},"cardinality":"?"}]}]},{"$type":"Alternatives","elements":[{"$type":"Assignment","feature":"dotKind","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@151"},"arguments":[]}},{"$type":"Group","elements":[{"$type":"Keyword","value":"-["},{"$type":"Assignment","feature":"kind","operator":"=","terminal":{"$type":"CrossReference","type":{"$ref":"#/rules@5"},"deprecatedSyntax":false}},{"$type":"Keyword","value":"]->"}]},{"$type":"Keyword","value":"->"}]},{"$type":"Assignment","feature":"target","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@32"},"arguments":[]}},{"$type":"Group","elements":[{"$type":"Assignment","feature":"title","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@186"},"arguments":[]}},{"$type":"Group","elements":[{"$type":"Assignment","feature":"description","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@186"},"arguments":[]}},{"$type":"Assignment","feature":"technology","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@186"},"arguments":[]},"cardinality":"?"}],"cardinality":"?"}],"cardinality":"?"},{"$type":"Assignment","feature":"tags","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@18"},"arguments":[]},"cardinality":"?"},{"$type":"Assignment","feature":"body","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@35"},"arguments":[]},"cardinality":"?"}]},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"wildcard":false},{"$type":"ParserRule","name":"RelationBody","definition":{"$type":"Group","elements":[{"$type":"Keyword","value":"{"},{"$type":"Assignment","feature":"tags","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@18"},"arguments":[]},"cardinality":"?"},{"$type":"Assignment","feature":"props","operator":"+=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@36"},"arguments":[]},"cardinality":"*"},{"$type":"Keyword","value":"}"}]},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"RelationProperty","definition":{"$type":"Alternatives","elements":[{"$type":"RuleCall","rule":{"$ref":"#/rules@37"},"arguments":[]},{"$type":"RuleCall","rule":{"$ref":"#/rules@81"},"arguments":[]},{"$type":"RuleCall","rule":{"$ref":"#/rules@38"},"arguments":[]},{"$type":"RuleCall","rule":{"$ref":"#/rules@129"},"arguments":[]},{"$type":"RuleCall","rule":{"$ref":"#/rules@39"},"arguments":[]}]},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"RelationStringProperty","definition":{"$type":"Group","elements":[{"$type":"Assignment","feature":"key","operator":"=","terminal":{"$type":"Alternatives","elements":[{"$type":"Keyword","value":"title"},{"$type":"Keyword","value":"technology"},{"$type":"Keyword","value":"description"}]}},{"$type":"Keyword","value":":","cardinality":"?"},{"$type":"Assignment","feature":"value","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@163"},"arguments":[]}},{"$type":"Keyword","value":";","cardinality":"?"}]},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"RelationStyleProperty","definition":{"$type":"Group","elements":[{"$type":"Assignment","feature":"key","operator":"=","terminal":{"$type":"Keyword","value":"style"}},{"$type":"Keyword","value":"{"},{"$type":"Assignment","feature":"props","operator":"+=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@149"},"arguments":[]},"cardinality":"*"},{"$type":"Keyword","value":"}"}]},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"MetadataProperty","definition":{"$type":"Group","elements":[{"$type":"Keyword","value":"metadata"},{"$type":"RuleCall","rule":{"$ref":"#/rules@40"},"arguments":[]}]},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"MetadataBody","definition":{"$type":"Group","elements":[{"$type":"Keyword","value":"{"},{"$type":"Assignment","feature":"props","operator":"+=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@41"},"arguments":[]},"cardinality":"*"},{"$type":"Keyword","value":"}"}]},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"MetadataAttribute","definition":{"$type":"Group","elements":[{"$type":"Assignment","feature":"key","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@189"},"arguments":[]}},{"$type":"Keyword","value":":","cardinality":"?"},{"$type":"Alternatives","elements":[{"$type":"Assignment","feature":"value","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@42"},"arguments":[]}},{"$type":"Assignment","feature":"boolValue","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@172"},"arguments":[]}}]},{"$type":"Keyword","value":";","cardinality":"?"}]},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"MetadataValue","definition":{"$type":"Alternatives","elements":[{"$type":"RuleCall","rule":{"$ref":"#/rules@163"},"arguments":[]},{"$type":"RuleCall","rule":{"$ref":"#/rules@43"},"arguments":[]}]},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"MetadataArray","definition":{"$type":"Group","elements":[{"$type":"Keyword","value":"["},{"$type":"Assignment","feature":"values","operator":"+=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@163"},"arguments":[]}},{"$type":"Group","elements":[{"$type":"Keyword","value":","},{"$type":"Assignment","feature":"values","operator":"+=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@163"},"arguments":[]}}],"cardinality":"*"},{"$type":"Keyword","value":"]"}]},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"ModelViews","definition":{"$type":"Group","elements":[{"$type":"Assignment","feature":"name","operator":"=","terminal":{"$type":"Keyword","value":"views"}},{"$type":"Assignment","feature":"folder","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@186"},"arguments":[]},"cardinality":"?"},{"$type":"Keyword","value":"{"},{"$type":"Alternatives","elements":[{"$type":"Assignment","feature":"views","operator":"+=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@45"},"arguments":[]}},{"$type":"Assignment","feature":"styles","operator":"+=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@74"},"arguments":[]}}],"cardinality":"*"},{"$type":"Keyword","value":"}"}]},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"LikeC4ViewRule","returnType":{"$ref":"#/types@2"},"definition":{"$type":"Alternatives","elements":[{"$type":"RuleCall","rule":{"$ref":"#/rules@46"},"arguments":[]},{"$type":"RuleCall","rule":{"$ref":"#/rules@47"},"arguments":[]},{"$type":"RuleCall","rule":{"$ref":"#/rules@118"},"arguments":[]}]},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"ElementView","definition":{"$type":"Group","elements":[{"$type":"Keyword","value":"view"},{"$type":"Assignment","feature":"name","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@165"},"arguments":[]},"cardinality":"?"},{"$type":"Alternatives","elements":[{"$type":"Group","elements":[{"$type":"Keyword","value":"extends"},{"$type":"Assignment","feature":"extends","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@49"},"arguments":[]}}]},{"$type":"Group","elements":[{"$type":"Keyword","value":"of"},{"$type":"Assignment","feature":"viewOf","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@30"},"arguments":[]}}]}],"cardinality":"?"},{"$type":"Assignment","feature":"body","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@51"},"arguments":[]},"cardinality":"?"}]},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"DynamicView","definition":{"$type":"Group","elements":[{"$type":"Keyword","value":"dynamic"},{"$type":"Keyword","value":"view"},{"$type":"Assignment","feature":"name","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@165"},"arguments":[]}},{"$type":"Assignment","feature":"body","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@52"},"arguments":[]},"cardinality":"?"}]},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"ViewRef","definition":{"$type":"Assignment","feature":"view","operator":"=","terminal":{"$type":"CrossReference","type":{"$ref":"#/types@2"},"deprecatedSyntax":false}},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"ElementViewRef","definition":{"$type":"Assignment","feature":"view","operator":"=","terminal":{"$type":"CrossReference","type":{"$ref":"#/rules@46"},"deprecatedSyntax":false}},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"DynamicViewRef","definition":{"$type":"Assignment","feature":"view","operator":"=","terminal":{"$type":"CrossReference","type":{"$ref":"#/rules@47"},"deprecatedSyntax":false}},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"ElementViewBody","definition":{"$type":"Group","elements":[{"$type":"Keyword","value":"{"},{"$type":"Assignment","feature":"tags","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@18"},"arguments":[]},"cardinality":"?"},{"$type":"Assignment","feature":"props","operator":"+=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@55"},"arguments":[]},"cardinality":"*"},{"$type":"Assignment","feature":"rules","operator":"+=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@58"},"arguments":[]},"cardinality":"*"},{"$type":"Keyword","value":"}"}]},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"DynamicViewBody","definition":{"$type":"Group","elements":[{"$type":"Keyword","value":"{"},{"$type":"Assignment","feature":"tags","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@18"},"arguments":[]},"cardinality":"?"},{"$type":"Assignment","feature":"props","operator":"+=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@53"},"arguments":[]},"cardinality":"*"},{"$type":"Alternatives","elements":[{"$type":"Assignment","feature":"steps","operator":"+=","terminal":{"$type":"Alternatives","elements":[{"$type":"RuleCall","rule":{"$ref":"#/rules@63"},"arguments":[]},{"$type":"RuleCall","rule":{"$ref":"#/rules@65"},"arguments":[]}]}},{"$type":"Assignment","feature":"rules","operator":"+=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@62"},"arguments":[]}}],"cardinality":"*"},{"$type":"Keyword","value":"}"}]},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"DynamicViewProperty","definition":{"$type":"Alternatives","elements":[{"$type":"RuleCall","rule":{"$ref":"#/rules@54"},"arguments":[]},{"$type":"RuleCall","rule":{"$ref":"#/rules@55"},"arguments":[]}]},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"DynamicViewDisplayVariantProperty","definition":{"$type":"Group","elements":[{"$type":"Assignment","feature":"key","operator":"=","terminal":{"$type":"Keyword","value":"variant"}},{"$type":"Assignment","feature":"value","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@154"},"arguments":[]}}]},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"ViewProperty","definition":{"$type":"Alternatives","elements":[{"$type":"RuleCall","rule":{"$ref":"#/rules@56"},"arguments":[]},{"$type":"RuleCall","rule":{"$ref":"#/rules@129"},"arguments":[]}]},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"ViewStringProperty","definition":{"$type":"Group","elements":[{"$type":"Assignment","feature":"key","operator":"=","terminal":{"$type":"Alternatives","elements":[{"$type":"Keyword","value":"title"},{"$type":"Keyword","value":"description"}]}},{"$type":"Keyword","value":":","cardinality":"?"},{"$type":"Assignment","feature":"value","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@163"},"arguments":[]}},{"$type":"Keyword","value":";","cardinality":"?"}]},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"ViewLayoutDirection","dataType":"string","definition":{"$type":"Alternatives","elements":[{"$type":"Keyword","value":"TopBottom"},{"$type":"Keyword","value":"LeftRight"},{"$type":"Keyword","value":"BottomTop"},{"$type":"Keyword","value":"RightLeft"}]},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"ViewRule","definition":{"$type":"Alternatives","elements":[{"$type":"RuleCall","rule":{"$ref":"#/rules@68"},"arguments":[]},{"$type":"RuleCall","rule":{"$ref":"#/rules@69"},"arguments":[]},{"$type":"RuleCall","rule":{"$ref":"#/rules@61"},"arguments":[]},{"$type":"RuleCall","rule":{"$ref":"#/rules@74"},"arguments":[]},{"$type":"RuleCall","rule":{"$ref":"#/rules@75"},"arguments":[]},{"$type":"RuleCall","rule":{"$ref":"#/rules@59"},"arguments":[]}]},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"ViewRuleRank","definition":{"$type":"Group","elements":[{"$type":"Keyword","value":"rank"},{"$type":"Assignment","feature":"value","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@60"},"arguments":[]},"cardinality":"?"},{"$type":"Keyword","value":"{"},{"$type":"Assignment","feature":"targets","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@95"},"arguments":[]}},{"$type":"Keyword","value":"}"}]},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"RankValue","dataType":"string","definition":{"$type":"Alternatives","elements":[{"$type":"Keyword","value":"same"},{"$type":"Keyword","value":"min"},{"$type":"Keyword","value":"max"},{"$type":"Keyword","value":"source"},{"$type":"Keyword","value":"sink"}]},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"ViewRuleGroup","definition":{"$type":"Group","elements":[{"$type":"Keyword","value":"group"},{"$type":"Assignment","feature":"title","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@186"},"arguments":[]},"cardinality":"?"},{"$type":"Keyword","value":"{"},{"$type":"Assignment","feature":"props","operator":"+=","terminal":{"$type":"Alternatives","elements":[{"$type":"RuleCall","rule":{"$ref":"#/rules@130"},"arguments":[]},{"$type":"RuleCall","rule":{"$ref":"#/rules@140"},"arguments":[]},{"$type":"RuleCall","rule":{"$ref":"#/rules@131"},"arguments":[]}]},"cardinality":"*"},{"$type":"Assignment","feature":"groupRules","operator":"+=","terminal":{"$type":"Alternatives","elements":[{"$type":"RuleCall","rule":{"$ref":"#/rules@68"},"arguments":[]},{"$type":"RuleCall","rule":{"$ref":"#/rules@61"},"arguments":[]}]},"cardinality":"*"},{"$type":"Keyword","value":"}"}]},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"DynamicViewRule","definition":{"$type":"Alternatives","elements":[{"$type":"RuleCall","rule":{"$ref":"#/rules@70"},"arguments":[]},{"$type":"RuleCall","rule":{"$ref":"#/rules@71"},"arguments":[]},{"$type":"RuleCall","rule":{"$ref":"#/rules@74"},"arguments":[]},{"$type":"RuleCall","rule":{"$ref":"#/rules@75"},"arguments":[]}]},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"DynamicViewParallelSteps","definition":{"$type":"Group","elements":[{"$type":"Alternatives","elements":[{"$type":"Keyword","value":"parallel"},{"$type":"Keyword","value":"par"}]},{"$type":"Keyword","value":"{"},{"$type":"Assignment","feature":"steps","operator":"+=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@65"},"arguments":[]},"cardinality":"*"},{"$type":"Keyword","value":"}"}]},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","fragment":true,"name":"DynamicViewStepTarget","definition":{"$type":"Group","elements":[{"$type":"Assignment","feature":"target","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@30"},"arguments":[]}},{"$type":"Assignment","feature":"title","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@186"},"arguments":[]},"cardinality":"?"},{"$type":"Assignment","feature":"custom","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@79"},"arguments":[]},"cardinality":"?"}]},"definesHiddenTokens":false,"entry":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"DynamicViewStep","returnType":{"$ref":"#/types@5"},"definition":{"$type":"RuleCall","rule":{"$ref":"#/rules@66"},"arguments":[]},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"DynamicStepChain","returnType":{"$ref":"#/interfaces@1"},"definition":{"$type":"Group","elements":[{"$type":"RuleCall","rule":{"$ref":"#/rules@67"},"arguments":[]},{"$type":"Group","elements":[{"$type":"Action","type":{"$ref":"#/interfaces@2"},"feature":"source","operator":"="},{"$type":"Alternatives","elements":[{"$type":"Keyword","value":"->"},{"$type":"Group","elements":[{"$type":"Keyword","value":"-["},{"$type":"Assignment","feature":"kind","operator":"=","terminal":{"$type":"CrossReference","type":{"$ref":"#/rules@5"},"deprecatedSyntax":false}},{"$type":"Keyword","value":"]->"}]},{"$type":"Assignment","feature":"dotKind","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@151"},"arguments":[]}}]},{"$type":"RuleCall","rule":{"$ref":"#/rules@64"},"arguments":[]}],"cardinality":"*"}]},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"DynamicStepSingle","returnType":{"$ref":"#/interfaces@1"},"definition":{"$type":"Group","elements":[{"$type":"Assignment","feature":"source","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@30"},"arguments":[]}},{"$type":"Alternatives","elements":[{"$type":"Assignment","feature":"isBackward","operator":"?=","terminal":{"$type":"Keyword","value":"<-"}},{"$type":"Keyword","value":"->"},{"$type":"Group","elements":[{"$type":"Keyword","value":"-["},{"$type":"Assignment","feature":"kind","operator":"=","terminal":{"$type":"CrossReference","type":{"$ref":"#/rules@5"},"deprecatedSyntax":false}},{"$type":"Keyword","value":"]->"}]},{"$type":"Assignment","feature":"dotKind","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@151"},"arguments":[]}}]},{"$type":"RuleCall","rule":{"$ref":"#/rules@64"},"arguments":[]}]},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"ViewRulePredicate","definition":{"$type":"Group","elements":[{"$type":"Alternatives","elements":[{"$type":"Assignment","feature":"isInclude","operator":"?=","terminal":{"$type":"Keyword","value":"include"}},{"$type":"Keyword","value":"exclude"}]},{"$type":"Assignment","feature":"exprs","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@82"},"arguments":[]}}]},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"ViewRuleGlobalPredicateRef","definition":{"$type":"Group","elements":[{"$type":"Keyword","value":"global"},{"$type":"Keyword","value":"predicate"},{"$type":"Assignment","feature":"predicate","operator":"=","terminal":{"$type":"CrossReference","type":{"$ref":"#/rules@124"},"deprecatedSyntax":false}}]},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"DynamicViewIncludePredicate","definition":{"$type":"Group","elements":[{"$type":"Keyword","value":"include"},{"$type":"Assignment","feature":"exprs","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@82"},"arguments":[]}}]},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"DynamicViewGlobalPredicateRef","definition":{"$type":"Group","elements":[{"$type":"Keyword","value":"global"},{"$type":"Keyword","value":"predicate"},{"$type":"Assignment","feature":"predicate","operator":"=","terminal":{"$type":"CrossReference","type":{"$ref":"#/rules@125"},"deprecatedSyntax":false}}]},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"ViewRuleStyle","definition":{"$type":"Group","elements":[{"$type":"Keyword","value":"style"},{"$type":"Assignment","feature":"targets","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@95"},"arguments":[]}},{"$type":"Keyword","value":"{"},{"$type":"Assignment","feature":"props","operator":"+=","terminal":{"$type":"Alternatives","elements":[{"$type":"RuleCall","rule":{"$ref":"#/rules@145"},"arguments":[]},{"$type":"RuleCall","rule":{"$ref":"#/rules@76"},"arguments":[]}]},"cardinality":"*"},{"$type":"Keyword","value":"}"}]},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"ViewRuleGlobalStyle","definition":{"$type":"Group","elements":[{"$type":"Keyword","value":"global"},{"$type":"Keyword","value":"style"},{"$type":"Assignment","feature":"style","operator":"=","terminal":{"$type":"CrossReference","type":{"$ref":"#/rules@126"},"deprecatedSyntax":false}}]},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"ViewRuleStyleOrGlobalRef","definition":{"$type":"Alternatives","elements":[{"$type":"RuleCall","rule":{"$ref":"#/rules@72"},"arguments":[]},{"$type":"RuleCall","rule":{"$ref":"#/rules@73"},"arguments":[]}]},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"ViewRuleAutoLayout","definition":{"$type":"Group","elements":[{"$type":"Keyword","value":"autoLayout"},{"$type":"Assignment","feature":"direction","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@57"},"arguments":[]}},{"$type":"Group","elements":[{"$type":"Assignment","feature":"rankSep","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@188"},"arguments":[]}},{"$type":"Assignment","feature":"nodeSep","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@188"},"arguments":[]},"cardinality":"?"}],"cardinality":"?"}]},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"NotationProperty","definition":{"$type":"Group","elements":[{"$type":"Assignment","feature":"key","operator":"=","terminal":{"$type":"Keyword","value":"notation"}},{"$type":"Keyword","value":":","cardinality":"?"},{"$type":"Assignment","feature":"value","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@163"},"arguments":[]}},{"$type":"Keyword","value":";","cardinality":"?"}]},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"NotesProperty","definition":{"$type":"Group","elements":[{"$type":"Assignment","feature":"key","operator":"=","terminal":{"$type":"Keyword","value":"notes"}},{"$type":"Keyword","value":":","cardinality":"?"},{"$type":"Assignment","feature":"value","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@163"},"arguments":[]}},{"$type":"Keyword","value":";","cardinality":"?"}]},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"CustomElementProperties","definition":{"$type":"Group","elements":[{"$type":"Keyword","value":"{"},{"$type":"Assignment","feature":"props","operator":"+=","terminal":{"$type":"Alternatives","elements":[{"$type":"RuleCall","rule":{"$ref":"#/rules@80"},"arguments":[]},{"$type":"RuleCall","rule":{"$ref":"#/rules@23"},"arguments":[]},{"$type":"RuleCall","rule":{"$ref":"#/rules@76"},"arguments":[]},{"$type":"RuleCall","rule":{"$ref":"#/rules@77"},"arguments":[]},{"$type":"RuleCall","rule":{"$ref":"#/rules@145"},"arguments":[]}]},"cardinality":"*"},{"$type":"Keyword","value":"}"}]},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"CustomRelationProperties","definition":{"$type":"Group","elements":[{"$type":"Keyword","value":"{"},{"$type":"Assignment","feature":"props","operator":"+=","terminal":{"$type":"Alternatives","elements":[{"$type":"RuleCall","rule":{"$ref":"#/rules@81"},"arguments":[]},{"$type":"RuleCall","rule":{"$ref":"#/rules@37"},"arguments":[]},{"$type":"RuleCall","rule":{"$ref":"#/rules@76"},"arguments":[]},{"$type":"RuleCall","rule":{"$ref":"#/rules@77"},"arguments":[]},{"$type":"RuleCall","rule":{"$ref":"#/rules@149"},"arguments":[]}]},"cardinality":"*"},{"$type":"Keyword","value":"}"}]},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"NavigateToProperty","definition":{"$type":"Group","elements":[{"$type":"Assignment","feature":"key","operator":"=","terminal":{"$type":"Keyword","value":"navigateTo"}},{"$type":"Assignment","feature":"value","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@48"},"arguments":[]}}]},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"RelationNavigateToProperty","definition":{"$type":"Group","elements":[{"$type":"Assignment","feature":"key","operator":"=","terminal":{"$type":"Keyword","value":"navigateTo"}},{"$type":"Assignment","feature":"value","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@50"},"arguments":[]}}]},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"Expressions","definition":{"$type":"Group","elements":[{"$type":"Assignment","feature":"value","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@83"},"arguments":[]}},{"$type":"Group","elements":[{"$type":"Action","inferredType":{"$type":"InferredType","name":"Expressions"},"feature":"prev","operator":"="},{"$type":"Keyword","value":","},{"$type":"Assignment","feature":"value","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@83"},"arguments":[]},"cardinality":"?"}],"cardinality":"*"}]},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"ExpressionV2","definition":{"$type":"Alternatives","elements":[{"$type":"RuleCall","rule":{"$ref":"#/rules@86"},"arguments":[]},{"$type":"RuleCall","rule":{"$ref":"#/rules@84"},"arguments":[]}]},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"FqnExprOrWith","definition":{"$type":"Group","elements":[{"$type":"RuleCall","rule":{"$ref":"#/rules@85"},"arguments":[]},{"$type":"Group","elements":[{"$type":"Action","inferredType":{"$type":"InferredType","name":"FqnExprWith"},"feature":"subject","operator":"="},{"$type":"Keyword","value":"with"},{"$type":"Assignment","feature":"custom","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@78"},"arguments":[]},"cardinality":"?"}],"cardinality":"?"}]},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"FqnExprOrWhere","definition":{"$type":"Group","elements":[{"$type":"RuleCall","rule":{"$ref":"#/rules@88"},"arguments":[]},{"$type":"Group","elements":[{"$type":"Action","inferredType":{"$type":"InferredType","name":"FqnExprWhere"},"feature":"subject","operator":"="},{"$type":"Keyword","value":"where"},{"$type":"Assignment","feature":"where","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@96"},"arguments":[]},"cardinality":"?"}],"cardinality":"?"}]},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"RelationExprOrWith","definition":{"$type":"Group","elements":[{"$type":"RuleCall","rule":{"$ref":"#/rules@87"},"arguments":[]},{"$type":"Group","elements":[{"$type":"Action","inferredType":{"$type":"InferredType","name":"RelationExprWith"},"feature":"subject","operator":"="},{"$type":"Keyword","value":"with"},{"$type":"Assignment","feature":"custom","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@79"},"arguments":[]},"cardinality":"?"}],"cardinality":"?"}]},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"RelationExprOrWhere","definition":{"$type":"Group","elements":[{"$type":"RuleCall","rule":{"$ref":"#/rules@90"},"arguments":[]},{"$type":"Group","elements":[{"$type":"Action","inferredType":{"$type":"InferredType","name":"RelationExprWhere"},"feature":"subject","operator":"="},{"$type":"Keyword","value":"where"},{"$type":"Assignment","feature":"where","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@103"},"arguments":[]},"cardinality":"?"}],"cardinality":"?"}]},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"FqnExpr","definition":{"$type":"Alternatives","elements":[{"$type":"Group","elements":[{"$type":"Action","inferredType":{"$type":"InferredType","name":"WildcardExpression"}},{"$type":"Assignment","feature":"isWildcard","operator":"?=","terminal":{"$type":"Keyword","value":"*"}}]},{"$type":"Group","elements":[{"$type":"Action","inferredType":{"$type":"InferredType","name":"ElementTagExpression"}},{"$type":"Keyword","value":"element.tag"},{"$type":"RuleCall","rule":{"$ref":"#/rules@167"},"arguments":[]},{"$type":"Assignment","feature":"tag","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@150"},"arguments":[]}}]},{"$type":"Group","elements":[{"$type":"Action","inferredType":{"$type":"InferredType","name":"ElementKindExpression"}},{"$type":"Keyword","value":"element.kind"},{"$type":"RuleCall","rule":{"$ref":"#/rules@167"},"arguments":[]},{"$type":"Assignment","feature":"kind","operator":"=","terminal":{"$type":"CrossReference","type":{"$ref":"#/rules@3"},"deprecatedSyntax":false}}]},{"$type":"RuleCall","rule":{"$ref":"#/rules@89"},"arguments":[]}]},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"FqnRefExpr","definition":{"$type":"Group","elements":[{"$type":"Assignment","feature":"ref","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@32"},"arguments":[]}},{"$type":"Assignment","feature":"selector","operator":"=","terminal":{"$type":"Alternatives","elements":[{"$type":"RuleCall","rule":{"$ref":"#/rules@177"},"arguments":[]},{"$type":"RuleCall","rule":{"$ref":"#/rules@178"},"arguments":[]}]},"cardinality":"?"}]},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"RelationExpr","definition":{"$type":"Alternatives","elements":[{"$type":"RuleCall","rule":{"$ref":"#/rules@91"},"arguments":[]},{"$type":"RuleCall","rule":{"$ref":"#/rules@93"},"arguments":[]}]},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"InOutRelationExpr","inferredType":{"$type":"InferredType","name":"RelationExpr"},"definition":{"$type":"Group","elements":[{"$type":"RuleCall","rule":{"$ref":"#/rules@92"},"arguments":[]},{"$type":"Group","elements":[{"$type":"Action","inferredType":{"$type":"InferredType","name":"InOutRelationExpr"},"feature":"inout","operator":"="},{"$type":"Keyword","value":"->"}],"cardinality":"?"}]},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"IncomingRelationExpr","definition":{"$type":"Group","elements":[{"$type":"Keyword","value":"->"},{"$type":"Assignment","feature":"to","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@88"},"arguments":[]}}]},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"DirectedRelationExpr","inferredType":{"$type":"InferredType","name":"RelationExpr"},"definition":{"$type":"Group","elements":[{"$type":"RuleCall","rule":{"$ref":"#/rules@94"},"arguments":[]},{"$type":"Group","elements":[{"$type":"Action","inferredType":{"$type":"InferredType","name":"DirectedRelationExpr"},"feature":"source","operator":"="},{"$type":"Assignment","feature":"target","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@88"},"arguments":[]}}],"cardinality":"?"}]},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"OutgoingRelationExpr","definition":{"$type":"Group","elements":[{"$type":"Assignment","feature":"from","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@88"},"arguments":[]}},{"$type":"Alternatives","elements":[{"$type":"Assignment","feature":"isBidirectional","operator":"?=","terminal":{"$type":"Keyword","value":"<->"}},{"$type":"Keyword","value":"->"},{"$type":"Group","elements":[{"$type":"Keyword","value":"-["},{"$type":"Assignment","feature":"kind","operator":"=","terminal":{"$type":"CrossReference","type":{"$ref":"#/rules@5"},"terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@165"},"arguments":[]},"deprecatedSyntax":false}},{"$type":"Keyword","value":"]->"}]},{"$type":"Assignment","feature":"dotKind","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@151"},"arguments":[]}}]}]},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"FqnExpressions","definition":{"$type":"Group","elements":[{"$type":"Assignment","feature":"value","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@88"},"arguments":[]}},{"$type":"Group","elements":[{"$type":"Action","inferredType":{"$type":"InferredType","name":"FqnExpressions"},"feature":"prev","operator":"="},{"$type":"Keyword","value":","},{"$type":"Assignment","feature":"value","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@88"},"arguments":[]},"cardinality":"?"}],"cardinality":"*"}]},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"WhereElementExpression","definition":{"$type":"RuleCall","rule":{"$ref":"#/rules@97"},"arguments":[]},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"WhereElementOr","inferredType":{"$type":"InferredType","name":"WhereElementExpression"},"definition":{"$type":"Group","elements":[{"$type":"RuleCall","rule":{"$ref":"#/rules@98"},"arguments":[]},{"$type":"Group","elements":[{"$type":"Action","inferredType":{"$type":"InferredType","name":"WhereBinaryExpression"},"feature":"left","operator":"="},{"$type":"Assignment","feature":"operator","operator":"=","terminal":{"$type":"Keyword","value":"or"}},{"$type":"Assignment","feature":"right","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@98"},"arguments":[]}}],"cardinality":"*"}]},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"WhereElementAnd","inferredType":{"$type":"InferredType","name":"WhereElementExpression"},"definition":{"$type":"Group","elements":[{"$type":"RuleCall","rule":{"$ref":"#/rules@99"},"arguments":[]},{"$type":"Group","elements":[{"$type":"Action","inferredType":{"$type":"InferredType","name":"WhereBinaryExpression"},"feature":"left","operator":"="},{"$type":"Assignment","feature":"operator","operator":"=","terminal":{"$type":"Keyword","value":"and"}},{"$type":"Assignment","feature":"right","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@99"},"arguments":[]}}],"cardinality":"*"}]},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"WhereElementPrimary","inferredType":{"$type":"InferredType","name":"WhereElementExpression"},"definition":{"$type":"Alternatives","elements":[{"$type":"Group","elements":[{"$type":"Keyword","value":"("},{"$type":"RuleCall","rule":{"$ref":"#/rules@96"},"arguments":[]},{"$type":"Keyword","value":")"}]},{"$type":"RuleCall","rule":{"$ref":"#/rules@100"},"arguments":[]},{"$type":"RuleCall","rule":{"$ref":"#/rules@101"},"arguments":[]}]},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"WhereElementNegation","definition":{"$type":"Group","elements":[{"$type":"Keyword","value":"not"},{"$type":"Assignment","feature":"value","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@96"},"arguments":[]}}]},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"WhereElement","definition":{"$type":"Alternatives","elements":[{"$type":"Group","elements":[{"$type":"Action","inferredType":{"$type":"InferredType","name":"WhereElementTag"}},{"$type":"Keyword","value":"tag"},{"$type":"RuleCall","rule":{"$ref":"#/rules@166"},"arguments":[]},{"$type":"Assignment","feature":"value","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@150"},"arguments":[]}}]},{"$type":"Group","elements":[{"$type":"Action","inferredType":{"$type":"InferredType","name":"WhereElementKind"}},{"$type":"Keyword","value":"kind"},{"$type":"RuleCall","rule":{"$ref":"#/rules@166"},"arguments":[]},{"$type":"Assignment","feature":"value","operator":"=","terminal":{"$type":"CrossReference","type":{"$ref":"#/types@6"},"deprecatedSyntax":false}}]},{"$type":"Group","elements":[{"$type":"Action","inferredType":{"$type":"InferredType","name":"WhereElementMetadata"}},{"$type":"Keyword","value":"metadata"},{"$type":"RuleCall","rule":{"$ref":"#/rules@180"},"arguments":[]},{"$type":"Assignment","feature":"key","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@165"},"arguments":[]}},{"$type":"Group","elements":[{"$type":"RuleCall","rule":{"$ref":"#/rules@166"},"arguments":[]},{"$type":"Assignment","feature":"value","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@102"},"arguments":[]}}],"cardinality":"?"}]}]},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"MetadataFilterValue","dataType":"string","definition":{"$type":"Alternatives","elements":[{"$type":"RuleCall","rule":{"$ref":"#/rules@186"},"arguments":[]},{"$type":"RuleCall","rule":{"$ref":"#/rules@172"},"arguments":[]}]},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"WhereRelationExpression","definition":{"$type":"RuleCall","rule":{"$ref":"#/rules@104"},"arguments":[]},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"WhereRelationOr","inferredType":{"$type":"InferredType","name":"WhereRelationExpression"},"definition":{"$type":"Group","elements":[{"$type":"RuleCall","rule":{"$ref":"#/rules@105"},"arguments":[]},{"$type":"Group","elements":[{"$type":"Action","inferredType":{"$type":"InferredType","name":"WhereBinaryExpression"},"feature":"left","operator":"="},{"$type":"Assignment","feature":"operator","operator":"=","terminal":{"$type":"Keyword","value":"or"}},{"$type":"Assignment","feature":"right","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@105"},"arguments":[]}}],"cardinality":"*"}]},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"WhereRelationAnd","inferredType":{"$type":"InferredType","name":"WhereRelationExpression"},"definition":{"$type":"Group","elements":[{"$type":"RuleCall","rule":{"$ref":"#/rules@106"},"arguments":[]},{"$type":"Group","elements":[{"$type":"Action","inferredType":{"$type":"InferredType","name":"WhereBinaryExpression"},"feature":"left","operator":"="},{"$type":"Assignment","feature":"operator","operator":"=","terminal":{"$type":"Keyword","value":"and"}},{"$type":"Assignment","feature":"right","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@106"},"arguments":[]}}],"cardinality":"*"}]},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"WhereRelationPrimary","inferredType":{"$type":"InferredType","name":"WhereRelationExpression"},"definition":{"$type":"Alternatives","elements":[{"$type":"Group","elements":[{"$type":"Keyword","value":"("},{"$type":"RuleCall","rule":{"$ref":"#/rules@103"},"arguments":[]},{"$type":"Keyword","value":")"}]},{"$type":"RuleCall","rule":{"$ref":"#/rules@107"},"arguments":[]},{"$type":"RuleCall","rule":{"$ref":"#/rules@108"},"arguments":[]}]},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"WhereRelationNegation","definition":{"$type":"Group","elements":[{"$type":"Keyword","value":"not"},{"$type":"Assignment","feature":"value","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@103"},"arguments":[]}}]},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"WhereRelation","definition":{"$type":"Alternatives","elements":[{"$type":"Group","elements":[{"$type":"Action","inferredType":{"$type":"InferredType","name":"WhereRelationTag"}},{"$type":"Keyword","value":"tag"},{"$type":"RuleCall","rule":{"$ref":"#/rules@166"},"arguments":[]},{"$type":"Assignment","feature":"value","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@150"},"arguments":[]}}]},{"$type":"Group","elements":[{"$type":"Action","inferredType":{"$type":"InferredType","name":"WhereRelationKind"}},{"$type":"Keyword","value":"kind"},{"$type":"RuleCall","rule":{"$ref":"#/rules@166"},"arguments":[]},{"$type":"Assignment","feature":"value","operator":"=","terminal":{"$type":"CrossReference","type":{"$ref":"#/rules@5"},"terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@165"},"arguments":[]},"deprecatedSyntax":false}}]},{"$type":"Group","elements":[{"$type":"Action","inferredType":{"$type":"InferredType","name":"WhereRelationMetadata"}},{"$type":"Keyword","value":"metadata"},{"$type":"RuleCall","rule":{"$ref":"#/rules@180"},"arguments":[]},{"$type":"Assignment","feature":"key","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@165"},"arguments":[]}},{"$type":"Group","elements":[{"$type":"RuleCall","rule":{"$ref":"#/rules@166"},"arguments":[]},{"$type":"Assignment","feature":"value","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@102"},"arguments":[]}}],"cardinality":"?"}]},{"$type":"Group","elements":[{"$type":"Action","inferredType":{"$type":"InferredType","name":"WhereRelationParticipantTag"}},{"$type":"Assignment","feature":"participant","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@157"},"arguments":[]}},{"$type":"RuleCall","rule":{"$ref":"#/rules@180"},"arguments":[]},{"$type":"Keyword","value":"tag"},{"$type":"RuleCall","rule":{"$ref":"#/rules@166"},"arguments":[]},{"$type":"Assignment","feature":"value","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@150"},"arguments":[]}}]},{"$type":"Group","elements":[{"$type":"Action","inferredType":{"$type":"InferredType","name":"WhereRelationParticipantKind"}},{"$type":"Assignment","feature":"participant","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@157"},"arguments":[]}},{"$type":"RuleCall","rule":{"$ref":"#/rules@180"},"arguments":[]},{"$type":"Keyword","value":"kind"},{"$type":"RuleCall","rule":{"$ref":"#/rules@166"},"arguments":[]},{"$type":"Assignment","feature":"value","operator":"=","terminal":{"$type":"CrossReference","type":{"$ref":"#/types@6"},"terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@165"},"arguments":[]},"deprecatedSyntax":false}}]},{"$type":"Group","elements":[{"$type":"Action","inferredType":{"$type":"InferredType","name":"WhereRelationParticipantMetadata"}},{"$type":"Assignment","feature":"participant","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@157"},"arguments":[]}},{"$type":"RuleCall","rule":{"$ref":"#/rules@180"},"arguments":[]},{"$type":"Keyword","value":"metadata"},{"$type":"RuleCall","rule":{"$ref":"#/rules@180"},"arguments":[]},{"$type":"Assignment","feature":"key","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@165"},"arguments":[]}},{"$type":"Group","elements":[{"$type":"RuleCall","rule":{"$ref":"#/rules@166"},"arguments":[]},{"$type":"Assignment","feature":"value","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@102"},"arguments":[]}}],"cardinality":"?"}]}]},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"ModelDeployments","definition":{"$type":"Group","elements":[{"$type":"Assignment","feature":"name","operator":"=","terminal":{"$type":"Keyword","value":"deployment"}},{"$type":"Keyword","value":"{"},{"$type":"Assignment","feature":"elements","operator":"+=","terminal":{"$type":"Alternatives","elements":[{"$type":"RuleCall","rule":{"$ref":"#/rules@110"},"arguments":[]},{"$type":"RuleCall","rule":{"$ref":"#/rules@116"},"arguments":[{"$type":"NamedArgument","value":{"$type":"BooleanLiteral","true":true},"calledByName":false}]},{"$type":"RuleCall","rule":{"$ref":"#/rules@114"},"arguments":[]}]},"cardinality":"*"},{"$type":"Keyword","value":"}"}]},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"DeploymentNode","definition":{"$type":"Group","elements":[{"$type":"Alternatives","elements":[{"$type":"Group","elements":[{"$type":"Assignment","feature":"kind","operator":"=","terminal":{"$type":"CrossReference","type":{"$ref":"#/rules@7"},"terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@165"},"arguments":[]},"deprecatedSyntax":false}},{"$type":"Assignment","feature":"name","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@165"},"arguments":[]}}]},{"$type":"Group","elements":[{"$type":"Assignment","feature":"name","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@165"},"arguments":[]}},{"$type":"RuleCall","rule":{"$ref":"#/rules@183"},"arguments":[]},{"$type":"Assignment","feature":"kind","operator":"=","terminal":{"$type":"CrossReference","type":{"$ref":"#/rules@7"},"terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@165"},"arguments":[]},"deprecatedSyntax":false}}]}]},{"$type":"Group","elements":[{"$type":"Assignment","feature":"title","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@186"},"arguments":[]}},{"$type":"Assignment","feature":"summary","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@186"},"arguments":[]},"cardinality":"?"}],"cardinality":"?"},{"$type":"Assignment","feature":"body","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@111"},"arguments":[]},"cardinality":"?"}]},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"DeploymentNodeBody","definition":{"$type":"Group","elements":[{"$type":"Keyword","value":"{"},{"$type":"Assignment","feature":"tags","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@18"},"arguments":[]},"cardinality":"?"},{"$type":"Assignment","feature":"props","operator":"+=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@22"},"arguments":[]},"cardinality":"*"},{"$type":"Assignment","feature":"elements","operator":"+=","terminal":{"$type":"Alternatives","elements":[{"$type":"RuleCall","rule":{"$ref":"#/rules@112"},"arguments":[]},{"$type":"RuleCall","rule":{"$ref":"#/rules@116"},"arguments":[{"$type":"NamedArgument","value":{"$type":"BooleanLiteral","true":false},"calledByName":false}]},{"$type":"RuleCall","rule":{"$ref":"#/rules@110"},"arguments":[]}]},"cardinality":"*"},{"$type":"Keyword","value":"}"}]},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"DeployedInstance","definition":{"$type":"Group","elements":[{"$type":"Group","elements":[{"$type":"Assignment","feature":"name","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@165"},"arguments":[]}},{"$type":"RuleCall","rule":{"$ref":"#/rules@183"},"arguments":[]}],"cardinality":"?"},{"$type":"Keyword","value":"instanceOf"},{"$type":"Assignment","feature":"target","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@30"},"arguments":[]}},{"$type":"Group","elements":[{"$type":"Assignment","feature":"title","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@186"},"arguments":[]}},{"$type":"Assignment","feature":"summary","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@186"},"arguments":[]},"cardinality":"?"}],"cardinality":"?"},{"$type":"Assignment","feature":"body","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@113"},"arguments":[]},"cardinality":"?"},{"$type":"Keyword","value":";","cardinality":"?"}]},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"DeployedInstanceBody","definition":{"$type":"Group","elements":[{"$type":"Keyword","value":"{"},{"$type":"Assignment","feature":"tags","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@18"},"arguments":[]},"cardinality":"?"},{"$type":"Assignment","feature":"props","operator":"+=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@22"},"arguments":[]},"cardinality":"*"},{"$type":"Assignment","feature":"elements","operator":"+=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@116"},"arguments":[{"$type":"NamedArgument","value":{"$type":"BooleanLiteral","true":false},"calledByName":false}]},"cardinality":"*"},{"$type":"Keyword","value":"}"}]},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"ExtendDeployment","definition":{"$type":"Group","elements":[{"$type":"Keyword","value":"extend"},{"$type":"Assignment","feature":"deploymentNode","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@33"},"arguments":[]}},{"$type":"Assignment","feature":"body","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@115"},"arguments":[]}}]},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"ExtendDeploymentBody","definition":{"$type":"Group","elements":[{"$type":"Keyword","value":"{"},{"$type":"Assignment","feature":"tags","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@18"},"arguments":[]},"cardinality":"?"},{"$type":"Assignment","feature":"props","operator":"+=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@26"},"arguments":[]},"cardinality":"*"},{"$type":"Assignment","feature":"elements","operator":"+=","terminal":{"$type":"Alternatives","elements":[{"$type":"RuleCall","rule":{"$ref":"#/rules@112"},"arguments":[]},{"$type":"RuleCall","rule":{"$ref":"#/rules@116"},"arguments":[{"$type":"NamedArgument","value":{"$type":"BooleanLiteral","true":true},"calledByName":false}]},{"$type":"RuleCall","rule":{"$ref":"#/rules@110"},"arguments":[]}]},"cardinality":"*"},{"$type":"Keyword","value":"}"}]},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"DeploymentRelation","parameters":[{"$type":"Parameter","name":"isExplicit"}],"definition":{"$type":"Group","elements":[{"$type":"Alternatives","elements":[{"$type":"Group","guardCondition":{"$type":"ParameterReference","parameter":{"$ref":"#/rules@116/parameters@0"}},"elements":[{"$type":"Assignment","feature":"source","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@32"},"arguments":[]}}]},{"$type":"Group","guardCondition":{"$type":"Negation","value":{"$type":"ParameterReference","parameter":{"$ref":"#/rules@116/parameters@0"}}},"elements":[{"$type":"Assignment","feature":"source","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@32"},"arguments":[]},"cardinality":"?"}]}]},{"$type":"Alternatives","elements":[{"$type":"Assignment","feature":"dotKind","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@151"},"arguments":[]}},{"$type":"Group","elements":[{"$type":"Keyword","value":"-["},{"$type":"Assignment","feature":"kind","operator":"=","terminal":{"$type":"CrossReference","type":{"$ref":"#/rules@5"},"deprecatedSyntax":false}},{"$type":"Keyword","value":"]->"}]},{"$type":"Keyword","value":"->"}]},{"$type":"Assignment","feature":"target","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@32"},"arguments":[]}},{"$type":"Group","elements":[{"$type":"Assignment","feature":"title","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@186"},"arguments":[]}},{"$type":"Group","elements":[{"$type":"Assignment","feature":"description","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@186"},"arguments":[]}},{"$type":"Assignment","feature":"technology","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@186"},"arguments":[]},"cardinality":"?"}],"cardinality":"?"}],"cardinality":"?"},{"$type":"Assignment","feature":"tags","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@18"},"arguments":[]},"cardinality":"?"},{"$type":"Assignment","feature":"body","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@117"},"arguments":[]},"cardinality":"?"}]},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"wildcard":false},{"$type":"ParserRule","name":"DeploymentRelationBody","definition":{"$type":"Group","elements":[{"$type":"Keyword","value":"{"},{"$type":"Assignment","feature":"tags","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@18"},"arguments":[]},"cardinality":"?"},{"$type":"Assignment","feature":"props","operator":"+=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@36"},"arguments":[]},"cardinality":"*"},{"$type":"Keyword","value":"}"}]},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"DeploymentView","definition":{"$type":"Group","elements":[{"$type":"Keyword","value":"deployment"},{"$type":"Keyword","value":"view"},{"$type":"Assignment","feature":"name","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@165"},"arguments":[]}},{"$type":"Assignment","feature":"body","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@119"},"arguments":[]},"cardinality":"?"}]},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"DeploymentViewBody","definition":{"$type":"Group","elements":[{"$type":"Keyword","value":"{"},{"$type":"Assignment","feature":"tags","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@18"},"arguments":[]},"cardinality":"?"},{"$type":"Assignment","feature":"props","operator":"+=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@55"},"arguments":[]},"cardinality":"*"},{"$type":"Assignment","feature":"rules","operator":"+=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@120"},"arguments":[]},"cardinality":"*"},{"$type":"Keyword","value":"}"}]},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"DeploymentViewRule","definition":{"$type":"Alternatives","elements":[{"$type":"RuleCall","rule":{"$ref":"#/rules@122"},"arguments":[]},{"$type":"RuleCall","rule":{"$ref":"#/rules@121"},"arguments":[]},{"$type":"RuleCall","rule":{"$ref":"#/rules@75"},"arguments":[]}]},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"DeploymentViewRuleStyle","definition":{"$type":"Group","elements":[{"$type":"Keyword","value":"style"},{"$type":"Assignment","feature":"targets","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@95"},"arguments":[]}},{"$type":"Keyword","value":"{"},{"$type":"Assignment","feature":"props","operator":"+=","terminal":{"$type":"Alternatives","elements":[{"$type":"RuleCall","rule":{"$ref":"#/rules@145"},"arguments":[]},{"$type":"RuleCall","rule":{"$ref":"#/rules@76"},"arguments":[]}]},"cardinality":"*"},{"$type":"Keyword","value":"}"}]},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"DeploymentViewRulePredicate","definition":{"$type":"Group","elements":[{"$type":"Alternatives","elements":[{"$type":"Assignment","feature":"isInclude","operator":"?=","terminal":{"$type":"Keyword","value":"include"}},{"$type":"Keyword","value":"exclude"}]},{"$type":"Assignment","feature":"expr","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@82"},"arguments":[]}}]},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"Globals","definition":{"$type":"Group","elements":[{"$type":"Assignment","feature":"name","operator":"=","terminal":{"$type":"Keyword","value":"global"}},{"$type":"Keyword","value":"{"},{"$type":"Group","elements":[{"$type":"Assignment","feature":"predicates","operator":"+=","terminal":{"$type":"Alternatives","elements":[{"$type":"RuleCall","rule":{"$ref":"#/rules@124"},"arguments":[]},{"$type":"RuleCall","rule":{"$ref":"#/rules@125"},"arguments":[]}]},"cardinality":"*"},{"$type":"Assignment","feature":"styles","operator":"+=","terminal":{"$type":"Alternatives","elements":[{"$type":"RuleCall","rule":{"$ref":"#/rules@127"},"arguments":[]},{"$type":"RuleCall","rule":{"$ref":"#/rules@128"},"arguments":[]}]},"cardinality":"*"}],"cardinality":"*"},{"$type":"Keyword","value":"}"}]},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"GlobalPredicateGroup","definition":{"$type":"Group","elements":[{"$type":"Keyword","value":"predicateGroup"},{"$type":"Assignment","feature":"name","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@189"},"arguments":[]}},{"$type":"Keyword","value":"{"},{"$type":"Assignment","feature":"predicates","operator":"+=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@68"},"arguments":[]},"cardinality":"*"},{"$type":"Keyword","value":"}"}]},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"GlobalDynamicPredicateGroup","definition":{"$type":"Group","elements":[{"$type":"Keyword","value":"dynamicPredicateGroup"},{"$type":"Assignment","feature":"name","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@189"},"arguments":[]}},{"$type":"Keyword","value":"{"},{"$type":"Assignment","feature":"predicates","operator":"+=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@70"},"arguments":[]},"cardinality":"*"},{"$type":"Keyword","value":"}"}]},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"GlobalStyleId","definition":{"$type":"Assignment","feature":"name","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@189"},"arguments":[]}},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"GlobalStyle","definition":{"$type":"Group","elements":[{"$type":"Keyword","value":"style"},{"$type":"Assignment","feature":"id","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@126"},"arguments":[]}},{"$type":"Assignment","feature":"targets","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@95"},"arguments":[]}},{"$type":"Keyword","value":"{"},{"$type":"Assignment","feature":"props","operator":"+=","terminal":{"$type":"Alternatives","elements":[{"$type":"RuleCall","rule":{"$ref":"#/rules@145"},"arguments":[]},{"$type":"RuleCall","rule":{"$ref":"#/rules@76"},"arguments":[]}]},"cardinality":"*"},{"$type":"Keyword","value":"}"}]},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"GlobalStyleGroup","definition":{"$type":"Group","elements":[{"$type":"Keyword","value":"styleGroup"},{"$type":"Assignment","feature":"id","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@126"},"arguments":[]}},{"$type":"Keyword","value":"{"},{"$type":"Assignment","feature":"styles","operator":"+=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@72"},"arguments":[]},"cardinality":"*"},{"$type":"Keyword","value":"}"}]},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"LinkProperty","definition":{"$type":"Group","elements":[{"$type":"Assignment","feature":"key","operator":"=","terminal":{"$type":"Keyword","value":"link"}},{"$type":"Keyword","value":":","cardinality":"?"},{"$type":"Assignment","feature":"value","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@162"},"arguments":[]}},{"$type":"Assignment","feature":"title","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@186"},"arguments":[]},"cardinality":"?"},{"$type":"Keyword","value":";","cardinality":"?"}]},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"ColorProperty","definition":{"$type":"Group","elements":[{"$type":"Assignment","feature":"key","operator":"=","terminal":{"$type":"Keyword","value":"color"}},{"$type":"Keyword","value":":","cardinality":"?"},{"$type":"Alternatives","elements":[{"$type":"Assignment","feature":"themeColor","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@155"},"arguments":[]}},{"$type":"Assignment","feature":"customColor","operator":"=","terminal":{"$type":"CrossReference","type":{"$ref":"#/rules@6"},"terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@164"},"arguments":[]},"deprecatedSyntax":false}}]},{"$type":"Keyword","value":";","cardinality":"?"}]},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"OpacityProperty","definition":{"$type":"Group","elements":[{"$type":"Assignment","feature":"key","operator":"=","terminal":{"$type":"Keyword","value":"opacity"}},{"$type":"Keyword","value":":","cardinality":"?"},{"$type":"Assignment","feature":"value","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@184"},"arguments":[]}},{"$type":"Keyword","value":";","cardinality":"?"}]},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"MultipleProperty","definition":{"$type":"Group","elements":[{"$type":"Assignment","feature":"key","operator":"=","terminal":{"$type":"Keyword","value":"multiple"}},{"$type":"Keyword","value":":","cardinality":"?"},{"$type":"Assignment","feature":"value","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@172"},"arguments":[]}},{"$type":"Keyword","value":";","cardinality":"?"}]},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"IconProperty","definition":{"$type":"Group","elements":[{"$type":"Assignment","feature":"key","operator":"=","terminal":{"$type":"Keyword","value":"icon"}},{"$type":"Keyword","value":":","cardinality":"?"},{"$type":"Alternatives","elements":[{"$type":"Assignment","feature":"libicon","operator":"=","terminal":{"$type":"CrossReference","type":{"$ref":"#/rules@2"},"terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@161"},"arguments":[]},"deprecatedSyntax":false}},{"$type":"Assignment","feature":"value","operator":"=","terminal":{"$type":"Alternatives","elements":[{"$type":"Keyword","value":"none"},{"$type":"RuleCall","rule":{"$ref":"#/rules@162"},"arguments":[]}]}}]},{"$type":"Keyword","value":";","cardinality":"?"}]},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"IconColorProperty","definition":{"$type":"Group","elements":[{"$type":"Assignment","feature":"key","operator":"=","terminal":{"$type":"Keyword","value":"iconColor"}},{"$type":"Keyword","value":":","cardinality":"?"},{"$type":"Alternatives","elements":[{"$type":"Assignment","feature":"themeColor","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@155"},"arguments":[]}},{"$type":"Assignment","feature":"customColor","operator":"=","terminal":{"$type":"CrossReference","type":{"$ref":"#/rules@6"},"terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@164"},"arguments":[]},"deprecatedSyntax":false}}]},{"$type":"Keyword","value":";","cardinality":"?"}]},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"IconSizeProperty","definition":{"$type":"Group","elements":[{"$type":"Assignment","feature":"key","operator":"=","terminal":{"$type":"Keyword","value":"iconSize"}},{"$type":"Keyword","value":":","cardinality":"?"},{"$type":"Assignment","feature":"value","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@141"},"arguments":[]}},{"$type":"Keyword","value":";","cardinality":"?"}]},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"IconPositionValue","dataType":"string","definition":{"$type":"Alternatives","elements":[{"$type":"Keyword","value":"left"},{"$type":"Keyword","value":"right"},{"$type":"Keyword","value":"top"},{"$type":"Keyword","value":"bottom"}]},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"IconPositionProperty","definition":{"$type":"Group","elements":[{"$type":"Assignment","feature":"key","operator":"=","terminal":{"$type":"Keyword","value":"iconPosition"}},{"$type":"Keyword","value":":","cardinality":"?"},{"$type":"Assignment","feature":"value","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@136"},"arguments":[]}},{"$type":"Keyword","value":";","cardinality":"?"}]},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"ShapeProperty","definition":{"$type":"Group","elements":[{"$type":"Assignment","feature":"key","operator":"=","terminal":{"$type":"Keyword","value":"shape"}},{"$type":"Keyword","value":":","cardinality":"?"},{"$type":"Assignment","feature":"value","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@156"},"arguments":[]}},{"$type":"Keyword","value":";","cardinality":"?"}]},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"BorderStyleValue","dataType":"string","definition":{"$type":"Alternatives","elements":[{"$type":"RuleCall","rule":{"$ref":"#/rules@152"},"arguments":[]},{"$type":"Keyword","value":"none"}]},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"BorderProperty","definition":{"$type":"Group","elements":[{"$type":"Assignment","feature":"key","operator":"=","terminal":{"$type":"Keyword","value":"border"}},{"$type":"Keyword","value":":","cardinality":"?"},{"$type":"Assignment","feature":"value","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@139"},"arguments":[]}},{"$type":"Keyword","value":";","cardinality":"?"}]},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"SizeValue","dataType":"string","definition":{"$type":"Alternatives","elements":[{"$type":"Keyword","value":"xs"},{"$type":"Keyword","value":"sm"},{"$type":"Keyword","value":"md"},{"$type":"Keyword","value":"lg"},{"$type":"Keyword","value":"xl"},{"$type":"Keyword","value":"xsmall"},{"$type":"Keyword","value":"small"},{"$type":"Keyword","value":"medium"},{"$type":"Keyword","value":"large"},{"$type":"Keyword","value":"xlarge"}]},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"ShapeSizeProperty","definition":{"$type":"Group","elements":[{"$type":"Assignment","feature":"key","operator":"=","terminal":{"$type":"Keyword","value":"size"}},{"$type":"Keyword","value":":","cardinality":"?"},{"$type":"Assignment","feature":"value","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@141"},"arguments":[]}},{"$type":"Keyword","value":";","cardinality":"?"}]},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"PaddingSizeProperty","definition":{"$type":"Group","elements":[{"$type":"Assignment","feature":"key","operator":"=","terminal":{"$type":"Keyword","value":"padding"}},{"$type":"Keyword","value":":","cardinality":"?"},{"$type":"Assignment","feature":"value","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@141"},"arguments":[]}},{"$type":"Keyword","value":";","cardinality":"?"}]},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"TextSizeProperty","definition":{"$type":"Group","elements":[{"$type":"Assignment","feature":"key","operator":"=","terminal":{"$type":"Keyword","value":"textSize"}},{"$type":"Keyword","value":":","cardinality":"?"},{"$type":"Assignment","feature":"value","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@141"},"arguments":[]}},{"$type":"Keyword","value":";","cardinality":"?"}]},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"StyleProperty","definition":{"$type":"Alternatives","elements":[{"$type":"RuleCall","rule":{"$ref":"#/rules@130"},"arguments":[]},{"$type":"RuleCall","rule":{"$ref":"#/rules@138"},"arguments":[]},{"$type":"RuleCall","rule":{"$ref":"#/rules@140"},"arguments":[]},{"$type":"RuleCall","rule":{"$ref":"#/rules@131"},"arguments":[]},{"$type":"RuleCall","rule":{"$ref":"#/rules@133"},"arguments":[]},{"$type":"RuleCall","rule":{"$ref":"#/rules@134"},"arguments":[]},{"$type":"RuleCall","rule":{"$ref":"#/rules@132"},"arguments":[]},{"$type":"RuleCall","rule":{"$ref":"#/rules@142"},"arguments":[]},{"$type":"RuleCall","rule":{"$ref":"#/rules@143"},"arguments":[]},{"$type":"RuleCall","rule":{"$ref":"#/rules@144"},"arguments":[]},{"$type":"RuleCall","rule":{"$ref":"#/rules@135"},"arguments":[]},{"$type":"RuleCall","rule":{"$ref":"#/rules@137"},"arguments":[]}]},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"ElementStyleProperty","definition":{"$type":"Group","elements":[{"$type":"Assignment","feature":"key","operator":"=","terminal":{"$type":"Keyword","value":"style"}},{"$type":"Keyword","value":"{"},{"$type":"Assignment","feature":"props","operator":"+=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@145"},"arguments":[]},"cardinality":"*"},{"$type":"Keyword","value":"}"}]},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"LineProperty","definition":{"$type":"Group","elements":[{"$type":"Assignment","feature":"key","operator":"=","terminal":{"$type":"Keyword","value":"line"}},{"$type":"Keyword","value":":","cardinality":"?"},{"$type":"Assignment","feature":"value","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@152"},"arguments":[]}},{"$type":"Keyword","value":";","cardinality":"?"}]},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"ArrowProperty","definition":{"$type":"Group","elements":[{"$type":"Assignment","feature":"key","operator":"=","terminal":{"$type":"Alternatives","elements":[{"$type":"Keyword","value":"head"},{"$type":"Keyword","value":"tail"}]}},{"$type":"Keyword","value":":","cardinality":"?"},{"$type":"Assignment","feature":"value","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@153"},"arguments":[]}},{"$type":"Keyword","value":";","cardinality":"?"}]},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"RelationshipStyleProperty","definition":{"$type":"Alternatives","elements":[{"$type":"RuleCall","rule":{"$ref":"#/rules@130"},"arguments":[]},{"$type":"RuleCall","rule":{"$ref":"#/rules@147"},"arguments":[]},{"$type":"RuleCall","rule":{"$ref":"#/rules@148"},"arguments":[]}]},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"TagRef","definition":{"$type":"Group","elements":[{"$type":"RuleCall","rule":{"$ref":"#/rules@179"},"arguments":[]},{"$type":"Assignment","feature":"tag","operator":"=","terminal":{"$type":"CrossReference","type":{"$ref":"#/rules@4"},"terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@165"},"arguments":[]},"deprecatedSyntax":false}}]},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"RelationKindDotRef","definition":{"$type":"Group","elements":[{"$type":"RuleCall","rule":{"$ref":"#/rules@181"},"arguments":[]},{"$type":"Assignment","feature":"kind","operator":"=","terminal":{"$type":"CrossReference","type":{"$ref":"#/rules@5"},"terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@165"},"arguments":[]},"deprecatedSyntax":false}}]},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"LineOptions","dataType":"string","definition":{"$type":"Alternatives","elements":[{"$type":"Keyword","value":"solid"},{"$type":"Keyword","value":"dashed"},{"$type":"Keyword","value":"dotted"}]},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"ArrowType","dataType":"string","definition":{"$type":"Alternatives","elements":[{"$type":"Keyword","value":"none"},{"$type":"Keyword","value":"normal"},{"$type":"Keyword","value":"onormal"},{"$type":"Keyword","value":"dot"},{"$type":"Keyword","value":"odot"},{"$type":"Keyword","value":"diamond"},{"$type":"Keyword","value":"odiamond"},{"$type":"Keyword","value":"crow"},{"$type":"Keyword","value":"open"},{"$type":"Keyword","value":"vee"}]},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"DynamicViewDisplayVariantValue","dataType":"string","definition":{"$type":"Alternatives","elements":[{"$type":"Keyword","value":"diagram"},{"$type":"Keyword","value":"sequence"}]},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"ThemeColor","dataType":"string","definition":{"$type":"Alternatives","elements":[{"$type":"Keyword","value":"primary"},{"$type":"Keyword","value":"secondary"},{"$type":"Keyword","value":"muted"},{"$type":"Keyword","value":"slate"},{"$type":"Keyword","value":"blue"},{"$type":"Keyword","value":"indigo"},{"$type":"Keyword","value":"sky"},{"$type":"Keyword","value":"red"},{"$type":"Keyword","value":"gray"},{"$type":"Keyword","value":"green"},{"$type":"Keyword","value":"amber"}]},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"ElementShape","dataType":"string","definition":{"$type":"Alternatives","elements":[{"$type":"Keyword","value":"rectangle"},{"$type":"Keyword","value":"component"},{"$type":"Keyword","value":"person"},{"$type":"Keyword","value":"browser"},{"$type":"Keyword","value":"mobile"},{"$type":"Keyword","value":"cylinder"},{"$type":"Keyword","value":"storage"},{"$type":"Keyword","value":"queue"},{"$type":"Keyword","value":"bucket"},{"$type":"Keyword","value":"document"}]},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"Participant","dataType":"string","definition":{"$type":"Alternatives","elements":[{"$type":"Keyword","value":"source"},{"$type":"Keyword","value":"target"}]},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"ColorLiteral","definition":{"$type":"Alternatives","elements":[{"$type":"RuleCall","rule":{"$ref":"#/rules@159"},"arguments":[]},{"$type":"RuleCall","rule":{"$ref":"#/rules@160"},"arguments":[]}]},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"RGBAColor","definition":{"$type":"Group","elements":[{"$type":"Alternatives","elements":[{"$type":"Keyword","value":"rgba"},{"$type":"Keyword","value":"rgb"}]},{"$type":"Keyword","value":"("},{"$type":"Assignment","feature":"red","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@188"},"arguments":[]}},{"$type":"Keyword","value":",","cardinality":"?"},{"$type":"Assignment","feature":"green","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@188"},"arguments":[]}},{"$type":"Keyword","value":",","cardinality":"?"},{"$type":"Assignment","feature":"blue","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@188"},"arguments":[]}},{"$type":"Keyword","value":",","cardinality":"?"},{"$type":"Assignment","feature":"alpha","operator":"=","terminal":{"$type":"Alternatives","elements":[{"$type":"RuleCall","rule":{"$ref":"#/rules@187"},"arguments":[]},{"$type":"RuleCall","rule":{"$ref":"#/rules@188"},"arguments":[]},{"$type":"RuleCall","rule":{"$ref":"#/rules@184"},"arguments":[]}]},"cardinality":"?"},{"$type":"Keyword","value":")"}]},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"HexColor","definition":{"$type":"Group","elements":[{"$type":"RuleCall","rule":{"$ref":"#/rules@179"},"arguments":[]},{"$type":"Assignment","feature":"hex","operator":"=","terminal":{"$type":"Alternatives","elements":[{"$type":"RuleCall","rule":{"$ref":"#/rules@190"},"arguments":[]},{"$type":"RuleCall","rule":{"$ref":"#/rules@188"},"arguments":[]},{"$type":"RuleCall","rule":{"$ref":"#/rules@189"},"arguments":[]}]}}]},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"IconId","dataType":"string","definition":{"$type":"RuleCall","rule":{"$ref":"#/rules@173"},"arguments":[]},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"Uri","dataType":"string","definition":{"$type":"Alternatives","elements":[{"$type":"RuleCall","rule":{"$ref":"#/rules@174"},"arguments":[]},{"$type":"RuleCall","rule":{"$ref":"#/rules@175"},"arguments":[]},{"$type":"RuleCall","rule":{"$ref":"#/rules@176"},"arguments":[]}]},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"MarkdownOrString","definition":{"$type":"Alternatives","elements":[{"$type":"Assignment","feature":"markdown","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@185"},"arguments":[]}},{"$type":"Assignment","feature":"text","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@186"},"arguments":[]}}]},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"CustomColorId","dataType":"string","definition":{"$type":"Alternatives","elements":[{"$type":"RuleCall","rule":{"$ref":"#/rules@189"},"arguments":[]},{"$type":"RuleCall","rule":{"$ref":"#/rules@156"},"arguments":[]},{"$type":"RuleCall","rule":{"$ref":"#/rules@153"},"arguments":[]},{"$type":"RuleCall","rule":{"$ref":"#/rules@152"},"arguments":[]},{"$type":"RuleCall","rule":{"$ref":"#/rules@157"},"arguments":[]},{"$type":"Keyword","value":"element"},{"$type":"Keyword","value":"model"}]},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"Id","dataType":"string","definition":{"$type":"Alternatives","elements":[{"$type":"RuleCall","rule":{"$ref":"#/rules@189"},"arguments":[]},{"$type":"RuleCall","rule":{"$ref":"#/rules@156"},"arguments":[]},{"$type":"RuleCall","rule":{"$ref":"#/rules@155"},"arguments":[]},{"$type":"RuleCall","rule":{"$ref":"#/rules@153"},"arguments":[]},{"$type":"RuleCall","rule":{"$ref":"#/rules@152"},"arguments":[]},{"$type":"RuleCall","rule":{"$ref":"#/rules@157"},"arguments":[]},{"$type":"RuleCall","rule":{"$ref":"#/rules@141"},"arguments":[]},{"$type":"RuleCall","rule":{"$ref":"#/rules@154"},"arguments":[]},{"$type":"RuleCall","rule":{"$ref":"#/rules@136"},"arguments":[]},{"$type":"RuleCall","rule":{"$ref":"#/rules@60"},"arguments":[]},{"$type":"Keyword","value":"element"},{"$type":"Keyword","value":"model"},{"$type":"Keyword","value":"group"},{"$type":"Keyword","value":"node"},{"$type":"Keyword","value":"deployment"},{"$type":"Keyword","value":"instance"}]},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","fragment":true,"name":"EqOperator","definition":{"$type":"Alternatives","elements":[{"$type":"Assignment","feature":"operator","operator":"=","terminal":{"$type":"Alternatives","elements":[{"$type":"RuleCall","rule":{"$ref":"#/rules@183"},"arguments":[]},{"$type":"RuleCall","rule":{"$ref":"#/rules@182"},"arguments":[]}]}},{"$type":"Group","elements":[{"$type":"Assignment","feature":"operator","operator":"=","terminal":{"$type":"Keyword","value":"is"}},{"$type":"Assignment","feature":"not","operator":"?=","terminal":{"$type":"Keyword","value":"not"},"cardinality":"?"}]}]},"definesHiddenTokens":false,"entry":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","fragment":true,"name":"IsEqual","definition":{"$type":"Alternatives","elements":[{"$type":"Assignment","feature":"isEqual","operator":"?=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@183"},"arguments":[]}},{"$type":"RuleCall","rule":{"$ref":"#/rules@182"},"arguments":[]}]},"definesHiddenTokens":false,"entry":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"TerminalRule","hidden":true,"name":"BLOCK_COMMENT","definition":{"$type":"RegexToken","regex":"/\\\\/\\\\*[\\\\s\\\\S]*?\\\\*\\\\//"},"fragment":false},{"$type":"TerminalRule","hidden":true,"name":"LINE_COMMENT","definition":{"$type":"RegexToken","regex":"/\\\\/\\\\/[^\\\\n\\\\r]*/"},"fragment":false},{"$type":"TerminalRule","hidden":true,"name":"WS","definition":{"$type":"RegexToken","regex":"/[\\\\t ]+/"},"fragment":false},{"$type":"TerminalRule","hidden":true,"name":"NL","definition":{"$type":"RegexToken","regex":"/[\\\\r\\\\n]+/"},"fragment":false},{"$type":"TerminalRule","name":"BOOLEAN","type":{"$type":"ReturnType","name":"boolean"},"definition":{"$type":"RegexToken","regex":"/\\\\b(true|false)\\\\b/"},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"LIB_ICON","definition":{"$type":"RegexToken","regex":"/(aws|azure|bootstrap|gcp|tech):[-\\\\w]*/"},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"URI_WITH_SCHEMA","definition":{"$type":"RegexToken","regex":"/\\\\w+:\\\\/{2}\\\\S+/"},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"URI_RELATIVE","definition":{"$type":"RegexToken","regex":"/\\\\.{0,2}\\\\/[^\\\\/]\\\\S+/"},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"URI_ALIAS","definition":{"$type":"RegexToken","regex":"/@[a-zA-Z0-9_-]*\\\\/[^\\\\s]+/"},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"DotUnderscore","definition":{"$type":"RegexToken","regex":"/\\\\b\\\\._(?![_a-zA-Z])/"},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"DotWildcard","definition":{"$type":"RegexToken","regex":"/\\\\b\\\\.\\\\*{1,2}/"},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"Hash","definition":{"$type":"CharacterRange","left":{"$type":"Keyword","value":"#"}},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"StickyDot","definition":{"$type":"RegexToken","regex":"/\\\\b\\\\./"},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"Dot","definition":{"$type":"CharacterRange","left":{"$type":"Keyword","value":"."}},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"NotEqual","definition":{"$type":"RegexToken","regex":"/\\\\!\\\\={1,2}/"},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"Eq","definition":{"$type":"RegexToken","regex":"/\\\\={1,2}/"},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"Percent","definition":{"$type":"RegexToken","regex":"/\\\\b\\\\d+%/"},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"MarkdownString","definition":{"$type":"TerminalAlternatives","elements":[{"$type":"TerminalGroup","elements":[{"$type":"CharacterRange","left":{"$type":"Keyword","value":"'''"}},{"$type":"UntilToken","terminal":{"$type":"CharacterRange","left":{"$type":"Keyword","value":"'''"}}}]},{"$type":"TerminalGroup","elements":[{"$type":"CharacterRange","left":{"$type":"Keyword","value":"\\"\\"\\""}},{"$type":"UntilToken","terminal":{"$type":"CharacterRange","left":{"$type":"Keyword","value":"\\"\\"\\""}}}]}]},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"String","definition":{"$type":"RegexToken","regex":"/\\"(?:[^\\"\\\\\\\\]|\\\\\\\\.)*\\"|'(?:[^'\\\\\\\\]|\\\\\\\\.)*'/"},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"Float","type":{"$type":"ReturnType","name":"number"},"definition":{"$type":"RegexToken","regex":"/\\\\b\\\\d+\\\\.\\\\d+\\\\b/"},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"Number","type":{"$type":"ReturnType","name":"number"},"definition":{"$type":"RegexToken","regex":"/\\\\b\\\\d+\\\\b/"},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"IdTerminal","definition":{"$type":"RegexToken","regex":"/[_]*[a-zA-Z][-\\\\w]*/"},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"Hex","definition":{"$type":"RegexToken","regex":"/[a-fA-F0-9]{3,}(?![-_g-zG-Z])/"},"fragment":false,"hidden":false}],"types":[{"$type":"Type","name":"ModelReferenceable","type":{"$type":"UnionType","types":[{"$type":"SimpleType","typeRef":{"$ref":"#/rules@20"}},{"$type":"SimpleType","typeRef":{"$ref":"#/rules@17"}}]}},{"$type":"Type","name":"Referenceable","type":{"$type":"UnionType","types":[{"$type":"SimpleType","typeRef":{"$ref":"#/rules@110"}},{"$type":"SimpleType","typeRef":{"$ref":"#/rules@112"}},{"$type":"SimpleType","typeRef":{"$ref":"#/rules@20"}},{"$type":"SimpleType","typeRef":{"$ref":"#/rules@17"}}]}},{"$type":"Type","name":"LikeC4View","type":{"$type":"UnionType","types":[{"$type":"SimpleType","typeRef":{"$ref":"#/rules@46"}},{"$type":"SimpleType","typeRef":{"$ref":"#/rules@47"}},{"$type":"SimpleType","typeRef":{"$ref":"#/rules@118"}}]}},{"$type":"Type","name":"StringProperty","type":{"$type":"UnionType","types":[{"$type":"SimpleType","typeRef":{"$ref":"#/rules@23"}},{"$type":"SimpleType","typeRef":{"$ref":"#/rules@56"}},{"$type":"SimpleType","typeRef":{"$ref":"#/rules@37"}},{"$type":"SimpleType","typeRef":{"$ref":"#/rules@41"}},{"$type":"SimpleType","typeRef":{"$ref":"#/rules@10"}},{"$type":"SimpleType","typeRef":{"$ref":"#/rules@15"}},{"$type":"SimpleType","typeRef":{"$ref":"#/rules@76"}},{"$type":"SimpleType","typeRef":{"$ref":"#/rules@77"}}]}},{"$type":"Type","name":"AnyProperty","type":{"$type":"UnionType","types":[{"$type":"SimpleType","typeRef":{"$ref":"#/types@3"}},{"$type":"SimpleType","typeRef":{"$ref":"#/rules@55"}},{"$type":"SimpleType","typeRef":{"$ref":"#/rules@53"}},{"$type":"SimpleType","typeRef":{"$ref":"#/rules@22"}},{"$type":"SimpleType","typeRef":{"$ref":"#/rules@36"}},{"$type":"SimpleType","typeRef":{"$ref":"#/rules@149"}},{"$type":"SimpleType","typeRef":{"$ref":"#/rules@76"}},{"$type":"SimpleType","typeRef":{"$ref":"#/rules@77"}},{"$type":"SimpleType","typeRef":{"$ref":"#/rules@80"}},{"$type":"SimpleType","typeRef":{"$ref":"#/rules@145"}}]}},{"$type":"Type","name":"DynamicViewStep","type":{"$type":"UnionType","types":[{"$type":"SimpleType","typeRef":{"$ref":"#/interfaces@1"}},{"$type":"SimpleType","typeRef":{"$ref":"#/interfaces@2"}}]}},{"$type":"Type","name":"DeploymentNodeOrElementKind","type":{"$type":"UnionType","types":[{"$type":"SimpleType","typeRef":{"$ref":"#/rules@3"}},{"$type":"SimpleType","typeRef":{"$ref":"#/rules@7"}}]}},{"$type":"Type","name":"WhereTagEqual","type":{"$type":"UnionType","types":[{"$type":"SimpleType","typeRef":{"$ref":"#/rules@101/definition/elements@0/elements@0/inferredType"}},{"$type":"SimpleType","typeRef":{"$ref":"#/rules@108/definition/elements@0/elements@0/inferredType"}},{"$type":"SimpleType","typeRef":{"$ref":"#/rules@108/definition/elements@3/elements@0/inferredType"}}]}},{"$type":"Type","name":"WhereKindEqual","type":{"$type":"UnionType","types":[{"$type":"SimpleType","typeRef":{"$ref":"#/rules@101/definition/elements@1/elements@0/inferredType"}},{"$type":"SimpleType","typeRef":{"$ref":"#/rules@108/definition/elements@1/elements@0/inferredType"}},{"$type":"SimpleType","typeRef":{"$ref":"#/rules@108/definition/elements@4/elements@0/inferredType"}}]}},{"$type":"Type","name":"WhereMetadataEqual","type":{"$type":"UnionType","types":[{"$type":"SimpleType","typeRef":{"$ref":"#/rules@101/definition/elements@2/elements@0/inferredType"}},{"$type":"SimpleType","typeRef":{"$ref":"#/rules@108/definition/elements@2/elements@0/inferredType"}},{"$type":"SimpleType","typeRef":{"$ref":"#/rules@108/definition/elements@5/elements@0/inferredType"}}]}},{"$type":"Type","name":"WhereExpression","type":{"$type":"UnionType","types":[{"$type":"SimpleType","typeRef":{"$ref":"#/rules@96"}},{"$type":"SimpleType","typeRef":{"$ref":"#/rules@103"}}]}},{"$type":"Type","name":"DeploymentElement","type":{"$type":"UnionType","types":[{"$type":"SimpleType","typeRef":{"$ref":"#/rules@110"}},{"$type":"SimpleType","typeRef":{"$ref":"#/rules@112"}}]}},{"$type":"Type","name":"FqnReferenceable","type":{"$type":"UnionType","types":[{"$type":"SimpleType","typeRef":{"$ref":"#/types@1"}},{"$type":"SimpleType","typeRef":{"$ref":"#/rules@20"}},{"$type":"SimpleType","typeRef":{"$ref":"#/rules@24"}},{"$type":"SimpleType","typeRef":{"$ref":"#/rules@114"}}]}},{"$type":"Type","name":"SizeProperty","type":{"$type":"UnionType","types":[{"$type":"SimpleType","typeRef":{"$ref":"#/rules@142"}},{"$type":"SimpleType","typeRef":{"$ref":"#/rules@143"}},{"$type":"SimpleType","typeRef":{"$ref":"#/rules@144"}},{"$type":"SimpleType","typeRef":{"$ref":"#/rules@135"}}]}}],"interfaces":[{"$type":"Interface","name":"AbstractDynamicStep","attributes":[{"$type":"TypeAttribute","name":"kind","isOptional":true,"type":{"$type":"ReferenceType","referenceType":{"$type":"SimpleType","typeRef":{"$ref":"#/rules@5"}}}},{"$type":"TypeAttribute","name":"dotKind","isOptional":true,"type":{"$type":"SimpleType","typeRef":{"$ref":"#/rules@151"}}},{"$type":"TypeAttribute","name":"target","type":{"$type":"SimpleType","typeRef":{"$ref":"#/rules@30"}},"isOptional":false},{"$type":"TypeAttribute","name":"title","isOptional":true,"type":{"$type":"SimpleType","primitiveType":"string"}},{"$type":"TypeAttribute","name":"custom","isOptional":true,"type":{"$type":"SimpleType","typeRef":{"$ref":"#/rules@79"}}}],"superTypes":[]},{"$type":"Interface","name":"DynamicStepSingle","superTypes":[{"$ref":"#/interfaces@0"}],"attributes":[{"$type":"TypeAttribute","name":"source","type":{"$type":"SimpleType","typeRef":{"$ref":"#/rules@30"}},"isOptional":false},{"$type":"TypeAttribute","name":"isBackward","isOptional":true,"type":{"$type":"SimpleType","primitiveType":"boolean"}}]},{"$type":"Interface","name":"DynamicStepChain","superTypes":[{"$ref":"#/interfaces@0"}],"attributes":[{"$type":"TypeAttribute","name":"source","type":{"$type":"UnionType","types":[{"$type":"SimpleType","typeRef":{"$ref":"#/interfaces@1"}},{"$type":"SimpleType","typeRef":{"$ref":"#/interfaces@2"}}]},"isOptional":false}]}],"definesHiddenTokens":false,"hiddenTokens":[],"imports":[],"usedGrammars":[]}`),yf={languageId:`likec4`,fileExtensions:[`.c4`,`.likec4`,`.like-c4`],caseInsensitive:!1,mode:`production`},bf={skipValidations:!0,recoveryEnabled:!0,nodeLocationTracking:`full`},xf={AstReflection:()=>new gf},Sf={Grammar:()=>vf(),LanguageMetaData:()=>yf,parser:{ParserConfig:()=>bf}},Cf=Symbol.for(`idattr`),wf={writeId(e,t){return e[Cf]=t,e},readId(e){return e[Cf]}},Tf={writeId(e,t){return a(t)?e[Cf]=void 0:e[Cf]=t,e},readId(e){return e[Cf]}};function Ef(e){return e?.textDocument.languageId===yf.languageId}function Df(e){return Ef(e)&&co(e)}function Of(e){return e?.markdown||e?.text}function kf(e){let n=parseFloat(e);return isNaN(n)?100:t(n,{min:0,max:100})}function Af({value:e}){return kf(e)}function jf({value:e}){switch(e){case`xs`:case`sm`:case`md`:case`lg`:case`xl`:return e;case`xsmall`:return`xs`;case`small`:return`sm`;case`medium`:return`md`;case`large`:return`lg`;case`xlarge`:return`xl`;default:ri(e)}}function Mf({value:e}){switch(e){case`left`:case`right`:case`top`:case`bottom`:return e;default:ri(e)}}function Nf(e,t){let n={};if(!e||e.length===0)return n;for(let r of e)if(t(r))switch(!0){case Ns(r):{let e=Pf(r);i(e)&&(n.color=e);break}case Jl(r):n.line=r.value;break;case ks(r):switch(r.key){case`head`:n.head=r.value;break;case`tail`:n.tail=r.value;break;default:ri(r)}break;default:ri(r)}return n}function Pf(e){return e?.themeColor??e?.customColor?.$refText}function Ff(e){let t=e.rankSep,n=e.nodeSep,r;switch(e.direction){case`TopBottom`:r=`TB`;break;case`BottomTop`:r=`BT`;break;case`LeftRight`:r=`LR`;break;case`RightLeft`:r=`RL`;break;default:ri(e.direction)}return{direction:r,...n&&{nodeSep:n},...t&&{rankSep:t}}}function If(e){switch(e){case`TB`:return`TopBottom`;case`BT`:return`BottomTop`;case`LR`:return`LeftRight`;case`RL`:return`RightLeft`;default:ri(e)}}function Lf(e){return Ut(e,e=>Md(e)||ic(e)||vc(e))}const Rf=e=>ou(e)||wc(e)||Zc(e)||Bc(e)||fc(e)||Ac(e),zf=e=>cu(e)||nc(e)||Ks(e)||qc(e)||Hs(e);function Bf(e){for(;;){if(zf(e)||Rf(e))return!1;if(_l(e)||uu(e))return!0;if(e.$container)e=e.$container;else return!1}}function Vf(e){for(;;){if(zf(e))return!1;if(Rf(e))return!0;if(e.$container)e=e.$container;else return!1}}function Hf(e){for(;;){if(Rf(e))return!1;if(zf(e))return!0;if(e.$container)e=e.$container;else return!1}}function Uf(e){try{let t=fd(e)?e.el.ref:e.modelElement.value.ref;return t?.$type===`Imported`&&(t=t.imported.ref),t?.$type===`Element`?t:void 0}catch{return}}function Wf(e){let t=[e.$type===`StrictFqnRef`?e.value.$refText:e.el.$refText],n=e.parent;for(;n;)t.push(n.$type===`StrictFqnRef`?n.value.$refText:n.el.$refText),n=n.parent;return t.length===1?t[0]:t.reverse().join(`.`)}function Gf(e){for(;e.parent;)e=e.parent;return e.value.ref??null}function Kf(e){let t;for(;t=e.value?.ref;){if(Ws(t))return null;if(Bs(t))return t;if(a(e.parent))return null;e=e.parent}return null}function qf(e){let t=Gf(e);return t?.$type===`Imported`?t:null}function Jf(e){let t;for(;t=e.value?.ref;){if(go(t))return!0;if(a(e.parent))return!1;e=e.parent}return!1}var Yf=class extends at{constructor(e){super(e),this.services=e}createDescription(e,t,n){n??=rn(e);let r=super.createDescription(e,t,n);return so(n.uri)||(n.likec4ProjectId??=this.services.shared.workspace.ProjectsManager.ownerProjectId(n),r.likec4ProjectId=n.likec4ProjectId),r}},Xf=class extends sn{constructor(e){super(e),this.services=e}async updateContent(e,t){e.likec4ProjectId=this.services.workspace.ProjectsManager.ownerProjectId(e),await super.updateContent(e,t)}projectElements(e,t,n){let r=this.services.workspace.ProjectsManager;return on(this.symbolIndex.keys()).filter(t=>n&&!n.has(t)?!1:r.isIncluded(e,t)).flatMap(e=>this.getFileDescriptions(e,t))}};const Zf=qr(`/`),Qf=(e,t)=>Zf(e.uri.path,t.uri.path);var $f=class extends dn{constructor(e){super(e),this.services=e}get projectsManager(){return this.services.workspace.ProjectsManager}addDocument(e){let t=e.uri.toString();if(this.documentMap.has(t))throw Error(`A document with the URI '${t}' is already present.`);let n=[...this.documentMap.values(),e].sort(Qf);this.documentMap.clear();for(let e of n)this.documentMap.set(e.uri.toString(),e);Df(e)&&(e.likec4ProjectId=this.projectsManager.ownerProjectId(e))}getDocument(e){let t=super.getDocument(e);return Df(t)&&(t.likec4ProjectId=this.projectsManager.ownerProjectId(t)),t}get userDocuments(){return on(this.documentMap.values()).filter(e=>Df(e)&&!this.projectsManager.isExcluded(e))}get all(){return on(this.documentMap.values()).map(e=>(Df(e)&&(e.likec4ProjectId=this.projectsManager.ownerProjectId(e)),e))}projectDocuments(e){let t=this.services.workspace.ProjectsManager;return on(this.documentMap.values()).filter(n=>Df(n)&&t.isIncluded(e,n)?(n.likec4ProjectId=e,!0):!1)}groupedByProject(){let e=this.services.workspace.ProjectsManager;return y(this.userDocuments.toArray(),x(t=>(t.likec4ProjectId=e.ownerProjectId(t),t)),_(De(`likec4ProjectId`)))}resetProjectIds(){let e=[];for(let t of this.documentMap.values())delete t.likec4ProjectId,Df(t)&&!this.projectsManager.isExcluded(t)&&e.push(t.uri);return e}},ep=e(Cn(),1);const W=B.getChild(`projects`);function tp(e){return typeof e==`object`&&`uri`in e&&`textDocument`in e}function np(e){return tp(e)?e.uri.toString():typeof e==`string`?Mn(e,{acceptRelative:!1,strict:!0})?e:C.file(e).toString():e.toString()}const rp=qr(`/`,!0),ip=(e,t)=>rp(jn(e.path),jn(t.path));function ap(e){return t=>e.startsWith($r(t)?t:t.folder)}function op(e,t){let n=$r(e)?e:e.folder,r=$r(t)?t:t.folder;return n.startsWith(r)||r.startsWith(n)}function sp(...e){return be(op,e)}function cp(e,t){return t.startsWith(e.folder)||e.includePaths?.some(ap(t))?!lp(e,t):!1}function lp(e,t){return e.exclude?.(En(t))??!1}function up(...e){return be(cp,e)}function dp(...e){return be(lp,e)}function fp(e){return e=np(e),On(e)}const pp=(e,t)=>ip(e.folderUri,t.folderUri);function mp(e){return e.sort(pp)}const hp={id:`default`,config:{name:`default`,exclude:[`**/node_modules/**`]},exclude:(0,ep.default)(`**/node_modules/**`,{dot:!0}),includeConfig:{paths:[],maxDepth:3,fileThreshold:30}};function gp(e){return hp.exclude(En(e))}function _p(e){if(`configUri`in e){I(!ge(e.configUri),`configUri is emptyish`);let t=C.isUri(e.configUri)?e.configUri:C.parse(np(e.configUri)),n=fp(T.dirname(t));return{configUri:t,folder:n,folderUri:C.parse(n)}}I(!ge(e.folderUri),`folderUri is emptyish`);let t=fp(e.folderUri),n=C.parse(t);return{configUri:T.joinPath(n,`likec4.config.json`),folder:t,folderUri:n}}var vp=class e{static DefaultProjectId=hp.id;#e=[];#t=void 0;#n=[];#r=new Vr(t=>{if(t===e.DefaultProjectId){let e=this.getWorkspaceFolder(),n=T.joinPath(e,`likec4.config.json`),r=fp(e);return{id:t,config:hp.config,folder:r,folderUri:C.parse(r),configUri:n,exclude:hp.exclude,includeConfig:{...hp.includeConfig}}}return ni(this.#n.find(e=>e.id===t),`Project ${t} not found`)});#i=new Vr(e=>{let t=np(e),n=this.#a.get(t);return n?dp(n,t)?!this.#n.some(up(t)):!1:gp(t)});#a=new Vr(e=>{let t=ap(e);return this.#n.find(t)??this.#n.find(up(e))??null});constructor(e){this.services=e,W.debug`created`}get defaultProjectId(){if(this.#t)return this.#t;if(!(this.#n.length>1))return v(this.#n,1)?this.#n[0].id:e.DefaultProjectId}set defaultProjectId(t){if(t!==this.#t){if(this.#t=void 0,!t||t===e.DefaultProjectId){W.debug`reset default project ID`;return}I(this.#n.find(e=>e.id===t),`Project "${t}" not found`),W.debug`set default project ID to ${t}`,this.#t=t}}get default(){return this.#r.get(this.defaultProjectId??e.DefaultProjectId)}get all(){if(v(this.#n,1)){let e=[...x(this.#n,De(`id`)),hp.id];if(this.#t){let t=e.findIndex(e=>e===this.#t);t>0&&(e.splice(t,1),e.unshift(this.#t))}return e}return[hp.id]}getProject(e){let t=typeof e==`string`?e:e.likec4ProjectId??this.ownerProjectId(e);return this.#r.get(t)}findOverlaped(e){let t=sp(fp(e)),n=e=>t(e)||!!e.includePaths&&!!d(e.includePaths,t);return this.#n.filter(n)}ensureProjectId(t){return t===e.DefaultProjectId?this.defaultProjectId??e.DefaultProjectId:t?(I(this.#n.some(e=>t===e.id),`Project ID ${t} is not registered`),t):ni(this.defaultProjectId,()=>`Specify exact project, known: [${x(this.#n,De(`id`)).join(`, `)}]`)}ensureProject(e){return e=this.ensureProjectId(e),this.getProject(e)}hasMultipleProjects(){return this.#n.length>1}isExcluded(...e){let t=e.length===1?e[0]:e[1];return tp(t)&&so(t)?!0:e.length===1?this.#i.get(np(t)):dp(this.#r.get(e[0]),np(t))}isIncluded(t,n){let r=np(n);return v(this.#n,1)?t===e.DefaultProjectId?!this.#a.get(r)&&!gp(r):up(this.#r.get(t),np(n)):!gp(r)}async registerConfigFile(e,t){if(gp(np(e)))throw Error(`Failed to register project config, path ${e.fsPath} is excluded by: ${hp.config.exclude.map(e=>`"${e}"`).join(`, `)}`);try{let n=await this.services.workspace.FileSystemProvider.loadProjectConfig(e);return await this.registerProject({config:n,configUri:e},t)}catch(t){if(!st(t))throw Li(t,`Failed to register project config ${e.fsPath}:\n`);return Promise.reject(t)}}async registerProject(e,t){let n=Ze.validate(e.config),{configUri:r,folder:i,folderUri:a}=_p(e),o=Ze.normalizeInclude(n.include),s=this.#n.find(e=>e.folder===i);return s?(s.config.name!==n.name&&(W.info`project name changed from ${s.config.name} to ${n.name}`,W.info`unregistering ${s.id}`,s.id=this.uniqueProjectId(n.name),W.info`register ${s.id}`),this.warnIfConfigOverride(s,r),s.config=n,s.folder=i,s.folderUri=a,s.configUri=r,s.includeConfig=o):(s={id:this.uniqueProjectId(n.name),config:n,folder:i,configUri:r,folderUri:a,includeConfig:o},this.#n=mp([...this.#n,s]),W.info`register ${s.id}`),Tp(()=>this.updateIncludesExcludes(s)),this.#o?s:(this.resetCaches(),this.notifyListeners(),await this.rebuildProject(s.id,t).catch(e=>st(e)?Promise.reject(e):(W.warn(`Failed to rebuild project {projectId} after config change`,{projectId:s.id,error:e}),Promise.resolve())),s)}ownerProjectId(t){return this.#a.get(np(t))?.id??this.#t??e.DefaultProjectId}#o=null;async reloadProjects(e){return this.#o?(W.debug`reload projects is already in progress, waiting`,await this.#o.catch(()=>{})):(W.debug`schedule reload projects`,this.#o=Promise.resolve().then(()=>this._reloadProjects(e)).catch(e=>(st(e)||W.warn(`Failed to reload projects`,{error:e}),Promise.reject(e))).finally(()=>{this.#o=null,this.notifyListeners()}),await this.#o)}async _reloadProjects(e){let t=this.services.workspace.WorkspaceManager.workspaceFolders;if(!t||t.length===0){W.warn(`Failed to reloadProjects, no workspace folders found`);return}W.debug`start reload projects`;let n=[];for(let e of t){let t=C.parse(e.uri);W.debug`scan projects in ${t.fsPath}`;try{let e=await this.services.workspace.FileSystemProvider.scanProjectFiles(t);for(let r of e)W.debug`found config ${T.relative(t,r.uri)}`,n.push(r.uri)}catch(e){W.warn(`Failed on scanProjectFiles in {folder}`,{folder:t.fsPath,error:e})}}if(n.length===0){if(this.#n.length===0){W.warning(`No config files found`);return}W.warning(`no config files found, but {count} projects were registered before`,{count:this.#n.length}),W.warning(`reset`)}n.sort(ip);let r=new Map(this.#n.map(e=>[e.configUri.toString(),e]));this.#n=[],this.#r.clear();for(let e of n)try{await this.registerConfigFile(e)}catch(t){W.warn(L(t));let n=r.get(e.toString());n&&(W.debug`Update failed, restore project ${n.id}`,await this.registerProject(n).catch(e=>{W.warn(`fail to restore project ${n.id}, ignoring`,{error:e})}))}this.resetCaches(),this.notifyListeners(),await this.services.workspace.WorkspaceManager.rebuildAll(e)}uniqueProjectId(e){let t=new Set(x(this.#n,De(`id`))),n=e;if(!t.has(n))return n;W.warn`Project "${e}" already exists, generating unique ID`;let r=1;for(;t.has(n);)n=`${e}-${r++}`;return n}resetCaches(){W.trace(`resetCaches`),this.#t&&!this.#n.some(e=>e.id===this.#t)&&(this.#t=void 0),this.#r.clear(),this.#a.clear(),this.#i.clear()}async rebuildProject(t,n){let r=this.#n.find(e=>e.id===t);if(!r)return t===e.DefaultProjectId?W.info`Rebuilding all documents `:W.warn`Project ${t} not found, rebuilding all`,await this.services.workspace.WorkspaceManager.rebuildAll(n);let i=W.getChild(r.id),a=e=>up(r,np(e)),o=this.services.workspace.LangiumDocuments.userDocuments.filter(a).map(e=>e.uri).toArray();if(o.length===0){i.debug`no documents found for project ${r.id}, skipping rebuild`;return}i.info(`rebuild project documents: {docs}`,{docs:o.length}),this.resetCaches(),await this.services.workspace.DocumentBuilder.update(o,[],n).catch(e=>{i.warn(`Failed to rebuild project`,{error:e})})}getAllIncludePaths(){let e=[];for(let t of this.#n)if(t.includePaths)for(let n of t.includePaths)e.push({projectId:t.id,includePath:n.uri,includeConfig:t.includeConfig});return e}onProjectsUpdate(e){return this.#e.push(e),vt.create(()=>{let t=this.#e.indexOf(e);t>=0&&this.#e.splice(t,1)})}getWorkspaceFolder(){try{return this.services.workspace.WorkspaceManager.workspaceUri}catch(e){return W.warn(`Failed to get workspace URI, using default folder`,{error:e}),C.file(`/`)}}notifyListeners(){for(let e of this.#e)try{e()}catch(e){W.warn(L(e))}}updateIncludesExcludes(e){let t=e.config;switch(delete e.includePaths,delete e.exclude,!0){case a(t.exclude):e.exclude=hp.exclude;break;case t.exclude&&v(t.exclude,1):e.exclude=(0,ep.default)(x(t.exclude,t=>(!Dn(t)&&!t.startsWith(`**`)&&(t=An(`**`,t)),Nn(wn(e.folderUri.path,t)))),{contains:!0,dot:!0});break}let n=e.includeConfig.paths;if(!v(n,1))return e;e.includePaths=x(n,t=>{let n=T.resolvePath(e.folderUri,t);return{uri:n,folder:fp(n)}}),W.debug`project ${e.id} include paths: ${e.includePaths.map(e=>e.uri.fsPath).join(`, `)}`;for(let t of e.includePaths)for(let n of this.#n)n.id!==e.id&&(sp(t,n)&&W.warn(`Project "{projectId}" include path "{includePath}" overlaps with project "{otherProjectId}" folder. Files in overlapping areas will only belong to one project.`,{projectId:e.id,includePath:t.folder,otherProjectId:n.id}),n.includePaths?.forEach(r=>{sp(t,r)&&W.warn(`Project "{projectId}" include path "{includePath}" overlaps with project "{otherProjectId}" include path "{otherIncludePath}". Files in overlapping areas will only belong to one project.`,{projectId:e.id,includePath:t.folder,otherProjectId:n.id,otherIncludePath:r.folder})}));return e}warnIfConfigOverride(e,t){try{let[n,r]=x([e.configUri,t],T.basename);n!==r&&W.warn`config ${r} overrides ${n} in folder ${e.folder}`}catch{}}};function yp(e){return yf.fileExtensions.some(t=>e!==t&&e.endsWith(t))}function bp(e){return[`node_modules`,`.git`,`.svn`,`.yarn`,`.pnpm`].includes(e)}const xp=qr(`/`);function Sp(e,t){return xp(e.uri.path,t.uri.path)}var Cp=class extends rt{documentFactory;fileSystemProvider;#e=[];initialBuildOptions={eagerLinking:!0,validation:!0};constructor(e){super(e),this.services=e,this.documentFactory=e.workspace.LangiumDocumentFactory,this.fileSystemProvider=e.workspace.FileSystemProvider}async performStartup(e){this.folders??=e;let t=[];for(let n of e)try{let e=C.parse(n.uri),r=await this.fileSystemProvider.scanProjectFiles(e);t.push(...r),this.services.workspace.FileSystemWatcher.watch(e.fsPath)}catch(e){V(e)}let n=this.services.workspace.ProjectsManager;for(let e of t)try{await n.registerConfigFile(e.uri)}catch(e){V(e)}return await super.performStartup(e)}async loadAdditionalDocuments(e,t){t(this.documentFactory.fromString(io,C.parse(oo)));let n=this.services.workspace.ProjectsManager.getAllIncludePaths(),r=0,i=[];for(let{projectId:e,includePath:t,includeConfig:r}of n)try{B.debug`scanning include path ${t.fsPath} for project ${e}`;let n=await this.fileSystemProvider.readDirectory(t,{recursive:!0,maxDepth:r.maxDepth});i.push(...n),n.length===0&&B.debug`loaded ${n.length} files from include path ${t.fsPath}`}catch(e){B.warn(`Failed to scan include path ${t.fsPath}`,{error:e})}for(let e of ye(i,e=>e.uri.path))try{t(await this.langiumDocuments.getOrCreateDocument(e.uri)),r++}catch(t){B.warn(`Failed to load document ${e.uri.fsPath}`,{error:t})}if(n.length>0&&r>0){let e=Math.min(...n.map(e=>e.includeConfig.fileThreshold));r>e?B.warn(`Loaded ${r} files from include paths (threshold: ${e}). Large include directories may slow workspace initialization. Consider adjusting "include.fileThreshold" or "include.maxDepth" in your project configuration.`):B.info`loaded ${r} total files from ${n.length} include paths`}}includeEntry(e,t,n){let r=T.basename(t.uri);return t.isDirectory?!bp(r):t.isFile?(n.fileExtensions.includes(T.extname(t.uri))||n.fileNames.includes(r))&&!this.services.workspace.ProjectsManager.isExcluded(t.uri):!1}workspace(){return this.folders&&v(this.folders,1)?this.folders[0]:null}async rebuildAll(e){let t=this.services.workspace.LangiumDocuments.resetProjectIds();B.info(`invalidate and rebuild all {docs} documents`,{docs:t.length}),this.forceCleanCaches(),await this.documentBuilder.update(t,[],e)}get workspaceUri(){let e=this.workspace();return N(e,`Workspace not initialized`),C.parse(e.uri)}get workspaceURL(){let e=this.workspace();return N(e,`Workspace not initialized`),new URL(e.uri)}forceCleanCaches(){for(let e of this.#e)e();this.services.workspace.ManualLayouts.clearCaches(),this.services.workspace.Cache.clear()}onForceCleanCache(e){return this.#e.push(e),vt.create(()=>{this.#e=this.#e.filter(t=>t!==e)})}};function G(e){if(Pl(e)){for(;e.$type===`Imported`&&e.$container;)e=e.$container;N(Il(e))}if(Il(e))return e.project;let t=Dt(e)?rn(e):e;return t.likec4ProjectId?t.likec4ProjectId:(B.warn`Document ${t.uri.fsPath} does not have a project ID assigned, this may lead to unexpected behavior.`,vp.DefaultProjectId)}function wp(...e){return ui(e.length>1?e.join(`:::`):e[0])}function Tp(e){try{return e()}catch(e){B.trace(`Safe call failed`,{error:e});return}}function Ep(){try{return globalThis.performance.now()}catch{return Date.now()}}function Dp(){let e=Ep();return{get ms(){return Ep()-e},get pretty(){return Sn(Ep()-e)}}}Qt();const Op=B.getChild(`manual-layouts`),kp=`.likec4.snap`,Ap=e=>e.endsWith(kp);function jp(e){return`${e}${kp}`}function Mp(e){let t=T.basename(e);return Ap(t)?t.slice(0,-12):null}function Np(e){return T.resolvePath(e.folderUri,e.config.manualLayouts?.outDir??`.likec4`)}const Pp={manualLayouts:e=>new Ip(e)},Fp=`file://./`;var Ip=class{cache;listeners=[];#e=yn(1);constructor(e){this.services=e,this.cache=new nt,ai(()=>{e.workspace.ProjectsManager.onProjectsUpdate(()=>{this.clearCaches()})})}async handleFileSystemUpdate(e){let t=e.update??e.delete,n=Mp(t)??void 0,r=this.services.workspace.ProjectsManager.ownerProjectId(t);if(this.cache.delete(r),`delete`in e){this.triggerUpdate(pr({removed:t,projectId:r,viewId:n}));return}let i=this.services.workspace.ProjectsManager.getProject(r);if(!n){let e=await this.readSnapshot(t,i);e?n=e.id:(Op.error(`File ${t} does not exist or is not a valid manual layout file`),n=`index`)}this.triggerUpdate({updated:t,projectId:r,viewId:n})}onManualLayoutUpdate(e){return this.listeners.push(e),{dispose:()=>{let t=this.listeners.indexOf(e);t!==-1&&this.listeners.splice(t,1)}}}async readManualLayouts(e){let t=Op.getChild(e.id),n=this.services.workspace.FileSystemProvider,r=Np(e),i=[];try{let a=await n.scanDirectory(r,Ap);if(a.length===0)return null;for(let r of a)try{let t=await n.readFile(r.uri),a=Ue.parse(t),o=this.resolveIconPathsAfterRead(a,e.folderUri);i.push({...o,_layout:`manual`})}catch(e){t.warn(`Failed to read view snapshot ${r.uri.fsPath}`,{err:e})}i.length&&t.trace`read manual layouts for ${e.id}, found ${i.length}`}catch(n){t.warn(`Failed to read manual layouts for ${e.folderUri.fsPath}`,{err:n})}if(i.length===0)return null;let a=h(i,De(`id`));return{hash:ii(a),views:a}}async readSnapshot(e,t){let n=this.services.workspace.FileSystemProvider;try{let r=await n.readFile(e),i=Ue.parse(r);if(!t){let n=this.services.workspace.ProjectsManager.ownerProjectId(e);t=this.services.workspace.ProjectsManager.getProject(n)}return{...this.resolveIconPathsAfterRead(i,t.folderUri),_layout:`manual`}}catch(t){return Op.warn(`Failed to read view snapshot ${e.fsPath}`,{err:t}),null}}async read(e){return await this.#e(async()=>{let t=this.cache.get(e.id);if(t!==void 0)return t;let n=await this.readManualLayouts(e);return this.cache.set(e.id,n),n})}async write(e,t){this.cache.delete(e.id);let n=Op.getChild(e.id),r=Np(e),i=T.joinPath(r,jp(t.id));if(`manualLayout`in t){let{manualLayout:e,...n}=t;t=n}let a=Ue.stringify(this.normalizeIconPathsForWrite(t,e.folderUri),{space:2,quote:`'`}),o={uri:i.toString(),range:ht.create(St.create(0,0),St.create(a.split(`
|
|
44
|
-
`).length-1,1))};n.debug`write snapshot of ${t.id} in project ${e.id} to ${i.fsPath}`;let s=this.services.workspace.FileSystemProvider;try{await s.writeFile(i,a+`
|
|
45
|
-
`),this.triggerUpdate({updated:i,projectId:e.id,viewId:t.id})}catch(e){n.warn(`Failed to write snapshot ${t.id} to ${i.fsPath}`,{err:e})}return o}async remove(e,t){this.cache.delete(e.id);let n=Op.getChild(e.id),r=Np(e),i=T.joinPath(r,jp(t));n.debug`delete snapshot of ${t} in project ${e.id}. File: ${i.fsPath}`;let a={uri:i.toString(),range:ht.create(0,0,0,0)};try{if(!await this.services.workspace.FileSystemProvider.deleteFile(i))return n.warn`Snapshot ${t} did not exist at ${i.fsPath}`,null;this.triggerUpdate({removed:i,projectId:e.id,viewId:t})}catch(e){n.warn(`Failed to delete snapshot ${t} from ${i.fsPath}`,{err:e})}return a}clearCaches(){Op.trace`clear caches`,this.cache.clear()}triggerUpdate(e){for(let t of this.listeners)Tp(()=>t(e))}normalizeIconPathsForWrite(e,t){let n=e.nodes.map(e=>{if(!e.icon||typeof e.icon!=`string`)return e;if(e.icon.startsWith(`file://`)){let n=C.parse(e.icon),r=T.relative(t,n);return r.startsWith(`..`)?e:{...e,icon:`${Fp}${r}`}}return e});return{...e,nodes:n}}resolveIconPathsAfterRead(e,t){let n=e.nodes.map(e=>{if(!e.icon||typeof e.icon!=`string`)return e;if(e.icon.startsWith(Fp)){let n=e.icon.substring(9),r=T.joinPath(t,n);return{...e,icon:r.toString()}}return e});return{...e,nodes:n}}};const Lp=B.getChild(`chokidar`),Rp={fileSystemWatcher:e=>new Bp(e)},zp=e=>{let t=wi(e);return yp(t)||Qe(t)||Ap(t)};var Bp=class{watcher;queue=new bn({concurrency:1,timeout:5e3});constructor(e){this.services=e}watch(e){if(this.watcher){Lp.debug`add watching folder: ${e}`,this.watcher.add(e);return}this.watcher=this.createWatcher(e)}async dispose(){if(this.watcher){let e=this.watcher;this.watcher=void 0,await e.close()}}createWatcher(e){Lp.debug`create watcher for folder: ${e}`;let t=Ai.watch(e,{ignored:[e=>e.includes(`node_modules`)||e.includes(`.git`),(e,t)=>!!t?.isFile()&&!zp(e)],followSymlinks:!0,ignoreInitial:!0}),n=(e,t)=>{t?.isDirectory()||this.enqueueFileOp(`addOrChange: `+e,async()=>{await this.onAddOrChange(e)})},r=(e,t)=>{t?.isDirectory()||this.enqueueFileOp(`remove: `+e,async()=>{await this.onRemove(e)})};return t.on(`add`,n).on(`change`,n).on(`unlink`,r).on(`unlinkDir`,e=>{this.enqueueFileOp(`removeDir: `+e,async()=>{await this.onRemoveDir(e)})}),t}enqueueFileOp(e,t){this.queue.add(async()=>{try{await t()}catch(t){Lp.warn(`Failed on {fileop}`,{fileop:e,error:t})}}).catch(t=>{Lp.error(`Error on {fileop}`,{fileop:e,error:t})})}async onAddOrChange(e){let t=this.services.workspace,n=wi(e),r=C.file(e);switch(!0){case Qe(n):Lp.debug`project file changed: ${e}`,t.ManualLayouts.clearCaches(),await t.ProjectsManager.registerConfigFile(r);break;case yp(n):Lp.debug`file changed: ${e}`,await t.DocumentBuilder.update([r],[]);break;case Ap(n):Lp.debug`manual layout file changed: ${e}`,t.ManualLayouts.clearCaches(),await t.ManualLayouts.handleFileSystemUpdate({update:r});break;default:Lp.warn`Unknown file change: ${e}`}}async onRemove(e){let t=this.services.workspace,n=wi(e),r=C.file(e);switch(!0){case Qe(n):Lp.debug`project file removed: ${e}`,t.ManualLayouts.clearCaches(),await t.ProjectsManager.reloadProjects();break;case yp(n):Lp.debug`file removed: ${e}`,await t.DocumentBuilder.update([],[r]);break;case Ap(n):Lp.debug`manual layout file removed: ${e}`,await t.ManualLayouts.handleFileSystemUpdate({delete:r});break;default:Lp.warn`Unknown file removal: ${e}`}}async onRemoveDir(e){Lp.debug`directory removed: ${e}`;let t=this.services.workspace;t.ProjectsManager.findOverlaped(e).length>0&&(t.ManualLayouts.clearCaches(),await t.ProjectsManager.reloadProjects())}},Vp=class{scanProjectFiles(){return Promise.resolve([])}scanDirectory(){return Promise.resolve([])}readFile(e){if(so(e))return Promise.resolve(io);throw Error(`No file system is available.`)}readDirectory(){return Promise.resolve([])}loadProjectConfig(){throw Error(`No file system is available.`)}writeFile(){throw Error(`No file system is available.`)}deleteFile(){throw Error(`No file system is available.`)}},Hp=class{watch(){}dispose(){return Promise.resolve()}},Up=class{handleFileSystemUpdate(){return Promise.resolve()}readSnapshot(){return Promise.resolve(null)}read(){return Promise.resolve(null)}write(){return Promise.reject(Error(`NoopLikeC4ManualLayouts: write operation is not supported`))}remove(){return Promise.resolve(null)}clearCaches(){}onManualLayoutUpdate(){return{dispose:()=>{}}}};const Wp={fileSystemWatcher:()=>new Hp},Gp={fileSystemProvider:()=>new Vp,...Wp},Kp={manualLayouts:()=>new Up},qp=B.getChild(`filesystem`);function Jp(e,t=!1){return!t&&Qe(wi(e))}function Yp(e,t=!1){return!t&&yp(wi(e))}const Xp=(e=!0)=>({fileSystemProvider:()=>new Zp,...e?Rp:Wp});var Zp=class extends qt{async readFile(e){if(so(e))return Promise.resolve(io);try{return await super.readFile(e)}catch(t){return qp.warn(`Failed to read file ${e.fsPath}`,{error:t}),``}}async readDirectory(e,t){let n=t?.recursive??!0,r=t?.maxDepth??1/0,i=[];try{let t=new Di().withSymlinks({resolvePaths:!1}).exclude(bp).withFullPaths().filter(Yp);n?r!==1/0&&(t=t.withMaxDepth(r)):t=t.withMaxDepth(1);let a=await t.crawl(e.fsPath).withPromise();for(let e of a)i.push({isFile:!0,isDirectory:!1,uri:C.file(e)})}catch(t){qp.warn(`Failed to read directory ${e.fsPath}`,{error:t})}return i.sort(Sp)}async scanProjectFiles(e){return await this.scanDirectory(e,Jp)}async scanDirectory(e,t){let n=[];try{let r=await new Di().withSymlinks({resolvePaths:!1}).exclude(bp).withFullPaths().filter(t).crawl(e.fsPath).withPromise();for(let e of r)n.push({isFile:!0,isDirectory:!1,uri:C.file(e)})}catch(t){qp.warn(`Failed to scan directory {path}`,{path:e.fsPath,error:t})}return n}async loadProjectConfig(e){return await ro(e)}async writeFile(e,t){let n=Ti(e.fsPath),r=ki(n,{throwIfNoEntry:!1});if(r?.isFile())throw Error(`Cannot create directory ${n} because a file with the same name exists.`);return r||(qp.debug(`creating directory {path}`,{path:n}),Oi(n,{recursive:!0})),qp.debug(`writing file {path}`,{path:e.fsPath}),await Ci(e.fsPath,t,{encoding:`utf-8`})}async deleteFile(e){try{let t=e.fsPath,n=ki(t,{throwIfNoEntry:!1});return n?.isFile()||n?.isSymbolicLink()?(await Si(t),qp.debug(`deleted file {path}`,{path:t}),!0):(qp.warn(`deleteFile failed: {path} does not exist, or is not a file`,{path:t}),!1)}catch(t){qp.warn(`Failed to delete file ${e.fsPath}`,{error:t})}return!1}};const Qp={mcpServer:()=>new $p,mcpServerFactory:()=>new em};var $p=class{get mcp(){throw Error(`NoopLikeC4MCPServer does not have a McpServer`)}get isStarted(){return!1}get port(){return NaN}start(){return Promise.resolve()}stop(){return Promise.resolve()}},em=class{create(e){throw Error(`NoopLikeC4MCPServerFactory`)}};const K=B.getChild(`mcp`);function q(e,t){let{name:n,description:r,...i}=e;return e=>[n,{description:r?.trim()??``,...i},tm(n,e,t)]}function tm(e,t,n){let r=n.bind(null,t);return(async function t(n,i){K.debug(`Calling tool {name}, args: {args}`,{name:e,args:n});try{let e=await r.call(null,n,i);return typeof e==`string`?{content:[{type:`text`,text:e}]}:{content:[{type:`text`,text:JSON.stringify(e)}],structuredContent:e}}catch(t){return K.error(`Tool ${e} failed`,{err:t}),{content:[{type:`text`,text:L(t)}],isError:!0}}})}var nm=`1.53.0`;const rm=O({name:k().describe(`Project identifier`),title:k().optional().describe(`Human-readable project title`),contactPerson:k().optional().describe(`Maintainer contact information`),metadata:Ln(k(),Fn()).optional().describe(`Custom project metadata as key-value pairs`),extends:zn([k(),j(k())]).optional().describe(`Style inheritance paths`),exclude:j(k()).optional().describe(`File exclusion patterns`),include:O({paths:j(k()).describe(`Include paths`),maxDepth:A().describe(`Maximum directory depth`),fileThreshold:A().describe(`File threshold`)}).optional().describe(`Include configuration`),manualLayouts:O({outDir:k().describe(`Output directory for manual layouts`)}).optional().describe(`Manual layouts configuration`),styles:O({hasTheme:Un().describe(`Whether theme customization is defined`),hasDefaults:Un().describe(`Whether default style values are defined`),hasCustomCss:Un().describe(`Whether custom CSS is defined`)}).optional().describe(`Simplified styles configuration (boolean flags)`)});function im(e){let t={name:e.name};return e.title!=null&&(t.title=e.title),e.contactPerson!=null&&(t.contactPerson=e.contactPerson),e.metadata&&(t.metadata=e.metadata),e.extends&&(t.extends=e.extends),e.exclude&&(t.exclude=e.exclude),e.include&&(t.include={paths:e.include.paths||[],maxDepth:e.include.maxDepth??3,fileThreshold:e.include.fileThreshold??30}),e.manualLayouts&&(t.manualLayouts={outDir:e.manualLayouts.outDir??`.likec4`}),e.styles&&(t.styles={hasTheme:!!e.styles.theme,hasDefaults:!!e.styles.defaults,hasCustomCss:!!e.styles.customCss}),t}const am=O({id:k().describe(`Element id (FQN)`),name:k().describe(`Element name`),kind:k().describe(`Element kind`),title:k(),tags:j(k()),metadata:Ln(zn([k(),j(k())])),includedInViews:j(O({id:k().describe(`View id`),title:k().describe(`View title`),type:In([`element`,`deployment`,`dynamic`]).describe(`View type`)})).describe(`Views that include this element`)});function om(e){return{id:e.id,name:e.name,kind:e.kind,title:e.title,tags:[...e.tags],metadata:e.getMetadata(),includedInViews:dm(e.views())}}function sm(e,t,n,r,i,a){N(e.findElement(t),`Element "${t}" not found`);let o=new Set,s={},c=0,l=!1,u=[{elementId:t,depth:0}];for(;u.length>0;){let{elementId:t,depth:d}=u.shift();if(d>i||o.has(t))continue;if(o.size>=a){l=!0;break}let f=e.findElement(t);if(!f)continue;o.add(t),c=Math.max(c,d);let p=(n===`incoming`?[...f.incoming(r)]:[...f.outgoing(r)]).map(e=>{let t={elementId:n===`incoming`?e.source.id:e.target.id};return e.title&&(t.relationshipLabel=e.title),e.technology&&(t.technology=e.technology),t});s[t]={...om(f),neighbors:p,depth:d};for(let e of p)o.has(e.elementId)||u.push({elementId:e.elementId,depth:d+1})}for(let e of Object.values(s))e.neighbors=e.neighbors.filter(e=>e.elementId in s);return{target:t,totalNodes:o.size,maxDepth:c,truncated:l,nodes:s}}const cm=O({path:k().describe(`Path to the file`),range:O({start:O({line:A(),character:A()}),end:O({line:A(),character:A()})}).describe(`Range in the file`)}).nullable(),lm=k().refine(e=>!0).optional().default(vp.DefaultProjectId).describe(`Project id (optional, will use "default" if not specified)`),um=j(O({id:k().describe(`View id`),title:k().describe(`View title`),type:In([`element`,`deployment`,`dynamic`]).describe(`View type`)})),dm=e=>[...e].map(e=>({id:e.id,title:e.titleOrId,type:e.$view._type})),fm=(e,t)=>n=>{try{let r=e.locate({projectId:t,...n});return r?{path:C.parse(r.uri).fsPath,range:r.range}:null}catch(e){return K.debug(`Failed to locate {params}`,{error:e,params:n}),null}},pm=am.extend({description:k().nullable().describe(`Element description`),technology:k().nullable().describe(`Element technology`),shape:k().describe(`Rendered shape`),color:k().describe(`Rendered color`),children:j(k()).describe(`Direct child element ids`),incomingCount:A().describe(`Number of incoming relationships`),outgoingCount:A().describe(`Number of outgoing relationships`)}),mm=q({name:`batch-read-elements`,description:`
|
|
46
|
-
Read details of multiple elements in a single call, reducing round-trips.
|
|
47
|
-
Returns a compact summary for each element including metadata, description, technology, shape, children, and relationship counts.
|
|
48
|
-
|
|
49
|
-
Request:
|
|
50
|
-
- ids: string[] — array of element ids (FQNs) to read (max 50)
|
|
51
|
-
- project: string (optional) — project id. Defaults to "default" if omitted.
|
|
52
|
-
|
|
53
|
-
Response (JSON object):
|
|
54
|
-
- elements: Array of element details, each with:
|
|
55
|
-
- id: string — element id (FQN)
|
|
56
|
-
- name: string — element name
|
|
57
|
-
- kind: string — element kind
|
|
58
|
-
- title: string — human-readable title
|
|
59
|
-
- description: string|null — optional description
|
|
60
|
-
- technology: string|null — optional technology
|
|
61
|
-
- tags: string[] — assigned tags
|
|
62
|
-
- metadata: Record<string, string | string[]> — element metadata
|
|
63
|
-
- shape: string — rendered shape
|
|
64
|
-
- color: string — rendered color
|
|
65
|
-
- children: string[] — direct child element ids
|
|
66
|
-
- incomingCount: number — number of incoming relationships
|
|
67
|
-
- outgoingCount: number — number of outgoing relationships
|
|
68
|
-
- includedInViews: View[] — views that include this element
|
|
69
|
-
- notFound: string[] — ids that were not found in the project
|
|
70
|
-
|
|
71
|
-
View (object) fields:
|
|
72
|
-
- id: string — view identifier
|
|
73
|
-
- title: string — view title
|
|
74
|
-
- type: "element" | "deployment" | "dynamic"
|
|
75
|
-
|
|
76
|
-
Notes:
|
|
77
|
-
- Read-only, idempotent, no side effects.
|
|
78
|
-
- Safe to call repeatedly.
|
|
79
|
-
- Maximum 50 element ids per call.
|
|
80
|
-
- Elements not found are listed in notFound array (not an error).
|
|
81
|
-
- More efficient than multiple read-element calls when you need summary data for many elements.
|
|
82
|
-
|
|
83
|
-
Example response:
|
|
84
|
-
{
|
|
85
|
-
"elements": [
|
|
86
|
-
{
|
|
87
|
-
"id": "shop.frontend",
|
|
88
|
-
"name": "frontend",
|
|
89
|
-
"kind": "container",
|
|
90
|
-
"title": "Frontend",
|
|
91
|
-
"description": "User-facing web app",
|
|
92
|
-
"technology": "React",
|
|
93
|
-
"tags": ["public"],
|
|
94
|
-
"metadata": { "owner": "web-team" },
|
|
95
|
-
"shape": "browser",
|
|
96
|
-
"color": "#2F80ED",
|
|
97
|
-
"children": ["shop.frontend.auth"],
|
|
98
|
-
"incomingCount": 2,
|
|
99
|
-
"outgoingCount": 3,
|
|
100
|
-
"includedInViews": [
|
|
101
|
-
{ "id": "system-overview", "title": "System Overview", "type": "element" }
|
|
102
|
-
]
|
|
103
|
-
}
|
|
104
|
-
],
|
|
105
|
-
"notFound": []
|
|
106
|
-
}
|
|
107
|
-
`,annotations:{readOnlyHint:!0,idempotentHint:!0,title:`Batch read elements`},inputSchema:{ids:j(k()).min(1).max(50).describe(`Array of element ids (FQNs) to read (max 50)`),project:lm},outputSchema:{elements:j(pm),notFound:j(k()).describe(`Element ids that were not found`)}},async(e,t)=>{N(t.ids.length<=50,`Maximum 50 element ids per call`);let n=e.projectsManager.ensureProjectId(t.project),r=await e.computedModel(n),i=[],a=[];for(let e of t.ids){let t=r.findElement(e);if(!t){a.push(e);continue}i.push({...om(t),description:t.description.text,technology:t.technology,shape:t.shape,color:t.color,children:[...t.children()].map(e=>e.id),incomingCount:t.allIncoming.size,outgoingCount:t.allOutgoing.size})}return{elements:i,notFound:a}}),hm=O({id:k(),kind:k(),title:k(),description:k().nullable(),technology:k().nullable(),shape:k(),color:k()}),gm=O({element1:hm,element2:hm,propertyDiffs:j(O({property:k().describe(`Property name`),element1Value:k().nullable().describe(`Value in element1`),element2Value:k().nullable().describe(`Value in element2`)})).describe(`Properties that differ between the two elements`),tags:O({onlyInElement1:j(k()).describe(`Tags present only in element1`),onlyInElement2:j(k()).describe(`Tags present only in element2`),common:j(k()).describe(`Tags present in both elements`)}),metadata:O({onlyInElement1:Ln(zn([k(),j(k())])).describe(`Metadata keys only in element1`),onlyInElement2:Ln(zn([k(),j(k())])).describe(`Metadata keys only in element2`),different:j(O({key:k(),element1Value:zn([k(),j(k())]),element2Value:zn([k(),j(k())])})).describe(`Metadata keys present in both but with different values`),common:Ln(zn([k(),j(k())])).describe(`Metadata keys with identical values in both`)}),relationships:O({incomingOnlyElement1:A().describe(`Count of unique source elements sending to element1 only`),incomingOnlyElement2:A().describe(`Count of unique source elements sending to element2 only`),incomingShared:A().describe(`Count of unique source elements sending to both`),outgoingOnlyElement1:A().describe(`Count of unique target elements receiving from element1 only`),outgoingOnlyElement2:A().describe(`Count of unique target elements receiving from element2 only`),outgoingShared:A().describe(`Count of unique target elements receiving from both`)})}),_m=q({name:`element-diff`,description:`
|
|
108
|
-
Compare two elements side-by-side, showing differences in properties, tags, metadata, and relationships.
|
|
109
|
-
|
|
110
|
-
Request:
|
|
111
|
-
- element1Id: string — first element id (FQN)
|
|
112
|
-
- element2Id: string — second element id (FQN)
|
|
113
|
-
- project: string (optional) — project id. Defaults to "default" if omitted.
|
|
114
|
-
|
|
115
|
-
Response (JSON object):
|
|
116
|
-
- element1: object — snapshot of first element (id, kind, title, description, technology, shape, color)
|
|
117
|
-
- element2: object — snapshot of second element
|
|
118
|
-
- propertyDiffs: Array of { property, element1Value, element2Value } — properties that differ
|
|
119
|
-
- tags: object
|
|
120
|
-
- onlyInElement1: string[] — tags only in element1
|
|
121
|
-
- onlyInElement2: string[] — tags only in element2
|
|
122
|
-
- common: string[] — tags in both
|
|
123
|
-
- metadata: object
|
|
124
|
-
- onlyInElement1: Record — metadata keys only in element1
|
|
125
|
-
- onlyInElement2: Record — metadata keys only in element2
|
|
126
|
-
- different: Array of { key, element1Value, element2Value } — keys present in both but with different values
|
|
127
|
-
- common: Record — metadata keys with identical values in both
|
|
128
|
-
- relationships: object — relationship count comparison
|
|
129
|
-
- incomingOnlyElement1/incomingOnlyElement2/incomingShared
|
|
130
|
-
- outgoingOnlyElement1/outgoingOnlyElement2/outgoingShared
|
|
131
|
-
|
|
132
|
-
Notes:
|
|
133
|
-
- Read-only, idempotent, no side effects.
|
|
134
|
-
- Safe to call repeatedly.
|
|
135
|
-
- Both elements must exist in the same project.
|
|
136
|
-
- Useful for comparing similar nodes to understand why they have different configurations.
|
|
137
|
-
|
|
138
|
-
Example response:
|
|
139
|
-
{
|
|
140
|
-
"element1": { "id": "planner.nodeA", "kind": "cgf-node", "title": "nodeA", ... },
|
|
141
|
-
"element2": { "id": "planner.nodeB", "kind": "cgf-node", "title": "nodeB", ... },
|
|
142
|
-
"propertyDiffs": [
|
|
143
|
-
{ "property": "title", "element1Value": "nodeA :dwNodeTypeA", "element2Value": "nodeB :dwNodeTypeB" }
|
|
144
|
-
],
|
|
145
|
-
"tags": {
|
|
146
|
-
"onlyInElement1": ["target_asil_qm"],
|
|
147
|
-
"onlyInElement2": ["target_asil_asil_b"],
|
|
148
|
-
"common": ["is_in_dag", "process_camera_master"]
|
|
149
|
-
},
|
|
150
|
-
"metadata": {
|
|
151
|
-
"onlyInElement1": {},
|
|
152
|
-
"onlyInElement2": {},
|
|
153
|
-
"different": [
|
|
154
|
-
{ "key": "target_asil", "element1Value": "QM", "element2Value": "ASIL-B" }
|
|
155
|
-
],
|
|
156
|
-
"common": { "host": "machine0" }
|
|
157
|
-
},
|
|
158
|
-
"relationships": {
|
|
159
|
-
"incomingOnlyElement1": 2,
|
|
160
|
-
"incomingOnlyElement2": 1,
|
|
161
|
-
"incomingShared": 3,
|
|
162
|
-
"outgoingOnlyElement1": 0,
|
|
163
|
-
"outgoingOnlyElement2": 1,
|
|
164
|
-
"outgoingShared": 2
|
|
165
|
-
}
|
|
166
|
-
}
|
|
167
|
-
`,annotations:{readOnlyHint:!0,idempotentHint:!0,title:`Compare two elements`},inputSchema:{element1Id:k().describe(`First element id (FQN)`),element2Id:k().describe(`Second element id (FQN)`),project:lm},outputSchema:gm.shape},async(e,t)=>{let n=e.projectsManager.ensureProjectId(t.project),r=await e.computedModel(n),i=r.findElement(t.element1Id);N(i,`Element "${t.element1Id}" not found in project "${n}"`);let a=r.findElement(t.element2Id);N(a,`Element "${t.element2Id}" not found in project "${n}"`);let o=[],s=[{name:`kind`,get:e=>e.kind},{name:`title`,get:e=>e.title},{name:`description`,get:e=>e.description.text},{name:`technology`,get:e=>e.technology},{name:`shape`,get:e=>e.shape},{name:`color`,get:e=>e.color}];for(let e of s){let t=e.get(i),n=e.get(a);t!==n&&o.push({property:e.name,element1Value:t,element2Value:n})}let c=new Set(i.tags),l=new Set(a.tags),u=[],d=[],f=[];for(let e of c)l.has(e)?u.push(e):d.push(e);for(let e of l)c.has(e)||f.push(e);let p=i.getMetadata(),m=a.getMetadata(),h=new Set([...Object.keys(p),...Object.keys(m)]),g={},_={},ee=[],te={};for(let e of h){let t=p[e],n=m[e];t!==void 0&&n===void 0?g[e]=t:t===void 0&&n!==void 0?_[e]=n:t!==void 0&&n!==void 0&&(JSON.stringify(t)===JSON.stringify(n)?te[e]=t:ee.push({key:e,element1Value:t,element2Value:n}))}let ne=new Set([...i.incoming()].map(e=>e.source.id)),re=new Set([...a.incoming()].map(e=>e.source.id)),ie=new Set([...i.outgoing()].map(e=>e.target.id)),v=new Set([...a.outgoing()].map(e=>e.target.id)),y=0,ae=0,oe=0;for(let e of ne)re.has(e)?y++:ae++;for(let e of re)ne.has(e)||oe++;let se=0,ce=0,le=0;for(let e of ie)v.has(e)?se++:ce++;for(let e of v)ie.has(e)||le++;return{element1:{id:i.id,kind:i.kind,title:i.title,description:i.description.text,technology:i.technology,shape:i.shape,color:i.color},element2:{id:a.id,kind:a.kind,title:a.title,description:a.description.text,technology:a.technology,shape:a.shape,color:a.color},propertyDiffs:o,tags:{onlyInElement1:d,onlyInElement2:f,common:u},metadata:{onlyInElement1:g,onlyInElement2:_,different:ee,common:te},relationships:{incomingOnlyElement1:ae,incomingOnlyElement2:oe,incomingShared:y,outgoingOnlyElement1:ce,outgoingOnlyElement2:le,outgoingShared:se}}}),vm=q({name:`find-relationship-paths`,description:`
|
|
168
|
-
Discover all paths (chains of relationships) between two elements, supporting multi-hop traversal.
|
|
169
|
-
|
|
170
|
-
Request:
|
|
171
|
-
- sourceId: string — source element FQN
|
|
172
|
-
- targetId: string — target element FQN
|
|
173
|
-
- maxDepth: number (optional, default: 3, max: 5) — maximum path length (number of hops)
|
|
174
|
-
- includeIndirect: boolean (optional, default: false) — include indirect (implied) relationships through nested elements
|
|
175
|
-
- project: string (optional) — project id. Defaults to "default" if omitted.
|
|
176
|
-
|
|
177
|
-
Algorithm:
|
|
178
|
-
- Uses breadth-first search (BFS) to find all paths
|
|
179
|
-
- Prevents cycles with visited set per path
|
|
180
|
-
- Paths are sorted by length (shortest first)
|
|
181
|
-
- Limited to 100 paths to avoid overwhelming responses
|
|
182
|
-
|
|
183
|
-
Response (JSON object):
|
|
184
|
-
- paths: Array of path objects, each with:
|
|
185
|
-
- length: number — number of hops in the path
|
|
186
|
-
- steps: Array<Step> — ordered sequence of relationships
|
|
187
|
-
|
|
188
|
-
Step (object) fields:
|
|
189
|
-
- source: string — source element FQN
|
|
190
|
-
- target: string — target element FQN
|
|
191
|
-
- relationship: object
|
|
192
|
-
- kind: string|null — relationship kind
|
|
193
|
-
- title: string|null — relationship title
|
|
194
|
-
- description: string|null — relationship description
|
|
195
|
-
- technology: string|null — relationship technology
|
|
196
|
-
- tags: string[] — relationship tags
|
|
197
|
-
|
|
198
|
-
Notes:
|
|
199
|
-
- Read-only, idempotent, no side effects.
|
|
200
|
-
- Safe to call repeatedly.
|
|
201
|
-
- Returns empty paths array if no paths exist.
|
|
202
|
-
- Rejects if source equals target.
|
|
203
|
-
- includeIndirect=false (default): only follows direct relationships on each element.
|
|
204
|
-
includeIndirect=true: also follows implied relationships through nested elements.
|
|
205
|
-
- maxDepth is capped at 5 to prevent excessive computation.
|
|
206
|
-
- Paths are discovered iteratively and sorted by length.
|
|
207
|
-
|
|
208
|
-
Example response:
|
|
209
|
-
{
|
|
210
|
-
"paths": [
|
|
211
|
-
{
|
|
212
|
-
"length": 1,
|
|
213
|
-
"steps": [
|
|
214
|
-
{
|
|
215
|
-
"source": "shop.frontend",
|
|
216
|
-
"target": "shop.backend",
|
|
217
|
-
"relationship": {
|
|
218
|
-
"kind": "uses",
|
|
219
|
-
"title": "Calls API",
|
|
220
|
-
"description": null,
|
|
221
|
-
"technology": "HTTPS",
|
|
222
|
-
"tags": []
|
|
223
|
-
}
|
|
224
|
-
}
|
|
225
|
-
]
|
|
226
|
-
},
|
|
227
|
-
{
|
|
228
|
-
"length": 2,
|
|
229
|
-
"steps": [
|
|
230
|
-
{
|
|
231
|
-
"source": "shop.frontend",
|
|
232
|
-
"target": "shop.cache",
|
|
233
|
-
"relationship": {
|
|
234
|
-
"kind": "uses",
|
|
235
|
-
"title": "Reads from",
|
|
236
|
-
"description": null,
|
|
237
|
-
"technology": "Redis",
|
|
238
|
-
"tags": []
|
|
239
|
-
}
|
|
240
|
-
},
|
|
241
|
-
{
|
|
242
|
-
"source": "shop.cache",
|
|
243
|
-
"target": "shop.backend",
|
|
244
|
-
"relationship": {
|
|
245
|
-
"kind": "syncs-with",
|
|
246
|
-
"title": "Updates",
|
|
247
|
-
"description": null,
|
|
248
|
-
"technology": null,
|
|
249
|
-
"tags": []
|
|
250
|
-
}
|
|
251
|
-
}
|
|
252
|
-
]
|
|
253
|
-
}
|
|
254
|
-
]
|
|
255
|
-
}
|
|
256
|
-
`,annotations:{readOnlyHint:!0,idempotentHint:!0,title:`Find relationship paths`},inputSchema:{sourceId:k().describe(`Source element FQN`),targetId:k().describe(`Target element FQN`),maxDepth:A().int().min(1).max(5).optional().default(3).describe(`Maximum path length (default: 3, max: 5)`),includeIndirect:Un().optional().default(!1).describe(`Include indirect (implied) relationships through nested elements (default: false)`),project:lm},outputSchema:{paths:j(O({length:A().describe(`Number of hops in the path`),steps:j(O({source:k().describe(`Source element FQN`),target:k().describe(`Target element FQN`),relationship:O({kind:k().nullable().describe(`Relationship kind`),title:k().nullable().describe(`Relationship title`),description:k().nullable().describe(`Relationship description`),technology:k().nullable().describe(`Relationship technology`),tags:j(k()).describe(`Relationship tags`)})})).describe(`Ordered sequence of relationships in the path`)}))}},async(e,t)=>{let n=e.projectsManager.ensureProjectId(t.project),r=await e.computedModel(n),i=r.findElement(t.sourceId);N(i,`Source element "${t.sourceId}" not found in project "${n}"`);let a=r.findElement(t.targetId);N(a,`Target element "${t.targetId}" not found in project "${n}"`),N(i.id!==a.id,`Source and target must be different elements`);let o=t.maxDepth,s=t.includeIndirect?`all`:`direct`,c=[{elementId:i.id,path:[],visited:new Set([i.id])}],l=[];for(;c.length>0&&l.length<100;){let e=c.shift();if(e.path.length>=o)continue;let t=r.findElement(e.elementId);if(t)for(let n of t.outgoing(s)){let t=n.target.id;if(t===a.id){let t={source:n.source.id,target:n.target.id,relationship:{kind:n.kind,title:n.title,description:n.description.text,technology:n.technology,tags:[...n.tags]}};if(l.push({length:e.path.length+1,steps:[...e.path,t]}),l.length>=100)break;continue}if(e.visited.has(t))continue;let r={source:n.source.id,target:n.target.id,relationship:{kind:n.kind,title:n.title,description:n.description.text,technology:n.technology,tags:[...n.tags]}};c.push({elementId:t,path:[...e.path,r],visited:new Set([...e.visited,t])})}}return l.sort((e,t)=>e.length-t.length),{paths:l}}),ym=O({id:k(),title:k(),kind:k()}),bm=O({type:In([`direct`,`indirect`]).describe(`Type of relationship, "direct" for direct relationships, "indirect" for relationships through nested elements`),source:ym,target:ym,kind:k().nullable().describe(`Relationship kind`),title:k().nullable().describe(`Relationship title`),description:k().nullable().describe(`Relationship description`),technology:k().nullable().describe(`Relationship technology`),tags:j(k()).describe(`Relationship tags`),includedInViews:um.describe(`Views that include this relationship`),sourceLocation:cm}),xm=q({name:`find-relationships`,annotations:{readOnlyHint:!0,idempotentHint:!0,title:`Find relationships between two elements`},description:`
|
|
257
|
-
Find relationships between two LikeC4 elements within a project.
|
|
258
|
-
|
|
259
|
-
What it does:
|
|
260
|
-
- Finds both direct relationships (element1 ↔ element2) and indirect ones that arise via containment (e.g. via nested elements).
|
|
261
|
-
- Returns rich metadata for each relationship and where it appears in views.
|
|
262
|
-
|
|
263
|
-
Inputs:
|
|
264
|
-
- element1: string — Element ID (FQN)
|
|
265
|
-
- element2: string — Element ID (FQN)
|
|
266
|
-
- project: string (optional, defaults to "default") — Project id
|
|
267
|
-
|
|
268
|
-
Output:
|
|
269
|
-
- found: Relationship[]
|
|
270
|
-
|
|
271
|
-
Relationship (object) fields:
|
|
272
|
-
- type: "direct" | "indirect" — direct is between the specified endpoints; indirect is via nested elements
|
|
273
|
-
- source: Endpoint
|
|
274
|
-
- target: Endpoint
|
|
275
|
-
- kind: string|null — relationship kind from the model
|
|
276
|
-
- title: string|null — relationship title if provided
|
|
277
|
-
- description: string|null — relationship description text
|
|
278
|
-
- technology: string|null — relationship technology
|
|
279
|
-
- tags: string[] — relationship tags
|
|
280
|
-
- includedInViews: View[] — views where this relationship appears
|
|
281
|
-
- sourceLocation: { path: string, range: { start: { line: number, character: number }, end: { line: number, character: number } } } | null
|
|
282
|
-
|
|
283
|
-
Endpoint (object) fields:
|
|
284
|
-
- id: string — Element ID (FQN)
|
|
285
|
-
- title: string — element title
|
|
286
|
-
- kind: string — element kind
|
|
287
|
-
|
|
288
|
-
View (object) fields:
|
|
289
|
-
- id: string — view identifier
|
|
290
|
-
- title: string — view title
|
|
291
|
-
- type: "element" | "deployment" | "dynamic"
|
|
292
|
-
|
|
293
|
-
Notes:
|
|
294
|
-
- Read-only, idempotent; does not mutate the model. May trigger UI navigation in supporting clients.
|
|
295
|
-
- The order of results is not guaranteed.
|
|
296
|
-
|
|
297
|
-
Example:
|
|
298
|
-
Request:
|
|
299
|
-
{
|
|
300
|
-
"element1": "shop.frontend",
|
|
301
|
-
"element2": "shop.backend",
|
|
302
|
-
"project": "default"
|
|
303
|
-
}
|
|
304
|
-
|
|
305
|
-
Response:
|
|
306
|
-
{
|
|
307
|
-
"found": [
|
|
308
|
-
{
|
|
309
|
-
"type": "direct",
|
|
310
|
-
"source": { "id": "shop.frontend", "title": "Frontend", "kind": "component" },
|
|
311
|
-
"target": { "id": "shop.backend", "title": "Backend", "kind": "component" },
|
|
312
|
-
"kind": "sync",
|
|
313
|
-
"title": "Calls",
|
|
314
|
-
"description": "Frontend calls Backend",
|
|
315
|
-
"technology": "HTTP",
|
|
316
|
-
"tags": ["public"],
|
|
317
|
-
"includedInViews": [
|
|
318
|
-
{ "id": "system-overview", "title": "System Overview", "type": "element" }
|
|
319
|
-
],
|
|
320
|
-
"sourceLocation": {
|
|
321
|
-
"path": "/abs/path/project/model.c4",
|
|
322
|
-
"range": { "start": { "line": 12, "character": 0 }, "end": { "line": 14, "character": 0 } }
|
|
323
|
-
}
|
|
324
|
-
}
|
|
325
|
-
]
|
|
326
|
-
}
|
|
327
|
-
`,inputSchema:{element1:k().describe(`Element ID (FQN)`),element2:k().describe(`Element ID (FQN)`),project:lm},outputSchema:{found:j(bm)}},async(e,t)=>{let n=e.projectsManager.ensureProjectId(t.project);if(Qr(t.element1,t.element2))throw Error(`No relationships possible between parent-child`);let r=[],i=await e.computedModel(n),a=i.findElement(t.element1);I(a,`Element "${t.element1}" not found in project "${n}"`);let o=i.findElement(t.element2);I(o,`Element "${t.element2}" not found in project "${n}"`);let s=fm(e,n),c=Xn.findConnection(a,o,`both`).flatMap(e=>[...e.relations]);for(let e of c){let t=e.source===a&&e.target===o||e.source===o&&e.target===a;r.push({type:t?`direct`:`indirect`,source:{id:e.source.id,title:e.source.title,kind:e.source.kind},target:{id:e.target.id,title:e.target.title,kind:e.target.kind},kind:e.kind,title:e.title,description:e.description.text,technology:e.technology,tags:[...e.tags],includedInViews:dm(e.views()),sourceLocation:s({relation:e.id})})}return{found:r}}),Sm=q({name:`list-projects`,description:`
|
|
328
|
-
List LikeC4 projects discoverable in the current workspace.
|
|
329
|
-
|
|
330
|
-
Request:
|
|
331
|
-
- No input parameters.
|
|
332
|
-
|
|
333
|
-
Response (JSON object):
|
|
334
|
-
- projects: Project[]
|
|
335
|
-
|
|
336
|
-
Project (object) fields:
|
|
337
|
-
- id: string — stable project identifier
|
|
338
|
-
- title: string — human-readable project title
|
|
339
|
-
- folder: string — absolute path to the project root
|
|
340
|
-
- sources: string[] — absolute file paths of related documents
|
|
341
|
-
|
|
342
|
-
Notes:
|
|
343
|
-
- Read-only, idempotent, no side effects.
|
|
344
|
-
- Safe to call repeatedly.
|
|
345
|
-
|
|
346
|
-
Example response:
|
|
347
|
-
{
|
|
348
|
-
"projects": [
|
|
349
|
-
{
|
|
350
|
-
"id": "docs",
|
|
351
|
-
"title": "Documentation",
|
|
352
|
-
"folder": "/abs/path/to/workspace/docs",
|
|
353
|
-
"sources": [
|
|
354
|
-
"/abs/path/to/workspace/docs/model/contexts.likec4",
|
|
355
|
-
"/abs/path/to/workspace/docs/model/relations.likec4"
|
|
356
|
-
]
|
|
357
|
-
}
|
|
358
|
-
]
|
|
359
|
-
}
|
|
360
|
-
`,annotations:{readOnlyHint:!0,idempotentHint:!0,title:`List projects`},outputSchema:{projects:j(O({id:k(),title:k(),folder:k(),sources:j(k())}))}},async e=>({projects:e.projects().map(e=>({id:e.id,title:e.title,folder:e.folder.fsPath,sources:e.documents.map(e=>e.fsPath)}))})),Cm=q({name:`open-view`,description:`
|
|
361
|
-
Open a LikeC4 view in the editor's preview panel.
|
|
362
|
-
|
|
363
|
-
Request:
|
|
364
|
-
- viewId: string — view id (name)
|
|
365
|
-
- project: string (optional) — project id. Defaults to "default" if omitted.
|
|
366
|
-
|
|
367
|
-
Response (JSON object):
|
|
368
|
-
- location: { path: string, range: { start: { line: number, character: number }, end: { line: number, character: number } } } | null — source location of the view if available
|
|
369
|
-
|
|
370
|
-
Notes:
|
|
371
|
-
- Read-only and idempotent with respect to the project model. Triggers a UI action in the editor.
|
|
372
|
-
- Only one preview panel can be open at a time.
|
|
373
|
-
|
|
374
|
-
Example response:
|
|
375
|
-
{
|
|
376
|
-
"location": {
|
|
377
|
-
"path": "/abs/path/project/model.c4",
|
|
378
|
-
"range": { "start": { "line": 10, "character": 0 }, "end": { "line": 30, "character": 0 } }
|
|
379
|
-
}
|
|
380
|
-
}
|
|
381
|
-
`,annotations:{readOnlyHint:!0,idempotentHint:!0,title:`Open view in preview panel`},inputSchema:{viewId:k().describe(`View id (name)`),project:lm},outputSchema:{location:cm}},async(e,t)=>{let n=e.projectsManager.ensureProjectId(t.project),r=(await e.computedModel(n)).findView(t.viewId);if(!r)throw Error(`View with ID '${t.viewId}' not found in project ${n}`);return await e.views.openView(r.id,n),{location:fm(e,n)({view:r.id})}}),wm=In([`exact`,`contains`,`exists`]),Tm=q({name:`query-by-metadata`,description:`
|
|
382
|
-
Search elements and deployment nodes by metadata key-value pairs with flexible matching modes.
|
|
383
|
-
|
|
384
|
-
Request:
|
|
385
|
-
- key: string — metadata key to filter by
|
|
386
|
-
- value: string (optional) — metadata value to match (ignored for 'exists' mode)
|
|
387
|
-
- matchMode: "exact" | "contains" | "exists" (optional, default: "exact")
|
|
388
|
-
- project: string (optional) — project id. Defaults to "default" if omitted.
|
|
389
|
-
|
|
390
|
-
Match Modes:
|
|
391
|
-
- exact: Value must match exactly (case-sensitive)
|
|
392
|
-
Example: key="owner", value="platform-team" matches only exact "platform-team"
|
|
393
|
-
- contains: Value contains the search string (case-insensitive)
|
|
394
|
-
Example: key="technology", value="aws" matches "AWS Lambda", "aws-s3", etc.
|
|
395
|
-
- exists: Element has the key (value parameter is ignored)
|
|
396
|
-
Example: key="owner" returns all elements with any "owner" metadata
|
|
397
|
-
|
|
398
|
-
Response (JSON object):
|
|
399
|
-
- results: Array of matching elements/deployment-nodes, each with:
|
|
400
|
-
- id: string — element/node id (FQN)
|
|
401
|
-
- name: string — element/node name
|
|
402
|
-
- kind: string — element/node kind
|
|
403
|
-
- title: string — human-readable title
|
|
404
|
-
- tags: string[] — assigned tags
|
|
405
|
-
- metadata: Record<string, string | string[]> — all element metadata
|
|
406
|
-
- matchedValue: string — the metadata value that matched (for reference)
|
|
407
|
-
- includedInViews: View[] — views that include this element
|
|
408
|
-
|
|
409
|
-
View (object) fields:
|
|
410
|
-
- id: string — view identifier
|
|
411
|
-
- title: string — view title
|
|
412
|
-
- type: "element" | "deployment" | "dynamic"
|
|
413
|
-
|
|
414
|
-
Notes:
|
|
415
|
-
- Read-only, idempotent, no side effects.
|
|
416
|
-
- Safe to call repeatedly.
|
|
417
|
-
- Handles both string and array metadata values.
|
|
418
|
-
- For array values, matches if any element in the array matches.
|
|
419
|
-
- Returns empty array if no matches found.
|
|
420
|
-
- Limited to 50 results to avoid overwhelming responses.
|
|
421
|
-
- Case-sensitive for exact mode, case-insensitive for contains mode.
|
|
422
|
-
|
|
423
|
-
Example response:
|
|
424
|
-
{
|
|
425
|
-
"results": [
|
|
426
|
-
{
|
|
427
|
-
"id": "shop.frontend",
|
|
428
|
-
"name": "frontend",
|
|
429
|
-
"kind": "container",
|
|
430
|
-
"title": "Frontend",
|
|
431
|
-
"tags": ["public"],
|
|
432
|
-
"metadata": {
|
|
433
|
-
"owner": "platform-team",
|
|
434
|
-
"tier": "critical"
|
|
435
|
-
},
|
|
436
|
-
"matchedValue": "platform-team",
|
|
437
|
-
"includedInViews": [
|
|
438
|
-
{
|
|
439
|
-
"id": "system-overview",
|
|
440
|
-
"title": "System Overview",
|
|
441
|
-
"type": "element"
|
|
442
|
-
}
|
|
443
|
-
]
|
|
444
|
-
}
|
|
445
|
-
]
|
|
446
|
-
}
|
|
447
|
-
`,annotations:{readOnlyHint:!0,idempotentHint:!0,title:`Query by metadata`},inputSchema:{key:k().describe(`Metadata key to filter by`),value:k().optional().describe(`Metadata value to match (ignored for exists mode)`),matchMode:wm.optional().default(`exact`).describe(`Matching mode`),project:lm},outputSchema:{results:j(am.extend({matchedValue:k().describe(`The metadata value that matched`)}))}},async(e,t)=>{let n=e.projectsManager.ensureProjectId(t.project),r=await e.computedModel(n),i=t.matchMode,a=[],o=(e,t,n)=>{let r=Array.isArray(e)?e:[e];switch(n){case`exists`:return!0;case`exact`:return t===void 0?!1:r.some(e=>e===t);case`contains`:{if(t===void 0)return!1;let e=t.toLowerCase();return r.some(t=>t.toLowerCase().includes(e))}default:return!1}},s=(e,t,n)=>{let r=Array.isArray(e)?e:[e];if(n===`exists`||t===void 0)return r[0]||``;if(n===`exact`)return r.find(e=>e===t)||r[0]||``;if(n===`contains`){let e=t.toLowerCase();return r.find(t=>t.toLowerCase().includes(e))||r[0]||``}return r[0]||``};for(let e of r.elements()){if(a.length>=50)break;let n=e.getMetadata();if(t.key in n){let r=n[t.key];r!==void 0&&o(r,t.value,i)&&a.push({...om(e),matchedValue:s(r,t.value,i)})}}if(a.length<50)for(let e of r.deployment.elements()){if(a.length>=50)break;let n=e.getMetadata();if(t.key in n){let r=n[t.key];r!==void 0&&o(r,t.value,i)&&a.push({...om(e),matchedValue:s(r,t.value,i)})}}return{results:a}}),Em=q({name:`query-by-tag-pattern`,description:`
|
|
448
|
-
Search elements by tag patterns using prefix or substring matching.
|
|
449
|
-
Useful for tag taxonomies with structured naming conventions (e.g., "schedule_*", "*_asil_*").
|
|
450
|
-
|
|
451
|
-
Request:
|
|
452
|
-
- pattern: string — tag pattern to match
|
|
453
|
-
- matchMode: "prefix" | "contains" | "suffix" (optional, default: "prefix")
|
|
454
|
-
- prefix: matches tags starting with the pattern (e.g., "target_asil" matches "target_asil_qm", "target_asil_asil_b")
|
|
455
|
-
- contains: matches tags containing the pattern anywhere (e.g., "asil" matches "target_asil_qm", "unit_asil_b")
|
|
456
|
-
- suffix: matches tags ending with the pattern (e.g., "_tbc" matches "target_asil_qm__tbc")
|
|
457
|
-
- project: string (optional) — project id. Defaults to "default" if omitted.
|
|
458
|
-
|
|
459
|
-
Response (JSON object):
|
|
460
|
-
- results: Array of matching elements, each with:
|
|
461
|
-
- id: string — element id (FQN)
|
|
462
|
-
- name: string — element name
|
|
463
|
-
- kind: string — element kind
|
|
464
|
-
- title: string — human-readable title
|
|
465
|
-
- tags: string[] — all assigned tags
|
|
466
|
-
- metadata: Record<string, string | string[]> — element metadata
|
|
467
|
-
- matchedTags: string[] — the specific tags that matched the pattern
|
|
468
|
-
- includedInViews: View[] — views that include this element
|
|
469
|
-
- truncated: boolean — true if results were truncated due to exceeding the 50-result limit
|
|
470
|
-
- matchedTagValues: string[] — all unique tag values that matched the pattern across all elements
|
|
471
|
-
|
|
472
|
-
View (object) fields:
|
|
473
|
-
- id: string — view identifier
|
|
474
|
-
- title: string — view title
|
|
475
|
-
- type: "element" | "deployment" | "dynamic"
|
|
476
|
-
|
|
477
|
-
Notes:
|
|
478
|
-
- Read-only, idempotent, no side effects.
|
|
479
|
-
- Safe to call repeatedly.
|
|
480
|
-
- Pattern matching is case-insensitive.
|
|
481
|
-
- Returns empty array if no matches found.
|
|
482
|
-
- Limited to 50 results.
|
|
483
|
-
- matchedTagValues provides a summary of all distinct matching tag values found.
|
|
484
|
-
|
|
485
|
-
Example response:
|
|
486
|
-
{
|
|
487
|
-
"results": [
|
|
488
|
-
{
|
|
489
|
-
"id": "top.planner.behaviorNode",
|
|
490
|
-
"name": "behaviorNode",
|
|
491
|
-
"kind": "cgf-node",
|
|
492
|
-
"title": "behaviorNode :dwBehaviorPlannerNode",
|
|
493
|
-
"tags": ["is_in_dag", "target_asil_qm", "process_camera_master"],
|
|
494
|
-
"metadata": {},
|
|
495
|
-
"matchedTags": ["target_asil_qm"],
|
|
496
|
-
"includedInViews": []
|
|
497
|
-
}
|
|
498
|
-
],
|
|
499
|
-
"truncated": false,
|
|
500
|
-
"matchedTagValues": ["target_asil_qm", "target_asil_asil_b", "target_asil_qm__tbc"]
|
|
501
|
-
}
|
|
502
|
-
`,annotations:{readOnlyHint:!0,idempotentHint:!0,title:`Query by tag pattern`},inputSchema:{pattern:k().min(1).describe(`Tag pattern to match`),matchMode:In([`prefix`,`contains`,`suffix`]).optional().default(`prefix`).describe(`Pattern matching mode (default: prefix)`),project:lm},outputSchema:{results:j(am.extend({matchedTags:j(k()).describe(`Tags that matched the pattern`)})),truncated:Un().describe(`True if results were truncated`),matchedTagValues:j(k()).describe(`All unique tag values matching the pattern across all elements`)}},async(e,t)=>{let n=e.projectsManager.ensureProjectId(t.project),r=await e.computedModel(n),i=t.pattern.toLowerCase(),a=e=>{let n=e.toLowerCase();switch(t.matchMode){case`prefix`:return n.startsWith(i);case`contains`:return n.includes(i);case`suffix`:return n.endsWith(i)}},o=[],s=!1,c=new Set;for(let e of r.elements()){let t=[...e.tags].filter(a);if(t.length>0){if(t.forEach(e=>c.add(e)),o.length>=50){s=!0;continue}o.push({...om(e),matchedTags:t})}}for(let e of r.deployment.elements()){if(!Yn(e))continue;let t=[...e.tags].filter(a);if(t.length>0){if(t.forEach(e=>c.add(e)),o.length>=50){s=!0;continue}o.push({...om(e),matchedTags:t})}}return{results:o,truncated:s,matchedTagValues:[...c].sort((e,t)=>e.localeCompare(t))}}),Dm=q({name:`query-by-tags`,description:`
|
|
503
|
-
Advanced tag filtering with boolean logic (AND, OR, NOT).
|
|
504
|
-
|
|
505
|
-
Request:
|
|
506
|
-
- allOf: string[] (optional) — element must have ALL these tags (AND logic)
|
|
507
|
-
- anyOf: string[] (optional) — element must have ANY of these tags (OR logic)
|
|
508
|
-
- noneOf: string[] (optional) — element must have NONE of these tags (NOT logic)
|
|
509
|
-
- project: string (optional) — project id. Defaults to "default" if omitted.
|
|
510
|
-
|
|
511
|
-
Boolean Logic:
|
|
512
|
-
- All three conditions are combined with AND logic
|
|
513
|
-
- At least one condition must be specified
|
|
514
|
-
- Tags are case-sensitive
|
|
515
|
-
|
|
516
|
-
Example Queries:
|
|
517
|
-
- Public APIs: {"allOf": ["public", "api"]}
|
|
518
|
-
- Deprecated or legacy: {"anyOf": ["deprecated", "legacy"]}
|
|
519
|
-
- Public but not deprecated: {"allOf": ["public"], "noneOf": ["deprecated"]}
|
|
520
|
-
- Critical services not in migration: {"allOf": ["critical", "service"], "noneOf": ["migration", "deprecated"]}
|
|
521
|
-
|
|
522
|
-
Response (JSON object):
|
|
523
|
-
- results: Array of matching elements/deployment-nodes, each with:
|
|
524
|
-
- id: string — element/node id (FQN)
|
|
525
|
-
- name: string — element/node name
|
|
526
|
-
- kind: string — element/node kind
|
|
527
|
-
- title: string — human-readable title
|
|
528
|
-
- tags: string[] — assigned tags (for reference)
|
|
529
|
-
- metadata: Record<string, string | string[]> — element metadata
|
|
530
|
-
- includedInViews: View[] — views that include this element
|
|
531
|
-
|
|
532
|
-
View (object) fields:
|
|
533
|
-
- id: string — view identifier
|
|
534
|
-
- title: string — view title
|
|
535
|
-
- type: "element" | "deployment" | "dynamic"
|
|
536
|
-
|
|
537
|
-
Notes:
|
|
538
|
-
- Read-only, idempotent, no side effects.
|
|
539
|
-
- Safe to call repeatedly.
|
|
540
|
-
- Returns empty array if no matches found.
|
|
541
|
-
- Limited to 50 results to avoid overwhelming responses.
|
|
542
|
-
- Conflicting conditions (e.g., allOf and noneOf with same tag) will return no results.
|
|
543
|
-
|
|
544
|
-
Example response:
|
|
545
|
-
{
|
|
546
|
-
"results": [
|
|
547
|
-
{
|
|
548
|
-
"id": "shop.api",
|
|
549
|
-
"name": "api",
|
|
550
|
-
"kind": "container",
|
|
551
|
-
"title": "API Gateway",
|
|
552
|
-
"tags": ["public", "api", "critical"],
|
|
553
|
-
"metadata": {
|
|
554
|
-
"owner": "platform-team"
|
|
555
|
-
},
|
|
556
|
-
"includedInViews": [
|
|
557
|
-
{
|
|
558
|
-
"id": "system-overview",
|
|
559
|
-
"title": "System Overview",
|
|
560
|
-
"type": "element"
|
|
561
|
-
}
|
|
562
|
-
]
|
|
563
|
-
}
|
|
564
|
-
]
|
|
565
|
-
}
|
|
566
|
-
`,annotations:{readOnlyHint:!0,idempotentHint:!0,title:`Query by tags`},inputSchema:{allOf:j(k()).optional().describe(`Element must have ALL these tags (AND)`),anyOf:j(k()).optional().describe(`Element must have ANY of these tags (OR)`),noneOf:j(k()).optional().describe(`Element must have NONE of these tags (NOT)`),project:lm},outputSchema:{results:j(am),truncated:Un().describe(`True if results were truncated due to exceeding the 50-result limit`)}},async(e,t)=>{N(t.allOf&&t.allOf.length>0||t.anyOf&&t.anyOf.length>0||t.noneOf&&t.noneOf.length>0,`At least one condition (allOf, anyOf, or noneOf) must be specified with at least one tag`);let n=e.projectsManager.ensureProjectId(t.project),r=await e.computedModel(n),i=[],a=!1,o=e=>{let n=e instanceof Set?e:new Set(e);return!(t.allOf&&t.allOf.length>0&&!t.allOf.every(e=>n.has(e))||t.anyOf&&t.anyOf.length>0&&!t.anyOf.some(e=>n.has(e))||t.noneOf&&t.noneOf.length>0&&t.noneOf.some(e=>n.has(e)))};for(let e of r.elements()){if(i.length>=50){a=!0;break}o(e.tags)&&i.push(om(e))}if(!a)for(let e of r.deployment.elements()){if(i.length>=50){a=!0;break}Yn(e)&&o(e.tags)&&i.push(om(e))}return{results:i,truncated:a}}),Om=In([`ancestors`,`descendants`,`siblings`,`children`,`parent`,`incomers`,`outgoers`]),km=q({name:`query-graph`,description:`
|
|
567
|
-
Query element hierarchy and relationships in the architecture graph.
|
|
568
|
-
|
|
569
|
-
Request:
|
|
570
|
-
- elementId: string — element id (FQN) to query
|
|
571
|
-
- queryType: "ancestors" | "descendants" | "siblings" | "children" | "parent" | "incomers" | "outgoers"
|
|
572
|
-
- includeIndirect: boolean (optional, default: true) — for incomers/outgoers, include indirect relationships (through nested elements)
|
|
573
|
-
- project: string (optional) — project id. Defaults to "default" if omitted.
|
|
574
|
-
|
|
575
|
-
Query Types:
|
|
576
|
-
- ancestors: Returns all parent elements up to the root (hierarchical)
|
|
577
|
-
Example: shop.frontend.auth.service returns [shop.frontend.auth, shop.frontend, shop]
|
|
578
|
-
- descendants: Returns all child elements recursively (hierarchical)
|
|
579
|
-
Example: shop.frontend returns all nested elements like shop.frontend.auth, shop.frontend.auth.service
|
|
580
|
-
- siblings: Returns elements at the same hierarchy level with the same parent
|
|
581
|
-
Example: shop.frontend returns [shop.backend, shop.database] if they're siblings
|
|
582
|
-
- children: Returns direct child elements only (not recursive)
|
|
583
|
-
Example: shop returns [shop.frontend, shop.backend] but not shop.frontend.auth
|
|
584
|
-
- parent: Returns the direct parent element
|
|
585
|
-
Example: shop.frontend.auth returns shop.frontend
|
|
586
|
-
- incomers: Returns elements that have outgoing relationships to this element (single hop, not recursive).
|
|
587
|
-
For recursive upstream traversal, use query-incomers-graph instead.
|
|
588
|
-
includeIndirect=true: Includes relationships to nested children
|
|
589
|
-
Example: Elements that depend on this element
|
|
590
|
-
- outgoers: Returns elements that receive incoming relationships from this element (single hop, not recursive).
|
|
591
|
-
For recursive downstream traversal, use query-outgoers-graph instead.
|
|
592
|
-
includeIndirect=true: Includes relationships from nested children
|
|
593
|
-
Example: Elements this element depends on
|
|
594
|
-
|
|
595
|
-
Response (JSON object):
|
|
596
|
-
- results: Array of elements (max 100), each with:
|
|
597
|
-
- id: string — element id (FQN)
|
|
598
|
-
- name: string — element name
|
|
599
|
-
- kind: string — element kind
|
|
600
|
-
- title: string — human-readable title
|
|
601
|
-
- tags: string[] — assigned tags
|
|
602
|
-
- metadata: Record<string, string> — element metadata
|
|
603
|
-
- includedInViews: View[] — views that include this element
|
|
604
|
-
- truncated: boolean — true if results were truncated due to exceeding maximum limit (100)
|
|
605
|
-
|
|
606
|
-
View (object) fields:
|
|
607
|
-
- id: string — view identifier
|
|
608
|
-
- title: string — view title
|
|
609
|
-
- type: "element" | "deployment" | "dynamic"
|
|
610
|
-
|
|
611
|
-
Notes:
|
|
612
|
-
- Read-only, idempotent, no side effects.
|
|
613
|
-
- Safe to call repeatedly.
|
|
614
|
-
- For parent query on root element, returns empty array.
|
|
615
|
-
- For hierarchical queries (ancestors, descendants, siblings, children), includeIndirect is ignored.
|
|
616
|
-
|
|
617
|
-
Example response:
|
|
618
|
-
{
|
|
619
|
-
"results": [
|
|
620
|
-
{
|
|
621
|
-
"id": "shop.frontend",
|
|
622
|
-
"name": "frontend",
|
|
623
|
-
"kind": "container",
|
|
624
|
-
"title": "Frontend",
|
|
625
|
-
"tags": ["public"],
|
|
626
|
-
"metadata": { "owner": "web-team" },
|
|
627
|
-
"includedInViews": [
|
|
628
|
-
{
|
|
629
|
-
"id": "system-overview",
|
|
630
|
-
"title": "System Overview",
|
|
631
|
-
"type": "element"
|
|
632
|
-
}
|
|
633
|
-
]
|
|
634
|
-
}
|
|
635
|
-
],
|
|
636
|
-
"truncated": false
|
|
637
|
-
}
|
|
638
|
-
`,annotations:{readOnlyHint:!0,idempotentHint:!0,title:`Query element graph`},inputSchema:{elementId:k().describe(`Element id (FQN) to query`),queryType:Om.describe(`Type of graph query`),includeIndirect:Un().optional().default(!0).describe(`For incomers/outgoers: include indirect relationships (default: true)`),project:lm},outputSchema:{results:j(am),truncated:Un().describe(`True if results were truncated due to exceeding maximum limit`)}},async(e,t)=>{let n=e.projectsManager.ensureProjectId(t.project),r=(await e.computedModel(n)).findElement(t.elementId);N(r,`Element "${t.elementId}" not found in project "${n}"`);let i=[],a=!1;switch(t.queryType){case`ancestors`:for(let e of r.ancestors()){if(i.length>=100){a=!0;break}i.push(om(e))}break;case`descendants`:for(let e of r.descendants()){if(i.length>=100){a=!0;break}i.push(om(e))}break;case`siblings`:for(let e of r.siblings()){if(i.length>=100){a=!0;break}i.push(om(e))}break;case`children`:for(let e of r.children()){if(i.length>=100){a=!0;break}i.push(om(e))}break;case`parent`:{let e=r.parent;e&&i.push(om(e));break}case`incomers`:{let e=t.includeIndirect?`all`:`direct`;for(let t of r.incomers(e)){if(i.length>=100){a=!0;break}i.push(om(t))}break}case`outgoers`:{let e=t.includeIndirect?`all`:`direct`;for(let t of r.outgoers(e)){if(i.length>=100){a=!0;break}i.push(om(t))}break}}return{results:i,truncated:a}}),Am=O({elementId:k().describe(`ID of the incoming element`),relationshipLabel:k().optional().describe(`Label on the relationship`),technology:k().optional().describe(`Technology specified on the relationship`)}),jm=q({name:`query-incomers-graph`,description:`
|
|
639
|
-
Query the complete graph of all elements that provide input to the target element (recursive incomers/producers).
|
|
640
|
-
|
|
641
|
-
This tool performs a breadth-first traversal to discover all upstream dependencies - elements that directly or
|
|
642
|
-
indirectly provide input to the target element. It returns the complete subgraph in a single response,
|
|
643
|
-
making it much more efficient than repeated individual queries.
|
|
644
|
-
|
|
645
|
-
Request:
|
|
646
|
-
- elementId: string — target element id (FQN) to start from
|
|
647
|
-
- includeIndirect: boolean (optional, default: true) — include relationships through nested elements
|
|
648
|
-
- maxDepth: number (optional, default: 10, max: 50) — maximum traversal depth to prevent infinite recursion
|
|
649
|
-
- maxNodes: number (optional, default: 200, max: 2000) — maximum number of nodes to return
|
|
650
|
-
- project: string (optional) — project id. Defaults to "default" if omitted.
|
|
651
|
-
|
|
652
|
-
Response Structure:
|
|
653
|
-
{
|
|
654
|
-
"target": "element.id",
|
|
655
|
-
"totalNodes": number,
|
|
656
|
-
"maxDepth": number,
|
|
657
|
-
"truncated": boolean,
|
|
658
|
-
"nodes": {
|
|
659
|
-
"element.id": {
|
|
660
|
-
"id": "element.id",
|
|
661
|
-
"name": "name",
|
|
662
|
-
"kind": "kind",
|
|
663
|
-
"title": "title",
|
|
664
|
-
"tags": ["tag1", "tag2"],
|
|
665
|
-
"metadata": {},
|
|
666
|
-
"includedInViews": [...],
|
|
667
|
-
"incomers": [
|
|
668
|
-
{
|
|
669
|
-
"elementId": "id1",
|
|
670
|
-
"relationshipLabel": "uses",
|
|
671
|
-
"technology": "REST"
|
|
672
|
-
}
|
|
673
|
-
],
|
|
674
|
-
"depth": number
|
|
675
|
-
}
|
|
676
|
-
}
|
|
677
|
-
}
|
|
678
|
-
|
|
679
|
-
Use Cases:
|
|
680
|
-
- Find all producers/dependencies for an element
|
|
681
|
-
- Trace data lineage upstream
|
|
682
|
-
- Identify root causes and dependencies
|
|
683
|
-
- Build complete dependency trees
|
|
684
|
-
- Answer "what feeds into this?" questions
|
|
685
|
-
|
|
686
|
-
Notes:
|
|
687
|
-
- Read-only, idempotent, no side effects
|
|
688
|
-
- Cycle detection prevents infinite loops
|
|
689
|
-
- Result size limited to maxNodes to prevent huge responses
|
|
690
|
-
- If truncated=true, increase maxNodes or reduce maxDepth to get more specific results
|
|
691
|
-
|
|
692
|
-
Example:
|
|
693
|
-
For a database element, this returns all services, APIs, and components that write to it,
|
|
694
|
-
plus all their dependencies, recursively up to maxDepth levels.
|
|
695
|
-
`,annotations:{readOnlyHint:!0,idempotentHint:!0,title:`Query complete incomers graph`},inputSchema:{elementId:k().describe(`Target element id (FQN) to query incomers for`),includeIndirect:Un().optional().default(!0).describe(`Include indirect relationships through nested elements (default: true)`),maxDepth:A().int().positive().max(50).optional().default(10).describe(`Maximum traversal depth (default: 10, max: 50)`),maxNodes:A().int().positive().max(2e3).optional().default(200).describe(`Maximum number of nodes to return (default: 200, max: 2000)`),project:lm},outputSchema:{target:k().describe(`Target element id`),totalNodes:A().describe(`Total number of nodes in the graph`),maxDepth:A().describe(`Maximum depth reached`),truncated:Un().describe(`True if result was truncated due to maxNodes limit`),nodes:Ln(am.extend({incomers:j(Am).describe(`Incoming relationships with details`),depth:A().describe(`Distance from target element (0 = target)`)}))}},async(e,t)=>{let n=e.projectsManager.ensureProjectId(t.project),r=await e.computedModel(n);N(r.findElement(t.elementId),`Element "${t.elementId}" not found in project "${n}"`);let i=t.includeIndirect?`all`:`direct`,a=sm(r,t.elementId,`incoming`,i,t.maxDepth,t.maxNodes),o={};for(let[e,t]of Object.entries(a.nodes)){let{neighbors:n,...r}=t;o[e]={...r,incomers:n}}return{target:a.target,totalNodes:a.totalNodes,maxDepth:a.maxDepth,truncated:a.truncated,nodes:o}}),Mm=O({elementId:k().describe(`ID of the outgoing element`),relationshipLabel:k().optional().describe(`Label on the relationship`),technology:k().optional().describe(`Technology specified on the relationship`)}),Nm=q({name:`query-outgoers-graph`,description:`
|
|
696
|
-
Query the complete graph of all elements that receive output from the target element (recursive outgoers/consumers).
|
|
697
|
-
|
|
698
|
-
This tool performs a breadth-first traversal to discover all downstream dependencies - elements that directly or
|
|
699
|
-
indirectly consume output from the target element. It returns the complete subgraph in a single response,
|
|
700
|
-
making it much more efficient than repeated individual queries.
|
|
701
|
-
|
|
702
|
-
Request:
|
|
703
|
-
- elementId: string — target element id (FQN) to start from
|
|
704
|
-
- includeIndirect: boolean (optional, default: true) — include relationships through nested elements
|
|
705
|
-
- maxDepth: number (optional, default: 10, max: 50) — maximum traversal depth to prevent infinite recursion
|
|
706
|
-
- maxNodes: number (optional, default: 200, max: 2000) — maximum number of nodes to return
|
|
707
|
-
- project: string (optional) — project id. Defaults to "default" if omitted.
|
|
708
|
-
|
|
709
|
-
Response Structure:
|
|
710
|
-
{
|
|
711
|
-
"target": "element.id",
|
|
712
|
-
"totalNodes": number,
|
|
713
|
-
"maxDepth": number,
|
|
714
|
-
"truncated": boolean,
|
|
715
|
-
"nodes": {
|
|
716
|
-
"element.id": {
|
|
717
|
-
"id": "element.id",
|
|
718
|
-
"name": "name",
|
|
719
|
-
"kind": "kind",
|
|
720
|
-
"title": "title",
|
|
721
|
-
"tags": ["tag1", "tag2"],
|
|
722
|
-
"metadata": {},
|
|
723
|
-
"includedInViews": [...],
|
|
724
|
-
"outgoers": [
|
|
725
|
-
{
|
|
726
|
-
"elementId": "id1",
|
|
727
|
-
"relationshipLabel": "sends data to",
|
|
728
|
-
"technology": "Kafka"
|
|
729
|
-
}
|
|
730
|
-
],
|
|
731
|
-
"depth": number
|
|
732
|
-
}
|
|
733
|
-
}
|
|
734
|
-
}
|
|
735
|
-
|
|
736
|
-
Use Cases:
|
|
737
|
-
- Find all consumers/dependents of an element
|
|
738
|
-
- Trace data lineage downstream
|
|
739
|
-
- Assess impact of changes (blast radius)
|
|
740
|
-
- Build complete consumer trees
|
|
741
|
-
- Answer "what depends on this?" questions
|
|
742
|
-
|
|
743
|
-
Notes:
|
|
744
|
-
- Read-only, idempotent, no side effects
|
|
745
|
-
- Cycle detection prevents infinite loops
|
|
746
|
-
- Result size limited to maxNodes to prevent huge responses
|
|
747
|
-
- If truncated=true, increase maxNodes or reduce maxDepth to get more specific results
|
|
748
|
-
|
|
749
|
-
Example:
|
|
750
|
-
For an API service, this returns all clients, services, and systems that consume its output,
|
|
751
|
-
plus all their consumers, recursively up to maxDepth levels.
|
|
752
|
-
`,annotations:{readOnlyHint:!0,idempotentHint:!0,title:`Query complete outgoers graph`},inputSchema:{elementId:k().describe(`Target element id (FQN) to query outgoers for`),includeIndirect:Un().optional().default(!0).describe(`Include indirect relationships through nested elements (default: true)`),maxDepth:A().int().positive().max(50).optional().default(10).describe(`Maximum traversal depth (default: 10, max: 50)`),maxNodes:A().int().positive().max(2e3).optional().default(200).describe(`Maximum number of nodes to return (default: 200, max: 2000)`),project:lm},outputSchema:{target:k().describe(`Target element id`),totalNodes:A().describe(`Total number of nodes in the graph`),maxDepth:A().describe(`Maximum depth reached`),truncated:Un().describe(`True if result was truncated due to maxNodes limit`),nodes:Ln(am.extend({outgoers:j(Mm).describe(`Outgoing relationships with details`),depth:A().describe(`Distance from target element (0 = target)`)}))}},async(e,t)=>{let n=e.projectsManager.ensureProjectId(t.project),r=await e.computedModel(n);N(r.findElement(t.elementId),`Element "${t.elementId}" not found in project "${n}"`);let i=t.includeIndirect?`all`:`direct`,a=sm(r,t.elementId,`outgoing`,i,t.maxDepth,t.maxNodes),o={};for(let[e,t]of Object.entries(a.nodes)){let{neighbors:n,...r}=t;o[e]={...r,outgoers:n}}return{target:a.target,totalNodes:a.totalNodes,maxDepth:a.maxDepth,truncated:a.truncated,nodes:o}}),Pm=q({name:`read-deployment`,description:`
|
|
753
|
-
Read details about a deployment node or a deployed instance in a LikeC4 project.
|
|
754
|
-
|
|
755
|
-
What it does:
|
|
756
|
-
- Returns metadata about a deployment entity (node or instance), including kind, tags, color/shape, children, which views include it, and its source location.
|
|
757
|
-
|
|
758
|
-
Inputs:
|
|
759
|
-
- id: string — Deployment id (FQN)
|
|
760
|
-
- project: string (optional, defaults to "default") — Project id
|
|
761
|
-
|
|
762
|
-
Output fields:
|
|
763
|
-
- type: "deployment-node" | "deployed-instance"
|
|
764
|
-
- id: string — Deployment id (FQN)
|
|
765
|
-
- kind: string — Deployment node kind, or element kind for deployed instances
|
|
766
|
-
- name: string — Name of the deployment entity
|
|
767
|
-
- title: string — Title of the deployment entity
|
|
768
|
-
- description: string|null — Description text
|
|
769
|
-
- technology: string|null — Technology info, if any
|
|
770
|
-
- tags: string[] — Tags assigned to this entity
|
|
771
|
-
- project: string — Project id
|
|
772
|
-
- metadata: Record<string, string>
|
|
773
|
-
- links: Array<{ title: string|null, url: string, relative: string|null }> — external links associated with this deployment entity
|
|
774
|
-
- shape: string — Rendered shape
|
|
775
|
-
- color: string — Rendered color
|
|
776
|
-
- children: string[] — Child deployment ids (empty for instances)
|
|
777
|
-
- includedInViews: View[] — Views that include this entity
|
|
778
|
-
- instanceof: { id: string, title: string, kind: string } | null — If type is "deployed-instance", the referenced element
|
|
779
|
-
- sourceLocation: { path: string, range: { start: { line: number, character: number }, end: { line: number, character: number } } } | null
|
|
780
|
-
|
|
781
|
-
View (object) fields:
|
|
782
|
-
- id: string — view identifier
|
|
783
|
-
- title: string — view title
|
|
784
|
-
- type: "element" | "deployment" | "dynamic"
|
|
785
|
-
|
|
786
|
-
Notes:
|
|
787
|
-
- Read-only, idempotent; does not mutate the model.
|
|
788
|
-
|
|
789
|
-
Example request:
|
|
790
|
-
{ "id": "k8s.cluster.frontend", "project": "default" }
|
|
791
|
-
|
|
792
|
-
Example response (deployed instance):
|
|
793
|
-
{
|
|
794
|
-
"type": "deployed-instance",
|
|
795
|
-
"id": "k8s.cluster.frontend",
|
|
796
|
-
"kind": "k8s.pod",
|
|
797
|
-
"name": "frontend",
|
|
798
|
-
"title": "Frontend Pod",
|
|
799
|
-
"description": null,
|
|
800
|
-
"technology": "Kubernetes",
|
|
801
|
-
"tags": ["prod"],
|
|
802
|
-
"project": "default",
|
|
803
|
-
"metadata": {},
|
|
804
|
-
"links": [],
|
|
805
|
-
"shape": "rectangle",
|
|
806
|
-
"color": "#2F80ED",
|
|
807
|
-
"children": [],
|
|
808
|
-
"includedInViews": [
|
|
809
|
-
{ "id": "runtime-overview", "title": "Runtime Overview", "type": "deployment" }
|
|
810
|
-
],
|
|
811
|
-
"instanceof": { "id": "shop.frontend", "title": "Frontend", "kind": "component" },
|
|
812
|
-
"sourceLocation": {
|
|
813
|
-
"path": "/abs/path/project/model.c4",
|
|
814
|
-
"range": { "start": { "line": 10, "character": 0 }, "end": { "line": 25, "character": 0 } }
|
|
815
|
-
}
|
|
816
|
-
}
|
|
817
|
-
`,annotations:{readOnlyHint:!0,idempotentHint:!0,title:`Read deployment entity`},inputSchema:{id:k().describe(`Deployment id (FQN)`),project:lm},outputSchema:{type:In([`deployment-node`,`deployed-instance`]),id:k().describe(`Deployment id (FQN)`),kind:k().describe(`Deployment node kind, or element kind for deployed instances`),name:k(),title:k(),description:k().nullable(),technology:k().nullable(),tags:j(k()),project:k(),metadata:Ln(zn([k(),j(k())])),links:j(O({title:k().nullable().describe(`Optional link title`),url:k().describe(`Link URL`),relative:k().nullable().describe(`Relative path (if URL is relative to workspace root)`)})).describe(`External links associated with this deployment entity`),shape:k(),color:k(),children:j(k()).describe(`Children of this deployment node (Array of Deployment ids)`),includedInViews:um.describe(`Views that include this deployment node`),instanceof:O({id:k().describe(`Element ID (FQN)`),title:k(),kind:k()}).nullable().describe(`If type is "deployed-instance", the referenced element`),sourceLocation:cm}},async(e,t)=>{let n=e.projectsManager.ensureProjectId(t.project),r=(await e.computedModel(n)).deployment.findElement(t.id);N(r,`Deployment entity "${t.id}" not found in project "${n}"`);let i=fm(e,n);return{type:r.isInstance()?`deployed-instance`:`deployment-node`,id:r.id,name:r.name,kind:r.kind,title:r.title,description:r.description.text,technology:r.technology,tags:[...r.tags],project:n,metadata:r.getMetadata(),links:(r.links??[]).map(e=>({title:e.title??null,url:e.url,relative:e.relative??null})),shape:r.shape,color:r.color,children:r.isInstance()?[]:[...r.children()].map(e=>e.id),includedInViews:dm(r.views()),instanceof:r.isInstance()?{id:r.element.id,title:r.element.title,kind:r.element.kind}:null,sourceLocation:i({deployment:r.id})}}),Fm=q({name:`read-element`,description:`
|
|
818
|
-
Read detailed information about a LikeC4 element.
|
|
819
|
-
|
|
820
|
-
Request:
|
|
821
|
-
- id: string — element id (FQN)
|
|
822
|
-
- project: string (optional) — project id. Defaults to "default" if omitted.
|
|
823
|
-
|
|
824
|
-
Response (JSON object):
|
|
825
|
-
- id: string — element id (FQN)
|
|
826
|
-
- name: string — element name
|
|
827
|
-
- kind: string — element kind
|
|
828
|
-
- title: string — human-readable title
|
|
829
|
-
- description: string|null — optional description
|
|
830
|
-
- technology: string|null — optional technology
|
|
831
|
-
- tags: string[] — assigned tags
|
|
832
|
-
- project: string — project id this element belongs to
|
|
833
|
-
- metadata: Record<string, string> — element metadata
|
|
834
|
-
- links: Array<{ title: string|null, url: string, relative: string|null }> — external links associated with this element
|
|
835
|
-
- shape: string — rendered shape
|
|
836
|
-
- color: string — rendered color
|
|
837
|
-
- children: string[] — ids (FQNs) of direct child elements
|
|
838
|
-
- defaultView: string|null — default view name if set
|
|
839
|
-
- includedInViews: View[] — views that include this element
|
|
840
|
-
- relationships: object — relationships of this element (direct and indirect)
|
|
841
|
-
- incoming: Array<{ source: { id: string, title: string, kind: string }, kind: string|null, target: string, title: string|null, description: string|null, technology: string|null, tags: string[] }>
|
|
842
|
-
- outgoing: Array<{ source: string, target: { id: string, title: string, kind: string }, kind: string|null, title: string|null, description: string|null, technology: string|null, tags: string[] }>
|
|
843
|
-
- deployedInstances: string[] — deployed instance ids (Deployment FQNs)
|
|
844
|
-
- sourceLocation: { path: string, range: { start: { line: number, character: number }, end: { line: number, character: number } } } | null — source location if available
|
|
845
|
-
|
|
846
|
-
View (object) fields:
|
|
847
|
-
- id: string — view identifier
|
|
848
|
-
- title: string — view title
|
|
849
|
-
- type: "element" | "deployment" | "dynamic"
|
|
850
|
-
|
|
851
|
-
Notes:
|
|
852
|
-
- Read-only, idempotent, no side effects.
|
|
853
|
-
- Safe to call repeatedly.
|
|
854
|
-
|
|
855
|
-
Example response:
|
|
856
|
-
{
|
|
857
|
-
"id": "shop.frontend",
|
|
858
|
-
"name": "frontend",
|
|
859
|
-
"kind": "container",
|
|
860
|
-
"title": "Frontend",
|
|
861
|
-
"description": "User-facing web app",
|
|
862
|
-
"technology": "React",
|
|
863
|
-
"tags": ["public"],
|
|
864
|
-
"project": "default",
|
|
865
|
-
"metadata": { "owner": "web" },
|
|
866
|
-
"links": [
|
|
867
|
-
{
|
|
868
|
-
"title": "Documentation",
|
|
869
|
-
"url": "https://docs.example.com/frontend",
|
|
870
|
-
"relative": null
|
|
871
|
-
}
|
|
872
|
-
],
|
|
873
|
-
"shape": "rounded-rectangle",
|
|
874
|
-
"color": "#2F80ED",
|
|
875
|
-
"children": ["shop.frontend.auth"],
|
|
876
|
-
"defaultView": "frontend-overview",
|
|
877
|
-
"includedInViews": [
|
|
878
|
-
{
|
|
879
|
-
"id": "frontend-overview",
|
|
880
|
-
"title": "Frontend Overview",
|
|
881
|
-
"type": "element"
|
|
882
|
-
}
|
|
883
|
-
],
|
|
884
|
-
"relationships": {
|
|
885
|
-
"incoming": [
|
|
886
|
-
{
|
|
887
|
-
"source": { "id": "shop.api", "title": "API", "kind": "container" },
|
|
888
|
-
"kind": "uses",
|
|
889
|
-
"target": "shop.frontend",
|
|
890
|
-
"title": "Calls",
|
|
891
|
-
"description": null,
|
|
892
|
-
"technology": "HTTPS",
|
|
893
|
-
"tags": []
|
|
894
|
-
}
|
|
895
|
-
],
|
|
896
|
-
"outgoing": []
|
|
897
|
-
},
|
|
898
|
-
"deployedInstances": ["k8s.cluster.frontend"],
|
|
899
|
-
"sourceLocation": {
|
|
900
|
-
"path": "/abs/path/project/model.c4",
|
|
901
|
-
"range": { "start": { "line": 10, "character": 0 }, "end": { "line": 25, "character": 0 } }
|
|
902
|
-
}
|
|
903
|
-
}
|
|
904
|
-
`,annotations:{readOnlyHint:!0,idempotentHint:!0,title:`Read element`},inputSchema:{id:k().describe(`Element id (FQN)`),project:lm},outputSchema:{id:k().describe(`Element id (FQN)`),kind:k().describe(`Element kind`),name:k().describe(`Element name`),title:k(),description:k().nullable(),technology:k().nullable(),tags:j(k()),project:k(),metadata:Ln(zn([k(),j(k())])),links:j(O({title:k().nullable().describe(`Optional link title`),url:k().describe(`Link URL`),relative:k().nullable().describe(`Relative path (if URL is relative to workspace root)`)})).describe(`External links associated with this element`),shape:k(),color:k(),children:j(k()).describe(`Children of this element (Array of FQNs)`),defaultView:k().nullable().describe(`Name of the default view of this element`),includedInViews:um.describe(`Views that include this element`),relationships:O({incoming:j(O({source:O({id:k(),title:k(),kind:k()}).describe(`Source element of this relationship`),kind:k().nullable().describe(`Relationship kind`),target:k().describe(`Target element id (FQN), either this element or nested element, if relationship is indirect`),title:k().nullable().describe(`Relationship title`),description:k().nullable().describe(`Relationship description`),technology:k().nullable().describe(`Relationship technology`),tags:j(k()).describe(`Relationship tags`)})).describe(`Incoming relationships of this element (direct and indirect, incoming to nested elements)`),outgoing:j(O({source:k().describe(`Source element id (FQN), either this element or nested element, if relationship is indirect`),target:O({id:k(),title:k(),kind:k()}).describe(`Target element of this relationship`),kind:k().nullable().describe(`Relationship kind`),title:k().nullable().describe(`Relationship title`),description:k().nullable().describe(`Relationship description`),technology:k().nullable().describe(`Relationship technology`),tags:j(k()).describe(`Relationship tags`)})).describe(`Outgoing relationships of this element (direct and indirect, outgoing from nested elements)`)}).describe(`Relationships of this element`),deployedInstances:j(k()).describe(`Deployed instances of this element (Array of Deployment FQNs)`),sourceLocation:cm}},async(e,t)=>{let n=e.projectsManager.ensureProjectId(t.project),r=(await e.computedModel(n)).findElement(t.id);N(r,`Element "${t.id}" not found in project "${n}"`);let i=fm(e,n);return{id:r.id,name:r.name,kind:r.kind,title:r.title,description:r.description.text,technology:r.technology,tags:[...r.tags],project:n,metadata:r.getMetadata(),links:(r.links??[]).map(e=>({title:e.title??null,url:e.url,relative:e.relative??null})),shape:r.shape,color:r.color,children:[...r.children()].map(e=>e.id),defaultView:r.defaultView?.id||null,includedInViews:dm(r.views()),relationships:{incoming:[...r.incoming()].map(e=>({source:{id:e.source.id,title:e.source.title,kind:e.source.kind},kind:e.kind,target:e.target.id,title:e.title,description:e.description.text,technology:e.technology,tags:[...e.tags]})),outgoing:[...r.outgoing()].map(e=>({source:e.source.id,target:{id:e.target.id,title:e.target.title,kind:e.target.kind},kind:e.kind,title:e.title,description:e.description.text,technology:e.technology,tags:[...e.tags]}))},deployedInstances:[...r.deployments()].map(e=>e.id),sourceLocation:i({element:r.id})}}),Im=q({name:`read-project-summary`,annotations:{readOnlyHint:!0,idempotentHint:!0,title:`Read project summary`},description:`
|
|
905
|
-
Request:
|
|
906
|
-
- project: string (optional) — project id. Defaults to "default" if omitted.
|
|
907
|
-
|
|
908
|
-
Response (JSON object):
|
|
909
|
-
- title: string — human-readable project title
|
|
910
|
-
- folder: string — absolute path to the project root
|
|
911
|
-
- sources: string[] — absolute file paths of model documents
|
|
912
|
-
- config: object — project configuration
|
|
913
|
-
- name: string — project identifier
|
|
914
|
-
- title?: string — human-readable title
|
|
915
|
-
- contactPerson?: string — maintainer contact
|
|
916
|
-
- metadata?: object — custom project metadata as key-value pairs
|
|
917
|
-
- extends?: string | string[] — style inheritance paths
|
|
918
|
-
- exclude?: string[] — file exclusion patterns
|
|
919
|
-
- include?: object — include configuration (paths, maxDepth, fileThreshold)
|
|
920
|
-
- manualLayouts?: object — manual layouts config (outDir)
|
|
921
|
-
- styles?: object — simplified styles (hasTheme, hasDefaults, hasCustomCss)
|
|
922
|
-
- specification: object
|
|
923
|
-
- elementKinds: string[] — all element kinds
|
|
924
|
-
- relationshipKinds: string[] — all relationship kinds
|
|
925
|
-
- deploymentKinds: string[] — all deployment kinds
|
|
926
|
-
- tags: string[] — all tags
|
|
927
|
-
- metadataKeys: string[] — used metadata keys
|
|
928
|
-
- elements: Element[] — list of elements
|
|
929
|
-
- deployments: Deployment[] — list of deployment entities
|
|
930
|
-
- views: View[] — list of views defined in the model
|
|
931
|
-
|
|
932
|
-
Element (object) fields:
|
|
933
|
-
- id: string — element id (FQN)
|
|
934
|
-
- kind: string — element kind
|
|
935
|
-
- title: string — element title
|
|
936
|
-
- tags: string[] — element tags
|
|
937
|
-
|
|
938
|
-
Deployment (object) fields:
|
|
939
|
-
- type = "deployment-node": { id: string, kind: string, title: string, tags: string[] }
|
|
940
|
-
- type = "deployed-instance": { id: string, title: string, tags: string[], referencedElementId: string }
|
|
941
|
-
|
|
942
|
-
View (object) fields:
|
|
943
|
-
- id: string — view identifier
|
|
944
|
-
- title: string — view title
|
|
945
|
-
- type: "element" | "deployment" | "dynamic"
|
|
946
|
-
|
|
947
|
-
Notes:
|
|
948
|
-
- Read-only, idempotent, no side effects.
|
|
949
|
-
- Safe to call repeatedly.
|
|
950
|
-
|
|
951
|
-
Example response:
|
|
952
|
-
{
|
|
953
|
-
"title": "Cloud Boutique",
|
|
954
|
-
"folder": "/abs/path/to/workspace/examples/cloud-system",
|
|
955
|
-
"sources": [
|
|
956
|
-
"/abs/path/to/workspace/examples/cloud-system/model.c4"
|
|
957
|
-
],
|
|
958
|
-
"config": {
|
|
959
|
-
"name": "cloud-boutique",
|
|
960
|
-
"title": "Cloud Boutique",
|
|
961
|
-
"contactPerson": "admin@example.com"
|
|
962
|
-
},
|
|
963
|
-
"specification": {
|
|
964
|
-
"elementKinds": ["system", "container", "component"],
|
|
965
|
-
"relationshipKinds": ["uses", "depends-on"],
|
|
966
|
-
"deploymentKinds": ["node", "cluster"],
|
|
967
|
-
"tags": ["public", "internal"],
|
|
968
|
-
"metadataKeys": ["owner", "tier"]
|
|
969
|
-
},
|
|
970
|
-
"elements": [
|
|
971
|
-
{
|
|
972
|
-
"id": "shop.frontend",
|
|
973
|
-
"kind": "component",
|
|
974
|
-
"title": "Frontend",
|
|
975
|
-
"tags": ["public"]
|
|
976
|
-
}
|
|
977
|
-
],
|
|
978
|
-
"deployments": [
|
|
979
|
-
{
|
|
980
|
-
"type": "deployment-node",
|
|
981
|
-
"id": "k8s.shop.frontend",
|
|
982
|
-
"kind": "cluster",
|
|
983
|
-
"title": "Frontend",
|
|
984
|
-
"tags": []
|
|
985
|
-
}
|
|
986
|
-
],
|
|
987
|
-
"views": [
|
|
988
|
-
{
|
|
989
|
-
"id": "system-overview",
|
|
990
|
-
"title": "System Overview",
|
|
991
|
-
"type": "element"
|
|
992
|
-
}
|
|
993
|
-
]
|
|
994
|
-
}
|
|
995
|
-
`,inputSchema:{project:lm},outputSchema:{title:k(),folder:k(),sources:j(k()),config:rm.describe(`Project configuration`),specification:O({elementKinds:j(k()),relationshipKinds:j(k()),deploymentKinds:j(k()),tags:j(k()),metadataKeys:j(k())}),elements:j(O({id:k(),kind:k(),title:k(),tags:j(k())})).describe(`List of elements in the project`),deployments:j(Rn(`type`,[O({type:Hn(`deployment-node`),id:k().describe(`Node ID`),kind:k().describe(`Deployment node kind`),title:k().describe(`Node title`),tags:j(k())}),O({type:Hn(`deployed-instance`),id:k().describe(`Node ID`),title:k().describe(`Node title`),tags:j(k()),referencedElementId:k().describe(`Element ID (FQN)`)})])).describe(`List of deployment nodes and deployed instances in the project`),views:j(O({id:k(),title:k(),type:In([`element`,`deployment`,`dynamic`])}))}},async(e,t)=>{let n=e.projectsManager.ensureProjectId(t.project),r=e.project(n),i=await e.computedModel(n);return{title:r.title,folder:r.folder.fsPath,sources:r.documents?.map(e=>e.fsPath)??[],config:im(r.config),specification:{elementKinds:Ae(i.specification.elements),relationshipKinds:Ae(i.specification.relationships),deploymentKinds:Ae(i.specification.deployments),tags:[...i.tags],metadataKeys:i.specification.metadataKeys??[]},elements:[...i.elements()].filter(e=>!e.imported).map(e=>({id:e.id,kind:e.kind,title:e.title,tags:[...e.tags]})),deployments:[...i.deployment.elements()].map(e=>e.isInstance()?{type:`deployed-instance`,id:e.id,title:e.title,tags:[...e.tags],referencedElementId:e.element.id}:{type:`deployment-node`,id:e.id,kind:e.kind,title:e.title,tags:[...e.tags]}),views:[...i.views()].map(e=>({id:e.id,title:e.titleOrId,type:e.$view._type}))}}),Lm=e=>e.hasElement()?e.element.id:e.hasDeployment()?e.deployment.id:null,Rm=Rn(`type`,[O({type:Hn(`element`),id:k().describe(`Node ID`),elementId:k().describe(`Element ID (FQN)`),kind:k().describe(`Element kind`),title:k().describe(`Node title`),description:k().nullable(),technology:k().nullable(),children:j(k()).describe(`Children nodes, array of node IDs`),shape:k().describe(`Rendered shape`),color:k().describe(`Rendered color`),tags:j(k())}),O({type:Hn(`deployment-node`),id:k().describe(`Node ID`),deploymentId:k().describe(`Deployment entity ID (FQN)`),kind:k().describe(`Deployment kind`),title:k().describe(`Node title`),description:k().nullable(),technology:k().nullable(),children:j(k()).describe(`Children nodes, array of node IDs`),shape:k().describe(`Rendered shape`),color:k().describe(`Rendered color`),tags:j(k())}),O({type:Hn(`deployed-instance`),id:k().describe(`Node ID`),deploymentId:k().describe(`Deployment entity ID (FQN)`),title:k().describe(`Node title`),description:k().nullable(),technology:k().nullable(),referencedElement:O({id:k().describe(`Element ID (FQN)`),kind:k().describe(`Element kind`),title:k().describe(`Element title`)}),shape:k().describe(`Rendered shape`),color:k().describe(`Rendered color`),tags:j(k())})]),zm=q({name:`read-view`,description:`
|
|
996
|
-
Read detailed information about a LikeC4 view.
|
|
997
|
-
|
|
998
|
-
Request:
|
|
999
|
-
- viewId: string — view id (name)
|
|
1000
|
-
- project: string (optional) — project id. Defaults to "default" if omitted.
|
|
1001
|
-
|
|
1002
|
-
Response (JSON object):
|
|
1003
|
-
- id: string — view id
|
|
1004
|
-
- type: "element" | "deployment" | "dynamic" — view type
|
|
1005
|
-
- title: string — view title (falls back to id if not set)
|
|
1006
|
-
- description: string|null — optional description
|
|
1007
|
-
- tags: string[] — view tags
|
|
1008
|
-
- project: string — project id this view belongs to
|
|
1009
|
-
- nodes: Node[] — nodes included in the view
|
|
1010
|
-
- edges: Edge[] — relationships between nodes
|
|
1011
|
-
- sourceLocation: { path: string, range: { start: { line: number, character: number }, end: { line: number, character: number } } } | null — source location if available
|
|
1012
|
-
|
|
1013
|
-
Node (discriminated union by "type"):
|
|
1014
|
-
- type = "element": { id: string, elementId: string, kind: string, title: string, description: string|null, technology: string|null, children: string[], shape: string, color: string, tags: string[] }
|
|
1015
|
-
- type = "deployment-node": { id: string, deploymentId: string, kind: string, title: string, description: string|null, technology: string|null, children: string[], shape: string, color: string, tags: string[] }
|
|
1016
|
-
- type = "deployed-instance": { id: string, deploymentId: string, title: string, description: string|null, technology: string|null, referencedElement: { id: string, kind: string, title: string }, shape: string, color: string, tags: string[] }
|
|
1017
|
-
|
|
1018
|
-
Edge object:
|
|
1019
|
-
- { source: string, target: string, label: string|null, description: string|null, technology: string|null, tags: string[] }
|
|
1020
|
-
|
|
1021
|
-
Notes:
|
|
1022
|
-
- Read-only, idempotent, no side effects.
|
|
1023
|
-
|
|
1024
|
-
Example response:
|
|
1025
|
-
{
|
|
1026
|
-
"id": "system-overview",
|
|
1027
|
-
"type": "element",
|
|
1028
|
-
"title": "System Overview",
|
|
1029
|
-
"description": null,
|
|
1030
|
-
"tags": [],
|
|
1031
|
-
"project": "default",
|
|
1032
|
-
"nodes": [
|
|
1033
|
-
{ "type": "logical", "id": "n1", "elementId": "shop.frontend", "kind": "container", "title": "Frontend", "description": null, "technology": "React", "children": [], "shape": "rounded-rectangle", "color": "#2F80ED", "tags": [] }
|
|
1034
|
-
],
|
|
1035
|
-
"edges": [
|
|
1036
|
-
{ "source": "n1", "target": "n2", "label": "calls", "description": null, "technology": "HTTPS", "tags": [] }
|
|
1037
|
-
],
|
|
1038
|
-
"sourceLocation": {
|
|
1039
|
-
"path": "/abs/path/project/model.c4",
|
|
1040
|
-
"range": { "start": { "line": 10, "character": 0 }, "end": { "line": 30, "character": 0 } }
|
|
1041
|
-
}
|
|
1042
|
-
}
|
|
1043
|
-
`,annotations:{readOnlyHint:!0,idempotentHint:!0,title:`Read view`},inputSchema:{viewId:k().describe(`View id (name)`),project:lm},outputSchema:{id:k(),type:In([`element`,`deployment`,`dynamic`]).describe(`View type`),title:k(),description:k().nullable(),tags:j(k()),project:k(),nodes:j(Rm),edges:j(O({source:k().describe(`Source node`),target:k().describe(`Target node`),label:k().nullable(),description:k().nullable(),technology:k().nullable(),tags:j(k())})).describe(`Edge represents relationship between nodes`),sourceLocation:cm}},async(e,t)=>{let n=e.projectsManager.ensureProjectId(t.project),r=e.project(n),i=(await e.computedModel(n)).findView(t.viewId);if(!i)throw Error(`View with ID '${t.viewId}' not found in project ${r.id}`);let a=fm(e,r.id);return{id:i.id,type:i.$view._type,title:i.title??i.id,description:i.description.text,tags:[...i.tags],project:r.id,nodes:[...i.nodes()].flatMap(e=>{let t={id:e.id,title:e.title,description:e.description.text,technology:e.technology,shape:e.shape,color:e.color,tags:[...e.tags]};return e.hasDeployedInstance()?{...t,type:`deployed-instance`,deploymentId:e.deployment.id,referencedElement:{id:e.deployment.element.id,kind:e.deployment.element.kind,title:e.deployment.element.title}}:e.hasDeployment()?{...t,type:`deployment-node`,kind:e.deployment.kind,deploymentId:e.deployment.id,children:[...e.children()].map(e=>e.id)}:e.hasElement()?{...t,type:`element`,elementId:e.element.id,kind:e.element.kind,children:[...e.children()].flatMap(e=>Lm(e)??[])}:[]}),edges:[...i.edges()].map(e=>({source:e.source.id,target:e.target.id,label:e.label,description:e.description.text,technology:e.technology,tags:[...e.tags]})),sourceLocation:a({view:i.id})}}),Bm=j(Rn(`type`,[O({type:Hn(`element`),project:k().describe(`Project ID`),id:k().describe(`Element ID (FQN)`),name:k().describe(`Element name`),kind:k(),title:k(),technology:k().nullable(),shape:k(),includedInViews:um,metadata:Ln(zn([k(),j(k())])),tags:j(k())}),O({type:Hn(`deployment-node`),project:k().describe(`Project ID`),id:k().describe(`Deployment ID (FQN)`),name:k().describe(`Deployment name`),kind:k(),title:k(),technology:k().nullable(),shape:k(),includedInViews:um,metadata:Ln(zn([k(),j(k())])),tags:j(k())})])),Vm=q({name:`search-element`,annotations:{readOnlyHint:!0,idempotentHint:!0,title:`Search elements`},description:`
|
|
1044
|
-
Search LikeC4 elements and deployment nodes across all projects.
|
|
1045
|
-
|
|
1046
|
-
Query syntax (case-insensitive):
|
|
1047
|
-
- kind:<value> filters by kind
|
|
1048
|
-
- shape:<value> filters by shape
|
|
1049
|
-
- meta:<key> filters by having metadata with the given key
|
|
1050
|
-
- #<value> matches assigned tags
|
|
1051
|
-
- <value> matches id (FQN) or title
|
|
1052
|
-
|
|
1053
|
-
Request:
|
|
1054
|
-
- search: string — at least 2 characters
|
|
1055
|
-
|
|
1056
|
-
Response (JSON object):
|
|
1057
|
-
- total: number - total number of results
|
|
1058
|
-
- found: Result[] - returns top 20 results
|
|
1059
|
-
|
|
1060
|
-
Result (discriminated union by "type"):
|
|
1061
|
-
- type = "element": { id: string, name: string, kind: string, title: string, technology: string|null, shape: string, project: string, includedInViews: View[], tags: string[], metadata: Record<string, string> }
|
|
1062
|
-
- type = "deployment-node": { id: string, name: string, kind: string, title: string, technology: string|null, shape: string, project: string, includedInViews: View[], tags: string[], metadata: Record<string, string> }
|
|
1063
|
-
|
|
1064
|
-
View (object) fields:
|
|
1065
|
-
- id: string — view identifier
|
|
1066
|
-
- title: string — view title
|
|
1067
|
-
- type: "element" | "deployment" | "dynamic"
|
|
1068
|
-
|
|
1069
|
-
Notes:
|
|
1070
|
-
- Read-only, idempotent.
|
|
1071
|
-
- Use results as input to other tools (e.g., read-element, read-view).
|
|
1072
|
-
|
|
1073
|
-
Example response:
|
|
1074
|
-
{
|
|
1075
|
-
"total": 1,
|
|
1076
|
-
"found": [
|
|
1077
|
-
{
|
|
1078
|
-
"type": "logical",
|
|
1079
|
-
"project": "default",
|
|
1080
|
-
"id": "shop.frontend",
|
|
1081
|
-
"name": "frontend",
|
|
1082
|
-
"kind": "container",
|
|
1083
|
-
"title": "Frontend",
|
|
1084
|
-
"technology": "React",
|
|
1085
|
-
"shape": "rectangle",
|
|
1086
|
-
"includedInViews": [
|
|
1087
|
-
{
|
|
1088
|
-
"id": "system-overview",
|
|
1089
|
-
"title": "System Overview",
|
|
1090
|
-
"type": "element"
|
|
1091
|
-
}
|
|
1092
|
-
],
|
|
1093
|
-
"tags": ["public"],
|
|
1094
|
-
"metadata": {}
|
|
1095
|
-
}
|
|
1096
|
-
]
|
|
1097
|
-
}
|
|
1098
|
-
`,inputSchema:{search:k().min(2,`Search must be at least 2 characters long`)},outputSchema:{total:A(),found:Bm}},async(e,t)=>{let n=e.projects(),r=[],i=t.search.toLowerCase(),a;i.startsWith(`kind:`)?(i=i.slice(5),K.debug(`search by kind: {search}`,{search:i}),a=e=>e.kind.toLowerCase()===i):i.startsWith(`shape:`)?(i=i.slice(6),K.debug(`search by shape: {search}`,{search:i}),a=e=>e.shape.toLowerCase()===i):i.startsWith(`meta:`)?(i=i.slice(5),K.debug(`search by metadata: {search}`,{search:i}),a=e=>!!e.getMetadata(i)):i.startsWith(`#`)?(i=i.slice(1),K.debug(`search by tag: {search}`,{search:i}),a=e=>e.tags.some(e=>e.toLowerCase().includes(i))):(K.debug(`search by id/title: {search}`,{search:i}),a=e=>e.id.toLowerCase().includes(i)||e.title.toLowerCase().includes(i));for(let t of n)try{let n=await e.computedModel(t.id);for(let e of Xr(n.elements(),e=>!e.imported&&a(e)))r.push({type:`element`,project:t.id,id:e.id,name:e.name,kind:e.kind,title:e.title,technology:e.technology,shape:e.shape,tags:[...e.tags],metadata:e.getMetadata(),includedInViews:dm(e.views())});for(let e of Xr(n.deployment.nodes(),a))r.push({type:`deployment-node`,project:t.id,id:e.id,name:e.name,kind:e.kind,title:e.title,technology:e.technology,shape:e.shape,tags:[...e.tags],metadata:e.getMetadata(),includedInViews:dm(e.views())})}catch(e){K.error(`Error searching in project ${t.id}:`,{error:e})}return{total:r.length,found:r.slice(0,20)}}),Hm=O({id:k().describe(`Element id (FQN)`),name:k().describe(`Element name`),kind:k().describe(`Element kind`),title:k().describe(`Human-readable title`),depth:A().describe(`Depth relative to the root element (1 = direct child)`),tags:j(k()).describe(`Assigned tags`),metadata:Ln(zn([k(),j(k())])).describe(`Element metadata`),childCount:A().describe(`Number of direct children`),incomingCount:A().describe(`Number of incoming relationships`),outgoingCount:A().describe(`Number of outgoing relationships`)}),Um=q({name:`subgraph-summary`,description:`
|
|
1099
|
-
Get a compact, table-friendly summary of all descendants of a parent element.
|
|
1100
|
-
Returns each descendant with its depth, metadata, tags, and relationship counts in a single call.
|
|
1101
|
-
Much more efficient than calling read-element for each descendant individually.
|
|
1102
|
-
|
|
1103
|
-
Request:
|
|
1104
|
-
- elementId: string — parent element id (FQN) whose descendants to summarize
|
|
1105
|
-
- maxDepth: number (optional, default: 10, max: 20) — maximum depth of descendants to include
|
|
1106
|
-
- metadataKeys: string[] (optional) — if provided, only include these metadata keys in the response (reduces response size)
|
|
1107
|
-
- project: string (optional) — project id. Defaults to "default" if omitted.
|
|
1108
|
-
|
|
1109
|
-
Response (JSON object):
|
|
1110
|
-
- root: object — the root element summary
|
|
1111
|
-
- id: string — element id
|
|
1112
|
-
- kind: string — element kind
|
|
1113
|
-
- title: string — element title
|
|
1114
|
-
- childCount: number — number of direct children
|
|
1115
|
-
- descendants: Array of descendant summaries, each with:
|
|
1116
|
-
- id: string — element id (FQN)
|
|
1117
|
-
- name: string — element name
|
|
1118
|
-
- kind: string — element kind
|
|
1119
|
-
- title: string — human-readable title
|
|
1120
|
-
- depth: number — depth relative to root (1 = direct child)
|
|
1121
|
-
- tags: string[] — assigned tags
|
|
1122
|
-
- metadata: Record<string, string | string[]> — element metadata (filtered by metadataKeys if provided)
|
|
1123
|
-
- childCount: number — number of direct children
|
|
1124
|
-
- incomingCount: number — number of incoming relationships
|
|
1125
|
-
- outgoingCount: number — number of outgoing relationships
|
|
1126
|
-
- totalDescendants: number — total number of descendants (may differ from array length if truncated)
|
|
1127
|
-
- truncated: boolean — true if results were truncated due to exceeding the 200-result limit
|
|
1128
|
-
- truncatedByDepth: boolean — true if deeper descendants exist beyond maxDepth
|
|
1129
|
-
|
|
1130
|
-
Notes:
|
|
1131
|
-
- Read-only, idempotent, no side effects.
|
|
1132
|
-
- Safe to call repeatedly.
|
|
1133
|
-
- Limited to 200 descendants in the response.
|
|
1134
|
-
- Use metadataKeys to reduce response size when you only need specific metadata.
|
|
1135
|
-
- Descendants are returned in breadth-first order (closest to root first).
|
|
1136
|
-
- depth=1 means direct child, depth=2 means grandchild, etc.
|
|
1137
|
-
|
|
1138
|
-
Example response:
|
|
1139
|
-
{
|
|
1140
|
-
"root": {
|
|
1141
|
-
"id": "top.planner",
|
|
1142
|
-
"kind": "subsystem",
|
|
1143
|
-
"title": "Planner Subsystem",
|
|
1144
|
-
"childCount": 5
|
|
1145
|
-
},
|
|
1146
|
-
"descendants": [
|
|
1147
|
-
{
|
|
1148
|
-
"id": "top.planner.nodeA",
|
|
1149
|
-
"name": "nodeA",
|
|
1150
|
-
"kind": "cgf-node",
|
|
1151
|
-
"title": "nodeA :dwNodeTypeA",
|
|
1152
|
-
"depth": 1,
|
|
1153
|
-
"tags": ["is_in_dag", "target_asil_qm"],
|
|
1154
|
-
"metadata": { "target_asil": "QM", "safety_info_unit_asil": "QM" },
|
|
1155
|
-
"childCount": 0,
|
|
1156
|
-
"incomingCount": 3,
|
|
1157
|
-
"outgoingCount": 2
|
|
1158
|
-
}
|
|
1159
|
-
],
|
|
1160
|
-
"totalDescendants": 5,
|
|
1161
|
-
"truncated": false,
|
|
1162
|
-
"truncatedByDepth": false
|
|
1163
|
-
}
|
|
1164
|
-
`,annotations:{readOnlyHint:!0,idempotentHint:!0,title:`Subgraph summary`},inputSchema:{elementId:k().describe(`Parent element id (FQN) whose descendants to summarize`),maxDepth:A().int().min(1).max(20).optional().default(10).describe(`Maximum depth of descendants to include (default: 10, max: 20)`),metadataKeys:j(k()).optional().describe(`If provided, only include these metadata keys in the response`),project:lm},outputSchema:{root:O({id:k(),kind:k(),title:k(),childCount:A()}),descendants:j(Hm),totalDescendants:A().describe(`Total number of descendants found`),truncated:Un().describe(`True if results were truncated due to exceeding the limit`),truncatedByDepth:Un().describe(`True if deeper descendants exist beyond maxDepth`)}},async(e,t)=>{let n=e.projectsManager.ensureProjectId(t.project),r=(await e.computedModel(n)).findElement(t.elementId);N(r,`Element "${t.elementId}" not found in project "${n}"`);let i=t.maxDepth,a=t.metadataKeys,o=[],s=0,c=!1,l=!1,u=[],d=[...r.children()];for(let e of d)u.push({element:e,depth:1});for(;u.length>0;){let{element:e,depth:t}=u.shift();if(t>i){l=!0;continue}s++;let n=[...e.children()];if(o.length<200){let r=e.getMetadata(),i=a?Object.fromEntries(a.filter(e=>e in r).map(e=>[e,r[e]])):r;o.push({id:e.id,name:e.name,kind:e.kind,title:e.title,depth:t,tags:[...e.tags],metadata:i,childCount:n.length,incomingCount:[...e.incoming()].length,outgoingCount:[...e.outgoing()].length})}else c=!0;for(let e of n)u.push({element:e,depth:t+1})}return{root:{id:r.id,kind:r.kind,title:r.title,childCount:d.length},descendants:o,totalDescendants:s,truncated:c,truncatedByDepth:l}});var Wm=class{constructor(e){this.services=e}create(e){let t=this.services.shared.lsp.Connection!==void 0,n=new Bn({name:`LikeC4`,version:nm},{instructions:`LikeC4 MCP – query and navigate LikeC4 models.
|
|
1165
|
-
|
|
1166
|
-
Conventions:
|
|
1167
|
-
- All tools are read-only and idempotent.
|
|
1168
|
-
- "project" is optional and defaults to "default".
|
|
1169
|
-
|
|
1170
|
-
Available tools:
|
|
1171
|
-
- list-projects — List all LikeC4 projects in the workspace.
|
|
1172
|
-
- read-project-summary — Project specification, configuration, all elements, deployment nodes and views. Input: { project? }.
|
|
1173
|
-
- search-element — Search elements and deployment nodes across all projects by id/title/kind/shape/tags/metadata. Input: { search }.
|
|
1174
|
-
- read-element — Full element details including relationships, includedInViews, deployedInstances, metadata and sourceLocation. Input: { id, project? }.
|
|
1175
|
-
- read-deployment — Details of a deployment node or deployed instance. Input: { id, project? }.
|
|
1176
|
-
- read-view — Full view details (nodes/edges) and sourceLocation. Input: { viewId, project? }.
|
|
1177
|
-
- find-relationships — Direct and indirect relationships between two elements in a project. Input: { element1, element2, project? }.
|
|
1178
|
-
- query-graph — Query element hierarchy (ancestors, descendants, siblings, children, parent) and relationships (incomers, outgoers). Input: { elementId, queryType, includeIndirect?, project? }.
|
|
1179
|
-
- query-incomers-graph — Get complete graph of all upstream dependencies/producers (recursive incomers). Much more efficient than repeated query-graph calls. Input: { elementId, includeIndirect?, maxDepth?, maxNodes?, project? }.
|
|
1180
|
-
- query-outgoers-graph — Get complete graph of all downstream consumers/dependents (recursive outgoers). Much more efficient than repeated query-graph calls. Input: { elementId, includeIndirect?, maxDepth?, maxNodes?, project? }.
|
|
1181
|
-
- query-by-metadata — Search elements by metadata key-value pairs with exact/contains/exists matching. Input: { key, value?, matchMode?, project? }.
|
|
1182
|
-
- query-by-tags — Advanced tag filtering with boolean logic (allOf, anyOf, noneOf). Input: { allOf?, anyOf?, noneOf?, project? }.
|
|
1183
|
-
- find-relationship-paths — Discover all paths (chains of relationships) between two elements with BFS traversal. Input: { sourceId, targetId, maxDepth?, includeIndirect?, project? }.
|
|
1184
|
-
- batch-read-elements — Read details of multiple elements in a single call, reducing round-trips. Input: { ids, project? }.
|
|
1185
|
-
- query-by-tag-pattern — Search elements by tag prefix/contains/suffix patterns. Input: { pattern, matchMode?, project? }.
|
|
1186
|
-
- element-diff — Compare two elements side-by-side showing differences in properties, tags, metadata, and relationships. Input: { element1Id, element2Id, project? }.
|
|
1187
|
-
- subgraph-summary — Compact summary of all descendants of a parent element with metadata, tags, and relationship counts. Input: { elementId, maxDepth?, metadataKeys?, project? }.
|
|
1188
|
-
${t?`- open-view — Opens the LikeC4 view panel in the editor. Triggers UI; at most one preview panel at a time. Input: { viewId, project? }.`:``}
|
|
1189
|
-
|
|
1190
|
-
Instructions:
|
|
1191
|
-
- Identify the project first
|
|
1192
|
-
- Use "search-element" to find elements by id/title/kind/shape/tags/metadata and select the project
|
|
1193
|
-
- Use "read-project-summary" to find all elements and deployment nodes inside the project, what kinds, tags, metadata keys are available
|
|
1194
|
-
- Use "list-projects" to list all available projects
|
|
1195
|
-
- If response returns "sourceLocation", provide link to this location in the editor
|
|
1196
|
-
|
|
1197
|
-
Full documentation: https://likec4.dev/llms-full.txt
|
|
1198
|
-
`,enforceStrictCapabilities:!0,...e,capabilities:{tools:{},logging:{},...e?.capabilities}});return n.registerTool(...Sm(this.services.likec4.LanguageServices)),n.registerTool(...Im(this.services.likec4.LanguageServices)),n.registerTool(...Fm(this.services.likec4.LanguageServices)),n.registerTool(...Pm(this.services.likec4.LanguageServices)),n.registerTool(...zm(this.services.likec4.LanguageServices)),n.registerTool(...Vm(this.services.likec4.LanguageServices)),n.registerTool(...xm(this.services.likec4.LanguageServices)),n.registerTool(...km(this.services.likec4.LanguageServices)),n.registerTool(...jm(this.services.likec4.LanguageServices)),n.registerTool(...Nm(this.services.likec4.LanguageServices)),n.registerTool(...Tm(this.services.likec4.LanguageServices)),n.registerTool(...Dm(this.services.likec4.LanguageServices)),n.registerTool(...vm(this.services.likec4.LanguageServices)),n.registerTool(...mm(this.services.likec4.LanguageServices)),n.registerTool(...Em(this.services.likec4.LanguageServices)),n.registerTool(..._m(this.services.likec4.LanguageServices)),n.registerTool(...Um(this.services.likec4.LanguageServices)),t&&n.registerTool(...Cm(this.services.likec4.LanguageServices)),n.server.onerror=e=>{B.error(L(e))},n}},Gm=class{transport=void 0;_mcp=void 0;constructor(e){this.services=e}get mcp(){if(!this._mcp)throw Error(`MCP server is not started`);return this._mcp}get isStarted(){return this.transport!==void 0}get port(){return NaN}async dispose(){await this.stop()}async start(){this.transport||(K.info(`Starting MCP stdio server`),this._mcp=this.services.mcp.ServerFactory.create(),this.transport=new Vn,await this._mcp.connect(this.transport),K.info(`LikeC4 MCP Server running on stdio`))}async stop(){if(this.transport)try{K.info(`Stopping MCP stdio server`),await this.transport.close(),this._mcp&&await this._mcp.close()}finally{this._mcp=void 0,this.transport=void 0}}};async function Km(e){let t=new Ge;t.use(`*`,qe({origin:`*`,allowHeaders:[`Content-Type`,`mcp-session-id`,`Last-Event-ID`,`mcp-protocol-version`],exposeHeaders:[`mcp-session-id`,`mcp-protocol-version`]})),t.get(`/health`,e=>e.json({status:`ok`}));let n=e.create(),r=new Ke({eventStore:new Je({})});return t.all(`/mcp`,async e=>(n.isConnected()||await n.connect(r),await r.handleRequest(e))),t.notFound(e=>(K.debug(`${e.req.method} ${e.req.url} not found`),e.json({jsonrpc:`2.0`,error:{code:-32e3,message:`Method not found.`},id:null},{status:404}))),t.onError((e,t)=>(K.error(L(e)),t.json({jsonrpc:`2.0`,error:{code:-32603,message:`Internal server error`},id:null},{status:500}))),t}async function qm(e){let{factory:t,port:n}=e,r=await Km(t);return new Promise((e,t)=>{let i=Wn({fetch:r.fetch,hostname:`0.0.0.0`,port:n}).prependOnceListener(`error`,t).prependOnceListener(`listening`,()=>{i.removeListener(`error`,t),e(i.unref())})})}var Jm=class{server=void 0;constructor(e,t=33335){this.services=e,this._port=t}get mcp(){throw Error(`StreamableLikeC4MCPServer has access to McpServer only during the request`)}get isStarted(){return this.server?.listening===!0}get port(){return this._port}async dispose(){await this.stop()}async start(e=this._port){if(this.server){if(this.port===e)return;await this.stop()}K.info(`Starting MCP server on port {port}`,{port:e}),this._port=e,this.server=await qm({factory:this.services.mcp.ServerFactory,port:e}),K.info(`MCP server ready at http://0.0.0.0:{port}/mcp`,{port:e})}stop(){let e=this.server;return e?(K.info(`Stopping MCP server`),this.server=void 0,new Promise(t=>{e.close(e=>{e?K.error(`Failed to stop MCP server`,{err:e}):K.info(`MCP server stopped`),t()})})):(K.info(`MCP server is not running, nothing to stop`),Promise.resolve())}};function Ym(e,t=33335){K.debug(`Creating StreamableLikeC4MCPServer`);let n=new Jm(e,t),r=e.LanguageMetaData.languageId,i=e.shared.lsp.Connection;return e.shared.workspace.ConfigurationProvider.onConfigurationSectionUpdate(e=>{if(e.section!==r){K.warn(`Unexpected configuration update: {update}`,{update:e});return}let{enabled:a=!1,port:o=t}=e.configuration.mcp;if(!a){n.stop();return}Promise.resolve().then(()=>n.start(o)).then(()=>{i?.telemetry?.logEvent({eventName:`mcp-server-started`,mcpPort:o})}).catch(e=>{let t=L(e);i?.telemetry?.logEvent({eventName:`mcp-server-start-failed`,mcpPort:o,message:t}),K.warn(`Failed to start LikeC4 MCP Server: \n${t}`),i&&i.window.showErrorMessage(`LikeC4: Failed to start MCP Server\n\n${t}`)})}),n}function Xm(e){return new Gm(e)}function Zm(e=`sse`){return{mcpServer:t=>e===`stdio`?Xm(t):Ym(t,typeof e==`object`?e.port:33335),mcpServerFactory:e=>new Wm(e)}}var Qm=class extends _t{parser;locator;constructor(e){super(e),this.parser=e.likec4.ModelParser,this.locator=e.likec4.ModelLocator}getDocumentation(e){if(!Ws(e)&&!Bs(e)&&!H(e))return super.getDocumentation(e);try{let t=rn(e);if(t.state<S.Linked)return super.getDocumentation(e);let n=this.parser.forDocument(t);switch(!0){case Ws(e):{let t=n.parseDeploymentNode(e);return t?`**${t.title}**`:void 0}case Bs(e):{let r=n.parseDeployedInstance(e);if(!r)return;let[i,a]=M.isImportRef(r.element)?[r.element.project,r.element.model]:[t.likec4ProjectId,r.element.model],o=i?this.locator.getParsedElement(a,i):this.locator.getParsedElement(a),s=[`_instance of_ \`${a}\``];return o&&s.push(`**${o.element.title}**`),s.join(`
|
|
1199
|
-
`)}case H(e):{let t=n.parseElement(e);return t?[`**${t.title}**`,`<small>kind: \`${t.kind}\`</small>`].join(`
|
|
1200
|
-
`):void 0}default:return e}}catch(e){V(e)}}};function $m(e,t){return[e,t]=eh(e,t)>0?[t,e]:[e,t],th(e.range,t.range.start)}function eh(e,t){let n=e.range.start.line-t.range.start.line;return n===0?e.range.start.character-t.range.start.character:n}function th(e,t){return!(t.line<e.start.line||t.line>e.end.line||t.line==e.start.line&&t.character<e.start.character||t.line==e.end.line&&t.character>e.end.character)}function nh(e){return!!e&&e.range.start.line!=e.range.end.line}const J={newLine:Ot.newLine({allowMore:!0}),oneSpace:Ot.oneSpace(),noSpace:Ot.noSpace(),indent:Ot.indent({allowMore:!0}),noIndent:Ot.noIndent()};var rh=class extends $t{options={quoteStyle:`auto`};extendedFormattingCommands=[];constructor(e){super(),e.shared.workspace.ConfigurationProvider.onConfigurationSectionUpdate(e=>this.onConfigurationUpdate(e.configuration.formatting))}doDocumentFormat(e,t,n){this.extendedFormattingCommands=[];let r=super.doDocumentFormat(e,t,n);return this.doExtendedFormatting(r),r}format(e){this.removeIndentFromTopLevelStatements(e),this.indentContentInBraces(e),this.normalizeQuotes(e),this.formatImports(e),this.formatSpecificationRule(e),this.formatGlobals(e),this.formatElementDeclaration(e),this.formatExtendElement(e),this.formatRelation(e),this.formatMetadataProperty(e),this.formatDeploymentNodeDeclaration(e),this.formatDeployedInstance(e),this.formatDeploymentRelation(e),this.formatExtendDeployment(e),this.formatView(e),this.formatViewRuleGroup(e),this.formatViewRuleGlobalStyle(e),this.formatViewRuleGlobalPredicate(e),this.formatIncludeExcludeExpressions(e),this.formatWhereExpression(e),this.formatWhereRelationExpression(e),this.formatWhereElementExpression(e),this.formatRelationExpression(e),this.formatAutolayoutProperty(e),this.formatWithPredicate(e),this.formatViewRuleStyle(e),this.formatLeafProperty(e),this.formatLinkProperty(e),this.formatNavigateToProperty(e),this.formatTags(e)}formatTags(e){this.on(e,yd,(e,t)=>{let n=Jt(e.$cstNode,`values`).filter(i).slice(1);t.cst(n).prepend(J.oneSpace),t.keywords(`,`).prepend(J.noSpace).append(J.oneSpace)})}formatDeploymentRelation(e){this.on(e,Xs,(e,t)=>{let n=e?.source?.$cstNode?[e?.source?.$cstNode]:[];t.cst(n).append(J.oneSpace),t.keywords(`]->`).prepend(J.noSpace),t.keywords(`-[`).append(J.noSpace),t.nodes(...b([e.target,e.tags],i)).prepend(J.oneSpace),t.properties(`title`,`description`,`technology`).prepend(J.oneSpace)})}formatExtendDeployment(e){this.on(e,Gc,(e,t)=>{t.keywords(`extend`).append(J.oneSpace)})}formatRelation(e){this.on(e,e=>Eu(e)||Xs(e),(e,t)=>{let n=e?.source?.$cstNode?[e?.source?.$cstNode]:[];t.cst(n).append(J.oneSpace),t.keywords(`]->`).prepend(J.noSpace),t.keywords(`-[`).append(J.noSpace),t.nodes(...b([e.target,e.tags],i)).prepend(J.oneSpace),t.properties(`title`,`description`,`technology`).prepend(J.oneSpace)}),this.on(e,wo,(e,t)=>{t.keywords(`->`,`<-`).surround(J.oneSpace),t.property(`dotKind`).prepend(J.oneSpace).append(J.oneSpace),t.keywords(`]->`).prepend(J.noSpace).append(J.oneSpace),t.keywords(`-[`).prepend(J.oneSpace).append(J.noSpace),t.properties(`title`).prepend(J.oneSpace),(pf(e)&&nh(e.$cstNode)||hf(e)&&pf(e.$container)&&nh(e.$container.$cstNode))&&(t.property(`dotKind`).prepend(Ot.indent({allowLess:!1,allowMore:!0,priority:2})),t.keywords(`->`,`-[`).prepend(Ot.indent({allowLess:!1,allowMore:!0,priority:2})),e.custom?.$cstNode&&nh(e.custom.$cstNode)&&t.property(`custom`).prepend({options:{allowLess:!1,allowMore:!0,priority:2},moves:[{tabs:1}]}))})}removeIndentFromTopLevelStatements(e){Wl(e.$container)&&this.getNodeFormatter(e).keywords(`specification`,`model`,`views`,`likec4lib`,`global`,`deployments`,`import`).prepend(J.noIndent)}indentContentInBraces(e){if(Kl(e)||cd(e)||ed(e)||id(e)||Qu(e)||_l(e)||yl(e)||xl(e)||hl(e)||pl(e)||xl(e)||ou(e)||wc(e)||Zc(e)||Ou(e)||Hu(e)||iu(e)||uu(e)||Bc(e)||fc(e)||nc(e)||Id(e)||Ad(e)||Is(e)||Rs(e)||Pc(e)||bc(e)||cu(e)||Ks(e)||Qs(e)||Hs(e)||qc(e)){let t=this.getNodeFormatter(e),n=t.keywords(`{`);n.prepend(J.noIndent).prepend(J.oneSpace);let r=nh(e.$cstNode),i=t.keywords(`}`),a=t.interior(n,i),o=null;for(let e of a.nodes){if(!r){t.cst([e]).surround(J.oneSpace);continue}(!o||!$m(o,e))&&t.cst([e]).prepend(Ot.newLine({allowMore:!0})).prepend(J.indent),o=e}r?i.prepend(J.noIndent).prepend(Ot.newLine({allowMore:!0})):i.prepend(Ot.oneSpace({allowLess:!0}))}}appendKeywordsWithSpace(e){this.on(e,Ec)?.keywords(`element`).append(J.oneSpace)}formatView(e){this.on(e,Rc,(e,t)=>{(e.extends||e.viewOf||e.name)&&t.keywords(`view`).append(J.oneSpace),t.keywords(`of`,`extends`).surround(J.oneSpace)}),this.on(e,uc)?.keywords(`dynamic`,`view`).append(J.oneSpace),this.on(e,ec)?.keywords(`deployment`,`view`).append(J.oneSpace)}formatLeafProperty(e){if(Mc(e)||Bu(e)||Rd(e)||gu(e)||vu(e)||nd(e)||od(e)||Ns(e)||Jl(e)||ks(e)||Al(e)||Ku(e)||js(e)||bu(e)||fu(e)||El(e)||Ml(e)||Ol(e)||Ju(e)||wu(e)||xd(e)){let t=this.getNodeFormatter(e),n=t.keyword(`:`),r=t.keywords(`title`,`description`,`technology`,`summary`,`notation`,`notes`,`color`,`line`,`head`,`tail`,`icon`,`iconColor`,`iconSize`,`iconPosition`,`shape`,`border`,`opacity`,`multiple`,`size`,`padding`,`textSize`);n.nodes.length===0?r.append(J.oneSpace):n.prepend(J.noSpace).append(J.oneSpace),t.keyword(`;`).prepend(J.noSpace).append(J.newLine)}}formatLinkProperty(e){this.on(e,Xl,(e,t)=>{t.keyword(`link`).append(J.oneSpace),t.property(`value`).append(J.oneSpace),t.keyword(`:`).prepend(J.noSpace).append(J.oneSpace),t.keyword(`;`).prepend(J.noSpace).append(J.newLine)})}formatNavigateToProperty(e){this.on(e,mu)?.property(`key`).append(J.oneSpace)}formatAutolayoutProperty(e){this.on(e,wd,(e,t)=>{t.keyword(`autoLayout`).append(J.oneSpace),t.property(`rankSep`).prepend(J.oneSpace),t.property(`nodeSep`).prepend(J.oneSpace)})}formatMetadataProperty(e){this.on(e,nu,(e,t)=>{t.property(`key`).append(J.oneSpace),t.keyword(`:`).prepend(J.noSpace).append(J.oneSpace),t.keyword(`;`).prepend(J.noSpace).append(J.newLine)})}formatElementDeclaration(e){this.on(e,H,(e,t)=>{let n=Tt(e.$cstNode,`kind`),r=Tt(e.$cstNode,`name`);r&&n&&(eh(r,n)>0?t.cst([n]).append(J.oneSpace):(t.cst([r]).append(J.oneSpace),t.cst([n]).prepend(J.oneSpace))),t.properties(`props`).prepend(J.oneSpace)})}formatExtendElement(e){this.on(e,Yc,(e,t)=>{t.keywords(`extend`).append(J.oneSpace)})}formatGlobals(e){this.on(e,yl,(e,t)=>{t.keyword(`style`).append(J.oneSpace),t.property(`id`).append(J.oneSpace)}),this.on(e,xl,(e,t)=>{t.keyword(`styleGroup`).append(J.oneSpace)}),this.on(e,hl,(e,t)=>{t.keyword(`predicateGroup`).append(J.oneSpace)}),this.on(e,pl,(e,t)=>{t.keyword(`dynamicPredicateGroup`).append(J.oneSpace)})}formatImports(e){this.on(e,Il,(e,t)=>{t.keyword(`import`).append(J.oneSpace),t.keywords(`{`,`}`,`from`).surround(J.oneSpace)}),this.on(e,Pl,(e,t)=>{t.keywords(`,`).prepend(J.noSpace).append(J.oneSpace)})}formatSpecificationRule(e){if((ed(e)||id(e)||ud(e)||Qu(e))&&this.getNodeFormatter(e).keywords(`element`,`relationship`,`tag`,`deploymentNode`).append(J.oneSpace),Xu(e)){let t=this.getNodeFormatter(e);t.keyword(`color`).append(J.oneSpace),t.property(`name`).append(J.oneSpace)}}formatWithPredicate(e){(sl(e)||Mu(e))&&this.getNodeFormatter(e).keyword(`with`).prepend(J.oneSpace)}formatDeploymentNodeDeclaration(e){this.on(e,Ws,(e,t)=>{let n=Tt(e.$cstNode,`kind`),r=Tt(e.$cstNode,`name`);r&&n&&(eh(r,n)>0?t.cst([n]).append(J.oneSpace):(t.cst([r]).append(J.oneSpace),t.cst([n]).prepend(J.oneSpace))),t.properties(`title`).prepend(J.oneSpace)})}formatDeployedInstance(e){this.on(e,Bs,(e,t)=>{let n=e.$cstNode?.content.find(e=>e.text===`=`);n&&t.cst([n]).surround(J.oneSpace),t.keyword(`instanceOf`).append(J.oneSpace),t.property(`title`).prepend(J.oneSpace)})}formatViewRuleGlobalStyle(e){this.on(e,Od,(e,t)=>{t.keywords(`global`,`style`).append(J.oneSpace)})}formatViewRuleGlobalPredicate(e){let t=this.getNodeFormatter(e);(Ed(e)||gc(e))&&t.keywords(`global`,`predicate`).append(J.oneSpace)}formatViewRuleGroup(e){this.on(e,Ad,(e,t)=>{t.keyword(`group`).append(J.oneSpace)})}formatViewRuleStyle(e){this.on(e,Id)?.keyword(`style`).append(J.oneSpace),this.on(e,oc)?.keyword(`style`).append(J.oneSpace),this.on(e,Uc)?.keyword(`,`).prepend(J.noSpace).append(J.oneSpace),this.on(e,rl)?.keyword(`,`).prepend(J.noSpace).append(J.oneSpace)}formatWhereExpression(e){(Au(e)||al(e))&&this.getNodeFormatter(e).keyword(`where`).append(J.oneSpace)}formatWhereRelationExpression(e){if(this.on(e,ws,(e,t)=>{t.property(`operator`).surround(J.oneSpace)}),this.on(e,ef,(e,t)=>{t.keyword(`not`).append(J.oneSpace)}),Ss(e)){let t=this.getNodeFormatter(e);t.property(`operator`).surround(J.oneSpace),t.property(`not`).surround(J.oneSpace)}}formatWhereElementExpression(e){if(this.on(e,hs,(e,t)=>{t.property(`operator`).surround(J.oneSpace)}),this.on(e,Kd,(e,t)=>{t.keyword(`not`).append(J.oneSpace)}),ps(e)){let t=this.getNodeFormatter(e);t.property(`operator`).surround(J.oneSpace),t.property(`not`).surround(J.oneSpace)}}formatIncludeExcludeExpressions(e){if(So(e)||Md(e)||ic(e)){let t=this.getNodeFormatter(e);(!e.$cstNode||!nh(e.$cstNode))&&t.keywords(`include`,`exclude`).append(J.oneSpace)}if(Uc(e)){let t=this.getNodeFormatter(e),n=this.findPredicateExpressionRoot(e),r=n?.$cstNode&&nh(n?.$cstNode);r&&t.property(`value`).prepend(J.indent),t.keyword(`,`).prepend(J.noSpace).append(r?J.newLine:J.oneSpace)}}formatRelationExpression(e){this.on(e,Rl,(e,t)=>{t.keyword(`->`).append(J.oneSpace)}),this.on(e,Bl,(e,t)=>{t.keyword(`->`).prepend(J.oneSpace)}),this.on(e,Su,(e,t)=>{t.keywords(`->`,`<->`).prepend(J.oneSpace),t.keywords(`-[`).prepend(J.oneSpace).append(J.noSpace),t.keywords(`]->`).prepend(J.noSpace).append(J.oneSpace),t.property(`dotKind`).prepend(J.oneSpace).append(J.oneSpace)}),this.on(e,cc,(e,t)=>{t.property(`target`).prepend(J.oneSpace)})}findPredicateExpressionRoot(e){let t=e.$container;for(;;){if(!t||So(t)||Md(t)||ic(t))return t;t=t.$container}}on(e,t,n){let r=t(e)?this.getNodeFormatter(e):void 0;return n&&r&&n(e,r),r}doExtendedFormatting(e){let t=this.quotesNormalizerFactory(this.extendedFormattingCommands);for(let n of this.extendedFormattingCommands)switch(n.type){case`normalizeQuotes`:t(n,e);break;default:P(n.type)}}normalizeQuotes(e){if(this.options.quoteStyle===`ignore`)return;let t=null;t??=this.on(e,rs)?.property(`value`),t??=this.on(e,H)?.properties(`props`),t??=this.on(e,Il)?.properties(`project`),t??=this.on(e,Eu)?.properties(`title`,`technology`),t??=this.on(e,Ad)?.properties(`title`),t??=this.on(e,wo)?.properties(`title`),t??=this.on(e,Ws)?.properties(`title`),t??=this.on(e,Bs)?.properties(`title`),t??=this.on(e,Xs)?.properties(`title`,`technology`),t??=this.on(e,Xl)?.properties(`title`),t&&this.extendedFormattingCommands.push({type:`normalizeQuotes`,region:t})}quotesNormalizerFactory(e){let t=this.options.quoteStyle==`auto`?this.getAutoQuoteStyle(e):this.options.quoteStyle;return(e,n)=>{let r=t===`single`?`"`:`'`,i=t===`single`?`'`:`"`,a=i.repeat(3),o=i,s=e.region.nodes.map(e=>{let t=e.text.startsWith(`"""`)||e.text.startsWith(`'''`)?a:o;return{range:e.range,newText:t+this.escapeQuotesInternalQuotes(e.text.slice(t.length,-t.length),r,i)+t}});n.push(...s)}}escapeQuotesInternalQuotes(e,t,n){let r=``,i=0;for(;i>=0;){let t=e.indexOf(n,i);if(t<0){r+=e.slice(i);break}r+=e.slice(i,t),i=t+1;let a=!1;for(;t>0&&e[t-1]==`\\`;)a=!a,t--;r+=a?n:`\\${n}`}return r}getAutoQuoteStyle(e){let t=e.flatMap(e=>e.region.nodes);return t.filter(e=>e.text[0]==`"`).length*2>=t.length?`double`:`single`}onConfigurationUpdate(e){this.options={...this.options,...e??{quoteStyle:`auto`}}}};Qt();const ih=B.getChild(`LanguageServices`),ah=e=>e.severity===xt.Error;var oh=class{builder;editor;projectsManager;constructor(e){this.services=e,this.builder=e.likec4.ModelBuilder,this.projectsManager=e.shared.workspace.ProjectsManager,this.editor=e.likec4.ModelChanges}get mcpServer(){let e=this.services.mcp.Server;return e instanceof $p?null:e}get views(){return this.services.likec4.Views}get workspaceUri(){return this.services.shared.workspace.WorkspaceManager.workspaceUri}projects(){let e=this.services.shared.workspace.ProjectsManager,t=y(this.services.shared.workspace.LangiumDocuments.groupedByProject(),u(),x(([t,n])=>{let r=t,{folderUri:i,config:a}=e.getProject(r);return{id:r,folder:i,title:a.title??a.name,documents:x(n,De(`uri`)),config:a}}));if(v(t,2)&&e.defaultProjectId){let n=t.findIndex(t=>t.id===e.defaultProjectId);if(n>0){let[e]=t.splice(n,1);return[e,...t]}return t}if(v(t,1))return t;let{id:n,folderUri:r,config:i}=e.default;return[{id:n,folder:r,title:i.title??i.name,documents:[],config:i}]}project(e){let{id:t,folderUri:n,config:r}=this.projectsManager.ensureProject(e),i=x(this.services.shared.workspace.LangiumDocuments.projectDocuments(t).toArray(),De(`uri`));return{id:t,folder:n,title:r.title??r.name,documents:i,config:r}}async diagrams(e,t){let n=this.projectsManager.ensureProjectId(e);return await this.views.diagrams(n,t)}async computedModel(e,t){let n=this.projectsManager.ensureProjectId(e);return await this.builder.computeModel(n,t)}async layoutedModel(e,t){let n=this.projectsManager.ensureProjectId(e),r=await this.builder.computeModel(n,t);if(!r)throw Error(`Failed to compute model, empty project?`);let i=await this.views.layoutAllViews(n,t);return Jn.create({...r.$data,_stage:`layouted`,views:y(i,x(De(`diagram`)),h(De(`id`)))})}async projectsOverview(e){let t=this.services.shared.workspace.ProjectsManager.all,n=[];for(let r of t){let t=await this.builder.computeModel(r,e);if(e?.isCancellationRequested)throw Error(`Operation cancelled`);if(t===Jn.EMPTY){ih.debug(`Project ${r} is empty, skipping`);continue}n.push(t)}if(!v(n,1))throw Error(`No models found`);let r=Mi(n);return await this.views.layouter.layoutProjectsView(r)}getErrors(){return y(this.services.shared.workspace.LangiumDocuments.userDocuments.toArray(),l(e=>y(e.diagnostics??[],b(ah),x(({message:t,range:n})=>({message:t,line:n.start.line,range:n,sourceFsPath:e.uri.fsPath})))))}locate(e){switch(!0){case`element`in e:return this.services.likec4.ModelLocator.locateElement(e.element,e.projectId);case`relation`in e:return this.services.likec4.ModelLocator.locateRelation(e.relation,e.projectId);case`view`in e:return this.services.likec4.ModelLocator.locateView(e.view,e.projectId);case`deployment`in e:return this.services.likec4.ModelLocator.locateDeploymentElement(e.deployment,e.projectId);default:P(e)}}async format(e){let t=this.services.shared.workspace.LangiumDocuments,n=this.services.lsp.Formatter,r=sh(e),i=this.collectDocumentsToFormat(t,e);i.sort((e,t)=>e.uri.toString().localeCompare(t.uri.toString()));let a=new Map;for(let e of i){let t=e.uri.toString(),i=await n.formatDocument(e,{options:r,textDocument:{uri:t}}),o=i.length===0?e.textDocument.getText():yt.applyEdits(e.textDocument,i);a.set(t,o)}return a}collectDocumentsToFormat(e,t){let n=t?.projectIds??[],r=t?.documentUris??[],i=new Map;if(n.length>0)for(let t of n)for(let n of e.projectDocuments(t))i.set(n.uri.toString(),n);else if(r.length===0)for(let t of this.projectsManager.all)for(let n of e.projectDocuments(t))i.set(n.uri.toString(),n);for(let t of r){if(i.has(t))continue;let n;try{n=e.getDocument(C.parse(t))}catch{ih.warn(`format: skipping unknown document ${t}`);continue}if(!Ef(n)){ih.warn(`format: skipping unknown document ${t}`);continue}i.set(t,n)}return[...i.values()]}async dispose(){try{ih.debug(`disposing LikeC4LanguageServices`),await this.services.shared.workspace.FileSystemWatcher.dispose(),this.services.mcp.Server.isStarted&&await this.services.mcp.Server.stop(),this.services.Rpc.dispose(),this.services.likec4.ModelBuilder.dispose()}catch(e){ih.error(L(e))}finally{ih.debug(`LikeC4LanguageServices disposed`)}}};function sh(e){return{tabSize:e?.tabSize??2,insertSpaces:e?.insertSpaces??!0,...e?.trimTrailingWhitespace!=null&&{trimTrailingWhitespace:e.trimTrailingWhitespace},...e?.insertFinalNewline!=null&&{insertFinalNewline:e.insertFinalNewline},...e?.trimFinalNewlines!=null&&{trimFinalNewlines:e.trimFinalNewlines}}}var ch=class{constructor(e){this.services=e}async provideCodeLens(e,t,n){if(Ef(e))return e.state<S.Linked&&(B.debug(`Waiting for document ${e.uri.path} to be Linked`),await this.services.shared.workspace.DocumentBuilder.waitUntil(S.Linked,e.uri,n),B.debug(`Document is linked`)),e.parseResult.value.views.flatMap(e=>e.views).flatMap(e=>{let t=wf.readId(e),n=e.$cstNode?.range;if(!n||!t)return[];let r=G(e);return{range:{start:n.start,end:{line:n.start.line,character:n.start.character+4}},command:{command:`likec4.open-preview`,arguments:[t,r],title:`open preview`}}})}};Qt();const lh=[`color`,`shape`,`icon`,`iconColor`,`iconSize`,`iconPosition`,`border`,`opacity`,`multiple`,`size`,`textSize`].join(`,`);function uh(e,t){return Rt(t.feature)&&t.property===`project`&&Il(e.node)}var dh=class extends Ft{constructor(e){super(e),this.services=e}completionOptions={triggerCharacters:[`.`,`#`]};completionFor(e,t,n){switch(!0){case Gt(t.feature):return this.completionForKeyword(e,t.feature,n);case Xt(t.feature)&&!!e.node:return this.completionForCrossReference(e,t,n);case uh(e,t):return this.completionForImportedProject(e,n)}}completionForKeyword(e,t,n){if(this.filterKeyword(e,t))switch(!0){case t.value===`import`:n(e,{label:t.value,kind:w.Snippet,insertTextFormat:E.Snippet,insertText:`${t.value} { $0 } from '\${1|${this.services.shared.workspace.ProjectsManager.all.join(`,`)}|}'`});break;case t.value===`deployment`&&jt(e.node,uu):n(e,{label:t.value,detail:`Insert deployment view`,kind:w.Class,insertTextFormat:E.Snippet,insertText:["deployment view ${1:view_${TM_FILENAME_BASE}_${CURRENT_SECOND}} {"," title '${2:Untitled}'",` `,` include $0`,`}`].join(`
|
|
1201
|
-
`)});break;case[`title`,`description`,`technology`,`link`].includes(t.value):n(e,{label:t.value,detail:`Insert ${t.value} property`,kind:w.Property,insertTextFormat:E.Snippet,insertText:`${t.value} '\${0}'`});break;case t.value===`color`:n(e,{label:t.value,kind:w.Property,insertTextFormat:E.Snippet,insertText:`${t.value} \${1|${jr.join(`,`)}|}$0`});break;case t.value===`opacity`:n(e,{label:t.value,kind:w.Property,insertTextFormat:E.Snippet,insertText:`${t.value} \${0:100}%`});break;case[`views`,`specification`,`model`,`deployment`,`with`].includes(t.value):n(e,{label:t.value,detail:`Insert ${t.value} block`,kind:w.Module,insertTextFormat:E.Snippet,insertText:`${t.value} {\n\t$0\n}`});break;case t.value===`group`:n(e,{label:t.value,detail:`Insert group block`,kind:w.Module,insertTextFormat:E.Snippet,insertText:["group '${1:Title}' {",` $0`,`}`].join(`
|
|
1202
|
-
`)});break;case[`par`,`parallel`].includes(t.value):n(e,{label:t.value,detail:`Insert block of parallel steps`,kind:w.Module,insertTextFormat:E.Snippet,insertText:[`${t.value} {`,` $0`,`}`].join(`
|
|
1203
|
-
`)});break;case t.value===`dynamic`&&jt(e.node,uu):n(e,{label:t.value,detail:`Insert dynamic view`,kind:w.Class,insertTextFormat:E.Snippet,insertText:["dynamic view ${1:view_${TM_FILENAME_BASE}_${CURRENT_SECOND}} {"," title '${2:Untitled}'",` `,` $0`,`}`].join(`
|
|
1204
|
-
`)});break;case t.value===`style`&&e.node&&jt(e.node,yl):n(e,{label:t.value,detail:`Insert ${t.value} block`,kind:w.Module,insertTextFormat:E.Snippet,insertText:`${t.value} \${1:name} \${2:*} {\n\t\${3|${lh}|} $0\n}`});break;case t.value===`style`&&e.node&&jt(e.node,Ee([uu,xl])):n(e,{label:t.value,detail:`Insert ${t.value} block`,kind:w.Module,insertTextFormat:E.Snippet,insertText:`${t.value} \${1:*} {\n\t\${2|${lh}|} $0\n}`});break;case t.value===`style`:n(e,{label:t.value,detail:`Insert ${t.value} block`,kind:w.Module,insertTextFormat:E.Snippet,insertText:`${t.value} {\n\t\${1|${lh}|} $0\n}`});break;case t.value===`extend`:n(e,{label:t.value,detail:`Extend another view`,kind:w.Class,insertTextFormat:E.Snippet,insertText:`extend $1 {
|
|
1205
|
-
$0
|
|
1206
|
-
}`});break;case t.value===`autoLayout`:n(e,{label:t.value,kind:w.Property,insertTextFormat:E.Snippet,insertText:"autoLayout ${1|TopBottom,BottomTop,LeftRight,RightLeft|}$0"});break;case t.value===`mode`:n(e,{label:t.value,kind:w.Property,insertTextFormat:E.Snippet,insertText:"mode ${1|sequence,diagram|}$0"});break;case[`include`,`exclude`].includes(t.value):n(e,{label:t.value,kind:w.Operator,detail:`Insert ${t.value} predicate`,insertTextFormat:E.PlainText,insertText:`${t.value} `});break;default:n(e,{label:t.value,kind:this.getKeywordCompletionItemKind(t),detail:`Keyword`,sortText:`1`})}}completionForImportedProject(e,t){let r=this.services.shared.workspace.ProjectsManager,i=e.document.textDocument,a={start:i.positionAt(e.tokenOffset),end:i.positionAt(e.tokenEndOffset)},o=i.getText(a),s=n(o)?`'`:o.substring(0,1);for(let n of r.all){let r=s+n+s;t(e,{label:n,kind:w.Folder,insertText:r,filterText:r,textEdit:Kt.replace(a,r),detail:`Project`,sortText:`0_`+n})}}},fh=Ct(),ph=class extends Lt{createDocumentHighlight(e){return fh.DocumentHighlight.create(e.segment.range,fh.DocumentHighlightKind.Read)}},mh=class{constructor(e){this.services=e}async getDocumentLinks(e,t,n){return!Ef(e)||this.services.shared.workspace.ProjectsManager.isExcluded(e)?[]:Pt(e.parseResult.value).filter(Xl).map(t=>{try{let n=Tt(t.$cstNode,`value`)?.range,r=n&&this.resolveLink(e,t.value);if(r&&Mn(r))return{range:n,target:r}}catch(e){V(e)}return null}).nonNullable().toArray()}resolveLink(e,t){if(Mn(t)||kn(t))return t;if(Dn(t))return wn(e.uri.toString(),`../`,t);let n=this.services.shared.workspace.ProjectsManager.getProject(e).folderUri;return wn(n.toString(),t)}relativeLink(e,t){if(kn(t))return Tn(t);if(Dn(t)){let n=this.services.shared.workspace.ProjectsManager.getProject(e).folderUri.toString(),r=new URL(e.uri.toString());return Tn(Pn(new URL(t,r).toString(),n))}return null}};Qt();const hh=B.getChild(`DocumentSymbolProvider`);var gh=class{nodeKindProvider;nameProvider;parser;locator;constructor(e){this.services=e,this.nodeKindProvider=e.shared.lsp.NodeKindProvider,this.parser=e.likec4.ModelParser,this.locator=e.likec4.ModelLocator,this.nameProvider=e.references.NameProvider}async getSymbols(e,t,n){if(!Ef(e)||this.services.shared.workspace.ProjectsManager.isExcluded(e))return[];e.state<S.Linked&&(hh.debug(`Waiting for document ${e.uri.path} to be Linked`),await this.services.shared.workspace.DocumentBuilder.waitUntil(S.Linked,e.uri,n),hh.debug(`document is Linked`));let{parseResult:{value:{specifications:r,models:i,deployments:a,views:o,likec4lib:s}}}=e;return[...s.map(e=>()=>this.getLikec4LibSymbol(e)),...r.map(e=>()=>this.getSpecSymbol(e)),...i.map(e=>()=>this.getModelSymbol(e)),...a.map(e=>()=>this.getDeploymentModelSymbol(e)),...o.map(e=>()=>this.getModelViewsSymbol(e))].flatMap(e=>{try{return e()??[]}catch(e){return V(e),[]}})}getLikec4LibSymbol(e){let t=e?.$cstNode;if(!t)return[];let n=e.icons.map(e=>this.getLibIconSymbol(e)).filter(i);return n.length===0?[]:[{kind:tn.Namespace,name:`icons`,range:t.range,selectionRange:zt(t,`icons`)?.range??t.range,children:n}]}getSpecSymbol(e){let t=e?.$cstNode;if(!t)return[];let n=Tt(t,`name`);if(!n)return[];let r=y([...e.elements,...e.tags,...e.relationships],x(e=>{try{if(ed(e)||id(e)||Qu(e))return this.getKindSymbol(e);if(ud(e))return this.getTagSymbol(e)}catch(e){return V(e),null}P(e)}),b(i));return r.length===0?[]:[{kind:tn.Namespace,name:e.name,range:t.range,selectionRange:n.range,children:r}]}getModelSymbol(e){let t=e.$cstNode;if(!t)return[];let n=Tt(t,`name`);return n?[{kind:this.symbolKind(e),name:e.name,range:t.range,selectionRange:n.range,children:e.elements.flatMap(e=>$c(e)?[]:this.getElementsSymbol(e))}]:[]}getDeploymentModelSymbol(e){let t=e.$cstNode;if(!t)return[];let n=Tt(t,`name`);return n?[{kind:this.symbolKind(e),name:e.name,range:t.range,selectionRange:n.range,children:e.elements.flatMap(e=>this.getDeploymentElementSymbol(e))}]:[]}getElementsSymbol(e){try{if(Yc(e))return this.getExtendElementSymbol(e);if(H(e))return this.getElementSymbol(e)}catch(e){V(e)}return[]}getExtendElementSymbol(e){let t=e.$cstNode,n=e.element.$cstNode,r=e.body;return!t||!n?[]:[{kind:this.symbolKind(e),name:Wf(e.element),range:t.range,selectionRange:n.range,children:r.elements.flatMap(e=>this.getElementsSymbol(e))}]}getElementSymbol(e){let t=e.$cstNode,n=Tt(t,`name`);if(!n||!t)return[];let r=e.name,i=e.kind.$refText;return[{kind:this.symbolKind(e),name:r,range:t.range,selectionRange:n.range,detail:i,children:e.body?.elements.flatMap(e=>this.getElementsSymbol(e))??[]}]}getModelViewsSymbol(e){let t=e.$cstNode,n=Tt(t,`name`);return!n||!t?[]:[{kind:this.symbolKind(e),name:e.name,range:t.range,selectionRange:n.range,children:e.views.flatMap(e=>this.getViewSymbol(e))}]}getKindSymbol(e){return!e.$cstNode||!e.kind.$cstNode||n(e.kind.name)?null:{kind:this.symbolKind(e),name:e.kind.name,range:e.$cstNode.range,selectionRange:e.kind.$cstNode.range}}getTagSymbol(e){return!e.$cstNode||!e.tag.$cstNode||n(e.tag.name)?null:{kind:this.symbolKind(e),name:`#`+e.tag.name,range:e.$cstNode.range,selectionRange:e.tag.$cstNode.range}}getLibIconSymbol(e){return!e.$cstNode||n(e.name)?null:{kind:this.symbolKind(e),name:e.name,range:e.$cstNode.range,selectionRange:e.$cstNode.range}}getViewSymbol(e){let t=e?.$cstNode;if(!t)return[];let n=e.name?Tt(t,`name`):null;return n?[{kind:this.symbolKind(e),name:n.text,range:t.range,selectionRange:n.range,children:[]}]:[]}getDeploymentElementSymbol(e){try{if(Ws(e))return this.getDeploymentNodeSymbol(e);if(Bs(e))return this.getDeployedInstanceSymbol(e);if(Gc(e))return[]}catch(e){V(e)}return[]}getDeploymentNodeSymbol(e){let t=e.$cstNode,n=this.nameProvider.getNameNode(e);if(!n||!t)return[];let r=this.nameProvider.getNameStrict(e),i=e.kind.$refText;return[{kind:this.symbolKind(e),name:r,range:t.range,selectionRange:n.range,detail:i,children:e.body?.elements.flatMap(e=>this.getDeploymentElementSymbol(e))??[]}]}getDeployedInstanceSymbol(e){let t=e.$cstNode,n=this.nameProvider.getNameNode(e);if(!n||!t)return[];let r=rn(e),i=this.parser.forDocument(r).parseDeployedInstance(e),a=this.nameProvider.getNameStrict(e),o=`instance of `+i.element.model;return[{kind:this.symbolKind(e),name:a,range:t.range,selectionRange:n.range,detail:o,children:[]}]}symbolKind(e){return this.nodeKindProvider.getSymbolKind(e)}};const _h=`
|
|
1207
|
-
---
|
|
1208
|
-
`;var vh=class extends Wt{parser;locator;constructor(e){super(e),this.services=e,this.parser=e.likec4.ModelParser,this.locator=e.likec4.ModelLocator}getAstNodeHoverContent(e){if(hd(e))return{contents:{kind:`markdown`,value:"tag `"+e.name+"`"}};if(Ec(e))return{contents:{kind:`markdown`,value:"element kind `"+e.name+"`"}};if(Js(e))return{contents:{kind:`markdown`,value:"deployment node `"+e.name+"`"}};if(Ru(e))return{contents:{kind:`markdown`,value:"relationship kind `"+e.name+"`"}};try{if(H(e))return this.getElementHover(e);if(Ws(e))return this.getDeploymentNodeHover(e);if(Bs(e))return this.getDeployedInstanceHover(e)}catch(e){B.debug(L(e))}}getElementHover(e){let t=this.locator.getParsedElement(e);if(!t)return;let n=t.element,r=[`<sup>\`${n.id}\`</sup> `,`### ${n.title} `],i=Or(n);i&&r.push(``,(i.md??i.txt).split(`
|
|
1209
|
-
`).join(`
|
|
1210
|
-
`));let a=this.services.likec4.LastSeen.model(t.projectId)?.findElement(n.id),o=a&&this.getElementModelHover(a,t.projectId);return r.push(o||`
|
|
1211
|
-
<small>_Model not processed yet, open any view to trigger_</small> `),{contents:{kind:`markdown`,value:r.join(`
|
|
1212
|
-
`)}}}getElementModelHover(e,t){let n=[],r=[...e.incoming(`direct`)].length,i=[...e.outgoing(`direct`)].length;(r>0||i>0)&&n.push(_h,`<small>**${r}** incoming, **${i}** outgoing relationships</small> `);let a=e=>{let n=[e.id,t],r=C.parse(`command:likec4.open-preview?${encodeURIComponent(JSON.stringify(n))}`);return` - [${e.titleOrId}](${r})`},o=[...e.scopedViews()].map(a);o.length>0&&n.push(_h,`<small>Element views:</small>`,...o);let s=[...e.views()].map(t=>t.isScopedElementView()&&t.viewOf===e?null:a(t)).filter(m);if(s.length>0){let e=o.length>0?`Also appears in views:`:`Appears in views:`;n.push(o.length>0?``:_h,`<small>${e}</small>`,...s,` `)}return n.length>0?n.join(`
|
|
1213
|
-
`):void 0}getDeploymentNodeHover(e){let t=rn(e),n=this.parser.forDocument(t).parseDeploymentNode(e),r=[n.id+` `];n.title!==e.name&&r.push(`### ${n.title}`),r.push("deployment node `"+n.kind+"` ");let i=Or(n);return i&&r.push(``,i.md??i.txt),{contents:{kind:`markdown`,value:r.join(`
|
|
1214
|
-
`)}}}getDeployedInstanceHover(e){let t=rn(e),n=this.parser.forDocument(t).parseDeployedInstance(e),[r,i]=M.isImportRef(n.element)?[n.element.project,n.element.model]:[t.likec4ProjectId,n.element.model],a=r?this.locator.getParsedElement(i,r):this.locator.getParsedElement(i),o=[n.id+` `,`instance of \`${M.flatten(n.element)}\``];return a&&o.push(`### ${a.element.title}`,"element kind `"+a.element.kind+"` "),{contents:{kind:`markdown`,value:o.join(`
|
|
1215
|
-
`)}}}},yh=an(),bh=class{getCodeActions(e,t){}};Qt();const xh=B.getChild(`SemanticTokenProvider`),Sh={...Mt},Ch={...tt};function wh(e){let t=[],n=new Proxy({},{get(r,i){if(i===`modifier`)return e=>(t.push(e),n);if(i in Ch)return t.push(Ch[i]),n;if(i in Sh)return()=>e(Sh[i],t);throw Error(`Unknown semantic token type or modifier: ${i}`)}});return n}const Th=`Stop Highlighting`,Eh=()=>{throw Th};var Dh=class extends Yt{rules=[];constructor(e){super(e),this.services=e,this.initRules()}initRules(){this.rules=[];let e=(e,t)=>{let n={predicate:e,highlightFn:t};this.rules.push(n)};e(Ru,e=>{e.property(`name`).function()}),e(zr(Eu,Su,Xs),e=>{e.property(`kind`).function()}),e(Hl,e=>{e.property(`name`).definition.function(),Eh()}),e(zr(mu,Iu),e=>{e.property(`value`).readonly.definition.interface()}),e(df,e=>{e.cst().readonly.definition.variable(),Eh()}),e(dl,e=>{e.node.selector&&(e.node.ref.parent?e.property(`selector`).property():e.property(`selector`).readonly.definition.variable())}),e(_d,e=>{e.cst().type()}),e(Pu,e=>{e.cst().function()}),e(Xd,e=>{i(e.node.value?.$refText)&&e.property(`value`).function()}),e(zr(Wd,Qd,af),e=>{e.keyword(`metadata`).keyword(),e.property(`key`).property()}),e(zr(Jd,Hd,lf,Xd),e=>{i(e.node.value)&&e.property(`value`).readonly.definition.type()}),e(zr(nf,sf,af),e=>{e.property(`participant`).keyword()}),e(Oc,e=>{i(e.node.kind)&&e.property(`kind`).definition.type()}),e(zr(xl,yl),e=>{e.property(`id`).readonly.definition.variable()}),e(Od,e=>{e.property(`style`).readonly.definition.variable()}),e(zr(hl,pl),e=>{e.property(`name`).readonly.definition.variable()}),e(Ed,e=>{e.property(`predicate`).readonly.definition.variable()}),e(Ic,e=>{i(e.node.tag)&&e.property(`tag`).definition.type()}),e(zr(ll,md),e=>{if(e.node.parent){e.property(`value`).property();return}let t=e.node.value.$refText;t!==`this`&&t!==`it`&&e.property(`value`).readonly.definition.variable()}),e(fd,e=>{e.node.parent?e.property(`el`).property():e.property(`el`).readonly.definition.variable()}),e(Xu,e=>{e.keyword(`color`).keyword(),e.property(`name`).readonly.declaration.type()}),e(ud,e=>{i(e.node.color)&&e.keyword(`color`).property()}),e(zr(ed,id,Qu),e=>{e.property(`kind`).readonly.declaration.type()}),e(hd,e=>{e.property(`name`).definition.type()}),e(bu,e=>{e.property(`value`).number()}),e(Al,e=>{if(e.node.libicon||e.node.value===`none`){e.property(e.node.libicon?`libicon`:`value`).defaultLibrary.enum();return}e.property(`value`).string()}),e(Xl,e=>{i(e.node.value)&&e.property(`value`).string()}),e(zr(Ns,El),e=>{i(e.node.customColor)&&e.property(`customColor`).enum(),i(e.node.themeColor)&&e.property(`themeColor`).enum()}),e(e=>fo(e)&&!zr(Vo,Pc,Hu)(e)&&i(e.key),e=>e.property(`key`).property()),e(zr(Ku,ks,Jl,js,ts,Ol,Ml,mc),e=>{i(e.node.value)&&e.property(`value`).enum()})}highlightElement(e,t){if(zr(H,Ws,Bs)(e))return this.highlightNameAndKind(e);if(zo(e))return this.highlightView(e);let n;for(let{predicate:t,highlightFn:r}of this.rules)if(t(e))try{n??=this.mark(e),r(n)}catch(t){if(t===Th)return`prune`;xh.warn(`Error highlighting node of type ${e._type}`,{error:t})}}highlightNameAndKind(e){if(this.mark(e).property(`name`).declaration.readonly.variable(),Bs(e)||this.mark(e).property(`kind`).keyword(),H(e)){e.props.length>0&&this.mark(e).property(`props`).string();return}e.title&&this.mark(e).property(`title`).string()}highlightView(e){e.name&&this.mark(e).property(`name`).modifier(`local`).declaration.readonly.interface()}mark(e){let t=t=>wh((n,r)=>this.highlightToken({range:ni(t??e.$cstNode,`AST node has no CST node`).range,type:n,modifier:r})),n=t=>wh((n,r)=>this.highlightKeyword({node:e,keyword:t,type:n,modifier:r})),r=(t,n)=>wh((r,i)=>this.highlightProperty({node:e,property:t,type:r,modifier:i,...n===void 0?{}:{index:n}}));return{node:e,cst:t,keyword:n,property:r}}};const Oh=zr(H,Yc);var kh=class extends lo{projects;langiumDocuments;documentCache;workspaceCache;logger=B.getChild(`fqn-index`);constructor(e){super(),this.services=e,this.langiumDocuments=e.shared.workspace.LangiumDocuments,this.projects=e.shared.workspace.ProjectsManager,this.documentCache=new Hr(e=>this.createDocumentIndex(e)),this.workspaceCache=new Bt(e.shared,S.IndexedContent),this.onDispose(e.shared.workspace.DocumentBuilder.onDocumentPhase(S.IndexedContent,e=>{Df(e)&&this.documentCache.delete(e)}))}documents(e){return this.langiumDocuments.projectDocuments(e).filter(e=>e.state>=S.IndexedContent)}get(e){return e.state<S.IndexedContent&&this.logger.warn(`document {doc} is in state {state}, expected at least IndexedContent ({expect}). This may lead to incorrect FQN resolution.`,{doc:T.basename(e.uri),state:e.state,expect:S.IndexedContent}),this.documentCache.get(e)}resolve(e){return e.$type===`Imported`?this.getFqn(e.imported.ref):e.$type===`Element`?this.getFqn(e):this.services.likec4.DeploymentsIndex.getFqn(e)}getFqn(e){N(H(e)||go(e));let t=Tf.readId(e);if(i(t))return t;let n=rn(e);return n.state<S.IndexedContent&&this.logger.warn(`document {doc} is not yet indexed, creating on the fly to resolve FQN for element {el}`,{el:e.name??e.$type,doc:T.basename(n.uri)}),N(Ef(n)),this.get(n),Dr(Tf.readId(e),`Element fqn must be set, invalid state`)}byFqn(e,t){return on(this.workspaceCache.get(`${e}:fqn:${t}`,()=>this.documents(e).flatMap(e=>this.get(e).byFqn(t)).toArray()))}rootElements(e){return on(this.workspaceCache.get(`${e}:rootElements`,()=>{let t=new Ur;for(let n of this.documents(e))for(let e of this.get(n).rootElements())t.set(e.name,e);return Ah(t)}))}directChildrenOf(e,t){return on(this.workspaceCache.get(`${e}:directChildrenOf:${t}`,()=>{let n=new Ur;for(let r of this.documents(e))for(let e of this.get(r).children(t))n.set(e.name,e);return Ah(n)}))}uniqueDescedants(e,t){return on(this.workspaceCache.get(`${e}:uniqueDescedants:${t}`,()=>{let n=new Ur,r=new Ur;for(let i of this.documents(e)){let e=this.get(i);for(let r of e.children(t))n.set(r.name,r);for(let n of e.descendants(t))r.set(n.name,n)}let i=Ah(n),a=[...r.associations()].flatMap(([e,t])=>t.length===1&&!n.has(e)?t:[]);return[...i,...ci(a)]}))}createDocumentIndex(e){let t=e.parseResult.value.models.flatMap(e=>e.elements.filter(Oh));if(t.length===0)return jh.EMPTY;let n=e.likec4ProjectId??this.projects.ownerProjectId(e),r=[],i=new Ur,a=new Ur,o=new Ur,s=this.services.workspace.AstNodeDescriptionProvider,c=(t,r,i)=>{let a=Object.assign(s.createDescription(t,r,e),{id:i,likec4ProjectId:n});return Tf.writeId(t,i),o.set(i,a),a};function u(e,t){let n=Pr(e.name,t),o=c(e,e.name,n);t?i.set(t,o):r.push(o);let s=b(e.body?.elements??[],Oh);if(!v(s,1))return[o];let d=l(s,e=>u(e,n));for(let e of d)a.set(n,e);return[o,...d]}function d(e){let t=Wf(e.element),n=y(e.body?.elements??[],b(H),l(e=>u(e,t)));if(n.length!==0)for(let e of[t,...Wr(t)])for(let t of n)a.set(e,t)}for(let n of t)try{if(Yc(n)){d(n);continue}u(n,null)}catch(t){this.logger.warn(`Error while traversing element {el} in document {doc}`,{el:n.$type,doc:T.basename(e.uri),error:t})}return new jh(r,i,a,o,n)}};function Ah(e){return[...e.associations()].flatMap(([e,t])=>t.length===1?t:[]).sort((e,t)=>Kr(e.name,t.name))}var jh=class e{static EMPTY=new e([],new Ur,new Ur,new Ur,vp.DefaultProjectId);constructor(e,t,n,r,i){this._rootElements=e,this._children=t,this._descendants=n,this._byfqn=r,this.projectId=i}rootElements(){return this._rootElements}byFqn(e){return this._byfqn.get(e)??[]}children(e){return this._children.get(e)??[]}descendants(e){return this._descendants.get(e)??[]}};const Mh=_r(go,Gc);var Nh=class extends kh{Names;logger=B.getChild(`deployments-index`);constructor(e){super(e),this.services=e,this.Names=e.references.NameProvider}createDocumentIndex(e){let t=e.parseResult.value.deployments.flatMap(e=>e.elements.filter(Mh));if(t.length===0)return jh.EMPTY;let n=e.likec4ProjectId??this.projects.ownerProjectId(e),r=[],a=new Ur,o=new Ur,s=new Ur,c=this.Names,u=this.services.workspace.AstNodeDescriptionProvider,d=(t,r,i)=>{let a={...u.createDescription(t,r,e),id:i,likec4ProjectId:n};return Tf.writeId(t,i),s.set(i,a),a};function f(e,t){let n=c.getName(e);if(!i(n))return[];let s=$n(n,t),u=d(e,n,s);if(t?a.set(t,u):r.push(u),Bs(e))return[u];let p=b(e.body?.elements??[],Mh);if(!v(p,1))return[u];let m=l(p,e=>f(e,s));for(let e of m)o.set(s,e);return[u,...m]}function p(e){let t=Wf(e.deploymentNode),n=y(e.body?.elements??[],b(Mh),l(e=>f(e,t)));if(n.length!==0)for(let e of[t,...lr(t)])for(let t of n)o.set(e,t)}for(let n of t)try{if(Gc(n)){p(n);continue}f(n,null)}catch(t){this.logger.warn(`Error while traversing element {el} in document {doc}`,{el:n.$type,doc:T.basename(e.uri),error:t})}return new jh(r,a,o,s,n)}};const Ph=/^(aws|azure|gcp|tech):(.+)$/;function Fh(e){if(!e)return;let t=Ph.exec(e);if(t)return t[2].replace(/-icon$/,``).split(`-`).map(e=>e.charAt(0).toUpperCase()+e.slice(1)).join(` `)}var Ih=class{specs={elements:{},deployments:{},relationships:{},colors:{}};tags;globals={predicates:{},dynamicPredicates:{},styles:{}};imports=new Ur(Set);projectId;inferTechFromIcon;constructor(e,t){let n={},r=[];for(let t of e){let{c4Specification:e,c4Globals:i,c4Imports:a}=t,o=t.likec4ProjectId;m(o)&&(r.length===0||r[0]!==o)&&r.push(t.likec4ProjectId),Object.assign(n,e.tags),Object.assign(this.specs.elements,e.elements),Object.assign(this.specs.relationships,e.relationships),Object.assign(this.specs.colors,e.colors),Object.assign(this.specs.deployments,e.deployments),Object.assign(this.globals.predicates,i.predicates),Object.assign(this.globals.dynamicPredicates,i.dynamicPredicates),Object.assign(this.globals.styles,i.styles);for(let[e,t]of a)this.imports.set(e,t)}this.tags=Mr(n),this.projectId=Se(r),this.inferTechFromIcon=t?.inferTechFromIcon??!0}toModelElement=({tags:e,links:t,style:r,id:i,kind:a,title:o,description:s,technology:c,summary:l,metadata:u})=>{try{let d=this.specs.elements[a];if(!d)return B.warn`No kind '${a}' found for ${i}`,null;c??=d.technology,s??=d.description,l??=d.summary,t??=d.links,ge(o)&&(o=d.title||ti(i)),d.tags&&Zr(d.tags)&&(e=e?Ce([...d.tags,...e]):d.tags);let f=Rr({...d.style,...r});return!c&&this.inferTechFromIcon&&(c=Fh(f.icon)),Rr({metadata:u&&!n(u)?u:void 0,notation:d.notation,style:f,links:t,tags:e,summary:l,technology:c,description:s,title:o,kind:a,id:i})}catch(e){V(e)}return null};toModelRelation=({astPath:e,source:t,target:n,kind:r,links:i,id:a,...o})=>m(r)&&this.specs.relationships[r]?{...this.specs.relationships[r],...o,...i&&{links:i},source:t,target:n,kind:r,id:a}:{...i&&{links:i},...o,source:t,target:n,id:a};toDeploymentElement=e=>{if(`element`in e&&!(`kind`in e))return{...e,element:F.flatten(e.element)};if(`element`in e)return B.warn`Invalid ParsedAstDeployment ${e.id}, has both element and kind properties`,null;try{let t=this.specs.deployments[e.kind];if(!t)return B.warn`No kind ${e.kind} found for ${e.id}`,null;let{id:n,style:r,title:i,...a}=e;return i=i===ti(e.id)&&t.title?t.title:i,Rr({...t,...a,title:i,style:Rr({...t.style,...r}),id:n})}catch(e){V(e)}return null};toDeploymentRelation=({astPath:e,source:t,target:n,kind:r,links:i,id:a,...o})=>m(r)&&this.specs.relationships[r]?{...this.specs.relationships[r],...o,...i&&{links:i},source:t,target:n,kind:r,id:a}:{...i&&{links:i},...o,source:t,target:n,id:a}},Lh=class{#e=new Map;#t=new Map;#n=new Map;constructor(e){e.shared.workspace.WorkspaceManager.onForceCleanCache(()=>{this.#e.clear(),this.#t.clear(),this.#n.clear()})}rememberSpecification(e){return e.projectId&&this.#e.set(e.projectId,e),e}rememberModel(e){let t=e.projectId,n=e.$styles,r=this.#t.get(t);return(!r||!r.equals(n))&&this.#t.set(t,n),this.#n.set(t,e),e}specification(e){return this.#e.get(e)}styles(e){return this.#t.get(e)}model(e){return this.#n.get(e)}};function Rh(e){let t=new Map;for(let n of e)if(xr(n)&&n.viewOf&&a(n.extends)){let e=t.get(n.viewOf)??[];e.push(n.id),t.set(n.viewOf,e)}for(let{id:n,nodes:r}of e)for(let e of r){let r=e.modelRef;if(e.navigateTo||!r)continue;let i=d(t.get(r)??[],e=>e!==n);i&&(e.navigateTo=i)}return e}var zh=class{mergedData=new Map;mergeMetadata(e,t){let n={...e};for(let[e,r]of Object.entries(t)){let t=n[e];if(t===void 0){n[e]=r;continue}let i=Array.isArray(t)?t:[t],a=Array.isArray(r)?r:[r],o=Ce([...i,...a]);n[e]=o.length===1?o[0]:o}return n}merge(e){for(let t of e){let{id:e,links:n,tags:r,metadata:i}=t,a=this.mergedData.get(e)??{links:[],tags:[],metadata:{}};n&&a.links.push(...n),r&&(a.tags=Ce([...a.tags,...r])),i&&(a.metadata=this.mergeMetadata(a.metadata,i)),this.mergedData.set(e,a)}}applyExtended(e){let t=this.mergedData.get(e.id);if(!t)return e;let r=t.links;e.links&&e.links.length>0&&(r=[...e.links,...r]);let i=t.tags;e.tags&&e.tags.length>0&&(i=Ce([...e.tags,...i]));let a=t.metadata;return e.metadata&&(a=this.mergeMetadata(e.metadata,t.metadata)),{...e,tags:v(i,1)?i:null,links:v(r,1)?r:null,...!n(a)&&{metadata:a}}}};function Bh(e,t,r){let o=new Ih(r,{inferTechFromIcon:t.config.inferTechnologyFromIcon??!0});o.projectId===t.id&&e.likec4.LastSeen.rememberSpecification(o);let s=ae(o.specs.colors,e=>Nr(e.color)),c=new Set,u=new zh,d=new zh,f=r.flatMap(e=>e.c4ExtendRelations),p=new Set,m=e=>{e?.metadata&&Ae(e.metadata).forEach(e=>c.add(e))},g=y(r,l(e=>(u.merge(e.c4ExtendElements),x(e.c4Elements,o.toModelElement))),b(i),li,ce((e,t)=>{let n=oi(t.id);return n&&a(e[n])?(B.debug`No parent found for ${t.id}`,e):(e[t.id]=u.applyExtended(t),m(e[t.id]),e)},{})),_=y(r,l(e=>x(e.c4Relations,o.toModelRelation)),b(e=>{if(!e)return!1;let t=F.flatten(e.source),n=F.flatten(e.target);return a(g[t])&&!Sr(t)||a(g[n])&&!Sr(n)?(B.debug`Invalid relation ${e.id}
|
|
1216
|
-
source: ${t} resolved: ${!!g[t]}
|
|
1217
|
-
target: ${n} resolved: ${!!g[n]}\n`,!1):!0}),x(e=>{let t=wp(`extend-relation`,F.flatten(e.source),F.flatten(e.target),e.kind??`default`,e.title??``),r=f.filter(e=>e.id===t);if(r.length===0)return e;r.forEach(e=>p.add(e.astPath));let i=e.tags?[...e.tags]:[],a=e.links?[...e.links]:[],o=e.metadata?{...e.metadata}:{};for(let e of r){if(e.tags&&i.push(...e.tags),e.links)for(let t of e.links)a.some(e=>e.url===t.url&&(e.title||``)===(t.title||``))||a.push(t);if(e.metadata)for(let[t,n]of Object.entries(e.metadata)){let e=o[t];if(e===void 0)o[t]=n;else{let r=Array.isArray(e)?e:[e],i=Array.isArray(n)?n:[n],a=Ce([...r,...i]);o[t]=a.length===1?a[0]:a}}}let s=Ce(i),c=a;return{...e,...v(s,1)&&{tags:s},...v(c,1)&&{links:c},...!n(o)&&{metadata:o}}}),ne(m),h(De(`id`))),ee=y(r,l(e=>(d.merge(e.c4ExtendDeployments),x(e.c4Deployments,o.toDeploymentElement))),b(i),li,ce((e,t)=>{let n=oi(t.id);return n&&a(e[n])?(B.debug`No parent found for deployment element ${t.id}`,e):(e[t.id]=vr(t)?d.applyExtended(t):t,m(e[t.id]),e)},{})),te=y(r,l(e=>x(e.c4DeploymentRelations,o.toDeploymentRelation)),b(e=>e?a(ee[e.source.deployment])||a(ee[e.target.deployment])?(B.debug`Invalid deployment relation ${e.id}
|
|
1218
|
-
source: ${e.source.deployment} resolved: ${!!ee[e.source.deployment]}
|
|
1219
|
-
target: ${e.target.deployment} resolved: ${!!ee[e.target.deployment]}\n`,!1):!0:!1),ce((e,t)=>he(e[t.id])?(B.debug`Duplicate deployment relation ${t.id}`,e):(m(t),e[t.id]=t,e),{}));function re(e){let n=e.uri.toString();return e=>{let{id:r,title:i,description:o,astPath:s,...c}=e;return e[Lr]===`element`&&a(i)&&`viewOf`in e&&(i=g[e.viewOf]?.title??null),a(i)&&r===`index`&&(i=`Landscape view`),{...pe(c,e=>e===void 0),[Ir]:`parsed`,sourcePath:T.relative(t.folderUri,n),docUri:n,description:o,title:i,id:r}}}let ie=r.flatMap(e=>x(e.c4Views,re(e)));if(ie.some(e=>e.id===`index`)||ie.unshift({[Ir]:`parsed`,[Lr]:`element`,id:`index`,title:`Landscape view`,description:null,rules:[{include:[{wildcard:!0}]}]}),t.config.implicitViews===!0){let e=new Set;for(let t of ie)t[Lr]===`element`&&`viewOf`in t&&t.viewOf&&e.add(t.viewOf);let t=new Set(ie.map(e=>e.id));for(let n of Ae(g)){if(e.has(n)||Sr(n))continue;let r=`__`+n.replaceAll(`.`,`_`);t.has(r)||(t.add(r),ie.push({[Ir]:`parsed`,[Lr]:`element`,id:r,viewOf:n,title:`Auto / ${(g[n]?.title??n).replaceAll(`
|
|
1220
|
-
`,` `)}`,description:null,rules:[{include:[{wildcard:!0}]}]}))}}let oe=y(ie,h(De(`id`)));ie.some(Br)&&(oe=Pi(oe));for(let e of f)p.has(e.astPath)||B.warn(`Relation extend at ${e.astPath} does not match any relation in the model`);return{data:{[Ir]:`parsed`,projectId:t.id,project:Rr({id:t.id,title:t.config.title??t.config.name,styles:t.config.styles,manualLayouts:t.config.manualLayouts,inferTechnologyFromIcon:t.config.inferTechnologyFromIcon}),specification:{tags:o.tags,elements:o.specs.elements,relationships:ae(o.specs.relationships,({notation:e,technology:t,...n})=>({...e&&{notation:e},...t&&{technology:t},style:n})),deployments:o.specs.deployments,...c.size>0&&{metadataKeys:[...c].sort(Kr)},customColors:s},elements:g,relations:_,globals:o.globals,views:oe,deployments:{elements:ee,relations:te},imports:{}},imports:o.imports}}const Vh=B.getChild(`builder`);var Hh=class extends lo{projects;parser;listeners=[];cache;DocumentBuilder;manualLayouts;mutex;lastSeen;constructor(e){super(),this.services=e,this.projects=e.shared.workspace.ProjectsManager,this.parser=e.likec4.ModelParser,this.DocumentBuilder=e.shared.workspace.DocumentBuilder,this.mutex=e.shared.workspace.WorkspaceLock,this.manualLayouts=e.shared.workspace.ManualLayouts,this.lastSeen=e.likec4.LastSeen,this.cache=new Uh(e),this.onDispose(this.cache,this.DocumentBuilder.onUpdate((e,t)=>{t.length>0&&this.notifyListeners(t)}),e.shared.workspace.WorkspaceManager.onForceCleanCache(()=>{this.clearCache()}),this.manualLayouts.onManualLayoutUpdate(({projectId:e})=>{this.notifyListeners(e)}));let t=le(s(),b(e=>co(e)&&!this.projects.isExcluded(e)),x(e=>e.uri));this.onDispose(this.DocumentBuilder.onBuildPhase(S.Validated,(e,n)=>{let r=t(e);r.length>0&&this.notifyListeners(r)})),Vh.debug`created`}unsafeSyncParseModelData(e){return this.cache.parsedData(e,()=>{let t=Vh.getChild(e);try{let n=this.projects.getProject(e),r=this.documents(e);return r.length===0?(t.debug`unsafeSyncParseModelData: skipped due to no documents`,null):(t.debug`unsafeSyncParseModelData: completed`,Bh(this.services,n,r))}catch(t){return Vh.warn(`unsafeSyncParseModelData failed for project ${e}`,{err:t}),null}})}unsafeSyncJoinedModelData(e){return this.cache.parsedJoinedData(e,()=>{let t=Vh.getChild(e),n=this.unsafeSyncParseModelData(e);if(!n)return null;if(n.imports.size===0)return n.data;t.debug`processing imports of ${e}`;let r=[...n.imports.associations()].reduce((e,[t,n])=>{if(n.size===0)return e;let r=this.unsafeSyncParseModelData(t);if(r){let i=[...n].flatMap(e=>r.data.elements[e]??[]);v(i,1)&&(e[t]=structuredClone(i))}return e},{});return{...n.data,imports:r}})}async parseModel(e,t){e=this.projects.ensureProjectId(e);let n=Dp();return await this.mutex.read(async()=>(t?.isCancellationRequested&&await bt(t),this.cache.parsedModel(e,()=>{let t=Vh.getChild(e),r=this.unsafeSyncJoinedModelData(e);return r?(t.debug`parseModel in ${n.pretty}`,Jn.create(r)):(t.debug`parseModel: returning EMPTY`,Jn.EMPTY.asParsed)})))}unsafeSyncComputeModel(e,t){return this.cache.computedModel(e,t??null,()=>{let n=Vh.getChild(e),r=this.unsafeSyncJoinedModelData(e);if(!r)return n.debug`unsafeSyncComputeModel: returning EMPTY`,Jn.EMPTY.asComputed;let i=Jn.create(r),a=[];for(let e of Te(r.views)){let r=Ni(e,i);if(!r.isSuccess){n.warn(L(r.error));continue}t?.views[e.id]&&Object.assign(r.view,{hasManualLayout:!0}),a.push(r.view)}Rh(a);let o={...r,manualLayouts:{...t?.views},[sr]:`computed`,views:h(a,De(`id`))};return n.debug(`unsafeSyncComputeModel${t?` with manual layouts`:``}: completed`),this.lastSeen.rememberModel(Jn.create(o))})}async computeModel(e,t){e=this.projects.ensureProjectId(e);let n=Vh.getChild(e),r=Dp();return await this.mutex.read(async()=>{t?.isCancellationRequested&&await bt(t);let i=this.projects.getProject(e),a=await this.manualLayouts.read(i),o=this.unsafeSyncComputeModel(e,a);return o===Jn.EMPTY?n.debug(`computeModel returned EMPTY`):r.ms>10&&n.debug(`computeModel completed in ${r.pretty}`),o})}onModelParsed(e){return this.listeners.push(e),vt.create(()=>{let t=this.listeners.indexOf(e);t>=0&&this.listeners.splice(t,1)})}clearCache(){Vh.debug(`clearCache`),this.cache.clear()}documents(e){return this.parser.documents(e).toArray()}notifyListeners(e){let t;t=p(e)?y(e,_(e=>this.projects.ownerProjectId(e)),u()):[[e,[]]];for(let e of this.listeners)try{for(let[n,r]of t)e(n,r)}catch(e){Vh.warn(L(e))}}},Uh=class extends Vt{constructor(e){super(e=>typeof e==`string`?e:e.id),this.toDispose.push(e.shared.workspace.DocumentBuilder.onDocumentPhase(S.Validated,t=>{let n=e.shared.workspace.ProjectsManager.ownerProjectId(t);this.clear(n)})),this.toDispose.push(e.shared.workspace.DocumentBuilder.onUpdate((t,n)=>{if(n.length>0){let t=e.shared.workspace.ProjectsManager,r=Ce(x(n,t.ownerProjectId.bind(t)));for(let e of r)this.clear(e)}}))}parsedData(e,t){return super.get(e,`parsed-data`,t)}parsedJoinedData(e,t){return super.get(e,`parsed-joined-data`,t)}parsedModel(e,t){return super.get(e,`parsed-model`,t)}computedModel(e,t,n){return super.get(e,`computed-model-${t?.hash??``}`,n)}};const{findNodeForKeyword:Wh,findNodeForProperty:Gh}=en,{getDocument:Kh,streamAllContents:qh}=kt,Jh=B.getChild(`locator`);var Yh=class{fqnIndex;deploymentsIndex;langiumDocuments;parser;projects;constructor(e){this.services=e,this.fqnIndex=e.likec4.FqnIndex,this.deploymentsIndex=e.likec4.DeploymentsIndex,this.langiumDocuments=e.shared.workspace.LangiumDocuments,this.parser=e.likec4.ModelParser,this.projects=e.shared.workspace.ProjectsManager}documents(e){return this.parser.documents(e)}getParsedElement(...e){try{let t,n;if(e.length===2?(t=e[0],n=e[1]):(t=e[0],n=ke(t)?this.projects.ensureProjectId():G(t)),ke(t)){let e=t,r=this.fqnIndex.byFqn(n,e).head();if(!r)return null;let i=this.langiumDocuments.getDocument(r.documentUri),a=this.findParsedElementByFqnIn(e,i);return a&&i?{projectId:n,element:a,document:i}:null}let r=this.fqnIndex.getFqn(t),i=Kh(t),a=this.findParsedElementByFqnIn(r,i);return a&&i?{projectId:n,element:a,document:i}:null}catch(e){return Jh.debug(L(e)),null}}findParsedElementByFqnIn(e,t){if(t)return this.parser.parse(t).c4Elements.find(t=>t.id===e)}locateElement(e,t){let[n,r]=kr(e);n??=this.projects.ensureProjectId(t);let i=this.fqnIndex.byFqn(n,r).head(),a=i?.nameSegment??i?.selectionSegment;return!i||!a?null:{uri:i.documentUri.toString(),range:a.range}}locateDeploymentElement(e,t){let n=this.projects.ensureProjectId(t),r=e,i=this.deploymentsIndex.byFqn(n,r).head(),a=i?.nameSegment??i?.selectionSegment;return!i||!a?null:{uri:i.documentUri.toString(),range:a.range}}locateRelation(e,t){let n=this.projects.ensureProjectId(t);for(let t of this.documents(n)){let n=t.c4Relations.find(t=>t.id===e)??t.c4DeploymentRelations.find(t=>t.id===e);if(!n)continue;let r=this.services.workspace.AstNodeLocator.getAstNode(t.parseResult.value,n.astPath);if(!Eu(r)&&!Xs(r))continue;let i=r.kind?Gh(r.$cstNode,`kind`):void 0;if(i??=r.dotKind?Gh(r.$cstNode,`dotKind`):void 0,i??=Wh(r.$cstNode,`->`),i??=Gh(r.$cstNode,`title`),i??=Gh(r.$cstNode,`target`),i??=r.$cstNode,i)return{uri:t.uri.toString(),range:{start:i.range.start,end:i.range.start}}}return null}locateViewAst(e,t){let n=this.projects.ensureProjectId(t);for(let t of this.documents(n)){let n=t.c4Views.find(t=>t.id===e);if(!n)continue;let r=this.services.workspace.AstNodeLocator.getAstNode(t.parseResult.value,n.astPath);if(zo(r))return{doc:t,view:n,viewAst:r}}return null}locateView(e,t){let n=this.locateViewAst(e,t);if(!n)return null;let r=n.viewAst,i=r.name?Gh(r.$cstNode,`name`):void 0;return i??=Wh(r.$cstNode,`view`),i??=r.$cstNode,i?{uri:n.doc.uri.toString(),range:{start:i.range.start,end:i.range.start}}:null}async locateDocumentTags(e,t){let n=this.langiumDocuments.getDocument(e);if(!n||!n.likec4ProjectId)return null;n.state<S.Linked&&(Jh.debug(`Waiting for document ${n.uri.path} to be Linked`),await this.services.shared.workspace.DocumentBuilder.waitUntil(S.Linked,n.uri,t));let r=G(n);Jh.trace`locate document tags for ${n.uri.fsPath} in project ${r}`;try{let e=this.services.likec4.LastSeen.specification(r)?.tags,t=this.services.likec4.LastSeen.styles(r)??Ar.DEFAULT;if(!e)return Jh.trace(`No specification or styles found for project ${r}, cannot locate tags for document ${n.uri.fsPath}`),null;let i=y(qh(n.parseResult.value),Xr(e=>hd(e)||_d(e)),di(),l(n=>{let r,i;try{hd(n)?(r=n.name,i=n.$cstNode):(r=n.tag.$refText,i=n.tag.$refNode);let a=e[r];return I(a,`Tag ${r} not found in merged specification`),I(i,`Tag ${r} does not have a $cstNode`),{name:r,color:t.tagColor(a.color).fill,range:i.range,isSpecification:hd(n)}}catch(e){return Jh.warn(`Fail on tag ${r}`,{err:e}),[]}}));return Jh.debug(`Found ${i.length} tags in document ${n.uri.path}`),i}catch(e){return Jh.warn(L(e)),null}}locateDynamicViewStep(e){let{doc:t,viewAst:n}=this.locateViewAst(e.view,e.projectId)??{};if(!t||!n)return null;if(!uc(n)||!n.body)return Jh.warn(`View ${e.view} is not a dynamic view`),null;let r=this.services.workspace.AstNodeLocator.getAstNodePath(n.body)+e.astPath,i=this.services.workspace.AstNodeLocator.getAstNode(t.parseResult.value,r);if(!i||!wo(i))return Jh.warn(`Failed to locate dynamic view step ${r} in view ${e.view}`),null;let a=i.kind?Gh(i.$cstNode,`kind`):void 0;return a??=i.dotKind?Gh(i.$cstNode,`dotKind`):void 0,a??=Wh(i.$cstNode,`->`),a??=Wh(i.$cstNode,`<-`),a??=Gh(i.$cstNode,`title`),a??=Gh(i.$cstNode,`target`),a??=i.$cstNode,a?{uri:t.uri.toString(),range:{start:a.range.start,end:a.range.start}}:null}};const Xh=[`this`,`it`,`self`,`super`,`likec4lib`,`global`];function Y(e){return async function t(n,r,i){try{let t=e(n,r,i);te(t)&&await t;return}catch(e){let t=e instanceof Error?e.message:String(e);r(`error`,`Validation failed: ${t}`,{node:n}),B.debug(`Validation failed: ${t}`,{error:e})}}}const{getDocument:Zh}=kt,Qh=e=>{let t=e.likec4.DeploymentsIndex,n=e.references.NameProvider;return Y((e,r)=>{let i=n.getName(e);if(!i){r(`error`,`DeploymentNode must be named`,{node:e});return}let a=Dr(n.getNameNode(e),`name CstNode not found`).range;Xh.includes(i)&&r(`error`,`Reserved word: ${i}`,{node:e,range:a});let o=G(e),s=t.getFqn(e);t.byFqn(o,s).limit(2).toArray().length>1&&r(`error`,`Duplicate node name "${s}"`,{node:e,range:a})})},$h=e=>{let t=e.likec4.DeploymentsIndex,n=e.references.NameProvider;return Y((e,r)=>{let i=n.getName(e);if(!i){r(`error`,`Deployed instance must be named, unique inside node`,{node:e});return}let a=Dr(n.getNameNode(e),`name CstNode not found`).range;Xh.includes(i)&&r(`error`,`Reserved word: ${i}`,{node:e,range:a});let o=G(e),s=t.getFqn(e);t.byFqn(o,s).limit(2).toArray().length>1&&r(`error`,`Duplicate instance name "${s}"`,{node:e,range:a})})},eg=e=>{let t=e.likec4.ModelParser;return Y((e,n)=>{if(!e.target?.value?.ref){n(`error`,`DeploymentRelation target '${e.target?.$cstNode?.text??``}' not resolved`,{node:e,property:`target`});return}let r=Zh(e),i=t.forDocument(r),a;try{a=i._resolveDeploymentRelationSource(e)}catch(t){B.warn(L(t)),n(`error`,`DeploymentRelation source not resolved`,{node:e,property:`source`});return}if(M.isImportRef(a)){n(`error`,`DeploymentRelation cannot refer imported model (not implemented yet)`,{node:e,property:`source`});return}if(M.isModelRef(a)){n(`error`,`DeploymentRelation must refer deployment element`,{node:e,property:`source`});return}let o=i.parseFqnRef(e.target);if(M.isImportRef(o)){n(`error`,`DeploymentRelation cannot refer imported model (not implemented yet)`,{node:e,property:`target`});return}if(M.isModelRef(o)){n(`error`,`DeploymentRelation must refer deployment element`,{node:e,property:`target`});return}Tr(a.deployment,o.deployment)&&n(`error`,`Invalid parent-child relationship`,{node:e})})},tg=e=>Y((e,t)=>{let n=e.deploymentNode.value.ref;(!n||!Ws(n))&&t(`error`,`ExtendDeployment allows only DeploymentNode`,{node:e,property:`deploymentNode`})}),ng=e=>{let t=e.likec4.FqnIndex;return Y((e,n)=>{let r=Uf(e.source),i=r&&t.getFqn(r);i||n(`error`,`Source not found (not parsed/indexed yet)`,{node:e,property:`source`});let a=Uf(e.target),o=a&&t.getFqn(a);o||n(`error`,`Target not found (not parsed/indexed yet)`,{node:e,property:`target`}),i&&o&&(hr(i,o)||hr(o,i))&&n(`error`,`Invalid parent-child relationship`,{node:e})})},rg=e=>{let t=e.likec4.FqnIndex;return Y((e,n)=>{let r=e.source;hf(r)&&r.isBackward&&n(`error`,`Invalid chain after backward step`,{node:e});let i=Uf(e.target);i&&t.getFqn(i)||n(`error`,`Target not found (not parsed/indexed yet)`,{node:e,property:`target`})})},ig=e=>Y((e,t)=>{if(n(e.value)||e.value!==`diagram`&&e.value!==`sequence`){t(`error`,`Invalid display variant: "diagram" or "sequence" are allowed`,{node:e,property:`value`});return}jt(e,fc)||t(`error`,`Display mode can be defined only inside dynamic view`,{node:e})}),{getDocument:ag}=kt,og=e=>{let t=e.likec4.FqnIndex,n=e.workspace.AstNodeLocator;return Y((e,r)=>{let i=t.getFqn(e);if(!i){r(`error`,`Not indexed element`,{node:e,property:`name`});return}Xh.includes(e.name)&&r(`error`,`Reserved word: ${e.name}`,{node:e,property:`name`});let a=ag(e),o=a.uri,s=n.getAstNodePath(e),c=t.byFqn(G(a),i).filter(e=>e.documentUri!==o||e.path!==s).head();if(c){let t=c.documentUri!==o;r(`error`,`Duplicate element name ${e.name===i?e.name:e.name+` (`+i+`)`}`,{node:e,property:`name`,...t&&{relatedInformation:[{location:{range:c.nameSegment?.range??c.selectionSegment?.range,uri:c.documentUri.toString()},message:`conflicting element`}]}})}})},sg=e=>Y((e,t)=>{Jf(e.modelElement)&&t(`error`,`Only model elements allowed here`,{node:e,property:`modelElement`})}),{getDocument:cg}=kt,lg=e=>{let t=e.shared.workspace.ProjectsManager;return Y((e,n)=>{if(!t.all.includes(e.project)){n(`error`,`Imported project not found`,{node:e,property:`project`});return}let r=G(cg(e));if(e.project===r){n(`error`,`Imported project cannot be the same as the current project`,{node:e,property:`project`});return}})},ug=e=>Y((e,t)=>{let n=parseFloat(e.value);(isNaN(n)||n<0||n>100)&&t(`warning`,`Value ignored, must be between 0% and 100%`,{node:e,property:`value`})}),dg=e=>(e,t)=>{let n=e.$container;n.props.some(t=>Al(t)&&t!==e)&&t(`error`,`Icon must be defined once`,{node:e}),Pc(n)&&wc(n.$container)&&n.$container.props.some(e=>Al(e))&&t(`warning`,`Redundant as icon defined on element`,{node:e}),e.value?.startsWith(`file://`)&&t(`error`,`Icon URI must not start with file://`,{node:e,property:`value`})},fg=e=>(e,t)=>{if(e.$type===`HexColor`){if(e.hex===void 0||ke(e.hex)&&!e.hex.match(/^[a-fA-F0-9]+$/)){t(`error`,`Invalid HEX`,{node:e,property:`hex`});return}let n=o(e.hex)?e.hex.toString().length:e.hex.length;n!==6&&n!==3&&n!==8&&t(`error`,`Invalid value "${e.$cstNode?.text}", must be 3, 6 or 8 characters long`,{node:e,property:`hex`});return}if(e.$type===`RGBAColor`){if((!o(e.red)||e.red<0||e.red>255)&&t(`error`,`Invalid value, must be between 0 and 255`,{node:e,property:`red`}),(!o(e.green)||e.green<0||e.green>255)&&t(`error`,`Invalid value, must be between 0 and 255`,{node:e,property:`green`}),(!o(e.blue)||e.blue<0||e.blue>255)&&t(`error`,`Invalid value, must be between 0 and 255`,{node:e,property:`blue`}),o(e.alpha)&&(e.alpha<0||e.alpha>1)&&t(`error`,`Invalid value, must be between 0 and 1`,{node:e,property:`alpha`}),ke(e.alpha)){let n=parseFloat(e.alpha);(n<0||n>100)&&t(`error`,`Invalid value, must be between 0% and 100%`,{node:e,property:`alpha`})}return}P(e)},pg=e=>{let t=e.likec4.ModelParser;return Y((e,n)=>{let r=t.forDocument(rn(e)),i=Tp(()=>r._resolveRelationSource(e));if(!i){n(`error`,`Source not resolved`,{node:e,property:`source`});return}let a=Tp(()=>r.parseFqnRef(e.target));if(!a){n(`error`,`Target not resolved`,{node:e,property:`target`});return}M.isImportRef(i)&&(M.isImportRef(a)?n(`warning`,`Relationship between imported elements may not be visible in origin projects`,{node:e}):n(`warning`,`Relationship from imported element to local element may not be visible in origin project`,{node:e,property:`source`})),Tr(M.flatten(i),M.flatten(a))&&n(`error`,`Invalid parent-child relationship`,{node:e})})},mg=e=>Y((e,t)=>{e.$container.tags?.values&&e.tags?.values&&t(`error`,`Relation cannot have tags in both header and body`,{node:e.tags})}),hg=e=>{let t=e.likec4.ModelParser,n=new Bt(e.shared,S.Linked),r=({source:e,target:t,kind:n,title:r})=>wp(`extend-relation`,M.flatten(e),M.flatten(t),n??`default`,r??``);function i(t){return n.get(t,()=>new Set(y(e.shared.workspace.LangiumDocuments.projectDocuments(t).toArray(),l(e=>e.c4Relations??[]),x(e=>r(e)))))}return Y((e,n)=>{let a=rn(e),o=t.forDocument(a),s=Tp(()=>o.parseFqnRef(e.source));if(!s){n(`error`,`Source not resolved`,{node:e,property:`source`});return}let c=Tp(()=>o.parseFqnRef(e.target));if(!c){n(`error`,`Target not resolved`,{node:e,property:`target`});return}if(!M.isModelRef(s)&&!M.isImportRef(s)){n(`error`,`Source must reference a model element`,{node:e,property:`source`});return}if(!M.isModelRef(c)&&!M.isImportRef(c)){n(`error`,`Target must reference a model element`,{node:e,property:`target`});return}let l=G(a),u=(e.kind??e.dotKind?.kind)?.ref?.name??`default`,{title:d=``}=o.parseBaseProps({},{title:e.title}),f=r({source:s,target:c,kind:u,title:d});i(l).has(f)||n(`warning`,`This extend does not match any relation (by source, kind, target, title)`,{node:e})})},gg=e=>Y((e,t)=>{e.$containerIndex&&e.$containerIndex>0&&t(`warning`,`Prefer one specification per document`,{node:e,property:`name`})}),_g=e=>Y((e,t)=>{e.$containerIndex&&e.$containerIndex>0&&t(`warning`,`Prefer one model per document`,{node:e,property:`name`})}),vg=e=>Y((e,t)=>{e.$containerIndex&&e.$containerIndex>0&&t(`warning`,`Prefer one global block per document`,{node:e,property:`name`})}),yg=e=>{let t=e.shared.workspace.IndexManager;return Y((e,n)=>{Xh.includes(e.name)&&n(`error`,`Reserved word: ${e.name}`,{node:e,property:`name`});let r=G(e),i=t.projectElements(r,Tc).filter(t=>t.name===e.name&&t.node!==e).head();if(i){let t=i.documentUri!==rn(e).uri;n(`error`,`Duplicate element kind '${e.name}'`,{node:e,property:`name`,...t&&{relatedInformation:[{location:{range:i.nameSegment.range,uri:i.documentUri.toString()},message:`conflicting definition`}]}})}})},bg=e=>{let t=e.shared.workspace.IndexManager;return Y((e,n)=>{Xh.includes(e.name)&&n(`error`,`Reserved word: ${e.name}`,{node:e,property:`name`});let r=G(e),i=t.projectElements(r,qs).filter(t=>t.name===e.name&&t.node!==e).head();if(i){let t=i.documentUri!==rn(e).uri;n(`error`,`Duplicate deploymentNode kind '${e.name}'`,{node:e,property:`name`,...t&&{relatedInformation:[{location:{range:i.nameSegment.range,uri:i.documentUri.toString()},message:`conflicting definition`}]}})}})},xg=e=>{let t=e.shared.workspace.IndexManager;return Y((e,n)=>{let r=e.name,i=G(e),a=t.projectElements(i,`Tag`).filter(t=>t.name===r&&t.node!==e).head();if(a){let t=a.documentUri!==rn(e).uri;n(`error`,`Duplicate tag '${e.name}'`,{node:e,property:`name`,...t&&{relatedInformation:[{location:{range:a.nameSegment.range,uri:a.documentUri.toString()},message:`conflicting definition`}]}})}})},Sg=e=>{let t=e.shared.workspace.IndexManager;return Y((e,n)=>{Xh.includes(e.name)&&n(`error`,`Reserved word: ${e.name}`,{node:e,property:`name`});let r=G(e);t.projectElements(r,Lu).filter(t=>t.name===e.name).limit(2).count()>1&&n(`error`,`Duplicate RelationshipKind '${e.name}'`,{node:e,property:`name`})})},Cg=e=>{let t=e.shared.workspace.IndexManager;return Y((e,n)=>{let r=G(e),i=t.projectElements(r,ml),a=t.projectElements(r,fl);i.concat(a).filter(t=>t.name===e.name).limit(2).count()>1&&n(`error`,`Duplicate GlobalPredicateGroup or GlobalDynamicPredicateGroup name '${e.name}'`,{node:e,property:`name`})})},wg=e=>{let t=e.shared.workspace.IndexManager;return Y((e,n)=>{let r=G(e);t.projectElements(r,Sl).filter(t=>t.name===e.name).limit(2).count()>1&&n(`error`,`Duplicate GlobalStyleId name '${e.name}'`,{node:e,property:`name`})})},Tg=/@likec4-generated/,Eg=e=>{let t=e.shared.workspace.IndexManager;return Y((e,n)=>{let r=It(e.$cstNode,[`BLOCK_COMMENT`]);if(r&&Tg.test(r.text)&&n(`warning`,`ManualLayoutV1 is no longer supported; remove this block`,{node:e,range:r.range}),!e.name)return;Xh.includes(e.name)&&n(`error`,`Reserved word: ${e.name}`,{node:e,property:`name`});let i=G(e);t.projectElements(i,Ro).filter(t=>t.name===e.name).limit(2).count()>1&&n(`error`,`Duplicate view '${e.name}'`,{node:e,property:`name`})})};function Dg(e){let t=[],n=e;for(;n;)n.value&&t.push(n.value),n=n.prev;return t.reverse()}const Og=e=>Y((e,t)=>{let n=Dg(e.targets);n.length<2&&e.value===`same`&&t(`warning`,`Rank rule should have at least 2 targets`,{node:e,property:`targets`});let r=n.filter(dl),i=r[0]?.ref?.parent;for(let n=1;n<r.length;n++){let a=r[n];e.value===`same`&&!kg(i,a?.ref?.parent)&&t(`error`,`All targets must have the same parent rank same`,{node:e,property:`targets`})}});function kg(e,t){return!e&&!t?!0:!e||!t||e.value.ref!==t.value.ref?!1:kg(e.parent,t.parent)}const Ag=e=>{let t=e.likec4.ModelParser;return Y((e,n)=>{let r=Lf(e);if(r?.$type!==`DynamicViewIncludePredicate`&&r?.isInclude!==!0){n(`error`,`Invalid usage inside "exclude"`,{node:e});return}let i=r.$type===`DynamicViewIncludePredicate`,a=t.forDocument(rn(r)),o=Fr.unwrap(a.parseFqnExprWith(e).custom.expr);switch(!0){case Fr.isWildcard(o)&&i:case Fr.isElementKindExpr(o)&&i:case Fr.isElementTagExpr(o)&&i:n(`warning`,`Predicate is ignored, as not supported in dynamic views`,{node:e});return;case Fr.isWildcard(o):case Fr.isModelRef(o):case Fr.isDeploymentRef(o):return;case Fr.isElementKindExpr(o):case Fr.isElementTagExpr(o):n(`error`,`Invalid target (expect reference to specific element)`,{node:e,property:`subject`});return;default:ri(o)}})},jg=e=>{let t=e.likec4.ModelParser;return Y((e,n)=>{let r=t.forDocument(rn(e)).parseFqnRefExpr(e),a=Lf(e),o=Hf(e)&&!jt(e,e=>oc(e)||Id(e));if(a?.$type===`DeploymentViewRulePredicate`||o){if(!jt(e,Ko)){if(Fr.isModelRef(r)){n(`error`,`Deployment view predicate must reference deployment model`,{node:e});return}if(Fr.isDeploymentRef(r)&&F.isInsideInstanceRef(r.ref)){n(`error`,`Must reference deployment nodes or instances, but not internals`,{node:e});return}}i(e.selector)&&!Ws(e.ref.value?.ref)&&n(`warning`,`Selector '${e.selector}' applies to deployment nodes only, ignored here`,{node:e,property:`selector`});return}if(a?.$type===`DynamicViewIncludePredicate`)switch(!0){case Fr.isElementKindExpr(r):case Fr.isElementTagExpr(r):case Fr.isWildcard(r):n(`warning`,`Predicate is ignored, as not supported in dynamic views`,{node:e});return}})},Mg=e=>Y((e,t)=>{e.to.$type===`WildcardExpression`&&!Bl(e.$container)&&a(Ut(e,Rc)?.viewOf)&&t(`warning`,`Predicate is ignored as it concerns all relationships`,{node:e})}),Ng=e=>Y((e,t)=>{if(Lf(e)?.$type===`ViewRulePredicate`&&e.$container.$type!==`DirectedRelationExpr`&&e.from.$type===`WildcardExpression`){let n=Ut(e,Rc);n&&a(n.viewOf)&&t(`warning`,`Predicate is ignored as it concerns all relationships`,{node:e})}}),Pg=e=>{let t=e.likec4.ModelParser;return Y((e,n)=>{let r=Ut(e,ic);if(!r||r.isInclude!==!0)return;let i=rn(e),a=t.forDocument(i),o=ir.unwrap(a.parseRelationExpr(e)),s=`Model reference is allowed in exclude predicate only`;if(ir.isDirect(o)){(er.isModelRef(o.source)||er.isModelRef(o.target))&&n(`error`,s,{node:e});return}let c;if(c=ir.isIncoming(o)?o.incoming:ir.isOutgoing(o)?o.outgoing:o.inout,er.isModelRef(c)){n(`error`,s,{node:e});return}})},Fg=e=>Y((e,t)=>{let n=Lf(e);if(!(!n||n.$type==`DynamicViewIncludePredicate`)&&!n.isInclude){t(`error`,`Invalid usage inside "exclude"`,{node:e});return}});var Ig=class extends it{constructor(e){super(e),this.services=e}async validateDocument(e,t,n){return this.services.shared.workspace.ProjectsManager.isExcluded(e)?[]:await super.validateDocument(e,t,n)}};Qt();const Lg=zr(Il,Pl,_l,hl,pl,yl,xl,sl,Mu,Mo,Ko,bc,pf,hf,yo,ic,Oo,Ko,dl,ss,as,yd,ls,So,zo,ds,Bs,Ws,Xs,$o,mc,iu,Vo,Eu,Ou,Eo,rs,mu,H,wc,Pc,Ac,Yc,Zc,Gc,qc,$c,tl,ed,id,Qu,ud,Xu,cd,Uc,mo),Rg=e=>{let t=e;for(;t&&!Wl(t);){if(Lg(t))return t;t=t.$container}};function zg(e){let t=e.state>=S.Validated?e.diagnostics?.filter(e=>e.severity===xt.Error)??[]:[],n=new WeakSet;for(let{node:e}of t){if(a(e)||n.has(e))continue;n.add(e);let t=Rg(e);t&&n.add(t)}let r=e=>!n.has(e);return{isValid:r,invalidNodes:n}}function Bg(e){B.debug(`registerValidationChecks`),e.validation.ValidationRegistry.register({DeployedInstance:$h(e),DeploymentNodeKind:bg(e),DeploymentNode:Qh(e),DeploymentRelation:eg(e),ExtendDeployment:tg(e),ExtendRelation:hg(e),FqnRefExpr:jg(e),RelationExpr:Pg(e),OpacityProperty:ug(e),IconProperty:dg(e),SpecificationRule:gg(e),Model:_g(e),Globals:vg(e),GlobalPredicateGroup:Cg(e),GlobalDynamicPredicateGroup:Cg(e),GlobalStyleId:wg(e),DynamicStepSingle:ng(e),DynamicStepChain:rg(e),LikeC4View:Eg(e),Element:og(e),ElementRef:sg(e),ElementKind:yg(e),Relation:pg(e),RelationBody:mg(e),Tag:xg(e),FqnExprWith:Ag(e),RelationExprWith:Fg(e),RelationshipKind:Sg(e),IncomingRelationExpr:Mg(e),OutgoingRelationExpr:Ng(e),ImportsFromPoject:lg(e),ColorLiteral:fg(e),DynamicViewDisplayVariantProperty:ig(e),ViewRuleRank:Og(e)});let t=e.shared.lsp.Connection;t&&ai(()=>{e.shared.workspace.DocumentBuilder.onUpdate((e,n)=>{for(let e of n)B.debug(`clear diagnostics for deleted ${e.path}`),t.sendDiagnostics({uri:e.toString(),diagnostics:[]}).catch(e=>B.error(L(e)))})})}const Vg=B.getChild(`parser`);function Hg(e){if(e==null)return;let t=X(e);return ke(t)?t.split(`
|
|
1221
|
-
`).join(` `):`md`in t?{md:t.md.split(`
|
|
1222
|
-
`).join(` `)}:{txt:t.txt.split(`
|
|
1223
|
-
`).join(` `)}}function X(e){if(e!=null)switch(!0){case ke(e):return Gn(e).trim();case Ql(e)&&ke(e.markdown):return{md:Gn(e.markdown).trim()};case Ql(e)&&ke(e.text):return{txt:Gn(e.text).trim()};case Ql(e):return{txt:``};default:return}}var Ug=class{isValid;constructor(e,t,n){this.services=e,this.doc=t,this.project=n,this.isValid=zg(t).isValid}logError(e,t,n){let r=e instanceof Error?e.message:typeof e==`string`?e:String(e);if(Dt(t)){let e=this.services.references.NameProvider.getName(t);e=e?`"${e}" (${t.$type})`:`${t.$type}`;let n=t.$cstNode,i=n?`:${n.range.start.line+1}:${n.range.start.character+1}`:``;r+=`\n\tat ${e} (${this.doc.uri.fsPath}${i})`}else t&&`$refText`in t&&(r+=`\n\tat reference "${t.$refText}" (${this.doc.uri.fsPath})`);n&&n!==`base`?Vg.getChild(n).debug(r):Vg.debug(r)}tryParse(e,t,n){try{return!t||!this.isValid(t)?void 0:n(t)}catch(n){this.logError(n,t,e);return}}tryMap(e,t,n){return l(t,t=>this.tryParse(e,t,n)??[])}resolveFqn(e){if(Pl(e)){let t=G(e),n=this.resolveFqn(Dr(e.imported.ref,`FqnRef is empty of imported: ${e.$cstNode?.text}`));return this.doc.c4Imports.set(t,n),tr(t,n)}return Yc(e)?Wf(e.element):Gc(e)?Wf(e.deploymentNode):go(e)?this.services.likec4.DeploymentsIndex.getFqn(e):this.services.likec4.FqnIndex.getFqn(e)}getAstNodePath(e){return this.services.workspace.AstNodeLocator.getAstNodePath(e)}getMetadata(e){if(!e||!this.isValid(e)||n(e.props))return;let t=e=>{if(Ql(e)){let t=X(e);if(!t)return[];if(typeof t==`string`)return i(t)?[t]:[];{let e=t.md||t.txt;return i(e)?[e]:[]}}else if(eu(e))return e.values.map(e=>X(e)).map(e=>typeof e==`string`?e:e.md||e.txt).filter(i);return[]},r=y(e.props,l(e=>e.value?t(e.value).map(t=>[e.key,t]):[[e.key,String(e.boolValue)]]),b(([e,t])=>i(t)));if(n(r))return;let a=y(r,_(([e])=>e),ae(e=>e.map(([e,t])=>t))),o={};for(let[e,t]of Object.entries(a))t&&t.length>0&&(o[e]=t.length===1?t[0]:t);return n(o)?void 0:o}parseMarkdownOrString(e){if(Ql(e))return X(e)}convertTags(e){return this.parseTags(e)}parseTags(e){let t=e?.tags;if(!t)return null;let n=[];for(;t;)n.push(...this.tryMap(`base`,t.values,e=>Dr(e.tag.ref,`Tag reference is not resolved`).name).filter(i)),t=t.prev;return Cr(n)?Ce(n):null}convertLinks(e){return this.parseLinks(e)}parseLinks(e){if(!e?.props||e.props.length===0)return;let t=this.tryMap(`base`,b(e.props,Xl),e=>{let t=e.value;if(ge(t))return;let n=i(e.title)?Hg(e.title):void 0,r=this.services.lsp.DocumentLinkProvider.relativeLink(this.doc,t);return pr({url:t,title:n,relative:r&&r!==t?r:void 0})});return Cr(t)?t:void 0}parseIconProperty(e){if(!e||!this.isValid(e))return;let{libicon:t,value:n}=e;switch(!0){case!!t:{let n=t.ref?.name;if(!n){this.logError(`Library icon ${t.$refText} is not a valid library icon`,e);return}return n}case n&&n===`none`:return n;case n&&Mn(n):if(n.startsWith(`file:`)){this.logError(`Icon property '${n}' used the 'file' protocol which is not supported`,e);return}return n;case n&&n.startsWith(`@`):return this.parseImageAlias(n);case n&&Dn(n):return wn(this.doc.uri.toString(),`../`,n);case n&&kn(n):return An(this.project.folderUri.toString(),n);default:this.logError(`Icon property '${n}' is not a valid URL, library icon, image alias or 'none'`,e);return}}parseImageAlias(e){let t=e.indexOf(`/`),n=t>0?e.substring(0,t):e,r=t>0?e.substring(t+1):``,i={"@":`./images`,...this.project.config.imageAliases}[n];if(!i){Vg.warn(`Image alias "${n}" not found in project configuration`);return}let a=r?An(i,r):i;return An(this.project.folderUri.toString(),a)}parseColorLiteral(e){if(this.isValid(e)){if(wl(e))return`#${e.hex}`;if(Wu(e)){let t=o(e.alpha)?e.alpha:void 0;return ke(e.alpha)&&(t=kf(e.alpha)/100),t===void 0?`rgb(${e.red},${e.green},${e.blue})`:`rgba(${e.red},${e.green},${e.blue},${t})`}P(e)}}parseElementStyle(e){if(!e)return{};if(p(e)){let t=this.parseStyleProps(e.find(Pc)?.props);try{let n=this.parseIconProperty(e.find(Al));n&&(t.icon=n)}catch(e){this.logError(e)}return t}return this.parseStyleProps(e.props)}parseStyleProps(e){let t={};if(!e||e.length===0)return t;for(let n of e)if(this.isValid(n))try{switch(!0){case js(n):i(n.value)&&(t.border=n.value);break;case Ns(n):{let e=Pf(n);i(e)&&(t.color=e);break}case Ku(n):i(n.value)&&(t.shape=n.value);break;case Al(n):{let e=this.parseIconProperty(n);i(e)&&(t.icon=e);break}case El(n):{let e=Pf(n);i(e)&&(t.iconColor=e);break}case Ml(n):i(n.value)&&(t.iconSize=jf(n));break;case Ol(n):i(n.value)&&(t.iconPosition=Mf(n));break;case bu(n):t.opacity=Af(n);break;case fu(n):t.multiple=f(n.value)?n.value:!1;break;case Ju(n):i(n.value)&&(t.size=jf(n));break;case wu(n):i(n.value)&&(t.padding=jf(n));break;case xd(n):i(n.value)&&(t.textSize=jf(n));break;default:P(n)}}catch(e){this.logError(e,n)}return pr(t)}parseBaseProps(e,t){let n=X(t?.title??Of(e.title)),r=t?.description?{txt:X(t.description)}:this.parseMarkdownOrString(e.description);return pr({title:n,summary:t?.summary?{txt:X(t.summary)}:this.parseMarkdownOrString(e.summary),description:r,technology:Hg(t?.technology)??X(Of(e.technology))})}};function*Wg(e){let t=rr.from(e.parseResult.value.deployments.flatMap(e=>e.elements)),n=[],r;for(;r=t.shift();){if(Xs(r)){n.push(r);continue}if(r.body&&r.body.elements.length>0)for(let e of r.body.elements)t.push(e);yield r}yield*n}function Gg(e){return class t extends e{parseDeployment(){let e=this.doc;for(let t of Wg(e))try{switch(!0){case Xs(t):this.isValid(t)&&e.c4DeploymentRelations.push(this.parseDeploymentRelation(t));break;case Bs(t):e.c4Deployments.push(this.parseDeployedInstance(t));break;case Ws(t):e.c4Deployments.push(this.parseDeploymentNode(t));break;case Gc(t):{let n=this.parseExtendDeployment(t);n&&e.c4ExtendDeployments.push(n);break}default:P(t)}}catch(e){this.logError(e,t,`deployment`)}}parseDeploymentNode(e){let t=this.isValid,n=this.resolveFqn(e),r=Dr(e.kind.ref,`DeploymentKind not resolved`).name,i=this.parseTags(e.body)??void 0,a=this.parseLinks(e.body),o=this.parseElementStyle(e.body?.props),s=this.getMetadata(e.body?.props.find(Vo)),c=y(e.body?.props??[],b(t),b(Mc),Oe(e=>[e.key,e.value])),{title:l,...u}=this.parseBaseProps(c,{title:e.title,summary:e.summary});return pr({id:n,kind:r,title:l??Er(n),...u,tags:i,links:a,style:o,metadata:s})}parseDeployedInstance(e){let t=this.isValid,n=this.resolveFqn(e),r=this.parseFqnRef(e.target.modelElement);N(M.isModelRef(r)||M.isImportRef(r),`Target must be a model reference`);let i=this.parseTags(e.body)??void 0,a=this.parseElementStyle(e.body?.props),o=this.getMetadata(e.body?.props.find(Vo)),s=y(e.body?.props??[],b(t),b(Mc),Oe(e=>[e.key,e.value])),c=this.parseBaseProps(s,{title:e.title,summary:e.summary});return pr({id:n,element:r,tags:i,links:this.parseLinks(e.body),...c,style:a,metadata:o})}parseExtendDeployment(e){let t=this.parseTags(e.body),r=this.getMetadata(e.body?.props.find(Vo)),i=this.parseLinks(e.body);return!t&&n(r??{})&&!i?null:pr({id:this.resolveFqn(e),astPath:this.getAstNodePath(e),metadata:r,tags:t,links:i})}_resolveDeploymentRelationSource(e){if(he(e.source))return this.parseFqnRef(e.source);if(e.$container.$type===`DeploymentNodeBody`||e.$container.$type===`DeployedInstanceBody`)return{deployment:this.resolveFqn(e.$container.$container)};throw Error(`RelationRefError: Invalid container for sourceless relation`)}parseDeploymentRelation(e){let t=this.isValid,n=this.getAstNodePath(e),r=this._resolveDeploymentRelationSource(e);N(M.isDeploymentRef(r),`Invalid source for deployment relation`);let a=this.parseFqnRef(e.target);N(M.isDeploymentRef(a),`Invalid target for deployment relation`);let o=this.convertTags(e)??this.convertTags(e.body)??void 0,s=this.convertLinks(e.body),c=(e.kind??e.dotKind?.kind)?.ref?.name,l=this.getMetadata(e.body?.props.find(Vo)),u=y(e.body?.props??[],b(Bu),b(e=>i(e.value)),Oe(e=>[e.key,e.value])),d=y(e.body?.props??[],b(Iu),re())?.value.view.ref?.name,f=this.parseBaseProps(u,{title:e.title}),p=e.body?.props.find(Hu);return pr({id:wp(`deployment`,n,r.deployment,a.deployment),source:r,target:a,...f,metadata:l,kind:c,tags:o,links:s,...Nf(p?.props,t),navigateTo:d,astPath:n})}}}function Kg(e){return class t extends e{parseDeploymentView(e){let t=e.body;N(t,`DynamicElementView body is not defined`);let n=t.props.filter(this.isValid),r=this.getAstNodePath(e),i=e.name;i||=`deployment_`+wp(this.doc.uri.toString(),r);let{title:a=null,description:o=null}=this.parseBaseProps(y(n,b(Rd),Oe(e=>[e.key,e.value]))),s=this.convertTags(t),c=this.convertLinks(t);return wf.writeId(e,i),{[Zn._type]:`deployment`,id:i,astPath:r,title:Hg(a)??null,description:o,tags:s,links:Cr(c)?c:null,rules:this.tryMap(`deployment`,t.rules,e=>this.parseDeploymentViewRule(e))}}parseDeploymentViewRule(e){if(ic(e))return this.parseDeploymentViewRulePredicate(e);if(wd(e))return Ff(e);if(oc(e))return this.parseDeploymentViewRuleStyle(e);P(e)}parseDeploymentViewRulePredicate(e){let t=[],n=e.expr;for(;n;){try{let e=n.value;m(e)&&this.isValid(e)&&t.unshift(this.parseExpressionV2(e))}catch(e){V(e)}n=n.prev}return e.isInclude?{include:t}:{exclude:t}}parseDeploymentViewRuleStyle(e){let t=this.parseStyleProps(e.props.filter(as)),n=X(Of(e.props.find(gu)?.value));return{targets:this.parseFqnExpressions(e.targets),style:t,...n&&{notation:n}}}}}const qg=({operator:e,not:t},n)=>e?.startsWith(`!=`)?{neq:n}:e?.startsWith(`=`)?{eq:n}:t?{neq:n}:{eq:n},Jg=({operator:e,not:t},n)=>e.startsWith(`!=`)?{neq:n}:e.startsWith(`=`)?{eq:n}:t?{neq:n}:{eq:n};function Yg(e){return!nf(e)&&!sf(e)&&!af(e)?null:e.participant}function Xg(e){switch(!0){case Es(e):{let t=e.value.tag.ref?.name,n=Yg(e);N(t,`Expected tag name`);let r={tag:Jg(e,t)};return n?{participant:n,operator:r}:r}case vs(e):{let t=e.value?.ref?.name,n=Yg(e);N(t,`Expected kind name`);let r={kind:Jg(e,t)};return n?{participant:n,operator:r}:r}case bs(e):{let t=e.key,n=Yg(e);N(t,`Expected metadata key`);let r={metadata:{key:t,...e.value==null?{}:{value:qg(e,String(e.value))}}};return n?{participant:n,operator:r}:r}case Kd(e)||ef(e):return{not:Xg(e.value)};case Bd(e):{let t=Xg(e.left),n=Xg(e.right);return Zg(e.operator.toLowerCase(),t,n)}default:P(e)}}function Zg(e,t,n){if(n===null)return t;switch(e){case`and`:{let e=[gr(t)?t.and:t,gr(n)?n.and:n].flat();return N(Cr(e),`Expected non-empty array`),{and:e}}case`or`:{let e=[wr(t)?t.or:t,wr(n)?n.or:n].flat();return N(Cr(e),`Expected non-empty array`),{or:e}}default:P(e)}}function Qg(e){return class t extends e{parseFqnRef(e){let t=Dr(e.value?.ref,()=>`Element "${e.$cstNode?.text}" is not resolved`);if(Pl(t)){let e={project:G(t),model:this.resolveFqn(Dr(t.imported.ref,`Imported "${t.$cstNode?.text}" is not resolved`))};return this.doc.c4Imports.set(e.project,e.model),e}if(H(t)){let n=qf(e);if(n){let e={project:G(n),model:this.resolveFqn(t)};return this.doc.c4Imports.set(e.project,e.model),e}let r=Kf(e);return r?{deployment:this.resolveFqn(r),element:this.resolveFqn(t)}:{model:this.resolveFqn(t)}}if(go(t))return{deployment:this.resolveFqn(t)};P(t)}parseExpressionV2(e){if(Io(e))return this.parseFqnExprOrWith(e);if(Xo(e))return this.parseRelationExprOrWith(e);P(e)}parseFqnExprOrWith(e){if(sl(e))return this.parseFqnExprWith(e);if(Po(e))return this.parseFqnExprOrWhere(e);P(e)}parseFqnExprWith(e){let t=this.parseFqnExprOrWhere(e.subject);return(e.custom?.props??[]).reduce((e,t)=>{if(!this.isValid(t))return e;if(mu(t)){let n=t.value.view.$refText;return i(n)&&(e.custom.navigateTo=n),e}if(vu(t)){let n=this.parseMarkdownOrString(t.value);return n&&(e.custom[t.key]=n),e}if(Mc(t)){if(t.key===`description`||t.key===`summary`){let n=this.parseMarkdownOrString(t.value);return n&&(e.custom.description=n),e}let n=X(Of(t.value));return n&&(e.custom[t.key]=n),e}if(Al(t)){let n=this.parseIconProperty(t);return he(n)&&(e.custom[t.key]=n),e}if(Ns(t)){let n=Pf(t);return he(n)&&(e.custom[t.key]=n),e}if(Ku(t)||js(t))return he(t.value)&&(e.custom[t.key]=t.value),e;if(bu(t))return he(t.value)&&(e.custom[t.key]=Af(t)),e;if(El(t)){let n=Pf(t);return he(n)&&(e.custom[t.key]=n),e}if(gu(t)){let n=i(t.value)?X(Of(t.value)):void 0;return n&&(e.custom[t.key]=n),e}if(fu(t))return f(t.value)&&(e.custom[t.key]=t.value),e;if(Ju(t)||xd(t)||wu(t)||Ml(t))return i(t.value)&&(e.custom[t.key]=jf(t)),e;if(Ol(t))return i(t.value)&&(e.custom[t.key]=t.value),e;P(t)},{custom:{expr:t}})}parseFqnExprOrWhere(e){if(al(e))return this.parseFqnExprWhere(e);if(Mo(e))return this.parseFqnExpr(e);P(e)}parseFqnExprWhere(e){return N(!al(e.subject),`FqnExprWhere is not allowed as subject of FqnExprWhere`),{where:{expr:this.parseFqnExpr(e.subject),condition:e.where?Xg(e.where):{kind:{neq:`--always-true--`}}}}}parseFqnExpr(e){if(df(e))return{wildcard:!0};if(Oc(e))return N(e.kind?.ref,`ElementKind "${e.$cstNode?.text}" is not resolved`),{elementKind:e.kind.ref.name,isEqual:e.isEqual};if(Ic(e))return N(e.tag.tag.ref,`Tag ${e.$cstNode?.text} is not resolved`),{elementTag:e.tag.tag.$refText,isEqual:e.isEqual};if(dl(e))return this.parseFqnRefExpr(e);P(e)}parseFqnRefExpr(e){let t=this.parseFqnRef(e.ref);switch(!0){case e.selector===`._`:return{ref:t,selector:`expanded`};case e.selector===`.**`:return{ref:t,selector:`descendants`};case e.selector===`.*`:return{ref:t,selector:`children`};default:return{ref:t}}}parseFqnExpressions(e){let t=[],n=e;for(;n;){try{m(n.value)&&this.isValid(n.value)&&t.push(this.parseFqnExpr(n.value))}catch(e){this.logError(e,n.value,`fqnref`)}n=n.prev}return t.reverse()}parseRelationExprOrWith(e){if(Mu(e))return this.parseRelationExprWith(e);if(Jo(e))return this.parseRelationExprOrWhere(e);P(e)}parseRelationExprWith(e){let t=this.parseRelationExprOrWhere(e.subject);return{customRelation:{...this.parseCustomRelationProperties(e.custom),expr:t}}}parseCustomRelationProperties(e){return(e?.props??[]).reduce((e,t)=>{if(vu(t)){let n=this.parseMarkdownOrString(t.value);return n&&(e[t.key]=n),e}if(Bu(t)||gu(t)){if(t.key===`description`){let n=this.parseMarkdownOrString(t.value);return n&&(e.description=n),e}let n=X(Of(t.value));return n&&(e[t.key]=n),e}if(ks(t))return i(t.value)&&(e[t.key]=t.value),e;if(Ns(t)){let n=Pf(t);return i(n)&&(e[t.key]=n),e}if(Jl(t))return i(t.value)&&(e[t.key]=t.value),e;if(Iu(t)){let n=t.value.view.ref?.name;return i(n)&&(e[t.key]=n),e}P(t)},{})}parseRelationExprOrWhere(e){if(Au(e))return this.parseRelationExprWhere(e);if(Ko(e))return this.parseRelationExpr(e);P(e)}parseRelationExprWhere(e){N(!Au(e.subject),`RelationExprWhere is not allowed as subject of RelationExprWhere`);let t=this.parseRelationExpr(e.subject),n=t.where?.expr??t,r=t.where?.condition,i=e.where?Xg(e.where):null,a;return a=i&&r?Zg(`and`,r,i):i??r??{kind:{neq:`--always-true--`}},{where:{expr:n,condition:a}}}parseRelationExpr(e){switch(e.$type){case`DirectedRelationExpr`:return this.wrapInWhere({source:this.parseFqnExpr(e.source.from),target:this.parseFqnExpr(e.target),isBidirectional:e.source.isBidirectional},this.parseInlineKindCondition(e.source));case`InOutRelationExpr`:return{inout:this.parseFqnExpr(e.inout.to)};case`OutgoingRelationExpr`:return this.wrapInWhere({outgoing:this.parseFqnExpr(e.from)},this.parseInlineKindCondition(e));case`IncomingRelationExpr`:return{incoming:this.parseFqnExpr(e.to)};default:P(e)}}parseInlineKindCondition(e){let t=e.kind??e.dotKind?.kind;return t?t.ref?{kind:{eq:t.ref?.name}}:(this.logError(`RelationshipKind "${t.$refText}" is not resolved`,e,`fqnref`),null):null}wrapInWhere(e,t){return t?{where:{expr:e,condition:t}}:e}}}function $g(e){return class t extends e{parseGlobals(){let{parseResult:e,c4Globals:t}=this.doc,n=this.isValid,r=e.value.globals.filter(n),a=r.flatMap(e=>e.predicates.filter(n));for(let e of a)try{let n=e.name;if(!i(n))continue;if(n in t.predicates){this.logError(`Global predicate named "${n}" is already defined`,e,`globals`);continue}this.parseAndStoreGlobalPredicateGroupOrDynamic(e,n,t)}catch(t){this.logError(t,e,`globals`)}let o=r.flatMap(e=>e.styles.filter(n));for(let e of o)try{let n=e.id.name;if(!i(n))continue;if(n in t.styles){this.logError(`Global style named "${n}" is already defined`,e,`globals`);continue}let r=this.parseGlobalStyleOrGroup(e);v(r,1)&&(t.styles[n]=r)}catch(t){this.logError(t,e,`globals`)}}parseAndStoreGlobalPredicateGroupOrDynamic(e,t,n){if(hl(e)){let r=this.parseGlobalPredicateGroup(e);v(r,1)&&(n.predicates[t]=r);return}if(pl(e)){let r=this.parseGlobalDynamicPredicateGroup(e);v(r,1)&&(n.dynamicPredicates[t]=r);return}P(e)}parseGlobalPredicateGroup(e){return e.predicates.map(e=>this.parseViewRulePredicate(e))}parseGlobalDynamicPredicateGroup(e){return e.predicates.map(e=>this.parseDynamicViewIncludePredicate(e))}parseGlobalStyleOrGroup(e){if(yl(e))return[this.parseViewRuleStyle(e)];if(xl(e))return e.styles.map(e=>this.parseViewRuleStyle(e));P(e)}}}function e_(e){return class t extends e{parseImports(){let e=this.doc.parseResult.value.imports??[];for(let t of e){let e=t.project,n=t.imports;for(;n;){try{this.doc.c4Imports.set(e,this.resolveFqn(Dr(n.imported.ref,`ElementRef is empty of imported: ${n.imported.$refText}`)))}catch(e){this.logError(e,n,`imports`)}n=n.prev}}}}}function*t_(e){let t=rr.from(e.parseResult.value.models.flatMap(e=>e.elements)),n=[],r;for(;r=t.shift();){if(Eu(r)){n.push(r);continue}if($c(r)){n.push(r);continue}if(r.body?.elements&&v(r.body.elements,1))for(let e of r.body.elements)t.push(e);yield r}yield*n}function n_(e){return class t extends e{parseModel(){let e=this.doc;for(let t of t_(e))try{if(H(t)){e.c4Elements.push(this.parseElement(t));continue}if(Eu(t)){e.c4Relations.push(this.parseRelation(t));continue}if(Yc(t)){let n=this.parseExtendElement(t);n&&e.c4ExtendElements.push(n);continue}if($c(t)){let n=this.parseExtendRelation(t);n&&e.c4ExtendRelations.push(n);continue}P(t)}catch(e){this.logError(e,t,`model`)}}parseElement(e){let t=this.isValid,n=this.resolveFqn(e),r=Dr(e.kind.ref,`Element kind is not resolved`).name,i=this.parseTags(e.body),a=this.parseElementStyle(e.body?.props),o=this.getMetadata(e.body?.props.find(Vo)),s=this.getAstNodePath(e),[c,l,u]=e.props??[],d=y(e.body?.props??[],b(t),b(Mc),Oe(e=>[e.key,e.value])),{title:f,...p}=this.parseBaseProps(d,{title:c,summary:l,technology:u});return Rr({id:n,kind:r,astPath:s,title:f,metadata:o,tags:i??void 0,links:this.parseLinks(e.body),...p,style:a})}parseExtendElement(e){let t=this.parseTags(e.body),n=this.getMetadata(e.body?.props.find(Vo)),r=this.parseLinks(e.body);if(!t&&ge(n)&&!r)return null;let i=this.getAstNodePath(e);return Rr({id:this.resolveFqn(e),astPath:i,metadata:n,tags:t,links:r})}parseExtendRelation(e){let t=this.parseFqnRef(e.source),r=this.parseFqnRef(e.target);N(F.isModelRef(t)||F.isImportRef(t),`Source must be a model reference`),N(F.isModelRef(r)||F.isImportRef(r),`Target must be a model reference`);let i=this.parseTags(e.body),a=this.getMetadata(e.body?.props.find(Vo)),o=this.getAstNodePath(e),s=this.parseLinks(e.body);if(!i&&n(a??{})&&!s)return null;let c=(e.kind??e.dotKind?.kind)?.ref?.name,{title:l=``}=this.parseBaseProps({},{title:e.title});return Rr({id:wp(`extend-relation`,F.flatten(t),F.flatten(r),c??`default`,l),astPath:o,metadata:a,tags:i,links:s})}_resolveRelationSource(e){if(he(e.source)){let t=this.parseFqnRef(e.source);return N(F.isModelRef(t)||F.isImportRef(t),`Relation source must be a model reference`),t}if(wc(e.$container)||Zc(e.$container))return{model:this.resolveFqn(e.$container.$container)};throw Error(`RelationRefError: Invalid container for sourceless relation`)}parseRelation(e){let t=this.isValid,n=this._resolveRelationSource(e),r=this.parseFqnRef(e.target);N(F.isModelRef(r)||F.isImportRef(r),`Target must be a model reference`);let a=this.parseTags(e)??this.parseTags(e.body)??void 0,o=this.parseLinks(e.body),s=(e.kind??e.dotKind?.kind)?.ref?.name,c=this.getMetadata(e.body?.props.find(Vo)),l=this.getAstNodePath(e),u=y(e.body?.props??[],b(Bu),b(e=>i(e.value)),Oe(e=>[e.key,e.value])),d=y(e.body?.props??[],b(Iu),x(e=>e.value.view.ref?.name),b(i),re()),{title:f=``,description:p,technology:m}=this.parseBaseProps(u,{title:e.title,description:e.description,technology:e.technology}),h=e.body?.props.find(Hu);return Rr({id:wp(l,n.model,r.model),astPath:l,source:n,target:r,title:f,metadata:c,kind:s,tags:a,links:o,navigateTo:d,description:p,technology:m,...Nf(h?.props,t)})}}}function r_(e){return class t extends e{parsePredicate(e){return this.parseExpressionV2(e)}parseElementPredicate(e){if(sl(e))return this.parseFqnExprWith(e);if(Po(e))return this.parseFqnExprOrWhere(e);P(e)}parseElementPredicateOrWhere(e){return this.parseFqnExprOrWhere(e)}parseElementExpression(e){return this.parseFqnExpr(e)}parseElementPredicateWhere(e){return this.parseFqnExprWhere(e)}parseElementPredicateWith(e){return this.parseFqnExprWith(e)}parseRelationPredicate(e){return this.parseRelationExprOrWith(e)}parseRelationPredicateOrWhere(e){return this.parseRelationExprOrWhere(e)}parseRelationPredicateWhere(e){return this.parseRelationExprWhere(e)}parseRelationPredicateWith(e){return this.parseRelationExprWith(e)}parseRelationExpression(e){return this.parseRelationExpr(e)}}}function i_(e){return class t extends e{parseSpecification(){let{parseResult:{value:{specifications:e}},c4Specification:t}=this.doc,n=this.isValid;for(let r of e.flatMap(e=>e.elements.filter(n)))try{Object.assign(t.elements,this.parseElementSpecificationNode(r))}catch(e){this.logError(e,r,`specification`)}for(let r of e.flatMap(e=>e.deploymentNodes.filter(n)))try{Object.assign(t.deployments,this.parseElementSpecificationNode(r))}catch(e){this.logError(e,r,`specification`)}let r=e.flatMap(e=>e.relationships.filter(this.isValid));for(let{kind:e,props:n}of r)try{let r=e.name;if(!i(r))continue;if(r in t.relationships){this.logError(`Relationship kind "${r}" is already defined`,e,`specification`);continue}let o=y(n.filter(od)??[],b(e=>this.isValid(e)&&m(e.value)),Oe(e=>[e.key,X(Of(e.value))]),pe(a));t.relationships[r]={...o,...Nf(n.filter($o),this.isValid)}}catch(t){this.logError(t,e,`specification`)}let o=e.flatMap(e=>e.tags.filter(this.isValid));for(let e of o)try{let n=e.tag.name,r=this.getAstNodePath(e.tag),a=e.color&&this.parseColorLiteral(e.color);if(n in t.tags){this.logError(`Tag ${n} is already defined, skipping duplicate`,e,`specification`);continue}i(n)&&(t.tags[n]={astPath:r,...a?{color:a}:{}})}catch(t){this.logError(t,e,`specification`)}let s=e.flatMap(e=>e.colors.filter(n));for(let{name:e,color:n}of s)try{let r=e.name;if(r in t.colors){this.logError(`Custom color "${r}" is already defined`,e,`specification`);continue}t.colors[r]={color:ni(this.parseColorLiteral(n),`Color "${r}" is not valid`)}}catch(e){this.logError(e,n,`specification`)}}parseElementSpecificationNode(e){let{kind:t,props:n}=e,r=t.name;if(!i(r))throw Error(`DeploymentNodeKind name is not resolved`);let a=this.parseTags(e),o=this.parseElementStyle(n.find(Pc)),s=this.parseLinks(e),c=y(n.filter(nd)??[],b(e=>this.isValid(e)),Oe(e=>[e.key,e.value])),l=this.parseBaseProps(c),u=X(Of(c.notation));return{[r]:pr({...l,notation:u,tags:a??void 0,...s&&Zn.isNonEmptyArray(s)&&{links:s},style:o})}}}}function a_(e){return class t extends e{parseViews(){let e=this.isValid;for(let t of this.doc.parseResult.value.views){let r=t.styles.flatMap(t=>{try{return e(t)?this.parseViewRuleStyleOrGlobalRef(t):[]}catch(e){return this.logError(e,t,`views`),[]}}),i=t.folder&&!n(t.folder.trim())?Hg(t.folder):null;for(let n of t.views)try{if(!e(n))continue;switch(!0){case Rc(n):this.doc.c4Views.push(this.parseElementView(n,r));break;case uc(n):this.doc.c4Views.push(this.parseDynamicElementView(n,r));break;case ec(n):this.doc.c4Views.push(this.parseDeploymentView(n));break;default:P(n)}if(i){let e=this.doc.c4Views.at(-1);e.title=i+` / `+(e.title||e.id)}}catch(e){this.logError(e,n,`views`)}}}parseElementView(e,t){let n=e.body;N(n,`ElementView body is not defined`);let r=this.getAstNodePath(e),i=null;if(`viewOf`in e){let t=Uf(e.viewOf),n=t&&Tp(()=>this.resolveFqn(t));if(n)i=n;else{let t=e.name??`unnamed`,n=e.viewOf.$cstNode?.text??`<unknown>`;this.logError(`viewOf ${t} not resolved ${n}`,e.viewOf)}}let a=e.name;a||=`view_`+wp(this.doc.uri.toString(),r,i??``);let{title:o=null,description:s=null}=this.parseBaseProps(y(n.props,b(e=>this.isValid(e)),b(Rd),Oe(e=>[e.key,e.value]))),c=this.convertTags(n),l=this.convertLinks(n),u={[Zn._type]:`element`,id:a,astPath:r,title:Hg(o)??null,description:s,tags:c,links:Cr(l)?l:null,rules:[...t,...this.tryMap(`views`,n.rules,e=>this.parseElementViewRule(e))],...i&&{viewOf:i}};if(wf.writeId(e,u.id),`extends`in e){let t=e.extends.view.ref;return N(t?.name,`view extends is not resolved: `+e.$cstNode?.text),Object.assign(u,{extends:t.name})}return u}parseElementViewRule(e){if(Md(e))return this.parseViewRulePredicate(e);if(Ed(e))return this.parseViewRuleGlobalPredicateRef(e);if(ds(e))return this.parseViewRuleStyleOrGlobalRef(e);if(wd(e))return Ff(e);if(Ad(e))return this.parseViewRuleGroup(e);if(Pd(e))return this.parseViewRuleRank(e);P(e)}parseViewRulePredicate(e){let t=[],n=e.exprs;for(;n;){let{value:e,prev:r}=n;if(this.tryParse(`views`,e,()=>{let n=this.parsePredicate(e);t.unshift(n)}),!r)break;n=r}return e.isInclude?{include:t}:{exclude:t}}parseViewRuleGlobalPredicateRef(e){return{predicateId:e.predicate.$refText}}parseViewRuleStyleOrGlobalRef(e){if(Id(e))return this.parseViewRuleStyle(e);if(Od(e))return this.parseViewRuleGlobalStyle(e);P(e)}parseViewRuleGroup(e){let t=[];for(let n of e.groupRules)try{if(!this.isValid(n))continue;if(Md(n)){t.push(this.parseViewRulePredicate(n));continue}if(Ad(n)){t.push(this.parseViewRuleGroup(n));continue}P(n)}catch(e){this.logError(e,n,`views`)}return{title:Hg(e.title)??null,groupRules:t,...this.parseStyleProps(e.props)}}parseViewRuleRank(e){let t=this.parseFqnExpressions(e.targets).filter(e=>Zn.ModelExpression.isFqnExpr(e));return{rank:e.value??`same`,targets:t}}parseViewRuleStyle(e){let t=this.parseFqnExpressions(e.targets).filter(e=>Zn.ModelExpression.isFqnExpr(e)),n=this.parseStyleProps(e.props.filter(as)),r=X(Of(e.props.find(gu)?.value));return{targets:t,style:n,...r&&{notation:r}}}parseViewRuleGlobalStyle(e){return{styleId:e.style.$refText}}parseDynamicElementView(e,t){let n=e.body;N(n,`DynamicElementView body is not defined`);let r=this.isValid,i=n.props.filter(r),a=this.getAstNodePath(e),o=e.name;o||=`dynamic_`+wp(this.doc.uri.toString(),a);let{title:s=null,description:c=null}=this.parseBaseProps(y(i,b(Rd),Oe(e=>[e.key,e.value]))),l=this.convertTags(n),u=this.convertLinks(n);wf.writeId(e,o);let f=d(i,mc)?.value;return{[Zn._type]:`dynamic`,id:o,astPath:a,title:Hg(s)??null,description:c,tags:l,links:Cr(u)?u:null,variant:f,rules:[...t,...this.tryMap(`views`,n.rules,e=>this.parseDynamicViewRule(e))],steps:this.tryMap(`views`,n.steps,e=>bc(e)?this.parseDynamicParallelSteps(e):this.parseDynamicStep(e))}}parseDynamicViewRule(e){if(vc(e))return this.parseDynamicViewIncludePredicate(e);if(gc(e))return this.parseViewRuleGlobalPredicateRef(e);if(ds(e))return this.parseViewRuleStyleOrGlobalRef(e);if(wd(e))return Ff(e);P(e)}parseDynamicViewIncludePredicate(e){let t=[],n=e.exprs;for(;n;)this.tryParse(`views`,n.value,e=>{if(Io(e)){let n=this.parseElementPredicate(e);t.unshift(n)}}),n=n.prev;return{include:t}}parseDynamicParallelSteps(e){let t=o_(e),n=this.tryMap(`views`,e.steps,e=>this.parseDynamicStep(e));return N(Cr(n),`Dynamic parallel steps must have at least one step`),{parallelId:t,__parallel:n}}parseDynamicStep(e){if(hf(e))return this.parseDynamicStepSingle(e);let t=this.recursiveParseDynamicStepChain(e);return N(Cr(t),`Dynamic step chain must have at least one step`),{seriesId:o_(e),__series:t}}recursiveParseDynamicStepChain(e,t){if(hf(e.source)){if(!this.isValid(e.source))return[];let n=this.parseDynamicStepSingle(e.source);if(n.isBackward)return[];let r={...this.parseAbstractDynamicStep(e),source:n.target};return r.target===n.source?r.isBackward=!0:t&&(t.push([n.source,n.target]),t.push([r.source,r.target])),[n,r]}t??=[];let n=this.recursiveParseDynamicStepChain(e.source,t);if(!Cr(n)||!this.isValid(e))return[];let r=se(n),i={...this.parseAbstractDynamicStep(e),source:r.target},a=t.findIndex(([e,t])=>e===i.target&&t===i.source);return a===-1?t.push([i.source,i.target]):(i.isBackward=!0,t.splice(a,t.length-a)),[...n,i]}parseDynamicStepSingle(e){let t=Uf(e.source);if(!t)throw Error(`Invalid reference to source`);let n={...this.parseAbstractDynamicStep(e),source:this.resolveFqn(t)};return e.isBackward&&(n={...n,source:n.target,target:n.source,isBackward:!0}),n}parseAbstractDynamicStep(e){let t=Uf(e.target);if(!t)throw Error(`Invalid reference to target`);let n={target:this.resolveFqn(t),astPath:o_(e)},r=X(e.title);r&&(n.title=r);let a=e.kind?.ref?.name??e.dotKind?.kind.ref?.name;a&&(n.kind=a);for(let t of e.custom?.props??[])try{switch(!0){case Iu(t):{let e=t.value.view.ref?.name;i(e)&&(n.navigateTo=e);break}case Bu(t):case gu(t):if(he(t.value))if(t.key===`description`){let e=X(t.value);e&&(n.description=e)}else n[t.key]=X(Of(t.value))??``;break;case vu(t):he(t.value)&&(n[t.key]=X(t.value));break;case ks(t):he(t.value)&&(n[t.key]=t.value);break;case Ns(t):{let e=Pf(t);he(e)&&(n[t.key]=e);break}case Jl(t):he(t.value)&&(n[t.key]=t.value);break;default:P(t)}}catch(e){this.logError(e,t,`views`)}return n}}}function o_(e){let t=e,n=[];for(;!fc(t);)o(t.$containerIndex)&&n.unshift(`@${t.$containerIndex}`),n.unshift(`/${t.$containerProperty??`__invalid__`}`),t=t.$container;return n.join(``)}Qt();const s_=y(Ug,Qg,e_,n_,Gg,Kg,r_,i_,a_,$g);var c_=class extends s_{};const l_=B.getChild(`parser`),u_=e=>e.severity===xt.Error;var d_=class{cachedParsers=new Hr(e=>this.createParser(e));constructor(e){this.services=e,e.shared.workspace.DocumentBuilder.onDocumentPhase(S.Linked,async e=>{this.cachedParsers.has(e)&&(l_.trace(`Linked: clear cached parser {projectId} document {doc}`,{projectId:e.likec4ProjectId,doc:T.basename(e.uri)}),this.cachedParsers.delete(e))}),e.shared.workspace.DocumentBuilder.onBuildPhase(S.Linked,async t=>{for(let n of t)if(!e.shared.workspace.ProjectsManager.isExcluded(n))try{this.parse(n)}catch(e){V(e)}}),e.shared.workspace.DocumentBuilder.onDocumentPhase(S.Validated,async e=>{e.diagnostics?.some(u_)&&this.cachedParsers.has(e)&&(l_.trace(`Validated: clear cached parser {projectId} document {doc} because of errors`,{projectId:e.likec4ProjectId,doc:T.basename(e.uri)}),this.cachedParsers.delete(e))})}documents(e){return this.services.shared.workspace.LangiumDocuments.projectDocuments(e).map(e=>this.parse(e))}parse(e){return this.forDocument(e).doc}forDocument(e){return this.cachedParsers.get(e)}createParser(e){I(Ef(e),`Document ${e.uri.toString()} is not a LikeC4 document`);let t=this.services.shared.workspace.ProjectsManager.getProject(e),n=T.relative(t.folderUri,e.uri);e.likec4ProjectId?l_.trace(`create parser {projectId} document {doc}`,{projectId:e.likec4ProjectId,doc:n}):l_.debug(`create parser for document without project {doc}`,{doc:e.uri.fsPath}),e.state<S.Linked&&l_.debug(`Document {doc} is not linked, state is {state}`,{doc:n,state:e.state});let r={c4Specification:{tags:{},elements:{},relationships:{},colors:{},deployments:{}},c4Elements:[],c4ExtendElements:[],c4ExtendDeployments:[],c4ExtendRelations:[],c4Relations:[],c4Deployments:[],c4DeploymentRelations:[],c4Globals:{predicates:{},dynamicPredicates:{},styles:{}},c4Views:[],c4Imports:new Ur(Set)};e=Object.assign(e,r);let i=new c_(this.services,e,t);try{i.parseSpecification(),i.parseImports(),i.parseModel(),i.parseDeployment(),i.parseGlobals(),i.parseViews()}catch(e){throw Error(`Error parsing document ${n}`,{cause:e})}return i}},f_=class extends lt{runConverter(e,t,n){return e.name===`MarkdownString`?((t.startsWith(`"""`)&&t.endsWith(`"""`)||t.startsWith(`'''`)&&t.endsWith(`'''`))&&(t=t.slice(2,-2)),Zt.convertString(t)):super.runConverter(e,t,n)}};Qt();const{findNodeForKeyword:p_}=en,m_=(e,t,n=0)=>{let r=n>0?` `.repeat(n):``;return[r+`style ${e} {`,...u(t).map(([e,t])=>r+` ${e} ${e===`opacity`?t.toString()+`%`:t}`),r+`}`]},h_=(e,t)=>n=>{if(!Id(n)&&!oc(n))return!1;let r=n.targets.value;if(!r||i(n.targets.prev)||r.$type!==`FqnRefExpr`||i(r.selector))return!1;let a=r.ref?.value?.ref;return(a?t.resolve(a):null)===e};function g_(e,{view:t,viewAst:n,targets:r,style:i}){N(n.body,`View ${t.id} has no body`);let a=n.$cstNode;N(a,`viewCstNode`);let o=se(n.body.rules)?.$cstNode?.range.end??n.body.$cstNode?.range.end;N(o,`insertPos is not defined`);let s=a.range.start.character+2,l=e.likec4.FqnIndex,d=b(n.body.rules,e=>Id(e)||oc(e)),f=t[cr]===`element`?t.viewOf??null:null,p=[],m=[];r.forEach(e=>{let t=c(d,h_(e,l)),n=f&&hr(f,e)?e.substring(f.length+1):e;t?p.push({fqn:n,rule:t}):m.push({fqn:n})});let h={start:o,end:o},g=e=>{e.start.line<=h.start.line&&(e.start.line==h.start.line?h.start.character=Math.min(e.start.character,h.start.character):h.start=e.start),e.end.line>=h.end.line&&(e.end.line==h.end.line?h.end.character=Math.max(e.end.character,h.end.character):h.end=e.end)},_=[];if(m.length>0){let e=m.flatMap(({fqn:e})=>m_(e,i,s));_.push(Kt.insert(o,`
|
|
1224
|
-
`+e.join(`
|
|
1225
|
-
`))),h.start={line:o.line+1,character:s},h.end={line:o.line+e.length,character:se(e)?.length??0}}if(p.length>0)for(let{rule:e}of p){let t=e.$cstNode;N(t,`RuleCstNode not found`);for(let[n,r]of u(i)){let i=n===`opacity`?r.toString()+`%`:r,a=e.props.find(e=>e.key===n);if(a&&a.$cstNode){let{range:{start:e,end:t}}=a.$cstNode;g({start:e,end:t}),_.push(Kt.replace({start:e,end:t},n+` `+i));continue}let o=p_(t,`{`)?.range.end;N(o,`Opening brace not found`);let s=` `.repeat(t.range.start.character)+` `,c=s+n+` `+i;_.push(Kt.insert(o,`
|
|
1226
|
-
`+c)),g({start:{line:o.line+1,character:s.length},end:{line:o.line+1,character:c.length}})}}return{modifiedRange:h,edits:_}}Qt();const{findNodeForKeyword:__}=en;function v_(e,{view:t,viewAst:n,layout:r}){N(n.body,`View ${t.id} has no body`);let i=n.$cstNode;N(i,`viewCstNode`);let a=If(r.direction),s=c(n.body.rules,wd),l=`autoLayout ${a}`;if(o(r.rankSep)&&(l+=` ${r.rankSep}`,o(r.nodeSep)&&(l+=` ${r.nodeSep}`)),s&&s.$cstNode)return Kt.replace(s.$cstNode.range,l);let u=__(n.body.$cstNode,`}`)?.range.start;N(u,`Closing brace not found`);let d=`\t${l}\n\t`;return Kt.insert(u,d)}Qt();const y_=B.getChild(`model-changes`);var b_=class{locator;constructor(e){this.services=e,this.locator=e.likec4.ModelLocator}async applyChange(e){let t=this.services.shared.lsp.Connection,n=this.services.shared.workspace;try{let{viewId:r,projectId:i,change:a}=e,o=n.ProjectsManager.ensureProject(i);y_.debug`Applying model change ${a.op} to view ${r} in project ${o.id}`;let s=this.locator.locateViewAst(r,o.id);if(!s)throw Error(`View ${r} not found in project ${o.id}`);let c={uri:s.doc.textDocument.uri,version:s.doc.textDocument.version};if(a.op===`save-view-snapshot`)return N(r===a.layout.id,`View ID does not match, expected `+r+`, got `+a.layout.id),{success:!0,location:await n.ManualLayouts.write(o,a.layout)};if(a.op===`reset-manual-layout`)return{success:!0,location:await n.ManualLayouts.remove(o,r)};N(t,`This change only supported in IDE (running as Extension)`);let{edits:l,modifiedRange:u}=this.convertToTextEdit({lookup:s,change:a});if(!l.length)return{success:!1,error:`No changes to apply`};let d=await t.workspace.applyEdit({label:`LikeC4 - change view ${e.viewId}`,edit:{changes:{[c.uri]:l}}});return d.applied?(await n.DocumentBuilder.update([s.doc.uri],[]),{success:!0,location:{uri:c.uri,range:u}}):(t.window.showErrorMessage(`Failed to apply changes ${d.failureReason}`),{success:!1,error:`Failed to apply changes ${d.failureReason}`})}catch(t){let n=L(Li(t,`Failed to apply change ${e.change.op} ${e.viewId}`));return y_.error(n),{success:!1,error:n}}}convertToTextEdit({lookup:e,change:t}){switch(t.op){case`change-element-style`:return g_(this.services,{...e,targets:t.targets,style:t.style});case`change-autolayout`:{let n=v_(this.services,{...e,layout:t.layout});return{modifiedRange:n.range,edits:[n]}}default:P(t)}}},x_=class extends ut{constructor(e){super(),this.services=e}getNameStrict(e){return Dr(this.getName(e),`Failed getName for ${this.services.workspace.AstNodeLocator.getAstNodePath(e)}`)}getName(e){if(gt(e))return e.name;if(Pl(e))return e.imported.$refText;if(Bs(e))return e.target.modelElement.value.$refText}getNameNode(e){if(gt(e))return super.getNameNode(e);if(Pl(e))return e.imported.$refNode;if(Bs(e))return e.target.modelElement.value.$refNode}};function S_(e){return y(e,_(e=>`${e.type}.${e.name}`),u(),l(([e,t])=>t.length===1?t:[]))}var C_=class extends ot{constructor(e){super(e)}async computeExports(e,t){let n=[];try{let{specifications:t,models:r,views:i,globals:a,likec4lib:o,deployments:s}=e.parseResult.value;this.exportLibrary(o,n,e),this.exportSpecification(t,n,e),this.exportModel(r,n,e),this.exportViews(i,n,e),this.exportGlobals(a,n,e),this.exportDeployments(s,n,e)}catch(e){V(e)}return n}exportViews(e,t,n){let r=e?.flatMap(e=>e.views);if(!(a(r)||r.length===0))for(let e of r)try{i(e.name)&&t.push(this.descriptions.createDescription(e,e.name,n))}catch(e){V(e)}}exportGlobals(e,t,n){if(!(a(e)||e.length===0)){for(let r of e.flatMap(e=>e.predicates))try{let e=r;i(e.name)&&t.push(this.descriptions.createDescription(e,e.name,n))}catch(e){V(e)}for(let r of e.flatMap(e=>e.styles))try{let e=r.id;i(e.name)&&t.push(this.descriptions.createDescription(e,e.name,n))}catch(e){V(e)}}}exportModel(e,t,n){if(!(a(e)||e.length===0))for(let r of e.flatMap(e=>e.elements))try{H(r)&&i(r.name)&&t.push(this.descriptions.createDescription(r,r.name,n))}catch(e){V(e)}}exportLibrary(e,t,n){if(!a(e))try{for(let r of e.flatMap(e=>e.icons))t.push(this.descriptions.createDescription(r,r.name,n))}catch(e){V(e)}}exportSpecification(e,t,n){if(!(a(e)||e.length===0))for(let r of e.flatMap(e=>[...e.elements,...e.relationships,...e.deploymentNodes,...e.tags,...e.colors]))try{switch(!0){case Qu(r):case ed(r):i(r.kind.name)&&t.push(this.descriptions.createDescription(r.kind,r.kind.name,n));continue;case ud(r):i(r.tag.name)&&t.push(this.descriptions.createDescription(r.tag,r.tag.name,n));continue;case id(r):i(r.kind.name)&&t.push(this.descriptions.createDescription(r.kind,r.kind.name,n));continue;case Xu(r):i(r.name.name)&&t.push(this.descriptions.createDescription(r.name,r.name.name,n));continue;default:P(r)}}catch(e){V(e)}}exportDeployments(e,t,n){let r=e?.flatMap(e=>e.elements);if(!(a(r)||r.length===0))for(let e of r)try{Ws(e)&&i(e.name)&&t.push(this.descriptions.createDescription(e,e.name,n))}catch(e){V(e)}}computeLocalScopes(e,t){return new Promise(t=>{let n=e.parseResult.value,r=[],i=new ct;for(let t of n.models)try{r.push(...this.processContainer(t,i,e))}catch(e){V(e)}for(let t of n.deployments)try{r.push(...this.processDeployments(t,i,e))}catch(e){V(e)}for(let e of n.imports.flatMap(e=>e.imports))try{let t=e;for(;t;)r.push(this.descriptions.createDescription(t,t.imported.$refText)),t=t.prev}catch(e){V(e)}S_(r).forEach(e=>{i.add(n,e)}),t(i)})}processContainer(e,t,n){let a=new ct,o=[];for(let r of e.elements){if(Eu(r))continue;let e;if(H(r)?(i(r.name)&&a.add(r.name,this.descriptions.createDescription(r,r.name,n)),e=r.body,e&&(t.add(e,this.descriptions.createDescription(r,`this`,n)),t.add(e,this.descriptions.createDescription(r,`it`,n)))):Yc(r)&&(e=r.body),e&&e.elements.length>0)try{o.push(...this.processContainer(e,t,n))}catch(e){V(e)}}o.length&&y(o,b(e=>!a.has(e.name)),_(e=>e.name),r((e,t)=>{e.length===1&&a.add(t,e[0])}));let s=[...a.values()];return t.addAll(e,s),s}processDeployments(e,t,n){let a=new ct,o=[];for(let r of e.elements){if(Xs(r))continue;let e=r.body;if(!Gc(r)){let o=this.nameProvider.getName(r);if(i(o)){let e=this.descriptions.createDescription(r,o,n);a.add(o,e)}e&&(t.add(e,this.descriptions.createDescription(r,`this`,n)),t.add(e,this.descriptions.createDescription(r,`it`,n)))}if(e)try{o.push(...this.processDeployments(e,t,n))}catch(e){V(e)}}o.length&&y(o,b(e=>!a.has(e.name)),_(e=>e.name),r((e,t)=>{e.length===1&&a.add(t,e[0])}));let s=[...a.values()];return t.addAll(e,s),s}};const{getDocument:w_}=kt;var T_=class extends pt{deploymentsIndex;fqnIndex;indexManager;constructor(e){super(e),this.indexManager=e.shared.workspace.IndexManager,this.fqnIndex=e.likec4.FqnIndex,this.deploymentsIndex=e.likec4.DeploymentsIndex}getScope(e){try{let t=G(e.container),n=this.reflection.getReferenceType(e);try{let r=e.container;if(ll(r))return new mt(this.streamForFqnRef(t,r,e));if(md(r))return this.getScopeForStrictFqnRef(t,r,e);if(n!==Sc)return this.getProjectScope(t,n,e);if(Pl(r)){let e=G(r);return new mt(this.fqnIndex.rootElements(e))}if(fd(r)&&e.property===`el`){let i=r.parent;return i?new mt(this.fqnIndex.directChildrenOf(t,Wf(i))):this.getProjectScope(t,n,e)}return new mt(on(this.computeScope(t,e)))}catch(r){return V(r),this.getProjectScope(t,n,e)}}catch(e){return V(e),dt}}*genUniqueDescedants(e){if(!e)return;let t=G(e);if(H(e)){let n=this.fqnIndex.getFqn(e);yield*this.fqnIndex.uniqueDescedants(t,n);return}if(Ws(e)){let n=this.deploymentsIndex.getFqn(e);yield*this.deploymentsIndex.uniqueDescedants(t,n)}}*genScopeExtendElement({element:e}){e.el.$nodeDescription&&(yield e.el.$nodeDescription,yield{...e.el.$nodeDescription,name:`this`},yield{...e.el.$nodeDescription,name:`it`}),yield*this.genUniqueDescedants(Uf(e))}*genScopeElementView({viewOf:e,extends:t}){if(e){e.modelElement.value.$nodeDescription&&(yield e.modelElement.value.$nodeDescription),yield*this.genUniqueDescedants(Uf(e));return}if(t){let e=t.view.ref;e&&(yield*this.genScopeElementView(e))}}getScopeForStrictFqnRef(e,t,n){let r=t.parent;return r?new mt(this.deploymentsIndex.directChildrenOf(e,Wf(r)).filter(e=>this.reflection.isSubtype(e.type,Us))):this.getProjectScope(e,Us,n)}*genScopeExtendDeployment({deploymentNode:e}){e.value.$nodeDescription&&(yield e.value.$nodeDescription);let t=e.value.ref;t&&Ws(t)&&(yield*this.genUniqueDescedants(t))}streamForFqnRef(e,t,n){let r=t.parent;if(!r)return on(this.genScopeForParentlessFqnRef(e,t,n));let i=r.value.ref;if(!i)return wt;if(Pl(i))return on(this.genUniqueDescedants(i.imported.ref));if(Ws(i))return on(this.genUniqueDescedants(i));if(Bs(i)){let e=i.target.modelElement.value.ref,t=Pl(e)?e.imported.ref:H(e)?e:void 0;return on(this.genUniqueDescedants(t))}return H(i)?on(this.genUniqueDescedants(i)):P(i)}*genScopeForParentlessFqnRef(e,t,n){jt(t,Ac)||Vf(t)?yield*this.computeScope(e,n,Sc):Bf(t)?(yield*this.computeScope(e,n,Sc),yield*this.computeScope(e,n,Us),yield*this.computeScope(e,n,zs)):(yield*this.computeScope(e,n,Us),yield*this.computeScope(e,n,zs),jt(t,nc)&&(yield*this.computeScope(e,n,Sc)));let r=w_(t).precomputedScopes;r&&(yield*r.values().filter(e=>this.reflection.isSubtype(e.type,Nl)))}*computeScope(e,t,n=this.reflection.getReferenceType(t)){let r=this.reflection.isSubtype(n,Sc),i=this.reflection.isSubtype(n,ho),a=w_(t.container).precomputedScopes;if(!a){yield*this.getProjectScope(e,n,t).getAllElements();return}let o=e=>this.reflection.isSubtype(e.type,n),s=t.container;for(;s;){let e=a.get(s).filter(o);e.length>0&&(yield*e),i&&qc(s)&&(yield*this.genScopeExtendDeployment(s.$container)),r&&Zc(s)&&(yield*this.genScopeExtendElement(s.$container)),r&&Bc(s)&&(yield*this.genScopeElementView(s.$container)),s=s.$container}yield*this.getProjectScope(e,n,t).getAllElements()}getProjectScope(e,t,n){return t===Vl?super.getGlobalScope(t,n):this.globalScopeCache.get(`${e}::${t}`,()=>new ft(this.indexManager.projectElements(e,t)))}getGlobalScope(e,t){if(e===Vl)return super.getGlobalScope(e,t);let n=G(t.container);return this.getProjectScope(n,e,t)}},Z=ln();let E_;(function(e){e.type=new Z.NotificationType(`likec4/onDidChangeModel`)})(E_||={});let D_;(function(e){e.type=new Z.NotificationType0(`likec4/onDidChangeProjects`)})(D_||={});let O_;(function(e){e.type=new Z.NotificationType(e.Method=`likec4/onDidChangeSnapshot`)})(O_||={});let k_;(function(e){e.type=new Z.NotificationType(`likec4/onRequestOpenView`)})(k_||={});let A_;(function(e){e.req=new Z.RequestType(`likec4/fetchComputedModel`)})(A_||={});let j_;(function(e){e.req=new Z.RequestType0(`likec4/fetchViewsFromAllProjects`)})(j_||={});let M_;(function(e){e.req=new Z.RequestType(`likec4/fetchLayoutedModel`)})(M_||={});let N_;(function(e){e.req=new Z.RequestType(`likec4/layout-view`)})(N_||={});let P_;(function(e){e.req=new Z.RequestType(`likec4/validate-layout`)})(P_||={});let F_;(function(e){e.req=new Z.RequestType0(`likec4/reload-projects`)})(F_||={});let I_;(function(e){e.req=new Z.RequestType0(`likec4/fetch-projects`)})(I_||={});let L_;(function(e){e.req=new Z.RequestType(`likec4/register-project`)})(L_||={});let R_;(function(e){e.req=new Z.RequestType(`likec4/build`)})(R_||={});let z_;(function(e){e.req=new Z.RequestType(`likec4/locate`)})(z_||={});let B_;(function(e){e.req=new Z.RequestType(`likec4/change-view`)})(B_||={});let V_;(function(e){e.req=new Z.RequestType0(`likec4/metrics`)})(V_||={});let H_;(function(e){e.req=new Z.RequestType(`likec4/document-tags`)})(H_||={});let U_;(function(e){e.req=new Z.RequestType0(`likec4/fetch-projects-overview`)})(U_||={});const Q=B.getChild(`rpc`);var W_=class extends lo{constructor(e){super(),this.services=e}init=ve(()=>{let e=this.services.shared.lsp.Connection;if(!e){Q.info(`no connection, skip init ServerRpc`);return}Q.info(`init ServerRpc`);let t=this.services.likec4,n=this.services.shared.workspace,r=n.LangiumDocuments,i=n.DocumentBuilder,a=t=>{Q.debug`send ${`onDidChangeModel`} for project ${t}`,e.sendNotification(E_.type,{projectId:t}).catch(e=>{Q.warn(`[ServerRpc] error sending onDidChangeModel for project {project}`,{error:e,project:t})})},o=je(e=>{if(typeof e==`string`){a(e);return}for(let t of e)a(t)},{reducer:(e,t)=>!e||e===t?t:e instanceof Set?(e.add(t),e):new Set([e,t]),triggerAt:`end`,minQuietPeriodMs:130,maxBurstDurationMs:400}),s=je(t=>{t>1?Q.debug`send ${`DidChangeProjectsNotification`} (${t} batched)`:Q.debug`send ${`DidChangeProjectsNotification`}`,e.sendNotification(D_.type).catch(e=>{Q.warn(`[ServerRpc] error sending DidChangeProjectsNotification:`,{error:e})})},{reducer:(e,t)=>(e??0)+t,triggerAt:`end`,minQuietPeriodMs:250,maxBurstDurationMs:700}),c=!0;this.onDispose(t.ModelBuilder.onModelParsed(e=>o.call(e)),n.ProjectsManager.onProjectsUpdate(()=>s.call(1)),e.onRequest(A_.req,async({projectId:e,cleanCaches:r=!1},i)=>{Q.debug`received request ${`fetchComputedModel`} for project ${e}`,r&&(Q.debug`cleanCaches: ${r}`,e?await n.ProjectsManager.rebuildProject(e):await n.WorkspaceManager.rebuildAll());let a=await t.ModelBuilder.computeModel(e,i);return a===Jn.EMPTY?{model:null}:{model:a.$data}}),e.onNotification(O_.type,async e=>{let t=C.parse(e.update??e.delete),r=`update`in e?{update:t}:{delete:t};Q.debug`received notification ${`onDidChangeSnapshot`} with ${e}`,await n.ManualLayouts.handleFileSystemUpdate(r)}),e.onRequest(M_.req,async({projectId:e},n)=>{Q.debug`received request ${`fetchLayoutedModel`} for project ${e}`;let r=await t.LanguageServices.layoutedModel(e);if(r===null)return{model:null};let i=await t.Views.diagrams(e,n);return{model:{...r.$data,_stage:`layouted`,views:h(i,e=>e.id)}}}),e.onRequest(N_.req,async({viewId:e,projectId:n,layoutType:r},i)=>(Q.debug`received request ${`layoutView`} for ${e} from project ${n} (layout type: ${r??`not set`})`,{result:await t.Views.layoutView({viewId:e,projectId:n,layoutType:r,cancelToken:i})})),e.onRequest(P_.req,async({projectId:e},n)=>(Q.debug`received request ${`validateLayout`} for project ${e}`,{result:l((await t.Views.layoutAllViews(e,n)).map(e=>e.diagram))})),e.onRequest(I_.req,async()=>(Q.debug`received request ${`FetchProjects`}`,{projects:ae(r.groupedByProject(),(e,t)=>{let{folderUri:r,config:{name:i,title:a}}=n.ProjectsManager.getProject(t);return{folder:r.toString(),config:{name:i,title:a},docs:x(e,e=>e.uri.toString())}})})),e.onRequest(F_.req,async e=>{Q.debug`received request ${`ReloadProjects`}`,n.ManualLayouts.clearCaches(),await n.ProjectsManager.reloadProjects(e)}),e.onRequest(L_.req,async(e,t)=>{Q.debug`received request ${`RegisterProject`}`,n.ManualLayouts.clearCaches();let r;return r=`configUri`in e?await n.ProjectsManager.registerConfigFile(C.parse(e.configUri),t):await n.ProjectsManager.registerProject(e,t),{id:r.id}}),e.onRequest(j_.req,async e=>{Q.debug`received request ${`FetchViewsFromAllProjects`}`;let r=[];for(let i of n.ProjectsManager.all){await bt(e);try{let n=await t.Views.computedViews(i,e);r.push(...y(n,x(e=>({id:e.id,title:e.title??e.id,projectId:i})),xe((e,t)=>e.id===`index`?-1:t.id===`index`?1:e.title.localeCompare(t.title))))}catch(e){Q.warn(`Failed to fetch views for project ${i}:`,{error:e})}}return{views:r}}),e.onRequest(R_.req,async({docs:t},n)=>{let a=t.map(e=>C.parse(e)),o=e=>!a.some(t=>T.equals(t,e)),s=r.userDocuments.map(e=>e.uri).filter(o).toArray();Q.debug(`[ServerRpc] received request to build:
|
|
1227
|
-
changed (total ${a.length}):${t.map(e=>`
|
|
1228
|
-
- `+e).join(``)}
|
|
1229
|
-
deleted (total ${s.length}):${s.map(e=>`
|
|
1230
|
-
- `+e.toString()).join(`
|
|
1231
|
-
`)}`),!c&&a.length+s.length>0&&await Promise.allSettled([...a,...s].map(async t=>{let n=t.toString();Q.debug(`clear diagnostics for ${n}`);try{await e.sendDiagnostics({uri:n,diagnostics:[]})}catch(e){Q.warn(`error clearing diagnostics for ${n}: ${e}`)}})),c=!1,await bt(n),await i.update(a,s,n)}),e.onRequest(z_.req,e=>{Q.debug`received request ${`locate`}, ${e}`;let n=e.projectId;switch(!0){case`element`in e:return t.ModelLocator.locateElement(e.element,n);case`relation`in e:return t.ModelLocator.locateRelation(e.relation,n);case`astPath`in e:return t.ModelLocator.locateDynamicViewStep({view:e.view,astPath:e.astPath,projectId:n});case`view`in e:return t.ModelLocator.locateView(e.view,n);case`deployment`in e:return t.ModelLocator.locateDeploymentElement(e.deployment,n);default:P(e)}}),e.onRequest(B_.req,async e=>(Q.debug`received request ${`changeView`} of ${e.viewId} from project ${e.projectId}`,await t.ModelChanges.applyChange(e))),e.onRequest(V_.req,async e=>{let r=null;for(let i of n.ProjectsManager.all)try{let n=await t.ModelBuilder.computeModel(i,e);if(n===Jn.EMPTY)continue;r??={elementKinds:0,deploymentKinds:0,relationshipKinds:0,tags:0,customColors:0,elements:0,deploymentNodes:0,relationships:0,views:0,projects:0},r.elementKinds+=Ae(n.specification.elements).length,r.deploymentKinds+=Ae(n.specification.deployments).length,r.relationshipKinds+=Ae(n.specification.relationships).length,r.tags+=Ae(n.specification.tags).length,r.customColors+=Ae(n.specification.customColors??{}).length,r.elements+=Ae(n.$data.elements).length,r.deploymentNodes+=[...n.deployment.nodes()].length,r.relationships+=Ae(n.$data.relations).length,r.views+=Ae(n.$data.views).length,r.projects+=1}catch(e){Q.warn(`Error fetching telemetry metrics for project ${i}`,{err:e})}return await bt(e),{metrics:r}}),e.onRequest(H_.req,async({documentUri:e},r)=>{let i=C.parse(e);Q.debug`received request ${`GetDocumentTags`} for document ${i}`;let a=await t.ModelLocator.locateDocumentTags(i,r);return{projectId:n.ProjectsManager.ownerProjectId(i),tags:a??[]}}),e.onRequest(U_.req,async e=>(Q.debug`received request ${`FetchProjectsOverview`}`,{projectsView:await t.LanguageServices.projectsOverview(e)})),vt.create(()=>{o.cancel()}));function l(e){return y(e,b(e=>!!e.hasLayoutDrift),x(e=>{let n=t.ModelLocator.locateView(e.id);return N(n,`View ${e.id} not found`),{uri:n.uri,viewId:e.id,severity:yh.DiagnosticSeverity.Warning,message:`Layout drift detected for view '${e.id}'`,range:n.range}}))}});async openView(e){let t=this.services.shared.lsp.Connection;if(!t){Q.warn(`No LSP connection`);return}await t.sendNotification(k_.type,e)}};Qt();var G_=class{constructor(e){this.services=e}getSymbolKind(e){let t=Dt(e)?e.$type:e.type,n=(...e)=>e.some(e=>this.services.AstReflection.isSubtype(t,e));switch(!0){case n(Sc,Jc,Us,zs,Nl):return tn.Constructor;case n(au,lu,su,gl,sd):return tn.Namespace;case n(Ro):return tn.Class;case n(`Tag`,Vl,Ps,ld):return tn.EnumMember;case n(Lu,rd):return tn.Event;case n(Tc,qs,$u,Zu):return tn.TypeParameter}return tn.Field}getCompletionItemKind(e){let t=Dt(e)?e.$type:e.type,n=(...e)=>e.some(e=>this.services.AstReflection.isSubtype(t,e));switch(!0){case n(Ps):return w.Color;case n(Sc,Us,zs,Jc,Nl):return w.Constructor;case n(au,lu,su,gl,sd):return w.Module;case n(Ro):return w.Class;case n(`Tag`,Vl,Ps,ld):return w.EnumMember;case n(Lu,rd):return w.Event;case n(Tc,$u,qs,Zu):return w.TypeParameter;default:return w.Reference}}},K_=class extends At{};const q_=B.getChild(`views`);var J_=class{#e;#t=new Qn(e=>new Y_({projectId:e,storage:Kn(this.#e,e),layouter:this.layouter.layout.bind(this.layouter)}));ModelBuilder;constructor(e){this.services=e,this.ModelBuilder=e.likec4.ModelBuilder,this.#e=qn(),e.shared.workspace.WorkspaceManager.onForceCleanCache(()=>{q_.info`force clean cache`,this.#e.clear()})}get layouter(){return this.services.likec4.Layouter}async computedViews(e,t){return Te((await this.ModelBuilder.computeModel(e,t)).$data.views)}async _layoutAllViews(e,t){let n=Te(e.$data.views);if(n.length===0)return[];let r=e.project.id,i=q_.getChild(r),a=this.projectStorage(r),o=[],s=e.$styles,c=[];for(let e of n){let t={view:e,styles:s},n=await a.get(t);if(n){c.push(n);continue}o.push(t)}if(o.length>0){let e=Dp();await this.layouter.batchLayout({batch:o,cancelToken:t,onSuccess:(e,t)=>{c.push(a.remember(e,t))},onError:(e,t)=>{i.warn(`Fail layout view ${e.view.id}`,{error:t})}}),i.trace`layouted ${o.length} views in ${e.pretty}`}return t&&t.isCancellationRequested&&await bt(t),c.length!==n.length&&i.warn`layouted ${c.length} of ${n.length} views`,c}async layoutAllViews(e,t){let n=await this.ModelBuilder.computeModel(e,t);return await this._layoutAllViews(n,t)}async layoutView({viewId:e,layoutType:t,projectId:n,cancelToken:r}){let a=await this.ModelBuilder.computeModel(n,r),o=a.findView(e)?.$view;n=a.project.id;let s=q_.getChild(n);if(!o){s.warn`layoutView ${e} not found`;let t=a.findManualLayout(e);if(t){s.debug`found manual layout for ${e}`;let n={...t};return n.drifts=[`not-exists`],n._layout=`manual`,{diagram:n,dot:`# manual layout`}}return null}let c=this.projectStorage(n);try{let e={view:o,styles:a.$styles},n=await c.getOrExecute(e);return i(t)?{dot:n.dot,diagram:this.withLayoutType(n.diagram,a,t)}:n}catch(e){let t=L(e);return s.warn(t),this.reportViewError(o,n,t),Promise.reject(e)}}async diagrams(e,t){let n=await this.ModelBuilder.computeModel(e,t);return(await this._layoutAllViews(n,t)).map(({diagram:e})=>this.withLayoutType(e,n,`manual`))}async viewsAsGraphvizOut(e,t){let n=`All-LayoutedViews-DotWithSvg`,r=this.services.shared.workspace.Cache;if(r.has(n))return await Promise.resolve(r.get(n));let i=await this.ModelBuilder.computeModel(e,t),a=Te(i.$data.views);if(a.length===0)return[];let o=a.map(async e=>{let{dot:t,svg:n}=await this.layouter.svg({view:e,styles:i.$styles});return{id:e.id,dot:t,svg:n}}),s=[],c=await Promise.allSettled(o);for(let e of c)e.status===`fulfilled`?s.push(e.value):V(e.reason);return r.set(n,s),s}async openView(e,t){await this.services.Rpc.openView({viewId:e,projectId:t})}async adhocView(e,t){q_.debug`layouting adhoc view...`;let n=await this.ModelBuilder.computeModel(t),r=ji(n,e),{diagram:i}=await this.layouter.layout({view:{...r,hash:``,_type:`element`},styles:n.$styles});return q_.debug`layouting adhoc view... done`,i}reportViewError(e,t,n){this.projectStorage(t).reportViewError(e,()=>{this.services.shared.lsp.Connection?.window.showErrorMessage(`LikeC4: ${n}`)})}withLayoutType(e,t,n){if(!n)return e;let r=t.findManualLayout(e.id);return r?n===`manual`?e[or]===`manual`?(q_.error(`View ${e.id} already has manual layout, this should not happen`),e):dr(e,r):fr(e,r):e}projectStorage(e){return this.#t.get(e)}},Y_=class{#e;#t;#n;#r;constructor(e){this.#e=q_.getChild(e.projectId),this.#t=e.projectId,this.#n=e.storage,this.#r=e.layouter}async get(e){let t=X_(e),n=await this.#n.get(t);if(n)return this.#e.trace`cache hit for ${e.view.id}`,Z_(e.view,n);B.trace`cache miss for ${e.view.id}`}async getOrExecute(e){let t=X_(e),n=await this.#n.get(t);if(n)return this.#e.trace`cache hit for ${e.view.id}`,Z_(e.view,n);B.trace`cache miss for ${e.view.id}`;let r=Dp(),i=await this.#r(e);return B.trace(`layouted {view} in ${r.pretty}`,{view:e.view.id}),await this.#n.set(t,i),this.resetViewError(e.view),i}remember=(e,t)=>{let n=X_(e);return t&&(this.#n.set(n,t).catch(e=>{this.#e.error(e)}),this.resetViewError(e.view)),t};reportViewError(e,t){let n=`error-${e.id}`;this.#n.has(n).then(e=>{e||(this.#n.set(n,`true`),t())})}resetViewError(e){this.#n.del(`error-${e.id}`)}};function X_(e){return`${e.view.hash}-${e.styles.fingerprint}`}function Z_(e,t){return{dot:t.dot,diagram:ur(e,t.diagram)}}const Q_={graphviz(){return new Ha}};function $_(e){return{graphviz(){return e}}}function ev(e){return{lsp:{NodeKindProvider:e=>new G_(e),WorkspaceSymbolProvider:e=>new K_(e)},workspace:{Cache:e=>new Bt(e,S.Validated),IndexManager:e=>new Xf(e),LangiumDocuments:e=>new $f(e),ProjectsManager:e=>new vp(e),WorkspaceManager:e=>new Cp(e),FileSystemProvider:()=>e.fileSystemProvider(),FileSystemWatcher:t=>e.fileSystemWatcher(t),ManualLayouts:t=>e.manualLayouts(t)}}}function $(e){return t=>new e(t)}function tv(e){return{documentation:{DocumentationProvider:$(Qm)},validation:{DocumentValidator:$(Ig)},Rpc:$(W_),mcp:{Server:t=>e.mcpServer(t),ServerFactory:t=>e.mcpServerFactory(t)},likec4:{LanguageServices:$(oh),Graphviz:t=>e.graphviz(t),Layouter:e=>new qa({graphviz:e.likec4.Graphviz}),Views:$(J_),DeploymentsIndex:$(Nh),ModelChanges:$(b_),FqnIndex:$(kh),ModelParser:$(d_),ModelBuilder:$(Hh),ModelLocator:$(Yh),LastSeen:$(Lh)},lsp:{CompletionProvider:$(dh),DocumentHighlightProvider:$(ph),DocumentSymbolProvider:$(gh),SemanticTokenProvider:$(Dh),HoverProvider:$(vh),CodeLensProvider:$(ch),DocumentLinkProvider:$(mh),Formatter:$(rh),CodeActionProvider:$(bh)},workspace:{AstNodeDescriptionProvider:$(Yf)},references:{NameProvider:$(x_),ScopeComputation:$(C_),ScopeProvider:$(T_)},parser:{ValueConverter:$(f_)}}}function nv(e={},t,n,r){let i=rv(e),a=cn([Ht({shared:i}),Sf,tv({...Qp,...Gp,...Kp,...Q_,...e}),t,n,r].reduce(iv,{}));return i.ServiceRegistry.register(a),Bg(a),e.connection?ai(()=>a.Rpc.init()):i.workspace.ConfigurationProvider.initialized({}),{shared:i,likec4:a}}function rv(e={}){let t={...Qp,...Gp,...Kp,...e};return cn(nn(t),xf,ev(t))}function iv(e,t){if(t){for(let[n,r]of Object.entries(t))if(r!==void 0){let t=e[n];t!==null&&r!==null&&typeof t==`object`&&typeof r==`object`?e[n]=iv(t,r):e[n]=r}}return e}function av(){try{return Ja.default.sync(`dot`)}catch(e){return B.error(`Error checking for native Graphviz:`,{error:e}),null}}const ov={likec4:{Layouter(e){B.debug(`Creating ConfigurableLayouter`);let t=e.likec4.Graphviz,r=new qa({graphviz:t});return e.shared.workspace.ConfigurationProvider.onConfigurationSectionUpdate(t=>{if(B.debug(`Configuration update: {update}`,{update:t}),t.section!==e.LanguageMetaData.languageId){B.debug(`Ignoring configuration update as it is not for ${e.LanguageMetaData.languageId}`);return}try{let{mode:i,path:a}=t.configuration.graphviz??{mode:`wasm`,path:``};if(i!==`wasm`){let t=n(a)?av():a;if(!n(t)){r.changePort(new Xa(t)),B.info`use graphviz binary: ${t}`;return}B.warn(`No Graphviz binaries found on PATH, use graphviz wasm`),e.shared.lsp.Connection?.window.showWarningMessage(`No Graphviz binaries found on PATH, set path to binaries in settings.`)}r.changePort(new Ha),B.info(`use graphviz wasm`)}catch(e){B.error(`Failed to update configuration`,{error:e})}}),r}}};function sv(e){let t=e?.connection,n=Be(e,{enableWatcher:!0,enableMCP:`sse`,enableManualLayouts:!0,graphviz:`wasm`,configureLogger:!1});n.configureLogger!==!1&&(n.configureLogger===`stderr`||n.enableMCP===`stdio`?Qa({lspConnection:t,enableTelemetry:!1,useStdErr:!0}):n.configureLogger===`console`&&Qa({lspConnection:t})),t?B.info(`Starting LikeC4 language server`):B.warn(`Starting LikeC4 language server (headless - no LSP connection)`);let r=nv({...t&&{connection:t},...Xp(n.enableWatcher),...!!n.enableMCP&&Zm(n.enableMCP),...n.enableManualLayouts&&Pp,...$_(n.graphviz===`binary`?new Xa:new Ha)},t?{likec4:{...ov.likec4}}:void 0);return Nt(r.shared),r}function cv(e){let t=e?.configureLogger??!1;if(t!==!1){if(t===`stderr`||e?.mcp===`stdio`){Qa({useStdErr:!0,colors:!1,logLevel:e?.logLevel});return}Qa({colors:_i,logLevel:e?.logLevel})}}export{Zi as _,Zm as a,Ji as b,Kp as c,Xa as d,Ha as f,$i as g,ra as h,$_ as i,Pp as l,aa as m,sv as n,Xp as o,oa as p,nv as r,Gp as s,cv as t,Qa as u,Yi as v,L as x,qi as y};
|