@kekonic/diagrams-studio 1.0.0-rc.4

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.
Files changed (36) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +47 -0
  3. package/dist/browser/assets/SourceEditor-CTsSCxbb.js +23 -0
  4. package/dist/browser/assets/codicon-Brq4_Ui5.ttf +0 -0
  5. package/dist/browser/assets/dist-xSRpPWs-.js +49 -0
  6. package/dist/browser/assets/editor-CPgU7loC.css +1 -0
  7. package/dist/browser/assets/editor.api-Pc7YbpSQ.js +423 -0
  8. package/dist/browser/assets/editor.worker-r79G8Edd.js +30 -0
  9. package/dist/browser/assets/format-CEbYvQUd.css +1 -0
  10. package/dist/browser/assets/format-CX-V5tOl.js +425 -0
  11. package/dist/browser/assets/github-dark-C-LZuMrd.js +1 -0
  12. package/dist/browser/assets/github-light-EUqPIrTm.js +1 -0
  13. package/dist/browser/assets/ibm-plex-mono-latin-400-normal-CvHOgSBP.woff +0 -0
  14. package/dist/browser/assets/ibm-plex-mono-latin-400-normal-DMJ8VG8y.woff2 +0 -0
  15. package/dist/browser/assets/ibm-plex-mono-latin-500-normal-CB9ihrfo.woff +0 -0
  16. package/dist/browser/assets/ibm-plex-mono-latin-500-normal-DSY6xOcd.woff2 +0 -0
  17. package/dist/browser/assets/ibm-plex-sans-latin-400-normal-CDDApCn2.woff2 +0 -0
  18. package/dist/browser/assets/ibm-plex-sans-latin-400-normal-CYLoc0-x.woff +0 -0
  19. package/dist/browser/assets/ibm-plex-sans-latin-500-normal-6ng42L7E.woff2 +0 -0
  20. package/dist/browser/assets/ibm-plex-sans-latin-500-normal-BgVn5rGT.woff +0 -0
  21. package/dist/browser/assets/ibm-plex-sans-latin-600-normal-Cu4Hd6ag.woff +0 -0
  22. package/dist/browser/assets/ibm-plex-sans-latin-600-normal-CuJfVYMP.woff2 +0 -0
  23. package/dist/browser/assets/index-D15KDLkg.css +1 -0
  24. package/dist/browser/assets/index-D4UABSTV.js +3411 -0
  25. package/dist/browser/assets/inter-latin-500-normal-BL9OpVg8.woff +0 -0
  26. package/dist/browser/assets/inter-latin-500-normal-DIm8MnOp.js +1 -0
  27. package/dist/browser/assets/language-BHyJ3vcB.js +11 -0
  28. package/dist/browser/assets/monaco-features-DiflRtGt.css +1 -0
  29. package/dist/browser/assets/monaco-features-i8AvDstT.js +28 -0
  30. package/dist/browser/assets/wasm-BnjxR4X6.js +1 -0
  31. package/dist/browser/favicon.svg +8 -0
  32. package/dist/browser/index.html +17 -0
  33. package/dist/index.d.mts +173 -0
  34. package/dist/index.mjs +457 -0
  35. package/dist/index.mjs.map +1 -0
  36. package/package.json +72 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.mjs","names":[],"sources":["../src/protocol.ts","../src/preview.ts","../src/state.ts","../src/presentation.ts","../src/source-settings.ts"],"sourcesContent":["import type {\n Diagnostic,\n GraphModel,\n InteractiveRenderOptions,\n RenderStats,\n SourceRange,\n} from \"@kekonic/diagrams\";\n\nexport const STUDIO_PROTOCOL_VERSION = 1 as const;\n\nexport type StudioDocument = {\n id: string;\n path: string;\n label: string;\n revision: number;\n source: string;\n};\n\nexport type StudioCapabilities = {\n write: boolean;\n export: true;\n};\n\nexport type StudioSelection = {\n documentId: string;\n range?: SourceRange;\n graphElement?: { type: \"node\" | \"edge\"; id: string };\n};\n\nexport type StudioViewport = {\n zoom: number;\n x: number;\n y: number;\n};\n\nexport type StudioPresentation = {\n theme: \"dark\" | \"light\";\n options: InteractiveRenderOptions;\n};\n\nexport type StudioRender = {\n documentId: string;\n revision: number;\n ok: boolean;\n svg?: string;\n diagnostics: Diagnostic[];\n graph?: GraphModel;\n stats: RenderStats;\n};\n\nexport type StudioServerMessage =\n | {\n version: 1;\n type: \"ready\";\n sessionId: string;\n documents: StudioDocument[];\n activeDocumentId: string;\n capabilities: StudioCapabilities;\n presentation: StudioPresentation;\n }\n | ({ version: 1; type: \"document\"; reason: \"open\" | \"external\" | \"saved\" } & StudioDocument)\n | ({ version: 1; type: \"render\" } & StudioRender)\n | { version: 1; type: \"selection\"; selection: StudioSelection }\n | { version: 1; type: \"viewport\"; viewport: StudioViewport }\n | { version: 1; type: \"presentation\"; presentation: StudioPresentation }\n | { version: 1; type: \"saved\"; documentId: string; revision: number }\n | { version: 1; type: \"error\"; code: string; message: string; requestType?: string };\n\nexport type StudioClientMessage =\n | { version: 1; type: \"open\"; documentId: string }\n | { version: 1; type: \"source\"; documentId: string; revision: number; source: string }\n | { version: 1; type: \"save\"; documentId: string; revision: number; source: string }\n | { version: 1; type: \"selection\"; selection: StudioSelection }\n | { version: 1; type: \"viewport\"; viewport: StudioViewport }\n | { version: 1; type: \"presentation\"; presentation: StudioPresentation };\n\nexport function parseStudioClientMessage(value: unknown): StudioClientMessage {\n if (\n !isRecord(value) ||\n value.version !== STUDIO_PROTOCOL_VERSION ||\n typeof value.type !== \"string\"\n ) {\n throw new Error(\"Expected a version 1 studio message\");\n }\n switch (value.type) {\n case \"open\":\n return {\n version: 1,\n type: \"open\",\n documentId: requiredString(value.documentId, \"documentId\"),\n };\n case \"source\":\n case \"save\":\n return {\n version: 1,\n type: value.type,\n documentId: requiredString(value.documentId, \"documentId\"),\n revision: requiredRevision(value.revision),\n source: requiredString(value.source, \"source\", true),\n };\n case \"selection\":\n return { version: 1, type: \"selection\", selection: parseSelection(value.selection) };\n case \"viewport\":\n return { version: 1, type: \"viewport\", viewport: parseViewport(value.viewport) };\n case \"presentation\":\n return {\n version: 1,\n type: \"presentation\",\n presentation: parsePresentation(value.presentation),\n };\n default:\n throw new Error(`Unknown studio message type: ${value.type}`);\n }\n}\n\nexport function studioMessageJson(message: StudioServerMessage): string {\n return JSON.stringify(message);\n}\n\nfunction parseSelection(value: unknown): StudioSelection {\n if (!isRecord(value)) throw new Error(\"selection must be an object\");\n const selection: StudioSelection = {\n documentId: requiredString(value.documentId, \"selection.documentId\"),\n };\n if (value.range != null) selection.range = value.range as SourceRange;\n if (isRecord(value.graphElement)) {\n const type = value.graphElement.type;\n if (type !== \"node\" && type !== \"edge\") throw new Error(\"Invalid graph element type\");\n selection.graphElement = {\n type,\n id: requiredString(value.graphElement.id, \"selection.graphElement.id\"),\n };\n }\n return selection;\n}\n\nfunction parseViewport(value: unknown): StudioViewport {\n if (!isRecord(value)) throw new Error(\"viewport must be an object\");\n const zoom = requiredFinite(value.zoom, \"viewport.zoom\");\n if (zoom < 0.1 || zoom > 8) throw new Error(\"viewport.zoom must be between 0.1 and 8\");\n return {\n zoom,\n x: requiredFinite(value.x, \"viewport.x\"),\n y: requiredFinite(value.y, \"viewport.y\"),\n };\n}\n\nfunction parsePresentation(value: unknown): StudioPresentation {\n if (!isRecord(value) || (value.theme !== \"dark\" && value.theme !== \"light\")) {\n throw new Error(\"presentation.theme must be dark or light\");\n }\n if (!isRecord(value.options)) throw new Error(\"presentation.options must be an object\");\n return { theme: value.theme, options: value.options as InteractiveRenderOptions };\n}\n\nfunction requiredString(value: unknown, label: string, allowEmpty = false): string {\n if (typeof value !== \"string\" || (!allowEmpty && value.length === 0)) {\n throw new Error(`${label} must be a string`);\n }\n return value;\n}\n\nfunction requiredRevision(value: unknown): number {\n if (!Number.isSafeInteger(value) || (value as number) < 0) {\n throw new Error(\"revision must be a non-negative safe integer\");\n }\n return value as number;\n}\n\nfunction requiredFinite(value: unknown, label: string): number {\n if (typeof value !== \"number\" || !Number.isFinite(value))\n throw new Error(`${label} must be finite`);\n return value;\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return value != null && typeof value === \"object\" && !Array.isArray(value);\n}\n","import type { Diagnostic, InteractiveRenderOptions, RenderResult } from \"@kekonic/diagrams\";\nimport type { StudioRender } from \"./protocol.ts\";\n\nexport type StudioRenderer = (\n source: string,\n options: InteractiveRenderOptions,\n) => Promise<RenderResult>;\n\nexport type StudioPreviewCoordinator = {\n render(\n documentId: string,\n revision: number,\n source: string,\n options: InteractiveRenderOptions,\n ): Promise<StudioRender | undefined>;\n invalidate(documentId: string): void;\n};\n\n/**\n * Drops stale async renders so every host observes monotonically newer document results.\n * Rendering stays injected, keeping this coordinator browser-safe and renderer-neutral.\n */\nexport function createStudioPreviewCoordinator(renderer: StudioRenderer): StudioPreviewCoordinator {\n const generations = new Map<string, number>();\n return {\n async render(documentId, revision, source, options) {\n const generation = (generations.get(documentId) ?? 0) + 1;\n generations.set(documentId, generation);\n const result = await renderer(source, options);\n if (generations.get(documentId) !== generation) return undefined;\n return {\n documentId,\n revision,\n ok: result.ok,\n svg: result.svg,\n diagnostics: uniqueDiagnostics(result.diagnostics),\n graph: result.graph,\n stats: result.stats,\n };\n },\n invalidate(documentId) {\n generations.set(documentId, (generations.get(documentId) ?? 0) + 1);\n },\n };\n}\n\nfunction uniqueDiagnostics(diagnostics: readonly Diagnostic[]): Diagnostic[] {\n const seen = new Set<string>();\n return diagnostics.filter((diagnostic) => {\n const { start, end } = diagnostic.range;\n const key = `${diagnostic.code}:${diagnostic.severity}:${start.offset}:${end.offset}:${diagnostic.message}`;\n if (seen.has(key)) return false;\n seen.add(key);\n return true;\n });\n}\n","import type {\n StudioCapabilities,\n StudioDocument,\n StudioPresentation,\n StudioRender,\n StudioSelection,\n StudioServerMessage,\n StudioViewport,\n} from \"./protocol.ts\";\n\nexport type StudioState = {\n connected: boolean;\n sessionId?: string;\n documents: StudioDocument[];\n activeDocumentId?: string;\n capabilities: StudioCapabilities;\n presentation: StudioPresentation;\n render?: StudioRender;\n selection?: StudioSelection;\n viewport: StudioViewport;\n error?: { code: string; message: string };\n};\n\nexport const INITIAL_STUDIO_STATE: StudioState = {\n connected: false,\n documents: [],\n capabilities: { write: false, export: true },\n presentation: { theme: \"dark\", options: { theme: \"dark\" } },\n viewport: { zoom: 1, x: 0, y: 0 },\n};\n\nexport function reduceStudioMessage(state: StudioState, message: StudioServerMessage): StudioState {\n switch (message.type) {\n case \"ready\":\n return {\n ...state,\n connected: true,\n sessionId: message.sessionId,\n documents: message.documents,\n activeDocumentId: message.activeDocumentId,\n capabilities: message.capabilities,\n presentation: message.presentation,\n error: undefined,\n };\n case \"document\": {\n const documents = state.documents.some((item) => item.id === message.id)\n ? state.documents.map((item) =>\n item.id === message.id ? documentFromMessage(message) : item,\n )\n : [...state.documents, documentFromMessage(message)];\n return { ...state, documents, activeDocumentId: message.id, error: undefined };\n }\n case \"render\":\n if (message.documentId !== state.activeDocumentId) return state;\n if (state.render && message.revision < state.render.revision) return state;\n return { ...state, render: message };\n case \"selection\":\n return { ...state, selection: message.selection };\n case \"viewport\":\n return { ...state, viewport: message.viewport };\n case \"presentation\":\n return { ...state, presentation: message.presentation };\n case \"saved\":\n return state;\n case \"error\":\n return { ...state, error: { code: message.code, message: message.message } };\n }\n}\n\nfunction documentFromMessage(\n message: Extract<StudioServerMessage, { type: \"document\" }>,\n): StudioDocument {\n return {\n id: message.id,\n path: message.path,\n label: message.label,\n revision: message.revision,\n source: message.source,\n };\n}\n","import type { InteractiveRenderOptions, LayoutOptions, ThemeMode } from \"@kekonic/diagrams\";\n\nexport type StudioPresentationControls = {\n /** Diagram palette authored through `render.theme`. */\n theme: \"dark\" | \"light\";\n direction: \"\" | \"LR\" | \"RL\" | \"TD\" | \"BT\";\n density: \"\" | \"compact\" | \"normal\" | \"spacious\";\n spacingScale: number | null;\n nodePlacement: \"\" | \"straight\" | \"balanced\" | \"basic\";\n groupLayout: \"\" | \"auto\" | \"compound\" | \"flat\" | \"swimlane\";\n modelOrder: \"\" | \"on\" | \"off\";\n groupGap: \"\" | \"40\" | \"90\" | \"170\";\n edgeGaps: \"\" | \"tight\" | \"normal\" | \"wide\";\n edgeStyle: \"\" | \"metro\" | \"rounded\" | \"orthogonal\" | \"straight\" | \"bezier\";\n crossings: \"\" | \"jumps\" | \"smart\" | \"gaps\" | \"none\";\n roundedCorners: boolean;\n showPorts: boolean;\n showBounds: boolean;\n};\n\nexport const DEFAULT_STUDIO_PRESENTATION: StudioPresentationControls = {\n theme: \"dark\",\n direction: \"\",\n density: \"\",\n spacingScale: null,\n nodePlacement: \"\",\n groupLayout: \"\",\n modelOrder: \"\",\n groupGap: \"\",\n edgeGaps: \"\",\n edgeStyle: \"\",\n crossings: \"\",\n roundedCorners: false,\n showPorts: false,\n showBounds: false,\n};\n\nconst EDGE_GAP_PRESETS = {\n tight: { edgeNodeSpacing: 28, edgeEdgeSpacing: 14, edgeLabelSpacing: 10 },\n normal: { edgeNodeSpacing: 36, edgeEdgeSpacing: 28, edgeLabelSpacing: 16 },\n wide: { edgeNodeSpacing: 72, edgeEdgeSpacing: 56, edgeLabelSpacing: 28 },\n} as const;\n\nexport function buildStudioRenderOptions(\n options: StudioPresentationControls,\n diagramTheme: ThemeMode = options.theme,\n): InteractiveRenderOptions {\n const layout: LayoutOptions = {};\n if (options.spacingScale != null) layout.spacingScale = options.spacingScale;\n if (options.density) layout.density = options.density;\n if (options.direction) layout.direction = options.direction;\n if (options.nodePlacement) layout.nodePlacement = options.nodePlacement;\n if (options.groupLayout) layout.groupLayout = options.groupLayout;\n if (options.modelOrder === \"on\") layout.considerModelOrder = true;\n if (options.modelOrder === \"off\") layout.considerModelOrder = false;\n if (options.groupGap) layout.groupGap = Number(options.groupGap);\n if (options.edgeGaps) Object.assign(layout, EDGE_GAP_PRESETS[options.edgeGaps]);\n\n const edges: InteractiveRenderOptions[\"edges\"] = {};\n if (options.edgeStyle) edges.route = options.edgeStyle;\n if (options.crossings) edges.crossings = options.crossings;\n return {\n theme: diagramTheme,\n layout,\n edges,\n ...(options.roundedCorners ? { roundedCorners: true } : {}),\n debug: { showPorts: options.showPorts, showBounds: options.showBounds },\n };\n}\n","import {\n parse,\n type DiagramAst,\n type PropertyMap,\n type PropertyValue,\n type StatementAst,\n} from \"@kekonic/diagrams-core\";\nimport type { StudioPresentationControls } from \"./presentation.ts\";\n\nexport type StudioSourceSetting =\n | \"theme\"\n | \"direction\"\n | \"density\"\n | \"groupLayout\"\n | \"edgeStyle\"\n | \"crossings\";\n\nexport type StudioSourceSettings = Pick<StudioPresentationControls, StudioSourceSetting>;\n\nconst EMPTY_SETTINGS: StudioSourceSettings = {\n theme: \"dark\",\n direction: \"\",\n density: \"\",\n groupLayout: \"\",\n edgeStyle: \"\",\n crossings: \"\",\n};\n\nexport function readStudioSourceSettings(source: string): StudioSourceSettings {\n const diagram = firstDiagram(source);\n if (!diagram) return { ...EMPTY_SETTINGS };\n const result = { ...EMPTY_SETTINGS };\n for (const statement of diagram.statements) {\n if (statement.type === \"Directive\" && statement.name === \"direction\") {\n result.direction = oneOf(String(statement.value ?? \"\"), [\"LR\", \"RL\", \"TD\", \"BT\"]);\n } else if (statement.type === \"Directive\" && statement.name === \"density\") {\n result.density = oneOf(String(statement.value ?? \"\"), [\"compact\", \"normal\", \"spacious\"]);\n } else if (statement.type === \"LayoutBlock\") {\n const direction = stringProperty(statement.properties, \"direction\");\n const density = stringProperty(statement.properties, \"density\");\n if (direction) result.direction = oneOf(direction, [\"LR\", \"RL\", \"TD\", \"BT\"]);\n if (density) result.density = oneOf(density, [\"compact\", \"normal\", \"spacious\"]);\n const groupLayout = stringProperty(statement.properties, \"groupLayout\");\n if (groupLayout) {\n result.groupLayout = oneOf(groupLayout, [\"auto\", \"compound\", \"flat\", \"swimlane\"]);\n }\n } else if (statement.type === \"EdgePolicyBlock\") {\n const edgeStyle = stringProperty(statement.properties, \"route\");\n const crossings = stringProperty(statement.properties, \"crossings\");\n if (edgeStyle) {\n result.edgeStyle = oneOf(edgeStyle, [\n \"metro\",\n \"rounded\",\n \"orthogonal\",\n \"straight\",\n \"bezier\",\n ]);\n }\n if (crossings) result.crossings = oneOf(crossings, [\"jumps\", \"smart\", \"gaps\", \"none\"]);\n } else if (statement.type === \"RenderBlock\") {\n result.theme =\n oneOf(String(statement.properties.theme ?? \"dark\"), [\"dark\", \"light\"]) || \"dark\";\n }\n }\n return result;\n}\n\n/** Apply one end-user diagram setting as a minimal source edit. Empty values remove the setting. */\nexport function updateStudioSourceSetting(\n source: string,\n setting: StudioSourceSetting,\n value: string,\n): string {\n const diagram = firstDiagram(source);\n if (!diagram) return source;\n if (setting === \"direction\" || setting === \"density\") {\n const layout = diagram.statements.find((item) => item.type === \"LayoutBlock\");\n if (value && layout?.properties[setting] != null) {\n return updateBlock(source, diagram, \"LayoutBlock\", \"layout\", setting, value);\n }\n const withoutDirective = updateDirective(source, diagram, setting, value);\n if (value) return withoutDirective;\n const reparsed = firstDiagram(withoutDirective);\n return reparsed\n ? updateBlock(withoutDirective, reparsed, \"LayoutBlock\", \"layout\", setting, \"\")\n : withoutDirective;\n }\n if (setting === \"groupLayout\") {\n return updateBlock(source, diagram, \"LayoutBlock\", \"layout\", \"groupLayout\", value);\n }\n if (setting === \"theme\") {\n return updateBlock(source, diagram, \"RenderBlock\", \"render\", \"theme\", value);\n }\n return updateBlock(\n source,\n diagram,\n \"EdgePolicyBlock\",\n \"edges\",\n setting === \"edgeStyle\" ? \"route\" : \"crossings\",\n value,\n );\n}\n\nexport function resetStudioSourceSettings(source: string): string {\n return (Object.keys(EMPTY_SETTINGS) as StudioSourceSetting[]).reduce(\n (current, setting) => updateStudioSourceSetting(current, setting, \"\"),\n source,\n );\n}\n\nfunction firstDiagram(source: string): DiagramAst | null {\n const first = parse(source).body[0];\n return first?.type === \"Diagram\" ? first : null;\n}\n\nfunction updateDirective(\n source: string,\n diagram: DiagramAst,\n name: \"direction\" | \"density\",\n value: string,\n): string {\n const statement = diagram.statements.find(\n (item): item is Extract<StatementAst, { type: \"Directive\" }> =>\n item.type === \"Directive\" && item.name === name,\n );\n if (statement) {\n if (!value) return removePolicyStatement(source, diagram, statement);\n return replaceRange(\n source,\n statement.range.start.offset,\n statement.range.end.offset,\n `${name} ${value}`,\n );\n }\n return value\n ? insertPolicyStatement(source, diagram, `${name} ${value}`, policyRank(name))\n : source;\n}\n\nfunction updateBlock(\n source: string,\n diagram: DiagramAst,\n type: \"LayoutBlock\" | \"EdgePolicyBlock\" | \"RenderBlock\",\n keyword: \"layout\" | \"edges\" | \"render\",\n property: string,\n value: string,\n): string {\n const block = diagram.statements.find((item) => item.type === type) as\n | Extract<StatementAst, { type: \"LayoutBlock\" | \"EdgePolicyBlock\" | \"RenderBlock\" }>\n | undefined;\n if (!block) {\n return value\n ? insertPolicyStatement(\n source,\n diagram,\n printBlock(keyword, { [property]: value }),\n policyRank(keyword),\n )\n : source;\n }\n const blockSource = source.slice(block.range.start.offset, block.range.end.offset);\n const openingBrace = blockSource.indexOf(\"{\");\n const closingBrace = blockSource.lastIndexOf(\"}\");\n const body = blockSource.slice(openingBrace + 1, closingBrace);\n if (!body.includes(\"\\n\")) {\n const properties: PropertyMap = { ...block.properties };\n if (value) properties[property] = value;\n else delete properties[property];\n if (Object.keys(properties).length === 0) return removePolicyStatement(source, diagram, block);\n return replaceRange(\n source,\n block.range.start.offset,\n block.range.end.offset,\n printBlock(keyword, properties),\n );\n }\n const propertyLine = new RegExp(\n `^([\\\\t ]*${escapeRegex(property)}[\\\\t ]*:[\\\\t ]*)(.*?)([\\\\t ]*//.*)?$`,\n \"m\",\n );\n const match = propertyLine.exec(blockSource);\n if (match) {\n const updatedBlock = value\n ? blockSource.replace(propertyLine, `$1${value}$3`)\n : removeMatchedLine(blockSource, match.index, match[0].length);\n const updatedBody = updatedBlock.slice(\n updatedBlock.indexOf(\"{\") + 1,\n updatedBlock.lastIndexOf(\"}\"),\n );\n if (!updatedBody.trim()) return removePolicyStatement(source, diagram, block);\n return replaceRange(source, block.range.start.offset, block.range.end.offset, updatedBlock);\n }\n if (!value) return source;\n const indent = indentationAt(source, block.range.start.offset);\n const addition = `${indent} ${property}: ${value}\\n`;\n const updatedBlock = `${blockSource.slice(0, closingBrace)}${addition}${blockSource.slice(closingBrace)}`;\n return replaceRange(source, block.range.start.offset, block.range.end.offset, updatedBlock);\n}\n\nfunction printBlock(keyword: string, properties: PropertyMap, indent = \"\"): string {\n const lines = Object.entries(properties).map(\n ([key, value]) => `${indent} ${key}: ${printValue(value)}`,\n );\n return `${keyword} {\\n${lines.join(\"\\n\")}\\n${indent}}`;\n}\n\nfunction insertPolicyStatement(\n source: string,\n diagram: DiagramAst,\n statement: string,\n rank: number,\n): string {\n const indent = `${indentationAt(source, diagram.range.start.offset)} `;\n const rendered = statement\n .split(\"\\n\")\n .map((line) => `${indent}${line}`)\n .join(\"\\n\");\n const target = diagram.statements.find((item) => policyRank(item) > rank);\n if (target) {\n const insertionOffset = source.lastIndexOf(\"\\n\", target.range.start.offset - 1) + 1;\n const separatesContent = policyRank(target) === Number.POSITIVE_INFINITY;\n return `${source.slice(0, insertionOffset)}${rendered}\\n${separatesContent ? \"\\n\" : \"\"}${source.slice(insertionOffset)}`;\n }\n\n const closingBrace = source.lastIndexOf(\"}\", diagram.range.end.offset);\n if (closingBrace < 0) return source;\n return `${source.slice(0, closingBrace)}${rendered}\\n${source.slice(closingBrace)}`;\n}\n\nfunction policyRank(\n value: StatementAst | \"direction\" | \"density\" | \"layout\" | \"edges\" | \"render\",\n): number {\n const name =\n typeof value === \"string\"\n ? value\n : value.type === \"Directive\"\n ? value.name\n : value.type === \"LayoutBlock\"\n ? \"layout\"\n : value.type === \"EdgePolicyBlock\"\n ? \"edges\"\n : value.type === \"RenderBlock\"\n ? \"render\"\n : value.type === \"PresentationBlock\"\n ? \"presentation\"\n : \"content\";\n const order = [\"direction\", \"density\", \"layout\", \"edges\", \"render\", \"presentation\"];\n return order.indexOf(name) === -1 ? Number.POSITIVE_INFINITY : order.indexOf(name);\n}\n\nfunction removeStatementLine(source: string, statement: StatementAst): string {\n const start = source.lastIndexOf(\"\\n\", statement.range.start.offset - 1) + 1;\n const nextNewline = source.indexOf(\"\\n\", statement.range.end.offset);\n const end = nextNewline < 0 ? statement.range.end.offset : nextNewline + 1;\n return replaceRange(source, start, end, \"\");\n}\n\nfunction removePolicyStatement(\n source: string,\n diagram: DiagramAst,\n statement: StatementAst,\n): string {\n const updated = removeStatementLine(source, statement);\n const hasOtherPolicy = diagram.statements.some(\n (item) => item !== statement && policyRank(item) < Number.POSITIVE_INFINITY,\n );\n if (hasOtherPolicy) return updated;\n\n const firstStatement = firstDiagram(updated)?.statements[0];\n if (!firstStatement) return updated;\n const lineStart = updated.lastIndexOf(\"\\n\", firstStatement.range.start.offset - 1) + 1;\n const preceding = updated.slice(0, lineStart);\n return preceding.endsWith(\"\\n\\n\")\n ? `${preceding.slice(0, -1)}${updated.slice(lineStart)}`\n : updated;\n}\n\nfunction indentationAt(source: string, offset: number): string {\n const lineStart = source.lastIndexOf(\"\\n\", offset - 1) + 1;\n return /^\\s*/.exec(source.slice(lineStart, offset))?.[0] ?? \"\";\n}\n\nfunction replaceRange(source: string, start: number, end: number, replacement: string): string {\n return `${source.slice(0, start)}${replacement}${source.slice(end)}`;\n}\n\nfunction stringProperty(properties: PropertyMap, name: string): string {\n const value = properties[name];\n return typeof value === \"string\" ? value : \"\";\n}\n\nfunction printValue(value: PropertyValue): string {\n return Array.isArray(value) ? `[${value.join(\", \")}]` : String(value);\n}\n\nfunction removeMatchedLine(source: string, start: number, length: number): string {\n const lineStart = source.lastIndexOf(\"\\n\", start - 1) + 1;\n const nextNewline = source.indexOf(\"\\n\", start + length);\n const lineEnd = nextNewline < 0 ? start + length : nextNewline + 1;\n return `${source.slice(0, lineStart)}${source.slice(lineEnd)}`;\n}\n\nfunction escapeRegex(value: string): string {\n return value.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n}\n\nfunction oneOf<const Value extends string>(value: string, allowed: readonly Value[]): Value | \"\" {\n return allowed.includes(value as Value) ? (value as Value) : \"\";\n}\n"],"mappings":";;AAQA,MAAa,0BAA0B;AAoEvC,SAAgB,yBAAyB,OAAqC;CAC5E,IACE,CAAC,SAAS,KAAK,KACf,MAAM,YAAA,KACN,OAAO,MAAM,SAAS,UAEtB,MAAM,IAAI,MAAM,qCAAqC;CAEvD,QAAQ,MAAM,MAAd;EACE,KAAK,QACH,OAAO;GACL,SAAS;GACT,MAAM;GACN,YAAY,eAAe,MAAM,YAAY,YAAY;EAC3D;EACF,KAAK;EACL,KAAK,QACH,OAAO;GACL,SAAS;GACT,MAAM,MAAM;GACZ,YAAY,eAAe,MAAM,YAAY,YAAY;GACzD,UAAU,iBAAiB,MAAM,QAAQ;GACzC,QAAQ,eAAe,MAAM,QAAQ,UAAU,IAAI;EACrD;EACF,KAAK,aACH,OAAO;GAAE,SAAS;GAAG,MAAM;GAAa,WAAW,eAAe,MAAM,SAAS;EAAE;EACrF,KAAK,YACH,OAAO;GAAE,SAAS;GAAG,MAAM;GAAY,UAAU,cAAc,MAAM,QAAQ;EAAE;EACjF,KAAK,gBACH,OAAO;GACL,SAAS;GACT,MAAM;GACN,cAAc,kBAAkB,MAAM,YAAY;EACpD;EACF,SACE,MAAM,IAAI,MAAM,gCAAgC,MAAM,MAAM;CAChE;AACF;AAEA,SAAgB,kBAAkB,SAAsC;CACtE,OAAO,KAAK,UAAU,OAAO;AAC/B;AAEA,SAAS,eAAe,OAAiC;CACvD,IAAI,CAAC,SAAS,KAAK,GAAG,MAAM,IAAI,MAAM,6BAA6B;CACnE,MAAM,YAA6B,EACjC,YAAY,eAAe,MAAM,YAAY,sBAAsB,EACrE;CACA,IAAI,MAAM,SAAS,MAAM,UAAU,QAAQ,MAAM;CACjD,IAAI,SAAS,MAAM,YAAY,GAAG;EAChC,MAAM,OAAO,MAAM,aAAa;EAChC,IAAI,SAAS,UAAU,SAAS,QAAQ,MAAM,IAAI,MAAM,4BAA4B;EACpF,UAAU,eAAe;GACvB;GACA,IAAI,eAAe,MAAM,aAAa,IAAI,2BAA2B;EACvE;CACF;CACA,OAAO;AACT;AAEA,SAAS,cAAc,OAAgC;CACrD,IAAI,CAAC,SAAS,KAAK,GAAG,MAAM,IAAI,MAAM,4BAA4B;CAClE,MAAM,OAAO,eAAe,MAAM,MAAM,eAAe;CACvD,IAAI,OAAO,MAAO,OAAO,GAAG,MAAM,IAAI,MAAM,yCAAyC;CACrF,OAAO;EACL;EACA,GAAG,eAAe,MAAM,GAAG,YAAY;EACvC,GAAG,eAAe,MAAM,GAAG,YAAY;CACzC;AACF;AAEA,SAAS,kBAAkB,OAAoC;CAC7D,IAAI,CAAC,SAAS,KAAK,KAAM,MAAM,UAAU,UAAU,MAAM,UAAU,SACjE,MAAM,IAAI,MAAM,0CAA0C;CAE5D,IAAI,CAAC,SAAS,MAAM,OAAO,GAAG,MAAM,IAAI,MAAM,wCAAwC;CACtF,OAAO;EAAE,OAAO,MAAM;EAAO,SAAS,MAAM;CAAoC;AAClF;AAEA,SAAS,eAAe,OAAgB,OAAe,aAAa,OAAe;CACjF,IAAI,OAAO,UAAU,YAAa,CAAC,cAAc,MAAM,WAAW,GAChE,MAAM,IAAI,MAAM,GAAG,MAAM,kBAAkB;CAE7C,OAAO;AACT;AAEA,SAAS,iBAAiB,OAAwB;CAChD,IAAI,CAAC,OAAO,cAAc,KAAK,KAAM,QAAmB,GACtD,MAAM,IAAI,MAAM,8CAA8C;CAEhE,OAAO;AACT;AAEA,SAAS,eAAe,OAAgB,OAAuB;CAC7D,IAAI,OAAO,UAAU,YAAY,CAAC,OAAO,SAAS,KAAK,GACrD,MAAM,IAAI,MAAM,GAAG,MAAM,gBAAgB;CAC3C,OAAO;AACT;AAEA,SAAS,SAAS,OAAkD;CAClE,OAAO,SAAS,QAAQ,OAAO,UAAU,YAAY,CAAC,MAAM,QAAQ,KAAK;AAC3E;;;;;;;AC3JA,SAAgB,+BAA+B,UAAoD;CACjG,MAAM,8BAAc,IAAI,IAAoB;CAC5C,OAAO;EACL,MAAM,OAAO,YAAY,UAAU,QAAQ,SAAS;GAClD,MAAM,cAAc,YAAY,IAAI,UAAU,KAAK,KAAK;GACxD,YAAY,IAAI,YAAY,UAAU;GACtC,MAAM,SAAS,MAAM,SAAS,QAAQ,OAAO;GAC7C,IAAI,YAAY,IAAI,UAAU,MAAM,YAAY,OAAO,KAAA;GACvD,OAAO;IACL;IACA;IACA,IAAI,OAAO;IACX,KAAK,OAAO;IACZ,aAAa,kBAAkB,OAAO,WAAW;IACjD,OAAO,OAAO;IACd,OAAO,OAAO;GAChB;EACF;EACA,WAAW,YAAY;GACrB,YAAY,IAAI,aAAa,YAAY,IAAI,UAAU,KAAK,KAAK,CAAC;EACpE;CACF;AACF;AAEA,SAAS,kBAAkB,aAAkD;CAC3E,MAAM,uBAAO,IAAI,IAAY;CAC7B,OAAO,YAAY,QAAQ,eAAe;EACxC,MAAM,EAAE,OAAO,QAAQ,WAAW;EAClC,MAAM,MAAM,GAAG,WAAW,KAAK,GAAG,WAAW,SAAS,GAAG,MAAM,OAAO,GAAG,IAAI,OAAO,GAAG,WAAW;EAClG,IAAI,KAAK,IAAI,GAAG,GAAG,OAAO;EAC1B,KAAK,IAAI,GAAG;EACZ,OAAO;CACT,CAAC;AACH;;;AChCA,MAAa,uBAAoC;CAC/C,WAAW;CACX,WAAW,CAAC;CACZ,cAAc;EAAE,OAAO;EAAO,QAAQ;CAAK;CAC3C,cAAc;EAAE,OAAO;EAAQ,SAAS,EAAE,OAAO,OAAO;CAAE;CAC1D,UAAU;EAAE,MAAM;EAAG,GAAG;EAAG,GAAG;CAAE;AAClC;AAEA,SAAgB,oBAAoB,OAAoB,SAA2C;CACjG,QAAQ,QAAQ,MAAhB;EACE,KAAK,SACH,OAAO;GACL,GAAG;GACH,WAAW;GACX,WAAW,QAAQ;GACnB,WAAW,QAAQ;GACnB,kBAAkB,QAAQ;GAC1B,cAAc,QAAQ;GACtB,cAAc,QAAQ;GACtB,OAAO,KAAA;EACT;EACF,KAAK,YAAY;GACf,MAAM,YAAY,MAAM,UAAU,MAAM,SAAS,KAAK,OAAO,QAAQ,EAAE,IACnE,MAAM,UAAU,KAAK,SACnB,KAAK,OAAO,QAAQ,KAAK,oBAAoB,OAAO,IAAI,IAC1D,IACA,CAAC,GAAG,MAAM,WAAW,oBAAoB,OAAO,CAAC;GACrD,OAAO;IAAE,GAAG;IAAO;IAAW,kBAAkB,QAAQ;IAAI,OAAO,KAAA;GAAU;EAC/E;EACA,KAAK;GACH,IAAI,QAAQ,eAAe,MAAM,kBAAkB,OAAO;GAC1D,IAAI,MAAM,UAAU,QAAQ,WAAW,MAAM,OAAO,UAAU,OAAO;GACrE,OAAO;IAAE,GAAG;IAAO,QAAQ;GAAQ;EACrC,KAAK,aACH,OAAO;GAAE,GAAG;GAAO,WAAW,QAAQ;EAAU;EAClD,KAAK,YACH,OAAO;GAAE,GAAG;GAAO,UAAU,QAAQ;EAAS;EAChD,KAAK,gBACH,OAAO;GAAE,GAAG;GAAO,cAAc,QAAQ;EAAa;EACxD,KAAK,SACH,OAAO;EACT,KAAK,SACH,OAAO;GAAE,GAAG;GAAO,OAAO;IAAE,MAAM,QAAQ;IAAM,SAAS,QAAQ;GAAQ;EAAE;CAC/E;AACF;AAEA,SAAS,oBACP,SACgB;CAChB,OAAO;EACL,IAAI,QAAQ;EACZ,MAAM,QAAQ;EACd,OAAO,QAAQ;EACf,UAAU,QAAQ;EAClB,QAAQ,QAAQ;CAClB;AACF;;;AC3DA,MAAa,8BAA0D;CACrE,OAAO;CACP,WAAW;CACX,SAAS;CACT,cAAc;CACd,eAAe;CACf,aAAa;CACb,YAAY;CACZ,UAAU;CACV,UAAU;CACV,WAAW;CACX,WAAW;CACX,gBAAgB;CAChB,WAAW;CACX,YAAY;AACd;AAEA,MAAM,mBAAmB;CACvB,OAAO;EAAE,iBAAiB;EAAI,iBAAiB;EAAI,kBAAkB;CAAG;CACxE,QAAQ;EAAE,iBAAiB;EAAI,iBAAiB;EAAI,kBAAkB;CAAG;CACzE,MAAM;EAAE,iBAAiB;EAAI,iBAAiB;EAAI,kBAAkB;CAAG;AACzE;AAEA,SAAgB,yBACd,SACA,eAA0B,QAAQ,OACR;CAC1B,MAAM,SAAwB,CAAC;CAC/B,IAAI,QAAQ,gBAAgB,MAAM,OAAO,eAAe,QAAQ;CAChE,IAAI,QAAQ,SAAS,OAAO,UAAU,QAAQ;CAC9C,IAAI,QAAQ,WAAW,OAAO,YAAY,QAAQ;CAClD,IAAI,QAAQ,eAAe,OAAO,gBAAgB,QAAQ;CAC1D,IAAI,QAAQ,aAAa,OAAO,cAAc,QAAQ;CACtD,IAAI,QAAQ,eAAe,MAAM,OAAO,qBAAqB;CAC7D,IAAI,QAAQ,eAAe,OAAO,OAAO,qBAAqB;CAC9D,IAAI,QAAQ,UAAU,OAAO,WAAW,OAAO,QAAQ,QAAQ;CAC/D,IAAI,QAAQ,UAAU,OAAO,OAAO,QAAQ,iBAAiB,QAAQ,SAAS;CAE9E,MAAM,QAA2C,CAAC;CAClD,IAAI,QAAQ,WAAW,MAAM,QAAQ,QAAQ;CAC7C,IAAI,QAAQ,WAAW,MAAM,YAAY,QAAQ;CACjD,OAAO;EACL,OAAO;EACP;EACA;EACA,GAAI,QAAQ,iBAAiB,EAAE,gBAAgB,KAAK,IAAI,CAAC;EACzD,OAAO;GAAE,WAAW,QAAQ;GAAW,YAAY,QAAQ;EAAW;CACxE;AACF;;;ACjDA,MAAM,iBAAuC;CAC3C,OAAO;CACP,WAAW;CACX,SAAS;CACT,aAAa;CACb,WAAW;CACX,WAAW;AACb;AAEA,SAAgB,yBAAyB,QAAsC;CAC7E,MAAM,UAAU,aAAa,MAAM;CACnC,IAAI,CAAC,SAAS,OAAO,EAAE,GAAG,eAAe;CACzC,MAAM,SAAS,EAAE,GAAG,eAAe;CACnC,KAAK,MAAM,aAAa,QAAQ,YAC9B,IAAI,UAAU,SAAS,eAAe,UAAU,SAAS,aACvD,OAAO,YAAY,MAAM,OAAO,UAAU,SAAS,EAAE,GAAG;EAAC;EAAM;EAAM;EAAM;CAAI,CAAC;MAC3E,IAAI,UAAU,SAAS,eAAe,UAAU,SAAS,WAC9D,OAAO,UAAU,MAAM,OAAO,UAAU,SAAS,EAAE,GAAG;EAAC;EAAW;EAAU;CAAU,CAAC;MAClF,IAAI,UAAU,SAAS,eAAe;EAC3C,MAAM,YAAY,eAAe,UAAU,YAAY,WAAW;EAClE,MAAM,UAAU,eAAe,UAAU,YAAY,SAAS;EAC9D,IAAI,WAAW,OAAO,YAAY,MAAM,WAAW;GAAC;GAAM;GAAM;GAAM;EAAI,CAAC;EAC3E,IAAI,SAAS,OAAO,UAAU,MAAM,SAAS;GAAC;GAAW;GAAU;EAAU,CAAC;EAC9E,MAAM,cAAc,eAAe,UAAU,YAAY,aAAa;EACtE,IAAI,aACF,OAAO,cAAc,MAAM,aAAa;GAAC;GAAQ;GAAY;GAAQ;EAAU,CAAC;CAEpF,OAAO,IAAI,UAAU,SAAS,mBAAmB;EAC/C,MAAM,YAAY,eAAe,UAAU,YAAY,OAAO;EAC9D,MAAM,YAAY,eAAe,UAAU,YAAY,WAAW;EAClE,IAAI,WACF,OAAO,YAAY,MAAM,WAAW;GAClC;GACA;GACA;GACA;GACA;EACF,CAAC;EAEH,IAAI,WAAW,OAAO,YAAY,MAAM,WAAW;GAAC;GAAS;GAAS;GAAQ;EAAM,CAAC;CACvF,OAAO,IAAI,UAAU,SAAS,eAC5B,OAAO,QACL,MAAM,OAAO,UAAU,WAAW,SAAS,MAAM,GAAG,CAAC,QAAQ,OAAO,CAAC,KAAK;CAGhF,OAAO;AACT;;AAGA,SAAgB,0BACd,QACA,SACA,OACQ;CACR,MAAM,UAAU,aAAa,MAAM;CACnC,IAAI,CAAC,SAAS,OAAO;CACrB,IAAI,YAAY,eAAe,YAAY,WAAW;EACpD,MAAM,SAAS,QAAQ,WAAW,MAAM,SAAS,KAAK,SAAS,aAAa;EAC5E,IAAI,SAAS,QAAQ,WAAW,YAAY,MAC1C,OAAO,YAAY,QAAQ,SAAS,eAAe,UAAU,SAAS,KAAK;EAE7E,MAAM,mBAAmB,gBAAgB,QAAQ,SAAS,SAAS,KAAK;EACxE,IAAI,OAAO,OAAO;EAClB,MAAM,WAAW,aAAa,gBAAgB;EAC9C,OAAO,WACH,YAAY,kBAAkB,UAAU,eAAe,UAAU,SAAS,EAAE,IAC5E;CACN;CACA,IAAI,YAAY,eACd,OAAO,YAAY,QAAQ,SAAS,eAAe,UAAU,eAAe,KAAK;CAEnF,IAAI,YAAY,SACd,OAAO,YAAY,QAAQ,SAAS,eAAe,UAAU,SAAS,KAAK;CAE7E,OAAO,YACL,QACA,SACA,mBACA,SACA,YAAY,cAAc,UAAU,aACpC,KACF;AACF;AAEA,SAAgB,0BAA0B,QAAwB;CAChE,OAAQ,OAAO,KAAK,cAAc,CAAC,CAA2B,QAC3D,SAAS,YAAY,0BAA0B,SAAS,SAAS,EAAE,GACpE,MACF;AACF;AAEA,SAAS,aAAa,QAAmC;CACvD,MAAM,QAAQ,MAAM,MAAM,CAAC,CAAC,KAAK;CACjC,OAAO,OAAO,SAAS,YAAY,QAAQ;AAC7C;AAEA,SAAS,gBACP,QACA,SACA,MACA,OACQ;CACR,MAAM,YAAY,QAAQ,WAAW,MAClC,SACC,KAAK,SAAS,eAAe,KAAK,SAAS,IAC/C;CACA,IAAI,WAAW;EACb,IAAI,CAAC,OAAO,OAAO,sBAAsB,QAAQ,SAAS,SAAS;EACnE,OAAO,aACL,QACA,UAAU,MAAM,MAAM,QACtB,UAAU,MAAM,IAAI,QACpB,GAAG,KAAK,GAAG,OACb;CACF;CACA,OAAO,QACH,sBAAsB,QAAQ,SAAS,GAAG,KAAK,GAAG,SAAS,WAAW,IAAI,CAAC,IAC3E;AACN;AAEA,SAAS,YACP,QACA,SACA,MACA,SACA,UACA,OACQ;CACR,MAAM,QAAQ,QAAQ,WAAW,MAAM,SAAS,KAAK,SAAS,IAAI;CAGlE,IAAI,CAAC,OACH,OAAO,QACH,sBACE,QACA,SACA,WAAW,SAAS,GAAG,WAAW,MAAM,CAAC,GACzC,WAAW,OAAO,CACpB,IACA;CAEN,MAAM,cAAc,OAAO,MAAM,MAAM,MAAM,MAAM,QAAQ,MAAM,MAAM,IAAI,MAAM;CACjF,MAAM,eAAe,YAAY,QAAQ,GAAG;CAC5C,MAAM,eAAe,YAAY,YAAY,GAAG;CAEhD,IAAI,CADS,YAAY,MAAM,eAAe,GAAG,YACzC,CAAC,CAAC,SAAS,IAAI,GAAG;EACxB,MAAM,aAA0B,EAAE,GAAG,MAAM,WAAW;EACtD,IAAI,OAAO,WAAW,YAAY;OAC7B,OAAO,WAAW;EACvB,IAAI,OAAO,KAAK,UAAU,CAAC,CAAC,WAAW,GAAG,OAAO,sBAAsB,QAAQ,SAAS,KAAK;EAC7F,OAAO,aACL,QACA,MAAM,MAAM,MAAM,QAClB,MAAM,MAAM,IAAI,QAChB,WAAW,SAAS,UAAU,CAChC;CACF;CACA,MAAM,eAAe,IAAI,OACvB,YAAY,YAAY,QAAQ,EAAE,uCAClC,GACF;CACA,MAAM,QAAQ,aAAa,KAAK,WAAW;CAC3C,IAAI,OAAO;EACT,MAAM,eAAe,QACjB,YAAY,QAAQ,cAAc,KAAK,MAAM,GAAG,IAChD,kBAAkB,aAAa,MAAM,OAAO,MAAM,EAAE,CAAC,MAAM;EAK/D,IAAI,CAJgB,aAAa,MAC/B,aAAa,QAAQ,GAAG,IAAI,GAC5B,aAAa,YAAY,GAAG,CAEf,CAAC,CAAC,KAAK,GAAG,OAAO,sBAAsB,QAAQ,SAAS,KAAK;EAC5E,OAAO,aAAa,QAAQ,MAAM,MAAM,MAAM,QAAQ,MAAM,MAAM,IAAI,QAAQ,YAAY;CAC5F;CACA,IAAI,CAAC,OAAO,OAAO;CAEnB,MAAM,WAAW,GADF,cAAc,QAAQ,MAAM,MAAM,MAAM,MAC9B,EAAE,IAAI,SAAS,IAAI,MAAM;CAClD,MAAM,eAAe,GAAG,YAAY,MAAM,GAAG,YAAY,IAAI,WAAW,YAAY,MAAM,YAAY;CACtG,OAAO,aAAa,QAAQ,MAAM,MAAM,MAAM,QAAQ,MAAM,MAAM,IAAI,QAAQ,YAAY;AAC5F;AAEA,SAAS,WAAW,SAAiB,YAAyB,SAAS,IAAY;CAIjF,OAAO,GAAG,QAAQ,MAHJ,OAAO,QAAQ,UAAU,CAAC,CAAC,KACtC,CAAC,KAAK,WAAW,GAAG,OAAO,IAAI,IAAI,IAAI,WAAW,KAAK,GAE9B,CAAC,CAAC,KAAK,IAAI,EAAE,IAAI,OAAO;AACtD;AAEA,SAAS,sBACP,QACA,SACA,WACA,MACQ;CACR,MAAM,SAAS,GAAG,cAAc,QAAQ,QAAQ,MAAM,MAAM,MAAM,EAAE;CACpE,MAAM,WAAW,UACd,MAAM,IAAI,CAAC,CACX,KAAK,SAAS,GAAG,SAAS,MAAM,CAAC,CACjC,KAAK,IAAI;CACZ,MAAM,SAAS,QAAQ,WAAW,MAAM,SAAS,WAAW,IAAI,IAAI,IAAI;CACxE,IAAI,QAAQ;EACV,MAAM,kBAAkB,OAAO,YAAY,MAAM,OAAO,MAAM,MAAM,SAAS,CAAC,IAAI;EAClF,MAAM,mBAAmB,WAAW,MAAM,MAAM,OAAO;EACvD,OAAO,GAAG,OAAO,MAAM,GAAG,eAAe,IAAI,SAAS,IAAI,mBAAmB,OAAO,KAAK,OAAO,MAAM,eAAe;CACvH;CAEA,MAAM,eAAe,OAAO,YAAY,KAAK,QAAQ,MAAM,IAAI,MAAM;CACrE,IAAI,eAAe,GAAG,OAAO;CAC7B,OAAO,GAAG,OAAO,MAAM,GAAG,YAAY,IAAI,SAAS,IAAI,OAAO,MAAM,YAAY;AAClF;AAEA,SAAS,WACP,OACQ;CACR,MAAM,OACJ,OAAO,UAAU,WACb,QACA,MAAM,SAAS,cACb,MAAM,OACN,MAAM,SAAS,gBACb,WACA,MAAM,SAAS,oBACb,UACA,MAAM,SAAS,gBACb,WACA,MAAM,SAAS,sBACb,iBACA;CAChB,MAAM,QAAQ;EAAC;EAAa;EAAW;EAAU;EAAS;EAAU;CAAc;CAClF,OAAO,MAAM,QAAQ,IAAI,MAAM,KAAK,OAAO,oBAAoB,MAAM,QAAQ,IAAI;AACnF;AAEA,SAAS,oBAAoB,QAAgB,WAAiC;CAC5E,MAAM,QAAQ,OAAO,YAAY,MAAM,UAAU,MAAM,MAAM,SAAS,CAAC,IAAI;CAC3E,MAAM,cAAc,OAAO,QAAQ,MAAM,UAAU,MAAM,IAAI,MAAM;CAEnE,OAAO,aAAa,QAAQ,OADhB,cAAc,IAAI,UAAU,MAAM,IAAI,SAAS,cAAc,GACjC,EAAE;AAC5C;AAEA,SAAS,sBACP,QACA,SACA,WACQ;CACR,MAAM,UAAU,oBAAoB,QAAQ,SAAS;CAIrD,IAHuB,QAAQ,WAAW,MACvC,SAAS,SAAS,aAAa,WAAW,IAAI,IAAI,OAAO,iBAE3C,GAAG,OAAO;CAE3B,MAAM,iBAAiB,aAAa,OAAO,CAAC,EAAE,WAAW;CACzD,IAAI,CAAC,gBAAgB,OAAO;CAC5B,MAAM,YAAY,QAAQ,YAAY,MAAM,eAAe,MAAM,MAAM,SAAS,CAAC,IAAI;CACrF,MAAM,YAAY,QAAQ,MAAM,GAAG,SAAS;CAC5C,OAAO,UAAU,SAAS,MAAM,IAC5B,GAAG,UAAU,MAAM,GAAG,EAAE,IAAI,QAAQ,MAAM,SAAS,MACnD;AACN;AAEA,SAAS,cAAc,QAAgB,QAAwB;CAC7D,MAAM,YAAY,OAAO,YAAY,MAAM,SAAS,CAAC,IAAI;CACzD,OAAO,OAAO,KAAK,OAAO,MAAM,WAAW,MAAM,CAAC,CAAC,GAAG,MAAM;AAC9D;AAEA,SAAS,aAAa,QAAgB,OAAe,KAAa,aAA6B;CAC7F,OAAO,GAAG,OAAO,MAAM,GAAG,KAAK,IAAI,cAAc,OAAO,MAAM,GAAG;AACnE;AAEA,SAAS,eAAe,YAAyB,MAAsB;CACrE,MAAM,QAAQ,WAAW;CACzB,OAAO,OAAO,UAAU,WAAW,QAAQ;AAC7C;AAEA,SAAS,WAAW,OAA8B;CAChD,OAAO,MAAM,QAAQ,KAAK,IAAI,IAAI,MAAM,KAAK,IAAI,EAAE,KAAK,OAAO,KAAK;AACtE;AAEA,SAAS,kBAAkB,QAAgB,OAAe,QAAwB;CAChF,MAAM,YAAY,OAAO,YAAY,MAAM,QAAQ,CAAC,IAAI;CACxD,MAAM,cAAc,OAAO,QAAQ,MAAM,QAAQ,MAAM;CACvD,MAAM,UAAU,cAAc,IAAI,QAAQ,SAAS,cAAc;CACjE,OAAO,GAAG,OAAO,MAAM,GAAG,SAAS,IAAI,OAAO,MAAM,OAAO;AAC7D;AAEA,SAAS,YAAY,OAAuB;CAC1C,OAAO,MAAM,QAAQ,uBAAuB,MAAM;AACpD;AAEA,SAAS,MAAkC,OAAe,SAAuC;CAC/F,OAAO,QAAQ,SAAS,KAAc,IAAK,QAAkB;AAC/D"}
