@hydralms/components 0.1.0 → 0.1.2

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.
Files changed (159) hide show
  1. package/dist/components.css +1 -1
  2. package/dist/index.cjs +1 -1
  3. package/dist/index.js +442 -110
  4. package/dist/modules/CoursePlayer/CoursePlayer.d.ts +2 -0
  5. package/dist/modules/CoursePlayer/types.d.ts +59 -0
  6. package/dist/modules/FlashcardLab/FlashcardLab.d.ts +2 -0
  7. package/dist/modules/FlashcardLab/types.d.ts +55 -0
  8. package/dist/modules/QuizModule/QuizModule.d.ts +2 -0
  9. package/dist/modules/QuizModule/types.d.ts +54 -0
  10. package/dist/modules/index.d.ts +6 -0
  11. package/dist/provider/HydraProvider.d.ts +1 -1
  12. package/dist/sections.cjs +1 -1
  13. package/dist/sections.js +261 -291
  14. package/dist/table-BrS5cDQu.js +2510 -0
  15. package/dist/table-D6AkBBEo.cjs +1 -0
  16. package/dist/ui/alert-dialog.d.ts +14 -8
  17. package/dist/ui/button.d.ts +1 -1
  18. package/dist/ui/tabs.d.ts +15 -5
  19. package/dist/ui/tooltip.d.ts +12 -5
  20. package/dist/video/index.d.ts +6 -1
  21. package/dist/video/types.d.ts +167 -0
  22. package/dist/video/video-bookmark.d.ts +2 -0
  23. package/dist/video/video-chapter-list.d.ts +2 -0
  24. package/dist/video/video-playlist-item.d.ts +2 -0
  25. package/dist/video/video-thumbnail-card.d.ts +2 -0
  26. package/dist/video/video-transcript.d.ts +2 -0
  27. package/package.json +135 -24
  28. package/src/__tests__/setup.ts +1 -0
  29. package/src/assessment-toolbar/assessment-toolbar.tsx +96 -0
  30. package/src/assessment-toolbar/index.ts +10 -0
  31. package/src/assessment-toolbar/question-navigator.tsx +86 -0
  32. package/src/assessment-toolbar/timer-display.tsx +73 -0
  33. package/src/assessment-toolbar/types.ts +92 -0
  34. package/src/assets/hydra-icon.png +0 -0
  35. package/src/assets/hydra-icon.svg +18 -0
  36. package/src/assets/hydra-lms-icon.png +0 -0
  37. package/src/assets/hydra-lms-icon.svg +9 -0
  38. package/src/common/confirm-dialog.tsx +60 -0
  39. package/src/common/due-date-display.tsx +64 -0
  40. package/src/common/empty-state.tsx +24 -0
  41. package/src/common/index.ts +12 -0
  42. package/src/common/search-input.tsx +68 -0
  43. package/src/common/status-badge.test.tsx +43 -0
  44. package/src/common/status-badge.tsx +81 -0
  45. package/src/common/types.ts +129 -0
  46. package/src/content/content-block.tsx +116 -0
  47. package/src/content/file-upload-zone.tsx +109 -0
  48. package/src/content/index.ts +7 -0
  49. package/src/content/types.ts +76 -0
  50. package/src/curriculum/curriculum-item.tsx +81 -0
  51. package/src/curriculum/curriculum-tree.tsx +69 -0
  52. package/src/curriculum/index.ts +11 -0
  53. package/src/curriculum/learning-object-icon.tsx +44 -0
  54. package/src/curriculum/types.ts +83 -0
  55. package/src/feedback/feedback-banner.tsx +46 -0
  56. package/src/feedback/index.ts +8 -0
  57. package/src/feedback/likert-scale.tsx +58 -0
  58. package/src/feedback/star-rating.tsx +65 -0
  59. package/src/feedback/types.ts +86 -0
  60. package/src/flashcards/flashcard-deck.tsx +130 -0
  61. package/src/flashcards/flashcard.tsx +108 -0
  62. package/src/flashcards/index.ts +3 -0
  63. package/src/flashcards/types.ts +60 -0
  64. package/src/index.ts +38 -0
  65. package/src/lib/utils.ts +6 -0
  66. package/src/modules/CoursePlayer/CoursePlayer.tsx +281 -0
  67. package/src/modules/CoursePlayer/types.ts +48 -0
  68. package/src/modules/FlashcardLab/FlashcardLab.tsx +275 -0
  69. package/src/modules/FlashcardLab/types.ts +58 -0
  70. package/src/modules/QuizModule/QuizModule.tsx +241 -0
  71. package/src/modules/QuizModule/types.ts +56 -0
  72. package/src/modules/index.ts +12 -0
  73. package/src/progress/grade-indicator.tsx +65 -0
  74. package/src/progress/index.ts +8 -0
  75. package/src/progress/progress-ring.tsx +56 -0
  76. package/src/progress/stat-card.tsx +42 -0
  77. package/src/progress/types.ts +73 -0
  78. package/src/provider/HydraProvider.tsx +26 -0
  79. package/src/provider/index.ts +2 -0
  80. package/src/questions/choice.tsx +90 -0
  81. package/src/questions/essay.tsx +59 -0
  82. package/src/questions/fill-in-the-blank.tsx +69 -0
  83. package/src/questions/index.ts +14 -0
  84. package/src/questions/multiple-choice.test.tsx +104 -0
  85. package/src/questions/multiple-choice.tsx +97 -0
  86. package/src/questions/question-renderer.tsx +37 -0
  87. package/src/questions/true-false.test.tsx +89 -0
  88. package/src/questions/true-false.tsx +90 -0
  89. package/src/questions/types.ts +53 -0
  90. package/src/sections/AnnouncementFeed/AnnouncementFeed.tsx +141 -0
  91. package/src/sections/AnnouncementFeed/types.ts +50 -0
  92. package/src/sections/AssessmentReview/AssessmentReview.tsx +148 -0
  93. package/src/sections/AssessmentReview/types.ts +61 -0
  94. package/src/sections/AssignmentSubmission/AssignmentSubmission.tsx +190 -0
  95. package/src/sections/AssignmentSubmission/types.ts +60 -0
  96. package/src/sections/CertificateViewer/CertificateViewer.tsx +117 -0
  97. package/src/sections/CertificateViewer/types.ts +45 -0
  98. package/src/sections/CourseOutline/CourseOutline.tsx +79 -0
  99. package/src/sections/CourseOutline/types.ts +53 -0
  100. package/src/sections/DiscussionThread/DiscussionThread.tsx +186 -0
  101. package/src/sections/DiscussionThread/types.ts +77 -0
  102. package/src/sections/ExamSession/ExamSession.tsx +182 -0
  103. package/src/sections/ExamSession/types.ts +64 -0
  104. package/src/sections/FlashcardStudySession/FlashcardStudySession.tsx +76 -0
  105. package/src/sections/FlashcardStudySession/types.ts +42 -0
  106. package/src/sections/GradebookTable/GradebookTable.tsx +229 -0
  107. package/src/sections/GradebookTable/types.ts +75 -0
  108. package/src/sections/LecturePlayer/LecturePlayer.tsx +60 -0
  109. package/src/sections/LecturePlayer/types.ts +48 -0
  110. package/src/sections/LessonPage/LessonPage.tsx +91 -0
  111. package/src/sections/LessonPage/types.ts +41 -0
  112. package/src/sections/PracticeQuiz/PracticeQuiz.tsx +199 -0
  113. package/src/sections/PracticeQuiz/types.ts +44 -0
  114. package/src/sections/ProgressDashboard/ProgressDashboard.tsx +140 -0
  115. package/src/sections/ProgressDashboard/types.ts +74 -0
  116. package/src/sections/QuizSession/QuizSession.tsx +113 -0
  117. package/src/sections/QuizSession/types.ts +47 -0
  118. package/src/sections/ResourceLibrary/ResourceLibrary.tsx +218 -0
  119. package/src/sections/ResourceLibrary/types.ts +57 -0
  120. package/src/sections/ScrollableQuiz/ScrollableQuiz.tsx +170 -0
  121. package/src/sections/ScrollableQuiz/types.ts +40 -0
  122. package/src/sections/SurveyForm/SurveyForm.tsx +180 -0
  123. package/src/sections/SurveyForm/types.ts +69 -0
  124. package/src/sections/index.ts +90 -0
  125. package/src/social/index.ts +3 -0
  126. package/src/social/post-card.tsx +91 -0
  127. package/src/social/types.ts +57 -0
  128. package/src/social/user-avatar.tsx +76 -0
  129. package/src/styles/globals.css +125 -0
  130. package/src/ui/alert-dialog.tsx +343 -0
  131. package/src/ui/alert.tsx +65 -0
  132. package/src/ui/avatar.tsx +52 -0
  133. package/src/ui/badge.tsx +53 -0
  134. package/src/ui/button.tsx +62 -0
  135. package/src/ui/card.tsx +92 -0
  136. package/src/ui/index.ts +44 -0
  137. package/src/ui/input.tsx +21 -0
  138. package/src/ui/progress.tsx +73 -0
  139. package/src/ui/separator.tsx +29 -0
  140. package/src/ui/skeleton.tsx +15 -0
  141. package/src/ui/slot.tsx +48 -0
  142. package/src/ui/table.tsx +108 -0
  143. package/src/ui/tabs.tsx +147 -0
  144. package/src/ui/textarea.tsx +20 -0
  145. package/src/ui/tooltip.tsx +177 -0
  146. package/src/utils/debounce.test.ts +59 -0
  147. package/src/utils/debounce.ts +10 -0
  148. package/src/utils/format-duration.test.ts +55 -0
  149. package/src/utils/format-duration.ts +30 -0
  150. package/src/video/index.ts +17 -0
  151. package/src/video/types.ts +216 -0
  152. package/src/video/video-bookmark.tsx +76 -0
  153. package/src/video/video-chapter-list.tsx +93 -0
  154. package/src/video/video-player.tsx +103 -0
  155. package/src/video/video-playlist-item.tsx +90 -0
  156. package/src/video/video-thumbnail-card.tsx +74 -0
  157. package/src/video/video-transcript.tsx +102 -0
  158. package/dist/table-CW4_BYny.js +0 -9869
  159. package/dist/table-DSBBqb9X.cjs +0 -56
