| 
						
						
							
								
							
						
						
					 | 
					@ -4,7 +4,9 @@ | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					      <div class="text-lg text-center font-bold relative"> | 
					 | 
					 | 
					      <div class="text-lg text-center font-bold relative"> | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					        <h1 id="ViewHeading" class="text-center font-bold"> | 
					 | 
					 | 
					        <h1 id="ViewHeading" class="text-center font-bold"> | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					          <span v-if="uploading">Uploading Image…</span> | 
					 | 
					 | 
					          <span v-if="uploading">Uploading Image…</span> | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					          <span v-else-if="blob">{{ crop ? 'Crop Image' : 'Preview Image' }}</span> | 
					 | 
					 | 
					          <span v-else-if="blob">{{ | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					            crop ? "Crop Image" : "Preview Image" | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					          }}</span> | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					          <span v-else-if="showCameraPreview">Upload Image</span> | 
					 | 
					 | 
					          <span v-else-if="showCameraPreview">Upload Image</span> | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					          <span v-else>Add Photo</span> | 
					 | 
					 | 
					          <span v-else>Add Photo</span> | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					        </h1> | 
					 | 
					 | 
					        </h1> | 
				
			
			
		
	
	
		
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
					@ -119,7 +121,9 @@ | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					                  playsinline | 
					 | 
					 | 
					                  playsinline | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					                  muted | 
					 | 
					 | 
					                  muted | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					                ></video> | 
					 | 
					 | 
					                ></video> | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					                <div class="absolute bottom-4 inset-x-0 flex items-center justify-center gap-4"> | 
					 | 
					 | 
					                <div | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					                  class="absolute bottom-4 inset-x-0 flex items-center justify-center gap-4" | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					                > | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					                  <button | 
					 | 
					 | 
					                  <button | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					                    class="bg-white text-slate-800 p-3 rounded-full text-2xl leading-none" | 
					 | 
					 | 
					                    class="bg-white text-slate-800 p-3 rounded-full text-2xl leading-none" | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					                    @click="capturePhoto" | 
					 | 
					 | 
					                    @click="capturePhoto" | 
				
			
			
		
	
	
		
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
					@ -278,9 +282,9 @@ const inputImageFileNameRef = ref<Blob>(); | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					    }, | 
					 | 
					 | 
					    }, | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					    defaultCameraMode: { | 
					 | 
					 | 
					    defaultCameraMode: { | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					      type: String, | 
					 | 
					 | 
					      type: String, | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					      default: 'environment', | 
					 | 
					 | 
					      default: "environment", | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					      validator: (value: string) => ['environment', 'user'].includes(value) | 
					 | 
					 | 
					      validator: (value: string) => ["environment", "user"].includes(value), | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					    } | 
					 | 
					 | 
					    }, | 
				
			
			
				
				
			
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					 | 
					 | 
					  }, | 
					 | 
					 | 
					  }, | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					}) | 
					 | 
					 | 
					}) | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					export default class ImageMethodDialog extends Vue { | 
					 | 
					 | 
					export default class ImageMethodDialog extends Vue { | 
				
			
			
		
	
	
		
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
					@ -323,7 +327,7 @@ export default class ImageMethodDialog extends Vue { | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					  private cameraStream: MediaStream | null = null; | 
					 | 
					 | 
					  private cameraStream: MediaStream | null = null; | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					
 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					  /** Current camera facing mode */ | 
					 | 
					 | 
					  /** Current camera facing mode */ | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					  private currentFacingMode: 'environment' | 'user' = 'environment'; | 
					 | 
					 | 
					  private currentFacingMode: "environment" | "user" = "environment"; | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					 | 
					 | 
					
 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					  private platformService = PlatformServiceFactory.getInstance(); | 
					 | 
					 | 
					  private platformService = PlatformServiceFactory.getInstance(); | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					  URL = window.URL || window.webkitURL; | 
					 | 
					 | 
					  URL = window.URL || window.webkitURL; | 
				
			
			
		
	
	
		
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
					@ -391,7 +395,7 @@ export default class ImageMethodDialog extends Vue { | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					    this.crop = !!crop; | 
					 | 
					 | 
					    this.crop = !!crop; | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					    this.imageCallback = setImageFn; | 
					 | 
					 | 
					    this.imageCallback = setImageFn; | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					    this.visible = true; | 
					 | 
					 | 
					    this.visible = true; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					    this.currentFacingMode = this.defaultCameraMode as 'environment' | 'user'; | 
					 | 
					 | 
					    this.currentFacingMode = this.defaultCameraMode as "environment" | "user"; | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					 | 
					 | 
					
 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					    // Start camera preview immediately | 
					 | 
					 | 
					    // Start camera preview immediately | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					    logger.debug("Starting camera preview from open()"); | 
					 | 
					 | 
					    logger.debug("Starting camera preview from open()"); | 
				
			
			
		
	
	
		
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
					@ -465,7 +469,10 @@ export default class ImageMethodDialog extends Vue { | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					    logger.debug("Current showCameraPreview state:", this.showCameraPreview); | 
					 | 
					 | 
					    logger.debug("Current showCameraPreview state:", this.showCameraPreview); | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					    logger.debug("Platform capabilities:", this.platformCapabilities); | 
					 | 
					 | 
					    logger.debug("Platform capabilities:", this.platformCapabilities); | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					    logger.debug("MediaDevices available:", !!navigator.mediaDevices); | 
					 | 
					 | 
					    logger.debug("MediaDevices available:", !!navigator.mediaDevices); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					    logger.debug("getUserMedia available:", !!(navigator.mediaDevices && navigator.mediaDevices.getUserMedia)); | 
					 | 
					 | 
					    logger.debug( | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					      "getUserMedia available:", | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					      !!(navigator.mediaDevices && navigator.mediaDevices.getUserMedia), | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					    ); | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					
 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					    try { | 
					 | 
					 | 
					    try { | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					      this.cameraState = "initializing"; | 
					 | 
					 | 
					      this.cameraState = "initializing"; | 
				
			
			
		
	
	
		
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
					@ -492,13 +499,16 @@ export default class ImageMethodDialog extends Vue { | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					        videoElement.srcObject = stream; | 
					 | 
					 | 
					        videoElement.srcObject = stream; | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					        await new Promise((resolve) => { | 
					 | 
					 | 
					        await new Promise((resolve) => { | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					          videoElement.onloadedmetadata = () => { | 
					 | 
					 | 
					          videoElement.onloadedmetadata = () => { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					            videoElement.play().then(() => { | 
					 | 
					 | 
					            videoElement | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					              logger.debug("Video element started playing"); | 
					 | 
					 | 
					              .play() | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					              resolve(true); | 
					 | 
					 | 
					              .then(() => { | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					            }).catch(error => { | 
					 | 
					 | 
					                logger.debug("Video element started playing"); | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					              logger.error("Error playing video:", error); | 
					 | 
					 | 
					                resolve(true); | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					              throw error; | 
					 | 
					 | 
					              }) | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					            }); | 
					 | 
					 | 
					              .catch((error) => { | 
				
			
			
				
				
			
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					                logger.error("Error playing video:", error); | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					                throw error; | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					              }); | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					          }; | 
					 | 
					 | 
					          }; | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					        }); | 
					 | 
					 | 
					        }); | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					      } else { | 
					 | 
					 | 
					      } else { | 
				
			
			
		
	
	
		
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
					@ -510,17 +520,16 @@ export default class ImageMethodDialog extends Vue { | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					      let errorMessage = | 
					 | 
					 | 
					      let errorMessage = | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					        error instanceof Error ? error.message : "Failed to access camera"; | 
					 | 
					 | 
					        error instanceof Error ? error.message : "Failed to access camera"; | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					      if ( | 
					 | 
					 | 
					      if ( | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					        error instanceof Error && ( | 
					 | 
					 | 
					        error instanceof Error && | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					        error.name === "NotReadableError" || | 
					 | 
					 | 
					        (error.name === "NotReadableError" || error.name === "TrackStartError") | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					        error.name === "TrackStartError" | 
					 | 
					 | 
					      ) { | 
				
			
			
				
				
			
		
	
		
		
			
				
					 | 
					 | 
					      )) { | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					 | 
					 | 
					        errorMessage = | 
					 | 
					 | 
					        errorMessage = | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					          "Camera is in use by another application. Please close any other apps or browser tabs using the camera and try again."; | 
					 | 
					 | 
					          "Camera is in use by another application. Please close any other apps or browser tabs using the camera and try again."; | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					      } else if ( | 
					 | 
					 | 
					      } else if ( | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					        error instanceof Error && ( | 
					 | 
					 | 
					        error instanceof Error && | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					        error.name === "NotAllowedError" || | 
					 | 
					 | 
					        (error.name === "NotAllowedError" || | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					        error.name === "PermissionDeniedError" | 
					 | 
					 | 
					          error.name === "PermissionDeniedError") | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					      )) { | 
					 | 
					 | 
					      ) { | 
				
			
			
				
				
			
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					 | 
					 | 
					        errorMessage = | 
					 | 
					 | 
					        errorMessage = | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					          "Camera access was denied. Please allow camera access in your browser settings."; | 
					 | 
					 | 
					          "Camera access was denied. Please allow camera access in your browser settings."; | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					      } | 
					 | 
					 | 
					      } | 
				
			
			
		
	
	
		
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
					@ -590,11 +599,12 @@ export default class ImageMethodDialog extends Vue { | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					
 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					  async rotateCamera() { | 
					 | 
					 | 
					  async rotateCamera() { | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					    // Toggle between front and back cameras | 
					 | 
					 | 
					    // Toggle between front and back cameras | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					    this.currentFacingMode = this.currentFacingMode === 'environment' ? 'user' : 'environment'; | 
					 | 
					 | 
					    this.currentFacingMode = | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					     | 
					 | 
					 | 
					      this.currentFacingMode === "environment" ? "user" : "environment"; | 
				
			
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					    // Stop current stream | 
					 | 
					 | 
					    // Stop current stream | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					    if (this.cameraStream) { | 
					 | 
					 | 
					    if (this.cameraStream) { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					      this.cameraStream.getTracks().forEach(track => track.stop()); | 
					 | 
					 | 
					      this.cameraStream.getTracks().forEach((track) => track.stop()); | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					 | 
					 | 
					      this.cameraStream = null; | 
					 | 
					 | 
					      this.cameraStream = null; | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					    } | 
					 | 
					 | 
					    } | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					
 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
	
		
		
			
				
					| 
						
							
								
							
						
						
						
					 | 
					
  |