transcriptify 1.0.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.
Files changed (135) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +78 -0
  3. package/dist/src/generateHtml.d.ts +3 -0
  4. package/dist/src/generateHtml.js +303 -0
  5. package/dist/src/index.d.ts +5 -0
  6. package/dist/src/index.js +252 -0
  7. package/dist/src/transcript.d.ts +12 -0
  8. package/dist/src/transcript.js +179 -0
  9. package/dist/src/types/entities.d.ts +30 -0
  10. package/dist/src/types/entities.js +2 -0
  11. package/dist/src/utils/assetManager.d.ts +12 -0
  12. package/dist/src/utils/assetManager.js +295 -0
  13. package/dist/src/utils/authors.d.ts +4 -0
  14. package/dist/src/utils/authors.js +115 -0
  15. package/dist/src/utils/cache.d.ts +16 -0
  16. package/dist/src/utils/cache.js +29 -0
  17. package/dist/src/utils/extractors.d.ts +112 -0
  18. package/dist/src/utils/extractors.js +223 -0
  19. package/dist/src/utils/polls.d.ts +2 -0
  20. package/dist/src/utils/polls.js +91 -0
  21. package/dist/src/utils/transformer.d.ts +6 -0
  22. package/dist/src/utils/transformer.js +78 -0
  23. package/dist/src/utils/user.d.ts +4 -0
  24. package/dist/src/utils/user.js +56 -0
  25. package/dist/src/web/client.d.ts +20 -0
  26. package/dist/src/web/client.js +21 -0
  27. package/dist/src/web/discord-components/AudioPlayer.d.ts +5 -0
  28. package/dist/src/web/discord-components/AudioPlayer.js +231 -0
  29. package/dist/src/web/discord-components/Button.d.ts +3 -0
  30. package/dist/src/web/discord-components/Button.js +27 -0
  31. package/dist/src/web/discord-components/ChannelPinnedMessage.d.ts +7 -0
  32. package/dist/src/web/discord-components/ChannelPinnedMessage.js +11 -0
  33. package/dist/src/web/discord-components/DateSeperator.d.ts +3 -0
  34. package/dist/src/web/discord-components/DateSeperator.js +19 -0
  35. package/dist/src/web/discord-components/Embed.d.ts +2 -0
  36. package/dist/src/web/discord-components/Embed.js +78 -0
  37. package/dist/src/web/discord-components/ForwardedMessage.d.ts +2 -0
  38. package/dist/src/web/discord-components/ForwardedMessage.js +44 -0
  39. package/dist/src/web/discord-components/Message.d.ts +2 -0
  40. package/dist/src/web/discord-components/Message.js +543 -0
  41. package/dist/src/web/discord-components/PinnedMessagesModal.d.ts +6 -0
  42. package/dist/src/web/discord-components/PinnedMessagesModal.js +119 -0
  43. package/dist/src/web/discord-components/PinnedMessagesOverview.d.ts +5 -0
  44. package/dist/src/web/discord-components/PinnedMessagesOverview.js +22 -0
  45. package/dist/src/web/discord-components/Reply.d.ts +2 -0
  46. package/dist/src/web/discord-components/Reply.js +42 -0
  47. package/dist/src/web/discord-components/StickerPreview.d.ts +6 -0
  48. package/dist/src/web/discord-components/StickerPreview.js +40 -0
  49. package/dist/src/web/discord-components/ThemeSwitcher.d.ts +2 -0
  50. package/dist/src/web/discord-components/ThemeSwitcher.js +54 -0
  51. package/dist/src/web/discord-components/Transcript.d.ts +2 -0
  52. package/dist/src/web/discord-components/Transcript.js +174 -0
  53. package/dist/src/web/discord-components/UserJoinMessage.d.ts +3 -0
  54. package/dist/src/web/discord-components/UserJoinMessage.js +33 -0
  55. package/dist/src/web/discord-components/VideoPlayer.d.ts +6 -0
  56. package/dist/src/web/discord-components/VideoPlayer.js +222 -0
  57. package/dist/src/web/discord-components/icons/ChevronDownIcon.d.ts +1 -0
  58. package/dist/src/web/discord-components/icons/ChevronDownIcon.js +7 -0
  59. package/dist/src/web/discord-components/icons/CloseIcon.d.ts +1 -0
  60. package/dist/src/web/discord-components/icons/CloseIcon.js +7 -0
  61. package/dist/src/web/discord-components/icons/ExternalLinkIcon.d.ts +1 -0
  62. package/dist/src/web/discord-components/icons/ExternalLinkIcon.js +7 -0
  63. package/dist/src/web/discord-components/icons/FileAudioIcon.d.ts +1 -0
  64. package/dist/src/web/discord-components/icons/FileAudioIcon.js +7 -0
  65. package/dist/src/web/discord-components/icons/FileCodeIcon.d.ts +1 -0
  66. package/dist/src/web/discord-components/icons/FileCodeIcon.js +7 -0
  67. package/dist/src/web/discord-components/icons/FileDocumentIcon.d.ts +1 -0
  68. package/dist/src/web/discord-components/icons/FileDocumentIcon.js +7 -0
  69. package/dist/src/web/discord-components/icons/PinIcon.d.ts +1 -0
  70. package/dist/src/web/discord-components/icons/PinIcon.js +7 -0
  71. package/dist/src/web/discord-components/icons/VerifiedIcon.d.ts +1 -0
  72. package/dist/src/web/discord-components/icons/VerifiedIcon.js +7 -0
  73. package/dist/src/web/discord-components/index.d.ts +11 -0
  74. package/dist/src/web/discord-components/index.js +24 -0
  75. package/dist/src/web/discord-components/messageHelpers.d.ts +8 -0
  76. package/dist/src/web/discord-components/messageHelpers.js +72 -0
  77. package/dist/src/web/discord-components/themeColors.d.ts +9 -0
  78. package/dist/src/web/discord-components/themeColors.js +320 -0
  79. package/dist/src/web/discord-components/transcriptHelpers.d.ts +19 -0
  80. package/dist/src/web/discord-components/transcriptHelpers.js +120 -0
  81. package/dist/src/web/discord-components/types.d.ts +1 -0
  82. package/dist/src/web/discord-components/types.js +2 -0
  83. package/dist/src/web/discord-components/utils/date.d.ts +3 -0
  84. package/dist/src/web/discord-components/utils/date.js +50 -0
  85. package/dist/src/web/discord-components/utils/markdown.d.ts +11 -0
  86. package/dist/src/web/discord-components/utils/markdown.js +538 -0
  87. package/dist/src/web/discord-components/utils/markdownUtils.d.ts +12 -0
  88. package/dist/src/web/discord-components/utils/markdownUtils.js +140 -0
  89. package/dist/src/web/helpers/avatarHelpers.d.ts +2 -0
  90. package/dist/src/web/helpers/avatarHelpers.js +15 -0
  91. package/dist/src/web/helpers/cdnHelpers.d.ts +5 -0
  92. package/dist/src/web/helpers/cdnHelpers.js +48 -0
  93. package/dist/src/web/helpers/contentHelpers.d.ts +9 -0
  94. package/dist/src/web/helpers/contentHelpers.js +41 -0
  95. package/dist/src/web/helpers/renderContent.d.ts +2 -0
  96. package/dist/src/web/helpers/renderContent.js +15 -0
  97. package/dist/src/web/helpers/scrollHelpers.d.ts +2 -0
  98. package/dist/src/web/helpers/scrollHelpers.js +31 -0
  99. package/dist/src/web/helpers/timestampHelpers.d.ts +6 -0
  100. package/dist/src/web/helpers/timestampHelpers.js +66 -0
  101. package/dist/src/web/hooks/useMessageContent.d.ts +5 -0
  102. package/dist/src/web/hooks/useMessageContent.js +37 -0
  103. package/dist/src/web/index.d.ts +1 -0
  104. package/dist/src/web/index.js +17 -0
  105. package/dist/src/web/types/attachment.d.ts +6 -0
  106. package/dist/src/web/types/attachment.js +2 -0
  107. package/dist/src/web/types/author.d.ts +14 -0
  108. package/dist/src/web/types/author.js +2 -0
  109. package/dist/src/web/types/channel.d.ts +8 -0
  110. package/dist/src/web/types/channel.js +2 -0
  111. package/dist/src/web/types/embed.d.ts +52 -0
  112. package/dist/src/web/types/embed.js +2 -0
  113. package/dist/src/web/types/interaction.d.ts +8 -0
  114. package/dist/src/web/types/interaction.js +2 -0
  115. package/dist/src/web/types/markdown.d.ts +5 -0
  116. package/dist/src/web/types/markdown.js +2 -0
  117. package/dist/src/web/types/message.d.ts +73 -0
  118. package/dist/src/web/types/message.js +2 -0
  119. package/dist/src/web/types/poll.d.ts +11 -0
  120. package/dist/src/web/types/poll.js +2 -0
  121. package/dist/src/web/types/props.d.ts +155 -0
  122. package/dist/src/web/types/props.js +2 -0
  123. package/dist/src/web/types/reaction.d.ts +6 -0
  124. package/dist/src/web/types/reaction.js +2 -0
  125. package/dist/src/web/types/theme.d.ts +14 -0
  126. package/dist/src/web/types/theme.js +2 -0
  127. package/dist/src/web/types/ui.d.ts +10 -0
  128. package/dist/src/web/types/ui.js +2 -0
  129. package/dist/types/download.d.ts +12 -0
  130. package/dist/types/download.js +2 -0
  131. package/dist/types/exportableTranscript.d.ts +169 -0
  132. package/dist/types/exportableTranscript.js +2 -0
  133. package/dist/types/general.d.ts +90 -0
  134. package/dist/types/general.js +2 -0
  135. package/package.json +46 -0
