ice-entity-designer-dsl 0.0.9 → 0.0.10

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/README.md CHANGED
@@ -14,6 +14,10 @@ One document kind, three shapes:
14
14
  enums with free-text members (`- id: string`, `+ pay(): void`), plus the six relation
15
15
  kinds (inheritance / realization / association / aggregation / composition /
16
16
  dependency). Coordinates are optional — inheritance drives a top-down layering.
17
+ - **Statechart** (`kind: "statechart"` with `nodes` / `edges`): initial/final pseudo-states,
18
+ states, **composite states** (containers — children follow when you drag the parent) and
19
+ transitions labelled `event [guard] / action`. Coordinates are optional — the flow lays
20
+ out left to right.
17
21
 
18
22
  The package contains:
19
23
 
@@ -22,7 +26,8 @@ The package contains:
22
26
  - compilers from DSL to Entity/Relation or FlowNode/FlowEdge props (shared layered layout)
23
27
  - browser runtime that renders DSL through `ice-entity-designer`
24
28
  - browser examples with a JSON editor (`examples/entity-editor-dsl.html`,
25
- `examples/flowchart-dsl.html`, `examples/bpmn-dsl.html`, `examples/uml-dsl.html`)
29
+ `examples/flowchart-dsl.html`, `examples/bpmn-dsl.html`, `examples/uml-dsl.html`,
30
+ `examples/statechart-dsl.html`)
26
31
 
27
32
  ## Install
28
33
 
@@ -129,6 +134,38 @@ const xml = IED.toBpmnXml(result.designer); // BPMN 2.0 + BPMNDI(互操作格
129
134
  const svg = result.designer.toSvg(); // 矢量 SVG(与画布同一口径,放大不糊)
130
135
  ```
131
136
 
137
+ ### Statechart usage
138
+
139
+ ```js
140
+ const chart = {
141
+ schemaVersion: 1,
142
+ kind: 'statechart',
143
+ nodes: [
144
+ { id: 'start', kind: 'initial' },
145
+ { id: 'pending', title: '待支付' },
146
+ { id: 'paid', title: '已支付' },
147
+ { id: 'processing', kind: 'composite', title: '订单处理' },
148
+ { id: 'stock', title: '库存校验', parent: 'processing' }, // 子状态:进复合状态
149
+ { id: 'done', kind: 'final' },
150
+ ],
151
+ edges: [
152
+ { source: 'start', target: 'pending' },
153
+ { source: 'pending', target: 'paid', event: '支付成功', guard: '金额 > 0', action: '生成订单' },
154
+ { source: 'paid', target: 'stock', event: '进入处理' },
155
+ { source: 'stock', target: 'done', event: '已发货' },
156
+ ],
157
+ };
158
+
159
+ const result = ICEDSL.renderDsl('canvas', chart);
160
+ // result.kind === 'statechart'; result.designer is a StatechartDesigner
161
+ result.designer.validateStatechart(); // 缺初始状态 / 终态出边 / 孤立节点 / 不可达
162
+ result.designer.toSvg(); // 矢量导出(实心箭头也是填充路径)
163
+ ```
164
+
165
+ Node kinds: `initial` (filled dot) / `final` (bullseye) / `state` (rounded box, default) /
166
+ `composite` (container; children declared with `parent`). Transition labels are composed
167
+ from `event` / `guard` / `action` (missing parts are omitted).
168
+
132
169
  ### UML usage
133
170
 
134
171
  ```js
