if Config.RegisterKeyMapping then
    RegisterKeyMapping('TogglePhone', Lang:t('info.openphone'), 'keyboard', Config.OpenKey)
else
    CreateThread(function()
        while true do
            if IsControlJustReleased(0, Config.OpenKeyNumber) then
                openPhone()
            end
            Wait(0)
        end
    end)
end
local isInFocus = false
local isBlocked = false
function sendNotification(text)
    TriggerEvent('QBCore:Notify', text) --You can edit this event to any Notification System you want
end
function blockPhone()
    if isBlocked then
        return true
    end
    return false --return true if you want to block that anyone can open the phone
    
end
function GiveCarKeys(plate, model)
    TriggerEvent("qb-vehiclekeys:client:AddKeys", plate)
end
CreateThread(function()
    while true do
        if getHandyActive() then
            if not getFlashLight() then
                DisableControlAction(0, 1, true)
                DisableControlAction(0, 2, true)
            end
            DisableControlAction(0, 304, true)
            DisableControlAction(0, 101, true)
            DisableControlAction(0, 74, true)
            DisableControlAction(0, 303, true)
            DisableControlAction(0, 311, true)
            DisableControlAction(0, 24, true)
            DisableControlAction(0, 25, true)
            DisableControlAction(0, 29, true)
            DisableControlAction(0, 322, true)
            DisableControlAction(0, 200, true)
            DisableControlAction(0, 202, true)
            DisableControlAction(0, 177, true)
            DisableControlAction(0, 37, true)
            DisableControlAction(0, 245, true)
            DisableControlAction(0, 263, true)
            DisableControlAction(0, 45, true)
            DisableControlAction(0, 80, true)
            DisableControlAction(0, 140, true)
            DisableControlAction(0, 0, true)
            DisableControlAction(0, 69, true)
            DisableControlAction(0, 70, true)
            DisableControlAction(0, 36, true)
            DisableControlAction(0, 326, true)
            DisableControlAction(0, 341, true)
            DisableControlAction(0, 343, true)
            DisableControlAction(0, 257, true)
            DisableControlAction(0, 22, true)
            DisableControlAction(0, 44, true)
            DisableControlAction(0, 288, true)
            DisableControlAction(0, 289, true)
            DisableControlAction(0, 170, true)
            DisableControlAction(0, 167, true)
            DisableControlAction(0, 26, true)
            DisableControlAction(0, 73, true)
            DisableControlAction(2, 199, true)
            DisableControlAction(0, 47, true)
            DisableControlAction(0, 264, true)
            DisableControlAction(0, 257, true)
            DisableControlAction(0, 140, true)
            DisableControlAction(0, 121, true)
            DisableControlAction(0, 114, true)
            DisableControlAction(0, 81, true)
            DisableControlAction(0, 82, true)
            DisableControlAction(0, 99, true)
            DisableControlAction(0, 330, true)
            DisableControlAction(0, 331, true)
            DisableControlAction(0, 100, true)
            DisableControlAction(0, 141, true)
            DisableControlAction(0, 142, true)
            DisableControlAction(0, 143, true)
            DisableControlAction(0, 106, true)
            DisableControlAction(0, 115, true)
            DisableControlAction(0, 91, true)
            DisableControlAction(0, 92, true)
            DisableControlAction(0, 245, true)
            DisableControlAction(0, 44, true)
            DisableControlAction(0, 157, true)
            DisableControlAction(0, 158, true)
            DisableControlAction(0, 160, true)
            DisableControlAction(0, 164, true)
            DisableControlAction(0, 165, true)
            DisableControlAction(0, 159, true)
            DisableControlAction(0, 161, true)
            DisableControlAction(0, 162, true)
            DisableControlAction(0, 163, true)
            DisableControlAction(0, 182, true)
        end
        Wait(0)
    end
end)
function checkPlayerDead()
    local PlayerData = QBCore.Functions.GetPlayerData()
    if Config.VisnAre then
        local dead = exports['visn_are']:GetHealthBuffer().unconscious
        return dead
    end
    if not PlayerData or not PlayerData.metadata then
        return false
    end
    
    return PlayerData.metadata['isdead']
end
function ShowHelpNotification(msg, thisFrame, beep, duration)
    AddTextEntry('HelpNotification', msg)
    if thisFrame then
        DisplayHelpTextThisFrame('HelpNotification', false)
    else
        if beep == nil then
            beep = true
        end
        BeginTextCommandDisplayHelp('HelpNotification')
        EndTextCommandDisplayHelp(0, false, beep, duration or -1)
    end