@@ -0,0 +1,222 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.default = VideoPlayer;
7
+ const jsx_runtime_1 = require("react/jsx-runtime");
8
+ const react_1 = __importDefault(require("react"));
9
+ function VideoPlayer({ url, filename, filesize }) {
10
+ const videoRef = react_1.default.useRef(null);
11
+ const [isPlaying, setIsPlaying] = react_1.default.useState(false);
12
+ const [currentTime, setCurrentTime] = react_1.default.useState(0);
13
+ const [duration, setDuration] = react_1.default.useState(0);
14
+ const [isMuted, setIsMuted] = react_1.default.useState(false);
15
+ const [volume, setVolume] = react_1.default.useState(1);
16
+ const volTrackRef = react_1.default.useRef(null);
17
+ const draggingRef = react_1.default.useRef(false);
18
+ const [showVolPopover, setShowVolPopover] = react_1.default.useState(false);
19
+ const hideTimeoutRef = react_1.default.useRef(null);
20
+ const popoverContainerRef = react_1.default.useRef(null);
21
+ const popoverRef = react_1.default.useRef(null);
22
+ const cancelHide = () => {
23
+ if (hideTimeoutRef.current !== null) {
24
+ window.clearTimeout(hideTimeoutRef.current);
25
+ hideTimeoutRef.current = null;
26
+ }
27
+ };
28
+ const scheduleHide = (ms = 260) => {
29
+ cancelHide();
30
+ hideTimeoutRef.current = window.setTimeout(() => {
31
+ hideTimeoutRef.current = null;
32
+ setShowVolPopover(false);
33
+ }, ms);
34
+ };
35
+ react_1.default.useEffect(() => {
36
+ return () => {
37
+ cancelHide();
38
+ };
39
+ }, []);
40
+ react_1.default.useEffect(() => {
41
+ if (!showVolPopover)
42
+ return;
43
+ const onMove = (e) => {
44
+ const el = popoverContainerRef.current;
45
+ const pop = popoverRef.current;
46
+ if (!el && !pop)
47
+ return;
48
+ let left = Infinity, top = Infinity, right = -Infinity, bottom = -Infinity;
49
+ const addRect = (r) => {
50
+ if (!r)
51
+ return;
52
+ left = Math.min(left, r.left);
53
+ top = Math.min(top, r.top);
54
+ right = Math.max(right, r.right);
55
+ bottom = Math.max(bottom, r.bottom);
56
+ };
57
+ addRect(el ? el.getBoundingClientRect() : null);
58
+ addRect(pop ? pop.getBoundingClientRect() : null);
59
+ const expand = 20;
60
+ const inside = e.clientX >= left - expand && e.clientX <= right + expand && e.clientY >= top - expand && e.clientY <= bottom + expand;
61
+ if (inside) {
62
+ cancelHide();
63
+ }
64
+ else {
65
+ scheduleHide(400);
66
+ }
67
+ };
68
+ window.addEventListener("mousemove", onMove);
69
+ return () => window.removeEventListener("mousemove", onMove);
70
+ }, [showVolPopover]);
71
+ const handleVolPointer = (clientY) => {
72
+ const el = volTrackRef.current;
73
+ if (!el || !videoRef.current)
74
+ return;
75
+ const rect = el.getBoundingClientRect();
76
+ const y = clientY - rect.top;
77
+ const pct = 1 - y / rect.height;
78
+ const v = Math.max(0, Math.min(1, pct));
79
+ videoRef.current.volume = v;
80
+ videoRef.current.muted = v === 0;
81
+ setVolume(v);
82
+ setIsMuted(v === 0);
83
+ };
84
+ const onGlobalMouseMove = (e) => {
85
+ if (!draggingRef.current)
86
+ return;
87
+ handleVolPointer(e.clientY);
88
+ };
89
+ const onGlobalMouseUp = () => {
90
+ draggingRef.current = false;
91
+ window.removeEventListener("mousemove", onGlobalMouseMove);
92
+ window.removeEventListener("mouseup", onGlobalMouseUp);
93
+ };
94
+ const startDrag = (ev) => {
95
+ draggingRef.current = true;
96
+ handleVolPointer(ev.clientY);
97
+ window.addEventListener("mousemove", onGlobalMouseMove);
98
+ window.addEventListener("mouseup", onGlobalMouseUp);
99
+ };
100
+ const startTouchDrag = (touch) => {
101
+ draggingRef.current = true;
102
+ handleVolPointer(touch.clientY);
103
+ const onTouchMove = (e) => handleVolPointer(e.touches[0].clientY);
104
+ const onTouchEnd = () => {
105
+ draggingRef.current = false;
106
+ window.removeEventListener("touchmove", onTouchMove);
107
+ window.removeEventListener("touchend", onTouchEnd);
108
+ };
109
+ window.addEventListener("touchmove", onTouchMove);
110
+ window.addEventListener("touchend", onTouchEnd);
111
+ };
112
+ const formatTime = (seconds) => {
113
+ if (!isFinite(seconds))
114
+ return "0:00";
115
+ const mins = Math.floor(seconds / 60);
116
+ const secs = Math.floor(seconds % 60);
117
+ return `${mins}:${secs.toString().padStart(2, "0")}`;
118
+ };
119
+ const togglePlay = () => {
120
+ if (videoRef.current) {
121
+ if (isPlaying) {
122
+ videoRef.current.pause();
123
+ }
124
+ else {
125
+ videoRef.current.play().catch((err) => {
126
+ console.error("Playback failed:", err);
127
+ setIsPlaying(false);
128
+ });
129
+ }
130
+ }
131
+ };
132
+ const handlePlay = () => setIsPlaying(true);
133
+ const handlePause = () => setIsPlaying(false);
134
+ const handleTimeUpdate = () => {
135
+ if (videoRef.current)
136
+ setCurrentTime(videoRef.current.currentTime);
137
+ };
138
+ const handleLoadedMetadata = () => {
139
+ if (videoRef.current)
140
+ setDuration(videoRef.current.duration);
141
+ };
142
+ const handleEnded = () => setIsPlaying(false);
143
+ react_1.default.useEffect(() => {
144
+ const v = videoRef.current;
145
+ if (!v)
146
+ return;
147
+ if (!v.src)
148
+ v.src = url;
149
+ setVolume(v.volume);
150
+ setIsMuted(v.muted);
151
+ setIsPlaying(!v.paused);
152
+ if (isFinite(v.duration) && v.duration > 0)
153
+ setDuration(v.duration);
154
+ setCurrentTime(v.currentTime);
155
+ v.addEventListener("timeupdate", handleTimeUpdate);
156
+ v.addEventListener("loadedmetadata", handleLoadedMetadata);
157
+ v.addEventListener("ended", handleEnded);
158
+ v.addEventListener("play", handlePlay);
159
+ v.addEventListener("pause", handlePause);
160
+ const handleVolumeChangeEvent = () => {
161
+ if (videoRef.current) {
162
+ setVolume(videoRef.current.volume);
163
+ setIsMuted(videoRef.current.muted);
164
+ }
165
+ };
166
+ v.addEventListener("volumechange", handleVolumeChangeEvent);
167
+ return () => {
168
+ v.removeEventListener("timeupdate", handleTimeUpdate);
169
+ v.removeEventListener("loadedmetadata", handleLoadedMetadata);
170
+ v.removeEventListener("ended", handleEnded);
171
+ v.removeEventListener("play", handlePlay);
172
+ v.removeEventListener("pause", handlePause);
173
+ v.removeEventListener("volumechange", handleVolumeChangeEvent);
174
+ };
175
+ }, [url]);
176
+ const handleSliderChange = (e) => {
177
+ const newTime = parseFloat(e.target.value);
178
+ if (videoRef.current) {
179
+ videoRef.current.currentTime = newTime;
180
+ setCurrentTime(newTime);
181
+ }
182
+ };
183
+ return ((0, jsx_runtime_1.jsxs)("div", { className: "w-full max-w-[520px] bg-[#1e1f22] border border-[#111214] rounded-lg overflow-hidden", children: [(0, jsx_runtime_1.jsx)("video", { ref: videoRef, src: url, className: "w-full h-auto block bg-black max-h-[312px]", preload: "metadata" }), (0, jsx_runtime_1.jsxs)("div", { className: "p-4", children: [(0, jsx_runtime_1.jsxs)("div", { className: "flex items-center justify-between mb-3", children: [(0, jsx_runtime_1.jsxs)("div", { className: "flex items-center gap-2 flex-1 min-w-0", children: [(0, jsx_runtime_1.jsx)("div", { className: "w-8 h-10 flex-shrink-0 flex items-center justify-center", children: (0, jsx_runtime_1.jsx)("svg", { width: "24", height: "24", viewBox: "0 0 24 24", fill: "none", children: (0, jsx_runtime_1.jsx)("path", { fill: "#b5bac1", d: "M4 3a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2V5a2 2 0 0 0-2-2H4zm8 6a2 2 0 1 1 0 4 2 2 0 0 1 0-4z" }) }) }), (0, jsx_runtime_1.jsxs)("div", { className: "min-w-0", children: [(0, jsx_runtime_1.jsx)("a", { href: url, download: true, className: "text-[15px] font-medium text-[#00a8fc] truncate hover:underline block", children: filename }), (0, jsx_runtime_1.jsx)("div", { className: "text-xs text-[#b5bac1]", children: filesize })] })] }), (0, jsx_runtime_1.jsx)("a", { href: url, download: true, className: "ml-2 p-1 hover:bg-[#23252b] rounded transition-colors flex-shrink-0", title: "Download", children: (0, jsx_runtime_1.jsx)("svg", { width: "20", height: "20", viewBox: "0 0 24 24", children: (0, jsx_runtime_1.jsx)("path", { fill: "#b5bac1", d: "M12 2a1 1 0 0 1 1 1v10.59l3.3-3.3a1 1 0 1 1 1.4 1.42l-5 5a1 1 0 0 1-1.4 0l-5-5a1 1 0 1 1 1.4-1.42l3.3 3.3V3a1 1 0 0 1 1-1ZM3 20a1 1 0 1 0 0 2h18a1 1 0 1 0 0-2H3Z" }) }) })] }), (0, jsx_runtime_1.jsxs)("div", { className: "flex items-center gap-2", children: [(0, jsx_runtime_1.jsx)("button", { onClick: togglePlay, className: "p-2 hover:bg-[#23252b] rounded transition-colors flex-shrink-0", title: isPlaying ? "Pause" : "Play", children: isPlaying ? ((0, jsx_runtime_1.jsx)("svg", { className: "controlIcon_cf09d8", "aria-hidden": "true", role: "img", xmlns: "http://www.w3.org/2000/svg", width: "20", height: "20", fill: "none", viewBox: "0 0 24 24", children: (0, jsx_runtime_1.jsx)("path", { fill: "currentColor", d: "M6 4a1 1 0 0 0-1 1v14a1 1 0 0 0 1 1h3a1 1 0 0 0 1-1V5a1 1 0 0 0-1-1H6ZM15 4a1 1 0 0 0-1 1v14a1 1 0 0 0 1 1h3a1 1 0 0 0 1-1V5a1 1 0 0 0-1-1h-3Z", className: "" }) })) : ((0, jsx_runtime_1.jsx)("svg", { className: "controlIcon_cf09d8", "aria-hidden": "true", role: "img", xmlns: "http://www.w3.org/2000/svg", width: "20", height: "20", fill: "none", viewBox: "0 0 24 24", children: (0, jsx_runtime_1.jsx)("path", { fill: "currentColor", d: "M9.25 3.35C7.87 2.45 6 3.38 6 4.96v14.08c0 1.58 1.87 2.5 3.25 1.61l10.85-7.04a1.9 1.9 0 0 0 0-3.22L9.25 3.35Z", className: "" }) })) }), (0, jsx_runtime_1.jsxs)("span", { className: "text-xs text-[#b5bac1] min-w-[60px]", children: [formatTime(currentTime), " / ", formatTime(duration)] }), (0, jsx_runtime_1.jsxs)("div", { className: "flex-1 relative h-3", children: [(0, jsx_runtime_1.jsx)("div", { className: "absolute left-0 right-0 top-1/2 transform -translate-y-1/2 h-1 bg-[#23252b] rounded" }), (0, jsx_runtime_1.jsx)("div", { className: "absolute left-0 top-1/2 transform -translate-y-1/2 h-1 bg-[#7c5cff] rounded pointer-events-none", style: { width: `${duration > 0 ? (currentTime / duration) * 100 : 0}%` } }), (0, jsx_runtime_1.jsx)("input", { type: "range", min: 0, max: duration || 0, value: currentTime, onChange: handleSliderChange, className: "absolute left-0 top-0 w-full h-3 bg-transparent appearance-none cursor-pointer" })] }), (0, jsx_runtime_1.jsxs)("div", { ref: (el) => {
184
+ popoverContainerRef.current = el;
185
+ }, className: "relative flex-shrink-0", onMouseEnter: () => {
186
+ cancelHide();
187
+ setShowVolPopover(true);
188
+ }, onMouseLeave: () => {
189
+ scheduleHide(260);
190
+ }, children: [(0, jsx_runtime_1.jsx)("button", { onClick: () => {
191
+ if (videoRef.current) {
192
+ const next = !videoRef.current.muted;
193
+ videoRef.current.muted = next;
194
+ setIsMuted(next);
195
+ }
196
+ }, className: "w-8 h-8 p-1 hover:bg-[#23252b] rounded transition-colors flex items-center justify-center", title: "Toggle mute", children: isMuted ? ((0, jsx_runtime_1.jsx)("svg", { className: "volumeButtonIcon_a8e786", "aria-hidden": "true", role: "img", xmlns: "http://www.w3.org/2000/svg", width: "100%", height: "100%", fill: "none", viewBox: "0 0 24 24", children: (0, jsx_runtime_1.jsx)("path", { fill: "currentColor", d: "M12 3a1 1 0 0 0-1-1h-.06a1 1 0 0 0-.74.32L5.92 7H3a1 1 0 0 0-1 1v8a1 1 0 0 0 1 1h2.92l4.28 4.68a1 1 0 0 0 .74.32H11a1 1 0 0 0 1-1V3ZM22.7 8.3a1 1 0 0 0-1.4 0L19 10.58l-2.3-2.3a1 1 0 1 0-1.4 1.42L17.58 12l-2.3 2.3a1 1 0 0 0 1.42 1.4L19 13.42l2.3 2.3a1 1 0 0 0 1.4-1.42L20.42 12l2.3-2.3a1 1 0 0 0 0-1.4Z", className: "" }) })) : ((0, jsx_runtime_1.jsx)("svg", { width: "100%", height: "100%", viewBox: "0 0 24 24", fill: "#b5bac1", children: (0, jsx_runtime_1.jsx)("path", { d: "M5 9v6h4l5 5V4L9 9H5z" }) })) }), (0, jsx_runtime_1.jsx)("div", { ref: (el) => {
197
+ popoverRef.current = el;
198
+ }, className: `absolute left-1/2 bottom-full volume-popover transition-opacity flex flex-col items-center z-50`, style: {
199
+ transform: "translate(-50%, -2px)",
200
+ width: 14,
201
+ padding: 2,
202
+ opacity: showVolPopover ? 1 : 0,
203
+ pointerEvents: showVolPopover ? "auto" : "none"
204
+ }, children: (0, jsx_runtime_1.jsx)("div", { ref: (el) => {
205
+ volTrackRef.current = el;
206
+ }, onClick: (e) => handleVolPointer(e.clientY), onMouseDown: (e) => {
207
+ cancelHide();
208
+ startDrag(e.nativeEvent);
209
+ }, onTouchStart: (e) => {
210
+ cancelHide();
211
+ startTouchDrag(e.touches[0]);
212
+ }, className: "relative h-28 overflow-visible cursor-pointer flex items-end justify-center", title: "Volume", style: { width: 10 }, children: (0, jsx_runtime_1.jsx)("div", { style: {
213
+ position: "absolute",
214
+ left: "50%",
215
+ transform: "translateX(-50%)",
216
+ bottom: 0,
217
+ width: 6,
218
+ borderRadius: 6,
219
+ background: "#7c5cff",
220
+ height: `${volume * 100}%`
221
+ } }) }) })] })] })] })] }));
222
+ }
@@ -0,0 +1 @@
1
+ export default function ChevronDownIcon(props: React.SVGProps<SVGSVGElement>): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,7 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.default = ChevronDownIcon;
4
+ const jsx_runtime_1 = require("react/jsx-runtime");
5
+ function ChevronDownIcon(props) {
6
+ return ((0, jsx_runtime_1.jsx)("svg", { xmlns: "http://www.w3.org/2000/svg", width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", ...props, children: (0, jsx_runtime_1.jsx)("path", { d: "M7 10l5 5 5-5", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round" }) }));
7
+ }
@@ -0,0 +1 @@
1
+ export default function CloseIcon(props: React.SVGProps<SVGSVGElement>): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,7 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.default = CloseIcon;
4
+ const jsx_runtime_1 = require("react/jsx-runtime");
5
+ function CloseIcon(props) {
6
+ return ((0, jsx_runtime_1.jsxs)("svg", { width: "20", height: "20", viewBox: "0 0 24 24", fill: "none", ...props, children: [(0, jsx_runtime_1.jsx)("line", { x1: "18", y1: "6", x2: "6", y2: "18", stroke: "currentColor", strokeWidth: "2" }), (0, jsx_runtime_1.jsx)("line", { x1: "6", y1: "6", x2: "18", y2: "18", stroke: "currentColor", strokeWidth: "2" })] }));
7
+ }
@@ -0,0 +1 @@
1
+ export default function ExternalLinkIcon(props: React.SVGProps<SVGSVGElement>): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,7 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.default = ExternalLinkIcon;
4
+ const jsx_runtime_1 = require("react/jsx-runtime");
5
+ function ExternalLinkIcon(props) {
6
+ return ((0, jsx_runtime_1.jsxs)("svg", { className: "ml-2 inline-block", "aria-hidden": "true", role: "img", xmlns: "http://www.w3.org/2000/svg", width: "16", height: "16", fill: "none", viewBox: "0 0 24 24", ...props, children: [(0, jsx_runtime_1.jsx)("path", { fill: "currentColor", d: "M15 2a1 1 0 0 1 1-1h6a1 1 0 0 1 1 1v6a1 1 0 1 1-2 0V4.41l-4.3 4.3a1 1 0 1 1-1.4-1.42L19.58 3H16a1 1 0 0 1-1-1Z" }), (0, jsx_runtime_1.jsx)("path", { fill: "currentColor", d: "M5 2a3 3 0 0 0-3 3v14a3 3 0 0 0 3 3h14a3 3 0 0 0 3-3v-6a1 1 0 1 0-2 0v6a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V5a1 1 0 0 1 1-1h6a1 1 0 1 0 0-2H5Z" })] }));
7
+ }
@@ -0,0 +1 @@
1
+ export default function FileAudioIcon(props: React.SVGProps<SVGSVGElement>): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,7 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.default = FileAudioIcon;
4
+ const jsx_runtime_1 = require("react/jsx-runtime");
5
+ function FileAudioIcon(props) {
6
+ return ((0, jsx_runtime_1.jsxs)("svg", { fill: "none", height: "96", viewBox: "0 0 72 96", width: "72", xmlns: "http://www.w3.org/2000/svg", ...props, children: [(0, jsx_runtime_1.jsx)("path", { d: "m72 29.3v60.3c0 2.24 0 3.36-.44 4.22-.38.74-1 1.36-1.74 1.74-.86.44-1.98.44-4.22.44h-59.2c-2.24 0-3.36 0-4.22-.44-.74-.38-1.36-1-1.74-1.74-.44-.86-.44-1.98-.44-4.22v-83.2c0-2.24 0-3.36.44-4.22.38-.74 1-1.36 1.74-1.74.86-.44 1.98-.44 4.22-.44h36.3c1.96 0 2.94 0 3.86.22.5.12.98.28 1.44.5v16.88c0 2.24 0 3.36.44 4.22.38.74 1 1.36 1.74 1.74.86.44 1.98.44 4.22.44h16.88c.22.46.38.94.5 1.44.22.92.22 1.9.22 3.86z", fill: "#d3d6fd" }), (0, jsx_runtime_1.jsx)("path", { d: "m68.26 20.26c1.38 1.38 2.06 2.06 2.56 2.88.18.28.32.56.46.86h-16.88c-2.24 0-3.36 0-4.22-.44-.74-.38-1.36-1-1.74-1.74-.44-.86-.44-1.98-.44-4.22v-16.880029c.3.14.58.28.86.459999.82.5 1.5 1.18 2.88 2.56z", fill: "#939bf9" }), (0, jsx_runtime_1.jsx)("path", { clipRule: "evenodd", d: "m34.76 42.16c-.74-.3-1.6-.14-2.18.44l-8.58 9.4h-6c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h6l8.58 9.42c.58.58 1.44.74 2.18.44.76-.32 1.24-1.06 1.24-1.86v-32c0-.8-.48-1.54-1.24-1.84zm5.24 3.84v4c5.52 0 10 4.48 10 10s-4.48 10-10 10v4c7.72 0 14-6.28 14-14s-6.28-14-14-14zm0 8c3.3 0 6 2.7 6 6s-2.7 6-6 6v-4c1.1 0 2-.9 2-2s-.9-2-2-2z", fill: "#5865f2", fillRule: "evenodd" })] }));
7
+ }
@@ -0,0 +1 @@
1
+ export default function FileCodeIcon(props: React.SVGProps<SVGSVGElement>): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,7 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.default = FileCodeIcon;
4
+ const jsx_runtime_1 = require("react/jsx-runtime");
5
+ function FileCodeIcon(props) {
6
+ return ((0, jsx_runtime_1.jsxs)("svg", { fill: "none", height: "96", viewBox: "0 0 72 96", width: "72", xmlns: "http://www.w3.org/2000/svg", ...props, children: [(0, jsx_runtime_1.jsx)("path", { d: "m72 29.3v60.3c0 2.24 0 3.36-.44 4.22-.38.74-1 1.36-1.74 1.74-.86.44-1.98.44-4.22.44h-59.2c-2.24 0-3.36 0-4.22-.44-.74-.38-1.36-1-1.74-1.74-.44-.86-.44-1.98-.44-4.22v-83.2c0-2.24 0-3.36.44-4.22.38-.74 1-1.36 1.74-1.74.86-.44 1.98-.44 4.22-.44h36.3c1.96 0 2.94 0 3.86.22.5.12.98.28 1.44.5v16.88c0 2.24 0 3.36.44 4.22.38.74 1 1.36 1.74 1.74.86.44 1.98.44 4.22.44h16.88c.22.46.38.94.5 1.44.22.92.22 1.9.22 3.86z", fill: "#d3d6fd" }), (0, jsx_runtime_1.jsx)("path", { d: "m68.26 20.26c1.38 1.38 2.06 2.06 2.56 2.88.18.28.32.56.46.86h-16.88c-2.24 0-3.36 0-4.22-.44-.74-.38-1.36-1-1.74-1.74-.44-.86-.44-1.98-.44-4.22v-16.880029c.3.14.58.28.86.459999.82.5 1.5 1.18 2.88 2.56z", fill: "#939bf9" }), (0, jsx_runtime_1.jsx)("path", { clipRule: "evenodd", d: "m23.7 40.46c.66-.28 1.32-.38 1.98-.42.62-.04 1.38-.04 2.26-.04h.06v4c-.96 0-1.58 0-2.04.02-.46.04-.64.08-.72.12-.48.2-.88.6-1.08 1.08-.04.1-.08.26-.12.72-.04.48-.04 1.1-.04 2.06v6.06c0 .88 0 1.64-.04 2.26-.06.66-.14 1.32-.42 1.98-.26.64-.64 1.2-1.1 1.7.46.5.84 1.06 1.1 1.7.28.66.38 1.32.42 1.98.04.62.04 1.38.04 2.26v6.06c0 .96 0 1.58.02 2.04.04.46.08.64.12.72.2.48.6.88 1.08 1.08.1.04.26.08.72.12.48.04 1.1.04 2.06.04v4h-.06c-.88 0-1.64 0-2.26-.04-.66-.06-1.32-.14-1.98-.42-1.46-.6-2.64-1.76-3.24-3.24-.28-.66-.38-1.32-.42-1.98-.04-.62-.04-1.38-.04-2.26v-6.06c0-.96 0-1.58-.02-2.04-.04-.46-.08-.64-.12-.72-.2-.48-.6-.88-1.08-1.08-.1-.04-.26-.08-.72-.12-.48-.04-1.1-.04-2.06-.04v-4c.96 0 1.58 0 2.04-.02.46-.04.64-.08.72-.12.48-.2.88-.58 1.08-1.08.04-.1.08-.26.12-.72.04-.48.04-1.1.04-2.06v-6.06c0-.88 0-1.64.04-2.26.06-.66.14-1.32.42-1.98.6-1.46 1.76-2.64 3.24-3.24zm29.52 17.38c.1.04.26.08.72.12.48.04 1.1.04 2.06.04v4c-.96 0-1.58 0-2.04.02-.46.04-.64.08-.72.12-.48.2-.88.6-1.08 1.08-.04.1-.08.26-.12.72-.04.48-.04 1.1-.04 2.06v6.06c0 .88 0 1.64-.04 2.26-.06.66-.14 1.32-.42 1.98-.6 1.46-1.78 2.64-3.24 3.24-.66.28-1.32.38-1.98.42-.62.04-1.38.04-2.26.04h-.06v-4c.96 0 1.58 0 2.04-.02.46-.04.64-.08.72-.12.48-.2.88-.58 1.08-1.08.04-.1.08-.26.12-.72.04-.48.04-1.1.04-2.06v-6.06c0-.88 0-1.64.04-2.26.06-.66.16-1.32.42-1.98.26-.64.64-1.2 1.1-1.7-.46-.5-.84-1.06-1.1-1.7-.28-.66-.38-1.32-.42-1.98-.04-.62-.04-1.38-.04-2.26v-6.06c0-.96 0-1.58-.02-2.04-.04-.46-.08-.64-.12-.72-.2-.48-.6-.88-1.08-1.08-.1-.04-.26-.08-.72-.12-.48-.04-1.1-.04-2.06-.04v-4h.06c.88 0 1.64 0 2.26.04.66.06 1.32.14 1.98.42 1.46.6 2.64 1.76 3.24 3.24.28.66.38 1.32.42 1.98.04.62.04 1.38.04 2.26v6.06c0 .96 0 1.58.02 2.04.04.46.08.64.12.72.2.48.6.88 1.08 1.08z", fill: "#5865f2", fillRule: "evenodd" })] }));
7
+ }
@@ -0,0 +1 @@
1
+ export default function FileDocumentIcon(props: React.SVGProps<SVGSVGElement>): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,7 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.default = FileDocumentIcon;
4
+ const jsx_runtime_1 = require("react/jsx-runtime");
5
+ function FileDocumentIcon(props) {
6
+ return ((0, jsx_runtime_1.jsxs)("svg", { fill: "none", height: "96", viewBox: "0 0 72 96", width: "72", xmlns: "http://www.w3.org/2000/svg", ...props, children: [(0, jsx_runtime_1.jsx)("path", { d: "m72 29.3v60.3c0 2.24 0 3.36-.44 4.22-.38.74-1 1.36-1.74 1.74-.86.44-1.98.44-4.22.44h-59.2c-2.24 0-3.36 0-4.22-.44-.74-.38-1.36-1-1.74-1.74-.44-.86-.44-1.98-.44-4.22v-83.2c0-2.24 0-3.36.44-4.22.38-.74 1-1.36 1.74-1.74.86-.44 1.98-.44 4.22-.44h36.3c1.96 0 2.94 0 3.86.22.5.12.98.28 1.44.5v16.88c0 2.24 0 3.36.44 4.22.38.74 1 1.36 1.74 1.74.86.44 1.98.44 4.22.44h16.88c.22.46.38.94.5 1.44.22.92.22 1.9.22 3.86z", fill: "#d3d6fd" }), (0, jsx_runtime_1.jsx)("path", { d: "m68.26 20.26c1.38 1.38 2.06 2.06 2.56 2.88.18.28.32.56.46.86h-16.88c-2.24 0-3.36 0-4.22-.44-.74-.38-1.36-1-1.74-1.74-.44-.86-.44-1.98-.44-4.22v-16.880029c.3.14.58.28.86.459999.82.5 1.5 1.18 2.88 2.56z", fill: "#939bf9" }), (0, jsx_runtime_1.jsx)("path", { d: "m56.1014 65.0909c-3.1394-3.2-11.7-1.8909-13.7625-1.6545-2.2633-2.2182-4.1981-4.7273-5.7861-7.4546 1.1317-3.1636 1.7705-6.4727 1.9348-9.8182 0-2.9636-1.2047-6.1636-4.5815-6.1636-1.1864.0364-2.2815.6545-2.9021 1.6545-1.442 2.491-.8397 7.4546 1.4419 12.5455-1.5697 4.6545-3.5592 9.1636-5.9138 13.4909-3.5046 1.4182-10.8604 4.7273-11.4627 8.2909-.2373 1.0909.146 2.2.9674 2.9637.8578.6909 1.9165 1.0545 3.0299 1.0545 4.4719 0 8.8161-6.0364 11.8278-11.1273 3.4315-1.1454 6.936-2.0545 10.4952-2.7272 4.7092 4.0181 8.8161 4.6181 10.9882 4.6181 2.9021 0 3.9791-1.1818 4.3441-2.2545.5293-1.1455.2921-2.5091-.6206-3.4182zm-3.0117 2.0182c-.1277.8364-1.2047 1.6545-3.1394 1.1818-2.2451-.5818-4.3442-1.6364-6.1512-3.0727 1.5697-.2364 5.0743-.6 7.5931-.1273.9674.2364 1.9348.8182 1.6975 2.0182zm-20.1509-24.3818c.2007-.3455.5658-.5637.9673-.6 1.077 0 1.3325 1.3091 1.3325 2.3636-.1278 2.5091-.6023 4.9636-1.442 7.3455-1.8252-4.7273-1.4602-8.0546-.8578-9.1091zm-.2373 22.9454c1.0404-2.1636 1.9713-4.3636 2.7744-6.6182 1.1134 1.7455 2.4093 3.3637 3.8695 4.8546-.0182.1091-3.76.8182-6.6439 1.7636zm-7.1186 4.7455c-2.7744 4.4909-5.6766 7.3454-7.2463 7.3454-.2555-.0181-.5111-.1091-.7301-.2363-.3651-.2364-.5111-.6728-.3651-1.0728.3651-1.6545 3.5046-3.909 8.3415-6.0363z", fill: "#5865f2" })] }));
7
+ }
@@ -0,0 +1 @@
1
+ export default function PinIcon(props: React.SVGProps<SVGSVGElement>): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,7 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.default = PinIcon;
4
+ const jsx_runtime_1 = require("react/jsx-runtime");
5
+ function PinIcon(props) {
6
+ return ((0, jsx_runtime_1.jsx)("svg", { "aria-hidden": "true", role: "img", xmlns: "http://www.w3.org/2000/svg", width: "20", height: "20", fill: "none", viewBox: "0 0 24 24", ...props, children: (0, jsx_runtime_1.jsx)("path", { fill: "currentColor", d: "M19.38 11.38a3 3 0 0 0 4.24 0l.03-.03a.5.5 0 0 0 0-.7L13.35.35a.5.5 0 0 0-.7 0l-.03.03a3 3 0 0 0 0 4.24L13 5l-2.92 2.92-3.65-.34a2 2 0 0 0-1.6.58l-.62.63a1 1 0 0 0 0 1.42l9.58 9.58a1 1 0 0 0 1.42 0l.63-.63a2 2 0 0 0 .58-1.6l-.34-3.64L19 11l.38.38ZM9.07 17.07a.5.5 0 0 1-.08.77l-5.15 3.43a.5.5 0 0 1-.63-.06l-.42-.42a.5.5 0 0 1-.06-.63L6.16 15a.5.5 0 0 1 .77-.08l2.14 2.14Z" }) }));
7
+ }
@@ -0,0 +1 @@
1
+ export default function VerifiedIcon(props: React.SVGProps<SVGSVGElement>): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,7 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.default = VerifiedIcon;
4
+ const jsx_runtime_1 = require("react/jsx-runtime");
5
+ function VerifiedIcon(props) {
6
+ return ((0, jsx_runtime_1.jsx)("svg", { viewBox: "0 0 24 24", className: "botTagVerified", xmlns: "http://www.w3.org/2000/svg", "aria-hidden": true, ...props, children: (0, jsx_runtime_1.jsx)("path", { fill: "#fff", fillRule: "evenodd", d: "M19.06 6.94a1.5 1.5 0 0 1 0 2.12l-8 8a1.5 1.5 0 0 1-2.12 0l-4-4a1.5 1.5 0 0 1 2.12-2.12L10 13.88l6.94-6.94a1.5 1.5 0 0 1 2.12 0Z", clipRule: "evenodd" }) }));
7
+ }
@@ -0,0 +1,11 @@
1
+ export { default as Button } from "./Button";
2
+ export { default as Embed } from "./Embed";
3
+ export { default as ForwardedMessage } from "./ForwardedMessage";
4
+ export { default as Message } from "./Message";
5
+ export { default as Reply } from "./Reply";
6
+ export { default as ThemeSwitcher } from "./ThemeSwitcher";
7
+ export { default as Transcript } from "./Transcript";
8
+ export { default as AudioPlayer } from "./AudioPlayer";
9
+ export { default as VideoPlayer } from "./VideoPlayer";
10
+ export type { ThemeColors } from "../types/theme";
11
+ export type { TranscriptThemes } from "../types/theme";
@@ -0,0 +1,24 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.VideoPlayer = exports.AudioPlayer = exports.Transcript = exports.ThemeSwitcher = exports.Reply = exports.Message = exports.ForwardedMessage = exports.Embed = exports.Button = void 0;
7
+ var Button_1 = require("./Button");
8
+ Object.defineProperty(exports, "Button", { enumerable: true, get: function () { return __importDefault(Button_1).default; } });
9
+ var Embed_1 = require("./Embed");
10
+ Object.defineProperty(exports, "Embed", { enumerable: true, get: function () { return __importDefault(Embed_1).default; } });
11
+ var ForwardedMessage_1 = require("./ForwardedMessage");
12
+ Object.defineProperty(exports, "ForwardedMessage", { enumerable: true, get: function () { return __importDefault(ForwardedMessage_1).default; } });
13
+ var Message_1 = require("./Message");
14
+ Object.defineProperty(exports, "Message", { enumerable: true, get: function () { return __importDefault(Message_1).default; } });
15
+ var Reply_1 = require("./Reply");
16
+ Object.defineProperty(exports, "Reply", { enumerable: true, get: function () { return __importDefault(Reply_1).default; } });
17
+ var ThemeSwitcher_1 = require("./ThemeSwitcher");
18
+ Object.defineProperty(exports, "ThemeSwitcher", { enumerable: true, get: function () { return __importDefault(ThemeSwitcher_1).default; } });
19
+ var Transcript_1 = require("./Transcript");
20
+ Object.defineProperty(exports, "Transcript", { enumerable: true, get: function () { return __importDefault(Transcript_1).default; } });
21
+ var AudioPlayer_1 = require("./AudioPlayer");
22
+ Object.defineProperty(exports, "AudioPlayer", { enumerable: true, get: function () { return __importDefault(AudioPlayer_1).default; } });
23
+ var VideoPlayer_1 = require("./VideoPlayer");
24
+ Object.defineProperty(exports, "VideoPlayer", { enumerable: true, get: function () { return __importDefault(VideoPlayer_1).default; } });
@@ -0,0 +1,8 @@
1
+ export declare function getAttachmentKind(name?: string, url?: string): string;
2
+ export declare function formatFileSize(size?: number, human?: string): string;
3
+ export declare function isImageUrl(url?: string): boolean;
4
+ export declare function isAudioUrl(url?: string): boolean;
5
+ export declare function isVideoUrl(url?: string): boolean;
6
+ export declare function extractFilenameFromUrl(url?: string): string | undefined;
7
+ export declare function sanitizeMarkdownString(s: string | unknown): string | unknown;
8
+ export declare function timeAgo(d: Date): string;
@@ -0,0 +1,72 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getAttachmentKind = getAttachmentKind;
4
+ exports.formatFileSize = formatFileSize;
5
+ exports.isImageUrl = isImageUrl;
6
+ exports.isAudioUrl = isAudioUrl;
7
+ exports.isVideoUrl = isVideoUrl;
8
+ exports.extractFilenameFromUrl = extractFilenameFromUrl;
9
+ exports.sanitizeMarkdownString = sanitizeMarkdownString;
10
+ exports.timeAgo = timeAgo;
11
+ function getAttachmentKind(name, url) {
12
+ const target = (name || url || "").toLowerCase();
13
+ if (/(\.mp3|\.wav|\.flac|\.ogg|\.m4a|\.aac|\.opus)$/.test(target))
14
+ return "audio";
15
+ if (/(\.js|\.ts|\.tsx|\.jsx|\.json|\.py|\.java|\.c|\.cpp|\.cs|\.rb|\.php|\.go|\.rs|\.swift|\.kt|\.kts|\.sh|\.ps1|\.bat|\.sql|\.html|\.css|\.scss|\.sass)$/.test(target))
16
+ return "code";
17
+ return "document";
18
+ }
19
+ function formatFileSize(size, human) {
20
+ if (typeof size === "number") {
21
+ const kb = size / 1024;
22
+ if (kb < 1024)
23
+ return `${kb.toFixed(2)} KB`;
24
+ return `${(kb / 1024).toFixed(2)} MB`;
25
+ }
26
+ return human || "";
27
+ }
28
+ function isImageUrl(url) {
29
+ if (!url)
30
+ return false;
31
+ return /\.(png|jpe?g|gif|webp|svg|bmp|avif)(\?|$)/i.test(url);
32
+ }
33
+ function isAudioUrl(url) {
34
+ if (!url)
35
+ return false;
36
+ return /\.(mp3|wav|ogg|m4a|flac|aac|weba)(\?|$)/i.test(url);
37
+ }
38
+ function isVideoUrl(url) {
39
+ if (!url)
40
+ return false;
41
+ return /\.(mp4|mov|webm|avi|mkv)(\?|$)/i.test(url);
42
+ }
43
+ function extractFilenameFromUrl(url) {
44
+ if (!url)
45
+ return undefined;
46
+ try {
47
+ const u = new URL(url, window.location.origin);
48
+ let p = u.pathname || "";
49
+ if (p.endsWith("/"))
50
+ p = p.slice(0, -1);
51
+ const last = p.split("/").pop() || "";
52
+ return last ? decodeURIComponent(last) : undefined;
53
+ }
54
+ catch (e) {
55
+ const parts = url.split("?")[0].split("/");
56
+ const last = parts.pop() || "";
57
+ return last ? decodeURIComponent(last) : undefined;
58
+ }
59
+ }
60
+ function sanitizeMarkdownString(s) {
61
+ return typeof s === "string" ? s.replace(/[\u200B\u200C\u200D\uFEFF\u2060\u200E\u200F\u00AD]/g, "") : s;
62
+ }
63
+ function timeAgo(d) {
64
+ const diff = Math.floor((Date.now() - d.getTime()) / 1000);
65
+ if (Math.abs(diff) < 60)
66
+ return `${Math.abs(diff)}s ago`;
67
+ if (Math.abs(diff) < 3600)
68
+ return `${Math.round(Math.abs(diff) / 60)}m ago`;
69
+ if (Math.abs(diff) < 86400)
70
+ return `${Math.round(Math.abs(diff) / 3600)}h ago`;
71
+ return d.toLocaleString("en-US", { month: "2-digit", day: "2-digit", year: "numeric" });
72
+ }
@@ -0,0 +1,9 @@
1
+ import type { TranscriptThemes, ThemeColors, ThemePreview } from "../types/theme";
2
+ export declare const defaultThemeColors: Record<"light" | "ash" | "dark" | "onyx", ThemeColors>;
3
+ export declare const colorThemeColors: Record<string, ThemeColors>;
4
+ export declare function getThemeColors(theme: TranscriptThemes, systemPrefersDark: boolean): ThemeColors;
5
+ export declare function getThemeGradient(theme: TranscriptThemes): string | null;
6
+ export declare const defaultThemePreviews: Record<"light" | "ash" | "dark" | "onyx" | "system", ThemePreview>;
7
+ export declare const colorThemePreviews: Record<string, {
8
+ gradient: string;
9
+ }>;