> For the complete documentation index, see [llms.txt](https://savana.gitbook.io/savanascripts/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://savana.gitbook.io/savanascripts/scripts/radar-system/editable-files.md).

# Editable Files

{% hint style="info" %} <mark style="color:$info;">The core logic files are encrypted via Cfx.re Escrow, but all configuration and language files remain fully accessible and editable. You retain full control over the script’s behavior, visual settings, and translations without any restrictions.</mark>

<mark style="color:blue;">(Source package users are not affected by this)</mark>
{% endhint %}

{% tabs %}
{% tab title="shared/bridge.lua" %}

```lua
Bridge = {
    name = 'standalone',
    core = nil,
}

CreateThread(function()
    if GetResourceState('qbx_core') == 'started' then
        Bridge.name = 'qbx'
    elseif GetResourceState('qb-core') == 'started' then
        Bridge.name = 'qb'
        Bridge.core = exports['qb-core']:GetCoreObject()
    elseif GetResourceState('es_extended') == 'started' then
        Bridge.name = 'esx'
        Bridge.core = exports['es_extended']:getSharedObject()
    end
end)

local function hasOxLib()
    return GetResourceState('ox_lib') == 'started'
end


if IsDuplicityVersion() then
else
    function Bridge:GetJob()
        if self.name == 'qbx' then
            local data = exports.qbx_core:GetPlayerData()
            return data and data.job and data.job.name or nil,
                   data and data.job and (data.job.onduty ~= false) or false
        elseif self.name == 'qb' and self.core then
            local data = self.core.Functions.GetPlayerData()
            return data and data.job and data.job.name or nil,
                   data and data.job and (data.job.onduty ~= false) or false
        elseif self.name == 'esx' and self.core then
            local data = self.core.GetPlayerData()
            return data and data.job and data.job.name or nil, true
        end
        return nil, false
    end

    function Bridge:HasPermission()
        local job, onDuty = self:GetJob()
        if not job then return false end
        if not Config.AllowedJobs[job] then return false end
        if not onDuty then return false end
        return true
    end

    function Bridge:Notify(msg, kind)
        kind = kind or 'inform'
        if hasOxLib() then
            exports.ox_lib:notify({ description = msg, type = kind == 'inform' and 'info' or kind })
            return
        end
        if self.name == 'qbx' then
            exports.qbx_core:Notify(msg, kind)
        elseif self.name == 'qb' and self.core then
            self.core.Functions.Notify(msg, kind)
        elseif self.name == 'esx' and self.core then
            self.core.ShowNotification(msg)
        else
            BeginTextCommandThefeedPost('STRING')
            AddTextComponentSubstringPlayerName(msg)
            EndTextCommandThefeedPostTicker(false, true)
        end
    end

end

if IsDuplicityVersion() then

    function Bridge:GetJob(src)
        if self.name == 'qbx' then
            local player = exports.qbx_core:GetPlayer(src)
            if not player then return nil, false end
            return player.PlayerData.job.name, player.PlayerData.job.onduty ~= false
        elseif self.name == 'qb' and self.core then
            local player = self.core.Functions.GetPlayer(src)
            if not player then return nil, false end
            return player.PlayerData.job.name, player.PlayerData.job.onduty ~= false
        elseif self.name == 'esx' and self.core then
            local player = self.core.GetPlayerFromId(src)
            if not player then return nil, false end
            return player.job and player.job.name or nil, true
        end
        return nil, false
    end

    function Bridge:HasPermission(src)
        local job, onDuty = self:GetJob(src)
        if not job then return false end
        if not Config.AllowedJobs[job] then return false end
        if not onDuty then return false end
        return true
    end

    function Bridge:Notify(src, msg, kind)
        kind = kind or 'inform'
        if hasOxLib() then
            TriggerClientEvent('ox_lib:notify', src, { description = msg, type = kind == 'inform' and 'info' or kind })
            return
        end
        if self.name == 'qbx' then
            exports.qbx_core:Notify(src, msg, kind)
        elseif self.name == 'qb' and self.core then
            TriggerClientEvent('QBCore:Notify', src, msg, kind)
        elseif self.name == 'esx' and self.core then
            TriggerClientEvent('esx:showNotification', src, msg)
        else
            TriggerClientEvent('chat:addMessage', src, { args = { '[Radar]', msg } })
        end
    end

end

```

{% endtab %}
{% endtabs %}


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://savana.gitbook.io/savanascripts/scripts/radar-system/editable-files.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
