@otmc/ui 0.1.6 → 0.1.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -18,8 +18,9 @@ var __copyProps = (to, from, except, desc) => {
18
18
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
19
 
20
20
  // src/index.ts
21
- var index_exports = {};
22
- __export(index_exports, {
21
+ var src_exports = {};
22
+ __export(src_exports, {
23
+ BACKEND_URL: () => BACKEND_URL,
23
24
  DEFAULT_AUTHOR: () => DEFAULT_AUTHOR,
24
25
  DEFAULT_AUTHOR_HREF: () => DEFAULT_AUTHOR_HREF,
25
26
  DEFAULT_COPYRIGHT: () => DEFAULT_COPYRIGHT,
@@ -34,23 +35,218 @@ __export(index_exports, {
34
35
  ThemeProvider: () => ThemeProvider,
35
36
  ThemeSetting: () => ThemeSetting,
36
37
  UNKNOWN: () => UNKNOWN,
38
+ apiClient: () => apiClient,
39
+ apiUtils: () => apiUtils,
37
40
  calculateRemainingTime: () => calculateRemainingTime,
38
41
  copyToClipboard: () => copyToClipboard,
42
+ debug: () => debug,
39
43
  formatAbsolute: () => formatAbsolute,
40
44
  formatAbsoluteAndRelativeTime: () => formatAbsoluteAndRelativeTime,
41
45
  formatHumanDate: () => formatHumanDate,
42
46
  formatRelativeTime: () => formatRelativeTime,
47
+ getBackendUrl: () => getBackendUrl,
48
+ instructionsApi: () => instructionsApi,
49
+ llmApi: () => llmApi,
43
50
  normalizeDate: () => normalizeDate,
51
+ notificationCenter: () => NotificationCenter_default,
44
52
  pad: () => pad,
45
53
  resolveColorScheme: () => resolveColorScheme,
54
+ setAccessTokenGetter: () => setAccessTokenGetter,
55
+ setBackendUrl: () => setBackendUrl,
46
56
  useTheme: () => useTheme
47
57
  });
48
- module.exports = __toCommonJS(index_exports);
58
+ module.exports = __toCommonJS(src_exports);
59
+
60
+ // src/components/common/NotificationCenter.tsx
61
+ var import_notifications = require("@mantine/notifications");
62
+ var import_icons_react = require("@tabler/icons-react");
63
+ var import_jsx_runtime = require("react/jsx-runtime");
64
+ var notificationCenter = {
65
+ error: ({ title, message, autoClose = 15e3 }) => {
66
+ import_notifications.notifications.show({
67
+ color: "red",
68
+ title: `${title}`,
69
+ message,
70
+ icon: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_icons_react.IconX, {}),
71
+ autoClose,
72
+ radius: "lg"
73
+ });
74
+ },
75
+ warn: ({ title, message, autoClose = 1e4 }) => {
76
+ import_notifications.notifications.show({
77
+ color: "yellow",
78
+ title: `${title}`,
79
+ message,
80
+ icon: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_icons_react.IconAlertCircle, {}),
81
+ autoClose,
82
+ radius: "lg"
83
+ });
84
+ },
85
+ info: ({ title, message, autoClose = 8e3 }) => {
86
+ import_notifications.notifications.show({
87
+ color: "blue",
88
+ title: `${title}`,
89
+ icon: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_icons_react.IconInfoCircle, {}),
90
+ message,
91
+ autoClose,
92
+ radius: "lg"
93
+ });
94
+ },
95
+ success: ({ title, message, autoClose = 5e3 }) => {
96
+ import_notifications.notifications.show({
97
+ color: "green",
98
+ title: `${title}`,
99
+ icon: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_icons_react.IconCheck, {}),
100
+ message,
101
+ autoClose,
102
+ radius: "lg"
103
+ });
104
+ }
105
+ };
106
+ var NotificationCenter_default = notificationCenter;
107
+
108
+ // src/api/utils.ts
109
+ var backendUrlOverride;
110
+ function setBackendUrl(url) {
111
+ backendUrlOverride = url;
112
+ }
113
+ function getBackendUrl() {
114
+ if (backendUrlOverride) return backendUrlOverride;
115
+ if (typeof window !== "undefined" && window.location?.origin) {
116
+ return window.location.origin + "/api";
117
+ }
118
+ return "";
119
+ }
120
+ var BACKEND_URL = getBackendUrl();
121
+ var accessTokenGetter = null;
122
+ function setAccessTokenGetter(getter) {
123
+ accessTokenGetter = getter;
124
+ }
125
+ var ApiClient = class {
126
+ constructor(baseUrl) {
127
+ this.baseUrl = baseUrl;
128
+ }
129
+ async request(endpoint, options = {}) {
130
+ const url = `${this.baseUrl ?? getBackendUrl()}${endpoint}`;
131
+ const config = {
132
+ headers: {
133
+ "Content-Type": "application/json",
134
+ ...options.headers
135
+ },
136
+ ...options
137
+ };
138
+ const token = accessTokenGetter ? await accessTokenGetter() : null;
139
+ if (token) {
140
+ config.headers.Authorization = `Bearer ${token}`;
141
+ }
142
+ try {
143
+ const response = await fetch(url, config);
144
+ if (options.method === "DELETE") {
145
+ if (response.status === 204 || response.status === 200) {
146
+ return { success: true, data: void 0, message: "Success" };
147
+ }
148
+ const text = await response.text();
149
+ if (text) {
150
+ const data = JSON.parse(text);
151
+ if (!response.ok) {
152
+ const error = data.error;
153
+ NotificationCenter_default.error({
154
+ title: `${error.summary}`,
155
+ message: `${error.detail}`,
156
+ autoClose: 15e3
157
+ });
158
+ throw new Error(`${error.summary}: ${error.detail}` || `Request Failed with status: ${response.status}`);
159
+ }
160
+ return data;
161
+ } else {
162
+ return { success: true, data: void 0, message: "Success" };
163
+ }
164
+ }
165
+ const responseData = await response.json();
166
+ if (!response.ok) {
167
+ const error = responseData.error;
168
+ NotificationCenter_default.error({
169
+ title: `${error.summary}`,
170
+ message: `${error.detail}`,
171
+ autoClose: 15e3
172
+ });
173
+ throw new Error(`${error.summary}: ${error.detail}` || `Request Failed with status: ${response.status}`);
174
+ }
175
+ return responseData;
176
+ } catch (error) {
177
+ console.error(`API request failed: ${endpoint}`, error);
178
+ throw error;
179
+ }
180
+ }
181
+ get(endpoint, params) {
182
+ const queryString = params ? `?${new URLSearchParams(params).toString()}` : "";
183
+ return this.request(`${endpoint}${queryString}`, { method: "GET" });
184
+ }
185
+ post(endpoint, data) {
186
+ return this.request(endpoint, {
187
+ method: "POST",
188
+ body: data ? JSON.stringify(data) : void 0
189
+ });
190
+ }
191
+ put(endpoint, data) {
192
+ return this.request(endpoint, {
193
+ method: "PUT",
194
+ body: data ? JSON.stringify(data) : void 0
195
+ });
196
+ }
197
+ patch(endpoint, data) {
198
+ return this.request(endpoint, {
199
+ method: "PATCH",
200
+ body: data ? JSON.stringify(data) : void 0
201
+ });
202
+ }
203
+ delete(endpoint) {
204
+ return this.request(endpoint, { method: "DELETE" });
205
+ }
206
+ };
207
+ var apiClient = new ApiClient();
208
+ var apiUtils = {
209
+ handleSuccess: (response) => {
210
+ return response.data;
211
+ },
212
+ handleError: (error) => {
213
+ console.error("API Error:", error);
214
+ throw error;
215
+ },
216
+ validateId: (id) => {
217
+ return /^[0-9A-HJKMNP-TV-Z]{26}$/.test(id);
218
+ },
219
+ getDataFromResponse: (response) => {
220
+ if (response.success && "data" in response) {
221
+ return response.data;
222
+ }
223
+ return void 0;
224
+ }
225
+ };
226
+
227
+ // src/api/llm.ts
228
+ var llmApi = {
229
+ generate: (data) => apiClient.post("/llm/generate", data),
230
+ generateDocument: (data) => apiClient.post("/llm/generate-document", data),
231
+ formatDocument: (templateId, data) => apiClient.post(`/llm/format/${templateId}`, data),
232
+ getConfig: () => apiClient.get("/llm/config"),
233
+ testConnection: () => apiClient.get("/llm/test"),
234
+ reload: () => apiClient.post("/llm/reload")
235
+ };
236
+
237
+ // src/api/instructions.ts
238
+ var instructionsApi = {
239
+ getAll: () => apiClient.get("/prompts"),
240
+ getById: (id) => apiClient.get(`/prompts/${id}`),
241
+ create: (instruction) => apiClient.post("/prompts", instruction),
242
+ update: (id, content) => apiClient.patch(`/prompts/${id}`, { content }),
243
+ delete: (id) => apiClient.delete(`/prompts/${id}`)
244
+ };
49
245
 
50
246
  // src/branding/Footer.tsx
51
247
  var import_core = require("@mantine/core");
52
248
  var import_lucide_react = require("lucide-react");
53
- var import_icons_react = require("@tabler/icons-react");
249
+ var import_icons_react2 = require("@tabler/icons-react");
54
250
 
55
251
  // src/utils/constants.ts
56
252
  var DEFAULT_AUTHOR = "Nguyen Van Trung, OTMC Contributors.";
@@ -62,26 +258,26 @@ var DEFAULT_VERSION_TYPE = "Internal";
62
258
  var UNKNOWN = "Unknown";
63
259
 
64
260
  // src/branding/Footer.tsx
65
- var import_jsx_runtime = require("react/jsx-runtime");
261
+ var import_jsx_runtime2 = require("react/jsx-runtime");
66
262
  var DEFAULT_SOCIAL_LINKS = [
67
263
  {
68
264
  label: "Facebook",
69
265
  href: "https://www.facebook.com",
70
- icon: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_icons_react.IconBrandFacebook, { size: 20 }),
266
+ icon: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_icons_react2.IconBrandFacebook, { size: 20 }),
71
267
  color: "blue.8",
72
268
  external: true
73
269
  },
