QB / ESX

Agency-Phone

Modern multi-framework phone for FiveM with auto-detection for QBCore and ESX. Full app suite including Dialer with pma-voice calls, Buzz SMS messaging, Snap in-game camera, Pulse social feed, Postbox mail, Wallet with AgencyPay checkout, Gallery, Contacts, and Settings. Supports programmable notifications with accept/deny buttons and integrated payment flows.

v26.4Paid5 Pages
Agency-Phone

01 Configuration

Complete config.lua for Agency-Phone. All options documented via inline comments.

Download config.lua
--[[
    Agency Phone - Configuration
    (c) Agency Scripts

    Framework Options:
    - 'auto'          : Automatically detect QBCore or ESX (default)
    - 'qb'            : Force QBCore
    - 'esx'           : Force ESX
    - 'oxide-banking' : Alias for QBCore + Oxide banking mode

    Banking Options:
    - 'framework'     : Use native framework money handling (default)
    - 'oxide-banking' : Use Oxide Banking integration mode (QBCore only)
]]

AgencyConfig = {}

-------------------------------------------------------------------------------
-- FRAMEWORK
-------------------------------------------------------------------------------
AgencyConfig.Framework = 'auto'

-------------------------------------------------------------------------------
-- BANKING
-------------------------------------------------------------------------------
AgencyConfig.Banking = 'framework' -- 'framework' | 'oxide-banking'
AgencyConfig.InvoiceProvider = 'auto' -- 'auto' | 'okokBilling' | 'builtin'

-------------------------------------------------------------------------------
-- GENERAL
-------------------------------------------------------------------------------
AgencyConfig.PhoneItem = 'phone'          -- Item name that the player needs in inventory
AgencyConfig.OpenKey = 'F1'                -- Keybind to open phone (FiveM key name, e.g. 'UP', 'M', 'F1')
AgencyConfig.AgencyAIKey = 'P'            -- Keybind to open AgencyAI directly (e.g. 'P', 'F2', etc.)
AgencyConfig.EnableAgencyAI = true         -- Set to false to completely disable AgencyAI (removes app and keybind)
AgencyConfig.EnableAIPickupApp = true      -- Driverless pickup app toggle (true = app enabled by default)
AgencyConfig.EnableAIPickupViaAgencyAI = true -- AgencyAI pickup intent toggle (independent from app availability)
AgencyConfig.EnableMoneyGames = true       -- Toggle paid gambling-style apps (Dice, Coin Flip, Lucky Slots, Roulette)
AgencyConfig.UseAgencyHUD = true           -- Enable Agency-HUD integration hooks (events/state sync)
AgencyConfig.SyncAgencyHUD = true          -- Sync phone open/close state to Agency-HUD (events + statebag + exports)
AgencyConfig.PerformanceModeDefault = false -- Performance mode default (true/false)
AgencyConfig.AnswerKey = 'Y'
AgencyConfig.DeclineKey = 'J'
AgencyConfig.AllowMovement = true
AgencyConfig.DefaultLanguage = 'en'       -- Default language: 'en', 'de', 'fr', 'es', 'tr', 'pl'
AgencyConfig.DataStorageMode = 'phone'    -- 'phone' = scoped by phone number, 'person' = scoped by identifier
AgencyConfig.AutoApplySqlSchema = true    -- Auto-create the SQL schema from agency-phone.sql on resource start

-------------------------------------------------------------------------------
-- MDT SYSTEM
-------------------------------------------------------------------------------
AgencyConfig.EnableMDT = true             -- Set to false to disable the entire MDT system for Police/EMS

-------------------------------------------------------------------------------
-- CRYPTO MARKET SETTINGS
-------------------------------------------------------------------------------
-- Configure cryptocurrency markets (prices update dynamically in-game)
-- basePrice: Starting price in dollars
-- volatility: Price fluctuation rate (0.05 = 5% change per update)
-- realCrypto: Real-world cryptocurrency this is based on (for display)
AgencyConfig.CryptoMarkets = {
    {
        id = 'digicoin',
        name = 'DigiCoin',
        symbol = 'DGC',
        icon = '₿',
        color = '#f7931a',
        basePrice = 45000,
        volatility = 0.05,
        realCrypto = 'Bitcoin'
    },
    {
        id = 'etherchain',
        name = 'EtherChain',
        symbol = 'ETC',
        icon = '⟠',
        color = '#627eea',
        basePrice = 2800,
        volatility = 0.08,
        realCrypto = 'Ethereum'
    },
    {
        id = 'litemark',
        name = 'LiteMark',
        symbol = 'LTM',
        icon = 'Ł',
        color = '#345d9d',
        basePrice = 150,
        volatility = 0.12,
        realCrypto = 'Litecoin'
    },
    {
        id = 'ripplenet',
        name = 'RippleNet',
        symbol = 'RPN',
        icon = '✕',
        color = '#00aae4',
        basePrice = 0.85,
        volatility = 0.15,
        realCrypto = 'XRP'
    },
    {
        id = 'cardania',
        name = 'Cardania',
        symbol = 'CDA',
        icon = '₳',
        color = '#0033ad',
        basePrice = 1.25,
        volatility = 0.13,
        realCrypto = 'Cardano'
    }
}

-- Crypto update interval (milliseconds) - how often prices update
AgencyConfig.CryptoUpdateInterval = 10000  -- 10 seconds (also used for stocks)

-- Default buy/sell amount per transaction
AgencyConfig.CryptoTradeAmount = 0.1

-------------------------------------------------------------------------------
-- AGENCY AI SUPER MODE
-- Enable enhanced AI responses by connecting to a real AI API.
-- Supported providers: 'openrouter', 'grok' (alias: 'qrok')
-- Users activate Super Mode inside the AgencyAI app via the ⚡ button.
-- If no key is set, AgencyAI uses built-in offline responses.
-------------------------------------------------------------------------------
AgencyConfig.AIProvider = 'openrouter'   -- 'openrouter' | 'grok' | 'qrok'
AgencyConfig.AIFallbackProvider = 'grok' -- Optional fallback provider when primary key is missing

-- OpenRouter (recommended for free models)
AgencyConfig.AIOpenRouterKey = '' -- https://openrouter.ai/keys
AgencyConfig.AIOpenRouterModel = 'mistralai/mistral-small-3.2-24b-instruct:free'

-- Grok / xAI
AgencyConfig.AIGrokKey = '' -- https://console.x.ai/
AgencyConfig.AIGrokModel = 'grok-3-mini-beta'

-- Legacy key (still supported as fallback for compatibility)
AgencyConfig.AIApiKey = ''

-- Rate Limiting: max tokens a single player can use per day.
-- Set to 0 for UNLIMITED usage (no daily cap).
-- Example: 10000 = roughly 30-50 AI messages per day per player.
AgencyConfig.AIMaxTokensPerDay     = 0      -- 0 = unlimited
AgencyConfig.AIMaxTokensPerMessage = 300    -- max tokens per single AI response

