@llumi/design-system 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,1601 @@
1
+ import { fromCallback as st, setup as It, emit as lt, assign as x, stateIn as St, enqueueActions as Tt, createActor as kt } from "xstate";
2
+ import { tinykeys as Lt } from "tinykeys";
3
+ import { svg as _, html as v, LitElement as zt, unsafeCSS as Ot } from "lit";
4
+ import { property as f, query as F, state as At, customElement as A } from "lit/decorators.js";
5
+ import { clsx as Dt } from "clsx";
6
+ import { twMerge as Mt } from "tailwind-merge";
7
+ import { autoUpdate as pt, computePosition as ft, offset as vt, flip as wt, shift as bt, size as xt } from "@floating-ui/dom";
8
+ import { classMap as _t } from "lit/directives/class-map.js";
9
+ import { repeat as Nt } from "lit/directives/repeat.js";
10
+ import { styleMap as $t } from "lit/directives/style-map.js";
11
+ function ct(o, e) {
12
+ const t = o.getAttribute("data-review-id");
13
+ if (t) return t;
14
+ for (const i of e ?? [])
15
+ if (o.matches(i.selector)) {
16
+ const n = i.toId(o);
17
+ if (n) return n;
18
+ }
19
+ return null;
20
+ }
21
+ function N(o, e) {
22
+ const t = o.closest("[data-review-id]");
23
+ if (t) {
24
+ const i = t.getAttribute("data-review-id");
25
+ if (i) return { element: t, targetId: i };
26
+ }
27
+ for (const i of e ?? []) {
28
+ const n = o.closest(i.selector);
29
+ if (n) {
30
+ const r = i.toId(n);
31
+ if (r) return { element: n, targetId: r };
32
+ }
33
+ }
34
+ return null;
35
+ }
36
+ function $(o, e) {
37
+ const t = /* @__PURE__ */ new Set(), i = [];
38
+ for (const n of Array.from(
39
+ o.querySelectorAll("[data-review-id]")
40
+ )) {
41
+ const r = n.getAttribute("data-review-id");
42
+ if (!r) continue;
43
+ const a = n.hasAttribute("data-review-selectable");
44
+ i.push({
45
+ element: n,
46
+ targetId: r,
47
+ kind: a ? "both" : "element"
48
+ }), t.add(n);
49
+ }
50
+ for (const n of e ?? [])
51
+ for (const r of Array.from(
52
+ o.querySelectorAll(n.selector)
53
+ )) {
54
+ if (t.has(r)) continue;
55
+ const a = n.toId(r);
56
+ if (!a) continue;
57
+ const s = r.hasAttribute("data-review-selectable");
58
+ i.push({
59
+ element: r,
60
+ targetId: a,
61
+ kind: s ? "both" : "element"
62
+ }), t.add(r);
63
+ }
64
+ for (const n of Array.from(
65
+ o.querySelectorAll("[data-review-selectable]")
66
+ )) {
67
+ if (t.has(n)) continue;
68
+ const r = n.getAttribute("data-review-selectable");
69
+ r && (i.push({ element: n, targetId: r, kind: "selectable" }), t.add(n));
70
+ }
71
+ return i;
72
+ }
73
+ const et = "review-highlight-hover", C = "review-highlight-commented", G = "review-highlight-editing", j = "review-highlight-uncommented", V = "review-target", dt = "review-active";
74
+ function B(o) {
75
+ o.classList.remove(
76
+ et,
77
+ C,
78
+ G,
79
+ j
80
+ );
81
+ }
82
+ function Pt(o, e) {
83
+ let t = null, i = null, n = null;
84
+ function r(c) {
85
+ o.classList.add(dt);
86
+ const h = $(o, e);
87
+ for (const { element: p, targetId: d, kind: T } of h)
88
+ (T === "element" || T === "both") && (p.hasAttribute("data-review-id") || p.classList.add(V), c.has(d) && p.classList.add(C));
89
+ }
90
+ function a() {
91
+ o.classList.remove(dt), t && (clearTimeout(t), t = null);
92
+ const c = $(o, e);
93
+ for (const { element: h } of c)
94
+ B(h), h.classList.remove(V);
95
+ }
96
+ function s(c) {
97
+ const h = $(o, e), p = [];
98
+ for (const { element: d } of h)
99
+ !d.classList.contains(C) && !d.classList.contains(G) && (d.classList.add(j), p.push(d));
100
+ c && (t && clearTimeout(t), t = setTimeout(() => {
101
+ t = null;
102
+ for (const d of p)
103
+ d.classList.contains(G) || d.classList.remove(j);
104
+ }, 500));
105
+ }
106
+ function l() {
107
+ t && (clearTimeout(t), t = null);
108
+ const c = $(o, e);
109
+ for (const { element: h } of c)
110
+ h.classList.remove(j);
111
+ }
112
+ function m(c, h) {
113
+ h || (B(c), c.classList.add(G));
114
+ }
115
+ function u(c, h) {
116
+ B(c), h && c.classList.add(C);
117
+ }
118
+ function b(c, h) {
119
+ (ct(c, e) ?? c.getAttribute("data-review-selectable")) !== h && c.classList.add(et);
120
+ }
121
+ function g(c, h, p) {
122
+ const d = ct(c, e) ?? c.getAttribute("data-review-selectable");
123
+ d !== h && (c.classList.remove(et), d && (p != null && p.has(d)) && c.classList.add(C));
124
+ }
125
+ function Ct(c) {
126
+ W(), n = c.editingTarget ?? null, i = new MutationObserver((h) => {
127
+ for (const p of h) {
128
+ for (const d of Array.from(p.removedNodes)) {
129
+ if (!(d instanceof HTMLElement)) continue;
130
+ n && (d === n || d.contains(n)) && (n = null, c.onTargetDisconnected()), (d.hasAttribute("data-review-selectable") || d.querySelector("[data-review-selectable]") !== null) && c.onSelectableReconnected();
131
+ }
132
+ for (const d of Array.from(p.addedNodes)) {
133
+ if (!(d instanceof HTMLElement)) continue;
134
+ const T = [
135
+ ...d.matches("[data-review-id]") ? [d] : [],
136
+ ...Array.from(
137
+ d.querySelectorAll("[data-review-id]")
138
+ )
139
+ ];
140
+ for (const I of T) {
141
+ const M = I.getAttribute("data-review-id");
142
+ M && c.commentedIds.has(M) && I.classList.add(C);
143
+ }
144
+ for (const I of e ?? []) {
145
+ const M = [
146
+ ...d.matches(I.selector) ? [d] : [],
147
+ ...Array.from(d.querySelectorAll(I.selector))
148
+ ];
149
+ for (const K of M) {
150
+ const at = I.toId(K);
151
+ K.classList.add(V), at && c.commentedIds.has(at) && K.classList.add(C);
152
+ }
153
+ }
154
+ (d.hasAttribute("data-review-selectable") || d.querySelector("[data-review-selectable]") !== null) && c.onSelectableReconnected();
155
+ }
156
+ }
157
+ }), i.observe(o, { childList: !0, subtree: !0 });
158
+ }
159
+ function W() {
160
+ i && (i.disconnect(), i = null), n = null;
161
+ }
162
+ function Et() {
163
+ a(), W();
164
+ }
165
+ return {
166
+ activate: r,
167
+ deactivate: a,
168
+ reveal: s,
169
+ unreveal: l,
170
+ setEditing: m,
171
+ clearEditing: u,
172
+ applyHover: b,
173
+ clearHover: g,
174
+ startObserving: Ct,
175
+ stopObserving: W,
176
+ destroy: Et
177
+ };
178
+ }
179
+ const Rt = `:root{--review-highlight-uncommented-color: oklch(.7 0 0 / .15);--review-highlight-commented-color: oklch(.7 0 0 / .3);--review-highlight-color: oklch(.7 0 0 / .5);--review-highlight-editing-color: oklch(.6 0 0 / .7);--review-badge-icon-color: oklch(.35 0 0);--review-z-index: 9998;--review-selection-commented-color: oklch(.85 .08 250 / .4);--review-selection-editing-color: oklch(.75 .12 250 / .6);--review-selection-hover-color: oklch(.8 .1 250 / .5)}[data-review-id],[data-review-selectable],.review-target{outline:2px solid transparent;outline-offset:2px;transition:outline-color .15s ease}.review-highlight-uncommented{outline-color:var(--review-highlight-uncommented-color)}.review-highlight-commented{outline-color:var(--review-highlight-commented-color);position:relative}.review-highlight-hover{outline-color:var(--review-highlight-color)}.review-highlight-commented:after{content:"";position:absolute;top:-12px;right:-14px;width:20px;height:20px;border-radius:50%;background-color:#fff;background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%23404040' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M22 17a2 2 0 0 1-2 2H6.828a2 2 0 0 0-1.414.586l-2.202 2.202A.71.71 0 0 1 2 21.286V5a2 2 0 0 1 2-2h16a2 2 0 0 1 2 2z'/%3E%3C/svg%3E");background-size:12px 12px;background-repeat:no-repeat;background-position:center;box-shadow:0 1px 3px #0000001a;pointer-events:none}.review-highlight-editing:after{display:none}[data-review-selectable]:not([data-review-id]).review-highlight-commented:after{display:none}.review-highlight-editing{outline-color:var(--review-highlight-editing-color)}::highlight(review-selection-commented){background-color:var(--review-selection-commented-color)}::highlight(review-selection-editing){background-color:var(--review-selection-editing-color)}::highlight(review-selection-hover){background-color:var(--review-selection-hover-color)}.review-active [data-review-id],.review-active .review-target{cursor:pointer}.review-active [data-review-selectable]{cursor:text}`;
180
+ function Ht(o, e) {
181
+ const t = o.find(
182
+ (n) => n.targetId === e && !n.selection
183
+ );
184
+ return t ? { comment: t, isNew: !1 } : { comment: {
185
+ commentId: crypto.randomUUID(),
186
+ targetId: e,
187
+ content: "",
188
+ createdAt: (/* @__PURE__ */ new Date()).toISOString()
189
+ }, isNew: !0 };
190
+ }
191
+ function Gt(o) {
192
+ let e = o.comments;
193
+ if (o.editingCommentId !== null) {
194
+ const t = e.find(
195
+ (i) => i.commentId === o.editingCommentId
196
+ );
197
+ t && t.content === "" && (e = e.filter(
198
+ (i) => i.commentId !== o.editingCommentId
199
+ ));
200
+ }
201
+ return {
202
+ comments: e,
203
+ editingCommentId: null,
204
+ targetElement: null,
205
+ selectionRange: null
206
+ };
207
+ }
208
+ function ht(o) {
209
+ const e = o.comments.filter((n) => n.content.trim()), t = e.length > 0, i = o.overallComment.trim().length > 0;
210
+ return !t && !i ? { status: "approved" } : {
211
+ status: "commented",
212
+ comments: e,
213
+ overallComment: i ? o.overallComment.trim() : void 0
214
+ };
215
+ }
216
+ function jt(o) {
217
+ const e = /* @__PURE__ */ new Set();
218
+ for (const t of o.comments)
219
+ !t.selection && t.content.trim() && e.add(t.targetId);
220
+ return e;
221
+ }
222
+ function Ut() {
223
+ const o = st(
224
+ ({ sendBack: t, input: i }) => {
225
+ const n = () => t({ type: "RELEASE_ANNOTATE" }), r = (l) => {
226
+ l.key === "Alt" && (l.preventDefault(), t({ type: "HOLD_ANNOTATE" }));
227
+ }, a = (l) => {
228
+ l.key === "Alt" && t({ type: "RELEASE_ANNOTATE" });
229
+ }, s = Lt(window, {
230
+ [i.shortcut]: (l) => {
231
+ l.preventDefault(), t({ type: "TOGGLE" });
232
+ },
233
+ "$mod+Enter": (l) => {
234
+ l.preventDefault(), t({ type: "CLOSE" });
235
+ },
236
+ "$mod+Shift+Backspace": (l) => {
237
+ l.preventDefault(), t({ type: "DELETE" });
238
+ },
239
+ Escape: (l) => {
240
+ l.preventDefault(), t({ type: "CLOSE" });
241
+ }
242
+ });
243
+ return window.addEventListener("keydown", r), window.addEventListener("keyup", a), window.addEventListener("blur", n), () => {
244
+ s(), window.removeEventListener("keydown", r), window.removeEventListener("keyup", a), window.removeEventListener("blur", n);
245
+ };
246
+ }
247
+ ), e = st(({ sendBack: t, input: i }) => {
248
+ const n = new MutationObserver((r) => {
249
+ for (const a of r)
250
+ for (const s of Array.from(a.removedNodes))
251
+ if (s instanceof HTMLElement && (s === i.targetElement || s.contains(i.targetElement))) {
252
+ t({ type: "TARGET_DISCONNECTED" });
253
+ return;
254
+ }
255
+ });
256
+ return n.observe(i.wrapperElement, { childList: !0, subtree: !0 }), () => n.disconnect();
257
+ });
258
+ return It({
259
+ types: {
260
+ context: {},
261
+ events: {},
262
+ input: {},
263
+ emitted: {}
264
+ },
265
+ actors: {
266
+ keyboardActor: o,
267
+ mutationObserverActor: e
268
+ },
269
+ guards: {
270
+ isCommentingEditing: St({ commenting: "editing" }),
271
+ hasSelectionCommentId: ({ event: t }) => t.type !== "CLICK" ? !1 : !!t.selectionCommentId,
272
+ hasTargetId: ({ event: t }) => t.type !== "CLICK" ? !1 : !!t.targetId && !t.selectionCommentId,
273
+ hasNoTarget: ({ event: t }) => t.type !== "CLICK" ? !1 : !t.targetId && !t.selectionCommentId,
274
+ isSameComment: ({ context: t, event: i }) => {
275
+ if (i.type !== "CLICK") return !1;
276
+ if (i.selectionCommentId)
277
+ return t.editingCommentId === i.selectionCommentId;
278
+ if (i.targetId) {
279
+ const n = t.comments.find(
280
+ (r) => r.commentId === t.editingCommentId
281
+ );
282
+ return !!n && n.targetId === i.targetId && !n.selection;
283
+ }
284
+ return !1;
285
+ }
286
+ },
287
+ delays: {
288
+ flashDuration: 500
289
+ },
290
+ actions: {
291
+ openElementComment: x(({ context: t, event: i }) => {
292
+ if (i.type !== "CLICK" || !i.targetId) return {};
293
+ const { comment: n, isNew: r } = Ht(
294
+ t.comments,
295
+ i.targetId
296
+ );
297
+ return {
298
+ comments: r ? [...t.comments, n] : t.comments,
299
+ editingCommentId: n.commentId,
300
+ targetElement: i.element ?? null,
301
+ selectionRange: null
302
+ };
303
+ }),
304
+ openSelectionComment: x(({ event: t }) => t.type !== "CLICK" || !t.selectionCommentId ? {} : {
305
+ editingCommentId: t.selectionCommentId,
306
+ targetElement: t.element ?? null,
307
+ selectionRange: null
308
+ }),
309
+ createSelectionComment: x(({ context: t, event: i }) => {
310
+ if (i.type !== "SELECT_TEXT") return {};
311
+ const n = {
312
+ commentId: crypto.randomUUID(),
313
+ targetId: i.targetId,
314
+ content: "",
315
+ createdAt: (/* @__PURE__ */ new Date()).toISOString(),
316
+ selection: i.selectionRange
317
+ };
318
+ return {
319
+ comments: [...t.comments, n],
320
+ editingCommentId: n.commentId,
321
+ targetElement: i.targetElement,
322
+ selectionRange: i.selectionRange
323
+ };
324
+ }),
325
+ updateContent: x(({ context: t, event: i }) => i.type !== "COMMENT_CHANGE" ? {} : t.editingCommentId === null ? { overallComment: i.content } : {
326
+ comments: t.comments.map(
327
+ (n) => n.commentId === t.editingCommentId ? { ...n, content: i.content } : n
328
+ )
329
+ }),
330
+ deleteComment: x(({ context: t }) => ({
331
+ comments: t.comments.filter(
332
+ (i) => i.commentId !== t.editingCommentId
333
+ ),
334
+ editingCommentId: null,
335
+ targetElement: null,
336
+ selectionRange: null
337
+ })),
338
+ cleanup: x(({ context: t }) => Gt(t)),
339
+ emitChanged: lt(({ context: t }) => ({
340
+ type: "REVIEW_CHANGED",
341
+ result: ht(t)
342
+ })),
343
+ emitSubmitted: lt(({ context: t }) => ({
344
+ type: "REVIEW_SUBMITTED",
345
+ result: ht(t)
346
+ })),
347
+ // Highlight lifecycle actions — call manager methods directly via
348
+ // callbacks passed through input. The machine owns WHEN highlights
349
+ // change; the manager owns HOW (DOM manipulation).
350
+ // Actions run synchronously during transitions — no timing gap.
351
+ // Never add useEffects that react to derived machine state.
352
+ highlightsActivate: ({ context: t }) => {
353
+ t.highlights.activate(jt(t));
354
+ },
355
+ highlightsDeactivate: ({ context: t }) => {
356
+ t.highlights.deactivate();
357
+ },
358
+ highlightsRevealFlash: ({ context: t }) => {
359
+ t.highlights.reveal(!0);
360
+ },
361
+ highlightsReveal: ({ context: t }) => {
362
+ t.highlights.reveal(!1);
363
+ },
364
+ highlightsUnreveal: ({ context: t }) => {
365
+ t.highlights.unreveal();
366
+ },
367
+ editingTargetSet: ({ context: t }) => {
368
+ var n;
369
+ if (!t.targetElement) return;
370
+ const i = !!((n = t.comments.find(
371
+ (r) => r.commentId === t.editingCommentId
372
+ )) != null && n.selection);
373
+ t.highlights.setEditing(t.targetElement, i);
374
+ },
375
+ editingTargetCleared: ({ context: t }) => {
376
+ if (!t.targetElement) return;
377
+ const i = t.comments.find(
378
+ (n) => n.commentId === t.editingCommentId
379
+ );
380
+ t.highlights.clearEditing(
381
+ t.targetElement,
382
+ !!(i != null && i.content.trim())
383
+ );
384
+ }
385
+ }
386
+ }).createMachine({
387
+ id: "review",
388
+ type: "parallel",
389
+ context: ({ input: t }) => {
390
+ var r, a;
391
+ const i = ((r = t.initialData) == null ? void 0 : r.status) === "commented" ? t.initialData.comments ?? [] : [], n = ((a = t.initialData) == null ? void 0 : a.status) === "commented" ? t.initialData.overallComment ?? "" : "";
392
+ return {
393
+ comments: i,
394
+ overallComment: n,
395
+ editingCommentId: null,
396
+ targetElement: null,
397
+ selectionRange: null,
398
+ shortcut: t.shortcut,
399
+ defaultMode: t.defaultMode,
400
+ highlights: t.highlights
401
+ };
402
+ },
403
+ invoke: {
404
+ id: "keyboard",
405
+ src: "keyboardActor",
406
+ input: ({ context: t }) => ({ shortcut: t.shortcut })
407
+ },
408
+ states: {
409
+ annotating: {
410
+ initial: "waitingForMount",
411
+ on: {
412
+ SUBMIT: ".inactive"
413
+ },
414
+ states: {
415
+ waitingForMount: {
416
+ on: {
417
+ MOUNTED: [
418
+ {
419
+ guard: ({ context: t }) => t.defaultMode === "annotating",
420
+ target: "toggled"
421
+ },
422
+ { target: "inactive" }
423
+ ]
424
+ }
425
+ },
426
+ inactive: {
427
+ on: {
428
+ TOGGLE: "toggled",
429
+ HOLD_ANNOTATE: "held"
430
+ }
431
+ },
432
+ toggled: {
433
+ initial: "flashing",
434
+ entry: "highlightsActivate",
435
+ exit: "highlightsDeactivate",
436
+ on: {
437
+ TOGGLE: {
438
+ target: "inactive",
439
+ actions: Tt(({ enqueue: t, check: i }) => {
440
+ i("isCommentingEditing") && t.raise({ type: "CLOSE" });
441
+ })
442
+ }
443
+ },
444
+ states: {
445
+ flashing: {
446
+ entry: "highlightsRevealFlash",
447
+ exit: "highlightsUnreveal",
448
+ after: {
449
+ flashDuration: "ready"
450
+ },
451
+ on: {
452
+ HOLD_ANNOTATE: "revealing"
453
+ }
454
+ },
455
+ ready: {
456
+ on: {
457
+ HOLD_ANNOTATE: "revealing"
458
+ }
459
+ },
460
+ revealing: {
461
+ entry: "highlightsReveal",
462
+ exit: "highlightsUnreveal",
463
+ on: {
464
+ RELEASE_ANNOTATE: "ready"
465
+ }
466
+ }
467
+ }
468
+ },
469
+ held: {
470
+ initial: "revealing",
471
+ entry: "highlightsActivate",
472
+ exit: "highlightsDeactivate",
473
+ states: {
474
+ revealing: {
475
+ entry: "highlightsReveal",
476
+ exit: "highlightsUnreveal",
477
+ on: {
478
+ RELEASE_ANNOTATE: [
479
+ { guard: "isCommentingEditing", target: "lingering" },
480
+ { target: "#review.annotating.inactive" }
481
+ ]
482
+ }
483
+ },
484
+ lingering: {
485
+ on: {
486
+ CLOSE: "#review.annotating.inactive",
487
+ DELETE: "#review.annotating.inactive"
488
+ }
489
+ }
490
+ }
491
+ }
492
+ }
493
+ },
494
+ commenting: {
495
+ initial: "idle",
496
+ states: {
497
+ idle: {
498
+ on: {
499
+ CLICK: [
500
+ {
501
+ guard: "hasSelectionCommentId",
502
+ target: "editing.selection",
503
+ actions: ["openSelectionComment", "editingTargetSet"]
504
+ },
505
+ {
506
+ guard: "hasTargetId",
507
+ target: "editing.element",
508
+ actions: ["openElementComment", "editingTargetSet"]
509
+ }
510
+ ],
511
+ SELECT_TEXT: {
512
+ target: "editing.selection",
513
+ actions: ["createSelectionComment", "editingTargetSet"]
514
+ },
515
+ OPEN_OVERALL: {
516
+ target: "editing.element",
517
+ actions: x({
518
+ editingCommentId: null,
519
+ targetElement: null,
520
+ selectionRange: null
521
+ })
522
+ },
523
+ SUBMIT: {
524
+ actions: ["emitSubmitted"]
525
+ }
526
+ }
527
+ },
528
+ editing: {
529
+ initial: "element",
530
+ on: {
531
+ CLICK: [
532
+ { guard: "isSameComment" },
533
+ {
534
+ guard: "hasSelectionCommentId",
535
+ target: ".selection",
536
+ reenter: !0,
537
+ actions: [
538
+ "editingTargetCleared",
539
+ "cleanup",
540
+ "openSelectionComment",
541
+ "editingTargetSet"
542
+ ]
543
+ },
544
+ {
545
+ guard: "hasTargetId",
546
+ target: ".element",
547
+ reenter: !0,
548
+ actions: [
549
+ "editingTargetCleared",
550
+ "cleanup",
551
+ "openElementComment",
552
+ "editingTargetSet"
553
+ ]
554
+ },
555
+ {
556
+ guard: "hasNoTarget",
557
+ target: "idle",
558
+ actions: ["editingTargetCleared", "cleanup", "emitChanged"]
559
+ }
560
+ ],
561
+ SELECT_TEXT: {
562
+ target: ".selection",
563
+ reenter: !0,
564
+ actions: [
565
+ "editingTargetCleared",
566
+ "cleanup",
567
+ "createSelectionComment",
568
+ "editingTargetSet"
569
+ ]
570
+ },
571
+ COMMENT_CHANGE: {
572
+ actions: ["updateContent", "emitChanged"]
573
+ },
574
+ DELETE: {
575
+ target: "idle",
576
+ actions: [
577
+ "editingTargetCleared",
578
+ "deleteComment",
579
+ "emitChanged"
580
+ ]
581
+ },
582
+ CLOSE: {
583
+ target: "idle",
584
+ actions: ["editingTargetCleared", "cleanup", "emitChanged"]
585
+ },
586
+ TARGET_DISCONNECTED: {
587
+ target: "idle",
588
+ actions: ["editingTargetCleared", "cleanup", "emitChanged"]
589
+ },
590
+ SUBMIT: {
591
+ target: "idle",
592
+ actions: ["editingTargetCleared", "cleanup", "emitSubmitted"]
593
+ },
594
+ OPEN_OVERALL: {
595
+ target: ".element",
596
+ reenter: !0,
597
+ actions: [
598
+ "editingTargetCleared",
599
+ "cleanup",
600
+ x({
601
+ editingCommentId: null,
602
+ targetElement: null,
603
+ selectionRange: null
604
+ })
605
+ ]
606
+ }
607
+ },
608
+ states: {
609
+ element: {},
610
+ selection: {}
611
+ }
612
+ }
613
+ }
614
+ }
615
+ }
616
+ });
617
+ }
618
+ const Ft = 3;
619
+ function Xt(o) {
620
+ const e = window.getSelection();
621
+ if (!e || e.isCollapsed || e.rangeCount === 0)
622
+ return null;
623
+ const t = e.getRangeAt(0), i = t.toString();
624
+ if (i.length < Ft) return null;
625
+ const n = Kt(
626
+ o,
627
+ t.startContainer,
628
+ t.startOffset
629
+ ), r = n + i.length;
630
+ if (n < 0) return null;
631
+ const a = Vt(
632
+ o.textContent ?? "",
633
+ i,
634
+ n
635
+ );
636
+ return { startOffset: n, endOffset: r, selectedText: i, matchIndex: a };
637
+ }
638
+ function gt(o, e) {
639
+ const t = o.textContent ?? "";
640
+ if (t.slice(
641
+ e.startOffset,
642
+ e.endOffset
643
+ ) === e.selectedText)
644
+ return mt(
645
+ o,
646
+ e.startOffset,
647
+ e.endOffset
648
+ );
649
+ const n = Bt(
650
+ t,
651
+ e.selectedText,
652
+ e.matchIndex
653
+ );
654
+ return n < 0 ? null : mt(
655
+ o,
656
+ n,
657
+ n + e.selectedText.length
658
+ );
659
+ }
660
+ function qt(o, e) {
661
+ if (o.isCollapsed || o.rangeCount === 0) return !1;
662
+ const t = o.getRangeAt(0);
663
+ return e.contains(t.startContainer) && e.contains(t.endContainer);
664
+ }
665
+ function Y(o) {
666
+ const e = o instanceof HTMLElement ? o : o.parentElement;
667
+ return (e == null ? void 0 : e.closest("[data-review-selectable]")) ?? null;
668
+ }
669
+ function Wt(o, e) {
670
+ var a;
671
+ if (o.isCollapsed || o.rangeCount === 0) return null;
672
+ const t = o.getRangeAt(0), i = t.cloneRange(), n = e.contains(t.startContainer), r = e.contains(t.endContainer);
673
+ if (n && r) return i;
674
+ if (n && !r) {
675
+ const s = Yt(e);
676
+ return s && i.setEnd(s, ((a = s.textContent) == null ? void 0 : a.length) ?? 0), i;
677
+ }
678
+ return null;
679
+ }
680
+ function Kt(o, e, t) {
681
+ var r;
682
+ const i = document.createTreeWalker(o, NodeFilter.SHOW_TEXT);
683
+ let n = 0;
684
+ for (; i.nextNode(); ) {
685
+ if (i.currentNode === e) return n + t;
686
+ n += ((r = i.currentNode.textContent) == null ? void 0 : r.length) ?? 0;
687
+ }
688
+ return -1;
689
+ }
690
+ function mt(o, e, t) {
691
+ var s;
692
+ const i = document.createTreeWalker(o, NodeFilter.SHOW_TEXT), n = document.createRange();
693
+ let r = 0, a = !1;
694
+ for (; i.nextNode(); ) {
695
+ const l = ((s = i.currentNode.textContent) == null ? void 0 : s.length) ?? 0;
696
+ if (!a && r + l > e && (n.setStart(i.currentNode, e - r), a = !0), a && r + l >= t)
697
+ return n.setEnd(i.currentNode, t - r), n;
698
+ r += l;
699
+ }
700
+ return null;
701
+ }
702
+ function Vt(o, e, t) {
703
+ let i = 0, n = 0;
704
+ for (; ; ) {
705
+ const r = o.indexOf(e, n);
706
+ if (r < 0 || r === t) return i;
707
+ n = r + 1, i++;
708
+ }
709
+ }
710
+ function Bt(o, e, t) {
711
+ let i = 0, n = 0;
712
+ for (; ; ) {
713
+ const r = o.indexOf(e, n);
714
+ if (r < 0) return -1;
715
+ if (i === t) return r;
716
+ n = r + 1, i++;
717
+ }
718
+ }
719
+ function Yt(o) {
720
+ const e = document.createTreeWalker(o, NodeFilter.SHOW_TEXT);
721
+ let t = null;
722
+ for (; e.nextNode(); )
723
+ t = e.currentNode;
724
+ return t;
725
+ }
726
+ function Jt(o, e) {
727
+ const t = /* @__PURE__ */ new Map();
728
+ return e.querySelectorAll("[data-review-id]").forEach((n, r) => {
729
+ const a = n.getAttribute("data-review-id");
730
+ a && t.set(a, r);
731
+ }), [...o].sort((n, r) => {
732
+ const a = t.get(n.targetId) ?? Number.MAX_SAFE_INTEGER, s = t.get(r.targetId) ?? Number.MAX_SAFE_INTEGER;
733
+ return a - s;
734
+ });
735
+ }
736
+ function k(...o) {
737
+ return Mt(Dt(o));
738
+ }
739
+ function P(o) {
740
+ return v`<svg
741
+ xmlns="http://www.w3.org/2000/svg"
742
+ viewBox="0 0 24 24"
743
+ fill="none"
744
+ stroke="currentColor"
745
+ stroke-width="2"
746
+ stroke-linecap="round"
747
+ stroke-linejoin="round"
748
+ aria-hidden="true"
749
+ >
750
+ ${o}
751
+ </svg>`;
752
+ }
753
+ const U = {
754
+ check: P(_`<path d="M20 6 9 17l-5-5" />`),
755
+ gripVertical: P(
756
+ _`<circle cx="9" cy="12" r="1" /><circle cx="9" cy="5" r="1" /><circle cx="9" cy="19" r="1" /><circle cx="15" cy="12" r="1" /><circle cx="15" cy="5" r="1" /><circle cx="15" cy="19" r="1" />`
757
+ ),
758
+ messageSquare: P(
759
+ _`<path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z" />`
760
+ ),
761
+ trash: P(
762
+ _`<path d="M3 6h18" /><path d="M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2" />`
763
+ )
764
+ }, Qt = '/*! tailwindcss v4.3.1 | MIT License | https://tailwindcss.com */@layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-translate-x:0;--tw-translate-y:0;--tw-translate-z:0;--tw-rotate-x:initial;--tw-rotate-y:initial;--tw-rotate-z:initial;--tw-skew-x:initial;--tw-skew-y:initial;--tw-space-y-reverse:0;--tw-border-style:solid;--tw-leading:initial;--tw-font-weight:initial;--tw-shadow:0 0 #0000;--tw-shadow-color:initial;--tw-shadow-alpha:100%;--tw-inset-shadow:0 0 #0000;--tw-inset-shadow-color:initial;--tw-inset-shadow-alpha:100%;--tw-ring-color:initial;--tw-ring-shadow:0 0 #0000;--tw-inset-ring-color:initial;--tw-inset-ring-shadow:0 0 #0000;--tw-ring-inset:initial;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-offset-shadow:0 0 #0000;--tw-outline-style:solid;--tw-blur:initial;--tw-brightness:initial;--tw-contrast:initial;--tw-grayscale:initial;--tw-hue-rotate:initial;--tw-invert:initial;--tw-opacity:initial;--tw-saturate:initial;--tw-sepia:initial;--tw-drop-shadow:initial;--tw-drop-shadow-color:initial;--tw-drop-shadow-alpha:100%;--tw-drop-shadow-size:initial;--tw-duration:initial}}}@layer theme{:root,:host{--font-sans:ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";--font-mono:ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;--color-zinc-50:oklch(98.5% 0 0);--color-zinc-100:oklch(96.7% .001 286.375);--color-zinc-200:oklch(92% .004 286.32);--color-zinc-300:oklch(87.1% .006 286.286);--color-zinc-400:oklch(70.5% .015 286.067);--color-zinc-500:oklch(55.2% .016 285.938);--color-zinc-600:oklch(44.2% .017 285.786);--color-zinc-700:oklch(37% .013 285.805);--color-zinc-800:oklch(27.4% .006 286.033);--color-zinc-900:oklch(21% .006 285.885);--color-zinc-950:oklch(14.1% .005 285.823);--color-white:#fff;--spacing:.25rem;--container-2xl:42rem;--text-xs:.75rem;--text-xs--line-height:calc(1 / .75);--text-sm:.875rem;--text-sm--line-height:calc(1.25 / .875);--text-lg:1.125rem;--text-lg--line-height:calc(1.75 / 1.125);--text-2xl:1.5rem;--text-2xl--line-height:calc(2 / 1.5);--font-weight-medium:500;--font-weight-semibold:600;--font-weight-bold:700;--leading-relaxed:1.625;--radius-md:.375rem;--radius-lg:.5rem;--default-transition-duration:.15s;--default-transition-timing-function:cubic-bezier(.4, 0, .2, 1);--default-font-family:var(--font-sans);--default-mono-font-family:var(--font-mono)}}@layer base{*,:after,:before,::backdrop{box-sizing:border-box;border:0 solid;margin:0;padding:0}::file-selector-button{box-sizing:border-box;border:0 solid;margin:0;padding:0}html,:host{-webkit-text-size-adjust:100%;-moz-tab-size:4;tab-size:4;line-height:1.5;font-family:var(--default-font-family,ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji");font-feature-settings:var(--default-font-feature-settings,normal);font-variation-settings:var(--default-font-variation-settings,normal);-webkit-tap-highlight-color:transparent}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;-webkit-text-decoration:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:var(--default-mono-font-family,ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace);font-feature-settings:var(--default-mono-font-feature-settings,normal);font-variation-settings:var(--default-mono-font-variation-settings,normal);font-size:1em}small{font-size:80%}sub,sup{vertical-align:baseline;font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}:-moz-focusring{outline:auto}progress{vertical-align:baseline}summary{display:list-item}ol,ul,menu{list-style:none}img,svg,video,canvas,audio,iframe,embed,object{vertical-align:middle;display:block}img,video{max-width:100%;height:auto}button,input,select,optgroup,textarea{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}::file-selector-button{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}:where(select:is([multiple],[size])) optgroup{font-weight:bolder}:where(select:is([multiple],[size])) optgroup option{padding-inline-start:20px}::file-selector-button{margin-inline-end:4px}::placeholder{opacity:1}@supports (not ((-webkit-appearance:-apple-pay-button))) or (contain-intrinsic-size:1px){::placeholder{color:currentColor}@supports (color:color-mix(in lab,red,red)){::placeholder{color:color-mix(in oklab,currentcolor 50%,transparent)}}}textarea{resize:vertical}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-date-and-time-value{min-height:1lh;text-align:inherit}::-webkit-datetime-edit{display:inline-flex}::-webkit-datetime-edit-fields-wrapper{padding:0}::-webkit-datetime-edit{padding-block:0}::-webkit-datetime-edit-year-field{padding-block:0}::-webkit-datetime-edit-month-field{padding-block:0}::-webkit-datetime-edit-day-field{padding-block:0}::-webkit-datetime-edit-hour-field{padding-block:0}::-webkit-datetime-edit-minute-field{padding-block:0}::-webkit-datetime-edit-second-field{padding-block:0}::-webkit-datetime-edit-millisecond-field{padding-block:0}::-webkit-datetime-edit-meridiem-field{padding-block:0}::-webkit-calendar-picker-indicator{line-height:1}:-moz-ui-invalid{box-shadow:none}button,input:where([type=button],[type=reset],[type=submit]){-webkit-appearance:button;-moz-appearance:button;appearance:button}::file-selector-button{-webkit-appearance:button;-moz-appearance:button;appearance:button}::-webkit-inner-spin-button{height:auto}::-webkit-outer-spin-button{height:auto}[hidden]:where(:not([hidden=until-found])){display:none!important}}@layer components;@layer utilities{.absolute{position:absolute}.fixed{position:fixed}.relative{position:relative}.static{position:static}.top-2{top:calc(var(--spacing) * 2)}.right-2{right:calc(var(--spacing) * 2)}.z-10{z-index:10}.z-\\[calc\\(var\\(--review-z-index\\,9998\\)\\+1\\)\\]{z-index:calc(var(--review-z-index,9998) + 1)}.container{width:100%}@media(min-width:40rem){.container{max-width:40rem}}@media(min-width:48rem){.container{max-width:48rem}}@media(min-width:64rem){.container{max-width:64rem}}@media(min-width:80rem){.container{max-width:80rem}}@media(min-width:96rem){.container{max-width:96rem}}.mb-2{margin-bottom:calc(var(--spacing) * 2)}.block{display:block}.flex{display:flex}.inline-block{display:inline-block}.inline-flex{display:inline-flex}.size-3{width:calc(var(--spacing) * 3);height:calc(var(--spacing) * 3)}.size-3\\.5{width:calc(var(--spacing) * 3.5);height:calc(var(--spacing) * 3.5)}.h-4{height:calc(var(--spacing) * 4)}.h-7{height:calc(var(--spacing) * 7)}.h-\\[18px\\]{height:18px}.max-h-\\[200px\\]{max-height:200px}.w-7{width:calc(var(--spacing) * 7)}.w-\\[400px\\]{width:400px}.w-full{width:100%}.w-px{width:1px}.max-w-0{max-width:0}.max-w-2xl{max-width:var(--container-2xl)}.min-w-\\[18px\\]{min-width:18px}.flex-1{flex:1}.translate-x-0\\.5{--tw-translate-x:calc(var(--spacing) * .5);translate:var(--tw-translate-x) var(--tw-translate-y)}.translate-x-3\\.5{--tw-translate-x:calc(var(--spacing) * 3.5);translate:var(--tw-translate-x) var(--tw-translate-y)}.transform{transform:var(--tw-rotate-x,) var(--tw-rotate-y,) var(--tw-rotate-z,) var(--tw-skew-x,) var(--tw-skew-y,)}.animate-\\[llumi-fade-in_0\\.15s_ease-out\\]{animation:.15s ease-out llumi-fade-in}.cursor-grab{cursor:grab}.cursor-pointer{cursor:pointer}.resize-none{resize:none}.items-center{align-items:center}.justify-center{justify-content:center}.gap-1{gap:var(--spacing)}.gap-1\\.5{gap:calc(var(--spacing) * 1.5)}.gap-2{gap:calc(var(--spacing) * 2)}.gap-3{gap:calc(var(--spacing) * 3)}:where(.space-y-6>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 6) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 6) * calc(1 - var(--tw-space-y-reverse)))}.overflow-hidden{overflow:hidden}.overflow-y-auto{overflow-y:auto}.rounded{border-radius:.25rem}.rounded-full{border-radius:3.40282e38px}.rounded-lg{border-radius:var(--radius-lg)}.rounded-md{border-radius:var(--radius-md)}.border{border-style:var(--tw-border-style);border-width:1px}.border-zinc-200{border-color:var(--color-zinc-200)}.border-zinc-300{border-color:var(--color-zinc-300)}.bg-transparent{background-color:#0000}.bg-white{background-color:var(--color-white)}.bg-white\\/25{background-color:#ffffff40}@supports (color:color-mix(in lab,red,red)){.bg-white\\/25{background-color:color-mix(in oklab,var(--color-white) 25%,transparent)}}.bg-zinc-100{background-color:var(--color-zinc-100)}.bg-zinc-200{background-color:var(--color-zinc-200)}.bg-zinc-300{background-color:var(--color-zinc-300)}.bg-zinc-900{background-color:var(--color-zinc-900)}.p-1{padding:var(--spacing)}.p-3{padding:calc(var(--spacing) * 3)}.p-4{padding:calc(var(--spacing) * 4)}.p-8{padding:calc(var(--spacing) * 8)}.px-1{padding-inline:var(--spacing)}.px-1\\.5{padding-inline:calc(var(--spacing) * 1.5)}.px-3{padding-inline:calc(var(--spacing) * 3)}.py-1{padding-block:var(--spacing)}.py-1\\.5{padding-block:calc(var(--spacing) * 1.5)}.pr-2{padding-right:calc(var(--spacing) * 2)}.pl-3{padding-left:calc(var(--spacing) * 3)}.text-center{text-align:center}.text-2xl{font-size:var(--text-2xl);line-height:var(--tw-leading,var(--text-2xl--line-height))}.text-lg{font-size:var(--text-lg);line-height:var(--tw-leading,var(--text-lg--line-height))}.text-sm{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.text-xs{font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height))}.text-\\[11px\\]{font-size:11px}.leading-relaxed{--tw-leading:var(--leading-relaxed);line-height:var(--leading-relaxed)}.font-bold{--tw-font-weight:var(--font-weight-bold);font-weight:var(--font-weight-bold)}.font-medium{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.font-semibold{--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold)}.text-white{color:var(--color-white)}.text-zinc-400{color:var(--color-zinc-400)}.text-zinc-500{color:var(--color-zinc-500)}.text-zinc-600{color:var(--color-zinc-600)}.text-zinc-700{color:var(--color-zinc-700)}.text-zinc-900{color:var(--color-zinc-900)}.italic{font-style:italic}.shadow{--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a), 0 1px 2px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-lg{--tw-shadow:0 10px 15px -3px var(--tw-shadow-color,#0000001a), 0 4px 6px -4px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-xl{--tw-shadow:0 20px 25px -5px var(--tw-shadow-color,#0000001a), 0 8px 10px -6px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.ring-1{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.ring-zinc-400\\/20{--tw-ring-color:#9f9fa933}@supports (color:color-mix(in lab,red,red)){.ring-zinc-400\\/20{--tw-ring-color:color-mix(in oklab, var(--color-zinc-400) 20%, transparent)}}.outline{outline-style:var(--tw-outline-style);outline-width:1px}.blur{--tw-blur:blur(8px);filter:var(--tw-blur,) var(--tw-brightness,) var(--tw-contrast,) var(--tw-grayscale,) var(--tw-hue-rotate,) var(--tw-invert,) var(--tw-saturate,) var(--tw-sepia,) var(--tw-drop-shadow,)}.transition-all{transition-property:all;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-colors{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-transform{transition-property:transform,translate,scale,rotate;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.duration-150{--tw-duration:.15s;transition-duration:.15s}.select-none{-webkit-user-select:none;user-select:none}@media(hover:hover){.group-hover\\:max-w-\\[60px\\]:is(:where(.group):hover *){max-width:60px}}.placeholder\\:text-zinc-400::placeholder{color:var(--color-zinc-400)}@media(hover:hover){.hover\\:bg-zinc-50:hover{background-color:var(--color-zinc-50)}.hover\\:bg-zinc-200:hover{background-color:var(--color-zinc-200)}.hover\\:bg-zinc-800:hover{background-color:var(--color-zinc-800)}.hover\\:bg-zinc-900:hover{background-color:var(--color-zinc-900)}.hover\\:text-white:hover{color:var(--color-white)}}.focus\\:outline-none:focus{--tw-outline-style:none;outline-style:none}.active\\:cursor-grabbing:active{cursor:grabbing}.active\\:bg-zinc-950:active{background-color:var(--color-zinc-950)}}@keyframes llumi-fade-in{0%{opacity:0;transform:translateY(4px)}to{opacity:1;transform:translateY(0)}}@property --tw-translate-x{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-y{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-z{syntax:"*";inherits:false;initial-value:0}@property --tw-rotate-x{syntax:"*";inherits:false}@property --tw-rotate-y{syntax:"*";inherits:false}@property --tw-rotate-z{syntax:"*";inherits:false}@property --tw-skew-x{syntax:"*";inherits:false}@property --tw-skew-y{syntax:"*";inherits:false}@property --tw-space-y-reverse{syntax:"*";inherits:false;initial-value:0}@property --tw-border-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-leading{syntax:"*";inherits:false}@property --tw-font-weight{syntax:"*";inherits:false}@property --tw-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-shadow-color{syntax:"*";inherits:false}@property --tw-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-inset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-shadow-color{syntax:"*";inherits:false}@property --tw-inset-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-ring-color{syntax:"*";inherits:false}@property --tw-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-ring-color{syntax:"*";inherits:false}@property --tw-inset-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-ring-inset{syntax:"*";inherits:false}@property --tw-ring-offset-width{syntax:"<length>";inherits:false;initial-value:0}@property --tw-ring-offset-color{syntax:"*";inherits:false;initial-value:#fff}@property --tw-ring-offset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-outline-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-blur{syntax:"*";inherits:false}@property --tw-brightness{syntax:"*";inherits:false}@property --tw-contrast{syntax:"*";inherits:false}@property --tw-grayscale{syntax:"*";inherits:false}@property --tw-hue-rotate{syntax:"*";inherits:false}@property --tw-invert{syntax:"*";inherits:false}@property --tw-opacity{syntax:"*";inherits:false}@property --tw-saturate{syntax:"*";inherits:false}@property --tw-sepia{syntax:"*";inherits:false}@property --tw-drop-shadow{syntax:"*";inherits:false}@property --tw-drop-shadow-color{syntax:"*";inherits:false}@property --tw-drop-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-drop-shadow-size{syntax:"*";inherits:false}@property --tw-duration{syntax:"*";inherits:false}', Zt = Ot(Qt), ot = class ot extends zt {
765
+ };
766
+ ot.styles = Zt;
767
+ let E = ot;
768
+ var te = Object.defineProperty, ee = Object.getOwnPropertyDescriptor, y = (o, e, t, i) => {
769
+ for (var n = i > 1 ? void 0 : i ? ee(e, t) : e, r = o.length - 1, a; r >= 0; r--)
770
+ (a = o[r]) && (n = (i ? a(e, t, n) : a(n)) || n);
771
+ return i && n && te(e, t, n), n;
772
+ };
773
+ const ie = {
774
+ "top-left": { top: "16px", left: "16px" },
775
+ "top-center": { top: "16px", left: "50%", translateX: "-50%" },
776
+ "top-right": { top: "16px", right: "16px" },
777
+ "bottom-left": { bottom: "16px", left: "16px" },
778
+ "bottom-center": { bottom: "16px", left: "50%", translateX: "-50%" },
779
+ "bottom-right": { bottom: "16px", right: "16px" }
780
+ };
781
+ let w = class extends E {
782
+ constructor() {
783
+ super(...arguments), this.mode = "idle", this.commentCount = 0, this.hasOverallComment = !1, this.overallCommentOpen = !1, this.barPosition = "bottom-center", this.dragOffset = null, this.dragStart = null, this.onDragStart = (o) => {
784
+ const e = this.bar.getBoundingClientRect();
785
+ this.dragStart = {
786
+ px: o.clientX,
787
+ py: o.clientY,
788
+ ox: e.left,
789
+ oy: e.top
790
+ }, window.addEventListener("pointermove", this.onDragMove), window.addEventListener("pointerup", this.onDragEnd);
791
+ }, this.onDragMove = (o) => {
792
+ if (!this.dragStart) return;
793
+ const e = this.dragStart.ox + (o.clientX - this.dragStart.px), t = this.dragStart.oy + (o.clientY - this.dragStart.py), i = 16, n = window.innerWidth - this.bar.offsetWidth - i, r = window.innerHeight - this.bar.offsetHeight - i;
794
+ this.dragOffset = {
795
+ x: Math.max(i, Math.min(e, n)),
796
+ y: Math.max(i, Math.min(t, r))
797
+ };
798
+ }, this.onDragEnd = () => {
799
+ this.dragStart = null, window.removeEventListener("pointermove", this.onDragMove), window.removeEventListener("pointerup", this.onDragEnd);
800
+ };
801
+ }
802
+ get barRoot() {
803
+ return this.bar ?? null;
804
+ }
805
+ render() {
806
+ const o = this.mode !== "idle", e = this.commentCount + (this.hasOverallComment ? 1 : 0), t = e > 0, i = ie[this.barPosition], n = this.dragOffset ? `position:fixed;left:${this.dragOffset.x}px;top:${this.dragOffset.y}px;z-index:var(--review-z-index,9998);` : `position:fixed;${i.top ? `top:${i.top};` : ""}${i.bottom ? `bottom:${i.bottom};` : ""}${i.left ? `left:${i.left};` : ""}${i.right ? `right:${i.right};` : ""}${i.translateX ? `transform:translateX(${i.translateX});` : ""}z-index:var(--review-z-index,9998);`;
807
+ return v`<div
808
+ data-bar
809
+ class=${k(
810
+ "flex items-center gap-2 rounded-full border border-zinc-200 bg-white p-1 shadow-lg",
811
+ o && "ring-1 ring-zinc-400/20"
812
+ )}
813
+ style=${n}
814
+ >
815
+ <div
816
+ class="flex h-7 w-7 cursor-grab items-center justify-center text-zinc-400 active:cursor-grabbing"
817
+ @pointerdown=${this.onDragStart}
818
+ >
819
+ <span class="size-3">${U.gripVertical}</span>
820
+ </div>
821
+
822
+ <label class="flex cursor-pointer items-center gap-2 px-1">
823
+ <span class=${k("select-none text-xs font-medium transition-colors duration-150", o ? "text-zinc-900" : "text-zinc-500")}>Annotate</span>
824
+ <button
825
+ type="button"
826
+ role="switch"
827
+ aria-checked=${o ? "true" : "false"}
828
+ data-toggle
829
+ @click=${this.onToggle}
830
+ class=${k(
831
+ "relative inline-flex h-4 w-7 items-center rounded-full transition-colors",
832
+ o ? "bg-zinc-900" : "bg-zinc-300"
833
+ )}
834
+ >
835
+ <span class=${k("inline-block size-3 transform rounded-full bg-white transition-transform", o ? "translate-x-3.5" : "translate-x-0.5")}></span>
836
+ </button>
837
+ </label>
838
+
839
+ <div class="h-4 w-px bg-zinc-200"></div>
840
+
841
+ <button
842
+ type="button"
843
+ data-overall
844
+ @click=${this.onOverallToggle}
845
+ class=${k(
846
+ "relative flex h-7 items-center gap-1.5 rounded-full px-3 text-xs font-medium",
847
+ this.hasOverallComment ? "bg-zinc-900 text-white hover:bg-zinc-800 active:bg-zinc-950" : this.overallCommentOpen ? "bg-zinc-100 hover:bg-zinc-200" : "border border-zinc-200 hover:bg-zinc-50"
848
+ )}
849
+ >
850
+ Comment
851
+ <span class="size-3.5">${U.messageSquare}</span>
852
+ </button>
853
+
854
+ <div class="h-4 w-px bg-zinc-200"></div>
855
+
856
+ <button
857
+ type="button"
858
+ data-submit
859
+ @click=${this.onSubmit}
860
+ class="flex h-7 items-center gap-1.5 rounded-full bg-zinc-900 pl-3 pr-2 text-xs font-medium text-white hover:bg-zinc-800 active:bg-zinc-950"
861
+ >
862
+ ${t ? "Submit" : "Approve"}
863
+ <span class="flex h-[18px] min-w-[18px] items-center justify-center rounded-full bg-white/25 px-1 text-[11px] font-semibold">
864
+ ${t ? e : v`<span class="size-3">${U.check}</span>`}
865
+ </span>
866
+ </button>
867
+ </div>`;
868
+ }
869
+ onToggle() {
870
+ this.dispatchEvent(
871
+ new CustomEvent("toggle", { bubbles: !0, composed: !0 })
872
+ );
873
+ }
874
+ onOverallToggle() {
875
+ this.dispatchEvent(
876
+ new CustomEvent("overall-toggle", { bubbles: !0, composed: !0 })
877
+ );
878
+ }
879
+ onSubmit() {
880
+ this.dispatchEvent(
881
+ new CustomEvent("submit", { bubbles: !0, composed: !0 })
882
+ );
883
+ }
884
+ disconnectedCallback() {
885
+ super.disconnectedCallback(), window.removeEventListener("pointermove", this.onDragMove), window.removeEventListener("pointerup", this.onDragEnd);
886
+ }
887
+ };
888
+ y([
889
+ f()
890
+ ], w.prototype, "mode", 2);
891
+ y([
892
+ f({ type: Number })
893
+ ], w.prototype, "commentCount", 2);
894
+ y([
895
+ f({ type: Boolean })
896
+ ], w.prototype, "hasOverallComment", 2);
897
+ y([
898
+ f({ type: Boolean })
899
+ ], w.prototype, "overallCommentOpen", 2);
900
+ y([
901
+ f()
902
+ ], w.prototype, "barPosition", 2);
903
+ y([
904
+ F("[data-bar]")
905
+ ], w.prototype, "bar", 2);
906
+ y([
907
+ At()
908
+ ], w.prototype, "dragOffset", 2);
909
+ w = y([
910
+ A("llumi-review-bar")
911
+ ], w);
912
+ var ne = Object.defineProperty, oe = Object.getOwnPropertyDescriptor, D = (o, e, t, i) => {
913
+ for (var n = i > 1 ? void 0 : i ? oe(e, t) : e, r = o.length - 1, a; r >= 0; r--)
914
+ (a = o[r]) && (n = (i ? a(e, t, n) : a(n)) || n);
915
+ return i && n && ne(e, t, n), n;
916
+ };
917
+ let S = class extends E {
918
+ constructor() {
919
+ super(...arguments), this.value = "", this.autoFocus = !1, this.placeholder = "Write a comment...";
920
+ }
921
+ /** Focus the inner textarea (the element itself isn't focusable). */
922
+ focus() {
923
+ var o;
924
+ (o = this.textarea) == null || o.focus();
925
+ }
926
+ render() {
927
+ return v`<textarea
928
+ rows="1"
929
+ placeholder=${this.placeholder}
930
+ .value=${this.value}
931
+ class="w-full resize-none bg-transparent text-sm text-zinc-900 placeholder:text-zinc-400 focus:outline-none max-h-[200px] overflow-y-auto"
932
+ @input=${this.onInput}
933
+ ></textarea>`;
934
+ }
935
+ onInput(o) {
936
+ const e = o.target.value;
937
+ this.autoGrow(), this.dispatchEvent(
938
+ new CustomEvent("change", {
939
+ detail: e,
940
+ bubbles: !0,
941
+ composed: !0
942
+ })
943
+ );
944
+ }
945
+ autoGrow() {
946
+ const o = this.textarea;
947
+ o && (o.style.height = "auto", o.style.height = `${o.scrollHeight}px`);
948
+ }
949
+ firstUpdated() {
950
+ this.autoFocus && this.textarea.focus(), this.autoGrow();
951
+ }
952
+ updated() {
953
+ this.autoGrow();
954
+ }
955
+ };
956
+ D([
957
+ f()
958
+ ], S.prototype, "value", 2);
959
+ D([
960
+ f({ type: Boolean })
961
+ ], S.prototype, "autoFocus", 2);
962
+ D([
963
+ f()
964
+ ], S.prototype, "placeholder", 2);
965
+ D([
966
+ F("textarea")
967
+ ], S.prototype, "textarea", 2);
968
+ S = D([
969
+ A("llumi-default-editor")
970
+ ], S);
971
+ var re = Object.defineProperty, ae = Object.getOwnPropertyDescriptor, X = (o, e, t, i) => {
972
+ for (var n = i > 1 ? void 0 : i ? ae(e, t) : e, r = o.length - 1, a; r >= 0; r--)
973
+ (a = o[r]) && (n = (i ? a(e, t, n) : a(n)) || n);
974
+ return i && n && re(e, t, n), n;
975
+ };
976
+ let z = class extends E {
977
+ constructor() {
978
+ super(...arguments), this.targetElement = null, this.value = "";
979
+ }
980
+ render() {
981
+ const o = this.value.trim().length > 0;
982
+ return v`<div
983
+ data-floating
984
+ class="z-[calc(var(--review-z-index,9998)+1)]"
985
+ style="position:absolute;top:0;left:0;"
986
+ >
987
+ <div
988
+ class=${_t({
989
+ "relative w-[400px] rounded-lg border border-zinc-200 bg-white shadow-xl": !0,
990
+ "animate-[llumi-fade-in_0.15s_ease-out]": !0
991
+ })}
992
+ >
993
+ ${o ? v`<button
994
+ type="button"
995
+ data-delete
996
+ @click=${this.onDelete}
997
+ class="group absolute top-2 right-2 z-10 flex items-center gap-1 rounded-md px-1.5 py-1 text-zinc-400 transition-all duration-150 hover:bg-zinc-900 hover:text-white"
998
+ >
999
+ <span class="size-3.5">${U.trash}</span>
1000
+ <span class="max-w-0 overflow-hidden text-xs transition-all duration-150 group-hover:max-w-[60px]">Delete</span>
1001
+ </button>` : null}
1002
+ <div class="p-3" @change=${this.onEditorChange} @cancel=${this.onCancel} @delete=${this.onDelete}>
1003
+ <slot name="editor">
1004
+ <llumi-default-editor .value=${this.value} autoFocus></llumi-default-editor>
1005
+ </slot>
1006
+ </div>
1007
+ </div>
1008
+ </div>`;
1009
+ }
1010
+ onEditorChange(o) {
1011
+ if (typeof o.detail != "string") return;
1012
+ const e = o.detail;
1013
+ o.stopPropagation(), this.dispatchEvent(
1014
+ new CustomEvent("change", { detail: e, bubbles: !0, composed: !0 })
1015
+ );
1016
+ }
1017
+ onCancel(o) {
1018
+ o.stopPropagation(), this.dispatchEvent(
1019
+ new CustomEvent("close", { bubbles: !0, composed: !0 })
1020
+ );
1021
+ }
1022
+ onDelete(o) {
1023
+ o.stopPropagation(), this.dispatchEvent(
1024
+ new CustomEvent("delete", { bubbles: !0, composed: !0 })
1025
+ );
1026
+ }
1027
+ startPositioning() {
1028
+ var t;
1029
+ const o = this.targetElement, e = this.floating;
1030
+ !o || !e || ((t = this.cleanup) == null || t.call(this), this.cleanup = pt(o, e, () => {
1031
+ ft(o, e, {
1032
+ placement: "right",
1033
+ middleware: [
1034
+ vt(12),
1035
+ wt({ padding: 16 }),
1036
+ bt({ padding: 16, crossAxis: !0 }),
1037
+ xt({
1038
+ padding: 16,
1039
+ apply({ availableWidth: i, elements: n }) {
1040
+ Object.assign(n.floating.style, {
1041
+ maxWidth: `${Math.min(400, i)}px`
1042
+ });
1043
+ }
1044
+ })
1045
+ ]
1046
+ }).then(({ x: i, y: n }) => {
1047
+ Object.assign(e.style, { left: `${i}px`, top: `${n}px` });
1048
+ });
1049
+ }));
1050
+ }
1051
+ updated(o) {
1052
+ o.has("targetElement") && (this.startPositioning(), this.focusEditor());
1053
+ }
1054
+ focusEditor() {
1055
+ const o = this.renderRoot.querySelector(
1056
+ 'slot[name="editor"]'
1057
+ ), t = ((o == null ? void 0 : o.assignedElements()) ?? [])[0] ?? this.renderRoot.querySelector("llumi-default-editor");
1058
+ t == null || t.focus();
1059
+ }
1060
+ disconnectedCallback() {
1061
+ var o;
1062
+ super.disconnectedCallback(), (o = this.cleanup) == null || o.call(this), this.cleanup = void 0;
1063
+ }
1064
+ };
1065
+ X([
1066
+ f({ attribute: !1 })
1067
+ ], z.prototype, "targetElement", 2);
1068
+ X([
1069
+ f()
1070
+ ], z.prototype, "value", 2);
1071
+ X([
1072
+ F("[data-floating]")
1073
+ ], z.prototype, "floating", 2);
1074
+ z = X([
1075
+ A("llumi-comment-dialog")
1076
+ ], z);
1077
+ var se = Object.defineProperty, le = Object.getOwnPropertyDescriptor, q = (o, e, t, i) => {
1078
+ for (var n = i > 1 ? void 0 : i ? le(e, t) : e, r = o.length - 1, a; r >= 0; r--)
1079
+ (a = o[r]) && (n = (i ? a(e, t, n) : a(n)) || n);
1080
+ return i && n && se(e, t, n), n;
1081
+ };
1082
+ let O = class extends E {
1083
+ constructor() {
1084
+ super(...arguments), this.barElement = null, this.value = "", this.onDocKeydown = (o) => {
1085
+ o.key === "Escape" && (o.preventDefault(), this.emitClose());
1086
+ }, this.onDocPointerdown = (o) => {
1087
+ const e = o.composedPath();
1088
+ this.floating && !e.includes(this.floating) && !e.includes(this) && this.emitClose();
1089
+ };
1090
+ }
1091
+ render() {
1092
+ return v`<div
1093
+ data-floating
1094
+ class="z-[calc(var(--review-z-index,9998)+1)]"
1095
+ style="position:absolute;top:0;left:0;"
1096
+ >
1097
+ <div class="w-[400px] rounded-lg border border-zinc-200 bg-white shadow-xl animate-[llumi-fade-in_0.15s_ease-out]">
1098
+ <div class="p-3" @change=${this.onEditorChange}>
1099
+ <slot name="editor">
1100
+ <llumi-default-editor
1101
+ .value=${this.value}
1102
+ autoFocus
1103
+ placeholder="Overall comment..."
1104
+ ></llumi-default-editor>
1105
+ </slot>
1106
+ </div>
1107
+ </div>
1108
+ </div>`;
1109
+ }
1110
+ onEditorChange(o) {
1111
+ if (typeof o.detail != "string") return;
1112
+ const e = o.detail;
1113
+ o.stopPropagation(), this.dispatchEvent(
1114
+ new CustomEvent("change", { detail: e, bubbles: !0, composed: !0 })
1115
+ );
1116
+ }
1117
+ emitClose() {
1118
+ this.dispatchEvent(
1119
+ new CustomEvent("close", { bubbles: !0, composed: !0 })
1120
+ );
1121
+ }
1122
+ startPositioning() {
1123
+ var t;
1124
+ const o = this.barElement, e = this.floating;
1125
+ !o || !e || ((t = this.cleanup) == null || t.call(this), this.cleanup = pt(o, e, () => {
1126
+ ft(o, e, {
1127
+ placement: "top",
1128
+ middleware: [
1129
+ vt(12),
1130
+ wt({ padding: 16 }),
1131
+ bt({ padding: 16, crossAxis: !0 }),
1132
+ xt({
1133
+ padding: 16,
1134
+ apply({ availableWidth: i, elements: n }) {
1135
+ Object.assign(n.floating.style, {
1136
+ maxWidth: `${Math.min(400, i)}px`
1137
+ });
1138
+ }
1139
+ })
1140
+ ]
1141
+ }).then(({ x: i, y: n }) => {
1142
+ Object.assign(e.style, { left: `${i}px`, top: `${n}px` });
1143
+ });
1144
+ }));
1145
+ }
1146
+ connectedCallback() {
1147
+ super.connectedCallback(), document.addEventListener("keydown", this.onDocKeydown), document.addEventListener("pointerdown", this.onDocPointerdown, !0);
1148
+ }
1149
+ updated(o) {
1150
+ o.has("barElement") && this.startPositioning();
1151
+ }
1152
+ disconnectedCallback() {
1153
+ var o;
1154
+ super.disconnectedCallback(), (o = this.cleanup) == null || o.call(this), this.cleanup = void 0, document.removeEventListener("keydown", this.onDocKeydown), document.removeEventListener("pointerdown", this.onDocPointerdown, !0);
1155
+ }
1156
+ };
1157
+ q([
1158
+ f({ attribute: !1 })
1159
+ ], O.prototype, "barElement", 2);
1160
+ q([
1161
+ f()
1162
+ ], O.prototype, "value", 2);
1163
+ q([
1164
+ F("[data-floating]")
1165
+ ], O.prototype, "floating", 2);
1166
+ O = q([
1167
+ A("llumi-overall-comment-dialog")
1168
+ ], O);
1169
+ var ce = Object.defineProperty, de = Object.getOwnPropertyDescriptor, yt = (o, e, t, i) => {
1170
+ for (var n = i > 1 ? void 0 : i ? de(e, t) : e, r = o.length - 1, a; r >= 0; r--)
1171
+ (a = o[r]) && (n = (i ? a(e, t, n) : a(n)) || n);
1172
+ return i && n && ce(e, t, n), n;
1173
+ };
1174
+ const he = "data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%23404040' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M22 17a2 2 0 0 1-2 2H6.828a2 2 0 0 0-1.414.586l-2.202 2.202A.71.71 0 0 1 2 21.286V5a2 2 0 0 1 2-2h16a2 2 0 0 1 2 2z'/%3E%3C/svg%3E";
1175
+ let it = class extends E {
1176
+ constructor() {
1177
+ super(...arguments), this.positions = [];
1178
+ }
1179
+ render() {
1180
+ return v`${Nt(
1181
+ this.positions,
1182
+ (o) => o.commentId,
1183
+ (o) => v`<button
1184
+ type="button"
1185
+ @click=${(e) => this.onClick(e, o.commentId)}
1186
+ style=${$t({
1187
+ position: "absolute",
1188
+ top: `${o.top - 10}px`,
1189
+ left: `${o.left + 2}px`,
1190
+ width: "20px",
1191
+ height: "20px",
1192
+ borderRadius: "50%",
1193
+ backgroundColor: "white",
1194
+ backgroundImage: `url("${he}")`,
1195
+ backgroundSize: "12px 12px",
1196
+ backgroundRepeat: "no-repeat",
1197
+ backgroundPosition: "center",
1198
+ boxShadow: "0 1px 3px oklch(0 0 0 / 0.1)",
1199
+ zIndex: "calc(var(--review-z-index, 9998) + 1)",
1200
+ border: "none",
1201
+ padding: "0",
1202
+ cursor: "pointer"
1203
+ })}
1204
+ ></button>`
1205
+ )}`;
1206
+ }
1207
+ onClick(o, e) {
1208
+ o.stopPropagation(), this.dispatchEvent(
1209
+ new CustomEvent("icon-click", {
1210
+ detail: e,
1211
+ bubbles: !0,
1212
+ composed: !0
1213
+ })
1214
+ );
1215
+ }
1216
+ };
1217
+ yt([
1218
+ f({ attribute: !1 })
1219
+ ], it.prototype, "positions", 2);
1220
+ it = yt([
1221
+ A("llumi-selection-comment-icons")
1222
+ ], it);
1223
+ const R = "data-review-selectable", J = "review-selection-commented", Q = "review-selection-editing", L = "review-selection-hover", ge = "$mod+Shift+M", ut = "data-llumi-review";
1224
+ let Z = !1;
1225
+ function me() {
1226
+ if (Z) return;
1227
+ if (document.querySelector(`style[${ut}]`)) {
1228
+ Z = !0;
1229
+ return;
1230
+ }
1231
+ const o = document.createElement("style");
1232
+ o.setAttribute(ut, ""), o.textContent = Rt, document.head.append(o), Z = !0;
1233
+ }
1234
+ function H() {
1235
+ if (!(typeof CSS > "u"))
1236
+ return CSS.highlights;
1237
+ }
1238
+ function tt(...o) {
1239
+ return new Highlight(
1240
+ ...o
1241
+ );
1242
+ }
1243
+ const rt = class rt extends HTMLElement {
1244
+ constructor() {
1245
+ super(...arguments), this.manager = null, this.rangeMap = /* @__PURE__ */ new Map(), this.hoveredComment = null, this.selectionJustHandled = !1, this.selectionComments = [], this.commentDialog = null, this.overallDialog = null, this.onPointerUp = () => {
1246
+ if (!this.isAnnotating()) return;
1247
+ const e = window.getSelection();
1248
+ if (!e || e.isCollapsed || e.rangeCount === 0)
1249
+ return;
1250
+ const t = e.getRangeAt(0), i = Y(t.startContainer);
1251
+ if (!i) return;
1252
+ const n = Y(t.endContainer);
1253
+ if (n && n !== i) {
1254
+ e.removeAllRanges();
1255
+ return;
1256
+ }
1257
+ if (!n || !qt(e, i)) {
1258
+ const s = Wt(e, i);
1259
+ if (!s) return;
1260
+ e.removeAllRanges(), e.addRange(s);
1261
+ }
1262
+ const r = i.getAttribute(R);
1263
+ if (!r) return;
1264
+ const a = Xt(i);
1265
+ a && (e.removeAllRanges(), this.selectionJustHandled = !0, this.actor.send({
1266
+ type: "SELECT_TEXT",
1267
+ targetId: r,
1268
+ targetElement: i,
1269
+ selectionRange: a
1270
+ }));
1271
+ }, this.onPointerMove = (e) => {
1272
+ if (!this.isAnnotating()) return;
1273
+ const t = H();
1274
+ if (!t) return;
1275
+ const i = this.caretPosition(e.clientX, e.clientY);
1276
+ if (!i) {
1277
+ this.hoveredComment && (t.delete(L), this.hoveredComment = null);
1278
+ return;
1279
+ }
1280
+ let n = null;
1281
+ for (const [r, a] of this.rangeMap)
1282
+ if (a.isPointInRange(i.offsetNode, i.offset)) {
1283
+ n = r;
1284
+ break;
1285
+ }
1286
+ if (n !== this.hoveredComment)
1287
+ if (this.hoveredComment = n, n) {
1288
+ const r = this.rangeMap.get(n);
1289
+ r && t.set(
1290
+ L,
1291
+ tt(r)
1292
+ );
1293
+ } else
1294
+ t.delete(L);
1295
+ }, this.onClickCapture = (e) => {
1296
+ if (!this.isAnnotating() || e.defaultPrevented) return;
1297
+ if (this.selectionJustHandled) {
1298
+ this.selectionJustHandled = !1, e.stopPropagation();
1299
+ return;
1300
+ }
1301
+ const t = window.getSelection();
1302
+ if (t && !t.isCollapsed) return;
1303
+ const i = this.caretPosition(e.clientX, e.clientY);
1304
+ if (i) {
1305
+ for (const [s, l] of this.rangeMap)
1306
+ if (l.isPointInRange(i.offsetNode, i.offset)) {
1307
+ const m = this.selectionComments.find(
1308
+ (b) => b.commentId === s
1309
+ );
1310
+ if (!m) continue;
1311
+ const u = Y(i.offsetNode);
1312
+ if (!u) continue;
1313
+ e.stopPropagation(), e.preventDefault(), this.actor.send({
1314
+ type: "CLICK",
1315
+ targetId: m.targetId,
1316
+ element: u,
1317
+ selectionCommentId: s
1318
+ });
1319
+ return;
1320
+ }
1321
+ }
1322
+ const n = e.target, a = n.closest(
1323
+ ".review-highlight-hover, .review-highlight-commented, .review-highlight-editing"
1324
+ );
1325
+ if (a && this.contains(a)) {
1326
+ e.stopPropagation(), e.preventDefault();
1327
+ const s = N(n, this.customTargets);
1328
+ s ? this.actor.send({
1329
+ type: "CLICK",
1330
+ targetId: s.targetId,
1331
+ element: s.element
1332
+ }) : this.actor.send({ type: "CLICK" });
1333
+ }
1334
+ }, this.onWrapperClick = (e) => {
1335
+ if (!this.contains(e.target) || !this.isAnnotating()) return;
1336
+ const t = N(e.target, this.customTargets);
1337
+ t ? (e.stopPropagation(), e.preventDefault(), this.actor.send({
1338
+ type: "CLICK",
1339
+ targetId: t.targetId,
1340
+ element: t.element
1341
+ })) : this.actor.send({ type: "CLICK" });
1342
+ }, this.onMouseOver = (e) => {
1343
+ const t = this.manager;
1344
+ if (!t || !this.isAnnotating()) return;
1345
+ const i = this.currentEditingTargetId(), n = N(
1346
+ e.target,
1347
+ this.customTargets
1348
+ );
1349
+ if (n) {
1350
+ t.applyHover(n.element, i);
1351
+ return;
1352
+ }
1353
+ const r = e.target.closest(
1354
+ "[data-review-selectable]"
1355
+ );
1356
+ r && t.applyHover(r, i);
1357
+ }, this.onMouseOut = (e) => {
1358
+ const t = this.manager;
1359
+ if (!t || !this.isAnnotating()) return;
1360
+ const i = this.currentEditingTargetId(), n = /* @__PURE__ */ new Set();
1361
+ for (const s of this.actor.getSnapshot().context.comments)
1362
+ !s.selection && s.content.trim() && n.add(s.targetId);
1363
+ const r = N(
1364
+ e.target,
1365
+ this.customTargets
1366
+ );
1367
+ if (r) {
1368
+ t.clearHover(r.element, i, n);
1369
+ return;
1370
+ }
1371
+ const a = e.target.closest(
1372
+ "[data-review-selectable]"
1373
+ );
1374
+ a && t.clearHover(a, i);
1375
+ };
1376
+ }
1377
+ get shortcut() {
1378
+ return this.getAttribute("shortcut") ?? ge;
1379
+ }
1380
+ get barPosition() {
1381
+ return this.getAttribute("bar-position") ?? "bottom-center";
1382
+ }
1383
+ get defaultMode() {
1384
+ return this.getAttribute("default-mode") === "annotating" ? "annotating" : "idle";
1385
+ }
1386
+ connectedCallback() {
1387
+ me(), this.style.position === "" && (this.style.position = "relative"), this.style.display === "" && (this.style.display = "block");
1388
+ const e = this.buildHighlightCallbacks(), t = Ut();
1389
+ this.actor = kt(t, {
1390
+ input: {
1391
+ shortcut: this.shortcut,
1392
+ initialData: this.initialData,
1393
+ defaultMode: this.defaultMode,
1394
+ highlights: e
1395
+ }
1396
+ }), this.actor.on(
1397
+ "REVIEW_CHANGED",
1398
+ (i) => this.emitResult("llumi-review-change", i.result)
1399
+ ), this.actor.on(
1400
+ "REVIEW_SUBMITTED",
1401
+ (i) => this.emitResult("llumi-review-submit", i.result)
1402
+ ), this.mountChrome(), this.actor.subscribe(() => this.syncFromSnapshot()), this.actor.start(), this.manager = Pt(this, this.customTargets), this.actor.send({ type: "MOUNTED" }), this.addEventListener("pointerup", this.onPointerUp), this.addEventListener("pointermove", this.onPointerMove), this.addEventListener("click", this.onClickCapture, !0), this.addEventListener("click", this.onWrapperClick), this.addEventListener("mouseover", this.onMouseOver), this.addEventListener("mouseout", this.onMouseOut), this.syncFromSnapshot();
1403
+ }
1404
+ disconnectedCallback() {
1405
+ var t, i, n, r, a, s;
1406
+ this.removeEventListener("pointerup", this.onPointerUp), this.removeEventListener("pointermove", this.onPointerMove), this.removeEventListener("click", this.onClickCapture, !0), this.removeEventListener("click", this.onWrapperClick), this.removeEventListener("mouseover", this.onMouseOver), this.removeEventListener("mouseout", this.onMouseOut);
1407
+ const e = H();
1408
+ e && (e.delete(J), e.delete(Q), e.delete(L)), this.icons && (this.icons.positions = []), (t = this.manager) == null || t.destroy(), this.manager = null, (i = this.actor) == null || i.stop(), (n = this.bar) == null || n.remove(), (r = this.commentDialog) == null || r.remove(), (a = this.overallDialog) == null || a.remove(), (s = this.icons) == null || s.remove();
1409
+ }
1410
+ attributeChangedCallback() {
1411
+ this.bar && (this.bar.barPosition = this.barPosition);
1412
+ }
1413
+ emitResult(e, t) {
1414
+ let i = t;
1415
+ t.status === "commented" && (i = {
1416
+ ...t,
1417
+ comments: Jt(t.comments, this)
1418
+ }), this.dispatchEvent(
1419
+ new CustomEvent(e, {
1420
+ detail: i,
1421
+ bubbles: !0,
1422
+ composed: !0
1423
+ })
1424
+ );
1425
+ }
1426
+ // --- chrome lifecycle ---
1427
+ mountChrome() {
1428
+ this.bar = document.createElement("llumi-review-bar"), this.bar.barPosition = this.barPosition, this.bar.addEventListener(
1429
+ "toggle",
1430
+ () => this.actor.send({ type: "TOGGLE" })
1431
+ ), this.bar.addEventListener("overall-toggle", () => {
1432
+ const e = this.actor.getSnapshot(), t = e.matches({ commenting: "editing" }) && e.context.editingCommentId === null;
1433
+ this.actor.send(
1434
+ t ? { type: "CLOSE" } : { type: "OPEN_OVERALL" }
1435
+ );
1436
+ }), this.bar.addEventListener(
1437
+ "submit",
1438
+ () => this.actor.send({ type: "SUBMIT" })
1439
+ ), document.body.append(this.bar), this.icons = document.createElement(
1440
+ "llumi-selection-comment-icons"
1441
+ ), this.icons.addEventListener(
1442
+ "icon-click",
1443
+ (e) => this.onIconClick(e.detail)
1444
+ ), document.body.append(this.icons);
1445
+ }
1446
+ onIconClick(e) {
1447
+ const t = this.actor.getSnapshot().context.comments.find((n) => n.commentId === e);
1448
+ if (!t) return;
1449
+ const i = this.querySelector(
1450
+ `[${R}="${t.targetId}"]`
1451
+ );
1452
+ i && this.actor.send({
1453
+ type: "CLICK",
1454
+ targetId: t.targetId,
1455
+ element: i,
1456
+ selectionCommentId: e
1457
+ });
1458
+ }
1459
+ // --- snapshot → UI sync (replaces review.component.tsx render) ---
1460
+ syncFromSnapshot() {
1461
+ const e = this.actor.getSnapshot(), { comments: t, overallComment: i, editingCommentId: n, targetElement: r } = e.context;
1462
+ this.selectionComments = t.filter(
1463
+ (g) => g.selection && g.content.trim()
1464
+ );
1465
+ const a = !e.matches({ annotating: "inactive" }), s = e.matches({ commenting: "editing" }), l = n ? t.find((g) => g.commentId === n) : null, m = s && n === null, u = t.filter((g) => g.content.trim()).length, b = i.trim().length > 0;
1466
+ this.bar.mode = a ? l ? "editing" : "commenting" : "idle", this.bar.commentCount = u, this.bar.hasOverallComment = b, this.bar.overallCommentOpen = m, this.icons.style.display = a ? "" : "none", s && l && r ? (this.commentDialog || (this.commentDialog = document.createElement(
1467
+ "llumi-comment-dialog"
1468
+ ), this.commentDialog.addEventListener(
1469
+ "change",
1470
+ (g) => this.actor.send({
1471
+ type: "COMMENT_CHANGE",
1472
+ content: g.detail
1473
+ })
1474
+ ), this.commentDialog.addEventListener(
1475
+ "delete",
1476
+ () => this.actor.send({ type: "DELETE" })
1477
+ ), this.commentDialog.addEventListener(
1478
+ "close",
1479
+ () => this.actor.send({ type: "CLOSE" })
1480
+ ), document.body.append(this.commentDialog)), this.commentDialog.targetElement = r, this.commentDialog.value = l.content) : this.commentDialog && (this.commentDialog.remove(), this.commentDialog = null), m ? (this.overallDialog || (this.overallDialog = document.createElement(
1481
+ "llumi-overall-comment-dialog"
1482
+ ), this.overallDialog.addEventListener(
1483
+ "change",
1484
+ (g) => this.actor.send({
1485
+ type: "COMMENT_CHANGE",
1486
+ content: g.detail
1487
+ })
1488
+ ), this.overallDialog.addEventListener(
1489
+ "close",
1490
+ () => this.actor.send({ type: "CLOSE" })
1491
+ ), document.body.append(this.overallDialog)), this.overallDialog.barElement = this.bar.barRoot, this.overallDialog.value = i) : this.overallDialog && (this.overallDialog.remove(), this.overallDialog = null), a && this.updateSelectionHighlights();
1492
+ }
1493
+ // --- highlight callbacks (port of use-review.ts `highlights`) ---
1494
+ buildHighlightCallbacks() {
1495
+ return {
1496
+ activate: (e) => {
1497
+ const t = this.manager;
1498
+ t && (t.activate(e), t.startObserving({
1499
+ editingTarget: this.actor.getSnapshot().context.targetElement,
1500
+ onTargetDisconnected: () => this.actor.send({ type: "CLOSE" }),
1501
+ onSelectableReconnected: () => this.updateSelectionHighlights(),
1502
+ commentedIds: e
1503
+ }));
1504
+ },
1505
+ deactivate: () => {
1506
+ const e = this.manager;
1507
+ if (!e) return;
1508
+ e.deactivate(), e.stopObserving();
1509
+ const t = H();
1510
+ t && (t.delete(J), t.delete(Q), t.delete(L)), this.rangeMap.clear(), this.icons.positions = [];
1511
+ },
1512
+ reveal: (e) => {
1513
+ var t;
1514
+ return (t = this.manager) == null ? void 0 : t.reveal(e);
1515
+ },
1516
+ unreveal: () => {
1517
+ var e;
1518
+ return (e = this.manager) == null ? void 0 : e.unreveal();
1519
+ },
1520
+ setEditing: (e, t) => {
1521
+ var i;
1522
+ (i = this.manager) == null || i.setEditing(e, t), this.updateSelectionHighlights();
1523
+ },
1524
+ clearEditing: (e, t) => {
1525
+ var i;
1526
+ (i = this.manager) == null || i.clearEditing(e, t), this.updateSelectionHighlights();
1527
+ }
1528
+ };
1529
+ }
1530
+ // --- selection highlight painting (port of updateSelectionHighlights) ---
1531
+ updateSelectionHighlights() {
1532
+ const e = H();
1533
+ if (!e) return;
1534
+ const t = tt(), i = tt(), n = /* @__PURE__ */ new Map(), r = [], a = this.actor.getSnapshot().context;
1535
+ for (const l of this.selectionComments) {
1536
+ if (!l.selection) continue;
1537
+ const m = this.querySelector(
1538
+ `[${R}="${l.targetId}"]`
1539
+ );
1540
+ if (!m) continue;
1541
+ const u = gt(m, l.selection);
1542
+ if (!u) continue;
1543
+ n.set(l.commentId, u), l.commentId === a.editingCommentId ? i.add(u) : t.add(u);
1544
+ const b = u.getClientRects(), g = b[b.length - 1];
1545
+ g && r.push({
1546
+ commentId: l.commentId,
1547
+ top: g.top + window.scrollY,
1548
+ left: g.right + window.scrollX
1549
+ });
1550
+ }
1551
+ const s = a.editingCommentId;
1552
+ if (s && !n.has(s)) {
1553
+ const l = a.comments.find(
1554
+ (m) => m.commentId === s
1555
+ );
1556
+ if (l != null && l.selection) {
1557
+ const m = this.querySelector(
1558
+ `[${R}="${l.targetId}"]`
1559
+ );
1560
+ if (m) {
1561
+ const u = gt(m, l.selection);
1562
+ u && i.add(u);
1563
+ }
1564
+ }
1565
+ }
1566
+ this.rangeMap = n, e.set(
1567
+ J,
1568
+ t
1569
+ ), e.set(Q, i), this.icons.positions = r;
1570
+ }
1571
+ isAnnotating() {
1572
+ return !this.actor.getSnapshot().matches({ annotating: "inactive" });
1573
+ }
1574
+ caretPosition(e, t) {
1575
+ if ("caretPositionFromPoint" in document) {
1576
+ const i = document.caretPositionFromPoint(e, t);
1577
+ if (i) return i;
1578
+ } else if ("caretRangeFromPoint" in document) {
1579
+ const i = document.caretRangeFromPoint(e, t);
1580
+ if (i) return { offsetNode: i.startContainer, offset: i.startOffset };
1581
+ }
1582
+ return null;
1583
+ }
1584
+ currentEditingTargetId() {
1585
+ var t;
1586
+ const e = this.actor.getSnapshot().context;
1587
+ if (e.editingCommentId)
1588
+ return ((t = e.comments.find((i) => i.commentId === e.editingCommentId)) == null ? void 0 : t.targetId) ?? void 0;
1589
+ }
1590
+ };
1591
+ rt.observedAttributes = ["bar-position", "shortcut", "default-mode"];
1592
+ let nt = rt;
1593
+ customElements.get("llumi-review") || customElements.define("llumi-review", nt);
1594
+ export {
1595
+ z as LlumiCommentDialog,
1596
+ S as LlumiDefaultEditor,
1597
+ O as LlumiOverallCommentDialog,
1598
+ nt as LlumiReview,
1599
+ w as LlumiReviewBar,
1600
+ it as LlumiSelectionCommentIcons
1601
+ };