PageSourceSearch

https://counter2.personyze.com/webdriver/simulator-placeholder-debug.js?v=1790277591

js personyze.com collected 2026-09-25 14:58:47 UTC 108,689 bytes, 3,829 lines download raw bytes

1/*! Personyze on-site components (fresh-service/webdriver-apps) */
2(function()
3{'use strict';
4// ../../../../deno-dir/npm/registry.npmjs.org/preact/10.22.0/dist/preact.module.js
5var n;
6var l;
7var u;
8var t;
9var i;
10var o;
11var r;
12var f;
13var e;
14var c;
15var s;
16var a;
17var h = {};
18var p = [];
19var v = /acit|ex(?:s|g|n|p|$)|rph|grid|ows|mnc|ntw|ine[ch]|zoo|^ord|itera/i;
20var y = Array.isArray;
21function d(n2, l3) {
22  for (var u4 in l3) n2[u4] = l3[u4];
23  return n2;
24}
25function w(n2) {
26  var l3 = n2.parentNode;
27  l3 && l3.removeChild(n2);
28}
29function _(l3, u4, t3) {
30  var i4, o3, r3, f4 = {};
31  for (r3 in u4) "key" == r3 ? i4 = u4[r3] : "ref" == r3 ? o3 = u4[r3] : f4[r3] = u4[r3];
32  if (arguments.length > 2 && (f4.children = arguments.length > 3 ? n.call(arguments, 2) : t3), "function" == typeof l3 && null != l3.defaultProps) for (r3 in l3.defaultProps) void 0 === f4[r3] && (f4[r3] = l3.defaultProps[r3]);
33  return g(l3, f4, i4, o3, null);
34}
35function g(n2, t3, i4, o3, r3) {
36  var f4 = {
37    type: n2,
38    props: t3,
39    key: i4,
40    ref: o3,
41    __k: null,
42    __: null,
43    __b: 0,
44    __e: null,
45    __d: void 0,
46    __c: null,
47    constructor: void 0,
48    __v: null == r3 ? ++u : r3,
49    __i: -1,
50    __u: 0
51  };
52  return null == r3 && null != l.vnode && l.vnode(f4), f4;
53}
54function k(n2) {
55  return n2.children;
56}
57function b(n2, l3) {
58  this.props = n2, this.context = l3;
59}
60function x(n2, l3) {
61  if (null == l3) return n2.__ ? x(n2.__, n2.__i + 1) : null;
62  for (var u4; l3 < n2.__k.length; l3++) if (null != (u4 = n2.__k[l3]) && null != u4.__e) return u4.__e;
63  return "function" == typeof n2.type ? x(n2) : null;
64}
65function C(n2) {
66  var l3, u4;
67  if (null != (n2 = n2.__) && null != n2.__c) {
68    for (n2.__e = n2.__c.base = null, l3 = 0; l3 < n2.__k.length; l3++) if (null != (u4 = n2.__k[l3]) && null != u4.__e) {
69      n2.__e = n2.__c.base = u4.__e;
70      break;
71    }
72    return C(n2);
73  }
74}
75function M(n2) {
76  (!n2.__d && (n2.__d = true) && i.push(n2) && !P.__r++ || o !== l.debounceRendering) && ((o = l.debounceRendering) || r)(P);
77}
78function P() {
79  var n2, u4, t3, o3, r3, e3, c3, s3;
80  for (i.sort(f); n2 = i.shift(); ) n2.__d && (u4 = i.length, o3 = void 0, e3 = (r3 = (t3 = n2).__v).__e, c3 = [], s3 = [], t3.__P && ((o3 = d({}, r3)).__v = r3.__v + 1, l.vnode && l.vnode(o3), O(t3.__P, o3, r3, t3.__n, t3.__P.namespaceURI, 32 & r3.__u ? [
81    e3
82  ] : null, c3, null == e3 ? x(r3) : e3, !!(32 & r3.__u), s3), o3.__v = r3.__v, o3.__.__k[o3.__i] = o3, j(c3, o3, s3), o3.__e != e3 && C(o3)), i.length > u4 && i.sort(f));
83  P.__r = 0;
84}
85function S(n2, l3, u4, t3, i4, o3, r3, f4, e3, c3, s3) {
86  var a3, v3, y3, d3, w3, _3 = t3 && t3.__k || p, g2 = l3.length;
87  for (u4.__d = e3, $(u4, l3, _3), e3 = u4.__d, a3 = 0; a3 < g2; a3++) null != (y3 = u4.__k[a3]) && "boolean" != typeof y3 && "function" != typeof y3 && (v3 = -1 === y3.__i ? h : _3[y3.__i] || h, y3.__i = a3, O(n2, y3, v3, i4, o3, r3, f4, e3, c3, s3), d3 = y3.__e, y3.ref && v3.ref != y3.ref && (v3.ref && N(v3.ref, null, y3), s3.push(y3.ref, y3.__c || d3, y3)), null == w3 && null != d3 && (w3 = d3), 65536 & y3.__u || v3.__k === y3.__k ? (e3 && !e3.isConnected && (e3 = x(v3)), e3 = I(y3, e3, n2)) : "function" == typeof y3.type && void 0 !== y3.__d ? e3 = y3.__d : d3 && (e3 = d3.nextSibling), y3.__d = void 0, y3.__u &= -196609);
88  u4.__d = e3, u4.__e = w3;
89}
90function $(n2, l3, u4) {
91  var t3, i4, o3, r3, f4, e3 = l3.length, c3 = u4.length, s3 = c3, a3 = 0;
92  for (n2.__k = [], t3 = 0; t3 < e3; t3++) r3 = t3 + a3, null != (i4 = n2.__k[t3] = null == (i4 = l3[t3]) || "boolean" == typeof i4 || "function" == typeof i4 ? null : "string" == typeof i4 || "number" == typeof i4 || "bigint" == typeof i4 || i4.constructor == String ? g(null, i4, null, null, null) : y(i4) ? g(k, {
93    children: i4
94  }, null, null, null) : void 0 === i4.constructor && i4.__b > 0 ? g(i4.type, i4.props, i4.key, i4.ref ? i4.ref : null, i4.__v) : i4) ? (i4.__ = n2, i4.__b = n2.__b + 1, f4 = L(i4, u4, r3, s3), i4.__i = f4, o3 = null, -1 !== f4 && (s3--, (o3 = u4[f4]) && (o3.__u |= 131072)), null == o3 || null === o3.__v ? (-1 == f4 && a3--, "function" != typeof i4.type && (i4.__u |= 65536)) : f4 !== r3 && (f4 === r3 + 1 ? a3++ : f4 > r3 ? s3 > e3 - r3 ? a3 += f4 - r3 : a3-- : f4 < r3 ? f4 == r3 - 1 && (a3 = f4 - r3) : a3 = 0, f4 !== t3 + a3 && (i4.__u |= 65536))) : (o3 = u4[r3]) && null == o3.ke
vendor: 4,430 bytes, lines 94-165
94y && o3.__e && 0 == (131072 & o3.__u) && (o3.__e == n2.__d && (n2.__d = x(o3)), V(o3, o3, false), u4[r3] = null, s3--);
95  if (s3) for (t3 = 0; t3 < c3; t3++) null != (o3 = u4[t3]) && 0 == (131072 & o3.__u) && (o3.__e == n2.__d && (n2.__d = x(o3)), V(o3, o3));
96}
97function I(n2, l3, u4) {
98  var t3, i4;
99  if ("function" == typeof n2.type) {
100    for (t3 = n2.__k, i4 = 0; t3 && i4 < t3.length; i4++) t3[i4] && (t3[i4].__ = n2, l3 = I(t3[i4], l3, u4));
101    return l3;
102  }
103  n2.__e != l3 && (u4.insertBefore(n2.__e, l3 || null), l3 = n2.__e);
104  do {
105    l3 = l3 && l3.nextSibling;
106  } while (null != l3 && 8 === l3.nodeType);
107  return l3;
108}
109function L(n2, l3, u4, t3) {
110  var i4 = n2.key, o3 = n2.type, r3 = u4 - 1, f4 = u4 + 1, e3 = l3[u4];
111  if (null === e3 || e3 && i4 == e3.key && o3 === e3.type && 0 == (131072 & e3.__u)) return u4;
112  if (t3 > (null != e3 && 0 == (131072 & e3.__u) ? 1 : 0)) for (; r3 >= 0 || f4 < l3.length; ) {
113    if (r3 >= 0) {
114      if ((e3 = l3[r3]) && 0 == (131072 & e3.__u) && i4 == e3.key && o3 === e3.type) return r3;
115      r3--;
116    }
117    if (f4 < l3.length) {
118      if ((e3 = l3[f4]) && 0 == (131072 & e3.__u) && i4 == e3.key && o3 === e3.type) return f4;
119      f4++;
120    }
121  }
122  return -1;
123}
124function T(n2, l3, u4) {
125  "-" === l3[0] ? n2.setProperty(l3, null == u4 ? "" : u4) : n2[l3] = null == u4 ? "" : "number" != typeof u4 || v.test(l3) ? u4 : u4 + "px";
126}
127function A(n2, l3, u4, t3, i4) {
128  var o3;
129  n: if ("style" === l3) if ("string" == typeof u4) n2.style.cssText = u4;
130  else {
131    if ("string" == typeof t3 && (n2.style.cssText = t3 = ""), t3) for (l3 in t3) u4 && l3 in u4 || T(n2.style, l3, "");
132    if (u4) for (l3 in u4) t3 && u4[l3] === t3[l3] || T(n2.style, l3, u4[l3]);
133  }
134  else if ("o" === l3[0] && "n" === l3[1]) o3 = l3 !== (l3 = l3.replace(/(PointerCapture)$|Capture$/i, "$1")), l3 = l3.toLowerCase() in n2 || "onFocusOut" === l3 || "onFocusIn" === l3 ? l3.toLowerCase().slice(2) : l3.slice(2), n2.l || (n2.l = {}), n2.l[l3 + o3] = u4, u4 ? t3 ? u4.u = t3.u : (u4.u = e, n2.addEventListener(l3, o3 ? s : c, o3)) : n2.removeEventListener(l3, o3 ? s : c, o3);
135  else {
136    if ("http://www.w3.org/2000/svg" == i4) l3 = l3.replace(/xlink(H|:h)/, "h").replace(/sName$/, "s");
137    else if ("width" != l3 && "height" != l3 && "href" != l3 && "list" != l3 && "form" != l3 && "tabIndex" != l3 && "download" != l3 && "rowSpan" != l3 && "colSpan" != l3 && "role" != l3 && l3 in n2) try {
138      n2[l3] = null == u4 ? "" : u4;
139      break n;
140    } catch (n3) {
141    }
142    "function" == typeof u4 || (null == u4 || false === u4 && "-" !== l3[4] ? n2.removeAttribute(l3) : n2.setAttribute(l3, u4));
143  }
144}
145function F(n2) {
146  return function(u4) {
147    if (this.l) {
148      var t3 = this.l[u4.type + n2];
149      if (null == u4.t) u4.t = e++;
150      else if (u4.t < t3.u) return;
151      return t3(l.event ? l.event(u4) : u4);
152    }
153  };
154}
155function O(n2, u4, t3, i4, o3, r3, f4, e3, c3, s3) {
156  var a3, h3, p3, v3, w3, _3, g2, m2, x3, C3, M2, P2, $2, I2, H, L2 = u4.type;
157  if (void 0 !== u4.constructor) return null;
158  128 & t3.__u && (c3 = !!(32 & t3.__u), r3 = [
159    e3 = u4.__e = t3.__e
160  ]), (a3 = l.__b) && a3(u4);
161  n: if ("function" == typeof L2) try {
162    if (m2 = u4.props, x3 = (a3 = L2.contextType) && i4[a3.__c], C3 = a3 ? x3 ? x3.props.value : a3.__ : i4, t3.__c ? g2 = (h3 = u4.__c = t3.__c).__ = h3.__E : ("prototype" in L2 && L2.prototype.render ? u4.__c = h3 = new L2(m2, C3) : (u4.__c = h3 = new b(m2, C3), h3.constructor = L2, h3.render = q), x3 && x3.sub(h3), h3.props = m2, h3.state || (h3.state = {}), h3.context = C3, h3.__n = i4, p3 = h3.__d = true, h3.__h = [], h3._sb = []), null == h3.__s && (h3.__s = h3.state), null != L2.getDerivedStateFromProps && (h3.__s == h3.state && (h3.__s = d({}, h3.__s)), d(h3.__s, L2.getDerivedStateFromProps(m2, h3.__s))), v3 = h3.props, w3 = h3.state, h3.__v = u4, p3) null == L2.getDerivedStateFromProps && null != h3.componentWillMount && h3.componentWillMount(), null != h3.componentDidMount && h3.__h.push(h3.componentDidMount);
163    else {
164      if (null == L2.getDerivedStateFromProps && m2 !== v3 && null != h3.componentWillReceiveProps && h3.componentWillReceiveProps(m2, C3), !h3.__e && (null != h3.shouldComponentUpdate && false === h3.shouldComponentUpdate(m2, h3.__s, C3) || u4.__v === t3.__v)) {
165        for (u4.__v !== t3.__v && (h3.props = m2, h3.state = h3.__s, h3.__d = false), u4.__e = t3.__e, u4.__k = t3.__k, u4.__k.forEac
vendor: 1,103 bytes, lines 165-181
165h(function(n3) {
166          n3 && (n3.__ = u4);
167        }), M2 = 0; M2 < h3._sb.length; M2++) h3.__h.push(h3._sb[M2]);
168        h3._sb = [], h3.__h.length && f4.push(h3);
169        break n;
170      }
171      null != h3.componentWillUpdate && h3.componentWillUpdate(m2, h3.__s, C3), null != h3.componentDidUpdate && h3.__h.push(function() {
172        h3.componentDidUpdate(v3, w3, _3);
173      });
174    }
175    if (h3.context = C3, h3.props = m2, h3.__P = n2, h3.__e = false, P2 = l.__r, $2 = 0, "prototype" in L2 && L2.prototype.render) {
176      for (h3.state = h3.__s, h3.__d = false, P2 && P2(u4), a3 = h3.render(h3.props, h3.state, h3.context), I2 = 0; I2 < h3._sb.length; I2++) h3.__h.push(h3._sb[I2]);
177      h3._sb = [];
178    } else do {
179      h3.__d = false, P2 && P2(u4), a3 = h3.render(h3.props, h3.state, h3.context), h3.state = h3.__s;
180    } while (h3.__d && ++$2 < 25);
181    h3.state = h3.__s, null != h3.getChildContext && (i4 = d(d({}, i4), h3.getChildContext())), p3 || null == h3.getSnapshotBeforeUpdate || (_3 = h3.getSnapshotBeforeUpdate(v3, w3)), S(n2, y(H = null != a3 && a3.type === k && null == a3.ke
181y ? a3.props.children : a3) ? H : [
182      H
183    ], u4, t3, i4, o3, r3, f4, e3, c3, s3), h3.base = u4.__e, u4.__u &= -161, h3.__h.length && f4.push(h3), g2 && (h3.__E = h3.__ = null);
184  } catch (n3) {
185    u4.__v = null, c3 || null != r3 ? (u4.__e = e3, u4.__u |= c3 ? 160 : 32, r3[r3.indexOf(e3)] = null) : (u4.__e = t3.__e, u4.__k = t3.__k), l.__e(n3, u4, t3);
186  }
187  else null == r3 && u4.__v === t3.__v ? (u4.__k = t3.__k, u4.__e = t3.__e) : u4.__e = z(t3.__e, u4, t3, i4, o3, r3, f4, c3, s3);
188  (a3 = l.diffed) && a3(u4);
189}
190function j(n2, u4, t3) {
191  u4.__d = void 0;
192  for (var i4 = 0; i4 < t3.length; i4++) N(t3[i4], t3[++i4], t3[++i4]);
193  l.__c && l.__c(u4, n2), n2.some(function(u5) {
194    try {
195      n2 = u5.__h, u5.__h = [], n2.some(function(n3) {
196        n3.call(u5);
197      });
198    } catch (n3) {
199      l.__e(n3, u5.__v);
200    }
201  });
202}
203function z(l3, u4, t3, i4, o3, r3, f4, e3, c3) {
204  var s3, a3, p3, v3, d3, _3, g2, m2 = t3.props, k3 = u4.props, b2 = u4.type;
205  if ("svg" === b2 ? o3 = "http://www.w3.org/2000/svg" : "math" === b2 ? o3 = "http://www.w3.org/1998/Math/MathML" : o3 || (o3 = "http://www.w3.org/1999/xhtml"), null != r3) {
206    for (s3 = 0; s3 < r3.length; s3++) if ((d3 = r3[s3]) && "setAttribute" in d3 == !!b2 && (b2 ? d3.localName === b2 : 3 === d3.nodeType)) {
207      l3 = d3, r3[s3] = null;
208      break;
209    }
210  }
211  if (null == l3) {
212    if (null === b2) return document.createTextNode(k3);
213    l3 = document.createElementNS(o3, b2, k3.is && k3), r3 = null, e3 = false;
214  }
215  if (null === b2) m2 === k3 || e3 && l3.data === k3 || (l3.data = k3);
216  else {
217    if (r3 = r3 && n.call(l3.childNodes), m2 = t3.props || h, !e3 && null != r3) for (m2 = {}, s3 = 0; s3 < l3.attributes.length; s3++) m2[(d3 = l3.attributes[s3]).name] = d3.value;
218    for (s3 in m2) if (d3 = m2[s3], "children" == s3) ;
219    else if ("dangerouslySetInnerHTML" == s3) p3 = d3;
220    else if ("key" !== s3 && !(s3 in k3)) {
221      if ("value" == s3 && "defaultValue" in k3 || "checked" == s3 && "defaultChecked" in k3) continue;
222      A(l3, s3, null, d3, o3);
223    }
224    for (s3 in k3) d3 = k3[s3], "children" == s3 ? v3 = d3 : "dangerouslySetInnerHTML" == s3 ? a3 = d3 : "value" == s3 ? _3 = d3 : "checked" == s3 ? g2 = d3 : "key" === s3 || e3 && "function" != typeof d3 || m2[s3] === d3 || A(l3, s3, d3, m2[s3], o3);
225    if (a3) e3 || p3 && (a3.__html === p3.__html || a3.__html === l3.innerHTML) || (l3.innerHTML = a3.__html), u4.__k = [];
226    else if (p3 && (l3.innerHTML = ""), S(l3, y(v3) ? v3 : [
227      v3
228    ], u4, t3, i4, "foreignObject" === b2 ? "http://www.w3.org/1999/xhtml" : o3, r3, f4, r3 ? r3[0] : t3.__k && x(t3, 0), e3, c3), null != r3) for (s3 = r3.length; s3--; ) null != r3[s3] && w(r3[s3]);
229    e3 || (s3 = "value", void 0 !== _3 && (_3 !== l3[s3] || "progress" === b2 && !_3 || "option" === b2 && _3 !== m2[s3]) && A(l3, s3, _3, m2[s3], o3), s3 = "checked", void 0 !== g2 && g2 !== l3[s3] && A(l3, s3, g2, m2[s3], o3));
230  }
231  return l3;
232}
233function N(n2, u4, t3) {
234  try {
235    "function" == typeof n2 ? n2(u4) : n2.current = u4;
236  } catch (n3) {
237    l.__e(n3, t3);
238  }
239}
240function V(n2, u4, t3) {
241  var i4, o3;
242  if (l.unmount && l.unmount(n2), (i4 = n2.ref) && (i4.current && i4.current !== n2.__e || N(i4, null, u4)), null != (i4 = n2.__c)) {
243    if (i4.componentWillUnmount) try {
244      i4.componentWillUnmount();
245    } catch (n3) {
246      l.__e(n3, u4);
247    }
248    i4.base = i4.__P = null;
249  }
250  if (i4 = n2.__k) for (o3 = 0; o3 < i4.length; o3++) i4[o3] && V(i4[o3], u4, t3 || "function" != typeof n2.type);
251  t3 || null == n2.__e || w(n2.__e), n2.__c = n2.__ = n2.__e = n2.__d = void 0;
252}
253function q(n2, l3, u4) {
254  return this.constructor(n2, u4);
255}
256function B(u4, t3, i4) {
257  var o3, r3, f4, e3;
258  l.__ && l.__(u4, t3), r3 = (o3 = "function" == typeof i4) ? null : i4 && i4.__k || t3.__k, f4 = [], e3 = [], O(t3, u4 = (!o3 && i4 || t3).__k = _(k, null, [
259    u4
260  ]), r3 || h, h, t3.namespaceURI, !o3 && i4 ? [
261    i4
262  ] : r3 ? null : t3.firstChild ? n.call(t3.childNodes) : null, f4, !o3 && i4 ? i4 : r3 ? r3.__e : t3.firstChild, o3, e3), j(f4, u4, e3);
263}
264n = p.slice, l = {
265  __e: function(n2, l3, u4, t3) {
266    for (var i4, o3, r3; l3 = l3.__; ) if ((i4 = l3.__c) && !i4.__) try {
267      if ((o3 = i4.constructor) && null != o3.getDerivedStateFromError && (i4.setState(o3.getDerivedStateFromError(n2)), r3 = i4.__d), null != i4.componentDidCatch && (i4.componentDidCatch(n2, t3 || {}), r3 = i4.__d), r3) return i4.__E = i4;
268    } catch (l4) {
269      n2 = l4;
270    }
271    throw n2;
272  }
273}, u = 0, t = function(n2) {
274  return null != n2 && null == n2.constructor;
275}, b.prototype.setState = function(n2, l3) {
276  var u4;
277  u4 = null != this.__s && this.__s !== this.state ? this.__s : this.__s = d({}, this.state), "function" == typeof n2 && (n2 = n2(d({}, u4), this.props)), n2 && d(u4, n2), null != n2 && this.__v && (l3 && this._sb.push(l3), M(this));
278}, b.prototype.forceUpdate = function(n2) {
279  this.__v && (this.__e = true, n2 && this.__h.push(n2), M(this));
280}, b.prototype.render = k, i = [], r = "function" == typeof Promise ? Promise.prototype.then.bind(Prom
280ise.resolve()) : setTimeout, f = function(n2, l3) {
281  return n2.__v.__b - l3.__v.__b;
282}, P.__r = 0, e = 0, c = F(false), s = F(true), a = 0;
283
vendor: 715 bytes, lines 284-312
284// ../../../../deno-dir/npm/registry.npmjs.org/preact/10.22.0/jsx-runtime/dist/jsxRuntime.module.js
285var f2 = 0;
286var i2 = Array.isArray;
287function u2(e3, t3, n2, o3, i4, u4) {
288  t3 || (t3 = {});
289  var a3, c3, p3 = t3;
290  if ("ref" in p3) for (c3 in p3 = {}, t3) "ref" == c3 ? a3 = t3[c3] : p3[c3] = t3[c3];
291  var l3 = {
292    type: e3,
293    props: p3,
294    key: n2,
295    ref: a3,
296    __k: null,
297    __: null,
298    __b: 0,
299    __e: null,
300    __d: void 0,
301    __c: null,
302    constructor: void 0,
303    __v: --f2,
304    __i: -1,
305    __u: 0,
306    __source: i4,
307    __self: u4
308  };
309  if ("function" == typeof e3 && (a3 = e3.defaultProps)) for (c3 in a3) void 0 === p3[c3] && (p3[c3] = a3[c3]);
310  return l.vnode && l.vnode(l3), l3;
311}
312
313// ../../../../deno-dir/npm/registry.npmjs.org/preact/10.22.0/hooks/dist/hooks.module.js
314var t2;
315var r2;
316var u3;
317var i3;
318var o2 = 0;
319var f3 = [];
320var c2 = [];
321var e2 = l;
322var a2 = e2.__b;
323var v2 = e2.__r;
324var l2 = e2.diffed;
325var m = e2.__c;
326var s2 = e2.unmount;
327var d2 = e2.__;
328function h2(n2, t3) {
329  e2.__h && e2.__h(r2, n2, o2 || t3), o2 = 0;
330  var u4 = r2.__H || (r2.__H = {
331    __: [],
332    __h: []
333  });
334  return n2 >= u4.__.length && u4.__.push({
335    __V: c2
336  }), u4.__[n2];
337}
338function p2(n2) {
339  return o2 = 1, y2(D, n2);
340}
341function y2(n2, u4, i4) {
342  var o3 = h2(t2++, 2);
343  if (o3.t = n2, !o3.__c && (o3.__ = [
344    i4 ? i4(u4) : D(void 0, u4),
345    function(n3) {
346      var t3 = o3.__N ? o3.__N[0] : o3.__[0], r3 = o3.t(t3, n3);
347      t3 !== r3 && (o3.__N = [
348        r3,
349        o3.__[1]
350      ], o3.__c.setState({}));
351    }
352  ], o3.__c = r2, !r2.u)) {
353    var f4 = function(n3, t3, r3) {
354      if (!o3.__c.__H) return true;
355      var u5 = o3.__c.__H.__.filter(function(n4) {
356        return !!n4.__c;
357      });
358      if (u5.every(function(n4) {
359        return !n4.__N;
360      })) return !c3 || c3.call(this, n3, t3, r3);
361      var i5 = false;
362      return u5.forEach(function(n4) {
363        if (n4.__N) {
364          var t4 = n4.__[0];
365          n4.__ = n4.__N, n4.__N = void 0, t4 !== n4.__[0] && (i5 = true);
366        }
367      }), !(!i5 && o3.__c.props === n3) && (!c3 || c3.call(this, n3, t3, r3));
368    };
369    r2.u = true;
370    var c3 = r2.shouldComponentUpdate, e3 = r2.componentWillUpdate;
371    r2.componentWillUpdate = function(n3, t3, r3) {
372      if (this.__e) {
373        var u5 = c3;
374        c3 = void 0, f4(n3, t3, r3), c3 = u5;
375      }
376      e3 && e3.call(this, n3, t3, r3);
377    }, r2.shouldComponentUpdate = f4;
378  }
379  return o3.__N || o3.__;
380}
381function _2(n2, u4) {
382  var i4 = h2(t2++, 3);
383  !e2.__s && C2(i4.__H, u4) && (i4.__ = n2, i4.i = u4, r2.__H.__h.push(i4));
384}
385function F2(n2) {
386  return o2 = 5, q2(function() {
387    return {
388      current: n2
389    };
390  }, []);
391}
392function q2(n2, r3) {
393  var u4 = h2(t2++, 7);
394  return C2(u4.__H, r3) ? (u4.__V = n2(), u4.i = r3, u4.__h = n2, u4.__V) : u4.__;
395}
396function x2(n2, t3) {
397  return o2 = 8, q2(function() {
398    return n2;
399  }, t3);
400}
401function j2() {
402  for (var n2; n2 = f3.shift(); ) if (n2.__P && n2.__H) try {
403    n2.__H.__h.forEach(z2), n2.__H.__h.forEach(B2), n2.__H.__h = [];
404  } catch (t3) {
405    n2.__H.__h = [], e2.__e(t3, n2.__v);
406  }
407}
408e2.__b = function(n2) {
409  r2 = null, a2 && a2(n2);
410}, e2.__ = function(n2, t3) {
411  n2 && t3.__k && t3.__k.__m && (n2.__m = t3.__k.__m), d2 && d2(n2, t3);
412}, e2.__r = function(n2) {
413  v2 && v2(n2), t2 = 0;
414  var i4 = (r2 = n2.__c).__H;
415  i4 && (u3 === r2 ? (i4.__h = [], r2.__h = [], i4.__.forEach(function(n3) {
416    n3.__N && (n3.__ = n3.__N), n3.__V = c2, n3.__N = n3.i = void 0;
417  })) : (i4.__h.forEach(z2), i4.__h.forEach(B2), i4.__h = [], t2 = 0)), u3 = r2;
418}, e2.diffed = function(n2) {
419  l2 && l2(n2);
420  var t3 = n2.__c;
421  t3 && t3.__H && (t3.__H.__h.length && (1 !== f3.push(t3) && i3 === e2.requestAnimationFrame || ((i3 = e2.requestAnimationFrame) || w2)(j2)), t3.__H.__.forEach(function(n3) {
422    n3.i && (n3.__H = n3.i), n3.__V !== c2 && (n3.__ = n3.__V), n3.i = void 0, n3.__V = c2;
423  })), u3 = r2 = null;
424}, e2.__c = function(n2, t3) {
425  t3.some(function(n3) {
426    try {
427      n3.__h.forEach(z2), n3.__h = n3.__h.filter(function(n4) {
428        return !n4.__ || B2(n4);
429      });
430    } catch (r3) {
431      t3.some(function(n4) {
432        n4.__h && (n4.__h = []);
433      }), t3 = [], e2.__e(r3, n3.__v);
434    }
435  }), m && m(n2, t3);
436}, e2.unmount = function(n2) {
437  s2 && s2(n2);
438  var t3, r3 = n2.__c;
439  r3 && r3.__H && (r3.__H.__.forEach(function(n3) {
440    try {
441      z2(n3);
442    } catch (n4) {
443      t3 = n4;
444    }
445  }), r3.__H = void 0, t3 && e2.__e(t3, r3.__v));
446};
447var k2 = "function" == typeof requestAnimationFrame;
448function w2(n2) {
449  var t3, r3 = function() {
450    clearTimeout(u4), k2 && cancelAnimationFrame(t3), setTimeout(n2);
451  }, u4 = setTimeout(r3, 100);
452  k2 && (t3 = requestAnimationFrame(r3));
453}
454function z2(n2) {
455  var t3 = r2, u4 = n2.__c;
456  "function" == typeof u4 && (n2.__c = void 0, u4()), r2 = t3;
457}
458function B2(n2) {
459  var t3 = r2;
460  n2.__c = n2.__(), r2 = t3;
461}
462function C2(n2, t3) {
463  return !n2 || n2.length !== t3.length || t3.some(function(t4, r3) {
464    return t4 !== n2[r3];
465  });
466}
467function D(n2, t3) {
468  return "function" == typeof t3 ? t3(n2) : t3;
469}
470
471// src/components/SimulatorPanel.tsx
472var PANEL_STYLE = `	.qs-panel
473	{	--qs-chrome: #12182A;
474		--qs-chrome-2: #171D31;
475		--qs-chrome-3: #1E2640;
476		--qs-line: rgba(255, 255, 255, 0.08);
477		--qs-line-2: rgba(255, 255, 255, 0.14);
478		--qs-fg: #E8EDF7;
479		--qs-muted: #94A3C1;
480		--qs-muted-2: #6A7698;
481		--qs-brand: #12B886;
482		--qs-brand-soft: rgba(18, 184, 134, 0.14);
483		--qs-brand-fg: #7BDFAE;
484		--qs-danger-soft: rgba(239, 68, 68, 0.14);
485		--qs-danger-fg: #FFB4B4;
486		--qs-mono: ui-monospace, Menlo, Consolas, monospace;
487
488		position: fixed;
489		top: 0;
490		right: 0;
491		z-index: 2147483647;
492		display: flex;
493		flex-direction: column;
494		box-sizing: border-box;
495		width: 30em;
496		max-width: 85vw;
497		height: 100vh;
498		border-left: 1px solid var(--qs-line);
499		background-color: var(--qs-chrome);
500		color: var(--qs-fg);
501		direction: ltr;
502		text-align: left;
503		font: normal normal 400 13px/1.45 -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
504		box-shadow: 0 0 2em rgba(0, 0, 0, 0.45);
505	}
506	.qs-panel.qs-left
507	{	right: auto;
508		left: 0;
509		border-left: none;
510		border-right: 1px solid var(--qs-line);
511	}
512
513	.qs-panel *
514	{	box-sizing: border-box;
515	}
516
517	/*	Every icon here is an inline <svg> with a viewBox and no width/height of its own, so without
518		this it stretches to fill whatever flex line it lands on.
519	 */
520	.qs-panel svg,
521	.qs-handle svg
522	{	flex: 0 0 auto;
523		width: 1.1em;
524		height: 1.1em;
525	}
526
527	/* ===== header ===== */
528	.qs-head
529	{	display: flex;
530		flex: 0 0 auto;
531		align-items: center;
532		gap: 0.5em;
533		padding: 0.7em 0.8em;
534		border-bottom: 1px solid var(--qs-line);
535	}
536	.qs-logo
537	{	width: auto;
538		height: 2.2em;
539		border: none;
540	}
541	.qs-title
542	{	flex: 10000 1 0;
543		min-width: 0;
544	}
545	.qs-title-main
546	{	font-size: 100%;
547		font-weight: 700;
548		letter-spacing: 0.04em;
549	}
550	.qs-title-sub
551	{	color: var(--qs-muted);
552		font-size: 85%;
553	}
554	.qs-icon
555	{	display: flex;
556		flex: 0 0 auto;
557		align-items: center;
558		justify-content: center;
559		width: 1.9em;
560		height: 1.9em;
561		padding: 0;
562		border: none;
563		border-radius: 0.4em;
564		background: transparent;
565		color: var(--qs-muted);
566		font: inherit;
567		cursor: pointer;
568	}
569	.qs-icon:hover
570	{	background-color: var(--qs-chrome-3);
571		color: var(--qs-fg);
572	}
573
574	/* ===== body ===== */
575	.qs-body
576	{	flex: 10000 1 auto;
577		overflow: auto;
578		padding: 0.9em;
579	}
580	.qs-foot
581	{	display: flex;
582		flex: 0 0 auto;
583		gap: 0.6em;
584		align-items: center;
585		justify-content: flex-end;
586		padding: 0.8em;
587		border-top: 1px solid var(--qs-line);
588	}
589
590	.qs-sec + .qs-sec
591	{	margin-top: 1.2em;
592		padding-top: 1.2em;
593		border-top: 1px solid var(--qs-line);
594	}
595	.qs-sec-head
596	{	display: flex;
597		align-items: center;
598		gap: 0.45em;
599		margin: 0 0 0.4em;
600		font-size: 100%;
601		font-weight: 600;
602	}
603	.qs-sec-head svg
604	{	color: var(--qs-brand);
605	}
606	.qs-hint
607	{	margin-bottom: 0.7em;
608		color: var(--qs-muted);
609		font-size: 92%;
610	}
611	.qs-label
612	{	display: block;
613		margin-bottom: 0.3em;
614		color: var(--qs-muted-2);
615		font-size: 84%;
616		font-weight: 600;
617		letter-spacing: 0.04em;
618		text-transform: uppercase;
619	}
620
621	/* ===== collapsible section ===== */
622	.qs-fold + .qs-fold
623	{	margin-top: 0.7em;
624	}
625	.qs-fold
626	{	border: 1px solid var(--qs-line);
627		border-radius: 0.7em;
628		background-color: var(--qs-chrome-2);
629		overflow: hidden;
630	}
631	.qs-fold-head
632	{	display: flex;
633		gap: 0.55em;
634		align-items: center;
635		width: 100%;
636		padding: 0.7em 0.8em;
637		border: none;
638		background: none;
639		color: var(--qs-fg);
640		font: inherit;
641		font-weight: 600;
642		text-align: left;
643		cursor: pointer;
644	}
645	.qs-fold-head:hover
646	{	background-color: var(--qs-chrome-3);
647	}
648	.qs-fold-ico
649	{	display: inline-flex;
650		flex: 0 0 auto;
651		color: var(--qs-brand);
652	}
653	.qs-fold-name
654	{	flex: 10000 1 auto;
655		min-width: 0;
656	}
657	.qs-fold-meta
658	{	flex: 0 1 auto;
659		overflow: hidden;
660		color: var(--qs-muted-2);
661		font-size: 86%;
662		font-weight: 600;
663		white-space: nowrap;
664		text-overflow: ellipsis;
665	}
666	.qs-fold-chev
667	{	display: inline-flex;
668		flex: 0 0 auto;
669		color: var(--qs-muted-2);
670		transition: transform 0.2s;
671	}
672	.qs-fold.qs-closed .qs-fold-chev
673	{	transform: rotate(-90deg);
674	}
675	.qs-fold-body
676	{	padding: 0 0.8em 0.85em;
677	}
678
679	/* ===== source cards ===== */
680	.qs-cards
681	{	display: grid;
682		grid-template-columns: repeat(auto-fill, minmax(8.5em, 1fr));
683		gap: 0.45em;
684	}
685	.qs-card
686	{	display: flex;
687		flex-direction: column;
688		gap: 0.3em;
689		padding: 0.65em 0.6em;
690		border: 1px solid var(--qs-line);
691		border-radius: 0.6em;
692		background-color: var(--qs-chrome-2);
693		color: var(--qs-fg);
694		font: inherit;
695		text-align: left;
696		cursor: pointer;
697	}
698	.qs-card:hover
699	{	border-color: var(--qs-line-2);
700		background-color: var(--qs-chrome-3);
701	}
702	.qs-card.qs-on
703	{	border-color: var(--qs-brand);
704		background-color: var(--qs-brand-soft);
705	}
706	.qs-card-ico
707	{	display: inline-flex;
708		color: var(--qs-muted-2);
709	}
710	.qs-card-ico svg
711	{	width: 1.25em;
712		height: 1.25em;
713	}
714	.qs-card.qs-on .qs-card-ico
715	{	color: var(--qs-brand);
716	}
717	.qs-card-t
718	{	font-size: 92%;
719		font-weight: 600;
720		line-height: 1.25;
721	}
722	/*	The count is the reason these are cards and not a dropdown: "this page has 12 cookies and no
723		META tags" is the answer that decides which one to open. */
724	.qs-card-n
725	{	color: var(--qs-muted-2);
726		font-size: 82%;
727	}
728	.qs-card.qs-on .qs-card-n
729	{	color: var(--qs-brand-fg);
730	}
731	.qs-card-n.qs-none
732	{	opacity: 0.55;
733	}
734
735	/*	Inside a framed section, anything that is itself a card has to sit a shade DARKER than the
736		frame, or it merges into it and the grid reads as loose icons on a panel. The frame is
737		--qs-chrome-2, so its contents drop to --qs-chrome - the same relationship the placement
738		cards (.qs-opt) already have. Scoped to .qs-fold-body because outside a frame these sit on
739		the panel background, where the lighter shade is what makes them stand out at all. */
740	.qs-fold-body .qs-card,
741	.qs-fold-body .qs-tree
742	{	background-color: var(--qs-chrome);
743	}
744
745	.qs-link
746	{	padding: 0;
747		border: none;
748		background: none;
749		color: var(--qs-brand-fg);
750		font: inherit;
751		text-decoration: underline;
752		text-underline-offset: 2px;
753		cursor: pointer;
754	}
755
756	/* ===== radio cards (placement) ===== */
757	.qs-opt
758	{	display: flex;
759		gap: 0.6em;
760		align-items: flex-start;
761		width: 100%;
762		margin-top: 0.4em;
763		padding: 0.6em 0.7em;
764		border: 1px solid var(--qs-line);
765		border-radius: 0.6em;
766		background-color: var(--qs-chrome);
767		color: var(--qs-fg);
768		font: inherit;
769		text-align: left;
770		cursor: pointer;
771	}
772	.qs-opt:hover
773	{	border-color: var(--qs-line-2);
774	}
775	.qs-opt.qs-on
776	{	border-color: var(--qs-brand);
777		background-color: var(--qs-brand-soft);
778	}
779	.qs-opt-radio
780	{	display: inline-flex;
781		flex: 0 0 auto;
782		align-items: center;
783		justify-content: center;
784		width: 1.05em;
785		height: 1.05em;
786		margin-top: 0.15em;
787		border: 1px solid var(--qs-line-2);
788		border-radius: 50%;
789	}
790	.qs-opt.qs-on .qs-opt-radio
791	{	border-color: var(--qs-brand);
792	}
793	.qs-opt.qs-on .qs-opt-radio::after
794	{	content: '';
795		width: 0.5em;
796		height: 0.5em;
797		border-radius: 50%;
798		background-color: var(--qs-brand);
799	}
800	.qs-opt-t
801	{	font-weight: 600;
802	}
803	.qs-opt-d
804	{	margin-top: 0.15em;
805		color: var(--qs-muted);
806		font-size: 88%;
807	}
808
809	/* ===== checkbox row ===== */
810	.qs-chk
811	{	display: flex;
812		gap: 0.55em;
813		align-items: flex-start;
814		margin-top: 0.6em;
815		cursor: pointer;
816	}
817	.qs-chk input
818	{	flex: 0 0 auto;
819		margin: 0.2em 0 0;
820	}
821	.qs-chk-sub
822	{	margin-top: 0.15em;
823		color: var(--qs-muted);
824		font-size: 88%;
825	}
826
827	/* ===== ad-size grid ===== */
828	.qs-sizes
829	{	display: flex;
830		flex-wrap: wrap;
831		gap: 0.4em;
832		margin-top: 0.4em;
833	}
834	.qs-size
835	{	padding: 0.35em 0.6em;
836		border: 1px solid var(--qs-line);
837		border-radius: 0.5em;
838		background-color: var(--qs-chrome);
839		color: var(--qs-muted);
840		font: inherit;
841		font-size: 88%;
842		font-weight: 700;
843		cursor: pointer;
844	}
845	.qs-size:hover
846	{	border-color: var(--qs-line-2);
847		color: var(--qs-fg);
848	}
849	.qs-size.qs-on
850	{	border-color: var(--qs-brand);
851		background-color: var(--qs-brand-soft);
852		color: var(--qs-brand-fg);
853	}
854	.qs-size-custom
855	{	display: flex;
856		gap: 0.4em;
857		align-items: center;
858		margin-top: 0.55em;
859		color: var(--qs-muted);
860		font-size: 88%;
861	}
862	.qs-num
863	{	width: 5em;
864		padding: 0.4em 0.5em;
865		border: 1px solid var(--qs-line);
866		border-radius: 0.5em;
867		background-color: var(--qs-chrome);
868		color: var(--qs-fg);
869		font: inherit;
870		font-size: 100%;
871	}
872
873	/* ===== how broad is this selector ===== */
874	.qs-scope
875	{	margin-top: 0.6em;
876		padding: 0.6em 0.7em;
877		border: 1px solid var(--qs-line);
878		border-radius: 0.6em;
879		background-color: var(--qs-chrome);
880	}
881	.qs-scope-top
882	{	display: flex;
883		gap: 0.5em;
884		align-items: center;
885	}
886	.qs-scope-dot
887	{	flex: 0 0 auto;
888		width: 0.6em;
889		height: 0.6em;
890		border-radius: 50%;
891		background-color: currentColor;
892	}
893	.qs-scope-label
894	{	font-weight: 700;
895	}
896	.qs-scope-tag
897	{	flex: 0 0 auto;
898		margin-left: auto;
899		color: var(--qs-muted-2);
900		font-size: 86%;
901	}
902	.qs-scope-meter
903	{	position: relative;
904		height: 0.35em;
905		margin: 0.5em 0 0.3em;
906		border-radius: 1em;
907		background-color: var(--qs-chrome-3);
908		overflow: hidden;
909	}
910	.qs-scope-bar
911	{	position: absolute;
912		top: 0;
913		left: 0;
914		height: 100%;
915		border-radius: 1em;
916		background-color: currentColor;
917	}
918	.qs-scope-scale
919	{	display: flex;
920		justify-content: space-between;
921		color: var(--qs-muted-2);
922		font-size: 80%;
923	}
924	.qs-scope-desc
925	{	margin-top: 0.4em;
926		color: var(--qs-muted);
927		font-size: 88%;
928	}
929	.qs-narrow
930	{	color: var(--qs-brand-fg);
931	}
932	.qs-wide
933	{	color: #F0B429;
934	}
935
936	/* ===== error banner ===== */
937	.qs-err
938	{	display: flex;
939		gap: 0.6em;
940		align-items: flex-start;
941		margin: 0.8em 0.8em 0;
942		padding: 0.7em 0.8em;
943		border: 1px solid rgba(239, 68, 68, 0.35);
944		border-radius: 0.7em;
945		background-color: var(--qs-danger-soft);
946		color: var(--qs-danger-fg);
947		font-size: 92%;
948	}
949	.qs-err > div
950	{	flex: 10000 1 0;
951	}
952
953	/* ===== controls ===== */
954	.qs-btn
955	{	display: inline-flex;
956		align-items: center;
957		gap: 0.4em;
958		padding: 0.45em 0.9em;
959		border: 1px solid var(--qs-line-2);
960		border-radius: 0.5em;
961		background-color: var(--qs-chrome-2);
962		color: var(--qs-fg);
963		font: inherit;
964		font-weight: 600;
965		white-space: nowrap;
966		cursor: pointer;
967	}
968	.qs-btn:hover:not(:disabled)
969	{	background-color: var(--qs-chrome-3);
970	}
971	.qs-btn:disabled
972	{	opacity: 0.55;
973		cursor: default;
974	}
975	.qs-btn-primary
976	{	border-color: transparent;
977		background-color: var(--qs-brand);
978		color: #08231C;
979	}
980	.qs-btn-primary:hover:not(:disabled)
981	{	background-color: #15CE97;
982	}
983	.qs-btn-row
984	{	display: flex;
985		flex-wrap: wrap;
986		gap: 0.5em;
987		align-items: center;
988	}
989
990	.qs-select
991	{	width: 100%;
992		padding: 0.45em 0.6em;
993		border: 1px solid var(--qs-line);
994		border-radius: 0.5em;
995		background-color: var(--qs-chrome-2);
996		color: var(--qs-fg);
997		font: inherit;
998	}
999
1000	/* ===== pick states ===== */
1001	.qs-callout
1002	{	display: flex;
1003		gap: 0.6em;
1004		align-items: center;
1005		padding: 0.8em;
1006		border: 1px dashed var(--qs-brand);
1007		border-radius: 0.7em;
1008		background-color: var(--qs-brand-soft);
1009		color: var(--qs-brand-fg);
1010	}
1011	.qs-callout > div
1012	{	flex: 10000 1 0;
1013	}
1014
1015	.qs-selector
1016	{	padding: 0.55em 0.7em;
1017		border: 1px solid var(--qs-line);
1018		border-radius: 0.5em;
1019		background-color: var(--qs-chrome-2);
1020		color: var(--qs-brand-fg);
1021		font-family: var(--qs-mono);
1022		font-size: 92%;
1023		word-break: break-all;
1024	}
1025
1026	.qs-tree
1027	{	margin: 0.5em 0 0;
1028		padding: 0.35em;
1029		border: 1px solid var(--qs-line);
1030		border-radius: 0.5em;
1031		background-color: var(--qs-chrome-2);
1032		max-height: 12em;
1033		overflow: auto;
1034	}
1035	.qs-tree-row
1036	{	display: block;
1037		width: 100%;
1038		padding: 0.2em 0.45em;
1039		border: none;
1040		border-radius: 0.35em;
1041		background: transparent;
1042		color: var(--qs-muted);
1043		font-family: var(--qs-mono);
1044		font-size: 92%;
1045		text-align: left;
1046		white-space: nowrap;
1047		overflow: hidden;
1048		text-overflow: ellipsis;
1049		cursor: pointer;
1050	}
1051	.qs-tree-row:hover
1052	{	background-color: var(--qs-chrome-3);
1053		color: var(--qs-fg);
1054	}
1055	.qs-tree-row.qs-on
1056	{	background-color: var(--qs-brand-soft);
1057		color: var(--qs-brand-fg);
1058		font-weight: 700;
1059	}
1060
1061	/*	A "name = value" row. The two are the same length and the same monospace on their own, so
1062		without a weight and a colour between them the eye has to parse the '=' to tell which half it
1063		is reading. The name is what the row is chosen by, so it gets the emphasis; the value is
1064		evidence, so it recedes.
1065		Each half ellipsises separately: the row used to clip as one string, and a long cookie name
1066		would then push the value off the end entirely - the half that says whether it is the right
1067		cookie. */
1068	.qs-tree-row.qs-kv
1069	{	display: flex;
1070		gap: 0.35em;
1071		align-items: baseline;
1072	}
1073	.qs-kv-k
1074	{	flex: 0 1 auto;
1075		min-width: 3em;
1076		max-width: 60%;
1077		overflow: hidden;
1078		color: var(--qs-fg);
1079		font-weight: 700;
1080		text-overflow: ellipsis;
1081	}
1082	.qs-kv-sep
1083	{	flex: 0 0 auto;
1084		color: var(--qs-muted-2);
1085	}
1086	.qs-kv-v
1087	{	flex: 1 1 auto;
1088		min-width: 0;
1089		overflow: hidden;
1090		color: var(--qs-muted);
1091		font-weight: 400;
1092		text-overflow: ellipsis;
1093	}
1094	.qs-kv-v.qs-empty
1095	{	opacity: 0.6;
1096		font-style: italic;
1097	}
1098	/*	Selected: the row already carries the brand colour, so the two halves separate by weight
1099		alone rather than fighting it with a second colour. */
1100	.qs-tree-row.qs-on .qs-kv-k,
1101	.qs-tree-row.qs-on .qs-kv-v,
1102	.qs-tree-row.qs-on .qs-kv-sep
1103	{	color: inherit;
1104	}
1105	.qs-tree-row.qs-on .qs-kv-v
1106	{	opacity: 0.75;
1107	}
1108	.qs-tree-row:hover .qs-kv-v
1109	{	color: var(--qs-fg);
1110	}
1111
1112	/* ===== "Describe what to grab" AI card =====
1113		The mockup's own treatment: the one purple surface in a green panel, so the box that writes
1114		the form for you doesn't read as another of the form's own sections. */
1115	.qs-ai
1116	{	margin-bottom: 1.2em;
1117		padding: 0.15em 0.75em 0.55em;
1118		border: 1px solid rgba(167, 139, 250, 0.28);
1119		border-radius: 0.7em;
1120		background-image: linear-gradient(180deg, rgba(167, 139, 250, 0.09), rgba(167, 139, 250, 0));
1121	}
1122	.qs-ai + .qs-sec
1123	{	margin-top: 0;
1124		padding-top: 0;
1125		border-top: none;
1126	}
1127	/*	A framed section after the AI card keeps its own border, so it only needs the gap. */
1128	.qs-ai + .qs-fold
1129	{	margin-top: 0.7em;
1130	}
1131	.qs-ai-head
1132	{	display: flex;
1133		gap: 0.5em;
1134		align-items: center;
1135		width: 100%;
1136		padding: 0.6em 0;
1137		border: none;
1138		background: transparent;
1139		color: inherit;
1140		font: inherit;
1141		text-align: left;
1142		cursor: pointer;
1143	}
1144	.qs-ai-head h3
1145	{	flex: 10000 1 0;
1146		margin: 0;
1147		font-size: 100%;
1148		font-weight: 600;
1149	}
1150	.qs-ai-ico
1151	{	display: grid;
1152		flex: 0 0 auto;
1153		place-items: center;
1154		width: 1.7em;
1155		height: 1.7em;
1156		border-radius: 0.4em;
1157		background-color: rgba(167, 139, 250, 0.16);
1158		color: #C4B5FD;
1159	}
1160	.qs-ai-ico svg
1161	{	width: 0.95em;
1162		height: 0.95em;
1163	}
1164	.qs-ai-tag
1165	{	flex: 0 0 auto;
1166		color: #C4B5FD;
1167		font-size: 80%;
1168		font-weight: 700;
1169		letter-spacing: 0.06em;
1170	}
1171	.qs-ai-chev
1172	{	display: flex;
1173		flex: 0 0 auto;
1174		color: var(--qs-muted-2);
1175		transition: transform 0.15s;
1176	}
1177	.qs-ai-chev.qs-on
1178	{	transform: rotate(180deg);
1179	}
1180
1181	.qs-ai-input
1182	{	display: block;
1183		width: 100%;
1184		padding: 0.6em 0.7em;
1185		border: 1px solid var(--qs-line);
1186		border-radius: 0.5em;
1187		background-color: var(--qs-chrome-2);
1188		color: var(--qs-fg);
1189		font: inherit;
1190		line-height: 1.5;
1191		resize: vertical;
1192	}
1193	.qs-ai-input:focus
1194	{	border-color: #A78BFA;
1195		outline: none;
1196	}
1197	.qs-ai-chips
1198	{	display: flex;
1199		flex-wrap: wrap;
1200		gap: 0.35em;
1201		margin-top: 0.55em;
1202	}
1203	.qs-ai-chip
1204	{	padding: 0.3em 0.7em;
1205		border: 1px solid var(--qs-line-2);
1206		border-radius: 999px;
1207		background-color: var(--qs-chrome-2);
1208		color: var(--qs-muted);
1209		font: inherit;
1210		font-size: 88%;
1211		cursor: pointer;
1212	}
1213	.qs-ai-chip:hover:not(:disabled)
1214	{	border-color: #A78BFA;
1215		color: var(--qs-fg);
1216	}
1217	.qs-ai-chip:disabled
1218	{	opacity: 0.55;
1219		cursor: default;
1220	}
1221	.qs-ai-btn
1222	{	justify-content: center;
1223		width: 100%;
1224		margin-top: 0.6em;
1225		border-color: rgba(167, 139, 250, 0.45);
1226		background-color: rgba(167, 139, 250, 0.18);
1227		color: #E4CCFF;
1228	}
1229	.qs-ai-btn:hover:not(:disabled)
1230	{	background-color: rgba(167, 139, 250, 0.3);
1231		color: #FFF;
1232	}
1233	.qs-ai-status
1234	{	margin-top: 0.5em;
1235		color: var(--qs-muted-2);
1236		font-family: var(--qs-mono);
1237		font-size: 88%;
1238		word-break: break-all;
1239	}
1240	.qs-ai-warn
1241	{	border-color: rgba(239, 68, 68, 0.35);
1242		border-style: solid;
1243		background-color: var(--qs-danger-soft);
1244		color: var(--qs-danger-fg);
1245	}
1246
1247	.qs-ai-result
1248	{	margin-top: 0.8em;
1249		padding: 0.75em;
1250		border: 1px solid rgba(167, 139, 250, 0.3);
1251		border-radius: 0.7em;
1252		background-color: rgba(167, 139, 250, 0.07);
1253	}
1254	.qs-ai-result-head
1255	{	display: flex;
1256		gap: 0.45em;
1257		align-items: center;
1258		margin-bottom: 0.6em;
1259		color: #C4B5FD;
1260		font-size: 80%;
1261		font-weight: 700;
1262		letter-spacing: 0.06em;
1263		text-transform: uppercase;
1264	}
1265	.qs-ai-field + .qs-ai-field
1266	{	margin-top: 0.5em;
1267	}
1268	.qs-ai-k
1269	{	margin-bottom: 0.1em;
1270		color: var(--qs-muted-2);
1271		font-size: 78%;
1272		font-weight: 700;
1273		letter-spacing: 0.04em;
1274		text-transform: uppercase;
1275	}
1276	.qs-ai-v
1277	{	font-weight: 600;
1278		overflow-wrap: break-word;
1279	}
1280	.qs-ai-v.qs-ai-mono
1281	{	color: #C4B5FD;
1282		font-family: var(--qs-mono);
1283		font-size: 92%;
1284		font-weight: 400;
1285		word-break: break-all;
1286	}
1287
1288	/* ===== collapsed handle ===== */
1289	.qs-handle
1290	{	position: fixed;
1291		top: 40vh;
1292		right: 0;
1293		z-index: 2147483647;
1294		display: flex;
1295		align-items: center;
1296		gap: 0.4em;
1297		padding: 0.6em 0.7em;
1298		border: none;
1299		border-radius: 0.7em 0 0 0.7em;
1300		background-color: #12182A;
1301		color: #E8EDF7;
1302		font: normal normal 700 13px/1.45 -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
1303		cursor: pointer;
1304		box-shadow: 0 0 1em rgba(0, 0, 0, 0.45);
1305	}
1306	.qs-handle.qs-left
1307	{	right: auto;
1308		left: 0;
1309		border-radius: 0 0.7em 0.7em 0;
1310	}
1311
1312	/* ===== spinner ===== */
1313	.qs-spin
1314	{	display: inline-block;
1315		width: 1em;
1316		height: 1em;
1317		border: 2px solid rgba(255, 255, 255, 0.25);
1318		border-top-color: #12B886;
1319		border-radius: 50%;
1320		animation: qs-spin 0.8s linear infinite;
1321	}
1322	@keyframes qs-spin
1323	{	to
1324		{	transform: rotate(360deg);
1325		}
1326	}
1327`;
1328var ic = {
1329  target: /* @__PURE__ */ u2("svg", {
1330    viewBox: "0 0 24 24",
1331    fill: "none",
1332    stroke: "currentColor",
1333    "stroke-width": "2",
1334    children: [
1335      /* @__PURE__ */ u2("circle", {
1336        cx: "12",
1337        cy: "12",
1338        r: "9"
1339      }),
1340      /* @__PURE__ */ u2("circle", {
1341        cx: "12",
1342        cy: "12",
1343        r: "4"
1344      }),
1345      /* @__PURE__ */ u2("path", {
1346        d: "M12 1v3M12 20v3M1 12h3M20 12h3"
1347      })
1348    ]
1349  }),
1350  layout: /* @__PURE__ */ u2("svg", {
1351    viewBox: "0 0 24 24",
1352    fill: "none",
1353    stroke: "currentColor",
1354    "stroke-width": "2",
1355    children: [
1356      /* @__PURE__ */ u2("rect", {
1357        x: "3",
1358        y: "3",
1359        width: "18",
1360        height: "18",
1361        rx: "2"
1362      }),
1363      /* @__PURE__ */ u2("path", {
1364        d: "M3 9h18M9 21V9"
1365      })
1366    ]
1367  }),
1368  eye: /* @__PURE__ */ u2("svg", {
1369    viewBox: "0 0 24 24",
1370    fill: "none",
1371    stroke: "currentColor",
1372    "stroke-width": "2",
1373    children: [
1374      /* @__PURE__ */ u2("path", {
1375        d: "M1 12s4-7 11-7 11 7 11 7-4 7-11 7S1 12 1 12z"
1376      }),
1377      /* @__PURE__ */ u2("circle", {
1378        cx: "12",
1379        cy: "12",
1380        r: "3"
1381      })
1382    ]
1383  }),
1384  warn: /* @__PURE__ */ u2("svg", {
1385    viewBox: "0 0 24 24",
1386    fill: "none",
1387    stroke: "currentColor",
1388    "stroke-width": "2",
1389    children: [
1390      /* @__PURE__ */ u2("path", {
1391        d: "M12 3l9 16H3z"
1392      }),
1393      /* @__PURE__ */ u2("path", {
1394        d: "M12 9v5M12 17h.01"
1395      })
1396    ]
1397  }),
1398  check: /* @__PURE__ */ u2("svg", {
1399    viewBox: "0 0 24 24",
1400    fill: "none",
1401    stroke: "currentColor",
1402    "stroke-width": "2",
1403    children: /* @__PURE__ */ u2("path", {
1404      d: "M20 6L9 17l-5-5"
1405    })
1406  }),
1407  cross: /* @__PURE__ */ u2("svg", {
1408    viewBox: "0 0 24 24",
1409    fill: "none",
1410    stroke: "currentColor",
1411    "stroke-width": "2",
1412    children: /* @__PURE__ */ u2("path", {
1413      d: "M18 6L6 18M6 6l12 12"
1414    })
1415  }),
1416  minus: /* @__PURE__ */ u2("svg", {
1417    viewBox: "0 0 24 24",
1418    fill: "none",
1419    stroke: "currentColor",
1420    "stroke-width": "2",
1421    children: /* @__PURE__ */ u2("path", {
1422      d: "M5 12h14"
1423    })
1424  }),
1425  swap: /* @__PURE__ */ u2("svg", {
1426    viewBox: "0 0 24 24",
1427    fill: "none",
1428    stroke: "currentColor",
1429    "stroke-width": "2",
1430    children: /* @__PURE__ */ u2("path", {
1431      d: "M7 8h13l-3-3M17 16H4l3 3"
1432    })
1433  }),
1434  sparkle: /* @__PURE__ */ u2("svg", {
1435    viewBox: "0 0 24 24",
1436    fill: "none",
1437    stroke: "currentColor",
1438    "stroke-width": "2",
1439    "stroke-linejoin": "round",
1440    children: /* @__PURE__ */ u2("path", {
1441      d: "M12 3l1.9 5.1L19 10l-5.1 1.9L12 17l-1.9-5.1L5 10l5.1-1.9z"
1442    })
1443  }),
1444  chevronDown: /* @__PURE__ */ u2("svg", {
1445    viewBox: "0 0 24 24",
1446    fill: "none",
1447    stroke: "currentColor",
1448    "stroke-width": "2",
1449    "stroke-linecap": "round",
1450    "stroke-linejoin": "round",
1451    children: /* @__PURE__ */ u2("path", {
1452      d: "M6 9l6 6 6-6"
1453    })
1454  })
1455};
1456function PanelSection(props) {
1457  return /* @__PURE__ */ u2("div", {
1458    class: "qs-fold" + (props.isOpen ? "" : " qs-closed"),
1459    children: [
1460      /* @__PURE__ */ u2("button", {
1461        type: "button",
1462        class: "qs-fold-head",
1463        onClick: props.onToggle,
1464        children: [
1465          /* @__PURE__ */ u2("span", {
1466            class: "qs-fold-ico",
1467            children: props.icon
1468          }),
1469          /* @__PURE__ */ u2("span", {
1470            class: "qs-fold-name",
1471            children: props.title
1472          }),
1473          props.meta != null && props.meta !== "" && /* @__PURE__ */ u2("span", {
1474            class: "qs-fold-meta",
1475            children: props.meta
1476          }),
1477          /* @__PURE__ */ u2("span", {
1478            class: "qs-fold-chev",
1479            children: ic.chevronDown
1480          })
1481        ]
1482      }),
1483      props.isOpen && /* @__PURE__ */ u2("div", {
1484        class: "qs-fold-body",
1485        children: props.children
1486      })
1487    ]
1488  });
1489}
1490function SimulatorPanel(props) {
1491  const [isLeft, setIsLeft] = p2(false);
1492  const [isMinimized, setIsMinimized] = p2(false);
1493  const sideClass = isLeft ? " qs-left" : "";
1494  if (isMinimized) {
1495    return /* @__PURE__ */ u2("button", {
1496      type: "button",
1497      class: "qs-handle" + sideClass,
1498      title: "Reopen the Personyze picker",
1499      onClick: () => setIsMinimized(false),
1500      children: [
1501        ic.target,
1502        "Personyze"
1503      ]
1504    });
1505  }
1506  return /* @__PURE__ */ u2("div", {
1507    class: "qs-panel" + sideClass + (props.panelClass ? " " + props.panelClass : ""),
1508    children: [
1509      /* @__PURE__ */ u2("div", {
1510        class: "qs-head",
1511        children: [
1512          props.logoSrc && /* @__PURE__ */ u2("img", {
1513            class: "qs-logo",
1514            src: props.logoSrc,
1515            alt: ""
1516          }),
1517          /* @__PURE__ */ u2("div", {
1518            class: "qs-title",
1519            children: [
1520              /* @__PURE__ */ u2("div", {
1521                class: "qs-title-main",
1522                children: props.title
1523              }),
1524              /* @__PURE__ */ u2("div", {
1525                class: "qs-title-sub",
1526                children: props.subtitle
1527              })
1528            ]
1529          }),
1530          /* @__PURE__ */ u2("button", {
1531            type: "button",
1532            class: "qs-icon",
1533            title: "Move the window to the other side",
1534            onClick: () => setIsLeft(!isLeft),
1535            children: ic.swap
1536          }),
1537          /* @__PURE__ */ u2("button", {
1538            type: "button",
1539            class: "qs-icon",
1540            title: "Collapse the window",
1541            onClick: () => setIsMinimized(true),
1542            children: ic.minus
1543          }),
1544          /* @__PURE__ */ u2("button", {
1545            type: "button",
1546            class: "qs-icon",
1547            title: "Close the picker",
1548            onClick: props.onClose,
1549            children: ic.cross
1550          })
1551        ]
1552      }),
1553      props.error && /* @__PURE__ */ u2("div", {
1554        class: "qs-err",
1555        children: [
1556          ic.warn,
1557          /* @__PURE__ */ u2("div", {
1558            children: props.error
1559          }),
1560          props.onDismissError && /* @__PURE__ */ u2("button", {
1561            type: "button",
1562            class: "qs-icon",
1563            title: "Dismiss",
1564            onClick: props.onDismissError,
1565            children: ic.cross
1566          })
1567        ]
1568      }),
1569      /* @__PURE__ */ u2("div", {
1570        class: "qs-body",
1571        children: props.children
1572      }),
1573      props.footer && /* @__PURE__ */ u2("div", {
1574        class: "qs-foot",
1575        children: props.footer
1576      })
1577    ]
1578  });
1579}
1580
1581// src/modules/picker/private/selector.ts
1582var RE_VOLATILE_TAIL = /[_\-.][0-9A-F]{4,}$/i;
1583var RE_CSS_IN_JS = /^(?:css|sc|jsx|emotion|svelte|ng)-[0-9a-z]{4,}$/i;
1584var RE_OWN_CLASS = /^(?:\$|_st|personyze|qs-)/i;
1585function isStableName(name) {
1586  return !!name && !RE_VOLATILE_TAIL.test(name) && !RE_CSS_IN_JS.test(name) && !RE_OWN_CLASS.test(name);
1587}
1588function cssEscape(name) {
1589  return typeof CSS != "undefined" && CSS.escape ? CSS.escape(name) : name.replace(/[^\w-]/g, (ch) => "\\" + ch);
1590}
1591function matchesOnly(selector, elem) {
1592  if (!selector) {
1593    return false;
1594  }
1595  try {
1596    const found = elem.ownerDocument.querySelectorAll(selector);
1597    return found.length == 1 && found[0] == elem;
1598  } catch {
1599    return false;
1600  }
1601}
1602function indexOfType(elem) {
1603  let index = 1;
1604  for (const sib of elem.parentElement?.children ?? []) {
1605    if (sib == elem) {
1606      break;
1607    }
1608    if (sib.localName == elem.localName) {
1609      index++;
1610    }
1611  }
1612  return index;
1613}
1614function groupStep(localName, classNames) {
1615  let step = localName;
1616  for (const name of classNames) {
1617    if (isStableName(name)) {
1618      step += "." + cssEscape(name);
1619    }
1620  }
1621  return step;
1622}
1623function elemToStep(elem) {
1624  const step = groupStep(elem.localName, elem.classList);
1625  let nMatching = 0;
1626  for (const sib of elem.parentElement?.children ?? []) {
1627    try {
1628      if (sib.matches(step)) {
1629        nMatching++;
1630      }
1631    } catch {
1632      nMatching = 2;
1633      break;
1634    }
1635  }
1636  return nMatching > 1 ? `${step}:nth-of-type(${indexOfType(elem)})` : step;
1637}
1638function structuralPath(elem) {
1639  const doc = elem.ownerDocument;
1640  const steps = new Array();
1641  for (let node = elem; node && node != doc.documentElement; node = node.parentElement) {
1642    if (node == doc.body) {
1643      steps.unshift("body");
1644      break;
1645    }
1646    steps.unshift(`${node.localName}:nth-of-type(${indexOfType(node)})`);
1647  }
1648  return steps.join(" > ");
1649}
1650function elemToSelector(elem) {
1651  const doc = elem.ownerDocument;
1652  if (!doc || !doc.body || !doc.body.contains(elem)) {
1653    return "";
1654  }
1655  const steps = new Array();
1656  for (let node = elem; node && node != doc.body && node != doc.documentElement; node = node.parentElement) {
1657    const id = node.getAttribute("id") ?? "";
1658    if (isStableName(id) && doc.querySelectorAll("#" + cssEscape(id)).length == 1) {
1659      steps.unshift("#" + cssEscape(id));
1660      break;
1661    }
1662    steps.unshift(elemToStep(node));
1663    const selector2 = steps.join(" > ");
1664    if (matchesOnly(selector2, elem)) {
1665      return selector2;
1666    }
1667  }
1668  const selector = steps.join(" > ");
1669  return matchesOnly(selector, elem) ? selector : structuralPath(elem);
1670}
1671function findMatches(selector, doc = document) {
1672  if (!selector) {
1673    return [];
1674  }
1675  try {
1676    return Array.from(doc.querySelectorAll(selector));
1677  } catch {
1678    return [];
1679  }
1680}
1681function describeElem(elem) {
1682  let text = elem.localName;
1683  if (elem.id) {
1684    text += "#" + elem.id;
1685  }
1686  for (const name of elem.classList) {
1687    text += "." + name;
1688  }
1689  return text;
1690}
1691function ancestorChain(elem) {
1692  const doc = elem.ownerDocument;
1693  const chain = new Array();
1694  for (let node = elem; node && node != doc.body && node != doc.documentElement; node = node.parentElement) {
1695    chain.unshift(node);
1696  }
1697  return chain;
1698}
1699
1700// src/modules/picker/private/picker.ts
1701var Z_INDEX = 2147483646;
1702var Picker = class {
1703  #layer;
1704  #highlights = new Array();
1705  #select;
1706  #hovered;
1707  #isTracking = false;
1708  #timer = 0;
1709  /**	Outline these elements until the next call. `label` writes the element's name into the
1710  corner of the box, which is what makes a hover read as "this is what you'd get".
1711  **/
1712  highlight(elems, color = "#12B886", label = false) {
1713    this.#highlights = [];
1714    for (const elem of elems) {
1715      if (elem && elem.isConnected) {
1716        this.#highlights.push({
1717          elem,
1718          color,
1719          label
1720        });
1721      }
1722    }
1723    this.#draw();
1724    this.#trackViewport(this.#highlights.length > 0);
1725  }
1726  /**	Enter picking mode: highlight what's under the cursor, and swallow the next click.
1727  **/
1728  selectBegin(options) {
1729    this.selectEnd();
1730    this.#select = options;
1731    this.#hovered = void 0;
1732    for (const type of [
1733      "mousemove",
1734      "mouseover",
1735      "click",
1736      "mousedown",
1737      "mouseup",
1738      "keydown"
1739    ]) {
1740      document.addEventListener(type, this.#onEvent, true);
1741    }
1742  }
1743  selectEnd() {
1744    if (this.#select) {
1745      this.#select = void 0;
1746      this.#hovered = void 0;
1747      for (const type of [
1748        "mousemove",
1749        "mouseover",
1750        "click",
1751        "mousedown",
1752        "mouseup",
1753        "keydown"
1754      ]) {
1755        document.removeEventListener(type, this.#onEvent, true);
1756      }
1757      this.highlight([]);
1758    }
1759  }
1760  isSelecting() {
1761    return !!this.#select;
1762  }
1763  destroy() {
1764    this.selectEnd();
1765    this.highlight([]);
1766    this.#layer?.remove();
1767    this.#layer = void 0;
1768  }
1769  /**	Single capture-phase handler for the whole picking session. Capture phase and
1770  `stopPropagation()` are what keep the page from reacting: the click never reaches the
1771  page's own listeners, and `preventDefault()` keeps links and submit buttons inert.
1772  **/
1773  #onEvent = (event) => {
1774    const select = this.#select;
1775    if (!select) {
1776      return;
1777    }
1778    if (event.type == "keydown") {
1779      if (event.key == "Escape") {
1780        event.preventDefault();
1781        event.stopPropagation();
1782        select.onSelect(null);
1783      }
1784      return;
1785    }
1786    const target = this.#targetOf(event, select.ignore);
1787    if (!target) {
1788      if (this.#hovered) {
1789        this.#hovered = void 0;
1790        this.highlight([]);
1791        select.onHover?.(null);
1792      }
1793      return;
1794    }
1795    event.preventDefault();
1796    event.stopPropagation();
1797    if (event.type == "click") {
1798      select.onSelect(target);
1799    } else if (event.type == "mousemove" || event.type == "mouseover") {
1800      if (this.#hovered != target) {
1801        this.#hovered = target;
1802        this.highlight([
1803          target
1804        ], "#12B886", true);
1805        select.onHover?.(target);
1806      }
1807    }
1808  };
1809  /**	The element the event points at, or null when it's the tool's own UI. `composedPath()` is
1810  what sees through the panel's shadow root, whose events retarget to the host element.
1811  **/
1812  #targetOf(event, ignore) {
1813    const path = typeof event.composedPath == "function" ? event.composedPath() : [];
1814    const target = path[0] ?? event.target;
1815    if (!(target instanceof Element)) {
1816      return null;
1817    }
1818    for (const root of ignore) {
1819      if (root == target || root.contains(target) || path.indexOf(root) != -1) {
1820        return null;
1821      }
1822    }
1823    return target;
1824  }
1825  #draw = () => {
1826    const layer = this.#ensureLayer();
1827    while (layer.childNodes.length > this.#highlights.length) {
1828      layer.lastChild.remove();
1829    }
1830    while (layer.childNodes.length < this.#highlights.length) {
1831      const box = document.createElement("div");
1832      box.appendChild(document.createElement("span"));
1833      layer.appendChild(box);
1834    }
1835    for (let i4 = 0; i4 < this.#highlights.length; i4++) {
1836      const { elem, color, label } = this.#highlights[i4];
1837      const box = layer.childNodes[i4];
1838      const rect = elem.getBoundingClientRect();
1839      box.style.cssText = `position:absolute; box-sizing:border-box; pointer-events:none; border:2px solid ${color}; background-color:${color}22; border-radius:2px; left:${rect.left + globalThis.scrollX}px; top:${rect.top + globalThis.scrollY}px; width:${Math.max(rect.width, 4)}px; height:${Math.max(rect.height, 4)}px`;
1840      const tag = box.firstChild;
1841      tag.textContent = !label ? "" : describeElem(elem).slice(0, 80);
1842      tag.style.cssText = !label ? "display:none" : `position:absolute; left:0; top:-1.5em; max-width:100%; overflow:hidden; white-space:nowrap; box-sizing:border-box; padding:0 0.4em; border-radius:2px; background-color:${color}; color:#08231C; font:600 11px/1.5em ui-monospace, Menlo, Consolas, monospace`;
1843    }
1844  };
1845  #ensureLayer() {
1846    let layer = this.#layer;
1847    if (!layer?.isConnected) {
1848      layer = document.createElement("div");
1849      layer.style.cssText = `position:absolute; left:0; top:0; width:0; height:0; margin:0; padding:0; border:none; pointer-events:none; z-index:${Z_INDEX}`;
1850      document.body.appendChild(layer);
1851      this.#layer = layer;
1852    }
1853    return layer;
1854  }
1855  /**	Highlight boxes are placed in page coordinates, so they only need redrawing when the page
1856  moves under them - but an element can also be resized by the page itself, hence the poll.
1857  **/
1858  #trackViewport(on) {
1859    if (on != this.#isTracking) {
1860      this.#isTracking = on;
1861      if (on) {
1862        globalThis.addEventListener("scroll", this.#draw, true);
1863        globalThis.addEventListener("resize", this.#draw);
1864        this.#timer = setInterval(this.#draw, 500);
1865      } else {
1866        globalThis.removeEventListener("scroll", this.#draw, true);
1867        globalThis.removeEventListener("resize", this.#draw);
1868        clearInterval(this.#timer);
1869      }
1870    }
1871  }
1872};
1873
1874// src/modules/tracker/private/tracker.ts
1875function getPageUrl() {
1876  try {
1877    return getTracker()?.get_location?.()?.href || location.href;
1878  } catch {
1879    return location.href;
1880  }
1881}
1882var GRAB_MAX_CHARS = 150;
1883function grabValue(elem) {
1884  const value = elem.value;
1885  const text = typeof value == "string" ? value : elem.textContent ?? "";
1886  return text.trim().replace(/\s+/g, " ").substring(0, GRAB_MAX_CHARS).trim();
1887}
1888function getTracker() {
1889  return globalThis._S_T;
1890}
1891function getPanelWindow() {
1892  const scope = globalThis;
1893  const thisWindow = globalThis;
1894  return scope._S_T_OPENER ?? globalThis.opener ?? (parent != thisWindow ? parent : null);
1895}
1896function resolveHtmlId(htmlId) {
1897  const tracker = getTracker();
1898  if (tracker?.id) {
1899    try {
1900      const found = tracker.id(htmlId);
1901      if (found instanceof Element) {
1902        return found;
1903      }
1904    } catch (e3) {
1905      console.error(e3);
1906    }
1907  }
1908  try {
1909    return document.querySelector(htmlId);
1910  } catch {
1911    return null;
1912  }
1913}
1914
1915// src/modules/toolbridge/private/toolbridge.ts
1916var ACK_TIMEOUT = 4e4;
1917var RESEND_EACH = 1e3;
1918var GET_VALUE_TRIES = 60;
1919var MESSAGE_TYPE_GET_VALUE = "(GET_VALUE)";
1920var MESSAGE_TYPE_VALUE = "(VALUE)";
1921var MESSAGE_TYPE_SLAVE = "slave";
1922var ToolBridge = class {
1923  #options;
1924  #pending = new Array();
1925  #timer = 0;
1926  #isStopped = false;
1927  #lastValue = null;
1928  constructor(options) {
1929    this.#options = options;
1930  }
1931  /**	Start listening, then ask the panel for the value being edited. Resolves true once the panel
1932  has answered, false if it never did.
1933  **/
1934  async start() {
1935    globalThis.addEventListener("message", this.#onMessage);
1936    for (let i4 = 0; i4 < GET_VALUE_TRIES; i4++) {
1937      if (this.#isStopped || await this.#send({
1938        get_value: true
1939      }, MESSAGE_TYPE_GET_VALUE)) {
1940        return !this.#isStopped;
1941      }
1942    }
1943    return false;
1944  }
1945  /**	Hand the result back to the panel. Resolves true once the panel acknowledges it - the caller
1946  must not close the window before that, or the result is lost.
1947  **/
1948  setValue(value) {
1949    this.#lastValue = value;
1950    return this.#send({
1951      value
1952    }, MESSAGE_TYPE_VALUE);
1953  }
1954  /**	Push an incremental update to the panel - for the WYSIWYG editor, `{page_is_loaded, href,
1955  		n_changes, html_changes}`. Resolves true once the panel acknowledges it.
1956  
1957  		Only the latest one matters, so an unanswered previous update is superseded rather than
1958  		queued: a burst of keystrokes must not turn into a backlog of resends.
1959  	 **/
1960  reportMessage(messageData) {
1961    return this.#send({
1962      message_data: messageData
1963    }, MESSAGE_TYPE_SLAVE);
1964  }
1965  destroy() {
1966    this.#isStopped = true;
1967    globalThis.removeEventListener("message", this.#onMessage);
1968    clearInterval(this.#timer);
1969    this.#timer = 0;
1970    for (const pending of this.#pending.splice(0)) {
1971      pending.resolve(false);
1972    }
1973  }
1974  #send(message, messageType) {
1975    message.buffer_key = this.#options.bufferKey;
1976    message.message_type = messageType;
1977    for (let i4 = this.#pending.length - 1; i4 >= 0; i4--) {
1978      if (this.#pending[i4].message.message_type == messageType) {
1979        this.#pending.splice(i4, 1)[0].resolve(false);
1980      }
1981    }
1982    this.#post(message);
1983    return new Promise((resolve) => {
1984      const now = Date.now();
1985      this.#pending.push({
1986        message,
1987        resolve,
1988        startTime: now,
1989        lastTime: now
1990      });
1991      this.#startStopResend();
1992    });
1993  }
1994  /**	Reply that needs no acknowledgement of its own: it IS the acknowledgement of `messageType`.
1995  **/
1996  #postAck(messageType, extra) {
1997    this.#post({
1998      ...extra,
1999      buffer_key: this.#options.bufferKey,
2000      message_type: messageType
2001    });
2002  }
2003  #post(message) {
2004    getPanelWindow()?.postMessage(message, this.#options.guiOrigin);
2005  }
2006  #onMessage = (event) => {
2007    const { guiOrigin, bufferKey, onValue, onMessageData } = this.#options;
2008    if (guiOrigin != "*" && event.origin != guiOrigin) {
2009      return;
2010    }
2011    const message = event.data;
2012    if (!message || typeof message != "object") {
2013      return;
2014    }
2015    const messageType = typeof message.message_type == "string" ? message.message_type : "";
2016    if (!messageType || message.buffer_key != bufferKey) {
2017      return;
2018    }
2019    if ("value" in message) {
2020      const value = message.value;
2021      if (value && typeof value == "object") {
2022        onValue(value);
2023      }
2024    } else if (message.message_data && typeof message.message_data == "object") {
2025      onMessageData?.(message.message_data);
2026    }
2027    const i4 = this.#pending.findIndex((v3) => v3.message.message_type == messageType);
2028    if (i4 != -1) {
2029      this.#pending.splice(i4, 1)[0].resolve(true);
2030      this.#startStopResend();
2031    } else if (message.get_value === true) {
2032      this.#postAck(messageType, {
2033        value: this.#lastValue
2034      });
2035    } else if ("value" in message || message.message_data) {
2036      this.#postAck(messageType);
2037    }
2038  };
2039  #startStopResend() {
2040    if (this.#pending.length == 0) {
2041      clearInterval(this.#timer);
2042      this.#timer = 0;
2043    } else if (this.#timer == 0) {
2044      this.#timer = setInterval(() => {
2045        const now = Date.now();
2046        for (let i4 = this.#pending.length - 1; i4 >= 0; i4--) {
2047          const pending = this.#pending[i4];
2048          if (now - pending.startTime > ACK_TIMEOUT) {
2049            this.#pending.splice(i4, 1);
2050            pending.resolve(false);
2051          } else if (now - pending.lastTime > RESEND_EACH) {
2052            pending.lastTime = now;
2053            this.#post(pending.message);
2054          }
2055        }
2056        this.#startStopResend();
2057      }, RESEND_EACH);
2058    }
2059  }
2060};
2061
2062// src/modules/jsapi/private/jsapi.ts
2063var N_ATTEMPTS = 3;
2064var CACHE_MAX_QUERIES = 32;
2065var MAX_URLENCODED_DATA = 7 * 1024;
2066var config = null;
2067var cache = /* @__PURE__ */ new Map();
2068function configureJsapi(newConfig) {
2069  config = newConfig;
2070  cache.clear();
2071}
2072function isJsapiConfigured() {
2073  return config != null;
2074}
2075async function query(sql, params, noCache = false) {
2076  if (!config) {
2077    throw new Error("The Simulator has no database connection.");
2078  }
2079  const postQuery = {
2080    sql,
2081    params
2082  };
2083  const post = JSON.stringify(postQuery);
2084  if (!noCache) {
2085    const hit = cache.get(post);
2086    if (hit) {
2087      return hit;
2088    }
2089  }
2090  const isBig = post.length > MAX_URLENCODED_DATA;
2091  const response = await fetchRetrying(config.url, {
2092    mode: "cors",
2093    credentials: "include",
2094    headers: {
2095      "Content-Type": isBig ? "application/json" : "application/x-www-form-urlencoded"
2096    },
2097    method: "POST",
2098    body: isBig ? JSON.stringify({
2099      data: [
2100        postQuery
2101      ],
2102      server_id: config.serverId
2103    }) : `data=${encodeURIComponent("[" + post + "]")}&server_id=${config.serverId}`
2104  });
2105  if (!response.ok) {
2106    throw new Error(response.statusText || `Database request failed (${response.status})`);
2107  }
2108  const resultsets = toResultsets(await response.text());
2109  if (!noCache && resultsets.every((v3) => v3.fields)) {
2110    while (cache.size >= CACHE_MAX_QUERIES) {
2111      const oldest = cache.keys().next().value;
2112      if (oldest == void 0) {
2113        break;
2114      }
2115      cache.delete(oldest);
2116    }
2117    cache.set(post, resultsets);
2118  }
2119  return resultsets;
2120}
2121async function queryRow(sql, params, noCache = false) {
2122  const resultsets = await query(sql, params, noCache);
2123  return resultsets[0]?.[0];
2124}
2125async function fetchRetrying(url, init) {
2126  let lastError;
2127  for (let i4 = 0; i4 < N_ATTEMPTS; i4++) {
2128    try {
2129      return await fetch(url, init);
2130    } catch (e3) {
2131      lastError = e3;
2132    }
2133  }
2134  console.error(lastError);
2135  throw new Error("Failed to reach the Personyze server. Please check your network connection.");
2136}
2137function toResultsets(text) {
2138  const pos = text.indexOf("\n\n//");
2139  const data = JSON.parse(pos == -1 ? text : text.slice(0, pos));
2140  const raw = data?.[0];
2141  if (raw?.error) {
2142    throw new Error(raw.error + "");
2143  }
2144  if (!Array.isArray(raw)) {
2145    throw new Error("Unexpected answer from the Personyze server.");
2146  }
2147  const resultsets = new Array();
2148  for (const rset of raw) {
2149    if (rset?.error) {
2150      throw new Error(rset.error + "");
2151    }
2152    const fields = rset?.fields;
2153    const rows = rset?.rows;
2154    const converted = [];
2155    if (fields && rows) {
2156      for (const row of rows) {
2157        const obj = {};
2158        for (let i4 = 0; i4 < fields.length; i4++) {
2159          obj[fields[i4]] = row[i4];
2160        }
2161        converted.push(obj);
2162      }
2163      converted.fields = fields;
2164    }
2165    resultsets.push(converted);
2166  }
2167  return resultsets;
2168}
2169
2170// src/modules/ailive/private/serialize.ts
2171var OPAQUE = /* @__PURE__ */ new Set([
2172  "script",
2173  "style",
2174  "noscript",
2175  "template",
2176  "svg",
2177  "iframe",
2178  "object",
2179  "embed",
2180  "canvas",
2181  "video",
2182  "audio",
2183  "select"
2184]);
2185var SHOWN_ATTRS = [
2186  [
2187    "href",
2188    60
2189  ],
2190  [
2191    "src",
2192    60
2193  ],
2194  [
2195    "alt",
2196    40
2197  ],
2198  [
2199    "title",
2200    40
2201  ],
2202  [
2203    "type",
2204    20
2205  ],
2206  [
2207    "name",
2208    30
2209  ],
2210  [
2211    "role",
2212    20
2213  ],
2214  [
2215    "aria-label",
2216    40
2217  ],
2218  [
2219    "placeholder",
2220    40
2221  ]
2222];
2223var MAX_CLASSES = 5;
2224var MAX_TEXT_CHARS = 80;
2225var MAX_CHILDREN = 30;
2226var MAX_DEPTH = 30;
2227var XML_ELEMENT_NODE = 1;
2228var XML_TEXT_NODE = 3;
2229function pageSkeleton(ignore, maxChars = 6e4) {
2230  const out = new Array();
2231  let spent = 0;
2232  let truncated = false;
2233  function emit(line) {
2234    if (spent + line.length > maxChars) {
2235      truncated = true;
2236      return false;
2237    }
2238    out.push(line);
2239    spent += line.length + 1;
2240    return true;
2241  }
2242  function walk(elem, depth) {
2243    if (ignore.indexOf(elem) != -1) {
2244      return true;
2245    }
2246    const indent = "	".repeat(depth);
2247    if (depth > MAX_DEPTH) {
2248      return emit(indent + "\u2026");
2249    }
2250    let line = indent + "<" + elem.localName;
2251    if (elem.id) {
2252      line += " #" + elem.id;
2253    }
2254    const classes = Array.from(elem.classList).slice(0, MAX_CLASSES);
2255    if (classes.length) {
2256      line += " ." + classes.join(".");
2257    }
2258    for (const [name, max] of SHOWN_ATTRS) {
2259      const value = elem.getAttribute(name);
2260      if (value) {
2261        line += ` ${name}="${cut(value, max)}"`;
2262      }
2263    }
2264    line += ">";
2265    const isOpaque = OPAQUE.has(elem.localName);
2266    if (!isOpaque) {
2267      let text = "";
2268      for (let node = elem.firstChild; node; node = node.nextSibling) {
2269        if (node.nodeType == XML_TEXT_NODE) {
2270          text += node.data;
2271        }
2272      }
2273      text = text.replace(/\s+/g, " ").trim();
2274      if (text) {
2275        line += ` "${cut(text, MAX_TEXT_CHARS)}"`;
2276      }
2277    }
2278    if (!emit(line)) {
2279      return false;
2280    }
2281    if (isOpaque) {
2282      return true;
2283    }
2284    let nShown = 0;
2285    let nSkipped = 0;
2286    for (let node = elem.firstChild; node; node = node.nextSibling) {
2287      if (node.nodeType != XML_ELEMENT_NODE) {
2288        continue;
2289      }
2290      if (nShown >= MAX_CHILDREN) {
2291        nSkipped++;
2292        continue;
2293      }
2294      if (!walk(node, depth + 1)) {
2295        return false;
2296      }
2297      nShown++;
2298    }
2299    if (nSkipped) {
2300      return emit("	".repeat(depth + 1) + `\u2026 ${nSkipped} more elements`);
2301    }
2302    return true;
2303  }
2304  walk(document.body, 0);
2305  if (truncated) {
2306    out.push("\u2026 (the skeleton was cut here - the page continues)");
2307  }
2308  return out.join("\n");
2309}
2310function cut(text, maxChars) {
2311  return text.length <= maxChars ? text : text.slice(0, maxChars - 1) + "\u2026";
2312}
2313
2314// src/modules/pagedata/private/pagedata.ts
2315function parsePairs(text, separator) {
2316  const pairs = new Array();
2317  for (const pair of text.split(separator)) {
2318    if (!pair) {
2319      continue;
2320    }
2321    const pos = pair.indexOf("=");
2322    const rawKey = pos < 0 ? pair : pair.slice(0, pos);
2323    const rawValue = pos < 0 ? "" : pair.slice(pos + 1);
2324    pairs.push({
2325      key: decodeSafe(rawKey),
2326      value: decodeSafe(rawValue)
2327    });
2328  }
2329  return pairs;
2330}
2331function decodeSafe(text) {
2332  try {
2333    return decodeURIComponent(text);
2334  } catch {
2335    return text;
2336  }
2337}
2338function resolveVarPath(root, path) {
2339  let value = root;
2340  for (const step of varPathSteps(path)) {
2341    if (value == null || typeof value != "object" && typeof value != "function") {
2342      return void 0;
2343    }
2344    value = value[step];
2345  }
2346  return value;
2347}
2348function varPathSteps(path) {
2349  const steps = new Array();
2350  for (const step of path.split(/[.[\]]/)) {
2351    const name = step.trim().replace(/^(["'])(.*)\1$/, "$2");
2352    if (name) {
2353      steps.push(name);
2354    }
2355  }
2356  return steps;
2357}
2358function listCandidates(source, url) {
2359  switch (source) {
2360    case "cookie":
2361      return dedupeByKey(parsePairs(document.cookie, /;\s*/));
2362    case "url":
2363      return dedupeByKey(parsePairs(queryOf(url), /&/));
2364    case "local":
2365      return listStorage(safeStorage(() => localStorage));
2366    case "session":
2367      return listStorage(safeStorage(() => sessionStorage));
2368    case "meta":
2369      return dedupeByKey(listMetas());
2370    default:
2371      return [];
2372  }
2373}
2374function dedupeByKey(candidates) {
2375  const seen = /* @__PURE__ */ new Set();
2376  return candidates.filter((item) => {
2377    if (seen.has(item.key)) {
2378      return false;
2379    }
2380    seen.add(item.key);
2381    return true;
2382  });
2383}
2384function queryOf(url) {
2385  const pos = url.indexOf("?");
2386  if (pos < 0) {
2387    return "";
2388  }
2389  const hash = url.indexOf("#", pos);
2390  return url.slice(pos + 1, hash < 0 ? void 0 : hash);
2391}
2392function safeStorage(get) {
2393  try {
2394    return get();
2395  } catch {
2396    return null;
2397  }
2398}
2399function listStorage(storage) {
2400  const found = new Array();
2401  for (let i4 = 0; storage && i4 < storage.length; i4++) {
2402    const key = storage.key(i4);
2403    if (key != null) {
2404      found.push({
2405        key,
2406        value: storage.getItem(key) ?? ""
2407      });
2408    }
2409  }
2410  return found;
2411}
2412function listMetas() {
2413  const found = new Array();
2414  for (const meta of document.getElementsByTagName("meta")) {
2415    if (meta.httpEquiv) {
2416      continue;
2417    }
2418    const key = meta.getAttribute("name") || meta.getAttribute("property") || "";
2419    const content = meta.content ?? "";
2420    if (key) {
2421      found.push({
2422        key,
2423        value: content
2424      });
2425    } else {
2426      const selector = selectorForMeta(meta);
2427      if (selector) {
2428        found.push({
2429          key: selector,
2430          value: content,
2431          selector
2432        });
2433      }
2434    }
2435  }
2436  return found;
2437}
2438function selectorForMeta(meta) {
2439  for (const { name, value } of meta.attributes) {
2440    if (name != "content" && /^[\w-]+$/.test(name)) {
2441      const selector = `meta[${name}=${JSON.stringify(value)}]`;
2442      const all = document.querySelectorAll(selector);
2443      if (all.length == 1 && all[0] == meta) {
2444        return selector;
2445      }
2446    }
2447  }
2448  return "";
2449}
2450function readValue(source, key, url) {
2451  if (!key) {
2452    return "";
2453  }
2454  if (source == "variable") {
2455    const value = resolveVarPath(globalThis, key);
2456    return value == null || typeof value == "object" && !(value instanceof Date) ? "" : String(value);
2457  }
2458  const found = listCandidates(source, url).find((v3) => v3.key == key);
2459  return found?.value ?? "";
2460}
2461
2462// src/modules/aigrab/private/aiGrab.ts
2463var MAX_NAME_CHARS = 50;
2464var MASK_LABELS = {
2465  none: "Pass everything",
2466  number: "Number only",
2467  nonnumber: "Nonnumbers only",
2468  email: "Email address"
2469};
2470function maskLabel(mask) {
2471  return MASK_LABELS[mask] ?? MASK_LABELS.none;
2472}
2473var MAX_ROUNDS = 8;
2474var SKELETON_MAX_CHARS = 3e4;
2475var SOURCES_MAX_CHARS = 24e3;
2476var SOURCE_VALUE_MAX_CHARS = 200;
2477var MAX_LISTED_MATCHES = 10;
2478var QUERY_VALUE_MAX_CHARS = 120;
2479async function aiGrabSuggest(request) {
2480  const { kind, hostElem, onStatus } = request;
2481  let payload = {
2482    prompt: request.instruction,
2483    grab: {
2484      kind,
2485      sources: kind == "attribute" ? listSources(request.pageUrl) : ""
2486    },
2487    page: {
2488      url: request.pageUrl || location.href,
2489      title: document.title,
2490      viewport: `${globalThis.innerWidth}x${globalThis.innerHeight}`,
2491      skeleton: pageSkeleton([
2492        hostElem
2493      ], SKELETON_MAX_CHARS)
2494    }
2495  };
2496  let text = "";
2497  for (let round = 0; true; round++) {
2498    const turn = await callServer(payload);
2499    if (turn.text) {
2500      text = turn.text;
2501    }
2502    const proposal = turn.tool_calls.find((v3) => v3.name == "propose_grab");
2503    if (proposal) {
2504      return {
2505        suggestion: readSuggestion(kind, proposal.input, hostElem, request.pageUrl),
2506        text
2507      };
2508    }
2509    if (!turn.tool_calls.length) {
2510      return {
2511        suggestion: null,
2512        text: text || "The AI did not find anything on this page that matches what you described."
2513      };
2514    }
2515    if (round >= MAX_ROUNDS) {
2516      return {
2517        suggestion: null,
2518        text: "The AI did not settle on an answer in the allotted number of steps. Try describing the value differently."
2519      };
2520    }
2521    const results = turn.tool_calls.map((call) => ({
2522      id: call.id,
2523      ...call.name == "query" ? runQuery(str(call.input.selector), hostElem, onStatus) : {
2524        content: `Unknown tool: ${call.name}`,
2525        is_error: true
2526      }
2527    }));
2528    payload = {
2529      grab: {
2530        kind
2531      },
2532      messages: turn.messages,
2533      tool_results: results
2534    };
2535  }
2536}
2537async function callServer(payload) {
2538  const row = await queryRow("CALL acc_actions.ai_live_edit(@request, @action_id, @action_version)", {
2539    request: JSON.stringify(payload),
2540    action_id: 0,
2541    action_version: 0
2542  }, true);
2543  const raw = String(row?.result ?? "");
2544  if (!raw) {
2545    throw new Error("The AI service returned an empty answer. Your picker session may have expired - reopen the picker from Personyze.");
2546  }
2547  let parsed;
2548  try {
2549    parsed = JSON.parse(raw);
2550  } catch {
2551    throw new Error("The AI service answered with something unreadable: " + raw.slice(0, 120));
2552  }
2553  if (!Array.isArray(parsed?.messages) || !Array.isArray(parsed?.tool_calls)) {
2554    throw new Error("Unexpected answer from the AI service.");
2555  }
2556  return {
2557    messages: parsed.messages,
2558    text: typeof parsed.text == "string" ? parsed.text : "",
2559    tool_calls: parsed.tool_calls
2560  };
2561}
2562function runQuery(selector, hostElem, onStatus) {
2563  if (!selector) {
2564    return {
2565      content: "No selector given",
2566      is_error: true
2567    };
2568  }
2569  let found;
2570  try {
2571    found = Array.from(document.querySelectorAll(selector)).filter((v3) => v3 != hostElem && !hostElem.contains(v3));
2572  } catch {
2573    return {
2574      content: `Not a valid CSS selector: ${selector}`,
2575      is_error: true
2576    };
2577  }
2578  onStatus?.(`Checked ${selector} - ${found.length} match${found.length == 1 ? "" : "es"}`);
2579  if (!found.length) {
2580    return {
2581      content: "0 elements match."
2582    };
2583  }
2584  const lines = [
2585    `${found.length} element${found.length == 1 ? "" : "s"} match.`
2586  ];
2587  for (let i4 = 0, iEnd = Math.min(found.length, MAX_LISTED_MATCHES); i4 < iEnd; i4++) {
2588    const elem = found[i4];
2589    const value = grabValue(elem);
2590    lines.push(`${i4 + 1}. ${describeElem(elem)} - would read: ${value ? JSON.stringify(cut2(value, QUERY_VALUE_MAX_CHARS)) : "(nothing)"}`);
2591  }
2592  if (found.length > MAX_LISTED_MATCHES) {
2593    lines.push(`... and ${found.length - MAX_LISTED_MATCHES} more`);
2594  }
2595  return {
2596    content: lines.join("\n")
2597  };
2598}
2599function listSources(pageUrl) {
2600  const blocks = [
2601    [
2602      "Cookies",
2603      "cookie"
2604    ],
2605    [
2606      "Local storage",
2607      "local"
2608    ],
2609    [
2610      "Session storage",
2611      "session"
2612    ],
2613    [
2614      "META tags",
2615      "meta"
2616    ],
2617    [
2618      "URL parameters",
2619      "url"
2620    ]
2621  ];
2622  const out = new Array();
2623  let spent = 0;
2624  for (const [title, source] of blocks) {
2625    const candidates = listCandidates(source, pageUrl);
2626    const lines = [
2627      `## ${title} (source: ${source})`
2628    ];
2629    if (!candidates.length) {
2630      lines.push("(none on this page)");
2631    }
2632    for (const item of candidates) {
2633      const line = `- ${item.key} = ${JSON.stringify(cut2(item.value, SOURCE_VALUE_MAX_CHARS))}`;
2634      if (spent + line.length > SOURCES_MAX_CHARS) {
2635        lines.push(`- ... the rest of this list was cut`);
2636        break;
2637      }
2638      spent += line.length;
2639      lines.push(line);
2640    }
2641    out.push(lines.join("\n"));
2642  }
2643  return out.join("\n\n");
2644}
2645function readSuggestion(kind, input, hostElem, pageUrl) {
2646  const explanation = str(input.explanation).trim();
2647  if (kind == "placeholder") {
2648    const selector = str(input.selector).trim();
2649    const matches2 = findOutside(selector, hostElem);
2650    return {
2651      kind: "placeholder",
2652      selector,
2653      placement: readPlacement(str(input.placement)),
2654      name: str(input.name).trim().slice(0, MAX_NAME_CHARS),
2655      explanation,
2656      elem: matches2[0] ?? null,
2657      nMatches: matches2.length
2658    };
2659  }
2660  if (kind != "attribute") {
2661    const selector = str(input.selector).trim();
2662    const matches2 = findOutside(selector, hostElem);
2663    return {
2664      kind: "goal",
2665      selector,
2666      isMany: input.match_many === true,
2667      explanation,
2668      elem: matches2[0] ?? null,
2669      value: matches2[0] ? grabValue(matches2[0]) : "",
2670      nMatches: matches2.length
2671    };
2672  }
2673  const source = readSource(str(input.source));
2674  const key = str(input.key).trim();
2675  const isPage = source == "page";
2676  const matches = isPage ? findOutside(key, hostElem) : [];
2677  const elem = matches[0] ?? null;
2678  const attrRaw = str(input.attr).trim();
2679  const attr = isPage && elem?.hasAttribute(attrRaw) ? attrRaw : "";
2680  const triggerRaw = str(input.trigger_selector).trim();
2681  const trigger = findOutside(triggerRaw, hostElem).length ? triggerRaw : "";
2682  return {
2683    kind: "attribute",
2684    source,
2685    key,
2686    attr,
2687    isSearchInput: input.is_search_input === true,
2688    triggerSelector: trigger,
2689    mask: readMask(str(input.mask)),
2690    explanation,
2691    elem,
2692    value: !isPage ? readValue(source, key, pageUrl) : !elem ? "" : attr ? elem.getAttribute(attr) ?? "" : grabValue(elem),
2693    nMatches: isPage ? matches.length : -1
2694  };
2695}
2696function findOutside(selector, hostElem) {
2697  if (!selector) {
2698    return [];
2699  }
2700  try {
2701    return Array.from(document.querySelectorAll(selector)).filter((v3) => v3 != hostElem && !hostElem.contains(v3));
2702  } catch {
2703    return [];
2704  }
2705}
2706function readSource(source) {
2707  switch (source) {
2708    case "page":
2709    case "meta":
2710    case "cookie":
2711    case "local":
2712    case "session":
2713    case "variable":
2714    case "url":
2715      return source;
2716  }
2717  return "page";
2718}
2719function readPlacement(placement) {
2720  switch (placement) {
2721    case "before":
2722    case "after":
2723    case "replace":
2724      return placement;
2725  }
2726  return "inside";
2727}
2728function readMask(mask) {
2729  switch (mask) {
2730    case "number":
2731    case "nonnumber":
2732    case "email":
2733      return mask;
2734  }
2735  return "none";
2736}
2737function str(value) {
2738  return typeof value == "string" ? value : "";
2739}
2740function cut2(text, maxChars) {
2741  return text.length <= maxChars ? text : text.slice(0, maxChars - 1) + "\u2026";
2742}
2743
2744// src/components/AiGrabCard.tsx
2745function AiGrabCard(props) {
2746  const [isOpen, setIsOpen] = p2(false);
2747  const [prompt, setPrompt] = p2("");
2748  const [isBusy, setIsBusy] = p2(false);
2749  const [status, setStatus] = p2("");
2750  const [error, setError] = p2("");
2751  const [suggestion, setSuggestion] = p2(null);
2752  const [answer, setAnswer] = p2("");
2753  if (!isJsapiConfigured()) {
2754    return null;
2755  }
2756  async function suggest(instruction) {
2757    const text = instruction.trim();
2758    if (!text || isBusy) {
2759      return;
2760    }
2761    setIsBusy(true);
2762    setError("");
2763    setStatus("");
2764    setSuggestion(null);
2765    setAnswer("");
2766    try {
2767      const result = await aiGrabSuggest({
2768        kind: props.kind,
2769        instruction: text,
2770        hostElem: props.hostElem,
2771        pageUrl: props.pageUrl,
2772        onStatus: setStatus
2773      });
2774      setSuggestion(result.suggestion);
2775      setAnswer(result.suggestion ? "" : result.text);
2776    } catch (e3) {
2777      console.error(e3);
2778      setError(e3 instanceof Error ? e3.message : "The AI request failed.");
2779    }
2780    setIsBusy(false);
2781    setStatus("");
2782  }
2783  return /* @__PURE__ */ u2("div", {
2784    class: "qs-sec qs-ai",
2785    children: [
2786      /* @__PURE__ */ u2("button", {
2787        type: "button",
2788        class: "qs-ai-head",
2789        "aria-expanded": isOpen,
2790        onClick: () => setIsOpen(!isOpen),
2791        children: [
2792          /* @__PURE__ */ u2("span", {
2793            class: "qs-ai-ico",
2794            children: ic.sparkle
2795          }),
2796          /* @__PURE__ */ u2("h3", {
2797            children: props.title
2798          }),
2799          /* @__PURE__ */ u2("span", {
2800            class: "qs-ai-tag",
2801            children: "AI"
2802          }),
2803          /* @__PURE__ */ u2("span", {
2804            class: "qs-ai-chev" + (isOpen ? " qs-on" : ""),
2805            children: ic.chevronDown
2806          })
2807        ]
2808      }),
2809      isOpen && /* @__PURE__ */ u2("div", {
2810        class: "qs-ai-body",
2811        children: [
2812          /* @__PURE__ */ u2("div", {
2813            class: "qs-hint",
2814            children: props.hint
2815          }),
2816          /* @__PURE__ */ u2("textarea", {
2817            class: "qs-ai-input",
2818            rows: 2,
2819            value: prompt,
2820            placeholder: props.placeholder,
2821            disabled: isBusy,
2822            onInput: (ev) => setPrompt(ev.target.value),
2823            onKeyDown: (ev) => {
2824              if (ev.key == "Enter" && !ev.shiftKey) {
2825                ev.preventDefault();
2826                void suggest(prompt);
2827              }
2828            }
2829          }),
2830          /* @__PURE__ */ u2("div", {
2831            class: "qs-ai-chips",
2832            children: props.chips.map((chip) => /* @__PURE__ */ u2("button", {
2833              type: "button",
2834              class: "qs-ai-chip",
2835              title: "Ask for: " + chip.prompt,
2836              disabled: isBusy,
2837              onClick: () => {
2838                setPrompt(chip.prompt);
2839                void suggest(chip.prompt);
2840              },
2841              children: chip.label
2842            }, chip.label))
2843          }),
2844          /* @__PURE__ */ u2("button", {
2845            type: "button",
2846            class: "qs-btn qs-ai-btn",
2847            disabled: isBusy || !prompt.trim(),
2848            onClick: () => void suggest(prompt),
2849            children: [
2850              isBusy ? /* @__PURE__ */ u2("span", {
2851                class: "qs-spin"
2852              }) : ic.sparkle,
2853              isBusy ? "Looking at the page..." : "Suggest with AI"
2854            ]
2855          }),
2856          isBusy && status && /* @__PURE__ */ u2("div", {
2857            class: "qs-ai-status",
2858            children: status
2859          }),
2860          error && /* @__PURE__ */ u2("div", {
2861            class: "qs-callout qs-ai-warn",
2862            style: "margin-top:0.7em",
2863            children: [
2864              ic.warn,
2865              /* @__PURE__ */ u2("div", {
2866                children: error
2867              })
2868            ]
2869          }),
2870          !!answer && !suggestion && /* @__PURE__ */ u2("div", {
2871            class: "qs-callout qs-ai-warn",
2872            style: "margin-top:0.7em",
2873            children: [
2874              ic.warn,
2875              /* @__PURE__ */ u2("div", {
2876                children: answer
2877              })
2878            ]
2879          }),
2880          suggestion && /* @__PURE__ */ u2(Result, {
2881            suggestion,
2882            onApply: () => props.onApply(suggestion),
2883            onDiscard: () => setSuggestion(null)
2884          })
2885        ]
2886      })
2887    ]
2888  });
2889}
2890function Result(props) {
2891  const { suggestion } = props;
2892  const rows = suggestion.kind == "attribute" ? attributeRows(suggestion) : suggestion.kind == "placeholder" ? placeholderRows(suggestion) : goalRows(suggestion);
2893  const isUnusable = suggestion.nMatches == 0;
2894  return /* @__PURE__ */ u2("div", {
2895    class: "qs-ai-result",
2896    children: [
2897      /* @__PURE__ */ u2("div", {
2898        class: "qs-ai-result-head",
2899        children: [
2900          ic.sparkle,
2901          " AI suggestion"
2902        ]
2903      }),
2904      rows.map(([label, value, isMono]) => /* @__PURE__ */ u2("div", {
2905        class: "qs-ai-field",
2906        children: [
2907          /* @__PURE__ */ u2("div", {
2908            class: "qs-ai-k",
2909            children: label
2910          }),
2911          /* @__PURE__ */ u2("div", {
2912            class: "qs-ai-v" + (isMono ? " qs-ai-mono" : ""),
2913            children: value || "\u2014"
2914          })
2915        ]
2916      }, label)),
2917      !!suggestion.explanation && /* @__PURE__ */ u2("div", {
2918        class: "qs-hint",
2919        style: "margin:0.6em 0 0",
2920        children: suggestion.explanation
2921      }),
2922      isUnusable && /* @__PURE__ */ u2("div", {
2923        class: "qs-hint",
2924        style: "margin:0.6em 0 0",
2925        children: "That selector matches nothing on this page, so there is nothing to apply. Rephrase, or pick the element by hand below."
2926      }),
2927      /* @__PURE__ */ u2("div", {
2928        class: "qs-btn-row",
2929        style: "margin-top:0.7em",
2930        children: [
2931          /* @__PURE__ */ u2("button", {
2932            type: "button",
2933            class: "qs-btn",
2934            onClick: props.onDiscard,
2935            children: "Discard"
2936          }),
2937          /* @__P
2937URE__ */ u2("button", {
2938            type: "button",
2939            class: "qs-btn qs-btn-primary",
2940            disabled: isUnusable,
2941            onClick: props.onApply,
2942            children: [
2943              ic.check,
2944              "Apply & fill the form"
2945            ]
2946          })
2947        ]
2948      })
2949    ]
2950  });
2951}
2952var SOURCE_LABELS = {
2953  page: "An element on the page",
2954  cookie: "A cookie",
2955  local: "Local storage",
2956  session: "Session storage",
2957  meta: "A META tag",
2958  url: "A URL parameter",
2959  variable: "A JavaScript variable"
2960};
2961function attributeRows(suggestion) {
2962  const isPage = suggestion.source == "page";
2963  const rows = [
2964    [
2965      "Source",
2966      SOURCE_LABELS[suggestion.source] ?? suggestion.source
2967    ],
2968    [
2969      isPage ? "Selector" : "Key",
2970      suggestion.key,
2971      true
2972    ]
2973  ];
2974  if (isPage) {
2975    rows.push([
2976      "Collect",
2977      suggestion.attr ? `The "${suggestion.attr}" attribute` : `The element's text`
2978    ]);
2979    rows.push([
2980      "Matches on this page",
2981      suggestion.nMatches == 1 ? "1 element" : `${suggestion.nMatches} elements`
2982    ]);
2983    if (suggestion.isSearchInput) {
2984      rows.push([
2985        "This field is",
2986        `The site's search box`
2987      ]);
2988    }
2989  }
2990  if (suggestion.triggerSelector) {
2991    rows.push([
2992      "Read it after a click on",
2993      suggestion.triggerSelector,
2994      true
2995    ]);
2996  }
2997  if (suggestion.mask != "none") {
2998    rows.push([
2999      "Mask",
3000      maskLabel(suggestion.mask)
3001    ]);
3002  }
3003  rows.push([
3004    "Value right now",
3005    suggestion.value || "(nothing here right now)"
3006  ]);
3007  return rows;
3008}
3009var PLACEMENT_LABELS = {
3010  inside: "Inside the selected element",
3011  before: "Before the selected element",
3012  after: "After the selected element",
3013  replace: "Replace the selected element"
3014};
3015function placeholderRows(suggestion) {
3016  return [
3017    [
3018      "Placeholder name",
3019      suggestion.name
3020    ],
3021    [
3022      "Anchor element",
3023      suggestion.selector,
3024      true
3025    ],
3026    [
3027      "Content goes",
3028      PLACEMENT_LABELS[suggestion.placement] ?? suggestion.placement
3029    ],
3030    [
3031      "Matches on this page",
3032      suggestion.nMatches == 1 ? "1 element" : `${suggestion.nMatches} elements`
3033    ]
3034  ];
3035}
3036function goalRows(suggestion) {
3037  const rows = [
3038    [
3039      "Selector",
3040      suggestion.selector,
3041      true
3042    ],
3043    [
3044      "This goal is about",
3045      suggestion.isMany ? "Every element like it" : "Only this element"
3046    ],
3047    [
3048      "Matches on this page",
3049      suggestion.nMatches == 1 ? "1 element" : `${suggestion.nMatches} elements`
3050    ]
3051  ];
3052  if (suggestion.value) {
3053    rows.push([
3054      "Value right now",
3055      suggestion.value
3056    ]);
3057  }
3058  return rows;
3059}
3060
3061// src/components/ElementPick.tsx
3062function useElementPick(hostElem, options) {
3063  const [isPicking, setIsPicking] = p2(false);
3064  const [chain, setChain] = p2(new Array());
3065  const [chainIndex, setChainIndex] = p2(-1);
3066  const [selector, setSelector] = p2("");
3067  const [highlight, setHighlight] = p2(null);
3068  const pickerRef = F2();
3069  const optionsRef = F2(options);
3070  optionsRef.current = options;
3071  if (!pickerRef.current) {
3072    pickerRef.current = new Picker();
3073  }
3074  const picker = pickerRef.current;
3075  const selected = chainIndex >= 0 && chainIndex < chain.length ? chain[chainIndex] : null;
3076  const chainRef = F2(chain);
3077  chainRef.current = chain;
3078  const highlightRef = F2(highlight);
3079  highlightRef.current = highlight;
3080  const selectedRef = F2(selected);
3081  selectedRef.current = selected;
3082  const selectElem = x2((elem, selector2) => {
3083    const newChain = ancestorChain(elem);
3084    setChain(newChain);
3085    setChainIndex(newChain.length - 1);
3086    setSelector(selector2 ?? (optionsRef.current?.selectorOf ?? elemToSelector)(elem));
3087  }, []);
3088  const pickAncestor = x2((index) => {
3089    const elem = chainRef.current[index];
3090    if (elem) {
3091      setChainIndex(index);
3092      setSelector((optionsRef.current?.selectorOf ?? elemToSelector)(elem));
3093    }
3094  }, []);
3095  const beginPick = x2(() => {
3096    setIsPicking(true);
3097    getTracker()?.proxy_modify_links?.(true, 111);
3098    picker.selectBegin({
3099      ignore: [
3100        hostElem
3101      ],
3102      onSelect(elem) {
3103        picker.selectEnd();
3104        setIsPicking(false);
3105        if (elem) {
3106          selectElem(elem);
3107        }
3108      }
3109    });
3110  }, [
3111    picker,
3112    hostElem,
3113    selectElem
3114  ]);
3115  const endPick = x2(() => {
3116    picker.selectEnd();
3117    setIsPicking(false);
3118  }, [
3119    picker
3120  ]);
3121  const restoreHighlight = x2(() => picker.highlight(highlightRef.current ?? (selectedRef.current ? [
3122    selectedRef.current
3123  ] : [])), [
3124    picker
3125  ]);
3126  _2(() => {
3127    if (!isPicking) {
3128      picker.highlight(highlight ?? (selected ? [
3129        selected
3130      ] : []));
3131    }
3132  }, [
3133    picker,
3134    highlight,
3135    selected,
3136    isPicking
3137  ]);
3138  _2(() => () => picker.destroy(), [
3139    picker
3140  ]);
3141  return {
3142    picker,
3143    isPicking,
3144    chain,
3145    chainIndex,
3146    selected,
3147    selector,
3148    setSelector,
3149    beginPick,
3150    endPick,
3151    selectElem,
3152    pickAncestor,
3153    setHighlight,
3154    restoreHighlight
3155  };
3156}
3157function ElementPickBody(props) {
3158  const { pick } = props;
3159  if (props.isConnecting) {
3160    return /* @__PURE__ */ u2("div", {
3161      class: "qs-callout",
3162      children: [
3163        /* @__PURE__ */ u2("span", {
3164          class: "qs-spin"
3165        }),
3166        /* @__PURE__ */ u2("div", {
3167          children: "Connecting to the Personyze panel..."
3168        })
3169      ]
3170    });
3171  }
3172  if (pick.isPicking) {
3173    return /* @__PURE__ */ u2("div", {
3174      class: "qs-callout",
3175      children: [
3176        ic.target,
3177        /* @__PURE__ */ u2("div", {
3178          children: "Point and click the spot on the page. Press Esc to stop."
3179        })
3180      ]
3181    });
3182  }
3183  if (!pick.selected) {
3184    return /* @__PURE__ */ u2("div", {
3185      class: "qs-btn-row",
3186      children: [
3187        /* @__PURE__ */ u2("button", {
3188          type: "button",
3189          class: "qs-btn qs-btn-primary",
3190          onClick: pick.beginPick,
3191          children: [
3192            ic.target,
3193            " ",
3194            props.pickLabel
3195          ]
3196        }),
3197        pick.selector && /* @__PURE__ */ u2("span", {
3198          class: "qs-selector",
3199          children: pick.selector
3200        })
3201      ]
3202    });
3203  }
3204  return /* @__PURE__ */ u2(k, {
3205    children: [
3206      /* @__PURE__ */ u2("div", {
3207        class: "qs-label",
3208        children: "Element"
3209      }),
3210      /* @__PURE__ */ u2("div", {
3211        class: "qs-tree",
3212        children: pick.chain.map((elem, i4) => /* @__PURE__ */ u2("button", {
3213          type: "button",
3214          class: "qs-tree-row" + (i4 == pick.chainIndex ? " qs-on" : ""),
3215          style: "padding-left:" + (0.45 + i4 * 0.9) + "em",
3216          title: describeElem(elem),
3217          onMouseEnter: () => pick.picker.highlight([
3218            elem
3219          ], "#60A5FA", true),
3220          onMouseLeave: pick.restoreHighlight,
3221          onClick: () => pick.pickAncestor(i4),
3222          children: describeElem(elem)
3223        }, i4))
3224      }),
3225      /* @__PURE__ */ u2("div", {
3226        class: "qs-label",
3227        style: "margin-top:0.8em",
3228        children: "Captured selector"
3229      }),
3230      /* @__PURE__ */ u2("div", {
3231        class: "qs-selector",
3232        children: pick.selector
3233      }),
3234      /* @__PURE__ */ u2("div", {
3235        class: "qs-btn-row",
3236        style: "margin-top:0.6em",
3237        children: /* @__PURE__ */ u2("button", {
3238          type: "button",
3239          class: "qs-btn",
3240          onClick: pick.beginPick,
3241          children: "Reselect"
3242        })
3243      })
3244    ]
3245  });
3246}
3247
3248// src/components/PlaceholderTool.tsx
3249var PANEL_TIMEOUT = 2e4;
3250var PLACE_MODES = [
3251  {
3252    value: "inside",
3253    text: "Inside the selected element",
3254    hint: "Replaces whatever is inside the element with your content.",
3255    meta: "Inside element"
3256  },
3257  {
3258    value: "before",
3259    text: "Before selected element",
3260    hint: "Injects the content before the element in the DOM.",
3261    meta: "Before element"
3262  },
3263  {
3264    value: "after",
3265    text: "After selected element",
3266    hint: "Injects the content after the element in the DOM.",
3267    meta: "After element"
3268  },
3269  {
3270    value: "replace",
3271    text: "Replace selected element",
3272    hint: "Swaps the element out and renders your content in its place.",
3273    meta: "Replace element"
3274  }
3275];
3276var AI_CHIPS = [
3277  {
3278    label: "Recommendations for returning shoppers",
3279    prompt: "A recommendations widget for returning shoppers, under the category title"
3280  },
3281  {
3282    label: "Promo banner above the grid",
3283    prompt: "A limited-time promo banner above the main product grid"
3284  },
3285  {
3286    label: "Free-shipping bar",
3287    prompt: "A free-shipping bar across the top of the page, for first-time visitors"
3288  },
3289  {
3290    label: "Newsletter block before the footer",
3291    prompt: "A newsletter signup block just before the footer"
3292  }
3293];
3294var PREVIEW_SIZES = [
3295  {
3296    value: "336x280",
3297    color: "#79B157"
3298  },
3299  {
3300    value: "300x250",
3301    color: "#5794B1"
3302  },
3303  {
3304    value: "728x90",
3305    color: "#B1575F"
3306  },
3307  {
3308    value: "300x600",
3309    color: "#C79352"
3310  },
3311  {
3312    value: "320x100",
3313    color: "#1EA774"
3314  }
3315];
3316var CUSTOM_SIZE_COLOR = "#8B7BD8";
3317function hasContent(elem) {
3318  for (const node of Array.from(elem?.childNodes ?? [])) {
3319    if (node.nodeType == 1) {
3320      return true;
3321    }
3322    if (node.nodeType == 3 && (node.nodeValue ?? "").trim()) {
3323      return true;
3324    }
3325  }
3326  return false;
3327}
3328function scopeOf(selector, nMatches) {
3329  if (/#[\w-]/.test(selector)) {
3330    return {
3331      label: "Precise match",
3332      tag: "this element only",
3333      ratio: 0.12,
3334      desc: "Pinned to an id, so it lands on exactly one element wherever it appears.",
3335      isWide: false
3336    };
3337  }
3338  if (nMatches <= 1) {
3339    return {
3340      label: "Specific match",
3341      tag: "one element here",
3342      ratio: 0.38,
3343      desc: "Matches a single element on this page. It may still match on other pages built from the same template.",
3344      isWide: false
3345    };
3346  }
3347  if (nMatches <= 4) {
3348    return {
3349      label: "Repeats on this page",
3350      tag: `${nMatches} elements here`,
3351      ratio: 0.66,
3352      desc: `This selector already matches ${nMatches} elements here, so the content would be placed at each of them.`,
3353      isWide: true
3354    };
3355  }
3356  return {
3357    label: "Broad match",
3358    tag: "appears on many pages",
3359    ratio: 0.92,
3360    desc: `A generic selector like this matches ${nMatches} elements on this page alone, and typically appears across many pages of the site.`,
3361    isWide: true
3362  };
3363}
3364function PlaceholderTool(props) {
3365  const [isConnecting, setIsConnecting] = p2(true);
3366  const [error, setError] = p2("");
3367  const [isSaving, setIsSaving] = p2(false);
3368  const [isClosed, setIsClosed] = p2(false);
3369  const [placeMode, setPlaceMode] = p2("inside");
3370  const [previewSize, setPreviewSize] = p2(PREVIEW_SIZES[0].value);
3371  const [isPreviewOn, setIsPreviewOn] = p2(false);
3372  const [customWidth, setCustomWidth] = p2(336);
3373  const [customHeight, setCustomHeight] = p2(280);
3374  const [isPickOpen, setIsPickOpen] = p2(true);
3375  const [isPlaceOpen, setIsPlaceOpen] = p2(false);
3376  const [isLookOpen, setIsLookOpen] = p2(false);
3377  const bridgeRef = F2();
3378  const previewRef = F2(null);
3379  const styleOverrideRef = F2("");
3380  const aiNameRef = F2("");
3381  const pick = useElementPick(props.hostElem);
3382  const { selected, selector: htmlId, setSelector: setHtmlId, selectElem, beginPick, endPick } = pick;
3383  _2(() => {
3384    let isGone = false;
3385    let isConnected = false;
3386    const bridge = new ToolBridge({
3387      bufferKey: props.bufferKey,
3388      guiOrigin: props.guiOrigin,
3389      onValue(value) {
3390        if (isGone) {
3391          return;
3392        }
3393        isConnected = true;
3394        setIsConnecting(false);
3395        const columns = value.columns ?? {};
3396        const toolProps = value.tool_props ?? {};
3397        const savedPlaceMode = parseAeWhere(toolProps.html_change ?? columns.html_change);
3398        if (savedPlaceMode) {
3399          setPlaceMode(savedPlaceMode);
3400        }
3401        const savedStyleOverride = toolProps.style_override_occupied ?? columns.style_override_occupied;
3402        if (typeof savedStyleOverride == "string") {
3403          styleOverrideRef.current = savedStyleOverride;
3404        }
3405        const savedHtmlId = typeof columns.html_id == "string" ? columns.html_id : "";
3406        if (!savedHtmlId) {
3407          beginPick();
3408          return;
3409        }
3410        setHtmlId(savedHtmlId);
3411        const elem = resolveHtmlId(savedHtmlId);
3412        if (elem) {
3413          selectElem(elem, savedHtmlId);
3414        } else {
3415          setError("This placeholder points at an element that is not on this page. Pick the spot again, or open a page where it exists.");
3416          beginPick();
3417        }
3418      }
3419    });
3420    bridgeRef.current = bridge;
3421    bridge.start();
3422    const timer = setTimeout(() => {
3423      if (!isGone && !isConnected) {
3424        setIsConnecting(false);
3425        setError("Could not reach the Personyze panel, so this placeholder could not be loaded. Keep the Personyze tab open and reopen the picker from there.");
3426      }
3427    }, PANEL_TIMEOUT);
3428    return () => {
3429      isGone = true;
3430      clearTimeout(timer);
3431      bridge.destroy();
3432    };
3433  }, [
3434    props.bufferKey,
3435    props.guiOrigin,
3436    beginPick,
3437    selectElem,
3438    setHtmlId
3439  ]);
3440  _2(() => {
3441    if (htmlId) {
3442      setIsPickOpen(false);
3443      setIsPlaceOpen(true);
3444    }
3445  }, [
3446    htmlId
3447  ]);
3448  _2(() => () => {
3449    previewRef.current?.revert();
3450    previewRef.current = null;
3451  }, []);
3452  _2(() => {
3453    previewRef.current?.revert();
3454    previewRef.current = null;
3455    if (isPreviewOn && selected) {
3456      const size = PREVIEW_SIZES.find((v3) => v3.value == previewSize) ?? {
3457        value: previewSize,
3458        color: CUSTOM_SIZE_COLOR
3459      };
3460      const doPutHtml = getTracker()?.do_put_html;
3461      if (!doPutHtml) {
3462        setError("This page is running an older Personyze tracker that cannot show the preview.");
3463        setIsPreviewOn(false);
3464        return;
3465      }
3466      try {
3467        previewRef.current = doPutHtml(selected, previewElem(size.value, size.color), "", {
3468          ae_where: placeMode,
3469          add_elem: "div"
3470        }, {}, false, 0);
3471      } catch (e3) {
3472        setError(e3 instanceof Error ? e3.message : String(e3));
3473        setIsPreviewOn(false);
3474      }
3475    }
3476  }, [
3477    isPreviewOn,
3478    previewSize,
3479    placeMode,
3480    selected
3481  ]);
3482  function applySuggestion(suggestion) {
3483    if (suggestion.kind != "placeholder") {
3484      return;
3485    }
3486    setError("");
3487    endPick();
3488    aiNameRef.current = suggestion.name;
3489    setPlaceMode(suggestion.placement);
3490    setHtmlId(suggestion.selector);
3491    if (suggestion.elem) {
3492      selectElem(suggestion.elem, suggestion.selector);
3493    }
3494  }
3495  function close() {
3496    const panelWindow = getPanelWindow();
3497    setIsClosed(true);
3498    try {
3499      globalThis.close();
3500      panelWindow?.focus();
3501    } catch (e3) {
3502      console.error(e3);
3503    }
3504  }
3505  async function save() {
3506    const bridge = bridgeRef.current;
3507    if (!bridge || !htmlId) {
3508      return;
3509    }
3510    const htmlChange = JSON.stringify({
3511      ae_where: placeMode,
3512      add_elem: "div"
3513    });
3514    setIsSaving(true);
3515    setError("");
3516    previewRef.current?.revert();
3517    previewRef.current = null;
3518    setIsPreviewOn(false);
3519    const styleOverride = styleOverrideRef.current;
3520    const isAcked = await bridge.setValue({
3521      columns: {
3522        name: selected ? describeElem(selected) : htmlId,
3523        html_id: htmlId,
3524        html_change: htmlChange,
3525        style_override_occupied: styleOverride
3526      },
3527      tool_props: {
3528        html_change: htmlChange,
3529        style_override_occupied: styleOverride,
3530        ai_name: aiNameRef.current,
3531        has_content: hasContent(selected)
3532      }
3533    });
3534    setIsSaving(false);
3535    if (!isAcked) {
3536      setError("The Personyze panel did not confirm the selection. Make sure its tab is still open, then try again.");
3537    } else {
3538      close();
3539    }
3540  }
3541  if (isClosed) {
3542    return null;
3543  }
3544  const scope = scopeOf(htmlId, findMatches(htmlId).length);
3545  const placeMeta = PLACE_MODES.find((v3) => v3.value == placeMode);
3546  return /* @__PURE__ */ u2(SimulatorPanel, {
3547    title: "CONTENT PLACEHOLDER",
3548    subtitle: "Point, place & preview on your live page",
3549    logoSrc: props.counterUrl ? props.counterUrl + "/images/logo-icon.svg" : void 0,
3550    error,
3551    onDismissError: () => setError(""),
3552    onClose: close,
3553    footer: /* @__PURE__ */ u2(k, {
3554      children: [
3555        /* @__PURE__ */ u2("button", {
3556          type: "button",
3557          class: "qs-btn",
3558          onClick: close,
3559          children: "Cancel"
3560        }),
3561        /* @__PURE__ */ u2("button", {
3562          type: "button",
3563          class: "qs-btn qs-btn-primary",
3564          disabled: !htmlId || isSaving,
3565          onClick: save,
3566          children: [
3567            isSaving ? /* @__PURE__ */ u2("span", {
3568              class: "qs-spin"
3569            }) : ic.check,
3570            "Save placeholder"
3571          ]
3572        })
3573      ]
3574    }),
3575    children: [
3576      !isConnecting && /* @__PURE__ */ u2(AiGrabCard, {
3577        kind: "placeholder",
3578        hostElem: props.hostElem,
3579        pageUrl: getPageUrl(),
3580        title: "Describe this placement",
3581        hint: "Tell the AI what this placeholder is for - it reads this page, picks the element to anchor the content to, decides where it goes, and names the spot for you.",
3582        placeholder: 'e.g. a promo strip under the "Shop by Category" title... / a recommendations widget before the footer...',
3583        chips: AI_CHIPS,
3584        onApply: applySuggestion
3585      }),
3586      /* @__PURE__ */ u2(PanelSection, {
3587        icon: ic.target,
3588        title: "Select the placeholder element",
3589        meta: htmlId ? scope.label : "",
3590        isOpen: isPickOpen,
3591        onToggle: () => setIsPickOpen(!isPickOpen),
3592        children: [
3593          /* @__PURE__ */ u2("div", {
3594            class: "qs-hint",
3595            children: "Point and click an element on the page. Personyze writes the CSS selector for you \u2014 walk up the list to widen the selection, or start over with Reselect."
3596          }),
3597          /* @__PURE__ */ u2(ElementPickBody, {
3598            pick,
3599            isConnecting,
3600            pickLabel: "Pick an element"
3601          }),
3602          !!htmlId && /* @__PURE__ */ u2("div", {
3603            class: "qs-scope " + (scope.isWide ? "qs-wide" : "qs-narrow"),
3604            children: [
3605              /* @__PURE__ */ u2("div", {
3606                class: "qs-scope-top",
3607                children: [
3608                  /* @__PURE__ */ u2("span", {
3609                    class: "qs-scope-dot"
3610                  }),
3611                  /* @__PURE__ */ u2("span", {
3612                    class: "qs-scope-label",
3613                    children: scope.label
3614                  }),
3615                  /* @__PURE__ */ u2("span", {
3616                    class: "qs-scope-tag",
3617                    children: scope.tag
3618                  })
3619                ]
3620              }),
3621              /* @__PURE__ */ u2("div", {
3622                class: "qs-scope-meter",
3623                children: /* @__PURE__ */ u2("div", {
3624                  class: "qs-scope-bar",
3625                  style: `width:${Math.round(scope.ratio * 100)}%`
3626                })
3627              }),
3628              /* @__PURE__ */ u2("div", {
3629                class: "qs-scope-scale",
3630                children: [
3631                  /* @__PURE__ */ u2("span", {
3632                    children: "This page & variants"
3633                  }),
3634                  /* @__PURE__ */ u2("span", {
3635                    children: "Many pages"
3636                  })
3637                ]
3638              }),
3639              /* @__PURE__ */ u2("div", {
3640                class: "qs-scope-desc",
3641                children: scope.desc
3642              })
3643            ]
3644          })
3645        ]
3646      }),
3647      /* @__PURE__ */ u2(PanelSection, {
3648        icon: ic.swap,
3649        title: "Put personalized content to",
3650        meta: placeMeta?.meta,
3651        isOpen: isPlaceOpen,
3652        onToggle: () => setIsPlaceOpen(!isPlaceOpen),
3653        children: [
3654          /* @__PURE__ */ u2("div", {
3655            class: "qs-hint",
3656            children: "Where the content is injected, relative to the element you selected."
3657          }),
3658          PLACE_MODES.map((item) => /* @__PURE__ */ u2("button", {
3659            type: "button",
3660            class: "qs-opt" + (item.value == placeMode ? " qs-on" : ""),
3661            //	Answering this one opens the preview, which is the only reason to still be
3662            //	here: the placement is chosen to be looked at.
3663            onClick: () => {
3664              setPlaceMode(item.value);
3665              setIsPlaceOpen(false);
3666              setIsLookOpen(true);
3667            },
3668            children: [
3669              /* @__PURE__ */ u2("span", {
3670                class: "qs-opt-radio"
3671              }),
3672              /* @__P
3672URE__ */ u2("span", {
3673                children: [
3674                  /* @__PURE__ */ u2("div", {
3675                    class: "qs-opt-t",
3676                    children: item.text
3677                  }),
3678                  /* @__PURE__ */ u2("div", {
3679                    class: "qs-opt-d",
3680                    children: item.hint
3681                  })
3682                ]
3683              })
3684            ]
3685          }, item.value))
3686        ]
3687      }),
3688      /* @__PURE__ */ u2(PanelSection, {
3689        icon: ic.eye,
3690        title: "Test the look",
3691        meta: isPreviewOn ? previewSize : "Nothing previewed",
3692        isOpen: isLookOpen,
3693        onToggle: () => setIsLookOpen(!isLookOpen),
3694        children: [
3695          /* @__PURE__ */ u2("div", {
3696            class: "qs-hint",
3697            children: "Drop a blank block in to see how content sits here. Nothing is saved to the page \u2014 this is only a preview, and it comes off when you save."
3698          }),
3699          /* @__PURE__ */ u2("div", {
3700            class: "qs-label",
3701            children: "Test a blank ad size"
3702          }),
3703          /* @__PURE__ */ u2("div", {
3704            class: "qs-sizes",
3705            children: PREVIEW_SIZES.map((v3) => /* @__PURE__ */ u2("button", {
3706              type: "button",
3707              class: "qs-size" + (v3.value == previewSize ? " qs-on" : ""),
3708              onClick: () => setPreviewSize(v3.value),
3709              children: v3.value
3710            }, v3.value))
3711          }),
3712          /* @__PURE__ */ u2("div", {
3713            class: "qs-size-custom",
3714            children: [
3715              /* @__PURE__ */ u2("span", {
3716                children: "Or"
3717              }),
3718              /* @__PURE__ */ u2("input", {
3719                class: "qs-num",
3720                type: "number",
3721                min: "1",
3722                value: customWidth,
3723                onInput: (e3) => setCustomWidth(Number(e3.target.value) || 0)
3724              }),
3725              /* @__PURE__ */ u2("span", {
3726                children: "\xD7"
3727              }),
3728              /* @__PURE__ */ u2("input", {
3729                class: "qs-num",
3730                type: "number",
3731                min: "1",
3732                value: customHeight,
3733                onInput: (e3) => setCustomHeight(Number(e3.target.value) || 0)
3734              }),
3735              /* @__PURE__ */ u2("button", {
3736                type: "button",
3737                class: "qs-btn",
3738                disabled: !(customWidth > 0 && customHeight > 0),
3739                onClick: () => setPreviewSize(`${customWidth | 0}x${customHeight | 0}`),
3740                children: "Use this size"
3741              })
3742            ]
3743          }),
3744          /* @__PURE__ */ u2("div", {
3745            class: "qs-btn-row",
3746            style: "margin-top:0.7em",
3747            children: /* @__PURE__ */ u2("button", {
3748              type: "button",
3749              class: "qs-btn",
3750              disabled: !selected,
3751              onClick: () => setIsPreviewOn(!isPreviewOn),
3752              children: [
3753                ic.layout,
3754                isPreviewOn ? "Remove preview" : "Preview in this location"
3755              ]
3756            })
3757          })
3758        ]
3759      })
3760    ]
3761  });
3762}
3763function previewElem(size, color) {
3764  const [width, height] = size.split("x");
3765  const elem = document.createElement("div");
3766  elem.style.cssText = `box-sizing:border-box; width:${width}px; height:${height}px; max-width:100%; line-height:${height}px; border:1px solid ${color}; text-align:center; overflow:hidden; background-image:repeating-linear-gradient(135deg, ${color} 0px, ${color} 5px, white 5px, white 10px, ${color} 10px)`;
3767  const text = document.createElement("span");
3768  text.style.cssText = "background-color:white; color:black; padding:3px; font:normal normal 400 13px/1.45 sans-serif";
3769  text.textContent = size;
3770  elem.appendChild(text);
3771  return elem;
3772}
3773function parseAeWhere(htmlChange) {
3774  let value = htmlChange;
3775  if (typeof value == "string") {
3776    if (!value) {
3777      return void 0;
3778    }
3779    try {
3780      value = JSON.parse(value);
3781    } catch {
3782      return void 0;
3783    }
3784  }
3785  const aeWhere = value?.ae_where;
3786  return aeWhere == "before" || aeWhere == "after" || aeWhere == "replace" || aeWhere == "inside" ? aeWhere : void 0;
3787}
3788
3789// src/apps/simulator-placeholder.ts
3790var HOST_STYLE = "all: initial !important; position: fixed !important; z-index: 2147483647 !important; top: 0 !important; left: 0 !important; width: 0 !important; height: 0 !important";
3791function start(options) {
3792  if (options.jsapi_url) {
3793    configureJsapi({
3794      url: options.jsapi_url,
3795      serverId: options.server_id || 0
3796    });
3797  }
3798  const hostElem = document.createElement("div");
3799  hostElem.setAttribute("style", HOST_STYLE);
3800  document.body.appendChild(hostElem);
3801  const shadow = hostElem.attachShadow({
3802    mode: "open"
3803  });
3804  const style = document.createElement("style");
3805  style.textContent = PANEL_STYLE;
3806  shadow.appendChild(style);
3807  const mount = document.createElement("div");
3808  shadow.appendChild(mount);
3809  B(_(PlaceholderTool, {
3810    bufferKey: options.buffer_key,
3811    guiOrigin: options.gui_origin || "*",
3812    counterUrl: options.counter_url || "",
3813    hostElem
3814  }), mount);
3815  return {
3816    destroy() {
3817      B(null, mount);
3818      hostElem.remove();
3819    }
3820  };
3821}
3822var globalScope = globalThis;
3823if (globalScope.personyzeSimulatorPlaceholder == void 0) {
3824  globalScope.personyzeSimulatorPlaceholder = {
3825    version: 1,
3826    start
3827  };
3828}
3829})();

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.