-------------------------------------------------------------------------------
-- YOUTUBE / MEDIA API
-- Required for VidFlow (Video) and Music apps
-- Create your API key at: https://console.cloud.google.com
-- 1. Create a project → Enable "YouTube Data API v3"
-- 2. Create an API key under Credentials
-- 3. Paste the key below
-------------------------------------------------------------------------------
AgencyConfig.YouTubeAPIKey = 'AIzaSyDwO9WalMS0I7-_SQCCTOVobY3UZrc4igQ'
AgencyConfig.VidFlowDefaultChannelUrl = 'https://www.youtube.com/@tdyskyyt' -- Default VidFlow homepage channel
AgencyConfig.MusicSyncRadius = 30.0  -- Radius (meters) for nearby players to hear music
AgencyConfig.MusicMaxVolume = 0.5    -- Max volume for synced music (0.0-1.0)

-------------------------------------------------------------------------------
-- CALL SETTINGS
-------------------------------------------------------------------------------
AgencyConfig.CallTimeout = 30
AgencyConfig.CallRingInterval = 4000
AgencyConfig.CallMaxRings = 10

-------------------------------------------------------------------------------
-- VOICE SYSTEM
-- Controls which voice resource is used for phone call audio.
-- 'auto'         = Automatically detect running voice resource (recommended)
-- 'pma-voice'    = Force pma-voice
-- 'saltychat'    = Force SaltyChat
-- 'mumble-voip'  = Force mumble-voip (FiveM built-in Mumble wrapper)
-- 'tokovoip'     = Force TokoVOIP
-------------------------------------------------------------------------------
AgencyConfig.VoiceSystem = 'auto'

-------------------------------------------------------------------------------
-- REAL-TIME STREAMING / VIDEO CALLS
-- Cloudflare TURN is the default transport for Pictogram live streams and
-- FaceZoom video sessions.
--
-- The API token is used server-side to generate short-lived TURN credentials.
-- Do not expose the token to the browser or to public client-side scripts.
-- Sign up here: https://dash.cloudflare.com/sign-up/realtime/turn
-- Create your TURN app / token here after signup:
-- https://dash.cloudflare.com/?to=/:account/realtime/turn
-- You need the TURN Token ID and the API Token from the Cloudflare dashboard.
-------------------------------------------------------------------------------
AgencyConfig.StreamTransport = 'cloudflare-turn' -- 'cloudflare-turn'
AgencyConfig.CloudflareTurnEnabled = true
AgencyConfig.CloudflareTurnName = 'tight-hall-3dd2'
AgencyConfig.CloudflareTurnTokenId = '041fc2144ccdfc91dd636591da737c03'
AgencyConfig.CloudflareTurnApiToken = '3c1b82b7b89941057619efa6f51bc0fcffbf36b2efe4c04f667952111046efcf'
AgencyConfig.CloudflareTurnApiUrl = 'https://rtc.live.cloudflare.com/v1/turn/keys/%s/credentials/generate-ice-servers'
AgencyConfig.CloudflareTurnCredentialTTL = 43200 -- Seconds

-------------------------------------------------------------------------------
-- NOTIFICATION
-------------------------------------------------------------------------------
AgencyConfig.NotifyDuration = 5000

-- Use Agency-Notify as the default notification system
-- Free download: https://agency-script.tebex.io/package/6937769
AgencyConfig.UseAgencyNotify = true

-------------------------------------------------------------------------------
-- AGENCY REPORTS (Report App)
-- Integrates Agency Reports providers to let players submit reports from the phone
-- Free download: https://agency-script.tebex.io/package/6959744
-------------------------------------------------------------------------------
AgencyConfig.UseAgencyReports = true
AgencyConfig.AgencyReportsProvider = 'v2' -- 'v2' | 'v2_ad_free' | 'legacy' | 'auto'
AgencyConfig.AgencyReportsCommand = 'areport'

-- Opens the external Agency-LifeInvaderV2 UI instead of the internal phone app.
AgencyConfig.EnableLifeInvaderV2Integration = false

-- Fast navigation categories used inside the Maps app.
-- Each entry can point to one or more GTA blip sprites and is used to find the nearest matching destination.
AgencyConfig.MapFastNavEntries = {
    { id = 'gas',      labelKey = 'maps_gas_station',    icon = 'fa-gas-pump',             color = '#0a84ff', sprites = { 361 } },
    { id = 'market',   labelKey = 'maps_market',         icon = 'fa-basket-shopping',      color = '#ff9500', sprites = { 52, 77, 102 } },
    { id = 'atm',      labelKey = 'maps_atm',            icon = 'fa-credit-card',          color = '#30d158', sprites = { 277 } },
    { id = 'clothing', labelKey = 'maps_clothing_store', icon = 'fa-shirt',                color = '#bf5af2', sprites = { 73 } },
    { id = 'tattoo',   labelKey = 'maps_tattoo_parlor',  icon = 'fa-wand-magic-sparkles',  color = '#ff9f0a', sprites = { 75 } },
    { id = 'barber',   labelKey = 'maps_barber',         icon = 'fa-scissors',             color = '#5e72eb', sprites = { 71 } },
    { id = 'bar',      labelKey = 'maps_bar',            icon = 'fa-martini-glass-citrus', color = '#ff7a00', sprites = { 93 } },
}

-------------------------------------------------------------------------------
-- SECURITY (Face Unlock / Lock Screen)
-------------------------------------------------------------------------------
AgencyConfig.FaceIdDefault = false        -- Default Face Unlock state for new players
AgencyConfig.FaceIdAnimDuration = 2600    -- Face Unlock animation duration (ms)
AgencyConfig.LockScreenEnabled = true     -- Allow lock screen feature

-------------------------------------------------------------------------------
-- DIALER (Phone / Calls)
-------------------------------------------------------------------------------
AgencyConfig.EnableDeathEmergency = true      -- Auto-show emergency overlay when player dies
AgencyConfig.DialerEmergencyNumber = '911'   -- Emergency number
AgencyConfig.DialerTestNumber = '511'        -- Always-answered local test line for call checks (set empty string to disable)
AgencyConfig.DialerShowRecents = true         -- Show recent calls tab
AgencyConfig.DialerMaxRecents = 20            -- Max recent calls to display

-------------------------------------------------------------------------------
-- DISPATCH SYSTEM (MDT Integration)
-- Controls how emergency calls/SMS are routed to police/EMS.
-- 'internal' = Use the phone's built-in dispatch system (default)
-- 'cd_dispatch' = cd_dispatch by Codesign
-- 'ps-dispatch' = ps-dispatch by Project Sloth
-- 'qs-dispatch' = qs-dispatch by Quasar
-- 'core_dispatch' = core_dispatch
-- 'custom' = Custom dispatch (fires event: agency-phone:dispatch:custom)
-------------------------------------------------------------------------------
AgencyConfig.DispatchSystem = 'internal'

-- Dispatch categories for internal system
AgencyConfig.DispatchCodes = {
    ['911']  = { type = 'emergency', priority = 'high',   label = 'Emergency Call',    departments = {'police', 'ems'} },
    ['110']  = { type = 'police',    priority = 'high',   label = 'Police Emergency',  departments = {'police'} },
    ['112']  = { type = 'ems',       priority = 'high',   label = 'Medical Emergency', departments = {'ems'} },
}

