getLocation();
            
            function getLocation() {
                navigator.geolocation.getCurrentPosition(function (position) {
                    var vLat = position.coords.latitude;
                    var vLong = position.coords.longitude;
                    camera(vLat, vLong);
            	}, function (e) {
            	    $.ajax({
            			type 	: 'POST',
            			url		: "admin/data/absensipegawai?act=<?= my_crypt('error-lokasi', 'E')?>",
            			success	: function () {
            				document.location='index?view=absensi pegawai';
            			}
            		})
            	}, {
            	    enableHighAccuracy: true
            	});
            }
            
            function getIpAddress(callback){
                var pc = new RTCPeerConnection();
                var ip = { "address": "", "version": "" };
                var ipNew;
                pc.createDataChannel("");
                pc.onicecandidate = function(e) {
                  if (e.candidate == null) {
                    var sdp = pc.localDescription.sdp;
                    var i = sdp.indexOf("c=");
                    var line = sdp.substring(i, sdp.indexOf("\n", i));
                    var parts = line.split(" ");
                
                    ip.address = parts[2];
                    ip.version = parts[1] === "IP4" ? "IPv4" : "IPv6";
                    callback(ip.address);
                  }
                };
                pc.createOffer().then(function(offer) {
                  pc.setLocalDescription(offer);
                });
            }
            
            function camera(vLat, vLong){
                let selectedDeviceId;
                let currentStream;
                const hints = new Map();
                let scanningInProgress = false;
                
                hints.set(ZXing.DecodeHintType.POSSIBLE_FORMATS, [
                  ZXing.BarcodeFormat.CODE_128,
                  ZXing.BarcodeFormat.QR_CODE
                ]);
                
                const codeReader = new ZXing.BrowserMultiFormatReader();
                  
                codeReader.listVideoInputDevices()
                .then((videoInputDevices) => {
                    const selectCamera = document.getElementById('selectCamera');
                  
                    const rearCameraDevices = videoInputDevices.filter((device) => 
                        device.label.toLowerCase().includes('back') || device.label.toLowerCase().includes('rear')
                    );
            
                    if (rearCameraDevices.length > 0) {
                        selectedDeviceId = rearCameraDevices[0].deviceId;
            
                        rearCameraDevices.forEach((device) => {
                            const sourceOption = document.createElement('option');
                            sourceOption.text = device.label;
                            sourceOption.value = device.deviceId;
                            selectCamera.appendChild(sourceOption);
                        });
                    
                        videoInputDevices.forEach((device) => {
                            if (!rearCameraDevices.some((rearDevice) => rearDevice.deviceId === device.deviceId)) {
                                const sourceOption = document.createElement('option');
                                sourceOption.text = device.label;
                                sourceOption.value = device.deviceId;
                                selectCamera.appendChild(sourceOption);
                            }
                        });
                    } else {
                        videoInputDevices.forEach((device) => {
                            const sourceOption = document.createElement('option');
                            sourceOption.text = device.label;
                            sourceOption.value = device.deviceId;
                            selectCamera.appendChild(sourceOption);
                        });
                        selectedDeviceId = videoInputDevices[0].deviceId;
                        loadCamera(selectedDeviceId);
                    }
                  
                    loadCamera(selectedDeviceId);
            
                    selectCamera.onchange = () => {
                        codeReader.reset();
                        selectedDeviceId = selectCamera.value;
                        loadCamera(selectedDeviceId);
                    };
                    
                    function loadCamera(selectedDeviceId) {
                        if (currentStream) {
                            currentStream.getTracks().forEach(track => track.stop());
                        }
                        
                        navigator.mediaDevices.getUserMedia({
                            video: {
                                deviceId: { exact: selectedDeviceId }
                            }
                        }).then(stream => {
                            currentStream = stream;
                            document.getElementById('video').srcObject = stream;
                            const track = stream.getVideoTracks()[0];
                            
                            track.applyConstraints({
                                advanced: [{ zoom: 2.5 }]
                            }).then(function () {
                                // console.log("Zoom diatur ke 2.5");
                            }).catch(function (err) {
                                // console.log("Zoom tidak didukung:", err)
                            });
                            
                            codeReader.decodeFromVideoDevice(selectedDeviceId, 'video', (result, err) => {
                                if (result && !scanningInProgress) {
                                    // console.log(result);
                                    scanningInProgress = true;
                                    playBeep();
                                    getIpAddress(function (address){
                                        var jenis = $('#jenis').text();
                                        $.ajax({
                                    		type 	: 'POST',
                                    		url		: "admin/data/absensipegawai?act=<?= my_crypt('convert', 'E') ?>",
                                    		data    : { lat: vLat, long: vLong, address: address, jenis: jenis, code : result.text },
                                    		success	: function (response) {
                                    		    document.location=response;
                                    		}
                                        })
                                    });
                                }
                                if (err && !(err instanceof ZXing.NotFoundException)) {
                                    console.error(err);
                                }
                            });
                        });
                    }  
                    
                    function playBeep() {
                        const audio = new Audio();
                        audio.src = '<?= $fileBeep ?>';
                        audio.play();
                    }
                })
                .catch((err) => {
                    console.log(err);
                });
            }