likec4 1.48.0 → 1.49.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (113) hide show
  1. package/README.md +11 -1
  2. package/__app__/src/likec4.js +5595 -4127
  3. package/__app__/src/routes/index.js +3 -153
  4. package/__app__/src/routes/projects.js +21 -1087
  5. package/__app__/src/routes/single.js +1221 -16
  6. package/__app__/src/style.css +1 -1
  7. package/__app__/src/vendors.js +3507 -894
  8. package/__app__/src/webcomponent.js +1 -1
  9. package/config/schema.json +155 -143
  10. package/dist/THIRD-PARTY-LICENSES.md +1739 -0
  11. package/dist/_chunks/GraphvizBinaryAdapter.mjs +72 -0
  12. package/dist/_chunks/filenames.mjs +14 -0
  13. package/dist/_chunks/index.d.mts +224 -129
  14. package/dist/_chunks/index2.d.mts +2033 -1908
  15. package/dist/_chunks/libs/@chevrotain/gast.mjs +1 -3969
  16. package/dist/_chunks/libs/@chevrotain/regexp-to-ast.mjs +9 -785
  17. package/dist/_chunks/libs/@chevrotain/utils.mjs +1 -37
  18. package/dist/_chunks/libs/@hono/mcp.mjs +34 -0
  19. package/dist/_chunks/libs/@hono/node-server.mjs +1 -436
  20. package/dist/_chunks/libs/@logtape/logtape.d.mts +741 -0
  21. package/dist/_chunks/libs/@logtape/logtape.mjs +6 -1354
  22. package/dist/_chunks/libs/@lume/kiwi.mjs +1 -1355
  23. package/dist/_chunks/libs/@modelcontextprotocol/sdk.d.mts +14 -14
  24. package/dist/_chunks/libs/@modelcontextprotocol/sdk.mjs +12 -25105
  25. package/dist/_chunks/libs/@msgpack/msgpack.mjs +1 -1503
  26. package/dist/_chunks/libs/@nanostores/react.mjs +1 -30
  27. package/dist/_chunks/libs/@smithy/util-base64.mjs +1 -100
  28. package/dist/_chunks/libs/ajv.mjs +1 -777
  29. package/dist/_chunks/libs/atomically.mjs +1 -362
  30. package/dist/_chunks/libs/birpc.mjs +1 -201
  31. package/dist/_chunks/libs/chevrotain-allstar.mjs +2 -850
  32. package/dist/_chunks/libs/chevrotain.mjs +55 -6229
  33. package/dist/_chunks/libs/conf.mjs +1 -2258
  34. package/dist/_chunks/libs/defu.mjs +1 -42
  35. package/dist/_chunks/libs/esm-env.mjs +1 -5
  36. package/dist/_chunks/libs/eventemitter3.mjs +1 -243
  37. package/dist/_chunks/libs/fast-equals.mjs +1 -446
  38. package/dist/_chunks/libs/find-up-simple.mjs +1 -24
  39. package/dist/_chunks/libs/get-port.mjs +1 -107
  40. package/dist/_chunks/libs/is-docker.mjs +1 -26
  41. package/dist/_chunks/libs/is-error-instance.mjs +1 -26
  42. package/dist/_chunks/libs/is-inside-container.mjs +1 -20
  43. package/dist/_chunks/libs/is-plain-obj.mjs +1 -9
  44. package/dist/_chunks/libs/isexe.mjs +1 -127
  45. package/dist/_chunks/libs/json5.mjs +14 -959
  46. package/dist/_chunks/libs/khroma.mjs +1 -605
  47. package/dist/_chunks/libs/ky.mjs +2 -807
  48. package/dist/_chunks/libs/langium.d.mts +2880 -2844
  49. package/dist/_chunks/libs/langium.mjs +32 -20351
  50. package/dist/_chunks/libs/merge-error-cause.mjs +2 -746
  51. package/dist/_chunks/libs/nanostores.mjs +1 -198
  52. package/dist/_chunks/libs/p-limit.mjs +1 -120
  53. package/dist/_chunks/libs/p-queue.mjs +1 -449
  54. package/dist/_chunks/libs/package-manager-detector.mjs +1 -559
  55. package/dist/_chunks/libs/package-up.mjs +1 -10
  56. package/dist/_chunks/libs/parse-ms.mjs +1 -36
  57. package/dist/_chunks/libs/pathe.mjs +1 -0
  58. package/dist/_chunks/libs/picomatch.mjs +1 -1673
  59. package/dist/_chunks/libs/pretty-ms.mjs +1 -80
  60. package/dist/_chunks/libs/remeda.mjs +1 -690
  61. package/dist/_chunks/libs/safe-stringify.mjs +1 -21
  62. package/dist/_chunks/libs/strip-indent.mjs +1 -15
  63. package/dist/_chunks/libs/tinyrainbow.mjs +1 -88
  64. package/dist/_chunks/libs/ts-graphviz.mjs +4 -725
  65. package/dist/_chunks/libs/ufo.mjs +1 -240
  66. package/dist/_chunks/libs/which.mjs +1 -84
  67. package/dist/_chunks/libs/word-wrap.mjs +12 -43
  68. package/dist/_chunks/node.mjs +481 -0
  69. package/dist/_chunks/plugin.mjs +98 -772
  70. package/dist/_chunks/rolldown-runtime.mjs +1 -48
  71. package/dist/_chunks/sequence-view.mjs +1 -575
  72. package/dist/cli/index.mjs +127 -1846
  73. package/dist/config/index.d.mts +2 -2
  74. package/dist/config/index.mjs +1 -6
  75. package/dist/index.d.mts +148 -7
  76. package/dist/index.mjs +1 -21
  77. package/dist/model/builder.mjs +1 -3
  78. package/dist/model/index.d.mts +57 -3
  79. package/dist/model/index.mjs +1 -5
  80. package/dist/vite-plugin/index.d.mts +4 -3
  81. package/dist/vite-plugin/index.mjs +1 -22
  82. package/dist/vite-plugin/internal.d.mts +5 -5
  83. package/dist/vite-plugin/internal.mjs +1 -68
  84. package/package.json +60 -41
  85. package/react/{index.d.ts → index.d.mts} +112 -70
  86. package/react/{index.js → index.mjs} +21361 -22064
  87. package/react/package.json +2 -5
  88. package/vite-plugin-modules.d.ts +5 -5
  89. package/dist/_chunks/LikeC4.d.mts +0 -121
  90. package/dist/_chunks/LikeC4.mjs +0 -202
  91. package/dist/_chunks/config-app.prod.d.mts +0 -18
  92. package/dist/_chunks/config-app.prod.mjs +0 -188
  93. package/dist/_chunks/config-webcomponent.prod.mjs +0 -71
  94. package/dist/_chunks/define-config.mjs +0 -409
  95. package/dist/_chunks/index3.d.mts +0 -60
  96. package/dist/_chunks/index4.d.mts +0 -1
  97. package/dist/_chunks/libs/@smithy/is-array-buffer.mjs +0 -10
  98. package/dist/_chunks/libs/hono.mjs +0 -1829
  99. package/dist/_chunks/libs/nanoid.mjs +0 -29
  100. package/dist/_chunks/model.mjs +0 -12
  101. package/dist/_chunks/module.d.mts +0 -71
  102. package/dist/_chunks/module.mjs +0 -18657
  103. package/dist/_chunks/vite-build.mjs +0 -69
  104. package/dist/_chunks/vite-dev.mjs +0 -79
  105. package/dist/_chunks/vite-preview.mjs +0 -27
  106. package/dist/language/module.d.mts +0 -5
  107. package/dist/language/module.mjs +0 -20
  108. package/dist/vite/vite-build.d.mts +0 -26
  109. package/dist/vite/vite-build.mjs +0 -27
  110. package/dist/vite/vite-dev.d.mts +0 -34
  111. package/dist/vite/vite-dev.mjs +0 -29
  112. package/dist/vite/vite-preview.d.mts +0 -20
  113. package/dist/vite/vite-preview.mjs +0 -26