74
270
  {
75
271
  label: "GitHub",
76
272
  href: "https://github.com",
77
- icon: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_icons_react.IconBrandGithub, { size: 20 }),
273
+ icon: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_icons_react2.IconBrandGithub, { size: 20 }),
78
274
  color: "gray.6",
79
275
  external: true
80
276
  },
81
277
  {
82
278
  label: "Gmail",
83
279
  href: "mailto:test@gmail.com",
84
- icon: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_icons_react.IconMail, { size: 20 }),
280
+ icon: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_icons_react2.IconMail, { size: 20 }),
85
281
  color: "red.8",
86
282
  external: false
87
283
  }
@@ -93,31 +289,31 @@ function Footer({
93
289
  socialLinks = DEFAULT_SOCIAL_LINKS,
94
290
  showSocialLinks = true
95
291
  }) {
96
- return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_core.Stack, { gap: "sm", mt: "md", align: "center", children: [
97
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_core.Stack, { gap: 2, align: "center", children: [
98
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_core.Group, { gap: 4, wrap: "nowrap", children: [
99
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_core.Text, { c: "dimmed", size: "xs", children: [
292
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_core.Stack, { gap: "sm", mt: "md", align: "center", children: [
293
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_core.Stack, { gap: 2, align: "center", children: [
294
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_core.Group, { gap: 4, wrap: "nowrap", children: [
295
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_core.Text, { c: "dimmed", size: "xs", children: [
100
296
  "Copyright",
101
297
  " "
102
298
  ] }),
103
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_lucide_react.Copyright, { size: 15, color: "var(--mantine-color-dimmed)" }),
104
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_core.Text, { size: "xs", c: "dimmed", children: [
299
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_lucide_react.Copyright, { size: 15, color: "var(--mantine-color-dimmed)" }),
300
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_core.Text, { size: "xs", c: "dimmed", children: [
105
301
  (/* @__PURE__ */ new Date()).getFullYear(),
106
302
  " ",
107
303
  copyright
108
304
  ] })
109
305
  ] }),
110
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_core.Group, { gap: 4, wrap: "nowrap", children: [
111
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_core.Text, { size: "xs", c: "dimmed", children: "Built with" }),
112
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
113
- import_icons_react.IconHeart,
306
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_core.Group, { gap: 4, wrap: "nowrap", children: [
307
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_core.Text, { size: "xs", c: "dimmed", children: "Built with" }),
308
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
309
+ import_icons_react2.IconHeart,
114
310
  {
115
311
  size: 15,
116
312
  style: { color: "var(--mantine-color-red-7)" }
117
313
  }
118
314
  ),
119
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_core.Text, { size: "xs", c: "dimmed", children: "by" }),
120
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
315
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_core.Text, { size: "xs", c: "dimmed", children: "by" }),
316
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
121
317
  import_core.Anchor,
122
318
  {
123
319
  href: authorHref,
@@ -129,7 +325,7 @@ function Footer({
129
325
  )
130
326
  ] })
131
327
  ] }),
132
- showSocialLinks && socialLinks.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_core.Group, { gap: "sm", children: socialLinks.map((link) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_core.Tooltip, { label: link.label, withArrow: true, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
328
+ showSocialLinks && socialLinks.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_core.Group, { gap: "sm", children: socialLinks.map((link) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_core.Tooltip, { label: link.label, withArrow: true, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
133
329
  import_core.ActionIcon,
134
330
  {
135
331
  variant: "subtle",
@@ -151,7 +347,7 @@ var import_lucide_react2 = require("lucide-react");
151
347
  // src/contexts/ThemeProvider.tsx
152
348
  var import_react = require("react");
153
349
  var import_core2 = require("@mantine/core");
154
- var import_jsx_runtime2 = require("react/jsx-runtime");
350
+ var import_jsx_runtime3 = require("react/jsx-runtime");
155
351
  var ThemeContext = (0, import_react.createContext)(null);
156
352
  var useTheme = () => {
157
353
  const ctx = (0, import_react.useContext)(ThemeContext);
@@ -229,7 +425,7 @@ var ThemeProvider = ({
229
425
  setTheme(colorScheme === "dark" ? "light" : "dark");
230
426
  };
231
427
  const currentTheme = theme === "time-based" ? resolveTimeBasedTheme(timeBasedSettings) : colorScheme === "auto" ? resolveAutoScheme() : colorScheme;
232
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
428
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
233
429
  ThemeContext.Provider,
234
430
  {
235
431
  value: {
@@ -246,7 +442,7 @@ var ThemeProvider = ({
246
442
  };
247
443
 
248
444
  // src/components/ThemeMenu.tsx
249
- var import_jsx_runtime3 = require("react/jsx-runtime");
445
+ var import_jsx_runtime4 = require("react/jsx-runtime");
250
446
  var DEFAULT_LABELS = {
251
447
  tooltip: "Ch\u1EBF \u0111\u1ED9 giao di\u1EC7n",
252
448
  title: "Ch\u1EBF \u0111\u1ED9 giao di\u1EC7n",
@@ -256,10 +452,10 @@ var DEFAULT_LABELS = {
256
452
  timeBased: "Theo th\u1EDDi gian"
257
453
  };
258
454
  var MODE_ICONS = {
259
- light: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_lucide_react2.Sun, { size: 16 }),
260
- dark: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_lucide_react2.Moon, { size: 16 }),
261
- auto: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_lucide_react2.Monitor, { size: 16 }),
262
- "time-based": /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_lucide_react2.Clock, { size: 16 })
455
+ light: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_lucide_react2.Sun, { size: 16 }),
456
+ dark: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_lucide_react2.Moon, { size: 16 }),
457
+ auto: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_lucide_react2.Monitor, { size: 16 }),
458
+ "time-based": /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_lucide_react2.Clock, { size: 16 })
263
459
  };
264
460
  function ThemeMenu({
265
461
  modes = ["light", "dark", "auto", "time-based"],
@@ -272,9 +468,9 @@ function ThemeMenu({
272
468
  const text = { ...DEFAULT_LABELS, ...labels };
273
469
  const isDark = currentTheme === "dark";
274
470
  const activeColor = isDark ? "yellow.8" : "blue.8";
275
- const triggerIcon = theme === "light" ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_lucide_react2.Sun, { size: iconSize, strokeWidth: 2 }) : theme === "dark" ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_lucide_react2.Moon, { size: iconSize, strokeWidth: 2 }) : theme === "auto" ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_lucide_react2.Monitor, { size: iconSize, strokeWidth: 2 }) : /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_lucide_react2.Clock, { size: iconSize, strokeWidth: 2 });
276
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_core3.Menu, { shadow: "md", width: 200, position: "bottom-end", ...menuProps, children: [
277
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_core3.Menu.Target, { children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_core3.Tooltip, { label: text.tooltip, position: "bottom", withArrow: true, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
471
+ const triggerIcon = theme === "light" ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_lucide_react2.Sun, { size: iconSize, strokeWidth: 2 }) : theme === "dark" ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_lucide_react2.Moon, { size: iconSize, strokeWidth: 2 }) : theme === "auto" ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_lucide_react2.Monitor, { size: iconSize, strokeWidth: 2 }) : /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_lucide_react2.Clock, { size: iconSize, strokeWidth: 2 });
472
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_core3.Menu, { shadow: "md", width: 200, position: "bottom-end", ...menuProps, children: [
473
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_core3.Menu.Target, { children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_core3.Tooltip, { label: text.tooltip, position: "bottom", withArrow: true, children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
278
474
  import_core3.ActionIcon,
279
475
  {
280
476
  variant: "subtle",
@@ -287,9 +483,9 @@ function ThemeMenu({
287
483
  children: triggerIcon
288
484
  }
289
485
  ) }) }),
290
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_core3.Menu.Dropdown, { style: { borderRadius: "11px" }, children: [
291
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_core3.Menu.Label, { children: text.title }),
292
- modes.map((mode) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
486
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_core3.Menu.Dropdown, { style: { borderRadius: "11px" }, children: [
487
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_core3.Menu.Label, { children: text.title }),
488
+ modes.map((mode) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
293
489
  import_core3.Menu.Item,
294
490
  {
295
491
  leftSection: MODE_ICONS[mode],
@@ -307,8 +503,8 @@ function ThemeMenu({
307
503
  // src/components/ThemeSetting.tsx
308
504
  var import_core4 = require("@mantine/core");
309
505
  var import_dates = require("@mantine/dates");
310
- var import_icons_react2 = require("@tabler/icons-react");
311
- var import_jsx_runtime4 = require("react/jsx-runtime");
506
+ var import_icons_react3 = require("@tabler/icons-react");
507
+ var import_jsx_runtime5 = require("react/jsx-runtime");
312
508
  var DEFAULT_LABELS2 = {
313
509
  title: "Appearance",
314
510
  subtitle: "Control how the application looks and feels",
@@ -324,10 +520,10 @@ var DEFAULT_LABELS2 = {
324
520
  timeBased: "Time-based"
325
521
  };
326
522
  var MODE_ICONS2 = {
327
- light: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_icons_react2.IconSun, { size: 16 }),
328
- dark: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_icons_react2.IconMoon, { size: 16 }),
329
- auto: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_icons_react2.IconDeviceLaptop, { size: 16 }),
330
- "time-based": /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_icons_react2.IconClock, { size: 16 })
523
+ light: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_icons_react3.IconSun, { size: 16 }),
524
+ dark: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_icons_react3.IconMoon, { size: 16 }),
525
+ auto: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_icons_react3.IconDeviceLaptop, { size: 16 }),
526
+ "time-based": /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_icons_react3.IconClock, { size: 16 })
331
527
  };
332
528
  var MODE_ORDER = ["light", "dark", "auto", "time-based"];
333
529
  function ThemeSetting({
@@ -346,7 +542,7 @@ function ThemeSetting({
346
542
  const isTimeBased = theme === "time-based";
347
543
  const isDark = currentTheme === "dark";
348
544
  const showTimeBased = modes.includes("time-based");
349
- return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
545
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
350
546
  import_core4.Card,
351
547
  {
352
548
  withBorder: true,
@@ -355,18 +551,18 @@ function ThemeSetting({
355
551
  bg: isDark ? "dark.8" : "gray.0",
356
552
  style: { flex: 1, overflow: "auto", display: "flex", flexDirection: "column" },
357
553
  ...cardProps,
358
- children: /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_core4.Stack, { gap: "lg", style: { flex: 1 }, children: [
359
- /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_core4.Box, { children: [
360
- /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_core4.Group, { gap: "xs", children: [
361
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_core4.ThemeIcon, { variant: "subtle", color: "blue.8", size: "md", radius: "md", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_icons_react2.IconPalette, { size: 25 }) }),
362
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_core4.Title, { order: 4, children: text.title })
554
+ children: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_core4.Stack, { gap: "lg", style: { flex: 1 }, children: [
555
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_core4.Box, { children: [
556
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_core4.Group, { gap: "xs", children: [
557
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_core4.ThemeIcon, { variant: "subtle", color: "blue.8", size: "md", radius: "md", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_icons_react3.IconPalette, { size: 25 }) }),
558
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_core4.Title, { order: 4, children: text.title })
363
559
  ] }),
364
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_core4.Text, { size: "sm", c: "dimmed", children: text.subtitle })
560
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_core4.Text, { size: "sm", c: "dimmed", children: text.subtitle })
365
561
  ] }),
366
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_core4.Divider, {}),
367
- /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_core4.Box, { children: [
368
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_core4.Text, { fw: 500, mb: 6, children: text.themeMode }),
369
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
562
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_core4.Divider, {}),
563
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_core4.Box, { children: [
564
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_core4.Text, { fw: 500, mb: 6, children: text.themeMode }),
565
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
370
566
  import_core4.SegmentedControl,
371
567
  {
372
568
  fullWidth: true,
@@ -378,24 +574,24 @@ function ThemeSetting({
378
574
  data: MODE_ORDER.filter((mode) => modes.includes(mode)).map(
379
575
  (mode) => ({
380
576
  value: mode,
381
- label: /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_core4.Group, { gap: 6, children: [
577
+ label: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_core4.Group, { gap: 6, children: [
382
578
  MODE_ICONS2[mode],
383
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { children: mode === "light" ? text.light : mode === "dark" ? text.dark : mode === "auto" ? text.system : text.timeBased })
579
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { children: mode === "light" ? text.light : mode === "dark" ? text.dark : mode === "auto" ? text.system : text.timeBased })
384
580
  ] })
385
581
  })
386
582
  )
387
583
  }
388
584
  ),
389
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_core4.Text, { size: "xs", c: "dimmed", mt: "xs", children: text.themeModeHint }),
390
- /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_core4.Text, { size: "xs", mt: 4, children: [
585
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_core4.Text, { size: "xs", c: "dimmed", mt: "xs", children: text.themeModeHint }),
586
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_core4.Text, { size: "xs", mt: 4, children: [
391
587
  text.currentlyActive,
392
588
  " ",
393
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("b", { children: isDark ? text.dark : text.light })
589
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("b", { children: isDark ? text.dark : text.light })
394
590
  ] })
395
591
  ] }),
396
- showTimeBased && /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_jsx_runtime4.Fragment, { children: [
397
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_core4.Divider, {}),
398
- /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
592
+ showTimeBased && /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_jsx_runtime5.Fragment, { children: [
593
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_core4.Divider, {}),
594
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
399
595
  import_core4.Box,
400
596
  {
401
597
  style: {
@@ -404,14 +600,14 @@ function ThemeSetting({
404
600
  transition: "opacity 150ms ease"
405
601
  },
406
602
  children: [
407
- /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_core4.Group, { gap: 6, mb: 6, children: [
408
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_icons_react2.IconClock, { size: 16 }),
409
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_core4.Text, { fw: 500, children: text.timeBasedSettings })
603
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_core4.Group, { gap: 6, mb: 6, children: [
604
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_icons_react3.IconClock, { size: 16 }),
605
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_core4.Text, { fw: 500, children: text.timeBasedSettings })
410
606
  ] }),
411
- /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_core4.Group, { grow: true, children: [
412
- /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_core4.Box, { children: [
413
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_core4.Text, { size: "sm", mb: 4, children: text.lightStartTime }),
414
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
607
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_core4.Group, { grow: true, children: [
608
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_core4.Box, { children: [
609
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_core4.Text, { size: "sm", mb: 4, children: text.lightStartTime }),
610
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
415
611
  import_dates.TimeInput,
416
612
  {
417
613
  withSeconds: false,
@@ -424,9 +620,9 @@ function ThemeSetting({
424
620
  }
425
621
  )
426
622
  ] }),
427
- /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_core4.Box, { children: [
428
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_core4.Text, { size: "sm", mb: 4, children: text.darkStartTime }),
429
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
623
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_core4.Box, { children: [
624
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_core4.Text, { size: "sm", mb: 4, children: text.darkStartTime }),
625
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
430
626
  import_dates.TimeInput,
431
627
  {
432
628
  withSeconds: false,
@@ -440,14 +636,14 @@ function ThemeSetting({
440
636
  )
441
637
  ] })
442
638
  ] }),
443
- /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_core4.Text, { size: "xs", c: "dimmed", mt: "xs", children: [
639
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_core4.Text, { size: "xs", c: "dimmed", mt: "xs", children: [
444
640
  text.light,
445
641
  ": ",
446
642
  timeBasedSettings.lightStartTime,
447
643
  " \u2192",
448
644
  " ",
449
645
  timeBasedSettings.darkStartTime,
450
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("br", {}),
646
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("br", {}),
451
647
  text.dark,
452
648
  ": ",
453
649
  timeBasedSettings.darkStartTime,
@@ -607,10 +803,10 @@ function formatHumanDate(date, options) {
607
803
  }
608
804
 
609
805
  // src/modals/Information.tsx
610
- var import_jsx_runtime5 = require("react/jsx-runtime");
611
- var DEFAULT_TITLE = /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_core5.Group, { gap: "xs", wrap: "nowrap", children: [
612
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_lucide_react3.Cpu, { size: 20 }),
613
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { children: "System Information" })
806
+ var import_jsx_runtime6 = require("react/jsx-runtime");
807
+ var DEFAULT_TITLE = /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_core5.Group, { gap: "xs", wrap: "nowrap", children: [
808
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_lucide_react3.Cpu, { size: 20 }),
809
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { children: "System Information" })
614
810
  ] });
615
811
  function InformationContent({ info }) {
616
812
  const colorScheme = (0, import_core5.useComputedColorScheme)();
@@ -618,46 +814,46 @@ function InformationContent({ info }) {
618
814
  const versionType = info.versionType ?? DEFAULT_VERSION_TYPE;
619
815
  const cards = [
620
816
  {
621
- icon: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_lucide_react3.User, { size: 18 }),
817
+ icon: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_lucide_react3.User, { size: 18 }),
622
818
  label: "Author",
623
819
  value: author,
624
820
  color: "blue"
625
821
  },
626
822
  {
627
- icon: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_lucide_react3.Award, { size: 18 }),
823
+ icon: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_lucide_react3.Award, { size: 18 }),
628
824
  label: "License",
629
825
  value: info.license ?? DEFAULT_LICENSE,
630
826
  color: "orange"
631
827
  },
632
828
  {
633
- icon: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_lucide_react3.MapPin, { size: 18 }),
829
+ icon: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_lucide_react3.MapPin, { size: 18 }),
634
830
  label: "Location",
635
831
  value: info.location ?? DEFAULT_LOCATION,
636
832
  color: "teal"
637
833
  },
638
834
  {
639
- icon: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_lucide_react3.Tag, { size: 18 }),
835
+ icon: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_lucide_react3.Tag, { size: 18 }),
640
836
  label: "Version Type",
641
837
  value: versionType,
642
838
  color: "red"
643
839
  },
644
840
  {
645
- icon: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_lucide_react3.Calendar, { size: 18 }),
841
+ icon: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_lucide_react3.Calendar, { size: 18 }),
646
842
  label: "Build Time",
647
843
  value: info.buildTime !== void 0 ? formatAbsoluteAndRelativeTime(info.buildTime) : UNKNOWN,
648
844
  color: "green"
649
845
  },
650
846
  ...info.metadata ?? []
651
847
  ];
652
- return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_core5.Stack, { gap: "lg", children: [
653
- /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_core5.Stack, { gap: "xs", align: "center", children: [
848
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_core5.Stack, { gap: "lg", children: [
849
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_core5.Stack, { gap: "xs", align: "center", children: [
654
850
  info.logo,
655
- /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_core5.Stack, { gap: 2, align: "center", children: [
656
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_core5.Title, { order: 2, children: info.name }),
657
- info.tagline && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_core5.Text, { size: "sm", c: "dimmed", w: 600, ta: "center", children: info.tagline })
851
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_core5.Stack, { gap: 2, align: "center", children: [
852
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_core5.Title, { order: 2, children: info.name }),
853
+ info.tagline && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_core5.Text, { size: "sm", c: "dimmed", w: 600, ta: "center", children: info.tagline })
658
854
  ] }),
659
- /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_core5.Group, { gap: "xs", children: [
660
- info.version && /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
855
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_core5.Group, { gap: "xs", children: [
856
+ info.version && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
661
857
  import_core5.Badge,
662
858
  {
663
859
  size: "lg",
@@ -672,7 +868,7 @@ function InformationContent({ info }) {
672
868
  ]
673
869
  }
674
870
  ),
675
- /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
871
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
676
872
  import_core5.Badge,
677
873
  {
678
874
  size: "lg",
@@ -689,39 +885,39 @@ function InformationContent({ info }) {
689
885
  )
690
886
  ] })
691
887
  ] }),
692
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_core5.Divider, { label: "System Information", labelPosition: "center" }),
693
- /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_core5.SimpleGrid, { cols: { base: 1, sm: 2 }, children: [
694
- cards.map((card) => /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
888
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_core5.Divider, { label: "System Information", labelPosition: "center" }),
889
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_core5.SimpleGrid, { cols: { base: 1, sm: 2 }, children: [
890
+ cards.map((card) => /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
695
891
  InfoCard,
696
892
  {
697
- icon: card.icon ?? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_lucide_react3.Award, { size: 18 }),
893
+ icon: card.icon ?? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_lucide_react3.Award, { size: 18 }),
698
894
  label: card.label,
699
895
  value: card.value,
700
896
  color: card.color ?? "gray"
701
897
  },
702
898
  card.label
703
899
  )),
704
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
900
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
705
901
  import_core5.Paper,
706
902
  {
707
903
  withBorder: true,
708
904
  p: "sm",
709
905
  radius: "18px",
710
906
  bg: colorScheme === "dark" ? "gray.9" : "gray.0",
711
- children: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_core5.Group, { justify: "space-between", wrap: "nowrap", children: [
712
- /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_core5.Group, { gap: "sm", flex: 1, children: [
713
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_core5.ThemeIcon, { variant: "light", color: "yellow", size: "lg", radius: "14px", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_lucide_react3.Hash, { size: 18 }) }),
714
- /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_core5.Stack, { gap: 2, children: [
715
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_core5.Text, { size: "xs", c: "dimmed", fw: 700, tt: "uppercase", children: "Build ID" }),
716
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_core5.Text, { size: "sm", fw: 500, truncate: true, children: info.buildId ?? UNKNOWN })
907
+ children: /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_core5.Group, { justify: "space-between", wrap: "nowrap", children: [
908
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_core5.Group, { gap: "sm", flex: 1, children: [
909
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_core5.ThemeIcon, { variant: "light", color: "yellow", size: "lg", radius: "14px", children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_lucide_react3.Hash, { size: 18 }) }),
910
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_core5.Stack, { gap: 2, children: [
911
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_core5.Text, { size: "xs", c: "dimmed", fw: 700, tt: "uppercase", children: "Build ID" }),
912
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_core5.Text, { size: "sm", fw: 500, truncate: true, children: info.buildId ?? UNKNOWN })
717
913
  ] })
718
914
  ] }),
719
- info.buildId && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(CopyBuildIdButton, { buildId: info.buildId })
915
+ info.buildId && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(CopyBuildIdButton, { buildId: info.buildId })
720
916
  ] })
721
917
  }
722
918
  )
723
919
  ] }),
724
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
920
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
725
921
  Footer,
726
922
  {
727
923
  copyright: info.copyright,
@@ -738,7 +934,7 @@ function InformationModal({
738
934
  info,
739
935
  title = DEFAULT_TITLE
740
936
  }) {
741
- return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
937
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
742
938
  import_core5.Modal,
743
939
  {
744
940
  opened,
@@ -758,7 +954,7 @@ function InformationModal({
758
954
  }
759
955
  },
760
956
  title,
761
- children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(InformationContent, { info })
957
+ children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(InformationContent, { info })
762
958
  }
763
959
  );
764
960
  }
@@ -771,13 +967,13 @@ function CopyBuildIdButton({ buildId }) {
771
967
  setTimeout(() => setCopied(false), 2e3);
772
968
  }
773
969
  };
774
- return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_core5.Tooltip, { label: copied ? "Copied!" : "Copy ID", withArrow: true, children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
970
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_core5.Tooltip, { label: copied ? "Copied!" : "Copy ID", withArrow: true, children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
775
971
  import_core5.ActionIcon,
776
972
  {
777
973
  variant: "subtle",
778
974
  color: copied ? "teal" : "gray",
779
975
  onClick: handleCopy,
780
- children: copied ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_lucide_react3.Check, { size: 16 }) : /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_lucide_react3.Copy, { size: 16 })
976
+ children: copied ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_lucide_react3.Check, { size: 16 }) : /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_lucide_react3.Copy, { size: 16 })
781
977
  }
782
978
  ) });