@@ -0,0 +1,2510 @@
1
+ import { jsx as t, jsxs as u, Fragment as ee } from "react/jsx-runtime";
2
+ import { Clock as $, Flag as pe, ChevronLeft as te, Send as he, ChevronRight as H, RotateCcw as B, BookOpen as U, Code as K, Image as be, Music as xe, ExternalLink as W, MessageSquare as ve, ClipboardList as ye, HelpCircle as Z, FileText as j, PlayCircle as Ne, Video as R, CheckCircle2 as we, Circle as Ce, ChevronDown as ke, Play as G, Search as Te, X as re, CheckCircle as ne, XCircle as ze, Star as _e, Minus as Se, TrendingDown as Ie, TrendingUp as De, Pin as Le, Lightbulb as Me, AlertTriangle as Ee, Info as je, Upload as $e, File as Re } from "lucide-react";
3
+ import * as E from "react";
4
+ import { useState as v, useEffect as C, useCallback as T, useRef as k, useId as V, useLayoutEffect as Ve, isValidElement as He, cloneElement as Fe, createContext as F, useContext as P, useMemo as Pe } from "react";
5
+ import { createPortal as ae } from "react-dom";
6
+ import { cva as S } from "class-variance-authority";
7
+ import { clsx as Oe } from "clsx";
8
+ import { twMerge as Ae } from "tailwind-merge";
9
+ function m(...e) {
10
+ return Ae(Oe(e));
11
+ }
12
+ const Be = S(
13
+ "relative flex w-full items-start gap-3 rounded-lg border p-4 text-sm [&>svg]:size-4 [&>svg]:shrink-0 [&>svg]:translate-y-0.5",
14
+ {
15
+ variants: {
16
+ variant: {
17
+ default: "bg-card text-foreground",
18
+ destructive: "border-destructive/50 bg-destructive/5 text-destructive [&>svg]:text-destructive",
19
+ success: "border-success/50 bg-success/5 text-success [&>svg]:text-success",
20
+ warning: "border-warning/50 bg-warning/5 text-warning [&>svg]:text-warning",
21
+ info: "border-info/50 bg-info/5 text-info [&>svg]:text-info"
22
+ }
23
+ },
24
+ defaultVariants: {
25
+ variant: "default"
26
+ }
27
+ }
28
+ );
29
+ function I({
30
+ className: e,
31
+ variant: r,
32
+ ...n
33
+ }) {
34
+ return /* @__PURE__ */ t(
35
+ "div",
36
+ {
37
+ "data-slot": "alert",
38
+ role: "alert",
39
+ className: m(Be({ variant: r }), e),
40
+ ...n
41
+ }
42
+ );
43
+ }
44
+ function cr({ className: e, ...r }) {
45
+ return /* @__PURE__ */ t(
46
+ "div",
47
+ {
48
+ "data-slot": "alert-title",
49
+ className: m("font-medium leading-normal tracking-tight", e),
50
+ ...r
51
+ }
52
+ );
53
+ }
54
+ function D({
55
+ className: e,
56
+ ...r
57
+ }) {
58
+ return /* @__PURE__ */ t(
59
+ "div",
60
+ {
61
+ "data-slot": "alert-description",
62
+ className: m("text-foreground text-sm [&_p]:leading-relaxed", e),
63
+ ...r
64
+ }
65
+ );
66
+ }
67
+ const Ue = ({
68
+ question: e,
69
+ sessionAnswers: r,
70
+ onAnswer: n,
71
+ readOnly: a = !1,
72
+ showCorrectAnswers: s = !1,
73
+ disabled: l = !1
74
+ }) => {
75
+ const [o, i] = v([]), g = [...e.answers || []].sort(
76
+ (d, c) => d.sequence - c.sequence
77
+ ), f = (d) => {
78
+ a || l || i((c) => {
79
+ const p = c.includes(d) ? c.filter((b) => b !== d) : [...c, d];
80
+ return n == null || n(p.map((b) => ({ uid: b }))), p;
81
+ });
82
+ };
83
+ C(() => {
84
+ const d = (r == null ? void 0 : r.map((c) => c.answerUid)) || [];
85
+ i(d);
86
+ }, [r]);
87
+ const h = (d) => {
88
+ var p;
89
+ if (!s) return "";
90
+ const c = (p = e.answers) == null ? void 0 : p.find((b) => b.uid === d);
91
+ return c != null && c.isCorrect ? "bg-success/10 border border-success/30 px-2" : o.includes(d) && !(c != null && c.isCorrect) ? "bg-destructive/10 border border-destructive/30 px-2" : "";
92
+ };
93
+ return /* @__PURE__ */ u("div", { className: "flex flex-col gap-4", children: [
94
+ /* @__PURE__ */ t("div", { dangerouslySetInnerHTML: { __html: e.content } }),
95
+ /* @__PURE__ */ t("div", { className: "flex flex-col gap-2", children: g.map((d) => /* @__PURE__ */ t(
96
+ "div",
97
+ {
98
+ className: m("rounded-md transition-colors", h(d.uid)),
99
+ children: /* @__PURE__ */ u("label", { className: "flex items-center gap-2 cursor-pointer py-1 has-[input:disabled]:cursor-default has-[input:disabled]:opacity-60", children: [
100
+ /* @__PURE__ */ t(
101
+ "input",
102
+ {
103
+ type: "checkbox",
104
+ checked: o.includes(d.uid),
105
+ onChange: () => f(d.uid),
106
+ disabled: a || l,
107
+ className: "accent-primary m-0 shrink-0"
108
+ }
109
+ ),
110
+ /* @__PURE__ */ t(
111
+ "span",
112
+ {
113
+ className: "text-sm",
114
+ dangerouslySetInnerHTML: { __html: d.content }
115
+ }
116
+ )
117
+ ] })
118
+ },
119
+ d.uid
120
+ )) }),
121
+ s && e.explanation && /* @__PURE__ */ t(I, { className: "mt-2", children: /* @__PURE__ */ u(D, { children: [
122
+ /* @__PURE__ */ t("strong", { children: "Explanation:" }),
123
+ " ",
124
+ /* @__PURE__ */ t("span", { dangerouslySetInnerHTML: { __html: e.explanation } })
125
+ ] }) })
126
+ ] });
127
+ }, Ke = ({
128
+ question: e,
129
+ sessionAnswers: r,
130
+ onAnswer: n,
131
+ readOnly: a = !1,
132
+ showCorrectAnswers: s = !1,
133
+ disabled: l = !1
134
+ }) => {
135
+ const [o, i] = v(""), g = [...e.answers || []].sort(
136
+ (d, c) => d.sequence - c.sequence
137
+ ), f = (d) => {
138
+ a || l || (i(d), n == null || n([{ uid: d }]));
139
+ };
140
+ C(() => {
141
+ var c;
142
+ const d = ((c = r == null ? void 0 : r[0]) == null ? void 0 : c.answerUid) || "";
143
+ i(d);
144
+ }, [r]);
145
+ const h = (d) => {
146
+ var p;
147
+ if (!s) return "px-2";
148
+ const c = (p = e.answers) == null ? void 0 : p.find((b) => b.uid === d);
149
+ return c != null && c.isCorrect ? "bg-success/10 border border-success/30 px-2" : o === d && !(c != null && c.isCorrect) ? "bg-destructive/10 border border-destructive/30 px-2" : "px-2";
150
+ };
151
+ return /* @__PURE__ */ u("div", { className: "flex flex-col gap-4", children: [
152
+ /* @__PURE__ */ t("div", { dangerouslySetInnerHTML: { __html: e.content } }),
153
+ /* @__PURE__ */ t("div", { className: "flex flex-col gap-2", children: g.map((d) => /* @__PURE__ */ t(
154
+ "div",
155
+ {
156
+ className: m("rounded-md transition-colors", h(d.uid)),
157
+ children: /* @__PURE__ */ u("label", { className: "flex items-center gap-2 cursor-pointer py-1 has-[input:disabled]:cursor-default has-[input:disabled]:opacity-60", children: [
158
+ /* @__PURE__ */ t(
159
+ "input",
160
+ {
161
+ type: "radio",
162
+ name: e.uid,
163
+ value: d.uid,
164
+ checked: o === d.uid,
165
+ onChange: () => f(d.uid),
166
+ disabled: a || l,
167
+ className: "accent-primary m-0 shrink-0"
168
+ }
169
+ ),
170
+ /* @__PURE__ */ t("span", { dangerouslySetInnerHTML: { __html: d.content } })
171
+ ] })
172
+ },
173
+ d.uid
174
+ )) }),
175
+ s && e.explanation && /* @__PURE__ */ t(I, { className: "mt-2", children: /* @__PURE__ */ u(D, { children: [
176
+ /* @__PURE__ */ t("strong", { children: "Explanation:" }),
177
+ " ",
178
+ /* @__PURE__ */ t("span", { dangerouslySetInnerHTML: { __html: e.explanation } })
179
+ ] }) })
180
+ ] });
181
+ }, We = ({
182
+ question: e,
183
+ sessionAnswers: r,
184
+ onAnswer: n,
185
+ readOnly: a = !1,
186
+ showCorrectAnswers: s = !1,
187
+ disabled: l = !1
188
+ }) => {
189
+ const [o, i] = v(""), g = [...e.answers || []].sort(
190
+ (d, c) => d.sequence - c.sequence
191
+ ), f = (d) => {
192
+ a || l || (i(d), n == null || n([{ uid: d }]));
193
+ };
194
+ C(() => {
195
+ var c;
196
+ const d = ((c = r == null ? void 0 : r[0]) == null ? void 0 : c.answerUid) || "";
197
+ i(d);
198
+ }, [r]);
199
+ const h = (d) => {
200
+ var p;
201
+ if (!s) return "px-2";
202
+ const c = (p = e.answers) == null ? void 0 : p.find((b) => b.uid === d);
203
+ return c != null && c.isCorrect ? "bg-success/10 border border-success/30 px-2" : o === d && !(c != null && c.isCorrect) ? "bg-destructive/10 border border-destructive/30 px-2" : "px-2";
204
+ };
205
+ return /* @__PURE__ */ u("div", { className: "flex flex-col gap-4", children: [
206
+ /* @__PURE__ */ t("div", { dangerouslySetInnerHTML: { __html: e.content } }),
207
+ /* @__PURE__ */ t("div", { className: "flex flex-col gap-2", children: g.map((d) => /* @__PURE__ */ t(
208
+ "div",
209
+ {
210
+ className: m("rounded-md transition-colors", h(d.uid)),
211
+ children: /* @__PURE__ */ u("label", { className: "flex items-center gap-2 cursor-pointer py-1 has-[input:disabled]:cursor-default has-[input:disabled]:opacity-60", children: [
212
+ /* @__PURE__ */ t(
213
+ "input",
214
+ {
215
+ type: "radio",
216
+ name: e.uid,
217
+ value: d.uid,
218
+ checked: o === d.uid,
219
+ onChange: () => f(d.uid),
220
+ disabled: a || l,
221
+ className: "accent-primary m-0 shrink-0"
222
+ }
223
+ ),
224
+ /* @__PURE__ */ t("span", { dangerouslySetInnerHTML: { __html: d.content } })
225
+ ] })
226
+ },
227
+ d.uid
228
+ )) }),
229
+ s && e.explanation && /* @__PURE__ */ t(I, { className: "mt-2", children: /* @__PURE__ */ u(D, { children: [
230
+ /* @__PURE__ */ t("strong", { children: "Explanation:" }),
231
+ " ",
232
+ /* @__PURE__ */ t("span", { dangerouslySetInnerHTML: { __html: e.explanation } })
233
+ ] }) })
234
+ ] });
235
+ };
236
+ function O(e, r) {
237
+ let n;
238
+ return (...a) => {
239
+ clearTimeout(n), n = setTimeout(() => e(...a), r);
240
+ };
241
+ }
242
+ function Ze({ className: e, type: r, ...n }) {
243
+ return /* @__PURE__ */ t(
244
+ "input",
245
+ {
246
+ type: r,
247
+ "data-slot": "input",
248
+ className: m(
249
+ "file:text-foreground placeholder:text-muted-foreground selection:bg-primary selection:text-primary-foreground border-input flex h-9 w-full min-w-0 rounded-md border bg-transparent px-3 py-1 text-sm shadow-xs outline-none transition-[color,box-shadow] file:inline-flex file:h-7 file:border-0 file:bg-transparent file:text-sm file:font-medium disabled:pointer-events-none disabled:opacity-50",
250
+ "focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px]",
251
+ "aria-invalid:ring-destructive/20 aria-invalid:border-destructive",
252
+ e
253
+ ),
254
+ ...n
255
+ }
256
+ );
257
+ }
258
+ const Ge = ({
259
+ question: e,
260
+ sessionAnswers: r,
261
+ onAnswer: n,
262
+ readOnly: a = !1,
263
+ showCorrectAnswers: s = !1,
264
+ disabled: l = !1
265
+ }) => {
266
+ const [o, i] = v(""), g = T(
267
+ O((h) => {
268
+ var d, c;
269
+ n == null || n([
270
+ {
271
+ uid: ((c = (d = e.answers) == null ? void 0 : d[0]) == null ? void 0 : c.uid) || "",
272
+ content: h
273
+ }
274
+ ]);
275
+ }, 300),
276
+ [n, e.answers]
277
+ ), f = (h) => {
278
+ const d = h.target.value;
279
+ i(d), g(d);
280
+ };
281
+ return C(() => {
282
+ var h;
283
+ i(((h = r == null ? void 0 : r[0]) == null ? void 0 : h.content) || "");
284
+ }, [r]), /* @__PURE__ */ u("div", { className: "flex flex-col gap-2", children: [
285
+ /* @__PURE__ */ t("div", { dangerouslySetInnerHTML: { __html: e.content } }),
286
+ /* @__PURE__ */ t(
287
+ Ze,
288
+ {
289
+ value: o,
290
+ onChange: f,
291
+ placeholder: "Type your answer here...",
292
+ disabled: a || l
293
+ }
294
+ ),
295
+ s && e.explanation && /* @__PURE__ */ t(I, { className: "mt-1", children: /* @__PURE__ */ u(D, { children: [
296
+ /* @__PURE__ */ t("strong", { children: "Explanation:" }),
297
+ " ",
298
+ /* @__PURE__ */ t("span", { dangerouslySetInnerHTML: { __html: e.explanation } })
299
+ ] }) })
300
+ ] });
301
+ };
302
+ function Ye({ className: e, ...r }) {
303
+ return /* @__PURE__ */ t(
304
+ "textarea",
305
+ {
306
+ "data-slot": "textarea",
307
+ className: m(
308
+ "placeholder:text-muted-foreground border-input flex min-h-16 w-full rounded-md border bg-transparent px-3 py-2 text-sm shadow-xs outline-none transition-[color,box-shadow] disabled:pointer-events-none disabled:opacity-50",
309
+ "focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px]",
310
+ "aria-invalid:ring-destructive/20 aria-invalid:border-destructive",
311
+ e
312
+ ),
313
+ ...r
314
+ }
315
+ );
316
+ }
317
+ const Xe = ({
318
+ question: e,
319
+ sessionAnswers: r,
320
+ onAnswer: n,
321
+ readOnly: a = !1,
322
+ disabled: s = !1
323
+ }) => {
324
+ const [l, o] = v(""), i = T(
325
+ O((f) => {
326
+ var h, d;
327
+ n == null || n([
328
+ {
329
+ uid: ((d = (h = e.answers) == null ? void 0 : h[0]) == null ? void 0 : d.uid) || e.uid,
330
+ content: f
331
+ }
332
+ ]);
333
+ }, 500),
334
+ [n, e.answers, e.uid]
335
+ ), g = (f) => {
336
+ const h = f.target.value;
337
+ o(h), i(h);
338
+ };
339
+ return C(() => {
340
+ var f;
341
+ o(((f = r == null ? void 0 : r[0]) == null ? void 0 : f.content) || "");
342
+ }, [r]), /* @__PURE__ */ u("div", { className: "flex flex-col gap-2", children: [
343
+ /* @__PURE__ */ t("div", { dangerouslySetInnerHTML: { __html: e.content } }),
344
+ /* @__PURE__ */ t(
345
+ Ye,
346
+ {
347
+ className: "min-h-30 resize-y",
348
+ value: l,
349
+ onChange: g,
350
+ placeholder: "Write your response here...",
351
+ disabled: a || s
352
+ }
353
+ )
354
+ ] });
355
+ }, Je = (e) => {
356
+ switch (e.question.type) {
357
+ case "multiple_choice":
358
+ return /* @__PURE__ */ t(Ue, { ...e });
359
+ case "choice":
360
+ return /* @__PURE__ */ t(Ke, { ...e });
361
+ case "true_false":
362
+ return /* @__PURE__ */ t(We, { ...e });
363
+ case "fill_in_the_blank":
364
+ return /* @__PURE__ */ t(Ge, { ...e });
365
+ case "essay":
366
+ return /* @__PURE__ */ t(Xe, { ...e });
367
+ default:
368
+ return /* @__PURE__ */ u("p", { className: "text-muted-foreground", children: [
369
+ "Question type “",
370
+ e.question.type,
371
+ "” is not supported yet."
372
+ ] });
373
+ }
374
+ }, Qe = (e) => {
375
+ if (e < 1)
376
+ return "-";
377
+ const r = Math.floor(e / 3600), n = Math.floor(e % 3600 / 60), a = e % 60, s = [];
378
+ return r > 0 && s.push(`${r}h`), n > 0 && s.push(`${n}m`), a > 0 && s.push(`${a}s`), s.join(" ");
379
+ }, Y = (e) => {
380
+ const r = Math.floor(e / 3600), n = Math.floor(e % 3600 / 60), a = e % 60, s = (l) => l.toString().padStart(2, "0");
381
+ return r > 0 ? `${s(r)}:${s(n)}:${s(a)}` : `${s(n)}:${s(a)}`;
382
+ };
383
+ function qe(e, r) {
384
+ return e ? {
385
+ wrapper: "border-destructive/30 bg-destructive/10 text-destructive",
386
+ bold: !0
387
+ } : r ? {
388
+ wrapper: "border-warning/30 bg-warning/10 text-warning",
389
+ bold: !0
390
+ } : {
391
+ wrapper: "border-border bg-muted text-muted-foreground",
392
+ bold: !1
393
+ };
394
+ }
395
+ const et = ({
396
+ timeElapsedSeconds: e,
397
+ timeLimitSeconds: r,
398
+ variant: n = "compact"
399
+ }) => {
400
+ const a = r != null && r > 0, s = a ? Math.max(0, r - e) : 0, l = a && s < r * 0.1, o = a && s <= 60, i = Y(a ? s : e), g = qe(o, l);
401
+ return n === "compact" ? /* @__PURE__ */ u(
402
+ "div",
403
+ {
404
+ className: m(
405
+ "flex items-center gap-1.5 px-2.5 py-1 rounded-full border",
406
+ g.wrapper
407
+ ),
408
+ children: [
409
+ /* @__PURE__ */ t("span", { className: "inline-flex leading-none", children: /* @__PURE__ */ t($, { size: 13 }) }),
410
+ /* @__PURE__ */ t("span", { className: "text-xs font-semibold font-mono tracking-wide", children: i })
411
+ ]
412
+ }
413
+ ) : /* @__PURE__ */ u("div", { className: m("flex items-center gap-1.5", g.wrapper), children: [
414
+ /* @__PURE__ */ t("span", { className: "inline-flex leading-none", children: /* @__PURE__ */ t($, { size: 16 }) }),
415
+ /* @__PURE__ */ u("span", { className: m("text-sm", g.bold && "font-semibold"), children: [
416
+ a ? "Time remaining: " : "Time elapsed: ",
417
+ /* @__PURE__ */ t("span", { className: "font-mono font-semibold", children: i })
418
+ ] })
419
+ ] });
420
+ }, se = F(null);
421
+ function oe() {
422
+ const e = P(se);
423
+ if (!e) throw new Error("Tooltip compound components must be used within <Tooltip>");
424
+ return e;
425
+ }
426
+ function tt({ children: e, delayDuration: r = 300 }) {
427
+ const [n, a] = v(!1), s = k(null), l = k(void 0), o = V(), i = T(() => {
428
+ clearTimeout(l.current), l.current = setTimeout(() => a(!0), r);
429
+ }, [r]), g = T(() => {
430
+ clearTimeout(l.current), a(!1);
431
+ }, []);
432
+ return /* @__PURE__ */ t(se.Provider, { value: { open: n, show: i, hide: g, triggerRef: s, tooltipId: o }, children: e });
433
+ }
434
+ function rt({ children: e }) {
435
+ const { show: r, hide: n, triggerRef: a, tooltipId: s, open: l } = oe();
436
+ return He(e) ? Fe(e, {
437
+ ref: (o) => {
438
+ a.current = o;
439
+ const i = e.ref;
440
+ typeof i == "function" ? i(o) : i && typeof i == "object" && (i.current = o);
441
+ },
442
+ onMouseEnter: (o) => {
443
+ r();
444
+ const i = e.props.onMouseEnter;
445
+ i == null || i(o);
446
+ },
447
+ onMouseLeave: (o) => {
448
+ n();
449
+ const i = e.props.onMouseLeave;
450
+ i == null || i(o);
451
+ },
452
+ onFocus: (o) => {
453
+ r();
454
+ const i = e.props.onFocus;
455
+ i == null || i(o);
456
+ },
457
+ onBlur: (o) => {
458
+ n();
459
+ const i = e.props.onBlur;
460
+ i == null || i(o);
461
+ },
462
+ "aria-describedby": l ? s : void 0
463
+ }) : e;
464
+ }
465
+ function nt({
466
+ className: e,
467
+ sideOffset: r = 8,
468
+ children: n,
469
+ style: a,
470
+ ...s
471
+ }) {
472
+ const { open: l, triggerRef: o, tooltipId: i } = oe(), g = k(null), [f, h] = v({
473
+ position: "fixed",
474
+ top: 0,
475
+ left: 0,
476
+ visibility: "hidden"
477
+ });
478
+ return Ve(() => {
479
+ if (!l || !o.current || !g.current) return;
480
+ const d = o.current.getBoundingClientRect(), c = g.current.getBoundingClientRect();
481
+ let p = d.top - c.height - r, b = d.left + d.width / 2 - c.width / 2;
482
+ p < 4 && (p = d.bottom + r), b < 4 && (b = 4), b + c.width > window.innerWidth - 4 && (b = window.innerWidth - c.width - 4), h({ position: "fixed", top: p, left: b, visibility: "visible" });
483
+ }, [l, r, o]), l ? ae(
484
+ /* @__PURE__ */ t(
485
+ "div",
486
+ {
487
+ ref: g,
488
+ id: i,
489
+ role: "tooltip",
490
+ "data-slot": "tooltip-content",
491
+ className: m(
492
+ "bg-primary text-primary-foreground z-50 max-w-60 rounded-md px-2.5 py-1.5 text-xs leading-snug shadow-md animate-in fade-in-0 zoom-in-95",
493
+ e
494
+ ),
495
+ style: { ...f, ...a },
496
+ ...s,
497
+ children: n
498
+ }
499
+ ),
500
+ document.body
501
+ ) : null;
502
+ }
503
+ const at = {
504
+ current: "bg-primary text-primary-foreground border-primary",
505
+ flagged: "bg-warning/10 text-warning border-warning/30",
506
+ answered: "bg-success/10 text-success border-success/30",
507
+ default: "bg-background text-muted-foreground border-border"
508
+ }, st = (e, r) => e.uid === r ? "current" : e.isFlagged ? "flagged" : e.isAnswered ? "answered" : "default", ot = ({
509
+ questions: e,
510
+ currentQuestionUid: r,
511
+ onNavigate: n,
512
+ onToggleFlag: a,
513
+ readOnly: s = !1
514
+ }) => {
515
+ const l = (o) => {
516
+ const i = [`Question ${o.sequence + 1}`];
517
+ return o.isFlagged && i.push("Flagged"), o.isAnswered && i.push("Answered"), o.isSkipped && i.push("Skipped"), i.join(" · ");
518
+ };
519
+ return /* @__PURE__ */ t("div", { className: "flex flex-wrap gap-1.5", children: e.map((o) => {
520
+ const i = st(o, r);
521
+ return /* @__PURE__ */ u(
522
+ "div",
523
+ {
524
+ title: l(o),
525
+ className: m(
526
+ "inline-flex items-center gap-1 px-2 py-1 rounded-md border transition-all duration-150",
527
+ at[i],
528
+ s ? "cursor-default" : "cursor-pointer hover:shadow-sm hover:-translate-y-px"
529
+ ),
530
+ onClick: s ? void 0 : () => n == null ? void 0 : n(o.uid),
531
+ children: [
532
+ /* @__PURE__ */ t("span", { className: "text-xs font-semibold min-w-4 text-center", children: o.sequence + 1 }),
533
+ !s && a && /* @__PURE__ */ u(tt, { children: [
534
+ /* @__PURE__ */ t(rt, { children: /* @__PURE__ */ t(
535
+ "span",
536
+ {
537
+ role: "button",
538
+ "aria-label": o.isFlagged ? "Unflag question" : "Flag question",
539
+ className: m(
540
+ "inline-flex cursor-pointer transition-colors duration-150",
541
+ o.isFlagged ? "text-warning" : i === "current" ? "text-primary-foreground/60 hover:text-primary-foreground" : "text-muted-foreground hover:text-warning"
542
+ ),
543
+ onClick: (g) => {
544
+ g.stopPropagation(), a(o.uid);
545
+ },
546
+ children: /* @__PURE__ */ t(pe, { size: 11, fill: o.isFlagged ? "currentColor" : "none" })
547
+ }
548
+ ) }),
549
+ /* @__PURE__ */ t(nt, { children: o.isFlagged ? "Unflag question" : "Flag question" })
550
+ ] })
551
+ ]
552
+ },
553
+ o.uid
554
+ );
555
+ }) });
556
+ };
557
+ function ie({
558
+ children: e,
559
+ ...r
560
+ }) {
561
+ return E.isValidElement(e) ? E.cloneElement(e, {
562
+ ...it(r, e.props),
563
+ ref: e.ref
564
+ }) : (E.Children.count(e) > 1 && E.Children.only(null), null);
565
+ }
566
+ function it(e, r) {
567
+ const n = { ...r };
568
+ for (const a in r) {
569
+ const s = e[a], l = r[a];
570
+ a === "style" ? n[a] = { ...s, ...l } : a === "className" ? n[a] = [s, l].filter(Boolean).join(" ") : typeof s == "function" && typeof l == "function" && (n[a] = (...o) => {
571
+ l(...o), s(...o);
572
+ });
573
+ }
574
+ return { ...e, ...n };
575
+ }
576
+ const A = S(
577
+ "inline-flex shrink-0 items-center justify-center gap-2 rounded-md text-sm font-medium whitespace-nowrap transition-all outline-none focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
578
+ {
579
+ variants: {
580
+ variant: {
581
+ default: "bg-primary text-primary-foreground hover:bg-primary/90",
582
+ destructive: "bg-destructive text-destructive-foreground hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:bg-destructive/60 dark:focus-visible:ring-destructive/40",
583
+ outline: "border bg-background shadow-xs hover:bg-accent hover:text-accent-foreground dark:border-input dark:bg-input/30 dark:hover:bg-input/50",
584
+ secondary: "bg-secondary text-secondary-foreground hover:bg-secondary/80",
585
+ ghost: "hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50",
586
+ link: "text-primary underline-offset-4 hover:underline"
587
+ },
588
+ size: {
589
+ default: "h-9 px-4 py-2 has-[>svg]:px-3",
590
+ xs: "h-6 gap-1 rounded-md px-2 text-xs has-[>svg]:px-1.5 [&_svg:not([class*='size-'])]:size-3",
591
+ sm: "h-8 gap-1.5 rounded-md px-3 has-[>svg]:px-2.5",
592
+ lg: "h-10 rounded-md px-6 has-[>svg]:px-4",
593
+ icon: "size-9",
594
+ "icon-xs": "size-6 rounded-md [&_svg:not([class*='size-'])]:size-3",
595
+ "icon-sm": "size-8",
596
+ "icon-lg": "size-10"
597
+ }
598
+ },
599
+ defaultVariants: {
600
+ variant: "default",
601
+ size: "default"
602
+ }
603
+ }
604
+ );
605
+ function _({
606
+ className: e,
607
+ variant: r = "default",
608
+ size: n = "default",
609
+ asChild: a = !1,
610
+ ...s
611
+ }) {
612
+ return /* @__PURE__ */ t(
613
+ a ? ie : "button",
614
+ {
615
+ "data-slot": "button",
616
+ className: m(A({ variant: r, size: n, className: e })),
617
+ ...s
618
+ }
619
+ );
620
+ }
621
+ const ur = ({
622
+ currentQuestionIndex: e,
623
+ totalQuestions: r,
624
+ hasNext: n,
625
+ hasPrevious: a,
626
+ onNext: s,
627
+ onPrevious: l,
628
+ onSubmit: o,
629
+ timeElapsedSeconds: i,
630
+ timeLimitSeconds: g,
631
+ questions: f,
632
+ onNavigateToQuestion: h,
633
+ onToggleFlag: d,
634
+ currentQuestionUid: c,
635
+ isCompleted: p = !1,
636
+ isSubmitting: b = !1,
637
+ readOnly: x = !1
638
+ }) => {
639
+ const N = i != null && i >= 0, y = f && f.length > 0;
640
+ return /* @__PURE__ */ u("div", { className: "rounded-lg border border-border overflow-hidden shadow-sm", children: [
641
+ /* @__PURE__ */ u("div", { className: "flex items-center justify-between px-4 py-2.5 bg-muted border-b border-border", children: [
642
+ /* @__PURE__ */ u("span", { className: "text-sm font-medium text-foreground", children: [
643
+ "Question",
644
+ " ",
645
+ /* @__PURE__ */ t("span", { className: "font-bold", children: e + 1 }),
646
+ " ",
647
+ "of ",
648
+ r
649
+ ] }),
650
+ N && /* @__PURE__ */ t(
651
+ et,
652
+ {
653
+ timeElapsedSeconds: i,
654
+ timeLimitSeconds: g
655
+ }
656
+ )
657
+ ] }),
658
+ y && /* @__PURE__ */ t("div", { className: "px-4 py-3 border-b border-border", children: /* @__PURE__ */ t(
659
+ ot,
660
+ {
661
+ questions: f,
662
+ currentQuestionUid: c,
663
+ onNavigate: h,
664
+ onToggleFlag: d,
665
+ readOnly: x
666
+ }
667
+ ) }),
668
+ /* @__PURE__ */ u("div", { className: "flex items-center justify-between gap-2 px-4 py-3", children: [
669
+ /* @__PURE__ */ u(
670
+ _,
671
+ {
672
+ variant: "outline",
673
+ size: "sm",
674
+ className: "rounded-lg",
675
+ disabled: !a || x,
676
+ onClick: l,
677
+ children: [
678
+ /* @__PURE__ */ t(te, { size: 16 }),
679
+ " Previous"
680
+ ]
681
+ }
682
+ ),
683
+ !n || p ? /* @__PURE__ */ u(
684
+ _,
685
+ {
686
+ variant: p ? "secondary" : "default",
687
+ size: "sm",
688
+ className: "rounded-lg",
689
+ onClick: o,
690
+ disabled: x || b,
691
+ children: [
692
+ b ? "Submitting..." : p ? "Review" : "Submit",
693
+ !b && /* @__PURE__ */ t(he, { size: 14 })
694
+ ]
695
+ }
696
+ ) : /* @__PURE__ */ u(
697
+ _,
698
+ {
699
+ size: "sm",
700
+ className: "rounded-lg",
701
+ disabled: !n || x,
702
+ onClick: s,
703
+ children: [
704
+ "Next ",
705
+ /* @__PURE__ */ t(H, { size: 16 })
706
+ ]
707
+ }
708
+ )
709
+ ] })
710
+ ] });
711
+ }, X = {
712
+ color1: { bg: "bg-blue-50 dark:bg-blue-950/40", border: "border-blue-200 dark:border-blue-800", accent: "bg-blue-200 dark:bg-blue-800" },
713
+ color2: { bg: "bg-violet-50 dark:bg-violet-950/40", border: "border-violet-200 dark:border-violet-800", accent: "bg-violet-200 dark:bg-violet-800" },
714
+ color3: { bg: "bg-emerald-50 dark:bg-emerald-950/40", border: "border-emerald-200 dark:border-emerald-800", accent: "bg-emerald-200 dark:bg-emerald-800" },
715
+ color4: { bg: "bg-amber-50 dark:bg-amber-950/40", border: "border-amber-200 dark:border-amber-800", accent: "bg-amber-200 dark:bg-amber-800" },
716
+ color5: { bg: "bg-rose-50 dark:bg-rose-950/40", border: "border-rose-200 dark:border-rose-800", accent: "bg-rose-200 dark:bg-rose-800" },
717
+ color6: { bg: "bg-green-50 dark:bg-green-950/40", border: "border-green-200 dark:border-green-800", accent: "bg-green-200 dark:bg-green-800" }
718
+ }, lt = {
719
+ small: { width: 280, height: 180, fontSize: "0.875rem" },
720
+ medium: { width: 400, height: 260, fontSize: "1rem" },
721
+ large: { width: 520, height: 340, fontSize: "1.125rem" }
722
+ }, dt = ({
723
+ card: e,
724
+ isFlipped: r,
725
+ onFlip: n,
726
+ readOnly: a = !1,
727
+ size: s = "medium"
728
+ }) => {
729
+ const [l, o] = v(!1), i = r !== void 0, g = i ? r : l, f = () => {
730
+ a || (i || o((b) => !b), n == null || n());
731
+ }, { width: h, height: d, fontSize: c } = lt[s], p = X[e.color] || X.color1;
732
+ return /* @__PURE__ */ t(
733
+ "div",
734
+ {
735
+ className: "perspective-[1000px]",
736
+ style: { width: `${h}px`, height: `${d}px` },
737
+ children: /* @__PURE__ */ u(
738
+ "div",
739
+ {
740
+ className: m(
741
+ "relative size-full transition-transform duration-500 transform-3d",
742
+ g && "transform-[rotateY(180deg)]"
743
+ ),
744
+ children: [
745
+ /* @__PURE__ */ u(
746
+ "div",
747
+ {
748
+ className: m(
749
+ "absolute inset-0 flex flex-col rounded-lg border backface-hidden",
750
+ p.bg,
751
+ p.border,
752
+ !a && "cursor-pointer"
753
+ ),
754
+ onClick: f,
755
+ children: [
756
+ /* @__PURE__ */ t("div", { className: "flex flex-1 items-center justify-center p-5 overflow-auto", children: /* @__PURE__ */ t(
757
+ "div",
758
+ {
759
+ className: "text-center",
760
+ style: { fontSize: c },
761
+ dangerouslySetInnerHTML: { __html: e.front }
762
+ }
763
+ ) }),
764
+ !a && /* @__PURE__ */ u("div", { className: "flex items-center justify-center gap-1 pb-3 text-muted-foreground", children: [
765
+ /* @__PURE__ */ t(B, { size: 12 }),
766
+ /* @__PURE__ */ t("span", { className: "text-xs", children: "Tap to flip" })
767
+ ] })
768
+ ]
769
+ }
770
+ ),
771
+ /* @__PURE__ */ u(
772
+ "div",
773
+ {
774
+ className: m(
775
+ "absolute inset-0 flex flex-col rounded-lg border border-border bg-background backface-hidden transform-[rotateY(180deg)]",
776
+ !a && "cursor-pointer"
777
+ ),
778
+ onClick: f,
779
+ children: [
780
+ /* @__PURE__ */ t("div", { className: m("h-1.5 rounded-t-lg", p.accent) }),
781
+ /* @__PURE__ */ t("div", { className: "flex flex-1 items-start justify-center p-5 overflow-auto", children: /* @__PURE__ */ t(
782
+ "div",
783
+ {
784
+ className: "text-left w-full flashcard-back-content",
785
+ style: { fontSize: c },
786
+ dangerouslySetInnerHTML: { __html: e.back }
787
+ }
788
+ ) }),
789
+ !a && /* @__PURE__ */ u("div", { className: "flex items-center justify-center gap-1 pb-3 text-muted-foreground", children: [
790
+ /* @__PURE__ */ t(B, { size: 12 }),
791
+ /* @__PURE__ */ t("span", { className: "text-xs", children: "Tap to flip back" })
792
+ ] })
793
+ ]
794
+ }
795
+ )
796
+ ]
797
+ }
798
+ )
799
+ }
800
+ );
801
+ };
802
+ function ct(e) {
803
+ const r = [...e];
804
+ for (let n = r.length - 1; n > 0; n--) {
805
+ const a = Math.floor(Math.random() * (n + 1));
806
+ [r[n], r[a]] = [r[a], r[n]];
807
+ }
808
+ return r;
809
+ }
810
+ const ut = ({
811
+ cards: e,
812
+ deckName: r,
813
+ deckDescription: n,
814
+ currentIndex: a,
815
+ onNavigate: s,
816
+ onComplete: l,
817
+ readOnly: o = !1,
818
+ showProgress: i = !0,
819
+ shuffled: g = !1
820
+ }) => {
821
+ const f = Pe(
822
+ () => g ? ct(e) : e,
823
+ [e, g]
824
+ ), [h, d] = v(0), [c, p] = v(!1), b = a !== void 0, x = b ? a : h, N = f[x], y = x > 0, w = x < f.length - 1, z = (M) => {
825
+ p(!1), b ? s == null || s(M) : d(M);
826
+ }, fe = () => {
827
+ y && z(x - 1);
828
+ }, me = () => {
829
+ w ? z(x + 1) : l == null || l();
830
+ };
831
+ if (!f.length)
832
+ return /* @__PURE__ */ t("span", { className: "text-sm text-muted-foreground", children: "No flashcards in this deck." });
833
+ const ge = (x + 1) / f.length * 100;
834
+ return /* @__PURE__ */ u("div", { className: "flex flex-col items-center gap-4", children: [
835
+ (r || n) && /* @__PURE__ */ u("div", { className: "flex flex-col gap-0.5 text-center", children: [
836
+ r && /* @__PURE__ */ t("span", { className: "text-lg font-semibold", children: r }),
837
+ n && /* @__PURE__ */ t("span", { className: "text-sm text-muted-foreground", children: n })
838
+ ] }),
839
+ N && /* @__PURE__ */ t(
840
+ dt,
841
+ {
842
+ card: N,
843
+ isFlipped: c,
844
+ onFlip: () => p((M) => !M),
845
+ readOnly: o
846
+ }
847
+ ),
848
+ i && /* @__PURE__ */ u("div", { className: "flex w-full items-center gap-2", children: [
849
+ /* @__PURE__ */ t("div", { className: "flex-1 h-1.5 rounded-full bg-muted overflow-hidden", children: /* @__PURE__ */ t(
850
+ "div",
851
+ {
852
+ className: "h-full rounded-full bg-primary transition-[width] duration-300",
853
+ style: { width: `${ge}%` }
854
+ }
855
+ ) }),
856
+ /* @__PURE__ */ u("span", { className: "text-xs text-muted-foreground whitespace-nowrap", children: [
857
+ x + 1,
858
+ " of ",
859
+ f.length
860
+ ] })
861
+ ] }),
862
+ /* @__PURE__ */ u("div", { className: "flex w-full items-center justify-between gap-3", children: [
863
+ /* @__PURE__ */ u(
864
+ _,
865
+ {
866
+ variant: "outline",
867
+ size: "sm",
868
+ className: "rounded-lg",
869
+ disabled: !y,
870
+ onClick: fe,
871
+ children: [
872
+ /* @__PURE__ */ t(te, { size: 16 }),
873
+ " Previous"
874
+ ]
875
+ }
876
+ ),
877
+ /* @__PURE__ */ u(
878
+ _,
879
+ {
880
+ size: "sm",
881
+ className: "rounded-lg",
882
+ onClick: me,
883
+ children: [
884
+ w ? "Next" : "Finish",
885
+ " ",
886
+ /* @__PURE__ */ t(H, { size: 16 })
887
+ ]
888
+ }
889
+ )
890
+ ] })
891
+ ] });
892
+ }, ft = {
893
+ video: R,
894
+ video_lesson: R,
895
+ stream: Ne,
896
+ document: j,
897
+ pdf: j,
898
+ page: j,
899
+ quiz: Z,
900
+ assessment: Z,
901
+ assignment: ye,
902
+ discussion: ve,
903
+ link: W,
904
+ url: W,
905
+ audio: xe,
906
+ image: be,
907
+ scorm: K,
908
+ iframe: K,
909
+ lesson: U,
910
+ module: U
911
+ }, mt = ({
912
+ type: e,
913
+ size: r = 18
914
+ }) => {
915
+ const n = ft[e] ?? j;
916
+ return /* @__PURE__ */ t(n, { size: r });
917
+ }, gt = ({
918
+ item: e,
919
+ level: r,
920
+ isActive: n = !1,
921
+ isCompleted: a = !1,
922
+ isExpanded: s = !1,
923
+ hasChildren: l,
924
+ onToggleExpand: o,
925
+ onClick: i,
926
+ showDuration: g = !0,
927
+ showIcon: f = !0,
928
+ showProgress: h = !0
929
+ }) => {
930
+ const d = l, c = d ? "font-semibold" : n ? "font-medium" : "font-normal";
931
+ return /* @__PURE__ */ u(
932
+ "div",
933
+ {
934
+ className: m(
935
+ "flex items-center gap-2 py-2 pr-3 transition-colors",
936
+ i && "cursor-pointer hover:bg-muted",
937
+ n && "bg-secondary"
938
+ ),
939
+ style: { paddingLeft: `${r * 20 + 8}px` },
940
+ onClick: i,
941
+ children: [
942
+ /* @__PURE__ */ t("div", { className: "shrink-0 flex items-center justify-center size-5", children: h && a ? /* @__PURE__ */ t("span", { className: "text-success", children: /* @__PURE__ */ t(we, { size: 18 }) }) : f ? /* @__PURE__ */ t("span", { className: n ? "text-primary" : "text-muted-foreground", children: /* @__PURE__ */ t(mt, { type: e.type, size: 16 }) }) : /* @__PURE__ */ t("span", { className: "text-muted-foreground", children: /* @__PURE__ */ t(Ce, { size: 16 }) }) }),
943
+ /* @__PURE__ */ u("div", { className: "flex-1 min-w-0", children: [
944
+ /* @__PURE__ */ t(
945
+ "div",
946
+ {
947
+ className: m("text-sm truncate", n ? "text-primary" : "text-foreground", c),
948
+ children: e.name
949
+ }
950
+ ),
951
+ g && e.duration > 0 && !d && /* @__PURE__ */ t("div", { className: "text-xs text-muted-foreground mt-0.5", children: Qe(e.duration) })
952
+ ] }),
953
+ l && /* @__PURE__ */ t(
954
+ "button",
955
+ {
956
+ className: "inline-flex items-center justify-center rounded-md p-1 text-muted-foreground transition-colors hover:bg-muted hover:text-foreground",
957
+ "aria-label": s ? "Collapse" : "Expand",
958
+ onClick: (p) => {
959
+ p.stopPropagation(), o == null || o();
960
+ },
961
+ children: s ? /* @__PURE__ */ t(ke, { size: 16 }) : /* @__PURE__ */ t(H, { size: 16 })
962
+ }
963
+ )
964
+ ]
965
+ }
966
+ );
967
+ }, fr = ({
968
+ items: e,
969
+ progress: r,
970
+ activeItemUid: n,
971
+ onItemClick: a,
972
+ readOnly: s = !1,
973
+ showDuration: l = !0,
974
+ showIcons: o = !0,
975
+ showProgress: i = !0
976
+ }) => {
977
+ const [g, f] = v({});
978
+ if (!e || e.length === 0)
979
+ return null;
980
+ const h = (p) => {
981
+ f((b) => ({ ...b, [p]: !b[p] }));
982
+ }, d = (p) => !r || !i ? !1 : r.some((b) => b.resourceUid === p && b.isCompleted), c = (p, b) => /* @__PURE__ */ t("div", { className: "flex flex-col", children: p.map((x) => {
983
+ var w;
984
+ const N = !!((w = x.children) != null && w.length), y = g[x.uid] || !1;
985
+ return /* @__PURE__ */ u("div", { children: [
986
+ /* @__PURE__ */ t(
987
+ gt,
988
+ {
989
+ item: x,
990
+ level: b,
991
+ isActive: n === x.uid,
992
+ isCompleted: d(x.uid),
993
+ isExpanded: y,
994
+ hasChildren: N,
995
+ onToggleExpand: () => h(x.uid),
996
+ onClick: s ? void 0 : () => a == null ? void 0 : a(x),
997
+ showDuration: l,
998
+ showIcon: o,
999
+ showProgress: i
1000
+ }
1001
+ ),
1002
+ N && y && c(x.children, b + 1)
1003
+ ] }, x.uid);
1004
+ }) });
1005
+ return /* @__PURE__ */ t("nav", { className: "rounded-lg border border-border overflow-hidden", children: c(e, 0) });
1006
+ }, pt = ({
1007
+ src: e,
1008
+ poster: r,
1009
+ title: n,
1010
+ autoPlay: a = !1,
1011
+ onPlay: s,
1012
+ onPause: l,
1013
+ onEnded: o,
1014
+ onTimeUpdate: i,
1015
+ readOnly: g = !1,
1016
+ aspectRatio: f = "16/9",
1017
+ className: h,
1018
+ style: d
1019
+ }) => {
1020
+ const c = k(null), p = () => {
1021
+ const b = c.current;
1022
+ b && i && i(b.currentTime, b.duration);
1023
+ };
1024
+ return e ? g ? /* @__PURE__ */ u(
1025
+ "div",
1026
+ {
1027
+ className: m("relative overflow-hidden rounded-lg", h),
1028
+ style: { aspectRatio: f, ...d },
1029
+ children: [
1030
+ r ? /* @__PURE__ */ t(
1031
+ "img",
1032
+ {
1033
+ src: r,
1034
+ alt: n || "Video poster",
1035
+ style: { width: "100%", height: "100%", objectFit: "cover" }
1036
+ }
1037
+ ) : /* @__PURE__ */ t("div", { className: "absolute inset-0 flex items-center justify-center bg-muted", children: /* @__PURE__ */ t("div", { className: "flex items-center justify-center size-14 rounded-full bg-black/60", children: /* @__PURE__ */ t(G, { size: 28, className: "text-white ml-0.5" }) }) }),
1038
+ r && /* @__PURE__ */ t("div", { className: "absolute inset-0 flex items-center justify-center bg-black/30 transition-opacity", children: /* @__PURE__ */ t("div", { className: "flex items-center justify-center size-14 rounded-full bg-black/60", children: /* @__PURE__ */ t(G, { size: 28, className: "text-white ml-0.5" }) }) }),
1039
+ n && /* @__PURE__ */ t("div", { className: "absolute bottom-0 left-0 right-0 bg-linear-to-t from-black/60 to-transparent p-2", children: /* @__PURE__ */ t("span", { className: "text-sm text-white font-medium", children: n }) })
1040
+ ]
1041
+ }
1042
+ ) : /* @__PURE__ */ u("div", { className: h, style: d, children: [
1043
+ n && /* @__PURE__ */ t("p", { className: "mb-2 text-sm font-medium", children: n }),
1044
+ /* @__PURE__ */ t("div", { className: "rounded-lg overflow-hidden", children: /* @__PURE__ */ t(
1045
+ "video",
1046
+ {
1047
+ ref: c,
1048
+ src: e,
1049
+ poster: r,
1050
+ controls: !0,
1051
+ autoPlay: a,
1052
+ onPlay: s,
1053
+ onPause: l,
1054
+ onEnded: o,
1055
+ onTimeUpdate: p,
1056
+ style: { width: "100%", aspectRatio: f, display: "block" }
1057
+ }
1058
+ ) })
1059
+ ] }) : /* @__PURE__ */ t(
1060
+ "div",
1061
+ {
1062
+ className: m("relative overflow-hidden rounded-lg border border-border bg-muted", h),
1063
+ style: { aspectRatio: f, ...d },
1064
+ children: /* @__PURE__ */ u("div", { className: "absolute inset-0 flex flex-col items-center justify-center gap-2", children: [
1065
+ /* @__PURE__ */ t("div", { className: "flex items-center justify-center size-12 rounded-full bg-muted-foreground/10", children: /* @__PURE__ */ t(R, { size: 24 }) }),
1066
+ /* @__PURE__ */ t("span", { className: "text-sm text-muted-foreground", children: "No video source provided" })
1067
+ ] })
1068
+ }
1069
+ );
1070
+ }, ht = S("h-full rounded-full transition-all duration-300", {
1071
+ variants: {
1072
+ variant: {
1073
+ default: "bg-primary",
1074
+ success: "bg-success",
1075
+ warning: "bg-warning",
1076
+ info: "bg-info"
1077
+ },
1078
+ size: {
1079
+ sm: "",
1080
+ default: ""
1081
+ }
1082
+ },
1083
+ defaultVariants: {
1084
+ variant: "default",
1085
+ size: "default"
1086
+ }
1087
+ }), bt = S("bg-muted overflow-hidden rounded-full w-full", {
1088
+ variants: {
1089
+ size: {
1090
+ sm: "h-1.5",
1091
+ default: "h-2.5"
1092
+ }
1093
+ },
1094
+ defaultVariants: {
1095
+ size: "default"
1096
+ }
1097
+ });
1098
+ function mr({
1099
+ className: e,
1100
+ value: r = 0,
1101
+ max: n = 100,
1102
+ variant: a,
1103
+ size: s,
1104
+ ...l
1105
+ }) {
1106
+ const o = Math.min(100, Math.max(0, r / n * 100));
1107
+ return /* @__PURE__ */ t(
1108
+ "div",
1109
+ {
1110
+ "data-slot": "progress",
1111
+ role: "progressbar",
1112
+ "aria-valuenow": r,
1113
+ "aria-valuemin": 0,
1114
+ "aria-valuemax": n,
1115
+ className: m(bt({ size: s }), e),
1116
+ ...l,
1117
+ children: /* @__PURE__ */ t(
1118
+ "div",
1119
+ {
1120
+ className: ht({ variant: a, size: s }),
1121
+ style: { width: `${o}%` }
1122
+ }
1123
+ )
1124
+ }
1125
+ );
1126
+ }
1127
+ function gr({ icon: e, title: r, description: n, action: a, className: s, style: l }) {
1128
+ return /* @__PURE__ */ u(
1129
+ "div",
1130
+ {
1131
+ className: m("flex flex-col items-center justify-center text-center px-3 py-6", s),
1132
+ style: l,
1133
+ children: [
1134
+ e && /* @__PURE__ */ t("div", { className: "mb-2 text-muted-foreground [&>svg]:size-12", children: e }),
1135
+ /* @__PURE__ */ t("p", { className: "text-lg font-semibold text-foreground mb-1", children: r }),
1136
+ n && /* @__PURE__ */ t("p", { className: m("text-sm text-muted-foreground max-w-[360px]", a && "mb-2"), children: n }),
1137
+ a
1138
+ ]
1139
+ }
1140
+ );
1141
+ }
1142
+ const le = F(null);
1143
+ function L() {
1144
+ const e = P(le);
1145
+ if (!e)
1146
+ throw new Error(
1147
+ "AlertDialog compound components must be used within <AlertDialog>"
1148
+ );
1149
+ return e;
1150
+ }
1151
+ const J = [
1152
+ "a[href]",
1153
+ "button:not([disabled])",
1154
+ "input:not([disabled])",
1155
+ "select:not([disabled])",
1156
+ "textarea:not([disabled])",
1157
+ '[tabindex]:not([tabindex="-1"])'
1158
+ ].join(", ");
1159
+ function xt(e, r) {
1160
+ const n = k(null);
1161
+ return C(() => {
1162
+ if (!r || !e.current) return;
1163
+ n.current = document.activeElement;
1164
+ const s = e.current.querySelectorAll(J);
1165
+ return s.length > 0 && s[0].focus(), () => {
1166
+ n.current instanceof HTMLElement && n.current.focus();
1167
+ };
1168
+ }, [r, e]), T(
1169
+ (s) => {
1170
+ if (s.key !== "Tab" || !e.current) return;
1171
+ const l = Array.from(
1172
+ e.current.querySelectorAll(J)
1173
+ );
1174
+ if (l.length === 0) return;
1175
+ const o = l[0], i = l[l.length - 1];
1176
+ s.shiftKey && document.activeElement === o ? (s.preventDefault(), i.focus()) : !s.shiftKey && document.activeElement === i && (s.preventDefault(), o.focus());
1177
+ },
1178
+ [e]
1179
+ );
1180
+ }
1181
+ function vt(e) {
1182
+ C(() => {
1183
+ if (!e) return;
1184
+ const r = document.body.style.overflow;
1185
+ return document.body.style.overflow = "hidden", () => {
1186
+ document.body.style.overflow = r;
1187
+ };
1188
+ }, [e]);
1189
+ }
1190
+ function yt({ children: e, open: r, onOpenChange: n }) {
1191
+ const a = V(), s = V();
1192
+ return /* @__PURE__ */ t(
1193
+ le.Provider,
1194
+ {
1195
+ value: { open: r, onOpenChange: n, titleId: a, descriptionId: s },
1196
+ children: e
1197
+ }
1198
+ );
1199
+ }
1200
+ function pr({
1201
+ className: e,
1202
+ onClick: r,
1203
+ ...n
1204
+ }) {
1205
+ const { onOpenChange: a } = L();
1206
+ return /* @__PURE__ */ t(
1207
+ "button",
1208
+ {
1209
+ type: "button",
1210
+ "data-slot": "alert-dialog-trigger",
1211
+ className: e,
1212
+ onClick: (s) => {
1213
+ a(!0), r == null || r(s);
1214
+ },
1215
+ ...n
1216
+ }
1217
+ );
1218
+ }
1219
+ function Nt({ children: e }) {
1220
+ return ae(e, document.body);
1221
+ }
1222
+ function wt({
1223
+ className: e,
1224
+ ...r
1225
+ }) {
1226
+ const { onOpenChange: n } = L();
1227
+ return /* @__PURE__ */ t(
1228
+ "div",
1229
+ {
1230
+ "data-slot": "alert-dialog-backdrop",
1231
+ className: m(
1232
+ "fixed inset-0 z-50 bg-black/50 transition-opacity data-[state=open]:animate-in data-[state=open]:fade-in-0 data-[state=closed]:animate-out data-[state=closed]:fade-out-0",
1233
+ e
1234
+ ),
1235
+ "data-state": "open",
1236
+ onClick: () => n(!1),
1237
+ ...r
1238
+ }
1239
+ );
1240
+ }
1241
+ function Ct({
1242
+ className: e,
1243
+ children: r,
1244
+ ...n
1245
+ }) {
1246
+ const { open: a, onOpenChange: s, titleId: l, descriptionId: o } = L(), i = k(null), g = xt(i, a);
1247
+ return vt(a), C(() => {
1248
+ if (!a) return;
1249
+ const f = (h) => {
1250
+ h.key === "Escape" && s(!1);
1251
+ };
1252
+ return document.addEventListener("keydown", f), () => document.removeEventListener("keydown", f);
1253
+ }, [a, s]), a ? /* @__PURE__ */ u(Nt, { children: [
1254
+ /* @__PURE__ */ t(wt, {}),
1255
+ /* @__PURE__ */ t(
1256
+ "div",
1257
+ {
1258
+ ref: i,
1259
+ role: "alertdialog",
1260
+ "aria-modal": "true",
1261
+ "aria-labelledby": l,
1262
+ "aria-describedby": o,
1263
+ "data-slot": "alert-dialog-content",
1264
+ "data-state": "open",
1265
+ className: m(
1266
+ "bg-background fixed top-1/2 left-1/2 z-50 grid w-full max-w-lg -translate-x-1/2 -translate-y-1/2 gap-4 rounded-lg border p-6 shadow-lg transition-all data-[state=open]:animate-in data-[state=open]:fade-in-0 data-[state=open]:zoom-in-95 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95",
1267
+ e
1268
+ ),
1269
+ onKeyDown: g,
1270
+ ...n,
1271
+ children: r
1272
+ }
1273
+ )
1274
+ ] }) : null;
1275
+ }
1276
+ function kt({
1277
+ className: e,
1278
+ ...r
1279
+ }) {
1280
+ return /* @__PURE__ */ t(
1281
+ "div",
1282
+ {
1283
+ "data-slot": "alert-dialog-header",
1284
+ className: m(
1285
+ "flex flex-col gap-2 text-center sm:text-left",
1286
+ e
1287
+ ),
1288
+ ...r
1289
+ }
1290
+ );
1291
+ }
1292
+ function Tt({
1293
+ className: e,
1294
+ ...r
1295
+ }) {
1296
+ return /* @__PURE__ */ t(
1297
+ "div",
1298
+ {
1299
+ "data-slot": "alert-dialog-footer",
1300
+ className: m(
1301
+ "flex flex-col-reverse gap-2 sm:flex-row sm:justify-end",
1302
+ e
1303
+ ),
1304
+ ...r
1305
+ }
1306
+ );
1307
+ }
1308
+ function zt({
1309
+ className: e,
1310
+ ...r
1311
+ }) {
1312
+ const { titleId: n } = L();
1313
+ return /* @__PURE__ */ t(
1314
+ "h2",
1315
+ {
1316
+ id: n,
1317
+ "data-slot": "alert-dialog-title",
1318
+ className: m("text-lg font-semibold", e),
1319
+ ...r
1320
+ }
1321
+ );
1322
+ }
1323
+ function _t({
1324
+ className: e,
1325
+ ...r
1326
+ }) {
1327
+ const { descriptionId: n } = L();
1328
+ return /* @__PURE__ */ t(
1329
+ "p",
1330
+ {
1331
+ id: n,
1332
+ "data-slot": "alert-dialog-description",
1333
+ className: m("text-muted-foreground text-sm", e),
1334
+ ...r
1335
+ }
1336
+ );
1337
+ }
1338
+ function St({
1339
+ className: e,
1340
+ ...r
1341
+ }) {
1342
+ return /* @__PURE__ */ t(
1343
+ "button",
1344
+ {
1345
+ type: "button",
1346
+ className: m(A(), e),
1347
+ ...r
1348
+ }
1349
+ );
1350
+ }
1351
+ function It({
1352
+ className: e,
1353
+ ...r
1354
+ }) {
1355
+ return /* @__PURE__ */ t(
1356
+ "button",
1357
+ {
1358
+ type: "button",
1359
+ className: m(A({ variant: "outline" }), e),
1360
+ ...r
1361
+ }
1362
+ );
1363
+ }
1364
+ const Q = {
1365
+ primary: "bg-primary text-primary-foreground hover:bg-primary/90",
1366
+ error: "bg-destructive text-destructive-foreground hover:bg-destructive/90",
1367
+ warning: "bg-warning text-warning-foreground hover:bg-warning/90"
1368
+ };
1369
+ function hr({
1370
+ open: e,
1371
+ title: r,
1372
+ message: n,
1373
+ confirmLabel: a = "Confirm",
1374
+ cancelLabel: s = "Cancel",
1375
+ confirmColor: l = "primary",
1376
+ onConfirm: o,
1377
+ onCancel: i,
1378
+ isLoading: g = !1
1379
+ }) {
1380
+ return /* @__PURE__ */ t(yt, { open: e, onOpenChange: (f) => !f && i(), children: /* @__PURE__ */ u(Ct, { children: [
1381
+ /* @__PURE__ */ u(kt, { children: [
1382
+ /* @__PURE__ */ t(zt, { children: r }),
1383
+ typeof n == "string" ? /* @__PURE__ */ t(_t, { children: n }) : n
1384
+ ] }),
1385
+ /* @__PURE__ */ u(Tt, { children: [
1386
+ /* @__PURE__ */ t(It, { onClick: i, disabled: g, children: s }),
1387
+ /* @__PURE__ */ u(
1388
+ St,
1389
+ {
1390
+ className: m(Q[l] ?? Q.primary),
1391
+ onClick: o,
1392
+ disabled: g,
1393
+ children: [
1394
+ g && /* @__PURE__ */ t("span", { className: "inline-block size-4 animate-spin rounded-full border-2 border-current border-t-transparent" }),
1395
+ a
1396
+ ]
1397
+ }
1398
+ )
1399
+ ] })
1400
+ ] }) });
1401
+ }
1402
+ function br({
1403
+ value: e,
1404
+ onChange: r,
1405
+ placeholder: n = "Search...",
1406
+ debounceMs: a = 300,
1407
+ fullWidth: s = !1,
1408
+ size: l = "small",
1409
+ className: o,
1410
+ style: i
1411
+ }) {
1412
+ const [g, f] = v(e);
1413
+ C(() => {
1414
+ f(e);
1415
+ }, [e]);
1416
+ const h = T(O(r, a), [r, a]);
1417
+ function d(p) {
1418
+ const b = p.target.value;
1419
+ f(b), h(b);
1420
+ }
1421
+ function c() {
1422
+ f(""), r("");
1423
+ }
1424
+ return /* @__PURE__ */ t(
1425
+ "div",
1426
+ {
1427
+ className: m("w-full", o),
1428
+ style: { ...i, width: s ? "100%" : void 0 },
1429
+ children: /* @__PURE__ */ u("div", { className: "flex items-center w-full border border-input rounded-md bg-background transition-colors focus-within:border-ring focus-within:ring-ring/50 focus-within:ring-[3px]", children: [
1430
+ /* @__PURE__ */ t("span", { className: "flex items-center justify-center px-2 text-muted-foreground shrink-0", children: /* @__PURE__ */ t(Te, { size: 18 }) }),
1431
+ /* @__PURE__ */ t(
1432
+ "input",
1433
+ {
1434
+ className: m(
1435
+ "flex-1 border-none outline-none bg-transparent text-foreground text-sm min-w-0 placeholder:text-muted-foreground",
1436
+ l === "medium" ? "py-2" : "py-1.5"
1437
+ ),
1438
+ value: g,
1439
+ onChange: d,
1440
+ placeholder: n
1441
+ }
1442
+ ),
1443
+ g && /* @__PURE__ */ t(
1444
+ "button",
1445
+ {
1446
+ type: "button",
1447
+ className: "inline-flex items-center justify-center p-0.5 mr-1 rounded-md text-muted-foreground cursor-pointer transition-colors hover:bg-muted hover:text-foreground",
1448
+ "aria-label": "Clear search",
1449
+ onClick: c,
1450
+ children: /* @__PURE__ */ t(re, { size: 16 })
1451
+ }
1452
+ )
1453
+ ] })
1454
+ }
1455
+ );
1456
+ }
1457
+ const Dt = S(
1458
+ "inline-flex items-center justify-center rounded-full border px-2.5 py-0.5 text-xs font-medium whitespace-nowrap transition-colors [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-3",
1459
+ {
1460
+ variants: {
1461
+ variant: {
1462
+ default: "border-transparent bg-primary text-primary-foreground",
1463
+ secondary: "border-transparent bg-secondary text-secondary-foreground",
1464
+ destructive: "border-transparent bg-destructive text-destructive-foreground",
1465
+ outline: "text-foreground",
1466
+ success: "border-transparent bg-success/15 text-success",
1467
+ warning: "border-transparent bg-warning/15 text-warning",
1468
+ info: "border-transparent bg-info/15 text-info",
1469
+ muted: "border-transparent bg-muted text-muted-foreground"
1470
+ }
1471
+ },
1472
+ defaultVariants: {
1473
+ variant: "default"
1474
+ }
1475
+ }
1476
+ );
1477
+ function Lt({
1478
+ className: e,
1479
+ variant: r,
1480
+ asChild: n = !1,
1481
+ ...a
1482
+ }) {
1483
+ return /* @__PURE__ */ t(
1484
+ n ? ie : "span",
1485
+ {
1486
+ "data-slot": "badge",
1487
+ className: m(Dt({ variant: r }), e),
1488
+ ...a
1489
+ }
1490
+ );
1491
+ }
1492
+ const Mt = {
1493
+ graded: "green",
1494
+ submitted: "teal",
1495
+ pending: "gray",
1496
+ missing: "red",
1497
+ late: "orange",
1498
+ excused: "gray",
1499
+ draft: "gray",
1500
+ not_started: "gray",
1501
+ resubmit: "orange"
1502
+ }, Et = {
1503
+ success: "green",
1504
+ error: "red",
1505
+ warning: "orange",
1506
+ info: "teal",
1507
+ default: "gray"
1508
+ }, jt = {
1509
+ green: "success",
1510
+ red: "destructive",
1511
+ orange: "warning",
1512
+ gray: "muted",
1513
+ teal: "info"
1514
+ }, q = {
1515
+ green: "bg-transparent border-success text-success",
1516
+ red: "bg-transparent border-destructive text-destructive",
1517
+ orange: "bg-transparent border-warning text-warning",
1518
+ gray: "bg-transparent border-border text-muted-foreground",
1519
+ teal: "bg-transparent border-info text-info"
1520
+ }, $t = {
1521
+ green: "bg-success text-success-foreground",
1522
+ red: "bg-destructive text-destructive-foreground",
1523
+ orange: "bg-warning text-warning-foreground",
1524
+ teal: "bg-info text-info-foreground"
1525
+ };
1526
+ function xr({
1527
+ status: e,
1528
+ colorMap: r,
1529
+ size: n = "small",
1530
+ variant: a = "filled"
1531
+ }) {
1532
+ const s = { ...Mt };
1533
+ if (r)
1534
+ for (const [f, h] of Object.entries(r))
1535
+ s[f] = Et[h] ?? h;
1536
+ const l = s[e] ?? "gray", o = e.replace(/_/g, " ").replace(/\b\w/g, (f) => f.toUpperCase()), i = jt[l] ?? "muted", g = a === "outlined" ? q[l] ?? q.gray : $t[l] ?? void 0;
1537
+ return /* @__PURE__ */ t(
1538
+ Lt,
1539
+ {
1540
+ variant: i,
1541
+ className: m(
1542
+ n === "small" ? "text-xs px-2 h-5.5" : "text-sm px-2.5 h-6.5",
1543
+ "leading-none",
1544
+ g
1545
+ ),
1546
+ children: o
1547
+ }
1548
+ );
1549
+ }
1550
+ const Rt = {
1551
+ success: "text-success",
1552
+ destructive: "text-destructive",
1553
+ warning: "text-warning",
1554
+ muted: "text-muted-foreground"
1555
+ };
1556
+ function Vt(e) {
1557
+ const r = /* @__PURE__ */ new Date(), n = e.getTime() - r.getTime(), a = Math.round(n / (1e3 * 60 * 60 * 24));
1558
+ return a === 0 ? "Due today" : a === 1 ? "Due tomorrow" : a === -1 ? "Due yesterday" : a > 1 ? `Due in ${a} days` : `${Math.abs(a)} days overdue`;
1559
+ }
1560
+ function Ht(e, r) {
1561
+ if (r) return "success";
1562
+ const n = /* @__PURE__ */ new Date(), s = (e.getTime() - n.getTime()) / (1e3 * 60 * 60 * 24);
1563
+ return s < 0 ? "destructive" : s < 2 ? "warning" : "muted";
1564
+ }
1565
+ function vr({
1566
+ dueDate: e,
1567
+ submittedDate: r,
1568
+ showRelative: n = !0,
1569
+ size: a = "medium",
1570
+ className: s,
1571
+ style: l
1572
+ }) {
1573
+ const o = new Date(e), i = !!r, g = Rt[Ht(o, i)] ?? "text-muted-foreground", f = a === "small" ? 14 : 16;
1574
+ return /* @__PURE__ */ u(
1575
+ "div",
1576
+ {
1577
+ className: m("flex items-center gap-1", g, s),
1578
+ style: l,
1579
+ children: [
1580
+ /* @__PURE__ */ t("span", { className: "shrink-0 inline-flex", children: i ? /* @__PURE__ */ t(ne, { size: f }) : /* @__PURE__ */ t($, { size: f }) }),
1581
+ /* @__PURE__ */ t("span", { className: a === "small" ? "text-xs" : "text-sm", children: i ? `Submitted ${new Date(r).toLocaleDateString()}` : n ? Vt(o) : o.toLocaleDateString() })
1582
+ ]
1583
+ }
1584
+ );
1585
+ }
1586
+ function yr({
1587
+ isCorrect: e,
1588
+ explanation: r,
1589
+ onRetry: n,
1590
+ retryLabel: a = "Try Again",
1591
+ className: s,
1592
+ style: l
1593
+ }) {
1594
+ return /* @__PURE__ */ u(
1595
+ "div",
1596
+ {
1597
+ role: "alert",
1598
+ className: m(
1599
+ "flex items-start gap-2 rounded-md border p-3 text-sm",
1600
+ e ? "border-success/50 bg-success/5" : "border-destructive/50 bg-destructive/5",
1601
+ s
1602
+ ),
1603
+ style: l,
1604
+ children: [
1605
+ /* @__PURE__ */ t("span", { className: m("shrink-0", e ? "text-success" : "text-destructive"), children: e ? /* @__PURE__ */ t(ne, { size: 20 }) : /* @__PURE__ */ t(ze, { size: 20 }) }),
1606
+ /* @__PURE__ */ t("div", { className: "flex-1", children: /* @__PURE__ */ u("div", { className: "flex items-start justify-between gap-2", children: [
1607
+ /* @__PURE__ */ u("div", { children: [
1608
+ /* @__PURE__ */ t("span", { className: "font-semibold", children: e ? "Correct!" : "Incorrect" }),
1609
+ r && /* @__PURE__ */ t("p", { className: "mt-1 text-foreground", children: r })
1610
+ ] }),
1611
+ !e && n && /* @__PURE__ */ t(
1612
+ "button",
1613
+ {
1614
+ className: "shrink-0 rounded-md border border-border bg-background px-3 py-1 text-sm font-medium transition-colors hover:bg-muted",
1615
+ onClick: n,
1616
+ children: a
1617
+ }
1618
+ )
1619
+ ] }) })
1620
+ ]
1621
+ }
1622
+ );
1623
+ }
1624
+ function Nr({
1625
+ value: e,
1626
+ onChange: r,
1627
+ points: n = 5,
1628
+ lowLabel: a = "Strongly Disagree",
1629
+ highLabel: s = "Strongly Agree",
1630
+ disabled: l = !1,
1631
+ readOnly: o = !1,
1632
+ className: i,
1633
+ style: g
1634
+ }) {
1635
+ const f = Array.from({ length: n }, (d, c) => c + 1), h = !l && !o;
1636
+ return /* @__PURE__ */ u("div", { className: m("flex flex-col gap-1", i), style: g, children: [
1637
+ /* @__PURE__ */ t("div", { className: "flex flex-row", role: "radiogroup", children: f.map((d) => {
1638
+ const c = e === d;
1639
+ return /* @__PURE__ */ u(
1640
+ "label",
1641
+ {
1642
+ className: m(
1643
+ "flex items-center justify-center border border-border px-1.5 py-2 text-sm transition-colors first:rounded-l-md last:rounded-r-md -ml-px first:ml-0",
1644
+ c ? "bg-primary text-primary-foreground border-primary z-10" : "bg-background text-foreground",
1645
+ !h && "opacity-60 cursor-not-allowed",
1646
+ h && !c && "cursor-pointer hover:bg-muted"
1647
+ ),
1648
+ children: [
1649
+ /* @__PURE__ */ t(
1650
+ "input",
1651
+ {
1652
+ type: "radio",
1653
+ name: "likert-scale",
1654
+ className: "sr-only",
1655
+ value: d,
1656
+ checked: c,
1657
+ disabled: l,
1658
+ onChange: () => {
1659
+ h && r(d);
1660
+ }
1661
+ }
1662
+ ),
1663
+ /* @__PURE__ */ t("span", { className: "text-sm font-medium", children: d })
1664
+ ]
1665
+ },
1666
+ d
1667
+ );
1668
+ }) }),
1669
+ /* @__PURE__ */ u("div", { className: "flex justify-between", children: [
1670
+ /* @__PURE__ */ t("span", { className: "text-xs text-muted-foreground", children: a }),
1671
+ /* @__PURE__ */ t("span", { className: "text-xs text-muted-foreground", children: s })
1672
+ ] })
1673
+ ] });
1674
+ }
1675
+ const Ft = { small: 18, medium: 24, large: 32 };
1676
+ function wr({
1677
+ value: e,
1678
+ onChange: r,
1679
+ maxStars: n = 5,
1680
+ allowHalf: a = !1,
1681
+ size: s = "medium",
1682
+ disabled: l = !1,
1683
+ readOnly: o = !1,
1684
+ className: i,
1685
+ style: g
1686
+ }) {
1687
+ const [f, h] = v(null), d = Ft[s], c = f ?? e, p = !l && !o;
1688
+ function b(x) {
1689
+ p && r(x);
1690
+ }
1691
+ return /* @__PURE__ */ t(
1692
+ "div",
1693
+ {
1694
+ className: m("inline-flex gap-0.5", i),
1695
+ style: g,
1696
+ onMouseLeave: () => p && h(null),
1697
+ children: Array.from({ length: n }, (x, N) => {
1698
+ const y = N + 1, w = c >= y, z = a && !w && c >= y - 0.5;
1699
+ return /* @__PURE__ */ t(
1700
+ "button",
1701
+ {
1702
+ type: "button",
1703
+ className: m(
1704
+ "inline-flex items-center justify-center rounded-md border-none bg-transparent p-0",
1705
+ p ? "cursor-pointer" : "cursor-default",
1706
+ w || z ? "text-warning" : "text-muted-foreground"
1707
+ ),
1708
+ disabled: l,
1709
+ onClick: () => b(y),
1710
+ onMouseEnter: () => p && h(y),
1711
+ "aria-label": `Rate ${y} star${y !== 1 ? "s" : ""}`,
1712
+ children: /* @__PURE__ */ t(
1713
+ _e,
1714
+ {
1715
+ size: d,
1716
+ fill: w || z ? "currentColor" : "none",
1717
+ strokeWidth: 1.5,
1718
+ style: z ? { clipPath: "inset(0 50% 0 0)" } : void 0
1719
+ }
1720
+ )
1721
+ },
1722
+ N
1723
+ );
1724
+ })
1725
+ }
1726
+ );
1727
+ }
1728
+ function Pt({
1729
+ value: e,
1730
+ size: r = 120,
1731
+ strokeWidth: n = 8,
1732
+ label: a,
1733
+ color: s,
1734
+ className: l,
1735
+ style: o
1736
+ }) {
1737
+ const i = (r - n) / 2, g = 2 * Math.PI * i, f = g - Math.min(Math.max(e, 0), 100) / 100 * g, h = r / 2;
1738
+ return /* @__PURE__ */ u(
1739
+ "div",
1740
+ {
1741
+ className: m("relative inline-flex", l),
1742
+ style: { width: `${r}px`, height: `${r}px`, ...o },
1743
+ children: [
1744
+ /* @__PURE__ */ u("svg", { width: r, height: r, children: [
1745
+ /* @__PURE__ */ t(
1746
+ "circle",
1747
+ {
1748
+ cx: h,
1749
+ cy: h,
1750
+ r: i,
1751
+ fill: "none",
1752
+ stroke: "currentColor",
1753
+ strokeWidth: n,
1754
+ opacity: 0.15
1755
+ }
1756
+ ),
1757
+ /* @__PURE__ */ t(
1758
+ "circle",
1759
+ {
1760
+ cx: h,
1761
+ cy: h,
1762
+ r: i,
1763
+ fill: "none",
1764
+ stroke: s ?? "currentColor",
1765
+ strokeWidth: n,
1766
+ strokeDasharray: g,
1767
+ strokeDashoffset: f,
1768
+ strokeLinecap: "round",
1769
+ transform: `rotate(-90 ${h} ${h})`,
1770
+ style: { transition: "stroke-dashoffset 0.4s ease" }
1771
+ }
1772
+ )
1773
+ ] }),
1774
+ /* @__PURE__ */ t(
1775
+ "span",
1776
+ {
1777
+ className: "absolute inset-0 flex items-center justify-center font-bold text-foreground",
1778
+ style: { fontSize: `${r * 0.2}px` },
1779
+ children: a ?? `${Math.round(e)}%`
1780
+ }
1781
+ )
1782
+ ]
1783
+ }
1784
+ );
1785
+ }
1786
+ const Ot = { small: 48, medium: 64, large: 96 }, At = { small: "0.75rem", medium: "0.875rem", large: "1rem" }, Bt = { small: "4px", medium: "6px", large: "8px" }, Ut = {
1787
+ primary: "var(--primary)",
1788
+ success: "var(--success)",
1789
+ warning: "var(--warning)",
1790
+ destructive: "var(--destructive)"
1791
+ };
1792
+ function Kt(e, r) {
1793
+ return r == null ? "primary" : e >= r ? "success" : e >= r * 0.7 ? "warning" : "destructive";
1794
+ }
1795
+ function Cr({
1796
+ percentage: e,
1797
+ letterGrade: r,
1798
+ variant: n = "circular",
1799
+ size: a = "medium",
1800
+ passingThreshold: s,
1801
+ showLabel: l = !0,
1802
+ className: o,
1803
+ style: i
1804
+ }) {
1805
+ const g = Kt(e, s), f = Ut[g] ?? "var(--primary)";
1806
+ return n === "linear" ? /* @__PURE__ */ u("div", { className: m("flex flex-row items-center gap-1", o), style: i, children: [
1807
+ /* @__PURE__ */ t("div", { className: "flex-1 bg-muted rounded-full overflow-hidden", style: { height: Bt[a] }, children: /* @__PURE__ */ t(
1808
+ "div",
1809
+ {
1810
+ className: "h-full rounded-full transition-[width] duration-300 ease-in-out",
1811
+ style: { width: `${e}%`, background: f }
1812
+ }
1813
+ ) }),
1814
+ l && /* @__PURE__ */ t("span", { className: "font-semibold min-w-9", style: { fontSize: At[a] }, children: r ?? `${Math.round(e)}%` })
1815
+ ] }) : /* @__PURE__ */ t("div", { className: m("inline-flex flex-col items-center", o), style: i, children: /* @__PURE__ */ t(
1816
+ Pt,
1817
+ {
1818
+ value: e,
1819
+ size: Ot[a],
1820
+ strokeWidth: a === "small" ? 4 : 6,
1821
+ color: f,
1822
+ label: r ?? `${Math.round(e)}%`
1823
+ }
1824
+ ) });
1825
+ }
1826
+ const Wt = {
1827
+ up: "var(--success)",
1828
+ down: "var(--destructive)",
1829
+ flat: "var(--muted-foreground)"
1830
+ }, Zt = { up: De, down: Ie, flat: Se };
1831
+ function kr({
1832
+ icon: e,
1833
+ label: r,
1834
+ value: n,
1835
+ subtitle: a,
1836
+ trend: s,
1837
+ className: l,
1838
+ style: o
1839
+ }) {
1840
+ const i = s ? Zt[s.direction] : null;
1841
+ return /* @__PURE__ */ u("div", { className: m("rounded-md border border-border p-4", l), style: o, children: [
1842
+ e && /* @__PURE__ */ t("div", { className: "mb-1 text-primary [&>svg]:size-6", children: e }),
1843
+ /* @__PURE__ */ t("span", { className: "text-xs text-muted-foreground", children: r }),
1844
+ /* @__PURE__ */ u("div", { className: "flex flex-row items-baseline gap-1", children: [
1845
+ /* @__PURE__ */ t("span", { className: "text-2xl font-bold", children: n }),
1846
+ s && i && /* @__PURE__ */ u("span", { className: "flex flex-row items-center gap-px", style: { color: Wt[s.direction] }, children: [
1847
+ /* @__PURE__ */ t(i, { size: 14 }),
1848
+ /* @__PURE__ */ u("span", { className: "text-xs font-semibold", children: [
1849
+ s.value > 0 ? "+" : "",
1850
+ s.value,
1851
+ "%"
1852
+ ] })
1853
+ ] })
1854
+ ] }),
1855
+ a && /* @__PURE__ */ t("span", { className: "text-xs text-muted-foreground", children: a })
1856
+ ] });
1857
+ }
1858
+ const Gt = { small: 28, medium: 36, large: 48 }, Yt = {
1859
+ student: "Student",
1860
+ instructor: "Instructor",
1861
+ ta: "Teaching Assistant",
1862
+ admin: "Admin"
1863
+ }, Xt = {
1864
+ instructor: "var(--primary)",
1865
+ ta: "var(--purple)",
1866
+ admin: "var(--destructive)",
1867
+ student: "var(--muted-foreground)"
1868
+ };
1869
+ function Jt(e) {
1870
+ return e.split(" ").filter(Boolean).map((r) => r[0]).slice(0, 2).join("").toUpperCase();
1871
+ }
1872
+ function Qt({
1873
+ displayName: e,
1874
+ avatarUrl: r,
1875
+ role: n,
1876
+ showRoleBadge: a = !1,
1877
+ size: s = "medium",
1878
+ className: l,
1879
+ style: o
1880
+ }) {
1881
+ const i = Gt[s], g = i * 0.4, [f, h] = v(!1), d = a && n && n !== "student", c = d ? Yt[n] ?? n : void 0;
1882
+ return /* @__PURE__ */ u(
1883
+ "div",
1884
+ {
1885
+ className: m("relative inline-flex", l),
1886
+ style: o,
1887
+ title: c,
1888
+ children: [
1889
+ /* @__PURE__ */ t(
1890
+ "div",
1891
+ {
1892
+ className: "flex items-center justify-center rounded-full bg-muted text-muted-foreground overflow-hidden",
1893
+ style: { width: `${i}px`, height: `${i}px`, fontSize: `${g}px` },
1894
+ children: r && !f ? /* @__PURE__ */ t(
1895
+ "img",
1896
+ {
1897
+ className: "size-full object-cover",
1898
+ src: r,
1899
+ alt: e,
1900
+ onError: () => h(!0)
1901
+ }
1902
+ ) : /* @__PURE__ */ t("span", { children: Jt(e) })
1903
+ }
1904
+ ),
1905
+ d && /* @__PURE__ */ t(
1906
+ "span",
1907
+ {
1908
+ className: "absolute -bottom-0.5 -right-0.5 size-2.5 rounded-full border-2 border-background",
1909
+ style: { background: Xt[n] ?? "var(--muted-foreground)" }
1910
+ }
1911
+ )
1912
+ ]
1913
+ }
1914
+ );
1915
+ }
1916
+ function de({
1917
+ className: e,
1918
+ orientation: r = "horizontal",
1919
+ decorative: n = !0,
1920
+ ...a
1921
+ }) {
1922
+ return /* @__PURE__ */ t(
1923
+ "div",
1924
+ {
1925
+ "data-slot": "separator",
1926
+ role: n ? "none" : "separator",
1927
+ "aria-orientation": n ? void 0 : r,
1928
+ className: m(
1929
+ "bg-border shrink-0",
1930
+ r === "horizontal" ? "h-px w-full" : "h-full w-px",
1931
+ e
1932
+ ),
1933
+ ...a
1934
+ }
1935
+ );
1936
+ }
1937
+ function qt(e) {
1938
+ const r = new Date(e), a = (/* @__PURE__ */ new Date()).getTime() - r.getTime(), s = Math.floor(a / 6e4);
1939
+ if (s < 1) return "Just now";
1940
+ if (s < 60) return `${s}m ago`;
1941
+ const l = Math.floor(s / 60);
1942
+ if (l < 24) return `${l}h ago`;
1943
+ const o = Math.floor(l / 24);
1944
+ return o < 7 ? `${o}d ago` : r.toLocaleDateString();
1945
+ }
1946
+ const er = {
1947
+ pinned: "var(--warning)",
1948
+ answer: "var(--success)"
1949
+ };
1950
+ function Tr({
1951
+ author: e,
1952
+ content: r,
1953
+ createdAt: n,
1954
+ updatedAt: a,
1955
+ actions: s,
1956
+ highlight: l = "none",
1957
+ indentLevel: o = 0,
1958
+ className: i,
1959
+ style: g
1960
+ }) {
1961
+ const f = er[l];
1962
+ return /* @__PURE__ */ t(
1963
+ "div",
1964
+ {
1965
+ className: m("rounded-md border border-border p-3", i),
1966
+ style: {
1967
+ marginLeft: o ? `calc(${o} * 1rem)` : void 0,
1968
+ ...f && {
1969
+ borderLeftWidth: "3px",
1970
+ borderLeftColor: f
1971
+ },
1972
+ ...g
1973
+ },
1974
+ children: /* @__PURE__ */ u("div", { className: "flex gap-2", children: [
1975
+ /* @__PURE__ */ t(
1976
+ Qt,
1977
+ {
1978
+ displayName: e.displayName,
1979
+ avatarUrl: e.avatarUrl,
1980
+ role: e.role,
1981
+ size: "medium"
1982
+ }
1983
+ ),
1984
+ /* @__PURE__ */ u("div", { className: "flex-1 min-w-0", children: [
1985
+ /* @__PURE__ */ u("div", { className: "flex items-center gap-1.5 flex-wrap text-sm", children: [
1986
+ /* @__PURE__ */ t("span", { className: "font-semibold", children: e.displayName }),
1987
+ e.role && e.role !== "student" && /* @__PURE__ */ t("span", { className: "rounded-full bg-primary/10 px-1.5 py-0.5 text-xs font-medium text-primary capitalize", children: e.role }),
1988
+ /* @__PURE__ */ t("span", { className: "text-xs text-muted-foreground", children: qt(n) }),
1989
+ a && /* @__PURE__ */ t("span", { className: "text-xs text-muted-foreground italic", children: "(edited)" }),
1990
+ l === "pinned" && /* @__PURE__ */ t(Le, { size: 14 })
1991
+ ] }),
1992
+ /* @__PURE__ */ t("p", { className: "mt-1 text-sm whitespace-pre-wrap", children: r }),
1993
+ s && /* @__PURE__ */ u(ee, { children: [
1994
+ /* @__PURE__ */ t(de, { className: "my-2" }),
1995
+ /* @__PURE__ */ t("div", { className: "flex items-center gap-1", children: s })
1996
+ ] })
1997
+ ] })
1998
+ ] })
1999
+ }
2000
+ );
2001
+ }
2002
+ const tr = {
2003
+ info: { variant: "info", Icon: je },
2004
+ warning: { variant: "warning", Icon: Ee },
2005
+ tip: { variant: "success", Icon: Me }
2006
+ };
2007
+ function zr({
2008
+ block: e,
2009
+ onQuestionAnswer: r,
2010
+ readOnly: n = !1,
2011
+ className: a,
2012
+ style: s
2013
+ }) {
2014
+ const l = (o) => /* @__PURE__ */ t("div", { className: m(a), style: s, children: o });
2015
+ switch (e.type) {
2016
+ case "video":
2017
+ return l(/* @__PURE__ */ t(pt, { ...e.video, readOnly: n }));
2018
+ case "richtext":
2019
+ return l(
2020
+ /* @__PURE__ */ t(
2021
+ "div",
2022
+ {
2023
+ className: "[&_p]:mb-[1.5em] [&_ul]:pl-[1.5em] [&_ol]:pl-[1.5em]",
2024
+ dangerouslySetInnerHTML: { __html: e.html }
2025
+ }
2026
+ )
2027
+ );
2028
+ case "heading": {
2029
+ const o = e.level === 1 ? "h2" : e.level === 3 ? "h4" : "h3", i = e.level === 1 ? "text-xl" : e.level === 3 ? "text-base" : "text-lg";
2030
+ return l(
2031
+ /* @__PURE__ */ t(o, { className: m(i, "font-semibold m-0"), children: e.text })
2032
+ );
2033
+ }
2034
+ case "image":
2035
+ return l(
2036
+ /* @__PURE__ */ u("figure", { className: "m-0", children: [
2037
+ /* @__PURE__ */ t(
2038
+ "img",
2039
+ {
2040
+ src: e.src,
2041
+ alt: e.alt ?? "",
2042
+ className: "max-w-full rounded-sm"
2043
+ }
2044
+ ),
2045
+ e.caption && /* @__PURE__ */ t("figcaption", { className: "text-xs text-muted-foreground mt-0.5", children: e.caption })
2046
+ ] })
2047
+ );
2048
+ case "callout": {
2049
+ const o = tr[e.variant ?? "info"];
2050
+ return l(
2051
+ /* @__PURE__ */ u(I, { variant: o.variant, children: [
2052
+ /* @__PURE__ */ t(o.Icon, { size: 20 }),
2053
+ /* @__PURE__ */ t(D, { children: e.content })
2054
+ ] })
2055
+ );
2056
+ }
2057
+ case "question":
2058
+ return l(
2059
+ /* @__PURE__ */ t(
2060
+ Je,
2061
+ {
2062
+ question: e.question,
2063
+ onAnswer: (o) => r == null ? void 0 : r(
2064
+ e.question.uid,
2065
+ o.map((i) => ({
2066
+ uid: e.question.uid,
2067
+ answerUid: i.uid,
2068
+ content: i.content
2069
+ }))
2070
+ ),
2071
+ readOnly: n
2072
+ }
2073
+ )
2074
+ );
2075
+ case "flashcards":
2076
+ return l(
2077
+ /* @__PURE__ */ t(
2078
+ ut,
2079
+ {
2080
+ cards: e.cards,
2081
+ deckName: e.deckName,
2082
+ readOnly: n
2083
+ }
2084
+ )
2085
+ );
2086
+ case "divider":
2087
+ return l(/* @__PURE__ */ t(de, {}));
2088
+ case "custom":
2089
+ return l(/* @__PURE__ */ t(ee, { children: e.render }));
2090
+ default:
2091
+ return null;
2092
+ }
2093
+ }
2094
+ function rr(e) {
2095
+ return e < 1024 ? `${e} B` : e < 1024 * 1024 ? `${(e / 1024).toFixed(1)} KB` : `${(e / (1024 * 1024)).toFixed(1)} MB`;
2096
+ }
2097
+ function _r({
2098
+ files: e,
2099
+ onFilesAdded: r,
2100
+ onFileRemove: n,
2101
+ accept: a,
2102
+ maxFiles: s,
2103
+ maxSizeMB: l,
2104
+ disabled: o = !1,
2105
+ label: i = "Drag files here or click to browse"
2106
+ }) {
2107
+ const g = k(null), [f, h] = v(!1), d = s != null && e.length >= s;
2108
+ function c(p) {
2109
+ if (!p) return;
2110
+ let b = Array.from(p);
2111
+ l && (b = b.filter((x) => x.size <= l * 1024 * 1024)), s && (b = b.slice(0, s - e.length)), b.length > 0 && r(b);
2112
+ }
2113
+ return /* @__PURE__ */ u("div", { children: [
2114
+ /* @__PURE__ */ u(
2115
+ "div",
2116
+ {
2117
+ className: m(
2118
+ "border-2 border-dashed border-border rounded-md p-8 text-center cursor-pointer transition-all duration-200",
2119
+ f && "border-primary bg-muted",
2120
+ o && "cursor-default opacity-50",
2121
+ d && "cursor-default"
2122
+ ),
2123
+ onDragOver: (p) => {
2124
+ p.preventDefault(), !o && !d && h(!0);
2125
+ },
2126
+ onDragLeave: () => h(!1),
2127
+ onDrop: (p) => {
2128
+ p.preventDefault(), h(!1), !o && !d && c(p.dataTransfer.files);
2129
+ },
2130
+ onClick: () => {
2131
+ var p;
2132
+ return !o && !d && ((p = g.current) == null ? void 0 : p.click());
2133
+ },
2134
+ children: [
2135
+ /* @__PURE__ */ t($e, { size: 32, className: "mx-auto mb-2 opacity-50" }),
2136
+ /* @__PURE__ */ t("span", { className: "text-sm text-muted-foreground", children: d ? `Maximum ${s} files reached` : i }),
2137
+ (a || l) && /* @__PURE__ */ t("span", { className: "text-xs text-muted-foreground mt-1 block", children: [a && `Accepted: ${a}`, l && `Max: ${l}MB`].filter(Boolean).join(" · ") })
2138
+ ]
2139
+ }
2140
+ ),
2141
+ /* @__PURE__ */ t(
2142
+ "input",
2143
+ {
2144
+ ref: g,
2145
+ type: "file",
2146
+ accept: a,
2147
+ multiple: !s || s > 1,
2148
+ hidden: !0,
2149
+ onChange: (p) => {
2150
+ c(p.target.files), p.target.value = "";
2151
+ }
2152
+ }
2153
+ ),
2154
+ e.length > 0 && /* @__PURE__ */ t("div", { className: "flex flex-col gap-1 mt-2", children: e.map((p, b) => /* @__PURE__ */ u("div", { className: "flex items-center gap-3 py-1", children: [
2155
+ /* @__PURE__ */ t("div", { className: "shrink-0 w-9 flex justify-center text-muted-foreground", children: /* @__PURE__ */ t(Re, { size: 18 }) }),
2156
+ /* @__PURE__ */ u("div", { className: "flex-1 min-w-0", children: [
2157
+ /* @__PURE__ */ t("span", { className: "text-sm block truncate", children: p.name }),
2158
+ /* @__PURE__ */ t("span", { className: "text-xs text-muted-foreground", children: rr(p.size) })
2159
+ ] }),
2160
+ /* @__PURE__ */ t(
2161
+ _,
2162
+ {
2163
+ variant: "ghost",
2164
+ size: "icon-xs",
2165
+ "aria-label": "Remove file",
2166
+ onClick: () => n(b),
2167
+ disabled: o,
2168
+ children: /* @__PURE__ */ t(re, { size: 16 })
2169
+ }
2170
+ )
2171
+ ] }, `${p.name}-${b}`)) })
2172
+ ] });
2173
+ }
2174
+ function Sr({ className: e, ...r }) {
2175
+ return /* @__PURE__ */ t(
2176
+ "div",
2177
+ {
2178
+ "data-slot": "card",
2179
+ className: m(
2180
+ "bg-card text-card-foreground rounded-xl border shadow-sm",
2181
+ e
2182
+ ),
2183
+ ...r
2184
+ }
2185
+ );
2186
+ }
2187
+ function Ir({ className: e, ...r }) {
2188
+ return /* @__PURE__ */ t(
2189
+ "div",
2190
+ {
2191
+ "data-slot": "card-header",
2192
+ className: m(
2193
+ "flex flex-col gap-1.5 px-6 pt-6 has-data-[slot=card-action]:flex-row has-data-[slot=card-action]:items-center has-data-[slot=card-action]:justify-between",
2194
+ e
2195
+ ),
2196
+ ...r
2197
+ }
2198
+ );
2199
+ }
2200
+ function Dr({ className: e, ...r }) {
2201
+ return /* @__PURE__ */ t(
2202
+ "div",
2203
+ {
2204
+ "data-slot": "card-title",
2205
+ className: m("leading-none font-semibold", e),
2206
+ ...r
2207
+ }
2208
+ );
2209
+ }
2210
+ function Lr({ className: e, ...r }) {
2211
+ return /* @__PURE__ */ t(
2212
+ "div",
2213
+ {
2214
+ "data-slot": "card-description",
2215
+ className: m("text-muted-foreground text-sm", e),
2216
+ ...r
2217
+ }
2218
+ );
2219
+ }
2220
+ function Mr({ className: e, ...r }) {
2221
+ return /* @__PURE__ */ t(
2222
+ "div",
2223
+ {
2224
+ "data-slot": "card-action",
2225
+ className: m(
2226
+ "col-start-2 row-span-2 row-start-1 self-start justify-self-end",
2227
+ e
2228
+ ),
2229
+ ...r
2230
+ }
2231
+ );
2232
+ }
2233
+ function Er({ className: e, ...r }) {
2234
+ return /* @__PURE__ */ t(
2235
+ "div",
2236
+ {
2237
+ "data-slot": "card-content",
2238
+ className: m("px-6 pb-6 pt-0", e),
2239
+ ...r
2240
+ }
2241
+ );
2242
+ }
2243
+ function jr({ className: e, ...r }) {
2244
+ return /* @__PURE__ */ t(
2245
+ "div",
2246
+ {
2247
+ "data-slot": "card-footer",
2248
+ className: m("flex items-center px-6 pb-6 pt-0", e),
2249
+ ...r
2250
+ }
2251
+ );
2252
+ }
2253
+ const ce = F(null);
2254
+ function ue() {
2255
+ const e = P(ce);
2256
+ if (!e) throw new Error("Tabs compound components must be used within <Tabs>");
2257
+ return e;
2258
+ }
2259
+ function $r({
2260
+ value: e,
2261
+ defaultValue: r,
2262
+ onValueChange: n,
2263
+ className: a,
2264
+ ...s
2265
+ }) {
2266
+ const [l, o] = v(r ?? ""), i = e ?? l, g = T(
2267
+ (f) => {
2268
+ e === void 0 && o(f), n == null || n(f);
2269
+ },
2270
+ [e, n]
2271
+ );
2272
+ return /* @__PURE__ */ t(ce.Provider, { value: { selectedValue: i, onSelect: g }, children: /* @__PURE__ */ t("div", { "data-slot": "tabs", className: a, ...s }) });
2273
+ }
2274
+ function Rr({
2275
+ className: e,
2276
+ children: r,
2277
+ ...n
2278
+ }) {
2279
+ const a = k(null), s = (l) => {
2280
+ if (l.key !== "ArrowLeft" && l.key !== "ArrowRight") return;
2281
+ const o = a.current;
2282
+ if (!o) return;
2283
+ const i = Array.from(
2284
+ o.querySelectorAll('[role="tab"]:not([disabled])')
2285
+ ), g = i.indexOf(document.activeElement);
2286
+ if (g === -1) return;
2287
+ l.preventDefault();
2288
+ const f = l.key === "ArrowRight" ? (g + 1) % i.length : (g - 1 + i.length) % i.length;
2289
+ i[f].focus();
2290
+ };
2291
+ return /* @__PURE__ */ t(
2292
+ "div",
2293
+ {
2294
+ ref: a,
2295
+ role: "tablist",
2296
+ "data-slot": "tabs-list",
2297
+ className: m(
2298
+ "inline-flex h-9 items-center justify-center rounded-lg bg-muted p-1 text-muted-foreground",
2299
+ e
2300
+ ),
2301
+ onKeyDown: s,
2302
+ ...n,
2303
+ children: r
2304
+ }
2305
+ );
2306
+ }
2307
+ function Vr({ value: e, className: r, ...n }) {
2308
+ const { selectedValue: a, onSelect: s } = ue(), l = a === e;
2309
+ return /* @__PURE__ */ t(
2310
+ "button",
2311
+ {
2312
+ role: "tab",
2313
+ type: "button",
2314
+ "data-slot": "tabs-trigger",
2315
+ "aria-selected": l,
2316
+ ...l ? { "data-selected": "" } : {},
2317
+ className: m(
2318
+ "inline-flex items-center justify-center whitespace-nowrap rounded-md px-3 py-1 text-sm font-medium transition-all cursor-pointer disabled:pointer-events-none disabled:opacity-50 data-selected:bg-background data-selected:text-foreground data-selected:shadow-sm",
2319
+ r
2320
+ ),
2321
+ onClick: () => s(e),
2322
+ ...n
2323
+ }
2324
+ );
2325
+ }
2326
+ function Hr({ value: e, className: r, ...n }) {
2327
+ const { selectedValue: a } = ue();
2328
+ return a !== e ? null : /* @__PURE__ */ t(
2329
+ "div",
2330
+ {
2331
+ role: "tabpanel",
2332
+ "data-slot": "tabs-content",
2333
+ className: m("pt-2", r),
2334
+ ...n
2335
+ }
2336
+ );
2337
+ }
2338
+ function Fr({ className: e, ...r }) {
2339
+ return /* @__PURE__ */ t("div", { "data-slot": "table-container", className: "relative w-full overflow-auto", children: /* @__PURE__ */ t(
2340
+ "table",
2341
+ {
2342
+ "data-slot": "table",
2343
+ className: m("w-full caption-bottom text-sm", e),
2344
+ ...r
2345
+ }
2346
+ ) });
2347
+ }
2348
+ function Pr({ className: e, ...r }) {
2349
+ return /* @__PURE__ */ t(
2350
+ "thead",
2351
+ {
2352
+ "data-slot": "table-header",
2353
+ className: m("[&_tr]:border-b", e),
2354
+ ...r
2355
+ }
2356
+ );
2357
+ }
2358
+ function Or({ className: e, ...r }) {
2359
+ return /* @__PURE__ */ t(
2360
+ "tbody",
2361
+ {
2362
+ "data-slot": "table-body",
2363
+ className: m("[&_tr:last-child]:border-0", e),
2364
+ ...r
2365
+ }
2366
+ );
2367
+ }
2368
+ function Ar({ className: e, ...r }) {
2369
+ return /* @__PURE__ */ t(
2370
+ "tfoot",
2371
+ {
2372
+ "data-slot": "table-footer",
2373
+ className: m(
2374
+ "bg-muted/50 border-t font-medium [&>tr]:last:border-b-0",
2375
+ e
2376
+ ),
2377
+ ...r
2378
+ }
2379
+ );
2380
+ }
2381
+ function Br({ className: e, ...r }) {
2382
+ return /* @__PURE__ */ t(
2383
+ "tr",
2384
+ {
2385
+ "data-slot": "table-row",
2386
+ className: m(
2387
+ "border-b border-border transition-colors hover:bg-muted/50 data-[state=selected]:bg-muted",
2388
+ e
2389
+ ),
2390
+ ...r
2391
+ }
2392
+ );
2393
+ }
2394
+ function Ur({ className: e, ...r }) {
2395
+ return /* @__PURE__ */ t(
2396
+ "th",
2397
+ {
2398
+ "data-slot": "table-head",
2399
+ className: m(
2400
+ "text-muted-foreground h-10 px-3 text-left align-middle font-semibold whitespace-nowrap text-sm [&:has([role=checkbox])]:pr-0 [&>[role=checkbox]]:translate-y-[2px]",
2401
+ e
2402
+ ),
2403
+ ...r
2404
+ }
2405
+ );
2406
+ }
2407
+ function Kr({ className: e, ...r }) {
2408
+ return /* @__PURE__ */ t(
2409
+ "td",
2410
+ {
2411
+ "data-slot": "table-cell",
2412
+ className: m(
2413
+ "px-3 py-2 align-middle [&:has([role=checkbox])]:pr-0 [&>[role=checkbox]]:translate-y-[2px]",
2414
+ e
2415
+ ),
2416
+ ...r
2417
+ }
2418
+ );
2419
+ }
2420
+ function Wr({ className: e, ...r }) {
2421
+ return /* @__PURE__ */ t(
2422
+ "caption",
2423
+ {
2424
+ "data-slot": "table-caption",
2425
+ className: m("text-muted-foreground mt-4 text-sm", e),
2426
+ ...r
2427
+ }
2428
+ );
2429
+ }
2430
+ export {
2431
+ kr as $,
2432
+ I as A,
2433
+ Lt as B,
2434
+ Sr as C,
2435
+ zr as D,
2436
+ gt as E,
2437
+ fr as F,
2438
+ vr as G,
2439
+ gr as H,
2440
+ Xe as I,
2441
+ yr as J,
2442
+ _r as K,
2443
+ Ge as L,
2444
+ dt as M,
2445
+ ut as N,
2446
+ Cr as O,
2447
+ mr as P,
2448
+ Ze as Q,
2449
+ mt as R,
2450
+ Nr as S,
2451
+ Ue as T,
2452
+ Tr as U,
2453
+ Pt as V,
2454
+ ot as W,
2455
+ Je as X,
2456
+ br as Y,
2457
+ de as Z,
2458
+ wr as _,
2459
+ Qe as a,
2460
+ xr as a0,
2461
+ Fr as a1,
2462
+ Or as a2,
2463
+ Wr as a3,
2464
+ Kr as a4,
2465
+ Ar as a5,
2466
+ Ur as a6,
2467
+ Pr as a7,
2468
+ Br as a8,
2469
+ $r as a9,
2470
+ Hr as aa,
2471
+ Rr as ab,
2472
+ Vr as ac,
2473
+ Ye as ad,
2474
+ et as ae,
2475
+ tt as af,
2476
+ nt as ag,
2477
+ rt as ah,
2478
+ We as ai,
2479
+ Qt as aj,
2480
+ pt as ak,
2481
+ Be as al,
2482
+ Dt as am,
2483
+ A as an,
2484
+ ht as ao,
2485
+ D as b,
2486
+ m as c,
2487
+ yt as d,
2488
+ St as e,
2489
+ Y as f,
2490
+ wt as g,
2491
+ It as h,
2492
+ Ct as i,
2493
+ _t as j,
2494
+ Tt as k,
2495
+ kt as l,
2496
+ Nt as m,
2497
+ zt as n,
2498
+ pr as o,
2499
+ cr as p,
2500
+ ur as q,
2501
+ _ as r,
2502
+ Mr as s,
2503
+ Er as t,
2504
+ Lr as u,
2505
+ jr as v,
2506
+ Ir as w,
2507
+ Dr as x,
2508
+ Ke as y,
2509
+ hr as z
2510
+ };