@baack-software/baack-ts-editor 0.0.0-stage → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +202 -0
- package/README.md +99 -2
- package/dist/chunks/chunk-JI2V7IMH.js +336 -0
- package/dist/chunks/chunk-JI2V7IMH.js.map +7 -0
- package/dist/editor.js +17 -0
- package/dist/editor.js.map +7 -0
- package/dist/loader.js +2 -0
- package/dist/loader.js.map +7 -0
- package/package.json +43 -4
|
@@ -0,0 +1,336 @@
|
|
|
1
|
+
function L(){let t=document.querySelector('meta[name="baack-editor-api"]')?.content;return{...window.baackEditorConfig,baseUrl:window.baackEditorConfig?.baseUrl??t??"https://api.baack.co"}}var o=t=>["path",{d:t}],s=(t,e)=>["circle",{cx:t,cy:e,r:1}],A={"arrow-down":[o("M12 5v14"),o("m19 12-7 7-7-7")],"arrow-up":[o("m5 12 7-7 7 7"),o("M12 19V5")],check:[o("M20 6 9 17l-5-5")],"chevron-down":[o("m6 9 6 6 6-6")],"chevron-left":[o("m15 18-6-6 6-6")],"chevron-right":[o("m9 18 6-6-6-6")],ellipsis:[s(12,12),s(19,12),s(5,12)],"grip-vertical":[s(9,12),s(9,5),s(9,19),s(15,12),s(15,5),s(15,19)],history:[o("M3 12a9 9 0 1 0 9-9 9.75 9.75 0 0 0-6.74 2.74L3 8"),o("M3 3v5h5"),o("M12 7v5l4 2")],"list-ordered":[o("M10 12h11"),o("M10 18h11"),o("M10 6h11"),o("M4 10h2"),o("M4 6h1v4"),o("M6 18H4c0-1 2-2 2-3s-1-1.5-2-1")],"panel-left":[["rect",{width:18,height:18,x:3,y:3,rx:2}],o("M9 3v18")],"panel-right":[["rect",{width:18,height:18,x:3,y:3,rx:2}],o("M15 3v18")],"pencil-line":[o("M13 21h8"),o("m15 5 4 4"),o("M21.174 6.812a1 1 0 0 0-3.986-3.987L3.842 16.174a2 2 0 0 0-.5.83l-1.321 4.352a.5.5 0 0 0 .623.622l4.353-1.32a2 2 0 0 0 .83-.497z")],plus:[o("M5 12h14"),o("M12 5v14")],search:[["circle",{cx:11,cy:11,r:8}],o("m21 21-4.3-4.3")],x:[o("M18 6 6 18"),o("m6 6 12 12")]},y="http://www.w3.org/2000/svg";function k(t){let e=document.createElementNS(y,"svg");for(let[r,n]of Object.entries({viewBox:"0 0 24 24",width:16,height:16,fill:"none",stroke:"currentColor","stroke-width":2,"stroke-linecap":"round","stroke-linejoin":"round","aria-hidden":"true",focusable:"false",class:`icon icon-${t}`}))e.setAttribute(r,String(n));for(let[r,n]of A[t]){let a=document.createElementNS(y,r);for(let[d,l]of Object.entries(n))a.setAttribute(d,String(l));e.append(a)}return e}var u={background:"#ffffff",foreground:"#111827",popover:"#ffffff","popover-foreground":"#111827",primary:"#1d4ed8","primary-foreground":"#ffffff",secondary:"#f6f7f9","secondary-foreground":"#111827",muted:"#f6f7f9","muted-foreground":"#4b5563",accent:"#f3f4f6","accent-foreground":"#111827",destructive:"#dc2626","destructive-text":"#b91c1c",border:"#e5e7eb",input:"#d1d5db",ring:"#1d4ed8",success:"#047857",warning:"#92400e",preview:"#6d28d9",overlay:"rgb(0 0 0 / 0.5)","shadow-color":"rgb(17 24 39 / 0.1)","control-background":"var(--background)","control-border":"var(--border)","control-hover":"var(--muted)","field-background":"transparent","switch-off":"var(--input)","switch-thumb-off":"var(--background)","switch-thumb-on":"var(--background)"},p={background:"#0d1117",foreground:"#f3f4f6",popover:"#151b24","popover-foreground":"#f3f4f6",primary:"#6b9bff","primary-foreground":"#0d1117",secondary:"#1c2430","secondary-foreground":"#f3f4f6",muted:"#11161e","muted-foreground":"#a1a9b6",accent:"#1f2733","accent-foreground":"#f3f4f6",destructive:"#f87171","destructive-text":"#f87171",border:"#262e3a",input:"#343e4d",ring:"#6b9bff",success:"#34d399",warning:"#fbbf24",preview:"#c4b5fd",overlay:"rgb(0 0 0 / 0.65)","shadow-color":"rgb(0 0 0 / 0.45)","control-background":"color-mix(in oklab, var(--input) 30%, transparent)","control-border":"var(--input)","control-hover":"color-mix(in oklab, var(--input) 50%, transparent)","field-background":"color-mix(in oklab, var(--input) 30%, transparent)","switch-off":"color-mix(in oklab, var(--input) 80%, transparent)","switch-thumb-off":"var(--foreground)","switch-thumb-on":"var(--primary-foreground)"},M=`
|
|
2
|
+
/* Installed fonts only, so no site needs to allow a font source in its Content Security Policy. Figtree when the
|
|
3
|
+
page has loaded it (www.baack.co), then the nearest match on Apple devices, then each platform's UI font. */
|
|
4
|
+
--font-sans: Figtree, "Avenir Next", "Segoe UI Variable Text", "Segoe UI", Roboto, system-ui, -apple-system, sans-serif;
|
|
5
|
+
--font-mono: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
|
|
6
|
+
--text-xs: 12px;
|
|
7
|
+
--text-sm: 14px;
|
|
8
|
+
--text-base: 16px;
|
|
9
|
+
--radius: 10px;
|
|
10
|
+
--radius-sm: 6px;
|
|
11
|
+
--radius-md: 8px;
|
|
12
|
+
--radius-lg: 10px;
|
|
13
|
+
--radius-xl: 14px;
|
|
14
|
+
--shadow-sm: 0 1px 2px 0 var(--shadow-color);
|
|
15
|
+
--shadow-md: 0 4px 6px -1px var(--shadow-color), 0 2px 4px -2px var(--shadow-color);
|
|
16
|
+
--shadow-lg: 0 10px 15px -3px var(--shadow-color), 0 4px 6px -4px var(--shadow-color);
|
|
17
|
+
/* shadcn's ring-3 ring-ring/50. */
|
|
18
|
+
--focus-ring: 0 0 0 3px color-mix(in oklab, var(--ring) 50%, transparent);
|
|
19
|
+
`;function b(t){return Object.entries(t).map(([e,r])=>` --${e}: ${r};`).join(`
|
|
20
|
+
`)}var E=`
|
|
21
|
+
:host {
|
|
22
|
+
color-scheme: light;
|
|
23
|
+
${b(u)}
|
|
24
|
+
${M}
|
|
25
|
+
}
|
|
26
|
+
@media (prefers-color-scheme: dark) {
|
|
27
|
+
:host {
|
|
28
|
+
color-scheme: dark;
|
|
29
|
+
${b(p)}
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
/* Baack's login page does not follow the dark setting yet, so the login stays light: the modal around it, and the
|
|
33
|
+
frame wherever it is (an iframe's color-scheme is the one its page sees). */
|
|
34
|
+
.login-modal {
|
|
35
|
+
color-scheme: light;
|
|
36
|
+
${b(u)}
|
|
37
|
+
}
|
|
38
|
+
.login iframe { color-scheme: light; background: ${u.background}; }
|
|
39
|
+
`,C={primary:[u.primary,p.primary],warning:["#b45309",p.warning],preview:["#7c3aed",p.preview],success:[u.success,p.success],muted:["#6b7280","#9ca3af"]};var T="baack-editor-host",N=`${E}
|
|
40
|
+
:host { all: initial; }
|
|
41
|
+
* { box-sizing: border-box; }
|
|
42
|
+
.panel {
|
|
43
|
+
position: fixed; z-index: 2147483647;
|
|
44
|
+
font: var(--text-sm)/1.45 var(--font-sans);
|
|
45
|
+
color: var(--popover-foreground); background: var(--popover);
|
|
46
|
+
border: 1px solid var(--border); border-radius: var(--radius-lg);
|
|
47
|
+
box-shadow: var(--shadow-md);
|
|
48
|
+
padding: 10px 12px;
|
|
49
|
+
}
|
|
50
|
+
.toolbar { right: 16px; bottom: 16px; display: flex; flex-direction: column; gap: 6px; max-width: 380px; }
|
|
51
|
+
/* A row wraps whole buttons onto the next line rather than squeezing their labels. */
|
|
52
|
+
.toolbar-row { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 8px; }
|
|
53
|
+
.toolbar-row > button, .toolbar-row > .brand { white-space: nowrap; }
|
|
54
|
+
.toolbar > .message-action { align-self: flex-start; }
|
|
55
|
+
.debug { font-size: var(--text-xs); color: var(--muted-foreground); }
|
|
56
|
+
.debug summary { cursor: pointer; }
|
|
57
|
+
.debug pre { margin: 4px 0 0; padding: 6px; max-height: 12em; overflow: auto; white-space: pre-wrap; overflow-wrap: anywhere; background: var(--muted); border-radius: var(--radius-sm); font: 11px/1.45 var(--font-mono); }
|
|
58
|
+
.brand { font-weight: 700; letter-spacing: -0.01em; }
|
|
59
|
+
.pending { color: var(--warning); }
|
|
60
|
+
/* Buttons: shadcn/ui's variants and sizes (button() in this module). With no class, the outline variant. */
|
|
61
|
+
button {
|
|
62
|
+
display: inline-flex; align-items: center; justify-content: center; gap: 6px; flex-shrink: 0;
|
|
63
|
+
font: 500 var(--text-sm)/1.25 var(--font-sans); color: var(--foreground); cursor: pointer; user-select: none;
|
|
64
|
+
min-height: 32px; padding: 4px 10px; border-radius: var(--radius-lg);
|
|
65
|
+
border: 1px solid var(--control-border); background: var(--control-background); background-clip: padding-box;
|
|
66
|
+
transition: background-color 120ms, border-color 120ms, box-shadow 120ms, color 120ms;
|
|
67
|
+
}
|
|
68
|
+
button:enabled:hover { background-color: var(--control-hover); color: var(--foreground); }
|
|
69
|
+
button:active:not([aria-haspopup]) { transform: translateY(1px); }
|
|
70
|
+
button:focus-visible { outline: none; border-color: var(--ring); box-shadow: var(--focus-ring); }
|
|
71
|
+
/* Not pointer-events: none, so the title saying why it is disabled still shows on hover. */
|
|
72
|
+
button:disabled { opacity: 0.5; cursor: default; }
|
|
73
|
+
button svg { flex-shrink: 0; width: 16px; height: 16px; pointer-events: none; }
|
|
74
|
+
button.primary { background: var(--primary); border-color: transparent; color: var(--primary-foreground); }
|
|
75
|
+
button.primary:enabled:hover { background: color-mix(in oklab, var(--primary) 80%, transparent); }
|
|
76
|
+
button.secondary { background: var(--secondary); border-color: transparent; color: var(--secondary-foreground); }
|
|
77
|
+
button.secondary:enabled:hover { background: color-mix(in oklab, var(--secondary), var(--foreground) 5%); }
|
|
78
|
+
button.ghost { background: transparent; border-color: transparent; }
|
|
79
|
+
button.ghost:enabled:hover { background: var(--control-hover); }
|
|
80
|
+
button.destructive { background: color-mix(in oklab, var(--destructive) 10%, transparent); border-color: transparent; color: var(--destructive-text); }
|
|
81
|
+
button.destructive:enabled:hover { background: color-mix(in oklab, var(--destructive) 20%, transparent); }
|
|
82
|
+
button.destructive:focus-visible { border-color: color-mix(in oklab, var(--destructive) 40%, transparent); box-shadow: 0 0 0 3px color-mix(in oklab, var(--destructive) 20%, transparent); }
|
|
83
|
+
/* A link inside text: no box, so it sits in the line. */
|
|
84
|
+
button.link { display: inline; min-height: 0; padding: 0; border: 0; border-radius: var(--radius-sm); background: none; font: inherit; color: var(--primary); text-decoration: underline; text-underline-offset: 4px; }
|
|
85
|
+
button.link:hover { background: none; text-decoration-thickness: 2px; }
|
|
86
|
+
button.link:active { transform: none; }
|
|
87
|
+
button.xs { min-height: 24px; gap: 4px; padding: 2px 8px; font-size: var(--text-xs); border-radius: var(--radius-md); }
|
|
88
|
+
button.xs svg { width: 12px; height: 12px; }
|
|
89
|
+
button.sm { min-height: 28px; gap: 4px; padding: 2px 10px; font-size: 12.8px; border-radius: var(--radius-md); }
|
|
90
|
+
button.sm svg { width: 14px; height: 14px; }
|
|
91
|
+
button.lg { min-height: 36px; }
|
|
92
|
+
button.icon, button.icon-sm, button.icon-xs { padding: 0; width: 32px; height: 32px; min-height: 0; }
|
|
93
|
+
button.icon-sm { width: 28px; height: 28px; border-radius: var(--radius-md); }
|
|
94
|
+
button.icon-xs { width: 24px; height: 24px; border-radius: var(--radius-md); }
|
|
95
|
+
button.icon-xs svg { width: 12px; height: 12px; }
|
|
96
|
+
/* A toggle that is on, such as the live-page preview. */
|
|
97
|
+
button[aria-pressed="true"] { background: color-mix(in oklab, var(--primary) 10%, var(--control-background)); border-color: color-mix(in oklab, var(--primary) 60%, transparent); color: var(--primary); }
|
|
98
|
+
/* Messages: shadcn/ui's alert. The colour is in the border and tint; the text keeps full contrast. */
|
|
99
|
+
.message:empty, .issues:empty, .error:empty { display: none; }
|
|
100
|
+
p.message, p.error, .issues {
|
|
101
|
+
margin: 0; padding: 8px 12px; border-radius: var(--radius-lg); font-size: var(--text-sm); color: var(--foreground);
|
|
102
|
+
border: 1px solid color-mix(in oklab, var(--destructive) 50%, transparent);
|
|
103
|
+
background: color-mix(in oklab, var(--destructive) 5%, var(--popover));
|
|
104
|
+
}
|
|
105
|
+
p.message.info { border-color: var(--border); background: var(--popover); }
|
|
106
|
+
.issues { padding-left: 12px; border-color: color-mix(in oklab, var(--warning) 45%, transparent); background: color-mix(in oklab, var(--warning) 6%, var(--popover)); }
|
|
107
|
+
ul.issues { padding-left: 28px; }
|
|
108
|
+
.issues li::marker { color: var(--warning); }
|
|
109
|
+
.issues li.error::marker { color: var(--destructive); }
|
|
110
|
+
.issues li { color: var(--foreground); }
|
|
111
|
+
/* A status line beside a field or in a list: coloured text, not a box. */
|
|
112
|
+
span.error, .hint.error { color: var(--destructive-text); }
|
|
113
|
+
.login iframe { display: block; width: 100%; height: 140px; border: 1px solid var(--border); border-radius: var(--radius-md); }
|
|
114
|
+
.panel:not(.popover) { z-index: 2147483646; }
|
|
115
|
+
/* Below the editor's panels, so a popover or the sidebar covers the tags. */
|
|
116
|
+
.order-tag {
|
|
117
|
+
position: fixed; z-index: 2147483645; min-height: 0;
|
|
118
|
+
font: 500 var(--text-xs)/1.3 var(--font-sans); color: var(--foreground);
|
|
119
|
+
padding: 2px 8px; border-radius: 999px; border: 1px solid var(--border);
|
|
120
|
+
background: color-mix(in oklab, var(--background) 94%, transparent); box-shadow: var(--shadow-sm);
|
|
121
|
+
}
|
|
122
|
+
.popover { width: max-content; min-width: 240px; max-width: 360px; display: flex; flex-direction: column; gap: 10px; padding: 12px 14px; }
|
|
123
|
+
.popover.wide { width: min(560px, calc(100vw - 16px)); max-width: none; }
|
|
124
|
+
.form:empty { display: none; }
|
|
125
|
+
.form { display: flex; flex-direction: column; gap: 10px; }
|
|
126
|
+
.field { display: flex; flex-direction: column; gap: 6px; }
|
|
127
|
+
.field.checkbox { flex-direction: row; align-items: center; gap: 8px; cursor: pointer; }
|
|
128
|
+
/* A field's label: shadcn/ui's label. A caption over a value shown read-only stays small and muted. */
|
|
129
|
+
.caption { color: var(--muted-foreground); font-size: var(--text-xs); font-weight: 500; }
|
|
130
|
+
.field > .caption, .field.checkbox .caption { color: var(--foreground); font-size: var(--text-sm); line-height: 1; }
|
|
131
|
+
/* Fields: shadcn/ui's input, textarea and select. */
|
|
132
|
+
input, textarea, select {
|
|
133
|
+
font: var(--text-sm)/1.4 var(--font-sans); color: var(--foreground); background: var(--field-background);
|
|
134
|
+
min-width: 0; min-height: 32px; border: 1px solid var(--input); border-radius: var(--radius-lg); padding: 4px 10px;
|
|
135
|
+
transition: border-color 120ms, box-shadow 120ms;
|
|
136
|
+
}
|
|
137
|
+
select { cursor: pointer; }
|
|
138
|
+
input:focus-visible, textarea:focus-visible, select:focus-visible { outline: none; border-color: var(--ring); box-shadow: var(--focus-ring); }
|
|
139
|
+
input::placeholder, textarea::placeholder { color: var(--muted-foreground); }
|
|
140
|
+
input:disabled, textarea:disabled, select:disabled { opacity: 0.5; cursor: not-allowed; background: color-mix(in oklab, var(--input) 50%, transparent); }
|
|
141
|
+
[aria-invalid="true"] { border-color: var(--destructive); box-shadow: 0 0 0 3px color-mix(in oklab, var(--destructive) 20%, transparent); }
|
|
142
|
+
textarea { resize: vertical; width: 100%; }
|
|
143
|
+
input[type="file"] { min-height: 0; padding: 4px; }
|
|
144
|
+
input[type="file"]::file-selector-button {
|
|
145
|
+
font: 500 var(--text-sm) var(--font-sans); color: var(--foreground); cursor: pointer; margin-right: 8px;
|
|
146
|
+
padding: 3px 10px; border: 1px solid var(--control-border); border-radius: var(--radius-md); background: var(--control-background);
|
|
147
|
+
}
|
|
148
|
+
input[type="checkbox"]:not(.switch) { min-height: 0; accent-color: var(--primary); }
|
|
149
|
+
/* A switch: a checkbox with role="switch", drawn as shadcn/ui's. */
|
|
150
|
+
input.switch {
|
|
151
|
+
appearance: none; position: relative; flex-shrink: 0; cursor: pointer; margin: 0; padding: 0;
|
|
152
|
+
width: 32px; height: 18.4px; min-height: 0; border-radius: 999px; border: 1px solid transparent; background: var(--switch-off);
|
|
153
|
+
transition: background-color 150ms, box-shadow 120ms;
|
|
154
|
+
}
|
|
155
|
+
input.switch::before {
|
|
156
|
+
content: ""; position: absolute; top: 50%; left: 0; width: 16px; height: 16px; border-radius: 999px;
|
|
157
|
+
background: var(--switch-thumb-off); transform: translate(0, -50%); transition: transform 150ms;
|
|
158
|
+
}
|
|
159
|
+
input.switch:checked { background: var(--primary); }
|
|
160
|
+
input.switch:checked::before { background: var(--switch-thumb-on); transform: translate(14px, -50%); }
|
|
161
|
+
/* iOS Safari zooms into a field under 16px as it takes focus. */
|
|
162
|
+
@media (max-width: 767px) { input, textarea, select { font-size: var(--text-base); } }
|
|
163
|
+
/* The entity picker: a combo box with its list below. */
|
|
164
|
+
.entity-picker { display: flex; flex-direction: column; gap: 4px; }
|
|
165
|
+
/* shadcn/ui's combobox (its Command list): a search field, then the options. */
|
|
166
|
+
.combobox-field, .select-box { position: relative; display: flex; flex-direction: column; }
|
|
167
|
+
.combobox-field > svg, .select-box > svg { position: absolute; top: 50%; transform: translateY(-50%); pointer-events: none; color: var(--muted-foreground); }
|
|
168
|
+
.combobox-field > svg:first-child { left: 10px; }
|
|
169
|
+
.combobox-field > svg:last-child, .select-box > svg { right: 10px; }
|
|
170
|
+
.combobox-field > input { padding-left: 32px; padding-right: 32px; }
|
|
171
|
+
.select-box > select { appearance: none; padding-right: 32px; }
|
|
172
|
+
.entity-options { list-style: none; margin: 0; padding: 4px; border: 1px solid var(--border); border-radius: var(--radius-lg); max-height: 220px; overflow: auto; background: var(--popover); box-shadow: var(--shadow-md); }
|
|
173
|
+
.entity-option { display: flex; align-items: center; gap: 6px; padding: 6px 8px; border-radius: var(--radius-sm); cursor: pointer; overflow-wrap: anywhere; }
|
|
174
|
+
.entity-option > .meta { flex: 1 1 auto; }
|
|
175
|
+
.entity-option > svg { flex-shrink: 0; }
|
|
176
|
+
.entity-option:hover, .entity-option.active { background: var(--accent); color: var(--accent-foreground); }
|
|
177
|
+
.entity-option[aria-selected="true"] { font-weight: 500; }
|
|
178
|
+
.entity-option.create { margin-top: 4px; border-top: 1px solid var(--border); border-radius: 0 0 var(--radius-sm) var(--radius-sm); }
|
|
179
|
+
.entity-create:empty { display: none; }
|
|
180
|
+
.entity-create { border-top: 1px solid var(--border); padding-top: 6px; }
|
|
181
|
+
.field.code textarea { font: var(--text-xs)/1.45 var(--font-mono); }
|
|
182
|
+
.hint:empty { display: none; }
|
|
183
|
+
.popover[hidden], .login[hidden], .pending[hidden], [hidden] { display: none !important; }
|
|
184
|
+
.login-modal { position: fixed; inset: 0; z-index: 2147483647; background: var(--overlay); display: grid; place-items: center; }
|
|
185
|
+
/* shadcn/ui's dialog: a larger title, a muted description, then the frame and its button. */
|
|
186
|
+
.panel.modal { position: static; width: min(440px, calc(100vw - 32px)); display: flex; flex-direction: column; gap: 16px; padding: 24px; border-radius: var(--radius-xl); box-shadow: var(--shadow-lg); }
|
|
187
|
+
.modal > .title { font-size: 18px; line-height: 1.2; letter-spacing: -0.01em; }
|
|
188
|
+
.modal > p.message.info { padding: 0; border: 0; background: none; color: var(--muted-foreground); margin-top: -8px; }
|
|
189
|
+
.modal .login iframe { height: 320px; }
|
|
190
|
+
.pending { color: var(--warning); border-color: color-mix(in oklab, var(--warning) 40%, transparent); background: color-mix(in oklab, var(--warning) 10%, var(--background)); }
|
|
191
|
+
.rows { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 2px; }
|
|
192
|
+
.row.problem { color: var(--destructive); }
|
|
193
|
+
.simple-form { display: flex; flex-direction: column; gap: 10px; }
|
|
194
|
+
.snippet { font: var(--text-xs)/1.45 var(--font-mono); background: var(--muted); border-radius: var(--radius-sm); padding: 6px 8px; overflow-wrap: anywhere; margin: 0; }
|
|
195
|
+
/* shadcn/ui's dropdown menu (src/ui/menu.ts). */
|
|
196
|
+
.menu {
|
|
197
|
+
position: fixed; z-index: 2147483647; display: flex; flex-direction: column; padding: 4px;
|
|
198
|
+
background: var(--popover); color: var(--popover-foreground);
|
|
199
|
+
border: 1px solid var(--border); border-radius: var(--radius-lg); box-shadow: var(--shadow-md);
|
|
200
|
+
animation: baack-fade-in 100ms ease-out;
|
|
201
|
+
}
|
|
202
|
+
.menu-item {
|
|
203
|
+
justify-content: flex-start; gap: 8px; width: 100%; min-height: 0; padding: 6px 8px;
|
|
204
|
+
border: 0; border-radius: var(--radius-sm); background: none; font-weight: 400; white-space: nowrap;
|
|
205
|
+
}
|
|
206
|
+
.menu-item svg { color: var(--muted-foreground); }
|
|
207
|
+
.menu-item:enabled:hover, .menu-item:focus-visible { background: var(--accent); color: var(--accent-foreground); box-shadow: none; }
|
|
208
|
+
.menu-item:active { transform: none; }
|
|
209
|
+
.menu-item.destructive { color: var(--destructive-text); }
|
|
210
|
+
.menu-item.destructive svg { color: currentColor; }
|
|
211
|
+
/* shadcn/ui's tooltip (src/ui/tooltip.ts). */
|
|
212
|
+
.tooltip {
|
|
213
|
+
position: fixed; z-index: 2147483647; pointer-events: none; max-width: 280px; width: max-content;
|
|
214
|
+
padding: 6px 12px; border-radius: var(--radius-md); background: var(--foreground); color: var(--background);
|
|
215
|
+
font: var(--text-xs)/1.35 var(--font-sans); animation: baack-fade-in 100ms ease-out;
|
|
216
|
+
}
|
|
217
|
+
@keyframes baack-fade-in { from { opacity: 0; transform: scale(0.96); } }
|
|
218
|
+
@media (prefers-reduced-motion: reduce) { .menu, .tooltip { animation: none; } }
|
|
219
|
+
/* The sidebar (src/ui/stack.ts), docked right (or left); a bottom sheet on narrow screens. */
|
|
220
|
+
.side { top: 16px; right: 16px; bottom: 16px; width: min(420px, calc(100vw - 32px)); display: flex; flex-direction: column; gap: 8px; padding: 12px 14px; box-shadow: var(--shadow-lg); }
|
|
221
|
+
.side[data-side="left"] { right: auto; left: 16px; }
|
|
222
|
+
/* shadcn/ui's sheet, floating clear of the page's edge: it slides in from its side, or up from the bottom. */
|
|
223
|
+
.side.stack:not([hidden]) { animation: baack-sheet-right 200ms ease-out; }
|
|
224
|
+
.side.stack[data-side="left"]:not([hidden]) { animation-name: baack-sheet-left; }
|
|
225
|
+
@keyframes baack-sheet-right { from { transform: translateX(calc(100% + 16px)); } }
|
|
226
|
+
@keyframes baack-sheet-left { from { transform: translateX(calc(-100% - 16px)); } }
|
|
227
|
+
@keyframes baack-sheet-up { from { transform: translateY(calc(100% + 16px)); } }
|
|
228
|
+
@media (prefers-reduced-motion: reduce) { .side.stack:not([hidden]) { animation: none !important; } }
|
|
229
|
+
.side-dock { white-space: nowrap; }
|
|
230
|
+
@media (max-width: 640px) {
|
|
231
|
+
.side.stack, .side.stack[data-side="left"] { top: auto; left: 8px; right: 8px; width: auto; max-height: 60vh; border-radius: var(--radius-xl) var(--radius-xl) var(--radius-md) var(--radius-md); }
|
|
232
|
+
.side.stack.item-editing { display: none; }
|
|
233
|
+
/* A sheet has no side to dock on. */
|
|
234
|
+
.side.stack .side-dock { display: none; }
|
|
235
|
+
.side.stack:not([hidden]), .side.stack[data-side="left"]:not([hidden]) { animation-name: baack-sheet-up; }
|
|
236
|
+
/* The sheet's grip, as on a drawer. */
|
|
237
|
+
.side.stack::before { content: ""; align-self: center; flex-shrink: 0; width: 40px; height: 4px; margin: -4px 0 2px; border-radius: 999px; background: var(--muted-foreground); opacity: 0.35; }
|
|
238
|
+
}
|
|
239
|
+
/* The sidebar stack (src/ui/stack.ts): Back, breadcrumb, title, then the level on screen. */
|
|
240
|
+
.stack { gap: 4px; }
|
|
241
|
+
/* The toolbar's entity: its title, then its state and unsaved count, as one line of text that wraps. */
|
|
242
|
+
.entity-label { display: block; width: 100%; padding: 6px 10px; text-align: left; font-weight: 400; line-height: 1.4; }
|
|
243
|
+
.level-lifecycle { display: flex; flex-direction: column; gap: 6px; margin-bottom: 6px; }
|
|
244
|
+
.level-entity, .level-slots, .level-page { display: flex; flex-direction: column; gap: 8px; }
|
|
245
|
+
.stack-bar { display: flex; align-items: center; gap: 6px; }
|
|
246
|
+
.stack-spacer { flex: 1 1 auto; }
|
|
247
|
+
.stack-back { max-width: 60%; padding-left: 4px; }
|
|
248
|
+
.stack-back-text { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
|
249
|
+
.stack-close { white-space: nowrap; }
|
|
250
|
+
.stack-crumbs ol { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 6px; list-style: none; margin: 0; padding: 0; font-size: var(--text-xs); color: var(--muted-foreground); overflow-wrap: anywhere; }
|
|
251
|
+
.stack-crumbs li { display: inline-flex; align-items: center; }
|
|
252
|
+
.stack-crumb-separator svg { width: 14px; height: 14px; }
|
|
253
|
+
.stack-crumb { border: none; background: none; min-height: 0; padding: 0; font-size: inherit; font-weight: 400; color: var(--muted-foreground); }
|
|
254
|
+
.stack-crumb:hover { background: none; color: var(--foreground); }
|
|
255
|
+
.stack-crumb:active { transform: none; }
|
|
256
|
+
.stack-crumbs [aria-current="page"] { color: var(--foreground); }
|
|
257
|
+
.stack-title { margin: 0; font-size: var(--text-base); font-weight: 600; outline: none; }
|
|
258
|
+
.stack-body { position: relative; flex: 1 1 auto; min-height: 0; overflow-y: auto; overflow-x: hidden; border-top: 1px solid var(--border); padding-top: 8px; }
|
|
259
|
+
.stack-level.leaving { position: absolute; left: 0; right: 0; background: var(--popover); z-index: 1; }
|
|
260
|
+
.stack-row { display: flex; justify-content: flex-start; align-items: center; gap: 8px; width: 100%; text-align: left; margin: 0 0 4px; padding: 8px 10px; background: var(--popover); box-shadow: none; }
|
|
261
|
+
.stack-row-text { display: flex; flex-direction: column; flex: 1 1 auto; min-width: 0; overflow-wrap: anywhere; }
|
|
262
|
+
.stack-row-label { font-weight: 600; }
|
|
263
|
+
.stack-chevron { display: inline-flex; color: var(--muted-foreground); }
|
|
264
|
+
.visually-hidden { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; margin: 0; padding: 0; }
|
|
265
|
+
.tab-panel { flex: 1 1 auto; min-height: 0; display: flex; flex-direction: column; gap: 8px; }
|
|
266
|
+
.tab-panel > .outline-body { flex: 1 1 auto; min-height: 0; }
|
|
267
|
+
.outline-header { display: flex; justify-content: space-between; align-items: center; }
|
|
268
|
+
.outline-body { overflow: auto; display: flex; flex-direction: column; gap: 14px; }
|
|
269
|
+
.section-title { margin: 0; font-size: var(--text-sm); }
|
|
270
|
+
.outline-group { display: flex; flex-direction: column; gap: 4px; margin-top: 8px; }
|
|
271
|
+
.group-heading { display: flex; justify-content: space-between; align-items: center; color: var(--foreground); font-size: var(--text-xs); font-weight: 600; border-bottom: 1px solid var(--border); padding-bottom: 4px; }
|
|
272
|
+
.group-hint { margin: 0; color: var(--muted-foreground); font-size: var(--text-xs); }
|
|
273
|
+
.section-status { margin: 2px 0 0; color: var(--muted-foreground); font-size: var(--text-xs); }
|
|
274
|
+
.status.note { background: var(--secondary); color: var(--secondary-foreground); }
|
|
275
|
+
.outline .row { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 6px; padding: 3px 0; border-bottom: 1px solid var(--border); }
|
|
276
|
+
.row-main { flex: 1 1 auto; display: flex; flex-wrap: wrap; justify-content: flex-start; align-items: baseline; gap: 4px; text-align: left; border: 0; background: none; padding: 2px 6px; font-weight: 400; }
|
|
277
|
+
button.row-main { min-height: 0; }
|
|
278
|
+
button.row-main:hover { background: var(--accent); }
|
|
279
|
+
button.row-main:active, .stack-row:active { transform: none; }
|
|
280
|
+
.row-name { font-weight: 600; }
|
|
281
|
+
.row-name.link { font-weight: 600; }
|
|
282
|
+
.outline .row.current { background: color-mix(in oklab, var(--primary) 8%, var(--popover)); box-shadow: inset 3px 0 0 var(--primary); }
|
|
283
|
+
/* Badges: shadcn/ui's badge, for lifecycle and item states. Secondary unless the state says otherwise. */
|
|
284
|
+
.status, .flag {
|
|
285
|
+
display: inline-flex; align-items: center; gap: 4px; flex-shrink: 0; white-space: nowrap;
|
|
286
|
+
height: 20px; padding: 0 8px; border-radius: 999px; border: 1px solid transparent;
|
|
287
|
+
font: 500 var(--text-xs)/1 var(--font-sans); background: var(--secondary); color: var(--secondary-foreground);
|
|
288
|
+
}
|
|
289
|
+
.status-unpublished-changes, .status-unsaved { background: color-mix(in oklab, var(--warning) 12%, var(--popover)); color: var(--warning); }
|
|
290
|
+
.status-not-in-content, .flag { background: color-mix(in oklab, var(--destructive) 10%, var(--popover)); color: var(--destructive-text); }
|
|
291
|
+
.status-up-to-date { background: transparent; border-color: var(--success); color: var(--success); }
|
|
292
|
+
.history-row { flex-direction: column; align-items: stretch !important; gap: 4px !important; padding: 8px 0 !important; }
|
|
293
|
+
.history-row > .actions { margin-top: -2px; }
|
|
294
|
+
.history-row > .row-main { display: flex; flex-wrap: wrap; align-items: center; gap: 4px; width: 100%; text-align: left; }
|
|
295
|
+
.history-row > .row-main .stack-chevron { margin-left: auto; }
|
|
296
|
+
.version-head { display: flex; flex-wrap: wrap; align-items: center; gap: 4px; margin: 0 0 8px; }
|
|
297
|
+
.version-change { margin-bottom: 8px; }
|
|
298
|
+
.level-confirm .description { margin: 8px 0; }
|
|
299
|
+
.level-confirm > .meta { margin-top: 0; }
|
|
300
|
+
/* A long review keeps Publish in reach: its buttons stay at the bottom of the sidebar. */
|
|
301
|
+
.level-review > .actions { position: sticky; bottom: 0; background: var(--popover); padding: 8px 0 2px; border-top: 1px solid var(--border); }
|
|
302
|
+
.level-schedule { display: flex; flex-direction: column; gap: 8px; }
|
|
303
|
+
.level-schedule .hint { margin: 0; }
|
|
304
|
+
.row > .change { padding-inline: 6px; }
|
|
305
|
+
.change { white-space: pre-wrap; overflow-wrap: anywhere; font-size: var(--text-xs); color: var(--foreground); }
|
|
306
|
+
.change ins { background: color-mix(in oklab, var(--success) 15%, transparent); color: var(--success); text-decoration: underline; }
|
|
307
|
+
.change del { background: color-mix(in oklab, var(--destructive) 12%, transparent); color: var(--destructive); }
|
|
308
|
+
.change .delta { font-weight: 600; padding: 0 3px; border-radius: 3px; }
|
|
309
|
+
/* The arrow glyph sits low in most fonts: centre it on the line. */
|
|
310
|
+
.change .arrow { display: inline-block; vertical-align: middle; line-height: 1; margin: 0 0.35em; }
|
|
311
|
+
.change .delta.up { background: color-mix(in oklab, var(--success) 15%, transparent); color: var(--success); }
|
|
312
|
+
.change .delta.down { background: color-mix(in oklab, var(--destructive) 12%, transparent); color: var(--destructive); }
|
|
313
|
+
.slot-preview { display: flex; align-items: center; gap: 6px; }
|
|
314
|
+
.slot-preview img { width: 56px; height: 40px; object-fit: cover; border-radius: var(--radius-sm); border: 1px solid var(--border); }
|
|
315
|
+
.slot-preview .meta { font-size: 11px; overflow-wrap: anywhere; }
|
|
316
|
+
.extras:empty { display: none; }
|
|
317
|
+
.extras { display: flex; flex-wrap: wrap; justify-content: flex-end; align-items: center; gap: 4px; }
|
|
318
|
+
.extras button { white-space: nowrap; }
|
|
319
|
+
.popover .title { overflow-wrap: anywhere; }
|
|
320
|
+
.reorder-row { align-items: center; }
|
|
321
|
+
.reorder-row.dragging { opacity: 0.5; }
|
|
322
|
+
.handle { display: inline-flex; cursor: grab; color: var(--muted-foreground); padding: 0 2px; }
|
|
323
|
+
.entities:empty { display: none; }
|
|
324
|
+
.entities { display: flex; flex-direction: column; gap: 8px; border-top: 1px solid var(--border); padding-top: 6px; max-height: 50vh; overflow: auto; }
|
|
325
|
+
.entity { display: flex; flex-direction: column; gap: 4px; }
|
|
326
|
+
.entity + .entity { border-top: 1px dashed var(--border); padding-top: 6px; }
|
|
327
|
+
.unsent { color: var(--warning); }
|
|
328
|
+
.lifecycle-status { font-weight: 600; color: var(--foreground); }
|
|
329
|
+
.title { font-weight: 600; }
|
|
330
|
+
.meta { color: var(--muted-foreground); font-weight: 400; }
|
|
331
|
+
/* Buttons wrap whole onto the next line rather than squeezing their labels. */
|
|
332
|
+
.actions { display: flex; flex-wrap: wrap; justify-content: flex-end; gap: 6px; }
|
|
333
|
+
.actions > button { white-space: nowrap; }
|
|
334
|
+
.hint { margin: 0; color: var(--muted-foreground); font-size: var(--text-xs); }
|
|
335
|
+
`;function D(){let t=document.getElementById(T);t||(t=document.createElement("div"),t.id=T,t.attachShadow({mode:"open"}),document.body.append(t));let e=t.shadowRoot;if(!e.querySelector("style")){let r=document.createElement("style");r.textContent=N,e.append(r)}return{element:t,root:e}}function Y(t){if(!t)return[];let e=i("details","debug");return e.append(i("summary","","Debug"),i("pre","",t)),[e]}function j(t,e="outline",r="default",n=""){let a=[n,e==="outline"?"":e,r==="default"?"":r].filter(Boolean).join(" "),d=i("button",a,t);return d.type="button",d}function G(t){return t.destructive?"destructive":t.primary?"primary":"outline"}function U(t){let e=i("span","select-box");return e.append(t,k("chevron-down")),e}function i(t,e="",r=""){let n=document.createElement(t);return e&&(n.className=e),r&&(n.textContent=r),n}var R="Edit page";function q(t){let e=t.root.querySelector(".toolbar button.mode");if(e)return e;let r=i("div","panel toolbar");r.setAttribute("role","region"),r.setAttribute("aria-label","Baack editor");let n=i("div","toolbar-row"),a=i("button","mode",R);return a.type="button",a.setAttribute("aria-pressed","false"),n.append(i("span","brand","Baack"),a),r.append(n),t.root.append(r),a}var v=Object.freeze({ADDRESS:"/n/v1/address/",API_CLIENT:"/n/v1/apiclient/",BEARER_TOKEN:"/n/v1/bearertoken/",BOOLEAN:"/n/v1/booleanitem/",BOOLEAN_HISTORY:"/n/v1/booleanitemhistory/",CLIENT_CONTEXT:"/n/v1/clientcontext",CLIENT_IDENTIFIER:"/n/v1/clientidentifier/",COMPANIES:"/n/v1/companies",COMPANY:"/n/v1/company/",DATE_TIME:"/n/v1/datetimeitem/",DATE_TIME_HISTORY:"/n/v1/datetimeitemhistory/",DOUBLE:"/n/v1/doubleitem/",DOUBLE_HISTORY:"/n/v1/doubleitemhistory/",EMAIL:"/n/v1/email/",ENTITY:"/n/v1/entity/",ENTITY_LIST:"/n/v1/entitylist/",ENTITY_VIEW:"/v/v1/entityview/",GROUP:"/n/v1/group/",GROUP_MEMBERSHIP:"/n/v1/groupmembership/",IDENTITY:"/n/v1/identity/",IDENTITY_NOTIFICATION_INBOX:"/n/v1/identitynotificationinbox/",IMAGE:"/n/v1/imageitem/",IMAGE_HISTORY:"/n/v1/imageitemhistory/",IMAGE_FILE:"/n/v1/imageitemfile",JSON:"/n/v1/jsonitem/",JSON_HISTORY:"/n/v1/jsonitemhistory/",LAT_LONG:"/n/v1/latlongitem/",LAT_LONG_HISTORY:"/n/v1/latlongitemhistory/",LINK:"/n/v1/linkitem/",LINK_HISTORY:"/n/v1/linkitemhistory/",LONG:"/n/v1/longitem/",LONG_HISTORY:"/n/v1/longitemhistory/",MARKDOWN:"/n/v1/markdownitem/",MARKDOWN_HISTORY:"/n/v1/markdownitemhistory/",MESSAGE_THREAD:"/n/v1/messagethread/",MESSAGE_THREAD_NOTIFICATION:"/n/v1/messagethreadnotification/",MONEY:"/n/v1/moneyitem/",MONEY_HISTORY:"/n/v1/moneyitemhistory/",OAUTH_TOKEN:"/n/v1/oauthtoken/",PAYMENT_INVOICE:"/n/v1/paymentinvoice/",PERMISSION:"/n/v1/permission/",PERSON:"/n/v1/person/",PERSON_NAME:"/n/v1/personname/",SEARCH:"/n/v1/search/",REFERENCE:"/n/v1/referenceitem/",REFERENCE_HISTORY:"/n/v1/referenceitemhistory/",TASK:"/n/v1/task/",TASK_LOG:"/n/v1/tasklog/",TASK_LOGS:"/n/v1/tasklogs/",TEMPLATE:"/n/v1/templateitem/",TEMPLATE_HISTORY:"/n/v1/templateitemhistory/",TEXT:"/n/v1/textitem/",TEXT_HISTORY:"/n/v1/textitemhistory/",THREAD_POST:"/n/v1/threadpost/",WEBHOOK_SUBSCRIPTION:"/n/v1/webhooksubscription/",WEBHOOK_TRIGGER:"/n/v1/webhooktrigger/",WORKFLOW:"/n/v1/workflow/"});var g=class extends Error{status;statusText;body;method;url;requestBody;name="BaackApiError";constructor(e,r,n,a,d,l){super(`Baack API Error [${e}]: ${n||r}`),this.status=e,this.statusText=r,this.body=n,this.method=a,this.url=d,this.requestBody=l}get isUnauthorized(){return this.status===401}get isForbidden(){return this.status===403}get isNotFound(){return this.status===404}get isConflict(){return this.status===409||this.status===412}get isServerError(){return this.status>=500}get apiError(){let e=this.json();return e!==null&&typeof e=="object"?e:void 0}get detail(){let e=this.apiError?.detail;return typeof e=="string"&&e!==""?e:void 0}json(){if(this.body)try{return JSON.parse(this.body)}catch{return}}};function V(t){return t instanceof g}var c={CREATE:"POST",READ:"GET",UPDATE:"PUT",DELETE:"DELETE"},S=class{baseUrl;defaultHeaders;credentials;constructor(e){this.baseUrl=e.baseUrl.replace(/\/$/,""),this.defaultHeaders={...e.headers},this.credentials=e.credentials}async request(e,r={},n){let a=new URL(this.baseUrl+e);n&&Object.entries(n).forEach(([h,f])=>{f!=null&&a.searchParams.append(h,String(f))});let d=typeof r.body=="string"?{"Content-Type":"application/json",...this.defaultHeaders}:{...this.defaultHeaders},l={...r,headers:{...d,...r.headers}};this.credentials&&(l.credentials=this.credentials);let O=r.method??c.READ,x=await fetch(a.toString(),l),m=await x.text();if(!x.ok){let h=typeof l.body=="string"?l.body:void 0;throw new g(x.status,x.statusText,m,O,a.toString(),h)}return m?JSON.parse(m):void 0}async create(e,r){return this.request(e,I(c.CREATE,r))}async read(e,r,n,a){return this.request(w(e,r),{method:c.READ,...a?{headers:a}:{}},n)}async update(e,r,n){return this.request(w(e,r),I(c.UPDATE,n))}async delete(e,r){return this.request(w(e,r),{method:c.DELETE})}async upload(e,r){return this.request(e,{method:c.CREATE,body:r})}async search(e){return this.create(v.SEARCH,e)}async searchResult(e,r){return this.read(v.SEARCH,e,{after:r})}};function w(t,e){return t.endsWith("/")&&e.startsWith("/")?t+e.slice(1):t+e}function I(t,e){return e===void 0?{method:t}:{method:t,body:JSON.stringify(e)}}export{L as a,v as b,V as c,S as d,k as e,C as f,D as g,Y as h,j as i,G as j,U as k,i as l,q as m};
|
|
336
|
+
//# sourceMappingURL=chunk-JI2V7IMH.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/config.ts", "../../src/ui/icons.ts", "../../src/ui/theme.ts", "../../src/ui/host.ts", "../../src/ui/launcher.ts", "../../node_modules/@baack-software/baack-ts-client/src/endpoints.ts", "../../node_modules/@baack-software/baack-ts-client/src/errors.ts", "../../node_modules/@baack-software/baack-ts-client/src/client.ts"],
|
|
4
|
+
"sourcesContent": ["import type { AfterPublish } from './after-publish.ts';\nimport type { EntityNameForPage, PagePathForEntity } from './page-entity.ts';\n\n// Site configuration, set before the loader runs:\n// <script>window.baackEditorConfig = { baseUrl: 'https://api.baack.co' }</script>\n\nexport interface EditorConfig {\n /** Where the Baack API is. Requests carry the user's session cookie. */\n baseUrl: string;\n /** How long a publish may stay in progress before the editor says it is taking too long. Default 5 minutes. */\n publishTimeoutMs?: number;\n /** Image slots a version needs before its entity can be published. Default: the default slot only. */\n requiredImageSlots?: ('DEFAULT' | 'MEDIUM' | 'LARGE')[];\n /**\n * Off by default. Widths to create the medium and large files at, in the\n * browser, when only a default file is chosen. Never scales up.\n */\n imageWidths?: { MEDIUM?: number; LARGE?: number };\n /** Largest image file the editor will upload, in bytes. Default 10 MB. */\n maxImageBytes?: number;\n /** Above this size the editor warns that the file is large for the web. Default 2 MB. */\n warnImageBytes?: number;\n /**\n * After every publish (an entity, or a version from History): a message to\n * show, such as \"Live after the next build, in about 2 minutes\", or a\n * function called with what was published, which may return a message.\n * Fixed text also replaces the note about built sites on leaving edit mode.\n */\n afterPublish?: AfterPublish;\n /**\n * The entity name that serves a page whose markup names no entity, from\n * the page's URL path: used to find its content, and offered when creating\n * it. Baack has no index entities, so a directory path needs a name of its\n * own. Default: `/` (and `/index.html`) is `/home`, otherwise the path\n * without a trailing slash.\n */\n entityNameForPage?: EntityNameForPage;\n /**\n * The reverse: the page address an entity serves, from its name. Used for\n * a link's suggestions and the `path` told to `afterPublish`. Default:\n * `/home` is `/`, any other name its own path.\n */\n pagePathForEntity?: PagePathForEntity;\n}\n\ndeclare global {\n interface Window {\n baackEditorConfig?: Partial<EditorConfig>;\n }\n}\n\n/**\n * The configuration, from `window.baackEditorConfig`, or (for sites whose\n * Content-Security-Policy forbids inline scripts) a meta tag:\n * <meta name=\"baack-editor-api\" content=\"https://api.baack.co\">\n */\nexport function readConfig(): EditorConfig {\n const meta = document.querySelector<HTMLMetaElement>('meta[name=\"baack-editor-api\"]')?.content;\n return { ...window.baackEditorConfig, baseUrl: window.baackEditorConfig?.baseUrl ?? meta ?? 'https://api.baack.co' };\n}\n", "// The editor's icons: a few from lucide (https://lucide.dev, ISC licence),\n// copied as shapes and drawn with DOM calls, so there is no package and no\n// markup parsed. 24 by 24, stroked in currentColor, as lucide draws them.\n\ntype Shape = [tag: 'path' | 'circle' | 'rect', attributes: Record<string, string | number>];\n\nconst path = (d: string): Shape => ['path', { d }];\nconst dot = (cx: number, cy: number): Shape => ['circle', { cx, cy, r: 1 }];\n\nconst ICONS = {\n 'arrow-down': [path('M12 5v14'), path('m19 12-7 7-7-7')],\n 'arrow-up': [path('m5 12 7-7 7 7'), path('M12 19V5')],\n check: [path('M20 6 9 17l-5-5')],\n 'chevron-down': [path('m6 9 6 6 6-6')],\n 'chevron-left': [path('m15 18-6-6 6-6')],\n 'chevron-right': [path('m9 18 6-6-6-6')],\n ellipsis: [dot(12, 12), dot(19, 12), dot(5, 12)],\n 'grip-vertical': [dot(9, 12), dot(9, 5), dot(9, 19), dot(15, 12), dot(15, 5), dot(15, 19)],\n history: [path('M3 12a9 9 0 1 0 9-9 9.75 9.75 0 0 0-6.74 2.74L3 8'), path('M3 3v5h5'), path('M12 7v5l4 2')],\n 'list-ordered': [path('M10 12h11'), path('M10 18h11'), path('M10 6h11'), path('M4 10h2'), path('M4 6h1v4'), path('M6 18H4c0-1 2-2 2-3s-1-1.5-2-1')],\n 'panel-left': [['rect', { width: 18, height: 18, x: 3, y: 3, rx: 2 }], path('M9 3v18')],\n 'panel-right': [['rect', { width: 18, height: 18, x: 3, y: 3, rx: 2 }], path('M15 3v18')],\n 'pencil-line': [path('M13 21h8'), path('m15 5 4 4'), path('M21.174 6.812a1 1 0 0 0-3.986-3.987L3.842 16.174a2 2 0 0 0-.5.83l-1.321 4.352a.5.5 0 0 0 .623.622l4.353-1.32a2 2 0 0 0 .83-.497z')],\n plus: [path('M5 12h14'), path('M12 5v14')],\n search: [['circle', { cx: 11, cy: 11, r: 8 }], path('m21 21-4.3-4.3')],\n x: [path('M18 6 6 18'), path('m6 6 12 12')],\n} satisfies Record<string, Shape[]>;\n\nexport type IconName = keyof typeof ICONS;\n\nconst SVG = 'http://www.w3.org/2000/svg';\n\n/** An icon, hidden from assistive technology: the control it sits in carries the name. */\nexport function icon(name: IconName): SVGSVGElement {\n const svg = document.createElementNS(SVG, 'svg');\n for (const [attribute, value] of Object.entries({\n viewBox: '0 0 24 24',\n width: 16,\n height: 16,\n fill: 'none',\n stroke: 'currentColor',\n 'stroke-width': 2,\n 'stroke-linecap': 'round',\n 'stroke-linejoin': 'round',\n 'aria-hidden': 'true',\n focusable: 'false',\n class: `icon icon-${name}`,\n })) {\n svg.setAttribute(attribute, String(value));\n }\n for (const [tag, attributes] of ICONS[name] as Shape[]) {\n const shape = document.createElementNS(SVG, tag);\n for (const [attribute, value] of Object.entries(attributes)) shape.setAttribute(attribute, String(value));\n svg.append(shape);\n }\n return svg;\n}\n", "// The Baack look (docs/plans/baack-look.md): www.baack.co's shadcn/ui tokens\n// as CSS custom properties on the editor's shadow host, light and dark. The\n// editor's stylesheet (host.ts) uses only these: no literal colours.\n//\n// Sizes are in px, not rem: rem follows the host page's root font size.\n\nconst LIGHT = {\n background: '#ffffff',\n foreground: '#111827',\n popover: '#ffffff',\n 'popover-foreground': '#111827',\n primary: '#1d4ed8',\n 'primary-foreground': '#ffffff',\n secondary: '#f6f7f9',\n 'secondary-foreground': '#111827',\n muted: '#f6f7f9',\n 'muted-foreground': '#4b5563',\n accent: '#f3f4f6',\n 'accent-foreground': '#111827',\n destructive: '#dc2626',\n // Red text on a red tint (destructive buttons, badges): darker, for 4.5:1 contrast.\n 'destructive-text': '#b91c1c',\n border: '#e5e7eb',\n input: '#d1d5db',\n ring: '#1d4ed8',\n success: '#047857',\n // The site's amber tone: unsaved and pending work.\n warning: '#92400e',\n // The site's violet tone: previews of other versions.\n preview: '#6d28d9',\n overlay: 'rgb(0 0 0 / 0.5)',\n 'shadow-color': 'rgb(17 24 39 / 0.1)',\n // The outline button and fields: shadcn's light and dark treatments differ.\n 'control-background': 'var(--background)',\n 'control-border': 'var(--border)',\n 'control-hover': 'var(--muted)',\n 'field-background': 'transparent',\n 'switch-off': 'var(--input)',\n 'switch-thumb-off': 'var(--background)',\n 'switch-thumb-on': 'var(--background)',\n};\n\nconst DARK: typeof LIGHT = {\n background: '#0d1117',\n foreground: '#f3f4f6',\n popover: '#151b24',\n 'popover-foreground': '#f3f4f6',\n primary: '#6b9bff',\n 'primary-foreground': '#0d1117',\n secondary: '#1c2430',\n 'secondary-foreground': '#f3f4f6',\n muted: '#11161e',\n 'muted-foreground': '#a1a9b6',\n accent: '#1f2733',\n 'accent-foreground': '#f3f4f6',\n destructive: '#f87171',\n 'destructive-text': '#f87171',\n border: '#262e3a',\n input: '#343e4d',\n ring: '#6b9bff',\n success: '#34d399',\n warning: '#fbbf24',\n preview: '#c4b5fd',\n overlay: 'rgb(0 0 0 / 0.65)',\n 'shadow-color': 'rgb(0 0 0 / 0.45)',\n 'control-background': 'color-mix(in oklab, var(--input) 30%, transparent)',\n 'control-border': 'var(--input)',\n 'control-hover': 'color-mix(in oklab, var(--input) 50%, transparent)',\n 'field-background': 'color-mix(in oklab, var(--input) 30%, transparent)',\n 'switch-off': 'color-mix(in oklab, var(--input) 80%, transparent)',\n 'switch-thumb-off': 'var(--foreground)',\n 'switch-thumb-on': 'var(--primary-foreground)',\n};\n\nconst SCALE = `\n /* Installed fonts only, so no site needs to allow a font source in its Content Security Policy. Figtree when the\n page has loaded it (www.baack.co), then the nearest match on Apple devices, then each platform's UI font. */\n --font-sans: Figtree, \"Avenir Next\", \"Segoe UI Variable Text\", \"Segoe UI\", Roboto, system-ui, -apple-system, sans-serif;\n --font-mono: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;\n --text-xs: 12px;\n --text-sm: 14px;\n --text-base: 16px;\n --radius: 10px;\n --radius-sm: 6px;\n --radius-md: 8px;\n --radius-lg: 10px;\n --radius-xl: 14px;\n --shadow-sm: 0 1px 2px 0 var(--shadow-color);\n --shadow-md: 0 4px 6px -1px var(--shadow-color), 0 2px 4px -2px var(--shadow-color);\n --shadow-lg: 0 10px 15px -3px var(--shadow-color), 0 4px 6px -4px var(--shadow-color);\n /* shadcn's ring-3 ring-ring/50. */\n --focus-ring: 0 0 0 3px color-mix(in oklab, var(--ring) 50%, transparent);\n`;\n\nfunction tokens(set: typeof LIGHT): string {\n return Object.entries(set)\n .map(([name, value]) => ` --${name}: ${value};`)\n .join('\\n');\n}\n\n/** The tokens, for the start of the shadow root's stylesheet. Dark follows the visitor's system setting. */\nexport const THEME_CSS = `\n:host {\n color-scheme: light;\n${tokens(LIGHT)}\n${SCALE}\n}\n@media (prefers-color-scheme: dark) {\n :host {\n color-scheme: dark;\n${tokens(DARK)}\n }\n}\n/* Baack's login page does not follow the dark setting yet, so the login stays light: the modal around it, and the\n frame wherever it is (an iframe's color-scheme is the one its page sees). */\n.login-modal {\n color-scheme: light;\n${tokens(LIGHT)}\n}\n.login iframe { color-scheme: light; background: ${LIGHT.background}; }\n`;\n\n/**\n * Outline colours for elements on the host page, outside the shadow root: each is light-dark(), so it follows the\n * page's own color-scheme, with the light colour for browsers without light-dark().\n */\nexport const PAGE_COLOURS = {\n primary: [LIGHT.primary, DARK.primary],\n warning: ['#b45309', DARK.warning],\n preview: ['#7c3aed', DARK.preview],\n success: [LIGHT.success, DARK.success],\n muted: ['#6b7280', '#9ca3af'],\n} as const satisfies Record<string, readonly [string, string]>;\n", "// The editor's own corner of the page: one element with a shadow root, so\n// host page CSS cannot reach the editor UI and the editor's CSS cannot leak.\n\nimport { icon } from './icons.ts';\nimport { THEME_CSS } from './theme.ts';\n\nconst HOST_ID = 'baack-editor-host';\n\nconst STYLES = `${THEME_CSS}\n:host { all: initial; }\n* { box-sizing: border-box; }\n.panel {\n position: fixed; z-index: 2147483647;\n font: var(--text-sm)/1.45 var(--font-sans);\n color: var(--popover-foreground); background: var(--popover);\n border: 1px solid var(--border); border-radius: var(--radius-lg);\n box-shadow: var(--shadow-md);\n padding: 10px 12px;\n}\n.toolbar { right: 16px; bottom: 16px; display: flex; flex-direction: column; gap: 6px; max-width: 380px; }\n/* A row wraps whole buttons onto the next line rather than squeezing their labels. */\n.toolbar-row { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 8px; }\n.toolbar-row > button, .toolbar-row > .brand { white-space: nowrap; }\n.toolbar > .message-action { align-self: flex-start; }\n.debug { font-size: var(--text-xs); color: var(--muted-foreground); }\n.debug summary { cursor: pointer; }\n.debug pre { margin: 4px 0 0; padding: 6px; max-height: 12em; overflow: auto; white-space: pre-wrap; overflow-wrap: anywhere; background: var(--muted); border-radius: var(--radius-sm); font: 11px/1.45 var(--font-mono); }\n.brand { font-weight: 700; letter-spacing: -0.01em; }\n.pending { color: var(--warning); }\n/* Buttons: shadcn/ui's variants and sizes (button() in this module). With no class, the outline variant. */\nbutton {\n display: inline-flex; align-items: center; justify-content: center; gap: 6px; flex-shrink: 0;\n font: 500 var(--text-sm)/1.25 var(--font-sans); color: var(--foreground); cursor: pointer; user-select: none;\n min-height: 32px; padding: 4px 10px; border-radius: var(--radius-lg);\n border: 1px solid var(--control-border); background: var(--control-background); background-clip: padding-box;\n transition: background-color 120ms, border-color 120ms, box-shadow 120ms, color 120ms;\n}\nbutton:enabled:hover { background-color: var(--control-hover); color: var(--foreground); }\nbutton:active:not([aria-haspopup]) { transform: translateY(1px); }\nbutton:focus-visible { outline: none; border-color: var(--ring); box-shadow: var(--focus-ring); }\n/* Not pointer-events: none, so the title saying why it is disabled still shows on hover. */\nbutton:disabled { opacity: 0.5; cursor: default; }\nbutton svg { flex-shrink: 0; width: 16px; height: 16px; pointer-events: none; }\nbutton.primary { background: var(--primary); border-color: transparent; color: var(--primary-foreground); }\nbutton.primary:enabled:hover { background: color-mix(in oklab, var(--primary) 80%, transparent); }\nbutton.secondary { background: var(--secondary); border-color: transparent; color: var(--secondary-foreground); }\nbutton.secondary:enabled:hover { background: color-mix(in oklab, var(--secondary), var(--foreground) 5%); }\nbutton.ghost { background: transparent; border-color: transparent; }\nbutton.ghost:enabled:hover { background: var(--control-hover); }\nbutton.destructive { background: color-mix(in oklab, var(--destructive) 10%, transparent); border-color: transparent; color: var(--destructive-text); }\nbutton.destructive:enabled:hover { background: color-mix(in oklab, var(--destructive) 20%, transparent); }\nbutton.destructive:focus-visible { border-color: color-mix(in oklab, var(--destructive) 40%, transparent); box-shadow: 0 0 0 3px color-mix(in oklab, var(--destructive) 20%, transparent); }\n/* A link inside text: no box, so it sits in the line. */\nbutton.link { display: inline; min-height: 0; padding: 0; border: 0; border-radius: var(--radius-sm); background: none; font: inherit; color: var(--primary); text-decoration: underline; text-underline-offset: 4px; }\nbutton.link:hover { background: none; text-decoration-thickness: 2px; }\nbutton.link:active { transform: none; }\nbutton.xs { min-height: 24px; gap: 4px; padding: 2px 8px; font-size: var(--text-xs); border-radius: var(--radius-md); }\nbutton.xs svg { width: 12px; height: 12px; }\nbutton.sm { min-height: 28px; gap: 4px; padding: 2px 10px; font-size: 12.8px; border-radius: var(--radius-md); }\nbutton.sm svg { width: 14px; height: 14px; }\nbutton.lg { min-height: 36px; }\nbutton.icon, button.icon-sm, button.icon-xs { padding: 0; width: 32px; height: 32px; min-height: 0; }\nbutton.icon-sm { width: 28px; height: 28px; border-radius: var(--radius-md); }\nbutton.icon-xs { width: 24px; height: 24px; border-radius: var(--radius-md); }\nbutton.icon-xs svg { width: 12px; height: 12px; }\n/* A toggle that is on, such as the live-page preview. */\nbutton[aria-pressed=\"true\"] { background: color-mix(in oklab, var(--primary) 10%, var(--control-background)); border-color: color-mix(in oklab, var(--primary) 60%, transparent); color: var(--primary); }\n/* Messages: shadcn/ui's alert. The colour is in the border and tint; the text keeps full contrast. */\n.message:empty, .issues:empty, .error:empty { display: none; }\np.message, p.error, .issues {\n margin: 0; padding: 8px 12px; border-radius: var(--radius-lg); font-size: var(--text-sm); color: var(--foreground);\n border: 1px solid color-mix(in oklab, var(--destructive) 50%, transparent);\n background: color-mix(in oklab, var(--destructive) 5%, var(--popover));\n}\np.message.info { border-color: var(--border); background: var(--popover); }\n.issues { padding-left: 12px; border-color: color-mix(in oklab, var(--warning) 45%, transparent); background: color-mix(in oklab, var(--warning) 6%, var(--popover)); }\nul.issues { padding-left: 28px; }\n.issues li::marker { color: var(--warning); }\n.issues li.error::marker { color: var(--destructive); }\n.issues li { color: var(--foreground); }\n/* A status line beside a field or in a list: coloured text, not a box. */\nspan.error, .hint.error { color: var(--destructive-text); }\n.login iframe { display: block; width: 100%; height: 140px; border: 1px solid var(--border); border-radius: var(--radius-md); }\n.panel:not(.popover) { z-index: 2147483646; }\n/* Below the editor's panels, so a popover or the sidebar covers the tags. */\n.order-tag {\n position: fixed; z-index: 2147483645; min-height: 0;\n font: 500 var(--text-xs)/1.3 var(--font-sans); color: var(--foreground);\n padding: 2px 8px; border-radius: 999px; border: 1px solid var(--border);\n background: color-mix(in oklab, var(--background) 94%, transparent); box-shadow: var(--shadow-sm);\n}\n.popover { width: max-content; min-width: 240px; max-width: 360px; display: flex; flex-direction: column; gap: 10px; padding: 12px 14px; }\n.popover.wide { width: min(560px, calc(100vw - 16px)); max-width: none; }\n.form:empty { display: none; }\n.form { display: flex; flex-direction: column; gap: 10px; }\n.field { display: flex; flex-direction: column; gap: 6px; }\n.field.checkbox { flex-direction: row; align-items: center; gap: 8px; cursor: pointer; }\n/* A field's label: shadcn/ui's label. A caption over a value shown read-only stays small and muted. */\n.caption { color: var(--muted-foreground); font-size: var(--text-xs); font-weight: 500; }\n.field > .caption, .field.checkbox .caption { color: var(--foreground); font-size: var(--text-sm); line-height: 1; }\n/* Fields: shadcn/ui's input, textarea and select. */\ninput, textarea, select {\n font: var(--text-sm)/1.4 var(--font-sans); color: var(--foreground); background: var(--field-background);\n min-width: 0; min-height: 32px; border: 1px solid var(--input); border-radius: var(--radius-lg); padding: 4px 10px;\n transition: border-color 120ms, box-shadow 120ms;\n}\nselect { cursor: pointer; }\ninput:focus-visible, textarea:focus-visible, select:focus-visible { outline: none; border-color: var(--ring); box-shadow: var(--focus-ring); }\ninput::placeholder, textarea::placeholder { color: var(--muted-foreground); }\ninput:disabled, textarea:disabled, select:disabled { opacity: 0.5; cursor: not-allowed; background: color-mix(in oklab, var(--input) 50%, transparent); }\n[aria-invalid=\"true\"] { border-color: var(--destructive); box-shadow: 0 0 0 3px color-mix(in oklab, var(--destructive) 20%, transparent); }\ntextarea { resize: vertical; width: 100%; }\ninput[type=\"file\"] { min-height: 0; padding: 4px; }\ninput[type=\"file\"]::file-selector-button {\n font: 500 var(--text-sm) var(--font-sans); color: var(--foreground); cursor: pointer; margin-right: 8px;\n padding: 3px 10px; border: 1px solid var(--control-border); border-radius: var(--radius-md); background: var(--control-background);\n}\ninput[type=\"checkbox\"]:not(.switch) { min-height: 0; accent-color: var(--primary); }\n/* A switch: a checkbox with role=\"switch\", drawn as shadcn/ui's. */\ninput.switch {\n appearance: none; position: relative; flex-shrink: 0; cursor: pointer; margin: 0; padding: 0;\n width: 32px; height: 18.4px; min-height: 0; border-radius: 999px; border: 1px solid transparent; background: var(--switch-off);\n transition: background-color 150ms, box-shadow 120ms;\n}\ninput.switch::before {\n content: \"\"; position: absolute; top: 50%; left: 0; width: 16px; height: 16px; border-radius: 999px;\n background: var(--switch-thumb-off); transform: translate(0, -50%); transition: transform 150ms;\n}\ninput.switch:checked { background: var(--primary); }\ninput.switch:checked::before { background: var(--switch-thumb-on); transform: translate(14px, -50%); }\n/* iOS Safari zooms into a field under 16px as it takes focus. */\n@media (max-width: 767px) { input, textarea, select { font-size: var(--text-base); } }\n/* The entity picker: a combo box with its list below. */\n.entity-picker { display: flex; flex-direction: column; gap: 4px; }\n/* shadcn/ui's combobox (its Command list): a search field, then the options. */\n.combobox-field, .select-box { position: relative; display: flex; flex-direction: column; }\n.combobox-field > svg, .select-box > svg { position: absolute; top: 50%; transform: translateY(-50%); pointer-events: none; color: var(--muted-foreground); }\n.combobox-field > svg:first-child { left: 10px; }\n.combobox-field > svg:last-child, .select-box > svg { right: 10px; }\n.combobox-field > input { padding-left: 32px; padding-right: 32px; }\n.select-box > select { appearance: none; padding-right: 32px; }\n.entity-options { list-style: none; margin: 0; padding: 4px; border: 1px solid var(--border); border-radius: var(--radius-lg); max-height: 220px; overflow: auto; background: var(--popover); box-shadow: var(--shadow-md); }\n.entity-option { display: flex; align-items: center; gap: 6px; padding: 6px 8px; border-radius: var(--radius-sm); cursor: pointer; overflow-wrap: anywhere; }\n.entity-option > .meta { flex: 1 1 auto; }\n.entity-option > svg { flex-shrink: 0; }\n.entity-option:hover, .entity-option.active { background: var(--accent); color: var(--accent-foreground); }\n.entity-option[aria-selected=\"true\"] { font-weight: 500; }\n.entity-option.create { margin-top: 4px; border-top: 1px solid var(--border); border-radius: 0 0 var(--radius-sm) var(--radius-sm); }\n.entity-create:empty { display: none; }\n.entity-create { border-top: 1px solid var(--border); padding-top: 6px; }\n.field.code textarea { font: var(--text-xs)/1.45 var(--font-mono); }\n.hint:empty { display: none; }\n.popover[hidden], .login[hidden], .pending[hidden], [hidden] { display: none !important; }\n.login-modal { position: fixed; inset: 0; z-index: 2147483647; background: var(--overlay); display: grid; place-items: center; }\n/* shadcn/ui's dialog: a larger title, a muted description, then the frame and its button. */\n.panel.modal { position: static; width: min(440px, calc(100vw - 32px)); display: flex; flex-direction: column; gap: 16px; padding: 24px; border-radius: var(--radius-xl); box-shadow: var(--shadow-lg); }\n.modal > .title { font-size: 18px; line-height: 1.2; letter-spacing: -0.01em; }\n.modal > p.message.info { padding: 0; border: 0; background: none; color: var(--muted-foreground); margin-top: -8px; }\n.modal .login iframe { height: 320px; }\n.pending { color: var(--warning); border-color: color-mix(in oklab, var(--warning) 40%, transparent); background: color-mix(in oklab, var(--warning) 10%, var(--background)); }\n.rows { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 2px; }\n.row.problem { color: var(--destructive); }\n.simple-form { display: flex; flex-direction: column; gap: 10px; }\n.snippet { font: var(--text-xs)/1.45 var(--font-mono); background: var(--muted); border-radius: var(--radius-sm); padding: 6px 8px; overflow-wrap: anywhere; margin: 0; }\n/* shadcn/ui's dropdown menu (src/ui/menu.ts). */\n.menu {\n position: fixed; z-index: 2147483647; display: flex; flex-direction: column; padding: 4px;\n background: var(--popover); color: var(--popover-foreground);\n border: 1px solid var(--border); border-radius: var(--radius-lg); box-shadow: var(--shadow-md);\n animation: baack-fade-in 100ms ease-out;\n}\n.menu-item {\n justify-content: flex-start; gap: 8px; width: 100%; min-height: 0; padding: 6px 8px;\n border: 0; border-radius: var(--radius-sm); background: none; font-weight: 400; white-space: nowrap;\n}\n.menu-item svg { color: var(--muted-foreground); }\n.menu-item:enabled:hover, .menu-item:focus-visible { background: var(--accent); color: var(--accent-foreground); box-shadow: none; }\n.menu-item:active { transform: none; }\n.menu-item.destructive { color: var(--destructive-text); }\n.menu-item.destructive svg { color: currentColor; }\n/* shadcn/ui's tooltip (src/ui/tooltip.ts). */\n.tooltip {\n position: fixed; z-index: 2147483647; pointer-events: none; max-width: 280px; width: max-content;\n padding: 6px 12px; border-radius: var(--radius-md); background: var(--foreground); color: var(--background);\n font: var(--text-xs)/1.35 var(--font-sans); animation: baack-fade-in 100ms ease-out;\n}\n@keyframes baack-fade-in { from { opacity: 0; transform: scale(0.96); } }\n@media (prefers-reduced-motion: reduce) { .menu, .tooltip { animation: none; } }\n/* The sidebar (src/ui/stack.ts), docked right (or left); a bottom sheet on narrow screens. */\n.side { top: 16px; right: 16px; bottom: 16px; width: min(420px, calc(100vw - 32px)); display: flex; flex-direction: column; gap: 8px; padding: 12px 14px; box-shadow: var(--shadow-lg); }\n.side[data-side=\"left\"] { right: auto; left: 16px; }\n/* shadcn/ui's sheet, floating clear of the page's edge: it slides in from its side, or up from the bottom. */\n.side.stack:not([hidden]) { animation: baack-sheet-right 200ms ease-out; }\n.side.stack[data-side=\"left\"]:not([hidden]) { animation-name: baack-sheet-left; }\n@keyframes baack-sheet-right { from { transform: translateX(calc(100% + 16px)); } }\n@keyframes baack-sheet-left { from { transform: translateX(calc(-100% - 16px)); } }\n@keyframes baack-sheet-up { from { transform: translateY(calc(100% + 16px)); } }\n@media (prefers-reduced-motion: reduce) { .side.stack:not([hidden]) { animation: none !important; } }\n.side-dock { white-space: nowrap; }\n@media (max-width: 640px) {\n .side.stack, .side.stack[data-side=\"left\"] { top: auto; left: 8px; right: 8px; width: auto; max-height: 60vh; border-radius: var(--radius-xl) var(--radius-xl) var(--radius-md) var(--radius-md); }\n .side.stack.item-editing { display: none; }\n /* A sheet has no side to dock on. */\n .side.stack .side-dock { display: none; }\n .side.stack:not([hidden]), .side.stack[data-side=\"left\"]:not([hidden]) { animation-name: baack-sheet-up; }\n /* The sheet's grip, as on a drawer. */\n .side.stack::before { content: \"\"; align-self: center; flex-shrink: 0; width: 40px; height: 4px; margin: -4px 0 2px; border-radius: 999px; background: var(--muted-foreground); opacity: 0.35; }\n}\n/* The sidebar stack (src/ui/stack.ts): Back, breadcrumb, title, then the level on screen. */\n.stack { gap: 4px; }\n/* The toolbar's entity: its title, then its state and unsaved count, as one line of text that wraps. */\n.entity-label { display: block; width: 100%; padding: 6px 10px; text-align: left; font-weight: 400; line-height: 1.4; }\n.level-lifecycle { display: flex; flex-direction: column; gap: 6px; margin-bottom: 6px; }\n.level-entity, .level-slots, .level-page { display: flex; flex-direction: column; gap: 8px; }\n.stack-bar { display: flex; align-items: center; gap: 6px; }\n.stack-spacer { flex: 1 1 auto; }\n.stack-back { max-width: 60%; padding-left: 4px; }\n.stack-back-text { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }\n.stack-close { white-space: nowrap; }\n.stack-crumbs ol { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 6px; list-style: none; margin: 0; padding: 0; font-size: var(--text-xs); color: var(--muted-foreground); overflow-wrap: anywhere; }\n.stack-crumbs li { display: inline-flex; align-items: center; }\n.stack-crumb-separator svg { width: 14px; height: 14px; }\n.stack-crumb { border: none; background: none; min-height: 0; padding: 0; font-size: inherit; font-weight: 400; color: var(--muted-foreground); }\n.stack-crumb:hover { background: none; color: var(--foreground); }\n.stack-crumb:active { transform: none; }\n.stack-crumbs [aria-current=\"page\"] { color: var(--foreground); }\n.stack-title { margin: 0; font-size: var(--text-base); font-weight: 600; outline: none; }\n.stack-body { position: relative; flex: 1 1 auto; min-height: 0; overflow-y: auto; overflow-x: hidden; border-top: 1px solid var(--border); padding-top: 8px; }\n.stack-level.leaving { position: absolute; left: 0; right: 0; background: var(--popover); z-index: 1; }\n.stack-row { display: flex; justify-content: flex-start; align-items: center; gap: 8px; width: 100%; text-align: left; margin: 0 0 4px; padding: 8px 10px; background: var(--popover); box-shadow: none; }\n.stack-row-text { display: flex; flex-direction: column; flex: 1 1 auto; min-width: 0; overflow-wrap: anywhere; }\n.stack-row-label { font-weight: 600; }\n.stack-chevron { display: inline-flex; color: var(--muted-foreground); }\n.visually-hidden { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; margin: 0; padding: 0; }\n.tab-panel { flex: 1 1 auto; min-height: 0; display: flex; flex-direction: column; gap: 8px; }\n.tab-panel > .outline-body { flex: 1 1 auto; min-height: 0; }\n.outline-header { display: flex; justify-content: space-between; align-items: center; }\n.outline-body { overflow: auto; display: flex; flex-direction: column; gap: 14px; }\n.section-title { margin: 0; font-size: var(--text-sm); }\n.outline-group { display: flex; flex-direction: column; gap: 4px; margin-top: 8px; }\n.group-heading { display: flex; justify-content: space-between; align-items: center; color: var(--foreground); font-size: var(--text-xs); font-weight: 600; border-bottom: 1px solid var(--border); padding-bottom: 4px; }\n.group-hint { margin: 0; color: var(--muted-foreground); font-size: var(--text-xs); }\n.section-status { margin: 2px 0 0; color: var(--muted-foreground); font-size: var(--text-xs); }\n.status.note { background: var(--secondary); color: var(--secondary-foreground); }\n.outline .row { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 6px; padding: 3px 0; border-bottom: 1px solid var(--border); }\n.row-main { flex: 1 1 auto; display: flex; flex-wrap: wrap; justify-content: flex-start; align-items: baseline; gap: 4px; text-align: left; border: 0; background: none; padding: 2px 6px; font-weight: 400; }\nbutton.row-main { min-height: 0; }\nbutton.row-main:hover { background: var(--accent); }\nbutton.row-main:active, .stack-row:active { transform: none; }\n.row-name { font-weight: 600; }\n.row-name.link { font-weight: 600; }\n.outline .row.current { background: color-mix(in oklab, var(--primary) 8%, var(--popover)); box-shadow: inset 3px 0 0 var(--primary); }\n/* Badges: shadcn/ui's badge, for lifecycle and item states. Secondary unless the state says otherwise. */\n.status, .flag {\n display: inline-flex; align-items: center; gap: 4px; flex-shrink: 0; white-space: nowrap;\n height: 20px; padding: 0 8px; border-radius: 999px; border: 1px solid transparent;\n font: 500 var(--text-xs)/1 var(--font-sans); background: var(--secondary); color: var(--secondary-foreground);\n}\n.status-unpublished-changes, .status-unsaved { background: color-mix(in oklab, var(--warning) 12%, var(--popover)); color: var(--warning); }\n.status-not-in-content, .flag { background: color-mix(in oklab, var(--destructive) 10%, var(--popover)); color: var(--destructive-text); }\n.status-up-to-date { background: transparent; border-color: var(--success); color: var(--success); }\n.history-row { flex-direction: column; align-items: stretch !important; gap: 4px !important; padding: 8px 0 !important; }\n.history-row > .actions { margin-top: -2px; }\n.history-row > .row-main { display: flex; flex-wrap: wrap; align-items: center; gap: 4px; width: 100%; text-align: left; }\n.history-row > .row-main .stack-chevron { margin-left: auto; }\n.version-head { display: flex; flex-wrap: wrap; align-items: center; gap: 4px; margin: 0 0 8px; }\n.version-change { margin-bottom: 8px; }\n.level-confirm .description { margin: 8px 0; }\n.level-confirm > .meta { margin-top: 0; }\n/* A long review keeps Publish in reach: its buttons stay at the bottom of the sidebar. */\n.level-review > .actions { position: sticky; bottom: 0; background: var(--popover); padding: 8px 0 2px; border-top: 1px solid var(--border); }\n.level-schedule { display: flex; flex-direction: column; gap: 8px; }\n.level-schedule .hint { margin: 0; }\n.row > .change { padding-inline: 6px; }\n.change { white-space: pre-wrap; overflow-wrap: anywhere; font-size: var(--text-xs); color: var(--foreground); }\n.change ins { background: color-mix(in oklab, var(--success) 15%, transparent); color: var(--success); text-decoration: underline; }\n.change del { background: color-mix(in oklab, var(--destructive) 12%, transparent); color: var(--destructive); }\n.change .delta { font-weight: 600; padding: 0 3px; border-radius: 3px; }\n/* The arrow glyph sits low in most fonts: centre it on the line. */\n.change .arrow { display: inline-block; vertical-align: middle; line-height: 1; margin: 0 0.35em; }\n.change .delta.up { background: color-mix(in oklab, var(--success) 15%, transparent); color: var(--success); }\n.change .delta.down { background: color-mix(in oklab, var(--destructive) 12%, transparent); color: var(--destructive); }\n.slot-preview { display: flex; align-items: center; gap: 6px; }\n.slot-preview img { width: 56px; height: 40px; object-fit: cover; border-radius: var(--radius-sm); border: 1px solid var(--border); }\n.slot-preview .meta { font-size: 11px; overflow-wrap: anywhere; }\n.extras:empty { display: none; }\n.extras { display: flex; flex-wrap: wrap; justify-content: flex-end; align-items: center; gap: 4px; }\n.extras button { white-space: nowrap; }\n.popover .title { overflow-wrap: anywhere; }\n.reorder-row { align-items: center; }\n.reorder-row.dragging { opacity: 0.5; }\n.handle { display: inline-flex; cursor: grab; color: var(--muted-foreground); padding: 0 2px; }\n.entities:empty { display: none; }\n.entities { display: flex; flex-direction: column; gap: 8px; border-top: 1px solid var(--border); padding-top: 6px; max-height: 50vh; overflow: auto; }\n.entity { display: flex; flex-direction: column; gap: 4px; }\n.entity + .entity { border-top: 1px dashed var(--border); padding-top: 6px; }\n.unsent { color: var(--warning); }\n.lifecycle-status { font-weight: 600; color: var(--foreground); }\n.title { font-weight: 600; }\n.meta { color: var(--muted-foreground); font-weight: 400; }\n/* Buttons wrap whole onto the next line rather than squeezing their labels. */\n.actions { display: flex; flex-wrap: wrap; justify-content: flex-end; gap: 6px; }\n.actions > button { white-space: nowrap; }\n.hint { margin: 0; color: var(--muted-foreground); font-size: var(--text-xs); }\n`;\n\nexport interface EditorHost {\n readonly element: HTMLElement;\n readonly root: ShadowRoot;\n}\n\n/** Creates the host, or returns the existing one if the loader ran twice. */\nexport function createHost(): EditorHost {\n let element = document.getElementById(HOST_ID);\n if (!element) {\n element = document.createElement('div');\n element.id = HOST_ID;\n element.attachShadow({ mode: 'open' });\n document.body.append(element);\n }\n const root = element.shadowRoot!;\n if (!root.querySelector('style')) {\n const style = document.createElement('style');\n style.textContent = STYLES;\n root.append(style);\n }\n return { element, root };\n}\n\n/**\n * A collapsed \"Debug\" section showing an API error body (pretty-printed JSON),\n * inserted as text. Empty when there is nothing to show.\n */\nexport function debugDetails(debug: string | undefined): HTMLElement[] {\n if (!debug) return [];\n const details = el('details', 'debug');\n details.append(el('summary', '', 'Debug'), el('pre', '', debug));\n return [details];\n}\n\n/** shadcn/ui's button variants. Outline is the editor's usual button, so it has no class. */\nexport type ButtonVariant = 'primary' | 'outline' | 'secondary' | 'ghost' | 'destructive' | 'link';\nexport type ButtonSize = 'xs' | 'sm' | 'default' | 'lg' | 'icon' | 'icon-sm' | 'icon-xs';\n\n/** A button (type \"button\", so it never submits a form) with its label as text. */\nexport function button(label: string, variant: ButtonVariant = 'outline', size: ButtonSize = 'default', className = ''): HTMLButtonElement {\n const classes = [className, variant === 'outline' ? '' : variant, size === 'default' ? '' : size].filter(Boolean).join(' ');\n const element = el('button', classes, label);\n element.type = 'button';\n return element;\n}\n\n/** The variant for an action that may be marked primary or destructive. */\nexport function variantOf(action: { primary?: boolean; destructive?: boolean }): ButtonVariant {\n return action.destructive ? 'destructive' : action.primary ? 'primary' : 'outline';\n}\n\n/** A select with shadcn/ui's chevron in place of the browser's arrow. */\nexport function selectBox(select: HTMLSelectElement): HTMLElement {\n const box = el('span', 'select-box');\n box.append(select, icon('chevron-down'));\n return box;\n}\n\n/** Creates an element with a class and optional text, as text. */\nexport function el<K extends keyof HTMLElementTagNameMap>(\n tag: K,\n className = '',\n text = '',\n): HTMLElementTagNameMap[K] {\n const element = document.createElement(tag);\n if (className) element.className = className;\n if (text) element.textContent = text;\n return element;\n}\n", "// The only UI the loader needs: the button that loads the editor. Kept apart\n// from the toolbar so anonymous visitors never download the rest.\n\nimport { el, type EditorHost } from './host.ts';\n\nexport const EDIT_LABEL = 'Edit page';\n\n/** The loader's minimal toolbar: just the button that loads the editor. */\nexport function createLauncher(host: EditorHost): HTMLButtonElement {\n const existing = host.root.querySelector<HTMLButtonElement>('.toolbar button.mode');\n if (existing) return existing;\n const bar = el('div', 'panel toolbar');\n bar.setAttribute('role', 'region');\n bar.setAttribute('aria-label', 'Baack editor');\n const row = el('div', 'toolbar-row');\n const button = el('button', 'mode', EDIT_LABEL);\n button.type = 'button';\n button.setAttribute('aria-pressed', 'false');\n row.append(el('span', 'brand', 'Baack'), button);\n bar.append(row);\n host.root.append(bar);\n return button;\n}\n", "export const Endpoint = Object.freeze({\n ADDRESS: '/n/v1/address/',\n API_CLIENT: '/n/v1/apiclient/',\n BEARER_TOKEN: '/n/v1/bearertoken/',\n BOOLEAN: '/n/v1/booleanitem/',\n BOOLEAN_HISTORY : '/n/v1/booleanitemhistory/',\n CLIENT_CONTEXT : '/n/v1/clientcontext',\n CLIENT_IDENTIFIER: '/n/v1/clientidentifier/',\n COMPANIES: '/n/v1/companies',\n COMPANY: '/n/v1/company/',\n DATE_TIME: '/n/v1/datetimeitem/',\n DATE_TIME_HISTORY: '/n/v1/datetimeitemhistory/',\n DOUBLE: '/n/v1/doubleitem/',\n DOUBLE_HISTORY: '/n/v1/doubleitemhistory/',\n EMAIL: '/n/v1/email/',\n ENTITY: '/n/v1/entity/',\n ENTITY_LIST: '/n/v1/entitylist/',\n ENTITY_VIEW : '/v/v1/entityview/',\n GROUP: '/n/v1/group/',\n GROUP_MEMBERSHIP: '/n/v1/groupmembership/',\n IDENTITY: '/n/v1/identity/',\n IDENTITY_NOTIFICATION_INBOX: '/n/v1/identitynotificationinbox/',\n IMAGE: '/n/v1/imageitem/',\n IMAGE_HISTORY: '/n/v1/imageitemhistory/',\n IMAGE_FILE: '/n/v1/imageitemfile',\n JSON: '/n/v1/jsonitem/',\n JSON_HISTORY: '/n/v1/jsonitemhistory/',\n LAT_LONG: '/n/v1/latlongitem/',\n LAT_LONG_HISTORY: '/n/v1/latlongitemhistory/',\n LINK: '/n/v1/linkitem/',\n LINK_HISTORY: '/n/v1/linkitemhistory/',\n LONG: '/n/v1/longitem/',\n LONG_HISTORY: '/n/v1/longitemhistory/',\n MARKDOWN: '/n/v1/markdownitem/',\n MARKDOWN_HISTORY: '/n/v1/markdownitemhistory/',\n MESSAGE_THREAD: '/n/v1/messagethread/',\n MESSAGE_THREAD_NOTIFICATION: '/n/v1/messagethreadnotification/',\n MONEY: '/n/v1/moneyitem/',\n MONEY_HISTORY: '/n/v1/moneyitemhistory/',\n OAUTH_TOKEN: '/n/v1/oauthtoken/',\n PAYMENT_INVOICE: '/n/v1/paymentinvoice/',\n PERMISSION: '/n/v1/permission/',\n PERSON: '/n/v1/person/',\n PERSON_NAME: '/n/v1/personname/',\n SEARCH : '/n/v1/search/',\n REFERENCE: '/n/v1/referenceitem/',\n /**\n * Not yet released by the API; follows the pattern of the other item\n * history endpoints and may change.\n * @experimental\n */\n REFERENCE_HISTORY: '/n/v1/referenceitemhistory/',\n TASK: '/n/v1/task/',\n TASK_LOG: '/n/v1/tasklog/',\n TASK_LOGS: '/n/v1/tasklogs/',\n TEMPLATE: '/n/v1/templateitem/',\n TEMPLATE_HISTORY: '/n/v1/templateitemhistory/',\n TEXT: '/n/v1/textitem/',\n TEXT_HISTORY: '/n/v1/textitemhistory/',\n THREAD_POST: '/n/v1/threadpost/',\n WEBHOOK_SUBSCRIPTION: '/n/v1/webhooksubscription/',\n WEBHOOK_TRIGGER: '/n/v1/webhooktrigger/',\n WORKFLOW: '/n/v1/workflow/'\n});\n\n\n\n", "import type { ApiError } from './types/index.ts';\n\n/**\n * Thrown for any non-2xx response from the Baack API. Carries the HTTP status\n * so callers can tell an expired session (401) from a missing permission (403),\n * a conflict (409) or a server failure (5xx).\n *\n * Network failures (no response at all) are not wrapped: `fetch` rejects with\n * its own error, typically a `TypeError`.\n */\nexport class BaackApiError extends Error {\n override readonly name = 'BaackApiError';\n\n constructor(\n readonly status: number,\n readonly statusText: string,\n /** The raw response body, which may be a JSON error document or empty. */\n readonly body: string,\n readonly method: string,\n readonly url: string,\n /** The JSON body that was sent, when there was one, for debugging (not multipart uploads). */\n readonly requestBody?: string,\n ) {\n super(`Baack API Error [${status}]: ${body || statusText}`);\n }\n\n get isUnauthorized(): boolean {\n return this.status === 401;\n }\n\n get isForbidden(): boolean {\n return this.status === 403;\n }\n\n get isNotFound(): boolean {\n return this.status === 404;\n }\n\n get isConflict(): boolean {\n return this.status === 409 || this.status === 412;\n }\n\n get isServerError(): boolean {\n return this.status >= 500;\n }\n\n /** The API error object from the body, when there is one. */\n get apiError(): ApiError | undefined {\n const parsed = this.json<ApiError>();\n return parsed !== null && typeof parsed === 'object' ? parsed : undefined;\n }\n\n /** The API's description of the problem, when it gave one. */\n get detail(): string | undefined {\n const detail = this.apiError?.detail;\n return typeof detail === 'string' && detail !== '' ? detail : undefined;\n }\n\n /** The body parsed as JSON, or undefined when it is empty or not JSON. */\n json<T = unknown>(): T | undefined {\n if (!this.body) return undefined;\n try {\n return JSON.parse(this.body) as T;\n } catch {\n return undefined;\n }\n }\n}\n\nexport function isBaackApiError(error: unknown): error is BaackApiError {\n return error instanceof BaackApiError;\n}\n", "import { Endpoint } from './endpoints.ts';\nimport { BaackApiError } from './errors.ts';\nimport type { Search } from './types/index.ts';\n\nexport interface BaackConfig {\n baseUrl: string;\n headers?: Record<string, string>;\n /**\n * Whether the browser sends cookies with each request. Use 'include' for a\n * browser client that relies on the user's Baack session from another\n * origin. Defaults to the fetch default ('same-origin').\n */\n credentials?: 'omit' | 'same-origin' | 'include';\n}\n\n/**\n * The HTTP method behind each of the API's operations, named as the API docs\n * and this client's methods name them: `Method.UPDATE` is `PUT`. Use these\n * rather than HTTP method strings, for example in tests or a proxy allowlist.\n */\nexport const Method = {\n CREATE: 'POST',\n READ: 'GET',\n UPDATE: 'PUT',\n DELETE: 'DELETE',\n} as const;\nexport type Method = (typeof Method)[keyof typeof Method];\n\nexport type QueryParams =Record<string, string | number | boolean | null | undefined>;\n\nexport class BaackClient {\n private baseUrl: string;\n private defaultHeaders: Record<string, string>;\n private credentials: BaackConfig['credentials'];\n\n constructor(config: BaackConfig) {\n this.baseUrl = config.baseUrl.replace(/\\/$/, ''); // Remove trailing slash\n this.defaultHeaders = { ...config.headers };\n this.credentials = config.credentials;\n }\n\n /**\n * Core request handler.\n * Supports both Browser and Node environments via global fetch.\n *\n * Throws BaackApiError for any non-2xx response. Resolves to undefined for\n * an empty response body (for example a 204 from a delete).\n */\n private async request<T>(\n path: string,\n options: RequestInit = {},\n params?: QueryParams\n ): Promise<T> {\n const url = new URL(this.baseUrl + path);\n if (params) {\n Object.entries(params).forEach(([k, v]) => {\n if (v !== undefined && v !== null) {\n url.searchParams.append(k, String(v));\n }\n });\n }\n\n // Only declare a JSON body when there is one: a Content-Type header on a\n // bodiless cross-origin GET forces a CORS preflight.\n const headers: Record<string, string> = typeof options.body === 'string'\n ? { 'Content-Type': 'application/json', ...this.defaultHeaders }\n : { ...this.defaultHeaders };\n\n const init: RequestInit = {\n ...options,\n headers: {\n ...headers,\n ...(options.headers as Record<string, string> | undefined),\n },\n };\n if (this.credentials) {\n init.credentials = this.credentials;\n }\n\n const method = options.method ?? Method.READ;\n const response = await fetch(url.toString(), init);\n const text = await response.text();\n\n if (!response.ok) {\n const sent = typeof init.body === 'string' ? init.body : undefined;\n throw new BaackApiError(response.status, response.statusText, text, method, url.toString(), sent);\n }\n\n return (text ? JSON.parse(text) : undefined) as T;\n }\n\n /**\n * CREATE / POST method for creating resources\n */\n public async create<T>(endpoint: string, body?: unknown): Promise<T> {\n return this.request<T>(endpoint, jsonInit(Method.CREATE, body));\n }\n\n /**\n * READ / GET method for all endpoints. `headers` are added to this request\n * only: a server reading the entity view for a visitor can forward their\n * `Accept-Language`, so the view picks the best available language.\n */\n public async read<T>(endpoint: string, urn: string, params?: QueryParams, headers?: Record<string, string>): Promise<T> {\n return this.request<T>(join(endpoint, urn), { method: Method.READ, ...(headers ? { headers } : {}) }, params);\n }\n\n /**\n * UPDATE / PUT for updating representations\n */\n public async update<T>(endpoint: string, urn: string, body?: unknown): Promise<T> {\n return this.request<T>(join(endpoint, urn), jsonInit(Method.UPDATE, body));\n }\n\n /**\n * DELETE for deleting representations\n */\n public async delete<T = undefined>(endpoint: string, urn: string): Promise<T> {\n return this.request<T>(join(endpoint, urn), {\n method: Method.DELETE,\n });\n }\n\n /**\n * POST a multipart form, for example an image file upload. The browser sets\n * the multipart Content-Type and boundary itself.\n */\n public async upload<T>(endpoint: string, form: FormData): Promise<T> {\n return this.request<T>(endpoint, { method: Method.CREATE, body: form });\n }\n\n /**\n * Starts a search (`owner`, `includeScopes`, optional `order`). The result\n * may be partial (`status` before `FULL_RESULT`): read it again with\n * `searchResult` until it is full, and follow its `pagination`.\n */\n public async search(params: Search): Promise<Search> {\n return this.create<Search>(Endpoint.SEARCH, params);\n }\n\n /** Reads a search's results again by its URN, optionally from a page (`after`). */\n public async searchResult(urn: string, after?: string): Promise<Search> {\n return this.read<Search>(Endpoint.SEARCH, urn, { after });\n }\n}\n\n/**\n * Appends a URN or path to an endpoint. Endpoints end with a slash and paths\n * such as '/home' start with one, so drop the duplicate: the API accepts\n * either, but one slash is the canonical URL.\n */\nfunction join(endpoint: string, urn: string): string {\n return endpoint.endsWith('/') && urn.startsWith('/') ? endpoint + urn.slice(1) : endpoint + urn;\n}\n\nfunction jsonInit(method: Method, body: unknown): RequestInit {\n return body === undefined ? { method } : { method, body: JSON.stringify(body) };\n}\n"],
|
|
5
|
+
"mappings": "AAwDO,SAASA,GAA2B,CACzC,IAAMC,EAAO,SAAS,cAA+B,+BAA+B,GAAG,QACvF,MAAO,CAAE,GAAG,OAAO,kBAAmB,QAAS,OAAO,mBAAmB,SAAWA,GAAQ,sBAAuB,CACrH,CCrDA,IAAMC,EAAQC,GAAqB,CAAC,OAAQ,CAAE,EAAAA,CAAE,CAAC,EAC3CC,EAAM,CAACC,EAAYC,IAAsB,CAAC,SAAU,CAAE,GAAAD,EAAI,GAAAC,EAAI,EAAG,CAAE,CAAC,EAEpEC,EAAQ,CACZ,aAAc,CAACL,EAAK,UAAU,EAAGA,EAAK,gBAAgB,CAAC,EACvD,WAAY,CAACA,EAAK,eAAe,EAAGA,EAAK,UAAU,CAAC,EACpD,MAAO,CAACA,EAAK,iBAAiB,CAAC,EAC/B,eAAgB,CAACA,EAAK,cAAc,CAAC,EACrC,eAAgB,CAACA,EAAK,gBAAgB,CAAC,EACvC,gBAAiB,CAACA,EAAK,eAAe,CAAC,EACvC,SAAU,CAACE,EAAI,GAAI,EAAE,EAAGA,EAAI,GAAI,EAAE,EAAGA,EAAI,EAAG,EAAE,CAAC,EAC/C,gBAAiB,CAACA,EAAI,EAAG,EAAE,EAAGA,EAAI,EAAG,CAAC,EAAGA,EAAI,EAAG,EAAE,EAAGA,EAAI,GAAI,EAAE,EAAGA,EAAI,GAAI,CAAC,EAAGA,EAAI,GAAI,EAAE,CAAC,EACzF,QAAS,CAACF,EAAK,mDAAmD,EAAGA,EAAK,UAAU,EAAGA,EAAK,aAAa,CAAC,EAC1G,eAAgB,CAACA,EAAK,WAAW,EAAGA,EAAK,WAAW,EAAGA,EAAK,UAAU,EAAGA,EAAK,SAAS,EAAGA,EAAK,UAAU,EAAGA,EAAK,gCAAgC,CAAC,EAClJ,aAAc,CAAC,CAAC,OAAQ,CAAE,MAAO,GAAI,OAAQ,GAAI,EAAG,EAAG,EAAG,EAAG,GAAI,CAAE,CAAC,EAAGA,EAAK,SAAS,CAAC,EACtF,cAAe,CAAC,CAAC,OAAQ,CAAE,MAAO,GAAI,OAAQ,GAAI,EAAG,EAAG,EAAG,EAAG,GAAI,CAAE,CAAC,EAAGA,EAAK,UAAU,CAAC,EACxF,cAAe,CAACA,EAAK,UAAU,EAAGA,EAAK,WAAW,EAAGA,EAAK,kIAAkI,CAAC,EAC7L,KAAM,CAACA,EAAK,UAAU,EAAGA,EAAK,UAAU,CAAC,EACzC,OAAQ,CAAC,CAAC,SAAU,CAAE,GAAI,GAAI,GAAI,GAAI,EAAG,CAAE,CAAC,EAAGA,EAAK,gBAAgB,CAAC,EACrE,EAAG,CAACA,EAAK,YAAY,EAAGA,EAAK,YAAY,CAAC,CAC5C,EAIMM,EAAM,6BAGL,SAASC,EAAKC,EAA+B,CAClD,IAAMC,EAAM,SAAS,gBAAgBH,EAAK,KAAK,EAC/C,OAAW,CAACI,EAAWC,CAAK,IAAK,OAAO,QAAQ,CAC9C,QAAS,YACT,MAAO,GACP,OAAQ,GACR,KAAM,OACN,OAAQ,eACR,eAAgB,EAChB,iBAAkB,QAClB,kBAAmB,QACnB,cAAe,OACf,UAAW,QACX,MAAO,aAAaH,CAAI,EAC1B,CAAC,EACCC,EAAI,aAAaC,EAAW,OAAOC,CAAK,CAAC,EAE3C,OAAW,CAACC,EAAKC,CAAU,IAAKR,EAAMG,CAAI,EAAc,CACtD,IAAMM,EAAQ,SAAS,gBAAgBR,EAAKM,CAAG,EAC/C,OAAW,CAACF,EAAWC,CAAK,IAAK,OAAO,QAAQE,CAAU,EAAGC,EAAM,aAAaJ,EAAW,OAAOC,CAAK,CAAC,EACxGF,EAAI,OAAOK,CAAK,CAClB,CACA,OAAOL,CACT,CClDA,IAAMM,EAAQ,CACZ,WAAY,UACZ,WAAY,UACZ,QAAS,UACT,qBAAsB,UACtB,QAAS,UACT,qBAAsB,UACtB,UAAW,UACX,uBAAwB,UACxB,MAAO,UACP,mBAAoB,UACpB,OAAQ,UACR,oBAAqB,UACrB,YAAa,UAEb,mBAAoB,UACpB,OAAQ,UACR,MAAO,UACP,KAAM,UACN,QAAS,UAET,QAAS,UAET,QAAS,UACT,QAAS,mBACT,eAAgB,sBAEhB,qBAAsB,oBACtB,iBAAkB,gBAClB,gBAAiB,eACjB,mBAAoB,cACpB,aAAc,eACd,mBAAoB,oBACpB,kBAAmB,mBACrB,EAEMC,EAAqB,CACzB,WAAY,UACZ,WAAY,UACZ,QAAS,UACT,qBAAsB,UACtB,QAAS,UACT,qBAAsB,UACtB,UAAW,UACX,uBAAwB,UACxB,MAAO,UACP,mBAAoB,UACpB,OAAQ,UACR,oBAAqB,UACrB,YAAa,UACb,mBAAoB,UACpB,OAAQ,UACR,MAAO,UACP,KAAM,UACN,QAAS,UACT,QAAS,UACT,QAAS,UACT,QAAS,oBACT,eAAgB,oBAChB,qBAAsB,qDACtB,iBAAkB,eAClB,gBAAiB,qDACjB,mBAAoB,qDACpB,aAAc,qDACd,mBAAoB,oBACpB,kBAAmB,2BACrB,EAEMC,EAAQ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAoBd,SAASC,EAAOC,EAA2B,CACzC,OAAO,OAAO,QAAQA,CAAG,EACtB,IAAI,CAAC,CAACC,EAAMC,CAAK,IAAM,OAAOD,CAAI,KAAKC,CAAK,GAAG,EAC/C,KAAK;AAAA,CAAI,CACd,CAGO,IAAMC,EAAY;AAAA;AAAA;AAAA,EAGvBJ,EAAOH,CAAK,CAAC;AAAA,EACbE,CAAK;AAAA;AAAA;AAAA;AAAA;AAAA,EAKLC,EAAOF,CAAI,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOZE,EAAOH,CAAK,CAAC;AAAA;AAAA,mDAEoCA,EAAM,UAAU;AAAA,EAOtDQ,EAAe,CAC1B,QAAS,CAACR,EAAM,QAASC,EAAK,OAAO,EACrC,QAAS,CAAC,UAAWA,EAAK,OAAO,EACjC,QAAS,CAAC,UAAWA,EAAK,OAAO,EACjC,QAAS,CAACD,EAAM,QAASC,EAAK,OAAO,EACrC,MAAO,CAAC,UAAW,SAAS,CAC9B,EC9HA,IAAMQ,EAAU,oBAEVC,EAAS,GAAGC,CAAS;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAgTpB,SAASC,GAAyB,CACvC,IA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",
|
|
6
|
+
"names": ["readConfig", "meta", "path", "d", "dot", "cx", "cy", "ICONS", "SVG", "icon", "name", "svg", "attribute", "value", "tag", "attributes", "shape", "LIGHT", "DARK", "SCALE", "tokens", "set", "name", "value", "THEME_CSS", "PAGE_COLOURS", "HOST_ID", "STYLES", "THEME_CSS", "createHost", "element", "root", "style", "debugDetails", "debug", "details", "el", "button", "label", "variant", "size", "className", "classes", "variantOf", "action", "selectBox", "select", "box", "icon", "tag", "text", "EDIT_LABEL", "createLauncher", "host", "existing", "bar", "el", "row", "button", "Endpoint", "BaackApiError", "status", "statusText", "body", "method", "url", "requestBody", "parsed", "detail", "isBaackApiError", "error", "Method", "BaackClient", "config", "path", "options", "params", "url", "k", "v", "headers", "init", "method", "response", "text", "sent", "BaackApiError", "endpoint", "body", "jsonInit", "urn", "join", "form", "Endpoint", "after"]
|
|
7
|
+
}
|