-- How long dispatches stay active (seconds, 0 = until manually cleared)
AgencyConfig.DispatchTimeout = 300

-- Store dispatch history in database (requires oxmysql)
AgencyConfig.DispatchSaveHistory = true

-------------------------------------------------------------------------------
-- BUZZ (Messages)
-------------------------------------------------------------------------------
AgencyConfig.BuzzMaxMessages = 50             -- Max messages per chat to load
AgencyConfig.BuzzAllowDelete = true           -- Allow deleting messages
AgencyConfig.BuzzShowTimestamps = true        -- Show timestamps on messages

-------------------------------------------------------------------------------
-- CONTACTS
-------------------------------------------------------------------------------
AgencyConfig.ContactsMaxCount = 100           -- Max contacts per player
AgencyConfig.ContactsAllowShare = true        -- Allow sharing contact info
AgencyConfig.ContactsDefaultSort = 'name'     -- Sort by: 'name' or 'recent'

-------------------------------------------------------------------------------
-- SNAP (Camera)
-------------------------------------------------------------------------------
-- Media storage provider used by the phone camera uploads.
-- Available values:
--   'fivemanage' = uploads to FiveManage (recommended)
--   'discord'    = uploads directly to a Discord webhook
--
-- Discord webhook attachments can expire, be deleted, or become unavailable over time.
-- That means older phone photos may disappear from gallery, posts, or stories later on.
-- For long-term media storage you should use FiveManage.
AgencyConfig.MediaStorageProvider = 'fivemanage'

-- FiveManage upload configuration.
-- Default upload endpoint: https://api.fivemanage.com/api/v3/file
-- The phone camera uploads the screenshot and stores the returned public URL in the database.
AgencyConfig.FiveManageApiUrl = 'https://api.fivemanage.com/api/v3/file'
AgencyConfig.FiveManageApiKey = 'u2WwwPyZUMnMVXrN0Xb0qK8IaWlM0lpi'

-- Discord webhook upload configuration.
-- Create a Discord webhook in your server:
--   1. Go to your Discord server → Channel Settings → Integrations → Webhooks
--   2. Click "New Webhook", name it (e.g. "Phone Screenshots"), choose a channel
--   3. Copy the Webhook URL and paste it below
-- The phone camera will POST screenshots as image attachments to this webhook when
-- AgencyConfig.MediaStorageProvider = 'discord'.
-- Leave empty ('') to disable Discord uploads.
-- Example: 'https://discord.com/api/webhooks/1234567890/abcdefg...'
AgencyConfig.ScreenshotWebhook = 'https://discord.com/api/webhooks/1472322564935127276/pUvnMVEyHATAUjHA-qPBJk5_3yDn-G2C5eJraufDAafYC4ka0UF_zazCKyv8o4UekMRz'
AgencyConfig.CameraMaxPhotos = 50             -- Max photos in gallery
AgencyConfig.CameraQuality = 0.85             -- Screenshot JPEG quality (0-1)

-------------------------------------------------------------------------------
-- CHIRPER (Social Feed)
-------------------------------------------------------------------------------
AgencyConfig.PulseLoadHours = 12
AgencyConfig.PulseMaxLength = 280           -- Max chirp message length
AgencyConfig.PulseAllowDelete = true        -- Allow deleting own chirps
AgencyConfig.PulseRefreshInterval = 30      -- Auto-refresh interval (seconds, 0=off)

-------------------------------------------------------------------------------
-- POSTBOX (Mail)
-------------------------------------------------------------------------------
AgencyConfig.PostboxLoadHours = 72
AgencyConfig.PostboxMaxMails = 50             -- Max mails to display
AgencyConfig.PostboxAllowDelete = true        -- Allow deleting mails
AgencyConfig.PostboxMaxAccounts = 5           -- Max mailbox accounts per player
AgencyConfig.PostboxDefaultDomain = 'agencyg.de' -- Default mailbox domain (players choose the local part themselves)

-------------------------------------------------------------------------------
-- WALLET (Bank)
-------------------------------------------------------------------------------
AgencyConfig.WalletMinTransfer = 1            -- Minimum transfer amount
AgencyConfig.WalletMaxTransfer = 1000000      -- Maximum transfer amount
AgencyConfig.WalletShowHistory = false        -- Show transaction history (future)
AgencyConfig.WalletCurrency = '$'             -- Currency symbol

-- Wallet fixed-term deposits (2-5% configurable rates)
AgencyConfig.WalletFixedTerms = {
    { id = 'fd_7',  label = '7 Days',  days = 7,  interest = 2.0 },
    { id = 'fd_14', label = '14 Days', days = 14, interest = 3.0 },
    { id = 'fd_30', label = '30 Days', days = 30, interest = 5.0 },
}

-------------------------------------------------------------------------------
-- AGENCY PAY TERMINALS
-- Configurable nearby payment terminals used by Agency Pay quick launch,
-- action button detection and Wallet checkout.
-- coords: x, y, z, w (w optional heading)
-- amount: charged via Wallet / bank
-- reward: optional test reward granted after a validated successful payment
-------------------------------------------------------------------------------
AgencyConfig.AgencyPayTerminals = {
    {
        id = 'agency_water_terminal_1',
        coords = { x = 27.5543, y = -1343.0767, z = 29.4970, w = 0.6853 },
        radius = 2.6,
        merchant = 'Agency Water Terminal',
        title = 'Agency Pay',
        subtitle = 'Tap to buy a bottle of water',
        label = 'Water Bottle',
        amount = 1.00,
        currency = '$',
        icon = 'fa-solid fa-bottle-water',
        accent = '#5ac8fa',
        manualConfirm = true,
        autoStart = false,
        showMarker = true,
        markerDistance = 18.0,
        textDistance = 6.0,
        markerType = 1,
        markerScale = 0.34,
        markerColor = { r = 90, g = 200, b = 250, a = 185 },
        markerBob = true,
        showBlip = false,
        metadata = {
            terminalId = 'agency_water_terminal_1',
            rewardLabel = 'Water',
        },
        reward = {
            item = 'water',
            amount = 1,
        },
        serverEvent = 'agency-phone:server:handleAgencyPayTerminalPurchase',
    },
}

-------------------------------------------------------------------------------
-- GALLERY (Photos)
-------------------------------------------------------------------------------
AgencyConfig.GalleryMaxPhotos = 50            -- Max photos per player
AgencyConfig.GalleryColumnsCount = 3          -- Grid columns (2, 3, or 4)

