@flowengage/react-chatbot 1.1.0 → 1.1.2
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.
|
@@ -171,12 +171,14 @@ var d = Object.defineProperty, f = (e, t) => {
|
|
|
171
171
|
body: JSON.stringify({ session_id: e })
|
|
172
172
|
});
|
|
173
173
|
},
|
|
174
|
-
async syncVoice(e,
|
|
174
|
+
async syncVoice(e, r) {
|
|
175
175
|
return i("/api/ai/voice/sync", {
|
|
176
176
|
method: "POST",
|
|
177
177
|
body: JSON.stringify({
|
|
178
178
|
session_id: e,
|
|
179
|
-
messages:
|
|
179
|
+
messages: r,
|
|
180
|
+
...t ? { userId: String(t) } : {},
|
|
181
|
+
...n ? { siteId: String(n) } : {}
|
|
180
182
|
})
|
|
181
183
|
});
|
|
182
184
|
},
|
|
@@ -264,13 +266,15 @@ var d = Object.defineProperty, f = (e, t) => {
|
|
|
264
266
|
site_id: n
|
|
265
267
|
});
|
|
266
268
|
},
|
|
267
|
-
beaconSyncVoice(
|
|
269
|
+
beaconSyncVoice(r, i) {
|
|
268
270
|
if (typeof navigator > "u" || !navigator.sendBeacon) return !1;
|
|
269
|
-
let
|
|
270
|
-
session_id:
|
|
271
|
-
messages:
|
|
272
|
-
|
|
273
|
-
|
|
271
|
+
let a = {
|
|
272
|
+
session_id: r,
|
|
273
|
+
messages: i,
|
|
274
|
+
...t ? { userId: String(t) } : {},
|
|
275
|
+
...n ? { siteId: String(n) } : {}
|
|
276
|
+
}, o = new Blob([JSON.stringify(a)], { type: "application/json" });
|
|
277
|
+
return navigator.sendBeacon(`${e}/api/ai/voice/sync`, o);
|
|
274
278
|
}
|
|
275
279
|
};
|
|
276
280
|
}, y = Object.create(null);
|
|
@@ -2423,8 +2427,8 @@ function vn({ siteId: e, config: t, children: n, language: r = "en" }) {
|
|
|
2423
2427
|
};
|
|
2424
2428
|
}, [c, r]), i(() => () => {
|
|
2425
2429
|
if (x && !ct.current && st.current.length > 0) {
|
|
2426
|
-
let e = T.current, t = st.current, n = w.current
|
|
2427
|
-
n && e && t.length > 0 && (console.log("[FlowEngageProvider] safety-net: syncing voice transcript on unmount"), n.beaconSyncVoice(
|
|
2430
|
+
let e = T.current, t = st.current, n = w.current;
|
|
2431
|
+
n && e && t.length > 0 && (console.log("[FlowEngageProvider] safety-net: syncing voice transcript on unmount"), n.beaconSyncVoice(e, t) || n.syncVoice(e, t).catch(() => {}), ct.current = !0);
|
|
2428
2432
|
}
|
|
2429
2433
|
}, [x, _]), i(() => {
|
|
2430
2434
|
if (!w.current || !v || d !== "ready" || he) return;
|
|
@@ -22269,7 +22273,24 @@ function Sg() {
|
|
|
22269
22273
|
}));
|
|
22270
22274
|
}), e;
|
|
22271
22275
|
}
|
|
22272
|
-
function Cg() {
|
|
22276
|
+
function Cg(e) {
|
|
22277
|
+
if (!e || typeof e.closest != "function") return !1;
|
|
22278
|
+
try {
|
|
22279
|
+
return !!e.closest("footer, [role=\"contentinfo\"], #footer, .site-footer, [class*=\"footer\"], [id*=\"footer\"]");
|
|
22280
|
+
} catch {
|
|
22281
|
+
return !1;
|
|
22282
|
+
}
|
|
22283
|
+
}
|
|
22284
|
+
function wg() {
|
|
22285
|
+
let e = Sg();
|
|
22286
|
+
for (let t of e) {
|
|
22287
|
+
if ((t.type || "").toLowerCase() !== "email" || Cg(t)) continue;
|
|
22288
|
+
let e = gg(t);
|
|
22289
|
+
if (e) return e;
|
|
22290
|
+
}
|
|
22291
|
+
return null;
|
|
22292
|
+
}
|
|
22293
|
+
function Tg() {
|
|
22273
22294
|
let e = Sg(), t = /* @__PURE__ */ new Map(), n = 0;
|
|
22274
22295
|
return e.map((e, r) => {
|
|
22275
22296
|
let i = gg(e), a = i || "__orphan__";
|
|
@@ -22288,7 +22309,7 @@ function Cg() {
|
|
|
22288
22309
|
};
|
|
22289
22310
|
});
|
|
22290
22311
|
}
|
|
22291
|
-
function
|
|
22312
|
+
function Eg() {
|
|
22292
22313
|
let e = [];
|
|
22293
22314
|
return yg((t) => {
|
|
22294
22315
|
e.push(...Array.from(t.querySelectorAll("button, [role=\"button\"], input[type=\"submit\"], input[type=\"button\"]")).filter((e) => {
|
|
@@ -22306,18 +22327,18 @@ function wg() {
|
|
|
22306
22327
|
type: e.type || e.tagName
|
|
22307
22328
|
}));
|
|
22308
22329
|
}
|
|
22309
|
-
function
|
|
22330
|
+
function Dg(e) {
|
|
22310
22331
|
return String(e || "").toLowerCase().replace(/\u00a0/g, " ").replace(/\*/g, "").replace(/\s+/g, " ").trim();
|
|
22311
22332
|
}
|
|
22312
|
-
function
|
|
22313
|
-
let t =
|
|
22333
|
+
function Og(e) {
|
|
22334
|
+
let t = Dg(e);
|
|
22314
22335
|
return t = t.replace(/\s+field\s*$/i, "").trim(), t;
|
|
22315
22336
|
}
|
|
22316
|
-
function
|
|
22317
|
-
let n =
|
|
22337
|
+
function kg(e, t) {
|
|
22338
|
+
let n = Og(t);
|
|
22318
22339
|
if (!n) return 0;
|
|
22319
22340
|
let r = (e.name || "").toLowerCase(), i = (e.id || "").toLowerCase();
|
|
22320
|
-
if (r === "url" && /url|website|domain|site|
|
|
22341
|
+
if (r === "url" && /url|website|domain|audit|conduct|site(\s|$)|page(\s|$)/.test(n) && !/email|e-mail|mail|name|message|phone/.test(n) || (i === "url-input" || i.endsWith("-url-input")) && /url|website|domain|audit|conduct/.test(n) && !/email|e-mail|mail|name|message|phone/.test(n)) return 100;
|
|
22321
22342
|
let a = (e.type || "").toLowerCase();
|
|
22322
22343
|
if (a === "email" && /email|e-mail|mail/.test(n)) return 100;
|
|
22323
22344
|
if (a === "tel" && /phone|mobile|tel|cell/.test(n)) return 95;
|
|
@@ -22331,7 +22352,7 @@ function Dg(e, t) {
|
|
|
22331
22352
|
e.getAttribute("title"),
|
|
22332
22353
|
e.getAttribute("data-testid"),
|
|
22333
22354
|
e.getAttribute("autocomplete")
|
|
22334
|
-
].filter(Boolean).map((e) =>
|
|
22355
|
+
].filter(Boolean).map((e) => Dg(e)), s = 0;
|
|
22335
22356
|
for (let e of o) {
|
|
22336
22357
|
if (!e) continue;
|
|
22337
22358
|
if (e === n) {
|
|
@@ -22351,18 +22372,18 @@ function Dg(e, t) {
|
|
|
22351
22372
|
}
|
|
22352
22373
|
return s;
|
|
22353
22374
|
}
|
|
22354
|
-
var
|
|
22355
|
-
function
|
|
22375
|
+
var Ag = 22;
|
|
22376
|
+
function jg(e, t) {
|
|
22356
22377
|
let n = null, r = 0;
|
|
22357
22378
|
for (let i of e) {
|
|
22358
|
-
let e =
|
|
22379
|
+
let e = kg(i, t);
|
|
22359
22380
|
e > r && (r = e, n = i);
|
|
22360
22381
|
}
|
|
22361
|
-
return !n || r <
|
|
22382
|
+
return !n || r < Ag ? null : n;
|
|
22362
22383
|
}
|
|
22363
|
-
function
|
|
22384
|
+
function Mg(e, t, n) {
|
|
22364
22385
|
let r = String(t || "").toLowerCase().trim(), i = String(n || "").trim();
|
|
22365
|
-
if (!(/^https?:\/\//i.test(i) || /\.\w{2,}(\/|\s|$)/.test(i) || r.includes("url") || r.includes("website") || r.includes("domain") || r.includes("site"))) return null;
|
|
22386
|
+
if (/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(i) || !(/^https?:\/\//i.test(i) || /\.\w{2,}(\/|\s|$)/.test(i) || r.includes("url") || r.includes("website") || r.includes("domain") || r.includes("site"))) return null;
|
|
22366
22387
|
let a = null, o = 0;
|
|
22367
22388
|
for (let t of e) {
|
|
22368
22389
|
if (t.tagName !== "INPUT" && t.tagName !== "TEXTAREA") continue;
|
|
@@ -22388,15 +22409,15 @@ function Ag(e, t, n) {
|
|
|
22388
22409
|
}
|
|
22389
22410
|
return !a || o < 42 ? null : a;
|
|
22390
22411
|
}
|
|
22391
|
-
function
|
|
22412
|
+
function Ng(e) {
|
|
22392
22413
|
let t = String(e ?? "").trim();
|
|
22393
|
-
return t ? /^https?:\/\//i.test(t) ? !0 : /\.\w{2,}(\/|\s|$)/.test(t)
|
|
22414
|
+
return !t || /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(t) ? !1 : /^https?:\/\//i.test(t) ? !0 : /\.\w{2,}(\/|\s|$)/.test(t);
|
|
22394
22415
|
}
|
|
22395
|
-
function
|
|
22416
|
+
function Pg(e) {
|
|
22396
22417
|
let t = String(e ?? "").toLowerCase().trim();
|
|
22397
22418
|
return t ? !!(t === "url" || t === "website" || t === "website url" || t === "website_url" || t === "enter website url" || t.includes("website") || t.includes("domain") || /(enter\s+website|site\s*url|page\s*url)/.test(t)) : !1;
|
|
22398
22419
|
}
|
|
22399
|
-
function
|
|
22420
|
+
function Fg(e) {
|
|
22400
22421
|
if (!e || e.tagName !== "INPUT" && e.tagName !== "TEXTAREA") return !1;
|
|
22401
22422
|
let t = (e.type || "").toLowerCase();
|
|
22402
22423
|
return ![
|
|
@@ -22408,8 +22429,8 @@ function Ng(e) {
|
|
|
22408
22429
|
"file"
|
|
22409
22430
|
].includes(t);
|
|
22410
22431
|
}
|
|
22411
|
-
function
|
|
22412
|
-
if (!
|
|
22432
|
+
function Ig(e) {
|
|
22433
|
+
if (!Fg(e)) return !1;
|
|
22413
22434
|
let t = (e.name || "").toLowerCase(), n = (e.id || "").toLowerCase(), r = [
|
|
22414
22435
|
e.name,
|
|
22415
22436
|
e.id,
|
|
@@ -22419,11 +22440,11 @@ function Pg(e) {
|
|
|
22419
22440
|
].filter(Boolean).join(" ").toLowerCase();
|
|
22420
22441
|
return t === "url" || n === "url-input" || n.endsWith("-url-input") || /(website\s*url|enter\s+website|site\s*url)/.test(r) || /(website|domain)/.test(r) && /(url|site)/.test(r);
|
|
22421
22442
|
}
|
|
22422
|
-
function
|
|
22423
|
-
let r = String(t ?? ""), i = String(n ?? ""), a =
|
|
22443
|
+
function Lg(e, t, n) {
|
|
22444
|
+
let r = String(t ?? ""), i = String(n ?? ""), a = Bg(e, r) || jg(e, r) || Mg(e, r, i);
|
|
22424
22445
|
if (!a) return [];
|
|
22425
22446
|
let o = new Set([a]);
|
|
22426
|
-
if (
|
|
22447
|
+
if (Ng(i) && Pg(r)) for (let t of e) t !== a && Ig(t) && o.add(t);
|
|
22427
22448
|
let s = Array.from(o);
|
|
22428
22449
|
return s.sort((e, t) => {
|
|
22429
22450
|
if (e === t) return 0;
|
|
@@ -22431,7 +22452,7 @@ function Fg(e, t, n) {
|
|
|
22431
22452
|
return n & Node.DOCUMENT_POSITION_FOLLOWING ? -1 : n & Node.DOCUMENT_POSITION_PRECEDING ? 1 : 0;
|
|
22432
22453
|
}), s;
|
|
22433
22454
|
}
|
|
22434
|
-
function
|
|
22455
|
+
function Rg(e, t) {
|
|
22435
22456
|
try {
|
|
22436
22457
|
if (!e?.getBoundingClientRect || !t?.getBoundingClientRect) return Infinity;
|
|
22437
22458
|
let n = e.getBoundingClientRect(), r = t.getBoundingClientRect(), i = {
|
|
@@ -22446,7 +22467,7 @@ function Ig(e, t) {
|
|
|
22446
22467
|
return Infinity;
|
|
22447
22468
|
}
|
|
22448
22469
|
}
|
|
22449
|
-
function
|
|
22470
|
+
function zg(e) {
|
|
22450
22471
|
if (!e || typeof e != "string") return null;
|
|
22451
22472
|
let t = null;
|
|
22452
22473
|
return yg((n) => {
|
|
@@ -22456,7 +22477,7 @@ function Lg(e) {
|
|
|
22456
22477
|
} catch {}
|
|
22457
22478
|
}), t;
|
|
22458
22479
|
}
|
|
22459
|
-
function
|
|
22480
|
+
function Bg(e, t) {
|
|
22460
22481
|
let n = String(t ?? "").trim();
|
|
22461
22482
|
if (!n) return null;
|
|
22462
22483
|
let r = n.match(/^name:\s*([\w.-]+)$/i);
|
|
@@ -22466,12 +22487,12 @@ function Rg(e, t) {
|
|
|
22466
22487
|
}
|
|
22467
22488
|
let i = n.match(/^id:\s*([\w.-]+)$/i);
|
|
22468
22489
|
if (i) {
|
|
22469
|
-
let e =
|
|
22490
|
+
let e = zg(i[1]);
|
|
22470
22491
|
if (e) return e;
|
|
22471
22492
|
}
|
|
22472
22493
|
let a = n.startsWith("#") ? n.slice(1) : n;
|
|
22473
22494
|
if (/^[\w-]+$/.test(a)) {
|
|
22474
|
-
let e =
|
|
22495
|
+
let e = zg(a);
|
|
22475
22496
|
if (e) return e;
|
|
22476
22497
|
}
|
|
22477
22498
|
let o = n.toLowerCase().replace(/\s+/g, " ");
|
|
@@ -22481,7 +22502,7 @@ function Rg(e, t) {
|
|
|
22481
22502
|
}
|
|
22482
22503
|
return null;
|
|
22483
22504
|
}
|
|
22484
|
-
function
|
|
22505
|
+
function Vg(e, t) {
|
|
22485
22506
|
let n = String(t || "").toLowerCase().trim();
|
|
22486
22507
|
if (!n) return 0;
|
|
22487
22508
|
let r = [
|
|
@@ -22498,7 +22519,7 @@ function zg(e, t) {
|
|
|
22498
22519
|
for (let e of i) r.includes(e) && (a += 1);
|
|
22499
22520
|
return a / i.length * 92;
|
|
22500
22521
|
}
|
|
22501
|
-
function
|
|
22522
|
+
function Hg(e, t) {
|
|
22502
22523
|
let n = [];
|
|
22503
22524
|
yg((e) => {
|
|
22504
22525
|
n.push(...Array.from(e.querySelectorAll("button, [role=\"button\"], input[type=\"submit\"], input[type=\"button\"]")).filter((e) => {
|
|
@@ -22512,7 +22533,7 @@ function Bg(e, t) {
|
|
|
22512
22533
|
});
|
|
22513
22534
|
let r = 0, i = n.map((t) => ({
|
|
22514
22535
|
el: t,
|
|
22515
|
-
s:
|
|
22536
|
+
s: Vg(t, e)
|
|
22516
22537
|
}));
|
|
22517
22538
|
for (let { s: e } of i) e > r && (r = e);
|
|
22518
22539
|
if (r < 36) return null;
|
|
@@ -22522,14 +22543,14 @@ function Bg(e, t) {
|
|
|
22522
22543
|
if (o.length) {
|
|
22523
22544
|
let e = a[0], t = Infinity;
|
|
22524
22545
|
for (let n of a) for (let r of o) {
|
|
22525
|
-
let i =
|
|
22546
|
+
let i = Rg(n, r);
|
|
22526
22547
|
i < t && (t = i, e = n);
|
|
22527
22548
|
}
|
|
22528
22549
|
return e;
|
|
22529
22550
|
}
|
|
22530
22551
|
return a[0];
|
|
22531
22552
|
}
|
|
22532
|
-
function
|
|
22553
|
+
function Ug(e) {
|
|
22533
22554
|
if (e == null) return {};
|
|
22534
22555
|
if (typeof e == "string") {
|
|
22535
22556
|
let t = e.trim();
|
|
@@ -22542,8 +22563,8 @@ function Vg(e) {
|
|
|
22542
22563
|
}
|
|
22543
22564
|
return e;
|
|
22544
22565
|
}
|
|
22545
|
-
function
|
|
22546
|
-
let t =
|
|
22566
|
+
function Wg(e) {
|
|
22567
|
+
let t = Ug(e);
|
|
22547
22568
|
if (Array.isArray(t) && t.length > 0) {
|
|
22548
22569
|
let e = t[0];
|
|
22549
22570
|
if (e?.field_key != null || e?.fieldKey != null) return t.map((e) => ({
|
|
@@ -22571,12 +22592,12 @@ function Hg(e) {
|
|
|
22571
22592
|
value: e?.value ?? e?.Value
|
|
22572
22593
|
})) : [];
|
|
22573
22594
|
}
|
|
22574
|
-
function
|
|
22595
|
+
function Gg(e) {
|
|
22575
22596
|
if (!e || typeof e != "string") return e;
|
|
22576
22597
|
let t = e.trim();
|
|
22577
22598
|
return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(t) ? t : (t = t.replace(/\s+at\s+the\s+rate\s*(of)?\s+/gi, "@"), t = t.replace(/\s+at\s+/gi, "@"), t = t.replace(/\s+dot\s+/gi, "."), t = t.replace(/\s+/g, ""), t = t.replace(/\.{2,}/g, ".").replace(/\.$/, ""), t);
|
|
22578
22599
|
}
|
|
22579
|
-
function
|
|
22600
|
+
function Kg(e) {
|
|
22580
22601
|
if (!e || typeof e != "string") return e;
|
|
22581
22602
|
let t = {
|
|
22582
22603
|
zero: "0",
|
|
@@ -22595,7 +22616,7 @@ function Wg(e) {
|
|
|
22595
22616
|
for (let [e, r] of Object.entries(t)) n = n.replace(RegExp(`\\b${e}\\b`, "g"), r);
|
|
22596
22617
|
return n = n.replace(/[^\d+]/g, ""), n;
|
|
22597
22618
|
}
|
|
22598
|
-
function
|
|
22619
|
+
function qg(e) {
|
|
22599
22620
|
if (!e || typeof e != "string") return [];
|
|
22600
22621
|
let t = e.trim();
|
|
22601
22622
|
if (!t || /\b[a-z0-9._%+-]+@[a-z0-9.-]+\.[a-z]{2,}\b/i.test(t)) return [];
|
|
@@ -22614,7 +22635,7 @@ function Gg(e) {
|
|
|
22614
22635
|
}
|
|
22615
22636
|
return [];
|
|
22616
22637
|
}
|
|
22617
|
-
function
|
|
22638
|
+
function Jg(e) {
|
|
22618
22639
|
if (!e || typeof e != "string") return [];
|
|
22619
22640
|
let t = e.trim();
|
|
22620
22641
|
if (!t) return [];
|
|
@@ -22626,7 +22647,7 @@ function Kg(e) {
|
|
|
22626
22647
|
field_key: e,
|
|
22627
22648
|
value: i
|
|
22628
22649
|
}));
|
|
22629
|
-
}, o =
|
|
22650
|
+
}, o = Gg(t), s = i.test(o), c = o.match(/^\s*([a-z0-9._%+-]+@[a-z0-9.-]+\.[a-z]{2,})\s*$/i);
|
|
22630
22651
|
if (c) return a("Email Address", c[1]), n;
|
|
22631
22652
|
if (!i.test(t) && s) {
|
|
22632
22653
|
let e = o.match(i);
|
|
@@ -22654,17 +22675,17 @@ function Kg(e) {
|
|
|
22654
22675
|
}
|
|
22655
22676
|
return n;
|
|
22656
22677
|
}
|
|
22657
|
-
function
|
|
22678
|
+
function Yg(e) {
|
|
22658
22679
|
if (!e || typeof e != "object") return null;
|
|
22659
22680
|
let t = e.url ?? e.target_url ?? e.page_url ?? e.pageUrl ?? e.link ?? e.href ?? e.path;
|
|
22660
22681
|
return t == null ? null : String(t).trim() || null;
|
|
22661
22682
|
}
|
|
22662
|
-
function
|
|
22683
|
+
function Xg(e) {
|
|
22663
22684
|
if (!e || typeof e != "object") return null;
|
|
22664
|
-
let t = e.query ?? e.q ?? e.search ?? e.text ?? e.keywords;
|
|
22685
|
+
let t = e.query ?? e.q ?? e.search ?? e.text ?? e.keywords ?? e.search_query ?? e.searchQuery ?? e.question ?? e.prompt ?? e.topic ?? e.intent;
|
|
22665
22686
|
return t == null ? null : String(t).trim() || null;
|
|
22666
22687
|
}
|
|
22667
|
-
function
|
|
22688
|
+
function Zg(e) {
|
|
22668
22689
|
let t = e.ownerDocument?.defaultView || window, n = e.tagName === "TEXTAREA" ? t.HTMLTextAreaElement.prototype : t.HTMLInputElement.prototype, r = Object.getOwnPropertyDescriptor(n, "value");
|
|
22669
22690
|
return (e, t) => {
|
|
22670
22691
|
try {
|
|
@@ -22673,7 +22694,7 @@ function Yg(e) {
|
|
|
22673
22694
|
r?.set ? r.set.call(e, t) : e.value = t;
|
|
22674
22695
|
};
|
|
22675
22696
|
}
|
|
22676
|
-
async function
|
|
22697
|
+
async function Qg(e, t, n) {
|
|
22677
22698
|
if (!n?.skipScroll) try {
|
|
22678
22699
|
e.scrollIntoView({
|
|
22679
22700
|
behavior: "smooth",
|
|
@@ -22713,7 +22734,7 @@ async function Xg(e, t, n) {
|
|
|
22713
22734
|
].includes(String(t).toLowerCase().trim()), e.dispatchEvent(new Event("input", a)), e.dispatchEvent(new Event("change", a)), cg(e), !0;
|
|
22714
22735
|
let o = String(t);
|
|
22715
22736
|
if (r === "INPUT" || r === "TEXTAREA") {
|
|
22716
|
-
let t =
|
|
22737
|
+
let t = Zg(e);
|
|
22717
22738
|
try {
|
|
22718
22739
|
await eg(e, o, t);
|
|
22719
22740
|
} catch {
|
|
@@ -22743,11 +22764,11 @@ async function Xg(e, t, n) {
|
|
|
22743
22764
|
} catch {}
|
|
22744
22765
|
return cg(e), !0;
|
|
22745
22766
|
}
|
|
22746
|
-
function
|
|
22767
|
+
function $g(e) {
|
|
22747
22768
|
let t = e.siteId || null, n = (e.apiBaseUrl || "").replace(/\/$/, ""), r = typeof e.getLastUserVoiceText == "function" ? e.getLastUserVoiceText : null, i = [], a = null, o = {
|
|
22748
22769
|
navigate_to_page: async (n) => {
|
|
22749
22770
|
$("navigate_to_page ▶ raw parameters:", n);
|
|
22750
|
-
let r =
|
|
22771
|
+
let r = Ug(n), i = Yg(r), a = r.section_text ?? r.sectionText ?? r.section;
|
|
22751
22772
|
if ($("navigate_to_page · coerced:", {
|
|
22752
22773
|
url: i,
|
|
22753
22774
|
sectionText: a
|
|
@@ -22755,7 +22776,8 @@ function Zg(e) {
|
|
|
22755
22776
|
let e = "Missing url: pass a string url, path like /pricing, or JSON with a url field.";
|
|
22756
22777
|
return $("navigate_to_page ✖", e), e;
|
|
22757
22778
|
}
|
|
22758
|
-
|
|
22779
|
+
let o = typeof window < "u" ? sn(i) : i;
|
|
22780
|
+
if (rg(`Navigating to ${String(o).replace(/^https?:\/\/[^/]+/, "") || "/"}…`), ag(), !await ln(o, {
|
|
22759
22781
|
siteId: t,
|
|
22760
22782
|
apiBaseUrl: e.apiBaseUrl
|
|
22761
22783
|
})) {
|
|
@@ -22764,7 +22786,7 @@ function Zg(e) {
|
|
|
22764
22786
|
return $("navigate_to_page ✖ blocked", e), e;
|
|
22765
22787
|
}
|
|
22766
22788
|
try {
|
|
22767
|
-
if ($("navigate_to_page → shadowNavigate",
|
|
22789
|
+
if ($("navigate_to_page → shadowNavigate", o), await dn(o, { sectionText: a || void 0 }), await new Promise((e) => setTimeout(e, 600)), og(), ig(300), a && typeof a == "string") {
|
|
22768
22790
|
let e = rn(null, a);
|
|
22769
22791
|
e && an(e), $("navigate_to_page · highlight", {
|
|
22770
22792
|
sectionText: a,
|
|
@@ -22773,13 +22795,13 @@ function Zg(e) {
|
|
|
22773
22795
|
}
|
|
22774
22796
|
let e = "";
|
|
22775
22797
|
try {
|
|
22776
|
-
let t =
|
|
22798
|
+
let t = Tg(), n = Eg();
|
|
22777
22799
|
if (t.length > 0) {
|
|
22778
22800
|
let r = t.map((e) => e.label || e.placeholder || e.name || e.id).filter(Boolean).join(", "), i = n.map((e) => e.text).filter(Boolean).join(", ");
|
|
22779
22801
|
e = ` This page has a form with fields: [${r}]` + (i ? ` and buttons: [${i}].` : ".") + " Call list_page_forms then start filling.";
|
|
22780
22802
|
}
|
|
22781
22803
|
} catch {}
|
|
22782
|
-
let t = `OK_NAVIGATION ${
|
|
22804
|
+
let t = `OK_NAVIGATION ${o}${e}`;
|
|
22783
22805
|
return $("navigate_to_page ✓", t), t;
|
|
22784
22806
|
} catch (e) {
|
|
22785
22807
|
og(), ig(200);
|
|
@@ -22789,12 +22811,12 @@ function Zg(e) {
|
|
|
22789
22811
|
},
|
|
22790
22812
|
highlight_on_page: async (e) => {
|
|
22791
22813
|
$("highlight_on_page ▶", e);
|
|
22792
|
-
let t =
|
|
22814
|
+
let t = Ug(e), n = t?.section_id || t?.sectionId, r = t?.section_text || t?.sectionText, i = rn(n || null, r || null);
|
|
22793
22815
|
return i ? (an(i), $("highlight_on_page ✓"), "Highlighted the section.") : ($("highlight_on_page ✖ no element"), "Could not find that section on the page.");
|
|
22794
22816
|
},
|
|
22795
22817
|
search_site_content: async (e) => {
|
|
22796
22818
|
$("search_site_content ▶", e);
|
|
22797
|
-
let r =
|
|
22819
|
+
let r = Xg(Ug(e));
|
|
22798
22820
|
if ($("search_site_content · query:", r, "siteId:", t, "apiBase:", n || "(empty)"), rg("Searching site content…", { spinner: !0 }), !r) return ig(), $("search_site_content ✖ missing query"), "Missing query parameter.";
|
|
22799
22821
|
if (!t) return ig(), $("search_site_content ✖ no siteId"), "Site is not configured for search.";
|
|
22800
22822
|
if (!n) return ig(), $("search_site_content ✖ no api base"), "API base URL is missing; cannot search.";
|
|
@@ -22828,20 +22850,20 @@ function Zg(e) {
|
|
|
22828
22850
|
duration: 2e3
|
|
22829
22851
|
}), dg(!0), lg(), typeof e.requestEndSession == "function" && e.requestEndSession(), "Voice session is ending."),
|
|
22830
22852
|
list_page_forms: async () => {
|
|
22831
|
-
let e =
|
|
22832
|
-
return $("list_page_forms ✓", `${e.length} field(s)`, `${t.length} button(s)`), a =
|
|
22853
|
+
let e = Tg(), t = Eg();
|
|
22854
|
+
return $("list_page_forms ✓", `${e.length} field(s)`, `${t.length} button(s)`), a = wg(), $("list_page_forms · activeFormAncestor", a ? "contact-preferring" : "none"), JSON.stringify({
|
|
22833
22855
|
fields: e,
|
|
22834
22856
|
buttons: t,
|
|
22835
|
-
hint: "Fields are grouped by formIndex/formName. Work with ONE form at a time — only fill fields from the same formIndex. Do not jump to fields in a different form. field_key: use placeholder, label, name, or id from this list. click_page_button picks the button nearest the filled fields."
|
|
22857
|
+
hint: "Fields are grouped by formIndex/formName. Work with ONE form at a time — only fill fields from the same formIndex. Do not jump to fields in a different form. On pages with a contact form AND a footer 'Conduct Audit' / website URL field: only use the contact form unless the visitor explicitly asks to run an audit. Contact forms: fill in order Full Name → Email Address → Message. Message must be a short note the visitor wants to send (one or two sentences), never a recap of the whole chat or assistant replies. field_key: use placeholder, label, name, or id from this list. click_page_button picks the button nearest the filled fields (e.g. Send Message on the same form)."
|
|
22836
22858
|
});
|
|
22837
22859
|
},
|
|
22838
22860
|
fill_form_fields: async (e) => {
|
|
22839
22861
|
try {
|
|
22840
22862
|
$("fill_form_fields ▶ raw:", e);
|
|
22841
|
-
let t =
|
|
22863
|
+
let t = Wg(e);
|
|
22842
22864
|
if (!t.length && r) {
|
|
22843
|
-
let e = r(), n =
|
|
22844
|
-
n.length ? $("fill_form_fields · inferred URL from last user utterance (model omitted usable fields):", n) : (n =
|
|
22865
|
+
let e = r(), n = qg(e);
|
|
22866
|
+
n.length ? $("fill_form_fields · inferred URL from last user utterance (model omitted usable fields):", n) : (n = Jg(e), n.length && $("fill_form_fields · inferred contact fields from last user utterance (empty tool params):", n)), n.length && (t = n);
|
|
22845
22867
|
}
|
|
22846
22868
|
if ($("fill_form_fields · normalized fields:", t), !t.length) return "No fields provided. Call list_page_forms for field_key strings, then fill_form_fields with { \"fields\": [ { \"field_key\": \"<label or placeholder from list>\", \"value\": \"<user value>\" } ] }. Never use empty {}. Pass the value the user just said (email, message, name, URL) in fields.";
|
|
22847
22869
|
t.length > 1 && rg(`Filling ${t.length} fields…`);
|
|
@@ -22850,7 +22872,16 @@ function Zg(e) {
|
|
|
22850
22872
|
let t = e?.field_key ?? e?.fieldKey, r = e?.value;
|
|
22851
22873
|
if (t == null || r == null) continue;
|
|
22852
22874
|
let o = String(t).toLowerCase();
|
|
22853
|
-
/email|e-mail|mail/.test(o)
|
|
22875
|
+
if (/email|e-mail|mail/.test(o)) r = Gg(r);
|
|
22876
|
+
else if (/phone|mobile|tel|cell/.test(o)) r = Kg(r);
|
|
22877
|
+
else if (Pg(t) || o === "url") {
|
|
22878
|
+
let e = String(r ?? "").trim();
|
|
22879
|
+
if (/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(e) || /\bat\b/i.test(e) && /\bdot\b/i.test(e)) {
|
|
22880
|
+
let n = Gg(e);
|
|
22881
|
+
/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(n.trim()) && ($("fill_form_fields · remapping url/website intent to Email Address (value is an email)"), t = "Email Address", o = "email address", r = n.trim());
|
|
22882
|
+
}
|
|
22883
|
+
}
|
|
22884
|
+
rg(`Filling ${t}…`), $("fill_form_fields · processing field:", t, "=", r);
|
|
22854
22885
|
let s = Sg(), c = s;
|
|
22855
22886
|
if (a) {
|
|
22856
22887
|
let e = s.filter((e) => gg(e) === a);
|
|
@@ -22859,15 +22890,15 @@ function Zg(e) {
|
|
|
22859
22890
|
$("fill_form_fields · visible inputs count:", s.length, "scoped:", c.length);
|
|
22860
22891
|
let l = !1;
|
|
22861
22892
|
for (let e of [c, ...c === s ? [] : [s]]) {
|
|
22862
|
-
let o =
|
|
22893
|
+
let o = Lg(e, String(t), r);
|
|
22863
22894
|
if (o.length) {
|
|
22864
|
-
for (let e = 0; e < o.length; e++) await
|
|
22895
|
+
for (let e = 0; e < o.length; e++) await Qg(o[e], r, { skipScroll: e > 0 }), await new Promise((e) => setTimeout(e, 80));
|
|
22865
22896
|
i = o, a = gg(o[0]) || a, n.push(String(t)), l = !0;
|
|
22866
22897
|
break;
|
|
22867
22898
|
}
|
|
22868
|
-
let s =
|
|
22869
|
-
if (s ||=
|
|
22870
|
-
await
|
|
22899
|
+
let s = Bg(e, String(t));
|
|
22900
|
+
if (s ||= jg(e, String(t)), s ||= Mg(e, String(t), r), s) {
|
|
22901
|
+
await Qg(s, r), i = [s], a = gg(s) || a, n.push(String(t)), l = !0;
|
|
22871
22902
|
break;
|
|
22872
22903
|
}
|
|
22873
22904
|
}
|
|
@@ -22887,10 +22918,10 @@ function Zg(e) {
|
|
|
22887
22918
|
}
|
|
22888
22919
|
},
|
|
22889
22920
|
click_page_button: async (e) => {
|
|
22890
|
-
let t =
|
|
22921
|
+
let t = Ug(e), n = (t.button_text ?? t.buttonText ?? t.text ?? "").trim();
|
|
22891
22922
|
if ($("click_page_button ▶", n), !n) return "Missing button_text: pass the visible label, e.g. Conduct Audit.";
|
|
22892
22923
|
rg(`Clicking "${n}"…`);
|
|
22893
|
-
let r =
|
|
22924
|
+
let r = Hg(n, i);
|
|
22894
22925
|
if (!r) return ig(200), $("click_page_button ✖ no match"), `Could not find a button matching "${n}". Call list_page_forms to see button texts.`;
|
|
22895
22926
|
try {
|
|
22896
22927
|
try {
|
|
@@ -22956,32 +22987,39 @@ function Zg(e) {
|
|
|
22956
22987
|
}
|
|
22957
22988
|
//#endregion
|
|
22958
22989
|
//#region src/utils/wrapVoiceToolsForLogging.js
|
|
22959
|
-
function
|
|
22990
|
+
function e_(e) {
|
|
22960
22991
|
return !e || typeof e != "object" ? e : Object.fromEntries(Object.entries(e).map(([e, t]) => [e, async (n) => {
|
|
22961
22992
|
let r = Zt();
|
|
22962
22993
|
r ? console.log("[FlowEngage:voice-tool] ▶", e, n) : console.info(`[FlowEngage] voice tool » ${e}`);
|
|
22963
|
-
let i
|
|
22994
|
+
let i;
|
|
22995
|
+
try {
|
|
22996
|
+
i = await t(n);
|
|
22997
|
+
} catch (t) {
|
|
22998
|
+
let n = `Tool error: ${t?.message || String(t)}`;
|
|
22999
|
+
return console.error(`[FlowEngage] voice tool ${e} threw:`, t), n;
|
|
23000
|
+
}
|
|
23001
|
+
let a = typeof i == "string" ? i.length > 220 ? `${i.slice(0, 220)}…` : i : String(i);
|
|
22964
23002
|
return r ? console.log("[FlowEngage:voice-tool] ◀", e, a) : console.info(`[FlowEngage] voice tool « ${e}:`, a), i;
|
|
22965
23003
|
}]));
|
|
22966
23004
|
}
|
|
22967
23005
|
//#endregion
|
|
22968
23006
|
//#region src/components/VoiceInterface.jsx
|
|
22969
|
-
var
|
|
23007
|
+
var t_ = {
|
|
22970
23008
|
idle: "rgba(99,102,241,0.18)",
|
|
22971
23009
|
listening: "rgba(16,185,129,0.25)",
|
|
22972
23010
|
speaking: "rgba(245,158,11,0.25)",
|
|
22973
23011
|
error: "rgba(239,68,68,0.2)"
|
|
22974
|
-
},
|
|
23012
|
+
}, n_ = {
|
|
22975
23013
|
idle: "#6366f1",
|
|
22976
23014
|
listening: "#10b981",
|
|
22977
23015
|
speaking: "#f59e0b",
|
|
22978
23016
|
error: "#ef4444"
|
|
22979
23017
|
};
|
|
22980
|
-
function
|
|
23018
|
+
function r_(e, t) {
|
|
22981
23019
|
let n = (t || "").trim();
|
|
22982
23020
|
return n ? !!(/\b(let'?s|let us)\s+(end|stop|finish|wrap up|close)\s+(the\s+)?(voice\s+)?(session|call|chat)\b/i.test(n) || /\bend\s+(this\s+)?(the\s+)?(voice\s+)?(session|call|chat)\b/i.test(n) || /\b(hang\s+up|disconnect)\b/i.test(n) || /\b(that'?s all|we'?re done)\b/i.test(n) || e === "bot" && (/\b(I'?ll|I will|Let me|I can|I'?m going to)\s+(end|close)\s+(the\s+)?(voice\s+)?(session|call)\b/i.test(n) || /\b(ending|closing)\s+(the\s+)?(voice\s+)?session\b|\bvoice\s+session\s+(is\s+)?(now\s+)?(ended|over|closing)\b/i.test(n) || /\b(session|call)\s+(is\s+)?(now\s+)?(ended|over)\b/i.test(n) || /\bwe\s+can\s+end\s+(the\s+)?(session|call)?\s*(here|now)\b/i.test(n) || /\b(wrapping\s+up|signing\s+off)\b/i.test(n)) || /^(goodbye|bye|that'?s all|we'?re done|hang up|disconnect)\b/i.test(n)) : !1;
|
|
22983
23021
|
}
|
|
22984
|
-
function
|
|
23022
|
+
function i_({ agentId: e, chatId: t, siteId: r, apiBaseUrl: a, onEnd: c, historyRef: d, hasSyncedRef: f, onMessageSync: p, onStartSync: m }) {
|
|
22985
23023
|
let [h, g] = s("idle"), [ee, te] = s(null), [_, ne] = s(!1), re = o(null), ie = o(null), ae = o(""), oe = o(async () => {}), se = o(!1), v = n(async () => {
|
|
22986
23024
|
try {
|
|
22987
23025
|
await re.current?.endSession?.();
|
|
@@ -22998,7 +23036,7 @@ function n_({ agentId: e, chatId: t, siteId: r, apiBaseUrl: a, onEnd: c, history
|
|
|
22998
23036
|
try {
|
|
22999
23037
|
if (await navigator.mediaDevices.getUserMedia({ audio: !0 }), t) return;
|
|
23000
23038
|
d.current = [], ae.current = "", se.current = !1;
|
|
23001
|
-
let i =
|
|
23039
|
+
let i = e_($g({
|
|
23002
23040
|
siteId: r || null,
|
|
23003
23041
|
apiBaseUrl: a || null,
|
|
23004
23042
|
getLastUserVoiceText: () => ae.current,
|
|
@@ -23025,7 +23063,7 @@ function n_({ agentId: e, chatId: t, siteId: r, apiBaseUrl: a, onEnd: c, history
|
|
|
23025
23063
|
message: r,
|
|
23026
23064
|
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
23027
23065
|
};
|
|
23028
|
-
n === "user" && (ae.current = r), d.current = [...d.current, i],
|
|
23066
|
+
n === "user" && (ae.current = r), d.current = [...d.current, i], r_(n, r) && queueMicrotask(() => {
|
|
23029
23067
|
se.current || (se.current = !0, oe.current?.());
|
|
23030
23068
|
});
|
|
23031
23069
|
},
|
|
@@ -23048,7 +23086,7 @@ function n_({ agentId: e, chatId: t, siteId: r, apiBaseUrl: a, onEnd: c, history
|
|
|
23048
23086
|
} catch {
|
|
23049
23087
|
t = "[]";
|
|
23050
23088
|
}
|
|
23051
|
-
o.sendContextualUpdate(`Current page URL: ${e}. Site ID: ${r || "unknown"}. Page fields/buttons JSON: ${t}. Navigation: when the user wants to go to any page (contact, pricing, about, services, etc.), call search_site_content then navigate_to_page immediately — never ask permission. After navigating to a page with a form, call list_page_forms and proactively start helping the user fill it.
|
|
23089
|
+
o.sendContextualUpdate(`Current page URL: ${e}. Site ID: ${r || "unknown"}. Page fields/buttons JSON: ${t}. Navigation: when the user wants to go to any page (contact, pricing, about, services, etc.), call search_site_content then navigate_to_page immediately — never ask permission. After navigating to a page with a form, call list_page_forms and proactively start helping the user fill it. Contact / lead forms: use only the main contact form (Full Name, Email, Message). Ignore footer “Conduct Audit” or marketing URL fields unless the user explicitly asks to run a website audit. Fill in order: name → email → message. Message must be a short visitor note (what they want from the team), not a transcript of the conversation. Forms: use fill_form_fields then click_page_button (e.g. Send Message) when appropriate. Fill each field right after the user gives that value — do not click submit until required fields are filled. Voice: if the user wants to end the voice session, call end_voice_session or confirm and end.`);
|
|
23052
23090
|
} catch {}
|
|
23053
23091
|
typeof m == "function" && m();
|
|
23054
23092
|
} catch (e) {
|
|
@@ -23064,7 +23102,7 @@ function n_({ agentId: e, chatId: t, siteId: r, apiBaseUrl: a, onEnd: c, history
|
|
|
23064
23102
|
d,
|
|
23065
23103
|
m
|
|
23066
23104
|
]);
|
|
23067
|
-
let ce = h === "listening" || h === "speaking", le =
|
|
23105
|
+
let ce = h === "listening" || h === "speaking", le = n_[h] || n_.idle, ue = t_[h] || t_.idle;
|
|
23068
23106
|
return /* @__PURE__ */ u("div", {
|
|
23069
23107
|
ref: ie,
|
|
23070
23108
|
style: {
|
|
@@ -23170,7 +23208,7 @@ function n_({ agentId: e, chatId: t, siteId: r, apiBaseUrl: a, onEnd: c, history
|
|
|
23170
23208
|
}
|
|
23171
23209
|
//#endregion
|
|
23172
23210
|
//#region src/components/FlowEngageWidget.jsx
|
|
23173
|
-
var
|
|
23211
|
+
var a_ = [
|
|
23174
23212
|
{
|
|
23175
23213
|
key: "become_client",
|
|
23176
23214
|
label: "Become a Client"
|
|
@@ -23191,7 +23229,7 @@ var r_ = [
|
|
|
23191
23229
|
key: "looking_for_job",
|
|
23192
23230
|
label: "Looking for a Job"
|
|
23193
23231
|
}
|
|
23194
|
-
],
|
|
23232
|
+
], o_ = () => /* @__PURE__ */ l("div", {
|
|
23195
23233
|
style: {
|
|
23196
23234
|
display: "flex",
|
|
23197
23235
|
marginBottom: "12px",
|
|
@@ -23222,7 +23260,7 @@ var r_ = [
|
|
|
23222
23260
|
} }, e)), /* @__PURE__ */ l("style", { children: "\n @keyframes fe-dot-bounce {\n 0%, 80%, 100% { transform: translateY(0); opacity: 0.5; }\n 40% { transform: translateY(-5px); opacity: 1; }\n }\n " })]
|
|
23223
23261
|
})
|
|
23224
23262
|
});
|
|
23225
|
-
function
|
|
23263
|
+
function s_() {
|
|
23226
23264
|
let { status: e, runtimeConfig: t, resolvedConfig: n, chatId: r, chatHistory: o, isOpen: c, activeScreen: d, isHumanHandled: f, agentName: p, agentHeadshot: m, visitorEmail: h, isAgentTyping: g, isAiTyping: ee, isLoading: te, isVoiceMode: _, isRateLimited: ne, rateLimitMessage: re, isConversationEnded: ie, incomingCall: ae, activeCallId: oe, callConnectionState: se, callConnectedAt: v, isCallMuted: ce, webRTCError: le, language: ue, historyRef: y, onMessageSync: b, endConversation: de, acceptCall: fe, rejectCall: pe, endWebRTCCall: me, toggleCallMute: he, dismissCallError: ge, captureVisitorEmail: _e, openWidget: ve, closeWidget: ye, sendMessage: be, setVoiceMode: xe, startTyping: Se, stopTyping: Ce, updateTypingDraft: we } = Xt(), [Te, Ee] = s(""), [De, Oe] = s(null), [ke, Ae] = s(null), [je, Me] = s(null), [Ne, Pe] = s(0), [x, Fe] = s(h || ""), [Ie, Le] = s("");
|
|
23227
23265
|
i(() => {
|
|
23228
23266
|
try {
|
|
@@ -23250,7 +23288,7 @@ function a_() {
|
|
|
23250
23288
|
outline: "none",
|
|
23251
23289
|
fontFamily: "ui-sans-serif, system-ui, sans-serif",
|
|
23252
23290
|
...c ? {} : Ue
|
|
23253
|
-
}, Ge = S.recommendations?.[ue] || Re.recommendations?.[ue] ||
|
|
23291
|
+
}, Ge = S.recommendations?.[ue] || Re.recommendations?.[ue] || a_, Ke = S.greetings?.[ue] || Re.greetings?.[ue], qe = ze.chatButtonText || "Chat with us", Je = ze.headerName || t?.websiteName || "OpenSense Labs", C = ze.logoUrl || null, w = ze.hideWatermark || !1, T = Re.elevenLabsAgentId || t?.elevenLabsAgentId || null, Ye = t?.siteId || n?.siteId || null, Xe = t?.apiBaseUrl || "", Ze = ze.fallbackAgentName || "Agent", Qe = ze.botLabel || "AI", $e = m && String(m).trim() || t?.ownerProfileImageUrl && String(t.ownerProfileImageUrl).trim() || null, et = ae?.agentName || p || Ze, tt = o.some((e) => e.sender === "user"), nt = a(() => {
|
|
23254
23292
|
let e = o.findIndex((e) => e.sender === "user");
|
|
23255
23293
|
return e === -1 ? !1 : o.slice(e + 1).some((e) => e.sender === "bot" || e.sender === "ai" || e.sender === "agent");
|
|
23256
23294
|
}, [o]), rt = !h && tt && nt;
|
|
@@ -23378,7 +23416,7 @@ function a_() {
|
|
|
23378
23416
|
flexDirection: "column"
|
|
23379
23417
|
},
|
|
23380
23418
|
className: "fe-screen-fade-in",
|
|
23381
|
-
children: /* @__PURE__ */ l(
|
|
23419
|
+
children: /* @__PURE__ */ l(i_, {
|
|
23382
23420
|
agentId: T,
|
|
23383
23421
|
chatId: r,
|
|
23384
23422
|
siteId: Ye,
|
|
@@ -23411,7 +23449,7 @@ function a_() {
|
|
|
23411
23449
|
isAiTyping: ee,
|
|
23412
23450
|
isAgentTyping: g,
|
|
23413
23451
|
setReplyContext: Me,
|
|
23414
|
-
TypingDots:
|
|
23452
|
+
TypingDots: o_,
|
|
23415
23453
|
primaryColor: Ve,
|
|
23416
23454
|
agentHeadshot: $e,
|
|
23417
23455
|
agentDisplayName: p || Ze
|
|
@@ -23490,4 +23528,4 @@ function a_() {
|
|
|
23490
23528
|
}) : null;
|
|
23491
23529
|
}
|
|
23492
23530
|
//#endregion
|
|
23493
|
-
export { vn as FlowEngageProvider,
|
|
23531
|
+
export { vn as FlowEngageProvider, s_ as FlowEngageWidget, Xt as useFlowEngage };
|