@crediblemark/build 0.25.6 → 0.25.8

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 (59) hide show
  1. package/dist/ArrayField-HYHS4HCO.mjs +17 -0
  2. package/dist/{ArrayField-PAJW74AC.css → ArrayField-MCFJLKAL.css} +15 -15
  3. package/dist/{Editor-Y342RWPN.css → Editor-CVT4RKSU.css} +7 -7
  4. package/dist/{Editor-OFA3KX3N.mjs → Editor-P3UUWNSZ.mjs} +9 -11
  5. package/dist/ObjectField-4N5XWAFL.mjs +17 -0
  6. package/dist/{ObjectField-WACQHQ4N.css → ObjectField-YPHZU7G2.css} +15 -15
  7. package/dist/{Render-HVM2KISU.css → Render-DOE2LXKX.css} +1 -1
  8. package/dist/{Render-5WYR4VZX.mjs → Render-I6PZ5MEA.mjs} +1 -1
  9. package/dist/{actions-LaZpJ1KE.d.mts → actions-CKSDxt4l.d.mts} +1 -1
  10. package/dist/{actions-LaZpJ1KE.d.ts → actions-CKSDxt4l.d.ts} +1 -1
  11. package/dist/{chunk-QHJGER7I.mjs → chunk-44PQTFGV.mjs} +7 -9
  12. package/dist/{chunk-STIUFJT2.mjs → chunk-AZFZRLP7.mjs} +12 -12
  13. package/dist/{chunk-JX7LICWE.mjs → chunk-E4F5M5JH.mjs} +2 -2
  14. package/dist/chunk-HHKM5MBJ.mjs +3163 -0
  15. package/dist/{chunk-H6RPI3T6.mjs → chunk-ISXFLTBM.mjs} +1 -1
  16. package/dist/{chunk-MZXW5F5R.mjs → chunk-KN26YZZJ.mjs} +286 -131
  17. package/dist/chunk-MWCFPGI6.mjs +4807 -0
  18. package/dist/{chunk-64A37UUC.mjs → chunk-O44M27KT.mjs} +442 -7
  19. package/dist/{chunk-XAD7XPP2.mjs → chunk-P2AZFZ7Q.mjs} +3 -3
  20. package/dist/{chunk-SLKHXT3Q.mjs → chunk-PFHKXXSV.mjs} +1 -1
  21. package/dist/{chunk-RUJOMPX6.mjs → chunk-S32JZ2HU.mjs} +1 -1
  22. package/dist/{chunk-KAOWYQIB.mjs → chunk-T2LBDQLG.mjs} +12 -12
  23. package/dist/{chunk-4NZUDTR6.mjs → chunk-XLRMLBFR.mjs} +1 -1
  24. package/dist/{chunk-WSTUSWZT.mjs → chunk-Z7DDX2XU.mjs} +2 -2
  25. package/dist/{full-ECZCK3RE.mjs → full-3VRJOFG5.mjs} +6 -8
  26. package/dist/{full-PLJRDIMB.css → full-C7RVGAUA.css} +6 -6
  27. package/dist/{index-CD3PszvP.d.mts → index-Ds4Dkkyr.d.mts} +1 -1
  28. package/dist/{index-Bj2x5pZ7.d.ts → index-DwajIHZf.d.ts} +1 -1
  29. package/dist/index.css +231 -43
  30. package/dist/index.d.mts +8 -40
  31. package/dist/index.d.ts +8 -40
  32. package/dist/index.js +1306 -649
  33. package/dist/index.mjs +26 -26
  34. package/dist/internal.d.mts +2 -2
  35. package/dist/internal.d.ts +2 -2
  36. package/dist/internal.mjs +1 -2
  37. package/dist/{loaded-FY2TCG5Y.css → loaded-4FAPBCAU.css} +1 -1
  38. package/dist/{loaded-NRHNHJPM.mjs → loaded-C2JGMUXV.mjs} +3 -5
  39. package/dist/{loaded-5D7VRSXM.mjs → loaded-FJHWTGH6.mjs} +3 -5
  40. package/dist/{loaded-3MKTRGL5.mjs → loaded-NTEK7RT3.mjs} +3 -5
  41. package/dist/no-external.css +225 -39
  42. package/dist/no-external.d.mts +4 -4
  43. package/dist/no-external.d.ts +4 -4
  44. package/dist/no-external.js +1306 -649
  45. package/dist/no-external.mjs +26 -26
  46. package/dist/rsc.css +1421 -1
  47. package/dist/rsc.d.mts +2 -2
  48. package/dist/rsc.d.ts +2 -2
  49. package/dist/rsc.js +10328 -1011
  50. package/dist/rsc.mjs +21 -4
  51. package/dist/{walk-tree-BO8uRNcW.d.mts → walk-tree-B_jHFa3L.d.mts} +39 -2
  52. package/dist/{walk-tree-BEw6kTXm.d.ts → walk-tree-DHMRjk5Z.d.ts} +39 -2
  53. package/package.json +1 -1
  54. package/dist/ArrayField-PGZLQW7G.mjs +0 -19
  55. package/dist/ObjectField-N7ES6H3B.mjs +0 -19
  56. package/dist/chunk-7LXZOPYT.mjs +0 -445
  57. package/dist/chunk-HIE6KXP6.mjs +0 -455
  58. package/dist/chunk-SMAWAXVX.mjs +0 -139
  59. package/dist/chunk-W7LED3JG.mjs +0 -6890