end
CreateThread(function()
    while true do
        Wait(500)
        if NetworkIsPlayerActive(PlayerId()) then
            TriggerServerEvent('roadphone:playerLoad', GetPlayerServerId(PlayerId()))
            break
        end
    end
end)
RegisterNetEvent('QBCore:Client:OnPlayerLoaded', function()
    CreateThread(function()
        if Config.RemoveFromRadioWhenDead then
            while true do
                Wait(2000)
                if checkPlayerDead() and isInRadio() then
                    TriggerEvent("roadphone:client:leaveradio")
                end
            end
        end
    end)
    
end)
RegisterNUICallback('inputfocus', function(data, cb) -- Do not change anything here!
    isInFocus = data.focus
    
    if isInFocus then
        SetNuiFocusKeepInput(false)
    else
        SetNuiFocusKeepInput(true)
    end
    cb('ok')
end)
function setRadioChannel(frequenz, playername)
    if Config.UseMumbleVoip then
        exports[Config.MumbleExport]:addPlayerToRadio(frequenz)
        exports[Config.MumbleExport]:SetMumbleProperty("radioEnabled", true)
    elseif Config.UseTokoVoip then
        local radiochannel = exports.tokovoip_script:getPlayerData(playername, "radio:channel")
        exports.tokovoip_script:removePlayerFromRadio(radiochannel)
        exports.tokovoip_script:setPlayerData(playername, "radio:channel", frequenz, true)
        exports.tokovoip_script:addPlayerToRadio(frequenz)
    elseif Config.UseSaltyChat then
        exports['saltychat']:SetRadioChannel(frequenz, true)
    elseif Config.UsePmaVoice then
        exports[Config.PMAVoiceExport]:addPlayerToRadio(frequenz)
        exports[Config.PMAVoiceExport]:setVoiceProperty('radioEnabled', true)
        exports[Config.PMAVoiceExport]:setVoiceProperty('micClicks', true)
    elseif Config.UseYacaVoice then
        exports['yaca-voice']:enableRadio(true)
        exports['yaca-voice']:changeRadioFrequency(frequenz)
    end
    TriggerEvent("roadphone:sendNotification", {
        apptitle = "APP_RADIO_NAME",
        title = Lang:t('info.radiojoined', { value = frequenz }),
        message = nil,
        img = "/public/img/Apps/radio.png"
    })
    setInRadio(true)
end
AddEventHandler("roadphone:client:call:eventnumber", function(number)
    if tostring(number) == "77777" then  --CHECK WHICH NUMBER IS CALLED
        
        --YOUR CODE
    end
end)
RegisterNUICallback('sendDispatch', function(data, cb)
    TriggerServerEvent("roadphone:sendDispatch", GetPlayerServerId(PlayerId()), data.text, data.job, nil, false, data.image)
    cb('ok')
end)
function clientSideInventoryValidation() -- DONT USE THIS FUNCTION IF YOU DONT KNOW WHAT YOU ARE DOING
    --YOUR CODE
    return 'PHONEITEM' --needs to return colored phone items name from config.lua = phone will open | false = phone will not open
    
end
function testMail()
    local data = {
        sender = 'RoadShop',
        subject = "RoadShop TEST",
        message = "Mails from scripts come back even better than before now even with Color support. 
 
 + Support for line breaks and button support ^^",
        button = {
            buttonEvent = "qb-drugs:client:setLocation",
            buttonData = "test",
            buttonname = "test"
          }
    }
    TriggerServerEvent("roadphone:receiveMail", data)
end
function playRoadSound(type)
    if type == 'message' then
                        
        PlaySound(-1, "Menu_Accept", "Phone_SoundSet_Default", 0, 0, 1)
        Wait(300)
        PlaySound(-1, "Menu_Accept", "Phone_SoundSet_Default", 0, 0, 1)
        Wait(300)
        PlaySound(-1, "Menu_Accept", "Phone_SoundSet_Default", 0, 0, 1)
    elseif type == 'dispatch' then
                
        PlaySound(-1, "Menu_Accept", "Phone_SoundSet_Default", 0, 0, 1)
        Wait(300)
        PlaySound(-1, "Menu_Accept", "Phone_SoundSet_Default", 0, 0, 1)
        Wait(300)
        PlaySound(-1, "Menu_Accept", "Phone_SoundSet_Default", 0, 0, 1)
    end
        
    
end
RegisterNUICallback('app_custom_event', function(data, cb)
    local app = data.app
    if app == "APPNAME" then
        --Your Code
        
    end
    cb('ok')
    
end)
exports('isBlocked', function()
    return blockPhone()
    
end)
exports('blockPhone', function()
    isBlocked = true
    return true
    
end)
exports('unblockPhone', function()
    isBlocked = false
    return false
    
end)
exports('inputFocus', function(boolean)
    isInFocus = boolean
    if isInFocus then
        SetNuiFocusKeepInput(false)
    else
        SetNuiFocusKeepInput(true)
    end
    
end)
function temperatureRanges(weatherType)
    local temperatureRanges = {
        ExtraSunny = {90, 110},
        Clear = {80, 95},
        Neutral = {80, 95},
        Smog = {90, 95},
        Foggy = {80, 90},
        Clouds = {80, 90},
        Overcast = {80, 80},
        Clearing = {75, 85},
        Raining = {75, 90},
        ThunderStorm = {75, 90},
        Blizzard = {-15, 10},
        Snowing = {0, 32},
        Snowlight = {0, 32},
        Christmas = {-5, 15},
        Halloween = {50, 80}
    }
    -- Fetch the range and get a random temperature within that range
    local minTemp, maxTemp = table.unpack(temperatureRanges[weatherType])
    local randomTemperature = getRandomInt(minTemp, maxTemp)
    -- Convert to Celsius if necessary
    if not Config.Fahrenheit then
        randomTemperature = (randomTemperature - 32) * 5 / 9
    end
    -- Format and return temperature with unit
    return string.format('%.0f°%s', randomTemperature, Config.Fahrenheit and 'F' or 'C')
end
CreateThread(function()
    while true do
        Wait(3000)
        TriggerEvent('roadphone:checkWeather')
        Wait(120000)
    end
end)