Configuration

This section includes all configurable files for the selected script. Most settings are configured automatically, but each config.lua file contains a header comment explaining the purpose and usage of every configuration type. Be sure to read the header of each file carefully to fully understand how to customize and adapt the system for QBCORE, ESX, or standalone environments, ensuring seamless integration with your server.


qs-gangs/shared/main.lua
--──────────────────────────────────────────────────────────────────────────────
--  Quasar Store · Configuration Guidelines
--──────────────────────────────────────────────────────────────────────────────
--  • [EDIT] Safe to change          • [INFO] Explanation/context
--  • [ADV]  Advanced users only     • [CORE] Do not modify
--  • [AUTO] Handled by the system
--  Always back up before editing. Wrong edits in [CORE]/[AUTO] may break the resource.
--──────────────────────────────────────────────────────────────────────────────

Config = Config or {}    -- [CORE] Main configuration table.
Locales = Locales or {}  -- [CORE] Language strings container.

--──────────────────────────────────────────────────────────────────────────────
-- Language                                                                    [EDIT]
-- [INFO] Choose your main language (files in locales/*). Add your own if missing.
-- [INFO] Available examples: ar,bg,ca,da,de,en,es,fa,fr,he,hi,it,jp,ko,pt,ru,tr,zh
--──────────────────────────────────────────────────────────────────────────────
Config.Language = 'en' -- [EDIT] 'en' or 'es' by default (you can create more)

--──────────────────────────────────────────────────────────────────────────────
-- Framework Detection                                                         [AUTO]
-- [INFO] Detects qb-core or es_extended. If renamed, set Config.Framework manually
--        after adapting client/custom/* and server/custom/*.
-- [ADV]  Do not edit if you are not sure what you’re doing.
--──────────────────────────────────────────────────────────────────────────────
local esxHas = GetResourceState('es_extended') == 'started' -- [CORE]
local qbHas  = GetResourceState('qb-core')     == 'started' -- [CORE]

Config.Framework = esxHas and 'esx' or qbHas and 'qb' or 'esx' -- [AUTO] You can force 'qb' or 'esx'

--──────────────────────────────────────────────────────────────────────────────
-- Integrations                                                                [EDIT]
-- [INFO] Set or auto-detect Inventory/Phone/Dispatch. If unsupported, set to 'none'
--        or add adapters in client/custom/* and server/custom/*.
-- Inventory options: 'qb-inventory','qs-inventory','ox_inventory','core_inventory'
-- Phone options:     'qb-phone','qs-smartphone','qs-smartphone-pro','none'
-- Dispatch options:  'qs-dispatch','qb-policejob','none'
--──────────────────────────────────────────────────────────────────────────────
local qsInvHas   = GetResourceState('qs-inventory')   == 'started' -- [CORE]
local qbInvHas   = GetResourceState('qb-inventory')   == 'started' -- [CORE]
local oxInvHas   = GetResourceState('ox_inventory')   == 'started' -- [CORE]
local coreInvHas = GetResourceState('core_inventory') == 'started' -- [CORE]

Config.Inventory = qsInvHas and 'qs-inventory'
                or qbInvHas and 'qb-inventory'
                or oxInvHas and 'ox_inventory'
                or coreInvHas and 'core_inventory'
                or 'none'                                           -- [AUTO]

Config.Dispatch = 'none'  -- [EDIT]
Config.Phone    = 'none'  -- [EDIT]

--──────────────────────────────────────────────────────────────────────────────
-- Notifications & Visuals                                                     [EDIT]
-- [INFO] Toggles for gang notices, zone alerts, body dragging and boss marker.
--──────────────────────────────────────────────────────────────────────────────
Config.GangNotifications   = true   -- [EDIT] Enable/disable gang notifications and warnings
Config.TeamLogNotification = false  -- [EDIT] Enable/disable login and logout notifications
Config.LosingZoneAlert     = true   -- [EDIT] Alert if your gang is losing an area
Config.DragDeadBody        = true   -- [EDIT] Allow dragging bodies in territories
Config.EnableDrawMarker    = false  -- [EDIT] Show a marker at boss location

--──────────────────────────────────────────────────────────────────────────────
-- Dealer Products                                                             [EDIT]
-- [INFO] Items sold by the Dealer. Visibility is gated by `minrep`.
-- [INFO] Players initially see only entries with minrep = 0.
--──────────────────────────────────────────────────────────────────────────────
Config.Products = {
    [1] = {
        name = 'weed_white-widow',
        price = 15,
        amount = 150,
        info = {},
        type = 'item',
        slot = 1,
        minrep = 0,
    },
    [2] = {
        name = 'weed_skunk',
        price = 15,
        amount = 150,
        info = {},
        type = 'item',
        slot = 2,
        minrep = 20,
    },
    [3] = {
        name = 'weed_purple-haze',
        price = 15,
        amount = 150,
        info = {},
        type = 'item',
        slot = 3,
        minrep = 40,
    },
    [4] = {
        name = 'weed_og-kush',
        price = 15,
        amount = 150,
        info = {},
        type = 'item',
        slot = 4,
        minrep = 60,
    },
    [5] = {
        name = 'weed_amnesia',
        price = 15,
        amount = 150,
        info = {},
        type = 'item',
        slot = 5,
        minrep = 80,
    },
    [6] = {
        name = 'weed_white-widow_seed',
        price = 15,
        amount = 150,
        info = {},
        type = 'item',
        slot = 6,
        minrep = 100,
    },
    [7] = {
        name = 'weed_skunk_seed',
        price = 15,
        amount = 150,
        info = {},
        type = 'item',
        slot = 7,
        minrep = 120,
    },
    [8] = {
        name = 'weed_purple-haze_seed',
        price = 15,
        amount = 150,
        info = {},
        type = 'item',
        slot = 8,
        minrep = 140,
    },
    [9] = {
        name = 'weed_og-kush_seed',
        price = 15,
        amount = 150,
        info = {},
        type = 'item',
        slot = 9,
        minrep = 160,
    },
    [10] = {
        name = 'weed_amnesia_seed',
        price = 15,
        amount = 150,
        info = {},
        type = 'item',
        slot = 10,
        minrep = 180,
    }
}

--──────────────────────────────────────────────────────────────────────────────
-- Territories                                                                 [EDIT]
-- [INFO] Conquerable zones; only one gang controls each territory.
--        When owned, your gang can sell to NPCs and access the area’s Dealer.
--        Enable your ZoneDebug to assist with `points` placement.
--──────────────────────────────────────────────────────────────────────────────
Config.Territories = {
    [1] = {
        area = { -- [EDIT] Visual rectangles on your map
            {
                coords = vec3(254.610992, -1972.153809, 21.562622),
                width = 170.0,
                height = 85.0,
                blipRotation = 6.0
            },
            {
                coords = vec3(177.441757, -2023.833008, 21.394165),
                width = 9.0,
                height = 20.0,
                blipRotation = 6.0
            },
            {
                coords = vec3(171.494507, -2028.382446, 17.838867),
                width = 5.0,
                height = 8.0,
                blipRotation = 6.0
            },
            {
                coords = vec3(188.004395, -2030.676880, 17.822021),
                width = 6.0,
                height = 6.0,
                blipRotation = 6.0
            },
        },
        points = { -- [EDIT] Zone corners (activate your Config.ZoneDebug to guide you)
            vec3(342.580231, -1937.947266, 17.8),
            vec3(317.063751, -1970.162598, 17.8),
            vec3(267.309906, -2029.015381, 17.8),
            vec3(242.320877, -2057.050537, 17.8),
            vec3(232.298904, -2059.727539, 17.8),
            vec3(215.749451, -2047.068115, 17.8),
            vec3(187.885712, -2035.265991, 17.8),
            vec3(169.147247, -2031.547241, 17.8),
            vec3(168.237366, -2020.114258, 17.8),
            vec3(173.090118, -2008.483521, 17.8),
            vec3(212.848358, -1960.470337, 17.8),
            vec3(274.852753, -1887.032959, 17.8),
            vec3(284.136261, -1885.199951, 17.8),
            vec3(340.298889, -1932.527466, 17.8),
        },
        minScore = 1800,     -- [EDIT] Seconds to take the zone (1800 = 30 minutes)
        winner   = 'neutral',-- [EDIT] Default owner. If you use occupants, set a gang here or keep 'neutral'
        occupants = {
            ['neutral'] = {
                label = 'Neutral',
                score = 60,
            },
        },
        dealers = { -- [EDIT] Dealer(s) available in the area
            ['zone-1'] = {
                name = 'Abel Pintos',
                coords = vector3(267.665955, -1979.446167, 21.461548),
                time = { -- [EDIT] Active hours (server time)
                    min = 01,
                    max = 12,
                },
                products = Config.Products
            }
        }
    },
    [2] = {
        area = { -- These are the visual squares on your map
            {
                coords = vec3(368.136261, -1837.411011, 28.403687),
                width = 122.0,
                height = 80.0,
                blipRotation = 6.0
            },
            {
                coords = vec3(400.931885, -1864.298950, 26.600708),
                width = 122.0,
                height = 5.5,
                blipRotation = 6.0
            },
            {
                coords = vec3(414.725281, -1855.582397, 27.308472),
                width = 91.0,
                height = 6.0,
                blipRotation = 6.0
            },
            {
                coords = vec3(433.516479, -1842.052734, 27.931885),
                width = 46.0,
                height = 6.5,
                blipRotation = 6.0
            },
            {
                coords = vec3(445.885712, -1833.850586, 27.898193),
                width = 18.0,
                height = 3.0,
                blipRotation = 6.0
            },
            {
                coords = vec3(414.224182, -1864.140625, 26.920898),
                width = 15.0,
                height = 4.0,
                blipRotation = 6.0
            },
            {
                coords = vec3(405.916473, -1873.226318, 26.314331),
                width = 10.0,
                height = 3.0,
                blipRotation = 6.0
            },
            {
                coords = vec3(380.492310, -1896.712036, 24.966309),
                width = 19.0,
                height = 4.0,
                blipRotation = 6.0
            },
        },
        points = { -- These are the corners of the zone, activate the Config.ZoneDebug to guide you!
            vec3(372.145050, -1913.446167, 24.7),
            vec3(365.221985, -1915.964844, 24.7),
            vec3(301.872528, -1863.520874, 24.7),
            vec3(301.147247, -1856.492310, 24.7),
            vec3(372.738464, -1771.134033, 24.7),
            vec3(383.393402, -1766.597778, 24.7),
            vec3(455.142853, -1825.951660, 24.7),
            vec3(455.643951, -1832.663696, 24.7),
        },
        minScore = 1800,    -- Timer for take zone 1800 = 30 minutes (in seconds)
        winner = 'neutral', -- if you use occupants, set gang here, if not use 'neutral'
        occupants = {
            ['neutral'] = {
                label = 'Neutral',
                score = 60,
            },
        },
        dealers = { -- This will be the dealer in the area
            ['zone-2'] = {
                name = 'Judy Alvarez',
                coords = vector3(406.892303, -1833.415405, 28.336304),
                time = { -- Hours in which the dealer is active
                    min = 01,
                    max = 12,
                },
                products = Config.Products
            }
        }
    },
    [3] = {
        area = { -- These are the visual squares on your map
            {
                coords = vec3(349.437378, -2047.806641, 21.815430),
                width = 125.0,
                height = 145.0,
                blipRotation = 16.0
            },
            {
                coords = vec3(298.074738, -2109.309814, 15.867432),
                width = 125.0,
                height = 15.0,
                blipRotation = 16.0
            },
            {
                coords = vec3(417.534058, -2089.898926, 20.332642),
                width = 35.0,
                height = 119.0,
                blipRotation = 16.0
            },
            {
                coords = vec3(366.712097, -2142.672607, 15.378784),
                width = 26.0,
                height = 28.0,
                blipRotation = 16.0
            },
            {
                coords = vec3(351.046143, -2153.749512, 13.643188),
                width = 14.0,
                height = 10.0,
                blipRotation = 16.0
            },
            {
                coords = vec3(383.657135, -2148.421875, 15.732666),
                width = 8.0,
                height = 15.0,
                blipRotation = 16.0
            },
            {
                coords = vec3(370.140656, -1964.360474, 24.157471),
                width = 48.0,
                height = 10.0,
                blipRotation = 16.0
            },
            {
                coords = vec3(397.239563, -1990.246094, 22.944336),
                width = 27.0,
                height = 6.0,
                blipRotation = 16.0
            },
            {
                coords = vec3(416.624176, -2008.391235, 22.455688),
                width = 27.0,
                height = 4.0,
                blipRotation = 16.0
            },
        },
        points = { -- These are the corners of the zone, activate the Config.ZoneDebug to guide you!
            vec3(349.529663, -1947.362671, 24.8),
            vec3(356.518677, -1945.621948, 24.8),
            vec3(371.815399, -1958.795654, 24.8),
            vec3(462.237366, -2054.307617, 24.8),
            vec3(463.305481, -2066.123047, 24.8),
            vec3(401.802185, -2136.923096, 24.8),
            vec3(387.929657, -2147.709961, 24.8),
            vec3(373.635162, -2153.327393, 24.8),
            vec3(355.213196, -2155.173584, 24.8),
            vec3(340.325287, -2151.797852, 24.8),
            vec3(326.492310, -2144.887939, 24.8),
            vec3(318.672546, -2138.887939, 24.8),
            vec3(249.745056, -2075.103271, 24.8),
            vec3(247.872528, -2070.421875, 24.8),
            vec3(250.259338, -2065.767090, 24.8),
        },
        minScore = 1800,    -- Timer for take zone 1800 = 30 minutes (in seconds)
        winner = 'neutral', -- if you use occupants, set gang here, if not use 'neutral'
        occupants = {
            ['neutral'] = {
                label = 'Neutral',
                score = 60,
            },
        },
        dealers = { -- This will be the dealer in the area
            ['zone-3'] = {
                name = 'Rowan Atkinson',
                coords = vector3(367.147247, -2000.360474, 24.241699),
                time = { -- Hours in which the dealer is active
                    min = 01,
                    max = 12,
                },
                products = Config.Products
            }
        }
    },
    [4] = {
        area = { -- These are the visual squares on your map
            {
                coords = vec3(835.134094, -2345.709961, 30.324585),
                width = 186.0,
                height = 127.0,
                blipRotation = 1.0
            },
        },
        points = { -- These are the corners of the zone, activate the Config.ZoneDebug to guide you!
            vec3(780.593384, -2440.997803, 20.0),
            vec3(770.663757, -2438.109863, 20.0),
            vec3(763.793396, -2430.712158, 20.0),
            vec3(762.039551, -2422.430664, 20.0),
            vec3(776.914307, -2244.936279, 20.0),
            vec3(780.065918, -2242.351562, 20.0),
            vec3(905.828552, -2253.006592, 20.0),
            vec3(910.945068, -2256.250488, 20.0),
            vec3(906.619812, -2305.344971, 20.0),
            vec3(907.701111, -2307.204346, 20.0),
            vec3(894.461548, -2445.797852, 20.0),
            vec3(888.342834, -2451.494385, 20.0),
            vec3(883.846130, -2452.101074, 20.0),
        },
        minScore = 1800,    -- Timer for take zone 1800 = 30 minutes (in seconds)
        winner = 'neutral', -- if you use occupants, set gang here, if not use 'neutral'
        occupants = {
            ['neutral'] = {
                label = 'Neutral',
                score = 60,
            },
        },
        dealers = { -- This will be the dealer in the area
            ['zone-4'] = {
                name = 'Nicolás del Caño',
                coords = vector3(813.230774, -2398.575928, 23.786865),
                time = { -- Hours in which the dealer is active
                    min = 01,
                    max = 12,
                },
                products = Config.Products
            }
        }
    },
    [5] = {
        area = { -- These are the visual squares on your map
            {
                coords = vec3(854.123108, -2157.573730, 42.001465),
                width = 147.0,
                height = 127.0,
                blipRotation = 1.0
            },
        },
        points = { -- These are the corners of the zone, activate the Config.ZoneDebug to guide you!
            vec3(919.978027, -2091.692383, 25.5),
            vec3(922.839539, -2093.301025, 25.5),
            vec3(923.353821, -2095.951660, 25.5),
            vec3(911.419800, -2237.657227, 25.5),
            vec3(909.204407, -2241.388916, 25.5),
            vec3(905.287903, -2242.417480, 25.5),
            vec3(784.588989, -2231.564941, 25.5),
            vec3(780.263733, -2230.417480, 25.5),
            vec3(778.918701, -2228.083496, 25.5),
            vec3(791.934082, -2084.373535, 25.5),
            vec3(793.107666, -2080.496582, 25.5),
            vec3(796.048340, -2079.969238, 25.5),
        },
        minScore = 1800,    -- Timer for take zone 1800 = 30 minutes (in seconds)
        winner = 'neutral', -- if you use occupants, set gang here, if not use 'neutral'
        occupants = {
            ['neutral'] = {
                label = 'Neutral',
                score = 60,
            },
        },
        dealers = { -- This will be the dealer in the area
            ['zone-5'] = {
                name = 'Ragnar Lodbrok',
                coords = vector3(853.160461, -2207.459229, 30.661499),
                time = { -- Hours in which the dealer is active
                    min = 01,
                    max = 12,
                },
                products = Config.Products
            }
        }
    },
    [6] = {
        area = { -- These are the visual squares on your map
            {
                coords = vec3(982.720886, -2270.835205, 34.722290),
                width = 360.0,
                height = 114.0,
                blipRotation = 1.0
            },
        },
        points = { -- These are the corners of the zone, activate the Config.ZoneDebug to guide you!
            vec3(935.947266, -2095.912109, 27.5),
            vec3(937.701111, -2093.762695, 27.5),
            vec3(985.569214, -2094.975830, 27.5),
            vec3(1025.327515, -2092.417480, 27.5),
            vec3(1041.692261, -2093.789062, 27.5),
            vec3(1051.793457, -2100.606689, 27.5),
            vec3(1057.582397, -2113.503174, 27.5),
            vec3(1026.197754, -2454.896729, 27.5),
            vec3(1022.109863, -2464.166992, 27.5),
            vec3(906.712097, -2454.685791, 27.5),
            vec3(904.219788, -2451.837402, 27.5),
            vec3(908.782410, -2409.837402, 27.5),
        },
        minScore = 1800,    -- Timer for take zone 1800 = 30 minutes (in seconds)
        winner = 'neutral', -- if you use occupants, set gang here, if not use 'neutral'
        occupants = {
            ['neutral'] = {
                label = 'Neutral',
                score = 60,
            },
        },
        dealers = { -- This will be the dealer in the area
            ['zone-6'] = {
                name = 'Britney Spears',
                coords = vector3(975.520874, -2357.907715, 31.807373),
                time = { -- Hours in which the dealer is active
                    min = 01,
                    max = 12,
                },
                products = Config.Products
            }
        }
    },
    [7] = {
        area = { -- These are the visual squares on your map
            {
                coords = vec3(-1150.285767, -1493.512085, 4.426392),
                width = 140.0,
                height = 145.0,
                blipRotation = 5.0
            },
        },
        points = { -- These are the corners of the zone, activate the Config.ZoneDebug to guide you!
            vec3(-1135.846191, -1404.197754, 4.8),
            vec3(-1132.509888, -1405.582397, 4.8),
            vec3(-1119.547241, -1430.492310, 4.8),
            vec3(-1105.635132, -1451.960449, 4.8),
            vec3(-1093.279175, -1468.021973, 4.8),
            vec3(-1061.815430, -1513.041748, 4.8),
            vec3(-1061.920898, -1520.795654, 4.8),
            vec3(-1172.268188, -1597.134033, 3.8),
            vec3(-1197.151611, -1563.151611, 3.8),
            vec3(-1246.193359, -1494.949463, 3.8),
            vec3(-1245.468140, -1474.074707, 3.8),
        },
        minScore = 1800,    -- Timer for take zone 1800 = 30 minutes (in seconds)
        winner = 'neutral', -- if you use occupants, set gang here, if not use 'neutral'
        occupants = {
            ['neutral'] = {
                label = 'Neutral',
                score = 60,
            },
        },
        dealers = { -- This will be the dealer in the area
            ['zone-7'] = {
                name = 'Leonardo DiCaprio',
                coords = vector3(-1155.850586, -1543.002197, 4.443237),
                time = { -- Hours in which the dealer is active
                    min = 01,
                    max = 12,
                },
                products = Config.Products
            }
        }
    },
    [8] = {
        area = { -- These are the visual squares on your map
            {
                coords = vec3(-1096.325317, -1629.599976, 5.808105),
                width = 65.0,
                height = 120.0,
                blipRotation = 5.0
            },
        },
        points = { -- These are the corners of the zone, activate the Config.ZoneDebug to guide you!
            vec3(-1166.202148, -1605.731812, 3.8),
            vec3(-1110.461548, -1567.068115, 3.8),
            vec3(-1102.747192, -1567.542847, 3.8),
            vec3(-1048.523071, -1640.004395, 3.8),
            vec3(-1038.382446, -1650.989014, 3.8),
            vec3(-1038.052734, -1657.833008, 3.8),
            vec3(-1080.329712, -1700.188965, 3.8),
            vec3(-1094.953857, -1709.129639, 3.8),
        },
        minScore = 1800,    -- Timer for take zone 1800 = 30 minutes (in seconds)
        winner = 'neutral', -- if you use occupants, set gang here, if not use 'neutral'
        occupants = {
            ['neutral'] = {
                label = 'Neutral',
                score = 60,
            },
        },
        dealers = { -- This will be the dealer in the area
            ['zone-8'] = {
                name = 'Lloyd Christmas',
                coords = vector3(-1120.391235, -1624.865967, 4.392700),
                time = { -- Hours in which the dealer is active
                    min = 01,
                    max = 12,
                },
                products = Config.Products
            }
        }
    },
    [9] = {
        area = { -- These are the visual squares on your map
            {
                coords = vec3(-1055.446167, -1566.487915, 4.679077),
                width = 55.0,
                height = 65.0,
                blipRotation = 5.0
            },
            {
                coords = vec3(-1037.789062, -1614.237305, 12.649048),
                width = 25.0,
                height = 35.0,
                blipRotation = 5.0
            },
            {
                coords = vec3(-1021.516479, -1597.476929, 5.201416),
                width = 22.0,
                height = 25.0,
                blipRotation = 5.0
            },
            {
                coords = vec3(-1026.804443, -1632.698853, 4.611694),
                width = 20.0,
                height = 10.0,
                blipRotation = 5.0
            },
            {
                coords = vec3(-1017.389038, -1614.461548, 4.982422),
                width = 8.0,
                height = 8.0,
                blipRotation = 5.0
            },
        },
        points = { -- These are the corners of the zone, activate the Config.ZoneDebug to guide you!
            vec3(-1025.327515, -1638.501099, 3.8),
            vec3(-1032.342896, -1640.980225, 3.8),
            vec3(-1037.815430, -1637.525269, 3.8),
            vec3(-1059.098877, -1611.942871, 3.8),
            vec3(-1093.648315, -1563.349487, 3.8),
            vec3(-1093.635132, -1556.650513, 3.8),
            vec3(-1090.615356, -1552.892334, 3.8),
            vec3(-1058.400024, -1531.028564, 3.8),
            vec3(-1053.797852, -1529.419800, 3.8),
            vec3(-1048.720825, -1532.136230, 3.8),
            vec3(-1019.498901, -1573.621948, 3.8),
            vec3(-1012.074707, -1593.309937, 3.8),
            vec3(-1012.971436, -1614.857178, 3.8),
            vec3(-1017.085693, -1627.041748, 3.8),
        },
        minScore = 1800,    -- Timer for take zone 1800 = 30 minutes (in seconds)
        winner = 'neutral', -- if you use occupants, set gang here, if not use 'neutral'
        occupants = {
            ['neutral'] = {
                label = 'Neutral',
                score = 60,
            },
        },
        dealers = { -- This will be the dealer in the area
            ['zone-9'] = {
                name = 'Ace Ventura',
                coords = vector3(-1072.298950, -1565.815430, 4.359009),
                time = { -- Hours in which the dealer is active
                    min = 01,
                    max = 12,
                },
                products = Config.Products
            }
        }
    },
    [10] = {
        area = { -- These are the visual squares on your map
            {
                coords = vec3(-1260.949463, -756.342834, 24.494507),
                width = 200.0,
                height = 220.0,
                blipRotation = 5.0
            },
            {
                coords = vec3(-1173.309937, -690.725281, 44.798584),
                width = 20.0,
                height = 220.0,
                blipRotation = 5.0
            },
            {
                coords = vec3(-1398.804443, -756.962646, 22.674683),
                width = 25.0,
                height = 58.0,
                blipRotation = 5.0
            },
            {
                coords = vec3(-1370.030762, -790.114258, 19.321655),
                width = 17.0,
                height = 30.0,
                blipRotation = 5.0
            },
            {
                coords = vec3(-1353.705444, -806.268127, 19.153076),
                width = 10.0,
                height = 20.0,
                blipRotation = 5.0
            },
            {
                coords = vec3(-1121.709839, -738.751648, 20.130371),
                width = 7.0,
                height = 83.0,
                blipRotation = 5.0
            },
        },
        points = { -- These are the corners of the zone, activate the Config.ZoneDebug to guide you!
            vec3(-1273.041748, -897.389038, 21.5),
            vec3(-1280.663696, -894.448364, 21.5),
            vec3(-1285.437378, -883.859314, 21.5),
            vec3(-1315.068115, -844.101074, 21.5),
            vec3(-1334.347290, -823.621948, 21.5),
            vec3(-1410.435181, -759.982422, 21.5),
            vec3(-1416.909912, -749.459351, 21.5),
            vec3(-1414.536255, -738.263733, 21.5),
            vec3(-1374.263672, -706.879089, 21.5),
            vec3(-1329.692261, -676.799988, 21.5),
            vec3(-1262.887939, -626.861511, 21.5),
            vec3(-1234.800049, -606.949463, 21.5),
            vec3(-1230.356079, -607.397827, 21.5),
            vec3(-1193.432983, -649.859314, 21.5),
            vec3(-1177.173584, -670.615356, 21.5),
            vec3(-1103.709839, -754.984619, 21.5),
            vec3(-1103.116455, -763.753845, 21.5),
            vec3(-1117.582397, -776.993408, 21.5),
            vec3(-1120.945068, -783.191223, 21.5),
            vec3(-1141.753784, -801.402222, 21.5),
            vec3(-1176.632935, -830.189026, 21.5),
            vec3(-1218.936279, -860.967041, 21.5),
        },
        minScore = 1800,    -- Timer for take zone 1800 = 30 minutes (in seconds)
        winner = 'neutral', -- if you use occupants, set gang here, if not use 'neutral'
        occupants = {
            ['neutral'] = {
                label = 'Neutral',
                score = 60,
            },
        },
        dealers = { -- This will be the dealer in the area
            ['zone-10'] = {
                name = 'Oliver Tree',
                coords = vector3(-1267.833008, -811.938477, 17.097412),
                time = { -- Hours in which the dealer is active
                    min = 01,
                    max = 12,
                },
                products = Config.Products
            }
        }
    },
}

--──────────────────────────────────────────────────────────────────────────────
-- Gang Locations                                                              [EDIT]
-- [INFO] Interactable points used by gangs (stash, boss menu, garage).
-- [INFO] You can translate prompts (`help`) or change the triggered events.
--──────────────────────────────────────────────────────────────────────────────
Config.Locations = {
    ['stash'] = {
        ['help'] = '[E] Open stash',
        ['event'] = 'gangs:openStash'
    },
    ['boss'] = {
        ['help'] = '[E] Open boss menu',
        ['event'] = 'gangs:requestOpenBoss'
    },
    ['vehicles'] = {
        ['help'] = '[E] Open garage',
        ['event'] = 'gangs:vehiclesMenu'
    },
}

--──────────────────────────────────────────────────────────────────────────────
-- Grades & Labels                                                             [ADV]
-- [INFO] Rank map and display labels. Do not remove the `none` rank.
-- [INFO] Changing numeric values may break permission checks.
--──────────────────────────────────────────────────────────────────────────────
Config.Grades = {
    ['none'] = 0,
    ['soldier'] = 1,
    ['underboss'] = 2,
    ['boss'] = 3,
}

Config.LabelGrades = {
    ['none'] = 'None',
    ['soldier'] = 'Soldier',
    ['underboss'] = 'Under Boss',
    ['boss'] = 'Boss',
}

Config.allowedGrades = {
    'boss',
    -- [EDIT] Add more grades with stock permits if needed
}

--──────────────────────────────────────────────────────────────────────────────
-- Gangs Setup                                                                 [EDIT]
-- [INFO] Define gangs, their colors, locations, map blips, and available vehicles.
-- [INFO] Do not remove the `none` gang; it’s used to clear a player’s rank
--        via `/setgang id none none`.
--──────────────────────────────────────────────────────────────────────────────
Config.Gangs = {
    ['none'] = {}, -- [CORE] Ignore this gang, used when player has no gang

    ['neutral'] = {
        ['territoryColor'] = 55, -- [INFO] Default blip color for unconquered territories
    },

    ['ballas'] = {                    -- [EDIT] Gang id
        ['label'] = 'Ballas',         -- [EDIT] Display name
        ['color'] = { 151, 8, 120 },  -- [EDIT] RGB color for UI
        ['territoryColor'] = 27,      -- [EDIT] Map blip color (https://docs.fivem.net/docs/game-references/blips/)
        ['locations'] = {
            {
                ['boss'] = vector3(114.329674, -1961.116455, 21.326782),
                ['stash'] = vector3(102.936264, -1959.771484, 20.821289),
                ['vehicles'] = vector3(116.927475, -1949.235107, 20.720093),
                ['heading'] = 56.692913
            }
        },
        ['blips'] = {
            [1] = { name = 'Ballas Zone', sprite = 84, color = 27, size = 0.6, coords = vec3(108.131866, -1941.085693, 20.787598) }
        },
        ['vehicles'] = {
            { ['model'] = 'avarus',     ['label'] = 'Avarus',    ['icon'] = 'fas fa-motorcycle' },
            { ['model'] = 'buccaneer2', ['label'] = 'Buccaneer', ['icon'] = 'fas fa-car-alt' }
        }
    },

    ['families'] = {
        ['label'] = 'The Families',
        ['color'] = { 19, 138, 19 },
        ['territoryColor'] = 2,
        ['locations'] = {
            {
                ['stash'] = vector3(530.070312, -1821.586792, 28.487915),
                ['boss'] = vector3(524.439575, -1822.246094, 28.487915),
                ['vehicles'] = vector3(524.373657, -1833.098877, 28.100342),
                ['heading'] = 133.228333
            }
        },
        ['blips'] = {
            [1] = { name = 'The Families Zone', sprite = 84, color = 2, size = 0.6, coords = vec3(529.859375, -1801.265869, 28.521606) }
        },
        ['vehicles'] = {
            { ['model'] = 'daemon2',   ['label'] = 'Daemon',   ['icon'] = 'fas fa-motorcycle' },
            { ['model'] = 'coquette3', ['label'] = 'Coquette', ['icon'] = 'fas fa-car-alt' },
        }
    },

    ['aztecas'] = {
        ['label'] = 'Varrios Los Aztecas',
        ['color'] = { 31, 71, 202 },
        ['territoryColor'] = 3,
        ['locations'] = {
            {
                ['stash'] = vector3(295.806580, -1750.259277, 29.128174),
                ['boss'] = vector3(310.879120, -1750.312134, 29.616821),
                ['vehicles'] = vector3(312.909882, -1737.349487, 29.498901),
                ['heading'] = 232.440948
            }
        },
        ['blips'] = {
            [1] = { name = 'Varrios Los Aztecas', sprite = 3, color = 1, size = 0.6, coords = vec3(-2633.558, 1306.246, 145.3014) }
        },
        ['vehicles'] = {
            { ['model'] = 'innovation', ['label'] = 'Innovation', ['icon'] = 'fas fa-motorcycle' },
            { ['model'] = 'hermes',     ['label'] = 'Hermes',     ['icon'] = 'fas fa-car-alt' },
            { ['model'] = 'stalion',    ['label'] = 'Stalion',    ['icon'] = 'fas fa-car-alt' }
        }
    },

    ['vagos'] = {
        ['label'] = 'Los Santos Vagos',
        ['color'] = { 235, 178, 23 },
        ['territoryColor'] = 28,
        ['locations'] = {
            {
                ['stash'] = vector3(-75.599998, -1423.397827, 29.566284),
                ['boss'] = vector3(-128.953842, -1416.013184, 31.285034),
                ['vehicles'] = vector3(-104.505493, -1410.883545, 29.684204),
                ['heading'] = 184.251968
            }
        },
        ['blips'] = {
            [1] = { name = 'Los Santos Vagos', sprite = 84, color = 28, size = 0.6, coords = vec3(-88.615387, -1420.285767, 29.482056) }
        },
        ['vehicles'] = {
            { ['model'] = 'lectro',    ['label'] = 'Lectro',   ['icon'] = 'fas fa-motorcycle' },
            { ['model'] = 'wolfsbane', ['label'] = 'Wolfbane', ['icon'] = 'fas fa-motorcycle' },
            { ['model'] = 'yosemite',  ['label'] = 'Yosemite', ['icon'] = 'fas fa-car-alt' }

        }
    }
}

--──────────────────────────────────────────────────────────────────────────────
-- Dealer Settings                                                             [EDIT]
-- [INFO] Configure dealer list, police presence requirements, and risk chances.
-- [INFO] Current values are battle-tested defaults; adjust with care and test.
--──────────────────────────────────────────────────────────────────────────────
Config.Dealers = {}                 -- [AUTO] Populated below from Config.Territories dealers (do not edit)

Config.RequiredCops     = 1         -- [EDIT] Minimum online police needed to sell drugs
Config.PoliceCallChance = 15        -- [EDIT] % chance an NPC calls police during a sale

Config.PoliceJob = {                -- [EDIT] Jobs considered police
    ['police'] = true,
    --['sheriff'] = true,
}

Config.SuccessChance = 50           -- [EDIT] % chance of a successful sale
Config.ScamChance    = 25           -- [EDIT] % chance NPC scams the player
Config.RobberyChance = 15           -- [EDIT] % chance NPC attempts robbery

--──────────────────────────────────────────────────────────────────────────────
-- Drug Price Ranges                                                           [EDIT]
-- [INFO] Min/Max payout per item. Actual payout may vary with other modifiers.
--──────────────────────────────────────────────────────────────────────────────
Config.DrugsPrice = {
    ['weed_white-widow'] = { min = 15, max = 24 },
    ['weed_og-kush']     = { min = 15, max = 28 },
    ['weed_skunk']       = { min = 15, max = 31 },
    ['weed_amnesia']     = { min = 18, max = 34 },
    ['weed_purple-haze'] = { min = 18, max = 37 },
    ['weed_ak47']        = { min = 18, max = 40 },
    ['crack_baggy']      = { min = 18, max = 34 },
    ['cokebaggy']        = { min = 18, max = 37 },
    ['meth']             = { min = 18, max = 40 },
}

--──────────────────────────────────────────────────────────────────────────────
-- Delivery Settings                                                            [EDIT]
-- [INFO] Tuning for delivery missions: payouts, reputation gain/loss, and fees.
--──────────────────────────────────────────────────────────────────────────────
Config.UseMarkedBills        = false -- [EDIT] Use qb-core marked bills (QB only)
Config.DeliveryRepGain       = 1     -- [EDIT] Rep gained for a successful delivery
Config.DeliveryRepLoss       = 1     -- [EDIT] Rep lost for late delivery
Config.PoliceDeliveryModifier= 0     -- [EDIT] Multiplies value per # of police (e.g., 2 = x2). 0 to disable
Config.WrongAmountFee        = 2     -- [EDIT] Divide payout by this when amount is wrong
Config.OverdueDeliveryFee    = 4     -- [EDIT] Divide payout by this when delivery is late

Config.DeliveryItems = {            -- [EDIT] Items that can be requested for delivery
    [1] = { ['item'] = 'weed_white-widow', ['minrep'] = 0, ['payout'] = 1000 },
    [2] = { ['item'] = 'weed_skunk',       ['minrep'] = 0, ['payout'] = 1000 },
}

Config.DeliveryLocations = {        -- [EDIT] Possible drop-off locations
    [1] = { ['label'] = 'Stripclub',      ['coords'] = vector3(106.24,  -1280.32, 29.24) },
    [2] = { ['label'] = 'Vinewood Video', ['coords'] = vector3(223.98,   121.53, 102.76) },
    [3] = { ['label'] = 'Taxi',           ['coords'] = vector3(882.67,  -160.26,  77.11) },
    [4] = { ['label'] = 'Resort',         ['coords'] = vector3(-1245.63, 376.21,  75.34) },
    [5] = { ['label'] = 'Bahama Mamas',   ['coords'] = vector3(-1383.1,  -639.99, 28.67) },
}

--──────────────────────────────────────────────────────────────────────────────
-- Dealer Autoload from Territories                                            [AUTO]
-- [INFO] Scans Config.Territories.*.dealers and injects them into Config.Dealers.
-- [INFO] Do not edit this block unless you know what you’re doing.
--──────────────────────────────────────────────────────────────────────────────
for k, v in pairs(Config.Territories) do
    if v.dealers then
        for k2, v2 in pairs(v.dealers) do
            v2.territory = k
            Config.Dealers[v2.name] = v2
        end
    end
end

--──────────────────────────────────────────────────────────────────────────────
-- Debug                                                                       [EDIT]
-- [INFO] Enable verbose logs and zone drawing for development/troubleshooting.
--──────────────────────────────────────────────────────────────────────────────
Config.Debug     = false
Config.ZoneDebug = false
qs-gangmenu/config/config.lua
--──────────────────────────────────────────────────────────────────────────────
--  Quasar Store · Configuration Guidelines
--──────────────────────────────────────────────────────────────────────────────
--  This configuration file defines all adjustable parameters for the script.
--  Comments are standardized to indicate safety of edits:
--    [EDIT] Safe to change     [INFO] Explanation/context
--    [ADV]  Advanced users     [CORE] Do not modify
--    [AUTO] Handled by system
--  Always back up before editing. Incorrect changes in [CORE]/[AUTO] may break the resource.
--──────────────────────────────────────────────────────────────────────────────

Config  = Config  or {} -- [CORE] Main configuration table.
Locales = Locales or {} -- [CORE] Language strings container.

--──────────────────────────────────────────────────────────────────────────────
-- Language                                                                    [EDIT]
-- [INFO] Pick your main language. Files live in locales/* — add your own if missing.
-- [INFO] Examples available by default: ar,bg,ca,da,de,en,es,fa,fr,he,hi,it,jp,ko,pt,ru,tr,zh
--──────────────────────────────────────────────────────────────────────────────
Config.Language = 'en' -- [EDIT] 'en' or 'es' by default (you can create more).

--──────────────────────────────────────────────────────────────────────────────
-- Framework Detection                                                         [AUTO]
-- [INFO] Auto-detects your framework by checking running resources.
-- [ADV]  You can force it to 'qb' or 'esx' manually if needed.
--──────────────────────────────────────────────────────────────────────────────
local esxHas = GetResourceState('es_extended') == 'started' -- [CORE]
local qbHas  = GetResourceState('qb-core')     == 'started' -- [CORE]
Config.Framework = esxHas and 'esx' or qbHas and 'qb' or 'esx' -- [AUTO] You can change to 'qb' or 'esx'.

--──────────────────────────────────────────────────────────────────────────────
-- Inventory Detection                                                         [AUTO]
-- [INFO] Detects popular inventory resources to enable per-house stash features.
-- [ADV]  Not on the list? Implement an adapter in client/custom/inventory/*.lua.
--──────────────────────────────────────────────────────────────────────────────
local qsInvHas   = GetResourceState('qs-inventory')   == 'started' -- [CORE]
local qbInvHas   = GetResourceState('qb-inventory')   == 'started' -- [CORE]
local oxInvHas   = GetResourceState('ox_inventory')   == 'started' -- [CORE]
local coreInvHas = GetResourceState('core_inventory') == 'started' -- [CORE]

Config.Inventory =                   -- [AUTO]
    qsInvHas   and 'qs-inventory' or
    qbInvHas   and 'qb-inventory' or
    oxInvHas   and 'ox_inventory' or
    coreInvHas and 'core_inventory' or
    'none'

--──────────────────────────────────────────────────────────────────────────────
-- General Settings                                                            [EDIT]
-- [INFO] UI keybinds and basic timers.
--──────────────────────────────────────────────────────────────────────────────
Config.OpenMenu = 'K'                 -- [EDIT] Key to open the main menu.
Config.RemoveHandcuffTimer = 300000   -- [EDIT] Milliseconds before auto-uncuff (300000 = 5 minutes).

--──────────────────────────────────────────────────────────────────────────────
-- Gang Menu Configuration                                                     [EDIT]
-- [INFO] Fully customizable action menu. Add/remove/edit entries as needed.
-- [INFO] Each entry supports: name,label,action,triggerType,submenu,grade.
-- [INFO] triggerType: 'client' or 'server'. Use submenu = { ... } for nested items.
--──────────────────────────────────────────────────────────────────────────────
---@type table<string, {
---  name: string, label: string, action: string|false, triggerType: 'client'|'server'|false,
---  submenu: false|table<string, any>, grade: string[]
---}>
Config.Menu = {
    ['steal'] = {
        name = 'steal',
        label = 'Steal',
        action = 'event:client:search',
        triggerType = 'client',
        submenu = false,
        grade = { 'soldier', 'underboss', 'boss' }
    },

    ['escort'] = {
        name = 'escort',
        label = 'Escort',
        action = 'event:client:dragPlayer',
        triggerType = 'client',
        submenu = false,
        grade = { 'soldier', 'underboss', 'boss' }
    },

    ['handcuff'] = {
        name = 'handcuff',
        label = 'Handcuff',
        action = 'event:client:handcuff',
        triggerType = 'client',
        submenu = false,
        grade = { 'soldier', 'underboss', 'boss' }
    },

    ['vehicle'] = {
        name = 'vehicle',
        label = 'Vehicle Options',
        action = false,            -- [INFO] Parent item only; executes no action.
        triggerType = false,       -- [INFO] N/A for parent entries.
        grade = { 'soldier', 'underboss', 'boss' },
        submenu = {
            ['putvehicle'] = {
                name = 'putvehicle',
                label = 'Put in vehicle',
                action = 'event:client:putvehicle',
                triggerType = 'client',
                submenu = false,
                grade = { 'soldier', 'underboss', 'boss' }
            },
            ['getvehicle'] = {
                name = 'getvehicle',
                label = 'Get out vehicle',
                action = 'event:client:getvehicle',
                triggerType = 'client',
                submenu = false,
                grade = { 'soldier', 'underboss', 'boss' }
            },
        },
    },

    ['cornersell'] = {
        name = 'selldrugs',
        label = 'Sell drugs',
        action = 'gangs:client:cornerselling',
        triggerType = 'client',
        submenu = false,
        grade = { 'soldier', 'underboss', 'boss' }
    },

    -- [EDIT] You can add more actions here.
}