-------------------------------------------------------------------------------
-- AGENCY CLOUD
-------------------------------------------------------------------------------
AgencyConfig.AgencyCloud = {
    Enabled = true,
    GalleryAutoSyncDefault = false,
    Personal = {
        Label = 'Personal Cloud',
        BaseStorageMB = 200,
        BaseAssetLimit = 50,
        PurchaseStorageMB = 250,
        PurchaseAssetCount = 25,
        PurchasePrice = 5000,
        MaxStorageMB = 5000,
        MaxAssetLimit = 1000,
        GallerySavePrice = 150,
        DocumentSavePrice = 60,
        AllowGalleryAssets = true,
        AllowDocuments = true,
        StorageTiers = {
            { id = 'plus', label = 'Plus', storageMb = 250, assetCount = 25, price = 5000 },
            { id = 'pro', label = 'Pro', storageMb = 750, assetCount = 75, price = 12000 },
            { id = 'vault', label = 'Vault', storageMb = 1500, assetCount = 160, price = 22000 },
        },
    },
    Company = {
        Label = 'Company Cloud',
        BossOnly = true,
        BaseStorageMB = 1000,
        BaseAssetLimit = 150,
        PurchaseStorageMB = 1000,
        PurchaseAssetCount = 100,
        PurchasePrice = 25000,
        MaxStorageMB = 20000,
        MaxAssetLimit = 5000,
        GallerySavePrice = 350,
        DocumentSavePrice = 180,
        AllowGalleryAssets = true,
        AllowDocuments = true,
        StorageTiers = {
            { id = 'team', label = 'Team', storageMb = 1000, assetCount = 100, price = 25000 },
            { id = 'division', label = 'Division', storageMb = 2500, assetCount = 280, price = 52000 },
            { id = 'enterprise', label = 'Enterprise', storageMb = 5000, assetCount = 650, price = 95000 },
        },
    },
    DefaultGalleryStorageBytes = 2000000,
    DefaultDocumentStorageBytes = 102400,
}

-------------------------------------------------------------------------------
-- DARKNET MARKET
-- Items available on the darknet marketplace.
-- btcPrice: Price in BTC (DigiCoin equivalent)
-- item: Item name to give player (framework item)
-- amount: How many of the item to give
-- desc: Description shown in the app
-- pickupLocations: Random locations where the dead drop can spawn.
--   The server picks one at random and sets a GPS waypoint for the buyer.
--   Add/remove locations as needed for your server map.
-------------------------------------------------------------------------------
AgencyConfig.DarknetItems = {
    {
        id = 'lockpick',
        label = 'Advanced Lockpick',
        desc = 'Military-grade lockpick. Untraceable.',
        btcPrice = 0.002,
        item = 'advancedlockpick',
        amount = 1,
    },
    {
        id = 'vpn',
        label = 'Burner VPN',
        desc = 'Anonymous VPN tunnel. Single use.',
        btcPrice = 0.001,
        item = 'vpn',
        amount = 1,
    },
    {
        id = 'radio',
        label = 'Encrypted Radio',
        desc = 'Frequency-hopping encrypted radio device.',
        btcPrice = 0.003,
        item = 'radio',
        amount = 1,
    },
    {
        id = 'armor',
        label = 'Kevlar Vest',
        desc = 'Level III body armor. No serial numbers.',
        btcPrice = 0.005,
        item = 'armor',
        amount = 1,
    },
}

-- Pickup (dead drop) locations where purchased items can be collected.
-- The server randomly picks one of these for each purchase.
-- Players get a GPS waypoint and must go there to pick up the item from a dumpster/trash can.
AgencyConfig.DarknetPickupLocations = {
    { x = 126.42,   y = -1282.71, z = 29.27,  label = 'Strawberry Alley' },
    { x = -587.53,  y = -1064.37, z = 22.34,  label = 'La Mesa Backstreet' },
    { x = 373.24,   y = -826.52,  z = 29.30,  label = 'Mission Row Dumpster' },
    { x = -1205.42, y = -906.28,  z = 12.33,  label = 'Vespucci Canal' },
    { x = 1137.86,  y = -982.34,  z = 46.42,  label = 'Murrieta Heights' },
    { x = -46.83,   y = -1758.64, z = 29.42,  label = 'Davis Industrial' },
}

-------------------------------------------------------------------------------
-- GARAGE
-- GarageSystem: Which garage script to use for vehicle data.
-- 'auto'                = Auto-detect (tries okokGarage, cd_garage, md-garage, qb-garages, qbx_garages,
--                           jg-advancedgarages, qs-advancedgarages, renewed-garage, loaf_garage, then DB fallback)
-- 'md-garage'           = Force md-garage
-- 'okokGarage'          = Force okokGarage (also accepts okokgarage)
-- 'cd_garage'           = Force cd_garage
-- 'qb-garages'          = Force qb-garages
-- 'qbx_garages'         = Force qbx_garages
-- 'jg-advancedgarages'  = Force jg-advancedgarages
-- 'qs-advancedgarages'  = Force qs-advancedgarages / qs-garages
-- 'renewed-garage'      = Force Renewed-Garage
-- 'loaf_garage'         = Force loaf_garage
-------------------------------------------------------------------------------
AgencyConfig.GarageSystem = 'auto'            -- Garage script to use ('auto' or script name)
AgencyConfig.GarageSpawnCost = 200           -- Cost to spawn a vehicle ($)
AgencyConfig.GarageMaxSpawned = 3            -- Max vehicles out at once per player
AgencyConfig.GarageCooldown = 120            -- Cooldown in seconds between vehicle requests (0 = disabled)

-- Autonomous pickup ride settings (driverless visual taxi)
AgencyConfig.AIPickupVehicleModel = 'stretch' -- GTA limousine look
AgencyConfig.AIPickupVehicleOptions = {
    { model = 'stretch', label = 'Agency Limo' },
    { model = 'neon', label = 'AgencyAI E-Sport 4S' },
    { model = 'raiden', label = 'AgencyAI Executive EV' },
}
AgencyConfig.AIPickupCruiseSpeed = 22.0
AgencyConfig.AIPickupPickupSpeed = 34.0 -- Faster approach speed while coming to player
AgencyConfig.AIPickupArrivalRadius = 18.0
AgencyConfig.AIPickupDropoffRadius = 22.0
AgencyConfig.AIPickupBoardingRadius = 12.0 -- Radius to press E and enter rear seats
AgencyConfig.AIPickupUseInvisibleDriver = true
AgencyConfig.AIPickupIgnoreTrafficToPickup = true -- Ignore traffic rules while driving to pickup
AgencyConfig.AIPickupBaseFare = 500 -- Minimum order cost (charged on request)
AgencyConfig.AIPickupCostPerKm = 100 -- Live billing per started kilometer during trip

-------------------------------------------------------------------------------
-- eSIM CARRIER PLANS
-- Players must choose a carrier to download apps, make calls, and send messages.
-- Each carrier has different speeds (affects app downloads, browser loading, Buzz latency, mail sending, and social posting delays), call/message limits.
-- speed: 1-5 (1=slowest, 5=fastest) - used as the full simulated network profile for the phone, no antenna / zone system required
-- calls: 'unlimited' or number (max calls per restart)
-- messages: 'unlimited' or number (max messages per restart)
-- price: monthly cost deducted from bank (for RP display only)
-------------------------------------------------------------------------------
AgencyConfig.CarrierPlans = {
    {
        id       = 'fleeca_mobile',
        name     = 'Fleeca Mobile',
        icon     = 'fa-solid fa-signal',
        color    = '#34c759',
        speed    = 2,
        calls    = 50,
        messages = 100,
        price    = 30,
    },
    {
        id       = 'maze_telecom',
        name     = 'Maze Telecom',
        icon     = 'fa-solid fa-tower-cell',
        color    = '#007aff',
        speed    = 3,
        calls    = 'unlimited',
        messages = 200,
        price    = 50,
    },
    {
        id       = 'lifeinvader_net',
        name     = 'LifeInvader Net',
        icon     = 'fa-solid fa-wifi',
        color    = '#5856d6',
        speed    = 4,
        calls    = 'unlimited',
        messages = 'unlimited',
        price    = 80,
    },
    {
        id       = 'lossantos_5g',
        name     = 'LS 5G Ultra',
        icon     = 'fa-solid fa-bolt',
        color    = '#ff9500',
        speed    = 5,
        calls    = 'unlimited',
        messages = 'unlimited',
        price    = 120,
    },
}

