sa2kit 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (218) hide show
  1. package/LICENSE +22 -0
  2. package/README.md +298 -0
  3. package/dist/AliyunOSSProvider-7JLMJDXK.js +15 -0
  4. package/dist/AliyunOSSProvider-7JLMJDXK.js.map +1 -0
  5. package/dist/AliyunOSSProvider-GQMSDJGZ.mjs +6 -0
  6. package/dist/AliyunOSSProvider-GQMSDJGZ.mjs.map +1 -0
  7. package/dist/LocalStorageProvider-FVLLHBHO.mjs +6 -0
  8. package/dist/LocalStorageProvider-FVLLHBHO.mjs.map +1 -0
  9. package/dist/LocalStorageProvider-NBNHHWLY.js +15 -0
  10. package/dist/LocalStorageProvider-NBNHHWLY.js.map +1 -0
  11. package/dist/analytics/index.d.mts +1084 -0
  12. package/dist/analytics/index.d.ts +1084 -0
  13. package/dist/analytics/index.js +2595 -0
  14. package/dist/analytics/index.js.map +1 -0
  15. package/dist/analytics/index.mjs +2518 -0
  16. package/dist/analytics/index.mjs.map +1 -0
  17. package/dist/analytics/server/index.d.mts +499 -0
  18. package/dist/analytics/server/index.d.ts +499 -0
  19. package/dist/analytics/server/index.js +529 -0
  20. package/dist/analytics/server/index.js.map +1 -0
  21. package/dist/analytics/server/index.mjs +525 -0
  22. package/dist/analytics/server/index.mjs.map +1 -0
  23. package/dist/auth/client/index.d.mts +104 -0
  24. package/dist/auth/client/index.d.ts +104 -0
  25. package/dist/auth/client/index.js +21 -0
  26. package/dist/auth/client/index.js.map +1 -0
  27. package/dist/auth/client/index.mjs +4 -0
  28. package/dist/auth/client/index.mjs.map +1 -0
  29. package/dist/auth/components/index.d.mts +82 -0
  30. package/dist/auth/components/index.d.ts +82 -0
  31. package/dist/auth/components/index.js +93 -0
  32. package/dist/auth/components/index.js.map +1 -0
  33. package/dist/auth/components/index.mjs +86 -0
  34. package/dist/auth/components/index.mjs.map +1 -0
  35. package/dist/auth/hooks/index.d.mts +2 -0
  36. package/dist/auth/hooks/index.d.ts +2 -0
  37. package/dist/auth/hooks/index.js +17 -0
  38. package/dist/auth/hooks/index.js.map +1 -0
  39. package/dist/auth/hooks/index.mjs +4 -0
  40. package/dist/auth/hooks/index.mjs.map +1 -0
  41. package/dist/auth/index.d.mts +15 -0
  42. package/dist/auth/index.d.ts +15 -0
  43. package/dist/auth/index.js +110 -0
  44. package/dist/auth/index.js.map +1 -0
  45. package/dist/auth/index.mjs +9 -0
  46. package/dist/auth/index.mjs.map +1 -0
  47. package/dist/auth/middleware/index.d.mts +75 -0
  48. package/dist/auth/middleware/index.d.ts +75 -0
  49. package/dist/auth/middleware/index.js +15 -0
  50. package/dist/auth/middleware/index.js.map +1 -0
  51. package/dist/auth/middleware/index.mjs +6 -0
  52. package/dist/auth/middleware/index.mjs.map +1 -0
  53. package/dist/auth/routes/index.d.mts +163 -0
  54. package/dist/auth/routes/index.d.ts +163 -0
  55. package/dist/auth/routes/index.js +27 -0
  56. package/dist/auth/routes/index.js.map +1 -0
  57. package/dist/auth/routes/index.mjs +6 -0
  58. package/dist/auth/routes/index.mjs.map +1 -0
  59. package/dist/auth/schema/index.d.mts +789 -0
  60. package/dist/auth/schema/index.d.ts +789 -0
  61. package/dist/auth/schema/index.js +41 -0
  62. package/dist/auth/schema/index.js.map +1 -0
  63. package/dist/auth/schema/index.mjs +4 -0
  64. package/dist/auth/schema/index.mjs.map +1 -0
  65. package/dist/auth/services/index.d.mts +47 -0
  66. package/dist/auth/services/index.d.ts +47 -0
  67. package/dist/auth/services/index.js +34 -0
  68. package/dist/auth/services/index.js.map +1 -0
  69. package/dist/auth/services/index.mjs +5 -0
  70. package/dist/auth/services/index.mjs.map +1 -0
  71. package/dist/chunk-3RFBUDRA.js +507 -0
  72. package/dist/chunk-3RFBUDRA.js.map +1 -0
  73. package/dist/chunk-3XG5OHFD.mjs +37 -0
  74. package/dist/chunk-3XG5OHFD.mjs.map +1 -0
  75. package/dist/chunk-6BL3AZGD.js +285 -0
  76. package/dist/chunk-6BL3AZGD.js.map +1 -0
  77. package/dist/chunk-6FNUWAIV.js +394 -0
  78. package/dist/chunk-6FNUWAIV.js.map +1 -0
  79. package/dist/chunk-6PRFP5EG.js +171 -0
  80. package/dist/chunk-6PRFP5EG.js.map +1 -0
  81. package/dist/chunk-6VHWOPRR.mjs +90 -0
  82. package/dist/chunk-6VHWOPRR.mjs.map +1 -0
  83. package/dist/chunk-AIKEVVDR.mjs +122 -0
  84. package/dist/chunk-AIKEVVDR.mjs.map +1 -0
  85. package/dist/chunk-APY57REU.js +300 -0
  86. package/dist/chunk-APY57REU.js.map +1 -0
  87. package/dist/chunk-BJTO5JO5.mjs +10 -0
  88. package/dist/chunk-BJTO5JO5.mjs.map +1 -0
  89. package/dist/chunk-C64RY2OW.mjs +295 -0
  90. package/dist/chunk-C64RY2OW.mjs.map +1 -0
  91. package/dist/chunk-DGUM43GV.js +12 -0
  92. package/dist/chunk-DGUM43GV.js.map +1 -0
  93. package/dist/chunk-FV3FNHQY.js +92 -0
  94. package/dist/chunk-FV3FNHQY.js.map +1 -0
  95. package/dist/chunk-GSTLV3MB.mjs +316 -0
  96. package/dist/chunk-GSTLV3MB.mjs.map +1 -0
  97. package/dist/chunk-HEMA7SWK.mjs +212 -0
  98. package/dist/chunk-HEMA7SWK.mjs.map +1 -0
  99. package/dist/chunk-HWJ34NL6.js +43 -0
  100. package/dist/chunk-HWJ34NL6.js.map +1 -0
  101. package/dist/chunk-HXFFYNIF.mjs +385 -0
  102. package/dist/chunk-HXFFYNIF.mjs.map +1 -0
  103. package/dist/chunk-KGRQNEIR.mjs +183 -0
  104. package/dist/chunk-KGRQNEIR.mjs.map +1 -0
  105. package/dist/chunk-KH6RQ4J5.js +28 -0
  106. package/dist/chunk-KH6RQ4J5.js.map +1 -0
  107. package/dist/chunk-KQGP6BTS.mjs +165 -0
  108. package/dist/chunk-KQGP6BTS.mjs.map +1 -0
  109. package/dist/chunk-NMF4ANIC.js +365 -0
  110. package/dist/chunk-NMF4ANIC.js.map +1 -0
  111. package/dist/chunk-O26VCNS3.js +216 -0
  112. package/dist/chunk-O26VCNS3.js.map +1 -0
  113. package/dist/chunk-OLHGZXN3.mjs +86 -0
  114. package/dist/chunk-OLHGZXN3.mjs.map +1 -0
  115. package/dist/chunk-QU5OT4DF.js +88 -0
  116. package/dist/chunk-QU5OT4DF.js.map +1 -0
  117. package/dist/chunk-RCNNVNLT.mjs +356 -0
  118. package/dist/chunk-RCNNVNLT.mjs.map +1 -0
  119. package/dist/chunk-ROEYW4A7.js +186 -0
  120. package/dist/chunk-ROEYW4A7.js.map +1 -0
  121. package/dist/chunk-SVWQN2LR.js +131 -0
  122. package/dist/chunk-SVWQN2LR.js.map +1 -0
  123. package/dist/chunk-TKCYPDWU.js +338 -0
  124. package/dist/chunk-TKCYPDWU.js.map +1 -0
  125. package/dist/chunk-U2L6V7KD.mjs +273 -0
  126. package/dist/chunk-U2L6V7KD.mjs.map +1 -0
  127. package/dist/chunk-YVBU7QDJ.mjs +505 -0
  128. package/dist/chunk-YVBU7QDJ.mjs.map +1 -0
  129. package/dist/chunk-ZGVB35L2.mjs +25 -0
  130. package/dist/chunk-ZGVB35L2.mjs.map +1 -0
  131. package/dist/config/index.d.mts +64 -0
  132. package/dist/config/index.d.ts +64 -0
  133. package/dist/config/index.js +136 -0
  134. package/dist/config/index.js.map +1 -0
  135. package/dist/config/index.mjs +128 -0
  136. package/dist/config/index.mjs.map +1 -0
  137. package/dist/drizzle-auth-service-Bxlovhv8.d.ts +145 -0
  138. package/dist/drizzle-auth-service-DZY2F1sv.d.mts +145 -0
  139. package/dist/enums-Dume-V5Y.d.mts +16 -0
  140. package/dist/enums-Dume-V5Y.d.ts +16 -0
  141. package/dist/i18n/index.d.mts +416 -0
  142. package/dist/i18n/index.d.ts +416 -0
  143. package/dist/i18n/index.js +671 -0
  144. package/dist/i18n/index.js.map +1 -0
  145. package/dist/i18n/index.mjs +650 -0
  146. package/dist/i18n/index.mjs.map +1 -0
  147. package/dist/index-8VoHap_4.d.mts +105 -0
  148. package/dist/index-8VoHap_4.d.ts +105 -0
  149. package/dist/index.d.mts +4 -0
  150. package/dist/index.d.ts +4 -0
  151. package/dist/index.js +84 -0
  152. package/dist/index.js.map +1 -0
  153. package/dist/index.mjs +7 -0
  154. package/dist/index.mjs.map +1 -0
  155. package/dist/logger/index.d.mts +125 -0
  156. package/dist/logger/index.d.ts +125 -0
  157. package/dist/logger/index.js +29 -0
  158. package/dist/logger/index.js.map +1 -0
  159. package/dist/logger/index.mjs +4 -0
  160. package/dist/logger/index.mjs.map +1 -0
  161. package/dist/request/index.d.mts +51 -0
  162. package/dist/request/index.d.ts +51 -0
  163. package/dist/request/index.js +85 -0
  164. package/dist/request/index.js.map +1 -0
  165. package/dist/request/index.mjs +82 -0
  166. package/dist/request/index.mjs.map +1 -0
  167. package/dist/storage/index.d.mts +74 -0
  168. package/dist/storage/index.d.ts +74 -0
  169. package/dist/storage/index.js +46 -0
  170. package/dist/storage/index.js.map +1 -0
  171. package/dist/storage/index.mjs +5 -0
  172. package/dist/storage/index.mjs.map +1 -0
  173. package/dist/types-BINlP9MK.d.mts +286 -0
  174. package/dist/types-BINlP9MK.d.ts +286 -0
  175. package/dist/types-BaZccpvk.d.mts +48 -0
  176. package/dist/types-BaZccpvk.d.ts +48 -0
  177. package/dist/types-CbTsi9CZ.d.mts +31 -0
  178. package/dist/types-CbTsi9CZ.d.ts +31 -0
  179. package/dist/types-CoGG1rNV.d.mts +258 -0
  180. package/dist/types-CoGG1rNV.d.ts +258 -0
  181. package/dist/types-DAxQ1MeY.d.ts +70 -0
  182. package/dist/types-DT8LVCvE.d.mts +70 -0
  183. package/dist/types-DW9qar-w.d.mts +52 -0
  184. package/dist/types-DW9qar-w.d.ts +52 -0
  185. package/dist/universalExport/index.d.mts +235 -0
  186. package/dist/universalExport/index.d.ts +235 -0
  187. package/dist/universalExport/index.js +621 -0
  188. package/dist/universalExport/index.js.map +1 -0
  189. package/dist/universalExport/index.mjs +580 -0
  190. package/dist/universalExport/index.mjs.map +1 -0
  191. package/dist/universalExport/server/index.d.mts +429 -0
  192. package/dist/universalExport/server/index.d.ts +429 -0
  193. package/dist/universalExport/server/index.js +263 -0
  194. package/dist/universalExport/server/index.js.map +1 -0
  195. package/dist/universalExport/server/index.mjs +242 -0
  196. package/dist/universalExport/server/index.mjs.map +1 -0
  197. package/dist/universalFile/index.d.mts +310 -0
  198. package/dist/universalFile/index.d.ts +310 -0
  199. package/dist/universalFile/index.js +811 -0
  200. package/dist/universalFile/index.js.map +1 -0
  201. package/dist/universalFile/index.mjs +736 -0
  202. package/dist/universalFile/index.mjs.map +1 -0
  203. package/dist/universalFile/server/index.d.mts +2428 -0
  204. package/dist/universalFile/server/index.d.ts +2428 -0
  205. package/dist/universalFile/server/index.js +4578 -0
  206. package/dist/universalFile/server/index.js.map +1 -0
  207. package/dist/universalFile/server/index.mjs +4518 -0
  208. package/dist/universalFile/server/index.mjs.map +1 -0
  209. package/dist/useElectronStorage-Dj0rcorG.d.mts +65 -0
  210. package/dist/useElectronStorage-DwnNfIhl.d.ts +65 -0
  211. package/dist/utils/index.d.mts +188 -0
  212. package/dist/utils/index.d.ts +188 -0
  213. package/dist/utils/index.js +42 -0
  214. package/dist/utils/index.js.map +1 -0
  215. package/dist/utils/index.mjs +5 -0
  216. package/dist/utils/index.mjs.map +1 -0
  217. package/package.json +220 -0
  218. package/tailwind.animations.js +34 -0
