@arfuhad/react-native-smart-camera 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (95) hide show
  1. package/ARCHITECTURE.md +341 -0
  2. package/README.md +154 -0
  3. package/android/build.gradle +89 -0
  4. package/android/src/main/AndroidManifest.xml +2 -0
  5. package/android/src/main/java/expo/modules/smartcamera/ImageLoader.kt +106 -0
  6. package/android/src/main/java/expo/modules/smartcamera/MLKitFaceDetector.kt +273 -0
  7. package/android/src/main/java/expo/modules/smartcamera/SmartCameraModule.kt +205 -0
  8. package/android/src/main/java/expo/modules/smartcamera/SmartCameraView.kt +153 -0
  9. package/android/src/main/java/expo/modules/smartcamera/WebRTCFrameBridge.kt +184 -0
  10. package/app.plugin.js +17 -0
  11. package/build/SmartCamera.d.ts +17 -0
  12. package/build/SmartCamera.d.ts.map +1 -0
  13. package/build/SmartCamera.js +270 -0
  14. package/build/SmartCamera.js.map +1 -0
  15. package/build/SmartCameraModule.d.ts +112 -0
  16. package/build/SmartCameraModule.d.ts.map +1 -0
  17. package/build/SmartCameraModule.js +121 -0
  18. package/build/SmartCameraModule.js.map +1 -0
  19. package/build/SmartCameraView.d.ts +8 -0
  20. package/build/SmartCameraView.d.ts.map +1 -0
  21. package/build/SmartCameraView.js +7 -0
  22. package/build/SmartCameraView.js.map +1 -0
  23. package/build/detection/blinkProcessor.d.ts +23 -0
  24. package/build/detection/blinkProcessor.d.ts.map +1 -0
  25. package/build/detection/blinkProcessor.js +90 -0
  26. package/build/detection/blinkProcessor.js.map +1 -0
  27. package/build/detection/faceDetector.d.ts +16 -0
  28. package/build/detection/faceDetector.d.ts.map +1 -0
  29. package/build/detection/faceDetector.js +46 -0
  30. package/build/detection/faceDetector.js.map +1 -0
  31. package/build/detection/index.d.ts +4 -0
  32. package/build/detection/index.d.ts.map +1 -0
  33. package/build/detection/index.js +4 -0
  34. package/build/detection/index.js.map +1 -0
  35. package/build/detection/staticImageDetector.d.ts +25 -0
  36. package/build/detection/staticImageDetector.d.ts.map +1 -0
  37. package/build/detection/staticImageDetector.js +48 -0
  38. package/build/detection/staticImageDetector.js.map +1 -0
  39. package/build/hooks/index.d.ts +5 -0
  40. package/build/hooks/index.d.ts.map +1 -0
  41. package/build/hooks/index.js +5 -0
  42. package/build/hooks/index.js.map +1 -0
  43. package/build/hooks/useBlinkDetection.d.ts +39 -0
  44. package/build/hooks/useBlinkDetection.d.ts.map +1 -0
  45. package/build/hooks/useBlinkDetection.js +67 -0
  46. package/build/hooks/useBlinkDetection.js.map +1 -0
  47. package/build/hooks/useFaceDetection.d.ts +46 -0
  48. package/build/hooks/useFaceDetection.d.ts.map +1 -0
  49. package/build/hooks/useFaceDetection.js +80 -0
  50. package/build/hooks/useFaceDetection.js.map +1 -0
  51. package/build/hooks/useSmartCamera.d.ts +31 -0
  52. package/build/hooks/useSmartCamera.d.ts.map +1 -0
  53. package/build/hooks/useSmartCamera.js +75 -0
  54. package/build/hooks/useSmartCamera.js.map +1 -0
  55. package/build/hooks/useSmartCameraWebRTC.d.ts +58 -0
  56. package/build/hooks/useSmartCameraWebRTC.d.ts.map +1 -0
  57. package/build/hooks/useSmartCameraWebRTC.js +160 -0
  58. package/build/hooks/useSmartCameraWebRTC.js.map +1 -0
  59. package/build/index.d.ts +14 -0
  60. package/build/index.d.ts.map +1 -0
  61. package/build/index.js +20 -0
  62. package/build/index.js.map +1 -0
  63. package/build/types.d.ts +478 -0
  64. package/build/types.d.ts.map +1 -0
  65. package/build/types.js +2 -0
  66. package/build/types.js.map +1 -0
  67. package/build/utils/index.d.ts +98 -0
  68. package/build/utils/index.d.ts.map +1 -0
  69. package/build/utils/index.js +276 -0
  70. package/build/utils/index.js.map +1 -0
  71. package/build/webrtc/WebRTCBridge.d.ts +55 -0
  72. package/build/webrtc/WebRTCBridge.d.ts.map +1 -0
  73. package/build/webrtc/WebRTCBridge.js +113 -0
  74. package/build/webrtc/WebRTCBridge.js.map +1 -0
  75. package/build/webrtc/index.d.ts +3 -0
  76. package/build/webrtc/index.d.ts.map +1 -0
  77. package/build/webrtc/index.js +2 -0
  78. package/build/webrtc/index.js.map +1 -0
  79. package/build/webrtc/types.d.ts +64 -0
  80. package/build/webrtc/types.d.ts.map +1 -0
  81. package/build/webrtc/types.js +5 -0
  82. package/build/webrtc/types.js.map +1 -0
  83. package/expo-module.config.json +9 -0
  84. package/ios/MLKitFaceDetector.swift +310 -0
  85. package/ios/SmartCamera.podspec +33 -0
  86. package/ios/SmartCameraModule.swift +225 -0
  87. package/ios/SmartCameraView.swift +146 -0
  88. package/ios/WebRTCFrameBridge.swift +150 -0
  89. package/package.json +91 -0
  90. package/plugin/build/index.d.ts +28 -0
  91. package/plugin/build/index.js +33 -0
  92. package/plugin/build/withSmartCameraAndroid.d.ts +9 -0
  93. package/plugin/build/withSmartCameraAndroid.js +108 -0
  94. package/plugin/build/withSmartCameraIOS.d.ts +11 -0
  95. package/plugin/build/withSmartCameraIOS.js +92 -0
