@smileid/web-components 11.0.3 → 11.2.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 (93) hide show
  1. package/README.md +61 -0
  2. package/dist/components/smart-camera-web/src/README.md +0 -1
  3. package/dist/esm/{DocumentCaptureScreens-C5BhNB-0.js → DocumentCaptureScreens-BbtA-WkX.js} +199 -193
  4. package/dist/esm/DocumentCaptureScreens-BbtA-WkX.js.map +1 -0
  5. package/dist/esm/{EndUserConsent-D4fd1ovG.js → EndUserConsent-HVufMamg.js} +65 -63
  6. package/dist/esm/EndUserConsent-HVufMamg.js.map +1 -0
  7. package/dist/esm/{Navigation-CTjK6tLU.js → Navigation-B-dqPkZj.js} +17 -9
  8. package/dist/esm/Navigation-B-dqPkZj.js.map +1 -0
  9. package/dist/esm/{SelfieCaptureScreens-KoQpCxtc.js → SelfieCaptureScreens-ChAMfKi3.js} +3274 -3329
  10. package/dist/esm/SelfieCaptureScreens-ChAMfKi3.js.map +1 -0
  11. package/dist/esm/{TotpConsent-CQU5jQi4.js → TotpConsent-XxR8TNxy.js} +13 -9
  12. package/dist/esm/TotpConsent-XxR8TNxy.js.map +1 -0
  13. package/dist/esm/combobox.js +20 -19
  14. package/dist/esm/combobox.js.map +1 -1
  15. package/dist/esm/document.js +1 -1
  16. package/dist/esm/end-user-consent.js +1 -1
  17. package/dist/esm/index-B_ozpejI.js +1360 -0
  18. package/dist/esm/index-B_ozpejI.js.map +1 -0
  19. package/dist/esm/localisation.js +21 -0
  20. package/dist/esm/localisation.js.map +1 -0
  21. package/dist/esm/main.js +34 -17
  22. package/dist/esm/main.js.map +1 -1
  23. package/dist/esm/navigation.js +1 -1
  24. package/dist/esm/{package-B-UwEdv7.js → package-u3FEJ3Fm.js} +25 -40
  25. package/dist/esm/package-u3FEJ3Fm.js.map +1 -0
  26. package/dist/esm/selfie.js +1 -1
  27. package/dist/esm/smart-camera-web.js +32 -23
  28. package/dist/esm/smart-camera-web.js.map +1 -1
  29. package/dist/esm/totp-consent.js +1 -1
  30. package/dist/package.json +1 -1
  31. package/dist/smart-camera-web.js +144 -160
  32. package/dist/smart-camera-web.js.map +1 -1
  33. package/dist/src/components/combobox/src/index.js +424 -1
  34. package/dist/src/components/document/src/index.js +1422 -1
  35. package/dist/src/components/end-user-consent/src/index.js +1573 -1
  36. package/dist/src/components/selfie/src/index.js +1220 -1
  37. package/dist/src/components/signature-pad/src/index.js +787 -1
  38. package/dist/src/components/smart-camera-web/src/SmartCameraWeb.js +2753 -1
  39. package/dist/src/components/totp-consent/src/index.js +1292 -1
  40. package/dist/types/combobox.d.ts +2 -2
  41. package/dist/types/document.d.ts +2 -2
  42. package/dist/types/end-user-consent.d.ts +2 -2
  43. package/dist/types/locale.d.ts +19 -0
  44. package/dist/types/localisation.d.ts +21 -0
  45. package/dist/types/main.d.ts +35 -26
  46. package/dist/types/navigation.d.ts +2 -2
  47. package/dist/types/selfie.d.ts +2 -2
  48. package/dist/types/signature-pad.d.ts +2 -2
  49. package/dist/types/smart-camera-web.d.ts +2 -2
  50. package/dist/types/totp-consent.d.ts +2 -2
  51. package/lib/components/camera-permission/CameraPermission.js +9 -4
  52. package/lib/components/combobox/src/Combobox.js +4 -2
  53. package/lib/components/document/src/DocumentCaptureScreens.js +4 -3
  54. package/lib/components/document/src/DocumentCaptureScreens.stories.js +37 -13
  55. package/lib/components/document/src/document-capture/DocumentCapture.js +23 -17
  56. package/lib/components/document/src/document-capture/DocumentCapture.stories.js +11 -2
  57. package/lib/components/document/src/document-capture-instructions/DocumentCaptureInstructions.js +19 -14
  58. package/lib/components/document/src/document-capture-instructions/DocumentCaptureInstructions.stories.js +14 -5
  59. package/lib/components/document/src/document-capture-review/DocumentCaptureReview.js +14 -10
  60. package/lib/components/document/src/document-capture-review/DocumentCaptureReview.stories.js +14 -5
  61. package/lib/components/end-user-consent/src/EndUserConsent.js +30 -29
  62. package/lib/components/end-user-consent/src/EndUserConsent.stories.js +12 -2
  63. package/lib/components/navigation/src/Navigation.js +15 -2
  64. package/lib/components/navigation/src/Navigation.stories.js +20 -4
  65. package/lib/components/selfie/src/SelfieCaptureScreens.js +12 -8
  66. package/lib/components/selfie/src/SelfieCaptureScreens.stories.js +16 -4
  67. package/lib/components/selfie/src/selfie-capture/SelfieCapture.js +25 -18
  68. package/lib/components/selfie/src/selfie-capture/SelfieCapture.stories.js +19 -7
  69. package/lib/components/selfie/src/selfie-capture-instructions/SelfieCaptureInstructions.js +19 -14
  70. package/lib/components/selfie/src/selfie-capture-instructions/SelfieCaptureInstructions.stories.js +14 -5
  71. package/lib/components/selfie/src/selfie-capture-review/SelfieCaptureReview.js +13 -8
  72. package/lib/components/selfie/src/selfie-capture-review/SelfieCaptureReview.stories.js +14 -5
  73. package/lib/components/selfie/src/selfie-capture-wrapper/SelfieCaptureWrapper.tsx +98 -47
  74. package/lib/components/selfie/src/smartselfie-capture/SmartSelfieCapture.tsx +2 -2
  75. package/lib/components/selfie/src/smartselfie-capture/components/CaptureControls.tsx +5 -2
  76. package/lib/components/selfie/src/smartselfie-capture/hooks/useCamera.ts +4 -4
  77. package/lib/components/selfie/src/smartselfie-capture/hooks/useFaceCapture.ts +6 -5
  78. package/lib/components/selfie/src/smartselfie-capture/utils/alertMessages.ts +11 -9
  79. package/lib/components/selfie/src/smartselfie-capture/utils/imageCapture.ts +3 -1
  80. package/lib/components/signature-pad/package.json +1 -1
  81. package/lib/components/smart-camera-web/src/SmartCameraWeb.js +9 -1
  82. package/lib/components/totp-consent/src/TotpConsent.js +8 -3
  83. package/lib/domain/camera/src/SmartCamera.js +7 -22
  84. package/lib/domain/constants/src/Constants.js +28 -0
  85. package/lib/domain/file-upload/src/SmartFileUpload.js +9 -10
  86. package/lib/domain/localisation/index.js +456 -0
  87. package/package.json +13 -7
  88. package/dist/esm/DocumentCaptureScreens-C5BhNB-0.js.map +0 -1
  89. package/dist/esm/EndUserConsent-D4fd1ovG.js.map +0 -1
  90. package/dist/esm/Navigation-CTjK6tLU.js.map +0 -1
  91. package/dist/esm/SelfieCaptureScreens-KoQpCxtc.js.map +0 -1
  92. package/dist/esm/TotpConsent-CQU5jQi4.js.map +0 -1
  93. package/dist/esm/package-B-UwEdv7.js.map +0 -1