@@ -1,101 +1,8 @@
1
1
  import { jsx, jsxs, Fragment } from "react/jsx-runtime";
2
- import { d4 as Loader, d5 as useStore, d as deepEqual, s as shallowEqual, d6 as useMatches, cN as useParams, v as useIsomorphicLayoutEffect, cZ as createFileRoute, cP as Container, ba as Stack, b$ as Title, V as Button, cT as Link, d7 as notFound, c_ as redirect, O as m, cY as Outlet, d8 as Navigate, k as useMantineColorScheme, d9 as useComputedColorScheme, aA as ActionIcon, aF as MotionDiv, cI as isValidMotionProp, aD as Menu, bg as MenuTarget, bh as MenuDropdown, bi as MenuItem, da as MenuDivider, by as Alert, bc as rem, R as Text, cM as useRouter, aM as Box, bA as Group, b1 as CopyButton$1, cQ as Code, db as Select, dc as ModalRoot, dd as ModalOverlay, de as ModalContent, df as ModalBody, bP as Tabs, bQ as TabsList, bR as TabsTab, bS as TabsPanel, dg as useMantineTheme, dh as useMediaQuery, di as useDisclosure, aG as Divider, dj as MenuLabel, dk as useSearch, dl as LoadingOverlay, dm as toBlob, cU as useNavigate, bU as useCallbackRef, c$ as useDocumentTitle, dn as useIsMounted, cX as stripSearchParams, cV as z, T as Tooltip, dp as useAsync, dq as It, dr as Ot, bT as ScrollArea, ds as Nt } from "../vendors.js";
3
- import { F as Fallback, N as NotFound } from "./index.js";
4
- import { s as styled, I as IconRendererProvider, a as LikeC4ModelProvider, u as useUpdateEffect, b as LikeC4AdHocViewEditor, d as IconMoonStars, e as IconSun, f as createStyleContext, n as navigationPanel, i as isCssProperty, g as useLikeC4Projects$1, h as IconChevronDown, j as IconAlertTriangle, k as IconCheck, l as IconCopy, m as IconExternalLink, o as IconShare, p as pickViewBounds, B as Box$1, q as LikeC4Diagram, S as StaticLikeC4Diagram, r as useLikeC4Model, t as useDiagramContext, v as useDiagram, w as useOnDiagramEvent, x as LikeC4EditorProvider, c as css } from "../likec4.js";
5
- import { lazy, Suspense, createContext, useContext, useState, useEffect, memo, useRef } from "react";
6
- import { likec4rpc, isRpcAvailable } from "likec4:rpc";
7
- import { useHashHistory, ComponentName, pageTitle, isDevelopment, krokiPumlSvgUrl, krokiD2SvgUrl } from "../const.js";
8
- import { useLikeC4Projects } from "likec4:projects";
9
- const ViewOutlet = styled("div", {
10
- base: {
11
- padding: "0",
12
- margin: "0",
13
- width: "full",
14
- height: "full"
15
- }
16
- }), ProjectIcons = lazy(async () => {
17
- const { ProjectIcons: ProjectIcons2 } = await import("likec4:icons");
18
- return {
19
- default: ProjectIcons2
20
- };
21
- }), ProjectIconRenderer = (props) => /* @__PURE__ */ jsx(Suspense, { fallback: /* @__PURE__ */ jsx(Loader, { className: "pending", type: "oval", size: "xs" }), children: /* @__PURE__ */ jsx(ProjectIcons, { ...props }) });
22
- let _renderers = {};
23
- function LikeC4IconRendererContext({ children, projectId }) {
24
- const IconRenderer = _renderers[projectId] ??= (props) => /* @__PURE__ */ jsx(ProjectIconRenderer, { ...props, projectId });
25
- return /* @__PURE__ */ jsx(IconRendererProvider, { value: IconRenderer, children });
26
- }
27
- const LikeC4ModelDataContext = createContext(null), LikeC4ModelDataContextProvider = LikeC4ModelDataContext.Provider, useLikeC4ModelAtom = () => {
28
- const ctx = useContext(LikeC4ModelDataContext);
29
- if (ctx === null)
30
- throw new Error("LikeC4ModelAtom is not provided");
31
- return ctx;
32
- };
33
- function LikeC4ModelContext({ likec4model, children }) {
34
- const model = useStore(likec4model);
35
- return /* @__PURE__ */ jsx(LikeC4ModelDataContextProvider, { value: likec4model, children: /* @__PURE__ */ jsx(LikeC4ModelProvider, { likec4model: model, children }) });
36
- }
37
- function useTransparentBackground(enabled = !0) {
38
- useIsomorphicLayoutEffect(() => {
39
- const htmlEl = document.body.parentElement;
40
- if (!htmlEl || enabled !== !0) return;
41
- const classname = "transparent-bg";
42
- return htmlEl.classList.add(classname), () => {
43
- htmlEl.classList.remove(classname);
44
- };
45
- }, [enabled]);
46
- }
47
- function useLikeC4Views() {
48
- const $likec4model = useLikeC4ModelAtom(), [views, setViews] = useState([]);
49
- return useEffect(() => $likec4model.subscribe((next) => {
50
- setViews((prev) => {
51
- const nextViews = [...next.views()].map((v) => {
52
- const n = v.$layouted, p = prev.find((_) => _.id === v.id);
53
- return p && deepEqual(n, p) ? p : n;
54
- });
55
- return shallowEqual(prev, nextViews) ? prev : nextViews;
56
- });
57
- }), [$likec4model]), views;
58
- }
59
- function useCurrentViewId() {
60
- return useParams({
61
- select: (params) => params.viewId,
62
- strict: !1
63
- }) ?? "index";
64
- }
65
- function useCurrentView() {
66
- const viewId = useCurrentViewId(), $likec4model = useLikeC4ModelAtom(), [layoutType, setLayoutType] = useState("manual");
67
- useUpdateEffect(() => {
68
- setLayoutType("manual");
69
- }, [viewId]);
70
- const [view, setView] = useState(() => $likec4model.get().findView(viewId)?.$layouted ?? null);
71
- return useEffect(() => $likec4model.subscribe((next) => {
72
- setView((current) => {
73
- const vm = next.findView(viewId);
74
- if (!vm)
75
- return null;
76
- const nextView = layoutType === "auto" ? vm.$view : vm.$layouted;
77
- return deepEqual(current, nextView) ? current : nextView;
78
- });
79
- }), [$likec4model, viewId, layoutType]), [view, setLayoutType];
80
- }
81
- function useCurrentProject() {
82
- const projects = useLikeC4Projects(), projectId = useMatches({
83
- select: (m2) => m2.find((m22) => m22.routeId === "/project/$projectId")?.params?.projectId ?? m2.at(-1)?.context.projectId ?? "default"
84
- });
85
- return projects.find((p) => p.id === projectId) ?? projects[0];
86
- }
87
- function AdHocViewEditor({ projectId }) {
88
- return /* @__PURE__ */ jsx(
89
- LikeC4AdHocViewEditor,
90
- {
91
- service: {
92
- process: async ({ predicates }) => ({
93
- view: await likec4rpc.calcAdhocView({ projectId, predicates })
94
- })
95
- }
96
- }
97
- );
98
- }
2
+ import { d1 as createFileRoute, db as Container, bp as Stack, bZ as Title, W as Button, df as Link, dD as notFound, d2 as redirect, Q as m, d0 as Outlet, dE as Navigate, c$ as stripSearchParams, cZ as z } from "../vendors.js";
3
+ import { loadModel } from "likec4:model";
4
+ import { V as ViewOutlet, F as Fallback, L as LikeC4IconRendererContext, l as LikeC4ModelContext, A as AdHocViewEditor, H as Header, E as ExportPage, m as EmbedPage, n as ViewEditor, o as ViewReact, p as ViewAsPuml, q as ViewAsMmd, r as ViewAsDot, s as ViewAsD2 } from "./single.js";
5
+ import { isRpcAvailable } from "likec4:rpc";
99
6
  const Route$a = createFileRoute("/project/$projectId")({
100
7
  staleTime: 1 / 0,
101
8
  beforeLoad: ({ params }) => ({
@@ -105,26 +12,21 @@ const Route$a = createFileRoute("/project/$projectId")({
105
12
  return [];
106
13
  },
107
14
  loader: async ({ context }) => {
108
- const projectId = context.projectId;
109
- return await import("likec4:model").then((m2) => m2.loadModel(projectId)).catch((err) => {
110
- throw console.error(err), notFound();
111
- }).then((likec4model) => {
112
- const data = likec4model.$likec4data.value;
113
- if (!data)
114
- throw notFound();
115
- if (data.projectId !== projectId)
116
- throw redirect({
117
- to: "/project/$projectId/",
118
- search: !0,
119
- params: {
120
- projectId: data.projectId
121
- }
122
- });
123
- return {
124
- $likec4model: likec4model.$likec4model,
125
- projectId
126
- };
127
- });
15
+ const projectId = context.projectId, likec4model = await loadModel(projectId), data = likec4model.$likec4data.value;
16
+ if (!data)
17
+ throw notFound();
18
+ if (data.projectId !== projectId)
19
+ throw redirect({
20
+ to: "/project/$projectId/",
21
+ search: !0,
22
+ params: {
23
+ projectId: data.projectId
24
+ }
25
+ });
26
+ return {
27
+ $likec4model: likec4model.$likec4model,
28
+ projectId
29
+ };
128
30
  },
129
31
  remountDeps({ params }) {
130
32
  return [params.projectId];
@@ -170,724 +72,6 @@ function Page$4() {
170
72
  const { projectId } = Route$8.useRouteContext();
171
73
  return /* @__PURE__ */ jsx(AdHocViewEditor, { projectId });
172
74
  }
173
- function ColorSchemeToggle() {
174
- const { setColorScheme } = useMantineColorScheme({
175
- keepTransitions: !0
176
- }), computedColorScheme = useComputedColorScheme("light");
177
- return /* @__PURE__ */ jsxs(
178
- ActionIcon,
179
- {
180
- visibleFrom: "sm",
181
- size: "md",
182
- variant: "subtle",
183
- color: "gray",
184
- onClick: () => setColorScheme(computedColorScheme === "light" ? "dark" : "light"),
185
- "aria-label": "Toggle color scheme",
186
- children: [
187
- /* @__PURE__ */ jsx(IconMoonStars, { stroke: 1.5, display: computedColorScheme === "light" ? "block" : "none" }),
188
- /* @__PURE__ */ jsx(IconSun, { stroke: 1.5, display: computedColorScheme === "dark" ? "block" : "none" })
189
- ]
190
- }
191
- );
192
- }
193
- const { withProvider, withContext } = createStyleContext(navigationPanel), shouldForwardProp = (prop, variantKeys) => !variantKeys.includes(prop) && (isValidMotionProp(prop) || !isCssProperty(prop)), Root = withProvider(MotionDiv, "root", {
194
- shouldForwardProp
195
- }), Body = withContext(MotionDiv, "body", {
196
- shouldForwardProp
197
- });
198
- withContext(MotionDiv, "label", {
199
- shouldForwardProp
200
- });
201
- withContext(MotionDiv, "dropdown", {
202
- shouldForwardProp
203
- });
204
- const NavigationPanel = {
205
- Root,
206
- Body
207
- };
208
- function SelectProject() {
209
- const projects = useLikeC4Projects$1(), project = useCurrentProject();
210
- return projects.length < 2 ? null : /* @__PURE__ */ jsxs(Menu, { shadow: "md", width: 200, trigger: "click-hover", openDelay: 200, children: [
211
- /* @__PURE__ */ jsx(MenuTarget, { children: /* @__PURE__ */ jsx(
212
- Button,
213
- {
214
- variant: "subtle",
215
- size: "sm",
216
- color: "gray",
217
- px: "sm",
218
- rightSection: /* @__PURE__ */ jsx(IconChevronDown, { opacity: 0.5, size: 14 }),
219
- visibleFrom: "md",
220
- children: project.title ?? project.id
221
- }
222
- ) }),
223
- /* @__PURE__ */ jsxs(MenuDropdown, { children: [
224
- /* @__PURE__ */ jsx(
225
- MenuItem,
226
- {
227
- renderRoot: (props) => /* @__PURE__ */ jsx(
228
- Link,
229
- {
230
- ...props,
231
- to: "/projects"
232
- }
233
- ),
234
- children: "Projects overview"
235
- }
236
- ),
237
- /* @__PURE__ */ jsx(MenuDivider, {}),
238
- projects.map(({ id, title }) => /* @__PURE__ */ jsx(
239
- MenuItem,
240
- {
241
- renderRoot: (props) => /* @__PURE__ */ jsx(
242
- Link,
243
- {
244
- ...props,
245
- to: "/project/$projectId/view/$viewId/",
246
- params: {
247
- projectId: id,
248
- viewId: "index"
249
- }
250
- }
251
- ),
252
- children: title ?? id
253
- },
254
- id
255
- ))
256
- ] })
257
- ] });
258
- }
259
- const AlertLocalhost = () => /* @__PURE__ */ jsx(
260
- Alert,
261
- {
262
- color: "yellow",
263
- icon: /* @__PURE__ */ jsx(IconAlertTriangle, {}),
264
- title: "Localhost URL",
265
- styles: { body: { gap: rem(4) } },
266
- children: /* @__PURE__ */ jsx(Text, { c: "yellow", size: "sm", children: "You need to deploy your project to make it available on the internet" })
267
- }
268
- ), CopyButtonChild = ({ copied, copy }) => /* @__PURE__ */ jsx(
269
- Button,
270
- {
271
- size: "xs",
272
- color: copied ? "teal" : "gray",
273
- variant: "light",
274
- leftSection: copied ? /* @__PURE__ */ jsx(IconCheck, { style: { width: rem(16) } }) : /* @__PURE__ */ jsx(IconCopy, { style: { width: rem(16) } }),
275
- onClick: copy,
276
- children: copied ? "Copied" : "Copy to clipboard"
277
- }
278
- ), EmbedPanel = ({ diagram }) => {
279
- const router = useRouter(), { colorScheme } = useMantineColorScheme(), [theme, setTheme] = useState(colorScheme), padding = 20;
280
- let location = router.buildLocation({
281
- to: "/embed/$viewId/",
282
- // '/' at the end added by Gemini 3, must have to pass typecheck
283
- params: { viewId: diagram.id },
284
- search: {
285
- padding,
286
- ...theme !== "auto" ? { theme } : {}
287
- // changed from "theme: theme !== 'auto' ? theme : undefined" by Gemini 3
288
- }
289
- }).href;
290
- location = useHashHistory ? `#${location}` : location;
291
- const url = new URL(location, window.location.href), width = diagram.bounds.width + padding * 2, height = diagram.bounds.height + padding * 2, href = url.href, code = `
292
- <div style="aspect-ratio:${width}/${height};width:100%;height:auto;max-width:${width}px;margin:0 auto">
293
- <iframe src="${href}" width="100%" height="100%" style="border:0;background:transparent;"></iframe>
294
- </div>
295
- `.trim();
296
- return /* @__PURE__ */ jsxs(Stack, { children: [
297
- code.includes("http://localhost") && /* @__PURE__ */ jsx(AlertLocalhost, {}),
298
- /* @__PURE__ */ jsx(Box, { children: /* @__PURE__ */ jsx(Text, { size: "sm", children: "Embedded view is an iframe with a static diagram" }) }),
299
- /* @__PURE__ */ jsxs(Stack, { gap: "xs", children: [
300
- /* @__PURE__ */ jsxs(Group, { justify: "space-between", children: [
301
- /* @__PURE__ */ jsx(Box, { children: /* @__PURE__ */ jsx(Text, { fw: "500", size: "sm", children: "HTML" }) }),
302
- /* @__PURE__ */ jsxs(Group, { gap: "xs", children: [
303
- /* @__PURE__ */ jsx(ActionIcon, { component: "a", href, target: "_blank", variant: "light", color: "gray", children: /* @__PURE__ */ jsx(IconExternalLink, {}) }),
304
- /* @__PURE__ */ jsx(CopyButton$1, { value: code, timeout: 1500, children: CopyButtonChild })
305
- ] })
306
- ] }),
307
- /* @__PURE__ */ jsx(Code, { block: !0, children: code }),
308
- /* @__PURE__ */ jsx(
309
- Box,
310
- {
311
- style: {
312
- alignSelf: "flex-start"
313
- },
314
- children: /* @__PURE__ */ jsx(
315
- Select,
316
- {
317
- label: "Color scheme",
318
- value: theme,
319
- allowDeselect: !1,
320
- onChange: (v) => setTheme(v ?? "auto"),
321
- data: [
322
- { value: "auto", label: "Auto" },
323
- { value: "light", label: "Light" },
324
- { value: "dark", label: "Dark" }
325
- ]
326
- }
327
- )
328
- }
329
- )
330
- ] })
331
- ] });
332
- };
333
- function WebcomponentsPanel({ diagram }) {
334
- const router = useRouter();
335
- let base = router.basepath.endsWith("/") ? router.basepath : `${router.basepath}/`;
336
- const jscode = `
337
- <script module src="${new URL(
338
- `${base}likec4-views.js`,
339
- window.location.href
340
- ).href}"><\/script>
341
- `.trim(), htmlCode = `
342
- <${ComponentName.View}
343
- view-id="${encodeURIComponent(diagram.id)}"
344
- browser="true"
345
- dynamic-variant="sequence">
346
- </${ComponentName.View}>
347
- `.trim(), webcomponentPreview = router.buildLocation(
348
- {
349
- to: "/webcomponent/$/",
350
- // '/' at the end added by Gemini 3, must have to pass typecheck
351
- params: { _splat: diagram.id },
352
- search: !0
353
- }
354
- );
355
- return /* @__PURE__ */ jsxs(Stack, { children: [
356
- jscode.includes("http://localhost") && /* @__PURE__ */ jsx(AlertLocalhost, {}),
357
- /* @__PURE__ */ jsx(Box, { children: /* @__PURE__ */ jsx(Text, { size: "sm", children: "Add this script to your page:" }) }),
358
- /* @__PURE__ */ jsxs(Stack, { gap: "xs", children: [
359
- /* @__PURE__ */ jsxs(Group, { justify: "space-between", children: [
360
- /* @__PURE__ */ jsx(Box, { children: /* @__PURE__ */ jsx(Text, { fw: "500", size: "sm", children: "JavaScript" }) }),
361
- /* @__PURE__ */ jsxs(Group, { gap: "xs", children: [
362
- /* @__PURE__ */ jsx(ActionIcon, { component: "a", href: webcomponentPreview.href, target: "_blank", variant: "light", color: "gray", children: /* @__PURE__ */ jsx(IconExternalLink, {}) }),
363
- /* @__PURE__ */ jsx(
364
- CopyButton$1,
365
- {
366
- value: jscode,
367
- timeout: 1500,
368
- children: CopyButtonChild
369
- }
370
- )
371
- ] })
372
- ] }),
373
- /* @__PURE__ */ jsx(Code, { block: !0, children: jscode }),
374
- /* @__PURE__ */ jsx(Box, { children: /* @__PURE__ */ jsxs(Text, { size: "sm", c: "dimmed", children: [
375
- "This script defines a custom element (webcomponent) that renders your diagrams.",
376
- /* @__PURE__ */ jsx("br", {}),
377
- "Script must be inserted once in the ",
378
- /* @__PURE__ */ jsx("code", { children: "<head>" }),
379
- " or at the end of the ",
380
- /* @__PURE__ */ jsx("code", { children: "<body>" }),
381
- " ",
382
- "tag."
383
- ] }) })
384
- ] }),
385
- /* @__PURE__ */ jsxs(Stack, { gap: "xs", children: [
386
- /* @__PURE__ */ jsxs(Group, { justify: "space-between", children: [
387
- /* @__PURE__ */ jsx(Box, { children: /* @__PURE__ */ jsx(Text, { fw: "500", size: "sm", children: "HTML" }) }),
388
- /* @__PURE__ */ jsx(Box, { children: /* @__PURE__ */ jsx(
389
- CopyButton$1,
390
- {
391
- value: htmlCode,
392
- timeout: 1500,
393
- children: CopyButtonChild
394
- }
395
- ) })
396
- ] }),
397
- /* @__PURE__ */ jsx(Code, { block: !0, children: htmlCode }),
398
- /* @__PURE__ */ jsx(Box, { children: /* @__PURE__ */ jsxs(Text, { size: "sm", c: "dimmed", children: [
399
- "Insert this code to your page. Page may have multiple ",
400
- /* @__PURE__ */ jsx("code", { children: "<likec4-view>" }),
401
- "."
402
- ] }) })
403
- ] })
404
- ] });
405
- }
406
- function ShareModal({
407
- onClose
408
- }) {
409
- const [diagram] = useCurrentView(), [activeTab, setActiveTab] = useState("webcomponent");
410
- return diagram ? /* @__PURE__ */ jsxs(
411
- ModalRoot,
412
- {
413
- size: "xl",
414
- opened: !0,
415
- onClose,
416
- children: [
417
- /* @__PURE__ */ jsx(ModalOverlay, { backgroundOpacity: 0.5, blur: 3 }),
418
- /* @__PURE__ */ jsx(ModalContent, { children: /* @__PURE__ */ jsxs(ModalBody, { children: [
419
- /* @__PURE__ */ jsxs(Tabs, { value: activeTab, onChange: (tab) => setActiveTab(tab ?? "webcomponent"), children: [
420
- /* @__PURE__ */ jsxs(TabsList, { children: [
421
- /* @__PURE__ */ jsx(TabsTab, { value: "webcomponent", children: "Webcomponent" }),
422
- /* @__PURE__ */ jsx(TabsTab, { value: "embed", children: "Embedded" })
423
- ] }),
424
- /* @__PURE__ */ jsx(TabsPanel, { value: "embed", pt: "md", children: /* @__PURE__ */ jsx(EmbedPanel, { diagram }) }),
425
- /* @__PURE__ */ jsx(TabsPanel, { value: "webcomponent", pt: "md", children: /* @__PURE__ */ jsx(WebcomponentsPanel, { diagram }) })
426
- ] }),
427
- /* @__PURE__ */ jsx(Group, { justify: "flex-end", mt: "lg", children: /* @__PURE__ */ jsx(Button, { size: "sm", onClick: onClose, children: "Close" }) })
428
- ] }) })
429
- ]
430
- }
431
- ) : null;
432
- }
433
- const Header = memo(() => {
434
- const projects = useLikeC4Projects$1(), isReactDiagramRoute = useMatches({
435
- select(matches) {
436
- return matches.some(
437
- ({ routeId }) => routeId === "/_single/view/$viewId/" || routeId === "/project/$projectId/view/$viewId/"
438
- );
439
- }
440
- }), { breakpoints } = useMantineTheme(), isTablet = useMediaQuery(`(min-width: ${breakpoints.md})`) ?? !1, [opened, { open, close }] = useDisclosure(!1);
441
- return /* @__PURE__ */ jsxs(Fragment, { children: [
442
- /* @__PURE__ */ jsx(NavigationPanel.Root, { panelPosition: "right", hideBelow: "md", children: /* @__PURE__ */ jsxs(NavigationPanel.Body, { gap: "2", children: [
443
- isReactDiagramRoute ? /* @__PURE__ */ jsxs(Fragment, { children: [
444
- /* @__PURE__ */ jsx(SelectProject, {}),
445
- projects.length <= 1 && /* @__PURE__ */ jsx(
446
- Button,
447
- {
448
- size: isTablet ? "sm" : "xs",
449
- leftSection: /* @__PURE__ */ jsx(IconShare, { size: 14 }),
450
- onClick: open,
451
- children: "Share"
452
- }
453
- ),
454
- /* @__PURE__ */ jsx(ExportButton, {})
455
- ] }) : /* @__PURE__ */ jsx(
456
- Button,
457
- {
458
- component: Link,
459
- to: "/view/$viewId/",
460
- size: isTablet ? "sm" : "xs",
461
- variant: "subtle",
462
- color: "gray",
463
- children: "Back to diagram"
464
- }
465
- ),
466
- /* @__PURE__ */ jsx(Divider, { orientation: "vertical", visibleFrom: "md" }),
467
- /* @__PURE__ */ jsx(ColorSchemeToggle, {})
468
- ] }) }),
469
- opened && /* @__PURE__ */ jsx(ShareModal, { onClose: close })
470
- ] });
471
- }), enableDownload = (params) => ({
472
- ...params,
473
- download: !0
474
- });
475
- function ExportButton() {
476
- const isInsideProject = useMatches({
477
- select: (matches) => matches.some(({ routeId }) => routeId === "/project/$projectId")
478
- });
479
- return /* @__PURE__ */ jsxs(Menu, { shadow: "md", width: 200, trigger: "click-hover", openDelay: 200, children: [
480
- /* @__PURE__ */ jsx(MenuTarget, { children: /* @__PURE__ */ jsx(
481
- Button,
482
- {
483
- variant: "subtle",
484
- size: "sm",
485
- color: "gray",
486
- px: "sm",
487
- rightSection: /* @__PURE__ */ jsx(IconChevronDown, { opacity: 0.5, size: 14 }),
488
- visibleFrom: "md",
489
- children: "Export"
490
- }
491
- ) }),
492
- /* @__PURE__ */ jsxs(MenuDropdown, { children: [
493
- /* @__PURE__ */ jsx(MenuLabel, { children: "Current view" }),
494
- /* @__PURE__ */ jsx(
495
- MenuItem,
496
- {
497
- renderRoot: (props) => /* @__PURE__ */ jsx(
498
- Link,
499
- {
500
- target: "_blank",
501
- to: isInsideProject ? "/project/$projectId/export/$viewId/" : "/export/$viewId/",
502
- search: enableDownload,
503
- ...props
504
- }
505
- ),
506
- children: "Export as .png"
507
- }
508
- ),
509
- /* @__PURE__ */ jsx(
510
- MenuItem,
511
- {
512
- renderRoot: (props) => /* @__PURE__ */ jsx(
513
- Link,
514
- {
515
- to: isInsideProject ? "/project/$projectId/view/$viewId/dot/" : "/view/$viewId/dot/",
516
- search: !0,
517
- ...props
518
- }
519
- ),
520
- children: "Export as .dot"
521
- }
522
- ),
523
- /* @__PURE__ */ jsx(
524
- MenuItem,
525
- {
526
- renderRoot: (props) => /* @__PURE__ */ jsx(
527
- Link,
528
- {
529
- to: isInsideProject ? "/project/$projectId/view/$viewId/d2" : "/view/$viewId/d2",
530
- search: !0,
531
- ...props
532
- }
533
- ),
534
- children: "Export as .d2"
535
- }
536
- ),
537
- /* @__PURE__ */ jsx(
538
- MenuItem,
539
- {
540
- renderRoot: (props) => /* @__PURE__ */ jsx(
541
- Link,
542
- {
543
- to: isInsideProject ? "/project/$projectId/view/$viewId/mmd" : "/view/$viewId/mmd",
544
- search: !0,
545
- ...props
546
- }
547
- ),
548
- children: "Export as .mmd"
549
- }
550
- ),
551
- /* @__PURE__ */ jsx(
552
- MenuItem,
553
- {
554
- renderRoot: (props) => /* @__PURE__ */ jsx(
555
- Link,
556
- {
557
- to: isInsideProject ? "/project/$projectId/view/$viewId/puml" : "/view/$viewId/puml",
558
- search: !0,
559
- ...props
560
- }
561
- ),
562
- children: "Export as .puml"
563
- }
564
- ),
565
- /* @__PURE__ */ jsx(MenuItem, { disabled: !0, children: "Export to Draw.io" }),
566
- /* @__PURE__ */ jsx(MenuItem, { disabled: !0, children: "Export to Miro" }),
567
- /* @__PURE__ */ jsx(MenuItem, { disabled: !0, children: "Export to Notion" })
568
- ] })
569
- ] });
570
- }
571
- async function downloadAsPng({
572
- pngFilename,
573
- viewport
574
- }) {
575
- try {
576
- const blob = await toBlob(viewport, {
577
- backgroundColor: "transparent",
578
- cacheBust: !0,
579
- imagePlaceholder: "data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw=="
580
- });
581
- if (!blob)
582
- throw new Error("Failed to create PNG blob");
583
- var url = URL.createObjectURL(blob), link = document.createElement("a");
584
- link.setAttribute("download", `${pngFilename}.png`), link.href = url, document.body.appendChild(link), link.click(), await new Promise((resolve) => setTimeout(resolve, 1e3)), document.body.removeChild(link), URL.revokeObjectURL(url), window.close();
585
- } catch (err) {
586
- console.error(err), window.alert("Failed to export to PNG, check the console for more details.");
587
- }
588
- }
589
- function ExportPage() {
590
- const [diagram] = useCurrentView();
591
- return useTransparentBackground(), diagram ? /* @__PURE__ */ jsx(GuardedExportPage, { diagram }) : /* @__PURE__ */ jsx("div", { children: "Loading..." });
592
- }
593
- function GuardedExportPage({ diagram }) {
594
- const {
595
- padding = 20,
596
- download = !1,
597
- dynamic
598
- } = useSearch({
599
- strict: !1
600
- }), viewportRef = useRef(null), loadingOverlayRef = useRef(null), downloadedRef = useRef(!1), bounds = pickViewBounds(diagram, dynamic), downloadDiagram = () => {
601
- const viewport = viewportRef.current;
602
- if (!download || !viewport || !diagram || downloadedRef.current)
603
- return;
604
- const loadingOverlay = loadingOverlayRef.current;
605
- loadingOverlay && (loadingOverlay.style.display = "none"), downloadedRef.current = !0, downloadAsPng({
606
- pngFilename: diagram.id,
607
- viewport
608
- });
609
- }, extraPadding = 16, width = bounds.width + padding * 2 + extraPadding, height = bounds.height + padding * 2 + extraPadding;
610
- return /* @__PURE__ */ jsxs(
611
- Box$1,
612
- {
613
- ref: viewportRef,
614
- "data-testid": "export-page",
615
- css: {
616
- position: "fixed",
617
- top: "0",
618
- left: "0",
619
- padding: "0",
620
- margin: "0",
621
- background: "transparent",
622
- overflow: "hidden",
623
- zIndex: 2
624
- },
625
- style: {
626
- marginRight: "auto",
627
- marginBottom: "auto",
628
- minWidth: width,
629
- width,
630
- minHeight: height,
631
- height
632
- },
633
- children: [
634
- download && /* @__PURE__ */ jsx(LoadingOverlay, { ref: loadingOverlayRef, visible: !0 }),
635
- /* @__PURE__ */ jsx(
636
- LikeC4Diagram,
637
- {
638
- view: diagram,
639
- fitView: !1,
640
- fitViewPadding: {
641
- top: "0px",
642
- bottom: "0px",
643
- left: "0px",
644
- right: "0px"
645
- },
646
- background: "transparent",
647
- reduceGraphics: !1,
648
- dynamicViewVariant: dynamic,
649
- className: "likec4-static-view",
650
- pannable: !1,
651
- zoomable: !1,
652
- controls: !1,
653
- enableNotations: !1,
654
- enableElementDetails: !1,
655
- enableRelationshipDetails: !1,
656
- enableRelationshipBrowser: !1,
657
- enableDynamicViewWalkthrough: !1,
658
- enableFocusMode: !1,
659
- enableSearch: !1,
660
- nodesSelectable: !1,
661
- enableElementTags: !1,
662
- onInitialized: () => {
663
- if (!viewportRef.current) {
664
- console.error("viewportRef.current is null");
665
- return;
666
- }
667
- const x = Math.round(-bounds.x + padding), y = Math.round(-bounds.y + padding);
668
- [...viewportRef.current.querySelectorAll(".react-flow__viewport")].forEach((el) => {
669
- el.style.transform = "translate(" + x + "px, " + y + "px)";
670
- }), download && window.setTimeout(downloadDiagram, 500);
671
- }
672
- }
673
- )
674
- ]
675
- }
676
- );
677
- }
678
- function EmbedPage() {
679
- const {
680
- padding = 20,
681
- dynamic
682
- } = useSearch({
683
- strict: !1
684
- }), [diagram] = useCurrentView();
685
- if (useTransparentBackground(!!diagram), !diagram)
686
- return /* @__PURE__ */ jsx("div", { children: "Loading..." });
687
- const bounds = pickViewBounds(diagram, dynamic);
688
- return /* @__PURE__ */ jsx(
689
- "div",
690
- {
691
- style: {
692
- position: "absolute",
693
- top: 0,
694
- left: "50%",
695
- boxSizing: "border-box",
696
- padding,
697
- transform: "translateX(-50%)",
698
- aspectRatio: `${bounds.width + padding * 2} / ${bounds.height + padding * 2}`,
699
- width: "100vw",
700
- maxWidth: bounds.width + padding * 2,
701
- height: "auto",
702
- maxHeight: "100vh"
703
- },
704
- children: /* @__PURE__ */ jsx(
705
- StaticLikeC4Diagram,
706
- {
707
- view: diagram,
708
- fitView: !0,
709
- background: "transparent",
710
- fitViewPadding: 0,
711
- dynamicViewVariant: dynamic,
712
- initialWidth: bounds.width,
713
- initialHeight: bounds.height
714
- }
715
- )
716
- }
717
- );
718
- }
719
- function ViewReact() {
720
- const navigate = useNavigate(), [view, setLayoutType] = useCurrentView(), model = useLikeC4Model(), { dynamic } = useSearch({
721
- from: "__root__"
722
- }), onNavigateTo = useCallbackRef((viewId) => {
723
- navigate({
724
- to: "./",
725
- viewTransition: !1,
726
- params: (current) => ({
727
- ...current,
728
- viewId
729
- }),
730
- search: !0
731
- });
732
- }), title = view ? view.title ?? view.id : "View not found", pageTitle$1 = model.project.title ?? pageTitle;
733
- if (useDocumentTitle(`${title} - ${pageTitle$1}`), !view)
734
- return /* @__PURE__ */ jsx(NotFound, {});
735
- const hasNotations = (view.notation?.nodes ?? []).length > 0;
736
- return /* @__PURE__ */ jsxs(
737
- LikeC4Diagram,
738
- {
739
- view,
740
- zoomable: !0,
741
- pannable: !0,
742
- controls: !0,
743
- fitViewPadding: {
744
- top: "70px",
745
- bottom: "32px",
746
- left: "32px",
747
- right: "32px"
748
- },
749
- showNavigationButtons: !0,
750
- enableSearch: !0,
751
- enableFocusMode: !0,
752
- enableDynamicViewWalkthrough: !0,
753
- dynamicViewVariant: dynamic,
754
- enableElementDetails: !0,
755
- enableRelationshipDetails: !0,
756
- enableRelationshipBrowser: !0,
757
- enableElementTags: !0,
758
- enableCompareWithLatest: !0,
759
- enableNotations: hasNotations,
760
- nodesSelectable: !0,
761
- onNavigateTo,
762
- onLayoutTypeChange: setLayoutType,
763
- onLogoClick: () => {
764
- navigate({
765
- to: "/"
766
- });
767
- },
768
- children: [
769
- /* @__PURE__ */ jsx(ListenForDynamicVariantChange, {}),
770
- /* @__PURE__ */ jsx(OpenRelationshipBrowserFromUrl, {})
771
- ]
772
- }
773
- );
774
- }
775
- function OpenRelationshipBrowserFromUrl() {
776
- const router = useRouter(), diagram = useDiagram(), { relationships } = useSearch({
777
- from: "__root__"
778
- }), processedRef = useRef(null), isInitializedRef = useRef(!1), isProcessingRef = useRef(Promise.resolve()), isMounted = useIsMounted(), openAndClear = (fqn) => {
779
- isProcessingRef.current = isProcessingRef.current.then(async () => {
780
- if (!(!isMounted() || processedRef.current === fqn))
781
- try {
782
- processedRef.current = fqn, diagram.openRelationshipsBrowser(fqn), await router.buildAndCommitLocation({
783
- search: (s) => {
784
- const { relationships: _, ...rest } = s;
785
- return rest;
786
- },
787
- replace: !0,
788
- viewTransition: !1
789
- });
790
- } catch (error) {
791
- console.error("Failed to open relationship browser:", error);
792
- }
793
- });
794
- }, process = () => {
795
- if (!relationships) {
796
- processedRef.current = null;
797
- return;
798
- }
799
- relationships && processedRef.current !== relationships && openAndClear(relationships);
800
- };
801
- return useOnDiagramEvent("initialized", () => {
802
- isInitializedRef.current = !0, process();
803
- }), useUpdateEffect(() => {
804
- process();
805
- }, [relationships]), null;
806
- }
807
- function ListenForDynamicVariantChange() {
808
- const router = useRouter(), dynamicViewVariant = useDiagramContext((c) => c.dynamicViewVariant);
809
- return useUpdateEffect(() => {
810
- (router.latestLocation.search.dynamic ?? "diagram") !== dynamicViewVariant && router.buildAndCommitLocation({
811
- search: (current) => ({
812
- ...current,
813
- dynamic: dynamicViewVariant
814
- }),
815
- viewTransition: !1
816
- });
817
- }, [dynamicViewVariant]), null;
818
- }
819
- function ViewEditor() {
820
- const navigate = useNavigate(), project = useCurrentProject(), [view, setLayoutType] = useCurrentView(), $likec4model = useLikeC4ModelAtom(), { dynamic } = useSearch({ strict: !1 }), onNavigateTo = useCallbackRef((viewId) => {
821
- navigate({
822
- to: "./",
823
- viewTransition: !1,
824
- params: (current) => ({
825
- ...current,
826
- viewId
827
- }),
828
- search: !0
829
- });
830
- });
831
- if (!view)
832
- return /* @__PURE__ */ jsx(NotFound, {});
833
- const hasNotations = (view.notation?.nodes ?? []).length > 0;
834
- return /* @__PURE__ */ jsx(
835
- LikeC4EditorProvider,
836
- {
837
- editor: {
838
- fetchView: (id, layout) => {
839
- const model = $likec4model.get().view(id);
840
- return layout === "auto" ? model.$view : model.$layouted;
841
- },
842
- handleChange: (viewId, change) => {
843
- const event = {
844
- projectId: project.id,
845
- viewId,
846
- change
847
- };
848
- return likec4rpc.updateView(event);
849
- }
850
- },
851
- children: /* @__PURE__ */ jsxs(
852
- LikeC4Diagram,
853
- {
854
- view,
855
- zoomable: !0,
856
- pannable: !0,
857
- controls: !0,
858
- fitViewPadding: {
859
- top: "70px",
860
- bottom: "32px",
861
- left: "50px",
862
- right: "32px"
863
- },
864
- showNavigationButtons: !0,
865
- enableNotations: isDevelopment || hasNotations,
866
- enableSearch: !0,
867
- enableDynamicViewWalkthrough: !0,
868
- enableFocusMode: !0,
869
- enableElementDetails: !0,
870
- enableRelationshipDetails: !0,
871
- enableRelationshipBrowser: !0,
872
- enableElementTags: !0,
873
- enableCompareWithLatest: !0,
874
- dynamicViewVariant: dynamic,
875
- onNavigateTo,
876
- onLayoutTypeChange: setLayoutType,
877
- onLogoClick: () => {
878
- navigate({
879
- to: "/"
880
- });
881
- },
882
- children: [
883
- /* @__PURE__ */ jsx(ListenForDynamicVariantChange, {}),
884
- /* @__PURE__ */ jsx(OpenRelationshipBrowserFromUrl, {})
885
- ]
886
- }
887
- )
888
- }
889
- );
890
- }
891
75
  const Route$7 = createFileRoute("/project/$projectId/view/$viewId")({
892
76
  component: ViewLayout,
893
77
  errorComponent: ({ error, reset }) => /* @__PURE__ */ jsx(Fallback, { error, resetErrorBoundary: reset })
@@ -912,243 +96,7 @@ const Route$6 = createFileRoute("/project/$projectId/export/$viewId")({
912
96
  component: ExportPage
913
97
  }), Route$5 = createFileRoute("/project/$projectId/embed/$viewId")({
914
98
  component: EmbedPage
915
- });
916
- function CopyButton({ text }) {
917
- return /* @__PURE__ */ jsx(CopyButton$1, { value: text, timeout: 2e3, children: ({ copied, copy }) => /* @__PURE__ */ jsx(Tooltip, { label: copied ? "Copied" : "Copy", withArrow: !0, position: "right", children: /* @__PURE__ */ jsx(ActionIcon, { color: copied ? "teal" : "gray", variant: copied ? "light" : "subtle", onClick: copy, children: copied ? /* @__PURE__ */ jsx(IconCheck, { style: { width: rem(16) } }) : /* @__PURE__ */ jsx(IconCopy, { style: { width: rem(16) } }) }) }) });
918
- }
919
- function CopyToClipboard({ text }) {
920
- return /* @__PURE__ */ jsx(Box, { pos: "absolute", top: "0", right: "0", p: "4", children: /* @__PURE__ */ jsx(CopyButton, { text }) });
921
- }
922
- const svgContainer = css({
923
- minWidth: 300,
924
- "& svg": {
925
- width: "100%",
926
- height: "auto"
927
- }
928
- }), cssScrollArea = css({
929
- height: "100%",
930
- "& .mantine-ScrollArea-viewport": {
931
- minHeight: "100%"
932
- },
933
- "& .mantine-ScrollArea-viewport > div": {
934
- minHeight: "100%",
935
- height: "100%"
936
- }
937
- }), cssCodeBlock = css({
938
- minHeight: "100%"
939
- }), viewWithTopPadding = css({
940
- height: "100%",
941
- paddingTop: "[var(--header-height)]"
942
- }), fetchFromKroki$1 = async (puml) => await (await fetch(krokiPumlSvgUrl, {
943
- method: "POST",
944
- cache: "force-cache",
945
- body: JSON.stringify({
946
- diagram_source: puml,
947
- output_format: "svg"
948
- }),
949
- headers: {
950
- "Content-Type": "application/json"
951
- }
952
- })).text();
953
- function ViewAsPuml({ pumlSource }) {
954
- const [krokiSvg, { execute }] = useAsync(fetchFromKroki$1, null);
955
- return /* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ jsxs(
956
- It,
957
- {
958
- className: viewWithTopPadding,
959
- orientation: "horizontal",
960
- children: [
961
- /* @__PURE__ */ jsx(Ot, { children: /* @__PURE__ */ jsxs(
962
- ScrollArea,
963
- {
964
- className: cssScrollArea,
965
- p: 5,
966
- styles: {
967
- viewport: {
968
- borderRadius: 6
969
- }
970
- },
971
- children: [
972
- /* @__PURE__ */ jsx(Code, { block: !0, className: cssCodeBlock, children: pumlSource }),
973
- /* @__PURE__ */ jsx(CopyToClipboard, { text: pumlSource })
974
- ]
975
- }
976
- ) }),
977
- /* @__PURE__ */ jsx(
978
- Nt,
979
- {
980
- style: {
981
- width: 10
982
- }
983
- }
984
- ),
985
- /* @__PURE__ */ jsx(Ot, { children: /* @__PURE__ */ jsxs(ScrollArea, { h: "100%", children: [
986
- krokiSvg.status !== "success" && /* @__PURE__ */ jsxs(Fragment, { children: [
987
- /* @__PURE__ */ jsx(
988
- Button,
989
- {
990
- mt: "xs",
991
- variant: "light",
992
- disabled: krokiSvg.status === "loading",
993
- onClick: () => {
994
- execute(pumlSource);
995
- },
996
- children: krokiSvg.status === "loading" ? "Loading..." : "Render with Kroki"
997
- }
998
- ),
999
- krokiSvg.status === "error" && /* @__PURE__ */ jsx(Box$1, { children: krokiSvg.error?.message })
1000
- ] }),
1001
- krokiSvg.status === "success" && /* @__PURE__ */ jsx(Box$1, { className: svgContainer, children: krokiSvg.result ? /* @__PURE__ */ jsx("div", { dangerouslySetInnerHTML: { __html: krokiSvg.result } }) : /* @__PURE__ */ jsx(Box$1, { children: "Empty result" }) })
1002
- ] }) })
1003
- ]
1004
- }
1005
- ) });
1006
- }
1007
- const renderSvg = async (viewId, diagram) => {
1008
- const { default: mermaid } = await import("https://cdn.jsdelivr.net/npm/mermaid@11.12/dist/mermaid.esm.min.mjs");
1009
- mermaid.initialize({
1010
- theme: "dark"
1011
- });
1012
- const { svg } = await mermaid.render(viewId, diagram);
1013
- return svg;
1014
- };
1015
- function ViewAsMmd({ viewId, mmdSource }) {
1016
- const [mmdSvg, { execute }] = useAsync(renderSvg, null);
1017
- return useEffect(() => {
1018
- execute(viewId, mmdSource);
1019
- }, [mmdSource]), /* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ jsxs(
1020
- It,
1021
- {
1022
- className: viewWithTopPadding,
1023
- orientation: "horizontal",
1024
- children: [
1025
- /* @__PURE__ */ jsx(Ot, { children: /* @__PURE__ */ jsxs(
1026
- ScrollArea,
1027
- {
1028
- className: cssScrollArea,
1029
- p: 5,
1030
- styles: {
1031
- viewport: {
1032
- borderRadius: 6
1033
- }
1034
- },
1035
- children: [
1036
- /* @__PURE__ */ jsx(Code, { block: !0, className: cssCodeBlock, children: mmdSource }),
1037
- /* @__PURE__ */ jsx(CopyToClipboard, { text: mmdSource })
1038
- ]
1039
- }
1040
- ) }),
1041
- /* @__PURE__ */ jsx(
1042
- Nt,
1043
- {
1044
- style: {
1045
- width: 10
1046
- }
1047
- }
1048
- ),
1049
- /* @__PURE__ */ jsx(Ot, { children: /* @__PURE__ */ jsx(ScrollArea, { h: "100%", children: mmdSvg.result && /* @__PURE__ */ jsx(Box$1, { className: svgContainer, dangerouslySetInnerHTML: { __html: mmdSvg.result } }) }) })
1050
- ]
1051
- }
1052
- ) });
1053
- }
1054
- function ViewAsDot({ dot, dotSvg }) {
1055
- return /* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ jsxs(It, { className: viewWithTopPadding, children: [
1056
- /* @__PURE__ */ jsx(Ot, { children: /* @__PURE__ */ jsxs(
1057
- ScrollArea,
1058
- {
1059
- className: cssScrollArea,
1060
- p: 5,
1061
- styles: {
1062
- viewport: {
1063
- borderRadius: 6
1064
- }
1065
- },
1066
- children: [
1067
- /* @__PURE__ */ jsx(Code, { block: !0, className: cssCodeBlock, children: dot }),
1068
- /* @__PURE__ */ jsx(CopyToClipboard, { text: dot })
1069
- ]
1070
- }
1071
- ) }),
1072
- /* @__PURE__ */ jsx(
1073
- Nt,
1074
- {
1075
- style: {
1076
- width: 10
1077
- }
1078
- }
1079
- ),
1080
- /* @__PURE__ */ jsx(Ot, { children: /* @__PURE__ */ jsx(ScrollArea, { h: "100%", children: /* @__PURE__ */ jsx("div", { className: svgContainer, dangerouslySetInnerHTML: { __html: dotSvg } }) }) })
1081
- ] }) });
1082
- }
1083
- const fetchFromKroki = async (d2) => await (await fetch(krokiD2SvgUrl, {
1084
- method: "POST",
1085
- cache: "force-cache",
1086
- body: JSON.stringify({
1087
- diagram_source: d2,
1088
- // diagram_options: {
1089
- // theme: 'colorblind-clear'
1090
- // },
1091
- output_format: "svg"
1092
- }),
1093
- headers: {
1094
- "Content-Type": "application/json"
1095
- }
1096
- })).text();
1097
- function ViewAsD2({ d2Source }) {
1098
- const [krokiSvg, { execute }] = useAsync(fetchFromKroki, null);
1099
- return /* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ jsxs(
1100
- It,
1101
- {
1102
- className: viewWithTopPadding,
1103
- orientation: "horizontal",
1104
- children: [
1105
- /* @__PURE__ */ jsx(Ot, { children: /* @__PURE__ */ jsxs(
1106
- ScrollArea,
1107
- {
1108
- className: cssScrollArea,
1109
- p: 5,
1110
- styles: {
1111
- viewport: {
1112
- borderRadius: 6
1113
- }
1114
- },
1115
- children: [
1116
- /* @__PURE__ */ jsx(Code, { block: !0, className: cssCodeBlock, children: d2Source }),
1117
- /* @__PURE__ */ jsx(CopyToClipboard, { text: d2Source })
1118
- ]
1119
- }
1120
- ) }),
1121
- /* @__PURE__ */ jsx(
1122
- Nt,
1123
- {
1124
- style: {
1125
- width: 10
1126
- }
1127
- }
1128
- ),
1129
- /* @__PURE__ */ jsx(Ot, { children: /* @__PURE__ */ jsxs(ScrollArea, { h: "100%", children: [
1130
- krokiSvg.status !== "success" && /* @__PURE__ */ jsxs(Fragment, { children: [
1131
- /* @__PURE__ */ jsx(
1132
- Button,
1133
- {
1134
- mt: "xs",
1135
- variant: "light",
1136
- disabled: krokiSvg.status === "loading",
1137
- onClick: () => {
1138
- execute(d2Source);
1139
- },
1140
- children: krokiSvg.status === "loading" ? "Loading..." : "Render with Kroki"
1141
- }
1142
- ),
1143
- krokiSvg.status === "error" && /* @__PURE__ */ jsx(Box$1, { children: krokiSvg.error?.message })
1144
- ] }),
1145
- krokiSvg.status === "success" && /* @__PURE__ */ jsx(Box$1, { className: svgContainer, children: krokiSvg.result ? /* @__PURE__ */ jsx("div", { dangerouslySetInnerHTML: { __html: krokiSvg.result } }) : /* @__PURE__ */ jsx(Box$1, { children: "Empty result" }) })
1146
- ] }) })
1147
- ]
1148
- }
1149
- ) });
1150
- }
1151
- const Route$4 = createFileRoute("/project/$projectId/view/$viewId/")({
99
+ }), Route$4 = createFileRoute("/project/$projectId/view/$viewId/")({
1152
100
  component: isRpcAvailable ? ViewEditor : ViewReact
1153
101
  }), Route$3 = createFileRoute("/project/$projectId/view/$viewId/puml")({
1154
102
  component: Page$3,
@@ -1227,12 +175,7 @@ function Page() {
1227
175
  return /* @__PURE__ */ jsx(ViewAsD2, { d2Source: source });
1228
176
  }
1229
177
  export {
1230
- AdHocViewEditor as A,
1231
- ExportPage as E,
1232
- Header as H,
1233
- LikeC4IconRendererContext as L,
1234
178
  Route$a as R,
1235
- ViewOutlet as V,
1236
179
  Route$9 as a,
1237
180
  Route$8 as b,
1238
181
  Route$7 as c,
@@ -1242,14 +185,5 @@ export {
1242
185
  Route$3 as g,
1243
186
  Route$2 as h,
1244
187
  Route$1 as i,
1245
- Route as j,
1246
- LikeC4ModelContext as k,
1247
- EmbedPage as l,
1248
- ViewEditor as m,
1249
- ViewReact as n,
1250
- ViewAsPuml as o,
1251
- ViewAsMmd as p,
1252
- ViewAsDot as q,
1253
- ViewAsD2 as r,
1254
- useLikeC4Views as u
188
+ Route as j
1255
189
  };