package/package.json ADDED
@@ -0,0 +1,72 @@
1
+ {
2
+ "name": "@kekonic/diagrams-studio",
3
+ "version": "1.0.0-rc.4",
4
+ "description": "Host-neutral synchronization core and local browser studio for KDiagram authoring.",
5
+ "keywords": [
6
+ "diagram",
7
+ "editor",
8
+ "preview",
9
+ "studio"
10
+ ],
11
+ "homepage": "https://github.com/kekonic/diagrams#readme",
12
+ "bugs": {
13
+ "url": "https://github.com/kekonic/diagrams/issues"
14
+ },
15
+ "license": "MIT",
16
+ "repository": {
17
+ "type": "git",
18
+ "url": "git+https://github.com/kekonic/diagrams.git",
19
+ "directory": "packages/diagrams-studio"
20
+ },
21
+ "files": [
22
+ "dist"
23
+ ],
24
+ "type": "module",
25
+ "exports": {
26
+ ".": {
27
+ "types": "./dist/index.d.mts",
28
+ "import": "./dist/index.mjs"
29
+ },
30
+ "./browser": "./dist/browser/index.html"
31
+ },
32
+ "publishConfig": {
33
+ "access": "public"
34
+ },
35
+ "dependencies": {
36
+ "@fontsource/ibm-plex-mono": "^5.2.6",
37
+ "@fontsource/ibm-plex-sans": "^5.2.6",
38
+ "@monaco-editor/react": "^4.7.0",
39
+ "@shikijs/monaco": "^4.4.2",
40
+ "@shikijs/themes": "^4.4.2",
41
+ "lucide-react": "^1.28.0",
42
+ "monaco-editor": "^0.56.0",
43
+ "react": "^19.2.8",
44
+ "react-dom": "^19.2.8",
45
+ "shiki": "^4.3.1",
46
+ "@kekonic/diagrams": "1.0.0-rc.4",
47
+ "@kekonic/diagrams-core": "1.0.0-rc.4",
48
+ "@kekonic/diagrams-element": "1.0.0-rc.4",
49
+ "@kekonic/diagrams-icons": "1.0.0-rc.4",
50
+ "@kekonic/diagrams-language-service": "1.0.0-rc.4",
51
+ "@kekonic/diagrams-theme": "1.0.0-rc.4",
52
+ "@kekonic/diagrams-ui": "1.0.0-rc.4"
53
+ },
54
+ "devDependencies": {
55
+ "@types/node": "^26",
56
+ "@types/react": "^19.2.17",
57
+ "@types/react-dom": "^19.2.3",
58
+ "@vitejs/plugin-react": "^6.0.4",
59
+ "typescript": "^5",
60
+ "vite": "npm:@voidzero-dev/vite-plus-core@0.2.2",
61
+ "vite-plus": "0.2.2",
62
+ "vitest": "^4"
63
+ },
64
+ "engines": {
65
+ "node": ">=22.18.0"
66
+ },
67
+ "scripts": {
68
+ "dev": "vp dev",
69
+ "build": "vp pack && vp build",
70
+ "test": "vp test"
71
+ }
72
+ }