@@ -0,0 +1,4807 @@
1
+ import {
2
+ Drawer,
3
+ DropZoneEditPure,
4
+ DropZoneProvider,
5
+ DropZonePure,
6
+ DropZoneRenderPure,
7
+ SlotRender,
8
+ ZoneStoreContext,
9
+ ZoneStoreProvider,
10
+ dragListenerContext,
11
+ getFrame,
12
+ getSelectorForId,
13
+ renderContext,
14
+ useRichtextProps,
15
+ useSlots
16
+ } from "./chunk-HHKM5MBJ.mjs";
17
+ import {
18
+ collisionStore,
19
+ useSensors
20
+ } from "./chunk-44PQTFGV.mjs";
21
+ import {
22
+ AutoFieldPrivate,
23
+ Button,
24
+ Heading,
25
+ fieldContextStore,
26
+ useContextStore,
27
+ useSafeId
28
+ } from "./chunk-T2LBDQLG.mjs";
29
+ import {
30
+ IconButton,
31
+ Loader
32
+ } from "./chunk-AZFZRLP7.mjs";
33
+ import {
34
+ Box,
35
+ ChartColumn,
36
+ Check,
37
+ ChevronDown,
38
+ ChevronRight,
39
+ ChevronUp,
40
+ CircleCheck,
41
+ Code,
42
+ Copy,
43
+ CreditCard,
44
+ Expand,
45
+ ExternalLink,
46
+ Eye,
47
+ FileText,
48
+ Image,
49
+ Inbox,
50
+ Info,
51
+ Layers,
52
+ LayoutDashboard,
53
+ LayoutGrid,
54
+ LayoutTemplate,
55
+ List,
56
+ Maximize2,
57
+ Megaphone,
58
+ Minimize2,
59
+ Monitor,
60
+ Moon,
61
+ PanelLeft,
62
+ PanelRight,
63
+ Quote,
64
+ RectangleEllipsis,
65
+ Redo2,
66
+ Search,
67
+ Settings,
68
+ Shapes,
69
+ Smartphone,
70
+ Sun,
71
+ Tablet,
72
+ ToyBrick,
73
+ Type,
74
+ Undo2,
75
+ X,
76
+ Zap,
77
+ ZoomIn,
78
+ ZoomOut,
79
+ appStoreContext,
80
+ createAppStore,
81
+ defaultAppState,
82
+ defaultViewports,
83
+ getBox,
84
+ monitorHotkeys,
85
+ useAppStore,
86
+ useAppStoreApi,
87
+ useHotkey,
88
+ useMonitorHotkeys,
89
+ useRegisterFieldsSlice,
90
+ useRegisterHistorySlice,
91
+ useRegisterPermissionsSlice,
92
+ useResetAutoZoom
93
+ } from "./chunk-KN26YZZJ.mjs";
94
+ import {
95
+ get_class_name_factory_default
96
+ } from "./chunk-BFHV72KK.mjs";
97
+ import {
98
+ generateId,
99
+ getItem,
100
+ insertAction,
101
+ makeStatePublic,
102
+ populateIds,
103
+ rootAreaId,
104
+ rootDroppableId,
105
+ rootZone,
106
+ toComponent,
107
+ walkAppState
108
+ } from "./chunk-O44M27KT.mjs";
109
+
110
+ // types/API/Overrides.ts
111
+ var overrideKeys = [
112
+ "header",
113
+ "headerActions",
114
+ "fields",
115
+ "fieldLabel",
116
+ "drawer",
117
+ "drawerItem",
118
+ "componentOverlay",
119
+ "outline",
120
+ "credbuild",
121
+ "preview"
122
+ ];
123
+
124
+ // components/Render/index.tsx
125
+ import { useMemo } from "react";
126
+
127
+ // components/HtmlModeRender/index.tsx
128
+ import { useId, useState, useEffect, useRef } from "react";
129
+ import { jsx } from "react/jsx-runtime";
130
+ var HtmlModeRender = ({
131
+ htmlCode,
132
+ isEditing
133
+ }) => {
134
+ const id = useId().replace(/:/g, "");
135
+ const [iframeHeight, setIframeHeight] = useState("100%");
136
+ const divRef = useRef(null);
137
+ useEffect(() => {
138
+ if (!isEditing) return;
139
+ const handleMessage = (event) => {
140
+ if (event.data && event.data.type === "resize-iframe" && event.data.id === id) {
141
+ setIframeHeight(`${event.data.height}px`);
142
+ }
143
+ };
144
+ window.addEventListener("message", handleMessage);
145
+ return () => window.removeEventListener("message", handleMessage);
146
+ }, [id, isEditing]);
147
+ useEffect(() => {
148
+ if (isEditing || !divRef.current || !htmlCode) return;
149
+ const scripts = divRef.current.querySelectorAll("script");
150
+ scripts.forEach((script) => {
151
+ const newScript = document.createElement("script");
152
+ Array.from(script.attributes).forEach(
153
+ (attr) => newScript.setAttribute(attr.name, attr.value)
154
+ );
155
+ newScript.appendChild(document.createTextNode(script.innerHTML));
156
+ script.parentNode?.replaceChild(newScript, script);
157
+ });
158
+ }, [htmlCode, isEditing]);
159
+ if (!htmlCode) {
160
+ return /* @__PURE__ */ jsx("div", { style: { padding: 48, textAlign: "center", color: "#666" }, children: "Belum ada kode HTML yang ditempel." });
161
+ }
162
+ if (isEditing) {
163
+ const resizeScript = `
164
+ <script>
165
+ function sendHeight() {
166
+ const height = document.documentElement.scrollHeight || document.body.scrollHeight;
167
+ window.parent.postMessage({ type: 'resize-iframe', id: '${id}', height: height }, '*');
168
+ }
169
+ window.addEventListener('load', sendHeight);
170
+ window.addEventListener('resize', sendHeight);
171
+
172
+ if (window.ResizeObserver) {
173
+ new ResizeObserver(sendHeight).observe(document.body);
174
+ } else {
175
+ setInterval(sendHeight, 1000);
176
+ }
177
+ </script>
178
+ `;
179
+ const needsTailwind = htmlCode.includes("cdn.tailwindcss.com") || htmlCode.includes("tailwindcss") || /\b(bg-|text-|p[xy]?[-0-9]|m[xy]?[-0-9]|flex|grid|border-|rounded-|shadow-|justify-|items-|gap-|relative|absolute|hidden|w-|h-|leading-|tracking-|font-|transition|duration-|ease-|hover:|focus:|sm:|md:|lg:|xl:)/.test(
180
+ htmlCode
181
+ );
182
+ const isStandalone = htmlCode.includes("<html") || htmlCode.includes("<!DOCTYPE") || htmlCode.includes("<body") || htmlCode.includes("<head>");
183
+ let srcDoc = "";
184
+ if (isStandalone) {
185
+ let processed = htmlCode;
186
+ if (processed.includes("</body>")) {
187
+ processed = processed.replace("</body>", `${resizeScript}</body>`);
188
+ } else {
189
+ processed = processed + resizeScript;
190
+ }
191
+ if (needsTailwind && !processed.includes("cdn.tailwindcss.com") && !processed.includes("tailwindcss")) {
192
+ if (processed.includes("</head>")) {
193
+ processed = processed.replace(
194
+ "</head>",
195
+ `<script src="https://cdn.tailwindcss.com"></script></head>`
196
+ );
197
+ } else if (processed.includes("<head>")) {
198
+ processed = processed.replace(
199
+ "<head>",
200
+ `<head><script src="https://cdn.tailwindcss.com"></script>`
201
+ );
202
+ } else {
203
+ processed = `<script src="https://cdn.tailwindcss.com"></script>` + processed;
204
+ }
205
+ }
206
+ srcDoc = processed;
207
+ } else {
208
+ srcDoc = `
209
+ <!DOCTYPE html>
210
+ <html>
211
+ <head>
212
+ ${needsTailwind ? `<script src="https://cdn.tailwindcss.com"></script>` : ""}
213
+ <style>
214
+ *, *::before, *::after { box-sizing: border-box; }
215
+ body {
216
+ margin: 0;
217
+ padding: 0;
218
+ font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
219
+ }
220
+ img, iframe, video {
221
+ max-width: 100%;
222
+ }
223
+ </style>
224
+ </head>
225
+ <body>
226
+ ${htmlCode}
227
+ ${resizeScript}
228
+ </body>
229
+ </html>
230
+ `;
231
+ }
232
+ return /* @__PURE__ */ jsx("div", { style: { width: "100%" }, children: /* @__PURE__ */ jsx(
233
+ "iframe",
234
+ {
235
+ srcDoc,
236
+ sandbox: "allow-scripts",
237
+ title: "Html Mode Sandboxed Canvas",
238
+ loading: "lazy",
239
+ style: {
240
+ height: iframeHeight,
241
+ border: "none",
242
+ width: "100%",
243
+ display: "block",
244
+ background: "transparent"
245
+ }
246
+ }
247
+ ) });
248
+ }
249
+ return /* @__PURE__ */ jsx(
250
+ "div",
251
+ {
252
+ ref: divRef,
253
+ dangerouslySetInnerHTML: { __html: htmlCode },
254
+ style: { width: "100%" }
255
+ }
256
+ );
257
+ };
258
+
259
+ // components/Render/index.tsx
260
+ import { jsx as jsx2 } from "react/jsx-runtime";
261
+ function Render({
262
+ config,
263
+ data,
264
+ metadata = {}
265
+ }) {
266
+ const defaultedData = {
267
+ ...data,
268
+ root: data.root || {},
269
+ content: data.content || []
270
+ };
271
+ const rootProps = "props" in defaultedData.root ? defaultedData.root.props : defaultedData.root;
272
+ const title = rootProps?.title || "";
273
+ if (rootProps?.mode === "html") {
274
+ return /* @__PURE__ */ jsx2(renderContext.Provider, { value: { config, data: defaultedData, metadata }, children: /* @__PURE__ */ jsx2(HtmlModeRender, { htmlCode: rootProps.htmlCode, isEditing: false }) });
275
+ }
276
+ const pageProps = {
277
+ ...rootProps,
278
+ credbuild: {
279
+ renderDropZone: DropZonePure,
280
+ isEditing: false,
281
+ dragRef: null,
282
+ metadata
283
+ },
284
+ title,
285
+ editMode: false,
286
+ id: "credbuild-root"
287
+ };
288
+ const propsWithSlots = useSlots(
289
+ config,
290
+ { type: "root", props: pageProps },
291
+ (props) => /* @__PURE__ */ jsx2(SlotRender, { ...props, config, metadata })
292
+ );
293
+ const richtextProps = useRichtextProps(config.root?.fields, pageProps);
294
+ const nextContextValue = useMemo(
295
+ () => ({
296
+ mode: "render",
297
+ depth: 0
298
+ }),
299
+ []
300
+ );
301
+ if (config.root?.render) {
302
+ return /* @__PURE__ */ jsx2(renderContext.Provider, { value: { config, data: defaultedData, metadata }, children: /* @__PURE__ */ jsx2(DropZoneProvider, { value: nextContextValue, children: /* @__PURE__ */ jsx2(config.root.render, { ...propsWithSlots, ...richtextProps, children: /* @__PURE__ */ jsx2(DropZoneRenderPure, { zone: rootZone }) }) }) });
303
+ }
304
+ return /* @__PURE__ */ jsx2(renderContext.Provider, { value: { config, data: defaultedData, metadata }, children: /* @__PURE__ */ jsx2(DropZoneProvider, { value: nextContextValue, children: /* @__PURE__ */ jsx2(DropZoneRenderPure, { zone: rootZone }) }) });
305
+ }
306
+
307
+ // lib/use-credbuild.ts
308
+ import { createContext, useContext, useEffect as useEffect2, useState as useState2 } from "react";
309
+ import { createStore, useStore } from "zustand";
310
+
311
+ // lib/data/resolve-and-replace-data.ts
312
+ async function resolveAndReplaceData(currentData, getState, trigger = "force") {
313
+ const resolvedResult = await getState().resolveComponentData(
314
+ currentData,
315
+ trigger
316
+ );
317
+ if (!resolvedResult.didChange) return;
318
+ const itemSelector = getSelectorForId(
319
+ getState().state,
320
+ resolvedResult.node.props.id
321
+ );
322
+ if (!itemSelector) {
323
+ console.warn(
324
+ `Warning: Could not find component with id "${currentData.props.id}" to resolve its data. Component may have been removed or the id is invalid.`
325
+ );
326
+ return;
327
+ }
328
+ getState().dispatch({
329
+ type: "replace",
330
+ data: toComponent(resolvedResult.node),
331
+ destinationIndex: itemSelector.index,
332
+ destinationZone: itemSelector.zone
333
+ });
334
+ }
335
+
336
+ // lib/data/resolve-data-by-id.ts
337
+ async function resolveDataById(id, getState, trigger) {
338
+ const node = getState().state.indexes.nodes[id];
339
+ if (!node) {
340
+ console.warn(
341
+ `Warning: Could not find component with id "${id}" to resolve its data. Component may have been removed or the id is invalid.`
342
+ );
343
+ return;
344
+ }
345
+ await resolveAndReplaceData(node.data, getState, trigger);
346
+ }
347
+
348
+ // lib/data/resolve-data-by-selector.ts
349
+ async function resolveDataBySelector(selector, getState, trigger) {
350
+ const item = getItem(selector, getState().state);
351
+ if (!item) {
352
+ console.warn(
353
+ `Warning: Could not find component for selector "${JSON.stringify(
354
+ selector
355
+ )}" to resolve its data. Component may have been removed or the selector is invalid.`
356
+ );
357
+ return;
358
+ }
359
+ const itemAsComponent = toComponent(item);
360
+ await resolveAndReplaceData(itemAsComponent, getState, trigger);
361
+ }
362
+
363
+ // lib/use-credbuild.ts
364
+ var generateUseCredBuild = (store, getState) => {
365
+ const history = {
366
+ back: store.history.back,
367
+ forward: store.history.forward,
368
+ setHistories: store.history.setHistories,
369
+ setHistoryIndex: store.history.setHistoryIndex,
370
+ hasPast: store.history.hasPast(),
371
+ hasFuture: store.history.hasFuture(),
372
+ histories: store.history.histories,
373
+ index: store.history.index
374
+ };
375
+ const storeData = {
376
+ appState: makeStatePublic(store.state),
377
+ config: store.config,
378
+ dispatch: store.dispatch,
379
+ getPermissions: store.permissions.getPermissions,
380
+ refreshPermissions: store.permissions.refreshPermissions,
381
+ resolveDataById: (id, trigger) => resolveDataById(id, getState, trigger),
382
+ resolveDataBySelector: (selector, trigger) => resolveDataBySelector(selector, getState, trigger),
383
+ history,
384
+ selectedItem: store.selectedItem || null,
385
+ getItemBySelector: (selector) => getItem(selector, store.state),
386
+ getItemById: (id) => store.state.indexes.nodes[id].data,
387
+ getSelectorForId: (id) => getSelectorForId(store.state, id),
388
+ getParentById: (id) => {
389
+ const node = store.state.indexes.nodes[id];
390
+ const parentId = node.parentId;
391
+ if (parentId === null) return;
392
+ const parentNode = store.state.indexes.nodes[parentId];
393
+ if (!parentNode) return;
394
+ return parentNode.data;
395
+ }
396
+ };
397
+ storeData.__private = {
398
+ appState: store.state
399
+ };
400
+ return storeData;
401
+ };
402
+ var UseCredBuildStoreContext = createContext(
403
+ null
404
+ );
405
+ var convertToPickedStore = (store) => {
406
+ return {
407
+ state: store.state,
408
+ config: store.config,
409
+ dispatch: store.dispatch,
410
+ permissions: store.permissions,
411
+ history: store.history,
412
+ selectedItem: store.selectedItem
413
+ };
414
+ };
415
+ var useRegisterUseCredBuildStore = (appStore) => {
416
+ const [useCredBuildStore] = useState2(
417
+ () => createStore(
418
+ () => generateUseCredBuild(
419
+ convertToPickedStore(appStore.getState()),
420
+ appStore.getState
421
+ )
422
+ )
423
+ );
424
+ useEffect2(() => {
425
+ return appStore.subscribe(
426
+ (store) => convertToPickedStore(store),
427
+ (pickedStore) => {
428
+ useCredBuildStore.setState(
429
+ generateUseCredBuild(pickedStore, appStore.getState)
430
+ );
431
+ }
432
+ );
433
+ }, [appStore, useCredBuildStore]);
434
+ return useCredBuildStore;
435
+ };
436
+ function createUseCredBuild() {
437
+ return function useCredBuild2(selector) {
438
+ const useCredBuildApi = useContext(UseCredBuildStoreContext);
439
+ if (!useCredBuildApi) {
440
+ throw new Error("useCredBuild must be used inside <CredBuild>.");
441
+ }
442
+ const result = useStore(
443
+ useCredBuildApi,
444
+ selector ?? ((s) => s)
445
+ );
446
+ return result;
447
+ };
448
+ }
449
+ function useCredBuild() {
450
+ useEffect2(() => {
451
+ console.warn(
452
+ "You're using the `useCredBuild` method without a selector, which may cause unnecessary re-renders. Replace with `createUseCredBuild` and provide a selector for improved performance."
453
+ );
454
+ }, []);
455
+ return createUseCredBuild()((s) => s);
456
+ }
457
+ function useGetCredBuild() {
458
+ const useCredBuildApi = useContext(UseCredBuildStoreContext);
459
+ if (!useCredBuildApi) {
460
+ throw new Error("useCredBuildGet must be used inside <CredBuild>.");
461
+ }
462
+ return useCredBuildApi.getState;
463
+ }
464
+
465
+ // lib/use-component-list.tsx
466
+ import { useEffect as useEffect4, useState as useState3 } from "react";
467
+
468
+ // css-module:/home/runner/work/credbuild/credbuild/components/ComponentList/styles.module.css#css-module
469
+ var styles_module_default = { "ComponentList": "_ComponentList_10tqo_1", "ComponentList--isExpanded": "_ComponentList--isExpanded_10tqo_5", "ComponentList-content": "_ComponentList-content_10tqo_9", "ComponentList-title": "_ComponentList-title_10tqo_17", "ComponentList-titleIcon": "_ComponentList-titleIcon_10tqo_53" };
470
+
471
+ // components/ComponentList/index.tsx
472
+ import { useEffect as useEffect3, memo } from "react";
473
+ import { jsx as jsx3, jsxs } from "react/jsx-runtime";
474
+ var getClassName = get_class_name_factory_default("ComponentList", styles_module_default);
475
+ var ComponentListItem = memo(({
476
+ name,
477
+ label
478
+ }) => {
479
+ const overrides = useAppStore((s) => s.overrides);
480
+ const canInsert = useAppStore(
481
+ (s) => s.permissions.getPermissions({
482
+ type: name
483
+ }).insert
484
+ );
485
+ useEffect3(() => {
486
+ if (overrides.componentItem) {
487
+ console.warn(
488
+ "The `componentItem` override has been deprecated and renamed to `drawerItem`"
489
+ );
490
+ }
491
+ }, [overrides]);
492
+ return /* @__PURE__ */ jsx3(Drawer.Item, { label, name, isDragDisabled: !canInsert, children: overrides.componentItem ?? overrides.drawerItem });
493
+ });
494
+ var ComponentList = ({
495
+ children,
496
+ title,
497
+ id
498
+ }) => {
499
+ const config = useAppStore((s) => s.config);
500
+ const expanded = useAppStore((s) => s.state.ui.componentList[id]?.expanded ?? true);
501
+ const appStoreApi = useAppStoreApi();
502
+ const components = Object.keys(config.components);
503
+ return /* @__PURE__ */ jsxs("div", { className: getClassName({ isExpanded: expanded }), children: [
504
+ title && /* @__PURE__ */ jsxs(
505
+ "button",
506
+ {
507
+ type: "button",
508
+ className: getClassName("title"),
509
+ "aria-expanded": expanded,
510
+ "aria-controls": `${id}-content`,
511
+ onClick: () => {
512
+ const currentComponentList = appStoreApi.getState().state.ui.componentList;
513
+ appStoreApi.getState().setUi({
514
+ componentList: {
515
+ ...currentComponentList,
516
+ [id]: {
517
+ ...currentComponentList[id],
518
+ expanded: !expanded
519
+ }
520
+ }
521
+ });
522
+ },
523
+ children: [
524
+ /* @__PURE__ */ jsxs("div", { style: { display: "flex", alignItems: "center", gap: "8px" }, children: [
525
+ id.toLowerCase().includes("hero") && /* @__PURE__ */ jsx3(LayoutTemplate, { size: 12, strokeWidth: 2.5 }),
526
+ id.toLowerCase().includes("content") && /* @__PURE__ */ jsx3(FileText, { size: 12, strokeWidth: 2.5 }),
527
+ id.toLowerCase().includes("marketing") && /* @__PURE__ */ jsx3(Megaphone, { size: 12, strokeWidth: 2.5 }),
528
+ id.toLowerCase().includes("layout") && /* @__PURE__ */ jsx3(Box, { size: 12, strokeWidth: 2.5 }),
529
+ id.toLowerCase().includes("basic") && /* @__PURE__ */ jsx3(Settings, { size: 12, strokeWidth: 2.5 }),
530
+ id === "other" && /* @__PURE__ */ jsx3(Layers, { size: 12, strokeWidth: 2.5 }),
531
+ /* @__PURE__ */ jsx3("div", { children: title?.replace(/[\u2600-\u27BF]|[\uD83C][\uDF00-\uDFFF]|[\uD83D][\uDC00-\uDE4F]|[\uD83D][\uDE80-\uDEFF]/g, "").trim() })
532
+ ] }),
533
+ /* @__PURE__ */ jsx3("div", { className: getClassName("titleIcon"), children: expanded ? /* @__PURE__ */ jsx3(ChevronUp, { size: 12 }) : /* @__PURE__ */ jsx3(ChevronDown, { size: 12 }) })
534
+ ]
535
+ }
536
+ ),
537
+ /* @__PURE__ */ jsx3(
538
+ "div",
539
+ {
540
+ id: `${id}-content`,
541
+ className: getClassName("content"),
542
+ style: {
543
+ overflow: "visible",
544
+ display: expanded ? "block" : "none"
545
+ },
546
+ children: /* @__PURE__ */ jsx3(Drawer, { children: children || components.map((componentKey, i) => {
547
+ return /* @__PURE__ */ jsx3(
548
+ ComponentListItem,
549
+ {
550
+ label: config.components[componentKey]["label"] ?? componentKey,
551
+ name: componentKey,
552
+ index: i
553
+ },
554
+ componentKey
555
+ );
556
+ }) })
557
+ }
558
+ )
559
+ ] });
560
+ };
561
+ ComponentList.Item = ComponentListItem;
562
+
563
+ // lib/use-component-list.tsx
564
+ import { jsx as jsx4 } from "react/jsx-runtime";
565
+ var useComponentList = () => {
566
+ const [componentList, setComponentList] = useState3();
567
+ const config = useAppStore((s) => s.config);
568
+ const uiComponentList = useAppStore((s) => s.state.ui.componentList);
569
+ useEffect4(() => {
570
+ if (Object.keys(uiComponentList).length > 0) {
571
+ const matchedComponents = [];
572
+ let _componentList;
573
+ _componentList = Object.entries(uiComponentList).map(
574
+ ([categoryKey, category]) => {
575
+ if (!category.components) {
576
+ return null;
577
+ }
578
+ category.components.forEach((componentName) => {
579
+ matchedComponents.push(componentName);
580
+ });
581
+ if (category.visible === false) {
582
+ return null;
583
+ }
584
+ return /* @__PURE__ */ jsx4(
585
+ ComponentList,
586
+ {
587
+ id: categoryKey,
588
+ title: category.title || categoryKey,
589
+ children: category.components.map((componentName, i) => {
590
+ const componentConf = config.components[componentName] || {};
591
+ return /* @__PURE__ */ jsx4(
592
+ ComponentList.Item,
593
+ {
594
+ label: componentConf["label"] ?? componentName,
595
+ name: componentName,
596
+ index: i
597
+ },
598
+ componentName
599
+ );
600
+ })
601
+ },
602
+ categoryKey
603
+ );
604
+ }
605
+ );
606
+ const remainingComponents = Object.keys(config.components).filter(
607
+ (component) => matchedComponents.indexOf(component) === -1
608
+ );
609
+ if (remainingComponents.length > 0 && !uiComponentList.other?.components && uiComponentList.other?.visible !== false) {
610
+ _componentList.push(
611
+ /* @__PURE__ */ jsx4(
612
+ ComponentList,
613
+ {
614
+ id: "other",
615
+ title: uiComponentList.other?.title || "Other",
616
+ children: remainingComponents.map((componentName, i) => {
617
+ const componentConf = config.components[componentName] || {};
618
+ return /* @__PURE__ */ jsx4(
619
+ ComponentList.Item,
620
+ {
621
+ name: componentName,
622
+ label: componentConf["label"] ?? componentName,
623
+ index: i
624
+ },
625
+ componentName
626
+ );
627
+ })
628
+ },
629
+ "other"
630
+ )
631
+ );
632
+ }
633
+ setComponentList(_componentList);
634
+ }
635
+ }, [config.categories, config.components, uiComponentList]);
636
+ return componentList;
637
+ };
638
+
639
+ // components/CredBuild/components/Components/index.tsx
640
+ import { useMemo as useMemo2, useState as useState4 } from "react";
641
+
642
+ // css-module:/home/runner/work/credbuild/credbuild/components/CredBuild/components/Components/styles.module.css#css-module
643
+ var styles_module_default2 = { "CredBuildComponents": "_CredBuildComponents_1a9p4_1", "CredBuildComponents-searchContainer": "_CredBuildComponents-searchContainer_1a9p4_7", "CredBuildComponents-searchWrapper": "_CredBuildComponents-searchWrapper_1a9p4_16", "CredBuildComponents-searchInput": "_CredBuildComponents-searchInput_1a9p4_23", "CredBuildComponents-searchIcon": "_CredBuildComponents-searchIcon_1a9p4_42", "CredBuildComponents-clearButton": "_CredBuildComponents-clearButton_1a9p4_54", "CredBuildComponents-listContainer": "_CredBuildComponents-listContainer_1a9p4_74", "CredBuildComponents-noResults": "_CredBuildComponents-noResults_1a9p4_79" };
644
+
645
+ // components/CredBuild/components/Components/index.tsx
646
+ import { jsx as jsx5, jsxs as jsxs2 } from "react/jsx-runtime";
647
+ var getClassName2 = get_class_name_factory_default("CredBuildComponents", styles_module_default2);
648
+ var Components = () => {
649
+ const overrides = useAppStore((s) => s.overrides);
650
+ const config = useAppStore((s) => s.config);
651
+ const [searchTerm, setSearchTerm] = useState4("");
652
+ const componentList = useComponentList();
653
+ const Wrapper = useMemo2(() => {
654
+ if (overrides.components) {
655
+ console.warn(
656
+ "The `components` override has been deprecated and renamed to `drawer`"
657
+ );
658
+ }
659
+ return overrides.components || overrides.drawer || "div";
660
+ }, [overrides]);
661
+ const matchingComponents = useMemo2(() => {
662
+ if (!searchTerm.trim()) return [];
663
+ return Object.keys(config.components).filter((componentKey) => {
664
+ const componentConf = config.components[componentKey] || {};
665
+ const label = componentConf["label"] ?? componentKey;
666
+ return label.toLowerCase().includes(searchTerm.toLowerCase()) || componentKey.toLowerCase().includes(searchTerm.toLowerCase());
667
+ });
668
+ }, [searchTerm, config.components]);
669
+ return /* @__PURE__ */ jsxs2(Wrapper, { className: getClassName2(), children: [
670
+ /* @__PURE__ */ jsx5("div", { className: getClassName2("searchContainer"), children: /* @__PURE__ */ jsxs2("div", { className: getClassName2("searchWrapper"), children: [
671
+ /* @__PURE__ */ jsx5(Search, { size: 14, className: getClassName2("searchIcon"), "aria-hidden": "true" }),
672
+ /* @__PURE__ */ jsx5(
673
+ "input",
674
+ {
675
+ type: "text",
676
+ className: getClassName2("searchInput"),
677
+ placeholder: "Search blocks...",
678
+ value: searchTerm,
679
+ onChange: (e) => setSearchTerm(e.target.value),
680
+ "aria-label": "Search blocks"
681
+ }
682
+ ),
683
+ searchTerm && /* @__PURE__ */ jsx5(
684
+ "button",
685
+ {
686
+ type: "button",
687
+ className: getClassName2("clearButton"),
688
+ onClick: () => setSearchTerm(""),
689
+ title: "Clear search",
690
+ "aria-label": "Clear search",
691
+ children: /* @__PURE__ */ jsx5(X, { size: 12, "aria-hidden": "true" })
692
+ }
693
+ )
694
+ ] }) }),
695
+ /* @__PURE__ */ jsx5("div", { className: getClassName2("listContainer"), children: searchTerm.trim() ? matchingComponents.length > 0 ? /* @__PURE__ */ jsxs2("div", { style: { padding: "10px 12px" }, children: [
696
+ /* @__PURE__ */ jsxs2(
697
+ "div",
698
+ {
699
+ style: {
700
+ fontSize: "10px",
701
+ fontWeight: 700,
702
+ color: "var(--cb-silver-muted)",
703
+ marginBottom: "8px",
704
+ textTransform: "uppercase",
705
+ letterSpacing: "0.05em"
706
+ },
707
+ children: [
708
+ "Search Results (",
709
+ matchingComponents.length,
710
+ ")"
711
+ ]
712
+ }
713
+ ),
714
+ /* @__PURE__ */ jsx5(Drawer, { children: /* @__PURE__ */ jsx5("div", { style: { display: "flex", flexDirection: "column", gap: "2px" }, children: matchingComponents.map((componentName, i) => {
715
+ const componentConf = config.components[componentName] || {};
716
+ return /* @__PURE__ */ jsx5(
717
+ ComponentList.Item,
718
+ {
719
+ label: componentConf["label"] ?? componentName,
720
+ name: componentName,
721
+ index: i
722
+ },
723
+ componentName
724
+ );
725
+ }) }) })
726
+ ] }) : /* @__PURE__ */ jsxs2("div", { className: getClassName2("noResults"), children: [
727
+ /* @__PURE__ */ jsx5(Inbox, { size: 20, strokeWidth: 1.5 }),
728
+ /* @__PURE__ */ jsxs2("div", { children: [
729
+ 'No blocks found matching "',
730
+ searchTerm,
731
+ '"'
732
+ ] })
733
+ ] }) : componentList ? componentList : /* @__PURE__ */ jsx5(ComponentList, { id: "all" }) })
734
+ ] });
735
+ };
736
+
737
+ // css-module:/home/runner/work/credbuild/credbuild/plugins/blocks/styles.module.css#css-module
738
+ var styles_module_default3 = { "BlocksPlugin": "_BlocksPlugin_1q0b2_1" };
739
+
740
+ // plugins/blocks/index.tsx
741
+ import { jsx as jsx6 } from "react/jsx-runtime";
742
+ var getClassName3 = get_class_name_factory_default("BlocksPlugin", styles_module_default3);
743
+ var blocksPlugin = () => ({
744
+ name: "blocks",
745
+ label: "Blocks",
746
+ render: () => /* @__PURE__ */ jsx6("div", { className: getClassName3(), children: /* @__PURE__ */ jsx6(Components, {}) }),
747
+ icon: /* @__PURE__ */ jsx6(Shapes, {})
748
+ });
749
+
750
+ // css-module:/home/runner/work/credbuild/credbuild/components/LayerTree/styles.module.css#css-module
751
+ var styles_module_default4 = { "LayerTree": "_LayerTree_nus40_1", "LayerTree-zoneTitle": "_LayerTree-zoneTitle_nus40_11", "LayerTree-helper": "_LayerTree-helper_nus40_17", "Layer": "_Layer_nus40_1", "Layer-inner": "_Layer-inner_nus40_29", "Layer--containsZone": "_Layer--containsZone_nus40_35", "Layer-clickable": "_Layer-clickable_nus40_39", "Layer--isSelected": "_Layer--isSelected_nus40_58", "Layer-chevron": "_Layer-chevron_nus40_79", "Layer--childIsSelected": "_Layer--childIsSelected_nus40_80", "Layer-zones": "_Layer-zones_nus40_84", "Layer-title": "_Layer-title_nus40_98", "Layer-name": "_Layer-name_nus40_107", "Layer-icon": "_Layer-icon_nus40_113", "Layer-zoneIcon": "_Layer-zoneIcon_nus40_118" };
752
+
753
+ // components/LayerTree/index.tsx
754
+ import {
755
+ forwardRef,
756
+ useCallback,
757
+ useContext as useContext2,
758
+ useRef as useRef2,
759
+ memo as memo2
760
+ } from "react";
761
+ import { useVirtualizer } from "@tanstack/react-virtual";
762
+ import { Fragment, jsx as jsx7, jsxs as jsxs3 } from "react/jsx-runtime";
763
+ var getClassName4 = get_class_name_factory_default("LayerTree", styles_module_default4);
764
+ var getClassNameLayer = get_class_name_factory_default("Layer", styles_module_default4);
765
+ var DEFAULT_LAYER_ROW_HEIGHT = 32;
766
+ var LAYER_TREE_VIRTUALIZATION_OVERSCAN = 8;
767
+ var MIN_VIRTUALIZED_LAYER_COUNT = 25;
768
+ var measuredRowHeights = /* @__PURE__ */ new Map();
769
+ var getZonesByParent = (zones) => {
770
+ return Object.keys(zones).reduce((acc, zone) => {
771
+ const [parentId] = zone.split(":");
772
+ acc[parentId] = [...acc[parentId] || [], zone];
773
+ return acc;
774
+ }, {});
775
+ };
776
+ var getZoneLabel = (zoneCompound, nodes, config, label) => {
777
+ if (label !== void 0) {
778
+ return label;
779
+ }
780
+ const [componentId, slotId] = zoneCompound.split(":");
781
+ if (!slotId) {
782
+ return;
783
+ }
784
+ const componentType = nodes[componentId]?.data.type;
785
+ const configForComponent = componentType && componentType !== rootAreaId ? config.components[componentType] : config.root;
786
+ return configForComponent?.fields?.[slotId]?.label ?? slotId;
787
+ };
788
+ var buildLayerNode = ({
789
+ config,
790
+ itemId,
791
+ index,
792
+ nodes,
793
+ zoneCompound,
794
+ zones,
795
+ zonesByParent
796
+ }) => {
797
+ const nodeData = nodes[itemId];
798
+ const componentType = nodeData?.data.type?.toString() || "Component";
799
+ const label = config.components[componentType]?.label ?? componentType;
800
+ const childZoneCompounds = zonesByParent[itemId] || [];
801
+ return {
802
+ childZones: childZoneCompounds.map(
803
+ (childZoneCompound) => buildLayerTree({
804
+ config,
805
+ nodes,
806
+ zoneCompound: childZoneCompound,
807
+ zones,
808
+ zonesByParent
809
+ })
810
+ ),
811
+ componentType,
812
+ index,
813
+ itemId,
814
+ label,
815
+ zoneCompound
816
+ };
817
+ };
818
+ var buildLayerTree = ({
819
+ config,
820
+ label,
821
+ nodes,
822
+ zoneCompound,
823
+ zones,
824
+ zonesByParent = getZonesByParent(zones)
825
+ }) => {
826
+ const contentIds = zones[zoneCompound]?.contentIds ?? [];
827
+ return {
828
+ items: contentIds.map(
829
+ (itemId, index) => buildLayerNode({
830
+ config,
831
+ itemId,
832
+ index,
833
+ nodes,
834
+ zoneCompound,
835
+ zones,
836
+ zonesByParent
837
+ })
838
+ ),
839
+ label: getZoneLabel(zoneCompound, nodes, config, label),
840
+ zoneCompound
841
+ };
842
+ };
843
+ var getEstimatedRowHeight = (itemId) => measuredRowHeights.get(itemId) ?? DEFAULT_LAYER_ROW_HEIGHT;
844
+ var cacheMeasuredRowHeight = (itemId, height) => {
845
+ if (height <= 0) {
846
+ return;
847
+ }
848
+ measuredRowHeights.set(itemId, height);
849
+ };
850
+ var getScrollParent = (el) => {
851
+ let current = el?.parentElement ?? null;
852
+ while (current) {
853
+ const { overflow, overflowY } = getComputedStyle(current);
854
+ if ([overflow, overflowY].some((value) => /auto|scroll/.test(value))) {
855
+ return current;
856
+ }
857
+ current = current.parentElement;
858
+ }
859
+ return null;
860
+ };
861
+ var Layer = memo2(forwardRef(function Layer2({
862
+ childIsSelected,
863
+ dataIndex,
864
+ depth,
865
+ isSelected,
866
+ node,
867
+ selectedId,
868
+ selectedPathIds
869
+ }, ref) {
870
+ const dispatch = useAppStore((s) => s.dispatch);
871
+ const zoneStore = useContext2(ZoneStoreContext);
872
+ const isHovering = useContextStore(
873
+ ZoneStoreContext,
874
+ (s) => s.hoveringComponent === node.itemId
875
+ );
876
+ const containsZone = node.childZones.length > 0;
877
+ const setItemSelector = useCallback(
878
+ (itemSelector) => {
879
+ dispatch({ type: "setUi", ui: { itemSelector } });
880
+ },
881
+ [dispatch]
882
+ );
883
+ const shouldRenderChildren = isSelected || childIsSelected;
884
+ const getLayerIcon = (type) => {
885
+ const t = type.toLowerCase();
886
+ if (t === "text" || t === "heading" || t.includes("heading")) return /* @__PURE__ */ jsx7(Type, { size: "14", strokeWidth: 2.5 });
887
+ if (t.includes("hero")) return /* @__PURE__ */ jsx7(LayoutTemplate, { size: "14", strokeWidth: 2.5 });
888
+ if (t.includes("pricing")) return /* @__PURE__ */ jsx7(CreditCard, { size: "14", strokeWidth: 2.5 });
889
+ if (t.includes("stats")) return /* @__PURE__ */ jsx7(ChartColumn, { size: "14", strokeWidth: 2.5 });
890
+ if (t.includes("testimonials")) return /* @__PURE__ */ jsx7(Quote, { size: "14", strokeWidth: 2.5 });
891
+ if (t.includes("about") || t.includes("info")) return /* @__PURE__ */ jsx7(Info, { size: "14", strokeWidth: 2.5 });
892
+ if (t.includes("gallery") || t.includes("image")) return /* @__PURE__ */ jsx7(Image, { size: "14", strokeWidth: 2.5 });
893
+ if (t.includes("marketing") || t.includes("cta")) return /* @__PURE__ */ jsx7(Megaphone, { size: "14", strokeWidth: 2.5 });
894
+ if (t.includes("content") || t.includes("blog")) return /* @__PURE__ */ jsx7(FileText, { size: "14", strokeWidth: 2.5 });
895
+ if (t.includes("container") || t.includes("layout") || t.includes("flex")) return /* @__PURE__ */ jsx7(Box, { size: "14", strokeWidth: 2.5 });
896
+ return /* @__PURE__ */ jsx7(LayoutGrid, { size: "14", strokeWidth: 2.5 });
897
+ };
898
+ return /* @__PURE__ */ jsxs3(
899
+ "li",
900
+ {
901
+ ref,
902
+ className: getClassNameLayer({
903
+ childIsSelected,
904
+ containsZone,
905
+ isHovering,
906
+ isSelected
907
+ }),
908
+ "data-index": dataIndex,
909
+ "data-credbuild-layer-tree-id": node.itemId,
910
+ children: [
911
+ /* @__PURE__ */ jsx7("div", { className: getClassNameLayer("inner"), children: /* @__PURE__ */ jsxs3(
912
+ "button",
913
+ {
914
+ type: "button",
915
+ className: getClassNameLayer("clickable"),
916
+ onClick: () => {
917
+ if (isSelected) {
918
+ setItemSelector(null);
919
+ return;
920
+ }
921
+ setItemSelector({
922
+ index: node.index,
923
+ zone: node.zoneCompound
924
+ });
925
+ zoneStore.getState().scrollToComponent(node.itemId);
926
+ },
927
+ onMouseEnter: (e) => {
928
+ e.stopPropagation();
929
+ zoneStore.setState({ hoveringComponent: node.itemId });
930
+ },
931
+ onMouseLeave: (e) => {
932
+ e.stopPropagation();
933
+ zoneStore.setState({ hoveringComponent: null });
934
+ },
935
+ children: [
936
+ containsZone && /* @__PURE__ */ jsx7(
937
+ "div",
938
+ {
939
+ className: getClassNameLayer("chevron"),
940
+ title: isSelected ? "Collapse" : "Expand",
941
+ children: /* @__PURE__ */ jsx7(ChevronDown, { size: "12" })
942
+ }
943
+ ),
944
+ /* @__PURE__ */ jsxs3("div", { className: getClassNameLayer("title"), children: [
945
+ /* @__PURE__ */ jsx7("div", { className: getClassNameLayer("icon"), children: getLayerIcon(node.componentType) }),
946
+ /* @__PURE__ */ jsx7("div", { className: getClassNameLayer("name"), children: node.label })
947
+ ] })
948
+ ]
949
+ }
950
+ ) }),
951
+ containsZone && shouldRenderChildren && node.childZones.map((childZone) => /* @__PURE__ */ jsx7(
952
+ "div",
953
+ {
954
+ className: getClassNameLayer("zones"),
955
+ children: /* @__PURE__ */ jsx7(
956
+ LayerTreeZone,
957
+ {
958
+ depth: depth + 1,
959
+ selectedId,
960
+ selectedPathIds,
961
+ tree: childZone
962
+ }
963
+ )
964
+ },
965
+ childZone.zoneCompound
966
+ ))
967
+ ]
968
+ }
969
+ );
970
+ }));
971
+ var LayerTreeZone = memo2(({
972
+ depth,
973
+ selectedId,
974
+ selectedPathIds,
975
+ tree
976
+ }) => {
977
+ const shouldVirtualize = depth === 0 && tree.items.length >= MIN_VIRTUALIZED_LAYER_COUNT;
978
+ return /* @__PURE__ */ jsxs3(Fragment, { children: [
979
+ tree.label && /* @__PURE__ */ jsxs3("div", { className: getClassName4("zoneTitle"), children: [
980
+ /* @__PURE__ */ jsx7("div", { className: getClassName4("zoneIcon"), children: /* @__PURE__ */ jsx7(Layers, { size: "16" }) }),
981
+ tree.label
982
+ ] }),
983
+ shouldVirtualize ? /* @__PURE__ */ jsx7(
984
+ VirtualizedLayerTreeItems,
985
+ {
986
+ depth,
987
+ selectedId,
988
+ selectedPathIds,
989
+ tree
990
+ }
991
+ ) : /* @__PURE__ */ jsx7(
992
+ StaticLayerTreeItems,
993
+ {
994
+ depth,
995
+ selectedId,
996
+ selectedPathIds,
997
+ tree
998
+ }
999
+ )
1000
+ ] });
1001
+ });
1002
+ var StaticLayerTreeItems = memo2(({
1003
+ depth,
1004
+ selectedId,
1005
+ selectedPathIds,
1006
+ tree
1007
+ }) => {
1008
+ return /* @__PURE__ */ jsxs3("ul", { className: getClassName4(), children: [
1009
+ tree.items.length === 0 && /* @__PURE__ */ jsx7("div", { className: getClassName4("helper"), children: "No items" }),
1010
+ tree.items.map((node) => /* @__PURE__ */ jsx7(
1011
+ Layer,
1012
+ {
1013
+ childIsSelected: selectedPathIds.has(node.itemId),
1014
+ depth,
1015
+ isSelected: selectedId === node.itemId,
1016
+ node,
1017
+ selectedId,
1018
+ selectedPathIds
1019
+ },
1020
+ node.itemId
1021
+ ))
1022
+ ] });
1023
+ });
1024
+ var VirtualizedLayerTreeItems = memo2(({
1025
+ depth,
1026
+ selectedId,
1027
+ selectedPathIds,
1028
+ tree
1029
+ }) => {
1030
+ const listRef = useRef2(null);
1031
+ const virtualizer = useVirtualizer({
1032
+ count: tree.items.length,
1033
+ estimateSize: (index) => getEstimatedRowHeight(tree.items[index].itemId),
1034
+ getItemKey: (index) => tree.items[index].itemId,
1035
+ getScrollElement: () => getScrollParent(listRef.current),
1036
+ overscan: LAYER_TREE_VIRTUALIZATION_OVERSCAN,
1037
+ measureElement: (element) => {
1038
+ const height = Math.ceil(element.getBoundingClientRect().height);
1039
+ const itemId = element.dataset.credbuildLayerTreeId;
1040
+ if (itemId) {
1041
+ cacheMeasuredRowHeight(itemId, height);
1042
+ }
1043
+ return height || DEFAULT_LAYER_ROW_HEIGHT;
1044
+ }
1045
+ });
1046
+ const virtualItems = virtualizer.getVirtualItems();
1047
+ const totalSize = virtualizer.getTotalSize();
1048
+ const renderedItems = [];
1049
+ let previousEnd = 0;
1050
+ let previousIndex = -1;
1051
+ virtualItems.forEach((virtualItem) => {
1052
+ const node = tree.items[virtualItem.index];
1053
+ const gapSize = Math.max(virtualItem.start - previousEnd, 0);
1054
+ if (gapSize > 0) {
1055
+ renderedItems.push(
1056
+ /* @__PURE__ */ jsx7(
1057
+ "li",
1058
+ {
1059
+ "aria-hidden": "true",
1060
+ style: { height: `${gapSize}px` }
1061
+ },
1062
+ `gap:${tree.zoneCompound}:${previousIndex}:${virtualItem.index}`
1063
+ )
1064
+ );
1065
+ }
1066
+ renderedItems.push(
1067
+ /* @__PURE__ */ jsx7(
1068
+ Layer,
1069
+ {
1070
+ childIsSelected: selectedPathIds.has(node.itemId),
1071
+ dataIndex: virtualItem.index,
1072
+ depth,
1073
+ isSelected: selectedId === node.itemId,
1074
+ node,
1075
+ ref: virtualizer.measureElement,
1076
+ selectedId,
1077
+ selectedPathIds
1078
+ },
1079
+ node.itemId
1080
+ )
1081
+ );
1082
+ previousEnd = virtualItem.end;
1083
+ previousIndex = virtualItem.index;
1084
+ });
1085
+ const trailingGap = Math.max(totalSize - previousEnd, 0);
1086
+ if (trailingGap > 0) {
1087
+ renderedItems.push(
1088
+ /* @__PURE__ */ jsx7(
1089
+ "li",
1090
+ {
1091
+ "aria-hidden": "true",
1092
+ style: { height: `${trailingGap}px` }
1093
+ },
1094
+ `gap:${tree.zoneCompound}:${previousIndex}:end`
1095
+ )
1096
+ );
1097
+ }
1098
+ return /* @__PURE__ */ jsxs3("ul", { className: getClassName4(), ref: listRef, children: [
1099
+ tree.items.length === 0 && /* @__PURE__ */ jsx7("div", { className: getClassName4("helper"), children: "No items" }),
1100
+ renderedItems
1101
+ ] });
1102
+ });
1103
+ var LayerTree = memo2(({
1104
+ selectedId,
1105
+ selectedPathIds,
1106
+ trees
1107
+ }) => {
1108
+ return /* @__PURE__ */ jsx7(Fragment, { children: trees.map((tree) => /* @__PURE__ */ jsx7(
1109
+ LayerTreeZone,
1110
+ {
1111
+ depth: 0,
1112
+ selectedId,
1113
+ selectedPathIds,
1114
+ tree
1115
+ },
1116
+ tree.zoneCompound
1117
+ )) });
1118
+ });
1119
+
1120
+ // components/CredBuild/components/Outline/index.tsx
1121
+ import { useMemo as useMemo3, memo as memo3 } from "react";
1122
+
1123
+ // lib/data/find-zones-for-area.ts
1124
+ var findZonesForArea = (state, area) => {
1125
+ return Object.keys(state.indexes.zones).filter(
1126
+ (zone) => zone.split(":")[0] === area
1127
+ );
1128
+ };
1129
+
1130
+ // components/CredBuild/components/Outline/index.tsx
1131
+ import { useShallow } from "zustand/react/shallow";
1132
+ import { jsx as jsx8 } from "react/jsx-runtime";
1133
+ var Outline = memo3(() => {
1134
+ const outlineOverride = useAppStore((s) => s.overrides.outline);
1135
+ const config = useAppStore((s) => s.config);
1136
+ const nodes = useAppStore((s) => s.state.indexes.nodes);
1137
+ const zones = useAppStore((s) => s.state.indexes.zones);
1138
+ const selectedId = useAppStore((s) => s.selectedItem?.props.id || null);
1139
+ const rootZones = useAppStore(
1140
+ useShallow((s) => findZonesForArea(s.state, "root"))
1141
+ );
1142
+ const selectedPathIds = useMemo3(() => {
1143
+ const selectedPath = selectedId ? nodes[selectedId]?.path : null;
1144
+ return new Set(
1145
+ selectedPath?.map((candidate) => candidate.split(":")[0]).filter(Boolean) || []
1146
+ );
1147
+ }, [nodes, selectedId]);
1148
+ const trees = useMemo3(
1149
+ () => rootZones.map(
1150
+ (zoneCompound) => buildLayerTree({
1151
+ config,
1152
+ label: rootZones.length === 1 ? "" : zoneCompound.split(":")[1],
1153
+ nodes,
1154
+ zoneCompound,
1155
+ zones
1156
+ })
1157
+ ),
1158
+ [config, nodes, rootZones, zones]
1159
+ );
1160
+ const Wrapper = useMemo3(() => outlineOverride || "div", [outlineOverride]);
1161
+ return /* @__PURE__ */ jsx8(Wrapper, { children: /* @__PURE__ */ jsx8(
1162
+ LayerTree,
1163
+ {
1164
+ selectedId,
1165
+ selectedPathIds,
1166
+ trees
1167
+ }
1168
+ ) });
1169
+ });
1170
+
1171
+ // css-module:/home/runner/work/credbuild/credbuild/plugins/outline/styles.module.css#css-module
1172
+ var styles_module_default5 = { "OutlinePlugin": "_OutlinePlugin_q92j6_1" };
1173
+
1174
+ // plugins/outline/index.tsx
1175
+ import { jsx as jsx9 } from "react/jsx-runtime";
1176
+ var getClassName5 = get_class_name_factory_default("OutlinePlugin", styles_module_default5);
1177
+ var outlinePlugin = () => ({
1178
+ name: "outline",
1179
+ label: "Outline",
1180
+ render: () => /* @__PURE__ */ jsx9("div", { className: getClassName5(), children: /* @__PURE__ */ jsx9(Outline, {}) }),
1181
+ icon: /* @__PURE__ */ jsx9(List, {})
1182
+ });
1183
+
1184
+ // css-module:/home/runner/work/credbuild/credbuild/components/Breadcrumbs/styles.module.css#css-module
1185
+ var styles_module_default6 = { "Breadcrumbs": "_Breadcrumbs_1e0gb_1", "Breadcrumbs-breadcrumbLabel": "_Breadcrumbs-breadcrumbLabel_1e0gb_7", "Breadcrumbs-breadcrumb": "_Breadcrumbs-breadcrumb_1e0gb_7" };
1186
+
1187
+ // lib/use-breadcrumbs.ts
1188
+ import { useMemo as useMemo4 } from "react";
1189
+ var useBreadcrumbs = (renderCount) => {
1190
+ const selectedId = useAppStore((s) => s.selectedItem?.props.id);
1191
+ const config = useAppStore((s) => s.config);
1192
+ const path = useAppStore((s) => s.state.indexes.nodes[selectedId]?.path);
1193
+ const appStore = useAppStoreApi();
1194
+ return useMemo4(() => {
1195
+ const breadcrumbs = path?.map((zoneCompound) => {
1196
+ const [componentId] = zoneCompound.split(":");
1197
+ if (componentId === "root") {
1198
+ return {
1199
+ label: config?.root?.label || "Page",
1200
+ selector: null
1201
+ };
1202
+ }
1203
+ const node = appStore.getState().state.indexes.nodes[componentId];
1204
+ const parentId = node.path[node.path.length - 1];
1205
+ const contentIds = appStore.getState().state.indexes.zones[parentId]?.contentIds || [];
1206
+ const index = contentIds.indexOf(componentId);
1207
+ const label = node ? config.components[node.data.type]?.label ?? node.data.type : "Component";
1208
+ return {
1209
+ label,
1210
+ selector: node ? {
1211
+ index,
1212
+ zone: node.path[node.path.length - 1]
1213
+ } : null
1214
+ };
1215
+ }) || [];
1216
+ if (renderCount) {
1217
+ return breadcrumbs.slice(breadcrumbs.length - renderCount);
1218
+ }
1219
+ return breadcrumbs;
1220
+ }, [path, renderCount, appStore, config.components, config?.root?.label]);
1221
+ };
1222
+
1223
+ // components/Breadcrumbs/index.tsx
1224
+ import { jsx as jsx10, jsxs as jsxs4 } from "react/jsx-runtime";
1225
+ var getClassName6 = get_class_name_factory_default("Breadcrumbs", styles_module_default6);
1226
+ var Breadcrumbs = ({
1227
+ children,
1228
+ numParents = 1
1229
+ }) => {
1230
+ const setUi = useAppStore((s) => s.setUi);
1231
+ const breadcrumbs = useBreadcrumbs(numParents);
1232
+ return /* @__PURE__ */ jsxs4("div", { className: getClassName6(), children: [
1233
+ breadcrumbs.map((breadcrumb, i) => /* @__PURE__ */ jsxs4("div", { className: getClassName6("breadcrumb"), children: [
1234
+ /* @__PURE__ */ jsx10(
1235
+ "button",
1236
+ {
1237
+ type: "button",
1238
+ className: getClassName6("breadcrumbLabel"),
1239
+ onClick: () => setUi({ itemSelector: breadcrumb.selector }),
1240
+ children: breadcrumb.label
1241
+ }
1242
+ ),
1243
+ /* @__PURE__ */ jsx10(ChevronRight, { size: 16 })
1244
+ ] }, i)),
1245
+ children
1246
+ ] });
1247
+ };
1248
+
1249
+ // css-module:/home/runner/work/credbuild/credbuild/components/CredBuild/components/Fields/styles.module.css#css-module
1250
+ var styles_module_default7 = { "CredBuildFields": "_CredBuildFields_53gu7_1", "CredBuildFields--isLoading": "_CredBuildFields--isLoading_53gu7_6", "CredBuildFields-loadingOverlay": "_CredBuildFields-loadingOverlay_53gu7_10", "CredBuildFields-loadingOverlayInner": "_CredBuildFields-loadingOverlayInner_53gu7_25", "CredBuildFields-field": "_CredBuildFields-field_53gu7_32", "CredBuildFields--wrapFields": "_CredBuildFields--wrapFields_53gu7_36" };
1251
+
1252
+ // components/CredBuild/components/Fields/index.tsx
1253
+ import {
1254
+ memo as memo4,
1255
+ useCallback as useCallback2,
1256
+ useContext as useContext3,
1257
+ useEffect as useEffect5,
1258
+ useMemo as useMemo5
1259
+ } from "react";
1260
+ import { useShallow as useShallow2 } from "zustand/react/shallow";
1261
+ import { Fragment as Fragment2, jsx as jsx11, jsxs as jsxs5 } from "react/jsx-runtime";
1262
+ var getClassName7 = get_class_name_factory_default("CredBuildFields", styles_module_default7);
1263
+ var DefaultFields = ({
1264
+ children
1265
+ }) => {
1266
+ return /* @__PURE__ */ jsx11(Fragment2, { children });
1267
+ };
1268
+ var createOnChange = (fieldName, appStore) => async (value, updatedUi) => {
1269
+ const { dispatch, state, selectedItem, resolveComponentData } = appStore.getState();
1270
+ const { data, ui } = state;
1271
+ const { itemSelector } = ui;
1272
+ const rootProps = data.root.props || data.root;
1273
+ const currentProps = selectedItem ? selectedItem.props : rootProps;
1274
+ const newProps = { ...currentProps, [fieldName]: value };
1275
+ if (selectedItem && itemSelector) {
1276
+ const resolved = await resolveComponentData(
1277
+ { ...selectedItem, props: newProps },
1278
+ "replace"
1279
+ );
1280
+ const latestSelector = getSelectorForId(
1281
+ appStore.getState().state,
1282
+ selectedItem.props.id
1283
+ );
1284
+ if (!latestSelector) return;
1285
+ dispatch({
1286
+ type: "replace",
1287
+ destinationIndex: latestSelector.index,
1288
+ destinationZone: latestSelector.zone || rootDroppableId,
1289
+ data: resolved.node,
1290
+ ui: updatedUi
1291
+ });
1292
+ return;
1293
+ }
1294
+ if (data.root.props) {
1295
+ dispatch({
1296
+ type: "replaceRoot",
1297
+ root: (await resolveComponentData(
1298
+ { ...data.root, props: newProps },
1299
+ "replace"
1300
+ )).node,
1301
+ ui: { ...ui, ...updatedUi },
1302
+ recordHistory: true
1303
+ });
1304
+ return;
1305
+ }
1306
+ dispatch({
1307
+ type: "setData",
1308
+ data: { root: newProps }
1309
+ });
1310
+ };
1311
+ var FieldsChildInner = ({ fieldName }) => {
1312
+ const field = useAppStore((s) => s.fields.fields[fieldName]);
1313
+ const isReadOnly = useAppStore(
1314
+ (s) => ((s.selectedItem ? s.selectedItem.readOnly : s.state.data.root.readOnly) || {})[fieldName]
1315
+ );
1316
+ const id = useAppStore((s) => {
1317
+ if (!field) return null;
1318
+ return s.selectedItem ? `${s.selectedItem.props.id}_${field.type}_${fieldName}` : `root_${field.type}_${fieldName}`;
1319
+ });
1320
+ const permissions = useAppStore(
1321
+ useShallow2((s) => {
1322
+ const { selectedItem, permissions: permissions2 } = s;
1323
+ return selectedItem ? permissions2.getPermissions({ item: selectedItem }) : permissions2.getPermissions({ root: true });
1324
+ })
1325
+ );
1326
+ const appStore = useAppStoreApi();
1327
+ const onChange = useCallback2(
1328
+ async (value, updatedUi) => {
1329
+ createOnChange(fieldName, appStore)(value, updatedUi);
1330
+ },
1331
+ [fieldName, appStore]
1332
+ );
1333
+ const { visible = true } = field ?? {};
1334
+ const fieldStore = useContext3(fieldContextStore.ctx);
1335
+ useEffect5(() => {
1336
+ return appStore.subscribe(
1337
+ (s) => {
1338
+ const data = s.getCurrentData();
1339
+ return data.props?.[fieldName];
1340
+ },
1341
+ (value) => {
1342
+ fieldStore.setState({ [fieldName]: value });
1343
+ }
1344
+ );
1345
+ }, [appStore, fieldStore, fieldName]);
1346
+ if (!field || !id || !visible) return null;
1347
+ if (field.type === "slot") return null;
1348
+ return /* @__PURE__ */ jsx11("div", { className: getClassName7("field"), children: /* @__PURE__ */ jsx11(
1349
+ AutoFieldPrivate,
1350
+ {
1351
+ field,
1352
+ name: fieldName,
1353
+ id,
1354
+ readOnly: !permissions.edit || isReadOnly,
1355
+ onChange
1356
+ }
1357
+ ) }, id);
1358
+ };
1359
+ var FieldsChild = ({ fieldName }) => {
1360
+ const appStore = useAppStoreApi();
1361
+ const initialValue = useMemo5(() => {
1362
+ const value = appStore.getState().getCurrentData().props?.[fieldName];
1363
+ return { [fieldName]: value };
1364
+ }, [appStore, fieldName]);
1365
+ return /* @__PURE__ */ jsx11(fieldContextStore.Provider, { value: initialValue, children: /* @__PURE__ */ jsx11(FieldsChildInner, { fieldName }) });
1366
+ };
1367
+ var FieldsChildMemo = memo4(FieldsChild);
1368
+ var FieldsInternal = ({ wrapFields = true }) => {
1369
+ const overrides = useAppStore((s) => s.overrides);
1370
+ const componentResolving = useAppStore((s) => {
1371
+ const loadingCount = s.selectedItem ? s.componentState[s.selectedItem.props.id]?.loadingCount : s.componentState["root"]?.loadingCount;
1372
+ return (loadingCount ?? 0) > 0;
1373
+ });
1374
+ const itemSelector = useAppStore(useShallow2((s) => s.state.ui.itemSelector));
1375
+ const id = useAppStore((s) => s.selectedItem?.props.id);
1376
+ const appStore = useAppStoreApi();
1377
+ useRegisterFieldsSlice(appStore, id);
1378
+ const fieldsLoading = useAppStore((s) => s.fields.loading);
1379
+ const fieldNames = useAppStore(
1380
+ useShallow2((s) => {
1381
+ if (s.fields.id === id) {
1382
+ return Object.keys(s.fields.fields);
1383
+ }
1384
+ return [];
1385
+ })
1386
+ );
1387
+ const isLoading = fieldsLoading || componentResolving;
1388
+ const Wrapper = useMemo5(() => overrides.fields || DefaultFields, [overrides]);
1389
+ return /* @__PURE__ */ jsxs5(
1390
+ "form",
1391
+ {
1392
+ className: getClassName7({ wrapFields }),
1393
+ onSubmit: (e) => {
1394
+ e.preventDefault();
1395
+ },
1396
+ children: [
1397
+ /* @__PURE__ */ jsx11(Wrapper, { isLoading, itemSelector, children: fieldNames.map((fieldName) => /* @__PURE__ */ jsx11(FieldsChildMemo, { fieldName }, fieldName)) }),
1398
+ isLoading && /* @__PURE__ */ jsx11("div", { className: getClassName7("loadingOverlay"), children: /* @__PURE__ */ jsx11("div", { className: getClassName7("loadingOverlayInner"), children: /* @__PURE__ */ jsx11(Loader, { size: 16 }) }) })
1399
+ ]
1400
+ }
1401
+ );
1402
+ };
1403
+ var Fields = memo4(FieldsInternal);
1404
+
1405
+ // css-module:/home/runner/work/credbuild/credbuild/plugins/fields/styles.module.css#css-module
1406
+ var styles_module_default8 = { "FieldsPlugin": "_FieldsPlugin_6as57_1", "FieldsPlugin-header": "_FieldsPlugin-header_6as57_7" };
1407
+
1408
+ // plugins/fields/index.tsx
1409
+ import { jsx as jsx12, jsxs as jsxs6 } from "react/jsx-runtime";
1410
+ var getClassName8 = get_class_name_factory_default("FieldsPlugin", styles_module_default8);
1411
+ var CurrentTitle = () => {
1412
+ const label = useAppStore((s) => {
1413
+ const selectedItem = s.selectedItem;
1414
+ return selectedItem ? s.config.components[selectedItem.type]?.label ?? selectedItem.type : "Page";
1415
+ });
1416
+ return label;
1417
+ };
1418
+ var fieldsPlugin = ({ desktopSideBar = "right" } = {}) => ({
1419
+ name: "fields",
1420
+ label: "Fields",
1421
+ render: () => /* @__PURE__ */ jsxs6("div", { className: getClassName8(), children: [
1422
+ /* @__PURE__ */ jsx12("div", { className: getClassName8("header"), children: /* @__PURE__ */ jsx12(Breadcrumbs, { numParents: 2, children: /* @__PURE__ */ jsx12(CurrentTitle, {}) }) }),
1423
+ /* @__PURE__ */ jsx12(Fields, {})
1424
+ ] }),
1425
+ icon: /* @__PURE__ */ jsx12(RectangleEllipsis, {}),
1426
+ mobileOnly: desktopSideBar === "right"
1427
+ });
1428
+
1429
+ // plugins/code/CodePanel.tsx
1430
+ import { useState as useState5 } from "react";
1431
+
1432
+ // css-module:/home/runner/work/credbuild/credbuild/plugins/code/styles.module.css#css-module
1433
+ var styles_module_default9 = { "CodePlugin": "_CodePlugin_77s8n_1", "CodePanel": "_CodePanel_77s8n_9", "CodePanel-title": "_CodePanel-title_77s8n_18", "CodePanel-textarea": "_CodePanel-textarea_77s8n_27", "CodePanel-optionsSection": "_CodePanel-optionsSection_77s8n_49", "CodePanel-optionTitle": "_CodePanel-optionTitle_77s8n_53", "CodePanel-radioGroup": "_CodePanel-radioGroup_77s8n_62", "CodePanel-radioLabel": "_CodePanel-radioLabel_77s8n_68", "CodePanel-radioInput": "_CodePanel-radioInput_77s8n_77", "CodePanel-button": "_CodePanel-button_77s8n_87", "CodePanel-error": "_CodePanel-error_77s8n_120", "CodePanel-success": "_CodePanel-success_77s8n_131", "CodePanel-promptSection": "_CodePanel-promptSection_77s8n_142", "CodePanel-promptHeader": "_CodePanel-promptHeader_77s8n_148", "CodePanel-promptText": "_CodePanel-promptText_77s8n_155", "CodePanel-copyBtn": "_CodePanel-copyBtn_77s8n_169", "CodePanel-copyBtn--copied": "_CodePanel-copyBtn--copied_77s8n_193" };
1434
+
1435
+ // plugins/code/CodePanel.tsx
1436
+ import { Fragment as Fragment3, jsx as jsx13, jsxs as jsxs7 } from "react/jsx-runtime";
1437
+ var getClassName9 = get_class_name_factory_default("CodePanel", styles_module_default9);
1438
+ var CodePanel = () => {
1439
+ const [copied, setCopied] = useState5(false);
1440
+ const dispatch = useAppStore((s) => s.dispatch);
1441
+ const root = useAppStore((s) => s.state.data.root);
1442
+ const rootProps = root?.props || root;
1443
+ const currentMode = rootProps?.mode || "blocks";
1444
+ const aiPrompt = `Buatkan desain landing page lengkap dan premium dengan pendekatan mobile-first, modern, rapi, dan compact (padat & elegan) menggunakan HTML murni dan utilitas kelas Tailwind CSS. Halaman harus memuat struktur lengkap seperti Header/Navigation, Hero Section, Features/Layanan, Testimoni, Call-to-Action (CTA), dan Footer.
1445
+
1446
+ Ketentuan penulisan kode:
1447
+ 1. STRUKTUR BERSIH: Gunakan elemen semantik HTML5 seperti <section>, <header>, atau <div> sebagai wrapper utama per seksi. JANGAN sertakan tag <html>, <body>, <head>, atau <script>.
1448
+ 2. MOBILE-FIRST & RESPONSIF: Desain harus sepenuhnya responsif. Mulai dari layout ponsel (default), lalu gunakan breakpoint (sm:, md:, lg:, xl:) secara terstruktur untuk layar yang lebih besar.
1449
+ 3. ESTETIKA MODERN & PREMIUM: Gunakan skema warna harmonis (misal: warna gelap bernuansa glassmorphism, gradasi halus, border tipis semi-transparan, efek hover mikro interaktif).
1450
+ 4. COMPACT & EFISIEN: Hindari padding/margin berlebih yang membuat halaman kosong melompong. Pastikan konten padat, terbaca dengan baik, dan memiliki rasio grid/flexbox yang rapi.
1451
+ 5. BEBAS JAVASCRIPT: Seluruh interaktivitas dasar (seperti hover, focus, state) harus ditangani murni menggunakan utilitas kelas CSS Tailwind.`;
1452
+ const handleCopyPrompt = () => {
1453
+ navigator.clipboard.writeText(aiPrompt);
1454
+ setCopied(true);
1455
+ setTimeout(() => setCopied(false), 2e3);
1456
+ };
1457
+ const handleActivateHtmlMode = () => {
1458
+ dispatch({
1459
+ type: "setData",
1460
+ data: (currentData) => {
1461
+ return {
1462
+ ...currentData,
1463
+ content: [],
1464
+ root: {
1465
+ ...currentData.root,
1466
+ props: {
1467
+ ...currentData.root?.props,
1468
+ mode: "html",
1469
+ htmlCode: "",
1470
+ htmlViewMode: "code"
1471
+ }
1472
+ }
1473
+ };
1474
+ }
1475
+ });
1476
+ };
1477
+ const handleResetToBlocks = () => {
1478
+ dispatch({
1479
+ type: "setData",
1480
+ data: (currentData) => {
1481
+ return {
1482
+ ...currentData,
1483
+ content: [],
1484
+ root: {
1485
+ ...currentData.root,
1486
+ props: {
1487
+ ...currentData.root?.props,
1488
+ mode: "blocks",
1489
+ htmlCode: "",
1490
+ htmlViewMode: "code"
1491
+ }
1492
+ }
1493
+ };
1494
+ }
1495
+ });
1496
+ };
1497
+ return /* @__PURE__ */ jsxs7("div", { className: getClassName9(), children: [
1498
+ currentMode === "html" ? /* @__PURE__ */ jsxs7("div", { style: { display: "flex", flexDirection: "column", gap: 16 }, children: [
1499
+ /* @__PURE__ */ jsx13("div", { className: getClassName9("title"), children: "Tempel Kode HTML" }),
1500
+ /* @__PURE__ */ jsxs7("div", { className: "p-3 bg-emerald-950/40 border border-emerald-800/40 rounded-lg", children: [
1501
+ /* @__PURE__ */ jsxs7("div", { className: "flex items-center gap-2 text-emerald-400 text-xs font-semibold mb-3", children: [
1502
+ /* @__PURE__ */ jsx13(CircleCheck, { size: 14, className: "shrink-0" }),
1503
+ /* @__PURE__ */ jsx13("span", { children: "Mode HTML Aktif pada Kanvas" })
1504
+ ] }),
1505
+ /* @__PURE__ */ jsx13("p", { className: "text-[11px] leading-relaxed text-zinc-400 mb-4", children: "Gunakan editor kode langsung yang lapang langsung di area kanvas tengah untuk mengedit kode." }),
1506
+ /* @__PURE__ */ jsx13("div", { className: "flex flex-col gap-2", children: /* @__PURE__ */ jsxs7(
1507
+ "button",
1508
+ {
1509
+ type: "button",
1510
+ onClick: handleResetToBlocks,
1511
+ className: "w-full px-3 py-2 text-xs font-bold text-zinc-400 hover:text-white bg-zinc-950/50 border border-zinc-900 hover:border-zinc-800 rounded transition-colors cursor-pointer flex items-center justify-center gap-1.5",
1512
+ children: [
1513
+ /* @__PURE__ */ jsx13(LayoutGrid, { size: 13 }),
1514
+ "Matikan Mode HTML (Mode Blok)"
1515
+ ]
1516
+ }
1517
+ ) })
1518
+ ] })
1519
+ ] }) : /* @__PURE__ */ jsxs7("div", { style: { display: "flex", flexDirection: "column" }, children: [
1520
+ /* @__PURE__ */ jsx13("div", { className: getClassName9("title"), children: "Tempel Kode HTML" }),
1521
+ /* @__PURE__ */ jsxs7("div", { className: "mb-4 p-3 bg-zinc-900/60 border border-zinc-800/60 rounded-lg text-[11px] leading-relaxed text-zinc-400", children: [
1522
+ "Kanvas saat ini menggunakan ",
1523
+ /* @__PURE__ */ jsx13("strong", { children: "Mode Blok Visual" }),
1524
+ ". Klik tombol di bawah untuk beralih ke Mode HTML penuh pada kanvas."
1525
+ ] }),
1526
+ /* @__PURE__ */ jsxs7(
1527
+ "button",
1528
+ {
1529
+ type: "button",
1530
+ onClick: handleActivateHtmlMode,
1531
+ className: "w-full px-4 py-2 border border-zinc-800 rounded-md text-xs font-semibold text-zinc-300 bg-zinc-900 hover:bg-zinc-800 hover:text-white transition-colors cursor-pointer flex items-center justify-center gap-1.5 mb-4",
1532
+ children: [
1533
+ /* @__PURE__ */ jsx13(Code, { size: 13 }),
1534
+ "Aktifkan Mode HTML"
1535
+ ]
1536
+ }
1537
+ )
1538
+ ] }),
1539
+ /* @__PURE__ */ jsxs7("div", { className: getClassName9("promptSection"), children: [
1540
+ /* @__PURE__ */ jsxs7("div", { className: getClassName9("promptHeader"), children: [
1541
+ /* @__PURE__ */ jsx13("div", { className: getClassName9("optionTitle"), style: { margin: 0 }, children: "Prompt AI Generator" }),
1542
+ /* @__PURE__ */ jsx13(
1543
+ "button",
1544
+ {
1545
+ type: "button",
1546
+ onClick: handleCopyPrompt,
1547
+ className: getClassName9("copyBtn") + (copied ? ` ${styles_module_default9["CodePanel-copyBtn--copied"]}` : ""),
1548
+ children: copied ? /* @__PURE__ */ jsxs7(Fragment3, { children: [
1549
+ /* @__PURE__ */ jsx13(Check, { size: 11 }),
1550
+ "Tersalin"
1551
+ ] }) : /* @__PURE__ */ jsxs7(Fragment3, { children: [
1552
+ /* @__PURE__ */ jsx13(Copy, { size: 11 }),
1553
+ "Salin Prompt"
1554
+ ] })
1555
+ }
1556
+ )
1557
+ ] }),
1558
+ /* @__PURE__ */ jsx13("div", { className: getClassName9("promptText"), children: aiPrompt })
1559
+ ] })
1560
+ ] });
1561
+ };
1562
+
1563
+ // plugins/code/index.tsx
1564
+ import { jsx as jsx14 } from "react/jsx-runtime";
1565
+ var getClassName10 = get_class_name_factory_default("CodePlugin", styles_module_default9);
1566
+ var codePlugin = () => ({
1567
+ name: "code",
1568
+ label: "Code",
1569
+ render: () => /* @__PURE__ */ jsx14("div", { className: getClassName10(), children: /* @__PURE__ */ jsx14(CodePanel, {}) }),
1570
+ icon: /* @__PURE__ */ jsx14(Code, { size: 18 })
1571
+ });
1572
+
1573
+ // components/CredBuild/index.tsx
1574
+ import {
1575
+ useCallback as useCallback12,
1576
+ useEffect as useEffect15,
1577
+ useMemo as useMemo15,
1578
+ useRef as useRef10,
1579
+ useState as useState15
1580
+ } from "react";
1581
+
1582
+ // components/CredBuild/components/Preview/index.tsx
1583
+ import { useCallback as useCallback4, useEffect as useEffect7, useRef as useRef4, useMemo as useMemo7, useState as useState7 } from "react";
1584
+
1585
+ // components/AutoFrame/index.tsx
1586
+ import {
1587
+ createContext as createContext2,
1588
+ useCallback as useCallback3,
1589
+ useContext as useContext4,
1590
+ useEffect as useEffect6,
1591
+ useRef as useRef3,
1592
+ useState as useState6
1593
+ } from "react";
1594
+ import hash from "object-hash";
1595
+ import { createPortal } from "react-dom";
1596
+ import { Fragment as Fragment4, jsx as jsx15 } from "react/jsx-runtime";
1597
+ var styleSelector = 'style, link[rel="stylesheet"]';
1598
+ var collectStyles = (doc) => {
1599
+ const collected = [];
1600
+ doc.querySelectorAll(styleSelector).forEach((style) => {
1601
+ if (style.tagName === "STYLE") {
1602
+ const hasContent = !!style.innerHTML.trim();
1603
+ if (hasContent) {
1604
+ collected.push(style);
1605
+ }
1606
+ } else {
1607
+ collected.push(style);
1608
+ }
1609
+ });
1610
+ return collected;
1611
+ };
1612
+ var getStyleSheet = (el) => {
1613
+ return Array.from(document.styleSheets).find((ss) => {
1614
+ const ownerNode = ss.ownerNode;
1615
+ return ownerNode.href === el.href;
1616
+ });
1617
+ };
1618
+ var getStyles = (styleSheet) => {
1619
+ if (styleSheet) {
1620
+ try {
1621
+ return Array.from(styleSheet.cssRules).map((rule) => rule.cssText).join("");
1622
+ } catch (e) {
1623
+ console.warn(
1624
+ "Access to stylesheet %s is denied. Ignoring\u2026",
1625
+ styleSheet.href
1626
+ );
1627
+ }
1628
+ }
1629
+ return "";
1630
+ };
1631
+ var syncAttributes = (sourceElement, targetElement) => {
1632
+ const attributes = sourceElement.attributes;
1633
+ if (attributes?.length > 0) {
1634
+ Array.from(attributes).forEach((attribute) => {
1635
+ targetElement.setAttribute(attribute.name, attribute.value);
1636
+ });
1637
+ }
1638
+ };
1639
+ var defer = (fn) => setTimeout(fn, 0);
1640
+ var CopyHostStyles = ({
1641
+ children,
1642
+ debug = false,
1643
+ onStylesLoaded = () => null
1644
+ }) => {
1645
+ const { document: doc, window: win } = useFrame();
1646
+ useEffect6(() => {
1647
+ if (!win || !doc) {
1648
+ return () => {
1649
+ };
1650
+ }
1651
+ let elements = [];
1652
+ const hashes = {};
1653
+ const lookupEl = (el) => elements.findIndex((elementMap) => elementMap.original === el);
1654
+ const mirrorEl = async (el, inlineStyles = false) => {
1655
+ let mirror;
1656
+ if (el.nodeName === "LINK" && inlineStyles) {
1657
+ mirror = document.createElement("style");
1658
+ mirror.type = "text/css";
1659
+ let styleSheet = getStyleSheet(el);
1660
+ if (!styleSheet) {
1661
+ await new Promise((resolve) => {
1662
+ const fn = () => {
1663
+ resolve();
1664
+ el.removeEventListener("load", fn);
1665
+ };
1666
+ el.addEventListener("load", fn);
1667
+ });
1668
+ styleSheet = getStyleSheet(el);
1669
+ }
1670
+ const styles2 = getStyles(styleSheet);
1671
+ if (!styles2) {
1672
+ if (debug) {
1673
+ console.warn(
1674
+ `Tried to load styles for link element, but couldn't find them. Skipping...`
1675
+ );
1676
+ }
1677
+ return;
1678
+ }
1679
+ mirror.innerHTML = styles2;
1680
+ mirror.setAttribute("data-href", el.getAttribute("href"));
1681
+ } else {
1682
+ mirror = el.cloneNode(true);
1683
+ }
1684
+ return mirror;
1685
+ };
1686
+ const addEl = async (el) => {
1687
+ const index = lookupEl(el);
1688
+ if (index > -1) {
1689
+ if (debug)
1690
+ console.log(
1691
+ `Tried to add an element that was already mirrored. Updating instead...`
1692
+ );
1693
+ elements[index].mirror.innerText = el.innerText;
1694
+ return;
1695
+ }
1696
+ const mirror = await mirrorEl(el);
1697
+ if (!mirror) {
1698
+ return;
1699
+ }
1700
+ const elHash = hash(mirror.outerHTML);
1701
+ if (hashes[elHash]) {
1702
+ if (debug)
1703
+ console.log(
1704
+ `iframe already contains element that is being mirrored. Skipping...`
1705
+ );
1706
+ return;
1707
+ }
1708
+ hashes[elHash] = true;
1709
+ doc.head.append(mirror);
1710
+ elements.push({ original: el, mirror });
1711
+ if (debug) console.log(`Added style node ${el.outerHTML}`);
1712
+ };
1713
+ const removeEl = (el) => {
1714
+ const index = lookupEl(el);
1715
+ if (index === -1) {
1716
+ if (debug)
1717
+ console.log(
1718
+ `Tried to remove an element that did not exist. Skipping...`
1719
+ );
1720
+ return;
1721
+ }
1722
+ const elHash = hash(el.outerHTML);
1723
+ elements[index]?.mirror?.remove();
1724
+ delete hashes[elHash];
1725
+ if (debug) console.log(`Removed style node ${el.outerHTML}`);
1726
+ };
1727
+ const observer = new MutationObserver((mutations) => {
1728
+ mutations.forEach((mutation) => {
1729
+ if (mutation.type === "childList") {
1730
+ mutation.addedNodes.forEach((node) => {
1731
+ if (node.nodeType === Node.TEXT_NODE || node.nodeType === Node.ELEMENT_NODE) {
1732
+ const el = node.nodeType === Node.TEXT_NODE ? node.parentElement : node;
1733
+ if (el && el.matches(styleSelector)) {
1734
+ defer(() => addEl(el));
1735
+ }
1736
+ }
1737
+ });
1738
+ mutation.removedNodes.forEach((node) => {
1739
+ if (node.nodeType === Node.TEXT_NODE || node.nodeType === Node.ELEMENT_NODE) {
1740
+ const el = node.nodeType === Node.TEXT_NODE ? node.parentElement : node;
1741
+ if (el && el.matches(styleSelector)) {
1742
+ defer(() => removeEl(el));
1743
+ }
1744
+ }
1745
+ });
1746
+ }
1747
+ });
1748
+ });
1749
+ const parentDocument = win.parent.document;
1750
+ const collectedStyles = collectStyles(parentDocument);
1751
+ const hrefs = [];
1752
+ let stylesLoaded = 0;
1753
+ const parentHtml = parentDocument.getElementsByTagName("html")[0];
1754
+ syncAttributes(parentHtml, doc.documentElement);
1755
+ const parentBody = parentDocument.getElementsByTagName("body")[0];
1756
+ syncAttributes(parentBody, doc.body);
1757
+ Promise.all(
1758
+ collectedStyles.map(async (styleNode, i) => {
1759
+ if (styleNode.nodeName === "LINK") {
1760
+ const linkHref = styleNode.href;
1761
+ if (hrefs.indexOf(linkHref) > -1) {
1762
+ return;
1763
+ }
1764
+ hrefs.push(linkHref);
1765
+ }
1766
+ const mirror = await mirrorEl(styleNode);
1767
+ if (!mirror) return;
1768
+ elements.push({ original: styleNode, mirror });
1769
+ return mirror;
1770
+ })
1771
+ ).then((mirrorStyles) => {
1772
+ const filtered = mirrorStyles.filter(
1773
+ (el) => typeof el !== "undefined"
1774
+ );
1775
+ filtered.forEach((mirror) => {
1776
+ mirror.onload = () => {
1777
+ stylesLoaded = stylesLoaded + 1;
1778
+ if (stylesLoaded >= filtered.length) {
1779
+ onStylesLoaded();
1780
+ }
1781
+ };
1782
+ mirror.onerror = () => {
1783
+ console.warn(`AutoFrame couldn't load a stylesheet`);
1784
+ stylesLoaded = stylesLoaded + 1;
1785
+ if (stylesLoaded >= filtered.length) {
1786
+ onStylesLoaded();
1787
+ }
1788
+ };
1789
+ });
1790
+ doc.head.innerHTML = "";
1791
+ doc.head.append(...filtered);
1792
+ filtered.forEach((mirror) => {
1793
+ if (mirror.nodeName === "STYLE") {
1794
+ stylesLoaded = stylesLoaded + 1;
1795
+ }
1796
+ });
1797
+ if (stylesLoaded >= filtered.length) {
1798
+ onStylesLoaded();
1799
+ }
1800
+ observer.observe(parentDocument.head, { childList: true, subtree: true });
1801
+ filtered.forEach((el) => {
1802
+ const elHash = hash(el.outerHTML);
1803
+ hashes[elHash] = true;
1804
+ });
1805
+ });
1806
+ return () => {
1807
+ observer.disconnect();
1808
+ };
1809
+ }, [debug, doc, onStylesLoaded, win]);
1810
+ return /* @__PURE__ */ jsx15(Fragment4, { children });
1811
+ };
1812
+ var autoFrameContext = createContext2({});
1813
+ var useFrame = () => useContext4(autoFrameContext);
1814
+ function AutoFrame({
1815
+ children,
1816
+ className,
1817
+ debug,
1818
+ id,
1819
+ onReady = () => {
1820
+ },
1821
+ onNotReady = () => {
1822
+ },
1823
+ frameRef,
1824
+ ...props
1825
+ }) {
1826
+ const [loaded, setLoaded] = useState6(false);
1827
+ const [ctx, setCtx] = useState6({});
1828
+ const [mountTarget, setMountTarget] = useState6();
1829
+ const [stylesLoaded, setStylesLoaded] = useState6(false);
1830
+ const handleStylesLoaded = useCallback3(() => {
1831
+ setStylesLoaded(true);
1832
+ }, []);
1833
+ const onReadyRef = useRef3(onReady);
1834
+ const onNotReadyRef = useRef3(onNotReady);
1835
+ useEffect6(() => {
1836
+ onReadyRef.current = onReady;
1837
+ onNotReadyRef.current = onNotReady;
1838
+ }, [onReady, onNotReady]);
1839
+ useEffect6(() => {
1840
+ if (frameRef.current) {
1841
+ const doc = frameRef.current.contentDocument;
1842
+ const win = frameRef.current.contentWindow;
1843
+ setCtx((prev) => {
1844
+ if (prev.document === doc && prev.window === win) return prev;
1845
+ return {
1846
+ document: doc || void 0,
1847
+ window: win || void 0
1848
+ };
1849
+ });
1850
+ const newMountTarget = frameRef.current.contentDocument?.getElementById("frame-root");
1851
+ setMountTarget((prev) => {
1852
+ if (prev === newMountTarget) return prev;
1853
+ return newMountTarget;
1854
+ });
1855
+ if (doc && win && stylesLoaded) {
1856
+ onReadyRef.current();
1857
+ }
1858
+ }
1859
+ }, [frameRef, loaded, stylesLoaded]);
1860
+ return /* @__PURE__ */ jsx15(
1861
+ "iframe",
1862
+ {
1863
+ ...props,
1864
+ className,
1865
+ id,
1866
+ srcDoc: '<!DOCTYPE html><html><head></head><body><div id="frame-root" data-credbuild-entry></div></body></html>',
1867
+ ref: frameRef,
1868
+ onLoad: () => {
1869
+ setLoaded(true);
1870
+ },
1871
+ children: /* @__PURE__ */ jsx15(autoFrameContext.Provider, { value: ctx, children: loaded && mountTarget && /* @__PURE__ */ jsx15(
1872
+ CopyHostStyles,
1873
+ {
1874
+ debug,
1875
+ onStylesLoaded: handleStylesLoaded,
1876
+ children: createPortal(children, mountTarget)
1877
+ }
1878
+ ) })
1879
+ }
1880
+ );
1881
+ }
1882
+ AutoFrame.displayName = "AutoFrame";
1883
+ var AutoFrame_default = AutoFrame;
1884
+
1885
+ // css-module:/home/runner/work/credbuild/credbuild/components/CredBuild/components/Preview/styles.module.css#css-module
1886
+ var styles_module_default10 = { "CredBuildPreview": "_CredBuildPreview_1z08a_1", "CredBuildPreview-frame": "_CredBuildPreview-frame_1z08a_6" };
1887
+
1888
+ // lib/bubble-pointer-event.ts
1889
+ var BaseEvent = typeof PointerEvent !== "undefined" ? PointerEvent : Event;
1890
+ var BubbledPointerEvent = class extends BaseEvent {
1891
+ constructor(type, data) {
1892
+ super(type, data);
1893
+ this._originalTarget = null;
1894
+ this.originalTarget = data.originalTarget;
1895
+ }
1896
+ // Necessary for Firefox
1897
+ set originalTarget(target) {
1898
+ this._originalTarget = target;
1899
+ }
1900
+ // Necessary for Firefox
1901
+ get originalTarget() {
1902
+ return this._originalTarget;
1903
+ }
1904
+ };
1905
+
1906
+ // components/CredBuild/components/Preview/index.tsx
1907
+ import { Fragment as Fragment5, jsx as jsx16, jsxs as jsxs8 } from "react/jsx-runtime";
1908
+ var getClassName11 = get_class_name_factory_default("CredBuildPreview", styles_module_default10);
1909
+ var useBubbleIframeEvents = (ref) => {
1910
+ const status = useAppStore((s) => s.status);
1911
+ useEffect7(() => {
1912
+ if (ref.current && status === "READY") {
1913
+ const iframe = ref.current;
1914
+ const handlePointerMove = (event) => {
1915
+ const evt = new BubbledPointerEvent("pointermove", {
1916
+ ...event,
1917
+ bubbles: true,
1918
+ cancelable: false,
1919
+ clientX: event.clientX,
1920
+ clientY: event.clientY,
1921
+ originalTarget: event.target
1922
+ });
1923
+ iframe.dispatchEvent(evt);
1924
+ };
1925
+ const register = () => {
1926
+ unregister();
1927
+ iframe.contentDocument?.addEventListener(
1928
+ "pointermove",
1929
+ handlePointerMove,
1930
+ {
1931
+ capture: true
1932
+ }
1933
+ );
1934
+ };
1935
+ const unregister = () => {
1936
+ iframe.contentDocument?.removeEventListener(
1937
+ "pointermove",
1938
+ handlePointerMove
1939
+ );
1940
+ };
1941
+ register();
1942
+ return () => {
1943
+ unregister();
1944
+ };
1945
+ }
1946
+ }, [status, ref]);
1947
+ };
1948
+ var Preview = ({ id = "credbuild-preview" }) => {
1949
+ const dispatch = useAppStore((s) => s.dispatch);
1950
+ const root = useAppStore((s) => s.state.data.root);
1951
+ const config = useAppStore((s) => s.config);
1952
+ const setStatus = useAppStore((s) => s.setStatus);
1953
+ const iframe = useAppStore((s) => s.iframe);
1954
+ const overrides = useAppStore((s) => s.overrides);
1955
+ const metadata = useAppStore((s) => s.metadata);
1956
+ const renderData = useAppStore(
1957
+ (s) => s.state.ui.previewMode === "edit" ? null : s.state.data
1958
+ );
1959
+ const Page = useCallback4(
1960
+ (pageProps) => {
1961
+ const propsWithSlots = useSlots(
1962
+ config,
1963
+ { type: "root", props: pageProps },
1964
+ DropZoneEditPure
1965
+ );
1966
+ const richtextProps = useRichtextProps(
1967
+ config.root?.fields ?? {},
1968
+ pageProps
1969
+ );
1970
+ return config.root?.render ? config.root?.render({
1971
+ id: "credbuild-root",
1972
+ ...propsWithSlots,
1973
+ ...richtextProps
1974
+ }) : /* @__PURE__ */ jsx16(Fragment5, { children: propsWithSlots.children });
1975
+ },
1976
+ [config]
1977
+ );
1978
+ const Frame = useMemo7(() => overrides.iframe, [overrides]);
1979
+ const rootProps = root.props || root;
1980
+ const isHtmlMode = rootProps?.mode === "html";
1981
+ const htmlViewMode = rootProps?.htmlViewMode || (rootProps?.htmlCode ? "preview" : "code");
1982
+ const htmlCode = rootProps?.htmlCode || "";
1983
+ const ref = useRef4(null);
1984
+ useBubbleIframeEvents(ref);
1985
+ const [localCode, setLocalCode] = useState7(htmlCode);
1986
+ useEffect7(() => {
1987
+ setLocalCode(htmlCode);
1988
+ }, [htmlCode]);
1989
+ useEffect7(() => {
1990
+ if (localCode === htmlCode) return;
1991
+ const timer = setTimeout(() => {
1992
+ dispatch({
1993
+ type: "setData",
1994
+ data: (currentData) => {
1995
+ if (currentData.root?.props?.htmlCode === localCode) {
1996
+ return currentData;
1997
+ }
1998
+ return {
1999
+ ...currentData,
2000
+ root: {
2001
+ ...currentData.root,
2002
+ props: {
2003
+ ...currentData.root?.props,
2004
+ htmlCode: localCode
2005
+ }
2006
+ }
2007
+ };
2008
+ }
2009
+ });
2010
+ }, 300);
2011
+ return () => clearTimeout(timer);
2012
+ }, [localCode, htmlCode, dispatch]);
2013
+ const handleSaveOnBlur = () => {
2014
+ dispatch({
2015
+ type: "setData",
2016
+ data: (currentData) => {
2017
+ if (currentData.root?.props?.htmlCode === localCode) {
2018
+ return currentData;
2019
+ }
2020
+ return {
2021
+ ...currentData,
2022
+ root: {
2023
+ ...currentData.root,
2024
+ props: {
2025
+ ...currentData.root?.props,
2026
+ htmlCode: localCode
2027
+ }
2028
+ }
2029
+ };
2030
+ }
2031
+ });
2032
+ };
2033
+ const handleSetViewMode = (modeVal) => {
2034
+ dispatch({
2035
+ type: "setData",
2036
+ data: (currentData) => ({
2037
+ ...currentData,
2038
+ root: {
2039
+ ...currentData.root,
2040
+ props: {
2041
+ ...currentData.root?.props,
2042
+ htmlViewMode: modeVal
2043
+ }
2044
+ }
2045
+ })
2046
+ });
2047
+ };
2048
+ const handleResetToBlocks = () => {
2049
+ dispatch({
2050
+ type: "setData",
2051
+ data: (currentData) => ({
2052
+ ...currentData,
2053
+ content: [],
2054
+ root: {
2055
+ ...currentData.root,
2056
+ props: {
2057
+ ...currentData.root?.props,
2058
+ mode: "blocks",
2059
+ htmlCode: "",
2060
+ htmlViewMode: "code"
2061
+ }
2062
+ }
2063
+ })
2064
+ });
2065
+ };
2066
+ const isHtmlCodeEditActive = isHtmlMode && !renderData && htmlViewMode === "code";
2067
+ const isHtmlPreviewActive = isHtmlMode && !renderData && htmlViewMode === "preview";
2068
+ const inner = rootProps?.mode === "html" ? !renderData ? /* @__PURE__ */ jsx16(HtmlModeRender, { htmlCode: rootProps.htmlCode, isEditing: true }) : /* @__PURE__ */ jsx16(Render, { data: renderData, config, metadata }) : !renderData ? /* @__PURE__ */ jsx16(
2069
+ Page,
2070
+ {
2071
+ ...rootProps,
2072
+ credbuild: {
2073
+ renderDropZone: DropZonePure,
2074
+ isEditing: true,
2075
+ dragRef: null,
2076
+ metadata
2077
+ },
2078
+ editMode: true,
2079
+ children: /* @__PURE__ */ jsx16(DropZonePure, { zone: rootDroppableId })
2080
+ }
2081
+ ) : /* @__PURE__ */ jsx16(Render, { data: renderData, config, metadata });
2082
+ useEffect7(() => {
2083
+ if (!iframe.enabled) {
2084
+ setStatus("READY");
2085
+ }
2086
+ }, [iframe.enabled, setStatus]);
2087
+ if (isHtmlCodeEditActive) {
2088
+ return /* @__PURE__ */ jsx16(
2089
+ "div",
2090
+ {
2091
+ className: getClassName11(),
2092
+ id,
2093
+ "data-credbuild-preview": true,
2094
+ style: { height: "100%", display: "flex", flexDirection: "column" },
2095
+ children: /* @__PURE__ */ jsx16("div", { style: {
2096
+ display: "flex",
2097
+ flexDirection: "column",
2098
+ flex: 1,
2099
+ background: "#020617",
2100
+ position: "relative"
2101
+ }, children: /* @__PURE__ */ jsxs8("div", { style: {
2102
+ display: "flex",
2103
+ flex: 1,
2104
+ position: "relative",
2105
+ overflow: "hidden"
2106
+ }, children: [
2107
+ /* @__PURE__ */ jsx16("div", { style: {
2108
+ width: 45,
2109
+ background: "#0b0f19",
2110
+ borderRight: "1px solid #1e293b",
2111
+ display: "flex",
2112
+ flexDirection: "column",
2113
+ alignItems: "flex-end",
2114
+ padding: "16px 8px 16px 0",
2115
+ fontFamily: "Menlo, Monaco, Consolas, monospace",
2116
+ fontSize: 12,
2117
+ color: "#475569",
2118
+ userSelect: "none",
2119
+ lineHeight: 1.6
2120
+ }, children: Array.from({ length: Math.max(localCode.split("\n").length, 25) }).map((_, i) => /* @__PURE__ */ jsx16("div", { children: i + 1 }, i)) }),
2121
+ /* @__PURE__ */ jsx16(
2122
+ "textarea",
2123
+ {
2124
+ value: localCode,
2125
+ onChange: (e) => setLocalCode(e.target.value),
2126
+ onBlur: handleSaveOnBlur,
2127
+ placeholder: "<!-- Tempel kode HTML/Tailwind di sini -->\n<section class='bg-zinc-900 text-white p-12'>\n <h1 class='text-3xl font-bold'>Hello World</h1>\n</section>",
2128
+ spellCheck: false,
2129
+ style: {
2130
+ flex: 1,
2131
+ background: "transparent",
2132
+ border: "none",
2133
+ outline: "none",
2134
+ color: "#e2e8f0",
2135
+ fontFamily: "Menlo, Monaco, Consolas, 'Fira Code', monospace",
2136
+ fontSize: 13,
2137
+ lineHeight: 1.6,
2138
+ padding: "16px 20px",
2139
+ resize: "none",
2140
+ height: "100%",
2141
+ width: "100%",
2142
+ overflowY: "auto"
2143
+ }
2144
+ }
2145
+ )
2146
+ ] }) })
2147
+ }
2148
+ );
2149
+ }
2150
+ return /* @__PURE__ */ jsx16(
2151
+ "div",
2152
+ {
2153
+ className: getClassName11(),
2154
+ id,
2155
+ "data-credbuild-preview": true,
2156
+ style: { height: "100%", display: "flex", flexDirection: "column" },
2157
+ onClick: (e) => {
2158
+ const el = e.target;
2159
+ if (!el.hasAttribute("data-credbuild-component") && !el.hasAttribute("data-credbuild-dropzone")) {
2160
+ dispatch({ type: "setUi", ui: { itemSelector: null } });
2161
+ }
2162
+ },
2163
+ children: /* @__PURE__ */ jsx16("div", { style: { flex: 1, position: "relative", minHeight: 0, height: "100%" }, children: iframe.enabled ? /* @__PURE__ */ jsx16(
2164
+ AutoFrame_default,
2165
+ {
2166
+ id: "preview-frame",
2167
+ className: getClassName11("frame"),
2168
+ "data-rfd-iframe": true,
2169
+ onReady: () => {
2170
+ setStatus("READY");
2171
+ },
2172
+ onNotReady: () => {
2173
+ setStatus("MOUNTED");
2174
+ },
2175
+ frameRef: ref,
2176
+ children: /* @__PURE__ */ jsx16(autoFrameContext.Consumer, { children: ({ document: document2 }) => {
2177
+ if (Frame) {
2178
+ return /* @__PURE__ */ jsx16(Frame, { document: document2, children: inner });
2179
+ }
2180
+ return inner;
2181
+ } })
2182
+ }
2183
+ ) : /* @__PURE__ */ jsx16(
2184
+ "div",
2185
+ {
2186
+ id: "preview-frame",
2187
+ className: getClassName11("frame"),
2188
+ ref,
2189
+ "data-credbuild-entry": true,
2190
+ style: { height: "100%", width: "100%" },
2191
+ children: inner
2192
+ }
2193
+ ) })
2194
+ }
2195
+ );
2196
+ };
2197
+
2198
+ // lib/use-loaded-overrides.ts
2199
+ import { useMemo as useMemo8 } from "react";
2200
+
2201
+ // lib/load-overrides.ts
2202
+ var loadOverrides = ({
2203
+ overrides,
2204
+ plugins
2205
+ }) => {
2206
+ const collected = { ...overrides };
2207
+ plugins?.forEach((plugin) => {
2208
+ if (!plugin.overrides) return;
2209
+ Object.keys(plugin.overrides).forEach((_overridesType) => {
2210
+ const overridesType = _overridesType;
2211
+ if (!plugin.overrides?.[overridesType]) return;
2212
+ if (overridesType === "fieldTypes") {
2213
+ const fieldTypes = plugin.overrides.fieldTypes;
2214
+ Object.keys(fieldTypes).forEach((fieldType) => {
2215
+ collected.fieldTypes = collected.fieldTypes || {};
2216
+ const childNode2 = collected.fieldTypes[fieldType];
2217
+ const Comp2 = (props) => fieldTypes[fieldType]({
2218
+ ...props,
2219
+ children: childNode2 ? childNode2(props) : props.children
2220
+ });
2221
+ collected.fieldTypes[fieldType] = Comp2;
2222
+ });
2223
+ return;
2224
+ }
2225
+ const childNode = collected[overridesType];
2226
+ const Comp = (props) => plugin.overrides[overridesType]({
2227
+ ...props,
2228
+ children: childNode ? childNode(props) : props.children
2229
+ });
2230
+ collected[overridesType] = Comp;
2231
+ });
2232
+ });
2233
+ return collected;
2234
+ };
2235
+
2236
+ // lib/use-loaded-overrides.ts
2237
+ var useLoadedOverrides = ({
2238
+ overrides,
2239
+ plugins
2240
+ }) => {
2241
+ return useMemo8(() => {
2242
+ return loadOverrides({ overrides, plugins });
2243
+ }, [plugins, overrides]);
2244
+ };
2245
+
2246
+ // components/CredBuild/index.tsx
2247
+ import { deepEqual } from "fast-equals";
2248
+
2249
+ // components/CredBuild/components/Layout/index.tsx
2250
+ import { useEffect as useEffect14, useMemo as useMemo14, useState as useState14 } from "react";
2251
+
2252
+ // components/CredBuild/context.tsx
2253
+ import {
2254
+ createContext as createContext3,
2255
+ useContext as useContext5
2256
+ } from "react";
2257
+ import { jsx as jsx17 } from "react/jsx-runtime";
2258
+ var propsContext = createContext3({});
2259
+ function PropsProvider(props) {
2260
+ return /* @__PURE__ */ jsx17(propsContext.Provider, { value: props, children: props.children });
2261
+ }
2262
+ var usePropsContext = () => useContext5(propsContext);
2263
+
2264
+ // css-module:/home/runner/work/credbuild/credbuild/components/CredBuild/components/Layout/styles.module.css#css-module
2265
+ var styles_module_default11 = { "CredBuildLayout": "_CredBuildLayout_14aaz_1", "CredBuildLayout-inner": "_CredBuildLayout-inner_14aaz_8", "CredBuildLayout--leftSideBarVisible": "_CredBuildLayout--leftSideBarVisible_14aaz_29", "CredBuildLayout--rightSideBarVisible": "_CredBuildLayout--rightSideBarVisible_14aaz_33", "CredBuild--hidePlugins": "_CredBuild--hidePlugins_14aaz_37", "CredBuildLayout-item": "_CredBuildLayout-item_14aaz_43", "CredBuildLayout-header": "_CredBuildLayout-header_14aaz_49", "CredBuildLayout-left": "_CredBuildLayout-left_14aaz_54", "CredBuildLayout-editor": "_CredBuildLayout-editor_14aaz_67", "CredBuildLayout-right": "_CredBuildLayout-right_14aaz_75", "CredBuildLayout-sidebar": "_CredBuildLayout-sidebar_14aaz_92", "CredBuildPluginTab": "_CredBuildPluginTab_14aaz_107", "CredBuildPluginTab--visible": "_CredBuildPluginTab--visible_14aaz_114", "CredBuildPluginTab-body": "_CredBuildPluginTab-body_14aaz_118", "CredBuildLayout--mounted": "_CredBuildLayout--mounted_14aaz_134" };
2266
+
2267
+ // lib/use-inject-css.ts
2268
+ import { useEffect as useEffect8, useState as useState8 } from "react";
2269
+ var styles = ``;
2270
+ var useInjectStyleSheet = (initialStyles, iframeEnabled) => {
2271
+ const [el, setEl] = useState8();
2272
+ useEffect8(() => {
2273
+ setEl(document.createElement("style"));
2274
+ }, []);
2275
+ useEffect8(() => {
2276
+ if (!el || typeof window === "undefined") {
2277
+ return;
2278
+ }
2279
+ el.innerHTML = initialStyles;
2280
+ if (iframeEnabled) {
2281
+ const frame = getFrame();
2282
+ frame?.head?.appendChild(el);
2283
+ }
2284
+ document.head.appendChild(el);
2285
+ }, [iframeEnabled, el, initialStyles]);
2286
+ return el;
2287
+ };
2288
+ var useInjectGlobalCss = (iframeEnabled) => {
2289
+ return useInjectStyleSheet(styles, iframeEnabled);
2290
+ };
2291
+
2292
+ // components/DefaultOverride/index.tsx
2293
+ import { Fragment as Fragment6, jsx as jsx18 } from "react/jsx-runtime";
2294
+ var DefaultOverride = ({ children }) => /* @__PURE__ */ jsx18(Fragment6, { children });
2295
+
2296
+ // lib/use-preview-mode-hotkeys.ts
2297
+ import { useCallback as useCallback5 } from "react";
2298
+ var usePreviewModeHotkeys = () => {
2299
+ const appStore = useAppStoreApi();
2300
+ const toggleInteractive = useCallback5(() => {
2301
+ const dispatch = appStore.getState().dispatch;
2302
+ dispatch({
2303
+ type: "setUi",
2304
+ ui: (ui) => ({
2305
+ previewMode: ui.previewMode === "edit" ? "interactive" : "edit"
2306
+ })
2307
+ });
2308
+ }, [appStore]);
2309
+ useHotkey({ meta: true, i: true }, toggleInteractive);
2310
+ useHotkey({ ctrl: true, i: true }, toggleInteractive);
2311
+ };
2312
+
2313
+ // components/DragDropContext/index.tsx
2314
+ import { DragDropProvider } from "@dnd-kit/react";
2315
+ import {
2316
+ useCallback as useCallback6,
2317
+ useEffect as useEffect9,
2318
+ useMemo as useMemo9,
2319
+ useRef as useRef5,
2320
+ useState as useState9
2321
+ } from "react";
2322
+ import { AutoScroller, defaultPreset } from "@dnd-kit/dom";
2323
+
2324
+ // lib/dnd/NestedDroppablePlugin.ts
2325
+ import { Plugin } from "@dnd-kit/abstract";
2326
+
2327
+ // lib/throttle.ts
2328
+ function timeout(callback, duration) {
2329
+ const id = setTimeout(callback, duration);
2330
+ return () => clearTimeout(id);
2331
+ }
2332
+ function throttle(func, limit) {
2333
+ const time = () => performance.now();
2334
+ let cancel;
2335
+ let lastRan = 0;
2336
+ return function(...args) {
2337
+ const now = time();
2338
+ const context = this;
2339
+ if (now - lastRan >= limit) {
2340
+ func.apply(context, args);
2341
+ lastRan = now;
2342
+ } else {
2343
+ cancel?.();
2344
+ cancel = timeout(() => {
2345
+ func.apply(context, args);
2346
+ lastRan = time();
2347
+ }, limit - (now - lastRan));
2348
+ }
2349
+ };
2350
+ }
2351
+
2352
+ // lib/global-position.ts
2353
+ var GlobalPosition = class {
2354
+ constructor(target, original) {
2355
+ this.scaleFactor = 1;
2356
+ this.frameEl = null;
2357
+ this.frameRect = null;
2358
+ this.target = target;
2359
+ this.original = original;
2360
+ this.frameEl = document.querySelector("iframe#preview-frame");
2361
+ if (this.frameEl) {
2362
+ this.frameRect = this.frameEl.getBoundingClientRect();
2363
+ this.scaleFactor = this.frameRect.width / (this.frameEl.contentWindow?.innerWidth || 1);
2364
+ }
2365
+ }
2366
+ get x() {
2367
+ return this.original.x;
2368
+ }
2369
+ get y() {
2370
+ return this.original.y;
2371
+ }
2372
+ get global() {
2373
+ if (document !== this.target.ownerDocument && this.frameRect) {
2374
+ return {
2375
+ x: this.x * this.scaleFactor + this.frameRect.left,
2376
+ y: this.y * this.scaleFactor + this.frameRect.top
2377
+ };
2378
+ }
2379
+ return this.original;
2380
+ }
2381
+ get frame() {
2382
+ if (document === this.target.ownerDocument && this.frameRect) {
2383
+ return {
2384
+ x: (this.x - this.frameRect.left) / this.scaleFactor,
2385
+ y: (this.y - this.frameRect.top) / this.scaleFactor
2386
+ };
2387
+ }
2388
+ return this.original;
2389
+ }
2390
+ };
2391
+
2392
+ // lib/dnd/NestedDroppablePlugin.ts
2393
+ var depthSort = (candidates) => {
2394
+ return candidates.sort((a, b) => {
2395
+ const aData = a.data;
2396
+ const bData = b.data;
2397
+ if (aData.depth > bData.depth) {
2398
+ return 1;
2399
+ }
2400
+ if (bData.depth > aData.depth) {
2401
+ return -1;
2402
+ }
2403
+ return 0;
2404
+ });
2405
+ };
2406
+ var getZoneId = (candidate) => {
2407
+ let id = candidate?.id;
2408
+ if (!candidate) return null;
2409
+ if (candidate.type === "component") {
2410
+ const data = candidate.data;
2411
+ if (data.containsActiveZone) {
2412
+ id = null;
2413
+ } else {
2414
+ id = data.zone;
2415
+ }
2416
+ } else if (candidate.type === "void") {
2417
+ return "void";
2418
+ }
2419
+ return id;
2420
+ };
2421
+ var BUFFER = 6;
2422
+ var getPointerCollisions = (position, manager) => {
2423
+ const candidates = [];
2424
+ let elements = position.target.ownerDocument.elementsFromPoint(
2425
+ position.x,
2426
+ position.y
2427
+ );
2428
+ const previewFrame = elements.find(
2429
+ (el) => el.getAttribute("data-credbuild-preview")
2430
+ );
2431
+ const drawer = elements.find((el) => el.getAttribute("data-credbuild-drawer"));
2432
+ if (drawer) {
2433
+ elements = [drawer];
2434
+ }
2435
+ if (previewFrame) {
2436
+ const frame = getFrame();
2437
+ if (frame) {
2438
+ elements = frame.elementsFromPoint(position.frame.x, position.frame.y);
2439
+ }
2440
+ }
2441
+ if (elements) {
2442
+ for (let i = 0; i < elements.length; i++) {
2443
+ const element = elements[i];
2444
+ const dropzoneId = element.getAttribute("data-credbuild-dropzone");
2445
+ const id = element.getAttribute("data-credbuild-dnd");
2446
+ const isVoid = element.hasAttribute("data-credbuild-dnd-void");
2447
+ if (BUFFER && (dropzoneId || id) && !isVoid) {
2448
+ const box = element.getBoundingClientRect();
2449
+ const contractedBox = {
2450
+ left: box.left + BUFFER,
2451
+ right: box.right - BUFFER,
2452
+ top: box.top + BUFFER,
2453
+ bottom: box.bottom - BUFFER
2454
+ };
2455
+ if (position.frame.x < contractedBox.left || position.frame.x > contractedBox.right || position.frame.y > contractedBox.bottom || position.frame.y < contractedBox.top) {
2456
+ continue;
2457
+ }
2458
+ }
2459
+ if (dropzoneId) {
2460
+ const droppable = manager.registry.droppables.get(dropzoneId);
2461
+ if (droppable) {
2462
+ candidates.push(droppable);
2463
+ }
2464
+ }
2465
+ if (id) {
2466
+ const droppable = manager.registry.droppables.get(id);
2467
+ if (droppable) {
2468
+ candidates.push(droppable);
2469
+ }
2470
+ }
2471
+ }
2472
+ }
2473
+ return candidates;
2474
+ };
2475
+ var findDeepestCandidate = (position, manager) => {
2476
+ const candidates = getPointerCollisions(position, manager);
2477
+ if (candidates.length > 0) {
2478
+ const sortedCandidates = depthSort(candidates);
2479
+ const draggable = manager.dragOperation.source;
2480
+ const draggedCandidateIndex = sortedCandidates.findIndex(
2481
+ (candidate) => candidate.id === draggable?.id
2482
+ );
2483
+ const draggedCandidateId = draggable?.id;
2484
+ let filteredCandidates = [...sortedCandidates];
2485
+ if (draggedCandidateId && draggedCandidateIndex > -1) {
2486
+ filteredCandidates.splice(draggedCandidateIndex, 1);
2487
+ }
2488
+ filteredCandidates = filteredCandidates.filter((candidate) => {
2489
+ const candidateData = candidate.data;
2490
+ if (draggedCandidateId && draggedCandidateIndex > -1) {
2491
+ if (candidateData.path.indexOf(draggedCandidateId) > -1) {
2492
+ return false;
2493
+ }
2494
+ }
2495
+ if (candidate.type === "dropzone") {
2496
+ const candidateData2 = candidate.data;
2497
+ if (!candidateData2.isDroppableTarget) {
2498
+ return false;
2499
+ }
2500
+ if (candidateData2.areaId === draggedCandidateId) {
2501
+ return false;
2502
+ }
2503
+ } else if (candidate.type === "component") {
2504
+ const candidateData2 = candidate.data;
2505
+ if (!candidateData2.inDroppableZone) {
2506
+ return false;
2507
+ }
2508
+ }
2509
+ return true;
2510
+ });
2511
+ filteredCandidates.reverse();
2512
+ const primaryCandidate = filteredCandidates[0];
2513
+ if (!primaryCandidate) return { zone: null, area: null };
2514
+ const primaryCandidateData = primaryCandidate.data;
2515
+ const primaryCandidateIsComponent = "containsActiveZone" in primaryCandidateData;
2516
+ const zone = getZoneId(primaryCandidate);
2517
+ const area = primaryCandidateIsComponent && primaryCandidateData.containsActiveZone ? filteredCandidates[0].id : filteredCandidates[0]?.data.areaId;
2518
+ return { zone, area };
2519
+ }
2520
+ return {
2521
+ zone: rootDroppableId,
2522
+ area: rootAreaId
2523
+ };
2524
+ };
2525
+ var createNestedDroppablePlugin = ({ onChange }, id) => class NestedDroppablePlugin extends Plugin {
2526
+ constructor(manager, options) {
2527
+ super(manager);
2528
+ if (typeof window === "undefined") {
2529
+ return;
2530
+ }
2531
+ this.registerEffect(() => {
2532
+ const handleMove = (event) => {
2533
+ const target = event instanceof BubbledPointerEvent ? event.originalTarget || event.target : event.target;
2534
+ const position = new GlobalPosition(target, {
2535
+ x: event.clientX,
2536
+ y: event.clientY
2537
+ });
2538
+ const elements = document.elementsFromPoint(
2539
+ position.global.x,
2540
+ position.global.y
2541
+ );
2542
+ const overEl = elements.some((el) => el.id === id);
2543
+ if (overEl) {
2544
+ onChange(findDeepestCandidate(position, manager), manager);
2545
+ }
2546
+ };
2547
+ const handleMoveThrottled = throttle(handleMove, 50);
2548
+ const handlePointerMove = (event) => {
2549
+ handleMoveThrottled(event);
2550
+ };
2551
+ document.body.addEventListener("pointermove", handlePointerMove, {
2552
+ capture: true
2553
+ // dndkit's PointerSensor prevents propagation during drag
2554
+ });
2555
+ const cleanup = () => {
2556
+ document.body.removeEventListener("pointermove", handlePointerMove, {
2557
+ capture: true
2558
+ });
2559
+ };
2560
+ return cleanup;
2561
+ });
2562
+ }
2563
+ };
2564
+
2565
+ // lib/insert-component.ts
2566
+ var insertComponent = async (componentType, zone, index, appStore) => {
2567
+ const { getState } = appStore;
2568
+ const id = generateId(componentType);
2569
+ const insertActionData = {
2570
+ type: "insert",
2571
+ componentType,
2572
+ destinationIndex: index,
2573
+ destinationZone: zone,
2574
+ id
2575
+ };
2576
+ const stateBefore = getState().state;
2577
+ const insertedState = insertAction(stateBefore, insertActionData, getState());
2578
+ const dispatch = getState().dispatch;
2579
+ dispatch({
2580
+ ...insertActionData,
2581
+ // Dispatch insert rather set, as user's may rely on this via onAction
2582
+ // We must always record history here so the insert is added to user history
2583
+ // If the user has defined a resolveData method, they will end up with 2 history
2584
+ // entries on insert - one for the initial insert, and one when the data resolves
2585
+ recordHistory: true
2586
+ });
2587
+ const itemSelector = { index, zone };
2588
+ dispatch({ type: "setUi", ui: { itemSelector } });
2589
+ const itemData = getItem(itemSelector, insertedState);
2590
+ if (!itemData) return;
2591
+ const resolveComponentData = getState().resolveComponentData;
2592
+ const resolved = await resolveComponentData(itemData, "insert");
2593
+ if (!resolved.didChange) return;
2594
+ const latestItemSelector = getSelectorForId(getState().state, id);
2595
+ if (!latestItemSelector) return;
2596
+ dispatch({
2597
+ type: "replace",
2598
+ destinationZone: latestItemSelector.zone,
2599
+ destinationIndex: latestItemSelector.index,
2600
+ data: resolved.node
2601
+ });
2602
+ };
2603
+
2604
+ // lib/move-component.ts
2605
+ var moveComponent = async (id, sourceSelector, destinationSelector, appStore) => {
2606
+ const dispatch = appStore.getState().dispatch;
2607
+ dispatch({
2608
+ type: "move",
2609
+ sourceIndex: sourceSelector.index,
2610
+ sourceZone: sourceSelector.zone ?? rootDroppableId,
2611
+ destinationIndex: destinationSelector.index,
2612
+ destinationZone: destinationSelector.zone ?? rootDroppableId,
2613
+ recordHistory: false
2614
+ });
2615
+ const componentData = appStore.getState().state.indexes.nodes[id]?.data;
2616
+ if (!componentData) return;
2617
+ const resolveComponentData = appStore.getState().resolveComponentData;
2618
+ const resolvedData = await resolveComponentData(componentData, "move");
2619
+ const latestItemSelector = getSelectorForId(
2620
+ appStore.getState().state,
2621
+ componentData.props.id
2622
+ );
2623
+ if (!latestItemSelector) return;
2624
+ if (resolvedData.didChange)
2625
+ dispatch({
2626
+ type: "replace",
2627
+ data: resolvedData.node,
2628
+ destinationIndex: latestItemSelector.index,
2629
+ destinationZone: latestItemSelector.zone ?? rootDroppableId
2630
+ });
2631
+ };
2632
+
2633
+ // components/DragDropContext/index.tsx
2634
+ import { useDebouncedCallback } from "use-debounce";
2635
+ import { createStore as createStore2 } from "zustand";
2636
+
2637
+ // lib/get-deep-dir.ts
2638
+ function getDeepDir(el) {
2639
+ function findDir(node) {
2640
+ if (!node) return "ltr";
2641
+ const d = node.getAttribute("dir");
2642
+ return d || findDir(node.parentElement);
2643
+ }
2644
+ return el ? findDir(el) : "ltr";
2645
+ }
2646
+
2647
+ // components/DragDropContext/index.tsx
2648
+ import { effect } from "@dnd-kit/state";
2649
+ import { jsx as jsx19 } from "react/jsx-runtime";
2650
+ var DEBUG = false;
2651
+ var AREA_CHANGE_DEBOUNCE_MS = 100;
2652
+ var useTempDisableFallback = (timeout2) => {
2653
+ const lastFallbackDisable = useRef5(null);
2654
+ return useCallback6((manager) => {
2655
+ collisionStore.setState({ fallbackEnabled: false });
2656
+ const fallbackId = generateId();
2657
+ lastFallbackDisable.current = fallbackId;
2658
+ setTimeout(() => {
2659
+ if (lastFallbackDisable.current === fallbackId) {
2660
+ collisionStore.setState({ fallbackEnabled: true });
2661
+ manager.collisionObserver.forceUpdate(true);
2662
+ }
2663
+ }, timeout2);
2664
+ }, [timeout2]);
2665
+ };
2666
+ var DragDropContextClient = ({
2667
+ children,
2668
+ disableAutoScroll
2669
+ }) => {
2670
+ const dispatch = useAppStore((s) => s.dispatch);
2671
+ const instanceId = useAppStore((s) => s.instanceId);
2672
+ const appStore = useAppStoreApi();
2673
+ const debouncedParamsRef = useRef5(null);
2674
+ const tempDisableFallback = useTempDisableFallback(100);
2675
+ const [zoneStore] = useState9(() => {
2676
+ const rootVirtualizers = /* @__PURE__ */ new Map();
2677
+ return createStore2(() => ({
2678
+ zoneDepthIndex: {},
2679
+ nextZoneDepthIndex: {},
2680
+ areaDepthIndex: {},
2681
+ nextAreaDepthIndex: {},
2682
+ draggedItem: null,
2683
+ previewIndex: {},
2684
+ enabledIndex: {},
2685
+ hoveringComponent: null,
2686
+ registerRootVirtualizer: (zoneCompound, handle) => {
2687
+ rootVirtualizers.set(zoneCompound, handle);
2688
+ },
2689
+ unregisterRootVirtualizer: (zoneCompound) => {
2690
+ rootVirtualizers.delete(zoneCompound);
2691
+ },
2692
+ scrollToComponent: (id) => {
2693
+ const virtualizers = Array.from(rootVirtualizers.values());
2694
+ if (virtualizers.length > 0) {
2695
+ for (const handle of virtualizers) {
2696
+ const index = handle.resolveIndex(id);
2697
+ if (index < 0) {
2698
+ continue;
2699
+ }
2700
+ handle.virtualizer.scrollToIndex(index, {
2701
+ behavior: "auto",
2702
+ // We avoid smooth scroll as this triggers virtualizer renders
2703
+ align: "auto"
2704
+ });
2705
+ }
2706
+ } else {
2707
+ const frame = getFrame();
2708
+ const el = frame?.querySelector(`[data-credbuild-component="${id}"]`);
2709
+ el?.scrollIntoView({ behavior: "smooth" });
2710
+ }
2711
+ }
2712
+ }));
2713
+ });
2714
+ const getChanged = useCallback6(
2715
+ (params) => {
2716
+ const { zoneDepthIndex = {}, areaDepthIndex = {} } = zoneStore.getState() || {};
2717
+ const stateHasZone = Object.keys(zoneDepthIndex).length > 0;
2718
+ const stateHasArea = Object.keys(areaDepthIndex).length > 0;
2719
+ let zoneChanged = false;
2720
+ let areaChanged = false;
2721
+ if (params.zone && !zoneDepthIndex[params.zone]) {
2722
+ zoneChanged = true;
2723
+ } else if (!params.zone && stateHasZone) {
2724
+ zoneChanged = true;
2725
+ }
2726
+ if (params.area && !areaDepthIndex[params.area]) {
2727
+ areaChanged = true;
2728
+ } else if (!params.area && stateHasArea) {
2729
+ areaChanged = true;
2730
+ }
2731
+ return { zoneChanged, areaChanged };
2732
+ },
2733
+ [zoneStore]
2734
+ );
2735
+ const setDeepestAndCollide = useCallback6(
2736
+ (params, manager) => {
2737
+ const { zoneChanged, areaChanged } = getChanged(params);
2738
+ if (!zoneChanged && !areaChanged) return;
2739
+ zoneStore.setState({
2740
+ zoneDepthIndex: params.zone ? { [params.zone]: true } : {},
2741
+ areaDepthIndex: params.area ? { [params.area]: true } : {}
2742
+ });
2743
+ tempDisableFallback(manager);
2744
+ setTimeout(() => {
2745
+ manager.collisionObserver.forceUpdate(true);
2746
+ }, 50);
2747
+ debouncedParamsRef.current = null;
2748
+ },
2749
+ [zoneStore, getChanged, tempDisableFallback]
2750
+ );
2751
+ const setDeepestDb = useDebouncedCallback(
2752
+ setDeepestAndCollide,
2753
+ AREA_CHANGE_DEBOUNCE_MS
2754
+ );
2755
+ const cancelDb = () => {
2756
+ setDeepestDb.cancel();
2757
+ debouncedParamsRef.current = null;
2758
+ };
2759
+ useEffect9(() => {
2760
+ if (DEBUG) {
2761
+ return zoneStore.subscribe(
2762
+ (s) => console.log(
2763
+ s.previewIndex,
2764
+ Object.entries(s.zoneDepthIndex || {})[0]?.[0],
2765
+ Object.entries(s.areaDepthIndex || {})[0]?.[0]
2766
+ )
2767
+ );
2768
+ }
2769
+ }, [zoneStore]);
2770
+ const [plugins] = useState9(() => [
2771
+ ...disableAutoScroll ? defaultPreset.plugins.filter((plugin) => plugin !== AutoScroller) : defaultPreset.plugins,
2772
+ createNestedDroppablePlugin(
2773
+ {
2774
+ onChange: (params, manager) => {
2775
+ const state = zoneStore.getState();
2776
+ const { zoneChanged, areaChanged } = getChanged(params);
2777
+ const isDragging = manager.dragOperation.status.dragging;
2778
+ if (areaChanged || zoneChanged) {
2779
+ let nextZoneDepthIndex = {};
2780
+ let nextAreaDepthIndex = {};
2781
+ if (params.zone) {
2782
+ nextZoneDepthIndex = { [params.zone]: true };
2783
+ }
2784
+ if (params.area) {
2785
+ nextAreaDepthIndex = { [params.area]: true };
2786
+ }
2787
+ zoneStore.setState({ nextZoneDepthIndex, nextAreaDepthIndex });
2788
+ }
2789
+ if (params.zone !== "void" && state?.zoneDepthIndex["void"]) {
2790
+ setDeepestAndCollide(params, manager);
2791
+ return;
2792
+ }
2793
+ if (areaChanged) {
2794
+ if (isDragging) {
2795
+ const debouncedParams = debouncedParamsRef.current;
2796
+ const isSameParams = debouncedParams && debouncedParams.area === params.area && debouncedParams.zone === params.zone;
2797
+ if (!isSameParams) {
2798
+ cancelDb();
2799
+ setDeepestDb(params, manager);
2800
+ debouncedParamsRef.current = params;
2801
+ }
2802
+ } else {
2803
+ cancelDb();
2804
+ setDeepestAndCollide(params, manager);
2805
+ }
2806
+ return;
2807
+ }
2808
+ if (zoneChanged) {
2809
+ setDeepestAndCollide(params, manager);
2810
+ }
2811
+ cancelDb();
2812
+ }
2813
+ },
2814
+ instanceId
2815
+ )
2816
+ ]);
2817
+ const sensors = useSensors();
2818
+ const [dragListeners, setDragListeners] = useState9({});
2819
+ const dragMode = useRef5(null);
2820
+ const initialSelector = useRef5(void 0);
2821
+ const nextContextValue = useMemo9(
2822
+ () => ({
2823
+ mode: "edit",
2824
+ areaId: "root",
2825
+ depth: 0
2826
+ }),
2827
+ []
2828
+ );
2829
+ return /* @__PURE__ */ jsx19(
2830
+ dragListenerContext.Provider,
2831
+ {
2832
+ value: {
2833
+ dragListeners,
2834
+ setDragListeners
2835
+ },
2836
+ children: /* @__PURE__ */ jsx19(
2837
+ DragDropProvider,
2838
+ {
2839
+ plugins,
2840
+ sensors,
2841
+ onDragEnd: (event, manager) => {
2842
+ const entryEl = getFrame()?.querySelector("[data-credbuild-entry]");
2843
+ entryEl?.removeAttribute("data-credbuild-dragging");
2844
+ const { source, target } = event.operation;
2845
+ if (!source) {
2846
+ zoneStore.setState({ draggedItem: null });
2847
+ return;
2848
+ }
2849
+ const { zone, index } = source.data;
2850
+ const { previewIndex = {} } = zoneStore.getState() || {};
2851
+ const thisPreview = previewIndex[zone]?.props.id === source.id ? previewIndex[zone] : null;
2852
+ const onAnimationEnd = () => {
2853
+ zoneStore.setState({ draggedItem: null });
2854
+ if (event.canceled || target?.type === "void") {
2855
+ zoneStore.setState({ previewIndex: {} });
2856
+ dragListeners.dragend?.forEach((item) => {
2857
+ const fn = typeof item === "function" ? item : item.fn;
2858
+ if (typeof fn === "function") {
2859
+ fn(event, manager);
2860
+ }
2861
+ });
2862
+ dispatch({
2863
+ type: "setUi",
2864
+ ui: {
2865
+ itemSelector: null,
2866
+ isDragging: false
2867
+ }
2868
+ });
2869
+ return;
2870
+ }
2871
+ if (thisPreview) {
2872
+ zoneStore.setState({ previewIndex: {} });
2873
+ if (thisPreview.type === "insert") {
2874
+ insertComponent(
2875
+ thisPreview.componentType,
2876
+ thisPreview.zone,
2877
+ thisPreview.index,
2878
+ appStore
2879
+ );
2880
+ } else if (initialSelector.current) {
2881
+ moveComponent(
2882
+ thisPreview.props.id,
2883
+ initialSelector.current,
2884
+ thisPreview,
2885
+ appStore
2886
+ );
2887
+ }
2888
+ }
2889
+ const movedToNewPosition = initialSelector.current?.zone !== thisPreview?.zone || initialSelector.current?.index !== thisPreview?.index;
2890
+ dispatch({
2891
+ type: "setUi",
2892
+ ui: {
2893
+ itemSelector: { index, zone },
2894
+ isDragging: false
2895
+ },
2896
+ recordHistory: movedToNewPosition
2897
+ });
2898
+ dragListeners.dragend?.forEach((item) => {
2899
+ const fn = typeof item === "function" ? item : item.fn;
2900
+ if (typeof fn === "function") {
2901
+ fn(event, manager);
2902
+ }
2903
+ });
2904
+ };
2905
+ let dispose;
2906
+ dispose = effect(() => {
2907
+ if (source.status === "idle") {
2908
+ onAnimationEnd();
2909
+ dispose?.();
2910
+ }
2911
+ });
2912
+ },
2913
+ onDragOver: (event, manager) => {
2914
+ event.preventDefault();
2915
+ const draggedItem = zoneStore.getState()?.draggedItem;
2916
+ if (!draggedItem) return;
2917
+ cancelDb();
2918
+ const { source, target } = event.operation;
2919
+ if (!target || !source || target.type === "void") return;
2920
+ const [sourceId] = source.id.split(":");
2921
+ const [targetId] = target.id.split(":");
2922
+ const sourceData = source.data;
2923
+ let sourceZone = sourceData.zone;
2924
+ let sourceIndex = sourceData.index;
2925
+ let targetZone = "";
2926
+ let targetIndex = 0;
2927
+ if (target.type === "component") {
2928
+ const targetData = target.data;
2929
+ targetZone = targetData.zone;
2930
+ targetIndex = targetData.index;
2931
+ const collisionData = manager.collisionObserver.collisions[0]?.data;
2932
+ const dir = getDeepDir(target.element);
2933
+ const collisionPosition = collisionData?.direction === "up" || dir === "ltr" && collisionData?.direction === "left" || dir === "rtl" && collisionData?.direction === "right" ? "before" : "after";
2934
+ if (targetIndex >= sourceIndex && sourceZone === targetZone) {
2935
+ targetIndex = targetIndex - 1;
2936
+ }
2937
+ if (collisionPosition === "after") {
2938
+ targetIndex = targetIndex + 1;
2939
+ }
2940
+ } else {
2941
+ targetZone = target.id.toString();
2942
+ targetIndex = 0;
2943
+ }
2944
+ const path = appStore.getState().state.indexes.nodes[target.id]?.path || [];
2945
+ if (targetId === sourceId || path.find((path2) => {
2946
+ const [pathId] = path2.split(":");
2947
+ return pathId === sourceId;
2948
+ })) {
2949
+ return;
2950
+ }
2951
+ if (dragMode.current === "new") {
2952
+ zoneStore.setState({
2953
+ previewIndex: {
2954
+ [targetZone]: {
2955
+ componentType: sourceData.componentType,
2956
+ type: "insert",
2957
+ index: targetIndex,
2958
+ zone: targetZone,
2959
+ element: source.element,
2960
+ props: {
2961
+ id: source.id.toString()
2962
+ }
2963
+ }
2964
+ }
2965
+ });
2966
+ } else {
2967
+ if (!initialSelector.current) {
2968
+ initialSelector.current = {
2969
+ zone: sourceData.zone,
2970
+ index: sourceData.index
2971
+ };
2972
+ }
2973
+ const item = getItem(
2974
+ initialSelector.current,
2975
+ appStore.getState().state
2976
+ );
2977
+ if (item) {
2978
+ zoneStore.setState({
2979
+ previewIndex: {
2980
+ [targetZone]: {
2981
+ componentType: sourceData.componentType,
2982
+ type: "move",
2983
+ index: targetIndex,
2984
+ zone: targetZone,
2985
+ props: item.props,
2986
+ element: source.element
2987
+ }
2988
+ }
2989
+ });
2990
+ }
2991
+ }
2992
+ dragListeners.dragover?.forEach((item) => {
2993
+ const fn = typeof item === "function" ? item : item.fn;
2994
+ if (typeof fn === "function") {
2995
+ fn(event, manager);
2996
+ }
2997
+ });
2998
+ },
2999
+ onDragStart: (event, manager) => {
3000
+ const { source } = event.operation;
3001
+ if (source && source.type !== "void") {
3002
+ const sourceData = source.data;
3003
+ const item = getItem(
3004
+ {
3005
+ zone: sourceData.zone,
3006
+ index: sourceData.index
3007
+ },
3008
+ appStore.getState().state
3009
+ );
3010
+ if (item) {
3011
+ zoneStore.setState({
3012
+ previewIndex: {
3013
+ [sourceData.zone]: {
3014
+ componentType: sourceData.componentType,
3015
+ type: "move",
3016
+ index: sourceData.index,
3017
+ zone: sourceData.zone,
3018
+ props: item.props,
3019
+ element: source.element
3020
+ }
3021
+ }
3022
+ });
3023
+ }
3024
+ }
3025
+ dragListeners.dragstart?.forEach((item) => {
3026
+ const fn = typeof item === "function" ? item : item.fn;
3027
+ if (typeof fn === "function") {
3028
+ fn(event, manager);
3029
+ }
3030
+ });
3031
+ },
3032
+ onBeforeDragStart: (event) => {
3033
+ const isNewComponent = event.operation.source?.type === "drawer";
3034
+ dragMode.current = isNewComponent ? "new" : "existing";
3035
+ initialSelector.current = void 0;
3036
+ zoneStore.setState({ draggedItem: event.operation.source });
3037
+ if (appStore.getState().selectedItem?.props.id !== event.operation.source?.id) {
3038
+ dispatch({
3039
+ type: "setUi",
3040
+ ui: {
3041
+ itemSelector: null,
3042
+ isDragging: true
3043
+ },
3044
+ recordHistory: false
3045
+ });
3046
+ } else {
3047
+ dispatch({
3048
+ type: "setUi",
3049
+ ui: {
3050
+ isDragging: true
3051
+ },
3052
+ recordHistory: false
3053
+ });
3054
+ }
3055
+ const entryEl = getFrame()?.querySelector("[data-credbuild-entry]");
3056
+ entryEl?.setAttribute("data-credbuild-dragging", "true");
3057
+ },
3058
+ children: /* @__PURE__ */ jsx19(ZoneStoreProvider, { store: zoneStore, children: /* @__PURE__ */ jsx19(DropZoneProvider, { value: nextContextValue, children }) })
3059
+ }
3060
+ )
3061
+ }
3062
+ );
3063
+ };
3064
+ var DragDropContext = ({
3065
+ children,
3066
+ disableAutoScroll
3067
+ }) => {
3068
+ const status = useAppStore((s) => s.status);
3069
+ if (status === "LOADING") {
3070
+ return children;
3071
+ }
3072
+ return /* @__PURE__ */ jsx19(DragDropContextClient, { disableAutoScroll, children });
3073
+ };
3074
+
3075
+ // components/CredBuild/components/Header/index.tsx
3076
+ import { memo as memo5, useCallback as useCallback7, useMemo as useMemo12, useState as useState11 } from "react";
3077
+
3078
+ // css-module:/home/runner/work/credbuild/credbuild/components/MenuBar/styles.module.css#css-module
3079
+ var styles_module_default12 = { "MenuBar": "_MenuBar_1m2ld_1", "MenuBar--menuOpen": "_MenuBar--menuOpen_1m2ld_14", "MenuBar-inner": "_MenuBar-inner_1m2ld_29", "MenuBar-history": "_MenuBar-history_1m2ld_45" };
3080
+
3081
+ // components/MenuBar/index.tsx
3082
+ import { Fragment as Fragment7, jsx as jsx20, jsxs as jsxs9 } from "react/jsx-runtime";
3083
+ var getClassName12 = get_class_name_factory_default("MenuBar", styles_module_default12);
3084
+ function MenuBar({
3085
+ menuOpen = false,
3086
+ renderHeaderActions,
3087
+ setMenuOpen
3088
+ }) {
3089
+ const back = useAppStore((s) => s.history.back);
3090
+ const forward = useAppStore((s) => s.history.forward);
3091
+ const hasFuture = useAppStore((s) => s.history.hasFuture());
3092
+ const hasPast = useAppStore((s) => s.history.hasPast());
3093
+ return /* @__PURE__ */ jsx20(
3094
+ "div",
3095
+ {
3096
+ className: getClassName12({ menuOpen }),
3097
+ onClick: (event) => {
3098
+ const element = event.target;
3099
+ if (window.matchMedia("(min-width: 638px)").matches) {
3100
+ return;
3101
+ }
3102
+ if (element.tagName === "A" && element.getAttribute("href")?.startsWith("#")) {
3103
+ setMenuOpen(false);
3104
+ }
3105
+ },
3106
+ children: /* @__PURE__ */ jsxs9("div", { className: getClassName12("inner"), children: [
3107
+ /* @__PURE__ */ jsxs9("div", { className: getClassName12("history"), children: [
3108
+ /* @__PURE__ */ jsx20(
3109
+ IconButton,
3110
+ {
3111
+ type: "button",
3112
+ title: "undo",
3113
+ disabled: !hasPast,
3114
+ onClick: back,
3115
+ children: /* @__PURE__ */ jsx20(Undo2, { size: 21 })
3116
+ }
3117
+ ),
3118
+ /* @__PURE__ */ jsx20(
3119
+ IconButton,
3120
+ {
3121
+ type: "button",
3122
+ title: "redo",
3123
+ disabled: !hasFuture,
3124
+ onClick: forward,
3125
+ children: /* @__PURE__ */ jsx20(Redo2, { size: 21 })
3126
+ }
3127
+ )
3128
+ ] }),
3129
+ /* @__PURE__ */ jsx20(Fragment7, { children: renderHeaderActions && renderHeaderActions() })
3130
+ ] })
3131
+ }
3132
+ );
3133
+ }
3134
+
3135
+ // components/ViewportControls/index.tsx
3136
+ import { useEffect as useEffect10, useMemo as useMemo10, useState as useState10 } from "react";
3137
+
3138
+ // css-module:/home/runner/work/credbuild/credbuild/components/ViewportControls/styles.module.css#css-module
3139
+ var styles_module_default13 = { "ViewportControls": "_ViewportControls_gefvg_1", "ViewportControls--fullScreen": "_ViewportControls--fullScreen_gefvg_5", "ViewportControls-toggleButton": "_ViewportControls-toggleButton_gefvg_14", "ViewportControls--isExpanded": "_ViewportControls--isExpanded_gefvg_38", "ViewportControls-actions": "_ViewportControls-actions_gefvg_42", "ViewportControls-actionsInner": "_ViewportControls-actionsInner_gefvg_46", "ViewportControls-divider": "_ViewportControls-divider_gefvg_76", "ViewportControls-zoomSelect": "_ViewportControls-zoomSelect_gefvg_83", "ViewportControls-zoom": "_ViewportControls-zoom_gefvg_83", "ViewportButton-inner": "_ViewportButton-inner_gefvg_114", "ViewportButton--isActive": "_ViewportButton--isActive_gefvg_122" };
3140
+
3141
+ // components/ViewportControls/index.tsx
3142
+ import { jsx as jsx21, jsxs as jsxs10 } from "react/jsx-runtime";
3143
+ var icons = {
3144
+ Smartphone: /* @__PURE__ */ jsx21(Smartphone, { size: 16 }),
3145
+ Tablet: /* @__PURE__ */ jsx21(Tablet, { size: 16 }),
3146
+ Monitor: /* @__PURE__ */ jsx21(Monitor, { size: 16 }),
3147
+ FullWidth: /* @__PURE__ */ jsx21(Expand, { size: 16 })
3148
+ };
3149
+ var getClassName13 = get_class_name_factory_default("ViewportControls", styles_module_default13);
3150
+ var getClassNameButton = get_class_name_factory_default("ViewportButton", styles_module_default13);
3151
+ var ActionButton = ({
3152
+ children,
3153
+ title,
3154
+ onClick,
3155
+ isActive,
3156
+ disabled
3157
+ }) => {
3158
+ return /* @__PURE__ */ jsx21("span", { className: getClassNameButton({ isActive }), suppressHydrationWarning: true, children: /* @__PURE__ */ jsx21(
3159
+ IconButton,
3160
+ {
3161
+ type: "button",
3162
+ title,
3163
+ disabled: disabled || isActive,
3164
+ onClick,
3165
+ suppressHydrationWarning: true,
3166
+ children: /* @__PURE__ */ jsx21("span", { className: getClassNameButton("inner"), children })
3167
+ }
3168
+ ) });
3169
+ };
3170
+ var defaultZoomOptions = [
3171
+ { label: "25%", value: 0.25 },
3172
+ { label: "50%", value: 0.5 },
3173
+ { label: "75%", value: 0.75 },
3174
+ { label: "100%", value: 1 },
3175
+ { label: "125%", value: 1.25 },
3176
+ { label: "150%", value: 1.5 },
3177
+ { label: "200%", value: 2 }
3178
+ ];
3179
+ var ViewportControls = ({
3180
+ autoZoom,
3181
+ zoom,
3182
+ onViewportChange,
3183
+ onZoom,
3184
+ fullScreen
3185
+ }) => {
3186
+ const viewports = useAppStore((s) => s.viewports);
3187
+ const uiViewports = useAppStore((s) => s.state.ui.viewports);
3188
+ const defaultsContainAutoZoom = defaultZoomOptions.find(
3189
+ (option) => option.value === autoZoom
3190
+ );
3191
+ const zoomOptions = useMemo10(() => {
3192
+ const options = [
3193
+ ...defaultZoomOptions,
3194
+ ...defaultsContainAutoZoom || isNaN(autoZoom) ? [] : [
3195
+ {
3196
+ value: autoZoom,
3197
+ label: `${(autoZoom * 100).toFixed(0)}% (Auto)`
3198
+ }
3199
+ ]
3200
+ ].filter((a) => a.value <= (autoZoom || 1)).sort((a, b) => a.value > b.value ? 1 : -1);
3201
+ return options.length > 0 ? options : defaultZoomOptions;
3202
+ }, [autoZoom, defaultsContainAutoZoom]);
3203
+ const [activeViewport, setActiveViewport] = useState10(
3204
+ uiViewports.current.width
3205
+ );
3206
+ useEffect10(() => {
3207
+ setActiveViewport(uiViewports.current.width);
3208
+ }, [uiViewports.current.width, uiViewports]);
3209
+ const [isExpanded, setIsExpanded] = useState10(false);
3210
+ return /* @__PURE__ */ jsxs10(
3211
+ "div",
3212
+ {
3213
+ className: getClassName13({ isExpanded, fullScreen }),
3214
+ suppressHydrationWarning: true,
3215
+ children: [
3216
+ /* @__PURE__ */ jsx21("div", { className: getClassName13("actions"), children: /* @__PURE__ */ jsxs10("div", { className: getClassName13("actionsInner"), children: [
3217
+ viewports.map((viewport, i) => /* @__PURE__ */ jsx21(
3218
+ ActionButton,
3219
+ {
3220
+ title: viewport.label ? `Switch to ${viewport.label} viewport` : "Switch viewport",
3221
+ onClick: () => {
3222
+ setActiveViewport(viewport.width);
3223
+ onViewportChange(viewport);
3224
+ },
3225
+ isActive: activeViewport === viewport.width,
3226
+ children: typeof viewport.icon === "string" ? icons[viewport.icon] || viewport.icon : viewport.icon || icons.Smartphone
3227
+ },
3228
+ i
3229
+ )),
3230
+ /* @__PURE__ */ jsx21("div", { className: getClassName13("divider") }),
3231
+ /* @__PURE__ */ jsx21(
3232
+ ActionButton,
3233
+ {
3234
+ title: "Zoom viewport out",
3235
+ disabled: zoom <= (zoomOptions[0]?.value || 0),
3236
+ onClick: (e) => {
3237
+ e.stopPropagation();
3238
+ const currentIndex = zoomOptions.findIndex((option) => option.value === zoom);
3239
+ const nextIndex = Math.max(
3240
+ (currentIndex === -1 ? zoomOptions.length : currentIndex) - 1,
3241
+ 0
3242
+ );
3243
+ onZoom(zoomOptions[nextIndex]?.value || 1);
3244
+ },
3245
+ children: /* @__PURE__ */ jsx21(ZoomOut, { size: 16 })
3246
+ }
3247
+ ),
3248
+ /* @__PURE__ */ jsx21(
3249
+ ActionButton,
3250
+ {
3251
+ title: "Zoom viewport in",
3252
+ disabled: zoom >= (zoomOptions[zoomOptions.length - 1]?.value || 2),
3253
+ onClick: (e) => {
3254
+ e.stopPropagation();
3255
+ const currentIndex = zoomOptions.findIndex((option) => option.value === zoom);
3256
+ const nextIndex = Math.min(
3257
+ (currentIndex === -1 ? -1 : currentIndex) + 1,
3258
+ zoomOptions.length - 1
3259
+ );
3260
+ onZoom(zoomOptions[nextIndex]?.value || 1);
3261
+ },
3262
+ children: /* @__PURE__ */ jsx21(ZoomIn, { size: 16 })
3263
+ }
3264
+ ),
3265
+ /* @__PURE__ */ jsxs10("div", { className: getClassName13("zoom"), children: [
3266
+ /* @__PURE__ */ jsx21("div", { className: getClassName13("divider") }),
3267
+ /* @__PURE__ */ jsx21(
3268
+ "select",
3269
+ {
3270
+ className: getClassName13("zoomSelect"),
3271
+ value: zoom.toString(),
3272
+ onClick: (e) => {
3273
+ e.stopPropagation();
3274
+ },
3275
+ onChange: (e) => {
3276
+ onZoom(parseFloat(e.currentTarget.value));
3277
+ },
3278
+ children: zoomOptions.map((option) => /* @__PURE__ */ jsx21(
3279
+ "option",
3280
+ {
3281
+ value: option.value,
3282
+ label: option.label
3283
+ },
3284
+ option.label
3285
+ ))
3286
+ }
3287
+ )
3288
+ ] })
3289
+ ] }) }),
3290
+ /* @__PURE__ */ jsx21(
3291
+ "button",
3292
+ {
3293
+ className: getClassName13("toggleButton"),
3294
+ title: "Toggle viewport menu",
3295
+ "aria-expanded": isExpanded,
3296
+ onClick: () => setIsExpanded((s) => !s),
3297
+ children: isExpanded ? /* @__PURE__ */ jsx21(X, { size: 16 }) : /* @__PURE__ */ jsx21(Monitor, { size: 16 })
3298
+ }
3299
+ )
3300
+ ]
3301
+ }
3302
+ );
3303
+ };
3304
+
3305
+ // components/CredBuild/components/Header/index.tsx
3306
+ import { useShallow as useShallow3 } from "zustand/react/shallow";
3307
+
3308
+ // lib/frame-context.tsx
3309
+ import {
3310
+ createContext as createContext5,
3311
+ useContext as useContext7,
3312
+ useRef as useRef6,
3313
+ useMemo as useMemo11
3314
+ } from "react";
3315
+ import { jsx as jsx22 } from "react/jsx-runtime";
3316
+ var FrameContext = createContext5(null);
3317
+ var FrameProvider = ({
3318
+ children
3319
+ }) => {
3320
+ const frameRef = useRef6(null);
3321
+ const value = useMemo11(
3322
+ () => ({
3323
+ frameRef
3324
+ }),
3325
+ []
3326
+ );
3327
+ return /* @__PURE__ */ jsx22(FrameContext.Provider, { value, children });
3328
+ };
3329
+ var useCanvasFrame = () => {
3330
+ const context = useContext7(FrameContext);
3331
+ if (context === null) {
3332
+ throw new Error("useCanvasFrame must be used within a FrameProvider");
3333
+ }
3334
+ return context;
3335
+ };
3336
+
3337
+ // css-module:/home/runner/work/credbuild/credbuild/components/CredBuild/components/Header/styles.module.css#css-module
3338
+ var styles_module_default14 = { "CredBuildHeader": "_CredBuildHeader_qzv5u_1", "CredBuildHeader-inner": "_CredBuildHeader-inner_qzv5u_20", "CredBuildHeader-viewportTools": "_CredBuildHeader-viewportTools_qzv5u_28", "CredBuildHeader-leftActions": "_CredBuildHeader-leftActions_qzv5u_35", "CredBuildHeader-toggle": "_CredBuildHeader-toggle_qzv5u_41", "CredBuildHeader-leftSideBarToggle": "_CredBuildHeader-leftSideBarToggle_qzv5u_47", "CredBuildHeader-rightSideBarToggle": "_CredBuildHeader-rightSideBarToggle_qzv5u_48", "CredBuildHeader-title": "_CredBuildHeader-title_qzv5u_52", "CredBuildHeader-path": "_CredBuildHeader-path_qzv5u_57", "CredBuildHeader-tools": "_CredBuildHeader-tools_qzv5u_68", "CredBuildHeader-menuButton": "_CredBuildHeader-menuButton_qzv5u_75" };
3339
+
3340
+ // components/CredBuild/components/Header/index.tsx
3341
+ import { Fragment as Fragment8, jsx as jsx23, jsxs as jsxs11 } from "react/jsx-runtime";
3342
+ var getClassName14 = get_class_name_factory_default("CredBuildHeader", styles_module_default14);
3343
+ var HeaderInner = ({
3344
+ hidePlugins,
3345
+ theme
3346
+ }) => {
3347
+ const {
3348
+ onPublish,
3349
+ renderHeader,
3350
+ renderHeaderActions,
3351
+ headerTitle,
3352
+ headerPath,
3353
+ iframe: _iframe
3354
+ } = usePropsContext();
3355
+ const dispatch = useAppStore((s) => s.dispatch);
3356
+ const appStore = useAppStoreApi();
3357
+ const defaultHeaderRender = useMemo12(() => {
3358
+ if (renderHeader) {
3359
+ console.warn(
3360
+ "`renderHeader` is deprecated. Please use `overrides.header` and the `useCredBuild` hook instead"
3361
+ );
3362
+ const RenderHeader = ({ actions, ...props }) => {
3363
+ const Comp = renderHeader;
3364
+ const appState = useAppStore((s) => s.state);
3365
+ return /* @__PURE__ */ jsx23(Comp, { ...props, dispatch, state: appState, children: actions });
3366
+ };
3367
+ return RenderHeader;
3368
+ }
3369
+ return DefaultOverride;
3370
+ }, [renderHeader, dispatch]);
3371
+ const defaultHeaderActionsRender = useMemo12(() => {
3372
+ if (renderHeaderActions) {
3373
+ console.warn(
3374
+ "`renderHeaderActions` is deprecated. Please use `overrides.headerActions` and the `useCredBuild` hook instead."
3375
+ );
3376
+ const RenderHeader = (props) => {
3377
+ const Comp = renderHeaderActions;
3378
+ const appState = useAppStore((s) => s.state);
3379
+ return /* @__PURE__ */ jsx23(Comp, { ...props, dispatch, state: appState });
3380
+ };
3381
+ return RenderHeader;
3382
+ }
3383
+ return DefaultOverride;
3384
+ }, [renderHeaderActions, dispatch]);
3385
+ const CustomHeader = useAppStore(
3386
+ (s) => s.overrides.header || defaultHeaderRender
3387
+ );
3388
+ const CustomHeaderActions = useAppStore(
3389
+ (s) => s.overrides.headerActions || defaultHeaderActionsRender
3390
+ );
3391
+ const [menuOpen, setMenuOpen] = useState11(false);
3392
+ const rootTitle = useAppStore((s) => {
3393
+ const rootData = s.state.indexes.nodes["root"]?.data;
3394
+ return rootData.props.title ?? "";
3395
+ });
3396
+ const root = useAppStore((s) => s.state.data.root);
3397
+ const rootProps = root?.props || root;
3398
+ const isHtmlMode = rootProps?.mode === "html";
3399
+ const htmlViewMode = rootProps?.htmlViewMode || (rootProps?.htmlCode ? "preview" : "code");
3400
+ const handleSetViewMode = useCallback7((modeVal) => {
3401
+ dispatch({
3402
+ type: "setData",
3403
+ data: (currentData) => ({
3404
+ ...currentData,
3405
+ root: {
3406
+ ...currentData.root,
3407
+ props: {
3408
+ ...currentData.root?.props,
3409
+ htmlViewMode: modeVal
3410
+ }
3411
+ }
3412
+ })
3413
+ });
3414
+ }, [dispatch]);
3415
+ const handleResetToBlocks = useCallback7(() => {
3416
+ dispatch({
3417
+ type: "setData",
3418
+ data: (currentData) => ({
3419
+ ...currentData,
3420
+ content: [],
3421
+ root: {
3422
+ ...currentData.root,
3423
+ props: {
3424
+ ...currentData.root?.props,
3425
+ mode: "blocks",
3426
+ htmlCode: "",
3427
+ htmlViewMode: "code"
3428
+ }
3429
+ }
3430
+ })
3431
+ });
3432
+ }, [dispatch]);
3433
+ const leftSideBarVisible = useAppStore((s) => s.state.ui.leftSideBarVisible);
3434
+ const rightSideBarVisible = useAppStore(
3435
+ (s) => s.state.ui.rightSideBarVisible
3436
+ );
3437
+ const {
3438
+ setUi,
3439
+ zoomConfig,
3440
+ setZoomConfig,
3441
+ _experimentalFullScreenCanvas
3442
+ } = useAppStore(
3443
+ useShallow3((s) => ({
3444
+ setUi: s.setUi,
3445
+ zoomConfig: s.zoomConfig,
3446
+ setZoomConfig: s.setZoomConfig,
3447
+ _experimentalFullScreenCanvas: s._experimentalFullScreenCanvas
3448
+ }))
3449
+ );
3450
+ const { viewports } = useAppStore(
3451
+ useShallow3((s) => ({
3452
+ viewports: s.state.ui.viewports
3453
+ }))
3454
+ );
3455
+ const { frameRef } = useCanvasFrame();
3456
+ const resetAutoZoom = useResetAutoZoom(frameRef);
3457
+ const toggleSidebars = useCallback7(
3458
+ (sidebar) => {
3459
+ const widerViewport = window.matchMedia("(min-width: 638px)").matches;
3460
+ const sideBarVisible = sidebar === "left" ? leftSideBarVisible : rightSideBarVisible;
3461
+ const oppositeSideBar = sidebar === "left" ? "rightSideBarVisible" : "leftSideBarVisible";
3462
+ dispatch({
3463
+ type: "setUi",
3464
+ ui: {
3465
+ [`${sidebar}SideBarVisible`]: !sideBarVisible,
3466
+ ...!widerViewport ? { [oppositeSideBar]: false } : {}
3467
+ }
3468
+ });
3469
+ },
3470
+ [dispatch, leftSideBarVisible, rightSideBarVisible]
3471
+ );
3472
+ return /* @__PURE__ */ jsx23(
3473
+ CustomHeader,
3474
+ {
3475
+ actions: /* @__PURE__ */ jsx23(Fragment8, { children: /* @__PURE__ */ jsxs11(CustomHeaderActions, { children: [
3476
+ /* @__PURE__ */ jsx23(
3477
+ Button,
3478
+ {
3479
+ href: headerPath || "/",
3480
+ newTab: true,
3481
+ variant: "secondary",
3482
+ icon: /* @__PURE__ */ jsx23(ExternalLink, { size: 14 }),
3483
+ children: "View Web"
3484
+ }
3485
+ ),
3486
+ /* @__PURE__ */ jsx23("span", { className: "PublishButton", children: /* @__PURE__ */ jsx23(
3487
+ Button,
3488
+ {
3489
+ onClick: () => {
3490
+ const data = appStore.getState().state.data;
3491
+ onPublish && onPublish(data);
3492
+ },
3493
+ icon: /* @__PURE__ */ jsx23(Zap, { size: 14, fill: "currentColor" }),
3494
+ children: "Publish"
3495
+ }
3496
+ ) })
3497
+ ] }) }),
3498
+ children: /* @__PURE__ */ jsx23(
3499
+ "header",
3500
+ {
3501
+ className: getClassName14({
3502
+ leftSideBarVisible,
3503
+ rightSideBarVisible,
3504
+ hidePlugins
3505
+ }),
3506
+ children: /* @__PURE__ */ jsxs11("div", { className: getClassName14("inner"), children: [
3507
+ /* @__PURE__ */ jsxs11("div", { className: getClassName14("leftActions"), children: [
3508
+ /* @__PURE__ */ jsxs11("div", { style: { marginRight: "8px", display: "flex", gap: "8px", alignItems: "center" }, children: [
3509
+ /* @__PURE__ */ jsx23(
3510
+ Button,
3511
+ {
3512
+ href: "/dashboard",
3513
+ variant: "secondary",
3514
+ size: "medium",
3515
+ icon: /* @__PURE__ */ jsx23(LayoutDashboard, { size: 14 }),
3516
+ children: "Dashboard"
3517
+ }
3518
+ ),
3519
+ /* @__PURE__ */ jsx23(
3520
+ IconButton,
3521
+ {
3522
+ type: "button",
3523
+ onClick: () => {
3524
+ const editorEl = document.querySelector(".CredBuild");
3525
+ if (!editorEl) return;
3526
+ const isDark = editorEl.classList.contains("dark");
3527
+ const newTheme = isDark ? "light" : "dark";
3528
+ if (isDark) {
3529
+ editorEl.classList.remove("dark");
3530
+ } else {
3531
+ editorEl.classList.add("dark");
3532
+ }
3533
+ localStorage.setItem("credbuild-theme", newTheme);
3534
+ window.dispatchEvent(new CustomEvent("credbuild-theme-change", { detail: newTheme }));
3535
+ },
3536
+ title: "Toggle Theme",
3537
+ children: theme === "dark" ? /* @__PURE__ */ jsx23(Sun, { size: 16 }) : /* @__PURE__ */ jsx23(Moon, { size: 16 })
3538
+ }
3539
+ )
3540
+ ] }),
3541
+ /* @__PURE__ */ jsxs11("div", { className: getClassName14("toggle"), children: [
3542
+ /* @__PURE__ */ jsx23("div", { className: getClassName14("leftSideBarToggle"), children: /* @__PURE__ */ jsx23(
3543
+ IconButton,
3544
+ {
3545
+ type: "button",
3546
+ onClick: () => {
3547
+ toggleSidebars("left");
3548
+ },
3549
+ title: "Toggle left sidebar",
3550
+ children: /* @__PURE__ */ jsx23(PanelLeft, { size: 16, focusable: "false" })
3551
+ }
3552
+ ) }),
3553
+ /* @__PURE__ */ jsx23("div", { className: getClassName14("rightSideBarToggle"), children: /* @__PURE__ */ jsx23(
3554
+ IconButton,
3555
+ {
3556
+ type: "button",
3557
+ onClick: () => {
3558
+ toggleSidebars("right");
3559
+ },
3560
+ title: "Toggle right sidebar",
3561
+ children: /* @__PURE__ */ jsx23(PanelRight, { size: 16, focusable: "false" })
3562
+ }
3563
+ ) })
3564
+ ] }),
3565
+ /* @__PURE__ */ jsx23("div", { className: getClassName14("title"), children: /* @__PURE__ */ jsxs11(Heading, { rank: "2", size: "xs", children: [
3566
+ /* @__PURE__ */ jsx23("span", { style: { fontSize: "11px", textTransform: "uppercase", letterSpacing: "0.08em", fontWeight: 600 }, children: headerTitle || rootTitle || "Page" }),
3567
+ headerPath && /* @__PURE__ */ jsx23(Fragment8, { children: /* @__PURE__ */ jsx23("code", { className: getClassName14("path"), style: { fontSize: "10px", opacity: 0.6, marginLeft: "8px" }, children: headerPath }) })
3568
+ ] }) })
3569
+ ] }),
3570
+ /* @__PURE__ */ jsxs11("div", { className: getClassName14("viewportTools"), style: { display: "flex", gap: "16px", alignItems: "center" }, children: [
3571
+ isHtmlMode && /* @__PURE__ */ jsxs11("div", { style: {
3572
+ display: "flex",
3573
+ alignItems: "center",
3574
+ gap: "8px"
3575
+ }, children: [
3576
+ /* @__PURE__ */ jsxs11("div", { style: {
3577
+ display: "flex",
3578
+ background: "var(--credbuild-color-grey-09)",
3579
+ padding: 2,
3580
+ borderRadius: 6,
3581
+ border: "1px solid var(--credbuild-color-grey-10)"
3582
+ }, children: [
3583
+ /* @__PURE__ */ jsxs11(
3584
+ "button",
3585
+ {
3586
+ type: "button",
3587
+ onClick: () => handleSetViewMode("code"),
3588
+ style: {
3589
+ display: "flex",
3590
+ alignItems: "center",
3591
+ gap: 4,
3592
+ padding: "4px 10px",
3593
+ borderRadius: 4,
3594
+ fontSize: 11,
3595
+ fontWeight: 600,
3596
+ cursor: "pointer",
3597
+ border: "none",
3598
+ background: htmlViewMode === "code" ? "var(--credbuild-color-white)" : "transparent",
3599
+ color: "var(--credbuild-color-black)",
3600
+ opacity: htmlViewMode === "code" ? 1 : 0.6,
3601
+ boxShadow: htmlViewMode === "code" ? "0 1px 2px rgba(0,0,0,0.1)" : "none",
3602
+ transition: "all 0.15s ease"
3603
+ },
3604
+ children: [
3605
+ /* @__PURE__ */ jsx23(Code, { size: 12 }),
3606
+ "Edit Kode"
3607
+ ]
3608
+ }
3609
+ ),
3610
+ /* @__PURE__ */ jsxs11(
3611
+ "button",
3612
+ {
3613
+ type: "button",
3614
+ onClick: () => handleSetViewMode("preview"),
3615
+ style: {
3616
+ display: "flex",
3617
+ alignItems: "center",
3618
+ gap: 4,
3619
+ padding: "4px 10px",
3620
+ borderRadius: 4,
3621
+ fontSize: 11,
3622
+ fontWeight: 600,
3623
+ cursor: "pointer",
3624
+ border: "none",
3625
+ background: htmlViewMode === "preview" ? "var(--credbuild-color-white)" : "transparent",
3626
+ color: "var(--credbuild-color-black)",
3627
+ opacity: htmlViewMode === "preview" ? 1 : 0.6,
3628
+ boxShadow: htmlViewMode === "preview" ? "0 1px 2px rgba(0,0,0,0.1)" : "none",
3629
+ transition: "all 0.15s ease"
3630
+ },
3631
+ children: [
3632
+ /* @__PURE__ */ jsx23(Eye, { size: 12 }),
3633
+ "Lihat Hasil"
3634
+ ]
3635
+ }
3636
+ )
3637
+ ] }),
3638
+ /* @__PURE__ */ jsx23(
3639
+ Button,
3640
+ {
3641
+ type: "button",
3642
+ onClick: handleResetToBlocks,
3643
+ variant: "secondary",
3644
+ size: "medium",
3645
+ icon: /* @__PURE__ */ jsx23(LayoutGrid, { size: 14 }),
3646
+ children: "Kembali ke Mode Blok"
3647
+ }
3648
+ )
3649
+ ] }),
3650
+ (!isHtmlMode || htmlViewMode === "preview") && /* @__PURE__ */ jsx23(
3651
+ ViewportControls,
3652
+ {
3653
+ fullScreen: _experimentalFullScreenCanvas,
3654
+ autoZoom: zoomConfig.autoZoom,
3655
+ zoom: zoomConfig.zoom,
3656
+ onViewportChange: (viewport) => {
3657
+ const isFullWidth = viewport.width === "100%";
3658
+ const uiViewport = {
3659
+ ...viewport,
3660
+ height: viewport.height || "auto",
3661
+ zoom: isFullWidth ? 1 : zoomConfig.zoom
3662
+ };
3663
+ const newUi = {
3664
+ viewports: { ...viewports, current: uiViewport }
3665
+ };
3666
+ if (isFullWidth) {
3667
+ setZoomConfig({ ...zoomConfig, zoom: 1 });
3668
+ }
3669
+ setUi(newUi);
3670
+ },
3671
+ onZoom: (zoom) => {
3672
+ setZoomConfig({ ...zoomConfig, zoom });
3673
+ }
3674
+ }
3675
+ )
3676
+ ] }),
3677
+ /* @__PURE__ */ jsxs11("div", { className: getClassName14("tools"), children: [
3678
+ /* @__PURE__ */ jsx23("div", { className: getClassName14("menuButton"), children: /* @__PURE__ */ jsx23(
3679
+ IconButton,
3680
+ {
3681
+ type: "button",
3682
+ onClick: () => {
3683
+ return setMenuOpen(!menuOpen);
3684
+ },
3685
+ title: "Toggle menu bar",
3686
+ children: menuOpen ? /* @__PURE__ */ jsx23(ChevronUp, { size: 16, focusable: "false" }) : /* @__PURE__ */ jsx23(ChevronDown, { size: 16, focusable: "false" })
3687
+ }
3688
+ ) }),
3689
+ /* @__PURE__ */ jsx23(
3690
+ MenuBar,
3691
+ {
3692
+ dispatch,
3693
+ onPublish,
3694
+ menuOpen,
3695
+ renderHeaderActions: () => /* @__PURE__ */ jsxs11(CustomHeaderActions, { children: [
3696
+ /* @__PURE__ */ jsx23(
3697
+ Button,
3698
+ {
3699
+ href: headerPath || "/",
3700
+ newTab: true,
3701
+ variant: "secondary",
3702
+ icon: /* @__PURE__ */ jsx23(ExternalLink, { size: 14 }),
3703
+ children: "View Web"
3704
+ }
3705
+ ),
3706
+ /* @__PURE__ */ jsx23("span", { className: "PublishButton", children: /* @__PURE__ */ jsx23(
3707
+ Button,
3708
+ {
3709
+ onClick: () => {
3710
+ const data = appStore.getState().state.data;
3711
+ onPublish && onPublish(data);
3712
+ },
3713
+ icon: /* @__PURE__ */ jsx23(Zap, { size: 14, fill: "currentColor" }),
3714
+ children: "Publish"
3715
+ }
3716
+ ) })
3717
+ ] }),
3718
+ setMenuOpen
3719
+ }
3720
+ )
3721
+ ] })
3722
+ ] })
3723
+ }
3724
+ )
3725
+ }
3726
+ );
3727
+ };
3728
+ var Header = memo5(HeaderInner);
3729
+
3730
+ // css-module:/home/runner/work/credbuild/credbuild/components/SidebarSection/styles.module.css#css-module
3731
+ var styles_module_default15 = { "SidebarSection": "_SidebarSection_bv89x_1", "SidebarSection-title": "_SidebarSection-title_bv89x_12", "SidebarSection--noBorderTop": "_SidebarSection--noBorderTop_bv89x_37", "SidebarSection-content": "_SidebarSection-content_bv89x_41", "SidebarSection-breadcrumbLabel": "_SidebarSection-breadcrumbLabel_bv89x_50", "SidebarSection-breadcrumbs": "_SidebarSection-breadcrumbs_bv89x_79", "SidebarSection-breadcrumb": "_SidebarSection-breadcrumb_bv89x_50", "SidebarSection-heading": "_SidebarSection-heading_bv89x_91", "SidebarSection-loadingOverlay": "_SidebarSection-loadingOverlay_bv89x_95" };
3732
+
3733
+ // components/SidebarSection/index.tsx
3734
+ import { jsx as jsx24, jsxs as jsxs12 } from "react/jsx-runtime";
3735
+ var getClassName15 = get_class_name_factory_default("SidebarSection", styles_module_default15);
3736
+ var SidebarSection = ({
3737
+ children,
3738
+ title,
3739
+ background,
3740
+ showBreadcrumbs,
3741
+ noBorderTop,
3742
+ isLoading
3743
+ }) => {
3744
+ return /* @__PURE__ */ jsxs12("div", { className: getClassName15({ noBorderTop }), style: { background }, children: [
3745
+ /* @__PURE__ */ jsx24("div", { className: getClassName15("title"), children: /* @__PURE__ */ jsxs12("div", { className: getClassName15("breadcrumbs"), children: [
3746
+ showBreadcrumbs && /* @__PURE__ */ jsx24(Breadcrumbs, {}),
3747
+ /* @__PURE__ */ jsx24("div", { className: getClassName15("heading"), children: /* @__PURE__ */ jsx24(Heading, { rank: "2", size: "xs", children: title }) })
3748
+ ] }) }),
3749
+ /* @__PURE__ */ jsx24("div", { className: getClassName15("content"), children }),
3750
+ isLoading && /* @__PURE__ */ jsx24("div", { className: getClassName15("loadingOverlay"), children: /* @__PURE__ */ jsx24(Loader, { size: 32 }) })
3751
+ ] });
3752
+ };
3753
+
3754
+ // components/CredBuild/components/Canvas/index.tsx
3755
+ import {
3756
+ useCallback as useCallback8,
3757
+ useEffect as useEffect11,
3758
+ useMemo as useMemo13,
3759
+ useRef as useRef7,
3760
+ useState as useState12
3761
+ } from "react";
3762
+
3763
+ // css-module:/home/runner/work/credbuild/credbuild/components/CredBuild/components/Canvas/styles.module.css#css-module
3764
+ var styles_module_default16 = { "CredBuildCanvas": "_CredBuildCanvas_1ivia_1", "CredBuildCanvas--fullScreen": "_CredBuildCanvas--fullScreen_1ivia_22", "CredBuildCanvas-inner": "_CredBuildCanvas-inner_1ivia_33", "CredBuildCanvas-root": "_CredBuildCanvas-root_1ivia_42", "CredBuildCanvas--ready": "_CredBuildCanvas--ready_1ivia_67", "CredBuildCanvas-loader": "_CredBuildCanvas-loader_1ivia_72", "CredBuildCanvas--showLoader": "_CredBuildCanvas--showLoader_1ivia_82" };
3765
+
3766
+ // components/CredBuild/components/Canvas/index.tsx
3767
+ import { useShallow as useShallow4 } from "zustand/react/shallow";
3768
+ import { Fragment as Fragment9, jsx as jsx25, jsxs as jsxs13 } from "react/jsx-runtime";
3769
+ var getClassName16 = get_class_name_factory_default("CredBuildCanvas", styles_module_default16);
3770
+ var ZOOM_ON_CHANGE = true;
3771
+ var TRANSITION_DURATION = 150;
3772
+ var Canvas = () => {
3773
+ const { frameRef } = useCanvasFrame();
3774
+ const resetAutoZoom = useResetAutoZoom(frameRef);
3775
+ const { viewports: viewportOptions = defaultViewports, ui: uiProp } = usePropsContext();
3776
+ const {
3777
+ dispatch,
3778
+ overrides,
3779
+ setUi,
3780
+ zoomConfig,
3781
+ setZoomConfig,
3782
+ status,
3783
+ iframe,
3784
+ _experimentalFullScreenCanvas
3785
+ } = useAppStore(
3786
+ useShallow4((s) => ({
3787
+ dispatch: s.dispatch,
3788
+ overrides: s.overrides,
3789
+ setUi: s.setUi,
3790
+ zoomConfig: s.zoomConfig,
3791
+ setZoomConfig: s.setZoomConfig,
3792
+ status: s.status,
3793
+ iframe: s.iframe,
3794
+ _experimentalFullScreenCanvas: s._experimentalFullScreenCanvas
3795
+ }))
3796
+ );
3797
+ const {
3798
+ leftSideBarVisible,
3799
+ rightSideBarVisible,
3800
+ leftSideBarWidth,
3801
+ rightSideBarWidth,
3802
+ viewports,
3803
+ root
3804
+ } = useAppStore(
3805
+ useShallow4((s) => ({
3806
+ leftSideBarVisible: s.state.ui.leftSideBarVisible,
3807
+ rightSideBarVisible: s.state.ui.rightSideBarVisible,
3808
+ leftSideBarWidth: s.state.ui.leftSideBarWidth,
3809
+ rightSideBarWidth: s.state.ui.rightSideBarWidth,
3810
+ viewports: s.state.ui.viewports,
3811
+ root: s.state.data.root
3812
+ }))
3813
+ );
3814
+ const isNonFullWidth = viewports.current.width !== "100%";
3815
+ const shouldApplyViewport = true;
3816
+ const [showTransition, setShowTransition] = useState12(false);
3817
+ const isResizingRef = useRef7(false);
3818
+ const defaultRender = useMemo13(() => {
3819
+ const CredBuildDefault = ({ children }) => /* @__PURE__ */ jsx25(Fragment9, { children });
3820
+ return CredBuildDefault;
3821
+ }, []);
3822
+ const CustomPreview = useMemo13(
3823
+ () => overrides.preview || defaultRender,
3824
+ [overrides, defaultRender]
3825
+ );
3826
+ const getFrameDimensions = useCallback8(() => {
3827
+ if (frameRef.current) {
3828
+ const frame = frameRef.current;
3829
+ const box = getBox(frame);
3830
+ return { width: box.contentBox.width, height: box.contentBox.height };
3831
+ }
3832
+ return { width: 0, height: 0 };
3833
+ }, [frameRef]);
3834
+ useEffect11(() => {
3835
+ resetAutoZoom();
3836
+ }, [
3837
+ frameRef,
3838
+ leftSideBarVisible,
3839
+ rightSideBarVisible,
3840
+ rightSideBarWidth,
3841
+ viewports,
3842
+ resetAutoZoom
3843
+ ]);
3844
+ useEffect11(() => {
3845
+ const updateRootHeight = () => {
3846
+ const iframeEl = frameRef.current?.querySelector("iframe");
3847
+ if (iframeEl) {
3848
+ try {
3849
+ const doc = iframeEl.contentDocument;
3850
+ if (doc && doc.body) {
3851
+ const contentHeight = doc.body.scrollHeight || doc.documentElement.scrollHeight;
3852
+ if (contentHeight > 0) {
3853
+ const newRootHeight2 = contentHeight;
3854
+ if (zoomConfig.rootHeight !== newRootHeight2) {
3855
+ setZoomConfig({
3856
+ ...zoomConfig,
3857
+ rootHeight: newRootHeight2
3858
+ });
3859
+ }
3860
+ return;
3861
+ }
3862
+ }
3863
+ } catch (e) {
3864
+ }
3865
+ }
3866
+ const { height: frameHeight } = getFrameDimensions();
3867
+ const newRootHeight = frameHeight / zoomConfig.zoom;
3868
+ if (zoomConfig.rootHeight !== newRootHeight) {
3869
+ setZoomConfig({
3870
+ ...zoomConfig,
3871
+ rootHeight: newRootHeight
3872
+ });
3873
+ }
3874
+ };
3875
+ if (viewports.current.height === "auto") {
3876
+ updateRootHeight();
3877
+ const iframeEl = frameRef.current?.querySelector("iframe");
3878
+ if (iframeEl) {
3879
+ try {
3880
+ const doc = iframeEl.contentDocument;
3881
+ if (doc && doc.body) {
3882
+ const observer = new ResizeObserver(updateRootHeight);
3883
+ observer.observe(doc.body);
3884
+ return () => observer.disconnect();
3885
+ }
3886
+ } catch (e) {
3887
+ }
3888
+ }
3889
+ }
3890
+ }, [
3891
+ zoomConfig.zoom,
3892
+ getFrameDimensions,
3893
+ setZoomConfig,
3894
+ viewports,
3895
+ zoomConfig.rootHeight,
3896
+ frameRef
3897
+ ]);
3898
+ useEffect11(() => {
3899
+ if (ZOOM_ON_CHANGE) {
3900
+ resetAutoZoom();
3901
+ }
3902
+ }, [viewports.current.width, viewports, resetAutoZoom]);
3903
+ useEffect11(() => {
3904
+ if (!frameRef.current) return;
3905
+ const resizeObserver = new ResizeObserver(() => {
3906
+ if (!isResizingRef.current) {
3907
+ resetAutoZoom();
3908
+ }
3909
+ });
3910
+ resizeObserver.observe(frameRef.current);
3911
+ return () => {
3912
+ resizeObserver.disconnect();
3913
+ };
3914
+ }, [frameRef, resetAutoZoom]);
3915
+ const [showLoader, setShowLoader] = useState12(false);
3916
+ useEffect11(() => {
3917
+ setTimeout(() => {
3918
+ setShowLoader(true);
3919
+ }, 500);
3920
+ }, []);
3921
+ const appStoreApi = useAppStoreApi();
3922
+ useEffect11(() => {
3923
+ if (typeof window === "undefined") return;
3924
+ if (uiProp?.viewports?.current) return;
3925
+ const viewportWidth = window.innerWidth;
3926
+ const frameWidth = frameRef.current?.getBoundingClientRect().width;
3927
+ if (!viewportWidth) return;
3928
+ if (!frameWidth) return;
3929
+ if (viewportOptions.length === 0) return;
3930
+ const fullWidthViewport = Object.values(viewportOptions).find(
3931
+ (v) => v.width === "100%"
3932
+ );
3933
+ const containsFullWidthViewport = !!fullWidthViewport;
3934
+ const viewportDifferences = Object.entries(viewportOptions).filter(([_, value]) => value.width !== "100%").map(([key, value]) => ({
3935
+ key,
3936
+ diff: Math.abs(
3937
+ viewportWidth - (typeof value.width === "string" ? viewportWidth : value.width)
3938
+ ),
3939
+ value
3940
+ })).sort((a, b) => a.diff > b.diff ? 1 : -1);
3941
+ let closestViewport = viewportDifferences[0].value;
3942
+ if (closestViewport.width < frameWidth && containsFullWidthViewport) {
3943
+ closestViewport = fullWidthViewport;
3944
+ }
3945
+ {
3946
+ const s = appStoreApi.getState();
3947
+ const appState = {
3948
+ state: {
3949
+ ...s.state,
3950
+ ui: {
3951
+ ...s.state.ui,
3952
+ viewports: {
3953
+ ...s.state.ui.viewports,
3954
+ current: {
3955
+ ...s.state.ui.viewports.current,
3956
+ height: closestViewport?.height || "auto",
3957
+ width: closestViewport?.width
3958
+ }
3959
+ }
3960
+ }
3961
+ }
3962
+ };
3963
+ let history = s.history;
3964
+ if (s.history.histories.length === 1) {
3965
+ history = { ...history, histories: [appState] };
3966
+ }
3967
+ appStoreApi.setState({ ...appState, history });
3968
+ }
3969
+ }, [
3970
+ viewportOptions,
3971
+ iframe,
3972
+ appStoreApi,
3973
+ uiProp?.viewports,
3974
+ frameRef
3975
+ ]);
3976
+ return /* @__PURE__ */ jsx25(
3977
+ "div",
3978
+ {
3979
+ className: getClassName16({
3980
+ ready: status === "READY" || !iframe.enabled || !iframe.waitForStyles,
3981
+ showLoader,
3982
+ fullScreen: _experimentalFullScreenCanvas
3983
+ }),
3984
+ onClick: (e) => {
3985
+ const el = e.target;
3986
+ if (!el.hasAttribute("data-credbuild-component") && !el.hasAttribute("data-credbuild-dropzone")) {
3987
+ dispatch({
3988
+ type: "setUi",
3989
+ ui: { itemSelector: null },
3990
+ recordHistory: false
3991
+ });
3992
+ }
3993
+ },
3994
+ children: /* @__PURE__ */ jsxs13("div", { className: getClassName16("inner"), ref: frameRef, children: [
3995
+ /* @__PURE__ */ jsx25(
3996
+ "div",
3997
+ {
3998
+ className: getClassName16("root"),
3999
+ style: {
4000
+ width: viewports.current.width || "100%",
4001
+ height: !zoomConfig.rootHeight || isNaN(zoomConfig.rootHeight) ? "100%" : zoomConfig.rootHeight,
4002
+ minHeight: "100%",
4003
+ transform: `scale(${zoomConfig.zoom})`,
4004
+ transition: showTransition ? `width ${TRANSITION_DURATION}ms ease-out, height ${TRANSITION_DURATION}ms ease-out, transform ${TRANSITION_DURATION}ms ease-out` : "",
4005
+ overflow: isNonFullWidth ? void 0 : "auto"
4006
+ },
4007
+ suppressHydrationWarning: true,
4008
+ id: "credbuild-canvas-root",
4009
+ onTransitionEnd: () => {
4010
+ setShowTransition(false);
4011
+ isResizingRef.current = false;
4012
+ },
4013
+ children: /* @__PURE__ */ jsx25(CustomPreview, { children: /* @__PURE__ */ jsx25(Preview, {}) })
4014
+ }
4015
+ ),
4016
+ /* @__PURE__ */ jsx25("div", { className: getClassName16("loader"), children: /* @__PURE__ */ jsx25(Loader, { size: 24 }) })
4017
+ ] })
4018
+ }
4019
+ );
4020
+ };
4021
+
4022
+ // lib/use-sidebar-resize.ts
4023
+ import { useCallback as useCallback9, useEffect as useEffect12, useRef as useRef8, useState as useState13 } from "react";
4024
+ function useSidebarResize(position, dispatch) {
4025
+ const [width, setWidth] = useState13(null);
4026
+ const sidebarRef = useRef8(null);
4027
+ const storeWidth = useAppStore(
4028
+ (s) => position === "left" ? s.state.ui.leftSideBarWidth : s.state.ui.rightSideBarWidth
4029
+ );
4030
+ useEffect12(() => {
4031
+ if (typeof window !== "undefined" && !storeWidth) {
4032
+ try {
4033
+ const savedWidths = localStorage.getItem("credbuild-sidebar-widths");
4034
+ if (savedWidths) {
4035
+ const widths = JSON.parse(savedWidths);
4036
+ const savedWidth = widths[position];
4037
+ const key = position === "left" ? "leftSideBarWidth" : "rightSideBarWidth";
4038
+ if (savedWidth) {
4039
+ dispatch({
4040
+ type: "setUi",
4041
+ ui: {
4042
+ [key]: savedWidth
4043
+ }
4044
+ });
4045
+ }
4046
+ }
4047
+ } catch (error) {
4048
+ console.error(
4049
+ `Failed to load ${position} sidebar width from localStorage`,
4050
+ error
4051
+ );
4052
+ }
4053
+ }
4054
+ }, [dispatch, position, storeWidth]);
4055
+ useEffect12(() => {
4056
+ if (storeWidth !== void 0) {
4057
+ setWidth(storeWidth);
4058
+ }
4059
+ }, [storeWidth]);
4060
+ const handleResizeEnd = useCallback9(
4061
+ (width2) => {
4062
+ dispatch({
4063
+ type: "setUi",
4064
+ ui: {
4065
+ [position === "left" ? "leftSideBarWidth" : "rightSideBarWidth"]: width2
4066
+ }
4067
+ });
4068
+ let widths = {};
4069
+ try {
4070
+ const savedWidths = localStorage.getItem("credbuild-sidebar-widths");
4071
+ widths = savedWidths ? JSON.parse(savedWidths) : {};
4072
+ } catch (error) {
4073
+ console.error(
4074
+ `Failed to save ${position} sidebar width to localStorage`,
4075
+ error
4076
+ );
4077
+ } finally {
4078
+ localStorage.setItem(
4079
+ "credbuild-sidebar-widths",
4080
+ JSON.stringify({
4081
+ ...widths,
4082
+ [position]: width2
4083
+ })
4084
+ );
4085
+ }
4086
+ window.dispatchEvent(
4087
+ new CustomEvent("viewportchange", {
4088
+ bubbles: true,
4089
+ cancelable: false
4090
+ })
4091
+ );
4092
+ },
4093
+ [dispatch, position]
4094
+ );
4095
+ return {
4096
+ width,
4097
+ setWidth,
4098
+ sidebarRef,
4099
+ handleResizeEnd
4100
+ };
4101
+ }
4102
+
4103
+ // components/CredBuild/components/ResizeHandle/index.tsx
4104
+ import { useCallback as useCallback10, useRef as useRef9 } from "react";
4105
+
4106
+ // css-module:/home/runner/work/credbuild/credbuild/components/CredBuild/components/ResizeHandle/styles.module.css#css-module
4107
+ var styles_module_default17 = { "ResizeHandle": "_ResizeHandle_144bf_2", "ResizeHandle--left": "_ResizeHandle--left_144bf_16", "ResizeHandle--right": "_ResizeHandle--right_144bf_20" };
4108
+
4109
+ // components/CredBuild/components/ResizeHandle/index.tsx
4110
+ import { jsx as jsx26 } from "react/jsx-runtime";
4111
+ var getClassName17 = get_class_name_factory_default("ResizeHandle", styles_module_default17);
4112
+ var ResizeHandle = ({
4113
+ position,
4114
+ sidebarRef,
4115
+ onResize,
4116
+ onResizeEnd
4117
+ }) => {
4118
+ const { frameRef } = useCanvasFrame();
4119
+ const resetAutoZoom = useResetAutoZoom(frameRef);
4120
+ const handleRef = useRef9(null);
4121
+ const isDragging = useRef9(false);
4122
+ const startX = useRef9(0);
4123
+ const startWidth = useRef9(0);
4124
+ const handleMouseMove = useCallback10(
4125
+ (e) => {
4126
+ if (!isDragging.current) return;
4127
+ const delta = e.clientX - startX.current;
4128
+ const newWidth = position === "left" ? startWidth.current + delta : startWidth.current - delta;
4129
+ const width = Math.max(192, newWidth);
4130
+ onResize(width);
4131
+ e.preventDefault();
4132
+ },
4133
+ [onResize, position]
4134
+ );
4135
+ const handleMouseUp = useCallback10(() => {
4136
+ if (!isDragging.current) return;
4137
+ isDragging.current = false;
4138
+ document.body.style.cursor = "";
4139
+ document.body.style.userSelect = "";
4140
+ const overlay = document.getElementById("resize-overlay");
4141
+ if (overlay) {
4142
+ document.body.removeChild(overlay);
4143
+ }
4144
+ document.removeEventListener("mousemove", handleMouseMove);
4145
+ document.removeEventListener("mouseup", handleMouseUp);
4146
+ const finalWidth = sidebarRef.current?.getBoundingClientRect().width || 0;
4147
+ onResizeEnd(finalWidth);
4148
+ resetAutoZoom();
4149
+ }, [onResizeEnd, handleMouseMove, resetAutoZoom, sidebarRef]);
4150
+ const handleMouseDown = useCallback10(
4151
+ (e) => {
4152
+ isDragging.current = true;
4153
+ startX.current = e.clientX;
4154
+ startWidth.current = sidebarRef.current?.getBoundingClientRect().width || 0;
4155
+ document.body.style.cursor = "col-resize";
4156
+ document.body.style.userSelect = "none";
4157
+ const overlay = document.createElement("div");
4158
+ overlay.id = "resize-overlay";
4159
+ overlay.setAttribute("data-resize-overlay", "");
4160
+ document.body.appendChild(overlay);
4161
+ document.addEventListener("mousemove", handleMouseMove);
4162
+ document.addEventListener("mouseup", handleMouseUp);
4163
+ e.preventDefault();
4164
+ },
4165
+ [handleMouseMove, handleMouseUp, sidebarRef]
4166
+ );
4167
+ return /* @__PURE__ */ jsx26(
4168
+ "div",
4169
+ {
4170
+ ref: handleRef,
4171
+ className: getClassName17({ [position]: true }),
4172
+ onMouseDown: handleMouseDown
4173
+ }
4174
+ );
4175
+ };
4176
+
4177
+ // css-module:/home/runner/work/credbuild/credbuild/components/CredBuild/components/Sidebar/styles.module.css#css-module
4178
+ var styles_module_default18 = { "Sidebar": "_Sidebar_1kcif_1", "Sidebar--isVisible": "_Sidebar--isVisible_1kcif_13", "Sidebar--left": "_Sidebar--left_1kcif_17", "Sidebar--right": "_Sidebar--right_1kcif_29", "Sidebar-resizeHandle": "_Sidebar-resizeHandle_1kcif_42" };
4179
+
4180
+ // components/CredBuild/components/Sidebar/index.tsx
4181
+ import { Fragment as Fragment10, jsx as jsx27, jsxs as jsxs14 } from "react/jsx-runtime";
4182
+ var getClassName18 = get_class_name_factory_default("Sidebar", styles_module_default18);
4183
+ var Sidebar = ({
4184
+ position,
4185
+ sidebarRef,
4186
+ isVisible,
4187
+ onResize,
4188
+ onResizeEnd,
4189
+ children
4190
+ }) => {
4191
+ return /* @__PURE__ */ jsxs14(Fragment10, { children: [
4192
+ /* @__PURE__ */ jsx27(
4193
+ "div",
4194
+ {
4195
+ ref: sidebarRef,
4196
+ className: getClassName18({ [position]: true, isVisible }),
4197
+ children
4198
+ }
4199
+ ),
4200
+ /* @__PURE__ */ jsx27("div", { className: `${getClassName18("resizeHandle")}`, children: /* @__PURE__ */ jsx27(
4201
+ ResizeHandle,
4202
+ {
4203
+ position,
4204
+ sidebarRef,
4205
+ onResize,
4206
+ onResizeEnd
4207
+ }
4208
+ ) })
4209
+ ] });
4210
+ };
4211
+
4212
+ // lib/use-delete-hotkeys.ts
4213
+ import { useCallback as useCallback11 } from "react";
4214
+ var isElementVisible = (element) => {
4215
+ let current = element;
4216
+ while (current && current !== document.body) {
4217
+ const style = window.getComputedStyle(current);
4218
+ if (style.display === "none" || style.visibility === "hidden" || style.opacity === "0" || current.getAttribute("aria-hidden") === "true" || current.hasAttribute("hidden")) {
4219
+ return false;
4220
+ }
4221
+ current = current.parentElement;
4222
+ }
4223
+ return true;
4224
+ };
4225
+ var shouldBlockDeleteHotkey = (e) => {
4226
+ if (e?.defaultPrevented) return true;
4227
+ const origin = e?.composedPath?.()[0] || e?.target || document.activeElement;
4228
+ if (origin instanceof HTMLElement) {
4229
+ const tag = origin.tagName.toLowerCase();
4230
+ if (tag === "input" || tag === "textarea" || tag === "select") return true;
4231
+ if (origin.isContentEditable) return true;
4232
+ const role = origin.getAttribute("role");
4233
+ if (role === "textbox" || role === "combobox" || role === "searchbox" || role === "listbox" || role === "grid") {
4234
+ return true;
4235
+ }
4236
+ }
4237
+ const modal = document.querySelector(
4238
+ 'dialog[open], [aria-modal="true"], [role="dialog"], [role="alertdialog"]'
4239
+ );
4240
+ if (modal && isElementVisible(modal)) {
4241
+ return true;
4242
+ }
4243
+ return false;
4244
+ };
4245
+ var useDeleteHotkeys = () => {
4246
+ const appStore = useAppStoreApi();
4247
+ const deleteSelectedComponent = useCallback11(
4248
+ (e) => {
4249
+ if (shouldBlockDeleteHotkey(e)) {
4250
+ return false;
4251
+ }
4252
+ const { state, dispatch, permissions, selectedItem } = appStore.getState();
4253
+ const sel = state.ui?.itemSelector;
4254
+ if (!sel?.zone || !selectedItem) return true;
4255
+ if (!permissions.getPermissions({ item: selectedItem }).delete)
4256
+ return true;
4257
+ dispatch({
4258
+ type: "remove",
4259
+ index: sel.index,
4260
+ zone: sel.zone
4261
+ });
4262
+ return true;
4263
+ },
4264
+ [appStore]
4265
+ );
4266
+ useHotkey({ delete: true }, deleteSelectedComponent);
4267
+ useHotkey({ backspace: true }, deleteSelectedComponent);
4268
+ };
4269
+
4270
+ // css-module:/home/runner/work/credbuild/credbuild/components/CredBuild/components/Nav/styles.module.css#css-module
4271
+ var styles_module_default19 = { "Nav": "_Nav_wbh7e_1", "Nav-list": "_Nav-list_wbh7e_9", "CredBuildHeader-path": "_CredBuildHeader-path_wbh7e_20", "NavItem": "_NavItem_wbh7e_38", "NavItem-link": "_NavItem-link_wbh7e_43", "NavItem-linkIcon": "_NavItem-linkIcon_wbh7e_64", "NavItem--active": "_NavItem--active_wbh7e_77", "NavItem--mobileOnly": "_NavItem--mobileOnly_wbh7e_90", "NavItem--desktopOnly": "_NavItem--desktopOnly_wbh7e_95" };
4272
+
4273
+ // components/CredBuild/components/Nav/index.tsx
4274
+ import { jsx as jsx28, jsxs as jsxs15 } from "react/jsx-runtime";
4275
+ var getClassName19 = get_class_name_factory_default("Nav", styles_module_default19);
4276
+ var getClassNameItem = get_class_name_factory_default("NavItem", styles_module_default19);
4277
+ var MenuItem = ({
4278
+ label,
4279
+ icon,
4280
+ onClick,
4281
+ isActive,
4282
+ mobileOnly,
4283
+ desktopOnly
4284
+ }) => {
4285
+ return /* @__PURE__ */ jsx28(
4286
+ "li",
4287
+ {
4288
+ className: getClassNameItem({
4289
+ active: isActive,
4290
+ mobileOnly,
4291
+ desktopOnly
4292
+ }),
4293
+ children: onClick && /* @__PURE__ */ jsx28("div", { className: getClassNameItem("link"), onClick, title: label, children: icon && /* @__PURE__ */ jsx28("span", { className: getClassNameItem("linkIcon"), children: icon }) })
4294
+ }
4295
+ );
4296
+ };
4297
+ var Nav = ({
4298
+ items,
4299
+ mobileActions
4300
+ }) => {
4301
+ return /* @__PURE__ */ jsxs15("nav", { className: getClassName19(), children: [
4302
+ /* @__PURE__ */ jsx28("ul", { className: getClassName19("list"), children: Object.entries(items).map(([key, item]) => /* @__PURE__ */ jsx28(MenuItem, { ...item }, key)) }),
4303
+ mobileActions && /* @__PURE__ */ jsx28("div", { className: getClassName19("mobileActions"), children: mobileActions })
4304
+ ] });
4305
+ };
4306
+
4307
+ // components/CredBuild/components/Layout/index.tsx
4308
+ import { jsx as jsx29, jsxs as jsxs16 } from "react/jsx-runtime";
4309
+ var getClassName20 = get_class_name_factory_default("CredBuild", styles_module_default11);
4310
+ var getLayoutClassName = get_class_name_factory_default("CredBuildLayout", styles_module_default11);
4311
+ var getPluginTabClassName = get_class_name_factory_default("CredBuildPluginTab", styles_module_default11);
4312
+ var FieldSideBar = () => {
4313
+ const title = useAppStore(
4314
+ (s) => s.selectedItem ? s.config.components[s.selectedItem.type]?.["label"] ?? s.selectedItem.type.toString() : s.config.root?.label || "Page"
4315
+ );
4316
+ return /* @__PURE__ */ jsx29(SidebarSection, { noBorderTop: true, showBreadcrumbs: true, title, children: /* @__PURE__ */ jsx29(Fields, {}) });
4317
+ };
4318
+ var PluginTab = ({
4319
+ children,
4320
+ visible,
4321
+ mobileOnly
4322
+ }) => {
4323
+ return /* @__PURE__ */ jsx29("div", { className: getPluginTabClassName({ visible, mobileOnly }), children: /* @__PURE__ */ jsx29("div", { className: getPluginTabClassName("body"), children }) });
4324
+ };
4325
+ var Layout = ({ children }) => {
4326
+ const {
4327
+ iframe: _iframe,
4328
+ dnd,
4329
+ initialHistory: _initialHistory,
4330
+ plugins,
4331
+ height
4332
+ } = usePropsContext();
4333
+ const iframe = useMemo14(
4334
+ () => ({
4335
+ enabled: true,
4336
+ waitForStyles: true,
4337
+ ..._iframe
4338
+ }),
4339
+ [_iframe]
4340
+ );
4341
+ useInjectGlobalCss(iframe.enabled);
4342
+ const dispatch = useAppStore((s) => s.dispatch);
4343
+ const leftSideBarVisible = useAppStore((s) => s.state.ui.leftSideBarVisible);
4344
+ const rightSideBarVisible = useAppStore(
4345
+ (s) => s.state.ui.rightSideBarVisible
4346
+ );
4347
+ const instanceId = useAppStore((s) => s.instanceId);
4348
+ const {
4349
+ width: leftWidth,
4350
+ setWidth: setLeftWidth,
4351
+ sidebarRef: leftSidebarRef,
4352
+ handleResizeEnd: handleLeftSidebarResizeEnd
4353
+ } = useSidebarResize("left", dispatch);
4354
+ const {
4355
+ width: rightWidth,
4356
+ setWidth: setRightWidth,
4357
+ sidebarRef: rightSidebarRef,
4358
+ handleResizeEnd: handleRightSidebarResizeEnd
4359
+ } = useSidebarResize("right", dispatch);
4360
+ useEffect14(() => {
4361
+ if (!window.matchMedia("(min-width: 638px)").matches) {
4362
+ dispatch({
4363
+ type: "setUi",
4364
+ ui: {
4365
+ leftSideBarVisible: false,
4366
+ rightSideBarVisible: false
4367
+ }
4368
+ });
4369
+ }
4370
+ const handleResize = () => {
4371
+ if (!window.matchMedia("(min-width: 638px)").matches) {
4372
+ dispatch({
4373
+ type: "setUi",
4374
+ ui: (ui) => ({
4375
+ ...ui,
4376
+ ...ui.rightSideBarVisible ? { leftSideBarVisible: false } : {}
4377
+ })
4378
+ });
4379
+ }
4380
+ };
4381
+ window.addEventListener("resize", handleResize);
4382
+ return () => {
4383
+ window.removeEventListener("resize", handleResize);
4384
+ };
4385
+ }, [dispatch]);
4386
+ const overrides = useAppStore((s) => s.overrides);
4387
+ const CustomCredBuild = useMemo14(
4388
+ () => overrides.credbuild || DefaultOverride,
4389
+ [overrides]
4390
+ );
4391
+ const [mounted, setMounted] = useState14(false);
4392
+ const [theme, setTheme] = useState14("dark");
4393
+ useEffect14(() => {
4394
+ setMounted(true);
4395
+ const savedTheme = localStorage.getItem("credbuild-theme");
4396
+ if (savedTheme) {
4397
+ setTheme(savedTheme);
4398
+ }
4399
+ const handleThemeToggle = (e) => {
4400
+ const newTheme = e.detail || localStorage.getItem("credbuild-theme");
4401
+ if (newTheme) setTheme(newTheme);
4402
+ };
4403
+ window.addEventListener("credbuild-theme-change", handleThemeToggle);
4404
+ window.addEventListener("storage", handleThemeToggle);
4405
+ return () => {
4406
+ window.removeEventListener("credbuild-theme-change", handleThemeToggle);
4407
+ window.removeEventListener("storage", handleThemeToggle);
4408
+ };
4409
+ }, []);
4410
+ const ready = useAppStore((s) => s.status === "READY");
4411
+ useMonitorHotkeys();
4412
+ useEffect14(() => {
4413
+ if (ready && iframe.enabled) {
4414
+ const frameDoc = getFrame();
4415
+ if (frameDoc) {
4416
+ return monitorHotkeys(frameDoc);
4417
+ }
4418
+ }
4419
+ }, [ready, iframe.enabled]);
4420
+ usePreviewModeHotkeys();
4421
+ useDeleteHotkeys();
4422
+ const layoutOptions = {};
4423
+ if (leftWidth) {
4424
+ layoutOptions["--credbuild-user-left-side-bar-width"] = `${leftWidth}px`;
4425
+ }
4426
+ if (rightWidth) {
4427
+ layoutOptions["--credbuild-user-right-side-bar-width"] = `${rightWidth}px`;
4428
+ }
4429
+ const setUi = useAppStore((s) => s.setUi);
4430
+ const currentPlugin = useAppStore((s) => s.state.ui.plugin?.current);
4431
+ const appStoreApi = useAppStoreApi();
4432
+ const [mobilePanelHeightMode, setMobilePanelHeightMode] = useState14("toggle");
4433
+ const hasLegacySideBarPlugin = useMemo14(
4434
+ () => !!plugins?.find((p) => p.name === "legacy-side-bar"),
4435
+ [plugins]
4436
+ );
4437
+ const pluginItems = useMemo14(() => {
4438
+ const details = {};
4439
+ const defaultPlugins = [
4440
+ blocksPlugin(),
4441
+ outlinePlugin(),
4442
+ codePlugin()
4443
+ ];
4444
+ const isLegacy = (plugin) => plugin.name === "legacy-side-bar" ? -1 : 0;
4445
+ const combinedPlugins = [
4446
+ ...defaultPlugins,
4447
+ ...plugins ?? []
4448
+ ].sort((a, b) => isLegacy(a) - isLegacy(b));
4449
+ if (!plugins?.some((p) => p.name === "fields")) {
4450
+ combinedPlugins.push(fieldsPlugin());
4451
+ }
4452
+ combinedPlugins?.forEach((plugin) => {
4453
+ if (plugin.name && plugin.render) {
4454
+ if (details[plugin.name]) {
4455
+ delete details[plugin.name];
4456
+ }
4457
+ details[plugin.name] = {
4458
+ label: plugin.label ?? plugin.name,
4459
+ icon: plugin.icon ?? /* @__PURE__ */ jsx29(ToyBrick, {}),
4460
+ onClick: () => {
4461
+ setMobilePanelHeightMode(plugin.mobilePanelHeight ?? "toggle");
4462
+ if (plugin.name === currentPlugin) {
4463
+ if (leftSideBarVisible) {
4464
+ setUi({ leftSideBarVisible: false });
4465
+ } else {
4466
+ setUi({ leftSideBarVisible: true });
4467
+ }
4468
+ } else {
4469
+ if (plugin.name) {
4470
+ setUi({
4471
+ plugin: { current: plugin.name },
4472
+ leftSideBarVisible: true
4473
+ });
4474
+ }
4475
+ }
4476
+ },
4477
+ isActive: leftSideBarVisible && currentPlugin === plugin.name,
4478
+ render: plugin.render,
4479
+ mobileOnly: hasLegacySideBarPlugin || plugin.mobileOnly,
4480
+ desktopOnly: plugin.name === "legacy-side-bar" || plugin.desktopOnly
4481
+ };
4482
+ }
4483
+ });
4484
+ return details;
4485
+ }, [plugins, currentPlugin, leftSideBarVisible, hasLegacySideBarPlugin, setUi]);
4486
+ useEffect14(() => {
4487
+ if (!currentPlugin) {
4488
+ const names = Object.keys(pluginItems);
4489
+ setUi({ plugin: { current: names[0] } });
4490
+ }
4491
+ }, [pluginItems, currentPlugin, setUi]);
4492
+ const hasDesktopFieldsPlugin = pluginItems["fields"] && pluginItems["fields"].mobileOnly === false;
4493
+ const mobilePanelExpanded = useAppStore(
4494
+ (s) => s.state.ui.mobilePanelExpanded ?? false
4495
+ );
4496
+ return /* @__PURE__ */ jsxs16(
4497
+ "div",
4498
+ {
4499
+ className: `CredBuild ${theme === "dark" ? "dark" : ""} ${getClassName20({
4500
+ hidePlugins: hasLegacySideBarPlugin
4501
+ })}`,
4502
+ "data-theme": theme,
4503
+ id: instanceId,
4504
+ style: { height: typeof height === "number" && isNaN(height) ? void 0 : height },
4505
+ children: [
4506
+ /* @__PURE__ */ jsx29(DragDropContext, { disableAutoScroll: dnd?.disableAutoScroll, children: /* @__PURE__ */ jsx29(CustomCredBuild, { children: children || /* @__PURE__ */ jsx29(FrameProvider, { children: /* @__PURE__ */ jsx29(
4507
+ "div",
4508
+ {
4509
+ className: getLayoutClassName({
4510
+ leftSideBarVisible,
4511
+ mounted,
4512
+ rightSideBarVisible: !hasDesktopFieldsPlugin && rightSideBarVisible,
4513
+ isExpanded: mobilePanelExpanded,
4514
+ mobilePanelHeightToggle: mobilePanelHeightMode === "toggle",
4515
+ mobilePanelHeightMinContent: mobilePanelHeightMode === "min-content"
4516
+ }),
4517
+ style: { height: typeof height === "number" && isNaN(height) ? void 0 : height },
4518
+ children: /* @__PURE__ */ jsxs16(
4519
+ "div",
4520
+ {
4521
+ className: getLayoutClassName("inner"),
4522
+ style: layoutOptions,
4523
+ children: [
4524
+ /* @__PURE__ */ jsx29("div", { className: getLayoutClassName("header"), children: /* @__PURE__ */ jsx29(Header, { theme, hidePlugins: hasLegacySideBarPlugin }) }),
4525
+ /* @__PURE__ */ jsxs16(
4526
+ Sidebar,
4527
+ {
4528
+ position: "left",
4529
+ sidebarRef: leftSidebarRef,
4530
+ isVisible: leftSideBarVisible,
4531
+ onResize: setLeftWidth,
4532
+ onResizeEnd: handleLeftSidebarResizeEnd,
4533
+ children: [
4534
+ /* @__PURE__ */ jsx29("div", { className: getLayoutClassName("nav"), children: /* @__PURE__ */ jsx29(
4535
+ Nav,
4536
+ {
4537
+ items: pluginItems,
4538
+ mobileActions: typeof window !== "undefined" && !window.matchMedia("(min-width: 638px)").matches && leftSideBarVisible && mobilePanelHeightMode === "toggle" && /* @__PURE__ */ jsx29(
4539
+ IconButton,
4540
+ {
4541
+ type: "button",
4542
+ title: "maximize",
4543
+ onClick: () => {
4544
+ setUi({
4545
+ mobilePanelExpanded: !mobilePanelExpanded
4546
+ });
4547
+ },
4548
+ children: mobilePanelExpanded ? /* @__PURE__ */ jsx29(Minimize2, { size: 21 }) : /* @__PURE__ */ jsx29(Maximize2, { size: 21 })
4549
+ }
4550
+ )
4551
+ }
4552
+ ) }),
4553
+ Object.entries(pluginItems).map(
4554
+ ([id, { mobileOnly, render: Render2, label }]) => /* @__PURE__ */ jsx29(
4555
+ PluginTab,
4556
+ {
4557
+ visible: currentPlugin === id,
4558
+ mobileOnly,
4559
+ children: /* @__PURE__ */ jsx29(Render2, {})
4560
+ },
4561
+ id
4562
+ )
4563
+ )
4564
+ ]
4565
+ }
4566
+ ),
4567
+ /* @__PURE__ */ jsx29(Canvas, {}),
4568
+ !hasDesktopFieldsPlugin && /* @__PURE__ */ jsx29(
4569
+ Sidebar,
4570
+ {
4571
+ position: "right",
4572
+ sidebarRef: rightSidebarRef,
4573
+ isVisible: rightSideBarVisible,
4574
+ onResize: setRightWidth,
4575
+ onResizeEnd: handleRightSidebarResizeEnd,
4576
+ children: /* @__PURE__ */ jsx29(FieldSideBar, {})
4577
+ }
4578
+ )
4579
+ ]
4580
+ }
4581
+ )
4582
+ }
4583
+ ) }) }) }),
4584
+ /* @__PURE__ */ jsx29("div", { id: "credbuild-portal-root", className: getClassName20("portal") })
4585
+ ]
4586
+ }
4587
+ );
4588
+ };
4589
+
4590
+ // components/CredBuild/index.tsx
4591
+ import { jsx as jsx30 } from "react/jsx-runtime";
4592
+ function CredBuildProvider({ children }) {
4593
+ const {
4594
+ config,
4595
+ data: initialData,
4596
+ ui: initialUi,
4597
+ onChange,
4598
+ permissions = {},
4599
+ plugins,
4600
+ overrides,
4601
+ viewports = defaultViewports,
4602
+ iframe: _iframe,
4603
+ initialHistory: _initialHistory,
4604
+ metadata,
4605
+ onAction,
4606
+ fieldTransforms,
4607
+ _experimentalFullScreenCanvas,
4608
+ _experimentalVirtualization
4609
+ } = usePropsContext();
4610
+ const iframe = useMemo15(
4611
+ () => ({
4612
+ enabled: true,
4613
+ waitForStyles: true,
4614
+ ..._iframe
4615
+ }),
4616
+ [_iframe]
4617
+ );
4618
+ const [generatedAppState] = useState15(() => {
4619
+ const initial = { ...defaultAppState.ui, ...initialUi };
4620
+ let clientUiState = {};
4621
+ if (Object.keys(initialData?.root || {}).length > 0 && !initialData?.root?.props) {
4622
+ console.warn(
4623
+ "Warning: Defining props on `root` is deprecated. Please use `root.props`, or republish this page to migrate automatically."
4624
+ );
4625
+ }
4626
+ const rootProps = initialData?.root?.props || initialData?.root || {};
4627
+ const defaultedRootProps = {
4628
+ ...config.root?.defaultProps,
4629
+ ...rootProps
4630
+ };
4631
+ const root = populateIds(
4632
+ toComponent({ ...initialData?.root, props: defaultedRootProps }),
4633
+ config
4634
+ );
4635
+ const newAppState = {
4636
+ ...defaultAppState,
4637
+ data: {
4638
+ ...initialData,
4639
+ root: { ...initialData?.root, props: root.props },
4640
+ content: initialData.content || []
4641
+ },
4642
+ ui: {
4643
+ ...initial,
4644
+ ...clientUiState,
4645
+ // Store categories under componentList on state to allow render functions and plugins to modify
4646
+ componentList: config.categories ? Object.entries(config.categories).reduce(
4647
+ (acc, [categoryName, category]) => {
4648
+ return {
4649
+ ...acc,
4650
+ [categoryName]: {
4651
+ title: category.title,
4652
+ components: category.components,
4653
+ expanded: category.defaultExpanded,
4654
+ visible: category.visible
4655
+ }
4656
+ };
4657
+ },
4658
+ {}
4659
+ ) : {}
4660
+ }
4661
+ };
4662
+ return walkAppState(newAppState, config);
4663
+ });
4664
+ const { appendData = true } = _initialHistory || {};
4665
+ const [blendedHistories] = useState15(
4666
+ [
4667
+ ..._initialHistory?.histories || [],
4668
+ ...appendData ? [{ state: generatedAppState }] : []
4669
+ ].map((history) => {
4670
+ let newState = { ...generatedAppState, ...history.state };
4671
+ if (!history.state.indexes) {
4672
+ newState = walkAppState(newState, config);
4673
+ }
4674
+ return {
4675
+ ...history,
4676
+ state: newState
4677
+ };
4678
+ })
4679
+ );
4680
+ const initialHistoryIndex = useMemo15(() => {
4681
+ if (_initialHistory?.index !== void 0 && _initialHistory?.index >= 0 && _initialHistory?.index < blendedHistories.length) {
4682
+ return _initialHistory?.index;
4683
+ }
4684
+ return blendedHistories.length - 1;
4685
+ }, [_initialHistory?.index, blendedHistories.length]);
4686
+ const initialAppState = blendedHistories[initialHistoryIndex].state;
4687
+ const loadedOverrides = useLoadedOverrides({
4688
+ overrides,
4689
+ plugins
4690
+ });
4691
+ const loadedFieldTransforms = useMemo15(() => {
4692
+ const _plugins = plugins || [];
4693
+ const pluginFieldTransforms = _plugins.reduce(
4694
+ (acc, plugin) => ({ ...acc, ...plugin.fieldTransforms }),
4695
+ {}
4696
+ );
4697
+ return {
4698
+ ...pluginFieldTransforms,
4699
+ ...fieldTransforms
4700
+ };
4701
+ }, [fieldTransforms, plugins]);
4702
+ const instanceId = useSafeId();
4703
+ const generateAppStore = useCallback12(
4704
+ (state) => {
4705
+ return {
4706
+ instanceId,
4707
+ state,
4708
+ config,
4709
+ plugins: plugins || [],
4710
+ overrides: loadedOverrides,
4711
+ viewports,
4712
+ iframe,
4713
+ _experimentalFullScreenCanvas: !!_experimentalFullScreenCanvas,
4714
+ _experimentalVirtualization: !!_experimentalVirtualization,
4715
+ onAction,
4716
+ metadata,
4717
+ fieldTransforms: loadedFieldTransforms
4718
+ };
4719
+ },
4720
+ [
4721
+ instanceId,
4722
+ config,
4723
+ plugins,
4724
+ loadedOverrides,
4725
+ viewports,
4726
+ iframe,
4727
+ _experimentalFullScreenCanvas,
4728
+ _experimentalVirtualization,
4729
+ onAction,
4730
+ metadata,
4731
+ loadedFieldTransforms
4732
+ ]
4733
+ );
4734
+ const [appStore] = useState15(
4735
+ () => createAppStore(generateAppStore(initialAppState))
4736
+ );
4737
+ useEffect15(() => {
4738
+ if (process.env.NODE_ENV !== "production") {
4739
+ window.__CREDBUILD_INTERNAL_DO_NOT_USE = { appStore };
4740
+ }
4741
+ }, [appStore]);
4742
+ useEffect15(() => {
4743
+ const state = appStore.getState().state;
4744
+ appStore.setState({
4745
+ ...generateAppStore(state)
4746
+ });
4747
+ }, [generateAppStore, appStore]);
4748
+ useRegisterHistorySlice(appStore, {
4749
+ histories: blendedHistories,
4750
+ index: initialHistoryIndex,
4751
+ initialAppState
4752
+ });
4753
+ const previousData = useRef10(null);
4754
+ useEffect15(() => {
4755
+ return appStore.subscribe(
4756
+ (s) => s.state.data,
4757
+ (data) => {
4758
+ if (onChange) {
4759
+ if (deepEqual(data, previousData.current)) return;
4760
+ onChange(data);
4761
+ previousData.current = data;
4762
+ }
4763
+ }
4764
+ );
4765
+ }, [onChange, appStore]);
4766
+ useRegisterPermissionsSlice(appStore, permissions);
4767
+ const uCredBuildStore = useRegisterUseCredBuildStore(appStore);
4768
+ useEffect15(() => {
4769
+ const { resolveAndCommitData } = appStore.getState();
4770
+ setTimeout(() => {
4771
+ resolveAndCommitData();
4772
+ }, 0);
4773
+ }, [appStore]);
4774
+ return /* @__PURE__ */ jsx30(appStoreContext.Provider, { value: appStore, children: /* @__PURE__ */ jsx30(UseCredBuildStoreContext.Provider, { value: uCredBuildStore, children }) });
4775
+ }
4776
+ function CredBuild(props) {
4777
+ return /* @__PURE__ */ jsx30(PropsProvider, { ...props, children: /* @__PURE__ */ jsx30(CredBuildProvider, { ...props, children: /* @__PURE__ */ jsx30(Layout, { children: props.children }) }) });
4778
+ }
4779
+ CredBuild.Components = Components;
4780
+ CredBuild.Fields = Fields;
4781
+ CredBuild.Layout = Layout;
4782
+ CredBuild.Outline = Outline;
4783
+ CredBuild.Preview = Preview;
4784
+
4785
+ // plugins/legacy-side-bar/index.tsx
4786
+ import { jsx as jsx31, jsxs as jsxs17 } from "react/jsx-runtime";
4787
+ var legacySideBarPlugin = () => ({
4788
+ name: "legacy-side-bar",
4789
+ render: () => /* @__PURE__ */ jsxs17("div", { style: { overflowY: "auto" }, children: [
4790
+ /* @__PURE__ */ jsx31(SidebarSection, { title: "Components", noBorderTop: true, children: /* @__PURE__ */ jsx31(Components, {}) }),
4791
+ /* @__PURE__ */ jsx31(SidebarSection, { title: "Outline", children: /* @__PURE__ */ jsx31(Outline, {}) })
4792
+ ] })
4793
+ });
4794
+
4795
+ export {
4796
+ overrideKeys,
4797
+ Render,
4798
+ createUseCredBuild,
4799
+ useCredBuild,
4800
+ useGetCredBuild,
4801
+ blocksPlugin,
4802
+ outlinePlugin,
4803
+ fieldsPlugin,
4804
+ codePlugin,
4805
+ CredBuild,
4806
+ legacySideBarPlugin
4807
+ };