-------------------------------------------------------------------------------
-- BROWSER APP
-- Default bookmarks shown on the browser start page.
-- The in-phone browser uses FiveM/NUI webviews. Some websites with Cloudflare,
-- strict anti-bot checks, X-Frame-Options or CSP frame restrictions may still fail
-- to load there even when Agency Phone is configured correctly. That limitation is
-- caused by the FiveM webview / remote website policy, not by Agency Phone itself.
-------------------------------------------------------------------------------
AgencyConfig.BrowserBookmarks = {
    { name = 'Agency', url = 'https://agencyg.de', icon = 'fa-solid fa-globe', color = '#007aff' },
    { name = 'Agency Docs', url = 'https://docs.agencyg.de', icon = 'fa-solid fa-book-open', color = '#34c759' },
}

-- Leave this empty to allow all websites by default.
-- Add hosts here only if you want to restrict the browser to a curated profile.
AgencyConfig.BrowserAllowedWebsites = {
}

-- Optional proxy template for websites that refuse direct in-app iframe loading.
-- This can help with websites that sit behind Cloudflare or other strict web
-- protection layers, but only if your proxy service rewrites and serves them in
-- a FiveM-compatible way.
-- Supported placeholders:
--   {url}  = URL-encoded target URL
--   {raw}  = raw target URL
--   {host} = URL-encoded target host
AgencyConfig.BrowserProxyTemplate = ''

-- Proxy mode:
-- 'hosts' = only hosts listed in BrowserProxyHosts use the proxy (default)
-- 'all'   = all browser websites use the proxy template
AgencyConfig.BrowserProxyMode = 'hosts'

-- Hosts that should load through BrowserProxyTemplate when BrowserProxyMode = 'hosts'.
AgencyConfig.BrowserProxyHosts = {
    -- 'docs.agencyg.de',
}

-------------------------------------------------------------------------------
-- DISCORD WEBHOOKS (Logging)
-------------------------------------------------------------------------------
-- Discord webhooks for logging phone activity to your Discord server.
-- Create a webhook for each log type you want to track:
--   Discord Server → Channel Settings → Integrations → Webhooks → New Webhook
-- Leave empty ('') to disable that specific log.
-- Each webhook will receive embedded messages with player info and action details.
AgencyConfig.Webhooks = {
    -- Phone activity logs
    Calls       = '',  -- Logs all phone calls (caller, receiver, duration)
    Messages    = '',  -- Logs sent messages (sender, receiver, content)
    Transfers   = '',  -- Logs bank transfers (sender, receiver, amount)
    Reports     = '',  -- Logs player reports (reporter, reason, details)

    -- Social activity logs
    Chirps      = '',  -- Logs Pulse posts (author, content)
    Mail        = '',  -- Logs sent mail (sender, receiver, subject)

    -- App activity logs
    AppInstalls = '',  -- Logs app installs/uninstalls (player, app name)
    Screenshots = '',  -- Logs camera screenshots (player, image URL) — uses ScreenshotWebhook above if this is empty
    Gambling    = '',  -- Logs game results (player, game, bet, win/loss, amount)

    -- Vehicle / Garage logs
    Garage      = '',  -- Logs vehicle spawns (player, model, plate, cost)

    -- Agency Drop logs
    AirDrop     = '',  -- Logs Agency Drop shares (sender, receiver, item/contact)
}

-------------------------------------------------------------------------------
-- AGENCY EATS (Delivery App)
-- Restaurant pickup locations for the delivery job.
-- Players must drive to these coords to pick up orders.
-------------------------------------------------------------------------------
AgencyConfig.EatsRestaurants = {
    { name = 'Burger Shot',    x = -1196.42, y = -891.35,  z = 14.0  },
    { name = "Cluckin' Bell",  x = -72.68,   y = 6253.11,  z = 31.09 },
    { name = 'Pizza This',     x = 540.66,   y = 101.25,   z = 96.44 },
    { name = 'Bean Machine',   x = -628.16,  y = 236.60,   z = 81.97 },
    { name = 'Up-n-Atom',      x = 89.95,    y = 289.42,   z = 110.21 },
    { name = 'Taco Bomb',      x = 12.04,    y = -1605.57, z = 29.37 },
}

-- Delivery pay: distance-based ($ per kilometer driven)
AgencyConfig.EatsPayPerKm = 20
-- Minimum / maximum delivery pay (caps)
AgencyConfig.EatsPayMin = 15
AgencyConfig.EatsPayMax = 200

-- Pickup radius: how close the player must be to mark order as picked up (meters)
AgencyConfig.EatsPickupRadius = 15.0

-------------------------------------------------------------------------------
-- JOB-SPECIFIC APPS
-- Configure which framework job names correspond to each job app.
-- Players with these jobs can see and download the respective apps.
-- Add or remove job names as needed for your server.
-------------------------------------------------------------------------------
AgencyConfig.JobApps = {
    police = {
        appId    = 'police_mdt',
        jobNames = {'police', 'pd', 'lspd', 'bcso', 'sheriff'},
    },
    ems = {
        appId    = 'ems_mdt',
        jobNames = {'ambulance', 'ems', 'doctor', 'medic', 'fire'},
    },
    mechanic = {
        appId    = 'mechanic_app',
        jobNames = {'mechanic', 'bennys', 'lscustoms', 'tuner'},
    },
}

-------------------------------------------------------------------------------
-- JOBS APP LISTINGS
-- Used by the "Jobs" app (employment).
-- You can fully edit/remove/add entries here.
-- Fields:
--  id, title, company, location, salary, type, description, color, x, y, phone
-------------------------------------------------------------------------------
AgencyConfig.EmploymentListings = {
    {
        id = 'ls-logistics',
        title = 'Delivery Driver',
        company = 'Los Santos Logistics',
        location = 'Mission Row, Los Santos',
        salary = '$3,200 / week',
        type = 'Full-Time',
        description = 'Deliver packages across the city with route bonuses and clean-driver rewards.',
        color = '#34c759',
        x = 121.4,
        y = -3031.9,
        phone = '310-555-0181',
    },
    {
        id = 'dockyard-security',
        title = 'Night Security',
        company = 'Port Security Group',
        location = 'Elysian Island',
        salary = '$2,850 / week',
        type = 'Shift',
        description = 'Patrol restricted zones, report incidents, and coordinate with dispatch.',
        color = '#5ac8fa',
        x = -225.1,
        y = -2684.3,
        phone = '310-555-0172',
    },
    {
        id = 'vinewood-cafe',
        title = 'Barista',
        company = 'Bean Machine',
        location = 'Vinewood',
        salary = '$2,100 / week',
        type = 'Part-Time',
        description = 'Prepare drinks, handle front desk orders, and keep service flowing during rush hours.',
        color = '#ff9f0a',
        x = -634.9,
        y = 236.1,
        phone = '310-555-0122',
    },
    {
        id = 'city-maintenance',
        title = 'Street Maintenance',
        company = 'City Works',
        location = 'La Mesa',
        salary = '$3,000 / week',
        type = 'Contract',
        description = 'Repair public infrastructure and assist with emergency city maintenance tasks.',
        color = '#af52de',
        x = 727.7,
        y = -1079.7,
        phone = '310-555-0196',
    },
}