@@ -169,11 +206,12 @@ intermediate / end) + `trigger`, gateways carry `gatewayType` (exclusive / paral
169
206
 
170
207
  ## API
171
208
 
172
- - `validateDsl(dsl)` —— ER / flowchart / BPMN / UML documents (dispatches on `kind`); `validateFlowDsl(dsl)` / `validateBpmnDsl(dsl)` / `validateUmlDsl(dsl)` for one kind only
209
+ - `validateDsl(dsl)` —— ER / flowchart / BPMN / UML / statechart documents (dispatches on `kind`); `validateFlowDsl(dsl)` / `validateBpmnDsl(dsl)` / `validateUmlDsl(dsl)` / `validateStatechartDsl(dsl)` for one kind only
173
210
  - `compileDsl(dsl)` —— ER document → `Entity` / `Relation` props
174
211
  - `compileFlowDsl(dsl)` —— flowchart document → `FlowNode` / `FlowEdge` props (with layered auto-layout)
175
212
  - `compileBpmnDsl(dsl)` —— BPMN document → `FlowNode` / `FlowEdge` props (container auto-geometry + container-scoped auto-layout)
176
213
  - `compileUmlDsl(dsl)` —— UML document → `UmlClass` / `UmlRelation` props (inheritance-driven layering)
214
+ - `compileStatechartDsl(dsl)` —— statechart document → `StateNode` / `StateTransition` props (flow layering + composite auto-sizing)
177
215
  - `layeredLayout(items, edges, options)` —— the shared layered layout (`direction: "vertical" | "horizontal"`)
178
216
  - `renderDsl(canvasOrId, dsl)` —— renders any kind, returns `{ kind, ice, designer }`
179
217
  - Export: `result.designer.toSvg(options)` (flowchart / BPMN) or `IED.exportSvg(result.ice, options)`; `options` = `{ area: 'content' | 'viewport', padding, scale, background, includeTools }`. The SVG is regenerated from the component tree + path commands, so it matches the canvas (geometry, styles, opacity, shadows, link labels) and can be rasterised to PNG/PDF by any external tool.
@@ -182,7 +220,8 @@ intermediate / end) + `trigger`, gateways carry `gatewayType` (exclusive / paral
182
220
  ## Example
183
221
 
184
222
  Open `examples/entity-editor-dsl.html` (ER), `examples/flowchart-dsl.html`
185
- (flowchart), `examples/bpmn-dsl.html` (BPMN) or `examples/uml-dsl.html` (UML) after building.
223
+ (flowchart), `examples/bpmn-dsl.html` (BPMN), `examples/uml-dsl.html` (UML) or
224
+ `examples/statechart-dsl.html` (statechart) after building.
186
225
 
187
226
  ## Agent discovery
188
227
 
package/dist/index.cjs CHANGED
@@ -1 +1 @@
1
- "use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("ice-entity-designer");function isFlowDsl(e){return!!e&&"object"==typeof e&&"flowchart"===e.kind}function isBpmnDsl(e){return!!e&&"object"==typeof e&&"bpmn"===e.kind}function isUmlDsl(e){return!!e&&"object"==typeof e&&"uml"===e.kind}const t=["terminator","process","decision","io"],i=["T","R","B","L","C"],o=["pool","lane","task","event","gateway","subprocess","dataObject","annotation"],r=["start","intermediate","end"],n=["none","message","timer","error","terminate"],s=["exclusive","parallel","inclusive","event"],a=["none","user","service","script","send","receive","manual"],l=["sequence","message","association"],d=["class","interface","enum"],p=["inheritance","realization","association","aggregation","composition","dependency"];function validateDsl(e){return isUmlDsl(e)?validateUmlDsl(e):isBpmnDsl(e)?validateBpmnDsl(e):isFlowDsl(e)?validateFlowDsl(e):function validateErDsl(e){const t=[];if(!e||"object"!=typeof e||Array.isArray(e))return{valid:!1,errors:["DSL root must be an object"]};void 0!==e.schemaVersion&&1!==e.schemaVersion&&t.push("Unsupported schemaVersion: "+e.schemaVersion);if(Array.isArray(e.entities)){const i=new Set;e.entities.forEach((e,o)=>{const r=`entities[${o}]`;e&&"object"==typeof e?("string"==typeof e.id&&e.id.trim()?i.has(e.id)?t.push(`${r}.id is duplicated: ${e.id}`):i.add(e.id):t.push(r+".id must be a non-empty string"),Array.isArray(e.fields)?e.fields.forEach((e,i)=>{e&&"object"==typeof e&&"string"==typeof e.name&&e.name.trim()||t.push(`${r}.fields[${i}].name must be a non-empty string`)}):t.push(r+".fields must be an array")):t.push(r+" must be an object")})}else t.push("entities must be an array");void 0===e.relations||Array.isArray(e.relations)?(e.relations||[]).forEach((e,i)=>{const o=`relations[${i}]`;e&&"object"==typeof e?("string"==typeof e.source&&e.source.trim()||t.push(o+".source must be a non-empty string"),"string"==typeof e.target&&e.target.trim()||t.push(o+".target must be a non-empty string")):t.push(o+" must be an object")}):t.push("relations must be an array");return{valid:0===t.length,errors:t}}(e)}function validateBpmnDsl(e){const t=[];if(!e||"object"!=typeof e||Array.isArray(e))return{valid:!1,errors:["DSL root must be an object"]};void 0!==e.schemaVersion&&1!==e.schemaVersion&&t.push("Unsupported schemaVersion: "+e.schemaVersion);const i=new Set,d=new Map;return Array.isArray(e.nodes)?(e.nodes.forEach((e,l)=>{const p=`nodes[${l}]`;if(!e||"object"!=typeof e)return void t.push(p+" must be an object");"string"==typeof e.id&&e.id.trim()?i.has(e.id)?t.push(`${p}.id is duplicated: ${e.id}`):(i.add(e.id),d.set(e.id,e.kind||"task")):t.push(p+".id must be a non-empty string"),void 0!==e.kind&&-1===o.indexOf(e.kind)&&t.push(`${p}.kind must be one of ${o.join("/")}`),["left","top","width","height"].forEach(i=>{const o=e[i];void 0!==o&&"number"!=typeof o&&t.push(`${p}.${i} must be a number when present`)});[["eventKind",r],["trigger",n],["gatewayType",s],["taskType",a]].forEach(([i,o])=>{const r=e[i];void 0!==r&&-1===o.indexOf(r)&&t.push(`${p}.${i} must be one of ${o.join("/")}`)})}),e.nodes.forEach((e,o)=>{if(!e||"object"!=typeof e||void 0===e.parent)return;const r=`nodes[${o}]`;if("string"!=typeof e.parent||!e.parent.trim())return void t.push(r+".parent must be a non-empty string when present");if(!i.has(e.parent))return void t.push(r+".parent must reference an existing node id");if(e.parent===e.id)return void t.push(r+".parent must not reference itself");const n=d.get(e.parent);"pool"===e.kind?t.push(r+".parent is not allowed on a pool (池是最外层容器)"):"lane"===e.kind&&"pool"!==n?t.push(r+".parent must reference a pool"):"pool"!==n&&"lane"!==n&&t.push(r+".parent must reference a pool or a lane")})):t.push("nodes must be an array"),void 0===e.edges||Array.isArray(e.edges)?(e.edges||[]).forEach((e,o)=>{const r=`edges[${o}]`;if(!e||"object"!=typeof e)return void t.push(r+" must be an object");"string"==typeof e.source&&e.source.trim()&&i.has(e.source)||t.push(r+".source must reference an existing node id"),"string"==typeof e.target&&e.target.trim()&&i.has(e.target)||t.push(r+".target must reference an existing node id");const n=void 0!==e.type?e.type:e.flowType;void 0!==n&&-1===l.indexOf(n)&&t.push(`${r}.type must be one of ${l.join("/")}`),void 0!==e.label&&"string"!=typeof e.label&&t.push(r+".label must be a string when present"),void 0!==e.condition&&"string"!=typeof e.condition&&t.push(r+".condition must be a string when present"),void 0!==e.linkShape&&"visio"!==e.linkShape&&"bezier"!==e.linkShape&&t.push(r+'.linkShape must be "visio" or "bezier" when present')}):t.push("edges must be an array when present"),{valid:0===t.length,errors:t}}function validateFlowDsl(e){const o=[];if(!e||"object"!=typeof e||Array.isArray(e))return{valid:!1,errors:["DSL root must be an object"]};void 0!==e.schemaVersion&&1!==e.schemaVersion&&o.push("Unsupported schemaVersion: "+e.schemaVersion);const r=new Set;return Array.isArray(e.nodes)?e.nodes.forEach((e,i)=>{const n=`nodes[${i}]`;e&&"object"==typeof e?("string"==typeof e.id&&e.id.trim()?r.has(e.id)?o.push(`${n}.id is duplicated: ${e.id}`):r.add(e.id):o.push(n+".id must be a non-empty string"),void 0!==e.kind&&-1===t.indexOf(e.kind)&&o.push(`${n}.kind must be one of ${t.join("/")}`),["left","top","width","height"].forEach(t=>{const i=e[t];void 0!==i&&"number"!=typeof i&&o.push(`${n}.${t} must be a number when present`)})):o.push(n+" must be an object")}):o.push("nodes must be an array"),void 0===e.edges||Array.isArray(e.edges)?(e.edges||[]).forEach((e,t)=>{const n=`edges[${t}]`;e&&"object"==typeof e?("string"==typeof e.source&&e.source.trim()&&r.has(e.source)||o.push(n+".source must reference an existing node id"),"string"==typeof e.target&&e.target.trim()&&r.has(e.target)||o.push(n+".target must reference an existing node id"),void 0!==e.label&&"string"!=typeof e.label&&o.push(n+".label must be a string when present"),void 0!==e.sourcePort&&-1===i.indexOf(e.sourcePort)&&o.push(`${n}.sourcePort must be one of ${i.join("/")}`),void 0!==e.targetPort&&-1===i.indexOf(e.targetPort)&&o.push(`${n}.targetPort must be one of ${i.join("/")}`),void 0!==e.linkShape&&"visio"!==e.linkShape&&"bezier"!==e.linkShape&&o.push(n+'.linkShape must be "visio" or "bezier" when present')):o.push(n+" must be an object")}):o.push("edges must be an array when present"),{valid:0===o.length,errors:o}}function validateUmlDsl(e){const t=[];if(!e||"object"!=typeof e||Array.isArray(e))return{valid:!1,errors:["DSL root must be an object"]};void 0!==e.schemaVersion&&1!==e.schemaVersion&&t.push("Unsupported schemaVersion: "+e.schemaVersion);const i=new Set;return Array.isArray(e.nodes)?e.nodes.forEach((e,o)=>{const r=`nodes[${o}]`;e&&"object"==typeof e?("string"==typeof e.id&&e.id.trim()?i.has(e.id)?t.push(`${r}.id is duplicated: ${e.id}`):i.add(e.id):t.push(r+".id must be a non-empty string"),void 0!==e.kind&&-1===d.indexOf(e.kind)&&t.push(`${r}.kind must be one of ${d.join("/")}`),["attributes","methods"].forEach(i=>{const o=e[i];void 0!==o&&(Array.isArray(o)&&!o.some(e=>"string"!=typeof e)||t.push(`${r}.${i} must be an array of strings when present`))}),["left","top","width","height"].forEach(i=>{const o=e[i];void 0!==o&&"number"!=typeof o&&t.push(`${r}.${i} must be a number when present`)})):t.push(r+" must be an object")}):t.push("nodes must be an array"),void 0===e.edges||Array.isArray(e.edges)?(e.edges||[]).forEach((e,o)=>{const r=`edges[${o}]`;if(!e||"object"!=typeof e)return void t.push(r+" must be an object");"string"==typeof e.source&&e.source.trim()&&i.has(e.source)||t.push(r+".source must reference an existing node id"),"string"==typeof e.target&&e.target.trim()&&i.has(e.target)||t.push(r+".target must reference an existing node id");const n=void 0!==e.type?e.type:e.relation;void 0!==n&&-1===p.indexOf(n)&&t.push(`${r}.type must be one of ${p.join("/")}`),void 0!==e.label&&"string"!=typeof e.label&&t.push(r+".label must be a string when present")}):t.push("edges must be an array when present"),{valid:0===t.length,errors:t}}function entityName(e){return e.entityName||e.name||e.id}function relationType(e){return e.relationType||e.type||"one-to-many"}function compileDsl(e){if(isFlowDsl(e))throw new Error("compileDsl() 只处理 ER 文档;流程图文档请使用 compileFlowDsl()");if(!e||!Array.isArray(e.entities))throw new Error("ER 文档必须包含 entities 数组");return{entities:e.entities.map(e=>({id:e.id,entityName:entityName(e),fields:e.fields||[],left:e.left,top:e.top,width:e.width,height:e.height,style:e.style,headerStyle:e.headerStyle,fieldStyle:e.fieldStyle,dividerStyle:e.dividerStyle,draggable:e.draggable,interactive:e.interactive})),relations:(e.relations||[]).map((e,t)=>({id:e.id||"relation-"+t,relationType:relationType(e),sourceId:e.source,targetId:e.target,sourceField:e.sourceField||"id",targetField:e.targetField||"id",nullable:e.nullable,onDelete:e.onDelete,onUpdate:e.onUpdate,joinTableName:e.joinTableName,fromKey:e.fromKey,toKey:e.toKey,sourceCardinality:e.sourceCardinality,targetCardinality:e.targetCardinality,label:e.label,style:e.style,arrow:e.arrow,linkShape:e.linkShape,routeType:e.routeType,routeOffset:e.routeOffset,curveType:e.curveType,lineDash:e.lineDash})),layout:e.layout,options:e.options}}function layeredLayout(e,t,i={}){const o=Number(i.gapX)||90,r=Number(i.gapY)||90,n=void 0===i.originX?80:i.originX,s=void 0===i.originY?80:i.originY,a=new Map;if(!e.length)return a;const l=new Map;e.forEach(e=>l.set(e.id,e));const d=new Map,p=new Map;e.forEach(e=>{d.set(e.id,0),p.set(e.id,[])}),t.forEach(e=>{l.has(e.sourceId)&&l.has(e.targetId)&&(d.set(e.targetId,(d.get(e.targetId)||0)+1),p.get(e.sourceId).push(e.targetId))});const h=new Map,c=[];e.forEach(e=>{0===(d.get(e.id)||0)&&(h.set(e.id,0),c.push(e.id))}),c.length||(h.set(e[0].id,0),c.push(e[0].id));let u=e.length*e.length+e.length;for(;c.length&&u-- >0;){const e=c.shift(),t=h.get(e)||0;(p.get(e)||[]).forEach(e=>{const i=t+1;(void 0===h.get(e)?-1:h.get(e))<i&&(h.set(e,i),c.push(e))})}e.forEach(e=>{h.has(e.id)||h.set(e.id,0)});const m=new Map;e.forEach(e=>{const t=h.get(e.id)||0;m.has(t)||m.set(t,[]),m.get(t).push(e)});const f=[...m.keys()].sort((e,t)=>e-t);if("horizontal"===i.direction){const e=f.map(e=>Math.max(...m.get(e).map(e=>e.width)));let t=0;f.forEach((i,n)=>{const s=m.get(i);let l=-(s.reduce((e,t)=>e+t.height,0)+Math.max(s.length-1,0)*r)/2;s.forEach(i=>{a.set(i.id,{left:Math.round(t+(e[n]-i.width)/2),top:Math.round(l)}),l+=i.height+r}),t+=e[n]+o})}else{const e=f.map(e=>Math.max(...m.get(e).map(e=>e.height)));let t=0;f.forEach((i,n)=>{const s=m.get(i);let l=-(s.reduce((e,t)=>e+t.width,0)+Math.max(s.length-1,0)*o)/2;s.forEach(i=>{a.set(i.id,{left:Math.round(l),top:Math.round(t+(e[n]-i.height)/2)}),l+=i.width+o}),t+=e[n]+r})}const g=Math.min(...e.map(e=>a.get(e.id).left)),y=Math.min(...e.map(e=>a.get(e.id).top));return a.forEach(e=>{e.left+=n-g,e.top+=s-y}),a}const h={terminator:{width:e.FLOW_NODE_KINDS.terminator.width,height:e.FLOW_NODE_KINDS.terminator.height,fill:e.FLOW_NODE_KINDS.terminator.fill,stroke:e.FLOW_NODE_KINDS.terminator.stroke},process:{width:e.FLOW_NODE_KINDS.process.width,height:e.FLOW_NODE_KINDS.process.height,fill:e.FLOW_NODE_KINDS.process.fill,stroke:e.FLOW_NODE_KINDS.process.stroke},decision:{width:e.FLOW_NODE_KINDS.decision.width,height:e.FLOW_NODE_KINDS.decision.height,fill:e.FLOW_NODE_KINDS.decision.fill,stroke:e.FLOW_NODE_KINDS.decision.stroke},io:{width:e.FLOW_NODE_KINDS.io.width,height:e.FLOW_NODE_KINDS.io.height,fill:e.FLOW_NODE_KINDS.io.fill,stroke:e.FLOW_NODE_KINDS.io.stroke}};function compileFlowDsl(e){const t=e.options||{},i=(e.nodes||[]).map(e=>{const t=function nodeKind$1(e){return e.kind&&h[e.kind]?e.kind:"process"}(e),i=h[t];return{id:e.id,typeId:"FlowNode",kind:t,title:(o=e,o.title||o.name||o.id),left:"number"==typeof e.left?e.left:Number.NaN,top:"number"==typeof e.top?e.top:Number.NaN,width:"number"==typeof e.width?e.width:i.width,height:"number"==typeof e.height?e.height:i.height,fillColor:e.fillColor||i.fill,strokeColor:e.strokeColor||i.stroke};var o}),o=(e.edges||[]).map((e,t)=>({id:e.id||"edge-"+t,sourceId:e.source,targetId:e.target,sourcePort:e.sourcePort||"B",targetPort:e.targetPort||"T",label:e.label||"",linkShape:e.linkShape||"visio"})),r=t.layout||"layered";return"none"!==r&&i.some(e=>Number.isNaN(e.left)||Number.isNaN(e.top))&&(i.forEach(e=>{Number.isNaN(e.left)&&(e.left=0),Number.isNaN(e.top)&&(e.top=0)}),function autoLayout(e,t,i,o){const r=layeredLayout(e,t,{gapX:i,gapY:o});e.forEach(e=>{const t=r.get(e.id);t&&(e.left=t.left,e.top=t.top)})}(i,o,Number(t.gapX)||90,Number(t.gapY)||90)),i.forEach(e=>{Number.isNaN(e.left)&&(e.left=0),Number.isNaN(e.top)&&(e.top=0)}),{kind:"flowchart",nodes:i,edges:o,layout:r,options:t}}const c={pool:"bpmnPool",lane:"bpmnLane",task:"bpmnTask",event:"bpmnEvent",gateway:"bpmnGateway",subprocess:"bpmnSubprocess",dataObject:"bpmnDataObject",annotation:"bpmnAnnotation"},u=Number(e.FLOW_NODE_KINDS.bpmnPool.bandSize)||32,m=Number(e.FLOW_NODE_KINDS.bpmnLane.bandSize)||32,f=Number(e.FLOW_NODE_KINDS.bpmnLane.height)||130,g=Number(e.FLOW_NODE_KINDS.bpmnPool.width)||900;function toWorkingNode(t){const i=t.kind||"task",o=function presetOf(t){return e.FLOW_NODE_KINDS[t]||e.FLOW_NODE_KINDS.bpmnTask}(c[i]||"bpmnTask"),r={id:t.id,typeId:"FlowNode",kind:c[i]||"bpmnTask",title:t.title||t.name||t.id,left:"number"==typeof t.left?t.left:0,top:"number"==typeof t.top?t.top:0,width:"number"==typeof t.width?t.width:o.width,height:"number"==typeof t.height?t.height:o.height,fillColor:t.fillColor,strokeColor:t.strokeColor,dslKind:i,parent:t.parent,explicitLeft:"number"==typeof t.left,explicitTop:"number"==typeof t.top,explicitWidth:"number"==typeof t.width,explicitHeight:"number"==typeof t.height};return"event"===i&&(r.eventKind=t.eventKind||o.eventKind||"start",r.trigger=t.trigger||o.trigger||"none"),"gateway"===i&&(r.gatewayType=t.gatewayType||o.gatewayType||"exclusive"),"task"!==i&&"subprocess"!==i||(r.taskType=t.taskType||o.taskType||"none"),r}function buildGroups(e,t){const i=new Map;t.forEach(e=>i.set(e.id,e));const o=1===t.length?t[0]:null,r=[];return e.forEach(e=>{(e=>{let t=r.filter(t=>t.owner===e)[0];return t||(t={owner:e,nodes:[],box:null,didLayout:!1},r.push(t)),t})((e.parent?i.get(e.parent):void 0)||o).nodes.push(e)}),r}function layoutGroups(e,t,i,o){e.forEach(e=>{if(e.nodes.some(e=>!e.explicitLeft||!e.explicitTop)){const r=layeredLayout(e.nodes,t,{gapX:i,gapY:o,originX:0,originY:0,direction:"horizontal"});e.nodes.forEach(e=>{const t=r.get(e.id);t&&(e.left=t.left,e.top=t.top)}),e.didLayout=!0}e.box=function unionBox(e){if(!e.length)return null;let t=1/0,i=1/0,o=-1/0,r=-1/0;return e.forEach(e=>{t=Math.min(t,e.left),i=Math.min(i,e.top),o=Math.max(o,e.left+e.width),r=Math.max(r,e.top+e.height)}),{minX:t,minY:i,maxX:o,maxY:r}}(e.nodes)})}function compileBpmnDsl(e){const t=e.options||{},i=(e.nodes||[]).map(toWorkingNode),o=i.filter(e=>"pool"===e.dslKind),r=i.filter(e=>"lane"===e.dslKind),n=i.filter(e=>!function isContainer(e){return"pool"===e.dslKind||"lane"===e.dslKind}(e)),s=(e.edges||[]).map((e,t)=>({id:e.id||"edge-"+t,sourceId:e.source,targetId:e.target,flowType:e.type||e.flowType||"sequence",label:e.label||"",condition:e.condition||"",isDefault:!!e.isDefault,linkShape:e.linkShape||"visio"})),a=t.layout||"auto",l=function resolveLaneOwners(e,t){const i=new Map;return e.forEach(e=>{let o=e.parent;o||1!==t.length||(o=t[0].id),o&&i.set(e.id,o)}),i}(r,o),lanesOf=e=>r.filter(t=>l.get(t.id)===e);let d=[];"none"!==a&&(d=buildGroups(n,o.concat(r)),layoutGroups(d,s,Number(t.gapX)||90,Number(t.gapY)||60)),r.forEach(e=>{const t=d.filter(t=>t.owner===e)[0],i=t?t.box:null;e.explicitHeight||(e.height=Math.round(Math.max(56+(i?i.maxY-i.minY:0),f))),e.explicitWidth||(e.width=Math.round(Math.max((i?i.maxX-i.minX:0)+m+56,g)))}),o.forEach(e=>{const t=lanesOf(e.id);if(t.length){const i=t.reduce((e,t)=>Math.max(e,t.width),g);return e.explicitWidth||(e.width=i),e.explicitWidth&&t.forEach(t=>{t.explicitWidth||(t.width=e.width)}),void(e.explicitHeight||(e.height=u+t.reduce((e,t)=>e+t.height,0)))}const i=d.filter(t=>t.owner===e)[0],o=i?i.box:null;e.explicitWidth||(e.width=Math.round(Math.max(56+(o?o.maxX-o.minX:0),g))),e.explicitHeight||(e.height=Math.round(Math.max((o?o.maxY-o.minY:0)+u+56,160)))});let p=60;o.forEach(e=>{e.explicitLeft||(e.left=60),e.explicitTop||(e.top=p),p=Math.max(p,e.top+e.height+60)}),o.forEach(e=>{const t=lanesOf(e.id);if(!t.length)return;const i=e.top+u,o=Math.max(e.height-u,1),r=t.reduce((e,t)=>e+(t.explicitHeight?t.height:0),0),n=t.filter(e=>!e.explicitHeight),s=n.length?Math.max(o-r,0)/n.length:0;let a=i;t.forEach(t=>{t.explicitLeft||(t.left=e.left),t.explicitTop||(t.top=a),!t.explicitHeight&&e.explicitHeight&&(t.height=Math.round(s||f)),a=t.top+t.height})});let h=60;r.forEach(e=>{l.get(e.id)||(e.explicitLeft||(e.left=60),e.explicitTop||(e.top=h,h=e.top+e.height+60))}),d.forEach(e=>{const t=e.box;if(!t||!e.didLayout)return;const i=e.owner;let o=80,r=80;i&&(o=i.left+28,r=i.top+28,"pool"===i.dslKind?r+=u:o+=m),e.nodes.forEach(e=>{e.left=Math.round(o+(e.left-t.minX)),e.top=Math.round(r+(e.top-t.minY))})});return{kind:"bpmn",nodes:o.concat(r).concat(n).map(e=>{const t={id:e.id,typeId:"FlowNode",kind:e.kind,title:e.title,left:e.left,top:e.top,width:e.width,height:e.height};return void 0!==e.eventKind&&(t.eventKind=e.eventKind),void 0!==e.trigger&&(t.trigger=e.trigger),void 0!==e.gatewayType&&(t.gatewayType=e.gatewayType),void 0!==e.taskType&&(t.taskType=e.taskType),void 0!==e.fillColor&&(t.fillColor=e.fillColor),void 0!==e.strokeColor&&(t.strokeColor=e.strokeColor),t}),edges:s,layout:a,options:t}}function compileUmlDsl(e){const t=e.options||{},i=(e.nodes||[]).map(e=>{return{id:e.id,kind:(t=e,t.kind||"class"),className:e.title||e.name||e.id,abstract:!!e.abstract,attributes:Array.isArray(e.attributes)?e.attributes.map(e=>String(e)):[],methods:Array.isArray(e.methods)?e.methods.map(e=>String(e)):[],left:"number"==typeof e.left?e.left:Number.NaN,top:"number"==typeof e.top?e.top:Number.NaN,width:"number"==typeof e.width?e.width:240,height:"number"==typeof e.height?e.height:120+24*(e.attributes?e.attributes.length:0)+24*(e.methods?e.methods.length:0)};var t}),o=(e.edges||[]).map((e,t)=>({id:e.id||"relation-"+t,sourceId:e.source,targetId:e.target,relationKind:e.type||e.relation||"association",label:e.label||""})),r=t.layout||"layered";if("none"!==r&&i.some(e=>Number.isNaN(e.left)||Number.isNaN(e.top))){i.forEach(e=>{Number.isNaN(e.left)&&(e.left=0),Number.isNaN(e.top)&&(e.top=0)});const e=layeredLayout(i,o.filter(e=>"inheritance"===e.relationKind||"realization"===e.relationKind).map(e=>({sourceId:e.targetId,targetId:e.sourceId})),{gapX:Number(t.gapX)||80,gapY:Number(t.gapY)||110,originX:80,originY:80,direction:"vertical"});i.forEach(t=>{const i=e.get(t.id);i&&(t.left=i.left,t.top=i.top)})}return i.forEach(e=>{Number.isNaN(e.left)&&(e.left=0),Number.isNaN(e.top)&&(e.top=0)}),{kind:"uml",nodes:i,edges:o,layout:r,options:t}}function renderUmlDsl(t,i){const o=compileUmlDsl(i),r=o.options||{},n=(new e.ICE).init(t),s=new e.UmlDesigner(n);return o.nodes.forEach(e=>{s.createClass({id:e.id,kind:e.kind,className:e.className,abstract:e.abstract,attributes:e.attributes,methods:e.methods,left:e.left,top:e.top,width:e.width})}),o.edges.forEach(e=>{s.createRelation(e)}),s.select(null),r.viewport?n.setViewport(r.viewport.scale,r.viewport.tx,r.viewport.ty):!1!==r.fitViewport&&s.fitViewport(r.fitViewportPadding),s.resetHistory(),{kind:"uml",ice:n,designer:s}}function renderBpmnDsl(t,i){const o=compileBpmnDsl(i),r=o.options||{},n=(new e.ICE).init(t),s=new e.BpmnDesigner(n);return o.nodes.forEach(e=>{const t={id:e.id,title:e.title,left:e.left,top:e.top,width:e.width,height:e.height};["eventKind","trigger","gatewayType","taskType","fillColor","strokeColor"].forEach(i=>{void 0!==e[i]&&(t[i]=e[i])}),s.createNode(e.kind,t)}),o.edges.forEach(e=>{s.createEdge(e)}),s.select(null),r.viewport?n.setViewport(r.viewport.scale,r.viewport.tx,r.viewport.ty):!1!==r.fitViewport&&s.fitViewport(r.fitViewportPadding),s.resetHistory(),{kind:"bpmn",ice:n,designer:s}}function renderFlowDsl(t,i){const o=compileFlowDsl(i),r=o.options||{},n=(new e.ICE).init(t),s=new e.FlowDesigner(n);return o.nodes.forEach(e=>{s.createNode(e.kind,e)}),o.edges.forEach(e=>{s.createEdge(e)}),s.select(null),r.viewport?n.setViewport(r.viewport.scale,r.viewport.tx,r.viewport.ty):!1!==r.fitViewport&&s.fitViewport(r.fitViewportPadding),s.resetHistory(),{kind:"flowchart",ice:n,designer:s}}exports.DSL_SCHEMA_VERSION=1,exports.compileBpmnDsl=compileBpmnDsl,exports.compileDsl=compileDsl,exports.compileFlowDsl=compileFlowDsl,exports.compileUmlDsl=compileUmlDsl,exports.isBpmnDsl=isBpmnDsl,exports.isFlowDsl=isFlowDsl,exports.isUmlDsl=isUmlDsl,exports.layeredLayout=layeredLayout,exports.renderBpmnDsl=renderBpmnDsl,exports.renderDsl=function renderDsl(t,i){const o=validateDsl(i);if(!o.valid)throw new Error(o.errors.join("\n"));return isUmlDsl(i)?renderUmlDsl(t,i):isBpmnDsl(i)?renderBpmnDsl(t,i):isFlowDsl(i)?renderFlowDsl(t,i):function renderErDsl(t,i){const o=compileDsl(i),r=o.options||{},n=(new e.ICE).init(t),s=new e.EntityDesigner(n);o.entities.forEach(e=>{s.createEntity(e)}),function positionLinks(e,t,i){const o=new Map;return e.entities.forEach(e=>{o.set(e.state.id,e.getMinBoundingBox(!0))}),t.relations.map(e=>{const t=o.get(e.sourceId),r=o.get(e.targetId);let n="R",s="L";if(t&&r){const e=r.center[0]-t.center[0],i=r.center[1]-t.center[1];Math.abs(e)>Math.abs(i)?(n=e>=0?"R":"L",s=e>=0?"L":"R"):(n=i>=0?"B":"T",s=i>=0?"T":"B")}return{...e,routeType:e.routeType||i||"orthogonal",linkShape:e.linkShape||"visio",links:{start:{id:e.sourceId,position:n},end:{id:e.targetId,position:s}}}})}(s,o,r.routeType).forEach(e=>{s.createRelation(e)}),("layered"===o.layout||"horizontal"===o.layout)&&new e.ICELayeredLayout({gapX:r.gapX||120,gapY:r.gapY||50}).layoutContainer(n);r.viewport?n.setViewport(r.viewport.scale,r.viewport.tx,r.viewport.ty):r.fitViewport&&function fitViewport(e,t,i){const o=t.entities||[];let r=1/0,n=1/0,s=-1/0,a=-1/0;o.forEach(e=>{const t=e.getMinBoundingBox(!0).getMinAndMaxPoint();r=Math.min(r,t.minX),n=Math.min(n,t.minY),s=Math.max(s,t.maxX),a=Math.max(a,t.maxY)});const l=s-r,d=a-n,p=e.canvasWidth||0,h=e.canvasHeight||0;if(!p||!h||l<=0||d<=0)return;const c=Number.isFinite(i)&&i>=0?i:40,u=Math.max(1,p-2*c),m=Math.max(1,h-2*c),f=Math.min(u/l,m/d,1),g=(p-l*f)/2-r*f,y=(h-d*f)/2-n*f;e.setViewport(f,g,y)}(n,s,r.fitViewportPadding);return{kind:"entity",ice:n,designer:s}}(t,i)},exports.renderFlowDsl=renderFlowDsl,exports.renderUmlDsl=renderUmlDsl,exports.validateBpmnDsl=validateBpmnDsl,exports.validateDsl=validateDsl,exports.validateFlowDsl=validateFlowDsl,exports.validateUmlDsl=validateUmlDsl;
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("ice-entity-designer");function isFlowDsl(e){return!!e&&"object"==typeof e&&"flowchart"===e.kind}function isBpmnDsl(e){return!!e&&"object"==typeof e&&"bpmn"===e.kind}function isUmlDsl(e){return!!e&&"object"==typeof e&&"uml"===e.kind}function isStatechartDsl(e){return!!e&&"object"==typeof e&&"statechart"===e.kind}const t=["terminator","process","decision","io"],i=["T","R","B","L","C"],o=["pool","lane","task","event","gateway","subprocess","dataObject","annotation"],r=["start","intermediate","end"],n=["none","message","timer","error","terminate"],s=["exclusive","parallel","inclusive","event"],a=["none","user","service","script","send","receive","manual"],d=["sequence","message","association"],l=["initial","final","state","composite"],p=["class","interface","enum"],h=["inheritance","realization","association","aggregation","composition","dependency"];function validateDsl(e){return isStatechartDsl(e)?validateStatechartDsl(e):isUmlDsl(e)?validateUmlDsl(e):isBpmnDsl(e)?validateBpmnDsl(e):isFlowDsl(e)?validateFlowDsl(e):function validateErDsl(e){const t=[];if(!e||"object"!=typeof e||Array.isArray(e))return{valid:!1,errors:["DSL root must be an object"]};void 0!==e.schemaVersion&&1!==e.schemaVersion&&t.push("Unsupported schemaVersion: "+e.schemaVersion);if(Array.isArray(e.entities)){const i=new Set;e.entities.forEach((e,o)=>{const r=`entities[${o}]`;e&&"object"==typeof e?("string"==typeof e.id&&e.id.trim()?i.has(e.id)?t.push(`${r}.id is duplicated: ${e.id}`):i.add(e.id):t.push(r+".id must be a non-empty string"),Array.isArray(e.fields)?e.fields.forEach((e,i)=>{e&&"object"==typeof e&&"string"==typeof e.name&&e.name.trim()||t.push(`${r}.fields[${i}].name must be a non-empty string`)}):t.push(r+".fields must be an array")):t.push(r+" must be an object")})}else t.push("entities must be an array");void 0===e.relations||Array.isArray(e.relations)?(e.relations||[]).forEach((e,i)=>{const o=`relations[${i}]`;e&&"object"==typeof e?("string"==typeof e.source&&e.source.trim()||t.push(o+".source must be a non-empty string"),"string"==typeof e.target&&e.target.trim()||t.push(o+".target must be a non-empty string")):t.push(o+" must be an object")}):t.push("relations must be an array");return{valid:0===t.length,errors:t}}(e)}function validateBpmnDsl(e){const t=[];if(!e||"object"!=typeof e||Array.isArray(e))return{valid:!1,errors:["DSL root must be an object"]};void 0!==e.schemaVersion&&1!==e.schemaVersion&&t.push("Unsupported schemaVersion: "+e.schemaVersion);const i=new Set,l=new Map;return Array.isArray(e.nodes)?(e.nodes.forEach((e,d)=>{const p=`nodes[${d}]`;if(!e||"object"!=typeof e)return void t.push(p+" must be an object");"string"==typeof e.id&&e.id.trim()?i.has(e.id)?t.push(`${p}.id is duplicated: ${e.id}`):(i.add(e.id),l.set(e.id,e.kind||"task")):t.push(p+".id must be a non-empty string"),void 0!==e.kind&&-1===o.indexOf(e.kind)&&t.push(`${p}.kind must be one of ${o.join("/")}`),["left","top","width","height"].forEach(i=>{const o=e[i];void 0!==o&&"number"!=typeof o&&t.push(`${p}.${i} must be a number when present`)});[["eventKind",r],["trigger",n],["gatewayType",s],["taskType",a]].forEach(([i,o])=>{const r=e[i];void 0!==r&&-1===o.indexOf(r)&&t.push(`${p}.${i} must be one of ${o.join("/")}`)})}),e.nodes.forEach((e,o)=>{if(!e||"object"!=typeof e||void 0===e.parent)return;const r=`nodes[${o}]`;if("string"!=typeof e.parent||!e.parent.trim())return void t.push(r+".parent must be a non-empty string when present");if(!i.has(e.parent))return void t.push(r+".parent must reference an existing node id");if(e.parent===e.id)return void t.push(r+".parent must not reference itself");const n=l.get(e.parent);"pool"===e.kind?t.push(r+".parent is not allowed on a pool (池是最外层容器)"):"lane"===e.kind&&"pool"!==n?t.push(r+".parent must reference a pool"):"pool"!==n&&"lane"!==n&&t.push(r+".parent must reference a pool or a lane")})):t.push("nodes must be an array"),void 0===e.edges||Array.isArray(e.edges)?(e.edges||[]).forEach((e,o)=>{const r=`edges[${o}]`;if(!e||"object"!=typeof e)return void t.push(r+" must be an object");"string"==typeof e.source&&e.source.trim()&&i.has(e.source)||t.push(r+".source must reference an existing node id"),"string"==typeof e.target&&e.target.trim()&&i.has(e.target)||t.push(r+".target must reference an existing node id");const n=void 0!==e.type?e.type:e.flowType;void 0!==n&&-1===d.indexOf(n)&&t.push(`${r}.type must be one of ${d.join("/")}`),void 0!==e.label&&"string"!=typeof e.label&&t.push(r+".label must be a string when present"),void 0!==e.condition&&"string"!=typeof e.condition&&t.push(r+".condition must be a string when present"),void 0!==e.linkShape&&"visio"!==e.linkShape&&"bezier"!==e.linkShape&&t.push(r+'.linkShape must be "visio" or "bezier" when present')}):t.push("edges must be an array when present"),{valid:0===t.length,errors:t}}function validateFlowDsl(e){const o=[];if(!e||"object"!=typeof e||Array.isArray(e))return{valid:!1,errors:["DSL root must be an object"]};void 0!==e.schemaVersion&&1!==e.schemaVersion&&o.push("Unsupported schemaVersion: "+e.schemaVersion);const r=new Set;return Array.isArray(e.nodes)?e.nodes.forEach((e,i)=>{const n=`nodes[${i}]`;e&&"object"==typeof e?("string"==typeof e.id&&e.id.trim()?r.has(e.id)?o.push(`${n}.id is duplicated: ${e.id}`):r.add(e.id):o.push(n+".id must be a non-empty string"),void 0!==e.kind&&-1===t.indexOf(e.kind)&&o.push(`${n}.kind must be one of ${t.join("/")}`),["left","top","width","height"].forEach(t=>{const i=e[t];void 0!==i&&"number"!=typeof i&&o.push(`${n}.${t} must be a number when present`)})):o.push(n+" must be an object")}):o.push("nodes must be an array"),void 0===e.edges||Array.isArray(e.edges)?(e.edges||[]).forEach((e,t)=>{const n=`edges[${t}]`;e&&"object"==typeof e?("string"==typeof e.source&&e.source.trim()&&r.has(e.source)||o.push(n+".source must reference an existing node id"),"string"==typeof e.target&&e.target.trim()&&r.has(e.target)||o.push(n+".target must reference an existing node id"),void 0!==e.label&&"string"!=typeof e.label&&o.push(n+".label must be a string when present"),void 0!==e.sourcePort&&-1===i.indexOf(e.sourcePort)&&o.push(`${n}.sourcePort must be one of ${i.join("/")}`),void 0!==e.targetPort&&-1===i.indexOf(e.targetPort)&&o.push(`${n}.targetPort must be one of ${i.join("/")}`),void 0!==e.linkShape&&"visio"!==e.linkShape&&"bezier"!==e.linkShape&&o.push(n+'.linkShape must be "visio" or "bezier" when present')):o.push(n+" must be an object")}):o.push("edges must be an array when present"),{valid:0===o.length,errors:o}}function validateUmlDsl(e){const t=[];if(!e||"object"!=typeof e||Array.isArray(e))return{valid:!1,errors:["DSL root must be an object"]};void 0!==e.schemaVersion&&1!==e.schemaVersion&&t.push("Unsupported schemaVersion: "+e.schemaVersion);const i=new Set;return Array.isArray(e.nodes)?e.nodes.forEach((e,o)=>{const r=`nodes[${o}]`;e&&"object"==typeof e?("string"==typeof e.id&&e.id.trim()?i.has(e.id)?t.push(`${r}.id is duplicated: ${e.id}`):i.add(e.id):t.push(r+".id must be a non-empty string"),void 0!==e.kind&&-1===p.indexOf(e.kind)&&t.push(`${r}.kind must be one of ${p.join("/")}`),["attributes","methods"].forEach(i=>{const o=e[i];void 0!==o&&(Array.isArray(o)&&!o.some(e=>"string"!=typeof e)||t.push(`${r}.${i} must be an array of strings when present`))}),["left","top","width","height"].forEach(i=>{const o=e[i];void 0!==o&&"number"!=typeof o&&t.push(`${r}.${i} must be a number when present`)})):t.push(r+" must be an object")}):t.push("nodes must be an array"),void 0===e.edges||Array.isArray(e.edges)?(e.edges||[]).forEach((e,o)=>{const r=`edges[${o}]`;if(!e||"object"!=typeof e)return void t.push(r+" must be an object");"string"==typeof e.source&&e.source.trim()&&i.has(e.source)||t.push(r+".source must reference an existing node id"),"string"==typeof e.target&&e.target.trim()&&i.has(e.target)||t.push(r+".target must reference an existing node id");const n=void 0!==e.type?e.type:e.relation;void 0!==n&&-1===h.indexOf(n)&&t.push(`${r}.type must be one of ${h.join("/")}`),void 0!==e.label&&"string"!=typeof e.label&&t.push(r+".label must be a string when present")}):t.push("edges must be an array when present"),{valid:0===t.length,errors:t}}function validateStatechartDsl(e){const t=[];if(!e||"object"!=typeof e||Array.isArray(e))return{valid:!1,errors:["DSL root must be an object"]};void 0!==e.schemaVersion&&1!==e.schemaVersion&&t.push("Unsupported schemaVersion: "+e.schemaVersion);const i=new Set,o=new Map;return Array.isArray(e.nodes)?(e.nodes.forEach((e,r)=>{const n=`nodes[${r}]`;e&&"object"==typeof e?("string"==typeof e.id&&e.id.trim()?i.has(e.id)?t.push(`${n}.id is duplicated: ${e.id}`):(i.add(e.id),o.set(e.id,e.kind||"state")):t.push(n+".id must be a non-empty string"),void 0!==e.kind&&-1===l.indexOf(e.kind)&&t.push(`${n}.kind must be one of ${l.join("/")}`),["left","top","width","height"].forEach(i=>{const o=e[i];void 0!==o&&"number"!=typeof o&&t.push(`${n}.${i} must be a number when present`)})):t.push(n+" must be an object")}),e.nodes.forEach((e,r)=>{if(!e||"object"!=typeof e||void 0===e.parent)return;const n=`nodes[${r}]`;"string"==typeof e.parent&&e.parent.trim()&&i.has(e.parent)?e.parent!==e.id?"composite"!==o.get(e.parent)&&t.push(n+".parent must reference a composite state"):t.push(n+".parent must not reference itself"):t.push(n+".parent must reference an existing node id")})):t.push("nodes must be an array"),void 0===e.edges||Array.isArray(e.edges)?(e.edges||[]).forEach((e,o)=>{const r=`edges[${o}]`;e&&"object"==typeof e?("string"==typeof e.source&&e.source.trim()&&i.has(e.source)||t.push(r+".source must reference an existing node id"),"string"==typeof e.target&&e.target.trim()&&i.has(e.target)||t.push(r+".target must reference an existing node id"),["event","guard","action","label"].forEach(i=>{const o=e[i];void 0!==o&&"string"!=typeof o&&t.push(`${r}.${i} must be a string when present`)})):t.push(r+" must be an object")}):t.push("edges must be an array when present"),{valid:0===t.length,errors:t}}function entityName(e){return e.entityName||e.name||e.id}function relationType(e){return e.relationType||e.type||"one-to-many"}function compileDsl(e){if(isFlowDsl(e))throw new Error("compileDsl() 只处理 ER 文档;流程图文档请使用 compileFlowDsl()");if(!e||!Array.isArray(e.entities))throw new Error("ER 文档必须包含 entities 数组");return{entities:e.entities.map(e=>({id:e.id,entityName:entityName(e),fields:e.fields||[],left:e.left,top:e.top,width:e.width,height:e.height,style:e.style,headerStyle:e.headerStyle,fieldStyle:e.fieldStyle,dividerStyle:e.dividerStyle,draggable:e.draggable,interactive:e.interactive})),relations:(e.relations||[]).map((e,t)=>({id:e.id||"relation-"+t,relationType:relationType(e),sourceId:e.source,targetId:e.target,sourceField:e.sourceField||"id",targetField:e.targetField||"id",nullable:e.nullable,onDelete:e.onDelete,onUpdate:e.onUpdate,joinTableName:e.joinTableName,fromKey:e.fromKey,toKey:e.toKey,sourceCardinality:e.sourceCardinality,targetCardinality:e.targetCardinality,label:e.label,style:e.style,arrow:e.arrow,linkShape:e.linkShape,routeType:e.routeType,routeOffset:e.routeOffset,curveType:e.curveType,lineDash:e.lineDash})),layout:e.layout,options:e.options}}function layeredLayout(e,t,i={}){const o=Number(i.gapX)||90,r=Number(i.gapY)||90,n=void 0===i.originX?80:i.originX,s=void 0===i.originY?80:i.originY,a=new Map;if(!e.length)return a;const d=new Map;e.forEach(e=>d.set(e.id,e));const l=new Map,p=new Map;e.forEach(e=>{l.set(e.id,0),p.set(e.id,[])}),t.forEach(e=>{d.has(e.sourceId)&&d.has(e.targetId)&&(l.set(e.targetId,(l.get(e.targetId)||0)+1),p.get(e.sourceId).push(e.targetId))});const h=new Map,c=[];e.forEach(e=>{0===(l.get(e.id)||0)&&(h.set(e.id,0),c.push(e.id))}),c.length||(h.set(e[0].id,0),c.push(e[0].id));let u=e.length*e.length+e.length;for(;c.length&&u-- >0;){const e=c.shift(),t=h.get(e)||0;(p.get(e)||[]).forEach(e=>{const i=t+1;(void 0===h.get(e)?-1:h.get(e))<i&&(h.set(e,i),c.push(e))})}e.forEach(e=>{h.has(e.id)||h.set(e.id,0)});const f=new Map;e.forEach(e=>{const t=h.get(e.id)||0;f.has(t)||f.set(t,[]),f.get(t).push(e)});const m=[...f.keys()].sort((e,t)=>e-t);if("horizontal"===i.direction){const e=m.map(e=>Math.max(...f.get(e).map(e=>e.width)));let t=0;m.forEach((i,n)=>{const s=f.get(i);let d=-(s.reduce((e,t)=>e+t.height,0)+Math.max(s.length-1,0)*r)/2;s.forEach(i=>{a.set(i.id,{left:Math.round(t+(e[n]-i.width)/2),top:Math.round(d)}),d+=i.height+r}),t+=e[n]+o})}else{const e=m.map(e=>Math.max(...f.get(e).map(e=>e.height)));let t=0;m.forEach((i,n)=>{const s=f.get(i);let d=-(s.reduce((e,t)=>e+t.width,0)+Math.max(s.length-1,0)*o)/2;s.forEach(i=>{a.set(i.id,{left:Math.round(d),top:Math.round(t+(e[n]-i.height)/2)}),d+=i.width+o}),t+=e[n]+r})}const g=Math.min(...e.map(e=>a.get(e.id).left)),y=Math.min(...e.map(e=>a.get(e.id).top));return a.forEach(e=>{e.left+=n-g,e.top+=s-y}),a}const c={terminator:{width:e.FLOW_NODE_KINDS.terminator.width,height:e.FLOW_NODE_KINDS.terminator.height,fill:e.FLOW_NODE_KINDS.terminator.fill,stroke:e.FLOW_NODE_KINDS.terminator.stroke},process:{width:e.FLOW_NODE_KINDS.process.width,height:e.FLOW_NODE_KINDS.process.height,fill:e.FLOW_NODE_KINDS.process.fill,stroke:e.FLOW_NODE_KINDS.process.stroke},decision:{width:e.FLOW_NODE_KINDS.decision.width,height:e.FLOW_NODE_KINDS.decision.height,fill:e.FLOW_NODE_KINDS.decision.fill,stroke:e.FLOW_NODE_KINDS.decision.stroke},io:{width:e.FLOW_NODE_KINDS.io.width,height:e.FLOW_NODE_KINDS.io.height,fill:e.FLOW_NODE_KINDS.io.fill,stroke:e.FLOW_NODE_KINDS.io.stroke}};function compileFlowDsl(e){const t=e.options||{},i=(e.nodes||[]).map(e=>{const t=function nodeKind$1(e){return e.kind&&c[e.kind]?e.kind:"process"}(e),i=c[t];return{id:e.id,typeId:"FlowNode",kind:t,title:(o=e,o.title||o.name||o.id),left:"number"==typeof e.left?e.left:Number.NaN,top:"number"==typeof e.top?e.top:Number.NaN,width:"number"==typeof e.width?e.width:i.width,height:"number"==typeof e.height?e.height:i.height,fillColor:e.fillColor||i.fill,strokeColor:e.strokeColor||i.stroke};var o}),o=(e.edges||[]).map((e,t)=>({id:e.id||"edge-"+t,sourceId:e.source,targetId:e.target,sourcePort:e.sourcePort||"B",targetPort:e.targetPort||"T",label:e.label||"",linkShape:e.linkShape||"visio"})),r=t.layout||"layered";return"none"!==r&&i.some(e=>Number.isNaN(e.left)||Number.isNaN(e.top))&&(i.forEach(e=>{Number.isNaN(e.left)&&(e.left=0),Number.isNaN(e.top)&&(e.top=0)}),function autoLayout(e,t,i,o){const r=layeredLayout(e,t,{gapX:i,gapY:o});e.forEach(e=>{const t=r.get(e.id);t&&(e.left=t.left,e.top=t.top)})}(i,o,Number(t.gapX)||90,Number(t.gapY)||90)),i.forEach(e=>{Number.isNaN(e.left)&&(e.left=0),Number.isNaN(e.top)&&(e.top=0)}),{kind:"flowchart",nodes:i,edges:o,layout:r,options:t}}const u={pool:"bpmnPool",lane:"bpmnLane",task:"bpmnTask",event:"bpmnEvent",gateway:"bpmnGateway",subprocess:"bpmnSubprocess",dataObject:"bpmnDataObject",annotation:"bpmnAnnotation"},f=Number(e.FLOW_NODE_KINDS.bpmnPool.bandSize)||32,m=Number(e.FLOW_NODE_KINDS.bpmnLane.bandSize)||32,g=Number(e.FLOW_NODE_KINDS.bpmnLane.height)||130,y=Number(e.FLOW_NODE_KINDS.bpmnPool.width)||900;function toWorkingNode(t){const i=t.kind||"task",o=function presetOf(t){return e.FLOW_NODE_KINDS[t]||e.FLOW_NODE_KINDS.bpmnTask}(u[i]||"bpmnTask"),r={id:t.id,typeId:"FlowNode",kind:u[i]||"bpmnTask",title:t.title||t.name||t.id,left:"number"==typeof t.left?t.left:0,top:"number"==typeof t.top?t.top:0,width:"number"==typeof t.width?t.width:o.width,height:"number"==typeof t.height?t.height:o.height,fillColor:t.fillColor,strokeColor:t.strokeColor,dslKind:i,parent:t.parent,explicitLeft:"number"==typeof t.left,explicitTop:"number"==typeof t.top,explicitWidth:"number"==typeof t.width,explicitHeight:"number"==typeof t.height};return"event"===i&&(r.eventKind=t.eventKind||o.eventKind||"start",r.trigger=t.trigger||o.trigger||"none"),"gateway"===i&&(r.gatewayType=t.gatewayType||o.gatewayType||"exclusive"),"task"!==i&&"subprocess"!==i||(r.taskType=t.taskType||o.taskType||"none"),r}function buildGroups(e,t){const i=new Map;t.forEach(e=>i.set(e.id,e));const o=1===t.length?t[0]:null,r=[];return e.forEach(e=>{(e=>{let t=r.filter(t=>t.owner===e)[0];return t||(t={owner:e,nodes:[],box:null,didLayout:!1},r.push(t)),t})((e.parent?i.get(e.parent):void 0)||o).nodes.push(e)}),r}function layoutGroups(e,t,i,o){e.forEach(e=>{if(e.nodes.some(e=>!e.explicitLeft||!e.explicitTop)){const r=layeredLayout(e.nodes,t,{gapX:i,gapY:o,originX:0,originY:0,direction:"horizontal"});e.nodes.forEach(e=>{const t=r.get(e.id);t&&(e.left=t.left,e.top=t.top)}),e.didLayout=!0}e.box=function unionBox(e){if(!e.length)return null;let t=1/0,i=1/0,o=-1/0,r=-1/0;return e.forEach(e=>{t=Math.min(t,e.left),i=Math.min(i,e.top),o=Math.max(o,e.left+e.width),r=Math.max(r,e.top+e.height)}),{minX:t,minY:i,maxX:o,maxY:r}}(e.nodes)})}function compileBpmnDsl(e){const t=e.options||{},i=(e.nodes||[]).map(toWorkingNode),o=i.filter(e=>"pool"===e.dslKind),r=i.filter(e=>"lane"===e.dslKind),n=i.filter(e=>!function isContainer(e){return"pool"===e.dslKind||"lane"===e.dslKind}(e)),s=(e.edges||[]).map((e,t)=>({id:e.id||"edge-"+t,sourceId:e.source,targetId:e.target,flowType:e.type||e.flowType||"sequence",label:e.label||"",condition:e.condition||"",isDefault:!!e.isDefault,linkShape:e.linkShape||"visio"})),a=t.layout||"auto",d=function resolveLaneOwners(e,t){const i=new Map;return e.forEach(e=>{let o=e.parent;o||1!==t.length||(o=t[0].id),o&&i.set(e.id,o)}),i}(r,o),lanesOf=e=>r.filter(t=>d.get(t.id)===e);let l=[];"none"!==a&&(l=buildGroups(n,o.concat(r)),layoutGroups(l,s,Number(t.gapX)||90,Number(t.gapY)||60)),r.forEach(e=>{const t=l.filter(t=>t.owner===e)[0],i=t?t.box:null;e.explicitHeight||(e.height=Math.round(Math.max(56+(i?i.maxY-i.minY:0),g))),e.explicitWidth||(e.width=Math.round(Math.max((i?i.maxX-i.minX:0)+m+56,y)))}),o.forEach(e=>{const t=lanesOf(e.id);if(t.length){const i=t.reduce((e,t)=>Math.max(e,t.width),y);return e.explicitWidth||(e.width=i),e.explicitWidth&&t.forEach(t=>{t.explicitWidth||(t.width=e.width)}),void(e.explicitHeight||(e.height=f+t.reduce((e,t)=>e+t.height,0)))}const i=l.filter(t=>t.owner===e)[0],o=i?i.box:null;e.explicitWidth||(e.width=Math.round(Math.max(56+(o?o.maxX-o.minX:0),y))),e.explicitHeight||(e.height=Math.round(Math.max((o?o.maxY-o.minY:0)+f+56,160)))});let p=60;o.forEach(e=>{e.explicitLeft||(e.left=60),e.explicitTop||(e.top=p),p=Math.max(p,e.top+e.height+60)}),o.forEach(e=>{const t=lanesOf(e.id);if(!t.length)return;const i=e.top+f,o=Math.max(e.height-f,1),r=t.reduce((e,t)=>e+(t.explicitHeight?t.height:0),0),n=t.filter(e=>!e.explicitHeight),s=n.length?Math.max(o-r,0)/n.length:0;let a=i;t.forEach(t=>{t.explicitLeft||(t.left=e.left),t.explicitTop||(t.top=a),!t.explicitHeight&&e.explicitHeight&&(t.height=Math.round(s||g)),a=t.top+t.height})});let h=60;r.forEach(e=>{d.get(e.id)||(e.explicitLeft||(e.left=60),e.explicitTop||(e.top=h,h=e.top+e.height+60))}),l.forEach(e=>{const t=e.box;if(!t||!e.didLayout)return;const i=e.owner;let o=80,r=80;i&&(o=i.left+28,r=i.top+28,"pool"===i.dslKind?r+=f:o+=m),e.nodes.forEach(e=>{e.left=Math.round(o+(e.left-t.minX)),e.top=Math.round(r+(e.top-t.minY))})});return{kind:"bpmn",nodes:o.concat(r).concat(n).map(e=>{const t={id:e.id,typeId:"FlowNode",kind:e.kind,title:e.title,left:e.left,top:e.top,width:e.width,height:e.height};return void 0!==e.eventKind&&(t.eventKind=e.eventKind),void 0!==e.trigger&&(t.trigger=e.trigger),void 0!==e.gatewayType&&(t.gatewayType=e.gatewayType),void 0!==e.taskType&&(t.taskType=e.taskType),void 0!==e.fillColor&&(t.fillColor=e.fillColor),void 0!==e.strokeColor&&(t.strokeColor=e.strokeColor),t}),edges:s,layout:a,options:t}}function compileUmlDsl(e){const t=e.options||{},i=(e.nodes||[]).map(e=>{return{id:e.id,kind:(t=e,t.kind||"class"),className:e.title||e.name||e.id,abstract:!!e.abstract,attributes:Array.isArray(e.attributes)?e.attributes.map(e=>String(e)):[],methods:Array.isArray(e.methods)?e.methods.map(e=>String(e)):[],left:"number"==typeof e.left?e.left:Number.NaN,top:"number"==typeof e.top?e.top:Number.NaN,width:"number"==typeof e.width?e.width:240,height:"number"==typeof e.height?e.height:120+24*(e.attributes?e.attributes.length:0)+24*(e.methods?e.methods.length:0)};var t}),o=(e.edges||[]).map((e,t)=>({id:e.id||"relation-"+t,sourceId:e.source,targetId:e.target,relationKind:e.type||e.relation||"association",label:e.label||""})),r=t.layout||"layered";if("none"!==r&&i.some(e=>Number.isNaN(e.left)||Number.isNaN(e.top))){i.forEach(e=>{Number.isNaN(e.left)&&(e.left=0),Number.isNaN(e.top)&&(e.top=0)});const e=layeredLayout(i,o.filter(e=>"inheritance"===e.relationKind||"realization"===e.relationKind).map(e=>({sourceId:e.targetId,targetId:e.sourceId})),{gapX:Number(t.gapX)||80,gapY:Number(t.gapY)||110,originX:80,originY:80,direction:"vertical"});i.forEach(t=>{const i=e.get(t.id);i&&(t.left=i.left,t.top=i.top)})}return i.forEach(e=>{Number.isNaN(e.left)&&(e.left=0),Number.isNaN(e.top)&&(e.top=0)}),{kind:"uml",nodes:i,edges:o,layout:r,options:t}}const b={width:160,height:64},w={width:500,height:200};function compileStatechartDsl(e){const t=e.options||{},i=(e.nodes||[]).map(e=>{const t=e.kind||"state",i="initial"===t||"final"===t,o="composite"===t?w:i?{width:24,height:24}:b;return{id:e.id,kind:t,title:e.title||e.name||(i?"":e.id),parent:e.parent,left:"number"==typeof e.left?e.left:Number.NaN,top:"number"==typeof e.top?e.top:Number.NaN,width:"number"==typeof e.width?e.width:o.width,height:"number"==typeof e.height?e.height:o.height}}),o=(e.edges||[]).map((e,t)=>({id:e.id||"transition-"+t,sourceId:e.source,targetId:e.target,event:e.event||"",guard:e.guard||"",action:e.action||"",label:e.label})),r=t.layout||"auto",n=new Set;if("none"!==r){const e=new Map;i.forEach(t=>e.set(t.id,t));const r=i.filter(t=>!(t.parent&&e.has(t.parent)));if(r.some(e=>Number.isNaN(e.left)||Number.isNaN(e.top))){const containerOf=t=>{let i=e.get(t);for(;i&&i.parent&&e.has(i.parent);)i=e.get(i.parent);return i?i.id:t},i=o.map(e=>({sourceId:containerOf(e.sourceId),targetId:containerOf(e.targetId)})).filter(e=>e.sourceId!==e.targetId),n=layeredLayout(r,i,{gapX:Number(t.gapX)||110,gapY:Number(t.gapY)||80,originX:80,originY:80,direction:"horizontal"});r.forEach(e=>{const t=n.get(e.id);t&&(e.left=t.left,e.top=t.top)})}let s=0;i.filter(e=>"composite"===e.kind).forEach(e=>{const t=i.filter(t=>t.parent===e.id);if(Number.isNaN(e.left)&&(e.left=80),Number.isNaN(e.top)){const t=Math.max(...r.filter(t=>t!==e&&!Number.isNaN(t.top)).map(e=>e.top+e.height),0);e.top=Math.max(t+60,80)+s,s+=e.height+60}if(!t.length)return;let o=56,a=56,d=0,l=56;const p=e.width-112;t.forEach(e=>{(Number.isNaN(e.left)||Number.isNaN(e.top))&&(o>56&&o+e.width>56+p&&(o=56,a=l+40),n.add(e.id),e.left=o,e.top=a,o+=e.width+40,d=Math.max(d,o),l=Math.max(l,a+e.height))}),e.width=Math.max(e.width,d+56),e.height=Math.max(e.height,l+56)}),i.forEach(e=>{Number.isNaN(e.left)&&(e.left=0),Number.isNaN(e.top)&&(e.top=0)});const offsetChildren=(e,t,o)=>{i.filter(t=>t.parent===e.id).forEach(e=>{n.has(e.id)&&(e.left+=t,e.top+=o,offsetChildren(e,t,o))})};i.filter(e=>"composite"===e.kind).forEach(e=>offsetChildren(e,e.left,e.top))}return{kind:"statechart",nodes:i,edges:o,layout:r,options:t}}function renderStatechartDsl(t,i){const o=compileStatechartDsl(i),r=o.options||{},n=(new e.ICE).init(t),s=new e.StatechartDesigner(n);return o.nodes.forEach(e=>{s.createState({id:e.id,kind:e.kind,title:e.title,left:e.left,top:e.top,width:e.width,height:e.height})}),o.edges.forEach(e=>{s.createTransition(e)}),s.select(null),r.viewport?n.setViewport(r.viewport.scale,r.viewport.tx,r.viewport.ty):!1!==r.fitViewport&&s.fitViewport(r.fitViewportPadding),s.resetHistory(),{kind:"statechart",ice:n,designer:s}}function renderUmlDsl(t,i){const o=compileUmlDsl(i),r=o.options||{},n=(new e.ICE).init(t),s=new e.UmlDesigner(n);return o.nodes.forEach(e=>{s.createClass({id:e.id,kind:e.kind,className:e.className,abstract:e.abstract,attributes:e.attributes,methods:e.methods,left:e.left,top:e.top,width:e.width})}),o.edges.forEach(e=>{s.createRelation(e)}),s.select(null),r.viewport?n.setViewport(r.viewport.scale,r.viewport.tx,r.viewport.ty):!1!==r.fitViewport&&s.fitViewport(r.fitViewportPadding),s.resetHistory(),{kind:"uml",ice:n,designer:s}}function renderBpmnDsl(t,i){const o=compileBpmnDsl(i),r=o.options||{},n=(new e.ICE).init(t),s=new e.BpmnDesigner(n);return o.nodes.forEach(e=>{const t={id:e.id,title:e.title,left:e.left,top:e.top,width:e.width,height:e.height};["eventKind","trigger","gatewayType","taskType","fillColor","strokeColor"].forEach(i=>{void 0!==e[i]&&(t[i]=e[i])}),s.createNode(e.kind,t)}),o.edges.forEach(e=>{s.createEdge(e)}),s.select(null),r.viewport?n.setViewport(r.viewport.scale,r.viewport.tx,r.viewport.ty):!1!==r.fitViewport&&s.fitViewport(r.fitViewportPadding),s.resetHistory(),{kind:"bpmn",ice:n,designer:s}}function renderFlowDsl(t,i){const o=compileFlowDsl(i),r=o.options||{},n=(new e.ICE).init(t),s=new e.FlowDesigner(n);return o.nodes.forEach(e=>{s.createNode(e.kind,e)}),o.edges.forEach(e=>{s.createEdge(e)}),s.select(null),r.viewport?n.setViewport(r.viewport.scale,r.viewport.tx,r.viewport.ty):!1!==r.fitViewport&&s.fitViewport(r.fitViewportPadding),s.resetHistory(),{kind:"flowchart",ice:n,designer:s}}exports.DSL_SCHEMA_VERSION=1,exports.compileBpmnDsl=compileBpmnDsl,exports.compileDsl=compileDsl,exports.compileFlowDsl=compileFlowDsl,exports.compileStatechartDsl=compileStatechartDsl,exports.compileUmlDsl=compileUmlDsl,exports.isBpmnDsl=isBpmnDsl,exports.isFlowDsl=isFlowDsl,exports.isStatechartDsl=isStatechartDsl,exports.isUmlDsl=isUmlDsl,exports.layeredLayout=layeredLayout,exports.renderBpmnDsl=renderBpmnDsl,exports.renderDsl=function renderDsl(t,i){const o=validateDsl(i);if(!o.valid)throw new Error(o.errors.join("\n"));return isStatechartDsl(i)?renderStatechartDsl(t,i):isUmlDsl(i)?renderUmlDsl(t,i):isBpmnDsl(i)?renderBpmnDsl(t,i):isFlowDsl(i)?renderFlowDsl(t,i):function renderErDsl(t,i){const o=compileDsl(i),r=o.options||{},n=(new e.ICE).init(t),s=new e.EntityDesigner(n);o.entities.forEach(e=>{s.createEntity(e)}),function positionLinks(e,t,i){const o=new Map;return e.entities.forEach(e=>{o.set(e.state.id,e.getMinBoundingBox(!0))}),t.relations.map(e=>{const t=o.get(e.sourceId),r=o.get(e.targetId);let n="R",s="L";if(t&&r){const e=r.center[0]-t.center[0],i=r.center[1]-t.center[1];Math.abs(e)>Math.abs(i)?(n=e>=0?"R":"L",s=e>=0?"L":"R"):(n=i>=0?"B":"T",s=i>=0?"T":"B")}return{...e,routeType:e.routeType||i||"orthogonal",linkShape:e.linkShape||"visio",links:{start:{id:e.sourceId,position:n},end:{id:e.targetId,position:s}}}})}(s,o,r.routeType).forEach(e=>{s.createRelation(e)}),("layered"===o.layout||"horizontal"===o.layout)&&new e.ICELayeredLayout({gapX:r.gapX||120,gapY:r.gapY||50}).layoutContainer(n);r.viewport?n.setViewport(r.viewport.scale,r.viewport.tx,r.viewport.ty):r.fitViewport&&function fitViewport(e,t,i){const o=t.entities||[];let r=1/0,n=1/0,s=-1/0,a=-1/0;o.forEach(e=>{const t=e.getMinBoundingBox(!0).getMinAndMaxPoint();r=Math.min(r,t.minX),n=Math.min(n,t.minY),s=Math.max(s,t.maxX),a=Math.max(a,t.maxY)});const d=s-r,l=a-n,p=e.canvasWidth||0,h=e.canvasHeight||0;if(!p||!h||d<=0||l<=0)return;const c=Number.isFinite(i)&&i>=0?i:40,u=Math.max(1,p-2*c),f=Math.max(1,h-2*c),m=Math.min(u/d,f/l,1),g=(p-d*m)/2-r*m,y=(h-l*m)/2-n*m;e.setViewport(m,g,y)}(n,s,r.fitViewportPadding);return{kind:"entity",ice:n,designer:s}}(t,i)},exports.renderFlowDsl=renderFlowDsl,exports.renderStatechartDsl=renderStatechartDsl,exports.renderUmlDsl=renderUmlDsl,exports.validateBpmnDsl=validateBpmnDsl,exports.validateDsl=validateDsl,exports.validateFlowDsl=validateFlowDsl,exports.validateStatechartDsl=validateStatechartDsl,exports.validateUmlDsl=validateUmlDsl;
package/dist/index.mjs CHANGED
@@ -1 +1 @@
1
- import{FLOW_NODE_KINDS as e,ICE as t,UmlDesigner as i,BpmnDesigner as o,FlowDesigner as n,EntityDesigner as r,ICELayeredLayout as s}from"ice-entity-designer";function isFlowDsl(e){return!!e&&"object"==typeof e&&"flowchart"===e.kind}function isBpmnDsl(e){return!!e&&"object"==typeof e&&"bpmn"===e.kind}function isUmlDsl(e){return!!e&&"object"==typeof e&&"uml"===e.kind}const a=1,l=["terminator","process","decision","io"],d=["T","R","B","L","C"],p=["pool","lane","task","event","gateway","subprocess","dataObject","annotation"],h=["start","intermediate","end"],c=["none","message","timer","error","terminate"],u=["exclusive","parallel","inclusive","event"],f=["none","user","service","script","send","receive","manual"],m=["sequence","message","association"],g=["class","interface","enum"],y=["inheritance","realization","association","aggregation","composition","dependency"];function validateDsl(e){return isUmlDsl(e)?validateUmlDsl(e):isBpmnDsl(e)?validateBpmnDsl(e):isFlowDsl(e)?validateFlowDsl(e):function validateErDsl(e){const t=[];if(!e||"object"!=typeof e||Array.isArray(e))return{valid:!1,errors:["DSL root must be an object"]};void 0!==e.schemaVersion&&1!==e.schemaVersion&&t.push("Unsupported schemaVersion: "+e.schemaVersion);if(Array.isArray(e.entities)){const i=new Set;e.entities.forEach((e,o)=>{const n=`entities[${o}]`;e&&"object"==typeof e?("string"==typeof e.id&&e.id.trim()?i.has(e.id)?t.push(`${n}.id is duplicated: ${e.id}`):i.add(e.id):t.push(n+".id must be a non-empty string"),Array.isArray(e.fields)?e.fields.forEach((e,i)=>{e&&"object"==typeof e&&"string"==typeof e.name&&e.name.trim()||t.push(`${n}.fields[${i}].name must be a non-empty string`)}):t.push(n+".fields must be an array")):t.push(n+" must be an object")})}else t.push("entities must be an array");void 0===e.relations||Array.isArray(e.relations)?(e.relations||[]).forEach((e,i)=>{const o=`relations[${i}]`;e&&"object"==typeof e?("string"==typeof e.source&&e.source.trim()||t.push(o+".source must be a non-empty string"),"string"==typeof e.target&&e.target.trim()||t.push(o+".target must be a non-empty string")):t.push(o+" must be an object")}):t.push("relations must be an array");return{valid:0===t.length,errors:t}}(e)}function validateBpmnDsl(e){const t=[];if(!e||"object"!=typeof e||Array.isArray(e))return{valid:!1,errors:["DSL root must be an object"]};void 0!==e.schemaVersion&&1!==e.schemaVersion&&t.push("Unsupported schemaVersion: "+e.schemaVersion);const i=new Set,o=new Map;return Array.isArray(e.nodes)?(e.nodes.forEach((e,n)=>{const r=`nodes[${n}]`;if(!e||"object"!=typeof e)return void t.push(r+" must be an object");"string"==typeof e.id&&e.id.trim()?i.has(e.id)?t.push(`${r}.id is duplicated: ${e.id}`):(i.add(e.id),o.set(e.id,e.kind||"task")):t.push(r+".id must be a non-empty string"),void 0!==e.kind&&-1===p.indexOf(e.kind)&&t.push(`${r}.kind must be one of ${p.join("/")}`),["left","top","width","height"].forEach(i=>{const o=e[i];void 0!==o&&"number"!=typeof o&&t.push(`${r}.${i} must be a number when present`)});[["eventKind",h],["trigger",c],["gatewayType",u],["taskType",f]].forEach(([i,o])=>{const n=e[i];void 0!==n&&-1===o.indexOf(n)&&t.push(`${r}.${i} must be one of ${o.join("/")}`)})}),e.nodes.forEach((e,n)=>{if(!e||"object"!=typeof e||void 0===e.parent)return;const r=`nodes[${n}]`;if("string"!=typeof e.parent||!e.parent.trim())return void t.push(r+".parent must be a non-empty string when present");if(!i.has(e.parent))return void t.push(r+".parent must reference an existing node id");if(e.parent===e.id)return void t.push(r+".parent must not reference itself");const s=o.get(e.parent);"pool"===e.kind?t.push(r+".parent is not allowed on a pool (池是最外层容器)"):"lane"===e.kind&&"pool"!==s?t.push(r+".parent must reference a pool"):"pool"!==s&&"lane"!==s&&t.push(r+".parent must reference a pool or a lane")})):t.push("nodes must be an array"),void 0===e.edges||Array.isArray(e.edges)?(e.edges||[]).forEach((e,o)=>{const n=`edges[${o}]`;if(!e||"object"!=typeof e)return void t.push(n+" must be an object");"string"==typeof e.source&&e.source.trim()&&i.has(e.source)||t.push(n+".source must reference an existing node id"),"string"==typeof e.target&&e.target.trim()&&i.has(e.target)||t.push(n+".target must reference an existing node id");const r=void 0!==e.type?e.type:e.flowType;void 0!==r&&-1===m.indexOf(r)&&t.push(`${n}.type must be one of ${m.join("/")}`),void 0!==e.label&&"string"!=typeof e.label&&t.push(n+".label must be a string when present"),void 0!==e.condition&&"string"!=typeof e.condition&&t.push(n+".condition must be a string when present"),void 0!==e.linkShape&&"visio"!==e.linkShape&&"bezier"!==e.linkShape&&t.push(n+'.linkShape must be "visio" or "bezier" when present')}):t.push("edges must be an array when present"),{valid:0===t.length,errors:t}}function validateFlowDsl(e){const t=[];if(!e||"object"!=typeof e||Array.isArray(e))return{valid:!1,errors:["DSL root must be an object"]};void 0!==e.schemaVersion&&1!==e.schemaVersion&&t.push("Unsupported schemaVersion: "+e.schemaVersion);const i=new Set;return Array.isArray(e.nodes)?e.nodes.forEach((e,o)=>{const n=`nodes[${o}]`;e&&"object"==typeof e?("string"==typeof e.id&&e.id.trim()?i.has(e.id)?t.push(`${n}.id is duplicated: ${e.id}`):i.add(e.id):t.push(n+".id must be a non-empty string"),void 0!==e.kind&&-1===l.indexOf(e.kind)&&t.push(`${n}.kind must be one of ${l.join("/")}`),["left","top","width","height"].forEach(i=>{const o=e[i];void 0!==o&&"number"!=typeof o&&t.push(`${n}.${i} must be a number when present`)})):t.push(n+" must be an object")}):t.push("nodes must be an array"),void 0===e.edges||Array.isArray(e.edges)?(e.edges||[]).forEach((e,o)=>{const n=`edges[${o}]`;e&&"object"==typeof e?("string"==typeof e.source&&e.source.trim()&&i.has(e.source)||t.push(n+".source must reference an existing node id"),"string"==typeof e.target&&e.target.trim()&&i.has(e.target)||t.push(n+".target must reference an existing node id"),void 0!==e.label&&"string"!=typeof e.label&&t.push(n+".label must be a string when present"),void 0!==e.sourcePort&&-1===d.indexOf(e.sourcePort)&&t.push(`${n}.sourcePort must be one of ${d.join("/")}`),void 0!==e.targetPort&&-1===d.indexOf(e.targetPort)&&t.push(`${n}.targetPort must be one of ${d.join("/")}`),void 0!==e.linkShape&&"visio"!==e.linkShape&&"bezier"!==e.linkShape&&t.push(n+'.linkShape must be "visio" or "bezier" when present')):t.push(n+" must be an object")}):t.push("edges must be an array when present"),{valid:0===t.length,errors:t}}function validateUmlDsl(e){const t=[];if(!e||"object"!=typeof e||Array.isArray(e))return{valid:!1,errors:["DSL root must be an object"]};void 0!==e.schemaVersion&&1!==e.schemaVersion&&t.push("Unsupported schemaVersion: "+e.schemaVersion);const i=new Set;return Array.isArray(e.nodes)?e.nodes.forEach((e,o)=>{const n=`nodes[${o}]`;e&&"object"==typeof e?("string"==typeof e.id&&e.id.trim()?i.has(e.id)?t.push(`${n}.id is duplicated: ${e.id}`):i.add(e.id):t.push(n+".id must be a non-empty string"),void 0!==e.kind&&-1===g.indexOf(e.kind)&&t.push(`${n}.kind must be one of ${g.join("/")}`),["attributes","methods"].forEach(i=>{const o=e[i];void 0!==o&&(Array.isArray(o)&&!o.some(e=>"string"!=typeof e)||t.push(`${n}.${i} must be an array of strings when present`))}),["left","top","width","height"].forEach(i=>{const o=e[i];void 0!==o&&"number"!=typeof o&&t.push(`${n}.${i} must be a number when present`)})):t.push(n+" must be an object")}):t.push("nodes must be an array"),void 0===e.edges||Array.isArray(e.edges)?(e.edges||[]).forEach((e,o)=>{const n=`edges[${o}]`;if(!e||"object"!=typeof e)return void t.push(n+" must be an object");"string"==typeof e.source&&e.source.trim()&&i.has(e.source)||t.push(n+".source must reference an existing node id"),"string"==typeof e.target&&e.target.trim()&&i.has(e.target)||t.push(n+".target must reference an existing node id");const r=void 0!==e.type?e.type:e.relation;void 0!==r&&-1===y.indexOf(r)&&t.push(`${n}.type must be one of ${y.join("/")}`),void 0!==e.label&&"string"!=typeof e.label&&t.push(n+".label must be a string when present")}):t.push("edges must be an array when present"),{valid:0===t.length,errors:t}}function entityName(e){return e.entityName||e.name||e.id}function relationType(e){return e.relationType||e.type||"one-to-many"}function compileDsl(e){if(isFlowDsl(e))throw new Error("compileDsl() 只处理 ER 文档;流程图文档请使用 compileFlowDsl()");if(!e||!Array.isArray(e.entities))throw new Error("ER 文档必须包含 entities 数组");return{entities:e.entities.map(e=>({id:e.id,entityName:entityName(e),fields:e.fields||[],left:e.left,top:e.top,width:e.width,height:e.height,style:e.style,headerStyle:e.headerStyle,fieldStyle:e.fieldStyle,dividerStyle:e.dividerStyle,draggable:e.draggable,interactive:e.interactive})),relations:(e.relations||[]).map((e,t)=>({id:e.id||"relation-"+t,relationType:relationType(e),sourceId:e.source,targetId:e.target,sourceField:e.sourceField||"id",targetField:e.targetField||"id",nullable:e.nullable,onDelete:e.onDelete,onUpdate:e.onUpdate,joinTableName:e.joinTableName,fromKey:e.fromKey,toKey:e.toKey,sourceCardinality:e.sourceCardinality,targetCardinality:e.targetCardinality,label:e.label,style:e.style,arrow:e.arrow,linkShape:e.linkShape,routeType:e.routeType,routeOffset:e.routeOffset,curveType:e.curveType,lineDash:e.lineDash})),layout:e.layout,options:e.options}}function layeredLayout(e,t,i={}){const o=Number(i.gapX)||90,n=Number(i.gapY)||90,r=void 0===i.originX?80:i.originX,s=void 0===i.originY?80:i.originY,a=new Map;if(!e.length)return a;const l=new Map;e.forEach(e=>l.set(e.id,e));const d=new Map,p=new Map;e.forEach(e=>{d.set(e.id,0),p.set(e.id,[])}),t.forEach(e=>{l.has(e.sourceId)&&l.has(e.targetId)&&(d.set(e.targetId,(d.get(e.targetId)||0)+1),p.get(e.sourceId).push(e.targetId))});const h=new Map,c=[];e.forEach(e=>{0===(d.get(e.id)||0)&&(h.set(e.id,0),c.push(e.id))}),c.length||(h.set(e[0].id,0),c.push(e[0].id));let u=e.length*e.length+e.length;for(;c.length&&u-- >0;){const e=c.shift(),t=h.get(e)||0;(p.get(e)||[]).forEach(e=>{const i=t+1;(void 0===h.get(e)?-1:h.get(e))<i&&(h.set(e,i),c.push(e))})}e.forEach(e=>{h.has(e.id)||h.set(e.id,0)});const f=new Map;e.forEach(e=>{const t=h.get(e.id)||0;f.has(t)||f.set(t,[]),f.get(t).push(e)});const m=[...f.keys()].sort((e,t)=>e-t);if("horizontal"===i.direction){const e=m.map(e=>Math.max(...f.get(e).map(e=>e.width)));let t=0;m.forEach((i,r)=>{const s=f.get(i);let l=-(s.reduce((e,t)=>e+t.height,0)+Math.max(s.length-1,0)*n)/2;s.forEach(i=>{a.set(i.id,{left:Math.round(t+(e[r]-i.width)/2),top:Math.round(l)}),l+=i.height+n}),t+=e[r]+o})}else{const e=m.map(e=>Math.max(...f.get(e).map(e=>e.height)));let t=0;m.forEach((i,r)=>{const s=f.get(i);let l=-(s.reduce((e,t)=>e+t.width,0)+Math.max(s.length-1,0)*o)/2;s.forEach(i=>{a.set(i.id,{left:Math.round(l),top:Math.round(t+(e[r]-i.height)/2)}),l+=i.width+o}),t+=e[r]+n})}const g=Math.min(...e.map(e=>a.get(e.id).left)),y=Math.min(...e.map(e=>a.get(e.id).top));return a.forEach(e=>{e.left+=r-g,e.top+=s-y}),a}const b={terminator:{width:e.terminator.width,height:e.terminator.height,fill:e.terminator.fill,stroke:e.terminator.stroke},process:{width:e.process.width,height:e.process.height,fill:e.process.fill,stroke:e.process.stroke},decision:{width:e.decision.width,height:e.decision.height,fill:e.decision.fill,stroke:e.decision.stroke},io:{width:e.io.width,height:e.io.height,fill:e.io.fill,stroke:e.io.stroke}};function compileFlowDsl(e){const t=e.options||{},i=(e.nodes||[]).map(e=>{const t=function nodeKind$1(e){return e.kind&&b[e.kind]?e.kind:"process"}(e),i=b[t];return{id:e.id,typeId:"FlowNode",kind:t,title:(o=e,o.title||o.name||o.id),left:"number"==typeof e.left?e.left:Number.NaN,top:"number"==typeof e.top?e.top:Number.NaN,width:"number"==typeof e.width?e.width:i.width,height:"number"==typeof e.height?e.height:i.height,fillColor:e.fillColor||i.fill,strokeColor:e.strokeColor||i.stroke};var o}),o=(e.edges||[]).map((e,t)=>({id:e.id||"edge-"+t,sourceId:e.source,targetId:e.target,sourcePort:e.sourcePort||"B",targetPort:e.targetPort||"T",label:e.label||"",linkShape:e.linkShape||"visio"})),n=t.layout||"layered";return"none"!==n&&i.some(e=>Number.isNaN(e.left)||Number.isNaN(e.top))&&(i.forEach(e=>{Number.isNaN(e.left)&&(e.left=0),Number.isNaN(e.top)&&(e.top=0)}),function autoLayout(e,t,i,o){const n=layeredLayout(e,t,{gapX:i,gapY:o});e.forEach(e=>{const t=n.get(e.id);t&&(e.left=t.left,e.top=t.top)})}(i,o,Number(t.gapX)||90,Number(t.gapY)||90)),i.forEach(e=>{Number.isNaN(e.left)&&(e.left=0),Number.isNaN(e.top)&&(e.top=0)}),{kind:"flowchart",nodes:i,edges:o,layout:n,options:t}}const w={pool:"bpmnPool",lane:"bpmnLane",task:"bpmnTask",event:"bpmnEvent",gateway:"bpmnGateway",subprocess:"bpmnSubprocess",dataObject:"bpmnDataObject",annotation:"bpmnAnnotation"},v=Number(e.bpmnPool.bandSize)||32,k=Number(e.bpmnLane.bandSize)||32,x=Number(e.bpmnLane.height)||130,N=Number(e.bpmnPool.width)||900;function toWorkingNode(t){const i=t.kind||"task",o=function presetOf(t){return e[t]||e.bpmnTask}(w[i]||"bpmnTask"),n={id:t.id,typeId:"FlowNode",kind:w[i]||"bpmnTask",title:t.title||t.name||t.id,left:"number"==typeof t.left?t.left:0,top:"number"==typeof t.top?t.top:0,width:"number"==typeof t.width?t.width:o.width,height:"number"==typeof t.height?t.height:o.height,fillColor:t.fillColor,strokeColor:t.strokeColor,dslKind:i,parent:t.parent,explicitLeft:"number"==typeof t.left,explicitTop:"number"==typeof t.top,explicitWidth:"number"==typeof t.width,explicitHeight:"number"==typeof t.height};return"event"===i&&(n.eventKind=t.eventKind||o.eventKind||"start",n.trigger=t.trigger||o.trigger||"none"),"gateway"===i&&(n.gatewayType=t.gatewayType||o.gatewayType||"exclusive"),"task"!==i&&"subprocess"!==i||(n.taskType=t.taskType||o.taskType||"none"),n}function buildGroups(e,t){const i=new Map;t.forEach(e=>i.set(e.id,e));const o=1===t.length?t[0]:null,n=[];return e.forEach(e=>{(e=>{let t=n.filter(t=>t.owner===e)[0];return t||(t={owner:e,nodes:[],box:null,didLayout:!1},n.push(t)),t})((e.parent?i.get(e.parent):void 0)||o).nodes.push(e)}),n}function layoutGroups(e,t,i,o){e.forEach(e=>{if(e.nodes.some(e=>!e.explicitLeft||!e.explicitTop)){const n=layeredLayout(e.nodes,t,{gapX:i,gapY:o,originX:0,originY:0,direction:"horizontal"});e.nodes.forEach(e=>{const t=n.get(e.id);t&&(e.left=t.left,e.top=t.top)}),e.didLayout=!0}e.box=function unionBox(e){if(!e.length)return null;let t=1/0,i=1/0,o=-1/0,n=-1/0;return e.forEach(e=>{t=Math.min(t,e.left),i=Math.min(i,e.top),o=Math.max(o,e.left+e.width),n=Math.max(n,e.top+e.height)}),{minX:t,minY:i,maxX:o,maxY:n}}(e.nodes)})}function compileBpmnDsl(e){const t=e.options||{},i=(e.nodes||[]).map(toWorkingNode),o=i.filter(e=>"pool"===e.dslKind),n=i.filter(e=>"lane"===e.dslKind),r=i.filter(e=>!function isContainer(e){return"pool"===e.dslKind||"lane"===e.dslKind}(e)),s=(e.edges||[]).map((e,t)=>({id:e.id||"edge-"+t,sourceId:e.source,targetId:e.target,flowType:e.type||e.flowType||"sequence",label:e.label||"",condition:e.condition||"",isDefault:!!e.isDefault,linkShape:e.linkShape||"visio"})),a=t.layout||"auto",l=function resolveLaneOwners(e,t){const i=new Map;return e.forEach(e=>{let o=e.parent;o||1!==t.length||(o=t[0].id),o&&i.set(e.id,o)}),i}(n,o),lanesOf=e=>n.filter(t=>l.get(t.id)===e);let d=[];"none"!==a&&(d=buildGroups(r,o.concat(n)),layoutGroups(d,s,Number(t.gapX)||90,Number(t.gapY)||60)),n.forEach(e=>{const t=d.filter(t=>t.owner===e)[0],i=t?t.box:null;e.explicitHeight||(e.height=Math.round(Math.max(56+(i?i.maxY-i.minY:0),x))),e.explicitWidth||(e.width=Math.round(Math.max((i?i.maxX-i.minX:0)+k+56,N)))}),o.forEach(e=>{const t=lanesOf(e.id);if(t.length){const i=t.reduce((e,t)=>Math.max(e,t.width),N);return e.explicitWidth||(e.width=i),e.explicitWidth&&t.forEach(t=>{t.explicitWidth||(t.width=e.width)}),void(e.explicitHeight||(e.height=v+t.reduce((e,t)=>e+t.height,0)))}const i=d.filter(t=>t.owner===e)[0],o=i?i.box:null;e.explicitWidth||(e.width=Math.round(Math.max(56+(o?o.maxX-o.minX:0),N))),e.explicitHeight||(e.height=Math.round(Math.max((o?o.maxY-o.minY:0)+v+56,160)))});let p=60;o.forEach(e=>{e.explicitLeft||(e.left=60),e.explicitTop||(e.top=p),p=Math.max(p,e.top+e.height+60)}),o.forEach(e=>{const t=lanesOf(e.id);if(!t.length)return;const i=e.top+v,o=Math.max(e.height-v,1),n=t.reduce((e,t)=>e+(t.explicitHeight?t.height:0),0),r=t.filter(e=>!e.explicitHeight),s=r.length?Math.max(o-n,0)/r.length:0;let a=i;t.forEach(t=>{t.explicitLeft||(t.left=e.left),t.explicitTop||(t.top=a),!t.explicitHeight&&e.explicitHeight&&(t.height=Math.round(s||x)),a=t.top+t.height})});let h=60;n.forEach(e=>{l.get(e.id)||(e.explicitLeft||(e.left=60),e.explicitTop||(e.top=h,h=e.top+e.height+60))}),d.forEach(e=>{const t=e.box;if(!t||!e.didLayout)return;const i=e.owner;let o=80,n=80;i&&(o=i.left+28,n=i.top+28,"pool"===i.dslKind?n+=v:o+=k),e.nodes.forEach(e=>{e.left=Math.round(o+(e.left-t.minX)),e.top=Math.round(n+(e.top-t.minY))})});return{kind:"bpmn",nodes:o.concat(n).concat(r).map(e=>{const t={id:e.id,typeId:"FlowNode",kind:e.kind,title:e.title,left:e.left,top:e.top,width:e.width,height:e.height};return void 0!==e.eventKind&&(t.eventKind=e.eventKind),void 0!==e.trigger&&(t.trigger=e.trigger),void 0!==e.gatewayType&&(t.gatewayType=e.gatewayType),void 0!==e.taskType&&(t.taskType=e.taskType),void 0!==e.fillColor&&(t.fillColor=e.fillColor),void 0!==e.strokeColor&&(t.strokeColor=e.strokeColor),t}),edges:s,layout:a,options:t}}function compileUmlDsl(e){const t=e.options||{},i=(e.nodes||[]).map(e=>{return{id:e.id,kind:(t=e,t.kind||"class"),className:e.title||e.name||e.id,abstract:!!e.abstract,attributes:Array.isArray(e.attributes)?e.attributes.map(e=>String(e)):[],methods:Array.isArray(e.methods)?e.methods.map(e=>String(e)):[],left:"number"==typeof e.left?e.left:Number.NaN,top:"number"==typeof e.top?e.top:Number.NaN,width:"number"==typeof e.width?e.width:240,height:"number"==typeof e.height?e.height:120+24*(e.attributes?e.attributes.length:0)+24*(e.methods?e.methods.length:0)};var t}),o=(e.edges||[]).map((e,t)=>({id:e.id||"relation-"+t,sourceId:e.source,targetId:e.target,relationKind:e.type||e.relation||"association",label:e.label||""})),n=t.layout||"layered";if("none"!==n&&i.some(e=>Number.isNaN(e.left)||Number.isNaN(e.top))){i.forEach(e=>{Number.isNaN(e.left)&&(e.left=0),Number.isNaN(e.top)&&(e.top=0)});const e=layeredLayout(i,o.filter(e=>"inheritance"===e.relationKind||"realization"===e.relationKind).map(e=>({sourceId:e.targetId,targetId:e.sourceId})),{gapX:Number(t.gapX)||80,gapY:Number(t.gapY)||110,originX:80,originY:80,direction:"vertical"});i.forEach(t=>{const i=e.get(t.id);i&&(t.left=i.left,t.top=i.top)})}return i.forEach(e=>{Number.isNaN(e.left)&&(e.left=0),Number.isNaN(e.top)&&(e.top=0)}),{kind:"uml",nodes:i,edges:o,layout:n,options:t}}function renderDsl(e,i){const o=validateDsl(i);if(!o.valid)throw new Error(o.errors.join("\n"));return isUmlDsl(i)?renderUmlDsl(e,i):isBpmnDsl(i)?renderBpmnDsl(e,i):isFlowDsl(i)?renderFlowDsl(e,i):function renderErDsl(e,i){const o=compileDsl(i),n=o.options||{},a=(new t).init(e),l=new r(a);o.entities.forEach(e=>{l.createEntity(e)}),function positionLinks(e,t,i){const o=new Map;return e.entities.forEach(e=>{o.set(e.state.id,e.getMinBoundingBox(!0))}),t.relations.map(e=>{const t=o.get(e.sourceId),n=o.get(e.targetId);let r="R",s="L";if(t&&n){const e=n.center[0]-t.center[0],i=n.center[1]-t.center[1];Math.abs(e)>Math.abs(i)?(r=e>=0?"R":"L",s=e>=0?"L":"R"):(r=i>=0?"B":"T",s=i>=0?"T":"B")}return{...e,routeType:e.routeType||i||"orthogonal",linkShape:e.linkShape||"visio",links:{start:{id:e.sourceId,position:r},end:{id:e.targetId,position:s}}}})}(l,o,n.routeType).forEach(e=>{l.createRelation(e)}),("layered"===o.layout||"horizontal"===o.layout)&&new s({gapX:n.gapX||120,gapY:n.gapY||50}).layoutContainer(a);n.viewport?a.setViewport(n.viewport.scale,n.viewport.tx,n.viewport.ty):n.fitViewport&&function fitViewport(e,t,i){const o=t.entities||[];let n=1/0,r=1/0,s=-1/0,a=-1/0;o.forEach(e=>{const t=e.getMinBoundingBox(!0).getMinAndMaxPoint();n=Math.min(n,t.minX),r=Math.min(r,t.minY),s=Math.max(s,t.maxX),a=Math.max(a,t.maxY)});const l=s-n,d=a-r,p=e.canvasWidth||0,h=e.canvasHeight||0;if(!p||!h||l<=0||d<=0)return;const c=Number.isFinite(i)&&i>=0?i:40,u=Math.max(1,p-2*c),f=Math.max(1,h-2*c),m=Math.min(u/l,f/d,1),g=(p-l*m)/2-n*m,y=(h-d*m)/2-r*m;e.setViewport(m,g,y)}(a,l,n.fitViewportPadding);return{kind:"entity",ice:a,designer:l}}(e,i)}function renderUmlDsl(e,o){const n=compileUmlDsl(o),r=n.options||{},s=(new t).init(e),a=new i(s);return n.nodes.forEach(e=>{a.createClass({id:e.id,kind:e.kind,className:e.className,abstract:e.abstract,attributes:e.attributes,methods:e.methods,left:e.left,top:e.top,width:e.width})}),n.edges.forEach(e=>{a.createRelation(e)}),a.select(null),r.viewport?s.setViewport(r.viewport.scale,r.viewport.tx,r.viewport.ty):!1!==r.fitViewport&&a.fitViewport(r.fitViewportPadding),a.resetHistory(),{kind:"uml",ice:s,designer:a}}function renderBpmnDsl(e,i){const n=compileBpmnDsl(i),r=n.options||{},s=(new t).init(e),a=new o(s);return n.nodes.forEach(e=>{const t={id:e.id,title:e.title,left:e.left,top:e.top,width:e.width,height:e.height};["eventKind","trigger","gatewayType","taskType","fillColor","strokeColor"].forEach(i=>{void 0!==e[i]&&(t[i]=e[i])}),a.createNode(e.kind,t)}),n.edges.forEach(e=>{a.createEdge(e)}),a.select(null),r.viewport?s.setViewport(r.viewport.scale,r.viewport.tx,r.viewport.ty):!1!==r.fitViewport&&a.fitViewport(r.fitViewportPadding),a.resetHistory(),{kind:"bpmn",ice:s,designer:a}}function renderFlowDsl(e,i){const o=compileFlowDsl(i),r=o.options||{},s=(new t).init(e),a=new n(s);return o.nodes.forEach(e=>{a.createNode(e.kind,e)}),o.edges.forEach(e=>{a.createEdge(e)}),a.select(null),r.viewport?s.setViewport(r.viewport.scale,r.viewport.tx,r.viewport.ty):!1!==r.fitViewport&&a.fitViewport(r.fitViewportPadding),a.resetHistory(),{kind:"flowchart",ice:s,designer:a}}export{a as DSL_SCHEMA_VERSION,compileBpmnDsl,compileDsl,compileFlowDsl,compileUmlDsl,isBpmnDsl,isFlowDsl,isUmlDsl,layeredLayout,renderBpmnDsl,renderDsl,renderFlowDsl,renderUmlDsl,validateBpmnDsl,validateDsl,validateFlowDsl,validateUmlDsl};
1
+ import{FLOW_NODE_KINDS as e,ICE as t,StatechartDesigner as i,UmlDesigner as o,BpmnDesigner as r,FlowDesigner as n,EntityDesigner as s,ICELayeredLayout as a}from"ice-entity-designer";function isFlowDsl(e){return!!e&&"object"==typeof e&&"flowchart"===e.kind}function isBpmnDsl(e){return!!e&&"object"==typeof e&&"bpmn"===e.kind}function isUmlDsl(e){return!!e&&"object"==typeof e&&"uml"===e.kind}function isStatechartDsl(e){return!!e&&"object"==typeof e&&"statechart"===e.kind}const d=1,l=["terminator","process","decision","io"],p=["T","R","B","L","C"],h=["pool","lane","task","event","gateway","subprocess","dataObject","annotation"],c=["start","intermediate","end"],u=["none","message","timer","error","terminate"],f=["exclusive","parallel","inclusive","event"],m=["none","user","service","script","send","receive","manual"],g=["sequence","message","association"],y=["initial","final","state","composite"],b=["class","interface","enum"],w=["inheritance","realization","association","aggregation","composition","dependency"];function validateDsl(e){return isStatechartDsl(e)?validateStatechartDsl(e):isUmlDsl(e)?validateUmlDsl(e):isBpmnDsl(e)?validateBpmnDsl(e):isFlowDsl(e)?validateFlowDsl(e):function validateErDsl(e){const t=[];if(!e||"object"!=typeof e||Array.isArray(e))return{valid:!1,errors:["DSL root must be an object"]};void 0!==e.schemaVersion&&1!==e.schemaVersion&&t.push("Unsupported schemaVersion: "+e.schemaVersion);if(Array.isArray(e.entities)){const i=new Set;e.entities.forEach((e,o)=>{const r=`entities[${o}]`;e&&"object"==typeof e?("string"==typeof e.id&&e.id.trim()?i.has(e.id)?t.push(`${r}.id is duplicated: ${e.id}`):i.add(e.id):t.push(r+".id must be a non-empty string"),Array.isArray(e.fields)?e.fields.forEach((e,i)=>{e&&"object"==typeof e&&"string"==typeof e.name&&e.name.trim()||t.push(`${r}.fields[${i}].name must be a non-empty string`)}):t.push(r+".fields must be an array")):t.push(r+" must be an object")})}else t.push("entities must be an array");void 0===e.relations||Array.isArray(e.relations)?(e.relations||[]).forEach((e,i)=>{const o=`relations[${i}]`;e&&"object"==typeof e?("string"==typeof e.source&&e.source.trim()||t.push(o+".source must be a non-empty string"),"string"==typeof e.target&&e.target.trim()||t.push(o+".target must be a non-empty string")):t.push(o+" must be an object")}):t.push("relations must be an array");return{valid:0===t.length,errors:t}}(e)}function validateBpmnDsl(e){const t=[];if(!e||"object"!=typeof e||Array.isArray(e))return{valid:!1,errors:["DSL root must be an object"]};void 0!==e.schemaVersion&&1!==e.schemaVersion&&t.push("Unsupported schemaVersion: "+e.schemaVersion);const i=new Set,o=new Map;return Array.isArray(e.nodes)?(e.nodes.forEach((e,r)=>{const n=`nodes[${r}]`;if(!e||"object"!=typeof e)return void t.push(n+" must be an object");"string"==typeof e.id&&e.id.trim()?i.has(e.id)?t.push(`${n}.id is duplicated: ${e.id}`):(i.add(e.id),o.set(e.id,e.kind||"task")):t.push(n+".id must be a non-empty string"),void 0!==e.kind&&-1===h.indexOf(e.kind)&&t.push(`${n}.kind must be one of ${h.join("/")}`),["left","top","width","height"].forEach(i=>{const o=e[i];void 0!==o&&"number"!=typeof o&&t.push(`${n}.${i} must be a number when present`)});[["eventKind",c],["trigger",u],["gatewayType",f],["taskType",m]].forEach(([i,o])=>{const r=e[i];void 0!==r&&-1===o.indexOf(r)&&t.push(`${n}.${i} must be one of ${o.join("/")}`)})}),e.nodes.forEach((e,r)=>{if(!e||"object"!=typeof e||void 0===e.parent)return;const n=`nodes[${r}]`;if("string"!=typeof e.parent||!e.parent.trim())return void t.push(n+".parent must be a non-empty string when present");if(!i.has(e.parent))return void t.push(n+".parent must reference an existing node id");if(e.parent===e.id)return void t.push(n+".parent must not reference itself");const s=o.get(e.parent);"pool"===e.kind?t.push(n+".parent is not allowed on a pool (池是最外层容器)"):"lane"===e.kind&&"pool"!==s?t.push(n+".parent must reference a pool"):"pool"!==s&&"lane"!==s&&t.push(n+".parent must reference a pool or a lane")})):t.push("nodes must be an array"),void 0===e.edges||Array.isArray(e.edges)?(e.edges||[]).forEach((e,o)=>{const r=`edges[${o}]`;if(!e||"object"!=typeof e)return void t.push(r+" must be an object");"string"==typeof e.source&&e.source.trim()&&i.has(e.source)||t.push(r+".source must reference an existing node id"),"string"==typeof e.target&&e.target.trim()&&i.has(e.target)||t.push(r+".target must reference an existing node id");const n=void 0!==e.type?e.type:e.flowType;void 0!==n&&-1===g.indexOf(n)&&t.push(`${r}.type must be one of ${g.join("/")}`),void 0!==e.label&&"string"!=typeof e.label&&t.push(r+".label must be a string when present"),void 0!==e.condition&&"string"!=typeof e.condition&&t.push(r+".condition must be a string when present"),void 0!==e.linkShape&&"visio"!==e.linkShape&&"bezier"!==e.linkShape&&t.push(r+'.linkShape must be "visio" or "bezier" when present')}):t.push("edges must be an array when present"),{valid:0===t.length,errors:t}}function validateFlowDsl(e){const t=[];if(!e||"object"!=typeof e||Array.isArray(e))return{valid:!1,errors:["DSL root must be an object"]};void 0!==e.schemaVersion&&1!==e.schemaVersion&&t.push("Unsupported schemaVersion: "+e.schemaVersion);const i=new Set;return Array.isArray(e.nodes)?e.nodes.forEach((e,o)=>{const r=`nodes[${o}]`;e&&"object"==typeof e?("string"==typeof e.id&&e.id.trim()?i.has(e.id)?t.push(`${r}.id is duplicated: ${e.id}`):i.add(e.id):t.push(r+".id must be a non-empty string"),void 0!==e.kind&&-1===l.indexOf(e.kind)&&t.push(`${r}.kind must be one of ${l.join("/")}`),["left","top","width","height"].forEach(i=>{const o=e[i];void 0!==o&&"number"!=typeof o&&t.push(`${r}.${i} must be a number when present`)})):t.push(r+" must be an object")}):t.push("nodes must be an array"),void 0===e.edges||Array.isArray(e.edges)?(e.edges||[]).forEach((e,o)=>{const r=`edges[${o}]`;e&&"object"==typeof e?("string"==typeof e.source&&e.source.trim()&&i.has(e.source)||t.push(r+".source must reference an existing node id"),"string"==typeof e.target&&e.target.trim()&&i.has(e.target)||t.push(r+".target must reference an existing node id"),void 0!==e.label&&"string"!=typeof e.label&&t.push(r+".label must be a string when present"),void 0!==e.sourcePort&&-1===p.indexOf(e.sourcePort)&&t.push(`${r}.sourcePort must be one of ${p.join("/")}`),void 0!==e.targetPort&&-1===p.indexOf(e.targetPort)&&t.push(`${r}.targetPort must be one of ${p.join("/")}`),void 0!==e.linkShape&&"visio"!==e.linkShape&&"bezier"!==e.linkShape&&t.push(r+'.linkShape must be "visio" or "bezier" when present')):t.push(r+" must be an object")}):t.push("edges must be an array when present"),{valid:0===t.length,errors:t}}function validateUmlDsl(e){const t=[];if(!e||"object"!=typeof e||Array.isArray(e))return{valid:!1,errors:["DSL root must be an object"]};void 0!==e.schemaVersion&&1!==e.schemaVersion&&t.push("Unsupported schemaVersion: "+e.schemaVersion);const i=new Set;return Array.isArray(e.nodes)?e.nodes.forEach((e,o)=>{const r=`nodes[${o}]`;e&&"object"==typeof e?("string"==typeof e.id&&e.id.trim()?i.has(e.id)?t.push(`${r}.id is duplicated: ${e.id}`):i.add(e.id):t.push(r+".id must be a non-empty string"),void 0!==e.kind&&-1===b.indexOf(e.kind)&&t.push(`${r}.kind must be one of ${b.join("/")}`),["attributes","methods"].forEach(i=>{const o=e[i];void 0!==o&&(Array.isArray(o)&&!o.some(e=>"string"!=typeof e)||t.push(`${r}.${i} must be an array of strings when present`))}),["left","top","width","height"].forEach(i=>{const o=e[i];void 0!==o&&"number"!=typeof o&&t.push(`${r}.${i} must be a number when present`)})):t.push(r+" must be an object")}):t.push("nodes must be an array"),void 0===e.edges||Array.isArray(e.edges)?(e.edges||[]).forEach((e,o)=>{const r=`edges[${o}]`;if(!e||"object"!=typeof e)return void t.push(r+" must be an object");"string"==typeof e.source&&e.source.trim()&&i.has(e.source)||t.push(r+".source must reference an existing node id"),"string"==typeof e.target&&e.target.trim()&&i.has(e.target)||t.push(r+".target must reference an existing node id");const n=void 0!==e.type?e.type:e.relation;void 0!==n&&-1===w.indexOf(n)&&t.push(`${r}.type must be one of ${w.join("/")}`),void 0!==e.label&&"string"!=typeof e.label&&t.push(r+".label must be a string when present")}):t.push("edges must be an array when present"),{valid:0===t.length,errors:t}}function validateStatechartDsl(e){const t=[];if(!e||"object"!=typeof e||Array.isArray(e))return{valid:!1,errors:["DSL root must be an object"]};void 0!==e.schemaVersion&&1!==e.schemaVersion&&t.push("Unsupported schemaVersion: "+e.schemaVersion);const i=new Set,o=new Map;return Array.isArray(e.nodes)?(e.nodes.forEach((e,r)=>{const n=`nodes[${r}]`;e&&"object"==typeof e?("string"==typeof e.id&&e.id.trim()?i.has(e.id)?t.push(`${n}.id is duplicated: ${e.id}`):(i.add(e.id),o.set(e.id,e.kind||"state")):t.push(n+".id must be a non-empty string"),void 0!==e.kind&&-1===y.indexOf(e.kind)&&t.push(`${n}.kind must be one of ${y.join("/")}`),["left","top","width","height"].forEach(i=>{const o=e[i];void 0!==o&&"number"!=typeof o&&t.push(`${n}.${i} must be a number when present`)})):t.push(n+" must be an object")}),e.nodes.forEach((e,r)=>{if(!e||"object"!=typeof e||void 0===e.parent)return;const n=`nodes[${r}]`;"string"==typeof e.parent&&e.parent.trim()&&i.has(e.parent)?e.parent!==e.id?"composite"!==o.get(e.parent)&&t.push(n+".parent must reference a composite state"):t.push(n+".parent must not reference itself"):t.push(n+".parent must reference an existing node id")})):t.push("nodes must be an array"),void 0===e.edges||Array.isArray(e.edges)?(e.edges||[]).forEach((e,o)=>{const r=`edges[${o}]`;e&&"object"==typeof e?("string"==typeof e.source&&e.source.trim()&&i.has(e.source)||t.push(r+".source must reference an existing node id"),"string"==typeof e.target&&e.target.trim()&&i.has(e.target)||t.push(r+".target must reference an existing node id"),["event","guard","action","label"].forEach(i=>{const o=e[i];void 0!==o&&"string"!=typeof o&&t.push(`${r}.${i} must be a string when present`)})):t.push(r+" must be an object")}):t.push("edges must be an array when present"),{valid:0===t.length,errors:t}}function entityName(e){return e.entityName||e.name||e.id}function relationType(e){return e.relationType||e.type||"one-to-many"}function compileDsl(e){if(isFlowDsl(e))throw new Error("compileDsl() 只处理 ER 文档;流程图文档请使用 compileFlowDsl()");if(!e||!Array.isArray(e.entities))throw new Error("ER 文档必须包含 entities 数组");return{entities:e.entities.map(e=>({id:e.id,entityName:entityName(e),fields:e.fields||[],left:e.left,top:e.top,width:e.width,height:e.height,style:e.style,headerStyle:e.headerStyle,fieldStyle:e.fieldStyle,dividerStyle:e.dividerStyle,draggable:e.draggable,interactive:e.interactive})),relations:(e.relations||[]).map((e,t)=>({id:e.id||"relation-"+t,relationType:relationType(e),sourceId:e.source,targetId:e.target,sourceField:e.sourceField||"id",targetField:e.targetField||"id",nullable:e.nullable,onDelete:e.onDelete,onUpdate:e.onUpdate,joinTableName:e.joinTableName,fromKey:e.fromKey,toKey:e.toKey,sourceCardinality:e.sourceCardinality,targetCardinality:e.targetCardinality,label:e.label,style:e.style,arrow:e.arrow,linkShape:e.linkShape,routeType:e.routeType,routeOffset:e.routeOffset,curveType:e.curveType,lineDash:e.lineDash})),layout:e.layout,options:e.options}}function layeredLayout(e,t,i={}){const o=Number(i.gapX)||90,r=Number(i.gapY)||90,n=void 0===i.originX?80:i.originX,s=void 0===i.originY?80:i.originY,a=new Map;if(!e.length)return a;const d=new Map;e.forEach(e=>d.set(e.id,e));const l=new Map,p=new Map;e.forEach(e=>{l.set(e.id,0),p.set(e.id,[])}),t.forEach(e=>{d.has(e.sourceId)&&d.has(e.targetId)&&(l.set(e.targetId,(l.get(e.targetId)||0)+1),p.get(e.sourceId).push(e.targetId))});const h=new Map,c=[];e.forEach(e=>{0===(l.get(e.id)||0)&&(h.set(e.id,0),c.push(e.id))}),c.length||(h.set(e[0].id,0),c.push(e[0].id));let u=e.length*e.length+e.length;for(;c.length&&u-- >0;){const e=c.shift(),t=h.get(e)||0;(p.get(e)||[]).forEach(e=>{const i=t+1;(void 0===h.get(e)?-1:h.get(e))<i&&(h.set(e,i),c.push(e))})}e.forEach(e=>{h.has(e.id)||h.set(e.id,0)});const f=new Map;e.forEach(e=>{const t=h.get(e.id)||0;f.has(t)||f.set(t,[]),f.get(t).push(e)});const m=[...f.keys()].sort((e,t)=>e-t);if("horizontal"===i.direction){const e=m.map(e=>Math.max(...f.get(e).map(e=>e.width)));let t=0;m.forEach((i,n)=>{const s=f.get(i);let d=-(s.reduce((e,t)=>e+t.height,0)+Math.max(s.length-1,0)*r)/2;s.forEach(i=>{a.set(i.id,{left:Math.round(t+(e[n]-i.width)/2),top:Math.round(d)}),d+=i.height+r}),t+=e[n]+o})}else{const e=m.map(e=>Math.max(...f.get(e).map(e=>e.height)));let t=0;m.forEach((i,n)=>{const s=f.get(i);let d=-(s.reduce((e,t)=>e+t.width,0)+Math.max(s.length-1,0)*o)/2;s.forEach(i=>{a.set(i.id,{left:Math.round(d),top:Math.round(t+(e[n]-i.height)/2)}),d+=i.width+o}),t+=e[n]+r})}const g=Math.min(...e.map(e=>a.get(e.id).left)),y=Math.min(...e.map(e=>a.get(e.id).top));return a.forEach(e=>{e.left+=n-g,e.top+=s-y}),a}const v={terminator:{width:e.terminator.width,height:e.terminator.height,fill:e.terminator.fill,stroke:e.terminator.stroke},process:{width:e.process.width,height:e.process.height,fill:e.process.fill,stroke:e.process.stroke},decision:{width:e.decision.width,height:e.decision.height,fill:e.decision.fill,stroke:e.decision.stroke},io:{width:e.io.width,height:e.io.height,fill:e.io.fill,stroke:e.io.stroke}};function compileFlowDsl(e){const t=e.options||{},i=(e.nodes||[]).map(e=>{const t=function nodeKind$1(e){return e.kind&&v[e.kind]?e.kind:"process"}(e),i=v[t];return{id:e.id,typeId:"FlowNode",kind:t,title:(o=e,o.title||o.name||o.id),left:"number"==typeof e.left?e.left:Number.NaN,top:"number"==typeof e.top?e.top:Number.NaN,width:"number"==typeof e.width?e.width:i.width,height:"number"==typeof e.height?e.height:i.height,fillColor:e.fillColor||i.fill,strokeColor:e.strokeColor||i.stroke};var o}),o=(e.edges||[]).map((e,t)=>({id:e.id||"edge-"+t,sourceId:e.source,targetId:e.target,sourcePort:e.sourcePort||"B",targetPort:e.targetPort||"T",label:e.label||"",linkShape:e.linkShape||"visio"})),r=t.layout||"layered";return"none"!==r&&i.some(e=>Number.isNaN(e.left)||Number.isNaN(e.top))&&(i.forEach(e=>{Number.isNaN(e.left)&&(e.left=0),Number.isNaN(e.top)&&(e.top=0)}),function autoLayout(e,t,i,o){const r=layeredLayout(e,t,{gapX:i,gapY:o});e.forEach(e=>{const t=r.get(e.id);t&&(e.left=t.left,e.top=t.top)})}(i,o,Number(t.gapX)||90,Number(t.gapY)||90)),i.forEach(e=>{Number.isNaN(e.left)&&(e.left=0),Number.isNaN(e.top)&&(e.top=0)}),{kind:"flowchart",nodes:i,edges:o,layout:r,options:t}}const N={pool:"bpmnPool",lane:"bpmnLane",task:"bpmnTask",event:"bpmnEvent",gateway:"bpmnGateway",subprocess:"bpmnSubprocess",dataObject:"bpmnDataObject",annotation:"bpmnAnnotation"},k=Number(e.bpmnPool.bandSize)||32,x=Number(e.bpmnLane.bandSize)||32,E=Number(e.bpmnLane.height)||130,D=Number(e.bpmnPool.width)||900;function toWorkingNode(t){const i=t.kind||"task",o=function presetOf(t){return e[t]||e.bpmnTask}(N[i]||"bpmnTask"),r={id:t.id,typeId:"FlowNode",kind:N[i]||"bpmnTask",title:t.title||t.name||t.id,left:"number"==typeof t.left?t.left:0,top:"number"==typeof t.top?t.top:0,width:"number"==typeof t.width?t.width:o.width,height:"number"==typeof t.height?t.height:o.height,fillColor:t.fillColor,strokeColor:t.strokeColor,dslKind:i,parent:t.parent,explicitLeft:"number"==typeof t.left,explicitTop:"number"==typeof t.top,explicitWidth:"number"==typeof t.width,explicitHeight:"number"==typeof t.height};return"event"===i&&(r.eventKind=t.eventKind||o.eventKind||"start",r.trigger=t.trigger||o.trigger||"none"),"gateway"===i&&(r.gatewayType=t.gatewayType||o.gatewayType||"exclusive"),"task"!==i&&"subprocess"!==i||(r.taskType=t.taskType||o.taskType||"none"),r}function buildGroups(e,t){const i=new Map;t.forEach(e=>i.set(e.id,e));const o=1===t.length?t[0]:null,r=[];return e.forEach(e=>{(e=>{let t=r.filter(t=>t.owner===e)[0];return t||(t={owner:e,nodes:[],box:null,didLayout:!1},r.push(t)),t})((e.parent?i.get(e.parent):void 0)||o).nodes.push(e)}),r}function layoutGroups(e,t,i,o){e.forEach(e=>{if(e.nodes.some(e=>!e.explicitLeft||!e.explicitTop)){const r=layeredLayout(e.nodes,t,{gapX:i,gapY:o,originX:0,originY:0,direction:"horizontal"});e.nodes.forEach(e=>{const t=r.get(e.id);t&&(e.left=t.left,e.top=t.top)}),e.didLayout=!0}e.box=function unionBox(e){if(!e.length)return null;let t=1/0,i=1/0,o=-1/0,r=-1/0;return e.forEach(e=>{t=Math.min(t,e.left),i=Math.min(i,e.top),o=Math.max(o,e.left+e.width),r=Math.max(r,e.top+e.height)}),{minX:t,minY:i,maxX:o,maxY:r}}(e.nodes)})}function compileBpmnDsl(e){const t=e.options||{},i=(e.nodes||[]).map(toWorkingNode),o=i.filter(e=>"pool"===e.dslKind),r=i.filter(e=>"lane"===e.dslKind),n=i.filter(e=>!function isContainer(e){return"pool"===e.dslKind||"lane"===e.dslKind}(e)),s=(e.edges||[]).map((e,t)=>({id:e.id||"edge-"+t,sourceId:e.source,targetId:e.target,flowType:e.type||e.flowType||"sequence",label:e.label||"",condition:e.condition||"",isDefault:!!e.isDefault,linkShape:e.linkShape||"visio"})),a=t.layout||"auto",d=function resolveLaneOwners(e,t){const i=new Map;return e.forEach(e=>{let o=e.parent;o||1!==t.length||(o=t[0].id),o&&i.set(e.id,o)}),i}(r,o),lanesOf=e=>r.filter(t=>d.get(t.id)===e);let l=[];"none"!==a&&(l=buildGroups(n,o.concat(r)),layoutGroups(l,s,Number(t.gapX)||90,Number(t.gapY)||60)),r.forEach(e=>{const t=l.filter(t=>t.owner===e)[0],i=t?t.box:null;e.explicitHeight||(e.height=Math.round(Math.max(56+(i?i.maxY-i.minY:0),E))),e.explicitWidth||(e.width=Math.round(Math.max((i?i.maxX-i.minX:0)+x+56,D)))}),o.forEach(e=>{const t=lanesOf(e.id);if(t.length){const i=t.reduce((e,t)=>Math.max(e,t.width),D);return e.explicitWidth||(e.width=i),e.explicitWidth&&t.forEach(t=>{t.explicitWidth||(t.width=e.width)}),void(e.explicitHeight||(e.height=k+t.reduce((e,t)=>e+t.height,0)))}const i=l.filter(t=>t.owner===e)[0],o=i?i.box:null;e.explicitWidth||(e.width=Math.round(Math.max(56+(o?o.maxX-o.minX:0),D))),e.explicitHeight||(e.height=Math.round(Math.max((o?o.maxY-o.minY:0)+k+56,160)))});let p=60;o.forEach(e=>{e.explicitLeft||(e.left=60),e.explicitTop||(e.top=p),p=Math.max(p,e.top+e.height+60)}),o.forEach(e=>{const t=lanesOf(e.id);if(!t.length)return;const i=e.top+k,o=Math.max(e.height-k,1),r=t.reduce((e,t)=>e+(t.explicitHeight?t.height:0),0),n=t.filter(e=>!e.explicitHeight),s=n.length?Math.max(o-r,0)/n.length:0;let a=i;t.forEach(t=>{t.explicitLeft||(t.left=e.left),t.explicitTop||(t.top=a),!t.explicitHeight&&e.explicitHeight&&(t.height=Math.round(s||E)),a=t.top+t.height})});let h=60;r.forEach(e=>{d.get(e.id)||(e.explicitLeft||(e.left=60),e.explicitTop||(e.top=h,h=e.top+e.height+60))}),l.forEach(e=>{const t=e.box;if(!t||!e.didLayout)return;const i=e.owner;let o=80,r=80;i&&(o=i.left+28,r=i.top+28,"pool"===i.dslKind?r+=k:o+=x),e.nodes.forEach(e=>{e.left=Math.round(o+(e.left-t.minX)),e.top=Math.round(r+(e.top-t.minY))})});return{kind:"bpmn",nodes:o.concat(r).concat(n).map(e=>{const t={id:e.id,typeId:"FlowNode",kind:e.kind,title:e.title,left:e.left,top:e.top,width:e.width,height:e.height};return void 0!==e.eventKind&&(t.eventKind=e.eventKind),void 0!==e.trigger&&(t.trigger=e.trigger),void 0!==e.gatewayType&&(t.gatewayType=e.gatewayType),void 0!==e.taskType&&(t.taskType=e.taskType),void 0!==e.fillColor&&(t.fillColor=e.fillColor),void 0!==e.strokeColor&&(t.strokeColor=e.strokeColor),t}),edges:s,layout:a,options:t}}function compileUmlDsl(e){const t=e.options||{},i=(e.nodes||[]).map(e=>{return{id:e.id,kind:(t=e,t.kind||"class"),className:e.title||e.name||e.id,abstract:!!e.abstract,attributes:Array.isArray(e.attributes)?e.attributes.map(e=>String(e)):[],methods:Array.isArray(e.methods)?e.methods.map(e=>String(e)):[],left:"number"==typeof e.left?e.left:Number.NaN,top:"number"==typeof e.top?e.top:Number.NaN,width:"number"==typeof e.width?e.width:240,height:"number"==typeof e.height?e.height:120+24*(e.attributes?e.attributes.length:0)+24*(e.methods?e.methods.length:0)};var t}),o=(e.edges||[]).map((e,t)=>({id:e.id||"relation-"+t,sourceId:e.source,targetId:e.target,relationKind:e.type||e.relation||"association",label:e.label||""})),r=t.layout||"layered";if("none"!==r&&i.some(e=>Number.isNaN(e.left)||Number.isNaN(e.top))){i.forEach(e=>{Number.isNaN(e.left)&&(e.left=0),Number.isNaN(e.top)&&(e.top=0)});const e=layeredLayout(i,o.filter(e=>"inheritance"===e.relationKind||"realization"===e.relationKind).map(e=>({sourceId:e.targetId,targetId:e.sourceId})),{gapX:Number(t.gapX)||80,gapY:Number(t.gapY)||110,originX:80,originY:80,direction:"vertical"});i.forEach(t=>{const i=e.get(t.id);i&&(t.left=i.left,t.top=i.top)})}return i.forEach(e=>{Number.isNaN(e.left)&&(e.left=0),Number.isNaN(e.top)&&(e.top=0)}),{kind:"uml",nodes:i,edges:o,layout:r,options:t}}const M={width:160,height:64},$={width:500,height:200};function compileStatechartDsl(e){const t=e.options||{},i=(e.nodes||[]).map(e=>{const t=e.kind||"state",i="initial"===t||"final"===t,o="composite"===t?$:i?{width:24,height:24}:M;return{id:e.id,kind:t,title:e.title||e.name||(i?"":e.id),parent:e.parent,left:"number"==typeof e.left?e.left:Number.NaN,top:"number"==typeof e.top?e.top:Number.NaN,width:"number"==typeof e.width?e.width:o.width,height:"number"==typeof e.height?e.height:o.height}}),o=(e.edges||[]).map((e,t)=>({id:e.id||"transition-"+t,sourceId:e.source,targetId:e.target,event:e.event||"",guard:e.guard||"",action:e.action||"",label:e.label})),r=t.layout||"auto",n=new Set;if("none"!==r){const e=new Map;i.forEach(t=>e.set(t.id,t));const r=i.filter(t=>!(t.parent&&e.has(t.parent)));if(r.some(e=>Number.isNaN(e.left)||Number.isNaN(e.top))){const containerOf=t=>{let i=e.get(t);for(;i&&i.parent&&e.has(i.parent);)i=e.get(i.parent);return i?i.id:t},i=o.map(e=>({sourceId:containerOf(e.sourceId),targetId:containerOf(e.targetId)})).filter(e=>e.sourceId!==e.targetId),n=layeredLayout(r,i,{gapX:Number(t.gapX)||110,gapY:Number(t.gapY)||80,originX:80,originY:80,direction:"horizontal"});r.forEach(e=>{const t=n.get(e.id);t&&(e.left=t.left,e.top=t.top)})}let s=0;i.filter(e=>"composite"===e.kind).forEach(e=>{const t=i.filter(t=>t.parent===e.id);if(Number.isNaN(e.left)&&(e.left=80),Number.isNaN(e.top)){const t=Math.max(...r.filter(t=>t!==e&&!Number.isNaN(t.top)).map(e=>e.top+e.height),0);e.top=Math.max(t+60,80)+s,s+=e.height+60}if(!t.length)return;let o=56,a=56,d=0,l=56;const p=e.width-112;t.forEach(e=>{(Number.isNaN(e.left)||Number.isNaN(e.top))&&(o>56&&o+e.width>56+p&&(o=56,a=l+40),n.add(e.id),e.left=o,e.top=a,o+=e.width+40,d=Math.max(d,o),l=Math.max(l,a+e.height))}),e.width=Math.max(e.width,d+56),e.height=Math.max(e.height,l+56)}),i.forEach(e=>{Number.isNaN(e.left)&&(e.left=0),Number.isNaN(e.top)&&(e.top=0)});const offsetChildren=(e,t,o)=>{i.filter(t=>t.parent===e.id).forEach(e=>{n.has(e.id)&&(e.left+=t,e.top+=o,offsetChildren(e,t,o))})};i.filter(e=>"composite"===e.kind).forEach(e=>offsetChildren(e,e.left,e.top))}return{kind:"statechart",nodes:i,edges:o,layout:r,options:t}}function renderDsl(e,i){const o=validateDsl(i);if(!o.valid)throw new Error(o.errors.join("\n"));return isStatechartDsl(i)?renderStatechartDsl(e,i):isUmlDsl(i)?renderUmlDsl(e,i):isBpmnDsl(i)?renderBpmnDsl(e,i):isFlowDsl(i)?renderFlowDsl(e,i):function renderErDsl(e,i){const o=compileDsl(i),r=o.options||{},n=(new t).init(e),d=new s(n);o.entities.forEach(e=>{d.createEntity(e)}),function positionLinks(e,t,i){const o=new Map;return e.entities.forEach(e=>{o.set(e.state.id,e.getMinBoundingBox(!0))}),t.relations.map(e=>{const t=o.get(e.sourceId),r=o.get(e.targetId);let n="R",s="L";if(t&&r){const e=r.center[0]-t.center[0],i=r.center[1]-t.center[1];Math.abs(e)>Math.abs(i)?(n=e>=0?"R":"L",s=e>=0?"L":"R"):(n=i>=0?"B":"T",s=i>=0?"T":"B")}return{...e,routeType:e.routeType||i||"orthogonal",linkShape:e.linkShape||"visio",links:{start:{id:e.sourceId,position:n},end:{id:e.targetId,position:s}}}})}(d,o,r.routeType).forEach(e=>{d.createRelation(e)}),("layered"===o.layout||"horizontal"===o.layout)&&new a({gapX:r.gapX||120,gapY:r.gapY||50}).layoutContainer(n);r.viewport?n.setViewport(r.viewport.scale,r.viewport.tx,r.viewport.ty):r.fitViewport&&function fitViewport(e,t,i){const o=t.entities||[];let r=1/0,n=1/0,s=-1/0,a=-1/0;o.forEach(e=>{const t=e.getMinBoundingBox(!0).getMinAndMaxPoint();r=Math.min(r,t.minX),n=Math.min(n,t.minY),s=Math.max(s,t.maxX),a=Math.max(a,t.maxY)});const d=s-r,l=a-n,p=e.canvasWidth||0,h=e.canvasHeight||0;if(!p||!h||d<=0||l<=0)return;const c=Number.isFinite(i)&&i>=0?i:40,u=Math.max(1,p-2*c),f=Math.max(1,h-2*c),m=Math.min(u/d,f/l,1),g=(p-d*m)/2-r*m,y=(h-l*m)/2-n*m;e.setViewport(m,g,y)}(n,d,r.fitViewportPadding);return{kind:"entity",ice:n,designer:d}}(e,i)}function renderStatechartDsl(e,o){const r=compileStatechartDsl(o),n=r.options||{},s=(new t).init(e),a=new i(s);return r.nodes.forEach(e=>{a.createState({id:e.id,kind:e.kind,title:e.title,left:e.left,top:e.top,width:e.width,height:e.height})}),r.edges.forEach(e=>{a.createTransition(e)}),a.select(null),n.viewport?s.setViewport(n.viewport.scale,n.viewport.tx,n.viewport.ty):!1!==n.fitViewport&&a.fitViewport(n.fitViewportPadding),a.resetHistory(),{kind:"statechart",ice:s,designer:a}}function renderUmlDsl(e,i){const r=compileUmlDsl(i),n=r.options||{},s=(new t).init(e),a=new o(s);return r.nodes.forEach(e=>{a.createClass({id:e.id,kind:e.kind,className:e.className,abstract:e.abstract,attributes:e.attributes,methods:e.methods,left:e.left,top:e.top,width:e.width})}),r.edges.forEach(e=>{a.createRelation(e)}),a.select(null),n.viewport?s.setViewport(n.viewport.scale,n.viewport.tx,n.viewport.ty):!1!==n.fitViewport&&a.fitViewport(n.fitViewportPadding),a.resetHistory(),{kind:"uml",ice:s,designer:a}}function renderBpmnDsl(e,i){const o=compileBpmnDsl(i),n=o.options||{},s=(new t).init(e),a=new r(s);return o.nodes.forEach(e=>{const t={id:e.id,title:e.title,left:e.left,top:e.top,width:e.width,height:e.height};["eventKind","trigger","gatewayType","taskType","fillColor","strokeColor"].forEach(i=>{void 0!==e[i]&&(t[i]=e[i])}),a.createNode(e.kind,t)}),o.edges.forEach(e=>{a.createEdge(e)}),a.select(null),n.viewport?s.setViewport(n.viewport.scale,n.viewport.tx,n.viewport.ty):!1!==n.fitViewport&&a.fitViewport(n.fitViewportPadding),a.resetHistory(),{kind:"bpmn",ice:s,designer:a}}function renderFlowDsl(e,i){const o=compileFlowDsl(i),r=o.options||{},s=(new t).init(e),a=new n(s);return o.nodes.forEach(e=>{a.createNode(e.kind,e)}),o.edges.forEach(e=>{a.createEdge(e)}),a.select(null),r.viewport?s.setViewport(r.viewport.scale,r.viewport.tx,r.viewport.ty):!1!==r.fitViewport&&a.fitViewport(r.fitViewportPadding),a.resetHistory(),{kind:"flowchart",ice:s,designer:a}}export{d as DSL_SCHEMA_VERSION,compileBpmnDsl,compileDsl,compileFlowDsl,compileStatechartDsl,compileUmlDsl,isBpmnDsl,isFlowDsl,isStatechartDsl,isUmlDsl,layeredLayout,renderBpmnDsl,renderDsl,renderFlowDsl,renderStatechartDsl,renderUmlDsl,validateBpmnDsl,validateDsl,validateFlowDsl,validateStatechartDsl,validateUmlDsl};
package/dist/index.umd.js CHANGED
@@ -1 +1 @@
1
- !function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports,require("ice-entity-designer")):"function"==typeof define&&define.amd?define(["exports","ice-entity-designer"],t):t((e="undefined"!=typeof globalThis?globalThis:e||self).ICEDSL={},e.IED)}(this,(function(e,t){"use strict";function isFlowDsl(e){return!!e&&"object"==typeof e&&"flowchart"===e.kind}function isBpmnDsl(e){return!!e&&"object"==typeof e&&"bpmn"===e.kind}function isUmlDsl(e){return!!e&&"object"==typeof e&&"uml"===e.kind}const i=["terminator","process","decision","io"],o=["T","R","B","L","C"],n=["pool","lane","task","event","gateway","subprocess","dataObject","annotation"],r=["start","intermediate","end"],s=["none","message","timer","error","terminate"],a=["exclusive","parallel","inclusive","event"],l=["none","user","service","script","send","receive","manual"],d=["sequence","message","association"],p=["class","interface","enum"],h=["inheritance","realization","association","aggregation","composition","dependency"];function validateDsl(e){return isUmlDsl(e)?validateUmlDsl(e):isBpmnDsl(e)?validateBpmnDsl(e):isFlowDsl(e)?validateFlowDsl(e):function validateErDsl(e){const t=[];if(!e||"object"!=typeof e||Array.isArray(e))return{valid:!1,errors:["DSL root must be an object"]};void 0!==e.schemaVersion&&1!==e.schemaVersion&&t.push("Unsupported schemaVersion: "+e.schemaVersion);if(Array.isArray(e.entities)){const i=new Set;e.entities.forEach((e,o)=>{const n=`entities[${o}]`;e&&"object"==typeof e?("string"==typeof e.id&&e.id.trim()?i.has(e.id)?t.push(`${n}.id is duplicated: ${e.id}`):i.add(e.id):t.push(n+".id must be a non-empty string"),Array.isArray(e.fields)?e.fields.forEach((e,i)=>{e&&"object"==typeof e&&"string"==typeof e.name&&e.name.trim()||t.push(`${n}.fields[${i}].name must be a non-empty string`)}):t.push(n+".fields must be an array")):t.push(n+" must be an object")})}else t.push("entities must be an array");void 0===e.relations||Array.isArray(e.relations)?(e.relations||[]).forEach((e,i)=>{const o=`relations[${i}]`;e&&"object"==typeof e?("string"==typeof e.source&&e.source.trim()||t.push(o+".source must be a non-empty string"),"string"==typeof e.target&&e.target.trim()||t.push(o+".target must be a non-empty string")):t.push(o+" must be an object")}):t.push("relations must be an array");return{valid:0===t.length,errors:t}}(e)}function validateBpmnDsl(e){const t=[];if(!e||"object"!=typeof e||Array.isArray(e))return{valid:!1,errors:["DSL root must be an object"]};void 0!==e.schemaVersion&&1!==e.schemaVersion&&t.push("Unsupported schemaVersion: "+e.schemaVersion);const i=new Set,o=new Map;return Array.isArray(e.nodes)?(e.nodes.forEach((e,d)=>{const p=`nodes[${d}]`;if(!e||"object"!=typeof e)return void t.push(p+" must be an object");"string"==typeof e.id&&e.id.trim()?i.has(e.id)?t.push(`${p}.id is duplicated: ${e.id}`):(i.add(e.id),o.set(e.id,e.kind||"task")):t.push(p+".id must be a non-empty string"),void 0!==e.kind&&-1===n.indexOf(e.kind)&&t.push(`${p}.kind must be one of ${n.join("/")}`),["left","top","width","height"].forEach(i=>{const o=e[i];void 0!==o&&"number"!=typeof o&&t.push(`${p}.${i} must be a number when present`)});[["eventKind",r],["trigger",s],["gatewayType",a],["taskType",l]].forEach(([i,o])=>{const n=e[i];void 0!==n&&-1===o.indexOf(n)&&t.push(`${p}.${i} must be one of ${o.join("/")}`)})}),e.nodes.forEach((e,n)=>{if(!e||"object"!=typeof e||void 0===e.parent)return;const r=`nodes[${n}]`;if("string"!=typeof e.parent||!e.parent.trim())return void t.push(r+".parent must be a non-empty string when present");if(!i.has(e.parent))return void t.push(r+".parent must reference an existing node id");if(e.parent===e.id)return void t.push(r+".parent must not reference itself");const s=o.get(e.parent);"pool"===e.kind?t.push(r+".parent is not allowed on a pool (池是最外层容器)"):"lane"===e.kind&&"pool"!==s?t.push(r+".parent must reference a pool"):"pool"!==s&&"lane"!==s&&t.push(r+".parent must reference a pool or a lane")})):t.push("nodes must be an array"),void 0===e.edges||Array.isArray(e.edges)?(e.edges||[]).forEach((e,o)=>{const n=`edges[${o}]`;if(!e||"object"!=typeof e)return void t.push(n+" must be an object");"string"==typeof e.source&&e.source.trim()&&i.has(e.source)||t.push(n+".source must reference an existing node id"),"string"==typeof e.target&&e.target.trim()&&i.has(e.target)||t.push(n+".target must reference an existing node id");const r=void 0!==e.type?e.type:e.flowType;void 0!==r&&-1===d.indexOf(r)&&t.push(`${n}.type must be one of ${d.join("/")}`),void 0!==e.label&&"string"!=typeof e.label&&t.push(n+".label must be a string when present"),void 0!==e.condition&&"string"!=typeof e.condition&&t.push(n+".condition must be a string when present"),void 0!==e.linkShape&&"visio"!==e.linkShape&&"bezier"!==e.linkShape&&t.push(n+'.linkShape must be "visio" or "bezier" when present')}):t.push("edges must be an array when present"),{valid:0===t.length,errors:t}}function validateFlowDsl(e){const t=[];if(!e||"object"!=typeof e||Array.isArray(e))return{valid:!1,errors:["DSL root must be an object"]};void 0!==e.schemaVersion&&1!==e.schemaVersion&&t.push("Unsupported schemaVersion: "+e.schemaVersion);const n=new Set;return Array.isArray(e.nodes)?e.nodes.forEach((e,o)=>{const r=`nodes[${o}]`;e&&"object"==typeof e?("string"==typeof e.id&&e.id.trim()?n.has(e.id)?t.push(`${r}.id is duplicated: ${e.id}`):n.add(e.id):t.push(r+".id must be a non-empty string"),void 0!==e.kind&&-1===i.indexOf(e.kind)&&t.push(`${r}.kind must be one of ${i.join("/")}`),["left","top","width","height"].forEach(i=>{const o=e[i];void 0!==o&&"number"!=typeof o&&t.push(`${r}.${i} must be a number when present`)})):t.push(r+" must be an object")}):t.push("nodes must be an array"),void 0===e.edges||Array.isArray(e.edges)?(e.edges||[]).forEach((e,i)=>{const r=`edges[${i}]`;e&&"object"==typeof e?("string"==typeof e.source&&e.source.trim()&&n.has(e.source)||t.push(r+".source must reference an existing node id"),"string"==typeof e.target&&e.target.trim()&&n.has(e.target)||t.push(r+".target must reference an existing node id"),void 0!==e.label&&"string"!=typeof e.label&&t.push(r+".label must be a string when present"),void 0!==e.sourcePort&&-1===o.indexOf(e.sourcePort)&&t.push(`${r}.sourcePort must be one of ${o.join("/")}`),void 0!==e.targetPort&&-1===o.indexOf(e.targetPort)&&t.push(`${r}.targetPort must be one of ${o.join("/")}`),void 0!==e.linkShape&&"visio"!==e.linkShape&&"bezier"!==e.linkShape&&t.push(r+'.linkShape must be "visio" or "bezier" when present')):t.push(r+" must be an object")}):t.push("edges must be an array when present"),{valid:0===t.length,errors:t}}function validateUmlDsl(e){const t=[];if(!e||"object"!=typeof e||Array.isArray(e))return{valid:!1,errors:["DSL root must be an object"]};void 0!==e.schemaVersion&&1!==e.schemaVersion&&t.push("Unsupported schemaVersion: "+e.schemaVersion);const i=new Set;return Array.isArray(e.nodes)?e.nodes.forEach((e,o)=>{const n=`nodes[${o}]`;e&&"object"==typeof e?("string"==typeof e.id&&e.id.trim()?i.has(e.id)?t.push(`${n}.id is duplicated: ${e.id}`):i.add(e.id):t.push(n+".id must be a non-empty string"),void 0!==e.kind&&-1===p.indexOf(e.kind)&&t.push(`${n}.kind must be one of ${p.join("/")}`),["attributes","methods"].forEach(i=>{const o=e[i];void 0!==o&&(Array.isArray(o)&&!o.some(e=>"string"!=typeof e)||t.push(`${n}.${i} must be an array of strings when present`))}),["left","top","width","height"].forEach(i=>{const o=e[i];void 0!==o&&"number"!=typeof o&&t.push(`${n}.${i} must be a number when present`)})):t.push(n+" must be an object")}):t.push("nodes must be an array"),void 0===e.edges||Array.isArray(e.edges)?(e.edges||[]).forEach((e,o)=>{const n=`edges[${o}]`;if(!e||"object"!=typeof e)return void t.push(n+" must be an object");"string"==typeof e.source&&e.source.trim()&&i.has(e.source)||t.push(n+".source must reference an existing node id"),"string"==typeof e.target&&e.target.trim()&&i.has(e.target)||t.push(n+".target must reference an existing node id");const r=void 0!==e.type?e.type:e.relation;void 0!==r&&-1===h.indexOf(r)&&t.push(`${n}.type must be one of ${h.join("/")}`),void 0!==e.label&&"string"!=typeof e.label&&t.push(n+".label must be a string when present")}):t.push("edges must be an array when present"),{valid:0===t.length,errors:t}}function entityName(e){return e.entityName||e.name||e.id}function relationType(e){return e.relationType||e.type||"one-to-many"}function compileDsl(e){if(isFlowDsl(e))throw new Error("compileDsl() 只处理 ER 文档;流程图文档请使用 compileFlowDsl()");if(!e||!Array.isArray(e.entities))throw new Error("ER 文档必须包含 entities 数组");return{entities:e.entities.map(e=>({id:e.id,entityName:entityName(e),fields:e.fields||[],left:e.left,top:e.top,width:e.width,height:e.height,style:e.style,headerStyle:e.headerStyle,fieldStyle:e.fieldStyle,dividerStyle:e.dividerStyle,draggable:e.draggable,interactive:e.interactive})),relations:(e.relations||[]).map((e,t)=>({id:e.id||"relation-"+t,relationType:relationType(e),sourceId:e.source,targetId:e.target,sourceField:e.sourceField||"id",targetField:e.targetField||"id",nullable:e.nullable,onDelete:e.onDelete,onUpdate:e.onUpdate,joinTableName:e.joinTableName,fromKey:e.fromKey,toKey:e.toKey,sourceCardinality:e.sourceCardinality,targetCardinality:e.targetCardinality,label:e.label,style:e.style,arrow:e.arrow,linkShape:e.linkShape,routeType:e.routeType,routeOffset:e.routeOffset,curveType:e.curveType,lineDash:e.lineDash})),layout:e.layout,options:e.options}}function layeredLayout(e,t,i={}){const o=Number(i.gapX)||90,n=Number(i.gapY)||90,r=void 0===i.originX?80:i.originX,s=void 0===i.originY?80:i.originY,a=new Map;if(!e.length)return a;const l=new Map;e.forEach(e=>l.set(e.id,e));const d=new Map,p=new Map;e.forEach(e=>{d.set(e.id,0),p.set(e.id,[])}),t.forEach(e=>{l.has(e.sourceId)&&l.has(e.targetId)&&(d.set(e.targetId,(d.get(e.targetId)||0)+1),p.get(e.sourceId).push(e.targetId))});const h=new Map,c=[];e.forEach(e=>{0===(d.get(e.id)||0)&&(h.set(e.id,0),c.push(e.id))}),c.length||(h.set(e[0].id,0),c.push(e[0].id));let u=e.length*e.length+e.length;for(;c.length&&u-- >0;){const e=c.shift(),t=h.get(e)||0;(p.get(e)||[]).forEach(e=>{const i=t+1;(void 0===h.get(e)?-1:h.get(e))<i&&(h.set(e,i),c.push(e))})}e.forEach(e=>{h.has(e.id)||h.set(e.id,0)});const f=new Map;e.forEach(e=>{const t=h.get(e.id)||0;f.has(t)||f.set(t,[]),f.get(t).push(e)});const m=[...f.keys()].sort((e,t)=>e-t);if("horizontal"===i.direction){const e=m.map(e=>Math.max(...f.get(e).map(e=>e.width)));let t=0;m.forEach((i,r)=>{const s=f.get(i);let l=-(s.reduce((e,t)=>e+t.height,0)+Math.max(s.length-1,0)*n)/2;s.forEach(i=>{a.set(i.id,{left:Math.round(t+(e[r]-i.width)/2),top:Math.round(l)}),l+=i.height+n}),t+=e[r]+o})}else{const e=m.map(e=>Math.max(...f.get(e).map(e=>e.height)));let t=0;m.forEach((i,r)=>{const s=f.get(i);let l=-(s.reduce((e,t)=>e+t.width,0)+Math.max(s.length-1,0)*o)/2;s.forEach(i=>{a.set(i.id,{left:Math.round(l),top:Math.round(t+(e[r]-i.height)/2)}),l+=i.width+o}),t+=e[r]+n})}const g=Math.min(...e.map(e=>a.get(e.id).left)),y=Math.min(...e.map(e=>a.get(e.id).top));return a.forEach(e=>{e.left+=r-g,e.top+=s-y}),a}const c={terminator:{width:t.FLOW_NODE_KINDS.terminator.width,height:t.FLOW_NODE_KINDS.terminator.height,fill:t.FLOW_NODE_KINDS.terminator.fill,stroke:t.FLOW_NODE_KINDS.terminator.stroke},process:{width:t.FLOW_NODE_KINDS.process.width,height:t.FLOW_NODE_KINDS.process.height,fill:t.FLOW_NODE_KINDS.process.fill,stroke:t.FLOW_NODE_KINDS.process.stroke},decision:{width:t.FLOW_NODE_KINDS.decision.width,height:t.FLOW_NODE_KINDS.decision.height,fill:t.FLOW_NODE_KINDS.decision.fill,stroke:t.FLOW_NODE_KINDS.decision.stroke},io:{width:t.FLOW_NODE_KINDS.io.width,height:t.FLOW_NODE_KINDS.io.height,fill:t.FLOW_NODE_KINDS.io.fill,stroke:t.FLOW_NODE_KINDS.io.stroke}};function compileFlowDsl(e){const t=e.options||{},i=(e.nodes||[]).map(e=>{const t=function nodeKind$1(e){return e.kind&&c[e.kind]?e.kind:"process"}(e),i=c[t];return{id:e.id,typeId:"FlowNode",kind:t,title:(o=e,o.title||o.name||o.id),left:"number"==typeof e.left?e.left:Number.NaN,top:"number"==typeof e.top?e.top:Number.NaN,width:"number"==typeof e.width?e.width:i.width,height:"number"==typeof e.height?e.height:i.height,fillColor:e.fillColor||i.fill,strokeColor:e.strokeColor||i.stroke};var o}),o=(e.edges||[]).map((e,t)=>({id:e.id||"edge-"+t,sourceId:e.source,targetId:e.target,sourcePort:e.sourcePort||"B",targetPort:e.targetPort||"T",label:e.label||"",linkShape:e.linkShape||"visio"})),n=t.layout||"layered";return"none"!==n&&i.some(e=>Number.isNaN(e.left)||Number.isNaN(e.top))&&(i.forEach(e=>{Number.isNaN(e.left)&&(e.left=0),Number.isNaN(e.top)&&(e.top=0)}),function autoLayout(e,t,i,o){const n=layeredLayout(e,t,{gapX:i,gapY:o});e.forEach(e=>{const t=n.get(e.id);t&&(e.left=t.left,e.top=t.top)})}(i,o,Number(t.gapX)||90,Number(t.gapY)||90)),i.forEach(e=>{Number.isNaN(e.left)&&(e.left=0),Number.isNaN(e.top)&&(e.top=0)}),{kind:"flowchart",nodes:i,edges:o,layout:n,options:t}}const u={pool:"bpmnPool",lane:"bpmnLane",task:"bpmnTask",event:"bpmnEvent",gateway:"bpmnGateway",subprocess:"bpmnSubprocess",dataObject:"bpmnDataObject",annotation:"bpmnAnnotation"},f=Number(t.FLOW_NODE_KINDS.bpmnPool.bandSize)||32,m=Number(t.FLOW_NODE_KINDS.bpmnLane.bandSize)||32,g=Number(t.FLOW_NODE_KINDS.bpmnLane.height)||130,y=Number(t.FLOW_NODE_KINDS.bpmnPool.width)||900;function toWorkingNode(e){const i=e.kind||"task",o=function presetOf(e){return t.FLOW_NODE_KINDS[e]||t.FLOW_NODE_KINDS.bpmnTask}(u[i]||"bpmnTask"),n={id:e.id,typeId:"FlowNode",kind:u[i]||"bpmnTask",title:e.title||e.name||e.id,left:"number"==typeof e.left?e.left:0,top:"number"==typeof e.top?e.top:0,width:"number"==typeof e.width?e.width:o.width,height:"number"==typeof e.height?e.height:o.height,fillColor:e.fillColor,strokeColor:e.strokeColor,dslKind:i,parent:e.parent,explicitLeft:"number"==typeof e.left,explicitTop:"number"==typeof e.top,explicitWidth:"number"==typeof e.width,explicitHeight:"number"==typeof e.height};return"event"===i&&(n.eventKind=e.eventKind||o.eventKind||"start",n.trigger=e.trigger||o.trigger||"none"),"gateway"===i&&(n.gatewayType=e.gatewayType||o.gatewayType||"exclusive"),"task"!==i&&"subprocess"!==i||(n.taskType=e.taskType||o.taskType||"none"),n}function buildGroups(e,t){const i=new Map;t.forEach(e=>i.set(e.id,e));const o=1===t.length?t[0]:null,n=[];return e.forEach(e=>{(e=>{let t=n.filter(t=>t.owner===e)[0];return t||(t={owner:e,nodes:[],box:null,didLayout:!1},n.push(t)),t})((e.parent?i.get(e.parent):void 0)||o).nodes.push(e)}),n}function layoutGroups(e,t,i,o){e.forEach(e=>{if(e.nodes.some(e=>!e.explicitLeft||!e.explicitTop)){const n=layeredLayout(e.nodes,t,{gapX:i,gapY:o,originX:0,originY:0,direction:"horizontal"});e.nodes.forEach(e=>{const t=n.get(e.id);t&&(e.left=t.left,e.top=t.top)}),e.didLayout=!0}e.box=function unionBox(e){if(!e.length)return null;let t=1/0,i=1/0,o=-1/0,n=-1/0;return e.forEach(e=>{t=Math.min(t,e.left),i=Math.min(i,e.top),o=Math.max(o,e.left+e.width),n=Math.max(n,e.top+e.height)}),{minX:t,minY:i,maxX:o,maxY:n}}(e.nodes)})}function compileBpmnDsl(e){const t=e.options||{},i=(e.nodes||[]).map(toWorkingNode),o=i.filter(e=>"pool"===e.dslKind),n=i.filter(e=>"lane"===e.dslKind),r=i.filter(e=>!function isContainer(e){return"pool"===e.dslKind||"lane"===e.dslKind}(e)),s=(e.edges||[]).map((e,t)=>({id:e.id||"edge-"+t,sourceId:e.source,targetId:e.target,flowType:e.type||e.flowType||"sequence",label:e.label||"",condition:e.condition||"",isDefault:!!e.isDefault,linkShape:e.linkShape||"visio"})),a=t.layout||"auto",l=function resolveLaneOwners(e,t){const i=new Map;return e.forEach(e=>{let o=e.parent;o||1!==t.length||(o=t[0].id),o&&i.set(e.id,o)}),i}(n,o),lanesOf=e=>n.filter(t=>l.get(t.id)===e);let d=[];"none"!==a&&(d=buildGroups(r,o.concat(n)),layoutGroups(d,s,Number(t.gapX)||90,Number(t.gapY)||60)),n.forEach(e=>{const t=d.filter(t=>t.owner===e)[0],i=t?t.box:null;e.explicitHeight||(e.height=Math.round(Math.max(56+(i?i.maxY-i.minY:0),g))),e.explicitWidth||(e.width=Math.round(Math.max((i?i.maxX-i.minX:0)+m+56,y)))}),o.forEach(e=>{const t=lanesOf(e.id);if(t.length){const i=t.reduce((e,t)=>Math.max(e,t.width),y);return e.explicitWidth||(e.width=i),e.explicitWidth&&t.forEach(t=>{t.explicitWidth||(t.width=e.width)}),void(e.explicitHeight||(e.height=f+t.reduce((e,t)=>e+t.height,0)))}const i=d.filter(t=>t.owner===e)[0],o=i?i.box:null;e.explicitWidth||(e.width=Math.round(Math.max(56+(o?o.maxX-o.minX:0),y))),e.explicitHeight||(e.height=Math.round(Math.max((o?o.maxY-o.minY:0)+f+56,160)))});let p=60;o.forEach(e=>{e.explicitLeft||(e.left=60),e.explicitTop||(e.top=p),p=Math.max(p,e.top+e.height+60)}),o.forEach(e=>{const t=lanesOf(e.id);if(!t.length)return;const i=e.top+f,o=Math.max(e.height-f,1),n=t.reduce((e,t)=>e+(t.explicitHeight?t.height:0),0),r=t.filter(e=>!e.explicitHeight),s=r.length?Math.max(o-n,0)/r.length:0;let a=i;t.forEach(t=>{t.explicitLeft||(t.left=e.left),t.explicitTop||(t.top=a),!t.explicitHeight&&e.explicitHeight&&(t.height=Math.round(s||g)),a=t.top+t.height})});let h=60;n.forEach(e=>{l.get(e.id)||(e.explicitLeft||(e.left=60),e.explicitTop||(e.top=h,h=e.top+e.height+60))}),d.forEach(e=>{const t=e.box;if(!t||!e.didLayout)return;const i=e.owner;let o=80,n=80;i&&(o=i.left+28,n=i.top+28,"pool"===i.dslKind?n+=f:o+=m),e.nodes.forEach(e=>{e.left=Math.round(o+(e.left-t.minX)),e.top=Math.round(n+(e.top-t.minY))})});return{kind:"bpmn",nodes:o.concat(n).concat(r).map(e=>{const t={id:e.id,typeId:"FlowNode",kind:e.kind,title:e.title,left:e.left,top:e.top,width:e.width,height:e.height};return void 0!==e.eventKind&&(t.eventKind=e.eventKind),void 0!==e.trigger&&(t.trigger=e.trigger),void 0!==e.gatewayType&&(t.gatewayType=e.gatewayType),void 0!==e.taskType&&(t.taskType=e.taskType),void 0!==e.fillColor&&(t.fillColor=e.fillColor),void 0!==e.strokeColor&&(t.strokeColor=e.strokeColor),t}),edges:s,layout:a,options:t}}function compileUmlDsl(e){const t=e.options||{},i=(e.nodes||[]).map(e=>{return{id:e.id,kind:(t=e,t.kind||"class"),className:e.title||e.name||e.id,abstract:!!e.abstract,attributes:Array.isArray(e.attributes)?e.attributes.map(e=>String(e)):[],methods:Array.isArray(e.methods)?e.methods.map(e=>String(e)):[],left:"number"==typeof e.left?e.left:Number.NaN,top:"number"==typeof e.top?e.top:Number.NaN,width:"number"==typeof e.width?e.width:240,height:"number"==typeof e.height?e.height:120+24*(e.attributes?e.attributes.length:0)+24*(e.methods?e.methods.length:0)};var t}),o=(e.edges||[]).map((e,t)=>({id:e.id||"relation-"+t,sourceId:e.source,targetId:e.target,relationKind:e.type||e.relation||"association",label:e.label||""})),n=t.layout||"layered";if("none"!==n&&i.some(e=>Number.isNaN(e.left)||Number.isNaN(e.top))){i.forEach(e=>{Number.isNaN(e.left)&&(e.left=0),Number.isNaN(e.top)&&(e.top=0)});const e=layeredLayout(i,o.filter(e=>"inheritance"===e.relationKind||"realization"===e.relationKind).map(e=>({sourceId:e.targetId,targetId:e.sourceId})),{gapX:Number(t.gapX)||80,gapY:Number(t.gapY)||110,originX:80,originY:80,direction:"vertical"});i.forEach(t=>{const i=e.get(t.id);i&&(t.left=i.left,t.top=i.top)})}return i.forEach(e=>{Number.isNaN(e.left)&&(e.left=0),Number.isNaN(e.top)&&(e.top=0)}),{kind:"uml",nodes:i,edges:o,layout:n,options:t}}function renderUmlDsl(e,i){const o=compileUmlDsl(i),n=o.options||{},r=(new t.ICE).init(e),s=new t.UmlDesigner(r);return o.nodes.forEach(e=>{s.createClass({id:e.id,kind:e.kind,className:e.className,abstract:e.abstract,attributes:e.attributes,methods:e.methods,left:e.left,top:e.top,width:e.width})}),o.edges.forEach(e=>{s.createRelation(e)}),s.select(null),n.viewport?r.setViewport(n.viewport.scale,n.viewport.tx,n.viewport.ty):!1!==n.fitViewport&&s.fitViewport(n.fitViewportPadding),s.resetHistory(),{kind:"uml",ice:r,designer:s}}function renderBpmnDsl(e,i){const o=compileBpmnDsl(i),n=o.options||{},r=(new t.ICE).init(e),s=new t.BpmnDesigner(r);return o.nodes.forEach(e=>{const t={id:e.id,title:e.title,left:e.left,top:e.top,width:e.width,height:e.height};["eventKind","trigger","gatewayType","taskType","fillColor","strokeColor"].forEach(i=>{void 0!==e[i]&&(t[i]=e[i])}),s.createNode(e.kind,t)}),o.edges.forEach(e=>{s.createEdge(e)}),s.select(null),n.viewport?r.setViewport(n.viewport.scale,n.viewport.tx,n.viewport.ty):!1!==n.fitViewport&&s.fitViewport(n.fitViewportPadding),s.resetHistory(),{kind:"bpmn",ice:r,designer:s}}function renderFlowDsl(e,i){const o=compileFlowDsl(i),n=o.options||{},r=(new t.ICE).init(e),s=new t.FlowDesigner(r);return o.nodes.forEach(e=>{s.createNode(e.kind,e)}),o.edges.forEach(e=>{s.createEdge(e)}),s.select(null),n.viewport?r.setViewport(n.viewport.scale,n.viewport.tx,n.viewport.ty):!1!==n.fitViewport&&s.fitViewport(n.fitViewportPadding),s.resetHistory(),{kind:"flowchart",ice:r,designer:s}}e.DSL_SCHEMA_VERSION=1,e.compileBpmnDsl=compileBpmnDsl,e.compileDsl=compileDsl,e.compileFlowDsl=compileFlowDsl,e.compileUmlDsl=compileUmlDsl,e.isBpmnDsl=isBpmnDsl,e.isFlowDsl=isFlowDsl,e.isUmlDsl=isUmlDsl,e.layeredLayout=layeredLayout,e.renderBpmnDsl=renderBpmnDsl,e.renderDsl=function renderDsl(e,i){const o=validateDsl(i);if(!o.valid)throw new Error(o.errors.join("\n"));return isUmlDsl(i)?renderUmlDsl(e,i):isBpmnDsl(i)?renderBpmnDsl(e,i):isFlowDsl(i)?renderFlowDsl(e,i):function renderErDsl(e,i){const o=compileDsl(i),n=o.options||{},r=(new t.ICE).init(e),s=new t.EntityDesigner(r);o.entities.forEach(e=>{s.createEntity(e)}),function positionLinks(e,t,i){const o=new Map;return e.entities.forEach(e=>{o.set(e.state.id,e.getMinBoundingBox(!0))}),t.relations.map(e=>{const t=o.get(e.sourceId),n=o.get(e.targetId);let r="R",s="L";if(t&&n){const e=n.center[0]-t.center[0],i=n.center[1]-t.center[1];Math.abs(e)>Math.abs(i)?(r=e>=0?"R":"L",s=e>=0?"L":"R"):(r=i>=0?"B":"T",s=i>=0?"T":"B")}return{...e,routeType:e.routeType||i||"orthogonal",linkShape:e.linkShape||"visio",links:{start:{id:e.sourceId,position:r},end:{id:e.targetId,position:s}}}})}(s,o,n.routeType).forEach(e=>{s.createRelation(e)}),("layered"===o.layout||"horizontal"===o.layout)&&new t.ICELayeredLayout({gapX:n.gapX||120,gapY:n.gapY||50}).layoutContainer(r);n.viewport?r.setViewport(n.viewport.scale,n.viewport.tx,n.viewport.ty):n.fitViewport&&function fitViewport(e,t,i){const o=t.entities||[];let n=1/0,r=1/0,s=-1/0,a=-1/0;o.forEach(e=>{const t=e.getMinBoundingBox(!0).getMinAndMaxPoint();n=Math.min(n,t.minX),r=Math.min(r,t.minY),s=Math.max(s,t.maxX),a=Math.max(a,t.maxY)});const l=s-n,d=a-r,p=e.canvasWidth||0,h=e.canvasHeight||0;if(!p||!h||l<=0||d<=0)return;const c=Number.isFinite(i)&&i>=0?i:40,u=Math.max(1,p-2*c),f=Math.max(1,h-2*c),m=Math.min(u/l,f/d,1),g=(p-l*m)/2-n*m,y=(h-d*m)/2-r*m;e.setViewport(m,g,y)}(r,s,n.fitViewportPadding);return{kind:"entity",ice:r,designer:s}}(e,i)},e.renderFlowDsl=renderFlowDsl,e.renderUmlDsl=renderUmlDsl,e.validateBpmnDsl=validateBpmnDsl,e.validateDsl=validateDsl,e.validateFlowDsl=validateFlowDsl,e.validateUmlDsl=validateUmlDsl,Object.defineProperty(e,"__esModule",{value:!0})}));
1
+ !function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports,require("ice-entity-designer")):"function"==typeof define&&define.amd?define(["exports","ice-entity-designer"],t):t((e="undefined"!=typeof globalThis?globalThis:e||self).ICEDSL={},e.IED)}(this,(function(e,t){"use strict";function isFlowDsl(e){return!!e&&"object"==typeof e&&"flowchart"===e.kind}function isBpmnDsl(e){return!!e&&"object"==typeof e&&"bpmn"===e.kind}function isUmlDsl(e){return!!e&&"object"==typeof e&&"uml"===e.kind}function isStatechartDsl(e){return!!e&&"object"==typeof e&&"statechart"===e.kind}const i=["terminator","process","decision","io"],o=["T","R","B","L","C"],r=["pool","lane","task","event","gateway","subprocess","dataObject","annotation"],n=["start","intermediate","end"],s=["none","message","timer","error","terminate"],a=["exclusive","parallel","inclusive","event"],d=["none","user","service","script","send","receive","manual"],l=["sequence","message","association"],p=["initial","final","state","composite"],h=["class","interface","enum"],c=["inheritance","realization","association","aggregation","composition","dependency"];function validateDsl(e){return isStatechartDsl(e)?validateStatechartDsl(e):isUmlDsl(e)?validateUmlDsl(e):isBpmnDsl(e)?validateBpmnDsl(e):isFlowDsl(e)?validateFlowDsl(e):function validateErDsl(e){const t=[];if(!e||"object"!=typeof e||Array.isArray(e))return{valid:!1,errors:["DSL root must be an object"]};void 0!==e.schemaVersion&&1!==e.schemaVersion&&t.push("Unsupported schemaVersion: "+e.schemaVersion);if(Array.isArray(e.entities)){const i=new Set;e.entities.forEach((e,o)=>{const r=`entities[${o}]`;e&&"object"==typeof e?("string"==typeof e.id&&e.id.trim()?i.has(e.id)?t.push(`${r}.id is duplicated: ${e.id}`):i.add(e.id):t.push(r+".id must be a non-empty string"),Array.isArray(e.fields)?e.fields.forEach((e,i)=>{e&&"object"==typeof e&&"string"==typeof e.name&&e.name.trim()||t.push(`${r}.fields[${i}].name must be a non-empty string`)}):t.push(r+".fields must be an array")):t.push(r+" must be an object")})}else t.push("entities must be an array");void 0===e.relations||Array.isArray(e.relations)?(e.relations||[]).forEach((e,i)=>{const o=`relations[${i}]`;e&&"object"==typeof e?("string"==typeof e.source&&e.source.trim()||t.push(o+".source must be a non-empty string"),"string"==typeof e.target&&e.target.trim()||t.push(o+".target must be a non-empty string")):t.push(o+" must be an object")}):t.push("relations must be an array");return{valid:0===t.length,errors:t}}(e)}function validateBpmnDsl(e){const t=[];if(!e||"object"!=typeof e||Array.isArray(e))return{valid:!1,errors:["DSL root must be an object"]};void 0!==e.schemaVersion&&1!==e.schemaVersion&&t.push("Unsupported schemaVersion: "+e.schemaVersion);const i=new Set,o=new Map;return Array.isArray(e.nodes)?(e.nodes.forEach((e,l)=>{const p=`nodes[${l}]`;if(!e||"object"!=typeof e)return void t.push(p+" must be an object");"string"==typeof e.id&&e.id.trim()?i.has(e.id)?t.push(`${p}.id is duplicated: ${e.id}`):(i.add(e.id),o.set(e.id,e.kind||"task")):t.push(p+".id must be a non-empty string"),void 0!==e.kind&&-1===r.indexOf(e.kind)&&t.push(`${p}.kind must be one of ${r.join("/")}`),["left","top","width","height"].forEach(i=>{const o=e[i];void 0!==o&&"number"!=typeof o&&t.push(`${p}.${i} must be a number when present`)});[["eventKind",n],["trigger",s],["gatewayType",a],["taskType",d]].forEach(([i,o])=>{const r=e[i];void 0!==r&&-1===o.indexOf(r)&&t.push(`${p}.${i} must be one of ${o.join("/")}`)})}),e.nodes.forEach((e,r)=>{if(!e||"object"!=typeof e||void 0===e.parent)return;const n=`nodes[${r}]`;if("string"!=typeof e.parent||!e.parent.trim())return void t.push(n+".parent must be a non-empty string when present");if(!i.has(e.parent))return void t.push(n+".parent must reference an existing node id");if(e.parent===e.id)return void t.push(n+".parent must not reference itself");const s=o.get(e.parent);"pool"===e.kind?t.push(n+".parent is not allowed on a pool (池是最外层容器)"):"lane"===e.kind&&"pool"!==s?t.push(n+".parent must reference a pool"):"pool"!==s&&"lane"!==s&&t.push(n+".parent must reference a pool or a lane")})):t.push("nodes must be an array"),void 0===e.edges||Array.isArray(e.edges)?(e.edges||[]).forEach((e,o)=>{const r=`edges[${o}]`;if(!e||"object"!=typeof e)return void t.push(r+" must be an object");"string"==typeof e.source&&e.source.trim()&&i.has(e.source)||t.push(r+".source must reference an existing node id"),"string"==typeof e.target&&e.target.trim()&&i.has(e.target)||t.push(r+".target must reference an existing node id");const n=void 0!==e.type?e.type:e.flowType;void 0!==n&&-1===l.indexOf(n)&&t.push(`${r}.type must be one of ${l.join("/")}`),void 0!==e.label&&"string"!=typeof e.label&&t.push(r+".label must be a string when present"),void 0!==e.condition&&"string"!=typeof e.condition&&t.push(r+".condition must be a string when present"),void 0!==e.linkShape&&"visio"!==e.linkShape&&"bezier"!==e.linkShape&&t.push(r+'.linkShape must be "visio" or "bezier" when present')}):t.push("edges must be an array when present"),{valid:0===t.length,errors:t}}function validateFlowDsl(e){const t=[];if(!e||"object"!=typeof e||Array.isArray(e))return{valid:!1,errors:["DSL root must be an object"]};void 0!==e.schemaVersion&&1!==e.schemaVersion&&t.push("Unsupported schemaVersion: "+e.schemaVersion);const r=new Set;return Array.isArray(e.nodes)?e.nodes.forEach((e,o)=>{const n=`nodes[${o}]`;e&&"object"==typeof e?("string"==typeof e.id&&e.id.trim()?r.has(e.id)?t.push(`${n}.id is duplicated: ${e.id}`):r.add(e.id):t.push(n+".id must be a non-empty string"),void 0!==e.kind&&-1===i.indexOf(e.kind)&&t.push(`${n}.kind must be one of ${i.join("/")}`),["left","top","width","height"].forEach(i=>{const o=e[i];void 0!==o&&"number"!=typeof o&&t.push(`${n}.${i} must be a number when present`)})):t.push(n+" must be an object")}):t.push("nodes must be an array"),void 0===e.edges||Array.isArray(e.edges)?(e.edges||[]).forEach((e,i)=>{const n=`edges[${i}]`;e&&"object"==typeof e?("string"==typeof e.source&&e.source.trim()&&r.has(e.source)||t.push(n+".source must reference an existing node id"),"string"==typeof e.target&&e.target.trim()&&r.has(e.target)||t.push(n+".target must reference an existing node id"),void 0!==e.label&&"string"!=typeof e.label&&t.push(n+".label must be a string when present"),void 0!==e.sourcePort&&-1===o.indexOf(e.sourcePort)&&t.push(`${n}.sourcePort must be one of ${o.join("/")}`),void 0!==e.targetPort&&-1===o.indexOf(e.targetPort)&&t.push(`${n}.targetPort must be one of ${o.join("/")}`),void 0!==e.linkShape&&"visio"!==e.linkShape&&"bezier"!==e.linkShape&&t.push(n+'.linkShape must be "visio" or "bezier" when present')):t.push(n+" must be an object")}):t.push("edges must be an array when present"),{valid:0===t.length,errors:t}}function validateUmlDsl(e){const t=[];if(!e||"object"!=typeof e||Array.isArray(e))return{valid:!1,errors:["DSL root must be an object"]};void 0!==e.schemaVersion&&1!==e.schemaVersion&&t.push("Unsupported schemaVersion: "+e.schemaVersion);const i=new Set;return Array.isArray(e.nodes)?e.nodes.forEach((e,o)=>{const r=`nodes[${o}]`;e&&"object"==typeof e?("string"==typeof e.id&&e.id.trim()?i.has(e.id)?t.push(`${r}.id is duplicated: ${e.id}`):i.add(e.id):t.push(r+".id must be a non-empty string"),void 0!==e.kind&&-1===h.indexOf(e.kind)&&t.push(`${r}.kind must be one of ${h.join("/")}`),["attributes","methods"].forEach(i=>{const o=e[i];void 0!==o&&(Array.isArray(o)&&!o.some(e=>"string"!=typeof e)||t.push(`${r}.${i} must be an array of strings when present`))}),["left","top","width","height"].forEach(i=>{const o=e[i];void 0!==o&&"number"!=typeof o&&t.push(`${r}.${i} must be a number when present`)})):t.push(r+" must be an object")}):t.push("nodes must be an array"),void 0===e.edges||Array.isArray(e.edges)?(e.edges||[]).forEach((e,o)=>{const r=`edges[${o}]`;if(!e||"object"!=typeof e)return void t.push(r+" must be an object");"string"==typeof e.source&&e.source.trim()&&i.has(e.source)||t.push(r+".source must reference an existing node id"),"string"==typeof e.target&&e.target.trim()&&i.has(e.target)||t.push(r+".target must reference an existing node id");const n=void 0!==e.type?e.type:e.relation;void 0!==n&&-1===c.indexOf(n)&&t.push(`${r}.type must be one of ${c.join("/")}`),void 0!==e.label&&"string"!=typeof e.label&&t.push(r+".label must be a string when present")}):t.push("edges must be an array when present"),{valid:0===t.length,errors:t}}function validateStatechartDsl(e){const t=[];if(!e||"object"!=typeof e||Array.isArray(e))return{valid:!1,errors:["DSL root must be an object"]};void 0!==e.schemaVersion&&1!==e.schemaVersion&&t.push("Unsupported schemaVersion: "+e.schemaVersion);const i=new Set,o=new Map;return Array.isArray(e.nodes)?(e.nodes.forEach((e,r)=>{const n=`nodes[${r}]`;e&&"object"==typeof e?("string"==typeof e.id&&e.id.trim()?i.has(e.id)?t.push(`${n}.id is duplicated: ${e.id}`):(i.add(e.id),o.set(e.id,e.kind||"state")):t.push(n+".id must be a non-empty string"),void 0!==e.kind&&-1===p.indexOf(e.kind)&&t.push(`${n}.kind must be one of ${p.join("/")}`),["left","top","width","height"].forEach(i=>{const o=e[i];void 0!==o&&"number"!=typeof o&&t.push(`${n}.${i} must be a number when present`)})):t.push(n+" must be an object")}),e.nodes.forEach((e,r)=>{if(!e||"object"!=typeof e||void 0===e.parent)return;const n=`nodes[${r}]`;"string"==typeof e.parent&&e.parent.trim()&&i.has(e.parent)?e.parent!==e.id?"composite"!==o.get(e.parent)&&t.push(n+".parent must reference a composite state"):t.push(n+".parent must not reference itself"):t.push(n+".parent must reference an existing node id")})):t.push("nodes must be an array"),void 0===e.edges||Array.isArray(e.edges)?(e.edges||[]).forEach((e,o)=>{const r=`edges[${o}]`;e&&"object"==typeof e?("string"==typeof e.source&&e.source.trim()&&i.has(e.source)||t.push(r+".source must reference an existing node id"),"string"==typeof e.target&&e.target.trim()&&i.has(e.target)||t.push(r+".target must reference an existing node id"),["event","guard","action","label"].forEach(i=>{const o=e[i];void 0!==o&&"string"!=typeof o&&t.push(`${r}.${i} must be a string when present`)})):t.push(r+" must be an object")}):t.push("edges must be an array when present"),{valid:0===t.length,errors:t}}function entityName(e){return e.entityName||e.name||e.id}function relationType(e){return e.relationType||e.type||"one-to-many"}function compileDsl(e){if(isFlowDsl(e))throw new Error("compileDsl() 只处理 ER 文档;流程图文档请使用 compileFlowDsl()");if(!e||!Array.isArray(e.entities))throw new Error("ER 文档必须包含 entities 数组");return{entities:e.entities.map(e=>({id:e.id,entityName:entityName(e),fields:e.fields||[],left:e.left,top:e.top,width:e.width,height:e.height,style:e.style,headerStyle:e.headerStyle,fieldStyle:e.fieldStyle,dividerStyle:e.dividerStyle,draggable:e.draggable,interactive:e.interactive})),relations:(e.relations||[]).map((e,t)=>({id:e.id||"relation-"+t,relationType:relationType(e),sourceId:e.source,targetId:e.target,sourceField:e.sourceField||"id",targetField:e.targetField||"id",nullable:e.nullable,onDelete:e.onDelete,onUpdate:e.onUpdate,joinTableName:e.joinTableName,fromKey:e.fromKey,toKey:e.toKey,sourceCardinality:e.sourceCardinality,targetCardinality:e.targetCardinality,label:e.label,style:e.style,arrow:e.arrow,linkShape:e.linkShape,routeType:e.routeType,routeOffset:e.routeOffset,curveType:e.curveType,lineDash:e.lineDash})),layout:e.layout,options:e.options}}function layeredLayout(e,t,i={}){const o=Number(i.gapX)||90,r=Number(i.gapY)||90,n=void 0===i.originX?80:i.originX,s=void 0===i.originY?80:i.originY,a=new Map;if(!e.length)return a;const d=new Map;e.forEach(e=>d.set(e.id,e));const l=new Map,p=new Map;e.forEach(e=>{l.set(e.id,0),p.set(e.id,[])}),t.forEach(e=>{d.has(e.sourceId)&&d.has(e.targetId)&&(l.set(e.targetId,(l.get(e.targetId)||0)+1),p.get(e.sourceId).push(e.targetId))});const h=new Map,c=[];e.forEach(e=>{0===(l.get(e.id)||0)&&(h.set(e.id,0),c.push(e.id))}),c.length||(h.set(e[0].id,0),c.push(e[0].id));let u=e.length*e.length+e.length;for(;c.length&&u-- >0;){const e=c.shift(),t=h.get(e)||0;(p.get(e)||[]).forEach(e=>{const i=t+1;(void 0===h.get(e)?-1:h.get(e))<i&&(h.set(e,i),c.push(e))})}e.forEach(e=>{h.has(e.id)||h.set(e.id,0)});const f=new Map;e.forEach(e=>{const t=h.get(e.id)||0;f.has(t)||f.set(t,[]),f.get(t).push(e)});const m=[...f.keys()].sort((e,t)=>e-t);if("horizontal"===i.direction){const e=m.map(e=>Math.max(...f.get(e).map(e=>e.width)));let t=0;m.forEach((i,n)=>{const s=f.get(i);let d=-(s.reduce((e,t)=>e+t.height,0)+Math.max(s.length-1,0)*r)/2;s.forEach(i=>{a.set(i.id,{left:Math.round(t+(e[n]-i.width)/2),top:Math.round(d)}),d+=i.height+r}),t+=e[n]+o})}else{const e=m.map(e=>Math.max(...f.get(e).map(e=>e.height)));let t=0;m.forEach((i,n)=>{const s=f.get(i);let d=-(s.reduce((e,t)=>e+t.width,0)+Math.max(s.length-1,0)*o)/2;s.forEach(i=>{a.set(i.id,{left:Math.round(d),top:Math.round(t+(e[n]-i.height)/2)}),d+=i.width+o}),t+=e[n]+r})}const g=Math.min(...e.map(e=>a.get(e.id).left)),y=Math.min(...e.map(e=>a.get(e.id).top));return a.forEach(e=>{e.left+=n-g,e.top+=s-y}),a}const u={terminator:{width:t.FLOW_NODE_KINDS.terminator.width,height:t.FLOW_NODE_KINDS.terminator.height,fill:t.FLOW_NODE_KINDS.terminator.fill,stroke:t.FLOW_NODE_KINDS.terminator.stroke},process:{width:t.FLOW_NODE_KINDS.process.width,height:t.FLOW_NODE_KINDS.process.height,fill:t.FLOW_NODE_KINDS.process.fill,stroke:t.FLOW_NODE_KINDS.process.stroke},decision:{width:t.FLOW_NODE_KINDS.decision.width,height:t.FLOW_NODE_KINDS.decision.height,fill:t.FLOW_NODE_KINDS.decision.fill,stroke:t.FLOW_NODE_KINDS.decision.stroke},io:{width:t.FLOW_NODE_KINDS.io.width,height:t.FLOW_NODE_KINDS.io.height,fill:t.FLOW_NODE_KINDS.io.fill,stroke:t.FLOW_NODE_KINDS.io.stroke}};function compileFlowDsl(e){const t=e.options||{},i=(e.nodes||[]).map(e=>{const t=function nodeKind$1(e){return e.kind&&u[e.kind]?e.kind:"process"}(e),i=u[t];return{id:e.id,typeId:"FlowNode",kind:t,title:(o=e,o.title||o.name||o.id),left:"number"==typeof e.left?e.left:Number.NaN,top:"number"==typeof e.top?e.top:Number.NaN,width:"number"==typeof e.width?e.width:i.width,height:"number"==typeof e.height?e.height:i.height,fillColor:e.fillColor||i.fill,strokeColor:e.strokeColor||i.stroke};var o}),o=(e.edges||[]).map((e,t)=>({id:e.id||"edge-"+t,sourceId:e.source,targetId:e.target,sourcePort:e.sourcePort||"B",targetPort:e.targetPort||"T",label:e.label||"",linkShape:e.linkShape||"visio"})),r=t.layout||"layered";return"none"!==r&&i.some(e=>Number.isNaN(e.left)||Number.isNaN(e.top))&&(i.forEach(e=>{Number.isNaN(e.left)&&(e.left=0),Number.isNaN(e.top)&&(e.top=0)}),function autoLayout(e,t,i,o){const r=layeredLayout(e,t,{gapX:i,gapY:o});e.forEach(e=>{const t=r.get(e.id);t&&(e.left=t.left,e.top=t.top)})}(i,o,Number(t.gapX)||90,Number(t.gapY)||90)),i.forEach(e=>{Number.isNaN(e.left)&&(e.left=0),Number.isNaN(e.top)&&(e.top=0)}),{kind:"flowchart",nodes:i,edges:o,layout:r,options:t}}const f={pool:"bpmnPool",lane:"bpmnLane",task:"bpmnTask",event:"bpmnEvent",gateway:"bpmnGateway",subprocess:"bpmnSubprocess",dataObject:"bpmnDataObject",annotation:"bpmnAnnotation"},m=Number(t.FLOW_NODE_KINDS.bpmnPool.bandSize)||32,g=Number(t.FLOW_NODE_KINDS.bpmnLane.bandSize)||32,y=Number(t.FLOW_NODE_KINDS.bpmnLane.height)||130,b=Number(t.FLOW_NODE_KINDS.bpmnPool.width)||900;function toWorkingNode(e){const i=e.kind||"task",o=function presetOf(e){return t.FLOW_NODE_KINDS[e]||t.FLOW_NODE_KINDS.bpmnTask}(f[i]||"bpmnTask"),r={id:e.id,typeId:"FlowNode",kind:f[i]||"bpmnTask",title:e.title||e.name||e.id,left:"number"==typeof e.left?e.left:0,top:"number"==typeof e.top?e.top:0,width:"number"==typeof e.width?e.width:o.width,height:"number"==typeof e.height?e.height:o.height,fillColor:e.fillColor,strokeColor:e.strokeColor,dslKind:i,parent:e.parent,explicitLeft:"number"==typeof e.left,explicitTop:"number"==typeof e.top,explicitWidth:"number"==typeof e.width,explicitHeight:"number"==typeof e.height};return"event"===i&&(r.eventKind=e.eventKind||o.eventKind||"start",r.trigger=e.trigger||o.trigger||"none"),"gateway"===i&&(r.gatewayType=e.gatewayType||o.gatewayType||"exclusive"),"task"!==i&&"subprocess"!==i||(r.taskType=e.taskType||o.taskType||"none"),r}function buildGroups(e,t){const i=new Map;t.forEach(e=>i.set(e.id,e));const o=1===t.length?t[0]:null,r=[];return e.forEach(e=>{(e=>{let t=r.filter(t=>t.owner===e)[0];return t||(t={owner:e,nodes:[],box:null,didLayout:!1},r.push(t)),t})((e.parent?i.get(e.parent):void 0)||o).nodes.push(e)}),r}function layoutGroups(e,t,i,o){e.forEach(e=>{if(e.nodes.some(e=>!e.explicitLeft||!e.explicitTop)){const r=layeredLayout(e.nodes,t,{gapX:i,gapY:o,originX:0,originY:0,direction:"horizontal"});e.nodes.forEach(e=>{const t=r.get(e.id);t&&(e.left=t.left,e.top=t.top)}),e.didLayout=!0}e.box=function unionBox(e){if(!e.length)return null;let t=1/0,i=1/0,o=-1/0,r=-1/0;return e.forEach(e=>{t=Math.min(t,e.left),i=Math.min(i,e.top),o=Math.max(o,e.left+e.width),r=Math.max(r,e.top+e.height)}),{minX:t,minY:i,maxX:o,maxY:r}}(e.nodes)})}function compileBpmnDsl(e){const t=e.options||{},i=(e.nodes||[]).map(toWorkingNode),o=i.filter(e=>"pool"===e.dslKind),r=i.filter(e=>"lane"===e.dslKind),n=i.filter(e=>!function isContainer(e){return"pool"===e.dslKind||"lane"===e.dslKind}(e)),s=(e.edges||[]).map((e,t)=>({id:e.id||"edge-"+t,sourceId:e.source,targetId:e.target,flowType:e.type||e.flowType||"sequence",label:e.label||"",condition:e.condition||"",isDefault:!!e.isDefault,linkShape:e.linkShape||"visio"})),a=t.layout||"auto",d=function resolveLaneOwners(e,t){const i=new Map;return e.forEach(e=>{let o=e.parent;o||1!==t.length||(o=t[0].id),o&&i.set(e.id,o)}),i}(r,o),lanesOf=e=>r.filter(t=>d.get(t.id)===e);let l=[];"none"!==a&&(l=buildGroups(n,o.concat(r)),layoutGroups(l,s,Number(t.gapX)||90,Number(t.gapY)||60)),r.forEach(e=>{const t=l.filter(t=>t.owner===e)[0],i=t?t.box:null;e.explicitHeight||(e.height=Math.round(Math.max(56+(i?i.maxY-i.minY:0),y))),e.explicitWidth||(e.width=Math.round(Math.max((i?i.maxX-i.minX:0)+g+56,b)))}),o.forEach(e=>{const t=lanesOf(e.id);if(t.length){const i=t.reduce((e,t)=>Math.max(e,t.width),b);return e.explicitWidth||(e.width=i),e.explicitWidth&&t.forEach(t=>{t.explicitWidth||(t.width=e.width)}),void(e.explicitHeight||(e.height=m+t.reduce((e,t)=>e+t.height,0)))}const i=l.filter(t=>t.owner===e)[0],o=i?i.box:null;e.explicitWidth||(e.width=Math.round(Math.max(56+(o?o.maxX-o.minX:0),b))),e.explicitHeight||(e.height=Math.round(Math.max((o?o.maxY-o.minY:0)+m+56,160)))});let p=60;o.forEach(e=>{e.explicitLeft||(e.left=60),e.explicitTop||(e.top=p),p=Math.max(p,e.top+e.height+60)}),o.forEach(e=>{const t=lanesOf(e.id);if(!t.length)return;const i=e.top+m,o=Math.max(e.height-m,1),r=t.reduce((e,t)=>e+(t.explicitHeight?t.height:0),0),n=t.filter(e=>!e.explicitHeight),s=n.length?Math.max(o-r,0)/n.length:0;let a=i;t.forEach(t=>{t.explicitLeft||(t.left=e.left),t.explicitTop||(t.top=a),!t.explicitHeight&&e.explicitHeight&&(t.height=Math.round(s||y)),a=t.top+t.height})});let h=60;r.forEach(e=>{d.get(e.id)||(e.explicitLeft||(e.left=60),e.explicitTop||(e.top=h,h=e.top+e.height+60))}),l.forEach(e=>{const t=e.box;if(!t||!e.didLayout)return;const i=e.owner;let o=80,r=80;i&&(o=i.left+28,r=i.top+28,"pool"===i.dslKind?r+=m:o+=g),e.nodes.forEach(e=>{e.left=Math.round(o+(e.left-t.minX)),e.top=Math.round(r+(e.top-t.minY))})});return{kind:"bpmn",nodes:o.concat(r).concat(n).map(e=>{const t={id:e.id,typeId:"FlowNode",kind:e.kind,title:e.title,left:e.left,top:e.top,width:e.width,height:e.height};return void 0!==e.eventKind&&(t.eventKind=e.eventKind),void 0!==e.trigger&&(t.trigger=e.trigger),void 0!==e.gatewayType&&(t.gatewayType=e.gatewayType),void 0!==e.taskType&&(t.taskType=e.taskType),void 0!==e.fillColor&&(t.fillColor=e.fillColor),void 0!==e.strokeColor&&(t.strokeColor=e.strokeColor),t}),edges:s,layout:a,options:t}}function compileUmlDsl(e){const t=e.options||{},i=(e.nodes||[]).map(e=>{return{id:e.id,kind:(t=e,t.kind||"class"),className:e.title||e.name||e.id,abstract:!!e.abstract,attributes:Array.isArray(e.attributes)?e.attributes.map(e=>String(e)):[],methods:Array.isArray(e.methods)?e.methods.map(e=>String(e)):[],left:"number"==typeof e.left?e.left:Number.NaN,top:"number"==typeof e.top?e.top:Number.NaN,width:"number"==typeof e.width?e.width:240,height:"number"==typeof e.height?e.height:120+24*(e.attributes?e.attributes.length:0)+24*(e.methods?e.methods.length:0)};var t}),o=(e.edges||[]).map((e,t)=>({id:e.id||"relation-"+t,sourceId:e.source,targetId:e.target,relationKind:e.type||e.relation||"association",label:e.label||""})),r=t.layout||"layered";if("none"!==r&&i.some(e=>Number.isNaN(e.left)||Number.isNaN(e.top))){i.forEach(e=>{Number.isNaN(e.left)&&(e.left=0),Number.isNaN(e.top)&&(e.top=0)});const e=layeredLayout(i,o.filter(e=>"inheritance"===e.relationKind||"realization"===e.relationKind).map(e=>({sourceId:e.targetId,targetId:e.sourceId})),{gapX:Number(t.gapX)||80,gapY:Number(t.gapY)||110,originX:80,originY:80,direction:"vertical"});i.forEach(t=>{const i=e.get(t.id);i&&(t.left=i.left,t.top=i.top)})}return i.forEach(e=>{Number.isNaN(e.left)&&(e.left=0),Number.isNaN(e.top)&&(e.top=0)}),{kind:"uml",nodes:i,edges:o,layout:r,options:t}}const w={width:160,height:64},N={width:500,height:200};function compileStatechartDsl(e){const t=e.options||{},i=(e.nodes||[]).map(e=>{const t=e.kind||"state",i="initial"===t||"final"===t,o="composite"===t?N:i?{width:24,height:24}:w;return{id:e.id,kind:t,title:e.title||e.name||(i?"":e.id),parent:e.parent,left:"number"==typeof e.left?e.left:Number.NaN,top:"number"==typeof e.top?e.top:Number.NaN,width:"number"==typeof e.width?e.width:o.width,height:"number"==typeof e.height?e.height:o.height}}),o=(e.edges||[]).map((e,t)=>({id:e.id||"transition-"+t,sourceId:e.source,targetId:e.target,event:e.event||"",guard:e.guard||"",action:e.action||"",label:e.label})),r=t.layout||"auto",n=new Set;if("none"!==r){const e=new Map;i.forEach(t=>e.set(t.id,t));const r=i.filter(t=>!(t.parent&&e.has(t.parent)));if(r.some(e=>Number.isNaN(e.left)||Number.isNaN(e.top))){const containerOf=t=>{let i=e.get(t);for(;i&&i.parent&&e.has(i.parent);)i=e.get(i.parent);return i?i.id:t},i=o.map(e=>({sourceId:containerOf(e.sourceId),targetId:containerOf(e.targetId)})).filter(e=>e.sourceId!==e.targetId),n=layeredLayout(r,i,{gapX:Number(t.gapX)||110,gapY:Number(t.gapY)||80,originX:80,originY:80,direction:"horizontal"});r.forEach(e=>{const t=n.get(e.id);t&&(e.left=t.left,e.top=t.top)})}let s=0;i.filter(e=>"composite"===e.kind).forEach(e=>{const t=i.filter(t=>t.parent===e.id);if(Number.isNaN(e.left)&&(e.left=80),Number.isNaN(e.top)){const t=Math.max(...r.filter(t=>t!==e&&!Number.isNaN(t.top)).map(e=>e.top+e.height),0);e.top=Math.max(t+60,80)+s,s+=e.height+60}if(!t.length)return;let o=56,a=56,d=0,l=56;const p=e.width-112;t.forEach(e=>{(Number.isNaN(e.left)||Number.isNaN(e.top))&&(o>56&&o+e.width>56+p&&(o=56,a=l+40),n.add(e.id),e.left=o,e.top=a,o+=e.width+40,d=Math.max(d,o),l=Math.max(l,a+e.height))}),e.width=Math.max(e.width,d+56),e.height=Math.max(e.height,l+56)}),i.forEach(e=>{Number.isNaN(e.left)&&(e.left=0),Number.isNaN(e.top)&&(e.top=0)});const offsetChildren=(e,t,o)=>{i.filter(t=>t.parent===e.id).forEach(e=>{n.has(e.id)&&(e.left+=t,e.top+=o,offsetChildren(e,t,o))})};i.filter(e=>"composite"===e.kind).forEach(e=>offsetChildren(e,e.left,e.top))}return{kind:"statechart",nodes:i,edges:o,layout:r,options:t}}function renderStatechartDsl(e,i){const o=compileStatechartDsl(i),r=o.options||{},n=(new t.ICE).init(e),s=new t.StatechartDesigner(n);return o.nodes.forEach(e=>{s.createState({id:e.id,kind:e.kind,title:e.title,left:e.left,top:e.top,width:e.width,height:e.height})}),o.edges.forEach(e=>{s.createTransition(e)}),s.select(null),r.viewport?n.setViewport(r.viewport.scale,r.viewport.tx,r.viewport.ty):!1!==r.fitViewport&&s.fitViewport(r.fitViewportPadding),s.resetHistory(),{kind:"statechart",ice:n,designer:s}}function renderUmlDsl(e,i){const o=compileUmlDsl(i),r=o.options||{},n=(new t.ICE).init(e),s=new t.UmlDesigner(n);return o.nodes.forEach(e=>{s.createClass({id:e.id,kind:e.kind,className:e.className,abstract:e.abstract,attributes:e.attributes,methods:e.methods,left:e.left,top:e.top,width:e.width})}),o.edges.forEach(e=>{s.createRelation(e)}),s.select(null),r.viewport?n.setViewport(r.viewport.scale,r.viewport.tx,r.viewport.ty):!1!==r.fitViewport&&s.fitViewport(r.fitViewportPadding),s.resetHistory(),{kind:"uml",ice:n,designer:s}}function renderBpmnDsl(e,i){const o=compileBpmnDsl(i),r=o.options||{},n=(new t.ICE).init(e),s=new t.BpmnDesigner(n);return o.nodes.forEach(e=>{const t={id:e.id,title:e.title,left:e.left,top:e.top,width:e.width,height:e.height};["eventKind","trigger","gatewayType","taskType","fillColor","strokeColor"].forEach(i=>{void 0!==e[i]&&(t[i]=e[i])}),s.createNode(e.kind,t)}),o.edges.forEach(e=>{s.createEdge(e)}),s.select(null),r.viewport?n.setViewport(r.viewport.scale,r.viewport.tx,r.viewport.ty):!1!==r.fitViewport&&s.fitViewport(r.fitViewportPadding),s.resetHistory(),{kind:"bpmn",ice:n,designer:s}}function renderFlowDsl(e,i){const o=compileFlowDsl(i),r=o.options||{},n=(new t.ICE).init(e),s=new t.FlowDesigner(n);return o.nodes.forEach(e=>{s.createNode(e.kind,e)}),o.edges.forEach(e=>{s.createEdge(e)}),s.select(null),r.viewport?n.setViewport(r.viewport.scale,r.viewport.tx,r.viewport.ty):!1!==r.fitViewport&&s.fitViewport(r.fitViewportPadding),s.resetHistory(),{kind:"flowchart",ice:n,designer:s}}e.DSL_SCHEMA_VERSION=1,e.compileBpmnDsl=compileBpmnDsl,e.compileDsl=compileDsl,e.compileFlowDsl=compileFlowDsl,e.compileStatechartDsl=compileStatechartDsl,e.compileUmlDsl=compileUmlDsl,e.isBpmnDsl=isBpmnDsl,e.isFlowDsl=isFlowDsl,e.isStatechartDsl=isStatechartDsl,e.isUmlDsl=isUmlDsl,e.layeredLayout=layeredLayout,e.renderBpmnDsl=renderBpmnDsl,e.renderDsl=function renderDsl(e,i){const o=validateDsl(i);if(!o.valid)throw new Error(o.errors.join("\n"));return isStatechartDsl(i)?renderStatechartDsl(e,i):isUmlDsl(i)?renderUmlDsl(e,i):isBpmnDsl(i)?renderBpmnDsl(e,i):isFlowDsl(i)?renderFlowDsl(e,i):function renderErDsl(e,i){const o=compileDsl(i),r=o.options||{},n=(new t.ICE).init(e),s=new t.EntityDesigner(n);o.entities.forEach(e=>{s.createEntity(e)}),function positionLinks(e,t,i){const o=new Map;return e.entities.forEach(e=>{o.set(e.state.id,e.getMinBoundingBox(!0))}),t.relations.map(e=>{const t=o.get(e.sourceId),r=o.get(e.targetId);let n="R",s="L";if(t&&r){const e=r.center[0]-t.center[0],i=r.center[1]-t.center[1];Math.abs(e)>Math.abs(i)?(n=e>=0?"R":"L",s=e>=0?"L":"R"):(n=i>=0?"B":"T",s=i>=0?"T":"B")}return{...e,routeType:e.routeType||i||"orthogonal",linkShape:e.linkShape||"visio",links:{start:{id:e.sourceId,position:n},end:{id:e.targetId,position:s}}}})}(s,o,r.routeType).forEach(e=>{s.createRelation(e)}),("layered"===o.layout||"horizontal"===o.layout)&&new t.ICELayeredLayout({gapX:r.gapX||120,gapY:r.gapY||50}).layoutContainer(n);r.viewport?n.setViewport(r.viewport.scale,r.viewport.tx,r.viewport.ty):r.fitViewport&&function fitViewport(e,t,i){const o=t.entities||[];let r=1/0,n=1/0,s=-1/0,a=-1/0;o.forEach(e=>{const t=e.getMinBoundingBox(!0).getMinAndMaxPoint();r=Math.min(r,t.minX),n=Math.min(n,t.minY),s=Math.max(s,t.maxX),a=Math.max(a,t.maxY)});const d=s-r,l=a-n,p=e.canvasWidth||0,h=e.canvasHeight||0;if(!p||!h||d<=0||l<=0)return;const c=Number.isFinite(i)&&i>=0?i:40,u=Math.max(1,p-2*c),f=Math.max(1,h-2*c),m=Math.min(u/d,f/l,1),g=(p-d*m)/2-r*m,y=(h-l*m)/2-n*m;e.setViewport(m,g,y)}(n,s,r.fitViewportPadding);return{kind:"entity",ice:n,designer:s}}(e,i)},e.renderFlowDsl=renderFlowDsl,e.renderStatechartDsl=renderStatechartDsl,e.renderUmlDsl=renderUmlDsl,e.validateBpmnDsl=validateBpmnDsl,e.validateDsl=validateDsl,e.validateFlowDsl=validateFlowDsl,e.validateStatechartDsl=validateStatechartDsl,e.validateUmlDsl=validateUmlDsl,Object.defineProperty(e,"__esModule",{value:!0})}));
@@ -0,0 +1,37 @@
1
+ import type { DslStatechartDocument, DslStatechartNodeKind } from '../types';
2
+ export declare type CompiledStatechartNode = {
3
+ id: string;
4
+ kind: DslStatechartNodeKind;
5
+ title: string;
6
+ parent?: string;
7
+ left: number;
8
+ top: number;
9
+ width: number;
10
+ height: number;
11
+ };
12
+ export declare type CompiledStatechartEdge = {
13
+ id: string;
14
+ sourceId: string;
15
+ targetId: string;
16
+ event: string;
17
+ guard: string;
18
+ action: string;
19
+ label?: string;
20
+ };
21
+ export declare type CompiledStatechartScene = {
22
+ kind: 'statechart';
23
+ nodes: CompiledStatechartNode[];
24
+ edges: CompiledStatechartEdge[];
25
+ layout: string;
26
+ options?: Record<string, any>;
27
+ };
28
+ /**
29
+ * 状态机 DSL → `StateNode` / `StateTransition` 构造参数。
30
+ *
31
+ * 自动排布分两层(与 BPMN 的池/泳道同思路):
32
+ * 1. **根级节点**按转移流做横向分层(状态机读起来自左而右);
33
+ * 2. **子状态**留在所属复合状态里,按简单流式(左→右、超宽换行)落位,复合状态按内容自适应尺寸。
34
+ *
35
+ * 只要给了坐标(编辑器导出)编译过程就是恒等的。
36
+ */
37
+ export declare function compileStatechartDsl(dsl: DslStatechartDocument): CompiledStatechartScene;
@@ -1,5 +1,5 @@
1
1
  export * from './types';
