```lua
local vector = require("vector3d")
local imgui = require("imgui")
local encoding = require("encoding")
encoding.default = 'CP1251'
u8 = encoding.UTF8

local inicfg = require('inicfg')

local mainIni = inicfg.load({
    settings = {
        maxSpeedOnFoot = 0.6,
        maxSpeedInCar = 2.2,
        minCoefOnFoot = 1.8,
        maxCoefOnFoot = 3.5,
        minCoefInCar = 6.0,
        maxCoefInCar = 9.0,
        footStepInterval = 300
    }
}, 'tppsettings')

local syncblock = false
local teleportProgress = 0 
local displayProgress = 0 
local teleportActive = false 
local teleportText = "" 
local teleportDestination = {x = 0, y = 0, z = 0} 
local settingsWindowOpen = false 
local authorLink = "https://www.youtube.com/@TheIMPL"
local telegramLink = "https://t.me/cqdll"
local raindrops = {} 
local max_drops = 15 
local drop_interval = 0.2 
local last_drop_time = os.clock() 
local raindrops_size_multiplier = 1.0 
local raindrops_speed_multiplier = 1.0 
local progressBarColor = imgui.ImVec4(0.38, 0.60, 0.95, 1.0) 
local progressBarBgColor = imgui.ImVec4(0.10, 0.10, 0.15, 0.6) 
local textColor = imgui.ImVec4(0.95, 0.95, 0.95, 1.0) 
local linkColor = imgui.ImVec4(0.48, 0.70, 0.95, 1.0) 
local windowBgColor = imgui.ImVec4(0.02, 0.02, 0.04, 0.80) 
local progressBarWindowFlags = imgui.WindowFlags.NoTitleBar + 
                               imgui.WindowFlags.NoResize + 
                               imgui.WindowFlags.NoMove + 
                               imgui.WindowFlags.NoScrollbar + 
                               imgui.WindowFlags.NoCollapse +
                               imgui.WindowFlags.AlwaysAutoResize
local guiAlpha = 0.0 
local guiTargetAlpha = 0.0 
local guiAnimSpeed = 4.0 
local guiClosing = false 
local guiOpeningTime = 0 
local guiClosingTime = 0 
local lastFrameTime = os.clock() 
local speed = 0
local maxSpeedOnFoot = mainIni.settings.maxSpeedOnFoot  
local maxSpeedInCar = mainIni.settings.maxSpeedInCar
local minCoefOnFoot = mainIni.settings.minCoefOnFoot
local maxCoefOnFoot = mainIni.settings.maxCoefOnFoot
local minCoefInCar = mainIni.settings.minCoefInCar
local maxCoefInCar = mainIni.settings.maxCoefInCar
local footStepInterval = mainIni.settings.footStepInterval
local editMaxSpeedOnFoot = imgui.ImFloat(maxSpeedOnFoot)
local editMaxSpeedInCar = imgui.ImFloat(maxSpeedInCar)
local editMinCoefOnFoot = imgui.ImFloat(minCoefOnFoot)
local editMaxCoefOnFoot = imgui.ImFloat(maxCoefOnFoot)
local editMinCoefInCar = imgui.ImFloat(minCoefInCar)
local editMaxCoefInCar = imgui.ImFloat(maxCoefInCar)
local editFootStepInterval = imgui.ImInt(footStepInterval)

AnimatedButtons = {}

function imgui.AnimatedButton(label, size, speed, rounded)
    local size = size or imgui.ImVec2(0, 0)
    local bool = false
    local text = label:gsub('##.+$', '')
    local ts = imgui.CalcTextSize(text)
    speed = speed and speed or 0.4
    if not AnimatedButtons then AnimatedButtons = {} end
    if not AnimatedButtons[label] then
        local color = imgui.GetStyle().Colors[imgui.Col.ButtonHovered]
        AnimatedButtons[label] = {circles = {}, hovered = false, state = false, time = os.clock(), color = imgui.ImVec4(color.x, color.y, color.z, 0.2)}
    end
    local button = AnimatedButtons[label]
    local hasDrawList = pcall(function() return imgui.GetWindowDrawList() end)
    local dl = hasDrawList and imgui.GetWindowDrawList() or nil
    local p = imgui.GetCursorScreenPos()
    local c = imgui.GetCursorPos()
    local CalcItemSize = function(size, width, height)
        local region = imgui.GetContentRegionMax()
        if (size.x == 0) then
            size.x = width
        elseif (size.x < 0) then
            size.x = math.max(4.0, region.x - c.x + size.x);
        end
        if (size.y == 0) then
            size.y = height;
        elseif (size.y < 0) then
            size.y = math.max(4.0, region.y - c.y + size.y);
        end
        return size
    end
    size = CalcItemSize(size, ts.x+imgui.GetStyle().FramePadding.x*2, ts.y+imgui.GetStyle().FramePadding.y*2)
    local ImSaturate = function(f) return f < 0.0 and 0.0 or (f > 1.0 and 1.0 or f) end
    if hasDrawList and dl and #button.circles > 0 then
        local PathInvertedRect = function(a, b, col)
            local rounding = rounded and imgui.GetStyle().FrameRounding or 0
            if rounding <= 0 or not rounded then return end
            dl:PathLineTo(a)
            dl:PathArcTo(imgui.ImVec2(a.x + rounding, a.y + rounding), rounding, -3.0, -1.5)
            dl:PathFillConvex(col)
            dl:PathLineTo(imgui.ImVec2(b.x, a.y))
            dl:PathArcTo(imgui.ImVec2(b.x - rounding, a.y + rounding), rounding, -1.5, -0.205)
            dl:PathFillConvex(col)
            dl:PathLineTo(imgui.ImVec2(b.x, b.y))
            dl:PathArcTo(imgui.ImVec2(b.x - rounding, b.y - rounding), rounding, 1.5, 0.205)
            dl:PathFillConvex(col)
            dl:PathLineTo(imgui.ImVec2(a.x, b.y))
            dl:PathArcTo(imgui.ImVec2(a.x + rounding, b.y - rounding), rounding, 3.0, 1.5)
            dl:PathFillConvex(col)
        end
        for i, circle in ipairs(button.circles) do
            local time = os.clock() - circle.time
            local t = ImSaturate(time / speed)
            local color = imgui.GetStyle().Colors[imgui.Col.ButtonActive]
            local color = imgui.GetColorU32(imgui.ImVec4(color.x, color.y, color.z, (circle.reverse and (255-255*t) or (255*t))/255))
            local max_size = math.max(size.x, size.y) * 0.6
            local radius = max_size * (circle.reverse and 0.6 or t)
            if pcall(function() imgui.PushClipRect(p, imgui.ImVec2(p.x+size.x, p.y+size.y), true) end) then
                dl:AddCircleFilled(circle.clickpos, radius, color, 12) 
                PathInvertedRect(p, imgui.ImVec2(p.x+size.x, p.y+size.y), imgui.GetColorU32(imgui.GetStyle().Colors[imgui.Col.WindowBg]))
                imgui.PopClipRect()
            end
            if t == 1 then
                if not circle.reverse then
                    circle.reverse = true
                    circle.time = os.clock()
                else
                    table.remove(button.circles, i)
                end
            end
        end
    end
    local t = ImSaturate((os.clock()-button.time) / speed)
    button.color.w = button.color.w + (button.hovered and 0.8 or -0.8)*t
    button.color.w = button.color.w < 0.2 and 0.2 or (button.color.w > 1 and 1 or button.color.w)
    if hasDrawList and dl then
        local color = imgui.GetStyle().Colors[imgui.Col.Button]
        local btnColor = imgui.GetColorU32(imgui.ImVec4(color.x, color.y, color.z, 0.2))
        dl:AddRectFilled(p, imgui.ImVec2(p.x+size.x, p.y+size.y), btnColor, rounded and imgui.GetStyle().FrameRounding or 0)
        dl:AddRect(p, imgui.ImVec2(p.x+size.x, p.y+size.y), imgui.GetColorU32(button.color), rounded and imgui.GetStyle().FrameRounding or 0)
    end
    local align = imgui.GetStyle().ButtonTextAlign
    imgui.SetCursorPos(imgui.ImVec2(c.x+(size.x-ts.x)*align.x, c.y+(size.y-ts.y)*align.y))
    imgui.Text(text)
    imgui.SetCursorPos(c)
    if imgui.InvisibleButton(label, size) then
        bool = true
        if hasDrawList then
            local cursorPos
            if pcall(function() cursorPos = imgui.GetIO().MousePos end) then
                table.insert(button.circles, {
                    animate = true, 
                    reverse = false, 
                    time = os.clock(), 
                    clickpos = imgui.ImVec2(cursorPos.x, cursorPos.y)
                })
            else
                table.insert(button.circles, {
                    animate = true, 
                    reverse = false, 
                    time = os.clock(), 
                    clickpos = imgui.ImVec2(p.x + size.x/2, p.y + size.y/2)
                })
            end
        end
    end
    button.hovered = imgui.IsItemHovered()
    if button.hovered ~= button.state then
        button.state = button.hovered
        button.time = os.clock()
    end
    return bool
end

function randomInRange(min, max)
    return min + math.random() * (max - min)
end

function saveSettings()
    mainIni.settings.maxSpeedOnFoot = maxSpeedOnFoot
    mainIni.settings.maxSpeedInCar = maxSpeedInCar
    mainIni.settings.minCoefOnFoot = minCoefOnFoot
    mainIni.settings.maxCoefOnFoot = maxCoefOnFoot
    mainIni.settings.minCoefInCar = minCoefInCar
    mainIni.settings.maxCoefInCar = maxCoefInCar
    mainIni.settings.footStepInterval = footStepInterval
    inicfg.save(mainIni, 'tppsettings')
end

function applyImGuiStyle()
    imgui.SwitchContext()
    local style = imgui.GetStyle()
    local colors = style.Colors
    local clr = imgui.Col
    local ImVec4 = imgui.ImVec4
    local ImVec2 = imgui.ImVec2
    style.WindowRounding = 8.0
    style.WindowTitleAlign = ImVec2(0.5, 0.5)
    style.FrameRounding = 6.0
    style.ItemSpacing = ImVec2(8, 6)
    style.ScrollbarSize = 12
    style.ScrollbarRounding = 8
    style.GrabMinSize = 8
    style.GrabRounding = 3.0
    style.WindowPadding = ImVec2(10, 10)
    style.AntiAliasedLines = true
    style.FramePadding = ImVec2(6, 4)
    style.DisplayWindowPadding = ImVec2(24, 24)
    style.DisplaySafeAreaPadding = ImVec2(8, 8)
    style.ButtonTextAlign = ImVec2(0.5, 0.5)
    style.IndentSpacing = 20.0
    style.Alpha = 1.0
    local function setColor(colorEnum, colorValue)
        if type(colorEnum) == "number" and colors[colorEnum] ~= nil then
            colors[colorEnum] = colorValue
        end
    end
    setColor(clr.Text,                  ImVec4(0.95, 0.95, 0.95, 1.00))
    setColor(clr.TextDisabled,          ImVec4(0.60, 0.60, 0.60, 1.00))
    setColor(clr.WindowBg,              ImVec4(0.02, 0.02, 0.04, 0.80)) 
    setColor(clr.ChildBg,               ImVec4(0.05, 0.05, 0.08, 0.80)) 
    setColor(clr.PopupBg,               ImVec4(0.05, 0.05, 0.08, 0.80)) 
    setColor(clr.Border,                ImVec4(0.40, 0.40, 0.50, 0.40))
    setColor(clr.BorderShadow,          ImVec4(0.00, 0.00, 0.00, 0.00))
    setColor(clr.FrameBg,               ImVec4(0.08, 0.08, 0.12, 0.50)) 
    setColor(clr.FrameBgHovered,        ImVec4(0.20, 0.20, 0.27, 0.40))
    setColor(clr.FrameBgActive,         ImVec4(0.25, 0.25, 0.33, 0.60))
    setColor(clr.TitleBg,               ImVec4(0.08, 0.08, 0.12, 0.85))
    setColor(clr.TitleBgActive,         ImVec4(0.10, 0.10, 0.15, 0.90))
    setColor(clr.TitleBgCollapsed,      ImVec4(0.08, 0.08, 0.12, 0.70))
    setColor(clr.MenuBarBg,             ImVec4(0.08, 0.08, 0.12, 0.90))
    setColor(clr.ScrollbarBg,           ImVec4(0.08, 0.08, 0.12, 0.90))
    setColor(clr.ScrollbarGrab,         ImVec4(0.25, 0.25, 0.33, 0.90))
    setColor(clr.ScrollbarGrabHovered,  ImVec4(0.30, 0.30, 0.40, 0.90))
    setColor(clr.ScrollbarGrabActive,   ImVec4(0.35, 0.35, 0.45, 0.90))
    setColor(clr.CheckMark,             ImVec4(0.38, 0.60, 0.95, 0.80))
    setColor(clr.SliderGrab,            ImVec4(0.38, 0.60, 0.95, 0.8))
    setColor(clr.SliderGrabActive,      ImVec4(0.48, 0.70, 0.95, 1.00))
    setColor(clr.Button,                ImVec4(0.20, 0.25, 0.40, 0.60))
    setColor(clr.ButtonHovered,         ImVec4(0.28, 0.35, 0.50, 0.75))
    setColor(clr.ButtonActive,          ImVec4(0.38, 0.45, 0.64, 0.90))
    setColor(clr.Header,                ImVec4(0.25, 0.30, 0.45, 0.45))
    setColor(clr.HeaderHovered,         ImVec4(0.35, 0.40, 0.55, 0.75))
    setColor(clr.HeaderActive,          ImVec4(0.45, 0.50, 0.65, 0.90))
    setColor(clr.Separator,             ImVec4(0.40, 0.45, 0.60, 0.50))
    setColor(clr.SeparatorHovered,      ImVec4(0.45, 0.50, 0.65, 0.70))
    setColor(clr.SeparatorActive,       ImVec4(0.50, 0.55, 0.70, 0.90))
    setColor(clr.ResizeGrip,            ImVec4(0.38, 0.60, 0.95, 0.25))
    setColor(clr.ResizeGripHovered,     ImVec4(0.48, 0.70, 0.95, 0.60))
    setColor(clr.ResizeGripActive,      ImVec4(0.58, 0.80, 0.95, 0.90))
    setColor(clr.PlotLines,             ImVec4(0.61, 0.61, 0.61, 1.00))
    setColor(clr.PlotLinesHovered,      ImVec4(1.00, 0.70, 0.35, 1.00))
    setColor(clr.PlotHistogram,         ImVec4(0.38, 0.60, 0.95, 0.80))
    setColor(clr.PlotHistogramHovered,  ImVec4(0.48, 0.70, 0.95, 0.80))
    setColor(clr.TextSelectedBg,        ImVec4(0.38, 0.60, 0.95, 0.35))
end

function main()
    while not isSampAvailable() do wait(0) end
    imgui.Process = false
    imgui.SwitchContext()
    applyImGuiStyle()
    local style = imgui.GetStyle()
    local function safeSetColor(key, color)
        if type(key) == "number" and style.Colors[key] ~= nil then
            style.Colors[key] = color
        end
    end
    safeSetColor(imgui.Col.PlotHistogram, progressBarColor)      
    safeSetColor(imgui.Col.PlotHistogramHovered, progressBarColor) 
    safeSetColor(imgui.Col.FrameBg, progressBarBgColor)          
    safeSetColor(imgui.Col.Text, textColor)
    safeSetColor(imgui.Col.WindowBg, windowBgColor)
    function closeGuiWithAnimation()
        guiTargetAlpha = 0.0
        guiClosing = true
        guiClosingTime = os.clock() 
    end
    function openGuiWithAnimation()
        guiTargetAlpha = 1.0
        guiClosing = false
        imgui.Process = true
        guiOpeningTime = os.clock() 
    end
    sampRegisterChatCommand('stp', function()
        if not syncblock then
            local res, x, y, z = getTargetBlipCoordinatesFixed()
            if res then
                teleportActive = true
                teleportProgress = 0
                displayProgress = 0
                teleportDestination = {x = x, y = y, z = z}
                teleportText = "Подготовка к телепорту..."
                openGuiWithAnimation() 
                showCursor(false) 
                lua_thread.create(function()
                    local status, err = pcall(coordMaster, x, y, z)
                    if not status then
                        sampAddChatMessage('Ошибка телепорта: '..tostring(err), 0xFF0000)
                        syncblock = false
                        teleportActive = false
                        closeGuiWithAnimation() 
                    end
                end)
            else
                sampAddChatMessage('Метка не найдена', 0xFF0000)
            end
        else
            sampAddChatMessage('Телепорт уже выполняется', -1)    
        end
    end)
    sampRegisterChatCommand('stps', function()
        if settingsWindowOpen then
            closeGuiWithAnimation() 
        else
            settingsWindowOpen = true
            openGuiWithAnimation() 
        end
    end)
    local teleportFinishing = false 
    while true do
        wait(0)
        local currentTime = os.clock()
        local deltaTime = currentTime - lastFrameTime
        lastFrameTime = currentTime
        if guiAlpha ~= guiTargetAlpha then
            if guiTargetAlpha > guiAlpha then
                guiAlpha = guiAlpha + deltaTime * guiAnimSpeed
                if guiAlpha >= guiTargetAlpha then
                    guiAlpha = guiTargetAlpha
                end
            else
                guiAlpha = guiAlpha - deltaTime * guiAnimSpeed
                if guiAlpha <= 0.0 then
                    guiAlpha = 0.0
                    if guiClosing then
                        imgui.Process = false
                        settingsWindowOpen = false
                        guiClosing = false
                        if teleportFinishing then
                            teleportFinishing = false
                        end
                    end
                end
            end
        end
        imgui.Process = teleportActive or teleportFinishing or settingsWindowOpen or guiAlpha > 0.0
        if teleportActive then
            if displayProgress < teleportProgress then
                displayProgress = displayProgress + (teleportProgress - displayProgress) * 0.07
                if teleportProgress - displayProgress < 0.1 then
                    displayProgress = teleportProgress
                end
            end
            showCursor(false)
        end
    end
end

function imgui.OnDrawFrame()
    local oldAlpha = imgui.GetStyle().Alpha
    imgui.GetStyle().Alpha = guiAlpha
    local timeSinceOpening = os.clock() - guiOpeningTime
    local timeSinceClosing = os.clock() - guiClosingTime
    local vibrationOffset = imgui.ImVec2(0, 0)
    local closingOffset = imgui.ImVec2(0, 0)
    if settingsWindowOpen then
        local sw, sh = getScreenResolution()
        imgui.SetNextWindowPos(
            imgui.ImVec2(
                sw / 2 - 200, 
                sh / 2 - 200
            ), 
            imgui.Cond.Always
        )
        drawSettingsWindow()
    end
    if teleportActive or teleportFinishing then
        local sw, sh = getScreenResolution()
        local windowWidth = 240
        local windowHeight = 85
        imgui.SetNextWindowPos(
            imgui.ImVec2(
                sw / 2 - windowWidth / 2, 
                sh - windowHeight - 20
            ), 
            imgui.Cond.Always
        )
        drawTeleportProgressBar()
    end
    imgui.GetStyle().Alpha = oldAlpha
end

function drawCloseButton(size, color)
    local p = imgui.GetCursorScreenPos()
    local draw_list = imgui.GetWindowDrawList()
    local thickness = 2.0
    local padding = 4.0
    local bgColorNormal = imgui.GetColorU32(imgui.ImVec4(0.1, 0.1, 0.15, 0.7))
    local bgColorHovered = imgui.GetColorU32(imgui.ImVec4(0.15, 0.15, 0.22, 0.85))
    local xColorNormal = imgui.GetColorU32(progressBarColor) 
    local xColorHovered = imgui.GetColorU32(imgui.ImVec4(
        progressBarColor.x + 0.1,
        progressBarColor.y + 0.1,
        progressBarColor.z + 0.1,
        1.0
    )) 
    local result = imgui.InvisibleButton("##close", imgui.ImVec2(size, size))
    local isHovered = imgui.IsItemHovered()
    local bgColor = isHovered and bgColorHovered or bgColorNormal
    local xColor = isHovered and xColorHovered or xColorNormal
    draw_list:AddCircleFilled(imgui.ImVec2(p.x + size/2, p.y + size/2), size/2, bgColor, 12)
    draw_list:AddLine(
        imgui.ImVec2(p.x + padding, p.y + padding),
        imgui.ImVec2(p.x + size - padding, p.y + size - padding),
        xColor, 
        thickness
    )
    draw_list:AddLine(
        imgui.ImVec2(p.x + size - padding, p.y + padding),
        imgui.ImVec2(p.x + padding, p.y + size - padding),
        xColor, 
        thickness
    )
    return result
end

function drawSettingsWindow()
    imgui.SetNextWindowSize(imgui.ImVec2(400, 400), imgui.Cond.Always)
    local settingsWindowFlags = imgui.WindowFlags.NoTitleBar + imgui.WindowFlags.NoResize
    if imgui.Begin(u8("sTeleport"), nil, settingsWindowFlags) then
        imgui.SetCursorPos(imgui.ImVec2(imgui.GetWindowWidth() - 25, 5))
        if drawCloseButton(20, imgui.ImVec4(1.0, 0.4, 0.4, 1.0)) then
            closeGuiWithAnimation() 
        end
        imgui.SetCursorPos(imgui.ImVec2(10, 5))
        imgui.PushStyleColor(imgui.Col.Text, imgui.ImVec4(1.0, 1.0, 1.0, 1.0))
        imgui.Text(u8("sTeleport"))
        imgui.PopStyleColor()
        imgui.SetCursorPos(imgui.ImVec2(10, 25))
        imgui.PushStyleVar(imgui.StyleVar.ItemSpacing, imgui.ImVec2(6, 4))
        imgui.PushItemWidth(200)
        imgui.Text(u8("Настройки для персонажа пешком:"))
        imgui.Separator()
        local changed = false
        changed = imgui.SliderFloat(u8("Макс. скорость пешком"), editMaxSpeedOnFoot, 0.1, 2.0) or changed
        changed = imgui.SliderFloat(u8("Мин. коэф. скорости пешком"), editMinCoefOnFoot, 0.5, 5.0) or changed
        changed = imgui.SliderFloat(u8("Макс. коэф. скорости пешком"), editMaxCoefOnFoot, 0.5, 10.0) or changed
        changed = imgui.SliderInt(u8("Интервал между шагами (мс)"), editFootStepInterval, 100, 1000) or changed
        imgui.SetCursorPosY(imgui.GetCursorPosY() + 5)
        imgui.Text(u8("Настройки для транспорта:"))
        imgui.Separator()
        changed = imgui.SliderFloat(u8("Макс. скорость в машине"), editMaxSpeedInCar, 0.5, 5.0) or changed
        changed = imgui.SliderFloat(u8("Мин. коэф. скорости в машине"), editMinCoefInCar, 1.0, 15.0) or changed
        changed = imgui.SliderFloat(u8("Макс. коэф. скорости в машине"), editMaxCoefInCar, 1.0, 20.0) or changed
        if changed then
            maxSpeedOnFoot = editMaxSpeedOnFoot.v
            maxSpeedInCar = editMaxSpeedInCar.v
            minCoefOnFoot = editMinCoefOnFoot.v
            maxCoefOnFoot = editMaxCoefOnFoot.v
            minCoefInCar = editMinCoefInCar.v
            maxCoefInCar = editMaxCoefInCar.v
            footStepInterval = editFootStepInterval.v
            saveSettings()
        end
        imgui.SetCursorPosY(imgui.GetCursorPosY() + 5)
        local buttonWidth = imgui.GetWindowWidth() - 20
        if imgui.AnimatedButton(u8("Сбросить настройки"), imgui.ImVec2(buttonWidth, 30), 0.3, true) then
            editMaxSpeedOnFoot.v = 0.6
            editMaxSpeedInCar.v = 2.2
            editMinCoefOnFoot.v = 1.8
            editMaxCoefOnFoot.v = 3.5
            editMinCoefInCar.v = 6.0
            editMaxCoefInCar.v = 9.0
            editFootStepInterval.v = 300
            maxSpeedOnFoot = editMaxSpeedOnFoot.v
            maxSpeedInCar = editMaxSpeedInCar.v
            minCoefOnFoot = editMinCoefOnFoot.v
            maxCoefOnFoot = editMaxCoefOnFoot.v
            minCoefInCar = editMinCoefInCar.v
            maxCoefInCar = editMaxCoefInCar.v
            footStepInterval = editFootStepInterval.v
            saveSettings()
            sampAddChatMessage(u8:decode("Настройки телепорта сброшены до значений по умолчанию"), 0x00FF00)
        end
        imgui.PopItemWidth()
        imgui.SetCursorPosY(imgui.GetCursorPosY() + 8)
        imgui.Separator()
        imgui.SetCursorPosY(imgui.GetCursorPosY() + 8)
        imgui.CenterText(u8("TheIMPL"))
        imgui.SetCursorPosY(imgui.GetCursorPosY() + 5)
        local tgText = u8("Telegram: @cqdll")
        local tgTextSize = imgui.CalcTextSize(tgText)
        imgui.SetCursorPosX((imgui.GetWindowWidth() - tgTextSize.x) * 0.5)
        imgui.PushStyleColor(imgui.Col.Text, linkColor)
        imgui.Text(tgText)
        if imgui.IsItemClicked() then
            os.execute('start "" "' .. telegramLink .. '"')
        end
        imgui.PopStyleColor()
        if imgui.IsItemHovered() then
            local pos = imgui.GetCursorScreenPos()
            local draw_list = imgui.GetWindowDrawList()
            for i = 1, tgText:len() do
                local charPos = imgui.ImVec2(pos.x - tgTextSize.x + i * (tgTextSize.x / tgText:len()), pos.y - tgTextSize.y * 0.5)
                draw_list:AddCircleFilled(
                    charPos,
                    1.0,
                    imgui.GetColorU32(imgui.ImVec4(linkColor.x, linkColor.y, linkColor.z, 0.15)),
                    6
                )
            end
        end
        local ytText = u8("YouTube: TheIMPL")
        local ytTextSize = imgui.CalcTextSize(ytText)
        imgui.SetCursorPosX((imgui.GetWindowWidth() - ytTextSize.x) * 0.5)
        imgui.PushStyleColor(imgui.Col.Text, linkColor)
        imgui.Text(ytText)
        if imgui.IsItemClicked() then
            os.execute('start "" "' .. authorLink .. '"')
        end
        imgui.PopStyleColor()
        if imgui.IsItemHovered() then
            local pos = imgui.GetCursorScreenPos()
            local draw_list = imgui.GetWindowDrawList()
            for i = 1, ytText:len() do
                local charPos = imgui.ImVec2(pos.x - ytTextSize.x + i * (ytTextSize.x / ytText:len()), pos.y - tgTextSize.y * 0.5)
                draw_list:AddCircleFilled(
                    charPos,
                    1.0,
                    imgui.GetColorU32(imgui.ImVec4(linkColor.x, linkColor.y, linkColor.z, 0.15)),
                    6
                )
            end
        end
        imgui.PopStyleVar()
    end
    imgui.End()
end

function drawTeleportProgressBar()
    local sw, sh = getScreenResolution()
    local windowWidth = 240
    local windowHeight = 85
    imgui.SetNextWindowSize(imgui.ImVec2(windowWidth, windowHeight), imgui.Cond.Always)
    local hasBackgroundDrawList = pcall(function() return imgui.GetBackgroundDrawList() end)
    if hasBackgroundDrawList then
        local windowPos = imgui.GetWindowPos()
        local windowSize = imgui.ImVec2(windowWidth, windowHeight)
        local dl = imgui.GetBackgroundDrawList()
        for i = 0, 15 do
            local alpha = 0.3 - i * 0.02
            if alpha > 0 then
                dl:AddRectFilled(
                    imgui.ImVec2(windowPos.x - i, windowPos.y - i),
                    imgui.ImVec2(windowPos.x + windowSize.x + i, windowPos.y + windowSize.y + i),
                    imgui.GetColorU32(imgui.ImVec4(0, 0, 0, alpha * guiAlpha)), 
                    10.0 + i * 0.2
                )
            end
        end
    end
    imgui.PushStyleVar(imgui.StyleVar.WindowRounding, 10.0)
    imgui.PushStyleVar(imgui.StyleVar.WindowPadding, imgui.ImVec2(12, 10))
    imgui.PushStyleColor(imgui.Col.WindowBg, windowBgColor)
    if imgui.Begin("##TeleportProgress", nil, progressBarWindowFlags) then
        imgui.PushStyleColor(imgui.Col.Text, textColor)
        local current_time = os.clock()
        local delta_time = imgui.GetIO().DeltaTime
        local window_pos = imgui.GetWindowPos()
        local window_size = imgui.GetWindowSize()
        local title_scale = 1.0 + math.sin(current_time * 2) * 0.02
        local dist_text = string.format("%.1f м", getDistanceBetweenCoords3d(
            getCharCoordinates(PLAYER_PED), 
            teleportDestination.x, teleportDestination.y, teleportDestination.z
        ))
        local title_width = imgui.CalcTextSize(u8(dist_text)).x * title_scale
        imgui.SetCursorPosX((imgui.GetWindowWidth() - title_width) * 0.5)
        local title_alpha = 0.8 + math.sin(current_time * 3) * 0.2
        imgui.PushStyleColor(imgui.Col.Text, imgui.ImVec4(progressBarColor.x, progressBarColor.y, progressBarColor.z, title_alpha))
        imgui.Text(u8(dist_text))
        imgui.PopStyleColor()
        imgui.Spacing()
        local bar_width = imgui.GetWindowWidth() - 24
        local bar_height = 24  
        imgui.PushStyleColor(imgui.Col.PlotHistogram, progressBarColor)
        imgui.PushStyleColor(imgui.Col.FrameBg, progressBarBgColor)
        imgui.PushStyleVar(imgui.StyleVar.FrameRounding, 5.0) 
        imgui.SetCursorPosX(12)
        local progress = displayProgress / 100
        local current_progress_text = string.format("%.1f%%", displayProgress)
        imgui.ProgressBar(progress, imgui.ImVec2(bar_width, bar_height), "")
        local cursor_pos = imgui.GetCursorPos()
        if pcall(function() return imgui.GetWindowDrawList() end) then
            local draw_list = imgui.GetWindowDrawList()
            update_and_draw_raindrops(draw_list, window_pos, window_size, delta_time)
            local pb_pos_x = window_pos.x + 12
            local pb_pos_y = window_pos.y + cursor_pos.y - bar_height - imgui.GetStyle().ItemSpacing.y
            local percent_size = imgui.CalcTextSize(current_progress_text)
            local text_pos_x = pb_pos_x + (bar_width / 2) - (percent_size.x / 2)
            local text_pos_y = pb_pos_y + (bar_height / 2) - (percent_size.y / 2)
            draw_list:AddText(
                imgui.ImVec2(text_pos_x, text_pos_y),
                imgui.GetColorU32(imgui.ImVec4(1, 1, 1, 1)),
                current_progress_text
            )
        else
            local percent_size = imgui.CalcTextSize(current_progress_text)
            imgui.SetCursorPos(imgui.ImVec2((imgui.GetWindowWidth() - percent_size.x) * 0.5, cursor_pos.y - bar_height * 0.95))
            imgui.PushStyleColor(imgui.Col.Text, imgui.ImVec4(1, 1, 1, 1))
            imgui.Text(current_progress_text)
            imgui.PopStyleColor()
        end
        imgui.PopStyleVar() 
        imgui.PopStyleColor(2) 
        imgui.SetCursorPosY(cursor_pos.y + 2)
        imgui.PushStyleColor(imgui.Col.Text, linkColor)
        local textToShow = u8("by TheIMPL")
        local linkTextSize = imgui.CalcTextSize(textToShow)
        imgui.SetCursorPosX((imgui.GetWindowWidth() - linkTextSize.x) * 0.5)
        imgui.TextColored(linkColor, textToShow)
        if imgui.IsItemClicked() then
            os.execute('start "" "' .. authorLink .. '"')
        end
        if imgui.IsItemHovered() then
            local pos = imgui.GetCursorScreenPos()
            local draw_list = imgui.GetWindowDrawList()
            for i = 1, textToShow:len() do
                local charPos = imgui.ImVec2(
                    pos.x - linkTextSize.x + i * (linkTextSize.x / textToShow:len()), 
                    pos.y - linkTextSize.y * 0.5 - 2
                )
                draw_list:AddCircleFilled(
                    charPos,
                    1.2,
                    imgui.GetColorU32(imgui.ImVec4(linkColor.x, linkColor.y, linkColor.z, 0.15)),
                    6
                )
            end
        end
        imgui.PopStyleColor()
        imgui.PopStyleColor() 
    end
    imgui.End()
    imgui.PopStyleColor(1) 
    imgui.PopStyleVar(2) 
end

function imgui.CenterText(text)
    local width = imgui.GetWindowWidth()
    local textWidth = imgui.CalcTextSize(text).x
    imgui.SetCursorPosX((width - textWidth) * 0.5)
    imgui.Text(text)
end

function onSendPacket(id)
    if syncblock and (id == 200 or id == 207 or id == 211 or id == 203) then
        return false
    end
end

function coordMaster(x, y, z) 
    local pos = {x, y, z}
    local char = {getCharCoordinates(PLAYER_PED)}
    local vecDist = getDistanceBetweenCoords3d(char[1], char[2], char[3], pos[1], pos[2], pos[3])
    local isInCar = isCharInAnyCar(PLAYER_PED)
    local v = isInCar and storeCarCharIsInNoSave(PLAYER_PED) or -1
    local coef = isInCar and minCoefInCar or minCoefOnFoot
    local start = os.time()
    local w = 50
    local step = 0
    local stepLimit = math.random(10, 20)
    local progress = 0
    local lastSyncTime = 0
    local minSyncInterval = 40 
    local lastStepTime = os.clock() * 1000 
    math.randomseed(os.time())
    syncblock = true
    local function handleError(err)
        print("Ошибка в телепорте: " .. tostring(err))
        syncblock = false
        teleportActive = false
        teleportFinishing = true 
        closeGuiWithAnimation()
        teleportText = "Ошибка телепорта!"
        return false
    end
    local status, err = pcall(function()
    while getDistanceBetweenCoords3d(char[1], char[2], char[3], pos[1], pos[2], pos[3]) >= coef and syncblock do
            progress = 100 - (getDistanceBetweenCoords3d(char[1], char[2], char[3], pos[1], pos[2], pos[3]) / vecDist) * 100
            teleportProgress = progress
            teleportText = string.format("Телепорт: %.1f%% (%.1f м)", progress, 
                getDistanceBetweenCoords3d(char[1], char[2], char[3], pos[1], pos[2], pos[3]))
            local moveVector = vector(pos[1] - char[1], pos[2] - char[2], pos[3] - char[3])
            moveVector:normalize()
            local heading = -math.deg(math.atan2(moveVector.x, moveVector.y))
            if heading < 0 then heading = heading + 360 end
            if not isCharInAnyCar(PLAYER_PED) then
                setCharHeading(PLAYER_PED, heading)
            end
            if math.random() < 0.3 then  
                moveVector.x = moveVector.x + randomInRange(-0.05, 0.05)
                moveVector.y = moveVector.y + randomInRange(-0.05, 0.05)
                moveVector:normalize()
            end
            local currentTime = os.clock() * 1000
            if isCharInAnyCar(PLAYER_PED) then
                coef = randomInRange(minCoefInCar, maxCoefInCar)
                char[1] = char[1] + moveVector.x * coef
                char[2] = char[2] + moveVector.y * coef
                char[3] = char[3] + moveVector.z * coef
                if progress < 30 then
                    speed = speed < (maxSpeedInCar * 0.7) and speed + randomInRange(0.01, 0.03) or speed
                elseif progress > 70 then
                    speed = speed > 0.3 and speed - randomInRange(0.01, 0.03) or speed
                else
                    speed = speed < maxSpeedInCar and speed + randomInRange(0.01, 0.04) or speed
                end
                if currentTime - lastSyncTime >= minSyncInterval then
                    local syncStatus, syncErr = pcall(function() 
            SendVehicleSync(char[1], char[2], char[3])
                    end)
                    if not syncStatus then
                        print("Ошибка синхронизации транспорта: " .. tostring(syncErr))
                    end
                    lastSyncTime = currentTime
                end
                w = math.random(45, 60)
                stepLimit = math.random(8, 15)
            elseif isCharOnFoot(PLAYER_PED) then
                if currentTime - lastStepTime >= footStepInterval then
                    coef = randomInRange(minCoefOnFoot, maxCoefOnFoot)
                    char[1] = char[1] + moveVector.x * coef
                    char[2] = char[2] + moveVector.y * coef
                    char[3] = char[3] + moveVector.z * coef
                    if progress < 30 then
                        speed = speed < (maxSpeedOnFoot * 0.7) and speed + randomInRange(0.01, 0.03) or speed
                    elseif progress > 70 then
                        speed = speed > 0.3 and speed - randomInRange(0.01, 0.03) or speed
                    else
                        speed = speed < maxSpeedOnFoot and speed + randomInRange(0.01, 0.04) or speed
                    end
                    local syncStatus, syncErr = pcall(function() 
                        sendPlayerSync(char[1], char[2], char[3])
                    end)
                    if not syncStatus then
                        print("Ошибка синхронизации игрока: " .. tostring(syncErr))
                    end
                    lastStepTime = currentTime
                    lastSyncTime = currentTime
                    wait(math.random(150, 250)) 
                end
                w = math.random(15, 25) 
                stepLimit = math.random(10, 15) 
            end
        wait(w)
        step = step + 1
            if step >= stepLimit then
            step = 0
                stepLimit = math.random(10, 20)
                wait(math.random(200, 400))
        end
            local currentDist = getDistanceBetweenCoords3d(char[1], char[2], char[3], pos[1], pos[2], pos[3])
            if currentDist <= coef or os.time() - start > 30 then 
            speed = 0
            syncblock = false
                teleportActive = false
                teleportFinishing = true 
                teleportProgress = 100
                teleportText = "Телепорт завершен!"
                setCharCoordinates(PLAYER_PED, x, y, z)
                closeGuiWithAnimation()
                break
            end
        end
    end)
    if not status then
        handleError(err)
    end
    if syncblock then 
        syncblock = false
        teleportActive = false
        teleportFinishing = true 
        closeGuiWithAnimation()
    end
    return true
end

function getTargetBlipCoordinatesFixed()
    local bool, x, y, z = getTargetBlipCoordinates(); if not bool then return false end
    requestCollision(x, y); loadScene(x, y, z)
    local bool, x, y, z = getTargetBlipCoordinates()
    return bool, x, y, z
end

function SendVehicleSync(x, y, z)
    local data = samp_create_sync_data("vehicle")
    data.vehicleId = select(2, sampGetVehicleIdByCarHandle(storeCarCharIsInNoSave(PLAYER_PED)))
    data.position = {x, y, z}
    data.moveSpeed = {speed + randomInRange(-0.1, 0.1), speed + randomInRange(-0.1, 0.1), randomInRange(-0.05, 0.15)}
    data.vehicleHealth = getCarHealth(storeCarCharIsInNoSave(PLAYER_PED))
    data.send()
end

function sendPlayerSync(x, y, z)
	local data = samp_create_sync_data("player")
    data.position = {x, y, z}
    data.moveSpeed = {speed + randomInRange(-0.05, 0.05), randomInRange(-0.05, 0.05), randomInRange(-0.05, 0.1)}
    pcall(function()
        if data.animationId ~= nil then
            if speed > 0.3 then
                data.animationId = 4 
                data.animationFlags = 4
            else
                data.animationId = 3 
                data.animationFlags = 1
            end
        end
    end)
    pcall(function()
        if data.keysData ~= nil then
            data.keysData = 128 
        end
    end)
    pcall(function()
        if data.health ~= nil then
            data.health = getCharHealth(PLAYER_PED)
        end
        if data.armor ~= nil then
            data.armor = getCharArmour(PLAYER_PED)
        end
    end)
    pcall(function()
        if data.rotation ~= nil then
            data.rotation = getCharHeading(PLAYER_PED)
        end
    end)
    if isCharInAnyCar(PLAYER_PED) then return end
    data.send()
end

function getStructElement(struct, fieldName)
    local status, result = pcall(function() return struct[fieldName] end)
    if status then
        return result
    else
        return nil
    end
end

function samp_create_sync_data(sync_type, copy_from_player)
    local ffi = require 'ffi'
    local sampfuncs = require 'sampfuncs'
    local raknet = require 'samp.raknet'
    require 'samp.synchronization'
    copy_from_player = copy_from_player or true
    local sync_traits = {
        player = {'PlayerSyncData', raknet.PACKET.PLAYER_SYNC, sampStorePlayerOnfootData},
        vehicle = {'VehicleSyncData', raknet.PACKET.VEHICLE_SYNC, sampStorePlayerIncarData}
    }
    local data = ffi.new('struct ' .. sync_traits[sync_type][1], {})
    local func_send = function()
        local bs = raknetNewBitStream()
        raknetBitStreamWriteInt8(bs, sync_traits[sync_type][2])
        raknetBitStreamWriteBuffer(bs, tonumber(ffi.cast('uintptr_t', ffi.new('struct ' .. sync_traits[sync_type][1] .. '*', data))), ffi.sizeof(data))
        raknetSendBitStreamEx(bs, sampfuncs.HIGH_PRIORITY, sampfuncs.UNRELIABLE_SEQUENCED, 1)
        raknetDeleteBitStream(bs)
    end
    return setmetatable({send = func_send}, {__index = function(t, index) return data[index] end, __newindex = function(t, index, value) data[index] = value end})
end

function create_raindrop(window_pos, window_size)
    local r, g, b = progressBarColor.x, progressBarColor.y, progressBarColor.z
    local a = math.random(60, 90) / 100
    local special_color = math.random() < 0.3 
    local drop = {
        x = window_pos.x + math.random(10, window_size.x - 10), 
        y = window_pos.y - math.random(0, 20), 
        radius = math.random(2, 4) * raindrops_size_multiplier, 
        speed = math.random(25, 60) / 100 * raindrops_speed_multiplier, 
        color = imgui.ImVec4(r, g, b, a), 
        glow_color = imgui.ImVec4(r, g, b, a * 0.4), 
        oscillation = {
            amplitude = math.random(3, 10) / 10 * raindrops_speed_multiplier, 
            speed = math.random(1, 4) / 10 * raindrops_speed_multiplier, 
            offset = math.random(0, 628) / 100, 
        },
        trail = {}, 
        has_trail = special_color or (math.random() < 0.2), 
        pulse = {
            active = special_color or (math.random() < 0.3), 
            speed = math.random(2, 5) / 10 * raindrops_speed_multiplier,
            min = 0.7,
            max = 1.3
        }
    }
    table.insert(raindrops, drop)
end

function update_and_draw_raindrops(dl, window_pos, window_size, delta_time)
    if os.clock() - last_drop_time > drop_interval and #raindrops < max_drops then
        create_raindrop(window_pos, window_size)
        last_drop_time = os.clock()
    end
    for i = #raindrops, 1, -1 do
        local drop = raindrops[i]
        drop.y = drop.y + drop.speed * 60 * delta_time
        local base_x = drop.x
        if drop.oscillation then
            drop.x = base_x + math.sin((os.clock() + drop.oscillation.offset) * drop.oscillation.speed * 10) * drop.oscillation.amplitude * 10
        end
        local current_radius = drop.radius
        if drop.pulse and drop.pulse.active then
            local pulse_factor = drop.pulse.min + (math.sin(os.clock() * drop.pulse.speed * 10) * 0.5 + 0.5) * (drop.pulse.max - drop.pulse.min)
            current_radius = drop.radius * pulse_factor
        end
        if drop.has_trail and #drop.trail < 5 and math.random() < 0.3 then
            table.insert(drop.trail, {
                x = drop.x,
                y = drop.y,
                radius = current_radius * 0.8,
                alpha = 0.5,
                age = 0
            })
        end
        for j = #drop.trail, 1, -1 do
            local trail = drop.trail[j]
            trail.age = trail.age + delta_time
            trail.alpha = trail.alpha - delta_time * 2
            if trail.alpha <= 0 then
                table.remove(drop.trail, j)
            else
                dl:AddCircleFilled(
                    imgui.ImVec2(trail.x, trail.y),
                    trail.radius,
                    imgui.GetColorU32(imgui.ImVec4(drop.color.x, drop.color.y, drop.color.z, trail.alpha * 0.7)),
                    12
                )
            end
        end
        if math.random() < 0.8 then 
            dl:AddCircleFilled(
                imgui.ImVec2(drop.x, drop.y),
                current_radius * 1.5,
                imgui.GetColorU32(drop.glow_color),
                12
            )
        end
        dl:AddCircleFilled(
            imgui.ImVec2(drop.x, drop.y),
            current_radius,
            imgui.GetColorU32(drop.color),
            12
        )
        if drop.y > window_pos.y + window_size.y + 10 then
            table.remove(raindrops, i)
        end
    end
end
```
Пожалуйста, проведи глубокий и всесторонний анализ данного кода. Проанализируй его на наличие синтаксических ошибок, логических ошибок и багов, оценить эффективность алгоритмов и их сложность, проверить соответствие кодирования общепринятым стандартам и стилям программирования, проанализировать читаемость и структуру кода, выявить потенциальные уязвимости с точки зрения безопасности, оценить использование ресурсов и оптимизацию производительности, проверить наличие избыточного или дублирующегося кода, проанализировать обработку исключений и ошибок, а также оценить документацию и комментарии в коде. Предложи конкретные рекомендации по исправлению выявленных проблем, улучшению архитектуры и повышения качества кода в целом.