@nice2dev/templates 1.0.10

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.mjs ADDED
@@ -0,0 +1,3948 @@
1
+ var Y = Object.defineProperty;
2
+ var _ = (a, e, t) => e in a ? Y(a, e, { enumerable: !0, configurable: !0, writable: !0, value: t }) : a[e] = t;
3
+ var w = (a, e, t) => _(a, typeof e != "symbol" ? e + "" : e, t);
4
+ import { jsx as i, jsxs as o } from "react/jsx-runtime";
5
+ import { createContext as F, useContext as W, useState as S, useCallback as L, useMemo as z, useEffect as X } from "react";
6
+ const J = [
7
+ {
8
+ id: "apple",
9
+ name: "Apple",
10
+ servingSize: 1,
11
+ servingUnit: "medium",
12
+ calories: 95,
13
+ protein: 0.5,
14
+ carbs: 25,
15
+ fat: 0.3,
16
+ fiber: 4.4
17
+ },
18
+ {
19
+ id: "banana",
20
+ name: "Banana",
21
+ servingSize: 1,
22
+ servingUnit: "medium",
23
+ calories: 105,
24
+ protein: 1.3,
25
+ carbs: 27,
26
+ fat: 0.4,
27
+ fiber: 3.1
28
+ },
29
+ {
30
+ id: "chicken-breast",
31
+ name: "Chicken Breast",
32
+ servingSize: 100,
33
+ servingUnit: "g",
34
+ calories: 165,
35
+ protein: 31,
36
+ carbs: 0,
37
+ fat: 3.6
38
+ },
39
+ {
40
+ id: "brown-rice",
41
+ name: "Brown Rice",
42
+ servingSize: 1,
43
+ servingUnit: "cup",
44
+ calories: 216,
45
+ protein: 5,
46
+ carbs: 45,
47
+ fat: 1.8,
48
+ fiber: 3.5
49
+ },
50
+ {
51
+ id: "egg",
52
+ name: "Egg",
53
+ servingSize: 1,
54
+ servingUnit: "large",
55
+ calories: 78,
56
+ protein: 6,
57
+ carbs: 0.6,
58
+ fat: 5
59
+ },
60
+ {
61
+ id: "salmon",
62
+ name: "Salmon",
63
+ servingSize: 100,
64
+ servingUnit: "g",
65
+ calories: 208,
66
+ protein: 20,
67
+ carbs: 0,
68
+ fat: 13
69
+ },
70
+ {
71
+ id: "broccoli",
72
+ name: "Broccoli",
73
+ servingSize: 1,
74
+ servingUnit: "cup",
75
+ calories: 55,
76
+ protein: 3.7,
77
+ carbs: 11,
78
+ fat: 0.6,
79
+ fiber: 5.1
80
+ },
81
+ {
82
+ id: "oatmeal",
83
+ name: "Oatmeal",
84
+ servingSize: 1,
85
+ servingUnit: "cup",
86
+ calories: 158,
87
+ protein: 6,
88
+ carbs: 27,
89
+ fat: 3.2,
90
+ fiber: 4
91
+ },
92
+ {
93
+ id: "greek-yogurt",
94
+ name: "Greek Yogurt",
95
+ servingSize: 1,
96
+ servingUnit: "cup",
97
+ calories: 100,
98
+ protein: 17,
99
+ carbs: 6,
100
+ fat: 0.7
101
+ },
102
+ {
103
+ id: "almonds",
104
+ name: "Almonds",
105
+ servingSize: 1,
106
+ servingUnit: "oz",
107
+ calories: 164,
108
+ protein: 6,
109
+ carbs: 6,
110
+ fat: 14,
111
+ fiber: 3.5
112
+ }
113
+ ];
114
+ class Z {
115
+ constructor() {
116
+ w(this, "workouts", /* @__PURE__ */ new Map());
117
+ w(this, "meals", /* @__PURE__ */ new Map());
118
+ w(this, "sleep", /* @__PURE__ */ new Map());
119
+ w(this, "medicalRecords", /* @__PURE__ */ new Map());
120
+ w(this, "medications", /* @__PURE__ */ new Map());
121
+ w(this, "medicationLogs", []);
122
+ w(this, "vitals", []);
123
+ w(this, "goals", []);
124
+ w(this, "foodDatabase", [...J]);
125
+ }
126
+ /* ─────────────────────────────────────────────────────────────
127
+ WORKOUTS
128
+ ───────────────────────────────────────────────────────────── */
129
+ addWorkout(e) {
130
+ const t = this.generateId(), n = { ...e, id: t };
131
+ return this.workouts.set(t, n), n;
132
+ }
133
+ updateWorkout(e, t) {
134
+ const n = this.workouts.get(e);
135
+ n && this.workouts.set(e, { ...n, ...t, id: e });
136
+ }
137
+ deleteWorkout(e) {
138
+ this.workouts.delete(e);
139
+ }
140
+ getAllWorkouts() {
141
+ return Array.from(this.workouts.values()).sort(
142
+ (e, t) => new Date(t.date).getTime() - new Date(e.date).getTime()
143
+ );
144
+ }
145
+ getWorkoutsForPeriod(e, t) {
146
+ return this.getAllWorkouts().filter((n) => {
147
+ const r = new Date(n.date);
148
+ return r >= e && r <= t;
149
+ });
150
+ }
151
+ getWorkoutStats(e = 7) {
152
+ const t = new Date(Date.now() - e * 864e5), n = this.getWorkoutsForPeriod(t, /* @__PURE__ */ new Date()), r = /* @__PURE__ */ new Map();
153
+ for (const s of n)
154
+ r.set(s.type, (r.get(s.type) || 0) + 1);
155
+ return {
156
+ totalWorkouts: n.length,
157
+ totalDuration: n.reduce((s, l) => s + l.duration, 0),
158
+ totalCalories: n.reduce((s, l) => s + l.caloriesBurned, 0),
159
+ avgDuration: n.length > 0 ? n.reduce((s, l) => s + l.duration, 0) / n.length : 0,
160
+ byType: Array.from(r.entries()).map(([s, l]) => ({ type: s, count: l }))
161
+ };
162
+ }
163
+ /* ─────────────────────────────────────────────────────────────
164
+ NUTRITION
165
+ ───────────────────────────────────────────────────────────── */
166
+ addMeal(e) {
167
+ const t = this.generateId(), n = this.calculateMealTotals(e.foods), r = { ...e, id: t, ...n };
168
+ return this.meals.set(t, r), r;
169
+ }
170
+ calculateMealTotals(e) {
171
+ return e.reduce(
172
+ (t, { item: n, servings: r }) => ({
173
+ totalCalories: t.totalCalories + n.calories * r,
174
+ totalProtein: t.totalProtein + n.protein * r,
175
+ totalCarbs: t.totalCarbs + n.carbs * r,
176
+ totalFat: t.totalFat + n.fat * r
177
+ }),
178
+ { totalCalories: 0, totalProtein: 0, totalCarbs: 0, totalFat: 0 }
179
+ );
180
+ }
181
+ deleteMeal(e) {
182
+ this.meals.delete(e);
183
+ }
184
+ getAllMeals() {
185
+ return Array.from(this.meals.values()).sort(
186
+ (e, t) => new Date(t.date).getTime() - new Date(e.date).getTime()
187
+ );
188
+ }
189
+ getMealsForDate(e) {
190
+ const t = new Date(e);
191
+ t.setHours(0, 0, 0, 0);
192
+ const n = new Date(t.getTime() + 864e5);
193
+ return this.getAllMeals().filter((r) => {
194
+ const s = new Date(r.date);
195
+ return s >= t && s < n;
196
+ });
197
+ }
198
+ getDailyNutrition(e) {
199
+ const t = this.getMealsForDate(e);
200
+ return {
201
+ calories: t.reduce((n, r) => n + r.totalCalories, 0),
202
+ protein: t.reduce((n, r) => n + r.totalProtein, 0),
203
+ carbs: t.reduce((n, r) => n + r.totalCarbs, 0),
204
+ fat: t.reduce((n, r) => n + r.totalFat, 0),
205
+ meals: t.length
206
+ };
207
+ }
208
+ searchFoods(e) {
209
+ const t = e.toLowerCase();
210
+ return this.foodDatabase.filter((n) => n.name.toLowerCase().includes(t));
211
+ }
212
+ addCustomFood(e) {
213
+ const t = this.generateId(), n = { ...e, id: t };
214
+ return this.foodDatabase.push(n), n;
215
+ }
216
+ /* ─────────────────────────────────────────────────────────────
217
+ SLEEP
218
+ ───────────────────────────────────────────────────────────── */
219
+ addSleepEntry(e) {
220
+ const t = this.generateId(), n = (new Date(e.wakeTime).getTime() - new Date(e.bedtime).getTime()) / 36e5, r = { ...e, id: t, duration: n };
221
+ return this.sleep.set(t, r), r;
222
+ }
223
+ updateSleepEntry(e, t) {
224
+ const n = this.sleep.get(e);
225
+ if (n) {
226
+ let r = n.duration;
227
+ if (t.bedtime || t.wakeTime) {
228
+ const s = t.bedtime || n.bedtime, l = t.wakeTime || n.wakeTime;
229
+ r = (new Date(l).getTime() - new Date(s).getTime()) / 36e5;
230
+ }
231
+ this.sleep.set(e, { ...n, ...t, id: e, duration: r });
232
+ }
233
+ }
234
+ deleteSleepEntry(e) {
235
+ this.sleep.delete(e);
236
+ }
237
+ getAllSleepEntries() {
238
+ return Array.from(this.sleep.values()).sort(
239
+ (e, t) => new Date(t.date).getTime() - new Date(e.date).getTime()
240
+ );
241
+ }
242
+ getSleepStats(e = 7) {
243
+ const t = new Date(Date.now() - e * 864e5), n = this.getAllSleepEntries().filter((l) => new Date(l.date) >= t), r = {
244
+ poor: 1,
245
+ fair: 2,
246
+ good: 3,
247
+ excellent: 4
248
+ }, s = /* @__PURE__ */ new Map();
249
+ for (const l of n)
250
+ s.set(l.quality, (s.get(l.quality) || 0) + 1);
251
+ return {
252
+ avgDuration: n.length > 0 ? n.reduce((l, d) => l + d.duration, 0) / n.length : 0,
253
+ avgQuality: n.length > 0 ? n.reduce((l, d) => l + r[d.quality], 0) / n.length : 0,
254
+ totalEntries: n.length,
255
+ qualityDistribution: Array.from(s.entries()).map(([l, d]) => ({
256
+ quality: l,
257
+ count: d
258
+ }))
259
+ };
260
+ }
261
+ /* ─────────────────────────────────────────────────────────────
262
+ MEDICAL RECORDS
263
+ ───────────────────────────────────────────────────────────── */
264
+ addMedicalRecord(e) {
265
+ const t = this.generateId(), n = { ...e, id: t };
266
+ return this.medicalRecords.set(t, n), n;
267
+ }
268
+ updateMedicalRecord(e, t) {
269
+ const n = this.medicalRecords.get(e);
270
+ n && this.medicalRecords.set(e, { ...n, ...t, id: e });
271
+ }
272
+ deleteMedicalRecord(e) {
273
+ this.medicalRecords.delete(e);
274
+ }
275
+ getAllMedicalRecords() {
276
+ return Array.from(this.medicalRecords.values()).sort(
277
+ (e, t) => new Date(t.date).getTime() - new Date(e.date).getTime()
278
+ );
279
+ }
280
+ getMedicalRecordsByType(e) {
281
+ return this.getAllMedicalRecords().filter((t) => t.type === e);
282
+ }
283
+ getUpcomingFollowUps(e = 30) {
284
+ const t = /* @__PURE__ */ new Date(), n = new Date(t.getTime() + e * 864e5);
285
+ return this.getAllMedicalRecords().filter(
286
+ (r) => r.followUp && new Date(r.followUp) >= t && new Date(r.followUp) <= n
287
+ );
288
+ }
289
+ /* ─────────────────────────────────────────────────────────────
290
+ MEDICATIONS
291
+ ───────────────────────────────────────────────────────────── */
292
+ addMedication(e) {
293
+ const t = this.generateId(), n = { ...e, id: t };
294
+ return this.medications.set(t, n), n;
295
+ }
296
+ updateMedication(e, t) {
297
+ const n = this.medications.get(e);
298
+ n && this.medications.set(e, { ...n, ...t, id: e });
299
+ }
300
+ deleteMedication(e) {
301
+ this.medications.delete(e), this.medicationLogs = this.medicationLogs.filter((t) => t.medicationId !== e);
302
+ }
303
+ getAllMedications() {
304
+ return Array.from(this.medications.values());
305
+ }
306
+ getActiveMedications() {
307
+ return this.getAllMedications().filter((e) => e.isActive);
308
+ }
309
+ logMedication(e, t, n, r) {
310
+ const s = {
311
+ id: this.generateId(),
312
+ medicationId: e,
313
+ scheduledTime: t,
314
+ takenTime: n ? /* @__PURE__ */ new Date() : void 0,
315
+ skipped: !n,
316
+ notes: r
317
+ };
318
+ this.medicationLogs.push(s);
319
+ }
320
+ getMedicationLogsForDate(e) {
321
+ const t = new Date(e);
322
+ t.setHours(0, 0, 0, 0);
323
+ const n = new Date(t.getTime() + 864e5);
324
+ return this.medicationLogs.filter((r) => {
325
+ const s = new Date(r.scheduledTime);
326
+ return s >= t && s < n;
327
+ });
328
+ }
329
+ getTodayMedicationSchedule() {
330
+ const e = /* @__PURE__ */ new Date(), t = this.getMedicationLogsForDate(e), n = [];
331
+ for (const r of this.getActiveMedications())
332
+ for (const s of r.times) {
333
+ const l = t.find(
334
+ (d) => d.medicationId === r.id && new Date(d.scheduledTime).toTimeString().startsWith(s)
335
+ );
336
+ n.push({
337
+ medication: r,
338
+ time: s,
339
+ taken: (l == null ? void 0 : l.takenTime) !== void 0
340
+ });
341
+ }
342
+ return n.sort((r, s) => r.time.localeCompare(s.time));
343
+ }
344
+ /* ─────────────────────────────────────────────────────────────
345
+ VITALS
346
+ ───────────────────────────────────────────────────────────── */
347
+ recordVitals(e) {
348
+ this.vitals.push(e), this.vitals.sort((t, n) => new Date(n.date).getTime() - new Date(t.date).getTime());
349
+ }
350
+ getVitalsHistory() {
351
+ return [...this.vitals];
352
+ }
353
+ getLatestVitals() {
354
+ return this.vitals[0];
355
+ }
356
+ getWeightHistory(e = 30) {
357
+ const t = new Date(Date.now() - e * 864e5);
358
+ return this.vitals.filter((n) => n.weight !== void 0 && new Date(n.date) >= t).map((n) => ({ date: n.date, weight: n.weight }));
359
+ }
360
+ /* ─────────────────────────────────────────────────────────────
361
+ GOALS
362
+ ───────────────────────────────────────────────────────────── */
363
+ setGoal(e) {
364
+ const t = this.goals.findIndex((n) => n.id === e.id);
365
+ t >= 0 ? this.goals[t] = e : this.goals.push(e);
366
+ }
367
+ getGoals() {
368
+ return [...this.goals];
369
+ }
370
+ updateGoalProgress(e, t) {
371
+ const n = this.goals.find((r) => r.id === e);
372
+ n && (n.current = t);
373
+ }
374
+ /* ─────────────────────────────────────────────────────────────
375
+ UTILITIES
376
+ ───────────────────────────────────────────────────────────── */
377
+ generateId() {
378
+ return Date.now().toString(36) + Math.random().toString(36).substring(2, 8);
379
+ }
380
+ clear() {
381
+ this.workouts.clear(), this.meals.clear(), this.sleep.clear(), this.medicalRecords.clear(), this.medications.clear(), this.medicationLogs = [], this.vitals = [], this.goals = [];
382
+ }
383
+ }
384
+ function Ue() {
385
+ return new Z();
386
+ }
387
+ const N = F(null);
388
+ function je() {
389
+ const a = W(N);
390
+ if (!a)
391
+ throw new Error("useHealth must be used within HealthProvider");
392
+ return a;
393
+ }
394
+ const h = {
395
+ container: {
396
+ display: "flex",
397
+ height: "100%",
398
+ fontFamily: "'Inter', sans-serif",
399
+ backgroundColor: "#f5f7fa"
400
+ },
401
+ sidebar: {
402
+ width: "200px",
403
+ backgroundColor: "#fff",
404
+ borderRight: "1px solid #e0e0e0",
405
+ padding: "20px 0"
406
+ },
407
+ main: {
408
+ flex: 1,
409
+ padding: "20px",
410
+ overflow: "auto"
411
+ },
412
+ navItem: {
413
+ padding: "12px 24px",
414
+ cursor: "pointer",
415
+ display: "flex",
416
+ alignItems: "center",
417
+ gap: "12px",
418
+ borderLeft: "3px solid transparent"
419
+ },
420
+ grid: {
421
+ display: "grid",
422
+ gridTemplateColumns: "repeat(auto-fit, minmax(280px, 1fr))",
423
+ gap: "20px",
424
+ marginBottom: "20px"
425
+ },
426
+ card: {
427
+ backgroundColor: "#fff",
428
+ borderRadius: "12px",
429
+ padding: "20px",
430
+ boxShadow: "0 2px 8px rgba(0,0,0,0.08)"
431
+ },
432
+ cardTitle: {
433
+ fontSize: "16px",
434
+ fontWeight: 600,
435
+ marginBottom: "16px",
436
+ color: "#1a1a2e"
437
+ },
438
+ statValue: {
439
+ fontSize: "32px",
440
+ fontWeight: 700,
441
+ color: "#1976d2"
442
+ },
443
+ statLabel: {
444
+ fontSize: "12px",
445
+ color: "#666",
446
+ textTransform: "uppercase",
447
+ letterSpacing: "1px"
448
+ },
449
+ progressBar: {
450
+ height: "8px",
451
+ backgroundColor: "#e0e0e0",
452
+ borderRadius: "4px",
453
+ overflow: "hidden"
454
+ },
455
+ listItem: {
456
+ display: "flex",
457
+ alignItems: "center",
458
+ gap: "12px",
459
+ padding: "12px 0",
460
+ borderBottom: "1px solid #f0f0f0"
461
+ }
462
+ };
463
+ function He({ service: a, className: e, style: t }) {
464
+ const [, n] = S(0), [r, s] = S("overview"), l = L(() => n((g) => g + 1), []), d = { service: a, refresh: l }, c = [
465
+ { id: "overview", icon: "📊", label: "Overview" },
466
+ { id: "workouts", icon: "🏋️", label: "Workouts" },
467
+ { id: "nutrition", icon: "🥗", label: "Nutrition" },
468
+ { id: "sleep", icon: "😴", label: "Sleep" },
469
+ { id: "medical", icon: "🏥", label: "Medical" },
470
+ { id: "medications", icon: "💊", label: "Medications" }
471
+ ];
472
+ return /* @__PURE__ */ i(N.Provider, { value: d, children: /* @__PURE__ */ o("div", { className: e, style: { ...h.container, ...t }, children: [
473
+ /* @__PURE__ */ i("div", { style: h.sidebar, children: c.map((g) => /* @__PURE__ */ o(
474
+ "div",
475
+ {
476
+ onClick: () => s(g.id),
477
+ style: {
478
+ ...h.navItem,
479
+ backgroundColor: r === g.id ? "#e3f2fd" : "transparent",
480
+ borderLeftColor: r === g.id ? "#1976d2" : "transparent",
481
+ fontWeight: r === g.id ? 600 : 400
482
+ },
483
+ children: [
484
+ /* @__PURE__ */ i("span", { children: g.icon }),
485
+ /* @__PURE__ */ i("span", { children: g.label })
486
+ ]
487
+ },
488
+ g.id
489
+ )) }),
490
+ /* @__PURE__ */ o("div", { style: h.main, children: [
491
+ r === "overview" && /* @__PURE__ */ i(ee, { service: a }),
492
+ r === "workouts" && /* @__PURE__ */ i(te, { service: a, refresh: l }),
493
+ r === "nutrition" && /* @__PURE__ */ i(ne, { service: a }),
494
+ r === "sleep" && /* @__PURE__ */ i(re, { service: a }),
495
+ r === "medical" && /* @__PURE__ */ i(ie, { service: a }),
496
+ r === "medications" && /* @__PURE__ */ i(se, { service: a, refresh: l })
497
+ ] })
498
+ ] }) });
499
+ }
500
+ function ee({ service: a }) {
501
+ const e = a.getWorkoutStats(7), t = a.getSleepStats(7), n = a.getDailyNutrition(/* @__PURE__ */ new Date()), r = a.getLatestVitals(), s = a.getTodayMedicationSchedule();
502
+ return /* @__PURE__ */ o("div", { children: [
503
+ /* @__PURE__ */ i("h2", { style: { marginBottom: "20px" }, children: "Health Overview" }),
504
+ /* @__PURE__ */ o("div", { style: h.grid, children: [
505
+ /* @__PURE__ */ o("div", { style: h.card, children: [
506
+ /* @__PURE__ */ i("div", { style: h.cardTitle, children: "This Week's Workouts" }),
507
+ /* @__PURE__ */ i("div", { style: h.statValue, children: e.totalWorkouts }),
508
+ /* @__PURE__ */ i("div", { style: h.statLabel, children: "Workouts" }),
509
+ /* @__PURE__ */ o("div", { style: { marginTop: "12px", display: "flex", gap: "20px" }, children: [
510
+ /* @__PURE__ */ o("div", { children: [
511
+ /* @__PURE__ */ i("div", { style: { fontSize: "18px", fontWeight: 600 }, children: e.totalDuration }),
512
+ /* @__PURE__ */ i("div", { style: { fontSize: "12px", color: "#666" }, children: "Minutes" })
513
+ ] }),
514
+ /* @__PURE__ */ o("div", { children: [
515
+ /* @__PURE__ */ i("div", { style: { fontSize: "18px", fontWeight: 600 }, children: e.totalCalories }),
516
+ /* @__PURE__ */ i("div", { style: { fontSize: "12px", color: "#666" }, children: "Calories" })
517
+ ] })
518
+ ] })
519
+ ] }),
520
+ /* @__PURE__ */ o("div", { style: h.card, children: [
521
+ /* @__PURE__ */ i("div", { style: h.cardTitle, children: "Sleep (7-Day Average)" }),
522
+ /* @__PURE__ */ o("div", { style: h.statValue, children: [
523
+ t.avgDuration.toFixed(1),
524
+ "h"
525
+ ] }),
526
+ /* @__PURE__ */ i("div", { style: h.statLabel, children: "Per Night" }),
527
+ /* @__PURE__ */ i("div", { style: { marginTop: "12px" }, children: /* @__PURE__ */ o("div", { style: { fontSize: "14px", color: "#666" }, children: [
528
+ "Quality: ",
529
+ t.avgQuality.toFixed(1),
530
+ "/4"
531
+ ] }) })
532
+ ] }),
533
+ /* @__PURE__ */ o("div", { style: h.card, children: [
534
+ /* @__PURE__ */ i("div", { style: h.cardTitle, children: "Today's Nutrition" }),
535
+ /* @__PURE__ */ i("div", { style: h.statValue, children: n.calories }),
536
+ /* @__PURE__ */ i("div", { style: h.statLabel, children: "Calories" }),
537
+ /* @__PURE__ */ o("div", { style: { marginTop: "12px", display: "flex", gap: "16px", fontSize: "14px" }, children: [
538
+ /* @__PURE__ */ o("div", { children: [
539
+ "P: ",
540
+ n.protein,
541
+ "g"
542
+ ] }),
543
+ /* @__PURE__ */ o("div", { children: [
544
+ "C: ",
545
+ n.carbs,
546
+ "g"
547
+ ] }),
548
+ /* @__PURE__ */ o("div", { children: [
549
+ "F: ",
550
+ n.fat,
551
+ "g"
552
+ ] })
553
+ ] })
554
+ ] }),
555
+ /* @__PURE__ */ o("div", { style: h.card, children: [
556
+ /* @__PURE__ */ i("div", { style: h.cardTitle, children: "Latest Vitals" }),
557
+ r ? /* @__PURE__ */ o("div", { style: { display: "grid", gridTemplateColumns: "1fr 1fr", gap: "12px" }, children: [
558
+ r.weight && /* @__PURE__ */ o("div", { children: [
559
+ /* @__PURE__ */ o("div", { style: { fontSize: "18px", fontWeight: 600 }, children: [
560
+ r.weight,
561
+ " ",
562
+ r.weightUnit || "kg"
563
+ ] }),
564
+ /* @__PURE__ */ i("div", { style: { fontSize: "12px", color: "#666" }, children: "Weight" })
565
+ ] }),
566
+ r.bloodPressureSystolic && /* @__PURE__ */ o("div", { children: [
567
+ /* @__PURE__ */ o("div", { style: { fontSize: "18px", fontWeight: 600 }, children: [
568
+ r.bloodPressureSystolic,
569
+ "/",
570
+ r.bloodPressureDiastolic
571
+ ] }),
572
+ /* @__PURE__ */ i("div", { style: { fontSize: "12px", color: "#666" }, children: "Blood Pressure" })
573
+ ] }),
574
+ r.heartRate && /* @__PURE__ */ o("div", { children: [
575
+ /* @__PURE__ */ i("div", { style: { fontSize: "18px", fontWeight: 600 }, children: r.heartRate }),
576
+ /* @__PURE__ */ i("div", { style: { fontSize: "12px", color: "#666" }, children: "Heart Rate" })
577
+ ] })
578
+ ] }) : /* @__PURE__ */ i("div", { style: { color: "#999" }, children: "No vitals recorded" })
579
+ ] })
580
+ ] }),
581
+ /* @__PURE__ */ o("div", { style: h.card, children: [
582
+ /* @__PURE__ */ i("div", { style: h.cardTitle, children: "Today's Medications" }),
583
+ s.length === 0 ? /* @__PURE__ */ i("div", { style: { color: "#999", textAlign: "center", padding: "20px" }, children: "No medications scheduled" }) : s.map((l, d) => /* @__PURE__ */ o("div", { style: h.listItem, children: [
584
+ /* @__PURE__ */ i("span", { style: { width: "60px", fontWeight: 500 }, children: l.time }),
585
+ /* @__PURE__ */ o("span", { style: { flex: 1 }, children: [
586
+ l.medication.name,
587
+ " (",
588
+ l.medication.dosage,
589
+ ")"
590
+ ] }),
591
+ /* @__PURE__ */ i(
592
+ "span",
593
+ {
594
+ style: {
595
+ padding: "4px 12px",
596
+ borderRadius: "12px",
597
+ fontSize: "12px",
598
+ backgroundColor: l.taken ? "#e8f5e9" : "#fff3e0",
599
+ color: l.taken ? "#2e7d32" : "#ef6c00"
600
+ },
601
+ children: l.taken ? "Taken" : "Pending"
602
+ }
603
+ )
604
+ ] }, d))
605
+ ] })
606
+ ] });
607
+ }
608
+ function te({
609
+ service: a,
610
+ refresh: e
611
+ }) {
612
+ const t = a.getAllWorkouts(), n = a.getWorkoutStats(30);
613
+ return /* @__PURE__ */ o("div", { children: [
614
+ /* @__PURE__ */ i("h2", { style: { marginBottom: "20px" }, children: "Workouts" }),
615
+ /* @__PURE__ */ o("div", { style: h.grid, children: [
616
+ /* @__PURE__ */ o("div", { style: h.card, children: [
617
+ /* @__PURE__ */ i("div", { style: h.statValue, children: n.totalWorkouts }),
618
+ /* @__PURE__ */ i("div", { style: h.statLabel, children: "Workouts (30 days)" })
619
+ ] }),
620
+ /* @__PURE__ */ o("div", { style: h.card, children: [
621
+ /* @__PURE__ */ i("div", { style: h.statValue, children: n.totalDuration }),
622
+ /* @__PURE__ */ i("div", { style: h.statLabel, children: "Total Minutes" })
623
+ ] }),
624
+ /* @__PURE__ */ o("div", { style: h.card, children: [
625
+ /* @__PURE__ */ i("div", { style: h.statValue, children: n.totalCalories }),
626
+ /* @__PURE__ */ i("div", { style: h.statLabel, children: "Calories Burned" })
627
+ ] })
628
+ ] }),
629
+ /* @__PURE__ */ o("div", { style: h.card, children: [
630
+ /* @__PURE__ */ i("div", { style: h.cardTitle, children: "Recent Workouts" }),
631
+ t.length === 0 ? /* @__PURE__ */ i("div", { style: { color: "#999", textAlign: "center", padding: "30px" }, children: "No workouts logged yet" }) : t.slice(0, 10).map((r) => /* @__PURE__ */ o("div", { style: h.listItem, children: [
632
+ /* @__PURE__ */ o("div", { style: { flex: 1 }, children: [
633
+ /* @__PURE__ */ i("div", { style: { fontWeight: 500 }, children: r.name }),
634
+ /* @__PURE__ */ o("div", { style: { fontSize: "12px", color: "#666" }, children: [
635
+ new Date(r.date).toLocaleDateString(),
636
+ " • ",
637
+ r.duration,
638
+ " min •",
639
+ " ",
640
+ r.caloriesBurned,
641
+ " cal"
642
+ ] })
643
+ ] }),
644
+ /* @__PURE__ */ i(
645
+ "span",
646
+ {
647
+ style: {
648
+ padding: "4px 8px",
649
+ borderRadius: "4px",
650
+ fontSize: "12px",
651
+ backgroundColor: "#e3f2fd",
652
+ color: "#1565c0",
653
+ textTransform: "capitalize"
654
+ },
655
+ children: r.type
656
+ }
657
+ )
658
+ ] }, r.id))
659
+ ] })
660
+ ] });
661
+ }
662
+ function ne({ service: a }) {
663
+ const e = a.getDailyNutrition(/* @__PURE__ */ new Date()), t = a.getMealsForDate(/* @__PURE__ */ new Date()), n = { calories: 2e3, protein: 150, carbs: 250, fat: 65 };
664
+ return /* @__PURE__ */ o("div", { children: [
665
+ /* @__PURE__ */ i("h2", { style: { marginBottom: "20px" }, children: "Nutrition" }),
666
+ /* @__PURE__ */ i("div", { style: h.grid, children: [
667
+ { label: "Calories", value: e.calories, target: n.calories, unit: "" },
668
+ { label: "Protein", value: e.protein, target: n.protein, unit: "g" },
669
+ { label: "Carbs", value: e.carbs, target: n.carbs, unit: "g" },
670
+ { label: "Fat", value: e.fat, target: n.fat, unit: "g" }
671
+ ].map((r) => /* @__PURE__ */ o("div", { style: h.card, children: [
672
+ /* @__PURE__ */ o("div", { style: { display: "flex", justifyContent: "space-between", marginBottom: "8px" }, children: [
673
+ /* @__PURE__ */ i("span", { style: { fontWeight: 500 }, children: r.label }),
674
+ /* @__PURE__ */ o("span", { children: [
675
+ r.value,
676
+ r.unit,
677
+ " / ",
678
+ r.target,
679
+ r.unit
680
+ ] })
681
+ ] }),
682
+ /* @__PURE__ */ i("div", { style: h.progressBar, children: /* @__PURE__ */ i(
683
+ "div",
684
+ {
685
+ style: {
686
+ width: `${Math.min(100, r.value / r.target * 100)}%`,
687
+ height: "100%",
688
+ backgroundColor: r.value > r.target ? "#f44336" : "#4caf50",
689
+ borderRadius: "4px"
690
+ }
691
+ }
692
+ ) })
693
+ ] }, r.label)) }),
694
+ /* @__PURE__ */ o("div", { style: h.card, children: [
695
+ /* @__PURE__ */ i("div", { style: h.cardTitle, children: "Today's Meals" }),
696
+ t.length === 0 ? /* @__PURE__ */ i("div", { style: { color: "#999", textAlign: "center", padding: "30px" }, children: "No meals logged today" }) : t.map((r) => /* @__PURE__ */ o("div", { style: h.listItem, children: [
697
+ /* @__PURE__ */ i("span", { style: { textTransform: "capitalize", fontWeight: 500, width: "80px" }, children: r.type }),
698
+ /* @__PURE__ */ o("div", { style: { flex: 1 }, children: [
699
+ /* @__PURE__ */ i("div", { children: r.foods.map((s) => s.item.name).join(", ") }),
700
+ /* @__PURE__ */ o("div", { style: { fontSize: "12px", color: "#666" }, children: [
701
+ r.totalCalories,
702
+ " cal • P:",
703
+ r.totalProtein,
704
+ "g C:",
705
+ r.totalCarbs,
706
+ "g F:",
707
+ r.totalFat,
708
+ "g"
709
+ ] })
710
+ ] })
711
+ ] }, r.id))
712
+ ] })
713
+ ] });
714
+ }
715
+ function re({ service: a }) {
716
+ const e = a.getSleepStats(7), t = a.getAllSleepEntries(), n = {
717
+ poor: "#f44336",
718
+ fair: "#ff9800",
719
+ good: "#4caf50",
720
+ excellent: "#2196f3"
721
+ };
722
+ return /* @__PURE__ */ o("div", { children: [
723
+ /* @__PURE__ */ i("h2", { style: { marginBottom: "20px" }, children: "Sleep Tracking" }),
724
+ /* @__PURE__ */ o("div", { style: h.grid, children: [
725
+ /* @__PURE__ */ o("div", { style: h.card, children: [
726
+ /* @__PURE__ */ o("div", { style: h.statValue, children: [
727
+ e.avgDuration.toFixed(1),
728
+ "h"
729
+ ] }),
730
+ /* @__PURE__ */ i("div", { style: h.statLabel, children: "Avg Sleep (7 days)" })
731
+ ] }),
732
+ /* @__PURE__ */ o("div", { style: h.card, children: [
733
+ /* @__PURE__ */ o("div", { style: h.statValue, children: [
734
+ e.avgQuality.toFixed(1),
735
+ "/4"
736
+ ] }),
737
+ /* @__PURE__ */ i("div", { style: h.statLabel, children: "Avg Quality" })
738
+ ] })
739
+ ] }),
740
+ /* @__PURE__ */ o("div", { style: h.card, children: [
741
+ /* @__PURE__ */ i("div", { style: h.cardTitle, children: "Sleep History" }),
742
+ t.length === 0 ? /* @__PURE__ */ i("div", { style: { color: "#999", textAlign: "center", padding: "30px" }, children: "No sleep data logged" }) : t.slice(0, 10).map((r) => /* @__PURE__ */ o("div", { style: h.listItem, children: [
743
+ /* @__PURE__ */ i("span", { style: { width: "100px" }, children: new Date(r.date).toLocaleDateString() }),
744
+ /* @__PURE__ */ o("span", { style: { flex: 1 }, children: [
745
+ r.duration.toFixed(1),
746
+ " hours"
747
+ ] }),
748
+ /* @__PURE__ */ i(
749
+ "span",
750
+ {
751
+ style: {
752
+ padding: "4px 12px",
753
+ borderRadius: "12px",
754
+ fontSize: "12px",
755
+ backgroundColor: n[r.quality] + "20",
756
+ color: n[r.quality],
757
+ textTransform: "capitalize"
758
+ },
759
+ children: r.quality
760
+ }
761
+ )
762
+ ] }, r.id))
763
+ ] })
764
+ ] });
765
+ }
766
+ function ie({ service: a }) {
767
+ const e = a.getAllMedicalRecords(), t = a.getUpcomingFollowUps(), n = {
768
+ appointment: "📅",
769
+ "lab-result": "🧪",
770
+ vaccination: "💉",
771
+ prescription: "📝",
772
+ procedure: "🏥",
773
+ diagnosis: "🩺",
774
+ note: "📋"
775
+ };
776
+ return /* @__PURE__ */ o("div", { children: [
777
+ /* @__PURE__ */ i("h2", { style: { marginBottom: "20px" }, children: "Medical Records" }),
778
+ t.length > 0 && /* @__PURE__ */ o("div", { style: { ...h.card, marginBottom: "20px", backgroundColor: "#fff3e0" }, children: [
779
+ /* @__PURE__ */ i("div", { style: h.cardTitle, children: "Upcoming Follow-ups" }),
780
+ t.map((r) => /* @__PURE__ */ o("div", { style: h.listItem, children: [
781
+ /* @__PURE__ */ i("span", { children: n[r.type] }),
782
+ /* @__PURE__ */ i("span", { style: { flex: 1 }, children: r.title }),
783
+ /* @__PURE__ */ i("span", { style: { color: "#ef6c00" }, children: new Date(r.followUp).toLocaleDateString() })
784
+ ] }, r.id))
785
+ ] }),
786
+ /* @__PURE__ */ o("div", { style: h.card, children: [
787
+ /* @__PURE__ */ i("div", { style: h.cardTitle, children: "All Records" }),
788
+ e.length === 0 ? /* @__PURE__ */ i("div", { style: { color: "#999", textAlign: "center", padding: "30px" }, children: "No medical records" }) : e.slice(0, 15).map((r) => /* @__PURE__ */ o("div", { style: h.listItem, children: [
789
+ /* @__PURE__ */ i("span", { style: { fontSize: "20px" }, children: n[r.type] }),
790
+ /* @__PURE__ */ o("div", { style: { flex: 1 }, children: [
791
+ /* @__PURE__ */ i("div", { style: { fontWeight: 500 }, children: r.title }),
792
+ /* @__PURE__ */ o("div", { style: { fontSize: "12px", color: "#666" }, children: [
793
+ new Date(r.date).toLocaleDateString(),
794
+ r.provider && ` • ${r.provider}`
795
+ ] })
796
+ ] })
797
+ ] }, r.id))
798
+ ] })
799
+ ] });
800
+ }
801
+ function se({
802
+ service: a,
803
+ refresh: e
804
+ }) {
805
+ a.getAllMedications();
806
+ const t = a.getActiveMedications(), n = a.getTodayMedicationSchedule(), r = (s) => {
807
+ const l = /* @__PURE__ */ new Date();
808
+ l.setHours(
809
+ parseInt(s.times[0].split(":")[0]),
810
+ parseInt(s.times[0].split(":")[1]),
811
+ 0
812
+ ), a.logMedication(s.id, l, !0), e();
813
+ };
814
+ return /* @__PURE__ */ o("div", { children: [
815
+ /* @__PURE__ */ i("h2", { style: { marginBottom: "20px" }, children: "Medications" }),
816
+ /* @__PURE__ */ o("div", { style: { ...h.card, marginBottom: "20px" }, children: [
817
+ /* @__PURE__ */ i("div", { style: h.cardTitle, children: "Today's Schedule" }),
818
+ n.length === 0 ? /* @__PURE__ */ i("div", { style: { color: "#999", textAlign: "center", padding: "20px" }, children: "No medications scheduled" }) : n.map((s, l) => /* @__PURE__ */ o("div", { style: h.listItem, children: [
819
+ /* @__PURE__ */ i("span", { style: { width: "60px", fontWeight: 500 }, children: s.time }),
820
+ /* @__PURE__ */ o("div", { style: { flex: 1 }, children: [
821
+ /* @__PURE__ */ i("div", { style: { fontWeight: 500 }, children: s.medication.name }),
822
+ /* @__PURE__ */ i("div", { style: { fontSize: "12px", color: "#666" }, children: s.medication.dosage })
823
+ ] }),
824
+ !s.taken && /* @__PURE__ */ i(
825
+ "button",
826
+ {
827
+ onClick: () => r(s.medication),
828
+ style: {
829
+ padding: "6px 16px",
830
+ border: "none",
831
+ borderRadius: "6px",
832
+ backgroundColor: "#4caf50",
833
+ color: "#fff",
834
+ cursor: "pointer",
835
+ fontSize: "12px"
836
+ },
837
+ children: "Mark Taken"
838
+ }
839
+ ),
840
+ s.taken && /* @__PURE__ */ i("span", { style: { color: "#4caf50", fontSize: "12px" }, children: "✓ Taken" })
841
+ ] }, l))
842
+ ] }),
843
+ /* @__PURE__ */ o("div", { style: h.card, children: [
844
+ /* @__PURE__ */ i("div", { style: h.cardTitle, children: "Active Medications" }),
845
+ t.length === 0 ? /* @__PURE__ */ i("div", { style: { color: "#999", textAlign: "center", padding: "30px" }, children: "No active medications" }) : t.map((s) => /* @__PURE__ */ o("div", { style: h.listItem, children: [
846
+ /* @__PURE__ */ i("span", { style: { fontSize: "24px" }, children: "💊" }),
847
+ /* @__PURE__ */ o("div", { style: { flex: 1 }, children: [
848
+ /* @__PURE__ */ i("div", { style: { fontWeight: 500 }, children: s.name }),
849
+ /* @__PURE__ */ o("div", { style: { fontSize: "12px", color: "#666" }, children: [
850
+ s.dosage,
851
+ " • ",
852
+ s.frequency,
853
+ " • ",
854
+ s.times.join(", ")
855
+ ] })
856
+ ] })
857
+ ] }, s.id))
858
+ ] })
859
+ ] });
860
+ }
861
+ const oe = [
862
+ { id: "income", name: "Income", icon: "💰", color: "#4caf50" },
863
+ { id: "salary", name: "Salary", icon: "💵", color: "#4caf50", parent: "income" },
864
+ { id: "interest", name: "Interest", icon: "🏦", color: "#4caf50", parent: "income" },
865
+ { id: "housing", name: "Housing", icon: "🏠", color: "#2196f3" },
866
+ { id: "rent", name: "Rent", icon: "🏠", color: "#2196f3", parent: "housing" },
867
+ { id: "utilities", name: "Utilities", icon: "💡", color: "#2196f3", parent: "housing" },
868
+ { id: "food", name: "Food & Dining", icon: "🍔", color: "#ff9800" },
869
+ { id: "groceries", name: "Groceries", icon: "🛒", color: "#ff9800", parent: "food" },
870
+ { id: "restaurants", name: "Restaurants", icon: "🍽️", color: "#ff9800", parent: "food" },
871
+ { id: "transport", name: "Transportation", icon: "🚗", color: "#9c27b0" },
872
+ { id: "gas", name: "Gas", icon: "⛽", color: "#9c27b0", parent: "transport" },
873
+ { id: "parking", name: "Parking", icon: "🅿️", color: "#9c27b0", parent: "transport" },
874
+ { id: "shopping", name: "Shopping", icon: "🛍️", color: "#e91e63" },
875
+ { id: "entertainment", name: "Entertainment", icon: "🎬", color: "#673ab7" },
876
+ { id: "health", name: "Health", icon: "🏥", color: "#f44336" },
877
+ { id: "personal", name: "Personal", icon: "👤", color: "#607d8b" },
878
+ { id: "education", name: "Education", icon: "📚", color: "#00bcd4" },
879
+ { id: "travel", name: "Travel", icon: "✈️", color: "#009688" },
880
+ { id: "subscriptions", name: "Subscriptions", icon: "📱", color: "#795548" },
881
+ { id: "transfer", name: "Transfer", icon: "↔️", color: "#9e9e9e" },
882
+ { id: "other", name: "Other", icon: "📦", color: "#9e9e9e" }
883
+ ];
884
+ class ae {
885
+ constructor() {
886
+ w(this, "accounts", /* @__PURE__ */ new Map());
887
+ w(this, "transactions", /* @__PURE__ */ new Map());
888
+ w(this, "budgets", /* @__PURE__ */ new Map());
889
+ w(this, "bills", /* @__PURE__ */ new Map());
890
+ w(this, "investments", /* @__PURE__ */ new Map());
891
+ w(this, "categories", [...oe]);
892
+ w(this, "netWorthHistory", []);
893
+ }
894
+ /* ─────────────────────────────────────────────────────────────
895
+ ACCOUNTS
896
+ ───────────────────────────────────────────────────────────── */
897
+ addAccount(e) {
898
+ const t = this.generateId(), n = { ...e, id: t };
899
+ return this.accounts.set(t, n), n;
900
+ }
901
+ updateAccount(e, t) {
902
+ const n = this.accounts.get(e);
903
+ n && this.accounts.set(e, { ...n, ...t, id: e });
904
+ }
905
+ deleteAccount(e) {
906
+ this.accounts.delete(e);
907
+ for (const [t, n] of this.transactions)
908
+ n.accountId === e && this.transactions.delete(t);
909
+ }
910
+ getAllAccounts() {
911
+ return Array.from(this.accounts.values());
912
+ }
913
+ getAccountsByType(e) {
914
+ return this.getAllAccounts().filter((t) => t.type === e);
915
+ }
916
+ calculateTotalAssets() {
917
+ return this.getAllAccounts().filter((e) => ["checking", "savings", "investment", "cash", "crypto"].includes(e.type)).reduce((e, t) => e + t.balance, 0);
918
+ }
919
+ calculateTotalLiabilities() {
920
+ return this.getAllAccounts().filter((e) => ["credit-card", "loan", "mortgage"].includes(e.type)).reduce((e, t) => e + Math.abs(t.balance), 0);
921
+ }
922
+ calculateNetWorth() {
923
+ return this.calculateTotalAssets() - this.calculateTotalLiabilities();
924
+ }
925
+ recordNetWorthSnapshot() {
926
+ const e = {
927
+ date: /* @__PURE__ */ new Date(),
928
+ assets: this.calculateTotalAssets(),
929
+ liabilities: this.calculateTotalLiabilities(),
930
+ netWorth: this.calculateNetWorth()
931
+ };
932
+ this.netWorthHistory.push(e);
933
+ }
934
+ getNetWorthHistory() {
935
+ return [...this.netWorthHistory];
936
+ }
937
+ /* ─────────────────────────────────────────────────────────────
938
+ TRANSACTIONS
939
+ ───────────────────────────────────────────────────────────── */
940
+ addTransaction(e) {
941
+ const t = this.generateId(), n = { ...e, id: t };
942
+ this.transactions.set(t, n);
943
+ const r = this.accounts.get(e.accountId);
944
+ if (r) {
945
+ const s = e.type === "income" ? e.amount : -e.amount;
946
+ r.balance += s, this.accounts.set(r.id, r);
947
+ }
948
+ if (e.categoryId && e.type === "expense") {
949
+ const s = this.getBudgetByCategory(e.categoryId);
950
+ s && (s.spent += e.amount, this.budgets.set(s.id, s));
951
+ }
952
+ return n;
953
+ }
954
+ updateTransaction(e, t) {
955
+ const n = this.transactions.get(e);
956
+ n && this.transactions.set(e, { ...n, ...t, id: e });
957
+ }
958
+ deleteTransaction(e) {
959
+ const t = this.transactions.get(e);
960
+ if (t) {
961
+ const n = this.accounts.get(t.accountId);
962
+ if (n) {
963
+ const r = t.type === "income" ? -t.amount : t.amount;
964
+ n.balance += r, this.accounts.set(n.id, n);
965
+ }
966
+ this.transactions.delete(e);
967
+ }
968
+ }
969
+ getAllTransactions() {
970
+ return Array.from(this.transactions.values()).sort(
971
+ (e, t) => new Date(t.date).getTime() - new Date(e.date).getTime()
972
+ );
973
+ }
974
+ getTransactionsForAccount(e) {
975
+ return this.getAllTransactions().filter((t) => t.accountId === e);
976
+ }
977
+ getTransactionsForPeriod(e, t) {
978
+ return this.getAllTransactions().filter((n) => {
979
+ const r = new Date(n.date);
980
+ return r >= e && r <= t;
981
+ });
982
+ }
983
+ getTransactionsByCategory(e) {
984
+ return this.getAllTransactions().filter((t) => t.categoryId === e);
985
+ }
986
+ /** Auto-categorize transaction based on description */
987
+ autoCategorize(e) {
988
+ const t = [
989
+ { pattern: /walmart|target|costco|grocery|supermarket/i, categoryId: "groceries" },
990
+ { pattern: /starbucks|mcdonalds|restaurant|cafe|pizza/i, categoryId: "restaurants" },
991
+ { pattern: /shell|exxon|chevron|gas|fuel/i, categoryId: "gas" },
992
+ { pattern: /netflix|spotify|hulu|subscription/i, categoryId: "subscriptions" },
993
+ { pattern: /amazon|ebay|shopping/i, categoryId: "shopping" },
994
+ { pattern: /uber|lyft|taxi|parking/i, categoryId: "transport" },
995
+ { pattern: /rent|mortgage|lease/i, categoryId: "rent" },
996
+ { pattern: /electric|water|internet|phone/i, categoryId: "utilities" },
997
+ { pattern: /doctor|pharmacy|hospital|medical/i, categoryId: "health" },
998
+ { pattern: /payroll|salary|paycheck|deposit/i, categoryId: "salary" }
999
+ ];
1000
+ for (const n of t)
1001
+ if (n.pattern.test(e))
1002
+ return n.categoryId;
1003
+ }
1004
+ /* ─────────────────────────────────────────────────────────────
1005
+ CATEGORIES
1006
+ ───────────────────────────────────────────────────────────── */
1007
+ getAllCategories() {
1008
+ return [...this.categories];
1009
+ }
1010
+ getTopLevelCategories() {
1011
+ return this.categories.filter((e) => !e.parent);
1012
+ }
1013
+ getSubCategories(e) {
1014
+ return this.categories.filter((t) => t.parent === e);
1015
+ }
1016
+ addCategory(e) {
1017
+ this.categories.push(e);
1018
+ }
1019
+ /* ─────────────────────────────────────────────────────────────
1020
+ BUDGETS
1021
+ ───────────────────────────────────────────────────────────── */
1022
+ addBudget(e) {
1023
+ const t = this.generateId(), n = { ...e, id: t, spent: 0 };
1024
+ return this.budgets.set(t, n), n;
1025
+ }
1026
+ updateBudget(e, t) {
1027
+ const n = this.budgets.get(e);
1028
+ n && this.budgets.set(e, { ...n, ...t, id: e });
1029
+ }
1030
+ deleteBudget(e) {
1031
+ this.budgets.delete(e);
1032
+ }
1033
+ getAllBudgets() {
1034
+ return Array.from(this.budgets.values());
1035
+ }
1036
+ getBudgetByCategory(e) {
1037
+ return this.getAllBudgets().find((t) => t.categoryId === e);
1038
+ }
1039
+ resetBudgetSpending() {
1040
+ for (const [e, t] of this.budgets)
1041
+ t.rollover || (t.spent = 0), this.budgets.set(e, t);
1042
+ }
1043
+ calculateBudgetStatus() {
1044
+ const e = this.getAllBudgets(), t = e.reduce((s, l) => s + l.amount, 0), n = e.reduce((s, l) => s + l.spent, 0), r = e.filter((s) => s.spent > s.amount);
1045
+ return { total: t, used: n, remaining: t - n, overBudget: r };
1046
+ }
1047
+ /* ─────────────────────────────────────────────────────────────
1048
+ BILLS
1049
+ ───────────────────────────────────────────────────────────── */
1050
+ addBill(e) {
1051
+ const t = this.generateId(), n = { ...e, id: t };
1052
+ return this.bills.set(t, n), n;
1053
+ }
1054
+ updateBill(e, t) {
1055
+ const n = this.bills.get(e);
1056
+ n && this.bills.set(e, { ...n, ...t, id: e });
1057
+ }
1058
+ deleteBill(e) {
1059
+ this.bills.delete(e);
1060
+ }
1061
+ markBillPaid(e) {
1062
+ const t = this.bills.get(e);
1063
+ t && (t.lastPaid = /* @__PURE__ */ new Date(), this.bills.set(e, t));
1064
+ }
1065
+ getAllBills() {
1066
+ return Array.from(this.bills.values());
1067
+ }
1068
+ getUpcomingBills(e = 30) {
1069
+ const n = (/* @__PURE__ */ new Date()).getDate();
1070
+ return this.getAllBills().filter((r) => {
1071
+ let s = r.dueDate - n;
1072
+ return s < 0 && (s += 30), s <= e;
1073
+ }).sort((r, s) => r.dueDate - s.dueDate);
1074
+ }
1075
+ calculateMonthlyBillTotal() {
1076
+ return this.getAllBills().filter((e) => e.frequency === "monthly").reduce((e, t) => e + t.amount, 0);
1077
+ }
1078
+ /* ─────────────────────────────────────────────────────────────
1079
+ INVESTMENTS
1080
+ ───────────────────────────────────────────────────────────── */
1081
+ addInvestment(e) {
1082
+ const t = this.generateId(), n = e.shares * e.currentPrice, r = n - e.costBasis, s = e.costBasis > 0 ? r / e.costBasis * 100 : 0, l = { ...e, id: t, currentValue: n, gain: r, gainPercent: s };
1083
+ return this.investments.set(t, l), l;
1084
+ }
1085
+ updateInvestmentPrice(e, t) {
1086
+ const n = this.investments.get(e);
1087
+ n && (n.currentPrice = t, n.currentValue = n.shares * t, n.gain = n.currentValue - n.costBasis, n.gainPercent = n.costBasis > 0 ? n.gain / n.costBasis * 100 : 0, this.investments.set(e, n));
1088
+ }
1089
+ deleteInvestment(e) {
1090
+ this.investments.delete(e);
1091
+ }
1092
+ getAllInvestments() {
1093
+ return Array.from(this.investments.values());
1094
+ }
1095
+ getInvestmentsByAccount(e) {
1096
+ return this.getAllInvestments().filter((t) => t.accountId === e);
1097
+ }
1098
+ calculateTotalInvestmentValue() {
1099
+ return this.getAllInvestments().reduce((e, t) => e + t.currentValue, 0);
1100
+ }
1101
+ calculateTotalGain() {
1102
+ return this.getAllInvestments().reduce((e, t) => e + t.gain, 0);
1103
+ }
1104
+ getPortfolioAllocation() {
1105
+ const e = this.getAllInvestments(), t = this.calculateTotalInvestmentValue(), n = /* @__PURE__ */ new Map();
1106
+ for (const r of e)
1107
+ n.set(r.type, (n.get(r.type) || 0) + r.currentValue);
1108
+ return Array.from(n.entries()).map(([r, s]) => ({
1109
+ type: r,
1110
+ value: s,
1111
+ percentage: t > 0 ? s / t * 100 : 0
1112
+ }));
1113
+ }
1114
+ /* ─────────────────────────────────────────────────────────────
1115
+ ANALYTICS
1116
+ ───────────────────────────────────────────────────────────── */
1117
+ getSpendingSummary(e, t) {
1118
+ const n = this.getTransactionsForPeriod(e, t).filter(
1119
+ (l) => l.type === "expense"
1120
+ ), r = /* @__PURE__ */ new Map();
1121
+ let s = 0;
1122
+ for (const l of n) {
1123
+ const d = l.categoryId || "other", c = r.get(d) || { amount: 0, count: 0 };
1124
+ c.amount += l.amount, c.count++, r.set(d, c), s += l.amount;
1125
+ }
1126
+ return Array.from(r.entries()).map(([l, d]) => {
1127
+ const c = this.categories.find((g) => g.id === l);
1128
+ return {
1129
+ categoryId: l,
1130
+ categoryName: (c == null ? void 0 : c.name) || "Other",
1131
+ amount: d.amount,
1132
+ percentage: s > 0 ? d.amount / s * 100 : 0,
1133
+ transactions: d.count,
1134
+ trend: "stable"
1135
+ // Would compare with previous period
1136
+ };
1137
+ }).sort((l, d) => d.amount - l.amount);
1138
+ }
1139
+ getMonthlyIncome() {
1140
+ const e = /* @__PURE__ */ new Date(), t = new Date(e.getFullYear(), e.getMonth(), 1);
1141
+ return this.getTransactionsForPeriod(t, e).filter((r) => r.type === "income").reduce((r, s) => r + s.amount, 0);
1142
+ }
1143
+ getMonthlyExpenses() {
1144
+ const e = /* @__PURE__ */ new Date(), t = new Date(e.getFullYear(), e.getMonth(), 1);
1145
+ return this.getTransactionsForPeriod(t, e).filter((r) => r.type === "expense").reduce((r, s) => r + s.amount, 0);
1146
+ }
1147
+ getSavingsRate() {
1148
+ const e = this.getMonthlyIncome(), t = this.getMonthlyExpenses();
1149
+ return e === 0 ? 0 : (e - t) / e * 100;
1150
+ }
1151
+ /* ─────────────────────────────────────────────────────────────
1152
+ UTILITIES
1153
+ ───────────────────────────────────────────────────────────── */
1154
+ generateId() {
1155
+ return Date.now().toString(36) + Math.random().toString(36).substring(2, 8);
1156
+ }
1157
+ clear() {
1158
+ this.accounts.clear(), this.transactions.clear(), this.budgets.clear(), this.bills.clear(), this.investments.clear(), this.netWorthHistory = [];
1159
+ }
1160
+ /**
1161
+ * Export all data to JSON
1162
+ */
1163
+ exportData() {
1164
+ return JSON.stringify(
1165
+ {
1166
+ accounts: this.getAllAccounts(),
1167
+ transactions: this.getAllTransactions(),
1168
+ budgets: this.getAllBudgets(),
1169
+ bills: this.getAllBills(),
1170
+ investments: this.getAllInvestments(),
1171
+ categories: this.categories,
1172
+ netWorthHistory: this.netWorthHistory
1173
+ },
1174
+ null,
1175
+ 2
1176
+ );
1177
+ }
1178
+ }
1179
+ function Ne() {
1180
+ return new ae();
1181
+ }
1182
+ const $ = F(null);
1183
+ function $e() {
1184
+ const a = W($);
1185
+ if (!a)
1186
+ throw new Error("usePersonalFinance must be used within PersonalFinanceProvider");
1187
+ return a;
1188
+ }
1189
+ const m = {
1190
+ container: {
1191
+ display: "flex",
1192
+ height: "100%",
1193
+ fontFamily: "'Inter', sans-serif",
1194
+ backgroundColor: "#f5f7fa"
1195
+ },
1196
+ sidebar: {
1197
+ width: "250px",
1198
+ backgroundColor: "#1a1a2e",
1199
+ color: "#fff",
1200
+ padding: "20px"
1201
+ },
1202
+ main: {
1203
+ flex: 1,
1204
+ padding: "20px",
1205
+ overflow: "auto"
1206
+ },
1207
+ netWorth: {
1208
+ textAlign: "center",
1209
+ padding: "20px 0",
1210
+ borderBottom: "1px solid rgba(255,255,255,0.1)",
1211
+ marginBottom: "20px"
1212
+ },
1213
+ netWorthLabel: {
1214
+ fontSize: "12px",
1215
+ color: "rgba(255,255,255,0.6)",
1216
+ textTransform: "uppercase",
1217
+ letterSpacing: "1px"
1218
+ },
1219
+ netWorthValue: {
1220
+ fontSize: "28px",
1221
+ fontWeight: 700,
1222
+ marginTop: "8px"
1223
+ },
1224
+ accountList: {
1225
+ marginTop: "20px"
1226
+ },
1227
+ accountItem: {
1228
+ display: "flex",
1229
+ justifyContent: "space-between",
1230
+ padding: "12px",
1231
+ borderRadius: "8px",
1232
+ marginBottom: "8px",
1233
+ backgroundColor: "rgba(255,255,255,0.05)",
1234
+ cursor: "pointer"
1235
+ },
1236
+ grid: {
1237
+ display: "grid",
1238
+ gridTemplateColumns: "repeat(auto-fit, minmax(300px, 1fr))",
1239
+ gap: "20px",
1240
+ marginBottom: "20px"
1241
+ },
1242
+ card: {
1243
+ backgroundColor: "#fff",
1244
+ borderRadius: "12px",
1245
+ padding: "20px",
1246
+ boxShadow: "0 2px 8px rgba(0,0,0,0.08)"
1247
+ },
1248
+ cardTitle: {
1249
+ fontSize: "16px",
1250
+ fontWeight: 600,
1251
+ marginBottom: "16px",
1252
+ color: "#1a1a2e"
1253
+ },
1254
+ transactionRow: {
1255
+ display: "flex",
1256
+ justifyContent: "space-between",
1257
+ alignItems: "center",
1258
+ padding: "12px 0",
1259
+ borderBottom: "1px solid #f0f0f0"
1260
+ },
1261
+ progressBar: {
1262
+ height: "8px",
1263
+ backgroundColor: "#e0e0e0",
1264
+ borderRadius: "4px",
1265
+ overflow: "hidden",
1266
+ marginTop: "8px"
1267
+ }
1268
+ };
1269
+ function Ee({
1270
+ service: a,
1271
+ className: e,
1272
+ style: t
1273
+ }) {
1274
+ const [, n] = S(0), [r, s] = S("overview"), l = L(() => n((p) => p + 1), []), d = { service: a, refresh: l }, c = (p) => new Intl.NumberFormat("en-US", { style: "currency", currency: "USD" }).format(p), g = a.getAllAccounts(), u = a.calculateNetWorth();
1275
+ return /* @__PURE__ */ i($.Provider, { value: d, children: /* @__PURE__ */ o("div", { className: e, style: { ...m.container, ...t }, children: [
1276
+ /* @__PURE__ */ o("div", { style: m.sidebar, children: [
1277
+ /* @__PURE__ */ o("div", { style: m.netWorth, children: [
1278
+ /* @__PURE__ */ i("div", { style: m.netWorthLabel, children: "Net Worth" }),
1279
+ /* @__PURE__ */ i("div", { style: { ...m.netWorthValue, color: u >= 0 ? "#4caf50" : "#f44336" }, children: c(u) })
1280
+ ] }),
1281
+ /* @__PURE__ */ i("div", { children: [
1282
+ "overview",
1283
+ "accounts",
1284
+ "transactions",
1285
+ "budgets",
1286
+ "bills",
1287
+ "investments"
1288
+ ].map((p) => /* @__PURE__ */ i(
1289
+ "div",
1290
+ {
1291
+ onClick: () => s(p),
1292
+ style: {
1293
+ padding: "12px 16px",
1294
+ borderRadius: "8px",
1295
+ cursor: "pointer",
1296
+ marginBottom: "4px",
1297
+ backgroundColor: r === p ? "rgba(255,255,255,0.1)" : "transparent",
1298
+ textTransform: "capitalize"
1299
+ },
1300
+ children: p
1301
+ },
1302
+ p
1303
+ )) }),
1304
+ /* @__PURE__ */ o("div", { style: m.accountList, children: [
1305
+ /* @__PURE__ */ i(
1306
+ "div",
1307
+ {
1308
+ style: {
1309
+ fontSize: "12px",
1310
+ color: "rgba(255,255,255,0.6)",
1311
+ marginBottom: "12px",
1312
+ textTransform: "uppercase"
1313
+ },
1314
+ children: "Accounts"
1315
+ }
1316
+ ),
1317
+ g.slice(0, 5).map((p) => /* @__PURE__ */ o("div", { style: m.accountItem, children: [
1318
+ /* @__PURE__ */ i("span", { children: p.name }),
1319
+ /* @__PURE__ */ i("span", { style: { color: p.balance >= 0 ? "#4caf50" : "#f44336" }, children: c(p.balance) })
1320
+ ] }, p.id))
1321
+ ] })
1322
+ ] }),
1323
+ /* @__PURE__ */ o("div", { style: m.main, children: [
1324
+ r === "overview" && /* @__PURE__ */ i(le, { service: a }),
1325
+ r === "accounts" && /* @__PURE__ */ i(de, { service: a, refresh: l }),
1326
+ r === "transactions" && /* @__PURE__ */ i(ce, { service: a }),
1327
+ r === "budgets" && /* @__PURE__ */ i(ue, { service: a }),
1328
+ r === "bills" && /* @__PURE__ */ i(ge, { service: a }),
1329
+ r === "investments" && /* @__PURE__ */ i(he, { service: a })
1330
+ ] })
1331
+ ] }) });
1332
+ }
1333
+ function le({ service: a }) {
1334
+ const e = (g) => new Intl.NumberFormat("en-US", { style: "currency", currency: "USD" }).format(g), t = a.getMonthlyIncome(), n = a.getMonthlyExpenses(), r = a.getSavingsRate(), s = a.calculateBudgetStatus(), l = a.getUpcomingBills(14), d = /* @__PURE__ */ new Date(), c = a.getSpendingSummary(new Date(d.getFullYear(), d.getMonth(), 1), d);
1335
+ return /* @__PURE__ */ o("div", { children: [
1336
+ /* @__PURE__ */ i("h2", { style: { marginBottom: "20px" }, children: "Financial Overview" }),
1337
+ /* @__PURE__ */ o("div", { style: m.grid, children: [
1338
+ /* @__PURE__ */ o("div", { style: m.card, children: [
1339
+ /* @__PURE__ */ i("div", { style: m.cardTitle, children: "This Month" }),
1340
+ /* @__PURE__ */ o("div", { style: { display: "flex", justifyContent: "space-between", marginBottom: "12px" }, children: [
1341
+ /* @__PURE__ */ i("span", { children: "Income" }),
1342
+ /* @__PURE__ */ i("span", { style: { color: "#4caf50", fontWeight: 600 }, children: e(t) })
1343
+ ] }),
1344
+ /* @__PURE__ */ o("div", { style: { display: "flex", justifyContent: "space-between", marginBottom: "12px" }, children: [
1345
+ /* @__PURE__ */ i("span", { children: "Expenses" }),
1346
+ /* @__PURE__ */ i("span", { style: { color: "#f44336", fontWeight: 600 }, children: e(n) })
1347
+ ] }),
1348
+ /* @__PURE__ */ o(
1349
+ "div",
1350
+ {
1351
+ style: {
1352
+ display: "flex",
1353
+ justifyContent: "space-between",
1354
+ borderTop: "1px solid #f0f0f0",
1355
+ paddingTop: "12px"
1356
+ },
1357
+ children: [
1358
+ /* @__PURE__ */ i("span", { children: "Savings Rate" }),
1359
+ /* @__PURE__ */ o("span", { style: { fontWeight: 600 }, children: [
1360
+ r.toFixed(1),
1361
+ "%"
1362
+ ] })
1363
+ ]
1364
+ }
1365
+ )
1366
+ ] }),
1367
+ /* @__PURE__ */ o("div", { style: m.card, children: [
1368
+ /* @__PURE__ */ i("div", { style: m.cardTitle, children: "Budget Status" }),
1369
+ /* @__PURE__ */ o("div", { style: { display: "flex", justifyContent: "space-between", marginBottom: "8px" }, children: [
1370
+ /* @__PURE__ */ i("span", { children: "Used" }),
1371
+ /* @__PURE__ */ o("span", { children: [
1372
+ e(s.used),
1373
+ " / ",
1374
+ e(s.total)
1375
+ ] })
1376
+ ] }),
1377
+ /* @__PURE__ */ i("div", { style: m.progressBar, children: /* @__PURE__ */ i(
1378
+ "div",
1379
+ {
1380
+ style: {
1381
+ width: `${Math.min(100, s.used / s.total * 100)}%`,
1382
+ height: "100%",
1383
+ backgroundColor: s.used > s.total ? "#f44336" : "#4caf50",
1384
+ borderRadius: "4px"
1385
+ }
1386
+ }
1387
+ ) }),
1388
+ s.overBudget.length > 0 && /* @__PURE__ */ o("div", { style: { color: "#f44336", fontSize: "12px", marginTop: "8px" }, children: [
1389
+ s.overBudget.length,
1390
+ " categories over budget"
1391
+ ] })
1392
+ ] }),
1393
+ /* @__PURE__ */ o("div", { style: m.card, children: [
1394
+ /* @__PURE__ */ i("div", { style: m.cardTitle, children: "Upcoming Bills (14 days)" }),
1395
+ l.length === 0 ? /* @__PURE__ */ i("div", { style: { color: "#999", textAlign: "center", padding: "20px" }, children: "No upcoming bills" }) : l.slice(0, 4).map((g) => /* @__PURE__ */ o(
1396
+ "div",
1397
+ {
1398
+ style: {
1399
+ display: "flex",
1400
+ justifyContent: "space-between",
1401
+ padding: "8px 0",
1402
+ borderBottom: "1px solid #f0f0f0"
1403
+ },
1404
+ children: [
1405
+ /* @__PURE__ */ o("div", { children: [
1406
+ /* @__PURE__ */ i("div", { style: { fontWeight: 500 }, children: g.name }),
1407
+ /* @__PURE__ */ o("div", { style: { fontSize: "12px", color: "#666" }, children: [
1408
+ "Due: ",
1409
+ g.dueDate,
1410
+ "th"
1411
+ ] })
1412
+ ] }),
1413
+ /* @__PURE__ */ i("span", { style: { fontWeight: 600 }, children: e(g.amount) })
1414
+ ]
1415
+ },
1416
+ g.id
1417
+ ))
1418
+ ] }),
1419
+ /* @__PURE__ */ o("div", { style: m.card, children: [
1420
+ /* @__PURE__ */ i("div", { style: m.cardTitle, children: "Spending by Category" }),
1421
+ c.slice(0, 5).map((g) => /* @__PURE__ */ o("div", { style: { marginBottom: "12px" }, children: [
1422
+ /* @__PURE__ */ o(
1423
+ "div",
1424
+ {
1425
+ style: { display: "flex", justifyContent: "space-between", marginBottom: "4px" },
1426
+ children: [
1427
+ /* @__PURE__ */ i("span", { children: g.categoryName }),
1428
+ /* @__PURE__ */ o("span", { children: [
1429
+ e(g.amount),
1430
+ " (",
1431
+ g.percentage.toFixed(0),
1432
+ "%)"
1433
+ ] })
1434
+ ]
1435
+ }
1436
+ ),
1437
+ /* @__PURE__ */ i("div", { style: m.progressBar, children: /* @__PURE__ */ i(
1438
+ "div",
1439
+ {
1440
+ style: {
1441
+ width: `${g.percentage}%`,
1442
+ height: "100%",
1443
+ backgroundColor: "#1976d2",
1444
+ borderRadius: "4px"
1445
+ }
1446
+ }
1447
+ ) })
1448
+ ] }, g.categoryId))
1449
+ ] })
1450
+ ] })
1451
+ ] });
1452
+ }
1453
+ function de({
1454
+ service: a,
1455
+ refresh: e
1456
+ }) {
1457
+ const t = (l) => new Intl.NumberFormat("en-US", { style: "currency", currency: "USD" }).format(l);
1458
+ a.getAllAccounts();
1459
+ const n = a.calculateTotalAssets(), r = a.calculateTotalLiabilities(), s = [
1460
+ "checking",
1461
+ "savings",
1462
+ "credit-card",
1463
+ "investment",
1464
+ "loan",
1465
+ "cash"
1466
+ ];
1467
+ return /* @__PURE__ */ o("div", { children: [
1468
+ /* @__PURE__ */ i("h2", { style: { marginBottom: "20px" }, children: "Accounts" }),
1469
+ /* @__PURE__ */ o("div", { style: m.grid, children: [
1470
+ /* @__PURE__ */ o("div", { style: m.card, children: [
1471
+ /* @__PURE__ */ i("div", { style: m.cardTitle, children: "Assets" }),
1472
+ /* @__PURE__ */ i("div", { style: { fontSize: "24px", fontWeight: 600, color: "#4caf50" }, children: t(n) })
1473
+ ] }),
1474
+ /* @__PURE__ */ o("div", { style: m.card, children: [
1475
+ /* @__PURE__ */ i("div", { style: m.cardTitle, children: "Liabilities" }),
1476
+ /* @__PURE__ */ i("div", { style: { fontSize: "24px", fontWeight: 600, color: "#f44336" }, children: t(r) })
1477
+ ] })
1478
+ ] }),
1479
+ s.map((l) => {
1480
+ const d = a.getAccountsByType(l);
1481
+ return d.length === 0 ? null : /* @__PURE__ */ o("div", { style: { ...m.card, marginBottom: "20px" }, children: [
1482
+ /* @__PURE__ */ i("div", { style: m.cardTitle, children: l.replace("-", " ").replace(/\b\w/g, (c) => c.toUpperCase()) }),
1483
+ d.map((c) => /* @__PURE__ */ o("div", { style: m.transactionRow, children: [
1484
+ /* @__PURE__ */ o("div", { children: [
1485
+ /* @__PURE__ */ i("div", { style: { fontWeight: 500 }, children: c.name }),
1486
+ /* @__PURE__ */ i("div", { style: { fontSize: "12px", color: "#666" }, children: c.institution })
1487
+ ] }),
1488
+ /* @__PURE__ */ i("span", { style: { fontWeight: 600, color: c.balance >= 0 ? "#333" : "#f44336" }, children: t(c.balance) })
1489
+ ] }, c.id))
1490
+ ] }, l);
1491
+ })
1492
+ ] });
1493
+ }
1494
+ function ce({ service: a }) {
1495
+ const e = (s) => new Intl.NumberFormat("en-US", { style: "currency", currency: "USD" }).format(s), t = a.getAllTransactions(), n = a.getAllCategories(), r = (s) => {
1496
+ var l;
1497
+ return ((l = n.find((d) => d.id === s)) == null ? void 0 : l.name) || "Uncategorized";
1498
+ };
1499
+ return /* @__PURE__ */ o("div", { children: [
1500
+ /* @__PURE__ */ i("h2", { style: { marginBottom: "20px" }, children: "Transactions" }),
1501
+ /* @__PURE__ */ i("div", { style: m.card, children: t.length === 0 ? /* @__PURE__ */ i("div", { style: { color: "#999", textAlign: "center", padding: "40px" }, children: "No transactions" }) : t.slice(0, 20).map((s) => /* @__PURE__ */ o("div", { style: m.transactionRow, children: [
1502
+ /* @__PURE__ */ o("div", { children: [
1503
+ /* @__PURE__ */ i("div", { style: { fontWeight: 500 }, children: s.description }),
1504
+ /* @__PURE__ */ o("div", { style: { fontSize: "12px", color: "#666" }, children: [
1505
+ new Date(s.date).toLocaleDateString(),
1506
+ " • ",
1507
+ r(s.categoryId)
1508
+ ] })
1509
+ ] }),
1510
+ /* @__PURE__ */ o(
1511
+ "span",
1512
+ {
1513
+ style: { fontWeight: 600, color: s.type === "income" ? "#4caf50" : "#f44336" },
1514
+ children: [
1515
+ s.type === "income" ? "+" : "-",
1516
+ e(s.amount)
1517
+ ]
1518
+ }
1519
+ )
1520
+ ] }, s.id)) })
1521
+ ] });
1522
+ }
1523
+ function ue({ service: a }) {
1524
+ const e = (s) => new Intl.NumberFormat("en-US", { style: "currency", currency: "USD" }).format(s), t = a.getAllBudgets(), n = a.getAllCategories(), r = (s) => {
1525
+ var l;
1526
+ return ((l = n.find((d) => d.id === s)) == null ? void 0 : l.name) || "Unknown";
1527
+ };
1528
+ return /* @__PURE__ */ o("div", { children: [
1529
+ /* @__PURE__ */ i("h2", { style: { marginBottom: "20px" }, children: "Budgets" }),
1530
+ /* @__PURE__ */ i("div", { style: m.card, children: t.length === 0 ? /* @__PURE__ */ i("div", { style: { color: "#999", textAlign: "center", padding: "40px" }, children: "No budgets set" }) : t.map((s) => {
1531
+ const l = s.spent / s.amount * 100, d = s.spent > s.amount;
1532
+ return /* @__PURE__ */ o(
1533
+ "div",
1534
+ {
1535
+ style: {
1536
+ marginBottom: "20px",
1537
+ paddingBottom: "20px",
1538
+ borderBottom: "1px solid #f0f0f0"
1539
+ },
1540
+ children: [
1541
+ /* @__PURE__ */ o(
1542
+ "div",
1543
+ {
1544
+ style: { display: "flex", justifyContent: "space-between", marginBottom: "8px" },
1545
+ children: [
1546
+ /* @__PURE__ */ i("span", { style: { fontWeight: 500 }, children: r(s.categoryId) }),
1547
+ /* @__PURE__ */ o("span", { children: [
1548
+ e(s.spent),
1549
+ " / ",
1550
+ e(s.amount)
1551
+ ] })
1552
+ ]
1553
+ }
1554
+ ),
1555
+ /* @__PURE__ */ i("div", { style: m.progressBar, children: /* @__PURE__ */ i(
1556
+ "div",
1557
+ {
1558
+ style: {
1559
+ width: `${Math.min(100, l)}%`,
1560
+ height: "100%",
1561
+ backgroundColor: d ? "#f44336" : l > 80 ? "#ff9800" : "#4caf50",
1562
+ borderRadius: "4px"
1563
+ }
1564
+ }
1565
+ ) }),
1566
+ /* @__PURE__ */ i(
1567
+ "div",
1568
+ {
1569
+ style: { fontSize: "12px", color: d ? "#f44336" : "#666", marginTop: "4px" },
1570
+ children: d ? `Over by ${e(s.spent - s.amount)}` : `${e(s.amount - s.spent)} remaining`
1571
+ }
1572
+ )
1573
+ ]
1574
+ },
1575
+ s.id
1576
+ );
1577
+ }) })
1578
+ ] });
1579
+ }
1580
+ function ge({ service: a }) {
1581
+ const e = (r) => new Intl.NumberFormat("en-US", { style: "currency", currency: "USD" }).format(r), t = a.getAllBills(), n = a.calculateMonthlyBillTotal();
1582
+ return /* @__PURE__ */ o("div", { children: [
1583
+ /* @__PURE__ */ i("h2", { style: { marginBottom: "20px" }, children: "Bills & Subscriptions" }),
1584
+ /* @__PURE__ */ o("div", { style: { ...m.card, marginBottom: "20px" }, children: [
1585
+ /* @__PURE__ */ i("div", { style: m.cardTitle, children: "Monthly Bills Total" }),
1586
+ /* @__PURE__ */ i("div", { style: { fontSize: "24px", fontWeight: 600 }, children: e(n) })
1587
+ ] }),
1588
+ /* @__PURE__ */ i("div", { style: m.card, children: t.length === 0 ? /* @__PURE__ */ i("div", { style: { color: "#999", textAlign: "center", padding: "40px" }, children: "No bills tracked" }) : t.map((r) => /* @__PURE__ */ o("div", { style: m.transactionRow, children: [
1589
+ /* @__PURE__ */ o("div", { children: [
1590
+ /* @__PURE__ */ i("div", { style: { fontWeight: 500 }, children: r.name }),
1591
+ /* @__PURE__ */ o("div", { style: { fontSize: "12px", color: "#666" }, children: [
1592
+ "Due: ",
1593
+ r.dueDate,
1594
+ "th • ",
1595
+ r.frequency,
1596
+ r.autoPay && " • Auto-pay"
1597
+ ] })
1598
+ ] }),
1599
+ /* @__PURE__ */ i("span", { style: { fontWeight: 600 }, children: e(r.amount) })
1600
+ ] }, r.id)) })
1601
+ ] });
1602
+ }
1603
+ function he({ service: a }) {
1604
+ const e = (l) => new Intl.NumberFormat("en-US", { style: "currency", currency: "USD" }).format(l), t = a.getAllInvestments(), n = a.calculateTotalInvestmentValue(), r = a.calculateTotalGain(), s = a.getPortfolioAllocation();
1605
+ return /* @__PURE__ */ o("div", { children: [
1606
+ /* @__PURE__ */ i("h2", { style: { marginBottom: "20px" }, children: "Investments" }),
1607
+ /* @__PURE__ */ o("div", { style: m.grid, children: [
1608
+ /* @__PURE__ */ o("div", { style: m.card, children: [
1609
+ /* @__PURE__ */ i("div", { style: m.cardTitle, children: "Portfolio Value" }),
1610
+ /* @__PURE__ */ i("div", { style: { fontSize: "24px", fontWeight: 600 }, children: e(n) })
1611
+ ] }),
1612
+ /* @__PURE__ */ o("div", { style: m.card, children: [
1613
+ /* @__PURE__ */ i("div", { style: m.cardTitle, children: "Total Gain/Loss" }),
1614
+ /* @__PURE__ */ o(
1615
+ "div",
1616
+ {
1617
+ style: {
1618
+ fontSize: "24px",
1619
+ fontWeight: 600,
1620
+ color: r >= 0 ? "#4caf50" : "#f44336"
1621
+ },
1622
+ children: [
1623
+ r >= 0 ? "+" : "",
1624
+ e(r)
1625
+ ]
1626
+ }
1627
+ )
1628
+ ] })
1629
+ ] }),
1630
+ /* @__PURE__ */ o("div", { style: { ...m.card, marginBottom: "20px" }, children: [
1631
+ /* @__PURE__ */ i("div", { style: m.cardTitle, children: "Asset Allocation" }),
1632
+ s.map((l) => /* @__PURE__ */ o("div", { style: { marginBottom: "12px" }, children: [
1633
+ /* @__PURE__ */ o("div", { style: { display: "flex", justifyContent: "space-between", marginBottom: "4px" }, children: [
1634
+ /* @__PURE__ */ i("span", { style: { textTransform: "capitalize" }, children: l.type }),
1635
+ /* @__PURE__ */ o("span", { children: [
1636
+ l.percentage.toFixed(1),
1637
+ "%"
1638
+ ] })
1639
+ ] }),
1640
+ /* @__PURE__ */ i("div", { style: m.progressBar, children: /* @__PURE__ */ i(
1641
+ "div",
1642
+ {
1643
+ style: {
1644
+ width: `${l.percentage}%`,
1645
+ height: "100%",
1646
+ backgroundColor: "#1976d2",
1647
+ borderRadius: "4px"
1648
+ }
1649
+ }
1650
+ ) })
1651
+ ] }, l.type))
1652
+ ] }),
1653
+ /* @__PURE__ */ o("div", { style: m.card, children: [
1654
+ /* @__PURE__ */ i("div", { style: m.cardTitle, children: "Holdings" }),
1655
+ t.length === 0 ? /* @__PURE__ */ i("div", { style: { color: "#999", textAlign: "center", padding: "40px" }, children: "No investments tracked" }) : t.map((l) => /* @__PURE__ */ o("div", { style: m.transactionRow, children: [
1656
+ /* @__PURE__ */ o("div", { children: [
1657
+ /* @__PURE__ */ i("div", { style: { fontWeight: 500 }, children: l.symbol }),
1658
+ /* @__PURE__ */ o("div", { style: { fontSize: "12px", color: "#666" }, children: [
1659
+ l.shares,
1660
+ " shares @ ",
1661
+ e(l.currentPrice)
1662
+ ] })
1663
+ ] }),
1664
+ /* @__PURE__ */ o("div", { style: { textAlign: "right" }, children: [
1665
+ /* @__PURE__ */ i("div", { style: { fontWeight: 600 }, children: e(l.currentValue) }),
1666
+ /* @__PURE__ */ o("div", { style: { fontSize: "12px", color: l.gain >= 0 ? "#4caf50" : "#f44336" }, children: [
1667
+ l.gain >= 0 ? "+" : "",
1668
+ e(l.gain),
1669
+ " (",
1670
+ l.gainPercent.toFixed(1),
1671
+ "%)"
1672
+ ] })
1673
+ ] })
1674
+ ] }, l.id))
1675
+ ] })
1676
+ ] });
1677
+ }
1678
+ const j = {
1679
+ urgent: 0,
1680
+ high: 1,
1681
+ medium: 2,
1682
+ low: 3,
1683
+ none: 4
1684
+ };
1685
+ class pe {
1686
+ constructor() {
1687
+ w(this, "tasks", /* @__PURE__ */ new Map());
1688
+ w(this, "projects", /* @__PURE__ */ new Map());
1689
+ w(this, "tags", /* @__PURE__ */ new Map());
1690
+ w(this, "timeBlocks", /* @__PURE__ */ new Map());
1691
+ }
1692
+ /* ─────────────────────────────────────────────────────────────
1693
+ TASKS
1694
+ ───────────────────────────────────────────────────────────── */
1695
+ addTask(e) {
1696
+ const t = this.generateId(), n = /* @__PURE__ */ new Date(), r = {
1697
+ ...e,
1698
+ id: t,
1699
+ subtasks: [],
1700
+ createdAt: n,
1701
+ updatedAt: n
1702
+ };
1703
+ return this.tasks.set(t, r), r;
1704
+ }
1705
+ updateTask(e, t) {
1706
+ const n = this.tasks.get(e);
1707
+ n && this.tasks.set(e, { ...n, ...t, id: e, updatedAt: /* @__PURE__ */ new Date() });
1708
+ }
1709
+ deleteTask(e) {
1710
+ const t = this.tasks.get(e);
1711
+ if (t) {
1712
+ for (const n of t.subtasks)
1713
+ this.deleteTask(n.id);
1714
+ for (const n of t.timeBlocks)
1715
+ this.timeBlocks.delete(n.id);
1716
+ this.tasks.delete(e);
1717
+ }
1718
+ }
1719
+ getTask(e) {
1720
+ return this.tasks.get(e);
1721
+ }
1722
+ getAllTasks() {
1723
+ return Array.from(this.tasks.values());
1724
+ }
1725
+ /** Quick add task from text with natural language parsing */
1726
+ quickAddTask(e) {
1727
+ const t = this.parseQuickAdd(e);
1728
+ return this.addTask({
1729
+ title: t.title,
1730
+ status: "inbox",
1731
+ priority: t.priority,
1732
+ projectId: t.projectId,
1733
+ tags: t.tags,
1734
+ dueDate: t.dueDate,
1735
+ timeBlocks: [],
1736
+ notes: "",
1737
+ attachments: []
1738
+ });
1739
+ }
1740
+ parseQuickAdd(e) {
1741
+ let t = e, n = "none", r;
1742
+ const s = [];
1743
+ let l;
1744
+ e.includes("!!!") ? (n = "urgent", t = t.replace("!!!", "")) : e.includes("!!") ? (n = "high", t = t.replace("!!", "")) : e.includes("!") && (n = "medium", t = t.replace("!", ""));
1745
+ const d = e.match(/#(\w+)/);
1746
+ if (d) {
1747
+ const u = Array.from(this.projects.values()).find(
1748
+ (p) => p.name.toLowerCase() === d[1].toLowerCase()
1749
+ );
1750
+ u && (r = u.id, t = t.replace(d[0], ""));
1751
+ }
1752
+ const c = e.matchAll(/@(\w+)/g);
1753
+ for (const u of c) {
1754
+ const p = Array.from(this.tags.values()).find(
1755
+ (y) => y.name.toLowerCase() === u[1].toLowerCase()
1756
+ );
1757
+ p && (s.push(p.id), t = t.replace(u[0], ""));
1758
+ }
1759
+ const g = [
1760
+ { pattern: /\btoday\b/i, offset: () => /* @__PURE__ */ new Date() },
1761
+ { pattern: /\btomorrow\b/i, offset: () => new Date(Date.now() + 864e5) },
1762
+ { pattern: /\bnext week\b/i, offset: () => new Date(Date.now() + 7 * 864e5) },
1763
+ {
1764
+ pattern: /\bnext month\b/i,
1765
+ offset: () => {
1766
+ const u = /* @__PURE__ */ new Date();
1767
+ return u.setMonth(u.getMonth() + 1), u;
1768
+ }
1769
+ }
1770
+ ];
1771
+ for (const { pattern: u, offset: p } of g)
1772
+ if (u.test(e)) {
1773
+ l = p(), l.setHours(23, 59, 59, 999), t = t.replace(u, "");
1774
+ break;
1775
+ }
1776
+ return {
1777
+ title: t.trim(),
1778
+ priority: n,
1779
+ projectId: r,
1780
+ tags: s,
1781
+ dueDate: l
1782
+ };
1783
+ }
1784
+ /** Complete a task */
1785
+ completeTask(e) {
1786
+ const t = this.tasks.get(e);
1787
+ t && (t.status = "done", t.completedDate = /* @__PURE__ */ new Date(), t.updatedAt = /* @__PURE__ */ new Date(), t.recurrence && this.createRecurringTask(t), this.tasks.set(e, t));
1788
+ }
1789
+ createRecurringTask(e) {
1790
+ const t = this.calculateNextRecurrence(e);
1791
+ t && this.addTask({
1792
+ title: e.title,
1793
+ description: e.description,
1794
+ status: "todo",
1795
+ priority: e.priority,
1796
+ projectId: e.projectId,
1797
+ tags: e.tags,
1798
+ dueDate: t,
1799
+ recurrence: e.recurrence,
1800
+ timeBlocks: [],
1801
+ notes: "",
1802
+ attachments: []
1803
+ });
1804
+ }
1805
+ calculateNextRecurrence(e) {
1806
+ if (!e.recurrence || !e.dueDate)
1807
+ return null;
1808
+ const { pattern: t, interval: n, endDate: r, endAfterOccurrences: s } = e.recurrence, l = new Date(e.dueDate);
1809
+ let d;
1810
+ switch (t) {
1811
+ case "daily":
1812
+ d = new Date(l.getTime() + n * 864e5);
1813
+ break;
1814
+ case "weekdays":
1815
+ d = new Date(l);
1816
+ do
1817
+ d.setDate(d.getDate() + 1);
1818
+ while (d.getDay() === 0 || d.getDay() === 6);
1819
+ break;
1820
+ case "weekly":
1821
+ d = new Date(l.getTime() + n * 7 * 864e5);
1822
+ break;
1823
+ case "bi-weekly":
1824
+ d = new Date(l.getTime() + 14 * 864e5);
1825
+ break;
1826
+ case "monthly":
1827
+ d = new Date(l), d.setMonth(d.getMonth() + n);
1828
+ break;
1829
+ case "yearly":
1830
+ d = new Date(l), d.setFullYear(d.getFullYear() + n);
1831
+ break;
1832
+ default:
1833
+ return null;
1834
+ }
1835
+ return r && d > r ? null : d;
1836
+ }
1837
+ /* ─────────────────────────────────────────────────────────────
1838
+ FILTERING & SORTING
1839
+ ───────────────────────────────────────────────────────────── */
1840
+ filterTasks(e) {
1841
+ var n, r, s;
1842
+ let t = this.getAllTasks();
1843
+ if ((n = e.status) != null && n.length && (t = t.filter((l) => e.status.includes(l.status))), (r = e.priority) != null && r.length && (t = t.filter((l) => e.priority.includes(l.priority))), e.projectId !== void 0 && (t = t.filter((l) => l.projectId === e.projectId)), (s = e.tags) != null && s.length && (t = t.filter((l) => e.tags.some((d) => l.tags.includes(d)))), e.dueDateRange) {
1844
+ const { start: l, end: d } = e.dueDateRange;
1845
+ t = t.filter((c) => {
1846
+ if (!c.dueDate)
1847
+ return !1;
1848
+ const g = new Date(c.dueDate);
1849
+ return !(l && g < l || d && g > d);
1850
+ });
1851
+ }
1852
+ if (e.search) {
1853
+ const l = e.search.toLowerCase();
1854
+ t = t.filter(
1855
+ (d) => {
1856
+ var c;
1857
+ return d.title.toLowerCase().includes(l) || ((c = d.description) == null ? void 0 : c.toLowerCase().includes(l)) || d.notes.toLowerCase().includes(l);
1858
+ }
1859
+ );
1860
+ }
1861
+ return t;
1862
+ }
1863
+ sortTasks(e, t = "dueDate", n = "asc") {
1864
+ return [...e].sort((s, l) => {
1865
+ let d = 0;
1866
+ switch (t) {
1867
+ case "dueDate":
1868
+ const c = s.dueDate ? new Date(s.dueDate).getTime() : 1 / 0, g = l.dueDate ? new Date(l.dueDate).getTime() : 1 / 0;
1869
+ d = c - g;
1870
+ break;
1871
+ case "priority":
1872
+ d = j[s.priority] - j[l.priority];
1873
+ break;
1874
+ case "createdAt":
1875
+ d = new Date(s.createdAt).getTime() - new Date(l.createdAt).getTime();
1876
+ break;
1877
+ case "title":
1878
+ d = s.title.localeCompare(l.title);
1879
+ break;
1880
+ case "status":
1881
+ d = s.status.localeCompare(l.status);
1882
+ break;
1883
+ }
1884
+ return n === "asc" ? d : -d;
1885
+ });
1886
+ }
1887
+ /* ─────────────────────────────────────────────────────────────
1888
+ VIEWS
1889
+ ───────────────────────────────────────────────────────────── */
1890
+ getInbox() {
1891
+ return this.filterTasks({ status: ["inbox"] });
1892
+ }
1893
+ getToday() {
1894
+ const e = /* @__PURE__ */ new Date();
1895
+ e.setHours(0, 0, 0, 0);
1896
+ const t = new Date(e.getTime() + 864e5);
1897
+ return this.filterTasks({
1898
+ status: ["todo", "in-progress"],
1899
+ dueDateRange: { end: t }
1900
+ });
1901
+ }
1902
+ getUpcoming(e = 7) {
1903
+ const t = /* @__PURE__ */ new Date();
1904
+ t.setHours(0, 0, 0, 0);
1905
+ const n = new Date(t.getTime() + e * 864e5);
1906
+ return this.filterTasks({
1907
+ status: ["todo", "in-progress"],
1908
+ dueDateRange: { start: t, end: n }
1909
+ });
1910
+ }
1911
+ getOverdue() {
1912
+ const e = /* @__PURE__ */ new Date();
1913
+ return e.setHours(0, 0, 0, 0), this.getAllTasks().filter(
1914
+ (t) => t.dueDate && new Date(t.dueDate) < e && !["done", "cancelled"].includes(t.status)
1915
+ );
1916
+ }
1917
+ /* ─────────────────────────────────────────────────────────────
1918
+ PRIORITY MATRIX
1919
+ ───────────────────────────────────────────────────────────── */
1920
+ getPriorityMatrix() {
1921
+ const e = this.filterTasks({ status: ["todo", "in-progress"] }), t = (r) => r.dueDate ? Math.ceil((new Date(r.dueDate).getTime() - Date.now()) / 864e5) <= 2 : !1, n = (r) => ["urgent", "high"].includes(r.priority);
1922
+ return {
1923
+ doFirst: {
1924
+ name: "Do First",
1925
+ description: "Urgent and Important",
1926
+ tasks: e.filter((r) => t(r) && n(r))
1927
+ },
1928
+ schedule: {
1929
+ name: "Schedule",
1930
+ description: "Important but Not Urgent",
1931
+ tasks: e.filter((r) => !t(r) && n(r))
1932
+ },
1933
+ delegate: {
1934
+ name: "Delegate",
1935
+ description: "Urgent but Not Important",
1936
+ tasks: e.filter((r) => t(r) && !n(r))
1937
+ },
1938
+ eliminate: {
1939
+ name: "Eliminate",
1940
+ description: "Neither Urgent nor Important",
1941
+ tasks: e.filter((r) => !t(r) && !n(r))
1942
+ }
1943
+ };
1944
+ }
1945
+ /* ─────────────────────────────────────────────────────────────
1946
+ TIME BLOCKING
1947
+ ───────────────────────────────────────────────────────────── */
1948
+ addTimeBlock(e) {
1949
+ const t = this.generateId(), n = { ...e, id: t };
1950
+ if (this.timeBlocks.set(t, n), e.taskId) {
1951
+ const r = this.tasks.get(e.taskId);
1952
+ r && (r.timeBlocks.push(n), this.tasks.set(e.taskId, r));
1953
+ }
1954
+ return n;
1955
+ }
1956
+ updateTimeBlock(e, t) {
1957
+ const n = this.timeBlocks.get(e);
1958
+ n && this.timeBlocks.set(e, { ...n, ...t, id: e });
1959
+ }
1960
+ deleteTimeBlock(e) {
1961
+ const t = this.timeBlocks.get(e);
1962
+ if (t != null && t.taskId) {
1963
+ const n = this.tasks.get(t.taskId);
1964
+ n && (n.timeBlocks = n.timeBlocks.filter((r) => r.id !== e), this.tasks.set(n.id, n));
1965
+ }
1966
+ this.timeBlocks.delete(e);
1967
+ }
1968
+ getTimeBlocksForDate(e) {
1969
+ const t = new Date(e);
1970
+ t.setHours(0, 0, 0, 0);
1971
+ const n = new Date(t.getTime() + 864e5);
1972
+ return Array.from(this.timeBlocks.values()).filter((r) => {
1973
+ const s = new Date(r.start);
1974
+ return s >= t && s < n;
1975
+ });
1976
+ }
1977
+ /* ─────────────────────────────────────────────────────────────
1978
+ PROJECTS
1979
+ ───────────────────────────────────────────────────────────── */
1980
+ addProject(e) {
1981
+ const t = this.generateId(), n = {
1982
+ ...e,
1983
+ id: t,
1984
+ order: this.projects.size,
1985
+ createdAt: /* @__PURE__ */ new Date()
1986
+ };
1987
+ return this.projects.set(t, n), n;
1988
+ }
1989
+ updateProject(e, t) {
1990
+ const n = this.projects.get(e);
1991
+ n && this.projects.set(e, { ...n, ...t, id: e });
1992
+ }
1993
+ deleteProject(e) {
1994
+ this.projects.delete(e);
1995
+ for (const [t, n] of this.tasks)
1996
+ n.projectId === e && (n.projectId = void 0, this.tasks.set(t, n));
1997
+ }
1998
+ getAllProjects() {
1999
+ return Array.from(this.projects.values()).sort((e, t) => e.order - t.order);
2000
+ }
2001
+ getProjectTasks(e) {
2002
+ return this.filterTasks({ projectId: e });
2003
+ }
2004
+ getProjectProgress(e) {
2005
+ const t = this.getProjectTasks(e), n = t.filter((r) => r.status === "done").length;
2006
+ return {
2007
+ total: t.length,
2008
+ completed: n,
2009
+ percentage: t.length > 0 ? Math.round(n / t.length * 100) : 0
2010
+ };
2011
+ }
2012
+ /* ─────────────────────────────────────────────────────────────
2013
+ TAGS
2014
+ ───────────────────────────────────────────────────────────── */
2015
+ addTag(e) {
2016
+ const t = this.generateId(), n = { ...e, id: t };
2017
+ return this.tags.set(t, n), n;
2018
+ }
2019
+ deleteTag(e) {
2020
+ this.tags.delete(e);
2021
+ for (const [t, n] of this.tasks)
2022
+ n.tags.includes(e) && (n.tags = n.tags.filter((r) => r !== e), this.tasks.set(t, n));
2023
+ }
2024
+ getAllTags() {
2025
+ return Array.from(this.tags.values());
2026
+ }
2027
+ /* ─────────────────────────────────────────────────────────────
2028
+ STATISTICS
2029
+ ───────────────────────────────────────────────────────────── */
2030
+ getStatistics() {
2031
+ const e = this.getAllTasks(), t = /* @__PURE__ */ new Date();
2032
+ t.setHours(0, 0, 0, 0);
2033
+ const n = new Date(t.getTime() + 864e5), r = e.filter((c) => c.status === "done").length, s = this.getOverdue().length, l = e.filter(
2034
+ (c) => c.dueDate && new Date(c.dueDate) >= t && new Date(c.dueDate) < n && c.status !== "done"
2035
+ ).length, d = e.filter((c) => c.status === "in-progress").length;
2036
+ return {
2037
+ total: e.length,
2038
+ completed: r,
2039
+ overdue: s,
2040
+ dueToday: l,
2041
+ inProgress: d,
2042
+ completionRate: e.length > 0 ? Math.round(r / e.length * 100) : 0
2043
+ };
2044
+ }
2045
+ /* ─────────────────────────────────────────────────────────────
2046
+ UTILITIES
2047
+ ───────────────────────────────────────────────────────────── */
2048
+ generateId() {
2049
+ return Date.now().toString(36) + Math.random().toString(36).substring(2, 8);
2050
+ }
2051
+ clear() {
2052
+ this.tasks.clear(), this.projects.clear(), this.tags.clear(), this.timeBlocks.clear();
2053
+ }
2054
+ }
2055
+ function Ve() {
2056
+ return new pe();
2057
+ }
2058
+ const E = F(null);
2059
+ function Oe() {
2060
+ const a = W(E);
2061
+ if (!a)
2062
+ throw new Error("useTaskManager must be used within TaskManagerProvider");
2063
+ return a;
2064
+ }
2065
+ const k = {
2066
+ container: {
2067
+ display: "flex",
2068
+ height: "100%",
2069
+ fontFamily: "'Inter', sans-serif",
2070
+ backgroundColor: "#f5f7fa"
2071
+ },
2072
+ sidebar: {
2073
+ width: "250px",
2074
+ backgroundColor: "#fff",
2075
+ borderRight: "1px solid #e0e0e0",
2076
+ padding: "20px",
2077
+ overflow: "auto"
2078
+ },
2079
+ main: {
2080
+ flex: 1,
2081
+ padding: "20px",
2082
+ overflow: "auto"
2083
+ },
2084
+ menuItem: {
2085
+ display: "flex",
2086
+ alignItems: "center",
2087
+ gap: "12px",
2088
+ padding: "12px 16px",
2089
+ borderRadius: "8px",
2090
+ cursor: "pointer",
2091
+ marginBottom: "4px",
2092
+ transition: "background-color 0.2s"
2093
+ },
2094
+ badge: {
2095
+ backgroundColor: "#1976d2",
2096
+ color: "#fff",
2097
+ borderRadius: "10px",
2098
+ padding: "2px 8px",
2099
+ fontSize: "12px",
2100
+ marginLeft: "auto"
2101
+ },
2102
+ sectionTitle: {
2103
+ fontSize: "11px",
2104
+ fontWeight: 600,
2105
+ color: "#999",
2106
+ textTransform: "uppercase",
2107
+ letterSpacing: "1px",
2108
+ margin: "20px 0 12px"
2109
+ },
2110
+ header: {
2111
+ display: "flex",
2112
+ justifyContent: "space-between",
2113
+ alignItems: "center",
2114
+ marginBottom: "20px"
2115
+ },
2116
+ title: {
2117
+ fontSize: "24px",
2118
+ fontWeight: 600,
2119
+ color: "#1a1a2e"
2120
+ },
2121
+ taskInput: {
2122
+ width: "100%",
2123
+ padding: "12px 16px",
2124
+ border: "1px solid #e0e0e0",
2125
+ borderRadius: "8px",
2126
+ fontSize: "14px",
2127
+ marginBottom: "20px",
2128
+ outline: "none"
2129
+ },
2130
+ taskItem: {
2131
+ display: "flex",
2132
+ alignItems: "flex-start",
2133
+ gap: "12px",
2134
+ padding: "12px 16px",
2135
+ backgroundColor: "#fff",
2136
+ borderRadius: "8px",
2137
+ marginBottom: "8px",
2138
+ boxShadow: "0 1px 3px rgba(0,0,0,0.08)",
2139
+ cursor: "pointer"
2140
+ },
2141
+ checkbox: {
2142
+ width: "20px",
2143
+ height: "20px",
2144
+ borderRadius: "50%",
2145
+ border: "2px solid #ccc",
2146
+ cursor: "pointer",
2147
+ flexShrink: 0,
2148
+ marginTop: "2px"
2149
+ },
2150
+ taskContent: {
2151
+ flex: 1,
2152
+ minWidth: 0
2153
+ },
2154
+ taskTitle: {
2155
+ fontSize: "14px",
2156
+ fontWeight: 500,
2157
+ color: "#333",
2158
+ marginBottom: "4px"
2159
+ },
2160
+ taskMeta: {
2161
+ display: "flex",
2162
+ alignItems: "center",
2163
+ gap: "8px",
2164
+ fontSize: "12px",
2165
+ color: "#666"
2166
+ },
2167
+ priorityIndicator: {
2168
+ width: "4px",
2169
+ borderRadius: "2px",
2170
+ alignSelf: "stretch"
2171
+ },
2172
+ matrixGrid: {
2173
+ display: "grid",
2174
+ gridTemplateColumns: "1fr 1fr",
2175
+ gridTemplateRows: "1fr 1fr",
2176
+ gap: "16px",
2177
+ height: "calc(100% - 60px)"
2178
+ },
2179
+ matrixQuadrant: {
2180
+ backgroundColor: "#fff",
2181
+ borderRadius: "12px",
2182
+ padding: "16px",
2183
+ overflow: "auto"
2184
+ }
2185
+ }, H = {
2186
+ urgent: "#f44336",
2187
+ high: "#ff9800",
2188
+ medium: "#2196f3",
2189
+ low: "#4caf50",
2190
+ none: "#e0e0e0"
2191
+ };
2192
+ function Ge({
2193
+ service: a,
2194
+ className: e,
2195
+ style: t
2196
+ }) {
2197
+ var M;
2198
+ const [, n] = S(0), [r, s] = S("inbox"), [l, d] = S(null), [c, g] = S(""), u = L(() => n((T) => T + 1), []), p = { service: a, refresh: u }, y = a.getStatistics(), f = a.getAllProjects(), b = () => {
2199
+ c.trim() && (a.quickAddTask(c), g(""), u());
2200
+ }, D = (T, P) => {
2201
+ s(T), d(P ?? null);
2202
+ };
2203
+ return /* @__PURE__ */ i(E.Provider, { value: p, children: /* @__PURE__ */ o("div", { className: e, style: { ...k.container, ...t }, children: [
2204
+ /* @__PURE__ */ o("div", { style: k.sidebar, children: [
2205
+ /* @__PURE__ */ o(
2206
+ "div",
2207
+ {
2208
+ onClick: () => D("inbox"),
2209
+ style: {
2210
+ ...k.menuItem,
2211
+ backgroundColor: r === "inbox" ? "#e3f2fd" : "transparent"
2212
+ },
2213
+ children: [
2214
+ /* @__PURE__ */ i("span", { children: "📥" }),
2215
+ /* @__PURE__ */ i("span", { children: "Inbox" }),
2216
+ y.total - y.completed > 0 && /* @__PURE__ */ i("span", { style: k.badge, children: a.getInbox().length })
2217
+ ]
2218
+ }
2219
+ ),
2220
+ /* @__PURE__ */ o(
2221
+ "div",
2222
+ {
2223
+ onClick: () => D("today"),
2224
+ style: {
2225
+ ...k.menuItem,
2226
+ backgroundColor: r === "today" ? "#e3f2fd" : "transparent"
2227
+ },
2228
+ children: [
2229
+ /* @__PURE__ */ i("span", { children: "📅" }),
2230
+ /* @__PURE__ */ i("span", { children: "Today" }),
2231
+ y.dueToday > 0 && /* @__PURE__ */ i("span", { style: k.badge, children: y.dueToday })
2232
+ ]
2233
+ }
2234
+ ),
2235
+ /* @__PURE__ */ o(
2236
+ "div",
2237
+ {
2238
+ onClick: () => D("upcoming"),
2239
+ style: {
2240
+ ...k.menuItem,
2241
+ backgroundColor: r === "upcoming" ? "#e3f2fd" : "transparent"
2242
+ },
2243
+ children: [
2244
+ /* @__PURE__ */ i("span", { children: "🗓️" }),
2245
+ /* @__PURE__ */ i("span", { children: "Upcoming" })
2246
+ ]
2247
+ }
2248
+ ),
2249
+ /* @__PURE__ */ o(
2250
+ "div",
2251
+ {
2252
+ onClick: () => D("matrix"),
2253
+ style: {
2254
+ ...k.menuItem,
2255
+ backgroundColor: r === "matrix" ? "#e3f2fd" : "transparent"
2256
+ },
2257
+ children: [
2258
+ /* @__PURE__ */ i("span", { children: "⬜" }),
2259
+ /* @__PURE__ */ i("span", { children: "Priority Matrix" })
2260
+ ]
2261
+ }
2262
+ ),
2263
+ /* @__PURE__ */ o(
2264
+ "div",
2265
+ {
2266
+ onClick: () => D("all"),
2267
+ style: {
2268
+ ...k.menuItem,
2269
+ backgroundColor: r === "all" ? "#e3f2fd" : "transparent"
2270
+ },
2271
+ children: [
2272
+ /* @__PURE__ */ i("span", { children: "📋" }),
2273
+ /* @__PURE__ */ i("span", { children: "All Tasks" })
2274
+ ]
2275
+ }
2276
+ ),
2277
+ y.overdue > 0 && /* @__PURE__ */ o("div", { style: { ...k.menuItem, color: "#f44336" }, children: [
2278
+ /* @__PURE__ */ i("span", { children: "⚠️" }),
2279
+ /* @__PURE__ */ i("span", { children: "Overdue" }),
2280
+ /* @__PURE__ */ i("span", { style: { ...k.badge, backgroundColor: "#f44336" }, children: y.overdue })
2281
+ ] }),
2282
+ /* @__PURE__ */ i("div", { style: k.sectionTitle, children: "Projects" }),
2283
+ f.map((T) => {
2284
+ const P = a.getProjectProgress(T.id);
2285
+ return /* @__PURE__ */ o(
2286
+ "div",
2287
+ {
2288
+ onClick: () => D("project", T.id),
2289
+ style: {
2290
+ ...k.menuItem,
2291
+ backgroundColor: r === "project" && l === T.id ? "#e3f2fd" : "transparent"
2292
+ },
2293
+ children: [
2294
+ /* @__PURE__ */ i(
2295
+ "span",
2296
+ {
2297
+ style: {
2298
+ width: "10px",
2299
+ height: "10px",
2300
+ borderRadius: "50%",
2301
+ backgroundColor: T.color
2302
+ }
2303
+ }
2304
+ ),
2305
+ /* @__PURE__ */ i("span", { style: { flex: 1 }, children: T.name }),
2306
+ /* @__PURE__ */ o("span", { style: { fontSize: "12px", color: "#999" }, children: [
2307
+ P.percentage,
2308
+ "%"
2309
+ ] })
2310
+ ]
2311
+ },
2312
+ T.id
2313
+ );
2314
+ })
2315
+ ] }),
2316
+ /* @__PURE__ */ o("div", { style: k.main, children: [
2317
+ /* @__PURE__ */ o("div", { style: k.header, children: [
2318
+ /* @__PURE__ */ o("div", { style: k.title, children: [
2319
+ r === "inbox" && "Inbox",
2320
+ r === "today" && "Today",
2321
+ r === "upcoming" && "Upcoming",
2322
+ r === "matrix" && "Priority Matrix",
2323
+ r === "all" && "All Tasks",
2324
+ r === "project" && ((M = f.find((T) => T.id === l)) == null ? void 0 : M.name)
2325
+ ] }),
2326
+ /* @__PURE__ */ o("div", { style: { fontSize: "14px", color: "#666" }, children: [
2327
+ y.completed,
2328
+ "/",
2329
+ y.total,
2330
+ " completed"
2331
+ ] })
2332
+ ] }),
2333
+ r !== "matrix" && /* @__PURE__ */ i(
2334
+ "input",
2335
+ {
2336
+ type: "text",
2337
+ placeholder: "Quick add task (e.g., 'Buy groceries tomorrow #shopping !')",
2338
+ value: c,
2339
+ onChange: (T) => g(T.target.value),
2340
+ onKeyDown: (T) => T.key === "Enter" && b(),
2341
+ style: k.taskInput
2342
+ }
2343
+ ),
2344
+ r === "matrix" ? /* @__PURE__ */ i(me, { service: a, onComplete: u }) : /* @__PURE__ */ i(
2345
+ fe,
2346
+ {
2347
+ service: a,
2348
+ view: r,
2349
+ projectId: l,
2350
+ onComplete: u
2351
+ }
2352
+ )
2353
+ ] })
2354
+ ] }) });
2355
+ }
2356
+ function fe({
2357
+ service: a,
2358
+ view: e,
2359
+ projectId: t,
2360
+ onComplete: n
2361
+ }) {
2362
+ const r = z(() => {
2363
+ switch (e) {
2364
+ case "inbox":
2365
+ return a.getInbox();
2366
+ case "today":
2367
+ return a.getToday();
2368
+ case "upcoming":
2369
+ return a.getUpcoming();
2370
+ case "all":
2371
+ return a.sortTasks(
2372
+ a.filterTasks({ status: ["inbox", "todo", "in-progress"] }),
2373
+ "dueDate"
2374
+ );
2375
+ case "project":
2376
+ return t ? a.filterTasks({ projectId: t, status: ["inbox", "todo", "in-progress"] }) : [];
2377
+ default:
2378
+ return [];
2379
+ }
2380
+ }, [a, e, t]);
2381
+ return r.length === 0 ? /* @__PURE__ */ o("div", { style: { textAlign: "center", padding: "60px", color: "#999" }, children: [
2382
+ /* @__PURE__ */ i("div", { style: { fontSize: "48px", marginBottom: "16px" }, children: "✨" }),
2383
+ /* @__PURE__ */ i("div", { children: "No tasks here!" })
2384
+ ] }) : /* @__PURE__ */ i("div", { children: r.map((s) => /* @__PURE__ */ i(V, { task: s, service: a, onComplete: n }, s.id)) });
2385
+ }
2386
+ function V({
2387
+ task: a,
2388
+ service: e,
2389
+ onComplete: t
2390
+ }) {
2391
+ const n = (l) => {
2392
+ l.stopPropagation(), e.completeTask(a.id), t();
2393
+ }, r = (l) => {
2394
+ const d = new Date(l), c = /* @__PURE__ */ new Date();
2395
+ c.setHours(0, 0, 0, 0);
2396
+ const g = new Date(c.getTime() + 864e5);
2397
+ return d < c ? "Overdue" : d.toDateString() === c.toDateString() ? "Today" : d.toDateString() === g.toDateString() ? "Tomorrow" : d.toLocaleDateString("en-US", { month: "short", day: "numeric" });
2398
+ }, s = a.dueDate && new Date(a.dueDate) < /* @__PURE__ */ new Date() && a.status !== "done";
2399
+ return /* @__PURE__ */ o("div", { style: k.taskItem, children: [
2400
+ /* @__PURE__ */ i(
2401
+ "div",
2402
+ {
2403
+ style: { ...k.priorityIndicator, backgroundColor: H[a.priority] }
2404
+ }
2405
+ ),
2406
+ /* @__PURE__ */ i(
2407
+ "div",
2408
+ {
2409
+ onClick: n,
2410
+ style: {
2411
+ ...k.checkbox,
2412
+ borderColor: H[a.priority]
2413
+ }
2414
+ }
2415
+ ),
2416
+ /* @__PURE__ */ o("div", { style: k.taskContent, children: [
2417
+ /* @__PURE__ */ i("div", { style: k.taskTitle, children: a.title }),
2418
+ /* @__PURE__ */ o("div", { style: k.taskMeta, children: [
2419
+ a.dueDate && /* @__PURE__ */ o("span", { style: { color: s ? "#f44336" : "#666" }, children: [
2420
+ "📅 ",
2421
+ r(a.dueDate)
2422
+ ] }),
2423
+ a.estimatedMinutes && /* @__PURE__ */ o("span", { children: [
2424
+ "⏱️ ",
2425
+ a.estimatedMinutes,
2426
+ "m"
2427
+ ] }),
2428
+ a.recurrence && /* @__PURE__ */ i("span", { children: "🔄" })
2429
+ ] })
2430
+ ] })
2431
+ ] });
2432
+ }
2433
+ function me({
2434
+ service: a,
2435
+ onComplete: e
2436
+ }) {
2437
+ const t = a.getPriorityMatrix(), n = {
2438
+ doFirst: { bg: "#ffebee", border: "#f44336" },
2439
+ schedule: { bg: "#fff3e0", border: "#ff9800" },
2440
+ delegate: { bg: "#e3f2fd", border: "#2196f3" },
2441
+ eliminate: { bg: "#f5f5f5", border: "#9e9e9e" }
2442
+ };
2443
+ return /* @__PURE__ */ i("div", { style: k.matrixGrid, children: ["doFirst", "schedule", "delegate", "eliminate"].map((r) => {
2444
+ const s = t[r], l = n[r];
2445
+ return /* @__PURE__ */ o(
2446
+ "div",
2447
+ {
2448
+ style: {
2449
+ ...k.matrixQuadrant,
2450
+ backgroundColor: l.bg,
2451
+ borderLeft: `4px solid ${l.border}`
2452
+ },
2453
+ children: [
2454
+ /* @__PURE__ */ i("div", { style: { fontWeight: 600, marginBottom: "8px" }, children: s.name }),
2455
+ /* @__PURE__ */ i("div", { style: { fontSize: "12px", color: "#666", marginBottom: "12px" }, children: s.description }),
2456
+ s.tasks.map((d) => /* @__PURE__ */ i(V, { task: d, service: a, onComplete: e }, d.id)),
2457
+ s.tasks.length === 0 && /* @__PURE__ */ i("div", { style: { color: "#999", textAlign: "center", padding: "20px" }, children: "Empty" })
2458
+ ]
2459
+ },
2460
+ r
2461
+ );
2462
+ }) });
2463
+ }
2464
+ class ye {
2465
+ constructor() {
2466
+ w(this, "kpis", /* @__PURE__ */ new Map());
2467
+ w(this, "goals", /* @__PURE__ */ new Map());
2468
+ w(this, "habits", /* @__PURE__ */ new Map());
2469
+ w(this, "moodEntries", /* @__PURE__ */ new Map());
2470
+ w(this, "financeSummary", {
2471
+ netWorth: 0,
2472
+ monthlyIncome: 0,
2473
+ monthlyExpenses: 0,
2474
+ savings: 0,
2475
+ savingsRate: 0,
2476
+ debts: 0,
2477
+ investments: 0,
2478
+ budgetUsed: 0,
2479
+ budgetTotal: 0,
2480
+ categories: []
2481
+ });
2482
+ }
2483
+ /* ─────────────────────────────────────────────────────────────
2484
+ KPIs
2485
+ ───────────────────────────────────────────────────────────── */
2486
+ addKPI(e) {
2487
+ const t = this.generateId(), n = { ...e, id: t };
2488
+ return this.kpis.set(t, n), n;
2489
+ }
2490
+ updateKPI(e, t) {
2491
+ const n = this.kpis.get(e);
2492
+ n && this.kpis.set(e, { ...n, ...t, id: e });
2493
+ }
2494
+ recordKPIValue(e, t) {
2495
+ const n = this.kpis.get(e);
2496
+ if (n) {
2497
+ const r = n.currentValue;
2498
+ n.currentValue = t, n.history.push({ date: /* @__PURE__ */ new Date(), value: t }), n.trend = t > r ? "up" : t < r ? "down" : "stable", this.kpis.set(e, n);
2499
+ }
2500
+ }
2501
+ getAllKPIs() {
2502
+ return Array.from(this.kpis.values());
2503
+ }
2504
+ getKPIsByCategory(e) {
2505
+ return this.getAllKPIs().filter((t) => t.category === e);
2506
+ }
2507
+ calculateKPIProgress(e) {
2508
+ return e.targetValue === 0 ? 100 : Math.min(100, e.currentValue / e.targetValue * 100);
2509
+ }
2510
+ /* ─────────────────────────────────────────────────────────────
2511
+ GOALS
2512
+ ───────────────────────────────────────────────────────────── */
2513
+ addGoal(e) {
2514
+ const t = this.generateId(), n = { ...e, id: t };
2515
+ return this.goals.set(t, n), n;
2516
+ }
2517
+ updateGoal(e, t) {
2518
+ const n = this.goals.get(e);
2519
+ n && this.goals.set(e, { ...n, ...t, id: e });
2520
+ }
2521
+ completeGoalMilestone(e, t) {
2522
+ const n = this.goals.get(e);
2523
+ if (n) {
2524
+ const r = n.milestones.find((s) => s.id === t);
2525
+ r && (r.completed = !0, r.completedDate = /* @__PURE__ */ new Date(), n.progress = this.calculateGoalProgress(n), this.goals.set(e, n));
2526
+ }
2527
+ }
2528
+ calculateGoalProgress(e) {
2529
+ if (e.milestones.length === 0)
2530
+ return e.progress;
2531
+ const t = e.milestones.filter((n) => n.completed).length;
2532
+ return Math.round(t / e.milestones.length * 100);
2533
+ }
2534
+ getAllGoals() {
2535
+ return Array.from(this.goals.values());
2536
+ }
2537
+ getActiveGoals() {
2538
+ return this.getAllGoals().filter((e) => e.status === "in-progress");
2539
+ }
2540
+ getGoalsByCategory(e) {
2541
+ return this.getAllGoals().filter((t) => t.category === e);
2542
+ }
2543
+ getUpcomingDeadlines(e = 30) {
2544
+ const t = /* @__PURE__ */ new Date(), n = new Date(t.getTime() + e * 24 * 60 * 60 * 1e3);
2545
+ return this.getActiveGoals().filter((r) => r.targetDate <= n).sort((r, s) => r.targetDate.getTime() - s.targetDate.getTime());
2546
+ }
2547
+ /* ─────────────────────────────────────────────────────────────
2548
+ HABITS
2549
+ ───────────────────────────────────────────────────────────── */
2550
+ addHabit(e) {
2551
+ const t = this.generateId(), n = {
2552
+ ...e,
2553
+ id: t,
2554
+ streak: 0,
2555
+ longestStreak: 0,
2556
+ completions: [],
2557
+ createdAt: /* @__PURE__ */ new Date()
2558
+ };
2559
+ return this.habits.set(t, n), n;
2560
+ }
2561
+ completeHabit(e, t = 1, n) {
2562
+ const r = this.habits.get(e);
2563
+ if (r) {
2564
+ const s = /* @__PURE__ */ new Date();
2565
+ s.setHours(0, 0, 0, 0);
2566
+ const l = r.completions.find(
2567
+ (d) => new Date(d.date).toDateString() === s.toDateString()
2568
+ );
2569
+ l ? (l.count += t, n && (l.note = n)) : r.completions.push({ date: s, count: t, note: n }), this.updateStreak(r), this.habits.set(e, r);
2570
+ }
2571
+ }
2572
+ updateStreak(e) {
2573
+ const t = [...e.completions].sort(
2574
+ (s, l) => new Date(l.date).getTime() - new Date(s.date).getTime()
2575
+ );
2576
+ if (t.length === 0) {
2577
+ e.streak = 0;
2578
+ return;
2579
+ }
2580
+ let n = 0;
2581
+ const r = /* @__PURE__ */ new Date();
2582
+ r.setHours(0, 0, 0, 0);
2583
+ for (let s = 0; s < t.length; s++) {
2584
+ const l = new Date(t[s].date);
2585
+ l.setHours(0, 0, 0, 0);
2586
+ const d = new Date(r.getTime() - s * 24 * 60 * 60 * 1e3);
2587
+ if (l.getTime() === d.getTime())
2588
+ if (t[s].count >= e.targetPerPeriod)
2589
+ n++;
2590
+ else
2591
+ break;
2592
+ else
2593
+ break;
2594
+ }
2595
+ e.streak = n, n > e.longestStreak && (e.longestStreak = n);
2596
+ }
2597
+ getAllHabits() {
2598
+ return Array.from(this.habits.values());
2599
+ }
2600
+ getHabitCompletionRate(e, t = 30) {
2601
+ const n = this.habits.get(e);
2602
+ if (!n)
2603
+ return 0;
2604
+ const r = /* @__PURE__ */ new Date(), s = new Date(r.getTime() - t * 24 * 60 * 60 * 1e3), l = n.completions.filter(
2605
+ (d) => new Date(d.date) >= s && d.count >= n.targetPerPeriod
2606
+ );
2607
+ return Math.round(l.length / t * 100);
2608
+ }
2609
+ getTodayHabitStatus() {
2610
+ const e = (/* @__PURE__ */ new Date()).toDateString();
2611
+ return this.getAllHabits().map((t) => {
2612
+ const n = t.completions.find((r) => new Date(r.date).toDateString() === e);
2613
+ return {
2614
+ habit: t,
2615
+ completed: n ? n.count >= t.targetPerPeriod : !1,
2616
+ count: (n == null ? void 0 : n.count) ?? 0
2617
+ };
2618
+ });
2619
+ }
2620
+ /* ─────────────────────────────────────────────────────────────
2621
+ MOOD & HEALTH
2622
+ ───────────────────────────────────────────────────────────── */
2623
+ addMoodEntry(e) {
2624
+ const t = this.generateId(), n = { ...e, id: t };
2625
+ return this.moodEntries.set(t, n), n;
2626
+ }
2627
+ getAllMoodEntries() {
2628
+ return Array.from(this.moodEntries.values()).sort(
2629
+ (e, t) => new Date(t.date).getTime() - new Date(e.date).getTime()
2630
+ );
2631
+ }
2632
+ getMoodEntriesForPeriod(e, t) {
2633
+ return this.getAllMoodEntries().filter(
2634
+ (n) => new Date(n.date) >= e && new Date(n.date) <= t
2635
+ );
2636
+ }
2637
+ getAverageMood(e = 7) {
2638
+ const t = /* @__PURE__ */ new Date(), n = new Date(t.getTime() - e * 24 * 60 * 60 * 1e3), r = this.getMoodEntriesForPeriod(n, t);
2639
+ return r.length === 0 ? 0 : r.reduce((s, l) => s + l.mood, 0) / r.length;
2640
+ }
2641
+ getAverageSleep(e = 7) {
2642
+ const t = /* @__PURE__ */ new Date(), n = new Date(t.getTime() - e * 24 * 60 * 60 * 1e3), r = this.getMoodEntriesForPeriod(n, t);
2643
+ return r.length === 0 ? 0 : r.reduce((s, l) => s + l.sleep, 0) / r.length;
2644
+ }
2645
+ getMoodCorrelations() {
2646
+ const e = this.getAllMoodEntries();
2647
+ if (e.length < 5)
2648
+ return [];
2649
+ const t = [], n = this.calculateCorrelation(
2650
+ e.map((s) => s.sleep),
2651
+ e.map((s) => s.mood)
2652
+ );
2653
+ t.push({ factor: "Sleep", correlation: n });
2654
+ const r = this.calculateCorrelation(
2655
+ e.map((s) => s.stress),
2656
+ e.map((s) => s.mood)
2657
+ );
2658
+ return t.push({ factor: "Stress", correlation: r }), t.sort((s, l) => Math.abs(l.correlation) - Math.abs(s.correlation));
2659
+ }
2660
+ calculateCorrelation(e, t) {
2661
+ const n = e.length;
2662
+ if (n === 0)
2663
+ return 0;
2664
+ const r = e.reduce((p, y) => p + y, 0), s = t.reduce((p, y) => p + y, 0), l = e.reduce((p, y, f) => p + y * t[f], 0), d = e.reduce((p, y) => p + y * y, 0), c = t.reduce((p, y) => p + y * y, 0), g = n * l - r * s, u = Math.sqrt((n * d - r ** 2) * (n * c - s ** 2));
2665
+ return u === 0 ? 0 : g / u;
2666
+ }
2667
+ /* ─────────────────────────────────────────────────────────────
2668
+ FINANCE
2669
+ ───────────────────────────────────────────────────────────── */
2670
+ setFinanceSummary(e) {
2671
+ this.financeSummary = e;
2672
+ }
2673
+ getFinanceSummary() {
2674
+ return { ...this.financeSummary };
2675
+ }
2676
+ calculateFinanceHealth() {
2677
+ const e = [], t = Math.min(100, this.financeSummary.savingsRate / 20 * 100);
2678
+ e.push({ name: "Savings Rate", score: t });
2679
+ const n = this.financeSummary.budgetTotal > 0 ? Math.min(
2680
+ 100,
2681
+ (1 - this.financeSummary.budgetUsed / this.financeSummary.budgetTotal) * 100 + 50
2682
+ ) : 50;
2683
+ e.push({ name: "Budget Adherence", score: n });
2684
+ const r = this.financeSummary.monthlyIncome > 0 ? this.financeSummary.debts / (this.financeSummary.monthlyIncome * 12) : 0, s = Math.max(0, 100 - r * 100);
2685
+ e.push({ name: "Debt Management", score: s });
2686
+ const l = this.financeSummary.monthlyExpenses > 0 ? this.financeSummary.savings / this.financeSummary.monthlyExpenses : 0, d = Math.min(100, l / 6 * 100);
2687
+ e.push({ name: "Emergency Fund", score: d });
2688
+ const c = e.reduce((g, u) => g + u.score, 0) / e.length;
2689
+ return { score: Math.round(c), factors: e };
2690
+ }
2691
+ /* ─────────────────────────────────────────────────────────────
2692
+ INSIGHTS
2693
+ ───────────────────────────────────────────────────────────── */
2694
+ generateDailyInsights() {
2695
+ const e = [], t = this.getAllKPIs(), n = t.filter((g) => g.currentValue >= g.targetValue);
2696
+ n.length > 0 && e.push(`You've achieved ${n.length} of ${t.length} KPI targets!`);
2697
+ const r = this.getTodayHabitStatus(), s = r.filter((g) => g.completed);
2698
+ s.length === r.length && r.length > 0 ? e.push("All habits completed today! Keep it up!") : s.length > 0 && e.push(`${s.length}/${r.length} habits completed today.`);
2699
+ const l = this.getAllHabits().reduce((g, u) => Math.max(g, u.streak), 0);
2700
+ l >= 7 && e.push(`Amazing ${l}-day streak! You're building a strong routine.`);
2701
+ const d = this.getUpcomingDeadlines(7);
2702
+ d.length > 0 && e.push(`${d.length} goal deadline(s) coming up this week.`);
2703
+ const c = this.getAverageMood(7);
2704
+ return c >= 4 ? e.push("Your mood has been great this week!") : c < 3 && c > 0 && e.push("Your mood has been lower than usual. Consider some self-care activities."), e;
2705
+ }
2706
+ /* ─────────────────────────────────────────────────────────────
2707
+ UTILITIES
2708
+ ───────────────────────────────────────────────────────────── */
2709
+ generateId() {
2710
+ return Date.now().toString(36) + Math.random().toString(36).substring(2, 8);
2711
+ }
2712
+ clear() {
2713
+ this.kpis.clear(), this.goals.clear(), this.habits.clear(), this.moodEntries.clear();
2714
+ }
2715
+ }
2716
+ function qe() {
2717
+ return new ye();
2718
+ }
2719
+ const O = F(null);
2720
+ function Ke() {
2721
+ const a = W(O);
2722
+ if (!a)
2723
+ throw new Error("useLifeDashboard must be used within LifeDashboardProvider");
2724
+ return a;
2725
+ }
2726
+ const v = {
2727
+ dashboard: {
2728
+ display: "flex",
2729
+ flexDirection: "column",
2730
+ height: "100%",
2731
+ fontFamily: "'Inter', sans-serif",
2732
+ backgroundColor: "#f5f7fa",
2733
+ padding: "20px",
2734
+ gap: "20px",
2735
+ overflow: "auto"
2736
+ },
2737
+ header: {
2738
+ display: "flex",
2739
+ justifyContent: "space-between",
2740
+ alignItems: "center",
2741
+ marginBottom: "10px"
2742
+ },
2743
+ title: {
2744
+ fontSize: "24px",
2745
+ fontWeight: 600,
2746
+ color: "#1a1a2e"
2747
+ },
2748
+ grid: {
2749
+ display: "grid",
2750
+ gridTemplateColumns: "repeat(auto-fit, minmax(300px, 1fr))",
2751
+ gap: "20px"
2752
+ },
2753
+ card: {
2754
+ backgroundColor: "#fff",
2755
+ borderRadius: "12px",
2756
+ padding: "20px",
2757
+ boxShadow: "0 2px 8px rgba(0,0,0,0.08)"
2758
+ },
2759
+ cardTitle: {
2760
+ fontSize: "16px",
2761
+ fontWeight: 600,
2762
+ color: "#1a1a2e",
2763
+ marginBottom: "16px"
2764
+ },
2765
+ progressBar: {
2766
+ height: "8px",
2767
+ backgroundColor: "#e0e0e0",
2768
+ borderRadius: "4px",
2769
+ overflow: "hidden"
2770
+ },
2771
+ progressFill: {
2772
+ height: "100%",
2773
+ borderRadius: "4px",
2774
+ transition: "width 0.3s ease"
2775
+ },
2776
+ statRow: {
2777
+ display: "flex",
2778
+ justifyContent: "space-between",
2779
+ alignItems: "center",
2780
+ padding: "8px 0",
2781
+ borderBottom: "1px solid #f0f0f0"
2782
+ },
2783
+ habitItem: {
2784
+ display: "flex",
2785
+ alignItems: "center",
2786
+ gap: "12px",
2787
+ padding: "10px 0",
2788
+ borderBottom: "1px solid #f0f0f0"
2789
+ },
2790
+ habitCheck: {
2791
+ width: "24px",
2792
+ height: "24px",
2793
+ borderRadius: "50%",
2794
+ border: "2px solid #1976d2",
2795
+ cursor: "pointer",
2796
+ display: "flex",
2797
+ alignItems: "center",
2798
+ justifyContent: "center"
2799
+ },
2800
+ moodEmoji: {
2801
+ fontSize: "28px",
2802
+ textAlign: "center"
2803
+ },
2804
+ insight: {
2805
+ backgroundColor: "#e3f2fd",
2806
+ borderRadius: "8px",
2807
+ padding: "12px 16px",
2808
+ marginBottom: "8px",
2809
+ fontSize: "14px",
2810
+ color: "#1565c0"
2811
+ }
2812
+ };
2813
+ function Qe({
2814
+ service: a,
2815
+ className: e,
2816
+ style: t
2817
+ }) {
2818
+ const [, n] = S(0), r = L(() => {
2819
+ n((f) => f + 1);
2820
+ }, []), s = { service: a, refresh: r }, l = a.generateDailyInsights(), d = a.getAllKPIs(), c = a.getTodayHabitStatus(), g = a.getActiveGoals(), u = a.getFinanceSummary(), p = a.calculateFinanceHealth(), y = (f) => new Intl.NumberFormat("en-US", { style: "currency", currency: "USD" }).format(f);
2821
+ return /* @__PURE__ */ i(O.Provider, { value: s, children: /* @__PURE__ */ o("div", { className: e, style: { ...v.dashboard, ...t }, children: [
2822
+ /* @__PURE__ */ o("div", { style: v.header, children: [
2823
+ /* @__PURE__ */ i("div", { style: v.title, children: "Life Dashboard" }),
2824
+ /* @__PURE__ */ i("div", { style: { color: "#666" }, children: (/* @__PURE__ */ new Date()).toLocaleDateString("en-US", {
2825
+ weekday: "long",
2826
+ year: "numeric",
2827
+ month: "long",
2828
+ day: "numeric"
2829
+ }) })
2830
+ ] }),
2831
+ l.length > 0 && /* @__PURE__ */ i("div", { children: l.map((f, b) => /* @__PURE__ */ i("div", { style: v.insight, children: f }, b)) }),
2832
+ /* @__PURE__ */ o("div", { style: v.grid, children: [
2833
+ /* @__PURE__ */ o("div", { style: v.card, children: [
2834
+ /* @__PURE__ */ i("div", { style: v.cardTitle, children: "Personal KPIs" }),
2835
+ d.length === 0 ? /* @__PURE__ */ i("div", { style: { color: "#999", textAlign: "center", padding: "20px" }, children: "No KPIs defined yet" }) : d.slice(0, 5).map((f) => {
2836
+ const b = a.calculateKPIProgress(f);
2837
+ return /* @__PURE__ */ o("div", { style: { marginBottom: "16px" }, children: [
2838
+ /* @__PURE__ */ o(
2839
+ "div",
2840
+ {
2841
+ style: {
2842
+ display: "flex",
2843
+ justifyContent: "space-between",
2844
+ marginBottom: "4px"
2845
+ },
2846
+ children: [
2847
+ /* @__PURE__ */ i("span", { style: { fontWeight: 500 }, children: f.name }),
2848
+ /* @__PURE__ */ o("span", { style: { color: "#666" }, children: [
2849
+ f.currentValue,
2850
+ f.unit ? ` ${f.unit}` : "",
2851
+ " / ",
2852
+ f.targetValue,
2853
+ f.trend === "up" && " ↑",
2854
+ f.trend === "down" && " ↓"
2855
+ ] })
2856
+ ]
2857
+ }
2858
+ ),
2859
+ /* @__PURE__ */ i("div", { style: v.progressBar, children: /* @__PURE__ */ i(
2860
+ "div",
2861
+ {
2862
+ style: {
2863
+ ...v.progressFill,
2864
+ width: `${b}%`,
2865
+ backgroundColor: b >= 100 ? "#4caf50" : "#1976d2"
2866
+ }
2867
+ }
2868
+ ) })
2869
+ ] }, f.id);
2870
+ })
2871
+ ] }),
2872
+ /* @__PURE__ */ o("div", { style: v.card, children: [
2873
+ /* @__PURE__ */ i("div", { style: v.cardTitle, children: "Active Goals" }),
2874
+ g.length === 0 ? /* @__PURE__ */ i("div", { style: { color: "#999", textAlign: "center", padding: "20px" }, children: "No active goals" }) : g.slice(0, 4).map((f) => /* @__PURE__ */ o("div", { style: { marginBottom: "16px" }, children: [
2875
+ /* @__PURE__ */ o(
2876
+ "div",
2877
+ {
2878
+ style: {
2879
+ display: "flex",
2880
+ justifyContent: "space-between",
2881
+ marginBottom: "4px"
2882
+ },
2883
+ children: [
2884
+ /* @__PURE__ */ i("span", { style: { fontWeight: 500 }, children: f.title }),
2885
+ /* @__PURE__ */ o("span", { style: { color: "#666" }, children: [
2886
+ f.progress,
2887
+ "%"
2888
+ ] })
2889
+ ]
2890
+ }
2891
+ ),
2892
+ /* @__PURE__ */ i("div", { style: v.progressBar, children: /* @__PURE__ */ i(
2893
+ "div",
2894
+ {
2895
+ style: {
2896
+ ...v.progressFill,
2897
+ width: `${f.progress}%`,
2898
+ backgroundColor: "#ff9800"
2899
+ }
2900
+ }
2901
+ ) }),
2902
+ /* @__PURE__ */ o("div", { style: { fontSize: "12px", color: "#999", marginTop: "4px" }, children: [
2903
+ "Due: ",
2904
+ new Date(f.targetDate).toLocaleDateString()
2905
+ ] })
2906
+ ] }, f.id))
2907
+ ] }),
2908
+ /* @__PURE__ */ o("div", { style: v.card, children: [
2909
+ /* @__PURE__ */ i("div", { style: v.cardTitle, children: "Today's Habits" }),
2910
+ c.length === 0 ? /* @__PURE__ */ i("div", { style: { color: "#999", textAlign: "center", padding: "20px" }, children: "No habits tracked yet" }) : c.map(({ habit: f, completed: b, count: D }) => /* @__PURE__ */ o("div", { style: v.habitItem, children: [
2911
+ /* @__PURE__ */ i(
2912
+ "div",
2913
+ {
2914
+ style: {
2915
+ ...v.habitCheck,
2916
+ backgroundColor: b ? "#4caf50" : "transparent",
2917
+ borderColor: b ? "#4caf50" : "#ccc"
2918
+ },
2919
+ onClick: () => {
2920
+ a.completeHabit(f.id), r();
2921
+ },
2922
+ children: b && /* @__PURE__ */ i("span", { style: { color: "#fff" }, children: "✓" })
2923
+ }
2924
+ ),
2925
+ /* @__PURE__ */ o("div", { style: { flex: 1 }, children: [
2926
+ /* @__PURE__ */ i("div", { style: { fontWeight: 500 }, children: f.name }),
2927
+ /* @__PURE__ */ o("div", { style: { fontSize: "12px", color: "#666" }, children: [
2928
+ D,
2929
+ "/",
2930
+ f.targetPerPeriod,
2931
+ " • ",
2932
+ f.streak,
2933
+ " day streak"
2934
+ ] })
2935
+ ] })
2936
+ ] }, f.id))
2937
+ ] }),
2938
+ /* @__PURE__ */ o("div", { style: v.card, children: [
2939
+ /* @__PURE__ */ i("div", { style: v.cardTitle, children: "Finance Overview" }),
2940
+ /* @__PURE__ */ o("div", { style: v.statRow, children: [
2941
+ /* @__PURE__ */ i("span", { children: "Net Worth" }),
2942
+ /* @__PURE__ */ i("span", { style: { fontWeight: 600 }, children: y(u.netWorth) })
2943
+ ] }),
2944
+ /* @__PURE__ */ o("div", { style: v.statRow, children: [
2945
+ /* @__PURE__ */ i("span", { children: "Monthly Income" }),
2946
+ /* @__PURE__ */ i("span", { style: { color: "#4caf50" }, children: y(u.monthlyIncome) })
2947
+ ] }),
2948
+ /* @__PURE__ */ o("div", { style: v.statRow, children: [
2949
+ /* @__PURE__ */ i("span", { children: "Monthly Expenses" }),
2950
+ /* @__PURE__ */ i("span", { style: { color: "#f44336" }, children: y(u.monthlyExpenses) })
2951
+ ] }),
2952
+ /* @__PURE__ */ o("div", { style: v.statRow, children: [
2953
+ /* @__PURE__ */ i("span", { children: "Savings Rate" }),
2954
+ /* @__PURE__ */ o("span", { children: [
2955
+ u.savingsRate.toFixed(1),
2956
+ "%"
2957
+ ] })
2958
+ ] }),
2959
+ /* @__PURE__ */ o("div", { style: { marginTop: "16px" }, children: [
2960
+ /* @__PURE__ */ o(
2961
+ "div",
2962
+ {
2963
+ style: { display: "flex", justifyContent: "space-between", marginBottom: "8px" },
2964
+ children: [
2965
+ /* @__PURE__ */ i("span", { children: "Finance Health" }),
2966
+ /* @__PURE__ */ o("span", { style: { fontWeight: 600 }, children: [
2967
+ p.score,
2968
+ "/100"
2969
+ ] })
2970
+ ]
2971
+ }
2972
+ ),
2973
+ /* @__PURE__ */ i("div", { style: v.progressBar, children: /* @__PURE__ */ i(
2974
+ "div",
2975
+ {
2976
+ style: {
2977
+ ...v.progressFill,
2978
+ width: `${p.score}%`,
2979
+ backgroundColor: p.score >= 70 ? "#4caf50" : p.score >= 40 ? "#ff9800" : "#f44336"
2980
+ }
2981
+ }
2982
+ ) })
2983
+ ] })
2984
+ ] }),
2985
+ /* @__PURE__ */ o("div", { style: v.card, children: [
2986
+ /* @__PURE__ */ i("div", { style: v.cardTitle, children: "Mood & Health" }),
2987
+ /* @__PURE__ */ o("div", { style: { display: "flex", justifyContent: "space-around", marginBottom: "20px" }, children: [
2988
+ /* @__PURE__ */ o("div", { style: { textAlign: "center" }, children: [
2989
+ /* @__PURE__ */ i("div", { style: v.moodEmoji, children: xe(Math.round(a.getAverageMood(7))) }),
2990
+ /* @__PURE__ */ i("div", { style: { fontSize: "12px", color: "#666" }, children: "Avg Mood (7d)" })
2991
+ ] }),
2992
+ /* @__PURE__ */ o("div", { style: { textAlign: "center" }, children: [
2993
+ /* @__PURE__ */ o("div", { style: { fontSize: "28px", fontWeight: 600 }, children: [
2994
+ a.getAverageSleep(7).toFixed(1),
2995
+ "h"
2996
+ ] }),
2997
+ /* @__PURE__ */ i("div", { style: { fontSize: "12px", color: "#666" }, children: "Avg Sleep (7d)" })
2998
+ ] })
2999
+ ] }),
3000
+ a.getMoodCorrelations().slice(0, 2).map((f) => /* @__PURE__ */ o("div", { style: v.statRow, children: [
3001
+ /* @__PURE__ */ i("span", { children: f.factor }),
3002
+ /* @__PURE__ */ o("span", { style: { color: f.correlation > 0 ? "#4caf50" : "#f44336" }, children: [
3003
+ f.correlation > 0 ? "↑" : "↓",
3004
+ " ",
3005
+ Math.abs(f.correlation * 100).toFixed(0),
3006
+ "%"
3007
+ ] })
3008
+ ] }, f.factor))
3009
+ ] })
3010
+ ] })
3011
+ ] }) });
3012
+ }
3013
+ function xe(a) {
3014
+ return {
3015
+ 1: "😢",
3016
+ 2: "😕",
3017
+ 3: "😐",
3018
+ 4: "😊",
3019
+ 5: "😄"
3020
+ }[a] || "😐";
3021
+ }
3022
+ const be = {
3023
+ colors: {
3024
+ background: "#1a1a2e",
3025
+ surface: "#16213e",
3026
+ primary: "#0f3460",
3027
+ secondary: "#e94560",
3028
+ success: "#00c853",
3029
+ warning: "#ffab00",
3030
+ error: "#ff1744",
3031
+ text: "#ffffff",
3032
+ textSecondary: "#a0a0a0",
3033
+ border: "#2a2a4a"
3034
+ },
3035
+ spacing: {
3036
+ xs: "4px",
3037
+ sm: "8px",
3038
+ md: "16px",
3039
+ lg: "24px",
3040
+ xl: "32px"
3041
+ },
3042
+ borderRadius: "8px",
3043
+ fontFamily: "'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif"
3044
+ }, ve = [
3045
+ { id: "name", label: "Name", sortable: !0, visible: !0 },
3046
+ { id: "size", label: "Size", width: "100px", sortable: !0, visible: !0 },
3047
+ { id: "progress", label: "Progress", width: "150px", sortable: !0, visible: !0 },
3048
+ { id: "status", label: "Status", width: "100px", sortable: !0, visible: !0 },
3049
+ { id: "seeds", label: "Seeds", width: "80px", sortable: !0, visible: !0 },
3050
+ { id: "peers", label: "Peers", width: "80px", sortable: !0, visible: !0 },
3051
+ { id: "downloadSpeed", label: "Down", width: "100px", sortable: !0, visible: !0 },
3052
+ { id: "uploadSpeed", label: "Up", width: "100px", sortable: !0, visible: !0 },
3053
+ { id: "eta", label: "ETA", width: "100px", sortable: !0, visible: !0 },
3054
+ { id: "ratio", label: "Ratio", width: "80px", sortable: !0, visible: !0 }
3055
+ ], G = F(null);
3056
+ function C() {
3057
+ const a = W(G);
3058
+ if (!a)
3059
+ throw new Error("useTorrentUI must be used within TorrentUIProvider");
3060
+ return a;
3061
+ }
3062
+ function R(a, e = 2) {
3063
+ if (a === 0)
3064
+ return "0 B";
3065
+ const t = 1024, n = ["B", "KB", "MB", "GB", "TB", "PB"], r = Math.floor(Math.log(a) / Math.log(t));
3066
+ return `${parseFloat((a / Math.pow(t, r)).toFixed(e))} ${n[r]}`;
3067
+ }
3068
+ function U(a) {
3069
+ return `${R(a)}/s`;
3070
+ }
3071
+ function we(a) {
3072
+ if (!a || a <= 0)
3073
+ return "∞";
3074
+ if (a < 60)
3075
+ return `${a}s`;
3076
+ if (a < 3600)
3077
+ return `${Math.floor(a / 60)}m`;
3078
+ if (a < 86400) {
3079
+ const n = Math.floor(a / 3600), r = Math.floor(a % 3600 / 60);
3080
+ return `${n}h ${r}m`;
3081
+ }
3082
+ const e = Math.floor(a / 86400), t = Math.floor(a % 86400 / 3600);
3083
+ return `${e}d ${t}h`;
3084
+ }
3085
+ function q(a) {
3086
+ return a.toFixed(2);
3087
+ }
3088
+ function K(a, e) {
3089
+ switch (a) {
3090
+ case "downloading":
3091
+ return e.colors.primary;
3092
+ case "seeding":
3093
+ return e.colors.success;
3094
+ case "paused":
3095
+ return e.colors.textSecondary;
3096
+ case "checking":
3097
+ return e.colors.warning;
3098
+ case "error":
3099
+ return e.colors.error;
3100
+ case "queued":
3101
+ return e.colors.textSecondary;
3102
+ default:
3103
+ return e.colors.text;
3104
+ }
3105
+ }
3106
+ function ke({
3107
+ client: a,
3108
+ config: e = {},
3109
+ children: t
3110
+ }) {
3111
+ const n = z(
3112
+ () => ({ ...be, ...e.theme }),
3113
+ [e.theme]
3114
+ ), [r, s] = S([]), [l, d] = S(null), [c, g] = S("all"), [u, p] = S(""), y = L(() => {
3115
+ s(a.getAllTorrents());
3116
+ }, [a]);
3117
+ X(() => {
3118
+ y();
3119
+ const b = setInterval(y, e.refreshInterval || 1e3), D = () => y(), M = () => y();
3120
+ return a.on("torrent_added", D), a.on("torrent_removed", M), () => {
3121
+ clearInterval(b), a.off("torrent_added", D), a.off("torrent_removed", M);
3122
+ };
3123
+ }, [a, e.refreshInterval, y]);
3124
+ const f = {
3125
+ client: a,
3126
+ config: e,
3127
+ theme: n,
3128
+ torrents: r,
3129
+ selectedTorrent: l,
3130
+ setSelectedTorrent: d,
3131
+ filter: c,
3132
+ setFilter: g,
3133
+ searchQuery: u,
3134
+ setSearchQuery: p,
3135
+ refresh: y
3136
+ };
3137
+ return /* @__PURE__ */ i(G.Provider, { value: f, children: /* @__PURE__ */ i("div", { style: { fontFamily: n.fontFamily, color: n.colors.text }, children: t }) });
3138
+ }
3139
+ function Se({
3140
+ progress: a,
3141
+ status: e,
3142
+ showLabel: t = !0,
3143
+ height: n = "20px",
3144
+ className: r,
3145
+ style: s
3146
+ }) {
3147
+ const { theme: l } = C(), d = Math.min(100, Math.max(0, a * 100)), c = K(e, l);
3148
+ return /* @__PURE__ */ o(
3149
+ "div",
3150
+ {
3151
+ className: r,
3152
+ style: {
3153
+ display: "flex",
3154
+ alignItems: "center",
3155
+ gap: l.spacing.sm,
3156
+ ...s
3157
+ },
3158
+ children: [
3159
+ /* @__PURE__ */ i(
3160
+ "div",
3161
+ {
3162
+ style: {
3163
+ flex: 1,
3164
+ height: n,
3165
+ backgroundColor: l.colors.border,
3166
+ borderRadius: l.borderRadius,
3167
+ overflow: "hidden"
3168
+ },
3169
+ children: /* @__PURE__ */ i(
3170
+ "div",
3171
+ {
3172
+ style: {
3173
+ width: `${d}%`,
3174
+ height: "100%",
3175
+ backgroundColor: c,
3176
+ transition: "width 0.3s ease-in-out"
3177
+ }
3178
+ }
3179
+ )
3180
+ }
3181
+ ),
3182
+ t && /* @__PURE__ */ o("span", { style: { fontSize: "12px", minWidth: "45px", textAlign: "right" }, children: [
3183
+ d.toFixed(1),
3184
+ "%"
3185
+ ] })
3186
+ ]
3187
+ }
3188
+ );
3189
+ }
3190
+ function Te({ status: a, className: e, style: t }) {
3191
+ const { theme: n } = C(), r = K(a, n), s = {
3192
+ downloading: "Downloading",
3193
+ seeding: "Seeding",
3194
+ paused: "Paused",
3195
+ checking: "Checking",
3196
+ error: "Error",
3197
+ queued: "Queued"
3198
+ };
3199
+ return /* @__PURE__ */ o(
3200
+ "span",
3201
+ {
3202
+ className: e,
3203
+ style: {
3204
+ display: "inline-flex",
3205
+ alignItems: "center",
3206
+ gap: n.spacing.xs,
3207
+ padding: `${n.spacing.xs} ${n.spacing.sm}`,
3208
+ backgroundColor: `${r}20`,
3209
+ color: r,
3210
+ borderRadius: n.borderRadius,
3211
+ fontSize: "12px",
3212
+ fontWeight: 500,
3213
+ textTransform: "capitalize",
3214
+ ...t
3215
+ },
3216
+ children: [
3217
+ /* @__PURE__ */ i(
3218
+ "span",
3219
+ {
3220
+ style: {
3221
+ width: "8px",
3222
+ height: "8px",
3223
+ borderRadius: "50%",
3224
+ backgroundColor: r
3225
+ }
3226
+ }
3227
+ ),
3228
+ s[a]
3229
+ ]
3230
+ }
3231
+ );
3232
+ }
3233
+ function De({
3234
+ onTorrentSelect: a,
3235
+ onTorrentDoubleClick: e,
3236
+ className: t,
3237
+ style: n
3238
+ }) {
3239
+ const { theme: r, torrents: s, filter: l, searchQuery: d, selectedTorrent: c, setSelectedTorrent: g, config: u } = C(), [p, y] = S(u.defaultSortBy || "name"), [f, b] = S(u.defaultSortOrder || "asc"), D = u.columns || ve, M = z(() => s.filter((x) => {
3240
+ if (l !== "all") {
3241
+ if (l === "completed") {
3242
+ if (x.stats.progress < 1)
3243
+ return !1;
3244
+ } else if (l === "active") {
3245
+ if (x.status !== "downloading" && x.status !== "seeding")
3246
+ return !1;
3247
+ } else if (x.status !== l)
3248
+ return !1;
3249
+ }
3250
+ if (d) {
3251
+ const A = d.toLowerCase();
3252
+ if (!x.metadata.name.toLowerCase().includes(A))
3253
+ return !1;
3254
+ }
3255
+ return !0;
3256
+ }), [s, l, d]), T = z(() => [...M].sort((x, A) => {
3257
+ let I, B;
3258
+ switch (p) {
3259
+ case "name":
3260
+ I = x.metadata.name.toLowerCase(), B = A.metadata.name.toLowerCase();
3261
+ break;
3262
+ case "size":
3263
+ I = x.metadata.size, B = A.metadata.size;
3264
+ break;
3265
+ case "progress":
3266
+ I = x.stats.progress, B = A.stats.progress;
3267
+ break;
3268
+ case "status":
3269
+ I = x.status, B = A.status;
3270
+ break;
3271
+ case "downloadSpeed":
3272
+ I = x.stats.downloadSpeed, B = A.stats.downloadSpeed;
3273
+ break;
3274
+ case "uploadSpeed":
3275
+ I = x.stats.uploadSpeed, B = A.stats.uploadSpeed;
3276
+ break;
3277
+ case "ratio":
3278
+ I = x.stats.ratio, B = A.stats.ratio;
3279
+ break;
3280
+ default:
3281
+ I = x.metadata.name, B = A.metadata.name;
3282
+ }
3283
+ return I < B ? f === "asc" ? -1 : 1 : I > B ? f === "asc" ? 1 : -1 : 0;
3284
+ }), [M, p, f]), P = (x) => {
3285
+ p === x ? b(f === "asc" ? "desc" : "asc") : (y(x), b("asc"));
3286
+ }, Q = (x) => {
3287
+ g(x), a == null || a(x);
3288
+ };
3289
+ return /* @__PURE__ */ o(
3290
+ "div",
3291
+ {
3292
+ className: t,
3293
+ style: {
3294
+ backgroundColor: r.colors.surface,
3295
+ borderRadius: r.borderRadius,
3296
+ overflow: "hidden",
3297
+ ...n
3298
+ },
3299
+ children: [
3300
+ /* @__PURE__ */ i(
3301
+ "div",
3302
+ {
3303
+ style: {
3304
+ display: "grid",
3305
+ gridTemplateColumns: D.filter((x) => x.visible !== !1).map((x) => x.width || "1fr").join(" "),
3306
+ padding: `${r.spacing.sm} ${r.spacing.md}`,
3307
+ backgroundColor: r.colors.primary,
3308
+ borderBottom: `1px solid ${r.colors.border}`,
3309
+ fontSize: "12px",
3310
+ fontWeight: 600,
3311
+ textTransform: "uppercase"
3312
+ },
3313
+ children: D.filter((x) => x.visible !== !1).map((x) => /* @__PURE__ */ o(
3314
+ "div",
3315
+ {
3316
+ onClick: () => x.sortable && P(x.id),
3317
+ style: {
3318
+ cursor: x.sortable ? "pointer" : "default",
3319
+ display: "flex",
3320
+ alignItems: "center",
3321
+ gap: r.spacing.xs
3322
+ },
3323
+ children: [
3324
+ x.label,
3325
+ p === x.id && /* @__PURE__ */ i("span", { children: f === "asc" ? "↑" : "↓" })
3326
+ ]
3327
+ },
3328
+ x.id
3329
+ ))
3330
+ }
3331
+ ),
3332
+ /* @__PURE__ */ i("div", { style: { maxHeight: "500px", overflowY: "auto" }, children: T.length === 0 ? /* @__PURE__ */ i(
3333
+ "div",
3334
+ {
3335
+ style: {
3336
+ padding: r.spacing.xl,
3337
+ textAlign: "center",
3338
+ color: r.colors.textSecondary
3339
+ },
3340
+ children: "No torrents found"
3341
+ }
3342
+ ) : T.map((x) => /* @__PURE__ */ i(
3343
+ Ce,
3344
+ {
3345
+ torrent: x,
3346
+ columns: D,
3347
+ isSelected: c === x.metadata.infoHash,
3348
+ onClick: () => Q(x.metadata.infoHash),
3349
+ onDoubleClick: () => e == null ? void 0 : e(x.metadata.infoHash)
3350
+ },
3351
+ x.metadata.infoHash
3352
+ )) })
3353
+ ]
3354
+ }
3355
+ );
3356
+ }
3357
+ function Ce({
3358
+ torrent: a,
3359
+ columns: e,
3360
+ isSelected: t,
3361
+ onClick: n,
3362
+ onDoubleClick: r
3363
+ }) {
3364
+ const { theme: s } = C(), { metadata: l, stats: d, status: c } = a, g = (u) => {
3365
+ switch (u) {
3366
+ case "name":
3367
+ return /* @__PURE__ */ o("div", { style: { display: "flex", flexDirection: "column" }, children: [
3368
+ /* @__PURE__ */ i("span", { style: { fontWeight: 500 }, children: l.name }),
3369
+ /* @__PURE__ */ o("span", { style: { fontSize: "11px", color: s.colors.textSecondary }, children: [
3370
+ l.infoHash.substring(0, 8),
3371
+ "..."
3372
+ ] })
3373
+ ] });
3374
+ case "size":
3375
+ return R(l.size);
3376
+ case "progress":
3377
+ return /* @__PURE__ */ i(Se, { progress: d.progress, status: c, height: "16px" });
3378
+ case "status":
3379
+ return /* @__PURE__ */ i(Te, { status: c });
3380
+ case "seeds":
3381
+ return d.seeds;
3382
+ case "peers":
3383
+ return d.peers;
3384
+ case "downloadSpeed":
3385
+ return d.downloadSpeed > 0 ? U(d.downloadSpeed) : "-";
3386
+ case "uploadSpeed":
3387
+ return d.uploadSpeed > 0 ? U(d.uploadSpeed) : "-";
3388
+ case "eta":
3389
+ return c === "downloading" ? we(d.eta) : "-";
3390
+ case "ratio":
3391
+ return q(d.ratio);
3392
+ default:
3393
+ return "-";
3394
+ }
3395
+ };
3396
+ return /* @__PURE__ */ i(
3397
+ "div",
3398
+ {
3399
+ onClick: n,
3400
+ onDoubleClick: r,
3401
+ style: {
3402
+ display: "grid",
3403
+ gridTemplateColumns: e.filter((u) => u.visible !== !1).map((u) => u.width || "1fr").join(" "),
3404
+ padding: `${s.spacing.sm} ${s.spacing.md}`,
3405
+ backgroundColor: t ? s.colors.primary : "transparent",
3406
+ borderBottom: `1px solid ${s.colors.border}`,
3407
+ cursor: "pointer",
3408
+ transition: "background-color 0.15s",
3409
+ fontSize: "13px"
3410
+ },
3411
+ children: e.filter((u) => u.visible !== !1).map((u) => /* @__PURE__ */ i(
3412
+ "div",
3413
+ {
3414
+ style: {
3415
+ display: "flex",
3416
+ alignItems: "center",
3417
+ overflow: "hidden",
3418
+ textOverflow: "ellipsis",
3419
+ whiteSpace: "nowrap"
3420
+ },
3421
+ children: g(u.id)
3422
+ },
3423
+ u.id
3424
+ ))
3425
+ }
3426
+ );
3427
+ }
3428
+ function Ae({ className: a, style: e }) {
3429
+ const { theme: t, filter: n, setFilter: r, searchQuery: s, setSearchQuery: l, torrents: d } = C(), c = z(() => {
3430
+ const u = {
3431
+ all: d.length,
3432
+ downloading: 0,
3433
+ seeding: 0,
3434
+ paused: 0,
3435
+ checking: 0,
3436
+ error: 0,
3437
+ completed: 0,
3438
+ active: 0
3439
+ };
3440
+ for (const p of d)
3441
+ p.status === "downloading" && u.downloading++, p.status === "seeding" && u.seeding++, p.status === "paused" && u.paused++, p.status === "checking" && u.checking++, p.status === "error" && u.error++, p.stats.progress >= 1 && u.completed++, (p.status === "downloading" || p.status === "seeding") && u.active++;
3442
+ return u;
3443
+ }, [d]), g = [
3444
+ { id: "all", label: "All" },
3445
+ { id: "downloading", label: "Downloading" },
3446
+ { id: "seeding", label: "Seeding" },
3447
+ { id: "completed", label: "Completed" },
3448
+ { id: "active", label: "Active" },
3449
+ { id: "paused", label: "Paused" },
3450
+ { id: "error", label: "Error" }
3451
+ ];
3452
+ return /* @__PURE__ */ o(
3453
+ "div",
3454
+ {
3455
+ className: a,
3456
+ style: {
3457
+ display: "flex",
3458
+ alignItems: "center",
3459
+ gap: t.spacing.md,
3460
+ padding: t.spacing.md,
3461
+ backgroundColor: t.colors.surface,
3462
+ borderRadius: t.borderRadius,
3463
+ ...e
3464
+ },
3465
+ children: [
3466
+ /* @__PURE__ */ i("div", { style: { display: "flex", gap: t.spacing.xs }, children: g.map((u) => /* @__PURE__ */ o(
3467
+ "button",
3468
+ {
3469
+ onClick: () => r(u.id),
3470
+ style: {
3471
+ padding: `${t.spacing.xs} ${t.spacing.sm}`,
3472
+ backgroundColor: n === u.id ? t.colors.primary : "transparent",
3473
+ color: n === u.id ? t.colors.text : t.colors.textSecondary,
3474
+ border: "none",
3475
+ borderRadius: t.borderRadius,
3476
+ cursor: "pointer",
3477
+ fontSize: "13px",
3478
+ transition: "all 0.15s"
3479
+ },
3480
+ children: [
3481
+ u.label,
3482
+ " (",
3483
+ c[u.id],
3484
+ ")"
3485
+ ]
3486
+ },
3487
+ u.id
3488
+ )) }),
3489
+ /* @__PURE__ */ i("div", { style: { flex: 1 } }),
3490
+ /* @__PURE__ */ i(
3491
+ "input",
3492
+ {
3493
+ type: "text",
3494
+ placeholder: "Search torrents...",
3495
+ value: s,
3496
+ onChange: (u) => l(u.target.value),
3497
+ style: {
3498
+ padding: `${t.spacing.sm} ${t.spacing.md}`,
3499
+ backgroundColor: t.colors.background,
3500
+ color: t.colors.text,
3501
+ border: `1px solid ${t.colors.border}`,
3502
+ borderRadius: t.borderRadius,
3503
+ outline: "none",
3504
+ fontSize: "13px",
3505
+ width: "250px"
3506
+ }
3507
+ }
3508
+ )
3509
+ ]
3510
+ }
3511
+ );
3512
+ }
3513
+ function Ie({
3514
+ infoHash: a,
3515
+ className: e,
3516
+ style: t
3517
+ }) {
3518
+ const { theme: n, client: r } = C(), [s, l] = S("files"), d = r == null ? void 0 : r.getTorrent(a);
3519
+ if (!d)
3520
+ return null;
3521
+ const { metadata: c, stats: g, files: u, peers: p, trackers: y } = d, f = [
3522
+ { id: "files", label: `Files (${u.length})` },
3523
+ { id: "peers", label: `Peers (${p.length})` },
3524
+ { id: "trackers", label: `Trackers (${y.length})` },
3525
+ { id: "info", label: "Info" }
3526
+ ];
3527
+ return /* @__PURE__ */ o(
3528
+ "div",
3529
+ {
3530
+ className: e,
3531
+ style: {
3532
+ backgroundColor: n.colors.surface,
3533
+ borderRadius: n.borderRadius,
3534
+ overflow: "hidden",
3535
+ ...t
3536
+ },
3537
+ children: [
3538
+ /* @__PURE__ */ i(
3539
+ "div",
3540
+ {
3541
+ style: {
3542
+ display: "flex",
3543
+ borderBottom: `1px solid ${n.colors.border}`
3544
+ },
3545
+ children: f.map((b) => /* @__PURE__ */ i(
3546
+ "button",
3547
+ {
3548
+ onClick: () => l(b.id),
3549
+ style: {
3550
+ padding: `${n.spacing.sm} ${n.spacing.md}`,
3551
+ backgroundColor: s === b.id ? n.colors.primary : "transparent",
3552
+ color: s === b.id ? n.colors.text : n.colors.textSecondary,
3553
+ border: "none",
3554
+ cursor: "pointer",
3555
+ fontSize: "13px",
3556
+ fontWeight: 500
3557
+ },
3558
+ children: b.label
3559
+ },
3560
+ b.id
3561
+ ))
3562
+ }
3563
+ ),
3564
+ /* @__PURE__ */ o("div", { style: { padding: n.spacing.md, maxHeight: "300px", overflowY: "auto" }, children: [
3565
+ s === "files" && /* @__PURE__ */ i(Be, { files: u }),
3566
+ s === "peers" && /* @__PURE__ */ i(Me, { peers: p }),
3567
+ s === "trackers" && /* @__PURE__ */ i(Re, { trackers: y }),
3568
+ s === "info" && /* @__PURE__ */ i(Pe, { metadata: c, stats: g, addedAt: d.addedAt })
3569
+ ] })
3570
+ ]
3571
+ }
3572
+ );
3573
+ }
3574
+ function Be({ files: a }) {
3575
+ const { theme: e } = C();
3576
+ return /* @__PURE__ */ i("div", { style: { display: "flex", flexDirection: "column", gap: e.spacing.xs }, children: a.map((t, n) => /* @__PURE__ */ o(
3577
+ "div",
3578
+ {
3579
+ style: {
3580
+ display: "flex",
3581
+ alignItems: "center",
3582
+ gap: e.spacing.md,
3583
+ padding: e.spacing.sm,
3584
+ backgroundColor: e.colors.background,
3585
+ borderRadius: e.borderRadius,
3586
+ fontSize: "13px"
3587
+ },
3588
+ children: [
3589
+ /* @__PURE__ */ i("span", { style: { flex: 1, overflow: "hidden", textOverflow: "ellipsis" }, children: t.path }),
3590
+ /* @__PURE__ */ i("span", { style: { color: e.colors.textSecondary }, children: R(t.size) }),
3591
+ /* @__PURE__ */ o("span", { style: { width: "50px", textAlign: "right" }, children: [
3592
+ (t.progress * 100).toFixed(0),
3593
+ "%"
3594
+ ] })
3595
+ ]
3596
+ },
3597
+ n
3598
+ )) });
3599
+ }
3600
+ function Me({ peers: a }) {
3601
+ const { theme: e } = C();
3602
+ return /* @__PURE__ */ i("div", { style: { display: "flex", flexDirection: "column", gap: e.spacing.xs }, children: a.length === 0 ? /* @__PURE__ */ i("div", { style: { color: e.colors.textSecondary }, children: "No peers connected" }) : a.map((t) => /* @__PURE__ */ o(
3603
+ "div",
3604
+ {
3605
+ style: {
3606
+ display: "grid",
3607
+ gridTemplateColumns: "1fr 80px 100px 100px 80px",
3608
+ alignItems: "center",
3609
+ padding: e.spacing.sm,
3610
+ backgroundColor: e.colors.background,
3611
+ borderRadius: e.borderRadius,
3612
+ fontSize: "12px"
3613
+ },
3614
+ children: [
3615
+ /* @__PURE__ */ o("span", { children: [
3616
+ t.ip,
3617
+ ":",
3618
+ t.port,
3619
+ t.isUTP && /* @__PURE__ */ i("span", { style: { marginLeft: "4px", color: e.colors.secondary }, children: "µTP" }),
3620
+ t.isEncrypted && /* @__PURE__ */ i("span", { style: { marginLeft: "4px" }, children: "🔒" })
3621
+ ] }),
3622
+ /* @__PURE__ */ i("span", { style: { color: e.colors.textSecondary }, children: t.client || "Unknown" }),
3623
+ /* @__PURE__ */ o("span", { style: { color: e.colors.success }, children: [
3624
+ "↓ ",
3625
+ U(t.downloadSpeed)
3626
+ ] }),
3627
+ /* @__PURE__ */ o("span", { style: { color: e.colors.warning }, children: [
3628
+ "↑ ",
3629
+ U(t.uploadSpeed)
3630
+ ] }),
3631
+ /* @__PURE__ */ o("span", { children: [
3632
+ (t.progress * 100).toFixed(0),
3633
+ "%"
3634
+ ] })
3635
+ ]
3636
+ },
3637
+ t.id
3638
+ )) });
3639
+ }
3640
+ function Re({ trackers: a }) {
3641
+ const { theme: e } = C();
3642
+ return /* @__PURE__ */ i("div", { style: { display: "flex", flexDirection: "column", gap: e.spacing.xs }, children: a.map((t, n) => /* @__PURE__ */ o(
3643
+ "div",
3644
+ {
3645
+ style: {
3646
+ display: "flex",
3647
+ alignItems: "center",
3648
+ gap: e.spacing.md,
3649
+ padding: e.spacing.sm,
3650
+ backgroundColor: e.colors.background,
3651
+ borderRadius: e.borderRadius,
3652
+ fontSize: "12px"
3653
+ },
3654
+ children: [
3655
+ /* @__PURE__ */ i(
3656
+ "span",
3657
+ {
3658
+ style: {
3659
+ width: "8px",
3660
+ height: "8px",
3661
+ borderRadius: "50%",
3662
+ backgroundColor: t.status === "working" ? e.colors.success : t.status === "error" ? e.colors.error : e.colors.textSecondary
3663
+ }
3664
+ }
3665
+ ),
3666
+ /* @__PURE__ */ i("span", { style: { flex: 1, overflow: "hidden", textOverflow: "ellipsis" }, children: t.url }),
3667
+ /* @__PURE__ */ o("span", { style: { color: e.colors.textSecondary }, children: [
3668
+ "S: ",
3669
+ t.seeds,
3670
+ " | L: ",
3671
+ t.leechers
3672
+ ] })
3673
+ ]
3674
+ },
3675
+ n
3676
+ )) });
3677
+ }
3678
+ function Pe({
3679
+ metadata: a,
3680
+ stats: e,
3681
+ addedAt: t
3682
+ }) {
3683
+ const { theme: n } = C(), r = [
3684
+ { label: "Name", value: a.name },
3685
+ { label: "Info Hash", value: a.infoHash },
3686
+ { label: "Size", value: R(a.size) },
3687
+ { label: "Pieces", value: `${e.piecesComplete} / ${e.piecesTotal}` },
3688
+ { label: "Downloads", value: R(e.downloaded) },
3689
+ { label: "Uploaded", value: R(e.uploaded) },
3690
+ { label: "Ratio", value: q(e.ratio) },
3691
+ { label: "Availability", value: e.availability.toFixed(2) },
3692
+ { label: "Wasted", value: R(e.wastedBytes) },
3693
+ { label: "Hash Fails", value: e.hashFailures },
3694
+ { label: "Added", value: t.toLocaleString() },
3695
+ { label: "Comment", value: a.comment || "-" },
3696
+ { label: "Private", value: a.isPrivate ? "Yes" : "No" }
3697
+ ];
3698
+ return /* @__PURE__ */ i("div", { style: { display: "flex", flexDirection: "column", gap: n.spacing.xs }, children: r.map((s) => /* @__PURE__ */ o(
3699
+ "div",
3700
+ {
3701
+ style: {
3702
+ display: "flex",
3703
+ justifyContent: "space-between",
3704
+ padding: `${n.spacing.xs} ${n.spacing.sm}`,
3705
+ fontSize: "13px"
3706
+ },
3707
+ children: [
3708
+ /* @__PURE__ */ i("span", { style: { color: n.colors.textSecondary }, children: s.label }),
3709
+ /* @__PURE__ */ i("span", { style: { fontFamily: "monospace" }, children: s.value })
3710
+ ]
3711
+ },
3712
+ s.label
3713
+ )) });
3714
+ }
3715
+ function ze({
3716
+ isOpen: a,
3717
+ onClose: e,
3718
+ onAdd: t,
3719
+ className: n
3720
+ }) {
3721
+ const { theme: r, config: s, client: l } = C(), [d, c] = S(""), [g, u] = S(""), [p, y] = S(!1);
3722
+ if (!a)
3723
+ return null;
3724
+ const f = (b) => {
3725
+ b.preventDefault(), d.trim() && (t(d.trim(), { path: g || void 0, paused: p }), c(""), u(""), y(!1), e());
3726
+ };
3727
+ return /* @__PURE__ */ i(
3728
+ "div",
3729
+ {
3730
+ className: n,
3731
+ style: {
3732
+ position: "fixed",
3733
+ inset: 0,
3734
+ backgroundColor: "rgba(0,0,0,0.5)",
3735
+ display: "flex",
3736
+ alignItems: "center",
3737
+ justifyContent: "center",
3738
+ zIndex: 1e3
3739
+ },
3740
+ onClick: e,
3741
+ children: /* @__PURE__ */ o(
3742
+ "div",
3743
+ {
3744
+ style: {
3745
+ backgroundColor: r.colors.surface,
3746
+ borderRadius: r.borderRadius,
3747
+ padding: r.spacing.lg,
3748
+ width: "500px",
3749
+ maxWidth: "90vw"
3750
+ },
3751
+ onClick: (b) => b.stopPropagation(),
3752
+ children: [
3753
+ /* @__PURE__ */ i("h2", { style: { margin: 0, marginBottom: r.spacing.md }, children: "Add Torrent" }),
3754
+ /* @__PURE__ */ o(
3755
+ "form",
3756
+ {
3757
+ onSubmit: f,
3758
+ style: { display: "flex", flexDirection: "column", gap: r.spacing.md },
3759
+ children: [
3760
+ /* @__PURE__ */ o("div", { children: [
3761
+ /* @__PURE__ */ i("label", { style: { display: "block", marginBottom: r.spacing.xs, fontSize: "13px" }, children: "Magnet URI or .torrent file path" }),
3762
+ /* @__PURE__ */ i(
3763
+ "input",
3764
+ {
3765
+ type: "text",
3766
+ value: d,
3767
+ onChange: (b) => c(b.target.value),
3768
+ placeholder: "magnet:?xt=urn:btih:... or C:\\path\\to\\file.torrent",
3769
+ style: {
3770
+ width: "100%",
3771
+ padding: r.spacing.sm,
3772
+ backgroundColor: r.colors.background,
3773
+ color: r.colors.text,
3774
+ border: `1px solid ${r.colors.border}`,
3775
+ borderRadius: r.borderRadius,
3776
+ outline: "none",
3777
+ fontSize: "13px"
3778
+ }
3779
+ }
3780
+ )
3781
+ ] }),
3782
+ /* @__PURE__ */ o("div", { children: [
3783
+ /* @__PURE__ */ i("label", { style: { display: "block", marginBottom: r.spacing.xs, fontSize: "13px" }, children: "Save Location" }),
3784
+ /* @__PURE__ */ i(
3785
+ "input",
3786
+ {
3787
+ type: "text",
3788
+ value: g,
3789
+ onChange: (b) => u(b.target.value),
3790
+ placeholder: "Leave empty for default",
3791
+ style: {
3792
+ width: "100%",
3793
+ padding: r.spacing.sm,
3794
+ backgroundColor: r.colors.background,
3795
+ color: r.colors.text,
3796
+ border: `1px solid ${r.colors.border}`,
3797
+ borderRadius: r.borderRadius,
3798
+ outline: "none",
3799
+ fontSize: "13px"
3800
+ }
3801
+ }
3802
+ )
3803
+ ] }),
3804
+ /* @__PURE__ */ o(
3805
+ "label",
3806
+ {
3807
+ style: {
3808
+ display: "flex",
3809
+ alignItems: "center",
3810
+ gap: r.spacing.sm,
3811
+ fontSize: "13px"
3812
+ },
3813
+ children: [
3814
+ /* @__PURE__ */ i(
3815
+ "input",
3816
+ {
3817
+ type: "checkbox",
3818
+ checked: p,
3819
+ onChange: (b) => y(b.target.checked)
3820
+ }
3821
+ ),
3822
+ "Start paused"
3823
+ ]
3824
+ }
3825
+ ),
3826
+ /* @__PURE__ */ o("div", { style: { display: "flex", gap: r.spacing.sm, justifyContent: "flex-end" }, children: [
3827
+ /* @__PURE__ */ i(
3828
+ "button",
3829
+ {
3830
+ type: "button",
3831
+ onClick: e,
3832
+ style: {
3833
+ padding: `${r.spacing.sm} ${r.spacing.md}`,
3834
+ backgroundColor: "transparent",
3835
+ color: r.colors.text,
3836
+ border: `1px solid ${r.colors.border}`,
3837
+ borderRadius: r.borderRadius,
3838
+ cursor: "pointer"
3839
+ },
3840
+ children: "Cancel"
3841
+ }
3842
+ ),
3843
+ /* @__PURE__ */ i(
3844
+ "button",
3845
+ {
3846
+ type: "submit",
3847
+ style: {
3848
+ padding: `${r.spacing.sm} ${r.spacing.md}`,
3849
+ backgroundColor: r.colors.primary,
3850
+ color: r.colors.text,
3851
+ border: "none",
3852
+ borderRadius: r.borderRadius,
3853
+ cursor: "pointer"
3854
+ },
3855
+ children: "Add Torrent"
3856
+ }
3857
+ )
3858
+ ] })
3859
+ ]
3860
+ }
3861
+ )
3862
+ ]
3863
+ }
3864
+ )
3865
+ }
3866
+ );
3867
+ }
3868
+ function Ye({
3869
+ client: a,
3870
+ config: e,
3871
+ className: t,
3872
+ style: n
3873
+ }) {
3874
+ const [r, s] = S(!1), [l, d] = S(null);
3875
+ return /* @__PURE__ */ i(ke, { client: a, config: e, children: /* @__PURE__ */ o(
3876
+ "div",
3877
+ {
3878
+ className: t,
3879
+ style: {
3880
+ display: "flex",
3881
+ flexDirection: "column",
3882
+ gap: "16px",
3883
+ height: "100%",
3884
+ ...n
3885
+ },
3886
+ children: [
3887
+ /* @__PURE__ */ i("div", { style: { display: "flex", gap: "8px" }, children: /* @__PURE__ */ i(
3888
+ "button",
3889
+ {
3890
+ onClick: () => s(!0),
3891
+ style: {
3892
+ padding: "8px 16px",
3893
+ backgroundColor: "#0f3460",
3894
+ color: "white",
3895
+ border: "none",
3896
+ borderRadius: "8px",
3897
+ cursor: "pointer"
3898
+ },
3899
+ children: "+ Add Torrent"
3900
+ }
3901
+ ) }),
3902
+ /* @__PURE__ */ i(Ae, {}),
3903
+ /* @__PURE__ */ i(De, { onTorrentSelect: d, style: { flex: 1 } }),
3904
+ l && /* @__PURE__ */ i(Ie, { infoHash: l }),
3905
+ /* @__PURE__ */ i(
3906
+ ze,
3907
+ {
3908
+ isOpen: r,
3909
+ onClose: () => s(!1),
3910
+ onAdd: (c, g) => a.addTorrent(c, g)
3911
+ }
3912
+ )
3913
+ ]
3914
+ }
3915
+ ) });
3916
+ }
3917
+ export {
3918
+ ze as AddTorrentDialog,
3919
+ Ae as FilterBar,
3920
+ Z as HealthService,
3921
+ ye as LifeDashboardService,
3922
+ He as NiceHealth,
3923
+ Qe as NiceLifeDashboard,
3924
+ Ee as NicePersonalFinance,
3925
+ Ge as NiceTaskManager,
3926
+ Ye as NiceTorrentUI,
3927
+ ae as PersonalFinanceService,
3928
+ Se as ProgressBar,
3929
+ Te as StatusBadge,
3930
+ pe as TaskManagerService,
3931
+ Ie as TorrentDetails,
3932
+ De as TorrentList,
3933
+ ke as TorrentUIProvider,
3934
+ Ue as createHealthService,
3935
+ qe as createLifeDashboardService,
3936
+ Ne as createPersonalFinanceService,
3937
+ Ve as createTaskManagerService,
3938
+ R as formatBytes,
3939
+ we as formatETA,
3940
+ q as formatRatio,
3941
+ U as formatSpeed,
3942
+ K as getStatusColor,
3943
+ je as useHealth,
3944
+ Ke as useLifeDashboard,
3945
+ $e as usePersonalFinance,
3946
+ Oe as useTaskManager,
3947
+ C as useTorrentUI
3948
+ };