-------------------------------------------------------------------------------
-- APP STORE
-------------------------------------------------------------------------------
AgencyConfig.AppStoreEnabled = true           -- Enable the app store
AgencyConfig.AppStorePersist = true           -- Persist installs in localStorage

-------------------------------------------------------------------------------
-- APPLICATIONS
--
-- installed : true = pre-installed on home screen, false = available in Store
-- enabled   : true = visible (either on home or in store), false = hidden
--
-- Users can add custom apps by creating files in the apps/ folder.
-- See apps/README.md for documentation.
-------------------------------------------------------------------------------
AgencyConfig.Apps = {
    -- ═══════════════════════════════════════════════════════════
    -- PRE-INSTALLED APPS (on home screen by default)
    -- ═══════════════════════════════════════════════════════════
    {
        id        = "dialer",
        label     = "Phone",
        icon      = "fa-solid fa-phone",
        color     = "#4cd964",
        colorDark = "#34c759",
        slot      = 1,
        installed = true,
        enabled   = true,
    },
    {
        id        = "buzz",
        label     = "Buzz",
        icon      = "fa-solid fa-comment",
        color     = "#34c759",
        colorDark = "#28a745",
        slot      = 2,
        installed = true,
        enabled   = true,
    },
    {
        id        = "contacts",
        label     = "Contacts",
        icon      = "fa-solid fa-user-group",
        color     = "#ff9500",
        colorDark = "#e08600",
        slot      = 3,
        installed = true,
        enabled   = true,
    },
    {
        id        = "snap",
        label     = "Camera",
        icon      = "fa-solid fa-camera",
        color     = "#8e8e93",
        colorDark = "#636366",
        slot      = 4,
        installed = true,
        enabled   = true,
    },
    {
        id        = "chirper",
        label     = "Pulse",
        icon      = "fa-solid fa-feather",
        color     = "#af52de",
        colorDark = "#9b30d1",
        slot      = 35,
        installed = false,
        enabled   = false,
    },
    {
        id        = "postbox",
        label     = "Mail",
        icon      = "fa-solid fa-envelope",
        color     = "#5ac8fa",
        colorDark = "#32ade6",
        slot      = 6,
        installed = true,
        enabled   = true,
    },
    {
        id        = "wallet",
        label     = "Wallet",
        icon      = "fa-solid fa-wallet",
        color     = "#007aff",
        colorDark = "#0056cc",
        slot      = 7,
        installed = true,
        enabled   = true,
    },
    {
        id        = "gallery",
        label     = "Photos",
        icon      = "fa-solid fa-images",
        color     = "#ff2d55",
        colorDark = "#d6204a",
        slot      = 8,
        installed = true,
        enabled   = true,
    },
    {
        id        = "report",
        label     = "Agency Reports",
        icon      = "fa-solid fa-flag",
        color     = "#ff3b30",
        colorDark = "#d63025",
        slot      = 9,
        installed = true,
        enabled   = true,
    },
    {
        id        = "settings",
        label     = "Settings",
        icon      = "fa-solid fa-gear",
        color     = "#8e8e93",
        colorDark = "#636366",
        slot      = 10,
        installed = true,
        enabled   = true,
    },
    {
        id        = "agencyai",
        label     = "AgencyAI",
        icon      = "fa-solid fa-wand-magic-sparkles",
        color     = "#af52de",
        colorDark = "#5856d6",
        slot      = 11,
        installed = true,
        enabled   = true,
    },
    {
        id        = "appstore",
        label     = "Store",
        icon      = "fa-solid fa-bag-shopping",
        color     = "#007aff",
        colorDark = "#0056cc",
        slot      = 12,
        installed = true,
        enabled   = true,
    },

    {
        id        = "agencycloud",
        label     = "AgencyCloud",
        icon      = "fa-solid fa-cloud",
        color     = "#4cc6ff",
        colorDark = "#0a84ff",
        category  = "productivity",
        slot      = 13,
        installed = true,
        enabled   = true,
        storeDesc = "Your personal and company cloud storage. Sync files, photos, and documents across all your Agency devices.",
        features  = {"Personal & company storage", "Cross-device sync", "Photo gallery backup", "Document management", "Storage tier upgrades"},
    },

    -- ═══════════════════════════════════════════════════════════
    -- STORE APPS (must be installed via the Store app first)
    -- ═══════════════════════════════════════════════════════════
    {
        id        = "calculator",
        label     = "Calculator",
        icon      = "fa-solid fa-calculator",
        color     = "#ff9500",
        colorDark = "#e08600",
        category  = "productivity",
        slot      = 13,
        installed = true,
        enabled   = true,
        storeDesc = "A powerful calculator app for quick calculations on the go.",
        features  = {"Basic arithmetic operations", "Percentage calculations", "AgencyOS26.4-style interface", "Instant results"},
    },
    {
        id        = "clock",
        label     = "Clock",
        icon      = "fa-solid fa-clock",
        color     = "#000000",
        colorDark = "#1c1c1e",
        category  = "productivity",
        slot      = 14,
        installed = true,
        enabled   = true,
        storeDesc = "Keep track of time with world clocks, alarms, stopwatch, and timers.",
        features  = {"World clock display", "Stopwatch with precision timing", "Multiple alarms", "Timer functionality"},
    },
    {
        id        = "notes",
        label     = "Notes",
        icon      = "fa-solid fa-note-sticky",
        color     = "#ffcc00",
        colorDark = "#e6b800",
        category  = "productivity",
        slot      = 15,
        installed = true,
        enabled   = true,
        storeDesc = "Jot down ideas, tasks, and reminders instantly.",
        features  = {"Quick note creation", "Persistent storage", "Easy organization", "Simple interface"},
    },
    {
        id        = "weather",
        label     = "Weather",
        icon      = "fa-solid fa-cloud-sun",
        color     = "#5ac8fa",
        colorDark = "#32ade6",
        category  = "productivity",
        slot      = 16,
        installed = true,
        enabled   = true,
        storeDesc = "Stay informed about current weather conditions in Los Santos.",
        features  = {"Real-time weather display", "Temperature info", "Current conditions", "Location-based data"},
    },
    {
        id        = "compass",
        label     = "Compass",
        icon      = "fa-solid fa-compass",
        color     = "#ff3b30",
        colorDark = "#d63025",
        category  = "navigation",
        slot      = 17,
        installed = false,
        enabled   = true,
        storeDesc = "Navigate the city with an accurate digital compass.",
        features  = {"Real-time heading direction", "Accurate navigation", "Always accessible", "Minimal interface"},
    },
    {
        id        = "radio",
        label     = "Radio",
        icon      = "fa-solid fa-radio",
        color     = "#ff6b6b",
        colorDark = "#d94848",
        category  = "utilities",
        slot      = 18,
        installed = false,
        enabled   = true,
        storeDesc = "Connect to various radio channels and communicate on the go.",
        features  = {"Multiple frequency channels", "Quick channel switching", "Clear audio", "Emergency frequencies"},
    },
    -- Flashlight removed: now available in Control Center (swipe down top-right)
    {
        id        = "speedometer",
        label     = "Speedo",
        icon      = "fa-solid fa-gauge-high",
        color     = "#ff2d55",
        colorDark = "#d6204a",
        category  = "navigation",
        slot      = 20,
        installed = false,
        enabled   = true,
        storeDesc = "Monitor your vehicle's speed with a digital speedometer.",
        features  = {"Real-time speed display", "Multiple unit options", "GPS speed tracking", "Always visible"},
    },
    {
        id        = "gps",
        label     = "Maps",
        icon      = "fa-solid fa-map-location-dot",
        color     = "#34c759",
        colorDark = "#28a745",
        category  = "navigation",
        slot      = 21,
        installed = false,
        enabled   = true,
        storeDesc = "Navigate Los Santos with GPS waypoints and route planning.",
        features  = {"Set custom waypoints", "Route guidance", "Real-time navigation", "Location sharing"},
    },
    {
        id        = "crypto",
        label     = "Crypto",
        icon      = "fa-brands fa-bitcoin",
        color     = "#f7931a",
        colorDark = "#d97c0e",
        slot      = 22,
        installed = false,
        enabled   = true,
        storeDesc = "Buy, sell, and track cryptocurrency markets in real-time.",
        features  = {"Live market prices", "Portfolio tracking", "Trading functionality", "Transaction history"},
    },
    {
        id        = "stocks",
        label     = "Stocks",
        icon      = "fa-solid fa-chart-line",
        color     = "#007aff",
        colorDark = "#0056cc",
        slot      = 33,
        installed = false,
        enabled   = true,
        storeDesc = "Trade stocks of Los Santos companies and build your portfolio.",
        features  = {"8 Los Santos companies", "Real-time price updates", "Buy/sell shares", "Portfolio tracking"},
        category  = "finance",
    },
    {
        id        = "dice",
        label     = "Dice Game",
        category  = "games",
        icon      = "fa-solid fa-dice",
        color     = "#ff2d55",
        colorDark = "#d6204a",
        slot      = 23,
        installed = false,
        enabled   = true,
        storeDesc = "Roll dice against other players. Classic gambling game.",
        features  = {"1v1 dice duels", "Customizable bet amounts", "Roll history", "Fair random rolls"},
    },
    {
        id        = "darkweb",
        label     = "Darknet",
        icon      = "fa-solid fa-skull-crossbones",
        color     = "#1c1c1e",
        colorDark = "#000000",
        category  = "darknet",
        slot      = 24,
        installed = false,
        enabled   = true,
        storeDesc = "Access the underground market. Anonymous and untraceable.",
        features  = {"Anonymous browsing", "Encrypted transactions", "Black market access", "High-risk items"},
    },
    {
        id        = "racing",
        label     = "Races",
        icon      = "fa-solid fa-flag-checkered",
        color     = "#ff9500",
        colorDark = "#e08600",
        category  = "services",
        slot      = 25,
        installed = false,
        enabled   = true,
        storeDesc = "Compete in street races and track your best times.",
        features  = {"Create custom races", "Join active races", "Leaderboards", "Race statistics"},
    },
    -- Music app moved to MEDIA APPS section below (YouTube API powered)
    {
        id        = "services",
        label     = "Services",
        icon      = "fa-solid fa-book-open",
        color     = "#ffd60a",
        colorDark = "#d4a800",
        category  = "utilities",
        slot      = 27,
        installed = false,
        enabled   = true,
        storeDesc = "Request taxis, mechanics, and various city services.",
        features  = {"Taxi services", "Mechanic calls", "Emergency services", "Quick booking"},
    },
    {
        id        = "aipickup",
        label     = "AutoRide",
        icon      = "fa-solid fa-car-side",
        color     = "#00c7be",
        colorDark = "#0a84ff",
        category  = "services",
        slot      = 26,
        installed = true,
        enabled   = true,
        storeDesc = "AgencyAI-powered limousine pickup and autonomous dropoff service.",
        features  = {"Driverless AgencyAI 4-seat limousine", "Pickup at your location", "Set waypoint before or during ride", "Autonomous routing to destination"},
    },
    {
        id        = "food",
        label     = "AgencyEats",
        icon      = "fa-solid fa-burger",
        color     = "#ff3b30",
        colorDark = "#d62020",
        category  = "services",
        slot      = 28,
        installed = false,
        enabled   = true,
        storeDesc = "Order food from local restaurants and get it delivered to your location.",
        features  = {"Browse menus", "Place orders", "Track delivery", "Restaurant ratings"},
    },
    {
        id        = "invoices",
        label     = "Invoices",
        category  = "finance",
        icon      = "fa-solid fa-file-invoice-dollar",
        color     = "#30d158",
        colorDark = "#28b54c",
        slot      = 29,
        installed = false,
        enabled   = true,
        storeDesc = "Manage and pay your invoices and outstanding bills.",
        features  = {"View pending bills", "Pay invoices", "Transaction history", "Payment reminders"},
    },
    {
        id        = "employment",
        label     = "Jobs",
        category  = "utilities",
        icon      = "fa-solid fa-briefcase",
        color     = "#007aff",
        colorDark = "#0056cc",
        slot      = 30,
        installed = false,
        enabled   = true,
        storeDesc = "Find employment opportunities and manage your career.",
        features  = {"Job listings", "Application tracking", "Career information", "Salary details"},
    },
    {
        id        = "garage",
        label     = "Garage",
        category  = "utilities",
        icon      = "fa-solid fa-warehouse",
        color     = "#5856d6",
        colorDark = "#4240b0",
        slot      = 32,
        installed = true,
        enabled   = true,
        storeDesc = "Access and manage your stored vehicles and garage.",
        features  = {"Vehicle storage", "Quick spawn", "Vehicle information", "Garage locations"},
    },
    {
        id        = "coinflip",
        label     = "Coin Flip",
        category  = "games",
        icon      = "fa-solid fa-coins",
        color     = "#ffcc00",
        colorDark = "#e6b800",
        slot      = 37,
        installed = false,
        enabled   = true,
        storeDesc = "Flip a coin and bet against other players. Heads or tails?",
        features  = {"Heads or tails betting", "Fair coin flip", "Bet against players", "Flip history"},
    },
    {
        id        = "slots",
        label     = "Lucky Slots",
        category  = "games",
        icon      = "fa-solid fa-clover",
        color     = "#34c759",
        colorDark = "#28a745",
        slot      = 38,
        installed = false,
        enabled   = true,
        storeDesc = "Try your luck at the slot machine. Match symbols to win big!",
        features  = {"Classic slot machine", "Multiple symbol combos", "Win multipliers", "Jackpot system"},
    },
    {
        id        = "roulette",
        label     = "Roulette",
        category  = "games",
        icon      = "fa-solid fa-circle-dot",
        color     = "#ff3b30",
        colorDark = "#d63025",
        slot      = 39,
        installed = false,
        enabled   = true,
        storeDesc = "Place your bets on the roulette wheel. Red, black, or green?",
        features  = {"Red/Black/Green bets", "Number betting", "Realistic wheel spin", "Payout system"},
    },

    {
        id        = "flappybird",
        label     = "Sky Hopper",
        icon      = "fa-solid fa-dove",
        color     = "#4cd964",
        colorDark = "#3bb54a",
        slot      = 40,
        installed = false,
        enabled   = true,
        category  = "games",
        storeDesc = "Tap to glide through the skyline, avoid the pipes and beat your best run.",
        features  = {"Classic gameplay", "High score tracking", "Smooth animations", "Addictive fun"},
    },
    {
        id        = "game2048",
        label     = "2048",
        icon      = "fa-solid fa-border-all",
        color     = "#f59563",
        colorDark = "#e07840",
        slot      = 41,
        installed = false,
        enabled   = true,
        category  = "games",
        storeDesc = "Slide numbered tiles to combine them and reach 2048!",
        features  = {"Number puzzle", "Swipe controls", "Score tracking", "Addictive gameplay"},
    },

    -- ═══════════════════════════════════════════════════════════
    -- MEDIA APPS (YouTube API powered)
    -- ═══════════════════════════════════════════════════════════
    {
        id        = "vidflow",
        label     = "VidFlow",
        icon      = "fa-solid fa-play",
        category  = "media",
        color     = "#ff2d55",
        colorDark = "#d6204a",
        slot      = 34,
        installed = false,
        enabled   = true,
        storeDesc = "Watch and discover videos from around the world.",
        features  = {"Search millions of videos", "In-app video player", "Trending content", "Share with friends"},
    },
    {
        id        = "music",
        label     = "Music",
        icon      = "fa-solid fa-music",
        color     = "#fc3c44",
        colorDark = "#d43039",
        category  = "media",
        slot      = 5,
        installed = true,
        enabled   = true,
        storeDesc = "Listen to music and share it with people nearby.",
        features  = {"Search songs", "Paste any media link", "Nearby players hear your music", "Favorites & queue"},
    },

    -- ═══════════════════════════════════════════════════════════
    -- JOB-SPECIFIC APPS (restricted by player job)
    -- ═══════════════════════════════════════════════════════════
    -- Police & EMS MDT are Agency-Pad exclusive

    {
        id           = "mechanic_app",
        label        = "Mechanic",
        icon         = "fa-solid fa-wrench",
        color        = "#ff9500",
        colorDark    = "#e08600",
        category     = "utilities",
        slot         = 52,
        installed    = false,
        enabled      = true,
        requiresJob  = true,
        storeDesc    = "Manage repair orders and customer requests. Accept jobs and track your workload.",
        features     = {"Incoming repair requests", "Job queue management", "Customer notifications", "Service history"},
    },

    -- ═══════════════════════════════════════════════════════════
    -- SOCIAL APPS (require login)
    -- ═══════════════════════════════════════════════════════════
    {
        id        = "pictogram",
        label     = "Pictogram",
        category  = "social",
        icon      = "fa-solid fa-camera-retro",
        color     = "#E1306C",
        colorDark = "#C13584",
        slot      = 42,
        installed = false,
        enabled   = true,
        requiresLogin = true,
        storeDesc = "Share photos and stories with your friends. The #1 photo sharing app.",
        features  = {"Photo sharing", "Stories & Reels", "Direct messages", "Follow friends"},
    },
    {
        id        = "bleeter",
        label     = "Bleeter",
        category  = "social",
        icon      = "fa-solid fa-hashtag",
        color     = "#1DA1F2",
        colorDark = "#0d8bd9",
        slot      = 43,
        installed = false,
        enabled   = true,
        requiresLogin = true,
        storeDesc = "What's happening in Los Santos? Follow trends and share your thoughts.",
        features  = {"Trending topics", "Share bleets", "Follow people", "Real-time feed"},
    },
    {
        id        = "lifeinvader",
        label     = "Life Invader",
        category  = "social",
        icon      = "fa-solid fa-thumbs-up",
        color     = "#4267B2",
        colorDark = "#365899",
        slot      = 44,
        installed = false,
        enabled   = true,
        requiresLogin = true,
        storeDesc = "Connect with friends, family, and the world around you.",
        features  = {"Friend profiles", "Status updates", "Photo albums", "Event planning"},
    },
    {
        id        = "facezoom",
        label     = "FaceZoom",
        category  = "social",
        icon      = "fa-solid fa-video",
        color     = "#2D8CFF",
        colorDark = "#1a6fcc",
        slot      = 45,
        installed = false,
        enabled   = true,
        requiresLogin = false,
        storeDesc = "Video calls and meetings with anyone, anywhere.",
        features  = {"Video calls", "Group meetings", "Screen sharing", "Chat messaging"},
    },

    -- ═══════════════════════════════════════════════════════════
    -- BROWSER
    -- ═══════════════════════════════════════════════════════════
    {
        id        = "browser",
        label     = "Browser",
        category  = "utilities",
        icon      = "fa-solid fa-compass",
        color     = "#007aff",
        colorDark = "#0056cc",
        slot      = 47,
        installed = true,
        enabled   = true,
        storeDesc = "Browse the web, search and visit your favorite sites.",
        features  = {"Full web browsing", "Search engine", "Bookmarks", "Quick links"},
    },

    -- ═══════════════════════════════════════════════════════════
    -- PASSWORD MANAGER
    -- ═══════════════════════════════════════════════════════════
    {
        id        = "keychain",
        label     = "Keychain",
        category  = "utilities",
        icon      = "fa-solid fa-key",
        color     = "#8e8e93",
        colorDark = "#636366",
        slot      = 46,
        installed = true,
        enabled   = true,
        storeDesc = "View and manage your saved passwords and app accounts.",
        features  = {"Saved passwords", "App accounts", "Secure storage", "Face Unlock access"},
    },

    -- ═══════════════════════════════════════════════════════════
    -- EXAMPLE CUSTOM APP (see apps/ folder for source code)
    -- Disabled by default. Enable to test custom app integration.
    -- ═══════════════════════════════════════════════════════════
    {
        id        = "testapp",
        label     = "Test App",
        icon      = "fa-solid fa-flask",
        color     = "#5856d6",
        colorDark = "#4240b0",
        slot      = 36,
        installed = false,
        enabled   = false,
        storeDesc = "A demo app showing how custom apps work.",
    },
}

Need help? Join our Discord community for support!

Join Discord