@sanctum-key/react-native-sdk 1.0.13 → 1.0.14

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.
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sanctum-key/react-native-sdk",
3
- "version": "1.0.13",
3
+ "version": "1.0.14",
4
4
  "description": "Sanctum Key React Native SDK",
5
5
  "main": "build/src/index.js",
6
6
  "types": "build/src/index.d.ts",
@@ -1 +1 @@
1
- {"version":3,"file":"IDCardCapture.d.ts","sourceRoot":"","sources":["../../../../src/components/KYCElements/IDCardCapture.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAuC,MAAM,OAAO,CAAC;AAI5D,OAAO,EAAE,iBAAiB,EAAoI,MAAM,uBAAuB,CAAC;AAc5L,UAAU,cAAc;IAAG,GAAG,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,YAAY,CAAC,EAAE,MAAM,CAAC;CAAE;AAC3F,UAAU,kBAAkB;IAAG,SAAS,EAAE,iBAAiB,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;IAAC,aAAa,EAAE,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,cAAc,GAAG,MAAM,CAAC,KAAK,IAAI,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAAC,WAAW,CAAC,EAAE,MAAM,CAAC;CAAE;AAExO,eAAO,MAAM,aAAa,EAAE,KAAK,CAAC,EAAE,CAAC,kBAAkB,CA+atD,CAAC"}
1
+ {"version":3,"file":"IDCardCapture.d.ts","sourceRoot":"","sources":["../../../../src/components/KYCElements/IDCardCapture.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAuC,MAAM,OAAO,CAAC;AAI5D,OAAO,EAAE,iBAAiB,EAAoI,MAAM,uBAAuB,CAAC;AAc5L,UAAU,cAAc;IAAG,GAAG,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,YAAY,CAAC,EAAE,MAAM,CAAC;CAAE;AAC3F,UAAU,kBAAkB;IAAG,SAAS,EAAE,iBAAiB,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;IAAC,aAAa,EAAE,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,cAAc,GAAG,MAAM,CAAC,KAAK,IAAI,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAAC,WAAW,CAAC,EAAE,MAAM,CAAC;CAAE;AAExO,eAAO,MAAM,aAAa,EAAE,KAAK,CAAC,EAAE,CAAC,kBAAkB,CAudtD,CAAC"}
@@ -1,5 +1,5 @@
1
1
  import React, { useEffect, useMemo, useState } from 'react';
2
- import { View, Text, StyleSheet, Image, ScrollView, Platform, ActivityIndicator, TouchableOpacity } from 'react-native'; // 🚨 Added TouchableOpacity
2
+ import { View, Text, StyleSheet, Image, ScrollView, Platform, ActivityIndicator, TouchableOpacity } from 'react-native';
3
3
  import { showAlert } from '../../utils/platformAlert';
4
4
  import { EnhancedCameraView } from '../EnhancedCameraView';
5
5
  import { GovernmentDocumentTypeShorted, GovernmentDocumentTypeBackend } from '../../types/KYC.types';
@@ -23,8 +23,10 @@ export const IDCardCapture = ({ component, value = {}, onValueChange, error, lan
23
23
  const [silentCaptureResult, setSilentCaptureResult] = useState({ success: false, isAnalyzing: false });
24
24
  const [isProcessingCapture, setIsProcessingCapture] = useState(false);
25
25
  const [processingImagePath, setProcessingImagePath] = useState(null);
26
- // 🚨 ADDED: Key to force camera re-mount
27
26
  const [cameraKey, setCameraKey] = useState(0);
27
+ const [isRebootingCamera, setIsRebootingCamera] = useState(false);
28
+ // Web specific state
29
+ const [cameraType, setCameraType] = useState('back');
28
30
  const documentTypeMapping = { 'nationalId': 'national_id', 'passport': 'passport', 'driversLicense': 'drivers_licence', 'residencePermit': 'permanent_residence', 'healthInsuranceCard': 'health_insurance_card', };
29
31
  const { actions, state, env } = useTemplateKYCFlowContext();
30
32
  const getLocalizedText = (text) => {
@@ -44,7 +46,6 @@ export const IDCardCapture = ({ component, value = {}, onValueChange, error, lan
44
46
  return { type: mappedType, region: countrySelectionData.region || 'root' };
45
47
  }, [countrySelectionData, documentTypeMapping]);
46
48
  const countryData = useMemo(() => countrySelectionData, [countrySelectionData]);
47
- const [isRebootingCamera, setIsRebootingCamera] = useState(false);
48
49
  const refreshCamera = () => {
49
50
  setIsRebootingCamera(true);
50
51
  setTimeout(() => {
@@ -52,6 +53,10 @@ export const IDCardCapture = ({ component, value = {}, onValueChange, error, lan
52
53
  setIsRebootingCamera(false);
53
54
  }, 500);
54
55
  };
56
+ const toggleCameraLens = () => {
57
+ setCameraType(prev => prev === 'back' ? 'front' : 'back');
58
+ refreshCamera();
59
+ };
55
60
  useEffect(() => {
56
61
  if (value && Object.keys(value).length > 0) {
57
62
  if (JSON.stringify(value) !== JSON.stringify(capturedImages)) {
@@ -69,15 +74,17 @@ export const IDCardCapture = ({ component, value = {}, onValueChange, error, lan
69
74
  const cameraConfig = useMemo(() => {
70
75
  const instructions = selectedDocumentType ? (locale === 'en' ? getDocumentTypeInfo(selectedDocumentType.type).instructions.en : getDocumentTypeInfo(selectedDocumentType.type).instructions.fr) : getLocalizedText(component.instructions);
71
76
  return {
72
- cameraType: 'back', flashMode: 'auto',
77
+ cameraType: Platform.OS === 'web' ? cameraType : 'back', // Keep strictly 'back' on mobile
78
+ flashMode: 'auto',
73
79
  overlay: { guideText: instructions, bbox: { xMin: 15, yMin: 20, xMax: 85, yMax: 70, borderColor: '#2DBD60', borderWidth: 3, cornerRadius: 8 } }
74
80
  };
75
- }, [selectedDocumentType, locale, component.instructions]);
81
+ }, [selectedDocumentType, locale, component.instructions, cameraType]);
76
82
  const retakePicture = (sideToRetake) => {
77
83
  setIsProcessingCapture(false);
78
84
  setProcessingImagePath(null);
79
85
  setSilentCaptureResult({ path: '', success: false, isAnalyzing: false, error: '', templatePath: '', mrz: '', bbox: undefined });
80
86
  setShowCamera(true);
87
+ refreshCamera();
81
88
  actions.showCustomStepper(false);
82
89
  setCapturedImages((prev) => { const newState = { ...prev }; delete newState[sideToRetake]; return newState; });
83
90
  if (value) {
@@ -177,7 +184,9 @@ export const IDCardCapture = ({ component, value = {}, onValueChange, error, lan
177
184
  }, 600);
178
185
  }
179
186
  catch (e) {
180
- showAlert('Error', e?.message || 'Impossible de capturer la photo');
187
+ console.error("Backend Error:", e);
188
+ const friendlyError = state.currentLanguage === 'en' ? 'Unable to process document. Please try again.' : 'Impossible de traiter le document. Veuillez réessayer.';
189
+ showAlert('Error', friendlyError);
181
190
  setSilentCaptureResult(prev => ({ ...prev, isAnalyzing: false, success: false }));
182
191
  setIsProcessingCapture(false);
183
192
  setProcessingImagePath(null);
@@ -239,8 +248,11 @@ export const IDCardCapture = ({ component, value = {}, onValueChange, error, lan
239
248
  await autoCapture(result.path, verifiedResult);
240
249
  }
241
250
  catch (error) {
251
+ console.error("Backend Error:", error);
242
252
  const isCardNotFullyInFrame = error?.message === 'CARD_NOT_FULLY_IN_FRAME' || error?.message?.includes('entirement');
243
- const errorMessage = isCardNotFullyInFrame ? t('kyc.idCardCapture.cardNotFullyInFrame') : (error?.message || 'Erreur de détection');
253
+ const errorMessage = isCardNotFullyInFrame
254
+ ? t('kyc.idCardCapture.cardNotFullyInFrame')
255
+ : (t('errors.genericVerificationFailed') || 'Verification failed. Please ensure the document is clear and try again.');
244
256
  setSilentCaptureResult(prev => ({ ...prev, isAnalyzing: false, success: false, error: errorMessage }));
245
257
  }
246
258
  }
@@ -268,29 +280,35 @@ export const IDCardCapture = ({ component, value = {}, onValueChange, error, lan
268
280
  const isBusy = isProcessingCapture;
269
281
  if (isRebootingCamera) {
270
282
  return (<View style={[styles.root, { justifyContent: 'center', alignItems: 'center', backgroundColor: '#000' }]}>
271
- <ActivityIndicator size="large" color="#2DBD60"/>
272
- <Text style={{ color: 'white', marginTop: 20, fontSize: 16 }}>Initializing Camera...</Text>
273
- </View>);
283
+ <ActivityIndicator size="large" color="#2DBD60"/>
284
+ <Text style={{ color: 'white', marginTop: 20, fontSize: 16 }}>Initializing Camera...</Text>
285
+ </View>);
274
286
  }
275
287
  return (<View style={styles.root}>
276
- <View style={[styles.cameraWrapper, { flex: 1, minHeight: 400 }]}>
277
-
278
- <View style={styles.headerContainer}>
279
- <Text style={styles.headerTitle}>
280
- {selectedDocumentType ? (locale === 'en' ? getDocumentTypeInfo(selectedDocumentType.type).name.en : getDocumentTypeInfo(selectedDocumentType.type).name.fr) : ''}
281
- </Text>
282
- <View style={styles.stepBadge}>
283
- <Text style={styles.stepText}>
284
- {t('kyc.idCardCapture.captureTitle', { side: currentSide === 'front' ? locale === 'en' ? 'Front' : 'Recto' : locale === 'en' ? 'Back' : 'Verso' })}
288
+ <View style={[styles.cameraWrapper, { flex: 1 }]}>
289
+
290
+ <View style={styles.headerContainer}>
291
+ <Text style={styles.headerTitle}>
292
+ {selectedDocumentType ? (locale === 'en' ? getDocumentTypeInfo(selectedDocumentType.type).name.en : getDocumentTypeInfo(selectedDocumentType.type).name.fr) : ''}
285
293
  </Text>
294
+ <View style={styles.stepBadge}>
295
+ <Text style={styles.stepText}>
296
+ {t('kyc.idCardCapture.captureTitle', { side: currentSide === 'front' ? locale === 'en' ? 'Front' : 'Recto' : locale === 'en' ? 'Back' : 'Verso' })}
297
+ </Text>
298
+ </View>
286
299
  </View>
287
- </View>
288
-
289
- <View style={[styles.cameraFeedContainer, { flex: 1, backgroundColor: '#000' }]}>
290
300
 
291
- <EnhancedCameraView key={`${currentSide}-${cameraKey}`} showCamera={true} isProcessing={isBusy} cameraType={cameraConfig.cameraType} style={styles.absoluteFillObject} onError={handleError} onSilentCapture={handleSilentCapture} silentCaptureResult={silentCaptureResult} overlayComponent={<>
292
- {/* We ONLY put the ID frame here, because if the camera fails, we don't care if the frame fails too */}
293
- <IdCardOverlay xMin={cameraConfig.overlay.bbox.xMin} yMin={cameraConfig.overlay.bbox.yMin} xMax={cameraConfig.overlay.bbox.xMax} yMax={cameraConfig.overlay.bbox.yMax} instructions={cameraConfig.overlay.guideText} cornerOpacity={cameraConfig.overlay.bbox.cornerRadius || 0} isSuccess={silentCaptureResult.success} language={state.currentLanguage} stepperProps={{
301
+ <View style={[styles.cameraFeedContainer, { flex: 1, backgroundColor: '#000' }]}>
302
+
303
+ {/* WEB ONLY: Flip Camera Top Button */}
304
+ {Platform.OS === 'web' && (<View style={styles.webTopControls}>
305
+ <TouchableOpacity style={styles.webFlipButton} onPress={toggleCameraLens}>
306
+ <Text style={styles.webFlipText}>🔄 Flip Lens</Text>
307
+ </TouchableOpacity>
308
+ </View>)}
309
+
310
+ <EnhancedCameraView key={`${currentSide}-${cameraKey}`} showCamera={true} isProcessing={isBusy} cameraType={cameraConfig.cameraType} style={StyleSheet.absoluteFillObject} onError={handleError} onSilentCapture={handleSilentCapture} silentCaptureResult={silentCaptureResult} overlayComponent={<>
311
+ <IdCardOverlay xMin={cameraConfig.overlay.bbox.xMin} yMin={cameraConfig.overlay.bbox.yMin} xMax={cameraConfig.overlay.bbox.xMax} yMax={cameraConfig.overlay.bbox.yMax} instructions={cameraConfig.overlay.guideText} cornerOpacity={cameraConfig.overlay.bbox.cornerRadius || 0} isSuccess={silentCaptureResult.success} language={state.currentLanguage} stepperProps={{
294
312
  back: () => {
295
313
  if (currentSide === 'back') {
296
314
  setCurrentSide('front');
@@ -312,47 +330,59 @@ export const IDCardCapture = ({ component, value = {}, onValueChange, error, lan
312
330
  selectedDocumentType: selectedDocumentType ? (locale === 'en' ? getDocumentTypeInfo(selectedDocumentType.type).name.en : getDocumentTypeInfo(selectedDocumentType.type).name.fr) : '',
313
331
  step: state.currentComponentIndex + 1, totalSteps: state.template.components.length, side: currentSide,
314
332
  }}/>
315
- </>}/>
333
+ </>}/>
316
334
 
335
+ {!isBusy && silentCaptureResult.isAnalyzing && (<View style={styles.topAnalyzingPillContainer}>
336
+ <View style={styles.topAnalyzingPill}>
337
+ <ActivityIndicator size="small" color="white"/>
338
+ <Text style={styles.analyzingPillText}>
339
+ {state.currentLanguage === 'en' ? 'Scanning...' : 'Analyse...'}
340
+ </Text>
341
+ </View>
342
+ </View>)}
317
343
 
318
- {!isBusy && silentCaptureResult.isAnalyzing && (<View style={styles.topAnalyzingPillContainer}>
319
- <View style={styles.topAnalyzingPill}>
320
- <ActivityIndicator size="small" color="white"/>
321
- <Text style={styles.analyzingPillText}>
322
- {state.currentLanguage === 'en' ? 'Scanning...' : 'Analyse...'}
323
- </Text>
324
- </View>
325
- </View>)}
326
-
327
- {isBusy && (<View style={[StyleSheet.absoluteFillObject, { zIndex: 9999 }]}>
328
- {processingImagePath && (<Image source={{ uri: processingImagePath.startsWith('file://') ? processingImagePath : `file://${processingImagePath}` }} style={StyleSheet.absoluteFillObject} resizeMode="cover"/>)}
329
- <View style={styles.processingOverlay}>
330
- <ActivityIndicator size="large" color="#2DBD60"/>
331
- <Text style={styles.processingText}>
332
- {state.currentLanguage === 'en' ? 'Perfect!\nProcessing Document...' : 'Parfait!\nTraitement du document...'}
333
- </Text>
334
- </View>
335
- </View>)}
344
+ {isBusy && (<View style={[StyleSheet.absoluteFillObject, { zIndex: 9999 }]}>
345
+ {processingImagePath && (<Image source={{ uri: processingImagePath.startsWith('file://') ? processingImagePath : `file://${processingImagePath}` }} style={StyleSheet.absoluteFillObject} resizeMode="cover"/>)}
346
+ <View style={styles.processingOverlay}>
347
+ <ActivityIndicator size="large" color="#2DBD60"/>
348
+ <Text style={styles.processingText}>
349
+ {state.currentLanguage === 'en' ? 'Perfect!\nProcessing Document...' : 'Parfait!\nTraitement du document...'}
350
+ </Text>
351
+ </View>
352
+ </View>)}
336
353
 
337
- {!isBusy && (<View style={styles.escapeHatchContainer}>
338
- {/* Refresh Button */}
339
- <TouchableOpacity style={styles.fallbackRefreshButton} onPress={refreshCamera}>
340
- <Text style={styles.fallbackRefreshText}>↻ Refresh Camera</Text>
341
- </TouchableOpacity>
354
+ {/* 🚨 THE ESCAPE HATCH: Branching UI for Web vs Mobile */}
355
+ {!isBusy && Platform.OS === 'web' ? (<View style={styles.webBottomControlBar}>
356
+ {silentCaptureResult.error ? (<View style={styles.floatingErrorBanner}>
357
+ <Text style={styles.floatingErrorText}>⚠️ {silentCaptureResult.error}</Text>
358
+ </View>) : <View style={{ height: 10 }}/>}
342
359
 
343
- <TouchableOpacity style={[styles.fallbackRefreshButton, { marginTop: 15, backgroundColor: 'rgba(220, 38, 38, 0.8)', borderColor: '#DC2626' }]} onPress={() => setShowCamera(false)}>
344
- <Text style={styles.fallbackRefreshText}>Cancel / Go Back</Text>
345
- </TouchableOpacity>
346
- </View>)}
360
+ <View style={styles.webActionButtonsRow}>
361
+ <TouchableOpacity style={styles.webSecondaryButton} onPress={() => setShowCamera(false)}>
362
+ <Text style={styles.webSecondaryButtonText}>Cancel</Text>
363
+ </TouchableOpacity>
364
+ <TouchableOpacity style={styles.webPrimaryButton} onPress={refreshCamera}>
365
+ <Text style={styles.webPrimaryButtonText}>↻ Refresh Camera</Text>
366
+ </TouchableOpacity>
367
+ </View>
368
+ </View>) : !isBusy ? (<View style={styles.escapeHatchContainer}>
369
+ <TouchableOpacity style={styles.fallbackRefreshButton} onPress={refreshCamera}>
370
+ <Text style={styles.fallbackRefreshText}>↻ Refresh Camera</Text>
371
+ </TouchableOpacity>
372
+ <TouchableOpacity style={[styles.fallbackRefreshButton, { marginTop: 15, backgroundColor: 'rgba(220, 38, 38, 0.8)', borderColor: '#DC2626' }]} onPress={() => setShowCamera(false)}>
373
+ <Text style={styles.fallbackRefreshText}>Cancel / Go Back</Text>
374
+ </TouchableOpacity>
375
+ </View>) : null}
347
376
 
348
- {silentCaptureResult.error && !isBusy ? (<View style={[styles.floatingErrorBanner, { zIndex: 10000 }]}>
349
- <Text style={styles.floatingErrorText}>⚠️ {silentCaptureResult.error}</Text>
350
- </View>) : null}
377
+ {silentCaptureResult.error && !isBusy && Platform.OS !== 'web' ? (<View style={[styles.floatingErrorBanner, { zIndex: 10000 }]}>
378
+ <Text style={styles.floatingErrorText}>⚠️ {silentCaptureResult.error}</Text>
379
+ </View>) : null}
351
380
 
381
+ </View>
352
382
  </View>
353
- </View>
354
- </View>);
383
+ </View>);
355
384
  }
385
+ // --- PREVIEW RENDER ---
356
386
  return (<View style={styles.root}>
357
387
  <View style={styles.previewContainer}>
358
388
  <ScrollView style={styles.previewItemContainer} showsVerticalScrollIndicator={false}>
@@ -363,16 +393,20 @@ export const IDCardCapture = ({ component, value = {}, onValueChange, error, lan
363
393
  <Text style={{ fontSize: 14, color: '#666', textAlign: 'center', marginBottom: 16, lineHeight: 22 }}>
364
394
  {getLocalizedText(component.instructions)}
365
395
  </Text>
396
+
366
397
  <View style={{ alignItems: 'center', justifyContent: 'center', flexDirection: "column", gap: 16 }}>
367
398
  {silentCaptureResult?.error === 'TOO_FAR_AWAY' && (<View style={styles.warningBanner}>
368
399
  <Text style={styles.warningText}>
369
400
  {state.currentLanguage === "en" ? "Move the document closer to the camera and place it on a flat surface." : "Veuillez rapprocher le document de la caméra et le poser à plat."}
370
401
  </Text>
371
402
  </View>)}
403
+
404
+ {/* 🚨 PREVIEW CONTAINER WITH PLATFORM OVERRIDES */}
372
405
  <View style={styles.imagePreviewWrapper}>
373
406
  {capturedImages[currentSide]?.dir ? (<Image source={{ uri: capturedImages[currentSide].dir }} style={styles.previewImage}/>) : silentCaptureResult.path ? (<Image source={{ uri: silentCaptureResult.path }} style={styles.previewImage}/>) : null}
374
407
  </View>
375
- {!capturedImages[currentSide]?.dir && (<Button title={state.currentLanguage === "en" ? "Start Scanning" : "Commencer la numérisation"} onPress={() => { setShowCamera(true); actions.showCustomStepper(false); }} variant="primary" size="large" fullWidth/>)}
408
+
409
+ {!capturedImages[currentSide]?.dir && (<Button title={state.currentLanguage === "en" ? "Start Scanning" : "Commencer la numérisation"} onPress={() => { setShowCamera(true); refreshCamera(); actions.showCustomStepper(false); }} variant="primary" size="large" fullWidth/>)}
376
410
  {capturedImages[currentSide]?.dir && (<>
377
411
  <Button title={t('kyc.idCardCapture.retakeButton')} onPress={() => retakePicture(currentSide)} variant="outline" size="medium" fullWidth/>
378
412
  <Button title={t('common.next')} onPress={() => {
@@ -385,6 +419,7 @@ export const IDCardCapture = ({ component, value = {}, onValueChange, error, lan
385
419
  }
386
420
  else {
387
421
  setShowCamera(true);
422
+ refreshCamera();
388
423
  setCurrentSide('back');
389
424
  setSilentCaptureResult({ success: false, isAnalyzing: false, path: '', error: '', templatePath: undefined });
390
425
  setIsProcessingCapture(false);
@@ -401,38 +436,63 @@ export const IDCardCapture = ({ component, value = {}, onValueChange, error, lan
401
436
  const styles = StyleSheet.create({
402
437
  root: {
403
438
  flex: 1, width: '100%', backgroundColor: 'transparent', alignSelf: 'center',
404
- ...(Platform.OS === 'web' ? { minHeight: '85vh', justifyContent: 'center', alignItems: 'center', backdropFilter: 'blur(8px)' } : {})
439
+ ...Platform.select({
440
+ web: { minHeight: '85vh', justifyContent: 'center', alignItems: 'center', backdropFilter: 'blur(8px)' },
441
+ })
405
442
  },
406
443
  cameraWrapper: {
407
- width: '100%', backgroundColor: '#FFFFFF', overflow: 'hidden',
408
- ...(Platform.OS === 'web' ? { maxWidth: 500, height: 700, maxHeight: '90vh', borderRadius: 24, shadowColor: '#000', shadowOffset: { width: 0, height: 20 }, shadowOpacity: 0.25, shadowRadius: 35, elevation: 24, } : { flex: 1, })
444
+ width: '100%', backgroundColor: '#000000', overflow: 'hidden',
445
+ ...Platform.select({
446
+ web: { maxWidth: 550, height: '80vh', minHeight: 600, borderRadius: 24, shadowColor: '#000', shadowOffset: { width: 0, height: 20 }, shadowOpacity: 0.25, shadowRadius: 35, elevation: 24 },
447
+ default: { flex: 1 }
448
+ })
409
449
  },
410
450
  headerContainer: {
411
451
  flexDirection: 'row', alignItems: 'center', justifyContent: 'space-between', paddingHorizontal: 24, paddingVertical: 18, backgroundColor: '#FFFFFF', borderBottomWidth: 1, borderBottomColor: '#F1F5F9', zIndex: 10,
412
- ...(Platform.OS !== 'web' ? { display: 'none' } : {})
452
+ ...Platform.select({ web: { display: 'flex' }, default: { display: 'none' } })
413
453
  },
414
454
  headerTitle: { fontSize: 18, fontWeight: '700', color: '#0F172A', },
415
455
  stepBadge: { backgroundColor: '#F1F5F9', paddingHorizontal: 12, paddingVertical: 6, borderRadius: 20, },
416
456
  stepText: { fontSize: 13, fontWeight: '600', color: '#64748B', },
417
457
  cameraFeedContainer: { flex: 1, position: 'relative', backgroundColor: '#000', },
418
458
  camera: { flex: 1, },
419
- refreshButton: {
420
- position: 'absolute', bottom: 100, alignSelf: 'center', backgroundColor: 'rgba(0,0,0,0.6)', paddingVertical: 12, paddingHorizontal: 24, borderRadius: 24, zIndex: 500
421
- },
422
- refreshButtonText: { color: 'white', fontWeight: 'bold', fontSize: 16 },
459
+ // MOBILE: Escape Hatch layout
460
+ escapeHatchContainer: { position: 'absolute', bottom: 40, left: 0, right: 0, alignItems: 'center', justifyContent: 'center', zIndex: 99999 },
461
+ fallbackRefreshButton: { backgroundColor: 'rgba(0, 0, 0, 0.8)', borderWidth: 1, borderColor: 'rgba(255, 255, 255, 0.5)', paddingVertical: 12, paddingHorizontal: 24, borderRadius: 24, shadowColor: '#000', shadowOffset: { width: 0, height: 4 }, shadowOpacity: 0.3, shadowRadius: 5, elevation: 8 },
462
+ fallbackRefreshText: { color: '#FFFFFF', fontWeight: 'bold', fontSize: 16 },
463
+ // WEB: Control Bar layout
464
+ webBottomControlBar: { position: 'absolute', bottom: 0, left: 0, right: 0, paddingHorizontal: 20, paddingBottom: 20, paddingTop: 20, backgroundColor: 'rgba(0,0,0,0.6)', zIndex: 99999 },
465
+ webActionButtonsRow: { flexDirection: 'row', justifyContent: 'space-between', gap: 12, marginTop: 12 },
466
+ webPrimaryButton: { flex: 1, backgroundColor: '#2DBD60', paddingVertical: 14, borderRadius: 12, alignItems: 'center' },
467
+ webPrimaryButtonText: { color: 'white', fontWeight: 'bold', fontSize: 16 },
468
+ webSecondaryButton: { flex: 1, backgroundColor: 'rgba(255,255,255,0.2)', borderWidth: 1, borderColor: 'rgba(255,255,255,0.4)', paddingVertical: 14, borderRadius: 12, alignItems: 'center' },
469
+ webSecondaryButtonText: { color: 'white', fontWeight: 'bold', fontSize: 16 },
470
+ // WEB: Flip Controls
471
+ webTopControls: { position: 'absolute', top: 20, right: 20, zIndex: 9999 },
472
+ webFlipButton: { backgroundColor: 'rgba(0,0,0,0.5)', paddingHorizontal: 16, paddingVertical: 10, borderRadius: 20, borderWidth: 1, borderColor: 'rgba(255,255,255,0.3)' },
473
+ webFlipText: { color: 'white', fontWeight: 'bold', fontSize: 14 },
423
474
  previewContainer: {
424
475
  width: '100%', backgroundColor: 'white', borderRadius: 12, paddingVertical: 24, paddingHorizontal: 20, shadowColor: '#000', shadowOffset: { width: 0, height: 4 }, shadowOpacity: 0.1, shadowRadius: 12, elevation: 8,
425
- ...(Platform.OS === 'web' ? { alignSelf: 'center', maxWidth: 600 } : { margin: 10, width: '95%' })
476
+ ...Platform.select({ web: { alignSelf: 'center', maxWidth: 600 }, default: { margin: 10, width: '95%' } })
426
477
  },
427
478
  previewItemContainer: { flexGrow: 1, },
428
479
  title: { fontSize: 24, fontWeight: 'bold', color: '#333', marginBottom: 8, textAlign: 'center' },
429
480
  description: { fontSize: 16, color: '#666', textAlign: 'center', marginBottom: 24, lineHeight: 22 },
430
481
  sideContainer: { marginBottom: 24 },
431
482
  sideTitle: { fontSize: 25, fontWeight: 'bold', color: '#000', marginBottom: 12, textAlign: 'center' },
432
- imagePreviewWrapper: { width: '100%', height: 220, borderRadius: 12, padding: 1, overflow: 'hidden', shadowColor: '#000', shadowOffset: { width: 0, height: 4 }, shadowOpacity: 0.18, shadowRadius: 8, elevation: 8, backgroundColor: '#f0f0f0' },
483
+ imagePreviewWrapper: {
484
+ width: '100%', borderRadius: 12, padding: 1, overflow: 'hidden', shadowColor: '#000', shadowOffset: { width: 0, height: 4 }, shadowOpacity: 0.18, shadowRadius: 8, elevation: 8, backgroundColor: '#f0f0f0',
485
+ ...Platform.select({
486
+ web: { aspectRatio: 1.59, height: 'auto' }, // 🚨 Perfect ID ratio on web
487
+ default: { height: 220 } // 🚨 Strict original height on mobile
488
+ })
489
+ },
433
490
  previewImage: { width: '100%', height: '100%', borderRadius: 12, resizeMode: 'cover' },
434
491
  floatingErrorBanner: {
435
- position: 'absolute', bottom: 30, left: 24, right: 24, backgroundColor: '#FEF2F2', borderWidth: 1, borderColor: '#FCA5A5', paddingVertical: 12, paddingHorizontal: 16, borderRadius: 12, alignItems: 'center', justifyContent: 'center', shadowColor: '#DC2626', shadowOffset: { width: 0, height: 4 }, shadowOpacity: 0.1, shadowRadius: 8, elevation: 8, zIndex: 100
492
+ backgroundColor: '#FEF2F2', borderWidth: 1, borderColor: '#FCA5A5', paddingVertical: 12, paddingHorizontal: 16, borderRadius: 12, alignItems: 'center', justifyContent: 'center', width: '100%',
493
+ ...Platform.select({
494
+ default: { position: 'absolute', top: Platform.OS === 'ios' ? 90 : 70, left: 24, right: 24, zIndex: 10000 }
495
+ })
436
496
  },
437
497
  floatingErrorText: { color: '#991B1B', fontSize: 14, fontWeight: '700', textAlign: 'center' },
438
498
  processingOverlay: { flex: 1, backgroundColor: 'rgba(0, 0, 0, 0.6)', justifyContent: 'center', alignItems: 'center', zIndex: 9999 },
@@ -442,40 +502,6 @@ const styles = StyleSheet.create({
442
502
  errorText: { color: '#dc2626', fontSize: 14, marginTop: 8, textAlign: 'center' },
443
503
  topAnalyzingPillContainer: { position: 'absolute', top: Platform.OS === 'android' ? 60 : 50, left: 0, right: 0, alignItems: 'center', zIndex: 100 },
444
504
  topAnalyzingPill: { flexDirection: 'row', alignItems: 'center', backgroundColor: 'rgba(0,0,0,0.6)', paddingVertical: 8, paddingHorizontal: 16, borderRadius: 20, gap: 8 },
445
- analyzingPillText: { color: 'white', fontSize: 14, fontWeight: 'bold' },
446
- escapeHatchContainer: {
447
- position: 'absolute',
448
- bottom: 40,
449
- left: 0,
450
- right: 0,
451
- alignItems: 'center',
452
- justifyContent: 'center',
453
- zIndex: 99999, // Guarantees it is the top-most element
454
- },
455
- fallbackRefreshButton: {
456
- backgroundColor: 'rgba(0, 0, 0, 0.8)', // Darker so it's visible on white or black
457
- borderWidth: 1,
458
- borderColor: 'rgba(255, 255, 255, 0.5)',
459
- paddingVertical: 12,
460
- paddingHorizontal: 24,
461
- borderRadius: 24,
462
- shadowColor: '#000',
463
- shadowOffset: { width: 0, height: 4 },
464
- shadowOpacity: 0.3,
465
- shadowRadius: 5,
466
- elevation: 8,
467
- },
468
- fallbackRefreshText: {
469
- color: '#FFFFFF',
470
- fontWeight: 'bold',
471
- fontSize: 16,
472
- },
473
- absoluteFillObject: {
474
- position: 'absolute',
475
- top: 0,
476
- left: 0,
477
- right: 0,
478
- bottom: 0,
479
- },
505
+ analyzingPillText: { color: 'white', fontSize: 14, fontWeight: 'bold' }
480
506
  });
481
507
  //# sourceMappingURL=IDCardCapture.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"IDCardCapture.js","sourceRoot":"","sources":["../../../../src/components/KYCElements/IDCardCapture.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,SAAS,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAC5D,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,UAAU,EAAE,KAAK,EAAE,UAAU,EAAE,QAAQ,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC,CAAC,4BAA4B;AACrJ,OAAO,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AACtD,OAAO,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAC3D,OAAO,EAAyF,6BAA6B,EAAE,6BAA6B,EAAE,MAAM,uBAAuB,CAAC;AAC5L,OAAO,aAAa,MAAM,mBAAmB,CAAC;AAC9C,OAAO,EAAE,yBAAyB,EAAE,MAAM,gCAAgC,CAAC;AAC3E,OAAO,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;AAC9C,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AACtC,OAAO,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAC;AAChE,OAAO,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,wCAAwC,CAAC;AAChH,OAAO,EAAE,mBAAmB,EAAE,MAAM,oCAAoC,CAAC;AACzE,OAAO,YAAY,MAAM,0BAA0B,CAAC;AACpD,OAAO,EAAE,SAAS,EAAE,8BAA8B,EAAE,gBAAgB,EAAE,wBAAwB,EAAE,MAAM,uBAAuB,CAAC;AAC9H,OAAO,cAAc,MAAM,kCAAkC,CAAC;AAE9D,MAAM,mBAAmB,GAA2B,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,cAAc,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,aAAa,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;AAKjQ,MAAM,CAAC,MAAM,aAAa,GAAiC,CAAC,EAAE,SAAS,EAAE,KAAK,GAAG,EAAE,EAAE,aAAa,EAAE,KAAK,EAAE,QAAQ,GAAG,IAAI,EAAE,EAAE,EAAE;IAC9H,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,GAAG,OAAO,EAAE,CAAC;IAChC,MAAM,CAAC,UAAU,EAAE,aAAa,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;IACpD,MAAM,CAAC,cAAc,EAAE,iBAAiB,CAAC,GAAG,QAAQ,CAAiC,KAAK,IAAI,EAAE,CAAC,CAAC;IAClG,MAAM,CAAC,WAAW,EAAE,cAAc,CAAC,GAAG,QAAQ,CAAmB,OAAO,CAAC,CAAC;IAC1E,MAAM,CAAC,UAAU,EAAE,aAAa,CAAC,GAAG,QAAQ,CAAwB,EAAE,CAAC,CAAC;IACxE,MAAM,CAAC,mBAAmB,EAAE,sBAAsB,CAAC,GAAG,QAAQ,CAAuB,EAAE,OAAO,EAAE,KAAK,EAAE,WAAW,EAAE,KAAK,EAAE,CAAC,CAAC;IAC7H,MAAM,CAAC,mBAAmB,EAAE,sBAAsB,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;IACtE,MAAM,CAAC,mBAAmB,EAAE,sBAAsB,CAAC,GAAG,QAAQ,CAAgB,IAAI,CAAC,CAAC;IAEpF,yCAAyC;IACzC,MAAM,CAAC,SAAS,EAAE,YAAY,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC;IAE9C,MAAM,mBAAmB,GAA2C,EAAE,YAAY,EAAE,aAAa,EAAE,UAAU,EAAE,UAAU,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,qBAAqB,EAAE,qBAAqB,EAAE,uBAAuB,GAAG,CAAC;IAC5P,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,GAAG,EAAE,GAAG,yBAAyB,EAAE,CAAC;IAE5D,MAAM,gBAAgB,GAAG,CAAC,IAAmD,EAAU,EAAE;QACvF,IAAI,IAAI,IAAI,OAAO,IAAI,CAAC,WAAW,CAAC,KAAK,QAAQ,IAAI,IAAI,CAAC,WAAW,CAAC,CAAC,MAAM,CAAC;YAAE,OAAO,IAAI,CAAC,WAAW,CAAC,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC;QACvH,OAAO,EAAE,CAAC;IACZ,CAAC,CAAC;IAEF,MAAM,oBAAoB,GAAG,OAAO,CAAC,GAAG,EAAE;QACxC,MAAM,yBAAyB,GAAG,KAAK,CAAC,QAAQ,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,mBAAmB,CAAC,CAAC;QACtG,OAAO,yBAAyB,CAAC,CAAC,CAAC,KAAK,CAAC,aAAa,CAAC,yBAAyB,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IAC9F,CAAC,EAAE,CAAC,KAAK,CAAC,QAAQ,CAAC,UAAU,EAAE,KAAK,CAAC,aAAa,CAAC,CAAC,CAAC;IAErD,MAAM,oBAAoB,GAAG,OAAO,CAA0D,GAAG,EAAE;QACjG,IAAI,CAAC,oBAAoB,EAAE,YAAY;YAAE,OAAO,IAAI,CAAC;QACrD,MAAM,cAAc,GAAG,oBAAoB,CAAC,YAAY,CAAC;QACzD,MAAM,UAAU,GAAG,mBAAmB,CAAC,cAAc,CAAC,IAAI,cAAwC,CAAC;QACnG,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,MAAM,EAAE,oBAAoB,CAAC,MAAM,IAAI,MAAM,EAAE,CAAC;IAC7E,CAAC,EAAE,CAAC,oBAAoB,EAAE,mBAAmB,CAAC,CAAC,CAAC;IAEhD,MAAM,WAAW,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC,oBAAoB,EAAE,CAAC,oBAAoB,CAAC,CAAC,CAAC;IAEhF,MAAM,CAAC,iBAAiB,EAAE,oBAAoB,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;IAElE,MAAM,aAAa,GAAG,GAAG,EAAE;QACzB,oBAAoB,CAAC,IAAI,CAAC,CAAC;QAE3B,UAAU,CAAC,GAAG,EAAE;YACd,YAAY,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC;YAC/B,oBAAoB,CAAC,KAAK,CAAC,CAAC;QAC9B,CAAC,EAAE,GAAG,CAAC,CAAC;IACV,CAAC,CAAC;IAIF,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,KAAK,IAAI,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC3C,IAAI,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,KAAK,IAAI,CAAC,SAAS,CAAC,cAAc,CAAC,EAAE,CAAC;gBAC7D,MAAM,aAAa,GAAG,KAAuC,CAAC;gBAC9D,iBAAiB,CAAC,aAAa,CAAC,CAAC;gBACjC,MAAM,gBAAgB,GAAG,aAAa,CAAC,WAAW,CAAC,CAAC;gBACpD,IAAI,gBAAgB,EAAE,GAAG,EAAE,CAAC;oBAC1B,sBAAsB,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;wBAC9B,GAAG,IAAI,EAAE,IAAI,EAAE,gBAAgB,CAAC,GAAG,EAAE,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,KAAK,EAAE,GAAG,EAAE,gBAAgB,CAAC,GAAG,IAAI,EAAE,EAAE,YAAY,EAAE,gBAAgB,CAAC,YAAY,IAAI,EAAE;qBAC3J,CAAC,CAAC,CAAC;gBACN,CAAC;YACH,CAAC;QACH,CAAC;IACH,CAAC,EAAE,CAAC,KAAK,EAAE,WAAW,CAAC,CAAC,CAAC;IAEzB,MAAM,YAAY,GAAG,OAAO,CAAC,GAAG,EAAE;QAChC,MAAM,YAAY,GAAG,oBAAoB,CAAC,CAAC,CAAC,CAAC,MAAM,KAAK,IAAI,CAAC,CAAC,CAAC,mBAAmB,CAAC,oBAAoB,CAAC,IAAI,CAAC,CAAC,YAAY,CAAC,EAAE,CAAC,CAAC,CAAC,mBAAmB,CAAC,oBAAoB,CAAC,IAAI,CAAC,CAAC,YAAY,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,gBAAgB,CAAC,SAAS,CAAC,YAA6C,CAAC,CAAC;QAC5Q,OAAO;YACL,UAAU,EAAE,MAAe,EAAE,SAAS,EAAE,MAAe;YACvD,OAAO,EAAE,EAAE,SAAS,EAAE,YAAY,EAAE,IAAI,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE,WAAW,EAAE,SAAS,EAAE,WAAW,EAAE,CAAC,EAAE,YAAY,EAAE,CAAC,EAAE,EAAE;SAChJ,CAAC;IACJ,CAAC,EAAE,CAAC,oBAAoB,EAAE,MAAM,EAAE,SAAS,CAAC,YAAY,CAAC,CAAC,CAAC;IAE3D,MAAM,aAAa,GAAG,CAAC,YAA8B,EAAE,EAAE;QACvD,sBAAsB,CAAC,KAAK,CAAC,CAAC;QAC9B,sBAAsB,CAAC,IAAI,CAAC,CAAC;QAC7B,sBAAsB,CAAC,EAAE,IAAI,EAAE,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,WAAW,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE,EAAE,YAAY,EAAE,EAAE,EAAE,GAAG,EAAE,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC,CAAC;QAChI,aAAa,CAAC,IAAI,CAAC,CAAC;QACpB,OAAO,CAAC,iBAAiB,CAAC,KAAK,CAAC,CAAC;QACjC,iBAAiB,CAAC,CAAC,IAAI,EAAE,EAAE,GAAG,MAAM,QAAQ,GAAG,EAAE,GAAG,IAAI,EAAE,CAAC,CAAC,OAAO,QAAQ,CAAC,YAAY,CAAC,CAAC,CAAC,OAAO,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC;QAC/G,IAAI,KAAK,EAAE,CAAC;YAAC,MAAM,QAAQ,GAAG,EAAE,GAAG,KAAK,EAAE,CAAC;YAAC,OAAO,QAAQ,CAAC,YAAY,CAAC,CAAC;YAAC,aAAa,CAAC,QAAQ,CAAC,CAAC;QAAC,CAAC;IACvG,CAAC,CAAC;IAEF,MAAM,0BAA0B,GAAG,CAAC,WAAmB,EAAE,UAAkB,EAAE,EAAE;QAC7E,MAAM,UAAU,GAAG,oBAAoB,EAAE,YAAY,CAAC;QACtD,IAAI,CAAC,UAAU,IAAI,CAAC,UAAU,EAAE,CAAC;YAAC,OAAO,EAAE,UAAU,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,GAAG,EAAE,MAAM,EAAE,CAAC;QAAC,CAAC;QAC9G,MAAM,cAAc,GAAG,mBAAmB,CAAC,WAAW,EAAE,IAAI,IAAI,EAAE,CAAC,IAAI,WAAW,EAAE,IAAI,IAAI,UAAU,CAAC;QACvG,MAAM,WAAW,GAAI,cAAsB,CAAC,aAAa,IAAI,cAAc,CAAC;QAC5E,IAAI,cAAc,GAAG,WAAW,CAAC,cAAc,CAAC,CAAC;QACjD,IAAI,CAAC,cAAc,EAAE,CAAC;YACpB,MAAM,QAAQ,GAAG,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,WAAW,EAAE,KAAK,cAAc,CAAC,WAAW,EAAE,IAAI,CAAC,CAAC,WAAW,EAAE,KAAK,UAAU,CAAC,WAAW,EAAE,CAAC,CAAC;YACtJ,IAAI,QAAQ;gBAAE,cAAc,GAAG,WAAW,CAAC,QAAQ,CAAC,CAAC;QACvD,CAAC;QACD,IAAI,CAAC,cAAc,EAAE,CAAC;YAAC,OAAO,EAAE,UAAU,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,GAAG,EAAE,MAAM,EAAE,CAAC;QAAC,CAAC;QACnG,MAAM,aAAa,GAAG,cAAc,CAAC,UAAU,CAAC,CAAC;QACjD,IAAI,CAAC,aAAa,EAAE,CAAC;YAAC,OAAO,EAAE,UAAU,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,GAAG,EAAE,MAAM,EAAE,CAAC;QAAC,CAAC;QAClG,MAAM,UAAU,GAAa,EAAE,CAAC;QAChC,MAAM,QAAQ,GAAa,EAAE,CAAC;QAC9B,MAAM,GAAG,GAAG,oBAAoB,CAAC,MAAM,EAAE,IAAI,EAAE,EAAE,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,oBAAoB,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC;QAC1G,IAAI,aAAa,EAAE,CAAC,GAAG,CAAC,IAAI,KAAK,CAAC,OAAO,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC;YAC9D,aAAa,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,IAAS,EAAE,EAAE;gBACvC,IAAI,IAAI,CAAC,WAAW,CAAC,EAAE,CAAC;oBACtB,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC;oBACnC,IAAI,IAAI,EAAE,QAAQ;wBAAE,QAAQ,CAAC,IAAI,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;gBACpD,CAAC;YACH,CAAC,CAAC,CAAC;QACL,CAAC;QACD,OAAO,EAAE,UAAU,EAAE,gBAAgB,CAAC,UAAU,CAAC,EAAE,QAAQ,EAAE,gBAAgB,CAAC,QAAQ,CAAC,EAAE,aAAa,EAAE,GAAG,EAAE,CAAC;IAChH,CAAC,CAAA;IAED,MAAM,uBAAuB,GAAG,CAAC,YAAoB,EAAE,OAAY,EAAE,uBAA+B,MAAM,EAAE,EAAE;QAC5G,IAAI,CAAC,OAAO,IAAI,CAAC,OAAO,CAAC,oBAAoB,CAAC;YAAE,OAAO,IAAI,CAAC;QAC5D,MAAM,QAAQ,GAAG,YAAY,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;QACxF,IAAI,CAAC,QAAQ;YAAE,OAAO,IAAI,CAAC;QAC3B,MAAM,MAAM,GAAG,GAAG,QAAQ,KAAK,CAAC;QAChC,MAAM,KAAK,GAAG,OAAO,CAAC,oBAAoB,CAAC,CAAC,IAAI,CAAC,CAAC,IAAS,EAAE,EAAE,CAAC,IAAI,CAAC,OAAO,KAAK,MAAM,CAAC,CAAC;QACzF,OAAO,KAAK,EAAE,QAAQ,IAAI,IAAI,CAAC;IACjC,CAAC,CAAA;IAED,MAAM,0BAA0B,GAAG,CAAC,YAAoB,EAAE,OAAY,EAAE,uBAA+B,MAAM,EAAE,IAAsB,EAAE,EAAE;QACvI,IAAI,CAAC,OAAO,IAAI,CAAC,OAAO,CAAC,oBAAoB,CAAC;YAAE,OAAO,IAAI,CAAC;QAC5D,MAAM,QAAQ,GAAG,YAAY,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;QACxF,IAAI,CAAC,QAAQ;YAAE,OAAO,IAAI,CAAC;QAC3B,MAAM,MAAM,GAAG,GAAG,QAAQ,KAAK,CAAC;QAChC,MAAM,KAAK,GAAG,OAAO,CAAC,oBAAoB,CAAC,CAAC,IAAI,CAAC,CAAC,IAAS,EAAE,EAAE,CAAC,IAAI,CAAC,OAAO,KAAK,MAAM,CAAC,CAAC;QACzF,OAAO,KAAK,EAAE,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC;IAC/B,CAAC,CAAA;IAED,MAAM,WAAW,GAAG,KAAK,EAAE,WAAmB,EAAE,QAA8B,EAAE,EAAE;QAChF,IAAI,mBAAmB;YAAE,OAAO;QAChC,sBAAsB,CAAC,IAAI,CAAC,CAAC;QAC7B,sBAAsB,CAAC,WAAW,CAAC,CAAC;QACpC,IAAI,CAAC;YACH,IAAI,kBAAkB,GAAG,WAAW,CAAC;YACrC,IAAI,QAAQ,CAAC,IAAI,EAAE,CAAC;gBAClB,IAAI,CAAC;oBACH,kBAAkB,GAAG,MAAM,8BAA8B,CAAC,WAAW,EAAE,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;gBAC9F,CAAC;gBAAC,MAAM,CAAC;oBACP,kBAAkB,GAAG,WAAW,CAAC;gBACnC,CAAC;YACH,CAAC;YACD,MAAM,MAAM,GAAG,MAAM,YAAY,CAAC,kBAAkB,CAAC,CAAC;YACtD,MAAM,SAAS,GAAG;gBAChB,GAAG,cAAc;gBACjB,CAAC,WAAW,CAAC,EAAE,EAAE,GAAG,EAAE,kBAAkB,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,QAAQ,CAAC,GAAG,IAAI,EAAE,EAAE,YAAY,EAAE,QAAQ,CAAC,YAAY,EAAE;aACvH,CAAC;YACF,iBAAiB,CAAC,SAAS,CAAC,CAAC;YAC7B,IAAI,QAAQ,CAAC,OAAO,IAAI,QAAQ,CAAC,YAAY,EAAE,CAAC;gBAC9C,aAAa,CAAC;oBACZ,GAAG,SAAS;oBACZ,OAAO,EAAE,QAAQ,CAAC,OAAO;oBACzB,YAAY,EAAE,6BAA6B,CAAC,QAAQ,CAAC,YAA0D,CAAC,IAAI,EAAE;iBACvH,CAAC,CAAC;YACL,CAAC;YACD,UAAU,CAAC,GAAG,EAAE;gBACd,aAAa,CAAC,KAAK,CAAC,CAAC;gBACrB,OAAO,CAAC,iBAAiB,CAAC,IAAI,CAAC,CAAC;gBAChC,sBAAsB,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,EAAE,GAAG,IAAI,EAAE,WAAW,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC;gBAClE,sBAAsB,CAAC,KAAK,CAAC,CAAC;gBAC9B,sBAAsB,CAAC,IAAI,CAAC,CAAC;YAC/B,CAAC,EAAE,GAAG,CAAC,CAAC;QACV,CAAC;QAAC,OAAO,CAAM,EAAE,CAAC;YAChB,SAAS,CAAC,OAAO,EAAE,CAAC,EAAE,OAAO,IAAI,iCAAiC,CAAC,CAAC;YACpE,sBAAsB,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,EAAE,GAAG,IAAI,EAAE,WAAW,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC;YAClF,sBAAsB,CAAC,KAAK,CAAC,CAAC;YAC9B,sBAAsB,CAAC,IAAI,CAAC,CAAC;QAC/B,CAAC;IACH,CAAC,CAAC;IAEF,MAAM,mBAAmB,GAAG,KAAK,EAAE,MAA2D,EAAE,EAAE;QAChG,IAAI,mBAAmB,CAAC,WAAW,IAAI,mBAAmB;YAAE,OAAO;QACnE,IAAI,MAAM,CAAC,OAAO,IAAI,MAAM,CAAC,IAAI,EAAE,CAAC;YAClC,sBAAsB,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,IAAI,EAAE,WAAW,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC;YAC9F,IAAI,YAAY,GAAG,cAAc,CAAC,WAAW,CAAC,EAAE,YAAY,IAAI,EAAE,CAAC;YACnE,IAAI,YAA+B,CAAC;YACpC,IAAI,gBAAqB,CAAC;YAC1B,IAAI,CAAC,oBAAoB,EAAE,CAAC;gBAC1B,sBAAsB,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,IAAI,EAAE,WAAW,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,4BAA4B,EAAE,CAAC,CAAC,CAAC;gBACzH,OAAO;YACT,CAAC;YACD,IAAI,CAAC;gBACH,IAAI,CAAC,YAAY,EAAE,CAAC;oBAClB,MAAM,YAAY,GAAG,MAAM,iBAAiB,CAAC,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,IAAI,EAAE,EAAE,OAAO,EAAE,oBAAoB,EAAE,IAA8B,EAAE,SAAS,EAAE,WAAW,EAAE,IAAI,IAAI,EAAE,EAAE,OAAO,EAAE,WAAW,EAAE,EAAE,GAAG,CAAC,CAAC;oBACxM,gBAAgB,GAAG,YAAY,CAAC;oBAChC,IAAI,YAAY,CAAC,aAAa;wBAAE,YAAY,GAAG,YAAY,CAAC,aAAa,CAAC;oBAC1E,IAAI,YAAY,CAAC,QAAQ,EAAE,CAAC;wBAC1B,MAAM,aAAa,GAAG,gBAAgB,CAAE,YAAoB,CAAC,QAAQ,CAAC,CAAC;wBACvE,IAAI,aAAa,KAAK,IAAI,IAAI,aAAa,GAAG,wBAAwB,EAAE,CAAC;4BACvE,sBAAsB,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,IAAI,EAAE,WAAW,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,CAAC,uCAAuC,CAAC,EAAE,CAAC,CAAC,CAAC;4BACvI,OAAO;wBACT,CAAC;wBACD,IAAI,CAAC;4BACH,MAAM,IAAI,GAAG,MAAM,SAAS,CAAC,MAAM,CAAC,IAAI,EAAG,YAAoB,CAAC,QAAQ,CAAC,CAAC;4BAC1E,YAAY,GAAG,IAAI,CAAC,IAAI,CAAC;wBAC3B,CAAC;wBAAC,MAAM,CAAC,CAAC,CAAC;oBACb,CAAC;gBACH,CAAC;gBACD,MAAM,mBAAmB,GAAG,YAAY,CAAC,CAAC,CAAC,YAAY,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,mBAAmB,CAAC,WAAW,EAAE,IAAI,IAAI,EAAE,CAAC,IAAI,MAAM,CAAC,CAAC;gBACjI,MAAM,cAAc,GAAG,0BAA0B,CAAC,WAAW,EAAE,mBAAmB,CAAC,CAAC;gBACpF,IAAI,eAAoB,CAAC;gBACzB,IAAI,WAAW,KAAK,OAAO,EAAE,CAAC;oBAC5B,MAAM,iBAAiB,GAAG,0BAA0B,CAAC,YAAY,EAAE,cAAc,CAAC,aAAa,EAAE,cAAc,CAAC,GAAG,IAAI,EAAE,EAAE,OAAO,CAAC,CAAC;oBACpI,MAAM,OAAO,GAAG,uBAAuB,CAAC,YAAY,EAAE,cAAc,CAAC,aAAa,EAAE,cAAc,CAAC,GAAG,IAAI,EAAE,CAAC,IAAI,KAAK,CAAC;oBACvH,eAAe,GAAG,MAAM,iBAAiB,CAAC,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,aAAa,EAAE,EAAE,UAAU,EAAE,iBAAiB,CAAC,CAAC,CAAC,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC,cAAc,CAAC,UAAU,EAAE,QAAQ,EAAE,cAAc,CAAC,QAAQ,EAAE,EAAE,oBAAoB,EAAE,6BAA6B,CAAC,oBAAoB,EAAE,IAAkD,CAAC,IAAI,EAAE,EAAE,IAAI,EAAE,WAAW,EAAE,IAAI,IAAI,EAAE,EAAE,WAAW,EAAE,YAAY,EAAE,OAAO,EAAE,EAAE,GAAG,CAAC,CAAC;gBACvZ,CAAC;qBAAM,CAAC;oBACN,IAAI,qBAAqB,GAAG,0BAA0B,CAAC,YAAY,EAAE,cAAc,CAAC,aAAa,EAAE,cAAc,CAAC,GAAG,IAAI,EAAE,EAAE,MAAM,CAAC,CAAC;oBACrI,IAAI,CAAC,qBAAqB,IAAI,WAAW,KAAK,MAAM,EAAE,CAAC;wBACrD,qBAAqB,GAAG,KAAK,CAAC;oBAChC,CAAC;oBACD,MAAM,WAAW,GAAG,uBAAuB,CAAC,YAAY,EAAE,cAAc,CAAC,aAAa,EAAE,cAAc,CAAC,GAAG,IAAI,EAAE,CAAC,IAAI,KAAK,CAAC;oBAC3H,eAAe,GAAG,MAAM,gBAAgB,CAAC,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,aAAa,EAAE,EAAE,UAAU,EAAE,qBAAqB,CAAC,CAAC,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC,cAAc,CAAC,UAAU,EAAE,QAAQ,EAAE,cAAc,CAAC,QAAQ,EAAE,EAAE,oBAAoB,EAAE,6BAA6B,CAAC,oBAAoB,CAAC,IAAkD,CAAC,IAAI,EAAE,EAAE,IAAI,EAAE,WAAW,EAAE,IAAI,IAAI,EAAE,EAAE,WAAW,EAAE,YAAY,EAAE,OAAO,EAAE,WAAW,EAAE,gBAAgB,EAAE,EAAE,GAAG,CAAC,CAAC;gBAC5b,CAAC;gBACD,MAAM,IAAI,GAAG,eAAe,EAAE,IAAI,IAAI,YAAY,CAAC;gBACnD,MAAM,GAAG,GAAG,eAAe,EAAE,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,eAAe,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;gBAC5E,MAAM,cAAc,GAAyB,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,YAAY,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,GAAG,EAAE,WAAW,EAAE,KAAK,EAAE,OAAO,EAAE,WAAW,EAAE,IAAI,EAAE,YAAY,EAAE,oBAAoB,CAAC,IAAI,EAAE,CAAC;gBACpM,sBAAsB,CAAC,cAAc,CAAC,CAAC;gBACvC,IAAI,IAAI;oBAAE,aAAa,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,EAAE,GAAG,IAAI,EAAE,CAAC,WAAW,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;gBACpE,MAAM,WAAW,CAAC,MAAM,CAAC,IAAI,EAAE,cAAc,CAAC,CAAC;YACjD,CAAC;YAAC,OAAO,KAAU,EAAE,CAAC;gBACpB,MAAM,qBAAqB,GAAG,KAAK,EAAE,OAAO,KAAK,yBAAyB,IAAI,KAAK,EAAE,OAAO,EAAE,QAAQ,CAAC,YAAY,CAAC,CAAC;gBACrH,MAAM,YAAY,GAAG,qBAAqB,CAAC,CAAC,CAAC,CAAC,CAAC,uCAAuC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,EAAE,OAAO,IAAI,qBAAqB,CAAC,CAAC;gBACpI,sBAAsB,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,EAAE,GAAG,IAAI,EAAE,WAAW,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,YAAY,EAAE,CAAC,CAAC,CAAC;YACzG,CAAC;QACH,CAAC;IACH,CAAC,CAAC;IAEF,MAAM,WAAW,GAAG,CAAC,KAA0B,EAAE,EAAE;QACjD,SAAS,CAAC,QAAQ,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC;QACnC,aAAa,CAAC,KAAK,CAAC,CAAC;QACrB,sBAAsB,CAAC,KAAK,CAAC,CAAC;IAChC,CAAC,CAAC;IAEF,SAAS,CAAC,GAAG,EAAE;QACb,OAAO,CAAC,iBAAiB,CAAC,CAAC,UAAU,CAAC,CAAC;IACzC,CAAC,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC;IAEjB,IAAI,CAAC,oBAAoB,IAAI,CAAC,oBAAoB,EAAE,CAAC;QACnD,OAAO,CACL,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CACvB;QAAA,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,gBAAgB,CAAC,CACnC;UAAA,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,gBAAgB,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,EAAE,IAAI,CACrE;UAAA,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,WAAW,CAAC,CAC9B;YAAA,CAAC,KAAK,CAAC,eAAe,KAAK,IAAI,CAAC,CAAC,CAAC,2DAA2D,CAAC,CAAC,CAAC,iEAAiE,CACnK;UAAA,EAAE,IAAI,CACR;QAAA,EAAE,IAAI,CACR;MAAA,EAAE,IAAI,CAAC,CACR,CAAC;IACJ,CAAC;IAGF,wBAAwB;IACxB,IAAI,UAAU,EAAE,CAAC;QAChB,MAAM,MAAM,GAAG,mBAAmB,CAAC;QAEnC,IAAI,iBAAiB,EAAE,CAAC;YACtB,OAAO,CACL,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,EAAE,EAAE,cAAc,EAAE,QAAQ,EAAE,UAAU,EAAE,QAAQ,EAAE,eAAe,EAAE,MAAM,EAAE,CAAC,CAAC,CACtG;QAAA,CAAC,iBAAiB,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,SAAS,EAC/C;QAAA,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,SAAS,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC,CAAC,sBAAsB,EAAE,IAAI,CAC5F;MAAA,EAAE,IAAI,CAAC,CACR,CAAC;QACJ,CAAC;QAED,OAAO,CACL,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CACvB;MAAA,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,aAAa,EAAE,EAAE,IAAI,EAAE,CAAC,EAAE,SAAS,EAAE,GAAG,EAAE,CAAC,CAAC,CAE/D;;QAAA,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,eAAe,CAAC,CAClC;UAAA,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,WAAW,CAAC,CAC9B;YAAA,CAAC,oBAAoB,CAAC,CAAC,CAAC,CAAC,MAAM,KAAK,IAAI,CAAC,CAAC,CAAC,mBAAmB,CAAC,oBAAoB,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,mBAAmB,CAAC,oBAAoB,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAClK;UAAA,EAAE,IAAI,CACN;UAAA,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,CAC5B;YAAA,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,CAC3B;cAAA,CAAC,CAAC,CAAC,gCAAgC,EAAE,EAAE,IAAI,EAAE,WAAW,KAAK,OAAO,CAAC,CAAC,CAAC,MAAM,KAAK,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,KAAK,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CACpJ;YAAA,EAAE,IAAI,CACR;UAAA,EAAE,IAAI,CACR;QAAA,EAAE,IAAI,CAEN;;QAAA,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,mBAAmB,EAAE,EAAE,IAAI,EAAE,CAAC,EAAE,eAAe,EAAE,MAAM,EAAE,CAAC,CAAC,CAE9E;;UAAA,CAAC,kBAAkB,CACjB,GAAG,CAAC,CAAC,GAAG,WAAW,IAAI,SAAS,EAAE,CAAC,CACnC,UAAU,CAAC,CAAC,IAAI,CAAC,CACjB,YAAY,CAAC,CAAC,MAAM,CAAC,CACrB,UAAU,CAAC,CAAC,YAAY,CAAC,UAAU,CAAC,CACpC,KAAK,CAAC,CAAC,MAAM,CAAC,kBAAkB,CAAC,CACjC,OAAO,CAAC,CAAC,WAAW,CAAC,CACrB,eAAe,CAAC,CAAC,mBAAmB,CAAC,CACrC,mBAAmB,CAAC,CAAC,mBAAmB,CAAC,CACzC,gBAAgB,CAAC,CACf,EACG;iBAAA,CAAC,sGAAsG,CACxG;gBAAA,CAAC,aAAa,CACZ,IAAI,CAAC,CAAC,YAAY,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,YAAY,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,YAAY,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,YAAY,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CACvJ,YAAY,CAAC,CAAC,YAAY,CAAC,OAAO,CAAC,SAAS,CAAC,CAC7C,aAAa,CAAC,CAAC,YAAY,CAAC,OAAO,CAAC,IAAI,CAAC,YAAY,IAAI,CAAW,CAAC,CACrE,SAAS,CAAC,CAAC,mBAAmB,CAAC,OAAO,CAAC,CACvC,QAAQ,CAAC,CAAC,KAAK,CAAC,eAAe,CAAC,CAChC,YAAY,CAAC,CAAC;oBACZ,IAAI,EAAE,GAAG,EAAE;wBACT,IAAI,WAAW,KAAK,MAAM,EAAE,CAAC;4BAC3B,cAAc,CAAC,OAAO,CAAC,CAAC;4BACxB,aAAa,CAAC,KAAK,CAAC,CAAC;4BACrB,sBAAsB,CAAC,KAAK,CAAC,CAAC;4BAC9B,sBAAsB,CAAC,IAAI,CAAC,CAAC;4BAC7B,IAAI,cAAc,CAAC,OAAO,CAAC,EAAE,GAAG,EAAE,CAAC;gCACjC,MAAM,UAAU,GAAG,cAAc,CAAC,OAAO,CAAC,CAAC;gCAC3C,sBAAsB,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,IAAI,EAAE,IAAI,EAAE,UAAU,CAAC,GAAG,EAAE,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE,EAAE,GAAG,EAAE,UAAU,CAAC,GAAG,IAAI,EAAE,EAAE,YAAY,EAAE,UAAU,CAAC,YAAY,IAAI,EAAE,EAAE,IAAI,EAAE,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC;4BACzN,CAAC;iCAAM,CAAC;gCAAC,sBAAsB,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,IAAI,EAAE,IAAI,EAAE,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,WAAW,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE,EAAE,YAAY,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC;4BAAC,CAAC;wBACxI,CAAC;6BAAM,CAAC;4BAAC,OAAO,CAAC,iBAAiB,EAAE,CAAC;wBAAC,CAAC;oBACzC,CAAC;oBACD,oBAAoB,EAAE,oBAAoB,CAAC,CAAC,CAAC,CAAC,MAAM,KAAK,IAAI,CAAC,CAAC,CAAC,mBAAmB,CAAC,oBAAoB,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,mBAAmB,CAAC,oBAAoB,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE;oBACrL,IAAI,EAAE,KAAK,CAAC,qBAAqB,GAAG,CAAC,EAAE,UAAU,EAAE,KAAK,CAAC,QAAQ,CAAC,UAAU,CAAC,MAAM,EAAE,IAAI,EAAE,WAAW;iBACvG,CAAC,EAEN;cAAA,GACF,CAAC,EAIH;;;UAAA,CAAC,CAAC,MAAM,IAAI,mBAAmB,CAAC,WAAW,IAAI,CAC7C,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,yBAAyB,CAAC,CAC5C;cAAA,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,gBAAgB,CAAC,CACnC;gBAAA,CAAC,iBAAiB,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,OAAO,EAC7C;gBAAA,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,iBAAiB,CAAC,CACpC;kBAAA,CAAC,KAAK,CAAC,eAAe,KAAK,IAAI,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,YAAY,CAChE;gBAAA,EAAE,IAAI,CACR;cAAA,EAAE,IAAI,CACR;YAAA,EAAE,IAAI,CAAC,CACR,CAED;;UAAA,CAAC,MAAM,IAAI,CACT,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,UAAU,CAAC,kBAAkB,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,CAC7D;cAAA,CAAC,mBAAmB,IAAI,CACtB,CAAC,KAAK,CACJ,MAAM,CAAC,CAAC,EAAE,GAAG,EAAE,mBAAmB,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,mBAAmB,CAAC,CAAC,CAAC,UAAU,mBAAmB,EAAE,EAAE,CAAC,CACnH,KAAK,CAAC,CAAC,UAAU,CAAC,kBAAkB,CAAC,CACrC,UAAU,CAAC,OAAO,EAClB,CACH,CACD;cAAA,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,iBAAiB,CAAC,CACpC;gBAAA,CAAC,iBAAiB,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,SAAS,EAC/C;gBAAA,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,cAAc,CAAC,CACjC;kBAAA,CAAC,KAAK,CAAC,eAAe,KAAK,IAAI,CAAC,CAAC,CAAC,kCAAkC,CAAC,CAAC,CAAC,qCAAqC,CAC9G;gBAAA,EAAE,IAAI,CACR;cAAA,EAAE,IAAI,CACR;YAAA,EAAE,IAAI,CAAC,CACR,CAED;;UAAA,CAAC,CAAC,MAAM,IAAI,CACT,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,oBAAoB,CAAC,CACtC;gBAAA,CAAC,oBAAoB,CACrB;gBAAA,CAAC,gBAAgB,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,qBAAqB,CAAC,CAAC,OAAO,CAAC,CAAC,aAAa,CAAC,CAC5E;kBAAA,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,mBAAmB,CAAC,CAAC,gBAAgB,EAAE,IAAI,CACjE;gBAAA,EAAE,gBAAgB,CAElB;;gBAAA,CAAC,gBAAgB,CACf,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,qBAAqB,EAAE,EAAE,SAAS,EAAE,EAAE,EAAE,eAAe,EAAE,wBAAwB,EAAE,WAAW,EAAE,SAAS,EAAE,CAAC,CAAC,CAC5H,OAAO,CAAC,CAAC,GAAG,EAAE,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC,CAEpC;kBAAA,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,mBAAmB,CAAC,CAAC,gBAAgB,EAAE,IAAI,CACjE;gBAAA,EAAE,gBAAgB,CACrB;aAAA,EAAE,IAAI,CAAC,CACT,CAED;;UAAA,CAAC,mBAAmB,CAAC,KAAK,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CACtC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,mBAAmB,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC,CAC3D;cAAA,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,iBAAiB,CAAC,CAAC,GAAG,CAAC,mBAAmB,CAAC,KAAK,CAAC,EAAE,IAAI,CAC7E;YAAA,EAAE,IAAI,CAAC,CACR,CAAC,CAAC,CAAC,IAAI,CAEV;;QAAA,EAAE,IAAI,CACR;MAAA,EAAE,IAAI,CACR;IAAA,EAAE,IAAI,CAAC,CACR,CAAC;IACJ,CAAC;IAEC,OAAO,CACL,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CACvB;MAAA,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,gBAAgB,CAAC,CACnC;QAAA,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,oBAAoB,CAAC,CAAC,4BAA4B,CAAC,CAAC,KAAK,CAAC,CAClF;UAAA,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,WAAW,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,aAAa,CAAC,CAClD;YAAA,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,CAC5B;cAAA,CAAC,CAAC,CAAC,gCAAgC,EAAE,EAAE,IAAI,EAAE,WAAW,KAAK,OAAO,CAAC,CAAC,CAAC,MAAM,KAAK,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,KAAK,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CACpJ;YAAA,EAAE,IAAI,CACN;YAAA,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,QAAQ,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,QAAQ,EAAE,YAAY,EAAE,EAAE,EAAE,UAAU,EAAE,EAAE,EAAE,CAAC,CAClG;cAAA,CAAC,gBAAgB,CAAC,SAAS,CAAC,YAAY,CAAC,CAC3C;YAAA,EAAE,IAAI,CACN;YAAA,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,UAAU,EAAE,QAAQ,EAAE,cAAc,EAAE,QAAQ,EAAE,aAAa,EAAE,QAAQ,EAAE,GAAG,EAAE,EAAE,EAAE,CAAC,CAChG;cAAA,CAAC,mBAAmB,EAAE,KAAK,KAAK,cAAc,IAAI,CAChD,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,aAAa,CAAC,CAChC;kBAAA,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,WAAW,CAAC,CAC9B;oBAAA,CAAC,KAAK,CAAC,eAAe,KAAK,IAAI,CAAC,CAAC,CAAC,wEAAwE,CAAC,CAAC,CAAC,kEAAkE,CACjL;kBAAA,EAAE,IAAI,CACR;gBAAA,EAAE,IAAI,CAAC,CACR,CACD;cAAA,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,mBAAmB,CAAC,CACtC;gBAAA,CAAC,cAAc,CAAC,WAAW,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,CAClC,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,EAAE,GAAG,EAAE,cAAc,CAAC,WAAW,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,YAAY,CAAC,EAAG,CACxF,CAAC,CAAC,CAAC,mBAAmB,CAAC,IAAI,CAAC,CAAC,CAAC,CAC7B,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,EAAE,GAAG,EAAE,mBAAmB,CAAC,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,YAAY,CAAC,EAAG,CACjF,CAAC,CAAC,CAAC,IAAI,CACV;cAAA,EAAE,IAAI,CACN;cAAA,CAAC,CAAC,cAAc,CAAC,WAAW,CAAC,EAAE,GAAG,IAAI,CACpC,CAAC,MAAM,CACL,KAAK,CAAC,CAAC,KAAK,CAAC,eAAe,KAAK,IAAI,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC,CAAC,2BAA2B,CAAC,CACvF,OAAO,CAAC,CAAC,GAAG,EAAE,GAAG,aAAa,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,iBAAiB,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAC1E,OAAO,CAAC,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,SAAS,EACxC,CACH,CACD;cAAA,CAAC,cAAc,CAAC,WAAW,CAAC,EAAE,GAAG,IAAI,CACnC,EACE;kBAAA,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,gCAAgC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,GAAG,EAAE,CAAC,aAAa,CAAC,WAAW,CAAC,CAAC,CAAC,OAAO,CAAC,SAAS,CAAC,IAAI,CAAC,QAAQ,CAAC,SAAS,EACxI;kBAAA,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,GAAG,EAAE;gBAC7C,IAAI,CAAC,oBAAoB,EAAE,CAAC;oBAAC,SAAS,CAAC,OAAO,EAAE,4BAA4B,CAAC,CAAC;oBAAC,OAAO;gBAAC,CAAC;gBACxF,IAAI,WAAW,KAAK,MAAM,IAAI,oBAAoB,CAAC,IAAI,KAAK,UAAU,EAAE,CAAC;oBACvE,OAAO,CAAC,aAAa,EAAE,CAAC;gBAC1B,CAAC;qBAAM,CAAC;oBACN,aAAa,CAAC,IAAI,CAAC,CAAC;oBACpB,cAAc,CAAC,MAAM,CAAC,CAAC;oBACvB,sBAAsB,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,WAAW,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,YAAY,EAAE,SAAS,EAAE,CAAC,CAAC;oBAC7G,sBAAsB,CAAC,KAAK,CAAC,CAAC;oBAC9B,sBAAsB,CAAC,IAAI,CAAC,CAAC;gBAC/B,CAAC;YACH,CAAC,CAAC,CAAC,OAAO,CAAC,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,SAAS,EAC7C;gBAAA,GAAG,CACJ,CACH;YAAA,EAAE,IAAI,CACR;UAAA,EAAE,IAAI,CACR;QAAA,EAAE,UAAU,CACd;MAAA,EAAE,IAAI,CACR;IAAA,EAAE,IAAI,CAAC,CACR,CAAC;AACJ,CAAC,CAAC;AAEF,MAAM,MAAM,GAAG,UAAU,CAAC,MAAM,CAAC;IAC/B,IAAI,EAAE;QACJ,IAAI,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,eAAe,EAAE,aAAa,EAAE,SAAS,EAAE,QAAQ;QAC3E,GAAG,CAAC,QAAQ,CAAC,EAAE,KAAK,KAAK,CAAC,CAAC,CAAE,EAAE,SAAS,EAAE,MAAM,EAAE,cAAc,EAAE,QAAQ,EAAE,UAAU,EAAE,QAAQ,EAAE,cAAc,EAAE,WAAW,EAAU,CAAC,CAAC,CAAC,EAAE,CAAC;KAC9I;IACD,aAAa,EAAE;QACb,KAAK,EAAE,MAAM,EAAE,eAAe,EAAE,SAAS,EAAE,QAAQ,EAAE,QAAQ;QAC7D,GAAG,CAAC,QAAQ,CAAC,EAAE,KAAK,KAAK,CAAC,CAAC,CAAE,EAAE,QAAQ,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,SAAS,EAAE,MAAM,EAAE,YAAY,EAAE,EAAE,EAAE,WAAW,EAAE,MAAM,EAAE,YAAY,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,YAAY,EAAE,EAAE,EAAE,SAAS,EAAE,EAAE,GAAW,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,GAAG,CAAC;KAC7O;IACD,eAAe,EAAE;QACf,aAAa,EAAE,KAAK,EAAE,UAAU,EAAE,QAAQ,EAAE,cAAc,EAAE,eAAe,EAAE,iBAAiB,EAAE,EAAE,EAAE,eAAe,EAAE,EAAE,EAAE,eAAe,EAAE,SAAS,EAAE,iBAAiB,EAAE,CAAC,EAAE,iBAAiB,EAAE,SAAS,EAAE,MAAM,EAAE,EAAE;QACnN,GAAG,CAAC,QAAQ,CAAC,EAAE,KAAK,KAAK,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KACtD;IACD,WAAW,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE,UAAU,EAAE,KAAK,EAAE,KAAK,EAAE,SAAS,GAAG;IACnE,SAAS,EAAE,EAAE,eAAe,EAAE,SAAS,EAAE,iBAAiB,EAAE,EAAE,EAAE,eAAe,EAAE,CAAC,EAAE,YAAY,EAAE,EAAE,GAAG;IACvG,QAAQ,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE,UAAU,EAAE,KAAK,EAAE,KAAK,EAAE,SAAS,GAAG;IAChE,mBAAmB,EAAE,EAAE,IAAI,EAAE,CAAC,EAAE,QAAQ,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,GAAG;IAChF,MAAM,EAAE,EAAE,IAAI,EAAE,CAAC,GAAG;IACpB,aAAa,EAAE;QACb,QAAQ,EAAE,UAAU,EAAE,MAAM,EAAE,GAAG,EAAE,SAAS,EAAE,QAAQ,EAAE,eAAe,EAAE,iBAAiB,EAAE,eAAe,EAAE,EAAE,EAAE,iBAAiB,EAAE,EAAE,EAAE,YAAY,EAAE,EAAE,EAAE,MAAM,EAAE,GAAG;KACtK;IACD,iBAAiB,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,EAAE,QAAQ,EAAE,EAAE,EAAE;IACvE,gBAAgB,EAAE;QAChB,KAAK,EAAE,MAAM,EAAE,eAAe,EAAE,OAAO,EAAE,YAAY,EAAE,EAAE,EAAE,eAAe,EAAE,EAAE,EAAE,iBAAiB,EAAE,EAAE,EAAE,WAAW,EAAE,MAAM,EAAE,YAAY,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,EAAE,aAAa,EAAE,GAAG,EAAE,YAAY,EAAE,EAAE,EAAE,SAAS,EAAE,CAAC;QACrN,GAAG,CAAC,QAAQ,CAAC,EAAE,KAAK,KAAK,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,QAAQ,EAAE,QAAQ,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC;KACnG;IACD,oBAAoB,EAAE,EAAE,QAAQ,EAAE,CAAC,GAAG;IACtC,KAAK,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE,UAAU,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,YAAY,EAAE,CAAC,EAAE,SAAS,EAAE,QAAQ,EAAE;IAChG,WAAW,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,QAAQ,EAAE,YAAY,EAAE,EAAE,EAAE,UAAU,EAAE,EAAE,EAAE;IACnG,aAAa,EAAE,EAAE,YAAY,EAAE,EAAE,EAAE;IACnC,SAAS,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE,UAAU,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,YAAY,EAAE,EAAE,EAAE,SAAS,EAAE,QAAQ,EAAE;IACrG,mBAAmB,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,YAAY,EAAE,EAAE,EAAE,OAAO,EAAE,CAAC,EAAE,QAAQ,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,EAAE,YAAY,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,YAAY,EAAE,CAAC,EAAE,SAAS,EAAE,CAAC,EAAE,eAAe,EAAE,SAAS,EAAE;IACjP,YAAY,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,YAAY,EAAE,EAAE,EAAE,UAAU,EAAE,OAAO,EAAE;IACtF,mBAAmB,EAAE;QACnB,QAAQ,EAAE,UAAU,EAAE,MAAM,EAAE,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,eAAe,EAAE,SAAS,EAAE,WAAW,EAAE,CAAC,EAAE,WAAW,EAAE,SAAS,EAAE,eAAe,EAAE,EAAE,EAAE,iBAAiB,EAAE,EAAE,EAAE,YAAY,EAAE,EAAE,EAAE,UAAU,EAAE,QAAQ,EAAE,cAAc,EAAE,QAAQ,EAAE,WAAW,EAAE,SAAS,EAAE,YAAY,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,EAAE,aAAa,EAAE,GAAG,EAAE,YAAY,EAAE,CAAC,EAAE,SAAS,EAAE,CAAC,EAAE,MAAM,EAAE,GAAG;KACvW;IACD,iBAAiB,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,QAAQ,EAAE,EAAE,EAAE,UAAU,EAAE,KAAK,EAAE,SAAS,EAAE,QAAQ,EAAE;IAC7F,iBAAiB,EAAE,EAAE,IAAI,EAAE,CAAC,EAAE,eAAe,EAAE,oBAAoB,EAAE,cAAc,EAAE,QAAQ,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE;IACnI,cAAc,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,EAAE,EAAE,UAAU,EAAE,MAAM,EAAE,SAAS,EAAE,EAAE,EAAE,SAAS,EAAE,QAAQ,EAAE;IACvG,aAAa,EAAE,EAAE,eAAe,EAAE,SAAS,EAAE,OAAO,EAAE,EAAE,EAAE,YAAY,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,YAAY,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,EAAE,aAAa,EAAE,GAAG,EAAE,YAAY,EAAE,CAAC,EAAE,SAAS,EAAE,CAAC,EAAE;IACzM,WAAW,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,EAAE,SAAS,EAAE,QAAQ,EAAE,QAAQ,EAAE,EAAE,EAAE;IACtF,SAAS,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,QAAQ,EAAE,EAAE,EAAE,SAAS,EAAE,CAAC,EAAE,SAAS,EAAE,QAAQ,EAAE;IAChF,yBAAyB,EAAE,EAAE,QAAQ,EAAE,UAAU,EAAE,GAAG,EAAE,QAAQ,CAAC,EAAE,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,IAAI,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,EAAE,GAAG,EAAE;IACnJ,gBAAgB,EAAE,EAAE,aAAa,EAAE,KAAK,EAAE,UAAU,EAAE,QAAQ,EAAE,eAAe,EAAE,iBAAiB,EAAE,eAAe,EAAE,CAAC,EAAE,iBAAiB,EAAE,EAAE,EAAE,YAAY,EAAE,EAAE,EAAE,GAAG,EAAE,CAAC,EAAE;IACzK,iBAAiB,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,UAAU,EAAE,MAAM,EAAE;IACvE,oBAAoB,EAAE;QACpB,QAAQ,EAAE,UAAU;QACpB,MAAM,EAAE,EAAE;QACV,IAAI,EAAE,CAAC;QACP,KAAK,EAAE,CAAC;QACR,UAAU,EAAE,QAAQ;QACpB,cAAc,EAAE,QAAQ;QACxB,MAAM,EAAE,KAAK,EAAE,wCAAwC;KACxD;IACD,qBAAqB,EAAE;QACrB,eAAe,EAAE,oBAAoB,EAAE,2CAA2C;QAClF,WAAW,EAAE,CAAC;QACd,WAAW,EAAE,0BAA0B;QACvC,eAAe,EAAE,EAAE;QACnB,iBAAiB,EAAE,EAAE;QACrB,YAAY,EAAE,EAAE;QAChB,WAAW,EAAE,MAAM;QACnB,YAAY,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE;QACrC,aAAa,EAAE,GAAG;QAClB,YAAY,EAAE,CAAC;QACf,SAAS,EAAE,CAAC;KACb;IACD,mBAAmB,EAAE;QACnB,KAAK,EAAE,SAAS;QAChB,UAAU,EAAE,MAAM;QAClB,QAAQ,EAAE,EAAE;KACb;IACD,kBAAkB,EAAE;QAClB,QAAQ,EAAE,UAAU;QACpB,GAAG,EAAE,CAAC;QACN,IAAI,EAAE,CAAC;QACP,KAAK,EAAE,CAAC;QACR,MAAM,EAAE,CAAC;KACV;CACF,CAAC,CAAC","sourcesContent":["import React, { useEffect, useMemo, useState } from 'react';\nimport { View, Text, StyleSheet, Image, ScrollView, Platform, ActivityIndicator, TouchableOpacity } from 'react-native'; // 🚨 Added TouchableOpacity\nimport { showAlert } from '../../utils/platformAlert';\nimport { EnhancedCameraView } from '../EnhancedCameraView';\nimport { TemplateComponent, LocalizedText, GovernmentDocumentType, ISilentCaptureResult, IBbox, GovernmentDocumentTypeShorted, GovernmentDocumentTypeBackend } from '../../types/KYC.types';\nimport IdCardOverlay from '../OverLay/IdCard';\nimport { useTemplateKYCFlowContext } from '../../hooks/useTemplateKYCFlow';\nimport { useI18n } from '../../hooks/useI18n';\nimport { Button } from '../ui/Button';\nimport { removeDuplicates } from '../../utils/remove-duplicate';\nimport { backVerification, checkTemplateType, frontVerification } from '../../modules/api/CardAuthentification';\nimport { getDocumentTypeInfo } from '../../utils/get-document-type-info';\nimport pathToBase64 from '../../utils/pathToBase64';\nimport { cropByObb, cropImageWithBBoxWithTolerance, getObbConfidence, OBB_CONFIDENCE_THRESHOLD } from '../../utils/cropByObb';\nimport REGION_MAPPING from '../../config/region_mapping.json';\n\nconst ISO_TO_COUNTRY_NAME: Record<string, string> = { 'KE': 'Kenya', 'CM': 'Cameroon', 'NG': 'Nigeria', 'CA': 'Canada', 'FR': 'France', 'GH': 'Ghana', 'ZA': 'South Africa', 'GB': 'Britain', 'CI': 'Ivory Coast', 'SN': 'Senegal', 'TG': 'Togo', 'ML': 'Mali' };\n\ninterface IIDCardPayload { dir: string; file: string; mrz: string; templatePath?: string; }\ninterface IDCardCaptureProps { component: TemplateComponent; value?: Record<string, IIDCardPayload>; onValueChange: (value: Record<string, IIDCardPayload | string>) => void; error?: string; language?: string; currentSide?: string; }\n\nexport const IDCardCapture: React.FC<IDCardCaptureProps> = ({ component, value = {}, onValueChange, error, language = 'en' }) => {\n const { t, locale } = useI18n();\n const [showCamera, setShowCamera] = useState(false);\n const [capturedImages, setCapturedImages] = useState<Record<string, IIDCardPayload>>(value || {});\n const [currentSide, setCurrentSide] = useState<'front' | 'back'>('front');\n const [bboxBySide, setBboxBySide] = useState<Record<string, IBbox>>({});\n const [silentCaptureResult, setSilentCaptureResult] = useState<ISilentCaptureResult>({ success: false, isAnalyzing: false });\n const [isProcessingCapture, setIsProcessingCapture] = useState(false);\n const [processingImagePath, setProcessingImagePath] = useState<string | null>(null);\n \n // 🚨 ADDED: Key to force camera re-mount\n const [cameraKey, setCameraKey] = useState(0);\n\n const documentTypeMapping: Record<string, GovernmentDocumentType> = { 'nationalId': 'national_id', 'passport': 'passport', 'driversLicense': 'drivers_licence', 'residencePermit': 'permanent_residence', 'healthInsuranceCard': 'health_insurance_card', };\n const { actions, state, env } = useTemplateKYCFlowContext();\n\n const getLocalizedText = (text: LocalizedText | Record<string, LocalizedText>): string => {\n if (text && typeof text[currentSide] === 'object' && text[currentSide][locale]) return text[currentSide][locale] || '';\n return \"\";\n };\n\n const countrySelectionData = useMemo(() => {\n const countrySelectionComponent = state.template.components.find(c => c.type === 'country_selection');\n return countrySelectionComponent ? state.componentData[countrySelectionComponent.id] : null;\n }, [state.template.components, state.componentData]);\n\n const selectedDocumentType = useMemo<{ type: GovernmentDocumentType; region: string } | null>(() => {\n if (!countrySelectionData?.documentType) return null;\n const backendDocType = countrySelectionData.documentType;\n const mappedType = documentTypeMapping[backendDocType] || backendDocType as GovernmentDocumentType;\n return { type: mappedType, region: countrySelectionData.region || 'root' };\n }, [countrySelectionData, documentTypeMapping]);\n\n const countryData = useMemo(() => countrySelectionData, [countrySelectionData]);\n\n const [isRebootingCamera, setIsRebootingCamera] = useState(false);\n\n const refreshCamera = () => {\n setIsRebootingCamera(true);\n \n setTimeout(() => {\n setCameraKey(prev => prev + 1);\n setIsRebootingCamera(false);\n }, 500);\n };\n\n \n\n useEffect(() => {\n if (value && Object.keys(value).length > 0) {\n if (JSON.stringify(value) !== JSON.stringify(capturedImages)) {\n const updatedImages = value as Record<string, IIDCardPayload>;\n setCapturedImages(updatedImages);\n const currentImageData = updatedImages[currentSide];\n if (currentImageData?.dir) {\n setSilentCaptureResult(prev => ({\n ...prev, path: currentImageData.dir, success: true, isAnalyzing: false, mrz: currentImageData.mrz || '', templatePath: currentImageData.templatePath || '',\n }));\n }\n }\n }\n }, [value, currentSide]);\n\n const cameraConfig = useMemo(() => {\n const instructions = selectedDocumentType ? (locale === 'en' ? getDocumentTypeInfo(selectedDocumentType.type).instructions.en : getDocumentTypeInfo(selectedDocumentType.type).instructions.fr) : getLocalizedText(component.instructions as Record<string, LocalizedText>);\n return {\n cameraType: 'back' as const, flashMode: 'auto' as const,\n overlay: { guideText: instructions, bbox: { xMin: 15, yMin: 20, xMax: 85, yMax: 70, borderColor: '#2DBD60', borderWidth: 3, cornerRadius: 8 } }\n };\n }, [selectedDocumentType, locale, component.instructions]);\n\n const retakePicture = (sideToRetake: 'front' | 'back') => {\n setIsProcessingCapture(false);\n setProcessingImagePath(null);\n setSilentCaptureResult({ path: '', success: false, isAnalyzing: false, error: '', templatePath: '', mrz: '', bbox: undefined });\n setShowCamera(true);\n actions.showCustomStepper(false);\n setCapturedImages((prev) => { const newState = { ...prev }; delete newState[sideToRetake]; return newState; });\n if (value) { const newValue = { ...value }; delete newValue[sideToRetake]; onValueChange(newValue); }\n };\n\n const getCurrentSideVerification = (currentSide: string, countryKey: string) => {\n const rawDocType = countrySelectionData?.documentType;\n if (!rawDocType || !countryKey) { return { authMethod: [], mrzTypes: [], regionMapping: null, key: 'root' }; }\n const rawCountryName = ISO_TO_COUNTRY_NAME[countryData?.code || ''] || countryData?.code || countryKey;\n const baseMapping = (REGION_MAPPING as any).regionMapping || REGION_MAPPING;\n let countryMapping = baseMapping[rawCountryName];\n if (!countryMapping) {\n const foundKey = Object.keys(baseMapping).find(k => k.toLowerCase() === rawCountryName.toLowerCase() || k.toLowerCase() === countryKey.toLowerCase());\n if (foundKey) countryMapping = baseMapping[foundKey];\n }\n if (!countryMapping) { return { authMethod: [], mrzTypes: [], regionMapping: null, key: 'root' }; }\n const regionMapping = countryMapping[rawDocType];\n if (!regionMapping) { return { authMethod: [], mrzTypes: [], regionMapping: null, key: 'root' }; }\n const authMethod: string[] = [];\n const mrzTypes: string[] = [];\n const key = countrySelectionData.region?.trim()?.length > 0 ? countrySelectionData.region.trim() : 'root';\n if (regionMapping?.[key] && Array.isArray(regionMapping[key])) {\n regionMapping[key].forEach((item: any) => {\n if (item[currentSide]) {\n authMethod.push(item[currentSide]);\n if (item?.mrz_type) mrzTypes.push(item?.mrz_type);\n }\n });\n }\n return { authMethod: removeDuplicates(authMethod), mrzTypes: removeDuplicates(mrzTypes), regionMapping, key };\n }\n\n const getCorrespondingMrzType = (templatePath: string, mapping: any, selectedDocumentType: string = \"root\") => {\n if (!mapping || !mapping[selectedDocumentType]) return null;\n const fileName = templatePath.split(\"/\").pop()?.replace(\".jpg\", \"\").replace(\".png\", \"\");\n if (!fileName) return null;\n const pyName = `${fileName}.py`;\n const found = mapping[selectedDocumentType].find((item: any) => item.py_file === pyName);\n return found?.mrz_type || null;\n }\n\n const getCorrespondingAuthMethod = (templatePath: string, mapping: any, selectedDocumentType: string = \"root\", side: 'front' | 'back') => {\n if (!mapping || !mapping[selectedDocumentType]) return null;\n const fileName = templatePath.split(\"/\").pop()?.replace(\".jpg\", \"\").replace(\".png\", \"\");\n if (!fileName) return null;\n const pyName = `${fileName}.py`;\n const found = mapping[selectedDocumentType].find((item: any) => item.py_file === pyName);\n return found?.[side] || null;\n }\n\n const autoCapture = async (capturePath: string, verified: ISilentCaptureResult) => {\n if (isProcessingCapture) return;\n setIsProcessingCapture(true);\n setProcessingImagePath(capturePath);\n try {\n let imagePathForUpload = capturePath;\n if (verified.bbox) {\n try {\n imagePathForUpload = await cropImageWithBBoxWithTolerance(capturePath, verified.bbox, 0.15);\n } catch {\n imagePathForUpload = capturePath;\n }\n }\n const base64 = await pathToBase64(imagePathForUpload);\n const newImages = {\n ...capturedImages,\n [currentSide]: { dir: imagePathForUpload, file: base64, mrz: verified.mrz || \"\", templatePath: verified.templatePath },\n };\n setCapturedImages(newImages);\n if (verified.country && verified.documentType) {\n onValueChange({\n ...newImages,\n country: verified.country,\n documentType: GovernmentDocumentTypeBackend[verified.documentType as keyof typeof GovernmentDocumentTypeBackend] || '',\n });\n }\n setTimeout(() => {\n setShowCamera(false);\n actions.showCustomStepper(true);\n setSilentCaptureResult(prev => ({ ...prev, isAnalyzing: false }));\n setIsProcessingCapture(false);\n setProcessingImagePath(null);\n }, 600);\n } catch (e: any) {\n showAlert('Error', e?.message || 'Impossible de capturer la photo');\n setSilentCaptureResult(prev => ({ ...prev, isAnalyzing: false, success: false }));\n setIsProcessingCapture(false);\n setProcessingImagePath(null);\n }\n };\n\n const handleSilentCapture = async (result: { success: boolean; path?: string; error?: string }) => {\n if (silentCaptureResult.isAnalyzing || isProcessingCapture) return;\n if (result.success && result.path) {\n setSilentCaptureResult((prev) => ({ ...prev, isAnalyzing: true, success: false, error: '' }));\n let templatePath = capturedImages[currentSide]?.templatePath || '';\n let templateBbox: IBbox | undefined;\n let templateResponse: any;\n if (!selectedDocumentType) {\n setSilentCaptureResult((prev) => ({ ...prev, isAnalyzing: false, success: false, error: 'Document type not selected' }));\n return;\n }\n try {\n if (!templatePath) {\n const templateType = await checkTemplateType({ path: result.path || '', docType: selectedDocumentType?.type as GovernmentDocumentType, docRegion: countryData?.code || \"\", postfix: currentSide }, env);\n templateResponse = templateType;\n if (templateType.template_path) templatePath = templateType.template_path;\n if (templateType.card_obb) {\n const obbConfidence = getObbConfidence((templateType as any).card_obb);\n if (obbConfidence !== null && obbConfidence < OBB_CONFIDENCE_THRESHOLD) {\n setSilentCaptureResult((prev) => ({ ...prev, isAnalyzing: false, success: false, error: t('kyc.idCardCapture.cardNotFullyInFrame') }));\n return;\n }\n try {\n const crop = await cropByObb(result.path, (templateType as any).card_obb);\n templateBbox = crop.bbox;\n } catch { }\n }\n }\n const extractedCountryKey = templatePath ? templatePath.split('/')[0] : (ISO_TO_COUNTRY_NAME[countryData?.code || ''] || 'root');\n const regionMappings = getCurrentSideVerification(currentSide, extractedCountryKey);\n let verificationRes: any;\n if (currentSide === 'front') {\n const matchedAuthMethod = getCorrespondingAuthMethod(templatePath, regionMappings.regionMapping, regionMappings.key || '', 'front');\n const mrzType = getCorrespondingMrzType(templatePath, regionMappings.regionMapping, regionMappings.key || '') || 'TD1';\n verificationRes = await frontVerification({ path: result.path, regionMapping: { authMethod: matchedAuthMethod ? [matchedAuthMethod] : regionMappings.authMethod, mrzTypes: regionMappings.mrzTypes }, selectedDocumentType: GovernmentDocumentTypeShorted[selectedDocumentType?.type as keyof typeof GovernmentDocumentTypeShorted] || '', code: countryData?.code || '', currentSide, templatePath, mrzType }, env);\n } else {\n let matchedBackAuthMethod = getCorrespondingAuthMethod(templatePath, regionMappings.regionMapping, regionMappings.key || '', 'back');\n if (!matchedBackAuthMethod && currentSide === 'back') {\n matchedBackAuthMethod = 'MRZ';\n }\n const backMrzType = getCorrespondingMrzType(templatePath, regionMappings.regionMapping, regionMappings.key || '') || 'TD1';\n verificationRes = await backVerification({ path: result.path, regionMapping: { authMethod: matchedBackAuthMethod ? [matchedBackAuthMethod] : regionMappings.authMethod, mrzTypes: regionMappings.mrzTypes }, selectedDocumentType: GovernmentDocumentTypeShorted[selectedDocumentType.type as keyof typeof GovernmentDocumentTypeShorted] || '', code: countryData?.code || '', currentSide, templatePath, mrzType: backMrzType, templateResponse }, env);\n }\n const bbox = verificationRes?.bbox || templateBbox;\n const mrz = verificationRes?.mrz ? JSON.stringify(verificationRes.mrz) : \"\";\n const verifiedResult: ISilentCaptureResult = { path: result.path, templatePath, bbox, success: true, mrz, isAnalyzing: false, country: countryData?.code, documentType: selectedDocumentType.type };\n setSilentCaptureResult(verifiedResult);\n if (bbox) setBboxBySide(prev => ({ ...prev, [currentSide]: bbox }));\n await autoCapture(result.path, verifiedResult);\n } catch (error: any) {\n const isCardNotFullyInFrame = error?.message === 'CARD_NOT_FULLY_IN_FRAME' || error?.message?.includes('entirement');\n const errorMessage = isCardNotFullyInFrame ? t('kyc.idCardCapture.cardNotFullyInFrame') : (error?.message || 'Erreur de détection');\n setSilentCaptureResult(prev => ({ ...prev, isAnalyzing: false, success: false, error: errorMessage }));\n }\n }\n };\n\n const handleError = (event: { message: string }) => {\n showAlert('Erreur', event.message);\n setShowCamera(false);\n setIsProcessingCapture(false);\n };\n\n useEffect(() => {\n actions.showCustomStepper(!showCamera);\n }, [showCamera]);\n\n if (!countrySelectionData || !selectedDocumentType) {\n return (\n <View style={styles.root}>\n <View style={styles.previewContainer}>\n <Text style={styles.title}>{getLocalizedText(component.labels)}</Text>\n <Text style={styles.description}>\n {state.currentLanguage === \"en\" ? \"Please complete the country and document selection first.\" : \"Veuillez d'abord compléter la sélection du pays et du document.\"}\n </Text>\n </View>\n </View>\n );\n }\n\n\n // --- CAMERA RENDER ---\n if (showCamera) {\n const isBusy = isProcessingCapture;\n\n if (isRebootingCamera) {\n return (\n <View style={[styles.root, { justifyContent: 'center', alignItems: 'center', backgroundColor: '#000' }]}>\n <ActivityIndicator size=\"large\" color=\"#2DBD60\" />\n <Text style={{ color: 'white', marginTop: 20, fontSize: 16 }}>Initializing Camera...</Text>\n </View>\n );\n }\n\n return (\n <View style={styles.root}>\n <View style={[styles.cameraWrapper, { flex: 1, minHeight: 400 }]}>\n \n <View style={styles.headerContainer}>\n <Text style={styles.headerTitle}>\n {selectedDocumentType ? (locale === 'en' ? getDocumentTypeInfo(selectedDocumentType.type).name.en : getDocumentTypeInfo(selectedDocumentType.type).name.fr) : ''}\n </Text>\n <View style={styles.stepBadge}>\n <Text style={styles.stepText}>\n {t('kyc.idCardCapture.captureTitle', { side: currentSide === 'front' ? locale === 'en' ? 'Front' : 'Recto' : locale === 'en' ? 'Back' : 'Verso' })}\n </Text>\n </View>\n </View>\n \n <View style={[styles.cameraFeedContainer, { flex: 1, backgroundColor: '#000' }]}>\n \n <EnhancedCameraView\n key={`${currentSide}-${cameraKey}`}\n showCamera={true}\n isProcessing={isBusy}\n cameraType={cameraConfig.cameraType}\n style={styles.absoluteFillObject} \n onError={handleError}\n onSilentCapture={handleSilentCapture}\n silentCaptureResult={silentCaptureResult}\n overlayComponent={\n <>\n {/* We ONLY put the ID frame here, because if the camera fails, we don't care if the frame fails too */}\n <IdCardOverlay\n xMin={cameraConfig.overlay.bbox.xMin} yMin={cameraConfig.overlay.bbox.yMin} xMax={cameraConfig.overlay.bbox.xMax} yMax={cameraConfig.overlay.bbox.yMax}\n instructions={cameraConfig.overlay.guideText}\n cornerOpacity={cameraConfig.overlay.bbox.cornerRadius || 0 as number}\n isSuccess={silentCaptureResult.success}\n language={state.currentLanguage}\n stepperProps={{\n back: () => {\n if (currentSide === 'back') {\n setCurrentSide('front');\n setShowCamera(false);\n setIsProcessingCapture(false);\n setProcessingImagePath(null);\n if (capturedImages['front']?.dir) {\n const frontImage = capturedImages['front'];\n setSilentCaptureResult((prev) => ({ ...prev, path: frontImage.dir, success: true, isAnalyzing: false, error: '', mrz: frontImage.mrz || '', templatePath: frontImage.templatePath || '', bbox: bboxBySide['front'] }));\n } else { setSilentCaptureResult((prev) => ({ ...prev, path: '', success: false, isAnalyzing: false, error: '', templatePath: '' })); }\n } else { actions.previousComponent(); }\n },\n selectedDocumentType: selectedDocumentType ? (locale === 'en' ? getDocumentTypeInfo(selectedDocumentType.type).name.en : getDocumentTypeInfo(selectedDocumentType.type).name.fr) : '',\n step: state.currentComponentIndex + 1, totalSteps: state.template.components.length, side: currentSide,\n }}\n />\n </>\n }\n />\n\n\n {!isBusy && silentCaptureResult.isAnalyzing && (\n <View style={styles.topAnalyzingPillContainer}>\n <View style={styles.topAnalyzingPill}>\n <ActivityIndicator size=\"small\" color=\"white\" />\n <Text style={styles.analyzingPillText}>\n {state.currentLanguage === 'en' ? 'Scanning...' : 'Analyse...'}\n </Text>\n </View>\n </View>\n )}\n\n {isBusy && (\n <View style={[StyleSheet.absoluteFillObject, { zIndex: 9999 }]}>\n {processingImagePath && (\n <Image\n source={{ uri: processingImagePath.startsWith('file://') ? processingImagePath : `file://${processingImagePath}` }}\n style={StyleSheet.absoluteFillObject}\n resizeMode=\"cover\"\n />\n )}\n <View style={styles.processingOverlay}>\n <ActivityIndicator size=\"large\" color=\"#2DBD60\" />\n <Text style={styles.processingText}>\n {state.currentLanguage === 'en' ? 'Perfect!\\nProcessing Document...' : 'Parfait!\\nTraitement du document...'}\n </Text>\n </View>\n </View>\n )}\n\n {!isBusy && (\n <View style={styles.escapeHatchContainer}>\n {/* Refresh Button */}\n <TouchableOpacity style={styles.fallbackRefreshButton} onPress={refreshCamera}>\n <Text style={styles.fallbackRefreshText}>↻ Refresh Camera</Text>\n </TouchableOpacity>\n\n <TouchableOpacity \n style={[styles.fallbackRefreshButton, { marginTop: 15, backgroundColor: 'rgba(220, 38, 38, 0.8)', borderColor: '#DC2626' }]} \n onPress={() => setShowCamera(false)}\n >\n <Text style={styles.fallbackRefreshText}>Cancel / Go Back</Text>\n </TouchableOpacity>\n </View>\n )}\n\n {silentCaptureResult.error && !isBusy ? (\n <View style={[styles.floatingErrorBanner, { zIndex: 10000 }]}>\n <Text style={styles.floatingErrorText}>⚠️ {silentCaptureResult.error}</Text>\n </View>\n ) : null}\n\n </View>\n </View>\n </View>\n );\n}\n\n return (\n <View style={styles.root}>\n <View style={styles.previewContainer}>\n <ScrollView style={styles.previewItemContainer} showsVerticalScrollIndicator={false}>\n <View key={currentSide} style={styles.sideContainer}>\n <Text style={styles.sideTitle}>\n {t('kyc.idCardCapture.captureTitle', { side: currentSide === 'front' ? locale === 'en' ? 'Front' : 'Recto' : locale === 'en' ? 'Back' : 'Verso' })}\n </Text>\n <Text style={{ fontSize: 14, color: '#666', textAlign: 'center', marginBottom: 16, lineHeight: 22 }}>\n {getLocalizedText(component.instructions)}\n </Text>\n <View style={{ alignItems: 'center', justifyContent: 'center', flexDirection: \"column\", gap: 16 }}>\n {silentCaptureResult?.error === 'TOO_FAR_AWAY' && (\n <View style={styles.warningBanner}>\n <Text style={styles.warningText}>\n {state.currentLanguage === \"en\" ? \"Move the document closer to the camera and place it on a flat surface.\" : \"Veuillez rapprocher le document de la caméra et le poser à plat.\"}\n </Text>\n </View>\n )}\n <View style={styles.imagePreviewWrapper}>\n {capturedImages[currentSide]?.dir ? (\n <Image source={{ uri: capturedImages[currentSide].dir }} style={styles.previewImage} />\n ) : silentCaptureResult.path ? (\n <Image source={{ uri: silentCaptureResult.path }} style={styles.previewImage} />\n ) : null}\n </View>\n {!capturedImages[currentSide]?.dir && (\n <Button\n title={state.currentLanguage === \"en\" ? \"Start Scanning\" : \"Commencer la numérisation\"}\n onPress={() => { setShowCamera(true); actions.showCustomStepper(false); }}\n variant=\"primary\" size=\"large\" fullWidth\n />\n )}\n {capturedImages[currentSide]?.dir && (\n <>\n <Button title={t('kyc.idCardCapture.retakeButton')} onPress={() => retakePicture(currentSide)} variant=\"outline\" size=\"medium\" fullWidth />\n <Button title={t('common.next')} onPress={() => {\n if (!selectedDocumentType) { showAlert('Error', 'Document type not selected'); return; }\n if (currentSide === 'back' || selectedDocumentType.type === 'passport') {\n actions.nextComponent();\n } else {\n setShowCamera(true);\n setCurrentSide('back');\n setSilentCaptureResult({ success: false, isAnalyzing: false, path: '', error: '', templatePath: undefined });\n setIsProcessingCapture(false);\n setProcessingImagePath(null);\n }\n }} variant=\"primary\" size=\"large\" fullWidth />\n </>\n )}\n </View>\n </View>\n </ScrollView>\n </View>\n </View>\n );\n};\n\nconst styles = StyleSheet.create({\n root: {\n flex: 1, width: '100%', backgroundColor: 'transparent', alignSelf: 'center',\n ...(Platform.OS === 'web' ? ({ minHeight: '85vh', justifyContent: 'center', alignItems: 'center', backdropFilter: 'blur(8px)' } as any) : {})\n },\n cameraWrapper: {\n width: '100%', backgroundColor: '#FFFFFF', overflow: 'hidden',\n ...(Platform.OS === 'web' ? ({ maxWidth: 500, height: 700, maxHeight: '90vh', borderRadius: 24, shadowColor: '#000', shadowOffset: { width: 0, height: 20 }, shadowOpacity: 0.25, shadowRadius: 35, elevation: 24, } as any) : { flex: 1, })\n },\n headerContainer: {\n flexDirection: 'row', alignItems: 'center', justifyContent: 'space-between', paddingHorizontal: 24, paddingVertical: 18, backgroundColor: '#FFFFFF', borderBottomWidth: 1, borderBottomColor: '#F1F5F9', zIndex: 10,\n ...(Platform.OS !== 'web' ? { display: 'none' } : {})\n },\n headerTitle: { fontSize: 18, fontWeight: '700', color: '#0F172A', },\n stepBadge: { backgroundColor: '#F1F5F9', paddingHorizontal: 12, paddingVertical: 6, borderRadius: 20, },\n stepText: { fontSize: 13, fontWeight: '600', color: '#64748B', },\n cameraFeedContainer: { flex: 1, position: 'relative', backgroundColor: '#000', },\n camera: { flex: 1, },\n refreshButton: {\n position: 'absolute', bottom: 100, alignSelf: 'center', backgroundColor: 'rgba(0,0,0,0.6)', paddingVertical: 12, paddingHorizontal: 24, borderRadius: 24, zIndex: 500\n },\n refreshButtonText: { color: 'white', fontWeight: 'bold', fontSize: 16 },\n previewContainer: {\n width: '100%', backgroundColor: 'white', borderRadius: 12, paddingVertical: 24, paddingHorizontal: 20, shadowColor: '#000', shadowOffset: { width: 0, height: 4 }, shadowOpacity: 0.1, shadowRadius: 12, elevation: 8,\n ...(Platform.OS === 'web' ? { alignSelf: 'center', maxWidth: 600 } : { margin: 10, width: '95%' })\n },\n previewItemContainer: { flexGrow: 1, },\n title: { fontSize: 24, fontWeight: 'bold', color: '#333', marginBottom: 8, textAlign: 'center' },\n description: { fontSize: 16, color: '#666', textAlign: 'center', marginBottom: 24, lineHeight: 22 },\n sideContainer: { marginBottom: 24 },\n sideTitle: { fontSize: 25, fontWeight: 'bold', color: '#000', marginBottom: 12, textAlign: 'center' },\n imagePreviewWrapper: { width: '100%', height: 220, borderRadius: 12, padding: 1, overflow: 'hidden', shadowColor: '#000', shadowOffset: { width: 0, height: 4 }, shadowOpacity: 0.18, shadowRadius: 8, elevation: 8, backgroundColor: '#f0f0f0' },\n previewImage: { width: '100%', height: '100%', borderRadius: 12, resizeMode: 'cover' },\n floatingErrorBanner: {\n position: 'absolute', bottom: 30, left: 24, right: 24, backgroundColor: '#FEF2F2', borderWidth: 1, borderColor: '#FCA5A5', paddingVertical: 12, paddingHorizontal: 16, borderRadius: 12, alignItems: 'center', justifyContent: 'center', shadowColor: '#DC2626', shadowOffset: { width: 0, height: 4 }, shadowOpacity: 0.1, shadowRadius: 8, elevation: 8, zIndex: 100\n },\n floatingErrorText: { color: '#991B1B', fontSize: 14, fontWeight: '700', textAlign: 'center' },\n processingOverlay: { flex: 1, backgroundColor: 'rgba(0, 0, 0, 0.6)', justifyContent: 'center', alignItems: 'center', zIndex: 9999 },\n processingText: { color: '#FFF', fontSize: 18, fontWeight: 'bold', marginTop: 16, textAlign: 'center' },\n warningBanner: { backgroundColor: '#FF9500', padding: 12, borderRadius: 8, width: '100%', shadowColor: '#000', shadowOffset: { width: 0, height: 2 }, shadowOpacity: 0.2, shadowRadius: 4, elevation: 4 },\n warningText: { color: 'white', fontWeight: 'bold', textAlign: 'center', fontSize: 16 },\n errorText: { color: '#dc2626', fontSize: 14, marginTop: 8, textAlign: 'center' },\n topAnalyzingPillContainer: { position: 'absolute', top: Platform.OS === 'android' ? 60 : 50, left: 0, right: 0, alignItems: 'center', zIndex: 100 },\n topAnalyzingPill: { flexDirection: 'row', alignItems: 'center', backgroundColor: 'rgba(0,0,0,0.6)', paddingVertical: 8, paddingHorizontal: 16, borderRadius: 20, gap: 8 },\n analyzingPillText: { color: 'white', fontSize: 14, fontWeight: 'bold' },\n escapeHatchContainer: {\n position: 'absolute',\n bottom: 40,\n left: 0,\n right: 0,\n alignItems: 'center',\n justifyContent: 'center',\n zIndex: 99999, // Guarantees it is the top-most element\n },\n fallbackRefreshButton: {\n backgroundColor: 'rgba(0, 0, 0, 0.8)', // Darker so it's visible on white or black\n borderWidth: 1,\n borderColor: 'rgba(255, 255, 255, 0.5)',\n paddingVertical: 12,\n paddingHorizontal: 24,\n borderRadius: 24,\n shadowColor: '#000',\n shadowOffset: { width: 0, height: 4 },\n shadowOpacity: 0.3,\n shadowRadius: 5,\n elevation: 8,\n },\n fallbackRefreshText: {\n color: '#FFFFFF',\n fontWeight: 'bold',\n fontSize: 16,\n },\n absoluteFillObject: {\n position: 'absolute',\n top: 0,\n left: 0,\n right: 0,\n bottom: 0,\n },\n});"]}
1
+ {"version":3,"file":"IDCardCapture.js","sourceRoot":"","sources":["../../../../src/components/KYCElements/IDCardCapture.tsx"],"names":[],"mappings":"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","sourcesContent":["import React, { useEffect, useMemo, useState } from 'react';\nimport { View, Text, StyleSheet, Image, ScrollView, Platform, ActivityIndicator, TouchableOpacity } from 'react-native';\nimport { showAlert } from '../../utils/platformAlert';\nimport { EnhancedCameraView } from '../EnhancedCameraView';\nimport { TemplateComponent, LocalizedText, GovernmentDocumentType, ISilentCaptureResult, IBbox, GovernmentDocumentTypeShorted, GovernmentDocumentTypeBackend } from '../../types/KYC.types';\nimport IdCardOverlay from '../OverLay/IdCard';\nimport { useTemplateKYCFlowContext } from '../../hooks/useTemplateKYCFlow';\nimport { useI18n } from '../../hooks/useI18n';\nimport { Button } from '../ui/Button';\nimport { removeDuplicates } from '../../utils/remove-duplicate';\nimport { backVerification, checkTemplateType, frontVerification } from '../../modules/api/CardAuthentification';\nimport { getDocumentTypeInfo } from '../../utils/get-document-type-info';\nimport pathToBase64 from '../../utils/pathToBase64';\nimport { cropByObb, cropImageWithBBoxWithTolerance, getObbConfidence, OBB_CONFIDENCE_THRESHOLD } from '../../utils/cropByObb';\nimport REGION_MAPPING from '../../config/region_mapping.json';\n\nconst ISO_TO_COUNTRY_NAME: Record<string, string> = { 'KE': 'Kenya', 'CM': 'Cameroon', 'NG': 'Nigeria', 'CA': 'Canada', 'FR': 'France', 'GH': 'Ghana', 'ZA': 'South Africa', 'GB': 'Britain', 'CI': 'Ivory Coast', 'SN': 'Senegal', 'TG': 'Togo', 'ML': 'Mali' };\n\ninterface IIDCardPayload { dir: string; file: string; mrz: string; templatePath?: string; }\ninterface IDCardCaptureProps { component: TemplateComponent; value?: Record<string, IIDCardPayload>; onValueChange: (value: Record<string, IIDCardPayload | string>) => void; error?: string; language?: string; currentSide?: string; }\n\nexport const IDCardCapture: React.FC<IDCardCaptureProps> = ({ component, value = {}, onValueChange, error, language = 'en' }) => {\n const { t, locale } = useI18n();\n const [showCamera, setShowCamera] = useState(false);\n const [capturedImages, setCapturedImages] = useState<Record<string, IIDCardPayload>>(value || {});\n const [currentSide, setCurrentSide] = useState<'front' | 'back'>('front');\n const [bboxBySide, setBboxBySide] = useState<Record<string, IBbox>>({});\n const [silentCaptureResult, setSilentCaptureResult] = useState<ISilentCaptureResult>({ success: false, isAnalyzing: false });\n const [isProcessingCapture, setIsProcessingCapture] = useState(false);\n const [processingImagePath, setProcessingImagePath] = useState<string | null>(null);\n \n const [cameraKey, setCameraKey] = useState(0);\n const [isRebootingCamera, setIsRebootingCamera] = useState(false);\n // Web specific state\n const [cameraType, setCameraType] = useState<'back' | 'front'>('back');\n\n const documentTypeMapping: Record<string, GovernmentDocumentType> = { 'nationalId': 'national_id', 'passport': 'passport', 'driversLicense': 'drivers_licence', 'residencePermit': 'permanent_residence', 'healthInsuranceCard': 'health_insurance_card', };\n const { actions, state, env } = useTemplateKYCFlowContext();\n\n const getLocalizedText = (text: LocalizedText | Record<string, LocalizedText>): string => {\n if (text && typeof text[currentSide] === 'object' && text[currentSide][locale]) return text[currentSide][locale] || '';\n return \"\";\n };\n\n const countrySelectionData = useMemo(() => {\n const countrySelectionComponent = state.template.components.find(c => c.type === 'country_selection');\n return countrySelectionComponent ? state.componentData[countrySelectionComponent.id] : null;\n }, [state.template.components, state.componentData]);\n\n const selectedDocumentType = useMemo<{ type: GovernmentDocumentType; region: string } | null>(() => {\n if (!countrySelectionData?.documentType) return null;\n const backendDocType = countrySelectionData.documentType;\n const mappedType = documentTypeMapping[backendDocType] || backendDocType as GovernmentDocumentType;\n return { type: mappedType, region: countrySelectionData.region || 'root' };\n }, [countrySelectionData, documentTypeMapping]);\n\n const countryData = useMemo(() => countrySelectionData, [countrySelectionData]);\n\n const refreshCamera = () => {\n setIsRebootingCamera(true);\n setTimeout(() => {\n setCameraKey(prev => prev + 1);\n setIsRebootingCamera(false);\n }, 500);\n };\n\n const toggleCameraLens = () => {\n setCameraType(prev => prev === 'back' ? 'front' : 'back');\n refreshCamera();\n };\n\n useEffect(() => {\n if (value && Object.keys(value).length > 0) {\n if (JSON.stringify(value) !== JSON.stringify(capturedImages)) {\n const updatedImages = value as Record<string, IIDCardPayload>;\n setCapturedImages(updatedImages);\n const currentImageData = updatedImages[currentSide];\n if (currentImageData?.dir) {\n setSilentCaptureResult(prev => ({\n ...prev, path: currentImageData.dir, success: true, isAnalyzing: false, mrz: currentImageData.mrz || '', templatePath: currentImageData.templatePath || '',\n }));\n }\n }\n }\n }, [value, currentSide]);\n\n const cameraConfig = useMemo(() => {\n const instructions = selectedDocumentType ? (locale === 'en' ? getDocumentTypeInfo(selectedDocumentType.type).instructions.en : getDocumentTypeInfo(selectedDocumentType.type).instructions.fr) : getLocalizedText(component.instructions as Record<string, LocalizedText>);\n return {\n cameraType: Platform.OS === 'web' ? cameraType : 'back', // Keep strictly 'back' on mobile\n flashMode: 'auto' as const,\n overlay: { guideText: instructions, bbox: { xMin: 15, yMin: 20, xMax: 85, yMax: 70, borderColor: '#2DBD60', borderWidth: 3, cornerRadius: 8 } }\n };\n }, [selectedDocumentType, locale, component.instructions, cameraType]);\n\n const retakePicture = (sideToRetake: 'front' | 'back') => {\n setIsProcessingCapture(false);\n setProcessingImagePath(null);\n setSilentCaptureResult({ path: '', success: false, isAnalyzing: false, error: '', templatePath: '', mrz: '', bbox: undefined });\n setShowCamera(true);\n refreshCamera();\n actions.showCustomStepper(false);\n setCapturedImages((prev) => { const newState = { ...prev }; delete newState[sideToRetake]; return newState; });\n if (value) { const newValue = { ...value }; delete newValue[sideToRetake]; onValueChange(newValue); }\n };\n\n const getCurrentSideVerification = (currentSide: string, countryKey: string) => {\n const rawDocType = countrySelectionData?.documentType;\n if (!rawDocType || !countryKey) { return { authMethod: [], mrzTypes: [], regionMapping: null, key: 'root' }; }\n const rawCountryName = ISO_TO_COUNTRY_NAME[countryData?.code || ''] || countryData?.code || countryKey;\n const baseMapping = (REGION_MAPPING as any).regionMapping || REGION_MAPPING;\n let countryMapping = baseMapping[rawCountryName];\n if (!countryMapping) {\n const foundKey = Object.keys(baseMapping).find(k => k.toLowerCase() === rawCountryName.toLowerCase() || k.toLowerCase() === countryKey.toLowerCase());\n if (foundKey) countryMapping = baseMapping[foundKey];\n }\n if (!countryMapping) { return { authMethod: [], mrzTypes: [], regionMapping: null, key: 'root' }; }\n const regionMapping = countryMapping[rawDocType];\n if (!regionMapping) { return { authMethod: [], mrzTypes: [], regionMapping: null, key: 'root' }; }\n const authMethod: string[] = [];\n const mrzTypes: string[] = [];\n const key = countrySelectionData.region?.trim()?.length > 0 ? countrySelectionData.region.trim() : 'root';\n if (regionMapping?.[key] && Array.isArray(regionMapping[key])) {\n regionMapping[key].forEach((item: any) => {\n if (item[currentSide]) {\n authMethod.push(item[currentSide]);\n if (item?.mrz_type) mrzTypes.push(item?.mrz_type);\n }\n });\n }\n return { authMethod: removeDuplicates(authMethod), mrzTypes: removeDuplicates(mrzTypes), regionMapping, key };\n }\n\n const getCorrespondingMrzType = (templatePath: string, mapping: any, selectedDocumentType: string = \"root\") => {\n if (!mapping || !mapping[selectedDocumentType]) return null;\n const fileName = templatePath.split(\"/\").pop()?.replace(\".jpg\", \"\").replace(\".png\", \"\");\n if (!fileName) return null;\n const pyName = `${fileName}.py`;\n const found = mapping[selectedDocumentType].find((item: any) => item.py_file === pyName);\n return found?.mrz_type || null;\n }\n\n const getCorrespondingAuthMethod = (templatePath: string, mapping: any, selectedDocumentType: string = \"root\", side: 'front' | 'back') => {\n if (!mapping || !mapping[selectedDocumentType]) return null;\n const fileName = templatePath.split(\"/\").pop()?.replace(\".jpg\", \"\").replace(\".png\", \"\");\n if (!fileName) return null;\n const pyName = `${fileName}.py`;\n const found = mapping[selectedDocumentType].find((item: any) => item.py_file === pyName);\n return found?.[side] || null;\n }\n\n const autoCapture = async (capturePath: string, verified: ISilentCaptureResult) => {\n if (isProcessingCapture) return;\n setIsProcessingCapture(true);\n setProcessingImagePath(capturePath);\n try {\n let imagePathForUpload = capturePath;\n if (verified.bbox) {\n try {\n imagePathForUpload = await cropImageWithBBoxWithTolerance(capturePath, verified.bbox, 0.15);\n } catch {\n imagePathForUpload = capturePath;\n }\n }\n const base64 = await pathToBase64(imagePathForUpload);\n const newImages = {\n ...capturedImages,\n [currentSide]: { dir: imagePathForUpload, file: base64, mrz: verified.mrz || \"\", templatePath: verified.templatePath },\n };\n setCapturedImages(newImages);\n if (verified.country && verified.documentType) {\n onValueChange({\n ...newImages,\n country: verified.country,\n documentType: GovernmentDocumentTypeBackend[verified.documentType as keyof typeof GovernmentDocumentTypeBackend] || '',\n });\n }\n setTimeout(() => {\n setShowCamera(false);\n actions.showCustomStepper(true);\n setSilentCaptureResult(prev => ({ ...prev, isAnalyzing: false }));\n setIsProcessingCapture(false);\n setProcessingImagePath(null);\n }, 600);\n } catch (e: any) {\n console.error(\"Backend Error:\", e);\n const friendlyError = state.currentLanguage === 'en' ? 'Unable to process document. Please try again.' : 'Impossible de traiter le document. Veuillez réessayer.';\n showAlert('Error', friendlyError);\n setSilentCaptureResult(prev => ({ ...prev, isAnalyzing: false, success: false }));\n setIsProcessingCapture(false);\n setProcessingImagePath(null);\n }\n };\n\n const handleSilentCapture = async (result: { success: boolean; path?: string; error?: string }) => {\n if (silentCaptureResult.isAnalyzing || isProcessingCapture) return;\n if (result.success && result.path) {\n setSilentCaptureResult((prev) => ({ ...prev, isAnalyzing: true, success: false, error: '' }));\n let templatePath = capturedImages[currentSide]?.templatePath || '';\n let templateBbox: IBbox | undefined;\n let templateResponse: any;\n if (!selectedDocumentType) {\n setSilentCaptureResult((prev) => ({ ...prev, isAnalyzing: false, success: false, error: 'Document type not selected' }));\n return;\n }\n try {\n if (!templatePath) {\n const templateType = await checkTemplateType({ path: result.path || '', docType: selectedDocumentType?.type as GovernmentDocumentType, docRegion: countryData?.code || \"\", postfix: currentSide }, env);\n templateResponse = templateType;\n if (templateType.template_path) templatePath = templateType.template_path;\n if (templateType.card_obb) {\n const obbConfidence = getObbConfidence((templateType as any).card_obb);\n if (obbConfidence !== null && obbConfidence < OBB_CONFIDENCE_THRESHOLD) {\n setSilentCaptureResult((prev) => ({ ...prev, isAnalyzing: false, success: false, error: t('kyc.idCardCapture.cardNotFullyInFrame') }));\n return;\n }\n try {\n const crop = await cropByObb(result.path, (templateType as any).card_obb);\n templateBbox = crop.bbox;\n } catch { }\n }\n }\n const extractedCountryKey = templatePath ? templatePath.split('/')[0] : (ISO_TO_COUNTRY_NAME[countryData?.code || ''] || 'root');\n const regionMappings = getCurrentSideVerification(currentSide, extractedCountryKey);\n let verificationRes: any;\n if (currentSide === 'front') {\n const matchedAuthMethod = getCorrespondingAuthMethod(templatePath, regionMappings.regionMapping, regionMappings.key || '', 'front');\n const mrzType = getCorrespondingMrzType(templatePath, regionMappings.regionMapping, regionMappings.key || '') || 'TD1';\n verificationRes = await frontVerification({ path: result.path, regionMapping: { authMethod: matchedAuthMethod ? [matchedAuthMethod] : regionMappings.authMethod, mrzTypes: regionMappings.mrzTypes }, selectedDocumentType: GovernmentDocumentTypeShorted[selectedDocumentType?.type as keyof typeof GovernmentDocumentTypeShorted] || '', code: countryData?.code || '', currentSide, templatePath, mrzType }, env);\n } else {\n let matchedBackAuthMethod = getCorrespondingAuthMethod(templatePath, regionMappings.regionMapping, regionMappings.key || '', 'back');\n if (!matchedBackAuthMethod && currentSide === 'back') {\n matchedBackAuthMethod = 'MRZ';\n }\n const backMrzType = getCorrespondingMrzType(templatePath, regionMappings.regionMapping, regionMappings.key || '') || 'TD1';\n verificationRes = await backVerification({ path: result.path, regionMapping: { authMethod: matchedBackAuthMethod ? [matchedBackAuthMethod] : regionMappings.authMethod, mrzTypes: regionMappings.mrzTypes }, selectedDocumentType: GovernmentDocumentTypeShorted[selectedDocumentType.type as keyof typeof GovernmentDocumentTypeShorted] || '', code: countryData?.code || '', currentSide, templatePath, mrzType: backMrzType, templateResponse }, env);\n }\n const bbox = verificationRes?.bbox || templateBbox;\n const mrz = verificationRes?.mrz ? JSON.stringify(verificationRes.mrz) : \"\";\n const verifiedResult: ISilentCaptureResult = { path: result.path, templatePath, bbox, success: true, mrz, isAnalyzing: false, country: countryData?.code, documentType: selectedDocumentType.type };\n setSilentCaptureResult(verifiedResult);\n if (bbox) setBboxBySide(prev => ({ ...prev, [currentSide]: bbox }));\n await autoCapture(result.path, verifiedResult);\n } catch (error: any) {\n console.error(\"Backend Error:\", error); \n \n const isCardNotFullyInFrame = error?.message === 'CARD_NOT_FULLY_IN_FRAME' || error?.message?.includes('entirement');\n \n const errorMessage = isCardNotFullyInFrame \n ? t('kyc.idCardCapture.cardNotFullyInFrame') \n : (t('errors.genericVerificationFailed') || 'Verification failed. Please ensure the document is clear and try again.');\n \n setSilentCaptureResult(prev => ({ ...prev, isAnalyzing: false, success: false, error: errorMessage }));\n }\n }\n };\n\n const handleError = (event: { message: string }) => {\n showAlert('Erreur', event.message);\n setShowCamera(false);\n setIsProcessingCapture(false);\n };\n\n useEffect(() => {\n actions.showCustomStepper(!showCamera);\n }, [showCamera]);\n\n if (!countrySelectionData || !selectedDocumentType) {\n return (\n <View style={styles.root}>\n <View style={styles.previewContainer}>\n <Text style={styles.title}>{getLocalizedText(component.labels)}</Text>\n <Text style={styles.description}>\n {state.currentLanguage === \"en\" ? \"Please complete the country and document selection first.\" : \"Veuillez d'abord compléter la sélection du pays et du document.\"}\n </Text>\n </View>\n </View>\n );\n }\n\n // --- CAMERA RENDER ---\n if (showCamera) {\n const isBusy = isProcessingCapture;\n\n if (isRebootingCamera) {\n return (\n <View style={[styles.root, { justifyContent: 'center', alignItems: 'center', backgroundColor: '#000' }]}>\n <ActivityIndicator size=\"large\" color=\"#2DBD60\" />\n <Text style={{ color: 'white', marginTop: 20, fontSize: 16 }}>Initializing Camera...</Text>\n </View>\n );\n }\n\n return (\n <View style={styles.root}>\n <View style={[styles.cameraWrapper, { flex: 1 }]}>\n \n <View style={styles.headerContainer}>\n <Text style={styles.headerTitle}>\n {selectedDocumentType ? (locale === 'en' ? getDocumentTypeInfo(selectedDocumentType.type).name.en : getDocumentTypeInfo(selectedDocumentType.type).name.fr) : ''}\n </Text>\n <View style={styles.stepBadge}>\n <Text style={styles.stepText}>\n {t('kyc.idCardCapture.captureTitle', { side: currentSide === 'front' ? locale === 'en' ? 'Front' : 'Recto' : locale === 'en' ? 'Back' : 'Verso' })}\n </Text>\n </View>\n </View>\n \n <View style={[styles.cameraFeedContainer, { flex: 1, backgroundColor: '#000' }]}>\n \n {/* WEB ONLY: Flip Camera Top Button */}\n {Platform.OS === 'web' && (\n <View style={styles.webTopControls}>\n <TouchableOpacity style={styles.webFlipButton} onPress={toggleCameraLens}>\n <Text style={styles.webFlipText}>🔄 Flip Lens</Text>\n </TouchableOpacity>\n </View>\n )}\n\n <EnhancedCameraView\n key={`${currentSide}-${cameraKey}`}\n showCamera={true}\n isProcessing={isBusy}\n cameraType={cameraConfig.cameraType}\n style={StyleSheet.absoluteFillObject}\n onError={handleError}\n onSilentCapture={handleSilentCapture}\n silentCaptureResult={silentCaptureResult}\n overlayComponent={\n <>\n <IdCardOverlay\n xMin={cameraConfig.overlay.bbox.xMin} yMin={cameraConfig.overlay.bbox.yMin} xMax={cameraConfig.overlay.bbox.xMax} yMax={cameraConfig.overlay.bbox.yMax}\n instructions={cameraConfig.overlay.guideText}\n cornerOpacity={cameraConfig.overlay.bbox.cornerRadius || 0 as number}\n isSuccess={silentCaptureResult.success}\n language={state.currentLanguage}\n stepperProps={{\n back: () => {\n if (currentSide === 'back') {\n setCurrentSide('front');\n setShowCamera(false);\n setIsProcessingCapture(false);\n setProcessingImagePath(null);\n if (capturedImages['front']?.dir) {\n const frontImage = capturedImages['front'];\n setSilentCaptureResult((prev) => ({ ...prev, path: frontImage.dir, success: true, isAnalyzing: false, error: '', mrz: frontImage.mrz || '', templatePath: frontImage.templatePath || '', bbox: bboxBySide['front'] }));\n } else { setSilentCaptureResult((prev) => ({ ...prev, path: '', success: false, isAnalyzing: false, error: '', templatePath: '' })); }\n } else { actions.previousComponent(); }\n },\n selectedDocumentType: selectedDocumentType ? (locale === 'en' ? getDocumentTypeInfo(selectedDocumentType.type).name.en : getDocumentTypeInfo(selectedDocumentType.type).name.fr) : '',\n step: state.currentComponentIndex + 1, totalSteps: state.template.components.length, side: currentSide,\n }}\n />\n </>\n }\n />\n\n {!isBusy && silentCaptureResult.isAnalyzing && (\n <View style={styles.topAnalyzingPillContainer}>\n <View style={styles.topAnalyzingPill}>\n <ActivityIndicator size=\"small\" color=\"white\" />\n <Text style={styles.analyzingPillText}>\n {state.currentLanguage === 'en' ? 'Scanning...' : 'Analyse...'}\n </Text>\n </View>\n </View>\n )}\n\n {isBusy && (\n <View style={[StyleSheet.absoluteFillObject, { zIndex: 9999 }]}>\n {processingImagePath && (\n <Image\n source={{ uri: processingImagePath.startsWith('file://') ? processingImagePath : `file://${processingImagePath}` }}\n style={StyleSheet.absoluteFillObject}\n resizeMode=\"cover\"\n />\n )}\n <View style={styles.processingOverlay}>\n <ActivityIndicator size=\"large\" color=\"#2DBD60\" />\n <Text style={styles.processingText}>\n {state.currentLanguage === 'en' ? 'Perfect!\\nProcessing Document...' : 'Parfait!\\nTraitement du document...'}\n </Text>\n </View>\n </View>\n )}\n\n {/* 🚨 THE ESCAPE HATCH: Branching UI for Web vs Mobile */}\n {!isBusy && Platform.OS === 'web' ? (\n <View style={styles.webBottomControlBar}>\n {silentCaptureResult.error ? (\n <View style={styles.floatingErrorBanner}>\n <Text style={styles.floatingErrorText}>⚠️ {silentCaptureResult.error}</Text>\n </View>\n ) : <View style={{ height: 10 }} />}\n\n <View style={styles.webActionButtonsRow}>\n <TouchableOpacity style={styles.webSecondaryButton} onPress={() => setShowCamera(false)}>\n <Text style={styles.webSecondaryButtonText}>Cancel</Text>\n </TouchableOpacity>\n <TouchableOpacity style={styles.webPrimaryButton} onPress={refreshCamera}>\n <Text style={styles.webPrimaryButtonText}>↻ Refresh Camera</Text>\n </TouchableOpacity>\n </View>\n </View>\n ) : !isBusy ? (\n <View style={styles.escapeHatchContainer}>\n <TouchableOpacity style={styles.fallbackRefreshButton} onPress={refreshCamera}>\n <Text style={styles.fallbackRefreshText}>↻ Refresh Camera</Text>\n </TouchableOpacity>\n <TouchableOpacity \n style={[styles.fallbackRefreshButton, { marginTop: 15, backgroundColor: 'rgba(220, 38, 38, 0.8)', borderColor: '#DC2626' }]} \n onPress={() => setShowCamera(false)}\n >\n <Text style={styles.fallbackRefreshText}>Cancel / Go Back</Text>\n </TouchableOpacity>\n </View>\n ) : null}\n\n {silentCaptureResult.error && !isBusy && Platform.OS !== 'web' ? (\n <View style={[styles.floatingErrorBanner, { zIndex: 10000 }]}>\n <Text style={styles.floatingErrorText}>⚠️ {silentCaptureResult.error}</Text>\n </View>\n ) : null}\n\n </View>\n </View>\n </View>\n );\n }\n\n // --- PREVIEW RENDER ---\n return (\n <View style={styles.root}>\n <View style={styles.previewContainer}>\n <ScrollView style={styles.previewItemContainer} showsVerticalScrollIndicator={false}>\n <View key={currentSide} style={styles.sideContainer}>\n <Text style={styles.sideTitle}>\n {t('kyc.idCardCapture.captureTitle', { side: currentSide === 'front' ? locale === 'en' ? 'Front' : 'Recto' : locale === 'en' ? 'Back' : 'Verso' })}\n </Text>\n <Text style={{ fontSize: 14, color: '#666', textAlign: 'center', marginBottom: 16, lineHeight: 22 }}>\n {getLocalizedText(component.instructions)}\n </Text>\n \n <View style={{ alignItems: 'center', justifyContent: 'center', flexDirection: \"column\", gap: 16 }}>\n {silentCaptureResult?.error === 'TOO_FAR_AWAY' && (\n <View style={styles.warningBanner}>\n <Text style={styles.warningText}>\n {state.currentLanguage === \"en\" ? \"Move the document closer to the camera and place it on a flat surface.\" : \"Veuillez rapprocher le document de la caméra et le poser à plat.\"}\n </Text>\n </View>\n )}\n \n {/* 🚨 PREVIEW CONTAINER WITH PLATFORM OVERRIDES */}\n <View style={styles.imagePreviewWrapper}>\n {capturedImages[currentSide]?.dir ? (\n <Image source={{ uri: capturedImages[currentSide].dir }} style={styles.previewImage} />\n ) : silentCaptureResult.path ? (\n <Image source={{ uri: silentCaptureResult.path }} style={styles.previewImage} />\n ) : null}\n </View>\n\n {!capturedImages[currentSide]?.dir && (\n <Button\n title={state.currentLanguage === \"en\" ? \"Start Scanning\" : \"Commencer la numérisation\"}\n onPress={() => { setShowCamera(true); refreshCamera(); actions.showCustomStepper(false); }}\n variant=\"primary\" size=\"large\" fullWidth\n />\n )}\n {capturedImages[currentSide]?.dir && (\n <>\n <Button title={t('kyc.idCardCapture.retakeButton')} onPress={() => retakePicture(currentSide)} variant=\"outline\" size=\"medium\" fullWidth />\n <Button title={t('common.next')} onPress={() => {\n if (!selectedDocumentType) { showAlert('Error', 'Document type not selected'); return; }\n if (currentSide === 'back' || selectedDocumentType.type === 'passport') {\n actions.nextComponent();\n } else {\n setShowCamera(true);\n refreshCamera();\n setCurrentSide('back');\n setSilentCaptureResult({ success: false, isAnalyzing: false, path: '', error: '', templatePath: undefined });\n setIsProcessingCapture(false);\n setProcessingImagePath(null);\n }\n }} variant=\"primary\" size=\"large\" fullWidth />\n </>\n )}\n </View>\n </View>\n </ScrollView>\n </View>\n </View>\n );\n};\n\nconst styles = StyleSheet.create({\n root: {\n flex: 1, width: '100%', backgroundColor: 'transparent', alignSelf: 'center',\n ...Platform.select({\n web: { minHeight: '85vh', justifyContent: 'center', alignItems: 'center', backdropFilter: 'blur(8px)' } as any,\n })\n },\n cameraWrapper: {\n width: '100%', backgroundColor: '#000000', overflow: 'hidden',\n ...Platform.select({\n web: { maxWidth: 550, height: '80vh', minHeight: 600, borderRadius: 24, shadowColor: '#000', shadowOffset: { width: 0, height: 20 }, shadowOpacity: 0.25, shadowRadius: 35, elevation: 24 } as any,\n default: { flex: 1 }\n })\n },\n headerContainer: {\n flexDirection: 'row', alignItems: 'center', justifyContent: 'space-between', paddingHorizontal: 24, paddingVertical: 18, backgroundColor: '#FFFFFF', borderBottomWidth: 1, borderBottomColor: '#F1F5F9', zIndex: 10,\n ...Platform.select({ web: { display: 'flex' }, default: { display: 'none' } })\n },\n headerTitle: { fontSize: 18, fontWeight: '700', color: '#0F172A', },\n stepBadge: { backgroundColor: '#F1F5F9', paddingHorizontal: 12, paddingVertical: 6, borderRadius: 20, },\n stepText: { fontSize: 13, fontWeight: '600', color: '#64748B', },\n cameraFeedContainer: { flex: 1, position: 'relative', backgroundColor: '#000', },\n camera: { flex: 1, },\n\n // MOBILE: Escape Hatch layout\n escapeHatchContainer: { position: 'absolute', bottom: 40, left: 0, right: 0, alignItems: 'center', justifyContent: 'center', zIndex: 99999 },\n fallbackRefreshButton: { backgroundColor: 'rgba(0, 0, 0, 0.8)', borderWidth: 1, borderColor: 'rgba(255, 255, 255, 0.5)', paddingVertical: 12, paddingHorizontal: 24, borderRadius: 24, shadowColor: '#000', shadowOffset: { width: 0, height: 4 }, shadowOpacity: 0.3, shadowRadius: 5, elevation: 8 },\n fallbackRefreshText: { color: '#FFFFFF', fontWeight: 'bold', fontSize: 16 },\n\n // WEB: Control Bar layout\n webBottomControlBar: { position: 'absolute', bottom: 0, left: 0, right: 0, paddingHorizontal: 20, paddingBottom: 20, paddingTop: 20, backgroundColor: 'rgba(0,0,0,0.6)', zIndex: 99999 },\n webActionButtonsRow: { flexDirection: 'row', justifyContent: 'space-between', gap: 12, marginTop: 12 },\n webPrimaryButton: { flex: 1, backgroundColor: '#2DBD60', paddingVertical: 14, borderRadius: 12, alignItems: 'center' },\n webPrimaryButtonText: { color: 'white', fontWeight: 'bold', fontSize: 16 },\n webSecondaryButton: { flex: 1, backgroundColor: 'rgba(255,255,255,0.2)', borderWidth: 1, borderColor: 'rgba(255,255,255,0.4)', paddingVertical: 14, borderRadius: 12, alignItems: 'center' },\n webSecondaryButtonText: { color: 'white', fontWeight: 'bold', fontSize: 16 },\n \n // WEB: Flip Controls\n webTopControls: { position: 'absolute', top: 20, right: 20, zIndex: 9999 },\n webFlipButton: { backgroundColor: 'rgba(0,0,0,0.5)', paddingHorizontal: 16, paddingVertical: 10, borderRadius: 20, borderWidth: 1, borderColor: 'rgba(255,255,255,0.3)' },\n webFlipText: { color: 'white', fontWeight: 'bold', fontSize: 14 },\n\n previewContainer: {\n width: '100%', backgroundColor: 'white', borderRadius: 12, paddingVertical: 24, paddingHorizontal: 20, shadowColor: '#000', shadowOffset: { width: 0, height: 4 }, shadowOpacity: 0.1, shadowRadius: 12, elevation: 8,\n ...Platform.select({ web: { alignSelf: 'center', maxWidth: 600 }, default: { margin: 10, width: '95%' }})\n },\n previewItemContainer: { flexGrow: 1, },\n title: { fontSize: 24, fontWeight: 'bold', color: '#333', marginBottom: 8, textAlign: 'center' },\n description: { fontSize: 16, color: '#666', textAlign: 'center', marginBottom: 24, lineHeight: 22 },\n sideContainer: { marginBottom: 24 },\n sideTitle: { fontSize: 25, fontWeight: 'bold', color: '#000', marginBottom: 12, textAlign: 'center' },\n \n imagePreviewWrapper: { \n width: '100%', borderRadius: 12, padding: 1, overflow: 'hidden', shadowColor: '#000', shadowOffset: { width: 0, height: 4 }, shadowOpacity: 0.18, shadowRadius: 8, elevation: 8, backgroundColor: '#f0f0f0',\n ...Platform.select({\n web: { aspectRatio: 1.59, height: 'auto' } as any, // 🚨 Perfect ID ratio on web\n default: { height: 220 } // 🚨 Strict original height on mobile\n })\n },\n previewImage: { width: '100%', height: '100%', borderRadius: 12, resizeMode: 'cover' },\n\n floatingErrorBanner: {\n backgroundColor: '#FEF2F2', borderWidth: 1, borderColor: '#FCA5A5', paddingVertical: 12, paddingHorizontal: 16, borderRadius: 12, alignItems: 'center', justifyContent: 'center', width: '100%',\n ...Platform.select({ \n default: { position: 'absolute', top: Platform.OS === 'ios' ? 90 : 70, left: 24, right: 24, zIndex: 10000 } \n })\n },\n floatingErrorText: { color: '#991B1B', fontSize: 14, fontWeight: '700', textAlign: 'center' },\n processingOverlay: { flex: 1, backgroundColor: 'rgba(0, 0, 0, 0.6)', justifyContent: 'center', alignItems: 'center', zIndex: 9999 },\n processingText: { color: '#FFF', fontSize: 18, fontWeight: 'bold', marginTop: 16, textAlign: 'center' },\n warningBanner: { backgroundColor: '#FF9500', padding: 12, borderRadius: 8, width: '100%', shadowColor: '#000', shadowOffset: { width: 0, height: 2 }, shadowOpacity: 0.2, shadowRadius: 4, elevation: 4 },\n warningText: { color: 'white', fontWeight: 'bold', textAlign: 'center', fontSize: 16 },\n errorText: { color: '#dc2626', fontSize: 14, marginTop: 8, textAlign: 'center' },\n topAnalyzingPillContainer: { position: 'absolute', top: Platform.OS === 'android' ? 60 : 50, left: 0, right: 0, alignItems: 'center', zIndex: 100 },\n topAnalyzingPill: { flexDirection: 'row', alignItems: 'center', backgroundColor: 'rgba(0,0,0,0.6)', paddingVertical: 8, paddingHorizontal: 16, borderRadius: 20, gap: 8 },\n analyzingPillText: { color: 'white', fontSize: 14, fontWeight: 'bold' }\n});"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sanctum-key/react-native-sdk",
3
- "version": "1.0.13",
3
+ "version": "1.0.14",
4
4
  "description": "Sanctum Key React Native SDK",
5
5
  "main": "build/src/index.js",
6
6
  "types": "build/src/index.d.ts",
@@ -1,5 +1,5 @@
1
1
  import React, { useEffect, useMemo, useState } from 'react';
2
- import { View, Text, StyleSheet, Image, ScrollView, Platform, ActivityIndicator, TouchableOpacity } from 'react-native'; // 🚨 Added TouchableOpacity
2
+ import { View, Text, StyleSheet, Image, ScrollView, Platform, ActivityIndicator, TouchableOpacity } from 'react-native';
3
3
  import { showAlert } from '../../utils/platformAlert';
4
4
  import { EnhancedCameraView } from '../EnhancedCameraView';
5
5
  import { TemplateComponent, LocalizedText, GovernmentDocumentType, ISilentCaptureResult, IBbox, GovernmentDocumentTypeShorted, GovernmentDocumentTypeBackend } from '../../types/KYC.types';
@@ -29,8 +29,10 @@ export const IDCardCapture: React.FC<IDCardCaptureProps> = ({ component, value =
29
29
  const [isProcessingCapture, setIsProcessingCapture] = useState(false);
30
30
  const [processingImagePath, setProcessingImagePath] = useState<string | null>(null);
31
31
 
32
- // 🚨 ADDED: Key to force camera re-mount
33
32
  const [cameraKey, setCameraKey] = useState(0);
33
+ const [isRebootingCamera, setIsRebootingCamera] = useState(false);
34
+ // Web specific state
35
+ const [cameraType, setCameraType] = useState<'back' | 'front'>('back');
34
36
 
35
37
  const documentTypeMapping: Record<string, GovernmentDocumentType> = { 'nationalId': 'national_id', 'passport': 'passport', 'driversLicense': 'drivers_licence', 'residencePermit': 'permanent_residence', 'healthInsuranceCard': 'health_insurance_card', };
36
38
  const { actions, state, env } = useTemplateKYCFlowContext();
@@ -54,18 +56,18 @@ export const IDCardCapture: React.FC<IDCardCaptureProps> = ({ component, value =
54
56
 
55
57
  const countryData = useMemo(() => countrySelectionData, [countrySelectionData]);
56
58
 
57
- const [isRebootingCamera, setIsRebootingCamera] = useState(false);
58
-
59
59
  const refreshCamera = () => {
60
60
  setIsRebootingCamera(true);
61
-
62
61
  setTimeout(() => {
63
62
  setCameraKey(prev => prev + 1);
64
63
  setIsRebootingCamera(false);
65
64
  }, 500);
66
65
  };
67
66
 
68
-
67
+ const toggleCameraLens = () => {
68
+ setCameraType(prev => prev === 'back' ? 'front' : 'back');
69
+ refreshCamera();
70
+ };
69
71
 
70
72
  useEffect(() => {
71
73
  if (value && Object.keys(value).length > 0) {
@@ -85,16 +87,18 @@ export const IDCardCapture: React.FC<IDCardCaptureProps> = ({ component, value =
85
87
  const cameraConfig = useMemo(() => {
86
88
  const instructions = selectedDocumentType ? (locale === 'en' ? getDocumentTypeInfo(selectedDocumentType.type).instructions.en : getDocumentTypeInfo(selectedDocumentType.type).instructions.fr) : getLocalizedText(component.instructions as Record<string, LocalizedText>);
87
89
  return {
88
- cameraType: 'back' as const, flashMode: 'auto' as const,
90
+ cameraType: Platform.OS === 'web' ? cameraType : 'back', // Keep strictly 'back' on mobile
91
+ flashMode: 'auto' as const,
89
92
  overlay: { guideText: instructions, bbox: { xMin: 15, yMin: 20, xMax: 85, yMax: 70, borderColor: '#2DBD60', borderWidth: 3, cornerRadius: 8 } }
90
93
  };
91
- }, [selectedDocumentType, locale, component.instructions]);
94
+ }, [selectedDocumentType, locale, component.instructions, cameraType]);
92
95
 
93
96
  const retakePicture = (sideToRetake: 'front' | 'back') => {
94
97
  setIsProcessingCapture(false);
95
98
  setProcessingImagePath(null);
96
99
  setSilentCaptureResult({ path: '', success: false, isAnalyzing: false, error: '', templatePath: '', mrz: '', bbox: undefined });
97
100
  setShowCamera(true);
101
+ refreshCamera();
98
102
  actions.showCustomStepper(false);
99
103
  setCapturedImages((prev) => { const newState = { ...prev }; delete newState[sideToRetake]; return newState; });
100
104
  if (value) { const newValue = { ...value }; delete newValue[sideToRetake]; onValueChange(newValue); }
@@ -179,7 +183,9 @@ export const IDCardCapture: React.FC<IDCardCaptureProps> = ({ component, value =
179
183
  setProcessingImagePath(null);
180
184
  }, 600);
181
185
  } catch (e: any) {
182
- showAlert('Error', e?.message || 'Impossible de capturer la photo');
186
+ console.error("Backend Error:", e);
187
+ const friendlyError = state.currentLanguage === 'en' ? 'Unable to process document. Please try again.' : 'Impossible de traiter le document. Veuillez réessayer.';
188
+ showAlert('Error', friendlyError);
183
189
  setSilentCaptureResult(prev => ({ ...prev, isAnalyzing: false, success: false }));
184
190
  setIsProcessingCapture(false);
185
191
  setProcessingImagePath(null);
@@ -236,8 +242,14 @@ export const IDCardCapture: React.FC<IDCardCaptureProps> = ({ component, value =
236
242
  if (bbox) setBboxBySide(prev => ({ ...prev, [currentSide]: bbox }));
237
243
  await autoCapture(result.path, verifiedResult);
238
244
  } catch (error: any) {
245
+ console.error("Backend Error:", error);
246
+
239
247
  const isCardNotFullyInFrame = error?.message === 'CARD_NOT_FULLY_IN_FRAME' || error?.message?.includes('entirement');
240
- const errorMessage = isCardNotFullyInFrame ? t('kyc.idCardCapture.cardNotFullyInFrame') : (error?.message || 'Erreur de détection');
248
+
249
+ const errorMessage = isCardNotFullyInFrame
250
+ ? t('kyc.idCardCapture.cardNotFullyInFrame')
251
+ : (t('errors.genericVerificationFailed') || 'Verification failed. Please ensure the document is clear and try again.');
252
+
241
253
  setSilentCaptureResult(prev => ({ ...prev, isAnalyzing: false, success: false, error: errorMessage }));
242
254
  }
243
255
  }
@@ -266,134 +278,157 @@ export const IDCardCapture: React.FC<IDCardCaptureProps> = ({ component, value =
266
278
  );
267
279
  }
268
280
 
281
+ // --- CAMERA RENDER ---
282
+ if (showCamera) {
283
+ const isBusy = isProcessingCapture;
269
284
 
270
- // --- CAMERA RENDER ---
271
- if (showCamera) {
272
- const isBusy = isProcessingCapture;
285
+ if (isRebootingCamera) {
286
+ return (
287
+ <View style={[styles.root, { justifyContent: 'center', alignItems: 'center', backgroundColor: '#000' }]}>
288
+ <ActivityIndicator size="large" color="#2DBD60" />
289
+ <Text style={{ color: 'white', marginTop: 20, fontSize: 16 }}>Initializing Camera...</Text>
290
+ </View>
291
+ );
292
+ }
273
293
 
274
- if (isRebootingCamera) {
275
294
  return (
276
- <View style={[styles.root, { justifyContent: 'center', alignItems: 'center', backgroundColor: '#000' }]}>
277
- <ActivityIndicator size="large" color="#2DBD60" />
278
- <Text style={{ color: 'white', marginTop: 20, fontSize: 16 }}>Initializing Camera...</Text>
279
- </View>
280
- );
281
- }
282
-
283
- return (
284
- <View style={styles.root}>
285
- <View style={[styles.cameraWrapper, { flex: 1, minHeight: 400 }]}>
286
-
287
- <View style={styles.headerContainer}>
288
- <Text style={styles.headerTitle}>
289
- {selectedDocumentType ? (locale === 'en' ? getDocumentTypeInfo(selectedDocumentType.type).name.en : getDocumentTypeInfo(selectedDocumentType.type).name.fr) : ''}
290
- </Text>
291
- <View style={styles.stepBadge}>
292
- <Text style={styles.stepText}>
293
- {t('kyc.idCardCapture.captureTitle', { side: currentSide === 'front' ? locale === 'en' ? 'Front' : 'Recto' : locale === 'en' ? 'Back' : 'Verso' })}
295
+ <View style={styles.root}>
296
+ <View style={[styles.cameraWrapper, { flex: 1 }]}>
297
+
298
+ <View style={styles.headerContainer}>
299
+ <Text style={styles.headerTitle}>
300
+ {selectedDocumentType ? (locale === 'en' ? getDocumentTypeInfo(selectedDocumentType.type).name.en : getDocumentTypeInfo(selectedDocumentType.type).name.fr) : ''}
294
301
  </Text>
302
+ <View style={styles.stepBadge}>
303
+ <Text style={styles.stepText}>
304
+ {t('kyc.idCardCapture.captureTitle', { side: currentSide === 'front' ? locale === 'en' ? 'Front' : 'Recto' : locale === 'en' ? 'Back' : 'Verso' })}
305
+ </Text>
306
+ </View>
295
307
  </View>
296
- </View>
297
-
298
- <View style={[styles.cameraFeedContainer, { flex: 1, backgroundColor: '#000' }]}>
299
308
 
300
- <EnhancedCameraView
301
- key={`${currentSide}-${cameraKey}`}
302
- showCamera={true}
303
- isProcessing={isBusy}
304
- cameraType={cameraConfig.cameraType}
305
- style={styles.absoluteFillObject}
306
- onError={handleError}
307
- onSilentCapture={handleSilentCapture}
308
- silentCaptureResult={silentCaptureResult}
309
- overlayComponent={
310
- <>
311
- {/* We ONLY put the ID frame here, because if the camera fails, we don't care if the frame fails too */}
312
- <IdCardOverlay
313
- xMin={cameraConfig.overlay.bbox.xMin} yMin={cameraConfig.overlay.bbox.yMin} xMax={cameraConfig.overlay.bbox.xMax} yMax={cameraConfig.overlay.bbox.yMax}
314
- instructions={cameraConfig.overlay.guideText}
315
- cornerOpacity={cameraConfig.overlay.bbox.cornerRadius || 0 as number}
316
- isSuccess={silentCaptureResult.success}
317
- language={state.currentLanguage}
318
- stepperProps={{
319
- back: () => {
320
- if (currentSide === 'back') {
321
- setCurrentSide('front');
322
- setShowCamera(false);
323
- setIsProcessingCapture(false);
324
- setProcessingImagePath(null);
325
- if (capturedImages['front']?.dir) {
326
- const frontImage = capturedImages['front'];
327
- setSilentCaptureResult((prev) => ({ ...prev, path: frontImage.dir, success: true, isAnalyzing: false, error: '', mrz: frontImage.mrz || '', templatePath: frontImage.templatePath || '', bbox: bboxBySide['front'] }));
328
- } else { setSilentCaptureResult((prev) => ({ ...prev, path: '', success: false, isAnalyzing: false, error: '', templatePath: '' })); }
329
- } else { actions.previousComponent(); }
330
- },
331
- selectedDocumentType: selectedDocumentType ? (locale === 'en' ? getDocumentTypeInfo(selectedDocumentType.type).name.en : getDocumentTypeInfo(selectedDocumentType.type).name.fr) : '',
332
- step: state.currentComponentIndex + 1, totalSteps: state.template.components.length, side: currentSide,
333
- }}
334
- />
335
- </>
336
- }
337
- />
338
-
339
-
340
- {!isBusy && silentCaptureResult.isAnalyzing && (
341
- <View style={styles.topAnalyzingPillContainer}>
342
- <View style={styles.topAnalyzingPill}>
343
- <ActivityIndicator size="small" color="white" />
344
- <Text style={styles.analyzingPillText}>
345
- {state.currentLanguage === 'en' ? 'Scanning...' : 'Analyse...'}
346
- </Text>
309
+ <View style={[styles.cameraFeedContainer, { flex: 1, backgroundColor: '#000' }]}>
310
+
311
+ {/* WEB ONLY: Flip Camera Top Button */}
312
+ {Platform.OS === 'web' && (
313
+ <View style={styles.webTopControls}>
314
+ <TouchableOpacity style={styles.webFlipButton} onPress={toggleCameraLens}>
315
+ <Text style={styles.webFlipText}>🔄 Flip Lens</Text>
316
+ </TouchableOpacity>
347
317
  </View>
348
- </View>
349
- )}
350
-
351
- {isBusy && (
352
- <View style={[StyleSheet.absoluteFillObject, { zIndex: 9999 }]}>
353
- {processingImagePath && (
354
- <Image
355
- source={{ uri: processingImagePath.startsWith('file://') ? processingImagePath : `file://${processingImagePath}` }}
356
- style={StyleSheet.absoluteFillObject}
357
- resizeMode="cover"
358
- />
359
- )}
360
- <View style={styles.processingOverlay}>
361
- <ActivityIndicator size="large" color="#2DBD60" />
362
- <Text style={styles.processingText}>
363
- {state.currentLanguage === 'en' ? 'Perfect!\nProcessing Document...' : 'Parfait!\nTraitement du document...'}
364
- </Text>
318
+ )}
319
+
320
+ <EnhancedCameraView
321
+ key={`${currentSide}-${cameraKey}`}
322
+ showCamera={true}
323
+ isProcessing={isBusy}
324
+ cameraType={cameraConfig.cameraType}
325
+ style={StyleSheet.absoluteFillObject}
326
+ onError={handleError}
327
+ onSilentCapture={handleSilentCapture}
328
+ silentCaptureResult={silentCaptureResult}
329
+ overlayComponent={
330
+ <>
331
+ <IdCardOverlay
332
+ xMin={cameraConfig.overlay.bbox.xMin} yMin={cameraConfig.overlay.bbox.yMin} xMax={cameraConfig.overlay.bbox.xMax} yMax={cameraConfig.overlay.bbox.yMax}
333
+ instructions={cameraConfig.overlay.guideText}
334
+ cornerOpacity={cameraConfig.overlay.bbox.cornerRadius || 0 as number}
335
+ isSuccess={silentCaptureResult.success}
336
+ language={state.currentLanguage}
337
+ stepperProps={{
338
+ back: () => {
339
+ if (currentSide === 'back') {
340
+ setCurrentSide('front');
341
+ setShowCamera(false);
342
+ setIsProcessingCapture(false);
343
+ setProcessingImagePath(null);
344
+ if (capturedImages['front']?.dir) {
345
+ const frontImage = capturedImages['front'];
346
+ setSilentCaptureResult((prev) => ({ ...prev, path: frontImage.dir, success: true, isAnalyzing: false, error: '', mrz: frontImage.mrz || '', templatePath: frontImage.templatePath || '', bbox: bboxBySide['front'] }));
347
+ } else { setSilentCaptureResult((prev) => ({ ...prev, path: '', success: false, isAnalyzing: false, error: '', templatePath: '' })); }
348
+ } else { actions.previousComponent(); }
349
+ },
350
+ selectedDocumentType: selectedDocumentType ? (locale === 'en' ? getDocumentTypeInfo(selectedDocumentType.type).name.en : getDocumentTypeInfo(selectedDocumentType.type).name.fr) : '',
351
+ step: state.currentComponentIndex + 1, totalSteps: state.template.components.length, side: currentSide,
352
+ }}
353
+ />
354
+ </>
355
+ }
356
+ />
357
+
358
+ {!isBusy && silentCaptureResult.isAnalyzing && (
359
+ <View style={styles.topAnalyzingPillContainer}>
360
+ <View style={styles.topAnalyzingPill}>
361
+ <ActivityIndicator size="small" color="white" />
362
+ <Text style={styles.analyzingPillText}>
363
+ {state.currentLanguage === 'en' ? 'Scanning...' : 'Analyse...'}
364
+ </Text>
365
+ </View>
365
366
  </View>
366
- </View>
367
- )}
368
-
369
- {!isBusy && (
370
- <View style={styles.escapeHatchContainer}>
371
- {/* Refresh Button */}
372
- <TouchableOpacity style={styles.fallbackRefreshButton} onPress={refreshCamera}>
373
- <Text style={styles.fallbackRefreshText}>↻ Refresh Camera</Text>
374
- </TouchableOpacity>
375
-
376
- <TouchableOpacity
377
- style={[styles.fallbackRefreshButton, { marginTop: 15, backgroundColor: 'rgba(220, 38, 38, 0.8)', borderColor: '#DC2626' }]}
378
- onPress={() => setShowCamera(false)}
379
- >
380
- <Text style={styles.fallbackRefreshText}>Cancel / Go Back</Text>
381
- </TouchableOpacity>
382
- </View>
383
- )}
384
-
385
- {silentCaptureResult.error && !isBusy ? (
386
- <View style={[styles.floatingErrorBanner, { zIndex: 10000 }]}>
387
- <Text style={styles.floatingErrorText}>⚠️ {silentCaptureResult.error}</Text>
388
- </View>
389
- ) : null}
367
+ )}
368
+
369
+ {isBusy && (
370
+ <View style={[StyleSheet.absoluteFillObject, { zIndex: 9999 }]}>
371
+ {processingImagePath && (
372
+ <Image
373
+ source={{ uri: processingImagePath.startsWith('file://') ? processingImagePath : `file://${processingImagePath}` }}
374
+ style={StyleSheet.absoluteFillObject}
375
+ resizeMode="cover"
376
+ />
377
+ )}
378
+ <View style={styles.processingOverlay}>
379
+ <ActivityIndicator size="large" color="#2DBD60" />
380
+ <Text style={styles.processingText}>
381
+ {state.currentLanguage === 'en' ? 'Perfect!\nProcessing Document...' : 'Parfait!\nTraitement du document...'}
382
+ </Text>
383
+ </View>
384
+ </View>
385
+ )}
386
+
387
+ {/* 🚨 THE ESCAPE HATCH: Branching UI for Web vs Mobile */}
388
+ {!isBusy && Platform.OS === 'web' ? (
389
+ <View style={styles.webBottomControlBar}>
390
+ {silentCaptureResult.error ? (
391
+ <View style={styles.floatingErrorBanner}>
392
+ <Text style={styles.floatingErrorText}>⚠️ {silentCaptureResult.error}</Text>
393
+ </View>
394
+ ) : <View style={{ height: 10 }} />}
395
+
396
+ <View style={styles.webActionButtonsRow}>
397
+ <TouchableOpacity style={styles.webSecondaryButton} onPress={() => setShowCamera(false)}>
398
+ <Text style={styles.webSecondaryButtonText}>Cancel</Text>
399
+ </TouchableOpacity>
400
+ <TouchableOpacity style={styles.webPrimaryButton} onPress={refreshCamera}>
401
+ <Text style={styles.webPrimaryButtonText}>↻ Refresh Camera</Text>
402
+ </TouchableOpacity>
403
+ </View>
404
+ </View>
405
+ ) : !isBusy ? (
406
+ <View style={styles.escapeHatchContainer}>
407
+ <TouchableOpacity style={styles.fallbackRefreshButton} onPress={refreshCamera}>
408
+ <Text style={styles.fallbackRefreshText}>↻ Refresh Camera</Text>
409
+ </TouchableOpacity>
410
+ <TouchableOpacity
411
+ style={[styles.fallbackRefreshButton, { marginTop: 15, backgroundColor: 'rgba(220, 38, 38, 0.8)', borderColor: '#DC2626' }]}
412
+ onPress={() => setShowCamera(false)}
413
+ >
414
+ <Text style={styles.fallbackRefreshText}>Cancel / Go Back</Text>
415
+ </TouchableOpacity>
416
+ </View>
417
+ ) : null}
418
+
419
+ {silentCaptureResult.error && !isBusy && Platform.OS !== 'web' ? (
420
+ <View style={[styles.floatingErrorBanner, { zIndex: 10000 }]}>
421
+ <Text style={styles.floatingErrorText}>⚠️ {silentCaptureResult.error}</Text>
422
+ </View>
423
+ ) : null}
390
424
 
425
+ </View>
391
426
  </View>
392
427
  </View>
393
- </View>
394
- );
395
- }
428
+ );
429
+ }
396
430
 
431
+ // --- PREVIEW RENDER ---
397
432
  return (
398
433
  <View style={styles.root}>
399
434
  <View style={styles.previewContainer}>
@@ -405,6 +440,7 @@ export const IDCardCapture: React.FC<IDCardCaptureProps> = ({ component, value =
405
440
  <Text style={{ fontSize: 14, color: '#666', textAlign: 'center', marginBottom: 16, lineHeight: 22 }}>
406
441
  {getLocalizedText(component.instructions)}
407
442
  </Text>
443
+
408
444
  <View style={{ alignItems: 'center', justifyContent: 'center', flexDirection: "column", gap: 16 }}>
409
445
  {silentCaptureResult?.error === 'TOO_FAR_AWAY' && (
410
446
  <View style={styles.warningBanner}>
@@ -413,6 +449,8 @@ export const IDCardCapture: React.FC<IDCardCaptureProps> = ({ component, value =
413
449
  </Text>
414
450
  </View>
415
451
  )}
452
+
453
+ {/* 🚨 PREVIEW CONTAINER WITH PLATFORM OVERRIDES */}
416
454
  <View style={styles.imagePreviewWrapper}>
417
455
  {capturedImages[currentSide]?.dir ? (
418
456
  <Image source={{ uri: capturedImages[currentSide].dir }} style={styles.previewImage} />
@@ -420,10 +458,11 @@ export const IDCardCapture: React.FC<IDCardCaptureProps> = ({ component, value =
420
458
  <Image source={{ uri: silentCaptureResult.path }} style={styles.previewImage} />
421
459
  ) : null}
422
460
  </View>
461
+
423
462
  {!capturedImages[currentSide]?.dir && (
424
463
  <Button
425
464
  title={state.currentLanguage === "en" ? "Start Scanning" : "Commencer la numérisation"}
426
- onPress={() => { setShowCamera(true); actions.showCustomStepper(false); }}
465
+ onPress={() => { setShowCamera(true); refreshCamera(); actions.showCustomStepper(false); }}
427
466
  variant="primary" size="large" fullWidth
428
467
  />
429
468
  )}
@@ -436,6 +475,7 @@ export const IDCardCapture: React.FC<IDCardCaptureProps> = ({ component, value =
436
475
  actions.nextComponent();
437
476
  } else {
438
477
  setShowCamera(true);
478
+ refreshCamera();
439
479
  setCurrentSide('back');
440
480
  setSilentCaptureResult({ success: false, isAnalyzing: false, path: '', error: '', templatePath: undefined });
441
481
  setIsProcessingCapture(false);
@@ -455,38 +495,69 @@ export const IDCardCapture: React.FC<IDCardCaptureProps> = ({ component, value =
455
495
  const styles = StyleSheet.create({
456
496
  root: {
457
497
  flex: 1, width: '100%', backgroundColor: 'transparent', alignSelf: 'center',
458
- ...(Platform.OS === 'web' ? ({ minHeight: '85vh', justifyContent: 'center', alignItems: 'center', backdropFilter: 'blur(8px)' } as any) : {})
498
+ ...Platform.select({
499
+ web: { minHeight: '85vh', justifyContent: 'center', alignItems: 'center', backdropFilter: 'blur(8px)' } as any,
500
+ })
459
501
  },
460
502
  cameraWrapper: {
461
- width: '100%', backgroundColor: '#FFFFFF', overflow: 'hidden',
462
- ...(Platform.OS === 'web' ? ({ maxWidth: 500, height: 700, maxHeight: '90vh', borderRadius: 24, shadowColor: '#000', shadowOffset: { width: 0, height: 20 }, shadowOpacity: 0.25, shadowRadius: 35, elevation: 24, } as any) : { flex: 1, })
503
+ width: '100%', backgroundColor: '#000000', overflow: 'hidden',
504
+ ...Platform.select({
505
+ web: { maxWidth: 550, height: '80vh', minHeight: 600, borderRadius: 24, shadowColor: '#000', shadowOffset: { width: 0, height: 20 }, shadowOpacity: 0.25, shadowRadius: 35, elevation: 24 } as any,
506
+ default: { flex: 1 }
507
+ })
463
508
  },
464
509
  headerContainer: {
465
510
  flexDirection: 'row', alignItems: 'center', justifyContent: 'space-between', paddingHorizontal: 24, paddingVertical: 18, backgroundColor: '#FFFFFF', borderBottomWidth: 1, borderBottomColor: '#F1F5F9', zIndex: 10,
466
- ...(Platform.OS !== 'web' ? { display: 'none' } : {})
511
+ ...Platform.select({ web: { display: 'flex' }, default: { display: 'none' } })
467
512
  },
468
513
  headerTitle: { fontSize: 18, fontWeight: '700', color: '#0F172A', },
469
514
  stepBadge: { backgroundColor: '#F1F5F9', paddingHorizontal: 12, paddingVertical: 6, borderRadius: 20, },
470
515
  stepText: { fontSize: 13, fontWeight: '600', color: '#64748B', },
471
516
  cameraFeedContainer: { flex: 1, position: 'relative', backgroundColor: '#000', },
472
517
  camera: { flex: 1, },
473
- refreshButton: {
474
- position: 'absolute', bottom: 100, alignSelf: 'center', backgroundColor: 'rgba(0,0,0,0.6)', paddingVertical: 12, paddingHorizontal: 24, borderRadius: 24, zIndex: 500
475
- },
476
- refreshButtonText: { color: 'white', fontWeight: 'bold', fontSize: 16 },
518
+
519
+ // MOBILE: Escape Hatch layout
520
+ escapeHatchContainer: { position: 'absolute', bottom: 40, left: 0, right: 0, alignItems: 'center', justifyContent: 'center', zIndex: 99999 },
521
+ fallbackRefreshButton: { backgroundColor: 'rgba(0, 0, 0, 0.8)', borderWidth: 1, borderColor: 'rgba(255, 255, 255, 0.5)', paddingVertical: 12, paddingHorizontal: 24, borderRadius: 24, shadowColor: '#000', shadowOffset: { width: 0, height: 4 }, shadowOpacity: 0.3, shadowRadius: 5, elevation: 8 },
522
+ fallbackRefreshText: { color: '#FFFFFF', fontWeight: 'bold', fontSize: 16 },
523
+
524
+ // WEB: Control Bar layout
525
+ webBottomControlBar: { position: 'absolute', bottom: 0, left: 0, right: 0, paddingHorizontal: 20, paddingBottom: 20, paddingTop: 20, backgroundColor: 'rgba(0,0,0,0.6)', zIndex: 99999 },
526
+ webActionButtonsRow: { flexDirection: 'row', justifyContent: 'space-between', gap: 12, marginTop: 12 },
527
+ webPrimaryButton: { flex: 1, backgroundColor: '#2DBD60', paddingVertical: 14, borderRadius: 12, alignItems: 'center' },
528
+ webPrimaryButtonText: { color: 'white', fontWeight: 'bold', fontSize: 16 },
529
+ webSecondaryButton: { flex: 1, backgroundColor: 'rgba(255,255,255,0.2)', borderWidth: 1, borderColor: 'rgba(255,255,255,0.4)', paddingVertical: 14, borderRadius: 12, alignItems: 'center' },
530
+ webSecondaryButtonText: { color: 'white', fontWeight: 'bold', fontSize: 16 },
531
+
532
+ // WEB: Flip Controls
533
+ webTopControls: { position: 'absolute', top: 20, right: 20, zIndex: 9999 },
534
+ webFlipButton: { backgroundColor: 'rgba(0,0,0,0.5)', paddingHorizontal: 16, paddingVertical: 10, borderRadius: 20, borderWidth: 1, borderColor: 'rgba(255,255,255,0.3)' },
535
+ webFlipText: { color: 'white', fontWeight: 'bold', fontSize: 14 },
536
+
477
537
  previewContainer: {
478
538
  width: '100%', backgroundColor: 'white', borderRadius: 12, paddingVertical: 24, paddingHorizontal: 20, shadowColor: '#000', shadowOffset: { width: 0, height: 4 }, shadowOpacity: 0.1, shadowRadius: 12, elevation: 8,
479
- ...(Platform.OS === 'web' ? { alignSelf: 'center', maxWidth: 600 } : { margin: 10, width: '95%' })
539
+ ...Platform.select({ web: { alignSelf: 'center', maxWidth: 600 }, default: { margin: 10, width: '95%' }})
480
540
  },
481
541
  previewItemContainer: { flexGrow: 1, },
482
542
  title: { fontSize: 24, fontWeight: 'bold', color: '#333', marginBottom: 8, textAlign: 'center' },
483
543
  description: { fontSize: 16, color: '#666', textAlign: 'center', marginBottom: 24, lineHeight: 22 },
484
544
  sideContainer: { marginBottom: 24 },
485
545
  sideTitle: { fontSize: 25, fontWeight: 'bold', color: '#000', marginBottom: 12, textAlign: 'center' },
486
- imagePreviewWrapper: { width: '100%', height: 220, borderRadius: 12, padding: 1, overflow: 'hidden', shadowColor: '#000', shadowOffset: { width: 0, height: 4 }, shadowOpacity: 0.18, shadowRadius: 8, elevation: 8, backgroundColor: '#f0f0f0' },
546
+
547
+ imagePreviewWrapper: {
548
+ width: '100%', borderRadius: 12, padding: 1, overflow: 'hidden', shadowColor: '#000', shadowOffset: { width: 0, height: 4 }, shadowOpacity: 0.18, shadowRadius: 8, elevation: 8, backgroundColor: '#f0f0f0',
549
+ ...Platform.select({
550
+ web: { aspectRatio: 1.59, height: 'auto' } as any, // 🚨 Perfect ID ratio on web
551
+ default: { height: 220 } // 🚨 Strict original height on mobile
552
+ })
553
+ },
487
554
  previewImage: { width: '100%', height: '100%', borderRadius: 12, resizeMode: 'cover' },
555
+
488
556
  floatingErrorBanner: {
489
- position: 'absolute', bottom: 30, left: 24, right: 24, backgroundColor: '#FEF2F2', borderWidth: 1, borderColor: '#FCA5A5', paddingVertical: 12, paddingHorizontal: 16, borderRadius: 12, alignItems: 'center', justifyContent: 'center', shadowColor: '#DC2626', shadowOffset: { width: 0, height: 4 }, shadowOpacity: 0.1, shadowRadius: 8, elevation: 8, zIndex: 100
557
+ backgroundColor: '#FEF2F2', borderWidth: 1, borderColor: '#FCA5A5', paddingVertical: 12, paddingHorizontal: 16, borderRadius: 12, alignItems: 'center', justifyContent: 'center', width: '100%',
558
+ ...Platform.select({
559
+ default: { position: 'absolute', top: Platform.OS === 'ios' ? 90 : 70, left: 24, right: 24, zIndex: 10000 }
560
+ })
490
561
  },
491
562
  floatingErrorText: { color: '#991B1B', fontSize: 14, fontWeight: '700', textAlign: 'center' },
492
563
  processingOverlay: { flex: 1, backgroundColor: 'rgba(0, 0, 0, 0.6)', justifyContent: 'center', alignItems: 'center', zIndex: 9999 },
@@ -496,39 +567,5 @@ const styles = StyleSheet.create({
496
567
  errorText: { color: '#dc2626', fontSize: 14, marginTop: 8, textAlign: 'center' },
497
568
  topAnalyzingPillContainer: { position: 'absolute', top: Platform.OS === 'android' ? 60 : 50, left: 0, right: 0, alignItems: 'center', zIndex: 100 },
498
569
  topAnalyzingPill: { flexDirection: 'row', alignItems: 'center', backgroundColor: 'rgba(0,0,0,0.6)', paddingVertical: 8, paddingHorizontal: 16, borderRadius: 20, gap: 8 },
499
- analyzingPillText: { color: 'white', fontSize: 14, fontWeight: 'bold' },
500
- escapeHatchContainer: {
501
- position: 'absolute',
502
- bottom: 40,
503
- left: 0,
504
- right: 0,
505
- alignItems: 'center',
506
- justifyContent: 'center',
507
- zIndex: 99999, // Guarantees it is the top-most element
508
- },
509
- fallbackRefreshButton: {
510
- backgroundColor: 'rgba(0, 0, 0, 0.8)', // Darker so it's visible on white or black
511
- borderWidth: 1,
512
- borderColor: 'rgba(255, 255, 255, 0.5)',
513
- paddingVertical: 12,
514
- paddingHorizontal: 24,
515
- borderRadius: 24,
516
- shadowColor: '#000',
517
- shadowOffset: { width: 0, height: 4 },
518
- shadowOpacity: 0.3,
519
- shadowRadius: 5,
520
- elevation: 8,
521
- },
522
- fallbackRefreshText: {
523
- color: '#FFFFFF',
524
- fontWeight: 'bold',
525
- fontSize: 16,
526
- },
527
- absoluteFillObject: {
528
- position: 'absolute',
529
- top: 0,
530
- left: 0,
531
- right: 0,
532
- bottom: 0,
533
- },
570
+ analyzingPillText: { color: 'white', fontSize: 14, fontWeight: 'bold' }
534
571
  });