@@ -0,0 +1,456 @@
1
+ /**
2
+ * Minimal runtime i18n module for SmileID web components.
3
+ * Provides simple locale registration, loading, and translation lookup.
4
+ */
5
+
6
+ import merge from 'lodash/merge';
7
+
8
+ // Bundle supported locales for offline/instant switching
9
+ import arLocale from '../../../locales/ar-EG.json';
10
+ import enLocale from '../../../locales/en-GB.json';
11
+ import frLocale from '../../../locales/fr-FR.json';
12
+
13
+ // Locale alias mapping for short codes
14
+ const LOCALE_ALIASES = {
15
+ ar: 'ar-EG',
16
+ en: 'en-GB',
17
+ fr: 'fr-FR',
18
+ };
19
+
20
+ /**
21
+ * Resolve locale alias to full locale code.
22
+ * @param {string} lang - Language code (e.g., 'en', 'ar', 'en-GB')
23
+ * @returns {string} Resolved locale code
24
+ */
25
+ function resolveLocale(lang) {
26
+ return LOCALE_ALIASES[lang] || lang;
27
+ }
28
+
29
+ const DEFAULT_LOCALE = 'en-GB';
30
+ const FETCH_TIMEOUT_MS = 5000;
31
+
32
+ let currentLocale = DEFAULT_LOCALE;
33
+ const locales = {
34
+ 'ar-EG': arLocale,
35
+ 'en-GB': enLocale,
36
+ 'fr-FR': frLocale,
37
+ };
38
+
39
+ /**
40
+ * Register a locale object (in-memory).
41
+ * @param {string} lang - Language code (e.g., 'en-GB', 'ar-EG')
42
+ * @param {object} data - Locale translation object
43
+ */
44
+ export function registerLocale(lang, data) {
45
+ locales[lang] = data;
46
+ }
47
+
48
+ /**
49
+ * Deep merge source object into target object.
50
+ * Recursively merges nested objects while preserving non-overridden values.
51
+ * Uses lodash merge under the hood but returns a new object (does not mutate inputs).
52
+ * @param {object} target - Base object to merge into
53
+ * @param {object} source - Object with values to merge/override
54
+ * @returns {object} New merged object (does not mutate inputs)
55
+ */
56
+ export function deepMerge(target, source) {
57
+ if (!source || typeof source !== 'object') {
58
+ return target;
59
+ }
60
+
61
+ if (!target || typeof target !== 'object') {
62
+ return source;
63
+ }
64
+
65
+ // Use lodash merge with empty object as first arg to avoid mutating target
66
+ return merge({}, target, source);
67
+ }
68
+
69
+ /**
70
+ * Required translation keys for a complete locale.
71
+ * These are the minimum keys needed for the SDK to function properly.
72
+ */
73
+ const REQUIRED_LOCALE_KEYS = [
74
+ 'direction',
75
+ 'common.back',
76
+ 'common.close',
77
+ 'common.continue',
78
+ 'common.cancel',
79
+ 'camera.permission.description',
80
+ 'camera.permission.requestButton',
81
+ 'camera.error.notAllowed',
82
+ 'selfie.instructions.title',
83
+ 'selfie.capture.button.takeSelfie',
84
+ 'selfie.review.title',
85
+ 'selfie.review.acceptButton',
86
+ 'selfie.review.retakeButton',
87
+ 'document.capture.captureButton',
88
+ 'document.review.acceptButton',
89
+ 'document.review.retakeButton',
90
+ ];
91
+
92
+ /**
93
+ * Fetch with timeout wrapper.
94
+ * @param {string} url - URL to fetch
95
+ * @param {number} timeout - Timeout in milliseconds
96
+ * @returns {Promise<Response>} Fetch response
97
+ */
98
+ async function fetchWithTimeout(url, timeout = FETCH_TIMEOUT_MS) {
99
+ const controller = new AbortController();
100
+ const timeoutId = setTimeout(() => controller.abort(), timeout);
101
+
102
+ try {
103
+ const response = await fetch(url, { signal: controller.signal });
104
+ return response;
105
+ } finally {
106
+ clearTimeout(timeoutId);
107
+ }
108
+ }
109
+
110
+ /**
111
+ * Register a locale by URL (fetch and cache).
112
+ * @param {string} lang - Language code
113
+ * @param {string} url - URL to locale JSON file
114
+ * @returns {Promise<object>} Loaded locale data
115
+ */
116
+ export async function registerLocaleUrl(lang, url) {
117
+ try {
118
+ const response = await fetchWithTimeout(url);
119
+ if (!response.ok) {
120
+ throw new Error(`Failed to load locale from ${url}: ${response.status}`);
121
+ }
122
+ const data = await response.json();
123
+ registerLocale(lang, data);
124
+ return data;
125
+ } catch (error) {
126
+ const errorMessage =
127
+ error.name === 'AbortError'
128
+ ? `Timeout loading locale '${lang}' from ${url}`
129
+ : `Error loading locale '${lang}' from ${url}: ${error.message}`;
130
+ console.error(errorMessage);
131
+
132
+ // Fallback to default locale if available
133
+ if (lang !== DEFAULT_LOCALE && locales[DEFAULT_LOCALE]) {
134
+ console.warn(`Falling back to default locale '${DEFAULT_LOCALE}'`);
135
+ return locales[DEFAULT_LOCALE];
136
+ }
137
+ throw error;
138
+ }
139
+ }
140
+
141
+ /**
142
+ * Load a locale (supports both inline registration and URL fetch).
143
+ * @param {string} lang - Language code
144
+ * @param {string} [url] - Optional URL to fetch locale from
145
+ * @returns {Promise<object>} Loaded locale data
146
+ */
147
+ export async function loadLocale(lang, url) {
148
+ const resolvedLang = resolveLocale(lang);
149
+
150
+ // Return cached locale if available
151
+ if (locales[resolvedLang]) {
152
+ return locales[resolvedLang];
153
+ }
154
+
155
+ // Fetch from URL if provided
156
+ if (url) {
157
+ return registerLocaleUrl(lang, url);
158
+ }
159
+
160
+ // No URL provided and locale not cached - fallback to default
161
+ console.warn(
162
+ `Locale '${lang}' not found and no URL provided, using default '${DEFAULT_LOCALE}'`,
163
+ );
164
+ return locales[DEFAULT_LOCALE] || {};
165
+ }
166
+
167
+ /**
168
+ * Helper to get nested value from object using dot notation.
169
+ * @param {object} obj - Object to traverse
170
+ * @param {string} key - Dot-separated key path
171
+ * @returns {string|undefined} Value at path or undefined
172
+ */
173
+ function getNestedValue(obj, key) {
174
+ if (!obj) return undefined;
175
+
176
+ const value = key.split('.').reduce((acc, k) => {
177
+ if (acc && typeof acc === 'object' && k in acc) {
178
+ return acc[k];
179
+ }
180
+ return undefined;
181
+ }, obj);
182
+
183
+ return typeof value === 'string' ? value : undefined;
184
+ }
185
+
186
+ /**
187
+ * Validate that a locale has all required translation keys.
188
+ * @param {object} locale - Locale data to validate
189
+ * @returns {{ missingKeys: string[], valid: boolean }} Validation result
190
+ */
191
+ export function validateLocale(locale) {
192
+ if (!locale || typeof locale !== 'object') {
193
+ return { missingKeys: REQUIRED_LOCALE_KEYS, valid: false };
194
+ }
195
+
196
+ const missingKeys = REQUIRED_LOCALE_KEYS.filter((key) => {
197
+ if (key === 'direction') {
198
+ return !locale.direction;
199
+ }
200
+ return !getNestedValue(locale, key);
201
+ });
202
+
203
+ return {
204
+ missingKeys,
205
+ valid: missingKeys.length === 0,
206
+ };
207
+ }
208
+
209
+ /**
210
+ * Get translation for a key.
211
+ * Supports nested keys with dot notation (e.g., 'camera.permission.description').
212
+ * Fallback chain: current locale → default locale (English) → raw key.
213
+ * @param {string} key - Translation key
214
+ * @returns {string} Translated string or fallback
215
+ */
216
+ export function t(key) {
217
+ // Try current locale first
218
+ const resolvedLocale = resolveLocale(currentLocale);
219
+ const currentLocaleData = locales[resolvedLocale];
220
+ const value = getNestedValue(currentLocaleData, key);
221
+ if (value) {
222
+ return value;
223
+ }
224
+
225
+ // Fallback to default locale if different from current
226
+ const resolvedDefault = resolveLocale(DEFAULT_LOCALE);
227
+ if (resolvedLocale !== resolvedDefault) {
228
+ const defaultValue = getNestedValue(locales[resolvedDefault], key);
229
+ if (defaultValue) {
230
+ return defaultValue;
231
+ }
232
+ }
233
+
234
+ // Final fallback: return the key itself
235
+ console.warn(`Translation key '${key}' not found in any locale`);
236
+ return key;
237
+ }
238
+
239
+ /**
240
+ * Alias for t() function.
241
+ * @see t
242
+ */
243
+ export const translate = t;
244
+
245
+ /**
246
+ * HTML entity map for escaping special characters.
247
+ */
248
+ const HTML_ENTITIES = {
249
+ '"': '&quot;',
250
+ '&': '&amp;',
251
+ "'": '&#39;',
252
+ '<': '&lt;',
253
+ '>': '&gt;',
254
+ };
255
+
256
+ /**
257
+ * Escape HTML special characters to prevent XSS.
258
+ * @param {string} str - String to escape
259
+ * @returns {string} Escaped string
260
+ */
261
+ export function escapeHtml(str) {
262
+ return str.replace(/[&<>"']/g, (char) => HTML_ENTITIES[char]);
263
+ }
264
+
265
+ /**
266
+ * Get translation with HTML interpolation for styled placeholders.
267
+ * Placeholders in format {{key}} will be replaced with provided values.
268
+ * Values can be plain strings or objects with {value, className} for styled spans.
269
+ * @param {string} key - Translation key
270
+ * @param {Object} params - Interpolation parameters
271
+ * @returns {string} Translated string with interpolations
272
+ * @example
273
+ * // Plain interpolation
274
+ * tHtml('greeting', { name: 'John' }) // "Hello, John"
275
+ *
276
+ * // Styled interpolation
277
+ * tHtml('consent.accessRequest', {
278
+ * partnerName: { value: 'Acme', className: 'theme' }
279
+ * }) // "<span class="theme">Acme</span> wants to access..."
280
+ */
281
+ export function tHtml(key, params = {}) {
282
+ let text = t(key);
283
+
284
+ Object.keys(params).forEach((paramKey) => {
285
+ const paramValue = params[paramKey];
286
+ const placeholder = `{{${paramKey}}}`;
287
+
288
+ if (paramValue && typeof paramValue === 'object' && 'value' in paramValue) {
289
+ // Styled interpolation: { value: 'text', className: 'theme' }
290
+ const escapedValue = escapeHtml(String(paramValue.value || ''));
291
+ const className = escapeHtml(String(paramValue.className || ''));
292
+ text = text
293
+ .split(placeholder)
294
+ .join(
295
+ className
296
+ ? `<span class="${className}">${escapedValue}</span>`
297
+ : escapedValue,
298
+ );
299
+ } else {
300
+ // Plain text interpolation
301
+ text = text.split(placeholder).join(escapeHtml(String(paramValue)));
302
+ }
303
+ });
304
+
305
+ return text;
306
+ }
307
+
308
+ /**
309
+ * Alias for tHtml() function.
310
+ * @see tHtml
311
+ */
312
+ export const translateHtml = tHtml;
313
+
314
+ /**
315
+ * Set the current locale.
316
+ * If the locale is not registered, it will attempt to load it from the provided URL.
317
+ * Applies RTL direction to document element if direction is specified in locale.
318
+ * @param {string} lang - Language code
319
+ * @param {Object} [options] - Configuration options
320
+ * @param {string} [options.url] - URL to fetch locale from if not registered
321
+ * @param {Object} [options.translation] - Complete locale data object (legacy)
322
+ * @param {Object} [options.locales] - Locale data keyed by language code (new API)
323
+ * @param {boolean} [options.validate] - Whether to validate locale completeness
324
+ * @returns {Promise<boolean>} Whether locale was successfully set
325
+ */
326
+ export async function setCurrentLocale(
327
+ lang,
328
+ { url, translation, locales: customLocales, validate = false } = {},
329
+ ) {
330
+ currentLocale = resolveLocale(lang);
331
+ // Step 1: Process custom locales (new API - keyed by language code)
332
+ if (customLocales && typeof customLocales === 'object') {
333
+ Object.entries(customLocales).forEach(([localeKey, localeData]) => {
334
+ if (!localeData || typeof localeData !== 'object') {
335
+ return;
336
+ }
337
+
338
+ const resolvedKey = resolveLocale(localeKey);
339
+
340
+ if (locales[resolvedKey]) {
341
+ // Deep merge into existing bundled locale
342
+ locales[resolvedKey] = deepMerge(locales[resolvedKey], localeData);
343
+ } else {
344
+ // Register as new locale
345
+ registerLocale(resolvedKey, localeData);
346
+
347
+ // Add alias if short code provided
348
+ if (localeKey !== resolvedKey) {
349
+ LOCALE_ALIASES[localeKey] = resolvedKey;
350
+ }
351
+ }
352
+ });
353
+ }
354
+
355
+ // Step 2: Handle legacy translation option (for backward compatibility)
356
+ if (!locales[currentLocale]) {
357
+ if (translation) {
358
+ registerLocale(currentLocale, translation);
359
+ } else if (url) {
360
+ try {
361
+ await loadLocale(currentLocale, url);
362
+ } catch (error) {
363
+ console.error(
364
+ `Failed to load locale '${lang}', keeping current locale '${currentLocale}'`,
365
+ );
366
+ return false;
367
+ }
368
+ } else {
369
+ console.warn(`Locale '${lang}' not registered and no URL provided`);
370
+ return false;
371
+ }
372
+ }
373
+
374
+ // Step 3: Validate locale completeness if requested
375
+ if (validate && locales[currentLocale]) {
376
+ const validation = validateLocale(locales[currentLocale]);
377
+ if (!validation.valid) {
378
+ console.warn(
379
+ `Locale '${lang}' is missing required keys:`,
380
+ validation.missingKeys,
381
+ );
382
+ }
383
+ }
384
+
385
+ // Step 4: Apply RTL/LTR direction if specified in locale data
386
+ const locale = locales[currentLocale];
387
+ if (locale && locale.direction && document?.documentElement) {
388
+ document.documentElement.dir = locale.direction;
389
+ }
390
+
391
+ return true;
392
+ }
393
+
394
+ /**
395
+ * Get the current locale.
396
+ * @returns {string} Current language code
397
+ */
398
+ export function getCurrentLocale() {
399
+ return currentLocale;
400
+ }
401
+
402
+ /**
403
+ * Get the default locale code.
404
+ * @returns {string} Default language code
405
+ */
406
+ export function getDefaultLocale() {
407
+ return DEFAULT_LOCALE;
408
+ }
409
+
410
+ /**
411
+ * Check if a locale is registered.
412
+ * @param {string} lang - Language code
413
+ * @returns {boolean} Whether locale is registered
414
+ */
415
+ export function hasLocale(lang) {
416
+ return lang in locales;
417
+ }
418
+
419
+ /**
420
+ * Set document direction based on locale direction property.
421
+ * @param {string} lang - Language code
422
+ */
423
+ export function setDocumentDir(lang) {
424
+ const locale = locales[lang];
425
+ if (locale && locale.direction) {
426
+ document.documentElement.dir = locale.direction;
427
+ }
428
+ }
429
+
430
+ /**
431
+ * Get the text direction for the current locale.
432
+ * @returns {string} Direction ('ltr' or 'rtl'), defaults to 'ltr'
433
+ */
434
+ export function getDirection() {
435
+ const locale = locales[currentLocale];
436
+ return locale?.direction || 'ltr';
437
+ }
438
+
439
+ export default {
440
+ deepMerge,
441
+ escapeHtml,
442
+ getCurrentLocale,
443
+ getDefaultLocale,
444
+ getDirection,
445
+ hasLocale,
446
+ loadLocale,
447
+ registerLocale,
448
+ registerLocaleUrl,
449
+ setCurrentLocale,
450
+ setDocumentDir,
451
+ t,
452
+ tHtml,
453
+ translate,
454
+ translateHtml,
455
+ validateLocale,
456
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@smileid/web-components",
3
- "version": "11.0.3",
3
+ "version": "11.2.0",
4
4
  "main": "dist/esm/main.js",
5
5
  "module": "dist/esm/main.js",
6
6
  "types": "dist/types/main.d.ts",
@@ -40,6 +40,10 @@
40
40
  "./smart-camera-web": {
41
41
  "types": "./dist/types/smart-camera-web.d.ts",
42
42
  "import": "./dist/esm/smart-camera-web.js"
43
+ },
44
+ "./localisation": {
45
+ "types": "./dist/types/localisation.d.ts",
46
+ "import": "./dist/esm/localisation.js"
43
47
  }
44
48
  },
45
49
  "files": [
@@ -75,8 +79,8 @@
75
79
  "@mediapipe/tasks-vision": "^0.10.22-rc.20250304",
76
80
  "@preact/signals": "^2.1.1",
77
81
  "@tabler/icons-preact": "^3.34.0",
78
- "lodash": "^4.17.21",
79
- "preact": "^10.26.9",
82
+ "lodash": "^4.17.23",
83
+ "preact": "^10.27.3",
80
84
  "preact-custom-element": "^4.3.0",
81
85
  "preact-router": "^4.1.2",
82
86
  "signature_pad": "^5.0.2",
@@ -87,25 +91,27 @@
87
91
  "@types/lodash": "^4.17.20",
88
92
  "@types/node": "^20.11.24",
89
93
  "@types/preact-custom-element": "^4.0.4",
90
- "@typescript-eslint/eslint-plugin": "^7.18.0",
91
- "@typescript-eslint/parser": "^7.18.0",
94
+ "@typescript-eslint/eslint-plugin": "^8.49.0",
95
+ "@typescript-eslint/parser": "^8.49.0",
92
96
  "cross-env": "^7.0.3",
93
97
  "cypress": "^13.15.0",
94
98
  "eslint": "^8.57.0",
95
99
  "eslint-config-airbnb-base": "^15.0.0",
96
- "eslint-config-airbnb-typescript": "^18.0.0",
97
100
  "eslint-config-prettier": "^9.1.0",
98
101
  "eslint-import-resolver-typescript": "^3.6.1",
99
102
  "eslint-plugin-cypress": "^3.3.0",
100
103
  "eslint-plugin-import": "^2.29.1",
101
104
  "eslint-plugin-jest": "^28.8.3",
102
105
  "eslint-plugin-prettier": "^5.2.1",
103
- "glob": "^10.3.10",
106
+ "glob": "^10.5.0",
104
107
  "prettier": "^3.6.2",
105
108
  "rollup-plugin-visualizer": "^6.0.3",
106
109
  "typescript": "^5.8.3",
107
110
  "vite": "^7.2.2",
108
111
  "vite-plugin-dts": "^4.5.4",
109
112
  "vite-plugin-tsconfig-paths": "^1.4.1"
113
+ },
114
+ "optionalDependencies": {
115
+ "@rollup/rollup-linux-x64-gnu": "^4.53.5"
110
116
  }
111
117
  }