capacitor-camera-view 2.4.0 → 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. package/CapacitorCameraView.podspec +1 -1
  2. package/Package.swift +1 -1
  3. package/README.md +341 -49
  4. package/android/build.gradle +0 -1
  5. package/android/src/main/AndroidManifest.xml +0 -1
  6. package/android/src/main/java/com/michaelwolz/capacitorcameraview/CameraError.kt +42 -0
  7. package/android/src/main/java/com/michaelwolz/capacitorcameraview/CameraView.kt +945 -207
  8. package/android/src/main/java/com/michaelwolz/capacitorcameraview/CameraViewPlugin.kt +87 -43
  9. package/android/src/main/java/com/michaelwolz/capacitorcameraview/model/BarcodeDetectionResult.kt +28 -2
  10. package/android/src/main/java/com/michaelwolz/capacitorcameraview/model/CameraDevice.kt +6 -1
  11. package/android/src/main/java/com/michaelwolz/capacitorcameraview/model/CameraSessionConfiguration.kt +15 -1
  12. package/android/src/main/java/com/michaelwolz/capacitorcameraview/model/TorchModeState.kt +15 -0
  13. package/android/src/main/java/com/michaelwolz/capacitorcameraview/model/WebBoundingRect.kt +1 -1
  14. package/android/src/main/java/com/michaelwolz/capacitorcameraview/utils.kt +73 -19
  15. package/dist/docs.json +475 -30
  16. package/dist/esm/definitions.d.ts +478 -26
  17. package/dist/esm/definitions.js.map +1 -1
  18. package/dist/esm/utils.d.ts +59 -15
  19. package/dist/esm/utils.js +79 -38
  20. package/dist/esm/utils.js.map +1 -1
  21. package/dist/esm/web.d.ts +191 -13
  22. package/dist/esm/web.js +624 -141
  23. package/dist/esm/web.js.map +1 -1
  24. package/dist/plugin.cjs.js +711 -179
  25. package/dist/plugin.cjs.js.map +1 -1
  26. package/dist/plugin.js +711 -179
  27. package/dist/plugin.js.map +1 -1
  28. package/ios/Sources/CameraViewPlugin/CameraError.swift +147 -2
  29. package/ios/Sources/CameraViewPlugin/CameraEvents.swift +41 -19
  30. package/ios/Sources/CameraViewPlugin/CameraSessionConfiguration.swift +29 -1
  31. package/ios/Sources/CameraViewPlugin/CameraViewManager+BarcodeScan.swift +78 -23
  32. package/ios/Sources/CameraViewPlugin/CameraViewManager+DeferredStart.swift +37 -0
  33. package/ios/Sources/CameraViewPlugin/CameraViewManager+Focus.swift +131 -0
  34. package/ios/Sources/CameraViewPlugin/CameraViewManager+Lifecycle.swift +156 -0
  35. package/ios/Sources/CameraViewPlugin/CameraViewManager+PhotoCapture.swift +73 -41
  36. package/ios/Sources/CameraViewPlugin/CameraViewManager+ResolutionSelection.swift +57 -0
  37. package/ios/Sources/CameraViewPlugin/CameraViewManager+Rotation.swift +195 -0
  38. package/ios/Sources/CameraViewPlugin/CameraViewManager+VideoDataOutput.swift +24 -12
  39. package/ios/Sources/CameraViewPlugin/CameraViewManager+VideoRecording.swift +22 -73
  40. package/ios/Sources/CameraViewPlugin/CameraViewManager+Zoom.swift +113 -0
  41. package/ios/Sources/CameraViewPlugin/CameraViewManager.swift +450 -403
  42. package/ios/Sources/CameraViewPlugin/CameraViewPlugin.swift +98 -65
  43. package/ios/Sources/CameraViewPlugin/Utils.swift +61 -7
  44. package/package.json +25 -9