783
979
  }
@@ -788,26 +984,26 @@ function InfoCard({
788
984
  color
789
985
  }) {
790
986
  const colorScheme = (0, import_core5.useComputedColorScheme)();
791
- return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_core5.Paper, { withBorder: true, p: "md", radius: "18px", h: "100%", bg: colorScheme === "dark" ? "gray.9" : "gray.0", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_core5.Group, { gap: "sm", align: "flex-start", children: [
792
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_core5.ThemeIcon, { color, variant: "light", size: "lg", radius: "14px", children: icon }),
793
- /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_core5.Stack, { gap: 2, flex: 1, children: [
794
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_core5.Text, { size: "xs", c: "dimmed", fw: 700, tt: "uppercase", children: label }),
795
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_core5.Text, { size: "sm", fw: 500, lineClamp: 1, children: value })
987
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_core5.Paper, { withBorder: true, p: "md", radius: "18px", h: "100%", bg: colorScheme === "dark" ? "gray.9" : "gray.0", children: /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_core5.Group, { gap: "sm", align: "flex-start", children: [
988
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_core5.ThemeIcon, { color, variant: "light", size: "lg", radius: "14px", children: icon }),
989
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_core5.Stack, { gap: 2, flex: 1, children: [
990
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_core5.Text, { size: "xs", c: "dimmed", fw: 700, tt: "uppercase", children: label }),
991
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_core5.Text, { size: "sm", fw: 500, lineClamp: 1, children: value })
796
992
  ] })
797
993
  ] }) });
