@instructure/platform-notebook 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js ADDED
@@ -0,0 +1,761 @@
1
+ import { z as i } from "zod";
2
+ import le from "diff-match-patch";
3
+ import { useQueryClient as j, useMutation as P, useQuery as ce } from "@tanstack/react-query";
4
+ import { jsx as _ } from "react/jsx-runtime";
5
+ import { createContext as G, useContext as Y, useReducer as ue, useMemo as de } from "react";
6
+ const fe = i.object({
7
+ startContainer: i.string(),
8
+ endContainer: i.string(),
9
+ startOffset: i.number(),
10
+ endOffset: i.number()
11
+ }), ge = i.object({
12
+ start: i.number(),
13
+ end: i.number()
14
+ }), q = i.object({
15
+ selectedText: i.string(),
16
+ hasNoHighlightAnymore: i.boolean().optional(),
17
+ textPosition: ge.nullable(),
18
+ range: fe.nullable(),
19
+ pageLastModifiedAt: i.string()
20
+ });
21
+ var I = /* @__PURE__ */ ((n) => (n.IMPORTANT = "Important", n.CONFUSING = "Confusing", n))(I || {});
22
+ const M = i.enum([
23
+ "Important",
24
+ "Confusing"
25
+ /* CONFUSING */
26
+ ]), z = i.object({
27
+ startCursor: i.string().nullish(),
28
+ endCursor: i.string().nullish(),
29
+ hasNextPage: i.boolean().nullish(),
30
+ hasPreviousPage: i.boolean().nullish()
31
+ }), L = i.object({
32
+ id: i.string(),
33
+ rootAccountUuid: i.string(),
34
+ userId: i.string(),
35
+ courseId: i.string(),
36
+ objectId: i.string(),
37
+ objectType: i.string(),
38
+ userText: i.string().optional(),
39
+ reaction: i.array(M),
40
+ highlightData: q,
41
+ createdAt: i.string(),
42
+ updatedAt: i.string()
43
+ }), he = i.object({
44
+ cursor: i.string(),
45
+ node: L
46
+ });
47
+ i.object({
48
+ notes: i.object({
49
+ edges: i.array(he),
50
+ nodes: i.array(L),
51
+ pageInfo: z
52
+ })
53
+ });
54
+ const me = i.object({
55
+ type: i.string(),
56
+ id: i.string()
57
+ }), Ne = i.object({
58
+ courseId: i.string().optional(),
59
+ learningObject: me.optional(),
60
+ reactions: i.array(i.string()).optional()
61
+ }).optional();
62
+ i.object({
63
+ courseId: i.string().optional(),
64
+ filter: Ne,
65
+ pageParams: z.optional(),
66
+ direction: i.enum(["next", "prev"]).optional(),
67
+ pageSize: i.number().optional()
68
+ });
69
+ i.object({
70
+ courseId: i.string(),
71
+ objectId: i.string(),
72
+ objectType: i.string(),
73
+ userText: i.string().optional(),
74
+ reaction: i.array(M),
75
+ highlightData: q
76
+ });
77
+ i.object({
78
+ createNote: L
79
+ });
80
+ i.object({
81
+ id: i.string(),
82
+ userText: i.string().optional(),
83
+ reaction: i.array(M),
84
+ highlightData: q
85
+ });
86
+ i.object({
87
+ updateNote: L
88
+ });
89
+ i.object({
90
+ deleteNote: i.string()
91
+ });
92
+ var Z = /* @__PURE__ */ ((n) => (n[n.FORWARDS = 1] = "FORWARDS", n[n.BACKWARDS = 2] = "BACKWARDS", n))(Z || {});
93
+ class S {
94
+ constructor(e, t) {
95
+ this.start = e, this.end = t;
96
+ }
97
+ toRange() {
98
+ let e, t;
99
+ if (this.start.element === this.end.element && this.start.offset <= this.end.offset ? [e, t] = ee(this.start.element, this.start.offset, this.end.offset) : (e = this.start.resolve({
100
+ direction: 1
101
+ /* FORWARDS */
102
+ }), t = this.end.resolve({
103
+ direction: 2
104
+ /* BACKWARDS */
105
+ })), !e || !t)
106
+ return null;
107
+ const o = new Range();
108
+ return o.setStart(e.node, e.offset), o.setEnd(t.node, t.offset), o;
109
+ }
110
+ static fromRange(e) {
111
+ const t = E.fromPoint(e.startContainer, e.startOffset), o = E.fromPoint(e.endContainer, e.endOffset);
112
+ return !t || !o ? null : new S(t, o);
113
+ }
114
+ static fromOffsets(e, t, o) {
115
+ return new S(new E(e, t), new E(e, o));
116
+ }
117
+ relativeTo(e) {
118
+ return new S(this.start.relativeTo(e), this.end.relativeTo(e));
119
+ }
120
+ }
121
+ class E {
122
+ constructor(e, t) {
123
+ t < 0 && console.error("Offset is invalid"), this.element = e, this.offset = t;
124
+ }
125
+ resolve(e = {}) {
126
+ try {
127
+ return ee(this.element, this.offset)[0];
128
+ } catch (t) {
129
+ if (this.offset === 0 && e.direction !== void 0) {
130
+ const o = document.createTreeWalker(this.element.getRootNode(), NodeFilter.SHOW_TEXT);
131
+ o.currentNode = this.element;
132
+ const r = e.direction === Z.FORWARDS, s = r ? o.nextNode() : o.previousNode();
133
+ if (!s)
134
+ throw t;
135
+ return { node: s, offset: r ? 0 : s.data.length };
136
+ }
137
+ throw t;
138
+ }
139
+ }
140
+ static fromCharOffset(e, t) {
141
+ switch (e.nodeType) {
142
+ case Node.TEXT_NODE:
143
+ return E.fromPoint(e, t);
144
+ case Node.ELEMENT_NODE:
145
+ return new E(e, t);
146
+ default:
147
+ return console.error("Node is not an element or text node"), null;
148
+ }
149
+ }
150
+ static fromPoint(e, t) {
151
+ switch (e.nodeType) {
152
+ case Node.TEXT_NODE: {
153
+ if (t < 0 || t > e.data.length)
154
+ return console.error("Text node offset is out of range"), null;
155
+ if (!e.parentElement)
156
+ return console.error("Text node has no parent"), null;
157
+ const o = V(e) + t;
158
+ return new E(e.parentElement, o);
159
+ }
160
+ case Node.ELEMENT_NODE: {
161
+ if (t < 0 || t > e.childNodes.length)
162
+ return console.error("Child node offset is out of range"), null;
163
+ let o = 0;
164
+ for (let r = 0; r < t; r++)
165
+ o += J(e.childNodes[r]);
166
+ return new E(e, o);
167
+ }
168
+ default:
169
+ return console.error("Point is not in an element or text node"), null;
170
+ }
171
+ }
172
+ relativeTo(e) {
173
+ if (!e.contains(this.element))
174
+ throw new Error("Parent is not an ancestor of current element");
175
+ let t = this.element, o = this.offset;
176
+ for (; t !== e; )
177
+ o += V(t), t.parentElement && (t = t.parentElement);
178
+ return new E(t, o);
179
+ }
180
+ }
181
+ const pe = (n) => {
182
+ const e = n.nodeName.toLowerCase();
183
+ return e === "#text" ? "text()" : e;
184
+ };
185
+ function ye(n) {
186
+ let e = 0, t = n;
187
+ for (; t; )
188
+ t.nodeName === n.nodeName && (e += 1), t = t.previousSibling;
189
+ return e;
190
+ }
191
+ const Ee = (n) => {
192
+ const e = pe(n), t = ye(n);
193
+ return `${e}[${t}]`;
194
+ }, K = (n, e) => {
195
+ let t = "", o = n;
196
+ for (; o !== e; ) {
197
+ if (!o) {
198
+ console.error("Node is not a descendant of root");
199
+ return;
200
+ }
201
+ t = `${Ee(o)}/${t}`, o = o.parentNode;
202
+ }
203
+ return t = `/${t}`, t = t.replace(/\/$/, ""), t;
204
+ }, Se = (n, e, t) => {
205
+ const o = e.toUpperCase();
206
+ let r = -1;
207
+ for (let s = 0; s < n.children.length; s++) {
208
+ const a = n.children[s];
209
+ if (a.nodeName.toUpperCase() === o && (++r, r === t))
210
+ return a;
211
+ }
212
+ return null;
213
+ }, be = (n, e) => {
214
+ if (!(n.match(/^(\/[A-Za-z0-9-]+(\[[0-9]+])?)+$/) !== null))
215
+ return console.error("Expression is not a simple XPath"), null;
216
+ const o = n.split("/");
217
+ let r = e;
218
+ o.shift();
219
+ for (const s of o) {
220
+ let a, c;
221
+ const u = s.indexOf("[");
222
+ if (u !== -1) {
223
+ a = s.slice(0, u);
224
+ const h = s.slice(u + 1, s.indexOf("]"));
225
+ if (c = Number.parseInt(h, 10) - 1, c < 0)
226
+ return null;
227
+ } else
228
+ a = s, c = 0;
229
+ const d = Se(r, a, c);
230
+ if (!d)
231
+ return null;
232
+ r = d;
233
+ }
234
+ return r;
235
+ }, Q = (n, e = document.body) => {
236
+ try {
237
+ return be(n, e);
238
+ } catch {
239
+ return document.evaluate(`.${n}`, e, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue;
240
+ }
241
+ };
242
+ class A {
243
+ constructor(e, t) {
244
+ this.root = e, this.range = t;
245
+ }
246
+ static fromRange(e, t) {
247
+ return new A(e, t);
248
+ }
249
+ static fromSelector(e, t) {
250
+ if (!(t != null && t.startContainer) || !(t != null && t.endContainer))
251
+ return console.error("No start or end container in selector"), null;
252
+ const o = Q(t.startContainer, e);
253
+ if (!o)
254
+ return console.error("Failed to resolve startContainer XPath"), null;
255
+ const r = Q(t.endContainer, e);
256
+ if (!r)
257
+ return console.error("Failed to resolve endContainer XPath"), null;
258
+ const s = E.fromCharOffset(o, t.startOffset), a = E.fromCharOffset(r, t.endOffset);
259
+ if (!s || !a)
260
+ return null;
261
+ const c = new S(s, a).toRange();
262
+ return c ? new A(e, c) : null;
263
+ }
264
+ toRange() {
265
+ return this.range;
266
+ }
267
+ toSelector() {
268
+ var s;
269
+ const e = (s = S.fromRange(this.range)) == null ? void 0 : s.toRange(), t = e && S.fromRange(e), o = t && K(t.start.element, this.root), r = t && K(t.end.element, this.root);
270
+ return !o || !r ? null : {
271
+ startContainer: o,
272
+ startOffset: t.start.offset,
273
+ endContainer: r,
274
+ endOffset: t.end.offset
275
+ };
276
+ }
277
+ }
278
+ class v {
279
+ constructor(e, t, o) {
280
+ this.root = e, this.start = t, this.end = o;
281
+ }
282
+ static fromRange(e, t) {
283
+ var r;
284
+ const o = (r = S.fromRange(t)) == null ? void 0 : r.relativeTo(e);
285
+ return o ? new v(e, o.start.offset, o.end.offset) : null;
286
+ }
287
+ static fromSelector(e, t) {
288
+ return new v(e, t.start, t.end);
289
+ }
290
+ toSelector() {
291
+ return {
292
+ start: this.start,
293
+ end: this.end
294
+ };
295
+ }
296
+ toRange() {
297
+ return S.fromOffsets(this.root, this.start, this.end).toRange();
298
+ }
299
+ }
300
+ const J = (n) => {
301
+ var e;
302
+ switch (n.nodeType) {
303
+ case Node.ELEMENT_NODE:
304
+ case Node.TEXT_NODE:
305
+ return ((e = n.textContent) == null ? void 0 : e.length) ?? 0;
306
+ default:
307
+ return 0;
308
+ }
309
+ }, V = (n) => {
310
+ let e = n.previousSibling, t = 0;
311
+ for (; e; )
312
+ t += J(e), e = e.previousSibling;
313
+ return t;
314
+ }, ee = (n, ...e) => {
315
+ let t = e.shift();
316
+ const o = n.ownerDocument.createNodeIterator(n, NodeFilter.SHOW_TEXT), r = [];
317
+ let s = o.nextNode(), a = null, c = 0;
318
+ for (; t !== void 0 && s; )
319
+ a = s, c + a.data.length > t ? (r.push({ node: a, offset: t - c }), t = e.shift()) : (s = o.nextNode(), c += a.data.length);
320
+ for (; t !== void 0 && a && c === t; )
321
+ r.push({ node: a, offset: a.data.length }), t = e.shift();
322
+ return t !== void 0 && console.error("Offset exceeds text length"), r;
323
+ }, Te = (n, e, t, o) => {
324
+ const r = t - e;
325
+ return Math.abs(r - o) <= 5 ? v.fromSelector(n, {
326
+ start: e,
327
+ end: t
328
+ }) : null;
329
+ }, Ce = (n, e, t, o) => {
330
+ const r = new le();
331
+ r.Match_Distance = 5e3;
332
+ const s = n.textContent;
333
+ if (!s)
334
+ return null;
335
+ if (e.length > 32) {
336
+ const a = e.slice(0, 32), c = e.slice(-32), u = o - t;
337
+ let d = r.match_main(s, a, t);
338
+ const h = r.match_main(s, c, o), f = h + c.length;
339
+ if (d === -1 || h === -1)
340
+ return null;
341
+ const l = f - d, m = Math.abs(l - u);
342
+ if ((d > f || m > 5) && (r.Match_Distance = e.length + 100, d = r.match_main(s, a, f), d !== -1 && d < f))
343
+ return Te(n, d, f, u);
344
+ if (d < f && m <= 5)
345
+ return v.fromSelector(n, {
346
+ start: d,
347
+ end: f
348
+ });
349
+ } else {
350
+ const a = r.match_main(s, e, t);
351
+ if (a !== -1)
352
+ return v.fromSelector(n, {
353
+ start: a,
354
+ end: a + e.length
355
+ });
356
+ }
357
+ return null;
358
+ }, ve = (n, e) => {
359
+ if (!e) return null;
360
+ const { highlightData: t } = n, { textPosition: o, selectedText: r } = t;
361
+ return Ce(
362
+ e,
363
+ r,
364
+ (o == null ? void 0 : o.start) ?? 0,
365
+ (o == null ? void 0 : o.end) ?? 0
366
+ );
367
+ }, ht = (n, e, t) => {
368
+ const o = [], r = [];
369
+ for (const s of e) {
370
+ const a = ve(s, n);
371
+ if (a) {
372
+ const c = a.toRange(), u = c && A.fromRange(n, c);
373
+ o.push({
374
+ id: s.id,
375
+ reaction: s.reaction,
376
+ userText: s.userText,
377
+ highlightData: {
378
+ ...s.highlightData,
379
+ hasNoHighlightAnymore: !1,
380
+ range: (u == null ? void 0 : u.toSelector()) ?? null,
381
+ textPosition: a.toSelector(),
382
+ pageLastModifiedAt: t
383
+ }
384
+ });
385
+ } else
386
+ s.userText ? o.push({
387
+ id: s.id,
388
+ reaction: s.reaction,
389
+ userText: s.userText,
390
+ highlightData: {
391
+ ...s.highlightData,
392
+ pageLastModifiedAt: t,
393
+ hasNoHighlightAnymore: !0
394
+ }
395
+ }) : r.push(s.id);
396
+ }
397
+ return { notesForUpdate: o, noteIdsForDelete: r };
398
+ }, mt = (n) => {
399
+ const e = document.getElementById($(n));
400
+ if (e) {
401
+ const t = e.getBoundingClientRect();
402
+ t.top >= 0 && t.left >= 0 && t.bottom <= (window.innerHeight || document.documentElement.clientHeight) && t.right <= (window.innerWidth || document.documentElement.clientWidth) || e.scrollIntoView({ behavior: "smooth", block: "start" });
403
+ }
404
+ }, R = 90, k = 172, Nt = (n) => {
405
+ const e = n.getClientRects();
406
+ if (!e.length)
407
+ return null;
408
+ const t = e[0], o = e[e.length - 1], r = 4, s = 16, a = window.innerWidth || document.documentElement.clientWidth, c = window.innerHeight || document.documentElement.clientHeight, u = (N) => {
409
+ const b = N + k;
410
+ return N >= s && b <= a - s;
411
+ }, d = (N) => {
412
+ const b = N + R;
413
+ return N >= s && b <= c - s;
414
+ };
415
+ let h;
416
+ const f = t.right - k;
417
+ if (u(f))
418
+ h = f;
419
+ else {
420
+ const N = t.left;
421
+ if (u(N))
422
+ h = N;
423
+ else {
424
+ const T = (t.left + t.right) / 2 - k / 2;
425
+ u(T) ? h = T : f < s ? h = s : h = a - k - s;
426
+ }
427
+ }
428
+ let l;
429
+ const m = o.bottom + r;
430
+ if (d(m))
431
+ l = m;
432
+ else {
433
+ const N = t.top - R - r;
434
+ d(N) ? l = N : m + R > c - s ? l = c - R - s : l = s;
435
+ }
436
+ return { top: l, left: h };
437
+ }, pt = (n, e) => {
438
+ for (const t of e)
439
+ if (n.start < t.end && n.end > t.start)
440
+ return !0;
441
+ return !1;
442
+ }, W = (n) => `highlight-wrapper-${n}`, $ = (n) => `${W(n)}-start`, te = (n) => `${W(n)}-end`, D = (n) => `[data-highlight-id="${CSS.escape(n)}"]`, ne = (n, e) => {
443
+ const t = Number.parseInt(n.slice(1, 3), 16), o = Number.parseInt(n.slice(3, 5), 16), r = Number.parseInt(n.slice(5, 7), 16);
444
+ return `rgba(${t}, ${o}, ${r}, ${e})`;
445
+ }, Oe = (n, e) => {
446
+ var t;
447
+ try {
448
+ const o = ((t = e.nodeValue) == null ? void 0 : t.length) ?? e.childNodes.length;
449
+ return n.comparePoint(e, 0) <= 0 && n.comparePoint(e, o) >= 0;
450
+ } catch {
451
+ return !1;
452
+ }
453
+ }, we = (n) => {
454
+ var s;
455
+ if (n.collapsed)
456
+ return [];
457
+ let e = n.commonAncestorContainer;
458
+ if (e && e.nodeType !== Node.ELEMENT_NODE && (e = e.parentElement), !e)
459
+ return [];
460
+ const t = [], o = (s = e == null ? void 0 : e.ownerDocument) == null ? void 0 : s.createNodeIterator(e, NodeFilter.SHOW_TEXT);
461
+ let r = (o == null ? void 0 : o.nextNode()) || null;
462
+ for (; r; ) {
463
+ if (!Oe(n, r)) {
464
+ r = (o == null ? void 0 : o.nextNode()) || null;
465
+ continue;
466
+ }
467
+ const a = r;
468
+ if (a === n.startContainer && n.startOffset > 0) {
469
+ a.splitText(n.startOffset), r = (o == null ? void 0 : o.nextNode()) || null;
470
+ continue;
471
+ }
472
+ a === n.endContainer && n.endOffset < a.data.length && a.splitText(n.endOffset), t.push(a), r = (o == null ? void 0 : o.nextNode()) || null;
473
+ }
474
+ return t;
475
+ }, yt = (n, e, t) => {
476
+ if (n.collapsed) return;
477
+ const o = e.id ?? "", r = W(o);
478
+ if (document.getElementById($(o))) {
479
+ Ie(e, t);
480
+ return;
481
+ }
482
+ const a = e.type === I.IMPORTANT ? t.colors.importantBackground : t.colors.confusingBackground, u = e.id === e.selectedNoteId ? a : ne(a, 0.5), d = e.type === I.IMPORTANT ? t.colors.importantUnderline : t.colors.confusingUnderline, h = e.type === I.IMPORTANT ? "solid" : "dashed", f = n.toString(), l = document.createElement("span");
483
+ l.id = `${r}-start`, l.className = "highlight-marker-start", l.dataset.highlightId = o || "", l.setAttribute("role", "button"), l.setAttribute("tabindex", "0"), l.setAttribute("aria-label", f), l.style.position = "relative", l.style.fontSize = "0", l.style.lineHeight = "0", l.style.width = "0", l.style.height = "0", l.style.margin = "0", l.style.padding = "0", l.style.border = "0";
484
+ const m = document.createElement("span");
485
+ m.id = te(o), m.className = "highlight-marker-end", m.dataset.highlightId = o || "";
486
+ const N = n.cloneRange();
487
+ N.collapse(!1), N.insertNode(m);
488
+ const b = n.cloneRange();
489
+ b.collapse(!0), b.insertNode(l);
490
+ const T = document.createRange();
491
+ T.setStartAfter(l), T.setEndBefore(m);
492
+ const H = we(T).filter((g) => g.textContent && g.textContent.length > 0);
493
+ H.forEach((g, y) => {
494
+ var U;
495
+ const O = g.parentElement;
496
+ if ((O == null ? void 0 : O.dataset.highlightId) === o) return;
497
+ const F = y === 0, x = y === H.length - 1, ie = H.length === 1;
498
+ let w;
499
+ ie ? w = "single" : F ? w = "first" : x ? w = "last" : w = "middle";
500
+ const p = document.createElement("span");
501
+ p.className = "highlight-content", p.dataset.highlightId = o || "", p.dataset.position = w, p.style.backgroundColor = u, p.style.textDecorationLine = "underline", p.style.textDecorationColor = d, p.style.textDecorationStyle = h, p.style.textDecorationThickness = t.borderWidthSmall, p.style.textUnderlineOffset = t.underlineOffset, p.style.cursor = "pointer", p.addEventListener("click", (ae) => {
502
+ var X;
503
+ ae.target.tagName !== "A" && ((X = e.onClick) == null || X.call(e));
504
+ }), (U = g.parentNode) == null || U.insertBefore(p, g), p.appendChild(g);
505
+ }), l.addEventListener("click", (g) => {
506
+ var y;
507
+ g.target.tagName !== "A" && ((y = e.onClick) == null || y.call(e));
508
+ }), l.addEventListener("keydown", (g) => {
509
+ var y;
510
+ if (g.key === "Enter" || g.key === " ")
511
+ g.preventDefault(), (y = e.onClick) == null || y.call(e);
512
+ else if (g.key === "Tab" && !g.shiftKey) {
513
+ const O = document.querySelectorAll(D(o));
514
+ for (const F of O) {
515
+ const x = F.querySelector("a");
516
+ if (x) {
517
+ g.preventDefault(), x.focus();
518
+ break;
519
+ }
520
+ }
521
+ }
522
+ }), l.addEventListener("focus", () => {
523
+ document.querySelectorAll(
524
+ D(o)
525
+ ).forEach((y) => {
526
+ y.classList.add("highlight-focused");
527
+ });
528
+ }), l.addEventListener("blur", () => {
529
+ document.querySelectorAll(
530
+ D(o)
531
+ ).forEach((y) => {
532
+ y.classList.remove("highlight-focused");
533
+ });
534
+ });
535
+ };
536
+ function Ie(n, e) {
537
+ const t = n.type === I.IMPORTANT ? e.colors.importantBackground : e.colors.confusingBackground, r = n.id === n.selectedNoteId ? t : ne(t, 0.5);
538
+ document.querySelectorAll(
539
+ D(n.id ?? "")
540
+ ).forEach((a) => {
541
+ a.style.backgroundColor = r;
542
+ });
543
+ }
544
+ const Et = (n) => {
545
+ const e = n.id ?? "", t = document.getElementById($(e)), o = document.getElementById(te(e));
546
+ document.querySelectorAll(
547
+ D(e)
548
+ ).forEach((s) => {
549
+ var a;
550
+ for (; s.firstChild; )
551
+ (a = s.parentNode) == null || a.insertBefore(s.firstChild, s);
552
+ s.remove();
553
+ }), t == null || t.remove(), o == null || o.remove();
554
+ }, C = {
555
+ all: ["notebook"],
556
+ notes: (n) => ["notebook", "notes", n]
557
+ };
558
+ function St(n) {
559
+ const e = j();
560
+ return P({
561
+ mutationFn: (t) => n.createNote(t),
562
+ onSuccess: () => {
563
+ e.invalidateQueries({ queryKey: C.all });
564
+ }
565
+ });
566
+ }
567
+ function bt(n) {
568
+ const e = j();
569
+ return P({
570
+ mutationFn: (t) => n.deleteNote(t),
571
+ onSuccess: () => {
572
+ e.invalidateQueries({ queryKey: C.all });
573
+ }
574
+ });
575
+ }
576
+ function Tt({
577
+ api: n,
578
+ enabled: e = !0,
579
+ ...t
580
+ }) {
581
+ return ce({
582
+ queryKey: C.notes(t),
583
+ queryFn: () => n.getNotes(t),
584
+ enabled: e
585
+ });
586
+ }
587
+ function Ct(n) {
588
+ const e = j();
589
+ return P({
590
+ mutationFn: ({ id: t, input: o }) => n.updateNote(t, o),
591
+ onMutate: async ({ id: t, input: o }) => {
592
+ await e.cancelQueries({ queryKey: C.all });
593
+ const s = e.getQueryCache().findAll({ queryKey: C.all }), a = /* @__PURE__ */ new Map();
594
+ for (const c of s) {
595
+ const u = c.state.data;
596
+ u && (a.set(c.queryKey, u), e.setQueryData(c.queryKey, {
597
+ ...u,
598
+ notes: u.notes.map(
599
+ (d) => d.id === t ? { ...d, ...o, updatedAt: (/* @__PURE__ */ new Date()).toISOString() } : d
600
+ )
601
+ }));
602
+ }
603
+ return { previousData: a };
604
+ },
605
+ onError: (t, o, r) => {
606
+ if (r != null && r.previousData)
607
+ for (const [s, a] of r.previousData)
608
+ e.setQueryData(s, a);
609
+ },
610
+ onSettled: () => {
611
+ e.invalidateQueries({ queryKey: C.all });
612
+ }
613
+ });
614
+ }
615
+ const De = "Notebook", xe = "Notes", Re = "Important", ke = "Unclear", Ae = "Edit note", Le = "Save", He = "Cancel", Fe = "Delete note", _e = "Remove from Notebook", je = "Add a note (optional).", Pe = "Mark important", qe = "Mark unclear", Me = "Saved to Notebook.", We = "Note updated", $e = "Note deleted", Be = "Error saving to Notebook.", Ue = "Error updating note", Xe = "Note deletion failed", Ke = "Loading notes", Qe = "Failed to load notes", Ve = "Start capturing your notes", Ge = "Your notes from learning materials will appear here. Highlight key ideas, reflections, or questions as you learn—they'll all be saved in your Notebook for easy review later.", Ye = "Nothing here yet", ze = "Adjust your filters or create a new note to get started.", Ze = "You have no notes for the selected filter", Je = "Previous page", et = "Next page", tt = "All courses", nt = "All notes", ot = "Close Notebook panel", rt = "To use the Notebook feature, highlight an excerpt from your learning material to flag it as 'confusing' or 'important' and leave an optional note.", B = {
616
+ notebook: De,
617
+ notes: xe,
618
+ important: Re,
619
+ unclear: ke,
620
+ editNote: Ae,
621
+ save: Le,
622
+ cancel: He,
623
+ deleteNote: Fe,
624
+ removeFromNotebook: _e,
625
+ addNoteOptional: je,
626
+ markImportant: Pe,
627
+ markUnclear: qe,
628
+ savedToNotebook: Me,
629
+ noteUpdated: We,
630
+ noteDeleted: $e,
631
+ errorSavingNote: Be,
632
+ errorUpdatingNote: Ue,
633
+ noteDeletionFailed: Xe,
634
+ loadingNotes: Ke,
635
+ failedToLoadNotes: Qe,
636
+ emptyStateHeading: Ve,
637
+ emptyStateDescription: Ge,
638
+ nothingHereYet: Ye,
639
+ adjustFiltersOrCreate: ze,
640
+ noNotesForFilter: Ze,
641
+ previousPage: Je,
642
+ nextPage: et,
643
+ allCourses: tt,
644
+ allNotes: nt,
645
+ closeNotebookPanel: ot,
646
+ featureDescription: rt
647
+ }, oe = G(null);
648
+ function re(n, e) {
649
+ const t = B[n] ?? n;
650
+ return e ? t.replace(/%\{([^}]+)}/g, (o, r) => String(e[r] ?? `%{${r}}`)) : t;
651
+ }
652
+ function st({
653
+ translations: n,
654
+ translate: e,
655
+ children: t
656
+ }) {
657
+ const r = {
658
+ translations: { ...B, ...n },
659
+ translate: e ?? re
660
+ };
661
+ return /* @__PURE__ */ _(oe.Provider, { value: r, children: t });
662
+ }
663
+ function vt() {
664
+ const n = Y(oe);
665
+ return n || { translations: B, translate: re };
666
+ }
667
+ const it = {
668
+ selectedNoteId: null,
669
+ isNoteEditing: !1,
670
+ isTrayOpen: !1
671
+ };
672
+ function at(n, e) {
673
+ switch (e.type) {
674
+ case "SELECT_NOTE":
675
+ return {
676
+ ...n,
677
+ selectedNoteId: e.payload.id,
678
+ isNoteEditing: e.payload.isEditing
679
+ };
680
+ case "CLEAR_SELECTED_NOTE":
681
+ return { ...n, selectedNoteId: null, isNoteEditing: !1 };
682
+ case "SET_EDITING":
683
+ return { ...n, isNoteEditing: e.payload };
684
+ case "OPEN_TRAY":
685
+ return { ...n, isTrayOpen: !0 };
686
+ case "CLOSE_TRAY":
687
+ return { ...n, isTrayOpen: !1, selectedNoteId: null, isNoteEditing: !1 };
688
+ default:
689
+ return n;
690
+ }
691
+ }
692
+ const se = G(null);
693
+ function Ot({
694
+ api: n,
695
+ currentUserId: e,
696
+ objectId: t,
697
+ objectType: o,
698
+ courseId: r,
699
+ pageLastModifiedAt: s,
700
+ onAnalyticsEvent: a,
701
+ translations: c,
702
+ translate: u,
703
+ children: d
704
+ }) {
705
+ const [h, f] = ue(at, it), l = de(
706
+ () => ({
707
+ api: n,
708
+ currentUserId: e,
709
+ objectId: t,
710
+ objectType: o,
711
+ courseId: r,
712
+ pageLastModifiedAt: s,
713
+ onAnalyticsEvent: a,
714
+ ...h,
715
+ selectNote: (m, N = !1) => f({ type: "SELECT_NOTE", payload: { id: m, isEditing: N } }),
716
+ clearSelectedNote: () => f({ type: "CLEAR_SELECTED_NOTE" }),
717
+ setEditing: (m) => f({ type: "SET_EDITING", payload: m }),
718
+ openTray: () => f({ type: "OPEN_TRAY" }),
719
+ closeTray: () => f({ type: "CLOSE_TRAY" })
720
+ }),
721
+ [
722
+ n,
723
+ e,
724
+ t,
725
+ o,
726
+ r,
727
+ s,
728
+ a,
729
+ h
730
+ ]
731
+ );
732
+ return /* @__PURE__ */ _(se.Provider, { value: l, children: /* @__PURE__ */ _(st, { translations: c, translate: u, children: d }) });
733
+ }
734
+ function wt() {
735
+ const n = Y(se);
736
+ if (!n)
737
+ throw new Error("useNotebook must be used within a NotebookProvider");
738
+ return n;
739
+ }
740
+ export {
741
+ Ot as NotebookProvider,
742
+ I as REACTION_TYPE,
743
+ A as RangeAnchor,
744
+ E as TextPosition,
745
+ v as TextPositionAnchor,
746
+ S as TextRange,
747
+ yt as addHighlight,
748
+ Nt as getPlacement,
749
+ pt as isOverlapping,
750
+ Q as nodeFromXPath,
751
+ ht as recoverHighlights,
752
+ Et as removeHighlights,
753
+ mt as scrollToHighlight,
754
+ St as useCreateNote,
755
+ bt as useDeleteNote,
756
+ Tt as useGetNotes,
757
+ wt as useNotebook,
758
+ vt as useNotebookTranslations,
759
+ Ct as useUpdateNote,
760
+ K as xpathFromNode
761
+ };