@active-reach/web-sdk 1.34.1 → 1.35.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -5027,7 +5027,7 @@ function disposeActiveWebChat() {
5027
5027
  activeInstance = null;
5028
5028
  }
5029
5029
  const SVG_NS = "http://www.w3.org/2000/svg";
5030
- function el(tag, css, text) {
5030
+ function el$1(tag, css, text) {
5031
5031
  const e = document.createElement(tag);
5032
5032
  if (css) e.style.cssText = css;
5033
5033
  if (text != null) e.textContent = text;
@@ -5048,13 +5048,13 @@ function star(filled, size) {
5048
5048
  return svg;
5049
5049
  }
5050
5050
  function stars(rating, size = 15) {
5051
- const wrap = el("span", "display:inline-flex;gap:2px;vertical-align:middle;");
5051
+ const wrap = el$1("span", "display:inline-flex;gap:2px;vertical-align:middle;");
5052
5052
  wrap.setAttribute("aria-label", `${rating} out of 5`);
5053
5053
  for (let i = 1; i <= 5; i++) wrap.appendChild(star(i <= rating, size));
5054
5054
  return wrap;
5055
5055
  }
5056
5056
  function verifiedBadge() {
5057
- const b = el(
5057
+ const b = el$1(
5058
5058
  "span",
5059
5059
  "display:inline-flex;align-items:center;gap:3px;font-size:12px;font-weight:600;color:#059669;"
5060
5060
  );
@@ -5071,12 +5071,12 @@ function verifiedBadge() {
5071
5071
  p.setAttribute("stroke-linejoin", "round");
5072
5072
  svg.appendChild(p);
5073
5073
  b.appendChild(svg);
5074
- b.appendChild(el("span", "", "Verified purchase"));
5074
+ b.appendChild(el$1("span", "", "Verified purchase"));
5075
5075
  return b;
5076
5076
  }
5077
5077
  function avatar(name, accent) {
5078
5078
  const initial = (name.trim()[0] || "?").toUpperCase();
5079
- const a = el(
5079
+ const a = el$1(
5080
5080
  "span",
5081
5081
  `flex:0 0 auto;width:34px;height:34px;border-radius:999px;display:inline-flex;align-items:center;justify-content:center;font-size:14px;font-weight:700;color:${accent};background:${accent}1a;`,
5082
5082
  initial
@@ -5084,7 +5084,7 @@ function avatar(name, accent) {
5084
5084
  return a;
5085
5085
  }
5086
5086
  function thumbBtn(up, count, reviewId, creds) {
5087
- const btn = el(
5087
+ const btn = el$1(
5088
5088
  "button",
5089
5089
  "display:inline-flex;align-items:center;gap:5px;font-size:13px;color:#6b7280;background:none;border:none;cursor:pointer;padding:4px 6px;border-radius:8px;font-family:inherit;"
5090
5090
  );
@@ -5101,7 +5101,7 @@ function thumbBtn(up, count, reviewId, creds) {
5101
5101
  p.setAttribute("fill", "currentColor");
5102
5102
  svg.appendChild(p);
5103
5103
  btn.appendChild(svg);
5104
- const c = el("span", "", String(count));
5104
+ const c = el$1("span", "", String(count));
5105
5105
  btn.appendChild(c);
5106
5106
  const key = `aegis_rv_voted_${reviewId}`;
5107
5107
  let voted = false;
@@ -5179,7 +5179,7 @@ function renderReviewsInline(ctx, target, creds) {
5179
5179
  const productId = cfg.getAttribute("data-product-id") || ctx.campaign.product_id || null;
5180
5180
  const state = { sort: "recent", withPhotos: false };
5181
5181
  target.innerHTML = "";
5182
- target.appendChild(el("div", `font-family:${IN_APP_FONT_STACK};font-size:13px;color:#9ca3af;padding:10px 0;`, "Loading reviews…"));
5182
+ target.appendChild(el$1("div", `font-family:${IN_APP_FONT_STACK};font-size:13px;color:#9ca3af;padding:10px 0;`, "Loading reviews…"));
5183
5183
  function buildUrl() {
5184
5184
  const url = new URL("/v1/reviews/public", creds.apiHost);
5185
5185
  if (productId) url.searchParams.set("product_id", productId);
@@ -5194,12 +5194,12 @@ function renderReviewsInline(ctx, target, creds) {
5194
5194
  let listContainer = null;
5195
5195
  function reviewCard(r) {
5196
5196
  var _a, _b, _c;
5197
- const li = el("li", "padding:22px 0;border-top:1px solid #f0f1f3;");
5198
- const head = el("div", "display:flex;align-items:center;gap:10px;");
5197
+ const li = el$1("li", "padding:22px 0;border-top:1px solid #f0f1f3;");
5198
+ const head = el$1("div", "display:flex;align-items:center;gap:10px;");
5199
5199
  head.appendChild(avatar(((_a = r.reviewer_snapshot) == null ? void 0 : _a.name) ?? "Customer", accent));
5200
- const idn = el("div", "display:flex;flex-direction:column;gap:2px;min-width:0;");
5201
- const nameRow = el("div", "display:flex;flex-wrap:wrap;align-items:center;gap:8px;");
5202
- nameRow.appendChild(el("span", "font-size:15px;font-weight:700;color:#111827;", ((_b = r.reviewer_snapshot) == null ? void 0 : _b.name) ?? "Customer"));
5200
+ const idn = el$1("div", "display:flex;flex-direction:column;gap:2px;min-width:0;");
5201
+ const nameRow = el$1("div", "display:flex;flex-wrap:wrap;align-items:center;gap:8px;");
5202
+ nameRow.appendChild(el$1("span", "font-size:15px;font-weight:700;color:#111827;", ((_b = r.reviewer_snapshot) == null ? void 0 : _b.name) ?? "Customer"));
5203
5203
  if (r.verified_purchase) nameRow.appendChild(verifiedBadge());
5204
5204
  idn.appendChild(nameRow);
5205
5205
  idn.appendChild(stars(r.rating ?? 0, 14));
@@ -5207,7 +5207,7 @@ function renderReviewsInline(ctx, target, creds) {
5207
5207
  if (r.created_at) {
5208
5208
  const d = new Date(r.created_at);
5209
5209
  if (!Number.isNaN(d.getTime())) {
5210
- head.appendChild(el(
5210
+ head.appendChild(el$1(
5211
5211
  "span",
5212
5212
  "margin-left:auto;font-size:12px;color:#9ca3af;white-space:nowrap;",
5213
5213
  d.toLocaleDateString(void 0, { day: "numeric", month: "short", year: "numeric" })
@@ -5216,10 +5216,10 @@ function renderReviewsInline(ctx, target, creds) {
5216
5216
  }
5217
5217
  li.appendChild(head);
5218
5218
  if (r.review_text) {
5219
- li.appendChild(el("p", "margin:12px 0 0;font-size:15px;line-height:1.6;color:#374151;", r.review_text));
5219
+ li.appendChild(el$1("p", "margin:12px 0 0;font-size:15px;line-height:1.6;color:#374151;", r.review_text));
5220
5220
  }
5221
5221
  if (r.media && r.media.length > 0) {
5222
- const gallery = el("div", "display:flex;flex-wrap:wrap;gap:8px;margin-top:12px;");
5222
+ const gallery = el$1("div", "display:flex;flex-wrap:wrap;gap:8px;margin-top:12px;");
5223
5223
  for (const m2 of r.media.slice(0, 6)) {
5224
5224
  const safe = ctx.sanitizeUrl(m2.url);
5225
5225
  if (!safe) continue;
@@ -5232,22 +5232,22 @@ function renderReviewsInline(ctx, target, creds) {
5232
5232
  }
5233
5233
  if (gallery.childElementCount) li.appendChild(gallery);
5234
5234
  }
5235
- const foot = el("div", "display:flex;align-items:center;gap:6px;margin-top:12px;");
5236
- foot.appendChild(el("span", "font-size:13px;color:#9ca3af;margin-right:2px;", "Was this helpful?"));
5235
+ const foot = el$1("div", "display:flex;align-items:center;gap:6px;margin-top:12px;");
5236
+ foot.appendChild(el$1("span", "font-size:13px;color:#9ca3af;margin-right:2px;", "Was this helpful?"));
5237
5237
  foot.appendChild(thumbBtn(true, r.helpful_count ?? 0, r.id, creds));
5238
5238
  foot.appendChild(thumbBtn(false, r.not_helpful_count ?? 0, r.id, creds));
5239
5239
  li.appendChild(foot);
5240
5240
  if ((_c = r.operator_reply) == null ? void 0 : _c.text) {
5241
- const reply = el(
5241
+ const reply = el$1(
5242
5242
  "div",
5243
5243
  `margin-top:14px;margin-left:44px;border-left:3px solid ${accent};background:${accent}0d;border-radius:0 12px 12px 0;padding:12px 14px;`
5244
5244
  );
5245
- const rlabel = el("div", "display:flex;align-items:center;gap:6px;margin-bottom:5px;");
5246
- rlabel.appendChild(el("span", `width:7px;height:7px;border-radius:999px;background:${accent};display:inline-block;`));
5247
- rlabel.appendChild(el("span", `font-size:12px;font-weight:700;color:${accent};`, brand));
5248
- rlabel.appendChild(el("span", "font-size:12px;color:#9ca3af;", "· replied"));
5245
+ const rlabel = el$1("div", "display:flex;align-items:center;gap:6px;margin-bottom:5px;");
5246
+ rlabel.appendChild(el$1("span", `width:7px;height:7px;border-radius:999px;background:${accent};display:inline-block;`));
5247
+ rlabel.appendChild(el$1("span", `font-size:12px;font-weight:700;color:${accent};`, brand));
5248
+ rlabel.appendChild(el$1("span", "font-size:12px;color:#9ca3af;", "· replied"));
5249
5249
  reply.appendChild(rlabel);
5250
- reply.appendChild(el("p", "margin:0;font-size:14px;line-height:1.55;color:#4b5563;", r.operator_reply.text));
5250
+ reply.appendChild(el$1("p", "margin:0;font-size:14px;line-height:1.55;color:#4b5563;", r.operator_reply.text));
5251
5251
  li.appendChild(reply);
5252
5252
  }
5253
5253
  return li;
@@ -5256,15 +5256,15 @@ function renderReviewsInline(ctx, target, creds) {
5256
5256
  if (!listContainer) return;
5257
5257
  listContainer.innerHTML = "";
5258
5258
  if (items.length === 0) {
5259
- listContainer.appendChild(el("p", "padding:20px 0;font-size:14px;color:#9ca3af;text-align:center;", "No reviews match this filter."));
5259
+ listContainer.appendChild(el$1("p", "padding:20px 0;font-size:14px;color:#9ca3af;text-align:center;", "No reviews match this filter."));
5260
5260
  return;
5261
5261
  }
5262
- const ul = el("ul", "list-style:none;margin:0;padding:0;");
5262
+ const ul = el$1("ul", "list-style:none;margin:0;padding:0;");
5263
5263
  for (const r of items) ul.appendChild(reviewCard(r));
5264
5264
  listContainer.appendChild(ul);
5265
5265
  }
5266
5266
  function pill(label, active, onClick) {
5267
- const b = el(
5267
+ const b = el$1(
5268
5268
  "button",
5269
5269
  `font-size:13px;font-weight:600;padding:7px 16px;border-radius:999px;cursor:pointer;font-family:inherit;` + (active ? `background:${accent};color:#fff;border:1px solid ${accent};` : "background:#fff;color:#374151;border:1px solid #e5e7eb;"),
5270
5270
  label
@@ -5273,7 +5273,7 @@ function renderReviewsInline(ctx, target, creds) {
5273
5273
  return b;
5274
5274
  }
5275
5275
  function controls(rerender) {
5276
- const bar = el("div", "display:flex;flex-wrap:wrap;align-items:center;gap:8px;margin:18px 0 4px;");
5276
+ const bar = el$1("div", "display:flex;flex-wrap:wrap;align-items:center;gap:8px;margin:18px 0 4px;");
5277
5277
  const sel = document.createElement("select");
5278
5278
  sel.style.cssText = `font-size:13px;font-weight:600;padding:7px 30px 7px 14px;border:1px solid #e5e7eb;border-radius:999px;background:#fff;color:#374151;cursor:pointer;font-family:inherit;appearance:none;background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%236b7280' stroke-width='2'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E");background-repeat:no-repeat;background-position:right 12px center;`;
5279
5279
  for (const s of SORTS) {
@@ -5300,29 +5300,29 @@ function renderReviewsInline(ctx, target, creds) {
5300
5300
  return bar;
5301
5301
  }
5302
5302
  function distributionPanel(dist, total) {
5303
- const box = el("div", "flex:0 1 300px;width:300px;max-width:100%;display:flex;flex-direction:column;gap:7px;");
5303
+ const box = el$1("div", "flex:0 1 300px;width:300px;max-width:100%;display:flex;flex-direction:column;gap:7px;");
5304
5304
  for (let r = 5; r >= 1; r--) {
5305
5305
  const n = dist[String(r)] ?? 0;
5306
5306
  const pct = total > 0 ? Math.round(n / total * 100) : 0;
5307
- const row = el("div", "display:flex;align-items:center;gap:10px;font-size:13px;color:#6b7280;");
5308
- const lbl = el("span", "width:30px;display:inline-flex;align-items:center;gap:3px;color:#374151;font-weight:600;", String(r));
5307
+ const row = el$1("div", "display:flex;align-items:center;gap:10px;font-size:13px;color:#6b7280;");
5308
+ const lbl = el$1("span", "width:30px;display:inline-flex;align-items:center;gap:3px;color:#374151;font-weight:600;", String(r));
5309
5309
  lbl.appendChild(star(true, 11));
5310
5310
  row.appendChild(lbl);
5311
- const track = el("div", "flex:1;height:8px;background:#f0f1f3;border-radius:999px;overflow:hidden;");
5312
- track.appendChild(el("div", `width:${pct}%;height:100%;background:${accent};border-radius:999px;`));
5311
+ const track = el$1("div", "flex:1;height:8px;background:#f0f1f3;border-radius:999px;overflow:hidden;");
5312
+ track.appendChild(el$1("div", `width:${pct}%;height:100%;background:${accent};border-radius:999px;`));
5313
5313
  row.appendChild(track);
5314
- row.appendChild(el("span", "width:24px;text-align:right;font-variant-numeric:tabular-nums;", String(n)));
5314
+ row.appendChild(el$1("span", "width:24px;text-align:right;font-variant-numeric:tabular-nums;", String(n)));
5315
5315
  box.appendChild(row);
5316
5316
  }
5317
5317
  return box;
5318
5318
  }
5319
5319
  function aiSummaryCard(summary) {
5320
- const card = el(
5320
+ const card = el$1(
5321
5321
  "div",
5322
5322
  "position:relative;border-radius:18px;padding:18px 20px;margin-bottom:24px;background:linear-gradient(135deg,#faf5ff 0%,#f5f3ff 100%);border:1px solid #ede9fe;"
5323
5323
  );
5324
- const head = el("div", "display:flex;align-items:center;justify-content:space-between;margin-bottom:8px;");
5325
- const left = el("div", "display:flex;align-items:center;gap:7px;");
5324
+ const head = el$1("div", "display:flex;align-items:center;justify-content:space-between;margin-bottom:8px;");
5325
+ const left = el$1("div", "display:flex;align-items:center;gap:7px;");
5326
5326
  const sp = document.createElementNS(SVG_NS, "svg");
5327
5327
  sp.setAttribute("viewBox", "0 0 24 24");
5328
5328
  sp.setAttribute("width", "16");
@@ -5332,17 +5332,17 @@ function renderReviewsInline(ctx, target, creds) {
5332
5332
  spp.setAttribute("fill", "#7c3aed");
5333
5333
  sp.appendChild(spp);
5334
5334
  left.appendChild(sp);
5335
- left.appendChild(el("span", "font-size:12px;font-weight:800;letter-spacing:.07em;color:#6d28d9;text-transform:uppercase;", "What customers say"));
5335
+ left.appendChild(el$1("span", "font-size:12px;font-weight:800;letter-spacing:.07em;color:#6d28d9;text-transform:uppercase;", "What customers say"));
5336
5336
  head.appendChild(left);
5337
- head.appendChild(el("span", "font-size:11px;font-weight:600;color:#a78bda;", "AI-generated"));
5337
+ head.appendChild(el$1("span", "font-size:11px;font-weight:600;color:#a78bda;", "AI-generated"));
5338
5338
  card.appendChild(head);
5339
- card.appendChild(el("p", "margin:0;font-size:15px;line-height:1.6;color:#3b2a63;", summary.text));
5340
- card.appendChild(el("p", "margin:8px 0 0;font-size:12px;color:#a78bda;text-align:right;", `from ${summary.review_count} reviews`));
5339
+ card.appendChild(el$1("p", "margin:0;font-size:15px;line-height:1.6;color:#3b2a63;", summary.text));
5340
+ card.appendChild(el$1("p", "margin:8px 0 0;font-size:12px;color:#a78bda;text-align:right;", `from ${summary.review_count} reviews`));
5341
5341
  return card;
5342
5342
  }
5343
5343
  function renderWall(data) {
5344
5344
  target.innerHTML = "";
5345
- const root = el(
5345
+ const root = el$1(
5346
5346
  "section",
5347
5347
  `font-family:${IN_APP_FONT_STACK};color:#111827;max-width:860px;margin:0 auto;-webkit-font-smoothing:antialiased;`
5348
5348
  );
@@ -5350,25 +5350,25 @@ function renderReviewsInline(ctx, target, creds) {
5350
5350
  const summary = data.aggregate.ai_summary;
5351
5351
  if (summary && summary.text) root.appendChild(aiSummaryCard(summary));
5352
5352
  if (data.aggregate.count === 0) {
5353
- root.appendChild(el("p", "font-size:15px;color:#9ca3af;padding:6px 0;", "No reviews yet — be the first to share your experience."));
5353
+ root.appendChild(el$1("p", "font-size:15px;color:#9ca3af;padding:6px 0;", "No reviews yet — be the first to share your experience."));
5354
5354
  target.appendChild(root);
5355
5355
  return;
5356
5356
  }
5357
- const header = el("div", "display:flex;flex-wrap:wrap;align-items:center;gap:24px 40px;padding-bottom:4px;");
5358
- const ratingBlock = el("div", "display:flex;flex-direction:column;gap:4px;");
5359
- const topRow = el("div", "display:flex;align-items:center;gap:12px;");
5357
+ const header = el$1("div", "display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;gap:24px 40px;padding-bottom:4px;");
5358
+ const ratingBlock = el$1("div", "display:flex;flex-direction:column;gap:4px;");
5359
+ const topRow = el$1("div", "display:flex;align-items:center;gap:12px;");
5360
5360
  const avg = data.aggregate.avg_rating ?? 0;
5361
5361
  topRow.appendChild(stars(Math.round(avg), 20));
5362
- topRow.appendChild(el("span", "font-size:32px;font-weight:800;line-height:1;letter-spacing:-0.02em;", avg ? avg.toFixed(1) : "—"));
5362
+ topRow.appendChild(el$1("span", "font-size:32px;font-weight:800;line-height:1;letter-spacing:-0.02em;", avg ? avg.toFixed(1) : "—"));
5363
5363
  ratingBlock.appendChild(topRow);
5364
- ratingBlock.appendChild(el("span", "font-size:13px;color:#6b7280;", `${data.aggregate.count} review${data.aggregate.count === 1 ? "" : "s"} · 100% verified`));
5364
+ ratingBlock.appendChild(el$1("span", "font-size:13px;color:#6b7280;", `${data.aggregate.count} review${data.aggregate.count === 1 ? "" : "s"} · 100% verified`));
5365
5365
  header.appendChild(ratingBlock);
5366
5366
  header.appendChild(distributionPanel(data.aggregate.distribution, data.aggregate.count));
5367
5367
  root.appendChild(header);
5368
5368
  root.appendChild(controls(() => {
5369
5369
  void fetchReviews().then((d) => renderList((d == null ? void 0 : d.items) ?? []));
5370
5370
  }));
5371
- listContainer = el("div", "margin-top:2px;");
5371
+ listContainer = el$1("div", "margin-top:2px;");
5372
5372
  root.appendChild(listContainer);
5373
5373
  renderList(data.items);
5374
5374
  target.appendChild(root);
@@ -5380,23 +5380,23 @@ function renderReviewsInline(ctx, target, creds) {
5380
5380
  var _a;
5381
5381
  target.innerHTML = "";
5382
5382
  if (data.aggregate.count === 0) return;
5383
- const root = el(
5383
+ const root = el$1(
5384
5384
  "section",
5385
5385
  `font-family:${IN_APP_FONT_STACK};color:#111827;max-width:860px;margin:0 auto;border:1px solid #f0f1f3;border-radius:16px;padding:16px 18px;`
5386
5386
  );
5387
- const line = el("div", "display:flex;align-items:center;gap:8px;");
5387
+ const line = el$1("div", "display:flex;align-items:center;gap:8px;");
5388
5388
  const avg = data.aggregate.avg_rating ?? 0;
5389
5389
  line.appendChild(stars(Math.round(avg), 16));
5390
- line.appendChild(el("span", "font-size:16px;font-weight:700;", avg ? avg.toFixed(1) : "—"));
5391
- line.appendChild(el("span", "font-size:13px;color:#6b7280;", `(${data.aggregate.count})`));
5390
+ line.appendChild(el$1("span", "font-size:16px;font-weight:700;", avg ? avg.toFixed(1) : "—"));
5391
+ line.appendChild(el$1("span", "font-size:13px;color:#6b7280;", `(${data.aggregate.count})`));
5392
5392
  line.appendChild(verifiedBadge());
5393
5393
  root.appendChild(line);
5394
5394
  const top = data.items.find((i) => i.review_text);
5395
5395
  if (top && top.review_text) {
5396
- root.appendChild(el("p", "margin:10px 0 0;font-size:15px;color:#374151;line-height:1.5;", `“${top.review_text}”`));
5397
- root.appendChild(el("span", "font-size:13px;color:#9ca3af;", `— ${((_a = top.reviewer_snapshot) == null ? void 0 : _a.name) ?? "Customer"}`));
5396
+ root.appendChild(el$1("p", "margin:10px 0 0;font-size:15px;color:#374151;line-height:1.5;", `“${top.review_text}”`));
5397
+ root.appendChild(el$1("span", "font-size:13px;color:#9ca3af;", `— ${((_a = top.reviewer_snapshot) == null ? void 0 : _a.name) ?? "Customer"}`));
5398
5398
  }
5399
- const seeAll = el("button", `margin-top:12px;font-size:14px;font-weight:700;color:${accent};background:none;border:none;cursor:pointer;padding:0;font-family:inherit;`, "See all reviews →");
5399
+ const seeAll = el$1("button", `margin-top:12px;font-size:14px;font-weight:700;color:${accent};background:none;border:none;cursor:pointer;padding:0;font-family:inherit;`, "See all reviews →");
5400
5400
  seeAll.addEventListener("click", () => renderWall(data));
5401
5401
  root.appendChild(seeAll);
5402
5402
  target.appendChild(root);
@@ -5420,10 +5420,10 @@ function renderReviewsOverlay(ctx, creds) {
5420
5420
  overlay.style.cssText = "position:fixed;inset:0;background:rgba(17,24,39,0.5);display:flex;align-items:flex-end;justify-content:center;z-index:99999;";
5421
5421
  const sheet = document.createElement("div");
5422
5422
  sheet.style.cssText = `background:#fff;color:#111827;max-width:680px;width:100%;max-height:84vh;overflow-y:auto;border-radius:24px 24px 0 0;padding:18px 18px 28px;font-family:${IN_APP_FONT_STACK};box-shadow:0 -16px 40px rgba(0,0,0,0.14);`;
5423
- sheet.appendChild(el("div", "width:38px;height:4px;border-radius:999px;background:#e5e7eb;margin:0 auto 14px;"));
5424
- const bar = el("div", "display:flex;justify-content:space-between;align-items:center;margin-bottom:10px;");
5425
- bar.appendChild(el("div", "font-weight:800;font-size:17px;", ctx.campaign.title || "Customer reviews"));
5426
- const close = el("button", "background:none;border:none;cursor:pointer;padding:4px 8px;color:#6b7280;");
5423
+ sheet.appendChild(el$1("div", "width:38px;height:4px;border-radius:999px;background:#e5e7eb;margin:0 auto 14px;"));
5424
+ const bar = el$1("div", "display:flex;justify-content:space-between;align-items:center;margin-bottom:10px;");
5425
+ bar.appendChild(el$1("div", "font-weight:800;font-size:17px;", ctx.campaign.title || "Customer reviews"));
5426
+ const close = el$1("button", "background:none;border:none;cursor:pointer;padding:4px 8px;color:#6b7280;");
5427
5427
  const x = document.createElementNS(SVG_NS, "svg");
5428
5428
  x.setAttribute("viewBox", "0 0 24 24");
5429
5429
  x.setAttribute("width", "20");
@@ -5442,7 +5442,7 @@ function renderReviewsOverlay(ctx, creds) {
5442
5442
  });
5443
5443
  bar.appendChild(close);
5444
5444
  sheet.appendChild(bar);
5445
- const body = el("div");
5445
+ const body = el$1("div");
5446
5446
  const pid = ctx.campaign.product_id;
5447
5447
  if (pid) body.setAttribute("data-product-id", pid);
5448
5448
  sheet.appendChild(body);
@@ -5456,6 +5456,161 @@ function renderReviewsOverlay(ctx, creds) {
5456
5456
  document.body.appendChild(overlay);
5457
5457
  renderReviewsInline(ctx, body, creds);
5458
5458
  }
5459
+ const STAR_PATH = "M12 2L15.09 8.26 22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z";
5460
+ function el(tag, css, txt) {
5461
+ const e = document.createElement(tag);
5462
+ e.style.cssText = css;
5463
+ if (txt != null) e.textContent = txt;
5464
+ return e;
5465
+ }
5466
+ function starSvg(filled, accent, size = 26) {
5467
+ const svg = document.createElementNS("http://www.w3.org/2000/svg", "svg");
5468
+ svg.setAttribute("viewBox", "0 0 24 24");
5469
+ svg.setAttribute("width", String(size));
5470
+ svg.setAttribute("height", String(size));
5471
+ svg.style.cssText = "display:block;transition:transform .1s ease;";
5472
+ const path = document.createElementNS("http://www.w3.org/2000/svg", "path");
5473
+ path.setAttribute("d", STAR_PATH);
5474
+ path.setAttribute("fill", "#d1d5db");
5475
+ svg.appendChild(path);
5476
+ return svg;
5477
+ }
5478
+ function readContext(target) {
5479
+ const cfg = target.closest("[data-aegis-slot]") ?? target;
5480
+ let items = [];
5481
+ const raw = cfg.getAttribute("data-rateable-items");
5482
+ if (raw) {
5483
+ try {
5484
+ const parsed = JSON.parse(raw);
5485
+ if (Array.isArray(parsed)) {
5486
+ items = parsed.filter((p) => !!p && typeof p === "object" && "product_id" in p).map((p) => ({ product_id: String(p.product_id), name: p.name ?? null }));
5487
+ }
5488
+ } catch {
5489
+ }
5490
+ }
5491
+ return {
5492
+ items,
5493
+ orderId: cfg.getAttribute("data-order-id"),
5494
+ billCode: cfg.getAttribute("data-bill-code"),
5495
+ token: cfg.getAttribute("data-token"),
5496
+ accent: cfg.getAttribute("data-accent"),
5497
+ reviewsUrl: cfg.getAttribute("data-reviews-url"),
5498
+ // The bill knows its customer server-side; the SDK may still be anonymous
5499
+ // on a fresh visit. Prefer the slot-stamped contact so the per-item write
5500
+ // (contact_id NOT NULL) succeeds. On untrusted origins the server ignores
5501
+ // this and uses the token-resolved contact instead.
5502
+ contactId: cfg.getAttribute("data-contact-id")
5503
+ };
5504
+ }
5505
+ function renderProductRatingInline(ctx, target, creds) {
5506
+ if (typeof document === "undefined" || !(creds == null ? void 0 : creds.apiHost) || !(creds == null ? void 0 : creds.writeKey)) return false;
5507
+ ensureInAppFont();
5508
+ const { items, orderId, billCode, token, accent: slotAccent, reviewsUrl, contactId: slotContact } = readContext(target);
5509
+ if (items.length === 0 || !orderId && !billCode && !token) return false;
5510
+ const ic = ctx.campaign.interactive_config || {};
5511
+ const accent = ctx.sanitizeColor(
5512
+ slotAccent || ctx.campaign.background_color || "#4169e1"
5513
+ );
5514
+ const title = ic.question || "Rate your items";
5515
+ const scores = {};
5516
+ target.innerHTML = "";
5517
+ const card = el(
5518
+ "div",
5519
+ `font-family:${IN_APP_FONT_STACK};border:1px solid #f1f1f3;border-radius:14px;background:#fff;padding:14px 16px;`
5520
+ );
5521
+ card.appendChild(el("p", "margin:0;font-size:14px;font-weight:700;color:#111827;", title));
5522
+ const list = el("ul", "list-style:none;margin:10px 0 0;padding:0;display:flex;flex-direction:column;gap:10px;");
5523
+ for (const it of items) {
5524
+ const li = el("li", "display:flex;align-items:center;justify-content:space-between;gap:12px;");
5525
+ li.appendChild(el("span", "flex:1;min-width:0;font-size:13px;color:#374151;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;", it.name || it.product_id));
5526
+ const row = el("div", "display:flex;gap:2px;flex-shrink:0;");
5527
+ const starEls = [];
5528
+ for (let n = 1; n <= 5; n += 1) {
5529
+ const btn = el("span", "cursor:pointer;padding:1px;line-height:0;");
5530
+ const sv = starSvg();
5531
+ btn.appendChild(sv);
5532
+ starEls.push(sv);
5533
+ btn.setAttribute("role", "button");
5534
+ btn.setAttribute("aria-label", `Rate ${it.name || it.product_id} ${n} star${n === 1 ? "" : "s"}`);
5535
+ btn.addEventListener("click", () => {
5536
+ scores[it.product_id] = n;
5537
+ starEls.forEach((s, i) => {
5538
+ const p = s.querySelector("path");
5539
+ if (p) p.setAttribute("fill", i < n ? accent : "#d1d5db");
5540
+ });
5541
+ submitBtn.style.opacity = "1";
5542
+ submitBtn.style.pointerEvents = "auto";
5543
+ });
5544
+ row.appendChild(btn);
5545
+ }
5546
+ li.appendChild(row);
5547
+ list.appendChild(li);
5548
+ }
5549
+ card.appendChild(list);
5550
+ const submitBtn = el(
5551
+ "button",
5552
+ `margin-top:14px;width:100%;border:0;border-radius:999px;background:${accent};color:#fff;font-size:14px;font-weight:700;padding:10px 16px;cursor:pointer;opacity:.5;pointer-events:none;font-family:inherit;`,
5553
+ "Submit ratings"
5554
+ );
5555
+ card.appendChild(submitBtn);
5556
+ const done = (branch) => {
5557
+ target.innerHTML = "";
5558
+ const ack = el(
5559
+ "div",
5560
+ `font-family:${IN_APP_FONT_STACK};border:1px solid #f1f1f3;border-radius:14px;background:#fff;padding:18px 16px;text-align:center;`
5561
+ );
5562
+ ack.appendChild(el("p", "margin:0;font-size:14px;font-weight:700;color:#111827;", "Thanks for rating your items!"));
5563
+ const positiveUrl = reviewsUrl || ic.rating_high_url || null;
5564
+ if (branch === "positive" && positiveUrl) {
5565
+ const a = document.createElement("a");
5566
+ a.href = positiveUrl;
5567
+ a.textContent = ic.rating_high_cta || "Share a review";
5568
+ a.style.cssText = `display:inline-block;margin-top:8px;font-size:12px;font-weight:700;color:${accent};text-decoration:none;`;
5569
+ ack.appendChild(a);
5570
+ } else {
5571
+ ack.appendChild(el("p", "margin:6px 0 0;font-size:12px;color:#9ca3af;", "We'll use your feedback to improve."));
5572
+ }
5573
+ target.appendChild(ack);
5574
+ };
5575
+ submitBtn.addEventListener("click", () => {
5576
+ const rated = Object.keys(scores);
5577
+ if (rated.length === 0) return;
5578
+ submitBtn.disabled = true;
5579
+ submitBtn.style.opacity = ".6";
5580
+ submitBtn.textContent = "Saving…";
5581
+ const payload = {
5582
+ items: rated.map((pid) => ({ product_id: pid, score: scores[pid] })),
5583
+ order_id: orderId,
5584
+ bill_code: billCode,
5585
+ token
5586
+ };
5587
+ fetch(new URL("/v1/in-app/responses", creds.apiHost).toString(), {
5588
+ method: "POST",
5589
+ headers: {
5590
+ "Content-Type": "application/json",
5591
+ "X-Aegis-Write-Key": creds.writeKey,
5592
+ "X-Organization-ID": creds.organizationId
5593
+ },
5594
+ body: JSON.stringify({
5595
+ campaign_id: ctx.campaign.id,
5596
+ response_type: "rating",
5597
+ contact_id: slotContact || creds.contactId,
5598
+ platform: "web",
5599
+ payload
5600
+ })
5601
+ }).then((r) => r.ok ? r.json() : null).then((data) => {
5602
+ var _a;
5603
+ ctx.trackEvent(ctx.campaign.id, "clicked");
5604
+ done(((_a = data == null ? void 0 : data.rating_result) == null ? void 0 : _a.branch) || "positive");
5605
+ }).catch(() => {
5606
+ submitBtn.disabled = false;
5607
+ submitBtn.style.opacity = "1";
5608
+ submitBtn.textContent = "Submit ratings";
5609
+ });
5610
+ });
5611
+ target.appendChild(card);
5612
+ return true;
5613
+ }
5459
5614
  function readAnonIdFromStorage$1() {
5460
5615
  if (typeof document === "undefined") return void 0;
5461
5616
  try {
@@ -6427,6 +6582,23 @@ const _AegisInAppManager = class _AegisInAppManager {
6427
6582
  }
6428
6583
  return;
6429
6584
  }
6585
+ if (campaign.sub_type === "star_rating" && this._isPerItemRating(campaign)) {
6586
+ const ok = renderProductRatingInline(this.buildRenderContext(campaign), target, {
6587
+ apiHost: this.apiHost,
6588
+ writeKey: this.writeKey,
6589
+ organizationId: this.organizationId ?? "",
6590
+ contactId: this.contactId ?? null
6591
+ });
6592
+ if (!ok) {
6593
+ this.displayedCampaigns.delete(campaign.id);
6594
+ return;
6595
+ }
6596
+ if (!(options == null ? void 0 : options.deferImpression)) {
6597
+ this.trackEvent(campaign.id, "impression");
6598
+ this.emit("campaign-shown", campaign);
6599
+ }
6600
+ return;
6601
+ }
6430
6602
  this._ensureSurveyTemplate(campaign);
6431
6603
  const _isMultiCard = campaign.sub_type === "product_recommendation" || campaign.sub_type === "carousel_cards";
6432
6604
  if (this._hasComposedTemplate(ic) && !_isMultiCard) {
@@ -6507,6 +6679,14 @@ const _AegisInAppManager = class _AegisInAppManager {
6507
6679
  const tpl = ic.card_template;
6508
6680
  return !!tpl && typeof tpl === "object" && Array.isArray(tpl.elements) && tpl.elements.length > 0;
6509
6681
  }
6682
+ /** G5 — whether a `star_rating` campaign captures PER-SKU ratings (one row per
6683
+ * order line-item) vs a single order-level score. Opt-in via
6684
+ * `interactive_config.rating_mode='per_item'`, so the order-level star path is
6685
+ * untouched. The renderer reads the SKUs from the slot at mount. */
6686
+ _isPerItemRating(campaign) {
6687
+ const ic = campaign.interactive_config || {};
6688
+ return ic.rating_mode === "per_item";
6689
+ }
6510
6690
  /**
6511
6691
  * P6.full — flat survey → card_template adapter. A `nps_survey` / `star_rating`
6512
6692
  * / `quick_poll` authored WITHOUT a card_template gets one synthesised in place
@@ -14237,7 +14417,7 @@ const _AegisMessageRuntime = class _AegisMessageRuntime {
14237
14417
  var _a;
14238
14418
  this.initialized = false;
14239
14419
  {
14240
- const v = "1.34.1";
14420
+ const v = "1.35.0";
14241
14421
  try {
14242
14422
  globalThis.__AEGIS_SDK_VERSION__ = v;
14243
14423
  } catch {