@@ -0,0 +1,671 @@
1
+ 'use strict';
2
+
3
+ var chunkDGUM43GV_js = require('../chunk-DGUM43GV.js');
4
+ var React = require('react');
5
+
6
+ function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
7
+
8
+ var React__default = /*#__PURE__*/_interopDefault(React);
9
+
10
+ // src/i18n/i18n.ts
11
+ function defaultInterpolate(template, data) {
12
+ return template.replace(/\{\{(\w+)\}\}/g, (match, key) => {
13
+ return data[key]?.toString() ?? match;
14
+ });
15
+ }
16
+ function getNestedValue(obj, path) {
17
+ const keys = path.split(".");
18
+ let result = obj;
19
+ for (const key of keys) {
20
+ if (result && typeof result === "object" && key in result) {
21
+ result = result[key];
22
+ } else {
23
+ return void 0;
24
+ }
25
+ }
26
+ return result;
27
+ }
28
+ function createI18n(config) {
29
+ let currentLocale = config.locale;
30
+ const fallbackLocale = config.fallbackLocale || "zh-CN";
31
+ const resources = config.resources || {};
32
+ const interpolate = config.interpolate || defaultInterpolate;
33
+ function t2(key, options = {}) {
34
+ const { defaultValue, count, context = {} } = options;
35
+ let translation = getNestedValue(resources[currentLocale], key);
36
+ if (translation === void 0 && currentLocale !== fallbackLocale) {
37
+ translation = getNestedValue(resources[fallbackLocale], key);
38
+ }
39
+ if (translation === void 0) {
40
+ return defaultValue || key;
41
+ }
42
+ if (typeof translation !== "string") {
43
+ return JSON.stringify(translation);
44
+ }
45
+ if (count !== void 0) {
46
+ const pluralKey = count === 1 ? `${key}_one` : `${key}_other`;
47
+ const pluralTranslation = getNestedValue(resources[currentLocale], pluralKey);
48
+ if (pluralTranslation && typeof pluralTranslation === "string") {
49
+ translation = pluralTranslation;
50
+ }
51
+ }
52
+ const data = { ...context, count };
53
+ return interpolate(translation, data);
54
+ }
55
+ function setLocale(locale) {
56
+ currentLocale = locale;
57
+ }
58
+ function addResources(locale, newResources) {
59
+ if (!resources[locale]) {
60
+ resources[locale] = {};
61
+ }
62
+ resources[locale] = {
63
+ ...resources[locale],
64
+ ...newResources
65
+ };
66
+ }
67
+ function getLocale() {
68
+ return currentLocale;
69
+ }
70
+ return {
71
+ locale: currentLocale,
72
+ t: t2,
73
+ setLocale,
74
+ addResources,
75
+ getLocale
76
+ };
77
+ }
78
+ var globalI18n = null;
79
+ function initI18n(config) {
80
+ globalI18n = createI18n(config);
81
+ return globalI18n;
82
+ }
83
+ function getI18n() {
84
+ if (!globalI18n) {
85
+ throw new Error("i18n not initialized. Call initI18n() first.");
86
+ }
87
+ return globalI18n;
88
+ }
89
+ function t(key, options) {
90
+ return getI18n().t(key, options);
91
+ }
92
+ function useTranslation() {
93
+ const i18n = getI18n();
94
+ const [locale, setLocaleState] = React.useState(i18n.getLocale());
95
+ const t2 = React.useCallback(
96
+ (key, options) => {
97
+ return i18n.t(key, options);
98
+ },
99
+ [locale]
100
+ // locale 改变时重新创建函数
101
+ );
102
+ const setLocale = React.useCallback((newLocale) => {
103
+ i18n.setLocale(newLocale);
104
+ setLocaleState(newLocale);
105
+ }, []);
106
+ return {
107
+ t: t2,
108
+ locale,
109
+ setLocale
110
+ };
111
+ }
112
+ function useLocale() {
113
+ const i18n = getI18n();
114
+ const [locale, setLocaleState] = React.useState(i18n.getLocale());
115
+ const setLocale = React.useCallback((newLocale) => {
116
+ i18n.setLocale(newLocale);
117
+ setLocaleState(newLocale);
118
+ }, []);
119
+ return {
120
+ locale,
121
+ setLocale
122
+ };
123
+ }
124
+
125
+ // src/i18n/locales/zh-CN.ts
126
+ var zh_CN_default = {
127
+ // ==================== 应用信息 ====================
128
+ app: {
129
+ name: "LyricNote",
130
+ fullName: "LyricNote - \u6B4C\u8BCD\u7B14\u8BB0",
131
+ icon: "\u{1F3B5}",
132
+ description: "\u4E00\u4E2A\u5F3A\u5927\u7684\u6B4C\u8BCD\u548C\u7B14\u8BB0\u7BA1\u7406\u5E94\u7528",
133
+ author: "LyricNote Team",
134
+ copyright: `\xA9 ${(/* @__PURE__ */ new Date()).getFullYear()} LyricNote`,
135
+ version: "1.0.0"
136
+ },
137
+ // ==================== 应用标题 ====================
138
+ titles: {
139
+ main: "\u{1F3B5} LyricNote",
140
+ admin: "LyricNote \u7BA1\u7406\u540E\u53F0",
141
+ withVersion: "LyricNote v1.0.0",
142
+ welcome: "\u6B22\u8FCE\u4F7F\u7528 LyricNote",
143
+ about: "\u5173\u4E8E LyricNote"
144
+ },
145
+ // ==================== 通用文案 ====================
146
+ common: {
147
+ hello: "\u4F60\u597D",
148
+ welcome: "\u6B22\u8FCE",
149
+ confirm: "\u786E\u8BA4",
150
+ cancel: "\u53D6\u6D88",
151
+ save: "\u4FDD\u5B58",
152
+ delete: "\u5220\u9664",
153
+ edit: "\u7F16\u8F91",
154
+ back: "\u8FD4\u56DE",
155
+ next: "\u4E0B\u4E00\u6B65",
156
+ submit: "\u63D0\u4EA4",
157
+ finish: "\u5B8C\u6210",
158
+ loading: "\u52A0\u8F7D\u4E2D...",
159
+ success: "\u64CD\u4F5C\u6210\u529F",
160
+ error: "\u64CD\u4F5C\u5931\u8D25",
161
+ retry: "\u91CD\u8BD5",
162
+ empty: "\u6682\u65E0\u6570\u636E"
163
+ },
164
+ // ==================== 导航菜单 ====================
165
+ nav: {
166
+ home: "\u9996\u9875",
167
+ lyrics: "\u6B4C\u8BCD",
168
+ create: "\u521B\u4F5C",
169
+ collection: "\u6536\u85CF",
170
+ profile: "\u6211\u7684",
171
+ settings: "\u8BBE\u7F6E",
172
+ history: "\u5386\u53F2",
173
+ logout: "\u9000\u51FA\u767B\u5F55"
174
+ },
175
+ // ==================== 用户相关 ====================
176
+ user: {
177
+ login: "\u767B\u5F55",
178
+ register: "\u6CE8\u518C",
179
+ username: "\u7528\u6237\u540D",
180
+ password: "\u5BC6\u7801",
181
+ email: "\u90AE\u7BB1",
182
+ phone: "\u624B\u673A\u53F7",
183
+ nickname: "\u6635\u79F0"
184
+ },
185
+ // ==================== 页面标题和描述 ====================
186
+ pages: {
187
+ home: {
188
+ title: "\u9996\u9875",
189
+ description: "\u4E00\u4E2A\u5F3A\u5927\u7684\u6B4C\u8BCD\u548C\u7B14\u8BB0\u7BA1\u7406\u5E94\u7528"
190
+ },
191
+ profile: {
192
+ title: "\u4E2A\u4EBA\u4E2D\u5FC3",
193
+ description: "\u7BA1\u7406\u60A8\u7684\u4E2A\u4EBA\u4FE1\u606F\u548C\u504F\u597D\u8BBE\u7F6E"
194
+ },
195
+ admin: {
196
+ title: "LyricNote \u7BA1\u7406\u540E\u53F0",
197
+ description: "\u7CFB\u7EDF\u7BA1\u7406\u548C\u6570\u636E\u7EDF\u8BA1"
198
+ },
199
+ login: {
200
+ title: "\u767B\u5F55",
201
+ description: "\u767B\u5F55\u5230 LyricNote"
202
+ }
203
+ },
204
+ // ==================== 表单验证 ====================
205
+ validation: {
206
+ required: "{{field}}\u4E0D\u80FD\u4E3A\u7A7A",
207
+ invalid_email: "\u90AE\u7BB1\u683C\u5F0F\u4E0D\u6B63\u786E",
208
+ password_too_short: "\u5BC6\u7801\u81F3\u5C11\u9700\u8981{{count}}\u4E2A\u5B57\u7B26",
209
+ password_weak: "\u5BC6\u7801\u5F3A\u5EA6\u4E0D\u591F",
210
+ passwords_not_match: "\u4E24\u6B21\u5BC6\u7801\u4E0D\u4E00\u81F4"
211
+ },
212
+ // ==================== 状态提示 ====================
213
+ status: {
214
+ loading: "\u52A0\u8F7D\u4E2D...",
215
+ success: "\u64CD\u4F5C\u6210\u529F",
216
+ error: "\u64CD\u4F5C\u5931\u8D25",
217
+ empty: "\u6682\u65E0\u6570\u636E",
218
+ network_error: "\u7F51\u7EDC\u9519\u8BEF\uFF0C\u8BF7\u7A0D\u540E\u91CD\u8BD5"
219
+ },
220
+ // ==================== 错误消息 ====================
221
+ errors: {
222
+ network: "\u7F51\u7EDC\u9519\u8BEF\uFF0C\u8BF7\u7A0D\u540E\u91CD\u8BD5",
223
+ server: "\u670D\u52A1\u5668\u9519\u8BEF",
224
+ unauthorized: "\u672A\u6388\u6743\uFF0C\u8BF7\u5148\u767B\u5F55",
225
+ not_found: "\u672A\u627E\u5230\u76F8\u5173\u5185\u5BB9",
226
+ unknown: "\u672A\u77E5\u9519\u8BEF"
227
+ },
228
+ // ==================== 成功消息 ====================
229
+ success: {
230
+ saved: "\u4FDD\u5B58\u6210\u529F",
231
+ deleted: "\u5220\u9664\u6210\u529F",
232
+ updated: "\u66F4\u65B0\u6210\u529F",
233
+ created: "\u521B\u5EFA\u6210\u529F"
234
+ },
235
+ // ==================== 语言设置 ====================
236
+ language: {
237
+ label: "\u8BED\u8A00",
238
+ zh_cn: "\u7B80\u4F53\u4E2D\u6587",
239
+ zh_tw: "\u7E41\u9AD4\u4E2D\u6587",
240
+ en_us: "English",
241
+ ja_jp: "\u65E5\u672C\u8A9E"
242
+ }
243
+ };
244
+
245
+ // src/i18n/locales/en-US.ts
246
+ var en_US_default = {
247
+ // ==================== App Information ====================
248
+ app: {
249
+ name: "LyricNote",
250
+ fullName: "LyricNote - Lyrics & Notes",
251
+ icon: "\u{1F3B5}",
252
+ description: "A powerful lyrics and notes management app",
253
+ author: "LyricNote Team",
254
+ copyright: `\xA9 ${(/* @__PURE__ */ new Date()).getFullYear()} LyricNote`,
255
+ version: "1.0.0"
256
+ },
257
+ // ==================== App Titles ====================
258
+ titles: {
259
+ main: "\u{1F3B5} LyricNote",
260
+ admin: "LyricNote Admin",
261
+ withVersion: "LyricNote v1.0.0",
262
+ welcome: "Welcome to LyricNote",
263
+ about: "About LyricNote"
264
+ },
265
+ // ==================== Common ====================
266
+ common: {
267
+ hello: "Hello",
268
+ welcome: "Welcome",
269
+ confirm: "Confirm",
270
+ cancel: "Cancel",
271
+ save: "Save",
272
+ delete: "Delete",
273
+ edit: "Edit",
274
+ back: "Back",
275
+ next: "Next",
276
+ submit: "Submit",
277
+ finish: "Finish",
278
+ loading: "Loading...",
279
+ success: "Success",
280
+ error: "Error",
281
+ retry: "Retry",
282
+ empty: "No data"
283
+ },
284
+ // ==================== Navigation ====================
285
+ nav: {
286
+ home: "Home",
287
+ lyrics: "Lyrics",
288
+ create: "Create",
289
+ collection: "Collection",
290
+ profile: "Profile",
291
+ settings: "Settings",
292
+ history: "History",
293
+ logout: "Logout"
294
+ },
295
+ // ==================== User ====================
296
+ user: {
297
+ login: "Login",
298
+ register: "Register",
299
+ username: "Username",
300
+ password: "Password",
301
+ email: "Email",
302
+ phone: "Phone",
303
+ nickname: "Nickname"
304
+ },
305
+ // ==================== Pages ====================
306
+ pages: {
307
+ home: {
308
+ title: "Home",
309
+ description: "A powerful lyrics and notes management app"
310
+ },
311
+ profile: {
312
+ title: "Profile",
313
+ description: "Manage your personal information and preferences"
314
+ },
315
+ admin: {
316
+ title: "LyricNote Admin",
317
+ description: "System management and data statistics"
318
+ },
319
+ login: {
320
+ title: "Login",
321
+ description: "Login to LyricNote"
322
+ }
323
+ },
324
+ // ==================== Form Validation ====================
325
+ validation: {
326
+ required: "{{field}} is required",
327
+ invalid_email: "Invalid email format",
328
+ password_too_short: "Password must be at least {{count}} characters",
329
+ password_weak: "Password is too weak",
330
+ passwords_not_match: "Passwords do not match"
331
+ },
332
+ // ==================== Status Messages ====================
333
+ status: {
334
+ loading: "Loading...",
335
+ success: "Success",
336
+ error: "Error",
337
+ empty: "No data",
338
+ network_error: "Network error, please try again later"
339
+ },
340
+ // ==================== Error Messages ====================
341
+ errors: {
342
+ network: "Network error, please try again later",
343
+ server: "Server error",
344
+ unauthorized: "Unauthorized, please login first",
345
+ not_found: "Not found",
346
+ unknown: "Unknown error"
347
+ },
348
+ // ==================== Success Messages ====================
349
+ success: {
350
+ saved: "Saved successfully",
351
+ deleted: "Deleted successfully",
352
+ updated: "Updated successfully",
353
+ created: "Created successfully"
354
+ },
355
+ // ==================== Language Settings ====================
356
+ language: {
357
+ label: "Language",
358
+ zh_cn: "\u7B80\u4F53\u4E2D\u6587",
359
+ zh_tw: "\u7E41\u9AD4\u4E2D\u6587",
360
+ en_us: "English",
361
+ ja_jp: "\u65E5\u672C\u8A9E"
362
+ }
363
+ };
364
+
365
+ // src/i18n/adapters/web.ts
366
+ var WebI18nAdapter = class {
367
+ constructor() {
368
+ this.storageKey = "app_locale";
369
+ }
370
+ getSystemLocale() {
371
+ if (typeof navigator === "undefined") return "zh-CN";
372
+ const browserLocale = navigator.language;
373
+ return this.normalizeLocale(browserLocale);
374
+ }
375
+ async saveLocale(locale) {
376
+ if (typeof localStorage === "undefined") return;
377
+ localStorage.setItem(this.storageKey, locale);
378
+ }
379
+ async loadLocale() {
380
+ if (typeof localStorage === "undefined") return null;
381
+ const stored = localStorage.getItem(this.storageKey);
382
+ return stored;
383
+ }
384
+ normalizeLocale(locale) {
385
+ const map = {
386
+ "zh-CN": "zh-CN",
387
+ "zh-TW": "zh-TW",
388
+ "zh-HK": "zh-TW",
389
+ zh: "zh-CN",
390
+ "en-US": "en-US",
391
+ "en-GB": "en-US",
392
+ en: "en-US",
393
+ "ja-JP": "ja-JP",
394
+ ja: "ja-JP"
395
+ };
396
+ return map[locale] || "zh-CN";
397
+ }
398
+ };
399
+
400
+ // src/i18n/adapters/mobile.ts
401
+ var ReactNativeI18nAdapter = class {
402
+ constructor() {
403
+ this.storageKey = "@app_locale";
404
+ }
405
+ getSystemLocale() {
406
+ try {
407
+ const { Platform, NativeModules } = chunkDGUM43GV_js.__require("react-native");
408
+ const locale = Platform.OS === "ios" ? NativeModules.SettingsManager.settings.AppleLocale || NativeModules.SettingsManager.settings.AppleLanguages[0] : NativeModules.I18nManager.localeIdentifier;
409
+ return this.normalizeLocale(locale);
410
+ } catch {
411
+ return "zh-CN";
412
+ }
413
+ }
414
+ async saveLocale(locale) {
415
+ try {
416
+ const AsyncStorage = chunkDGUM43GV_js.__require("@react-native-async-storage/async-storage").default;
417
+ await AsyncStorage.setItem(this.storageKey, locale);
418
+ } catch (error) {
419
+ console.error("Failed to save locale:", error);
420
+ }
421
+ }
422
+ async loadLocale() {
423
+ try {
424
+ const AsyncStorage = chunkDGUM43GV_js.__require("@react-native-async-storage/async-storage").default;
425
+ const stored = await AsyncStorage.getItem(this.storageKey);
426
+ return stored;
427
+ } catch (error) {
428
+ console.error("Failed to load locale:", error);
429
+ return null;
430
+ }
431
+ }
432
+ normalizeLocale(locale) {
433
+ const map = {
434
+ "zh-CN": "zh-CN",
435
+ zh_CN: "zh-CN",
436
+ "zh-Hans": "zh-CN",
437
+ zh_Hans_CN: "zh-CN",
438
+ "zh-TW": "zh-TW",
439
+ zh_TW: "zh-TW",
440
+ "zh-Hant": "zh-TW",
441
+ zh_Hant_TW: "zh-TW",
442
+ "en-US": "en-US",
443
+ en_US: "en-US",
444
+ en: "en-US",
445
+ "ja-JP": "ja-JP",
446
+ ja_JP: "ja-JP",
447
+ ja: "ja-JP"
448
+ };
449
+ return map[locale] || "zh-CN";
450
+ }
451
+ };
452
+
453
+ // src/i18n/adapters/miniapp.ts
454
+ var TaroI18nAdapter = class {
455
+ constructor() {
456
+ this.storageKey = "app_locale";
457
+ }
458
+ getSystemLocale() {
459
+ try {
460
+ const Taro = chunkDGUM43GV_js.__require("@tarojs/taro").default;
461
+ const systemInfo = Taro.getSystemInfoSync();
462
+ return this.normalizeLocale(systemInfo.language);
463
+ } catch {
464
+ return "zh-CN";
465
+ }
466
+ }
467
+ async saveLocale(locale) {
468
+ try {
469
+ const Taro = chunkDGUM43GV_js.__require("@tarojs/taro").default;
470
+ await Taro.setStorage({
471
+ key: this.storageKey,
472
+ data: locale
473
+ });
474
+ } catch (error) {
475
+ console.error("Failed to save locale:", error);
476
+ }
477
+ }
478
+ async loadLocale() {
479
+ try {
480
+ const Taro = chunkDGUM43GV_js.__require("@tarojs/taro").default;
481
+ const res = await Taro.getStorage({
482
+ key: this.storageKey
483
+ });
484
+ return res.data;
485
+ } catch (error) {
486
+ return null;
487
+ }
488
+ }
489
+ normalizeLocale(locale) {
490
+ const map = {
491
+ zh_CN: "zh-CN",
492
+ "zh-CN": "zh-CN",
493
+ zh_TW: "zh-TW",
494
+ "zh-TW": "zh-TW",
495
+ en: "en-US",
496
+ "en-US": "en-US",
497
+ ja: "ja-JP",
498
+ "ja-JP": "ja-JP"
499
+ };
500
+ return map[locale] || "zh-CN";
501
+ }
502
+ };
503
+
504
+ // src/i18n/adapters/desktop.ts
505
+ var ElectronI18nAdapter = class {
506
+ constructor() {
507
+ this.storageKey = "app_locale";
508
+ }
509
+ getSystemLocale() {
510
+ if (typeof navigator === "undefined") return "zh-CN";
511
+ const browserLocale = navigator.language;
512
+ return this.normalizeLocale(browserLocale);
513
+ }
514
+ async saveLocale(locale) {
515
+ if (typeof localStorage === "undefined") return;
516
+ localStorage.setItem(this.storageKey, locale);
517
+ }
518
+ async loadLocale() {
519
+ if (typeof localStorage === "undefined") return null;
520
+ const stored = localStorage.getItem(this.storageKey);
521
+ return stored;
522
+ }
523
+ normalizeLocale(locale) {
524
+ const map = {
525
+ "zh-CN": "zh-CN",
526
+ "zh-TW": "zh-TW",
527
+ "zh-HK": "zh-TW",
528
+ zh: "zh-CN",
529
+ "en-US": "en-US",
530
+ "en-GB": "en-US",
531
+ en: "en-US",
532
+ "ja-JP": "ja-JP",
533
+ ja: "ja-JP"
534
+ };
535
+ return map[locale] || "zh-CN";
536
+ }
537
+ };
538
+ var LANGUAGE_OPTIONS = [
539
+ { locale: "zh-CN", label: "\u7B80\u4F53\u4E2D\u6587", flag: "\u{1F1E8}\u{1F1F3}" },
540
+ { locale: "zh-TW", label: "\u7E41\u9AD4\u4E2D\u6587", flag: "\u{1F1F9}\u{1F1FC}" },
541
+ { locale: "en-US", label: "English", flag: "\u{1F1FA}\u{1F1F8}" },
542
+ { locale: "ja-JP", label: "\u65E5\u672C\u8A9E", flag: "\u{1F1EF}\u{1F1F5}" }
543
+ ];
544
+ function LanguageSwitcherButtons({
545
+ className = "",
546
+ onLanguageChange
547
+ }) {
548
+ const { locale, setLocale } = useTranslation();
549
+ const handleChange = (newLocale) => {
550
+ setLocale(newLocale);
551
+ onLanguageChange?.(newLocale);
552
+ };
553
+ return /* @__PURE__ */ React__default.default.createElement("div", { className: `flex gap-2 flex-wrap ${className}` }, LANGUAGE_OPTIONS.map((option) => /* @__PURE__ */ React__default.default.createElement(
554
+ "button",
555
+ {
556
+ key: option.locale,
557
+ onClick: () => handleChange(option.locale),
558
+ className: `
559
+ flex items-center gap-2 px-4 py-2 rounded-lg border-2
560
+ transition-all duration-200 font-medium
561
+ ${locale === option.locale ? "border-blue-500 bg-blue-50 text-blue-700 shadow-md" : "border-gray-300 bg-white text-gray-700 hover:border-blue-300 hover:bg-blue-50"}
562
+ `,
563
+ "aria-label": option.label
564
+ },
565
+ /* @__PURE__ */ React__default.default.createElement("span", { className: "text-xl" }, option.flag),
566
+ /* @__PURE__ */ React__default.default.createElement("span", { className: "text-sm" }, option.label)
567
+ )));
568
+ }
569
+ function LanguageSwitcherDropdown({
570
+ className = "",
571
+ onLanguageChange
572
+ }) {
573
+ const { locale, setLocale, t: t2 } = useTranslation();
574
+ const handleChange = (e) => {
575
+ const newLocale = e.target.value;
576
+ setLocale(newLocale);
577
+ onLanguageChange?.(newLocale);
578
+ };
579
+ return /* @__PURE__ */ React__default.default.createElement("div", { className: `flex flex-col gap-2 ${className}` }, /* @__PURE__ */ React__default.default.createElement("label", { htmlFor: "language-select", className: "text-sm font-medium text-gray-700" }, t2("language.label")), /* @__PURE__ */ React__default.default.createElement(
580
+ "select",
581
+ {
582
+ id: "language-select",
583
+ value: locale,
584
+ onChange: handleChange,
585
+ className: "\n px-4 py-2 rounded-lg border-2 border-gray-300 bg-white\n text-gray-700 font-medium cursor-pointer\n focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500\n hover:border-gray-400 transition-colors duration-200\n ",
586
+ "aria-label": t2("language.label")
587
+ },
588
+ LANGUAGE_OPTIONS.map((option) => /* @__PURE__ */ React__default.default.createElement("option", { key: option.locale, value: option.locale }, option.flag, " ", option.label))
589
+ ));
590
+ }
591
+ function LanguageSwitcherIcon({ className = "", onLanguageChange }) {
592
+ const { locale, setLocale } = useTranslation();
593
+ const [isOpen, setIsOpen] = React__default.default.useState(false);
594
+ const currentOption = LANGUAGE_OPTIONS.find((opt) => opt.locale === locale);
595
+ const handleChange = (newLocale) => {
596
+ setLocale(newLocale);
597
+ setIsOpen(false);
598
+ onLanguageChange?.(newLocale);
599
+ };
600
+ React__default.default.useEffect(() => {
601
+ const handleClickOutside = (event) => {
602
+ const target = event.target;
603
+ if (!target.closest(".language-switcher-icon-wrapper")) {
604
+ setIsOpen(false);
605
+ }
606
+ };
607
+ if (isOpen) {
608
+ document.addEventListener("mousedown", handleClickOutside);
609
+ return () => document.removeEventListener("mousedown", handleClickOutside);
610
+ }
611
+ return void 0;
612
+ }, [isOpen]);
613
+ return /* @__PURE__ */ React__default.default.createElement("div", { className: `relative language-switcher-icon-wrapper ${className}` }, /* @__PURE__ */ React__default.default.createElement(
614
+ "button",
615
+ {
616
+ onClick: () => setIsOpen(!isOpen),
617
+ className: "\n flex items-center gap-2 px-3 py-2 rounded-lg border-2 border-gray-300\n bg-white hover:border-blue-300 hover:bg-blue-50\n transition-all duration-200 cursor-pointer\n focus:outline-none focus:ring-2 focus:ring-blue-500\n ",
618
+ "aria-label": "Switch Language",
619
+ "aria-expanded": isOpen
620
+ },
621
+ /* @__PURE__ */ React__default.default.createElement("span", { className: "text-xl" }, currentOption?.flag),
622
+ /* @__PURE__ */ React__default.default.createElement("span", { className: `text-gray-600 text-xs transition-transform duration-200 ${isOpen ? "rotate-180" : ""}` }, "\u25BC")
623
+ ), isOpen && /* @__PURE__ */ React__default.default.createElement("div", { className: "\n absolute right-0 top-full mt-2 w-48\n bg-white border-2 border-gray-200 rounded-lg shadow-lg\n overflow-hidden z-50\n animate-in fade-in slide-in-from-top-2 duration-200\n " }, LANGUAGE_OPTIONS.map((option) => /* @__PURE__ */ React__default.default.createElement(
624
+ "button",
625
+ {
626
+ key: option.locale,
627
+ onClick: () => handleChange(option.locale),
628
+ className: `
629
+ w-full flex items-center justify-between px-4 py-3
630
+ transition-colors duration-150
631
+ ${locale === option.locale ? "bg-blue-50 text-blue-700" : "text-gray-700 hover:bg-gray-50"}
632
+ `
633
+ },
634
+ /* @__PURE__ */ React__default.default.createElement("div", { className: "flex items-center gap-3" }, /* @__PURE__ */ React__default.default.createElement("span", { className: "text-lg" }, option.flag), /* @__PURE__ */ React__default.default.createElement("span", { className: "text-sm font-medium" }, option.label)),
635
+ locale === option.locale && /* @__PURE__ */ React__default.default.createElement("span", { className: "text-blue-600 font-bold" }, "\u2713")
636
+ ))));
637
+ }
638
+ function LanguageSwitcher({
639
+ variant = "buttons",
640
+ className,
641
+ onLanguageChange
642
+ }) {
643
+ switch (variant) {
644
+ case "dropdown":
645
+ return /* @__PURE__ */ React__default.default.createElement(LanguageSwitcherDropdown, { className, onLanguageChange });
646
+ case "icon":
647
+ return /* @__PURE__ */ React__default.default.createElement(LanguageSwitcherIcon, { className, onLanguageChange });
648
+ case "buttons":
649
+ default:
650
+ return /* @__PURE__ */ React__default.default.createElement(LanguageSwitcherButtons, { className, onLanguageChange });
651
+ }
652
+ }
653
+
654
+ exports.ElectronI18nAdapter = ElectronI18nAdapter;
655
+ exports.LanguageSwitcher = LanguageSwitcher;
656
+ exports.LanguageSwitcherButtons = LanguageSwitcherButtons;
657
+ exports.LanguageSwitcherDropdown = LanguageSwitcherDropdown;
658
+ exports.LanguageSwitcherIcon = LanguageSwitcherIcon;
659
+ exports.ReactNativeI18nAdapter = ReactNativeI18nAdapter;
660
+ exports.TaroI18nAdapter = TaroI18nAdapter;
661
+ exports.WebI18nAdapter = WebI18nAdapter;
662
+ exports.createI18n = createI18n;
663
+ exports.enUS = en_US_default;
664
+ exports.getI18n = getI18n;
665
+ exports.initI18n = initI18n;
666
+ exports.t = t;
667
+ exports.useLocale = useLocale;
668
+ exports.useTranslation = useTranslation;
669
+ exports.zhCN = zh_CN_default;
670
+ //# sourceMappingURL=index.js.map
671
+ //# sourceMappingURL=index.js.map