@@ -0,0 +1,146 @@
1
+ import ExpoModulesCore
2
+ import UIKit
3
+ import AVFoundation
4
+
5
+ class SmartCameraView: ExpoView {
6
+ // MARK: - Properties
7
+
8
+ var cameraFacing: AVCaptureDevice.Position = .front {
9
+ didSet {
10
+ if cameraFacing != oldValue {
11
+ setupCamera()
12
+ }
13
+ }
14
+ }
15
+
16
+ var isActive: Bool = true {
17
+ didSet {
18
+ if isActive != oldValue {
19
+ updateCameraState()
20
+ }
21
+ }
22
+ }
23
+
24
+ private var captureSession: AVCaptureSession?
25
+ private var previewLayer: AVCaptureVideoPreviewLayer?
26
+ private var videoOutput: AVCaptureVideoDataOutput?
27
+
28
+ // MARK: - Initialization
29
+
30
+ required init(appContext: AppContext? = nil) {
31
+ super.init(appContext: appContext)
32
+ setupView()
33
+ }
34
+
35
+ // MARK: - Setup
36
+
37
+ private func setupView() {
38
+ backgroundColor = .black
39
+ clipsToBounds = true
40
+ }
41
+
42
+ private func setupCamera() {
43
+ // Remove existing session
44
+ captureSession?.stopRunning()
45
+ previewLayer?.removeFromSuperlayer()
46
+
47
+ // Create new session
48
+ let session = AVCaptureSession()
49
+ session.sessionPreset = .high
50
+
51
+ // Get camera device
52
+ guard let device = getCameraDevice() else {
53
+ print("[SmartCameraView] No camera device available")
54
+ return
55
+ }
56
+
57
+ do {
58
+ let input = try AVCaptureDeviceInput(device: device)
59
+
60
+ if session.canAddInput(input) {
61
+ session.addInput(input)
62
+ }
63
+
64
+ // Add video output
65
+ let output = AVCaptureVideoDataOutput()
66
+ output.videoSettings = [
67
+ kCVPixelBufferPixelFormatTypeKey as String: kCVPixelFormatType_32BGRA
68
+ ]
69
+ output.alwaysDiscardsLateVideoFrames = true
70
+
71
+ if session.canAddOutput(output) {
72
+ session.addOutput(output)
73
+ }
74
+
75
+ videoOutput = output
76
+
77
+ // Setup preview layer
78
+ let preview = AVCaptureVideoPreviewLayer(session: session)
79
+ preview.videoGravity = .resizeAspectFill
80
+ preview.frame = bounds
81
+ layer.addSublayer(preview)
82
+
83
+ previewLayer = preview
84
+ captureSession = session
85
+
86
+ // Start session on background thread
87
+ DispatchQueue.global(qos: .userInitiated).async { [weak self] in
88
+ self?.captureSession?.startRunning()
89
+ }
90
+
91
+ } catch {
92
+ print("[SmartCameraView] Error setting up camera: \(error)")
93
+ }
94
+ }
95
+
96
+ private func getCameraDevice() -> AVCaptureDevice? {
97
+ let deviceTypes: [AVCaptureDevice.DeviceType] = [
98
+ .builtInWideAngleCamera,
99
+ .builtInDualCamera,
100
+ .builtInTrueDepthCamera
101
+ ]
102
+
103
+ let discoverySession = AVCaptureDevice.DiscoverySession(
104
+ deviceTypes: deviceTypes,
105
+ mediaType: .video,
106
+ position: cameraFacing
107
+ )
108
+
109
+ return discoverySession.devices.first
110
+ }
111
+
112
+ private func updateCameraState() {
113
+ if isActive {
114
+ DispatchQueue.global(qos: .userInitiated).async { [weak self] in
115
+ self?.captureSession?.startRunning()
116
+ }
117
+ } else {
118
+ DispatchQueue.global(qos: .userInitiated).async { [weak self] in
119
+ self?.captureSession?.stopRunning()
120
+ }
121
+ }
122
+ }
123
+
124
+ // MARK: - Layout
125
+
126
+ override func layoutSubviews() {
127
+ super.layoutSubviews()
128
+ previewLayer?.frame = bounds
129
+ }
130
+
131
+ // MARK: - Lifecycle
132
+
133
+ override func didMoveToWindow() {
134
+ super.didMoveToWindow()
135
+ if window != nil && captureSession == nil {
136
+ setupCamera()
137
+ }
138
+ }
139
+
140
+ override func removeFromSuperview() {
141
+ captureSession?.stopRunning()
142
+ captureSession = nil
143
+ super.removeFromSuperview()
144
+ }
145
+ }
146
+
@@ -0,0 +1,150 @@
1
+ import Foundation
2
+ import AVFoundation
3
+
4
+ // Note: This is a placeholder implementation.
5
+ // In production, you would integrate with WebRTC.framework
6
+ // and react-native-webrtc's RTCVideoSource.
7
+
8
+ class WebRTCFrameBridge {
9
+ // MARK: - Properties
10
+
11
+ private var isInitialized = false
12
+ private var isStreaming = false
13
+ private var streamWidth: Int = 1280
14
+ private var streamHeight: Int = 720
15
+ private var streamFrameRate: Int = 30
16
+
17
+ private var frameQueue: DispatchQueue?
18
+ private var lastFrameTime: CFTimeInterval = 0
19
+ private var frameInterval: CFTimeInterval = 1.0 / 30.0
20
+
21
+ // MARK: - Initialization
22
+
23
+ func initialize() async throws {
24
+ guard !isInitialized else { return }
25
+
26
+ // Initialize WebRTC
27
+ // In production: RTCInitializeSSL()
28
+
29
+ frameQueue = DispatchQueue(label: "com.smartcamera.webrtc.frame", qos: .userInteractive)
30
+ isInitialized = true
31
+
32
+ print("[WebRTCFrameBridge] Initialized")
33
+ }
34
+
35
+ // MARK: - Streaming
36
+
37
+ func startStream(width: Int, height: Int, frameRate: Int) async throws {
38
+ guard isInitialized else {
39
+ throw NSError(domain: "WebRTCFrameBridge", code: 1, userInfo: [
40
+ NSLocalizedDescriptionKey: "WebRTC not initialized"
41
+ ])
42
+ }
43
+
44
+ guard !isStreaming else {
45
+ print("[WebRTCFrameBridge] Already streaming")
46
+ return
47
+ }
48
+
49
+ streamWidth = width
50
+ streamHeight = height
51
+ streamFrameRate = frameRate
52
+ frameInterval = 1.0 / Double(frameRate)
53
+
54
+ // In production:
55
+ // 1. Create RTCVideoSource
56
+ // 2. Create RTCVideoTrack
57
+ // 3. Add track to peer connection
58
+
59
+ isStreaming = true
60
+ print("[WebRTCFrameBridge] Started streaming: \(width)x\(height)@\(frameRate)fps")
61
+ }
62
+
63
+ func stopStream() async {
64
+ guard isStreaming else { return }
65
+
66
+ // In production:
67
+ // 1. Remove track from peer connection
68
+ // 2. Stop video source
69
+
70
+ isStreaming = false
71
+ print("[WebRTCFrameBridge] Stopped streaming")
72
+ }
73
+
74
+ // MARK: - Frame Processing
75
+
76
+ func pushFrame(_ frameData: [String: Any]) {
77
+ guard isStreaming else { return }
78
+
79
+ // Rate limiting
80
+ let currentTime = CACurrentMediaTime()
81
+ guard currentTime - lastFrameTime >= frameInterval else { return }
82
+ lastFrameTime = currentTime
83
+
84
+ frameQueue?.async { [weak self] in
85
+ self?.processFrame(frameData)
86
+ }
87
+ }
88
+
89
+ func pushSampleBuffer(_ sampleBuffer: CMSampleBuffer) {
90
+ guard isStreaming else { return }
91
+
92
+ // Rate limiting
93
+ let currentTime = CACurrentMediaTime()
94
+ guard currentTime - lastFrameTime >= frameInterval else { return }
95
+ lastFrameTime = currentTime
96
+
97
+ frameQueue?.async { [weak self] in
98
+ self?.processSampleBuffer(sampleBuffer)
99
+ }
100
+ }
101
+
102
+ private func processFrame(_ frameData: [String: Any]) {
103
+ // In production:
104
+ // 1. Convert frame data to RTCVideoFrame
105
+ // 2. Push to RTCVideoSource
106
+
107
+ // Placeholder - log frame info
108
+ if let width = frameData["width"], let height = frameData["height"] {
109
+ // print("[WebRTCFrameBridge] Processing frame: \(width)x\(height)")
110
+ }
111
+ }
112
+
113
+ private func processSampleBuffer(_ sampleBuffer: CMSampleBuffer) {
114
+ guard let pixelBuffer = CMSampleBufferGetImageBuffer(sampleBuffer) else {
115
+ return
116
+ }
117
+
118
+ // In production:
119
+ // 1. Convert CVPixelBuffer to RTCCVPixelBuffer
120
+ // 2. Create RTCVideoFrame
121
+ // 3. Push to RTCVideoSource
122
+
123
+ // Example conversion (pseudo-code):
124
+ /*
125
+ let rtcPixelBuffer = RTCCVPixelBuffer(pixelBuffer: pixelBuffer)
126
+ let timeStampNs = Int64(CACurrentMediaTime() * 1_000_000_000)
127
+ let rotation = RTCVideoRotation._0
128
+
129
+ let frame = RTCVideoFrame(
130
+ buffer: rtcPixelBuffer,
131
+ rotation: rotation,
132
+ timeStampNs: timeStampNs
133
+ )
134
+
135
+ videoSource?.capturer(self, didCapture: frame)
136
+ */
137
+
138
+ let width = CVPixelBufferGetWidth(pixelBuffer)
139
+ let height = CVPixelBufferGetHeight(pixelBuffer)
140
+ // print("[WebRTCFrameBridge] Processing sample buffer: \(width)x\(height)")
141
+ }
142
+
143
+ // MARK: - Utilities
144
+
145
+ var currentStreamConfig: (width: Int, height: Int, frameRate: Int)? {
146
+ guard isStreaming else { return nil }
147
+ return (streamWidth, streamHeight, streamFrameRate)
148
+ }
149
+ }
150
+
package/package.json ADDED
@@ -0,0 +1,91 @@
1
+ {
2
+ "name": "@arfuhad/react-native-smart-camera",
3
+ "version": "0.1.0",
4
+ "description": "Expo-compatible native module for camera preview, face detection, blink detection, and WebRTC streaming",
5
+ "main": "build/index.js",
6
+ "types": "build/index.d.ts",
7
+ "scripts": {
8
+ "build": "expo-module build",
9
+ "build:plugin": "tsc --project plugin/tsconfig.json",
10
+ "clean": "expo-module clean && rm -rf plugin/build",
11
+ "lint": "expo-module lint",
12
+ "test": "expo-module test",
13
+ "prepare": "expo-module prepare && npm run build:plugin",
14
+ "prepublishOnly": "expo-module prepublishOnly",
15
+ "expo-module": "expo-module"
16
+ },
17
+ "keywords": [
18
+ "react-native",
19
+ "expo",
20
+ "camera",
21
+ "face-detection",
22
+ "blink-detection",
23
+ "webrtc",
24
+ "vision-camera",
25
+ "ml-kit",
26
+ "expo-module",
27
+ "frame-processor"
28
+ ],
29
+ "files": [
30
+ "build",
31
+ "ios",
32
+ "android",
33
+ "plugin/build",
34
+ "app.plugin.js",
35
+ "expo-module.config.json",
36
+ "README.md",
37
+ "ARCHITECTURE.md"
38
+ ],
39
+ "repository": {
40
+ "type": "git",
41
+ "url": "https://github.com/arfuhad/react-native-smart-camera.git"
42
+ },
43
+ "bugs": {
44
+ "url": "https://github.com/arfuhad/react-native-smart-camera/issues"
45
+ },
46
+ "author": "arfuhad",
47
+ "license": "MIT",
48
+ "homepage": "https://github.com/arfuhad/react-native-smart-camera#readme",
49
+ "exports": {
50
+ ".": {
51
+ "types": "./build/index.d.ts",
52
+ "default": "./build/index.js"
53
+ },
54
+ "./plugin": {
55
+ "types": "./plugin/build/index.d.ts",
56
+ "default": "./plugin/build/index.js"
57
+ }
58
+ },
59
+ "peerDependencies": {
60
+ "expo": ">=49.0.0",
61
+ "react": ">=18.0.0",
62
+ "react-native": ">=0.72.0",
63
+ "react-native-vision-camera": ">=3.0.0",
64
+ "react-native-webrtc": ">=118.0.0",
65
+ "react-native-worklets-core": ">=1.0.0"
66
+ },
67
+ "devDependencies": {
68
+ "@expo/config-plugins": "^7.8.0",
69
+ "@types/react": "^18.2.0",
70
+ "expo": "^51.0.0",
71
+ "expo-module-scripts": "^3.4.1",
72
+ "expo-modules-core": "^1.11.0",
73
+ "react": "^18.2.0",
74
+ "react-native": "^0.74.0",
75
+ "react-native-vision-camera": "^4.0.0",
76
+ "react-native-webrtc": "^118.0.7",
77
+ "react-native-worklets-core": "^1.3.0",
78
+ "typescript": "^5.3.0"
79
+ },
80
+ "peerDependenciesMeta": {
81
+ "react-native-vision-camera": {
82
+ "optional": false
83
+ },
84
+ "react-native-webrtc": {
85
+ "optional": true
86
+ },
87
+ "react-native-worklets-core": {
88
+ "optional": false
89
+ }
90
+ }
91
+ }
@@ -0,0 +1,28 @@
1
+ import { ConfigPlugin } from '@expo/config-plugins';
2
+ /**
3
+ * Plugin options for react-native-smart-camera
4
+ */
5
+ export interface SmartCameraPluginOptions {
6
+ /**
7
+ * Custom camera usage description for iOS
8
+ * @default "This app uses the camera for face detection and video streaming"
9
+ */
10
+ cameraPermissionText?: string;
11
+ /**
12
+ * Custom microphone usage description for iOS
13
+ * @default "This app uses the microphone for audio streaming"
14
+ */
15
+ microphonePermissionText?: string;
16
+ /**
17
+ * Enable ML Kit Face Detection
18
+ * @default true
19
+ */
20
+ enableMLKit?: boolean;
21
+ /**
22
+ * Enable WebRTC support
23
+ * @default true
24
+ */
25
+ enableWebRTC?: boolean;
26
+ }
27
+ declare const _default: ConfigPlugin<void | SmartCameraPluginOptions>;
28
+ export default _default;
@@ -0,0 +1,33 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const config_plugins_1 = require("@expo/config-plugins");
4
+ const withSmartCameraIOS_1 = require("./withSmartCameraIOS");
5
+ const withSmartCameraAndroid_1 = require("./withSmartCameraAndroid");
6
+ const pkg = require('../../package.json');
7
+ /**
8
+ * Expo config plugin for react-native-smart-camera
9
+ *
10
+ * This plugin:
11
+ * - Adds camera and microphone permissions
12
+ * - Configures iOS frameworks
13
+ * - Sets up Android Proguard rules
14
+ * - Adds ML Kit dependencies
15
+ */
16
+ const withSmartCamera = (config, options = {}) => {
17
+ const { cameraPermissionText = 'This app uses the camera for face detection and video streaming', microphonePermissionText = 'This app uses the microphone for audio streaming', enableMLKit = true, enableWebRTC = true, } = options ?? {};
18
+ // Apply iOS configuration
19
+ config = (0, withSmartCameraIOS_1.withSmartCameraIOS)(config, {
20
+ cameraPermissionText,
21
+ microphonePermissionText,
22
+ enableMLKit,
23
+ enableWebRTC,
24
+ });
25
+ // Apply Android configuration
26
+ config = (0, withSmartCameraAndroid_1.withSmartCameraAndroid)(config, {
27
+ enableMLKit,
28
+ enableWebRTC,
29
+ });
30
+ return config;
31
+ };
32
+ exports.default = (0, config_plugins_1.createRunOncePlugin)(withSmartCamera, pkg.name, pkg.version);
33
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7QUFBQSx5REFBeUU7QUFDekUsNkRBQTBEO0FBQzFELHFFQUFrRTtBQUVsRSxNQUFNLEdBQUcsR0FBRyxPQUFPLENBQUMsb0JBQW9CLENBQUMsQ0FBQztBQStCMUM7Ozs7Ozs7O0dBUUc7QUFDSCxNQUFNLGVBQWUsR0FBa0QsQ0FBQyxNQUFNLEVBQUUsT0FBTyxHQUFHLEVBQUUsRUFBRSxFQUFFO0lBQzlGLE1BQU0sRUFDSixvQkFBb0IsR0FBRyxpRUFBaUUsRUFDeEYsd0JBQXdCLEdBQUcsa0RBQWtELEVBQzdFLFdBQVcsR0FBRyxJQUFJLEVBQ2xCLFlBQVksR0FBRyxJQUFJLEdBQ3BCLEdBQUcsT0FBTyxJQUFJLEVBQUUsQ0FBQztJQUVsQiwwQkFBMEI7SUFDMUIsTUFBTSxHQUFHLElBQUEsdUNBQWtCLEVBQUMsTUFBTSxFQUFFO1FBQ2xDLG9CQUFvQjtRQUNwQix3QkFBd0I7UUFDeEIsV0FBVztRQUNYLFlBQVk7S0FDYixDQUFDLENBQUM7SUFFSCw4QkFBOEI7SUFDOUIsTUFBTSxHQUFHLElBQUEsK0NBQXNCLEVBQUMsTUFBTSxFQUFFO1FBQ3RDLFdBQVc7UUFDWCxZQUFZO0tBQ2IsQ0FBQyxDQUFDO0lBRUgsT0FBTyxNQUFNLENBQUM7QUFDaEIsQ0FBQyxDQUFDO0FBRUYsa0JBQWUsSUFBQSxvQ0FBbUIsRUFBQyxlQUFlLEVBQUUsR0FBRyxDQUFDLElBQUksRUFBRSxHQUFHLENBQUMsT0FBTyxDQUFDLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBDb25maWdQbHVnaW4sIGNyZWF0ZVJ1bk9uY2VQbHVnaW4gfSBmcm9tICdAZXhwby9jb25maWctcGx1Z2lucyc7XG5pbXBvcnQgeyB3aXRoU21hcnRDYW1lcmFJT1MgfSBmcm9tICcuL3dpdGhTbWFydENhbWVyYUlPUyc7XG5pbXBvcnQgeyB3aXRoU21hcnRDYW1lcmFBbmRyb2lkIH0gZnJvbSAnLi93aXRoU21hcnRDYW1lcmFBbmRyb2lkJztcblxuY29uc3QgcGtnID0gcmVxdWlyZSgnLi4vLi4vcGFja2FnZS5qc29uJyk7XG5cbi8qKlxuICogUGx1Z2luIG9wdGlvbnMgZm9yIHJlYWN0LW5hdGl2ZS1zbWFydC1jYW1lcmFcbiAqL1xuZXhwb3J0IGludGVyZmFjZSBTbWFydENhbWVyYVBsdWdpbk9wdGlvbnMge1xuICAvKipcbiAgICogQ3VzdG9tIGNhbWVyYSB1c2FnZSBkZXNjcmlwdGlvbiBmb3IgaU9TXG4gICAqIEBkZWZhdWx0IFwiVGhpcyBhcHAgdXNlcyB0aGUgY2FtZXJhIGZvciBmYWNlIGRldGVjdGlvbiBhbmQgdmlkZW8gc3RyZWFtaW5nXCJcbiAgICovXG4gIGNhbWVyYVBlcm1pc3Npb25UZXh0Pzogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBDdXN0b20gbWljcm9waG9uZSB1c2FnZSBkZXNjcmlwdGlvbiBmb3IgaU9TXG4gICAqIEBkZWZhdWx0IFwiVGhpcyBhcHAgdXNlcyB0aGUgbWljcm9waG9uZSBmb3IgYXVkaW8gc3RyZWFtaW5nXCJcbiAgICovXG4gIG1pY3JvcGhvbmVQZXJtaXNzaW9uVGV4dD86IHN0cmluZztcblxuICAvKipcbiAgICogRW5hYmxlIE1MIEtpdCBGYWNlIERldGVjdGlvblxuICAgKiBAZGVmYXVsdCB0cnVlXG4gICAqL1xuICBlbmFibGVNTEtpdD86IGJvb2xlYW47XG5cbiAgLyoqXG4gICAqIEVuYWJsZSBXZWJSVEMgc3VwcG9ydFxuICAgKiBAZGVmYXVsdCB0cnVlXG4gICAqL1xuICBlbmFibGVXZWJSVEM/OiBib29sZWFuO1xufVxuXG4vKipcbiAqIEV4cG8gY29uZmlnIHBsdWdpbiBmb3IgcmVhY3QtbmF0aXZlLXNtYXJ0LWNhbWVyYVxuICogXG4gKiBUaGlzIHBsdWdpbjpcbiAqIC0gQWRkcyBjYW1lcmEgYW5kIG1pY3JvcGhvbmUgcGVybWlzc2lvbnNcbiAqIC0gQ29uZmlndXJlcyBpT1MgZnJhbWV3b3Jrc1xuICogLSBTZXRzIHVwIEFuZHJvaWQgUHJvZ3VhcmQgcnVsZXNcbiAqIC0gQWRkcyBNTCBLaXQgZGVwZW5kZW5jaWVzXG4gKi9cbmNvbnN0IHdpdGhTbWFydENhbWVyYTogQ29uZmlnUGx1Z2luPFNtYXJ0Q2FtZXJhUGx1Z2luT3B0aW9ucyB8IHZvaWQ+ID0gKGNvbmZpZywgb3B0aW9ucyA9IHt9KSA9PiB7XG4gIGNvbnN0IHtcbiAgICBjYW1lcmFQZXJtaXNzaW9uVGV4dCA9ICdUaGlzIGFwcCB1c2VzIHRoZSBjYW1lcmEgZm9yIGZhY2UgZGV0ZWN0aW9uIGFuZCB2aWRlbyBzdHJlYW1pbmcnLFxuICAgIG1pY3JvcGhvbmVQZXJtaXNzaW9uVGV4dCA9ICdUaGlzIGFwcCB1c2VzIHRoZSBtaWNyb3Bob25lIGZvciBhdWRpbyBzdHJlYW1pbmcnLFxuICAgIGVuYWJsZU1MS2l0ID0gdHJ1ZSxcbiAgICBlbmFibGVXZWJSVEMgPSB0cnVlLFxuICB9ID0gb3B0aW9ucyA/PyB7fTtcblxuICAvLyBBcHBseSBpT1MgY29uZmlndXJhdGlvblxuICBjb25maWcgPSB3aXRoU21hcnRDYW1lcmFJT1MoY29uZmlnLCB7XG4gICAgY2FtZXJhUGVybWlzc2lvblRleHQsXG4gICAgbWljcm9waG9uZVBlcm1pc3Npb25UZXh0LFxuICAgIGVuYWJsZU1MS2l0LFxuICAgIGVuYWJsZVdlYlJUQyxcbiAgfSk7XG5cbiAgLy8gQXBwbHkgQW5kcm9pZCBjb25maWd1cmF0aW9uXG4gIGNvbmZpZyA9IHdpdGhTbWFydENhbWVyYUFuZHJvaWQoY29uZmlnLCB7XG4gICAgZW5hYmxlTUxLaXQsXG4gICAgZW5hYmxlV2ViUlRDLFxuICB9KTtcblxuICByZXR1cm4gY29uZmlnO1xufTtcblxuZXhwb3J0IGRlZmF1bHQgY3JlYXRlUnVuT25jZVBsdWdpbih3aXRoU21hcnRDYW1lcmEsIHBrZy5uYW1lLCBwa2cudmVyc2lvbik7XG5cbiJdfQ==
@@ -0,0 +1,9 @@
1
+ import { ConfigPlugin } from '@expo/config-plugins';
2
+ export interface AndroidPluginOptions {
3
+ enableMLKit: boolean;
4
+ enableWebRTC: boolean;
5
+ }
6
+ /**
7
+ * Android configuration for react-native-smart-camera
8
+ */
9
+ export declare const withSmartCameraAndroid: ConfigPlugin<AndroidPluginOptions>;
@@ -0,0 +1,108 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.withSmartCameraAndroid = void 0;
4
+ const config_plugins_1 = require("@expo/config-plugins");
5
+ /**
6
+ * Add camera and microphone permissions to AndroidManifest.xml
7
+ */
8
+ const withPermissions = (config, _options) => {
9
+ return (0, config_plugins_1.withAndroidManifest)(config, (config) => {
10
+ const manifest = config.modResults;
11
+ // Ensure permissions array exists
12
+ if (!manifest.manifest['uses-permission']) {
13
+ manifest.manifest['uses-permission'] = [];
14
+ }
15
+ const permissions = manifest.manifest['uses-permission'];
16
+ // Camera permission
17
+ const cameraPermission = 'android.permission.CAMERA';
18
+ if (!permissions.some((p) => p.$?.['android:name'] === cameraPermission)) {
19
+ permissions.push({
20
+ $: { 'android:name': cameraPermission },
21
+ });
22
+ }
23
+ // Microphone permission
24
+ const micPermission = 'android.permission.RECORD_AUDIO';
25
+ if (!permissions.some((p) => p.$?.['android:name'] === micPermission)) {
26
+ permissions.push({
27
+ $: { 'android:name': micPermission },
28
+ });
29
+ }
30
+ // Camera hardware feature
31
+ if (!manifest.manifest['uses-feature']) {
32
+ manifest.manifest['uses-feature'] = [];
33
+ }
34
+ const features = manifest.manifest['uses-feature'];
35
+ const cameraFeature = 'android.hardware.camera';
36
+ if (!features.some((f) => f.$?.['android:name'] === cameraFeature)) {
37
+ features.push({
38
+ $: {
39
+ 'android:name': cameraFeature,
40
+ 'android:required': 'false',
41
+ },
42
+ });
43
+ }
44
+ const cameraAutoFocus = 'android.hardware.camera.autofocus';
45
+ if (!features.some((f) => f.$?.['android:name'] === cameraAutoFocus)) {
46
+ features.push({
47
+ $: {
48
+ 'android:name': cameraAutoFocus,
49
+ 'android:required': 'false',
50
+ },
51
+ });
52
+ }
53
+ return config;
54
+ });
55
+ };
56
+ /**
57
+ * Add ML Kit dependency to app build.gradle
58
+ */
59
+ const withMLKitDependency = (config, options) => {
60
+ if (!options.enableMLKit) {
61
+ return config;
62
+ }
63
+ return (0, config_plugins_1.withAppBuildGradle)(config, (config) => {
64
+ const buildGradle = config.modResults;
65
+ // Check if ML Kit is already added
66
+ if (!buildGradle.contents.includes('com.google.mlkit:face-detection')) {
67
+ // Add ML Kit dependency in dependencies block
68
+ buildGradle.contents = buildGradle.contents.replace(/dependencies\s*{/, `dependencies {
69
+ // SmartCamera ML Kit Face Detection
70
+ implementation 'com.google.mlkit:face-detection:16.1.5'`);
71
+ }
72
+ return config;
73
+ });
74
+ };
75
+ /**
76
+ * Add proguard rules for ML Kit
77
+ */
78
+ const withProguardRules = (config, options) => {
79
+ if (!options.enableMLKit) {
80
+ return config;
81
+ }
82
+ return (0, config_plugins_1.withAppBuildGradle)(config, (config) => {
83
+ const buildGradle = config.modResults;
84
+ // Check if proguard is already configured for ML Kit
85
+ if (!buildGradle.contents.includes('mlkit-proguard-rules.pro')) {
86
+ // Add proguard configuration in release build type
87
+ buildGradle.contents = buildGradle.contents.replace(/buildTypes\s*{\s*release\s*{/, `buildTypes {
88
+ release {
89
+ // SmartCamera ML Kit Proguard rules
90
+ proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'`);
91
+ }
92
+ return config;
93
+ });
94
+ };
95
+ /**
96
+ * Android configuration for react-native-smart-camera
97
+ */
98
+ const withSmartCameraAndroid = (config, options) => {
99
+ // Add permissions
100
+ config = withPermissions(config, options);
101
+ // Add ML Kit dependency if enabled
102
+ config = withMLKitDependency(config, options);
103
+ // Add proguard rules if ML Kit enabled
104
+ config = withProguardRules(config, options);
105
+ return config;
106
+ };
107
+ exports.withSmartCameraAndroid = withSmartCameraAndroid;
108
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoid2l0aFNtYXJ0Q2FtZXJhQW5kcm9pZC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3NyYy93aXRoU21hcnRDYW1lcmFBbmRyb2lkLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUFBLHlEQU04QjtBQU85Qjs7R0FFRztBQUNILE1BQU0sZUFBZSxHQUF1QyxDQUFDLE1BQU0sRUFBRSxRQUFRLEVBQUUsRUFBRTtJQUMvRSxPQUFPLElBQUEsb0NBQW1CLEVBQUMsTUFBTSxFQUFFLENBQUMsTUFBTSxFQUFFLEVBQUU7UUFDNUMsTUFBTSxRQUFRLEdBQUcsTUFBTSxDQUFDLFVBQVUsQ0FBQztRQUVuQyxrQ0FBa0M7UUFDbEMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxRQUFRLENBQUMsaUJBQWlCLENBQUMsRUFBRSxDQUFDO1lBQzFDLFFBQVEsQ0FBQyxRQUFRLENBQUMsaUJBQWlCLENBQUMsR0FBRyxFQUFFLENBQUM7UUFDNUMsQ0FBQztRQUVELE1BQU0sV0FBVyxHQUFHLFFBQVEsQ0FBQyxRQUFRLENBQUMsaUJBQWlCLENBQUMsQ0FBQztRQUV6RCxvQkFBb0I7UUFDcEIsTUFBTSxnQkFBZ0IsR0FBRywyQkFBMkIsQ0FBQztRQUNyRCxJQUFJLENBQUMsV0FBVyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLGNBQWMsQ0FBQyxLQUFLLGdCQUFnQixDQUFDLEVBQUUsQ0FBQztZQUN6RSxXQUFXLENBQUMsSUFBSSxDQUFDO2dCQUNmLENBQUMsRUFBRSxFQUFFLGNBQWMsRUFBRSxnQkFBZ0IsRUFBRTthQUN4QyxDQUFDLENBQUM7UUFDTCxDQUFDO1FBRUQsd0JBQXdCO1FBQ3hCLE1BQU0sYUFBYSxHQUFHLGlDQUFpQyxDQUFDO1FBQ3hELElBQUksQ0FBQyxXQUFXLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMs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RkFHdUYsQ0FDeEYsQ0FBQztRQUNKLENBQUM7UUFFRCxPQUFPLE1BQU0sQ0FBQztJQUNoQixDQUFDLENBQUMsQ0FBQztBQUNMLENBQUMsQ0FBQztBQUVGOztHQUVHO0FBQ0ksTUFBTSxzQkFBc0IsR0FBdUMsQ0FBQyxNQUFNLEVBQUUsT0FBTyxFQUFFLEVBQUU7SUFDNUYsa0JBQWtCO0lBQ2xCLE1BQU0sR0FBRyxlQUFlLENBQUMsTUFBTSxFQUFFLE9BQU8sQ0FBQyxDQUFDO0lBRTFDLG1DQUFtQztJQUNuQyxNQUFNLEdBQUcsbUJBQW1CLENBQUMsTUFBTSxFQUFFLE9BQU8sQ0FBQyxDQUFDO0lBRTlDLHVDQUF1QztJQUN2QyxNQUFNLEdBQUcsaUJBQWlCLENBQUMsTUFBTSxFQUFFLE9BQU8sQ0FBQyxDQUFDO0lBRTVDLE9BQU8sTUFBTSxDQUFDO0FBQ2hCLENBQUMsQ0FBQztBQVhXLFFBQUEsc0JBQXNCLDBCQVdqQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7XG4gIENvbmZpZ1BsdWdpbixcbiAgd2l0aEFuZHJvaWRNYW5pZmVzdCxcbiAgd2l0aEFwcEJ1aWxkR3JhZGxlLFxuICB3aXRoUHJvamVjdEJ1aWxkR3JhZGxlLFxuICBBbmRyb2lkQ29uZmlnLFxufSBmcm9tICdAZXhwby9jb25maWctcGx1Z2lucyc7XG5cbmV4cG9ydCBpbnRlcmZhY2UgQW5kcm9pZFBsdWdpbk9wdGlvbnMge1xuICBlbmFibGVNTEtpdDogYm9vbGVhbjtcbiAgZW5hYmxlV2ViUlRDOiBib29sZWFuO1xufVxuXG4vKipcbiAqIEFkZCBjYW1lcmEgYW5kIG1pY3JvcGhvbmUgcGVybWlzc2lvbnMgdG8gQW5kcm9pZE1hbmlmZXN0LnhtbFxuICovXG5jb25zdCB3aXRoUGVybWlzc2lvbnM6IENvbmZpZ1BsdWdpbjxBbmRyb2lkUGx1Z2luT3B0aW9ucz4gPSAoY29uZmlnLCBfb3B0aW9ucykgPT4ge1xuICByZXR1cm4gd2l0aEFuZHJvaWRNYW5pZmVzdChjb25maWcsIChjb25maWcpID0+IHtcbiAgICBjb25zdCBtYW5pZmVzdCA9IGNvbmZpZy5tb2RSZXN1bHRzO1xuXG4gICAgLy8gRW5zdXJlIHBlcm1pc3Npb25zIGFycmF5IGV4aXN0c1xuICAgIGlmICghbWFuaWZlc3QubWFuaWZlc3RbJ3VzZXMtcGVybWlzc2lvbiddKSB7XG4gICAgICBtYW5pZmVzdC5tYW5pZmVzdFsndXNlcy1wZXJtaXNzaW9uJ10gPSBbXTtcbiAgICB9XG5cbiAgICBjb25zdCBwZXJtaXNzaW9ucyA9IG1hbmlmZXN0Lm1hbmlmZXN0Wyd1c2VzLXBlcm1pc3Npb24nXTtcblxuICAgIC8vIENhbWVyYSBwZXJtaXNzaW9uXG4gICAgY29uc3QgY2FtZXJhUGVybWlzc2lvbiA9ICdhbmRyb2lkLnBlcm1pc3Npb24uQ0FNRVJBJztcbiAgICBpZiAoIXBlcm1pc3Npb25zLnNvbWUoKHApID0+IHAuJD8uWydhbmRyb2lkOm5hbWUnXSA9PT0gY2FtZXJhUGVybWlzc2lvbikpIHtcbiAgICAgIHBlcm1pc3Npb25zLnB1c2goe1xuICAgICAgICAkOiB7ICdhbmRyb2lkOm5hbWUnOiBjYW1lcmFQZXJtaXNzaW9uIH0sXG4gICAgICB9KTtcbiAgICB9XG5cbiAgICAvLyBNaWNyb3Bob25lIHBlcm1pc3Npb25cbiAgICBjb25zdCBtaWNQZXJtaXNzaW9uID0gJ2FuZHJvaWQucGVybWlzc2lvbi5SRUNPUkRfQVVESU8nO1xuICAgIGlmICghcGVybWlzc2lvbnMuc29tZSgocCkgPT4gcC4kPy5bJ2FuZHJvaWQ6bmFtZSddID09PSBtaWNQZXJtaXNzaW9uKSkge1xuICAgICAgcGVybWlzc2lvbnMucHVzaCh7XG4gICAgICAgICQ6IHsgJ2FuZHJvaWQ6bmFtZSc6IG1pY1Blcm1pc3Npb24gfSxcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIC8vIENhbWVyYSBoYXJkd2FyZSBmZWF0dXJlXG4gICAgaWYgKCFtYW5pZmVzdC5tYW5pZmVzdFsndXNlcy1mZWF0dXJlJ10pIHtcbiAgICAgIG1hbmlmZXN0Lm1hbmlmZXN0Wyd1c2VzLWZlYXR1cmUnXSA9IFtdO1xuICAgIH1cblxuICAgIGNvbnN0IGZlYXR1cmVzID0gbWFuaWZlc3QubWFuaWZlc3RbJ3VzZXMtZmVhdHVyZSddO1xuICAgIGNvbnN0IGNhbWVyYUZlYXR1cmUgPSAnYW5kcm9pZC5oYXJkd2FyZS5jYW1lcmEnO1xuICAgIGlmICghZmVhdHVyZXMuc29tZSgoZikgPT4gZi4kPy5bJ2FuZHJvaWQ6bmFtZSddID09PSBjYW1lcmFGZWF0dXJlKSkge1xuICAgICAgZmVhdHVyZXMucHVzaCh7XG4gICAgICAgICQ6IHtcbiAgICAgICAgICAnYW5kcm9pZDpuYW1lJzogY2FtZXJhRmVhdHVyZSxcbiAgICAgICAgICAnYW5kcm9pZDpyZXF1aXJlZCc6ICdmYWxzZScsXG4gICAgICAgIH0sXG4gICAgICB9KTtcbiAgICB9XG5cbiAgICBjb25zdCBjYW1lcmFBdXRvRm9jdXMgPSAnYW5kcm9pZC5oYXJkd2FyZS5jYW1lcmEuYXV0b2ZvY3VzJztcbiAgICBpZiAoIWZlYXR1cmVzLnNvbWUoKGYpID0+IGYuJD8uWydhbmRyb2lkOm5hbWUnXSA9PT0gY2FtZXJhQXV0b0ZvY3VzKSkge1xuICAgICAgZmVhdHVyZXMucHVzaCh7XG4gICAgICAgICQ6IHtcbiAgICAgICAgICAnYW5kcm9pZDpuYW1lJzogY2FtZXJhQXV0b0ZvY3VzLFxuICAgICAgICAgICdhbmRyb2lkOnJlcXVpcmVkJzogJ2ZhbHNlJyxcbiAgICAgICAgfSxcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIHJldHVybiBjb25maWc7XG4gIH0pO1xufTtcblxuLyoqXG4gKiBBZGQgTUwgS2l0IGRlcGVuZGVuY3kgdG8gYXBwIGJ1aWxkLmdyYWRsZVxuICovXG5jb25zdCB3aXRoTUxLaXREZXBlbmRlbmN5OiBDb25maWdQbHVnaW48QW5kcm9pZFBsdWdpbk9wdGlvbnM+ID0gKGNvbmZpZywgb3B0aW9ucykgPT4ge1xuICBpZiAoIW9wdGlvbnMuZW5hYmxlTUxLaXQpIHtcbiAgICByZXR1cm4gY29uZmlnO1xuICB9XG5cbiAgcmV0dXJuIHdpdGhBcHBCdWlsZEdyYWRsZShjb25maWcsIChjb25maWcpID0+IHtcbiAgICBjb25zdCBidWlsZEdyYWRsZSA9IGNvbmZpZy5tb2RSZXN1bHRzO1xuXG4gICAgLy8gQ2hlY2sgaWYgTUwgS2l0IGlzIGFscmVhZHkgYWRkZWRcbiAgICBpZiAoIWJ1aWxkR3JhZGxlLmNvbnRlbnRzLmluY2x1ZGVzKCdjb20uZ29vZ2xlLm1sa2l0OmZhY2UtZGV0ZWN0aW9uJykpIHtcbiAgICAgIC8vIEFkZCBNTCBLaXQgZGVwZW5kZW5jeSBpbiBkZXBlbmRlbmNpZXMgYmxvY2tcbiAgICAgIGJ1aWxkR3JhZGxlLmNvbnRlbnRzID0gYnVpbGRHcmFkbGUuY29udGVudHMucmVwbGFjZShcbiAgICAgICAgL2RlcGVuZGVuY2llc1xccyp7LyxcbiAgICAgICAgYGRlcGVuZGVuY2llcyB7XG4gICAgLy8gU21hcnRDYW1lcmEgTUwgS2l0IEZhY2UgRGV0ZWN0aW9uXG4gICAgaW1wbGVtZW50YXRpb24gJ2NvbS5nb29nbGUubWxraXQ6ZmFjZS1kZXRlY3Rpb246MTYuMS41J2BcbiAgICAgICk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGNvbmZpZztcbiAgfSk7XG59O1xuXG4vKipcbiAqIEFkZCBwcm9ndWFyZCBydWxlcyBmb3IgTUwgS2l0XG4gKi9cbmNvbnN0IHdpdGhQcm9ndWFyZFJ1bGVzOiBDb25maWdQbHVnaW48QW5kcm9pZFBsdWdpbk9wdGlvbnM+ID0gKGNvbmZpZywgb3B0aW9ucykgPT4ge1xuICBpZiAoIW9wdGlvbnMuZW5hYmxlTUxLaXQpIHtcbiAgICByZXR1cm4gY29uZmlnO1xuICB9XG5cbiAgcmV0dXJuIHdpdGhBcHBCdWlsZEdyYWRsZShjb25maWcsIChjb25maWcpID0+IHtcbiAgICBjb25zdCBidWlsZEdyYWRsZSA9IGNvbmZpZy5tb2RSZXN1bHRzO1xuXG4gICAgLy8gQ2hlY2sgaWYgcHJvZ3VhcmQgaXMgYWxyZWFkeSBjb25maWd1cmVkIGZvciBNTCBLaXRcbiAgICBpZiAoIWJ1aWxkR3JhZGxlLmNvbnRlbnRzLmluY2x1ZGVzKCdtbGtpdC1wcm9ndWFyZC1ydWxlcy5wcm8nKSkge1xuICAgICAgLy8gQWRkIHByb2d1YXJkIGNvbmZpZ3VyYXRpb24gaW4gcmVsZWFzZSBidWlsZCB0eXBlXG4gICAgICBidWlsZEdyYWRsZS5jb250ZW50cyA9IGJ1aWxkR3JhZGxlLmNvbnRlbnRzLnJlcGxhY2UoXG4gICAgICAgIC9idWlsZFR5cGVzXFxzKntcXHMqcmVsZWFzZVxccyp7LyxcbiAgICAgICAgYGJ1aWxkVHlwZXMge1xuICAgICAgICByZWxlYXNlIHtcbiAgICAgICAgICAgIC8vIFNtYXJ0Q2FtZXJhIE1MIEtpdCBQcm9ndWFyZCBydWxlc1xuICAgICAgICAgICAgcHJvZ3VhcmRGaWxlcyBnZXREZWZhdWx0UHJvZ3VhcmRGaWxlKCdwcm9ndWFyZC1hbmRyb2lkLnR4dCcpLCAncHJvZ3VhcmQtcnVsZXMucHJvJ2BcbiAgICAgICk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGNvbmZpZztcbiAgfSk7XG59O1xuXG4vKipcbiAqIEFuZHJvaWQgY29uZmlndXJhdGlvbiBmb3IgcmVhY3QtbmF0aXZlLXNtYXJ0LWNhbWVyYVxuICovXG5leHBvcnQgY29uc3Qgd2l0aFNtYXJ0Q2FtZXJhQW5kcm9pZDogQ29uZmlnUGx1Z2luPEFuZHJvaWRQbHVnaW5PcHRpb25zPiA9IChjb25maWcsIG9wdGlvbnMpID0+IHtcbiAgLy8gQWRkIHBlcm1pc3Npb25zXG4gIGNvbmZpZyA9IHdpdGhQZXJtaXNzaW9ucyhjb25maWcsIG9wdGlvbnMpO1xuXG4gIC8vIEFkZCBNTCBLaXQgZGVwZW5kZW5jeSBpZiBlbmFibGVkXG4gIGNvbmZpZyA9IHdpdGhNTEtpdERlcGVuZGVuY3koY29uZmlnLCBvcHRpb25zKTtcblxuICAvLyBBZGQgcHJvZ3VhcmQgcnVsZXMgaWYgTUwgS2l0IGVuYWJsZWRcbiAgY29uZmlnID0gd2l0aFByb2d1YXJkUnVsZXMoY29uZmlnLCBvcHRpb25zKTtcblxuICByZXR1cm4gY29uZmlnO1xufTtcblxuIl19
@@ -0,0 +1,11 @@
1
+ import { ConfigPlugin } from '@expo/config-plugins';
2
+ export interface IOSPluginOptions {
3
+ cameraPermissionText: string;
4
+ microphonePermissionText: string;
5
+ enableMLKit: boolean;
6
+ enableWebRTC: boolean;
7
+ }
8
+ /**
9
+ * iOS configuration for react-native-smart-camera
10
+ */
11
+ export declare const withSmartCameraIOS: ConfigPlugin<IOSPluginOptions>;