--- @source amelia.ink
--- @version free

-- ебаная мразь не выключай мне компьютер

local isDebug = false

local found = function (lib)
    if not require (lib) then
        assert (false, 'Need Subscribe to ' .. lib .. ' in Workshop')
    end

    return require (lib)
end

local library = {
    antiaim_funcs = found ('gamesense/antiaim_funcs'),
    base64 =        found ('gamesense/base64'),
    bit =           require ('bit'),
    csgo_weapons =  found ('gamesense/csgo_weapons'),
    entity =        found('gamesense/entity'),
    vector =        require ('vector')
}

local ffi = require 'ffi' or assert (false, 'Allow Unsafe Scripts!')
local ffi_string, ffi_new, ffi_cdef, ffi_typeof, ffi_cast = ffi.string, ffi.new, ffi.cdef, ffi.typeof, ffi.cast

local client_current_threat, color_log, client_draw_text, client_latency, client_set_clan_tag, client_log, client_timestamp, client_userid_to_entindex, client_trace_line, client_set_event_callback, client_screen_size, client_trace_bullet, client_color_log, client_system_time, client_delay_call, client_visible, client_exec, client_eye_position, client_set_cvar, client_scale_damage, client_draw_hitboxes, client_get_cvar, client_camera_angles, client_draw_debug_text, client_random_int, client_random_float, client_create_interface, client_find_signature = client.current_threat, client.color_log, client.draw_text, client.latency, client.set_clan_tag, client.log, client.timestamp, client.userid_to_entindex, client.trace_line, client.set_event_callback, client.screen_size, client.trace_bullet, client.color_log, client.system_time, client.delay_call, client.visible, client.exec, client.eye_position, client.set_cvar, client.scale_damage, client.draw_hitboxes, client.get_cvar, client.camera_angles, client.draw_debug_text, client.random_int, client.random_float, client.create_interface, client.find_signature
local entity_get_origin, entity_get_esp_data, entity_get_player_resource, entity_get_local_player, entity_is_enemy, entity_get_bounding_box, entity_is_dormant, entity_get_steam64, entity_get_player_name, entity_hitbox_position, entity_get_game_rules, entity_get_all, entity_set_prop, entity_is_alive, entity_get_player_weapon, entity_get_prop, entity_get_players, entity_get_classname = entity.get_origin, entity.get_esp_data, entity.get_player_resource, entity.get_local_player, entity.is_enemy, entity.get_bounding_box, entity.is_dormant, entity.get_steam64, entity.get_player_name, entity.hitbox_position, entity.get_game_rules, entity.get_all, entity.set_prop, entity.is_alive, entity.get_player_weapon, entity.get_prop, entity.get_players, entity.get_classname
local globals_realtime, globals_absoluteframetime, globals_tickcount, globals_lastoutgoingcommand, globals_curtime, globals_mapname, globals_tickinterval, globals_framecount, globals_frametime, globals_maxplayers = globals.realtime, globals.absoluteframetime, globals.tickcount, globals.lastoutgoingcommand, globals.curtime, globals.mapname, globals.tickinterval, globals.framecount, globals.frametime, globals.maxplayers
local ui_type, ui_mouse_position, ui_new_slider, ui_new_combobox, ui_reference, ui_is_menu_open, ui_set_visible, ui_new_textbox, ui_new_color_picker, ui_set_callback, ui_set, ui_new_checkbox, ui_new_hotkey, ui_new_button, ui_new_multiselect, ui_get, ui_update, ui_new_label = ui.type, ui.mouse_position, ui.new_slider, ui.new_combobox, ui.reference, ui.is_menu_open, ui.set_visible, ui.new_textbox, ui.new_color_picker, ui.set_callback, ui.set, ui.new_checkbox, ui.new_hotkey, ui.new_button, ui.new_multiselect, ui.get, ui.update, ui.new_label
local renderer_circle_outline, renderer_rectangle, renderer_gradient, renderer_circle, renderer_text, renderer_line, renderer_measure_text, renderer_indicator, renderer_world_to_screen, renderer_triangle = renderer.circle_outline, renderer.rectangle, renderer.gradient, renderer.circle, renderer.text, renderer.line, renderer.measure_text, renderer.indicator, renderer.world_to_screen, renderer.triangle
local math_ceil, math_tan, math_cos, math_sinh, math_pi, math_max, math_atan2, math_floor, math_sqrt, math_deg, math_atan, math_fmod, math_acos, math_pow, math_abs, math_min, math_sin, math_log, math_exp, math_cosh, math_asin, math_rad, math_random = math.ceil, math.tan, math.cos, math.sinh, math.pi, math.max, math.atan2, math.floor, math.sqrt, math.deg, math.atan, math.fmod, math.acos, math.pow, math.abs, math.min, math.sin, math.log, math.exp, math.cosh, math.asin, math.rad, math.random
local table_sort, table_remove, table_concat, table_insert = table.sort, table.remove, table.concat, table.insert
local string_find, string_format, string_gsub, string_len, string_gmatch, string_match, string_reverse, string_upper, string_lower, string_sub = string.find, string.format, string.gsub, string.len, string.gmatch, string.match, string.reverse, string.upper, string.lower, string.sub
local ipairs, assert, pairs, next, tostring, tonumber, setmetatable, unpack, type, getmetatable, pcall, error, toticks = ipairs, assert, pairs, next, tostring, tonumber, setmetatable, unpack, type, getmetatable, pcall, error, toticks
local vtable_bind = vtable_bind

local bit_lshift, bit_band = library.bit.lshift, library.bit.band

local lua = {}
local defines = {}
local conditional_antiaims = {}
local antiaim_on_use = {}
local manual_antiaims = {}

local reference = {
    RAGE = {
        aimbot = {
            min_damage = ui_reference('RAGE', 'Aimbot', 'Minimum damage'),
            min_damage_override = {ui_reference('RAGE', 'Aimbot', 'Minimum damage override')},
            force_safe_point = ui_reference('RAGE', 'Aimbot', 'Force safe point'),
            force_body_aim = ui_reference('RAGE', 'Aimbot', 'Force body aim'),
            double_tap = { ui_reference('RAGE', 'Aimbot', 'Double tap') },
        },

        other = {
            quick_peek_assist = { ui_reference('RAGE', 'Other', 'Quick peek assist') },
            duck_peek_assist = ui_reference('RAGE', 'Other', 'Duck peek assist'),
        },
    },

    AA = {
        angles = {
            enabled = ui_reference('AA', 'Anti-aimbot angles', 'Enabled'),
            pitch = ui_reference('AA', 'Anti-aimbot angles', 'Pitch'),
            pitch_val = select(2, ui_reference('AA', 'Anti-aimbot angles', 'Pitch')),
            yaw_base = ui_reference('AA', 'Anti-aimbot angles', 'Yaw base'),
            yaw = { ui_reference('AA', 'Anti-aimbot angles', 'Yaw') },
            yaw_jitter = { ui_reference('AA', 'Anti-aimbot angles', 'Yaw jitter') },
            body_yaw = { ui_reference('AA', 'Anti-aimbot angles', 'Body yaw') },
            freestanding_body_yaw = ui_reference('AA', 'Anti-aimbot angles', 'Freestanding body yaw'),
            edge_yaw = ui_reference('AA', 'Anti-aimbot angles', 'Edge yaw'),
            freestanding = { ui_reference('AA', 'Anti-aimbot angles', 'Freestanding') },
            roll = ui_reference('AA', 'Anti-aimbot angles', 'Roll'),
        },

        fakelag = {
            enabled = ui_reference('AA', 'Fake lag', 'Enabled'),
            amount = ui_reference('AA', 'Fake lag', 'Amount'),
            variance = ui_reference('AA', 'Fake lag', 'Variance'),
            limit = ui_reference('AA', 'Fake lag', 'Limit'),
        },

        other = {
            slow_motion = { ui_reference('AA', 'Other', 'Slow motion') },
            leg_movement = ui_reference('AA', 'Other', 'Leg movement'),
            on_shot_antiaim = { ui_reference('AA', 'Other', 'On shot anti-aim') },
            fake_peek = ui_reference('AA', 'Other', 'Fake peek'),
        },
    },

    MISC = {
        clantag = ui_reference('Misc', 'Miscellaneous', 'Clan tag spammer'),
        color = ui_reference('Misc', 'Settings', 'Menu color'),
    },
}

local logistic = {}
local visual_controller = {}
local helpers = {}
local entity_helpers = {}
local animation_breaker = {}
local anti_bruteforce = {}

local hitlogs = {}
local kill_say = {}

defines.colors = {}
defines.colors.menu_r, defines.colors.menu_g, defines.colors.menu_b = ui_get(reference.MISC.color)

defines.convert_color = function(redArg, greenArg, blueArg)
    return string_format('\a' .. '%.2x%.2x%.2xFF', redArg, greenArg, blueArg)
end

defines.colors.menu = defines.convert_color(defines.colors.menu_r, defines.colors.menu_g, defines.colors.menu_b)

defines.colors.default = '\aFFFFFFB2'
defines.lua_prefix =     'Ame'..defines.colors.menu..'lia\a323232FF ~ \aFFFFFFB2'

defines.hitgroups=       { 'generic', 'head', 'chest', 'stomach', 'left arm', 'right arm', 'left leg', 'right leg', 'neck', '?', 'gear' }
defines.weapon_to_verb = { knife = 'Knifed', hegrenade = 'Naded', inferno = 'Burned' }
defines.weapon_to_kill = { knife = 'knife', hegrenade = 'nade', inferno = 'burn' }

defines.screen_size = client_screen_size()

defines.cvars = {}

do  -- CVAR List
    defines.cvars.sv_maxusrcmdprocessticks = client_get_cvar("sv_maxusrcmdprocessticks")
    defines.cvars.sv_maxunlag =              client_get_cvar("sv_maxunlag")
    defines.cvars.sv_clockcorrection_msecs = client_get_cvar("sv_clockcorrection_msecs")

    defines.cvars.sv_client_min_interp_ratio = client_get_cvar("sv_client_min_interp_ratio")
    defines.cvars.sv_client_max_interp_ratio = client_get_cvar("sv_client_max_interp_ratio")
    defines.cvars.sv_client_cmdrate_difference=client_get_cvar("sv_client_cmdrate_difference")

    defines.cvars.sv_maxcmdrate =    client_get_cvar("sv_maxcmdrate")
    defines.cvars.sv_maxrate =       client_get_cvar("sv_maxrate") -- 0
    defines.cvars.sv_minrate =       client_get_cvar("sv_minrate") -- 16000
    defines.cvars.sv_maxupdaterate = client_get_cvar("sv_maxupdaterate") --64
    defines.cvars.sv_minupdaterate = client_get_cvar("sv_minupdaterate") -- 64
end

do  --Conditional List
    conditional_antiaims.adress = {
    IN_ATTACK            =  bit_lshift(1, 0), -- Fire weapon
    IN_JUMP                =bit_lshift(1, 1), -- Jump
    IN_DUCK                =bit_lshift(1, 2), -- Crouch
    IN_FORWARD            = bit_lshift(1, 3), -- Walk forward
    IN_BACK                =bit_lshift(1, 4), -- Walk backwards
    IN_USE                = bit_lshift(1, 5), -- Use (Defuse bomb, etc...)
    IN_CANCEL            =  bit_lshift(1, 6), -- ??
    IN_LEFT                =bit_lshift(1, 7), -- Walk left
    IN_RIGHT            =   bit_lshift(1, 8), -- Walk right
    IN_MOVELEFT            =bit_lshift(1, 9), -- Alias? (not sure)
    IN_MOVERIGHT        =   bit_lshift(1, 10), -- Alias? (not sure)
    IN_ATTACK2            = bit_lshift(1, 11), -- Secondary fire (Revolver, Glock change fire mode, Famas change fire mode) (not sure)
    IN_RUN                = bit_lshift(1, 12),
    IN_RELOAD            =  bit_lshift(1, 13), -- Reload weapon
    IN_ALT1                =bit_lshift(1, 14),
    IN_ALT2                =bit_lshift(1, 15),
    IN_SCORE            =   bit_lshift(1, 16),
    IN_SPEED            =   bit_lshift(1, 17),
    IN_WALK                =bit_lshift(1, 18), -- Shift
    IN_ZOOM                =bit_lshift(1, 19), -- Zoom weapon (not sure)
    IN_WEAPON1            = bit_lshift(1, 20),
    IN_WEAPON2            = bit_lshift(1, 21),
    IN_BULLRUSH            =bit_lshift(1, 22),

    FL_ONGROUND            =bit_lshift(1, 0),
    FL_DUCKING            = bit_lshift(1, 1),
    FL_WATERJUMP        =   bit_lshift(1, 3),
    FL_ONTRAIN            = bit_lshift(1, 4),
    FL_INRAIN            =  bit_lshift(1, 5),
    FL_FROZEN            =  bit_lshift(1, 6),
    FL_ATCONTROLS       =   bit_lshift(1, 7),
    FL_CLIENT            =  bit_lshift(1, 8),
    FL_FAKECLIENT       =   bit_lshift(1, 9),
    FL_INWATER            = bit_lshift(1, 10)
    }
end

do
    helpers.cvars_saved = {
        sv_maxusrcmdprocessticks = 16,
        sv_maxunlag = 0.500,
        sv_clockcorrection_msecs = 0,
        sv_client_min_interp_ratio = 1,
        sv_client_max_interp_ratio = 2,
        sv_client_cmdrate_difference = 30,
        sv_maxcmdrate = 0,
        sv_maxrate = 0,
        sv_minrate = 16000,
        sv_maxupdaterate = 64,
        sv_minupdaterate = 64
    }
end

local native_GetClientEntity =       vtable_bind('client.dll', 'VClientEntityList003', 3, 'void*(__thiscall*)(void*, int)')

local native_GetClipboardTextCount = vtable_bind("vgui2.dll", "VGUI_System010", 7, "int(__thiscall*)(void*)")
local native_SetClipboardText =      vtable_bind("vgui2.dll", "VGUI_System010", 9,  "void(__thiscall*)(void*, const char*, int)")
local native_GetClipboardText =      vtable_bind("vgui2.dll", "VGUI_System010", 11, "int(__thiscall*)(void*, int, const char*, int)")

local clipboard = {
    get = function ()
        local len = native_GetClipboardTextCount()
        if (len > 0) then
            local char_arr = ffi_typeof("char[?]")(len)
            native_GetClipboardText(0, char_arr, len)
            local text = ffi_string(char_arr, len - 1)
            local suffix = text:find('_amelia')

            if suffix then
                text = text:sub(1, suffix)
            end

            return text
        end
    end,

    set = function (text)
        text = tostring(text)
	    native_SetClipboardText(text, string_len(text))
    end
}

message = function (r, g, b, ...)
    client_color_log(defines.colors.menu_r, defines.colors.menu_g, defines.colors.menu_b, 'amelia\0')
    client_color_log(150, 150, 150, ' ~ \0')
    client_color_log(r, g, b, string_format(...))
end

die = function (...)
    message(255, 145, 145, ...)
    error()
end

breathe = function(offset, multiplier)
    local speed = globals_realtime() * (multiplier or 1.0);
    local factor = speed % math_pi;

    local sin = math_sin(factor + (offset or 0));
    local abs = math_abs(sin);

    return abs
end

hex = function (r, g, b, a)
    return string_format('\a%02X%02X%02X%02X', r, g, b, a or 255)
end

int = function(x)
    return math_floor(x + 0.5)
end

get_curtime = function(offset)
    return globals_curtime() - (offset * globals_tickinterval())
end

lerp = function(x, v, t)
    if type(x) == 'table' then
        return lerp(x[1], v[1], t), lerp(x[2], v[2], t), lerp(x[3], v[3], t), lerp(x[4], v[4], t)
    end

    local delta = v - x

    if type(delta) == 'number' then
        if math_abs(delta) < 0.005 then
            return v
        end
    end

    return delta * t + x
end

lerp_st = function (start, vend, time)
    return start + (vend - start) * time
end

inverse = function (x, v, t)
    if type(x) == 'table' then
        return lerp(x[1], v[1], t), lerp(x[2], v[2], t), lerp(x[3], v[3], t), lerp(x[4], v[4], t)
    end

    local delta = v - x

    if type(delta) == 'number' then
        if math_abs(delta) < 0.005 then
            return v
        end
    end

    return delta * t + x
end

normalize = function(x, min, max)
    local delta = max - min
    while x < min do
        x = x + delta
    end

    while x > max do
        x = x - delta
    end

    return x
end

time_to_ticks = function(t) return math_floor(0.5 + (t / globals_tickinterval())) end

vec_substract = function(a, b) return { a[1] - b[1], a[2] - b[2], a[3] - b[3] } end

vec_lenght = function(x, y) return (x * x + y * y) end

math_normalize = function (ang)
    while (ang > 180.0) do
        ang = ang - 360.0
    end

    while (ang < -180.0) do
        ang = ang + 360.0
    end

    return ang
end

clamp = function(value, min, max)
    return math_max(min, math_min(value, max))
end

clamp_str = function(str, max)
	str = tostring(str)
	if str:len() > max then
	  	str = str:sub(0, max) .. '...'
	end
	return str
end

angle_to_forward = function (angle_x, angle_y)
    local sy = math_sin(math.rad(angle_y))
    local cy = math_cos(math.rad(angle_y))
    local sp = math_sin(math.rad(angle_x))
    local cp = math_cos(math.rad(angle_x))
    return cp * cy, cp * sy, -sp
end

math_in_bounds = function (a1, a2, b)
    return b.x >= a1.x and b.y >= a1.y and b.x <= a2.x and b.y <= a2.y
end

math_round = function (value)
    return math_floor(value + 0.5)
end

math_clamp = function (value, min, max)
    return math_min(max, math_max(min, value))
end

math_percent_to_pix = function (percent, axis)
    if axis:lower() == "x" then
        return library.vector((defines.screen_size.x / 100) * percent, 0)
    end

    if axis:lower() == "y" then
        return library.vector(0, (defines.screen_size.y / 100) * percent)
    end

    return library.vector((defines.screen_size.x / 100) * percent, (defines.screen_size.y / 100) * percent)
end

linear_interpolation = function (start, _end, time)
	return (_end - start) * time + start
end

math_lerp = function (start, _end, time)
    time = time or 0.005
    time = clamp(globals_frametime() * time * 175.0, 0.01, 1.0)

    local a = linear_interpolation(start, _end, time)

    if _end == 0.0 and a < 0.01 and a > -0.01 then
        a = 0.0
    elseif _end == 1.0 and a < 1.01 and a > 0.99 then
        a = 1.0
    end

    return a
end

rotate_point = function (x, y, rot, size)
	return math_cos(math_rad(rot)) * size + x, math_sin(math_rad(rot)) * size + y
end

renderer_arrow_left = function (x, y, r, g, b, a, rotation, size)
	local x0, y0 = rotate_point(x, y, rotation, 65)
	local x1, y1 = rotate_point(x, y, rotation + (size / 3), 55 - (size / 5))
	local x2, y2 = rotate_point(x, y, rotation - (size / 100), 65 - (size / 3))

	renderer_triangle(x0, y0, x1, y1, x2, y2, r, g, b, a)
end

renderer_arrow_right = function (x, y, r, g, b, a, rotation, size)
	local x0, y0 = rotate_point(x, y, rotation, 65)
	local x1, y1 = rotate_point(x, y, rotation + (size / 100), 65 - (size / 3))
	local x2, y2 = rotate_point(x, y, rotation - (size / 3), 55 - (size / 5))

	renderer_triangle(x0, y0, x1, y1, x2, y2, r, g, b, a)
end

math_vector_lerp = function (vecSource, vecDestination, flPercentage)
    return vecSource + (vecDestination - vecSource) * flPercentage
end

get_max_body_yaw = function (player)
	local x,y = entity_get_prop(player, "m_vecVelocity")

	return 58 - 58 * math_sqrt(x ^ 2 + y ^ 2) / 580
end

get_body_yaw = function (player)
	local model_yaw = entity_get_prop(player, "m_angAbsRotation")
	local eye_yaw = entity_get_prop(player, "m_angEyeAngles")

	if model_yaw == nil or eye_yaw == nil then return 0 end

	return normalize(model_yaw - eye_yaw)
end

math_closest_point_on_ray = function (ray_from, ray_to, desired_point)
    local to = desired_point - ray_from
    local direction = ray_to - ray_from
    local ray_length = direction:length()

    direction.x = direction.x / ray_length
    direction.y = direction.y / ray_length
    direction.z = direction.z / ray_length

    local direction_along = direction.x * to.x + direction.y * to.y + direction.z * to.z
    if direction_along < 0 then return ray_from end
    if direction_along > ray_length then return ray_to end

    return library.vector(ray_from.x + direction.x * direction_along, ray_from.y + direction.y * direction_along, ray_from.z + direction.z * direction_along)
end

math_get_distance = function (x1, y1, z1, x2, y2, z2)
    return math_sqrt((x2 - x1)^2 + (y2 - y1)^2 + (z2 - z1)^2)
end

