kenobi-js 0.1.30 → 0.1.32

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.
@@ -0,0 +1,3168 @@
1
+ /*!
2
+ * Kenobi SDK v0.1.32
3
+ * (c) 2025 Kenobi.ai
4
+ */
5
+ "use strict";
6
+ var KenobiLib = (() => {
7
+ var __defProp = Object.defineProperty;
8
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
9
+ var __getOwnPropNames = Object.getOwnPropertyNames;
10
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
11
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
12
+ var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
13
+ var __export = (target, all) => {
14
+ for (var name in all)
15
+ __defProp(target, name, { get: all[name], enumerable: true });
16
+ };
17
+ var __copyProps = (to, from, except, desc) => {
18
+ if (from && typeof from === "object" || typeof from === "function") {
19
+ for (let key of __getOwnPropNames(from))
20
+ if (!__hasOwnProp.call(to, key) && key !== except)
21
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
22
+ }
23
+ return to;
24
+ };
25
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
26
+ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
27
+
28
+ // src/index.ts
29
+ var index_exports = {};
30
+ __export(index_exports, {
31
+ CueCard: () => CueCard,
32
+ Kenobi: () => Kenobi,
33
+ TRANSFORMATION_ACTIONS: () => TRANSFORMATION_ACTIONS
34
+ });
35
+
36
+ // ../../node_modules/.pnpm/morphdom@2.7.7/node_modules/morphdom/dist/morphdom-esm.js
37
+ var DOCUMENT_FRAGMENT_NODE = 11;
38
+ function morphAttrs(fromNode, toNode) {
39
+ var toNodeAttrs = toNode.attributes;
40
+ var attr;
41
+ var attrName;
42
+ var attrNamespaceURI;
43
+ var attrValue;
44
+ var fromValue;
45
+ if (toNode.nodeType === DOCUMENT_FRAGMENT_NODE || fromNode.nodeType === DOCUMENT_FRAGMENT_NODE) {
46
+ return;
47
+ }
48
+ for (var i3 = toNodeAttrs.length - 1; i3 >= 0; i3--) {
49
+ attr = toNodeAttrs[i3];
50
+ attrName = attr.name;
51
+ attrNamespaceURI = attr.namespaceURI;
52
+ attrValue = attr.value;
53
+ if (attrNamespaceURI) {
54
+ attrName = attr.localName || attrName;
55
+ fromValue = fromNode.getAttributeNS(attrNamespaceURI, attrName);
56
+ if (fromValue !== attrValue) {
57
+ if (attr.prefix === "xmlns") {
58
+ attrName = attr.name;
59
+ }
60
+ fromNode.setAttributeNS(attrNamespaceURI, attrName, attrValue);
61
+ }
62
+ } else {
63
+ fromValue = fromNode.getAttribute(attrName);
64
+ if (fromValue !== attrValue) {
65
+ fromNode.setAttribute(attrName, attrValue);
66
+ }
67
+ }
68
+ }
69
+ var fromNodeAttrs = fromNode.attributes;
70
+ for (var d3 = fromNodeAttrs.length - 1; d3 >= 0; d3--) {
71
+ attr = fromNodeAttrs[d3];
72
+ attrName = attr.name;
73
+ attrNamespaceURI = attr.namespaceURI;
74
+ if (attrNamespaceURI) {
75
+ attrName = attr.localName || attrName;
76
+ if (!toNode.hasAttributeNS(attrNamespaceURI, attrName)) {
77
+ fromNode.removeAttributeNS(attrNamespaceURI, attrName);
78
+ }
79
+ } else {
80
+ if (!toNode.hasAttribute(attrName)) {
81
+ fromNode.removeAttribute(attrName);
82
+ }
83
+ }
84
+ }
85
+ }
86
+ __name(morphAttrs, "morphAttrs");
87
+ var range;
88
+ var NS_XHTML = "http://www.w3.org/1999/xhtml";
89
+ var doc = typeof document === "undefined" ? void 0 : document;
90
+ var HAS_TEMPLATE_SUPPORT = !!doc && "content" in doc.createElement("template");
91
+ var HAS_RANGE_SUPPORT = !!doc && doc.createRange && "createContextualFragment" in doc.createRange();
92
+ function createFragmentFromTemplate(str) {
93
+ var template = doc.createElement("template");
94
+ template.innerHTML = str;
95
+ return template.content.childNodes[0];
96
+ }
97
+ __name(createFragmentFromTemplate, "createFragmentFromTemplate");
98
+ function createFragmentFromRange(str) {
99
+ if (!range) {
100
+ range = doc.createRange();
101
+ range.selectNode(doc.body);
102
+ }
103
+ var fragment = range.createContextualFragment(str);
104
+ return fragment.childNodes[0];
105
+ }
106
+ __name(createFragmentFromRange, "createFragmentFromRange");
107
+ function createFragmentFromWrap(str) {
108
+ var fragment = doc.createElement("body");
109
+ fragment.innerHTML = str;
110
+ return fragment.childNodes[0];
111
+ }
112
+ __name(createFragmentFromWrap, "createFragmentFromWrap");
113
+ function toElement(str) {
114
+ str = str.trim();
115
+ if (HAS_TEMPLATE_SUPPORT) {
116
+ return createFragmentFromTemplate(str);
117
+ } else if (HAS_RANGE_SUPPORT) {
118
+ return createFragmentFromRange(str);
119
+ }
120
+ return createFragmentFromWrap(str);
121
+ }
122
+ __name(toElement, "toElement");
123
+ function compareNodeNames(fromEl, toEl) {
124
+ var fromNodeName = fromEl.nodeName;
125
+ var toNodeName = toEl.nodeName;
126
+ var fromCodeStart, toCodeStart;
127
+ if (fromNodeName === toNodeName) {
128
+ return true;
129
+ }
130
+ fromCodeStart = fromNodeName.charCodeAt(0);
131
+ toCodeStart = toNodeName.charCodeAt(0);
132
+ if (fromCodeStart <= 90 && toCodeStart >= 97) {
133
+ return fromNodeName === toNodeName.toUpperCase();
134
+ } else if (toCodeStart <= 90 && fromCodeStart >= 97) {
135
+ return toNodeName === fromNodeName.toUpperCase();
136
+ } else {
137
+ return false;
138
+ }
139
+ }
140
+ __name(compareNodeNames, "compareNodeNames");
141
+ function createElementNS(name, namespaceURI) {
142
+ return !namespaceURI || namespaceURI === NS_XHTML ? doc.createElement(name) : doc.createElementNS(namespaceURI, name);
143
+ }
144
+ __name(createElementNS, "createElementNS");
145
+ function moveChildren(fromEl, toEl) {
146
+ var curChild = fromEl.firstChild;
147
+ while (curChild) {
148
+ var nextChild = curChild.nextSibling;
149
+ toEl.appendChild(curChild);
150
+ curChild = nextChild;
151
+ }
152
+ return toEl;
153
+ }
154
+ __name(moveChildren, "moveChildren");
155
+ function syncBooleanAttrProp(fromEl, toEl, name) {
156
+ if (fromEl[name] !== toEl[name]) {
157
+ fromEl[name] = toEl[name];
158
+ if (fromEl[name]) {
159
+ fromEl.setAttribute(name, "");
160
+ } else {
161
+ fromEl.removeAttribute(name);
162
+ }
163
+ }
164
+ }
165
+ __name(syncBooleanAttrProp, "syncBooleanAttrProp");
166
+ var specialElHandlers = {
167
+ OPTION: /* @__PURE__ */ __name(function(fromEl, toEl) {
168
+ var parentNode = fromEl.parentNode;
169
+ if (parentNode) {
170
+ var parentName = parentNode.nodeName.toUpperCase();
171
+ if (parentName === "OPTGROUP") {
172
+ parentNode = parentNode.parentNode;
173
+ parentName = parentNode && parentNode.nodeName.toUpperCase();
174
+ }
175
+ if (parentName === "SELECT" && !parentNode.hasAttribute("multiple")) {
176
+ if (fromEl.hasAttribute("selected") && !toEl.selected) {
177
+ fromEl.setAttribute("selected", "selected");
178
+ fromEl.removeAttribute("selected");
179
+ }
180
+ parentNode.selectedIndex = -1;
181
+ }
182
+ }
183
+ syncBooleanAttrProp(fromEl, toEl, "selected");
184
+ }, "OPTION"),
185
+ /**
186
+ * The "value" attribute is special for the <input> element since it sets
187
+ * the initial value. Changing the "value" attribute without changing the
188
+ * "value" property will have no effect since it is only used to the set the
189
+ * initial value. Similar for the "checked" attribute, and "disabled".
190
+ */
191
+ INPUT: /* @__PURE__ */ __name(function(fromEl, toEl) {
192
+ syncBooleanAttrProp(fromEl, toEl, "checked");
193
+ syncBooleanAttrProp(fromEl, toEl, "disabled");
194
+ if (fromEl.value !== toEl.value) {
195
+ fromEl.value = toEl.value;
196
+ }
197
+ if (!toEl.hasAttribute("value")) {
198
+ fromEl.removeAttribute("value");
199
+ }
200
+ }, "INPUT"),
201
+ TEXTAREA: /* @__PURE__ */ __name(function(fromEl, toEl) {
202
+ var newValue = toEl.value;
203
+ if (fromEl.value !== newValue) {
204
+ fromEl.value = newValue;
205
+ }
206
+ var firstChild = fromEl.firstChild;
207
+ if (firstChild) {
208
+ var oldValue = firstChild.nodeValue;
209
+ if (oldValue == newValue || !newValue && oldValue == fromEl.placeholder) {
210
+ return;
211
+ }
212
+ firstChild.nodeValue = newValue;
213
+ }
214
+ }, "TEXTAREA"),
215
+ SELECT: /* @__PURE__ */ __name(function(fromEl, toEl) {
216
+ if (!toEl.hasAttribute("multiple")) {
217
+ var selectedIndex = -1;
218
+ var i3 = 0;
219
+ var curChild = fromEl.firstChild;
220
+ var optgroup;
221
+ var nodeName;
222
+ while (curChild) {
223
+ nodeName = curChild.nodeName && curChild.nodeName.toUpperCase();
224
+ if (nodeName === "OPTGROUP") {
225
+ optgroup = curChild;
226
+ curChild = optgroup.firstChild;
227
+ if (!curChild) {
228
+ curChild = optgroup.nextSibling;
229
+ optgroup = null;
230
+ }
231
+ } else {
232
+ if (nodeName === "OPTION") {
233
+ if (curChild.hasAttribute("selected")) {
234
+ selectedIndex = i3;
235
+ break;
236
+ }
237
+ i3++;
238
+ }
239
+ curChild = curChild.nextSibling;
240
+ if (!curChild && optgroup) {
241
+ curChild = optgroup.nextSibling;
242
+ optgroup = null;
243
+ }
244
+ }
245
+ }
246
+ fromEl.selectedIndex = selectedIndex;
247
+ }
248
+ }, "SELECT")
249
+ };
250
+ var ELEMENT_NODE = 1;
251
+ var DOCUMENT_FRAGMENT_NODE$1 = 11;
252
+ var TEXT_NODE = 3;
253
+ var COMMENT_NODE = 8;
254
+ function noop() {
255
+ }
256
+ __name(noop, "noop");
257
+ function defaultGetNodeKey(node) {
258
+ if (node) {
259
+ return node.getAttribute && node.getAttribute("id") || node.id;
260
+ }
261
+ }
262
+ __name(defaultGetNodeKey, "defaultGetNodeKey");
263
+ function morphdomFactory(morphAttrs2) {
264
+ return /* @__PURE__ */ __name(function morphdom2(fromNode, toNode, options) {
265
+ if (!options) {
266
+ options = {};
267
+ }
268
+ if (typeof toNode === "string") {
269
+ if (fromNode.nodeName === "#document" || fromNode.nodeName === "HTML" || fromNode.nodeName === "BODY") {
270
+ var toNodeHtml = toNode;
271
+ toNode = doc.createElement("html");
272
+ toNode.innerHTML = toNodeHtml;
273
+ } else {
274
+ toNode = toElement(toNode);
275
+ }
276
+ } else if (toNode.nodeType === DOCUMENT_FRAGMENT_NODE$1) {
277
+ toNode = toNode.firstElementChild;
278
+ }
279
+ var getNodeKey = options.getNodeKey || defaultGetNodeKey;
280
+ var onBeforeNodeAdded = options.onBeforeNodeAdded || noop;
281
+ var onNodeAdded = options.onNodeAdded || noop;
282
+ var onBeforeElUpdated = options.onBeforeElUpdated || noop;
283
+ var onElUpdated = options.onElUpdated || noop;
284
+ var onBeforeNodeDiscarded = options.onBeforeNodeDiscarded || noop;
285
+ var onNodeDiscarded = options.onNodeDiscarded || noop;
286
+ var onBeforeElChildrenUpdated = options.onBeforeElChildrenUpdated || noop;
287
+ var skipFromChildren = options.skipFromChildren || noop;
288
+ var addChild = options.addChild || function(parent, child) {
289
+ return parent.appendChild(child);
290
+ };
291
+ var childrenOnly = options.childrenOnly === true;
292
+ var fromNodesLookup = /* @__PURE__ */ Object.create(null);
293
+ var keyedRemovalList = [];
294
+ function addKeyedRemoval(key) {
295
+ keyedRemovalList.push(key);
296
+ }
297
+ __name(addKeyedRemoval, "addKeyedRemoval");
298
+ function walkDiscardedChildNodes(node, skipKeyedNodes) {
299
+ if (node.nodeType === ELEMENT_NODE) {
300
+ var curChild = node.firstChild;
301
+ while (curChild) {
302
+ var key = void 0;
303
+ if (skipKeyedNodes && (key = getNodeKey(curChild))) {
304
+ addKeyedRemoval(key);
305
+ } else {
306
+ onNodeDiscarded(curChild);
307
+ if (curChild.firstChild) {
308
+ walkDiscardedChildNodes(curChild, skipKeyedNodes);
309
+ }
310
+ }
311
+ curChild = curChild.nextSibling;
312
+ }
313
+ }
314
+ }
315
+ __name(walkDiscardedChildNodes, "walkDiscardedChildNodes");
316
+ function removeNode(node, parentNode, skipKeyedNodes) {
317
+ if (onBeforeNodeDiscarded(node) === false) {
318
+ return;
319
+ }
320
+ if (parentNode) {
321
+ parentNode.removeChild(node);
322
+ }
323
+ onNodeDiscarded(node);
324
+ walkDiscardedChildNodes(node, skipKeyedNodes);
325
+ }
326
+ __name(removeNode, "removeNode");
327
+ function indexTree(node) {
328
+ if (node.nodeType === ELEMENT_NODE || node.nodeType === DOCUMENT_FRAGMENT_NODE$1) {
329
+ var curChild = node.firstChild;
330
+ while (curChild) {
331
+ var key = getNodeKey(curChild);
332
+ if (key) {
333
+ fromNodesLookup[key] = curChild;
334
+ }
335
+ indexTree(curChild);
336
+ curChild = curChild.nextSibling;
337
+ }
338
+ }
339
+ }
340
+ __name(indexTree, "indexTree");
341
+ indexTree(fromNode);
342
+ function handleNodeAdded(el) {
343
+ onNodeAdded(el);
344
+ var curChild = el.firstChild;
345
+ while (curChild) {
346
+ var nextSibling = curChild.nextSibling;
347
+ var key = getNodeKey(curChild);
348
+ if (key) {
349
+ var unmatchedFromEl = fromNodesLookup[key];
350
+ if (unmatchedFromEl && compareNodeNames(curChild, unmatchedFromEl)) {
351
+ curChild.parentNode.replaceChild(unmatchedFromEl, curChild);
352
+ morphEl(unmatchedFromEl, curChild);
353
+ } else {
354
+ handleNodeAdded(curChild);
355
+ }
356
+ } else {
357
+ handleNodeAdded(curChild);
358
+ }
359
+ curChild = nextSibling;
360
+ }
361
+ }
362
+ __name(handleNodeAdded, "handleNodeAdded");
363
+ function cleanupFromEl(fromEl, curFromNodeChild, curFromNodeKey) {
364
+ while (curFromNodeChild) {
365
+ var fromNextSibling = curFromNodeChild.nextSibling;
366
+ if (curFromNodeKey = getNodeKey(curFromNodeChild)) {
367
+ addKeyedRemoval(curFromNodeKey);
368
+ } else {
369
+ removeNode(
370
+ curFromNodeChild,
371
+ fromEl,
372
+ true
373
+ /* skip keyed nodes */
374
+ );
375
+ }
376
+ curFromNodeChild = fromNextSibling;
377
+ }
378
+ }
379
+ __name(cleanupFromEl, "cleanupFromEl");
380
+ function morphEl(fromEl, toEl, childrenOnly2) {
381
+ var toElKey = getNodeKey(toEl);
382
+ if (toElKey) {
383
+ delete fromNodesLookup[toElKey];
384
+ }
385
+ if (!childrenOnly2) {
386
+ var beforeUpdateResult = onBeforeElUpdated(fromEl, toEl);
387
+ if (beforeUpdateResult === false) {
388
+ return;
389
+ } else if (beforeUpdateResult instanceof HTMLElement) {
390
+ fromEl = beforeUpdateResult;
391
+ indexTree(fromEl);
392
+ }
393
+ morphAttrs2(fromEl, toEl);
394
+ onElUpdated(fromEl);
395
+ if (onBeforeElChildrenUpdated(fromEl, toEl) === false) {
396
+ return;
397
+ }
398
+ }
399
+ if (fromEl.nodeName !== "TEXTAREA") {
400
+ morphChildren(fromEl, toEl);
401
+ } else {
402
+ specialElHandlers.TEXTAREA(fromEl, toEl);
403
+ }
404
+ }
405
+ __name(morphEl, "morphEl");
406
+ function morphChildren(fromEl, toEl) {
407
+ var skipFrom = skipFromChildren(fromEl, toEl);
408
+ var curToNodeChild = toEl.firstChild;
409
+ var curFromNodeChild = fromEl.firstChild;
410
+ var curToNodeKey;
411
+ var curFromNodeKey;
412
+ var fromNextSibling;
413
+ var toNextSibling;
414
+ var matchingFromEl;
415
+ outer: while (curToNodeChild) {
416
+ toNextSibling = curToNodeChild.nextSibling;
417
+ curToNodeKey = getNodeKey(curToNodeChild);
418
+ while (!skipFrom && curFromNodeChild) {
419
+ fromNextSibling = curFromNodeChild.nextSibling;
420
+ if (curToNodeChild.isSameNode && curToNodeChild.isSameNode(curFromNodeChild)) {
421
+ curToNodeChild = toNextSibling;
422
+ curFromNodeChild = fromNextSibling;
423
+ continue outer;
424
+ }
425
+ curFromNodeKey = getNodeKey(curFromNodeChild);
426
+ var curFromNodeType = curFromNodeChild.nodeType;
427
+ var isCompatible = void 0;
428
+ if (curFromNodeType === curToNodeChild.nodeType) {
429
+ if (curFromNodeType === ELEMENT_NODE) {
430
+ if (curToNodeKey) {
431
+ if (curToNodeKey !== curFromNodeKey) {
432
+ if (matchingFromEl = fromNodesLookup[curToNodeKey]) {
433
+ if (fromNextSibling === matchingFromEl) {
434
+ isCompatible = false;
435
+ } else {
436
+ fromEl.insertBefore(matchingFromEl, curFromNodeChild);
437
+ if (curFromNodeKey) {
438
+ addKeyedRemoval(curFromNodeKey);
439
+ } else {
440
+ removeNode(
441
+ curFromNodeChild,
442
+ fromEl,
443
+ true
444
+ /* skip keyed nodes */
445
+ );
446
+ }
447
+ curFromNodeChild = matchingFromEl;
448
+ curFromNodeKey = getNodeKey(curFromNodeChild);
449
+ }
450
+ } else {
451
+ isCompatible = false;
452
+ }
453
+ }
454
+ } else if (curFromNodeKey) {
455
+ isCompatible = false;
456
+ }
457
+ isCompatible = isCompatible !== false && compareNodeNames(curFromNodeChild, curToNodeChild);
458
+ if (isCompatible) {
459
+ morphEl(curFromNodeChild, curToNodeChild);
460
+ }
461
+ } else if (curFromNodeType === TEXT_NODE || curFromNodeType == COMMENT_NODE) {
462
+ isCompatible = true;
463
+ if (curFromNodeChild.nodeValue !== curToNodeChild.nodeValue) {
464
+ curFromNodeChild.nodeValue = curToNodeChild.nodeValue;
465
+ }
466
+ }
467
+ }
468
+ if (isCompatible) {
469
+ curToNodeChild = toNextSibling;
470
+ curFromNodeChild = fromNextSibling;
471
+ continue outer;
472
+ }
473
+ if (curFromNodeKey) {
474
+ addKeyedRemoval(curFromNodeKey);
475
+ } else {
476
+ removeNode(
477
+ curFromNodeChild,
478
+ fromEl,
479
+ true
480
+ /* skip keyed nodes */
481
+ );
482
+ }
483
+ curFromNodeChild = fromNextSibling;
484
+ }
485
+ if (curToNodeKey && (matchingFromEl = fromNodesLookup[curToNodeKey]) && compareNodeNames(matchingFromEl, curToNodeChild)) {
486
+ if (!skipFrom) {
487
+ addChild(fromEl, matchingFromEl);
488
+ }
489
+ morphEl(matchingFromEl, curToNodeChild);
490
+ } else {
491
+ var onBeforeNodeAddedResult = onBeforeNodeAdded(curToNodeChild);
492
+ if (onBeforeNodeAddedResult !== false) {
493
+ if (onBeforeNodeAddedResult) {
494
+ curToNodeChild = onBeforeNodeAddedResult;
495
+ }
496
+ if (curToNodeChild.actualize) {
497
+ curToNodeChild = curToNodeChild.actualize(fromEl.ownerDocument || doc);
498
+ }
499
+ addChild(fromEl, curToNodeChild);
500
+ handleNodeAdded(curToNodeChild);
501
+ }
502
+ }
503
+ curToNodeChild = toNextSibling;
504
+ curFromNodeChild = fromNextSibling;
505
+ }
506
+ cleanupFromEl(fromEl, curFromNodeChild, curFromNodeKey);
507
+ var specialElHandler = specialElHandlers[fromEl.nodeName];
508
+ if (specialElHandler) {
509
+ specialElHandler(fromEl, toEl);
510
+ }
511
+ }
512
+ __name(morphChildren, "morphChildren");
513
+ var morphedNode = fromNode;
514
+ var morphedNodeType = morphedNode.nodeType;
515
+ var toNodeType = toNode.nodeType;
516
+ if (!childrenOnly) {
517
+ if (morphedNodeType === ELEMENT_NODE) {
518
+ if (toNodeType === ELEMENT_NODE) {
519
+ if (!compareNodeNames(fromNode, toNode)) {
520
+ onNodeDiscarded(fromNode);
521
+ morphedNode = moveChildren(fromNode, createElementNS(toNode.nodeName, toNode.namespaceURI));
522
+ }
523
+ } else {
524
+ morphedNode = toNode;
525
+ }
526
+ } else if (morphedNodeType === TEXT_NODE || morphedNodeType === COMMENT_NODE) {
527
+ if (toNodeType === morphedNodeType) {
528
+ if (morphedNode.nodeValue !== toNode.nodeValue) {
529
+ morphedNode.nodeValue = toNode.nodeValue;
530
+ }
531
+ return morphedNode;
532
+ } else {
533
+ morphedNode = toNode;
534
+ }
535
+ }
536
+ }
537
+ if (morphedNode === toNode) {
538
+ onNodeDiscarded(fromNode);
539
+ } else {
540
+ if (toNode.isSameNode && toNode.isSameNode(morphedNode)) {
541
+ return;
542
+ }
543
+ morphEl(morphedNode, toNode, childrenOnly);
544
+ if (keyedRemovalList) {
545
+ for (var i3 = 0, len = keyedRemovalList.length; i3 < len; i3++) {
546
+ var elToRemove = fromNodesLookup[keyedRemovalList[i3]];
547
+ if (elToRemove) {
548
+ removeNode(elToRemove, elToRemove.parentNode, false);
549
+ }
550
+ }
551
+ }
552
+ }
553
+ if (!childrenOnly && morphedNode !== fromNode && fromNode.parentNode) {
554
+ if (morphedNode.actualize) {
555
+ morphedNode = morphedNode.actualize(fromNode.ownerDocument || doc);
556
+ }
557
+ fromNode.parentNode.replaceChild(morphedNode, fromNode);
558
+ }
559
+ return morphedNode;
560
+ }, "morphdom");
561
+ }
562
+ __name(morphdomFactory, "morphdomFactory");
563
+ var morphdom = morphdomFactory(morphAttrs);
564
+ var morphdom_esm_default = morphdom;
565
+
566
+ // ../../node_modules/.pnpm/preact@10.27.2/node_modules/preact/dist/preact.module.js
567
+ var n;
568
+ var l;
569
+ var u;
570
+ var t;
571
+ var i;
572
+ var r;
573
+ var o;
574
+ var e;
575
+ var f;
576
+ var c;
577
+ var s;
578
+ var a;
579
+ var h;
580
+ var p = {};
581
+ var v = [];
582
+ var y = /acit|ex(?:s|g|n|p|$)|rph|grid|ows|mnc|ntw|ine[ch]|zoo|^ord|itera/i;
583
+ var w = Array.isArray;
584
+ function d(n2, l3) {
585
+ for (var u4 in l3) n2[u4] = l3[u4];
586
+ return n2;
587
+ }
588
+ __name(d, "d");
589
+ function g(n2) {
590
+ n2 && n2.parentNode && n2.parentNode.removeChild(n2);
591
+ }
592
+ __name(g, "g");
593
+ function _(l3, u4, t3) {
594
+ var i3, r3, o3, e3 = {};
595
+ for (o3 in u4) "key" == o3 ? i3 = u4[o3] : "ref" == o3 ? r3 = u4[o3] : e3[o3] = u4[o3];
596
+ if (arguments.length > 2 && (e3.children = arguments.length > 3 ? n.call(arguments, 2) : t3), "function" == typeof l3 && null != l3.defaultProps) for (o3 in l3.defaultProps) void 0 === e3[o3] && (e3[o3] = l3.defaultProps[o3]);
597
+ return m(l3, e3, i3, r3, null);
598
+ }
599
+ __name(_, "_");
600
+ function m(n2, t3, i3, r3, o3) {
601
+ var e3 = { type: n2, props: t3, key: i3, ref: r3, __k: null, __: null, __b: 0, __e: null, __c: null, constructor: void 0, __v: null == o3 ? ++u : o3, __i: -1, __u: 0 };
602
+ return null == o3 && null != l.vnode && l.vnode(e3), e3;
603
+ }
604
+ __name(m, "m");
605
+ function k(n2) {
606
+ return n2.children;
607
+ }
608
+ __name(k, "k");
609
+ function x(n2, l3) {
610
+ this.props = n2, this.context = l3;
611
+ }
612
+ __name(x, "x");
613
+ function S(n2, l3) {
614
+ if (null == l3) return n2.__ ? S(n2.__, n2.__i + 1) : null;
615
+ for (var u4; l3 < n2.__k.length; l3++) if (null != (u4 = n2.__k[l3]) && null != u4.__e) return u4.__e;
616
+ return "function" == typeof n2.type ? S(n2) : null;
617
+ }
618
+ __name(S, "S");
619
+ function C(n2) {
620
+ var l3, u4;
621
+ if (null != (n2 = n2.__) && null != n2.__c) {
622
+ for (n2.__e = n2.__c.base = null, l3 = 0; l3 < n2.__k.length; l3++) if (null != (u4 = n2.__k[l3]) && null != u4.__e) {
623
+ n2.__e = n2.__c.base = u4.__e;
624
+ break;
625
+ }
626
+ return C(n2);
627
+ }
628
+ }
629
+ __name(C, "C");
630
+ function M(n2) {
631
+ (!n2.__d && (n2.__d = true) && i.push(n2) && !$.__r++ || r != l.debounceRendering) && ((r = l.debounceRendering) || o)($);
632
+ }
633
+ __name(M, "M");
634
+ function $() {
635
+ for (var n2, u4, t3, r3, o3, f4, c3, s3 = 1; i.length; ) i.length > s3 && i.sort(e), n2 = i.shift(), s3 = i.length, n2.__d && (t3 = void 0, r3 = void 0, o3 = (r3 = (u4 = n2).__v).__e, f4 = [], c3 = [], u4.__P && ((t3 = d({}, r3)).__v = r3.__v + 1, l.vnode && l.vnode(t3), O(u4.__P, t3, r3, u4.__n, u4.__P.namespaceURI, 32 & r3.__u ? [o3] : null, f4, null == o3 ? S(r3) : o3, !!(32 & r3.__u), c3), t3.__v = r3.__v, t3.__.__k[t3.__i] = t3, N(f4, t3, c3), r3.__e = r3.__ = null, t3.__e != o3 && C(t3)));
636
+ $.__r = 0;
637
+ }
638
+ __name($, "$");
639
+ function I(n2, l3, u4, t3, i3, r3, o3, e3, f4, c3, s3) {
640
+ var a3, h3, y3, w3, d3, g2, _2, m3 = t3 && t3.__k || v, b = l3.length;
641
+ for (f4 = P(u4, l3, m3, f4, b), a3 = 0; a3 < b; a3++) null != (y3 = u4.__k[a3]) && (h3 = -1 == y3.__i ? p : m3[y3.__i] || p, y3.__i = a3, g2 = O(n2, y3, h3, i3, r3, o3, e3, f4, c3, s3), w3 = y3.__e, y3.ref && h3.ref != y3.ref && (h3.ref && B(h3.ref, null, y3), s3.push(y3.ref, y3.__c || w3, y3)), null == d3 && null != w3 && (d3 = w3), (_2 = !!(4 & y3.__u)) || h3.__k === y3.__k ? f4 = A(y3, f4, n2, _2) : "function" == typeof y3.type && void 0 !== g2 ? f4 = g2 : w3 && (f4 = w3.nextSibling), y3.__u &= -7);
642
+ return u4.__e = d3, f4;
643
+ }
644
+ __name(I, "I");
645
+ function P(n2, l3, u4, t3, i3) {
646
+ var r3, o3, e3, f4, c3, s3 = u4.length, a3 = s3, h3 = 0;
647
+ for (n2.__k = new Array(i3), r3 = 0; r3 < i3; r3++) null != (o3 = l3[r3]) && "boolean" != typeof o3 && "function" != typeof o3 ? (f4 = r3 + h3, (o3 = n2.__k[r3] = "string" == typeof o3 || "number" == typeof o3 || "bigint" == typeof o3 || o3.constructor == String ? m(null, o3, null, null, null) : w(o3) ? m(k, { children: o3 }, null, null, null) : null == o3.constructor && o3.__b > 0 ? m(o3.type, o3.props, o3.key, o3.ref ? o3.ref : null, o3.__v) : o3).__ = n2, o3.__b = n2.__b + 1, e3 = null, -1 != (c3 = o3.__i = L(o3, u4, f4, a3)) && (a3--, (e3 = u4[c3]) && (e3.__u |= 2)), null == e3 || null == e3.__v ? (-1 == c3 && (i3 > s3 ? h3-- : i3 < s3 && h3++), "function" != typeof o3.type && (o3.__u |= 4)) : c3 != f4 && (c3 == f4 - 1 ? h3-- : c3 == f4 + 1 ? h3++ : (c3 > f4 ? h3-- : h3++, o3.__u |= 4))) : n2.__k[r3] = null;
648
+ if (a3) for (r3 = 0; r3 < s3; r3++) null != (e3 = u4[r3]) && 0 == (2 & e3.__u) && (e3.__e == t3 && (t3 = S(e3)), D(e3, e3));
649
+ return t3;
650
+ }
651
+ __name(P, "P");
652
+ function A(n2, l3, u4, t3) {
653
+ var i3, r3;
654
+ if ("function" == typeof n2.type) {
655
+ for (i3 = n2.__k, r3 = 0; i3 && r3 < i3.length; r3++) i3[r3] && (i3[r3].__ = n2, l3 = A(i3[r3], l3, u4, t3));
656
+ return l3;
657
+ }
658
+ n2.__e != l3 && (t3 && (l3 && n2.type && !l3.parentNode && (l3 = S(n2)), u4.insertBefore(n2.__e, l3 || null)), l3 = n2.__e);
659
+ do {
660
+ l3 = l3 && l3.nextSibling;
661
+ } while (null != l3 && 8 == l3.nodeType);
662
+ return l3;
663
+ }
664
+ __name(A, "A");
665
+ function L(n2, l3, u4, t3) {
666
+ var i3, r3, o3, e3 = n2.key, f4 = n2.type, c3 = l3[u4], s3 = null != c3 && 0 == (2 & c3.__u);
667
+ if (null === c3 && null == n2.key || s3 && e3 == c3.key && f4 == c3.type) return u4;
668
+ if (t3 > (s3 ? 1 : 0)) {
669
+ for (i3 = u4 - 1, r3 = u4 + 1; i3 >= 0 || r3 < l3.length; ) if (null != (c3 = l3[o3 = i3 >= 0 ? i3-- : r3++]) && 0 == (2 & c3.__u) && e3 == c3.key && f4 == c3.type) return o3;
670
+ }
671
+ return -1;
672
+ }
673
+ __name(L, "L");
674
+ function T(n2, l3, u4) {
675
+ "-" == l3[0] ? n2.setProperty(l3, null == u4 ? "" : u4) : n2[l3] = null == u4 ? "" : "number" != typeof u4 || y.test(l3) ? u4 : u4 + "px";
676
+ }
677
+ __name(T, "T");
678
+ function j(n2, l3, u4, t3, i3) {
679
+ var r3, o3;
680
+ n: if ("style" == l3) if ("string" == typeof u4) n2.style.cssText = u4;
681
+ else {
682
+ if ("string" == typeof t3 && (n2.style.cssText = t3 = ""), t3) for (l3 in t3) u4 && l3 in u4 || T(n2.style, l3, "");
683
+ if (u4) for (l3 in u4) t3 && u4[l3] == t3[l3] || T(n2.style, l3, u4[l3]);
684
+ }
685
+ else if ("o" == l3[0] && "n" == l3[1]) r3 = l3 != (l3 = l3.replace(f, "$1")), o3 = l3.toLowerCase(), l3 = o3 in n2 || "onFocusOut" == l3 || "onFocusIn" == l3 ? o3.slice(2) : l3.slice(2), n2.l || (n2.l = {}), n2.l[l3 + r3] = u4, u4 ? t3 ? u4.u = t3.u : (u4.u = c, n2.addEventListener(l3, r3 ? a : s, r3)) : n2.removeEventListener(l3, r3 ? a : s, r3);
686
+ else {
687
+ if ("http://www.w3.org/2000/svg" == i3) l3 = l3.replace(/xlink(H|:h)/, "h").replace(/sName$/, "s");
688
+ else if ("width" != l3 && "height" != l3 && "href" != l3 && "list" != l3 && "form" != l3 && "tabIndex" != l3 && "download" != l3 && "rowSpan" != l3 && "colSpan" != l3 && "role" != l3 && "popover" != l3 && l3 in n2) try {
689
+ n2[l3] = null == u4 ? "" : u4;
690
+ break n;
691
+ } catch (n3) {
692
+ }
693
+ "function" == typeof u4 || (null == u4 || false === u4 && "-" != l3[4] ? n2.removeAttribute(l3) : n2.setAttribute(l3, "popover" == l3 && 1 == u4 ? "" : u4));
694
+ }
695
+ }
696
+ __name(j, "j");
697
+ function F(n2) {
698
+ return function(u4) {
699
+ if (this.l) {
700
+ var t3 = this.l[u4.type + n2];
701
+ if (null == u4.t) u4.t = c++;
702
+ else if (u4.t < t3.u) return;
703
+ return t3(l.event ? l.event(u4) : u4);
704
+ }
705
+ };
706
+ }
707
+ __name(F, "F");
708
+ function O(n2, u4, t3, i3, r3, o3, e3, f4, c3, s3) {
709
+ var a3, h3, p3, v3, y3, _2, m3, b, S2, C3, M2, $2, P2, A3, H, L2, T3, j3 = u4.type;
710
+ if (null != u4.constructor) return null;
711
+ 128 & t3.__u && (c3 = !!(32 & t3.__u), o3 = [f4 = u4.__e = t3.__e]), (a3 = l.__b) && a3(u4);
712
+ n: if ("function" == typeof j3) try {
713
+ if (b = u4.props, S2 = "prototype" in j3 && j3.prototype.render, C3 = (a3 = j3.contextType) && i3[a3.__c], M2 = a3 ? C3 ? C3.props.value : a3.__ : i3, t3.__c ? m3 = (h3 = u4.__c = t3.__c).__ = h3.__E : (S2 ? u4.__c = h3 = new j3(b, M2) : (u4.__c = h3 = new x(b, M2), h3.constructor = j3, h3.render = E), C3 && C3.sub(h3), h3.props = b, h3.state || (h3.state = {}), h3.context = M2, h3.__n = i3, p3 = h3.__d = true, h3.__h = [], h3._sb = []), S2 && null == h3.__s && (h3.__s = h3.state), S2 && null != j3.getDerivedStateFromProps && (h3.__s == h3.state && (h3.__s = d({}, h3.__s)), d(h3.__s, j3.getDerivedStateFromProps(b, h3.__s))), v3 = h3.props, y3 = h3.state, h3.__v = u4, p3) S2 && null == j3.getDerivedStateFromProps && null != h3.componentWillMount && h3.componentWillMount(), S2 && null != h3.componentDidMount && h3.__h.push(h3.componentDidMount);
714
+ else {
715
+ if (S2 && null == j3.getDerivedStateFromProps && b !== v3 && null != h3.componentWillReceiveProps && h3.componentWillReceiveProps(b, M2), !h3.__e && null != h3.shouldComponentUpdate && false === h3.shouldComponentUpdate(b, h3.__s, M2) || u4.__v == t3.__v) {
716
+ for (u4.__v != t3.__v && (h3.props = b, h3.state = h3.__s, h3.__d = false), u4.__e = t3.__e, u4.__k = t3.__k, u4.__k.some(function(n3) {
717
+ n3 && (n3.__ = u4);
718
+ }), $2 = 0; $2 < h3._sb.length; $2++) h3.__h.push(h3._sb[$2]);
719
+ h3._sb = [], h3.__h.length && e3.push(h3);
720
+ break n;
721
+ }
722
+ null != h3.componentWillUpdate && h3.componentWillUpdate(b, h3.__s, M2), S2 && null != h3.componentDidUpdate && h3.__h.push(function() {
723
+ h3.componentDidUpdate(v3, y3, _2);
724
+ });
725
+ }
726
+ if (h3.context = M2, h3.props = b, h3.__P = n2, h3.__e = false, P2 = l.__r, A3 = 0, S2) {
727
+ for (h3.state = h3.__s, h3.__d = false, P2 && P2(u4), a3 = h3.render(h3.props, h3.state, h3.context), H = 0; H < h3._sb.length; H++) h3.__h.push(h3._sb[H]);
728
+ h3._sb = [];
729
+ } else do {
730
+ h3.__d = false, P2 && P2(u4), a3 = h3.render(h3.props, h3.state, h3.context), h3.state = h3.__s;
731
+ } while (h3.__d && ++A3 < 25);
732
+ h3.state = h3.__s, null != h3.getChildContext && (i3 = d(d({}, i3), h3.getChildContext())), S2 && !p3 && null != h3.getSnapshotBeforeUpdate && (_2 = h3.getSnapshotBeforeUpdate(v3, y3)), L2 = a3, null != a3 && a3.type === k && null == a3.key && (L2 = V(a3.props.children)), f4 = I(n2, w(L2) ? L2 : [L2], u4, t3, i3, r3, o3, e3, f4, c3, s3), h3.base = u4.__e, u4.__u &= -161, h3.__h.length && e3.push(h3), m3 && (h3.__E = h3.__ = null);
733
+ } catch (n3) {
734
+ if (u4.__v = null, c3 || null != o3) if (n3.then) {
735
+ for (u4.__u |= c3 ? 160 : 128; f4 && 8 == f4.nodeType && f4.nextSibling; ) f4 = f4.nextSibling;
736
+ o3[o3.indexOf(f4)] = null, u4.__e = f4;
737
+ } else {
738
+ for (T3 = o3.length; T3--; ) g(o3[T3]);
739
+ z(u4);
740
+ }
741
+ else u4.__e = t3.__e, u4.__k = t3.__k, n3.then || z(u4);
742
+ l.__e(n3, u4, t3);
743
+ }
744
+ else null == o3 && u4.__v == t3.__v ? (u4.__k = t3.__k, u4.__e = t3.__e) : f4 = u4.__e = q(t3.__e, u4, t3, i3, r3, o3, e3, c3, s3);
745
+ return (a3 = l.diffed) && a3(u4), 128 & u4.__u ? void 0 : f4;
746
+ }
747
+ __name(O, "O");
748
+ function z(n2) {
749
+ n2 && n2.__c && (n2.__c.__e = true), n2 && n2.__k && n2.__k.forEach(z);
750
+ }
751
+ __name(z, "z");
752
+ function N(n2, u4, t3) {
753
+ for (var i3 = 0; i3 < t3.length; i3++) B(t3[i3], t3[++i3], t3[++i3]);
754
+ l.__c && l.__c(u4, n2), n2.some(function(u5) {
755
+ try {
756
+ n2 = u5.__h, u5.__h = [], n2.some(function(n3) {
757
+ n3.call(u5);
758
+ });
759
+ } catch (n3) {
760
+ l.__e(n3, u5.__v);
761
+ }
762
+ });
763
+ }
764
+ __name(N, "N");
765
+ function V(n2) {
766
+ return "object" != typeof n2 || null == n2 || n2.__b && n2.__b > 0 ? n2 : w(n2) ? n2.map(V) : d({}, n2);
767
+ }
768
+ __name(V, "V");
769
+ function q(u4, t3, i3, r3, o3, e3, f4, c3, s3) {
770
+ var a3, h3, v3, y3, d3, _2, m3, b = i3.props, k3 = t3.props, x2 = t3.type;
771
+ if ("svg" == x2 ? o3 = "http://www.w3.org/2000/svg" : "math" == x2 ? o3 = "http://www.w3.org/1998/Math/MathML" : o3 || (o3 = "http://www.w3.org/1999/xhtml"), null != e3) {
772
+ for (a3 = 0; a3 < e3.length; a3++) if ((d3 = e3[a3]) && "setAttribute" in d3 == !!x2 && (x2 ? d3.localName == x2 : 3 == d3.nodeType)) {
773
+ u4 = d3, e3[a3] = null;
774
+ break;
775
+ }
776
+ }
777
+ if (null == u4) {
778
+ if (null == x2) return document.createTextNode(k3);
779
+ u4 = document.createElementNS(o3, x2, k3.is && k3), c3 && (l.__m && l.__m(t3, e3), c3 = false), e3 = null;
780
+ }
781
+ if (null == x2) b === k3 || c3 && u4.data == k3 || (u4.data = k3);
782
+ else {
783
+ if (e3 = e3 && n.call(u4.childNodes), b = i3.props || p, !c3 && null != e3) for (b = {}, a3 = 0; a3 < u4.attributes.length; a3++) b[(d3 = u4.attributes[a3]).name] = d3.value;
784
+ for (a3 in b) if (d3 = b[a3], "children" == a3) ;
785
+ else if ("dangerouslySetInnerHTML" == a3) v3 = d3;
786
+ else if (!(a3 in k3)) {
787
+ if ("value" == a3 && "defaultValue" in k3 || "checked" == a3 && "defaultChecked" in k3) continue;
788
+ j(u4, a3, null, d3, o3);
789
+ }
790
+ for (a3 in k3) d3 = k3[a3], "children" == a3 ? y3 = d3 : "dangerouslySetInnerHTML" == a3 ? h3 = d3 : "value" == a3 ? _2 = d3 : "checked" == a3 ? m3 = d3 : c3 && "function" != typeof d3 || b[a3] === d3 || j(u4, a3, d3, b[a3], o3);
791
+ if (h3) c3 || v3 && (h3.__html == v3.__html || h3.__html == u4.innerHTML) || (u4.innerHTML = h3.__html), t3.__k = [];
792
+ else if (v3 && (u4.innerHTML = ""), I("template" == t3.type ? u4.content : u4, w(y3) ? y3 : [y3], t3, i3, r3, "foreignObject" == x2 ? "http://www.w3.org/1999/xhtml" : o3, e3, f4, e3 ? e3[0] : i3.__k && S(i3, 0), c3, s3), null != e3) for (a3 = e3.length; a3--; ) g(e3[a3]);
793
+ c3 || (a3 = "value", "progress" == x2 && null == _2 ? u4.removeAttribute("value") : null != _2 && (_2 !== u4[a3] || "progress" == x2 && !_2 || "option" == x2 && _2 != b[a3]) && j(u4, a3, _2, b[a3], o3), a3 = "checked", null != m3 && m3 != u4[a3] && j(u4, a3, m3, b[a3], o3));
794
+ }
795
+ return u4;
796
+ }
797
+ __name(q, "q");
798
+ function B(n2, u4, t3) {
799
+ try {
800
+ if ("function" == typeof n2) {
801
+ var i3 = "function" == typeof n2.__u;
802
+ i3 && n2.__u(), i3 && null == u4 || (n2.__u = n2(u4));
803
+ } else n2.current = u4;
804
+ } catch (n3) {
805
+ l.__e(n3, t3);
806
+ }
807
+ }
808
+ __name(B, "B");
809
+ function D(n2, u4, t3) {
810
+ var i3, r3;
811
+ if (l.unmount && l.unmount(n2), (i3 = n2.ref) && (i3.current && i3.current != n2.__e || B(i3, null, u4)), null != (i3 = n2.__c)) {
812
+ if (i3.componentWillUnmount) try {
813
+ i3.componentWillUnmount();
814
+ } catch (n3) {
815
+ l.__e(n3, u4);
816
+ }
817
+ i3.base = i3.__P = null;
818
+ }
819
+ if (i3 = n2.__k) for (r3 = 0; r3 < i3.length; r3++) i3[r3] && D(i3[r3], u4, t3 || "function" != typeof n2.type);
820
+ t3 || g(n2.__e), n2.__c = n2.__ = n2.__e = void 0;
821
+ }
822
+ __name(D, "D");
823
+ function E(n2, l3, u4) {
824
+ return this.constructor(n2, u4);
825
+ }
826
+ __name(E, "E");
827
+ function G(u4, t3, i3) {
828
+ var r3, o3, e3, f4;
829
+ t3 == document && (t3 = document.documentElement), l.__ && l.__(u4, t3), o3 = (r3 = "function" == typeof i3) ? null : i3 && i3.__k || t3.__k, e3 = [], f4 = [], O(t3, u4 = (!r3 && i3 || t3).__k = _(k, null, [u4]), o3 || p, p, t3.namespaceURI, !r3 && i3 ? [i3] : o3 ? null : t3.firstChild ? n.call(t3.childNodes) : null, e3, !r3 && i3 ? i3 : o3 ? o3.__e : t3.firstChild, r3, f4), N(e3, u4, f4);
830
+ }
831
+ __name(G, "G");
832
+ n = v.slice, l = { __e: /* @__PURE__ */ __name(function(n2, l3, u4, t3) {
833
+ for (var i3, r3, o3; l3 = l3.__; ) if ((i3 = l3.__c) && !i3.__) try {
834
+ if ((r3 = i3.constructor) && null != r3.getDerivedStateFromError && (i3.setState(r3.getDerivedStateFromError(n2)), o3 = i3.__d), null != i3.componentDidCatch && (i3.componentDidCatch(n2, t3 || {}), o3 = i3.__d), o3) return i3.__E = i3;
835
+ } catch (l4) {
836
+ n2 = l4;
837
+ }
838
+ throw n2;
839
+ }, "__e") }, u = 0, t = /* @__PURE__ */ __name(function(n2) {
840
+ return null != n2 && null == n2.constructor;
841
+ }, "t"), x.prototype.setState = function(n2, l3) {
842
+ var u4;
843
+ u4 = null != this.__s && this.__s != this.state ? this.__s : this.__s = d({}, this.state), "function" == typeof n2 && (n2 = n2(d({}, u4), this.props)), n2 && d(u4, n2), null != n2 && this.__v && (l3 && this._sb.push(l3), M(this));
844
+ }, x.prototype.forceUpdate = function(n2) {
845
+ this.__v && (this.__e = true, n2 && this.__h.push(n2), M(this));
846
+ }, x.prototype.render = k, i = [], o = "function" == typeof Promise ? Promise.prototype.then.bind(Promise.resolve()) : setTimeout, e = /* @__PURE__ */ __name(function(n2, l3) {
847
+ return n2.__v.__b - l3.__v.__b;
848
+ }, "e"), $.__r = 0, f = /(PointerCapture)$|Capture$/i, c = 0, s = F(false), a = F(true), h = 0;
849
+
850
+ // ../../node_modules/.pnpm/preact@10.27.2/node_modules/preact/hooks/dist/hooks.module.js
851
+ var t2;
852
+ var r2;
853
+ var u2;
854
+ var i2;
855
+ var o2 = 0;
856
+ var f2 = [];
857
+ var c2 = l;
858
+ var e2 = c2.__b;
859
+ var a2 = c2.__r;
860
+ var v2 = c2.diffed;
861
+ var l2 = c2.__c;
862
+ var m2 = c2.unmount;
863
+ var s2 = c2.__;
864
+ function p2(n2, t3) {
865
+ c2.__h && c2.__h(r2, n2, o2 || t3), o2 = 0;
866
+ var u4 = r2.__H || (r2.__H = { __: [], __h: [] });
867
+ return n2 >= u4.__.length && u4.__.push({}), u4.__[n2];
868
+ }
869
+ __name(p2, "p");
870
+ function d2(n2) {
871
+ return o2 = 1, h2(D2, n2);
872
+ }
873
+ __name(d2, "d");
874
+ function h2(n2, u4, i3) {
875
+ var o3 = p2(t2++, 2);
876
+ if (o3.t = n2, !o3.__c && (o3.__ = [i3 ? i3(u4) : D2(void 0, u4), function(n3) {
877
+ var t3 = o3.__N ? o3.__N[0] : o3.__[0], r3 = o3.t(t3, n3);
878
+ t3 !== r3 && (o3.__N = [r3, o3.__[1]], o3.__c.setState({}));
879
+ }], o3.__c = r2, !r2.__f)) {
880
+ var f4 = /* @__PURE__ */ __name(function(n3, t3, r3) {
881
+ if (!o3.__c.__H) return true;
882
+ var u5 = o3.__c.__H.__.filter(function(n4) {
883
+ return !!n4.__c;
884
+ });
885
+ if (u5.every(function(n4) {
886
+ return !n4.__N;
887
+ })) return !c3 || c3.call(this, n3, t3, r3);
888
+ var i4 = o3.__c.props !== n3;
889
+ return u5.forEach(function(n4) {
890
+ if (n4.__N) {
891
+ var t4 = n4.__[0];
892
+ n4.__ = n4.__N, n4.__N = void 0, t4 !== n4.__[0] && (i4 = true);
893
+ }
894
+ }), c3 && c3.call(this, n3, t3, r3) || i4;
895
+ }, "f");
896
+ r2.__f = true;
897
+ var c3 = r2.shouldComponentUpdate, e3 = r2.componentWillUpdate;
898
+ r2.componentWillUpdate = function(n3, t3, r3) {
899
+ if (this.__e) {
900
+ var u5 = c3;
901
+ c3 = void 0, f4(n3, t3, r3), c3 = u5;
902
+ }
903
+ e3 && e3.call(this, n3, t3, r3);
904
+ }, r2.shouldComponentUpdate = f4;
905
+ }
906
+ return o3.__N || o3.__;
907
+ }
908
+ __name(h2, "h");
909
+ function y2(n2, u4) {
910
+ var i3 = p2(t2++, 3);
911
+ !c2.__s && C2(i3.__H, u4) && (i3.__ = n2, i3.u = u4, r2.__H.__h.push(i3));
912
+ }
913
+ __name(y2, "y");
914
+ function A2(n2) {
915
+ return o2 = 5, T2(function() {
916
+ return { current: n2 };
917
+ }, []);
918
+ }
919
+ __name(A2, "A");
920
+ function T2(n2, r3) {
921
+ var u4 = p2(t2++, 7);
922
+ return C2(u4.__H, r3) && (u4.__ = n2(), u4.__H = r3, u4.__h = n2), u4.__;
923
+ }
924
+ __name(T2, "T");
925
+ function q2(n2, t3) {
926
+ return o2 = 8, T2(function() {
927
+ return n2;
928
+ }, t3);
929
+ }
930
+ __name(q2, "q");
931
+ function j2() {
932
+ for (var n2; n2 = f2.shift(); ) if (n2.__P && n2.__H) try {
933
+ n2.__H.__h.forEach(z2), n2.__H.__h.forEach(B2), n2.__H.__h = [];
934
+ } catch (t3) {
935
+ n2.__H.__h = [], c2.__e(t3, n2.__v);
936
+ }
937
+ }
938
+ __name(j2, "j");
939
+ c2.__b = function(n2) {
940
+ r2 = null, e2 && e2(n2);
941
+ }, c2.__ = function(n2, t3) {
942
+ n2 && t3.__k && t3.__k.__m && (n2.__m = t3.__k.__m), s2 && s2(n2, t3);
943
+ }, c2.__r = function(n2) {
944
+ a2 && a2(n2), t2 = 0;
945
+ var i3 = (r2 = n2.__c).__H;
946
+ i3 && (u2 === r2 ? (i3.__h = [], r2.__h = [], i3.__.forEach(function(n3) {
947
+ n3.__N && (n3.__ = n3.__N), n3.u = n3.__N = void 0;
948
+ })) : (i3.__h.forEach(z2), i3.__h.forEach(B2), i3.__h = [], t2 = 0)), u2 = r2;
949
+ }, c2.diffed = function(n2) {
950
+ v2 && v2(n2);
951
+ var t3 = n2.__c;
952
+ t3 && t3.__H && (t3.__H.__h.length && (1 !== f2.push(t3) && i2 === c2.requestAnimationFrame || ((i2 = c2.requestAnimationFrame) || w2)(j2)), t3.__H.__.forEach(function(n3) {
953
+ n3.u && (n3.__H = n3.u), n3.u = void 0;
954
+ })), u2 = r2 = null;
955
+ }, c2.__c = function(n2, t3) {
956
+ t3.some(function(n3) {
957
+ try {
958
+ n3.__h.forEach(z2), n3.__h = n3.__h.filter(function(n4) {
959
+ return !n4.__ || B2(n4);
960
+ });
961
+ } catch (r3) {
962
+ t3.some(function(n4) {
963
+ n4.__h && (n4.__h = []);
964
+ }), t3 = [], c2.__e(r3, n3.__v);
965
+ }
966
+ }), l2 && l2(n2, t3);
967
+ }, c2.unmount = function(n2) {
968
+ m2 && m2(n2);
969
+ var t3, r3 = n2.__c;
970
+ r3 && r3.__H && (r3.__H.__.forEach(function(n3) {
971
+ try {
972
+ z2(n3);
973
+ } catch (n4) {
974
+ t3 = n4;
975
+ }
976
+ }), r3.__H = void 0, t3 && c2.__e(t3, r3.__v));
977
+ };
978
+ var k2 = "function" == typeof requestAnimationFrame;
979
+ function w2(n2) {
980
+ var t3, r3 = /* @__PURE__ */ __name(function() {
981
+ clearTimeout(u4), k2 && cancelAnimationFrame(t3), setTimeout(n2);
982
+ }, "r"), u4 = setTimeout(r3, 35);
983
+ k2 && (t3 = requestAnimationFrame(r3));
984
+ }
985
+ __name(w2, "w");
986
+ function z2(n2) {
987
+ var t3 = r2, u4 = n2.__c;
988
+ "function" == typeof u4 && (n2.__c = void 0, u4()), r2 = t3;
989
+ }
990
+ __name(z2, "z");
991
+ function B2(n2) {
992
+ var t3 = r2;
993
+ n2.__c = n2.__(), r2 = t3;
994
+ }
995
+ __name(B2, "B");
996
+ function C2(n2, t3) {
997
+ return !n2 || n2.length !== t3.length || t3.some(function(t4, r3) {
998
+ return t4 !== n2[r3];
999
+ });
1000
+ }
1001
+ __name(C2, "C");
1002
+ function D2(n2, t3) {
1003
+ return "function" == typeof t3 ? t3(n2) : t3;
1004
+ }
1005
+ __name(D2, "D");
1006
+
1007
+ // ../../node_modules/.pnpm/preact@10.27.2/node_modules/preact/jsx-runtime/dist/jsxRuntime.module.js
1008
+ var f3 = 0;
1009
+ function u3(e3, t3, n2, o3, i3, u4) {
1010
+ t3 || (t3 = {});
1011
+ var a3, c3, p3 = t3;
1012
+ if ("ref" in p3) for (c3 in p3 = {}, t3) "ref" == c3 ? a3 = t3[c3] : p3[c3] = t3[c3];
1013
+ var l3 = { type: e3, props: p3, key: n2, ref: a3, __k: null, __: null, __b: 0, __e: null, __c: null, constructor: void 0, __v: --f3, __i: -1, __u: 0, __source: i3, __self: u4 };
1014
+ if ("function" == typeof e3 && (a3 = e3.defaultProps)) for (c3 in a3) void 0 === p3[c3] && (p3[c3] = a3[c3]);
1015
+ return l.vnode && l.vnode(l3), l3;
1016
+ }
1017
+ __name(u3, "u");
1018
+
1019
+ // src/cue-card.tsx
1020
+ var ArrowRightIcon = /* @__PURE__ */ __name(() => /* @__PURE__ */ u3(
1021
+ "svg",
1022
+ {
1023
+ xmlns: "http://www.w3.org/2000/svg",
1024
+ viewBox: "0 0 24 24",
1025
+ fill: "currentColor",
1026
+ width: "16",
1027
+ height: "16",
1028
+ children: /* @__PURE__ */ u3(
1029
+ "path",
1030
+ {
1031
+ fillRule: "evenodd",
1032
+ d: "M16.72 7.72a.75.75 0 0 1 1.06 0l3.75 3.75a.75.75 0 0 1 0 1.06l-3.75 3.75a.75.75 0 1 1-1.06-1.06l2.47-2.47H3a.75.75 0 0 1 0-1.5h16.19l-2.47-2.47a.75.75 0 0 1 0-1.06Z",
1033
+ clipRule: "evenodd"
1034
+ }
1035
+ )
1036
+ }
1037
+ ), "ArrowRightIcon");
1038
+ var CheckIcon = /* @__PURE__ */ __name(() => /* @__PURE__ */ u3(
1039
+ "svg",
1040
+ {
1041
+ xmlns: "http://www.w3.org/2000/svg",
1042
+ viewBox: "0 0 24 24",
1043
+ fill: "currentColor",
1044
+ width: "16",
1045
+ height: "16",
1046
+ children: /* @__PURE__ */ u3(
1047
+ "path",
1048
+ {
1049
+ fillRule: "evenodd",
1050
+ d: "M19.916 4.626a.75.75 0 0 1 .208 1.04l-9 13.5a.75.75 0 0 1-1.154.114l-6-6a.75.75 0 0 1 1.06-1.06l5.353 5.353 8.493-12.739a.75.75 0 0 1 1.04-.208Z",
1051
+ clipRule: "evenodd"
1052
+ }
1053
+ )
1054
+ }
1055
+ ), "CheckIcon");
1056
+ var XMarkIcon = /* @__PURE__ */ __name(() => /* @__PURE__ */ u3(
1057
+ "svg",
1058
+ {
1059
+ xmlns: "http://www.w3.org/2000/svg",
1060
+ viewBox: "0 0 24 24",
1061
+ fill: "currentColor",
1062
+ width: "16",
1063
+ height: "16",
1064
+ children: /* @__PURE__ */ u3(
1065
+ "path",
1066
+ {
1067
+ fillRule: "evenodd",
1068
+ d: "M5.47 5.47a.75.75 0 0 1 1.06 0L12 10.94l5.47-5.47a.75.75 0 1 1 1.06 1.06L13.06 12l5.47 5.47a.75.75 0 1 1-1.06 1.06L12 13.06l-5.47 5.47a.75.75 0 0 1-1.06-1.06L10.94 12 5.47 6.53a.75.75 0 0 1 0-1.06Z",
1069
+ clipRule: "evenodd"
1070
+ }
1071
+ )
1072
+ }
1073
+ ), "XMarkIcon");
1074
+ var LoaderIcon = /* @__PURE__ */ __name(() => /* @__PURE__ */ u3(
1075
+ "svg",
1076
+ {
1077
+ xmlns: "http://www.w3.org/2000/svg",
1078
+ width: "16",
1079
+ height: "16",
1080
+ viewBox: "0 0 24 24",
1081
+ fill: "none",
1082
+ stroke: "currentColor",
1083
+ strokeWidth: "2",
1084
+ strokeLinecap: "round",
1085
+ strokeLinejoin: "round",
1086
+ className: "animate-spin",
1087
+ children: /* @__PURE__ */ u3("path", { d: "M21 12a9 9 0 1 1-6.219-8.56" })
1088
+ }
1089
+ ), "LoaderIcon");
1090
+ var LogoIcon = /* @__PURE__ */ __name(() => /* @__PURE__ */ u3(
1091
+ "svg",
1092
+ {
1093
+ width: "32",
1094
+ height: "32",
1095
+ viewBox: "0 0 900 900",
1096
+ fill: "none",
1097
+ xmlns: "http://www.w3.org/2000/svg",
1098
+ children: [
1099
+ /* @__PURE__ */ u3("circle", { cx: "446", cy: "450", r: "424", fill: "black" }),
1100
+ /* @__PURE__ */ u3("circle", { cx: "450", cy: "450", r: "357", fill: "url(#paint0_linear_1_41)" }),
1101
+ /* @__PURE__ */ u3(
1102
+ "ellipse",
1103
+ {
1104
+ cx: "579.85",
1105
+ cy: "294.451",
1106
+ rx: "79.778",
1107
+ ry: "108.483",
1108
+ transform: "rotate(-46.2324 579.85 294.451)",
1109
+ fill: "black"
1110
+ }
1111
+ ),
1112
+ /* @__PURE__ */ u3("defs", { children: /* @__PURE__ */ u3(
1113
+ "linearGradient",
1114
+ {
1115
+ id: "paint0_linear_1_41",
1116
+ x1: "807",
1117
+ y1: "93",
1118
+ x2: "93",
1119
+ y2: "807",
1120
+ gradientUnits: "userSpaceOnUse",
1121
+ children: [
1122
+ /* @__PURE__ */ u3("stop", { "stop-color": "#FAFAFA" }),
1123
+ /* @__PURE__ */ u3("stop", { offset: "1", "stop-color": "#CACACA" })
1124
+ ]
1125
+ }
1126
+ ) })
1127
+ ]
1128
+ }
1129
+ ), "LogoIcon");
1130
+ var STYLES = `
1131
+ :host { --kb-font-family: system-ui, -apple-system, sans-serif; --kb-bg-container: rgba(255, 255, 255, 0.05); --kb-border-container: rgba(255, 255, 255, 0.2); --kb-shadow-container: 0 25px 50px -12px rgba(0, 0, 0, 0.25); --kb-backdrop-blur: 16px; --kb-text-title: #ffffff; --kb-text-subtitle: rgba(255, 255, 255, 0.7); --kb-btn-dismiss-bg: rgba(0, 0, 0, 0.7); --kb-btn-dismiss-border: rgba(255, 255, 255, 0.2); --kb-btn-dismiss-text: rgba(255, 255, 255, 0.8); --kb-btn-dismiss-hover-bg: rgba(0, 0, 0, 0.9); --kb-btn-dismiss-hover-text: #ffffff; --kb-btn-trigger-bg: #ffffff; --kb-btn-trigger-text: #000000; --kb-btn-trigger-hover-bg: rgba(255, 255, 255, 0.9); --kb-progress-track: rgba(255, 255, 255, 0.2); --kb-progress-indicator: #ffffff; --kb-popover-bg: rgba(255, 255, 255, 0.05); --kb-popover-border: rgba(255, 255, 255, 0.2); --kb-popover-text: #ffffff; --kb-input-bg: transparent; --kb-input-border: rgba(255, 255, 255, 0.3); --kb-input-text: #ffffff; --kb-input-placeholder: rgba(255, 255, 255, 0.6); --kb-form-label: #ffffff; --kb-success-color: #6ee7b7; --kb-error-text: #ef4444; --kb-focus-blur: 10px; --kb-kbd-bg: rgba(255, 255, 255, 0.1); --kb-kbd-border: rgba(255, 255, 255, 0.2); --kb-kbd-text: rgba(255, 255, 255, 0.6); --kb-watermark-text: rgba(255, 255, 255, 0.4); font-family: var(--kb-font-family); }
1132
+ .theme-light { --kb-bg-container: #ffffff; --kb-border-container: #e2e8f0; --kb-shadow-container: 0 20px 25px -5px rgba(0, 0, 0, 0.1); --kb-backdrop-blur: 0px; --kb-text-title: #0f172a; --kb-text-subtitle: #475569; --kb-btn-dismiss-bg: #ffffff; --kb-btn-dismiss-border: #e2e8f0; --kb-btn-dismiss-text: #64748b; --kb-btn-dismiss-hover-bg: #f1f5f9; --kb-btn-dismiss-hover-text: #0f172a; --kb-btn-trigger-bg: #0f172a; --kb-btn-trigger-text: #ffffff; --kb-btn-trigger-hover-bg: #1e293b; --kb-progress-track: #e2e8f0; --kb-progress-indicator: #0f172a; --kb-popover-bg: #ffffff; --kb-popover-border: #e2e8f0; --kb-popover-text: #0f172a; --kb-input-bg: #ffffff; --kb-input-border: #cbd5e1; --kb-input-text: #0f172a; --kb-input-placeholder: #94a3b8; --kb-form-label: #334155; --kb-success-color: #059669; --kb-error-text: #ef4444; --kb-kbd-bg: #f1f5f9; --kb-kbd-border: #e2e8f0; --kb-kbd-text: #64748b; --kb-watermark-text: #94a3b8; }
1133
+ .theme-dark { --kb-bg-container: #0f172a; --kb-border-container: #334155; --kb-shadow-container: 0 25px 50px -12px rgba(0, 0, 0, 0.25); --kb-backdrop-blur: 0px; --kb-text-title: #f1f5f9; --kb-text-subtitle: #94a3b8; --kb-btn-dismiss-bg: #1e293b; --kb-btn-dismiss-border: #334155; --kb-btn-dismiss-text: #cbd5e1; --kb-btn-dismiss-hover-bg: #334155; --kb-btn-dismiss-hover-text: #ffffff; --kb-btn-trigger-bg: #ffffff; --kb-btn-trigger-text: #0f172a; --kb-btn-trigger-hover-bg: #f1f5f9; --kb-progress-track: #1e293b; --kb-progress-indicator: #ffffff; --kb-popover-bg: #0f172a; --kb-popover-border: #334155; --kb-popover-text: #f1f5f9; --kb-input-bg: #0f172a; --kb-input-border: #475569; --kb-input-text: #f1f5f9; --kb-input-placeholder: #94a3b8; --kb-form-label: #e2e8f0; --kb-success-color: #6ee7b7; --kb-error-text: #ef4444; --kb-kbd-bg: #1e293b; --kb-kbd-border: #334155; --kb-kbd-text: #94a3b8; --kb-watermark-text: #64748b; }
1134
+ *, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
1135
+ #cue-card-root { position: fixed; z-index: 2147483647; pointer-events: none; width: 100%; height: 0; top: 0; left: 0; isolation: isolate; }
1136
+ .container { position: absolute; pointer-events: auto; background-color: var(--kb-bg-container); border: 1px solid var(--kb-border-container); box-shadow: var(--kb-shadow-container); backdrop-filter: blur(var(--kb-backdrop-blur)); -webkit-backdrop-filter: blur(var(--kb-backdrop-blur)); border-radius: 0.25rem; border-bottom-left-radius: 0.25rem; border-bottom-right-radius: 0.25rem; padding: 1rem; width: auto; min-width: 320px; max-width: 90vw; opacity: 0; z-index: 1; font-family: var(--kb-font-family); }
1137
+ .backdrop { position: fixed; inset: 0; background: rgba(0,0,0,0); backdrop-filter: blur(0); -webkit-backdrop-filter: blur(0); transition: all 0.5s ease; z-index: 0; pointer-events: none; }
1138
+ .backdrop.active { background: rgba(0,0,0,0.1); backdrop-filter: blur(var(--kb-focus-blur)); -webkit-backdrop-filter: blur(var(--kb-focus-blur)); }
1139
+ .launcher { position: absolute; pointer-events: auto; background-color: var(--kb-bg-container); border: 1px solid var(--kb-border-container); box-shadow: var(--kb-shadow-container); backdrop-filter: blur(var(--kb-backdrop-blur)); -webkit-backdrop-filter: blur(var(--kb-backdrop-blur)); border-radius: 9999px; padding: 0.5rem 1rem; display: flex; align-items: center; gap: 0.75rem; cursor: pointer; transition: transform 0.2s, opacity 0.3s; opacity: 0; z-index: 1; color: var(--kb-text-title); font-weight: 500; font-size: 0.875rem; font-family: var(--kb-font-family); }
1140
+ .launcher .kbd-hint .kbd { background: var(--kb-kbd-bg); border: 1px solid var(--kb-kbd-border); color: var(--kb-kbd-text); }
1141
+ .launcher .kbd-hint .kbd-text { color: var(--kb-kbd-text); }
1142
+ .launcher:hover { transform: scale(1.02); background-color: var(--kb-bg-container); }
1143
+ .pos-top-center { left: 50%; translate: -50% 0; top: 1rem; }
1144
+ .pos-top-right { right: 1rem; top: 1rem; left: auto; }
1145
+ @media (max-width: 768px) { .pos-top-center, .pos-top-right { left: 0.5rem; right: 0.5rem; top: 0.5rem; translate: none; width: auto; max-width: none; } }
1146
+ :host(.kb-inline) { position: relative !important; z-index: auto !important; top: auto !important; left: auto !important; width: 100% !important; height: auto !important; pointer-events: auto !important; isolation: auto !important; display: block; }
1147
+ :host(.kb-inline) .container, :host(.kb-inline) .launcher { position: relative !important; left: auto !important; right: auto !important; top: auto !important; translate: none !important; width: 100% !important; max-width: 100% !important; margin: 0 !important; box-shadow: none !important; }
1148
+ :host(.kb-inline) .container { opacity: 1 !important; transform: none !important; }
1149
+ :host(.kb-inline) .popover { position: static !important; transform: none !important; opacity: 1 !important; visibility: visible !important; pointer-events: auto !important; margin-top: 0.75rem !important; }
1150
+ :host(.kb-inline) .backdrop, :host(.kb-inline) .launcher, :host(.kb-inline) .btn-dismiss { display: none !important; }
1151
+ .content-wrapper { display: flex; align-items: center; gap: 1rem; }
1152
+ .logo { width: 2.5rem; height: 2.5rem; display: none; }
1153
+ @media (min-width: 1024px) { .logo { display: block; } }
1154
+ .text-content { flex: 1; user-select: none; }
1155
+ .text-row { display: flex; align-items: center; justify-content: space-between; gap: 1.5rem; flex-wrap: wrap; }
1156
+ .title { color: var(--kb-text-title); font-size: 1rem; font-weight: 600; line-height: 1.5; }
1157
+ .subtitle { color: var(--kb-text-title); font-size: 0.875rem; line-height: 1.25; opacity: 0.8; }
1158
+ .btn { display: inline-flex; align-items: center; justify-content: center; border-radius: 0.375rem; font-weight: 500; font-size: 0.875rem; line-height: 1.25rem; padding: 0.5rem 1rem; transition: all 0.2s; cursor: pointer; border: none; outline: none; }
1159
+ .btn-trigger { background-color: var(--kb-btn-trigger-bg); color: var(--kb-btn-trigger-text); min-width: 8rem; gap: 0.5rem; }
1160
+ .btn-trigger:not(:disabled):hover { background-color: var(--kb-btn-trigger-hover-bg); }
1161
+ .btn-trigger:disabled { opacity: 0.8; cursor: not-allowed; }
1162
+ .btn-trigger.success { background-color: transparent; color: var(--kb-success-color); padding-right: 0.75rem; cursor: default; }
1163
+ .btn-trigger.success:hover { background-color: transparent; }
1164
+ .animate-spin { animation: spin 1s linear infinite; }
1165
+ @keyframes spin { from { transform: rotate(0deg); } to { transform: rotate(360deg); } }
1166
+ .btn-dismiss { position: absolute; top: -0.5rem; left: -0.5rem; width: 1.5rem; height: 1.5rem; padding: 0; border-radius: 9999px; display: flex; align-items: center; justify-content: center; background-color: var(--kb-btn-dismiss-bg); border: 1px solid var(--kb-btn-dismiss-border); color: var(--kb-btn-dismiss-text); cursor: pointer; transition: all 0.3s ease-out; z-index: 10; box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1); }
1167
+ .btn-dismiss:hover { background-color: var(--kb-btn-dismiss-hover-bg); color: var(--kb-btn-dismiss-hover-text); }
1168
+ .progress-clip { position: absolute; inset: 0; border-radius: inherit; overflow: hidden; pointer-events: none; }
1169
+ .progress-container { position: absolute; bottom: 0; left: 0; right: 0; height: 0.25rem; background-color: var(--kb-progress-track); overflow: hidden; pointer-events: none; }
1170
+ .progress-bar { height: 100%; background-color: var(--kb-progress-indicator); width: 0%; transition: width 0.3s ease; }
1171
+ .popover { position: absolute; top: 100%; left: 0; right: 0; margin-top: 0.375rem; background-color: var(--kb-popover-bg); border: 1px solid var(--kb-popover-border); border-radius: 0.25rem; border-top-left-radius: 0; border-top-right-radius: 0; padding: 1rem; color: var(--kb-popover-text); box-shadow: var(--kb-shadow-container); backdrop-filter: blur(var(--kb-backdrop-blur)); -webkit-backdrop-filter: blur(var(--kb-backdrop-blur)); opacity: 0; transform: translateY(-10px); pointer-events: none; visibility: hidden; transition: all 0.2s ease-out; }
1172
+ .popover.open { opacity: 1; transform: translateY(0); pointer-events: auto; visibility: visible; }
1173
+ .form-group { margin-bottom: 1rem; }
1174
+ .form-label { display: block; margin-bottom: 0.5rem; font-size: 0.875rem; color: var(--kb-form-label); font-weight: 500; }
1175
+ .input-row { display: flex; gap: 0.5rem; }
1176
+ .form-input { flex: 1; background-color: var(--kb-input-bg); border: 1px solid var(--kb-input-border); color: var(--kb-input-text); border-radius: 0.375rem; padding: 0.5rem 0.75rem; font-size: 0.875rem; outline: none; transition: border-color 0.2s; min-height: 44px; }
1177
+ .form-input::placeholder { color: var(--kb-input-placeholder); }
1178
+ .form-input:focus { border-color: var(--kb-progress-indicator); }
1179
+ .form-input.error { border-color: var(--kb-error-text); }
1180
+ .form-label.error { color: var(--kb-error-text); }
1181
+ .form-message { color: var(--kb-error-text); font-size: 0.75rem; margin-top: 0.25rem; font-weight: 500; }
1182
+ .btn-submit { background-color: var(--kb-btn-trigger-bg); color: var(--kb-btn-trigger-text); padding: 0.5rem 1rem; display: inline-flex; align-items: center; justify-content: center; gap: 0.5rem; }
1183
+ .btn-submit:disabled { opacity: 0.7; cursor: not-allowed; }
1184
+ .kbd-hint { display: flex; align-items: center; gap: 0.5rem; position: absolute; top: calc(100% + 0.5rem); left: 50%; transform: translateX(-50%); opacity: 0; pointer-events: none; transition: opacity 0.2s ease; white-space: nowrap; }
1185
+ .kbd-hint.visible { opacity: 1; }
1186
+ .kbd-group { display: flex; align-items: center; gap: 0.25rem; }
1187
+ .kbd { font-family: inherit; font-size: 0.75rem; line-height: 1; padding: 0.25rem 0.375rem; border-radius: 0.25rem; background: var(--kb-kbd-bg); border: 1px solid var(--kb-kbd-border); color: var(--kb-kbd-text); font-weight: 500; min-width: 1.25rem; text-align: center; }
1188
+ .kbd-text { font-size: 0.75rem; color: var(--kb-kbd-text); }
1189
+ .watermark { text-align: center; font-size: 0.625rem; color: var(--kb-watermark-text); opacity: 0.8; font-weight: 500; letter-spacing: 0.025em; }
1190
+ .watermark a { color: inherit; text-decoration: none; cursor: pointer; }
1191
+ .watermark a:hover { text-decoration: underline; text-decoration-color: var(--kb-watermark-text); }
1192
+ /* Launcher hint positioning */
1193
+ .launcher .kbd-hint { position: static; transform: none; opacity: 0.6; transition: opacity 0.2s; }
1194
+ .launcher:hover .kbd-hint { opacity: 1; }
1195
+ .pos-top-right.launcher .kbd-hint { left: auto; right: auto; }
1196
+ `;
1197
+ var useEnterExitAnimation = /* @__PURE__ */ __name((ref, isVisible, config) => {
1198
+ const hasEnteredRef = A2(false);
1199
+ y2(() => {
1200
+ const element = ref.current;
1201
+ if (!element) return;
1202
+ const isTopDown = config.direction === "top-to-bottom";
1203
+ const initialTransform = isTopDown ? `translateY(-60px)` : `translateX(60px)`;
1204
+ const exitTransform = isTopDown ? `translateY(-20px)` : `translateX(20px)`;
1205
+ const finalTransform = "translate(0, 0)";
1206
+ if (isVisible) {
1207
+ hasEnteredRef.current = true;
1208
+ const anim = element.animate(
1209
+ [
1210
+ { opacity: 0, transform: initialTransform },
1211
+ { opacity: 1, transform: finalTransform }
1212
+ ],
1213
+ {
1214
+ duration: 500,
1215
+ delay: config.entranceDelayMs,
1216
+ easing: "cubic-bezier(0.175, 0.885, 0.32, 1.275)",
1217
+ fill: "forwards"
1218
+ }
1219
+ );
1220
+ anim.onfinish = () => config.onEntranceComplete?.();
1221
+ } else {
1222
+ if (hasEnteredRef.current) {
1223
+ const anim = element.animate(
1224
+ [
1225
+ { opacity: 1, transform: finalTransform },
1226
+ { opacity: 0, transform: exitTransform }
1227
+ ],
1228
+ {
1229
+ duration: 350,
1230
+ delay: config.exitDelayMs,
1231
+ easing: "ease-in-out",
1232
+ fill: "forwards"
1233
+ }
1234
+ );
1235
+ anim.onfinish = () => config.onExitComplete?.();
1236
+ } else {
1237
+ element.style.opacity = "0";
1238
+ element.style.transform = exitTransform;
1239
+ }
1240
+ }
1241
+ }, [isVisible, config.direction]);
1242
+ }, "useEnterExitAnimation");
1243
+ var getThemeStyles = /* @__PURE__ */ __name((theme) => {
1244
+ if (!theme) return {};
1245
+ const styles = {};
1246
+ if (theme.fontFamily) styles["--kb-font-family"] = theme.fontFamily;
1247
+ if (theme.backgroundColor) {
1248
+ styles["--kb-bg-container"] = theme.backgroundColor;
1249
+ styles["--kb-popover-bg"] = theme.backgroundColor;
1250
+ }
1251
+ if (theme.borderColor) {
1252
+ styles["--kb-border-container"] = theme.borderColor;
1253
+ styles["--kb-popover-border"] = theme.borderColor;
1254
+ }
1255
+ if (theme.textColor) {
1256
+ styles["--kb-text-title"] = theme.textColor;
1257
+ styles["--kb-popover-text"] = theme.textColor;
1258
+ }
1259
+ if (theme.subtitleColor) styles["--kb-text-subtitle"] = theme.subtitleColor;
1260
+ if (theme.borderRadius) {
1261
+ styles["border-radius"] = theme.borderRadius;
1262
+ styles["border-bottom-left-radius"] = theme.borderRadius;
1263
+ styles["border-bottom-right-radius"] = theme.borderRadius;
1264
+ }
1265
+ if (theme.primaryColor) {
1266
+ styles["--kb-btn-trigger-bg"] = theme.primaryColor;
1267
+ styles["--kb-progress-indicator"] = theme.primaryColor;
1268
+ styles["--kb-success-color"] = theme.primaryColor;
1269
+ }
1270
+ if (theme.primaryTextColor) {
1271
+ styles["--kb-btn-trigger-text"] = theme.primaryTextColor;
1272
+ }
1273
+ return styles;
1274
+ }, "getThemeStyles");
1275
+ var CueCardContent = /* @__PURE__ */ __name(({ config, isOpen, skipFocus, setIsOpen }) => {
1276
+ const isInline = config.mountMode === "inline";
1277
+ const containerRef = A2(null);
1278
+ const launcherRef = A2(null);
1279
+ const backdropRef = A2(null);
1280
+ const firstInputRef = A2(null);
1281
+ const formRef = A2(null);
1282
+ const [mode, setMode] = d2("card");
1283
+ const hasEnteredRef = A2(false);
1284
+ const hasHadSuccessRef = A2(false);
1285
+ const isShowingInitialSuccessRef = A2(false);
1286
+ const justReopenedRef = A2(false);
1287
+ const previousModeRef = A2("card");
1288
+ const prevStatusRef = A2(config.status);
1289
+ const prevVisibilityRef = A2(!!config.isVisible);
1290
+ const timerStartRef = A2(null);
1291
+ const timerRafRef = A2(null);
1292
+ const hasTimerCompletedRef = A2(false);
1293
+ const [isHovering, setIsHovering] = d2(false);
1294
+ const [errors, setErrors] = d2({});
1295
+ const [timerProgress, setTimerProgressState] = d2(0);
1296
+ const timerProgressRef = A2(0);
1297
+ const timerEnabled = config.enableTimer !== false;
1298
+ const timerDuration = Math.max(500, config.timerDurationMs ?? 2e4);
1299
+ const setTimerProgress = q2((value) => {
1300
+ timerProgressRef.current = value;
1301
+ setTimerProgressState(value);
1302
+ }, []);
1303
+ y2(() => {
1304
+ if (config.isVisible) {
1305
+ setMode("card");
1306
+ hasEnteredRef.current = false;
1307
+ }
1308
+ }, [config.isVisible]);
1309
+ if (mode === "card" && previousModeRef.current === "launcher") {
1310
+ isShowingInitialSuccessRef.current = false;
1311
+ }
1312
+ if (config.status === "success" && prevStatusRef.current !== "success") {
1313
+ if (mode === "card") {
1314
+ isShowingInitialSuccessRef.current = true;
1315
+ }
1316
+ } else if (config.status !== "success") {
1317
+ isShowingInitialSuccessRef.current = false;
1318
+ }
1319
+ prevStatusRef.current = config.status;
1320
+ y2(() => {
1321
+ const wasLauncher = previousModeRef.current === "launcher";
1322
+ const isCard = mode === "card";
1323
+ if (wasLauncher && isCard && hasHadSuccessRef.current) {
1324
+ justReopenedRef.current = true;
1325
+ setTimeout(() => {
1326
+ justReopenedRef.current = false;
1327
+ }, 100);
1328
+ }
1329
+ if (mode === "launcher") {
1330
+ setIsHovering(false);
1331
+ }
1332
+ if (wasLauncher && isCard && timerEnabled) {
1333
+ setTimerProgress(0);
1334
+ timerStartRef.current = null;
1335
+ hasTimerCompletedRef.current = false;
1336
+ }
1337
+ }, [mode, setTimerProgress, timerEnabled]);
1338
+ y2(() => {
1339
+ if (config.status === "success") {
1340
+ hasHadSuccessRef.current = true;
1341
+ if (config.enableLauncher && mode === "card" && isShowingInitialSuccessRef.current) {
1342
+ const timer = setTimeout(() => {
1343
+ setMode("launcher");
1344
+ }, 2e3);
1345
+ return () => clearTimeout(timer);
1346
+ }
1347
+ }
1348
+ }, [config.status, config.enableLauncher, mode]);
1349
+ y2(() => {
1350
+ if (config.isVisible && !prevVisibilityRef.current && timerEnabled) {
1351
+ setTimerProgress(0);
1352
+ timerStartRef.current = null;
1353
+ hasTimerCompletedRef.current = false;
1354
+ }
1355
+ prevVisibilityRef.current = !!config.isVisible;
1356
+ }, [config.isVisible, setTimerProgress, timerEnabled]);
1357
+ y2(() => {
1358
+ previousModeRef.current = mode;
1359
+ }, [mode]);
1360
+ const skipFocusRef = A2(false);
1361
+ if (skipFocus) {
1362
+ skipFocusRef.current = true;
1363
+ }
1364
+ y2(() => {
1365
+ if (isOpen) {
1366
+ if (hasHadSuccessRef.current && formRef.current) {
1367
+ formRef.current.reset();
1368
+ }
1369
+ const shouldSkipFocus = skipFocusRef.current;
1370
+ skipFocusRef.current = false;
1371
+ if (!shouldSkipFocus) {
1372
+ const focusTimer = setTimeout(() => {
1373
+ if (firstInputRef.current) {
1374
+ firstInputRef.current.focus();
1375
+ }
1376
+ }, 100);
1377
+ return () => clearTimeout(focusTimer);
1378
+ }
1379
+ }
1380
+ }, [isOpen]);
1381
+ const prevIsOpenForExpandRef = A2(isOpen);
1382
+ y2(() => {
1383
+ const wasOpen = prevIsOpenForExpandRef.current;
1384
+ prevIsOpenForExpandRef.current = isOpen;
1385
+ if (!wasOpen && isOpen && mode === "launcher") {
1386
+ setMode("card");
1387
+ }
1388
+ }, [isOpen, mode]);
1389
+ y2(() => {
1390
+ if (config.status === "starting") {
1391
+ setIsOpen(false);
1392
+ }
1393
+ }, [config.status, setIsOpen]);
1394
+ if (!isInline) {
1395
+ useEnterExitAnimation(containerRef, !!config.isVisible && mode === "card", {
1396
+ direction: config.direction || "top-to-bottom",
1397
+ position: config.position || "top-center",
1398
+ entranceDelayMs: hasEnteredRef.current ? 0 : config.entranceDelayMs || 0,
1399
+ exitDelayMs: 75,
1400
+ onEntranceComplete: /* @__PURE__ */ __name(() => {
1401
+ config.onEntranceComplete?.();
1402
+ hasEnteredRef.current = true;
1403
+ }, "onEntranceComplete"),
1404
+ onExitComplete: /* @__PURE__ */ __name(() => {
1405
+ if (!config.isVisible) config.onExitComplete?.();
1406
+ }, "onExitComplete")
1407
+ });
1408
+ useEnterExitAnimation(
1409
+ launcherRef,
1410
+ !!config.isVisible && mode === "launcher",
1411
+ {
1412
+ direction: config.direction || "top-to-bottom",
1413
+ position: config.position || "top-center",
1414
+ entranceDelayMs: 0,
1415
+ exitDelayMs: 75
1416
+ }
1417
+ );
1418
+ }
1419
+ y2(() => {
1420
+ const el = backdropRef.current;
1421
+ if (!el) return;
1422
+ const isSuccess2 = config.status === "success";
1423
+ if (config.enableFocusMode && mode === "card" && config.isVisible && !isSuccess2) {
1424
+ const timer = setTimeout(() => {
1425
+ el.classList.add("active");
1426
+ }, config.focusDelayMs || 500);
1427
+ return () => clearTimeout(timer);
1428
+ } else {
1429
+ el.classList.remove("active");
1430
+ }
1431
+ }, [
1432
+ config.enableFocusMode,
1433
+ mode,
1434
+ config.isVisible,
1435
+ config.focusDelayMs,
1436
+ config.status
1437
+ ]);
1438
+ y2(() => {
1439
+ if (!config.isVisible) return;
1440
+ const handleKey = /* @__PURE__ */ __name((e3) => {
1441
+ if (e3.key === "Escape") {
1442
+ if (isOpen) {
1443
+ setIsOpen(false);
1444
+ return;
1445
+ }
1446
+ if (mode === "card") {
1447
+ if (config.enableLauncher) {
1448
+ setMode("launcher");
1449
+ } else {
1450
+ config.onDismiss?.();
1451
+ }
1452
+ }
1453
+ return;
1454
+ }
1455
+ const matchesShortcut = /* @__PURE__ */ __name((e4, shortcut) => {
1456
+ const s3 = shortcut || { key: "p", modifiers: ["meta", "ctrl"] };
1457
+ if (e4.key.toLowerCase() !== s3.key.toLowerCase()) return false;
1458
+ const mods = s3.modifiers || [];
1459
+ if (shortcut) {
1460
+ const hasMeta = mods.includes("meta") === e4.metaKey;
1461
+ const hasCtrl = mods.includes("ctrl") === e4.ctrlKey;
1462
+ const hasAlt = mods.includes("alt") === e4.altKey;
1463
+ const hasShift = mods.includes("shift") === e4.shiftKey;
1464
+ return hasMeta && hasCtrl && hasAlt && hasShift;
1465
+ }
1466
+ const isCmdOrCtrl = e4.metaKey || e4.ctrlKey;
1467
+ return isCmdOrCtrl;
1468
+ }, "matchesShortcut");
1469
+ if (matchesShortcut(e3, config.keyboardShortcut)) {
1470
+ e3.preventDefault();
1471
+ if (mode === "launcher") {
1472
+ setMode("card");
1473
+ setIsOpen(true);
1474
+ } else if (mode === "card") {
1475
+ if (config.enableLauncher) {
1476
+ setMode("launcher");
1477
+ } else {
1478
+ config.onDismiss?.();
1479
+ }
1480
+ }
1481
+ }
1482
+ }, "handleKey");
1483
+ window.addEventListener("keydown", handleKey);
1484
+ return () => window.removeEventListener("keydown", handleKey);
1485
+ }, [
1486
+ config.isVisible,
1487
+ isOpen,
1488
+ mode,
1489
+ config.enableLauncher,
1490
+ setIsOpen,
1491
+ config.onDismiss
1492
+ ]);
1493
+ const isMac = typeof navigator !== "undefined" && /Mac/.test(navigator.userAgent);
1494
+ const shortcutDisplay = (() => {
1495
+ if (config.keyboardShortcut) {
1496
+ const mods = config.keyboardShortcut.modifiers || [];
1497
+ const keys = [];
1498
+ if (mods.includes("meta")) keys.push(isMac ? "\u2318" : "Win");
1499
+ if (mods.includes("ctrl")) keys.push("Ctrl");
1500
+ if (mods.includes("alt")) keys.push(isMac ? "Opt" : "Alt");
1501
+ if (mods.includes("shift")) keys.push("Shift");
1502
+ keys.push(config.keyboardShortcut.key.toUpperCase());
1503
+ return keys;
1504
+ }
1505
+ return [isMac ? "\u2318" : "Ctrl", "P"];
1506
+ })();
1507
+ const isPending = config.status === "starting";
1508
+ const isSuccess = config.status === "success";
1509
+ const isError = config.status === "error";
1510
+ const showAsSuccess = isSuccess && isShowingInitialSuccessRef.current;
1511
+ const txt = config.textOverrides || {};
1512
+ const titleText = (() => {
1513
+ if (isSuccess) return txt.titleSuccess || "Personalization complete";
1514
+ if (isPending) return "Starting personalization";
1515
+ if (isError) return txt.titleError || "Let's try that again";
1516
+ return config.hasPersonalization ? "Personalization ready" : txt.titleResting || "Personalization available";
1517
+ })();
1518
+ const subtitleText = (() => {
1519
+ if (isSuccess) return txt.subtitleSuccess || "Take a look";
1520
+ if (isPending) return "Hang tight...";
1521
+ if (isError)
1522
+ return txt.subtitleError || "Something went wrong. Tap to retry.";
1523
+ return txt.subtitleResting || "This page can adapt to you";
1524
+ })();
1525
+ const buttonText = (() => {
1526
+ if (isPending) return txt.btnLoading || "Starting...";
1527
+ if (isError) return txt.btnError || "Try again";
1528
+ if (isSuccess && isShowingInitialSuccessRef.current) {
1529
+ return txt.btnSuccess || "Personalised";
1530
+ }
1531
+ if (hasHadSuccessRef.current) {
1532
+ return "Show me again";
1533
+ }
1534
+ return txt.btnResting || "Show me";
1535
+ })();
1536
+ const validateField = /* @__PURE__ */ __name((name, value, fieldConfig) => {
1537
+ if (!fieldConfig) return null;
1538
+ if (fieldConfig.required && !value.trim()) {
1539
+ return fieldConfig.errorMessage || `${fieldConfig.label} is required`;
1540
+ }
1541
+ if (!value) return null;
1542
+ if (fieldConfig.type === "email") {
1543
+ const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
1544
+ if (!emailRegex.test(value)) {
1545
+ return fieldConfig.errorMessage || "Please enter a valid email address";
1546
+ }
1547
+ }
1548
+ if (fieldConfig.type === "url") {
1549
+ try {
1550
+ new URL(value);
1551
+ } catch {
1552
+ return fieldConfig.errorMessage || "Please enter a valid URL (e.g., https://example.com)";
1553
+ }
1554
+ }
1555
+ if (fieldConfig.minLength && value.length < fieldConfig.minLength) {
1556
+ return fieldConfig.errorMessage || `Must be at least ${fieldConfig.minLength} characters`;
1557
+ }
1558
+ if (fieldConfig.maxLength && value.length > fieldConfig.maxLength) {
1559
+ return fieldConfig.errorMessage || `Must be at most ${fieldConfig.maxLength} characters`;
1560
+ }
1561
+ if (fieldConfig.pattern) {
1562
+ const regex = new RegExp(fieldConfig.pattern);
1563
+ if (!regex.test(value)) {
1564
+ return fieldConfig.errorMessage || "Invalid format";
1565
+ }
1566
+ }
1567
+ return null;
1568
+ }, "validateField");
1569
+ const handleSubmit = /* @__PURE__ */ __name((e3) => {
1570
+ e3.preventDefault();
1571
+ if (isPending) return;
1572
+ const formData = new FormData(e3.target);
1573
+ const values = {};
1574
+ const newErrors = {};
1575
+ let hasErrors = false;
1576
+ formData.forEach((value, key) => {
1577
+ const strValue = value.toString();
1578
+ values[key] = strValue;
1579
+ const fieldConfig = config.fields.find((f4) => f4.name === key);
1580
+ const error = validateField(key, strValue, fieldConfig);
1581
+ if (error) {
1582
+ newErrors[key] = error;
1583
+ hasErrors = true;
1584
+ }
1585
+ });
1586
+ if (hasErrors) {
1587
+ setErrors(newErrors);
1588
+ return;
1589
+ }
1590
+ setErrors({});
1591
+ setIsOpen(false);
1592
+ config.onSubmitPersonalization?.(values);
1593
+ }, "handleSubmit");
1594
+ const handleInput = /* @__PURE__ */ __name((e3) => {
1595
+ const target = e3.target;
1596
+ const name = target.name;
1597
+ if (errors[name]) {
1598
+ const fieldConfig = config.fields.find((f4) => f4.name === name);
1599
+ const error = validateField(name, target.value, fieldConfig);
1600
+ setErrors((prev) => {
1601
+ const next = { ...prev };
1602
+ if (error) {
1603
+ next[name] = error;
1604
+ } else {
1605
+ delete next[name];
1606
+ }
1607
+ return next;
1608
+ });
1609
+ }
1610
+ }, "handleInput");
1611
+ const togglePopover = /* @__PURE__ */ __name((e3) => {
1612
+ e3.stopPropagation();
1613
+ if (isPending || isSuccess) return;
1614
+ setIsOpen(!isOpen);
1615
+ }, "togglePopover");
1616
+ y2(() => {
1617
+ if (!timerEnabled) return;
1618
+ if (hasTimerCompletedRef.current) return;
1619
+ const shouldRun = config.isVisible && mode === "card" && config.status === "resting" && !isOpen && !isHovering;
1620
+ if (!shouldRun) {
1621
+ if (timerRafRef.current !== null) {
1622
+ cancelAnimationFrame(timerRafRef.current);
1623
+ timerRafRef.current = null;
1624
+ }
1625
+ timerStartRef.current = null;
1626
+ return;
1627
+ }
1628
+ const tick = /* @__PURE__ */ __name((timestamp) => {
1629
+ if (timerStartRef.current === null) {
1630
+ timerStartRef.current = timestamp - timerProgressRef.current / 100 * timerDuration;
1631
+ }
1632
+ const elapsed = timestamp - timerStartRef.current;
1633
+ const pct = Math.min(1, elapsed / timerDuration);
1634
+ const nextProgress = pct * 100;
1635
+ setTimerProgress(nextProgress);
1636
+ if (pct >= 1) {
1637
+ hasTimerCompletedRef.current = true;
1638
+ timerStartRef.current = null;
1639
+ timerRafRef.current = null;
1640
+ if (config.enableLauncher) {
1641
+ setMode("launcher");
1642
+ setIsOpen(false);
1643
+ } else {
1644
+ config.onDismiss?.();
1645
+ }
1646
+ return;
1647
+ }
1648
+ timerRafRef.current = requestAnimationFrame(tick);
1649
+ }, "tick");
1650
+ timerRafRef.current = requestAnimationFrame(tick);
1651
+ return () => {
1652
+ if (timerRafRef.current !== null) {
1653
+ cancelAnimationFrame(timerRafRef.current);
1654
+ timerRafRef.current = null;
1655
+ }
1656
+ };
1657
+ }, [
1658
+ config.enableLauncher,
1659
+ config.isVisible,
1660
+ config.onDismiss,
1661
+ config.status,
1662
+ isHovering,
1663
+ isOpen,
1664
+ mode,
1665
+ setIsOpen,
1666
+ timerDuration,
1667
+ timerEnabled,
1668
+ setTimerProgress
1669
+ ]);
1670
+ y2(() => {
1671
+ return () => {
1672
+ if (timerRafRef.current !== null) {
1673
+ cancelAnimationFrame(timerRafRef.current);
1674
+ }
1675
+ };
1676
+ }, []);
1677
+ const clampedProgress = Math.max(0, Math.min(100, config.progressPct ?? 0));
1678
+ const displayedProgress = timerEnabled ? timerProgress : clampedProgress;
1679
+ return /* @__PURE__ */ u3(k, { children: [
1680
+ /* @__PURE__ */ u3("div", { ref: backdropRef, class: "backdrop" }),
1681
+ /* @__PURE__ */ u3(
1682
+ "div",
1683
+ {
1684
+ ref: containerRef,
1685
+ class: `container theme-${config.theme || "glass"} pos-${config.position || "top-center"}`,
1686
+ style: getThemeStyles(config.customTheme),
1687
+ onClick: () => !isOpen && !isPending && !isSuccess && setIsOpen(true),
1688
+ onMouseEnter: () => setIsHovering(true),
1689
+ onMouseLeave: () => setIsHovering(false),
1690
+ children: [
1691
+ /* @__PURE__ */ u3(
1692
+ "button",
1693
+ {
1694
+ class: "btn-dismiss",
1695
+ "aria-label": "Dismiss",
1696
+ onClick: (e3) => {
1697
+ e3.stopPropagation();
1698
+ hasTimerCompletedRef.current = true;
1699
+ if (config.enableLauncher) {
1700
+ setMode("launcher");
1701
+ } else {
1702
+ config.onDismiss?.();
1703
+ }
1704
+ },
1705
+ children: /* @__PURE__ */ u3(XMarkIcon, {})
1706
+ }
1707
+ ),
1708
+ /* @__PURE__ */ u3("div", { class: "content-wrapper", children: [
1709
+ /* @__PURE__ */ u3("div", { class: "logo", children: /* @__PURE__ */ u3(LogoIcon, {}) }),
1710
+ /* @__PURE__ */ u3("div", { class: "text-content", children: /* @__PURE__ */ u3("div", { class: "text-row", children: [
1711
+ /* @__PURE__ */ u3("div", { children: [
1712
+ /* @__PURE__ */ u3("div", { class: "title", children: titleText }),
1713
+ /* @__PURE__ */ u3("div", { class: "subtitle", children: subtitleText })
1714
+ ] }),
1715
+ /* @__PURE__ */ u3(
1716
+ "button",
1717
+ {
1718
+ class: `btn btn-trigger ${showAsSuccess ? "success" : ""}`,
1719
+ disabled: isPending || showAsSuccess,
1720
+ onClick: togglePopover,
1721
+ children: isPending ? /* @__PURE__ */ u3(k, { children: [
1722
+ /* @__PURE__ */ u3(LoaderIcon, {}),
1723
+ " ",
1724
+ buttonText
1725
+ ] }) : showAsSuccess ? /* @__PURE__ */ u3(k, { children: [
1726
+ /* @__PURE__ */ u3(CheckIcon, {}),
1727
+ " ",
1728
+ buttonText
1729
+ ] }) : buttonText
1730
+ }
1731
+ )
1732
+ ] }) })
1733
+ ] }),
1734
+ /* @__PURE__ */ u3("div", { class: "progress-clip", children: /* @__PURE__ */ u3("div", { class: "progress-container", children: /* @__PURE__ */ u3(
1735
+ "div",
1736
+ {
1737
+ class: "progress-bar",
1738
+ style: {
1739
+ width: `${displayedProgress}%`
1740
+ }
1741
+ }
1742
+ ) }) }),
1743
+ /* @__PURE__ */ u3(
1744
+ "div",
1745
+ {
1746
+ class: `popover ${isOpen ? "open" : ""}`,
1747
+ onClick: (e3) => e3.stopPropagation(),
1748
+ children: [
1749
+ /* @__PURE__ */ u3("form", { onSubmit: handleSubmit, ref: formRef, children: [
1750
+ config.fields.map((field, idx) => /* @__PURE__ */ u3("div", { class: "form-group", children: [
1751
+ /* @__PURE__ */ u3(
1752
+ "label",
1753
+ {
1754
+ class: `form-label ${errors[field.name] ? "error" : ""}`,
1755
+ children: field.label
1756
+ }
1757
+ ),
1758
+ /* @__PURE__ */ u3("div", { class: "input-row", children: [
1759
+ /* @__PURE__ */ u3(
1760
+ "input",
1761
+ {
1762
+ ref: idx === 0 ? firstInputRef : void 0,
1763
+ class: `form-input ${errors[field.name] ? "error" : ""}`,
1764
+ name: field.name,
1765
+ type: field.type || "text",
1766
+ placeholder: field.placeholder,
1767
+ required: field.required,
1768
+ onInput: handleInput
1769
+ }
1770
+ ),
1771
+ config.fields.length === 1 && /* @__PURE__ */ u3(
1772
+ "button",
1773
+ {
1774
+ type: "submit",
1775
+ class: "btn btn-submit",
1776
+ disabled: isPending,
1777
+ children: isPending ? /* @__PURE__ */ u3(LoaderIcon, {}) : /* @__PURE__ */ u3(ArrowRightIcon, {})
1778
+ }
1779
+ )
1780
+ ] }),
1781
+ errors[field.name] && /* @__PURE__ */ u3("div", { class: "form-message", children: errors[field.name] })
1782
+ ] }, field.name)),
1783
+ config.fields.length > 1 && /* @__PURE__ */ u3(
1784
+ "button",
1785
+ {
1786
+ type: "submit",
1787
+ class: "btn btn-submit",
1788
+ style: { width: "100%" },
1789
+ disabled: isPending,
1790
+ children: isPending ? /* @__PURE__ */ u3(LoaderIcon, {}) : /* @__PURE__ */ u3(ArrowRightIcon, {})
1791
+ }
1792
+ )
1793
+ ] }),
1794
+ config.showWatermark && /* @__PURE__ */ u3("div", { class: "watermark", children: [
1795
+ "Powered by",
1796
+ " ",
1797
+ /* @__PURE__ */ u3(
1798
+ "a",
1799
+ {
1800
+ href: "https://kenobi.ai",
1801
+ target: "_blank",
1802
+ rel: "noopener noreferrer",
1803
+ children: "Kenobi"
1804
+ }
1805
+ )
1806
+ ] })
1807
+ ]
1808
+ }
1809
+ ),
1810
+ config.showKeyboardHints && config.enableFocusMode && /* @__PURE__ */ u3(
1811
+ "div",
1812
+ {
1813
+ class: `kbd-hint ${!isOpen && !isPending && !isSuccess ? "visible" : ""}`,
1814
+ children: [
1815
+ /* @__PURE__ */ u3("div", { class: "kbd-group", children: /* @__PURE__ */ u3("div", { class: "kbd", children: "Esc" }) }),
1816
+ /* @__PURE__ */ u3("span", { class: "kbd-text", children: "to dismiss" })
1817
+ ]
1818
+ }
1819
+ )
1820
+ ]
1821
+ }
1822
+ ),
1823
+ /* @__PURE__ */ u3(
1824
+ "button",
1825
+ {
1826
+ ref: launcherRef,
1827
+ class: `launcher theme-${config.theme || "glass"} pos-${config.position || "top-center"}`,
1828
+ style: getThemeStyles(config.customTheme),
1829
+ onClick: (e3) => {
1830
+ e3.stopPropagation();
1831
+ setMode("card");
1832
+ setIsOpen(true);
1833
+ },
1834
+ children: [
1835
+ /* @__PURE__ */ u3(
1836
+ "div",
1837
+ {
1838
+ style: {
1839
+ display: "flex",
1840
+ width: "20px",
1841
+ height: "20px",
1842
+ overflow: "hidden",
1843
+ alignItems: "center",
1844
+ justifyContent: "center"
1845
+ },
1846
+ children: /* @__PURE__ */ u3("div", { style: { transform: "scale(0.6)" }, children: /* @__PURE__ */ u3(LogoIcon, {}) })
1847
+ }
1848
+ ),
1849
+ config.textOverrides?.launcherLabel || (hasHadSuccessRef.current ? "Personalize again" : "Personalize"),
1850
+ config.showKeyboardHints && /* @__PURE__ */ u3("div", { class: "kbd-hint visible", children: /* @__PURE__ */ u3("div", { class: "kbd-group", children: shortcutDisplay.map((k3, i3) => /* @__PURE__ */ u3("div", { class: "kbd", children: k3 }, i3)) }) })
1851
+ ]
1852
+ }
1853
+ )
1854
+ ] });
1855
+ }, "CueCardContent");
1856
+ var _CueCard = class _CueCard {
1857
+ constructor(config) {
1858
+ __publicField(this, "host");
1859
+ __publicField(this, "shadow");
1860
+ __publicField(this, "config");
1861
+ __publicField(this, "isOpen", false);
1862
+ __publicField(this, "skipFocus", false);
1863
+ __publicField(this, "mountTarget", null);
1864
+ this.config = {
1865
+ position: "top-center",
1866
+ direction: "top-to-bottom",
1867
+ theme: "glass",
1868
+ entranceDelayMs: 0,
1869
+ exitDelayMs: 75,
1870
+ hasPersonalization: false,
1871
+ isVisible: false,
1872
+ progressPct: 0,
1873
+ status: "resting",
1874
+ enableTimer: true,
1875
+ timerDurationMs: 2e4,
1876
+ enableLauncher: true,
1877
+ enableFocusMode: false,
1878
+ focusBlurIntensity: "10px",
1879
+ focusDelayMs: 500,
1880
+ showKeyboardHints: false,
1881
+ showWatermark: true,
1882
+ mountMode: "overlay",
1883
+ ...config
1884
+ };
1885
+ this.mountTarget = config.mountNode ?? null;
1886
+ this.host = document.createElement("div");
1887
+ this.host.id = "kenobi-cue-card-root";
1888
+ this.applyHostStyles();
1889
+ this.shadow = this.host.attachShadow({ mode: "open" });
1890
+ const style = document.createElement("style");
1891
+ style.textContent = STYLES;
1892
+ this.shadow.appendChild(style);
1893
+ const mountPoint = document.createElement("div");
1894
+ this.shadow.appendChild(mountPoint);
1895
+ }
1896
+ applyHostStyles() {
1897
+ const isInline = this.config.mountMode === "inline";
1898
+ this.host.classList.toggle("kb-inline", isInline);
1899
+ if (isInline) {
1900
+ this.host.style.cssText = `
1901
+ position: relative !important;
1902
+ z-index: auto !important;
1903
+ top: auto !important;
1904
+ left: auto !important;
1905
+ width: 100% !important;
1906
+ height: auto !important;
1907
+ pointer-events: auto !important;
1908
+ isolation: auto !important;
1909
+ display: block !important;
1910
+ `;
1911
+ return;
1912
+ }
1913
+ this.host.style.cssText = `
1914
+ position: fixed !important;
1915
+ z-index: 2147483647 !important;
1916
+ top: 0 !important;
1917
+ left: 0 !important;
1918
+ width: 100% !important;
1919
+ height: 0 !important;
1920
+ pointer-events: none !important;
1921
+ isolation: isolate !important;
1922
+ `;
1923
+ }
1924
+ mount(target) {
1925
+ const resolvedTarget = target || this.config.mountNode || this.mountTarget || document.body;
1926
+ this.mountTarget = resolvedTarget;
1927
+ if (!resolvedTarget.contains(this.host)) {
1928
+ resolvedTarget.appendChild(this.host);
1929
+ }
1930
+ this.applyHostStyles();
1931
+ this.render();
1932
+ }
1933
+ unmount() {
1934
+ G(null, this.shadow.lastElementChild);
1935
+ this.host.remove();
1936
+ }
1937
+ update(newState) {
1938
+ this.config = { ...this.config, ...newState };
1939
+ this.applyHostStyles();
1940
+ this.render();
1941
+ }
1942
+ setTheme(theme) {
1943
+ this.update({ theme });
1944
+ }
1945
+ openForm(skipFocus) {
1946
+ this.isOpen = true;
1947
+ this.skipFocus = skipFocus ?? false;
1948
+ this.render();
1949
+ }
1950
+ render() {
1951
+ const mountPoint = this.shadow.lastElementChild;
1952
+ const skipFocusOnce = this.skipFocus;
1953
+ this.skipFocus = false;
1954
+ G(
1955
+ /* @__PURE__ */ u3(
1956
+ CueCardContent,
1957
+ {
1958
+ config: this.config,
1959
+ isOpen: this.isOpen,
1960
+ skipFocus: skipFocusOnce,
1961
+ setIsOpen: (val) => {
1962
+ this.isOpen = val;
1963
+ this.config.onOpenChange?.(val);
1964
+ this.render();
1965
+ }
1966
+ }
1967
+ ),
1968
+ mountPoint
1969
+ );
1970
+ }
1971
+ };
1972
+ __name(_CueCard, "CueCard");
1973
+ var CueCard = _CueCard;
1974
+
1975
+ // src/index.ts
1976
+ var VISITOR_QUERY_PARAM_KEY = "kfor";
1977
+ var VISITOR_SESSION_STORAGE_KEY = "kenobi_visitor_key";
1978
+ var TRANSFORMATION_DATA_ATTR_KEY = "data-kenobi-transformation-identifier";
1979
+ var DEFAULT_TRANSITION_CONFIG = {
1980
+ enabled: false,
1981
+ durationMs: 300,
1982
+ delayMs: 0,
1983
+ easing: "ease",
1984
+ animateSize: true,
1985
+ overflow: "hidden"
1986
+ // Default to hidden for clean size animations; use "visible" for gradient text
1987
+ };
1988
+ var createNormalizedTransitionConfig = /* @__PURE__ */ __name((config) => ({
1989
+ enabled: config?.enabled ?? DEFAULT_TRANSITION_CONFIG.enabled,
1990
+ durationMs: config?.durationMs ?? DEFAULT_TRANSITION_CONFIG.durationMs,
1991
+ delayMs: config?.delayMs ?? DEFAULT_TRANSITION_CONFIG.delayMs,
1992
+ easing: config?.easing ?? DEFAULT_TRANSITION_CONFIG.easing,
1993
+ animateSize: config?.animateSize ?? DEFAULT_TRANSITION_CONFIG.animateSize,
1994
+ overflow: config?.overflow ?? DEFAULT_TRANSITION_CONFIG.overflow,
1995
+ textAnimation: config?.textAnimation,
1996
+ enter: config?.enter,
1997
+ exit: config?.exit
1998
+ }), "createNormalizedTransitionConfig");
1999
+ var mergeTransitionConfig = /* @__PURE__ */ __name((base, override) => ({
2000
+ enabled: override?.enabled ?? base.enabled,
2001
+ durationMs: override?.durationMs ?? base.durationMs,
2002
+ delayMs: override?.delayMs ?? base.delayMs,
2003
+ easing: override?.easing ?? base.easing,
2004
+ animateSize: override?.animateSize ?? base.animateSize,
2005
+ overflow: override?.overflow ?? base.overflow,
2006
+ textAnimation: override?.textAnimation ?? base.textAnimation,
2007
+ enter: override?.enter ?? base.enter,
2008
+ exit: override?.exit ?? base.exit
2009
+ }), "mergeTransitionConfig");
2010
+ var isAnimationName = /* @__PURE__ */ __name((value) => typeof value === "string", "isAnimationName");
2011
+ var isAnimatableElement = /* @__PURE__ */ __name((element) => {
2012
+ if (element instanceof HTMLElement) return true;
2013
+ if (typeof SVGElement !== "undefined" && element instanceof SVGElement)
2014
+ return true;
2015
+ return false;
2016
+ }, "isAnimatableElement");
2017
+ var isEasing = /* @__PURE__ */ __name((value) => typeof value === "string", "isEasing");
2018
+ var isTransitionOverflow = /* @__PURE__ */ __name((value) => value === "hidden" || value === "visible" || value === "clip", "isTransitionOverflow");
2019
+ var isAnimationSplitTarget = /* @__PURE__ */ __name((value) => value === "line" || value === "word" || value === "character", "isAnimationSplitTarget");
2020
+ var isKeyframeDefinition = /* @__PURE__ */ __name((value) => {
2021
+ if (typeof value !== "object" || value === null) return false;
2022
+ if (Array.isArray(value)) {
2023
+ return value.every((item) => typeof item === "object" && item !== null);
2024
+ }
2025
+ return true;
2026
+ }, "isKeyframeDefinition");
2027
+ var isAnimationSettings = /* @__PURE__ */ __name((value) => {
2028
+ if (typeof value !== "object" || value === null) return false;
2029
+ const candidate = value;
2030
+ const { animationName, keyframes, durationMs, delayMs } = candidate;
2031
+ return (animationName === void 0 || isAnimationName(animationName)) && (keyframes === void 0 || isKeyframeDefinition(keyframes)) && (durationMs === void 0 || typeof durationMs === "number") && (delayMs === void 0 || typeof delayMs === "number");
2032
+ }, "isAnimationSettings");
2033
+ var isTextAnimationConfig = /* @__PURE__ */ __name((value) => {
2034
+ if (typeof value !== "object" || value === null) return false;
2035
+ const candidate = value;
2036
+ const { by, staggerMs, animationName, keyframes, delayMs, durationMs } = candidate;
2037
+ return isAnimationSplitTarget(by) && (delayMs === void 0 || typeof delayMs === "number") && (staggerMs === void 0 || typeof staggerMs === "number") && (durationMs === void 0 || typeof durationMs === "number") && (isAnimationName(animationName) || keyframes !== void 0) && (keyframes === void 0 || isKeyframeDefinition(keyframes));
2038
+ }, "isTextAnimationConfig");
2039
+ var isTransitionConfig = /* @__PURE__ */ __name((value) => {
2040
+ if (typeof value !== "object" || value === null) return false;
2041
+ const candidate = value;
2042
+ const {
2043
+ enabled,
2044
+ durationMs,
2045
+ delayMs,
2046
+ easing,
2047
+ animateSize,
2048
+ overflow,
2049
+ textAnimation,
2050
+ enter,
2051
+ exit
2052
+ } = candidate;
2053
+ return (enabled === void 0 || typeof enabled === "boolean") && (durationMs === void 0 || typeof durationMs === "number") && (delayMs === void 0 || typeof delayMs === "number") && (easing === void 0 || isEasing(easing)) && (animateSize === void 0 || typeof animateSize === "boolean") && (overflow === void 0 || isTransitionOverflow(overflow)) && (textAnimation === void 0 || isTextAnimationConfig(textAnimation)) && (enter === void 0 || isAnimationSettings(enter)) && (exit === void 0 || isAnimationSettings(exit));
2054
+ }, "isTransitionConfig");
2055
+ var _TransitionOrchestrator = class _TransitionOrchestrator {
2056
+ constructor() {
2057
+ /**
2058
+ * Replaces an existing element with a new one, applying coordinated enter,
2059
+ * exit, and size animations.
2060
+ *
2061
+ * The process involves creating a temporary wrapper to contain the animations,
2062
+ * measuring the new element's dimensions without causing layout shifts, and
2063
+ * then running all animations in parallel. Once complete, the wrapper is
2064
+ * replaced by the new element.
2065
+ *
2066
+ * @param oldElement The original element to be replaced.
2067
+ * @param newMarkup The HTML string for the new element.
2068
+ * @param config The transition configuration object.
2069
+ * @returns A promise that resolves with the new element after the transition completes.
2070
+ */
2071
+ __publicField(this, "replaceWithTransition", /* @__PURE__ */ __name(async (oldElement, newMarkup, config) => {
2072
+ const wrapper = document.createElement("div");
2073
+ wrapper.style.position = "relative";
2074
+ wrapper.style.overflow = config.overflow;
2075
+ const oldRect = oldElement.getBoundingClientRect();
2076
+ const oldStyle = window.getComputedStyle(oldElement);
2077
+ wrapper.style.display = oldStyle.display;
2078
+ wrapper.style.verticalAlign = oldStyle.verticalAlign;
2079
+ wrapper.style.width = `${oldRect.width}px`;
2080
+ wrapper.style.height = `${oldRect.height}px`;
2081
+ wrapper.style.margin = oldStyle.margin;
2082
+ const oldElClone = oldElement.cloneNode(true);
2083
+ if (!(oldElClone instanceof Element) || !isAnimatableElement(oldElClone)) {
2084
+ throw new Error("oldElClone is not an AnimatableElement");
2085
+ }
2086
+ oldElClone.style.position = "absolute";
2087
+ oldElClone.style.top = "0";
2088
+ oldElClone.style.left = "0";
2089
+ oldElClone.style.width = "100%";
2090
+ oldElClone.style.height = "100%";
2091
+ oldElClone.style.margin = "0";
2092
+ oldElClone.style.pointerEvents = "none";
2093
+ wrapper.appendChild(oldElClone);
2094
+ const tempContainer = document.createElement("div");
2095
+ tempContainer.innerHTML = newMarkup;
2096
+ const newElement = tempContainer.firstElementChild;
2097
+ if (!newElement || !(newElement instanceof HTMLElement || newElement instanceof SVGElement)) {
2098
+ const exitAnim2 = this.exit(oldElement, config);
2099
+ await exitAnim2.finished;
2100
+ return oldElement;
2101
+ }
2102
+ const originalStyle = newElement.style.cssText;
2103
+ const parent = oldElement.parentNode;
2104
+ let newRect;
2105
+ if (parent instanceof HTMLElement) {
2106
+ const parentClone = parent.cloneNode(false);
2107
+ const parentStyles = window.getComputedStyle(parent);
2108
+ const cssText = parentStyles.cssText ? parentStyles.cssText : Array.from(parentStyles).reduce(
2109
+ (str, prop) => `${str}${prop}:${parentStyles.getPropertyValue(prop)};`,
2110
+ ""
2111
+ );
2112
+ parentClone.style.cssText = cssText;
2113
+ parentClone.style.position = "absolute";
2114
+ parentClone.style.top = "-9999px";
2115
+ parentClone.style.left = "-9999px";
2116
+ parentClone.style.visibility = "hidden";
2117
+ parentClone.style.pointerEvents = "none";
2118
+ parentClone.appendChild(newElement);
2119
+ document.body.appendChild(parentClone);
2120
+ if (config.textAnimation) {
2121
+ this.applyTextAnimationToNode(newElement, config.textAnimation, config);
2122
+ }
2123
+ newRect = newElement.getBoundingClientRect();
2124
+ document.body.removeChild(parentClone);
2125
+ } else {
2126
+ const offscreenContainer = document.createElement("div");
2127
+ offscreenContainer.style.position = "absolute";
2128
+ offscreenContainer.style.top = "-9999px";
2129
+ offscreenContainer.style.left = "-9999px";
2130
+ offscreenContainer.style.visibility = "hidden";
2131
+ offscreenContainer.appendChild(newElement);
2132
+ document.body.appendChild(offscreenContainer);
2133
+ if (config.textAnimation) {
2134
+ this.applyTextAnimationToNode(newElement, config.textAnimation, config);
2135
+ }
2136
+ newRect = newElement.getBoundingClientRect();
2137
+ document.body.removeChild(offscreenContainer);
2138
+ }
2139
+ newElement.style.cssText = originalStyle;
2140
+ newElement.style.visibility = "";
2141
+ newElement.style.position = "absolute";
2142
+ newElement.style.top = "0";
2143
+ newElement.style.left = "0";
2144
+ newElement.style.width = `${newRect.width}px`;
2145
+ newElement.style.height = `${newRect.height}px`;
2146
+ newElement.style.margin = "0";
2147
+ newElement.style.opacity = "0";
2148
+ wrapper.appendChild(newElement);
2149
+ oldElement.replaceWith(wrapper);
2150
+ const exitDelay = config.exit?.delayMs ?? config.delayMs;
2151
+ const exitDuration = config.exit?.durationMs ?? config.durationMs;
2152
+ const enterDelay = config.enter?.delayMs ?? config.delayMs;
2153
+ const enterDuration = config.enter?.durationMs ?? config.durationMs;
2154
+ const animations = [];
2155
+ const exitKeyframes = this.resolveKeyframes(config.exit?.keyframes);
2156
+ const exitAnim = oldElClone.animate(exitKeyframes, {
2157
+ duration: exitDuration,
2158
+ delay: exitDelay,
2159
+ easing: config.easing,
2160
+ fill: "forwards"
2161
+ });
2162
+ animations.push(exitAnim);
2163
+ const enterKeyframes = this.resolveKeyframes(config.enter?.keyframes);
2164
+ const enterAnim = newElement.animate(enterKeyframes, {
2165
+ duration: enterDuration,
2166
+ delay: enterDelay,
2167
+ easing: config.easing,
2168
+ fill: "forwards"
2169
+ });
2170
+ animations.push(enterAnim);
2171
+ if (config.animateSize) {
2172
+ const sizeAnim = wrapper.animate(
2173
+ [
2174
+ { width: `${oldRect.width}px`, height: `${oldRect.height}px` },
2175
+ { width: `${newRect.width}px`, height: `${newRect.height}px` }
2176
+ ],
2177
+ {
2178
+ duration: enterDuration,
2179
+ // Match the enter animation
2180
+ delay: enterDelay,
2181
+ easing: config.easing,
2182
+ fill: "forwards"
2183
+ }
2184
+ );
2185
+ animations.push(sizeAnim);
2186
+ }
2187
+ await Promise.all(animations.map((a3) => a3.finished));
2188
+ if (wrapper.parentNode) {
2189
+ wrapper.replaceWith(newElement);
2190
+ }
2191
+ newElement.style.cssText = originalStyle;
2192
+ oldElClone.remove();
2193
+ return newElement;
2194
+ }, "replaceWithTransition"));
2195
+ /**
2196
+ * Triggers an enter animation on a given element.
2197
+ * @param element The element to animate.
2198
+ * @param config The transition configuration.
2199
+ * @returns The Animation object for the enter transition.
2200
+ */
2201
+ __publicField(this, "enter", /* @__PURE__ */ __name((element, config) => {
2202
+ const enterDelay = config.enter?.delayMs ?? config.delayMs;
2203
+ const enterDuration = config.enter?.durationMs ?? config.durationMs;
2204
+ const keyframes = this.resolveKeyframes(config.enter?.keyframes);
2205
+ return element.animate(keyframes, {
2206
+ duration: enterDuration,
2207
+ delay: enterDelay,
2208
+ easing: config.easing,
2209
+ fill: "forwards"
2210
+ });
2211
+ }, "enter"));
2212
+ /**
2213
+ * Triggers an exit animation on a given element.
2214
+ * @param element The element to animate.
2215
+ * @param config The transition configuration.
2216
+ * @returns The Animation object for the exit transition.
2217
+ */
2218
+ __publicField(this, "exit", /* @__PURE__ */ __name((element, config) => {
2219
+ const exitDelay = config.exit?.delayMs ?? config.delayMs;
2220
+ const exitDuration = config.exit?.durationMs ?? config.durationMs;
2221
+ const keyframes = this.resolveKeyframes(config.exit?.keyframes);
2222
+ return element.animate(keyframes, {
2223
+ duration: exitDuration,
2224
+ delay: exitDelay,
2225
+ easing: config.easing,
2226
+ fill: "forwards"
2227
+ });
2228
+ }, "exit"));
2229
+ /**
2230
+ * Resolves the keyframes to be used for an animation, prioritizing custom
2231
+ * definitions over presets.
2232
+ * @param definition An optional custom keyframe definition.
2233
+ * @returns An array of keyframes for use with WAAPI.
2234
+ */
2235
+ __publicField(this, "resolveKeyframes", /* @__PURE__ */ __name((definition) => {
2236
+ if (definition) {
2237
+ return Array.isArray(definition) ? definition : [definition];
2238
+ }
2239
+ return [];
2240
+ }, "resolveKeyframes"));
2241
+ /**
2242
+ * Traverses a DOM node to find text nodes and applies a staggered animation
2243
+ * to them by splitting the text into lines, words, or characters.
2244
+ *
2245
+ * Each segment is wrapped in a `<span>` and animated individually to create
2246
+ * a "typewriter" or "reveal" effect.
2247
+ *
2248
+ * @param element The root element to traverse for text nodes.
2249
+ * @param config The text animation configuration.
2250
+ * @param transitionConfig The parent transition configuration for timing.
2251
+ */
2252
+ __publicField(this, "applyTextAnimationToNode", /* @__PURE__ */ __name((element, config, transitionConfig) => {
2253
+ const initialDelay = config.delayMs ?? 0;
2254
+ const computedStyle = window.getComputedStyle(element);
2255
+ const isBackgroundClippedToText = computedStyle.getPropertyValue("background-clip") === "text" || computedStyle.getPropertyValue("-webkit-background-clip") === "text";
2256
+ const traverseAndAnimate = /* @__PURE__ */ __name((node, currentDelay, isBackgroundClippedToText2) => {
2257
+ if (node.nodeType === Node.TEXT_NODE) {
2258
+ const text = node.textContent ?? "";
2259
+ if (text.trim().length === 0) {
2260
+ return currentDelay;
2261
+ }
2262
+ if (config.by === "character") {
2263
+ const words = text.split(/(\s+)/);
2264
+ const fragment2 = document.createDocumentFragment();
2265
+ let delay2 = currentDelay;
2266
+ words.forEach((word) => {
2267
+ if (word.length === 0) return;
2268
+ if (word.trim().length === 0) {
2269
+ fragment2.appendChild(document.createTextNode(word));
2270
+ return;
2271
+ }
2272
+ const wordWrapper = document.createElement("span");
2273
+ wordWrapper.style.display = "inline-block";
2274
+ wordWrapper.style.whiteSpace = "nowrap";
2275
+ if (isBackgroundClippedToText2) {
2276
+ wordWrapper.style.setProperty("background", "inherit");
2277
+ wordWrapper.style.setProperty("-webkit-background-clip", "text");
2278
+ wordWrapper.style.setProperty("background-clip", "text");
2279
+ wordWrapper.style.setProperty("color", "transparent");
2280
+ }
2281
+ const chars = word.split("");
2282
+ chars.forEach((char) => {
2283
+ const span = document.createElement("span");
2284
+ span.textContent = char;
2285
+ span.style.display = "inline-block";
2286
+ span.style.opacity = "0";
2287
+ if (isBackgroundClippedToText2) {
2288
+ span.style.setProperty("background", "inherit");
2289
+ span.style.setProperty("-webkit-background-clip", "text");
2290
+ span.style.setProperty("background-clip", "text");
2291
+ span.style.setProperty("color", "transparent");
2292
+ span.style.paddingBottom = "0.1em";
2293
+ span.style.marginBottom = "-0.1em";
2294
+ }
2295
+ const keyframes = this.resolveKeyframes(config.keyframes);
2296
+ const duration = config.durationMs ?? transitionConfig.durationMs ?? 300;
2297
+ const easing = transitionConfig.easing ?? "ease";
2298
+ const animation = span.animate(keyframes, {
2299
+ duration,
2300
+ easing,
2301
+ delay: delay2,
2302
+ fill: "forwards"
2303
+ });
2304
+ animation.addEventListener("finish", () => {
2305
+ animation.commitStyles();
2306
+ animation.cancel();
2307
+ });
2308
+ wordWrapper.appendChild(span);
2309
+ delay2 += config.staggerMs ?? 50;
2310
+ });
2311
+ fragment2.appendChild(wordWrapper);
2312
+ });
2313
+ node.parentNode?.replaceChild(fragment2, node);
2314
+ return delay2;
2315
+ }
2316
+ let segments;
2317
+ switch (config.by) {
2318
+ case "word":
2319
+ segments = text.split(/(\s+)/);
2320
+ break;
2321
+ case "line":
2322
+ segments = text.split("\n");
2323
+ break;
2324
+ default:
2325
+ segments = text.split("");
2326
+ }
2327
+ const fragment = document.createDocumentFragment();
2328
+ let delay = currentDelay;
2329
+ segments.forEach((segment) => {
2330
+ if (segment.length === 0) return;
2331
+ const isWhitespace = segment.trim().length === 0;
2332
+ if (isWhitespace) {
2333
+ fragment.appendChild(document.createTextNode(segment));
2334
+ return;
2335
+ }
2336
+ const span = document.createElement("span");
2337
+ span.textContent = segment;
2338
+ span.style.display = "inline-block";
2339
+ span.style.opacity = "0";
2340
+ if (isBackgroundClippedToText2) {
2341
+ span.style.setProperty("background", "inherit");
2342
+ span.style.setProperty("-webkit-background-clip", "text");
2343
+ span.style.setProperty("background-clip", "text");
2344
+ span.style.setProperty("color", "transparent");
2345
+ span.style.setProperty("will-change", "opacity, transform");
2346
+ }
2347
+ const keyframes = this.resolveKeyframes(config.keyframes);
2348
+ const duration = config.durationMs ?? transitionConfig.durationMs ?? 300;
2349
+ const easing = transitionConfig.easing ?? "ease";
2350
+ const animation = span.animate(keyframes, {
2351
+ duration,
2352
+ easing,
2353
+ delay,
2354
+ fill: "forwards"
2355
+ });
2356
+ animation.addEventListener("finish", () => {
2357
+ animation.commitStyles();
2358
+ animation.cancel();
2359
+ });
2360
+ fragment.appendChild(span);
2361
+ delay += config.staggerMs ?? 50;
2362
+ });
2363
+ node.parentNode?.replaceChild(fragment, node);
2364
+ return delay;
2365
+ }
2366
+ if (node.nodeType === Node.ELEMENT_NODE) {
2367
+ let delay = currentDelay;
2368
+ const children = Array.from(node.childNodes);
2369
+ for (const child of children) {
2370
+ delay = traverseAndAnimate(child, delay, isBackgroundClippedToText2);
2371
+ }
2372
+ return delay;
2373
+ }
2374
+ return currentDelay;
2375
+ }, "traverseAndAnimate");
2376
+ traverseAndAnimate(element, initialDelay, isBackgroundClippedToText);
2377
+ }, "applyTextAnimationToNode"));
2378
+ }
2379
+ };
2380
+ __name(_TransitionOrchestrator, "TransitionOrchestrator");
2381
+ var TransitionOrchestrator = _TransitionOrchestrator;
2382
+ var TRANSFORMATION_ACTIONS = /* @__PURE__ */ new Set(["Replace", "InsertBefore", "InsertAfter", "Delete", "SetFormField"]);
2383
+ var isString = /* @__PURE__ */ __name((value) => typeof value === "string", "isString");
2384
+ var isStringArray = /* @__PURE__ */ __name((value) => Array.isArray(value) && value.every((item) => isString(item)), "isStringArray");
2385
+ var isTransformationAction = /* @__PURE__ */ __name((value) => typeof value === "string" && TRANSFORMATION_ACTIONS.has(value), "isTransformationAction");
2386
+ var isTransformation = /* @__PURE__ */ __name((value) => {
2387
+ if (typeof value !== "object" || value === null) return false;
2388
+ const candidate = value;
2389
+ return isString(candidate.identifier) && typeof candidate.markup === "string" && isStringArray(candidate.selectorGuesses) && isTransformationAction(candidate.action) && (candidate.transition === void 0 || isTransitionConfig(candidate.transition));
2390
+ }, "isTransformation");
2391
+ var parseTransformationsResponse = /* @__PURE__ */ __name((payload) => {
2392
+ if (typeof payload !== "object" || payload === null) {
2393
+ throw new Error("Invalid response: expected object with data array");
2394
+ }
2395
+ const data = payload.data;
2396
+ if (!Array.isArray(data)) {
2397
+ throw new Error("Invalid response: data must be an array");
2398
+ }
2399
+ data.forEach((item, index) => {
2400
+ if (!isTransformation(item)) {
2401
+ throw new Error(`Invalid transformation at index ${index}`);
2402
+ }
2403
+ });
2404
+ return data;
2405
+ }, "parseTransformationsResponse");
2406
+ var _Kenobi = class _Kenobi {
2407
+ constructor(config) {
2408
+ __publicField(this, "config");
2409
+ __publicField(this, "changeStack", /* @__PURE__ */ new Map());
2410
+ __publicField(this, "visitorKey", null);
2411
+ __publicField(this, "orchestrator");
2412
+ __publicField(this, "cueCardInstance", null);
2413
+ //
2414
+ __publicField(this, "currentPath");
2415
+ __publicField(this, "currentUrl");
2416
+ __publicField(this, "navTicking", false);
2417
+ __publicField(this, "transitionDefaults");
2418
+ __publicField(this, "startAutoTransform", /* @__PURE__ */ __name(async () => {
2419
+ try {
2420
+ this.syncChangeStack();
2421
+ await this.waitForLoaded();
2422
+ if (this.isFramer()) {
2423
+ await this.waitForFrames();
2424
+ await this.waitForIdle();
2425
+ await this.waitForQuietDom(100, 1e3);
2426
+ }
2427
+ await this.transform();
2428
+ } catch (error) {
2429
+ this.log("error", "Auto-transformation flow failed with error:", error);
2430
+ }
2431
+ }, "startAutoTransform"));
2432
+ __publicField(this, "transform", /* @__PURE__ */ __name(async () => {
2433
+ try {
2434
+ const startTime = /* @__PURE__ */ new Date();
2435
+ this.log("debug", "Starting transform");
2436
+ if (this.visitorKey === null) {
2437
+ this.log(
2438
+ "debug",
2439
+ `Couldn't find a visitor copy external ID with query param key "${VISITOR_QUERY_PARAM_KEY}"`,
2440
+ "Exiting..."
2441
+ );
2442
+ return;
2443
+ }
2444
+ let transformations = [];
2445
+ try {
2446
+ transformations = await this.getTransformations(
2447
+ this.currentPath,
2448
+ this.visitorKey
2449
+ );
2450
+ } catch (error) {
2451
+ this.log(
2452
+ "error_detailed",
2453
+ "An error occurred _getting_ transformations",
2454
+ error
2455
+ );
2456
+ }
2457
+ try {
2458
+ await this.applyTransformations(transformations);
2459
+ } catch (error) {
2460
+ this.log(
2461
+ "error_detailed",
2462
+ "An error occurred _applying_ transformations",
2463
+ error
2464
+ );
2465
+ }
2466
+ const endTime = /* @__PURE__ */ new Date();
2467
+ const fnDuration = this.getDurationInMilliseconds(startTime, endTime);
2468
+ this.log(
2469
+ "debug",
2470
+ `Transformation complete, took ${this.formatThousands(fnDuration)} ms`
2471
+ );
2472
+ } catch (error) {
2473
+ this.log(
2474
+ "error",
2475
+ "An unexpected, top-level error occurred during transformation",
2476
+ error
2477
+ );
2478
+ }
2479
+ }, "transform"));
2480
+ /*
2481
+ ----
2482
+ -- UTILITIES
2483
+ ----
2484
+ */
2485
+ __publicField(this, "log", /* @__PURE__ */ __name((level, message, ...rest) => {
2486
+ const version = typeof window.__KENOBI_VERSION__ !== "undefined" ? window.__KENOBI_VERSION__ : "dev";
2487
+ const masthead = `[Kenobi \u25D4] (v${version})`;
2488
+ const text = `${masthead} [${level.toLocaleUpperCase()}] :: ${message}`;
2489
+ switch (level) {
2490
+ case "debug":
2491
+ if (this.config.debug) console.log(text, ...rest);
2492
+ break;
2493
+ case "info":
2494
+ console.log(text, ...rest);
2495
+ break;
2496
+ case "warn":
2497
+ console.warn(text, ...rest);
2498
+ break;
2499
+ case "error_detailed":
2500
+ console.trace(...rest);
2501
+ // fallthrough
2502
+ case "error":
2503
+ console.error(text, ...rest);
2504
+ break;
2505
+ }
2506
+ }, "log"));
2507
+ __publicField(this, "resolveTransitionConfig", /* @__PURE__ */ __name((override) => mergeTransitionConfig(this.transitionDefaults, override), "resolveTransitionConfig"));
2508
+ __publicField(this, "retrieveElement", /* @__PURE__ */ __name((selectorGuesses) => {
2509
+ if (!Array.isArray(selectorGuesses) || selectorGuesses.some((s3) => typeof s3 !== "string")) {
2510
+ throw new Error(
2511
+ `Invalid selectorGuesses payload received: expected array of strings but got ${JSON.stringify(
2512
+ selectorGuesses
2513
+ )}`
2514
+ );
2515
+ }
2516
+ for (const selector of selectorGuesses) {
2517
+ const candidates = document.querySelectorAll(selector);
2518
+ if (candidates.length === 0) continue;
2519
+ if (candidates.length === 1) return candidates[0];
2520
+ const visible = Array.from(candidates).filter((el) => {
2521
+ const rect = el.getBoundingClientRect();
2522
+ const style = getComputedStyle(el);
2523
+ return style.display !== "none" && style.visibility !== "hidden" && rect.width > 0 && rect.height > 0;
2524
+ });
2525
+ if (visible.length === 0) continue;
2526
+ const sorted = visible.sort(
2527
+ (a3, b) => a3.getBoundingClientRect().top - b.getBoundingClientRect().top
2528
+ );
2529
+ this.log(
2530
+ "debug",
2531
+ `Selector "${selector}" matched ${candidates.length} elements, selected topmost visible one at y=${sorted[0].getBoundingClientRect().top}`
2532
+ );
2533
+ return sorted[0];
2534
+ }
2535
+ throw new Error(
2536
+ `Could not find an element in the document with any of these selector patterns: ${selectorGuesses.join(
2537
+ ", "
2538
+ )}`
2539
+ );
2540
+ }, "retrieveElement"));
2541
+ __publicField(this, "getQueryParam", /* @__PURE__ */ __name((key) => {
2542
+ const searchParams = new URLSearchParams(window.location.search);
2543
+ return searchParams.get(key);
2544
+ }, "getQueryParam"));
2545
+ __publicField(this, "getCurrentPath", /* @__PURE__ */ __name(() => window.location.pathname, "getCurrentPath"));
2546
+ __publicField(this, "getCurrentUrl", /* @__PURE__ */ __name(() => window.location.pathname + window.location.search + window.location.hash, "getCurrentUrl"));
2547
+ __publicField(this, "getDurationInMilliseconds", /* @__PURE__ */ __name((start, end) => +end - +start, "getDurationInMilliseconds"));
2548
+ __publicField(this, "formatThousands", /* @__PURE__ */ __name((number) => new Intl.NumberFormat("en-US").format(number), "formatThousands"));
2549
+ __publicField(this, "setDebug", /* @__PURE__ */ __name((value) => this.config.debug = value, "setDebug"));
2550
+ __publicField(this, "isInputElement", /* @__PURE__ */ __name((el) => {
2551
+ if (!(el instanceof HTMLInputElement) && !(el instanceof HTMLTextAreaElement) && !(el instanceof HTMLSelectElement))
2552
+ return false;
2553
+ return true;
2554
+ }, "isInputElement"));
2555
+ /*
2556
+ ----
2557
+ -- UTILITIES // PAGE WAITING
2558
+ ----
2559
+ */
2560
+ __publicField(this, "waitForFrames", /* @__PURE__ */ __name(() => (
2561
+ // waits 2 animation frames
2562
+ new Promise((r3) => requestAnimationFrame(() => requestAnimationFrame(r3)))
2563
+ ), "waitForFrames"));
2564
+ __publicField(this, "waitForIdle", /* @__PURE__ */ __name((timeout = 1e3) => {
2565
+ return new Promise(
2566
+ (r3) => "requestIdleCallback" in window ? window.requestIdleCallback(() => r3(), { timeout }) : setTimeout(r3, 50)
2567
+ );
2568
+ }, "waitForIdle"));
2569
+ __publicField(this, "waitForLoaded", /* @__PURE__ */ __name(() => {
2570
+ if (document.readyState === "complete") return Promise.resolve();
2571
+ return new Promise(
2572
+ (r3) => window.addEventListener("load", () => r3(), { once: true })
2573
+ );
2574
+ }, "waitForLoaded"));
2575
+ __publicField(this, "waitForQuietDom", /* @__PURE__ */ __name((maxWaitMs, quietMs) => {
2576
+ return new Promise((resolve) => {
2577
+ let last = performance.now();
2578
+ const mo = new MutationObserver(() => {
2579
+ last = performance.now();
2580
+ });
2581
+ mo.observe(document.documentElement, {
2582
+ subtree: true,
2583
+ childList: true,
2584
+ attributes: true,
2585
+ characterData: true
2586
+ });
2587
+ const deadline = performance.now() + maxWaitMs;
2588
+ (/* @__PURE__ */ __name((function tick() {
2589
+ const now = performance.now();
2590
+ if (now - last >= quietMs) {
2591
+ mo.disconnect();
2592
+ resolve();
2593
+ return;
2594
+ }
2595
+ if (now >= deadline) {
2596
+ mo.disconnect();
2597
+ resolve();
2598
+ return;
2599
+ }
2600
+ requestAnimationFrame(tick);
2601
+ }), "tick"))();
2602
+ });
2603
+ }, "waitForQuietDom"));
2604
+ /*
2605
+ ----
2606
+ -- UTILITIES // PLATFORMS
2607
+ ----
2608
+ */
2609
+ __publicField(this, "isFramer", /* @__PURE__ */ __name(() => {
2610
+ const scripts = Array.from(document.scripts).map((s3) => s3.src || "");
2611
+ const conditions = [
2612
+ "__framer_events" in window,
2613
+ document.querySelector(
2614
+ "[data-framer-root],[data-framer-component],[data-framer-page]"
2615
+ ),
2616
+ scripts.some((src) => /framerusercontent\.com\/sites/i.test(src))
2617
+ ];
2618
+ return conditions.some((c3) => !!c3);
2619
+ }, "isFramer"));
2620
+ /*
2621
+ ----
2622
+ -- VISITOR STATE MANAGEMENT
2623
+ ----
2624
+ */
2625
+ __publicField(this, "syncVisitorKey", /* @__PURE__ */ __name(() => {
2626
+ try {
2627
+ const queryParamValue = this.getQueryParam(VISITOR_QUERY_PARAM_KEY);
2628
+ if (queryParamValue) {
2629
+ this.log(
2630
+ "debug",
2631
+ `Query param value found (${queryParamValue}), pushing into session storage`
2632
+ );
2633
+ sessionStorage.setItem(VISITOR_SESSION_STORAGE_KEY, queryParamValue);
2634
+ this.visitorKey = queryParamValue;
2635
+ } else {
2636
+ this.visitorKey = sessionStorage.getItem(VISITOR_SESSION_STORAGE_KEY);
2637
+ }
2638
+ } catch (error) {
2639
+ this.log("error", "Failed to sync visitor key with error:", error);
2640
+ }
2641
+ }, "syncVisitorKey"));
2642
+ __publicField(this, "initNavigationListener", /* @__PURE__ */ __name(() => {
2643
+ if ("__KENOBI_NAV_HOOKED__" in window) return;
2644
+ window.__KENOBI_NAV_HOOKED__ = true;
2645
+ const schedule = /* @__PURE__ */ __name((src) => {
2646
+ if (this.navTicking) return;
2647
+ this.navTicking = true;
2648
+ queueMicrotask(() => {
2649
+ this.navTicking = false;
2650
+ const nextUrl = this.getCurrentUrl();
2651
+ if (nextUrl !== this.currentUrl) {
2652
+ this.currentUrl = nextUrl;
2653
+ this.currentPath = this.getCurrentPath();
2654
+ this.log("debug", `URL changed (${src}) \u2192 ${location.href}`);
2655
+ if (this.config.autoTransform) {
2656
+ this.undoAll();
2657
+ void this.startAutoTransform();
2658
+ }
2659
+ }
2660
+ });
2661
+ }, "schedule");
2662
+ if ("navigation" in window) {
2663
+ const nav = window.navigation;
2664
+ if (nav && "addEventListener" in nav && typeof nav.addEventListener === "function") {
2665
+ nav.addEventListener("navigate", () => schedule("navigation:navigate"));
2666
+ nav.addEventListener(
2667
+ "currententrychange",
2668
+ () => schedule("navigation:entrychange")
2669
+ );
2670
+ nav.addEventListener?.(
2671
+ "navigatesuccess",
2672
+ () => schedule("navigation:success")
2673
+ );
2674
+ }
2675
+ }
2676
+ const origPush = history.pushState.bind(history);
2677
+ const origRepl = history.replaceState.bind(history);
2678
+ history.pushState = ((...args) => {
2679
+ const ret = origPush(...args);
2680
+ schedule("pushState");
2681
+ return ret;
2682
+ });
2683
+ history.replaceState = ((...args) => {
2684
+ const ret = origRepl(...args);
2685
+ schedule("replaceState");
2686
+ return ret;
2687
+ });
2688
+ window.addEventListener("popstate", () => schedule("popstate"));
2689
+ window.addEventListener("hashchange", () => schedule("hashchange"));
2690
+ document.addEventListener(
2691
+ "click",
2692
+ (e3) => {
2693
+ const t3 = e3.target;
2694
+ const a3 = t3 && t3.closest?.("a[href]");
2695
+ if (!a3) return;
2696
+ if (a3.target && a3.target !== "_self") return;
2697
+ const url = new URL(a3.href, location.href);
2698
+ if (url.origin !== location.origin) return;
2699
+ setTimeout(() => schedule("click"), 0);
2700
+ },
2701
+ true
2702
+ );
2703
+ setInterval(() => {
2704
+ const next = this.getCurrentUrl();
2705
+ if (next !== this.currentUrl) schedule("poll");
2706
+ }, 1e3);
2707
+ }, "initNavigationListener"));
2708
+ /*
2709
+ ----
2710
+ -- DATA RETRIEVAL
2711
+ ----
2712
+ */
2713
+ __publicField(this, "getTransformations", /* @__PURE__ */ __name(async (path, visitorCopyId) => {
2714
+ const searchParams = new URLSearchParams({
2715
+ path
2716
+ // siteId: this.config.siteId,
2717
+ // publicKey: this.config.publicKey,
2718
+ });
2719
+ const rawResponse = await fetch(
2720
+ `${this.config.apiHost}/v1/visitor-copy-transformations/${visitorCopyId}?${searchParams.toString()}`
2721
+ );
2722
+ const responseJson = await rawResponse.json();
2723
+ if (!rawResponse.ok) {
2724
+ throw new Error(
2725
+ `Network error (status ${rawResponse.status}) with json body: ${JSON.stringify(responseJson, null, 2)}`
2726
+ );
2727
+ }
2728
+ return parseTransformationsResponse(responseJson);
2729
+ }, "getTransformations"));
2730
+ __publicField(this, "validateTransitionPreconditions", /* @__PURE__ */ __name((identifier, markup, transitionConfig) => {
2731
+ if (transitionConfig.enabled) {
2732
+ const tempContainer = document.createElement("div");
2733
+ tempContainer.innerHTML = markup;
2734
+ const prospectiveElement = tempContainer.firstElementChild;
2735
+ if (!prospectiveElement || !isAnimatableElement(prospectiveElement)) {
2736
+ this.log(
2737
+ "warn",
2738
+ `Transformation "${identifier}" was skipped: A transition was requested, but the element is not animatable.`
2739
+ );
2740
+ return false;
2741
+ }
2742
+ }
2743
+ return true;
2744
+ }, "validateTransitionPreconditions"));
2745
+ /*
2746
+ ----
2747
+ -- DOM + TRANSFORMATION MANIPULATION
2748
+ ----
2749
+ */
2750
+ __publicField(this, "applyTransformations", /* @__PURE__ */ __name(async (transformations, opts) => {
2751
+ this.log("debug", `Starting ${transformations.length} transformations`);
2752
+ if (opts?.shouldConsolidate) {
2753
+ this.changeStack.forEach((_2, key) => {
2754
+ const matchingTransformation = transformations.find(
2755
+ (tran) => tran.identifier === key
2756
+ );
2757
+ if (matchingTransformation) {
2758
+ this.undo(key);
2759
+ }
2760
+ });
2761
+ }
2762
+ for (const { identifier, ...transformation } of transformations) {
2763
+ try {
2764
+ if (this.changeStack.get(identifier)) {
2765
+ throw new Error("Transformation already exists in stack");
2766
+ }
2767
+ const cursor = this.retrieveElement(transformation.selectorGuesses);
2768
+ switch (transformation.action) {
2769
+ case "Replace": {
2770
+ const originalOuterHtml = cursor.outerHTML;
2771
+ const transitionConfig = this.resolveTransitionConfig(
2772
+ transformation.transition
2773
+ );
2774
+ if (transitionConfig.enabled && isAnimatableElement(cursor) && "animate" in cursor) {
2775
+ const newElement = await this.orchestrator.replaceWithTransition(
2776
+ cursor,
2777
+ transformation.markup,
2778
+ transitionConfig
2779
+ );
2780
+ this.setOrUpdateReplaceChangeRef(
2781
+ identifier,
2782
+ originalOuterHtml,
2783
+ newElement
2784
+ );
2785
+ } else {
2786
+ morphdom_esm_default(cursor, transformation.markup, {});
2787
+ this.setOrUpdateReplaceChangeRef(
2788
+ identifier,
2789
+ originalOuterHtml,
2790
+ cursor
2791
+ );
2792
+ }
2793
+ if (cursor.nodeName === "VIDEO")
2794
+ cursor.play();
2795
+ break;
2796
+ }
2797
+ case "InsertBefore": {
2798
+ const transitionConfig = this.resolveTransitionConfig(
2799
+ transformation.transition
2800
+ );
2801
+ if (!this.validateTransitionPreconditions(
2802
+ identifier,
2803
+ transformation.markup,
2804
+ transitionConfig
2805
+ )) {
2806
+ break;
2807
+ }
2808
+ cursor.insertAdjacentHTML("beforebegin", transformation.markup);
2809
+ const ref = cursor.previousElementSibling;
2810
+ if (ref === null) throw new Error("Element wasn't created");
2811
+ ref.setAttribute(TRANSFORMATION_DATA_ATTR_KEY, identifier);
2812
+ if (transitionConfig.enabled && isAnimatableElement(ref)) {
2813
+ const originalStyle = ref.style.cssText;
2814
+ ref.style.opacity = "0";
2815
+ const anim = this.orchestrator.enter(ref, {
2816
+ ...transitionConfig,
2817
+ delayMs: transitionConfig.enter?.delayMs ?? transitionConfig.delayMs
2818
+ });
2819
+ anim.addEventListener(
2820
+ "finish",
2821
+ () => {
2822
+ ref.style.cssText = originalStyle;
2823
+ },
2824
+ {
2825
+ once: true
2826
+ }
2827
+ );
2828
+ }
2829
+ this.changeStack.set(identifier, {
2830
+ undoOpts: {
2831
+ type: "Remove",
2832
+ ref
2833
+ }
2834
+ });
2835
+ break;
2836
+ }
2837
+ case "InsertAfter": {
2838
+ const transitionConfig = this.resolveTransitionConfig(
2839
+ transformation.transition
2840
+ );
2841
+ if (!this.validateTransitionPreconditions(
2842
+ identifier,
2843
+ transformation.markup,
2844
+ transitionConfig
2845
+ )) {
2846
+ break;
2847
+ }
2848
+ cursor.insertAdjacentHTML("afterend", transformation.markup);
2849
+ const ref = cursor.nextElementSibling;
2850
+ if (ref === null) throw new Error("Element wasn't created");
2851
+ ref.setAttribute(TRANSFORMATION_DATA_ATTR_KEY, identifier);
2852
+ if (transitionConfig.enabled && isAnimatableElement(ref)) {
2853
+ const originalStyle = ref.style.cssText;
2854
+ ref.style.opacity = "0";
2855
+ const anim = this.orchestrator.enter(ref, {
2856
+ ...transitionConfig,
2857
+ delayMs: transitionConfig.enter?.delayMs ?? transitionConfig.delayMs
2858
+ });
2859
+ anim.addEventListener(
2860
+ "finish",
2861
+ () => {
2862
+ ref.style.cssText = originalStyle;
2863
+ },
2864
+ {
2865
+ once: true
2866
+ }
2867
+ );
2868
+ }
2869
+ this.changeStack.set(identifier, {
2870
+ undoOpts: {
2871
+ type: "Remove",
2872
+ ref
2873
+ }
2874
+ });
2875
+ break;
2876
+ }
2877
+ case "Delete": {
2878
+ const originalOuterHtml = cursor.outerHTML;
2879
+ morphdom_esm_default(
2880
+ cursor,
2881
+ `<div style="display: none;" data-kenobi-delete-marker="true"></div>`,
2882
+ {}
2883
+ );
2884
+ cursor.setAttribute(TRANSFORMATION_DATA_ATTR_KEY, identifier);
2885
+ this.changeStack.set(identifier, {
2886
+ undoOpts: {
2887
+ type: "Replace",
2888
+ ref: cursor,
2889
+ content: originalOuterHtml
2890
+ }
2891
+ });
2892
+ break;
2893
+ }
2894
+ case "SetFormField": {
2895
+ if (!this.isInputElement(cursor))
2896
+ throw new Error("Element targeted is not of a supported type");
2897
+ const originalValue = cursor.value;
2898
+ this.setInputValue(cursor, transformation.markup);
2899
+ cursor.setAttribute(TRANSFORMATION_DATA_ATTR_KEY, identifier);
2900
+ this.changeStack.set(identifier, {
2901
+ undoOpts: {
2902
+ type: "SetInput",
2903
+ ref: cursor,
2904
+ content: originalValue
2905
+ }
2906
+ });
2907
+ }
2908
+ }
2909
+ } catch (err) {
2910
+ this.log(
2911
+ "warn",
2912
+ `Unable to apply transformation with identifier "${identifier}"`,
2913
+ err
2914
+ );
2915
+ }
2916
+ }
2917
+ }, "applyTransformations"));
2918
+ /**
2919
+ * Creates or updates an entry in the change stack for a "Replace" action,
2920
+ * enabling undo functionality.
2921
+ *
2922
+ * This function ensures that for any given transformation identifier, there is a
2923
+ * corresponding undo record. It handles both the initial creation of this
2924
+ * record and updates to it if a transformation is re-applied, for instance,
2925
+ * after a transition.
2926
+ *
2927
+ * @param identifier The unique identifier for the transformation.
2928
+ * @param originalOuterHtml The original outerHTML of the element before replacement.
2929
+ * @param ref The new element that has replaced the original one.
2930
+ */
2931
+ __publicField(this, "setOrUpdateReplaceChangeRef", /* @__PURE__ */ __name((identifier, originalOuterHtml, ref) => {
2932
+ const existing = this.changeStack.get(identifier);
2933
+ if (!existing) {
2934
+ ref.setAttribute(TRANSFORMATION_DATA_ATTR_KEY, identifier);
2935
+ this.changeStack.set(identifier, {
2936
+ undoOpts: {
2937
+ type: "Replace",
2938
+ ref,
2939
+ // The new element to be replaced back on undo.
2940
+ content: originalOuterHtml
2941
+ // The original content to restore.
2942
+ }
2943
+ });
2944
+ return;
2945
+ }
2946
+ const previousRef = existing.undoOpts.ref;
2947
+ if (previousRef && previousRef !== ref && previousRef.isConnected) {
2948
+ previousRef.removeAttribute(TRANSFORMATION_DATA_ATTR_KEY);
2949
+ }
2950
+ ref.setAttribute(TRANSFORMATION_DATA_ATTR_KEY, identifier);
2951
+ existing.undoOpts.ref = ref;
2952
+ }, "setOrUpdateReplaceChangeRef"));
2953
+ __publicField(this, "syncChangeStack", /* @__PURE__ */ __name(() => {
2954
+ let pruned = 0;
2955
+ for (const [id, entry] of this.changeStack) {
2956
+ const ref = entry.undoOpts.ref;
2957
+ const alive = !!ref && (ref.isConnected || document.contains(ref));
2958
+ if (!alive) {
2959
+ this.changeStack.delete(id);
2960
+ pruned++;
2961
+ continue;
2962
+ }
2963
+ const marker = ref.getAttribute(TRANSFORMATION_DATA_ATTR_KEY);
2964
+ if (marker !== id) {
2965
+ this.changeStack.delete(id);
2966
+ pruned++;
2967
+ }
2968
+ }
2969
+ this.log(
2970
+ "debug",
2971
+ `syncChangeStack pruned ${this.formatThousands(pruned)} stale entries`
2972
+ );
2973
+ }, "syncChangeStack"));
2974
+ __publicField(this, "undo", /* @__PURE__ */ __name((identifier) => {
2975
+ const stackItem = this.changeStack.get(identifier);
2976
+ if (stackItem === void 0) {
2977
+ throw new Error(
2978
+ `Cannot undo stack item with identifier ${identifier} as it does not exist.`
2979
+ );
2980
+ }
2981
+ const { undoOpts } = stackItem;
2982
+ switch (undoOpts.type) {
2983
+ case "Remove": {
2984
+ undoOpts.ref.remove();
2985
+ break;
2986
+ }
2987
+ case "Replace": {
2988
+ morphdom_esm_default(undoOpts.ref, undoOpts.content);
2989
+ undoOpts.ref.removeAttribute(TRANSFORMATION_DATA_ATTR_KEY);
2990
+ break;
2991
+ }
2992
+ case "SetInput": {
2993
+ if (!this.isInputElement(undoOpts.ref))
2994
+ throw new Error("Element targeted is not of a supported type");
2995
+ this.setInputValue(undoOpts.ref, undoOpts.content);
2996
+ undoOpts.ref.removeAttribute(TRANSFORMATION_DATA_ATTR_KEY);
2997
+ break;
2998
+ }
2999
+ }
3000
+ this.changeStack.delete(identifier);
3001
+ }, "undo"));
3002
+ __publicField(this, "undoAll", /* @__PURE__ */ __name(() => {
3003
+ this.changeStack.forEach((_2, ident) => this.undo(ident));
3004
+ }, "undoAll"));
3005
+ __publicField(this, "setInputValue", /* @__PURE__ */ __name((el, value) => {
3006
+ const proto = el instanceof HTMLTextAreaElement ? HTMLTextAreaElement.prototype : el instanceof HTMLInputElement ? HTMLInputElement.prototype : HTMLSelectElement.prototype;
3007
+ const descriptor = Object.getOwnPropertyDescriptor(proto, "value");
3008
+ if (!descriptor?.set) {
3009
+ throw new Error("No value setter found");
3010
+ }
3011
+ descriptor.set.call(el, value);
3012
+ el.dispatchEvent(new Event("input", { bubbles: true }));
3013
+ el.dispatchEvent(new Event("change", { bubbles: true }));
3014
+ }, "setInputValue"));
3015
+ /*
3016
+ ----
3017
+ -- CUE CARD AUTO-MOUNT & PERSONALIZATION
3018
+ ----
3019
+ */
3020
+ /**
3021
+ * Initializes and mounts a CueCard with default configuration.
3022
+ * Called automatically when publicKey is provided.
3023
+ *
3024
+ * Default config matches the template editor settings.
3025
+ * Future: This config will be fetched per-org from the database.
3026
+ */
3027
+ __publicField(this, "initCueCard", /* @__PURE__ */ __name(() => {
3028
+ if (this.cueCardInstance) {
3029
+ this.log("warn", "CueCard already initialized, skipping...");
3030
+ return;
3031
+ }
3032
+ this.cueCardInstance = new CueCard({
3033
+ theme: "light",
3034
+ position: "top-center",
3035
+ fields: [
3036
+ {
3037
+ name: "companyDomain",
3038
+ label: "Company Name or Domain",
3039
+ placeholder: "example.com",
3040
+ required: true,
3041
+ minLength: 3,
3042
+ errorMessage: "Company name or domain is required"
3043
+ }
3044
+ ],
3045
+ hasPersonalization: true,
3046
+ isVisible: true,
3047
+ enableFocusMode: true,
3048
+ showKeyboardHints: true,
3049
+ focusBlurIntensity: "8px",
3050
+ focusDelayMs: 2e3,
3051
+ enableLauncher: true,
3052
+ onSubmitPersonalization: /* @__PURE__ */ __name((values) => {
3053
+ this.log("debug", "CueCard submitted:", values);
3054
+ void this.personalize(values);
3055
+ }, "onSubmitPersonalization"),
3056
+ onOpenChange: /* @__PURE__ */ __name((isOpen) => {
3057
+ this.log("debug", "CueCard open state changed:", isOpen);
3058
+ }, "onOpenChange")
3059
+ });
3060
+ this.cueCardInstance.mount();
3061
+ this.log("debug", "CueCard mounted successfully");
3062
+ }, "initCueCard"));
3063
+ /**
3064
+ * Triggers personalization by calling the API with the provided input.
3065
+ * Updates CueCard status during the flow and applies transformations.
3066
+ *
3067
+ * @param input - User-provided fields (e.g., { companyDomain: "acme.com" })
3068
+ */
3069
+ __publicField(this, "personalize", /* @__PURE__ */ __name(async (input) => {
3070
+ if (!this.config.publicKey) {
3071
+ this.log("error", "Cannot personalize: publicKey not configured");
3072
+ return;
3073
+ }
3074
+ const startTime = /* @__PURE__ */ new Date();
3075
+ this.log("debug", "Starting personalization with input:", input);
3076
+ if (this.cueCardInstance) {
3077
+ this.cueCardInstance.update({ status: "starting", progressPct: 10 });
3078
+ }
3079
+ try {
3080
+ const response = await fetch(`${this.config.apiHost}/v1/personalize`, {
3081
+ method: "POST",
3082
+ headers: {
3083
+ "Content-Type": "application/json"
3084
+ },
3085
+ body: JSON.stringify({
3086
+ publicKey: this.config.publicKey,
3087
+ input,
3088
+ pagePath: this.currentPath
3089
+ })
3090
+ });
3091
+ if (this.cueCardInstance) {
3092
+ this.cueCardInstance.update({ progressPct: 50 });
3093
+ }
3094
+ if (!response.ok) {
3095
+ const errorBody = await response.json().catch(() => ({}));
3096
+ throw new Error(errorBody.error || `API error: ${response.status}`);
3097
+ }
3098
+ const result = await response.json();
3099
+ this.log("debug", "Personalization API response:", result);
3100
+ if (this.cueCardInstance) {
3101
+ this.cueCardInstance.update({ progressPct: 80 });
3102
+ }
3103
+ if (result.transformations && Array.isArray(result.transformations)) {
3104
+ await this.applyTransformations(result.transformations, {
3105
+ shouldConsolidate: true
3106
+ });
3107
+ }
3108
+ if (this.cueCardInstance) {
3109
+ this.cueCardInstance.update({ status: "success", progressPct: 100 });
3110
+ }
3111
+ const endTime = /* @__PURE__ */ new Date();
3112
+ const duration = this.getDurationInMilliseconds(startTime, endTime);
3113
+ this.log(
3114
+ "debug",
3115
+ `Personalization complete, took ${this.formatThousands(duration)} ms`
3116
+ );
3117
+ } catch (error) {
3118
+ this.log("error", "Personalization failed:", error);
3119
+ if (this.cueCardInstance) {
3120
+ this.cueCardInstance.update({ status: "error", progressPct: 0 });
3121
+ }
3122
+ }
3123
+ }, "personalize"));
3124
+ /**
3125
+ * Returns the CueCard instance if one was auto-mounted.
3126
+ * Useful for external control of the CueCard state.
3127
+ */
3128
+ __publicField(this, "getCueCard", /* @__PURE__ */ __name(() => {
3129
+ return this.cueCardInstance;
3130
+ }, "getCueCard"));
3131
+ this.config = {
3132
+ apiHost: "https://kenobi.ai/api",
3133
+ debug: false,
3134
+ autoTransform: true,
3135
+ ...config
3136
+ };
3137
+ this.transitionDefaults = createNormalizedTransitionConfig(
3138
+ this.config.transitionDefaults
3139
+ );
3140
+ this.orchestrator = new TransitionOrchestrator();
3141
+ this.syncVisitorKey();
3142
+ this.currentPath = this.getCurrentPath();
3143
+ this.currentUrl = this.getCurrentUrl();
3144
+ try {
3145
+ this.initNavigationListener();
3146
+ } catch (error) {
3147
+ this.log(
3148
+ "error",
3149
+ "Failed to initialize navigation listener with error:",
3150
+ error
3151
+ );
3152
+ }
3153
+ this.log("debug", "Kenobi initialized");
3154
+ if (this.config.autoTransform) {
3155
+ this.log("debug", "Auto-transform is requested... Starting...");
3156
+ void this.startAutoTransform();
3157
+ }
3158
+ if (this.config.publicKey) {
3159
+ this.log("debug", "Public key provided, auto-mounting CueCard...");
3160
+ this.initCueCard();
3161
+ }
3162
+ }
3163
+ };
3164
+ __name(_Kenobi, "Kenobi");
3165
+ var Kenobi = _Kenobi;
3166
+ return __toCommonJS(index_exports);
3167
+ })();
3168
+ //# sourceMappingURL=dist.js.map