798
994
  }
799
995
 
800
996
  // src/pages/NotFound.tsx
801
997
  var import_core6 = require("@mantine/core");
802
- var import_icons_react3 = require("@tabler/icons-react");
803
- var import_jsx_runtime6 = require("react/jsx-runtime");
998
+ var import_icons_react4 = require("@tabler/icons-react");
999
+ var import_jsx_runtime7 = require("react/jsx-runtime");
804
1000
  function NotFound({
805
1001
  path,
806
1002
  onSearchClick,
807
1003
  onHomeClick
808
1004
  }) {
809
1005
  const currentPath = path || (typeof window !== "undefined" ? window.location.pathname : "/404");
810
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
1006
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
811
1007
  import_core6.Box,
812
1008
  {
813
1009
  style: {
@@ -816,8 +1012,8 @@ function NotFound({
816
1012
  alignItems: "center",
817
1013
  background: "radial-gradient(circle at top left, rgba(34, 139, 230, 0.15), transparent 45%), radial-gradient(circle at bottom right, rgba(34, 211, 238, 0.12), transparent 45%), var(--mantine-color-body)"
818
1014
  },
819
- children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_core6.Container, { size: "xl", py: 80, children: /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_core6.Paper, { radius: "xl", p: 48, withBorder: true, style: { borderColor: "var(--mantine-color-default-border)", textAlign: "center" }, children: [
820
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
1015
+ children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_core6.Container, { size: "xl", py: 80, children: /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_core6.Paper, { radius: "xl", p: 48, withBorder: true, style: { borderColor: "var(--mantine-color-default-border)", textAlign: "center" }, children: [
1016
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
821
1017
  import_core6.Box,
822
1018
  {
823
1019
  mx: "auto",
@@ -832,10 +1028,10 @@ function NotFound({
832
1028
  background: "linear-gradient(135deg, var(--mantine-color-blue-6), var(--mantine-color-cyan-6))",
833
1029
  boxShadow: "0 12px 32px rgba(34, 139, 230, 0.35)"
834
1030
  },
835
- children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_icons_react3.IconFileOff, { size: 44, stroke: 1.5, color: "white" })
1031
+ children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_icons_react4.IconFileOff, { size: 44, stroke: 1.5, color: "white" })
836
1032
  }
837
1033
  ),
838
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
1034
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
839
1035
  import_core6.Text,
840
1036
  {
841
1037
  fz: { base: 72, sm: 100 },
@@ -846,33 +1042,33 @@ function NotFound({
846
1042
  children: "404"
847
1043
  }
848
1044
  ),
849
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_core6.Badge, { variant: "light", color: "blue", size: "lg", mb: "xs", children: "NOT FOUND" }),
850
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_core6.Title, { order: 2, mt: "sm", mb: "xs", children: "Trang kh\xF4ng t\u1ED3n t\u1EA1i" }),
851
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_core6.Text, { c: "dimmed", size: "sm", maw: 440, mx: "auto", children: "Trang ho\u1EB7c \u0111\u01B0\u1EDDng d\u1EABn b\u1EA1n truy c\u1EADp kh\xF4ng t\u1ED3n t\u1EA1i ho\u1EB7c \u0111\xE3 \u0111\u01B0\u1EE3c di chuy\u1EC3n. Vui l\xF2ng ki\u1EC3m tra l\u1EA1i \u0111\u01B0\u1EDDng d\u1EABn ho\u1EB7c quay v\u1EC1 trang ch\u1EE7." }),
852
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_core6.Box, { mt: "lg", children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_core6.Code, { color: "blue", variant: "light", px: "md", py: 6, children: currentPath }) }),
853
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_core6.Group, { gap: "sm", mt: "xl", justify: "center", children: [
854
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
1045
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_core6.Badge, { variant: "light", color: "blue", size: "lg", mb: "xs", children: "NOT FOUND" }),
1046
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_core6.Title, { order: 2, mt: "sm", mb: "xs", children: "Trang kh\xF4ng t\u1ED3n t\u1EA1i" }),
1047
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_core6.Text, { c: "dimmed", size: "sm", maw: 440, mx: "auto", children: "Trang ho\u1EB7c \u0111\u01B0\u1EDDng d\u1EABn b\u1EA1n truy c\u1EADp kh\xF4ng t\u1ED3n t\u1EA1i ho\u1EB7c \u0111\xE3 \u0111\u01B0\u1EE3c di chuy\u1EC3n. Vui l\xF2ng ki\u1EC3m tra l\u1EA1i \u0111\u01B0\u1EDDng d\u1EABn ho\u1EB7c quay v\u1EC1 trang ch\u1EE7." }),
1048
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_core6.Box, { mt: "lg", children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_core6.Code, { color: "blue", variant: "light", px: "md", py: 6, children: currentPath }) }),
1049
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_core6.Group, { gap: "sm", mt: "xl", justify: "center", children: [
1050
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
855
1051
  import_core6.Button,
856
1052
  {
857
1053
  variant: "light",
858
- leftSection: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_icons_react3.IconArrowLeft, { size: 16 }),
1054
+ leftSection: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_icons_react4.IconArrowLeft, { size: 16 }),
859
1055
  onClick: () => window.history.back(),
860
1056
  children: "Quay l\u1EA1i"
861
1057
  }
862
1058
  ),