hasFlag = function(espData, flagValue)
    return bit_band(espData.flags, flagValue) == flagValue
end

get_player_movement_direction = function ()
    local local_player = entity_get_local_player()

    if local_player == nil then
        return 0
    end

    local velocity_x = entity_get_prop(local_player, 'm_vecVelocity[0]')
    local yaw =        client_camera_angles()

    local camera_cos = math_cos( math_rad(yaw) )

    if velocity_x < 0 and camera_cos < 0 then     --LEFT
        return 1
    elseif velocity_x > 0 and camera_cos > 0 then --RIGHT
        return -1
    else
        return 0
    end
end


split = function (inputstr, sep)
    if sep == nil then
        sep = "%s"
    end

    local t={}

    for str in string_gmatch(inputstr, "([^"..sep.."]+)") do
        table_insert(t, str)
    end

    return t
end

angle_forward = function(angle)
    local sin_pitch = math_sin(math_rad(angle[1]))
    local cos_pitch = math_cos(math_rad(angle[1]))
    local sin_yaw = math_sin(math_rad(angle[2]))
    local cos_yaw = math_cos(math_rad(angle[2]))

    return {
        cos_pitch * cos_yaw,
        cos_pitch * sin_yaw,
        -sin_pitch
    }
end

calculate_damage = function(weapon_idx, local_origin, target_index)
    local local_player = entity_get_local_player()

    local weapon = library.csgo_weapons[weapon_idx]
    local target_origin = library.vector(entity_get_prop(target_index, "m_vecOrigin"))
    local distance = local_origin:dist(target_origin)
    local weapon_adjust = weapon.damage

    local min_dmg_slider = { ui_reference('rage', 'aimbot', 'minimum damage') }

    local min_dmg = ui_get(min_dmg_slider[1])

    local dmg_after_range = weapon_adjust * math_pow(weapon.range_modifier, distance / 500.0)

    local armor = entity_get_prop(target_index, "m_ArmorValue")

    local armor_ratio = weapon.armor_ratio
    local newdmg = dmg_after_range * (armor_ratio * 1)

    if dmg_after_range - (dmg_after_range * (armor_ratio * 0.5)) * 0.5 > armor then
        newdmg = dmg_after_range - (armor / 0.5)
    end

    local health = entity_get_prop(target_index, "m_iHealth")
    if newdmg > health then
        newdmg = health
    end

    local pitch, yaw = client_camera_angles()
    local fwd = angle_forward({ pitch, yaw, 0 })
    local start_pos = { client_eye_position() }
    local fraction = client_trace_line(local_player, start_pos[1], start_pos[2], start_pos[3], start_pos[1] + (fwd[1] * 8192), start_pos[2] + (fwd[2] * 8192), start_pos[3] + (fwd[3] * 8192))

    local wall_dmg = 0
    if fraction < 1 then
        local end_pos = {
            start_pos[1] + (fwd[1] * (8192 * fraction + 128)),
            start_pos[2] + (fwd[2] * (8192 * fraction + 128)),
            start_pos[3] + (fwd[3] * (8192 * fraction + 128)),
        }

        local ent, dmg = client_trace_bullet(local_player, start_pos[1], start_pos[2], start_pos[3], end_pos[1], end_pos[2], end_pos[3])
        if ent == nil then
            ent = -1
        end
        wall_dmg = dmg or 0
    end

    local actual_dmg = min_dmg < newdmg and newdmg - min_dmg or newdmg

    if wall_dmg <= 0 then
        return actual_dmg
    elseif wall_dmg > 0 then
        return wall_dmg
    else
        return
    end
end

table.find = function(list, value)
    for _, v in pairs(list) do
        if v == value then
            return _
        end
    end
    return false
end

table.contains = function(tbl, val)
    for i=1,#tbl do
        if tbl[i] == val then
            return true
        end
    end
    return false
end

table.length = function(list)
    local length = 0
    for _ in pairs(list) do
        length = length + 1
    end

    return length
end

local animations = {
    data = { },

    process = function (self, name, bool, time)
        if not self.data[name] then
            self.data[name] = 0
        end

        local animation = globals_frametime() * (bool and 1 or -1) * (time or 4)
        self.data[name] = clamp(self.data[name] + animation, 0, 1)
        return self.data[name]
    end,

    lerp = function (self, start, end_, speed, delta)
        if (math_abs(start - end_) < (delta or 0.01)) then
            return end_
        end
        speed = speed or 0.095
        local time = globals_frametime() * (175 * speed)
        return ((end_ - start) * time + start)
    end
}

lua.tab = {
    'General',
    'Anti Aim',
    'Visuals',
    'Miscellaneous',
    'Keybinds',
    'Configs'
}

lua.general = {
    anim_fix = {
        'Landing Pitch',
        'Force Falling',
        'Leg Breaker',
        'Sliding on Slow-Motion'
    },

    le_ideal_tick = {
        'No Packets on Peek',
        'No Choke on Shot'
    }
}

lua.misc = {
    trash = {
        'On Kill',
        'On Death',
        'On Revenge',

        type = {
            'Ru',
            'Eng'
        },
    },
}

lua.builder = {
    hotkey_states = {
        [0] = 'Always on',
        'On hotkey',
        'Toggle',
        'Off hotkey'
    },

    pitch = {
        'Off',
        'Default',
        'Up',
        'Down',
        'Minimal',
        'Random'
    },

    yaw_base = {
        'Local view',
        'At targets'
    },

    yaw = {
        'Off',
        '180',
        'Spin',
        'Static',
        '180 Z',
        'Crosshair',
        'Left/Right'
    },

    yaw_additions = {
        'Based On Tick',
        'Based On Distance',
        'Randomize',
        'Avoid Overlap'
    },

    rand = {
        'Default',
        'Flip'
    },

    aa_overlap = {
        'Fake Pitch',
        'Fake Yaw',
        'Fake Jitter',
        'Fake Body Yaw',
        'Fake Body Angle'
    },

    yaw_jitter = {
        'Off',
        'Offset',
        'Center',
        'Skitter',
        'Random',
        '3 Way',
        '5 Way'
    },

    body_yaw = {
        'Off',
        'Opposite',
        'Jitter',
        'Static'
    },

    team = {
        none = 0,
        spec = 1,
        t    = 2,
        ct   = 3,
    },
}

lua.anti_aims = {
    mode = {
        'SSS GHOUL',
        'Conditional'
    },

    states = {
        'Global',
        'Standing',
        'Moving',
        'Slow-motion',
        'In Air',
        'In Air & Crouching',
        'Is Falling',
        'Is Landing',
        'Crouching',
        'On Brute Force',
        'On Hittable',
        'On Fakelags',
        'On Use'
    },

    utils = {
        'Disable during Warmup',
        'Disable Fake Lags On Exploits',
        'Avoid Backstab',
        'Force Break LC in Air',
        'Defensive Anti-Aim',
        'Edge Yaw on Ctrl',
        'Safe Head'
    },

    static = {
        'Manual Yaw Base',
        'Freestanding'
    }
}

lua.other = {
    os_type = {
        'Default',
        'Switch',
        'Opposite',
        'Randomize'
    },

    fp_utils = {
        'Always',
        'On Manuals'
    }
}

local tabs = {
    general =  lua.tab[1],
    anti_aim = lua.tab[2],
    visuals =  lua.tab[3],
    misc =     lua.tab[4],
    keybinds = lua.tab[5],
    config =   lua.tab[6]
}

local g_drag = {}
g_drag.items = {}
g_drag.target = nil
g_drag.bound = nil

local drag_mt = {}
drag_mt.__index = drag_mt;
local screen = library.vector(client_screen_size())

function drag_mt:get()
    return self.x, self.y, self.w, self.h
end

function drag_mt:set(x, y, w, h)
    if x ~= nil then
        self.x = x
    end

    if y ~= nil then
        self.y = y
    end

    if w ~= nil then
        self.w = w
    end

    if h ~= nil then
        self.h = h
    end
end

function drag_mt:is_hovered()
    local cursor = library.vector(ui_mouse_position())

    if cursor.x < self.x then
        return false
    end

    if cursor.x > self.x + self.w then
        return false
    end

    if cursor.y < self.y then
        return false
    end

    if cursor.y > self.y + self.h then
        return false
    end

    return true
end

g_drag.new = function(x, y, w, h)
    local drag_t = {
        x = x or 0,
        y = y or 0,
        w = w or 130,
        h = h or 20
    }

    table_insert(g_drag.items, drag_t)
    setmetatable(drag_t, drag_mt)
    return drag_t
end

g_drag.get_target = function()
    if not client.key_state(0x01) then
        g_drag.target = nil
        return g_drag.target
    end

    if g_drag.target ~= nil then
        return g_drag.target
    end

    local target
    for _, value in ipairs(g_drag.items) do
        if value:is_hovered() then
            target = value
        end
    end

    if target == nil then
        return
    end

    local cursor = library.vector(ui_mouse_position())
    local pos = library.vector(target.x, target.y)

    g_drag.bound = pos - cursor
    g_drag.target = target
    return target
end

g_drag.paint_ui = function()
    local target = g_drag.get_target()

    if target == nil then
        return
    end

    local cursor = library.vector(ui_mouse_position())
    local new = cursor + g_drag.bound

    target:set(
        clamp(new.x, 0, screen.x - target.w),
        clamp(new.y, 0, screen.y - target.h)
    )
end

local callback = {}
local menu_mt = {}
local menu = {}

if not LPH_OBFUSCATED then
    LPH_NO_VIRTUALIZE = function(...) return ... end
end

local typeof = type

LPH_NO_VIRTUALIZE(function()
    callback.thread = 'main'
    callback.history = {}

    callback.get = function(key, result_only)
        local this = callback.history[key]
        if not this then
            return
        end

        if result_only then
            return unpack(this.m_result)
        end

        return this
    end

    callback.new = function(key, event_name, func)
        local this = {}
        this.m_key = key
        this.m_event_name = event_name
        this.m_func = func
        this.m_result = {}

        local handler = function(...)
            callback.thread = event_name
            this.m_result = { func(...) }
        end

        local protect = function(...)
            local success, result = pcall(handler, ...)

            if success then
                return
            end

            die('|!| callback::new - %s', result)
        end

        client_set_event_callback(event_name, protect)
        this.m_protect = protect

        callback.history[key] = this
        return this
    end

    menu_mt.register_callback = function(self, callback)
        if not callback then
            return false
        end

        if typeof(self) == 'table' then
            self = self.m_reference
        end

        if not self then
            return false
        end

        if menu.binds[self] == nil then
            menu.binds[self] = {}

            local refresh = function(item)
                for k, v in ipairs(menu.binds[self]) do
                    v(item)
                end
            end

            ui_set_callback(self, refresh)
        end

        table_insert(menu.binds[self], callback)
        return true
    end


    menu_mt.get = function(self, refresh)
        if not refresh then
            return unpack(self.m_value)
        end

        local protect = function()
            return { ui_get(self.m_reference) }
        end

        local success, result = pcall(protect)

        if not success then
            return
        end

        return unpack(result)
    end

    menu_mt.set = function(self, ...)
        if pcall(ui_set, self.m_reference, ...) then
            self.m_value = { self:get(true) }
        end
    end

    menu_mt.set_bypass = function(self, ...)
        local args = { ... }

        client_delay_call(-1, function()
            self:set(unpack(args))
        end)
    end

    menu_mt.set_visible = function(self, value)
        if pcall(ui_set_visible, self.m_reference, value) then
            self.m_visible = value
        end
    end

    menu_mt.update = function(self, ...)
        pcall(ui_update, self.m_reference, ...)
    end

    menu_mt.override = function(self, ...)
        pcall(menu.override, self.m_reference, ...)
    end

    menu_mt.add_as_parent = function(self, callback)
        self.m_parent = true

        local this = {}
        this.original = self
        this.callback = callback

        table_insert(menu.parents, this)
        this.idx = #menu.parents
    end

    menu.prod = {}
    menu.binds = {}
    menu.parents = {}
    menu.updates = {}
    menu.history = {}

    menu.list = {};

    menu.override = function(id, ...)
        if menu.history[callback.thread] == nil then
            menu.history[callback.thread] = {}

            local handler = function()
                local dir = menu.history[callback.thread]

                for k, v in pairs(dir) do
                    if v.active then
                        v.active = false;
                        goto skip;
                    end

                    ui_set(k, unpack(v.value));
                    dir[k] = nil;

                    ::skip::
                end
            end

            callback.new('menu::override::' .. callback.thread, callback.thread, handler)
        end

        local args = { ... }

        if #args == 0 then
            return
        end

        if menu.history[callback.thread][id] == nil then
            local item = { };
            local value = { ui.get(id) };

            if ui_type(id) == "hotkey" then
                value = {lua.builder.hotkey_states[value[2]]};
            end

            item.value = value;
            menu.history[callback.thread][id] = item;
        end

        menu.history[callback.thread][id].active = true;
        ui_set(id, ...);
    end

    menu.shutdown = function()
        for k, v in pairs(menu.history) do
            for x, y in pairs(v) do
                if y.backup == nil then
                    goto skip
                end

                ui_set(x, unpack(y.backup))
                y.backup = nil
                ::skip::
            end
        end
    end

    menu.set_visible = function(x, b)
        if typeof(x) == 'table' then
            for k, v in pairs(x) do
                menu.set_visible(v, b)
            end

            return
        end

        ui_set_visible(x, b)
    end

    menu.refresh = function()
        for k, v in pairs(menu.prod) do
            for x, y in pairs(v) do
                local protect = function()
                    local state = true

                    if y.m_parameters.callback ~= nil then
                        state = y.m_parameters.callback()
                    end

                    for k, v in pairs(menu.parents) do
                        if y.m_parameters.bypass then
                            if y.m_parameters.bypass[k] then
                                goto continue
                            end
                        end

                        if y == v.original then
                            break
                        end

                        if not v.callback(y) then
                            state = false
                            break
                        end

                        ::continue::
                    end

                    y:set_visible(state)
                end

                local isSuccess, output = pcall(protect)

                if isSuccess then
                    goto continue
                end

                if isDebug then
                    output = string_format('%s, debug info: group = %s, name = %s', output, y.m_group, y.name)
                end

                die('|!| menu::refresh - %s', output)
                ::continue::
            end
        end
    end

    menu.new = function(group, name, method, arguments, parameters)
        if menu.prod[group] == nil then
            menu.prod[group] = {}
        end

        if menu.prod[group][name] ~= nil then
            die('|!| menu::new - unable to create element with already used arguments: group = %s, name = %s', group, name)
        end

        local this = {}
        this.m_group = group
        this.name = name
        this.m_method = method
        this.m_arguments = arguments
        this.m_parameters = parameters or {}
        this.m_grouped = menu.allow_group
        this.m_visible = true

        setmetatable(this, {
            __index = menu_mt
        })

        local createReference = function()
            this.m_reference = this.m_method(unpack(this.m_arguments))
        end

        local isSuccess, output = pcall(createReference)

        if not isSuccess then
            if isDebug then
                output = f('%s, debug info: group = %s, name = %s', output, group, name)
            end

            die('|!| menu::new - %s', output)
        end

        menu.prod[group][name] = this

        if this.m_method == ui_new_button then
            this:register_callback(this.m_arguments[4])
        end

        local createCallback = function(item)
            local value = { ui_get(item) }
            this.m_value = value
        end

        local protect = function(item)
            pcall(createCallback, item)
            menu.refresh()
        end

        this:register_callback(protect)
        protect(this.m_reference)

        if this.m_parameters.update_per_frame then
            table.insert(menu.updates, this)

            if not callback.get('menu::update_per_frame') then
                callback.new('menu::update_per_frame', 'paint_ui', function()
                    for k, v in pairs(menu.updates) do
                        if v:get(true) == v:get() then
                            goto skip
                        end

                        v:set(v:get(true))
                        menu.refresh()
                        ::skip::
                    end
                end)
            end
        end
        return this
    end

    menu.register_callback = menu_mt.register_callback
    callback.new('menu::shutdown', 'shutdown', menu.shutdown)
end)()

local configs = {
    prefix = 'amelia::',
    suffix = '_amelia',
    key = 'AMELI4vipBCDFGHJKNOPQRSTUVWXYZabcdefghjklmnoqrstuwxyz012356789+/='
}

configs.export = function()
    local slot = {};

    for k, v in pairs(menu.prod) do
        local group = {}

        for x, y in pairs(v) do
            if y.m_parameters.config == false then
                goto skip
            end

            local value = { y:get(true) }

            if #value == 0 then
                goto skip
            end

            group[x] = value
            ::skip::
        end

        if next(group) ~= nil then
            slot[k] = group
        end
    end

    if next(slot) == nil then
        return false
    end

    local config = {
        data = slot,
        user = username or 'unknown',
        date = '12.12.2012',
        build = 'unknown',
    }

    local success, stringify = pcall(json.stringify, config)
    if not success then
        return message(255, 255, 255, 'Failed to stringify configuration.')
    end

    local success, encoded = pcall(library.base64.encode, stringify, configs.key)
    if not success then
        return message(255, 255, 255, 'Failed to encode configuration.')
    end

    return configs.prefix .. encoded .. configs.suffix
end

configs.import = function(s)
    local config = clipboard.get()
    local converted = false;

    if type(s) == 'string' then
        config = s
    end

    local prefix_length = #configs.prefix

    if config:sub(1, prefix_length) ~= configs.prefix then
        return
    end

    if config:find('_amelia') then
        config = config:gsub('_amelia', '')
    end

    config = config:sub(1 + prefix_length)
    local success, decoded = pcall(library.base64.decode, config, configs.key)
    if not success then
        return message(255, 255, 255, 'Failed to decode configuration.')
    end

    local successz, parsed = pcall(json.parse, decoded)
    if not successz then
        return message(255, 255, 255, 'Failed to parse configuration.')
    end

    if parsed.data == nil then
        return
    end

    for k, v in pairs(parsed.data) do
        if menu.prod[k] == nil then
            goto skip
        end

        for x, y in pairs(v) do
            if menu.prod[k][x] == nil then
                goto skip
            end

            local value = y;

            if type(value[1]) == "boolean" and type(value[2]) == "number" then
                menu.prod[k][x]:set(lua.builder.hotkey_states[value[2]]);
                goto skip
            end

            menu.prod[k][x]:set(unpack(value))
            ::skip::
        end

        ::skip::
    end

    return config
end

configs.data_slot = database.read('amelia::data_slot')
configs.load_startup = function()
    if not configs.data_slot then
        return
    end

    client_delay_call(-1, function()
        configs.import(configs.data_slot)
    end)
end

configs.shutdown = function()
    local encoded = configs.export()

    if not encoded then
        return
    end

    database.write('amelia::data_slot', encoded)
end

do
    menu.new('amelia', 'Tab Selection', ui_new_combobox, { 'AA', 'Anti-Aimbot angles', defines.lua_prefix..' Tab Selection', unpack(lua.tab) })
    menu.prod['amelia']['Tab Selection']:add_as_parent(function(self)
        return self.m_group == menu.prod['amelia']['Tab Selection']:get()
    end)
end

do
    menu.new(tabs.general, 'General', ui_new_checkbox, { 'AA', 'Anti-aimbot angles', 'Enable' .. defines.colors.menu .. ' General' })
    menu.prod[ tabs.general ]['General']:add_as_parent(function(self)
        if self.m_group ~= tabs.general then
            return true
        end
        return menu.prod[ tabs.general ]['General']:get()
    end)
end

menu.new(tabs.general, 'Anim Breaker', ui_new_multiselect, { 'AA', 'Anti-aimbot angles', defines.colors.menu .. 'Animation Fix Breaker', unpack(lua.general.anim_fix) })

menu.new(tabs.general, 'Moonwalk Mode', ui_new_checkbox, { 'AA', 'Anti-aimbot angles', 'Moonwalk Mode'})
menu.new(tabs.general, 'Moonwalk In Air', ui_new_checkbox, { 'AA', 'Anti-aimbot angles', 'Moonwalk In Air Mode'})

menu.new(tabs.general, 'Ideal Tick', ui_new_checkbox, { 'AA', 'Anti-aimbot angles', 'Ideal Tick'})
menu.new(tabs.general, 'Ideal Options', ui_new_multiselect, { 'AA', 'Anti-aimbot angles', 'Options', unpack(lua.general.le_ideal_tick) }, {
    config = false,
    callback = function()
        return menu.prod[ tabs.general ]['Ideal Tick']:get()
    end
})

do
    menu.new(tabs.anti_aim, 'Controller', ui_new_checkbox, { 'AA', 'Anti-aimbot angles', 'Enable' .. defines.colors.menu .. ' Anti Aim' })
    menu.prod[ tabs.anti_aim ]['Controller']:add_as_parent(function(self)
        if self.m_group ~= tabs.anti_aim then
            return true
        end
        return menu.prod[ tabs.anti_aim ]['Controller']:get()
    end)
end

menu.new(tabs.anti_aim, 'Functions', ui_new_multiselect, { 'AA', 'Anti-aimbot angles', defines.colors.menu .. 'Anti Aim Utils', unpack(lua.anti_aims.utils) })

