@mindbowser_inc/ui-feedback-plugin 0.5.0 → 0.6.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.
@@ -1,6 +1,6 @@
1
- var ge = Object.defineProperty;
2
- var xe = (e, t, r) => t in e ? ge(e, t, { enumerable: !0, configurable: !0, writable: !0, value: r }) : e[t] = r;
3
- var O = (e, t, r) => xe(e, typeof t != "symbol" ? t + "" : t, r);
1
+ var me = Object.defineProperty;
2
+ var ge = (e, t, r) => t in e ? me(e, t, { enumerable: !0, configurable: !0, writable: !0, value: r }) : e[t] = r;
3
+ var O = (e, t, r) => ge(e, typeof t != "symbol" ? t + "" : t, r);
4
4
  const I = /* @__PURE__ */ new Set();
5
5
  let R = {
6
6
  active: !1,
@@ -18,18 +18,18 @@ function A() {
18
18
  function k(e) {
19
19
  R = { ...R, ...e }, I.forEach((t) => t(R));
20
20
  }
21
- function ne(e) {
21
+ function oe(e) {
22
22
  return I.add(e), () => I.delete(e);
23
23
  }
24
- function oe() {
24
+ function re() {
25
25
  if (R.userName) return R.userName;
26
26
  const e = localStorage.getItem("ufp_user_name");
27
27
  return e ? (k({ userName: e }), e) : null;
28
28
  }
29
- function re(e) {
29
+ function ie(e) {
30
30
  localStorage.setItem("ufp_user_name", e), k({ userName: e });
31
31
  }
32
- function J(e) {
32
+ function Q(e) {
33
33
  try {
34
34
  const t = new URL(e);
35
35
  return t.origin + t.pathname;
@@ -37,7 +37,7 @@ function J(e) {
37
37
  return e;
38
38
  }
39
39
  }
40
- function ye(e) {
40
+ function xe(e) {
41
41
  return `
42
42
  :host {
43
43
  --ufp-primary: ${e};
@@ -592,15 +592,15 @@ function ye(e) {
592
592
  }
593
593
  `;
594
594
  }
595
- const ve = {
595
+ const ye = {
596
596
  "bottom-right": { bottom: "24px", right: "24px" },
597
597
  "bottom-left": { bottom: "24px", left: "24px" },
598
598
  "top-right": { top: "24px", right: "24px" },
599
599
  "top-left": { top: "24px", left: "24px" }
600
- }, q = "#6366f1", Q = "#4f46e5", Z = "#4338ca";
601
- function be(e, t, r, o) {
602
- const n = document.createElement("div");
603
- Object.assign(n.style, {
600
+ }, q = "#6366f1", Z = "#4f46e5", ee = "#4338ca";
601
+ function ve(e, t, r, n) {
602
+ const o = document.createElement("div");
603
+ Object.assign(o.style, {
604
604
  position: "fixed",
605
605
  zIndex: "2147483647",
606
606
  display: "flex",
@@ -609,10 +609,10 @@ function be(e, t, r, o) {
609
609
  boxShadow: "0 4px 20px rgba(0,0,0,0.28), 0 1px 4px rgba(0,0,0,0.16)",
610
610
  overflow: "hidden",
611
611
  userSelect: "none",
612
- ...ve[t]
612
+ ...ye[t]
613
613
  });
614
614
  const a = document.createElement("button");
615
- a.id = "ufp-btn-annotate", a.title = "Add feedback annotation", ee(a), a.style.padding = "10px 16px 10px 14px", a.innerHTML = `
615
+ a.id = "ufp-btn-annotate", a.title = "Add feedback annotation", te(a), a.style.padding = "10px 16px 10px 14px", a.innerHTML = `
616
616
  <svg width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" style="flex-shrink:0">
617
617
  <path d="M12 20h9"/>
618
618
  <path d="M16.5 3.5a2.121 2.121 0 0 1 3 3L7 19l-4 1 1-4L16.5 3.5z"/>
@@ -622,25 +622,25 @@ function be(e, t, r, o) {
622
622
  const p = document.createElement("div");
623
623
  p.style.cssText = "width:1px;background:rgba(255,255,255,0.3);flex-shrink:0;";
624
624
  const c = document.createElement("button");
625
- c.id = "ufp-btn-panel", c.title = "View all comments", ee(c), c.style.padding = "10px 14px", c.innerHTML = `
625
+ c.id = "ufp-btn-panel", c.title = "View all comments", te(c), c.style.padding = "10px 14px", c.innerHTML = `
626
626
  <svg width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" style="flex-shrink:0">
627
627
  <path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"/>
628
628
  </svg>
629
629
  <span id="ufp-panel-count" style="font-size:13px;font-weight:600;min-width:8px;text-align:center;"></span>
630
- `, n.appendChild(a), n.appendChild(p), n.appendChild(c), e.appendChild(n);
631
- const i = n.querySelector("#ufp-annotate-label"), l = n.querySelector("#ufp-panel-count");
630
+ `, o.appendChild(a), o.appendChild(p), o.appendChild(c), e.appendChild(o);
631
+ const i = o.querySelector("#ufp-annotate-label"), l = o.querySelector("#ufp-panel-count");
632
632
  return a.addEventListener("click", (s) => {
633
- if (s.stopPropagation(), n._dragged) return;
634
- const m = A();
635
- m.active || (m.panelOpen ? (o(), setTimeout(r, 220)) : r());
633
+ if (s.stopPropagation(), o._dragged) return;
634
+ const h = A();
635
+ h.active || (h.panelOpen ? (n(), setTimeout(r, 220)) : r());
636
636
  }), c.addEventListener("click", (s) => {
637
- s.stopPropagation(), !n._dragged && (A().active || o());
638
- }), te(a, () => (A().panelOpen, q), Q), te(c, () => A().panelOpen ? Z : q, Q), ne((s) => {
639
- const m = s.comments.filter((v) => !v.resolved).length;
640
- l.textContent = m > 0 ? String(m) : "", s.active ? (i.textContent = "Drawing…", a.style.opacity = "0.65", c.style.opacity = "0.65", a.style.pointerEvents = "none", c.style.pointerEvents = "none") : (i.textContent = "Feedback", a.style.opacity = "1", c.style.opacity = "1", a.style.pointerEvents = "auto", c.style.pointerEvents = "auto"), c.style.background = s.panelOpen ? Z : q;
641
- }), we(n), n;
637
+ s.stopPropagation(), !o._dragged && (A().active || n());
638
+ }), ne(a, () => (A().panelOpen, q), Z), ne(c, () => A().panelOpen ? ee : q, Z), oe((s) => {
639
+ const h = s.comments.filter((v) => !v.resolved).length;
640
+ l.textContent = h > 0 ? String(h) : "", s.active ? (i.textContent = "Drawing…", a.style.opacity = "0.65", c.style.opacity = "0.65", a.style.pointerEvents = "none", c.style.pointerEvents = "none") : (i.textContent = "Feedback", a.style.opacity = "1", c.style.opacity = "1", a.style.pointerEvents = "auto", c.style.pointerEvents = "auto"), c.style.background = s.panelOpen ? ee : q;
641
+ }), be(o), o;
642
642
  }
643
- function ee(e) {
643
+ function te(e) {
644
644
  Object.assign(e.style, {
645
645
  display: "flex",
646
646
  alignItems: "center",
@@ -654,23 +654,23 @@ function ee(e) {
654
654
  transition: "background 0.12s"
655
655
  });
656
656
  }
657
- function te(e, t, r) {
657
+ function ne(e, t, r) {
658
658
  e.addEventListener("mouseenter", () => {
659
659
  e.style.background = r;
660
660
  }), e.addEventListener("mouseleave", () => {
661
661
  e.style.background = t();
662
662
  });
663
663
  }
664
- function we(e) {
665
- let t = 0, r = 0, o = 0, n = 0;
664
+ function be(e) {
665
+ let t = 0, r = 0, n = 0, o = 0;
666
666
  e.addEventListener("pointerdown", (a) => {
667
667
  if (a.button !== 0) return;
668
668
  t = a.clientX, r = a.clientY;
669
669
  const p = e.getBoundingClientRect();
670
- o = p.left, n = p.top, e._dragged = !1;
670
+ n = p.left, o = p.top, e._dragged = !1;
671
671
  const c = (l) => {
672
- const s = l.clientX - t, m = l.clientY - r;
673
- !e._dragged && Math.sqrt(s * s + m * m) < 5 || (e._dragged = !0, e.style.left = `${Math.max(0, Math.min(window.innerWidth - e.offsetWidth, o + s))}px`, e.style.top = `${Math.max(0, Math.min(window.innerHeight - e.offsetHeight, n + m))}px`, e.style.right = "auto", e.style.bottom = "auto");
672
+ const s = l.clientX - t, h = l.clientY - r;
673
+ !e._dragged && Math.sqrt(s * s + h * h) < 5 || (e._dragged = !0, e.style.left = `${Math.max(0, Math.min(window.innerWidth - e.offsetWidth, n + s))}px`, e.style.top = `${Math.max(0, Math.min(window.innerHeight - e.offsetHeight, o + h))}px`, e.style.right = "auto", e.style.bottom = "auto");
674
674
  }, i = () => {
675
675
  document.removeEventListener("pointermove", c), document.removeEventListener("pointerup", i), requestAnimationFrame(() => {
676
676
  e._dragged = !1;
@@ -679,7 +679,7 @@ function we(e) {
679
679
  document.addEventListener("pointermove", c), document.addEventListener("pointerup", i);
680
680
  });
681
681
  }
682
- function ke(e) {
682
+ function we(e) {
683
683
  return new Promise((t) => {
684
684
  const r = document.createElement("div");
685
685
  r.className = "ufp-modal-backdrop", r.innerHTML = `
@@ -699,42 +699,42 @@ function ke(e) {
699
699
  </div>
700
700
  </div>
701
701
  `, e.appendChild(r);
702
- const o = r.querySelector("#ufp-name-input"), n = r.querySelector("#ufp-name-submit");
703
- o.addEventListener("input", () => {
704
- n.disabled = o.value.trim().length === 0;
702
+ const n = r.querySelector("#ufp-name-input"), o = r.querySelector("#ufp-name-submit");
703
+ n.addEventListener("input", () => {
704
+ o.disabled = n.value.trim().length === 0;
705
705
  });
706
706
  const a = () => {
707
- const p = o.value.trim();
708
- p && (re(p), r.remove(), t(p));
707
+ const p = n.value.trim();
708
+ p && (ie(p), r.remove(), t(p));
709
709
  };
710
- n.addEventListener("click", a), o.addEventListener("keydown", (p) => {
710
+ o.addEventListener("click", a), n.addEventListener("keydown", (p) => {
711
711
  p.key === "Enter" && a();
712
- }), requestAnimationFrame(() => o.focus());
712
+ }), requestAnimationFrame(() => n.focus());
713
713
  });
714
714
  }
715
- const L = "#6366f1", T = 3;
715
+ const L = "#6366f1", z = 3;
716
716
  function B(e, t = 1, r = 1) {
717
717
  switch (e.type) {
718
718
  case "pen": {
719
- const o = document.createElementNS("http://www.w3.org/2000/svg", "path");
720
- return o.setAttribute("d", Se(e.points, t, r)), o.setAttribute("stroke", e.color), o.setAttribute("stroke-width", String(e.width * Math.min(t, r))), o.setAttribute("fill", "none"), o.setAttribute("stroke-linecap", "round"), o.setAttribute("stroke-linejoin", "round"), o;
719
+ const n = document.createElementNS("http://www.w3.org/2000/svg", "path");
720
+ return n.setAttribute("d", Ee(e.points, t, r)), n.setAttribute("stroke", e.color), n.setAttribute("stroke-width", String(e.width * Math.min(t, r))), n.setAttribute("fill", "none"), n.setAttribute("stroke-linecap", "round"), n.setAttribute("stroke-linejoin", "round"), n;
721
721
  }
722
722
  case "rect": {
723
- const o = document.createElementNS("http://www.w3.org/2000/svg", "rect");
724
- return o.setAttribute("x", String(e.x * t)), o.setAttribute("y", String(e.y * r)), o.setAttribute("width", String(e.width * t)), o.setAttribute("height", String(e.height * r)), o.setAttribute("stroke", e.color), o.setAttribute("stroke-width", String(e.strokeWidth * Math.min(t, r))), o.setAttribute("fill", "none"), o.setAttribute("rx", "3"), o;
723
+ const n = document.createElementNS("http://www.w3.org/2000/svg", "rect");
724
+ return n.setAttribute("x", String(e.x * t)), n.setAttribute("y", String(e.y * r)), n.setAttribute("width", String(e.width * t)), n.setAttribute("height", String(e.height * r)), n.setAttribute("stroke", e.color), n.setAttribute("stroke-width", String(e.strokeWidth * Math.min(t, r))), n.setAttribute("fill", "none"), n.setAttribute("rx", "3"), n;
725
725
  }
726
726
  case "circle": {
727
- const o = document.createElementNS("http://www.w3.org/2000/svg", "ellipse");
728
- return o.setAttribute("cx", String(e.cx * t)), o.setAttribute("cy", String(e.cy * r)), o.setAttribute("rx", String(e.rx * t)), o.setAttribute("ry", String(e.ry * r)), o.setAttribute("stroke", e.color), o.setAttribute("stroke-width", String(e.strokeWidth * Math.min(t, r))), o.setAttribute("fill", "none"), o;
727
+ const n = document.createElementNS("http://www.w3.org/2000/svg", "ellipse");
728
+ return n.setAttribute("cx", String(e.cx * t)), n.setAttribute("cy", String(e.cy * r)), n.setAttribute("rx", String(e.rx * t)), n.setAttribute("ry", String(e.ry * r)), n.setAttribute("stroke", e.color), n.setAttribute("stroke-width", String(e.strokeWidth * Math.min(t, r))), n.setAttribute("fill", "none"), n;
729
729
  }
730
730
  case "arrow": {
731
- const o = document.createElementNS("http://www.w3.org/2000/svg", "g"), n = document.createElementNS("http://www.w3.org/2000/svg", "line");
732
- return n.setAttribute("x1", String(e.x1 * t)), n.setAttribute("y1", String(e.y1 * r)), n.setAttribute("x2", String(e.x2 * t)), n.setAttribute("y2", String(e.y2 * r)), n.setAttribute("stroke", e.color), n.setAttribute("stroke-width", String(e.width * Math.min(t, r))), n.setAttribute("marker-end", "url(#ufp-arrowhead)"), o.appendChild(n), o;
731
+ const n = document.createElementNS("http://www.w3.org/2000/svg", "g"), o = document.createElementNS("http://www.w3.org/2000/svg", "line");
732
+ return o.setAttribute("x1", String(e.x1 * t)), o.setAttribute("y1", String(e.y1 * r)), o.setAttribute("x2", String(e.x2 * t)), o.setAttribute("y2", String(e.y2 * r)), o.setAttribute("stroke", e.color), o.setAttribute("stroke-width", String(e.width * Math.min(t, r))), o.setAttribute("marker-end", "url(#ufp-arrowhead)"), n.appendChild(o), n;
733
733
  }
734
734
  }
735
735
  }
736
- function Ee(e, t, r, o) {
737
- const n = r / t.pageWidth, a = o / t.pageHeight;
736
+ function ke(e, t, r, n) {
737
+ const o = r / t.pageWidth, a = n / t.pageHeight;
738
738
  e.innerHTML = "";
739
739
  const p = document.createElementNS("http://www.w3.org/2000/svg", "defs");
740
740
  p.innerHTML = `
@@ -742,58 +742,58 @@ function Ee(e, t, r, o) {
742
742
  <polygon points="0 0, 10 3.5, 0 7" fill="${L}" />
743
743
  </marker>
744
744
  `, e.appendChild(p), t.shapes.forEach((c) => {
745
- e.appendChild(B(c, n, a));
745
+ e.appendChild(B(c, o, a));
746
746
  });
747
747
  }
748
- function Se(e, t, r) {
748
+ function Ee(e, t, r) {
749
749
  if (e.length === 0) return "";
750
750
  if (e.length === 1) {
751
- const n = e[0];
752
- return `M ${n.x * t} ${n.y * r}`;
751
+ const o = e[0];
752
+ return `M ${o.x * t} ${o.y * r}`;
753
753
  }
754
- let o = `M ${e[0].x * t} ${e[0].y * r}`;
755
- for (let n = 1; n < e.length; n++)
756
- o += ` L ${e[n].x * t} ${e[n].y * r}`;
757
- return o;
754
+ let n = `M ${e[0].x * t} ${e[0].y * r}`;
755
+ for (let o = 1; o < e.length; o++)
756
+ n += ` L ${e[o].x * t} ${e[o].y * r}`;
757
+ return n;
758
758
  }
759
- function Ce(e, t, r) {
760
- if (window.scrollY === 0) return null;
761
- const o = window.innerWidth, n = window.innerHeight, a = document.elementsFromPoint(e, t).find((p) => p !== r);
759
+ function Se(e, t, r) {
760
+ if (window.scrollX === 0 && window.scrollY === 0) return null;
761
+ const n = window.innerWidth, o = window.innerHeight, a = document.elementsFromPoint(e, t).find((p) => p !== r);
762
762
  for (let p = a ?? null; p && p !== document.documentElement; p = p.parentElement) {
763
763
  const c = getComputedStyle(p);
764
764
  if (c.position !== "fixed" && c.position !== "sticky") continue;
765
765
  const i = p.getBoundingClientRect();
766
- if (!(i.width >= o * 0.9 && i.height >= n * 0.9)) {
766
+ if (!(i.width >= n * 0.9 && i.height >= o * 0.9)) {
767
767
  if (c.position === "sticky") {
768
- if (i.top < n * 0.25) return "top";
768
+ if (i.top < o * 0.25) return "top";
769
769
  continue;
770
770
  }
771
- return n - i.bottom < i.top ? "bottom" : "top";
771
+ return o - i.bottom < i.top ? "bottom" : "top";
772
772
  }
773
773
  }
774
774
  return null;
775
775
  }
776
- function Le(e, t) {
777
- if (!t) return e;
776
+ function Ce(e, t, r) {
777
+ if (!t && !r) return e;
778
778
  switch (e.type) {
779
779
  case "pen":
780
- return { ...e, points: e.points.map((r) => ({ x: r.x, y: r.y + t })) };
780
+ return { ...e, points: e.points.map((n) => ({ x: n.x + t, y: n.y + r })) };
781
781
  case "rect":
782
- return { ...e, y: e.y + t };
782
+ return { ...e, x: e.x + t, y: e.y + r };
783
783
  case "circle":
784
- return { ...e, cy: e.cy + t };
784
+ return { ...e, cx: e.cx + t, cy: e.cy + r };
785
785
  case "arrow":
786
- return { ...e, y1: e.y1 + t, y2: e.y2 + t };
786
+ return { ...e, x1: e.x1 + t, y1: e.y1 + r, x2: e.x2 + t, y2: e.y2 + r };
787
787
  }
788
788
  }
789
- function Me(e) {
789
+ function Le(e) {
790
790
  return new Promise((t) => {
791
791
  let r = "pen";
792
- const o = [];
793
- let n = !1, a = 0, p = 0, c = [], i = null, l = null, s = !1, m = 0;
792
+ const n = [];
793
+ let o = !1, a = 0, p = 0, c = [], i = null, l = null, s = !1, h = 0;
794
794
  const v = [];
795
- let h = null;
796
- const b = () => h ? { x: 0, y: 0 } : { x: window.scrollX, y: window.scrollY }, x = document.createElement("div");
795
+ let m = null;
796
+ const b = () => m ? { x: 0, y: 0 } : { x: window.scrollX, y: window.scrollY }, x = document.createElement("div");
797
797
  x.style.cssText = "position:fixed;inset:0;z-index:2147483645;cursor:crosshair;background:rgba(99,102,241,0.04);touch-action:none;user-select:none;-webkit-user-select:none;";
798
798
  const u = document.createElementNS("http://www.w3.org/2000/svg", "svg");
799
799
  u.style.cssText = "position:absolute;inset:0;width:100%;height:100%;pointer-events:none;overflow:visible;", u.innerHTML = `
@@ -811,16 +811,16 @@ function Me(e) {
811
811
  N(), window.addEventListener("scroll", N, { passive: !0 });
812
812
  function H() {
813
813
  window.removeEventListener("scroll", N);
814
- for (const d of Y) window.removeEventListener(d, K, !0);
815
- for (const d of X) window.removeEventListener(d, G, !0);
814
+ for (const d of X) window.removeEventListener(d, K, !0);
815
+ for (const d of Y) window.removeEventListener(d, G, !0);
816
816
  x.remove(), P.remove(), l == null || l.remove();
817
817
  }
818
818
  function j() {
819
- w.innerHTML = "", C.innerHTML = "", o.forEach((d, g) => (v[g] ? C : w).appendChild(B(d)));
819
+ w.innerHTML = "", C.innerHTML = "", n.forEach((d, g) => (v[g] ? C : w).appendChild(B(d)));
820
820
  }
821
821
  function _() {
822
822
  let d = 0, g = 0, y = 0;
823
- return o.forEach((f, E) => {
823
+ return n.forEach((f, E) => {
824
824
  const S = v[E] ? 0 : window.scrollX, M = v[E] ? 0 : window.scrollY;
825
825
  if (f.type === "pen" && f.points.length) {
826
826
  const $ = f.points[f.points.length - 1];
@@ -831,10 +831,10 @@ function Me(e) {
831
831
  anchorY: y > 0 ? g / y : window.innerHeight / 2
832
832
  };
833
833
  }
834
- function ie() {
835
- s = !0, n = !1, x.style.pointerEvents = "none", P.style.pointerEvents = "none", ae();
836
- }
837
834
  function ae() {
835
+ s = !0, o = !1, x.style.pointerEvents = "none", P.style.pointerEvents = "none", se();
836
+ }
837
+ function se() {
838
838
  l && l.remove();
839
839
  const { anchorX: d, anchorY: g } = _(), y = 300, f = 12;
840
840
  let E = d + f, S = g + f;
@@ -861,22 +861,22 @@ function Me(e) {
861
861
  color:#fff;opacity:0.45;transition:opacity 0.15s;">Submit</button>
862
862
  </div>
863
863
  `, e.appendChild(l);
864
- const M = l.querySelector("#ufp-inline-text"), $ = l.querySelector("#ufp-popup-submit"), ce = l.querySelector("#ufp-popup-cancel");
864
+ const M = l.querySelector("#ufp-inline-text"), $ = l.querySelector("#ufp-popup-submit"), de = l.querySelector("#ufp-popup-cancel");
865
865
  M.addEventListener("input", () => {
866
866
  const W = M.value.trim().length > 0;
867
867
  $.disabled = !W, $.style.opacity = W ? "1" : "0.45";
868
868
  }), $.addEventListener("click", () => {
869
869
  const W = M.value.trim();
870
870
  if (!W) return;
871
- const de = _();
871
+ const ue = _();
872
872
  H();
873
- const ue = Math.max(0, document.documentElement.scrollHeight - window.innerHeight), fe = o.map((me, he) => Le(me, v[he] === "bottom" ? ue : 0));
874
- t({ shapes: fe, text: W, ...de });
875
- }), ce.addEventListener("click", () => {
873
+ const fe = n.map((J, he) => v[he] ? J : Ce(J, -window.scrollX, -window.scrollY));
874
+ t({ shapes: fe, text: W, ...ue });
875
+ }), de.addEventListener("click", () => {
876
876
  H(), t(null);
877
877
  }), requestAnimationFrame(() => M.focus());
878
878
  }
879
- const P = Ae(
879
+ const P = Me(
880
880
  e,
881
881
  (d) => {
882
882
  r = d;
@@ -885,71 +885,71 @@ function Me(e) {
885
885
  H(), t(null);
886
886
  },
887
887
  () => {
888
- o.length !== 0 && (l && (l.remove(), l = null, x.style.pointerEvents = "auto", P.style.pointerEvents = "auto", s = !1), o.pop(), v.pop(), j());
888
+ n.length !== 0 && (l && (l.remove(), l = null, x.style.pointerEvents = "auto", P.style.pointerEvents = "auto", s = !1), n.pop(), v.pop(), j());
889
889
  }
890
890
  );
891
891
  e.appendChild(x);
892
- const Y = ["pointerdown", "pointermove", "pointerup", "pointercancel"], X = ["mousedown", "mouseup", "click", "dblclick", "auxclick", "touchstart", "touchmove", "contextmenu", "dragstart", "selectstart"];
892
+ const X = ["pointerdown", "pointermove", "pointerup", "pointercancel"], Y = ["mousedown", "mouseup", "click", "dblclick", "auxclick", "touchstart", "touchmove", "contextmenu", "dragstart", "selectstart"];
893
893
  function V(d) {
894
894
  const g = d.composedPath();
895
895
  return g.includes(e.host) && !g.includes(x);
896
896
  }
897
897
  function G(d) {
898
- V(d) || s && performance.now() > m || (d.preventDefault(), d.stopPropagation());
898
+ V(d) || s && performance.now() > h || (d.preventDefault(), d.stopPropagation());
899
899
  }
900
900
  function K(d) {
901
901
  if (s || V(d)) return;
902
902
  d.stopPropagation();
903
903
  const g = d;
904
- d.type === "pointerdown" ? se(g) : d.type === "pointermove" ? le(g) : d.type === "pointerup" ? pe(g) : d.type === "pointercancel" && (n = !1, i && (i.remove(), i = null));
904
+ d.type === "pointerdown" ? le(g) : d.type === "pointermove" ? pe(g) : d.type === "pointerup" ? ce(g) : d.type === "pointercancel" && (o = !1, i && (i.remove(), i = null));
905
905
  }
906
- function se(d) {
906
+ function le(d) {
907
907
  if (d.button === 0) {
908
908
  d.preventDefault();
909
909
  try {
910
910
  x.setPointerCapture(d.pointerId);
911
911
  } catch {
912
912
  }
913
- n = !0, h = Ce(d.clientX, d.clientY, e.host), a = d.clientX + b().x, p = d.clientY + b().y, r === "pen" && (c = [{ x: a, y: p }]);
913
+ o = !0, m = Se(d.clientX, d.clientY, e.host), a = d.clientX + b().x, p = d.clientY + b().y, r === "pen" && (c = [{ x: a, y: p }]);
914
914
  }
915
915
  }
916
- function le(d) {
917
- if (!n) return;
916
+ function pe(d) {
917
+ if (!o) return;
918
918
  const g = d.clientX + b().x, y = d.clientY + b().y;
919
919
  if (i && i.remove(), r === "pen")
920
- c.push({ x: g, y }), i = B({ type: "pen", points: [...c], color: L, width: T });
920
+ c.push({ x: g, y }), i = B({ type: "pen", points: [...c], color: L, width: z });
921
921
  else if (r === "rect") {
922
- const f = { type: "rect", x: Math.min(a, g), y: Math.min(p, y), width: Math.abs(g - a), height: Math.abs(y - p), color: L, strokeWidth: T };
922
+ const f = { type: "rect", x: Math.min(a, g), y: Math.min(p, y), width: Math.abs(g - a), height: Math.abs(y - p), color: L, strokeWidth: z };
923
923
  i = B(f);
924
924
  } else if (r === "circle") {
925
- const f = Math.abs(g - a) / 2, E = Math.abs(y - p) / 2, S = { type: "circle", cx: Math.min(a, g) + f, cy: Math.min(p, y) + E, rx: f, ry: E, color: L, strokeWidth: T };
925
+ const f = Math.abs(g - a) / 2, E = Math.abs(y - p) / 2, S = { type: "circle", cx: Math.min(a, g) + f, cy: Math.min(p, y) + E, rx: f, ry: E, color: L, strokeWidth: z };
926
926
  i = B(S);
927
- } else r === "arrow" && (i = B({ type: "arrow", x1: a, y1: p, x2: g, y2: y, color: L, width: T }));
928
- i && (h ? C : w).appendChild(i);
927
+ } else r === "arrow" && (i = B({ type: "arrow", x1: a, y1: p, x2: g, y2: y, color: L, width: z }));
928
+ i && (m ? C : w).appendChild(i);
929
929
  }
930
- function pe(d) {
931
- if (!n) return;
932
- m = performance.now() + 400, n = !1, i && (i.remove(), i = null);
930
+ function ce(d) {
931
+ if (!o) return;
932
+ h = performance.now() + 400, o = !1, i && (i.remove(), i = null);
933
933
  const g = d.clientX + b().x, y = d.clientY + b().y;
934
934
  let f = !1;
935
935
  if (r === "pen" && c.length > 1)
936
- o.push({ type: "pen", points: [...c], color: L, width: T }), c = [], f = !0;
936
+ n.push({ type: "pen", points: [...c], color: L, width: z }), c = [], f = !0;
937
937
  else if (r === "rect") {
938
938
  const E = Math.abs(g - a), S = Math.abs(y - p);
939
- E > 4 && S > 4 && (o.push({ type: "rect", x: Math.min(a, g), y: Math.min(p, y), width: E, height: S, color: L, strokeWidth: T }), f = !0);
939
+ E > 4 && S > 4 && (n.push({ type: "rect", x: Math.min(a, g), y: Math.min(p, y), width: E, height: S, color: L, strokeWidth: z }), f = !0);
940
940
  } else if (r === "circle") {
941
941
  const E = Math.abs(g - a) / 2, S = Math.abs(y - p) / 2;
942
- E > 4 && S > 4 && (o.push({ type: "circle", cx: Math.min(a, g) + E, cy: Math.min(p, y) + S, rx: E, ry: S, color: L, strokeWidth: T }), f = !0);
943
- } else r === "arrow" && Math.sqrt((g - a) ** 2 + (y - p) ** 2) > 10 && (o.push({ type: "arrow", x1: a, y1: p, x2: g, y2: y, color: L, width: T }), f = !0);
944
- f && (v.push(h), j(), ie());
942
+ E > 4 && S > 4 && (n.push({ type: "circle", cx: Math.min(a, g) + E, cy: Math.min(p, y) + S, rx: E, ry: S, color: L, strokeWidth: z }), f = !0);
943
+ } else r === "arrow" && Math.sqrt((g - a) ** 2 + (y - p) ** 2) > 10 && (n.push({ type: "arrow", x1: a, y1: p, x2: g, y2: y, color: L, width: z }), f = !0);
944
+ f && (v.push(m), j(), ae());
945
945
  }
946
- for (const d of Y) window.addEventListener(d, K, { capture: !0, passive: !1 });
947
- for (const d of X) window.addEventListener(d, G, { capture: !0, passive: !1 });
946
+ for (const d of X) window.addEventListener(d, K, { capture: !0, passive: !1 });
947
+ for (const d of Y) window.addEventListener(d, G, { capture: !0, passive: !1 });
948
948
  });
949
949
  }
950
- function Ae(e, t, r, o) {
951
- const n = document.createElement("div");
952
- return n.className = "ufp-toolbar", n.innerHTML = `
950
+ function Me(e, t, r, n) {
951
+ const o = document.createElement("div");
952
+ return o.className = "ufp-toolbar", o.innerHTML = `
953
953
  <span class="ufp-toolbar-label">Draw to annotate</span>
954
954
  <div class="ufp-toolbar-sep"></div>
955
955
  <button class="ufp-btn-icon active" data-tool="pen" title="Pen">
@@ -976,54 +976,54 @@ function Ae(e, t, r, o) {
976
976
  </button>
977
977
  <div class="ufp-toolbar-sep"></div>
978
978
  <button class="ufp-btn ufp-btn-ghost" id="ufp-cancel-btn">Cancel</button>
979
- `, n.querySelectorAll("[data-tool]").forEach((a) => {
979
+ `, o.querySelectorAll("[data-tool]").forEach((a) => {
980
980
  a.addEventListener("click", () => {
981
- n.querySelectorAll("[data-tool]").forEach((p) => p.classList.remove("active")), a.classList.add("active"), t(a.dataset.tool);
981
+ o.querySelectorAll("[data-tool]").forEach((p) => p.classList.remove("active")), a.classList.add("active"), t(a.dataset.tool);
982
982
  });
983
- }), n.querySelector("#ufp-undo-btn").addEventListener("click", o), n.querySelector("#ufp-cancel-btn").addEventListener("click", r), e.appendChild(n), n;
983
+ }), o.querySelector("#ufp-undo-btn").addEventListener("click", n), o.querySelector("#ufp-cancel-btn").addEventListener("click", r), e.appendChild(o), o;
984
984
  }
985
985
  function U(e) {
986
986
  const t = Date.now() - e, r = Math.floor(t / 1e3);
987
987
  if (r < 60) return "just now";
988
- const o = Math.floor(r / 60);
989
- if (o < 60) return `${o}m ago`;
990
- const n = Math.floor(o / 60);
991
- if (n < 24) return `${n}h ago`;
992
- const a = Math.floor(n / 24);
988
+ const n = Math.floor(r / 60);
989
+ if (n < 60) return `${n}m ago`;
990
+ const o = Math.floor(n / 60);
991
+ if (o < 24) return `${o}h ago`;
992
+ const a = Math.floor(o / 24);
993
993
  return a < 7 ? `${a}d ago` : new Date(e).toLocaleDateString();
994
994
  }
995
995
  function D(e) {
996
996
  return e.split(" ").filter(Boolean).slice(0, 2).map((t) => t[0].toUpperCase()).join("");
997
997
  }
998
- function z(e) {
998
+ function T(e) {
999
999
  return e.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;");
1000
1000
  }
1001
- function Te(e, t, r, o) {
1002
- let n = [...t];
1001
+ function Ae(e, t, r, n) {
1002
+ let o = [...t];
1003
1003
  const a = document.createElement("div");
1004
1004
  a.className = "ufp-replies";
1005
- const p = (h) => {
1005
+ const p = (m) => {
1006
1006
  const b = a.querySelector(".ufp-replies-list");
1007
1007
  b && b.remove();
1008
1008
  const x = document.createElement("div");
1009
- if (x.className = "ufp-replies-list", x.style.cssText = "display:flex;flex-direction:column;gap:12px;", h.length > 0) {
1009
+ if (x.className = "ufp-replies-list", x.style.cssText = "display:flex;flex-direction:column;gap:12px;", m.length > 0) {
1010
1010
  const u = document.createElement("div");
1011
- u.className = "ufp-replies-title", u.textContent = `${h.length} ${h.length === 1 ? "Reply" : "Replies"}`, x.appendChild(u), h.forEach((w) => {
1011
+ u.className = "ufp-replies-title", u.textContent = `${m.length} ${m.length === 1 ? "Reply" : "Replies"}`, x.appendChild(u), m.forEach((w) => {
1012
1012
  const C = document.createElement("div");
1013
1013
  C.className = "ufp-reply", C.innerHTML = `
1014
1014
  <div class="ufp-reply-meta">
1015
1015
  <div class="ufp-avatar" style="width:22px;height:22px;font-size:10px;">${D(w.authorName)}</div>
1016
- <span class="ufp-reply-author">${z(w.authorName)}</span>
1016
+ <span class="ufp-reply-author">${T(w.authorName)}</span>
1017
1017
  <span class="ufp-reply-time">${U(w.createdAt)}</span>
1018
1018
  </div>
1019
- <div class="ufp-reply-text">${z(w.text)}</div>
1019
+ <div class="ufp-reply-text">${T(w.text)}</div>
1020
1020
  `, x.appendChild(C);
1021
1021
  });
1022
1022
  }
1023
1023
  a.insertBefore(x, a.querySelector(".ufp-reply-input-area"));
1024
1024
  }, c = document.createElement("div");
1025
1025
  c.className = "ufp-reply-input-area";
1026
- const i = oe();
1026
+ const i = re();
1027
1027
  c.innerHTML = `
1028
1028
  <div class="ufp-reply-name-row">
1029
1029
  <span class="ufp-reply-name-label">Replying as:</span>
@@ -1032,7 +1032,7 @@ function Te(e, t, r, o) {
1032
1032
  id="ufp-reply-name"
1033
1033
  type="text"
1034
1034
  placeholder="Your name"
1035
- value="${z(i ?? "")}"
1035
+ value="${T(i ?? "")}"
1036
1036
  style="flex:1;"
1037
1037
  />
1038
1038
  </div>
@@ -1047,30 +1047,30 @@ function Te(e, t, r, o) {
1047
1047
  <button class="ufp-btn ufp-btn-primary" id="ufp-reply-submit" disabled style="font-size:13px;padding:7px 14px;">Reply</button>
1048
1048
  </div>
1049
1049
  `;
1050
- const l = c.querySelector("#ufp-reply-name"), s = c.querySelector("#ufp-reply-text"), m = c.querySelector("#ufp-reply-submit"), v = () => {
1051
- m.disabled = l.value.trim().length === 0 || s.value.trim().length === 0;
1050
+ const l = c.querySelector("#ufp-reply-name"), s = c.querySelector("#ufp-reply-text"), h = c.querySelector("#ufp-reply-submit"), v = () => {
1051
+ h.disabled = l.value.trim().length === 0 || s.value.trim().length === 0;
1052
1052
  };
1053
- return l.addEventListener("input", v), s.addEventListener("input", v), m.addEventListener("click", async () => {
1054
- const h = l.value.trim(), b = s.value.trim();
1055
- if (!h || !b) return;
1056
- m.disabled = !0, m.textContent = "Sending…", re(h);
1053
+ return l.addEventListener("input", v), s.addEventListener("input", v), h.addEventListener("click", async () => {
1054
+ const m = l.value.trim(), b = s.value.trim();
1055
+ if (!m || !b) return;
1056
+ h.disabled = !0, h.textContent = "Sending…", ie(m);
1057
1057
  const x = {
1058
1058
  commentId: e,
1059
- authorName: h,
1059
+ authorName: m,
1060
1060
  text: b,
1061
1061
  createdAt: Date.now()
1062
1062
  };
1063
1063
  try {
1064
1064
  const w = { id: await r.addReply(x), ...x };
1065
- s.value = "", m.textContent = "Reply", m.disabled = !0, n = [...n, w], p(n), o(w);
1065
+ s.value = "", h.textContent = "Reply", h.disabled = !0, o = [...o, w], p(o), n(w);
1066
1066
  } catch (u) {
1067
- console.error("[ui-feedback-plugin] Failed to save reply:", u), m.disabled = !1, m.textContent = "Reply";
1067
+ console.error("[ui-feedback-plugin] Failed to save reply:", u), h.disabled = !1, h.textContent = "Reply";
1068
1068
  }
1069
- }), a.appendChild(c), p(n), a.addReply = (h) => {
1070
- n = [...n, h], p(n);
1069
+ }), a.appendChild(c), p(o), a.addReply = (m) => {
1070
+ o = [...o, m], p(o);
1071
1071
  }, a;
1072
1072
  }
1073
- function ze(e, t, r, o, n, a, p, c) {
1073
+ function ze(e, t, r, n, o, a, p, c) {
1074
1074
  const i = document.createElement("div");
1075
1075
  i.className = "ufp-detail", i.innerHTML = `
1076
1076
  <div class="ufp-detail-image-area">
@@ -1105,11 +1105,11 @@ function ze(e, t, r, o, n, a, p, c) {
1105
1105
  <div class="ufp-comment-meta">
1106
1106
  <div class="ufp-avatar">${D(t.authorName)}</div>
1107
1107
  <div>
1108
- <div class="ufp-comment-author">${z(t.authorName)}</div>
1108
+ <div class="ufp-comment-author">${T(t.authorName)}</div>
1109
1109
  <div class="ufp-comment-time">${U(t.createdAt)}</div>
1110
1110
  </div>
1111
1111
  </div>
1112
- <div class="ufp-detail-comment-text">${z(t.text)}</div>
1112
+ <div class="ufp-detail-comment-text">${T(t.text)}</div>
1113
1113
  <div class="ufp-detail-actions" id="ufp-detail-actions"></div>
1114
1114
  </div>
1115
1115
  <div id="ufp-detail-replies"></div>
@@ -1126,7 +1126,7 @@ function ze(e, t, r, o, n, a, p, c) {
1126
1126
  style="vertical-align:middle;margin-right:4px"><polyline points="9 14 4 9 9 4"/><path d="M20 20v-7a4 4 0 0 0-4-4H4"/></svg>
1127
1127
  Reopen
1128
1128
  `, u.addEventListener("click", async () => {
1129
- u.disabled = !0, u.textContent = "Reopening…", await o.updateComment(t.id, { resolved: !1 }), a(t.id), i.remove(), k({ panelOpen: !0 });
1129
+ u.disabled = !0, u.textContent = "Reopening…", await n.updateComment(t.id, { resolved: !1 }), a(t.id), i.remove(), k({ panelOpen: !0 });
1130
1130
  }), l.appendChild(u);
1131
1131
  } else {
1132
1132
  const u = document.createElement("button");
@@ -1135,29 +1135,29 @@ function ze(e, t, r, o, n, a, p, c) {
1135
1135
  style="vertical-align:middle;margin-right:4px"><polyline points="20 6 9 17 4 12"/></svg>
1136
1136
  Mark Resolved
1137
1137
  `, u.addEventListener("click", async () => {
1138
- u.disabled = !0, u.textContent = "Resolving…", await o.updateComment(t.id, { resolved: !0 }), n(t.id), i.remove(), k({ panelOpen: !0 });
1138
+ u.disabled = !0, u.textContent = "Resolving…", await n.updateComment(t.id, { resolved: !0 }), o(t.id), i.remove(), k({ panelOpen: !0 });
1139
1139
  }), l.appendChild(u);
1140
1140
  }
1141
1141
  const s = document.createElement("button");
1142
1142
  s.className = "ufp-btn ufp-btn-ghost", s.style.fontSize = "13px", s.textContent = "Delete", s.addEventListener("click", async () => {
1143
- confirm("Delete this comment and all its replies?") && (s.disabled = !0, await o.deleteComment(t.id), p(t.id), i.remove(), k({ panelOpen: !0 }));
1143
+ confirm("Delete this comment and all its replies?") && (s.disabled = !0, await n.deleteComment(t.id), p(t.id), i.remove(), k({ panelOpen: !0 }));
1144
1144
  }), l.appendChild(s);
1145
- const m = i.querySelector("#ufp-detail-replies"), v = Te(t.id, r, o, (u) => {
1145
+ const h = i.querySelector("#ufp-detail-replies"), v = Ae(t.id, r, n, (u) => {
1146
1146
  var w;
1147
1147
  (w = v.addReply) == null || w.call(v, u), c == null || c(u);
1148
1148
  });
1149
- m.appendChild(v);
1150
- const h = i.querySelector(".ufp-detail-screenshot"), b = i.querySelector(".ufp-detail-annotation-svg"), x = () => {
1151
- const u = h.clientWidth, w = h.clientHeight;
1152
- b.setAttribute("viewBox", `0 0 ${u} ${w}`), Ee(b, t.annotation, u, w), b.querySelectorAll("[marker-end]").forEach((C) => {
1149
+ h.appendChild(v);
1150
+ const m = i.querySelector(".ufp-detail-screenshot"), b = i.querySelector(".ufp-detail-annotation-svg"), x = () => {
1151
+ const u = m.clientWidth, w = m.clientHeight;
1152
+ b.setAttribute("viewBox", `0 0 ${u} ${w}`), ke(b, t.annotation, u, w), b.querySelectorAll("[marker-end]").forEach((C) => {
1153
1153
  C.setAttribute("marker-end", "url(#ufp-detail-arrowhead)");
1154
1154
  });
1155
1155
  };
1156
- h.complete && h.naturalWidth > 0 ? x() : h.addEventListener("load", x);
1156
+ m.complete && m.naturalWidth > 0 ? x() : m.addEventListener("load", x);
1157
1157
  }
1158
- function Ne(e, t, r) {
1159
- const o = document.createElement("div");
1160
- o.className = "ufp-panel", o.innerHTML = `
1158
+ function Te(e, t, r) {
1159
+ const n = document.createElement("div");
1160
+ n.className = "ufp-panel", n.innerHTML = `
1161
1161
  <div class="ufp-panel-header">
1162
1162
  <span class="ufp-panel-title">Feedback</span>
1163
1163
  <div style="display:flex;gap:8px;align-items:center;">
@@ -1177,19 +1177,19 @@ function Ne(e, t, r) {
1177
1177
  <button class="ufp-filter-tab" data-filter="resolved">Resolved</button>
1178
1178
  </div>
1179
1179
  <div class="ufp-panel-list" id="ufp-comment-list"></div>
1180
- `, e.appendChild(o), o.querySelector("#ufp-panel-close").addEventListener("click", () => {
1180
+ `, e.appendChild(n), n.querySelector("#ufp-panel-close").addEventListener("click", () => {
1181
1181
  k({ panelOpen: !1 });
1182
- }), o.querySelector("#ufp-new-feedback").addEventListener("click", () => {
1182
+ }), n.querySelector("#ufp-new-feedback").addEventListener("click", () => {
1183
1183
  k({ panelOpen: !1 }), r();
1184
- }), o.querySelectorAll(".ufp-filter-tab").forEach((c) => {
1184
+ }), n.querySelectorAll(".ufp-filter-tab").forEach((c) => {
1185
1185
  c.addEventListener("click", () => {
1186
- o.querySelectorAll(".ufp-filter-tab").forEach((i) => i.classList.remove("active")), c.classList.add("active"), k({ filter: c.dataset.filter });
1186
+ n.querySelectorAll(".ufp-filter-tab").forEach((i) => i.classList.remove("active")), c.classList.add("active"), k({ filter: c.dataset.filter });
1187
1187
  });
1188
1188
  });
1189
- const n = o.querySelector("#ufp-comment-list"), a = /* @__PURE__ */ new Map(), p = async (c, i) => {
1189
+ const o = n.querySelector("#ufp-comment-list"), a = /* @__PURE__ */ new Map(), p = async (c, i) => {
1190
1190
  const l = c.filter((s) => i === "open" ? !s.resolved : s.resolved);
1191
- if (n.innerHTML = "", l.length === 0) {
1192
- n.innerHTML = `
1191
+ if (o.innerHTML = "", l.length === 0) {
1192
+ o.innerHTML = `
1193
1193
  <div class="ufp-panel-empty">
1194
1194
  <svg width="32" height="32" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" opacity="0.4">
1195
1195
  <path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"/>
@@ -1207,30 +1207,30 @@ function Ne(e, t, r) {
1207
1207
  } catch {
1208
1208
  a.set(s.id, []);
1209
1209
  }
1210
- n.appendChild(
1211
- He(s, a, e, t)
1210
+ o.appendChild(
1211
+ Ne(s, a, e, t)
1212
1212
  );
1213
1213
  }
1214
1214
  };
1215
- return ne(async (c) => {
1216
- o.classList.toggle("open", c.panelOpen), c.panelOpen && await p(c.comments, c.filter);
1217
- }), o;
1215
+ return oe(async (c) => {
1216
+ n.classList.toggle("open", c.panelOpen), c.panelOpen && await p(c.comments, c.filter);
1217
+ }), n;
1218
1218
  }
1219
- function He(e, t, r, o, n) {
1219
+ function Ne(e, t, r, n, o) {
1220
1220
  const a = t.get(e.id) ?? [], p = document.createElement("div");
1221
1221
  return p.className = "ufp-comment-card", p.dataset.id = e.id, p.innerHTML = `
1222
1222
  <div class="ufp-comment-card-header">
1223
1223
  <div class="ufp-comment-meta">
1224
1224
  <div class="ufp-avatar">${D(e.authorName)}</div>
1225
1225
  <div>
1226
- <div class="ufp-comment-author">${z(e.authorName)}</div>
1226
+ <div class="ufp-comment-author">${T(e.authorName)}</div>
1227
1227
  <div class="ufp-comment-time">${U(e.createdAt)}</div>
1228
1228
  </div>
1229
1229
  </div>
1230
1230
  ${e.resolved ? '<span class="ufp-resolved-badge">Resolved</span>' : ""}
1231
1231
  </div>
1232
1232
  <img class="ufp-comment-thumbnail" src="${e.screenshotUrl}" alt="Screenshot" loading="lazy" />
1233
- <div class="ufp-comment-text">${z(e.text)}</div>
1233
+ <div class="ufp-comment-text">${T(e.text)}</div>
1234
1234
  <div class="ufp-comment-footer">
1235
1235
  <span class="ufp-reply-count">
1236
1236
  ${a.length > 0 ? `${a.length} ${a.length === 1 ? "reply" : "replies"}` : "No replies yet — click to reply"}
@@ -1239,7 +1239,7 @@ function He(e, t, r, o, n) {
1239
1239
  `, p.addEventListener("click", async () => {
1240
1240
  let c = t.get(e.id) ?? [];
1241
1241
  try {
1242
- c = await o.getReplies(e.id), t.set(e.id, c);
1242
+ c = await n.getReplies(e.id), t.set(e.id, c);
1243
1243
  } catch (i) {
1244
1244
  console.error("[ui-feedback-plugin] Failed to fetch replies:", i);
1245
1245
  }
@@ -1247,7 +1247,7 @@ function He(e, t, r, o, n) {
1247
1247
  r,
1248
1248
  e,
1249
1249
  c,
1250
- o,
1250
+ n,
1251
1251
  (i) => {
1252
1252
  const l = A();
1253
1253
  k({ comments: l.comments.map((s) => s.id === i ? { ...s, resolved: !0 } : s) });
@@ -1270,111 +1270,106 @@ function He(e, t, r, o, n) {
1270
1270
  );
1271
1271
  }), p;
1272
1272
  }
1273
- async function $e() {
1273
+ async function He() {
1274
1274
  try {
1275
- const e = await Be();
1276
- return await Re(e);
1275
+ const e = await $e();
1276
+ return await Be(e);
1277
1277
  } catch (e) {
1278
- return console.error("[ui-feedback-plugin] capturePageScreenshot failed:", e), We();
1278
+ return console.error("[ui-feedback-plugin] capturePageScreenshot failed:", e), Re();
1279
1279
  }
1280
1280
  }
1281
- async function Be() {
1281
+ async function $e() {
1282
1282
  return (await import("./html2canvas-pro.esm-QETbiPYt.mjs")).default;
1283
1283
  }
1284
- async function Re(e) {
1285
- const t = window.scrollX, r = window.scrollY;
1286
- window.scrollTo(0, 0);
1287
- try {
1288
- return (await e(document.body, {
1289
- allowTaint: !1,
1290
- useCORS: !0,
1291
- logging: !1,
1292
- scale: Math.min(window.devicePixelRatio, 2),
1293
- width: document.documentElement.scrollWidth,
1294
- height: document.documentElement.scrollHeight,
1295
- windowWidth: document.documentElement.scrollWidth,
1296
- windowHeight: document.documentElement.scrollHeight,
1297
- x: 0,
1298
- y: 0,
1299
- ignoreElements: (n) => n.tagName === "UI-FEEDBACK-PLUGIN"
1300
- })).toDataURL("image/png");
1301
- } finally {
1302
- window.scrollTo(t, r);
1303
- }
1284
+ async function Be(e) {
1285
+ const t = document.documentElement.clientWidth, r = window.innerHeight;
1286
+ return (await e(document.body, {
1287
+ allowTaint: !1,
1288
+ useCORS: !0,
1289
+ logging: !1,
1290
+ scale: Math.min(window.devicePixelRatio, 2),
1291
+ x: window.scrollX,
1292
+ y: window.scrollY,
1293
+ width: t,
1294
+ height: r,
1295
+ windowWidth: t,
1296
+ windowHeight: r,
1297
+ ignoreElements: (o) => o.tagName === "UI-FEEDBACK-PLUGIN"
1298
+ })).toDataURL("image/png");
1304
1299
  }
1305
- function We() {
1300
+ function Re() {
1306
1301
  const e = document.createElement("canvas");
1307
1302
  e.width = window.innerWidth, e.height = window.innerHeight;
1308
1303
  const t = e.getContext("2d");
1309
1304
  return t.fillStyle = "#f3f4f6", t.fillRect(0, 0, e.width, e.height), t.fillStyle = "#9ca3af", t.font = "16px -apple-system, sans-serif", t.textAlign = "center", t.fillText("Screenshot unavailable", e.width / 2, e.height / 2), e.toDataURL("image/png");
1310
1305
  }
1311
- async function Oe(e, t) {
1306
+ async function We(e, t) {
1312
1307
  try {
1313
1308
  const r = await new Promise((i, l) => {
1314
1309
  const s = new Image();
1315
1310
  s.onload = () => i(s), s.onerror = () => l(new Error("screenshot failed to load")), s.src = e;
1316
- }), o = document.createElement("canvas");
1317
- o.width = r.naturalWidth, o.height = r.naturalHeight;
1318
- const n = o.getContext("2d");
1319
- n.drawImage(r, 0, 0);
1320
- const a = o.width / t.pageWidth, p = o.height / t.pageHeight, c = Math.min(a, p);
1321
- n.lineCap = "round", n.lineJoin = "round";
1311
+ }), n = document.createElement("canvas");
1312
+ n.width = r.naturalWidth, n.height = r.naturalHeight;
1313
+ const o = n.getContext("2d");
1314
+ o.drawImage(r, 0, 0);
1315
+ const a = n.width / t.pageWidth, p = n.height / t.pageHeight, c = Math.min(a, p);
1316
+ o.lineCap = "round", o.lineJoin = "round";
1322
1317
  for (const i of t.shapes)
1323
- switch (n.strokeStyle = i.color, n.fillStyle = i.color, n.beginPath(), i.type) {
1318
+ switch (o.strokeStyle = i.color, o.fillStyle = i.color, o.beginPath(), i.type) {
1324
1319
  case "pen": {
1325
- n.lineWidth = i.width * c, i.points.forEach((l, s) => s === 0 ? n.moveTo(l.x * a, l.y * p) : n.lineTo(l.x * a, l.y * p)), n.stroke();
1320
+ o.lineWidth = i.width * c, i.points.forEach((l, s) => s === 0 ? o.moveTo(l.x * a, l.y * p) : o.lineTo(l.x * a, l.y * p)), o.stroke();
1326
1321
  break;
1327
1322
  }
1328
1323
  case "rect": {
1329
- n.lineWidth = i.strokeWidth * c, n.roundRect(i.x * a, i.y * p, i.width * a, i.height * p, 3 * c), n.stroke();
1324
+ o.lineWidth = i.strokeWidth * c, o.roundRect(i.x * a, i.y * p, i.width * a, i.height * p, 3 * c), o.stroke();
1330
1325
  break;
1331
1326
  }
1332
1327
  case "circle": {
1333
- n.lineWidth = i.strokeWidth * c, n.ellipse(i.cx * a, i.cy * p, i.rx * a, i.ry * p, 0, 0, Math.PI * 2), n.stroke();
1328
+ o.lineWidth = i.strokeWidth * c, o.ellipse(i.cx * a, i.cy * p, i.rx * a, i.ry * p, 0, 0, Math.PI * 2), o.stroke();
1334
1329
  break;
1335
1330
  }
1336
1331
  case "arrow": {
1337
- const l = i.width * c, s = i.x1 * a, m = i.y1 * p, v = i.x2 * a, h = i.y2 * p;
1338
- n.lineWidth = l, n.lineCap = "butt", n.moveTo(s, m), n.lineTo(v, h), n.stroke(), n.lineCap = "round";
1339
- const b = Math.hypot(v - s, h - m) || 1, x = (v - s) / b, u = (h - m) / b, w = v + x * l, C = h + u * l, N = w - x * 10 * l, H = C - u * 10 * l;
1340
- n.beginPath(), n.moveTo(w, C), n.lineTo(N - u * 3.5 * l, H + x * 3.5 * l), n.lineTo(N + u * 3.5 * l, H - x * 3.5 * l), n.closePath(), n.fill();
1332
+ const l = i.width * c, s = i.x1 * a, h = i.y1 * p, v = i.x2 * a, m = i.y2 * p;
1333
+ o.lineWidth = l, o.lineCap = "butt", o.moveTo(s, h), o.lineTo(v, m), o.stroke(), o.lineCap = "round";
1334
+ const b = Math.hypot(v - s, m - h) || 1, x = (v - s) / b, u = (m - h) / b, w = v + x * l, C = m + u * l, N = w - x * 10 * l, H = C - u * 10 * l;
1335
+ o.beginPath(), o.moveTo(w, C), o.lineTo(N - u * 3.5 * l, H + x * 3.5 * l), o.lineTo(N + u * 3.5 * l, H - x * 3.5 * l), o.closePath(), o.fill();
1341
1336
  break;
1342
1337
  }
1343
1338
  }
1344
- return o.toDataURL("image/png");
1339
+ return n.toDataURL("image/png");
1345
1340
  } catch (r) {
1346
1341
  return console.error("[ui-feedback-plugin] drawAnnotationsOnScreenshot failed:", r), e;
1347
1342
  }
1348
1343
  }
1349
1344
  const F = "ui-feedback-plugin";
1350
- async function qe(e) {
1345
+ async function Oe(e) {
1351
1346
  const { backend: t } = e;
1352
1347
  if (t.provider === "firebase") {
1353
- const { FirebaseAdapter: r } = await import("./firebase-BGU5KpRU.mjs"), o = new r(t);
1354
- return { db: o, screenshot: o };
1348
+ const { FirebaseAdapter: r } = await import("./firebase-BGU5KpRU.mjs"), n = new r(t);
1349
+ return { db: n, screenshot: n };
1355
1350
  }
1356
1351
  if (t.provider === "supabase") {
1357
- const { SupabaseAdapter: r } = await import("./supabase-BUHP2OkK.mjs"), o = new r(t.url, t.anonKey);
1358
- return { db: o, screenshot: o };
1352
+ const { SupabaseAdapter: r } = await import("./supabase-BUHP2OkK.mjs"), n = new r(t.url, t.anonKey);
1353
+ return { db: n, screenshot: n };
1359
1354
  }
1360
1355
  if (t.provider === "aws") {
1361
- const { AWSAdapter: r } = await import("./aws-DyQmIBI9.mjs"), o = new r(t);
1362
- return { db: o, screenshot: o };
1356
+ const { AWSAdapter: r } = await import("./aws-DyQmIBI9.mjs"), n = new r(t);
1357
+ return { db: n, screenshot: n };
1363
1358
  }
1364
1359
  if (t.provider === "local") {
1365
- const { LocalAdapter: r } = await import("./local-CqZPr-Eb.mjs"), o = new r();
1366
- return { db: o, screenshot: o };
1360
+ const { LocalAdapter: r } = await import("./local-CqZPr-Eb.mjs"), n = new r();
1361
+ return { db: n, screenshot: n };
1367
1362
  }
1368
1363
  throw new Error("[ui-feedback-plugin] Unknown backend provider");
1369
1364
  }
1370
- function Fe(e) {
1365
+ function Pe(e) {
1371
1366
  var p;
1372
1367
  if (customElements.get(F))
1373
1368
  return console.warn("[ui-feedback-plugin] Already initialized."), () => {
1374
1369
  };
1375
- const t = ((p = e.theme) == null ? void 0 : p.primaryColor) ?? "#6366f1", r = e.projectKey ?? "default", o = e.position ?? "bottom-right";
1370
+ const t = ((p = e.theme) == null ? void 0 : p.primaryColor) ?? "#6366f1", r = e.projectKey ?? "default", n = e.position ?? "bottom-right";
1376
1371
  k({ config: e });
1377
- class n extends HTMLElement {
1372
+ class o extends HTMLElement {
1378
1373
  constructor() {
1379
1374
  super();
1380
1375
  O(this, "shadow");
@@ -1385,9 +1380,9 @@ function Fe(e) {
1385
1380
  }
1386
1381
  async connectedCallback() {
1387
1382
  const l = document.createElement("style");
1388
- l.textContent = ye(t), this.shadow.appendChild(l);
1383
+ l.textContent = xe(t), this.shadow.appendChild(l);
1389
1384
  try {
1390
- const s = await qe(e);
1385
+ const s = await Oe(e);
1391
1386
  this.db = s.db, this.screenshot = s.screenshot;
1392
1387
  } catch (s) {
1393
1388
  console.error("[ui-feedback-plugin] Failed to initialise backend:", s);
@@ -1400,10 +1395,10 @@ function Fe(e) {
1400
1395
  (l = this.unsubscribe) == null || l.call(this);
1401
1396
  }
1402
1397
  mount() {
1403
- const l = J(window.location.href);
1404
- Ne(this.shadow, this.db, () => this.startAnnotation()), be(
1398
+ const l = Q(window.location.href);
1399
+ Te(this.shadow, this.db, () => this.startAnnotation()), ve(
1405
1400
  this.shadow,
1406
- o,
1401
+ n,
1407
1402
  () => this.startAnnotation(),
1408
1403
  () => k({ panelOpen: !A().panelOpen })
1409
1404
  ), this.unsubscribe = this.db.subscribeToComments(l, r, (s) => {
@@ -1411,11 +1406,11 @@ function Fe(e) {
1411
1406
  });
1412
1407
  }
1413
1408
  async startAnnotation() {
1414
- let l = oe();
1415
- if (!l && (l = await ke(this.shadow), !l))
1409
+ let l = re();
1410
+ if (!l && (l = await we(this.shadow), !l))
1416
1411
  return;
1417
1412
  k({ active: !0, panelOpen: !1 });
1418
- const s = await Me(this.shadow);
1413
+ const s = await Le(this.shadow);
1419
1414
  if (!s) {
1420
1415
  k({ active: !1 });
1421
1416
  return;
@@ -1423,57 +1418,58 @@ function Fe(e) {
1423
1418
  k({ active: !1 }), this.showToast("Saving comment…", "info");
1424
1419
  try {
1425
1420
  await this.saveComment(l, s.text, s.shapes), this.showToast("Comment saved!", "success");
1426
- } catch (m) {
1427
- console.error("[ui-feedback-plugin] Failed to save comment:", m), this.showToast("Failed to save — check the browser console for details.", "error");
1421
+ } catch (h) {
1422
+ console.error("[ui-feedback-plugin] Failed to save comment:", h), this.showToast("Failed to save — check the browser console for details.", "error");
1428
1423
  return;
1429
1424
  }
1430
1425
  k({ panelOpen: !0 });
1431
1426
  }
1432
- async saveComment(l, s, m) {
1433
- const v = J(window.location.href), h = {
1434
- shapes: m,
1435
- pageWidth: document.documentElement.scrollWidth,
1436
- pageHeight: document.documentElement.scrollHeight
1427
+ async saveComment(l, s, h) {
1428
+ const v = Q(window.location.href), m = {
1429
+ shapes: h,
1430
+ // Shapes are in viewport coordinates; the screenshot covers just the visible viewport.
1431
+ pageWidth: document.documentElement.clientWidth,
1432
+ pageHeight: window.innerHeight
1437
1433
  };
1438
1434
  this.style.visibility = "hidden";
1439
1435
  let b;
1440
1436
  try {
1441
- b = await $e();
1437
+ b = await He();
1442
1438
  } finally {
1443
1439
  this.style.visibility = "";
1444
1440
  }
1445
- b = await Oe(b, h);
1441
+ b = await We(b, m);
1446
1442
  const x = {
1447
1443
  pageUrl: v,
1448
1444
  projectKey: r,
1449
1445
  authorName: l,
1450
1446
  text: s,
1451
1447
  screenshotUrl: "",
1452
- annotation: h,
1448
+ annotation: m,
1453
1449
  resolved: !1,
1454
1450
  createdAt: Date.now()
1455
1451
  }, u = await this.db.addComment(x), w = await this.screenshot.uploadScreenshot(u, b);
1456
1452
  await this.db.updateComment(u, { screenshotUrl: w });
1457
1453
  }
1458
1454
  showToast(l, s) {
1459
- const m = this.shadow.querySelector(".ufp-toast");
1460
- m == null || m.remove();
1461
- const v = { info: "#6366f1", success: "#10b981", error: "#ef4444" }, h = document.createElement("div");
1462
- h.className = "ufp-toast", h.style.cssText = `
1455
+ const h = this.shadow.querySelector(".ufp-toast");
1456
+ h == null || h.remove();
1457
+ const v = { info: "#6366f1", success: "#10b981", error: "#ef4444" }, m = document.createElement("div");
1458
+ m.className = "ufp-toast", m.style.cssText = `
1463
1459
  position:fixed;bottom:80px;left:50%;transform:translateX(-50%);
1464
1460
  background:${v[s]};color:white;padding:10px 20px;border-radius:8px;
1465
1461
  font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,sans-serif;
1466
1462
  font-size:13px;font-weight:500;z-index:2147483647;
1467
1463
  box-shadow:0 4px 12px rgba(0,0,0,0.2);pointer-events:none;
1468
1464
  max-width:360px;text-align:center;
1469
- `, h.textContent = l, this.shadow.appendChild(h), setTimeout(() => h.remove(), s === "error" ? 6e3 : 2500);
1465
+ `, m.textContent = l, this.shadow.appendChild(m), setTimeout(() => m.remove(), s === "error" ? 6e3 : 2500);
1470
1466
  }
1471
1467
  }
1472
- customElements.define(F, n);
1468
+ customElements.define(F, o);
1473
1469
  const a = document.createElement(F);
1474
1470
  return document.body.appendChild(a), () => a.remove();
1475
1471
  }
1476
1472
  export {
1477
- Fe as initFeedbackPlugin
1473
+ Pe as initFeedbackPlugin
1478
1474
  };
1479
1475
  //# sourceMappingURL=ui-feedback-plugin.es.js.map