@@ -1 +1 @@
1
- {"version":3,"file":"web.js","sourceRoot":"","sources":["../../src/web.ts"],"names":[],"mappings":"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","sourcesContent":["import { WebPlugin } from '@capacitor/core';\n\nimport type {\n CameraSessionConfiguration,\n CameraViewPlugin,\n CameraPermissionType,\n GetAvailableDevicesResponse,\n GetFlashModeResponse,\n GetSupportedFlashModesResponse,\n GetTorchModeResponse,\n GetZoomResponse,\n IsTorchAvailableResponse,\n IsRunningResponse,\n PermissionStatus,\n CaptureResponse,\n FlashMode,\n CaptureOptions,\n VideoRecordingOptions,\n VideoRecordingResponse,\n BarcodeType,\n} from './definitions';\nimport { calculateVisibleArea, canvasToBase64, drawVisibleAreaToCanvas, transformBarcodeBoundingBox } from './utils';\n\nexport const BARCODE_TYPE_TO_WEB_FORMAT: Readonly<Record<BarcodeType, BarcodeFormat | null>> = {\n qr: 'qr_code',\n code128: 'code_128',\n code39: 'code_39',\n code39Mod43: null,\n code93: 'code_93',\n ean8: 'ean_8',\n ean13: 'ean_13',\n interleaved2of5: 'itf',\n itf14: 'itf',\n pdf417: 'pdf417',\n aztec: 'aztec',\n dataMatrix: 'data_matrix',\n upce: 'upc_e',\n} satisfies Record<BarcodeType, BarcodeFormat | null>;\n\n/**\n * Web implementation of the CameraViewPlugin.\n * Optimized for performance and battery efficiency.\n */\nexport class CameraViewWeb extends WebPlugin implements CameraViewPlugin {\n // DOM elements\n private videoElement: HTMLVideoElement | null = null;\n private canvasElement: HTMLCanvasElement | null = null;\n\n // Stream state\n private stream: MediaStream | null = null;\n #isRunning = false;\n\n // Configuration state\n private currentCamera = 'environment'; // Default to back camera\n private currentZoom = 1.0;\n private currentFlashMode: FlashMode = 'off';\n\n // Barcode detection support\n private barcodeDetectionSupported = false;\n private barcodeDetector: BarcodeDetector | null = null;\n\n // Recording state\n private mediaRecorder: MediaRecorder | null = null;\n private recordedChunks: Blob[] = [];\n private recordingAudioTrack: MediaStreamTrack | null = null;\n private recordingResolve: ((response: VideoRecordingResponse) => void) | null = null;\n private recordingReject: ((error: Error) => void) | null = null;\n\n constructor() {\n super();\n this.checkBarcodeDetectionSupport();\n }\n\n /**\n * Start the camera with the given configuration\n */\n async start(options?: CameraSessionConfiguration): Promise<void> {\n if (this.#isRunning) {\n return;\n }\n\n const permissionStatus = await this.requestPermissions();\n if (permissionStatus.camera !== 'granted') {\n throw new Error('Camera permission was not granted');\n }\n\n try {\n // Set up video element if it doesn't exist\n if (!this.videoElement) {\n await this.setupVideoElement(options?.containerElementId);\n }\n\n // Set up video constraints based on options\n const videoConstraints: MediaTrackConstraints = {};\n\n // Prefer deviceId if specified\n if (options?.deviceId) {\n videoConstraints.deviceId = { exact: options.deviceId };\n // Remember the current camera mode (though we're using a specific device)\n this.currentCamera = options?.position === 'front' ? 'user' : 'environment';\n } else {\n // Fall back to facing mode\n const facingMode = options?.position === 'front' ? 'user' : 'environment';\n this.currentCamera = facingMode;\n videoConstraints.facingMode = facingMode;\n }\n\n const constraints: MediaStreamConstraints = {\n video: videoConstraints,\n audio: false,\n };\n\n this.stream = await navigator.mediaDevices.getUserMedia(constraints);\n\n if (this.videoElement) {\n this.videoElement.srcObject = this.stream;\n this.videoElement.play();\n this.#isRunning = true;\n\n // If barcode detection is enabled and supported, start detection\n if (options?.enableBarcodeDetection) {\n await this.checkBarcodeDetectionSupport();\n\n if (this.barcodeDetectionSupported) {\n await this.configureBarcodeDetector(options?.barcodeTypes);\n this.startBarcodeDetection();\n }\n }\n }\n } catch (err) {\n throw new Error(`Failed to start camera: ${this.formatError(err)}`);\n }\n }\n\n /**\n * Stop the camera and release resources\n */\n async stop(): Promise<void> {\n if (!this.#isRunning) {\n return;\n }\n\n try {\n // Stop any active recording\n if (this.mediaRecorder && this.mediaRecorder.state !== 'inactive') {\n // Reject any pending stopRecording promise since we're force-stopping\n this.recordingReject?.(new Error('Camera session stopped while recording'));\n this.recordingResolve = null;\n this.recordingReject = null;\n this.mediaRecorder.stop();\n this.mediaRecorder = null;\n }\n this.recordedChunks = [];\n if (this.recordingAudioTrack) {\n this.recordingAudioTrack.stop();\n this.recordingAudioTrack = null;\n }\n\n // Stop all tracks in the stream\n if (this.stream) {\n this.stream.getTracks().forEach((track) => track.stop());\n this.stream = null;\n }\n\n // Clear video source\n if (this.videoElement) {\n this.videoElement = null;\n }\n\n this.#isRunning = false;\n } catch (err) {\n throw new Error(`Failed to stop camera: ${this.formatError(err)}`);\n }\n }\n\n /**\n * Check if the camera is currently running\n */\n async isRunning(): Promise<IsRunningResponse> {\n return { isRunning: this.#isRunning };\n }\n\n /**\n * Capture a photo using the camera and return it as a base64-encoded JPEG image.\n * Preserves what the user actually sees in the UI, including cropping from object-fit: cover.\n */\n async capture<T extends CaptureOptions>(options: T): Promise<CaptureResponse<T>> {\n const videoElement = this.videoElement;\n\n if (!this.#isRunning || !videoElement) {\n throw new Error('Camera is not running');\n }\n\n try {\n const canvas = this.getCanvasElement();\n const visibleArea = calculateVisibleArea(videoElement);\n\n drawVisibleAreaToCanvas(canvas, videoElement, visibleArea);\n\n const quality = Math.min(1.0, Math.max(0.1, options.quality / 100));\n\n if (options.saveToFile) {\n // Create a blob from canvas and return a blob URL.\n // `path` is native-only (no filesystem path on web), so it is omitted here.\n return new Promise((resolve, reject) => {\n canvas.toBlob(\n (blob) => {\n if (!blob) {\n reject(new Error('Failed to create blob from canvas'));\n return;\n }\n\n const url = URL.createObjectURL(blob);\n resolve({ webPath: url } as CaptureResponse<T>);\n },\n 'image/jpeg',\n quality,\n );\n });\n } else {\n // Return base64 data\n const base64Data = canvasToBase64(canvas, quality);\n return { photo: base64Data } as CaptureResponse<T>;\n }\n } catch (err) {\n throw new Error(`Failed to capture photo: ${this.formatError(err)}`);\n }\n }\n\n /**\n * Web implementation already uses images from the video stream, so this is the same as `capture()`\n */\n async captureSample<T extends CaptureOptions>(options: T): Promise<CaptureResponse<T>> {\n return this.capture(options);\n }\n\n /**\n * Start recording video using MediaRecorder API\n */\n async startRecording(options?: VideoRecordingOptions): Promise<void> {\n if (!this.#isRunning || !this.videoElement) {\n throw new Error('Camera is not running');\n }\n\n if (this.mediaRecorder) {\n throw new Error('Recording is already in progress');\n }\n\n try {\n let stream = this.stream;\n\n // If audio is requested, get a new stream with audio track\n if (options?.enableAudio && stream) {\n const audioStream = await navigator.mediaDevices.getUserMedia({ audio: true });\n const audioTrack = audioStream.getAudioTracks()[0];\n this.recordingAudioTrack = audioTrack;\n const videoTracks = stream.getVideoTracks();\n stream = new MediaStream([...videoTracks, audioTrack]);\n }\n\n if (!stream) {\n throw new Error('No camera stream available');\n }\n\n this.recordedChunks = [];\n\n const mimeType = ['video/webm;codecs=vp9', 'video/webm', 'video/mp4'].find((type) =>\n MediaRecorder.isTypeSupported(type),\n );\n\n if (!mimeType) {\n throw new Error('No supported video recording format found');\n }\n\n this.mediaRecorder = new MediaRecorder(stream, { mimeType });\n\n this.mediaRecorder.ondataavailable = (event) => {\n if (event.data && event.data.size > 0) {\n this.recordedChunks.push(event.data);\n }\n };\n\n this.mediaRecorder.onstop = () => {\n // Stop audio track if it was added for recording\n if (this.recordingAudioTrack) {\n this.recordingAudioTrack.stop();\n this.recordingAudioTrack = null;\n }\n const blob = new Blob(this.recordedChunks, { type: mimeType });\n const url = URL.createObjectURL(blob);\n this.recordedChunks = [];\n this.mediaRecorder = null;\n this.recordingResolve?.({ webPath: url });\n this.recordingResolve = null;\n this.recordingReject = null;\n };\n\n this.mediaRecorder.onerror = (event) => {\n if (this.recordingAudioTrack) {\n this.recordingAudioTrack.stop();\n this.recordingAudioTrack = null;\n }\n this.mediaRecorder = null;\n this.recordedChunks = [];\n const errorMessage = (event as ErrorEvent).error?.message ?? 'Unknown recording error';\n this.recordingReject?.(new Error('Recording error: ' + errorMessage));\n this.recordingResolve = null;\n this.recordingReject = null;\n };\n\n this.mediaRecorder.start(100); // Collect data in 100ms chunks\n } catch (err) {\n if (this.recordingAudioTrack) {\n this.recordingAudioTrack.stop();\n this.recordingAudioTrack = null;\n }\n this.mediaRecorder = null;\n this.recordedChunks = [];\n throw new Error(`Failed to start recording: ${this.formatError(err)}`);\n }\n }\n\n /**\n * Stop the current video recording\n */\n async stopRecording(): Promise<VideoRecordingResponse> {\n if (!this.mediaRecorder) {\n throw new Error('No recording is in progress');\n }\n\n return new Promise<VideoRecordingResponse>((resolve, reject) => {\n this.recordingResolve = resolve;\n this.recordingReject = reject;\n this.mediaRecorder?.stop();\n });\n }\n\n /**\n * Flip between front and back camera\n */\n public async flipCamera(): Promise<void> {\n if (!this.#isRunning) {\n throw new Error('Camera is not running');\n }\n\n try {\n // Switch current camera\n this.currentCamera = this.currentCamera === 'user' ? 'environment' : 'user';\n\n // Stop current stream\n if (this.stream) {\n this.stream.getTracks().forEach((track) => track.stop());\n }\n\n // Restart with new facing mode\n const constraints: MediaStreamConstraints = {\n video: {\n facingMode: this.currentCamera,\n },\n audio: false,\n };\n\n this.stream = await navigator.mediaDevices.getUserMedia(constraints);\n\n if (this.videoElement) {\n this.videoElement.srcObject = this.stream;\n }\n } catch (err) {\n throw new Error(`Failed to flip camera: ${this.formatError(err)}`);\n }\n }\n\n /**\n * Get available camera devices\n */\n public async getAvailableDevices(): Promise<GetAvailableDevicesResponse> {\n try {\n const devices = await navigator.mediaDevices.enumerateDevices();\n const videoDevices = devices.filter((device) => device.kind === 'videoinput');\n\n return {\n devices: videoDevices.map((device) => ({\n id: device.deviceId,\n name: device.label || `Camera ${device.deviceId.substring(0, 5)}`,\n position: device.label.toLowerCase().includes('front') ? 'front' : 'back',\n })),\n };\n } catch (err) {\n console.error('Failed to get available devices', err);\n return { devices: [] };\n }\n }\n\n /**\n * Get current zoom information (web has limited zoom support)\n */\n public async getZoom(): Promise<GetZoomResponse> {\n // Web has limited zoom capabilities in most browsers,\n // we fake zoomin by scaling the video element\n return {\n min: 1.0,\n max: 3.0,\n current: this.currentZoom,\n };\n }\n\n /**\n * Set zoom level (limited support in web)\n */\n public async setZoom(options: { level: number; ramp?: boolean }): Promise<void> {\n // Store the requested zoom level\n this.currentZoom = options.level;\n\n // Apply visual zoom using CSS transform when native zoom isn't supported\n if (this.videoElement) {\n this.videoElement.style.transition = options.ramp ? 'transform 0.2s ease-in-out' : 'none';\n const scale = Math.max(1.0, Math.min(options.level, 3.0)); // Limit scale to reasonable bounds\n this.videoElement.style.transform = `scale(${scale})`;\n this.videoElement.style.transformOrigin = 'center';\n }\n }\n\n /**\n * Get current flash mode\n */\n public async getFlashMode(): Promise<GetFlashModeResponse> {\n return { flashMode: this.currentFlashMode };\n }\n\n /**\n * Get supported flash modes\n */\n public async getSupportedFlashModes(): Promise<GetSupportedFlashModesResponse> {\n // Web has limited flash control\n return { flashModes: ['off'] };\n }\n\n /**\n * Set flash mode (limited support in web)\n */\n public async setFlashMode(options: { mode: FlashMode }): Promise<void> {\n this.currentFlashMode = options.mode;\n console.warn('Flash mode control is not fully supported in the web implementation');\n }\n\n /**\n * Check if torch is available (not supported in web)\n */\n public async isTorchAvailable(): Promise<IsTorchAvailableResponse> {\n // Torch is not supported in web implementation\n return { available: false };\n }\n\n /**\n * Get torch mode (not supported in web)\n */\n public async getTorchMode(): Promise<GetTorchModeResponse> {\n // Torch is not supported in web implementation\n return { enabled: false, level: 0.0 };\n }\n\n /**\n * Set torch mode (not supported in web)\n */\n public async setTorchMode(): Promise<void> {\n // Torch is not supported in web implementation\n throw this.unimplemented('Torch control is not supported in web implementation.');\n }\n\n /**\n * Check camera and microphone permission without requesting\n */\n public async checkPermissions(): Promise<PermissionStatus> {\n try {\n // Use Permissions API if available\n if (navigator.permissions) {\n const [cameraResult, microphoneResult] = await Promise.all([\n navigator.permissions.query({ name: 'camera' as PermissionName }),\n navigator.permissions.query({ name: 'microphone' as PermissionName }),\n ]);\n return {\n camera: cameraResult.state === 'granted' ? 'granted' : cameraResult.state === 'denied' ? 'denied' : 'prompt',\n microphone:\n microphoneResult.state === 'granted'\n ? 'granted'\n : microphoneResult.state === 'denied'\n ? 'denied'\n : 'prompt',\n };\n }\n\n // If Permissions API is not available, fall back to checking the active stream\n return {\n camera: this.stream ? 'granted' : 'prompt',\n microphone: 'prompt',\n };\n } catch (err) {\n // If permissions API is not supported or fails\n return {\n camera: 'prompt',\n microphone: 'prompt',\n };\n }\n }\n\n /**\n * Request camera and/or microphone permissions from the user.\n * By default, only camera permission is requested.\n */\n public async requestPermissions(options?: { permissions?: CameraPermissionType[] }): Promise<PermissionStatus> {\n const permissions = options?.permissions ?? ['camera'];\n const result: PermissionStatus = { camera: 'prompt', microphone: 'prompt' };\n\n // Request camera permission if included\n if (permissions.includes('camera')) {\n try {\n const stream = await navigator.mediaDevices.getUserMedia({ video: true });\n stream.getTracks().forEach((track) => track.stop());\n result.camera = 'granted';\n } catch {\n result.camera = 'denied';\n }\n } else {\n // Still report current status even if not requesting\n result.camera = (await this.checkPermissions()).camera;\n }\n\n // Request microphone permission only if explicitly included\n if (permissions.includes('microphone')) {\n try {\n const stream = await navigator.mediaDevices.getUserMedia({ audio: true });\n stream.getTracks().forEach((track) => track.stop());\n result.microphone = 'granted';\n } catch {\n result.microphone = 'denied';\n }\n } else {\n result.microphone = (await this.checkPermissions()).microphone;\n }\n\n return result;\n }\n\n /**\n * Start barcode detection if supported\n */\n private async startBarcodeDetection() {\n const barcodeDetector = this.barcodeDetector;\n const videoElement = this.videoElement;\n\n if (!this.barcodeDetectionSupported || !barcodeDetector || !videoElement) {\n return;\n }\n\n // Make sure video is fully loaded before starting detection\n if (videoElement.readyState < 2) {\n await new Promise<void>((resolve) => {\n const loadHandler = () => {\n videoElement.removeEventListener('loadeddata', loadHandler);\n resolve();\n };\n videoElement.addEventListener('loadeddata', loadHandler);\n });\n }\n\n // Add throttling to reduce CPU usage\n let lastDetectionTime = 0;\n const minTimeBetweenDetections = 100; // ms\n\n // Set up periodic frame analysis for barcode detection\n const detectFrame = async () => {\n if (!this.#isRunning || !videoElement || !barcodeDetector) {\n return;\n }\n\n const now = Date.now();\n if (now - lastDetectionTime >= minTimeBetweenDetections) {\n try {\n const barcodes = await barcodeDetector.detect(videoElement);\n lastDetectionTime = now;\n\n if (barcodes.length > 0) {\n const barcode = barcodes[0];\n\n // Transform barcode coordinates using the utility function\n const boundingRect = transformBarcodeBoundingBox(barcode.boundingBox, videoElement);\n\n this.notifyListeners('barcodeDetected', {\n value: barcode.rawValue,\n type: barcode.format.toLowerCase(),\n boundingRect,\n });\n }\n } catch (err) {\n console.error('Barcode detection error', err);\n }\n }\n\n if (this.#isRunning) {\n requestAnimationFrame(detectFrame);\n }\n };\n\n requestAnimationFrame(detectFrame);\n }\n\n /**\n * Clean up resources when the plugin is disposed\n */\n public async handleOnDestroy(): Promise<void> {\n await this.stop();\n\n // Remove elements from DOM\n if (this.videoElement?.parentNode) {\n this.videoElement.parentNode.removeChild(this.videoElement);\n this.videoElement = null;\n }\n\n if (this.canvasElement) {\n this.canvasElement = null;\n }\n\n this.barcodeDetector = null;\n }\n\n /**\n * Check if barcode detection is supported in this browser\n */\n private async checkBarcodeDetectionSupport() {\n if ('BarcodeDetector' in window) {\n try {\n this.barcodeDetector = new BarcodeDetector();\n this.barcodeDetectionSupported = true;\n } catch (e) {\n console.warn('BarcodeDetector is not supported by this browser.');\n this.barcodeDetectionSupported = false;\n }\n }\n }\n\n /**\n * Configure the barcode detector with requested barcode formats.\n * Unsupported formats are ignored and logged.\n */\n private async configureBarcodeDetector(barcodeTypes?: BarcodeType[]): Promise<void> {\n if (!this.barcodeDetectionSupported) {\n return;\n }\n\n if (!barcodeTypes?.length) {\n this.barcodeDetector = new BarcodeDetector();\n return;\n }\n\n const requestedFormats = barcodeTypes\n .map((barcodeType) => {\n const webFormat = BARCODE_TYPE_TO_WEB_FORMAT[barcodeType];\n if (!webFormat) {\n console.warn(`[CameraView] Barcode type \"${barcodeType}\" is not supported by the web BarcodeDetector API.`);\n }\n return webFormat;\n })\n .filter((format): format is BarcodeFormat => format !== null);\n\n if (!requestedFormats.length) {\n console.warn(\n '[CameraView] No requested barcode types are supported on web. Falling back to all supported formats.',\n );\n this.barcodeDetector = new BarcodeDetector();\n return;\n }\n\n const uniqueRequestedFormats = Array.from(new Set(requestedFormats));\n\n try {\n const supportedFormats = await BarcodeDetector.getSupportedFormats();\n const configuredFormats = uniqueRequestedFormats.filter((format) => supportedFormats.includes(format));\n const ignoredFormats = uniqueRequestedFormats.filter((format) => !supportedFormats.includes(format));\n\n if (ignoredFormats.length) {\n console.warn(\n `[CameraView] Ignoring unsupported barcode formats for this browser: ${ignoredFormats.join(', ')}.`,\n );\n }\n\n if (!configuredFormats.length) {\n console.warn(\n '[CameraView] No requested barcode formats are available in this browser. Falling back to all supported formats.',\n );\n this.barcodeDetector = new BarcodeDetector();\n return;\n }\n\n this.barcodeDetector = new BarcodeDetector({ formats: configuredFormats });\n } catch (error) {\n console.warn(\n '[CameraView] Failed to resolve supported barcode formats; falling back to unfiltered detector.',\n error,\n );\n this.barcodeDetector = new BarcodeDetector();\n }\n }\n\n /**\n * Set up the video element for the camera view\n */\n private async setupVideoElement(containerElementId?: string) {\n this.videoElement = document.createElement('video');\n this.videoElement.playsInline = true;\n this.videoElement.autoplay = true;\n this.videoElement.muted = true;\n this.videoElement.style.width = '100%';\n this.videoElement.style.height = '100%';\n this.videoElement.style.objectFit = 'cover';\n\n // If a container ID is provided, find that element and append the video to it\n if (containerElementId) {\n const container = document.getElementById(containerElementId);\n if (!container) {\n throw new Error(`Container element with ID ${containerElementId} not found`);\n }\n container.appendChild(this.videoElement);\n } else {\n // Otherwise, append to body as fallback\n document.body.appendChild(this.videoElement);\n }\n }\n\n /**\n * Ensures canvas element exists and returns it\n */\n private getCanvasElement(): HTMLCanvasElement {\n if (!this.canvasElement) {\n this.canvasElement = document.createElement('canvas');\n }\n return this.canvasElement;\n }\n\n /**\n * Format error message\n */\n private formatError(err: unknown): string {\n return err instanceof Error ? err.message : String(err);\n }\n}\n"]}
1
+ {"version":3,"file":"web.js","sourceRoot":"","sources":["../../src/web.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AA0B5C,OAAO,EACL,gBAAgB,EAChB,sBAAsB,EACtB,oBAAoB,EACpB,cAAc,EACd,uBAAuB,EACvB,2BAA2B,GAC5B,MAAM,SAAS,CAAC;AAEjB;;;;GAIG;AACH,MAAM,CAAC,MAAM,6BAA6B,GAAG,GAAG,CAAC;AAEjD;;;;GAIG;AACH,MAAM,CAAC,MAAM,kCAAkC,GAAG,EAAE,CAAC;AAErD;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,8BAA8B,GAAG,IAAI,CAAC;AAEnD;;;;;;;;GAQG;AACH,MAAM,CAAC,MAAM,2BAA2B,GAAG,IAAI,CAAC;AAChD,MAAM,CAAC,MAAM,4BAA4B,GAAG,IAAI,CAAC;AAEjD;;;;GAIG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG,GAAG,CAAC;AACtC,MAAM,CAAC,MAAM,kBAAkB,GAAG,GAAG,CAAC;AAgBtC,MAAM,CAAC,MAAM,0BAA0B,GAAG;IACxC,EAAE,EAAE,SAAS;IACb,OAAO,EAAE,UAAU;IACnB,MAAM,EAAE,SAAS;IACjB,WAAW,EAAE,IAAI;IACjB,MAAM,EAAE,SAAS;IACjB,OAAO,EAAE,SAAS;IAClB,IAAI,EAAE,OAAO;IACb,KAAK,EAAE,QAAQ;IACf,eAAe,EAAE,KAAK;IACtB,KAAK,EAAE,KAAK;IACZ,MAAM,EAAE,QAAQ;IAChB,KAAK,EAAE,OAAO;IACd,UAAU,EAAE,aAAa;IACzB,IAAI,EAAE,OAAO;IACb,IAAI,EAAE,OAAO;CACsC,CAAC;AAEtD;;;;;;;;;GASG;AACH,MAAM,CAAC,MAAM,0BAA0B,GAA0D,MAAM,CAAC,OAAO,CAC7G,0BAA0B,CAC3B,CAAC,MAAM,CAA8C,CAAC,GAAG,EAAE,CAAC,WAAW,EAAE,SAAS,CAAC,EAAE,EAAE;IACtF,IAAI,SAAS,EAAE,CAAC;QACd,GAAG,CAAC,SAAS,CAAC,GAAG,WAA0B,CAAC;IAC9C,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC,EAAE,EAAE,CAAC,CAAC;AAEP;;;;;;;;;GASG;AACH,MAAM,OAAO,eAAgB,SAAQ,KAAK;IAGxC,YAAY,OAAe,EAAE,IAAqB;QAChD,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,iBAAiB,CAAC;QAC9B,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;IACnB,CAAC;CACF;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,6BAA6B,CAAC,GAAY,EAAE,IAA6B;IACvF,IAAI,GAAG,YAAY,YAAY,EAAE,CAAC;QAChC,QAAQ,GAAG,CAAC,IAAI,EAAE,CAAC;YACjB,KAAK,iBAAiB;gBACpB,OAAO,mBAAmB,CAAC;YAC7B,KAAK,eAAe;gBAClB,OAAO,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,oBAAoB,CAAC,CAAC,CAAC,0BAA0B,CAAC;YAC/E,KAAK,kBAAkB;gBACrB,OAAO,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,6BAA6B,CAAC;QAC/E,CAAC;IACH,CAAC;IACD,OAAO,eAAe,CAAC;AACzB,CAAC;AAED;;;GAGG;AACH,MAAM,OAAO,aAAc,SAAQ,SAAS;IAsD1C;QACE,KAAK,EAAE,CAAC;QAtDV,eAAe;QACP,iBAAY,GAA4B,IAAI,CAAC;QAC7C,kBAAa,GAA6B,IAAI,CAAC;QAEvD,eAAe;QACP,WAAM,GAAuB,IAAI,CAAC;QAC1C,mCAAa,KAAK,EAAC;QAEnB,sBAAsB;QACd,kBAAa,GAAG,aAAa,CAAC,CAAC,yBAAyB;QACxD,gBAAW,GAAG,GAAG,CAAC;QAC1B,sEAAsE;QACtE,2EAA2E;QAC3E,wEAAwE;QACxE,qBAAqB;QACb,oBAAe,GAAG,KAAK,CAAC;QACxB,qBAAgB,GAAc,KAAK,CAAC;QAC5C,0EAA0E;QAC1E,4EAA4E;QAC5E,2EAA2E;QAC3E,+DAA+D;QAC/D,+CAA+C;QACvC,uBAAkB,GAA6B,IAAI,CAAC;QAC5D,yEAAyE;QACzE,6EAA6E;QAC7E,4EAA4E;QAC5E,sCAAsC;QAC9B,4BAAuB,GAAqB,OAAO,CAAC;QAC5D,sEAAsE;QACtE,wEAAwE;QACxE,kDAAkD;QAC1C,iCAA4B,GAA0B,EAAE,CAAC;QAEjE,4BAA4B;QACpB,8BAAyB,GAAG,KAAK,CAAC;QAClC,oBAAe,GAA2B,IAAI,CAAC;QAEvD,4EAA4E;QAC5E,2EAA2E;QAC3E,sEAAsE;QAC9D,oCAA+B,GAA2B,IAAI,CAAC;QACvE,yEAAyE;QACzE,wEAAwE;QACxE,YAAY;QACJ,4BAAuB,GAAkB,IAAI,CAAC;QAEtD,kBAAkB;QACV,kBAAa,GAAyB,IAAI,CAAC;QAC3C,mBAAc,GAAW,EAAE,CAAC;QAC5B,wBAAmB,GAA4B,IAAI,CAAC;QACpD,qBAAgB,GAAwD,IAAI,CAAC;QAC7E,oBAAe,GAAoC,IAAI,CAAC;QAI9D,IAAI,CAAC,4BAA4B,EAAE,CAAC;IACtC,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,KAAK,CAAC,OAAoC;;QAC9C,wEAAwE;QACxE,qEAAqE;QACrE,yEAAyE;QACzE,qEAAqE;QACrE,IAAI,uBAAA,IAAI,gCAAW,EAAE,CAAC;YACpB,MAAM,IAAI,eAAe,CAAC,uDAAuD,EAAE,yBAAyB,CAAC,CAAC;QAChH,CAAC;QAED,IAAI,CAAC;YACH,2CAA2C;YAC3C,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,CAAC;gBACvB,MAAM,IAAI,CAAC,iBAAiB,CAAC,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,kBAAkB,CAAC,CAAC;YAC5D,CAAC;QACH,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,uEAAuE;YACvE,qEAAqE;YACrE,oDAAoD;YACpD,MAAM,IAAI,eAAe,CAAC,2BAA2B,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,EAAE,EAAE,qBAAqB,CAAC,CAAC;QACvG,CAAC;QAED,yEAAyE;QACzE,6EAA6E;QAC7E,4EAA4E;QAC5E,IAAI,CAAC,uBAAuB,GAAG,MAAA,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,gBAAgB,mCAAI,OAAO,CAAC;QACpE,IAAI,IAAI,CAAC,YAAY,EAAE,CAAC;YACtB,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,SAAS,GAAG,IAAI,CAAC,uBAAuB,KAAK,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC;QACnG,CAAC;QAED,4CAA4C;QAC5C,IAAI,CAAC,kBAAkB,GAAG,MAAA,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,WAAW,mCAAI,IAAI,CAAC;QACvD,IAAI,CAAC,4BAA4B,GAAG,IAAI,CAAC,0BAA0B,CAAC,OAAO,CAAC,CAAC;QAC7E,MAAM,gBAAgB,qBACjB,IAAI,CAAC,4BAA4B,CACrC,CAAC;QAEF,+BAA+B;QAC/B,IAAI,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,QAAQ,EAAE,CAAC;YACtB,gBAAgB,CAAC,QAAQ,GAAG,EAAE,KAAK,EAAE,OAAO,CAAC,QAAQ,EAAE,CAAC;YACxD,0EAA0E;YAC1E,IAAI,CAAC,aAAa,GAAG,CAAA,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,QAAQ,MAAK,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,aAAa,CAAC;QAC9E,CAAC;aAAM,CAAC;YACN,2BAA2B;YAC3B,MAAM,UAAU,GAAG,CAAA,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,QAAQ,MAAK,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,aAAa,CAAC;YAC1E,IAAI,CAAC,aAAa,GAAG,UAAU,CAAC;YAChC,gBAAgB,CAAC,UAAU,GAAG,UAAU,CAAC;QAC3C,CAAC;QAED,MAAM,WAAW,GAA2B;YAC1C,KAAK,EAAE,gBAAgB;YACvB,KAAK,EAAE,KAAK;SACb,CAAC;QAEF,0EAA0E;QAC1E,0EAA0E;QAC1E,sEAAsE;QACtE,0EAA0E;QAC1E,iCAAiC;QACjC,IAAI,CAAC;YACH,IAAI,CAAC,MAAM,GAAG,MAAM,SAAS,CAAC,YAAY,CAAC,YAAY,CAAC,WAAW,CAAC,CAAC;QACvE,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,MAAM,IAAI,CAAC,wBAAwB,CAAC,GAAG,CAAC,CAAC;QAC3C,CAAC;QAED,IAAI,CAAC;YACH,IAAI,IAAI,CAAC,YAAY,EAAE,CAAC;gBACtB,IAAI,CAAC,YAAY,CAAC,SAAS,GAAG,IAAI,CAAC,MAAM,CAAC;gBAE1C,uEAAuE;gBACvE,4EAA4E;gBAC5E,0EAA0E;gBAC1E,mEAAmE;gBACnE,IAAI,CAAC;oBACH,MAAM,IAAI,CAAC,YAAY,CAAC,IAAI,EAAE,CAAC;gBACjC,CAAC;gBAAC,OAAO,GAAG,EAAE,CAAC;oBACb,OAAO,CAAC,IAAI,CAAC,mDAAmD,EAAE,GAAG,CAAC,CAAC;gBACzE,CAAC;gBAED,uBAAA,IAAI,4BAAc,IAAI,MAAA,CAAC;gBAEvB,uEAAuE;gBACvE,kEAAkE;gBAClE,wEAAwE;gBACxE,sEAAsE;gBACtE,IAAI,CAAC;oBACH,MAAM,IAAI,CAAC,OAAO,CAAC,EAAE,KAAK,EAAE,MAAA,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,UAAU,mCAAI,GAAG,EAAE,CAAC,CAAC;gBAC5D,CAAC;gBAAC,OAAO,GAAG,EAAE,CAAC;oBACb,OAAO,CAAC,IAAI,CAAC,kDAAkD,EAAE,GAAG,CAAC,CAAC;gBACxE,CAAC;gBAED,iEAAiE;gBACjE,IAAI,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,sBAAsB,EAAE,CAAC;oBACpC,MAAM,IAAI,CAAC,4BAA4B,EAAE,CAAC;oBAE1C,IAAI,IAAI,CAAC,yBAAyB,EAAE,CAAC;wBACnC,MAAM,IAAI,CAAC,wBAAwB,CAAC,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,YAAY,CAAC,CAAC;wBAC3D,IAAI,CAAC,qBAAqB,EAAE,CAAC;oBAC/B,CAAC;gBACH,CAAC;YACH,CAAC;QACH,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,sEAAsE;YACtE,wEAAwE;YACxE,iDAAiD;YACjD,MAAA,IAAI,CAAC,MAAM,0CAAE,SAAS,GAAG,OAAO,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC;YAC1D,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC;YACnB,uBAAA,IAAI,4BAAc,KAAK,MAAA,CAAC;YACxB,IAAI,IAAI,CAAC,YAAY,EAAE,CAAC;gBACtB,IAAI,CAAC,YAAY,CAAC,SAAS,GAAG,IAAI,CAAC;YACrC,CAAC;YAED,MAAM,IAAI,eAAe,CAAC,2BAA2B,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,EAAE,EAAE,eAAe,CAAC,CAAC;QACjG,CAAC;IACH,CAAC;IAED;;;;;;;;OAQG;IACK,0BAA0B,CAAC,OAAoC;;QACrE,MAAM,KAAK,GAAG,CAAA,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,WAAW,MAAK,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;QAC9D,MAAM,UAAU,GAAG,MAAA,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,mBAAmB,mCAAI,2BAA2B,CAAC;QAC/E,MAAM,WAAW,GAAG,IAAI,CAAC,KAAK,CAAC,UAAU,GAAG,KAAK,CAAC,CAAC;QAEnD,MAAM,WAAW,GAA0B;YACzC,KAAK,EAAE,EAAE,KAAK,EAAE,UAAU,EAAE;YAC5B,MAAM,EAAE,EAAE,KAAK,EAAE,WAAW,EAAE;SAC/B,CAAC;QAEF,IAAI,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,WAAW,EAAE,CAAC;YACzB,WAAW,CAAC,WAAW,GAAG,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC;QAC7C,CAAC;QAED,OAAO,WAAW,CAAC;IACrB,CAAC;IAED;;;;;;;;OAQG;IACK,wBAAwB,CAAC,GAAY;QAC3C,IAAI,GAAG,YAAY,YAAY,EAAE,CAAC;YAChC,QAAQ,GAAG,CAAC,IAAI,EAAE,CAAC;gBACjB,KAAK,iBAAiB;oBACpB,OAAO,IAAI,eAAe,CAAC,mCAAmC,EAAE,mBAAmB,CAAC,CAAC;gBACvF,KAAK,eAAe;oBAClB,OAAO,IAAI,eAAe,CACxB,mFAAmF,EACnF,oBAAoB,CACrB,CAAC;gBACJ,KAAK,kBAAkB;oBACrB,OAAO,IAAI,eAAe,CACxB,wHAAwH,EACxH,eAAe,CAChB,CAAC;YACN,CAAC;QACH,CAAC;QACD,OAAO,IAAI,eAAe,CAAC,2BAA2B,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,EAAE,EAAE,eAAe,CAAC,CAAC;IAClG,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,IAAI;;QACR,IAAI,CAAC,uBAAA,IAAI,gCAAW,EAAE,CAAC;YACrB,OAAO;QACT,CAAC;QAED,IAAI,CAAC;YACH,sEAAsE;YACtE,uDAAuD;YACvD,oEAAoE;YACpE,sEAAsE;YACtE,oDAAoD;YACpD,MAAA,IAAI,CAAC,+BAA+B,0CAAE,KAAK,EAAE,CAAC;YAC9C,IAAI,CAAC,+BAA+B,GAAG,IAAI,CAAC;YAC5C,IAAI,IAAI,CAAC,uBAAuB,KAAK,IAAI,EAAE,CAAC;gBAC1C,oBAAoB,CAAC,IAAI,CAAC,uBAAuB,CAAC,CAAC;gBACnD,IAAI,CAAC,uBAAuB,GAAG,IAAI,CAAC;YACtC,CAAC;YAED,4BAA4B;YAC5B,IAAI,IAAI,CAAC,aAAa,IAAI,IAAI,CAAC,aAAa,CAAC,KAAK,KAAK,UAAU,EAAE,CAAC;gBAClE,uEAAuE;gBACvE,gEAAgE;gBAChE,kEAAkE;gBAClE,YAAY;gBACZ,MAAA,IAAI,CAAC,eAAe,qDAAG,IAAI,eAAe,CAAC,wCAAwC,EAAE,eAAe,CAAC,CAAC,CAAC;gBACvG,IAAI,CAAC,gBAAgB,GAAG,IAAI,CAAC;gBAC7B,IAAI,CAAC,eAAe,GAAG,IAAI,CAAC;gBAC5B,IAAI,CAAC,aAAa,CAAC,IAAI,EAAE,CAAC;gBAC1B,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC;YAC5B,CAAC;YACD,IAAI,CAAC,cAAc,GAAG,EAAE,CAAC;YACzB,IAAI,IAAI,CAAC,mBAAmB,EAAE,CAAC;gBAC7B,IAAI,CAAC,mBAAmB,CAAC,IAAI,EAAE,CAAC;gBAChC,IAAI,CAAC,mBAAmB,GAAG,IAAI,CAAC;YAClC,CAAC;YAED,gCAAgC;YAChC,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;gBAChB,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC;gBACzD,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC;YACrB,CAAC;YAED,8DAA8D;YAC9D,IAAI,IAAI,CAAC,YAAY,EAAE,CAAC;gBACtB,IAAI,CAAC,YAAY,CAAC,KAAK,EAAE,CAAC;gBAC1B,IAAI,CAAC,YAAY,CAAC,SAAS,GAAG,IAAI,CAAC;gBACnC,MAAA,IAAI,CAAC,YAAY,CAAC,UAAU,0CAAE,WAAW,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;gBAC7D,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC;YAC3B,CAAC;YAED,uBAAA,IAAI,4BAAc,KAAK,MAAA,CAAC;QAC1B,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,wEAAwE;YACxE,8DAA8D;YAC9D,MAAM,IAAI,eAAe,CAAC,0BAA0B,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,EAAE,EAAE,eAAe,CAAC,CAAC;QAChG,CAAC;IACH,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,SAAS;QACb,OAAO,EAAE,SAAS,EAAE,uBAAA,IAAI,gCAAW,EAAE,CAAC;IACxC,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,OAAO,CACX,OAAW;;QAEX,MAAM,YAAY,GAAG,IAAI,CAAC,YAAY,CAAC;QAEvC,IAAI,CAAC,uBAAA,IAAI,gCAAW,IAAI,CAAC,YAAY,EAAE,CAAC;YACtC,MAAM,IAAI,eAAe,CAAC,uBAAuB,EAAE,qBAAqB,CAAC,CAAC;QAC5E,CAAC;QAED,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,IAAI,CAAC,gBAAgB,EAAE,CAAC;YACvC,uEAAuE;YACvE,qEAAqE;YACrE,yEAAyE;YACzE,qCAAqC;YACrC,MAAM,WAAW,GACf,IAAI,CAAC,uBAAuB,KAAK,KAAK,IAAI,IAAI,CAAC,kBAAkB;gBAC/D,CAAC,CAAC,sBAAsB,CAAC,YAAY,CAAC;gBACtC,CAAC,CAAC,oBAAoB,CAAC,YAAY,CAAC,CAAC;YACzC,0EAA0E;YAC1E,uEAAuE;YACvE,uEAAuE;YACvE,sEAAsE;YACtE,MAAM,WAAW,GAAG,gBAAgB,CAAC,WAAW,EAAE,IAAI,CAAC,eAAe,EAAE,CAAC,CAAC;YAE1E,uBAAuB,CAAC,MAAM,EAAE,YAAY,EAAE,WAAW,CAAC,CAAC;YAE3D,2EAA2E;YAC3E,sEAAsE;YACtE,wEAAwE;YACxE,yEAAyE;YACzE,wEAAwE;YACxE,8BAA8B;YAC9B,MAAM,gBAAgB,GAAG,MAAA,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,OAAO,mCAAI,EAAE,CAAC;YAChD,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,gBAAgB,GAAG,GAAG,CAAC,CAAC,CAAC;YAErE,IAAI,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,UAAU,EAAE,CAAC;gBACxB,mDAAmD;gBACnD,4EAA4E;gBAC5E,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;oBACrC,MAAM,CAAC,MAAM,CACX,CAAC,IAAI,EAAE,EAAE;wBACP,IAAI,CAAC,IAAI,EAAE,CAAC;4BACV,MAAM,CAAC,IAAI,eAAe,CAAC,mCAAmC,EAAE,0BAA0B,CAAC,CAAC,CAAC;4BAC7F,OAAO;wBACT,CAAC;wBAED,MAAM,GAAG,GAAG,GAAG,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC;wBACtC,OAAO,CAAC,EAAE,OAAO,EAAE,GAAG,EAAwB,CAAC,CAAC;oBAClD,CAAC,EACD,YAAY,EACZ,OAAO,CACR,CAAC;gBACJ,CAAC,CAAC,CAAC;YACL,CAAC;iBAAM,CAAC;gBACN,qBAAqB;gBACrB,MAAM,UAAU,GAAG,cAAc,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;gBACnD,OAAO,EAAE,KAAK,EAAE,UAAU,EAAwB,CAAC;YACrD,CAAC;QACH,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,MAAM,IAAI,eAAe,CAAC,4BAA4B,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,EAAE,EAAE,qBAAqB,CAAC,CAAC;QACxG,CAAC;IACH,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,aAAa,CACjB,OAAW;QAEX,OAAO,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;IAC/B,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,cAAc,CAAC,OAA+B;QAClD,IAAI,CAAC,uBAAA,IAAI,gCAAW,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,CAAC;YAC3C,MAAM,IAAI,eAAe,CAAC,uBAAuB,EAAE,qBAAqB,CAAC,CAAC;QAC5E,CAAC;QAED,IAAI,IAAI,CAAC,aAAa,EAAE,CAAC;YACvB,MAAM,IAAI,eAAe,CAAC,kCAAkC,EAAE,+BAA+B,CAAC,CAAC;QACjG,CAAC;QAED,IAAI,CAAC;YACH,IAAI,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC;YAEzB,2DAA2D;YAC3D,IAAI,CAAA,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,WAAW,KAAI,MAAM,EAAE,CAAC;gBACnC,MAAM,WAAW,GAAG,MAAM,SAAS,CAAC,YAAY,CAAC,YAAY,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;gBAC/E,MAAM,UAAU,GAAG,WAAW,CAAC,cAAc,EAAE,CAAC,CAAC,CAAC,CAAC;gBACnD,IAAI,CAAC,mBAAmB,GAAG,UAAU,CAAC;gBACtC,MAAM,WAAW,GAAG,MAAM,CAAC,cAAc,EAAE,CAAC;gBAC5C,MAAM,GAAG,IAAI,WAAW,CAAC,CAAC,GAAG,WAAW,EAAE,UAAU,CAAC,CAAC,CAAC;YACzD,CAAC;YAED,IAAI,CAAC,MAAM,EAAE,CAAC;gBACZ,MAAM,IAAI,KAAK,CAAC,4BAA4B,CAAC,CAAC;YAChD,CAAC;YAED,IAAI,CAAC,cAAc,GAAG,EAAE,CAAC;YAEzB,MAAM,QAAQ,GAAG,CAAC,uBAAuB,EAAE,YAAY,EAAE,WAAW,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAClF,aAAa,CAAC,eAAe,CAAC,IAAI,CAAC,CACpC,CAAC;YAEF,IAAI,CAAC,QAAQ,EAAE,CAAC;gBACd,MAAM,IAAI,KAAK,CAAC,2CAA2C,CAAC,CAAC;YAC/D,CAAC;YAED,IAAI,CAAC,aAAa,GAAG,IAAI,aAAa,CAAC,MAAM,EAAE,EAAE,QAAQ,EAAE,CAAC,CAAC;YAE7D,IAAI,CAAC,aAAa,CAAC,eAAe,GAAG,CAAC,KAAK,EAAE,EAAE;gBAC7C,IAAI,KAAK,CAAC,IAAI,IAAI,KAAK,CAAC,IAAI,CAAC,IAAI,GAAG,CAAC,EAAE,CAAC;oBACtC,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;gBACvC,CAAC;YACH,CAAC,CAAC;YAEF,IAAI,CAAC,aAAa,CAAC,MAAM,GAAG,GAAG,EAAE;;gBAC/B,iDAAiD;gBACjD,IAAI,IAAI,CAAC,mBAAmB,EAAE,CAAC;oBAC7B,IAAI,CAAC,mBAAmB,CAAC,IAAI,EAAE,CAAC;oBAChC,IAAI,CAAC,mBAAmB,GAAG,IAAI,CAAC;gBAClC,CAAC;gBACD,MAAM,IAAI,GAAG,IAAI,IAAI,CAAC,IAAI,CAAC,cAAc,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC,CAAC;gBAC/D,MAAM,GAAG,GAAG,GAAG,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC;gBACtC,IAAI,CAAC,cAAc,GAAG,EAAE,CAAC;gBACzB,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC;gBAC1B,MAAA,IAAI,CAAC,gBAAgB,qDAAG,EAAE,OAAO,EAAE,GAAG,EAAE,CAAC,CAAC;gBAC1C,IAAI,CAAC,gBAAgB,GAAG,IAAI,CAAC;gBAC7B,IAAI,CAAC,eAAe,GAAG,IAAI,CAAC;YAC9B,CAAC,CAAC;YAEF,IAAI,CAAC,aAAa,CAAC,OAAO,GAAG,CAAC,KAAK,EAAE,EAAE;;gBACrC,IAAI,IAAI,CAAC,mBAAmB,EAAE,CAAC;oBAC7B,IAAI,CAAC,mBAAmB,CAAC,IAAI,EAAE,CAAC;oBAChC,IAAI,CAAC,mBAAmB,GAAG,IAAI,CAAC;gBAClC,CAAC;gBACD,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC;gBAC1B,IAAI,CAAC,cAAc,GAAG,EAAE,CAAC;gBACzB,MAAM,YAAY,GAAG,MAAA,MAAC,KAAoB,CAAC,KAAK,0CAAE,OAAO,mCAAI,yBAAyB,CAAC;gBACvF,oEAAoE;gBACpE,6DAA6D;gBAC7D,kCAAkC;gBAClC,MAAA,IAAI,CAAC,eAAe,qDAAG,IAAI,eAAe,CAAC,mBAAmB,GAAG,YAAY,EAAE,eAAe,CAAC,CAAC,CAAC;gBACjG,IAAI,CAAC,gBAAgB,GAAG,IAAI,CAAC;gBAC7B,IAAI,CAAC,eAAe,GAAG,IAAI,CAAC;YAC9B,CAAC,CAAC;YAEF,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,+BAA+B;QAChE,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,IAAI,IAAI,CAAC,mBAAmB,EAAE,CAAC;gBAC7B,IAAI,CAAC,mBAAmB,CAAC,IAAI,EAAE,CAAC;gBAChC,IAAI,CAAC,mBAAmB,GAAG,IAAI,CAAC;YAClC,CAAC;YACD,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC;YAC1B,IAAI,CAAC,cAAc,GAAG,EAAE,CAAC;YACzB,MAAM,IAAI,eAAe,CACvB,8BAA8B,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,EAAE,EACrD,IAAI,CAAC,0BAA0B,CAAC,GAAG,CAAC,CACrC,CAAC;QACJ,CAAC;IACH,CAAC;IAED;;;;;;;OAOG;IACK,0BAA0B,CAAC,GAAY;QAC7C,IAAI,GAAG,YAAY,YAAY,EAAE,CAAC;YAChC,OAAO,6BAA6B,CAAC,GAAG,EAAE,YAAY,CAAC,CAAC;QAC1D,CAAC;QACD,IAAI,GAAG,YAAY,KAAK,EAAE,CAAC;YACzB,IAAI,GAAG,CAAC,OAAO,KAAK,4BAA4B,EAAE,CAAC;gBACjD,OAAO,oBAAoB,CAAC;YAC9B,CAAC;YACD,IAAI,GAAG,CAAC,OAAO,KAAK,2CAA2C,EAAE,CAAC;gBAChE,OAAO,sBAAsB,CAAC;YAChC,CAAC;QACH,CAAC;QACD,OAAO,eAAe,CAAC;IACzB,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,aAAa;QACjB,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,CAAC;YACxB,MAAM,IAAI,eAAe,CAAC,6BAA6B,EAAE,0BAA0B,CAAC,CAAC;QACvF,CAAC;QAED,gEAAgE;QAChE,2EAA2E;QAC3E,mBAAmB;QACnB,IAAI,IAAI,CAAC,gBAAgB,IAAI,IAAI,CAAC,eAAe,EAAE,CAAC;YAClD,MAAM,IAAI,eAAe,CAAC,oCAAoC,EAAE,eAAe,CAAC,CAAC;QACnF,CAAC;QAED,OAAO,IAAI,OAAO,CAAyB,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;;YAC7D,IAAI,CAAC,gBAAgB,GAAG,OAAO,CAAC;YAChC,IAAI,CAAC,eAAe,GAAG,MAAM,CAAC;YAC9B,MAAA,IAAI,CAAC,aAAa,0CAAE,IAAI,EAAE,CAAC;QAC7B,CAAC,CAAC,CAAC;IACL,CAAC;IAED;;OAEG;IACI,KAAK,CAAC,UAAU;;QACrB,IAAI,CAAC,uBAAA,IAAI,gCAAW,EAAE,CAAC;YACrB,MAAM,IAAI,eAAe,CAAC,uBAAuB,EAAE,qBAAqB,CAAC,CAAC;QAC5E,CAAC;QAED,yEAAyE;QACzE,0EAA0E;QAC1E,sEAAsE;QACtE,UAAU;QACV,IAAI,IAAI,CAAC,aAAa,IAAI,IAAI,CAAC,aAAa,CAAC,KAAK,KAAK,UAAU,EAAE,CAAC;YAClE,MAAM,IAAI,eAAe,CAAC,qDAAqD,EAAE,+BAA+B,CAAC,CAAC;QACpH,CAAC;QAED,yEAAyE;QACzE,sEAAsE;QACtE,sEAAsE;QACtE,kEAAkE;QAClE,sDAAsD;QACtD,MAAM,UAAU,GAAG,IAAI,CAAC,aAAa,KAAK,MAAM,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,MAAM,CAAC;QAE1E,sEAAsE;QACtE,sEAAsE;QACtE,mDAAmD;QACnD,MAAM,WAAW,GAA2B;YAC1C,KAAK,kCACA,IAAI,CAAC,4BAA4B,KACpC,UAAU,EAAE,UAAU,GACvB;YACD,KAAK,EAAE,KAAK;SACb,CAAC;QAEF,IAAI,SAAsB,CAAC;QAC3B,IAAI,CAAC;YACH,SAAS,GAAG,MAAM,SAAS,CAAC,YAAY,CAAC,YAAY,CAAC,WAAW,CAAC,CAAC;QACrE,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,wEAAwE;YACxE,sEAAsE;YACtE,qEAAqE;YACrE,kEAAkE;YAClE,MAAM,IAAI,eAAe,CACvB,0BAA0B,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,EAAE,EACjD,6BAA6B,CAAC,GAAG,EAAE,QAAQ,CAAC,CAC7C,CAAC;QACJ,CAAC;QAED,wEAAwE;QACxE,4BAA4B;QAC5B,MAAA,IAAI,CAAC,MAAM,0CAAE,SAAS,GAAG,OAAO,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC;QAC1D,IAAI,CAAC,MAAM,GAAG,SAAS,CAAC;QACxB,IAAI,CAAC,aAAa,GAAG,UAAU,CAAC;QAEhC,IAAI,IAAI,CAAC,YAAY,EAAE,CAAC;YACtB,IAAI,CAAC,YAAY,CAAC,SAAS,GAAG,SAAS,CAAC;QAC1C,CAAC;QAED,yEAAyE;QACzE,yEAAyE;QACzE,iEAAiE;QACjE,uEAAuE;QACvE,yCAAyC;QACzC,IAAI,CAAC;YACH,MAAM,IAAI,CAAC,OAAO,CAAC,EAAE,KAAK,EAAE,IAAI,CAAC,WAAW,EAAE,CAAC,CAAC;QAClD,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,CAAC,IAAI,CAAC,4DAA4D,EAAE,GAAG,CAAC,CAAC;QAClF,CAAC;IACH,CAAC;IAED;;;;;;;;OAQG;IACI,KAAK,CAAC,mBAAmB;;QAC9B,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,MAAM,SAAS,CAAC,YAAY,CAAC,gBAAgB,EAAE,CAAC;YAChE,MAAM,YAAY,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,IAAI,KAAK,YAAY,CAAC,CAAC;YAE9E,MAAM,WAAW,GAAG,IAAI,CAAC,aAAa,EAAE,CAAC;YACzC,MAAM,cAAc,GAAG,WAAW,aAAX,WAAW,uBAAX,WAAW,CAAE,WAAW,GAAG,QAAQ,CAAC;YAC3D,MAAM,gBAAgB,GACpB,WAAW,IAAI,OAAO,WAAW,CAAC,eAAe,KAAK,UAAU;gBAC9D,CAAC,CAAC,MAAA,WAAW,CAAC,eAAe,EAAE,CAAC,UAAU,0CAAG,CAAC,CAAC;gBAC/C,CAAC,CAAC,SAAS,CAAC;YAEhB,OAAO;gBACL,OAAO,EAAE,YAAY,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE;oBACnC,MAAM,QAAQ,GACZ,MAAM,CAAC,QAAQ,KAAK,cAAc,IAAI,gBAAgB;wBACpD,CAAC,CAAC,gBAAgB,KAAK,MAAM;4BAC3B,CAAC,CAAC,OAAO;4BACT,CAAC,CAAC,MAAM;wBACV,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,OAAO,CAAC;4BAC5C,CAAC,CAAC,OAAO;4BACT,CAAC,CAAC,MAAM,CAAC;oBAEf,OAAO;wBACL,EAAE,EAAE,MAAM,CAAC,QAAQ;wBACnB,IAAI,EAAE,MAAM,CAAC,KAAK,IAAI,UAAU,MAAM,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE;wBACjE,QAAQ;qBACT,CAAC;gBACJ,CAAC,CAAC;aACH,CAAC;QACJ,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,CAAC,KAAK,CAAC,iCAAiC,EAAE,GAAG,CAAC,CAAC;YACtD,OAAO,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC;QACzB,CAAC;IACH,CAAC;IAED;;;;;;OAMG;IACI,KAAK,CAAC,OAAO;QAClB,MAAM,KAAK,GAAG,IAAI,CAAC,aAAa,EAAE,CAAC;QACnC,MAAM,UAAU,GAAG,IAAI,CAAC,uBAAuB,CAAC,KAAK,CAAC,CAAC;QAEvD,IAAI,KAAK,IAAI,UAAU,EAAE,CAAC;YACxB,MAAM,QAAQ,GAAG,KAAK,CAAC,WAAW,EAAkB,CAAC;YACrD,OAAO;gBACL,GAAG,EAAE,UAAU,CAAC,GAAG;gBACnB,GAAG,EAAE,UAAU,CAAC,GAAG;gBACnB,OAAO,EAAE,OAAO,QAAQ,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,WAAW;aAC9E,CAAC;QACJ,CAAC;QAED,wDAAwD;QACxD,OAAO;YACL,GAAG,EAAE,kBAAkB;YACvB,GAAG,EAAE,kBAAkB;YACvB,OAAO,EAAE,IAAI,CAAC,WAAW;SAC1B,CAAC;IACJ,CAAC;IAED;;;;;;;OAOG;IACI,KAAK,CAAC,OAAO,CAAC,OAA0C;QAC7D,MAAM,KAAK,GAAG,IAAI,CAAC,aAAa,EAAE,CAAC;QACnC,MAAM,UAAU,GAAG,IAAI,CAAC,uBAAuB,CAAC,KAAK,CAAC,CAAC;QAEvD,IAAI,KAAK,IAAI,UAAU,EAAE,CAAC;YACxB,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,GAAG,EAAE,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,KAAK,EAAE,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC;YAClF,MAAM,KAAK,CAAC,gBAAgB,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,IAAI,EAAE,OAAO,EAAuB,CAAC,EAAE,CAAC,CAAC;YACrF,IAAI,CAAC,WAAW,GAAG,OAAO,CAAC;YAC3B,IAAI,CAAC,eAAe,GAAG,IAAI,CAAC;YAE5B,wEAAwE;YACxE,+BAA+B;YAC/B,IAAI,IAAI,CAAC,YAAY,EAAE,CAAC;gBACtB,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,SAAS,GAAG,EAAE,CAAC;YACzC,CAAC;YACD,OAAO;QACT,CAAC;QAED,0BAA0B;QAC1B,IAAI,CAAC,eAAe,GAAG,KAAK,CAAC;QAC7B,IAAI,CAAC,WAAW,GAAG,OAAO,CAAC,KAAK,CAAC;QAEjC,IAAI,IAAI,CAAC,YAAY,EAAE,CAAC;YACtB,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,4BAA4B,CAAC,CAAC,CAAC,MAAM,CAAC;YAC1F,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,SAAS,GAAG,SAAS,IAAI,CAAC,eAAe,EAAE,GAAG,CAAC;YACvE,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,eAAe,GAAG,QAAQ,CAAC;QACrD,CAAC;IACH,CAAC;IAED;;OAEG;IACK,aAAa;;QACnB,OAAO,MAAA,MAAA,IAAI,CAAC,MAAM,0CAAE,cAAc,GAAG,CAAC,CAAC,mCAAI,IAAI,CAAC;IAClD,CAAC;IAED;;;;OAIG;IACK,uBAAuB,CAAC,KAA8B;QAC5D,IAAI,CAAC,KAAK,IAAI,OAAO,KAAK,CAAC,eAAe,KAAK,UAAU,EAAE,CAAC;YAC1D,OAAO,IAAI,CAAC;QACd,CAAC;QAED,MAAM,IAAI,GAAI,KAAK,CAAC,eAAe,EAAuB,CAAC,IAAI,CAAC;QAChE,IAAI,IAAI,IAAI,OAAO,IAAI,CAAC,GAAG,KAAK,QAAQ,IAAI,OAAO,IAAI,CAAC,GAAG,KAAK,QAAQ,IAAI,IAAI,CAAC,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;YAChG,OAAO,IAAI,CAAC;QACd,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IAED;;;;;OAKG;IACK,eAAe;QACrB,IAAI,IAAI,CAAC,eAAe,EAAE,CAAC;YACzB,OAAO,CAAC,CAAC;QACX,CAAC;QACD,OAAO,IAAI,CAAC,GAAG,CAAC,kBAAkB,EAAE,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,WAAW,EAAE,kBAAkB,CAAC,CAAC,CAAC;IACtF,CAAC;IAED;;;;;;OAMG;IACI,KAAK,CAAC,aAAa;QACxB,MAAM,IAAI,CAAC,aAAa,CAAC,iEAAiE,CAAC,CAAC;IAC9F,CAAC;IAED;;OAEG;IACI,KAAK,CAAC,YAAY;QACvB,OAAO,EAAE,SAAS,EAAE,IAAI,CAAC,gBAAgB,EAAE,CAAC;IAC9C,CAAC;IAED;;OAEG;IACI,KAAK,CAAC,sBAAsB;QACjC,gCAAgC;QAChC,OAAO,EAAE,UAAU,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC;IACjC,CAAC;IAED;;;;;OAKG;IACI,KAAK,CAAC,YAAY,CAAC,OAA4B;QACpD,IAAI,OAAO,CAAC,IAAI,KAAK,KAAK,EAAE,CAAC;YAC3B,MAAM,IAAI,CAAC,aAAa,CAAC,gEAAgE,CAAC,CAAC;QAC7F,CAAC;QACD,IAAI,CAAC,gBAAgB,GAAG,KAAK,CAAC;IAChC,CAAC;IAED;;OAEG;IACI,KAAK,CAAC,gBAAgB;QAC3B,+CAA+C;QAC/C,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC;IAC9B,CAAC;IAED;;;;;;OAMG;IACI,KAAK,CAAC,YAAY;QACvB,MAAM,IAAI,CAAC,aAAa,CAAC,uDAAuD,CAAC,CAAC;IACpF,CAAC;IAED;;OAEG;IACI,KAAK,CAAC,YAAY;QACvB,+CAA+C;QAC/C,MAAM,IAAI,CAAC,aAAa,CAAC,uDAAuD,CAAC,CAAC;IACpF,CAAC;IAED;;OAEG;IACI,KAAK,CAAC,gBAAgB;QAC3B,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;YAC7C,IAAI,CAAC,qBAAqB,CAAC,QAAQ,CAAC;YACpC,IAAI,CAAC,qBAAqB,CAAC,YAAY,CAAC;SACzC,CAAC,CAAC;QACH,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,CAAC;IAChC,CAAC;IAED;;;;;;OAMG;IACK,KAAK,CAAC,qBAAqB,CAAC,IAA0B;QAC5D,IAAI,SAAS,CAAC,WAAW,EAAE,CAAC;YAC1B,IAAI,CAAC;gBACH,MAAM,MAAM,GAAG,MAAM,SAAS,CAAC,WAAW,CAAC,KAAK,CAAC,EAAE,IAAI,EAAE,IAAsB,EAAE,CAAC,CAAC;gBACnF,OAAO,MAAM,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC;YAClG,CAAC;YAAC,WAAM,CAAC;gBACP,uEAAuE;gBACvE,qEAAqE;gBACrE,4CAA4C;YAC9C,CAAC;QACH,CAAC;QAED,gFAAgF;QAChF,2EAA2E;QAC3E,kEAAkE;QAClE,IAAI,IAAI,KAAK,QAAQ,EAAE,CAAC;YACtB,OAAO,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,QAAQ,CAAC;QAC5C,CAAC;QACD,OAAO,QAAQ,CAAC;IAClB,CAAC;IAED;;;OAGG;IACI,KAAK,CAAC,kBAAkB,CAAC,OAAkD;;QAChF,MAAM,WAAW,GAAG,MAAA,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,WAAW,mCAAI,CAAC,QAAQ,CAAC,CAAC;QACvD,MAAM,MAAM,GAAqB,EAAE,MAAM,EAAE,QAAQ,EAAE,UAAU,EAAE,QAAQ,EAAE,CAAC;QAE5E,wCAAwC;QACxC,IAAI,WAAW,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC;YACnC,IAAI,CAAC;gBACH,MAAM,MAAM,GAAG,MAAM,SAAS,CAAC,YAAY,CAAC,YAAY,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;gBAC1E,MAAM,CAAC,SAAS,EAAE,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC;gBACpD,MAAM,CAAC,MAAM,GAAG,SAAS,CAAC;YAC5B,CAAC;YAAC,WAAM,CAAC;gBACP,MAAM,CAAC,MAAM,GAAG,QAAQ,CAAC;YAC3B,CAAC;QACH,CAAC;aAAM,CAAC;YACN,qDAAqD;YACrD,MAAM,CAAC,MAAM,GAAG,CAAC,MAAM,IAAI,CAAC,gBAAgB,EAAE,CAAC,CAAC,MAAM,CAAC;QACzD,CAAC;QAED,4DAA4D;QAC5D,IAAI,WAAW,CAAC,QAAQ,CAAC,YAAY,CAAC,EAAE,CAAC;YACvC,IAAI,CAAC;gBACH,MAAM,MAAM,GAAG,MAAM,SAAS,CAAC,YAAY,CAAC,YAAY,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;gBAC1E,MAAM,CAAC,SAAS,EAAE,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC;gBACpD,MAAM,CAAC,UAAU,GAAG,SAAS,CAAC;YAChC,CAAC;YAAC,WAAM,CAAC;gBACP,MAAM,CAAC,UAAU,GAAG,QAAQ,CAAC;YAC/B,CAAC;QACH,CAAC;aAAM,CAAC;YACN,MAAM,CAAC,UAAU,GAAG,CAAC,MAAM,IAAI,CAAC,gBAAgB,EAAE,CAAC,CAAC,UAAU,CAAC;QACjE,CAAC;QAED,OAAO,MAAM,CAAC;IAChB,CAAC;IAED;;OAEG;IACK,KAAK,CAAC,qBAAqB;;QACjC,MAAM,eAAe,GAAG,IAAI,CAAC,eAAe,CAAC;QAC7C,MAAM,YAAY,GAAG,IAAI,CAAC,YAAY,CAAC;QAEvC,IAAI,CAAC,IAAI,CAAC,yBAAyB,IAAI,CAAC,eAAe,IAAI,CAAC,YAAY,EAAE,CAAC;YACzE,OAAO;QACT,CAAC;QAED,uEAAuE;QACvE,wEAAwE;QACxE,uEAAuE;QACvE,sEAAsE;QACtE,+BAA+B;QAC/B,MAAA,IAAI,CAAC,+BAA+B,0CAAE,KAAK,EAAE,CAAC;QAC9C,MAAM,eAAe,GAAG,IAAI,eAAe,EAAE,CAAC;QAC9C,IAAI,CAAC,+BAA+B,GAAG,eAAe,CAAC;QACvD,MAAM,EAAE,MAAM,EAAE,GAAG,eAAe,CAAC;QAEnC,sEAAsE;QACtE,mEAAmE;QACnE,wEAAwE;QACxE,kEAAkE;QAClE,sDAAsD;QACtD,IAAI,YAAY,CAAC,UAAU,GAAG,CAAC,EAAE,CAAC;YAChC,MAAM,UAAU,GAAG,MAAM,IAAI,OAAO,CAAU,CAAC,OAAO,EAAE,EAAE;gBACxD,MAAM,OAAO,GAAG,GAAG,EAAE;oBACnB,YAAY,CAAC,mBAAmB,CAAC,YAAY,EAAE,WAAW,CAAC,CAAC;oBAC5D,MAAM,CAAC,mBAAmB,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC;oBAClD,YAAY,CAAC,SAAS,CAAC,CAAC;gBAC1B,CAAC,CAAC;gBACF,MAAM,WAAW,GAAG,GAAG,EAAE;oBACvB,OAAO,EAAE,CAAC;oBACV,OAAO,CAAC,IAAI,CAAC,CAAC;gBAChB,CAAC,CAAC;gBACF,MAAM,YAAY,GAAG,GAAG,EAAE;oBACxB,OAAO,EAAE,CAAC;oBACV,OAAO,CAAC,KAAK,CAAC,CAAC;gBACjB,CAAC,CAAC;gBACF,MAAM,SAAS,GAAG,UAAU,CAAC,GAAG,EAAE;oBAChC,OAAO,EAAE,CAAC;oBACV,OAAO,CAAC,KAAK,CAAC,CAAC;gBACjB,CAAC,EAAE,8BAA8B,CAAC,CAAC;gBAEnC,YAAY,CAAC,gBAAgB,CAAC,YAAY,EAAE,WAAW,CAAC,CAAC;gBACzD,MAAM,CAAC,gBAAgB,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC;YACjD,CAAC,CAAC,CAAC;YAEH,IAAI,CAAC,UAAU,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;gBAClC,OAAO;YACT,CAAC;QACH,CAAC;QAED,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;YACnB,OAAO;QACT,CAAC;QAED,qCAAqC;QACrC,IAAI,iBAAiB,GAAG,CAAC,CAAC;QAC1B,MAAM,wBAAwB,GAAG,GAAG,CAAC,CAAC,KAAK;QAE3C,yEAAyE;QACzE,wEAAwE;QACxE,qEAAqE;QACrE,wDAAwD;QACxD,MAAM,sBAAsB,GAAG,IAAI,GAAG,EAAkB,CAAC;QAEzD,uDAAuD;QACvD,MAAM,WAAW,GAAG,KAAK,IAAI,EAAE;;YAC7B,uEAAuE;YACvE,uEAAuE;YACvE,sEAAsE;YACtE,uCAAuC;YACvC,IAAI,MAAM,CAAC,OAAO,IAAI,CAAC,uBAAA,IAAI,gCAAW,IAAI,CAAC,YAAY,IAAI,CAAC,eAAe,EAAE,CAAC;gBAC5E,OAAO;YACT,CAAC;YAED,kEAAkE;YAClE,+CAA+C;YAC/C,MAAM,GAAG,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC;YAC9B,IAAI,GAAG,GAAG,iBAAiB,IAAI,wBAAwB,EAAE,CAAC;gBACxD,IAAI,CAAC;oBACH,MAAM,QAAQ,GAAG,MAAM,eAAe,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC;oBAC5D,iBAAiB,GAAG,GAAG,CAAC;oBAExB,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;wBACxB,MAAM,OAAO,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC;wBAE5B,uEAAuE;wBACvE,uEAAuE;wBACvE,oEAAoE;wBACpE,8CAA8C;wBAC9C,MAAM,IAAI,GAAG,MAAA,0BAA0B,CAAC,OAAO,CAAC,MAAM,CAAC,mCAAI,OAAO,CAAC,MAAM,CAAC;wBAE1E,qEAAqE;wBACrE,sEAAsE;wBACtE,+DAA+D;wBAC/D,iEAAiE;wBACjE,MAAM,UAAU,GAAG,GAAG,IAAI,SAAS,OAAO,CAAC,QAAQ,EAAE,CAAC;wBACtD,MAAM,QAAQ,GAAG,sBAAsB,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;wBACxD,IAAI,QAAQ,KAAK,SAAS,IAAI,GAAG,GAAG,QAAQ,IAAI,6BAA6B,EAAE,CAAC;4BAC9E,+DAA+D;4BAC/D,uDAAuD;4BACvD,IAAI,sBAAsB,CAAC,IAAI,GAAG,kCAAkC,EAAE,CAAC;gCACrE,KAAK,MAAM,CAAC,GAAG,EAAE,QAAQ,CAAC,IAAI,sBAAsB,EAAE,CAAC;oCACrD,IAAI,GAAG,GAAG,QAAQ,IAAI,6BAA6B,EAAE,CAAC;wCACpD,sBAAsB,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;oCACrC,CAAC;gCACH,CAAC;4BACH,CAAC;4BACD,sBAAsB,CAAC,GAAG,CAAC,UAAU,EAAE,GAAG,CAAC,CAAC;4BAE5C,4DAA4D;4BAC5D,gEAAgE;4BAChE,iEAAiE;4BACjE,MAAM,YAAY,GAAG,2BAA2B,CAC9C,OAAO,CAAC,WAAW,EACnB,YAAY,EACZ,IAAI,CAAC,uBAAuB,CAC7B,CAAC;4BAEF,IAAI,CAAC,eAAe,CAAC,iBAAiB,EAAE;gCACtC,KAAK,EAAE,OAAO,CAAC,QAAQ;gCACvB,IAAI;gCACJ,YAAY;6BACb,CAAC,CAAC;wBACL,CAAC;oBACH,CAAC;gBACH,CAAC;gBAAC,OAAO,GAAG,EAAE,CAAC;oBACb,OAAO,CAAC,KAAK,CAAC,yBAAyB,EAAE,GAAG,CAAC,CAAC;gBAChD,CAAC;YACH,CAAC;YAED,IAAI,CAAC,MAAM,CAAC,OAAO,IAAI,uBAAA,IAAI,gCAAW,EAAE,CAAC;gBACvC,IAAI,CAAC,uBAAuB,GAAG,qBAAqB,CAAC,WAAW,CAAC,CAAC;YACpE,CAAC;QACH,CAAC,CAAC;QAEF,IAAI,CAAC,uBAAuB,GAAG,qBAAqB,CAAC,WAAW,CAAC,CAAC;IACpE,CAAC;IAED;;OAEG;IACK,KAAK,CAAC,4BAA4B;QACxC,IAAI,iBAAiB,IAAI,MAAM,EAAE,CAAC;YAChC,IAAI,CAAC;gBACH,IAAI,CAAC,eAAe,GAAG,IAAI,eAAe,EAAE,CAAC;gBAC7C,IAAI,CAAC,yBAAyB,GAAG,IAAI,CAAC;YACxC,CAAC;YAAC,OAAO,CAAC,EAAE,CAAC;gBACX,OAAO,CAAC,IAAI,CAAC,mDAAmD,CAAC,CAAC;gBAClE,IAAI,CAAC,yBAAyB,GAAG,KAAK,CAAC;YACzC,CAAC;QACH,CAAC;IACH,CAAC;IAED;;;OAGG;IACK,KAAK,CAAC,wBAAwB,CAAC,YAA4B;QACjE,IAAI,CAAC,IAAI,CAAC,yBAAyB,EAAE,CAAC;YACpC,OAAO;QACT,CAAC;QAED,IAAI,CAAC,CAAA,YAAY,aAAZ,YAAY,uBAAZ,YAAY,CAAE,MAAM,CAAA,EAAE,CAAC;YAC1B,IAAI,CAAC,eAAe,GAAG,IAAI,eAAe,EAAE,CAAC;YAC7C,OAAO;QACT,CAAC;QAED,MAAM,gBAAgB,GAAG,YAAY;aAClC,GAAG,CAAC,CAAC,WAAW,EAAE,EAAE;YACnB,MAAM,SAAS,GAAG,0BAA0B,CAAC,WAAW,CAAC,CAAC;YAC1D,IAAI,CAAC,SAAS,EAAE,CAAC;gBACf,OAAO,CAAC,IAAI,CAAC,8BAA8B,WAAW,oDAAoD,CAAC,CAAC;YAC9G,CAAC;YACD,OAAO,SAAS,CAAC;QACnB,CAAC,CAAC;aACD,MAAM,CAAC,CAAC,MAAM,EAAwC,EAAE,CAAC,MAAM,KAAK,IAAI,CAAC,CAAC;QAE7E,IAAI,CAAC,gBAAgB,CAAC,MAAM,EAAE,CAAC;YAC7B,OAAO,CAAC,IAAI,CACV,sGAAsG,CACvG,CAAC;YACF,IAAI,CAAC,eAAe,GAAG,IAAI,eAAe,EAAE,CAAC;YAC7C,OAAO;QACT,CAAC;QAED,MAAM,sBAAsB,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,GAAG,CAAC,gBAAgB,CAAC,CAAC,CAAC;QAErE,IAAI,CAAC;YACH,MAAM,gBAAgB,GAAG,MAAM,eAAe,CAAC,mBAAmB,EAAE,CAAC;YACrE,MAAM,iBAAiB,GAAG,sBAAsB,CAAC,MAAM,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,gBAAgB,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC;YACvG,MAAM,cAAc,GAAG,sBAAsB,CAAC,MAAM,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,gBAAgB,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC;YAErG,IAAI,cAAc,CAAC,MAAM,EAAE,CAAC;gBAC1B,OAAO,CAAC,IAAI,CACV,uEAAuE,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CACpG,CAAC;YACJ,CAAC;YAED,IAAI,CAAC,iBAAiB,CAAC,MAAM,EAAE,CAAC;gBAC9B,OAAO,CAAC,IAAI,CACV,iHAAiH,CAClH,CAAC;gBACF,IAAI,CAAC,eAAe,GAAG,IAAI,eAAe,EAAE,CAAC;gBAC7C,OAAO;YACT,CAAC;YAED,IAAI,CAAC,eAAe,GAAG,IAAI,eAAe,CAAC,EAAE,OAAO,EAAE,iBAAiB,EAAE,CAAC,CAAC;QAC7E,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,IAAI,CACV,gGAAgG,EAChG,KAAK,CACN,CAAC;YACF,IAAI,CAAC,eAAe,GAAG,IAAI,eAAe,EAAE,CAAC;QAC/C,CAAC;IACH,CAAC;IAED;;OAEG;IACK,KAAK,CAAC,iBAAiB,CAAC,kBAA2B;QACzD,IAAI,CAAC,YAAY,GAAG,QAAQ,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC;QACpD,IAAI,CAAC,YAAY,CAAC,WAAW,GAAG,IAAI,CAAC;QACrC,IAAI,CAAC,YAAY,CAAC,QAAQ,GAAG,IAAI,CAAC;QAClC,IAAI,CAAC,YAAY,CAAC,KAAK,GAAG,IAAI,CAAC;QAC/B,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,KAAK,GAAG,MAAM,CAAC;QACvC,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,MAAM,GAAG,MAAM,CAAC;QACxC,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,SAAS,GAAG,OAAO,CAAC;QAE5C,8EAA8E;QAC9E,IAAI,kBAAkB,EAAE,CAAC;YACvB,MAAM,SAAS,GAAG,QAAQ,CAAC,cAAc,CAAC,kBAAkB,CAAC,CAAC;YAC9D,IAAI,CAAC,SAAS,EAAE,CAAC;gBACf,MAAM,IAAI,KAAK,CAAC,6BAA6B,kBAAkB,YAAY,CAAC,CAAC;YAC/E,CAAC;YACD,SAAS,CAAC,WAAW,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;QAC3C,CAAC;aAAM,CAAC;YACN,wCAAwC;YACxC,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;QAC/C,CAAC;IACH,CAAC;IAED;;OAEG;IACK,gBAAgB;QACtB,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,CAAC;YACxB,IAAI,CAAC,aAAa,GAAG,QAAQ,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC;QACxD,CAAC;QACD,OAAO,IAAI,CAAC,aAAa,CAAC;IAC5B,CAAC;IAED;;OAEG;IACK,WAAW,CAAC,GAAY;QAC9B,OAAO,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;IAC1D,CAAC;CACF","sourcesContent":["import { WebPlugin } from '@capacitor/core';\nimport type { PermissionState } from '@capacitor/core';\n\nimport type {\n CameraAspectRatio,\n CameraSessionConfiguration,\n CameraViewPlugin,\n CameraErrorCode,\n CameraPermissionType,\n CameraPosition,\n GetAvailableDevicesResponse,\n GetFlashModeResponse,\n GetSupportedFlashModesResponse,\n GetTorchModeResponse,\n GetZoomResponse,\n IsTorchAvailableResponse,\n IsRunningResponse,\n PermissionStatus,\n CaptureResponse,\n FlashMode,\n CaptureOptions,\n VideoRecordingOptions,\n VideoRecordingResponse,\n BarcodeType,\n PreviewScaleMode,\n} from './definitions';\nimport {\n applyCssZoomCrop,\n calculateFullFrameArea,\n calculateVisibleArea,\n canvasToBase64,\n drawVisibleAreaToCanvas,\n transformBarcodeBoundingBox,\n} from './utils';\n\n/**\n * Suppression window in milliseconds during which a repeat of the same barcode\n * (identical value + type) is not re-emitted. A genuinely new code still emits\n * immediately. Kept consistent with the iOS and Android implementations.\n */\nexport const BARCODE_SUPPRESSION_WINDOW_MS = 500;\n\n/**\n * Once the per-key dedupe map grows past this size, expired entries are pruned\n * so a long session scanning many different codes stays bounded. Kept\n * consistent with the iOS and Android implementations.\n */\nexport const BARCODE_DEDUPE_MAP_PRUNE_THRESHOLD = 64;\n\n/**\n * Backstop for the \"wait until the video is ready\" step in\n * {@link CameraViewWeb.startBarcodeDetection}. If the video element never\n * fires `loadeddata` (e.g. a stalled stream), the wait settles anyway after\n * this many milliseconds instead of leaving a dangling listener and a\n * permanently pending promise.\n */\nexport const BARCODE_VIDEO_READY_TIMEOUT_MS = 5000;\n\n/**\n * Baseline `ideal` capture resolution requested from `getUserMedia` in\n * {@link CameraViewWeb.start}. Without any width/height hint, browsers default\n * to a low-resolution stream (often 640x480), which caps capture quality.\n *\n * These are `ideal` (not `exact`/`min`) so devices that cannot deliver\n * 1080p-class video still start at their best available resolution rather\n * than failing acquisition.\n */\nexport const DEFAULT_IDEAL_CAPTURE_WIDTH = 1920;\nexport const DEFAULT_IDEAL_CAPTURE_HEIGHT = 1080;\n\n/**\n * Bounds for the CSS `transform: scale()` zoom simulation used when the browser\n * does not expose a native `zoom` track capability. `getZoom` reports this\n * range and `setZoom` clamps the applied scale to it in fallback mode.\n */\nexport const SIMULATED_ZOOM_MIN = 1.0;\nexport const SIMULATED_ZOOM_MAX = 3.0;\n\n/**\n * Non-standard MediaStream zoom shapes. The `zoom` field on capabilities /\n * settings / constraints is defined by the W3C Image Capture spec but is not\n * present in the TypeScript DOM lib, so it is declared here for typed access.\n */\ninterface ZoomCapability {\n min: number;\n max: number;\n step?: number;\n}\ntype ZoomCapabilities = MediaTrackCapabilities & { zoom?: ZoomCapability };\ntype ZoomSettings = MediaTrackSettings & { zoom?: number };\ntype ZoomConstraintSet = MediaTrackConstraintSet & { zoom?: number };\n\nexport const BARCODE_TYPE_TO_WEB_FORMAT = {\n qr: 'qr_code',\n code128: 'code_128',\n code39: 'code_39',\n code39Mod43: null,\n code93: 'code_93',\n codabar: 'codabar',\n ean8: 'ean_8',\n ean13: 'ean_13',\n interleaved2of5: 'itf',\n itf14: 'itf',\n pdf417: 'pdf417',\n aztec: 'aztec',\n dataMatrix: 'data_matrix',\n upcA: 'upc_a',\n upce: 'upc_e',\n} satisfies Record<BarcodeType, BarcodeFormat | null>;\n\n/**\n * Inverse of {@link BARCODE_TYPE_TO_WEB_FORMAT}: maps the web BarcodeDetector\n * format back onto the cross-platform {@link BarcodeType} vocabulary so the\n * `barcodeDetected` event emits the same `type` values as iOS and Android.\n *\n * Note: `interleaved2of5` and `itf14` both map to the web format `itf`, so the\n * inversion has a collision that is resolved by insertion order — `itf14` comes\n * last in {@link BARCODE_TYPE_TO_WEB_FORMAT} and wins, which is the intended\n * result for `itf` detections.\n */\nexport const WEB_FORMAT_TO_BARCODE_TYPE: Readonly<Partial<Record<BarcodeFormat, BarcodeType>>> = Object.entries(\n BARCODE_TYPE_TO_WEB_FORMAT,\n).reduce<Partial<Record<BarcodeFormat, BarcodeType>>>((acc, [barcodeType, webFormat]) => {\n if (webFormat) {\n acc[webFormat] = barcodeType as BarcodeType;\n }\n return acc;\n}, {});\n\n/**\n * Error thrown by the web implementation for a rejected plugin call.\n *\n * Carries a stable `code` from the {@link CameraErrorCode} vocabulary, the\n * same public contract iOS and Android provide, so consumers can `switch` on\n * `error.code` instead of matching on the human-readable `message`.\n *\n * Methods that reject via `WebPlugin.unimplemented()` are the one exception:\n * those keep Capacitor's own `UNIMPLEMENTED` convention.\n */\nexport class CameraViewError extends Error {\n public readonly code: CameraErrorCode;\n\n constructor(message: string, code: CameraErrorCode) {\n super(message);\n this.name = 'CameraViewError';\n this.code = code;\n }\n}\n\n/**\n * Classifies a `getUserMedia` failure into the closest-fitting\n * {@link CameraErrorCode}, shared by every acquisition site.\n *\n * `kind` selects which media type's dedicated codes apply for `NotFoundError`/\n * `NotReadableError` so a missing/busy camera and a missing/busy microphone\n * aren't conflated. Anything unmappable falls back to `UNKNOWN_ERROR`.\n */\nexport function classifyGetUserMediaErrorCode(err: unknown, kind: 'camera' | 'microphone'): CameraErrorCode {\n if (err instanceof DOMException) {\n switch (err.name) {\n case 'NotAllowedError':\n return 'PERMISSION_DENIED';\n case 'NotFoundError':\n return kind === 'camera' ? 'CAMERA_UNAVAILABLE' : 'AUDIO_DEVICE_UNAVAILABLE';\n case 'NotReadableError':\n return kind === 'camera' ? 'DEVICE_LOCKED' : 'AUDIO_INPUT_ADDITION_FAILED';\n }\n }\n return 'UNKNOWN_ERROR';\n}\n\n/**\n * Web implementation of the CameraViewPlugin.\n * Optimized for performance and battery efficiency.\n */\nexport class CameraViewWeb extends WebPlugin implements CameraViewPlugin {\n // DOM elements\n private videoElement: HTMLVideoElement | null = null;\n private canvasElement: HTMLCanvasElement | null = null;\n\n // Stream state\n private stream: MediaStream | null = null;\n #isRunning = false;\n\n // Configuration state\n private currentCamera = 'environment'; // Default to back camera\n private currentZoom = 1.0;\n // Whether the current zoom is applied through the native track `zoom`\n // capability (`applyConstraints`) rather than the CSS `transform: scale()`\n // simulation. Capture only needs to compensate for the transform in the\n // CSS-fallback case.\n private usingNativeZoom = false;\n private currentFlashMode: FlashMode = 'off';\n // The aspect ratio the current session was started with, or null when the\n // option was omitted. Selects the capture contract: with an explicit ratio,\n // capture() returns the full sensor-ratio frame (cross-platform contract);\n // without it, the legacy web behavior of capturing the visible\n // (cover-cropped) preview region is preserved.\n private sessionAspectRatio: CameraAspectRatio | null = null;\n // How the current session scales the preview into its container. `'fit'`\n // (object-fit: contain) letterboxes the whole frame; `'cover'` (the default)\n // center-crops it. Selects the barcode-transform variant and, together with\n // the aspect ratio, the capture crop.\n private sessionPreviewScaleMode: PreviewScaleMode = 'cover';\n // Resolution/aspect-ratio constraints of the current session, kept so\n // flipCamera() re-acquires the stream with the same resolution contract\n // instead of falling back to the browser default.\n private sessionResolutionConstraints: MediaTrackConstraints = {};\n\n // Barcode detection support\n private barcodeDetectionSupported = false;\n private barcodeDetector: BarcodeDetector | null = null;\n\n // Scopes the barcode detection loop to a single start()/stop() session so a\n // rapid stop() -> start() can't let the old loop mistake the new session's\n // running flag for its own and keep polling a detached video element.\n private barcodeDetectionAbortController: AbortController | null = null;\n // The most recently scheduled `requestAnimationFrame` id for the barcode\n // detection loop, so `stop()` can cancel a queued-but-not-yet-run frame\n // outright.\n private barcodeAnimationFrameId: number | null = null;\n\n // Recording state\n private mediaRecorder: MediaRecorder | null = null;\n private recordedChunks: Blob[] = [];\n private recordingAudioTrack: MediaStreamTrack | null = null;\n private recordingResolve: ((response: VideoRecordingResponse) => void) | null = null;\n private recordingReject: ((error: Error) => void) | null = null;\n\n constructor() {\n super();\n this.checkBarcodeDetectionSupport();\n }\n\n /**\n * Start the camera with the given configuration\n */\n async start(options?: CameraSessionConfiguration): Promise<void> {\n // A session is already running. Per the cross-platform contract, reject\n // instead of silently reconfiguring or no-op'ing: callers who need a\n // different configuration (e.g. a different position or resolution) must\n // call `stop()` first and then `start()` again with the new options.\n if (this.#isRunning) {\n throw new CameraViewError('Camera session is already running. Call stop() first.', 'SESSION_ALREADY_RUNNING');\n }\n\n try {\n // Set up video element if it doesn't exist\n if (!this.videoElement) {\n await this.setupVideoElement(options?.containerElementId);\n }\n } catch (err) {\n // The only failure path in setupVideoElement() is the target container\n // element not being found, which is the web equivalent of \"could not\n // find the view to render the camera preview into\".\n throw new CameraViewError(`Failed to start camera: ${this.formatError(err)}`, 'WEBVIEW_UNAVAILABLE');\n }\n\n // Apply the preview scale mode to the video element. `'fit'` letterboxes\n // the whole frame (object-fit: contain); the empty bars show the container's\n // own background. `'cover'` keeps the long-standing center-cropped preview.\n this.sessionPreviewScaleMode = options?.previewScaleMode ?? 'cover';\n if (this.videoElement) {\n this.videoElement.style.objectFit = this.sessionPreviewScaleMode === 'fit' ? 'contain' : 'cover';\n }\n\n // Set up video constraints based on options\n this.sessionAspectRatio = options?.aspectRatio ?? null;\n this.sessionResolutionConstraints = this.buildResolutionConstraints(options);\n const videoConstraints: MediaTrackConstraints = {\n ...this.sessionResolutionConstraints,\n };\n\n // Prefer deviceId if specified\n if (options?.deviceId) {\n videoConstraints.deviceId = { exact: options.deviceId };\n // Remember the current camera mode (though we're using a specific device)\n this.currentCamera = options?.position === 'front' ? 'user' : 'environment';\n } else {\n // Fall back to facing mode\n const facingMode = options?.position === 'front' ? 'user' : 'environment';\n this.currentCamera = facingMode;\n videoConstraints.facingMode = facingMode;\n }\n\n const constraints: MediaStreamConstraints = {\n video: videoConstraints,\n audio: false,\n };\n\n // Acquire the camera exactly once, using the real constraints, and derive\n // the permission outcome from this single call. Probing permission with a\n // throwaway acquisition first would double startup latency, flash the\n // camera indicator twice, and risk a spurious NotReadableError on devices\n // where the camera is exclusive.\n try {\n this.stream = await navigator.mediaDevices.getUserMedia(constraints);\n } catch (err) {\n throw this.mapStartAcquisitionError(err);\n }\n\n try {\n if (this.videoElement) {\n this.videoElement.srcObject = this.stream;\n\n // Some browsers' autoplay policies can reject `play()` (e.g. lack of a\n // recent user gesture). The element is muted + playsInline, which satisfies\n // autoplay policies in virtually all cases, but a rejection must still be\n // handled here rather than left as an unhandled promise rejection.\n try {\n await this.videoElement.play();\n } catch (err) {\n console.warn('[CameraView] Failed to autoplay the video preview', err);\n }\n\n this.#isRunning = true;\n\n // Apply the initial zoom. This also re-establishes zoom on the freshly\n // created video element after a stop()/start() cycle, keeping the\n // applied zoom in sync with `currentZoom` instead of silently resetting\n // to an untransformed element. A zoom failure must not abort start().\n try {\n await this.setZoom({ level: options?.zoomFactor ?? 1.0 });\n } catch (err) {\n console.warn('[CameraView] Failed to apply initial zoom factor', err);\n }\n\n // If barcode detection is enabled and supported, start detection\n if (options?.enableBarcodeDetection) {\n await this.checkBarcodeDetectionSupport();\n\n if (this.barcodeDetectionSupported) {\n await this.configureBarcodeDetector(options?.barcodeTypes);\n this.startBarcodeDetection();\n }\n }\n }\n } catch (err) {\n // The stream was already acquired here, so its tracks are still live.\n // Tear down the partially-initialized session state so the thrown error\n // leaves a clean slate for a subsequent start().\n this.stream?.getTracks().forEach((track) => track.stop());\n this.stream = null;\n this.#isRunning = false;\n if (this.videoElement) {\n this.videoElement.srcObject = null;\n }\n\n throw new CameraViewError(`Failed to start camera: ${this.formatError(err)}`, 'UNKNOWN_ERROR');\n }\n }\n\n /**\n * Builds the resolution/aspect-ratio part of the `getUserMedia` video\n * constraints for a session.\n *\n * `captureMaxDimension` replaces the ideal width (the longer edge in the\n * stream's landscape-oriented coordinate space) and the ideal height is\n * derived from the configured ratio. Everything stays `ideal` so acquisition\n * degrades gracefully on devices that cannot deliver the request.\n */\n private buildResolutionConstraints(options?: CameraSessionConfiguration): MediaTrackConstraints {\n const ratio = options?.aspectRatio === '4:3' ? 4 / 3 : 16 / 9;\n const idealWidth = options?.captureMaxDimension ?? DEFAULT_IDEAL_CAPTURE_WIDTH;\n const idealHeight = Math.round(idealWidth / ratio);\n\n const constraints: MediaTrackConstraints = {\n width: { ideal: idealWidth },\n height: { ideal: idealHeight },\n };\n\n if (options?.aspectRatio) {\n constraints.aspectRatio = { ideal: ratio };\n }\n\n return constraints;\n }\n\n /**\n * Map a `getUserMedia` failure from the real-constraints acquisition in\n * `start()` onto the plugin's error contract.\n *\n * `NotAllowedError` maps to `PERMISSION_DENIED`, `NotFoundError` (no\n * matching device) to `CAMERA_UNAVAILABLE`, and `NotReadableError` (device\n * claimed by another process) to `DEVICE_LOCKED`, matching the codes\n * iOS/Android use. Anything else falls back to `UNKNOWN_ERROR`.\n */\n private mapStartAcquisitionError(err: unknown): CameraViewError {\n if (err instanceof DOMException) {\n switch (err.name) {\n case 'NotAllowedError':\n return new CameraViewError('Camera permission was not granted', 'PERMISSION_DENIED');\n case 'NotFoundError':\n return new CameraViewError(\n 'Failed to start camera: No camera matching the requested configuration was found.',\n 'CAMERA_UNAVAILABLE',\n );\n case 'NotReadableError':\n return new CameraViewError(\n 'Failed to start camera: The camera could not be started, possibly because it is already in use by another application.',\n 'DEVICE_LOCKED',\n );\n }\n }\n return new CameraViewError(`Failed to start camera: ${this.formatError(err)}`, 'UNKNOWN_ERROR');\n }\n\n /**\n * Stop the camera and release resources\n */\n async stop(): Promise<void> {\n if (!this.#isRunning) {\n return;\n }\n\n try {\n // Tear down the barcode detection session tied to this camera session\n // first: abort settles any pending video-ready wait in\n // startBarcodeDetection, and cancelling the animation frame stops a\n // queued detectFrame call from ever running. Together these ensure no\n // stale loop can survive into a subsequent start().\n this.barcodeDetectionAbortController?.abort();\n this.barcodeDetectionAbortController = null;\n if (this.barcodeAnimationFrameId !== null) {\n cancelAnimationFrame(this.barcodeAnimationFrameId);\n this.barcodeAnimationFrameId = null;\n }\n\n // Stop any active recording\n if (this.mediaRecorder && this.mediaRecorder.state !== 'inactive') {\n // Reject any pending stopRecording promise since we're force-stopping.\n // There is no dedicated code for this case, so it falls back to\n // UNKNOWN_ERROR per the plugin's documented \"anything unmappable\"\n // contract.\n this.recordingReject?.(new CameraViewError('Camera session stopped while recording', 'UNKNOWN_ERROR'));\n this.recordingResolve = null;\n this.recordingReject = null;\n this.mediaRecorder.stop();\n this.mediaRecorder = null;\n }\n this.recordedChunks = [];\n if (this.recordingAudioTrack) {\n this.recordingAudioTrack.stop();\n this.recordingAudioTrack = null;\n }\n\n // Stop all tracks in the stream\n if (this.stream) {\n this.stream.getTracks().forEach((track) => track.stop());\n this.stream = null;\n }\n\n // Detach the stream and remove the video element from the DOM\n if (this.videoElement) {\n this.videoElement.pause();\n this.videoElement.srcObject = null;\n this.videoElement.parentNode?.removeChild(this.videoElement);\n this.videoElement = null;\n }\n\n this.#isRunning = false;\n } catch (err) {\n // No dedicated code for a teardown failure; falls back to UNKNOWN_ERROR\n // per the plugin's documented \"anything unmappable\" contract.\n throw new CameraViewError(`Failed to stop camera: ${this.formatError(err)}`, 'UNKNOWN_ERROR');\n }\n }\n\n /**\n * Check if the camera is currently running\n */\n async isRunning(): Promise<IsRunningResponse> {\n return { isRunning: this.#isRunning };\n }\n\n /**\n * Capture a photo using the camera and return it as a base64-encoded JPEG image.\n * Preserves what the user actually sees in the UI, including cropping from object-fit: cover.\n */\n async capture<T extends CaptureOptions = CaptureOptions & { saveToFile?: undefined }>(\n options?: T,\n ): Promise<CaptureResponse<T>> {\n const videoElement = this.videoElement;\n\n if (!this.#isRunning || !videoElement) {\n throw new CameraViewError('Camera is not running', 'SESSION_NOT_RUNNING');\n }\n\n try {\n const canvas = this.getCanvasElement();\n // `fit` mode letterboxes the whole frame and an explicit `aspectRatio`\n // contractually returns the full sensor-ratio frame, so both capture\n // uncropped. Otherwise capture the visible (cover-cropped) region so the\n // output matches what the user sees.\n const captureArea =\n this.sessionPreviewScaleMode === 'fit' || this.sessionAspectRatio\n ? calculateFullFrameArea(videoElement)\n : calculateVisibleArea(videoElement);\n // In CSS-fallback zoom mode the preview is magnified about its center via\n // `transform: scale()`, so tighten the source crop to match the zoomed\n // viewport (this preserves the frame's aspect ratio). Native-zoom mode\n // needs no compensation: the track already delivers the zoomed frame.\n const visibleArea = applyCssZoomCrop(captureArea, this.getCssZoomScale());\n\n drawVisibleAreaToCanvas(canvas, videoElement, visibleArea);\n\n // Mirror the native platforms' default: `quality` is optional and defaults\n // to 90 when omitted. Without this, `options?.quality / 100` would be\n // `NaN` for an undefined quality, which is passed silently to `toBlob`/\n // `toDataURL` (both treat an invalid quality as \"use the default\"), so a\n // caller relying on the documented default would get a different result\n // on web than on iOS/Android.\n const requestedQuality = options?.quality ?? 90;\n const quality = Math.min(1.0, Math.max(0.1, requestedQuality / 100));\n\n if (options?.saveToFile) {\n // Create a blob from canvas and return a blob URL.\n // `path` is native-only (no filesystem path on web), so it is omitted here.\n return new Promise((resolve, reject) => {\n canvas.toBlob(\n (blob) => {\n if (!blob) {\n reject(new CameraViewError('Failed to create blob from canvas', 'IMAGE_COMPRESSION_FAILED'));\n return;\n }\n\n const url = URL.createObjectURL(blob);\n resolve({ webPath: url } as CaptureResponse<T>);\n },\n 'image/jpeg',\n quality,\n );\n });\n } else {\n // Return base64 data\n const base64Data = canvasToBase64(canvas, quality);\n return { photo: base64Data } as CaptureResponse<T>;\n }\n } catch (err) {\n throw new CameraViewError(`Failed to capture photo: ${this.formatError(err)}`, 'FRAME_CAPTURE_ERROR');\n }\n }\n\n /**\n * Web implementation already uses images from the video stream, so this is the same as `capture()`\n */\n async captureSample<T extends CaptureOptions = CaptureOptions & { saveToFile?: undefined }>(\n options?: T,\n ): Promise<CaptureResponse<T>> {\n return this.capture(options);\n }\n\n /**\n * Start recording video using MediaRecorder API\n */\n async startRecording(options?: VideoRecordingOptions): Promise<void> {\n if (!this.#isRunning || !this.videoElement) {\n throw new CameraViewError('Camera is not running', 'SESSION_NOT_RUNNING');\n }\n\n if (this.mediaRecorder) {\n throw new CameraViewError('Recording is already in progress', 'RECORDING_ALREADY_IN_PROGRESS');\n }\n\n try {\n let stream = this.stream;\n\n // If audio is requested, get a new stream with audio track\n if (options?.enableAudio && stream) {\n const audioStream = await navigator.mediaDevices.getUserMedia({ audio: true });\n const audioTrack = audioStream.getAudioTracks()[0];\n this.recordingAudioTrack = audioTrack;\n const videoTracks = stream.getVideoTracks();\n stream = new MediaStream([...videoTracks, audioTrack]);\n }\n\n if (!stream) {\n throw new Error('No camera stream available');\n }\n\n this.recordedChunks = [];\n\n const mimeType = ['video/webm;codecs=vp9', 'video/webm', 'video/mp4'].find((type) =>\n MediaRecorder.isTypeSupported(type),\n );\n\n if (!mimeType) {\n throw new Error('No supported video recording format found');\n }\n\n this.mediaRecorder = new MediaRecorder(stream, { mimeType });\n\n this.mediaRecorder.ondataavailable = (event) => {\n if (event.data && event.data.size > 0) {\n this.recordedChunks.push(event.data);\n }\n };\n\n this.mediaRecorder.onstop = () => {\n // Stop audio track if it was added for recording\n if (this.recordingAudioTrack) {\n this.recordingAudioTrack.stop();\n this.recordingAudioTrack = null;\n }\n const blob = new Blob(this.recordedChunks, { type: mimeType });\n const url = URL.createObjectURL(blob);\n this.recordedChunks = [];\n this.mediaRecorder = null;\n this.recordingResolve?.({ webPath: url });\n this.recordingResolve = null;\n this.recordingReject = null;\n };\n\n this.mediaRecorder.onerror = (event) => {\n if (this.recordingAudioTrack) {\n this.recordingAudioTrack.stop();\n this.recordingAudioTrack = null;\n }\n this.mediaRecorder = null;\n this.recordedChunks = [];\n const errorMessage = (event as ErrorEvent).error?.message ?? 'Unknown recording error';\n // A generic MediaRecorder runtime failure has no dedicated code, so\n // it falls back to UNKNOWN_ERROR per the plugin's documented\n // \"anything unmappable\" contract.\n this.recordingReject?.(new CameraViewError('Recording error: ' + errorMessage, 'UNKNOWN_ERROR'));\n this.recordingResolve = null;\n this.recordingReject = null;\n };\n\n this.mediaRecorder.start(100); // Collect data in 100ms chunks\n } catch (err) {\n if (this.recordingAudioTrack) {\n this.recordingAudioTrack.stop();\n this.recordingAudioTrack = null;\n }\n this.mediaRecorder = null;\n this.recordedChunks = [];\n throw new CameraViewError(\n `Failed to start recording: ${this.formatError(err)}`,\n this.mapRecordingStartErrorCode(err),\n );\n }\n }\n\n /**\n * Maps a failure caught by `startRecording()`'s try/catch onto the closest-\n * fitting `CameraErrorCode`, without altering the existing wrapped message.\n *\n * A `DOMException` here can only come from the microphone `getUserMedia`\n * call, so it is classified with `kind: 'microphone'`. The two other\n * distinguishable failures are plain `Error`s matched by message text.\n */\n private mapRecordingStartErrorCode(err: unknown): CameraErrorCode {\n if (err instanceof DOMException) {\n return classifyGetUserMediaErrorCode(err, 'microphone');\n }\n if (err instanceof Error) {\n if (err.message === 'No camera stream available') {\n return 'CAMERA_UNAVAILABLE';\n }\n if (err.message === 'No supported video recording format found') {\n return 'CONFIGURATION_FAILED';\n }\n }\n return 'UNKNOWN_ERROR';\n }\n\n /**\n * Stop the current video recording\n */\n async stopRecording(): Promise<VideoRecordingResponse> {\n if (!this.mediaRecorder) {\n throw new CameraViewError('No recording is in progress', 'NO_RECORDING_IN_PROGRESS');\n }\n\n // A stop is already pending. Reject this second call instead of\n // overwriting the pending callbacks, which would orphan the first caller's\n // promise forever.\n if (this.recordingResolve || this.recordingReject) {\n throw new CameraViewError('stopRecording() is already pending', 'UNKNOWN_ERROR');\n }\n\n return new Promise<VideoRecordingResponse>((resolve, reject) => {\n this.recordingResolve = resolve;\n this.recordingReject = reject;\n this.mediaRecorder?.stop();\n });\n }\n\n /**\n * Flip between front and back camera\n */\n public async flipCamera(): Promise<void> {\n if (!this.#isRunning) {\n throw new CameraViewError('Camera is not running', 'SESSION_NOT_RUNNING');\n }\n\n // Flipping restarts the stream and stops the tracks the MediaRecorder is\n // consuming, which would silently freeze an in-progress recording. Reject\n // instead so the caller can stop recording first; the recording stays\n // intact.\n if (this.mediaRecorder && this.mediaRecorder.state !== 'inactive') {\n throw new CameraViewError('Cannot flip camera while a recording is in progress', 'RECORDING_ALREADY_IN_PROGRESS');\n }\n\n // The candidate facing mode, kept local until the new stream is actually\n // live: `currentCamera` (and the previous stream) must not be touched\n // before that point, or a failed re-acquisition below would leave the\n // session state pointing at a camera that isn't running while the\n // previous camera's tracks have already been stopped.\n const nextCamera = this.currentCamera === 'user' ? 'environment' : 'user';\n\n // Acquire the new-facing stream with the new facing mode, keeping the\n // session's resolution/aspect-ratio constraints so the flipped stream\n // honors the same contract as the one it replaces.\n const constraints: MediaStreamConstraints = {\n video: {\n ...this.sessionResolutionConstraints,\n facingMode: nextCamera,\n },\n audio: false,\n };\n\n let newStream: MediaStream;\n try {\n newStream = await navigator.mediaDevices.getUserMedia(constraints);\n } catch (err) {\n // Acquisition failed: `stream`/`currentCamera` haven't been touched, so\n // the previous camera is still attached and running. Just surface the\n // error. The only `getUserMedia` call in this method re-acquires the\n // camera (never the microphone), so classify with kind: 'camera'.\n throw new CameraViewError(\n `Failed to flip camera: ${this.formatError(err)}`,\n classifyGetUserMediaErrorCode(err, 'camera'),\n );\n }\n\n // The new stream is live: safe to stop the previous stream's tracks and\n // commit the flipped state.\n this.stream?.getTracks().forEach((track) => track.stop());\n this.stream = newStream;\n this.currentCamera = nextCamera;\n\n if (this.videoElement) {\n this.videoElement.srcObject = newStream;\n }\n\n // Re-apply the session's zoom level to the new stream through the normal\n // setZoom() path - a flip otherwise silently drops native-zoom's applied\n // constraint (reset on the fresh track) or leaves CSS-fallback's\n // transform stale against the fresh element state. Best-effort: a zoom\n // failure must not fail the flip itself.\n try {\n await this.setZoom({ level: this.currentZoom });\n } catch (err) {\n console.warn('[CameraView] Failed to re-apply zoom after flipping camera', err);\n }\n }\n\n /**\n * Get available camera devices.\n *\n * Position detection prefers the `facingMode` capability of the active video\n * track, since it is a standardized signal rather than a locale-dependent\n * string. Every other device falls back to matching the English word \"front\"\n * in `device.label` — which is empty for all devices until camera permission\n * has been granted once, so the fallback resolves to `'back'` in that case.\n */\n public async getAvailableDevices(): Promise<GetAvailableDevicesResponse> {\n try {\n const devices = await navigator.mediaDevices.enumerateDevices();\n const videoDevices = devices.filter((device) => device.kind === 'videoinput');\n\n const activeTrack = this.getVideoTrack();\n const activeDeviceId = activeTrack?.getSettings().deviceId;\n const activeFacingMode =\n activeTrack && typeof activeTrack.getCapabilities === 'function'\n ? activeTrack.getCapabilities().facingMode?.[0]\n : undefined;\n\n return {\n devices: videoDevices.map((device) => {\n const position: CameraPosition =\n device.deviceId === activeDeviceId && activeFacingMode\n ? activeFacingMode === 'user'\n ? 'front'\n : 'back'\n : device.label.toLowerCase().includes('front')\n ? 'front'\n : 'back';\n\n return {\n id: device.deviceId,\n name: device.label || `Camera ${device.deviceId.substring(0, 5)}`,\n position,\n };\n }),\n };\n } catch (err) {\n console.error('Failed to get available devices', err);\n return { devices: [] };\n }\n }\n\n /**\n * Get current zoom information.\n *\n * When the active video track exposes a native `zoom` capability (Chromium\n * on capable cameras), the real min/max/current are reported. Otherwise the\n * simulated CSS-scale range is returned.\n */\n public async getZoom(): Promise<GetZoomResponse> {\n const track = this.getVideoTrack();\n const capability = this.getNativeZoomCapability(track);\n\n if (track && capability) {\n const settings = track.getSettings() as ZoomSettings;\n return {\n min: capability.min,\n max: capability.max,\n current: typeof settings.zoom === 'number' ? settings.zoom : this.currentZoom,\n };\n }\n\n // No native zoom: report the simulated CSS-scale range.\n return {\n min: SIMULATED_ZOOM_MIN,\n max: SIMULATED_ZOOM_MAX,\n current: this.currentZoom,\n };\n }\n\n /**\n * Set the zoom level.\n *\n * Prefers real zoom via `track.applyConstraints({ advanced: [{ zoom }] })`\n * when the browser exposes the native `zoom` capability, clamping to the\n * reported range. Falls back to a CSS `transform: scale()` simulation\n * otherwise.\n */\n public async setZoom(options: { level: number; ramp?: boolean }): Promise<void> {\n const track = this.getVideoTrack();\n const capability = this.getNativeZoomCapability(track);\n\n if (track && capability) {\n const clamped = Math.max(capability.min, Math.min(options.level, capability.max));\n await track.applyConstraints({ advanced: [{ zoom: clamped } as ZoomConstraintSet] });\n this.currentZoom = clamped;\n this.usingNativeZoom = true;\n\n // Clear any CSS transform left over from a previous fallback so the two\n // zoom mechanisms can't stack.\n if (this.videoElement) {\n this.videoElement.style.transform = '';\n }\n return;\n }\n\n // CSS-transform fallback.\n this.usingNativeZoom = false;\n this.currentZoom = options.level;\n\n if (this.videoElement) {\n this.videoElement.style.transition = options.ramp ? 'transform 0.2s ease-in-out' : 'none';\n this.videoElement.style.transform = `scale(${this.getCssZoomScale()})`;\n this.videoElement.style.transformOrigin = 'center';\n }\n }\n\n /**\n * The video track backing the active stream, or `null`.\n */\n private getVideoTrack(): MediaStreamTrack | null {\n return this.stream?.getVideoTracks()[0] ?? null;\n }\n\n /**\n * Reads the native `zoom` capability off a track, if the browser both\n * supports `getCapabilities()` and exposes a usable `zoom` range on this\n * device. Returns `null` when native zoom is unavailable (CSS fallback).\n */\n private getNativeZoomCapability(track: MediaStreamTrack | null): ZoomCapability | null {\n if (!track || typeof track.getCapabilities !== 'function') {\n return null;\n }\n\n const zoom = (track.getCapabilities() as ZoomCapabilities).zoom;\n if (zoom && typeof zoom.min === 'number' && typeof zoom.max === 'number' && zoom.max > zoom.min) {\n return zoom;\n }\n return null;\n }\n\n /**\n * The effective CSS `transform: scale()` factor currently applied to the\n * preview: `1` when native zoom is in use (no transform), otherwise\n * `currentZoom` clamped to the simulated range. Used both to set the\n * transform and to compensate captures for it.\n */\n private getCssZoomScale(): number {\n if (this.usingNativeZoom) {\n return 1;\n }\n return Math.max(SIMULATED_ZOOM_MIN, Math.min(this.currentZoom, SIMULATED_ZOOM_MAX));\n }\n\n /**\n * Set the focus/metering point (not supported in web).\n *\n * The `pointsOfInterest` media-track constraint has effectively no browser\n * support, so this rejects with `unimplemented` rather than silently doing\n * nothing. Left as a hook for a future implementation.\n */\n public async setFocusPoint(): Promise<void> {\n throw this.unimplemented('Focus point control is not supported in the web implementation.');\n }\n\n /**\n * Get current flash mode\n */\n public async getFlashMode(): Promise<GetFlashModeResponse> {\n return { flashMode: this.currentFlashMode };\n }\n\n /**\n * Get supported flash modes\n */\n public async getSupportedFlashModes(): Promise<GetSupportedFlashModesResponse> {\n // Web has limited flash control\n return { flashModes: ['off'] };\n }\n\n /**\n * Set flash mode (limited support in web).\n *\n * Only `'off'` is supported on web; any other mode rejects rather than\n * silently accepting a mode it cannot apply.\n */\n public async setFlashMode(options: { mode: FlashMode }): Promise<void> {\n if (options.mode !== 'off') {\n throw this.unimplemented('Flash mode control is not supported in the web implementation.');\n }\n this.currentFlashMode = 'off';\n }\n\n /**\n * Check if torch is available (not supported in web)\n */\n public async isTorchAvailable(): Promise<IsTorchAvailableResponse> {\n // Torch is not supported in web implementation\n return { available: false };\n }\n\n /**\n * Get torch mode (not supported in web).\n *\n * Follows the documented contract for `getTorchMode()`: callers must check\n * `isTorchAvailable()` first, which always reports `false` on web, so this throws\n * rather than returning a fabricated \"off\" state.\n */\n public async getTorchMode(): Promise<GetTorchModeResponse> {\n throw this.unimplemented('Torch control is not supported in web implementation.');\n }\n\n /**\n * Set torch mode (not supported in web)\n */\n public async setTorchMode(): Promise<void> {\n // Torch is not supported in web implementation\n throw this.unimplemented('Torch control is not supported in web implementation.');\n }\n\n /**\n * Check camera and microphone permission without requesting\n */\n public async checkPermissions(): Promise<PermissionStatus> {\n const [camera, microphone] = await Promise.all([\n this.checkSinglePermission('camera'),\n this.checkSinglePermission('microphone'),\n ]);\n return { camera, microphone };\n }\n\n /**\n * Resolves the current state of a single permission.\n *\n * Queried independently per permission name so one unsupported query (e.g.\n * Firefox does not support querying `'microphone'`) rejects on its own\n * instead of collapsing *both* permissions to `'prompt'`.\n */\n private async checkSinglePermission(name: CameraPermissionType): Promise<PermissionState> {\n if (navigator.permissions) {\n try {\n const result = await navigator.permissions.query({ name: name as PermissionName });\n return result.state === 'granted' ? 'granted' : result.state === 'denied' ? 'denied' : 'prompt';\n } catch {\n // This permission name is not supported by the Permissions API in this\n // browser; fall through to the best-effort fallback below instead of\n // failing the other permission's check too.\n }\n }\n\n // If the Permissions API is unavailable/unsupported for this name, fall back to\n // checking the active stream for camera; there is no equivalent signal for\n // microphone without an active audio track, so it stays 'prompt'.\n if (name === 'camera') {\n return this.stream ? 'granted' : 'prompt';\n }\n return 'prompt';\n }\n\n /**\n * Request camera and/or microphone permissions from the user.\n * By default, only camera permission is requested.\n */\n public async requestPermissions(options?: { permissions?: CameraPermissionType[] }): Promise<PermissionStatus> {\n const permissions = options?.permissions ?? ['camera'];\n const result: PermissionStatus = { camera: 'prompt', microphone: 'prompt' };\n\n // Request camera permission if included\n if (permissions.includes('camera')) {\n try {\n const stream = await navigator.mediaDevices.getUserMedia({ video: true });\n stream.getTracks().forEach((track) => track.stop());\n result.camera = 'granted';\n } catch {\n result.camera = 'denied';\n }\n } else {\n // Still report current status even if not requesting\n result.camera = (await this.checkPermissions()).camera;\n }\n\n // Request microphone permission only if explicitly included\n if (permissions.includes('microphone')) {\n try {\n const stream = await navigator.mediaDevices.getUserMedia({ audio: true });\n stream.getTracks().forEach((track) => track.stop());\n result.microphone = 'granted';\n } catch {\n result.microphone = 'denied';\n }\n } else {\n result.microphone = (await this.checkPermissions()).microphone;\n }\n\n return result;\n }\n\n /**\n * Start barcode detection if supported\n */\n private async startBarcodeDetection() {\n const barcodeDetector = this.barcodeDetector;\n const videoElement = this.videoElement;\n\n if (!this.barcodeDetectionSupported || !barcodeDetector || !videoElement) {\n return;\n }\n\n // Scope this loop to its own session. Aborting the previous controller\n // (defensive - start() only calls in here once per session) and handing\n // out a fresh signal means a stale detectFrame closure from an earlier\n // session can never mistake a later session's #isRunning === true for\n // its own \"keep going\" signal.\n this.barcodeDetectionAbortController?.abort();\n const abortController = new AbortController();\n this.barcodeDetectionAbortController = abortController;\n const { signal } = abortController;\n\n // Make sure video is fully loaded before starting detection. The wait\n // settles - without starting detection - as soon as the session is\n // stopped (`signal` aborts), and a timeout backstops the case where the\n // video never fires `loadeddata` at all, so neither path leaves a\n // dangling listener or a permanently pending promise.\n if (videoElement.readyState < 2) {\n const videoReady = await new Promise<boolean>((resolve) => {\n const cleanup = () => {\n videoElement.removeEventListener('loadeddata', loadHandler);\n signal.removeEventListener('abort', abortHandler);\n clearTimeout(timeoutId);\n };\n const loadHandler = () => {\n cleanup();\n resolve(true);\n };\n const abortHandler = () => {\n cleanup();\n resolve(false);\n };\n const timeoutId = setTimeout(() => {\n cleanup();\n resolve(false);\n }, BARCODE_VIDEO_READY_TIMEOUT_MS);\n\n videoElement.addEventListener('loadeddata', loadHandler);\n signal.addEventListener('abort', abortHandler);\n });\n\n if (!videoReady || signal.aborted) {\n return;\n }\n }\n\n if (signal.aborted) {\n return;\n }\n\n // Add throttling to reduce CPU usage\n let lastDetectionTime = 0;\n const minTimeBetweenDetections = 100; // ms\n\n // Dedupe state: timestamps of recently emitted barcodes keyed by value +\n // type. A per-key map (rather than a single \"last\" slot) is required so\n // multiple codes in frame can't alternate and defeat the suppression\n // window. Closure-local, so it resets on every start().\n const recentBarcodeEmitTimes = new Map<string, number>();\n\n // Set up periodic frame analysis for barcode detection\n const detectFrame = async () => {\n // `signal.aborted` is this loop's own session check: it stays true for\n // this closure even if a rapid stop() -> start() flips #isRunning back\n // to true for a *new* session before this frame runs. `#isRunning` is\n // kept as a defensive secondary check.\n if (signal.aborted || !this.#isRunning || !videoElement || !barcodeDetector) {\n return;\n }\n\n // Monotonic clock: a backward wall-clock jump must not extend the\n // throttle or suppression windows arbitrarily.\n const now = performance.now();\n if (now - lastDetectionTime >= minTimeBetweenDetections) {\n try {\n const barcodes = await barcodeDetector.detect(videoElement);\n lastDetectionTime = now;\n\n if (barcodes.length > 0) {\n const barcode = barcodes[0];\n\n // Normalize the web BarcodeDetector format onto the shared BarcodeType\n // vocabulary. Fall back to the raw format for the few detector formats\n // that have no BarcodeType equivalent (e.g. 'unknown'); the emitted\n // `type` is therefore `BarcodeType | string`.\n const type = WEB_FORMAT_TO_BARCODE_TYPE[barcode.format] ?? barcode.format;\n\n // Rate control: suppress re-emission of the same code (value + type)\n // within the suppression window. A genuinely new code has a different\n // key and emits immediately. Timestamps are tracked per key so\n // multiple codes in frame can't alternate and defeat the window.\n const barcodeKey = `${type}\\u0000${barcode.rawValue}`;\n const lastEmit = recentBarcodeEmitTimes.get(barcodeKey);\n if (lastEmit === undefined || now - lastEmit >= BARCODE_SUPPRESSION_WINDOW_MS) {\n // Prune expired entries once the map grows, keeping it bounded\n // during long sessions that scan many different codes.\n if (recentBarcodeEmitTimes.size > BARCODE_DEDUPE_MAP_PRUNE_THRESHOLD) {\n for (const [key, emitTime] of recentBarcodeEmitTimes) {\n if (now - emitTime >= BARCODE_SUPPRESSION_WINDOW_MS) {\n recentBarcodeEmitTimes.delete(key);\n }\n }\n }\n recentBarcodeEmitTimes.set(barcodeKey, now);\n\n // Transform barcode coordinates using the utility function,\n // accounting for the session's preview scale mode (cover crops,\n // fit letterboxes) so the rect lands over the on-screen barcode.\n const boundingRect = transformBarcodeBoundingBox(\n barcode.boundingBox,\n videoElement,\n this.sessionPreviewScaleMode,\n );\n\n this.notifyListeners('barcodeDetected', {\n value: barcode.rawValue,\n type,\n boundingRect,\n });\n }\n }\n } catch (err) {\n console.error('Barcode detection error', err);\n }\n }\n\n if (!signal.aborted && this.#isRunning) {\n this.barcodeAnimationFrameId = requestAnimationFrame(detectFrame);\n }\n };\n\n this.barcodeAnimationFrameId = requestAnimationFrame(detectFrame);\n }\n\n /**\n * Check if barcode detection is supported in this browser\n */\n private async checkBarcodeDetectionSupport() {\n if ('BarcodeDetector' in window) {\n try {\n this.barcodeDetector = new BarcodeDetector();\n this.barcodeDetectionSupported = true;\n } catch (e) {\n console.warn('BarcodeDetector is not supported by this browser.');\n this.barcodeDetectionSupported = false;\n }\n }\n }\n\n /**\n * Configure the barcode detector with requested barcode formats.\n * Unsupported formats are ignored and logged.\n */\n private async configureBarcodeDetector(barcodeTypes?: BarcodeType[]): Promise<void> {\n if (!this.barcodeDetectionSupported) {\n return;\n }\n\n if (!barcodeTypes?.length) {\n this.barcodeDetector = new BarcodeDetector();\n return;\n }\n\n const requestedFormats = barcodeTypes\n .map((barcodeType) => {\n const webFormat = BARCODE_TYPE_TO_WEB_FORMAT[barcodeType];\n if (!webFormat) {\n console.warn(`[CameraView] Barcode type \"${barcodeType}\" is not supported by the web BarcodeDetector API.`);\n }\n return webFormat;\n })\n .filter((format): format is NonNullable<typeof format> => format !== null);\n\n if (!requestedFormats.length) {\n console.warn(\n '[CameraView] No requested barcode types are supported on web. Falling back to all supported formats.',\n );\n this.barcodeDetector = new BarcodeDetector();\n return;\n }\n\n const uniqueRequestedFormats = Array.from(new Set(requestedFormats));\n\n try {\n const supportedFormats = await BarcodeDetector.getSupportedFormats();\n const configuredFormats = uniqueRequestedFormats.filter((format) => supportedFormats.includes(format));\n const ignoredFormats = uniqueRequestedFormats.filter((format) => !supportedFormats.includes(format));\n\n if (ignoredFormats.length) {\n console.warn(\n `[CameraView] Ignoring unsupported barcode formats for this browser: ${ignoredFormats.join(', ')}.`,\n );\n }\n\n if (!configuredFormats.length) {\n console.warn(\n '[CameraView] No requested barcode formats are available in this browser. Falling back to all supported formats.',\n );\n this.barcodeDetector = new BarcodeDetector();\n return;\n }\n\n this.barcodeDetector = new BarcodeDetector({ formats: configuredFormats });\n } catch (error) {\n console.warn(\n '[CameraView] Failed to resolve supported barcode formats; falling back to unfiltered detector.',\n error,\n );\n this.barcodeDetector = new BarcodeDetector();\n }\n }\n\n /**\n * Set up the video element for the camera view\n */\n private async setupVideoElement(containerElementId?: string) {\n this.videoElement = document.createElement('video');\n this.videoElement.playsInline = true;\n this.videoElement.autoplay = true;\n this.videoElement.muted = true;\n this.videoElement.style.width = '100%';\n this.videoElement.style.height = '100%';\n this.videoElement.style.objectFit = 'cover';\n\n // If a container ID is provided, find that element and append the video to it\n if (containerElementId) {\n const container = document.getElementById(containerElementId);\n if (!container) {\n throw new Error(`Container element with ID ${containerElementId} not found`);\n }\n container.appendChild(this.videoElement);\n } else {\n // Otherwise, append to body as fallback\n document.body.appendChild(this.videoElement);\n }\n }\n\n /**\n * Ensures canvas element exists and returns it\n */\n private getCanvasElement(): HTMLCanvasElement {\n if (!this.canvasElement) {\n this.canvasElement = document.createElement('canvas');\n }\n return this.canvasElement;\n }\n\n /**\n * Format error message\n */\n private formatError(err: unknown): string {\n return err instanceof Error ? err.message : String(err);\n }\n}\n"]}