lokal-react 1.3.2 → 1.3.6
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.d.mts +144 -0
- package/dist/index.d.ts +144 -0
- package/dist/index.js +357 -44
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +369 -36
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -2
- package/src/context/LokalContext.tsx +475 -37
- package/src/hooks/useStandaloneTranslate.ts +117 -0
- package/src/index.ts +30 -4
package/dist/index.mjs
CHANGED
|
@@ -1,18 +1,81 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
3
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
4
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
5
|
+
var __esm = (fn, res) => function __init() {
|
|
6
|
+
return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
|
|
7
|
+
};
|
|
8
|
+
var __export = (target, all) => {
|
|
9
|
+
for (var name in all)
|
|
10
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
11
|
+
};
|
|
12
|
+
var __copyProps = (to, from, except, desc) => {
|
|
13
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
14
|
+
for (let key of __getOwnPropNames(from))
|
|
15
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
16
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
17
|
+
}
|
|
18
|
+
return to;
|
|
19
|
+
};
|
|
20
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
21
|
+
|
|
1
22
|
// packages/react/src/context/LokalContext.tsx
|
|
23
|
+
var LokalContext_exports = {};
|
|
24
|
+
__export(LokalContext_exports, {
|
|
25
|
+
LokalProvider: () => LokalProvider,
|
|
26
|
+
T: () => T,
|
|
27
|
+
default: () => LokalContext_default,
|
|
28
|
+
useFormatters: () => useFormatters,
|
|
29
|
+
useHydrated: () => useHydrated,
|
|
30
|
+
useIsLoading: () => useIsLoading,
|
|
31
|
+
useLazyTranslations: () => useLazyTranslations,
|
|
32
|
+
useLocale: () => useLocale,
|
|
33
|
+
useLokal: () => useLokal,
|
|
34
|
+
useSafeTranslations: () => useSafeTranslations,
|
|
35
|
+
useTranslate: () => useTranslate
|
|
36
|
+
});
|
|
2
37
|
import { createContext, useContext, useState, useEffect, useCallback } from "react";
|
|
3
38
|
import { jsx } from "react/jsx-runtime";
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
39
|
+
function getPluralCategory(locale, count) {
|
|
40
|
+
const rules = {
|
|
41
|
+
en: (n) => n === 1 ? "one" : "other",
|
|
42
|
+
fr: (n) => n === 0 || n === 1 ? "one" : "many",
|
|
43
|
+
es: (n) => n === 1 ? "one" : "many",
|
|
44
|
+
de: (n) => n === 1 ? "one" : "other",
|
|
45
|
+
it: (n) => n === 1 ? "one" : "other",
|
|
46
|
+
ru: (n) => {
|
|
47
|
+
const mod10 = n % 10;
|
|
48
|
+
const mod100 = n % 100;
|
|
49
|
+
if (n === 1) return "one";
|
|
50
|
+
if (mod10 >= 2 && mod10 <= 4 && !(mod100 >= 12 && mod100 <= 14)) return "few";
|
|
51
|
+
if (mod10 === 0 || mod10 >= 5 || mod10 >= 11 && mod10 <= 15) return "many";
|
|
52
|
+
return "other";
|
|
53
|
+
},
|
|
54
|
+
ar: (n) => {
|
|
55
|
+
if (n === 0) return "zero";
|
|
56
|
+
if (n === 1) return "one";
|
|
57
|
+
if (n === 2) return "two";
|
|
58
|
+
const mod100 = n % 100;
|
|
59
|
+
if (mod100 >= 3 && mod100 <= 10) return "few";
|
|
60
|
+
if (mod100 >= 11 && mod100 <= 99) return "many";
|
|
61
|
+
return "other";
|
|
62
|
+
}
|
|
63
|
+
};
|
|
64
|
+
const rule = rules[locale] || rules["en"];
|
|
65
|
+
return rule(count);
|
|
66
|
+
}
|
|
67
|
+
function getNestedValue(obj, path) {
|
|
68
|
+
const keys = path.split(".");
|
|
69
|
+
let value = obj;
|
|
70
|
+
for (const k of keys) {
|
|
71
|
+
if (value && typeof value === "object" && k in value) {
|
|
72
|
+
value = value[k];
|
|
73
|
+
} else {
|
|
74
|
+
return "";
|
|
75
|
+
}
|
|
13
76
|
}
|
|
14
|
-
|
|
15
|
-
|
|
77
|
+
return typeof value === "string" ? value : "";
|
|
78
|
+
}
|
|
16
79
|
function LokalProvider({
|
|
17
80
|
children,
|
|
18
81
|
locale: initialLocale = "en",
|
|
@@ -21,31 +84,46 @@ function LokalProvider({
|
|
|
21
84
|
storage = defaultStorage,
|
|
22
85
|
namespace = "locales",
|
|
23
86
|
defaultLocale = "en",
|
|
24
|
-
onLocaleChange
|
|
87
|
+
onLocaleChange,
|
|
88
|
+
initialLocale: ssrInitialLocale,
|
|
89
|
+
initialTranslations: ssrInitialTranslations,
|
|
90
|
+
fallbackLocale = "en"
|
|
25
91
|
}) {
|
|
26
|
-
const [locale, setLocaleState] = useState(initialLocale);
|
|
27
|
-
const [translations, setTranslations] = useState(initialTranslations);
|
|
28
|
-
const [isLoading, setIsLoading] = useState(
|
|
92
|
+
const [locale, setLocaleState] = useState(ssrInitialLocale || initialLocale);
|
|
93
|
+
const [translations, setTranslations] = useState(ssrInitialTranslations || initialTranslations);
|
|
94
|
+
const [isLoading, setIsLoading] = useState(!!ssrInitialLocale);
|
|
95
|
+
const [isHydrated, setIsHydrated] = useState(!!ssrInitialLocale);
|
|
96
|
+
useEffect(() => {
|
|
97
|
+
if (ssrInitialLocale && !isHydrated) {
|
|
98
|
+
setIsHydrated(true);
|
|
99
|
+
setIsLoading(false);
|
|
100
|
+
}
|
|
101
|
+
}, [ssrInitialLocale, isHydrated]);
|
|
29
102
|
useEffect(() => {
|
|
30
103
|
const loadLocale = async () => {
|
|
31
104
|
try {
|
|
32
105
|
const savedLocale = await storage.getItem(`${namespace}-locale`);
|
|
33
106
|
if (savedLocale && locales.includes(savedLocale)) {
|
|
34
107
|
setLocaleState(savedLocale);
|
|
35
|
-
} else {
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
108
|
+
} else if (!ssrInitialLocale) {
|
|
109
|
+
if (typeof navigator !== "undefined") {
|
|
110
|
+
const browserLocale = navigator.language.split("-")[0];
|
|
111
|
+
if (locales.includes(browserLocale)) {
|
|
112
|
+
setLocaleState(browserLocale);
|
|
113
|
+
}
|
|
39
114
|
}
|
|
40
115
|
}
|
|
41
116
|
} catch (error) {
|
|
42
117
|
console.warn("Failed to load locale from storage:", error);
|
|
118
|
+
if (!ssrInitialLocale) {
|
|
119
|
+
setLocaleState(fallbackLocale);
|
|
120
|
+
}
|
|
43
121
|
} finally {
|
|
44
122
|
setIsLoading(false);
|
|
45
123
|
}
|
|
46
124
|
};
|
|
47
125
|
loadLocale();
|
|
48
|
-
}, [storage, locales, namespace]);
|
|
126
|
+
}, [storage, locales, namespace, ssrInitialLocale, fallbackLocale]);
|
|
49
127
|
useEffect(() => {
|
|
50
128
|
const loadTranslations = async () => {
|
|
51
129
|
try {
|
|
@@ -60,32 +138,24 @@ function LokalProvider({
|
|
|
60
138
|
console.warn("Failed to load translations from storage:", error);
|
|
61
139
|
}
|
|
62
140
|
};
|
|
63
|
-
if (!isLoading) {
|
|
141
|
+
if (!isLoading && !ssrInitialTranslations) {
|
|
64
142
|
loadTranslations();
|
|
65
143
|
}
|
|
66
|
-
}, [locale, storage, namespace, isLoading]);
|
|
144
|
+
}, [locale, storage, namespace, isLoading, ssrInitialTranslations]);
|
|
67
145
|
const setLocale = useCallback((newLocale) => {
|
|
68
146
|
if (!locales.includes(newLocale)) {
|
|
69
147
|
console.warn(`Locale ${newLocale} is not in the list of available locales`);
|
|
70
148
|
return;
|
|
71
149
|
}
|
|
72
150
|
setLocaleState(newLocale);
|
|
73
|
-
storage.setItem(`${namespace}-locale`, newLocale);
|
|
151
|
+
storage.setItem(`${namespace}-locale`, newLocale).catch(console.warn);
|
|
74
152
|
if (onLocaleChange) {
|
|
75
153
|
onLocaleChange(newLocale);
|
|
76
154
|
}
|
|
77
155
|
}, [locales, storage, namespace, onLocaleChange]);
|
|
78
|
-
const
|
|
79
|
-
const
|
|
80
|
-
|
|
81
|
-
for (const k of keys) {
|
|
82
|
-
if (value && typeof value === "object" && k in value) {
|
|
83
|
-
value = value[k];
|
|
84
|
-
} else {
|
|
85
|
-
return key;
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
if (typeof value !== "string") {
|
|
156
|
+
const translate = useCallback((key, params) => {
|
|
157
|
+
const value = getNestedValue(translations, key);
|
|
158
|
+
if (!value) {
|
|
89
159
|
return key;
|
|
90
160
|
}
|
|
91
161
|
if (params) {
|
|
@@ -96,13 +166,85 @@ function LokalProvider({
|
|
|
96
166
|
}
|
|
97
167
|
return value;
|
|
98
168
|
}, [translations]);
|
|
169
|
+
const translatePlural = useCallback((key, params) => {
|
|
170
|
+
const { count, ...restParams } = params;
|
|
171
|
+
const pluralCategory = getPluralCategory(locale, count);
|
|
172
|
+
const pluralKey = `${key}_${pluralCategory}`;
|
|
173
|
+
let value = getNestedValue(translations, pluralKey);
|
|
174
|
+
if (!value) {
|
|
175
|
+
value = getNestedValue(translations, key);
|
|
176
|
+
}
|
|
177
|
+
if (!value) {
|
|
178
|
+
return key;
|
|
179
|
+
}
|
|
180
|
+
const allParams = { count, ...restParams };
|
|
181
|
+
return Object.entries(allParams).reduce(
|
|
182
|
+
(str, [paramKey, paramValue]) => str.replace(new RegExp(`{{${paramKey}}}`, "g"), String(paramValue)),
|
|
183
|
+
value
|
|
184
|
+
);
|
|
185
|
+
}, [locale, translations]);
|
|
186
|
+
const translateGender = useCallback((key, params) => {
|
|
187
|
+
const { gender, ...restParams } = params;
|
|
188
|
+
const genderKey = `${key}_${gender}`;
|
|
189
|
+
let value = getNestedValue(translations, genderKey);
|
|
190
|
+
if (!value) {
|
|
191
|
+
value = getNestedValue(translations, key);
|
|
192
|
+
}
|
|
193
|
+
if (!value) {
|
|
194
|
+
return key;
|
|
195
|
+
}
|
|
196
|
+
const allParams = { gender, ...restParams };
|
|
197
|
+
return Object.entries(allParams).reduce(
|
|
198
|
+
(str, [paramKey, paramValue]) => str.replace(new RegExp(`{{${paramKey}}}`, "g"), String(paramValue)),
|
|
199
|
+
value
|
|
200
|
+
);
|
|
201
|
+
}, [translations]);
|
|
202
|
+
const translateChoice = useCallback((key, params) => {
|
|
203
|
+
const { value } = params;
|
|
204
|
+
const choiceKey = `${key}_${value}`;
|
|
205
|
+
let translation = getNestedValue(translations, choiceKey);
|
|
206
|
+
if (!translation) {
|
|
207
|
+
translation = getNestedValue(translations, key);
|
|
208
|
+
}
|
|
209
|
+
if (!translation) {
|
|
210
|
+
return key;
|
|
211
|
+
}
|
|
212
|
+
return translation;
|
|
213
|
+
}, [translations]);
|
|
214
|
+
const t = useCallback(Object.assign(
|
|
215
|
+
translate,
|
|
216
|
+
{
|
|
217
|
+
plural: translatePlural,
|
|
218
|
+
gender: translateGender,
|
|
219
|
+
choice: translateChoice
|
|
220
|
+
}
|
|
221
|
+
), [translate, translatePlural, translateGender, translateChoice]);
|
|
222
|
+
const formatDate = useCallback((date, options) => {
|
|
223
|
+
const dateObj = typeof date === "string" ? new Date(date) : date;
|
|
224
|
+
try {
|
|
225
|
+
return new Intl.DateTimeFormat(locale, options).format(dateObj);
|
|
226
|
+
} catch (error) {
|
|
227
|
+
console.warn("Date formatting failed:", error);
|
|
228
|
+
return dateObj.toLocaleDateString();
|
|
229
|
+
}
|
|
230
|
+
}, [locale]);
|
|
231
|
+
const formatNumber = useCallback((num, options) => {
|
|
232
|
+
try {
|
|
233
|
+
return new Intl.NumberFormat(locale, options).format(num);
|
|
234
|
+
} catch (error) {
|
|
235
|
+
console.warn("Number formatting failed:", error);
|
|
236
|
+
return num.toString();
|
|
237
|
+
}
|
|
238
|
+
}, [locale]);
|
|
99
239
|
const contextValue = {
|
|
100
240
|
locale,
|
|
101
241
|
setLocale,
|
|
102
242
|
locales,
|
|
103
243
|
t,
|
|
104
244
|
translations,
|
|
105
|
-
isLoading
|
|
245
|
+
isLoading,
|
|
246
|
+
formatDate,
|
|
247
|
+
formatNumber
|
|
106
248
|
};
|
|
107
249
|
return /* @__PURE__ */ jsx(LokalContext.Provider, { value: contextValue, children });
|
|
108
250
|
}
|
|
@@ -113,8 +255,199 @@ function useLokal() {
|
|
|
113
255
|
}
|
|
114
256
|
return context;
|
|
115
257
|
}
|
|
258
|
+
function useTranslate() {
|
|
259
|
+
const { t } = useLokal();
|
|
260
|
+
return t;
|
|
261
|
+
}
|
|
262
|
+
function useLocale() {
|
|
263
|
+
const { locale, setLocale, locales } = useLokal();
|
|
264
|
+
return { locale, setLocale, locales };
|
|
265
|
+
}
|
|
266
|
+
function useFormatters() {
|
|
267
|
+
const { formatDate, formatNumber } = useLokal();
|
|
268
|
+
return { formatDate, formatNumber };
|
|
269
|
+
}
|
|
270
|
+
function useIsLoading() {
|
|
271
|
+
const { isLoading } = useLokal();
|
|
272
|
+
return isLoading;
|
|
273
|
+
}
|
|
274
|
+
function T({
|
|
275
|
+
children,
|
|
276
|
+
params,
|
|
277
|
+
plural,
|
|
278
|
+
gender,
|
|
279
|
+
className,
|
|
280
|
+
as: Component = "span"
|
|
281
|
+
}) {
|
|
282
|
+
const { t } = useLokal();
|
|
283
|
+
let translatedText;
|
|
284
|
+
if (plural !== void 0) {
|
|
285
|
+
translatedText = t.plural(children, { count: plural, ...params || {} });
|
|
286
|
+
} else if (gender) {
|
|
287
|
+
translatedText = t.gender(children, { gender, ...params || {} });
|
|
288
|
+
} else {
|
|
289
|
+
translatedText = t(children, params);
|
|
290
|
+
}
|
|
291
|
+
return /* @__PURE__ */ jsx(Component, { className, children: translatedText });
|
|
292
|
+
}
|
|
293
|
+
function useLazyTranslations(namespace) {
|
|
294
|
+
const { t, translations, isLoading } = useLokal();
|
|
295
|
+
const translate = useCallback((key, params) => {
|
|
296
|
+
const namespacedKey = `${namespace}.${key}`;
|
|
297
|
+
const value = getNestedValue(translations, namespacedKey);
|
|
298
|
+
if (!value) {
|
|
299
|
+
return key;
|
|
300
|
+
}
|
|
301
|
+
if (params) {
|
|
302
|
+
return Object.entries(params).reduce(
|
|
303
|
+
(str, [paramKey, paramValue]) => str.replace(new RegExp(`{{${paramKey}}}`, "g"), String(paramValue)),
|
|
304
|
+
value
|
|
305
|
+
);
|
|
306
|
+
}
|
|
307
|
+
return value;
|
|
308
|
+
}, [translations, namespace]);
|
|
309
|
+
return { t: translate, isLoading };
|
|
310
|
+
}
|
|
311
|
+
function useHydrated() {
|
|
312
|
+
const [hydrated, setHydrated] = useState(false);
|
|
313
|
+
useEffect(() => {
|
|
314
|
+
setHydrated(true);
|
|
315
|
+
}, []);
|
|
316
|
+
return hydrated;
|
|
317
|
+
}
|
|
318
|
+
function useSafeTranslations() {
|
|
319
|
+
const { t } = useLokal();
|
|
320
|
+
const isHydrated = useHydrated();
|
|
321
|
+
const safeT = (key, params) => {
|
|
322
|
+
if (!isHydrated) {
|
|
323
|
+
return key;
|
|
324
|
+
}
|
|
325
|
+
return t(key, params);
|
|
326
|
+
};
|
|
327
|
+
safeT.plural = (key, params) => {
|
|
328
|
+
if (!isHydrated) return key;
|
|
329
|
+
return t.plural(key, params);
|
|
330
|
+
};
|
|
331
|
+
safeT.gender = (key, params) => {
|
|
332
|
+
if (!isHydrated) return key;
|
|
333
|
+
return t.gender(key, params);
|
|
334
|
+
};
|
|
335
|
+
safeT.choice = (key, params) => {
|
|
336
|
+
if (!isHydrated) return key;
|
|
337
|
+
return t.choice(key, params);
|
|
338
|
+
};
|
|
339
|
+
return { t: safeT, isHydrated };
|
|
340
|
+
}
|
|
341
|
+
var LokalContext, defaultStorage, LokalContext_default;
|
|
342
|
+
var init_LokalContext = __esm({
|
|
343
|
+
"packages/react/src/context/LokalContext.tsx"() {
|
|
344
|
+
"use strict";
|
|
345
|
+
LokalContext = createContext(null);
|
|
346
|
+
defaultStorage = {
|
|
347
|
+
getItem: (key) => {
|
|
348
|
+
if (typeof window === "undefined") return Promise.resolve(null);
|
|
349
|
+
return Promise.resolve(localStorage.getItem(key));
|
|
350
|
+
},
|
|
351
|
+
setItem: (key, value) => {
|
|
352
|
+
if (typeof window === "undefined") return Promise.resolve();
|
|
353
|
+
localStorage.setItem(key, value);
|
|
354
|
+
return Promise.resolve();
|
|
355
|
+
}
|
|
356
|
+
};
|
|
357
|
+
LokalContext_default = LokalContext;
|
|
358
|
+
}
|
|
359
|
+
});
|
|
360
|
+
|
|
361
|
+
// packages/react/src/index.ts
|
|
362
|
+
init_LokalContext();
|
|
363
|
+
|
|
364
|
+
// packages/react/src/hooks/useStandaloneTranslate.ts
|
|
365
|
+
import { useMemo } from "react";
|
|
366
|
+
function getNestedValue2(obj, path) {
|
|
367
|
+
const keys = path.split(".");
|
|
368
|
+
let value = obj;
|
|
369
|
+
for (const k of keys) {
|
|
370
|
+
if (value && typeof value === "object" && k in value) {
|
|
371
|
+
value = value[k];
|
|
372
|
+
} else {
|
|
373
|
+
return "";
|
|
374
|
+
}
|
|
375
|
+
}
|
|
376
|
+
return typeof value === "string" ? value : "";
|
|
377
|
+
}
|
|
378
|
+
function getPluralCategory2(locale, count) {
|
|
379
|
+
const rules = {
|
|
380
|
+
en: (n) => n === 1 ? "one" : "other",
|
|
381
|
+
fr: (n) => n === 0 || n === 1 ? "one" : "many",
|
|
382
|
+
es: (n) => n === 1 ? "one" : "many",
|
|
383
|
+
de: (n) => n === 1 ? "one" : "other"
|
|
384
|
+
};
|
|
385
|
+
const rule = rules[locale] || rules["en"];
|
|
386
|
+
return rule(count);
|
|
387
|
+
}
|
|
388
|
+
function createTranslate(translations, locale = "en") {
|
|
389
|
+
const translate = (key, params) => {
|
|
390
|
+
const value = getNestedValue2(translations, key);
|
|
391
|
+
if (!value) return key;
|
|
392
|
+
if (params) {
|
|
393
|
+
return Object.entries(params).reduce(
|
|
394
|
+
(str, [paramKey, paramValue]) => str.replace(new RegExp(`{{${paramKey}}}`, "g"), String(paramValue)),
|
|
395
|
+
value
|
|
396
|
+
);
|
|
397
|
+
}
|
|
398
|
+
return value;
|
|
399
|
+
};
|
|
400
|
+
const translatePlural = (key, params) => {
|
|
401
|
+
const { count, ...restParams } = params;
|
|
402
|
+
const pluralCategory = getPluralCategory2(locale, count);
|
|
403
|
+
let value = getNestedValue2(translations, `${key}_${pluralCategory}`);
|
|
404
|
+
if (!value) value = getNestedValue2(translations, key);
|
|
405
|
+
if (!value) return key;
|
|
406
|
+
const allParams = { count, ...restParams };
|
|
407
|
+
return Object.entries(allParams).reduce(
|
|
408
|
+
(str, [paramKey, paramValue]) => str.replace(new RegExp(`{{${paramKey}}}`, "g"), String(paramValue)),
|
|
409
|
+
value
|
|
410
|
+
);
|
|
411
|
+
};
|
|
412
|
+
const translateGender = (key, params) => {
|
|
413
|
+
const { gender, ...restParams } = params;
|
|
414
|
+
let value = getNestedValue2(translations, `${key}_${gender}`);
|
|
415
|
+
if (!value) value = getNestedValue2(translations, key);
|
|
416
|
+
if (!value) return key;
|
|
417
|
+
const allParams = { gender, ...restParams };
|
|
418
|
+
return Object.entries(allParams).reduce(
|
|
419
|
+
(str, [paramKey, paramValue]) => str.replace(new RegExp(`{{${paramKey}}}`, "g"), String(paramValue)),
|
|
420
|
+
value
|
|
421
|
+
);
|
|
422
|
+
};
|
|
423
|
+
const translateChoice = (key, params) => {
|
|
424
|
+
const { value } = params;
|
|
425
|
+
let translation = getNestedValue2(translations, `${key}_${value}`);
|
|
426
|
+
if (!translation) translation = getNestedValue2(translations, key);
|
|
427
|
+
return translation || key;
|
|
428
|
+
};
|
|
429
|
+
const extendedFn = translate;
|
|
430
|
+
extendedFn.plural = translatePlural;
|
|
431
|
+
extendedFn.gender = translateGender;
|
|
432
|
+
extendedFn.choice = translateChoice;
|
|
433
|
+
return extendedFn;
|
|
434
|
+
}
|
|
435
|
+
function useStandaloneTranslate() {
|
|
436
|
+
const { t, translations, locale } = (init_LokalContext(), __toCommonJS(LokalContext_exports)).useLokal();
|
|
437
|
+
return useMemo(() => createTranslate(translations, locale), [translations, locale]);
|
|
438
|
+
}
|
|
116
439
|
export {
|
|
117
440
|
LokalProvider,
|
|
118
|
-
|
|
441
|
+
T,
|
|
442
|
+
createTranslate,
|
|
443
|
+
useFormatters,
|
|
444
|
+
useHydrated,
|
|
445
|
+
useIsLoading,
|
|
446
|
+
useLazyTranslations,
|
|
447
|
+
useLocale,
|
|
448
|
+
useLokal,
|
|
449
|
+
useSafeTranslations,
|
|
450
|
+
useStandaloneTranslate,
|
|
451
|
+
useTranslate
|
|
119
452
|
};
|
|
120
453
|
//# sourceMappingURL=index.mjs.map
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/context/LokalContext.tsx"],"sourcesContent":["import React, { createContext, useContext, useState, useEffect, useCallback, ReactNode } from 'react';\nimport type { LocaleData } from 'lokal-core';\n\n// Type for translation function\nexport type TranslateFunction = <K extends string>(\n key: K,\n params?: Record<string, string | number>\n) => string;\n\n// Storage interface for different platforms\nexport interface StorageInterface {\n getItem(key: string): Promise<string | null>;\n setItem(key: string, value: string): Promise<void>;\n}\n\n// Default to localStorage for web\nconst defaultStorage: StorageInterface = {\n getItem: (key: string) => {\n if (typeof window === 'undefined') return Promise.resolve(null);\n return Promise.resolve(localStorage.getItem(key));\n },\n setItem: (key: string, value: string) => {\n if (typeof window === 'undefined') return Promise.resolve();\n localStorage.setItem(key, value);\n return Promise.resolve();\n },\n};\n\nexport interface LokalContextValue {\n locale: string;\n setLocale: (locale: string) => void;\n locales: string[];\n t: TranslateFunction;\n translations: LocaleData;\n isLoading: boolean;\n}\n\nconst LokalContext = createContext<LokalContextValue | null>(null);\n\nexport interface LokalProviderProps {\n children: ReactNode;\n locale?: string;\n locales?: string[];\n translations?: LocaleData;\n storage?: StorageInterface;\n namespace?: string;\n defaultLocale?: string;\n onLocaleChange?: (locale: string) => void;\n}\n\ninterface StoredTranslations {\n [locale: string]: LocaleData;\n}\n\n/**\n * LokalProvider - Provides localization context to your React app\n */\nexport function LokalProvider({\n children,\n locale: initialLocale = 'en',\n locales = ['en'],\n translations: initialTranslations = {},\n storage = defaultStorage,\n namespace = 'locales',\n defaultLocale = 'en',\n onLocaleChange,\n}: LokalProviderProps) {\n const [locale, setLocaleState] = useState<string>(initialLocale);\n const [translations, setTranslations] = useState<LocaleData>(initialTranslations);\n const [isLoading, setIsLoading] = useState<boolean>(true);\n\n // Load saved locale and translations from storage\n useEffect(() => {\n const loadLocale = async () => {\n try {\n const savedLocale = await storage.getItem(`${namespace}-locale`);\n if (savedLocale && locales.includes(savedLocale)) {\n setLocaleState(savedLocale);\n } else {\n // Try to detect from browser\n const browserLocale = navigator.language.split('-')[0];\n if (locales.includes(browserLocale)) {\n setLocaleState(browserLocale);\n }\n }\n } catch (error) {\n console.warn('Failed to load locale from storage:', error);\n } finally {\n setIsLoading(false);\n }\n };\n\n loadLocale();\n }, [storage, locales, namespace]);\n\n // Load translations for current locale\n useEffect(() => {\n const loadTranslations = async () => {\n try {\n const storedData = await storage.getItem(`${namespace}-translations`);\n if (storedData) {\n const parsed: StoredTranslations = JSON.parse(storedData);\n if (parsed[locale]) {\n setTranslations(parsed[locale]);\n }\n }\n } catch (error) {\n console.warn('Failed to load translations from storage:', error);\n }\n };\n\n if (!isLoading) {\n loadTranslations();\n }\n }, [locale, storage, namespace, isLoading]);\n\n // Set locale and persist\n const setLocale = useCallback((newLocale: string) => {\n if (!locales.includes(newLocale)) {\n console.warn(`Locale ${newLocale} is not in the list of available locales`);\n return;\n }\n\n setLocaleState(newLocale);\n storage.setItem(`${namespace}-locale`, newLocale);\n\n if (onLocaleChange) {\n onLocaleChange(newLocale);\n }\n }, [locales, storage, namespace, onLocaleChange]);\n\n // Translation function\n const t = useCallback<TranslateFunction>((key, params) => {\n const keys = key.split('.');\n let value: any = translations;\n\n for (const k of keys) {\n if (value && typeof value === 'object' && k in value) {\n value = value[k];\n } else {\n // Return key if not found\n return key;\n }\n }\n\n if (typeof value !== 'string') {\n return key;\n }\n\n // Replace parameters\n if (params) {\n return Object.entries(params).reduce(\n (str, [paramKey, paramValue]) => str.replace(new RegExp(`{{${paramKey}}}`, 'g'), String(paramValue)),\n value\n );\n }\n\n return value;\n }, [translations]);\n\n const contextValue: LokalContextValue = {\n locale,\n setLocale,\n locales,\n t,\n translations,\n isLoading,\n };\n\n return (\n <LokalContext.Provider value={contextValue}>\n {children}\n </LokalContext.Provider>\n );\n}\n\n/**\n * Hook to access the Lokal context\n */\nexport function useLokal(): LokalContextValue {\n const context = useContext(LokalContext);\n\n if (!context) {\n throw new Error('useLokal must be used within a LokalProvider');\n }\n\n return context;\n}\n\nexport default LokalContext;\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/context/LokalContext.tsx","../src/index.ts","../src/hooks/useStandaloneTranslate.ts"],"sourcesContent":["import React, { createContext, useContext, useState, useEffect, useCallback, ReactNode } from 'react';\nimport type { LocaleData } from 'lokal-core';\n\n// ============================================\n// Type Definitions\n// ============================================\n\n// Type for translation function\nexport type TranslateFunction = <K extends string>(\n key: K,\n params?: Record<string, string | number>\n) => string;\n\n// Pluralization types\nexport type PluralCategory = 'zero' | 'one' | 'two' | 'few' | 'many' | 'other';\n\nexport interface PluralParams {\n count: number;\n [key: string]: string | number;\n}\n\n// Gender types\nexport type GenderCategory = 'male' | 'female' | 'other';\n\nexport interface GenderParams {\n gender: GenderCategory;\n [key: string]: string | number;\n}\n\n// Extended translation function with pluralization and gender\nexport interface ExtendedTranslateFunction {\n // Basic translation\n <K extends string>(key: K, params?: Record<string, string | number>): string;\n\n // Pluralization - use key like \"items_plural\" with {count}\n plural: <K extends string>(key: K, params: PluralParams) => string;\n\n // Gender - use key like \"user_gender\" with {gender}\n gender: <K extends string>(key: K, params: GenderParams) => string;\n\n // Choice/select - use key like \"color_choice\" with {value}\n choice: <K extends string>(key: K, params: { value: string | number }) => string;\n}\n\n// Storage interface for different platforms\nexport interface StorageInterface {\n getItem(key: string): Promise<string | null>;\n setItem(key: string, value: string): Promise<void>;\n}\n\n// Date formatting options\nexport interface DateFormatOptions {\n year?: 'numeric' | '2-digit';\n month?: 'numeric' | '2-digit' | 'long' | 'short' | 'narrow';\n day?: 'numeric' | '2-digit';\n hour?: 'numeric' | '2-digit';\n minute?: 'numeric' | '2-digit';\n second?: 'numeric' | '2-digit';\n timeZoneName?: 'short' | 'long';\n}\n\n// Number formatting options\nexport interface NumberFormatOptions {\n style?: 'decimal' | 'currency' | 'percent' | 'unit';\n currency?: string;\n currencyDisplay?: 'symbol' | 'code' | 'name';\n minimumFractionDigits?: number;\n maximumFractionDigits?: number;\n useGrouping?: boolean;\n unit?: string;\n unitDisplay?: 'long' | 'short' | 'narrow';\n}\n\n// ============================================\n// Context Value\n// ============================================\n\nexport interface LokalContextValue {\n locale: string;\n setLocale: (locale: string) => void;\n locales: string[];\n t: ExtendedTranslateFunction;\n translations: LocaleData;\n isLoading: boolean;\n // Date/Number formatting\n formatDate: (date: Date | string, options?: DateFormatOptions) => string;\n formatNumber: (num: number, options?: NumberFormatOptions) => string;\n}\n\n// ============================================\n// Context Creation\n// ============================================\n\nconst LokalContext = createContext<LokalContextValue | null>(null);\n\n// ============================================\n// Storage Interface\n// ============================================\n\n// Default to localStorage for web\nconst defaultStorage: StorageInterface = {\n getItem: (key: string) => {\n if (typeof window === 'undefined') return Promise.resolve(null);\n return Promise.resolve(localStorage.getItem(key));\n },\n setItem: (key: string, value: string) => {\n if (typeof window === 'undefined') return Promise.resolve();\n localStorage.setItem(key, value);\n return Promise.resolve();\n },\n};\n\n// ============================================\n// Helper Functions\n// ============================================\n\n/**\n * Get plural category based on locale and count\n */\nfunction getPluralCategory(locale: string, count: number): PluralCategory {\n // CLDR plural rules implementation\n const rules: Record<string, (n: number) => PluralCategory> = {\n en: (n) => n === 1 ? 'one' : 'other',\n fr: (n) => n === 0 || n === 1 ? 'one' : 'many',\n es: (n) => n === 1 ? 'one' : 'many',\n de: (n) => n === 1 ? 'one' : 'other',\n it: (n) => n === 1 ? 'one' : 'other',\n ru: (n) => {\n const mod10 = n % 10;\n const mod100 = n % 100;\n if (n === 1) return 'one';\n if (mod10 >= 2 && mod10 <= 4 && !(mod100 >= 12 && mod100 <= 14)) return 'few';\n if (mod10 === 0 || mod10 >= 5 || mod10 >= 11 && mod10 <= 15) return 'many';\n return 'other';\n },\n ar: (n) => {\n if (n === 0) return 'zero';\n if (n === 1) return 'one';\n if (n === 2) return 'two';\n const mod100 = n % 100;\n if (mod100 >= 3 && mod100 <= 10) return 'few';\n if (mod100 >= 11 && mod100 <= 99) return 'many';\n return 'other';\n },\n };\n\n const rule = rules[locale] || rules['en'];\n return rule(count);\n}\n\n/**\n * Get nested value from object using dot notation\n */\nfunction getNestedValue(obj: any, path: string): string {\n const keys = path.split('.');\n let value: any = obj;\n\n for (const k of keys) {\n if (value && typeof value === 'object' && k in value) {\n value = value[k];\n } else {\n return '';\n }\n }\n\n return typeof value === 'string' ? value : '';\n}\n\n/**\n * Set nested value in object using dot notation\n */\nfunction setNestedValue(obj: any, path: string, value: string): void {\n const keys = path.split('.');\n let current = obj;\n\n for (let i = 0; i < keys.length - 1; i++) {\n const key = keys[i];\n if (!(key in current)) {\n current[key] = {};\n }\n current = current[key];\n }\n\n current[keys[keys.length - 1]] = value;\n}\n\n// ============================================\n// Provider Props\n// ============================================\n\nexport interface LokalProviderProps {\n children: ReactNode;\n locale?: string;\n locales?: string[];\n translations?: LocaleData;\n storage?: StorageInterface;\n namespace?: string;\n defaultLocale?: string;\n onLocaleChange?: (locale: string) => void;\n // SSR Support\n initialLocale?: string;\n initialTranslations?: LocaleData;\n fallbackLocale?: string;\n}\n\ninterface StoredTranslations {\n [locale: string]: LocaleData;\n}\n\n// ============================================\n// LokalProvider Component\n// ============================================\n\nexport function LokalProvider({\n children,\n locale: initialLocale = 'en',\n locales = ['en'],\n translations: initialTranslations = {},\n storage = defaultStorage,\n namespace = 'locales',\n defaultLocale = 'en',\n onLocaleChange,\n initialLocale: ssrInitialLocale,\n initialTranslations: ssrInitialTranslations,\n fallbackLocale = 'en',\n}: LokalProviderProps) {\n // Use SSR initial values if provided, otherwise use client-side state\n const [locale, setLocaleState] = useState<string>(ssrInitialLocale || initialLocale);\n const [translations, setTranslations] = useState<LocaleData>(ssrInitialTranslations || initialTranslations);\n const [isLoading, setIsLoading] = useState<boolean>(!!ssrInitialLocale);\n const [isHydrated, setIsHydrated] = useState<boolean>(!!ssrInitialLocale);\n\n // Handle hydration for SSR\n useEffect(() => {\n if (ssrInitialLocale && !isHydrated) {\n setIsHydrated(true);\n setIsLoading(false);\n }\n }, [ssrInitialLocale, isHydrated]);\n\n // Load saved locale and translations from storage\n useEffect(() => {\n const loadLocale = async () => {\n try {\n const savedLocale = await storage.getItem(`${namespace}-locale`);\n if (savedLocale && locales.includes(savedLocale)) {\n setLocaleState(savedLocale);\n } else if (!ssrInitialLocale) {\n // Try to detect from browser\n if (typeof navigator !== 'undefined') {\n const browserLocale = navigator.language.split('-')[0];\n if (locales.includes(browserLocale)) {\n setLocaleState(browserLocale);\n }\n }\n }\n } catch (error) {\n console.warn('Failed to load locale from storage:', error);\n if (!ssrInitialLocale) {\n setLocaleState(fallbackLocale);\n }\n } finally {\n setIsLoading(false);\n }\n };\n\n loadLocale();\n }, [storage, locales, namespace, ssrInitialLocale, fallbackLocale]);\n\n // Load translations for current locale\n useEffect(() => {\n const loadTranslations = async () => {\n try {\n const storedData = await storage.getItem(`${namespace}-translations`);\n if (storedData) {\n const parsed: StoredTranslations = JSON.parse(storedData);\n if (parsed[locale]) {\n setTranslations(parsed[locale]);\n }\n }\n } catch (error) {\n console.warn('Failed to load translations from storage:', error);\n }\n };\n\n if (!isLoading && !ssrInitialTranslations) {\n loadTranslations();\n }\n }, [locale, storage, namespace, isLoading, ssrInitialTranslations]);\n\n // Set locale and persist\n const setLocale = useCallback((newLocale: string) => {\n if (!locales.includes(newLocale)) {\n console.warn(`Locale ${newLocale} is not in the list of available locales`);\n return;\n }\n\n setLocaleState(newLocale);\n storage.setItem(`${namespace}-locale`, newLocale).catch(console.warn);\n\n if (onLocaleChange) {\n onLocaleChange(newLocale);\n }\n }, [locales, storage, namespace, onLocaleChange]);\n\n // Basic translation function\n const translate = useCallback((key: string, params?: Record<string, string | number>): string => {\n const value = getNestedValue(translations, key);\n\n if (!value) {\n // Return key if not found\n return key;\n }\n\n // Replace parameters\n if (params) {\n return Object.entries(params).reduce(\n (str, [paramKey, paramValue]) => str.replace(new RegExp(`{{${paramKey}}}`, 'g'), String(paramValue)),\n value\n );\n }\n\n return value;\n }, [translations]);\n\n // Extended translation function with pluralization\n const translatePlural = useCallback((key: string, params: PluralParams): string => {\n const { count, ...restParams } = params;\n const pluralCategory = getPluralCategory(locale, count);\n\n // Try plural-specific key first (e.g., \"items_one\", \"items_other\")\n const pluralKey = `${key}_${pluralCategory}`;\n let value = getNestedValue(translations, pluralKey);\n\n // Fall back to base key if plural form not found\n if (!value) {\n value = getNestedValue(translations, key);\n }\n\n if (!value) {\n return key;\n }\n\n // Replace all parameters including count\n const allParams = { count, ...restParams };\n return Object.entries(allParams).reduce(\n (str, [paramKey, paramValue]) => str.replace(new RegExp(`{{${paramKey}}}`, 'g'), String(paramValue)),\n value\n );\n }, [locale, translations]);\n\n // Extended translation function with gender\n const translateGender = useCallback((key: string, params: GenderParams): string => {\n const { gender, ...restParams } = params;\n\n // Try gender-specific key first (e.g., \"user_male\", \"user_female\")\n const genderKey = `${key}_${gender}`;\n let value = getNestedValue(translations, genderKey);\n\n // Fall back to base key if gender form not found\n if (!value) {\n value = getNestedValue(translations, key);\n }\n\n if (!value) {\n return key;\n }\n\n // Replace all parameters including gender\n const allParams = { gender, ...restParams };\n return Object.entries(allParams).reduce(\n (str, [paramKey, paramValue]) => str.replace(new RegExp(`{{${paramKey}}}`, 'g'), String(paramValue)),\n value\n );\n }, [translations]);\n\n // Choice/select translation\n const translateChoice = useCallback((key: string, params: { value: string | number }): string => {\n const { value } = params;\n\n // Try value-specific key first (e.g., \"color_red\", \"color_blue\")\n const choiceKey = `${key}_${value}`;\n let translation = getNestedValue(translations, choiceKey);\n\n // Fall back to base key if choice not found\n if (!translation) {\n translation = getNestedValue(translations, key);\n }\n\n if (!translation) {\n return key;\n }\n\n return translation;\n }, [translations]);\n\n // Extended translate function\n const t = useCallback<ExtendedTranslateFunction>(Object.assign(\n translate,\n {\n plural: translatePlural,\n gender: translateGender,\n choice: translateChoice,\n }\n ), [translate, translatePlural, translateGender, translateChoice]);\n\n // Date formatting\n const formatDate = useCallback((date: Date | string, options?: DateFormatOptions): string => {\n const dateObj = typeof date === 'string' ? new Date(date) : date;\n\n try {\n return new Intl.DateTimeFormat(locale, options as Intl.DateTimeFormatOptions).format(dateObj);\n } catch (error) {\n console.warn('Date formatting failed:', error);\n return dateObj.toLocaleDateString();\n }\n }, [locale]);\n\n // Number formatting\n const formatNumber = useCallback((num: number, options?: NumberFormatOptions): string => {\n try {\n return new Intl.NumberFormat(locale, options as Intl.NumberFormatOptions).format(num);\n } catch (error) {\n console.warn('Number formatting failed:', error);\n return num.toString();\n }\n }, [locale]);\n\n const contextValue: LokalContextValue = {\n locale,\n setLocale,\n locales,\n t,\n translations,\n isLoading,\n formatDate,\n formatNumber,\n };\n\n return (\n <LokalContext.Provider value={contextValue}>\n {children}\n </LokalContext.Provider>\n );\n}\n\n// ============================================\n// Hooks\n// ============================================\n\n/**\n * Hook to access the full Lokal context\n */\nexport function useLokal(): LokalContextValue {\n const context = useContext(LokalContext);\n\n if (!context) {\n throw new Error('useLokal must be used within a LokalProvider');\n }\n\n return context;\n}\n\n/**\n * Hook to access only the translation function\n */\nexport function useTranslate(): ExtendedTranslateFunction {\n const { t } = useLokal();\n return t;\n}\n\n/**\n * Hook to access locale and setter\n */\nexport function useLocale(): { locale: string; setLocale: (locale: string) => void; locales: string[] } {\n const { locale, setLocale, locales } = useLokal();\n return { locale, setLocale, locales };\n}\n\n/**\n * Hook to access date/number formatters\n */\nexport function useFormatters(): { formatDate: (date: Date | string, options?: DateFormatOptions) => string; formatNumber: (num: number, options?: NumberFormatOptions) => string } {\n const { formatDate, formatNumber } = useLokal();\n return { formatDate, formatNumber };\n}\n\n/**\n * Hook to check if translations are loading\n */\nexport function useIsLoading(): boolean {\n const { isLoading } = useLokal();\n return isLoading;\n}\n\n// ============================================\n// T Component JSX Trans forlations\n// ============================================\n\ninterface TComponentProps {\n children: string;\n params?: Record<string, string | number>;\n plural?: number;\n gender?: GenderCategory;\n className?: string;\n as?: React.ElementType;\n}\n\n/**\n * T Component - Translate content directly in JSX\n * Usage: <T>hello_world</T> or <T params={{name: 'John'}}>greeting</T>\n */\nexport function T({\n children,\n params,\n plural,\n gender,\n className,\n as: Component = 'span'\n}: TComponentProps) {\n const { t } = useLokal();\n\n let translatedText: string;\n\n if (plural !== undefined) {\n translatedText = t.plural(children, { count: plural, ...(params || {}) });\n } else if (gender) {\n translatedText = t.gender(children, { gender, ...(params || {}) });\n } else {\n translatedText = t(children as any, params);\n }\n\n return (\n <Component className={className}>\n {translatedText}\n </Component>\n );\n}\n\n// ============================================\n// Lazy Translation Hook\n// ============================================\n\n/**\n * Hook for lazy-loaded translations (useful for code splitting)\n */\nexport function useLazyTranslations(namespace: string) {\n const { t, translations, isLoading } = useLokal();\n\n const translate = useCallback((key: string, params?: Record<string, string | number>): string => {\n const namespacedKey = `${namespace}.${key}`;\n const value = getNestedValue(translations, namespacedKey);\n\n if (!value) {\n return key;\n }\n\n if (params) {\n return Object.entries(params).reduce(\n (str, [paramKey, paramValue]) =>\n str.replace(new RegExp(`{{${paramKey}}}`, 'g'), String(paramValue)),\n value\n );\n }\n\n return value;\n }, [translations, namespace]);\n\n return { t: translate, isLoading };\n}\n\n// ============================================\n// SSR Hydration Helper\n// ============================================\n\n/**\n * Hook to handle SSR hydration\n * Returns true until client-side hydration is complete\n */\nexport function useHydrated(): boolean {\n const [hydrated, setHydrated] = useState(false);\n\n useEffect(() => {\n setHydrated(true);\n }, []);\n\n return hydrated;\n}\n\n/**\n * Hook to get translations only after hydration\n * Prevents hydration mismatches\n */\nexport function useSafeTranslations(): { t: ExtendedTranslateFunction; isHydrated: boolean } {\n const { t } = useLokal();\n const isHydrated = useHydrated();\n \n // Simple wrapper that returns key during SSR to prevent mismatch\n const safeT = (key: string, params?: Record<string, string | number>): string => {\n if (!isHydrated) {\n return key;\n }\n return t(key, params);\n };\n \n safeT.plural = (key: string, params: PluralParams): string => {\n if (!isHydrated) return key;\n return t.plural(key, params);\n };\n \n safeT.gender = (key: string, params: GenderParams): string => {\n if (!isHydrated) return key;\n return t.gender(key, params);\n };\n \n safeT.choice = (key: string, params: { value: string | number }): string => {\n if (!isHydrated) return key;\n return t.choice(key, params);\n };\n \n return { t: safeT as ExtendedTranslateFunction, isHydrated };\n}\n\n// ============================================\n// Default Export\n// ============================================\n\nexport default LokalContext;\n","// Main exports - Hooks & Components\nexport { \n LokalProvider, \n useLokal, \n useTranslate, \n useLocale, \n useFormatters, \n useIsLoading,\n useLazyTranslations,\n useHydrated,\n useSafeTranslations,\n T \n} from './context/LokalContext';\n\n// Standalone translation\nexport { createTranslate, useStandaloneTranslate } from './hooks/useStandaloneTranslate';\n\nexport type { \n LokalProviderProps, \n TranslateFunction, \n ExtendedTranslateFunction,\n StorageInterface,\n LokalContextValue,\n PluralParams,\n PluralCategory,\n GenderParams,\n GenderCategory,\n DateFormatOptions,\n NumberFormatOptions\n} from './context/LokalContext';\n\n// Re-export types from lokal-core\nexport type { LocaleData } from 'lokal-core';\n","import { useState, useEffect, useCallback, useMemo } from 'react';\nimport type { LocaleData } from 'lokal-core';\nimport type { ExtendedTranslateFunction, StorageInterface } from '../context/LokalContext';\n\n// Re-implement the translation logic for standalone use\nfunction getNestedValue(obj: any, path: string): string {\n const keys = path.split('.');\n let value: any = obj;\n\n for (const k of keys) {\n if (value && typeof value === 'object' && k in value) {\n value = value[k];\n } else {\n return '';\n }\n }\n\n return typeof value === 'string' ? value : '';\n}\n\nfunction getPluralCategory(locale: string, count: number): string {\n const rules: Record<string, (n: number) => string> = {\n en: (n) => n === 1 ? 'one' : 'other',\n fr: (n) => n === 0 || n === 1 ? 'one' : 'many',\n es: (n) => n === 1 ? 'one' : 'many',\n de: (n) => n === 1 ? 'one' : 'other',\n };\n\n const rule = rules[locale] || rules['en'];\n return rule(count);\n}\n\n/**\n * Create a standalone translation function\n * Useful for non-React contexts or when you want to avoid hooks\n */\nexport function createTranslate(\n translations: LocaleData,\n locale: string = 'en'\n): ExtendedTranslateFunction {\n const translate = (key: string, params?: Record<string, string | number>): string => {\n const value = getNestedValue(translations, key);\n\n if (!value) return key;\n\n if (params) {\n return Object.entries(params).reduce(\n (str, [paramKey, paramValue]) =>\n str.replace(new RegExp(`{{${paramKey}}}`, 'g'), String(paramValue)),\n value\n );\n }\n\n return value;\n };\n\n const translatePlural = (key: string, params: any): string => {\n const { count, ...restParams } = params;\n const pluralCategory = getPluralCategory(locale, count);\n\n let value = getNestedValue(translations, `${key}_${pluralCategory}`);\n if (!value) value = getNestedValue(translations, key);\n\n if (!value) return key;\n\n const allParams = { count, ...restParams };\n return Object.entries(allParams).reduce(\n (str, [paramKey, paramValue]) =>\n str.replace(new RegExp(`{{${paramKey}}}`, 'g'), String(paramValue)),\n value\n );\n };\n\n const translateGender = (key: string, params: any): string => {\n const { gender, ...restParams } = params;\n\n let value = getNestedValue(translations, `${key}_${gender}`);\n if (!value) value = getNestedValue(translations, key);\n\n if (!value) return key;\n\n const allParams = { gender, ...restParams };\n return Object.entries(allParams).reduce(\n (str, [paramKey, paramValue]) =>\n str.replace(new RegExp(`{{${paramKey}}}`, 'g'), String(paramValue)),\n value\n );\n };\n\n const translateChoice = (key: string, params: { value: string | number }): string => {\n const { value } = params;\n\n let translation = getNestedValue(translations, `${key}_${value}`);\n if (!translation) translation = getNestedValue(translations, key);\n\n return translation || key;\n };\n\n const extendedFn = translate as ExtendedTranslateFunction;\n extendedFn.plural = translatePlural;\n extendedFn.gender = translateGender;\n extendedFn.choice = translateChoice;\n\n return extendedFn;\n}\n\n/**\n * Hook to create a standalone translate function from context\n * This is useful when you want to pass translation function to non-React code\n */\nexport function useStandaloneTranslate(): ExtendedTranslateFunction {\n const { t, translations, locale } = require('../context/LokalContext').useLokal();\n\n return useMemo(() => createTranslate(translations, locale), [translations, locale]);\n}\n\nexport default createTranslate;\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,SAAgB,eAAe,YAAY,UAAU,WAAW,mBAA8B;AAwbtF;AAjUR,SAAS,kBAAkB,QAAgB,OAA+B;AAEtE,QAAM,QAAuD;AAAA,IACzD,IAAI,CAAC,MAAM,MAAM,IAAI,QAAQ;AAAA,IAC7B,IAAI,CAAC,MAAM,MAAM,KAAK,MAAM,IAAI,QAAQ;AAAA,IACxC,IAAI,CAAC,MAAM,MAAM,IAAI,QAAQ;AAAA,IAC7B,IAAI,CAAC,MAAM,MAAM,IAAI,QAAQ;AAAA,IAC7B,IAAI,CAAC,MAAM,MAAM,IAAI,QAAQ;AAAA,IAC7B,IAAI,CAAC,MAAM;AACP,YAAM,QAAQ,IAAI;AAClB,YAAM,SAAS,IAAI;AACnB,UAAI,MAAM,EAAG,QAAO;AACpB,UAAI,SAAS,KAAK,SAAS,KAAK,EAAE,UAAU,MAAM,UAAU,IAAK,QAAO;AACxE,UAAI,UAAU,KAAK,SAAS,KAAK,SAAS,MAAM,SAAS,GAAI,QAAO;AACpE,aAAO;AAAA,IACX;AAAA,IACA,IAAI,CAAC,MAAM;AACP,UAAI,MAAM,EAAG,QAAO;AACpB,UAAI,MAAM,EAAG,QAAO;AACpB,UAAI,MAAM,EAAG,QAAO;AACpB,YAAM,SAAS,IAAI;AACnB,UAAI,UAAU,KAAK,UAAU,GAAI,QAAO;AACxC,UAAI,UAAU,MAAM,UAAU,GAAI,QAAO;AACzC,aAAO;AAAA,IACX;AAAA,EACJ;AAEA,QAAM,OAAO,MAAM,MAAM,KAAK,MAAM,IAAI;AACxC,SAAO,KAAK,KAAK;AACrB;AAKA,SAAS,eAAe,KAAU,MAAsB;AACpD,QAAM,OAAO,KAAK,MAAM,GAAG;AAC3B,MAAI,QAAa;AAEjB,aAAW,KAAK,MAAM;AAClB,QAAI,SAAS,OAAO,UAAU,YAAY,KAAK,OAAO;AAClD,cAAQ,MAAM,CAAC;AAAA,IACnB,OAAO;AACH,aAAO;AAAA,IACX;AAAA,EACJ;AAEA,SAAO,OAAO,UAAU,WAAW,QAAQ;AAC/C;AA+CO,SAAS,cAAc;AAAA,EAC1B;AAAA,EACA,QAAQ,gBAAgB;AAAA,EACxB,UAAU,CAAC,IAAI;AAAA,EACf,cAAc,sBAAsB,CAAC;AAAA,EACrC,UAAU;AAAA,EACV,YAAY;AAAA,EACZ,gBAAgB;AAAA,EAChB;AAAA,EACA,eAAe;AAAA,EACf,qBAAqB;AAAA,EACrB,iBAAiB;AACrB,GAAuB;AAEnB,QAAM,CAAC,QAAQ,cAAc,IAAI,SAAiB,oBAAoB,aAAa;AACnF,QAAM,CAAC,cAAc,eAAe,IAAI,SAAqB,0BAA0B,mBAAmB;AAC1G,QAAM,CAAC,WAAW,YAAY,IAAI,SAAkB,CAAC,CAAC,gBAAgB;AACtE,QAAM,CAAC,YAAY,aAAa,IAAI,SAAkB,CAAC,CAAC,gBAAgB;AAGxE,YAAU,MAAM;AACZ,QAAI,oBAAoB,CAAC,YAAY;AACjC,oBAAc,IAAI;AAClB,mBAAa,KAAK;AAAA,IACtB;AAAA,EACJ,GAAG,CAAC,kBAAkB,UAAU,CAAC;AAGjC,YAAU,MAAM;AACZ,UAAM,aAAa,YAAY;AAC3B,UAAI;AACA,cAAM,cAAc,MAAM,QAAQ,QAAQ,GAAG,SAAS,SAAS;AAC/D,YAAI,eAAe,QAAQ,SAAS,WAAW,GAAG;AAC9C,yBAAe,WAAW;AAAA,QAC9B,WAAW,CAAC,kBAAkB;AAE1B,cAAI,OAAO,cAAc,aAAa;AAClC,kBAAM,gBAAgB,UAAU,SAAS,MAAM,GAAG,EAAE,CAAC;AACrD,gBAAI,QAAQ,SAAS,aAAa,GAAG;AACjC,6BAAe,aAAa;AAAA,YAChC;AAAA,UACJ;AAAA,QACJ;AAAA,MACJ,SAAS,OAAO;AACZ,gBAAQ,KAAK,uCAAuC,KAAK;AACzD,YAAI,CAAC,kBAAkB;AACnB,yBAAe,cAAc;AAAA,QACjC;AAAA,MACJ,UAAE;AACE,qBAAa,KAAK;AAAA,MACtB;AAAA,IACJ;AAEA,eAAW;AAAA,EACf,GAAG,CAAC,SAAS,SAAS,WAAW,kBAAkB,cAAc,CAAC;AAGlE,YAAU,MAAM;AACZ,UAAM,mBAAmB,YAAY;AACjC,UAAI;AACA,cAAM,aAAa,MAAM,QAAQ,QAAQ,GAAG,SAAS,eAAe;AACpE,YAAI,YAAY;AACZ,gBAAM,SAA6B,KAAK,MAAM,UAAU;AACxD,cAAI,OAAO,MAAM,GAAG;AAChB,4BAAgB,OAAO,MAAM,CAAC;AAAA,UAClC;AAAA,QACJ;AAAA,MACJ,SAAS,OAAO;AACZ,gBAAQ,KAAK,6CAA6C,KAAK;AAAA,MACnE;AAAA,IACJ;AAEA,QAAI,CAAC,aAAa,CAAC,wBAAwB;AACvC,uBAAiB;AAAA,IACrB;AAAA,EACJ,GAAG,CAAC,QAAQ,SAAS,WAAW,WAAW,sBAAsB,CAAC;AAGlE,QAAM,YAAY,YAAY,CAAC,cAAsB;AACjD,QAAI,CAAC,QAAQ,SAAS,SAAS,GAAG;AAC9B,cAAQ,KAAK,UAAU,SAAS,0CAA0C;AAC1E;AAAA,IACJ;AAEA,mBAAe,SAAS;AACxB,YAAQ,QAAQ,GAAG,SAAS,WAAW,SAAS,EAAE,MAAM,QAAQ,IAAI;AAEpE,QAAI,gBAAgB;AAChB,qBAAe,SAAS;AAAA,IAC5B;AAAA,EACJ,GAAG,CAAC,SAAS,SAAS,WAAW,cAAc,CAAC;AAGhD,QAAM,YAAY,YAAY,CAAC,KAAa,WAAqD;AAC7F,UAAM,QAAQ,eAAe,cAAc,GAAG;AAE9C,QAAI,CAAC,OAAO;AAER,aAAO;AAAA,IACX;AAGA,QAAI,QAAQ;AACR,aAAO,OAAO,QAAQ,MAAM,EAAE;AAAA,QAC1B,CAAC,KAAK,CAAC,UAAU,UAAU,MAAM,IAAI,QAAQ,IAAI,OAAO,KAAK,QAAQ,MAAM,GAAG,GAAG,OAAO,UAAU,CAAC;AAAA,QACnG;AAAA,MACJ;AAAA,IACJ;AAEA,WAAO;AAAA,EACX,GAAG,CAAC,YAAY,CAAC;AAGjB,QAAM,kBAAkB,YAAY,CAAC,KAAa,WAAiC;AAC/E,UAAM,EAAE,OAAO,GAAG,WAAW,IAAI;AACjC,UAAM,iBAAiB,kBAAkB,QAAQ,KAAK;AAGtD,UAAM,YAAY,GAAG,GAAG,IAAI,cAAc;AAC1C,QAAI,QAAQ,eAAe,cAAc,SAAS;AAGlD,QAAI,CAAC,OAAO;AACR,cAAQ,eAAe,cAAc,GAAG;AAAA,IAC5C;AAEA,QAAI,CAAC,OAAO;AACR,aAAO;AAAA,IACX;AAGA,UAAM,YAAY,EAAE,OAAO,GAAG,WAAW;AACzC,WAAO,OAAO,QAAQ,SAAS,EAAE;AAAA,MAC7B,CAAC,KAAK,CAAC,UAAU,UAAU,MAAM,IAAI,QAAQ,IAAI,OAAO,KAAK,QAAQ,MAAM,GAAG,GAAG,OAAO,UAAU,CAAC;AAAA,MACnG;AAAA,IACJ;AAAA,EACJ,GAAG,CAAC,QAAQ,YAAY,CAAC;AAGzB,QAAM,kBAAkB,YAAY,CAAC,KAAa,WAAiC;AAC/E,UAAM,EAAE,QAAQ,GAAG,WAAW,IAAI;AAGlC,UAAM,YAAY,GAAG,GAAG,IAAI,MAAM;AAClC,QAAI,QAAQ,eAAe,cAAc,SAAS;AAGlD,QAAI,CAAC,OAAO;AACR,cAAQ,eAAe,cAAc,GAAG;AAAA,IAC5C;AAEA,QAAI,CAAC,OAAO;AACR,aAAO;AAAA,IACX;AAGA,UAAM,YAAY,EAAE,QAAQ,GAAG,WAAW;AAC1C,WAAO,OAAO,QAAQ,SAAS,EAAE;AAAA,MAC7B,CAAC,KAAK,CAAC,UAAU,UAAU,MAAM,IAAI,QAAQ,IAAI,OAAO,KAAK,QAAQ,MAAM,GAAG,GAAG,OAAO,UAAU,CAAC;AAAA,MACnG;AAAA,IACJ;AAAA,EACJ,GAAG,CAAC,YAAY,CAAC;AAGjB,QAAM,kBAAkB,YAAY,CAAC,KAAa,WAA+C;AAC7F,UAAM,EAAE,MAAM,IAAI;AAGlB,UAAM,YAAY,GAAG,GAAG,IAAI,KAAK;AACjC,QAAI,cAAc,eAAe,cAAc,SAAS;AAGxD,QAAI,CAAC,aAAa;AACd,oBAAc,eAAe,cAAc,GAAG;AAAA,IAClD;AAEA,QAAI,CAAC,aAAa;AACd,aAAO;AAAA,IACX;AAEA,WAAO;AAAA,EACX,GAAG,CAAC,YAAY,CAAC;AAGjB,QAAM,IAAI,YAAuC,OAAO;AAAA,IACpD;AAAA,IACA;AAAA,MACI,QAAQ;AAAA,MACR,QAAQ;AAAA,MACR,QAAQ;AAAA,IACZ;AAAA,EACJ,GAAG,CAAC,WAAW,iBAAiB,iBAAiB,eAAe,CAAC;AAGjE,QAAM,aAAa,YAAY,CAAC,MAAqB,YAAwC;AACzF,UAAM,UAAU,OAAO,SAAS,WAAW,IAAI,KAAK,IAAI,IAAI;AAE5D,QAAI;AACA,aAAO,IAAI,KAAK,eAAe,QAAQ,OAAqC,EAAE,OAAO,OAAO;AAAA,IAChG,SAAS,OAAO;AACZ,cAAQ,KAAK,2BAA2B,KAAK;AAC7C,aAAO,QAAQ,mBAAmB;AAAA,IACtC;AAAA,EACJ,GAAG,CAAC,MAAM,CAAC;AAGX,QAAM,eAAe,YAAY,CAAC,KAAa,YAA0C;AACrF,QAAI;AACA,aAAO,IAAI,KAAK,aAAa,QAAQ,OAAmC,EAAE,OAAO,GAAG;AAAA,IACxF,SAAS,OAAO;AACZ,cAAQ,KAAK,6BAA6B,KAAK;AAC/C,aAAO,IAAI,SAAS;AAAA,IACxB;AAAA,EACJ,GAAG,CAAC,MAAM,CAAC;AAEX,QAAM,eAAkC;AAAA,IACpC;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACJ;AAEA,SACI,oBAAC,aAAa,UAAb,EAAsB,OAAO,cACzB,UACL;AAER;AASO,SAAS,WAA8B;AAC1C,QAAM,UAAU,WAAW,YAAY;AAEvC,MAAI,CAAC,SAAS;AACV,UAAM,IAAI,MAAM,8CAA8C;AAAA,EAClE;AAEA,SAAO;AACX;AAKO,SAAS,eAA0C;AACtD,QAAM,EAAE,EAAE,IAAI,SAAS;AACvB,SAAO;AACX;AAKO,SAAS,YAAwF;AACpG,QAAM,EAAE,QAAQ,WAAW,QAAQ,IAAI,SAAS;AAChD,SAAO,EAAE,QAAQ,WAAW,QAAQ;AACxC;AAKO,SAAS,gBAAoK;AAChL,QAAM,EAAE,YAAY,aAAa,IAAI,SAAS;AAC9C,SAAO,EAAE,YAAY,aAAa;AACtC;AAKO,SAAS,eAAwB;AACpC,QAAM,EAAE,UAAU,IAAI,SAAS;AAC/B,SAAO;AACX;AAmBO,SAAS,EAAE;AAAA,EACd;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,IAAI,YAAY;AACpB,GAAoB;AAChB,QAAM,EAAE,EAAE,IAAI,SAAS;AAEvB,MAAI;AAEJ,MAAI,WAAW,QAAW;AACtB,qBAAiB,EAAE,OAAO,UAAU,EAAE,OAAO,QAAQ,GAAI,UAAU,CAAC,EAAG,CAAC;AAAA,EAC5E,WAAW,QAAQ;AACf,qBAAiB,EAAE,OAAO,UAAU,EAAE,QAAQ,GAAI,UAAU,CAAC,EAAG,CAAC;AAAA,EACrE,OAAO;AACH,qBAAiB,EAAE,UAAiB,MAAM;AAAA,EAC9C;AAEA,SACI,oBAAC,aAAU,WACN,0BACL;AAER;AASO,SAAS,oBAAoB,WAAmB;AACnD,QAAM,EAAE,GAAG,cAAc,UAAU,IAAI,SAAS;AAEhD,QAAM,YAAY,YAAY,CAAC,KAAa,WAAqD;AAC7F,UAAM,gBAAgB,GAAG,SAAS,IAAI,GAAG;AACzC,UAAM,QAAQ,eAAe,cAAc,aAAa;AAExD,QAAI,CAAC,OAAO;AACR,aAAO;AAAA,IACX;AAEA,QAAI,QAAQ;AACR,aAAO,OAAO,QAAQ,MAAM,EAAE;AAAA,QAC1B,CAAC,KAAK,CAAC,UAAU,UAAU,MACvB,IAAI,QAAQ,IAAI,OAAO,KAAK,QAAQ,MAAM,GAAG,GAAG,OAAO,UAAU,CAAC;AAAA,QACtE;AAAA,MACJ;AAAA,IACJ;AAEA,WAAO;AAAA,EACX,GAAG,CAAC,cAAc,SAAS,CAAC;AAE5B,SAAO,EAAE,GAAG,WAAW,UAAU;AACrC;AAUO,SAAS,cAAuB;AACnC,QAAM,CAAC,UAAU,WAAW,IAAI,SAAS,KAAK;AAE9C,YAAU,MAAM;AACZ,gBAAY,IAAI;AAAA,EACpB,GAAG,CAAC,CAAC;AAEL,SAAO;AACX;AAMO,SAAS,sBAA6E;AACzF,QAAM,EAAE,EAAE,IAAI,SAAS;AACvB,QAAM,aAAa,YAAY;AAG/B,QAAM,QAAQ,CAAC,KAAa,WAAqD;AAC7E,QAAI,CAAC,YAAY;AACb,aAAO;AAAA,IACX;AACA,WAAO,EAAE,KAAK,MAAM;AAAA,EACxB;AAEA,QAAM,SAAS,CAAC,KAAa,WAAiC;AAC1D,QAAI,CAAC,WAAY,QAAO;AACxB,WAAO,EAAE,OAAO,KAAK,MAAM;AAAA,EAC/B;AAEA,QAAM,SAAS,CAAC,KAAa,WAAiC;AAC1D,QAAI,CAAC,WAAY,QAAO;AACxB,WAAO,EAAE,OAAO,KAAK,MAAM;AAAA,EAC/B;AAEA,QAAM,SAAS,CAAC,KAAa,WAA+C;AACxE,QAAI,CAAC,WAAY,QAAO;AACxB,WAAO,EAAE,OAAO,KAAK,MAAM;AAAA,EAC/B;AAEA,SAAO,EAAE,GAAG,OAAoC,WAAW;AAC/D;AA7mBA,IA6FM,cAOA,gBA+gBC;AAnnBP;AAAA;AAAA;AA6FA,IAAM,eAAe,cAAwC,IAAI;AAOjE,IAAM,iBAAmC;AAAA,MACrC,SAAS,CAAC,QAAgB;AACtB,YAAI,OAAO,WAAW,YAAa,QAAO,QAAQ,QAAQ,IAAI;AAC9D,eAAO,QAAQ,QAAQ,aAAa,QAAQ,GAAG,CAAC;AAAA,MACpD;AAAA,MACA,SAAS,CAAC,KAAa,UAAkB;AACrC,YAAI,OAAO,WAAW,YAAa,QAAO,QAAQ,QAAQ;AAC1D,qBAAa,QAAQ,KAAK,KAAK;AAC/B,eAAO,QAAQ,QAAQ;AAAA,MAC3B;AAAA,IACJ;AAqgBA,IAAO,uBAAQ;AAAA;AAAA;;;AClnBf;;;ACDA,SAA2C,eAAe;AAK1D,SAASA,gBAAe,KAAU,MAAsB;AACpD,QAAM,OAAO,KAAK,MAAM,GAAG;AAC3B,MAAI,QAAa;AAEjB,aAAW,KAAK,MAAM;AAClB,QAAI,SAAS,OAAO,UAAU,YAAY,KAAK,OAAO;AAClD,cAAQ,MAAM,CAAC;AAAA,IACnB,OAAO;AACH,aAAO;AAAA,IACX;AAAA,EACJ;AAEA,SAAO,OAAO,UAAU,WAAW,QAAQ;AAC/C;AAEA,SAASC,mBAAkB,QAAgB,OAAuB;AAC9D,QAAM,QAA+C;AAAA,IACjD,IAAI,CAAC,MAAM,MAAM,IAAI,QAAQ;AAAA,IAC7B,IAAI,CAAC,MAAM,MAAM,KAAK,MAAM,IAAI,QAAQ;AAAA,IACxC,IAAI,CAAC,MAAM,MAAM,IAAI,QAAQ;AAAA,IAC7B,IAAI,CAAC,MAAM,MAAM,IAAI,QAAQ;AAAA,EACjC;AAEA,QAAM,OAAO,MAAM,MAAM,KAAK,MAAM,IAAI;AACxC,SAAO,KAAK,KAAK;AACrB;AAMO,SAAS,gBACZ,cACA,SAAiB,MACQ;AACzB,QAAM,YAAY,CAAC,KAAa,WAAqD;AACjF,UAAM,QAAQD,gBAAe,cAAc,GAAG;AAE9C,QAAI,CAAC,MAAO,QAAO;AAEnB,QAAI,QAAQ;AACR,aAAO,OAAO,QAAQ,MAAM,EAAE;AAAA,QAC1B,CAAC,KAAK,CAAC,UAAU,UAAU,MACvB,IAAI,QAAQ,IAAI,OAAO,KAAK,QAAQ,MAAM,GAAG,GAAG,OAAO,UAAU,CAAC;AAAA,QACtE;AAAA,MACJ;AAAA,IACJ;AAEA,WAAO;AAAA,EACX;AAEA,QAAM,kBAAkB,CAAC,KAAa,WAAwB;AAC1D,UAAM,EAAE,OAAO,GAAG,WAAW,IAAI;AACjC,UAAM,iBAAiBC,mBAAkB,QAAQ,KAAK;AAEtD,QAAI,QAAQD,gBAAe,cAAc,GAAG,GAAG,IAAI,cAAc,EAAE;AACnE,QAAI,CAAC,MAAO,SAAQA,gBAAe,cAAc,GAAG;AAEpD,QAAI,CAAC,MAAO,QAAO;AAEnB,UAAM,YAAY,EAAE,OAAO,GAAG,WAAW;AACzC,WAAO,OAAO,QAAQ,SAAS,EAAE;AAAA,MAC7B,CAAC,KAAK,CAAC,UAAU,UAAU,MACvB,IAAI,QAAQ,IAAI,OAAO,KAAK,QAAQ,MAAM,GAAG,GAAG,OAAO,UAAU,CAAC;AAAA,MACtE;AAAA,IACJ;AAAA,EACJ;AAEA,QAAM,kBAAkB,CAAC,KAAa,WAAwB;AAC1D,UAAM,EAAE,QAAQ,GAAG,WAAW,IAAI;AAElC,QAAI,QAAQA,gBAAe,cAAc,GAAG,GAAG,IAAI,MAAM,EAAE;AAC3D,QAAI,CAAC,MAAO,SAAQA,gBAAe,cAAc,GAAG;AAEpD,QAAI,CAAC,MAAO,QAAO;AAEnB,UAAM,YAAY,EAAE,QAAQ,GAAG,WAAW;AAC1C,WAAO,OAAO,QAAQ,SAAS,EAAE;AAAA,MAC7B,CAAC,KAAK,CAAC,UAAU,UAAU,MACvB,IAAI,QAAQ,IAAI,OAAO,KAAK,QAAQ,MAAM,GAAG,GAAG,OAAO,UAAU,CAAC;AAAA,MACtE;AAAA,IACJ;AAAA,EACJ;AAEA,QAAM,kBAAkB,CAAC,KAAa,WAA+C;AACjF,UAAM,EAAE,MAAM,IAAI;AAElB,QAAI,cAAcA,gBAAe,cAAc,GAAG,GAAG,IAAI,KAAK,EAAE;AAChE,QAAI,CAAC,YAAa,eAAcA,gBAAe,cAAc,GAAG;AAEhE,WAAO,eAAe;AAAA,EAC1B;AAEA,QAAM,aAAa;AACnB,aAAW,SAAS;AACpB,aAAW,SAAS;AACpB,aAAW,SAAS;AAEpB,SAAO;AACX;AAMO,SAAS,yBAAoD;AAChE,QAAM,EAAE,GAAG,cAAc,OAAO,IAAI,0DAAmC,SAAS;AAEhF,SAAO,QAAQ,MAAM,gBAAgB,cAAc,MAAM,GAAG,CAAC,cAAc,MAAM,CAAC;AACtF;","names":["getNestedValue","getPluralCategory"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "lokal-react",
|
|
3
|
-
"version": "1.3.
|
|
3
|
+
"version": "1.3.6",
|
|
4
4
|
"description": "React & React Native adapter for LOKAL - Hooks and Context Providers",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"module": "./dist/index.mjs",
|
|
@@ -43,4 +43,4 @@
|
|
|
43
43
|
"engines": {
|
|
44
44
|
"node": ">=18.0.0"
|
|
45
45
|
}
|
|
46
|
-
}
|
|
46
|
+
}
|