@returningai/widget-sdk 1.7.1 → 1.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -6,7 +6,7 @@ function getDefaultExportFromCjs(x) {
6
6
  return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, "default") ? x["default"] : x;
7
7
  }
8
8
  var lottie_light = { exports: {} };
9
- (function(module, exports$1) {
9
+ (function(module, exports) {
10
10
  typeof document !== "undefined" && typeof navigator !== "undefined" && function(global2, factory) {
11
11
  module.exports = factory();
12
12
  }(commonjsGlobal, function() {
@@ -4231,7 +4231,7 @@ var lottie_light = { exports: {} };
4231
4231
  }
4232
4232
  var readyStateCheckInterval = setInterval(checkReady, 100);
4233
4233
  try {
4234
- if (!((false ? "undefined" : _typeof(exports$1)) === "object" && true) && true) {
4234
+ if (!((false ? "undefined" : _typeof(exports)) === "object" && true) && true) {
4235
4235
  window.bodymovin = lottie2;
4236
4236
  }
4237
4237
  } catch (err) {
@@ -10351,7 +10351,7 @@ async function fetchEligibleBanner(apiUrl, request) {
10351
10351
  return { banner: null, reason: "network_error" };
10352
10352
  }
10353
10353
  }
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 */
10354
+ /*! @license DOMPurify 3.4.12 | (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.12/LICENSE */
10355
10355
  function _arrayLikeToArray(r, a) {
10356
10356
  (null == a || a > r.length) && (a = r.length);
10357
10357
  for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e];
@@ -10584,7 +10584,7 @@ const mathMl$1 = freeze(["math", "menclose", "merror", "mfenced", "mfrac", "mgly
10584
10584
  const mathMlDisallowed = freeze(["maction", "maligngroup", "malignmark", "mlongdiv", "mscarries", "mscarry", "msgroup", "mstack", "msline", "msrow", "semantics", "annotation", "annotation-xml", "mprescripts", "none"]);
10585
10585
  const text = freeze(["#text"]);
10586
10586
  const html = freeze(["accept", "action", "align", "alt", "autocapitalize", "autocomplete", "autopictureinpicture", "autoplay", "background", "bgcolor", "border", "capture", "cellpadding", "cellspacing", "checked", "cite", "class", "clear", "color", "cols", "colspan", "command", "commandfor", "controls", "controlslist", "coords", "crossorigin", "datetime", "decoding", "default", "dir", "disabled", "disablepictureinpicture", "disableremoteplayback", "download", "draggable", "enctype", "enterkeyhint", "exportparts", "face", "for", "headers", "height", "hidden", "high", "href", "hreflang", "id", "inert", "inputmode", "integrity", "ismap", "kind", "label", "lang", "list", "loading", "loop", "low", "max", "maxlength", "media", "method", "min", "minlength", "multiple", "muted", "name", "nonce", "noshade", "novalidate", "nowrap", "open", "optimum", "part", "pattern", "placeholder", "playsinline", "popover", "popovertarget", "popovertargetaction", "poster", "preload", "pubdate", "radiogroup", "readonly", "rel", "required", "rev", "reversed", "role", "rows", "rowspan", "spellcheck", "scope", "selected", "shape", "size", "sizes", "slot", "span", "srclang", "start", "src", "srcset", "step", "style", "summary", "tabindex", "title", "translate", "type", "usemap", "valign", "value", "width", "wrap", "xmlns"]);
10587
- const svg = freeze(["accent-height", "accumulate", "additive", "alignment-baseline", "amplitude", "ascent", "attributename", "attributetype", "azimuth", "basefrequency", "baseline-shift", "begin", "bias", "by", "class", "clip", "clippathunits", "clip-path", "clip-rule", "color", "color-interpolation", "color-interpolation-filters", "color-profile", "color-rendering", "cx", "cy", "d", "dx", "dy", "diffuseconstant", "direction", "display", "divisor", "dur", "edgemode", "elevation", "end", "exponent", "fill", "fill-opacity", "fill-rule", "filter", "filterunits", "flood-color", "flood-opacity", "font-family", "font-size", "font-size-adjust", "font-stretch", "font-style", "font-variant", "font-weight", "fx", "fy", "g1", "g2", "glyph-name", "glyphref", "gradientunits", "gradienttransform", "height", "href", "id", "image-rendering", "in", "in2", "intercept", "k", "k1", "k2", "k3", "k4", "kerning", "keypoints", "keysplines", "keytimes", "lang", "lengthadjust", "letter-spacing", "kernelmatrix", "kernelunitlength", "lighting-color", "local", "marker-end", "marker-mid", "marker-start", "markerheight", "markerunits", "markerwidth", "maskcontentunits", "maskunits", "max", "mask", "mask-type", "media", "method", "mode", "min", "name", "numoctaves", "offset", "operator", "opacity", "order", "orient", "orientation", "origin", "overflow", "paint-order", "path", "pathlength", "patterncontentunits", "patterntransform", "patternunits", "points", "preservealpha", "preserveaspectratio", "primitiveunits", "r", "rx", "ry", "radius", "refx", "refy", "repeatcount", "repeatdur", "restart", "result", "rotate", "scale", "seed", "shape-rendering", "slope", "specularconstant", "specularexponent", "spreadmethod", "startoffset", "stddeviation", "stitchtiles", "stop-color", "stop-opacity", "stroke-dasharray", "stroke-dashoffset", "stroke-linecap", "stroke-linejoin", "stroke-miterlimit", "stroke-opacity", "stroke", "stroke-width", "style", "surfacescale", "systemlanguage", "tabindex", "tablevalues", "targetx", "targety", "transform", "transform-origin", "text-anchor", "text-decoration", "text-rendering", "textlength", "type", "u1", "u2", "unicode", "values", "viewbox", "visibility", "version", "vert-adv-y", "vert-origin-x", "vert-origin-y", "width", "word-spacing", "wrap", "writing-mode", "xchannelselector", "ychannelselector", "x", "x1", "x2", "xmlns", "y", "y1", "y2", "z", "zoomandpan"]);
10587
+ const svg = freeze(["accent-height", "accumulate", "additive", "alignment-baseline", "amplitude", "ascent", "attributename", "attributetype", "azimuth", "basefrequency", "baseline-shift", "begin", "bias", "by", "class", "clip", "clippathunits", "clip-path", "clip-rule", "color", "color-interpolation", "color-interpolation-filters", "color-profile", "color-rendering", "cx", "cy", "d", "dx", "dy", "diffuseconstant", "direction", "display", "divisor", "dominant-baseline", "dur", "edgemode", "elevation", "end", "exponent", "fill", "fill-opacity", "fill-rule", "filter", "filterunits", "flood-color", "flood-opacity", "font-family", "font-size", "font-size-adjust", "font-stretch", "font-style", "font-variant", "font-weight", "fx", "fy", "g1", "g2", "glyph-name", "glyphref", "gradientunits", "gradienttransform", "height", "href", "id", "image-rendering", "in", "in2", "intercept", "k", "k1", "k2", "k3", "k4", "kerning", "keypoints", "keysplines", "keytimes", "lang", "lengthadjust", "letter-spacing", "kernelmatrix", "kernelunitlength", "lighting-color", "local", "marker-end", "marker-mid", "marker-start", "markerheight", "markerunits", "markerwidth", "maskcontentunits", "maskunits", "max", "mask", "mask-type", "media", "method", "mode", "min", "name", "numoctaves", "offset", "operator", "opacity", "order", "orient", "orientation", "origin", "overflow", "paint-order", "path", "pathlength", "patterncontentunits", "patterntransform", "patternunits", "points", "preservealpha", "preserveaspectratio", "primitiveunits", "r", "rx", "ry", "radius", "refx", "refy", "repeatcount", "repeatdur", "restart", "result", "rotate", "scale", "seed", "shape-rendering", "slope", "specularconstant", "specularexponent", "spreadmethod", "startoffset", "stddeviation", "stitchtiles", "stop-color", "stop-opacity", "stroke-dasharray", "stroke-dashoffset", "stroke-linecap", "stroke-linejoin", "stroke-miterlimit", "stroke-opacity", "stroke", "stroke-width", "style", "surfacescale", "systemlanguage", "tabindex", "tablevalues", "targetx", "targety", "transform", "transform-origin", "text-anchor", "text-decoration", "text-orientation", "text-rendering", "textlength", "type", "u1", "u2", "unicode", "values", "viewbox", "visibility", "version", "vert-adv-y", "vert-origin-x", "vert-origin-y", "width", "word-spacing", "wrap", "writing-mode", "xchannelselector", "ychannelselector", "x", "x1", "x2", "xmlns", "y", "y1", "y2", "z", "zoomandpan"]);
10588
10588
  const mathMl = freeze(["accent", "accentunder", "align", "bevelled", "close", "columnalign", "columnlines", "columnspacing", "columnspan", "denomalign", "depth", "dir", "display", "displaystyle", "encoding", "fence", "frame", "height", "href", "id", "largeop", "length", "linethickness", "lquote", "lspace", "mathbackground", "mathcolor", "mathsize", "mathvariant", "maxsize", "minsize", "movablelimits", "notation", "numalign", "open", "rowalign", "rowlines", "rowspacing", "rowspan", "rspace", "rquote", "scriptlevel", "scriptminsize", "scriptsizemultiplier", "selection", "separator", "separators", "stretchy", "subscriptshift", "supscriptshift", "symmetric", "voffset", "width", "xmlns"]);
10589
10589
  const xml = freeze(["xlink:href", "xml:id", "xlink:title", "xml:space", "xmlns:xlink"]);
10590
10590
  const MUSTACHE_EXPR = seal(/{{[\w\W]*|^[\w\W]*}}/g);
@@ -10603,6 +10603,10 @@ const ATTR_WHITESPACE = seal(
10603
10603
  );
10604
10604
  const DOCTYPE_NAME = seal(/^html$/i);
10605
10605
  const CUSTOM_ELEMENT = seal(/^[a-z][.\w]*(-[.\w]+)+$/i);
10606
+ const ELEMENT_MARKUP_PROBE = seal(/<[/\w!]/g);
10607
+ const COMMENT_MARKUP_PROBE = seal(/<[/\w]/g);
10608
+ const FALLBACK_TAG_CLOSE = seal(/<\/no(script|embed|frames)/i);
10609
+ const SELF_CLOSING_TAG = seal(/\/>/i);
10606
10610
  const NODE_TYPE = {
10607
10611
  element: 1,
10608
10612
  attribute: 2,
@@ -10612,7 +10616,7 @@ const NODE_TYPE = {
10612
10616
  // Deprecated
10613
10617
  entityNode: 6,
10614
10618
  // Deprecated
10615
- progressingInstruction: 7,
10619
+ processingInstruction: 7,
10616
10620
  comment: 8,
10617
10621
  document: 9,
10618
10622
  documentType: 10,
@@ -10660,10 +10664,13 @@ const _createHooksMap = function _createHooksMap2() {
10660
10664
  uponSanitizeShadowNode: []
10661
10665
  };
10662
10666
  };
10667
+ const _resolveSetOption = function _resolveSetOption2(cfg, key, fallback, options) {
10668
+ return objectHasOwnProperty(cfg, key) && arrayIsArray(cfg[key]) ? addToSet(options.base ? clone(options.base) : {}, cfg[key], options.transform) : fallback;
10669
+ };
10663
10670
  function createDOMPurify() {
10664
10671
  let window2 = arguments.length > 0 && arguments[0] !== void 0 ? arguments[0] : getGlobal();
10665
10672
  const DOMPurify = (root) => createDOMPurify(root);
10666
- DOMPurify.version = "3.4.9";
10673
+ DOMPurify.version = "3.4.12";
10667
10674
  DOMPurify.removed = [];
10668
10675
  if (!window2 || !window2.document || window2.document.nodeType !== NODE_TYPE.document || !window2.Element) {
10669
10676
  DOMPurify.isSupported = false;
@@ -10782,6 +10789,8 @@ function createDOMPurify() {
10782
10789
  let SAFE_FOR_XML = true;
10783
10790
  let WHOLE_DOCUMENT = false;
10784
10791
  let SET_CONFIG = false;
10792
+ let SET_CONFIG_ALLOWED_TAGS = null;
10793
+ let SET_CONFIG_ALLOWED_ATTR = null;
10785
10794
  let FORCE_BODY = false;
10786
10795
  let RETURN_DOM = false;
10787
10796
  let RETURN_DOM_FRAGMENT = false;
@@ -10841,8 +10850,10 @@ function createDOMPurify() {
10841
10850
  let IS_EMPTY_INPUT = false;
10842
10851
  let ALLOWED_NAMESPACES = null;
10843
10852
  const DEFAULT_ALLOWED_NAMESPACES = addToSet({}, [MATHML_NAMESPACE, SVG_NAMESPACE, HTML_NAMESPACE], stringToString);
10844
- let MATHML_TEXT_INTEGRATION_POINTS = addToSet({}, ["mi", "mo", "mn", "ms", "mtext"]);
10845
- let HTML_INTEGRATION_POINTS = addToSet({}, ["annotation-xml"]);
10853
+ const DEFAULT_MATHML_TEXT_INTEGRATION_POINTS = freeze(["mi", "mo", "mn", "ms", "mtext"]);
10854
+ let MATHML_TEXT_INTEGRATION_POINTS = addToSet({}, DEFAULT_MATHML_TEXT_INTEGRATION_POINTS);
10855
+ const DEFAULT_HTML_INTEGRATION_POINTS = freeze(["annotation-xml"]);
10856
+ let HTML_INTEGRATION_POINTS = addToSet({}, DEFAULT_HTML_INTEGRATION_POINTS);
10846
10857
  const COMMON_SVG_AND_HTML_ELEMENTS = addToSet({}, ["title", "style", "font", "a", "script"]);
10847
10858
  let PARSER_MEDIA_TYPE = null;
10848
10859
  const SUPPORTED_PARSER_MEDIA_TYPES = ["application/xhtml+xml", "text/html"];
@@ -10865,14 +10876,32 @@ function createDOMPurify() {
10865
10876
  PARSER_MEDIA_TYPE = // eslint-disable-next-line unicorn/prefer-includes
10866
10877
  SUPPORTED_PARSER_MEDIA_TYPES.indexOf(cfg.PARSER_MEDIA_TYPE) === -1 ? DEFAULT_PARSER_MEDIA_TYPE : cfg.PARSER_MEDIA_TYPE;
10867
10878
  transformCaseFunc = PARSER_MEDIA_TYPE === "application/xhtml+xml" ? stringToString : stringToLowerCase;
10868
- ALLOWED_TAGS = objectHasOwnProperty(cfg, "ALLOWED_TAGS") && arrayIsArray(cfg.ALLOWED_TAGS) ? addToSet({}, cfg.ALLOWED_TAGS, transformCaseFunc) : DEFAULT_ALLOWED_TAGS;
10869
- ALLOWED_ATTR = objectHasOwnProperty(cfg, "ALLOWED_ATTR") && arrayIsArray(cfg.ALLOWED_ATTR) ? addToSet({}, cfg.ALLOWED_ATTR, transformCaseFunc) : DEFAULT_ALLOWED_ATTR;
10870
- ALLOWED_NAMESPACES = objectHasOwnProperty(cfg, "ALLOWED_NAMESPACES") && arrayIsArray(cfg.ALLOWED_NAMESPACES) ? addToSet({}, cfg.ALLOWED_NAMESPACES, stringToString) : DEFAULT_ALLOWED_NAMESPACES;
10871
- URI_SAFE_ATTRIBUTES = objectHasOwnProperty(cfg, "ADD_URI_SAFE_ATTR") && arrayIsArray(cfg.ADD_URI_SAFE_ATTR) ? addToSet(clone(DEFAULT_URI_SAFE_ATTRIBUTES), cfg.ADD_URI_SAFE_ATTR, transformCaseFunc) : DEFAULT_URI_SAFE_ATTRIBUTES;
10872
- DATA_URI_TAGS = objectHasOwnProperty(cfg, "ADD_DATA_URI_TAGS") && arrayIsArray(cfg.ADD_DATA_URI_TAGS) ? addToSet(clone(DEFAULT_DATA_URI_TAGS), cfg.ADD_DATA_URI_TAGS, transformCaseFunc) : DEFAULT_DATA_URI_TAGS;
10873
- FORBID_CONTENTS = objectHasOwnProperty(cfg, "FORBID_CONTENTS") && arrayIsArray(cfg.FORBID_CONTENTS) ? addToSet({}, cfg.FORBID_CONTENTS, transformCaseFunc) : DEFAULT_FORBID_CONTENTS;
10874
- FORBID_TAGS = objectHasOwnProperty(cfg, "FORBID_TAGS") && arrayIsArray(cfg.FORBID_TAGS) ? addToSet({}, cfg.FORBID_TAGS, transformCaseFunc) : clone({});
10875
- FORBID_ATTR = objectHasOwnProperty(cfg, "FORBID_ATTR") && arrayIsArray(cfg.FORBID_ATTR) ? addToSet({}, cfg.FORBID_ATTR, transformCaseFunc) : clone({});
10879
+ ALLOWED_TAGS = _resolveSetOption(cfg, "ALLOWED_TAGS", DEFAULT_ALLOWED_TAGS, {
10880
+ transform: transformCaseFunc
10881
+ });
10882
+ ALLOWED_ATTR = _resolveSetOption(cfg, "ALLOWED_ATTR", DEFAULT_ALLOWED_ATTR, {
10883
+ transform: transformCaseFunc
10884
+ });
10885
+ ALLOWED_NAMESPACES = _resolveSetOption(cfg, "ALLOWED_NAMESPACES", DEFAULT_ALLOWED_NAMESPACES, {
10886
+ transform: stringToString
10887
+ });
10888
+ URI_SAFE_ATTRIBUTES = _resolveSetOption(cfg, "ADD_URI_SAFE_ATTR", DEFAULT_URI_SAFE_ATTRIBUTES, {
10889
+ transform: transformCaseFunc,
10890
+ base: DEFAULT_URI_SAFE_ATTRIBUTES
10891
+ });
10892
+ DATA_URI_TAGS = _resolveSetOption(cfg, "ADD_DATA_URI_TAGS", DEFAULT_DATA_URI_TAGS, {
10893
+ transform: transformCaseFunc,
10894
+ base: DEFAULT_DATA_URI_TAGS
10895
+ });
10896
+ FORBID_CONTENTS = _resolveSetOption(cfg, "FORBID_CONTENTS", DEFAULT_FORBID_CONTENTS, {
10897
+ transform: transformCaseFunc
10898
+ });
10899
+ FORBID_TAGS = _resolveSetOption(cfg, "FORBID_TAGS", clone({}), {
10900
+ transform: transformCaseFunc
10901
+ });
10902
+ FORBID_ATTR = _resolveSetOption(cfg, "FORBID_ATTR", clone({}), {
10903
+ transform: transformCaseFunc
10904
+ });
10876
10905
  USE_PROFILES = objectHasOwnProperty(cfg, "USE_PROFILES") ? cfg.USE_PROFILES && typeof cfg.USE_PROFILES === "object" ? clone(cfg.USE_PROFILES) : cfg.USE_PROFILES : false;
10877
10906
  ALLOW_ARIA_ATTR = cfg.ALLOW_ARIA_ATTR !== false;
10878
10907
  ALLOW_DATA_ATTR = cfg.ALLOW_DATA_ATTR !== false;
@@ -10891,8 +10920,8 @@ function createDOMPurify() {
10891
10920
  IN_PLACE = cfg.IN_PLACE || false;
10892
10921
  IS_ALLOWED_URI$1 = isRegex(cfg.ALLOWED_URI_REGEXP) ? cfg.ALLOWED_URI_REGEXP : IS_ALLOWED_URI;
10893
10922
  NAMESPACE = typeof cfg.NAMESPACE === "string" ? cfg.NAMESPACE : HTML_NAMESPACE;
10894
- MATHML_TEXT_INTEGRATION_POINTS = objectHasOwnProperty(cfg, "MATHML_TEXT_INTEGRATION_POINTS") && cfg.MATHML_TEXT_INTEGRATION_POINTS && typeof cfg.MATHML_TEXT_INTEGRATION_POINTS === "object" ? clone(cfg.MATHML_TEXT_INTEGRATION_POINTS) : addToSet({}, ["mi", "mo", "mn", "ms", "mtext"]);
10895
- HTML_INTEGRATION_POINTS = objectHasOwnProperty(cfg, "HTML_INTEGRATION_POINTS") && cfg.HTML_INTEGRATION_POINTS && typeof cfg.HTML_INTEGRATION_POINTS === "object" ? clone(cfg.HTML_INTEGRATION_POINTS) : addToSet({}, ["annotation-xml"]);
10923
+ MATHML_TEXT_INTEGRATION_POINTS = objectHasOwnProperty(cfg, "MATHML_TEXT_INTEGRATION_POINTS") && cfg.MATHML_TEXT_INTEGRATION_POINTS && typeof cfg.MATHML_TEXT_INTEGRATION_POINTS === "object" ? clone(cfg.MATHML_TEXT_INTEGRATION_POINTS) : addToSet({}, DEFAULT_MATHML_TEXT_INTEGRATION_POINTS);
10924
+ HTML_INTEGRATION_POINTS = objectHasOwnProperty(cfg, "HTML_INTEGRATION_POINTS") && cfg.HTML_INTEGRATION_POINTS && typeof cfg.HTML_INTEGRATION_POINTS === "object" ? clone(cfg.HTML_INTEGRATION_POINTS) : addToSet({}, DEFAULT_HTML_INTEGRATION_POINTS);
10896
10925
  const customElementHandling = objectHasOwnProperty(cfg, "CUSTOM_ELEMENT_HANDLING") && cfg.CUSTOM_ELEMENT_HANDLING && typeof cfg.CUSTOM_ELEMENT_HANDLING === "object" ? clone(cfg.CUSTOM_ELEMENT_HANDLING) : create(null);
10897
10926
  CUSTOM_ELEMENT_HANDLING = create(null);
10898
10927
  if (objectHasOwnProperty(customElementHandling, "tagNameCheck") && isRegexOrFunction(customElementHandling.tagNameCheck)) {
@@ -10904,6 +10933,7 @@ function createDOMPurify() {
10904
10933
  if (objectHasOwnProperty(customElementHandling, "allowCustomizedBuiltInElements") && typeof customElementHandling.allowCustomizedBuiltInElements === "boolean") {
10905
10934
  CUSTOM_ELEMENT_HANDLING.allowCustomizedBuiltInElements = customElementHandling.allowCustomizedBuiltInElements;
10906
10935
  }
10936
+ seal(CUSTOM_ELEMENT_HANDLING);
10907
10937
  if (SAFE_FOR_TEMPLATES) {
10908
10938
  ALLOW_DATA_ATTR = false;
10909
10939
  }
@@ -11006,12 +11036,6 @@ function createDOMPurify() {
11006
11036
  emptyHTML = _createTrustedHTML("");
11007
11037
  }
11008
11038
  }
11009
- if ((hooks.uponSanitizeElement.length > 0 || hooks.uponSanitizeAttribute.length > 0) && ALLOWED_TAGS === DEFAULT_ALLOWED_TAGS) {
11010
- ALLOWED_TAGS = clone(ALLOWED_TAGS);
11011
- }
11012
- if (hooks.uponSanitizeAttribute.length > 0 && ALLOWED_ATTR === DEFAULT_ALLOWED_ATTR) {
11013
- ALLOWED_ATTR = clone(ALLOWED_ATTR);
11014
- }
11015
11039
  if (freeze) {
11016
11040
  freeze(cfg);
11017
11041
  }
@@ -11019,6 +11043,33 @@ function createDOMPurify() {
11019
11043
  };
11020
11044
  const ALL_SVG_TAGS = addToSet({}, [...svg$1, ...svgFilters, ...svgDisallowed]);
11021
11045
  const ALL_MATHML_TAGS = addToSet({}, [...mathMl$1, ...mathMlDisallowed]);
11046
+ const _checkSvgNamespace = function _checkSvgNamespace2(tagName, parent, parentTagName) {
11047
+ if (parent.namespaceURI === HTML_NAMESPACE) {
11048
+ return tagName === "svg";
11049
+ }
11050
+ if (parent.namespaceURI === MATHML_NAMESPACE) {
11051
+ return tagName === "svg" && (parentTagName === "annotation-xml" || MATHML_TEXT_INTEGRATION_POINTS[parentTagName]);
11052
+ }
11053
+ return Boolean(ALL_SVG_TAGS[tagName]);
11054
+ };
11055
+ const _checkMathMlNamespace = function _checkMathMlNamespace2(tagName, parent, parentTagName) {
11056
+ if (parent.namespaceURI === HTML_NAMESPACE) {
11057
+ return tagName === "math";
11058
+ }
11059
+ if (parent.namespaceURI === SVG_NAMESPACE) {
11060
+ return tagName === "math" && HTML_INTEGRATION_POINTS[parentTagName];
11061
+ }
11062
+ return Boolean(ALL_MATHML_TAGS[tagName]);
11063
+ };
11064
+ const _checkHtmlNamespace = function _checkHtmlNamespace2(tagName, parent, parentTagName) {
11065
+ if (parent.namespaceURI === SVG_NAMESPACE && !HTML_INTEGRATION_POINTS[parentTagName]) {
11066
+ return false;
11067
+ }
11068
+ if (parent.namespaceURI === MATHML_NAMESPACE && !MATHML_TEXT_INTEGRATION_POINTS[parentTagName]) {
11069
+ return false;
11070
+ }
11071
+ return !ALL_MATHML_TAGS[tagName] && (COMMON_SVG_AND_HTML_ELEMENTS[tagName] || !ALL_SVG_TAGS[tagName]);
11072
+ };
11022
11073
  const _checkValidNamespace = function _checkValidNamespace2(element) {
11023
11074
  let parent = getParentNode(element);
11024
11075
  if (!parent || !parent.tagName) {
@@ -11033,31 +11084,13 @@ function createDOMPurify() {
11033
11084
  return false;
11034
11085
  }
11035
11086
  if (element.namespaceURI === SVG_NAMESPACE) {
11036
- if (parent.namespaceURI === HTML_NAMESPACE) {
11037
- return tagName === "svg";
11038
- }
11039
- if (parent.namespaceURI === MATHML_NAMESPACE) {
11040
- return tagName === "svg" && (parentTagName === "annotation-xml" || MATHML_TEXT_INTEGRATION_POINTS[parentTagName]);
11041
- }
11042
- return Boolean(ALL_SVG_TAGS[tagName]);
11087
+ return _checkSvgNamespace(tagName, parent, parentTagName);
11043
11088
  }
11044
11089
  if (element.namespaceURI === MATHML_NAMESPACE) {
11045
- if (parent.namespaceURI === HTML_NAMESPACE) {
11046
- return tagName === "math";
11047
- }
11048
- if (parent.namespaceURI === SVG_NAMESPACE) {
11049
- return tagName === "math" && HTML_INTEGRATION_POINTS[parentTagName];
11050
- }
11051
- return Boolean(ALL_MATHML_TAGS[tagName]);
11090
+ return _checkMathMlNamespace(tagName, parent, parentTagName);
11052
11091
  }
11053
11092
  if (element.namespaceURI === HTML_NAMESPACE) {
11054
- if (parent.namespaceURI === SVG_NAMESPACE && !HTML_INTEGRATION_POINTS[parentTagName]) {
11055
- return false;
11056
- }
11057
- if (parent.namespaceURI === MATHML_NAMESPACE && !MATHML_TEXT_INTEGRATION_POINTS[parentTagName]) {
11058
- return false;
11059
- }
11060
- return !ALL_MATHML_TAGS[tagName] && (COMMON_SVG_AND_HTML_ELEMENTS[tagName] || !ALL_SVG_TAGS[tagName]);
11093
+ return _checkHtmlNamespace(tagName, parent, parentTagName);
11061
11094
  }
11062
11095
  if (PARSER_MEDIA_TYPE === "application/xhtml+xml" && ALLOWED_NAMESPACES[element.namespaceURI]) {
11063
11096
  return true;
@@ -11078,7 +11111,8 @@ function createDOMPurify() {
11078
11111
  }
11079
11112
  };
11080
11113
  const _neutralizeRoot = function _neutralizeRoot2(root) {
11081
- const childNodes = getChildNodes ? getChildNodes(root) : root.childNodes;
11114
+ _neutralizeSubtree(root);
11115
+ const childNodes = getChildNodes(root);
11082
11116
  if (childNodes) {
11083
11117
  const snapshot = [];
11084
11118
  arrayForEach(childNodes, (child) => {
@@ -11091,7 +11125,7 @@ function createDOMPurify() {
11091
11125
  }
11092
11126
  });
11093
11127
  }
11094
- const attributes = getAttributes ? getAttributes(root) : null;
11128
+ const attributes = getAttributes(root);
11095
11129
  if (attributes) {
11096
11130
  for (let i = attributes.length - 1; i >= 0; --i) {
11097
11131
  const attribute = attributes[i];
@@ -11133,7 +11167,7 @@ function createDOMPurify() {
11133
11167
  }
11134
11168
  };
11135
11169
  const _stripDisallowedAttributes = function _stripDisallowedAttributes2(element) {
11136
- const attributes = getAttributes ? getAttributes(element) : element.attributes;
11170
+ const attributes = getAttributes(element);
11137
11171
  if (!attributes) {
11138
11172
  return;
11139
11173
  }
@@ -11157,7 +11191,43 @@ function createDOMPurify() {
11157
11191
  if (nodeType === NODE_TYPE.element) {
11158
11192
  _stripDisallowedAttributes(node);
11159
11193
  }
11160
- const childNodes = getChildNodes ? getChildNodes(node) : node.childNodes;
11194
+ const childNodes = getChildNodes(node);
11195
+ if (childNodes) {
11196
+ for (let i = childNodes.length - 1; i >= 0; --i) {
11197
+ stack.push(childNodes[i]);
11198
+ }
11199
+ }
11200
+ }
11201
+ };
11202
+ const _neutralizePatchLinkage = function _neutralizePatchLinkage2(root) {
11203
+ if (!SAFE_FOR_XML) {
11204
+ return;
11205
+ }
11206
+ const stack = [root];
11207
+ while (stack.length > 0) {
11208
+ const node = stack.pop();
11209
+ const nodeType = getNodeType ? getNodeType(node) : node.nodeType;
11210
+ if (nodeType === NODE_TYPE.processingInstruction || nodeType === NODE_TYPE.comment && regExpTest(COMMENT_MARKUP_PROBE, node.data)) {
11211
+ try {
11212
+ remove(node);
11213
+ } catch (_) {
11214
+ }
11215
+ continue;
11216
+ }
11217
+ if (nodeType === NODE_TYPE.element) {
11218
+ const element = node;
11219
+ const lcTag = transformCaseFunc(getNodeName ? getNodeName(node) : node.nodeName);
11220
+ try {
11221
+ if (element.hasAttribute && element.hasAttribute("patchsrc")) {
11222
+ element.removeAttribute("patchsrc");
11223
+ }
11224
+ if (element.hasAttribute && element.hasAttribute("for") && lcTag !== "label" && lcTag !== "output") {
11225
+ element.removeAttribute("for");
11226
+ }
11227
+ } catch (_) {
11228
+ }
11229
+ }
11230
+ const childNodes = getChildNodes(node);
11161
11231
  if (childNodes) {
11162
11232
  for (let i = childNodes.length - 1; i >= 0; --i) {
11163
11233
  stack.push(childNodes[i]);
@@ -11209,8 +11279,14 @@ function createDOMPurify() {
11209
11279
  null
11210
11280
  );
11211
11281
  };
11282
+ const _stripTemplateExpressions = function _stripTemplateExpressions2(value) {
11283
+ value = stringReplace(value, MUSTACHE_EXPR$1, " ");
11284
+ value = stringReplace(value, ERB_EXPR$1, " ");
11285
+ value = stringReplace(value, TMPLIT_EXPR$1, " ");
11286
+ return value;
11287
+ };
11212
11288
  const _scrubTemplateExpressions2 = function _scrubTemplateExpressions(node) {
11213
- var _node$querySelectorAl, _node$querySelectorAl2;
11289
+ var _node$querySelectorAl;
11214
11290
  node.normalize();
11215
11291
  const walker = createNodeIterator.call(
11216
11292
  node.ownerDocument || node,
@@ -11221,19 +11297,17 @@ function createDOMPurify() {
11221
11297
  );
11222
11298
  let currentNode = walker.nextNode();
11223
11299
  while (currentNode) {
11224
- let data = currentNode.data;
11225
- arrayForEach([MUSTACHE_EXPR$1, ERB_EXPR$1, TMPLIT_EXPR$1], (expr) => {
11226
- data = stringReplace(data, expr, " ");
11227
- });
11228
- currentNode.data = data;
11300
+ currentNode.data = _stripTemplateExpressions(currentNode.data);
11229
11301
  currentNode = walker.nextNode();
11230
11302
  }
11231
- const templates = (_node$querySelectorAl = (_node$querySelectorAl2 = node.querySelectorAll) === null || _node$querySelectorAl2 === void 0 ? void 0 : _node$querySelectorAl2.call(node, "template")) !== null && _node$querySelectorAl !== void 0 ? _node$querySelectorAl : [];
11232
- arrayForEach(Array.from(templates), (tmpl) => {
11233
- if (_isDocumentFragment(tmpl.content)) {
11234
- _scrubTemplateExpressions2(tmpl.content);
11235
- }
11236
- });
11303
+ const templates = (_node$querySelectorAl = node.querySelectorAll) === null || _node$querySelectorAl === void 0 ? void 0 : _node$querySelectorAl.call(node, "template");
11304
+ if (templates) {
11305
+ arrayForEach(templates, (tmpl) => {
11306
+ if (_isDocumentFragment(tmpl.content)) {
11307
+ _scrubTemplateExpressions2(tmpl.content);
11308
+ }
11309
+ });
11310
+ }
11237
11311
  };
11238
11312
  const _isClobbered = function _isClobbered2(element) {
11239
11313
  const realTagName = getNodeName ? getNodeName(element) : null;
@@ -11289,13 +11363,56 @@ function createDOMPurify() {
11289
11363
  }
11290
11364
  };
11291
11365
  function _executeHooks(hooks2, currentNode, data) {
11366
+ if (hooks2.length === 0) {
11367
+ return;
11368
+ }
11292
11369
  arrayForEach(hooks2, (hook) => {
11293
11370
  hook.call(DOMPurify, currentNode, data, CONFIG);
11294
11371
  });
11295
11372
  }
11296
- const _sanitizeElements = function _sanitizeElements2(currentNode) {
11297
- let content = null;
11373
+ const _isUnsafeNode = function _isUnsafeNode2(currentNode, tagName) {
11374
+ if (SAFE_FOR_XML && currentNode.hasChildNodes() && !_isNode(currentNode.firstElementChild) && regExpTest(ELEMENT_MARKUP_PROBE, currentNode.textContent) && regExpTest(ELEMENT_MARKUP_PROBE, currentNode.innerHTML)) {
11375
+ return true;
11376
+ }
11377
+ if (SAFE_FOR_XML && currentNode.namespaceURI === HTML_NAMESPACE && tagName === "style" && _isNode(currentNode.firstElementChild)) {
11378
+ return true;
11379
+ }
11380
+ if (currentNode.nodeType === NODE_TYPE.processingInstruction) {
11381
+ return true;
11382
+ }
11383
+ if (SAFE_FOR_XML && currentNode.nodeType === NODE_TYPE.comment && regExpTest(COMMENT_MARKUP_PROBE, currentNode.data)) {
11384
+ return true;
11385
+ }
11386
+ return false;
11387
+ };
11388
+ const _sanitizeDisallowedNode = function _sanitizeDisallowedNode2(currentNode, tagName) {
11389
+ if (!FORBID_TAGS[tagName] && _isBasicCustomElement(tagName)) {
11390
+ if (CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof RegExp && regExpTest(CUSTOM_ELEMENT_HANDLING.tagNameCheck, tagName)) {
11391
+ return false;
11392
+ }
11393
+ if (CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof Function && CUSTOM_ELEMENT_HANDLING.tagNameCheck(tagName)) {
11394
+ return false;
11395
+ }
11396
+ }
11397
+ if (KEEP_CONTENT && !FORBID_CONTENTS[tagName]) {
11398
+ const parentNode = getParentNode(currentNode);
11399
+ const childNodes = getChildNodes(currentNode);
11400
+ if (childNodes && parentNode) {
11401
+ const childCount = childNodes.length;
11402
+ for (let i = childCount - 1; i >= 0; --i) {
11403
+ const hoisted = IN_PLACE ? childNodes[i] : cloneNode(childNodes[i], true);
11404
+ parentNode.insertBefore(hoisted, getNextSibling(currentNode));
11405
+ }
11406
+ }
11407
+ }
11408
+ _forceRemove(currentNode);
11409
+ return true;
11410
+ };
11411
+ const _sanitizeElements = function _sanitizeElements2(currentNode, root) {
11298
11412
  _executeHooks(hooks.beforeSanitizeElements, currentNode, null);
11413
+ if (currentNode !== root && getParentNode(currentNode) === null) {
11414
+ return true;
11415
+ }
11299
11416
  if (_isClobbered(currentNode)) {
11300
11417
  _forceRemove(currentNode);
11301
11418
  return true;
@@ -11305,59 +11422,31 @@ function createDOMPurify() {
11305
11422
  tagName,
11306
11423
  allowedTags: ALLOWED_TAGS
11307
11424
  });
11308
- if (SAFE_FOR_XML && currentNode.hasChildNodes() && !_isNode(currentNode.firstElementChild) && regExpTest(/<[/\w!]/g, currentNode.innerHTML) && regExpTest(/<[/\w!]/g, currentNode.textContent)) {
11309
- _forceRemove(currentNode);
11310
- return true;
11311
- }
11312
- if (SAFE_FOR_XML && currentNode.namespaceURI === HTML_NAMESPACE && tagName === "style" && _isNode(currentNode.firstElementChild)) {
11313
- _forceRemove(currentNode);
11425
+ if (currentNode !== root && getParentNode(currentNode) === null) {
11314
11426
  return true;
11315
11427
  }
11316
- if (currentNode.nodeType === NODE_TYPE.progressingInstruction) {
11317
- _forceRemove(currentNode);
11318
- return true;
11319
- }
11320
- if (SAFE_FOR_XML && currentNode.nodeType === NODE_TYPE.comment && regExpTest(/<[/\w]/g, currentNode.data)) {
11428
+ if (_isUnsafeNode(currentNode, tagName)) {
11321
11429
  _forceRemove(currentNode);
11322
11430
  return true;
11323
11431
  }
11324
11432
  if (FORBID_TAGS[tagName] || !(EXTRA_ELEMENT_HANDLING.tagCheck instanceof Function && EXTRA_ELEMENT_HANDLING.tagCheck(tagName)) && !ALLOWED_TAGS[tagName]) {
11325
- if (!FORBID_TAGS[tagName] && _isBasicCustomElement(tagName)) {
11326
- if (CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof RegExp && regExpTest(CUSTOM_ELEMENT_HANDLING.tagNameCheck, tagName)) {
11327
- return false;
11328
- }
11329
- if (CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof Function && CUSTOM_ELEMENT_HANDLING.tagNameCheck(tagName)) {
11330
- return false;
11331
- }
11332
- }
11333
- if (KEEP_CONTENT && !FORBID_CONTENTS[tagName]) {
11334
- const parentNode = getParentNode(currentNode);
11335
- const childNodes = getChildNodes(currentNode);
11336
- if (childNodes && parentNode) {
11337
- const childCount = childNodes.length;
11338
- for (let i = childCount - 1; i >= 0; --i) {
11339
- const hoisted = IN_PLACE ? childNodes[i] : cloneNode(childNodes[i], true);
11340
- parentNode.insertBefore(hoisted, getNextSibling(currentNode));
11341
- }
11342
- }
11433
+ const removed = _sanitizeDisallowedNode(currentNode, tagName);
11434
+ if (removed === false) {
11435
+ _executeHooks(hooks.afterSanitizeElements, currentNode, null);
11343
11436
  }
11344
- _forceRemove(currentNode);
11345
- return true;
11437
+ return removed;
11346
11438
  }
11347
11439
  const nt = getNodeType ? getNodeType(currentNode) : currentNode.nodeType;
11348
11440
  if (nt === NODE_TYPE.element && !_checkValidNamespace(currentNode)) {
11349
11441
  _forceRemove(currentNode);
11350
11442
  return true;
11351
11443
  }
11352
- if ((tagName === "noscript" || tagName === "noembed" || tagName === "noframes") && regExpTest(/<\/no(script|embed|frames)/i, currentNode.innerHTML)) {
11444
+ if ((tagName === "noscript" || tagName === "noembed" || tagName === "noframes") && regExpTest(FALLBACK_TAG_CLOSE, currentNode.innerHTML)) {
11353
11445
  _forceRemove(currentNode);
11354
11446
  return true;
11355
11447
  }
11356
11448
  if (SAFE_FOR_TEMPLATES && currentNode.nodeType === NODE_TYPE.text) {
11357
- content = currentNode.textContent;
11358
- arrayForEach([MUSTACHE_EXPR$1, ERB_EXPR$1, TMPLIT_EXPR$1], (expr) => {
11359
- content = stringReplace(content, expr, " ");
11360
- });
11449
+ const content = _stripTemplateExpressions(currentNode.textContent);
11361
11450
  if (currentNode.textContent !== content) {
11362
11451
  arrayPush(DOMPurify.removed, {
11363
11452
  element: currentNode.cloneNode()
@@ -11372,13 +11461,19 @@ function createDOMPurify() {
11372
11461
  if (FORBID_ATTR[lcName]) {
11373
11462
  return false;
11374
11463
  }
11464
+ if (SAFE_FOR_XML && lcName === "patchsrc") {
11465
+ return false;
11466
+ }
11467
+ if (SAFE_FOR_XML && lcName === "for" && lcTag !== "label" && lcTag !== "output") {
11468
+ return false;
11469
+ }
11375
11470
  if (SANITIZE_DOM && (lcName === "id" || lcName === "name") && (value in document2 || value in formElement)) {
11376
11471
  return false;
11377
11472
  }
11378
11473
  const nameIsPermitted = ALLOWED_ATTR[lcName] || EXTRA_ELEMENT_HANDLING.attributeCheck instanceof Function && EXTRA_ELEMENT_HANDLING.attributeCheck(lcName, lcTag);
11379
- if (ALLOW_DATA_ATTR && !FORBID_ATTR[lcName] && regExpTest(DATA_ATTR$1, lcName)) ;
11474
+ if (ALLOW_DATA_ATTR && regExpTest(DATA_ATTR$1, lcName)) ;
11380
11475
  else if (ALLOW_ARIA_ATTR && regExpTest(ARIA_ATTR$1, lcName)) ;
11381
- else if (!nameIsPermitted || FORBID_ATTR[lcName]) {
11476
+ else if (!nameIsPermitted) {
11382
11477
  if (
11383
11478
  // First condition does a very basic check if a) it's basically a valid custom element tagname AND
11384
11479
  // b) if the tagName passes whatever the user has configured for CUSTOM_ELEMENT_HANDLING.tagNameCheck
@@ -11403,6 +11498,35 @@ function createDOMPurify() {
11403
11498
  const _isBasicCustomElement = function _isBasicCustomElement2(tagName) {
11404
11499
  return !RESERVED_CUSTOM_ELEMENT_NAMES[stringToLowerCase(tagName)] && regExpTest(CUSTOM_ELEMENT$1, tagName);
11405
11500
  };
11501
+ const _applyTrustedTypesToAttribute = function _applyTrustedTypesToAttribute2(lcTag, lcName, namespaceURI, value) {
11502
+ if (trustedTypesPolicy && typeof trustedTypes === "object" && typeof trustedTypes.getAttributeType === "function" && !namespaceURI) {
11503
+ switch (trustedTypes.getAttributeType(lcTag, lcName)) {
11504
+ case "TrustedHTML": {
11505
+ return _createTrustedHTML(value);
11506
+ }
11507
+ case "TrustedScriptURL": {
11508
+ return _createTrustedScriptURL(value);
11509
+ }
11510
+ }
11511
+ }
11512
+ return value;
11513
+ };
11514
+ const _setAttributeValue = function _setAttributeValue2(currentNode, name, namespaceURI, value) {
11515
+ try {
11516
+ if (namespaceURI) {
11517
+ currentNode.setAttributeNS(namespaceURI, name, value);
11518
+ } else {
11519
+ currentNode.setAttribute(name, value);
11520
+ }
11521
+ if (_isClobbered(currentNode)) {
11522
+ _forceRemove(currentNode);
11523
+ } else {
11524
+ arrayPop(DOMPurify.removed);
11525
+ }
11526
+ } catch (_) {
11527
+ _removeAttribute(name, currentNode);
11528
+ }
11529
+ };
11406
11530
  const _sanitizeAttributes = function _sanitizeAttributes2(currentNode) {
11407
11531
  _executeHooks(hooks.beforeSanitizeAttributes, currentNode, null);
11408
11532
  const attributes = currentNode.attributes;
@@ -11417,6 +11541,7 @@ function createDOMPurify() {
11417
11541
  forceKeepAttr: void 0
11418
11542
  };
11419
11543
  let l = attributes.length;
11544
+ const lcTag = transformCaseFunc(currentNode.nodeName);
11420
11545
  while (l--) {
11421
11546
  const attr = attributes[l];
11422
11547
  const name = attr.name, namespaceURI = attr.namespaceURI, attrValue = attr.value;
@@ -11448,50 +11573,20 @@ function createDOMPurify() {
11448
11573
  _removeAttribute(name, currentNode);
11449
11574
  continue;
11450
11575
  }
11451
- if (!ALLOW_SELF_CLOSE_IN_ATTR && regExpTest(/\/>/i, value)) {
11576
+ if (!ALLOW_SELF_CLOSE_IN_ATTR && regExpTest(SELF_CLOSING_TAG, value)) {
11452
11577
  _removeAttribute(name, currentNode);
11453
11578
  continue;
11454
11579
  }
11455
11580
  if (SAFE_FOR_TEMPLATES) {
11456
- arrayForEach([MUSTACHE_EXPR$1, ERB_EXPR$1, TMPLIT_EXPR$1], (expr) => {
11457
- value = stringReplace(value, expr, " ");
11458
- });
11581
+ value = _stripTemplateExpressions(value);
11459
11582
  }
11460
- const lcTag = transformCaseFunc(currentNode.nodeName);
11461
11583
  if (!_isValidAttribute(lcTag, lcName, value)) {
11462
11584
  _removeAttribute(name, currentNode);
11463
11585
  continue;
11464
11586
  }
11465
- if (trustedTypesPolicy && typeof trustedTypes === "object" && typeof trustedTypes.getAttributeType === "function") {
11466
- if (namespaceURI) ;
11467
- else {
11468
- switch (trustedTypes.getAttributeType(lcTag, lcName)) {
11469
- case "TrustedHTML": {
11470
- value = _createTrustedHTML(value);
11471
- break;
11472
- }
11473
- case "TrustedScriptURL": {
11474
- value = _createTrustedScriptURL(value);
11475
- break;
11476
- }
11477
- }
11478
- }
11479
- }
11587
+ value = _applyTrustedTypesToAttribute(lcTag, lcName, namespaceURI, value);
11480
11588
  if (value !== initValue) {
11481
- try {
11482
- if (namespaceURI) {
11483
- currentNode.setAttributeNS(namespaceURI, name, value);
11484
- } else {
11485
- currentNode.setAttribute(name, value);
11486
- }
11487
- if (_isClobbered(currentNode)) {
11488
- _forceRemove(currentNode);
11489
- } else {
11490
- arrayPop(DOMPurify.removed);
11491
- }
11492
- } catch (_) {
11493
- _removeAttribute(name, currentNode);
11494
- }
11589
+ _setAttributeValue(currentNode, name, namespaceURI, value);
11495
11590
  }
11496
11591
  }
11497
11592
  _executeHooks(hooks.afterSanitizeAttributes, currentNode, null);
@@ -11502,14 +11597,14 @@ function createDOMPurify() {
11502
11597
  _executeHooks(hooks.beforeSanitizeShadowDOM, fragment, null);
11503
11598
  while (shadowNode = shadowIterator.nextNode()) {
11504
11599
  _executeHooks(hooks.uponSanitizeShadowNode, shadowNode, null);
11505
- _sanitizeElements(shadowNode);
11600
+ _sanitizeElements(shadowNode, fragment);
11506
11601
  _sanitizeAttributes(shadowNode);
11507
11602
  if (_isDocumentFragment(shadowNode.content)) {
11508
11603
  _sanitizeShadowDOM2(shadowNode.content);
11509
11604
  }
11510
11605
  const shadowNodeType = getNodeType ? getNodeType(shadowNode) : shadowNode.nodeType;
11511
11606
  if (shadowNodeType === NODE_TYPE.element) {
11512
- const innerSr = getShadowRoot ? getShadowRoot(shadowNode) : shadowNode.shadowRoot;
11607
+ const innerSr = getShadowRoot(shadowNode);
11513
11608
  if (_isDocumentFragment(innerSr)) {
11514
11609
  _sanitizeAttachedShadowRoots(innerSr);
11515
11610
  _sanitizeShadowDOM2(innerSr);
@@ -11532,7 +11627,7 @@ function createDOMPurify() {
11532
11627
  const node = item.node;
11533
11628
  const nodeType = getNodeType ? getNodeType(node) : node.nodeType;
11534
11629
  const isElement = nodeType === NODE_TYPE.element;
11535
- const childNodes = getChildNodes ? getChildNodes(node) : node.childNodes;
11630
+ const childNodes = getChildNodes(node);
11536
11631
  if (childNodes) {
11537
11632
  for (let i = childNodes.length - 1; i >= 0; --i) {
11538
11633
  stack.push({
@@ -11554,7 +11649,7 @@ function createDOMPurify() {
11554
11649
  }
11555
11650
  }
11556
11651
  if (isElement) {
11557
- const sr = getShadowRoot ? getShadowRoot(node) : node.shadowRoot;
11652
+ const sr = getShadowRoot(node);
11558
11653
  if (_isDocumentFragment(sr)) {
11559
11654
  stack.push({
11560
11655
  node: null,
@@ -11586,20 +11681,32 @@ function createDOMPurify() {
11586
11681
  if (!DOMPurify.isSupported) {
11587
11682
  return dirty;
11588
11683
  }
11589
- if (!SET_CONFIG) {
11684
+ if (SET_CONFIG) {
11685
+ ALLOWED_TAGS = SET_CONFIG_ALLOWED_TAGS;
11686
+ ALLOWED_ATTR = SET_CONFIG_ALLOWED_ATTR;
11687
+ } else {
11590
11688
  _parseConfig(cfg);
11591
11689
  }
11690
+ if (hooks.uponSanitizeElement.length > 0 || hooks.uponSanitizeAttribute.length > 0) {
11691
+ ALLOWED_TAGS = clone(ALLOWED_TAGS);
11692
+ }
11693
+ if (hooks.uponSanitizeAttribute.length > 0) {
11694
+ ALLOWED_ATTR = clone(ALLOWED_ATTR);
11695
+ }
11592
11696
  DOMPurify.removed = [];
11593
11697
  const inPlace = IN_PLACE && typeof dirty !== "string" && _isNode(dirty);
11594
11698
  if (inPlace) {
11699
+ _neutralizePatchLinkage(dirty);
11595
11700
  const nn = getNodeName ? getNodeName(dirty) : dirty.nodeName;
11596
11701
  if (typeof nn === "string") {
11597
11702
  const tagName = transformCaseFunc(nn);
11598
11703
  if (!ALLOWED_TAGS[tagName] || FORBID_TAGS[tagName]) {
11704
+ _neutralizeRoot(dirty);
11599
11705
  throw typeErrorCreate("root node is forbidden and cannot be sanitized in-place");
11600
11706
  }
11601
11707
  }
11602
11708
  if (_isClobbered(dirty)) {
11709
+ _neutralizeRoot(dirty);
11603
11710
  throw typeErrorCreate("root node is clobbered and cannot be sanitized in-place");
11604
11711
  }
11605
11712
  try {
@@ -11632,10 +11739,11 @@ function createDOMPurify() {
11632
11739
  if (body && FORCE_BODY) {
11633
11740
  _forceRemove(body.firstChild);
11634
11741
  }
11635
- const nodeIterator = _createNodeIterator(inPlace ? dirty : body);
11742
+ const walkRoot = inPlace ? dirty : body;
11743
+ const nodeIterator = _createNodeIterator(walkRoot);
11636
11744
  try {
11637
11745
  while (currentNode = nodeIterator.nextNode()) {
11638
- _sanitizeElements(currentNode);
11746
+ _sanitizeElements(currentNode, walkRoot);
11639
11747
  _sanitizeAttributes(currentNode);
11640
11748
  if (_isDocumentFragment(currentNode.content)) {
11641
11749
  _sanitizeShadowDOM2(currentNode.content);
@@ -11644,6 +11752,11 @@ function createDOMPurify() {
11644
11752
  } catch (error) {
11645
11753
  if (inPlace) {
11646
11754
  _neutralizeRoot(dirty);
11755
+ arrayForEach(DOMPurify.removed, (entry) => {
11756
+ if (entry.element) {
11757
+ _neutralizeSubtree(entry.element);
11758
+ }
11759
+ });
11647
11760
  }
11648
11761
  throw error;
11649
11762
  }
@@ -11680,9 +11793,7 @@ function createDOMPurify() {
11680
11793
  serializedHTML = "<!DOCTYPE " + body.ownerDocument.doctype.name + ">\n" + serializedHTML;
11681
11794
  }
11682
11795
  if (SAFE_FOR_TEMPLATES) {
11683
- arrayForEach([MUSTACHE_EXPR$1, ERB_EXPR$1, TMPLIT_EXPR$1], (expr) => {
11684
- serializedHTML = stringReplace(serializedHTML, expr, " ");
11685
- });
11796
+ serializedHTML = _stripTemplateExpressions(serializedHTML);
11686
11797
  }
11687
11798
  return trustedTypesPolicy && RETURN_TRUSTED_TYPE ? _createTrustedHTML(serializedHTML) : serializedHTML;
11688
11799
  };
@@ -11690,10 +11801,14 @@ function createDOMPurify() {
11690
11801
  let cfg = arguments.length > 0 && arguments[0] !== void 0 ? arguments[0] : {};
11691
11802
  _parseConfig(cfg);
11692
11803
  SET_CONFIG = true;
11804
+ SET_CONFIG_ALLOWED_TAGS = ALLOWED_TAGS;
11805
+ SET_CONFIG_ALLOWED_ATTR = ALLOWED_ATTR;
11693
11806
  };
11694
11807
  DOMPurify.clearConfig = function() {
11695
11808
  CONFIG = null;
11696
11809
  SET_CONFIG = false;
11810
+ SET_CONFIG_ALLOWED_TAGS = null;
11811
+ SET_CONFIG_ALLOWED_ATTR = null;
11697
11812
  trustedTypesPolicy = defaultTrustedTypesPolicy;
11698
11813
  emptyHTML = "";
11699
11814
  };
@@ -11709,9 +11824,15 @@ function createDOMPurify() {
11709
11824
  if (typeof hookFunction !== "function") {
11710
11825
  return;
11711
11826
  }
11827
+ if (!objectHasOwnProperty(hooks, entryPoint)) {
11828
+ return;
11829
+ }
11712
11830
  arrayPush(hooks[entryPoint], hookFunction);
11713
11831
  };
11714
11832
  DOMPurify.removeHook = function(entryPoint, hookFunction) {
11833
+ if (!objectHasOwnProperty(hooks, entryPoint)) {
11834
+ return void 0;
11835
+ }
11715
11836
  if (hookFunction !== void 0) {
11716
11837
  const index = arrayLastIndexOf(hooks[entryPoint], hookFunction);
11717
11838
  return index === -1 ? void 0 : arraySplice(hooks[entryPoint], index, 1)[0];
@@ -11719,6 +11840,9 @@ function createDOMPurify() {
11719
11840
  return arrayPop(hooks[entryPoint]);
11720
11841
  };
11721
11842
  DOMPurify.removeHooks = function(entryPoint) {
11843
+ if (!objectHasOwnProperty(hooks, entryPoint)) {
11844
+ return;
11845
+ }
11722
11846
  hooks[entryPoint] = [];
11723
11847
  };
11724
11848
  DOMPurify.removeAllHooks = function() {
@@ -11741,9 +11865,10 @@ function sanitizeBannerHtml(html2) {
11741
11865
  ALLOW_DATA_ATTR: false
11742
11866
  });
11743
11867
  }
11744
- function resolveCssToken(token) {
11868
+ function resolveCssToken(token, preferredScope) {
11745
11869
  const normalizedToken = token.startsWith("--") ? token : `--${token}`;
11746
11870
  const candidates = [
11871
+ preferredScope,
11747
11872
  document.documentElement,
11748
11873
  document.body,
11749
11874
  ...Array.from(
@@ -11763,32 +11888,33 @@ function resolveCssToken(token) {
11763
11888
  )
11764
11889
  )
11765
11890
  ].filter(Boolean);
11891
+ const checked = /* @__PURE__ */ new Set();
11766
11892
  for (const node of candidates) {
11893
+ if (checked.has(node)) continue;
11894
+ checked.add(node);
11767
11895
  const value = getComputedStyle(node).getPropertyValue(normalizedToken).trim();
11768
11896
  if (value) return value;
11769
11897
  }
11770
11898
  for (const node of Array.from(document.querySelectorAll("*"))) {
11899
+ if (checked.has(node)) continue;
11771
11900
  const value = getComputedStyle(node).getPropertyValue(normalizedToken).trim();
11772
11901
  if (value) return value;
11773
11902
  }
11774
11903
  return void 0;
11775
11904
  }
11776
- const safeColor = (v) => {
11905
+ function safeColor(v, preferredScope) {
11777
11906
  if (!v) return void 0;
11778
11907
  const value = v.trim();
11779
11908
  if (/^(#|rgb|hsl)/i.test(value)) return value;
11780
11909
  if (/^(--)?[a-z0-9-]+$/i.test(value)) {
11781
- const resolved = resolveCssToken(value);
11782
- return resolved;
11910
+ return resolveCssToken(value, preferredScope);
11783
11911
  }
11784
11912
  const varMatch = value.match(/^var\((--[a-z0-9-]+)\)$/i);
11785
11913
  if (varMatch) {
11786
- const token = varMatch[1];
11787
- const resolved = resolveCssToken(token);
11788
- return resolved;
11914
+ return resolveCssToken(varMatch[1], preferredScope);
11789
11915
  }
11790
11916
  return void 0;
11791
- };
11917
+ }
11792
11918
  function el(tag, styles, attrs) {
11793
11919
  const node = document.createElement(tag);
11794
11920
  Object.assign(node.style, styles);
@@ -11872,15 +11998,15 @@ function justifyFromTextAlign(align) {
11872
11998
  if (align === "right") return "flex-end";
11873
11999
  return "flex-start";
11874
12000
  }
11875
- function renderBanner(banner, handlers) {
12001
+ function renderBanner(banner, handlers, colorScope) {
11876
12002
  var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n;
11877
12003
  const placement = banner.placement || {};
11878
12004
  const mode = placement.mode || "overlay";
11879
12005
  const position = placement.position || "top";
11880
12006
  const zIndex = String(placement.zIndex || 2147483e3);
11881
12007
  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";
12008
+ const bg = imageBanner ? "transparent" : safeColor((_a = banner.style) == null ? void 0 : _a.backgroundColor, colorScope) || "#1f2024";
12009
+ const color = safeColor((_b = banner.style) == null ? void 0 : _b.color, colorScope) || "#ffffff";
11884
12010
  const isCard = mode === "overlay" || mode === "popup";
11885
12011
  const ctaPosition = getCtaStyleValue(banner, ["position"]) || "center";
11886
12012
  const imageHorizontal = imageAlign((_c = banner.image) == null ? void 0 : _c.horizontalAlignment);
@@ -12021,9 +12147,13 @@ function renderBanner(banner, handlers) {
12021
12147
  }
12022
12148
  if (!imageBanner && ((_n = banner.cta) == null ? void 0 : _n.enabled)) {
12023
12149
  const ctaBg = safeColor(
12024
- getCtaStyleValue(banner, ["backgroundColor", "buttonColor", "aColor"])
12150
+ getCtaStyleValue(banner, ["backgroundColor", "buttonColor", "aColor"]),
12151
+ colorScope
12025
12152
  ) || "#2f6df6";
12026
- const ctaColor = safeColor(getCtaStyleValue(banner, ["textColor", "color"])) || "#ffffff";
12153
+ const ctaColor = safeColor(
12154
+ getCtaStyleValue(banner, ["textColor", "color"]),
12155
+ colorScope
12156
+ ) || "#ffffff";
12027
12157
  const btn = el("button", {
12028
12158
  cursor: "pointer",
12029
12159
  border: "none",
@@ -12217,6 +12347,9 @@ function setTokens(config, state, data, onRefreshScheduled) {
12217
12347
  state.accessToken = data.accessToken;
12218
12348
  state.refreshToken = data.refreshToken;
12219
12349
  state.tokenFamily = data.tokenFamily ?? null;
12350
+ if (data.widgetData && typeof data.widgetData === "object" && !Array.isArray(data.widgetData)) {
12351
+ state.widgetData = data.widgetData;
12352
+ }
12220
12353
  const now = Date.now();
12221
12354
  state.accessTokenExpiry = now + data.accessTokenTTL * 1e3;
12222
12355
  state.refreshTokenExpiry = now + data.refreshTokenTTL * 1e3;
@@ -12435,6 +12568,9 @@ function applyErrorSettingsToState(state, data) {
12435
12568
  if (data.loadingAnimation) {
12436
12569
  state.loadingAnimation = data.loadingAnimation;
12437
12570
  }
12571
+ if (data.loadingSettings) {
12572
+ state.loadingSettings = data.loadingSettings;
12573
+ }
12438
12574
  if (data.themePalette) {
12439
12575
  state.themePalette = data.themePalette;
12440
12576
  }
@@ -12489,6 +12625,7 @@ function clearState(state) {
12489
12625
  state.isRefreshing = false;
12490
12626
  state.refreshPromise = null;
12491
12627
  state.lastAuthError = null;
12628
+ state.widgetData = null;
12492
12629
  if (state.refreshTimer) {
12493
12630
  clearTimeout(state.refreshTimer);
12494
12631
  state.refreshTimer = null;
@@ -12498,6 +12635,33 @@ function clearState(state) {
12498
12635
  state.syncTimer = null;
12499
12636
  }
12500
12637
  }
12638
+ const AUTO_THEME_LEASE_STATE = "__RAI_AUTO_THEME_LEASE_STATE__";
12639
+ const DISABLE_AUTO_THEME = "__DISABLE_AUTO_THEME__";
12640
+ function acquireAutoThemeDisableLease(target = window) {
12641
+ let state = target[AUTO_THEME_LEASE_STATE];
12642
+ if (!state) {
12643
+ state = {
12644
+ count: 0,
12645
+ previousValue: target[DISABLE_AUTO_THEME]
12646
+ };
12647
+ target[AUTO_THEME_LEASE_STATE] = state;
12648
+ }
12649
+ state.count += 1;
12650
+ target[DISABLE_AUTO_THEME] = true;
12651
+ let released = false;
12652
+ return () => {
12653
+ if (released) return;
12654
+ released = true;
12655
+ state.count = Math.max(0, state.count - 1);
12656
+ if (state.count > 0) return;
12657
+ if (state.previousValue === void 0) {
12658
+ delete target[DISABLE_AUTO_THEME];
12659
+ } else {
12660
+ target[DISABLE_AUTO_THEME] = state.previousValue;
12661
+ }
12662
+ delete target[AUTO_THEME_LEASE_STATE];
12663
+ };
12664
+ }
12501
12665
  const BUNDLE_READY_TIMEOUT_MS = 3e4;
12502
12666
  function isPromiseLike(value) {
12503
12667
  return (typeof value === "object" || typeof value === "function") && value !== null && typeof value.then === "function";
@@ -12542,6 +12706,20 @@ async function waitForBundleMountReadiness(mountResult, firstPaint, timeoutMs =
12542
12706
  );
12543
12707
  return "deep-ready";
12544
12708
  }
12709
+ function createBundleRuntimeWarmer({
12710
+ preloadScript: preloadScript2,
12711
+ baseUrl
12712
+ }) {
12713
+ const preloadPromises = /* @__PURE__ */ new Map();
12714
+ return function warmBundleRuntime2(globalName, bundleUrl) {
12715
+ const normalizedUrl = normalizeBundleUrl(bundleUrl, baseUrl());
12716
+ if (preloadPromises.has(normalizedUrl)) return;
12717
+ const preloadPromise = preloadScript2(normalizedUrl).catch(() => {
12718
+ preloadPromises.delete(normalizedUrl);
12719
+ });
12720
+ preloadPromises.set(normalizedUrl, preloadPromise);
12721
+ };
12722
+ }
12545
12723
  function isWidgetBundleRuntime(value) {
12546
12724
  return (typeof value === "object" || typeof value === "function") && value !== null && typeof value.mount === "function";
12547
12725
  }
@@ -12608,11 +12786,29 @@ function appendScript(url) {
12608
12786
  document.head.appendChild(script);
12609
12787
  });
12610
12788
  }
12789
+ function preloadScript(url) {
12790
+ return new Promise((resolve, reject) => {
12791
+ const link = document.createElement("link");
12792
+ link.rel = "preload";
12793
+ link.as = "script";
12794
+ link.href = url;
12795
+ link.onload = () => resolve();
12796
+ link.onerror = () => reject(new Error(`Failed to preload ${url}`));
12797
+ document.head.appendChild(link);
12798
+ });
12799
+ }
12611
12800
  const loadBrowserBundleRuntime = createBundleRuntimeLoader({
12612
12801
  loadScript: appendScript,
12613
12802
  readGlobal: (globalName) => window[globalName],
12614
12803
  baseUrl: () => document.baseURI
12615
12804
  });
12805
+ const warmBrowserBundleRuntime = createBundleRuntimeWarmer({
12806
+ preloadScript,
12807
+ baseUrl: () => document.baseURI
12808
+ });
12809
+ function warmBundleRuntime(globalName, bundleUrl) {
12810
+ warmBrowserBundleRuntime(globalName, bundleUrl);
12811
+ }
12616
12812
  function getOrLoadBundleRuntime(globalName, bundleUrl) {
12617
12813
  return loadBrowserBundleRuntime(globalName, bundleUrl);
12618
12814
  }
@@ -12660,23 +12856,194 @@ const STORE_CALLBACK_FIELD_OPTIONS_CALLBACK_NAME = "callbackFieldOptions";
12660
12856
  const STORE_CALLBACK_FIELD_OPTIONS_TIMEOUT_MS = 15e3;
12661
12857
  const STORE_PURCHASE_SUCCESS_SCOPE = "store.purchase_success";
12662
12858
  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;
12859
+ const MILESTONE_CTA_CLICK_SCOPE = "milestone.cta_click";
12860
+ const MILESTONE_CTA_CLICK_CALLBACK_NAME = "milestoneCtaClick";
12861
+ const MILESTONE_CTA_CLICK_EVENT = "milestone_cta_clicked";
12862
+ function isRecord(value) {
12863
+ return typeof value === "object" && value !== null;
12864
+ }
12865
+ function isStringRecord(value) {
12866
+ return isRecord(value) && Object.values(value).every((item) => typeof item === "string");
12666
12867
  }
12667
- async function invokeStoreHostCallback(callbacks, callbackName, payload) {
12668
- if (!isSupportedStoreHostCallback(callbackName, payload)) {
12669
- throw new Error("Host callback is only supported for store widgets");
12868
+ function readEmbedTokenUserIdentifiers(embedToken) {
12869
+ if (!embedToken) return null;
12870
+ const encodedPayload = embedToken.split(".")[1];
12871
+ if (!encodedPayload) return null;
12872
+ try {
12873
+ const normalizedPayload = encodedPayload.replace(/-/g, "+").replace(/_/g, "/");
12874
+ const paddedPayload = normalizedPayload.padEnd(
12875
+ Math.ceil(normalizedPayload.length / 4) * 4,
12876
+ "="
12877
+ );
12878
+ const bytes = Uint8Array.from(atob(paddedPayload), (character) => character.charCodeAt(0));
12879
+ const claims = JSON.parse(new TextDecoder().decode(bytes));
12880
+ if (!isRecord(claims) || !isStringRecord(claims.userIdentifiers)) return null;
12881
+ return { ...claims.userIdentifiers };
12882
+ } catch {
12883
+ return null;
12884
+ }
12885
+ }
12886
+ function resolveHostUserIdentifiers(config) {
12887
+ return readEmbedTokenUserIdentifiers(config.embedToken) ?? { ...config.userIdentifiers };
12888
+ }
12889
+ function hasCallbackContract(payload, callbackName, scope) {
12890
+ return isRecord(payload) && payload.callbackName === callbackName && payload.scope === scope;
12891
+ }
12892
+ function isMilestoneCtaClickPayload(payload) {
12893
+ if (!hasCallbackContract(
12894
+ payload,
12895
+ MILESTONE_CTA_CLICK_CALLBACK_NAME,
12896
+ MILESTONE_CTA_CLICK_SCOPE
12897
+ )) return false;
12898
+ const context = payload.context;
12899
+ if (!isRecord(context)) return false;
12900
+ const community = context.community;
12901
+ const milestone = context.milestone;
12902
+ const stage = context.stage;
12903
+ const button = context.button;
12904
+ const user = context.user;
12905
+ return context.event === MILESTONE_CTA_CLICK_EVENT && isRecord(community) && typeof community.id === "string" && community.id.length > 0 && (community.name === void 0 || community.name === null || typeof community.name === "string") && isRecord(milestone) && typeof milestone.id === "string" && milestone.id.length > 0 && typeof milestone.name === "string" && milestone.name.length > 0 && isRecord(stage) && typeof stage.id === "string" && stage.id.length > 0 && typeof stage.name === "string" && stage.name.length > 0 && isRecord(button) && typeof button.name === "string" && button.name.length > 0 && isRecord(user) && isStringRecord(user.identifiers) && typeof context.clickedAt === "string" && context.clickedAt.length > 0 && !Number.isNaN(Date.parse(context.clickedAt));
12906
+ }
12907
+ function enrichHostCallbackPayload(payload, userIdentifiers) {
12908
+ if (!userIdentifiers || Object.keys(userIdentifiers).length === 0) return payload;
12909
+ if (!isRecord(payload)) return payload;
12910
+ const context = payload.context;
12911
+ if (!isRecord(context)) return payload;
12912
+ const user = context.user;
12913
+ if (!isRecord(user)) return payload;
12914
+ return {
12915
+ ...payload,
12916
+ context: {
12917
+ ...context,
12918
+ user: {
12919
+ ...user,
12920
+ identifiers: { ...userIdentifiers }
12921
+ }
12922
+ }
12923
+ };
12924
+ }
12925
+ const HOST_CALLBACK_DEFINITIONS = {
12926
+ [STORE_CALLBACK_FIELD_OPTIONS_CALLBACK_NAME]: {
12927
+ callbackName: STORE_CALLBACK_FIELD_OPTIONS_CALLBACK_NAME,
12928
+ scope: STORE_CALLBACK_FIELD_OPTIONS_SCOPE,
12929
+ sourceWidgetType: "store",
12930
+ allowedHostWidgetTypes: ["store", "custom"],
12931
+ completionMode: "result",
12932
+ missingHandler: "reject",
12933
+ legacyActions: ["store:host-callback"],
12934
+ validatePayload: (payload) => hasCallbackContract(
12935
+ payload,
12936
+ STORE_CALLBACK_FIELD_OPTIONS_CALLBACK_NAME,
12937
+ STORE_CALLBACK_FIELD_OPTIONS_SCOPE
12938
+ )
12939
+ },
12940
+ [STORE_PURCHASE_SUCCESS_CALLBACK_NAME]: {
12941
+ callbackName: STORE_PURCHASE_SUCCESS_CALLBACK_NAME,
12942
+ scope: STORE_PURCHASE_SUCCESS_SCOPE,
12943
+ sourceWidgetType: "store",
12944
+ allowedHostWidgetTypes: ["store", "custom"],
12945
+ completionMode: "acknowledged",
12946
+ missingHandler: "reject",
12947
+ legacyActions: ["store:host-callback"],
12948
+ validatePayload: (payload) => hasCallbackContract(
12949
+ payload,
12950
+ STORE_PURCHASE_SUCCESS_CALLBACK_NAME,
12951
+ STORE_PURCHASE_SUCCESS_SCOPE
12952
+ )
12953
+ },
12954
+ [MILESTONE_CTA_CLICK_CALLBACK_NAME]: {
12955
+ callbackName: MILESTONE_CTA_CLICK_CALLBACK_NAME,
12956
+ scope: MILESTONE_CTA_CLICK_SCOPE,
12957
+ sourceWidgetType: "milestone",
12958
+ allowedHostWidgetTypes: ["milestone", "custom"],
12959
+ completionMode: "detached",
12960
+ missingHandler: "ignore",
12961
+ legacyActions: [],
12962
+ validatePayload: isMilestoneCtaClickPayload
12670
12963
  }
12671
- const callback = callbacks[callbackName];
12672
- if (!callback) throw new Error("Host callback is not registered");
12673
- let value;
12964
+ };
12965
+ function createInvocationId() {
12966
+ return `host_callback_${Date.now()}_${Math.random().toString(36).slice(2)}`;
12967
+ }
12968
+ function observe(observer, event) {
12969
+ if (!observer) return;
12674
12970
  try {
12675
- value = await callback(payload);
12971
+ observer(event);
12676
12972
  } catch {
12677
- throw new Error("Host callback failed");
12678
12973
  }
12679
- return callbackName === STORE_CALLBACK_FIELD_OPTIONS_CALLBACK_NAME ? value : void 0;
12974
+ }
12975
+ function getHostCallbackDefinition(callbackName, payload) {
12976
+ const definition = HOST_CALLBACK_DEFINITIONS[callbackName];
12977
+ return (definition == null ? void 0 : definition.validatePayload(payload)) ? definition : void 0;
12978
+ }
12979
+ function isHostCallbackMessageSupported(definition, action, sourceWidgetType, hostWidgetType) {
12980
+ const actionSupported = action === "widget:host-callback" || definition.legacyActions.includes(action);
12981
+ return actionSupported && sourceWidgetType === definition.sourceWidgetType && definition.allowedHostWidgetTypes.includes(hostWidgetType);
12982
+ }
12983
+ function dispatchHostCallback(input) {
12984
+ const definition = getHostCallbackDefinition(input.callbackName, input.payload);
12985
+ if (!definition || !definition.allowedHostWidgetTypes.includes(input.hostWidgetType)) {
12986
+ throw new Error("Host callback is not supported for this widget");
12987
+ }
12988
+ const invocationId = input.invocationId || createInvocationId();
12989
+ const eventBase = {
12990
+ invocationId,
12991
+ callbackName: definition.callbackName,
12992
+ scope: definition.scope,
12993
+ sourceWidgetType: definition.sourceWidgetType,
12994
+ hostWidgetType: input.hostWidgetType,
12995
+ completionMode: definition.completionMode,
12996
+ transport: input.transport
12997
+ };
12998
+ observe(input.observer, { type: "callback.received", ...eventBase });
12999
+ const callback = input.callbacks[definition.callbackName];
13000
+ if (!callback) {
13001
+ observe(input.observer, { type: "callback.handler_missing", ...eventBase });
13002
+ if (definition.missingHandler === "ignore") return;
13003
+ return Promise.reject(new Error("Host callback is not registered"));
13004
+ }
13005
+ observe(input.observer, { type: "callback.handler_started", ...eventBase });
13006
+ let result;
13007
+ try {
13008
+ result = callback(input.payload);
13009
+ } catch (error) {
13010
+ observe(input.observer, {
13011
+ type: "callback.handler_rejected",
13012
+ ...eventBase,
13013
+ error
13014
+ });
13015
+ if (definition.completionMode === "detached") return;
13016
+ return Promise.reject(new Error("Host callback failed"));
13017
+ }
13018
+ if (definition.completionMode === "detached") {
13019
+ if (result && typeof result.then === "function") {
13020
+ void Promise.resolve(result).then(
13021
+ () => observe(input.observer, { type: "callback.handler_resolved", ...eventBase }),
13022
+ (error) => observe(input.observer, {
13023
+ type: "callback.handler_rejected",
13024
+ ...eventBase,
13025
+ error
13026
+ })
13027
+ );
13028
+ } else {
13029
+ observe(input.observer, { type: "callback.handler_resolved", ...eventBase });
13030
+ }
13031
+ return;
13032
+ }
13033
+ return Promise.resolve(result).then(
13034
+ (value) => {
13035
+ observe(input.observer, { type: "callback.handler_resolved", ...eventBase });
13036
+ return definition.completionMode === "result" ? value : void 0;
13037
+ },
13038
+ (error) => {
13039
+ observe(input.observer, {
13040
+ type: "callback.handler_rejected",
13041
+ ...eventBase,
13042
+ error
13043
+ });
13044
+ throw new Error("Host callback failed");
13045
+ }
13046
+ );
12680
13047
  }
12681
13048
  function debounce(fn, wait) {
12682
13049
  let timer = null;
@@ -12768,52 +13135,58 @@ function setupMessageListener(config, state, _shadow, iframe, onRefreshScheduled
12768
13135
  }
12769
13136
  case "RETURNINGAI_WIDGET_ACTION": {
12770
13137
  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;
13138
+ const actionMessage = event.data;
13139
+ if (actionMessage.widgetId !== void 0 && actionMessage.widgetId !== config.widgetId) break;
13140
+ if (actionMessage.containerId !== void 0 && actionMessage.containerId !== config.container) break;
13141
+ const callbackPayload = enrichHostCallbackPayload(
13142
+ actionMessage.payload,
13143
+ resolveHostUserIdentifiers(config)
13144
+ );
13145
+ const definition = getHostCallbackDefinition(
13146
+ actionMessage.callbackName,
13147
+ callbackPayload
13148
+ );
13149
+ if (!definition) break;
13150
+ if (!isHostCallbackMessageSupported(
13151
+ definition,
13152
+ actionMessage.action,
13153
+ actionMessage.widgetType,
13154
+ config.widgetType
13155
+ )) break;
12778
13156
  const respond = (result) => {
12779
13157
  var _a2;
12780
13158
  (_a2 = iframe.contentWindow) == null ? void 0 : _a2.postMessage(result, config.widgetDomain);
12781
13159
  };
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
- }
13160
+ const dispatchResult = dispatchHostCallback({
13161
+ callbacks: (getCallbacks == null ? void 0 : getCallbacks()) ?? {},
13162
+ callbackName: actionMessage.callbackName,
13163
+ payload: callbackPayload,
13164
+ hostWidgetType: config.widgetType,
13165
+ invocationId: actionMessage.requestId,
13166
+ transport: "iframe"
13167
+ });
13168
+ if (!dispatchResult) break;
12794
13169
  try {
12795
- const value = await invokeStoreHostCallback(
12796
- callbacks,
12797
- message.callbackName,
12798
- message.payload
12799
- );
13170
+ const value = await dispatchResult;
12800
13171
  const result = {
12801
13172
  type: "RETURNINGAI_WIDGET_ACTION_RESULT",
12802
- requestId: message.requestId,
12803
- action: "store:host-callback",
13173
+ requestId: actionMessage.requestId,
13174
+ action: actionMessage.action === "widget:host-callback" ? "widget:host-callback" : "store:host-callback",
12804
13175
  ok: true,
12805
13176
  status: "success",
12806
- ...value !== void 0 ? { value } : {}
13177
+ ...definition.completionMode === "result" && value !== void 0 ? { value } : {}
12807
13178
  };
12808
13179
  respond(result);
12809
- } catch {
13180
+ } catch (error) {
12810
13181
  respond({
12811
13182
  type: "RETURNINGAI_WIDGET_ACTION_RESULT",
12812
- requestId: message.requestId,
12813
- action: "store:host-callback",
13183
+ requestId: actionMessage.requestId,
13184
+ action: actionMessage.action === "widget:host-callback" ? "widget:host-callback" : "store:host-callback",
12814
13185
  ok: false,
12815
13186
  status: "failed",
12816
- error: { message: "Host callback failed" }
13187
+ error: {
13188
+ message: error instanceof Error && error.message === "Host callback is not registered" ? error.message : "Host callback failed"
13189
+ }
12817
13190
  });
12818
13191
  }
12819
13192
  break;
@@ -12826,7 +13199,7 @@ function setupMessageListener(config, state, _shadow, iframe, onRefreshScheduled
12826
13199
  heightSetter.cancel();
12827
13200
  };
12828
13201
  }
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}';
13202
+ 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(--rai-loading-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-pending-settings{visibility:hidden}.rai-loader-text{margin:.5rem 0 0;font-family:var(--rai-loading-text-font, var(--rai-loader-font, "Roboto", system-ui, -apple-system, sans-serif));font-size:var(--rai-loading-text-size, 1.125rem);line-height:1.75rem;font-weight:var(--rai-loading-text-weight, 400);font-style:var(--rai-loading-text-style, normal);text-decoration:var(--rai-loading-text-decoration, none);letter-spacing:normal;color:var(--rai-loading-text-color, var(--accent-1, var(--rai-accent, #000000)));text-align:center}@media (min-width: 768px){.rai-loader-text{font-size:var(--rai-loading-text-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}';
12830
13203
  const DEFINED_ATTRS = /* @__PURE__ */ new Set([
12831
13204
  "community-id",
12832
13205
  "channel-id",
@@ -12934,17 +13307,88 @@ function resolveWidgetServerUrl(domainKey) {
12934
13307
  function resolveV2ApiUrl(domainKey) {
12935
13308
  return DOMAIN_KEY_TO_V2_API_URL[domainKey] || DOMAIN_KEY_TO_V2_API_URL.PROD;
12936
13309
  }
12937
- const loadedFonts = /* @__PURE__ */ new Set();
13310
+ const loadedGoogleFontFamilies = /* @__PURE__ */ new Set();
13311
+ const LOCAL_OR_SYSTEM_FONT_FAMILIES = /* @__PURE__ */ new Set([
13312
+ "aeonik",
13313
+ "courier",
13314
+ "courier new",
13315
+ "monaco",
13316
+ "monospace",
13317
+ "sans-serif",
13318
+ "serif",
13319
+ "system-ui"
13320
+ ]);
13321
+ const SERIF_FONT_FAMILIES = /* @__PURE__ */ new Set(["lora", "playfair display", "prata"]);
13322
+ const GOOGLE_FONT_VARIANTS = ":ital,wght@0,300;0,400;0,500;0,600;0,700;1,400;1,700";
13323
+ function normalizeFontFamily(family) {
13324
+ return family.trim() === "Noto" ? "Noto Sans" : family.trim();
13325
+ }
13326
+ function getFontStack(family) {
13327
+ const normalizedFamily = normalizeFontFamily(family);
13328
+ const normalizedKey = normalizedFamily.toLowerCase();
13329
+ switch (normalizedKey) {
13330
+ case "monospace":
13331
+ return "monospace";
13332
+ case "courier":
13333
+ case "courier new":
13334
+ return '"Courier New", Courier, monospace';
13335
+ case "monaco":
13336
+ return "Monaco, Menlo, Consolas, monospace";
13337
+ case "system-ui":
13338
+ return "system-ui, -apple-system, sans-serif";
13339
+ case "sans-serif":
13340
+ case "serif":
13341
+ return normalizedKey;
13342
+ default:
13343
+ return `'${normalizedFamily.replace(/[\\']/g, "\\\\$&")}', ${SERIF_FONT_FAMILIES.has(normalizedKey) ? "Georgia, 'Times New Roman', serif" : "system-ui, -apple-system, sans-serif"}`;
13344
+ }
13345
+ }
13346
+ function ensureGoogleFontPreconnect() {
13347
+ if (!document.getElementById("rai-fonts-preconnect")) {
13348
+ const link = document.createElement("link");
13349
+ link.id = "rai-fonts-preconnect";
13350
+ link.rel = "preconnect";
13351
+ link.href = "https://fonts.googleapis.com";
13352
+ document.head.appendChild(link);
13353
+ }
13354
+ if (!document.getElementById("rai-fonts-static-preconnect")) {
13355
+ const link = document.createElement("link");
13356
+ link.id = "rai-fonts-static-preconnect";
13357
+ link.rel = "preconnect";
13358
+ link.href = "https://fonts.gstatic.com";
13359
+ link.crossOrigin = "anonymous";
13360
+ document.head.appendChild(link);
13361
+ }
13362
+ }
12938
13363
  function ensureGoogleFontLoaded(family) {
12939
- if (!family || loadedFonts.has(family)) return;
12940
- loadedFonts.add(family);
12941
- const linkId = `rai-font-${family.toLowerCase().replace(/\s+/g, "-")}`;
12942
- if (document.getElementById(linkId)) return;
12943
- const link = document.createElement("link");
12944
- link.id = linkId;
12945
- link.rel = "stylesheet";
12946
- link.href = `https://fonts.googleapis.com/css2?family=${encodeURIComponent(family)}&display=swap`;
12947
- document.head.appendChild(link);
13364
+ const normalizedFamily = normalizeFontFamily(family);
13365
+ const fontKey = normalizedFamily.toLowerCase();
13366
+ if (!normalizedFamily || LOCAL_OR_SYSTEM_FONT_FAMILIES.has(fontKey)) {
13367
+ return;
13368
+ }
13369
+ if (loadedGoogleFontFamilies.has(fontKey)) return;
13370
+ ensureGoogleFontPreconnect();
13371
+ const linkId = `rai-font-${normalizedFamily.toLowerCase().replace(/[^a-z0-9]+/g, "-")}`;
13372
+ const fontUrl = `https://fonts.googleapis.com/css2?family=${encodeURIComponent(
13373
+ normalizedFamily
13374
+ )}${GOOGLE_FONT_VARIANTS}&display=swap`;
13375
+ let link = document.getElementById(linkId);
13376
+ if (link && link.href !== fontUrl) {
13377
+ link.remove();
13378
+ link = null;
13379
+ }
13380
+ if (!link) {
13381
+ link = document.createElement("link");
13382
+ link.id = linkId;
13383
+ link.rel = "stylesheet";
13384
+ link.href = fontUrl;
13385
+ document.head.appendChild(link);
13386
+ }
13387
+ loadedGoogleFontFamilies.add(fontKey);
13388
+ link.onerror = () => {
13389
+ loadedGoogleFontFamilies.delete(fontKey);
13390
+ link == null ? void 0 : link.remove();
13391
+ };
12948
13392
  }
12949
13393
  const DANGEROUS_ELEMENTS = ["script", "iframe", "object", "embed"];
12950
13394
  const URL_ATTRS = ["src", "href", "xlink:href"];
@@ -13107,10 +13551,12 @@ function createInitialState() {
13107
13551
  refreshPromise: null,
13108
13552
  errorSettings: null,
13109
13553
  loadingAnimation: null,
13554
+ loadingSettings: null,
13110
13555
  themePalette: null,
13111
13556
  font: null,
13112
13557
  defaultColorSchema: null,
13113
- lastAuthError: null
13558
+ lastAuthError: null,
13559
+ widgetData: null
13114
13560
  };
13115
13561
  }
13116
13562
  class BaseWidget extends HTMLElement {
@@ -13131,8 +13577,10 @@ class BaseWidget extends HTMLElement {
13131
13577
  __publicField(this, "hasAttemptedInit", false);
13132
13578
  __publicField(this, "initGeneration", 0);
13133
13579
  __publicField(this, "lottieInstances", []);
13580
+ __publicField(this, "renderedLoaderAnimationKey", null);
13134
13581
  __publicField(this, "callbackRegistry", new WidgetCallbackRegistry());
13135
13582
  __publicField(this, "bannerNode", null);
13583
+ __publicField(this, "releaseAutoThemeDisableLease");
13136
13584
  this.shadow = this.attachShadow({ mode: "closed" });
13137
13585
  }
13138
13586
  static get observedAttributes() {
@@ -13255,6 +13703,7 @@ class BaseWidget extends HTMLElement {
13255
13703
  applyFirstPaintColors() {
13256
13704
  var _a;
13257
13705
  const cached = loadErrorSettingsFromStorage(this.config);
13706
+ if (cached) applyErrorSettingsToState(this.state, cached);
13258
13707
  if (!this.config.themeExplicit) {
13259
13708
  const cachedDefault = cached == null ? void 0 : cached.defaultColorSchema;
13260
13709
  if (cachedDefault === "light" || cachedDefault === "dark") {
@@ -13267,6 +13716,7 @@ class BaseWidget extends HTMLElement {
13267
13716
  const cachedFont = typeof (cached == null ? void 0 : cached.font) === "string" ? cached.font : void 0;
13268
13717
  const font = cachedFont || this.config.firstPaintFont;
13269
13718
  if (font) this.applyFont(font);
13719
+ this.applyLoadingSettings();
13270
13720
  if (cachedPalette) return;
13271
13721
  const hints = this.config.firstPaintColors;
13272
13722
  if (hints == null ? void 0 : hints.bg) this.style.setProperty("--background-5", hints.bg);
@@ -13274,11 +13724,10 @@ class BaseWidget extends HTMLElement {
13274
13724
  if (hints == null ? void 0 : hints.accent) this.style.setProperty("--accent-1", hints.accent);
13275
13725
  }
13276
13726
  applyFont(font) {
13277
- this.style.setProperty(
13278
- "--rai-loader-font",
13279
- `'${font}', system-ui, -apple-system, sans-serif`
13280
- );
13281
- ensureGoogleFontLoaded(font);
13727
+ const normalizedFont = normalizeFontFamily(font);
13728
+ this.style.setProperty("--rai-loader-font", getFontStack(normalizedFont));
13729
+ this.style.setProperty("--font-family", normalizedFont);
13730
+ ensureGoogleFontLoaded(normalizedFont);
13282
13731
  }
13283
13732
  applyPalette(palette) {
13284
13733
  Object.entries(palette).forEach(([key, value]) => {
@@ -13287,14 +13736,91 @@ class BaseWidget extends HTMLElement {
13287
13736
  }
13288
13737
  });
13289
13738
  }
13739
+ applyLoadingSettings(loadingSettings = this.state.loadingSettings) {
13740
+ var _a, _b;
13741
+ const loadingText = loadingSettings == null ? void 0 : loadingSettings.loadingText;
13742
+ const colorMode = this.config.theme === "dark" ? "dark" : "light";
13743
+ const backgroundColor = ((_a = loadingSettings == null ? void 0 : loadingSettings.backgroundColors) == null ? void 0 : _a[colorMode]) ?? (loadingSettings == null ? void 0 : loadingSettings.backgroundColor);
13744
+ if (backgroundColor && backgroundColor !== "var(--background-5)") {
13745
+ this.style.setProperty("--rai-loading-background", backgroundColor);
13746
+ } else {
13747
+ this.style.removeProperty("--rai-loading-background");
13748
+ }
13749
+ const textEl = (_b = this.loaderEl) == null ? void 0 : _b.querySelector(".rai-loader-text");
13750
+ if (!loadingText) {
13751
+ this.style.removeProperty("--rai-loading-text-color");
13752
+ this.style.removeProperty("--rai-loading-text-font");
13753
+ this.style.removeProperty("--rai-loading-text-size");
13754
+ this.style.removeProperty("--rai-loading-text-weight");
13755
+ this.style.removeProperty("--rai-loading-text-style");
13756
+ this.style.removeProperty("--rai-loading-text-decoration");
13757
+ if (textEl) {
13758
+ textEl.textContent = this.config.loadingText;
13759
+ textEl.hidden = false;
13760
+ }
13761
+ return;
13762
+ }
13763
+ if (loadingText.color) {
13764
+ this.style.setProperty("--rai-loading-text-color", loadingText.color);
13765
+ }
13766
+ if (loadingText.fontFamily) {
13767
+ this.style.setProperty(
13768
+ "--rai-loading-text-font",
13769
+ getFontStack(loadingText.fontFamily)
13770
+ );
13771
+ ensureGoogleFontLoaded(loadingText.fontFamily);
13772
+ }
13773
+ if (Number.isFinite(loadingText.fontSizePx) && loadingText.fontSizePx > 0) {
13774
+ this.style.setProperty(
13775
+ "--rai-loading-text-size",
13776
+ `${loadingText.fontSizePx}px`
13777
+ );
13778
+ }
13779
+ this.style.setProperty(
13780
+ "--rai-loading-text-weight",
13781
+ loadingText.bold ? "700" : "400"
13782
+ );
13783
+ this.style.setProperty(
13784
+ "--rai-loading-text-style",
13785
+ loadingText.italic ? "italic" : "normal"
13786
+ );
13787
+ this.style.setProperty(
13788
+ "--rai-loading-text-decoration",
13789
+ loadingText.underline ? "underline" : "none"
13790
+ );
13791
+ if (textEl) {
13792
+ textEl.textContent = loadingText.text;
13793
+ textEl.hidden = !loadingText.enabled;
13794
+ }
13795
+ }
13796
+ getLoadingAnimationRenderKey() {
13797
+ var _a, _b, _c;
13798
+ const animation = this.state.loadingAnimation;
13799
+ const theme = this.config.theme === "dark" ? "dark" : "light";
13800
+ const custom = (animation == null ? void 0 : animation.type) === "custom" ? ((_a = animation.custom) == null ? void 0 : _a[theme]) || ((_b = animation.custom) == null ? void 0 : _b.light) || ((_c = animation.custom) == null ? void 0 : _c.dark) : void 0;
13801
+ return JSON.stringify({
13802
+ theme,
13803
+ type: (animation == null ? void 0 : animation.type) ?? null,
13804
+ preset: (animation == null ? void 0 : animation.preset) ?? null,
13805
+ custom: custom ? {
13806
+ type: custom.type ?? null,
13807
+ html: custom.html ?? null,
13808
+ lottie: custom.lottie ?? null
13809
+ } : null
13810
+ });
13811
+ }
13290
13812
  renderShell() {
13291
13813
  this.loaderEl = document.createElement("div");
13292
13814
  this.loaderEl.className = "rai-loader";
13815
+ if (this.config.widgetType === "custom" && !loadErrorSettingsFromStorage(this.config)) {
13816
+ this.loaderEl.classList.add("rai-loader-pending-settings");
13817
+ }
13293
13818
  const textEl = document.createElement("h1");
13294
13819
  textEl.className = "rai-loader-text";
13295
13820
  textEl.textContent = this.config.loadingText;
13296
13821
  this.loaderEl.appendChild(textEl);
13297
13822
  this.shadow.appendChild(this.loaderEl);
13823
+ this.applyLoadingSettings();
13298
13824
  this.fetchAndRenderLoader();
13299
13825
  this.errorEl = document.createElement("div");
13300
13826
  this.errorEl.className = "rai-error";
@@ -13325,11 +13851,21 @@ class BaseWidget extends HTMLElement {
13325
13851
  const cached = loadErrorSettingsFromStorage(this.config);
13326
13852
  if (cached) {
13327
13853
  applyErrorSettingsToState(this.state, cached);
13854
+ this.applyLoadingSettings();
13328
13855
  this.renderLoaderAnimation();
13329
- fetchErrorSettings(this.config, this.state, { skipCache: true }).catch(
13330
- () => {
13331
- }
13332
- );
13856
+ void fetchErrorSettings(this.config, this.state, { skipCache: true }).then(() => {
13857
+ var _a2;
13858
+ if (!this.loaderEl) return;
13859
+ const theme2 = this.config.theme === "dark" ? "dark" : "light";
13860
+ const palette2 = (_a2 = this.state.themePalette) == null ? void 0 : _a2[theme2];
13861
+ if (palette2) this.applyPalette(palette2);
13862
+ if (this.state.font) this.applyFont(this.state.font);
13863
+ this.applyLoadingSettings();
13864
+ if (this.renderedLoaderAnimationKey !== this.getLoadingAnimationRenderKey()) {
13865
+ this.renderLoaderAnimation();
13866
+ }
13867
+ }).catch(() => {
13868
+ });
13333
13869
  return;
13334
13870
  }
13335
13871
  try {
@@ -13344,7 +13880,9 @@ class BaseWidget extends HTMLElement {
13344
13880
  const palette = (_a = this.state.themePalette) == null ? void 0 : _a[theme];
13345
13881
  if (palette) this.applyPalette(palette);
13346
13882
  if (this.state.font) this.applyFont(this.state.font);
13883
+ this.applyLoadingSettings();
13347
13884
  this.renderLoaderAnimation();
13885
+ this.loaderEl.classList.remove("rai-loader-pending-settings");
13348
13886
  }
13349
13887
  /**
13350
13888
  * Append the loading animation above the text. Removes any previous
@@ -13353,6 +13891,7 @@ class BaseWidget extends HTMLElement {
13353
13891
  */
13354
13892
  renderLoaderAnimation() {
13355
13893
  if (!this.loaderEl) return;
13894
+ this.renderedLoaderAnimationKey = this.getLoadingAnimationRenderKey();
13356
13895
  this.clearLottieInstances();
13357
13896
  const existing = this.loaderEl.querySelector(".rai-loader-anim");
13358
13897
  if (existing) existing.remove();
@@ -13433,8 +13972,13 @@ class BaseWidget extends HTMLElement {
13433
13972
  hideLoader() {
13434
13973
  if (!this.loaderEl) return;
13435
13974
  const loader = this.loaderEl;
13975
+ const lottieInstances = this.lottieInstances;
13976
+ this.lottieInstances = [];
13436
13977
  loader.classList.add("fade-out");
13437
- setTimeout(() => loader.remove(), 300);
13978
+ setTimeout(() => {
13979
+ loader.remove();
13980
+ lottieInstances.forEach((instance) => instance.destroy());
13981
+ }, 300);
13438
13982
  this.loaderEl = null;
13439
13983
  }
13440
13984
  /**
@@ -13605,24 +14149,28 @@ class BaseWidget extends HTMLElement {
13605
14149
  if (!banner) return;
13606
14150
  if (((_a = banner.placement) == null ? void 0 : _a.mobileBehavior) === "hide" && device === "mobile")
13607
14151
  return;
13608
- const node = renderBanner(banner, {
13609
- onCtaClick: () => {
13610
- var _a2, _b2, _c;
13611
- fireTracking((_a2 = banner.tracking) == null ? void 0 : _a2.clickUrl);
13612
- this.emit("rai-banner-click", { bannerId: banner.id });
13613
- const url = (_b2 = banner.cta) == null ? void 0 : _b2.url;
13614
- if (!url) return;
13615
- if ((_c = banner.cta) == null ? void 0 : _c.openInNewTab)
13616
- window.open(url, "_blank", "noopener,noreferrer");
13617
- else window.location.href = url;
14152
+ const node = renderBanner(
14153
+ banner,
14154
+ {
14155
+ onCtaClick: () => {
14156
+ var _a2, _b2, _c;
14157
+ fireTracking((_a2 = banner.tracking) == null ? void 0 : _a2.clickUrl);
14158
+ this.emit("rai-banner-click", { bannerId: banner.id });
14159
+ const url = (_b2 = banner.cta) == null ? void 0 : _b2.url;
14160
+ if (!url) return;
14161
+ if ((_c = banner.cta) == null ? void 0 : _c.openInNewTab)
14162
+ window.open(url, "_blank", "noopener,noreferrer");
14163
+ else window.location.href = url;
14164
+ },
14165
+ onDismiss: () => {
14166
+ var _a2;
14167
+ fireTracking((_a2 = banner.tracking) == null ? void 0 : _a2.dismissUrl);
14168
+ this.emit("rai-banner-dismiss", { bannerId: banner.id });
14169
+ this.removeBanner();
14170
+ }
13618
14171
  },
13619
- onDismiss: () => {
13620
- var _a2;
13621
- fireTracking((_a2 = banner.tracking) == null ? void 0 : _a2.dismissUrl);
13622
- this.emit("rai-banner-dismiss", { bannerId: banner.id });
13623
- this.removeBanner();
13624
- }
13625
- });
14172
+ this
14173
+ );
13626
14174
  this.bannerNode = node;
13627
14175
  document.body.appendChild(node);
13628
14176
  fireTracking((_b = banner.tracking) == null ? void 0 : _b.impressionUrl);
@@ -13638,8 +14186,21 @@ class BaseWidget extends HTMLElement {
13638
14186
  this.showError();
13639
14187
  return;
13640
14188
  }
13641
- await fetchErrorSettings(this.config, this.state);
13642
- if (!this.isCurrentInit(initId)) return;
14189
+ if (this.config.bundleUrl) {
14190
+ this.prepareBundleRuntimeEnvironment();
14191
+ warmBundleRuntime(
14192
+ WIDGET_GLOBALS[this.config.widgetType],
14193
+ this.config.bundleUrl
14194
+ );
14195
+ }
14196
+ const errorSettingsPromise = fetchErrorSettings(this.config, this.state);
14197
+ const finishStartup = async (authentication) => {
14198
+ const [authenticated] = await Promise.all([
14199
+ authentication,
14200
+ errorSettingsPromise
14201
+ ]);
14202
+ return authenticated;
14203
+ };
13643
14204
  const launchWidget = () => {
13644
14205
  var _a;
13645
14206
  if (!this.isCurrentInit(initId)) return;
@@ -13665,10 +14226,12 @@ class BaseWidget extends HTMLElement {
13665
14226
  }
13666
14227
  };
13667
14228
  if (this.config.authUrl) {
13668
- const authed2 = await authenticateViaProxy(
13669
- this.config,
13670
- this.state,
13671
- () => this.scheduleRefresh()
14229
+ const authed2 = await finishStartup(
14230
+ authenticateViaProxy(
14231
+ this.config,
14232
+ this.state,
14233
+ () => this.scheduleRefresh()
14234
+ )
13672
14235
  );
13673
14236
  if (!this.isCurrentInit(initId)) return;
13674
14237
  if (authed2) {
@@ -13682,10 +14245,12 @@ class BaseWidget extends HTMLElement {
13682
14245
  if (this.config.embedToken) {
13683
14246
  clearState(this.state);
13684
14247
  clearStorage(this.config);
13685
- const authed2 = await authenticateServerless(
13686
- this.config,
13687
- this.state,
13688
- () => this.scheduleRefresh()
14248
+ const authed2 = await finishStartup(
14249
+ authenticateServerless(
14250
+ this.config,
14251
+ this.state,
14252
+ () => this.scheduleRefresh()
14253
+ )
13689
14254
  );
13690
14255
  if (!this.isCurrentInit(initId)) return;
13691
14256
  if (authed2) {
@@ -13698,10 +14263,12 @@ class BaseWidget extends HTMLElement {
13698
14263
  }
13699
14264
  const hasStored = loadFromStorage(this.config, this.state);
13700
14265
  if (hasStored) {
13701
- const refreshed = await refreshAccessToken(
13702
- this.config,
13703
- this.state,
13704
- () => this.scheduleRefresh()
14266
+ const refreshed = await finishStartup(
14267
+ refreshAccessToken(
14268
+ this.config,
14269
+ this.state,
14270
+ () => this.scheduleRefresh()
14271
+ )
13705
14272
  );
13706
14273
  if (!this.isCurrentInit(initId)) return;
13707
14274
  if (!refreshed) {
@@ -13713,10 +14280,12 @@ class BaseWidget extends HTMLElement {
13713
14280
  launchWidget();
13714
14281
  return;
13715
14282
  }
13716
- const authed = await authenticateServerless(
13717
- this.config,
13718
- this.state,
13719
- () => this.scheduleRefresh()
14283
+ const authed = await finishStartup(
14284
+ authenticateServerless(
14285
+ this.config,
14286
+ this.state,
14287
+ () => this.scheduleRefresh()
14288
+ )
13720
14289
  );
13721
14290
  if (!this.isCurrentInit(initId)) return;
13722
14291
  if (authed) {
@@ -13730,6 +14299,9 @@ class BaseWidget extends HTMLElement {
13730
14299
  return this.isConnected && initId === this.initGeneration;
13731
14300
  }
13732
14301
  teardownMountedWidget() {
14302
+ var _a;
14303
+ (_a = this.releaseAutoThemeDisableLease) == null ? void 0 : _a.call(this);
14304
+ this.releaseAutoThemeDisableLease = void 0;
13733
14305
  if (this.cleanupListener) {
13734
14306
  this.cleanupListener();
13735
14307
  this.cleanupListener = void 0;
@@ -13782,29 +14354,35 @@ class BaseWidget extends HTMLElement {
13782
14354
  );
13783
14355
  }
13784
14356
  // ── Bundle mode (no-iframe) ──────────────────────────────────────────
14357
+ prepareBundleRuntimeEnvironment() {
14358
+ const bundleApiUrl = this.config.v2ApiUrl || resolveV2ApiUrl(this.config.domainKey);
14359
+ const runtimeWindow = window;
14360
+ if (!runtimeWindow.DomainKey) {
14361
+ runtimeWindow.DomainKey = toInternalDomainKey(this.config.domainKey);
14362
+ }
14363
+ if (!runtimeWindow.api_url) {
14364
+ runtimeWindow.api_url = bundleApiUrl;
14365
+ }
14366
+ runtimeWindow.__IS_WIDGET__ = true;
14367
+ const colorMode = this.config.theme === "dark" ? "dark" : "light";
14368
+ const defaultThemeName = colorMode === "dark" ? "dark-knight" : "white-smoke";
14369
+ document.documentElement.setAttribute("data-theme", defaultThemeName);
14370
+ runtimeWindow.currentTheme = colorMode;
14371
+ runtimeWindow.__FORCE_COLOR_MODE__ = colorMode;
14372
+ runtimeWindow.__WIDGET_STORAGE_KEY__ = `color-schema-${this.config.widgetType}-${this.config.widgetId}`;
14373
+ return { bundleApiUrl, colorMode };
14374
+ }
13785
14375
  async mountWidget(initId) {
14376
+ var _a;
13786
14377
  let container = null;
13787
14378
  try {
13788
14379
  this.teardownMountedWidget();
13789
- const bundleApiUrl = this.config.v2ApiUrl || resolveV2ApiUrl(this.config.domainKey);
13790
- const w = window;
13791
- if (!w.DomainKey) {
13792
- w.DomainKey = toInternalDomainKey(this.config.domainKey);
14380
+ const autoHeight = this.config.height.trim().toLowerCase() === "auto";
14381
+ if (this.config.widgetType === "custom") {
14382
+ this.releaseAutoThemeDisableLease = acquireAutoThemeDisableLease();
13793
14383
  }
13794
- if (!w.api_url) {
13795
- w.api_url = bundleApiUrl;
13796
- }
13797
- window.__IS_WIDGET__ = true;
14384
+ const { bundleApiUrl, colorMode } = this.prepareBundleRuntimeEnvironment();
13798
14385
  window.guest_token = this.state.accessToken;
13799
- const colorMode = this.config.theme === "dark" ? "dark" : "light";
13800
- const defaultThemeName = colorMode === "dark" ? "dark-knight" : "white-smoke";
13801
- document.documentElement.setAttribute("data-theme", defaultThemeName);
13802
- window.currentTheme = colorMode;
13803
- window.__FORCE_COLOR_MODE__ = colorMode;
13804
- window.__WIDGET_STORAGE_KEY__ = `color-schema-${this.config.widgetType}-${this.config.widgetId}`;
13805
- if (this.state.loadingAnimation) {
13806
- window.loadingAnimation = this.state.loadingAnimation;
13807
- }
13808
14386
  const globalName = WIDGET_GLOBALS[this.config.widgetType];
13809
14387
  const widgetGlobal = await getOrLoadBundleRuntime(
13810
14388
  globalName,
@@ -13815,10 +14393,15 @@ class BaseWidget extends HTMLElement {
13815
14393
  const hideNestedBundleUntilReady = this.config.widgetType === "custom";
13816
14394
  container.className = "rai-widget-root";
13817
14395
  container.setAttribute("data-rai-widget-root", "true");
14396
+ container.__raiWidgetRuntime = {
14397
+ colorMode,
14398
+ loadingAnimation: this.state.loadingAnimation,
14399
+ loadingSettings: this.state.loadingSettings
14400
+ };
13818
14401
  container.style.cssText = [
13819
14402
  "position: relative",
13820
14403
  "width: 100%",
13821
- "height: 100%",
14404
+ `height: ${autoHeight ? "auto" : "100%"}`,
13822
14405
  "color: var(--text-1)",
13823
14406
  "background: transparent",
13824
14407
  "font-family: var(--rai-loader-font, 'Roboto', system-ui, -apple-system, sans-serif)",
@@ -13853,19 +14436,28 @@ class BaseWidget extends HTMLElement {
13853
14436
  // post. Mirrors the iframe behavior, where `isOpenWidget` is only
13854
14437
  // injected by SSR for the explicit `/open-widget` route.
13855
14438
  isOpenWidget: !this.state.accessToken,
13856
- defaultColorSchema: this.config.theme === "dark" ? "dark" : "light",
13857
- requestHostCallback: async (callbackName, payload) => {
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
- );
13868
- }
14439
+ defaultColorSchema: this.config.widgetType === "custom" && !this.config.themeExplicit ? null : colorMode,
14440
+ // Bundle loading screens are rendered beneath an instance-scoped
14441
+ // provider. Do not put these values on window: pages can mount several
14442
+ // widget types at once.
14443
+ colorMode,
14444
+ loadingAnimation: this.state.loadingAnimation,
14445
+ loadingSettings: this.state.loadingSettings,
14446
+ widgetData: this.config.widgetType === "custom" ? this.state.widgetData || void 0 : void 0,
14447
+ // Auto-height embeds delegate vertical sizing and scrolling to the
14448
+ // host page. Bundle consumers use this explicit contract instead of
14449
+ // inferring the SDK host element from their rendered DOM.
14450
+ autoHeight,
14451
+ requestHostCallback: (callbackName, payload) => dispatchHostCallback({
14452
+ callbacks: this.readRuntimeCallbacks(),
14453
+ callbackName,
14454
+ payload: enrichHostCallbackPayload(
14455
+ payload,
14456
+ resolveHostUserIdentifiers(this.config)
14457
+ ),
14458
+ hostWidgetType: this.config.widgetType,
14459
+ transport: "bundle"
14460
+ })
13869
14461
  });
13870
14462
  await waitForBundleMountReadiness(mountResult, firstPaint);
13871
14463
  if (!this.isCurrentInit(initId) || !container.isConnected) {
@@ -13881,6 +14473,8 @@ class BaseWidget extends HTMLElement {
13881
14473
  return;
13882
14474
  }
13883
14475
  console.error("[rai-widget] Bundle mount failed:", err);
14476
+ (_a = this.releaseAutoThemeDisableLease) == null ? void 0 : _a.call(this);
14477
+ this.releaseAutoThemeDisableLease = void 0;
13884
14478
  this.showError();
13885
14479
  }
13886
14480
  }
@@ -14056,17 +14650,19 @@ class CustomWidget extends BaseWidget {
14056
14650
  const base = config.widgetUrl.endsWith("custom-widget") ? `${config.widgetUrl}/${config.widgetId}` : config.widgetUrl;
14057
14651
  try {
14058
14652
  const u = new URL(base);
14059
- u.searchParams.set("color", config.theme);
14653
+ u.searchParams.set("auth", "postmessage");
14654
+ if (config.themeExplicit) u.searchParams.set("color", config.theme);
14060
14655
  if (config.locale) u.searchParams.set("locale", config.locale);
14061
14656
  return u.toString();
14062
14657
  } catch {
14063
- const params = [`color=${config.theme}`];
14658
+ const params = ["auth=postmessage"];
14659
+ if (config.themeExplicit) params.push(`color=${config.theme}`);
14064
14660
  if (config.locale) params.push(`locale=${encodeURIComponent(config.locale)}`);
14065
- return `${base}?${params.join("&")}`;
14661
+ return params.length > 0 ? `${base}?${params.join("&")}` : base;
14066
14662
  }
14067
14663
  }
14068
14664
  }
14069
- console.log(`[rai-widget] v${"1.7.1"}`);
14665
+ console.log(`[rai-widget] v${"1.8.0"}`);
14070
14666
  class StoreWidgetCompat extends StoreWidget {
14071
14667
  }
14072
14668
  const WIDGET_REGISTRY = [
@@ -14130,7 +14726,7 @@ function exposePublicApi() {
14130
14726
  })();
14131
14727
  const widget = container == null ? void 0 : container.querySelector(ALL_WIDGET_SELECTOR);
14132
14728
  window.ReturningAIWidget = {
14133
- version: "1.7.1",
14729
+ version: "1.8.0",
14134
14730
  reload: () => (widget == null ? void 0 : widget.reload()) ?? Promise.resolve(),
14135
14731
  logout: () => (widget == null ? void 0 : widget.logoutPublic()) ?? Promise.resolve(),
14136
14732
  isAuthenticated: () => (widget == null ? void 0 : widget.isAuthenticated()) ?? false,
@@ -14146,6 +14742,9 @@ export {
14146
14742
  ChannelWidget,
14147
14743
  CurrencyWidget,
14148
14744
  CustomWidget,
14745
+ MILESTONE_CTA_CLICK_CALLBACK_NAME,
14746
+ MILESTONE_CTA_CLICK_EVENT,
14747
+ MILESTONE_CTA_CLICK_SCOPE,
14149
14748
  MilestoneWidget,
14150
14749
  ReferralWidget,
14151
14750
  STORE_CALLBACK_FIELD_OPTIONS_CALLBACK_NAME,