PageSourceSearch

https://www.hamienet.com/assets/PersonalSpacePage-CP7O48ZA.js

js hamienet.com collected 2026-10-02 05:00:07 UTC 22,899 bytes, 296 lines download raw bytes

1import { r as reactExports, j as jsxRuntimeExports } from "./vendor-react-Bay9Y7Lb.js";
2import { a as api } from "./index-w5lXls15.js";
3import { i as isPro } from "./utils-CEVb7nN1.js";
4import { u as useTranslation } from "./vendor-i18n-BC7ZMXWQ.js";
5import { b6 as LoaderCircle, cK as ShieldAlert, bB as ListMusic, bM as Clock, bd as Heart, dh as SlidersVertical, bi as Sparkles, cn as ArrowRight, b5 as Trash2, b7 as Check, e7 as Lock } from "./vendor-D0P4XgNj.js";
6function PersonalSpacePage({ currentUser, onNavigate }) {
7  var _a, _b, _c;
8  const { t } = useTranslation();
9  const [loading, setLoading] = reactExports.useState(true);
10  const [error, setError] = reactExports.useState(null);
11  const [limitsData, setLimitsData] = reactExports.useState(null);
12  const [digitizerProjects, setDigitizerProjects] = reactExports.useState([]);
13  const [loadingProjects, setLoadingProjects] = reactExports.useState(true);
14  reactExports.useEffect(() => {
15    const fetchLimits = async () => {
16      try {
17        setLoading(true);
18        const data = await api.getUserLimits(currentUser.id);
19        setLimitsData(data);
20        setError(null);
21      } catch (err) {
22        console.error("Failed to load user limits:", err);
23        setError(err.message || "Failed to load limits data.");
24      } finally {
25        setLoading(false);
26      }
27    };
28    const fetchDigitizerProjects = async () => {
29      try {
30        const projs = await api.getDigitizerProjects();
31        setDigitizerProjects(projs);
32      } catch (err) {
33        console.error("Failed to load digitizer projects:", err);
34      } finally {
35        setLoadingProjects(false);
36      }
37    };
38    fetchLimits();
39    fetchDigitizerProjects();
40  }, [currentUser.id]);
41  if (loading) {
42    return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-col items-center justify-center min-h-[60vh] py-12 animate-in fade-in", children: [
43      /* @__PURE__ */ jsxRuntimeExports.jsx(LoaderCircle, { className: "w-10 h-10 text-indigo-500 animate-spin mb-4" }),
44      /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-zinc-500 dark:text-zinc-400 text-sm font-medium", children: t("common.loading", "Loading Personal Space...") })
45    ] });
46  }
47  if (error || !limitsData) {
48    return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "max-w-4xl mx-auto px-4 py-12 animate-in fade-in", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "bg-red-50 dark:bg-red-950/20 border border-red-200 dark:border-red-900/50 rounded-2xl p-6 text-center", children: [
49      /* @__PURE__ */ jsxRuntimeExports.jsx(ShieldAlert, { className: "w-12 h-12 text-red-500 mx-auto mb-4" }),
50      /* @__PURE__ */ jsxRuntimeExports.jsx("h3", { className: "text-lg font-bold text-zinc-900 dark:text-white mb-2", children: t("personalSpace.errorTitle", "Something went wrong") }),
51      /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-zinc-600 dark:text-zinc-400 text-sm mb-6 max-w-md mx-auto", children: error || t("personalSpace.errorDesc", "Could not load your personal space limits. Please try again.") }),
52      /* @__PURE__ */ jsxRuntimeExports.jsx(
53        "button",
54        {
55          onClick: () => window.location.reload(),
56          className: "px-6 py-2.5 bg-indigo-600 hover:bg-indigo-700 text-white rounded-xl font-semibold shadow-sm transition-all",
57          children: t("common.retry", "Retry")
58        }
59      )
60    ] }) });
61  }
62  const { usage, limits, tier } = limitsData;
63  const isUserPro = isPro(currentUser) || tier.toLowerCase() === "pro";
64  const items = [
65    {
66      name: t("personalSpace.playlists", "Playlists"),
67      icon: ListMusic,
68      count: usage.playlists,
69      limit: limits.playlists,
70      path: "playlists",
71      color: "from-blue-500 to-indigo-500",
72      bgColor: "bg-blue-500/10",
73      textColor: "text-blue-500",
74      description: t("personalSpace.playlistsDesc", "Organize your favorite MIDI tracks.")
75    },
76    {
77      name: t("personalSpace.watchLater", "Watch Later"),
78      icon: Clock,
79      count: usage.watchLater,
80      limit: limits.watchLater,
81      path: "watchLater",
82      color: "from-amber-500 to-orange-500",
83      bgColor: "bg-amber-500/10",
84      textColor: "text-amber-500",
85      description: t("personalSpace.watchLaterDesc", "Queue up tracks to check out later.")
86    },
87    {
88      name: t("personalSpace.likedTracks", "Liked Tracks"),
89      icon: Heart,
90      count: usage.likedTracks,
91      limit: limits.likedTracks,
92      path: "liked",
93      color: "from-rose-500 to-pink-500",
94      bgColor: "bg-rose-500/10",
95      textColor: "text-rose-500",
96      description: t("personalSpace.likedTracksDesc", "Tracks you saved and appreciated.")
97    },
98    {
99      name: t("personalSpace.eqSettings", "Saved EQ Settings"),
100      icon: SlidersVertical,
101      count: usage.savedEQSettingsTotal,
102      limit: limits.savedEQSettingsTotal,
103      path: null,
104      color: "from-emerald-500 to-teal-500",
105      bgColor: "bg-emerald-500/10",
106      textColor: "text-emerald-500",
107      description: `${t("personalSpace.eqSettingsDesc", "Custom equalization configurations.")} (${limits.savedEQSettingsPerTrack} ${t("personalSpace.perTrackLimit", "max per track")})`
108    }
109  ];
110  return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "max-w-5xl mx-auto px-4 py-8 animate-in fade-in duration-300", children: [
111    /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-col md:flex-row justify-between items-start md:items-center gap-4 mb-8", children: [
112      /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
113        /* @__PURE__ */ jsxRuntimeExports.jsxs("h1", { className: "text-3xl font-black tracking-tight text-zinc-950 dark:text-white flex items-center gap-3", children: [
114          /* @__PURE__ */ jsxRuntimeExports.jsx(Sparkles, { className: "w-8 h-8 text-indigo-500 animate-pulse" }),
115          t("personalSpace.title", "My Personal Space")
116        ] }),
117        /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-zinc-500 dark:text-zinc-400 mt-1.5 text-sm", children: t("personalSpace.subtitle", "Manage your saved content and monitor your account limits.") })
118      ] }),
119      /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: `flex items-center gap-2.5 px-4 py-2 rounded-xl border font-bold text-sm shadow-sm transition-all ${((_a = currentUser == null ? void 0 : currentUser.subscriptionTier) == null ? void 0 : _a.toLowerCase()) === "premium" ? "bg-gradient-to-r from-indigo-500/10 to-purple-500/10 border-indigo-300/50 dark:border-indigo-700/30 text-indigo-600 dark:text-indigo-400" : isUserPro ? "bg-gradient-to-r from-amber-500/10 to-orange-500/10 border-amber-300/50 dark:border-amber-700/30 text-amber-600 dark:text-amber-400" : "bg-zinc-100 dark:bg-zinc-800 border-zinc-200 dark:border-zinc-700 text-zinc-700 dark:text-zinc-300"}`, children: [
120        /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "shrink-0 w-2.5 h-2.5 rounded-full bg-current animate-pulse" }),
121        /* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: ((_b = currentUser == null ? void 0 : currentUser.subscriptionTier) == null ? void 0 : _b.toLowerCase()) === "premium" ? "PREMIUM SUPPORTER" : ((_c = currentUser == null ? void 0 : currentUser.subscriptionTier) == null ? void 0 : _c.toLowerCase()) === "gold" ? "GOLD SUPPORTER" : isUserPro ? (currentUser == null ? void 0 : currentUser.role) === "ADMIN" ? "ADMIN MEMBER" : "PRO SUBSCRIBER" : t("personalSpace.tierFree", "FREE MEMBER") })
122      ] })
123    ] }),
124    /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "grid grid-cols-1 lg:grid-cols-3 gap-8", children: [
125      /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "lg:col-span-2 space-y-6", children: [
126        /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "bg-white dark:bg-zinc-900 border border-zinc-200 dark:border-zinc-800 rounded-2xl p-6 shadow-sm", children: [
127          /* @__PURE__ */ jsxRuntimeExports.jsx("h2", { className: "text-lg font-bold text-zinc-950 dark:text-white mb-6", children: t("personalSpace.usageOverview", "Saved Content Limits") }),
128          /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "space-y-6", children: items.map((item, index) => {
129            const percentage = Math.min(item.count / item.limit * 100, 100);
130            const isNearLimit = percentage >= 85;
131            return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "group relative flex flex-col p-4 border border-zinc-100 dark:border-zinc-800/80 rounded-xl hover:border-zinc-200 dark:hover:border-zinc-700 transition-all duration-200", children: [
132              /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-start justify-between gap-4 mb-3", children: [
133                /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-3", children: [
134                  /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: `p-2.5 rounded-xl ${item.bgColor} ${item.textColor} transition-transform group-hover:scale-105 duration-200`, children: /* @__PURE__ */ jsxRuntimeExports.jsx(item.icon, { className: "w-5 h-5" }) }),
135                  /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
136                    /* @__PURE__ */ jsxRuntimeExports.jsx("h3", { className: "font-bold text-zinc-950 dark:text-white flex items-center gap-1.5", children: item.name }),
137                    /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs text-zinc-500 dark:text-zinc-400 mt-0.5", children: item.description })
138                  ] })
139                ] }),
140                /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "text-right", children: [
141                  /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "text-sm font-bold text-zinc-950 dark:text-white", children: [
142                    item.count,
143                    " ",
144                    /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-zinc-400 dark:text-zinc-600 font-medium", children: "/" }),
145                    " ",
146                    item.limit
147                  ] }),
148                  /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: `text-[10px] font-bold mt-0.5 ${isNearLimit ? "text-amber-500" : "text-zinc-400"}`, children: [
149                    percentage.toFixed(0),
150                    "%"
151                  ] })
152                ] })
153              ] }),
154              /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "w-full h-2 bg-zinc-100 dark:bg-zinc-800 rounded-full overflow-hidden mb-3", children: /* @__PURE__ */ jsxRuntimeExports.jsx(
155                "div",
156                {
157                  className: `h-full bg-gradient-to-r ${item.color} rounded-full transition-all duration-500`,
158                  style: { width: `${percentage}%` }
159                }
160              ) }),
161              /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex justify-between items-center mt-1", children: [
162                isNearLimit && /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-[11px] font-medium text-amber-600 dark:text-amber-400 flex items-center gap-1 bg-amber-500/5 px-2 py-0.5 rounded-md border border-amber-500/10", children: t("personalSpace.nearLimit", "Approaching limit") }),
163                item.path ? /* @__PURE__ */ jsxRuntimeExports.jsxs(
164                  "button",
165                  {
166                    onClick: () => onNavigate(item.path),
167                    className: "ml-auto text-xs font-bold text-indigo-600 hover:text-indigo-700 dark:text-indigo-400 dark:hover:text-indigo-300 flex items-center gap-1 group-hover:translate-x-0.5 transition-transform",
168                    children: [
169                      t("personalSpace.viewAll", "View saved items"),
170                      /* @__PURE__ */ jsxRuntimeExports.jsx(ArrowRight, { size: 12 })
171                    ]
172                  }
173                ) : /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "ml-auto text-[10px] text-zinc-400 dark:text-zinc-500 italic", children: t("personalSpace.eqUsageNote", "Configured inside player") })
174              ] })
175            ] }, index);
176          }) })
177        ] }),
178        /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "bg-white dark:bg-zinc-900 border border-zinc-200 dark:border-zinc-800 rounded-2xl p-6 shadow-sm", children: [
179          /* @__PURE__ */ jsxRuntimeExports.jsxs("h2", { className: "text-lg font-bold text-zinc-955 dark:text-white mb-6 flex items-center gap-2", children: [
180            /* @__PURE__ */ jsxRuntimeExports.jsx(SlidersVertical, { className: "w-5 h-5 text-rose-500 animate-pulse" }),
181            /* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: "Saved Digitizer Progress" })
182          ] }),
183          loadingProjects ? /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex items-center justify-center py-8", children: /* @__PURE__ */ jsxRuntimeExports.jsx(LoaderCircle, { className: "w-6 h-6 animate-spin text-rose-500" }) }) : digitizerProjects.length === 0 ? /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "text-center py-8 border border-dashed border-zinc-200 dark:border-zinc-800 rounded-xl bg-zinc-50/50 dark:bg-zinc-950/10", children: [
184            /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-sm text-zinc-500 dark:text-zinc-400", children: "No saved digitizer projects found." }),
185            /* @__PURE__ */ jsxRuntimeExports.jsxs(
186              "button",
187              {
188                onClick: () => onNavigate("sheet-digitizer"),
189                className: "mt-3 text-xs font-bold text-rose-500 hover:text-rose-600 flex items-center gap-1 mx-auto",
190                children: [
191                  /* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: "Start digitizing sheet music" }),
192                  /* @__PURE__ */ jsxRuntimeExports.jsx(ArrowRight, { size: 12 })
193                ]
194              }
195            )
196          ] }) : /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "space-y-3 max-h-[350px] overflow-y-auto pr-1", children: digitizerProjects.map((project) => {
197            const meta = typeof project.metadata === "string" ? JSON.parse(project.metadata) : project.metadata;
198            const isNotation = (meta == null ? void 0 : meta.isNotationScore) === true;
199            return /* @__PURE__ */ jsxRuntimeExports.jsxs(
200              "div",
201              {
202                onClick: () => onNavigate(isNotation ? "notation-editor" : "sheet-digitizer", project.id),
203                className: "group flex items-center justify-between p-3 rounded-lg border border-zinc-200 dark:border-zinc-800 hover:border-rose-500/50 dark:hover:border-rose-500/50 bg-white dark:bg-zinc-900/55 hover:bg-rose-50/10 dark:hover:bg-rose-950/5 cursor-pointer transition-all duration-200",
204                children: [
205                  /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-3 min-w-0", children: [
206                    /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: `p-2.5 rounded-xl group-hover:scale-105 transition-transform shrink-0 ${isNotation ? "bg-blue-500/10 text-blue-500" : "bg-rose-500/10 text-rose-500"}`, children: isNotation ? /* @__PURE__ */ jsxRuntimeExports.jsx(ListMusic, { size: 18 }) : /* @__PURE__ */ jsxRuntimeExports.jsx(SlidersVertical, { size: 18 }) }),
207                    /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "min-w-0", children: [
208                      /* @__PURE__ */ jsxRuntimeExports.jsx("h4", { className: "font-bold text-zinc-850 dark:text-zinc-200 truncate pr-2 group-hover:text-rose-500 dark:group-hover:text-rose-400 transition-colors text-sm", children: project.title }),
209                      /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2 text-[10px] text-zinc-550 dark:text-zinc-400 mt-1", children: [
210                        /* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: isNotation ? "Notation Score" : `${project.pagesCount} ${project.pagesCount === 1 ? "page" : "pages"}` }),
211                        /* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: "•" }),
212                        /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { children: [
213                          "Updated ",
214                          new Date(project.updatedAt).toLocaleDateString()
215                        ] })
216                      ] })
217                    ] })
218                  ] }),
219                  /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex items-center gap-1 shrink-0", children: /* @__PURE__ */ jsxRuntimeExports.jsx(
220                    "button",
221                    {
222                      onClick: async (e) => {
223                        e.stopPropagation();
224                        if (confirm("Are you sure you want to delete this saved progress?")) {
225                          try {
226                            await api.deleteDigitizerProject(project.id);
227                            setDigitizerProjects((prev) => prev.filter((p) => p.id !== project.id));
228                          } catch (err) {
229                            alert("Failed to delete project");
230                          }
231                        }
232                      },
233                      className: "p-2 text-zinc-400 hover:text-red-500 dark:text-zinc-500 dark:hover:text-red-400 hover:bg-red-50 dark:hover:bg-red-950/20 rounded-lg transition-all",
234                      title: "Delete progress",
235                      children: /* @__PURE__ */ jsxRuntimeExports.jsx(Trash2, { size: 16 })
236                    }
237                  ) })
238                ]
239              },
240              project.id
241            );
242          }) })
243        ] })
244      ] }),
245      /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-6", children: [
246        /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "bg-gradient-to-br from-indigo-900 via-indigo-950 to-purple-950 text-white rounded-2xl p-6 border border-indigo-500/20 shadow-md relative overflow-hidden", children: [
247          /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "absolute top-0 right-0 transform translate-x-6 -translate-y-6 w-32 h-32 bg-indigo-500/10 rounded-full blur-2xl" }),
248          /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "relative z-10", children: [
249            /* @__PURE__ */ jsxRuntimeExports.jsx(Sparkles, { className: "w-10 h-10 text-indigo-400 mb-4 animate-pulse" }),
250            /* @__PURE__ */ jsxRuntimeExports.jsx("h3", { className: "text-xl font-black tracking-tight mb-2", children: isUserPro ? t("personalSpace.proUnlocked", "Pro Unlocked") : t("personalSpace.upgradeTitle", "Go Unlimited with Pro") }),
251            /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-indigo-200 text-xs leading-relaxed mb-6", children: isUserPro ? t("personalSpace.proThanks", "Thank you for supporting HamieNET! Your limits have been greatly expanded.") : t("personalSpace.upgradeDesc", "Increase your limits to 100+ playlists, 1000 liked tracks, 1000 watch later saves, and unlock advanced studio features.") }),
252            isUserPro ? /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-3 bg-white/5 border border-white/10 rounded-xl p-4", children: [
253              /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2 text-xs font-bold text-indigo-300", children: [
254                /* @__PURE__ */ jsxRuntimeExports.jsx(Check, { size: 14, className: "text-emerald-400" }),
255                /* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: t("personalSpace.limit100Playlists", "100 Playlists Limit") })
256              ] }),
257              /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2 text-xs font-bold text-indigo-300", children: [
258                /* @__PURE__ */ jsxRuntimeExports.jsx(Check, { size: 14, className: "text-emerald-400" }),
259                /* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: t("personalSpace.limit1000Likes", "1000 Liked Tracks") })
260              ] }),
261              /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2 text-xs font-bold text-indigo-300", children: [
262                /* @__PURE__ */ jsxRuntimeExports.jsx(Check, { size: 14, className: "text-emerald-400" }),
263                /* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: t("personalSpace.limit1000WatchLater", "1000 Watch Later") })
264              ] }),
265              /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2 text-xs font-bold text-indigo-300", children: [
266                /* @__PURE__ */ jsxRuntimeExports.jsx(Check, { size: 14, className: "text-emerald-400" }),
267                /* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: t("personalSpace.limit100EQ", "100 Saved EQ Settings") })
268              ] })
269            ] }) : /* @__PURE__ */ jsxRuntimeExports.jsxs(
270              "button",
271              {
272                onClick: () => onNavigate("account"),
273                className: "w-full flex items-center justify-center gap-2 px-6 py-3 bg-white text-indigo-950 font-bold rounded-xl shadow-lg hover:bg-zinc-100 transition-all font-semibold active:scale-95 duration-100",
274                children: [
275                  /* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: t("personalSpace.upgradeBtn", "Upgrade to Pro") }),
276                  /* @__PURE__ */ jsxRuntimeExports.jsx(Sparkles, { size: 14 })
277                ]
278              }
279            )
280          ] })
281        ] }),
282        /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "bg-white dark:bg-zinc-900 border border-zinc-200 dark:border-zinc-800 rounded-2xl p-6 shadow-sm", children: [
283          /* @__PURE__ */ jsxRuntimeExports.jsx("h3", { className: "font-bold text-zinc-950 dark:text-white mb-3", children: t("personalSpace.howItWorksTitle", "About Personal Space") }),
284          /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs text-zinc-500 dark:text-zinc-400 leading-relaxed mb-4", children: t("personalSpace.howItWorksDesc", "Every time you like a track, queue it in Watch Later, create a playlist, or save custom equalizations, it consumes a slot in your Personal Space. Reaching a limit prevents saving new items until older ones are removed.") }),
285          /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2 text-[11px] font-bold text-indigo-600 dark:text-indigo-400", children: [
286            /* @__PURE__ */ jsxRuntimeExports.jsx(Lock, { size: 12, className: "shrink-0" }),
287            /* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: t("personalSpace.secureData", "Your Personal Space is private and secure") })
288          ] })
289        ] })
290      ] })
291    ] })
292  ] });
293}
294export {
295  PersonalSpacePage as default
296};

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.