veo-sdk 0.3.16 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/builder-ZDNVF6KG.mjs +5 -0
- package/dist/{builder-EQYOMQFY.mjs.map → builder-ZDNVF6KG.mjs.map} +1 -1
- package/dist/builder.cjs +1008 -215
- package/dist/builder.cjs.map +1 -1
- package/dist/builder.d.cts +38 -2
- package/dist/builder.d.ts +38 -2
- package/dist/builder.mjs +4 -4
- package/dist/{chunk-QCIT7CGE.mjs → chunk-I55Z7UGJ.mjs} +269 -5
- package/dist/chunk-I55Z7UGJ.mjs.map +1 -0
- package/dist/{chunk-YHUPUTWH.mjs → chunk-ICKEQ7VC.mjs} +713 -184
- package/dist/chunk-ICKEQ7VC.mjs.map +1 -0
- package/dist/{chunk-IEHGG5NL.mjs → chunk-MA2BXLZ7.mjs} +67 -11
- package/dist/chunk-MA2BXLZ7.mjs.map +1 -0
- package/dist/{guide-preview-DewCTa-B.d.cts → guide-preview-D_xhRVLe.d.cts} +20 -2
- package/dist/{guide-preview-DewCTa-B.d.ts → guide-preview-D_xhRVLe.d.ts} +20 -2
- package/dist/index.cjs +1097 -216
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.mjs +7 -6
- package/dist/index.mjs.map +1 -1
- package/dist/veo-builder.js +125 -9
- package/dist/veo-builder.js.map +1 -1
- package/dist/veo-guides.js +86 -4
- package/dist/veo-guides.js.map +1 -1
- package/dist/veo.js +1 -1
- package/dist/veo.js.map +1 -1
- package/package.json +1 -1
- package/dist/builder-EQYOMQFY.mjs +0 -5
- package/dist/chunk-IEHGG5NL.mjs.map +0 -1
- package/dist/chunk-QCIT7CGE.mjs.map +0 -1
- package/dist/chunk-YHUPUTWH.mjs.map +0 -1
|
@@ -162,6 +162,112 @@ var WALKTHROUGH_STATE_KEY_PREFIX = "veo:walkthrough_state:";
|
|
|
162
162
|
var WALKTHROUGH_ABANDONMENT_TIMEOUT_MS = 30 * 60 * 1e3;
|
|
163
163
|
var WALKTHROUGH_STEP_SELECTOR_TIMEOUT_MS = 5e3;
|
|
164
164
|
|
|
165
|
+
// src/plugins/guides/rich-text.ts
|
|
166
|
+
var ALLOWED_TAGS = {
|
|
167
|
+
P: "p",
|
|
168
|
+
BR: "br",
|
|
169
|
+
STRONG: "strong",
|
|
170
|
+
B: "strong",
|
|
171
|
+
EM: "em",
|
|
172
|
+
I: "em",
|
|
173
|
+
U: "u",
|
|
174
|
+
S: "s",
|
|
175
|
+
UL: "ul",
|
|
176
|
+
OL: "ol",
|
|
177
|
+
LI: "li",
|
|
178
|
+
A: "a"
|
|
179
|
+
};
|
|
180
|
+
var DROP_TAGS = /* @__PURE__ */ new Set([
|
|
181
|
+
"SCRIPT",
|
|
182
|
+
"STYLE",
|
|
183
|
+
"TEMPLATE",
|
|
184
|
+
"IFRAME",
|
|
185
|
+
"OBJECT",
|
|
186
|
+
"EMBED",
|
|
187
|
+
"NOSCRIPT",
|
|
188
|
+
"TITLE",
|
|
189
|
+
"TEXTAREA",
|
|
190
|
+
"SELECT",
|
|
191
|
+
"SVG",
|
|
192
|
+
"MATH"
|
|
193
|
+
]);
|
|
194
|
+
var MAX_INPUT_LEN = 16 * 1024;
|
|
195
|
+
var MAX_DEPTH = 20;
|
|
196
|
+
var MAX_NODES = 1e3;
|
|
197
|
+
function renderRichText(html, doc) {
|
|
198
|
+
const fragment = doc.createDocumentFragment();
|
|
199
|
+
if (typeof html !== "string" || html.length === 0) return fragment;
|
|
200
|
+
let parsed;
|
|
201
|
+
try {
|
|
202
|
+
parsed = new DOMParser().parseFromString(
|
|
203
|
+
html.length > MAX_INPUT_LEN ? html.slice(0, MAX_INPUT_LEN) : html,
|
|
204
|
+
"text/html"
|
|
205
|
+
);
|
|
206
|
+
} catch {
|
|
207
|
+
fragment.appendChild(doc.createTextNode(html));
|
|
208
|
+
return fragment;
|
|
209
|
+
}
|
|
210
|
+
const budget = { nodes: 0, exceeded: false };
|
|
211
|
+
for (const child of Array.from(parsed.body.childNodes)) {
|
|
212
|
+
const rebuilt = rebuildNode(child, doc, 0, budget);
|
|
213
|
+
if (rebuilt) fragment.appendChild(rebuilt);
|
|
214
|
+
}
|
|
215
|
+
if (budget.exceeded) {
|
|
216
|
+
const plain = doc.createDocumentFragment();
|
|
217
|
+
plain.appendChild(doc.createTextNode(parsed.body.textContent ?? ""));
|
|
218
|
+
return plain;
|
|
219
|
+
}
|
|
220
|
+
return fragment;
|
|
221
|
+
}
|
|
222
|
+
function rebuildNode(node, doc, depth, budget) {
|
|
223
|
+
if (budget.exceeded) return null;
|
|
224
|
+
if (++budget.nodes > MAX_NODES || depth > MAX_DEPTH) {
|
|
225
|
+
budget.exceeded = true;
|
|
226
|
+
return null;
|
|
227
|
+
}
|
|
228
|
+
if (node.nodeType === Node.TEXT_NODE) {
|
|
229
|
+
return doc.createTextNode(node.textContent ?? "");
|
|
230
|
+
}
|
|
231
|
+
if (node.nodeType !== Node.ELEMENT_NODE) return null;
|
|
232
|
+
const el = node;
|
|
233
|
+
if (DROP_TAGS.has(el.tagName)) return null;
|
|
234
|
+
const mapped = ALLOWED_TAGS[el.tagName];
|
|
235
|
+
if (!mapped) {
|
|
236
|
+
const frag = doc.createDocumentFragment();
|
|
237
|
+
for (const child of Array.from(el.childNodes)) {
|
|
238
|
+
const rebuilt2 = rebuildNode(child, doc, depth + 1, budget);
|
|
239
|
+
if (rebuilt2) frag.appendChild(rebuilt2);
|
|
240
|
+
}
|
|
241
|
+
return frag;
|
|
242
|
+
}
|
|
243
|
+
if (mapped === "a") {
|
|
244
|
+
const href = el.getAttribute("href") ?? "";
|
|
245
|
+
if (!isSafeUrl(href)) {
|
|
246
|
+
const frag = doc.createDocumentFragment();
|
|
247
|
+
for (const child of Array.from(el.childNodes)) {
|
|
248
|
+
const rebuilt2 = rebuildNode(child, doc, depth + 1, budget);
|
|
249
|
+
if (rebuilt2) frag.appendChild(rebuilt2);
|
|
250
|
+
}
|
|
251
|
+
return frag;
|
|
252
|
+
}
|
|
253
|
+
const a = doc.createElement("a");
|
|
254
|
+
a.setAttribute("href", href);
|
|
255
|
+
a.setAttribute("target", "_blank");
|
|
256
|
+
a.setAttribute("rel", "noopener noreferrer nofollow");
|
|
257
|
+
for (const child of Array.from(el.childNodes)) {
|
|
258
|
+
const rebuilt2 = rebuildNode(child, doc, depth + 1, budget);
|
|
259
|
+
if (rebuilt2) a.appendChild(rebuilt2);
|
|
260
|
+
}
|
|
261
|
+
return a;
|
|
262
|
+
}
|
|
263
|
+
const rebuilt = doc.createElement(mapped);
|
|
264
|
+
for (const child of Array.from(el.childNodes)) {
|
|
265
|
+
const childNode = rebuildNode(child, doc, depth + 1, budget);
|
|
266
|
+
if (childNode) rebuilt.appendChild(childNode);
|
|
267
|
+
}
|
|
268
|
+
return rebuilt;
|
|
269
|
+
}
|
|
270
|
+
|
|
165
271
|
// src/plugins/guides/block-builder.ts
|
|
166
272
|
function buildStepContent(step, doc, callbacks) {
|
|
167
273
|
const container = doc.createElement("div");
|
|
@@ -256,9 +362,13 @@ function buildContentBlock(block, doc) {
|
|
|
256
362
|
return el;
|
|
257
363
|
}
|
|
258
364
|
case "text": {
|
|
259
|
-
const el = doc.createElement("
|
|
365
|
+
const el = doc.createElement("div");
|
|
260
366
|
el.className = "veo-guide-text";
|
|
261
|
-
|
|
367
|
+
if (typeof block.html === "string" && block.html) {
|
|
368
|
+
el.appendChild(renderRichText(block.html, doc));
|
|
369
|
+
} else {
|
|
370
|
+
el.textContent = typeof block.text === "string" ? block.text : "";
|
|
371
|
+
}
|
|
262
372
|
applyBlockStyle(el, block.style, "text");
|
|
263
373
|
return el;
|
|
264
374
|
}
|
|
@@ -284,7 +394,11 @@ function buildButtonBlock(block, doc, callbacks) {
|
|
|
284
394
|
btn.addEventListener("click", () => {
|
|
285
395
|
const action = block.action ?? "dismiss";
|
|
286
396
|
const url = action === "url" && typeof block.url === "string" && isSafeUrl(block.url) ? block.url : void 0;
|
|
287
|
-
|
|
397
|
+
const meta = {
|
|
398
|
+
...typeof block.id === "string" && block.id ? { buttonId: block.id } : {},
|
|
399
|
+
...typeof block.text === "string" && block.text ? { buttonText: block.text } : {}
|
|
400
|
+
};
|
|
401
|
+
callbacks.onCtaClick(action, url, Object.keys(meta).length ? meta : void 0);
|
|
288
402
|
});
|
|
289
403
|
return btn;
|
|
290
404
|
}
|
|
@@ -299,6 +413,10 @@ function clampNum(n, min, max) {
|
|
|
299
413
|
function applyBlockStyle(el, style, kind) {
|
|
300
414
|
if (!style || typeof style !== "object") return;
|
|
301
415
|
const s = style;
|
|
416
|
+
if (kind === "image" && s.bleed === true) {
|
|
417
|
+
el.classList.add("veo-guide-image--bleed");
|
|
418
|
+
return;
|
|
419
|
+
}
|
|
302
420
|
const align = typeof s.align === "string" ? s.align : null;
|
|
303
421
|
if (align && (align === "left" || align === "center" || align === "right")) {
|
|
304
422
|
if (kind === "text") el.style.textAlign = align;
|
|
@@ -346,78 +464,6 @@ function readCtaUrl(step) {
|
|
|
346
464
|
return isSafeUrl(candidate) ? candidate : void 0;
|
|
347
465
|
}
|
|
348
466
|
|
|
349
|
-
// src/plugins/guides/walkthrough-block-builder.ts
|
|
350
|
-
function buildWalkthroughStepContent(step, stepIndex, totalSteps, doc, callbacks) {
|
|
351
|
-
const container = doc.createElement("div");
|
|
352
|
-
container.className = "veo-guide-content";
|
|
353
|
-
const counter = doc.createElement("div");
|
|
354
|
-
counter.className = "veo-walkthrough-counter";
|
|
355
|
-
counter.textContent = `Paso ${stepIndex + 1} de ${totalSteps}`;
|
|
356
|
-
container.appendChild(counter);
|
|
357
|
-
const progress = doc.createElement("div");
|
|
358
|
-
progress.className = "veo-walkthrough-progress";
|
|
359
|
-
for (let i = 0; i < totalSteps; i++) {
|
|
360
|
-
const dot = doc.createElement("span");
|
|
361
|
-
dot.className = "veo-walkthrough-progress-dot";
|
|
362
|
-
if (i < stepIndex) dot.classList.add("completed");
|
|
363
|
-
if (i === stepIndex) dot.classList.add("active");
|
|
364
|
-
progress.appendChild(dot);
|
|
365
|
-
}
|
|
366
|
-
container.appendChild(progress);
|
|
367
|
-
if (typeof step.imageUrl === "string" && step.imageUrl && isSafeUrl(step.imageUrl)) {
|
|
368
|
-
const img = doc.createElement("img");
|
|
369
|
-
img.className = "veo-guide-image";
|
|
370
|
-
img.src = step.imageUrl;
|
|
371
|
-
img.alt = typeof step.title === "string" ? step.title : "";
|
|
372
|
-
container.appendChild(img);
|
|
373
|
-
}
|
|
374
|
-
if (typeof step.title === "string" && step.title) {
|
|
375
|
-
const heading = doc.createElement("h2");
|
|
376
|
-
heading.className = "veo-guide-title";
|
|
377
|
-
heading.textContent = step.title;
|
|
378
|
-
container.appendChild(heading);
|
|
379
|
-
}
|
|
380
|
-
if (typeof step.content === "string" && step.content) {
|
|
381
|
-
const paragraph = doc.createElement("p");
|
|
382
|
-
paragraph.className = "veo-guide-text";
|
|
383
|
-
paragraph.textContent = step.content;
|
|
384
|
-
container.appendChild(paragraph);
|
|
385
|
-
}
|
|
386
|
-
const actions = doc.createElement("div");
|
|
387
|
-
actions.className = "veo-walkthrough-actions";
|
|
388
|
-
const skipBtn = doc.createElement("button");
|
|
389
|
-
skipBtn.type = "button";
|
|
390
|
-
skipBtn.className = "veo-walkthrough-skip";
|
|
391
|
-
skipBtn.textContent = "Omitir";
|
|
392
|
-
skipBtn.addEventListener("click", () => callbacks.onSkip());
|
|
393
|
-
actions.appendChild(skipBtn);
|
|
394
|
-
const rightGroup = doc.createElement("div");
|
|
395
|
-
rightGroup.className = "veo-walkthrough-actions-right";
|
|
396
|
-
if (stepIndex > 0) {
|
|
397
|
-
const backBtn = doc.createElement("button");
|
|
398
|
-
backBtn.type = "button";
|
|
399
|
-
backBtn.className = "veo-walkthrough-btn-secondary";
|
|
400
|
-
backBtn.textContent = "Atr\xE1s";
|
|
401
|
-
backBtn.addEventListener("click", () => callbacks.onBack());
|
|
402
|
-
rightGroup.appendChild(backBtn);
|
|
403
|
-
}
|
|
404
|
-
const isLastStep = stepIndex === totalSteps - 1;
|
|
405
|
-
const primaryBtn = doc.createElement("button");
|
|
406
|
-
primaryBtn.type = "button";
|
|
407
|
-
primaryBtn.className = "veo-guide-cta";
|
|
408
|
-
const defaultLabel = isLastStep ? "Finalizar" : "Siguiente";
|
|
409
|
-
primaryBtn.textContent = typeof step.ctaText === "string" && step.ctaText ? step.ctaText : defaultLabel;
|
|
410
|
-
primaryBtn.addEventListener("click", () => {
|
|
411
|
-
if (isLastStep) callbacks.onComplete();
|
|
412
|
-
else callbacks.onNext();
|
|
413
|
-
});
|
|
414
|
-
rightGroup.appendChild(primaryBtn);
|
|
415
|
-
actions.appendChild(rightGroup);
|
|
416
|
-
container.appendChild(actions);
|
|
417
|
-
container.appendChild(createCloseButton(doc, () => callbacks.onSkip()));
|
|
418
|
-
return container;
|
|
419
|
-
}
|
|
420
|
-
|
|
421
467
|
// src/plugins/guides/guide-design.ts
|
|
422
468
|
var DARK_THEME = {
|
|
423
469
|
"--veo-bg": "#1f2937",
|
|
@@ -490,6 +536,9 @@ function applyDesignVars(host, style) {
|
|
|
490
536
|
if (typeof s.width === "number" && Number.isFinite(s.width)) {
|
|
491
537
|
host.style.setProperty("--veo-width", `${clamp(s.width, 220, 720)}px`);
|
|
492
538
|
}
|
|
539
|
+
if (typeof s.height === "number" && Number.isFinite(s.height)) {
|
|
540
|
+
host.style.setProperty("--veo-min-h", `${clamp(s.height, 120, 900)}px`);
|
|
541
|
+
}
|
|
493
542
|
if (s.align === "left" || s.align === "center" || s.align === "right") {
|
|
494
543
|
host.style.setProperty("--veo-actions-justify", ALIGN_JUSTIFY[s.align]);
|
|
495
544
|
}
|
|
@@ -575,6 +624,68 @@ function applyElementVars(host, prefix, raw) {
|
|
|
575
624
|
}
|
|
576
625
|
}
|
|
577
626
|
|
|
627
|
+
// src/plugins/guides/inline-host.ts
|
|
628
|
+
function readInlinePosition(style) {
|
|
629
|
+
const p = style?.inlinePosition;
|
|
630
|
+
return p === "before" || p === "prepend" || p === "append" ? p : "after";
|
|
631
|
+
}
|
|
632
|
+
function insertHost(anchor, host, position) {
|
|
633
|
+
switch (position) {
|
|
634
|
+
case "before":
|
|
635
|
+
anchor.before(host);
|
|
636
|
+
break;
|
|
637
|
+
case "after":
|
|
638
|
+
anchor.after(host);
|
|
639
|
+
break;
|
|
640
|
+
case "prepend":
|
|
641
|
+
anchor.prepend(host);
|
|
642
|
+
break;
|
|
643
|
+
case "append":
|
|
644
|
+
anchor.append(host);
|
|
645
|
+
break;
|
|
646
|
+
}
|
|
647
|
+
}
|
|
648
|
+
function keepHostAttached(host, selector, position) {
|
|
649
|
+
const id = window.setInterval(() => {
|
|
650
|
+
if (host.isConnected) return;
|
|
651
|
+
const anchor = document.querySelector(selector);
|
|
652
|
+
if (anchor) insertHost(anchor, host, position);
|
|
653
|
+
}, 1e3);
|
|
654
|
+
return () => window.clearInterval(id);
|
|
655
|
+
}
|
|
656
|
+
|
|
657
|
+
// src/plugins/guides/wait-for-element.ts
|
|
658
|
+
function waitForElement(selector, timeoutMs = DEFAULT_ANCHOR_WAIT_MS) {
|
|
659
|
+
return new Promise((resolve) => {
|
|
660
|
+
const safeQuery = () => {
|
|
661
|
+
try {
|
|
662
|
+
return document.querySelector(selector);
|
|
663
|
+
} catch {
|
|
664
|
+
return null;
|
|
665
|
+
}
|
|
666
|
+
};
|
|
667
|
+
const existing = safeQuery();
|
|
668
|
+
if (existing) {
|
|
669
|
+
resolve(existing);
|
|
670
|
+
return;
|
|
671
|
+
}
|
|
672
|
+
let resolved = false;
|
|
673
|
+
const finish = (el) => {
|
|
674
|
+
if (resolved) return;
|
|
675
|
+
resolved = true;
|
|
676
|
+
observer.disconnect();
|
|
677
|
+
clearTimeout(timer);
|
|
678
|
+
resolve(el);
|
|
679
|
+
};
|
|
680
|
+
const observer = new MutationObserver(() => {
|
|
681
|
+
const el = safeQuery();
|
|
682
|
+
if (el) finish(el);
|
|
683
|
+
});
|
|
684
|
+
observer.observe(document.body, { childList: true, subtree: true });
|
|
685
|
+
const timer = setTimeout(() => finish(null), timeoutMs);
|
|
686
|
+
});
|
|
687
|
+
}
|
|
688
|
+
|
|
578
689
|
// src/plugins/guides/styles.ts
|
|
579
690
|
var GUIDE_STYLES = `
|
|
580
691
|
:host {
|
|
@@ -596,6 +707,13 @@ var GUIDE_STYLES = `
|
|
|
596
707
|
z-index: ${GUIDE_Z_INDEX};
|
|
597
708
|
animation: veo-fade-in 180ms ease-out;
|
|
598
709
|
}
|
|
710
|
+
/* Sin backdrop (style.backdrop === false): la app queda usable detr\xE1s; solo la
|
|
711
|
+
tarjeta captura el mouse. El click-en-backdrop deja de cerrar (no hay backdrop). */
|
|
712
|
+
.veo-modal-overlay--none {
|
|
713
|
+
background: transparent;
|
|
714
|
+
pointer-events: none;
|
|
715
|
+
}
|
|
716
|
+
.veo-modal-overlay--none .veo-modal-card { pointer-events: auto; }
|
|
599
717
|
/*
|
|
600
718
|
* Posici\xF3n libre/preset: --veo-pos-x/y son porcentajes (default 50% = centro).
|
|
601
719
|
* El truco translate(-pos) alinea la MISMA fracci\xF3n de la tarjeta con esa
|
|
@@ -612,6 +730,7 @@ var GUIDE_STYLES = `
|
|
|
612
730
|
border: var(--veo-border-width, 0) solid var(--veo-border-color, transparent);
|
|
613
731
|
padding: var(--veo-pad, 24px);
|
|
614
732
|
max-width: var(--veo-width); width: 90%;
|
|
733
|
+
min-height: var(--veo-min-h, auto);
|
|
615
734
|
box-shadow: var(--veo-shadow);
|
|
616
735
|
animation: veo-fade-in 180ms ease-out;
|
|
617
736
|
}
|
|
@@ -627,6 +746,14 @@ var GUIDE_STYLES = `
|
|
|
627
746
|
}
|
|
628
747
|
.veo-banner-top { top: 0; }
|
|
629
748
|
.veo-banner-bottom { bottom: 0; }
|
|
749
|
+
/* Banner EMBEBIDO en un contenedor (step.selector): fluye dentro del contenedor
|
|
750
|
+
y empuja su contenido, en vez de flotar fijo sobre la pantalla. */
|
|
751
|
+
.veo-banner-embedded {
|
|
752
|
+
position: static;
|
|
753
|
+
left: auto; right: auto;
|
|
754
|
+
width: 100%;
|
|
755
|
+
border-radius: var(--veo-radius, 0);
|
|
756
|
+
}
|
|
630
757
|
|
|
631
758
|
.veo-tooltip {
|
|
632
759
|
position: absolute;
|
|
@@ -680,6 +807,21 @@ var GUIDE_STYLES = `
|
|
|
680
807
|
border-radius: var(--veo-image-radius, 8px);
|
|
681
808
|
margin: var(--veo-image-mt, 0) 0 var(--veo-image-mb, 12px);
|
|
682
809
|
}
|
|
810
|
+
/* Imagen A SANGRE: rompe el padding de la tarjeta y ocupa el ancho completo
|
|
811
|
+
(hero estilo anuncio). Como primer bloque, hereda el redondeo superior. */
|
|
812
|
+
.veo-guide-image--bleed {
|
|
813
|
+
width: calc(100% + var(--veo-pad, 24px) * 2);
|
|
814
|
+
max-width: none;
|
|
815
|
+
max-height: 280px;
|
|
816
|
+
align-self: auto;
|
|
817
|
+
border-radius: 0;
|
|
818
|
+
margin: 0 calc(var(--veo-pad, 24px) * -1) 12px;
|
|
819
|
+
}
|
|
820
|
+
.veo-guide-content > .veo-guide-image--bleed:first-child {
|
|
821
|
+
margin-top: calc(var(--veo-pad, 24px) * -1);
|
|
822
|
+
border-radius: calc(var(--veo-radius, 12px) - var(--veo-border-width, 0px))
|
|
823
|
+
calc(var(--veo-radius, 12px) - var(--veo-border-width, 0px)) 0 0;
|
|
824
|
+
}
|
|
683
825
|
.veo-guide-title {
|
|
684
826
|
font-size: var(--veo-title-size, 18px); font-weight: 600; line-height: 1.3;
|
|
685
827
|
text-align: var(--veo-title-align, left);
|
|
@@ -692,6 +834,18 @@ var GUIDE_STYLES = `
|
|
|
692
834
|
margin: var(--veo-text-mt, 0) 0 var(--veo-text-mb, 16px);
|
|
693
835
|
color: var(--veo-text-color, var(--veo-text-secondary));
|
|
694
836
|
}
|
|
837
|
+
/* Rich text dentro de un bloque de texto (p/listas/links/\xE9nfasis). */
|
|
838
|
+
.veo-guide-text p { margin: 0 0 8px; }
|
|
839
|
+
.veo-guide-text p:last-child { margin-bottom: 0; }
|
|
840
|
+
.veo-guide-text ul, .veo-guide-text ol { margin: 0 0 8px; padding-left: 20px; }
|
|
841
|
+
.veo-guide-text ul { list-style: disc; }
|
|
842
|
+
.veo-guide-text ol { list-style: decimal; }
|
|
843
|
+
.veo-guide-text li { margin: 2px 0; display: list-item; }
|
|
844
|
+
.veo-guide-text a { color: var(--veo-primary); text-decoration: underline; cursor: pointer; }
|
|
845
|
+
.veo-guide-text strong { font-weight: 600; }
|
|
846
|
+
.veo-guide-text em { font-style: italic; }
|
|
847
|
+
.veo-guide-text u { text-decoration: underline; }
|
|
848
|
+
.veo-guide-text s { text-decoration: line-through; }
|
|
695
849
|
.veo-guide-actions {
|
|
696
850
|
display: flex; gap: 8px; justify-content: var(--veo-actions-justify);
|
|
697
851
|
}
|
|
@@ -830,6 +984,44 @@ var GUIDE_STYLES = `
|
|
|
830
984
|
}
|
|
831
985
|
.veo-walkthrough-skip:hover { color: var(--veo-text); }
|
|
832
986
|
|
|
987
|
+
/* \u2500\u2500 Badge (elemento inyectado junto al ancla que abre un tooltip) \u2500\u2500 */
|
|
988
|
+
.veo-badge {
|
|
989
|
+
display: inline-flex; align-items: center; justify-content: center;
|
|
990
|
+
border: none; padding: 0; margin: 0 4px;
|
|
991
|
+
background: none; cursor: pointer;
|
|
992
|
+
line-height: 1; vertical-align: middle;
|
|
993
|
+
font-family: inherit;
|
|
994
|
+
}
|
|
995
|
+
.veo-badge:focus-visible { outline: 2px solid var(--veo-primary); outline-offset: 2px; }
|
|
996
|
+
.veo-badge--icon {
|
|
997
|
+
border-radius: 50%;
|
|
998
|
+
background: color-mix(in srgb, var(--veo-primary) 14%, transparent);
|
|
999
|
+
color: var(--veo-primary);
|
|
1000
|
+
font-weight: 600;
|
|
1001
|
+
}
|
|
1002
|
+
.veo-badge--dot {
|
|
1003
|
+
border-radius: 50%;
|
|
1004
|
+
background: var(--veo-primary);
|
|
1005
|
+
animation: veo-badge-pulse 2s ease-out infinite;
|
|
1006
|
+
}
|
|
1007
|
+
.veo-badge--pill {
|
|
1008
|
+
border-radius: 999px;
|
|
1009
|
+
background: var(--veo-primary);
|
|
1010
|
+
color: #fff;
|
|
1011
|
+
font-weight: 600;
|
|
1012
|
+
padding: 3px 9px;
|
|
1013
|
+
white-space: nowrap;
|
|
1014
|
+
}
|
|
1015
|
+
.veo-badge--image img { display: block; border-radius: 4px; object-fit: cover; }
|
|
1016
|
+
/* El tooltip del badge usa strategy fixed (el host vive dentro del flujo del
|
|
1017
|
+
cliente; un absoluto se recortar\xEDa con overflow de ancestros). */
|
|
1018
|
+
.veo-badge-tooltip { position: fixed; }
|
|
1019
|
+
@keyframes veo-badge-pulse {
|
|
1020
|
+
0% { box-shadow: 0 0 0 0 color-mix(in srgb, var(--veo-primary) 45%, transparent); }
|
|
1021
|
+
70% { box-shadow: 0 0 0 7px transparent; }
|
|
1022
|
+
100% { box-shadow: 0 0 0 0 transparent; }
|
|
1023
|
+
}
|
|
1024
|
+
|
|
833
1025
|
.veo-custom-floating {
|
|
834
1026
|
position: fixed;
|
|
835
1027
|
z-index: ${GUIDE_Z_INDEX};
|
|
@@ -940,6 +1132,14 @@ var BaseRenderer = class {
|
|
|
940
1132
|
registerCleanup(fn) {
|
|
941
1133
|
this.cleanups.push(fn);
|
|
942
1134
|
}
|
|
1135
|
+
/**
|
|
1136
|
+
* Host de la guía montada (o `null` si aún no se montó / ya se destruyó).
|
|
1137
|
+
* Lo usa el modo builder para adjuntar manipulación directa (drag/resize)
|
|
1138
|
+
* sobre el shadow root abierto sin tocar los renderers.
|
|
1139
|
+
*/
|
|
1140
|
+
hostElement() {
|
|
1141
|
+
return this.host;
|
|
1142
|
+
}
|
|
943
1143
|
/** Remueve el host del DOM y corre todas las funciones de cleanup. */
|
|
944
1144
|
destroy() {
|
|
945
1145
|
for (const fn of this.cleanups) {
|
|
@@ -957,20 +1157,372 @@ var BaseRenderer = class {
|
|
|
957
1157
|
}
|
|
958
1158
|
};
|
|
959
1159
|
|
|
1160
|
+
// src/plugins/guides/renderers/floating-arrow.ts
|
|
1161
|
+
var STATIC_SIDE = {
|
|
1162
|
+
top: "bottom",
|
|
1163
|
+
bottom: "top",
|
|
1164
|
+
left: "right",
|
|
1165
|
+
right: "left"
|
|
1166
|
+
};
|
|
1167
|
+
function positionArrow(arrowEl, placement, data) {
|
|
1168
|
+
const side = STATIC_SIDE[placement.split("-")[0] ?? "bottom"] ?? "top";
|
|
1169
|
+
for (const prop of ["top", "bottom", "left", "right"]) {
|
|
1170
|
+
arrowEl.style.setProperty(prop, "");
|
|
1171
|
+
}
|
|
1172
|
+
if (data?.x != null) arrowEl.style.setProperty("left", `${data.x}px`);
|
|
1173
|
+
if (data?.y != null) arrowEl.style.setProperty("top", `${data.y}px`);
|
|
1174
|
+
arrowEl.style.setProperty(side, "-6px");
|
|
1175
|
+
}
|
|
1176
|
+
|
|
1177
|
+
// src/plugins/guides/renderers/badge-renderer.ts
|
|
1178
|
+
var HOVER_CLOSE_DELAY_MS = 150;
|
|
1179
|
+
var BadgeRenderer = class extends BaseRenderer {
|
|
1180
|
+
constructor() {
|
|
1181
|
+
super(...arguments);
|
|
1182
|
+
this.tooltip = null;
|
|
1183
|
+
this.arrowEl = null;
|
|
1184
|
+
this.badgeBtn = null;
|
|
1185
|
+
this.open = false;
|
|
1186
|
+
this.shownEmitted = false;
|
|
1187
|
+
this.trigger = "hover";
|
|
1188
|
+
this.side = "top";
|
|
1189
|
+
this.closeTimer = null;
|
|
1190
|
+
this.stopFloat = null;
|
|
1191
|
+
}
|
|
1192
|
+
async render(context) {
|
|
1193
|
+
const step = context.guide.guideSteps[0];
|
|
1194
|
+
if (!step) return;
|
|
1195
|
+
const selector = step.selector ?? context.guide.activationRules.selector;
|
|
1196
|
+
if (typeof selector !== "string" || selector.length === 0) return;
|
|
1197
|
+
const anchor = await waitForElement(selector);
|
|
1198
|
+
if (!anchor) return;
|
|
1199
|
+
const { host, root } = this.createHost();
|
|
1200
|
+
const ownerDocument = root.ownerDocument ?? document;
|
|
1201
|
+
this.applyDesign(step.style);
|
|
1202
|
+
this.trigger = step.style?.badgeTrigger === "click" ? "click" : "hover";
|
|
1203
|
+
const rawSide = step.style?.tooltipPlacement;
|
|
1204
|
+
this.side = rawSide === "bottom" || rawSide === "left" || rawSide === "right" ? rawSide : "top";
|
|
1205
|
+
const position = readInlinePosition(step.style);
|
|
1206
|
+
host.style.display = "inline-flex";
|
|
1207
|
+
host.style.verticalAlign = "middle";
|
|
1208
|
+
const badge = buildBadgeElement(readBadgeConfig(step), ownerDocument);
|
|
1209
|
+
root.appendChild(badge);
|
|
1210
|
+
this.badgeBtn = badge;
|
|
1211
|
+
insertHost(anchor, host, position);
|
|
1212
|
+
this.registerCleanup(keepHostAttached(host, selector, position));
|
|
1213
|
+
const tooltip = ownerDocument.createElement("div");
|
|
1214
|
+
tooltip.className = "veo-tooltip veo-badge-tooltip";
|
|
1215
|
+
tooltip.style.display = "none";
|
|
1216
|
+
const emit = (action, meta) => {
|
|
1217
|
+
context.onInteraction({
|
|
1218
|
+
guideId: context.guide.guideId,
|
|
1219
|
+
stepIndex: 0,
|
|
1220
|
+
action,
|
|
1221
|
+
...meta ? { metadata: meta } : {}
|
|
1222
|
+
});
|
|
1223
|
+
};
|
|
1224
|
+
const buildTooltipContent = (s) => buildStepContent(s, ownerDocument, {
|
|
1225
|
+
onCtaClick: (action, url, meta) => {
|
|
1226
|
+
emit("cta_clicked", meta);
|
|
1227
|
+
if (action === "url" && url) window.open(url, "_blank", "noopener,noreferrer");
|
|
1228
|
+
if (action === "dismiss") {
|
|
1229
|
+
emit("dismissed");
|
|
1230
|
+
context.onClose();
|
|
1231
|
+
return;
|
|
1232
|
+
}
|
|
1233
|
+
this.closeTooltip();
|
|
1234
|
+
},
|
|
1235
|
+
onDismiss: () => {
|
|
1236
|
+
emit("dismissed");
|
|
1237
|
+
context.onClose();
|
|
1238
|
+
}
|
|
1239
|
+
});
|
|
1240
|
+
const content = buildTooltipContent(step);
|
|
1241
|
+
tooltip.appendChild(content);
|
|
1242
|
+
const arrowEl = ownerDocument.createElement("div");
|
|
1243
|
+
arrowEl.className = "veo-tooltip-arrow";
|
|
1244
|
+
tooltip.appendChild(arrowEl);
|
|
1245
|
+
root.appendChild(tooltip);
|
|
1246
|
+
this.tooltip = tooltip;
|
|
1247
|
+
this.arrowEl = arrowEl;
|
|
1248
|
+
this.liveContainer = tooltip;
|
|
1249
|
+
this.liveContent = content;
|
|
1250
|
+
this.liveKey = this.liveKeyOf(step);
|
|
1251
|
+
this.liveBuild = buildTooltipContent;
|
|
1252
|
+
const openNow = () => {
|
|
1253
|
+
this.cancelClose();
|
|
1254
|
+
if (!this.open) {
|
|
1255
|
+
this.openTooltip(badge);
|
|
1256
|
+
if (!this.shownEmitted) {
|
|
1257
|
+
this.shownEmitted = true;
|
|
1258
|
+
emit("shown");
|
|
1259
|
+
}
|
|
1260
|
+
}
|
|
1261
|
+
};
|
|
1262
|
+
if (this.trigger === "hover") {
|
|
1263
|
+
const scheduleClose = () => {
|
|
1264
|
+
this.cancelClose();
|
|
1265
|
+
this.closeTimer = window.setTimeout(() => this.closeTooltip(), HOVER_CLOSE_DELAY_MS);
|
|
1266
|
+
};
|
|
1267
|
+
badge.addEventListener("mouseenter", openNow);
|
|
1268
|
+
badge.addEventListener("focus", openNow);
|
|
1269
|
+
badge.addEventListener("mouseleave", scheduleClose);
|
|
1270
|
+
badge.addEventListener("blur", scheduleClose);
|
|
1271
|
+
tooltip.addEventListener("mouseenter", () => this.cancelClose());
|
|
1272
|
+
tooltip.addEventListener("mouseleave", scheduleClose);
|
|
1273
|
+
} else {
|
|
1274
|
+
badge.addEventListener("click", () => {
|
|
1275
|
+
if (this.open) this.closeTooltip();
|
|
1276
|
+
else openNow();
|
|
1277
|
+
});
|
|
1278
|
+
const onDocClick = (e) => {
|
|
1279
|
+
if (!this.open) return;
|
|
1280
|
+
if (e.composedPath().includes(host)) return;
|
|
1281
|
+
this.closeTooltip();
|
|
1282
|
+
};
|
|
1283
|
+
document.addEventListener("click", onDocClick, true);
|
|
1284
|
+
this.registerCleanup(() => document.removeEventListener("click", onDocClick, true));
|
|
1285
|
+
}
|
|
1286
|
+
const onKey = (e) => {
|
|
1287
|
+
if (e.key === "Escape" && this.open) this.closeTooltip();
|
|
1288
|
+
};
|
|
1289
|
+
document.addEventListener("keydown", onKey);
|
|
1290
|
+
this.registerCleanup(() => document.removeEventListener("keydown", onKey));
|
|
1291
|
+
if (context.isPreview) openNow();
|
|
1292
|
+
}
|
|
1293
|
+
/** Cambiar de ancla/posición/trigger requiere re-montar y re-cablear. */
|
|
1294
|
+
liveKeyOf(step) {
|
|
1295
|
+
const selector = step.selector ?? "";
|
|
1296
|
+
const position = readInlinePosition(step.style);
|
|
1297
|
+
const trigger = step.style?.badgeTrigger === "click" ? "click" : "hover";
|
|
1298
|
+
return `${selector}|${position}|${trigger}`;
|
|
1299
|
+
}
|
|
1300
|
+
onLiveUpdate(step) {
|
|
1301
|
+
if (this.badgeBtn) {
|
|
1302
|
+
const doc = this.badgeBtn.ownerDocument;
|
|
1303
|
+
const next = buildBadgeElement(readBadgeConfig(step), doc);
|
|
1304
|
+
this.badgeBtn.className = next.className;
|
|
1305
|
+
this.badgeBtn.setAttribute("style", next.getAttribute("style") ?? "");
|
|
1306
|
+
this.badgeBtn.replaceChildren(...Array.from(next.childNodes));
|
|
1307
|
+
}
|
|
1308
|
+
const rawSide = step.style?.tooltipPlacement;
|
|
1309
|
+
this.side = rawSide === "bottom" || rawSide === "left" || rawSide === "right" ? rawSide : "top";
|
|
1310
|
+
if (this.open && this.badgeBtn) this.position(this.badgeBtn);
|
|
1311
|
+
}
|
|
1312
|
+
destroy() {
|
|
1313
|
+
this.cancelClose();
|
|
1314
|
+
this.stopFloat?.();
|
|
1315
|
+
this.stopFloat = null;
|
|
1316
|
+
this.tooltip = null;
|
|
1317
|
+
this.arrowEl = null;
|
|
1318
|
+
this.badgeBtn = null;
|
|
1319
|
+
this.open = false;
|
|
1320
|
+
super.destroy();
|
|
1321
|
+
}
|
|
1322
|
+
openTooltip(badge) {
|
|
1323
|
+
if (!this.tooltip) return;
|
|
1324
|
+
this.tooltip.style.display = "block";
|
|
1325
|
+
this.open = true;
|
|
1326
|
+
void this.position(badge);
|
|
1327
|
+
const reposition = () => {
|
|
1328
|
+
void this.position(badge);
|
|
1329
|
+
};
|
|
1330
|
+
window.addEventListener("scroll", reposition, true);
|
|
1331
|
+
window.addEventListener("resize", reposition);
|
|
1332
|
+
this.stopFloat = () => {
|
|
1333
|
+
window.removeEventListener("scroll", reposition, true);
|
|
1334
|
+
window.removeEventListener("resize", reposition);
|
|
1335
|
+
};
|
|
1336
|
+
}
|
|
1337
|
+
closeTooltip() {
|
|
1338
|
+
this.cancelClose();
|
|
1339
|
+
if (!this.tooltip || !this.open) return;
|
|
1340
|
+
this.tooltip.style.display = "none";
|
|
1341
|
+
this.open = false;
|
|
1342
|
+
this.stopFloat?.();
|
|
1343
|
+
this.stopFloat = null;
|
|
1344
|
+
}
|
|
1345
|
+
cancelClose() {
|
|
1346
|
+
if (this.closeTimer !== null) {
|
|
1347
|
+
window.clearTimeout(this.closeTimer);
|
|
1348
|
+
this.closeTimer = null;
|
|
1349
|
+
}
|
|
1350
|
+
}
|
|
1351
|
+
async position(badge) {
|
|
1352
|
+
const tooltip = this.tooltip;
|
|
1353
|
+
const arrowEl = this.arrowEl;
|
|
1354
|
+
if (!tooltip || !arrowEl) return;
|
|
1355
|
+
const { x, y, placement, middlewareData } = await computePosition(badge, tooltip, {
|
|
1356
|
+
strategy: "fixed",
|
|
1357
|
+
placement: this.side,
|
|
1358
|
+
middleware: [offset(8), flip(), shift({ padding: 8 }), arrow({ element: arrowEl })]
|
|
1359
|
+
});
|
|
1360
|
+
tooltip.style.left = `${x}px`;
|
|
1361
|
+
tooltip.style.top = `${y}px`;
|
|
1362
|
+
positionArrow(arrowEl, placement, middlewareData.arrow);
|
|
1363
|
+
}
|
|
1364
|
+
};
|
|
1365
|
+
function readBadgeConfig(step) {
|
|
1366
|
+
const raw = step.style?.badge;
|
|
1367
|
+
if (!raw || typeof raw !== "object") return { kind: "icon" };
|
|
1368
|
+
const b = raw;
|
|
1369
|
+
const kind = b.kind === "dot" || b.kind === "pill" || b.kind === "image" || b.kind === "icon" ? b.kind : "icon";
|
|
1370
|
+
return {
|
|
1371
|
+
kind,
|
|
1372
|
+
icon: typeof b.icon === "string" ? b.icon : null,
|
|
1373
|
+
text: typeof b.text === "string" ? b.text : null,
|
|
1374
|
+
imageUrl: typeof b.imageUrl === "string" ? b.imageUrl : null,
|
|
1375
|
+
color: typeof b.color === "string" && COLOR_RE.test(b.color.trim()) ? b.color.trim() : null,
|
|
1376
|
+
size: typeof b.size === "number" && Number.isFinite(b.size) ? b.size : null
|
|
1377
|
+
};
|
|
1378
|
+
}
|
|
1379
|
+
function clamp2(n, min, max) {
|
|
1380
|
+
return Math.min(max, Math.max(min, n));
|
|
1381
|
+
}
|
|
1382
|
+
function buildBadgeElement(config, doc) {
|
|
1383
|
+
const btn = doc.createElement("button");
|
|
1384
|
+
btn.type = "button";
|
|
1385
|
+
btn.className = `veo-badge veo-badge--${config.kind}`;
|
|
1386
|
+
btn.setAttribute("aria-label", "M\xE1s informaci\xF3n");
|
|
1387
|
+
const size = clamp2(config.size ?? 18, 8, 48);
|
|
1388
|
+
switch (config.kind) {
|
|
1389
|
+
case "dot":
|
|
1390
|
+
btn.style.width = `${size}px`;
|
|
1391
|
+
btn.style.height = `${size}px`;
|
|
1392
|
+
if (config.color) btn.style.background = config.color;
|
|
1393
|
+
break;
|
|
1394
|
+
case "pill": {
|
|
1395
|
+
btn.textContent = config.text?.slice(0, 24) || "Nuevo";
|
|
1396
|
+
btn.style.fontSize = `${clamp2(Math.round(size * 0.62), 8, 24)}px`;
|
|
1397
|
+
if (config.color) btn.style.background = config.color;
|
|
1398
|
+
break;
|
|
1399
|
+
}
|
|
1400
|
+
case "image": {
|
|
1401
|
+
if (config.imageUrl && isSafeUrl(config.imageUrl)) {
|
|
1402
|
+
const img = doc.createElement("img");
|
|
1403
|
+
img.src = config.imageUrl;
|
|
1404
|
+
img.alt = "";
|
|
1405
|
+
img.style.width = `${size}px`;
|
|
1406
|
+
img.style.height = `${size}px`;
|
|
1407
|
+
btn.appendChild(img);
|
|
1408
|
+
} else {
|
|
1409
|
+
btn.className = "veo-badge veo-badge--icon";
|
|
1410
|
+
btn.textContent = "?";
|
|
1411
|
+
btn.style.width = `${size}px`;
|
|
1412
|
+
btn.style.height = `${size}px`;
|
|
1413
|
+
btn.style.fontSize = `${clamp2(Math.round(size * 0.62), 8, 32)}px`;
|
|
1414
|
+
}
|
|
1415
|
+
break;
|
|
1416
|
+
}
|
|
1417
|
+
default: {
|
|
1418
|
+
btn.textContent = (config.icon || "\u2139\uFE0F").slice(0, 4);
|
|
1419
|
+
btn.style.width = `${size}px`;
|
|
1420
|
+
btn.style.height = `${size}px`;
|
|
1421
|
+
btn.style.fontSize = `${clamp2(Math.round(size * 0.62), 8, 32)}px`;
|
|
1422
|
+
if (config.color) btn.style.color = config.color;
|
|
1423
|
+
break;
|
|
1424
|
+
}
|
|
1425
|
+
}
|
|
1426
|
+
return btn;
|
|
1427
|
+
}
|
|
1428
|
+
|
|
1429
|
+
// src/plugins/guides/walkthrough-block-builder.ts
|
|
1430
|
+
function buildWalkthroughStepContent(step, stepIndex, totalSteps, doc, callbacks) {
|
|
1431
|
+
const container = doc.createElement("div");
|
|
1432
|
+
container.className = "veo-guide-content";
|
|
1433
|
+
const counter = doc.createElement("div");
|
|
1434
|
+
counter.className = "veo-walkthrough-counter";
|
|
1435
|
+
counter.textContent = `Paso ${stepIndex + 1} de ${totalSteps}`;
|
|
1436
|
+
container.appendChild(counter);
|
|
1437
|
+
const progress = doc.createElement("div");
|
|
1438
|
+
progress.className = "veo-walkthrough-progress";
|
|
1439
|
+
for (let i = 0; i < totalSteps; i++) {
|
|
1440
|
+
const dot = doc.createElement("span");
|
|
1441
|
+
dot.className = "veo-walkthrough-progress-dot";
|
|
1442
|
+
if (i < stepIndex) dot.classList.add("completed");
|
|
1443
|
+
if (i === stepIndex) dot.classList.add("active");
|
|
1444
|
+
progress.appendChild(dot);
|
|
1445
|
+
}
|
|
1446
|
+
container.appendChild(progress);
|
|
1447
|
+
if (typeof step.imageUrl === "string" && step.imageUrl && isSafeUrl(step.imageUrl)) {
|
|
1448
|
+
const img = doc.createElement("img");
|
|
1449
|
+
img.className = "veo-guide-image";
|
|
1450
|
+
img.src = step.imageUrl;
|
|
1451
|
+
img.alt = typeof step.title === "string" ? step.title : "";
|
|
1452
|
+
container.appendChild(img);
|
|
1453
|
+
}
|
|
1454
|
+
if (typeof step.title === "string" && step.title) {
|
|
1455
|
+
const heading = doc.createElement("h2");
|
|
1456
|
+
heading.className = "veo-guide-title";
|
|
1457
|
+
heading.textContent = step.title;
|
|
1458
|
+
container.appendChild(heading);
|
|
1459
|
+
}
|
|
1460
|
+
if (typeof step.content === "string" && step.content) {
|
|
1461
|
+
const paragraph = doc.createElement("p");
|
|
1462
|
+
paragraph.className = "veo-guide-text";
|
|
1463
|
+
paragraph.textContent = step.content;
|
|
1464
|
+
container.appendChild(paragraph);
|
|
1465
|
+
}
|
|
1466
|
+
const actions = doc.createElement("div");
|
|
1467
|
+
actions.className = "veo-walkthrough-actions";
|
|
1468
|
+
const skipBtn = doc.createElement("button");
|
|
1469
|
+
skipBtn.type = "button";
|
|
1470
|
+
skipBtn.className = "veo-walkthrough-skip";
|
|
1471
|
+
skipBtn.textContent = "Omitir";
|
|
1472
|
+
skipBtn.addEventListener("click", () => callbacks.onSkip());
|
|
1473
|
+
actions.appendChild(skipBtn);
|
|
1474
|
+
const rightGroup = doc.createElement("div");
|
|
1475
|
+
rightGroup.className = "veo-walkthrough-actions-right";
|
|
1476
|
+
if (stepIndex > 0) {
|
|
1477
|
+
const backBtn = doc.createElement("button");
|
|
1478
|
+
backBtn.type = "button";
|
|
1479
|
+
backBtn.className = "veo-walkthrough-btn-secondary";
|
|
1480
|
+
backBtn.textContent = "Atr\xE1s";
|
|
1481
|
+
backBtn.addEventListener("click", () => callbacks.onBack());
|
|
1482
|
+
rightGroup.appendChild(backBtn);
|
|
1483
|
+
}
|
|
1484
|
+
const isLastStep = stepIndex === totalSteps - 1;
|
|
1485
|
+
const primaryBtn = doc.createElement("button");
|
|
1486
|
+
primaryBtn.type = "button";
|
|
1487
|
+
primaryBtn.className = "veo-guide-cta";
|
|
1488
|
+
const defaultLabel = isLastStep ? "Finalizar" : "Siguiente";
|
|
1489
|
+
primaryBtn.textContent = typeof step.ctaText === "string" && step.ctaText ? step.ctaText : defaultLabel;
|
|
1490
|
+
primaryBtn.addEventListener("click", () => {
|
|
1491
|
+
if (isLastStep) callbacks.onComplete();
|
|
1492
|
+
else callbacks.onNext();
|
|
1493
|
+
});
|
|
1494
|
+
rightGroup.appendChild(primaryBtn);
|
|
1495
|
+
actions.appendChild(rightGroup);
|
|
1496
|
+
container.appendChild(actions);
|
|
1497
|
+
container.appendChild(createCloseButton(doc, () => callbacks.onSkip()));
|
|
1498
|
+
return container;
|
|
1499
|
+
}
|
|
1500
|
+
|
|
960
1501
|
// src/plugins/guides/renderers/banner-renderer.ts
|
|
961
1502
|
var BannerRenderer = class extends BaseRenderer {
|
|
962
|
-
render(context) {
|
|
1503
|
+
async render(context) {
|
|
963
1504
|
const idx = context.nav?.stepIndex ?? 0;
|
|
964
1505
|
const step = context.guide.guideSteps[idx];
|
|
965
1506
|
if (!step) return;
|
|
966
|
-
const
|
|
1507
|
+
const position = step.style?.position === "bottom" ? "bottom" : "top";
|
|
1508
|
+
const selector = context.nav ? null : step.selector?.trim() ?? null;
|
|
1509
|
+
let anchor = null;
|
|
1510
|
+
if (selector) {
|
|
1511
|
+
anchor = await waitForElement(selector);
|
|
1512
|
+
if (!anchor) return;
|
|
1513
|
+
}
|
|
1514
|
+
const { host, root } = this.createHost();
|
|
967
1515
|
this.applyDesign(step.style);
|
|
968
1516
|
const ownerDocument = root.ownerDocument ?? document;
|
|
969
|
-
const position = step.style?.position === "bottom" ? "bottom" : "top";
|
|
970
1517
|
const banner = ownerDocument.createElement("div");
|
|
971
|
-
banner.className =
|
|
972
|
-
const dismiss = (action, ctaUrl) => {
|
|
973
|
-
context.onInteraction({
|
|
1518
|
+
banner.className = bannerClassOf(position, Boolean(anchor));
|
|
1519
|
+
const dismiss = (action, ctaUrl, meta) => {
|
|
1520
|
+
context.onInteraction({
|
|
1521
|
+
guideId: context.guide.guideId,
|
|
1522
|
+
stepIndex: idx,
|
|
1523
|
+
action,
|
|
1524
|
+
...meta ? { metadata: meta } : {}
|
|
1525
|
+
});
|
|
974
1526
|
if (ctaUrl) window.open(ctaUrl, "_blank", "noopener,noreferrer");
|
|
975
1527
|
context.onClose();
|
|
976
1528
|
};
|
|
@@ -981,59 +1533,45 @@ var BannerRenderer = class extends BaseRenderer {
|
|
|
981
1533
|
ownerDocument,
|
|
982
1534
|
context.nav.callbacks
|
|
983
1535
|
) : buildStepContent(step, ownerDocument, {
|
|
984
|
-
onCtaClick: (action, url) => dismiss("cta_clicked", action === "url" ? url : void 0),
|
|
1536
|
+
onCtaClick: (action, url, meta) => dismiss("cta_clicked", action === "url" ? url : void 0, meta),
|
|
985
1537
|
onDismiss: () => dismiss("dismissed")
|
|
986
1538
|
});
|
|
987
1539
|
banner.appendChild(content);
|
|
988
1540
|
root.appendChild(banner);
|
|
1541
|
+
if (selector && anchor) {
|
|
1542
|
+
host.style.display = "block";
|
|
1543
|
+
const insertAt = position === "top" ? "prepend" : "append";
|
|
1544
|
+
insertHost(anchor, host, insertAt);
|
|
1545
|
+
this.registerCleanup(keepHostAttached(host, selector, insertAt));
|
|
1546
|
+
}
|
|
989
1547
|
if (!context.nav) {
|
|
990
1548
|
this.liveContainer = banner;
|
|
991
1549
|
this.liveContent = content;
|
|
992
1550
|
this.liveBuild = (s) => buildStepContent(s, ownerDocument, {
|
|
993
|
-
onCtaClick: (action, url) => dismiss("cta_clicked", action === "url" ? url : void 0),
|
|
1551
|
+
onCtaClick: (action, url, meta) => dismiss("cta_clicked", action === "url" ? url : void 0, meta),
|
|
994
1552
|
onDismiss: () => dismiss("dismissed")
|
|
995
1553
|
});
|
|
1554
|
+
this.liveKey = this.liveKeyOf(step);
|
|
996
1555
|
context.onInteraction({ guideId: context.guide.guideId, stepIndex: 0, action: "shown" });
|
|
997
1556
|
}
|
|
998
1557
|
}
|
|
1558
|
+
/** Cambiar de contenedor o de top/bottom embebido requiere re-insertar → remontar. */
|
|
1559
|
+
liveKeyOf(step) {
|
|
1560
|
+
const selector = step.selector?.trim() ?? "";
|
|
1561
|
+
if (!selector) return "";
|
|
1562
|
+
const position = step.style?.position === "bottom" ? "bottom" : "top";
|
|
1563
|
+
return `${selector}|${position}`;
|
|
1564
|
+
}
|
|
999
1565
|
onLiveUpdate(step) {
|
|
1000
1566
|
if (this.liveContainer) {
|
|
1001
1567
|
const position = step.style?.position === "bottom" ? "bottom" : "top";
|
|
1002
|
-
|
|
1568
|
+
const embedded = Boolean(step.selector?.trim());
|
|
1569
|
+
this.liveContainer.className = bannerClassOf(position, embedded);
|
|
1003
1570
|
}
|
|
1004
1571
|
}
|
|
1005
1572
|
};
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
function waitForElement(selector, timeoutMs = DEFAULT_ANCHOR_WAIT_MS) {
|
|
1009
|
-
return new Promise((resolve) => {
|
|
1010
|
-
const safeQuery = () => {
|
|
1011
|
-
try {
|
|
1012
|
-
return document.querySelector(selector);
|
|
1013
|
-
} catch {
|
|
1014
|
-
return null;
|
|
1015
|
-
}
|
|
1016
|
-
};
|
|
1017
|
-
const existing = safeQuery();
|
|
1018
|
-
if (existing) {
|
|
1019
|
-
resolve(existing);
|
|
1020
|
-
return;
|
|
1021
|
-
}
|
|
1022
|
-
let resolved = false;
|
|
1023
|
-
const finish = (el) => {
|
|
1024
|
-
if (resolved) return;
|
|
1025
|
-
resolved = true;
|
|
1026
|
-
observer.disconnect();
|
|
1027
|
-
clearTimeout(timer);
|
|
1028
|
-
resolve(el);
|
|
1029
|
-
};
|
|
1030
|
-
const observer = new MutationObserver(() => {
|
|
1031
|
-
const el = safeQuery();
|
|
1032
|
-
if (el) finish(el);
|
|
1033
|
-
});
|
|
1034
|
-
observer.observe(document.body, { childList: true, subtree: true });
|
|
1035
|
-
const timer = setTimeout(() => finish(null), timeoutMs);
|
|
1036
|
-
});
|
|
1573
|
+
function bannerClassOf(position, embedded) {
|
|
1574
|
+
return embedded ? "veo-banner veo-banner-embedded" : `veo-banner veo-banner-${position}`;
|
|
1037
1575
|
}
|
|
1038
1576
|
|
|
1039
1577
|
// src/utils/uuid.ts
|
|
@@ -1568,36 +2106,6 @@ var FormRenderer = class extends BaseRenderer {
|
|
|
1568
2106
|
}
|
|
1569
2107
|
};
|
|
1570
2108
|
|
|
1571
|
-
// src/plugins/guides/inline-host.ts
|
|
1572
|
-
function readInlinePosition(style) {
|
|
1573
|
-
const p = style?.inlinePosition;
|
|
1574
|
-
return p === "before" || p === "prepend" || p === "append" ? p : "after";
|
|
1575
|
-
}
|
|
1576
|
-
function insertHost(anchor, host, position) {
|
|
1577
|
-
switch (position) {
|
|
1578
|
-
case "before":
|
|
1579
|
-
anchor.before(host);
|
|
1580
|
-
break;
|
|
1581
|
-
case "after":
|
|
1582
|
-
anchor.after(host);
|
|
1583
|
-
break;
|
|
1584
|
-
case "prepend":
|
|
1585
|
-
anchor.prepend(host);
|
|
1586
|
-
break;
|
|
1587
|
-
case "append":
|
|
1588
|
-
anchor.append(host);
|
|
1589
|
-
break;
|
|
1590
|
-
}
|
|
1591
|
-
}
|
|
1592
|
-
function keepHostAttached(host, selector, position) {
|
|
1593
|
-
const id = window.setInterval(() => {
|
|
1594
|
-
if (host.isConnected) return;
|
|
1595
|
-
const anchor = document.querySelector(selector);
|
|
1596
|
-
if (anchor) insertHost(anchor, host, position);
|
|
1597
|
-
}, 1e3);
|
|
1598
|
-
return () => window.clearInterval(id);
|
|
1599
|
-
}
|
|
1600
|
-
|
|
1601
2109
|
// src/plugins/guides/renderers/inline-custom-renderer.ts
|
|
1602
2110
|
var InlineCustomRenderer = class extends BaseRenderer {
|
|
1603
2111
|
async render(context) {
|
|
@@ -1665,13 +2173,18 @@ var InlineRenderer = class extends BaseRenderer {
|
|
|
1665
2173
|
const ownerDocument = root.ownerDocument ?? document;
|
|
1666
2174
|
const card = ownerDocument.createElement("div");
|
|
1667
2175
|
card.className = "veo-inline";
|
|
1668
|
-
const dismiss = (action, ctaUrl) => {
|
|
1669
|
-
context.onInteraction({
|
|
2176
|
+
const dismiss = (action, ctaUrl, meta) => {
|
|
2177
|
+
context.onInteraction({
|
|
2178
|
+
guideId: context.guide.guideId,
|
|
2179
|
+
stepIndex: 0,
|
|
2180
|
+
action,
|
|
2181
|
+
...meta ? { metadata: meta } : {}
|
|
2182
|
+
});
|
|
1670
2183
|
if (ctaUrl) window.open(ctaUrl, "_blank", "noopener,noreferrer");
|
|
1671
2184
|
context.onClose();
|
|
1672
2185
|
};
|
|
1673
2186
|
const content = buildStepContent(step, ownerDocument, {
|
|
1674
|
-
onCtaClick: (action, url) => dismiss("cta_clicked", action === "url" ? url : void 0),
|
|
2187
|
+
onCtaClick: (action, url, meta) => dismiss("cta_clicked", action === "url" ? url : void 0, meta),
|
|
1675
2188
|
onDismiss: () => dismiss("dismissed")
|
|
1676
2189
|
});
|
|
1677
2190
|
card.appendChild(content);
|
|
@@ -1680,7 +2193,7 @@ var InlineRenderer = class extends BaseRenderer {
|
|
|
1680
2193
|
this.liveContent = content;
|
|
1681
2194
|
this.liveKey = `${selector}|${position}`;
|
|
1682
2195
|
this.liveBuild = (s) => buildStepContent(s, ownerDocument, {
|
|
1683
|
-
onCtaClick: (action, url) => dismiss("cta_clicked", action === "url" ? url : void 0),
|
|
2196
|
+
onCtaClick: (action, url, meta) => dismiss("cta_clicked", action === "url" ? url : void 0, meta),
|
|
1684
2197
|
onDismiss: () => dismiss("dismissed")
|
|
1685
2198
|
});
|
|
1686
2199
|
context.onInteraction({ guideId: context.guide.guideId, stepIndex: 0, action: "shown" });
|
|
@@ -1691,7 +2204,14 @@ var InlineRenderer = class extends BaseRenderer {
|
|
|
1691
2204
|
};
|
|
1692
2205
|
|
|
1693
2206
|
// src/plugins/guides/renderers/modal-renderer.ts
|
|
2207
|
+
function overlayClassOf(step) {
|
|
2208
|
+
return step.style?.backdrop === false ? "veo-modal-overlay veo-modal-overlay--none" : "veo-modal-overlay";
|
|
2209
|
+
}
|
|
1694
2210
|
var ModalRenderer = class extends BaseRenderer {
|
|
2211
|
+
constructor() {
|
|
2212
|
+
super(...arguments);
|
|
2213
|
+
this.overlay = null;
|
|
2214
|
+
}
|
|
1695
2215
|
render(context) {
|
|
1696
2216
|
const idx = context.nav?.stepIndex ?? 0;
|
|
1697
2217
|
const step = context.guide.guideSteps[idx];
|
|
@@ -1700,11 +2220,17 @@ var ModalRenderer = class extends BaseRenderer {
|
|
|
1700
2220
|
this.applyDesign(step.style);
|
|
1701
2221
|
const ownerDocument = root.ownerDocument ?? document;
|
|
1702
2222
|
const overlay = ownerDocument.createElement("div");
|
|
1703
|
-
overlay.className =
|
|
2223
|
+
overlay.className = overlayClassOf(step);
|
|
2224
|
+
this.overlay = overlay;
|
|
1704
2225
|
const card = ownerDocument.createElement("div");
|
|
1705
2226
|
card.className = "veo-modal-card";
|
|
1706
|
-
const dismiss = (action, ctaUrl) => {
|
|
1707
|
-
context.onInteraction({
|
|
2227
|
+
const dismiss = (action, ctaUrl, meta) => {
|
|
2228
|
+
context.onInteraction({
|
|
2229
|
+
guideId: context.guide.guideId,
|
|
2230
|
+
stepIndex: idx,
|
|
2231
|
+
action,
|
|
2232
|
+
...meta ? { metadata: meta } : {}
|
|
2233
|
+
});
|
|
1708
2234
|
if (ctaUrl) window.open(ctaUrl, "_blank", "noopener,noreferrer");
|
|
1709
2235
|
context.onClose();
|
|
1710
2236
|
};
|
|
@@ -1719,7 +2245,7 @@ var ModalRenderer = class extends BaseRenderer {
|
|
|
1719
2245
|
ownerDocument,
|
|
1720
2246
|
context.nav.callbacks
|
|
1721
2247
|
) : buildStepContent(step, ownerDocument, {
|
|
1722
|
-
onCtaClick: (action, url) => dismiss("cta_clicked", action === "url" ? url : void 0),
|
|
2248
|
+
onCtaClick: (action, url, meta) => dismiss("cta_clicked", action === "url" ? url : void 0, meta),
|
|
1723
2249
|
onDismiss: () => dismiss("dismissed")
|
|
1724
2250
|
});
|
|
1725
2251
|
card.appendChild(content);
|
|
@@ -1729,7 +2255,7 @@ var ModalRenderer = class extends BaseRenderer {
|
|
|
1729
2255
|
this.liveContainer = card;
|
|
1730
2256
|
this.liveContent = content;
|
|
1731
2257
|
this.liveBuild = (s) => buildStepContent(s, ownerDocument, {
|
|
1732
|
-
onCtaClick: (action, url) => dismiss("cta_clicked", action === "url" ? url : void 0),
|
|
2258
|
+
onCtaClick: (action, url, meta) => dismiss("cta_clicked", action === "url" ? url : void 0, meta),
|
|
1733
2259
|
onDismiss: () => dismiss("dismissed")
|
|
1734
2260
|
});
|
|
1735
2261
|
}
|
|
@@ -1745,26 +2271,14 @@ var ModalRenderer = class extends BaseRenderer {
|
|
|
1745
2271
|
context.onInteraction({ guideId: context.guide.guideId, stepIndex: 0, action: "shown" });
|
|
1746
2272
|
}
|
|
1747
2273
|
}
|
|
1748
|
-
|
|
1749
|
-
|
|
1750
|
-
// src/plugins/guides/renderers/floating-arrow.ts
|
|
1751
|
-
var STATIC_SIDE = {
|
|
1752
|
-
top: "bottom",
|
|
1753
|
-
bottom: "top",
|
|
1754
|
-
left: "right",
|
|
1755
|
-
right: "left"
|
|
1756
|
-
};
|
|
1757
|
-
function positionArrow(arrowEl, placement, data) {
|
|
1758
|
-
const side = STATIC_SIDE[placement.split("-")[0] ?? "bottom"] ?? "top";
|
|
1759
|
-
for (const prop of ["top", "bottom", "left", "right"]) {
|
|
1760
|
-
arrowEl.style.setProperty(prop, "");
|
|
2274
|
+
onLiveUpdate(step) {
|
|
2275
|
+
if (this.overlay) this.overlay.className = overlayClassOf(step);
|
|
1761
2276
|
}
|
|
1762
|
-
|
|
1763
|
-
|
|
1764
|
-
|
|
1765
|
-
}
|
|
1766
|
-
|
|
1767
|
-
// src/plugins/guides/renderers/tooltip-renderer.ts
|
|
2277
|
+
destroy() {
|
|
2278
|
+
this.overlay = null;
|
|
2279
|
+
super.destroy();
|
|
2280
|
+
}
|
|
2281
|
+
};
|
|
1768
2282
|
var TooltipRenderer = class extends BaseRenderer {
|
|
1769
2283
|
constructor() {
|
|
1770
2284
|
super(...arguments);
|
|
@@ -1786,18 +2300,19 @@ var TooltipRenderer = class extends BaseRenderer {
|
|
|
1786
2300
|
const ownerDocument = root.ownerDocument ?? document;
|
|
1787
2301
|
const tooltip = ownerDocument.createElement("div");
|
|
1788
2302
|
tooltip.className = "veo-tooltip";
|
|
1789
|
-
const dismiss = (action, ctaUrl) => {
|
|
2303
|
+
const dismiss = (action, ctaUrl, meta) => {
|
|
1790
2304
|
context.onInteraction({
|
|
1791
2305
|
guideId: context.guide.guideId,
|
|
1792
2306
|
stepIndex: 0,
|
|
1793
|
-
action
|
|
2307
|
+
action,
|
|
2308
|
+
...meta ? { metadata: meta } : {}
|
|
1794
2309
|
});
|
|
1795
2310
|
if (ctaUrl) window.open(ctaUrl, "_blank", "noopener,noreferrer");
|
|
1796
2311
|
context.onClose();
|
|
1797
2312
|
};
|
|
1798
2313
|
const content = buildStepContent(step, ownerDocument, {
|
|
1799
|
-
onCtaClick: (action, url) => {
|
|
1800
|
-
dismiss("cta_clicked", action === "url" ? url : void 0);
|
|
2314
|
+
onCtaClick: (action, url, meta) => {
|
|
2315
|
+
dismiss("cta_clicked", action === "url" ? url : void 0, meta);
|
|
1801
2316
|
},
|
|
1802
2317
|
onDismiss: () => dismiss("dismissed")
|
|
1803
2318
|
});
|
|
@@ -1830,7 +2345,7 @@ var TooltipRenderer = class extends BaseRenderer {
|
|
|
1830
2345
|
this.liveContent = content;
|
|
1831
2346
|
this.liveKey = selector;
|
|
1832
2347
|
this.liveBuild = (s) => buildStepContent(s, ownerDocument, {
|
|
1833
|
-
onCtaClick: (action, url) => dismiss("cta_clicked", action === "url" ? url : void 0),
|
|
2348
|
+
onCtaClick: (action, url, meta) => dismiss("cta_clicked", action === "url" ? url : void 0, meta),
|
|
1834
2349
|
onDismiss: () => dismiss("dismissed")
|
|
1835
2350
|
});
|
|
1836
2351
|
context.onInteraction({
|
|
@@ -1914,14 +2429,26 @@ var GuidePreviewController = class {
|
|
|
1914
2429
|
const nextStep = input.guideSteps[0];
|
|
1915
2430
|
if (this.singleStep && this.input && input.guideType === this.input.guideType && input.guideType !== "walkthrough" && nextStep && this.singleStep.updateStep(nextStep)) {
|
|
1916
2431
|
this.input = input;
|
|
1917
|
-
return {
|
|
2432
|
+
return {
|
|
2433
|
+
close: () => this.close(),
|
|
2434
|
+
ready: Promise.resolve({ rendered: true }),
|
|
2435
|
+
host: () => this.activeHost()
|
|
2436
|
+
};
|
|
1918
2437
|
}
|
|
1919
2438
|
this.close();
|
|
1920
2439
|
this.input = input;
|
|
1921
2440
|
const guide = normalize(input);
|
|
1922
2441
|
const start = typeof input.startStepIndex === "number" ? input.startStepIndex : 0;
|
|
1923
2442
|
const ready = guide.guideType === "walkthrough" ? this.startWalkthrough(guide, start) : this.renderSingleStep(guide);
|
|
1924
|
-
return { close: () => this.close(), ready };
|
|
2443
|
+
return { close: () => this.close(), ready, host: () => this.activeHost() };
|
|
2444
|
+
}
|
|
2445
|
+
/** Host de la guía montada (single-step o paso de walkthrough activo). */
|
|
2446
|
+
activeHost() {
|
|
2447
|
+
if (this.singleStep) return this.singleStep.hostElement();
|
|
2448
|
+
if (this.walkthrough instanceof BaseRenderer) {
|
|
2449
|
+
return this.walkthrough.hostElement();
|
|
2450
|
+
}
|
|
2451
|
+
return null;
|
|
1925
2452
|
}
|
|
1926
2453
|
close() {
|
|
1927
2454
|
if (this.singleStep) {
|
|
@@ -2042,7 +2569,7 @@ var activeController = null;
|
|
|
2042
2569
|
function previewGuide(input) {
|
|
2043
2570
|
if (!hasDocument()) {
|
|
2044
2571
|
return { close: () => {
|
|
2045
|
-
}, ready: Promise.resolve({ rendered: false }) };
|
|
2572
|
+
}, ready: Promise.resolve({ rendered: false }), host: () => null };
|
|
2046
2573
|
}
|
|
2047
2574
|
if (!activeController) activeController = new GuidePreviewController();
|
|
2048
2575
|
return activeController.preview(input);
|
|
@@ -2085,6 +2612,8 @@ function createSingleStepRenderer(type) {
|
|
|
2085
2612
|
return new FormRenderer();
|
|
2086
2613
|
case "inline-form":
|
|
2087
2614
|
return new InlineFormRenderer();
|
|
2615
|
+
case "badge":
|
|
2616
|
+
return new BadgeRenderer();
|
|
2088
2617
|
case "walkthrough":
|
|
2089
2618
|
return null;
|
|
2090
2619
|
}
|
|
@@ -2229,6 +2758,6 @@ function buildSelectorPath(element, maxAncestors = 5) {
|
|
|
2229
2758
|
return parts.join(" > ");
|
|
2230
2759
|
}
|
|
2231
2760
|
|
|
2232
|
-
export { ALWAYS_BLOCK_SELECTORS, BannerRenderer, CustomRenderer, DEFAULT_AUTOCAPTURE_CONFIG, DEFAULT_TRACKER_BATCH_SIZE, DEFAULT_TRACKER_FLUSH_INTERVAL_MS, DEFAULT_TRACKER_MAX_RETRIES, FREQUENCY_CACHE_KEY_PREFIX, FREQUENCY_CACHE_MAX_ENTRIES, FREQUENCY_CACHE_TTL_MS, FormRenderer, InlineCustomRenderer, InlineFormRenderer, InlineRenderer, MAX_ANCESTORS, ModalRenderer, PRIORITY_ATTRIBUTES, SENSITIVE_ATTRIBUTES, TooltipRenderer, WALKTHROUGH_ABANDONMENT_TIMEOUT_MS, WALKTHROUGH_STATE_KEY_PREFIX, WalkthroughRenderer, buildSelectorPath, clearBuilderToken, closeGuidePreview, filterHumanClasses, hasDocument, hasLocalStorage, hasNavigatorSendBeacon, hasWindow, isBuilderMode, previewGuide, resolveBuilderContext, resolveBuilderToken, uuidv7 };
|
|
2233
|
-
//# sourceMappingURL=chunk-
|
|
2234
|
-
//# sourceMappingURL=chunk-
|
|
2761
|
+
export { ALWAYS_BLOCK_SELECTORS, BadgeRenderer, BannerRenderer, CustomRenderer, DEFAULT_AUTOCAPTURE_CONFIG, DEFAULT_TRACKER_BATCH_SIZE, DEFAULT_TRACKER_FLUSH_INTERVAL_MS, DEFAULT_TRACKER_MAX_RETRIES, FREQUENCY_CACHE_KEY_PREFIX, FREQUENCY_CACHE_MAX_ENTRIES, FREQUENCY_CACHE_TTL_MS, FormRenderer, InlineCustomRenderer, InlineFormRenderer, InlineRenderer, MAX_ANCESTORS, ModalRenderer, PRIORITY_ATTRIBUTES, SENSITIVE_ATTRIBUTES, TooltipRenderer, WALKTHROUGH_ABANDONMENT_TIMEOUT_MS, WALKTHROUGH_STATE_KEY_PREFIX, WalkthroughRenderer, buildSelectorPath, clearBuilderToken, closeGuidePreview, filterHumanClasses, hasDocument, hasLocalStorage, hasNavigatorSendBeacon, hasWindow, isBuilderMode, previewGuide, resolveBuilderContext, resolveBuilderToken, uuidv7 };
|
|
2762
|
+
//# sourceMappingURL=chunk-ICKEQ7VC.mjs.map
|
|
2763
|
+
//# sourceMappingURL=chunk-ICKEQ7VC.mjs.map
|