@pluno/product-agent-web 0.1.16 → 0.1.19

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,7 +1,7 @@
1
- import { PlunoProductAgent as ye } from "./product-agent-sdk.js";
2
- const ve = "#7c3aed";
3
- function ke(t) {
4
- const e = Te(t);
1
+ import { PlunoProductAgent as dt } from "./product-agent-sdk.js";
2
+ const ct = "#7c3aed";
3
+ function ut(t) {
4
+ const e = bt(t);
5
5
  return `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1254 1254" role="img" aria-label="Pluno">
6
6
  <defs>
7
7
  <linearGradient id="boltFill" x1="420" y1="180" x2="790" y2="1040" gradientUnits="userSpaceOnUse">
@@ -75,23 +75,23 @@ function ke(t) {
75
75
  </g>
76
76
  </svg>`;
77
77
  }
78
- function Ce(t) {
79
- return `data:image/svg+xml,${encodeURIComponent(ke(t))}`;
78
+ function gt(t) {
79
+ return `data:image/svg+xml,${encodeURIComponent(ut(t))}`;
80
80
  }
81
- const N = "#2c2a1e", J = [253, 250, 241], Q = 3.5;
82
- function he(t) {
83
- const e = fe(t);
84
- if (ee(M(e), J) >= Q)
81
+ const G = "#2c2a1e", ye = [253, 250, 241], ve = 3.5;
82
+ function Ve(t) {
83
+ const e = qe(t);
84
+ if (Ce(q(e), ye) >= ve)
85
85
  return e;
86
- let o = M(e);
87
- const a = M(N);
86
+ let o = q(e);
87
+ const a = q(G);
88
88
  for (let r = 0; r < 6; r += 1)
89
- if (o = Ne(o, a, 0.22), ee(o, J) >= Q)
90
- return H(o);
91
- return H(o);
89
+ if (o = wt(o, a, 0.22), Ce(o, ye) >= ve)
90
+ return de(o);
91
+ return de(o);
92
92
  }
93
- function Se(t) {
94
- const e = he(t), n = "M547 151 C516 151 493 169 485 199 L382 606 C373 641 396 666 431 666 L523 666 C552 666 568 684 563 713 L491 1028 C486 1054 510 1067 527 1044 L894 487 C915 455 894 432 856 432 L815 432 C784 432 773 411 789 382 L904 205 C922 171 901 145 859 145 Z";
93
+ function ht(t) {
94
+ const e = Ve(t), n = "M547 151 C516 151 493 169 485 199 L382 606 C373 641 396 666 431 666 L523 666 C552 666 568 684 563 713 L491 1028 C486 1054 510 1067 527 1044 L894 487 C915 455 894 432 856 432 L815 432 C784 432 773 411 789 382 L904 205 C922 171 901 145 859 145 Z";
95
95
  return `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1254 1254" role="img" aria-label="Pluno">
96
96
  <defs>
97
97
  <clipPath id="scribbleBoltClip">
@@ -104,35 +104,35 @@ function Se(t) {
104
104
  </defs>
105
105
  <g filter="url(#scribbleBoltWobble)">
106
106
  <g clip-path="url(#scribbleBoltClip)">
107
- <path d="${Le()}" fill="none" stroke="${e}" stroke-width="56" stroke-linecap="round" stroke-linejoin="round" opacity="0.9" transform="rotate(-14 627 600)"/>
107
+ <path d="${mt()}" fill="none" stroke="${e}" stroke-width="56" stroke-linecap="round" stroke-linejoin="round" opacity="0.9" transform="rotate(-14 627 600)"/>
108
108
  </g>
109
- <path d="${n}" fill="none" stroke="${N}" stroke-width="18" stroke-linejoin="round"/>
109
+ <path d="${n}" fill="none" stroke="${G}" stroke-width="18" stroke-linejoin="round"/>
110
110
  <g transform="rotate(-2 528 463)">
111
- <ellipse cx="528" cy="463" rx="73" ry="80" fill="#ffffff" stroke="${N}" stroke-width="13"/>
112
- <ellipse cx="533" cy="473" rx="45" ry="53" fill="${N}"/>
111
+ <ellipse cx="528" cy="463" rx="73" ry="80" fill="#ffffff" stroke="${G}" stroke-width="13"/>
112
+ <ellipse cx="533" cy="473" rx="45" ry="53" fill="${G}"/>
113
113
  <circle cx="557" cy="447" r="16" fill="#ffffff"/>
114
114
  </g>
115
115
  <g transform="rotate(2 717 462)">
116
- <ellipse cx="717" cy="462" rx="73" ry="80" fill="#ffffff" stroke="${N}" stroke-width="13"/>
117
- <ellipse cx="712" cy="473" rx="45" ry="53" fill="${N}"/>
116
+ <ellipse cx="717" cy="462" rx="73" ry="80" fill="#ffffff" stroke="${G}" stroke-width="13"/>
117
+ <ellipse cx="712" cy="473" rx="45" ry="53" fill="${G}"/>
118
118
  <circle cx="728" cy="447" r="16" fill="#ffffff"/>
119
119
  </g>
120
120
  </g>
121
121
  </svg>`;
122
122
  }
123
- function Ee(t) {
124
- return `data:image/svg+xml,${encodeURIComponent(Se(t))}`;
123
+ function ft(t) {
124
+ return `data:image/svg+xml,${encodeURIComponent(ht(t))}`;
125
125
  }
126
- function Le() {
126
+ function mt() {
127
127
  let n = "M 280 120", o = !1, a = 0;
128
128
  for (let r = 150; r <= 1170; r += 62) {
129
- const i = (a % 3 - 1) * 18, d = o ? 280 - i : 1020 + i;
129
+ const l = (a % 3 - 1) * 18, d = o ? 280 - l : 1020 + l;
130
130
  n += ` L ${d} ${r}`, o = !o, a += 1;
131
131
  }
132
132
  return n;
133
133
  }
134
- function Te(t) {
135
- const e = fe(t), n = W(M(e));
134
+ function bt(t) {
135
+ const e = qe(t), n = ce(q(e));
136
136
  return n > 0.86 ? {
137
137
  top: "#ffffff",
138
138
  middle: "#f6f6f6",
@@ -156,108 +156,113 @@ function Te(t) {
156
156
  inner: "#4b4b4b",
157
157
  shadow: "#000000"
158
158
  } : {
159
- top: v(e, 0.28, -0.03),
160
- middle: v(e, 0.08, 0.04),
161
- bottom: v(e, -0.1, 0.02),
162
- edgeStart: v(e, 0.08, 0.08),
163
- edgeMiddle: v(e, -0.08, 0.08),
164
- edgeEnd: v(e, -0.18, 0.05),
165
- glow: v(e, 0.32, -0.12),
166
- highlight: v(e, 0.38, -0.18),
167
- inner: v(e, 0.24, -0.1),
168
- shadow: v(e, -0.25, -0.08)
159
+ top: L(e, 0.28, -0.03),
160
+ middle: L(e, 0.08, 0.04),
161
+ bottom: L(e, -0.1, 0.02),
162
+ edgeStart: L(e, 0.08, 0.08),
163
+ edgeMiddle: L(e, -0.08, 0.08),
164
+ edgeEnd: L(e, -0.18, 0.05),
165
+ glow: L(e, 0.32, -0.12),
166
+ highlight: L(e, 0.38, -0.18),
167
+ inner: L(e, 0.24, -0.1),
168
+ shadow: L(e, -0.25, -0.08)
169
169
  };
170
170
  }
171
- function fe(t) {
171
+ function qe(t) {
172
172
  const e = t.trim();
173
- return /^#[0-9a-f]{6}$/i.test(e) ? e.toLowerCase() : /^#[0-9a-f]{3}$/i.test(e) ? `#${e.slice(1).split("").map((n) => n + n).join("").toLowerCase()}` : ve;
173
+ return /^#[0-9a-f]{6}$/i.test(e) ? e.toLowerCase() : /^#[0-9a-f]{3}$/i.test(e) ? `#${e.slice(1).split("").map((n) => n + n).join("").toLowerCase()}` : ct;
174
174
  }
175
- function M(t) {
175
+ function q(t) {
176
176
  return [
177
177
  Number.parseInt(t.slice(1, 3), 16),
178
178
  Number.parseInt(t.slice(3, 5), 16),
179
179
  Number.parseInt(t.slice(5, 7), 16)
180
180
  ];
181
181
  }
182
- function H([t, e, n]) {
182
+ function de([t, e, n]) {
183
183
  const o = (a) => Math.max(0, Math.min(255, Math.round(a))).toString(16).padStart(2, "0");
184
184
  return `#${o(t)}${o(e)}${o(n)}`;
185
185
  }
186
- function W([t, e, n]) {
186
+ function ce([t, e, n]) {
187
187
  const o = (a) => {
188
188
  const r = a / 255;
189
189
  return r <= 0.04045 ? r / 12.92 : ((r + 0.055) / 1.055) ** 2.4;
190
190
  };
191
191
  return 0.2126 * o(t) + 0.7152 * o(e) + 0.0722 * o(n);
192
192
  }
193
- function ee(t, e) {
194
- const n = W(t), o = W(e), [a, r] = n > o ? [n, o] : [o, n];
193
+ function Ce(t, e) {
194
+ const n = ce(t), o = ce(e), [a, r] = n > o ? [n, o] : [o, n];
195
195
  return (a + 0.05) / (r + 0.05);
196
196
  }
197
- function Ne(t, e, n) {
198
- const o = V(n);
197
+ function wt(t, e, n) {
198
+ const o = ue(n);
199
199
  return [
200
200
  t[0] + (e[0] - t[0]) * o,
201
201
  t[1] + (e[1] - t[1]) * o,
202
202
  t[2] + (e[2] - t[2]) * o
203
203
  ];
204
204
  }
205
- function v(t, e, n) {
206
- const [o, a, r] = Pe(M(t));
207
- return H(Ie(o, V(a + n), V(r + e)));
205
+ function L(t, e, n) {
206
+ const [o, a, r] = _t(q(t));
207
+ return de(xt(o, ue(a + n), ue(r + e)));
208
208
  }
209
- function Pe([t, e, n]) {
210
- const o = t / 255, a = e / 255, r = n / 255, i = Math.max(o, a, r), d = Math.min(o, a, r), u = (i + d) / 2;
211
- if (i === d)
209
+ function _t([t, e, n]) {
210
+ const o = t / 255, a = e / 255, r = n / 255, l = Math.max(o, a, r), d = Math.min(o, a, r), u = (l + d) / 2;
211
+ if (l === d)
212
212
  return [0, 0, u];
213
- const p = i - d, g = u > 0.5 ? p / (2 - i - d) : p / (i + d);
214
- return [(i === o ? (a - r) / p + (a < r ? 6 : 0) : i === a ? (r - o) / p + 2 : (o - a) / p + 4) / 6, g, u];
213
+ const h = l - d, c = u > 0.5 ? h / (2 - l - d) : h / (l + d);
214
+ return [(l === o ? (a - r) / h + (a < r ? 6 : 0) : l === a ? (r - o) / h + 2 : (o - a) / h + 4) / 6, c, u];
215
215
  }
216
- function Ie(t, e, n) {
216
+ function xt(t, e, n) {
217
217
  if (e === 0)
218
218
  return [n * 255, n * 255, n * 255];
219
219
  const o = n < 0.5 ? n * (1 + e) : n + e - n * e, a = 2 * n - o;
220
220
  return [
221
- B(a, o, t + 1 / 3) * 255,
222
- B(a, o, t) * 255,
223
- B(a, o, t - 1 / 3) * 255
221
+ ie(a, o, t + 1 / 3) * 255,
222
+ ie(a, o, t) * 255,
223
+ ie(a, o, t - 1 / 3) * 255
224
224
  ];
225
225
  }
226
- function B(t, e, n) {
226
+ function ie(t, e, n) {
227
227
  let o = n;
228
228
  return o < 0 && (o += 1), o > 1 && (o -= 1), o < 1 / 6 ? t + (e - t) * 6 * o : o < 1 / 2 ? e : o < 2 / 3 ? t + (e - t) * (2 / 3 - o) * 6 : t;
229
229
  }
230
- function V(t) {
230
+ function ue(t) {
231
231
  return Math.max(0, Math.min(1, t));
232
232
  }
233
- const Ae = "product-agent:sdk-preview-socket-connect", Me = "product-agent:sdk-preview-socket-send", Oe = "product-agent:sdk-preview-socket-close", $e = "product-agent:sdk-preview-socket-open", De = "product-agent:sdk-preview-socket-message", Fe = "product-agent:sdk-preview-socket-error", Re = "product-agent:sdk-preview-socket-closed", te = "product-agent:sdk-preview-socket-id", Ge = "product-agent:preview-diagnostic", T = {
233
+ const yt = "product-agent:sdk-preview-socket-connect", vt = "product-agent:sdk-preview-socket-send", Ct = "product-agent:sdk-preview-socket-close", Et = "product-agent:sdk-preview-socket-open", kt = "product-agent:sdk-preview-socket-message", St = "product-agent:sdk-preview-socket-error", Lt = "product-agent:sdk-preview-socket-closed", Ee = "product-agent:sdk-preview-socket-id", Pt = "product-agent:preview-diagnostic", ee = 10, At = 10 * 1024 * 1024, Tt = /* @__PURE__ */ new Set(["image/png", "image/jpeg", "image/webp", "image/gif", "application/pdf"]), D = {
234
234
  launcherLabel: "Ask for anything...",
235
235
  accentColor: "#7c3aed",
236
236
  colorScheme: "light",
237
237
  fontFamily: '-apple-system, BlinkMacSystemFont, "Segoe UI", system-ui, "Helvetica Neue", sans-serif',
238
238
  scribbleStyle: !1,
239
- position: "bottom-right"
240
- }, ne = 'data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 104 36"><g><ellipse cx="17.5" cy="24.5" rx="2.4" ry="3" fill="none" stroke="%232c2a1e" stroke-width="1.6" opacity="0.8"/><path d="M18.5 27 C20.5 12, 7.5 2.5, 6 18.5" fill="none" stroke="%232c2a1e" stroke-width="2.5" stroke-linecap="round"/></g><g transform="translate(26 0)"><ellipse cx="17.9" cy="24.1" rx="2.5" ry="2.8" fill="none" stroke="%232c2a1e" stroke-width="1.5" opacity="0.8"/><path d="M18.9 26.4 C21.2 13, 8.6 3.6, 6.9 17.4" fill="none" stroke="%232c2a1e" stroke-width="2.35" stroke-linecap="round"/></g><g transform="translate(52 0)"><ellipse cx="17.1" cy="24.9" rx="2.2" ry="3.1" fill="none" stroke="%232c2a1e" stroke-width="1.7" opacity="0.8"/><path d="M18.1 27.5 C19.9 10.4, 6.4 2, 5.6 19.2" fill="none" stroke="%232c2a1e" stroke-width="2.6" stroke-linecap="round"/></g><g transform="translate(78 0)"><ellipse cx="17.6" cy="24.4" rx="2.4" ry="2.9" fill="none" stroke="%232c2a1e" stroke-width="1.6" opacity="0.8"/><path d="M18.7 26.8 C21 11.2, 7.1 1.6, 6.3 18.1" fill="none" stroke="%232c2a1e" stroke-width="2.45" stroke-linecap="round"/></g></svg>', ze = '"Architects Daughter", "Bradley Hand", "Chalkboard SE", "Comic Sans MS", "Comic Sans", "Segoe Print", cursive', oe = "pluno-pa-scribble-font";
241
- function Be(t) {
242
- return (e) => new C(e, t);
239
+ position: "bottom-right",
240
+ movableLauncher: !1
241
+ }, ke = 'data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 104 36"><g><ellipse cx="17.5" cy="24.5" rx="2.4" ry="3" fill="none" stroke="%232c2a1e" stroke-width="1.6" opacity="0.8"/><path d="M18.5 27 C20.5 12, 7.5 2.5, 6 18.5" fill="none" stroke="%232c2a1e" stroke-width="2.5" stroke-linecap="round"/></g><g transform="translate(26 0)"><ellipse cx="17.9" cy="24.1" rx="2.5" ry="2.8" fill="none" stroke="%232c2a1e" stroke-width="1.5" opacity="0.8"/><path d="M18.9 26.4 C21.2 13, 8.6 3.6, 6.9 17.4" fill="none" stroke="%232c2a1e" stroke-width="2.35" stroke-linecap="round"/></g><g transform="translate(52 0)"><ellipse cx="17.1" cy="24.9" rx="2.2" ry="3.1" fill="none" stroke="%232c2a1e" stroke-width="1.7" opacity="0.8"/><path d="M18.1 27.5 C19.9 10.4, 6.4 2, 5.6 19.2" fill="none" stroke="%232c2a1e" stroke-width="2.6" stroke-linecap="round"/></g><g transform="translate(78 0)"><ellipse cx="17.6" cy="24.4" rx="2.4" ry="2.9" fill="none" stroke="%232c2a1e" stroke-width="1.6" opacity="0.8"/><path d="M18.7 26.8 C21 11.2, 7.1 1.6, 6.3 18.1" fill="none" stroke="%232c2a1e" stroke-width="2.45" stroke-linecap="round"/></g></svg>', Nt = '"Architects Daughter", "Bradley Hand", "Chalkboard SE", "Comic Sans MS", "Comic Sans", "Segoe Print", cursive', Se = "pluno-pa-scribble-font", Ke = 190, je = 41, It = 48, Rt = 420, Dt = 680, S = 8, Le = 50, Mt = "http://www.w3.org/2000/svg", Ot = 11, Ft = 13, Gt = 4, Bt = 10, $t = 40, zt = "movable-launcher-position-v2";
242
+ function Wt(t) {
243
+ return (e) => new I(e, t);
243
244
  }
244
- async function Ue(t = {}) {
245
+ async function Ut(t = {}) {
245
246
  const e = {
246
- launcherLabel: t.launcherLabel ?? T.launcherLabel,
247
- accentColor: t.accentColor ?? T.accentColor,
248
- colorScheme: t.colorScheme ?? T.colorScheme,
249
- fontFamily: t.fontFamily ?? T.fontFamily,
250
- scribbleStyle: t.scribbleStyle ?? T.scribbleStyle,
251
- position: t.position ?? T.position,
247
+ launcherLabel: t.launcherLabel ?? D.launcherLabel,
248
+ accentColor: t.accentColor ?? D.accentColor,
249
+ colorScheme: t.colorScheme ?? D.colorScheme,
250
+ fontFamily: t.fontFamily ?? D.fontFamily,
251
+ scribbleStyle: t.scribbleStyle ?? D.scribbleStyle,
252
+ position: t.position ?? D.position,
253
+ movableLauncher: t.movableLauncher ?? D.movableLauncher,
252
254
  token: t.token,
253
255
  tokenProvider: t.tokenProvider,
254
256
  tokenEndpoint: t.tokenEndpoint,
255
257
  backendUrl: t.backendUrl,
256
258
  metadata: t.metadata,
257
259
  initialStarterPrompts: t.initialStarterPrompts,
258
- webSocketFactory: t.webSocketFactory
260
+ webSocketFactory: t.webSocketFactory,
261
+ loginRequired: t.loginRequired === !0,
262
+ loginButtonLabel: t.loginButtonLabel ?? "Log in to Pluno",
263
+ onLoginClick: t.onLoginClick
259
264
  };
260
- I("web-sdk.widget", "Mounting widget with merged options", {
265
+ O("web-sdk.widget", "Mounting widget with merged options", {
261
266
  accentColor: e.accentColor,
262
267
  colorScheme: e.colorScheme,
263
268
  fontFamily: e.fontFamily,
@@ -272,228 +277,291 @@ async function Ue(t = {}) {
272
277
  n.className = "pluno-pa-widget-host";
273
278
  const o = n.attachShadow({ mode: "open" }), a = document.createElement("div");
274
279
  a.className = `pluno-pa-widget pluno-pa-widget--${e.position}`;
275
- let r = ae(e.accentColor, e.scribbleStyle);
276
- a.innerHTML = `
277
- <svg class="pluno-pa-widget__scribble-defs" aria-hidden="true" focusable="false" width="0" height="0">
278
- <defs>
279
- <filter id="pluno-pa-scribble-wobble" x="-8%" y="-8%" width="116%" height="116%">
280
- <feTurbulence type="fractalNoise" baseFrequency="0.012 0.028" numOctaves="3" seed="2" result="stroke-noise" />
281
- <feDisplacementMap in="SourceGraphic" in2="stroke-noise" scale="3.5" xChannelSelector="R" yChannelSelector="G" result="warped" />
282
- <feTurbulence type="fractalNoise" baseFrequency="0.7" numOctaves="1" seed="12" result="ink-noise" />
283
- <feDisplacementMap in="warped" in2="ink-noise" scale="0.9" xChannelSelector="R" yChannelSelector="G" />
284
- </filter>
285
- <filter id="pluno-pa-scribble-wobble-2" x="-8%" y="-8%" width="116%" height="116%">
286
- <feTurbulence type="fractalNoise" baseFrequency="0.012 0.028" numOctaves="3" seed="5" result="stroke-noise" />
287
- <feDisplacementMap in="SourceGraphic" in2="stroke-noise" scale="3.5" xChannelSelector="R" yChannelSelector="G" result="warped" />
288
- <feTurbulence type="fractalNoise" baseFrequency="0.7" numOctaves="1" seed="15" result="ink-noise" />
289
- <feDisplacementMap in="warped" in2="ink-noise" scale="0.9" xChannelSelector="R" yChannelSelector="G" />
290
- </filter>
291
- <filter id="pluno-pa-scribble-wobble-3" x="-8%" y="-8%" width="116%" height="116%">
292
- <feTurbulence type="fractalNoise" baseFrequency="0.012 0.028" numOctaves="3" seed="9" result="stroke-noise" />
293
- <feDisplacementMap in="SourceGraphic" in2="stroke-noise" scale="3.5" xChannelSelector="R" yChannelSelector="G" result="warped" />
294
- <feTurbulence type="fractalNoise" baseFrequency="0.7" numOctaves="1" seed="19" result="ink-noise" />
295
- <feDisplacementMap in="warped" in2="ink-noise" scale="0.9" xChannelSelector="R" yChannelSelector="G" />
296
- </filter>
297
- </defs>
298
- </svg>
299
- <form class="pluno-pa-widget__launcher">
300
- <img class="pluno-pa-widget__character pluno-pa-widget__character--launcher" src="${D(r)}" alt="" aria-hidden="true" />
301
- <input class="pluno-pa-widget__launcher-input" type="text" placeholder="${D(e.launcherLabel)}" aria-label="${D(e.launcherLabel)}" />
302
- </form>
303
- <button type="button" class="pluno-pa-widget__close" aria-label="Close" hidden>
304
- <svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" stroke-width="2.25" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
305
- <path d="m6 9 6 6 6-6" />
306
- </svg>
307
- </button>
308
- <section class="pluno-pa-widget__panel" hidden>
309
- <div class="pluno-pa-widget__timeline-wrap">
310
- <main class="pluno-pa-widget__timeline">
311
- <div class="pluno-pa-widget__empty-state">
312
- <img class="pluno-pa-widget__character pluno-pa-widget__character--empty" src="${D(r)}" alt="" aria-hidden="true" />
313
- <div class="pluno-pa-widget__empty">Hey there, I'm Pluno 👋<br />What do you want to do today?</div>
314
- </div>
315
- </main>
316
- <button type="button" class="pluno-pa-widget__new-chat" aria-label="New chat" title="New chat" hidden>
317
- <svg viewBox="0 0 24 24" width="17" height="17" fill="none" stroke="currentColor" stroke-width="2.25" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
318
- <path d="M12 3H5a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7" />
319
- <path d="M18.4 2.6a2.1 2.1 0 0 1 3 3L12 15l-4 1 1-4Z" />
320
- </svg>
321
- </button>
322
- </div>
323
- <form class="pluno-pa-widget__composer">
324
- <div class="pluno-pa-widget__composer-inner">
325
- <textarea class="pluno-pa-widget__input" rows="1" placeholder="Ask for anything..."></textarea>
326
- <button type="button" class="pluno-pa-widget__send" aria-label="Send">
327
- <svg viewBox="0 0 24 24" width="14" height="14" fill="none" stroke="currentColor" stroke-width="2.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
328
- <line x1="12" y1="19" x2="12" y2="5" />
329
- <polyline points="5 12 12 5 19 12" />
330
- </svg>
331
- </button>
332
- </div>
333
- <a class="pluno-pa-widget__powered-by" href="https://pluno.ai" target="_blank" rel="noopener noreferrer">Powered by Pluno.ai</a>
334
- </form>
335
- </section>
336
- `, o.appendChild(a);
337
- const i = await Ye(), d = i.ownerDocument;
338
- i.appendChild(n), a.classList.add(`pluno-pa-widget--${e.colorScheme}`), ue(o, e.accentColor), re(a, r, {
280
+ let r = Pe(e.accentColor, e.scribbleStyle);
281
+ Zt(a, e.launcherLabel, r, e.movableLauncher), o.appendChild(a);
282
+ const l = await kn(), d = l.ownerDocument;
283
+ l.appendChild(n), a.classList.add(`pluno-pa-widget--${e.colorScheme}`), We(o, e.accentColor), Ae(a, r, {
339
284
  accentColor: e.accentColor,
340
285
  colorScheme: e.colorScheme,
341
286
  fontFamily: e.fontFamily,
342
287
  scribbleStyle: e.scribbleStyle
343
- }), I("web-sdk.widget", "Applied initial widget appearance", {
288
+ }), O("web-sdk.widget", "Applied initial widget appearance", {
344
289
  accentColor: e.accentColor,
345
290
  colorScheme: e.colorScheme,
346
291
  fontFamily: e.fontFamily,
347
292
  cssAccent: a.style.getPropertyValue("--pluno-pa-accent")
348
293
  });
349
- const u = a.querySelector(".pluno-pa-widget__launcher"), p = a.querySelector(".pluno-pa-widget__launcher-input"), g = a.querySelector(".pluno-pa-widget__panel"), f = a.querySelector(".pluno-pa-widget__close"), x = a.querySelector(".pluno-pa-widget__composer"), s = a.querySelector(".pluno-pa-widget__input"), _ = a.querySelector(".pluno-pa-widget__send"), c = a.querySelector(".pluno-pa-widget__new-chat"), b = a.querySelector(".pluno-pa-widget__timeline");
350
- if (!u || !p || !g || !f || !x || !s || !_ || !c || !b)
351
- throw new Error("Failed to mount Product Agent widget");
352
- ie(p), ie(s);
353
- const y = e.token || e.webSocketFactory ? void 0 : e.tokenProvider ?? (async () => {
294
+ const u = a.querySelector(".pluno-pa-widget__launcher"), h = a.querySelector(".pluno-pa-widget__launcher-drag-handle"), c = a.querySelector(".pluno-pa-widget__launcher-input"), m = a.querySelector(".pluno-pa-widget__panel"), y = a.querySelector(".pluno-pa-widget__close"), k = a.querySelector(".pluno-pa-widget__composer"), v = a.querySelector(".pluno-pa-widget__attachment-error"), s = a.querySelector(".pluno-pa-widget__attachments"), p = a.querySelector(".pluno-pa-widget__input"), f = a.querySelector(".pluno-pa-widget__send"), w = a.querySelector(".pluno-pa-widget__new-chat"), b = a.querySelector(".pluno-pa-widget__timeline");
295
+ if (!u || !c || !m || !y || !k || !v || !s || !p || !f || !w || !b)
296
+ throw new Error("Failed to mount Pluno widget");
297
+ if (e.movableLauncher && !h)
298
+ throw new Error("Failed to mount Pluno widget drag handle");
299
+ De(c), De(p);
300
+ let x = [], P = null;
301
+ const F = () => {
302
+ sn(s, x, (i) => {
303
+ x = x.filter((g, E) => E !== i), F(), N();
304
+ });
305
+ }, ot = e.loginRequired || e.token || e.webSocketFactory ? void 0 : e.tokenProvider ?? (async () => {
354
306
  if (!e.tokenEndpoint)
355
- throw new Error("Product Agent widget requires token or tokenEndpoint");
356
- const l = await fetch(e.tokenEndpoint, {
307
+ throw new Error("Pluno widget requires token or tokenEndpoint");
308
+ const i = await fetch(e.tokenEndpoint, {
357
309
  method: "POST",
358
310
  credentials: "include",
359
311
  headers: { "content-type": "application/json" },
360
312
  body: JSON.stringify({ origin: location.origin, url: location.href })
361
313
  });
362
- if (!l.ok)
363
- throw new Error("Failed to load Product Agent token");
364
- const k = await l.json();
365
- if (!k.token)
366
- throw new Error("Product Agent token endpoint did not return a token");
367
- return k.token;
314
+ if (!i.ok)
315
+ throw new Error("Failed to load Pluno token");
316
+ const g = await i.json();
317
+ if (!g.token)
318
+ throw new Error("Pluno token endpoint did not return a token");
319
+ return g.token;
368
320
  });
369
- let h;
370
- h = await ye.init({
321
+ let C;
322
+ C = await dt.init({
371
323
  token: e.token,
372
- tokenProvider: y,
324
+ tokenProvider: ot,
373
325
  backendUrl: e.backendUrl,
374
326
  metadata: () => ({
375
327
  ...e.metadata ?? {},
376
- ...!h.getState().sessionId && e.scribbleStyle ? { scribbleStyleStarted: !0 } : {}
328
+ ...!C.getState().sessionId && e.scribbleStyle ? { scribbleStyleStarted: !0 } : {}
377
329
  }),
378
330
  initialStarterPrompts: e.initialStarterPrompts,
379
- webSocketFactory: e.webSocketFactory
331
+ webSocketFactory: e.webSocketFactory,
332
+ autoConnect: e.loginRequired ? !1 : void 0
380
333
  });
381
- const w = Ze(e), m = new Set(w.openToolGroupKeys);
382
- let S = null, j = !1;
383
- const _e = () => {
384
- j || typeof document > "u" || (ue(o, e.accentColor), n.isConnected || d.body?.appendChild(n));
385
- }, q = new MutationObserver(_e);
386
- q.observe(d.documentElement, { childList: !0, subtree: !0 });
387
- const E = () => {
388
- Xe(e, {
334
+ const z = Sn(e), K = new Set(z.openToolGroupKeys);
335
+ let A = e.movableLauncher ? z.launcherPosition : null, he = A !== null, R = null, fe = !1;
336
+ const at = () => {
337
+ fe || typeof document > "u" || (We(o, e.accentColor), n.isConnected || d.body?.appendChild(n));
338
+ }, me = new MutationObserver(at);
339
+ me.observe(d.documentElement, { childList: !0, subtree: !0 });
340
+ const ne = (i = !0) => {
341
+ const g = Te(a, i);
342
+ return Ne(
343
+ a,
344
+ A ?? Kt(a, e.position, g),
345
+ g
346
+ );
347
+ }, T = () => {
348
+ Ln(e, {
389
349
  isOpen: a.classList.contains("pluno-pa-widget--open"),
390
- composerValue: s.value,
391
- openToolGroupKeys: [...m]
350
+ composerValue: p.value,
351
+ openToolGroupKeys: [...K],
352
+ launcherPosition: he ? A : null
353
+ });
354
+ }, M = (i, g = {}) => {
355
+ Xt(i, {
356
+ debugVersion: zt,
357
+ launcherPosition: A,
358
+ rootClasses: a.className,
359
+ rootStyle: {
360
+ left: a.style.left,
361
+ top: a.style.top,
362
+ right: a.style.right,
363
+ bottom: a.style.bottom
364
+ },
365
+ rootRect: le(a),
366
+ launcherRect: le(u),
367
+ panelRect: le(m),
368
+ viewport: B(),
369
+ panelHidden: m.hidden,
370
+ closeHidden: y.hidden,
371
+ ...g
392
372
  });
393
- }, P = (l = "", k = !0) => {
394
- if (S !== null && (window.clearTimeout(S), S = null), g.hidden = !1, f.hidden = !1, a.classList.remove("pluno-pa-widget--closing"), !k) {
395
- a.classList.add("pluno-pa-widget--open"), u.hidden = !0, l && (s.value = l, A(s)), b.scrollTop = b.scrollHeight, s.focus(), s.setSelectionRange(s.value.length, s.value.length), E();
373
+ }, j = (i = !0) => {
374
+ if (!A)
375
+ return X(a, null), ne(i);
376
+ const g = ne(i);
377
+ return X(a, g), M("Applied stored closed launcher position", { visibleLauncherPosition: g }), g;
378
+ }, be = (i, g) => {
379
+ if (!i || !g) {
380
+ Re(a);
381
+ return;
382
+ }
383
+ Yt(a, {
384
+ x: i.x - g.x,
385
+ y: i.y - g.y
386
+ });
387
+ }, we = () => {
388
+ const i = j();
389
+ if (a.classList.contains("pluno-pa-widget--open") || a.classList.contains("pluno-pa-widget--closing")) {
390
+ const g = Ie(i);
391
+ be(g, i), M("Applied open panel position after viewport resize", { openPanelPosition: g });
392
+ } else A && M("Applied visible launcher position after viewport resize", { visibleLauncherPosition: i });
393
+ };
394
+ let _e = () => {
395
+ };
396
+ e.movableLauncher && h ? (j(), window.addEventListener("resize", we), _e = Vt({
397
+ root: a,
398
+ launcherDragHandle: h,
399
+ getPosition: () => ne(),
400
+ setPosition: (i) => {
401
+ const g = i;
402
+ A = Ne(a, i, Te(a)), X(a, A), M("Dragging closed launcher", { requestedPosition: g });
403
+ },
404
+ persist: () => {
405
+ he = !0, T(), M("Persisted closed launcher drag position");
406
+ }
407
+ })) : X(a, null);
408
+ const W = (i = "", g = !0) => {
409
+ if (R !== null && (window.clearTimeout(R), R = null), m.hidden = !1, y.hidden = !1, a.classList.remove("pluno-pa-widget--closing"), e.movableLauncher) {
410
+ const E = j(), H = Ie(E);
411
+ be(H, E), M("Opening launcher at clamped open panel position", { openPanelPosition: H, visibleLauncherPosition: E });
412
+ } else
413
+ Re(a);
414
+ if (!g) {
415
+ a.classList.add("pluno-pa-widget--open"), u.hidden = !0, i && (p.value = i, V(p)), b.scrollTop = b.scrollHeight, p.focus(), p.setSelectionRange(p.value.length, p.value.length), T();
396
416
  return;
397
417
  }
398
418
  window.requestAnimationFrame(() => {
399
- a.classList.add("pluno-pa-widget--open"), l && (s.value = l, A(s)), b.scrollTop = b.scrollHeight, s.focus(), s.setSelectionRange(s.value.length, s.value.length), E(), S = window.setTimeout(() => {
419
+ a.classList.add("pluno-pa-widget--open"), i && (p.value = i, V(p)), b.scrollTop = b.scrollHeight, p.focus(), p.setSelectionRange(p.value.length, p.value.length), T(), R = window.setTimeout(() => {
400
420
  u.hidden = !0, b.scrollTop = b.scrollHeight;
401
421
  }, 220);
402
422
  });
403
- }, xe = () => {
404
- S !== null && (window.clearTimeout(S), S = null), u.hidden = !1, a.classList.add("pluno-pa-widget--closing"), a.classList.remove("pluno-pa-widget--open"), E(), S = window.setTimeout(() => {
405
- g.hidden = !0, f.hidden = !0, a.classList.remove("pluno-pa-widget--closing");
423
+ }, rt = () => {
424
+ R !== null && (window.clearTimeout(R), R = null), u.hidden = !1, A && (j(!1), M("Closing launcher at stored position")), a.classList.remove("pluno-pa-widget--open"), a.classList.add("pluno-pa-widget--closing"), T(), R = window.setTimeout(() => {
425
+ m.hidden = !0, y.hidden = !0, a.classList.remove("pluno-pa-widget--closing");
406
426
  }, 220);
407
427
  };
408
- u.addEventListener("submit", (l) => {
409
- l.preventDefault(), P(p.value), p.value = "";
410
- }), u.addEventListener("click", (l) => {
411
- l.target !== p && (P(p.value), p.value = "");
412
- }), p.addEventListener("focus", () => {
413
- P(p.value), p.value = "";
414
- }), p.addEventListener("input", () => {
415
- if (!p.value)
428
+ u.addEventListener("submit", (i) => {
429
+ i.preventDefault(), W(c.value), c.value = "";
430
+ }), h?.addEventListener("click", (i) => {
431
+ i.preventDefault(), i.stopPropagation();
432
+ }), u.addEventListener("click", (i) => {
433
+ i.target !== c && (W(c.value), c.value = "");
434
+ }), c.addEventListener("focus", () => {
435
+ W(c.value), c.value = "";
436
+ }), c.addEventListener("input", () => {
437
+ if (!c.value)
416
438
  return;
417
- const l = p.value;
418
- P(l), p.value = "";
419
- }), f.addEventListener("click", xe);
420
- const L = () => {
421
- _.disabled = !h.getState().isThinking && s.value.trim().length === 0;
439
+ const i = c.value;
440
+ W(i), c.value = "";
441
+ }), y.addEventListener("click", rt);
442
+ const N = () => {
443
+ f.disabled = !C.getState().isThinking && p.value.trim().length === 0 && x.length === 0;
422
444
  };
423
- x.addEventListener("submit", (l) => {
424
- l.preventDefault(), U(h, s), L();
425
- }), _.addEventListener("click", () => {
426
- if (h.getState().isThinking) {
427
- h.stop();
445
+ e.loginRequired && (c.readOnly = !0, c.placeholder = e.loginButtonLabel, p.placeholder = e.loginButtonLabel, k.hidden = !0), k.addEventListener("submit", (i) => {
446
+ if (i.preventDefault(), e.loginRequired) {
447
+ e.onLoginClick?.();
428
448
  return;
429
449
  }
430
- U(h, s), L();
431
- }), c.addEventListener("click", () => {
432
- h.startNewSession(), m.clear(), s.value = "", A(s), E(), L(), s.focus();
433
- }), s.addEventListener("input", () => {
434
- A(s), E(), L();
435
- }), s.addEventListener("keydown", (l) => {
436
- l.key !== "Enter" || l.shiftKey || (l.preventDefault(), U(h, s), L());
437
- }), a.addEventListener("click", (l) => {
438
- (l.target instanceof Element ? l.target : null)?.closest("a[href]") && E();
439
- }), w.composerValue && (s.value = w.composerValue, A(s)), w.isOpen && P(s.value, !1);
450
+ x = pe(C, p, x), F(), N();
451
+ });
452
+ let U = 0;
453
+ const it = () => {
454
+ U = 0, a.classList.remove("pluno-pa-widget--drag-over");
455
+ }, lt = (i) => {
456
+ P !== null && window.clearTimeout(P), v.textContent = i, v.hidden = !1, P = window.setTimeout(() => {
457
+ v.textContent = "", v.hidden = !0, P = null;
458
+ }, 3e3);
459
+ }, pt = () => {
460
+ P !== null && (window.clearTimeout(P), P = null), v.textContent = "", v.hidden = !0;
461
+ }, st = async (i) => {
462
+ if (i.length === 0)
463
+ return;
464
+ const g = await gn(i);
465
+ if (x.length + g.length > ee)
466
+ throw new Error(`Attach up to ${ee} files per message.`);
467
+ x = [...x, ...g], F(), pt(), N();
468
+ };
469
+ a.addEventListener("dragenter", (i) => {
470
+ !Z(i.dataTransfer) || e.loginRequired || (i.preventDefault(), i.stopPropagation(), U += 1, a.classList.add("pluno-pa-widget--drag-over"));
471
+ }), a.addEventListener("dragover", (i) => {
472
+ const g = i.dataTransfer;
473
+ !Z(g) || e.loginRequired || (i.preventDefault(), i.stopPropagation(), g.dropEffect = "copy");
474
+ }), a.addEventListener("dragleave", (i) => {
475
+ Z(i.dataTransfer) && (i.stopPropagation(), U = Math.max(0, U - 1), U === 0 && a.classList.remove("pluno-pa-widget--drag-over"));
476
+ }), a.addEventListener("drop", (i) => {
477
+ const g = i.dataTransfer;
478
+ !Z(g) || e.loginRequired || (i.preventDefault(), i.stopPropagation(), it(), st(g.files).catch((E) => {
479
+ lt(E instanceof Error ? E.message : "Failed to attach file"), O("web-sdk.widget", "Attachment failed", {
480
+ message: E instanceof Error ? E.message : String(E)
481
+ });
482
+ }));
483
+ }), f.addEventListener("click", () => {
484
+ if (e.loginRequired) {
485
+ e.onLoginClick?.();
486
+ return;
487
+ }
488
+ if (C.getState().isThinking) {
489
+ C.stop();
490
+ return;
491
+ }
492
+ x = pe(C, p, x), F(), N();
493
+ }), w.addEventListener("click", () => {
494
+ C.startNewSession(), K.clear(), p.value = "", x = [], F(), V(p), T(), N(), p.focus();
495
+ }), p.addEventListener("input", () => {
496
+ V(p), T(), N();
497
+ }), p.addEventListener("keydown", (i) => {
498
+ if (!(i.key !== "Enter" || i.shiftKey)) {
499
+ if (i.preventDefault(), e.loginRequired) {
500
+ e.onLoginClick?.();
501
+ return;
502
+ }
503
+ x = pe(C, p, x), F(), N();
504
+ }
505
+ }), a.addEventListener("click", (i) => {
506
+ (i.target instanceof Element ? i.target : null)?.closest("a[href]") && T();
507
+ }), z.composerValue && (p.value = z.composerValue, V(p)), z.isOpen && W(p.value, !1);
440
508
  const Y = () => r;
441
- let R = h.getState().appearance !== null;
442
- return h.on("state", (l) => {
443
- l.appearance ? (R = !0, I("web-sdk.widget", "Agent state supplied appearance", {
444
- appearance: l.appearance
445
- }), G(l.appearance, "agent.state.appearance")) : R && (R = !1, I("web-sdk.widget", "Agent state cleared appearance; reverting to configured widget options", {
509
+ let oe = C.getState().appearance !== null;
510
+ return C.on("state", (i) => {
511
+ i.appearance ? (oe = !0, O("web-sdk.widget", "Agent state supplied appearance", {
512
+ appearance: i.appearance
513
+ }), ae(i.appearance, "agent.state.appearance")) : oe && (oe = !1, O("web-sdk.widget", "Agent state cleared appearance; reverting to configured widget options", {
446
514
  fallbackAccentColor: e.accentColor,
447
515
  fallbackColorScheme: e.colorScheme,
448
516
  fallbackFontFamily: e.fontFamily
449
- }), G({}, "agent.state.appearance-cleared")), le(b, _, c, l, m, E, Y, (k) => {
450
- h.sendMessage(k);
451
- }), L();
452
- }), le(b, _, c, h.getState(), m, E, Y, (l) => {
453
- h.sendMessage(l);
454
- }), L(), {
455
- agent: h,
456
- updateAppearance: (l) => {
457
- l.scribbleStyle !== void 0 && (e.scribbleStyle = l.scribbleStyle), G(l, "widgetHandle.updateAppearance");
517
+ }), ae({}, "agent.state.appearance-cleared")), e.loginRequired ? Fe(b, f, w, Y, e.loginButtonLabel, e.onLoginClick) : Oe(b, f, w, i, K, T, Y, (g) => {
518
+ C.sendMessage(g);
519
+ }), N();
520
+ }), e.loginRequired ? Fe(b, f, w, Y, e.loginButtonLabel, e.onLoginClick) : Oe(b, f, w, C.getState(), K, T, Y, (i) => {
521
+ C.sendMessage(i);
522
+ }), N(), {
523
+ agent: C,
524
+ updateAppearance: (i) => {
525
+ i.scribbleStyle !== void 0 && (e.scribbleStyle = i.scribbleStyle), ae(i, "widgetHandle.updateAppearance");
458
526
  },
459
527
  destroy: () => {
460
- j = !0, q.disconnect(), h.destroy(), n.remove();
528
+ fe = !0, me.disconnect(), e.movableLauncher && window.removeEventListener("resize", we), _e(), P !== null && window.clearTimeout(P), C.destroy(), n.remove();
461
529
  }
462
530
  };
463
- function G(l, k) {
464
- const O = l.accentColor ?? e.accentColor, Z = l.colorScheme ?? e.colorScheme, X = l.fontFamily ?? e.fontFamily, z = l.scribbleStyle ?? e.scribbleStyle;
465
- r = ae(O, z), re(a, r, {
466
- accentColor: O,
467
- colorScheme: Z,
468
- fontFamily: X,
469
- scribbleStyle: z
470
- }), I("web-sdk.widget", "Updated widget appearance", {
471
- source: k,
472
- inputAppearance: l,
473
- appliedAccentColor: O,
474
- appliedColorScheme: Z,
475
- appliedFontFamily: X,
476
- appliedScribbleStyle: z,
531
+ function ae(i, g) {
532
+ const E = i.accentColor ?? e.accentColor, H = i.colorScheme ?? e.colorScheme, xe = i.fontFamily ?? e.fontFamily, re = i.scribbleStyle ?? e.scribbleStyle;
533
+ r = Pe(E, re), Ae(a, r, {
534
+ accentColor: E,
535
+ colorScheme: H,
536
+ fontFamily: xe,
537
+ scribbleStyle: re
538
+ }), O("web-sdk.widget", "Updated widget appearance", {
539
+ source: g,
540
+ inputAppearance: i,
541
+ appliedAccentColor: E,
542
+ appliedColorScheme: H,
543
+ appliedFontFamily: xe,
544
+ appliedScribbleStyle: re,
477
545
  cssAccent: a.style.getPropertyValue("--pluno-pa-accent")
478
546
  });
479
547
  }
480
548
  }
481
- function ae(t, e) {
482
- return e ? Ee(t) : Ce(t);
549
+ function Pe(t, e) {
550
+ return e ? ft(t) : gt(t);
483
551
  }
484
- function re(t, e, n) {
552
+ function Ae(t, e, n) {
485
553
  t.classList.toggle("pluno-pa-widget--dark", n.colorScheme === "dark"), t.classList.toggle("pluno-pa-widget--light", n.colorScheme !== "dark"), t.classList.toggle("pluno-pa-widget--scribble", n.scribbleStyle);
486
- const o = n.scribbleStyle ? he(n.accentColor) : n.accentColor;
487
- t.style.setProperty("--pluno-pa-accent", o), t.style.fontFamily = n.scribbleStyle ? ze : n.fontFamily, n.scribbleStyle && He(t.ownerDocument);
554
+ const o = n.scribbleStyle ? Ve(n.accentColor) : n.accentColor;
555
+ t.style.setProperty("--pluno-pa-accent", o), t.style.fontFamily = n.scribbleStyle ? Nt : n.fontFamily, n.scribbleStyle && Ht(t.ownerDocument);
488
556
  const a = Array.from(t.querySelectorAll(".pluno-pa-widget__character"));
489
557
  for (const r of a)
490
558
  r.src = e;
491
559
  }
492
- function He(t) {
493
- if (t.getElementById(oe))
560
+ function Ht(t) {
561
+ if (t.getElementById(Se))
494
562
  return;
495
563
  const e = t.createElement("style");
496
- e.id = oe, e.textContent = `@font-face {
564
+ e.id = Se, e.textContent = `@font-face {
497
565
  font-family: "Architects Daughter";
498
566
  font-style: normal;
499
567
  font-weight: 400;
@@ -501,7 +569,119 @@ function He(t) {
501
569
  src: url("https://fonts.gstatic.com/s/architectsdaughter/v20/KtkxAKiDZI_td1Lkx62xHZHDtgO_Y-bvTYlg4-7jA-U.woff2") format("woff2");
502
570
  }`, t.head.appendChild(e), t.fonts?.load('16px "Architects Daughter"');
503
571
  }
504
- function I(t, e, n) {
572
+ function Vt({
573
+ root: t,
574
+ launcherDragHandle: e,
575
+ getPosition: n,
576
+ setPosition: o,
577
+ persist: a
578
+ }) {
579
+ let r = null, l = null, d = null, u = !1;
580
+ const h = () => {
581
+ r = null, l = null, d = null, u = !1, t.classList.remove("pluno-pa-widget--dragging");
582
+ }, c = (s) => {
583
+ t.classList.contains("pluno-pa-widget--open") || t.classList.contains("pluno-pa-widget--closing") || (s.preventDefault(), s.stopPropagation(), r = s.pointerId, l = { x: s.clientX, y: s.clientY }, d = n(), u = !1, e.setPointerCapture?.(s.pointerId));
584
+ }, m = (s) => {
585
+ if (r !== s.pointerId || !l || !d)
586
+ return;
587
+ s.preventDefault();
588
+ const p = s.clientX - l.x, f = s.clientY - l.y;
589
+ !u && Math.hypot(p, f) < Gt || (u = !0, t.classList.add("pluno-pa-widget--dragging"), o({ x: d.x + p, y: d.y + f }));
590
+ }, y = (s) => {
591
+ r === s.pointerId && (s.preventDefault(), s.stopPropagation(), u && a(), h());
592
+ }, k = (s) => {
593
+ r === s.pointerId && (s.preventDefault(), h());
594
+ }, v = (s) => {
595
+ if (t.classList.contains("pluno-pa-widget--open") || t.classList.contains("pluno-pa-widget--closing"))
596
+ return;
597
+ const p = s.shiftKey ? $t : Bt, f = n();
598
+ let w = null;
599
+ s.key === "ArrowUp" ? w = { x: f.x, y: f.y - p } : s.key === "ArrowDown" ? w = { x: f.x, y: f.y + p } : s.key === "ArrowLeft" ? w = { x: f.x - p, y: f.y } : s.key === "ArrowRight" && (w = { x: f.x + p, y: f.y }), w && (s.preventDefault(), s.stopPropagation(), o(w), a());
600
+ };
601
+ return e.addEventListener("pointerdown", c), e.addEventListener("pointermove", m), e.addEventListener("pointerup", y), e.addEventListener("pointercancel", k), e.addEventListener("keydown", v), () => {
602
+ e.removeEventListener("pointerdown", c), e.removeEventListener("pointermove", m), e.removeEventListener("pointerup", y), e.removeEventListener("pointercancel", k), e.removeEventListener("keydown", v);
603
+ };
604
+ }
605
+ function Te(t, e = !0) {
606
+ const n = B(), o = t.getBoundingClientRect(), a = !t.classList.contains("pluno-pa-widget--open") && !t.classList.contains("pluno-pa-widget--closing");
607
+ return {
608
+ width: e && a && o.width > 0 ? o.width : Math.min(Ke, n.width - 36),
609
+ height: e && a && o.height > 0 ? o.height : t.classList.contains("pluno-pa-widget--scribble") ? It : je
610
+ };
611
+ }
612
+ function qt() {
613
+ const t = B();
614
+ return {
615
+ width: Math.min(Rt, t.width - 28),
616
+ height: Math.min(Dt, t.height - 28)
617
+ };
618
+ }
619
+ function Kt(t, e, n) {
620
+ const o = Number.parseFloat(t.style.left), a = Number.parseFloat(t.style.top);
621
+ if (Number.isFinite(o) && Number.isFinite(a))
622
+ return { x: o, y: a };
623
+ const r = t.getBoundingClientRect();
624
+ if (r.width > 0 || r.height > 0)
625
+ return { x: r.left, y: r.top };
626
+ const l = B();
627
+ return {
628
+ x: e === "bottom-left" ? 26 : l.width - 26 - n.width,
629
+ y: l.height - 24 - n.height
630
+ };
631
+ }
632
+ function Ne(t, e, n) {
633
+ const o = B(), a = S + jt(t);
634
+ return {
635
+ x: te(e.x, S, Math.max(S, o.width - n.width - S)),
636
+ y: te(e.y, a, Math.max(a, o.height - n.height - S))
637
+ };
638
+ }
639
+ function jt(t) {
640
+ return t.classList.contains("pluno-pa-widget--scribble") ? Ft : Ot;
641
+ }
642
+ function Ie(t) {
643
+ const e = B(), n = qt();
644
+ return {
645
+ x: te(t.x, S, Math.max(S, e.width - n.width - S)),
646
+ y: te(
647
+ t.y,
648
+ Le,
649
+ Math.max(Le, e.height - n.height - S)
650
+ )
651
+ };
652
+ }
653
+ function X(t, e) {
654
+ if (t.classList.toggle("pluno-pa-widget--custom-position", e !== null), !e) {
655
+ t.style.removeProperty("left"), t.style.removeProperty("top"), t.style.removeProperty("right"), t.style.removeProperty("bottom");
656
+ return;
657
+ }
658
+ t.style.left = `${e.x}px`, t.style.top = `${e.y}px`, t.style.right = "auto", t.style.bottom = "auto";
659
+ }
660
+ function Yt(t, e) {
661
+ t.style.setProperty("--pluno-pa-panel-offset-x", `${e.x}px`), t.style.setProperty("--pluno-pa-panel-offset-y", `${e.y}px`);
662
+ }
663
+ function Re(t) {
664
+ t.style.removeProperty("--pluno-pa-panel-offset-x"), t.style.removeProperty("--pluno-pa-panel-offset-y");
665
+ }
666
+ function B() {
667
+ return {
668
+ width: window.innerWidth || document.documentElement.clientWidth || Ke + S * 2,
669
+ height: window.innerHeight || document.documentElement.clientHeight || je + S * 2
670
+ };
671
+ }
672
+ function le(t) {
673
+ const e = t.getBoundingClientRect();
674
+ return {
675
+ x: Math.round(e.x),
676
+ y: Math.round(e.y),
677
+ width: Math.round(e.width),
678
+ height: Math.round(e.height)
679
+ };
680
+ }
681
+ function te(t, e, n) {
682
+ return Math.min(Math.max(t, e), n);
683
+ }
684
+ function O(t, e, n) {
505
685
  if (typeof window > "u")
506
686
  return;
507
687
  const o = window, a = {
@@ -510,136 +690,440 @@ function I(t, e, n) {
510
690
  message: e,
511
691
  details: n
512
692
  }, r = o.__plunoProductAgentDiagnostics__ ?? [];
513
- r.push(a), r.length > 120 && r.splice(0, r.length - 120), o.__plunoProductAgentDiagnostics__ = r, o.__PLUNO_PRODUCT_AGENT_DIAGNOSTICS__ = () => [...r], window.dispatchEvent(new CustomEvent(Ge, { detail: a }));
693
+ r.push(a), r.length > 120 && r.splice(0, r.length - 120), o.__plunoProductAgentDiagnostics__ = r, o.__PLUNO_PRODUCT_AGENT_DIAGNOSTICS__ = () => [...r], window.dispatchEvent(new CustomEvent(Pt, { detail: a }));
514
694
  }
515
- function U(t, e) {
516
- const n = e.value.trim();
517
- n && (e.value = "", e.style.height = "22px", e.style.overflowY = "hidden", t.sendMessage(n), e.dispatchEvent(new Event("input", { bubbles: !0 })));
695
+ function Xt(t, e) {
696
+ O("web-sdk.widget.position", t, e);
518
697
  }
519
- function A(t) {
698
+ function pe(t, e, n) {
699
+ const o = e.value.trim();
700
+ return !o && n.length === 0 ? n : (e.value = "", e.style.height = "22px", e.style.overflowY = "hidden", t.sendMessage(o, { attachments: n.length > 0 ? n : void 0 }), e.dispatchEvent(new Event("input", { bubbles: !0 })), []);
701
+ }
702
+ function V(t) {
520
703
  t.style.height = "0px";
521
704
  const e = Math.max(22, Math.min(t.scrollHeight, 140));
522
705
  t.style.height = `${e}px`, t.style.overflowY = t.scrollHeight > 140 ? "auto" : "hidden";
523
706
  }
524
- function ie(t) {
707
+ function Zt(t, e, n, o) {
708
+ t.appendChild(nn()), t.appendChild(Jt(e, n, o)), t.appendChild(Ze("pluno-pa-widget__close", "Close", on(16), !0)), t.appendChild(Qt(n));
709
+ }
710
+ function Jt(t, e, n) {
711
+ const o = document.createElement("form");
712
+ if (o.className = "pluno-pa-widget__launcher", n) {
713
+ const r = document.createElement("button");
714
+ r.type = "button", r.className = "pluno-pa-widget__launcher-drag-handle", r.setAttribute("aria-label", "Move Pluno launcher"), r.title = "Move Pluno launcher", o.appendChild(r);
715
+ }
716
+ o.appendChild(Xe("pluno-pa-widget__character--launcher", e));
717
+ const a = document.createElement("input");
718
+ return a.className = "pluno-pa-widget__launcher-input", a.type = "text", a.placeholder = t, a.setAttribute("aria-label", t), o.appendChild(a), o;
719
+ }
720
+ function Qt(t) {
721
+ const e = document.createElement("section");
722
+ e.className = "pluno-pa-widget__panel", e.hidden = !0;
723
+ const n = document.createElement("div");
724
+ n.className = "pluno-pa-widget__timeline-wrap";
725
+ const o = document.createElement("main");
726
+ return o.className = "pluno-pa-widget__timeline", o.appendChild(tn(t)), n.appendChild(o), n.appendChild(Ze("pluno-pa-widget__new-chat", "New chat", an(), !0)), e.appendChild(n), e.appendChild(en()), e;
727
+ }
728
+ function en() {
729
+ const t = document.createElement("form");
730
+ t.className = "pluno-pa-widget__composer";
731
+ const e = document.createElement("div");
732
+ e.className = "pluno-pa-widget__attachment-error", e.hidden = !0, t.appendChild(e);
733
+ const n = document.createElement("div");
734
+ n.className = "pluno-pa-widget__attachments", n.hidden = !0, t.appendChild(n);
735
+ const o = document.createElement("div");
736
+ o.className = "pluno-pa-widget__composer-inner";
737
+ const a = document.createElement("textarea");
738
+ a.className = "pluno-pa-widget__input", a.rows = 1, a.placeholder = "Ask for anything...", o.appendChild(a);
739
+ const r = document.createElement("button");
740
+ r.type = "button", r.className = "pluno-pa-widget__send", r.setAttribute("aria-label", "Send"), r.appendChild(Je()), o.appendChild(r), t.appendChild(o);
741
+ const l = document.createElement("a");
742
+ return l.className = "pluno-pa-widget__powered-by", l.href = "https://pluno.ai", l.target = "_blank", l.rel = "noopener noreferrer", l.textContent = "Powered by Pluno.ai", t.appendChild(l), t;
743
+ }
744
+ function tn(t) {
745
+ const e = document.createElement("div");
746
+ return e.className = "pluno-pa-widget__empty-state", e.appendChild(Xe("pluno-pa-widget__character--empty", t)), e.appendChild(Ye()), e;
747
+ }
748
+ function Ye() {
749
+ const t = document.createElement("div");
750
+ return t.className = "pluno-pa-widget__empty", t.appendChild(document.createTextNode("Hey there, I'm Pluno 👋")), t.appendChild(document.createElement("br")), t.appendChild(document.createTextNode("What do you want to do today?")), t;
751
+ }
752
+ function Xe(t, e) {
753
+ const n = document.createElement("img");
754
+ return n.className = `pluno-pa-widget__character ${t}`, n.src = e, n.alt = "", n.setAttribute("aria-hidden", "true"), n;
755
+ }
756
+ function Ze(t, e, n, o) {
757
+ const a = document.createElement("button");
758
+ return a.type = "button", a.className = t, a.setAttribute("aria-label", e), a.title = e, a.hidden = o, a.appendChild(n), a;
759
+ }
760
+ function nn() {
761
+ const t = _("svg", {
762
+ class: "pluno-pa-widget__scribble-defs",
763
+ "aria-hidden": "true",
764
+ focusable: "false",
765
+ width: "0",
766
+ height: "0"
767
+ }), e = _("defs");
768
+ return e.appendChild(se("pluno-pa-scribble-wobble", "2", "12")), e.appendChild(se("pluno-pa-scribble-wobble-2", "5", "15")), e.appendChild(se("pluno-pa-scribble-wobble-3", "9", "19")), t.appendChild(e), t;
769
+ }
770
+ function se(t, e, n) {
771
+ const o = _("filter", { id: t, x: "-8%", y: "-8%", width: "116%", height: "116%" });
772
+ return o.appendChild(
773
+ _("feTurbulence", {
774
+ type: "fractalNoise",
775
+ baseFrequency: "0.012 0.028",
776
+ numOctaves: "3",
777
+ seed: e,
778
+ result: "stroke-noise"
779
+ })
780
+ ), o.appendChild(
781
+ _("feDisplacementMap", {
782
+ in: "SourceGraphic",
783
+ in2: "stroke-noise",
784
+ scale: "3.5",
785
+ xChannelSelector: "R",
786
+ yChannelSelector: "G",
787
+ result: "warped"
788
+ })
789
+ ), o.appendChild(
790
+ _("feTurbulence", {
791
+ type: "fractalNoise",
792
+ baseFrequency: "0.7",
793
+ numOctaves: "1",
794
+ seed: n,
795
+ result: "ink-noise"
796
+ })
797
+ ), o.appendChild(
798
+ _("feDisplacementMap", {
799
+ in: "warped",
800
+ in2: "ink-noise",
801
+ scale: "0.9",
802
+ xChannelSelector: "R",
803
+ yChannelSelector: "G"
804
+ })
805
+ ), o;
806
+ }
807
+ function on(t) {
808
+ const e = $("0 0 24 24", t, t, "none", "currentColor", "2.25");
809
+ return e.appendChild(_("path", { d: "m6 9 6 6 6-6" })), e;
810
+ }
811
+ function an() {
812
+ const t = $("0 0 24 24", 17, 17, "none", "currentColor", "2.25");
813
+ return t.appendChild(_("path", { d: "M12 3H5a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7" })), t.appendChild(_("path", { d: "M18.4 2.6a2.1 2.1 0 0 1 3 3L12 15l-4 1 1-4Z" })), t;
814
+ }
815
+ function Je() {
816
+ const t = $("0 0 24 24", 14, 14, "none", "currentColor", "2.75");
817
+ return t.appendChild(_("line", { x1: "12", y1: "19", x2: "12", y2: "5" })), t.appendChild(_("polyline", { points: "5 12 12 5 19 12" })), t;
818
+ }
819
+ function rn() {
820
+ const t = $("0 0 24 24", 18, 18, "currentColor");
821
+ return t.appendChild(_("rect", { x: "6", y: "6", width: "12", height: "12", rx: "2" })), t;
822
+ }
823
+ function ln() {
824
+ const t = $("0 0 24 24", 12, 12, "none", "currentColor", "2.4");
825
+ return t.appendChild(_("path", { d: "M18 6 6 18" })), t.appendChild(_("path", { d: "m6 6 12 12" })), t;
826
+ }
827
+ function pn() {
828
+ const t = $("0 0 24 24", 13, 13, "none", "currentColor", "2.25");
829
+ return t.appendChild(_("rect", { width: "14", height: "14", x: "8", y: "8", rx: "2", ry: "2" })), t.appendChild(_("path", { d: "M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2" })), t;
830
+ }
831
+ function $(t, e, n, o, a, r) {
832
+ const l = {
833
+ viewBox: t,
834
+ width: String(e),
835
+ height: String(n),
836
+ fill: o,
837
+ "aria-hidden": "true"
838
+ };
839
+ return a && (l.stroke = a, l["stroke-linecap"] = "round", l["stroke-linejoin"] = "round"), r && (l["stroke-width"] = r), _("svg", l);
840
+ }
841
+ function _(t, e = {}) {
842
+ const n = document.createElementNS(Mt, t);
843
+ for (const [o, a] of Object.entries(e))
844
+ n.setAttribute(o, a);
845
+ return n;
846
+ }
847
+ function De(t) {
525
848
  for (const e of ["keydown", "keypress", "keyup"])
526
849
  t.addEventListener(e, (n) => {
527
850
  n.stopPropagation();
528
851
  });
529
852
  }
530
- function le(t, e, n, o, a, r, i, d) {
853
+ function sn(t, e, n) {
854
+ t.replaceChildren(), t.hidden = e.length === 0;
855
+ for (const [o, a] of e.entries()) {
856
+ const r = document.createElement("div");
857
+ r.className = "pluno-pa-widget__attachment", r.appendChild(dn(a));
858
+ const l = document.createElement("span");
859
+ l.textContent = a.name, r.appendChild(l);
860
+ const d = document.createElement("button");
861
+ d.type = "button", d.setAttribute("aria-label", `Remove ${a.name}`), d.appendChild(ln()), d.addEventListener("click", () => n(o)), r.appendChild(d), t.appendChild(r);
862
+ }
863
+ }
864
+ function dn(t) {
865
+ if (Qe(t)) {
866
+ const n = document.createElement("img");
867
+ return n.src = t.dataUrl, n.alt = "", n.setAttribute("aria-hidden", "true"), n;
868
+ }
869
+ const e = document.createElement("span");
870
+ return e.className = "pluno-pa-widget__attachment-file", e.textContent = "PDF", e;
871
+ }
872
+ function cn(t) {
873
+ if (Qe(t)) {
874
+ const a = document.createElement("img");
875
+ return a.src = t.dataUrl, a.alt = t.name, a;
876
+ }
877
+ const e = document.createElement("div");
878
+ e.className = "pluno-pa-widget__message-attachment-file";
879
+ const n = document.createElement("span");
880
+ n.textContent = "PDF";
881
+ const o = document.createElement("strong");
882
+ return o.textContent = t.name, e.append(n, o), e;
883
+ }
884
+ function Qe(t) {
885
+ return t.mimeType.startsWith("image/");
886
+ }
887
+ function un(t) {
888
+ return t === "application/pdf" ? "document.pdf" : "image";
889
+ }
890
+ async function gn(t) {
891
+ if (!t)
892
+ return [];
893
+ const e = Array.from(t);
894
+ if (e.length > ee)
895
+ throw new Error(`Attach up to ${ee} files per message.`);
896
+ return Promise.all(
897
+ e.map(async (n) => {
898
+ const o = hn(n);
899
+ if (!o)
900
+ throw new Error("Pluno supports PNG, JPEG, WebP, non-animated GIF, and PDF files.");
901
+ if (n.size > At)
902
+ throw new Error("Each Pluno attachment can be up to 10 MB.");
903
+ if (o === "image/gif") {
904
+ const a = new Uint8Array(await wn(n));
905
+ if (mn(a))
906
+ throw new Error("Pluno supports non-animated GIF images.");
907
+ }
908
+ return {
909
+ name: n.name || un(o),
910
+ mimeType: o,
911
+ sizeBytes: n.size,
912
+ dataUrl: fn(await _n(n), o)
913
+ };
914
+ })
915
+ );
916
+ }
917
+ function hn(t) {
918
+ if (Tt.has(t.type))
919
+ return t.type;
920
+ const e = t.name.toLowerCase();
921
+ return e.endsWith(".png") ? "image/png" : e.endsWith(".jpg") || e.endsWith(".jpeg") ? "image/jpeg" : e.endsWith(".webp") ? "image/webp" : e.endsWith(".gif") ? "image/gif" : e.endsWith(".pdf") ? "application/pdf" : null;
922
+ }
923
+ function fn(t, e) {
924
+ const n = `data:${e};base64,`;
925
+ return t.startsWith(n) ? t : t.replace(/^data:[^;]*;base64,/, n);
926
+ }
927
+ function mn(t) {
928
+ if (t.length < 14 || !bn(t))
929
+ return !1;
930
+ const e = t[10];
931
+ let n = 13;
932
+ e & 128 && (n += 3 * 2 ** ((e & 7) + 1));
933
+ let o = 0;
934
+ for (; n < t.length; ) {
935
+ const a = t[n];
936
+ if (n += 1, a === 59)
937
+ return !1;
938
+ if (a === 33) {
939
+ n += 1, n = Me(t, n);
940
+ continue;
941
+ }
942
+ if (a !== 44)
943
+ return !1;
944
+ if (o += 1, o > 1)
945
+ return !0;
946
+ if (n + 9 >= t.length)
947
+ return !1;
948
+ const r = t[n + 8];
949
+ if (n += 9, r & 128 && (n += 3 * 2 ** ((r & 7) + 1)), n >= t.length)
950
+ return !1;
951
+ n += 1, n = Me(t, n);
952
+ }
953
+ return !1;
954
+ }
955
+ function bn(t) {
956
+ return t[0] === 71 && t[1] === 73 && t[2] === 70 && t[3] === 56 && (t[4] === 55 || t[4] === 57) && t[5] === 97;
957
+ }
958
+ function Me(t, e) {
959
+ for (; e < t.length; ) {
960
+ const n = t[e];
961
+ if (e += 1, n === 0)
962
+ return e;
963
+ e += n;
964
+ }
965
+ return e;
966
+ }
967
+ function Z(t) {
968
+ return !!(t && Array.from(t.types).includes("Files"));
969
+ }
970
+ function wn(t) {
971
+ return new Promise((e, n) => {
972
+ const o = new FileReader();
973
+ o.addEventListener("load", () => {
974
+ if (o.result instanceof ArrayBuffer) {
975
+ e(o.result);
976
+ return;
977
+ }
978
+ n(new Error("Failed to read file"));
979
+ }), o.addEventListener("error", () => {
980
+ n(o.error ?? new Error("Failed to read file"));
981
+ }), o.readAsArrayBuffer(t);
982
+ });
983
+ }
984
+ function _n(t) {
985
+ return new Promise((e, n) => {
986
+ const o = new FileReader();
987
+ o.addEventListener("load", () => {
988
+ if (typeof o.result == "string") {
989
+ e(o.result);
990
+ return;
991
+ }
992
+ n(new Error("Failed to read file"));
993
+ }), o.addEventListener("error", () => {
994
+ n(o.error ?? new Error("Failed to read file"));
995
+ }), o.readAsDataURL(t);
996
+ });
997
+ }
998
+ function Oe(t, e, n, o, a, r, l, d) {
531
999
  const u = [...o.messages];
532
- t.innerHTML = "", je(e, o.isThinking);
533
- const p = u.length > 0 || !!o.assistantDraft || o.isThinking;
534
- if (n.hidden = !p, u.length === 0 && !o.assistantDraft && !o.lastError && !o.isThinking) {
535
- const c = document.createElement("div");
536
- c.className = "pluno-pa-widget__empty-state pluno-pa-widget__empty-state--starter";
537
- const b = document.createElement("img");
538
- b.className = "pluno-pa-widget__character pluno-pa-widget__character--empty", b.src = i(), b.alt = "", b.setAttribute("aria-hidden", "true"), c.appendChild(b);
539
- const y = document.createElement("div");
540
- y.className = "pluno-pa-widget__empty", y.innerHTML = "Hey there, I'm Pluno 👋<br />What do you want to do today?", c.appendChild(y);
541
- const h = document.createElement("div");
542
- h.className = o.starterPrompts.length > 0 ? "pluno-pa-widget__starter-prompts" : "pluno-pa-widget__starter-prompts pluno-pa-widget__starter-prompts--empty", o.starterPrompts.length === 0 && h.setAttribute("aria-hidden", "true");
1000
+ t.replaceChildren(), tt(e, o.isThinking);
1001
+ const h = u.length > 0 || !!o.assistantDraft || o.isThinking;
1002
+ if (n.hidden = !h, u.length === 0 && !o.assistantDraft && !o.lastError && !o.isThinking) {
1003
+ const s = document.createElement("div");
1004
+ s.className = "pluno-pa-widget__empty-state pluno-pa-widget__empty-state--starter";
1005
+ const p = document.createElement("img");
1006
+ p.className = "pluno-pa-widget__character pluno-pa-widget__character--empty", p.src = l(), p.alt = "", p.setAttribute("aria-hidden", "true"), s.appendChild(p), s.appendChild(Ye());
1007
+ const f = document.createElement("div");
1008
+ f.className = o.starterPrompts.length > 0 ? "pluno-pa-widget__starter-prompts" : "pluno-pa-widget__starter-prompts pluno-pa-widget__starter-prompts--empty", o.starterPrompts.length === 0 && f.setAttribute("aria-hidden", "true");
543
1009
  for (const w of o.starterPrompts) {
544
- const m = document.createElement("button");
545
- m.type = "button", m.className = "pluno-pa-widget__starter-prompt", m.textContent = `"${w}"`, m.addEventListener("click", () => {
1010
+ const b = document.createElement("button");
1011
+ b.type = "button", b.className = "pluno-pa-widget__starter-prompt", b.textContent = `"${w}"`, b.addEventListener("click", () => {
546
1012
  d(w);
547
- }), h.appendChild(m);
1013
+ }), f.appendChild(b);
548
1014
  }
549
- c.appendChild(h), t.appendChild(c);
1015
+ s.appendChild(f), t.appendChild(s);
550
1016
  return;
551
1017
  }
552
- let g = null, f = null, x = [];
553
- const s = () => {
554
- if (x.length === 0)
1018
+ let c = null, m = null, y = [];
1019
+ const k = () => {
1020
+ if (y.length === 0)
555
1021
  return !1;
556
- const c = We(x, a, r, i());
557
- return t.appendChild(c), g = null, f = c, x = [], !0;
1022
+ const s = yn(y, a, r, l());
1023
+ return t.appendChild(s), c = null, m = s, y = [], !0;
558
1024
  };
559
- for (let c = 0; c < u.length; c += 1) {
560
- const b = u[c];
561
- if (b.role === "tool") {
562
- x.push(b);
1025
+ for (let s = 0; s < u.length; s += 1) {
1026
+ const p = u[s];
1027
+ if (p.role === "tool") {
1028
+ y.push(p);
563
1029
  continue;
564
1030
  }
565
- if (b.role === "system")
1031
+ if (p.role === "system")
566
1032
  continue;
567
- const y = s(), h = se(b.content);
568
- if (b.role === "assistant" && !y) {
569
- const m = K(i());
570
- t.appendChild(m), g = null, f = m;
1033
+ const f = k(), w = Be(p.content);
1034
+ if (p.role === "assistant" && !f) {
1035
+ const x = ge(l());
1036
+ t.appendChild(x), c = null, m = x;
571
1037
  }
572
- const w = document.createElement("div");
573
- w.className = `pluno-pa-widget__message pluno-pa-widget__message--${b.role}`, b.role === "assistant" ? ce(w, h) : w.textContent = h, w.appendChild(pe(h)), t.appendChild(w), g = w, f = null;
1038
+ const b = document.createElement("div");
1039
+ b.className = `pluno-pa-widget__message pluno-pa-widget__message--${p.role}`, p.role === "assistant" ? ze(b, w) : b.textContent = w, p.role === "user" && p.attachments?.length && b.appendChild(xn(p.attachments)), b.appendChild(Ge(w)), t.appendChild(b), c = b, m = null;
574
1040
  }
575
- const _ = s();
1041
+ const v = k();
576
1042
  if (o.assistantDraft) {
577
- if (!_) {
578
- const y = K(i());
579
- t.appendChild(y), g = null, f = y;
1043
+ if (!v) {
1044
+ const f = ge(l());
1045
+ t.appendChild(f), c = null, m = f;
580
1046
  }
581
- const c = se(o.assistantDraft), b = document.createElement("div");
582
- b.className = "pluno-pa-widget__message pluno-pa-widget__message--assistant", ce(b, c), b.appendChild(pe(c)), t.appendChild(b), g = b, f = null;
1047
+ const s = Be(o.assistantDraft), p = document.createElement("div");
1048
+ p.className = "pluno-pa-widget__message pluno-pa-widget__message--assistant", ze(p, s), p.appendChild(Ge(s)), t.appendChild(p), c = p, m = null;
583
1049
  }
584
1050
  if (o.isThinking && !o.assistantDraft)
585
- if (_) {
586
- const c = we();
587
- t.appendChild(c), g = null, f = c;
1051
+ if (v) {
1052
+ const s = et();
1053
+ t.appendChild(s), c = null, m = s;
588
1054
  } else {
589
- const c = Ve(i());
590
- t.appendChild(c), g = null, f = c;
1055
+ const s = vn(l());
1056
+ t.appendChild(s), c = null, m = s;
591
1057
  }
592
1058
  if (o.lastError) {
593
- const c = document.createElement("div");
594
- c.className = "pluno-pa-widget__error", c.textContent = o.lastError, t.appendChild(c), g = c, f = null;
1059
+ const s = document.createElement("div");
1060
+ s.className = "pluno-pa-widget__error", s.textContent = o.lastError, t.appendChild(s), c = s, m = null;
595
1061
  }
596
- g?.classList.add("pluno-pa-widget__message--bottom-reserve"), f?.classList.add("pluno-pa-widget__bottom-reserve-compact"), t.scrollTop = t.scrollHeight;
1062
+ c?.classList.add("pluno-pa-widget__message--bottom-reserve"), m?.classList.add("pluno-pa-widget__bottom-reserve-compact"), t.scrollTop = t.scrollHeight;
597
1063
  }
598
- function pe(t) {
1064
+ function Fe(t, e, n, o, a, r) {
1065
+ t.replaceChildren(), tt(e, !1), e.disabled = !0, n.hidden = !0;
1066
+ const l = document.createElement("div");
1067
+ l.className = "pluno-pa-widget__empty-state pluno-pa-widget__empty-state--starter";
1068
+ const d = document.createElement("img");
1069
+ d.className = "pluno-pa-widget__character pluno-pa-widget__character--empty", d.src = o(), d.alt = "", d.setAttribute("aria-hidden", "true"), l.appendChild(d);
1070
+ const u = document.createElement("div");
1071
+ u.className = "pluno-pa-widget__empty", u.textContent = "Log in to use Pluno on this page.", l.appendChild(u);
1072
+ const h = document.createElement("button");
1073
+ h.type = "button", h.className = "pluno-pa-widget__login", h.textContent = a, h.addEventListener("click", () => r?.()), l.appendChild(h), t.appendChild(l);
1074
+ }
1075
+ function xn(t) {
1076
+ const e = document.createElement("div");
1077
+ e.className = "pluno-pa-widget__message-attachments";
1078
+ for (const n of t)
1079
+ e.appendChild(cn(n));
1080
+ return e;
1081
+ }
1082
+ function Ge(t) {
599
1083
  const e = document.createElement("button");
600
- return e.type = "button", e.className = "pluno-pa-widget__message-copy", e.setAttribute("aria-label", "Copy message"), e.title = "Copy message", e.innerHTML = '<svg viewBox="0 0 24 24" width="13" height="13" fill="none" stroke="currentColor" stroke-width="2.25" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><rect width="14" height="14" x="8" y="8" rx="2" ry="2"></rect><path d="M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2"></path></svg>', e.addEventListener("click", (n) => {
1084
+ return e.type = "button", e.className = "pluno-pa-widget__message-copy", e.setAttribute("aria-label", "Copy message"), e.title = "Copy message", e.appendChild(pn()), e.addEventListener("click", (n) => {
601
1085
  n.preventDefault(), n.stopPropagation(), navigator.clipboard.writeText(t);
602
1086
  }), e;
603
1087
  }
604
- function se(t) {
1088
+ function Be(t) {
605
1089
  return t.replace(/\uE200[^\uE201]*(?:\uE201|$)/g, "");
606
1090
  }
607
- function We(t, e, n, o) {
1091
+ function yn(t, e, n, o) {
608
1092
  const a = document.createElement("article");
609
1093
  a.className = "pluno-pa-widget__tool-group", a.title = new Date(t[t.length - 1].createdAt).toLocaleString();
610
1094
  const r = document.createElement("img");
611
1095
  r.className = "pluno-pa-widget__character pluno-pa-widget__character--tool-group", r.src = o, r.alt = "", r.setAttribute("aria-hidden", "true"), a.appendChild(r);
612
- const i = document.createElement("details"), d = Ke(t);
613
- i.open = e.has(d), i.addEventListener("toggle", () => {
614
- i.open ? e.add(d) : e.delete(d), n();
1096
+ const l = document.createElement("details"), d = Cn(t);
1097
+ l.open = e.has(d), l.addEventListener("toggle", () => {
1098
+ l.open ? e.add(d) : e.delete(d), n();
615
1099
  });
616
1100
  const u = document.createElement("summary");
617
- u.className = "pluno-pa-widget__tool-summary", t.some((f) => f.loading) && u.appendChild(de());
618
- const g = document.createElement("span");
619
- if (g.className = "pluno-pa-widget__tool-summary-title", g.textContent = t[t.length - 1].content || "Run tool", u.appendChild(g), i.appendChild(u), t.length > 0) {
620
- const f = document.createElement("div");
621
- f.className = "pluno-pa-widget__tool-lines";
622
- for (const x of t) {
623
- const s = document.createElement("div");
624
- s.className = "pluno-pa-widget__tool-line", x.loading && s.appendChild(de());
625
- const _ = document.createElement("span");
626
- _.textContent = x.content || "Run tool", s.appendChild(_), f.appendChild(s);
627
- }
628
- i.appendChild(f);
1101
+ u.className = "pluno-pa-widget__tool-summary", t.some((m) => m.loading) && u.appendChild($e());
1102
+ const c = document.createElement("span");
1103
+ if (c.className = "pluno-pa-widget__tool-summary-title", c.textContent = t[t.length - 1].content || "Run tool", u.appendChild(c), l.appendChild(u), t.length > 0) {
1104
+ const m = document.createElement("div");
1105
+ m.className = "pluno-pa-widget__tool-lines";
1106
+ for (const y of t) {
1107
+ const k = document.createElement("div");
1108
+ k.className = "pluno-pa-widget__tool-line", y.loading && k.appendChild($e());
1109
+ const v = document.createElement("span");
1110
+ v.textContent = y.content || "Run tool", k.appendChild(v), m.appendChild(k);
1111
+ }
1112
+ l.appendChild(m);
629
1113
  }
630
- return a.appendChild(i), a;
1114
+ return a.appendChild(l), a;
631
1115
  }
632
- function K(t) {
1116
+ function ge(t) {
633
1117
  const e = document.createElement("article");
634
1118
  e.className = "pluno-pa-widget__tool-group pluno-pa-widget__assistant-marker";
635
1119
  const n = document.createElement("img");
636
1120
  return n.className = "pluno-pa-widget__character pluno-pa-widget__character--tool-group", n.src = t, n.alt = "", n.setAttribute("aria-hidden", "true"), e.appendChild(n), e;
637
1121
  }
638
- function Ve(t) {
639
- const e = K(t);
640
- return e.classList.add("pluno-pa-widget__thinking-marker"), e.appendChild(we()), e;
1122
+ function vn(t) {
1123
+ const e = ge(t);
1124
+ return e.classList.add("pluno-pa-widget__thinking-marker"), e.appendChild(et()), e;
641
1125
  }
642
- function we() {
1126
+ function et() {
643
1127
  const t = document.createElement("div");
644
1128
  t.className = "pluno-pa-widget__status";
645
1129
  const e = document.createElement("span");
@@ -647,17 +1131,17 @@ function we() {
647
1131
  const n = document.createElement("span");
648
1132
  return n.textContent = "Thinking...", t.appendChild(n), t;
649
1133
  }
650
- function Ke(t) {
1134
+ function Cn(t) {
651
1135
  return `tools:${t.map((e) => e.id).join("|")}`;
652
1136
  }
653
- function de() {
1137
+ function $e() {
654
1138
  const t = document.createElement("span");
655
1139
  return t.className = "pluno-pa-widget__spinner", t.setAttribute("aria-hidden", "true"), t;
656
1140
  }
657
- function je(t, e) {
658
- t.setAttribute("aria-label", e ? "Stop" : "Send"), t.classList.toggle("pluno-pa-widget__send--stop", e), t.innerHTML = e ? '<svg viewBox="0 0 24 24" width="18" height="18" fill="currentColor" aria-hidden="true"><rect x="6" y="6" width="12" height="12" rx="2" /></svg>' : '<svg viewBox="0 0 24 24" width="14" height="14" fill="none" stroke="currentColor" stroke-width="2.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><line x1="12" y1="19" x2="12" y2="5" /><polyline points="5 12 12 5 19 12" /></svg>';
1141
+ function tt(t, e) {
1142
+ t.setAttribute("aria-label", e ? "Stop" : "Send"), t.classList.toggle("pluno-pa-widget__send--stop", e), t.replaceChildren(e ? rn() : Je());
659
1143
  }
660
- function ce(t, e) {
1144
+ function ze(t, e) {
661
1145
  const n = e.replace(/\r\n/g, `
662
1146
  `).split(`
663
1147
  `);
@@ -669,77 +1153,77 @@ function ce(t, e) {
669
1153
  continue;
670
1154
  }
671
1155
  if (a.match(/^```(\w+)?\s*$/)) {
672
- const p = [];
1156
+ const h = [];
673
1157
  for (o += 1; o < n.length && !/^```\s*$/.test(n[o]); )
674
- p.push(n[o]), o += 1;
1158
+ h.push(n[o]), o += 1;
675
1159
  o += o < n.length ? 1 : 0;
676
- const g = document.createElement("pre"), f = document.createElement("code");
677
- f.textContent = p.join(`
678
- `), g.appendChild(f), t.appendChild(g);
1160
+ const c = document.createElement("pre"), m = document.createElement("code");
1161
+ m.textContent = h.join(`
1162
+ `), c.appendChild(m), t.appendChild(c);
679
1163
  continue;
680
1164
  }
681
- const i = a.match(/^(#{1,3})\s+(.+)$/);
682
- if (i) {
683
- const p = document.createElement(`h${i[1].length + 2}`);
684
- $(p, i[2]), t.appendChild(p), o += 1;
1165
+ const l = a.match(/^(#{1,3})\s+(.+)$/);
1166
+ if (l) {
1167
+ const h = document.createElement(`h${l[1].length + 2}`);
1168
+ J(h, l[2]), t.appendChild(h), o += 1;
685
1169
  continue;
686
1170
  }
687
1171
  if (/^\s*[-*+]\s+/.test(a)) {
688
- const p = document.createElement("ul");
1172
+ const h = document.createElement("ul");
689
1173
  for (; o < n.length && /^\s*[-*+]\s+/.test(n[o]); ) {
690
- const g = document.createElement("li");
691
- $(g, n[o].replace(/^\s*[-*+]\s+/, "")), p.appendChild(g), o += 1;
1174
+ const c = document.createElement("li");
1175
+ J(c, n[o].replace(/^\s*[-*+]\s+/, "")), h.appendChild(c), o += 1;
692
1176
  }
693
- t.appendChild(p);
1177
+ t.appendChild(h);
694
1178
  continue;
695
1179
  }
696
1180
  if (/^\s*\d+\.\s+/.test(a)) {
697
- const p = document.createElement("ol");
1181
+ const h = document.createElement("ol");
698
1182
  for (; o < n.length && /^\s*\d+\.\s+/.test(n[o]); ) {
699
- const g = document.createElement("li");
700
- $(g, n[o].replace(/^\s*\d+\.\s+/, "")), p.appendChild(g), o += 1;
1183
+ const c = document.createElement("li");
1184
+ J(c, n[o].replace(/^\s*\d+\.\s+/, "")), h.appendChild(c), o += 1;
701
1185
  }
702
- t.appendChild(p);
1186
+ t.appendChild(h);
703
1187
  continue;
704
1188
  }
705
1189
  const d = [a];
706
1190
  for (o += 1; o < n.length && n[o].trim() && !/^```/.test(n[o]) && !/^(#{1,3})\s+/.test(n[o]) && !/^\s*[-*+]\s+/.test(n[o]) && !/^\s*\d+\.\s+/.test(n[o]); )
707
1191
  d.push(n[o]), o += 1;
708
1192
  const u = document.createElement("p");
709
- d.forEach((p, g) => {
710
- g > 0 && u.appendChild(document.createElement("br")), $(u, p);
1193
+ d.forEach((h, c) => {
1194
+ c > 0 && u.appendChild(document.createElement("br")), J(u, h);
711
1195
  }), t.appendChild(u);
712
1196
  }
713
1197
  }
714
- function $(t, e) {
1198
+ function J(t, e) {
715
1199
  const n = /(`[^`]+`|\*\*[^*]+\*\*|\*[^*]+\*|\[[^\]]+\]\(([^)\s]+)\))/g;
716
1200
  let o = 0;
717
1201
  for (const a of e.matchAll(n)) {
718
1202
  const r = a.index ?? 0;
719
1203
  r > o && t.appendChild(document.createTextNode(e.slice(o, r)));
720
- const i = a[0];
721
- if (i.startsWith("`")) {
1204
+ const l = a[0];
1205
+ if (l.startsWith("`")) {
722
1206
  const d = document.createElement("code");
723
- d.textContent = i.slice(1, -1), t.appendChild(d);
724
- } else if (i.startsWith("**")) {
1207
+ d.textContent = l.slice(1, -1), t.appendChild(d);
1208
+ } else if (l.startsWith("**")) {
725
1209
  const d = document.createElement("strong");
726
- d.textContent = i.slice(2, -2), t.appendChild(d);
727
- } else if (i.startsWith("*")) {
1210
+ d.textContent = l.slice(2, -2), t.appendChild(d);
1211
+ } else if (l.startsWith("*")) {
728
1212
  const d = document.createElement("em");
729
- d.textContent = i.slice(1, -1), t.appendChild(d);
1213
+ d.textContent = l.slice(1, -1), t.appendChild(d);
730
1214
  } else {
731
- const d = i.match(/^\[([^\]]+)\]\(([^)\s]+)\)$/);
732
- if (d && qe(d[2])) {
1215
+ const d = l.match(/^\[([^\]]+)\]\(([^)\s]+)\)$/);
1216
+ if (d && En(d[2])) {
733
1217
  const u = document.createElement("a");
734
1218
  u.href = d[2], u.target = "_top", u.rel = "noreferrer", u.textContent = d[1], t.appendChild(u);
735
1219
  } else
736
- t.appendChild(document.createTextNode(i));
1220
+ t.appendChild(document.createTextNode(l));
737
1221
  }
738
- o = r + i.length;
1222
+ o = r + l.length;
739
1223
  }
740
1224
  o < e.length && t.appendChild(document.createTextNode(e.slice(o)));
741
1225
  }
742
- function qe(t) {
1226
+ function En(t) {
743
1227
  if (t.startsWith("/") || t.startsWith("#"))
744
1228
  return !0;
745
1229
  try {
@@ -749,7 +1233,7 @@ function qe(t) {
749
1233
  return !1;
750
1234
  }
751
1235
  }
752
- function ue(t, e) {
1236
+ function We(t, e) {
753
1237
  if (t.getElementById("pluno-pa-widget-styles"))
754
1238
  return;
755
1239
  const n = t.ownerDocument.createElement("style");
@@ -795,18 +1279,20 @@ function ue(t, e) {
795
1279
  --pluno-pa-divider: rgba(24, 24, 27, 0.08);
796
1280
  --pluno-pa-launcher-hairline: rgba(24, 24, 27, 0.06);
797
1281
  --pluno-pa-launcher-width: min(190px, calc(100vw - 36px));
1282
+ --pluno-pa-launcher-height: 41px;
1283
+ --pluno-pa-panel-width: min(420px, calc(100vw - 28px));
1284
+ --pluno-pa-panel-height: min(680px, calc(100vh - 28px));
1285
+ --pluno-pa-panel-offset-x: calc(var(--pluno-pa-launcher-width) - var(--pluno-pa-panel-width));
1286
+ --pluno-pa-panel-offset-y: calc(var(--pluno-pa-launcher-height) - var(--pluno-pa-panel-height));
798
1287
  --pluno-pa-accent-soft: rgba(24, 24, 27, 0.12);
799
1288
  --pluno-pa-accent-contrast: #fafafa;
800
1289
  position: fixed;
801
1290
  z-index: 2147483645;
802
- font-family: ${T.fontFamily};
1291
+ font-family: ${D.fontFamily};
803
1292
  font-size: 14px;
804
1293
  color: var(--pluno-pa-text);
805
1294
  width: var(--pluno-pa-launcher-width);
806
- height: 41px;
807
- transition:
808
- width 220ms cubic-bezier(0.2, 0.8, 0.2, 1),
809
- height 220ms cubic-bezier(0.2, 0.8, 0.2, 1);
1295
+ height: var(--pluno-pa-launcher-height);
810
1296
  }
811
1297
  .pluno-pa-widget--dark {
812
1298
  --pluno-pa-bg: #0f0f10;
@@ -823,12 +1309,39 @@ function ue(t, e) {
823
1309
  .pluno-pa-widget [hidden] {
824
1310
  display: none !important;
825
1311
  }
1312
+ .pluno-pa-widget--drag-over::after {
1313
+ content: "Drop files to attach";
1314
+ position: absolute;
1315
+ inset: -8px;
1316
+ z-index: 12;
1317
+ display: grid;
1318
+ place-items: center;
1319
+ border: 2px dashed var(--pluno-pa-accent);
1320
+ border-radius: 20px;
1321
+ background: color-mix(in srgb, var(--pluno-pa-bg) 82%, transparent);
1322
+ box-shadow: 0 0 0 999px rgba(24, 24, 27, 0.12);
1323
+ color: var(--pluno-pa-text);
1324
+ font-size: 14px;
1325
+ font-weight: 650;
1326
+ pointer-events: none;
1327
+ }
1328
+ .pluno-pa-widget--open.pluno-pa-widget--drag-over::after,
1329
+ .pluno-pa-widget--closing.pluno-pa-widget--drag-over::after {
1330
+ inset: auto;
1331
+ left: calc(var(--pluno-pa-panel-offset-x) - 8px);
1332
+ top: calc(var(--pluno-pa-panel-offset-y) - 8px);
1333
+ width: calc(var(--pluno-pa-panel-width) + 16px);
1334
+ height: calc(var(--pluno-pa-panel-height) + 16px);
1335
+ border-radius: 18px;
1336
+ }
826
1337
  .pluno-pa-widget--bottom-right { right: 26px; bottom: 24px; }
827
1338
  .pluno-pa-widget--bottom-left { left: 26px; bottom: 24px; }
828
- .pluno-pa-widget--open,
829
- .pluno-pa-widget--closing {
830
- width: min(420px, calc(100vw - 28px));
831
- height: min(680px, calc(100vh - 28px));
1339
+ .pluno-pa-widget--bottom-left {
1340
+ --pluno-pa-panel-offset-x: 0px;
1341
+ }
1342
+ .pluno-pa-widget--custom-position {
1343
+ right: auto;
1344
+ bottom: auto;
832
1345
  }
833
1346
  .pluno-pa-widget__launcher {
834
1347
  position: absolute;
@@ -848,11 +1361,33 @@ function ue(t, e) {
848
1361
  inset 0 0 0 1px var(--pluno-pa-launcher-hairline);
849
1362
  transform-origin: bottom right;
850
1363
  transition:
851
- opacity 160ms ease,
852
- transform 220ms cubic-bezier(0.2, 0.8, 0.2, 1),
853
1364
  box-shadow 150ms ease,
854
1365
  background 150ms ease;
855
1366
  }
1367
+ .pluno-pa-widget__launcher-drag-handle {
1368
+ position: absolute;
1369
+ z-index: 2;
1370
+ top: -11px;
1371
+ left: 8px;
1372
+ right: 8px;
1373
+ height: 11px;
1374
+ border: 0;
1375
+ border-radius: 999px;
1376
+ background: transparent;
1377
+ color: transparent;
1378
+ padding: 0;
1379
+ cursor: grab;
1380
+ touch-action: none;
1381
+ }
1382
+ .pluno-pa-widget__launcher-drag-handle:active,
1383
+ .pluno-pa-widget__launcher-drag-handle:focus-visible,
1384
+ .pluno-pa-widget--dragging .pluno-pa-widget__launcher-drag-handle {
1385
+ cursor: grabbing;
1386
+ }
1387
+ .pluno-pa-widget__launcher-drag-handle:focus-visible {
1388
+ outline: 2px solid var(--pluno-pa-accent);
1389
+ outline-offset: 2px;
1390
+ }
856
1391
  .pluno-pa-widget__character {
857
1392
  display: block;
858
1393
  flex: 0 0 auto;
@@ -900,14 +1435,13 @@ function ue(t, e) {
900
1435
  .pluno-pa-widget--open .pluno-pa-widget__launcher {
901
1436
  opacity: 0;
902
1437
  pointer-events: none;
903
- transform: translateY(-8px) scale(0.96);
904
1438
  }
905
1439
  .pluno-pa-widget__panel {
906
1440
  position: absolute;
907
- right: 0;
908
- bottom: 0;
909
- width: 100%;
910
- height: 100%;
1441
+ left: var(--pluno-pa-panel-offset-x);
1442
+ top: var(--pluno-pa-panel-offset-y);
1443
+ width: var(--pluno-pa-panel-width);
1444
+ height: var(--pluno-pa-panel-height);
911
1445
  display: flex;
912
1446
  flex-direction: column;
913
1447
  min-height: 0;
@@ -924,8 +1458,6 @@ function ue(t, e) {
924
1458
  transform 220ms cubic-bezier(0.2, 0.8, 0.2, 1);
925
1459
  }
926
1460
  .pluno-pa-widget--bottom-left .pluno-pa-widget__panel {
927
- left: 0;
928
- right: auto;
929
1461
  transform-origin: bottom left;
930
1462
  }
931
1463
  .pluno-pa-widget--open .pluno-pa-widget__panel {
@@ -934,8 +1466,8 @@ function ue(t, e) {
934
1466
  }
935
1467
  .pluno-pa-widget__close {
936
1468
  position: absolute;
937
- top: -42px;
938
- right: 0;
1469
+ left: calc(var(--pluno-pa-panel-offset-x) + var(--pluno-pa-panel-width) - 32px);
1470
+ top: calc(var(--pluno-pa-panel-offset-y) - 42px);
939
1471
  z-index: 2;
940
1472
  width: 32px;
941
1473
  height: 32px;
@@ -1084,6 +1616,50 @@ function ue(t, e) {
1084
1616
  border-radius: 16px 16px 4px 16px;
1085
1617
  padding: 8px 12px;
1086
1618
  }
1619
+ .pluno-pa-widget__message-attachments {
1620
+ display: grid;
1621
+ grid-template-columns: repeat(auto-fill, minmax(72px, 1fr));
1622
+ gap: 6px;
1623
+ margin-top: 8px;
1624
+ max-width: 220px;
1625
+ }
1626
+ .pluno-pa-widget__message-attachments img {
1627
+ width: 100%;
1628
+ aspect-ratio: 1;
1629
+ border-radius: 8px;
1630
+ object-fit: cover;
1631
+ border: 1px solid var(--pluno-pa-divider);
1632
+ }
1633
+ .pluno-pa-widget__message-attachment-file {
1634
+ min-width: 0;
1635
+ aspect-ratio: 1;
1636
+ display: grid;
1637
+ align-content: center;
1638
+ gap: 5px;
1639
+ border: 1px solid var(--pluno-pa-divider);
1640
+ border-radius: 8px;
1641
+ background: var(--pluno-pa-surface);
1642
+ padding: 8px;
1643
+ color: var(--pluno-pa-text);
1644
+ }
1645
+ .pluno-pa-widget__message-attachment-file span {
1646
+ width: fit-content;
1647
+ border-radius: 4px;
1648
+ background: var(--pluno-pa-accent-soft);
1649
+ color: var(--pluno-pa-accent);
1650
+ padding: 2px 5px;
1651
+ font-size: 10px;
1652
+ font-weight: 700;
1653
+ line-height: 1;
1654
+ }
1655
+ .pluno-pa-widget__message-attachment-file strong {
1656
+ min-width: 0;
1657
+ overflow: hidden;
1658
+ text-overflow: ellipsis;
1659
+ white-space: nowrap;
1660
+ font-size: 11px;
1661
+ font-weight: 600;
1662
+ }
1087
1663
  .pluno-pa-widget__message--assistant {
1088
1664
  align-self: stretch;
1089
1665
  padding: 0 2px;
@@ -1294,6 +1870,85 @@ function ue(t, e) {
1294
1870
  background: var(--pluno-pa-bg);
1295
1871
  border-top: 1px solid var(--pluno-pa-divider);
1296
1872
  }
1873
+ .pluno-pa-widget__attachment-error {
1874
+ margin: 0 0 8px;
1875
+ padding: 6px 9px;
1876
+ border-radius: 8px;
1877
+ background: rgba(239, 68, 68, 0.12);
1878
+ color: #dc2626;
1879
+ font-size: 12px;
1880
+ line-height: 1.35;
1881
+ }
1882
+ .pluno-pa-widget__attachment-error[hidden] {
1883
+ display: none;
1884
+ }
1885
+ .pluno-pa-widget__attachments {
1886
+ display: flex;
1887
+ flex-wrap: wrap;
1888
+ gap: 6px;
1889
+ margin: 0 0 8px;
1890
+ }
1891
+ .pluno-pa-widget__attachments[hidden] {
1892
+ display: none;
1893
+ }
1894
+ .pluno-pa-widget__attachment {
1895
+ min-width: 0;
1896
+ max-width: 100%;
1897
+ height: 30px;
1898
+ display: inline-flex;
1899
+ align-items: center;
1900
+ gap: 7px;
1901
+ border: 1px solid var(--pluno-pa-divider);
1902
+ border-radius: 8px;
1903
+ background: var(--pluno-pa-surface);
1904
+ color: var(--pluno-pa-muted);
1905
+ padding: 3px 5px 3px 3px;
1906
+ font-size: 12px;
1907
+ }
1908
+ .pluno-pa-widget__attachment img {
1909
+ width: 22px;
1910
+ height: 22px;
1911
+ border-radius: 5px;
1912
+ object-fit: cover;
1913
+ flex: 0 0 auto;
1914
+ }
1915
+ .pluno-pa-widget__attachment-file {
1916
+ width: 28px;
1917
+ height: 22px;
1918
+ flex: 0 0 auto;
1919
+ display: inline-grid;
1920
+ place-items: center;
1921
+ border-radius: 5px;
1922
+ background: var(--pluno-pa-accent-soft);
1923
+ color: var(--pluno-pa-accent);
1924
+ font-size: 9px;
1925
+ font-weight: 700;
1926
+ line-height: 1;
1927
+ }
1928
+ .pluno-pa-widget__attachment span {
1929
+ overflow: hidden;
1930
+ text-overflow: ellipsis;
1931
+ white-space: nowrap;
1932
+ }
1933
+ .pluno-pa-widget__attachment button {
1934
+ border: 0;
1935
+ background: transparent;
1936
+ color: inherit;
1937
+ padding: 0;
1938
+ cursor: pointer;
1939
+ }
1940
+ .pluno-pa-widget__attachment button {
1941
+ width: 18px;
1942
+ height: 18px;
1943
+ display: inline-flex;
1944
+ align-items: center;
1945
+ justify-content: center;
1946
+ border-radius: 999px;
1947
+ flex: 0 0 auto;
1948
+ }
1949
+ .pluno-pa-widget__attachment button:hover:not(:disabled) {
1950
+ background: var(--pluno-pa-bubble);
1951
+ }
1297
1952
  .pluno-pa-widget__composer-inner {
1298
1953
  position: relative;
1299
1954
  display: flex;
@@ -1303,11 +1958,16 @@ function ue(t, e) {
1303
1958
  border: 1px solid var(--pluno-pa-divider);
1304
1959
  border-radius: 14px;
1305
1960
  padding: 8px 44px 8px 12px;
1306
- transition: border-color 150ms ease;
1961
+ transition: border-color 150ms ease, background-color 150ms ease, box-shadow 150ms ease;
1307
1962
  }
1308
1963
  .pluno-pa-widget__composer-inner:focus-within {
1309
1964
  border-color: var(--pluno-pa-accent);
1310
1965
  }
1966
+ .pluno-pa-widget--drag-over .pluno-pa-widget__composer-inner {
1967
+ border-color: var(--pluno-pa-accent);
1968
+ background: var(--pluno-pa-accent-soft);
1969
+ box-shadow: 0 0 0 3px var(--pluno-pa-accent-soft);
1970
+ }
1311
1971
  .pluno-pa-widget__input {
1312
1972
  flex: 1;
1313
1973
  width: 100%;
@@ -1448,6 +2108,20 @@ function ue(t, e) {
1448
2108
  color: var(--pluno-pa-text);
1449
2109
  background: transparent;
1450
2110
  }
2111
+ .pluno-pa-widget__login {
2112
+ border: 0;
2113
+ border-radius: 8px;
2114
+ background: #09090b;
2115
+ color: #ffffff;
2116
+ min-height: 38px;
2117
+ padding: 0 14px;
2118
+ font: 650 13px/1 var(--pluno-pa-font);
2119
+ cursor: pointer;
2120
+ box-shadow: 0 8px 18px rgba(9, 9, 11, 0.16);
2121
+ }
2122
+ .pluno-pa-widget__login:hover {
2123
+ background: #18181b;
2124
+ }
1451
2125
  .pluno-pa-widget__status {
1452
2126
  display: inline-flex;
1453
2127
  align-items: center;
@@ -1497,6 +2171,7 @@ function ue(t, e) {
1497
2171
  }
1498
2172
  .pluno-pa-widget--scribble {
1499
2173
  /* Paper is always light; scribble ignores the configured color scheme */
2174
+ --pluno-pa-launcher-height: 48px;
1500
2175
  --pluno-pa-bg: #fdfaf1;
1501
2176
  --pluno-pa-surface: #f7f2e3;
1502
2177
  --pluno-pa-bubble: #f3ecd8;
@@ -1544,7 +2219,7 @@ function ue(t, e) {
1544
2219
  right: 16px;
1545
2220
  height: 36px;
1546
2221
  z-index: 3;
1547
- background-image: url('${ne}');
2222
+ background-image: url('${ke}');
1548
2223
  background-repeat: repeat-x;
1549
2224
  background-size: 104px 36px;
1550
2225
  filter: url(#pluno-pa-scribble-wobble-2);
@@ -1720,15 +2395,19 @@ function ue(t, e) {
1720
2395
  /* Taller strip so the bolt clears the spiral ring stubs */
1721
2396
  height: 48px;
1722
2397
  }
1723
- .pluno-pa-widget--scribble:not(.pluno-pa-widget--open):not(.pluno-pa-widget--closing) {
1724
- height: 48px;
1725
- }
1726
2398
  .pluno-pa-widget--scribble .pluno-pa-widget__character--launcher {
1727
2399
  margin-top: 3px;
1728
2400
  }
1729
2401
  .pluno-pa-widget--scribble .pluno-pa-widget__launcher-input {
1730
2402
  margin-top: 2px;
1731
2403
  }
2404
+ .pluno-pa-widget--scribble .pluno-pa-widget__launcher-drag-handle {
2405
+ top: -13px;
2406
+ left: 12px;
2407
+ right: 12px;
2408
+ height: 12px;
2409
+ z-index: 3;
2410
+ }
1732
2411
  .pluno-pa-widget--scribble .pluno-pa-widget__launcher::before {
1733
2412
  background-color: var(--pluno-pa-bg);
1734
2413
  background-image:
@@ -1744,7 +2423,7 @@ function ue(t, e) {
1744
2423
  right: 12px;
1745
2424
  height: 22px;
1746
2425
  z-index: 1;
1747
- background-image: url('${ne}');
2426
+ background-image: url('${ke}');
1748
2427
  background-repeat: repeat-x;
1749
2428
  background-size: 62px 21.5px;
1750
2429
  filter: url(#pluno-pa-scribble-wobble-2);
@@ -1758,7 +2437,7 @@ function ue(t, e) {
1758
2437
  }
1759
2438
  `, t.appendChild(n);
1760
2439
  }
1761
- async function Ye() {
2440
+ async function kn() {
1762
2441
  return document.body ? document.body : await new Promise((t) => {
1763
2442
  const e = new MutationObserver(() => {
1764
2443
  document.body && (e.disconnect(), t(document.body));
@@ -1766,59 +2445,62 @@ async function Ye() {
1766
2445
  e.observe(document.documentElement, { childList: !0 });
1767
2446
  });
1768
2447
  }
1769
- function D(t) {
1770
- const e = document.createElement("span");
1771
- return e.textContent = t, e.innerHTML;
1772
- }
1773
- function me(t) {
2448
+ function nt(t) {
1774
2449
  return `pluno.productAgent.widgetState.${location.origin}.${t.backendUrl ?? ""}.${t.tokenEndpoint ?? ""}.${t.position ?? ""}`;
1775
2450
  }
1776
- function Ze(t) {
2451
+ function Sn(t) {
1777
2452
  try {
1778
- const e = window.localStorage.getItem(me(t));
2453
+ const e = window.localStorage.getItem(nt(t));
1779
2454
  if (!e)
1780
- return { isOpen: !1, composerValue: "", openToolGroupKeys: [] };
2455
+ return { isOpen: !1, composerValue: "", openToolGroupKeys: [], launcherPosition: null };
1781
2456
  const n = JSON.parse(e);
1782
2457
  return {
1783
2458
  isOpen: n.isOpen === !0,
1784
2459
  composerValue: typeof n.composerValue == "string" ? n.composerValue : "",
1785
- openToolGroupKeys: Array.isArray(n.openToolGroupKeys) ? n.openToolGroupKeys.filter((o) => typeof o == "string") : []
2460
+ openToolGroupKeys: Array.isArray(n.openToolGroupKeys) ? n.openToolGroupKeys.filter((o) => typeof o == "string") : [],
2461
+ launcherPosition: Pn(n.launcherPosition) ? n.launcherPosition : null
1786
2462
  };
1787
2463
  } catch {
1788
- return { isOpen: !1, composerValue: "", openToolGroupKeys: [] };
2464
+ return { isOpen: !1, composerValue: "", openToolGroupKeys: [], launcherPosition: null };
1789
2465
  }
1790
2466
  }
1791
- function Xe(t, e) {
2467
+ function Ln(t, e) {
1792
2468
  try {
1793
- window.localStorage.setItem(me(t), JSON.stringify(e));
2469
+ window.localStorage.setItem(nt(t), JSON.stringify(e));
1794
2470
  } catch {
1795
2471
  return;
1796
2472
  }
1797
2473
  }
1798
- const ge = /* @__PURE__ */ new WeakSet();
1799
- function Je(t) {
2474
+ function Pn(t) {
2475
+ if (!t || typeof t != "object")
2476
+ return !1;
2477
+ const e = t;
2478
+ return Number.isFinite(e.x) && Number.isFinite(e.y);
2479
+ }
2480
+ const Ue = /* @__PURE__ */ new WeakSet();
2481
+ function An(t) {
1800
2482
  return Object.keys(t.dataset).some((e) => e.startsWith("pluno"));
1801
2483
  }
1802
- function be(t) {
2484
+ function He(t) {
1803
2485
  const e = t.pathname.split("/");
1804
2486
  return e[e.length - 1] ?? "";
1805
2487
  }
1806
- function Qe(t, e) {
2488
+ function Tn(t, e) {
1807
2489
  const n = new URL(t.src, document.baseURI);
1808
- return n.href === e.href || n.pathname === e.pathname ? !0 : be(n) === be(e);
2490
+ return n.href === e.href || n.pathname === e.pathname ? !0 : He(n) === He(e);
1809
2491
  }
1810
- class C extends EventTarget {
2492
+ class I extends EventTarget {
1811
2493
  constructor(e, n) {
1812
- super(), this.channelId = n, this.url = e, this.addPreviewListener($e, () => {
1813
- this.readyState = C.OPEN, this.dispatchEvent(new Event("open"));
1814
- }), this.addPreviewListener(De, (o) => {
2494
+ super(), this.channelId = n, this.url = e, this.addPreviewListener(Et, () => {
2495
+ this.readyState = I.OPEN, this.dispatchEvent(new Event("open"));
2496
+ }), this.addPreviewListener(kt, (o) => {
1815
2497
  const a = o;
1816
2498
  this.dispatchEvent(new MessageEvent("message", { data: a.detail?.data ?? "" }));
1817
- }), this.addPreviewListener(Fe, () => {
1818
- this.readyState = C.CLOSED, this.dispatchEvent(new Event("error")), this.cleanup();
1819
- }), this.addPreviewListener(Re, (o) => {
2499
+ }), this.addPreviewListener(St, () => {
2500
+ this.readyState = I.CLOSED, this.dispatchEvent(new Event("error")), this.cleanup();
2501
+ }), this.addPreviewListener(Lt, (o) => {
1820
2502
  const a = o;
1821
- this.readyState = C.CLOSED, this.dispatchEvent(
2503
+ this.readyState = I.CLOSED, this.dispatchEvent(
1822
2504
  new CloseEvent("close", {
1823
2505
  code: a.detail?.code ?? 1e3,
1824
2506
  reason: a.detail?.reason ?? "",
@@ -1826,7 +2508,7 @@ class C extends EventTarget {
1826
2508
  })
1827
2509
  ), this.cleanup();
1828
2510
  }), window.dispatchEvent(
1829
- new CustomEvent(F(Ae, this.channelId), {
2511
+ new CustomEvent(Q(yt, this.channelId), {
1830
2512
  detail: { socketId: this.socketId, url: e }
1831
2513
  })
1832
2514
  );
@@ -1841,27 +2523,27 @@ class C extends EventTarget {
1841
2523
  extensions = "";
1842
2524
  binaryType = "blob";
1843
2525
  bufferedAmount = 0;
1844
- readyState = C.CONNECTING;
1845
- socketId = et();
2526
+ readyState = I.CONNECTING;
2527
+ socketId = Nn();
1846
2528
  listeners = /* @__PURE__ */ new Map();
1847
2529
  send(e) {
1848
- if (this.readyState !== C.OPEN)
1849
- throw new DOMException("Product Agent preview websocket is not open", "InvalidStateError");
2530
+ if (this.readyState !== I.OPEN)
2531
+ throw new DOMException("Pluno preview websocket is not open", "InvalidStateError");
1850
2532
  window.dispatchEvent(
1851
- new CustomEvent(F(Me, this.channelId), {
2533
+ new CustomEvent(Q(vt, this.channelId), {
1852
2534
  detail: { socketId: this.socketId, data: typeof e == "string" ? e : String(e) }
1853
2535
  })
1854
2536
  );
1855
2537
  }
1856
2538
  close(e, n) {
1857
- this.readyState !== C.CLOSED && (this.readyState = C.CLOSING, window.dispatchEvent(
1858
- new CustomEvent(F(Oe, this.channelId), {
2539
+ this.readyState !== I.CLOSED && (this.readyState = I.CLOSING, window.dispatchEvent(
2540
+ new CustomEvent(Q(Ct, this.channelId), {
1859
2541
  detail: { socketId: this.socketId, code: e, reason: n }
1860
2542
  })
1861
2543
  ), this.cleanup());
1862
2544
  }
1863
2545
  addPreviewListener(e, n) {
1864
- const o = F(e, this.channelId), a = (r) => {
2546
+ const o = Q(e, this.channelId), a = (r) => {
1865
2547
  r.detail?.socketId === this.socketId && n(r);
1866
2548
  };
1867
2549
  this.listeners.set(o, a), window.addEventListener(o, a);
@@ -1872,36 +2554,36 @@ class C extends EventTarget {
1872
2554
  this.listeners.clear();
1873
2555
  }
1874
2556
  }
1875
- function et() {
1876
- const t = window.sessionStorage.getItem(te);
2557
+ function Nn() {
2558
+ const t = window.sessionStorage.getItem(Ee);
1877
2559
  if (t)
1878
2560
  return t;
1879
2561
  const e = crypto.randomUUID();
1880
- return window.sessionStorage.setItem(te, e), e;
2562
+ return window.sessionStorage.setItem(Ee, e), e;
1881
2563
  }
1882
- function F(t, e) {
2564
+ function Q(t, e) {
1883
2565
  return `${t}:${e}`;
1884
2566
  }
1885
- function tt(t) {
2567
+ function In(t) {
1886
2568
  const e = document.currentScript;
1887
2569
  if (e instanceof HTMLScriptElement)
1888
2570
  return [e];
1889
2571
  const n = new URL(t, document.baseURI).href, o = new URL(n);
1890
2572
  return Array.from(document.querySelectorAll("script[type='module'][src]")).filter(
1891
- (a) => a instanceof HTMLScriptElement && Je(a) && Qe(a, o)
2573
+ (a) => a instanceof HTMLScriptElement && An(a) && Tn(a, o)
1892
2574
  );
1893
2575
  }
1894
- function nt(t) {
1895
- for (const e of tt(t)) {
1896
- if (ge.has(e) || e.dataset.plunoAutoMount === "false")
2576
+ function Rn(t) {
2577
+ for (const e of In(t)) {
2578
+ if (Ue.has(e) || e.dataset.plunoAutoMount === "false")
1897
2579
  continue;
1898
- ge.add(e);
2580
+ Ue.add(e);
1899
2581
  const n = e.dataset.plunoPreviewChannel;
1900
- Ue({
2582
+ Ut({
1901
2583
  token: e.dataset.plunoToken,
1902
2584
  tokenEndpoint: e.dataset.plunoTokenEndpoint,
1903
2585
  backendUrl: e.dataset.plunoBackendUrl,
1904
- webSocketFactory: n ? Be(n) : void 0,
2586
+ webSocketFactory: n ? Wt(n) : void 0,
1905
2587
  launcherLabel: e.dataset.plunoLauncherLabel,
1906
2588
  accentColor: e.dataset.plunoAccentColor,
1907
2589
  colorScheme: e.dataset.plunoColorScheme === "dark" ? "dark" : "light",
@@ -1909,12 +2591,12 @@ function nt(t) {
1909
2591
  scribbleStyle: e.dataset.plunoScribbleStyle === "true",
1910
2592
  position: e.dataset.plunoPosition === "bottom-left" ? "bottom-left" : "bottom-right"
1911
2593
  }).catch((o) => {
1912
- console.error("Failed to mount Pluno Product Agent widget", o);
2594
+ console.error("Failed to mount Pluno widget", o);
1913
2595
  });
1914
2596
  }
1915
2597
  }
1916
- nt(import.meta.url);
2598
+ Rn(import.meta.url);
1917
2599
  export {
1918
- Be as createProductAgentPreviewBridgeWebSocketFactory,
1919
- Ue as mountPlunoProductAgentWidget
2600
+ Wt as createProductAgentPreviewBridgeWebSocketFactory,
2601
+ Ut as mountPlunoProductAgentWidget
1920
2602
  };