@returningai/widget-sdk 1.6.2 → 1.7.1
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/CHANGELOG.md +29 -0
- package/README.md +42 -1
- package/dist/rai-banner.iife.js +1 -1
- package/dist/rai-banner.js +1 -1
- package/dist/rai-widget.iife.js +2 -2
- package/dist/rai-widget.js +1506 -1355
- package/dist/types/BaseWidget.d.ts +12 -21
- package/dist/types/core/bundle-readiness.d.ts +15 -0
- package/dist/types/core/bundle-runtime-cache.d.ts +20 -0
- package/dist/types/core/store-host-callback.d.ts +3 -0
- package/dist/types/index.d.ts +2 -2
- package/dist/types/types.d.ts +38 -2
- package/package.json +8 -2
package/dist/rai-widget.js
CHANGED
|
@@ -10335,794 +10335,245 @@ var lottie_light = { exports: {} };
|
|
|
10335
10335
|
})(lottie_light, lottie_light.exports);
|
|
10336
10336
|
var lottie_lightExports = lottie_light.exports;
|
|
10337
10337
|
const lottie = /* @__PURE__ */ getDefaultExportFromCjs(lottie_lightExports);
|
|
10338
|
-
function
|
|
10339
|
-
return `${config.storagePrefix}-${config.widgetId}-${config.container}-auth`;
|
|
10340
|
-
}
|
|
10341
|
-
function legacyStorageKey(config) {
|
|
10342
|
-
return `${config.storagePrefix}-${config.widgetId}-auth`;
|
|
10343
|
-
}
|
|
10344
|
-
function errorSettingsKey(config) {
|
|
10345
|
-
return `${config.storagePrefix}-${config.widgetId}-error-settings`;
|
|
10346
|
-
}
|
|
10347
|
-
function saveToStorage(config, state) {
|
|
10338
|
+
async function fetchEligibleBanner(apiUrl, request) {
|
|
10348
10339
|
try {
|
|
10349
|
-
const
|
|
10350
|
-
|
|
10351
|
-
|
|
10352
|
-
|
|
10353
|
-
};
|
|
10354
|
-
|
|
10340
|
+
const res = await fetch(`${apiUrl}/v2/api/banner-sdk/eligible`, {
|
|
10341
|
+
method: "POST",
|
|
10342
|
+
headers: { "Content-Type": "application/json" },
|
|
10343
|
+
body: JSON.stringify(request)
|
|
10344
|
+
});
|
|
10345
|
+
const json = await res.json();
|
|
10346
|
+
if (json && json.meta && json.meta.status === "success") {
|
|
10347
|
+
return json.data || { banner: null };
|
|
10348
|
+
}
|
|
10349
|
+
return { banner: null, reason: json && json.detail || "request_failed" };
|
|
10355
10350
|
} catch {
|
|
10351
|
+
return { banner: null, reason: "network_error" };
|
|
10356
10352
|
}
|
|
10357
10353
|
}
|
|
10358
|
-
|
|
10359
|
-
|
|
10360
|
-
|
|
10361
|
-
|
|
10362
|
-
|
|
10363
|
-
|
|
10364
|
-
|
|
10365
|
-
|
|
10366
|
-
|
|
10367
|
-
|
|
10368
|
-
|
|
10369
|
-
|
|
10370
|
-
|
|
10371
|
-
|
|
10372
|
-
|
|
10373
|
-
|
|
10354
|
+
/*! @license DOMPurify 3.4.9 | (c) Cure53 and other contributors | Released under the Apache license 2.0 and Mozilla Public License 2.0 | github.com/cure53/DOMPurify/blob/3.4.9/LICENSE */
|
|
10355
|
+
function _arrayLikeToArray(r, a) {
|
|
10356
|
+
(null == a || a > r.length) && (a = r.length);
|
|
10357
|
+
for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e];
|
|
10358
|
+
return n;
|
|
10359
|
+
}
|
|
10360
|
+
function _arrayWithHoles(r) {
|
|
10361
|
+
if (Array.isArray(r)) return r;
|
|
10362
|
+
}
|
|
10363
|
+
function _iterableToArrayLimit(r, l) {
|
|
10364
|
+
var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"];
|
|
10365
|
+
if (null != t) {
|
|
10366
|
+
var e, n, i, u, a = [], f = true, o = false;
|
|
10367
|
+
try {
|
|
10368
|
+
if (i = (t = t.call(r)).next, 0 === l) ;
|
|
10369
|
+
else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = true) ;
|
|
10370
|
+
} catch (r2) {
|
|
10371
|
+
o = true, n = r2;
|
|
10372
|
+
} finally {
|
|
10373
|
+
try {
|
|
10374
|
+
if (!f && null != t.return && (u = t.return(), Object(u) !== u)) return;
|
|
10375
|
+
} finally {
|
|
10376
|
+
if (o) throw n;
|
|
10374
10377
|
}
|
|
10375
|
-
return true;
|
|
10376
10378
|
}
|
|
10377
|
-
|
|
10378
|
-
return false;
|
|
10379
|
-
} catch {
|
|
10380
|
-
return false;
|
|
10379
|
+
return a;
|
|
10381
10380
|
}
|
|
10382
10381
|
}
|
|
10383
|
-
function
|
|
10384
|
-
|
|
10385
|
-
|
|
10386
|
-
|
|
10387
|
-
|
|
10382
|
+
function _nonIterableRest() {
|
|
10383
|
+
throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
|
|
10384
|
+
}
|
|
10385
|
+
function _slicedToArray(r, e) {
|
|
10386
|
+
return _arrayWithHoles(r) || _iterableToArrayLimit(r, e) || _unsupportedIterableToArray(r, e) || _nonIterableRest();
|
|
10387
|
+
}
|
|
10388
|
+
function _unsupportedIterableToArray(r, a) {
|
|
10389
|
+
if (r) {
|
|
10390
|
+
if ("string" == typeof r) return _arrayLikeToArray(r, a);
|
|
10391
|
+
var t = {}.toString.call(r).slice(8, -1);
|
|
10392
|
+
return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0;
|
|
10388
10393
|
}
|
|
10389
10394
|
}
|
|
10390
|
-
const
|
|
10391
|
-
|
|
10392
|
-
|
|
10393
|
-
|
|
10394
|
-
|
|
10395
|
-
|
|
10396
|
-
|
|
10397
|
-
|
|
10395
|
+
const entries = Object.entries, setPrototypeOf = Object.setPrototypeOf, isFrozen = Object.isFrozen, getPrototypeOf = Object.getPrototypeOf, getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor;
|
|
10396
|
+
let freeze = Object.freeze, seal = Object.seal, create = Object.create;
|
|
10397
|
+
let _ref = typeof Reflect !== "undefined" && Reflect, apply = _ref.apply, construct = _ref.construct;
|
|
10398
|
+
if (!freeze) {
|
|
10399
|
+
freeze = function freeze2(x) {
|
|
10400
|
+
return x;
|
|
10401
|
+
};
|
|
10402
|
+
}
|
|
10403
|
+
if (!seal) {
|
|
10404
|
+
seal = function seal2(x) {
|
|
10405
|
+
return x;
|
|
10406
|
+
};
|
|
10407
|
+
}
|
|
10408
|
+
if (!apply) {
|
|
10409
|
+
apply = function apply2(func, thisArg) {
|
|
10410
|
+
for (var _len = arguments.length, args = new Array(_len > 2 ? _len - 2 : 0), _key = 2; _key < _len; _key++) {
|
|
10411
|
+
args[_key - 2] = arguments[_key];
|
|
10398
10412
|
}
|
|
10399
|
-
|
|
10400
|
-
|
|
10401
|
-
} catch {
|
|
10402
|
-
return null;
|
|
10403
|
-
}
|
|
10413
|
+
return func.apply(thisArg, args);
|
|
10414
|
+
};
|
|
10404
10415
|
}
|
|
10405
|
-
|
|
10406
|
-
|
|
10407
|
-
|
|
10408
|
-
|
|
10409
|
-
|
|
10416
|
+
if (!construct) {
|
|
10417
|
+
construct = function construct2(Func) {
|
|
10418
|
+
for (var _len2 = arguments.length, args = new Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) {
|
|
10419
|
+
args[_key2 - 1] = arguments[_key2];
|
|
10420
|
+
}
|
|
10421
|
+
return new Func(...args);
|
|
10422
|
+
};
|
|
10410
10423
|
}
|
|
10411
|
-
|
|
10412
|
-
|
|
10413
|
-
|
|
10424
|
+
const arrayForEach = unapply(Array.prototype.forEach);
|
|
10425
|
+
const arrayLastIndexOf = unapply(Array.prototype.lastIndexOf);
|
|
10426
|
+
const arrayPop = unapply(Array.prototype.pop);
|
|
10427
|
+
const arrayPush = unapply(Array.prototype.push);
|
|
10428
|
+
const arraySplice = unapply(Array.prototype.splice);
|
|
10429
|
+
const arrayIsArray = Array.isArray;
|
|
10430
|
+
const stringToLowerCase = unapply(String.prototype.toLowerCase);
|
|
10431
|
+
const stringToString = unapply(String.prototype.toString);
|
|
10432
|
+
const stringMatch = unapply(String.prototype.match);
|
|
10433
|
+
const stringReplace = unapply(String.prototype.replace);
|
|
10434
|
+
const stringIndexOf = unapply(String.prototype.indexOf);
|
|
10435
|
+
const stringTrim = unapply(String.prototype.trim);
|
|
10436
|
+
const numberToString = unapply(Number.prototype.toString);
|
|
10437
|
+
const booleanToString = unapply(Boolean.prototype.toString);
|
|
10438
|
+
const bigintToString = typeof BigInt === "undefined" ? null : unapply(BigInt.prototype.toString);
|
|
10439
|
+
const symbolToString = typeof Symbol === "undefined" ? null : unapply(Symbol.prototype.toString);
|
|
10440
|
+
const objectHasOwnProperty = unapply(Object.prototype.hasOwnProperty);
|
|
10441
|
+
const objectToString = unapply(Object.prototype.toString);
|
|
10442
|
+
const regExpTest = unapply(RegExp.prototype.test);
|
|
10443
|
+
const typeErrorCreate = unconstruct(TypeError);
|
|
10444
|
+
function unapply(func) {
|
|
10445
|
+
return function(thisArg) {
|
|
10446
|
+
if (thisArg instanceof RegExp) {
|
|
10447
|
+
thisArg.lastIndex = 0;
|
|
10448
|
+
}
|
|
10449
|
+
for (var _len3 = arguments.length, args = new Array(_len3 > 1 ? _len3 - 1 : 0), _key3 = 1; _key3 < _len3; _key3++) {
|
|
10450
|
+
args[_key3 - 1] = arguments[_key3];
|
|
10451
|
+
}
|
|
10452
|
+
return apply(func, thisArg, args);
|
|
10453
|
+
};
|
|
10414
10454
|
}
|
|
10415
|
-
function
|
|
10416
|
-
|
|
10417
|
-
|
|
10418
|
-
|
|
10419
|
-
|
|
10420
|
-
|
|
10421
|
-
|
|
10422
|
-
|
|
10423
|
-
|
|
10424
|
-
|
|
10455
|
+
function unconstruct(Func) {
|
|
10456
|
+
return function() {
|
|
10457
|
+
for (var _len4 = arguments.length, args = new Array(_len4), _key4 = 0; _key4 < _len4; _key4++) {
|
|
10458
|
+
args[_key4] = arguments[_key4];
|
|
10459
|
+
}
|
|
10460
|
+
return construct(Func, args);
|
|
10461
|
+
};
|
|
10462
|
+
}
|
|
10463
|
+
function addToSet(set, array) {
|
|
10464
|
+
let transformCaseFunc = arguments.length > 2 && arguments[2] !== void 0 ? arguments[2] : stringToLowerCase;
|
|
10465
|
+
if (setPrototypeOf) {
|
|
10466
|
+
setPrototypeOf(set, null);
|
|
10467
|
+
}
|
|
10468
|
+
if (!arrayIsArray(array)) {
|
|
10469
|
+
return set;
|
|
10470
|
+
}
|
|
10471
|
+
let l = array.length;
|
|
10472
|
+
while (l--) {
|
|
10473
|
+
let element = array[l];
|
|
10474
|
+
if (typeof element === "string") {
|
|
10475
|
+
const lcElement = transformCaseFunc(element);
|
|
10476
|
+
if (lcElement !== element) {
|
|
10477
|
+
if (!isFrozen(array)) {
|
|
10478
|
+
array[l] = lcElement;
|
|
10479
|
+
}
|
|
10480
|
+
element = lcElement;
|
|
10481
|
+
}
|
|
10482
|
+
}
|
|
10483
|
+
set[element] = true;
|
|
10425
10484
|
}
|
|
10485
|
+
return set;
|
|
10426
10486
|
}
|
|
10427
|
-
function
|
|
10428
|
-
|
|
10429
|
-
|
|
10430
|
-
|
|
10487
|
+
function cleanArray(array) {
|
|
10488
|
+
for (let index = 0; index < array.length; index++) {
|
|
10489
|
+
const isPropertyExist = objectHasOwnProperty(array, index);
|
|
10490
|
+
if (!isPropertyExist) {
|
|
10491
|
+
array[index] = null;
|
|
10492
|
+
}
|
|
10431
10493
|
}
|
|
10432
|
-
|
|
10433
|
-
|
|
10494
|
+
return array;
|
|
10495
|
+
}
|
|
10496
|
+
function clone(object) {
|
|
10497
|
+
const newObject = create(null);
|
|
10498
|
+
for (const _ref2 of entries(object)) {
|
|
10499
|
+
var _ref3 = _slicedToArray(_ref2, 2);
|
|
10500
|
+
const property = _ref3[0];
|
|
10501
|
+
const value = _ref3[1];
|
|
10502
|
+
const isPropertyExist = objectHasOwnProperty(object, property);
|
|
10503
|
+
if (isPropertyExist) {
|
|
10504
|
+
if (arrayIsArray(value)) {
|
|
10505
|
+
newObject[property] = cleanArray(value);
|
|
10506
|
+
} else if (value && typeof value === "object" && value.constructor === Object) {
|
|
10507
|
+
newObject[property] = clone(value);
|
|
10508
|
+
} else {
|
|
10509
|
+
newObject[property] = value;
|
|
10510
|
+
}
|
|
10511
|
+
}
|
|
10434
10512
|
}
|
|
10435
|
-
return
|
|
10513
|
+
return newObject;
|
|
10436
10514
|
}
|
|
10437
|
-
|
|
10438
|
-
|
|
10439
|
-
|
|
10440
|
-
|
|
10441
|
-
const retryDelay = config.retryDelay ?? 500;
|
|
10442
|
-
for (let attempt = 0; attempt <= maxRetries; attempt++) {
|
|
10443
|
-
if (attempt > 0) {
|
|
10444
|
-
await new Promise(
|
|
10445
|
-
(resolve) => setTimeout(resolve, retryDelay * (1 << attempt - 1))
|
|
10446
|
-
);
|
|
10515
|
+
function stringifyValue(value) {
|
|
10516
|
+
switch (typeof value) {
|
|
10517
|
+
case "string": {
|
|
10518
|
+
return value;
|
|
10447
10519
|
}
|
|
10448
|
-
|
|
10449
|
-
|
|
10450
|
-
const body = {
|
|
10451
|
-
nonce,
|
|
10452
|
-
timestamp,
|
|
10453
|
-
widgetType: config.widgetType,
|
|
10454
|
-
...buildIdentityProof(config)
|
|
10455
|
-
};
|
|
10456
|
-
const response = await fetch(`${config.apiUrl}/${config.widgetId}/auth/serverless`, {
|
|
10457
|
-
method: "POST",
|
|
10458
|
-
headers: { "Content-Type": "application/json" },
|
|
10459
|
-
body: JSON.stringify(body),
|
|
10460
|
-
credentials: "include"
|
|
10461
|
-
});
|
|
10462
|
-
if (!response.ok) {
|
|
10463
|
-
is4xx = response.status >= 400 && response.status < 500;
|
|
10464
|
-
const errorBody = await response.json().catch(() => ({ error: "Authentication failed" }));
|
|
10465
|
-
if (is4xx) {
|
|
10466
|
-
state.lastAuthError = {
|
|
10467
|
-
status: response.status,
|
|
10468
|
-
error: errorBody == null ? void 0 : errorBody.error,
|
|
10469
|
-
hint: errorBody == null ? void 0 : errorBody.hint
|
|
10470
|
-
};
|
|
10471
|
-
console.error(
|
|
10472
|
-
`[rai-widget] /auth/serverless ${response.status}:`,
|
|
10473
|
-
(errorBody == null ? void 0 : errorBody.error) || "Authentication failed",
|
|
10474
|
-
(errorBody == null ? void 0 : errorBody.hint) ? `— ${errorBody.hint}` : ""
|
|
10475
|
-
);
|
|
10476
|
-
}
|
|
10477
|
-
throw new Error((errorBody == null ? void 0 : errorBody.error) || `HTTP ${response.status}`);
|
|
10478
|
-
}
|
|
10479
|
-
state.lastAuthError = null;
|
|
10480
|
-
const data = await response.json();
|
|
10481
|
-
if (!data.accessToken || !data.refreshToken) {
|
|
10482
|
-
throw new Error("Invalid authentication response");
|
|
10483
|
-
}
|
|
10484
|
-
setTokens(config, state, data, onRefreshScheduled);
|
|
10485
|
-
state.isAuthenticated = true;
|
|
10486
|
-
return true;
|
|
10487
|
-
} catch {
|
|
10488
|
-
if (is4xx || attempt === maxRetries) {
|
|
10489
|
-
state.isAuthenticated = false;
|
|
10490
|
-
return false;
|
|
10491
|
-
}
|
|
10520
|
+
case "number": {
|
|
10521
|
+
return numberToString(value);
|
|
10492
10522
|
}
|
|
10493
|
-
|
|
10494
|
-
|
|
10495
|
-
return false;
|
|
10496
|
-
}
|
|
10497
|
-
async function authenticateViaProxy(config, state, onRefreshScheduled) {
|
|
10498
|
-
const maxRetries = config.maxRetries ?? 3;
|
|
10499
|
-
const retryDelay = config.retryDelay ?? 500;
|
|
10500
|
-
for (let attempt = 0; attempt <= maxRetries; attempt++) {
|
|
10501
|
-
if (attempt > 0) {
|
|
10502
|
-
await new Promise(
|
|
10503
|
-
(resolve) => setTimeout(resolve, retryDelay * (1 << attempt - 1))
|
|
10504
|
-
);
|
|
10523
|
+
case "boolean": {
|
|
10524
|
+
return booleanToString(value);
|
|
10505
10525
|
}
|
|
10506
|
-
|
|
10507
|
-
|
|
10508
|
-
|
|
10509
|
-
|
|
10510
|
-
|
|
10511
|
-
|
|
10512
|
-
|
|
10513
|
-
|
|
10514
|
-
|
|
10515
|
-
|
|
10516
|
-
|
|
10517
|
-
|
|
10518
|
-
|
|
10519
|
-
throw new Error("Invalid proxy auth response");
|
|
10520
|
-
}
|
|
10521
|
-
const ttl = data.expiresIn ?? 300;
|
|
10522
|
-
state.accessToken = data.token;
|
|
10523
|
-
state.refreshToken = null;
|
|
10524
|
-
state.tokenFamily = null;
|
|
10525
|
-
state.accessTokenExpiry = Date.now() + ttl * 1e3;
|
|
10526
|
-
state.refreshTokenExpiry = null;
|
|
10527
|
-
state.isAuthenticated = true;
|
|
10528
|
-
if (config.autoRefresh && onRefreshScheduled) {
|
|
10529
|
-
onRefreshScheduled();
|
|
10526
|
+
case "bigint": {
|
|
10527
|
+
return bigintToString ? bigintToString(value) : "0";
|
|
10528
|
+
}
|
|
10529
|
+
case "symbol": {
|
|
10530
|
+
return symbolToString ? symbolToString(value) : "Symbol()";
|
|
10531
|
+
}
|
|
10532
|
+
case "undefined": {
|
|
10533
|
+
return objectToString(value);
|
|
10534
|
+
}
|
|
10535
|
+
case "function":
|
|
10536
|
+
case "object": {
|
|
10537
|
+
if (value === null) {
|
|
10538
|
+
return objectToString(value);
|
|
10530
10539
|
}
|
|
10531
|
-
|
|
10532
|
-
|
|
10533
|
-
if (
|
|
10534
|
-
|
|
10535
|
-
return
|
|
10540
|
+
const valueAsRecord = value;
|
|
10541
|
+
const valueToString = lookupGetter(valueAsRecord, "toString");
|
|
10542
|
+
if (typeof valueToString === "function") {
|
|
10543
|
+
const stringified = valueToString(valueAsRecord);
|
|
10544
|
+
return typeof stringified === "string" ? stringified : objectToString(stringified);
|
|
10536
10545
|
}
|
|
10546
|
+
return objectToString(value);
|
|
10547
|
+
}
|
|
10548
|
+
default: {
|
|
10549
|
+
return objectToString(value);
|
|
10537
10550
|
}
|
|
10538
10551
|
}
|
|
10539
|
-
state.isAuthenticated = false;
|
|
10540
|
-
return false;
|
|
10541
10552
|
}
|
|
10542
|
-
|
|
10543
|
-
|
|
10544
|
-
|
|
10545
|
-
|
|
10546
|
-
|
|
10547
|
-
|
|
10548
|
-
}
|
|
10549
|
-
state.isRefreshing = true;
|
|
10550
|
-
state.refreshPromise = (async () => {
|
|
10551
|
-
const reauthenticateAfterRefreshFailure = async () => {
|
|
10552
|
-
clearState(state);
|
|
10553
|
-
clearStorage(config);
|
|
10554
|
-
const authed = await authenticateServerless(config, state, onRefreshScheduled);
|
|
10555
|
-
if (authed && sendToken) sendToken();
|
|
10556
|
-
return authed;
|
|
10557
|
-
};
|
|
10558
|
-
try {
|
|
10559
|
-
const response = await fetch(`${config.apiUrl}/${config.widgetId}/auth/refresh`, {
|
|
10560
|
-
method: "POST",
|
|
10561
|
-
headers: {
|
|
10562
|
-
"Content-Type": "application/json",
|
|
10563
|
-
Authorization: `Bearer ${state.refreshToken}`
|
|
10564
|
-
},
|
|
10565
|
-
body: JSON.stringify({
|
|
10566
|
-
widgetType: config.widgetType,
|
|
10567
|
-
...buildIdentityProof(config)
|
|
10568
|
-
})
|
|
10569
|
-
});
|
|
10570
|
-
if (!response.ok) {
|
|
10571
|
-
if (response.status === 400 || response.status === 401 || response.status === 403) {
|
|
10572
|
-
return reauthenticateAfterRefreshFailure();
|
|
10573
|
-
}
|
|
10574
|
-
const error = await response.json().catch(() => ({ error: "Token refresh failed" }));
|
|
10575
|
-
throw new Error(error.error || `HTTP ${response.status}`);
|
|
10553
|
+
function lookupGetter(object, prop) {
|
|
10554
|
+
while (object !== null) {
|
|
10555
|
+
const desc = getOwnPropertyDescriptor(object, prop);
|
|
10556
|
+
if (desc) {
|
|
10557
|
+
if (desc.get) {
|
|
10558
|
+
return unapply(desc.get);
|
|
10576
10559
|
}
|
|
10577
|
-
|
|
10578
|
-
|
|
10579
|
-
throw new Error("Invalid refresh response");
|
|
10560
|
+
if (typeof desc.value === "function") {
|
|
10561
|
+
return unapply(desc.value);
|
|
10580
10562
|
}
|
|
10581
|
-
setTokens(config, state, data, onRefreshScheduled);
|
|
10582
|
-
if (sendToken) sendToken();
|
|
10583
|
-
return true;
|
|
10584
|
-
} catch {
|
|
10585
|
-
return reauthenticateAfterRefreshFailure();
|
|
10586
|
-
} finally {
|
|
10587
|
-
state.isRefreshing = false;
|
|
10588
|
-
state.refreshPromise = null;
|
|
10589
10563
|
}
|
|
10590
|
-
|
|
10591
|
-
return state.refreshPromise;
|
|
10592
|
-
}
|
|
10593
|
-
async function getValidToken(config, state, onRefreshScheduled) {
|
|
10594
|
-
if (state.accessToken && !isTokenExpired(state.accessTokenExpiry)) {
|
|
10595
|
-
return state.accessToken;
|
|
10596
|
-
}
|
|
10597
|
-
if (config.authUrl) {
|
|
10598
|
-
const authed2 = await authenticateViaProxy(config, state, onRefreshScheduled);
|
|
10599
|
-
if (authed2 && state.accessToken) return state.accessToken;
|
|
10600
|
-
throw new Error("Unable to obtain valid token");
|
|
10564
|
+
object = getPrototypeOf(object);
|
|
10601
10565
|
}
|
|
10602
|
-
|
|
10603
|
-
|
|
10604
|
-
const authed = await authenticateServerless(config, state, onRefreshScheduled);
|
|
10605
|
-
if (authed && state.accessToken) return state.accessToken;
|
|
10606
|
-
throw new Error("Unable to obtain valid token");
|
|
10607
|
-
}
|
|
10608
|
-
async function logout(config, state) {
|
|
10609
|
-
if (state.accessToken) {
|
|
10610
|
-
try {
|
|
10611
|
-
await fetch(`${config.apiUrl}/${config.widgetId}/auth/logout`, {
|
|
10612
|
-
method: "POST",
|
|
10613
|
-
headers: {
|
|
10614
|
-
"Content-Type": "application/json",
|
|
10615
|
-
Authorization: `Bearer ${state.accessToken}`
|
|
10616
|
-
},
|
|
10617
|
-
body: JSON.stringify({ refreshToken: state.refreshToken })
|
|
10618
|
-
});
|
|
10619
|
-
} catch {
|
|
10620
|
-
}
|
|
10566
|
+
function fallbackValue() {
|
|
10567
|
+
return null;
|
|
10621
10568
|
}
|
|
10622
|
-
|
|
10623
|
-
clearStorage(config);
|
|
10569
|
+
return fallbackValue;
|
|
10624
10570
|
}
|
|
10625
|
-
|
|
10626
|
-
|
|
10627
|
-
|
|
10628
|
-
|
|
10629
|
-
|
|
10630
|
-
|
|
10631
|
-
backgroundImage: data.backgroundImage
|
|
10632
|
-
};
|
|
10633
|
-
}
|
|
10634
|
-
if (data.loadingAnimation) {
|
|
10635
|
-
state.loadingAnimation = data.loadingAnimation;
|
|
10636
|
-
}
|
|
10637
|
-
if (data.themePalette) {
|
|
10638
|
-
state.themePalette = data.themePalette;
|
|
10639
|
-
}
|
|
10640
|
-
if (typeof data.font === "string" && data.font) {
|
|
10641
|
-
state.font = data.font;
|
|
10642
|
-
}
|
|
10643
|
-
if (data.defaultColorSchema === "light" || data.defaultColorSchema === "dark") {
|
|
10644
|
-
state.defaultColorSchema = data.defaultColorSchema;
|
|
10645
|
-
}
|
|
10646
|
-
}
|
|
10647
|
-
async function fetchErrorSettings(config, state, opts = {}) {
|
|
10648
|
-
if (!opts.skipCache) {
|
|
10649
|
-
const cached = loadErrorSettingsFromStorage(config);
|
|
10650
|
-
if (cached) {
|
|
10651
|
-
applyErrorSettingsToState(state, cached);
|
|
10652
|
-
return state.errorSettings;
|
|
10653
|
-
}
|
|
10654
|
-
}
|
|
10655
|
-
const url = `${config.apiUrl}/${config.widgetId}/auth/error-settings?widgetType=${config.widgetType}`;
|
|
10656
|
-
let promise = inflightErrorSettings.get(url);
|
|
10657
|
-
if (!promise) {
|
|
10658
|
-
promise = (async () => {
|
|
10659
|
-
try {
|
|
10660
|
-
const response = await fetch(url, {
|
|
10661
|
-
method: "GET",
|
|
10662
|
-
headers: { "Content-Type": "application/json" }
|
|
10663
|
-
});
|
|
10664
|
-
if (!response.ok) return null;
|
|
10665
|
-
const data2 = await response.json();
|
|
10666
|
-
saveErrorSettingsToStorage(config, data2);
|
|
10667
|
-
return data2;
|
|
10668
|
-
} catch {
|
|
10669
|
-
return null;
|
|
10670
|
-
} finally {
|
|
10671
|
-
inflightErrorSettings.delete(url);
|
|
10672
|
-
}
|
|
10673
|
-
})();
|
|
10674
|
-
inflightErrorSettings.set(url, promise);
|
|
10675
|
-
}
|
|
10676
|
-
const data = await promise;
|
|
10677
|
-
if (!data) return null;
|
|
10678
|
-
applyErrorSettingsToState(state, data);
|
|
10679
|
-
return state.errorSettings;
|
|
10680
|
-
}
|
|
10681
|
-
function clearState(state) {
|
|
10682
|
-
state.accessToken = null;
|
|
10683
|
-
state.refreshToken = null;
|
|
10684
|
-
state.tokenFamily = null;
|
|
10685
|
-
state.accessTokenExpiry = null;
|
|
10686
|
-
state.refreshTokenExpiry = null;
|
|
10687
|
-
state.isAuthenticated = false;
|
|
10688
|
-
state.isRefreshing = false;
|
|
10689
|
-
state.refreshPromise = null;
|
|
10690
|
-
state.lastAuthError = null;
|
|
10691
|
-
if (state.refreshTimer) {
|
|
10692
|
-
clearTimeout(state.refreshTimer);
|
|
10693
|
-
state.refreshTimer = null;
|
|
10694
|
-
}
|
|
10695
|
-
if (state.syncTimer) {
|
|
10696
|
-
clearInterval(state.syncTimer);
|
|
10697
|
-
state.syncTimer = null;
|
|
10698
|
-
}
|
|
10699
|
-
}
|
|
10700
|
-
const STORE_CALLBACK_FIELD_OPTIONS_SCOPE = "store.callback_field_options";
|
|
10701
|
-
const STORE_CALLBACK_FIELD_OPTIONS_CALLBACK_NAME = "callbackFieldOptions";
|
|
10702
|
-
const STORE_CALLBACK_FIELD_OPTIONS_TIMEOUT_MS = 15e3;
|
|
10703
|
-
function debounce(fn, wait) {
|
|
10704
|
-
let timer = null;
|
|
10705
|
-
return {
|
|
10706
|
-
call(h) {
|
|
10707
|
-
if (timer) clearTimeout(timer);
|
|
10708
|
-
timer = setTimeout(() => {
|
|
10709
|
-
fn(h);
|
|
10710
|
-
timer = null;
|
|
10711
|
-
}, wait);
|
|
10712
|
-
},
|
|
10713
|
-
cancel() {
|
|
10714
|
-
if (timer) {
|
|
10715
|
-
clearTimeout(timer);
|
|
10716
|
-
timer = null;
|
|
10717
|
-
}
|
|
10718
|
-
}
|
|
10719
|
-
};
|
|
10720
|
-
}
|
|
10721
|
-
function sendTokenToWidget(config, state, iframe) {
|
|
10722
|
-
var _a;
|
|
10723
|
-
if (!state.accessToken) return;
|
|
10724
|
-
try {
|
|
10725
|
-
(_a = iframe.contentWindow) == null ? void 0 : _a.postMessage(
|
|
10726
|
-
{
|
|
10727
|
-
type: "RETURNINGAI_WIDGET_TOKEN",
|
|
10728
|
-
value: {
|
|
10729
|
-
widgetId: config.widgetId,
|
|
10730
|
-
token: state.accessToken,
|
|
10731
|
-
...config.customData !== void 0 && { customData: config.customData }
|
|
10732
|
-
}
|
|
10733
|
-
},
|
|
10734
|
-
config.widgetDomain
|
|
10735
|
-
);
|
|
10736
|
-
} catch {
|
|
10737
|
-
}
|
|
10738
|
-
}
|
|
10739
|
-
function setupMessageListener(config, state, _shadow, iframe, onRefreshScheduled, onLogout, hideLoader, emit, getCallbacks) {
|
|
10740
|
-
const heightSetter = debounce((h) => {
|
|
10741
|
-
iframe.style.height = `${h}px`;
|
|
10742
|
-
emit == null ? void 0 : emit("rai-height-change", { height: h });
|
|
10743
|
-
}, config.heightDebounce ?? 100);
|
|
10744
|
-
const handler = async (event) => {
|
|
10745
|
-
var _a, _b;
|
|
10746
|
-
if (event.origin !== config.widgetDomain) return;
|
|
10747
|
-
if (!event.data || typeof event.data.type !== "string") return;
|
|
10748
|
-
const { type, containerId, widgetId, payload } = event.data;
|
|
10749
|
-
switch (type) {
|
|
10750
|
-
case "RETURNINGAI_WIDGET_REQUEST_TOKEN": {
|
|
10751
|
-
try {
|
|
10752
|
-
const token = await getValidToken(config, state, onRefreshScheduled);
|
|
10753
|
-
(_a = iframe.contentWindow) == null ? void 0 : _a.postMessage(
|
|
10754
|
-
{
|
|
10755
|
-
type: "RETURNINGAI_WIDGET_TOKEN",
|
|
10756
|
-
value: {
|
|
10757
|
-
token,
|
|
10758
|
-
widgetId: config.widgetId,
|
|
10759
|
-
...config.customData !== void 0 && { customData: config.customData }
|
|
10760
|
-
}
|
|
10761
|
-
},
|
|
10762
|
-
config.widgetDomain
|
|
10763
|
-
);
|
|
10764
|
-
} catch {
|
|
10765
|
-
}
|
|
10766
|
-
break;
|
|
10767
|
-
}
|
|
10768
|
-
case "WIDGET_HEIGHT_UPDATE": {
|
|
10769
|
-
const h = Number(payload == null ? void 0 : payload.height);
|
|
10770
|
-
if (Number.isFinite(h) && h > 0) {
|
|
10771
|
-
heightSetter.call(h);
|
|
10772
|
-
}
|
|
10773
|
-
break;
|
|
10774
|
-
}
|
|
10775
|
-
case "WIDGET_READY": {
|
|
10776
|
-
if (widgetId !== void 0 && widgetId !== config.widgetId) break;
|
|
10777
|
-
if (containerId !== void 0 && containerId !== config.container) break;
|
|
10778
|
-
iframe.classList.add("loaded");
|
|
10779
|
-
if (hideLoader) hideLoader();
|
|
10780
|
-
emit == null ? void 0 : emit("rai-ready");
|
|
10781
|
-
break;
|
|
10782
|
-
}
|
|
10783
|
-
case "WIDGET_ERROR": {
|
|
10784
|
-
if (hideLoader) hideLoader();
|
|
10785
|
-
break;
|
|
10786
|
-
}
|
|
10787
|
-
case "WIDGET_LOGOUT": {
|
|
10788
|
-
if (onLogout) await onLogout();
|
|
10789
|
-
break;
|
|
10790
|
-
}
|
|
10791
|
-
case "RETURNINGAI_WIDGET_ACTION": {
|
|
10792
|
-
if (event.source !== iframe.contentWindow) break;
|
|
10793
|
-
const message = event.data;
|
|
10794
|
-
if (config.widgetType !== "store" && config.widgetType !== "custom") break;
|
|
10795
|
-
if (message.widgetType !== "store") break;
|
|
10796
|
-
if (message.action !== "store:host-callback") break;
|
|
10797
|
-
if (message.callbackName !== STORE_CALLBACK_FIELD_OPTIONS_CALLBACK_NAME) break;
|
|
10798
|
-
if (((_b = message.payload) == null ? void 0 : _b.scope) !== STORE_CALLBACK_FIELD_OPTIONS_SCOPE) break;
|
|
10799
|
-
if (message.widgetId !== void 0 && message.widgetId !== config.widgetId) break;
|
|
10800
|
-
if (message.containerId !== void 0 && message.containerId !== config.container) break;
|
|
10801
|
-
const respond = (result) => {
|
|
10802
|
-
var _a2;
|
|
10803
|
-
(_a2 = iframe.contentWindow) == null ? void 0 : _a2.postMessage(result, config.widgetDomain);
|
|
10804
|
-
};
|
|
10805
|
-
const callbacks = (getCallbacks == null ? void 0 : getCallbacks()) ?? {};
|
|
10806
|
-
const callback = callbacks[message.callbackName];
|
|
10807
|
-
if (!callback) {
|
|
10808
|
-
respond({
|
|
10809
|
-
type: "RETURNINGAI_WIDGET_ACTION_RESULT",
|
|
10810
|
-
requestId: message.requestId,
|
|
10811
|
-
action: "store:host-callback",
|
|
10812
|
-
ok: false,
|
|
10813
|
-
status: "failed",
|
|
10814
|
-
error: { message: "Host callback is not registered" }
|
|
10815
|
-
});
|
|
10816
|
-
break;
|
|
10817
|
-
}
|
|
10818
|
-
try {
|
|
10819
|
-
const value = await callback(message.payload);
|
|
10820
|
-
respond({
|
|
10821
|
-
type: "RETURNINGAI_WIDGET_ACTION_RESULT",
|
|
10822
|
-
requestId: message.requestId,
|
|
10823
|
-
action: "store:host-callback",
|
|
10824
|
-
ok: true,
|
|
10825
|
-
status: "success",
|
|
10826
|
-
value
|
|
10827
|
-
});
|
|
10828
|
-
} catch {
|
|
10829
|
-
respond({
|
|
10830
|
-
type: "RETURNINGAI_WIDGET_ACTION_RESULT",
|
|
10831
|
-
requestId: message.requestId,
|
|
10832
|
-
action: "store:host-callback",
|
|
10833
|
-
ok: false,
|
|
10834
|
-
status: "failed",
|
|
10835
|
-
error: { message: "Host callback failed" }
|
|
10836
|
-
});
|
|
10837
|
-
}
|
|
10838
|
-
break;
|
|
10839
|
-
}
|
|
10840
|
-
}
|
|
10841
|
-
};
|
|
10842
|
-
window.addEventListener("message", handler);
|
|
10843
|
-
return () => {
|
|
10844
|
-
window.removeEventListener("message", handler);
|
|
10845
|
-
heightSetter.cancel();
|
|
10846
|
-
};
|
|
10847
|
-
}
|
|
10848
|
-
function assertCallbackName(callbackName) {
|
|
10849
|
-
if (!callbackName || typeof callbackName !== "string") {
|
|
10850
|
-
throw new TypeError("ReturningAI callback name must be a non-empty string");
|
|
10851
|
-
}
|
|
10852
|
-
}
|
|
10853
|
-
function assertCallback(callback) {
|
|
10854
|
-
if (typeof callback !== "function") {
|
|
10855
|
-
throw new TypeError("ReturningAI callback must be a function");
|
|
10856
|
-
}
|
|
10857
|
-
}
|
|
10858
|
-
class WidgetCallbackRegistry {
|
|
10859
|
-
constructor() {
|
|
10860
|
-
__publicField(this, "registeredCallbacks", {});
|
|
10861
|
-
__publicField(this, "locked", false);
|
|
10862
|
-
}
|
|
10863
|
-
get isLocked() {
|
|
10864
|
-
return this.locked;
|
|
10865
|
-
}
|
|
10866
|
-
registerCallback(callbackName, callback) {
|
|
10867
|
-
if (this.locked) {
|
|
10868
|
-
return;
|
|
10869
|
-
}
|
|
10870
|
-
assertCallbackName(callbackName);
|
|
10871
|
-
assertCallback(callback);
|
|
10872
|
-
this.registeredCallbacks = {
|
|
10873
|
-
...this.registeredCallbacks,
|
|
10874
|
-
[callbackName]: callback
|
|
10875
|
-
};
|
|
10876
|
-
}
|
|
10877
|
-
lock() {
|
|
10878
|
-
if (this.locked) {
|
|
10879
|
-
return;
|
|
10880
|
-
}
|
|
10881
|
-
this.locked = true;
|
|
10882
|
-
}
|
|
10883
|
-
read() {
|
|
10884
|
-
return { ...this.registeredCallbacks };
|
|
10885
|
-
}
|
|
10886
|
-
}
|
|
10887
|
-
async function fetchEligibleBanner(apiUrl, request) {
|
|
10888
|
-
try {
|
|
10889
|
-
const res = await fetch(`${apiUrl}/v2/api/banner-sdk/eligible`, {
|
|
10890
|
-
method: "POST",
|
|
10891
|
-
headers: { "Content-Type": "application/json" },
|
|
10892
|
-
body: JSON.stringify(request)
|
|
10893
|
-
});
|
|
10894
|
-
const json = await res.json();
|
|
10895
|
-
if (json && json.meta && json.meta.status === "success") {
|
|
10896
|
-
return json.data || { banner: null };
|
|
10897
|
-
}
|
|
10898
|
-
return { banner: null, reason: json && json.detail || "request_failed" };
|
|
10899
|
-
} catch {
|
|
10900
|
-
return { banner: null, reason: "network_error" };
|
|
10901
|
-
}
|
|
10902
|
-
}
|
|
10903
|
-
/*! @license DOMPurify 3.4.9 | (c) Cure53 and other contributors | Released under the Apache license 2.0 and Mozilla Public License 2.0 | github.com/cure53/DOMPurify/blob/3.4.9/LICENSE */
|
|
10904
|
-
function _arrayLikeToArray(r, a) {
|
|
10905
|
-
(null == a || a > r.length) && (a = r.length);
|
|
10906
|
-
for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e];
|
|
10907
|
-
return n;
|
|
10908
|
-
}
|
|
10909
|
-
function _arrayWithHoles(r) {
|
|
10910
|
-
if (Array.isArray(r)) return r;
|
|
10911
|
-
}
|
|
10912
|
-
function _iterableToArrayLimit(r, l) {
|
|
10913
|
-
var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"];
|
|
10914
|
-
if (null != t) {
|
|
10915
|
-
var e, n, i, u, a = [], f = true, o = false;
|
|
10916
|
-
try {
|
|
10917
|
-
if (i = (t = t.call(r)).next, 0 === l) ;
|
|
10918
|
-
else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = true) ;
|
|
10919
|
-
} catch (r2) {
|
|
10920
|
-
o = true, n = r2;
|
|
10921
|
-
} finally {
|
|
10922
|
-
try {
|
|
10923
|
-
if (!f && null != t.return && (u = t.return(), Object(u) !== u)) return;
|
|
10924
|
-
} finally {
|
|
10925
|
-
if (o) throw n;
|
|
10926
|
-
}
|
|
10927
|
-
}
|
|
10928
|
-
return a;
|
|
10929
|
-
}
|
|
10930
|
-
}
|
|
10931
|
-
function _nonIterableRest() {
|
|
10932
|
-
throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
|
|
10933
|
-
}
|
|
10934
|
-
function _slicedToArray(r, e) {
|
|
10935
|
-
return _arrayWithHoles(r) || _iterableToArrayLimit(r, e) || _unsupportedIterableToArray(r, e) || _nonIterableRest();
|
|
10936
|
-
}
|
|
10937
|
-
function _unsupportedIterableToArray(r, a) {
|
|
10938
|
-
if (r) {
|
|
10939
|
-
if ("string" == typeof r) return _arrayLikeToArray(r, a);
|
|
10940
|
-
var t = {}.toString.call(r).slice(8, -1);
|
|
10941
|
-
return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0;
|
|
10942
|
-
}
|
|
10943
|
-
}
|
|
10944
|
-
const entries = Object.entries, setPrototypeOf = Object.setPrototypeOf, isFrozen = Object.isFrozen, getPrototypeOf = Object.getPrototypeOf, getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor;
|
|
10945
|
-
let freeze = Object.freeze, seal = Object.seal, create = Object.create;
|
|
10946
|
-
let _ref = typeof Reflect !== "undefined" && Reflect, apply = _ref.apply, construct = _ref.construct;
|
|
10947
|
-
if (!freeze) {
|
|
10948
|
-
freeze = function freeze2(x) {
|
|
10949
|
-
return x;
|
|
10950
|
-
};
|
|
10951
|
-
}
|
|
10952
|
-
if (!seal) {
|
|
10953
|
-
seal = function seal2(x) {
|
|
10954
|
-
return x;
|
|
10955
|
-
};
|
|
10956
|
-
}
|
|
10957
|
-
if (!apply) {
|
|
10958
|
-
apply = function apply2(func, thisArg) {
|
|
10959
|
-
for (var _len = arguments.length, args = new Array(_len > 2 ? _len - 2 : 0), _key = 2; _key < _len; _key++) {
|
|
10960
|
-
args[_key - 2] = arguments[_key];
|
|
10961
|
-
}
|
|
10962
|
-
return func.apply(thisArg, args);
|
|
10963
|
-
};
|
|
10964
|
-
}
|
|
10965
|
-
if (!construct) {
|
|
10966
|
-
construct = function construct2(Func) {
|
|
10967
|
-
for (var _len2 = arguments.length, args = new Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) {
|
|
10968
|
-
args[_key2 - 1] = arguments[_key2];
|
|
10969
|
-
}
|
|
10970
|
-
return new Func(...args);
|
|
10971
|
-
};
|
|
10972
|
-
}
|
|
10973
|
-
const arrayForEach = unapply(Array.prototype.forEach);
|
|
10974
|
-
const arrayLastIndexOf = unapply(Array.prototype.lastIndexOf);
|
|
10975
|
-
const arrayPop = unapply(Array.prototype.pop);
|
|
10976
|
-
const arrayPush = unapply(Array.prototype.push);
|
|
10977
|
-
const arraySplice = unapply(Array.prototype.splice);
|
|
10978
|
-
const arrayIsArray = Array.isArray;
|
|
10979
|
-
const stringToLowerCase = unapply(String.prototype.toLowerCase);
|
|
10980
|
-
const stringToString = unapply(String.prototype.toString);
|
|
10981
|
-
const stringMatch = unapply(String.prototype.match);
|
|
10982
|
-
const stringReplace = unapply(String.prototype.replace);
|
|
10983
|
-
const stringIndexOf = unapply(String.prototype.indexOf);
|
|
10984
|
-
const stringTrim = unapply(String.prototype.trim);
|
|
10985
|
-
const numberToString = unapply(Number.prototype.toString);
|
|
10986
|
-
const booleanToString = unapply(Boolean.prototype.toString);
|
|
10987
|
-
const bigintToString = typeof BigInt === "undefined" ? null : unapply(BigInt.prototype.toString);
|
|
10988
|
-
const symbolToString = typeof Symbol === "undefined" ? null : unapply(Symbol.prototype.toString);
|
|
10989
|
-
const objectHasOwnProperty = unapply(Object.prototype.hasOwnProperty);
|
|
10990
|
-
const objectToString = unapply(Object.prototype.toString);
|
|
10991
|
-
const regExpTest = unapply(RegExp.prototype.test);
|
|
10992
|
-
const typeErrorCreate = unconstruct(TypeError);
|
|
10993
|
-
function unapply(func) {
|
|
10994
|
-
return function(thisArg) {
|
|
10995
|
-
if (thisArg instanceof RegExp) {
|
|
10996
|
-
thisArg.lastIndex = 0;
|
|
10997
|
-
}
|
|
10998
|
-
for (var _len3 = arguments.length, args = new Array(_len3 > 1 ? _len3 - 1 : 0), _key3 = 1; _key3 < _len3; _key3++) {
|
|
10999
|
-
args[_key3 - 1] = arguments[_key3];
|
|
11000
|
-
}
|
|
11001
|
-
return apply(func, thisArg, args);
|
|
11002
|
-
};
|
|
11003
|
-
}
|
|
11004
|
-
function unconstruct(Func) {
|
|
11005
|
-
return function() {
|
|
11006
|
-
for (var _len4 = arguments.length, args = new Array(_len4), _key4 = 0; _key4 < _len4; _key4++) {
|
|
11007
|
-
args[_key4] = arguments[_key4];
|
|
11008
|
-
}
|
|
11009
|
-
return construct(Func, args);
|
|
11010
|
-
};
|
|
11011
|
-
}
|
|
11012
|
-
function addToSet(set, array) {
|
|
11013
|
-
let transformCaseFunc = arguments.length > 2 && arguments[2] !== void 0 ? arguments[2] : stringToLowerCase;
|
|
11014
|
-
if (setPrototypeOf) {
|
|
11015
|
-
setPrototypeOf(set, null);
|
|
11016
|
-
}
|
|
11017
|
-
if (!arrayIsArray(array)) {
|
|
11018
|
-
return set;
|
|
11019
|
-
}
|
|
11020
|
-
let l = array.length;
|
|
11021
|
-
while (l--) {
|
|
11022
|
-
let element = array[l];
|
|
11023
|
-
if (typeof element === "string") {
|
|
11024
|
-
const lcElement = transformCaseFunc(element);
|
|
11025
|
-
if (lcElement !== element) {
|
|
11026
|
-
if (!isFrozen(array)) {
|
|
11027
|
-
array[l] = lcElement;
|
|
11028
|
-
}
|
|
11029
|
-
element = lcElement;
|
|
11030
|
-
}
|
|
11031
|
-
}
|
|
11032
|
-
set[element] = true;
|
|
11033
|
-
}
|
|
11034
|
-
return set;
|
|
11035
|
-
}
|
|
11036
|
-
function cleanArray(array) {
|
|
11037
|
-
for (let index = 0; index < array.length; index++) {
|
|
11038
|
-
const isPropertyExist = objectHasOwnProperty(array, index);
|
|
11039
|
-
if (!isPropertyExist) {
|
|
11040
|
-
array[index] = null;
|
|
11041
|
-
}
|
|
11042
|
-
}
|
|
11043
|
-
return array;
|
|
11044
|
-
}
|
|
11045
|
-
function clone(object) {
|
|
11046
|
-
const newObject = create(null);
|
|
11047
|
-
for (const _ref2 of entries(object)) {
|
|
11048
|
-
var _ref3 = _slicedToArray(_ref2, 2);
|
|
11049
|
-
const property = _ref3[0];
|
|
11050
|
-
const value = _ref3[1];
|
|
11051
|
-
const isPropertyExist = objectHasOwnProperty(object, property);
|
|
11052
|
-
if (isPropertyExist) {
|
|
11053
|
-
if (arrayIsArray(value)) {
|
|
11054
|
-
newObject[property] = cleanArray(value);
|
|
11055
|
-
} else if (value && typeof value === "object" && value.constructor === Object) {
|
|
11056
|
-
newObject[property] = clone(value);
|
|
11057
|
-
} else {
|
|
11058
|
-
newObject[property] = value;
|
|
11059
|
-
}
|
|
11060
|
-
}
|
|
11061
|
-
}
|
|
11062
|
-
return newObject;
|
|
11063
|
-
}
|
|
11064
|
-
function stringifyValue(value) {
|
|
11065
|
-
switch (typeof value) {
|
|
11066
|
-
case "string": {
|
|
11067
|
-
return value;
|
|
11068
|
-
}
|
|
11069
|
-
case "number": {
|
|
11070
|
-
return numberToString(value);
|
|
11071
|
-
}
|
|
11072
|
-
case "boolean": {
|
|
11073
|
-
return booleanToString(value);
|
|
11074
|
-
}
|
|
11075
|
-
case "bigint": {
|
|
11076
|
-
return bigintToString ? bigintToString(value) : "0";
|
|
11077
|
-
}
|
|
11078
|
-
case "symbol": {
|
|
11079
|
-
return symbolToString ? symbolToString(value) : "Symbol()";
|
|
11080
|
-
}
|
|
11081
|
-
case "undefined": {
|
|
11082
|
-
return objectToString(value);
|
|
11083
|
-
}
|
|
11084
|
-
case "function":
|
|
11085
|
-
case "object": {
|
|
11086
|
-
if (value === null) {
|
|
11087
|
-
return objectToString(value);
|
|
11088
|
-
}
|
|
11089
|
-
const valueAsRecord = value;
|
|
11090
|
-
const valueToString = lookupGetter(valueAsRecord, "toString");
|
|
11091
|
-
if (typeof valueToString === "function") {
|
|
11092
|
-
const stringified = valueToString(valueAsRecord);
|
|
11093
|
-
return typeof stringified === "string" ? stringified : objectToString(stringified);
|
|
11094
|
-
}
|
|
11095
|
-
return objectToString(value);
|
|
11096
|
-
}
|
|
11097
|
-
default: {
|
|
11098
|
-
return objectToString(value);
|
|
11099
|
-
}
|
|
11100
|
-
}
|
|
11101
|
-
}
|
|
11102
|
-
function lookupGetter(object, prop) {
|
|
11103
|
-
while (object !== null) {
|
|
11104
|
-
const desc = getOwnPropertyDescriptor(object, prop);
|
|
11105
|
-
if (desc) {
|
|
11106
|
-
if (desc.get) {
|
|
11107
|
-
return unapply(desc.get);
|
|
11108
|
-
}
|
|
11109
|
-
if (typeof desc.value === "function") {
|
|
11110
|
-
return unapply(desc.value);
|
|
11111
|
-
}
|
|
11112
|
-
}
|
|
11113
|
-
object = getPrototypeOf(object);
|
|
11114
|
-
}
|
|
11115
|
-
function fallbackValue() {
|
|
11116
|
-
return null;
|
|
11117
|
-
}
|
|
11118
|
-
return fallbackValue;
|
|
11119
|
-
}
|
|
11120
|
-
function isRegex(value) {
|
|
11121
|
-
try {
|
|
11122
|
-
regExpTest(value, "");
|
|
11123
|
-
return true;
|
|
11124
|
-
} catch (_unused) {
|
|
11125
|
-
return false;
|
|
10571
|
+
function isRegex(value) {
|
|
10572
|
+
try {
|
|
10573
|
+
regExpTest(value, "");
|
|
10574
|
+
return true;
|
|
10575
|
+
} catch (_unused) {
|
|
10576
|
+
return false;
|
|
11126
10577
|
}
|
|
11127
10578
|
}
|
|
11128
10579
|
const html$1 = freeze(["a", "abbr", "acronym", "address", "area", "article", "aside", "audio", "b", "bdi", "bdo", "big", "blink", "blockquote", "body", "br", "button", "canvas", "caption", "center", "cite", "code", "col", "colgroup", "content", "data", "datalist", "dd", "decorator", "del", "details", "dfn", "dialog", "dir", "div", "dl", "dt", "element", "em", "fieldset", "figcaption", "figure", "font", "footer", "form", "h1", "h2", "h3", "h4", "h5", "h6", "head", "header", "hgroup", "hr", "html", "i", "img", "input", "ins", "kbd", "label", "legend", "li", "main", "map", "mark", "marquee", "menu", "menuitem", "meter", "nav", "nobr", "ol", "optgroup", "option", "output", "p", "picture", "pre", "progress", "q", "rp", "rt", "ruby", "s", "samp", "search", "section", "select", "shadow", "slot", "small", "source", "spacer", "span", "strike", "strong", "style", "sub", "summary", "sup", "table", "tbody", "td", "template", "textarea", "tfoot", "th", "thead", "time", "tr", "track", "tt", "u", "ul", "var", "video", "wbr"]);
|
|
@@ -11225,7 +10676,7 @@ function createDOMPurify() {
|
|
|
11225
10676
|
const HTMLTemplateElement = window2.HTMLTemplateElement, Node = window2.Node, Element = window2.Element, NodeFilter = window2.NodeFilter, _window$NamedNodeMap = window2.NamedNodeMap;
|
|
11226
10677
|
_window$NamedNodeMap === void 0 ? window2.NamedNodeMap || window2.MozNamedAttrMap : _window$NamedNodeMap;
|
|
11227
10678
|
window2.HTMLFormElement;
|
|
11228
|
-
const
|
|
10679
|
+
const DOMParser = window2.DOMParser, trustedTypes = window2.trustedTypes;
|
|
11229
10680
|
const ElementPrototype = Element.prototype;
|
|
11230
10681
|
const cloneNode = lookupGetter(ElementPrototype, "cloneNode");
|
|
11231
10682
|
const remove = lookupGetter(ElementPrototype, "remove");
|
|
@@ -11729,7 +11180,7 @@ function createDOMPurify() {
|
|
|
11729
11180
|
const dirtyPayload = trustedTypesPolicy ? _createTrustedHTML(dirty) : dirty;
|
|
11730
11181
|
if (NAMESPACE === HTML_NAMESPACE) {
|
|
11731
11182
|
try {
|
|
11732
|
-
doc = new
|
|
11183
|
+
doc = new DOMParser().parseFromString(dirtyPayload, PARSER_MEDIA_TYPE);
|
|
11733
11184
|
} catch (_) {
|
|
11734
11185
|
}
|
|
11735
11186
|
}
|
|
@@ -12116,575 +11567,1265 @@ function createDOMPurify() {
|
|
|
12116
11567
|
}
|
|
12117
11568
|
}
|
|
12118
11569
|
};
|
|
12119
|
-
DOMPurify.sanitize = function(dirty) {
|
|
12120
|
-
let cfg = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : {};
|
|
12121
|
-
let body = null;
|
|
12122
|
-
let importedNode = null;
|
|
12123
|
-
let currentNode = null;
|
|
12124
|
-
let returnNode = null;
|
|
12125
|
-
IS_EMPTY_INPUT = !dirty;
|
|
12126
|
-
if (IS_EMPTY_INPUT) {
|
|
12127
|
-
dirty = "<!-->";
|
|
11570
|
+
DOMPurify.sanitize = function(dirty) {
|
|
11571
|
+
let cfg = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : {};
|
|
11572
|
+
let body = null;
|
|
11573
|
+
let importedNode = null;
|
|
11574
|
+
let currentNode = null;
|
|
11575
|
+
let returnNode = null;
|
|
11576
|
+
IS_EMPTY_INPUT = !dirty;
|
|
11577
|
+
if (IS_EMPTY_INPUT) {
|
|
11578
|
+
dirty = "<!-->";
|
|
11579
|
+
}
|
|
11580
|
+
if (typeof dirty !== "string" && !_isNode(dirty)) {
|
|
11581
|
+
dirty = stringifyValue(dirty);
|
|
11582
|
+
if (typeof dirty !== "string") {
|
|
11583
|
+
throw typeErrorCreate("dirty is not a string, aborting");
|
|
11584
|
+
}
|
|
11585
|
+
}
|
|
11586
|
+
if (!DOMPurify.isSupported) {
|
|
11587
|
+
return dirty;
|
|
11588
|
+
}
|
|
11589
|
+
if (!SET_CONFIG) {
|
|
11590
|
+
_parseConfig(cfg);
|
|
11591
|
+
}
|
|
11592
|
+
DOMPurify.removed = [];
|
|
11593
|
+
const inPlace = IN_PLACE && typeof dirty !== "string" && _isNode(dirty);
|
|
11594
|
+
if (inPlace) {
|
|
11595
|
+
const nn = getNodeName ? getNodeName(dirty) : dirty.nodeName;
|
|
11596
|
+
if (typeof nn === "string") {
|
|
11597
|
+
const tagName = transformCaseFunc(nn);
|
|
11598
|
+
if (!ALLOWED_TAGS[tagName] || FORBID_TAGS[tagName]) {
|
|
11599
|
+
throw typeErrorCreate("root node is forbidden and cannot be sanitized in-place");
|
|
11600
|
+
}
|
|
11601
|
+
}
|
|
11602
|
+
if (_isClobbered(dirty)) {
|
|
11603
|
+
throw typeErrorCreate("root node is clobbered and cannot be sanitized in-place");
|
|
11604
|
+
}
|
|
11605
|
+
try {
|
|
11606
|
+
_sanitizeAttachedShadowRoots(dirty);
|
|
11607
|
+
} catch (error) {
|
|
11608
|
+
_neutralizeRoot(dirty);
|
|
11609
|
+
throw error;
|
|
11610
|
+
}
|
|
11611
|
+
} else if (_isNode(dirty)) {
|
|
11612
|
+
body = _initDocument("<!---->");
|
|
11613
|
+
importedNode = body.ownerDocument.importNode(dirty, true);
|
|
11614
|
+
if (importedNode.nodeType === NODE_TYPE.element && importedNode.nodeName === "BODY") {
|
|
11615
|
+
body = importedNode;
|
|
11616
|
+
} else if (importedNode.nodeName === "HTML") {
|
|
11617
|
+
body = importedNode;
|
|
11618
|
+
} else {
|
|
11619
|
+
body.appendChild(importedNode);
|
|
11620
|
+
}
|
|
11621
|
+
_sanitizeAttachedShadowRoots(importedNode);
|
|
11622
|
+
} else {
|
|
11623
|
+
if (!RETURN_DOM && !SAFE_FOR_TEMPLATES && !WHOLE_DOCUMENT && // eslint-disable-next-line unicorn/prefer-includes
|
|
11624
|
+
dirty.indexOf("<") === -1) {
|
|
11625
|
+
return trustedTypesPolicy && RETURN_TRUSTED_TYPE ? _createTrustedHTML(dirty) : dirty;
|
|
11626
|
+
}
|
|
11627
|
+
body = _initDocument(dirty);
|
|
11628
|
+
if (!body) {
|
|
11629
|
+
return RETURN_DOM ? null : RETURN_TRUSTED_TYPE ? emptyHTML : "";
|
|
11630
|
+
}
|
|
11631
|
+
}
|
|
11632
|
+
if (body && FORCE_BODY) {
|
|
11633
|
+
_forceRemove(body.firstChild);
|
|
11634
|
+
}
|
|
11635
|
+
const nodeIterator = _createNodeIterator(inPlace ? dirty : body);
|
|
11636
|
+
try {
|
|
11637
|
+
while (currentNode = nodeIterator.nextNode()) {
|
|
11638
|
+
_sanitizeElements(currentNode);
|
|
11639
|
+
_sanitizeAttributes(currentNode);
|
|
11640
|
+
if (_isDocumentFragment(currentNode.content)) {
|
|
11641
|
+
_sanitizeShadowDOM2(currentNode.content);
|
|
11642
|
+
}
|
|
11643
|
+
}
|
|
11644
|
+
} catch (error) {
|
|
11645
|
+
if (inPlace) {
|
|
11646
|
+
_neutralizeRoot(dirty);
|
|
11647
|
+
}
|
|
11648
|
+
throw error;
|
|
11649
|
+
}
|
|
11650
|
+
if (inPlace) {
|
|
11651
|
+
arrayForEach(DOMPurify.removed, (entry) => {
|
|
11652
|
+
if (entry.element) {
|
|
11653
|
+
_neutralizeSubtree(entry.element);
|
|
11654
|
+
}
|
|
11655
|
+
});
|
|
11656
|
+
if (SAFE_FOR_TEMPLATES) {
|
|
11657
|
+
_scrubTemplateExpressions2(dirty);
|
|
11658
|
+
}
|
|
11659
|
+
return dirty;
|
|
11660
|
+
}
|
|
11661
|
+
if (RETURN_DOM) {
|
|
11662
|
+
if (SAFE_FOR_TEMPLATES) {
|
|
11663
|
+
_scrubTemplateExpressions2(body);
|
|
11664
|
+
}
|
|
11665
|
+
if (RETURN_DOM_FRAGMENT) {
|
|
11666
|
+
returnNode = createDocumentFragment.call(body.ownerDocument);
|
|
11667
|
+
while (body.firstChild) {
|
|
11668
|
+
returnNode.appendChild(body.firstChild);
|
|
11669
|
+
}
|
|
11670
|
+
} else {
|
|
11671
|
+
returnNode = body;
|
|
11672
|
+
}
|
|
11673
|
+
if (ALLOWED_ATTR.shadowroot || ALLOWED_ATTR.shadowrootmode) {
|
|
11674
|
+
returnNode = importNode.call(originalDocument, returnNode, true);
|
|
11675
|
+
}
|
|
11676
|
+
return returnNode;
|
|
11677
|
+
}
|
|
11678
|
+
let serializedHTML = WHOLE_DOCUMENT ? body.outerHTML : body.innerHTML;
|
|
11679
|
+
if (WHOLE_DOCUMENT && ALLOWED_TAGS["!doctype"] && body.ownerDocument && body.ownerDocument.doctype && body.ownerDocument.doctype.name && regExpTest(DOCTYPE_NAME, body.ownerDocument.doctype.name)) {
|
|
11680
|
+
serializedHTML = "<!DOCTYPE " + body.ownerDocument.doctype.name + ">\n" + serializedHTML;
|
|
11681
|
+
}
|
|
11682
|
+
if (SAFE_FOR_TEMPLATES) {
|
|
11683
|
+
arrayForEach([MUSTACHE_EXPR$1, ERB_EXPR$1, TMPLIT_EXPR$1], (expr) => {
|
|
11684
|
+
serializedHTML = stringReplace(serializedHTML, expr, " ");
|
|
11685
|
+
});
|
|
11686
|
+
}
|
|
11687
|
+
return trustedTypesPolicy && RETURN_TRUSTED_TYPE ? _createTrustedHTML(serializedHTML) : serializedHTML;
|
|
11688
|
+
};
|
|
11689
|
+
DOMPurify.setConfig = function() {
|
|
11690
|
+
let cfg = arguments.length > 0 && arguments[0] !== void 0 ? arguments[0] : {};
|
|
11691
|
+
_parseConfig(cfg);
|
|
11692
|
+
SET_CONFIG = true;
|
|
11693
|
+
};
|
|
11694
|
+
DOMPurify.clearConfig = function() {
|
|
11695
|
+
CONFIG = null;
|
|
11696
|
+
SET_CONFIG = false;
|
|
11697
|
+
trustedTypesPolicy = defaultTrustedTypesPolicy;
|
|
11698
|
+
emptyHTML = "";
|
|
11699
|
+
};
|
|
11700
|
+
DOMPurify.isValidAttribute = function(tag, attr, value) {
|
|
11701
|
+
if (!CONFIG) {
|
|
11702
|
+
_parseConfig({});
|
|
12128
11703
|
}
|
|
12129
|
-
|
|
12130
|
-
|
|
12131
|
-
|
|
12132
|
-
|
|
12133
|
-
|
|
11704
|
+
const lcTag = transformCaseFunc(tag);
|
|
11705
|
+
const lcName = transformCaseFunc(attr);
|
|
11706
|
+
return _isValidAttribute(lcTag, lcName, value);
|
|
11707
|
+
};
|
|
11708
|
+
DOMPurify.addHook = function(entryPoint, hookFunction) {
|
|
11709
|
+
if (typeof hookFunction !== "function") {
|
|
11710
|
+
return;
|
|
12134
11711
|
}
|
|
12135
|
-
|
|
12136
|
-
|
|
11712
|
+
arrayPush(hooks[entryPoint], hookFunction);
|
|
11713
|
+
};
|
|
11714
|
+
DOMPurify.removeHook = function(entryPoint, hookFunction) {
|
|
11715
|
+
if (hookFunction !== void 0) {
|
|
11716
|
+
const index = arrayLastIndexOf(hooks[entryPoint], hookFunction);
|
|
11717
|
+
return index === -1 ? void 0 : arraySplice(hooks[entryPoint], index, 1)[0];
|
|
12137
11718
|
}
|
|
12138
|
-
|
|
12139
|
-
|
|
11719
|
+
return arrayPop(hooks[entryPoint]);
|
|
11720
|
+
};
|
|
11721
|
+
DOMPurify.removeHooks = function(entryPoint) {
|
|
11722
|
+
hooks[entryPoint] = [];
|
|
11723
|
+
};
|
|
11724
|
+
DOMPurify.removeAllHooks = function() {
|
|
11725
|
+
hooks = _createHooksMap();
|
|
11726
|
+
};
|
|
11727
|
+
return DOMPurify;
|
|
11728
|
+
}
|
|
11729
|
+
var purify = createDOMPurify();
|
|
11730
|
+
purify.addHook("afterSanitizeAttributes", (node) => {
|
|
11731
|
+
if (node.tagName === "A" && node.getAttribute("target") === "_blank") {
|
|
11732
|
+
node.setAttribute("rel", "noopener noreferrer");
|
|
11733
|
+
}
|
|
11734
|
+
});
|
|
11735
|
+
function sanitizeBannerHtml(html2) {
|
|
11736
|
+
if (!html2) return "";
|
|
11737
|
+
return purify.sanitize(html2, {
|
|
11738
|
+
ALLOWED_TAGS: ["p", "strong", "em", "u", "img", "span", "div", "a", "br"],
|
|
11739
|
+
ALLOWED_ATTR: ["style", "src", "class", "href", "target", "alt", "width", "height"],
|
|
11740
|
+
ADD_ATTR: ["target"],
|
|
11741
|
+
ALLOW_DATA_ATTR: false
|
|
11742
|
+
});
|
|
11743
|
+
}
|
|
11744
|
+
function resolveCssToken(token) {
|
|
11745
|
+
const normalizedToken = token.startsWith("--") ? token : `--${token}`;
|
|
11746
|
+
const candidates = [
|
|
11747
|
+
document.documentElement,
|
|
11748
|
+
document.body,
|
|
11749
|
+
...Array.from(
|
|
11750
|
+
document.querySelectorAll(
|
|
11751
|
+
[
|
|
11752
|
+
"rai-widget",
|
|
11753
|
+
"rai-custom-widget",
|
|
11754
|
+
"rai-channel-widget",
|
|
11755
|
+
"rai-store-widget",
|
|
11756
|
+
"rai-milestone-widget",
|
|
11757
|
+
"rai-social-widget",
|
|
11758
|
+
"rai-currency-widget",
|
|
11759
|
+
"rai-referral-widget",
|
|
11760
|
+
".rai-widget-root",
|
|
11761
|
+
'[data-rai-widget-root="true"]'
|
|
11762
|
+
].join(",")
|
|
11763
|
+
)
|
|
11764
|
+
)
|
|
11765
|
+
].filter(Boolean);
|
|
11766
|
+
for (const node of candidates) {
|
|
11767
|
+
const value = getComputedStyle(node).getPropertyValue(normalizedToken).trim();
|
|
11768
|
+
if (value) return value;
|
|
11769
|
+
}
|
|
11770
|
+
for (const node of Array.from(document.querySelectorAll("*"))) {
|
|
11771
|
+
const value = getComputedStyle(node).getPropertyValue(normalizedToken).trim();
|
|
11772
|
+
if (value) return value;
|
|
11773
|
+
}
|
|
11774
|
+
return void 0;
|
|
11775
|
+
}
|
|
11776
|
+
const safeColor = (v) => {
|
|
11777
|
+
if (!v) return void 0;
|
|
11778
|
+
const value = v.trim();
|
|
11779
|
+
if (/^(#|rgb|hsl)/i.test(value)) return value;
|
|
11780
|
+
if (/^(--)?[a-z0-9-]+$/i.test(value)) {
|
|
11781
|
+
const resolved = resolveCssToken(value);
|
|
11782
|
+
return resolved;
|
|
11783
|
+
}
|
|
11784
|
+
const varMatch = value.match(/^var\((--[a-z0-9-]+)\)$/i);
|
|
11785
|
+
if (varMatch) {
|
|
11786
|
+
const token = varMatch[1];
|
|
11787
|
+
const resolved = resolveCssToken(token);
|
|
11788
|
+
return resolved;
|
|
11789
|
+
}
|
|
11790
|
+
return void 0;
|
|
11791
|
+
};
|
|
11792
|
+
function el(tag, styles, attrs) {
|
|
11793
|
+
const node = document.createElement(tag);
|
|
11794
|
+
Object.assign(node.style, styles);
|
|
11795
|
+
if (attrs) {
|
|
11796
|
+
for (const k of Object.keys(attrs)) node.setAttribute(k, attrs[k]);
|
|
11797
|
+
}
|
|
11798
|
+
return node;
|
|
11799
|
+
}
|
|
11800
|
+
function ctaAlign(pos) {
|
|
11801
|
+
if (pos === "left") return "flex-start";
|
|
11802
|
+
if (pos === "right") return "flex-end";
|
|
11803
|
+
return "center";
|
|
11804
|
+
}
|
|
11805
|
+
function isImageBanner(banner) {
|
|
11806
|
+
var _a, _b;
|
|
11807
|
+
return banner.type === "image" && Boolean(((_a = banner.image) == null ? void 0 : _a.desktopUrl) || ((_b = banner.image) == null ? void 0 : _b.mobileUrl));
|
|
11808
|
+
}
|
|
11809
|
+
function imageAlign(pos) {
|
|
11810
|
+
if (pos === "left" || pos === "top") return "flex-start";
|
|
11811
|
+
if (pos === "right" || pos === "bottom") return "flex-end";
|
|
11812
|
+
return "center";
|
|
11813
|
+
}
|
|
11814
|
+
function imageObjectPosition(horizontal, vertical) {
|
|
11815
|
+
const x = horizontal === "left" ? "left" : horizontal === "right" ? "right" : "center";
|
|
11816
|
+
const y = vertical === "top" ? "top" : vertical === "bottom" ? "bottom" : "center";
|
|
11817
|
+
return `${x} ${y}`;
|
|
11818
|
+
}
|
|
11819
|
+
function getCtaStyleValue(banner, keys) {
|
|
11820
|
+
var _a;
|
|
11821
|
+
const sources = [(_a = banner.cta) == null ? void 0 : _a.style, banner.cta, banner.ctaStyle];
|
|
11822
|
+
for (const source of sources) {
|
|
11823
|
+
for (const key of keys) {
|
|
11824
|
+
const value = source == null ? void 0 : source[key];
|
|
11825
|
+
if (value) return value;
|
|
12140
11826
|
}
|
|
12141
|
-
|
|
12142
|
-
|
|
12143
|
-
|
|
12144
|
-
|
|
12145
|
-
|
|
12146
|
-
|
|
12147
|
-
|
|
12148
|
-
|
|
12149
|
-
|
|
12150
|
-
|
|
12151
|
-
|
|
12152
|
-
|
|
12153
|
-
|
|
12154
|
-
|
|
12155
|
-
|
|
12156
|
-
|
|
12157
|
-
|
|
12158
|
-
|
|
11827
|
+
}
|
|
11828
|
+
return void 0;
|
|
11829
|
+
}
|
|
11830
|
+
function styleRichText(container) {
|
|
11831
|
+
container.querySelectorAll("p").forEach((p) => {
|
|
11832
|
+
p.style.margin = "0";
|
|
11833
|
+
p.style.whiteSpace = "normal";
|
|
11834
|
+
p.style.overflowWrap = "anywhere";
|
|
11835
|
+
});
|
|
11836
|
+
container.querySelectorAll("strong").forEach((strong) => {
|
|
11837
|
+
strong.style.fontWeight = "700";
|
|
11838
|
+
strong.style.whiteSpace = "normal";
|
|
11839
|
+
});
|
|
11840
|
+
container.querySelectorAll("em").forEach((em) => {
|
|
11841
|
+
em.style.fontStyle = "italic";
|
|
11842
|
+
em.style.whiteSpace = "normal";
|
|
11843
|
+
});
|
|
11844
|
+
container.querySelectorAll("u").forEach((u) => {
|
|
11845
|
+
u.style.textDecoration = "underline";
|
|
11846
|
+
u.style.whiteSpace = "normal";
|
|
11847
|
+
});
|
|
11848
|
+
container.querySelectorAll("a").forEach((a) => {
|
|
11849
|
+
a.style.color = "#3b82f6";
|
|
11850
|
+
a.style.textDecoration = "underline";
|
|
11851
|
+
a.style.whiteSpace = "normal";
|
|
11852
|
+
a.style.overflowWrap = "anywhere";
|
|
11853
|
+
if (a.getAttribute("target") === "_blank") {
|
|
11854
|
+
a.setAttribute("rel", "noopener noreferrer");
|
|
11855
|
+
}
|
|
11856
|
+
});
|
|
11857
|
+
container.querySelectorAll("img").forEach((img) => {
|
|
11858
|
+
img.style.maxWidth = "100%";
|
|
11859
|
+
img.style.height = "auto";
|
|
11860
|
+
});
|
|
11861
|
+
}
|
|
11862
|
+
function readTextAlign(container) {
|
|
11863
|
+
const aligned = container.querySelector(
|
|
11864
|
+
'[style*="text-align"]'
|
|
11865
|
+
);
|
|
11866
|
+
const value = ((aligned == null ? void 0 : aligned.style.textAlign) || container.style.textAlign || "").toLowerCase().trim();
|
|
11867
|
+
if (value === "center" || value === "right" || value === "justify") return value;
|
|
11868
|
+
return "left";
|
|
11869
|
+
}
|
|
11870
|
+
function justifyFromTextAlign(align) {
|
|
11871
|
+
if (align === "center") return "center";
|
|
11872
|
+
if (align === "right") return "flex-end";
|
|
11873
|
+
return "flex-start";
|
|
11874
|
+
}
|
|
11875
|
+
function renderBanner(banner, handlers) {
|
|
11876
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n;
|
|
11877
|
+
const placement = banner.placement || {};
|
|
11878
|
+
const mode = placement.mode || "overlay";
|
|
11879
|
+
const position = placement.position || "top";
|
|
11880
|
+
const zIndex = String(placement.zIndex || 2147483e3);
|
|
11881
|
+
const imageBanner = isImageBanner(banner);
|
|
11882
|
+
const bg = imageBanner ? "transparent" : safeColor((_a = banner.style) == null ? void 0 : _a.backgroundColor) || "#1f2024";
|
|
11883
|
+
const color = safeColor((_b = banner.style) == null ? void 0 : _b.color) || "#ffffff";
|
|
11884
|
+
const isCard = mode === "overlay" || mode === "popup";
|
|
11885
|
+
const ctaPosition = getCtaStyleValue(banner, ["position"]) || "center";
|
|
11886
|
+
const imageHorizontal = imageAlign((_c = banner.image) == null ? void 0 : _c.horizontalAlignment);
|
|
11887
|
+
const imageVertical = imageAlign((_d = banner.image) == null ? void 0 : _d.verticalAlignment);
|
|
11888
|
+
const imageHorizontalPosition = ((_e = banner.image) == null ? void 0 : _e.horizontalAlignment) || "center";
|
|
11889
|
+
const imageVerticalPosition = ((_f = banner.image) == null ? void 0 : _f.verticalAlignment) || "center";
|
|
11890
|
+
const closeColor = imageBanner ? "#ffffff" : color;
|
|
11891
|
+
const root = el("div", {
|
|
11892
|
+
boxSizing: "border-box",
|
|
11893
|
+
fontFamily: "Roboto, sans-serif",
|
|
11894
|
+
fontSize: "14px",
|
|
11895
|
+
lineHeight: "1.35",
|
|
11896
|
+
background: bg,
|
|
11897
|
+
color,
|
|
11898
|
+
borderRadius: isCard && !imageBanner ? "6px" : "0",
|
|
11899
|
+
boxShadow: isCard && !imageBanner ? "0 8px 24px rgba(0,0,0,0.22)" : "none",
|
|
11900
|
+
padding: imageBanner ? "0" : isCard ? "12px 42px 12px 24px" : "8px 42px 8px 16px",
|
|
11901
|
+
display: "flex",
|
|
11902
|
+
alignItems: imageBanner ? imageVertical : "flex-start",
|
|
11903
|
+
justifyContent: "center",
|
|
11904
|
+
gap: imageBanner ? "0" : "16px"
|
|
11905
|
+
});
|
|
11906
|
+
root.setAttribute("role", isCard ? "dialog" : "region");
|
|
11907
|
+
root.setAttribute("aria-label", "community banner");
|
|
11908
|
+
root.setAttribute("data-renderer-version", "sdk-banner-preview-layout");
|
|
11909
|
+
if (isCard) {
|
|
11910
|
+
Object.assign(root.style, {
|
|
11911
|
+
position: "fixed",
|
|
11912
|
+
left: "50%",
|
|
11913
|
+
width: "fit-content",
|
|
11914
|
+
maxWidth: imageBanner ? "70vw" : "min(700px, 80vw)",
|
|
11915
|
+
height: "auto",
|
|
11916
|
+
minHeight: imageBanner ? "0" : "80px",
|
|
11917
|
+
maxHeight: imageBanner ? "70vh" : "calc(100vh - 300px)",
|
|
11918
|
+
overflowY: imageBanner ? "visible" : "auto",
|
|
11919
|
+
zIndex
|
|
11920
|
+
});
|
|
11921
|
+
if (imageBanner) {
|
|
11922
|
+
const translate = [];
|
|
11923
|
+
if (imageHorizontalPosition === "left") {
|
|
11924
|
+
root.style.left = "24px";
|
|
11925
|
+
} else if (imageHorizontalPosition === "right") {
|
|
11926
|
+
root.style.left = "";
|
|
11927
|
+
root.style.right = "24px";
|
|
11928
|
+
} else {
|
|
11929
|
+
root.style.left = "50%";
|
|
11930
|
+
translate.push("-50%");
|
|
12159
11931
|
}
|
|
12160
|
-
|
|
12161
|
-
|
|
12162
|
-
|
|
12163
|
-
|
|
12164
|
-
body = importedNode;
|
|
12165
|
-
} else if (importedNode.nodeName === "HTML") {
|
|
12166
|
-
body = importedNode;
|
|
11932
|
+
if (imageVerticalPosition === "top") {
|
|
11933
|
+
root.style.top = "10px";
|
|
11934
|
+
} else if (imageVerticalPosition === "bottom") {
|
|
11935
|
+
root.style.bottom = "24px";
|
|
12167
11936
|
} else {
|
|
12168
|
-
|
|
11937
|
+
root.style.top = "50%";
|
|
11938
|
+
translate.push("-50%");
|
|
12169
11939
|
}
|
|
12170
|
-
|
|
11940
|
+
if (translate.length === 2) root.style.transform = `translate(${translate[0]}, ${translate[1]})`;
|
|
11941
|
+
else if (translate.length === 1 && imageHorizontalPosition === "center") root.style.transform = `translateX(${translate[0]})`;
|
|
11942
|
+
else if (translate.length === 1) root.style.transform = `translateY(${translate[0]})`;
|
|
11943
|
+
else root.style.transform = "";
|
|
11944
|
+
} else if (position === "bottom") {
|
|
11945
|
+
root.style.bottom = "24px";
|
|
11946
|
+
root.style.transform = "translateX(-50%)";
|
|
11947
|
+
} else if (position === "center") {
|
|
11948
|
+
root.style.top = "50%";
|
|
11949
|
+
root.style.transform = "translate(-50%, -50%)";
|
|
12171
11950
|
} else {
|
|
12172
|
-
|
|
12173
|
-
|
|
12174
|
-
return trustedTypesPolicy && RETURN_TRUSTED_TYPE ? _createTrustedHTML(dirty) : dirty;
|
|
12175
|
-
}
|
|
12176
|
-
body = _initDocument(dirty);
|
|
12177
|
-
if (!body) {
|
|
12178
|
-
return RETURN_DOM ? null : RETURN_TRUSTED_TYPE ? emptyHTML : "";
|
|
12179
|
-
}
|
|
12180
|
-
}
|
|
12181
|
-
if (body && FORCE_BODY) {
|
|
12182
|
-
_forceRemove(body.firstChild);
|
|
12183
|
-
}
|
|
12184
|
-
const nodeIterator = _createNodeIterator(inPlace ? dirty : body);
|
|
12185
|
-
try {
|
|
12186
|
-
while (currentNode = nodeIterator.nextNode()) {
|
|
12187
|
-
_sanitizeElements(currentNode);
|
|
12188
|
-
_sanitizeAttributes(currentNode);
|
|
12189
|
-
if (_isDocumentFragment(currentNode.content)) {
|
|
12190
|
-
_sanitizeShadowDOM2(currentNode.content);
|
|
12191
|
-
}
|
|
12192
|
-
}
|
|
12193
|
-
} catch (error) {
|
|
12194
|
-
if (inPlace) {
|
|
12195
|
-
_neutralizeRoot(dirty);
|
|
12196
|
-
}
|
|
12197
|
-
throw error;
|
|
11951
|
+
root.style.top = "10px";
|
|
11952
|
+
root.style.transform = "translateX(-50%)";
|
|
12198
11953
|
}
|
|
12199
|
-
|
|
12200
|
-
|
|
12201
|
-
|
|
12202
|
-
|
|
11954
|
+
} else {
|
|
11955
|
+
Object.assign(root.style, { position: "relative", width: "100%", zIndex });
|
|
11956
|
+
}
|
|
11957
|
+
const contentWrap = el("div", {
|
|
11958
|
+
display: "flex",
|
|
11959
|
+
width: imageBanner || isCard ? "auto" : "100%",
|
|
11960
|
+
maxWidth: "100%",
|
|
11961
|
+
flexDirection: "column",
|
|
11962
|
+
gap: imageBanner ? "0" : "12px",
|
|
11963
|
+
overflow: "hidden"
|
|
11964
|
+
});
|
|
11965
|
+
const contentRow = el("div", {
|
|
11966
|
+
display: "flex",
|
|
11967
|
+
width: imageBanner || isCard ? "auto" : "100%",
|
|
11968
|
+
justifyContent: imageBanner ? imageHorizontal : "space-between",
|
|
11969
|
+
alignItems: imageBanner ? imageVertical : "flex-start",
|
|
11970
|
+
gap: "12px"
|
|
11971
|
+
});
|
|
11972
|
+
const content = el("div", {
|
|
11973
|
+
width: imageBanner || isCard ? "auto" : "100%",
|
|
11974
|
+
maxWidth: imageBanner ? "70vw" : isCard ? "calc(min(700px, 80vw) - 66px)" : "100%",
|
|
11975
|
+
overflow: "hidden",
|
|
11976
|
+
wordBreak: "normal",
|
|
11977
|
+
overflowWrap: "anywhere",
|
|
11978
|
+
whiteSpace: "normal",
|
|
11979
|
+
color
|
|
11980
|
+
});
|
|
11981
|
+
const imageUrl = ((_g = banner.image) == null ? void 0 : _g.desktopUrl) || ((_h = banner.image) == null ? void 0 : _h.mobileUrl);
|
|
11982
|
+
if (imageBanner && imageUrl) {
|
|
11983
|
+
const imageLinkUrl = (_i = banner.image) == null ? void 0 : _i.linkUrl;
|
|
11984
|
+
const imageOpenInNewTab = (_j = banner.image) == null ? void 0 : _j.openInNewTab;
|
|
11985
|
+
const img = el(
|
|
11986
|
+
"img",
|
|
11987
|
+
{
|
|
11988
|
+
display: "block",
|
|
11989
|
+
maxWidth: "70vw",
|
|
11990
|
+
maxHeight: "70vh",
|
|
11991
|
+
width: "auto",
|
|
11992
|
+
height: "auto",
|
|
11993
|
+
objectFit: "contain",
|
|
11994
|
+
objectPosition: imageObjectPosition(
|
|
11995
|
+
(_k = banner.image) == null ? void 0 : _k.horizontalAlignment,
|
|
11996
|
+
(_l = banner.image) == null ? void 0 : _l.verticalAlignment
|
|
11997
|
+
),
|
|
11998
|
+
cursor: imageLinkUrl ? "pointer" : "",
|
|
11999
|
+
borderRadius: ((_m = banner.image) == null ? void 0 : _m.cornerRadius) === "rounded" ? "8px" : "0"
|
|
12000
|
+
},
|
|
12001
|
+
{ src: imageUrl, alt: banner.title || "banner" }
|
|
12002
|
+
);
|
|
12003
|
+
if (imageLinkUrl) {
|
|
12004
|
+
img.addEventListener("click", () => {
|
|
12005
|
+
if (imageOpenInNewTab) {
|
|
12006
|
+
window.open(imageLinkUrl, "_blank", "noopener,noreferrer");
|
|
12007
|
+
} else {
|
|
12008
|
+
window.location.href = imageLinkUrl;
|
|
12203
12009
|
}
|
|
12204
12010
|
});
|
|
12205
|
-
if (SAFE_FOR_TEMPLATES) {
|
|
12206
|
-
_scrubTemplateExpressions2(dirty);
|
|
12207
|
-
}
|
|
12208
|
-
return dirty;
|
|
12209
|
-
}
|
|
12210
|
-
if (RETURN_DOM) {
|
|
12211
|
-
if (SAFE_FOR_TEMPLATES) {
|
|
12212
|
-
_scrubTemplateExpressions2(body);
|
|
12213
|
-
}
|
|
12214
|
-
if (RETURN_DOM_FRAGMENT) {
|
|
12215
|
-
returnNode = createDocumentFragment.call(body.ownerDocument);
|
|
12216
|
-
while (body.firstChild) {
|
|
12217
|
-
returnNode.appendChild(body.firstChild);
|
|
12218
|
-
}
|
|
12219
|
-
} else {
|
|
12220
|
-
returnNode = body;
|
|
12221
|
-
}
|
|
12222
|
-
if (ALLOWED_ATTR.shadowroot || ALLOWED_ATTR.shadowrootmode) {
|
|
12223
|
-
returnNode = importNode.call(originalDocument, returnNode, true);
|
|
12224
|
-
}
|
|
12225
|
-
return returnNode;
|
|
12226
12011
|
}
|
|
12227
|
-
|
|
12228
|
-
|
|
12229
|
-
|
|
12012
|
+
content.appendChild(img);
|
|
12013
|
+
} else {
|
|
12014
|
+
content.innerHTML = sanitizeBannerHtml(banner.text);
|
|
12015
|
+
styleRichText(content);
|
|
12016
|
+
const textAlign = readTextAlign(content);
|
|
12017
|
+
content.style.textAlign = textAlign;
|
|
12018
|
+
if (isCard) {
|
|
12019
|
+
contentRow.style.justifyContent = justifyFromTextAlign(textAlign);
|
|
12230
12020
|
}
|
|
12231
|
-
|
|
12232
|
-
|
|
12233
|
-
|
|
12021
|
+
}
|
|
12022
|
+
if (!imageBanner && ((_n = banner.cta) == null ? void 0 : _n.enabled)) {
|
|
12023
|
+
const ctaBg = safeColor(
|
|
12024
|
+
getCtaStyleValue(banner, ["backgroundColor", "buttonColor", "aColor"])
|
|
12025
|
+
) || "#2f6df6";
|
|
12026
|
+
const ctaColor = safeColor(getCtaStyleValue(banner, ["textColor", "color"])) || "#ffffff";
|
|
12027
|
+
const btn = el("button", {
|
|
12028
|
+
cursor: "pointer",
|
|
12029
|
+
border: "none",
|
|
12030
|
+
borderRadius: "6px",
|
|
12031
|
+
height: "36px",
|
|
12032
|
+
minHeight: "36px",
|
|
12033
|
+
padding: "0 16px",
|
|
12034
|
+
fontFamily: "Roboto, sans-serif",
|
|
12035
|
+
fontSize: "12px",
|
|
12036
|
+
fontWeight: "600",
|
|
12037
|
+
lineHeight: "20px",
|
|
12038
|
+
backgroundColor: ctaBg,
|
|
12039
|
+
color: ctaColor,
|
|
12040
|
+
boxSizing: "border-box",
|
|
12041
|
+
display: "inline-flex",
|
|
12042
|
+
alignItems: "center",
|
|
12043
|
+
justifyContent: "center"
|
|
12044
|
+
});
|
|
12045
|
+
btn.type = "button";
|
|
12046
|
+
btn.textContent = banner.cta.label || "CTA Button";
|
|
12047
|
+
btn.addEventListener("click", handlers.onCtaClick);
|
|
12048
|
+
if (ctaPosition === "inline") {
|
|
12049
|
+
contentRow.appendChild(content);
|
|
12050
|
+
const inlineWrap = el("div", {
|
|
12051
|
+
display: "flex",
|
|
12052
|
+
flexDirection: "column",
|
|
12053
|
+
alignItems: "flex-end",
|
|
12054
|
+
justifyContent: "center",
|
|
12055
|
+
flexShrink: "0"
|
|
12234
12056
|
});
|
|
12057
|
+
inlineWrap.appendChild(btn);
|
|
12058
|
+
contentRow.appendChild(inlineWrap);
|
|
12059
|
+
contentWrap.appendChild(contentRow);
|
|
12060
|
+
} else {
|
|
12061
|
+
contentRow.appendChild(content);
|
|
12062
|
+
contentWrap.appendChild(contentRow);
|
|
12063
|
+
const wrap = el("div", {
|
|
12064
|
+
display: "flex",
|
|
12065
|
+
width: "100%",
|
|
12066
|
+
justifyContent: ctaAlign(ctaPosition)
|
|
12067
|
+
});
|
|
12068
|
+
wrap.appendChild(btn);
|
|
12069
|
+
contentWrap.appendChild(wrap);
|
|
12235
12070
|
}
|
|
12236
|
-
|
|
12237
|
-
|
|
12238
|
-
|
|
12239
|
-
|
|
12240
|
-
|
|
12241
|
-
|
|
12242
|
-
|
|
12243
|
-
|
|
12244
|
-
|
|
12245
|
-
|
|
12246
|
-
|
|
12247
|
-
|
|
12248
|
-
|
|
12249
|
-
|
|
12250
|
-
|
|
12251
|
-
|
|
12252
|
-
|
|
12253
|
-
|
|
12254
|
-
|
|
12255
|
-
|
|
12256
|
-
|
|
12257
|
-
|
|
12258
|
-
|
|
12259
|
-
|
|
12260
|
-
|
|
12261
|
-
|
|
12262
|
-
|
|
12263
|
-
|
|
12264
|
-
|
|
12265
|
-
|
|
12266
|
-
|
|
12267
|
-
|
|
12268
|
-
return arrayPop(hooks[entryPoint]);
|
|
12269
|
-
};
|
|
12270
|
-
DOMPurify.removeHooks = function(entryPoint) {
|
|
12271
|
-
hooks[entryPoint] = [];
|
|
12272
|
-
};
|
|
12273
|
-
DOMPurify.removeAllHooks = function() {
|
|
12274
|
-
hooks = _createHooksMap();
|
|
12275
|
-
};
|
|
12276
|
-
return DOMPurify;
|
|
12071
|
+
} else {
|
|
12072
|
+
contentRow.appendChild(content);
|
|
12073
|
+
contentWrap.appendChild(contentRow);
|
|
12074
|
+
}
|
|
12075
|
+
root.appendChild(contentWrap);
|
|
12076
|
+
const close = el("button", {
|
|
12077
|
+
position: isCard ? "absolute" : "",
|
|
12078
|
+
top: isCard ? imageBanner ? "16px" : "12px" : "",
|
|
12079
|
+
right: isCard ? imageBanner ? "16px" : "12px" : "",
|
|
12080
|
+
marginTop: isCard ? "0" : "8px",
|
|
12081
|
+
width: "20px",
|
|
12082
|
+
minWidth: "20px",
|
|
12083
|
+
height: "20px",
|
|
12084
|
+
cursor: "pointer",
|
|
12085
|
+
border: "none",
|
|
12086
|
+
borderRadius: "50%",
|
|
12087
|
+
background: "rgba(0,0,0,0.25)",
|
|
12088
|
+
color: closeColor,
|
|
12089
|
+
fontSize: "16px",
|
|
12090
|
+
lineHeight: "1",
|
|
12091
|
+
display: "flex",
|
|
12092
|
+
alignItems: "center",
|
|
12093
|
+
justifyContent: "center",
|
|
12094
|
+
padding: "0",
|
|
12095
|
+
flexShrink: "0"
|
|
12096
|
+
});
|
|
12097
|
+
close.type = "button";
|
|
12098
|
+
close.setAttribute("aria-label", "dismiss banner");
|
|
12099
|
+
close.innerHTML = "×";
|
|
12100
|
+
close.addEventListener("click", handlers.onDismiss);
|
|
12101
|
+
root.appendChild(close);
|
|
12102
|
+
return root;
|
|
12277
12103
|
}
|
|
12278
|
-
|
|
12279
|
-
|
|
12280
|
-
|
|
12281
|
-
|
|
12104
|
+
const VISITOR_KEY = "rai-banner-visitor";
|
|
12105
|
+
function uuid() {
|
|
12106
|
+
try {
|
|
12107
|
+
if (typeof crypto !== "undefined" && typeof crypto.randomUUID === "function") {
|
|
12108
|
+
return crypto.randomUUID();
|
|
12109
|
+
}
|
|
12110
|
+
} catch {
|
|
12282
12111
|
}
|
|
12283
|
-
|
|
12284
|
-
|
|
12285
|
-
|
|
12286
|
-
|
|
12287
|
-
ALLOWED_TAGS: ["p", "strong", "em", "u", "img", "span", "div", "a", "br"],
|
|
12288
|
-
ALLOWED_ATTR: ["style", "src", "class", "href", "target", "alt", "width", "height"],
|
|
12289
|
-
ADD_ATTR: ["target"],
|
|
12290
|
-
ALLOW_DATA_ATTR: false
|
|
12112
|
+
return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, (c) => {
|
|
12113
|
+
const r = Math.random() * 16 | 0;
|
|
12114
|
+
const v = c === "x" ? r : r & 3 | 8;
|
|
12115
|
+
return v.toString(16);
|
|
12291
12116
|
});
|
|
12292
12117
|
}
|
|
12293
|
-
function
|
|
12294
|
-
const
|
|
12295
|
-
|
|
12296
|
-
|
|
12297
|
-
|
|
12298
|
-
|
|
12299
|
-
|
|
12300
|
-
|
|
12301
|
-
|
|
12302
|
-
|
|
12303
|
-
|
|
12304
|
-
"rai-store-widget",
|
|
12305
|
-
"rai-milestone-widget",
|
|
12306
|
-
"rai-social-widget",
|
|
12307
|
-
"rai-currency-widget",
|
|
12308
|
-
"rai-referral-widget",
|
|
12309
|
-
".rai-widget-root",
|
|
12310
|
-
'[data-rai-widget-root="true"]'
|
|
12311
|
-
].join(",")
|
|
12312
|
-
)
|
|
12313
|
-
)
|
|
12314
|
-
].filter(Boolean);
|
|
12315
|
-
for (const node of candidates) {
|
|
12316
|
-
const value = getComputedStyle(node).getPropertyValue(normalizedToken).trim();
|
|
12317
|
-
if (value) return value;
|
|
12118
|
+
function getOrCreateVisitorId(communityId, storagePrefix) {
|
|
12119
|
+
const key = `${storagePrefix}-${VISITOR_KEY}-${communityId}`;
|
|
12120
|
+
try {
|
|
12121
|
+
let id = localStorage.getItem(key);
|
|
12122
|
+
if (!id) {
|
|
12123
|
+
id = uuid();
|
|
12124
|
+
localStorage.setItem(key, id);
|
|
12125
|
+
}
|
|
12126
|
+
return id;
|
|
12127
|
+
} catch {
|
|
12128
|
+
return uuid();
|
|
12318
12129
|
}
|
|
12319
|
-
|
|
12320
|
-
|
|
12321
|
-
|
|
12130
|
+
}
|
|
12131
|
+
function fireTracking(url) {
|
|
12132
|
+
if (!url) return;
|
|
12133
|
+
try {
|
|
12134
|
+
const img = new Image();
|
|
12135
|
+
img.src = url;
|
|
12136
|
+
} catch {
|
|
12322
12137
|
}
|
|
12323
|
-
return void 0;
|
|
12324
12138
|
}
|
|
12325
|
-
|
|
12326
|
-
|
|
12327
|
-
|
|
12328
|
-
|
|
12329
|
-
|
|
12330
|
-
|
|
12331
|
-
|
|
12139
|
+
function storageKey(config) {
|
|
12140
|
+
return `${config.storagePrefix}-${config.widgetId}-${config.container}-auth`;
|
|
12141
|
+
}
|
|
12142
|
+
function legacyStorageKey(config) {
|
|
12143
|
+
return `${config.storagePrefix}-${config.widgetId}-auth`;
|
|
12144
|
+
}
|
|
12145
|
+
function errorSettingsKey(config) {
|
|
12146
|
+
return `${config.storagePrefix}-${config.widgetId}-error-settings`;
|
|
12147
|
+
}
|
|
12148
|
+
function saveToStorage(config, state) {
|
|
12149
|
+
try {
|
|
12150
|
+
const data = {
|
|
12151
|
+
refreshToken: state.refreshToken,
|
|
12152
|
+
tokenFamily: state.tokenFamily,
|
|
12153
|
+
refreshTokenExpiry: state.refreshTokenExpiry
|
|
12154
|
+
};
|
|
12155
|
+
localStorage.setItem(storageKey(config), JSON.stringify(data));
|
|
12156
|
+
} catch {
|
|
12332
12157
|
}
|
|
12333
|
-
|
|
12334
|
-
|
|
12335
|
-
|
|
12336
|
-
|
|
12337
|
-
|
|
12158
|
+
}
|
|
12159
|
+
function loadFromStorage(config, state) {
|
|
12160
|
+
try {
|
|
12161
|
+
let raw = localStorage.getItem(storageKey(config));
|
|
12162
|
+
const loadedLegacyKey = !raw;
|
|
12163
|
+
if (!raw) {
|
|
12164
|
+
raw = localStorage.getItem(legacyStorageKey(config));
|
|
12165
|
+
}
|
|
12166
|
+
if (!raw) return false;
|
|
12167
|
+
const parsed = JSON.parse(raw);
|
|
12168
|
+
if (parsed.refreshToken && !isTokenExpired(parsed.refreshTokenExpiry)) {
|
|
12169
|
+
state.refreshToken = parsed.refreshToken;
|
|
12170
|
+
state.tokenFamily = parsed.tokenFamily;
|
|
12171
|
+
state.refreshTokenExpiry = parsed.refreshTokenExpiry;
|
|
12172
|
+
if (loadedLegacyKey) {
|
|
12173
|
+
saveToStorage(config, state);
|
|
12174
|
+
localStorage.removeItem(legacyStorageKey(config));
|
|
12175
|
+
}
|
|
12176
|
+
return true;
|
|
12177
|
+
}
|
|
12178
|
+
clearStorage(config);
|
|
12179
|
+
return false;
|
|
12180
|
+
} catch {
|
|
12181
|
+
return false;
|
|
12338
12182
|
}
|
|
12339
|
-
|
|
12340
|
-
|
|
12341
|
-
|
|
12342
|
-
|
|
12343
|
-
|
|
12344
|
-
|
|
12345
|
-
for (const k of Object.keys(attrs)) node.setAttribute(k, attrs[k]);
|
|
12183
|
+
}
|
|
12184
|
+
function clearStorage(config) {
|
|
12185
|
+
try {
|
|
12186
|
+
localStorage.removeItem(storageKey(config));
|
|
12187
|
+
localStorage.removeItem(legacyStorageKey(config));
|
|
12188
|
+
} catch {
|
|
12346
12189
|
}
|
|
12347
|
-
return node;
|
|
12348
12190
|
}
|
|
12349
|
-
|
|
12350
|
-
|
|
12351
|
-
|
|
12352
|
-
|
|
12191
|
+
const ERROR_SETTINGS_CACHE_TTL = 36e5;
|
|
12192
|
+
function loadErrorSettingsFromStorage(config) {
|
|
12193
|
+
try {
|
|
12194
|
+
const raw = localStorage.getItem(errorSettingsKey(config));
|
|
12195
|
+
if (!raw) return null;
|
|
12196
|
+
const parsed = JSON.parse(raw);
|
|
12197
|
+
if (parsed.cachedAt && Date.now() - parsed.cachedAt < ERROR_SETTINGS_CACHE_TTL) {
|
|
12198
|
+
return parsed;
|
|
12199
|
+
}
|
|
12200
|
+
localStorage.removeItem(errorSettingsKey(config));
|
|
12201
|
+
return null;
|
|
12202
|
+
} catch {
|
|
12203
|
+
return null;
|
|
12204
|
+
}
|
|
12353
12205
|
}
|
|
12354
|
-
function
|
|
12355
|
-
|
|
12356
|
-
|
|
12206
|
+
function saveErrorSettingsToStorage(config, settings) {
|
|
12207
|
+
try {
|
|
12208
|
+
localStorage.setItem(errorSettingsKey(config), JSON.stringify({ ...settings, cachedAt: Date.now() }));
|
|
12209
|
+
} catch {
|
|
12210
|
+
}
|
|
12357
12211
|
}
|
|
12358
|
-
function
|
|
12359
|
-
if (
|
|
12360
|
-
|
|
12361
|
-
return "center";
|
|
12212
|
+
function isTokenExpired(expiry) {
|
|
12213
|
+
if (!expiry) return true;
|
|
12214
|
+
return Date.now() >= expiry - 6e4;
|
|
12362
12215
|
}
|
|
12363
|
-
function
|
|
12364
|
-
|
|
12365
|
-
|
|
12366
|
-
|
|
12216
|
+
function setTokens(config, state, data, onRefreshScheduled) {
|
|
12217
|
+
state.accessToken = data.accessToken;
|
|
12218
|
+
state.refreshToken = data.refreshToken;
|
|
12219
|
+
state.tokenFamily = data.tokenFamily ?? null;
|
|
12220
|
+
const now = Date.now();
|
|
12221
|
+
state.accessTokenExpiry = now + data.accessTokenTTL * 1e3;
|
|
12222
|
+
state.refreshTokenExpiry = now + data.refreshTokenTTL * 1e3;
|
|
12223
|
+
saveToStorage(config, state);
|
|
12224
|
+
if (config.autoRefresh && onRefreshScheduled) {
|
|
12225
|
+
onRefreshScheduled();
|
|
12226
|
+
}
|
|
12367
12227
|
}
|
|
12368
|
-
function
|
|
12369
|
-
|
|
12370
|
-
|
|
12371
|
-
|
|
12372
|
-
|
|
12373
|
-
|
|
12374
|
-
|
|
12228
|
+
function buildIdentityProof(config) {
|
|
12229
|
+
const proof = {};
|
|
12230
|
+
if (config.embedToken) {
|
|
12231
|
+
proof.embedToken = config.embedToken;
|
|
12232
|
+
}
|
|
12233
|
+
if (config.userIdentifiers && Object.keys(config.userIdentifiers).length > 0) {
|
|
12234
|
+
proof.userIdentifiers = config.userIdentifiers;
|
|
12235
|
+
}
|
|
12236
|
+
return proof;
|
|
12237
|
+
}
|
|
12238
|
+
async function authenticateServerless(config, state, onRefreshScheduled) {
|
|
12239
|
+
const nonce = crypto.randomUUID();
|
|
12240
|
+
const timestamp = Date.now();
|
|
12241
|
+
const maxRetries = config.maxRetries ?? 3;
|
|
12242
|
+
const retryDelay = config.retryDelay ?? 500;
|
|
12243
|
+
for (let attempt = 0; attempt <= maxRetries; attempt++) {
|
|
12244
|
+
if (attempt > 0) {
|
|
12245
|
+
await new Promise(
|
|
12246
|
+
(resolve) => setTimeout(resolve, retryDelay * (1 << attempt - 1))
|
|
12247
|
+
);
|
|
12248
|
+
}
|
|
12249
|
+
let is4xx = false;
|
|
12250
|
+
try {
|
|
12251
|
+
const body = {
|
|
12252
|
+
nonce,
|
|
12253
|
+
timestamp,
|
|
12254
|
+
widgetType: config.widgetType,
|
|
12255
|
+
...buildIdentityProof(config)
|
|
12256
|
+
};
|
|
12257
|
+
const response = await fetch(`${config.apiUrl}/${config.widgetId}/auth/serverless`, {
|
|
12258
|
+
method: "POST",
|
|
12259
|
+
headers: { "Content-Type": "application/json" },
|
|
12260
|
+
body: JSON.stringify(body),
|
|
12261
|
+
credentials: "include"
|
|
12262
|
+
});
|
|
12263
|
+
if (!response.ok) {
|
|
12264
|
+
is4xx = response.status >= 400 && response.status < 500;
|
|
12265
|
+
const errorBody = await response.json().catch(() => ({ error: "Authentication failed" }));
|
|
12266
|
+
if (is4xx) {
|
|
12267
|
+
state.lastAuthError = {
|
|
12268
|
+
status: response.status,
|
|
12269
|
+
error: errorBody == null ? void 0 : errorBody.error,
|
|
12270
|
+
hint: errorBody == null ? void 0 : errorBody.hint
|
|
12271
|
+
};
|
|
12272
|
+
console.error(
|
|
12273
|
+
`[rai-widget] /auth/serverless ${response.status}:`,
|
|
12274
|
+
(errorBody == null ? void 0 : errorBody.error) || "Authentication failed",
|
|
12275
|
+
(errorBody == null ? void 0 : errorBody.hint) ? `— ${errorBody.hint}` : ""
|
|
12276
|
+
);
|
|
12277
|
+
}
|
|
12278
|
+
throw new Error((errorBody == null ? void 0 : errorBody.error) || `HTTP ${response.status}`);
|
|
12279
|
+
}
|
|
12280
|
+
state.lastAuthError = null;
|
|
12281
|
+
const data = await response.json();
|
|
12282
|
+
if (!data.accessToken || !data.refreshToken) {
|
|
12283
|
+
throw new Error("Invalid authentication response");
|
|
12284
|
+
}
|
|
12285
|
+
setTokens(config, state, data, onRefreshScheduled);
|
|
12286
|
+
state.isAuthenticated = true;
|
|
12287
|
+
return true;
|
|
12288
|
+
} catch {
|
|
12289
|
+
if (is4xx || attempt === maxRetries) {
|
|
12290
|
+
state.isAuthenticated = false;
|
|
12291
|
+
return false;
|
|
12292
|
+
}
|
|
12375
12293
|
}
|
|
12376
12294
|
}
|
|
12377
|
-
|
|
12295
|
+
state.isAuthenticated = false;
|
|
12296
|
+
return false;
|
|
12378
12297
|
}
|
|
12379
|
-
function
|
|
12380
|
-
|
|
12381
|
-
|
|
12382
|
-
|
|
12383
|
-
|
|
12384
|
-
|
|
12385
|
-
|
|
12386
|
-
|
|
12387
|
-
strong.style.whiteSpace = "normal";
|
|
12388
|
-
});
|
|
12389
|
-
container.querySelectorAll("em").forEach((em) => {
|
|
12390
|
-
em.style.fontStyle = "italic";
|
|
12391
|
-
em.style.whiteSpace = "normal";
|
|
12392
|
-
});
|
|
12393
|
-
container.querySelectorAll("u").forEach((u) => {
|
|
12394
|
-
u.style.textDecoration = "underline";
|
|
12395
|
-
u.style.whiteSpace = "normal";
|
|
12396
|
-
});
|
|
12397
|
-
container.querySelectorAll("a").forEach((a) => {
|
|
12398
|
-
a.style.color = "#3b82f6";
|
|
12399
|
-
a.style.textDecoration = "underline";
|
|
12400
|
-
a.style.whiteSpace = "normal";
|
|
12401
|
-
a.style.overflowWrap = "anywhere";
|
|
12402
|
-
if (a.getAttribute("target") === "_blank") {
|
|
12403
|
-
a.setAttribute("rel", "noopener noreferrer");
|
|
12298
|
+
async function authenticateViaProxy(config, state, onRefreshScheduled) {
|
|
12299
|
+
const maxRetries = config.maxRetries ?? 3;
|
|
12300
|
+
const retryDelay = config.retryDelay ?? 500;
|
|
12301
|
+
for (let attempt = 0; attempt <= maxRetries; attempt++) {
|
|
12302
|
+
if (attempt > 0) {
|
|
12303
|
+
await new Promise(
|
|
12304
|
+
(resolve) => setTimeout(resolve, retryDelay * (1 << attempt - 1))
|
|
12305
|
+
);
|
|
12404
12306
|
}
|
|
12405
|
-
|
|
12406
|
-
|
|
12407
|
-
|
|
12408
|
-
|
|
12409
|
-
|
|
12410
|
-
}
|
|
12411
|
-
|
|
12412
|
-
|
|
12413
|
-
|
|
12414
|
-
|
|
12415
|
-
|
|
12416
|
-
|
|
12417
|
-
|
|
12418
|
-
|
|
12419
|
-
|
|
12420
|
-
|
|
12421
|
-
|
|
12422
|
-
|
|
12307
|
+
let is4xx = false;
|
|
12308
|
+
try {
|
|
12309
|
+
const response = await fetch(config.authUrl, {
|
|
12310
|
+
method: "POST",
|
|
12311
|
+
credentials: "include",
|
|
12312
|
+
headers: { "Content-Type": "application/json" }
|
|
12313
|
+
});
|
|
12314
|
+
if (!response.ok) {
|
|
12315
|
+
is4xx = response.status >= 400 && response.status < 500;
|
|
12316
|
+
throw new Error(`HTTP ${response.status}`);
|
|
12317
|
+
}
|
|
12318
|
+
const data = await response.json();
|
|
12319
|
+
if (!data.token) {
|
|
12320
|
+
throw new Error("Invalid proxy auth response");
|
|
12321
|
+
}
|
|
12322
|
+
const ttl = data.expiresIn ?? 300;
|
|
12323
|
+
state.accessToken = data.token;
|
|
12324
|
+
state.refreshToken = null;
|
|
12325
|
+
state.tokenFamily = null;
|
|
12326
|
+
state.accessTokenExpiry = Date.now() + ttl * 1e3;
|
|
12327
|
+
state.refreshTokenExpiry = null;
|
|
12328
|
+
state.isAuthenticated = true;
|
|
12329
|
+
if (config.autoRefresh && onRefreshScheduled) {
|
|
12330
|
+
onRefreshScheduled();
|
|
12331
|
+
}
|
|
12332
|
+
return true;
|
|
12333
|
+
} catch {
|
|
12334
|
+
if (is4xx || attempt === maxRetries) {
|
|
12335
|
+
state.isAuthenticated = false;
|
|
12336
|
+
return false;
|
|
12337
|
+
}
|
|
12338
|
+
}
|
|
12339
|
+
}
|
|
12340
|
+
state.isAuthenticated = false;
|
|
12341
|
+
return false;
|
|
12423
12342
|
}
|
|
12424
|
-
function
|
|
12425
|
-
|
|
12426
|
-
|
|
12427
|
-
|
|
12428
|
-
|
|
12429
|
-
|
|
12430
|
-
|
|
12431
|
-
|
|
12432
|
-
|
|
12433
|
-
|
|
12434
|
-
|
|
12435
|
-
|
|
12436
|
-
|
|
12437
|
-
|
|
12438
|
-
|
|
12439
|
-
|
|
12440
|
-
|
|
12441
|
-
|
|
12442
|
-
|
|
12443
|
-
|
|
12444
|
-
|
|
12445
|
-
|
|
12446
|
-
|
|
12447
|
-
|
|
12448
|
-
|
|
12449
|
-
|
|
12450
|
-
|
|
12451
|
-
|
|
12452
|
-
|
|
12453
|
-
|
|
12454
|
-
|
|
12455
|
-
|
|
12456
|
-
|
|
12457
|
-
|
|
12458
|
-
if (isCard) {
|
|
12459
|
-
Object.assign(root.style, {
|
|
12460
|
-
position: "fixed",
|
|
12461
|
-
left: "50%",
|
|
12462
|
-
width: "fit-content",
|
|
12463
|
-
maxWidth: imageBanner ? "70vw" : "min(700px, 80vw)",
|
|
12464
|
-
height: "auto",
|
|
12465
|
-
minHeight: imageBanner ? "0" : "80px",
|
|
12466
|
-
maxHeight: imageBanner ? "70vh" : "calc(100vh - 300px)",
|
|
12467
|
-
overflowY: imageBanner ? "visible" : "auto",
|
|
12468
|
-
zIndex
|
|
12469
|
-
});
|
|
12470
|
-
if (imageBanner) {
|
|
12471
|
-
const translate = [];
|
|
12472
|
-
if (imageHorizontalPosition === "left") {
|
|
12473
|
-
root.style.left = "24px";
|
|
12474
|
-
} else if (imageHorizontalPosition === "right") {
|
|
12475
|
-
root.style.left = "";
|
|
12476
|
-
root.style.right = "24px";
|
|
12477
|
-
} else {
|
|
12478
|
-
root.style.left = "50%";
|
|
12479
|
-
translate.push("-50%");
|
|
12343
|
+
async function refreshAccessToken(config, state, onRefreshScheduled, sendToken) {
|
|
12344
|
+
if (state.isRefreshing) {
|
|
12345
|
+
return state.refreshPromise;
|
|
12346
|
+
}
|
|
12347
|
+
if (!state.refreshToken) {
|
|
12348
|
+
return false;
|
|
12349
|
+
}
|
|
12350
|
+
state.isRefreshing = true;
|
|
12351
|
+
state.refreshPromise = (async () => {
|
|
12352
|
+
const reauthenticateAfterRefreshFailure = async () => {
|
|
12353
|
+
clearState(state);
|
|
12354
|
+
clearStorage(config);
|
|
12355
|
+
const authed = await authenticateServerless(config, state, onRefreshScheduled);
|
|
12356
|
+
if (authed && sendToken) sendToken();
|
|
12357
|
+
return authed;
|
|
12358
|
+
};
|
|
12359
|
+
try {
|
|
12360
|
+
const response = await fetch(`${config.apiUrl}/${config.widgetId}/auth/refresh`, {
|
|
12361
|
+
method: "POST",
|
|
12362
|
+
headers: {
|
|
12363
|
+
"Content-Type": "application/json",
|
|
12364
|
+
Authorization: `Bearer ${state.refreshToken}`
|
|
12365
|
+
},
|
|
12366
|
+
body: JSON.stringify({
|
|
12367
|
+
widgetType: config.widgetType,
|
|
12368
|
+
...buildIdentityProof(config)
|
|
12369
|
+
})
|
|
12370
|
+
});
|
|
12371
|
+
if (!response.ok) {
|
|
12372
|
+
if (response.status === 400 || response.status === 401 || response.status === 403) {
|
|
12373
|
+
return reauthenticateAfterRefreshFailure();
|
|
12374
|
+
}
|
|
12375
|
+
const error = await response.json().catch(() => ({ error: "Token refresh failed" }));
|
|
12376
|
+
throw new Error(error.error || `HTTP ${response.status}`);
|
|
12480
12377
|
}
|
|
12481
|
-
|
|
12482
|
-
|
|
12483
|
-
|
|
12484
|
-
root.style.bottom = "24px";
|
|
12485
|
-
} else {
|
|
12486
|
-
root.style.top = "50%";
|
|
12487
|
-
translate.push("-50%");
|
|
12378
|
+
const data = await response.json();
|
|
12379
|
+
if (!data.accessToken || !data.refreshToken) {
|
|
12380
|
+
throw new Error("Invalid refresh response");
|
|
12488
12381
|
}
|
|
12489
|
-
|
|
12490
|
-
|
|
12491
|
-
|
|
12492
|
-
|
|
12493
|
-
|
|
12494
|
-
|
|
12495
|
-
|
|
12496
|
-
|
|
12497
|
-
root.style.top = "50%";
|
|
12498
|
-
root.style.transform = "translate(-50%, -50%)";
|
|
12499
|
-
} else {
|
|
12500
|
-
root.style.top = "10px";
|
|
12501
|
-
root.style.transform = "translateX(-50%)";
|
|
12382
|
+
setTokens(config, state, data, onRefreshScheduled);
|
|
12383
|
+
if (sendToken) sendToken();
|
|
12384
|
+
return true;
|
|
12385
|
+
} catch {
|
|
12386
|
+
return reauthenticateAfterRefreshFailure();
|
|
12387
|
+
} finally {
|
|
12388
|
+
state.isRefreshing = false;
|
|
12389
|
+
state.refreshPromise = null;
|
|
12502
12390
|
}
|
|
12503
|
-
}
|
|
12504
|
-
|
|
12391
|
+
})();
|
|
12392
|
+
return state.refreshPromise;
|
|
12393
|
+
}
|
|
12394
|
+
async function getValidToken(config, state, onRefreshScheduled) {
|
|
12395
|
+
if (state.accessToken && !isTokenExpired(state.accessTokenExpiry)) {
|
|
12396
|
+
return state.accessToken;
|
|
12505
12397
|
}
|
|
12506
|
-
|
|
12507
|
-
|
|
12508
|
-
|
|
12509
|
-
|
|
12510
|
-
|
|
12511
|
-
|
|
12512
|
-
|
|
12513
|
-
|
|
12514
|
-
|
|
12515
|
-
|
|
12516
|
-
|
|
12517
|
-
|
|
12518
|
-
|
|
12519
|
-
|
|
12520
|
-
|
|
12521
|
-
|
|
12522
|
-
|
|
12523
|
-
|
|
12524
|
-
|
|
12525
|
-
|
|
12526
|
-
|
|
12527
|
-
whiteSpace: "normal",
|
|
12528
|
-
color
|
|
12529
|
-
});
|
|
12530
|
-
const imageUrl = ((_g = banner.image) == null ? void 0 : _g.desktopUrl) || ((_h = banner.image) == null ? void 0 : _h.mobileUrl);
|
|
12531
|
-
if (imageBanner && imageUrl) {
|
|
12532
|
-
const imageLinkUrl = (_i = banner.image) == null ? void 0 : _i.linkUrl;
|
|
12533
|
-
const imageOpenInNewTab = (_j = banner.image) == null ? void 0 : _j.openInNewTab;
|
|
12534
|
-
const img = el(
|
|
12535
|
-
"img",
|
|
12536
|
-
{
|
|
12537
|
-
display: "block",
|
|
12538
|
-
maxWidth: "70vw",
|
|
12539
|
-
maxHeight: "70vh",
|
|
12540
|
-
width: "auto",
|
|
12541
|
-
height: "auto",
|
|
12542
|
-
objectFit: "contain",
|
|
12543
|
-
objectPosition: imageObjectPosition(
|
|
12544
|
-
(_k = banner.image) == null ? void 0 : _k.horizontalAlignment,
|
|
12545
|
-
(_l = banner.image) == null ? void 0 : _l.verticalAlignment
|
|
12546
|
-
),
|
|
12547
|
-
cursor: imageLinkUrl ? "pointer" : "",
|
|
12548
|
-
borderRadius: ((_m = banner.image) == null ? void 0 : _m.cornerRadius) === "rounded" ? "8px" : "0"
|
|
12549
|
-
},
|
|
12550
|
-
{ src: imageUrl, alt: banner.title || "banner" }
|
|
12551
|
-
);
|
|
12552
|
-
if (imageLinkUrl) {
|
|
12553
|
-
img.addEventListener("click", () => {
|
|
12554
|
-
if (imageOpenInNewTab) {
|
|
12555
|
-
window.open(imageLinkUrl, "_blank", "noopener,noreferrer");
|
|
12556
|
-
} else {
|
|
12557
|
-
window.location.href = imageLinkUrl;
|
|
12558
|
-
}
|
|
12398
|
+
if (config.authUrl) {
|
|
12399
|
+
const authed2 = await authenticateViaProxy(config, state, onRefreshScheduled);
|
|
12400
|
+
if (authed2 && state.accessToken) return state.accessToken;
|
|
12401
|
+
throw new Error("Unable to obtain valid token");
|
|
12402
|
+
}
|
|
12403
|
+
const refreshed = await refreshAccessToken(config, state, onRefreshScheduled);
|
|
12404
|
+
if (refreshed && state.accessToken) return state.accessToken;
|
|
12405
|
+
const authed = await authenticateServerless(config, state, onRefreshScheduled);
|
|
12406
|
+
if (authed && state.accessToken) return state.accessToken;
|
|
12407
|
+
throw new Error("Unable to obtain valid token");
|
|
12408
|
+
}
|
|
12409
|
+
async function logout(config, state) {
|
|
12410
|
+
if (state.accessToken) {
|
|
12411
|
+
try {
|
|
12412
|
+
await fetch(`${config.apiUrl}/${config.widgetId}/auth/logout`, {
|
|
12413
|
+
method: "POST",
|
|
12414
|
+
headers: {
|
|
12415
|
+
"Content-Type": "application/json",
|
|
12416
|
+
Authorization: `Bearer ${state.accessToken}`
|
|
12417
|
+
},
|
|
12418
|
+
body: JSON.stringify({ refreshToken: state.refreshToken })
|
|
12559
12419
|
});
|
|
12560
|
-
}
|
|
12561
|
-
content.appendChild(img);
|
|
12562
|
-
} else {
|
|
12563
|
-
content.innerHTML = sanitizeBannerHtml(banner.text);
|
|
12564
|
-
styleRichText(content);
|
|
12565
|
-
const textAlign = readTextAlign(content);
|
|
12566
|
-
content.style.textAlign = textAlign;
|
|
12567
|
-
if (isCard) {
|
|
12568
|
-
contentRow.style.justifyContent = justifyFromTextAlign(textAlign);
|
|
12420
|
+
} catch {
|
|
12569
12421
|
}
|
|
12570
12422
|
}
|
|
12571
|
-
|
|
12572
|
-
|
|
12573
|
-
|
|
12574
|
-
|
|
12575
|
-
|
|
12576
|
-
|
|
12577
|
-
|
|
12578
|
-
|
|
12579
|
-
|
|
12580
|
-
|
|
12581
|
-
|
|
12582
|
-
|
|
12583
|
-
|
|
12584
|
-
|
|
12585
|
-
|
|
12586
|
-
|
|
12587
|
-
|
|
12588
|
-
|
|
12589
|
-
|
|
12590
|
-
|
|
12591
|
-
|
|
12592
|
-
|
|
12593
|
-
|
|
12594
|
-
|
|
12595
|
-
|
|
12596
|
-
|
|
12597
|
-
|
|
12598
|
-
|
|
12599
|
-
|
|
12600
|
-
|
|
12601
|
-
|
|
12602
|
-
alignItems: "flex-end",
|
|
12603
|
-
justifyContent: "center",
|
|
12604
|
-
flexShrink: "0"
|
|
12605
|
-
});
|
|
12606
|
-
inlineWrap.appendChild(btn);
|
|
12607
|
-
contentRow.appendChild(inlineWrap);
|
|
12608
|
-
contentWrap.appendChild(contentRow);
|
|
12609
|
-
} else {
|
|
12610
|
-
contentRow.appendChild(content);
|
|
12611
|
-
contentWrap.appendChild(contentRow);
|
|
12612
|
-
const wrap = el("div", {
|
|
12613
|
-
display: "flex",
|
|
12614
|
-
width: "100%",
|
|
12615
|
-
justifyContent: ctaAlign(ctaPosition)
|
|
12616
|
-
});
|
|
12617
|
-
wrap.appendChild(btn);
|
|
12618
|
-
contentWrap.appendChild(wrap);
|
|
12423
|
+
clearState(state);
|
|
12424
|
+
clearStorage(config);
|
|
12425
|
+
}
|
|
12426
|
+
const inflightErrorSettings = /* @__PURE__ */ new Map();
|
|
12427
|
+
function applyErrorSettingsToState(state, data) {
|
|
12428
|
+
if (data.configured) {
|
|
12429
|
+
state.errorSettings = {
|
|
12430
|
+
errorMessage: data.errorMessage,
|
|
12431
|
+
modalColor: data.modalColor,
|
|
12432
|
+
backgroundImage: data.backgroundImage
|
|
12433
|
+
};
|
|
12434
|
+
}
|
|
12435
|
+
if (data.loadingAnimation) {
|
|
12436
|
+
state.loadingAnimation = data.loadingAnimation;
|
|
12437
|
+
}
|
|
12438
|
+
if (data.themePalette) {
|
|
12439
|
+
state.themePalette = data.themePalette;
|
|
12440
|
+
}
|
|
12441
|
+
if (typeof data.font === "string" && data.font) {
|
|
12442
|
+
state.font = data.font;
|
|
12443
|
+
}
|
|
12444
|
+
if (data.defaultColorSchema === "light" || data.defaultColorSchema === "dark") {
|
|
12445
|
+
state.defaultColorSchema = data.defaultColorSchema;
|
|
12446
|
+
}
|
|
12447
|
+
}
|
|
12448
|
+
async function fetchErrorSettings(config, state, opts = {}) {
|
|
12449
|
+
if (!opts.skipCache) {
|
|
12450
|
+
const cached = loadErrorSettingsFromStorage(config);
|
|
12451
|
+
if (cached) {
|
|
12452
|
+
applyErrorSettingsToState(state, cached);
|
|
12453
|
+
return state.errorSettings;
|
|
12619
12454
|
}
|
|
12620
|
-
} else {
|
|
12621
|
-
contentRow.appendChild(content);
|
|
12622
|
-
contentWrap.appendChild(contentRow);
|
|
12623
12455
|
}
|
|
12624
|
-
|
|
12625
|
-
|
|
12626
|
-
|
|
12627
|
-
|
|
12628
|
-
|
|
12629
|
-
|
|
12630
|
-
|
|
12631
|
-
|
|
12632
|
-
|
|
12633
|
-
|
|
12634
|
-
|
|
12635
|
-
|
|
12636
|
-
|
|
12637
|
-
|
|
12638
|
-
|
|
12639
|
-
|
|
12640
|
-
|
|
12641
|
-
|
|
12642
|
-
|
|
12643
|
-
|
|
12644
|
-
|
|
12456
|
+
const url = `${config.apiUrl}/${config.widgetId}/auth/error-settings?widgetType=${config.widgetType}`;
|
|
12457
|
+
let promise = inflightErrorSettings.get(url);
|
|
12458
|
+
if (!promise) {
|
|
12459
|
+
promise = (async () => {
|
|
12460
|
+
try {
|
|
12461
|
+
const response = await fetch(url, {
|
|
12462
|
+
method: "GET",
|
|
12463
|
+
headers: { "Content-Type": "application/json" }
|
|
12464
|
+
});
|
|
12465
|
+
if (!response.ok) return null;
|
|
12466
|
+
const data2 = await response.json();
|
|
12467
|
+
saveErrorSettingsToStorage(config, data2);
|
|
12468
|
+
return data2;
|
|
12469
|
+
} catch {
|
|
12470
|
+
return null;
|
|
12471
|
+
} finally {
|
|
12472
|
+
inflightErrorSettings.delete(url);
|
|
12473
|
+
}
|
|
12474
|
+
})();
|
|
12475
|
+
inflightErrorSettings.set(url, promise);
|
|
12476
|
+
}
|
|
12477
|
+
const data = await promise;
|
|
12478
|
+
if (!data) return null;
|
|
12479
|
+
applyErrorSettingsToState(state, data);
|
|
12480
|
+
return state.errorSettings;
|
|
12481
|
+
}
|
|
12482
|
+
function clearState(state) {
|
|
12483
|
+
state.accessToken = null;
|
|
12484
|
+
state.refreshToken = null;
|
|
12485
|
+
state.tokenFamily = null;
|
|
12486
|
+
state.accessTokenExpiry = null;
|
|
12487
|
+
state.refreshTokenExpiry = null;
|
|
12488
|
+
state.isAuthenticated = false;
|
|
12489
|
+
state.isRefreshing = false;
|
|
12490
|
+
state.refreshPromise = null;
|
|
12491
|
+
state.lastAuthError = null;
|
|
12492
|
+
if (state.refreshTimer) {
|
|
12493
|
+
clearTimeout(state.refreshTimer);
|
|
12494
|
+
state.refreshTimer = null;
|
|
12495
|
+
}
|
|
12496
|
+
if (state.syncTimer) {
|
|
12497
|
+
clearInterval(state.syncTimer);
|
|
12498
|
+
state.syncTimer = null;
|
|
12499
|
+
}
|
|
12500
|
+
}
|
|
12501
|
+
const BUNDLE_READY_TIMEOUT_MS = 3e4;
|
|
12502
|
+
function isPromiseLike(value) {
|
|
12503
|
+
return (typeof value === "object" || typeof value === "function") && value !== null && typeof value.then === "function";
|
|
12504
|
+
}
|
|
12505
|
+
function isReadyHandle(value) {
|
|
12506
|
+
if (typeof value !== "object" || value === null || !("ready" in value)) {
|
|
12507
|
+
return false;
|
|
12508
|
+
}
|
|
12509
|
+
return isPromiseLike(value.ready);
|
|
12510
|
+
}
|
|
12511
|
+
function waitWithTimeout(promise, timeoutMs, timeoutMessage) {
|
|
12512
|
+
return new Promise((resolve, reject) => {
|
|
12513
|
+
const timeoutId = setTimeout(() => {
|
|
12514
|
+
reject(new Error(timeoutMessage));
|
|
12515
|
+
}, timeoutMs);
|
|
12516
|
+
Promise.resolve(promise).then(
|
|
12517
|
+
(value) => {
|
|
12518
|
+
clearTimeout(timeoutId);
|
|
12519
|
+
resolve(value);
|
|
12520
|
+
},
|
|
12521
|
+
(error) => {
|
|
12522
|
+
clearTimeout(timeoutId);
|
|
12523
|
+
reject(error);
|
|
12524
|
+
}
|
|
12525
|
+
);
|
|
12526
|
+
});
|
|
12527
|
+
}
|
|
12528
|
+
async function waitForBundleMountReadiness(mountResult, firstPaint, timeoutMs = BUNDLE_READY_TIMEOUT_MS) {
|
|
12529
|
+
const resolvedMountResult = isPromiseLike(mountResult) ? await waitWithTimeout(
|
|
12530
|
+
mountResult,
|
|
12531
|
+
timeoutMs,
|
|
12532
|
+
`Widget bundle mount did not resolve within ${timeoutMs}ms`
|
|
12533
|
+
) : mountResult;
|
|
12534
|
+
if (!isReadyHandle(resolvedMountResult)) {
|
|
12535
|
+
await firstPaint;
|
|
12536
|
+
return "first-paint";
|
|
12537
|
+
}
|
|
12538
|
+
await waitWithTimeout(
|
|
12539
|
+
resolvedMountResult.ready,
|
|
12540
|
+
timeoutMs,
|
|
12541
|
+
`Widget bundle did not report deep readiness within ${timeoutMs}ms`
|
|
12542
|
+
);
|
|
12543
|
+
return "deep-ready";
|
|
12544
|
+
}
|
|
12545
|
+
function isWidgetBundleRuntime(value) {
|
|
12546
|
+
return (typeof value === "object" || typeof value === "function") && value !== null && typeof value.mount === "function";
|
|
12547
|
+
}
|
|
12548
|
+
function normalizeBundleUrl(url, baseUrl) {
|
|
12549
|
+
const normalized = new URL(url, baseUrl);
|
|
12550
|
+
normalized.hash = "";
|
|
12551
|
+
return normalized.href;
|
|
12552
|
+
}
|
|
12553
|
+
function createBundleRuntimeLoader({
|
|
12554
|
+
loadScript,
|
|
12555
|
+
readGlobal,
|
|
12556
|
+
baseUrl
|
|
12557
|
+
}) {
|
|
12558
|
+
const runtimePromises = /* @__PURE__ */ new Map();
|
|
12559
|
+
const globalLoadTails = /* @__PURE__ */ new Map();
|
|
12560
|
+
return async function getBundleRuntime(globalName, bundleUrl) {
|
|
12561
|
+
const normalizedUrl = normalizeBundleUrl(bundleUrl, baseUrl());
|
|
12562
|
+
const cacheKey = `${globalName}:${normalizedUrl}`;
|
|
12563
|
+
const cachedRuntime = runtimePromises.get(cacheKey);
|
|
12564
|
+
if (cachedRuntime) return cachedRuntime;
|
|
12565
|
+
const previousLoad = globalLoadTails.get(globalName) || Promise.resolve();
|
|
12566
|
+
const runtimePromise = previousLoad.then(async () => {
|
|
12567
|
+
await loadScript(normalizedUrl);
|
|
12568
|
+
const runtime = readGlobal(globalName);
|
|
12569
|
+
if (!isWidgetBundleRuntime(runtime)) {
|
|
12570
|
+
throw new Error(
|
|
12571
|
+
`window.${globalName}.mount not found after loading ${normalizedUrl}`
|
|
12572
|
+
);
|
|
12573
|
+
}
|
|
12574
|
+
const mount = runtime.mount;
|
|
12575
|
+
return {
|
|
12576
|
+
mount(container, config) {
|
|
12577
|
+
return mount.call(runtime, container, config);
|
|
12578
|
+
}
|
|
12579
|
+
};
|
|
12580
|
+
});
|
|
12581
|
+
runtimePromises.set(cacheKey, runtimePromise);
|
|
12582
|
+
const loadTail = runtimePromise.then(
|
|
12583
|
+
() => void 0,
|
|
12584
|
+
() => void 0
|
|
12585
|
+
);
|
|
12586
|
+
globalLoadTails.set(globalName, loadTail);
|
|
12587
|
+
void loadTail.then(() => {
|
|
12588
|
+
if (globalLoadTails.get(globalName) === loadTail) {
|
|
12589
|
+
globalLoadTails.delete(globalName);
|
|
12590
|
+
}
|
|
12591
|
+
});
|
|
12592
|
+
try {
|
|
12593
|
+
return await runtimePromise;
|
|
12594
|
+
} catch (error) {
|
|
12595
|
+
if (runtimePromises.get(cacheKey) === runtimePromise) {
|
|
12596
|
+
runtimePromises.delete(cacheKey);
|
|
12597
|
+
}
|
|
12598
|
+
throw error;
|
|
12599
|
+
}
|
|
12600
|
+
};
|
|
12601
|
+
}
|
|
12602
|
+
function appendScript(url) {
|
|
12603
|
+
return new Promise((resolve, reject) => {
|
|
12604
|
+
const script = document.createElement("script");
|
|
12605
|
+
script.src = url;
|
|
12606
|
+
script.onload = () => resolve();
|
|
12607
|
+
script.onerror = () => reject(new Error(`Failed to load ${url}`));
|
|
12608
|
+
document.head.appendChild(script);
|
|
12645
12609
|
});
|
|
12646
|
-
close.type = "button";
|
|
12647
|
-
close.setAttribute("aria-label", "dismiss banner");
|
|
12648
|
-
close.innerHTML = "×";
|
|
12649
|
-
close.addEventListener("click", handlers.onDismiss);
|
|
12650
|
-
root.appendChild(close);
|
|
12651
|
-
return root;
|
|
12652
12610
|
}
|
|
12653
|
-
const
|
|
12654
|
-
|
|
12655
|
-
|
|
12656
|
-
|
|
12657
|
-
|
|
12611
|
+
const loadBrowserBundleRuntime = createBundleRuntimeLoader({
|
|
12612
|
+
loadScript: appendScript,
|
|
12613
|
+
readGlobal: (globalName) => window[globalName],
|
|
12614
|
+
baseUrl: () => document.baseURI
|
|
12615
|
+
});
|
|
12616
|
+
function getOrLoadBundleRuntime(globalName, bundleUrl) {
|
|
12617
|
+
return loadBrowserBundleRuntime(globalName, bundleUrl);
|
|
12618
|
+
}
|
|
12619
|
+
function assertCallbackName(callbackName) {
|
|
12620
|
+
if (!callbackName || typeof callbackName !== "string") {
|
|
12621
|
+
throw new TypeError("ReturningAI callback name must be a non-empty string");
|
|
12622
|
+
}
|
|
12623
|
+
}
|
|
12624
|
+
function assertCallback(callback) {
|
|
12625
|
+
if (typeof callback !== "function") {
|
|
12626
|
+
throw new TypeError("ReturningAI callback must be a function");
|
|
12627
|
+
}
|
|
12628
|
+
}
|
|
12629
|
+
class WidgetCallbackRegistry {
|
|
12630
|
+
constructor() {
|
|
12631
|
+
__publicField(this, "registeredCallbacks", {});
|
|
12632
|
+
__publicField(this, "locked", false);
|
|
12633
|
+
}
|
|
12634
|
+
get isLocked() {
|
|
12635
|
+
return this.locked;
|
|
12636
|
+
}
|
|
12637
|
+
registerCallback(callbackName, callback) {
|
|
12638
|
+
if (this.locked) {
|
|
12639
|
+
return;
|
|
12658
12640
|
}
|
|
12659
|
-
|
|
12641
|
+
assertCallbackName(callbackName);
|
|
12642
|
+
assertCallback(callback);
|
|
12643
|
+
this.registeredCallbacks = {
|
|
12644
|
+
...this.registeredCallbacks,
|
|
12645
|
+
[callbackName]: callback
|
|
12646
|
+
};
|
|
12647
|
+
}
|
|
12648
|
+
lock() {
|
|
12649
|
+
if (this.locked) {
|
|
12650
|
+
return;
|
|
12651
|
+
}
|
|
12652
|
+
this.locked = true;
|
|
12653
|
+
}
|
|
12654
|
+
read() {
|
|
12655
|
+
return { ...this.registeredCallbacks };
|
|
12660
12656
|
}
|
|
12661
|
-
return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, (c) => {
|
|
12662
|
-
const r = Math.random() * 16 | 0;
|
|
12663
|
-
const v = c === "x" ? r : r & 3 | 8;
|
|
12664
|
-
return v.toString(16);
|
|
12665
|
-
});
|
|
12666
12657
|
}
|
|
12667
|
-
|
|
12668
|
-
|
|
12658
|
+
const STORE_CALLBACK_FIELD_OPTIONS_SCOPE = "store.callback_field_options";
|
|
12659
|
+
const STORE_CALLBACK_FIELD_OPTIONS_CALLBACK_NAME = "callbackFieldOptions";
|
|
12660
|
+
const STORE_CALLBACK_FIELD_OPTIONS_TIMEOUT_MS = 15e3;
|
|
12661
|
+
const STORE_PURCHASE_SUCCESS_SCOPE = "store.purchase_success";
|
|
12662
|
+
const STORE_PURCHASE_SUCCESS_CALLBACK_NAME = "storePurchaseSuccess";
|
|
12663
|
+
function isSupportedStoreHostCallback(callbackName, payload) {
|
|
12664
|
+
if (!payload) return false;
|
|
12665
|
+
return callbackName === STORE_CALLBACK_FIELD_OPTIONS_CALLBACK_NAME && payload.callbackName === STORE_CALLBACK_FIELD_OPTIONS_CALLBACK_NAME && payload.scope === STORE_CALLBACK_FIELD_OPTIONS_SCOPE || callbackName === STORE_PURCHASE_SUCCESS_CALLBACK_NAME && payload.callbackName === STORE_PURCHASE_SUCCESS_CALLBACK_NAME && payload.scope === STORE_PURCHASE_SUCCESS_SCOPE;
|
|
12666
|
+
}
|
|
12667
|
+
async function invokeStoreHostCallback(callbacks, callbackName, payload) {
|
|
12668
|
+
if (!isSupportedStoreHostCallback(callbackName, payload)) {
|
|
12669
|
+
throw new Error("Host callback is only supported for store widgets");
|
|
12670
|
+
}
|
|
12671
|
+
const callback = callbacks[callbackName];
|
|
12672
|
+
if (!callback) throw new Error("Host callback is not registered");
|
|
12673
|
+
let value;
|
|
12669
12674
|
try {
|
|
12670
|
-
|
|
12671
|
-
if (!id) {
|
|
12672
|
-
id = uuid();
|
|
12673
|
-
localStorage.setItem(key, id);
|
|
12674
|
-
}
|
|
12675
|
-
return id;
|
|
12675
|
+
value = await callback(payload);
|
|
12676
12676
|
} catch {
|
|
12677
|
-
|
|
12677
|
+
throw new Error("Host callback failed");
|
|
12678
12678
|
}
|
|
12679
|
+
return callbackName === STORE_CALLBACK_FIELD_OPTIONS_CALLBACK_NAME ? value : void 0;
|
|
12679
12680
|
}
|
|
12680
|
-
function
|
|
12681
|
-
|
|
12681
|
+
function debounce(fn, wait) {
|
|
12682
|
+
let timer = null;
|
|
12683
|
+
return {
|
|
12684
|
+
call(h) {
|
|
12685
|
+
if (timer) clearTimeout(timer);
|
|
12686
|
+
timer = setTimeout(() => {
|
|
12687
|
+
fn(h);
|
|
12688
|
+
timer = null;
|
|
12689
|
+
}, wait);
|
|
12690
|
+
},
|
|
12691
|
+
cancel() {
|
|
12692
|
+
if (timer) {
|
|
12693
|
+
clearTimeout(timer);
|
|
12694
|
+
timer = null;
|
|
12695
|
+
}
|
|
12696
|
+
}
|
|
12697
|
+
};
|
|
12698
|
+
}
|
|
12699
|
+
function sendTokenToWidget(config, state, iframe) {
|
|
12700
|
+
var _a;
|
|
12701
|
+
if (!state.accessToken) return;
|
|
12682
12702
|
try {
|
|
12683
|
-
|
|
12684
|
-
|
|
12703
|
+
(_a = iframe.contentWindow) == null ? void 0 : _a.postMessage(
|
|
12704
|
+
{
|
|
12705
|
+
type: "RETURNINGAI_WIDGET_TOKEN",
|
|
12706
|
+
value: {
|
|
12707
|
+
widgetId: config.widgetId,
|
|
12708
|
+
token: state.accessToken,
|
|
12709
|
+
...config.customData !== void 0 && { customData: config.customData }
|
|
12710
|
+
}
|
|
12711
|
+
},
|
|
12712
|
+
config.widgetDomain
|
|
12713
|
+
);
|
|
12685
12714
|
} catch {
|
|
12686
12715
|
}
|
|
12687
12716
|
}
|
|
12717
|
+
function setupMessageListener(config, state, _shadow, iframe, onRefreshScheduled, onLogout, hideLoader, emit, getCallbacks) {
|
|
12718
|
+
const heightSetter = debounce((h) => {
|
|
12719
|
+
iframe.style.height = `${h}px`;
|
|
12720
|
+
emit == null ? void 0 : emit("rai-height-change", { height: h });
|
|
12721
|
+
}, config.heightDebounce ?? 100);
|
|
12722
|
+
const handler = async (event) => {
|
|
12723
|
+
var _a;
|
|
12724
|
+
if (event.origin !== config.widgetDomain) return;
|
|
12725
|
+
if (!event.data || typeof event.data.type !== "string") return;
|
|
12726
|
+
const { type, containerId, widgetId, payload } = event.data;
|
|
12727
|
+
switch (type) {
|
|
12728
|
+
case "RETURNINGAI_WIDGET_REQUEST_TOKEN": {
|
|
12729
|
+
try {
|
|
12730
|
+
const token = await getValidToken(config, state, onRefreshScheduled);
|
|
12731
|
+
(_a = iframe.contentWindow) == null ? void 0 : _a.postMessage(
|
|
12732
|
+
{
|
|
12733
|
+
type: "RETURNINGAI_WIDGET_TOKEN",
|
|
12734
|
+
value: {
|
|
12735
|
+
token,
|
|
12736
|
+
widgetId: config.widgetId,
|
|
12737
|
+
...config.customData !== void 0 && { customData: config.customData }
|
|
12738
|
+
}
|
|
12739
|
+
},
|
|
12740
|
+
config.widgetDomain
|
|
12741
|
+
);
|
|
12742
|
+
} catch {
|
|
12743
|
+
}
|
|
12744
|
+
break;
|
|
12745
|
+
}
|
|
12746
|
+
case "WIDGET_HEIGHT_UPDATE": {
|
|
12747
|
+
const h = Number(payload == null ? void 0 : payload.height);
|
|
12748
|
+
if (Number.isFinite(h) && h > 0) {
|
|
12749
|
+
heightSetter.call(h);
|
|
12750
|
+
}
|
|
12751
|
+
break;
|
|
12752
|
+
}
|
|
12753
|
+
case "WIDGET_READY": {
|
|
12754
|
+
if (widgetId !== void 0 && widgetId !== config.widgetId) break;
|
|
12755
|
+
if (containerId !== void 0 && containerId !== config.container) break;
|
|
12756
|
+
iframe.classList.add("loaded");
|
|
12757
|
+
if (hideLoader) hideLoader();
|
|
12758
|
+
emit == null ? void 0 : emit("rai-ready");
|
|
12759
|
+
break;
|
|
12760
|
+
}
|
|
12761
|
+
case "WIDGET_ERROR": {
|
|
12762
|
+
if (hideLoader) hideLoader();
|
|
12763
|
+
break;
|
|
12764
|
+
}
|
|
12765
|
+
case "WIDGET_LOGOUT": {
|
|
12766
|
+
if (onLogout) await onLogout();
|
|
12767
|
+
break;
|
|
12768
|
+
}
|
|
12769
|
+
case "RETURNINGAI_WIDGET_ACTION": {
|
|
12770
|
+
if (event.source !== iframe.contentWindow) break;
|
|
12771
|
+
const message = event.data;
|
|
12772
|
+
if (config.widgetType !== "store" && config.widgetType !== "custom") break;
|
|
12773
|
+
if (message.widgetType !== "store") break;
|
|
12774
|
+
if (message.action !== "store:host-callback") break;
|
|
12775
|
+
if (!isSupportedStoreHostCallback(message.callbackName, message.payload)) break;
|
|
12776
|
+
if (message.widgetId !== void 0 && message.widgetId !== config.widgetId) break;
|
|
12777
|
+
if (message.containerId !== void 0 && message.containerId !== config.container) break;
|
|
12778
|
+
const respond = (result) => {
|
|
12779
|
+
var _a2;
|
|
12780
|
+
(_a2 = iframe.contentWindow) == null ? void 0 : _a2.postMessage(result, config.widgetDomain);
|
|
12781
|
+
};
|
|
12782
|
+
const callbacks = (getCallbacks == null ? void 0 : getCallbacks()) ?? {};
|
|
12783
|
+
if (!callbacks[message.callbackName]) {
|
|
12784
|
+
respond({
|
|
12785
|
+
type: "RETURNINGAI_WIDGET_ACTION_RESULT",
|
|
12786
|
+
requestId: message.requestId,
|
|
12787
|
+
action: "store:host-callback",
|
|
12788
|
+
ok: false,
|
|
12789
|
+
status: "failed",
|
|
12790
|
+
error: { message: "Host callback is not registered" }
|
|
12791
|
+
});
|
|
12792
|
+
break;
|
|
12793
|
+
}
|
|
12794
|
+
try {
|
|
12795
|
+
const value = await invokeStoreHostCallback(
|
|
12796
|
+
callbacks,
|
|
12797
|
+
message.callbackName,
|
|
12798
|
+
message.payload
|
|
12799
|
+
);
|
|
12800
|
+
const result = {
|
|
12801
|
+
type: "RETURNINGAI_WIDGET_ACTION_RESULT",
|
|
12802
|
+
requestId: message.requestId,
|
|
12803
|
+
action: "store:host-callback",
|
|
12804
|
+
ok: true,
|
|
12805
|
+
status: "success",
|
|
12806
|
+
...value !== void 0 ? { value } : {}
|
|
12807
|
+
};
|
|
12808
|
+
respond(result);
|
|
12809
|
+
} catch {
|
|
12810
|
+
respond({
|
|
12811
|
+
type: "RETURNINGAI_WIDGET_ACTION_RESULT",
|
|
12812
|
+
requestId: message.requestId,
|
|
12813
|
+
action: "store:host-callback",
|
|
12814
|
+
ok: false,
|
|
12815
|
+
status: "failed",
|
|
12816
|
+
error: { message: "Host callback failed" }
|
|
12817
|
+
});
|
|
12818
|
+
}
|
|
12819
|
+
break;
|
|
12820
|
+
}
|
|
12821
|
+
}
|
|
12822
|
+
};
|
|
12823
|
+
window.addEventListener("message", handler);
|
|
12824
|
+
return () => {
|
|
12825
|
+
window.removeEventListener("message", handler);
|
|
12826
|
+
heightSetter.cancel();
|
|
12827
|
+
};
|
|
12828
|
+
}
|
|
12688
12829
|
const widgetCSS = ':host{display:block;position:relative;width:100%;height:100%}.rai-loader{position:absolute;top:0;left:0;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:.75rem;width:100%;height:100%;background:var(--background-5, var(--rai-loader-bg, #ffffff));border-radius:8px;z-index:10;transition:opacity .3s ease-out;font-family:var(--rai-loader-font, "Roboto", system-ui, -apple-system, sans-serif)}.rai-loader.fade-out{opacity:0;pointer-events:none}.rai-loader-text{margin:.5rem 0 0;font-size:1.125rem;line-height:1.75rem;font-weight:400;letter-spacing:normal;color:var(--accent-1, var(--rai-accent, #000000));text-align:center}@media (min-width: 768px){.rai-loader-text{font-size:1.5rem;line-height:2rem}}.rai-error{display:none;position:absolute;top:0;left:0;width:100%;height:100%;align-items:center;justify-content:center;flex-direction:column;gap:12px;background:var(--rai-error-bg, #1a1a1a);border-radius:8px;padding:24px;box-sizing:border-box;text-align:center;color:var(--rai-error-text, #9ca3af);font-family:system-ui,-apple-system,sans-serif;z-index:10}.rai-error.visible{display:flex}iframe{display:block;border:none;opacity:0;transition:opacity .3s ease-in}iframe.loaded{opacity:1}.rai-lottie-loader{width:100px;height:100px}.rai-lottie-loader svg{width:100%!important;height:100%!important}.rai-lottie-spinner{width:32px;height:32px;margin:34px auto;border:3px solid var(--rai-text4, #6b7280);border-top-color:var(--rai-accent, #000000);border-radius:50%;animation:rai-spin .7s linear infinite}@keyframes rai-spin{to{transform:rotate(360deg)}}.rai-sdk-loader{position:relative;width:75px;height:100px}.rai-sdk-loader__bar{position:absolute;bottom:0;width:10px;height:50%;background:var(--rai-accent, #000000);transform-origin:center bottom;box-shadow:1px 1px #0003}.rai-sdk-loader__bar:nth-child(1){left:0;transform:scaleY(.2);animation:rai-sdk-barUp1 4s infinite}.rai-sdk-loader__bar:nth-child(2){left:15px;transform:scaleY(.4);animation:rai-sdk-barUp2 4s infinite}.rai-sdk-loader__bar:nth-child(3){left:30px;transform:scaleY(.6);animation:rai-sdk-barUp3 4s infinite}.rai-sdk-loader__bar:nth-child(4){left:45px;transform:scaleY(.8);animation:rai-sdk-barUp4 4s infinite}.rai-sdk-loader__bar:nth-child(5){left:60px;transform:scale(1);animation:rai-sdk-barUp5 4s infinite}.rai-sdk-loader__ball{position:absolute;bottom:10px;left:0;width:10px;height:10px;background:var(--rai-accent, #000000);border-radius:50%;animation:rai-sdk-ball 4s infinite}@keyframes rai-sdk-ball{0%{transform:translate(0)}5%{transform:translate(8px,-14px)}10%{transform:translate(15px,-10px)}17%{transform:translate(23px,-24px)}20%{transform:translate(30px,-20px)}27%{transform:translate(38px,-34px)}30%{transform:translate(45px,-30px)}37%{transform:translate(53px,-44px)}40%{transform:translate(60px,-40px)}50%{transform:translate(60px)}57%{transform:translate(53px,-14px)}60%{transform:translate(45px,-10px)}67%{transform:translate(37px,-24px)}70%{transform:translate(30px,-20px)}77%{transform:translate(22px,-34px)}80%{transform:translate(15px,-30px)}87%{transform:translate(7px,-44px)}90%{transform:translateY(-40px)}to{transform:translate(0)}}@keyframes rai-sdk-barUp1{0%{transform:scaleY(.2)}40%{transform:scaleY(.2)}50%{transform:scale(1)}90%{transform:scale(1)}to{transform:scaleY(.2)}}@keyframes rai-sdk-barUp2{0%{transform:scaleY(.4)}40%{transform:scaleY(.4)}50%{transform:scaleY(.8)}90%{transform:scaleY(.8)}to{transform:scaleY(.4)}}@keyframes rai-sdk-barUp3{0%{transform:scaleY(.6)}to{transform:scaleY(.6)}}@keyframes rai-sdk-barUp4{0%{transform:scaleY(.8)}40%{transform:scaleY(.8)}50%{transform:scaleY(.4)}90%{transform:scaleY(.4)}to{transform:scaleY(.8)}}@keyframes rai-sdk-barUp5{0%{transform:scale(1)}40%{transform:scale(1)}50%{transform:scaleY(.2)}90%{transform:scaleY(.2)}to{transform:scale(1)}}#loading-square{width:75px;aspect-ratio:1;display:flex;color:var(--rai-accent, #000000);background:linear-gradient(currentColor 0 0) right / 51% 100%,linear-gradient(currentColor 0 0) bottom / 100% 51%;background-repeat:no-repeat;animation:l16-0 2s infinite linear .25s}#loading-square>div{width:50%;height:50%;background:currentColor;animation:l16-1 .5s infinite linear}@keyframes l16-0{0%,12.49%{transform:rotate(0)}12.5%,37.49%{transform:rotate(90deg)}37.5%,62.49%{transform:rotate(180deg)}62.5%,87.49%{transform:rotate(270deg)}87.5%,to{transform:rotate(360deg)}}@keyframes l16-1{0%{transform:perspective(80px) rotate3d(-1,-1,0,0)}80%,to{transform:perspective(80px) rotate3d(-1,-1,0,-180deg)}}#loading-circle{width:75px;aspect-ratio:1;display:grid;grid:50%/50%;color:var(--rai-accent, #000000);border-radius:50%;--_g: no-repeat linear-gradient(currentColor 0 0);background:var(--_g),var(--_g),var(--_g);background-size:50.1% 50.1%;animation:l9-0 1.5s infinite steps(1) alternate,l9-0-0 3s infinite steps(1) alternate}#loading-circle>div{background:var(--rai-text4, #6b7280);border-top-left-radius:100px;transform:perspective(150px) rotateY(0) rotateX(0);transform-origin:bottom right;animation:l9-1 1.5s infinite linear alternate}@keyframes l9-0{0%{background-position:0 100%,100% 100%,100% 0}33%{background-position:100% 100%,100% 100%,100% 0}66%{background-position:100% 0,100% 0,100% 0}}@keyframes l9-0-0{0%{transform:scaleX(1) rotate(0)}50%{transform:scaleX(-1) rotate(-90deg)}}@keyframes l9-1{16.5%{transform:perspective(150px) rotateX(-90deg) rotateY(0) rotateX(0);filter:grayscale(.8)}33%{transform:perspective(150px) rotateX(-180deg) rotateY(0) rotateX(0)}66%{transform:perspective(150px) rotateX(-180deg) rotateY(-180deg) rotateX(0)}to{transform:perspective(150px) rotateX(-180deg) rotateY(-180deg) rotateX(-180deg);filter:grayscale(.8)}}.rai-custom-error{position:absolute;top:0;left:0;width:100%;height:100%;z-index:10}.tiptap strong.tw-font-bold,.tiptap b.tw-font-bold{font-weight:700}.tiptap em.tw-font-italic,.tiptap i.tw-font-italic{font-style:italic}.tiptap a.tiptap-rich-text-link{color:#3b82f6;text-decoration:underline;position:relative;display:inline-block;width:fit-content}.tiptap a.tiptap-rich-text-link:hover{color:#3b82f6cc;text-decoration:none}.tiptap a.tiptap-rich-text-link:not([title=""]):before{content:attr(title);position:absolute;top:-2rem;left:50%;transform:translate(-50%);white-space:nowrap;border-radius:.25rem;background-color:#000;padding:.25rem .5rem;color:#fff;opacity:0;transition:opacity .2s;pointer-events:none}.tiptap a.tiptap-rich-text-link:not([title=""]):hover:before{opacity:1}.tiptap p[style*="text-align: left"]{text-align:left}.tiptap p[style*="text-align: center"]{text-align:center}.tiptap p[style*="text-align: right"]{text-align:right}.tiptap p[style*="text-align: justify"]{text-align:justify}.tiptap u{text-decoration:underline}.tiptap.ProseMirror{background-color:transparent;height:fit-content!important;word-wrap:break-word;white-space:pre-wrap;white-space:break-spaces;-webkit-font-variant-ligatures:none;font-variant-ligatures:none;font-feature-settings:"liga" 0;padding:0;width:100%;overflow-y:auto}.tiptap{line-height:1.6;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,sans-serif}.tiptap p{margin:.5em 0}.tiptap p:first-child{margin-top:0}.tiptap p:last-child{margin-bottom:0}.tiptap img{max-width:100%;height:auto;display:block}.tiptap p[style*="text-align: left"] img{margin-left:0;margin-right:auto}.tiptap p[style*="text-align: center"] img{margin-left:auto;margin-right:auto}.tiptap p[style*="text-align: right"] img{margin-left:auto;margin-right:0}.rai-retry-btn{padding:8px 20px;border:none;border-radius:6px;background:var(--rai-accent, #000000);color:var(--rai-error-bg, #ffffff);font-size:14px;font-family:system-ui,-apple-system,sans-serif;cursor:pointer}.rai-retry-btn:hover{opacity:.85}';
|
|
12689
12830
|
const DEFINED_ATTRS = /* @__PURE__ */ new Set([
|
|
12690
12831
|
"community-id",
|
|
@@ -12793,15 +12934,6 @@ function resolveWidgetServerUrl(domainKey) {
|
|
|
12793
12934
|
function resolveV2ApiUrl(domainKey) {
|
|
12794
12935
|
return DOMAIN_KEY_TO_V2_API_URL[domainKey] || DOMAIN_KEY_TO_V2_API_URL.PROD;
|
|
12795
12936
|
}
|
|
12796
|
-
function loadScript(url) {
|
|
12797
|
-
return new Promise((resolve, reject) => {
|
|
12798
|
-
const s = document.createElement("script");
|
|
12799
|
-
s.src = url;
|
|
12800
|
-
s.onload = () => resolve();
|
|
12801
|
-
s.onerror = () => reject(new Error(`Failed to load ${url}`));
|
|
12802
|
-
document.head.appendChild(s);
|
|
12803
|
-
});
|
|
12804
|
-
}
|
|
12805
12937
|
const loadedFonts = /* @__PURE__ */ new Set();
|
|
12806
12938
|
function ensureGoogleFontLoaded(family) {
|
|
12807
12939
|
if (!family || loadedFonts.has(family)) return;
|
|
@@ -12817,9 +12949,10 @@ function ensureGoogleFontLoaded(family) {
|
|
|
12817
12949
|
const DANGEROUS_ELEMENTS = ["script", "iframe", "object", "embed"];
|
|
12818
12950
|
const URL_ATTRS = ["src", "href", "xlink:href"];
|
|
12819
12951
|
function sanitizeLoaderHtml(html2) {
|
|
12820
|
-
const
|
|
12821
|
-
|
|
12822
|
-
|
|
12952
|
+
const template = document.createElement("template");
|
|
12953
|
+
template.innerHTML = html2;
|
|
12954
|
+
template.content.querySelectorAll(DANGEROUS_ELEMENTS.join(",")).forEach((el2) => el2.remove());
|
|
12955
|
+
template.content.querySelectorAll("*").forEach((el2) => {
|
|
12823
12956
|
Array.from(el2.attributes).forEach((attr) => {
|
|
12824
12957
|
const name = attr.name.toLowerCase();
|
|
12825
12958
|
if (name.startsWith("on")) {
|
|
@@ -12832,7 +12965,9 @@ function sanitizeLoaderHtml(html2) {
|
|
|
12832
12965
|
}
|
|
12833
12966
|
});
|
|
12834
12967
|
});
|
|
12835
|
-
|
|
12968
|
+
const container = document.createElement("div");
|
|
12969
|
+
container.appendChild(template.content.cloneNode(true));
|
|
12970
|
+
return container.innerHTML;
|
|
12836
12971
|
}
|
|
12837
12972
|
function readConfig(el2, existingId) {
|
|
12838
12973
|
const get = (name) => el2.getAttribute(name) ?? el2.getAttribute(`data-${name}`) ?? "";
|
|
@@ -13177,15 +13312,13 @@ class BaseWidget extends HTMLElement {
|
|
|
13177
13312
|
}
|
|
13178
13313
|
/**
|
|
13179
13314
|
* Loads the community loading animation + theme palette from cache or API
|
|
13180
|
-
* and renders the animation above the
|
|
13181
|
-
* already painted by renderShell so this method only ADDS the animation;
|
|
13182
|
-
* users see two states at most: text-only → text + animation.
|
|
13315
|
+
* and renders the configured animation above the loading text.
|
|
13183
13316
|
*
|
|
13184
13317
|
* Stale-while-revalidate:
|
|
13185
13318
|
* - Cache hit → apply palette & render animation synchronously, fire
|
|
13186
13319
|
* background refresh.
|
|
13187
|
-
* - Cache miss →
|
|
13188
|
-
*
|
|
13320
|
+
* - Cache miss → retain the initial shell; await network; apply palette +
|
|
13321
|
+
* render the resolved animation or fallback.
|
|
13189
13322
|
*/
|
|
13190
13323
|
async fetchAndRenderLoader() {
|
|
13191
13324
|
var _a;
|
|
@@ -13299,48 +13432,35 @@ class BaseWidget extends HTMLElement {
|
|
|
13299
13432
|
}
|
|
13300
13433
|
hideLoader() {
|
|
13301
13434
|
if (!this.loaderEl) return;
|
|
13302
|
-
this.loaderEl
|
|
13303
|
-
|
|
13304
|
-
|
|
13305
|
-
return (_a = this.loaderEl) == null ? void 0 : _a.remove();
|
|
13306
|
-
}, 300);
|
|
13435
|
+
const loader = this.loaderEl;
|
|
13436
|
+
loader.classList.add("fade-out");
|
|
13437
|
+
setTimeout(() => loader.remove(), 300);
|
|
13307
13438
|
this.loaderEl = null;
|
|
13308
13439
|
}
|
|
13309
13440
|
/**
|
|
13310
|
-
*
|
|
13311
|
-
*
|
|
13312
|
-
*
|
|
13313
|
-
*
|
|
13314
|
-
* Strategy:
|
|
13315
|
-
* 1. MutationObserver fires when React commits any DOM mutation into
|
|
13316
|
-
* the container — synchronous inside mount(), but the callback runs
|
|
13317
|
-
* as a microtask, so it observes the first child addition.
|
|
13318
|
-
* 2. requestAnimationFrame waits one paint cycle so the React content
|
|
13319
|
-
* is actually visible before the SDK loader fades out.
|
|
13320
|
-
* 3. 2s fallback covers silent React mount errors so the loader doesn't
|
|
13321
|
-
* hang forever.
|
|
13322
|
-
*
|
|
13323
|
-
* Calls hideLoader() (with its 300ms fade-out) so the transition is smooth.
|
|
13441
|
+
* Resolve after a legacy bundle's first rendered child has reached a paint.
|
|
13442
|
+
* This remains the fallback for bundles that do not expose a deep-ready
|
|
13443
|
+
* handle from mount(). It intentionally does not hide the loader itself so
|
|
13444
|
+
* a stronger nested-MFE readiness signal can take ownership of the handoff.
|
|
13324
13445
|
*/
|
|
13325
|
-
|
|
13326
|
-
|
|
13327
|
-
|
|
13328
|
-
|
|
13329
|
-
|
|
13330
|
-
|
|
13331
|
-
|
|
13332
|
-
|
|
13333
|
-
|
|
13334
|
-
|
|
13446
|
+
waitForFirstBundlePaint(container) {
|
|
13447
|
+
return new Promise((resolve) => {
|
|
13448
|
+
let settled = false;
|
|
13449
|
+
let timeoutId;
|
|
13450
|
+
const observer = new MutationObserver(() => {
|
|
13451
|
+
if (container.children.length > 0) finish();
|
|
13452
|
+
});
|
|
13453
|
+
const finish = () => {
|
|
13454
|
+
if (settled) return;
|
|
13455
|
+
settled = true;
|
|
13335
13456
|
observer.disconnect();
|
|
13336
|
-
|
|
13337
|
-
|
|
13457
|
+
clearTimeout(timeoutId);
|
|
13458
|
+
requestAnimationFrame(() => resolve());
|
|
13459
|
+
};
|
|
13460
|
+
observer.observe(container, { childList: true });
|
|
13461
|
+
timeoutId = setTimeout(finish, 2e3);
|
|
13462
|
+
if (container.children.length > 0) finish();
|
|
13338
13463
|
});
|
|
13339
|
-
observer.observe(container, { childList: true });
|
|
13340
|
-
setTimeout(() => {
|
|
13341
|
-
observer.disconnect();
|
|
13342
|
-
remove();
|
|
13343
|
-
}, 2e3);
|
|
13344
13464
|
}
|
|
13345
13465
|
showError() {
|
|
13346
13466
|
this.hideLoader();
|
|
@@ -13418,7 +13538,8 @@ class BaseWidget extends HTMLElement {
|
|
|
13418
13538
|
}
|
|
13419
13539
|
removeBanner() {
|
|
13420
13540
|
var _a;
|
|
13421
|
-
if ((_a = this.bannerNode) == null ? void 0 : _a.parentNode)
|
|
13541
|
+
if ((_a = this.bannerNode) == null ? void 0 : _a.parentNode)
|
|
13542
|
+
this.bannerNode.parentNode.removeChild(this.bannerNode);
|
|
13422
13543
|
this.bannerNode = null;
|
|
13423
13544
|
}
|
|
13424
13545
|
/**
|
|
@@ -13431,7 +13552,8 @@ class BaseWidget extends HTMLElement {
|
|
|
13431
13552
|
var _a, _b;
|
|
13432
13553
|
try {
|
|
13433
13554
|
if (this.bannerNode) return;
|
|
13434
|
-
if (this.getAttribute("banner") === "off" || this.hasAttribute("no-banner"))
|
|
13555
|
+
if (this.getAttribute("banner") === "off" || this.hasAttribute("no-banner"))
|
|
13556
|
+
return;
|
|
13435
13557
|
const apiUrl = this.resolveBannerApiUrl();
|
|
13436
13558
|
const isCustom = this.config.widgetType === "custom";
|
|
13437
13559
|
let communityId;
|
|
@@ -13445,13 +13567,17 @@ class BaseWidget extends HTMLElement {
|
|
|
13445
13567
|
decoded = "";
|
|
13446
13568
|
}
|
|
13447
13569
|
if (isObjectId(decoded)) widgetId = decoded;
|
|
13448
|
-
else if (isObjectId(this.config.communityId))
|
|
13570
|
+
else if (isObjectId(this.config.communityId))
|
|
13571
|
+
widgetId = this.config.communityId;
|
|
13449
13572
|
if (!widgetId) return;
|
|
13450
13573
|
} else {
|
|
13451
13574
|
communityId = this.config.communityId;
|
|
13452
13575
|
}
|
|
13453
13576
|
const sessionKey = this.config.communityId || widgetId || "rai";
|
|
13454
|
-
const visitorId = getOrCreateVisitorId(
|
|
13577
|
+
const visitorId = getOrCreateVisitorId(
|
|
13578
|
+
sessionKey,
|
|
13579
|
+
this.config.storagePrefix
|
|
13580
|
+
);
|
|
13455
13581
|
const w = window.innerWidth;
|
|
13456
13582
|
const device = w < 640 ? "mobile" : w < 1024 ? "tablet" : "desktop";
|
|
13457
13583
|
const result = await fetchEligibleBanner(apiUrl, {
|
|
@@ -13467,13 +13593,18 @@ class BaseWidget extends HTMLElement {
|
|
|
13467
13593
|
hostname: window.location.hostname,
|
|
13468
13594
|
path: window.location.pathname
|
|
13469
13595
|
},
|
|
13470
|
-
viewport: {
|
|
13596
|
+
viewport: {
|
|
13597
|
+
width: window.innerWidth,
|
|
13598
|
+
height: window.innerHeight,
|
|
13599
|
+
device
|
|
13600
|
+
},
|
|
13471
13601
|
identifier: { type: "anonymous_session", value: visitorId }
|
|
13472
13602
|
});
|
|
13473
13603
|
if (!this.isConnected) return;
|
|
13474
13604
|
const banner = result.banner;
|
|
13475
13605
|
if (!banner) return;
|
|
13476
|
-
if (((_a = banner.placement) == null ? void 0 : _a.mobileBehavior) === "hide" && device === "mobile")
|
|
13606
|
+
if (((_a = banner.placement) == null ? void 0 : _a.mobileBehavior) === "hide" && device === "mobile")
|
|
13607
|
+
return;
|
|
13477
13608
|
const node = renderBanner(banner, {
|
|
13478
13609
|
onCtaClick: () => {
|
|
13479
13610
|
var _a2, _b2, _c;
|
|
@@ -13481,7 +13612,8 @@ class BaseWidget extends HTMLElement {
|
|
|
13481
13612
|
this.emit("rai-banner-click", { bannerId: banner.id });
|
|
13482
13613
|
const url = (_b2 = banner.cta) == null ? void 0 : _b2.url;
|
|
13483
13614
|
if (!url) return;
|
|
13484
|
-
if ((_c = banner.cta) == null ? void 0 : _c.openInNewTab)
|
|
13615
|
+
if ((_c = banner.cta) == null ? void 0 : _c.openInNewTab)
|
|
13616
|
+
window.open(url, "_blank", "noopener,noreferrer");
|
|
13485
13617
|
else window.location.href = url;
|
|
13486
13618
|
},
|
|
13487
13619
|
onDismiss: () => {
|
|
@@ -13527,7 +13659,7 @@ class BaseWidget extends HTMLElement {
|
|
|
13527
13659
|
this.addEventListener("rai-ready", mountBannerOnce);
|
|
13528
13660
|
bannerGateTimer = window.setTimeout(mountBannerOnce, 2500);
|
|
13529
13661
|
if (this.config.bundleUrl) {
|
|
13530
|
-
this.mountWidget();
|
|
13662
|
+
void this.mountWidget(initId);
|
|
13531
13663
|
} else {
|
|
13532
13664
|
this.createIframe();
|
|
13533
13665
|
}
|
|
@@ -13650,8 +13782,8 @@ class BaseWidget extends HTMLElement {
|
|
|
13650
13782
|
);
|
|
13651
13783
|
}
|
|
13652
13784
|
// ── Bundle mode (no-iframe) ──────────────────────────────────────────
|
|
13653
|
-
async mountWidget() {
|
|
13654
|
-
|
|
13785
|
+
async mountWidget(initId) {
|
|
13786
|
+
let container = null;
|
|
13655
13787
|
try {
|
|
13656
13788
|
this.teardownMountedWidget();
|
|
13657
13789
|
const bundleApiUrl = this.config.v2ApiUrl || resolveV2ApiUrl(this.config.domainKey);
|
|
@@ -13674,16 +13806,13 @@ class BaseWidget extends HTMLElement {
|
|
|
13674
13806
|
window.loadingAnimation = this.state.loadingAnimation;
|
|
13675
13807
|
}
|
|
13676
13808
|
const globalName = WIDGET_GLOBALS[this.config.widgetType];
|
|
13677
|
-
|
|
13678
|
-
|
|
13679
|
-
|
|
13680
|
-
|
|
13681
|
-
if (!(
|
|
13682
|
-
|
|
13683
|
-
|
|
13684
|
-
);
|
|
13685
|
-
}
|
|
13686
|
-
const container = document.createElement("div");
|
|
13809
|
+
const widgetGlobal = await getOrLoadBundleRuntime(
|
|
13810
|
+
globalName,
|
|
13811
|
+
this.config.bundleUrl
|
|
13812
|
+
);
|
|
13813
|
+
if (!this.isCurrentInit(initId)) return;
|
|
13814
|
+
container = document.createElement("div");
|
|
13815
|
+
const hideNestedBundleUntilReady = this.config.widgetType === "custom";
|
|
13687
13816
|
container.className = "rai-widget-root";
|
|
13688
13817
|
container.setAttribute("data-rai-widget-root", "true");
|
|
13689
13818
|
container.style.cssText = [
|
|
@@ -13691,16 +13820,21 @@ class BaseWidget extends HTMLElement {
|
|
|
13691
13820
|
"width: 100%",
|
|
13692
13821
|
"height: 100%",
|
|
13693
13822
|
"color: var(--text-1)",
|
|
13694
|
-
"background:
|
|
13695
|
-
"font-family: var(--rai-loader-font, 'Roboto', system-ui, -apple-system, sans-serif)"
|
|
13823
|
+
"background: transparent",
|
|
13824
|
+
"font-family: var(--rai-loader-font, 'Roboto', system-ui, -apple-system, sans-serif)",
|
|
13825
|
+
// Custom loaders may intentionally use a transparent backdrop. Keep
|
|
13826
|
+
// their nested bundle fallbacks out of the visual tree until deep
|
|
13827
|
+
// readiness so they cannot show through that transparency. Other
|
|
13828
|
+
// widget types preserve their existing first-paint behavior.
|
|
13829
|
+
`visibility: ${hideNestedBundleUntilReady ? "hidden" : "visible"}`
|
|
13696
13830
|
].join("; ");
|
|
13697
13831
|
this.appendChild(container);
|
|
13698
13832
|
if (!this.shadow.querySelector("slot")) {
|
|
13699
13833
|
const slot = document.createElement("slot");
|
|
13700
13834
|
this.shadow.appendChild(slot);
|
|
13701
13835
|
}
|
|
13702
|
-
this.
|
|
13703
|
-
widgetGlobal.mount(container, {
|
|
13836
|
+
const firstPaint = this.waitForFirstBundlePaint(container);
|
|
13837
|
+
const mountResult = widgetGlobal.mount(container, {
|
|
13704
13838
|
widgetType: this.config.widgetType,
|
|
13705
13839
|
communityId: this.config.communityId,
|
|
13706
13840
|
channelId: this.config.channelId,
|
|
@@ -13721,16 +13855,31 @@ class BaseWidget extends HTMLElement {
|
|
|
13721
13855
|
isOpenWidget: !this.state.accessToken,
|
|
13722
13856
|
defaultColorSchema: this.config.theme === "dark" ? "dark" : "light",
|
|
13723
13857
|
requestHostCallback: async (callbackName, payload) => {
|
|
13724
|
-
if (this.config.widgetType !== "store" && this.config.widgetType !== "custom"
|
|
13725
|
-
throw new Error(
|
|
13726
|
-
|
|
13727
|
-
|
|
13728
|
-
|
|
13729
|
-
return
|
|
13858
|
+
if (this.config.widgetType !== "store" && this.config.widgetType !== "custom") {
|
|
13859
|
+
throw new Error(
|
|
13860
|
+
"Host callback is only supported for store widgets"
|
|
13861
|
+
);
|
|
13862
|
+
}
|
|
13863
|
+
return invokeStoreHostCallback(
|
|
13864
|
+
this.readRuntimeCallbacks(),
|
|
13865
|
+
callbackName,
|
|
13866
|
+
payload
|
|
13867
|
+
);
|
|
13730
13868
|
}
|
|
13731
13869
|
});
|
|
13870
|
+
await waitForBundleMountReadiness(mountResult, firstPaint);
|
|
13871
|
+
if (!this.isCurrentInit(initId) || !container.isConnected) {
|
|
13872
|
+
container.remove();
|
|
13873
|
+
return;
|
|
13874
|
+
}
|
|
13875
|
+
if (hideNestedBundleUntilReady) container.style.visibility = "visible";
|
|
13876
|
+
this.hideLoader();
|
|
13732
13877
|
this.emit("rai-mounted");
|
|
13733
13878
|
} catch (err) {
|
|
13879
|
+
if (!this.isCurrentInit(initId)) {
|
|
13880
|
+
container == null ? void 0 : container.remove();
|
|
13881
|
+
return;
|
|
13882
|
+
}
|
|
13734
13883
|
console.error("[rai-widget] Bundle mount failed:", err);
|
|
13735
13884
|
this.showError();
|
|
13736
13885
|
}
|
|
@@ -13917,7 +14066,7 @@ class CustomWidget extends BaseWidget {
|
|
|
13917
14066
|
}
|
|
13918
14067
|
}
|
|
13919
14068
|
}
|
|
13920
|
-
console.log(`[rai-widget] v${"1.
|
|
14069
|
+
console.log(`[rai-widget] v${"1.7.1"}`);
|
|
13921
14070
|
class StoreWidgetCompat extends StoreWidget {
|
|
13922
14071
|
}
|
|
13923
14072
|
const WIDGET_REGISTRY = [
|
|
@@ -13981,7 +14130,7 @@ function exposePublicApi() {
|
|
|
13981
14130
|
})();
|
|
13982
14131
|
const widget = container == null ? void 0 : container.querySelector(ALL_WIDGET_SELECTOR);
|
|
13983
14132
|
window.ReturningAIWidget = {
|
|
13984
|
-
version: "1.
|
|
14133
|
+
version: "1.7.1",
|
|
13985
14134
|
reload: () => (widget == null ? void 0 : widget.reload()) ?? Promise.resolve(),
|
|
13986
14135
|
logout: () => (widget == null ? void 0 : widget.logoutPublic()) ?? Promise.resolve(),
|
|
13987
14136
|
isAuthenticated: () => (widget == null ? void 0 : widget.isAuthenticated()) ?? false,
|
|
@@ -14002,6 +14151,8 @@ export {
|
|
|
14002
14151
|
STORE_CALLBACK_FIELD_OPTIONS_CALLBACK_NAME,
|
|
14003
14152
|
STORE_CALLBACK_FIELD_OPTIONS_SCOPE,
|
|
14004
14153
|
STORE_CALLBACK_FIELD_OPTIONS_TIMEOUT_MS,
|
|
14154
|
+
STORE_PURCHASE_SUCCESS_CALLBACK_NAME,
|
|
14155
|
+
STORE_PURCHASE_SUCCESS_SCOPE,
|
|
14005
14156
|
SocialWidget,
|
|
14006
14157
|
StoreWidget
|
|
14007
14158
|
};
|