2
- export { DSL_SCHEMA_VERSION, validateDsl, validateFlowDsl, validateBpmnDsl, validateUmlDsl } from './validate';
2
+ export { DSL_SCHEMA_VERSION, validateDsl, validateFlowDsl, validateBpmnDsl, validateUmlDsl, validateStatechartDsl, } from './validate';
3
3
  export { compileDsl } from './compiler/dslToScene';
4
4
  export type { CompiledScene } from './compiler/dslToScene';
5
5
  export { compileFlowDsl } from './compiler/flowToScene';
@@ -10,5 +10,7 @@ export { layeredLayout } from './compiler/layout';
10
10
  export type { LayoutItem, LayoutEdge, LayoutOptions } from './compiler/layout';
11
11
  export { compileUmlDsl } from './compiler/umlToScene';
12
12
  export type { CompiledUmlScene, CompiledUmlNode, CompiledUmlEdge } from './compiler/umlToScene';
13
- export { renderDsl, renderFlowDsl, renderBpmnDsl, renderUmlDsl } from './runtime/renderDsl';
14
- export type { RenderDslResult, RenderErDslResult, RenderFlowDslResult, RenderBpmnDslResult, RenderUmlDslResult, } from './runtime/renderDsl';
13
+ export { compileStatechartDsl } from './compiler/statechartToScene';
14
+ export type { CompiledStatechartScene, CompiledStatechartNode, CompiledStatechartEdge } from './compiler/statechartToScene';
15
+ export { renderDsl, renderFlowDsl, renderBpmnDsl, renderUmlDsl, renderStatechartDsl } from './runtime/renderDsl';
16
+ export type { RenderDslResult, RenderErDslResult, RenderFlowDslResult, RenderBpmnDslResult, RenderUmlDslResult, RenderStatechartDslResult, } from './runtime/renderDsl';
@@ -1,4 +1,4 @@
1
- import type { DslBpmnDocument, DslDocument, DslFlowDocument, DslUmlDocument } from '../types';
1
+ import type { DslBpmnDocument, DslDocument, DslFlowDocument, DslStatechartDocument, DslUmlDocument } from '../types';
2
2
  export declare type RenderErDslResult = {
3
3
  kind: 'entity';
4
4
  ice: any;
@@ -19,7 +19,12 @@ export declare type RenderUmlDslResult = {
19
19
  ice: any;
20
20
  designer: any;
21
21
  };
22
- export declare type RenderDslResult = RenderErDslResult | RenderFlowDslResult | RenderBpmnDslResult | RenderUmlDslResult;
22
+ export declare type RenderStatechartDslResult = {
23
+ kind: 'statechart';
24
+ ice: any;
25
+ designer: any;
26
+ };
27
+ export declare type RenderDslResult = RenderErDslResult | RenderFlowDslResult | RenderBpmnDslResult | RenderUmlDslResult | RenderStatechartDslResult;
23
28
  /**
24
29
  * 渲染一份 DSL 文档:ER 文档(entities/relations)或流程图文档(kind: 'flowchart')。
25
30
  *
@@ -27,6 +32,12 @@ export declare type RenderDslResult = RenderErDslResult | RenderFlowDslResult |
27
32
  * `designer` 分别是 `EntityDesigner` / `FlowDesigner` 实例。
28
33
  */
29
34
  export declare function renderDsl(canvasOrId: any, dsl: DslDocument): RenderDslResult;
35
+ /**
36
+ * 渲染状态机文档:伪状态 / 状态 / 复合状态(容器)+ 转移。
37
+ *
38
+ * 语义校验用 `designer.validateStatechart()`;矢量导出用 `designer.toSvg()`。
39
+ */
40
+ export declare function renderStatechartDsl(canvasOrId: any, dsl: DslStatechartDocument): RenderStatechartDslResult;
30
41
  /**
31
42
  * 渲染 UML 类图文档:类是复合组件(成员由 state 派生),关系是六种记法之一。
32
43
  *
@@ -189,8 +189,8 @@ export declare type DslBpmnDocument = {
189
189
  edges?: DslBpmnEdge[];
190
190
  options?: DslBpmnDocumentOptions;
191
191
  };
192
- /** 一份 DSL 文档:ER(默认)、流程图(kind: 'flowchart')、BPMN(kind: 'bpmn')或 UML(kind: 'uml') */
193
- export declare type DslDocument = DslErDocument | DslFlowDocument | DslBpmnDocument | DslUmlDocument;
192
+ /** 一份 DSL 文档:ER(默认)、流程图、BPMN、UML 状态机 */
193
+ export declare type DslDocument = DslErDocument | DslFlowDocument | DslBpmnDocument | DslUmlDocument | DslStatechartDocument;
194
194
  export declare type DslValidationResult = {
195
195
  valid: boolean;
196
196
  errors: string[];
@@ -252,3 +252,53 @@ export declare type DslUmlDocument = {
252
252
  };
253
253
  /** 运行时判别:带 kind: 'uml' 的按类图文档处理 */
254
254
  export declare function isUmlDsl(dsl: any): dsl is DslUmlDocument;
255
+ export declare type DslStatechartNodeKind = 'initial' | 'final' | 'state' | 'composite';
256
+ export declare type DslStatechartNode = {
257
+ id: string;
258
+ /** 节点类型,默认 state */
259
+ kind?: DslStatechartNodeKind;
260
+ /** 状态名(title / name 二者取一) */
261
+ title?: string;
262
+ name?: string;
263
+ /** 归属容器:子状态写所属复合状态的 id;缺省时按坐标自动嵌套 */
264
+ parent?: string;
265
+ left?: number;
266
+ top?: number;
267
+ width?: number;
268
+ height?: number;
269
+ };
270
+ export declare type DslStatechartEdge = {
271
+ id?: string;
272
+ source: string;
273
+ target: string;
274
+ /** 触发事件 */
275
+ event?: string;
276
+ /** 守卫条件(画成 `[guard]`) */
277
+ guard?: string;
278
+ /** 动作(画成 `/ action`) */
279
+ action?: string;
280
+ /** 显式标签(给了就不由 event/guard/action 拼) */
281
+ label?: string;
282
+ };
283
+ export declare type DslStatechartDocumentOptions = {
284
+ fitViewport?: boolean;
285
+ fitViewportPadding?: number;
286
+ viewport?: {
287
+ scale: number;
288
+ tx: number;
289
+ ty: number;
290
+ };
291
+ /** 缺坐标时是否自动排布(转移流向自左而右),默认 auto */
292
+ layout?: 'auto' | 'none';
293
+ gapX?: number;
294
+ gapY?: number;
295
+ };
296
+ export declare type DslStatechartDocument = {
297
+ schemaVersion?: number;
298
+ kind: 'statechart';
299
+ nodes: DslStatechartNode[];
300
+ edges?: DslStatechartEdge[];
301
+ options?: DslStatechartDocumentOptions;
302
+ };
303
+ /** 运行时判别:带 kind: 'statechart' 的按状态机文档处理 */
304
+ export declare function isStatechartDsl(dsl: any): dsl is DslStatechartDocument;
@@ -1,4 +1,4 @@
1
- import type { DslBpmnDocument, DslUmlDocument, DslDocument, DslFlowDocument, DslValidationResult } from './types';
1
+ import type { DslBpmnDocument, DslStatechartDocument, DslUmlDocument, DslDocument, DslFlowDocument, DslValidationResult } from './types';
2
2
  export declare const DSL_SCHEMA_VERSION = 1;
3
3
  /**
4
4
  * 校验一份 DSL 文档:ER(entities/relations)、流程图(kind: 'flowchart')
@@ -22,3 +22,8 @@ export declare function validateFlowDsl(dsl: DslFlowDocument): DslValidationResu
22
22
  * 结构在 DSL 侧、语义在设计师侧,不重复实现。
23
23
  */
24
24
  export declare function validateUmlDsl(dsl: DslUmlDocument): DslValidationResult;
25
+ /**
26
+ * 状态机文档校验:结构 + 词汇表 + 端点存在 + parent 合法性(子状态只能挂复合状态)。
27
+ * 语义检查(初始状态、终态出边、可达性)交给 `StatechartDesigner.validateStatechart()`。
28
+ */
29
+ export declare function validateStatechartDsl(dsl: DslStatechartDocument): DslValidationResult;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ice-entity-designer-dsl",
3
- "version": "0.0.9",
3
+ "version": "0.0.10",
4
4
  "description": "A JSON-first DSL layer for AI agents to drive ice-entity-designer.",
5
5
  "main": "dist/index.cjs",
6
6
  "module": "dist/index.mjs",
@@ -19,7 +19,7 @@
19
19
  "types:check": "tsc --noEmit"
20
20
  },
21
21
  "dependencies": {
22
- "ice-entity-designer": "^0.0.24"
22
+ "ice-entity-designer": "^0.0.25"
23
23
  },
24
24
  "devDependencies": {
25
25
  "@babel/core": "7.17.8",