863
- onSearchClick && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
1059
+ onSearchClick && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
864
1060
  import_core6.Button,
865
1061
  {
866
1062
  variant: "outline",
867
- leftSection: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_icons_react3.IconSearch, { size: 16 }),
1063
+ leftSection: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_icons_react4.IconSearch, { size: 16 }),
868
1064
  onClick: onSearchClick,
869
1065
  children: "T\xECm Docs"
870
1066
  }
871
1067
  ),
872
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
1068
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
873
1069
  import_core6.Button,
874
1070
  {
875
- leftSection: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_icons_react3.IconHome, { size: 16 }),
1071
+ leftSection: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_icons_react4.IconHome, { size: 16 }),
876
1072
  onClick: onHomeClick || (() => window.location.href = "/"),
877
1073
  children: "Trang ch\u1EE7"
878
1074
  }
@@ -882,8 +1078,92 @@ function NotFound({
882
1078
  }
883
1079
  );
884
1080
  }
1081
+
1082
+ // src/utils/debug.ts
1083
+ var env = globalThis.process?.env ?? {};
1084
+ var shouldLog = env.NODE_ENV !== "production";
1085
+ var debugInclude = (() => {
1086
+ try {
1087
+ const envValue = globalThis.__OTMC_DEBUG_INCLUDE__ ?? env.OTMC_DEBUG_INCLUDE;
1088
+ if (envValue) {
1089
+ return JSON.parse(envValue);
1090
+ }
1091
+ } catch (e) {
1092
+ console.warn("Failed to parse OTMC_DEBUG_INCLUDE:", e);
1093
+ }
1094
+ return [];
1095
+ })();
1096
+ var shouldLogForFile = (fileName) => {
1097
+ if (!shouldLog) return false;
1098
+ if (!fileName || debugInclude.length === 0) return true;
1099
+ return debugInclude.some((included) => fileName.includes(included));
1100
+ };
1101
+ var getCallingFile = () => {
1102
+ const stack = new Error().stack;
1103
+ if (!stack) return void 0;
1104
+ const lines = stack.split("\n");
1105
+ for (let i = 3; i < lines.length; i++) {
1106
+ const line = lines[i];
1107
+ const match = line.match(/at .*?\((.+?):\d+:\d+\)|at (.+?):\d+:\d+/);
1108
+ if (match) {
1109
+ const filePath = match[1] || match[2];
1110
+ const fileName = filePath.split("/").pop();
1111
+ return fileName;
1112
+ }
1113
+ }
1114
+ return void 0;
1115
+ };
1116
+ var debug = {
1117
+ log: (...args) => {
1118
+ const fileName = getCallingFile();
1119
+ if (shouldLogForFile(fileName)) {
1120
+ console.log(...args);
1121
+ }
1122
+ },
1123
+ warn: (...args) => {
1124
+ const fileName = getCallingFile();
1125
+ if (shouldLogForFile(fileName)) {
1126
+ console.warn(...args);
1127
+ }
1128
+ },
1129
+ error: (...args) => {
1130
+ const fileName = getCallingFile();
1131
+ if (shouldLogForFile(fileName)) {
1132
+ console.error(...args);
1133
+ }
1134
+ },
1135
+ table: (...args) => {
1136
+ const fileName = getCallingFile();
1137
+ if (shouldLogForFile(fileName)) {
1138
+ console.table(...args);
1139
+ }
1140
+ },
1141
+ withFile: (fileName) => ({
1142
+ log: (...args) => {
1143
+ if (shouldLogForFile(fileName)) {
1144
+ console.log(...args);
1145
+ }
1146
+ },
1147
+ warn: (...args) => {
1148
+ if (shouldLogForFile(fileName)) {
1149
+ console.warn(...args);
1150
+ }
1151
+ },
1152
+ error: (...args) => {
1153
+ if (shouldLogForFile(fileName)) {
1154
+ console.error(...args);
1155
+ }
1156
+ },
1157
+ table: (...args) => {
1158
+ if (shouldLogForFile(fileName)) {
1159
+ console.table(...args);
1160
+ }
1161
+ }
1162
+ })
1163
+ };
885
1164
  // Annotate the CommonJS export names for ESM import in node:
886
1165
  0 && (module.exports = {
1166
+ BACKEND_URL,
887
1167
  DEFAULT_AUTHOR,
888
1168
  DEFAULT_AUTHOR_HREF,
889
1169
  DEFAULT_COPYRIGHT,
@@ -898,15 +1178,24 @@ function NotFound({
898
1178
  ThemeProvider,
899
1179
  ThemeSetting,
900
1180
  UNKNOWN,
1181
+ apiClient,
1182
+ apiUtils,
901
1183
  calculateRemainingTime,
902
1184
  copyToClipboard,
1185
+ debug,
903
1186
  formatAbsolute,
904
1187
  formatAbsoluteAndRelativeTime,
905
1188
  formatHumanDate,
906
1189
  formatRelativeTime,
1190
+ getBackendUrl,
1191
+ instructionsApi,
1192
+ llmApi,
907
1193
  normalizeDate,
1194
+ notificationCenter,
908
1195
  pad,
909
1196
  resolveColorScheme,
1197
+ setAccessTokenGetter,
1198
+ setBackendUrl,
910
1199
  useTheme
911
1200
  });
912
1201
  //# sourceMappingURL=index.cjs.map