menu.new(tabs.anti_aim, 'Static On Manuals', ui_new_multiselect, { 'AA', 'Anti-aimbot angles', 'Static Body Yaw On', unpack(lua.anti_aims.static) })

menu.new(tabs.anti_aim, 'Type', ui_new_combobox, { 'AA', 'Anti-aimbot angles', 'Mode', unpack(lua.anti_aims.mode) })

menu.new(tabs.anti_aim, 'PlayerCondition', ui_new_combobox, { 'AA', 'Anti-aimbot angles', 'Current State', unpack(lua.anti_aims.states) }, {
    config = false,
    callback = function()
        return menu.prod[ tabs.anti_aim ]['Type']:get() == 'Conditional'
    end
})

do
    local spacing = ''

    for key, value in ipairs(lua.anti_aims.states) do
        local is_visible = function ()
            return menu.prod[ tabs.anti_aim ]['Type']:get() == 'Conditional'
            and menu.prod[ tabs.anti_aim ]['PlayerCondition']:get() == value
        end

        if value ~= lua.anti_aims.states[ 1 ] then
            local override = value .. '::override'

            menu.new(tabs.anti_aim, override, ui_new_checkbox, { 'AA', 'Anti-aimbot angles', 'Enable\x20' .. defines.colors.menu .. value }, {
                callback = is_visible
            })

            is_visible = function()
                return menu.prod[ tabs.anti_aim ]['Type']:get() == 'Conditional'
                and menu.prod[ tabs.anti_aim ]['PlayerCondition']:get() == value
                and menu.prod[ tabs.anti_aim ][value .. '::override']:get()
            end
        end

        menu.new(tabs.anti_aim, value .. '::pitch', ui_new_combobox, { 'AA', 'Anti-aimbot angles', 'Pitch' .. spacing, unpack(lua.builder.pitch) }, {
            callback = is_visible
        })

        menu.new(tabs.anti_aim, value .. '::yaw_base', ui_new_combobox, { 'AA', 'Anti-aimbot angles', 'Yaw Base' .. spacing, unpack(lua.builder.yaw_base) }, {
            callback = is_visible
        })

        menu.new(tabs.anti_aim, value .. '::yaw', ui_new_combobox, { 'AA', 'Anti-aimbot angles', 'Yaw' .. spacing, unpack(lua.builder.yaw) }, {
            callback = is_visible
        })

        menu.new(tabs.anti_aim, value .. '::yaw_amount', ui_new_slider, { 'AA', 'Anti-aimbot angles', '\n yaw_amount' .. spacing, -180, 180, 0, true, '°' }, {
            callback = function()
                return is_visible()
                and menu.prod[ tabs.anti_aim ][value .. '::yaw']:get() ~= lua.builder.yaw[1] -- число в списке больше первого
                and menu.prod[ tabs.anti_aim ][value .. '::yaw']:get() ~= lua.builder.yaw[#lua.builder.yaw] -- конечное число в списке
            end
        })

        menu.new(tabs.anti_aim, value .. '::yaw_left', ui_new_slider, { 'AA', 'Anti-aimbot angles', 'Yaw Left' .. spacing, -180, 180, 0, true, '°' }, {
            callback = function()
                return is_visible()
                and menu.prod[ tabs.anti_aim ][value .. '::yaw']:get() == lua.builder.yaw[#lua.builder.yaw]
            end
        })

        menu.new(tabs.anti_aim, value .. '::yaw_right', ui_new_slider, { 'AA', 'Anti-aimbot angles', 'Yaw Right' .. spacing, -180, 180, 0, true, '°' }, {
            callback = function()
                return is_visible()
                and menu.prod[ tabs.anti_aim ][value .. '::yaw']:get() == lua.builder.yaw[#lua.builder.yaw]
            end
        })

        menu.new(tabs.anti_aim, value .. '::os_cond', ui_new_combobox, { 'AA', 'Anti-aimbot angles', 'On shot anti-aim' .. spacing, unpack(lua.other.os_type) }, {
            callback = is_visible
        })

        menu.new(tabs.anti_aim, value .. '::yaw_additions', ui_new_multiselect, { 'AA', 'Anti-aimbot angles', defines.colors.menu .. 'Yaw Additions' .. spacing, unpack(lua.builder.yaw_additions) }, {
            callback = function()
                return is_visible()
                and menu.prod[ tabs.anti_aim ][value .. '::yaw']:get() ~= lua.builder.yaw[1]
            end
        })

        menu.new(tabs.anti_aim, value .. '::yaw_tick_slider', ui_new_slider, { 'AA', 'Anti-aimbot angles', '\n Yaw Tick' .. spacing, 1, 10, 0, true, 't' }, {
            callback = function()
                return is_visible()
                and menu.prod[ tabs.anti_aim ][value .. '::yaw']:get() ~= lua.builder.yaw[1]
                and table.find(menu.prod[ tabs.anti_aim ][value .. '::yaw_additions']:get(), 'Based On Tick')
            end
        })

        menu.new(tabs.anti_aim, value .. '::yaw_randomize', ui_new_combobox, { 'AA', 'Anti-aimbot angles', 'Yaw Randomize' .. spacing, unpack(lua.builder.rand) }, {
            callback = function()
                return is_visible()
                and menu.prod[ tabs.anti_aim ][value .. '::yaw']:get() ~= lua.builder.yaw[1]
                and table.find(menu.prod[ tabs.anti_aim ][value .. '::yaw_additions']:get(), 'Randomize')
            end
        })

        menu.new(tabs.anti_aim, value .. '::yaw_rand_slider', ui_new_slider, { 'AA', 'Anti-aimbot angles', '\n max rand val' .. spacing, -180, 180, 0, true, '°' }, {
            callback = function()
                return is_visible()
                and menu.prod[ tabs.anti_aim ][value .. '::yaw']:get() ~= lua.builder.yaw[1]
                and table.find(menu.prod[ tabs.anti_aim ][value .. '::yaw_additions']:get(), 'Randomize')
            end
        })

        menu.new(tabs.anti_aim, value .. '::avoid_overlap', ui_new_multiselect, { 'AA', 'Anti-aimbot angles', defines.colors.menu .. 'Overlap Type' .. spacing, unpack(lua.builder.aa_overlap) }, {
            callback = function()
                return is_visible()
                and menu.prod[ tabs.anti_aim ][value .. '::yaw']:get() ~= lua.builder.yaw[1]
                and table.find(menu.prod[ tabs.anti_aim ][value .. '::yaw_additions']:get(), 'Avoid Overlap')
            end
        })

        menu.new(tabs.anti_aim, value .. '::yaw_jitter', ui_new_combobox, { 'AA', 'Anti-aimbot angles', 'Yaw Jitter' .. spacing, unpack(lua.builder.yaw_jitter) }, {
            callback = is_visible
        })

        menu.new(tabs.anti_aim, value .. '::yaw_jitter_type', ui_new_combobox, { 'AA', 'Anti-aimbot angles', 'Yaw Jitter Type' .. spacing, { 'Static', 'Switch Min/Max', 'Random' } }, {
            callback = function ()
                return is_visible()
                and menu.prod[ tabs.anti_aim ][value .. '::yaw_jitter']:get() ~= lua.builder.yaw_jitter[ 1 ]
            end
        })

        menu.new(tabs.anti_aim, value .. '::jitter_amount', ui_new_slider, { 'AA', 'Anti-aimbot angles', '\n jitter_amount' .. spacing, -180, 180, 0, true, '°' }, {
            callback = function()
                return is_visible()
                and menu.prod[ tabs.anti_aim ][value .. '::yaw_jitter']:get() ~= lua.builder.yaw_jitter[1]
            end
        })

        menu.new(tabs.anti_aim, value .. '::jitter_amount2', ui_new_slider, { 'AA', 'Anti-aimbot angles', '\n jitter_amount 2' .. spacing, -180, 180, 0, true, '°' }, {
            callback = function()
                return is_visible()
                and menu.prod[ tabs.anti_aim ][value .. '::yaw_jitter']:get() ~= lua.builder.yaw_jitter[ 1 ]
                and menu.prod[ tabs.anti_aim ][value .. '::yaw_jitter_type']:get() ~= 'Static'
            end
        })

        menu.new(tabs.anti_aim, value .. '::body_yaw', ui_new_combobox, { 'AA', 'Anti-aimbot angles', 'Body yaw' .. spacing, unpack(lua.builder.body_yaw) }, {
            callback = is_visible
        })

        menu.new(tabs.anti_aim, value .. '::body_yaw_amount', ui_new_slider, { 'AA', 'Anti-aimbot angles', '\n body_yaw_amount' .. spacing, -180, 180, 0, true, '°' }, {
            callback = function()
                return is_visible()
                and menu.prod[ tabs.anti_aim ][value .. '::body_yaw']:get() ~= lua.builder.body_yaw[1]
            end
        })

        menu.new(tabs.anti_aim, value .. '::freestanding_body_yaw', ui_new_checkbox, { 'AA', 'Anti-aimbot angles', 'Freestanding body yaw' .. spacing, false }, {
            callback = function()
                return is_visible()
                and menu.prod[ tabs.anti_aim ][value .. '::body_yaw']:get() ~= lua.builder.body_yaw[1]
                and menu.prod[ tabs.anti_aim ][value .. '::body_yaw']:get() ~= lua.builder.body_yaw[3]
            end
        })

        spacing = spacing .. '\x20'
    end
end

do
    menu.new(tabs.visuals, 'Visuals', ui_new_checkbox, { 'AA', 'Anti-aimbot angles', 'Enable' .. defines.colors.menu .. ' Visuals' })
    menu.prod[ tabs.visuals ]['Visuals']:add_as_parent(function(self)
        if self.m_group ~= tabs.visuals then
            return true
        end
        return menu.prod[ tabs.visuals ]['Visuals']:get()
    end)
end

menu.new(tabs.visuals, 'Anti Aim Arrow', ui_new_combobox, { 'AA', 'Anti-aimbot angles', 'Anti Aim Arrow', {'Disabled', 'Simple', 'Legacy', 'Modern'} })

menu.new(tabs.visuals, 'Arrow Color 1', ui_new_color_picker, { 'AA', 'Anti-aimbot angles', 'Arrow Background Color', defines.colors.menu_r, defines.colors.menu_g, defines.colors.menu_b, 255  }, {
    callback = function()
        return menu.prod[ tabs.visuals ]['Anti Aim Arrow']:get() ~= 'Disabled'
    end
})

menu.new(tabs.visuals, 'Arrow Color Text', ui_new_label, { 'AA', 'Anti-aimbot angles',  defines.colors.menu .. 'Desync Color' }, {
    callback = function()
        return menu.prod[ tabs.visuals ]['Anti Aim Arrow']:get() == 'Modern'
    end
})

menu.new(tabs.visuals, 'Arrow Color 2', ui_new_color_picker, { 'AA', 'Anti-aimbot angles',  'Desync Color', 225, 225, 225, 255}, {
    callback = function()
        return menu.prod[ tabs.visuals ]['Anti Aim Arrow']:get() == 'Modern'
    end
})

menu.new(tabs.visuals, 'Crosshair Indicators', ui_new_combobox, { 'AA', 'Anti-aimbot angles', 'Crosshair Indicators', {'Disabled', 'Gradient', 'Legacy'} })

menu.new(tabs.visuals, 'Gradient 1', ui_new_color_picker, { 'AA', 'Anti-aimbot angles', 'Background Color', 225, 225, 225, 255 }, {
    callback = function()
        return menu.prod[ tabs.visuals ]['Crosshair Indicators']:get() ~= 'Disabled'
    end
})

menu.new(tabs.visuals, 'Gradient 2 Text', ui_new_label, { 'AA', 'Anti-aimbot angles',  defines.colors.menu .. 'Gradient Color' }, {
    callback = function()
        return menu.prod[ tabs.visuals ]['Crosshair Indicators']:get() == 'Gradient'
    end
})

menu.new(tabs.visuals, 'Gradient 2', ui_new_color_picker, { 'AA', 'Anti-aimbot angles', 'Gradient Color', defines.colors.menu_r, defines.colors.menu_g, defines.colors.menu_b, 255  }, {
    callback = function()
        return menu.prod[ tabs.visuals ]['Crosshair Indicators']:get() == 'Gradient'
    end
})

menu.new(tabs.visuals, 'Logs', ui_new_checkbox, { 'AA', 'Anti-aimbot angles', 'Enable ' .. defines.colors.menu .. 'Logs' })

menu.new(tabs.visuals, 'Events', ui_new_multiselect, { 'AA', 'Anti-aimbot angles', defines.colors.menu .. 'Events', {'Lua Notify', 'Hit', 'Miss'} }, {
    callback = function()
        return menu.prod[ tabs.visuals ]['Logs']:get()
    end
})

menu.new(tabs.visuals, 'Logs Style', ui_new_multiselect, { 'AA', 'Anti-aimbot angles', defines.colors.menu .. 'Style', {'Amelia', 'Console Panel'} }, {
    callback = function()
        return menu.prod[ tabs.visuals ]['Logs']:get()
    end
})

do
    menu.new(tabs.misc, 'Miscellaneous', ui_new_checkbox, { 'AA', 'Anti-aimbot angles', 'Enable' .. defines.colors.menu .. ' Miscellaneous' })
    menu.prod[ tabs.misc ]['Miscellaneous']:add_as_parent(function(self)
        if self.m_group ~= tabs.misc then
            return true
        end
        return menu.prod[ tabs.misc ]['Miscellaneous']:get()
    end)
end

menu.new(tabs.misc, 'Clan Tag Spammer', ui_new_checkbox, { 'AA', 'Anti-aimbot angles', 'Clan Tag Spammer' })
menu.new(tabs.misc, 'Talk *****', ui_new_multiselect, { 'AA', 'Anti-aimbot angles', defines.colors.menu .. 'Talk *****', {'On Kill', 'On Death', 'Revenge'} })
menu.new(tabs.misc, 'Talk ***** Disabler', ui_new_checkbox, { 'AA', 'Anti-aimbot angles', 'Disable During Warmup' })
menu.new(tabs.misc, 'Fast Ladder', ui_new_checkbox, { 'AA', 'Anti-aimbot angles', 'Fast Ladder' })

menu.new(tabs.keybinds, 'Manual Left', ui_new_hotkey, { 'AA', 'Anti-aimbot angles', 'Manual Left' })
menu.new(tabs.keybinds, 'Manual Right', ui_new_hotkey, { 'AA', 'Anti-aimbot angles', 'Manual Right' })
menu.new(tabs.keybinds, 'Manual Forward', ui_new_hotkey, { 'AA', 'Anti-aimbot angles', 'Manual Forward' })
menu.new(tabs.keybinds, 'Freestanding Bound', ui_new_hotkey, { 'AA', 'Anti-aimbot angles', 'Freestanding' })

menu.new(tabs.config, 'DefaultConfig', ui_new_button, { 'AA', 'Anti-aimbot angles', 'Load Default Config', function() end })
menu.new(tabs.config, 'ExportConfig', ui_new_button, { 'AA', 'Anti-aimbot angles', 'Export settings to clipboard', function() end })
menu.new(tabs.config, 'ImportConfig', ui_new_button, { 'AA', 'Anti-aimbot angles', 'Import settings from clipboard', function() end })

--TODO: ДОБАВИТЬ КОНФИГ
menu.prod[ tabs.config ]['DefaultConfig']:register_callback(function ()
    local decoded = configs.import('amelia::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Uj4qHfm5UTZbUj4yVOp6SxBFX1GdXEM1WSR2phzqpghspI4mYfl6aS42T2BdXjNtXSh6VOp6SxBIVSVdZSwzphzqpghypIwdXjNmXjY6HkhdZ09xWSZlZEp6SyMZDEBBXeMMWTpcBeMLYj90U1dmXjY6HkhdZ09nWTNzVTpeHhqeGOMTUTgeTOueK2BtZSGlWS5kHfm5UTZbYj4sV49yXvhgVTpeHhquTOueP13cNj4oVSwdV2F6HkhdZ09xUS5gT2GqWSNhYep6SyMZDEBPXv92DS0tZvhtXfl6aS42T14rX2RsZEp6SxzxFRzqpg0tZjhsVyl6YvhzU1ceHhqePShsWS0dXEBZDEBGX2VmXjY6HkhdZ09qVSVzpfmXDPIzTOueOS3cKShxpEUcK2BtZSGlWS5kHfm5UTZbZvhfW09yXvhgVTpeHhqwTOueOTFcNj4qXvhsVyl6aS42T1whVkKeHhquTOueQ2NdXjNmXjY6HkhdZ09zWSGoT2GqWSNhYep6Sy4ZDEBJXeMpWTNzUSBqVPl6WjhzZvRxT14rX2RsZEp6SyMZDEBJXeMEYkRzVOMvX2BfVPl6X2GbU19sVEp6SxBOUS5gX10majQeTOueOTFcPv4sVvhsVyl6aS42T14rX2RsZEp6SyIxTOueP13cOvhzZv4eXvQ6HkhdZ09nWTNzVTBbZihuVOp6SxBPZv4zWSFeTOueQ1wtZx0rX2NmX136Hj91VTBxWSNhpfmXZiB0VRzqpg9spIdmZiNdUjwhHfm5UTZbZvhfW09yXvhgVTpeHhqwTOueQ2NdXjNmXjY6Hj41X1hgT191VTBqUTAeHhr7bRzqpghspI4mYfl6Uj9gaR95UTYeHhqeQ2NdZvhfphzqpg9spIdmZiNdUjwhHfmeX1N5T2hdZxp6SxBJYiMtY1hzVOBZDEBBXeMMWTp6HkhdZ09dVvNmZvhtXkFeHhrXpgBdY1RgpI9sp4NmU1qeTRzqpg9spIBxZTNhpIVtYjGhHfmuWTNfWEp6SxBIVSVdZSwzphzqpg9sp4RyVPl6WjhzZvRxT14rX2RsZLpeHhquTOueN1wtUj4qHfm5UTZbUS0tZS5zpfmXDP4ZDEBBYxMFUS5gWS5kHfmeX1N5T2hdZ09dXS90XkKeHhqrGf4ZDEBBYxMvUSwqWS5kHfm5UTZbZvhfW09yXvhgVTpeHhqwTOueOTFcNj4qXvhsVyl6Uj9gaR95UTYeHhqeP2MuX2GmZvQeTOueP13cRTGhHfmnWTNzVTBbUS0tZS5zpfmXF4zqpg0tZjhsVyl6X2GbU19sVEp6SxBPZ1hzU1ceTOuePS91WS5kHfm5UTZbZvhfW09yXvhgVTpeHhqwTOueP13cNj4oVSwdV2F6HjVxVSRyZv4sVvhsV09eX1N5T2hdZxp6S2NxZSRZbTzqpjNdZvQeHepwFe3wFe3xFLIxpkz=_amelia')
    if not decoded then
        return
    end

    message(255, 255, 255, 'Succesfully loaded default script settings!')
end)

menu.prod[ tabs.config ]['ExportConfig']:register_callback(function()
    local data = configs.export()
    clipboard.set(data)
end)

menu.prod[ tabs.config ]['ImportConfig']:register_callback(function()
    local decoded = configs.import()
    if not decoded then
        return
    end

    message(255, 255, 255, 'Succesfully imported settings from clipboard!')
end)

entity_helpers.local_player = {}

entity_helpers.local_player.last_time = -1
entity_helpers.local_player.cached = {ptr = nil, index = -1}

entity_helpers.local_player.pointer = function()
    if entity_helpers.local_player.last_time == globals_tickcount() then
        return entity_helpers.local_player.cached.ptr
    end

    entity_helpers.local_player.cached.ptr = entity_get_local_player()

    if entity_helpers.local_player.cached.ptr then
        entity_helpers.local_player.cached.index = client_userid_to_entindex(entity_helpers.local_player.cached.ptr)
    else
        entity_helpers.local_player.cached.index = -1
    end

    entity_helpers.local_player.last_time = globals_tickcount()

    return entity_helpers.local_player.cached.ptr
end

entity_helpers.local_player.index = function()
    entity_helpers.local_player.pointer()

    return entity_helpers.local_player.cached.index
end

local anti_aim = {
    manual_reset = 0,
    manual_yaw = 0,

    manual_items = {
        [ menu.prod[ tabs.keybinds ]['Manual Left'] ] = {
            yaw = 1,
            state = false,
        },

        [ menu.prod[ tabs.keybinds ]['Manual Right'] ] = {
            yaw = 2,
            state = false,
        },

        [ menu.prod[ tabs.keybinds ]['Manual Forward'] ] = {
            yaw = 3,
            state = false,
        },
    },

    manual_degree = {
        -90,
        90,
        180,
        0,
    },

    defensive = 0,

    ground_ticks = 0,
    last_body_yaw = 0,
}

ui_set(menu.prod[ tabs.keybinds ]['Manual Left'].m_reference, 'Toggle')
ui_set(menu.prod[ tabs.keybinds ]['Manual Right'].m_reference, 'Toggle')
ui_set(menu.prod[ tabs.keybinds ]['Manual Forward'].m_reference, 'Toggle')

anti_aim.defens = 0

anti_aim.handle_defensive = function () -- @Credits: Salvatore
    local lp = entity_get_local_player()

    if lp == nil or not entity_is_alive(lp) then
        return
    end

    local m_tick_base = entity_get_prop(lp, 'm_nTickBase')
    local defens = anti_aim.defens

    if math_abs(m_tick_base - defens) > 64 then
        defens = 0
    end

    local until_ticks = 0

    if m_tick_base > defens then
        defens = m_tick_base
    elseif defens > m_tick_base then
        until_ticks = math_min(14, math_max(0, defens-m_tick_base-1))
    end

    if defens > 0 then
        anti_aim.defensive = until_ticks;
        return;
    end
end

conditional_antiaims.vulnerable_ticks = 0

anti_aim.is_crouching = function (c)
    local local_player = entity_get_local_player()
    local flags = entity_get_prop(local_player, "m_fFlags")
    local is_crouching = bit_band(flags, conditional_antiaims.adress.FL_DUCKING) ~= 0
    local is_fd = ui_get(reference.RAGE.other.duck_peek_assist)
    local on_ground = bit_band(flags, conditional_antiaims.adress.FL_ONGROUND) ~= 0 and c.in_jump == 0
    if on_ground and (is_crouching or is_fd) then
        return true
    else
        return false
    end
end

anti_aim.is_uncrouching = function (c)
    local local_player = entity_get_local_player()
    local duck_amount = entity_get_prop(local_player, "m_flDuckAmount")
    local duck_diff = duck_amount - conditional_antiaims.last_duck_amount
    conditional_antiaims.last_duck_amount = duck_amount

    if duck_diff < 0 then
        return true
    else
        return false
    end
end

anti_aim.air_duck = function (c)
    local local_player = entity_get_local_player()
    local flags = entity_get_prop(local_player, "m_fFlags")

    local on_ground = bit_band(flags, conditional_antiaims.adress.FL_ONGROUND) ~= 0 or c.in_jump == 0

    local inair = bit_band(flags, 1 ) == 0 or c.in_jump == 1

    if not on_ground and inair and c.in_duck == 1 then
        return true
    else
        return false
    end
end

anti_aim.is_air = function (c)
    local local_player = entity_get_local_player()
    local flags = entity_get_prop(local_player, "m_fFlags")
    local on_ground = bit_band(flags, conditional_antiaims.adress.FL_ONGROUND) ~= 0 or c.in_jump == 0
    local inair = bit_band(flags, 1 ) == 0 or c.in_jump == 1
    if not on_ground and inair then
        return true
    else
        return false
    end
end

local wpn_ignored = {
	'CKnife',
	'CWeaponTaser',
	'CC4',
	'CHEGrenade',
	'CSmokeGrenade',
	'CMolotovGrenade',
	'CSensorGrenade',
	'CFlashbang',
	'CDecoyGrenade',
	'CIncendiaryGrenade'
}

anti_aim.is_hit = function (c)
    local local_player = entity_get_local_player()

    if local_player == nil then
        return
    end

    if not entity_is_alive(local_player) then
        return
    end

    local local_origin = library.vector(entity_get_prop(local_player, "m_vecAbsOrigin"))

    local players = entity_get_players(true)

    if #players == nil or #players == 0 then
        return
    end

    local weapon = entity_get_player_weapon(local_player)

    if weapon == nil or table.contains(wpn_ignored, entity_get_classname(weapon)) then
        return
    end

    local weapon_idx = entity_get_prop(weapon, "m_iItemDefinitionIndex")

    local espData
    local newdmg

    for i=1, #players do
        local entindex = players[i]

        newdmg = calculate_damage(weapon_idx, local_origin, entindex)
        espData = entity_get_esp_data(entindex)
    end

    local scan = entity_get_prop (local_player, 'm_iHealth')

    if hasFlag(espData, 2048) and newdmg >= scan then
        return true
    else
        return false
    end
end

animation_breaker.cvars = {
    ground_ticks = 0,
    end_time = 0
}

anti_aim.is_falling = function (c)
    local local_player = entity_get_local_player()
    local flags = entity_get_prop(local_player, "m_fFlags")
    local on_ground = bit_band(flags, conditional_antiaims.adress.FL_ONGROUND) ~= 0 and c.in_jump == 0
    local inair = bit_band(flags, 1 ) == 0 and c.in_jump == 1

    local on_ground2 = bit_band(flags, 1)

    if on_ground2 == 1 then
        animation_breaker.cvars.ground_ticks = animation_breaker.cvars.ground_ticks + 1
    else
        animation_breaker.cvars.ground_ticks = 0
        animation_breaker.cvars.end_time = globals_curtime() + 0.3
    end

    local land = animation_breaker.cvars.ground_ticks > ui_get(reference.AA.fakelag.limit)+1 and animation_breaker.cvars.end_time  > globals_curtime()

    if entity_get_prop(local_player, "m_MoveType") == 9 then
        return
    end

    if not on_ground and not inair and not land then
        return true
    else
        return false
    end
end

anti_aim.is_landing = function (c)
    local local_player = entity_get_local_player()
    local flags = entity_get_prop(local_player, "m_fFlags")
    local on_ground = bit_band(flags, 1)

    if on_ground == 1 then
        animation_breaker.cvars.ground_ticks = animation_breaker.cvars.ground_ticks + 1
    else
        animation_breaker.cvars.ground_ticks = 0
        animation_breaker.cvars.end_time = globals_curtime() + 0.3
    end

    local land = animation_breaker.cvars.ground_ticks > ui_get(reference.AA.fakelag.limit)+1 and animation_breaker.cvars.end_time  > globals_curtime()

    if land then
        return true
    else
        return false
    end
end

anti_aim.is_slow = function()
    local on_slowwalk = ui_get(reference.AA.other.slow_motion[1]) and ui_get(reference.AA.other.slow_motion[2])
    if on_slowwalk then
        return true
    else
        return false
    end
end

anti_aim.is_moving = function (c)
    local local_player = entity_get_local_player()
    local flags = entity_get_prop(local_player, "m_fFlags")
    local is_crouching = bit_band(flags, conditional_antiaims.adress.FL_DUCKING) ~= 0
    local on_ground = bit_band(flags, conditional_antiaims.adress.FL_ONGROUND) ~= 0 and c.in_jump == 0
    local vx, vy, vz = entity_get_prop(entity_get_local_player(), "m_vecVelocity")
    local on_still = math_sqrt(vx ^ 2 + vy ^ 2) < 2
    if not on_still and on_ground and not is_crouching then
        return true
    else
        return false
    end
end

anti_aim.is_standing = function(c)
    local local_player = entity_get_local_player()
    local flags = entity_get_prop(local_player, "m_fFlags")
    local on_ground = bit_band(flags, conditional_antiaims.adress.FL_ONGROUND) ~= 0 and c.in_jump == 0
    local vx, vy, vz = entity_get_prop(entity_get_local_player(), "m_vecVelocity")
    local on_still = math_sqrt(vx ^ 2 + vy ^ 2) < 2
    if on_still and on_ground then
        return true
    else
        return false
    end
end

anti_aim.is_fl = function(c)
    local local_player = entity_get_local_player()
    local vx, vy, vz = entity_get_prop(local_player, "m_vecVelocity")
    local is_os = ui_get(reference.AA.other.on_shot_antiaim[1]) and ui_get(reference.AA.other.on_shot_antiaim[2])
    local is_dt = ui_get(reference.RAGE.aimbot.double_tap[1]) and ui_get(reference.RAGE.aimbot.double_tap[2])
    local on_still = math_sqrt(vx ^ 2 + vy ^ 2) < 2
    if not is_dt and not is_os and not on_still then
        return true
    else
        return false
    end
end

visual_controller.helpers = {
    easeInOut = function(self, t)
        return (t > 0.5) and 4*((t-1)^3)+1 or 4*t^3;
    end,

    clamp = function(self, val, lower, upper)
        assert(val and lower and upper, "not very useful error message here")
        if lower > upper then lower, upper = upper, lower end -- swap if boundaries supplied the wrong way
        return math_max(lower, math_min(upper, val))
    end,

    split = function(self, inputstr, sep)
        if sep == nil then
            sep = "%s"
        end
        local t={}
        for str in string.gmatch(inputstr, "([^"..sep.."]+)") do
            table_insert(t, str)
        end
        return t
    end,

    rgba_to_hex = function(self, r, g, b, a)
      return library.bit.tohex(
        (math_floor(r + 0.5) * 16777216) +
        (math_floor(g + 0.5) * 65536) +
        (math_floor(b + 0.5) * 256) +
        (math_floor(a + 0.5))
      )
    end,

    hex_to_rgba = function(self, hex)
    local color = tonumber(hex, 16)

    return
    math_floor(color / 16777216) % 256,
    math_floor(color / 65536) % 256,
    math_floor(color / 256) % 256,
    color % 256
    end,

    color_text = function(self, string, r, g, b, a)
        local accent = "\a" .. self:rgba_to_hex(r, g, b, a)
        local white = "\a" .. self:rgba_to_hex(255, 255, 255, a)

        local str = ""
        for i, s in ipairs(self:split(string, "$")) do
            str = str .. (i % 2 ==( string:sub(1, 1) == "$" and 0 or 1) and white or accent) .. s
        end

        return str
    end
}

visual_controller.notfy = {
    rec = function(self, x, y, w, h, radius, color)
        radius = math.min(x/2, y/2, radius)
        local r, g, b, a = unpack(color)
        renderer_rectangle(x, y + radius, w, h - radius*2, r, g, b, a)
        renderer_rectangle(x + radius, y, w - radius*2, radius, r, g, b, a)
        renderer_rectangle(x + radius, y + h - radius, w - radius*2, radius, r, g, b, a)
        renderer_circle(x + radius, y + radius, r, g, b, a, radius, 180, 0.25)
        renderer_circle(x - radius + w, y + radius, r, g, b, a, radius, 90, 0.25)
        renderer_circle(x - radius + w, y - radius + h, r, g, b, a, radius, 0, 0.25)
        renderer_circle(x + radius, y - radius + h, r, g, b, a, radius, -90, 0.25)
    end,

    rec_outline = function(self, x, y, w, h, radius, thickness, color)
        radius = math.min(w/2, h/2, radius)
        local r, g, b, a = unpack(color)
        if radius == 1 then
            renderer_rectangle(x, y, w, thickness, r, g, b, a)
            renderer_rectangle(x, y + h - thickness, w , thickness, r, g, b, a)
        else
            renderer_rectangle(x + radius, y, w - radius*2, thickness, r, g, b, a)
            renderer_rectangle(x + radius, y + h - thickness, w - radius*2, thickness, r, g, b, a)
            renderer_rectangle(x, y + radius, thickness, h - radius*2, r, g, b, a)
            renderer_rectangle(x + w - thickness, y + radius, thickness, h - radius*2, r, g, b, a)
            renderer_circle_outline(x + radius, y + radius, r, g, b, a, radius, 180, 0.25, thickness)
            renderer_circle_outline(x + radius, y + h - radius, r, g, b, a, radius, 90, 0.25, thickness)
            renderer_circle_outline(x + w - radius, y + radius, r, g, b, a, radius, -90, 0.25, thickness)
            renderer_circle_outline(x + w - radius, y + h - radius, r, g, b, a, radius, 0, 0.25, thickness)
        end
    end,

    glow_module = function(self, x, y, w, h, width, rounding, accent, accent_inner)
        local thickness = 1
        local offset = 1
        local r, g, b, a = unpack(accent)
        if accent_inner then
            self:rec(x , y, w, h + 1, rounding, accent_inner)
            --renderer.blur(x , y, w, h)
            --m_render.rec_outline(x + width*thickness - width*thickness, y + width*thickness - width*thickness, w - width*thickness*2 + width*thickness*2, h - width*thickness*2 + width*thickness*2, color(r, g, b, 255), rounding, thickness)
        end
        for k = 0, width do
            if a * (k/width)^(1) > 5 then
                local accent = {r, g, b, a * (k/width)^(2)}
                self:rec_outline(x + (k - width - offset)*thickness, y + (k - width - offset) * thickness, w - (k - width - offset)*thickness*2, h + 1 - (k - width - offset)*thickness*2, rounding + thickness * (width - k + offset), thickness, accent)
            end
        end
    end
}

visual_controller.notifications = {
    anim_time = 0.45,
    max_notifs = 4,
    data = {},

    new = function(self, timeout, string, r, g, b)
        table_insert(self.data, {
            time = globals_curtime(),
            string = string,
            color = {r, g, b, 255},
            fraction = 0,
            timeout = timeout
        })
        local time = timeout
        for i = #self.data, 1, -1 do
            local notif = self.data[i]
            if #self.data - i + 1 > self.max_notifs and notif.time + time - globals_curtime() > 0 then
                notif.time = globals_curtime() - time
            end
        end
    end,

    render = function(self)
        local x, y = client_screen_size()
        local to_remove = {}
        local offset = 0

        if not menu.prod[ tabs.visuals ]['Visuals']:get() then
            return
        end

        if not menu.prod[ tabs.visuals ]['Logs']:get() then
            return
        end

        if not table.find(menu.prod[tabs.visuals]['Events']:get(), 'Lua Notify') then
            return
        end

        if not table.find(menu.prod[tabs.visuals]['Logs Style']:get(), 'Amelia') then
            return
        end

        for i = 1, #self.data do
            local notif = self.data[i]

            local data = {rounding = 3, size = 4, glow = 3, time = notif.timeout}

            if notif.time + data.time - globals_curtime() > 0 then
                notif.fraction = visual_controller.helpers:clamp(notif.fraction + globals_frametime() / self.anim_time, 0, 1)
            else
                notif.fraction = visual_controller.helpers:clamp(notif.fraction - globals_frametime() / self.anim_time, 0, 1)
            end

            if notif.fraction <= 0 and notif.time + data.time - globals_curtime() <= 0 then
                table_insert(to_remove, i)
            end
            local fraction = visual_controller.helpers:easeInOut(notif.fraction)

            local r, g, b, a = unpack(notif.color)
            local string = visual_controller.helpers:color_text(notif.string, r, g, b, a * fraction)

            local strw, strh = renderer_measure_text("", string)
            local strw2 = renderer_measure_text("c", " amelia » ")

            local paddingx, paddingy = 7, data.size
            data.rounding = math_ceil(data.rounding/10 * (strh + paddingy*2)/2)

            offset = offset + (strh + paddingy*2 + 	math_sqrt(data.glow/10)*10 + 5) * fraction

            visual_controller.notfy:glow_module(x/2 - (strw + strw2)/2 - paddingx, y - 100 - strh/2 - paddingy - offset, strw + strw2 + paddingx*2, strh + paddingy*2, data.glow, data.rounding, {r, g, b, 45 * fraction}, {20,20,20,105 * fraction})
            renderer_text(x/2 + strw2/2, y - 100 - offset, 255, 255, 255, 255 * fraction, "c", 0, string..' ')
            renderer_text(x/2 - strw/2, y - 100 - offset, 255, 255, 255, 255 * fraction, "c", 0, visual_controller.helpers:color_text(" $amelia » ", r, g, b, a * fraction))
        end

        for i = #to_remove, 1, -1 do
            table_remove(self.data, to_remove[i])
        end
    end,

    clear = function(self)
        self.data = {}
    end
}

visual_controller.notifications:new(4, "Current lua version: $debug$", 255, 255, 255)

anti_bruteforce.cvar = {
    enable = false,
    status = 'false',
    reset_time = 0,
    timer = 5,
    last_tick_triggered = 0,
    f_dist = 0,
    dist = 65,
    shot_time = 0,
    side = 0,
    last_miss = 0,
    best_angle = 0,
    invert = false,
    can_hit_head = 0,
    can_hit = 0
}

anti_bruteforce.is_teammate = function(entity)
    local local_player = entity_get_local_player()

    if local_player == nil then
        return false
    end

    local local_team = entity_get_prop(local_player, "m_iTeamNum")
    local entity_team = entity_get_prop(entity, "m_iTeamNum")

    if local_team ~= nil and entity_team ~= nil then
        return local_team == entity_team
    end

    return false
end

anti_bruteforce.bullet_impact = function(...)
    local currentTime = globals_curtime()

    if currentTime - anti_bruteforce.cvar.last_miss < 0.1 then
        return
    end

    anti_bruteforce.cvar.last_miss = currentTime

    local args = {...}
    local local_pos = args[3]

    local distance = math_closest_point_on_ray(...):dist(local_pos)

    if distance > anti_bruteforce.cvar.dist then
        return
    end

    anti_bruteforce.cvar.invert = not anti_bruteforce.cvar.invert
    anti_bruteforce.cvar.last_tick_triggered = globals_tickcount()
	anti_bruteforce.cvar.reset_time = globals_realtime() + anti_bruteforce.cvar.timer
end

anti_bruteforce.pre_bullet_impact = function(e)
    if anti_bruteforce.cvar.enable then
        return
    end

    local me = entity_helpers.local_player.pointer()

    if not me or entity_get_prop(me, "m_iHealth") <= 0 then
        anti_bruteforce.cvar.enable = false
        return
    end

    local userid = e.userid

    if not userid then return end

    local player_object = client_userid_to_entindex(userid)

    if not player_object or entity_is_dormant(player_object) or not entity_is_enemy(player_object) or anti_bruteforce.is_teammate(player_object) then
        anti_bruteforce.cvar.enable = false
        return
    end

    local eye_pos_x, eye_pos_y, eye_pos_z = client_eye_position()

    local eye_position = library.vector(eye_pos_x, eye_pos_y, eye_pos_z)

    if not eye_position then
        anti_bruteforce.cvar.enable = false
        return
    end

    --debug('Local eye position:  '..tostring(eye_position))

    local enemy_pos_x, enemy_pos_y, enemy_pos_z = entity_get_prop(player_object, "m_vecOrigin")

    local eye_offset_z = entity_get_prop(player_object, "m_vecViewOffset[2]")

    local eye_x, eye_y, eye_z = enemy_pos_x, enemy_pos_y, enemy_pos_z + eye_offset_z

    local eye_enemy_pos = library.vector(eye_x, eye_y, eye_z)

    if not eye_enemy_pos then
        anti_bruteforce.cvar.enable = false
        return
    end

    --debug('Enemy eye position: '..tostring(eye_enemy_pos))

    local x = e.x or -99999
    local y = e.y or -99999
    local z = e.z or -99999

    if x == -99999 or y == -99999 or z == -99999 then
        return
    end

    local impact_vector = library.vector(x, y, z)

    if impact_vector == nil or not impact_vector then
        return
    end

    --debug('Impact vector position: '..tostring(impact_vector))

    if anti_bruteforce.cvar.last_tick_triggered == globals_tickcount() then
        anti_bruteforce.cvar.enable = false
        return
    end

    anti_bruteforce.cvar.shot_time = globals_realtime()

    local side = 'left'

    if anti_bruteforce.cvar.invert then
        side = 'right'
    else
        side = 'left'
    end

    local trace_result = client_trace_bullet(me, eye_pos_x, eye_pos_y, eye_pos_z, x, y, z, true)
    if trace_result ~= nil then
        anti_bruteforce.cvar.enable = false
        return
    end

    local visible = client_visible(x, y, z)

    if not visible then
        anti_bruteforce.cvar.enable = false
        return
    end

    local name = string_lower(entity_get_player_name(player_object))

    local r,g,b = menu.prod[tabs.visuals]['Gradient 2']:get()

    visual_controller.notifications:new(3, string_format('%s $triggered$ anti-bruteforce: $switched$ to $%s$ side', name, side), r,g,b)

    anti_bruteforce.cvar.enable = true

    anti_bruteforce.bullet_impact(impact_vector, eye_enemy_pos, eye_position)
end

anti_bruteforce.reset = function()
    anti_bruteforce.cvar.enable = false
	anti_bruteforce.cvar.reset_time = 0
	anti_bruteforce.cvar.last_tick_triggered = 0
	anti_bruteforce.cvar.fs_side = 0
	anti_bruteforce.cvar.last_miss = 0
end

anti_bruteforce.work_time = function()
    if anti_bruteforce.cvar.shot_time + 0.34 < globals_realtime() then
		anti_bruteforce.reset()
	end
end

anti_aim.is_brute = function ()
    if anti_bruteforce.cvar.enable == true then
        return true
    else
        return false
    end
end

local jit_c = 1
local last_body_yaw = 0
local ground_ticks = 0

anti_aim.handle_ground = function()
    local lp = entity_get_local_player()
    if not lp then
        return
    end

    local flags = entity_get_prop(lp, 'm_fFlags')
    if not flags then
        return
    end

    if bit_band(flags, 1) == 0 then
        anti_aim.ground_ticks = 0
        conditional_antiaims.vulnerable_ticks = 0
    elseif anti_aim.ground_ticks <= 5 then
        anti_aim.ground_ticks = anti_aim.ground_ticks + 1
    end
end

callback.new('AA INFO', 'setup_command', function (cmd)
    local lp = entity_get_local_player()
    if lp == nil or not entity_is_alive(lp) then
        return
    end

    if entity_get_prop(lp, 'm_hGroundEntity') then
        ground_ticks = ground_ticks + 1
    else
        ground_ticks = 0
    end

    anti_aim.handle_ground()

	if cmd.chokedcommands == 0 then
        jit_c = jit_c + 1
	end
end)

anti_aim.condition = function(c)
    anti_aim.handle_ground()

    if c.in_use == 1 then
        return lua.anti_aims.states[13]
    end

    local lp = entity_get_local_player()
    if not lp then
        return
    end

    local m_flags = entity_get_prop(lp, 'm_fFlags')
    if not m_flags then
        return
    end

    local duck_amount = entity_get_prop(lp, 'm_flDuckAmount')
    if not duck_amount then
        return
    end

    local velocity = library.vector(entity_get_prop(lp, 'm_vecVelocity')):length()
    if not velocity then
        return
    end

    if anti_aim.is_brute() then
        return lua.anti_aims.states[10]
    end

    if anti_aim.is_fl(c) then
        return lua.anti_aims.states[12]
    end

    if anti_aim.is_hit(c) then
        return lua.anti_aims.states[11]
    end

    if anti_aim.is_air(c) then
        return lua.anti_aims.states[anti_aim.air_duck(c) and 6 or 5]
    end

    if anti_aim.is_crouching(c) then
        return lua.anti_aims.states[9]
    end

    if anti_aim.is_falling(c) then
        return lua.anti_aims.states[7]
    end

    if anti_aim.is_landing(c) then
        return lua.anti_aims.states[8]
    end

    if anti_aim.is_moving(c) and not anti_aim.is_slow() then
        return lua.anti_aims.states[3]
    end

    if anti_aim.is_slow() then
        return lua.anti_aims.states[4]
    end

    return lua.anti_aims.states[2]
end

anti_aim.anti_backstab = function(cmd)
    if not table.find(menu.prod[ tabs.anti_aim ]['Functions']:get(), lua.anti_aims.utils[3]) then
        return
    end

    local lp = entity_get_local_player()
    if not lp then
        return
    end

    local eye = library.vector(client_eye_position())

    local target = {
        idx = nil,
        distance = 158,
    }

    local enemies = entity_get_players(true)

    for _, entindex in pairs(enemies) do
        local weapon = entity_get_player_weapon(entindex)
        if not weapon then
            goto skip
        end

        local weapon_name = entity_get_classname(weapon)
        if not weapon_name then
            goto skip
        end

        if weapon_name ~= 'CKnife' then
            goto skip
        end

        local origin = library.vector(entity_get_origin(entindex))
        local distance = eye:dist(origin)

        if distance > target.distance then
            goto skip
        end

        target.idx = entindex
        target.distance = distance
        ::skip::
    end

    if not target.idx then
        return
    end

    local origin = library.vector(entity_get_origin(target.idx))
    local delta = eye - origin
    local angle = library.vector(delta:angles())
    local camera = library.vector(client_camera_angles())
    local yaw = normalize(angle.y - camera.y, -180, 180)

    menu.override(reference.AA.angles.yaw_base, lua.builder.yaw_base[1])
    menu.override(reference.AA.angles.yaw[2], yaw)

    return true
end

anti_aim.handle_manuals = function(c)
    for key, value in pairs(anti_aim.manual_items) do
        local state, m_mode = ui_get(key.m_reference)

        if state == value.state then
            goto skip
        end

        value.state = state

        if m_mode == 1 then
            anti_aim.manual_yaw = state and value.yaw or anti_aim.manual_reset
            goto skip
        end

        if m_mode == 2 then
            if anti_aim.manual_yaw == value.yaw then
                anti_aim.manual_yaw = anti_aim.manual_reset
            else
                anti_aim.manual_yaw = value.yaw
            end
            goto skip
        end

        ::skip::
    end
end

ovp = function()
    local overlap = library.antiaim_funcs.get_overlap()

    -- Проверяем, было ли значение больше 0.48 на предыдущем вызове
    if helpers.prev_value_above_0_48 then
        -- Если да, то возвращаем false и сбрасываем флаг prev_value_above_0_48
        helpers.prev_value_above_0_48 = false
        return false
    elseif overlap > 0.48 then
        -- Если значение больше 0.48, то запоминаем это и возвращаем true
        helpers.prev_value_above_0_48 = true
        return true
    else
        -- Иначе, возвращаем false
        return false
    end
end
anti_aim.preset = {
    -- Stand
    [ lua.anti_aims.states[ 2 ] ] = {

        pitch = lua.builder.pitch[ 2 ],

        yaw = lua.builder.yaw[ 7 ],

        yaw_left = -12,
        yaw_right = 12,

        yaw_jitter = lua.builder.yaw_jitter[ 3 ],
        jitter_amount = 28,

        body_yaw = lua.builder.body_yaw[ 3 ],
        body_yaw_amount = -19,
        },
    -- other
}

anti_aim.step_3 = 1
anti_aim.step_5 = 1
anti_aim.prev_yaw = 0

anti_aim.way_3 = {-1, 0, 1}
anti_aim.way_5 = {-1, -0.5, 0, 0.5, 1}--{-0.25, 0, 1, 0.5, -0.5} --{-1, -0.5, 0, 0.5, 1}--{-1, 0, -0.5, 0.5, 1}  --{0, -0.5, 0.5, 1, -1} --{-1, -0.5, 0, 0.5, 1}

anti_aim.on_warmup = function ()
    if not table.find(menu.prod[ tabs.anti_aim ]['Functions']:get(), lua.anti_aims.utils[1]) then
        return
    end

    if entity_get_prop(entity_get_game_rules(), "m_bWarmupPeriod") == 1 then
        menu.override(reference.AA.angles.yaw[1], lua.builder.yaw[6])
        menu.override(reference.AA.angles.yaw[2], 0)
        menu.override(reference.AA.angles.yaw_jitter[1], lua.builder.yaw_jitter[1])
        menu.override(reference.AA.angles.body_yaw[1], lua.builder.body_yaw[4])
    end
end

anti_aim.on_shot = false

anti_aim.on_aim = function ()
    anti_aim.on_shot = true
end

anti_aim.on_shooting = function()
    if anti_aim.on_shot == true then
        return true
    end
end

anti_aim.handle_preset = function(cmd)
    if menu.prod[ tabs.anti_aim ]['Type']:get() ~= 'Conditional' then
        return
    end

    local lp = entity_get_local_player()
    if not lp then
        return
    end

    local body_yaw = entity_get_prop(lp, 'm_flPoseParameter', 11)

    if cmd.chokedcommands == 0 then
        anti_aim.last_body_yaw = body_yaw * 120 - 60
    end

    local condition = callback.get('antiaim::condition', true)
    if not condition then
        return
    end

    local preset = anti_aim.preset[condition]
    if not preset then
        return
    end

    menu.override(reference.AA.angles.pitch, preset.pitch or lua.builder.pitch[4])
    menu.override(reference.AA.angles.yaw_base, preset.yaw_base or lua.builder.yaw_base[2])

    local yaw = preset.yaw or lua.builder.yaw[2]
    local yaw_amount = preset.yaw_amount or 0

    local jitter = preset.yaw_jitter or lua.builder.yaw_jitter[1]
    local jitter_amount = preset.jitter_amount or 0

    if yaw == lua.builder.yaw[ 7 ] then
        yaw = lua.builder.yaw[ 2 ]

        if anti_aim.last_body_yaw > 0 then
            yaw_amount = preset.yaw_left or 0
        elseif anti_aim.last_body_yaw < 0 then
            yaw_amount = preset.yaw_right or 0
        end

        if jitter == lua.builder.yaw_jitter[3] then
            jitter_amount = int(jitter_amount / 2)

            if anti_aim.last_body_yaw > 0 then
                yaw_amount = yaw_amount - jitter_amount
            elseif anti_aim.last_body_yaw < 0 then
                yaw_amount = yaw_amount + jitter_amount
            end

            jitter = lua.builder.yaw_jitter[1]
            jitter_amount = 0
        end
    end

    if jitter == '3 Way' then
        if cmd.chokedcommands == 0 then
            anti_aim.prev_yaw = jitter_amount * anti_aim.way_3[anti_aim.step_3]

            anti_aim.step_3 = anti_aim.step_3 + 1

            if anti_aim.step_3 > #anti_aim.way_3 then
                anti_aim.step_3 = 1
            end
        end

        jitter = 'Off'
        jitter_amount = 0
        yaw_amount = yaw_amount + anti_aim.prev_yaw
    end

    if jitter == '5 Way' then
        if cmd.chokedcommands == 0 then
            anti_aim.prev_yaw = jitter_amount * anti_aim.way_5[anti_aim.step_5]

            anti_aim.step_5 = anti_aim.step_5 + 1

            if anti_aim.step_5 > #anti_aim.way_5 then
                anti_aim.step_5 = 1
            end
        end

        jitter = 'Off'
        jitter_amount = 0

        yaw_amount = yaw_amount + anti_aim.prev_yaw
    end

    if yaw == lua.builder.yaw[4] then
        local angle = library.vector(client_camera_angles())
        yaw_amount = yaw_amount + angle.y

        yaw_amount = normalize(yaw_amount, -180, 180)
    end

    menu.override(reference.AA.angles.yaw[1], yaw)
    menu.override(reference.AA.angles.yaw[2], normalize(yaw_amount, -180, 180))

    menu.override(reference.AA.angles.yaw_jitter[1], jitter)
    menu.override(reference.AA.angles.yaw_jitter[2], jitter_amount)

    local body_yaw = preset.body_yaw or lua.builder.body_yaw[2]
    local freestanding_body_yaw = preset.freestanding_body_yaw or false

    if body_yaw == lua.builder.body_yaw[3] then
        freestanding_body_yaw = false
    end

    menu.override(reference.AA.angles.body_yaw[1], 'Static')
    menu.override(reference.AA.angles.body_yaw[2], 0)

    menu.override(reference.AA.angles.body_yaw[1], body_yaw)
    menu.override(reference.AA.angles.body_yaw[2], preset.body_yaw_amount or 180)
    menu.override(reference.AA.angles.freestanding_body_yaw, freestanding_body_yaw)

    menu.override(reference.AA.angles.roll, preset.roll or 0)
    return yaw_amount
end

local last_switch

anti_aim.builder = function(c)
    if not menu.prod[ tabs.anti_aim ]['Controller']:get() or menu.prod[ tabs.anti_aim ]['Type']:get() ~= 'Conditional' then
        return
    end

    local lp = entity_get_local_player();
    if not lp then
        return
    end

    local body_yaw = entity_get_prop(lp, 'm_flPoseParameter', 11)

    if c.chokedcommands == 0 then
        anti_aim.last_body_yaw = body_yaw * 120 - 60
    end

    local condition = callback.get('antiaim::condition', true)

    if not condition then
        return
    end

    if not menu.prod[ tabs.anti_aim ][condition .. '::override']:get() then
        condition = lua.anti_aims.states[1]
    end

    menu.override(reference.AA.angles.pitch, menu.prod[ tabs.anti_aim ][ condition .. '::pitch' ]:get())
    menu.override(reference.AA.angles.yaw_base, menu.prod[ tabs.anti_aim ][ condition .. '::yaw_base' ]:get())

    local yaw = menu.prod[ tabs.anti_aim ][ condition .. '::yaw' ]:get()
    local yaw_amount = menu.prod[ tabs.anti_aim ][ condition .. '::yaw_amount' ]:get()

    local yaw_jitter = menu.prod[ tabs.anti_aim ][ condition .. '::yaw_jitter' ]:get()
    local yaw_jitter_amt = menu.prod[ tabs.anti_aim ][ condition .. '::jitter_amount' ]:get()
    local yaw_jitter_amt2 = menu.prod[ tabs.anti_aim ][ condition .. '::jitter_amount2' ]:get()
    local yaw_jitter_type = menu.prod[ tabs.anti_aim ][ condition .. '::yaw_jitter_type' ]:get()

    if yaw_jitter_type == 'Random' then
        if jit_c % 2 == 0 or last_switch == nil then
            last_switch = math_random( menu.prod[ tabs.anti_aim ][ condition .. '::jitter_amount' ]:get(), menu.prod[ tabs.anti_aim ][ condition .. '::jitter_amount2' ]:get())
        end

        yaw_jitter_amt = last_switch
    elseif yaw_jitter_type == 'Switch Min/Max' then
        yaw_jitter_amt = jit_c % 4 > 1 and menu.prod[ tabs.anti_aim ][ condition .. '::jitter_amount' ]:get() or yaw_jitter_amt2
    else
        yaw_jitter_amt = menu.prod[ tabs.anti_aim ][ condition .. '::jitter_amount' ]:get()
    end

    local y_l = menu.prod[ tabs.anti_aim ][ condition .. '::yaw_left' ]:get()
    local y_r = menu.prod[ tabs.anti_aim ][ condition .. '::yaw_right' ]:get()

    if anti_aim.on_shooting() then
        if (menu.prod[tabs.anti_aim][condition .. '::os_cond']:get() == 'Default') or not anti_aim.on_shooting() then
            goto skip_check
        elseif (menu.prod[tabs.anti_aim][condition .. '::os_cond']:get() == 'Switch') then
            menu.override(reference.AA.angles.pitch,  lua.builder.pitch[6])
            menu.override(reference.AA.angles.body_yaw[1],  lua.builder.body_yaw[4])
        elseif (menu.prod[tabs.anti_aim][condition .. '::os_cond']:get() == 'Opposite') then
            menu.override(reference.AA.angles.pitch,  lua.builder.pitch[5])
            menu.override(reference.AA.angles.body_yaw[1],  lua.builder.body_yaw[2])
        elseif (menu.prod[tabs.anti_aim][condition .. '::os_cond']:get() == 'Randomize') then
            menu.override(reference.AA.angles.pitch,  lua.builder.pitch[6])
            menu.override(reference.AA.angles.body_yaw[1],  lua.builder.body_yaw[3])
        end

        anti_aim.on_shot = false
        ::skip_check::
    end

    if table.find(menu.prod[tabs.anti_aim][condition .. '::yaw_additions']:get(), 'Based On Distance') then
        local players = entity_get_players(true)
        local lx, ly, lz = entity_get_prop(entity_get_local_player(), "m_vecOrigin")
        local total_distance = 0
    
        for i = 1, #players do
            local x, y, z = entity_get_prop(players[i], "m_vecOrigin")
            local distance = math_get_distance(lx, ly, lz, x, y, z)
            total_distance = total_distance + distance
        end
    
        local dist = math_floor(total_distance)

        if dist > 350 then
            goto skip_check
        end
    
        if dist ~= 0 then
            yaw_amount = int(yaw_amount / dist)
            --print(dist)
        end
        ::skip_check::
    end

    if table.find(menu.prod[tabs.anti_aim][condition .. '::yaw_additions']:get(), 'Avoid Overlap') then
        if not ovp then
            goto skip_check
        end

        if table.find(menu.prod[tabs.anti_aim][condition .. '::avoid_overlap']:get(), 'Fake Pitch') then
            menu.override(reference.AA.angles.pitch, ovp and lua.builder.pitch[5])
        end

        if table.find(menu.prod[tabs.anti_aim][condition .. '::avoid_overlap']:get(), 'Fake Yaw') then
            yaw_amount = 0
            menu.override(reference.AA.angles.yaw[2], ovp and yaw_amount)
        end

        if table.find(menu.prod[tabs.anti_aim][condition .. '::avoid_overlap']:get(), 'Fake Jitter') then
            yaw_jitter_amt = 0
            yaw_jitter = 'Off'

            menu.override(reference.AA.angles.yaw_jitter[1], ovp and yaw_jitter)
            menu.override(reference.AA.angles.yaw_jitter[2], ovp and yaw_jitter_amt)
        end

        if table.find(menu.prod[tabs.anti_aim][condition .. '::avoid_overlap']:get(), 'Fake Body Yaw') then
            menu.override(reference.AA.angles.body_yaw[1], ovp and lua.builder.body_yaw[1])
        end

        if table.find(menu.prod[tabs.anti_aim][condition .. '::avoid_overlap']:get(), 'Fake Body Angle') then
            menu.override(reference.AA.angles.body_yaw[2], ovp and 0)
        end

        ::skip_check::
    end


    local currentTick = globals_tickcount()

    if yaw == lua.builder.yaw[ 7 ] then
        yaw = lua.builder.yaw[ 2 ]
        yaw_amount = 0
        if table.find(menu.prod[ tabs.anti_aim ][condition .. '::yaw_additions']:get(), 'Based On Tick') then
            if anti_aim.last_body_yaw > 0 then
                yaw_amount = (currentTick % toticks(menu.prod[ tabs.anti_aim ][ condition .. '::yaw_tick_slider' ]:get())) == 1 and y_l or y_r
            elseif anti_aim.last_body_yaw < 0 then
                yaw_amount = (currentTick % toticks(menu.prod[ tabs.anti_aim ][ condition .. '::yaw_tick_slider' ]:get())) == 1 and y_r or y_l
            end
        else
            if anti_aim.last_body_yaw > 0 then
                yaw_amount = menu.prod[ tabs.anti_aim ][ condition .. '::yaw_left' ]:get()
            elseif anti_aim.last_body_yaw < 0 then
                yaw_amount = menu.prod[ tabs.anti_aim ][ condition .. '::yaw_right' ]:get()
            end
        end

        if table.find(menu.prod[tabs.anti_aim][condition .. '::yaw_additions']:get(), 'Randomize') then
            local rand_integr = menu.prod[ tabs.anti_aim ][ condition .. '::yaw_rand_slider' ]:get()

            if (menu.prod[tabs.anti_aim][condition .. '::yaw_randomize']:get() == 'Default') then
                yaw_amount = math_random(yaw_amount, rand_integr)
            elseif (menu.prod[tabs.anti_aim][condition .. '::yaw_randomize']:get() == 'Flip') then
                yaw_amount = client_random_int(yaw_amount, rand_integr)
            end
        end

        if yaw_jitter == 'Center' then
			yaw_jitter_amt = int(yaw_jitter_amt / 2)
			if anti_aim.last_body_yaw > 0 then
				yaw_amount = yaw_amount - yaw_jitter_amt
			elseif anti_aim.last_body_yaw < 0 then
				yaw_amount = yaw_amount + yaw_jitter_amt
			end

			yaw_jitter = 'Off'
			yaw_jitter_amt = 0
		end
    end

    if yaw_jitter == '3 Way' then
        if c.chokedcommands == 0 then
            anti_aim.prev_yaw = yaw_jitter_amt * anti_aim.way_3[anti_aim.step_3]

            anti_aim.step_3 = anti_aim.step_3 + 1

            if anti_aim.step_3 > #anti_aim.way_3 then
                anti_aim.step_3 = 1
            end
        end

        yaw_jitter = 'Off'
        yaw_jitter_amt = 0
        yaw_amount = yaw_amount + anti_aim.prev_yaw
    end

    if yaw_jitter == '5 Way' then
        if c.chokedcommands == 0 then
            anti_aim.prev_yaw = yaw_jitter_amt * anti_aim.way_5[anti_aim.step_5]

            anti_aim.step_5 = anti_aim.step_5 + 1

            if anti_aim.step_5 > #anti_aim.way_5 then
                anti_aim.step_5 = 1
            end
        end

        yaw_jitter = 'Off'
        yaw_jitter_amt = 0

        yaw_amount = yaw_amount + anti_aim.prev_yaw
    end

    menu.override(reference.AA.angles.yaw[1], yaw)
    menu.override(reference.AA.angles.yaw[2], normalize(yaw_amount, -180, 180))
    menu.override(reference.AA.angles.yaw_jitter[1], yaw_jitter)
    menu.override(reference.AA.angles.yaw_jitter[2], yaw_jitter_amt)

    local body_yaw = menu.prod[ tabs.anti_aim ][ condition .. '::body_yaw']:get()
    local freestanding_body_yaw = menu.prod[ tabs.anti_aim ][ condition .. '::freestanding_body_yaw']:get()
    if body_yaw == lua.builder.body_yaw[3] then
        freestanding_body_yaw = false
    end

    ui_set(reference.AA.angles.body_yaw[1], 'Static')
    ui_set(reference.AA.angles.body_yaw[2], 0)

    menu.override(reference.AA.angles.body_yaw[1], body_yaw)
    menu.override(reference.AA.angles.body_yaw[2], menu.prod[ tabs.anti_aim ][ condition .. '::body_yaw_amount']:get())

    menu.override(reference.AA.angles.freestanding_body_yaw, freestanding_body_yaw)
    menu.override(reference.AA.angles.roll, 0)
    return yaw_amount
end

anti_aim.using = function(cmd)
    if not menu.prod[ tabs.anti_aim ]['Controller']:get() then
        return
    end

    if cmd.in_use == 0 then
        return
    end

    local lp = entity_get_local_player()
    if not lp then
        return
    end

    local crouch = entity_get_prop(lp, 'm_flDuckAmount') == 1
    local team = entity_get_prop(lp, 'm_iTeamNum')
    if not team then
        return
    end

    if team == lua.builder.team.t then
        if entity_get_prop(lp, 'm_bInBombZone') == 0 then
            goto skip_check
        end

        local m_weapon = entity_get_player_weapon(lp)
        if not m_weapon then
            goto skip_check
        end

        local name = entity_get_classname(m_weapon)
        if name == 'CC4' then
            return
        end
        ::skip_check::
    elseif team == lua.builder.team.ct then
        local planted_c4 = entity_get_all('CPlantedC4')
        if not planted_c4 then
            goto skip_check
        end

        local origin = library.vector(entity_get_origin(lp))
        if not origin then
            goto skip_check
        end

        local max_distance = crouch and 42.5 or 60

        for _, entity in pairs(planted_c4) do
            local position = library.vector(entity_get_origin(entity))
            if not position then
                goto skip_entity
            end

            local distance = origin:dist(position)
            if distance < max_distance then
                return
            end
            ::skip_entity::
        end
        ::skip_check::
    end

    local camera = library.vector(client_camera_angles())
    local forward = library.vector(angle_to_forward(camera:unpack()))

    local eye = library.vector(client_eye_position())
    local _end = eye + forward * 128

    local fraction, entindex = client_trace_line(lp, eye.x, eye.y, eye.z, _end.x, _end.y, _end.z)

    if fraction ~= 1 then
        if entindex == -1 then
            goto skip_check
        end

        local name = entity_get_classname(entindex)

        if name == 'CWorld' then
            goto skip_check
        end

        if name == 'CFuncBrush' then
            goto skip_check
        end

        if name == 'CCSPlayer' then
            goto skip_check
        end

        if name == 'CHostage' then
            local hostage_origin = library.vector(entity_get_origin(entindex))
            local distance = eye:dist(hostage_origin)
            local max_distance = crouch and 76 or 84

            if distance < max_distance then
                return
            end

            goto skip_check
        end

        if true then
            return
        end

        ::skip_check::
    end

    local interface = callback.get('antiaim::condition')

    if interface then
        interface.recent = {
            lua.anti_aims.states[13]
        }
    end

    if not menu.prod[ tabs.anti_aim ]['Type']:get() == 'Conditional' then
        menu.override(reference.AA.angles.pitch, lua.builder.pitch[1])
        menu.override(reference.AA.angles.yaw_base, lua.builder.yaw_base[1])
        menu.override(reference.AA.angles.yaw[1], lua.builder.yaw[2])
        menu.override(reference.AA.angles.yaw[2], 180)
    end


    cmd.in_use = false
    return true
end

anti_aim.defensive_antiaim = function(cmd)
    if not menu.prod[ tabs.anti_aim ]['Controller']:get() or
        not table.find(menu.prod[ tabs.anti_aim ]['Functions']:get(), 'Defensive Anti-Aim') then
        return
    end


    local condition = callback.get('antiaim::condition', true)
    local side = anti_aim.last_body_yaw
    local camera = get_player_movement_direction ()

    local is_qp = ui_get (reference.RAGE.other.quick_peek_assist[1]) and ui_get (reference.RAGE.other.quick_peek_assist[2])

    if condition == 'Moving' and is_qp then
        if camera == -1 and side > 0 then
            menu.override(reference.AA.angles.pitch, lua.builder.pitch [ 6 ])
            menu.override(reference.AA.angles.yaw_base, lua.builder.yaw_base [ 1 ])
            menu.override(reference.AA.angles.yaw[1], lua.builder.yaw [ 5 ])
            menu.override(reference.AA.angles.yaw[2], -90)
            menu.override(reference.AA.angles.yaw_jitter[1], lua.builder.yaw_jitter[ 1 ])
            menu.override(reference.AA.angles.yaw_jitter[2], 0)
            menu.override(reference.AA.angles.body_yaw[1], lua.builder.body_yaw[ 4 ])
            menu.override(reference.AA.angles.body_yaw[2], 180)
        elseif camera == 1 and side < 0 then
            menu.override(reference.AA.angles.pitch, lua.builder.pitch [ 6 ])
            menu.override(reference.AA.angles.yaw_base, lua.builder.yaw_base [ 1 ])
            menu.override(reference.AA.angles.yaw[1], lua.builder.yaw [ 5 ])
            menu.override(reference.AA.angles.yaw[2], 90)
            menu.override(reference.AA.angles.yaw_jitter[1], lua.builder.yaw_jitter[ 1 ])
            menu.override(reference.AA.angles.yaw_jitter[2], 0)
            menu.override(reference.AA.angles.body_yaw[1], lua.builder.body_yaw[ 4 ])
            menu.override(reference.AA.angles.body_yaw[2], -180)
        end
    elseif condition == 'In Air' or condition == 'In Air & Crouching' then
        if camera == -1 and side > 0 then
            menu.override(reference.AA.angles.pitch, lua.builder.pitch [ 6 ])
            menu.override(reference.AA.angles.yaw_base, lua.builder.yaw_base [ 2 ])
            menu.override(reference.AA.angles.yaw[1], lua.builder.yaw [ 5 ])
            menu.override(reference.AA.angles.yaw[2], -90)
            menu.override(reference.AA.angles.yaw_jitter[1], lua.builder.yaw_jitter[ 4 ])
            menu.override(reference.AA.angles.yaw_jitter[2], 32)
            menu.override(reference.AA.angles.body_yaw[1], lua.builder.body_yaw[ 4 ])
            menu.override(reference.AA.angles.body_yaw[2], 9)
        elseif camera == 1 and side < 0 then
            menu.override(reference.AA.angles.pitch, lua.builder.pitch [ 6 ])
            menu.override(reference.AA.angles.yaw_base, lua.builder.yaw_base [ 2 ])
            menu.override(reference.AA.angles.yaw[1], lua.builder.yaw [ 5 ])
            menu.override(reference.AA.angles.yaw[2], 90)
            menu.override(reference.AA.angles.yaw_jitter[1], lua.builder.yaw_jitter[ 4 ])
            menu.override(reference.AA.angles.yaw_jitter[2], 32)
            menu.override(reference.AA.angles.body_yaw[1], lua.builder.body_yaw[ 4 ])
            menu.override(reference.AA.angles.body_yaw[2], -9)
        elseif camera == 0 or side == 0 then
            menu.override(reference.AA.angles.pitch, lua.builder.pitch [ 6 ])
            menu.override(reference.AA.angles.yaw_base, lua.builder.yaw_base [ 2 ])
            menu.override(reference.AA.angles.yaw[1], lua.builder.yaw [ 5 ])
            menu.override(reference.AA.angles.yaw[2], 0)
            menu.override(reference.AA.angles.yaw_jitter[1], lua.builder.yaw_jitter[ 4 ])
            menu.override(reference.AA.angles.yaw_jitter[2], 32)
            menu.override(reference.AA.angles.body_yaw[1], lua.builder.body_yaw[ 4 ])
            menu.override(reference.AA.angles.body_yaw[2], 34)
        end
    elseif condition == 'Crouching' then
        if camera == 0 or side == 0 then
            menu.override(reference.AA.angles.pitch, lua.builder.pitch [ 6 ])
            menu.override(reference.AA.angles.yaw_base, lua.builder.yaw_base [ 1 ])
            menu.override(reference.AA.angles.yaw[1], lua.builder.yaw [ 5 ])
            menu.override(reference.AA.angles.yaw[2], 0)
            menu.override(reference.AA.angles.yaw_jitter[1], lua.builder.yaw_jitter[ 4 ])
            menu.override(reference.AA.angles.yaw_jitter[2], 32)
            menu.override(reference.AA.angles.body_yaw[1], lua.builder.body_yaw[ 4 ])
            menu.override(reference.AA.angles.body_yaw[2], 34)
        end
    else
        goto skip_check
    end

    ::skip_check::
end


anti_aim.dt_charge = function()
    local target = entity_get_local_player()
    if not target then
        return
    end

    local weapon = entity_get_player_weapon(target)

    if target == nil or weapon == nil then
        return false
    end

    if get_curtime(16) < entity_get_prop(target, 'm_flNextAttack') then
        return false
    end

    if get_curtime(0) < entity_get_prop(weapon, 'm_flNextPrimaryAttack') then
        return false
    end

    return true
end

helpers.is_nade = function()
    local local_player = entity_get_local_player()
    local weapon = entity_get_player_weapon(local_player)

    if weapon ~= nil then
        local weapon_class = entity_get_classname(weapon)

        local nades = {'CIncendiaryGrenade', 'CMolotovGrenade', 'CHEGrenade', 'CSmokeGrenade', 'CFlashbang', 'CDecoyGrenade'}
        for _, nade in ipairs(nades) do
            if weapon_class == nade then
                return true
            end
        end
    end

    return false
end

helpers.is_heavy_pistol = function()
    local local_player = entity_get_local_player()
    local weapon = entity_get_player_weapon(local_player)

    if weapon ~= nil then
        local weapon_class = entity_get_classname(weapon)
        if weapon_class == "CDEagle" then
            return true
        end
    end

    return false
end

helpers.is_knife = function()
    local local_player = entity_get_local_player()
    local weapon = entity_get_player_weapon(local_player)

    if weapon ~= nil then
        local weapon_class = entity_get_classname(weapon)

        if weapon_class == "CKnife" then
            return true
        end
    end

    return false
end

helpers.is_taser = function()
    local local_player = entity_get_local_player()
    local weapon = entity_get_player_weapon(local_player)

    if weapon ~= nil then
        local weapon_class = entity_get_classname(weapon)

        if weapon_class == "CWeaponTaser" then
            return true
        end
    end

    return false
end

anti_aim.safe_head = function ()
    local is_knife = helpers.is_knife ()
    local get_ze_us = helpers.is_taser ()

    if not menu.prod[ tabs.anti_aim ]['Controller']:get() or
    not table.find(menu.prod[ tabs.anti_aim ]['Functions']:get(), 'Safe Head') then
    return
    end

    local is_dt_charge = anti_aim.dt_charge ()

    local condition = callback.get('antiaim::condition', true)

    if condition == 'In Air' or condition == 'In Air & Crouching' then
        if is_knife or not is_dt_charge or get_ze_us then
            menu.override(reference.AA.angles.pitch, lua.builder.pitch [ 5 ])
            menu.override(reference.AA.angles.yaw_base, lua.builder.yaw_base [ 2 ])
            menu.override(reference.AA.angles.yaw[1], lua.builder.yaw [ 2 ])
            menu.override(reference.AA.angles.yaw[2], 9)
            menu.override(reference.AA.angles.yaw_jitter[1], lua.builder.yaw_jitter[ 1 ])
            menu.override(reference.AA.angles.yaw_jitter[2], 0)
            menu.override(reference.AA.angles.body_yaw[1], lua.builder.body_yaw[ 2 ])
            menu.override(reference.AA.angles.body_yaw[2], -9)
            return true
        end
    end
end

anti_aim.disable_fl_on_exploits = function (c)
    --#region

    local switch = true

    local is_os = ui_get(reference.AA.other.on_shot_antiaim[1]) and ui_get(reference.AA.other.on_shot_antiaim[2])
    local is_dt = ui_get(reference.RAGE.aimbot.double_tap[1]) and ui_get(reference.RAGE.aimbot.double_tap[2])

    local fakelag = reference.AA.fakelag.enabled

    if anti_aim.is_standing(c) then
        switch = false
    elseif is_dt and anti_aim.dt_charge() then
        switch = false
    elseif is_os then
        switch = false
    elseif is_dt and helpers.is_heavy_pistol() then
        switch = false
    elseif is_dt and helpers.is_knife() then
        switch = false
    elseif helpers.is_nade() then
        switch = false
    else
        switch = true
    end

    menu.override(fakelag, switch)
end

anti_aim.disable_stocks = function ()
    menu.override(reference.AA.angles.yaw[1], lua.builder.yaw[6])
    menu.override(reference.AA.angles.yaw[2], 0)
    menu.override(reference.AA.angles.yaw_jitter[1], lua.builder.yaw_jitter[1])
    menu.override(reference.AA.angles.body_yaw[1], lua.builder.body_yaw[4])
end

anti_aim.main = function(c)
    if not menu.prod[ tabs.anti_aim ]['Controller']:get() then
        return
    end

    local manual_yaw = anti_aim.manual_degree[anti_aim.manual_yaw]
    local modified_yaw = 0

    modified_yaw = modified_yaw + (anti_aim.handle_preset(c) or 0)
    modified_yaw = modified_yaw + (anti_aim.builder(c) or 0)
    local is_antibackstabing = anti_aim.anti_backstab(c)


    if table.find(menu.prod[ tabs.anti_aim ]['Functions']:get(), lua.anti_aims.utils[2]) then
        anti_aim.disable_fl_on_exploits(c)
    end

    local using = anti_aim.using(c)

    if using then
        return
    end

    local s_h = anti_aim.safe_head ()

    if not manual_yaw then
        if not is_antibackstabing then
            anti_aim.safe_head ();
            if not s_h then
                anti_aim.defensive_antiaim(c);
            end
        end

        if ui_get(menu.prod[ tabs.keybinds ]['Freestanding Bound'].m_reference) then
            if not ui_get(menu.prod[ tabs.keybinds ]['Freestanding Bound'].m_reference) then
                goto skip_check
            end

            --fsUTIL

            if table.find(menu.prod[ tabs.anti_aim ]['Static On Manuals']:get(), 'Freestanding') then
                menu.override(reference.AA.angles.yaw_jitter[1], lua.builder.yaw_jitter[1])
                menu.override(reference.AA.angles.body_yaw[1], lua.builder.body_yaw[4])
            end

            menu.override(reference.AA.angles.freestanding[1], true);
            menu.override(reference.AA.angles.freestanding[2], lua.builder.hotkey_states[0])
            ::skip_check::
        end

        if table.find(menu.prod[ tabs.anti_aim ]['Functions']:get(), 'Edge Yaw on Ctrl') then
            if not table.find(menu.prod[ tabs.anti_aim ]['Functions']:get(), 'Edge Yaw on Ctrl') then
                goto skip_check
            end

            local condition = callback.get('antiaim::condition', true)
            local state = false

            if condition == 'Crouching' then
                state = true
            end

            menu.override(reference.AA.angles.edge_yaw, state)
            ::skip_check::
        end
        return
    end

    if table.find(menu.prod[ tabs.anti_aim ]['Static On Manuals']:get(), 'Manual Yaw Base') then
        menu.override(reference.AA.angles.yaw_jitter[1], lua.builder.yaw_jitter[1])
        menu.override(reference.AA.angles.body_yaw[1], lua.builder.body_yaw[4])
    else
        manual_yaw = manual_yaw + modified_yaw
    end

    menu.override(reference.AA.angles.yaw_base, lua.builder.yaw_base[1])
    menu.override(reference.AA.angles.yaw[1], lua.builder.yaw[2])
    menu.override(reference.AA.angles.yaw[2], normalize(manual_yaw, -180, 180))
end

anti_aim.on_death = function (e)
    if client_userid_to_entindex(e.userid) ~= entity_get_local_player() then
        return
    end

    anti_aim.last_body_yaw = 0
    anti_bruteforce.reset()
end

anti_aim.air_defensive = function (cmd)
    if not menu.prod[ tabs.anti_aim ]['Controller']:get() then
        return
    end

    local condition = callback.get('antiaim::condition', true)
    if not condition then
        return
    end

    local enabled = table.find(menu.prod[ tabs.anti_aim ]['Functions']:get(), 'Force Break LC in Air')

    if condition == 'In Air' or condition == 'In Air & Crouching' or condition == 'Is Landing' or condition == 'Crouching' or condition == 'On Hittable' then
        cmd.force_defensive = enabled and 1 or 0
    end
end

local start = screen / 2 + library.vector(0, 15)
local dmg_drag = g_drag.new(start.x + 10, start.y - 40, 28, 16)

local engine_client = ffi_cast(ffi_typeof('void***'), client_create_interface('engine.dll', 'VEngineClient014'))
local console_is_visible = ffi_cast(ffi_typeof('bool(__thiscall*)(void*)'), engine_client[0][11])

local state_anim = 0
local dt_anim = 0
local damage_anim = 0

local manual_anim_right = 0
local manual_anim_left = 0

local anim = {
    damage_hovered = 0,
    wtr_hovered = 0,
    n = 0
}

do
    local elements = {
        {'DMG', reference.RAGE.aimbot.min_damage_override[1] and reference.RAGE.aimbot.min_damage_override[2]},
        {'OSAA', reference.AA.other.on_shot_antiaim[2]},
        {'FS', menu.prod[ tabs.keybinds ]['Freestanding Bound'].m_reference},
        {'BAIM', reference.RAGE.aimbot.force_body_aim},
        {'SAFE', reference.RAGE.aimbot.force_safe_point},
        {'DUCK', reference.RAGE.other.duck_peek_assist}
    }

    local txt_sizes = { }

    local got_sizes = false

    visual_controller.inidcators = function()
        local lp = entity_get_local_player()
        if not lp then
            return
        end

        if not menu.prod[ tabs.visuals ]['Visuals']:get() then
            return
        end

        local valid = lp ~= nil and entity_is_alive(lp)

        anim.pulse = math_min(255, 255 - animations:process("Pulse", not (globals_realtime() * 2.5 % 3 >= 1)) * 205) / 255

        anim.global_alpha = animations:process('Global', menu.prod[tabs.visuals]['Crosshair Indicators']:get() and valid)

        local is_nade = helpers.is_nade()
        local key_state_0x09 = client.key_state(0x09)  or console_is_visible(engine_client)
        
        anim.n = lerp_st(anim.n, is_nade and (is_nade and 55 or 255) or (key_state_0x09 and (key_state_0x09 and 0 or 255) or 255), globals_frametime() * 8)

        if anim.global_alpha < 0.01 or lp == nil then
            return
        end

        if not got_sizes then
            for i, v in pairs(elements) do
                txt_sizes[v[1]] = library.vector(renderer_measure_text('-', v[1]))
            end

            got_sizes = true
        end

        anim.doubletap = animations:process('Double Tap', anti_aim.dt_charge())

        local main_color = { menu.prod[tabs.visuals]['Gradient 2']:get() }
        local back_color = { menu.prod[tabs.visuals]['Gradient 1']:get() }

        local dt_r, dt_g, dt_b = lerp({ 255, 25, 25, 255 }, { 225, 225, 225, 255 }, anim.doubletap)

        local condition = callback.get('antiaim::condition', true) or 'UNKNOWN'
        anim.cyz = animations:process('swapper cond', condition, 8)

        local cond_sz = library.vector(renderer_measure_text('-', '-'..condition:upper()..'-')) do
            local pixels = cond_sz.x + 0.40;
            state_anim = animations:lerp(state_anim, pixels, 0.075);

            if pixels < state_anim then
                state_anim = anim.cyz;
            end
        end

        anim.scope = animations:process('Scope', (entity_get_prop(lp, 'm_bIsScoped') == 1), 5)

        local add_x = 34 * anim.scope

        local cond_centered = (-math_ceil(state_anim) / 2) * (1 - anim.scope) + (5 * anim.scope)

        anim.default = animations:process('Default', menu.prod[tabs.visuals]['Crosshair Indicators']:get() == 'Legacy')
        anim.fade = animations:process('Fade', menu.prod[tabs.visuals]['Crosshair Indicators']:get() == 'Gradient')

        local D_text = 'CHARGING'
        local D_text_len = #D_text + 1
        local D_light = ''
        local D_pos = start + library.vector(add_x, 5)

        for idx = 1, D_text_len do
            local letter = D_text:sub(idx, idx)

            local m_factor = (idx - 1) / D_text_len
            local m_breathe = breathe( m_factor * 1.5, 1.5)

            local r, g, b, a = lerp({ 225, 225, 225, anim.n }, { 255, 0, 0, anim.n }, m_breathe)
            a = anim.n * anim.global_alpha

            local m_hex_color = hex(r, g, b, a)
            D_light = D_light .. (m_hex_color .. letter)
        end

       -- BULL IT ***** CODE MADE

        local dt_s = 'BREAK'
        local d_col = { 255, 255, 255 }

        local cya_dt = reference.RAGE.aimbot.double_tap[2]
        local is_fd = ui_get(reference.RAGE.other.duck_peek_assist)

        local cya_y_ofs = 0

        local d_pos = 0

        local dt_pos = {renderer_measure_text("-","DT")}

        local recharge = ui_get(cya_dt) and (library.antiaim_funcs.get_tickbase_shifting() == 0)

        local is_dt_charged = ui_get(cya_dt) and anti_aim.dt_charge() and not is_fd
        local is_dt_charging = ui_get(cya_dt) and recharge and not anti_aim.dt_charge() and not is_fd
        local is_waiting = ui_get(cya_dt) and is_fd
        local cya_dt_released = ui_get(cya_dt)

        if is_dt_charged then
            dt_s = 'READY'
        elseif is_dt_charging then
            dt_s = D_light
            d_pos = -6
        elseif is_waiting then
            dt_s = 'WAITING'
            d_pos = -3
            d_col =  { 255, 97, 97 }
        elseif cya_dt_released then
            dt_s = 'ACTIVE'
            d_col =  { 150, 200, 59 }
        end

        if cya_dt_released then
            cya_y_ofs = cya_y_ofs + 27
        else
            cya_y_ofs = cya_y_ofs + 17
        end

        anim.rat = animations:process('release', (is_dt_charged or is_dt_charging or is_waiting or cya_dt_released), 6)

        local dt_vect = library.vector(renderer_measure_text('-', dt_s)) do
            local d_pix = dt_vect.x + 0.40;

            dt_anim = animations:lerp(dt_anim, d_pix, 0.095)

            if d_pix < dt_anim then
                dt_anim = anim.rat;
            end
        end

        local d_colorefuled = {
            r = math_lerp(255, d_col[1], 6),
            g = math_lerp(255, d_col[2], 6),
            b = math_lerp(255, d_col[3], 6),
            a = math_lerp(255 * anim.n, anim.n, 6)
        }

        local dt_centered = (-math_ceil(dt_anim) / 2) * (0 - anim.scope) + (9 * anim.scope)
        local dt_p_offset = (d_pos - anim.scope) + (4 * anim.scope)

        if anim.default > 0.01 then
            renderer_text(start.x - 29 + add_x, start.y + 1, 225, 225, 225, anim.n * anim.default * anim.global_alpha, '-', nil, 'AMELIA')
            renderer_text(start.x - 1 + add_x, start.y + 1, back_color[1], back_color[2],back_color[3], anim.n * anim.default * anim.pulse * anim.global_alpha, '-', nil, 'ALPHA')
            if anim.cyz ~= 0 then
                renderer_text(start.x + cond_centered, start.y + 9, 225, 225, 225, anim.n * anim.default * anim.global_alpha * anim.cyz, '-', math_ceil(state_anim) * anim.cyz, '-'..condition:upper()..'-')
            end

            if anim.rat ~= 0  then
                renderer_text(start.x - 19 + dt_centered + dt_p_offset, start.y + 18, 225, 225, 225, anim.n * anim.default * anim.global_alpha * anim.rat, '-', nil, 'DT')
                renderer_text(start.x - 19 + dt_pos[1] + 1 + dt_centered + dt_p_offset, start.y + 18, d_colorefuled.r * anim.rat, d_colorefuled.g * anim.rat, d_colorefuled.b * anim.rat, d_colorefuled.a * anim.default * anim.global_alpha * anim.rat, '-', math_ceil(dt_anim) * anim.rat, dt_s)
            end

        end

        local offset = 0

        if anim.fade > 0.01 then
            local text = 'amelia alpha'
            local text_len = #text + 1
            local light = ''
            local pos = start + library.vector(add_x, 5)

            add_x = 5 * anim.scope

            for idx = 1, text_len do
                local letter = text:sub(idx, idx)

                local m_factor = (idx - 1) / text_len
                local m_breathe = breathe(1 * m_factor * 1.5, 1.5)

                local r, g, b, a = lerp({ main_color[1], main_color[2], main_color[3], anim.n }, { back_color[1], back_color[2], back_color[3], anim.n }, m_breathe)
                a = anim.n * anim.fade * anim.global_alpha

                local m_hex_color = hex(r, g, b, a)
                light = light .. (m_hex_color .. letter)
            end

            local measure = library.vector(renderer_measure_text('c', light))

            renderer_text(pos.x + add_x, pos.y, 255, 255, 255, anim.n * anim.fade * anim.global_alpha, 'cb-', nil, light)
            if anim.cyz ~= 0 then
                renderer_text(start.x + cond_centered, start.y + 9, 225, 225, 225, anim.n * anim.fade * anim.global_alpha * anim.cyz, '-', math_ceil(state_anim) * anim.cyz, '-'..condition:upper()..'-')
            end
            if anim.rat ~= 0  then
                renderer_text(start.x - 19 + dt_centered + dt_p_offset, start.y + 18, 225, 225, 225, anim.n * anim.fade * anim.global_alpha * anim.rat, '-', nil, 'DT')
                renderer_text(start.x - 19 + dt_pos[1] + 1 + dt_centered + dt_p_offset, start.y + 18, d_colorefuled.r * anim.rat, d_colorefuled.g * anim.rat, d_colorefuled.b * anim.rat, d_colorefuled.a * anim.fade * anim.global_alpha * anim.rat, '-', math_ceil(dt_anim) * anim.rat, dt_s)
            end
            pos = pos + library.vector(0, measure.y * 0.85)
        end

        for _, element in ipairs(elements) do
            local bind_anim = animations:process(('Default_%s'):format(_), ui_get(element[2]), 6)
            local b_r, b_g, b_b, b_a = 225, 225, 225, anim.n * anim.global_alpha * bind_anim

            if bind_anim ~= 0 then

                local w_siz = 0

               --[[ if element[1] == 'DT' then
                    b_r, b_g, b_b, b_a = dt_r, dt_g, dt_b, 255 * anim.global_alpha * bind_anim
                end ]]

                local size_cur = txt_sizes[element[1]]
                local center_x = (-size_cur.x / 2) * (1.3 - anim.scope) + (7 * anim.scope)

                if anim.fade > 0.01 or anim.default > 0.01 then
                    renderer_text(start.x + center_x + w_siz, start.y + cya_y_ofs + offset, b_r, b_g, b_b, b_a, '-', nil, element[1])
                end

                offset = offset + 8 * bind_anim
            end
        end
    end
end

local ct = screen / 2 - library.vector(0, 1)

local r, g, b = 0, 0, 0
local r_1, g_1, b_1 = 0, 0, 0

anim.zal, anim.zal1 = 0,0

anim.m1, anim.m2, anim.m3 = 0,0,0
anim.m4, anim.m5, anim.m6 = 0,0,0

visual_controller.manual = function ()
    local lp = entity_get_local_player()
    if not lp then
        return
    end

    if not menu.prod[ tabs.visuals ]['Visuals']:get() then
        return
    end

    local valid = lp ~= nil and entity_is_alive(lp)

    anim.pulse1 = math_min(255, 255 - animations:process("Pulsez", not (globals_realtime() * 2.5 % 3 >= 1)) * 205) / 255

    anim.global_alpha1 = animations:process('Globalz', menu.prod[tabs.visuals]['Anti Aim Arrow']:get() and valid)

    if anim.global_alpha1 < 0.01 or lp == nil then
        return
    end

    local main_color = { menu.prod[tabs.visuals]['Arrow Color 1']:get() }
    local back_color = { menu.prod[tabs.visuals]['Arrow Color 2']:get() }

    anim.scope1 = animations:process('Scopez', (entity_get_prop(lp, 'm_bIsScoped') == 1), 5)

    local add_x = 34 * anim.scope1

    anim.default1 = animations:process('Defaultz', menu.prod[tabs.visuals]['Anti Aim Arrow']:get() == 'Simple')
    anim.fade1 =    animations:process('Fadez', menu.prod[tabs.visuals]['Anti Aim Arrow']:get() == 'Legacy')
    anim.modern1 =  animations:process('Modernz', menu.prod[tabs.visuals]['Anti Aim Arrow']:get() == 'Modern')

    local manual_left = animations:process('manual::left', anti_aim.manual_yaw == 1)
    local manual_right = animations:process('manual::right', anti_aim.manual_yaw == 2)
    local manual_forward = animations:process('manual::forward', anti_aim.manual_yaw == 3)

    local p1_offset = get_player_movement_direction()

    local manual_fstand = animations:process('manual::fstand', ui_get(menu.prod[ tabs.keybinds ]['Freestanding Bound'].m_reference) and anti_aim.manual_yaw == 0)
    local fstand_right_direction =  anti_aim.last_body_yaw > 0
    local fstand_left_direction =   anti_aim.last_body_yaw < 0

    r = animations:lerp(r, anti_aim.last_body_yaw > 0 and main_color[1] or 35, 0.015)
    g = animations:lerp(g, anti_aim.last_body_yaw > 0 and main_color[2] or 35, 0.015)
    b = animations:lerp(b, anti_aim.last_body_yaw > 0 and main_color[3] or 35, 0.015)

    r_1 = animations:lerp(r_1, anti_aim.last_body_yaw < 0 and main_color[1] or 35, 0.015)
    g_1 = animations:lerp(g_1, anti_aim.last_body_yaw < 0 and main_color[2] or 35, 0.015)
    b_1 = animations:lerp(b_1, anti_aim.last_body_yaw < 0 and main_color[3] or 35, 0.015)

    local is_nade = helpers.is_nade()
    local key_state_0x09 = client.key_state(0x09)  or console_is_visible(engine_client)
    
    anim.m1 = lerp_st(anim.m1, is_nade and (is_nade and 55 or 255) or (key_state_0x09 and (key_state_0x09 and 0 or 255) or 255), globals_frametime() * 8)
    anim.m2 = lerp_st(anim.m2, is_nade and (is_nade and 55 or 137) or (key_state_0x09 and (key_state_0x09 and 0 or 137) or 137), globals_frametime() * 8)

    anim.zal =    animations:lerp(anim.zal, anti_aim.last_body_yaw > 0 and 255 or 55, 0.045)
    anim.zal1 =   animations:lerp(anim.zal1, anti_aim.last_body_yaw < 0 and 255 or 55, 0.045)

    if anim.default1 > 0.01 then
        renderer_triangle(ct.x + 55, ct.y + 2, ct.x + 42, ct.y - 7, ct.x + 42, ct.y + 11, 17, 17, 17, anim.m2 * anim.default1)
        renderer_triangle(ct.x - 55, ct.y + 2, ct.x - 42, ct.y - 7, ct.x - 42, ct.y + 11, 17, 17, 17, anim.m2 * anim.default1)
        renderer_triangle(ct.x + 55, ct.y + 2, ct.x + 42, ct.y - 7, ct.x + 42, ct.y + 11, main_color[1], main_color[2], main_color[3], anim.m1 * anim.default1 * manual_right)
        renderer_triangle(ct.x - 55, ct.y + 2, ct.x - 42, ct.y - 7, ct.x - 42, ct.y + 11, main_color[1], main_color[2], main_color[3], anim.m1 * anim.default1 * manual_left)

        renderer_rectangle(ct.x + 38, ct.y - 7, 2, 18, 17, 17, 17, anim.m2 * anim.default1)
        renderer_rectangle(ct.x - 40, ct.y - 7, 2, 18, 17, 17, 17, anim.m2 * anim.default1)
        renderer_rectangle(ct.x + 38, ct.y - 7, 2, 18, r, g, b, anim.m1 * anim.default1)
        renderer_rectangle(ct.x - 40, ct.y - 7, 2, 18, r_1, g_1, b_1, anim.m1 * anim.default1)
    end

    if anim.fade1 > 0.01 then
        renderer_text (ct.x + add_x + manual_right * 55, ct.y + 2, main_color[1], main_color[2], main_color[3], anim.m1 * anim.fade1 * manual_right , 'c+', 0, '⮞')
        renderer_text (ct.x + add_x - manual_left * 55, ct.y + 2, main_color[1], main_color[2], main_color[3], anim.m1 * anim.fade1 * manual_left , 'c+', 0, '⮜')
        renderer_text (ct.x + add_x - manual_forward * -0, ct.y - manual_forward * 15, main_color[1], main_color[2], main_color[3], anim.m1 * anim.fade1 * manual_forward , 'c+', 0, '⮝')

        --[[
        renderer_arrow_right (ct.x + add_x + manual_left * 27, ct.y + 2, main_color[1], main_color[2], main_color[3], 255 * anim.fade1 * manual_left, 0,  25)
        renderer_arrow_left (ct.x + add_x + manual_left * 27, ct.y + 4, main_color[1], main_color[2], main_color[3], 255 * anim.fade1 * manual_left, 0, 25) ]]

        renderer_text (ct.x + add_x + manual_fstand * 55, ct.y + 2, r, g, b, anim.zal * anim.fade1 * manual_fstand , 'c+', 0, '⮞')
        renderer_text (ct.x + add_x + manual_fstand * 48, ct.y + 2, r, g, b, anim.zal * anim.fade1 * manual_fstand , 'c+', 0, '›')

        renderer_text (ct.x + add_x - manual_fstand * 48, ct.y + 2, r_1, g_1, b_1, anim.zal1 * anim.fade1 * manual_fstand , 'c+', 0, '‹')
        renderer_text (ct.x + add_x - manual_fstand * 55, ct.y + 2, r_1, g_1, b_1, anim.zal1 * anim.fade1 * manual_fstand , 'c+', 0, '⮜')
    end

    if anim.modern1 > 0.01 then
        local radius = 35
        local view = library.vector(client_camera_angles())

        local yaw = math_normalize(library.antiaim_funcs.get_abs_yaw() - view.y - 180)

        local yaw_add = 30

        renderer_arrow_left(ct.x +  add_x, ct.y + yaw_add, 17, 17, 17, anim.m2 * anim.modern1,  (yaw - 90) * -1, radius)
        renderer_arrow_right(ct.x + add_x, ct.y + yaw_add, 17, 17, 17, anim.m2 * anim.modern1,  (yaw - 90) * -1, radius)

        if anti_aim.last_body_yaw > 0 then
            renderer_arrow_left(ct.x +  add_x, ct.y + yaw_add, main_color[1], main_color[2], main_color[3], anim.m1 * anim.modern1,  (yaw - 90) * -1, radius)
            renderer_arrow_right(ct.x + add_x, ct.y + yaw_add, back_color[1], back_color[2], back_color[3], anim.m1 * anim.modern1,  (yaw - 90) * -1, radius)
        else
            renderer_arrow_right(ct.x +  add_x, ct.y + yaw_add, main_color[1], main_color[2], main_color[3], anim.m1 * anim.modern1,  (yaw - 90) * -1, radius)
            renderer_arrow_left(ct.x + add_x, ct.y + yaw_add,  back_color[1], back_color[2], back_color[3], anim.m1 * anim.modern1,  (yaw - 90) * -1, radius)
        end
    end
end

animation_breaker.run = function ()
    local me = entity_get_local_player()

    if not entity_is_alive(me) then
        return
    end

    local flags = entity_get_prop(me, "m_fFlags")
    local on_ground = bit_band(flags, 1)
    local menu_open = ui_is_menu_open()
	local legs_types = {[1] = "Off", [2] = "Always slide", [3] = "Never slide"}

    local on_slowwalk = ui_get(reference.AA.other.slow_motion[1]) and ui_get(reference.AA.other.slow_motion[2])

    if not menu.prod[ tabs.general ]['General']:get() then
        return
    end

    if table.find(menu.prod[tabs.general]['Anim Breaker']:get(), 'Landing Pitch') then
        if on_ground == 1 then
            animation_breaker.cvars.ground_ticks = animation_breaker.cvars.ground_ticks + 1
        else
            animation_breaker.cvars.ground_ticks = 0
            animation_breaker.cvars.end_time = globals_curtime() + 1
        end

        if animation_breaker.cvars.ground_ticks > ui_get(reference.AA.fakelag.limit)+1 and animation_breaker.cvars.end_time  > globals_curtime() then
            entity_set_prop(me, "m_flPoseParameter", 0.5, 12)
        end
    end

    if table.find(menu.prod[tabs.general]['Anim Breaker']:get(), 'Force Falling') then
        if on_ground ~= 1 then
            entity_set_prop(me, 'm_flPoseParameter', 1, 6)
            entity_set_prop(me, "m_fFlags", library.bit.bor(flags, 256))
        end
    end

    if table.find(menu.prod[tabs.general]['Anim Breaker']:get(), 'Leg Breaker') and not menu_open then
        ui_set(reference.AA.other.leg_movement, legs_types[math.random(1, 3)])
        entity_set_prop(entity_get_local_player(), "m_flPoseParameter", 8, 0)
    end

    if table.find(menu.prod[tabs.general]['Anim Breaker']:get(), 'Sliding on Slow-Motion') and on_slowwalk then
        ui_set(reference.AA.other.leg_movement, legs_types[2])
        entity_set_prop(entity_get_local_player(), "m_flPoseParameter", 8, 0)
    end
end

function library.entity.get_health(player)
	return player:get_prop('m_iHealth')
end

animation_breaker.moonwalk = function ()
    local me = library.entity.get_local_player()

    if not me then return end
	if me:get_health() <= 0 then return end

    local m_fFlags = me:get_prop("m_fFlags")
	local vx, vy, vz = me:get_prop("m_vecVelocity")

    local player = entity_get_local_player()
	if not entity_is_alive(player) then return end

    local on_still = math_sqrt(vx ^ 2 + vy ^ 2) < 2
    local on_ground = bit_band(m_fFlags, 1) == 1

    local legs_types = {[1] = "Off", [2] = "Always slide", [3] = "Never slide"}

    if not menu.prod[ tabs.general ]['General']:get() then
        return
    end

    if menu.prod[ tabs.general ]['Moonwalk Mode']:get() then
        if not on_still then
            local my_animlayer = me:get_anim_overlay(7)
            local speed = 0.4
            local factor = globals_realtime() * speed % 1
            my_animlayer.sequence = 26
            my_animlayer.weight = 1
            my_animlayer.cycle = factor
        else
            entity_set_prop(player, "m_flPoseP2arameter", 0, 1) --1,6
        end
    end

    if menu.prod[ tabs.general ]['Moonwalk In Air']:get() then
        if not on_ground then
            local my_animlayer = me:get_anim_overlay(6)
            local speed = 0.4
            local factor = globals_realtime() * speed % 1
            my_animlayer.sequence = 26
            my_animlayer.weight = 1
            my_animlayer.cycle = factor
        else
            entity_set_prop(player, "m_flPoseP2arameter", 6, 0) --1,6
            --ui_set(gamesense_refs.leg_movement, legs_types[1])
        end
    end
end

visual_controller.w = function () visual_controller.notifications:render() end

hitlogs.data = {}
hitlogs.sim, hitlogs.net = {}, {}

hitlogs.cl_data = {
    tick_shifted = false,
    tick_base = 0
}

hitlogs.ent = function (enemy_only, alive_only)
    local enemy_only = enemy_only ~= nil and enemy_only or false
    local alive_only = alive_only ~= nil and alive_only or true

    local result = {}
    local player_resource = entity_get_player_resource()
    for player = 1, globals_maxplayers() do
        local is_enemy, is_alive = true, true

        if enemy_only and not entity_is_enemy(player) then is_enemy = false end
        if is_enemy then
            if alive_only and entity_get_prop(player_resource, 'm_bAlive', player) ~= 1 then is_alive = false end
            if is_alive then table_insert(result, player) end
        end
    end

    return result
end

hitlogs.generate_flags = function (e, on_fire_data)
    return {
		e.refined and 'R' or '',
		e.expired and 'X' or '',
		e.noaccept and 'N' or '',
		hitlogs.cl_data.tick_shifted and 'S' or '',
		on_fire_data.teleported and 'T' or '',
		on_fire_data.interpolated and 'I' or '',
		on_fire_data.extrapolated and 'E' or '',
		on_fire_data.boosted and 'B' or '',
		on_fire_data.high_priority and 'H' or ''
    }
end

hitlogs.net_upd = function ()
	local me = entity_get_local_player()
    local players = hitlogs.ent(true, true)
	local m_tick_base = entity_get_prop(me, 'm_nTickBase')

    local cl_data = hitlogs.cl_data

    cl_data.tick_shifted = false

	if m_tick_base ~= nil then
		if cl_data.tick_base ~= 0 and m_tick_base < cl_data.tick_base then
			cl_data.tick_shifted = true
		end

		cl_data.tick_base = m_tick_base
    end

    local g_sim_ticks = hitlogs.sim
    local g_net_data = hitlogs.net

    for i=1, #players do
		local idx = players[i]
        local prev_tick = g_sim_ticks[idx]
        
        if entity_is_dormant(idx) or not entity_is_alive(idx) then
            g_sim_ticks[idx] = nil
            g_net_data[idx] = nil
        else
            local player_origin = { entity_get_origin(idx) }
            local simulation_time = time_to_ticks(entity_get_prop(idx, 'm_flSimulationTime'))
    
            if prev_tick ~= nil then
                local delta = simulation_time - prev_tick.tick

                if delta < 0 or delta > 0 and delta <= 64 then
                    local m_fFlags = entity_get_prop(idx, 'm_fFlags')

                    local diff_origin = vec_substract(player_origin, prev_tick.origin)
                    local teleport_distance = vec_lenght(diff_origin[1], diff_origin[2])

                    g_net_data[idx] = {
                        tick = delta-1,

                        origin = player_origin,
                        tickbase = delta < 0,
                        lagcomp = teleport_distance > 4096,
                    }
                end
            end

            g_sim_ticks[idx] = {
                tick = simulation_time,
                origin = player_origin,
            }
        end
    end
end

hitlogs.on_fire = function (e)
    local data = e

    local plist_sp = plist.get(e.target, 'Override safe point')
    local checkbox = ui_get(reference.RAGE.aimbot.force_safe_point)

    local g_aimbot_data = hitlogs.data
    local g_sim_ticks = hitlogs.sim
    local g_net_data = hitlogs.net

    if g_net_data[e.target] == nil then
        g_net_data[e.target] = { }
    end

    data.teleported = g_net_data[e.target].lagcomp or false
    data.choke = g_net_data[e.target].tick or '?'
    data.self_choke = globals.chokedcommands()
    data.safe_point = ({
        ['Off'] = 'off',
        ['On'] = 'true',
        ['-'] = checkbox
    })[plist_sp]
    data.pred_dmg = e.damage

    g_aimbot_data[e.id] = data
end

ticks_to_time = function(ticks)
    return globals_tickinterval() * ticks
end

hitlogs.aimbot = function (e)
    if not menu.prod[ tabs.visuals ]['Visuals']:get() then
        return
    end

    if not menu.prod[ tabs.visuals ]['Logs']:get() then
        return
    end

    local g_aimbot_data = hitlogs.data
    local g_sim_ticks = hitlogs.sim
    local g_net_data = hitlogs.net

    if g_aimbot_data [e.id] == nil then
        return
    end

    local on_fire_data = g_aimbot_data[e.id]
    local name = string.lower(entity_get_player_name(e.target))
    local hgroup = defines.hitgroups[e.hitgroup + 1] or '?'
    local aimed_hgroup = defines.hitgroups[on_fire_data.hitgroup + 1] or '?'

    local hitchance = math_floor(on_fire_data.hit_chance + 0.5) .. '%'
    local health = entity_get_prop(e.target, 'm_iHealth')

    local bt = globals_tickcount()-e.tick
    local bt_to_ms = math_floor(ticks_to_time(bt) * 100)

    local flags = hitlogs.generate_flags(e, on_fire_data)
    local d_state = ''

    local dmg = on_fire_data.damage - e.damage
    if dmg >= 0 then
        d_state = '+'
    else
        d_state = ''
    end

    local action
    if health <= 0 then
        action = 'Killed'
    elseif health > 0 then
        action = 'Hit'
    end

    if table.find(menu.prod[tabs.visuals]['Events']:get(), 'Hit') and table.find(menu.prod[tabs.visuals]['Logs Style']:get(), 'Console Panel') then
        color_log(160, 203, 39, string_format(
            '[+] Hit %s\'s %s for %i (%s%d) damage (%s) bt=%ims %s move=%s t=%s',
            name, hgroup, e.damage, d_state, dmg, hitchance, bt_to_ms, table_concat(flags), on_fire_data.choke, on_fire_data.self_choke
        ))
    end

    local r,g,b = menu.prod[tabs.visuals]['Gradient 2']:get()

    if table.find(menu.prod[tabs.visuals]['Events']:get(), 'Hit') and table.find(menu.prod[tabs.visuals]['Logs Style']:get(), 'Amelia') then
        if bt_to_ms > 0 then
            if action == 'Hit' then
                visual_controller.notifications:new(3, string_format('%s $%s$\'$s$ in $%s$ for $%i$ damage bt $%i$ms', action, name, hgroup, e.damage, bt_to_ms), r, g, b)
            elseif action == 'Killed' then
                visual_controller.notifications:new(3, string_format('%s $%s$\'$s$ in $%s$ bt $%i$ms', action, name, hgroup, bt_to_ms), r, g, b)
            end
        elseif bt_to_ms <= 0 then
            if action == 'Hit' then
                visual_controller.notifications:new(3, string_format('%s $%s$\'$s$ in $%s$ for $%i$ damage', action, name, hgroup, e.damage), r, g, b)
            elseif action == 'Killed' then
                visual_controller.notifications:new(3, string_format('%s $%s$\'$s$ in $%s$', action, name, hgroup), r, g, b)
            end
        end
    end
end

hitlogs.miss = function (e)
    if not menu.prod[ tabs.visuals ]['Visuals']:get() then
        return
    end

    if not menu.prod[ tabs.visuals ]['Logs']:get() then
        return
    end

    local g_aimbot_data = hitlogs.data
    local g_sim_ticks = hitlogs.sim
    local g_net_data = hitlogs.net

    if g_aimbot_data [e.id] == nil then
        return
    end

    local on_fire_data = g_aimbot_data[e.id]
    local name = string_lower(entity_get_player_name(e.target))

	local hgroup = defines.hitgroups[e.hitgroup + 1] or '?'
    local hitchance = math_floor(on_fire_data.hit_chance + 0.5) .. '%'

    local flags = hitlogs.generate_flags(e, on_fire_data)

    local bt = globals_tickcount()-e.tick
    local bt_to_ms = math_floor(ticks_to_time(bt) * 100)

    local dmg = on_fire_data.pred_dmg - on_fire_data.damage

    if table.find(menu.prod[tabs.visuals]['Events']:get(), 'Miss') and table.find(menu.prod[tabs.visuals]['Logs Style']:get(), 'Console Panel') then
        color_log(203, 39, 39, string_format(
            '[-] Missed %s\'s %s for %i damage (%s) due to %s (%d) bt=%ims %s move=%s t=%s',
            name, hgroup, on_fire_data.pred_dmg, hitchance, e.reason, dmg, bt_to_ms, table.concat(flags), on_fire_data.choke, on_fire_data.self_choke
    ))
    end

    local miss_r

    if e.reason == '?' then
        miss_r = 'resolver'
    else
        miss_r = e.reason
    end

    if table.find(menu.prod[tabs.visuals]['Events']:get(), 'Miss') and table.find(menu.prod[tabs.visuals]['Logs Style']:get(), 'Amelia') then
        visual_controller.notifications:new(3, string_format('Missed $%s$\'$s$ in $%s$ due to $%s$',  name, hgroup, miss_r), 228, 39, 39)
    end

end

hitlogs.other = function (e)
    if not menu.prod[ tabs.visuals ]['Visuals']:get() then
        return
    end

    if not menu.prod[ tabs.visuals ]['Logs']:get() then
        return
    end

    local attacker_id = client_userid_to_entindex(e.attacker)

    if attacker_id == nil or attacker_id ~= entity_get_local_player() then
        return
    end

    local group = defines.hitgroups[e.hitgroup + 1] or "?"

    if table.find(menu.prod[tabs.visuals]['Events']:get(), 'Hit') and table.find(menu.prod[tabs.visuals]['Logs Style']:get(), 'Console Panel') then
        if group == "generic" and defines.weapon_to_verb[e.weapon] ~= nil then
            local target_id = client_userid_to_entindex(e.userid)
            local target_name = entity_get_player_name(target_id)

            print(string_format("%s %s for %i damage (%i remaining) ", defines.weapon_to_verb[e.weapon], string.lower(target_name), e.dmg_health, e.health))
        end
    end

    local health = e.health
    local weap = defines.weapon_to_kill[e.weapon]

    local r,g,b = menu.prod[tabs.visuals]['Gradient 2']:get()
    local action

    if table.find(menu.prod[tabs.visuals]['Events']:get(), 'Hit') and table.find(menu.prod[tabs.visuals]['Logs Style']:get(), 'Amelia') then
        if group == "generic" and defines.weapon_to_verb[e.weapon] ~= nil  then
            if health <= 0 then
                action = 'Killed'
            elseif health > 0 then
                action = defines.weapon_to_verb[e.weapon]
            end
            local target_id = client_userid_to_entindex(e.userid)
            local target_name = entity_get_player_name(target_id)

            if action == defines.weapon_to_verb[e.weapon] then
                visual_controller.notifications:new(3, string_format('%s $%s$ for $%i$ damage ($%i$ remaining)',  action, string_lower(target_name), e.dmg_health, e.health), r,g,b)
            elseif action == 'Killed' then
                visual_controller.notifications:new(3, string_format('%s $%s$ with $%s',  action, string_lower(target_name), weap), r,g,b)
            end
        end
    end
end

helpers.fast_ladder = function (c)
    local local_player = entity_get_local_player()
    local pitch, yaw = math_floor(client_camera_angles())

    if not menu.prod[ tabs.misc ]['Miscellaneous']:get() then
        return
    end

    if not menu.prod[ tabs.misc ]['Fast Ladder']:get() then
        return
    end

    if not entity_get_prop(local_player, "m_MoveType") == 9 then
        return
    end

    if entity_get_prop(local_player, "m_MoveType") == 9 then
        c.yaw = math_floor(c.yaw+0.5)
        c.roll = 0
        c.yaw = math_floor(c.yaw+0.5)
        if c.forwardmove == 0 then
            c.pitch = 89
            c.yaw = c.yaw - 180
            if c.sidemove ~= 0 then
                c.pitch = 89
                c.yaw = c.yaw - 180
            end
            if c.sidemove < 0 then
                c.yaw = c.yaw - 180
                c.in_moveleft = 0
                c.in_moveright = 1
            end
            if c.sidemove > 0 then
                c.yaw = c.yaw - 180
                c.in_moveleft = 1
                c.in_moveright = 0
            end
        elseif c.forwardmove > 0 then
            if c.pitch < 45 then
                c.pitch = 89
                c.in_moveright = 1
                c.in_moveleft = 0
                c.in_forward = 0
                c.in_back = 1

                if c.sidemove == 0 then
                    c.yaw = c.yaw + 90
                end

                if c.sidemove < 0 then
                    c.yaw = c.yaw + 150
                end

                if c.sidemove > 0 then
                    c.yaw = c.yaw + 30
                end
            end
        elseif c.forwardmove < 0 then
            c.pitch = 89
            c.in_moveleft = 1
            c.in_moveright = 0
            c.in_forward = 1
            c.in_back = 0

            if c.sidemove == 0 then
                c.yaw = c.yaw + 90
            end

            if c.sidemove > 0 then
                c.yaw = c.yaw + 150
            end

            if c.sidemove < 0 then
                c.yaw = c.yaw + 30
            end
        end
    end
end

helpers.ideal_tick = function ()
    if not menu.prod[ tabs.general ]['General']:get() then
        return
    end

    if menu.prod[ tabs.general ]['Ideal Tick']:get() then
        return
    end

    local recharging = ui_get(reference.RAGE.aimbot.double_tap[2]) and (library.antiaim_funcs.get_tickbase_shifting() == 0)
    local shoting = anti_aim.on_shot

    local timer = globals_curtime()

    local me = entity.get_local_player ()

    local my_weapon = entity_get_player_weapon(me)

    if my_weapon == nil then
        return
    end

    local can_Fire =
    (entity_get_prop(me, "m_flNextAttack") <= timer and
    entity_get_prop(my_weapon, "m_flNextPrimaryAttack") <= timer)

    if table.find(menu.prod[tabs.general]['Ideal Options']:get(), 'No Packets on Peek') then
        helpers.cvars_saved.sv_maxunlag = 0.19
        helpers.cvars_saved.sv_clockcorrection_msecs = 0
        helpers.cvars_saved.sv_client_min_interp_ratio = 0
        helpers.cvars_saved.sv_client_min_interp_ratio = 0
        helpers.cvars_saved.sv_client_cmdrate_difference = 0
    end

    if table.find(menu.prod[tabs.general]['Ideal Options']:get(), 'No Choke on Shot') then
        if shoting or can_Fire then
            helpers.cvars_saved.sv_maxusrcmdprocessticks = 28
            helpers.cvars_saved.sv_maxcmdrate = 128
            helpers.cvars_saved.sv_maxrate = 0
            helpers.cvars_saved.sv_minrate = 0
            helpers.cvars_saved.sv_maxupdaterate = 128
            helpers.cvars_saved.sv_minupdaterate = 128
        end
    end
end

helpers.override_max_dt_speed = function ()
    local is_dt = ui_get(reference.RAGE.aimbot.double_tap[1]) and ui_get(reference.RAGE.aimbot.double_tap[2]) 
    local is_recharging = ui_get(reference.RAGE.aimbot.double_tap[2]) and (library.antiaim_funcs.get_tickbase_shifting() == 0)

    if is_dt and not is_recharging then
        helpers.cvars_saved.sv_maxusrcmdprocessticks = 14
        helpers.cvars_saved.sv_maxunlag = 0.140
        helpers.cvars_saved.sv_clockcorrection_msecs = 4
        helpers.cvars_saved.sv_client_min_interp_ratio = 0
        helpers.cvars_saved.sv_client_max_interp_ratio = 0
        helpers.cvars_saved.sv_client_cmdrate_difference = 0
        helpers.cvars_saved.sv_maxcmdrate = 128
        helpers.cvars_saved.sv_maxrate = 0
        helpers.cvars_saved.sv_minrate = 0
        helpers.cvars_saved.sv_maxupdaterate = 128
        helpers.cvars_saved.sv_minupdaterate = 128
    elseif is_dt and is_recharging then
        helpers.cvars_saved.sv_maxunlag = 0
        helpers.cvars_saved.sv_clockcorrection_msecs = 0
        helpers.cvars_saved.sv_client_min_interp_ratio = 0
        helpers.cvars_saved.sv_client_min_interp_ratio = 0
        helpers.cvars_saved.sv_client_cmdrate_difference = 0
        helpers.cvars_saved.sv_maxusrcmdprocessticks = 28
        helpers.cvars_saved.sv_maxcmdrate = 128
        helpers.cvars_saved.sv_maxrate = 0
        helpers.cvars_saved.sv_minrate = 0
        helpers.cvars_saved.sv_maxupdaterate = 128
        helpers.cvars_saved.sv_minupdaterate = 128
    end
end

helpers.override_cvars = function ()
    client_set_cvar(defines.cvars.sv_maxusrcmdprocessticks, helpers.cvars_saved.sv_maxusrcmdprocessticks)
    client_set_cvar(defines.cvars.sv_maxusrcmdprocessticks, helpers.cvars_saved.sv_maxunlag)
    client_set_cvar(defines.cvars.sv_maxusrcmdprocessticks, helpers.cvars_saved.sv_clockcorrection_msecs)
    client_set_cvar(defines.cvars.sv_maxusrcmdprocessticks, helpers.cvars_saved.sv_client_max_interp_ratio)
    client_set_cvar(defines.cvars.sv_maxusrcmdprocessticks, helpers.cvars_saved.sv_client_cmdrate_difference)
    client_set_cvar(defines.cvars.sv_maxusrcmdprocessticks, helpers.cvars_saved.sv_maxcmdrate)
    client_set_cvar(defines.cvars.sv_maxusrcmdprocessticks, helpers.cvars_saved.sv_maxrate)
    client_set_cvar(defines.cvars.sv_maxusrcmdprocessticks, helpers.cvars_saved.sv_minrate)
    client_set_cvar(defines.cvars.sv_maxusrcmdprocessticks, helpers.cvars_saved.sv_maxupdaterate)
    client_set_cvar(defines.cvars.sv_maxusrcmdprocessticks, helpers.cvars_saved.sv_minupdaterate)
end

helpers.cvars_shutdown = function ()
    helpers.cvars_saved.sv_maxusrcmdprocessticks = 16
    helpers.cvars_saved.sv_maxunlag = 0.500
    helpers.cvars_saved.sv_clockcorrection_msecs = 0
    helpers.cvars_saved.sv_client_min_interp_ratio = 1
    helpers.cvars_saved.sv_client_max_interp_ratio = 2
    helpers.cvars_saved.sv_client_cmdrate_difference = 30
    helpers.cvars_saved.sv_maxcmdrate = 0
    helpers.cvars_saved.sv_maxrate = 0
    helpers.cvars_saved.sv_minrate = 16000
    helpers.cvars_saved.sv_maxupdaterate = 64
    helpers.cvars_saved.sv_minupdaterate = 64
end

menu.visibility = function ()
    menu.set_visible(reference.AA.angles, false)
end

menu.visibility_shutdown = function ()
    menu.set_visible(reference.AA.angles, true)
end

menu.prevent_mouse = function (cmd)
    if ui_is_menu_open() then
        cmd.in_attack = false
    end
end

--НИЖЕ = ВЫШЕ ПО ЗНАЧЕНИЮ
callback.new('antiaim::condition', 'setup_command', anti_aim.condition)
callback.new('antiaim::handle_manual', 'paint', anti_aim.handle_manuals)
callback.new('antiaim::handle_defensive', 'net_update_end', anti_aim.handle_defensive)
callback.new('antiaim::anti_backstab', 'setup_command', anti_aim.anti_backstab)
callback.new('antiaim::handle_builder', 'setup_command', anti_aim.builder)
callback.new('antiaim::main', 'setup_command', anti_aim.main)

callback.new('antiaim::air_defensive', 'setup_command', anti_aim.air_defensive)
callback.new('antiaim::on_warmup', 'setup_command', anti_aim.on_warmup)

callback.new('roundender', 'round_end', anti_aim.disable_stocks)

callback.new('anti_bruteforce::bullet', 'bullet_impact', anti_bruteforce.pre_bullet_impact)
callback.new('anti_bruteforce::run_command', 'run_command', anti_bruteforce.work_time)

callback.new('::anim_break', 'pre_render', animation_breaker.run)
callback.new('::mwalk', 'pre_render', animation_breaker.moonwalk)

callback.new('ladder', 'setup_command', helpers.fast_ladder)
callback.new('dt_help', 'run_command', helpers.override_cvars)

callback.new('antiaim::on_aim', 'aim_fire', anti_aim.on_aim)

callback.new('hlogs::fire', 'aim_fire', hitlogs.on_fire)
callback.new('hlogs::hit', 'aim_hit', hitlogs.aimbot)
callback.new('hlogs::miss', 'aim_miss', hitlogs.miss)
callback.new('hlogs::other', 'player_hurt', hitlogs.other)
callback.new('hlogs::net', 'net_update_end', hitlogs.net_upd)

callback.new('antiaim::player_death', 'player_death', anti_aim.on_death)
callback.new('anti_bruteforce::discon', 'cs_game_disconnected', anti_bruteforce.reset)
callback.new('anti_bruteforce::new_map', 'game_newmap', anti_bruteforce.reset)
callback.new('anti_bruteforce::client_discon', 'client_disconnect', anti_bruteforce.reset)
callback.new('anti_bruteforce::round_start', 'round_start', anti_bruteforce.reset)
callback.new('anti_bruteforce::round_end', 'round_end', anti_bruteforce.reset)

hitlogs.z = function () visual_controller.notifications:clear() end

callback.new('hlo::discon', 'cs_game_disconnected', hitlogs.z)
callback.new('hlo::new_map', 'game_newmap', hitlogs.z)
callback.new('hlo::client_discon', 'client_disconnect', hitlogs.z)

callback.new('visuals::pidorz', 'paint', visual_controller.w)
callback.new('visuals::indicators', 'paint', visual_controller.inidcators)
callback.new('visuals::indicators', 'paint', visual_controller.manual)
callback.new('visuals::handle_draggables', 'paint_ui', g_drag.paint_ui)

callback.new('menu::visibility', 'paint_ui', menu.visibility)
callback.new('menu::restore', 'pre_config_save', menu.shutdown)
callback.new('menu::shutdown_vis', 'shutdown', menu.visibility_shutdown)
callback.new('menu::shutdown_cvar', 'shutdown', helpers.cvars_shutdown)

callback.new('configs::shutdown', 'shutdown', configs.shutdown)
configs.load_startup()

-- OSTANOVKA
 

Lua online compiler

Write, Run & Share Lua code online using OneCompiler's Lua online compiler for free. It's one of the robust, feature-rich online compilers for Lua language, running the latest Lua version 5.4. Getting started with the OneCompiler's Lua editor is easy and fast. The editor shows sample boilerplate code when you choose language as Lua and start coding.

Taking inputs (stdin)

OneCompiler's Lua online editor supports stdin and users can give inputs to programs using the STDIN textbox under the I/O tab. Following is a sample Lua program which takes name as input and prints hello message with your name.

name = io.read("*a")
print ("Hello ", name)

About Lua

Lua is a light weight embeddable scripting language which is built on top of C. It is used in almost all kind of applications like games, web applications, mobile applications, image processing etc. It's a very powerful, fast, easy to learn, open-source scripting language.

Syntax help

Variables

  • By default all the variables declared are global variables
  • If the variables are explicitly mentioned as local then they are local variables.
  • Lua is a dynamically typed language and hence only the values will have types not the variables.

Examples

-- global variables
a = 10

-- local variables

local x = 30
Value TypeDescription
numberRepresents numbers
stringRepresents text
nilDifferentiates values whether it has data or not
booleanValue can be either true or false
functionRepresents a sub-routine
userdataRepresents arbitary C data
threadRepresents independent threads of execution.
tableCan hold any value except nil

Loops

1. While:

While is also used to iterate a set of statements based on a condition. Usually while is preferred when number of iterations are not known in advance.

while(condition)
do
--code
end

2. Repeat-Until:

Repeat-Until is also used to iterate a set of statements based on a condition. It is very similar to Do-While, it is mostly used when you need to execute the statements atleast once.

repeat
   --code
until( condition )

3. For:

For loop is used to iterate a set of statements based on a condition.

for init,max/min value, increment
do
   --code
end

Functions

Function is a sub-routine which contains set of statements. Usually functions are written when multiple calls are required to same set of statements which increase re-usuability and modularity.

optional_function_scope function function_name( argument1, argument2, argument3........, argumentn)
--code
return params with comma seperated
end