kitty klient

kitty klient — a MooMoo.io client with adaptive zoom, fast autoheal, gear automation, combat tools, predictive placement, visual markers, manual quick builds, and a fully rebindable keyboard/mouse controls HUD.

Tendrás que instalar una extensión para tu navegador como Tampermonkey, Greasemonkey o Violentmonkey si quieres utilizar este script.

You will need to install an extension such as Tampermonkey or Violentmonkey to install this script.

Tendrás que instalar una extensión como Tampermonkey o Violentmonkey para instalar este script.

Necesitarás instalar una extensión como Tampermonkey o Userscripts para instalar este script.

Tendrás que instalar una extensión como Tampermonkey antes de poder instalar este script.

Necesitarás instalar una extensión para administrar scripts de usuario si quieres instalar este script.

(Ya tengo un administrador de scripts de usuario, déjame instalarlo)

Tendrás que instalar una extensión como Stylus antes de poder instalar este script.

Tendrás que instalar una extensión como Stylus antes de poder instalar este script.

Tendrás que instalar una extensión como Stylus antes de poder instalar este script.

Para poder instalar esto tendrás que instalar primero una extensión de estilos de usuario.

Para poder instalar esto tendrás que instalar primero una extensión de estilos de usuario.

Para poder instalar esto tendrás que instalar primero una extensión de estilos de usuario.

(Ya tengo un administrador de estilos de usuario, déjame instalarlo)

// ==UserScript==
// @name         kitty klient
// @author       Coder Guy
// @version      4.2.4
// @icon         https://static.wikia.nocookie.net/belugacinematicuniversefanon/images/6/6a/Beluga.jpg/revision/latest?cb=20231226224904
// @description  kitty klient — a MooMoo.io client with adaptive zoom, fast autoheal, gear automation, combat tools, predictive placement, visual markers, manual quick builds, and a fully rebindable keyboard/mouse controls HUD.
// @match        *://moomoo.io/*
// @match        *://*.moomoo.io/*
// @grant        none
// @run-at       document-start
// @namespace    thisisirrelevandandidontknowwhygreasyforkneedsthisanyways
// @license      MIT
// ==/UserScript==
 
(() => {
    "use strict";
 
    const MIN_VIEW_MULTIPLIER = 0.5;
    const MAX_VIEW_MULTIPLIER = 1 / 0.15;
    const ZOOM_STEP = 1.1;
    const TRACKPAD_PIXELS_PER_ZOOM_STEP = 360;
    const INDICATOR_ID = "moomoo-scroll-zoom-indicator";
    const HUD_ID = "moomoo-op-hud";
    const CHAT_HISTORY_ID = "kitty-klient-chat-history";
    const CHAT_HISTORY_COLLAPSED_KEY = "kitty-klient-chat-history-collapsed-v1";
    const HUD_STORAGE_KEY = "moomoo-op-hud-settings-v1";
    const KILL_MESSAGE_AUTO_MIGRATION_KEY = "kitty-klient-kill-message-auto-v1";
    const PLACEMENT_CORE_AUTO_MIGRATION_KEY = "kitty-klient-placement-core-auto-v3";
    const INSTA_HOTKEY_AUTO_MIGRATION_KEY = "kitty-klient-r-insta-auto-v1";
    const TAB_SYNC_BRIDGE_KEY = "kitty-klient-tab-sync-bridge-v1";
    const KITTY_KLIENT_VERSION = "4.2.4";
    const KITTY_AUX_PANELS_VISIBLE = true;
    const KITTY_TUTORIAL_ID = "kitty-klient-tutorial";
    const KITTY_TUTORIAL_COMPLETE_KEY = "kitty-klient-tutorial-complete-v1";
    const KITTY_HUD_LAUNCHER_ID = "kitty-klient-hud-launcher";
    const KITTY_UPDATE_POPUP_ID = "kitty-klient-update-popup";
    const KITTY_UPDATE_DISMISS_KEY = "kitty-klient-dismissed-update-v1";
    const KITTY_UPDATE_API = "https://api.greasyfork.org/en/scripts/592072.json";
    const KITTY_UPDATE_FALLBACK_URL = "https://update.greasyfork.org/scripts/592072/kitty%20klient.user.js";

    function installKittyUpgradeModuleUnlock() {
        if (window.__KittyUpgradeModuleUnlockInstalled) return;
        window.__KittyUpgradeModuleUnlockInstalled = true;
        const nativeCall = Function.prototype.call;
        let callProxy = null;
        const restoreCall = () => {
            if (Function.prototype.call === callProxy) Function.prototype.call = nativeCall;
            if (!window.__KittyUpgradeModuleData)
                window.__KittyUpgradeModuleUnlockInstalled = false;
        };
        const unlockData = (data) => {
            if (!data || !Array.isArray(data.weapons) || !Array.isArray(data.list)) return false;
            if (!window.__KittyVanillaUpgradePrerequisites) {
                window.__KittyVanillaUpgradePrerequisites = {
                    weapons: data.weapons.map((entry) => entry && entry.pre),
                    items: data.list.map((entry) => entry && entry.pre)
                };
            }
            data.weapons.forEach((entry) => {
                if (entry && entry.pre != null) entry.pre = null;
            });
            data.list.forEach((entry) => {
                if (entry && entry.pre != null) entry.pre = null;
            });
            window.__KittyUpgradeModuleData = data;
            return true;
        };
        callProxy = new Proxy(nativeCall, {
            apply(target, thisArg, args) {
                try {
                    // Intercept the MooMoo item-data module loader here. Keep
                    // the interception narrow and restore the
                    // native prototype immediately after item module 45 loads.
                    if (args[1] && Number(args[1].i) === 21 && typeof args[3] === "function") {
                        const moduleGetter = args[3];
                        args[3] = function (id) {
                            const data = Reflect.apply(moduleGetter, this, arguments);
                            if (Number(id) === 45 && unlockData(data)) {
                                args[3] = moduleGetter;
                                restoreCall();
                            }
                            return data;
                        };
                    }
                } catch (_) {
                    // The injected runtime has a direct data-module fallback.
                }
                return Reflect.apply(target, thisArg, args);
            }
        });
        Function.prototype.call = callProxy;
        window.setTimeout(restoreCall, 12000);
    }
    const KITTY_BINDING_ACTIONS = Object.freeze([
        Object.freeze({ id: "toggleHud", group: "Menu & view", binding: "Escape", action: "Toggle Kitty HUD", note: "Closes MooMoo shop, clan, or chat first when one is open." }),
        Object.freeze({ id: "primaryAttack", group: "Combat & gear", binding: "Mouse0", action: "Primary attack", note: "Held attack with Kitty's Bull and tail timing.", hold: true }),
        Object.freeze({ id: "secondaryAttack", group: "Combat & gear", binding: "Mouse2", action: "Secondary attack / Tank", note: "Held secondary or situational Shield/Tank path.", hold: true }),
        Object.freeze({ id: "clickBoostInsta", group: "Combat & gear", binding: "Shift+Mouse0", action: "Click Boost Insta", note: "Starts Boost Insta when ready; otherwise continues as a primary hold.", hold: true }),
        Object.freeze({ id: "normalInsta", group: "Combat & gear", binding: "KeyR", action: "Normal Insta", note: "Runs the selected full Insta profile or Bush manual ambush." }),
        Object.freeze({ id: "boostInsta", group: "Combat & gear", binding: "Shift+KeyR", action: "Boost Insta", note: "Requires the Crossbow Insta kit." }),
        Object.freeze({ id: "oneTickInsta", group: "Combat & gear", binding: "Shift+KeyP", action: "Toggle One-Tick Insta", note: "Toggles the secondary-first one-tick profile." }),
        Object.freeze({ id: "velTickInsta", group: "Combat & gear", binding: "KeyT", action: "Toggle VelTick Insta", note: "Toggles predictive spacing and Turret/Polearm timing." }),
        Object.freeze({ id: "boostSpike", group: "Combat & gear", binding: "KeyG", action: "Boost + Spike", note: "Continuously solves legal contact spikes while held.", hold: true }),
        Object.freeze({ id: "quadTrap", group: "Combat & gear", binding: "Shift+KeyB", action: "Manual Quad Trap", note: "Forces one legal four-slot trap solve." }),
        Object.freeze({ id: "quadSpike", group: "Combat & gear", binding: "Shift+KeyC", action: "Manual Quad Spike", note: "Forces one legal four-slot spike solve." }),
        Object.freeze({ id: "betrayalInsta", group: "Combat & gear", binding: "Shift+KeyT", action: "Betrayal Insta", note: "Leaves the team and attacks the nearest eligible player." }),
        Object.freeze({ id: "toggleAutoHeal", group: "Combat & gear", binding: "KeyP", action: "Toggle Autoheal", note: "Changes Autoheal without opening the HUD." }),
        Object.freeze({ id: "food", group: "Building & supplies", binding: "KeyQ", action: "Food", note: "Repeatedly uses the current food while held.", hold: true }),
        Object.freeze({ id: "trapBuild", group: "Building & supplies", binding: "KeyF", action: "Pit trap", note: "Repeatedly places the current trap while held.", hold: true }),
        Object.freeze({ id: "spikeBuild", group: "Building & supplies", binding: "KeyV", action: "Spike", note: "Repeatedly places the current spike while held.", hold: true }),
        Object.freeze({ id: "specialBuild", group: "Building & supplies", binding: "KeyH", action: "Special deployable", note: "Repeats the active turret, teleporter, pad, platform, or blocker.", hold: true }),
        Object.freeze({ id: "boostBreak", group: "Building & supplies", binding: "Shift+KeyF", action: "Boost-break", note: "Boosts forward and destroys each pad behind you while held.", hold: true }),
        Object.freeze({ id: "movingMills", group: "Modes & automation", binding: "KeyZ", action: "Toggle moving three-mill", note: "Primary Automill toggle." }),
        Object.freeze({ id: "movingMillsAlt", group: "Modes & automation", binding: "KeyN", action: "Toggle moving three-mill (alternate)", note: "Second independently editable Automill shortcut." }),
        Object.freeze({ id: "bushMode", group: "Modes & automation", binding: "KeyB", action: "Toggle Bush ambush", note: "Purchases and holds Bush Gear when possible." }),
        Object.freeze({ id: "cleanup", group: "Modes & automation", binding: "KeyC", action: "Toggle Cleanup", note: "Starts or stops automatic nearby breakable cleanup." }),
        Object.freeze({ id: "friendPick", group: "Friends & teammate sync", binding: "KeyU", action: "Add friend", note: "Arms click-to-friend selection for a non-teammate." }),
        Object.freeze({ id: "enemyPick", group: "Friends & teammate sync", binding: "KeyI", action: "Mark enemy", note: "Arms click-to-enemy selection." }),
        Object.freeze({ id: "syncPick", group: "Friends & teammate sync", binding: "KeyY", action: "Select sync teammate", note: "Arms click-to-sync selection for a teammate." })
    ]);
    const KITTY_DEFAULT_KEYBINDS = Object.freeze(Object.fromEntries(
        KITTY_BINDING_ACTIONS.map((entry) => [entry.id, entry.binding])
    ));
    const HUD_DEFAULTS = Object.freeze({
        autoHeal: true,
        soldierAuto: true,
        movementGear: true,
        trapEscape: true,
        automaticStateRepair: true,
        autoAcceptTeamRequests: false,
        autoDeclineTeamRequests: false,
        autoRespawn: false,
        antiBoostInsta: true,
        antiInsta: true,
        antiCollision: true,
        antiCollisionPauseCombat: true,
        shieldDefense: true,
        placementDefense: true,
        antiRetrapPush: true,
        teammateTrapRescue: true,
        turretSteal: true,
        spikeGearCounter: true,
        dashMovement: true,
        musketRecharge: true,
        autoPurchase: false,
        matThief: false,
        multiTargetBreak: true,
        mobSteal: false,
        assassinAutomation: false,
        spinningWindmills: false,
        forceFullServers: true,
        bushMode: false,
        fpsBoost: true,
        smoothVisuals: true,
        reloadArcs: true,
        entityDanger: true,
        notificationTracers: true,
        groundGrid: false,
        esp: true,
        espLines: true,
        predictionGhost: true,
        placementVisuals: true,
        cooldownBars: true,
        weaponXpBar: true,
        chatHistory: true,
        combatTelemetry: false,
        telemetryProjectileHits: true,
        telemetrySpikeKnockback: true,
        telemetryActualAim: true,
        telemetryBuildingOwners: true,
        telemetryShameCount: true,
        telemetryDamageHealing: true,
        enemyColor: "#ff4d5d",
        allyColor: "#a855f7",
        friendColor: "#facc15",
        ownColor: "#d8b4fe",
        bullHelmet: true,
        tankRightClick: true,
        instaKill: true,
        autoInsta: true,
        autoBowUpgradeInsta: false,
        reverseInsta: false,
        oneTickInsta: false,
        appleInsta: false,
        bleedInsta: false,
        knockbackInsta: false,
        velTickInsta: false,
        polearmAids: false,
        autoPushInsta: false,
        boostSpikeKill: true,
        autoTrapInsta: true,
        autoSpikeInsta: true,
        autoSpikeSpam: false,
        autoSpikeKill: false,
        animalTrap: false,
        passiveMobTrap: false,
        bossTeleporter: false,
        smartAutoPlace: true,
        smartPreplace: true,
        smartMultiPlace: true,
        smartQuadTraps: true,
        smartQuadSpikes: true,
        smartSpikeContact: true,
        smartTrapContact: true,
        smartKnockbackChain: true,
        smartTrapSurround: true,
        smartAngleDenial: true,
        smartAutoPushWeight: true,
        smartAutoReplace: false,
        smartSpikeSyncPlace: false,
        smartAntiBoostPlace: false,
        smartMovingMills: false,
        smartInstaUtilityPlace: false,
        instaSync: true,
        boostBreak: true,
        boostChat: true,
        materialReply: true,
        meowChainInsta: true,
        instaChat: true,
        bushChat: true,
        friendAddedChat: true,
        enemyMarkedChat: true,
        cleanupProgressChat: true,
        cleanupCompleteChat: true,
        modReplyChat: true,
        enemyTrapChat: true,
        friendTrapChat: true,
        trapAlertChat: true,
        deathHistoryChat: true,
        syncStatusChat: true,
        syncMovement: true,
        syncCopyWeapons: true,
        syncCopyBuilds: true,
        syncCopyGear: true,
        syncCopyAim: true,
        syncCopyAttacks: true,
        syncCatchupGear: true,
        syncPauseInCombat: false,
        syncWasdCombatOnly: true,
        syncTickCombat: true,
        syncFollowGap: 12,
        syncStopTolerance: 4,
        syncResumeTolerance: 9,
        syncPredictionMs: 130,
        syncCatchupDistance: 420,
        syncCatchupReleaseDistance: 190,
        syncMoveRefreshMs: 50,
        syncRelayUrl: "",
        syncRoom: "",
        syncStatus: "Sync off",
        syncTargetName: "",
        soldierRange: 400,
        combatRange: 400,
        gearHoldTicks: 3,
        antiBoostRange: 200,
        antiCollisionRange: 260,
        reactionMs: 25,
        adaptiveSmartness: true,
        smartDepth: 5,
        smartPlaceAccuracy: 50,
        smartMaxPlacements: 4,
        smartPlaceDelay: 111,
        assassinSafeMs: 2000,
        assassinMinHealth: 80,
        assassinDangerRange: 650,
        debugPanel: false,
        killMessageEnabled: true,
        killMessage: "gg",
        friendNames: [],
        keybinds: KITTY_DEFAULT_KEYBINDS
    });
    const HUD_BOOLEAN_KEYS = Object.freeze([
        "autoHeal",
        "soldierAuto",
        "movementGear",
        "trapEscape",
        "automaticStateRepair",
        "autoAcceptTeamRequests",
        "autoDeclineTeamRequests",
        "autoRespawn",
        "antiBoostInsta",
        "antiInsta",
        "antiCollision",
        "antiCollisionPauseCombat",
        "shieldDefense",
        "placementDefense",
        "antiRetrapPush",
        "teammateTrapRescue",
        "turretSteal",
        "spikeGearCounter",
        "dashMovement",
        "musketRecharge",
        "autoPurchase",
        "matThief",
        "multiTargetBreak",
        "mobSteal",
        "assassinAutomation",
        "spinningWindmills",
        "forceFullServers",
        "bushMode",
        "fpsBoost",
        "smoothVisuals",
        "reloadArcs",
        "entityDanger",
        "notificationTracers",
        "groundGrid",
        "esp",
        "espLines",
        "predictionGhost",
        "placementVisuals",
        "cooldownBars",
        "weaponXpBar",
        "chatHistory",
        "combatTelemetry",
        "telemetryProjectileHits",
        "telemetrySpikeKnockback",
        "telemetryActualAim",
        "telemetryBuildingOwners",
        "telemetryShameCount",
        "telemetryDamageHealing",
        "bullHelmet",
        "tankRightClick",
        "instaKill",
        "autoInsta",
        "autoBowUpgradeInsta",
        "reverseInsta",
        "oneTickInsta",
        "appleInsta",
        "bleedInsta",
        "knockbackInsta",
        "velTickInsta",
        "polearmAids",
        "autoPushInsta",
        "boostSpikeKill",
        "autoTrapInsta",
        "autoSpikeInsta",
        "autoSpikeSpam",
        "autoSpikeKill",
        "animalTrap",
        "passiveMobTrap",
        "bossTeleporter",
        "smartAutoPlace",
        "smartPreplace",
        "smartMultiPlace",
        "smartQuadTraps",
        "smartQuadSpikes",
        "smartSpikeContact",
        "smartTrapContact",
        "smartKnockbackChain",
        "smartTrapSurround",
        "smartAngleDenial",
        "smartAutoPushWeight",
        "smartAutoReplace",
        "smartSpikeSyncPlace",
        "smartAntiBoostPlace",
        "smartMovingMills",
        "smartInstaUtilityPlace",
        "adaptiveSmartness",
        "instaSync",
        "boostBreak",
        "boostChat",
        "materialReply",
        "meowChainInsta",
        "instaChat",
        "bushChat",
        "friendAddedChat",
        "enemyMarkedChat",
        "cleanupProgressChat",
        "cleanupCompleteChat",
        "modReplyChat",
        "enemyTrapChat",
        "friendTrapChat",
        "trapAlertChat",
        "deathHistoryChat",
        "syncStatusChat",
        "syncMovement",
        "syncCopyWeapons",
        "syncCopyBuilds",
        "syncCopyGear",
        "syncCopyAim",
        "syncCopyAttacks",
        "syncCatchupGear",
        "syncPauseInCombat",
        "syncWasdCombatOnly",
        "syncTickCombat",
        "debugPanel",
        "killMessageEnabled"
    ]);
    const HUD_NUMERIC_BOUNDS = Object.freeze({
        soldierRange: Object.freeze({ min: 100, max: 1000, step: 10 }),
        combatRange: Object.freeze({ min: 100, max: 1000, step: 10 }),
        gearHoldTicks: Object.freeze({ min: 1, max: 8, step: 1 }),
        antiBoostRange: Object.freeze({ min: 80, max: 500, step: 10 }),
        antiCollisionRange: Object.freeze({ min: 120, max: 500, step: 10 }),
        reactionMs: Object.freeze({ min: 10, max: 100, step: 5 }),
        smartDepth: Object.freeze({ min: 1, max: 10, step: 1 }),
        smartPlaceAccuracy: Object.freeze({ min: 20, max: 180, step: 5 }),
        smartMaxPlacements: Object.freeze({ min: 1, max: 4, step: 1 }),
        smartPlaceDelay: Object.freeze({ min: 0, max: 222, step: 1 }),
        assassinSafeMs: Object.freeze({ min: 500, max: 5000, step: 100 }),
        assassinMinHealth: Object.freeze({ min: 20, max: 100, step: 5 }),
        assassinDangerRange: Object.freeze({ min: 250, max: 1200, step: 25 }),
        syncFollowGap: Object.freeze({ min: 2, max: 120, step: 1 }),
        syncStopTolerance: Object.freeze({ min: 1, max: 30, step: 1 }),
        syncResumeTolerance: Object.freeze({ min: 2, max: 60, step: 1 }),
        syncPredictionMs: Object.freeze({ min: 0, max: 300, step: 5 }),
        syncCatchupDistance: Object.freeze({ min: 100, max: 1200, step: 10 }),
        syncCatchupReleaseDistance: Object.freeze({ min: 50, max: 800, step: 10 }),
        syncMoveRefreshMs: Object.freeze({ min: 16, max: 250, step: 1 })
    });
    const GAME_BUNDLE = /\/assets\/index-[\w-]+\.js(?:\?.*)?$/;
    const VIEWPORT_MARKER = "const _=y.maxScreenWidth,L=y.maxScreenHeight;";
    const HOTKEY_MARKER = "t==69?wl():t==67?tl():t==88?gl():";
    const FOOD_HOTKEY_MARKER = "t==81?je(v.items[0]):";
    const FOOD_KEYUP_MARKER = "function pl(e){if(v&&v.alive){const t=e.which||e.keyCode||0;";
    const MOVEMENT_KEYDOWN_MARKER = "bt[t]?Tt():t==32&&(U=1,ke())";
    const MOVEMENT_KEYUP_MARKER = "bt[t]?Tt():t==32&&(U=0,ke())";
    const NATIVE_GROUND_GRID_MARKER = 'k.lineWidth=4,k.strokeStyle="#000",k.globalAlpha=.06,k.beginPath();for(var i=-oe;i<_;i+=L/18)i>0&&(k.moveTo(i,0),k.lineTo(i,L));for(let c=-ae;c<L;c+=L/18)i>0&&(k.moveTo(0,c),k.lineTo(_,c));k.stroke(),';
    // The HUD kill-message hook wraps this local game function. Validate it before
    // injecting so a renamed game bundle falls back cleanly instead of half-loading.
    const PLAYER_STAT_UPDATE_MARKER = "function Kl(";
    const CHAT_DISPLAY_MARKER = "function dl(";
    // __mmInsta depends on both functions below to bind a target by SID and
    // to coexist with the game's normal attack dispatch. Missing either means
    // the complete patched bundle is abandoned in favor of the original.
    const INSTA_PLAYER_LOOKUP_MARKER = "function Rt(";
    const INSTA_PLAYER_ATTACK_MARKER = "function Pl(";
    const FORCE_FULL_DIRECT_MARKER = 's.playerCount>=s.playerCapacity){this.errorCallback("Server is already full.");return}';
    const FORCE_FULL_FILTER_MARKER = ".filter(function(h){return h.playerCount<n})";
    const FORCE_FULL_AUTO_MARKER = "e=e.filter(n=>n.playerCount!==n.playerCapacity)";
    const FORCE_FULL_SPAWN_MARKER = "moofoll:xt";
    const BUNDLE_RETRY_LIMIT = 8;
    const BUNDLE_RETRY_DELAY_MS = 250;
    const PATCHED_MODULE_RETRY_LIMIT = 3;
    let viewMultiplier = 1 / 0.75;
    let hideIndicatorTimer = 0;
    let gameScriptHijacked = false;
    let originalBundleLoaded = false;
    let restoreBundleInsertionGuards = () => {};
    let hudMounted = false;
    let hudSettingsSent = false;
    let hudState = readHudSettings();
    let hudOpen = false;
    let kittyTutorialIndex = 0;
    let kittyTutorialActive = false;
    let kittyTutorialHudWasOpen = false;
    let hotkeyCaptureAction = null;
    let hotkeyCaptureButton = null;
    const chatHistoryEntries = [];
    const hudControls = new Map();
    window.__MooMooScrollZoomMultiplier = viewMultiplier;
    window.__KittySmartAutoPlace = hudState.smartAutoPlace !== false;
    applyForceFullServersPreference(hudState.forceFullServers);
    document.documentElement &&
      !document.documentElement.hasAttribute("data-kitty-spinning-windmills") &&
      document.documentElement.setAttribute("data-kitty-spinning-windmills", "0");

    installKittyClanPingSocketObserver();

    // Arm the game-bundle interception before theme installation, HUD work, or
    // any optional network request. This userscript is intentionally large;
    // waiting until its final lines left a first-navigation race where the
    // outer UI loaded but MooMoo's original module escaped unpatched.
    installSynchronousBundleGuards();

    const gameBundleObserver = new MutationObserver((records) => {
        for (const record of records) {
            for (const node of record.addedNodes) {
                if (node.nodeType === Node.ELEMENT_NODE && node.tagName === "SCRIPT") {
                    interceptGameBundle(node);
                } else if (node.nodeType === Node.ELEMENT_NODE && node.querySelectorAll) {
                    node.querySelectorAll("script[src]").forEach(interceptGameBundle);
                }
            }
        }
    });

    gameBundleObserver.observe(document, { childList: true, subtree: true });
    document.querySelectorAll("script[src]").forEach(interceptGameBundle);

    // Firefox exposes a cancellable last-chance event for parser-inserted
    // scripts. Chromium simply ignores this listener and uses the synchronous
    // DOM guards plus the observer above.
    document.addEventListener("beforescriptexecute", (event) => {
        const script = event.target;
        if (script instanceof HTMLScriptElement && interceptGameBundle(script)) {
            event.preventDefault();
            event.stopImmediatePropagation();
        }
    }, true);

    document.addEventListener("readystatechange", () => {
        if (!gameScriptHijacked && document.readyState === "interactive") {
            document.querySelectorAll("script[src]").forEach(interceptGameBundle);
        }
    }, { once: true });

    window.addEventListener("load", () => {
        // If the page never produced the MooMoo module, stop wrapping DOM APIs.
        // Normal successful interception restores them immediately in claimGameBundle.
        if (!gameScriptHijacked) restoreBundleInsertionGuards();
    }, { once: true });

    function decodeKittyMessagePack(input) {
        const bytes = input instanceof Uint8Array
            ? input
            : new Uint8Array(input.buffer || input, input.byteOffset || 0, input.byteLength);
        const view = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);
        const decoder = new TextDecoder();
        let offset = 0;
        const take = (length) => {
            if (offset + length > bytes.length) throw new RangeError("short packet");
            const start = offset;
            offset += length;
            return start;
        };
        const text = (length) => {
            const start = take(length);
            return decoder.decode(bytes.subarray(start, start + length));
        };
        const array = (length) => {
            const value = new Array(length);
            for (let index = 0; index < length; index += 1) value[index] = read();
            return value;
        };
        const map = (length) => {
            const value = {};
            for (let index = 0; index < length; index += 1) value[String(read())] = read();
            return value;
        };
        const read = () => {
            const code = view.getUint8(take(1));
            if (code <= 0x7f) return code;
            if (code >= 0xe0) return code - 0x100;
            if (code >= 0xa0 && code <= 0xbf) return text(code & 0x1f);
            if (code >= 0x90 && code <= 0x9f) return array(code & 0x0f);
            if (code >= 0x80 && code <= 0x8f) return map(code & 0x0f);
            let start;
            switch (code) {
                case 0xc0: return null;
                case 0xc2: return false;
                case 0xc3: return true;
                case 0xca: start = take(4); return view.getFloat32(start);
                case 0xcb: start = take(8); return view.getFloat64(start);
                case 0xcc: return view.getUint8(take(1));
                case 0xcd: start = take(2); return view.getUint16(start);
                case 0xce: start = take(4); return view.getUint32(start);
                case 0xcf:
                    start = take(8);
                    return Number(view.getBigUint64(start));
                case 0xd0: return view.getInt8(take(1));
                case 0xd1: start = take(2); return view.getInt16(start);
                case 0xd2: start = take(4); return view.getInt32(start);
                case 0xd3:
                    start = take(8);
                    return Number(view.getBigInt64(start));
                case 0xd9: return text(view.getUint8(take(1)));
                case 0xda: start = take(2); return text(view.getUint16(start));
                case 0xdb: start = take(4); return text(view.getUint32(start));
                case 0xdc: start = take(2); return array(view.getUint16(start));
                case 0xdd: start = take(4); return array(view.getUint32(start));
                case 0xde: start = take(2); return map(view.getUint16(start));
                case 0xdf: start = take(4); return map(view.getUint32(start));
                default: throw new TypeError("unsupported packet value " + code);
            }
        };
        return read();
    }

    function observeKittyClanPingPacket(rawData) {
        if (typeof rawData === "string") return;
        if (typeof Blob === "function" && rawData instanceof Blob) {
            rawData.arrayBuffer().then(observeKittyClanPingPacket).catch(() => {});
            return;
        }
        if (!(rawData instanceof ArrayBuffer) && !ArrayBuffer.isView(rawData)) return;
        try {
            const packet = decodeKittyMessagePack(rawData);
            // Incoming packet 9 is MooMoo's teammate minimap distress ping.
            // Packet p is unrelated and previously produced false top-left
            // alerts when its payload happened to resemble two coordinates.
            if (!Array.isArray(packet) || String(packet[0]) !== "9") return;
            const payload = packet.length === 2 && Array.isArray(packet[1])
                ? packet[1]
                : packet.slice(1);
            const coordinates = payload.length === 1 && payload[0] &&
                typeof payload[0] === "object" && !Array.isArray(payload[0])
                ? payload[0]
                : payload;
            const x = Number(coordinates.x ?? coordinates[0]);
            const y = Number(coordinates.y ?? coordinates[1]);
            if (!Number.isFinite(x) || !Number.isFinite(y)) return;
            window.dispatchEvent(new CustomEvent("MooMooKittyClanPing", {
                detail: { x, y, at: Date.now() }
            }));
        } catch (_) {}
    }

    function installKittyClanPingSocketObserver() {
        if (window.__KittyClanPingSocketObserver || typeof WebSocket !== "function") return;
        const NativeWebSocket = window.WebSocket;
        function KittyObservedWebSocket(...args) {
            const socket = Reflect.construct(NativeWebSocket, args, NativeWebSocket);
            socket.addEventListener("message", (event) => observeKittyClanPingPacket(event.data));
            return socket;
        }
        Object.setPrototypeOf(KittyObservedWebSocket, NativeWebSocket);
        KittyObservedWebSocket.prototype = NativeWebSocket.prototype;
        try {
            window.WebSocket = KittyObservedWebSocket;
            window.__KittyClanPingSocketObserver = true;
        } catch (_) {}
    }

    function installCanvasTextTheme() {
        const prototype = window.CanvasRenderingContext2D && CanvasRenderingContext2D.prototype;
        if (!prototype || prototype.__kittyKlientTextTheme) return;
        Object.defineProperty(prototype, "__kittyKlientTextTheme", { value: true });
        ["fillText", "strokeText"].forEach((method) => {
            const original = prototype[method];
            if (typeof original !== "function") return;
            prototype[method] = function (...args) {
                const previousShadowColor = this.shadowColor;
                const previousShadowBlur = this.shadowBlur;
                const previousFillStyle = this.fillStyle;
                try {
                    this.shadowColor = "#8b5cf6";
                    this.shadowBlur = Math.max(8, Number(this.shadowBlur) || 0);
                    if (method === "fillText") {
                        const current = String(previousFillStyle || "").replace(/\s+/g, "").toLowerCase();
                        const dark = current === "#000" || current === "#000000" || current === "black" ||
                            /^rgba?\((?:0,){2}0(?:,|\))/.test(current);
                        this.fillStyle = dark ? "#050505" : "#ffffff";
                    }
                    return original.apply(this, args);
                } finally {
                    this.shadowColor = previousShadowColor;
                    this.shadowBlur = previousShadowBlur;
                    this.fillStyle = previousFillStyle;
                }
            };
        });
    }

    function applyKittyNameTrademark() {
        const input = document.getElementById("nameInput");
        if (!input) return;
        const prefix = "k-";
        const storedOriginal = Number(input.dataset.kittyOriginalNameMax);
        const originalMax = Number.isFinite(storedOriginal) && storedOriginal > 2
            ? storedOriginal
            : Math.max(3, Number(input.maxLength) || 15);
        const nameLimit = Math.max(1, originalMax - 2);
        input.dataset.kittyOriginalNameMax = String(originalMax);
        input.dataset.kittyNameLimit = String(nameLimit);
        input.maxLength = originalMax;
        input.setAttribute("maxlength", String(originalMax));
        input.placeholder = "k-Your Name";
        const normalize = () => {
            const normalized = prefix + String(input.value || "")
                .replace(/^(?:k-)+/i, "")
                .slice(0, nameLimit);
            if (input.value !== normalized) input.value = normalized;
            if (
                document.activeElement === input &&
                input.selectionStart != null &&
                input.selectionEnd != null &&
                input.selectionStart < prefix.length &&
                input.selectionEnd < prefix.length
            )
                input.setSelectionRange(prefix.length, prefix.length);
        };
        normalize();
        if (!input.dataset.kittyNameTrademarkBound) {
            input.dataset.kittyNameTrademarkBound = "1";
            input.addEventListener("input", normalize);
            input.addEventListener("change", normalize);
            const protectPrefix = (event) => {
                const start = Number(input.selectionStart),
                    end = Number(input.selectionEnd),
                    inputType = String(event.inputType || ""),
                    touchesPrefix = start < prefix.length ||
                        (inputType === "deleteContentBackward" &&
                            start === prefix.length && end === start);
                if (!Number.isFinite(start) || !Number.isFinite(end) || !touchesPrefix)
                    return;
                if (!inputType.startsWith("delete") && !inputType.startsWith("insert"))
                    return;
                event.preventDefault();
                const insertion = inputType.startsWith("insert")
                    ? String(event.data || (event.dataTransfer && event.dataTransfer.getData("text/plain")) || "")
                    : "";
                input.setRangeText(insertion, prefix.length, Math.max(prefix.length, end), "end");
                normalize();
                input.dispatchEvent(new Event("input", { bubbles: true }));
            };
            const clampCaret = () => {
                normalize();
                if (
                    input.selectionStart != null &&
                    input.selectionEnd != null &&
                    input.selectionStart === input.selectionEnd &&
                    input.selectionStart < prefix.length
                )
                    input.setSelectionRange(prefix.length, prefix.length);
            };
            input.addEventListener("beforeinput", protectPrefix);
            input.addEventListener("focus", clampCaret);
            input.addEventListener("click", clampCaret);
            input.addEventListener("keyup", clampCaret);
        }
    }

    const KITTY_TUTORIAL_STEPS = Object.freeze([
        Object.freeze({
            phase: "menu",
            target: "#gameName,[data-kitty-brand]",
            eyebrow: "Welcome",
            title: "Meet kitty klient",
            copy: "Kitty adds automation, combat helpers, visual tools, teammate sync, and a full control HUD while keeping MooMoo's normal menu available."
        }),
        Object.freeze({
            phase: "menu",
            target: "#nameInput",
            eyebrow: "Your name",
            title: "The k- tag is automatic",
            copy: "Type the part of your name after k-. The prefix is shown in the box, cannot be deleted, and is included when you enter the game."
        }),
        Object.freeze({
            phase: "menu",
            target: "#enterGame",
            eyebrow: "Start playing",
            title: "Play normally from here",
            copy: "Pick a server and press Play when ready. Starting the game closes this guide; you can replay it from the Tutorial button at any time."
        }),
        Object.freeze({
            phase: "menu",
            target: "#kitty-klient-home-tutorial",
            eyebrow: "Replay",
            title: "Tutorial stays available",
            copy: "The automatic tour only appears for first-time users. This button always starts it again without resetting any of your settings."
        }),
        Object.freeze({
            phase: "hud",
            page: "automation",
            target: "#moomoo-op-hud .mm-hud-panel",
            eyebrow: "Esc HUD",
            title: "Escape opens the control center",
            copy: "Esc or the in-game Menu button opens Kitty's HUD. Use Esc or × to close it. If shop, clan, or chat is open, Esc closes that first."
        }),
        Object.freeze({
            phase: "hud",
            page: "automation",
            target: "#moomoo-op-hud [data-page='automation'].mm-hud-page",
            eyebrow: "Automation",
            title: "Survival and utility controls",
            copy: "Configure healing, gear, trap escape, threat placement, weapon recharge, purchases, cleanup helpers, and other background behavior here."
        }),
        Object.freeze({
            phase: "hud",
            page: "combat",
            target: "#moomoo-op-hud [data-page='combat'].mm-hud-page",
            eyebrow: "Combat",
            title: "Combos, defense, and friends",
            copy: "This page controls Insta paths, spike prediction, anti-insta, boost tools, and friend targeting. Hover any option for a more exact explanation."
        }),
        Object.freeze({
            phase: "hud",
            page: "visuals",
            target: "#moomoo-op-hud [data-page='visuals'].mm-hud-page",
            eyebrow: "Visuals",
            title: "Choose what Kitty draws",
            copy: "Player markers, connection lines, prediction ghosts, stacked chat bubbles, and primary, secondary, and Turret Gear cooldown bars can be enabled independently."
        }),
        Object.freeze({
            phase: "hud",
            page: "sync",
            target: "#moomoo-op-hud [data-page='sync'].mm-hud-page",
            eyebrow: "Sync",
            title: "Follow and fight with a teammate",
            copy: "Press Y and click a teammate for a one-way follow. They only follow you back if they also press Y and click you; exact cross-client combat timing requires matching Kitty relay settings."
        }),
        Object.freeze({
            phase: "hud",
            page: "config",
            target: "#moomoo-op-hud [data-page='config'].mm-hud-page",
            eyebrow: "Config",
            title: "Tune behavior and messages",
            copy: "Adjust ranges and reaction speed, inspect diagnostics, choose each automated chat message, and reset saved settings from this page."
        }),
        Object.freeze({
            phase: "hud",
            page: "hotkeys",
            target: "#moomoo-op-hud [data-page='hotkeys'].mm-hud-page",
            eyebrow: "Hotkey library",
            title: "Every shortcut is editable",
            copy: "Click a Kitty keycap, then press any keyboard key or mouse button with the modifiers you want. Conflicts swap safely, and each action can be reset independently."
        }),
        Object.freeze({
            phase: "hud",
            page: "hotkeys",
            target: "#moomoo-op-hud .mm-hud-brand",
            eyebrow: "Ready",
            title: "You're ready to play",
            copy: "Use Back to revisit anything, Finish to complete onboarding, or Stop for now. The guide only opens when you press a Tutorial button."
        })
    ]);

    function kittyTutorialIsComplete() {
        try {
            return localStorage.getItem(KITTY_TUTORIAL_COMPLETE_KEY) === "1";
        } catch {
            return false;
        }
    }

    function setKittyTutorialComplete() {
        try {
            localStorage.setItem(KITTY_TUTORIAL_COMPLETE_KEY, "1");
        } catch {
            // Completion remains valid for this page when storage is blocked.
        }
    }

    function setKittyHudOpen(open) {
        hudOpen = Boolean(open);
        if (document.documentElement)
            document.documentElement.setAttribute("data-kitty-hud-open", hudOpen ? "1" : "0");
        window.dispatchEvent(new CustomEvent("MooMooKittyHudVisibility", { detail: hudOpen }));
        const root = document.getElementById(HUD_ID);
        if (!root) return;
        root.classList.toggle("mm-hud-collapsed", !hudOpen);
        root.setAttribute("aria-hidden", String(!hudOpen));
        const launcher = document.getElementById(KITTY_HUD_LAUNCHER_ID);
        if (launcher) {
            launcher.setAttribute("aria-expanded", String(hudOpen));
            launcher.classList.toggle("kitty-hud-open", hudOpen);
        }
    }

    function positionKittyTutorial() {
        const root = document.getElementById(KITTY_TUTORIAL_ID);
        if (!root || !kittyTutorialActive) return;
        const step = KITTY_TUTORIAL_STEPS[kittyTutorialIndex];
        const spotlight = root.querySelector(".kitty-tutorial-spotlight");
        const card = root.querySelector(".kitty-tutorial-card");
        const target = step && step.target ? document.querySelector(step.target) : null;
        if (!spotlight || !card) return;
        if (!target || !target.getClientRects().length) {
            spotlight.hidden = true;
            card.style.left = "50%";
            card.style.top = "50%";
            card.style.transform = "translate(-50%,-50%)";
            return;
        }
        const bounds = target.getBoundingClientRect();
        spotlight.hidden = false;
        spotlight.style.left = Math.max(6, bounds.left - 8) + "px";
        spotlight.style.top = Math.max(6, bounds.top - 8) + "px";
        spotlight.style.width = Math.max(24, Math.min(window.innerWidth - 12, bounds.width + 16)) + "px";
        spotlight.style.height = Math.max(24, Math.min(window.innerHeight - 12, bounds.height + 16)) + "px";
        card.style.transform = "none";
        const cardBounds = card.getBoundingClientRect();
        let left = bounds.left + bounds.width / 2 - cardBounds.width / 2;
        left = Math.max(12, Math.min(window.innerWidth - cardBounds.width - 12, left));
        let top = bounds.bottom + 18;
        if (top + cardBounds.height > window.innerHeight - 12)
            top = bounds.top - cardBounds.height - 18;
        if (top < 12) top = window.innerHeight - cardBounds.height - 18;
        card.style.left = left + "px";
        card.style.top = Math.max(12, top) + "px";
    }

    function showKittyTutorialStep() {
        const root = document.getElementById(KITTY_TUTORIAL_ID);
        const step = KITTY_TUTORIAL_STEPS[kittyTutorialIndex];
        if (!root || !step) return;
        if (step.phase === "hud") {
            setKittyHudOpen(true);
            if (step.page) {
                const button = document.querySelector("#" + HUD_ID + " .mm-hud-nav button[data-page='" + step.page + "']");
                if (button) button.click();
                const pages = document.querySelector("#" + HUD_ID + " .mm-hud-pages");
                if (pages) pages.scrollTop = 0;
            }
        } else setKittyHudOpen(false);
        root.querySelector("[data-tutorial-eyebrow]").textContent = step.eyebrow;
        root.querySelector("[data-tutorial-title]").textContent = step.title;
        root.querySelector("[data-tutorial-copy]").textContent = step.copy;
        root.querySelector("[data-tutorial-progress]").textContent =
            String(kittyTutorialIndex + 1) + " / " + String(KITTY_TUTORIAL_STEPS.length);
        const back = root.querySelector("[data-tutorial-back]");
        const next = root.querySelector("[data-tutorial-next]");
        back.disabled = kittyTutorialIndex === 0;
        next.textContent = kittyTutorialIndex === KITTY_TUTORIAL_STEPS.length - 1
            ? "Finish"
            : "Next";
        requestAnimationFrame(() => requestAnimationFrame(positionKittyTutorial));
    }

    function stopKittyTutorial(completed) {
        if (completed) setKittyTutorialComplete();
        kittyTutorialActive = false;
        document.getElementById(KITTY_TUTORIAL_ID)?.remove();
        setKittyHudOpen(kittyTutorialHudWasOpen);
    }

    function startKittyTutorial() {
        if (!document.body) return;
        document.getElementById(KITTY_TUTORIAL_ID)?.remove();
        kittyTutorialHudWasOpen = hudOpen;
        kittyTutorialIndex = 0;
        kittyTutorialActive = true;
        const root = document.createElement("aside");
        root.id = KITTY_TUTORIAL_ID;
        root.setAttribute("role", "dialog");
        root.setAttribute("aria-modal", "true");
        root.setAttribute("aria-label", "Kitty Klient tutorial");
        const spotlight = document.createElement("div");
        spotlight.className = "kitty-tutorial-spotlight";
        const card = document.createElement("section");
        card.className = "kitty-tutorial-card";
        card.innerHTML =
            "<div class='kitty-tutorial-top'><span data-tutorial-eyebrow></span><b data-tutorial-progress></b></div>" +
            "<h2 data-tutorial-title></h2><p data-tutorial-copy></p>" +
            "<div class='kitty-tutorial-actions'>" +
            "<button type='button' data-tutorial-stop>Stop for now</button>" +
            "<button type='button' data-tutorial-skip>Skip tutorial</button>" +
            "<span></span><button type='button' data-tutorial-back>Back</button>" +
            "<button type='button' data-tutorial-next>Next</button></div>";
        root.append(spotlight, card);
        document.body.appendChild(root);
        card.querySelector("[data-tutorial-stop]").addEventListener("click", () => stopKittyTutorial(false));
        card.querySelector("[data-tutorial-skip]").addEventListener("click", () => stopKittyTutorial(true));
        card.querySelector("[data-tutorial-back]").addEventListener("click", () => {
            kittyTutorialIndex = Math.max(0, kittyTutorialIndex - 1);
            showKittyTutorialStep();
        });
        card.querySelector("[data-tutorial-next]").addEventListener("click", () => {
            if (kittyTutorialIndex >= KITTY_TUTORIAL_STEPS.length - 1)
                return stopKittyTutorial(true);
            kittyTutorialIndex += 1;
            showKittyTutorialStep();
        });
        showKittyTutorialStep();
    }

    function kittyHomeActions() {
        const mainMenu = document.getElementById("mainMenu");
        if (!mainMenu) return null;
        let actions = document.getElementById("kitty-klient-home-actions");
        if (actions) return actions;
        const enterGame = document.getElementById("enterGame");
        const container = enterGame && enterGame.parentElement
            ? enterGame.parentElement
            : mainMenu.querySelector("#menuContainer,.menuCard") || mainMenu;
        actions = document.createElement("div");
        actions.id = "kitty-klient-home-actions";
        if (enterGame && enterGame.parentElement === container)
            enterGame.insertAdjacentElement("afterend", actions);
        else container.appendChild(actions);
        if (enterGame && !enterGame.dataset.kittyTutorialPlayBound) {
            enterGame.dataset.kittyTutorialPlayBound = "1";
            enterGame.addEventListener("click", () => {
                if (kittyTutorialActive) stopKittyTutorial(true);
            });
        }
        return actions;
    }

    function mountKittyHomeTutorial() {
        const actions = kittyHomeActions();
        if (!actions) return;
        let tutorial = document.getElementById("kitty-klient-home-tutorial");
        if (!tutorial) {
            tutorial = document.createElement("button");
            tutorial.id = "kitty-klient-home-tutorial";
            tutorial.type = "button";
            tutorial.textContent = "Tutorial";
            tutorial.addEventListener("click", startKittyTutorial);
        }
        if (tutorial.parentElement !== actions) actions.appendChild(tutorial);
    }

    function mountKittyHomeDiscord() {
        const actions = kittyHomeActions();
        if (!actions) return;
        let discord = document.getElementById("kitty-klient-home-discord");
        if (!discord) {
            discord = document.createElement("a");
            discord.id = "kitty-klient-home-discord";
            discord.href = "https://discord.gg/mHvC2kJSH";
            discord.target = "_blank";
            discord.rel = "noopener noreferrer";
            discord.textContent = "Official Discord";
        }
        if (discord.parentElement !== actions) actions.appendChild(discord);
    }

    function applyKittyBrand() {
        applyKittyNameTrademark();
        if (document.title !== "kitty klient") document.title = "kitty klient";
        const menu = document.getElementById("mainMenu") || document.body;
        if (!menu) return;
        const candidates = menu.querySelectorAll("#gameName,.gameName,h1,h2,[class*='title'],[id*='title']");
        candidates.forEach((element) => {
            const text = (element.textContent || "").trim();
            if (text.length <= 32 && /moo\s*moo(?:\.io)?/i.test(text)) {
                element.textContent = "kitty klient";
                element.dataset.kittyBrand = "";
            }
        });
        mountKittyHomeTutorial();
        mountKittyHomeDiscord();
        watchKittyAuxPanelVisibility();
    }

    function installKittyTheme() {
        if (!document.documentElement || document.getElementById("kitty-klient-theme")) return;
        const style = document.createElement("style");
        style.id = "kitty-klient-theme";
        style.textContent = [
            ":root{--kitty-purple:#a855f7;--kitty-purple-deep:#6d28d9;--kitty-black:#08050d}",
            "#kitty-klient-metrics.kitty-main-menu-hidden,#kitty-klient-chat-history.kitty-main-menu-hidden,#kitty-klient-hud-launcher.kitty-main-menu-hidden{display:none!important}",
            "#upgradeHolder[data-kitty-no-upgrades='1'],#upgradeCounter[data-kitty-no-upgrades='1']{display:none!important}",
            "body,button,input,select,textarea,label,#gameUI,#mainMenu,#menuCardHolder,.menuCard,.menuButton,.settingRadio,.leaderboardItem,.leaderScore,.notificationText,.allianceItem,.storeItem,#itemInfoHolder,#loadingText,#diedText{color:#fff!important;text-shadow:0 0 4px #8b5cf6,0 0 11px rgba(168,85,247,.9)!important}",
            ".menuCard,#guideCard,#serverBrowser,#storeHolder,#allianceHolder,#allianceManager,#chatBox{background-color:rgba(5,3,9,.82)!important;border-color:rgba(168,85,247,.7)!important;box-shadow:0 0 18px rgba(139,92,246,.4)!important}",
            "#mainMenu{background:rgba(5,3,9,.5)!important;border:0!important;box-shadow:none!important}#menuCardHolder,#storeMenu,#allianceMenu,#chatHolder{background:transparent!important;border:0!important;box-shadow:none!important;backdrop-filter:none!important}",
            "#menuContainer{position:fixed!important;top:50%!important;right:auto!important;bottom:auto!important;left:50%!important;width:min(1100px,calc(100vw - 28px))!important;box-sizing:border-box!important;margin:0!important;text-align:center!important;scale:none!important;transform:translate(-50%,-50%) scale(var(--kitty-native-ui-scale,.82))!important;transform-origin:center center!important}#menuContainer>#menuCardHolder{margin-inline:auto!important}#storeHolder{width:min(400px,calc(100vw - 40px))!important;box-sizing:border-box!important}#storeMenu>div:first-child{width:min(400px,calc(100vw - 40px));margin-inline:auto}#storeMenu .storeTab{width:calc(50% - 7px)!important;box-sizing:border-box!important}#allianceHolder,#allianceManager{width:min(370px,calc(100vw - 40px))!important;box-sizing:border-box!important;margin-inline:auto!important}#chatBox{width:min(420px,calc(100vw - 40px))!important;box-sizing:border-box!important}",
            "#chatBox,#chatBox input,#chatBox textarea,#chatHolder input,#chatHolder textarea{font-size:16px!important;line-height:1.35!important}",
            ":root{--kitty-native-ui-scale:.82}#gameUI>:is(.uiElement,#topInfoHolder,#itemInfoHolder,#upgradeHolder,#upgradeCounter,#leaderboard,#killCounter,#mapDisplay,#actionBar,#storeButton,#allianceButton,#chatButton,#chatHolder,#storeMenu,#allianceMenu,#notificationDisplay,#diedText,#disconnectDisplay){scale:var(--kitty-native-ui-scale)!important}",
            "#gameUI>:is(#topInfoHolder,#itemInfoHolder,#notificationDisplay){transform-origin:top center!important}#gameUI>:is(#leaderboard,#killCounter){transform-origin:top right!important}#gameUI>:is(#mapDisplay,#storeButton,#allianceButton,#chatButton){transform-origin:bottom right!important}#gameUI>:is(#actionBar,#chatHolder){transform-origin:bottom center!important}#gameUI>:is(#upgradeHolder,#upgradeCounter,#storeMenu,#allianceMenu,#diedText,#disconnectDisplay){transform-origin:center center!important}#kitty-klient-home-actions{scale:1.2195122!important}",
            "#mainMenu button,#mainMenu input,#mainMenu select,#enterGame,.menuButton,.allianceButtonM,.joinAlBtn{background:rgba(8,5,13,.82)!important;border:1px solid rgba(168,85,247,.72)!important;color:#fff!important;box-shadow:0 0 10px rgba(139,92,246,.28)!important}",
            "#mainMenu button:hover,#enterGame:hover,.menuButton:hover,.allianceButtonM:hover,.joinAlBtn:hover{border-color:#c084fc!important;box-shadow:0 0 16px rgba(168,85,247,.72)!important}",
            "#gameUI>#itemInfoHolder{position:fixed!important;top:var(--kitty-item-info-top,110px)!important;right:auto!important;left:14px!important;transform-origin:top left!important}@media(max-width:700px){#gameUI>#itemInfoHolder{left:8px!important;right:auto!important}}",
            "#kitty-klient-home-actions{display:grid!important;grid-template-columns:minmax(0,.8fr) minmax(0,1.2fr);gap:8px;width:min(340px,calc(100% - 24px));margin:10px auto 0;box-sizing:border-box;transform-origin:top center!important;position:relative;z-index:3}#kitty-klient-home-actions>*{display:flex!important;align-items:center;justify-content:center;min-width:0;min-height:38px;box-sizing:border-box;margin:0!important;padding:0 12px;border:1px solid #c084fc!important;border-radius:9px;color:#fff!important;font:900 12px/1.2 system-ui,-apple-system,BlinkMacSystemFont,'Segoe UI',sans-serif;text-decoration:none!important;text-shadow:0 0 8px #2e1065!important;transition:transform .12s ease,filter .12s ease}#kitty-klient-home-tutorial{background:rgba(8,5,13,.9)!important;cursor:pointer}#kitty-klient-home-discord{background:linear-gradient(135deg,rgba(76,29,149,.94),rgba(124,58,237,.94))!important;box-shadow:0 0 15px rgba(168,85,247,.5)!important}#kitty-klient-home-actions>*:hover{filter:brightness(1.14);transform:translateY(-1px);box-shadow:0 0 21px rgba(192,132,252,.72)!important}",
            "[data-kitty-brand],#gameName.kitty-klient-brand{font-family:'Segoe Print','Bradley Hand','Brush Script MT',cursive!important;font-style:italic!important;font-weight:900!important;letter-spacing:.045em!important;text-transform:lowercase!important;color:#07030b!important;-webkit-text-stroke:1px #17101f;text-shadow:-2px 1px 0 #a855f7,2px -1px 0 #6d28d9,0 0 8px #c084fc,0 0 22px #7c3aed!important;transform:skewX(-9deg) rotate(-1deg)!important}",
            "#mainMenu #gameName[data-kitty-brand]{display:block!important;width:max-content!important;max-width:100%!important;position:relative!important;left:50%!important;right:auto!important;margin-left:0!important;margin-right:0!important;text-align:center!important;transform-origin:center center!important;transform:translateX(-50%) skewX(-9deg) rotate(-1deg)!important}",
            "#kitty-klient-metrics{position:fixed;z-index:2147483645;right:14px;top:62%;transform:translateY(-50%);display:grid;gap:5px;padding:9px 10px;border:1px solid rgba(168,85,247,.68);border-radius:10px;background:rgba(5,3,9,.68);box-shadow:0 0 18px rgba(139,92,246,.38);backdrop-filter:blur(7px);pointer-events:none;color:#fff;font:800 11px/1.15 ui-monospace,SFMono-Regular,Menlo,monospace;text-shadow:0 0 7px #8b5cf6}",
            "#kitty-klient-metrics span{display:flex;justify-content:space-between;gap:10px;min-width:92px}#kitty-klient-metrics b{color:#c084fc;font-weight:900}",
            "#kitty-klient-tutorial{position:fixed;z-index:2147483647;inset:0;pointer-events:none;color:#fff;font:600 13px/1.45 system-ui,-apple-system,BlinkMacSystemFont,'Segoe UI',sans-serif;text-shadow:0 0 7px rgba(168,85,247,.8)}#kitty-klient-tutorial *{box-sizing:border-box}#kitty-klient-tutorial .kitty-tutorial-spotlight{position:fixed;border:2px solid #c084fc;border-radius:13px;box-shadow:0 0 0 9999px rgba(2,1,4,.72),0 0 25px rgba(192,132,252,.95),inset 0 0 18px rgba(168,85,247,.18);transition:left .18s ease,top .18s ease,width .18s ease,height .18s ease;pointer-events:none}#kitty-klient-tutorial .kitty-tutorial-spotlight[hidden]{display:none}",
            "#kitty-klient-tutorial .kitty-tutorial-card{position:fixed;width:min(410px,calc(100vw - 24px));padding:18px;border:1px solid rgba(192,132,252,.88);border-radius:15px;background:linear-gradient(145deg,rgba(7,4,12,.98),rgba(37,15,57,.96));box-shadow:0 0 30px rgba(139,92,246,.58),0 18px 60px rgba(0,0,0,.72);backdrop-filter:blur(14px);pointer-events:auto}#kitty-klient-tutorial .kitty-tutorial-top{display:flex;align-items:center;justify-content:space-between;gap:12px;color:#d8b4fe;font-size:10px;font-weight:900;letter-spacing:.12em;text-transform:uppercase}#kitty-klient-tutorial h2{margin:7px 0 7px;color:#fff!important;font-size:21px;line-height:1.12;text-shadow:0 0 11px #8b5cf6!important}#kitty-klient-tutorial p{margin:0;color:#f5f3ff;font-size:12px}#kitty-klient-tutorial .kitty-tutorial-actions{display:grid;grid-template-columns:auto auto 1fr auto auto;gap:7px;align-items:center;margin-top:16px}#kitty-klient-tutorial button{min-height:34px;padding:0 10px;border:1px solid rgba(192,132,252,.6);border-radius:8px;background:rgba(10,6,16,.88);color:#fff!important;font:800 11px/1 system-ui,-apple-system,BlinkMacSystemFont,'Segoe UI',sans-serif;cursor:pointer;text-shadow:0 0 7px #7c3aed!important}#kitty-klient-tutorial button:hover{border-color:#e9d5ff;box-shadow:0 0 13px rgba(168,85,247,.58)}#kitty-klient-tutorial button:disabled{opacity:.35;cursor:default;box-shadow:none}#kitty-klient-tutorial [data-tutorial-next]{background:linear-gradient(135deg,#6d28d9,#a855f7);border-color:#d8b4fe}#kitty-klient-tutorial [data-tutorial-stop]{border-color:rgba(248,113,113,.56)}@media(max-width:620px){#kitty-klient-tutorial .kitty-tutorial-actions{grid-template-columns:1fr 1fr}#kitty-klient-tutorial .kitty-tutorial-actions>span{display:none}#kitty-klient-tutorial .kitty-tutorial-card{padding:14px}}",
            "#kitty-klient-update-popup{position:fixed;z-index:2147483647;top:18px;right:18px;width:min(330px,calc(100vw - 36px));box-sizing:border-box;padding:17px 17px 16px;border:1px solid rgba(192,132,252,.82);border-radius:14px;background:linear-gradient(145deg,rgba(8,5,13,.94),rgba(30,12,48,.88));box-shadow:0 0 28px rgba(139,92,246,.5),inset 0 0 22px rgba(168,85,247,.08);backdrop-filter:blur(12px);color:#fff;font:600 13px/1.45 system-ui,-apple-system,BlinkMacSystemFont,'Segoe UI',sans-serif;text-shadow:0 0 7px rgba(168,85,247,.8);animation:kitty-update-enter .22s ease-out both}",
            "#kitty-klient-update-popup .kitty-update-title{margin:0 30px 5px 0;color:#fff;font-size:18px;font-weight:900;letter-spacing:.01em}#kitty-klient-update-popup .kitty-update-copy{margin:0 0 12px;color:#eee}#kitty-klient-update-popup .kitty-update-versions{display:flex;align-items:center;gap:7px;margin:0 0 14px;color:#d8b4fe;font:800 11px/1.2 ui-monospace,SFMono-Regular,Menlo,monospace;text-shadow:0 0 8px #7c3aed}",
            "#kitty-klient-update-popup .kitty-update-download{display:flex;align-items:center;justify-content:center;min-height:38px;padding:0 14px;border:1px solid #c084fc;border-radius:9px;background:linear-gradient(135deg,#7c3aed,#a855f7);color:#fff!important;font-size:13px;font-weight:900;text-decoration:none;box-shadow:0 0 15px rgba(168,85,247,.46);text-shadow:0 0 7px #4c1d95!important;transition:transform .12s ease,filter .12s ease}#kitty-klient-update-popup .kitty-update-download:hover{filter:brightness(1.13);transform:translateY(-1px)}",
            "#kitty-klient-update-popup .kitty-update-close{position:absolute;top:8px;right:9px;width:30px;height:30px;padding:0;border:0;border-radius:8px;background:transparent;color:#e9d5ff!important;font:900 23px/28px Arial,sans-serif;cursor:pointer;text-shadow:0 0 9px #a855f7!important}#kitty-klient-update-popup .kitty-update-close:hover{background:rgba(168,85,247,.2);color:#fff!important}@keyframes kitty-update-enter{from{opacity:0;transform:translateY(-9px) scale(.98)}to{opacity:1;transform:none}}",
            "html[data-kitty-fps-boost='1'] :is(#gameUI,#mainMenu,#moomoo-op-hud),html[data-kitty-fps-boost='1'] :is(#gameUI,#mainMenu,#moomoo-op-hud) *{backdrop-filter:none!important;animation-duration:.001ms!important;animation-iteration-count:1!important;transition-duration:.001ms!important}",
            "@media(max-width:700px){#kitty-klient-metrics{right:8px;top:60%;font-size:9px;padding:7px}#menuContainer{width:calc(100vw - 16px)!important;white-space:normal!important}}"
        ].join("");
        (document.head || document.documentElement).appendChild(style);
        applyKittyBrand();
        // The game mutates its DOM constantly. Running the full branding query
        // for every mutation can consume an entire frame on the main menu, so
        // observe only until MooMoo's menu has finished mounting.
        if (!document.getElementById("kitty-klient-home-actions")) {
            let brandRefreshTimer = 0;
            const observer = new MutationObserver(() => {
                if (brandRefreshTimer) return;
                brandRefreshTimer = window.setTimeout(() => {
                    brandRefreshTimer = 0;
                    applyKittyBrand();
                    if (
                        document.getElementById("mainMenu") &&
                        document.getElementById("enterGame") &&
                        document.getElementById("kitty-klient-home-actions")
                    ) observer.disconnect();
                }, 80);
            });
            observer.observe(document.documentElement, { childList: true, subtree: true });
        }
    }

    function mountMetrics() {
        if (!KITTY_AUX_PANELS_VISIBLE) {
            document.getElementById("kitty-klient-metrics")?.remove();
            return;
        }
        if (!document.body || document.getElementById("kitty-klient-metrics")) return;
        const metrics = document.createElement("div");
        metrics.id = "kitty-klient-metrics";
        metrics.setAttribute("aria-label", "kitty klient performance");
        metrics.innerHTML = "<span>PING <b data-metric='ping'>--</b></span>" +
            "<span>FPS <b data-metric='fps'>--</b></span>" +
            "<span>PACKETS <b data-metric='packets'>0</b></span>";
        document.body.appendChild(metrics);
        syncKittyAuxPanelVisibility();
    }

    function syncKittyAuxPanelVisibility() {
        const mainMenu = document.getElementById("mainMenu");
        const mainMenuVisible = !mainMenu || window.getComputedStyle(mainMenu).display !== "none";
        if (document.documentElement) {
            const nextValue = mainMenuVisible ? "1" : "0";
            if (document.documentElement.getAttribute("data-kitty-main-menu-open") !== nextValue) {
                document.documentElement.setAttribute("data-kitty-main-menu-open", nextValue);
                window.dispatchEvent(new CustomEvent("MooMooKittyMainMenuVisibility", {
                    detail: mainMenuVisible
                }));
            }
        }
        ["kitty-klient-metrics", CHAT_HISTORY_ID, KITTY_HUD_LAUNCHER_ID].forEach((id) => {
            document.getElementById(id)?.classList.toggle("kitty-main-menu-hidden", mainMenuVisible);
        });
        positionKittyHudLauncher();
    }

    function watchKittyAuxPanelVisibility() {
        const mainMenu = document.getElementById("mainMenu");
        if (!mainMenu || mainMenu.hasAttribute("data-kitty-aux-visibility-watch")) {
            syncKittyAuxPanelVisibility();
            return;
        }
        mainMenu.setAttribute("data-kitty-aux-visibility-watch", "");
        new MutationObserver(syncKittyAuxPanelVisibility).observe(mainMenu, {
            attributes: true,
            attributeFilter: ["style", "class", "hidden"]
        });
        syncKittyAuxPanelVisibility();
    }

    let kittyChatHistoryCollapsed = false;
    try {
        kittyChatHistoryCollapsed = localStorage.getItem(CHAT_HISTORY_COLLAPSED_KEY) === "1";
    } catch {
        // Collapsing remains available for this page when storage is blocked.
    }

    function setKittyChatHistoryCollapsed(collapsed, panel = document.getElementById(CHAT_HISTORY_ID)) {
        kittyChatHistoryCollapsed = !!collapsed;
        if (panel) {
            panel.classList.toggle("kitty-chat-collapsed", kittyChatHistoryCollapsed);
            const toggle = panel.querySelector("[data-kitty-chat-toggle]");
            if (toggle) {
                toggle.textContent = kittyChatHistoryCollapsed ? "Show chat" : "Hide chat";
                toggle.setAttribute("aria-expanded", String(!kittyChatHistoryCollapsed));
                toggle.setAttribute(
                    "aria-label",
                    kittyChatHistoryCollapsed ? "Show chat history" : "Hide chat history"
                );
            }
        }
        try {
            localStorage.setItem(CHAT_HISTORY_COLLAPSED_KEY, kittyChatHistoryCollapsed ? "1" : "0");
        } catch {
            // Persistence is optional.
        }
        requestAnimationFrame(() => {
            positionKittyChatHistory();
            positionKittyNativeTooltip();
        });
    }

    function positionKittyChatHistory() {
        const panel = document.getElementById(CHAT_HISTORY_ID);
        if (!panel) return;
        panel.style.top = window.innerWidth <= 700 ? "8px" : "14px";
        panel.style.bottom = "auto";
        requestAnimationFrame(positionKittyNativeTooltip);
    }

    function positionKittyNativeTooltip() {
        const panel = document.getElementById(CHAT_HISTORY_ID);
        const panelVisible = panel && panel.getClientRects().length > 0;
        const top = panelVisible
            ? Math.ceil(panel.getBoundingClientRect().bottom + 8)
            : window.innerWidth <= 700 ? 8 : 14;
        document.documentElement.style.setProperty("--kitty-item-info-top", top + "px");
    }

    function kittyChatIsNearBottom(log) {
        return !!log && log.scrollHeight - log.scrollTop - log.clientHeight <= 14;
    }

    function updateKittyChatScrollLock(log) {
        const panel = log && log.closest("#" + CHAT_HISTORY_ID);
        const jump = panel && panel.querySelector("[data-kitty-chat-jump]");
        if (!panel || !jump) return;
        const locked = !kittyChatIsNearBottom(log);
        panel.classList.toggle("kitty-chat-scroll-locked", locked);
        jump.hidden = !locked;
    }

    function appendKittyChatHistoryEntry(entry) {
        const panel = document.getElementById(CHAT_HISTORY_ID);
        const log = panel && panel.querySelector("[data-kitty-chat-log]");
        if (!panel || !log) return;
        const followLatest = kittyChatIsNearBottom(log);
        const empty = panel.querySelector("[data-kitty-chat-empty]");
        if (empty) empty.hidden = true;
        const row = document.createElement("article");
        row.className = "kitty-chat-entry";
        row.dataset.relation = entry.relation || "enemy";
        const meta = document.createElement("div");
        meta.className = "kitty-chat-meta";
        const name = document.createElement("strong");
        name.textContent = entry.name;
        const time = document.createElement("time");
        time.dateTime = new Date(entry.at).toISOString();
        time.textContent = new Date(entry.at).toLocaleTimeString([], {
            hour: "2-digit",
            minute: "2-digit"
        });
        meta.append(name, time);
        const message = document.createElement("p");
        message.textContent = entry.message;
        row.append(meta, message);
        log.appendChild(row);
        while (log.querySelectorAll(".kitty-chat-entry").length > 120)
            log.querySelector(".kitty-chat-entry")?.remove();
        const count = panel.querySelector("[data-kitty-chat-count]");
        if (count) count.textContent = String(Math.min(120, chatHistoryEntries.length));
        requestAnimationFrame(() => {
            if (followLatest)
                log.scrollTo({ top: log.scrollHeight, behavior: "smooth" });
            updateKittyChatScrollLock(log);
        });
        positionKittyChatHistory();
    }

    function mountKittyChatHistory() {
        if (!KITTY_AUX_PANELS_VISIBLE) {
            document.getElementById(CHAT_HISTORY_ID)?.remove();
            return;
        }
        if (!document.body || document.getElementById(CHAT_HISTORY_ID)) return;
        const style = document.createElement("style");
        style.id = CHAT_HISTORY_ID + "-style";
        style.textContent = [
            "#kitty-klient-chat-history{position:fixed;z-index:2147483644;top:14px;bottom:auto;left:14px;width:min(350px,calc(100vw - 28px));max-height:min(270px,36vh);display:grid;grid-template-rows:auto minmax(0,1fr);overflow:hidden;border:1px solid rgba(192,132,252,.62);border-radius:13px;background:linear-gradient(145deg,rgba(5,3,9,.58),rgba(25,10,40,.44));box-shadow:0 0 20px rgba(139,92,246,.3),0 12px 35px rgba(0,0,0,.28);backdrop-filter:blur(8px) saturate(1.12);color:#fff;font:13px/1.42 system-ui,-apple-system,BlinkMacSystemFont,'Segoe UI',sans-serif;text-shadow:0 0 6px rgba(168,85,247,.65);pointer-events:auto;transition:top .2s ease,opacity .2s ease,max-height .18s ease}#kitty-klient-chat-history.kitty-chat-disabled{display:none!important}#kitty-klient-chat-history.kitty-chat-collapsed{grid-template-rows:auto;width:auto;max-height:48px}#kitty-klient-chat-history.kitty-chat-collapsed .kitty-chat-title,#kitty-klient-chat-history.kitty-chat-collapsed .kitty-chat-count{display:none!important}",
            "#kitty-klient-chat-history:hover{border-color:rgba(216,180,254,.82);box-shadow:0 0 24px rgba(168,85,247,.42),0 14px 38px rgba(0,0,0,.32)}#kitty-klient-chat-history .kitty-chat-head{display:flex;align-items:center;justify-content:space-between;gap:9px;padding:9px 11px 8px;border-bottom:1px solid rgba(168,85,247,.25);background:rgba(10,5,17,.25)}#kitty-klient-chat-history.kitty-chat-collapsed .kitty-chat-head{border-bottom-color:transparent}",
            "#kitty-klient-chat-history .kitty-chat-title{display:flex;align-items:center;gap:7px;min-width:0;font-weight:900;letter-spacing:.1em;text-transform:uppercase}#kitty-klient-chat-history .kitty-chat-title:before{content:'';flex:0 0 auto;width:7px;height:7px;border-radius:50%;background:#a855f7;box-shadow:0 0 9px #c084fc}#kitty-klient-chat-history .kitty-chat-actions{display:flex;align-items:center;gap:6px;flex:0 0 auto}#kitty-klient-chat-history .kitty-chat-count{min-width:21px;padding:2px 6px;border:1px solid rgba(192,132,252,.42);border-radius:999px;background:rgba(109,40,217,.2);color:#e9d5ff;text-align:center;font:800 9px/1.2 ui-monospace,SFMono-Regular,Menlo,monospace}#kitty-klient-chat-history .kitty-chat-toggle{min-height:25px;padding:3px 8px;border:1px solid rgba(216,180,254,.58);border-radius:7px;background:rgba(76,29,149,.3);color:#fff;font:800 10px/1 system-ui,-apple-system,BlinkMacSystemFont,'Segoe UI',sans-serif;cursor:pointer;text-shadow:0 0 6px #7c3aed}#kitty-klient-chat-history .kitty-chat-toggle:hover{border-color:#d8b4fe;background:rgba(109,40,217,.46);box-shadow:0 0 10px rgba(168,85,247,.38)}",
            "#kitty-klient-chat-history .kitty-chat-log{min-height:54px;overflow-y:auto;overscroll-behavior:contain;scroll-behavior:smooth;padding:7px;scrollbar-width:thin;scrollbar-color:#7c3aed rgba(8,5,13,.42)}#kitty-klient-chat-history .kitty-chat-log::-webkit-scrollbar{width:6px}#kitty-klient-chat-history .kitty-chat-log::-webkit-scrollbar-track{background:rgba(8,5,13,.42)}#kitty-klient-chat-history .kitty-chat-log::-webkit-scrollbar-thumb{border-radius:999px;background:linear-gradient(#a855f7,#6d28d9)}",
            "#kitty-klient-chat-history .kitty-chat-empty{display:grid;place-items:center;min-height:42px;color:#c4b5fd;font-style:italic;opacity:.72}#kitty-klient-chat-history .kitty-chat-entry{margin:0 0 6px;padding:7px 8px;border:1px solid rgba(168,85,247,.17);border-left:3px solid var(--kitty-enemy,#ff4d5d);border-radius:8px;background:rgba(8,5,13,.29);animation:kitty-chat-enter .2s cubic-bezier(.2,.8,.2,1) both}#kitty-klient-chat-history .kitty-chat-entry:last-child{margin-bottom:0}#kitty-klient-chat-history .kitty-chat-entry[data-relation='self']{border-left-color:var(--kitty-own,#d8b4fe)}#kitty-klient-chat-history .kitty-chat-entry[data-relation='ally']{border-left-color:var(--kitty-ally,#a855f7)}#kitty-klient-chat-history .kitty-chat-entry[data-relation='friend']{border-left-color:var(--kitty-friend,#facc15)}#kitty-klient-chat-history.kitty-chat-collapsed .kitty-chat-log,#kitty-klient-chat-history.kitty-chat-collapsed .kitty-chat-jump{display:none!important}",
            "#kitty-klient-chat-history .kitty-chat-jump{position:absolute;right:11px;bottom:10px;min-height:28px;padding:0 10px;border:1px solid rgba(216,180,254,.82);border-radius:999px;background:rgba(76,29,149,.94);color:#fff;font:900 10px/1 system-ui,-apple-system,BlinkMacSystemFont,'Segoe UI',sans-serif;cursor:pointer;box-shadow:0 0 14px rgba(168,85,247,.55);text-shadow:0 0 7px #7c3aed}#kitty-klient-chat-history .kitty-chat-jump[hidden]{display:none}#kitty-klient-chat-history.kitty-chat-scroll-locked .kitty-chat-log{padding-bottom:44px}",
            "#kitty-klient-chat-history .kitty-chat-meta{display:flex;align-items:center;justify-content:space-between;gap:8px;margin-bottom:3px}#kitty-klient-chat-history .kitty-chat-meta strong{overflow:hidden;color:#fff;font-size:12px;text-overflow:ellipsis;white-space:nowrap}#kitty-klient-chat-history .kitty-chat-meta time{flex:0 0 auto;color:#c4b5fd;font:700 10px/1 ui-monospace,SFMono-Regular,Menlo,monospace}#kitty-klient-chat-history .kitty-chat-entry p{margin:0;color:#f5f3ff;font-size:14px;line-height:1.42;overflow-wrap:anywhere} @keyframes kitty-chat-enter{from{opacity:0;transform:translateX(9px) scale(.98)}to{opacity:1;transform:none}}",
            "@media(max-width:700px){#kitty-klient-chat-history{top:8px;bottom:auto;left:8px;width:min(310px,calc(100vw - 16px));max-height:29vh;font-size:12px}#kitty-klient-chat-history .kitty-chat-entry p{font-size:13px}}"
        ].join("");
        (document.head || document.documentElement).appendChild(style);
        const panel = document.createElement("aside");
        panel.id = CHAT_HISTORY_ID;
        panel.classList.toggle("kitty-chat-disabled", !hudState.chatHistory);
        panel.setAttribute("aria-label", "Chat history");
        panel.setAttribute("aria-hidden", String(!hudState.chatHistory));
        const head = document.createElement("header");
        head.className = "kitty-chat-head";
        const title = document.createElement("span");
        title.className = "kitty-chat-title";
        title.textContent = "Chat history";
        const count = document.createElement("span");
        count.className = "kitty-chat-count";
        count.dataset.kittyChatCount = "";
        count.textContent = "0";
        const actions = document.createElement("div");
        actions.className = "kitty-chat-actions";
        const toggle = document.createElement("button");
        toggle.className = "kitty-chat-toggle";
        toggle.type = "button";
        toggle.dataset.kittyChatToggle = "";
        toggle.setAttribute("aria-controls", CHAT_HISTORY_ID + "-log");
        toggle.addEventListener("click", () => {
            setKittyChatHistoryCollapsed(!kittyChatHistoryCollapsed, panel);
        });
        actions.append(count, toggle);
        head.append(title, actions);
        const log = document.createElement("div");
        log.id = CHAT_HISTORY_ID + "-log";
        log.className = "kitty-chat-log";
        log.dataset.kittyChatLog = "";
        log.setAttribute("role", "log");
        log.setAttribute("aria-live", "polite");
        const empty = document.createElement("div");
        empty.className = "kitty-chat-empty";
        empty.dataset.kittyChatEmpty = "";
        empty.textContent = "Messages will appear here";
        log.appendChild(empty);
        const jump = document.createElement("button");
        jump.className = "kitty-chat-jump";
        jump.type = "button";
        jump.dataset.kittyChatJump = "";
        jump.textContent = "Latest ↓";
        jump.hidden = true;
        jump.addEventListener("click", () => {
            log.scrollTo({ top: log.scrollHeight, behavior: "smooth" });
            requestAnimationFrame(() => updateKittyChatScrollLock(log));
        });
        log.addEventListener("scroll", () => updateKittyChatScrollLock(log), { passive: true });
        panel.append(head, log, jump);
        document.body.appendChild(panel);
        setKittyChatHistoryCollapsed(kittyChatHistoryCollapsed, panel);
        if (typeof ResizeObserver === "function")
            new ResizeObserver(positionKittyNativeTooltip).observe(panel);
        chatHistoryEntries.forEach(appendKittyChatHistoryEntry);
        positionKittyChatHistory();
        syncKittyAuxPanelVisibility();
    }

    window.addEventListener("MooMooKittyChatMessage", (event) => {
        const detail = event.detail && typeof event.detail === "object" ? event.detail : {};
        const message = String(detail.message || "").trim().slice(0, 120);
        if (!message) return;
        const entry = {
            name: String(detail.name || "Player").slice(0, 32),
            message,
            relation: ["self", "ally", "friend", "enemy"].includes(detail.relation)
                ? detail.relation
                : "enemy",
            at: Number.isFinite(Number(detail.at)) ? Number(detail.at) : Date.now()
        };
        chatHistoryEntries.push(entry);
        if (chatHistoryEntries.length > 120) chatHistoryEntries.shift();
        const alreadyMounted = !!document.getElementById(CHAT_HISTORY_ID);
        mountKittyChatHistory();
        alreadyMounted && appendKittyChatHistoryEntry(entry);
    });

    window.addEventListener("resize", () => {
        positionKittyChatHistory();
        positionKittyHudLauncher();
    }, { passive: true });

    installCanvasTextTheme();

    // Firefox can place a patched blob module in a messaging context that is
    // separate from the userscript's normal page context. Bridge tab-sync
    // traffic through the page-level storage event as a reliable fallback.
    window.addEventListener("MooMooTabSyncOutbound", (event) => {
        const payload = typeof event.detail === "string" ? event.detail : "";
        if (!payload || payload.length > 1200) return;
        try {
            localStorage.setItem(TAB_SYNC_BRIDGE_KEY, payload);
        } catch {
            // BroadcastChannel remains available when storage is blocked.
        }
    });
    window.addEventListener("storage", (event) => {
        if (!event || event.key !== TAB_SYNC_BRIDGE_KEY || !event.newValue) return;
        window.dispatchEvent(new CustomEvent("MooMooTabSyncInbound", { detail: event.newValue }));
    });
 
    function showZoomIndicator(message) {
        if (!document.body) return;
 
        let indicator = document.getElementById(INDICATOR_ID);
        if (!indicator) {
            indicator = document.createElement("div");
            indicator.id = INDICATOR_ID;
            indicator.style.cssText = [
                "position:fixed",
                "top:16px",
                "left:50%",
                "z-index:2147483647",
                "transform:translateX(-50%)",
                "max-width:min(560px,calc(100vw - 30px))",
                "box-sizing:border-box",
                "padding:10px 17px",
                "border:1px solid rgba(192,132,252,.78)",
                "border-radius:11px",
                "background:linear-gradient(145deg,rgba(5,3,9,.9),rgba(34,12,52,.86))",
                "color:#fff",
                "font:800 18px/1.3 Arial,sans-serif",
                "text-align:center",
                "text-shadow:0 0 8px rgba(168,85,247,.9)",
                "box-shadow:0 0 22px rgba(139,92,246,.44),0 8px 24px rgba(0,0,0,.3)",
                "backdrop-filter:blur(9px)",
                "pointer-events:none",
                "transition:opacity .2s"
            ].join(";");
            document.body.appendChild(indicator);
        }
 
        // A larger viewport multiplier means more of the map is visible.
        indicator.textContent = message || `Zoom: ${Math.round((1 / viewMultiplier) * 100)}%`;
        indicator.style.opacity = "1";
        clearTimeout(hideIndicatorTimer);
        hideIndicatorTimer = window.setTimeout(() => {
            indicator.style.opacity = "0";
        }, 900);
    }
 
    function applyViewportSize() {
        window.__MooMooScrollZoomMultiplier = viewMultiplier;
        if (typeof window.__MooMooScrollZoomSetViewport === "function") {
            window.__MooMooScrollZoomSetViewport(viewMultiplier);
        }
    }
 
    function isGameSurface(target) {
        return target instanceof Element && Boolean(target.closest("#gameCanvas, #touch-controls-fullscreen"));
    }
 
    function isLikelyTrackpadScroll(event) {
        // Physical mouse wheels normally report line-mode or a large pixel delta.
        // Trackpads emit frequent, small pixel-mode deltas.
        return event.deltaMode === WheelEvent.DOM_DELTA_PIXEL && Math.abs(event.deltaY) < 50;
    }
 
    document.addEventListener("wheel", (event) => {
        if (!isGameSurface(event.target) || event.ctrlKey || event.deltaY === 0) return;
 
        event.preventDefault();
        event.stopImmediatePropagation();
        const zoomStep = isLikelyTrackpadScroll(event)
            ? Math.pow(ZOOM_STEP, Math.abs(event.deltaY) / TRACKPAD_PIXELS_PER_ZOOM_STEP)
            : ZOOM_STEP;
        viewMultiplier = Math.min(
            MAX_VIEW_MULTIPLIER,
            Math.max(MIN_VIEW_MULTIPLIER, viewMultiplier * (event.deltaY > 0 ? zoomStep : 1 / zoomStep))
        );
        applyViewportSize();
        showZoomIndicator();
    }, { capture: true, passive: false });
 
    window.addEventListener("MooMooScrollZoomAutoheal", (event) => {
        showZoomIndicator(`Autoheal: ${event.detail ? "On" : "Off"}`);
    });
 
    window.addEventListener("MooMooScrollZoomMonkeyTail", (event) => {
        showZoomIndicator(event.detail);
    });
 
    window.addEventListener("MooMooScrollZoomStatus", (event) => {
        showZoomIndicator(event.detail);
    });
 
    function clampHudNumber(key, value) {
        const bounds = HUD_NUMERIC_BOUNDS[key];
        if (!bounds || !Number.isFinite(value)) return HUD_DEFAULTS[key];
        return Math.min(bounds.max, Math.max(bounds.min, value));
    }

    function normalizeHudColor(value, fallback) {
        const color = typeof value === "string" ? value.trim().toLowerCase() : "";
        return /^#[0-9a-f]{6}$/.test(color) ? color : fallback;
    }

    function normalizeKittyBinding(value, fallback) {
        const pieces = typeof value === "string"
            ? value.split("+").map((piece) => piece.trim()).filter(Boolean)
            : [];
        const modifiers = new Set();
        let trigger = "";
        pieces.forEach((piece) => {
            const token = piece.toLowerCase();
            if (token === "ctrl" || token === "control") modifiers.add("Ctrl");
            else if (token === "alt" || token === "option") modifiers.add("Alt");
            else if (token === "shift") modifiers.add("Shift");
            else if (token === "meta" || token === "command" || token === "cmd") modifiers.add("Meta");
            else trigger = piece;
        });
        const validTrigger = /^(?:Mouse[0-4]|Key[A-Z]|Digit[0-9]|F(?:[1-9]|1[0-2])|Escape|Space|Enter|Tab|Backquote|Minus|Equal|BracketLeft|BracketRight|Backslash|Semicolon|Quote|Comma|Period|Slash|ArrowUp|ArrowDown|ArrowLeft|ArrowRight|Home|End|PageUp|PageDown|Insert|Delete)$/i.test(trigger);
        if (!validTrigger) return fallback;
        if (/^mouse/i.test(trigger)) trigger = "Mouse" + trigger.replace(/\D/g, "");
        else if (/^key/i.test(trigger)) trigger = "Key" + trigger.slice(3).toUpperCase();
        else if (/^digit/i.test(trigger)) trigger = "Digit" + trigger.slice(5);
        else if (/^f\d+$/i.test(trigger)) trigger = trigger.toUpperCase();
        else {
            const canonical = ["Escape", "Space", "Enter", "Tab", "Backquote", "Minus", "Equal", "BracketLeft", "BracketRight", "Backslash", "Semicolon", "Quote", "Comma", "Period", "Slash", "ArrowUp", "ArrowDown", "ArrowLeft", "ArrowRight", "Home", "End", "PageUp", "PageDown", "Insert", "Delete"];
            trigger = canonical.find((entry) => entry.toLowerCase() === trigger.toLowerCase()) || trigger;
        }
        return ["Ctrl", "Alt", "Shift", "Meta"].filter((modifier) => modifiers.has(modifier)).concat(trigger).join("+");
    }

    function kittyBindingLabelPart(part) {
        if (part === "Ctrl") return "Ctrl";
        if (part === "Alt") return "Alt";
        if (part === "Shift") return "Shift";
        if (part === "Meta") return "Cmd";
        if (part === "Mouse0") return "Left click";
        if (part === "Mouse1") return "Middle click";
        if (part === "Mouse2") return "Right click";
        if (part === "Mouse3") return "Mouse 4";
        if (part === "Mouse4") return "Mouse 5";
        if (/^Key[A-Z]$/.test(part)) return part.slice(3);
        if (/^Digit[0-9]$/.test(part)) return part.slice(5);
        if (part === "Space") return "Space";
        return part.replace(/([a-z])([A-Z])/g, "$1 $2");
    }

    function kittyBindingFromEvent(event, mouse) {
        if (!event) return null;
        const trigger = mouse
            ? "Mouse" + Math.max(0, Math.min(4, Number(event.button) || 0))
            : String(event.code || "");
        if (!trigger || /^(?:Shift|Control|Alt|Meta)(?:Left|Right)$/.test(trigger)) return null;
        return normalizeKittyBinding([
            event.ctrlKey && "Ctrl",
            event.altKey && "Alt",
            event.shiftKey && "Shift",
            event.metaKey && "Meta",
            trigger
        ].filter(Boolean).join("+"), null);
    }

    function kittyBindingMatchesEvent(binding, event, mouse) {
        const actual = kittyBindingFromEvent(event, mouse);
        return Boolean(actual && normalizeKittyBinding(binding, "") === actual);
    }

    function normalizeHudSettings(candidate) {
        const settings = { ...HUD_DEFAULTS };
        settings.keybinds = { ...KITTY_DEFAULT_KEYBINDS };
        if (!candidate || typeof candidate !== "object" || Array.isArray(candidate)) return settings;
 
        HUD_BOOLEAN_KEYS.forEach((key) => {
            if (typeof candidate[key] === "boolean") settings[key] = candidate[key];
        });
        Object.keys(HUD_NUMERIC_BOUNDS).forEach((key) => {
            if (Number.isFinite(candidate[key])) settings[key] = clampHudNumber(key, candidate[key]);
        });
        ["enemyColor", "allyColor", "friendColor", "ownColor"].forEach((key) => {
            settings[key] = normalizeHudColor(candidate[key], HUD_DEFAULTS[key]);
        });
        if (typeof candidate.killMessage === "string") {
            settings.killMessage = candidate.killMessage.slice(0, 30);
        }
        if (typeof candidate.syncRelayUrl === "string") {
            settings.syncRelayUrl = candidate.syncRelayUrl.trim().slice(0, 200);
        }
        if (typeof candidate.syncRoom === "string") {
            settings.syncRoom = candidate.syncRoom.trim().slice(0, 64);
        }
        if (typeof candidate.syncStatus === "string") {
            settings.syncStatus = candidate.syncStatus.trim().slice(0, 100) || "Sync off";
        }
        if (typeof candidate.syncTargetName === "string") {
            settings.syncTargetName = candidate.syncTargetName.trim().slice(0, 15);
        }
        if (Array.isArray(candidate.friendNames)) {
            const seen = new Set();
            settings.friendNames = candidate.friendNames.reduce((names, value) => {
                const name = typeof value === "string" ? value.trim().slice(0, 15) : "";
                const key = name.toLowerCase();
                if (name && !seen.has(key) && names.length < 30) {
                    seen.add(key);
                    names.push(name);
                }
                return names;
            }, []);
        }
        if (candidate.keybinds && typeof candidate.keybinds === "object" && !Array.isArray(candidate.keybinds)) {
            KITTY_BINDING_ACTIONS.forEach((entry) => {
                settings.keybinds[entry.id] = normalizeKittyBinding(
                    candidate.keybinds[entry.id],
                    KITTY_DEFAULT_KEYBINDS[entry.id]
                );
            });
        }
        return settings;
    }
 
    function readHudSettings() {
        try {
            const settings = normalizeHudSettings(JSON.parse(localStorage.getItem(HUD_STORAGE_KEY) || "{}"));
            // Apply the requested auto death-message default once without
            // discarding the rest of the player's saved HUD configuration.
            if (localStorage.getItem(KILL_MESSAGE_AUTO_MIGRATION_KEY) !== "1") {
                settings.killMessageEnabled = true;
                if (!settings.killMessage.trim()) settings.killMessage = HUD_DEFAULTS.killMessage;
                localStorage.setItem(KILL_MESSAGE_AUTO_MIGRATION_KEY, "1");
            }
            // Older Kitty builds persisted the smart-placement master as false
            // because it was originally an opt-in preview. Enable the repaired
            // core once, persist that migration immediately, and leave the HUD
            // toggle fully user-controllable from then on.
            if (localStorage.getItem(PLACEMENT_CORE_AUTO_MIGRATION_KEY) !== "1") {
                settings.smartAutoPlace = true;
                settings.smartMultiPlace = true;
                settings.smartQuadTraps = true;
                settings.smartQuadSpikes = true;
                settings.smartSpikeContact = true;
                settings.smartTrapContact = true;
                settings.smartTrapSurround = true;
                settings.smartMaxPlacements = 4;
                settings.placementVisuals = true;
                localStorage.setItem(HUD_STORAGE_KEY, JSON.stringify(settings));
                localStorage.setItem(PLACEMENT_CORE_AUTO_MIGRATION_KEY, "1");
            }
            // R is a direct action key, so old installs must not silently keep
            // the master R-Insta switch in the historical false default.
            if (localStorage.getItem(INSTA_HOTKEY_AUTO_MIGRATION_KEY) !== "1") {
                settings.instaKill = true;
                localStorage.setItem(HUD_STORAGE_KEY, JSON.stringify(settings));
                localStorage.setItem(INSTA_HOTKEY_AUTO_MIGRATION_KEY, "1");
            }
            return settings;
        } catch {
            return { ...HUD_DEFAULTS };
        }
    }
 
    function saveHudSettings() {
        try {
            const settings = normalizeHudSettings(hudState);
            delete settings.syncStatus;
            delete settings.syncTargetName;
            localStorage.setItem(HUD_STORAGE_KEY, JSON.stringify(settings));
        } catch {
            // Saved settings are optional; the mod still works when storage is unavailable.
        }
    }

    function applyHudSettings(nextSettings) {
        hudState = {
            ...normalizeHudSettings({ ...hudState, ...nextSettings }),
            debugText: hudState.debugText
        };
        saveHudSettings();
        sendHudCommand({ type: "hydrate", settings: { ...hudState } });
        renderHud();
    }

    function applyHudPreset(name) {
        const presets = {
            performance: {
                fpsBoost: true,
                smoothVisuals: false,
                reloadArcs: false,
                entityDanger: true,
                notificationTracers: true,
                groundGrid: false,
                espLines: false,
                predictionGhost: false,
                placementVisuals: false,
                cooldownBars: false,
                weaponXpBar: false,
                chatHistory: false,
                combatTelemetry: false,
                debugPanel: false
            },
            combat: {
                fpsBoost: true,
                smoothVisuals: true,
                reloadArcs: true,
                entityDanger: true,
                notificationTracers: true,
                groundGrid: false,
                esp: true,
                espLines: true,
                predictionGhost: true,
                placementVisuals: true,
                cooldownBars: true,
                weaponXpBar: true,
                chatHistory: true,
                combatTelemetry: true,
                telemetryProjectileHits: true,
                telemetrySpikeKnockback: true,
                telemetryActualAim: true,
                telemetryDamageHealing: true,
                reactionMs: 20
            },
            visual: {
                fpsBoost: false,
                groundGrid: true,
                esp: true,
                espLines: true,
                predictionGhost: true,
                placementVisuals: true,
                cooldownBars: true,
                weaponXpBar: true,
                chatHistory: true,
                combatTelemetry: true,
                telemetryProjectileHits: true,
                telemetrySpikeKnockback: true,
                telemetryActualAim: true,
                telemetryBuildingOwners: true,
                telemetryShameCount: true,
                telemetryDamageHealing: true
            }
        };
        if (presets[name]) applyHudSettings(presets[name]);
    }

    function applyForceFullServersPreference(value) {
        const enabled = value !== false;
        window.__KittyForceFullServers = enabled;
        try {
            if (enabled) localStorage.setItem("moofoll", "1");
            else localStorage.removeItem("moofoll");
        } catch {
            // The bundle patches still honor the in-memory flag when storage is blocked.
        }
    }
 
    function sendHudCommand(detail) {
        if (detail && typeof detail === "object") {
            const forceFullValue = detail.type === "set" && detail.key === "forceFullServers"
                ? detail.value
                : detail.type === "hydrate" && detail.settings &&
                    Object.prototype.hasOwnProperty.call(detail.settings, "forceFullServers")
                    ? detail.settings.forceFullServers
                    : null;
            if (forceFullValue != null) applyForceFullServersPreference(forceFullValue);
            const placementValue = detail.type === "set" && detail.key === "smartAutoPlace"
                ? detail.value
                : detail.type === "hydrate" && detail.settings &&
                    Object.prototype.hasOwnProperty.call(detail.settings, "smartAutoPlace")
                    ? detail.settings.smartAutoPlace
                    : null;
            if (placementValue != null) window.__KittySmartAutoPlace = placementValue !== false;
        }
        if (document.documentElement && detail && typeof detail === "object") {
            const __kittySpinningValue = detail.type === "set" && detail.key === "spinningWindmills"
                ? detail.value
                : detail.type === "hydrate" && detail.settings &&
                    Object.prototype.hasOwnProperty.call(detail.settings, "spinningWindmills")
                    ? detail.settings.spinningWindmills
                    : null;
            if (__kittySpinningValue != null) {
                document.documentElement.setAttribute(
                    "data-kitty-spinning-windmills",
                    __kittySpinningValue ? "1" : "0"
                );
            }
            const __kittyFpsBoostValue = detail.type === "set" && detail.key === "fpsBoost"
                ? detail.value
                : detail.type === "hydrate" && detail.settings &&
                    Object.prototype.hasOwnProperty.call(detail.settings, "fpsBoost")
                    ? detail.settings.fpsBoost
                    : null;
            if (__kittyFpsBoostValue != null) {
                document.documentElement.setAttribute(
                    "data-kitty-fps-boost",
                    __kittyFpsBoostValue ? "1" : "0"
                );
            }
            const __kittyGroundGridValue = detail.type === "set" && detail.key === "groundGrid"
                ? detail.value
                : detail.type === "hydrate" && detail.settings &&
                    Object.prototype.hasOwnProperty.call(detail.settings, "groundGrid")
                    ? detail.settings.groundGrid
                    : null;
            if (__kittyGroundGridValue != null) {
                document.documentElement.setAttribute(
                    "data-kitty-ground-grid",
                    __kittyGroundGridValue ? "1" : "0"
                );
            }
        }
        window.dispatchEvent(new CustomEvent("MooMooOPHudCommand", { detail }));
    }
 
    function setHudControlValue(key, value) {
        const control = hudControls.get(key);
        if (!control) return;
        if (control.type === "checkbox") control.checked = Boolean(value);
        else {
            control.value = value == null ? "" : String(value);
            if (control._kittyValueOutput)
                control._kittyValueOutput.textContent = control.value;
        }
    }

    function renderKittyBindingButton(button, binding) {
        if (!button) return;
        button.textContent = "";
        const parts = String(binding || "").split("+").filter(Boolean);
        parts.forEach((part, index) => {
            if (index) {
                const plus = document.createElement("span");
                plus.className = "mm-hotkey-plus";
                plus.textContent = "+";
                button.appendChild(plus);
            }
            const keycap = document.createElement("kbd");
            keycap.textContent = kittyBindingLabelPart(part);
            button.appendChild(keycap);
        });
        button.setAttribute("aria-label", "Rebind " + (button.dataset.kittyBindingLabel || "Kitty action") + ", currently " + parts.map(kittyBindingLabelPart).join(" plus "));
    }

    function refreshKittyBindingButtons() {
        document.querySelectorAll("#" + HUD_ID + " [data-kitty-binding-action]").forEach((button) => {
            const action = button.dataset.kittyBindingAction;
            if (action === hotkeyCaptureAction) return;
            button.classList.remove("mm-capturing");
            renderKittyBindingButton(button, hudState.keybinds && hudState.keybinds[action]);
        });
    }

    function finishKittyBindingCapture() {
        if (hotkeyCaptureButton) hotkeyCaptureButton.classList.remove("mm-capturing");
        hotkeyCaptureAction = null;
        hotkeyCaptureButton = null;
        refreshKittyBindingButtons();
    }

    function beginKittyBindingCapture(action, button) {
        finishKittyBindingCapture();
        hotkeyCaptureAction = action;
        hotkeyCaptureButton = button;
        button.classList.add("mm-capturing");
        button.textContent = "Press input… · Backspace cancels";
        button.setAttribute("aria-label", "Waiting for a new key or mouse button");
    }

    function setKittyBinding(action, binding) {
        const entry = KITTY_BINDING_ACTIONS.find((candidate) => candidate.id === action);
        if (!entry) return false;
        const normalized = normalizeKittyBinding(binding, KITTY_DEFAULT_KEYBINDS[action]);
        const next = { ...KITTY_DEFAULT_KEYBINDS, ...(hudState.keybinds || {}) };
        const previous = next[action];
        const conflict = KITTY_BINDING_ACTIONS.find((candidate) =>
            candidate.id !== action && next[candidate.id] === normalized
        );
        next[action] = normalized;
        if (conflict) next[conflict.id] = previous;
        hudState.keybinds = next;
        saveHudSettings();
        sendHudCommand({ type: "set", key: "keybinds", value: { ...next } });
        refreshKittyBindingButtons();
        showZoomIndicator(conflict
            ? entry.action + " rebound · swapped with " + conflict.action
            : entry.action + " rebound");
        return true;
    }

    function captureKittyBindingEvent(event, mouse) {
        if (!hotkeyCaptureAction) return false;
        if (!mouse && event.code === "Backspace") {
            event.preventDefault();
            event.stopImmediatePropagation();
            finishKittyBindingCapture();
            showZoomIndicator("Keybind change cancelled");
            return true;
        }
        const binding = kittyBindingFromEvent(event, mouse);
        event.preventDefault();
        event.stopImmediatePropagation();
        if (!binding) return true;
        const action = hotkeyCaptureAction;
        finishKittyBindingCapture();
        setKittyBinding(action, binding);
        return true;
    }

    function renderHud() {
        if (document.documentElement) {
            document.documentElement.setAttribute("data-kitty-fps-boost", hudState.fpsBoost ? "1" : "0");
            document.documentElement.setAttribute("data-kitty-ground-grid", hudState.groundGrid ? "1" : "0");
            document.documentElement.style.setProperty("--kitty-enemy", hudState.enemyColor);
            document.documentElement.style.setProperty("--kitty-ally", hudState.allyColor);
            document.documentElement.style.setProperty("--kitty-friend", hudState.friendColor);
            document.documentElement.style.setProperty("--kitty-own", hudState.ownColor);
        }
        Object.entries(hudState).forEach(([key, value]) => setHudControlValue(key, value));
        refreshKittyBindingButtons();
        const chatHistory = document.getElementById(CHAT_HISTORY_ID);
        if (chatHistory) {
            chatHistory.classList.toggle("kitty-chat-disabled", !hudState.chatHistory);
            chatHistory.setAttribute("aria-hidden", String(!hudState.chatHistory));
            requestAnimationFrame(positionKittyNativeTooltip);
        }
        const friendList = document.querySelector("#" + HUD_ID + " [data-hud-friends]");
        if (friendList) {
            friendList.textContent = "";
            const names = Array.isArray(hudState.friendNames) ? hudState.friendNames : [];
            if (!names.length) {
                const empty = document.createElement("small");
                empty.textContent = "No friends yet — every non-teammate starts as an enemy.";
                friendList.appendChild(empty);
            } else {
                names.forEach((name) => {
                    const chip = document.createElement("span");
                    chip.className = "mm-hud-friend-chip";
                    chip.textContent = name;
                    friendList.appendChild(chip);
                });
            }
        }
        const status = document.querySelector("#" + HUD_ID + " [data-hud-status]");
        const syncStatus = document.querySelector("#" + HUD_ID + " [data-hud-sync-status]");
        if (syncStatus) {
            const syncText = String(hudState.syncStatus || "Sync off");
            syncStatus.textContent = syncText;
            syncStatus.dataset.syncPhase = /^Synced\b/i.test(syncText)
                ? "synced"
                : /^(?:Syncing|Reconnecting)/i.test(syncText)
                    ? "syncing"
                    : /(?:failed|error|blocked)/i.test(syncText)
                        ? "error"
                        : "off";
        }
        if (!status) return;
        const enabled = [
            hudState.autoHeal && "heal",
            hudState.antiInsta && "anti-insta",
            hudState.soldierAuto && "soldier",
            hudState.movementGear && "speed",
            hudState.matThief && "mat thief",
            hudState.multiTargetBreak && "multi-break",
            hudState.mobSteal && "mob steal",
            hudState.placementDefense && "placement defense",
            hudState.antiRetrapPush && "anti-retrap",
            hudState.teammateTrapRescue && "trap rescue",
            hudState.turretSteal && "turret finisher",
            hudState.spikeGearCounter && "spike counter",
            hudState.dashMovement && "dash break",
            hudState.assassinAutomation && "assassin",
            hudState.autoRespawn && "auto respawn",
            hudState.bushMode && "bush ambush",
            hudState.animalTrap && "animal trap",
            hudState.passiveMobTrap && "passive mob trap",
            hudState.bossTeleporter && "boss TP",
            hudState.smartAutoPlace && "smart auto place",
            hudState.smartQuadTraps && "auto quad traps",
            hudState.smartQuadSpikes && "auto quad spikes",
            hudState.autoSpikeSpam && "trap spike fill",
            hudState.autoSpikeKill && "lethal spike push",
            hudState.smartAutoReplace && "smart replace",
            hudState.smartAntiBoostPlace && "smart anti-boost",
            hudState.smartMovingMills && "moving mills",
            hudState.antiBoostInsta && "boost insta",
            hudState.boostSpikeKill && "boost + spike",
            hudState.antiCollision && "collision guard",
            hudState.combatTelemetry && "telemetry",
            hudState.syncTargetName && "sync: " + hudState.syncTargetName
        ].filter(Boolean);
        status.textContent = enabled.length ? "Active: " + enabled.join(" · ") : "Automation paused";
        const debug = document.querySelector("#" + HUD_ID + " [data-hud-debug]");
        if (debug) {
            debug.hidden = !hudState.debugPanel;
            debug.textContent = hudState.debugPanel
                ? (typeof hudState.debugText === "string" && hudState.debugText) || "Waiting for live game state…"
                : "";
        }
    }
 
    function setHudTooltip(element, message) {
        if (!element || typeof message !== "string" || !message.trim()) return element;
        element.dataset.hudTooltip = message.trim();
        return element;
    }

    function addHudToggle(container, key, label, subtitle) {
        const row = document.createElement("label");
        row.className = "mm-hud-row";
        setHudTooltip(row, label + ": " + subtitle);
        const text = document.createElement("span");
        const title = document.createElement("strong");
        title.textContent = label;
        const hint = document.createElement("small");
        hint.textContent = subtitle;
        text.append(title, hint);
        const input = document.createElement("input");
        input.type = "checkbox";
        input.checked = Boolean(hudState[key]);
        input.addEventListener("change", () => {
            hudState[key] = input.checked;
            saveHudSettings();
            sendHudCommand({ type: "set", key, value: input.checked });
            renderHud();
        });
        row.append(text, input);
        container.appendChild(row);
        hudControls.set(key, input);
    }
 
    function addHudNumber(container, key, label, subtitle) {
        const bounds = HUD_NUMERIC_BOUNDS[key];
        const row = document.createElement("label");
        row.className = "mm-hud-number";
        setHudTooltip(
            row,
            label + ": " + subtitle + ". Allowed " + bounds.min + "–" + bounds.max + ", step " + bounds.step + "."
        );
        const text = document.createElement("span");
        const title = document.createElement("strong");
        title.textContent = label;
        const hint = document.createElement("small");
        hint.textContent = subtitle;
        text.append(title, hint);
        const input = document.createElement("input");
        input.type = "number";
        input.min = String(bounds.min);
        input.max = String(bounds.max);
        input.step = String(bounds.step);
        input.value = String(hudState[key]);
        input.addEventListener("change", () => {
            const value = clampHudNumber(key, Number(input.value));
            hudState[key] = value;
            saveHudSettings();
            sendHudCommand({ type: "set", key, value });
            renderHud();
        });
        row.append(text, input);
        container.appendChild(row);
        hudControls.set(key, input);
    }

    function addHudSlider(container, key, label, subtitle) {
        const bounds = HUD_NUMERIC_BOUNDS[key];
        const row = document.createElement("label");
        row.className = "mm-hud-slider";
        setHudTooltip(
            row,
            label + ": " + subtitle + ". Allowed " + bounds.min + "–" + bounds.max + "."
        );
        const text = document.createElement("span");
        const title = document.createElement("strong");
        title.textContent = label;
        const hint = document.createElement("small");
        hint.textContent = subtitle;
        text.append(title, hint);
        const control = document.createElement("span");
        control.className = "mm-hud-slider-control";
        const input = document.createElement("input");
        input.type = "range";
        input.min = String(bounds.min);
        input.max = String(bounds.max);
        input.step = String(bounds.step);
        input.value = String(hudState[key]);
        const value = document.createElement("output");
        value.textContent = input.value;
        input._kittyValueOutput = value;
        input.addEventListener("input", () => {
            value.textContent = String(clampHudNumber(key, Number(input.value)));
        });
        input.addEventListener("change", () => {
            const next = clampHudNumber(key, Number(input.value));
            hudState[key] = next;
            value.textContent = String(next);
            saveHudSettings();
            sendHudCommand({ type: "set", key, value: next });
            renderHud();
        });
        control.append(input, value);
        row.append(text, control);
        container.appendChild(row);
        hudControls.set(key, input);
    }

    function addHudText(container, key, label, subtitle, options = {}) {
        const row = document.createElement("label");
        row.className = "mm-hud-text";
        setHudTooltip(row, label + ": " + subtitle);
        const text = document.createElement("span");
        const title = document.createElement("strong");
        title.textContent = label;
        const hint = document.createElement("small");
        hint.textContent = subtitle;
        text.append(title, hint);
        const input = document.createElement("input");
        input.className = "mm-hud-message";
        input.type = options.password ? "password" : "text";
        input.maxLength = options.maxLength || 120;
        input.placeholder = options.placeholder || "";
        input.value = String(hudState[key] || "");
        input.addEventListener("input", () => {
            hudState[key] = input.value.slice(0, input.maxLength);
            saveHudSettings();
        });
        input.addEventListener("change", () => {
            hudState[key] = input.value.trim().slice(0, input.maxLength);
            saveHudSettings();
            sendHudCommand({ type: "set", key, value: hudState[key] });
            renderHud();
        });
        row.append(text, input);
        container.appendChild(row);
        hudControls.set(key, input);
    }

    function addHudColor(container, key, label, subtitle) {
        const row = document.createElement("label");
        row.className = "mm-hud-color";
        setHudTooltip(row, label + ": " + subtitle);
        const text = document.createElement("span");
        const title = document.createElement("strong");
        title.textContent = label;
        const hint = document.createElement("small");
        hint.textContent = subtitle;
        text.append(title, hint);
        const input = document.createElement("input");
        input.type = "color";
        input.value = normalizeHudColor(hudState[key], HUD_DEFAULTS[key]);
        input.setAttribute("aria-label", label);
        input.addEventListener("input", () => {
            hudState[key] = normalizeHudColor(input.value, HUD_DEFAULTS[key]);
            saveHudSettings();
            sendHudCommand({ type: "set", key, value: hudState[key] });
            renderHud();
        });
        row.append(text, input);
        container.appendChild(row);
        hudControls.set(key, input);
    }
 
    function addHudSection(panel, heading) {
        const section = document.createElement("section");
        section.className = "mm-hud-section";
        const title = document.createElement("h3");
        title.textContent = heading;
        setHudTooltip(title, heading + " settings");
        section.appendChild(title);
        panel.appendChild(section);
        return section;
    }

    function attachHudTooltipController(root, tooltip) {
        let activeTarget = null;
        const position = (clientX, clientY) => {
            if (!activeTarget || tooltip.hidden) return;
            const margin = 10;
            let left = clientX + 14;
            let top = clientY + 18;
            const width = tooltip.offsetWidth;
            const height = tooltip.offsetHeight;
            if (left + width > window.innerWidth - margin)
                left = Math.max(margin, clientX - width - 14);
            if (top + height > window.innerHeight - margin)
                top = Math.max(margin, clientY - height - 14);
            tooltip.style.left = left + "px";
            tooltip.style.top = top + "px";
        };
        const show = (target, clientX, clientY) => {
            const message = target && target.dataset && target.dataset.hudTooltip;
            if (!message) return;
            activeTarget = target;
            tooltip.textContent = message;
            tooltip.hidden = false;
            position(clientX, clientY);
        };
        const hide = () => {
            activeTarget = null;
            tooltip.hidden = true;
        };
        root.addEventListener("pointerover", (event) => {
            const target = event.target.closest && event.target.closest("[data-hud-tooltip]");
            if (!target || !root.contains(target)) return;
            show(target, event.clientX, event.clientY);
        });
        root.addEventListener("pointermove", (event) => {
            activeTarget && position(event.clientX, event.clientY);
        });
        root.addEventListener("pointerout", (event) => {
            if (
                activeTarget &&
                !activeTarget.contains(event.relatedTarget)
            )
                hide();
        });
        root.addEventListener("focusin", (event) => {
            const target = event.target.closest && event.target.closest("[data-hud-tooltip]");
            if (!target) return;
            const bounds = target.getBoundingClientRect();
            show(target, bounds.left + bounds.width / 2, bounds.top);
        });
        root.addEventListener("focusout", hide);
        root.addEventListener("mouseleave", hide);
    }

    let kittyHudLauncherPositionFrame = 0;
    function positionKittyHudLauncher() {
        kittyHudLauncherPositionFrame && cancelAnimationFrame(kittyHudLauncherPositionFrame);
        kittyHudLauncherPositionFrame = requestAnimationFrame(() => {
            kittyHudLauncherPositionFrame = 0;
            const launcher = document.getElementById(KITTY_HUD_LAUNCHER_ID);
            if (!launcher) return;
            const edge = window.innerWidth <= 700 ? 8 : 14;
            let bottom = edge;
            const minimap = document.getElementById("mapDisplay");
            if (minimap && window.getComputedStyle(minimap).display !== "none") {
                const mapBounds = minimap.getBoundingClientRect();
                const launcherWidth = launcher.offsetWidth || 72;
                const launcherHeight = launcher.offsetHeight || 36;
                const launcherLeft = edge;
                const launcherRight = launcherLeft + launcherWidth;
                const launcherTop = window.innerHeight - edge - launcherHeight;
                const margin = 10;
                const overlapsMap =
                    launcherRight > mapBounds.left - margin &&
                    launcherLeft < mapBounds.right + margin &&
                    launcherTop < mapBounds.bottom + margin &&
                    window.innerHeight - edge > mapBounds.top - margin;
                if (overlapsMap)
                    bottom = Math.ceil(window.innerHeight - mapBounds.top + margin);
            }
            launcher.style.left = edge + "px";
            launcher.style.bottom = Math.min(
                Math.max(edge, bottom),
                Math.max(edge, window.innerHeight - (launcher.offsetHeight || 36) - edge),
            ) + "px";
        });
    }

    function mountKittyHudLauncher() {
        if (!document.body) return;
        let launcher = document.getElementById(KITTY_HUD_LAUNCHER_ID);
        if (!launcher) {
            launcher = document.createElement("button");
            launcher.id = KITTY_HUD_LAUNCHER_ID;
            launcher.type = "button";
            launcher.textContent = "Menu";
            launcher.setAttribute("aria-controls", HUD_ID);
            launcher.setAttribute("aria-label", "Open Kitty Klient menu");
            launcher.addEventListener("click", (event) => {
                event.preventDefault();
                event.stopPropagation();
                setKittyHudOpen(true);
            });
            document.body.appendChild(launcher);
        }
        launcher.setAttribute("aria-expanded", String(hudOpen));
        launcher.classList.toggle("kitty-hud-open", hudOpen);
        syncKittyAuxPanelVisibility();
        positionKittyHudLauncher();
        setTimeout(positionKittyHudLauncher, 250);
        setTimeout(positionKittyHudLauncher, 1000);
    }
 
    function mountHud() {
        if (hudMounted || !document.body) return;
        if (document.getElementById(HUD_ID)) {
            hudMounted = true;
            mountKittyHudLauncher();
            return;
        }
        hudMounted = true;
        hudState = { ...hudState, ...readHudSettings() };
 
        const style = document.createElement("style");
        style.id = HUD_ID + "-style";
        style.textContent = [
            "#moomoo-op-hud{--mm-bg:rgba(8,5,13,.95);--mm-surface:rgba(20,12,30,.88);--mm-line:rgba(168,85,247,.4);--mm-text:#fff;--mm-muted:#d8b4fe;--mm-accent:#a855f7;position:fixed;z-index:2147483646;inset:0;display:grid;place-items:center;padding:28px;font:13px/1.3 system-ui,-apple-system,BlinkMacSystemFont,'Segoe UI',sans-serif;color:var(--mm-text);pointer-events:none;background:rgba(0,0,0,.42);backdrop-filter:none;contain:strict}",
            "#moomoo-op-hud.mm-hud-collapsed{display:none}#moomoo-op-hud *,#moomoo-op-hud *:before,#moomoo-op-hud *:after{box-sizing:border-box}#moomoo-op-hud button,#moomoo-op-hud input{font:inherit}",
            "#kitty-klient-hud-launcher{position:fixed;z-index:2147483645;left:14px;bottom:14px;min-width:72px;min-height:36px;padding:0 14px;border:1px solid rgba(192,132,252,.8);border-radius:10px;background:linear-gradient(135deg,rgba(8,5,13,.9),rgba(76,29,149,.88));color:#fff;font:900 12px/1 system-ui,-apple-system,BlinkMacSystemFont,'Segoe UI',sans-serif;cursor:pointer;box-shadow:0 0 14px rgba(139,92,246,.48);text-shadow:0 0 8px #8b5cf6;transition:transform .12s ease,opacity .12s ease,box-shadow .12s ease}#kitty-klient-hud-launcher:hover{transform:translateY(-1px);box-shadow:0 0 21px rgba(192,132,252,.72)}#kitty-klient-hud-launcher.kitty-hud-open{opacity:0;pointer-events:none}",
            "#moomoo-op-hud .mm-hud-panel{pointer-events:auto;width:min(1040px,calc(100vw - 56px));height:min(720px,calc(100vh - 56px));display:grid;grid-template-rows:auto auto minmax(0,1fr);overflow:hidden;border:1px solid rgba(192,132,252,.7);border-radius:18px;background:var(--mm-bg);box-shadow:0 0 24px rgba(139,92,246,.38),0 22px 70px rgba(0,0,0,.7);backdrop-filter:none;contain:layout paint style}",
            "#moomoo-op-hud .mm-hud-panel{background-image:radial-gradient(circle at 15% 0%,rgba(168,85,247,.16),transparent 34%),radial-gradient(circle at 92% 100%,rgba(109,40,217,.12),transparent 38%)}#moomoo-op-hud .mm-hud-section{transition:transform .14s ease,border-color .14s ease;content-visibility:auto;contain-intrinsic-size:170px;contain:layout paint style}#moomoo-op-hud .mm-hud-section:hover{transform:translateY(-1px);border-color:rgba(192,132,252,.58)}#moomoo-op-hud .mm-hud-nav button{position:relative}#moomoo-op-hud .mm-hud-nav button.mm-active:after{content:'';position:absolute;left:22%;right:22%;bottom:2px;height:2px;border-radius:99px;background:linear-gradient(90deg,#7c3aed,#e9d5ff,#7c3aed);box-shadow:0 0 8px #a855f7}",
            "#moomoo-op-hud .mm-hud-head{display:flex;align-items:center;justify-content:space-between;gap:18px;padding:18px 20px 12px;border-bottom:1px solid var(--mm-line)}#moomoo-op-hud .mm-hud-brand{margin:0;font-family:'Segoe Print','Bradley Hand','Brush Script MT',cursive;font-style:italic;font-size:29px;line-height:1;color:#050208!important;-webkit-text-stroke:1px #17101f;text-shadow:-2px 1px 0 #a855f7,2px -1px 0 #6d28d9,0 0 13px #c084fc!important;transform:skewX(-8deg)}#moomoo-op-hud .mm-hud-head-info{margin-left:auto}#moomoo-op-hud .mm-hud-close{display:grid;place-items:center;flex:0 0 auto;width:34px;height:34px;padding:0;border:1px solid rgba(192,132,252,.55);border-radius:9px;background:rgba(9,5,14,.76);color:#fff;font:900 24px/1 Arial,sans-serif;cursor:pointer;text-shadow:0 0 9px #a855f7}#moomoo-op-hud .mm-hud-close:hover{border-color:#e9d5ff;background:rgba(109,40,217,.3);box-shadow:0 0 13px rgba(168,85,247,.55)}",
            "#moomoo-op-hud .mm-hud-status{margin:0;color:#fff;font-size:11px;font-weight:800;text-align:right;text-shadow:0 0 8px #8b5cf6}#moomoo-op-hud .mm-hud-escape{color:var(--mm-muted);font-size:10px;white-space:nowrap}",
            "#moomoo-op-hud .mm-hud-nav{display:flex;gap:6px;padding:10px 14px;border-bottom:1px solid var(--mm-line);overflow-x:auto}#moomoo-op-hud .mm-hud-nav button{border:1px solid transparent;border-radius:9px;background:transparent;color:#fff;padding:8px 13px;cursor:pointer;font-weight:800;text-shadow:0 0 7px #8b5cf6}#moomoo-op-hud .mm-hud-nav button:hover,#moomoo-op-hud .mm-hud-nav button.mm-active{border-color:#a855f7;background:rgba(109,40,217,.28);box-shadow:0 0 12px rgba(168,85,247,.35)}",
            "#moomoo-op-hud .mm-hud-pages{min-height:0;overflow:auto;padding:14px}#moomoo-op-hud .mm-hud-page{display:none;grid-template-columns:repeat(2,minmax(0,1fr));align-content:start;gap:12px}#moomoo-op-hud .mm-hud-page.mm-active{display:grid}",
            "#moomoo-op-hud .mm-hud-section{padding:13px 14px;border:1px solid var(--mm-line);border-radius:12px;background:var(--mm-surface);box-shadow:inset 0 0 18px rgba(109,40,217,.08)}#moomoo-op-hud h3{margin:0 0 8px;font-size:11px;text-transform:uppercase;letter-spacing:.11em;color:#d8b4fe;text-shadow:0 0 7px #7c3aed}",
            "#moomoo-op-hud .mm-hud-row,#moomoo-op-hud .mm-hud-number,#moomoo-op-hud .mm-hud-color{display:flex;justify-content:space-between;align-items:center;gap:10px;padding:6px 0;cursor:pointer}#moomoo-op-hud .mm-hud-text{display:grid;gap:5px;padding:6px 0}#moomoo-op-hud .mm-hud-row span,#moomoo-op-hud .mm-hud-number span,#moomoo-op-hud .mm-hud-color span,#moomoo-op-hud .mm-hud-text>span{display:grid;gap:2px}#moomoo-op-hud strong{font-size:13px;color:#fff;text-shadow:0 0 6px #7c3aed}#moomoo-op-hud small{color:var(--mm-muted);font-size:10px}",
            "#moomoo-op-hud input[type='checkbox']{appearance:none;width:36px;height:20px;margin:0;border:1px solid var(--mm-line);border-radius:999px;background:#21172b;position:relative;flex:0 0 auto;cursor:pointer}#moomoo-op-hud input[type='checkbox']:after{content:'';position:absolute;top:2px;left:2px;width:14px;height:14px;border-radius:50%;background:#fff;box-shadow:0 0 7px #c084fc;transition:transform .14s ease}#moomoo-op-hud input[type='checkbox']:checked{background:#7c3aed;border-color:#c084fc;box-shadow:0 0 10px rgba(168,85,247,.65)}#moomoo-op-hud input[type='checkbox']:checked:after{transform:translateX(16px)}",
            "#moomoo-op-hud input[type='number']{width:68px;border:1px solid var(--mm-line);border-radius:7px;background:#09050e;color:#fff;padding:6px;text-align:right}#moomoo-op-hud input[type='color']{width:42px;height:30px;padding:3px;border:1px solid var(--mm-line);border-radius:8px;background:#09050e;cursor:pointer}#moomoo-op-hud input[type='color']::-webkit-color-swatch{border:0;border-radius:5px}#moomoo-op-hud .mm-hud-message{width:100%;border:1px solid var(--mm-line);border-radius:8px;background:#09050e;color:#fff;padding:8px;margin:3px 0 7px}",
            "#moomoo-op-hud .mm-hud-slider{display:grid;grid-template-columns:minmax(0,1fr) minmax(150px,42%);align-items:center;gap:12px;padding:8px 0;cursor:pointer}#moomoo-op-hud .mm-hud-slider>span:first-child{display:grid;gap:2px}#moomoo-op-hud .mm-hud-slider-control{display:grid;grid-template-columns:minmax(0,1fr) 25px;align-items:center;gap:8px}#moomoo-op-hud .mm-hud-slider output{color:#fff;font:900 12px/1 ui-monospace,SFMono-Regular,Menlo,monospace;text-align:right;text-shadow:0 0 8px #a855f7}#moomoo-op-hud input[type='range']{appearance:none;width:100%;height:5px;border-radius:999px;background:linear-gradient(90deg,#6d28d9,#c084fc);box-shadow:0 0 9px rgba(168,85,247,.5);cursor:pointer}#moomoo-op-hud input[type='range']::-webkit-slider-thumb{appearance:none;width:16px;height:16px;border:2px solid #e9d5ff;border-radius:50%;background:#7c3aed;box-shadow:0 0 10px #c084fc}",
            "#moomoo-op-hud .mm-hud-adaptive-status{display:block;margin:1px 0 7px;padding:6px 8px;border:1px solid rgba(168,85,247,.28);border-radius:7px;background:rgba(9,5,14,.5);color:#fff;font:800 10px/1.25 ui-monospace,SFMono-Regular,Menlo,monospace;text-shadow:0 0 7px #7c3aed}",
            "#moomoo-op-hud .mm-hud-reset{border:1px solid var(--mm-line);border-radius:8px;background:#0b0711;color:#fff;padding:8px;cursor:pointer}#moomoo-op-hud .mm-hud-reset:hover{border-color:var(--mm-accent);box-shadow:0 0 11px rgba(168,85,247,.45)}#moomoo-op-hud .mm-hud-preset-grid{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:7px;margin-bottom:8px}#moomoo-op-hud .mm-hotkey-list{display:grid;gap:4px}#moomoo-op-hud .mm-hotkey-entry{display:grid;grid-template-columns:minmax(150px,.88fr) minmax(0,1.6fr) auto;gap:10px;align-items:center;padding:7px 0;border-bottom:1px solid rgba(168,85,247,.16)}#moomoo-op-hud .mm-hotkey-entry:last-child{border-bottom:0}#moomoo-op-hud .mm-hotkey-combo{display:flex;flex-wrap:wrap;gap:4px;align-items:center}#moomoo-op-hud kbd{display:inline-flex;align-items:center;justify-content:center;min-width:24px;min-height:23px;padding:2px 7px;border:1px solid rgba(216,180,254,.72);border-bottom-width:2px;border-radius:6px;background:linear-gradient(#1f142b,#0a0610);color:#fff;font:900 10px/1 ui-monospace,SFMono-Regular,Menlo,monospace;box-shadow:0 0 8px rgba(168,85,247,.24);text-shadow:0 0 6px #7c3aed}#moomoo-op-hud .mm-hotkey-plus{color:#c4b5fd;font-size:9px;font-weight:900}#moomoo-op-hud .mm-hotkey-action{display:grid;gap:2px}#moomoo-op-hud .mm-hotkey-action small{line-height:1.3}#moomoo-op-hud .mm-hotkey-intro{display:grid;grid-column:1/-1;gap:9px}#moomoo-op-hud .mm-hotkey-intro-actions{display:flex;gap:7px;flex-wrap:wrap}#moomoo-op-hud .mm-hotkey-bind{min-height:32px;padding:4px 7px;border:1px solid rgba(168,85,247,.42);border-radius:8px;background:rgba(9,5,14,.78);cursor:pointer;text-align:left}#moomoo-op-hud .mm-hotkey-bind:hover{border-color:#c084fc;box-shadow:0 0 12px rgba(168,85,247,.36)}#moomoo-op-hud .mm-hotkey-bind.mm-capturing{border-color:#facc15;box-shadow:0 0 16px rgba(250,204,21,.4);animation:mm-hotkey-capture 1s ease-in-out infinite alternate}#moomoo-op-hud .mm-hotkey-row-reset{width:29px;height:29px;padding:0;border:1px solid rgba(168,85,247,.32);border-radius:7px;background:transparent;color:#d8b4fe;cursor:pointer}#moomoo-op-hud .mm-hotkey-row-reset:hover{border-color:#c084fc;color:#fff}@keyframes mm-hotkey-capture{to{filter:brightness(1.35)}}@media(max-width:720px){#moomoo-op-hud .mm-hotkey-entry{grid-template-columns:1fr auto}#moomoo-op-hud .mm-hotkey-action{grid-column:1/-1;grid-row:2}}",
            "#moomoo-op-hud .mm-hud-discord{display:flex;align-items:center;justify-content:center;min-height:38px;padding:0 14px;border:1px solid #c084fc;border-radius:9px;background:linear-gradient(135deg,#4c1d95,#7c3aed);color:#fff!important;font-size:12px;font-weight:900;text-decoration:none;box-shadow:0 0 14px rgba(168,85,247,.4);text-shadow:0 0 7px #2e1065!important;transition:transform .12s ease,filter .12s ease}#moomoo-op-hud .mm-hud-discord:hover{filter:brightness(1.14);transform:translateY(-1px);box-shadow:0 0 18px rgba(192,132,252,.62)}",
            "#moomoo-op-hud .mm-hud-friend-actions{display:grid;grid-template-columns:1fr auto auto;gap:6px;align-items:center}#moomoo-op-hud .mm-hud-friend-actions .mm-hud-message{margin:3px 0 7px}#moomoo-op-hud .mm-hud-friend-list{display:flex;flex-wrap:wrap;gap:6px;min-height:24px;align-items:center}#moomoo-op-hud .mm-hud-friend-chip{border:1px solid rgba(250,204,21,.68);border-radius:999px;background:rgba(250,204,21,.12);color:#fff;padding:4px 8px;box-shadow:0 0 8px rgba(250,204,21,.28);text-shadow:0 0 6px #eab308}",
            "#moomoo-op-hud .mm-hud-debug{margin:4px 0 7px;white-space:pre-wrap;overflow-wrap:anywhere;border:1px solid var(--mm-line);border-radius:8px;background:rgba(0,0,0,.45);color:#fff;padding:8px;font:10px/1.4 ui-monospace,SFMono-Regular,Menlo,monospace;text-shadow:0 0 6px #7c3aed}",
            "#moomoo-op-hud [data-hud-sync-status][data-sync-phase='synced']{border-color:rgba(74,222,128,.72);box-shadow:0 0 11px rgba(74,222,128,.25);color:#dcfce7}#moomoo-op-hud [data-hud-sync-status][data-sync-phase='syncing']{border-color:rgba(192,132,252,.82);animation:mm-hud-sync-pulse .8s ease-in-out infinite alternate}#moomoo-op-hud [data-hud-sync-status][data-sync-phase='error']{border-color:rgba(248,113,113,.8);color:#fee2e2}@keyframes mm-hud-sync-pulse{from{box-shadow:0 0 4px rgba(168,85,247,.2)}to{box-shadow:0 0 14px rgba(192,132,252,.55)}}",
            "#moomoo-op-hud .mm-hud-tooltip{position:fixed;z-index:2147483647;max-width:min(320px,calc(100vw - 20px));padding:7px 9px;border:1px solid rgba(192,132,252,.72);border-radius:8px;background:rgba(7,3,12,.96);color:#fff;box-shadow:0 0 15px rgba(139,92,246,.5),0 8px 24px rgba(0,0,0,.55);font:700 11px/1.35 system-ui,-apple-system,BlinkMacSystemFont,'Segoe UI',sans-serif;text-shadow:0 0 7px #7c3aed;pointer-events:none;white-space:normal;overflow-wrap:anywhere}#moomoo-op-hud .mm-hud-tooltip[hidden]{display:none}",
            "@media(max-width:720px){#moomoo-op-hud{padding:10px}#moomoo-op-hud .mm-hud-panel{width:calc(100vw - 20px);height:calc(100vh - 20px)}#moomoo-op-hud .mm-hud-page{grid-template-columns:1fr}#moomoo-op-hud .mm-hud-head{padding:14px}#moomoo-op-hud .mm-hud-brand{font-size:23px}}"
        ].join("");
        (document.head || document.documentElement).appendChild(style);
 
        const root = document.createElement("aside");
        root.id = HUD_ID;
        root.className = "mm-hud-collapsed";
        root.setAttribute("aria-label", "kitty klient controls");
        const panel = document.createElement("div");
        panel.className = "mm-hud-panel";
        panel.addEventListener("mousedown", (event) => event.stopPropagation());
        panel.addEventListener("click", (event) => event.stopPropagation());
 
        const head = document.createElement("header");
        head.className = "mm-hud-head";
        const brand = document.createElement("h2");
        brand.className = "mm-hud-brand";
        brand.textContent = "kitty klient";
        setHudTooltip(brand, "kitty klient v" + KITTY_KLIENT_VERSION);
        const headInfo = document.createElement("div");
        headInfo.className = "mm-hud-head-info";
        const status = document.createElement("p");
        status.className = "mm-hud-status";
        status.dataset.hudStatus = "";
        setHudTooltip(status, "Currently enabled Kitty automation and combat features");
        const escapeHint = document.createElement("span");
        escapeHint.className = "mm-hud-escape";
        escapeHint.textContent = "ESC toggles · WASDFVR returns straight to the game";
        setHudTooltip(escapeHint, "Escape closes Kitty. Gameplay keys close it and continue directly into the game.");
        headInfo.append(status, escapeHint);
        const closeButton = document.createElement("button");
        closeButton.className = "mm-hud-close";
        closeButton.type = "button";
        closeButton.setAttribute("aria-label", "Close Kitty Klient menu");
        closeButton.textContent = "×";
        setHudTooltip(closeButton, "Close the Kitty HUD and return to the game");
        closeButton.addEventListener("click", () => {
            if (kittyTutorialActive) stopKittyTutorial(false);
            setKittyHudOpen(false);
        });
        head.append(brand, headInfo, closeButton);

        const nav = document.createElement("nav");
        nav.className = "mm-hud-nav";
        const pages = document.createElement("div");
        pages.className = "mm-hud-pages";
        const pageMap = new Map();
        const activatePage = (name) => {
            nav.querySelectorAll("button").forEach((button) => button.classList.toggle("mm-active", button.dataset.page === name));
            pages.querySelectorAll(".mm-hud-page").forEach((page) => page.classList.toggle("mm-active", page.dataset.page === name));
        };
        const addPage = (name, label, tooltip) => {
            const button = document.createElement("button");
            button.type = "button";
            button.dataset.page = name;
            button.textContent = label;
            setHudTooltip(button, tooltip);
            button.addEventListener("click", () => activatePage(name));
            nav.appendChild(button);
            const page = document.createElement("div");
            page.className = "mm-hud-page";
            page.dataset.page = name;
            pages.appendChild(page);
            pageMap.set(name, page);
            return page;
        };
        const automationPage = addPage("automation", "Automation", "Automatic survival, equipment, gathering, and cleanup features");
        const combatPage = addPage("combat", "Combat", "Combat combos, defenses, boosts, and friend targeting controls");
        const placementPage = addPage("placement", "Placement", "Kitty predictive placement controllers and scoring methods");
        const visualsPage = addPage("visuals", "Visuals", "Player markers, connection lines, predictions, cooldowns, and chat visuals");
        const syncPage = addPage("sync", "Sync", "Copy movement or synchronize combat with another Kitty teammate");
        const configPage = addPage("config", "Config", "Ranges, diagnostics, chat messages, saved settings, and community links");
        const hotkeysPage = addPage("hotkeys", "Hotkeys", "Complete Kitty and core MooMoo keyboard and mouse shortcut library");
        panel.append(head, nav, pages);
 
        const survivalAutomation = addHudSection(automationPage, "Survival & defense");
        addHudToggle(survivalAutomation, "autoHeal", "Autoheal", "Immediate first food, then tick-paced recovery");
        addHudToggle(survivalAutomation, "soldierAuto", "Soldier helmet", "Idle protection and combat range");
        addHudToggle(survivalAutomation, "movementGear", "Movement gear", "Speed gear while moving, Soldier around enemies, and EMP Helmet only while idle and out of combat, plus adaptive tails");
        addHudToggle(survivalAutomation, "trapEscape", "Trap escape", "Face and continuously break the locking trap; pulse Tank only for a real break swing, use the best normal hat between hits, and place up to two smart rear defenses");
        addHudToggle(survivalAutomation, "automaticStateRepair", "Automatic state repair", "Recover orphaned Bull, Tank, Turret, held-attack, forced-aim, and borrowed-tool state after an interrupted packet or timer");
        addHudToggle(survivalAutomation, "antiBoostInsta", "Anti-boost insta", "Full-insta an enemy boost-rushing into range");
        addHudToggle(survivalAutomation, "antiInsta", "Lethal anti-insta", "Use unified melee/projectile/turret/spike prediction to place one defensive spike before otherwise lethal incoming damage");
        addHudToggle(survivalAutomation, "antiCollision", "Anti TP / spike collision", "Predictive braking: always stop before Teleporters, avoid hostile spikes while safe, quick-right-click toward TPs, then allow one deliberate release/re-press bypass");
        addHudToggle(survivalAutomation, "antiCollisionPauseCombat", "Spike guard combat auto-pause", "Keep Teleporter protection active but temporarily ignore hostile-spike stopping while combat is active");
        addHudToggle(survivalAutomation, "shieldDefense", "Shield defense", "Face polearm and turret attacks");
        addHudToggle(survivalAutomation, "placementDefense", "Projectile placement defense", "Place one legal wall, blocker, platform, or mill toward an obstruction-aware incoming projectile that is imminent or lethal");
        addHudToggle(survivalAutomation, "antiRetrapPush", "Anti-retrap push", "If your locking trap is already a one-hit Hammer break, briefly push a close enemy away with your ready primary before resuming escape");
        addHudToggle(survivalAutomation, "teammateTrapRescue", "Teammate trap rescue", "Great Hammer a trap holding a reachable teammate or friend, using Tank when owned, then restore immediately");

        const utilityAutomation = addHudSection(automationPage, "Equipment & utility");
        addHudToggle(utilityAutomation, "autoAcceptTeamRequests", "Auto accept team requests", "Immediately accept incoming requests to join your team");
        addHudToggle(utilityAutomation, "autoDeclineTeamRequests", "Auto decline team requests", "Immediately decline incoming requests to join your team");
        addHudToggle(utilityAutomation, "autoRespawn", "Auto respawn", "Re-enter after the local death screen appears; disabled by default");
        addHudToggle(utilityAutomation, "musketRecharge", "Weapon recharge", "Main-first queue that briefly borrows held attacks to reload the other weapon");
        addHudToggle(utilityAutomation, "autoPurchase", "Auto purchase", "Monkey Tail → Soldier → Stick/Bull path → gear → wings");
        addHudToggle(utilityAutomation, "matThief", "Mat thief", "Last-hit nearby mills, turrets, and teleporters; starts disabled");
        addHudToggle(utilityAutomation, "multiTargetBreak", "Multi-target breaking", "While holding an attack or cleaning, choose a nearby legal swing angle that hits the most breakables");
        addHudToggle(utilityAutomation, "mobSteal", "Mob steal", "Predictive last hit: Monkey Tail off three ticks early, Bull on two ticks early, then revalidates and swings");
        addHudToggle(utilityAutomation, "turretSteal", "Turret finisher", "Use a ready Turret Gear shot on a visible enemy or animal at 25 health or less without stealing another combat action");
        addHudToggle(utilityAutomation, "dashMovement", "Boost-pad dash break", "When H is held on a boost pad, Tank + a ready one-hit weapon destroys each manual pad on the same local phase");
        addHudToggle(utilityAutomation, "assassinAutomation", "Assassin automation", "When stationary and safe, buy Assassin Gear if affordable, wait out concealment safety, then equip it; starts disabled");
        addHudNumber(utilityAutomation, "assassinSafeMs", "Assassin safe delay", "Stationary and invisibility-cooldown milliseconds required after movement, damage, combat, or turret danger");
        addHudNumber(utilityAutomation, "assassinMinHealth", "Assassin minimum health", "Minimum health percentage required before concealment");
        addHudNumber(utilityAutomation, "assassinDangerRange", "Assassin danger radius", "Enemy-player and hostile-turret exclusion distance");
        addHudToggle(utilityAutomation, "spinningWindmills", "Spinning windmills", "Allow native mill rotation; off freezes every mill without a background placement scanner");
        addHudToggle(utilityAutomation, "forceFullServers", "Force full servers", "Show, select, and attempt to join servers the normal browser marks full; the server can still reject a truly full shard");
        addHudToggle(utilityAutomation, "bushMode", "Bush ambush", "B toggles concealment; automatic ambush says SURPRISE, while R manually runs the same boost-first combo and says Meow; empty clicks stay concealed and incoming damage turns it off");

        const tabSync = addHudSection(syncPage, "Connection & target");
        const syncHint = document.createElement("small");
        syncHint.textContent = "Press Y, then click a teammate for a one-way link. They only follow you back if they independently press Y and click you. Click your target again to disconnect.";
        setHudTooltip(syncHint, "Visible movement works with any teammate; exact off-screen action and tick timing requires Kitty on both clients");
        tabSync.appendChild(syncHint);
        addHudToggle(tabSync, "syncStatusChat", "Sync status chat", "Announce Syncing..., Synced!, and Sync stopped. once per link-state transition");
        addHudText(tabSync, "syncRelayUrl", "Relay WebSocket", "Optional Kitty-to-Kitty exact sync across browsers; visible teammate following works without it", {
            maxLength: 200,
            placeholder: "wss://sync.example.com"
        });
        addHudText(tabSync, "syncRoom", "Private sync room", "Kitty users need the same case-sensitive phrase for exact cross-browser timing", {
            maxLength: 64,
            placeholder: "team room phrase",
            password: true
        });
        const syncReadout = document.createElement("pre");
        syncReadout.className = "mm-hud-debug";
        syncReadout.dataset.hudSyncStatus = "";
        syncReadout.textContent = "Sync off";
        setHudTooltip(syncReadout, "Selected teammate and available sync precision");
        tabSync.appendChild(syncReadout);

        const syncMovement = addHudSection(syncPage, "Follow movement");
        addHudToggle(syncMovement, "syncMovement", "Movement follow", "Walk to the selected teammate's predicted side position");
        addHudNumber(syncMovement, "syncFollowGap", "Hitbox gap", "Minimum pixels kept between the edges of both player hitboxes");
        addHudNumber(syncMovement, "syncStopTolerance", "Stop tolerance", "Extra arrival buffer so momentum stops before violating the hitbox gap");
        addHudNumber(syncMovement, "syncResumeTolerance", "Resume tolerance", "How far the side target may drift before following resumes");
        addHudNumber(syncMovement, "syncPredictionMs", "Position prediction", "Milliseconds of velocity lead used to hide visible follow delay");
        addHudNumber(syncMovement, "syncMoveRefreshMs", "Direction refresh", "Maximum milliseconds between movement-direction updates");
        addHudToggle(syncMovement, "syncPauseInCombat", "Pause follow in combat", "Stop automatic movement while either linked player is fighting");
        addHudToggle(syncMovement, "syncWasdCombatOnly", "WASD keeps combat link", "Manual WASD disables movement follow but preserves combat synchronization");

        const syncCatchup = addHudSection(syncPage, "Catch-up behavior");
        addHudToggle(syncCatchup, "syncCatchupGear", "Fast catch-up gear", "Use the fastest owned hat, tail, and compatible tool while far behind and out of combat");
        addHudNumber(syncCatchup, "syncCatchupDistance", "Catch-up starts", "Side-target distance that activates fast equipment");
        addHudNumber(syncCatchup, "syncCatchupReleaseDistance", "Catch-up ends", "Side-target distance that restores copied or previous equipment");

        const syncActions = addHudSection(syncPage, "Copied actions");
        addHudToggle(syncActions, "syncCopyWeapons", "Copy weapons", "Mirror compatible weapon selections from the selected teammate");
        addHudToggle(syncActions, "syncCopyBuilds", "Copy build items", "Mirror compatible placeable selections from the selected teammate");
        addHudToggle(syncActions, "syncCopyGear", "Copy hats & tails", "Mirror compatible gear pairs, including same-tick hat and tail updates");
        addHudToggle(syncActions, "syncCopyAim", "Copy aim", "Mirror exact aim packets when a Kitty or compatible mod bridge provides them");
        addHudToggle(syncActions, "syncCopyAttacks", "Copy attacks", "Mirror press-and-release swings from the selected teammate");
        addHudToggle(syncActions, "syncTickCombat", "Combat tick sync", "Queue full instas on one shared relay timestamp so Turret, weapons, and projectiles start together");
 
        const visuals = addHudSection(visualsPage, "Visuals");
        addHudToggle(visuals, "fpsBoost", "FPS boost", "Uses cheaper Kitty visual effects and bounded overlay budgets without slowing combat checks");
        addHudToggle(visuals, "smoothVisuals", "Polished entity styling", "Layered translucent markers, soft outlines, and relation-colored depth without covering the playfield");
        addHudToggle(visuals, "reloadArcs", "Smooth reload arcs", "Primary, secondary, and Turret refill arcs around you and the selected enemy");
        addHudToggle(visuals, "entityDanger", "Entity danger aura", "Pulse a restrained danger field around close hostile players and hostile animals");
        addHudToggle(visuals, "notificationTracers", "Clan alert tracers", "While you are on a team, place a directional ! marker halfway from your player toward a teammate's distress ping");
        addHudToggle(visuals, "groundGrid", "Ground grid", "Draws a camera-aligned purple world grid beneath players, animals, and placeables");
        addHudToggle(visuals, "esp", "Player & animal markers", "Colored circles plus a rotating red target reticle on the nearest enemy");
        addHudToggle(visuals, "espLines", "Player direction arrows", "Large high-contrast relationship-colored arrows sit midway between you and each player; enemies use the thickest style");
        addHudToggle(visuals, "predictionGhost", "Prediction ghost", "A translucent copy projects ahead by half your live ping");
        addHudToggle(visuals, "placementVisuals", "Placement previews", "Shows blocked sample slots, scored legal candidates, predicted pre-places, and the exact slots Kitty selects");
        addHudToggle(visuals, "cooldownBars", "Tool cooldown bars", "Three refill bars track primary, secondary, and Turret Gear cooldowns independently");
        addHudToggle(visuals, "weaponXpBar", "Weapon XP bar", "Compact local progress bar uses the live weapon XP and next upgrade threshold");
        addHudToggle(visuals, "chatHistory", "Stacked chat bubbles", "Shows up to three unexpired messages above each player plus the in-game chat-history panel");

        const relationshipColors = addHudSection(visualsPage, "Relationship colors");
        addHudColor(relationshipColors, "enemyColor", "Enemies", "Player markers, target reticle, chat, and hostile placeables");
        addHudColor(relationshipColors, "allyColor", "Teammates", "Team player markers, chat, and allied placeables");
        addHudColor(relationshipColors, "friendColor", "Friends", "Saved friend markers and chat-history entries");
        addHudColor(relationshipColors, "ownColor", "Your placeables", "Tint used for structures that you own");

        const combatTelemetry = addHudSection(visualsPage, "Combat telemetry");
        addHudToggle(combatTelemetry, "combatTelemetry", "Telemetry master", "Enable the bounded canvas telemetry layer; individual rows below remain independently configurable");
        addHudToggle(combatTelemetry, "telemetryProjectileHits", "Predicted projectile hits", "Draw obstruction-aware hostile projectile paths, impact times, and damage");
        addHudToggle(combatTelemetry, "telemetrySpikeKnockback", "Spike knockback", "Mark predicted hostile spike follow-up damage from incoming attacks");
        addHudToggle(combatTelemetry, "telemetryActualAim", "Actual aim", "Draw the server-facing weapon direction and reach for visible players");
        addHudToggle(combatTelemetry, "telemetryBuildingOwners", "Building owners", "Label nearby breakables with their resolved owner name or server id");
        addHudToggle(combatTelemetry, "telemetryShameCount", "Shame count", "Show Kitty's locally tracked rapid-heal shame value beside your player");
        addHudToggle(combatTelemetry, "telemetryDamageHealing", "Damage & healing values", "Stack recent health losses and gains above affected visible players");
 
        const actions = addHudSection(combatPage, "Gear & boost controls");
        addHudToggle(actions, "bullHelmet", "Bull helmet", "Equip Bull and the damage tail in the exact ready primary-swing phase, then restore on the next server tick");
        addHudToggle(actions, "tankRightClick", "Smart right-click", "With Shield: block close or ranged pressure; otherwise use Tank + main on its exact swing phase");
        addHudToggle(actions, "instaKill", "R insta", "Bull primary, then Turret secondary, then Soldier restore");
        addHudToggle(actions, "autoInsta", "Click insta", "Left-click starts the full combo; Shift+click starts Crossbow boost insta");
        addHudToggle(actions, "autoTrapInsta", "Owned-trap insta", "Full-insta a nearby caught enemy; every Great Hammer Insta attempts a legal spike after the combo, preferring target contact");
        addHudToggle(actions, "spikeGearCounter", "Spike Gear counter", "With Spike Gear + Corrupt X Wings owned, pre-arm both in one phase against a close Bull-primary swing, then answer with Bull + your ready primary");
        addHudToggle(actions, "autoSpikeInsta", "Spike-tick strike", "Ping-timed Turret lead-in, then Bull + Polearm/Katana on predicted allied-spike contact");
        addHudToggle(actions, "instaSync", "Insta sync", "Predictively matches allied-player and allied-turret projectile arrivals");
        addHudToggle(actions, "boostBreak", "Shift + F boost-break", "Place and boost forward, snap 180° for each destroy swing, then instantly face forward again");

        const kittyInstas = addHudSection(combatPage, "Kitty Insta library");
        addHudToggle(kittyInstas, "autoBowUpgradeInsta", "Bow Upgrade Insta", "Any primary works: with Bow, a special placeable, Turret Gear, and two saved upgrades, R fires Bow → Crossbow → Musket; an in-range Short Sword, Katana, or Polearm runs the normal Insta first and hands its Bow shot straight into the upgrades. Friendly and personal-turret shots can trigger it too");
        addHudToggle(kittyInstas, "reverseInsta", "Reverse R order", "R uses Turret + secondary first, then Bull + primary; Shift+R remains Kitty's Crossbow boost Insta");
        addHudToggle(kittyInstas, "oneTickInsta", "One-Tick Insta", "Shift+P toggles the secondary-first one-server-tick combo; projectile timing is prediction-adjusted");
        addHudToggle(kittyInstas, "appleInsta", "Apple Insta", "Automatically uses Turret + Great Hammer, then Bull + Polearm against a nearby Soldier-helmet target");
        addHudToggle(kittyInstas, "bleedInsta", "Bleed Insta", "Automatically runs the variant-damage secondary-first combo against a vulnerable non-Soldier target");
        addHudToggle(kittyInstas, "knockbackInsta", "Knockback Insta", "Predicts whether the opening hit pushes a target into an allied spike, then commits the Polearm finisher");
        addHudToggle(kittyInstas, "velTickInsta", "VelTick Insta", "T toggles predictive 170–245px spacing, Turret lead-in, and Bull + Polearm finish");
        addHudToggle(kittyInstas, "polearmAids", "Polearm Aids", "Against a target in your or an ally's trap: Tank + Great Hammer, then Bull + Polearm and a legal contact spike");
        addHudToggle(kittyInstas, "autoPushInsta", "Auto-Push Insta", "Aligns behind a trapped enemy to push it into an allied spike, and upgrades predicted spike contact to a full Insta");
        addHudToggle(kittyInstas, "boostSpikeKill", "Boost + Spike", "G predicts the nearest enemy, sends legal side/contact spikes first, then boosts through the open lane");

        const smartPlacementCore = addHudSection(placementPage, "Kitty smart auto place");
        addHudToggle(smartPlacementCore, "smartAutoPlace", "General smart placement", "Generic scored spike-and-pit-trap scanner; automatic quad trap and spike toggles continue independently when this is off");
        addHudToggle(smartPlacementCore, "smartPreplace", "Predictive pre-place", "Lead enemy velocity by ping plus one tick and place before contact");
        addHudToggle(smartPlacementCore, "smartMultiPlace", "Multi-place", "Choose several high-scoring non-overlapping slots in one placement phase");
        addHudToggle(smartPlacementCore, "smartQuadTraps", "Automatic quad traps", "Without a hotkey, fill up to four legal non-overlapping trap-pressure angles when an enemy enters the automatic placement radius");
        addHudToggle(smartPlacementCore, "smartQuadSpikes", "Automatic quad spikes", "Without a hotkey, prefer up to four legal contact, trapped-surround, or knockback-chain spikes around a close enemy");
        addHudToggle(smartPlacementCore, "smartSpikeContact", "Spike contact", "Score legal spikes that touch or intercept an enemy");
        addHudToggle(smartPlacementCore, "smartTrapContact", "Trap and retrap", "Score pit traps that catch, retrap, or block an enemy's route");
        addHudToggle(smartPlacementCore, "smartKnockbackChain", "Knockback chaining", "Prefer spikes that push an enemy into allied traps, spikes, or map hazards");
        addHudToggle(smartPlacementCore, "smartTrapSurround", "Trapped surround", "Fill legal escape-side slots around an enemy already held by an allied trap");
        addHudToggle(smartPlacementCore, "smartAngleDenial", "Placement denial", "Score slots that intercept the enemy's own useful placement angles");
        addHudToggle(smartPlacementCore, "smartAutoPushWeight", "Auto-push weighting", "Raise candidates that support pushing a trapped enemy into allied spikes");
        const placementReadout = document.createElement("pre");
        placementReadout.className = "mm-hud-debug";
        placementReadout.dataset.hudPlacementStatus = "";
        placementReadout.textContent = "STARTING — waiting for live game state";
        setHudTooltip(placementReadout, "Live placement state, legal/scored slot counts, sent packet count, and equipped item readiness");
        smartPlacementCore.appendChild(placementReadout);

        const smartPlacementEvents = addHudSection(placementPage, "Event placement");
        addHudToggle(smartPlacementEvents, "autoSpikeSpam", "Trapped-player spike fill", "Continuously finds and places a legal contact spike around a trapped enemy when your movement shows attack intent");
        addHudToggle(smartPlacementEvents, "autoSpikeKill", "Lethal spike push", "Predictively place a spike that keeps contact while pushing a killable enemy into allied spikes");
        addHudToggle(smartPlacementEvents, "smartAutoReplace", "Destroyed-object replace", "Immediately rescan and refill useful legal slots when a nearby structure disappears");
        addHudToggle(smartPlacementEvents, "smartSpikeSyncPlace", "Spike-sync replace", "Prioritize a contact spike when a nearby enemy's allied trap is broken");
        addHudToggle(smartPlacementEvents, "smartAntiBoostPlace", "Anti-boost fallback", "Blocker ring → side/rear spikes → trap ring → wall ring against a predicted boost rush");
        addHudToggle(smartPlacementEvents, "smartMovingMills", "Moving three-mill", "Probe every movement tick and place a geometry-spaced three-mill row as soon as every slot is clear");
        addHudToggle(smartPlacementEvents, "smartInstaUtilityPlace", "Projectile utility place", "Place an equipped Platform before compatible projectile-sync and boost-projectile stages");

        const wildlifePlacement = addHudSection(placementPage, "Wildlife placement");
        addHudToggle(wildlifePlacement, "animalTrap", "Animal trap", "Trap a nearby hostile animal; fall back to a spike when no usable pit trap exists, except against wolves");
        addHudToggle(wildlifePlacement, "passiveMobTrap", "Passive mob trap", "Predictively place a pit trap on a nearby passive mob's path; hostile animals and bosses keep priority, and already trapped mobs are ignored");
        addHudToggle(wildlifePlacement, "bossTeleporter", "Boss teleporter", "Place a Teleporter between you and nearby Moostafa or Moofie when it is owned, affordable, and the boss is not already trapped");

        const smartPlacementTuning = addHudSection(placementPage, "Placement tuning");
        addHudToggle(smartPlacementTuning, "adaptiveSmartness", "Adaptive smartness", "Lower effective placement depth during sustained FPS pressure, then recover it gradually when frames are stable—faster during combat");
        addHudSlider(smartPlacementTuning, "smartDepth", "Smartness depth ceiling", "1 is lightweight and reactive; 10 searches more angles, enemy branches, and future movement at a higher CPU cost");
        const adaptiveSmartnessReadout = document.createElement("small");
        adaptiveSmartnessReadout.className = "mm-hud-adaptive-status";
        adaptiveSmartnessReadout.dataset.hudAdaptiveSmartness = "";
        adaptiveSmartnessReadout.textContent = "Effective depth 5/5 · sampling FPS";
        setHudTooltip(adaptiveSmartnessReadout, "The first number is the depth currently used by placement searches; the second is your selected ceiling");
        smartPlacementTuning.appendChild(adaptiveSmartnessReadout);
        addHudNumber(smartPlacementTuning, "smartPlaceAccuracy", "Angle accuracy", "Placement samples per half-ring");
        addHudNumber(smartPlacementTuning, "smartMaxPlacements", "Maximum placements", "Legal non-overlapping items per phase");
        addHudNumber(smartPlacementTuning, "smartPlaceDelay", "Pre-place delay", "Milliseconds before a predictive pre-place; ping is subtracted");

        const friends = addHudSection(combatPage, "Friends");
        const friendHint = document.createElement("small");
        friendHint.textContent = "Press U to friend or I to mark an enemy, then click a non-teammate. Teammates are always allies and cannot be added as friends or enemies.";
        setHudTooltip(friendHint, "Friend rules apply to automatic targeting, traps, instas, and player markers");
        const friendList = document.createElement("div");
        friendList.className = "mm-hud-friend-list";
        friendList.dataset.hudFriends = "";
        setHudTooltip(friendList, "Saved non-teammate friends; use U + click to add and I + click to remove");
        friends.append(friendHint, friendList);

        const tuning = addHudSection(configPage, "Distance tuning");
        addHudNumber(tuning, "soldierRange", "Soldier radius", "Pixels");
        addHudNumber(tuning, "combatRange", "Combat radius", "Tail behavior cutoff");
        addHudNumber(tuning, "gearHoldTicks", "Gear restore grace", "Ticks allowed for delayed equipment-state reconciliation");
        addHudNumber(tuning, "antiBoostRange", "Boost-insta radius", "Pixels");
        addHudNumber(tuning, "antiCollisionRange", "Collision guard radius", "Maximum distance for Teleporter and hostile-spike prediction");
        addHudNumber(tuning, "reactionMs", "Reaction scan", "Milliseconds between live-state checks");

        const diagnostics = addHudSection(configPage, "Diagnostics");
        addHudToggle(diagnostics, "debugPanel", "Runtime debug", "Show live owner, target, trap, and cooldown reasons");
        const debugReadout = document.createElement("pre");
        debugReadout.className = "mm-hud-debug";
        debugReadout.dataset.hudDebug = "";
        debugReadout.hidden = !hudState.debugPanel;
        setHudTooltip(debugReadout, "Live action owner, target distance, trap state, reload state, and scan age");
        diagnostics.appendChild(debugReadout);
 
        const messages = addHudSection(configPage, "Chat automation");
        addHudToggle(messages, "instaChat", "Insta complete · Meow!", "Send Meow! after a completed normal or boost insta");
        addHudToggle(messages, "bushChat", "Bush ambush · SURPRISE!!!", "Send SURPRISE!!! when a bush ambush begins");
        addHudToggle(messages, "friendAddedChat", "Friend-added message", "Announce Added friend, [name]! after U + click");
        addHudToggle(messages, "enemyMarkedChat", "Enemy-marked message", "Announce [name] is an enemy! after I + click or betrayal detection");
        addHudToggle(messages, "cleanupProgressChat", "Cleanup progress", "Send the animated Cleaning messages while cleanup runs");
        addHudToggle(messages, "cleanupCompleteChat", "Cleanup completion", "Send Nice and tidy! when cleanup finishes");
        addHudToggle(messages, "boostChat", "Shift + F chat", "Send shuffled speed messages during boost-break");
        addHudToggle(messages, "materialReply", "Material request reply", "Tell teammates and friends your current wood and stone when they ask for materials");
        addHudToggle(messages, "meowChainInsta", "Meow chain insta", "If a recently attacking Kitty teammate says Meow!, start your own ready in-range insta; completion uses the Insta Meow toggle");
        addHudToggle(messages, "modReplyChat", "Mod-question reply", "Reply with the Kitty Klient version when another player asks about mods or clients");
        addHudToggle(messages, "enemyTrapChat", "Enemy trapped message", "Send Ha, I have you in my trap! for trapped enemies");
        addHudToggle(messages, "friendTrapChat", "Friend trapped message", "Send Uh oh! let me free you! for trapped friends");
        addHudToggle(messages, "trapAlertChat", "Self trapped message", "Send Oh no! A trap! once per trapping incident");
        addHudToggle(messages, "deathHistoryChat", "Death history entries", "Add [name] died notices to Kitty's local chat-history panel");
        addHudToggle(messages, "killMessageEnabled", "Auto send on kill", "Posts a chat line when your kill count rises");
        const message = document.createElement("input");
        message.className = "mm-hud-message";
        message.type = "text";
        message.maxLength = 30;
        message.placeholder = "Example: gg!";
        message.value = hudState.killMessage;
        setHudTooltip(message, "Message sent after your kill count increases; maximum 30 characters");
        message.addEventListener("input", () => {
            hudState.killMessage = message.value.slice(0, 30);
            saveHudSettings();
            sendHudCommand({ type: "set", key: "killMessage", value: hudState.killMessage });
        });
        messages.appendChild(message);
        hudControls.set("killMessage", message);

        const community = addHudSection(configPage, "Community");
        const discord = document.createElement("a");
        discord.className = "mm-hud-discord";
        discord.href = "https://discord.gg/mHvC2kJSH";
        discord.target = "_blank";
        discord.rel = "noopener noreferrer";
        discord.textContent = "Join official Discord server";
        setHudTooltip(discord, "Open the official Kitty Klient Discord invite in a new tab");
        community.appendChild(discord);
 
        const savedSettings = addHudSection(configPage, "Saved settings");
        const presetGrid = document.createElement("div");
        presetGrid.className = "mm-hud-preset-grid";
        [
            ["performance", "Performance", "Reduce optional drawing while leaving gameplay settings alone"],
            ["combat", "Combat", "Enable useful combat feedback with a faster reaction scan"],
            ["visual", "Visual", "Enable the full visual toolset and ground grid"]
        ].forEach(([name, label, tooltip]) => {
            const button = document.createElement("button");
            button.className = "mm-hud-reset";
            button.type = "button";
            button.textContent = label;
            setHudTooltip(button, tooltip);
            button.addEventListener("click", () => applyHudPreset(name));
            presetGrid.appendChild(button);
        });
        const reset = document.createElement("button");
        reset.className = "mm-hud-reset";
        reset.type = "button";
        reset.textContent = "Reset saved settings";
        setHudTooltip(reset, "Restore every saved Kitty setting to its default value");
        reset.addEventListener("click", () => {
            applyHudSettings({ ...HUD_DEFAULTS });
        });
        savedSettings.append(presetGrid, reset);

        const hotkeyIntro = addHudSection(hotkeysPage, "Hotkey library");
        hotkeyIntro.classList.add("mm-hotkey-intro");
        const hotkeyIntroText = document.createElement("small");
        hotkeyIntroText.textContent = "Click any binding, then press a keyboard key or mouse button with the modifiers you want. Conflicts swap bindings so no action becomes unreachable. Hold actions stop when their trigger or required modifier is released.";
        const hotkeyIntroActions = document.createElement("div");
        hotkeyIntroActions.className = "mm-hotkey-intro-actions";
        const replayTutorial = document.createElement("button");
        replayTutorial.className = "mm-hud-reset";
        replayTutorial.type = "button";
        replayTutorial.textContent = "Replay tutorial";
        replayTutorial.addEventListener("click", startKittyTutorial);
        const resetBindings = document.createElement("button");
        resetBindings.className = "mm-hud-reset";
        resetBindings.type = "button";
        resetBindings.textContent = "Reset keybinds";
        resetBindings.addEventListener("click", () => {
            hudState.keybinds = { ...KITTY_DEFAULT_KEYBINDS };
            saveHudSettings();
            sendHudCommand({ type: "set", key: "keybinds", value: { ...hudState.keybinds } });
            finishKittyBindingCapture();
            showZoomIndicator("Kitty keybinds reset");
        });
        hotkeyIntroActions.append(replayTutorial, resetBindings);
        hotkeyIntro.append(hotkeyIntroText, hotkeyIntroActions);

        const addHotkeyGroup = (heading, entries) => {
            const section = addHudSection(hotkeysPage, heading);
            const list = document.createElement("div");
            list.className = "mm-hotkey-list";
            entries.forEach((entry) => {
                const row = document.createElement("div");
                row.className = "mm-hotkey-entry";
                const combo = document.createElement("div");
                combo.className = "mm-hotkey-combo";
                if (entry.id) {
                    const bind = document.createElement("button");
                    bind.type = "button";
                    bind.className = "mm-hotkey-bind mm-hotkey-combo";
                    bind.dataset.kittyBindingAction = entry.id;
                    bind.dataset.kittyBindingLabel = entry.action;
                    bind.addEventListener("click", () => beginKittyBindingCapture(entry.id, bind));
                    bind.addEventListener("contextmenu", (event) => event.preventDefault());
                    renderKittyBindingButton(bind, hudState.keybinds[entry.id]);
                    combo.appendChild(bind);
                } else {
                    entry.keys.forEach((key, index) => {
                        if (index) {
                            const plus = document.createElement("span");
                            plus.className = "mm-hotkey-plus";
                            plus.textContent = "+";
                            combo.appendChild(plus);
                        }
                        const keycap = document.createElement("kbd");
                        keycap.textContent = key;
                        combo.appendChild(keycap);
                    });
                }
                const action = document.createElement("span");
                action.className = "mm-hotkey-action";
                const label = document.createElement("strong");
                label.textContent = entry.action;
                const note = document.createElement("small");
                note.textContent = entry.note;
                action.append(label, note);
                row.append(combo, action);
                if (entry.id) {
                    const resetOne = document.createElement("button");
                    resetOne.type = "button";
                    resetOne.className = "mm-hotkey-row-reset";
                    resetOne.textContent = "↺";
                    resetOne.setAttribute("aria-label", "Reset " + entry.action);
                    setHudTooltip(resetOne, "Reset this action to " + KITTY_DEFAULT_KEYBINDS[entry.id]);
                    resetOne.addEventListener("click", () => setKittyBinding(entry.id, KITTY_DEFAULT_KEYBINDS[entry.id]));
                    row.appendChild(resetOne);
                }
                list.appendChild(row);
            });
            section.appendChild(list);
            return section;
        };

        addHotkeyGroup("Menu & view", [
            ...KITTY_BINDING_ACTIONS.filter((entry) => entry.group === "Menu & view"),
            { keys: ["Menu", "or ×"], action: "Open or close by hand", note: "Menu appears at the lower-left during gameplay; × closes the HUD from its header." },
            { keys: ["Any bound action"], action: "Leave HUD into gameplay", note: "A bound gameplay action closes the HUD and continues into the game." },
            { keys: ["Mouse wheel"], action: "Zoom map view", note: "Scroll on the game canvas; trackpads use smooth smaller steps." },
            { keys: ["Tutorial"], action: "Replay onboarding", note: "Use the button beside Play or the button at the top of this page." }
        ]);
        addHotkeyGroup("Combat & gear", KITTY_BINDING_ACTIONS.filter((entry) => entry.group === "Combat & gear"));
        addHotkeyGroup("Building & supplies", KITTY_BINDING_ACTIONS.filter((entry) => entry.group === "Building & supplies"));
        addHotkeyGroup("Modes & automation", KITTY_BINDING_ACTIONS.filter((entry) => entry.group === "Modes & automation"));
        addHotkeyGroup("Friends & teammate sync", KITTY_BINDING_ACTIONS.filter((entry) => entry.group === "Friends & teammate sync"));
        addHotkeyGroup("Core MooMoo controls", [
            { keys: ["W/A/S/D"], action: "Move", note: "Normal movement stays active unless an automation currently owns movement." },
            { keys: ["Mouse"], action: "Aim", note: "Forced build and combat rotations restore to the current mouse direction afterward." },
            { keys: ["Left click", "or Space"], action: "Attack / gather", note: "Standard MooMoo held attack input." },
            { keys: ["1–9"], action: "Select hotbar slot", note: "Standard MooMoo weapon, food, and placeable selection." },
            { keys: ["Enter"], action: "Open chat", note: "Normal MooMoo chat remains available; Esc closes the text box." },
            { keys: ["E"], action: "Toggle native auto-attack", note: "Standard MooMoo automatic gathering and attack toggle." },
            { keys: ["X"], action: "Lock rotation", note: "Kitty automation restores the locked or mouse-facing direction after temporary forced aim." }
        ]);
 
        const tooltip = document.createElement("div");
        tooltip.className = "mm-hud-tooltip";
        tooltip.id = HUD_ID + "-tooltip";
        tooltip.setAttribute("role", "tooltip");
        tooltip.hidden = true;
        root.append(panel, tooltip);
        document.body.appendChild(root);
        mountKittyHudLauncher();
        setKittyHudOpen(false);
        attachHudTooltipController(root, tooltip);
        activatePage("automation");
        renderHud();
    }
 
    function scheduleHudMount() {
        const mountAll = () => {
            installKittyTheme();
            mountMetrics();
            mountKittyChatHistory();
            watchKittyAuxPanelVisibility();
            mountHud();
        };
        if (document.body) mountAll();
        else document.addEventListener("DOMContentLoaded", mountAll, { once: true });
    }

    function compareKittyVersions(left, right) {
        const leftParts = String(left || "").match(/\d+/g) || [];
        const rightParts = String(right || "").match(/\d+/g) || [];
        const length = Math.max(leftParts.length, rightParts.length);
        for (let index = 0; index < length; index += 1) {
            const difference = Number(leftParts[index] || 0) - Number(rightParts[index] || 0);
            if (difference) return difference > 0 ? 1 : -1;
        }
        return 0;
    }

    function safeKittyDownloadUrl(candidate) {
        try {
            const url = new URL(candidate || KITTY_UPDATE_FALLBACK_URL);
            if (
                url.protocol === "https:" &&
                url.hostname === "update.greasyfork.org" &&
                /^\/scripts\/592072(?:\/|$)/.test(url.pathname)
            ) return url.href;
        } catch {
            // The fixed GreasyFork installer remains the safe fallback.
        }
        return KITTY_UPDATE_FALLBACK_URL;
    }

    function mountKittyUpdatePopup(latestVersion, downloadUrl) {
        if (!document.body || document.getElementById(KITTY_UPDATE_POPUP_ID)) return;
        try {
            if (sessionStorage.getItem(KITTY_UPDATE_DISMISS_KEY) === latestVersion) return;
        } catch {
            // A blocked session store should not prevent an update notice.
        }

        const popup = document.createElement("aside");
        popup.id = KITTY_UPDATE_POPUP_ID;
        popup.setAttribute("role", "dialog");
        popup.setAttribute("aria-labelledby", "kitty-update-title");
        popup.setAttribute("aria-describedby", "kitty-update-copy");

        const title = document.createElement("h2");
        title.id = "kitty-update-title";
        title.className = "kitty-update-title";
        title.textContent = "Update available";

        const copy = document.createElement("p");
        copy.id = "kitty-update-copy";
        copy.className = "kitty-update-copy";
        copy.textContent = "A newer Kitty Klient build is ready.";

        const versions = document.createElement("div");
        versions.className = "kitty-update-versions";
        versions.textContent = KITTY_KLIENT_VERSION + "  →  " + latestVersion;

        const download = document.createElement("a");
        download.className = "kitty-update-download";
        download.href = safeKittyDownloadUrl(downloadUrl);
        download.target = "_blank";
        download.rel = "noopener noreferrer";
        download.textContent = "Download update";

        const close = document.createElement("button");
        close.className = "kitty-update-close";
        close.type = "button";
        close.setAttribute("aria-label", "Dismiss update notice");
        close.textContent = "×";
        close.addEventListener("click", () => {
            try {
                sessionStorage.setItem(KITTY_UPDATE_DISMISS_KEY, latestVersion);
            } catch {
                // Closing still works when storage is unavailable.
            }
            popup.remove();
        });

        popup.append(title, copy, versions, download, close);
        document.body.appendChild(popup);
    }

    async function checkForKittyUpdate() {
        const controller = typeof AbortController === "function" ? new AbortController() : null;
        const timeout = window.setTimeout(() => controller && controller.abort(), 5000);
        try {
            const response = await fetch(KITTY_UPDATE_API, {
                cache: "no-store",
                credentials: "omit",
                signal: controller ? controller.signal : undefined
            });
            if (!response.ok) return;
            const release = await response.json();
            const latestVersion = typeof release.version === "string" ? release.version.trim() : "";
            if (!latestVersion || compareKittyVersions(latestVersion, KITTY_KLIENT_VERSION) <= 0) return;
            const showPopup = () => mountKittyUpdatePopup(latestVersion, release.code_url);
            if (document.body) showPopup();
            else document.addEventListener("DOMContentLoaded", showPopup, { once: true });
        } catch {
            // Update checks are optional and must never interfere with the client.
        } finally {
            window.clearTimeout(timeout);
        }
    }

    let escapeClaimedByGameMenu = false;

    function isGameSubmenuOpen() {
        return ["allianceMenu", "storeMenu", "chatHolder"].some((id) => {
            const menu = document.getElementById(id);
            if (!menu) return false;
            return menu.style.display === "block" || window.getComputedStyle(menu).display !== "none";
        });
    }

    function closeHud(root) {
        if (root) setKittyHudOpen(false);
    }

    function isKittyHudTextInput(target, root) {
        if (!root || !target || typeof target.closest !== "function") return false;
        const editable = target.closest([
            "textarea",
            "[contenteditable='true']",
            "[contenteditable='plaintext-only']",
            "input:not([type])",
            "input[type='text']",
            "input[type='search']",
            "input[type='url']",
            "input[type='email']",
            "input[type='tel']",
            "input[type='password']",
            "input[type='number']"
        ].join(","));
        return Boolean(editable && root.contains(editable));
    }

    document.addEventListener("keydown", (event) => {
        if (!kittyTutorialActive || event.key !== "Escape") return;
        const root = document.getElementById(HUD_ID);
        if (isKittyHudTextInput(event.target, root)) {
            // Do not cancel the browser's normal text-field behavior, but keep
            // this Escape press away from every menu/game shortcut listener.
            event.stopImmediatePropagation();
            return;
        }
        stopKittyTutorial(false);
        event.preventDefault();
        event.stopImmediatePropagation();
    }, true);
    window.addEventListener("resize", () => {
        if (kittyTutorialActive) positionKittyTutorial();
    });
    document.addEventListener("scroll", () => {
        if (kittyTutorialActive) positionKittyTutorial();
    }, true);

    document.addEventListener("keydown", (event) => {
        const root = document.getElementById(HUD_ID);
        // Text editing inside Kitty owns these keystrokes. In particular,
        // WASDFVR must type normally and Escape must not close the HUD.
        if (isKittyHudTextInput(event.target, root)) {
            event.stopImmediatePropagation();
            return;
        }
        if (captureKittyBindingEvent(event, false)) return;
        const toggleHudBinding = hudState.keybinds && hudState.keybinds.toggleHud;
        if (kittyBindingMatchesEvent(toggleHudBinding, event, false)) {
            if (!root) return;
            if (escapeClaimedByGameMenu) {
                // Do not let a held Escape key close the game menu and then
                // toggle Kitty Klient open on the first repeat event.
                event.preventDefault();
                event.stopImmediatePropagation();
                return;
            }
            if (isGameSubmenuOpen()) {
                escapeClaimedByGameMenu = true;
                closeHud(root);
                const active = document.activeElement;
                if (active && active.matches("input,textarea,[contenteditable='true']")) active.blur();
                // Keep the trusted Escape event flowing. The game's own close
                // handler dismisses store, alliance, and the chat text box.
                return;
            }
            setKittyHudOpen(root.classList.contains("mm-hud-collapsed"));
            event.preventDefault();
            event.stopImmediatePropagation();
            return;
        }
        if (!root) return;
        const boundGameplayAction = KITTY_BINDING_ACTIONS.some((entry) =>
            entry.id !== "toggleHud" && kittyBindingMatchesEvent(hudState.keybinds[entry.id], event, false)
        );
        if (hudOpen && (/^[wasdfvrui]$/i.test(event.key) || boundGameplayAction)) {
            closeHud(root);
            // Keep the real trusted key event flowing into the game so movement
            // and held actions begin immediately after the menu disappears.
        }
    }, true);

    document.addEventListener("mousedown", (event) => {
        if (captureKittyBindingEvent(event, true)) return;
        if (!isGameSurface(event.target)) return;
        const toggleHudBinding = hudState.keybinds && hudState.keybinds.toggleHud;
        if (kittyBindingMatchesEvent(toggleHudBinding, event, true)) {
            const root = document.getElementById(HUD_ID);
            if (!root) return;
            setKittyHudOpen(root.classList.contains("mm-hud-collapsed"));
            event.preventDefault();
            event.stopImmediatePropagation();
            return;
        }
        if (
            hudOpen &&
            KITTY_BINDING_ACTIONS.some((entry) =>
                entry.id !== "toggleHud" && kittyBindingMatchesEvent(hudState.keybinds[entry.id], event, true)
            )
        )
            closeHud(document.getElementById(HUD_ID));
    }, true);

    document.addEventListener("keyup", (event) => {
        if (event.key === "Escape") escapeClaimedByGameMenu = false;
    }, true);

    window.addEventListener("MooMooKittyMetrics", (event) => {
        if (!event.detail || typeof event.detail !== "object") return;
        mountMetrics();
        const metrics = document.getElementById("kitty-klient-metrics");
        if (!metrics) return;
        const setMetric = (name, value) => {
            const field = metrics.querySelector("[data-metric='" + name + "']");
            if (field) field.textContent = value;
        };
        setMetric("ping", Number.isFinite(event.detail.ping) ? Math.round(event.detail.ping) + "ms" : "--");
        setMetric("fps", Number.isFinite(event.detail.fps) ? String(Math.round(event.detail.fps)) : "--");
        const packetText = String(Math.max(0, Number(event.detail.packets) || 0)) +
            (Number.isFinite(event.detail.pps) ? " · " + Math.round(event.detail.pps) + "/s" : "");
        setMetric("packets", packetText);
    });

    window.addEventListener("MooMooKittyAdaptiveSmartness", (event) => {
        if (!event.detail || typeof event.detail !== "object") return;
        const readout = document.querySelector("#" + HUD_ID + " [data-hud-adaptive-smartness]");
        if (!readout) return;
        const effective = Math.max(1, Math.round(Number(event.detail.effective) || 1));
        const ceiling = Math.max(effective, Math.round(Number(event.detail.ceiling) || effective));
        const fpsValue = Number(event.detail.fps);
        const fps = event.detail.fps != null && Number.isFinite(fpsValue) && fpsValue > 0
            ? Math.round(fpsValue) + " FPS"
            : "sampling FPS";
        const reason = String(event.detail.reason || "holding");
        readout.textContent = "Effective depth " + effective + "/" + ceiling + " · " + fps + " · " + reason;
        readout.dataset.adaptiveState = event.detail.enabled ? "adaptive" : "manual";
    });

    window.addEventListener("MooMooKittyPlacementStatus", (event) => {
        if (!event.detail || typeof event.detail !== "object") return;
        const readout = document.querySelector("#" + HUD_ID + " [data-hud-placement-status]");
        if (!readout) return;
        const state = String(event.detail.state || "idle").toUpperCase();
        const reason = String(event.detail.reason || "waiting");
        const legal = Math.max(0, Number(event.detail.legal) || 0);
        const scored = Math.max(0, Number(event.detail.scored) || 0);
        const sent = Math.max(0, Number(event.detail.sent) || 0);
        const items = String(event.detail.itemSummary || "none");
        readout.textContent = state + " — " + reason + "\nlegal " + legal + " · scored " + scored + " · sent " + sent + "\n" + items;
        readout.dataset.placementState = state.toLowerCase();
    });

    window.addEventListener("MooMooFriendPickNotice", (event) => {
        if (typeof event.detail === "string" && event.detail) {
            showZoomIndicator(event.detail);
        }
    });

    let kittyRespawnTimer = 0;
    window.addEventListener("MooMooKittyLocalDeath", () => {
        if (!hudState.autoRespawn) return;
        kittyRespawnTimer && clearTimeout(kittyRespawnTimer);
        let attempts = 0;
        const tryRespawn = () => {
            kittyRespawnTimer = 0;
            if (!hudState.autoRespawn || ++attempts > 10) return;
            const enterGame = document.getElementById("enterGame");
            const diedText = document.getElementById("diedText");
            const deathScreenVisible = !!(
                diedText &&
                diedText.getClientRects().length &&
                window.getComputedStyle(diedText).display !== "none"
            );
            if (enterGame && deathScreenVisible) {
                enterGame.click();
                return;
            }
            kittyRespawnTimer = window.setTimeout(tryRespawn, 250);
        };
        kittyRespawnTimer = window.setTimeout(tryRespawn, 450);
    });
 
    window.addEventListener("MooMooOPHudState", (event) => {
        if (!event.detail || typeof event.detail !== "object") return;
        const debugText = typeof event.detail.debugText === "string" ? event.detail.debugText : hudState.debugText;
        hudState = { ...normalizeHudSettings({ ...hudState, ...event.detail }), debugText };
        if (!hudSettingsSent) {
            hudSettingsSent = true;
            sendHudCommand({ type: "hydrate", settings: readHudSettings() });
        }
        saveHudSettings();
        renderHud();
    });

    window.addEventListener("MooMooFriendState", (event) => {
        const detail = event.detail;
        if (!detail || typeof detail.name !== "string") return;
        const name = detail.name.trim().slice(0, 15);
        if (!name) return;
        const key = name.toLowerCase();
        const names = Array.isArray(hudState.friendNames) ? hudState.friendNames.slice() : [];
        const existing = names.findIndex((entry) => entry.toLowerCase() === key);
        if (detail.type === "remove" && existing >= 0) names.splice(existing, 1);
        else if (detail.type === "add" && existing < 0) names.push(name);
        else return;
        hudState.friendNames = normalizeHudSettings({ friendNames: names }).friendNames;
        saveHudSettings();
        renderHud();
    });
 
    scheduleHudMount();
    void checkForKittyUpdate();
 
    function patchedViewportCode() {
        // This string replaces a matching section of the game bundle at runtime.
        return `
const __mmZoomBaseWidth = y.maxScreenWidth,
  __mmZoomBaseHeight = y.maxScreenHeight;
let __mmSoldierRange = 400,
  __mmCombatRange = 400,
  __mmGearHoldTicks = 3,
  __mmPassiveSpikeEnemyRange = 400,
  __mmAntiBoostRange = 200,
  __mmAntiCollisionRange = 260,
  __mmSoldierAutoEnabled = !0,
  __mmMovementGearEnabled = !0,
  __mmPassiveSpikeAvoidanceEnabled = !1,
  __mmTrapEscapeEnabled = !0,
  __mmAutomaticStateRepairEnabled = !0,
  __mmAutoSpikeReplaceEnabled = !1,
  __mmAutoAcceptTeamRequestsEnabled = !1,
  __mmAutoDeclineTeamRequestsEnabled = !1,
  __mmAntiBoostEnabled = !1,
  __mmAntiBoostInstaEnabled = !0,
  __mmAntiTrollEnabled = !1,
  __mmAntiCollisionEnabled = !0,
  __mmAntiCollisionPauseCombatEnabled = !0,
  __mmThreatTrapEnabled = !1,
  __mmPassiveMobTrapEnabled = !1,
  __mmBossTeleporterEnabled = !1,
  __mmAutoCloseSpikeEnabled = !1,
  __mmReloadSpikeEnabled = !1,
  __mmShieldDefenseEnabled = !0,
  __mmPlacementDefenseEnabled = !0,
  __mmAntiRetrapPushEnabled = !0,
  __mmTeammateTrapRescueEnabled = !0,
  __mmTurretStealEnabled = !0,
  __mmSpikeGearCounterEnabled = !0,
  __mmDashMovementEnabled = !0,
  __mmMusketRechargeEnabled = !0,
  __mmAutoPurchaseEnabled = !1,
  __mmMatThiefEnabled = !1,
  __mmMultiTargetBreakEnabled = !0,
  __mmMobStealEnabled = !1,
  __mmAssassinAutomationEnabled = !1,
  __mmSpinningWindmillsEnabled = !1,
  __mmForceFullServersEnabled = !0,
  __mmWeaponGrindEnabled = !1,
  __mmBushModeEnabled = !1,
  __mmFpsBoostEnabled = !0,
  __mmSmoothVisualsEnabled = !0,
  __mmReloadArcsEnabled = !0,
  __mmEntityDangerEnabled = !0,
  __mmNotificationTracersEnabled = !0,
  __mmGroundGridEnabled = !1,
  __mmEspEnabled = !0,
  __mmEspLinesEnabled = !0,
  __mmPredictionGhostEnabled = !0,
  __mmPlacementVisualsEnabled = !0,
  __mmCooldownBarsEnabled = !0,
  __mmWeaponXpBarEnabled = !0,
  __mmChatHistoryEnabled = !0,
  __mmCombatTelemetryEnabled = !1,
  __mmTelemetryProjectileHitsEnabled = !0,
  __mmTelemetrySpikeKnockbackEnabled = !0,
  __mmTelemetryActualAimEnabled = !0,
  __mmTelemetryBuildingOwnersEnabled = !0,
  __mmTelemetryShameCountEnabled = !0,
  __mmTelemetryDamageHealingEnabled = !0,
  __mmEnemyColor = "#ff4d5d",
  __mmAllyColor = "#a855f7",
  __mmFriendColor = "#facc15",
  __mmOwnColor = "#d8b4fe",
  __mmBullHelmetEnabled = !0,
  __mmTankRightClickEnabled = !0,
  __mmAllItemsUnlockEnabled = !0,
  __mmInstaUiEnabled = !0,
  __mmAutoInstaEnabled = !0,
  __mmAutoBowUpgradeInstaEnabled = !1,
  __mmReverseInstaEnabled = !1,
  __mmOneTickInstaEnabled = !1,
  __mmAppleInstaEnabled = !1,
  __mmBleedInstaEnabled = !1,
  __mmKnockbackInstaEnabled = !1,
  __mmVelTickInstaEnabled = !1,
  __mmPolearmAidsEnabled = !1,
  __mmAutoPushInstaEnabled = !1,
  __mmBoostSpikeEnabled = !0,
  __mmAutoTrapInstaEnabled = !0,
  __mmAutoSpikeInstaEnabled = !0,
  __mmSmartAutoPlaceEnabled = window.__KittySmartAutoPlace !== !1,
  __mmSmartPreplaceEnabled = !0,
  __mmSmartMultiPlaceEnabled = !0,
  __mmSmartQuadTrapsEnabled = !0,
  __mmSmartQuadSpikesEnabled = !0,
  __mmSmartSpikeContactEnabled = !0,
  __mmSmartTrapContactEnabled = !0,
  __mmSmartKnockbackChainEnabled = !0,
  __mmSmartTrapSurroundEnabled = !0,
  __mmSmartAngleDenialEnabled = !0,
  __mmSmartAutoPushWeightEnabled = !0,
  __mmSmartAutoReplaceEnabled = !1,
  __mmSmartSpikeSyncPlaceEnabled = !1,
  __mmSmartAntiBoostPlaceEnabled = !1,
  __mmSmartMovingMillsEnabled = !1,
  __mmSmartInstaUtilityPlaceEnabled = !1,
  __mmAutoSpikeSpamEnabled = !1,
  __mmAutoSpikeKillEnabled = !1,
  __mmAntiInstaEnabled = !0,
  __mmInstaSyncEnabled = !0,
  __mmBoostBreakEnabled = !0,
  __mmBoostChatEnabled = !0,
  __mmMaterialReplyEnabled = !0,
  __mmMeowChainInstaEnabled = !0,
  __mmInstaChatEnabled = !0,
  __mmBushChatEnabled = !0,
  __mmFriendAddedChatEnabled = !0,
  __mmEnemyMarkedChatEnabled = !0,
  __mmCleanupProgressChatEnabled = !0,
  __mmCleanupCompleteChatEnabled = !0,
  __mmModReplyChatEnabled = !0,
  __mmEnemyTrapChatEnabled = !0,
  __mmFriendTrapChatEnabled = !0,
  __mmTrapAlertChatEnabled = !0,
  __mmDeathHistoryChatEnabled = !0,
  __mmSyncStatusChatEnabled = !0,
  __mmSyncLeaderEnabled = !1,
  __mmSyncFollowerEnabled = !1,
  __mmSyncCombatOnlyEnabled = !1,
  __mmSyncMovementEnabled = !0,
  __mmSyncCopyWeaponsEnabled = !0,
  __mmSyncCopyBuildsEnabled = !0,
  __mmSyncCopyGearEnabled = !0,
  __mmSyncCopyAimEnabled = !0,
  __mmSyncCopyAttacksEnabled = !0,
  __mmSyncCatchupGearEnabled = !0,
  __mmSyncPauseInCombatEnabled = !1,
  __mmSyncWasdCombatOnlyEnabled = !0,
  __mmSyncTickCombatEnabled = !0,
  __mmSyncFollowGap = 12,
  __mmSyncStopTolerance = 4,
  __mmSyncResumeTolerance = 9,
  __mmSyncPredictionMs = 130,
  __mmSyncCatchupDistance = 420,
  __mmSyncCatchupReleaseDistance = 190,
  __mmSyncMoveRefreshMs = 50,
  __mmSyncRelayUrl = "",
  __mmSyncRoom = "",
  __mmDebugPanelEnabled = !1,
  __mmKillMessageEnabled = !0,
  __mmKillMessage = "gg",
  __mmReactionMs = 25,
  __mmAdaptiveSmartnessEnabled = !0,
  __mmSmartDepth = 5,
  __mmSmartPlaceAccuracy = 50,
  __mmSmartMaxPlacements = 4,
  __mmSmartPlaceDelay = 111,
  __mmAssassinSafeMs = 2000,
  __mmAssassinMinHealth = 80,
  __mmAssassinDangerRange = 650;
const __mmDefaultKeybinds = JSON.parse('${JSON.stringify(KITTY_DEFAULT_KEYBINDS)}');
let __mmKeybinds = Object.assign({}, __mmDefaultKeybinds);
const __mmBindingActions = Object.freeze(Object.keys(__mmDefaultKeybinds)),
  __mmBindingHoldActions = new Set([
    "primaryAttack",
    "secondaryAttack",
    "clickBoostInsta",
    "boostSpike",
    "food",
    "trapBuild",
    "spikeBuild",
    "specialBuild",
    "boostBreak",
    "movingMills",
    "movingMillsAlt",
    "bushMode",
  ]),
  __mmActiveBindingActions = new Map(),
  __mmConsumedBindingInputs = new Map();
const __mmShieldWeapon = 11,
  __mmToolHammer = 0,
  __mmMcGrabby = 14,
  __mmShortSword = 3,
  __mmPolearmWeapon = 5,
  __mmTurretGear = 53,
  __mmTurretGearRange = 700,
  __mmEmpHelmet = 22,
  __mmAssassinGear = 56,
  __mmFullInstaRangeMultiplier = 1.5,
  __mmThreatTrapRange = 300,
  __mmThreatAnimalRange = 200,
  __mmPassiveMobTrapRange = 190,
  __mmThreatTrapCooldownMs = 650,
  __mmEnemyTrapChatRange = 1500,
  __mmFriendTrapChatRange = 1500,
  __mmShieldDefenseRange = 240,
  __mmShieldDefenseMs = 750,
  __mmBoosterHat = 12,
  __mmBushGear = 10,
  __mmBushGearPrice = 3e3,
  __mmSnowHat = 15,
  __mmSnowHatPrice = 600,
  __mmFlipperHat = 31,
  __mmFlipperHatPrice = 2500,
  __mmGreatHammer = 10,
  __mmBow = 9,
  __mmKatana = 4,
  __mmCrossbow = 12,
  __mmMusket = 15,
  __mmAngelWings = 13,
  __mmShadowWings = 19,
  __mmBloodWings = 18,
  __mmCorruptXWings = 21;
const __mmUpgradePrerequisiteSnapshot =
    window.__KittyVanillaUpgradePrerequisites || null,
  __mmOriginalWeaponPrerequisites =
    __mmUpgradePrerequisiteSnapshot &&
    Array.isArray(__mmUpgradePrerequisiteSnapshot.weapons)
      ? __mmUpgradePrerequisiteSnapshot.weapons.slice()
      : b && Array.isArray(b.weapons)
        ? b.weapons.map(function (__mmWeapon) {
            return __mmWeapon && __mmWeapon.pre;
          })
        : [],
  __mmOriginalItemPrerequisites =
    __mmUpgradePrerequisiteSnapshot &&
    Array.isArray(__mmUpgradePrerequisiteSnapshot.items)
      ? __mmUpgradePrerequisiteSnapshot.items.slice()
      : b && Array.isArray(b.list)
        ? b.list.map(function (__mmItem) {
            return __mmItem && __mmItem.pre;
          })
        : [];
const __mmAutoPurchaseEntries = Object.freeze({
  monkeyTail: Object.freeze({ id: 11, tail: !0, price: 2e3 }),
  soldier: Object.freeze({ id: 6, tail: !1, price: 4e3 }),
  bull: Object.freeze({ id: 7, tail: !1, price: 6e3 }),
  booster: Object.freeze({ id: 12, tail: !1, price: 6e3 }),
  emp: Object.freeze({ id: 22, tail: !1, price: 6e3 }),
  turret: Object.freeze({ id: 53, tail: !1, price: 1e4 }),
  tank: Object.freeze({ id: 40, tail: !1, price: 15e3 }),
  shadow: Object.freeze({ id: 19, tail: !0, price: 15e3 }),
  angel: Object.freeze({ id: 13, tail: !0, price: 15e3 }),
  blood: Object.freeze({ id: 18, tail: !0, price: 2e4 }),
  corrupt: Object.freeze({ id: 21, tail: !0, price: 2e4 }),
});
let _ = y.maxScreenWidth,
  L = y.maxScreenHeight;
let __mmFoodSpamTimer = 0;
let __mmAutoHealTimer = 0,
  __mmAutoHealEnabled = !0,
  __mmAutoHealWasHealing = !1,
  __mmAutoHealPending = !1,
  __mmAutoHealBitesRemaining = 0,
  __mmAutoHealNextBiteAt = 0,
  __mmAutoHealLastObservedHealth = null,
  __mmAutoHealLastDamageAt = 0,
  __mmAutoHealShameCount = 0,
  __mmLastWeapon = null,
  __mmAutoHealWeapon = null;
let __mmAutoPurchaseTimer = 0,
  __mmAutoPurchasePending = null;
let __mmBushModeRequested = !1,
  __mmBushModeTimer = 0,
  __mmBushExitRestoreTimer = 0,
  __mmBushPurchaseTimer = 0,
  __mmBushPurchaseAt = 0,
  __mmBushHotkeyDown = !1,
  __mmBushPreviousHat = null,
  __mmBushPreviousTail = null,
  __mmBushRestoreOverrideHat = null,
  __mmBushRestoreOverrideTail = null,
  __mmBushRestoreOverrideUntil = 0;
let __mmMatThiefTimer = 0,
  __mmMatThiefReleaseTimer = 0,
  __mmMatThiefAimAngle = null,
  __mmMatThiefReturnAngle = null,
  __mmMatThiefRestoreTool = null,
  __mmMatThiefAttackHeld = !1;
const __mmMatThiefReservations = new WeakMap();
let __mmMultiBreakTimer = 0,
  __mmMultiBreakAimAngle = null,
  __mmMultiBreakTargetCount = 0;
let __mmAssassinTimer = 0,
  __mmAssassinPreviousHat = null,
  __mmAssassinSafeSince = 0,
  __mmAssassinLastUnsafeAt = 0,
  __mmAssassinLastDamageAt = 0,
  __mmAssassinPurchaseAt = 0,
  __mmAssassinCooldownUntil = 0,
  __mmAssassinConcealed = !1;
let __mmCleanupActive = !1,
  __mmCleanupTimer = 0,
  __mmCleanupProgressTimer = 0,
  __mmCleanupOriginX = 0,
  __mmCleanupOriginY = 0,
  __mmCleanupTarget = null,
  __mmCleanupSavedTool = null,
  __mmCleanupWeapon = null,
  __mmCleanupAttackHeld = !1,
  __mmCleanupMouseButton = null,
  __mmCleanupAimAngle = null,
  __mmCleanupMoveAngle = null,
  __mmCleanupApproachStopped = !1,
  __mmCleanupTargetHealth = null,
  __mmCleanupProgressAt = 0,
  __mmCleanupEmptySince = 0,
  __mmCleanupChatStep = 0;
const __mmCleanupReservations = new WeakMap();
let __mmMobStealTimer = 0,
  __mmMobStealStageTimer = 0,
  __mmMobStealReleaseTimer = 0,
  __mmMobStealPendingPlan = null,
  __mmMobStealAimAngle = null,
  __mmMobStealRestoreTool = null,
  __mmMobStealRestoreHat = null,
  __mmMobStealRestoreTail = null,
  __mmMobStealAttackHeld = !1;
const __mmMobStealMotion = Object.create(null),
  __mmMobStealReservations = Object.create(null);
let __mmAutoInstaTimer = 0;
let __mmKittyInstaTimer = 0,
  __mmKittyInstaLastAt = 0,
  __mmVelTickMoveAngle = null,
  __mmVelTickTargetSid = null,
  __mmVelTickStartedAt = 0,
  __mmVelTickManualUntil = 0,
  __mmAutoPushMoveAngle = null,
  __mmAutoPushTargetSid = null,
  __mmAutoPushManualUntil = 0,
  __mmAutoPushRoute = [],
  __mmAutoPushRouteAt = 0,
  __mmAutoPushRouteGoalX = null,
  __mmAutoPushRouteGoalY = null,
  __mmAutoPushRouteTargetSid = null;
let __mmAutoTrapInstaTimer = 0;
const __mmAutoTrapInstaIncidents = Object.create(null);
let __mmAutoSpikeInstaTimer = 0,
  __mmAutoSpikeInstaLastAt = 0,
  __mmSpikeTickStrikeTimer = 0,
  __mmSpikeTickStrikeTool = null,
  __mmSpikeTickStrikeHat = null,
  __mmSpikeTickStrikeTail = null,
  __mmSpikeTickStrikeAimAngle = null,
  __mmSpikeTickStrikeHeld = !1;
const __mmAutoSpikeInstaMotion = Object.create(null);
let __mmAutoSpikeSpamTimer = 0,
  __mmAutoSpikeSpamLastAt = 0,
  __mmAutoSpikeSpamGhost = null,
  __mmAutoSpikeSpamCandidateKey = null,
  __mmAutoSpikeSpamCandidateSince = 0,
  __mmAutoSpikeSpamAimAngle = null,
  __mmAutoSpikeSpamAimUntil = 0;
const __mmAutoSpikeSpamReservations = [];
const __mmAutoSpikeSpamMotion = Object.create(null),
  __mmAutoSpikeKillAssumedUntil = Object.create(null);
const __mmAutoSpikeSpamIntent = {
  targetSid: null,
  lastX: null,
  lastY: null,
  lastAt: 0,
  score: 0,
  armed: !1,
};
let __mmSmartPlacementTimer = 0,
  __mmSmartPlacementLastAt = 0,
  __mmSmartPlacementCalculatedAt = 0,
  __mmSmartObjectScanAt = 0,
  __mmSmartReplaceUntil = 0,
  __mmSmartReplacePoint = null,
  __mmSmartMillX = null,
  __mmSmartMillY = null,
  __mmSmartMillLastAt = 0,
  __mmSmartUtilityLastAt = 0;
let __mmBoostSpikeTimer = 0,
  __mmBoostSpikeLastAt = 0,
  __mmBoostSpikeMoveAngle = null;
const __mmSmartPlacementStats = {
  state: "starting",
  reason: "waiting for game state",
  scans: 0,
  legal: 0,
  scored: 0,
  sent: 0,
  failed: 0,
  blocked: 0,
  itemSummary: "none",
  updatedAt: 0,
  broadcastAt: 0,
  signature: "",
};
const __mmSmartPreplaceTimers = new Set(),
  __mmSmartPreplaceKeys = new Set(),
  __mmSmartKnownObjects = new Map(),
  __mmSmartPlacementMotion = Object.create(null);
const __mmSmartPreviewSamples = [];
let __mmSmartPlacementPreview = {
  samples: [],
  ranked: [],
  selected: [],
  reason: "idle",
  updatedAt: 0,
};
let __mmAntiInstaTimer = 0,
  __mmAntiInstaLastAt = 0,
  __mmAntiInstaUntil = 0,
  __mmAntiInstaActionTimer = 0;
let __mmCombatThreatCalculatedAt = 0,
  __mmCombatThreatCache = null;
let __mmInstaSyncLoopTimer = 0,
  __mmInstaSyncTimer = 0,
  __mmInstaSyncReleaseTimer = 0,
  __mmInstaSyncPending = !1,
  __mmInstaSyncFiring = !1,
  __mmInstaSyncLastAt = 0,
  __mmInstaSyncRestoreTool = null,
  __mmInstaSyncRestoreHat = null,
  __mmInstaSyncWeaponHeld = !1;
const __mmInstaSyncProjectileStates = new WeakMap();
let __mmMovementGearTimer = 0,
  __mmMovementGearPreviousHat = null,
  __mmMovementGearPreviousTail = null,
  __mmProximityTailPrevious = null;
let __mmPassiveSpikeMotionTimer = 0,
  __mmPassiveSpikePendingTimer = 0,
  __mmPassiveSpikeCorrectionTimer = 0,
  __mmPassiveSpikeCorrecting = !1,
  __mmPassiveSpikeMotion = null;
let __mmAntiCollisionTimer = 0,
  __mmAntiCollisionBlocked = !1,
  __mmAntiCollisionBlockedObject = null,
  __mmAntiCollisionBlockedKey = null,
  __mmAntiCollisionBypassArmedKey = null,
  __mmAntiCollisionBypassArmedUntil = 0,
  __mmAntiCollisionBypassActiveKey = null,
  __mmAntiCollisionLastPopupKey = null,
  __mmAntiCollisionLastPopupAt = 0,
  __mmAntiCollisionRightClickTimer = 0;
const __mmAntiCollisionPopups = [];
const __mmInstaTypePopups = [];
const __mmClanPingAlerts = [];
window.addEventListener("MooMooKittyClanPing", function (__mmEvent) {
  const __mmDetail = (__mmEvent && __mmEvent.detail) || {},
    __mmX = Number(__mmDetail.x),
    __mmY = Number(__mmDetail.y),
    __mmOwnTeam = __mmTeamKey(v),
    __mmMapScale = Number(y && y.mapScale);
  if (
    !v ||
    !v.alive ||
    __mmOwnTeam == null ||
    !Number.isFinite(__mmX) ||
    !Number.isFinite(__mmY) ||
    !Number.isFinite(__mmMapScale) ||
    __mmX < 0 ||
    __mmY < 0 ||
    __mmX > __mmMapScale ||
    __mmY > __mmMapScale ||
    // Do not turn our own echoed native ping into a teammate alert.
    Math.hypot(__mmX - Number(v.x), __mmY - Number(v.y)) < 45
  )
    return;
  let __mmVisiblePlayerAtPing = !1,
    __mmVisibleTeammateAtPing = !1;
  if (Array.isArray(E))
    for (let __mmPlayerIndex = 0; __mmPlayerIndex < E.length; __mmPlayerIndex++) {
      const __mmPlayer = E[__mmPlayerIndex];
      if (!__mmPlayer || __mmPlayer === v || !__mmPlayer.alive) continue;
      const __mmPlayerX = Number(__mmPlayer.x),
        __mmPlayerY = Number(__mmPlayer.y);
      if (
        !Number.isFinite(__mmPlayerX) ||
        !Number.isFinite(__mmPlayerY) ||
        Math.hypot(__mmPlayerX - __mmX, __mmPlayerY - __mmY) > 170
      )
        continue;
      __mmVisiblePlayerAtPing = !0;
      if (__mmSameTeam(__mmPlayer)) {
        __mmVisibleTeammateAtPing = !0;
        break;
      }
    }
  // Across-map teammates may not exist in the visible-player list, so trust
  // the team-only server packet when nobody is rendered at its coordinates.
  // If someone is visible there, require that player to be our teammate.
  if (__mmVisiblePlayerAtPing && !__mmVisibleTeammateAtPing) return;
  const __mmNow = performance.now(),
    __mmDuplicate = __mmClanPingAlerts.find(
      (__mmAlert) =>
        __mmNow - __mmAlert.startedAt < 180 &&
        Math.hypot(__mmAlert.x - __mmX, __mmAlert.y - __mmY) < 10,
    );
  if (__mmDuplicate) {
    __mmDuplicate.startedAt = __mmNow;
    __mmDuplicate.expiresAt = __mmNow + 5000;
  } else {
    __mmClanPingAlerts.push({
      x: __mmX,
      y: __mmY,
      startedAt: __mmNow,
      expiresAt: __mmNow + 5000,
    });
    __mmClanPingAlerts.length > 8 && __mmClanPingAlerts.shift();
  }
});
let __mmMinimapRegionTimer = 0,
  __mmMinimapRegionElement = null,
  __mmMinimapRegionBaseImage = "";
let __mmFlipperPurchaseAt = 0,
  __mmSnowPurchaseAt = 0;
let __mmBoostBreakTimer = 0,
  __mmBoostBreakHeld = !1,
  __mmBoostBreakCooldownWeapon = null,
  __mmBoostBreakReadyAt = 0,
  __mmBoostBreakStrikeTimer = 0,
  __mmBoostBreakStriking = !1,
  __mmBoostBreakPreviousWeapon = null,
  __mmBoostMoveDirection = null,
  __mmBoostTankPreviousHat = null,
  __mmBoostChatTimer = 0,
  __mmBoostChatOrder = [],
  __mmBoostChatIndex = 0;
let __mmSoldierAutoTimer = 0,
  __mmSoldierRestoreTimer = 0,
  __mmSoldierPreviousHat = null;
let __mmShieldDefenseTimer = 0,
  __mmShieldDefenseWeapon = null;
let __mmAntiBoostTimer = 0,
  __mmAntiBoostLast = 0,
  __mmAntiBoostBlockTimer = 0,
  __mmAntiBoostMoveTimer = 0,
  __mmAntiBoostBlockTool = null,
  __mmAntiBoostBlockAimAngle = null,
  __mmAntiBoostBackingUp = !1;
let __mmAntiTrollTimer = 0,
  __mmAntiTrollLastAt = 0,
  __mmAntiTrollLatchedSid = null;
const __mmAntiTrollMotion = Object.create(null);
let __mmThreatTrapTimer = 0,
  __mmThreatTrapLastAt = 0,
  __mmThreatTrapLastKey = null;
const __mmThreatTrapPlacements = Object.create(null);
let __mmTrapAlertTimer = 0,
  __mmTrapChatIncidentActive = !1;
let __mmFriendlyTrapChatTimer = 0,
  __mmFriendlyTrapChatLastAt = 0;
const __mmFriendlyTrapChatIncidents = Object.create(null);
let __mmReloadSpikeTimer = 0,
  __mmReloadSpikePlaced = !1,
  __mmTurretReloadUntil = 0;
const __mmEnemyBoostTrail = {};
const __mmSyncProtocol = "kitty-klient-tab-sync-v1";
const __mmSyncStorageKey = "kitty-klient-tab-sync-state-v1";
const __mmOpenSyncProtocol = "kitty-klient-open-sync-v1";
let __mmSyncChannel = null;
try {
  typeof BroadcastChannel === "function" &&
    (__mmSyncChannel = new BroadcastChannel(__mmSyncProtocol));
} catch (__mmSyncChannelError) {}
const __mmSyncTabId = (function () {
  try {
    const __mmStored = sessionStorage.getItem("kitty-klient-tab-sync-id");
    if (__mmStored) return __mmStored;
    const __mmId =
      Date.now().toString(36) + "-" + Math.random().toString(36).slice(2, 10);
    return (sessionStorage.setItem("kitty-klient-tab-sync-id", __mmId), __mmId);
  } catch (__mmStorageError) {
    return Date.now().toString(36) + "-" + Math.random().toString(36).slice(2, 10);
  }
})();
let __mmSyncTimer = 0,
  __mmSyncFollowFrame = 0,
  __mmSyncMoveActive = !1,
  __mmSyncLastMoveDirection = null,
  __mmSyncLastMoveAt = 0,
  __mmSyncTargetSid = null,
  __mmSyncTargetName = "",
  __mmSyncTargetExplicit = !1,
  __mmSyncLeaderState = null,
  __mmSyncStandLeaderKey = "",
  __mmSyncStandAngle = null,
  __mmSyncArrivedBeside = !1,
  __mmSyncCatchupActive = !1,
  __mmSyncCatchupPreviousHat = null,
  __mmSyncCatchupPreviousTail = null,
  __mmSyncLeaderCombatUntil = 0,
  __mmSyncSelectionBlockedUntil = 0,
  __mmSyncGearPairDispatch = !1,
  __mmSyncReplayDepth = 0,
  __mmSyncDirectAttackAt = 0,
  __mmSyncDirectAttackActive = !1,
  __mmSyncObservedAttackHeld = !1,
  __mmSyncObservedAttackReleaseTimer = 0,
  __mmOpenSyncSequence = 0,
  __mmSyncRequestLastAt = 0,
  __mmSyncSequence = 0,
  __mmSyncStatus = "Sync off";
let __mmSyncStatusChatPhase = "off",
  __mmSyncStatusChatTimer = 0,
  __mmSyncStatusChatLastAt = 0;
const __mmSyncStatusChatQueue = [];
const __mmSyncSeenPackets = Object.create(null);
let __mmSyncRelaySocket = null,
  __mmSyncRelayReconnectTimer = 0,
  __mmSyncRelayPingTimer = 0,
  __mmSyncRelayAttemptAt = 0,
  __mmSyncRelayClockOffset = 0,
  __mmSyncRelayRtt = 0,
  __mmSyncRelayRoomKey = "",
  __mmSyncScheduledInstaTimer = 0,
  __mmSyncScheduledInstaAt = 0;
let __mmBuildSpamTimer = 0,
  __mmBuildSpamKey = 0;
let __mmWindmillHotkeyDown = !1;
const __mmWindmillDataTurnSpeeds = Object.create(null),
  __mmWindmillObjectTurnSpeeds = new WeakMap();
let __mmWeaponGrindTimer = 0,
  __mmWeaponGrindWeapon = null,
  __mmWeaponGrindHold = !1,
  __mmWeaponGrindLayoutAngle = null,
  __mmWeaponGrindAimAngle = null,
  __mmWeaponGrindTargetIndex = 0,
  __mmWeaponGrindNextAimAt = 0,
  __mmWeaponGrindLastPlaceAt = 0,
  __mmWeaponGrindLifeSid = null;
const __mmWeaponGrindPlaced = { turret: 0, teleporter: 0 },
  __mmWeaponGrindReservations = [],
  __mmWeaponGrindSlots = { turret: [], teleporter: [] };
let __mmWeaponRechargeTimer = 0,
  __mmWeaponRechargePreviousTool = null,
  __mmWeaponRechargeActiveWeapon = null,
  __mmWeaponRechargeSelectAt = 0,
  __mmWeaponRechargeHeldLoan = null;
let __mmPredictionLastX = null,
  __mmPredictionLastY = null,
  __mmPredictionLastAt = 0;
let __mmPrimaryHeld = !1,
  __mmSecondaryHeld = !1,
  __mmPhysicalPrimaryDown = !1,
  __mmPhysicalSecondaryDown = !1,
  __mmPhysicalInputAt = 0,
  __mmHeldAttackTimer = 0,
  __mmPrimaryAttackDown = !1,
  __mmPrimaryManualReadyAt = 0,
  __mmPrimaryManualWeapon = null,
  __mmSecondaryAttackDown = !1,
  __mmSecondaryManualReadyAt = 0,
  __mmSecondaryManualWeapon = null,
  __mmSecondaryGearStage = null,
  __mmSecondaryGearTimer = 0,
  __mmSecondaryGearEpoch = 0,
  __mmSecondaryReleaseRestoreTimer = 0,
  __mmSecondaryReleaseRestoreHat = null,
  __mmSecondaryReleaseRestoreAttempts = 0,
  __mmSecondaryShieldActive = !1,
  __mmSecondaryShieldAngle = null,
  __mmSecondaryShieldUsed = !1,
  __mmSecondaryShieldAimAt = 0,
  __mmSecondaryRestoreWeapon = null,
  __mmRightClickShieldPlanAt = 0,
  __mmRightClickShieldPlanCache = null,
  __mmPrimaryClickHat = null,
  __mmPrimaryClickTail = null,
  __mmPrimaryGearStage = null,
  __mmPrimaryGearTimer = 0,
  __mmRightClickHat = null,
  __mmHeldHatPrevious = null,
  __mmHeldTailPrevious = null,
  __mmLastNormalHat = 0;
let __mmCombatHatLockHat = null,
  __mmCombatHatLockUntil = 0,
  __mmCombatHatLockTimer = 0,
  __mmCombatHatLockEpoch = 0,
  __mmCombatHatLockWriting = !1;
// Equipment packets are acknowledged by the game state. Keep local rendering
// authoritative and merely debounce duplicate requests while that update is in
// flight; directly rewriting skinIndex/tailIndex caused visible frame flicker.
let __mmPendingHat = null,
  __mmPendingHatAt = 0,
  __mmPendingTail = null,
  __mmPendingTailAt = 0;
let __mmTrapAttackTimer = 0,
  __mmTrapAttackActive = !1,
  __mmTrapAimAngle = null,
  __mmTrapAttackTargetKey = null,
  __mmTrapWeapon = null,
  __mmTrapHat = null,
  __mmTrapAttackHeld = !1,
  __mmTrapAttackHeldWeapon = null,
  __mmTrapManualReadyAt = 0,
  __mmTrapWeaponSelectAt = 0,
  __mmTrapHatRestoreTimer = 0,
  __mmTrapHatRestoreAttempts = 0,
  __mmTrapBuildTimer = 0,
  __mmTrapBuildAttemptKey = null,
  __mmTrapBuildLastAt = 0,
  __mmTrapBuildWeapon = null,
  __mmTrapBuildPreferredItem = null,
  __mmTrapBuildPlacedKey = null,
  __mmTrapBuildPlacedCount = 0,
  __mmTrapResumeTimer = 0,
  __mmTrapSpikeReplaceSlot = null,
  __mmTrapSpikeReplaceLastAt = 0;
let __mmAntiRetrapReleaseTimer = 0,
  __mmAntiRetrapLastAt = 0,
  __mmPlacementDefenseTimer = 0,
  __mmPlacementDefenseLastAt = 0,
  __mmTeammateRescueTimer = 0,
  __mmTeammateRescueReleaseTimer = 0,
  __mmTeammateRescueAngle = null,
  __mmTeammateRescueRestoreTool = null,
  __mmTeammateRescueLastAt = 0,
  __mmTurretStealTimer = 0,
  __mmTurretStealRestoreTimer = 0,
  __mmSpikeGearCounterTimer = 0,
  __mmSpikeGearCounterTargetSid = null,
  __mmSpikeGearCounterArmedAt = 0,
  __mmSpikeGearCounterPreviousTail = null,
  __mmSpikeGearCounterRestoreTimer = 0,
  __mmDashMovementReleaseTimer = 0,
  __mmDashMovementAngle = null,
  __mmDashMovementRestoreTool = null;
const __mmPlacementDefenseHandled = new WeakMap();
let __mmTeamRequestObserver = null,
  __mmTeamRequestTimer = 0;
const __mmHandledTeamRequestButtons = new WeakSet();
let __mmLiveStateTimer = 0,
  __mmDebugHudTimer = 0;
let __mmOperationPipelineTimer = 0,
  __mmOperationPipelineRunning = !1,
  __mmOperationPipelineCycle = 0,
  __mmOperationPipelineStage = "boot",
  __mmOperationPipelineLastAt = 0;
const __mmOperationPipelineOrder = Object.freeze([
  "snapshot",
  "housekeeping",
  "trap",
  "defense",
  "combat-sync",
  "combat-insta",
  "heal",
  "placement",
  "utility",
  "gear",
  "restore",
]),
  __mmOperationPipelineErrors = Object.create(null);
let __mmMetricFrames = 0,
  __mmMetricPackets = 0,
  __mmMetricPacketWindow = 0,
  __mmMetricFps = 0,
  __mmMetricPps = 0,
  __mmMetricUpdatedAt = performance.now();
let __mmHudMenuOpen = !!(
  document.documentElement &&
  document.documentElement.getAttribute("data-kitty-hud-open") === "1"
),
  __mmNativeMenuOpen = !!(
    document.documentElement &&
    document.documentElement.getAttribute("data-kitty-main-menu-open") === "1"
  );
window.addEventListener("MooMooKittyHudVisibility", (__mmEvent) => {
  __mmHudMenuOpen = !!__mmEvent.detail;
});
window.addEventListener("MooMooKittyMainMenuVisibility", (__mmEvent) => {
  __mmNativeMenuOpen = !!__mmEvent.detail;
});
let __mmAdaptiveSmartDepth = __mmSmartDepth,
  __mmAdaptiveFpsEma = 60,
  __mmAdaptiveLowSince = 0,
  __mmAdaptiveStableSince = 0,
  __mmAdaptiveLastChangeAt = 0,
  __mmAdaptiveReason = "sampling",
  __mmAdaptiveCombat = !1;
const __mmChatBubbleStacks = Object.create(null),
  __mmChatBubbleWidthCache = new Map();
let __mmChatBubbleCleanupAt = 0;
let __mmMouseAimReturnTimer = 0,
  __mmSendingMouseAimReturn = !1,
  __mmLastForcedDirectionAt = 0,
  __mmStateRepairLastAt = 0,
  __mmStateRepairLastReason = "watching",
  __mmStateRepairCount = 0;
const __mmBreakableHealth = new WeakMap(),
  __mmBreakableLabelCache = new WeakMap(),
  __mmRecentPlayerSwings = Object.create(null),
  __mmPlayerToolCooldowns = Object.create(null);
const __mmProjectileCooldownStates = new WeakMap();
let __mmProjectileCooldownLastScanAt = 0;
const __mmCombatDeltaStacks = Object.create(null);
const __mmFriendNames = new Map(),
  __mmFriendEnemies = new Set(),
  __mmFriendAttackWindows = Object.create(null);
let __mmFriendPickMode = null,
  __mmSyncPickArmed = !1;
const __mmLiveState = {
  updatedAt: 0,
  alive: !1,
  enemies: [],
  animals: [],
  nearestEnemy: null,
  nearestEnemyDistance: Infinity,
  nearbyTrap: null,
  trapped: !1,
  health: 0,
  maxHealth: 0,
  primaryReady: !1,
  secondaryReady: !1,
};
const __mmActionPriorities = Object.freeze({
  trapEscape: 100,
  antiInsta: 95,
  autoHeal: 90,
  insta: 80,
  bowUpgradeInsta: 86,
  velTickSetup: 79,
  autoPushSetup: 78,
  boostInsta: 84,
  boostSpike: 77,
  spikeTickStrike: 82,
  instaSync: 75,
  shieldDefense: 85,
  placementDefense: 93,
  teammateRescue: 87,
  spikeGearCounter: 83,
  turretSteal: 43,
  dashMovement: 66,
  antiBoostBlock: 88,
  antiTroll: 92,
  boostBreak: 65,
  manualAttack: 60,
  cleanup: 55,
  weaponGrind: 50,
  // Placement sits above ordinary clicks/cleanup, but all defensive and Insta
  // owners still win. Held attacks loan one placement phase without being
  // cancelled by this priority.
  smartAutoPlace: 64,
  spikeSpam: 94,
  threatTrap: 45,
  reloadSpike: 40,
  mobSteal: 38,
  matThief: 35,
  weaponRecharge: 20,
  movementGear: 10,
  soldierGear: 10,
});
let __mmActionOwner = "idle",
  __mmActionReason = "waiting",
  __mmActionSince = 0,
  __mmActionLastDecision = "waiting";
function __mmActionPriority(__mmOwner) {
  return Number(__mmActionPriorities[__mmOwner]) || 0;
}
function __mmHeldAttackMayLoan(__mmOwner) {
  return !!(
    __mmActionOwner === "manualAttack" &&
    (__mmPrimaryHeld || __mmSecondaryHeld) &&
    (
      __mmOwner === "antiTroll" ||
      __mmOwner === "antiInsta" ||
      __mmOwner === "antiBoostBlock" ||
      __mmOwner === "placementDefense" ||
      __mmOwner === "teammateRescue" ||
      __mmOwner === "spikeSpam" ||
      __mmOwner === "smartAutoPlace" ||
      __mmOwner === "threatTrap" ||
      __mmOwner === "reloadSpike" ||
      __mmOwner === "weaponRecharge"
    )
  );
}
function __mmActionAvailable(__mmOwner) {
  return (
    __mmActionOwner === "idle" ||
    __mmActionOwner === __mmOwner ||
    __mmHeldAttackMayLoan(__mmOwner) ||
    (__mmActionOwner === "weaponGrind" &&
      __mmActionPriority(__mmOwner) > __mmActionPriority("weaponGrind"))
  );
}
function __mmActionCanPreempt(__mmOwner) {
  return (
    __mmActionAvailable(__mmOwner) ||
    __mmActionPriority(__mmOwner) > __mmActionPriority(__mmActionOwner)
  );
}
function __mmActionClaim(__mmOwner, __mmReason) {
  const __mmIncomingHigher =
    __mmOwner !== __mmActionOwner &&
    __mmActionPriority(__mmOwner) > __mmActionPriority(__mmActionOwner);
  if (__mmIncomingHigher && __mmActionOwner === "insta")
    __mmInsta.cancel("preempted by " + __mmOwner);
  if (__mmIncomingHigher && __mmActionOwner === "bowUpgradeInsta")
    __mmBowUpgradeInsta.cancel("preempted by " + __mmOwner);
  if (__mmIncomingHigher && __mmActionOwner === "instaSync")
    __mmStopInstaSync();
  if (__mmIncomingHigher && __mmActionOwner === "shieldDefense")
    __mmStopShieldDefense("preempted by " + __mmOwner);
  if (__mmIncomingHigher && __mmActionOwner === "spikeGearCounter")
    __mmResetSpikeGearCounter(!0);
  if (__mmIncomingHigher && __mmActionOwner === "turretSteal") {
    (__mmTurretStealRestoreTimer &&
      clearTimeout(__mmTurretStealRestoreTimer),
      (__mmTurretStealRestoreTimer = 0),
      v && v.alive && __mmEquipHatNow(__mmBestPostCombatHat(), !0),
      __mmActionRelease("turretSteal", "preempted by " + __mmOwner));
  }
  if (__mmIncomingHigher && __mmActionOwner === "boostBreak")
    __mmStopBoostBreak();
  if (__mmIncomingHigher && __mmActionOwner === "teammateRescue")
    __mmStopTeammateRescue("preempted by " + __mmOwner);
  if (__mmIncomingHigher && __mmActionOwner === "dashMovement")
    __mmStopDashMovement("preempted by " + __mmOwner);
  if (
    __mmActionOwner === "autoPushSetup" &&
    __mmOwner !== "autoPushSetup" &&
    __mmActionPriority(__mmOwner) > __mmActionPriority("autoPushSetup")
  )
    __mmStopAutoPushSetup("preempted by " + __mmOwner);
  if (
    __mmActionOwner === "velTickSetup" &&
    __mmOwner !== "velTickSetup" &&
    __mmActionPriority(__mmOwner) > __mmActionPriority("velTickSetup")
  )
    __mmStopVelTickInsta("preempted by " + __mmOwner);
  if (
    __mmActionOwner === "boostInsta" &&
    __mmOwner !== "boostInsta" &&
    __mmActionPriority(__mmOwner) > __mmActionPriority("boostInsta")
  )
    __mmBoostInsta.cancel("preempted by " + __mmOwner);
  if (
    __mmActionOwner === "weaponGrind" &&
    __mmOwner !== "weaponGrind" &&
    __mmActionPriority(__mmOwner) > __mmActionPriority("weaponGrind")
  )
    __mmPauseWeaponGrind("preempted by " + __mmOwner);
  if (
    __mmActionOwner === "cleanup" &&
    __mmOwner !== "cleanup" &&
    __mmActionPriority(__mmOwner) > __mmActionPriority("cleanup")
  )
    __mmStopCleanup("preempted by " + __mmOwner, !1);
  if (
    __mmActionOwner === "spikeTickStrike" &&
    __mmOwner !== "spikeTickStrike" &&
    __mmActionPriority(__mmOwner) > __mmActionPriority("spikeTickStrike")
  )
    __mmStopSpikeTickStrike("preempted by " + __mmOwner);
  if (
    __mmActionOwner === "antiBoostBlock" &&
    __mmOwner !== "antiBoostBlock" &&
    __mmActionPriority(__mmOwner) > __mmActionPriority("antiBoostBlock")
  )
    __mmStopAntiBoostBlock("preempted by " + __mmOwner);
  if (
    __mmActionOwner === "weaponRecharge" &&
    __mmOwner !== "weaponRecharge" &&
    __mmActionPriority(__mmOwner) > __mmActionPriority("weaponRecharge")
  )
    __mmPauseWeaponRecharge(!0);
  if (
    __mmActionOwner === "matThief" &&
    __mmOwner !== "matThief" &&
    __mmActionPriority(__mmOwner) > __mmActionPriority("matThief")
  )
    __mmFinishMatThief("preempted by " + __mmOwner);
  if (
    __mmActionOwner === "mobSteal" &&
    __mmOwner !== "mobSteal" &&
    __mmActionPriority(__mmOwner) > __mmActionPriority("mobSteal")
  )
    __mmFinishMobSteal("preempted by " + __mmOwner);
  if (!__mmActionAvailable(__mmOwner)) {
    __mmActionLastDecision =
      __mmOwner +
      " blocked by " +
      __mmActionOwner +
      " (requested " +
      __mmActionPriority(__mmOwner) +
      ", active " +
      __mmActionPriority(__mmActionOwner) +
      "): " +
      (__mmReason || "busy");
    return !1;
  }
  if (__mmHeldAttackMayLoan(__mmOwner)) {
    __mmActionLastDecision =
      __mmOwner + ": borrowed held attack · " + (__mmReason || "active");
    return !0;
  }
  if (__mmActionOwner === __mmOwner) {
    ((__mmActionReason = __mmReason || __mmActionReason),
      (__mmActionLastDecision = __mmOwner + ": " + __mmActionReason));
    return !0;
  }
  ((__mmActionOwner = __mmOwner),
    (__mmActionReason = __mmReason || "active"),
    (__mmActionSince = Date.now()),
    (__mmActionLastDecision = __mmOwner + ": " + __mmActionReason));
  return !0;
}
function __mmActionRelease(__mmOwner, __mmReason) {
  if (__mmActionOwner !== __mmOwner) return !1;
  ((__mmActionOwner = "idle"),
    (__mmActionReason = "idle"),
    (__mmActionSince = 0),
    (__mmActionLastDecision = __mmOwner + ": " + (__mmReason || "complete")));
  return !0;
}
function __mmActionMayRestore(__mmOwner) {
  return (
    __mmActionOwner === __mmOwner ||
    __mmActionOwner === "idle" ||
    __mmHeldAttackMayLoan(__mmOwner)
  );
}
function __mmNormalizeRuntimeBindings(__mmCandidate) {
  const __mmNext = Object.assign({}, __mmDefaultKeybinds);
  if (!__mmCandidate || typeof __mmCandidate !== "object") return __mmNext;
  for (let __mmIndex = 0; __mmIndex < __mmBindingActions.length; __mmIndex++) {
    const __mmAction = __mmBindingActions[__mmIndex],
      __mmValue = __mmCandidate[__mmAction];
    if (typeof __mmValue === "string" && __mmValue.length <= 80)
      __mmNext[__mmAction] = __mmValue;
  }
  return __mmNext;
}
function __mmSetRuntimeBindings(__mmCandidate) {
  __mmReleaseAllConfiguredBindings();
  __mmKeybinds = __mmNormalizeRuntimeBindings(__mmCandidate);
}
function __mmRuntimeBindingParts(__mmBinding) {
  const __mmPieces = String(__mmBinding || "").split("+");
  return {
    ctrl: __mmPieces.includes("Ctrl"),
    alt: __mmPieces.includes("Alt"),
    shift: __mmPieces.includes("Shift"),
    meta: __mmPieces.includes("Meta"),
    trigger:
      __mmPieces.find(function (__mmPiece) {
        return !["Ctrl", "Alt", "Shift", "Meta"].includes(__mmPiece);
      }) || "",
  };
}
function __mmRuntimeInputTrigger(__mmEvent, __mmMouse) {
  return __mmMouse
    ? "Mouse" + Math.max(0, Math.min(4, Number(__mmEvent.button) || 0))
    : String(__mmEvent.code || "");
}
function __mmRuntimeBindingMatches(__mmBinding, __mmEvent, __mmMouse) {
  const __mmParts = __mmRuntimeBindingParts(__mmBinding);
  return !!(
    __mmParts.trigger === __mmRuntimeInputTrigger(__mmEvent, __mmMouse) &&
    __mmParts.ctrl === !!__mmEvent.ctrlKey &&
    __mmParts.alt === !!__mmEvent.altKey &&
    __mmParts.shift === !!__mmEvent.shiftKey &&
    __mmParts.meta === !!__mmEvent.metaKey
  );
}
function __mmConfiguredActionForEvent(__mmEvent, __mmMouse) {
  for (let __mmIndex = 0; __mmIndex < __mmBindingActions.length; __mmIndex++) {
    const __mmAction = __mmBindingActions[__mmIndex];
    if (
      __mmAction !== "toggleHud" &&
      __mmRuntimeBindingMatches(__mmKeybinds[__mmAction], __mmEvent, __mmMouse)
    )
      return __mmAction;
  }
  return null;
}
function __mmBindingActionHeld(__mmAction) {
  return __mmActiveBindingActions.has(__mmAction);
}
function __mmBindingTypingTarget(__mmTarget) {
  return !!(
    __mmTarget &&
    __mmTarget.closest &&
    __mmTarget.closest("input,textarea,[contenteditable='true']")
  );
}
function __mmBindingGameSubmenuOpen() {
  const __mmIds = ["allianceMenu", "storeMenu", "chatHolder"];
  for (let __mmIndex = 0; __mmIndex < __mmIds.length; __mmIndex++) {
    const __mmMenu = document.getElementById(__mmIds[__mmIndex]);
    if (
      __mmMenu &&
      (__mmMenu.style.display === "block" ||
        window.getComputedStyle(__mmMenu).display !== "none")
    )
      return !0;
  }
  return !1;
}
function __mmStartConfiguredPrimary(__mmEvent, __mmBoostClick) {
  if (!v || !v.alive || v.weapons[0] == null) return !1;
  if (__mmHandleBushCombatClick(__mmEvent)) return !0;
  if (__mmBoostInsta.isActive()) return !0;
  (__mmSecondaryHeld || __mmRightClickHat != null) &&
    (__mmFinishSecondaryInput(), __mmForceRestoreRightClickHat());
  __mmInsta.isActive() && __mmInsta.cancel("configured-primary");
  __mmActionOwner === "weaponRecharge" && __mmPauseWeaponRecharge(!0);
  if (__mmBoostClick) {
    if (
      __mmAutoInstaEnabled &&
      __mmBoostInsta.start({ automatic: !0 })
    )
      return !0;
  } else if (
    __mmInsta.canAutoStart() &&
    __mmInsta.start({ automatic: !0 })
  )
    return !0;
  return __mmStartPrimaryInput();
}
function __mmPressConfiguredAction(__mmAction, __mmEvent) {
  __mmCleanupActive &&
    __mmAction !== "cleanup" &&
    __mmStopCleanup("configured input", !1);
  if (__mmAction === "primaryAttack")
    return __mmStartConfiguredPrimary(__mmEvent, !1);
  if (__mmAction === "clickBoostInsta")
    return __mmStartConfiguredPrimary(__mmEvent, !0);
  if (__mmAction === "secondaryAttack")
    return __mmStartConfiguredSecondary(__mmEvent);
  if (__mmAction === "normalInsta") return __mmHandleInstaHotkey();
  if (__mmAction === "boostInsta") return __mmBoostInsta.start();
  if (__mmAction === "oneTickInsta") return (__mmToggleOneTickInsta(), !0);
  if (__mmAction === "velTickInsta") return (__mmToggleVelTickInsta(), !0);
  if (__mmAction === "boostSpike") return (__mmStartBoostSpike(), !0);
  if (__mmAction === "quadTrap")
    return (__mmManualQuadPlacement("trap"), !0);
  if (__mmAction === "quadSpike")
    return (__mmManualQuadPlacement("spike"), !0);
  if (__mmAction === "betrayalInsta") return __mmStartBetrayalInsta();
  if (__mmAction === "toggleAutoHeal") return (__mmToggleAutoHeal(), !0);
  if (__mmAction === "food") return (__mmStartFoodSpam(), !0);
  if (__mmAction === "trapBuild")
    return (v && v.items && v.items[4] != null &&
      __mmStartBuildSpam(4, __mmAction), !0);
  if (__mmAction === "spikeBuild")
    return (v && v.items && v.items[2] != null &&
      __mmStartBuildSpam(2, __mmAction), !0);
  if (__mmAction === "specialBuild")
    return (__mmStartSelectedBuildSpam(__mmAction), !0);
  if (__mmAction === "boostBreak") return (__mmStartBoostBreak(), !0);
  if (__mmAction === "movingMills" || __mmAction === "movingMillsAlt")
    return (__mmStartWindmillHold(), !0);
  if (__mmAction === "bushMode") return (__mmHandleBushHotkey(), !0);
  if (__mmAction === "cleanup") return (__mmToggleCleanup(), !0);
  if (__mmAction === "friendPick")
    return (__mmArmFriendPick("friend"), !0);
  if (__mmAction === "enemyPick")
    return (__mmArmFriendPick("enemy"), !0);
  if (__mmAction === "syncPick") return (__mmArmSyncPick(), !0);
  return !1;
}
function __mmReleaseConfiguredAction(__mmAction) {
  if (__mmAction === "primaryAttack" || __mmAction === "clickBoostInsta")
    return void (__mmPrimaryHeld && __mmStopPrimaryInput());
  if (__mmAction === "secondaryAttack")
    return void ((__mmSecondaryHeld || __mmRightClickHat != null) &&
      __mmFinishSecondaryInput());
  if (__mmAction === "boostSpike") return void __mmStopBoostSpike();
  if (__mmAction === "food") return void __mmStopFoodSpam();
  if (["trapBuild", "spikeBuild", "specialBuild"].includes(__mmAction))
    return void __mmStopBuildSpam(__mmAction);
  if (__mmAction === "boostBreak") return void __mmStopBoostBreak();
  if (__mmAction === "movingMills" || __mmAction === "movingMillsAlt")
    return void __mmStopWindmillHold();
  if (__mmAction === "bushMode") __mmBushHotkeyDown = !1;
}
function __mmReleaseAllConfiguredBindings() {
  const __mmActions = Array.from(__mmActiveBindingActions.keys());
  for (let __mmIndex = 0; __mmIndex < __mmActions.length; __mmIndex++)
    __mmReleaseConfiguredAction(__mmActions[__mmIndex]);
  (__mmActiveBindingActions.clear(), __mmConsumedBindingInputs.clear());
}
function __mmConfiguredModifierReleased(__mmCode, __mmParts) {
  return !!(
    (__mmParts.shift && /^Shift/.test(__mmCode)) ||
    (__mmParts.ctrl && /^Control/.test(__mmCode)) ||
    (__mmParts.alt && /^Alt/.test(__mmCode)) ||
    (__mmParts.meta && /^Meta/.test(__mmCode))
  );
}
function __mmHandleConfiguredInput(__mmEvent, __mmPressed, __mmMouse) {
  if (
    !__mmEvent ||
    (__mmPressed && __mmBindingTypingTarget(__mmEvent.target))
  )
    return !1;
  if (__mmPressed && __mmBindingGameSubmenuOpen()) return !1;
  if (__mmMouse) {
    if (!__mmIsGameClick(__mmEvent)) return !1;
    if (__mmFriendPickMode || __mmSyncPickArmed) return !1;
  }
  const __mmTrigger = __mmRuntimeInputTrigger(__mmEvent, __mmMouse);
  if (__mmPressed) {
    const __mmAction = __mmConfiguredActionForEvent(__mmEvent, __mmMouse);
    if (!__mmAction) return !1;
    (__mmEvent.preventDefault(), __mmEvent.stopImmediatePropagation());
    if (__mmEvent.repeat || __mmConsumedBindingInputs.has(__mmTrigger)) return !0;
    if (__mmBindingHoldActions.has(__mmAction))
      __mmActiveBindingActions.set(__mmAction, {
        trigger: __mmTrigger,
        binding: __mmKeybinds[__mmAction],
      });
    (__mmConsumedBindingInputs.set(__mmTrigger, __mmAction),
      __mmPressConfiguredAction(__mmAction, __mmEvent));
    return !0;
  }
  let __mmConsumed = !1;
  const __mmDirectAction = __mmConsumedBindingInputs.get(__mmTrigger);
  if (__mmDirectAction) {
    (__mmConsumedBindingInputs.delete(__mmTrigger), (__mmConsumed = !0));
    if (__mmActiveBindingActions.has(__mmDirectAction)) {
      (__mmReleaseConfiguredAction(__mmDirectAction),
        __mmActiveBindingActions.delete(__mmDirectAction));
    }
  }
  if (!__mmMouse) {
    for (const [__mmAction, __mmActive] of __mmActiveBindingActions) {
      if (
        __mmConfiguredModifierReleased(
          String(__mmEvent.code || ""),
          __mmRuntimeBindingParts(__mmActive.binding),
        )
      )
        (__mmReleaseConfiguredAction(__mmAction),
          __mmActiveBindingActions.delete(__mmAction));
    }
  }
  if (__mmConsumed)
    (__mmEvent.preventDefault(), __mmEvent.stopImmediatePropagation());
  return __mmConsumed;
}
document.addEventListener(
  "keydown",
  function (__mmEvent) {
    __mmHandleConfiguredInput(__mmEvent, !0, !1);
  },
  !0,
);
document.addEventListener(
  "keyup",
  function (__mmEvent) {
    __mmHandleConfiguredInput(__mmEvent, !1, !1);
  },
  !0,
);
document.addEventListener(
  "mousedown",
  function (__mmEvent) {
    __mmHandleConfiguredInput(__mmEvent, !0, !0);
  },
  !0,
);
document.addEventListener(
  "mouseup",
  function (__mmEvent) {
    __mmHandleConfiguredInput(__mmEvent, !1, !0);
  },
  !0,
);
window.addEventListener("blur", __mmReleaseAllConfiguredBindings);
function __mmSuspendHeldAttackForManualInsta() {
  const __mmHadHeldAttack = !!(__mmPrimaryHeld || __mmSecondaryHeld),
    __mmCanTakeHeldAttack =
      __mmActionOwner === "manualAttack" || __mmActionOwner === "idle";
  // A direct R press may borrow the player's current mouse hold. Keep the
  // logical held flags intact so mouseup can still cancel it, but stop the
  // native attack stream before the combo emits its own precisely timed taps.
  if (__mmHadHeldAttack && !__mmCanTakeHeldAttack) return !1;
  if (__mmHadHeldAttack) {
    (__mmHeldAttackTimer && clearInterval(__mmHeldAttackTimer),
      (__mmHeldAttackTimer = 0));
    if (v && v.alive)
      try {
        __mmSendWeaponAttack(0);
      } catch (__mmManualInstaReleaseError) {}
    ((__mmPrimaryAttackDown = !1), (__mmSecondaryAttackDown = !1));
  }
  // A missed mouseup can leave manualAttack owned even though neither button
  // is down. R should repair that stale owner instead of being swallowed.
  __mmActionOwner === "manualAttack" &&
    __mmActionRelease("manualAttack", "loaned to manual R Insta");
  return !0;
}
function __mmUpdateLiveState() {
  const __mmNow = Date.now(),
    __mmEnemies = [],
    __mmAnimals = [],
    __mmSeenEntities = Object.create(null);
  let __mmNearest = null,
    __mmNearestDistance = Infinity;
  if (!v || !v.alive) {
    ((__mmLiveState.updatedAt = __mmNow),
      (__mmLiveState.alive = !1),
      (__mmLiveState.enemies = __mmEnemies),
      (__mmLiveState.animals = __mmAnimals),
      (__mmLiveState.nearestEnemy = null),
      (__mmLiveState.nearestEnemyDistance = Infinity),
      (__mmLiveState.nearbyTrap = null),
      (__mmLiveState.trapped = !1));
    return __mmLiveState;
  }
  if (typeof E !== "undefined" && Array.isArray(E))
    for (let __mmIndex = 0; __mmIndex < E.length; __mmIndex += 1) {
      const __mmPlayer = E[__mmIndex];
      const __mmKey = __mmThreatTargetKey(__mmPlayer);
      __mmKey != null && (__mmSeenEntities[__mmKey] = !0);
      if (!__mmIsEnemyPlayer(__mmPlayer)) continue;
      const __mmDistance = Math.hypot(__mmPlayer.x - v.x, __mmPlayer.y - v.y);
      if (!Number.isFinite(__mmDistance)) continue;
      __mmEnemies.push(__mmPlayer);
      if (__mmDistance < __mmNearestDistance) {
        ((__mmNearest = __mmPlayer), (__mmNearestDistance = __mmDistance));
      }
    }
  if (typeof N !== "undefined" && Array.isArray(N))
    for (let __mmIndex = 0; __mmIndex < N.length; __mmIndex += 1) {
      const __mmAnimal = N[__mmIndex];
      const __mmKey = __mmThreatTargetKey(__mmAnimal);
      __mmKey != null && (__mmSeenEntities[__mmKey] = !0);
      __mmAnimal && __mmAnimal.active !== !1 && __mmAnimals.push(__mmAnimal);
    }
  for (const __mmKey in __mmThreatTrapPlacements)
    __mmSeenEntities[__mmKey] || delete __mmThreatTrapPlacements[__mmKey];
  for (const __mmKey in __mmUnknownTeamSeen)
    __mmSeenEntities[__mmKey] || delete __mmUnknownTeamSeen[__mmKey];
  const __mmTrap = __mmNearestLockingTrap();
  ((__mmLiveState.updatedAt = __mmNow),
    (__mmLiveState.alive = !0),
    (__mmLiveState.enemies = __mmEnemies),
    (__mmLiveState.animals = __mmAnimals),
    (__mmLiveState.nearestEnemy = __mmNearest),
    (__mmLiveState.nearestEnemyDistance = __mmNearestDistance),
    (__mmLiveState.nearbyTrap = __mmTrap),
    (__mmLiveState.trapped = !!__mmTrap),
    (__mmLiveState.health = Number(v.health) || 0),
    (__mmLiveState.maxHealth = Number(v.maxHealth) || 0),
    (__mmLiveState.primaryReady = !!__mmWeaponReady(v.weapons && v.weapons[0])),
    (__mmLiveState.secondaryReady = !!__mmWeaponReady(v.weapons && v.weapons[1])));
  return __mmLiveState;
}
function __mmLiveStateFresh() {
  return Date.now() - __mmLiveState.updatedAt <= 2 * __mmFastCheckMs();
}
function __mmCurrentNearbyTrap() {
  if (
    __mmLiveStateFresh() &&
    __mmPlayerCenterTouchesEnemyTrap(__mmLiveState.nearbyTrap)
  )
    return __mmLiveState.nearbyTrap;
  return __mmNearestLockingTrap();
}
function __mmIsTrapped() {
  return !!(v && v.alive && __mmCurrentNearbyTrap());
}
function __mmRuntimeDebugText() {
  const __mmState = __mmLiveState,
    __mmThreat = __mmCombatThreatSnapshot(),
    __mmEnemy = __mmState.nearestEnemy,
    __mmReload = v && v.weapons
      ? "main " + (__mmState.primaryReady ? "ready" : "reload") +
        " · secondary " + (__mmState.secondaryReady ? "ready" : "reload")
      : "weapons unavailable",
    __mmOwnerAge = __mmActionSince ? Date.now() - __mmActionSince : 0;
  return [
    "pipeline: " +
      __mmOperationPipelineStage +
      " · cycle " +
      __mmOperationPipelineCycle +
      " · " +
      __mmOperationPipelineOrder.join(" > "),
    "owner: " + __mmActionOwner + (__mmActionSince ? " (" + __mmOwnerAge + "ms)" : ""),
    "reason: " + __mmActionReason,
    "last: " + __mmActionLastDecision,
    "repair: " +
      (__mmStateRepairCount
        ? __mmStateRepairLastReason +
          " (" +
          (Date.now() - __mmStateRepairLastAt) +
          "ms ago · " +
          __mmStateRepairCount +
          ")"
        : "watching"),
    "insta: " +
      (__mmInsta && __mmInsta.isActive()
        ? __mmInsta.profile + " · " + __mmInsta.profileSource
        : "idle"),
    "enemy: " +
      (__mmEnemy
        ? String(__mmEnemy.sid) + " at " + Math.round(__mmState.nearestEnemyDistance)
        : "none"),
    "trap: " + (__mmState.trapped ? "locked/collision" : "clear"),
    "threat: " +
      Math.round(__mmThreat.damage) +
      " dmg (proj " +
      Math.round(__mmThreat.projectileDamage) +
      " · melee " +
      Math.round(__mmThreat.meleeDamage) +
      " · spike " +
      Math.round(__mmThreat.spikeDamage) +
      ") · heal " +
      Math.round(__mmThreat.healPotential) +
      (__mmThreat.lethal ? " · LETHAL" : ""),
    "reload: " + __mmReload,
    "smartness: " +
      __mmEffectiveSmartDepth() +
      "/" +
      __mmSmartDepthCeiling() +
      " · " +
      (__mmAdaptiveSmartnessEnabled ? __mmAdaptiveReason : "manual ceiling") +
      " · " +
      (Number.isFinite(__mmMetricFps) && __mmMetricFps > 0
        ? Math.round(__mmMetricFps) + " FPS"
        : "sampling FPS"),
    "placement: " +
      __mmSmartPlacementStats.state + " · " +
      __mmSmartPlacementStats.reason + " · legal " +
      __mmSmartPlacementStats.legal + " / scored " +
      __mmSmartPlacementStats.scored + " / sent " +
      __mmSmartPlacementStats.sent + " · items " +
      __mmSmartPlacementStats.itemSummary,
    "scan: " + __mmReactionMs + "ms · state age " +
      (Date.now() - __mmState.updatedAt) + "ms",
  ].join("\\n");
}
function __mmStartLiveState() {
  __mmEnsureOperationPipeline();
}
function __mmOperationStage(__mmStage, __mmCallback) {
  __mmOperationPipelineStage = __mmStage;
  try {
    __mmCallback();
  } catch (__mmPipelineStageError) {
    const __mmNow = Date.now(),
      __mmLastError = Number(__mmOperationPipelineErrors[__mmStage]) || 0;
    __mmOperationPipelineErrors[__mmStage] = __mmNow;
    __mmNow - __mmLastError >= 1000 &&
      console.warn(
        "[kitty klient] operation stage failed:",
        __mmStage,
        __mmPipelineStageError,
      );
  }
}
function __mmRunOperationPipeline() {
  if (__mmOperationPipelineRunning) return;
  (__mmOperationPipelineRunning = !0,
    (__mmOperationPipelineCycle += 1),
    (__mmOperationPipelineLastAt = Date.now()));
  try {
    __mmOperationStage("snapshot", function () {
      (__mmUpdateLiveState(),
        (__mmCombatThreatCalculatedAt = 0),
        __mmCombatThreatSnapshot(!0),
        __mmObserveProjectileCooldowns());
    });
    __mmOperationStage("housekeeping", function () {
      __mmUpdateAutoPurchase();
    });
    // A real lock owns the weapon/aim channels before every other module.
    __mmOperationStage("trap", function () {
      (__mmTrapEscapeEnabled || __mmTrapAttackActive) && __mmBreakTrap();
    });
    // Lethal prevention is evaluated before optional damage combos, with one
    // latency-sensitive combat module owning a server tick at a time.
    __mmOperationStage("defense", function () {
      (__mmUpdateAntiInsta(),
        __mmUpdateAntiTroll(),
        __mmUpdatePlacementDefense(),
        __mmUpdateTeammateTrapRescue(),
        __mmUpdateAntiCollision());
    });
    // Resolve allied projectile/turret sync and spike timing before
    // self-started Insta variants.
    __mmOperationStage("combat-sync", function () {
      (__mmUpdateInstaSync(), __mmUpdateAutoSpikeInsta());
    });
    __mmOperationStage("combat-insta", function () {
      (__mmUpdateKittyInstas(),
        __mmUpdateAutoTrapInsta(),
        __mmUpdateAntiBoostInsta(),
        __mmUpdateSpikeGearCounter(),
        __mmUpdateBushMode());
    });
    // Health events still call Autoheal synchronously; this ordered pass is
    // the between-packets fallback.
    __mmOperationStage("heal", function () {
      __mmAutoHeal();
    });
    __mmOperationStage("placement", function () {
      (__mmUpdateAutoSpikeSpam(),
        (__mmSmartAutoPlaceEnabled ||
          __mmAutomaticQuadPlacementEnabled() ||
          __mmSmartAutoReplaceEnabled ||
          __mmSmartSpikeSyncPlaceEnabled ||
          __mmSmartAntiBoostPlaceEnabled ||
          __mmSmartMovingMillsEnabled ||
          __mmSmartReplacePoint) &&
          __mmUpdateSmartPlacement(),
        __mmPlaceThreatTrap(),
        __mmUpdateReloadSpike());
    });
    __mmOperationStage("utility", function () {
      (__mmCleanupActive && __mmUpdateCleanup(),
        __mmWeaponGrindEnabled && __mmUpdateWeaponGrind(),
        __mmUpdateTurretSteal(),
        __mmUpdateMobSteal(),
        __mmUpdateMatThief(),
        __mmMusketRechargeEnabled && __mmUpdateWeaponRecharge(),
        __mmUpdateMultiBreakAim());
    });
    __mmOperationStage("gear", function () {
      (__mmUpdateAssassinAutomation(),
        __mmUpdateMovementGear(),
        __mmUpdateSoldier());
    });
    __mmOperationStage("restore", function () {
      (__mmUpdateAutomaticStateRepair(), __mmRecoverStrayCombatHat());
    });
  } finally {
    ((__mmOperationPipelineStage = "idle"),
      (__mmOperationPipelineRunning = !1));
  }
}
function __mmScheduleOperationPipeline() {
  if (__mmOperationPipelineTimer) return;
  __mmOperationPipelineTimer = setTimeout(function __mmOperationPipelineStep() {
    ((__mmOperationPipelineTimer = 0), __mmRunOperationPipeline());
    __mmOperationPipelineTimer = setTimeout(
      __mmOperationPipelineStep,
      Math.min(10, __mmFastCheckMs()),
    );
  }, 0);
}
function __mmEnsureOperationPipeline() {
  (__mmLiveStateTimer && clearInterval(__mmLiveStateTimer),
    (__mmLiveStateTimer = 0),
    __mmScheduleOperationPipeline());
}
function __mmStartDebugHud() {
  __mmDebugHudTimer ||
    (__mmDebugHudTimer = setInterval(function () {
      __mmDebugPanelEnabled && __mmPublishHudState();
    }, 200));
}
const __mmUnknownTeamSeen = {},
  __mmUnknownTeamGraceMs = 1500;
const __mmBoostChatLines = [
  "WHEEEEEE!",
  "Wooo-hooo!",
  "ZOOOOOM!",
  "Can't catch me!",
  "I AM SPEEEEED!",
  "I'M COMING FOR YOU!",
  "AAAHHHHH!",
];
const __mmOriginalSelect = je;
let __mmLastSelectionItem = null,
  __mmLastSelectionWasWeapon = !1,
  __mmLastSelectionAt = 0;
je = function (__mmItem, __mmIsWeapon) {
  ((__mmLastSelectionItem = __mmItem),
    (__mmLastSelectionWasWeapon = !!__mmIsWeapon),
    (__mmLastSelectionAt = Date.now()));
  __mmIsWeapon && (__mmLastWeapon = __mmItem);
  const __mmResult = __mmOriginalSelect(__mmItem, __mmIsWeapon);
  return (__mmSyncPublishSelection(__mmItem, __mmIsWeapon), __mmResult);
};
function __mmPrepareTrademarkNameInput() {
  // Do not touch MooMoo's minified name-input binding here. This patch block is
  // inserted before that top-level const is initialized in the current bundle,
  // so even testing the binding aborts the whole module through the TDZ.
  const __mmNameInput = document.getElementById("nameInput");
  if (!__mmNameInput) return 13;
  const __mmStoredOriginal = Number(__mmNameInput.dataset.kittyOriginalNameMax),
    __mmOriginalMax =
      Number.isFinite(__mmStoredOriginal) && __mmStoredOriginal > 2
        ? __mmStoredOriginal
        : Math.max(3, Number(__mmNameInput.maxLength) || 15),
    __mmLimit = Math.max(1, __mmOriginalMax - 2),
    __mmRaw = String(__mmNameInput.value || "")
      .replace(/^(?:k-)+/i, "")
      .slice(0, __mmLimit),
    __mmVisible = "k-" + __mmRaw;
  (__mmNameInput.dataset.kittyOriginalNameMax = String(__mmOriginalMax),
    __mmNameInput.dataset.kittyNameLimit = String(__mmLimit),
    (__mmNameInput.maxLength = __mmOriginalMax),
    __mmNameInput.setAttribute("maxlength", String(__mmOriginalMax)),
    (__mmNameInput.placeholder = "k-Your Name"),
    __mmNameInput.value !== __mmVisible &&
      (__mmNameInput.value = __mmVisible));
  return __mmLimit;
}
function __mmTrademarkPlayerName(__mmName) {
  const __mmLimit = __mmPrepareTrademarkNameInput(),
    __mmRaw = String(__mmName || "")
      .replace(/^(?:k-)+/i, "")
      .slice(0, __mmLimit);
  return "k-" + __mmRaw;
}
__mmPrepareTrademarkNameInput();
const __mmOriginalSocketSend = O.send;
let __mmKatanaMusketUpgradeTimer = 0,
  __mmKatanaMusketUpgradeActive = !1;
function __mmTryKatanaMusketUpgrade(__mmSelection) {
  if (Number(__mmSelection) !== Number(__mmMusket)) return !1;
  // Consume repeated Musket clicks while the fixed two-packet sequence owns
  // the upgrade channel. There are no confirmation retries.
  if (__mmKatanaMusketUpgradeActive) return !0;
  const __mmUpgradePoints = Number(v && v.upgradePoints);
  if (
    !v ||
    !v.alive ||
    !Array.isArray(v.weapons) ||
    !v.weapons.includes(__mmShortSword) ||
    v.weapons.includes(__mmKatana) ||
    (Number.isFinite(__mmUpgradePoints) && __mmUpgradePoints <= 0) ||
    !__mmUpgradeServerSafe(__mmMusket)
  )
    return !1;
  // Both choices must enter the same server update window. A full-tick delay
  // lets Katana consume/advance the upgrade phase before Musket arrives; zero
  // delay can be coalesced by some transports. Keep only a tiny ordering gap,
  // with no acknowledgement wait or retry loop.
  const __mmDelay = Math.max(4, Math.min(12, __mmFastCheckMs()));
  ((__mmKatanaMusketUpgradeActive = !0),
    (__mmLastUpgradePacketAt = Date.now()),
    __mmOriginalSocketSend.call(O, "H", __mmKatana),
    (__mmKatanaMusketUpgradeTimer = setTimeout(function () {
      __mmKatanaMusketUpgradeTimer = 0;
      if (v && v.alive) {
        ((__mmLastUpgradePacketAt = Date.now()),
          __mmOriginalSocketSend.call(O, "H", __mmMusket));
      }
      __mmKatanaMusketUpgradeActive = !1;
    }, __mmDelay)));
  window.dispatchEvent(
    new CustomEvent("MooMooScrollZoomStatus", {
      detail: "Katana + Musket",
    }),
  );
  return !0;
}
O.send = function () {
  const __mmUpgradePacket = arguments[0] === "H";
  if (__mmUpgradePacket && __mmTryKatanaMusketUpgrade(arguments[1])) return;
  if (__mmUpgradePacket && !__mmAllowUpgradePacket(arguments[1])) return;
  if (
    arguments[0] === "c" &&
    !arguments[3] &&
    Number(arguments[2]) === Number(__mmEmpHelmet) &&
    __mmEnemyWithinCombatRange()
  )
    arguments[2] = v && v.skins && v.skins[6] ? 6 : 0;
  if (
    arguments[0] === "c" &&
    !arguments[3] &&
    !__mmCombatHatPacketAllowed(arguments[2])
  )
    return;
  if (
    arguments[0] === "M" &&
    arguments[1] &&
    typeof arguments[1] === "object"
  )
    arguments[1] = {
      ...arguments[1],
      name: __mmTrademarkPlayerName(arguments[1].name),
    };
  const __mmResult = __mmOriginalSocketSend.apply(this, arguments);
  ((__mmMetricPackets += 1),
    (__mmMetricPacketWindow += 1),
    __mmObserveOutgoingProjectileAttack(arguments),
    __mmSyncObserveSocketSend(arguments),
    __mmObserveForcedDirectionPacket(arguments));
  return __mmResult;
};
const __mmOriginalPlayerAttack = Pl;
const __mmOriginalDeath = Sl;
const __mmOriginalHealthUpdate = $l;
const __mmOriginalAnimalUpdate = Xl;
const __mmOriginalPlayerStatUpdate = Kl;
const __mmOriginalChatDisplay = dl;
const __mmOriginalUpgradeDisplay = Un;
const __mmOriginalObjectRender = Ge;
const __mmOriginalObjectHit = Wl;
const __mmOriginalAimDirection = Ci;
const __mmOriginalRender = Cl;
Ci = function () {
  return __mmTrapAttackActive && Number.isFinite(__mmTrapAimAngle)
    ? __mmTrapAimAngle
    : __mmSecondaryShieldActive && Number.isFinite(__mmSecondaryShieldAngle)
      ? __mmSecondaryShieldAngle
    : Number.isFinite(__mmMatThiefAimAngle)
      ? __mmMatThiefAimAngle
    : Number.isFinite(__mmMobStealAimAngle)
      ? __mmMobStealAimAngle
    : Number.isFinite(__mmAntiBoostBlockAimAngle)
      ? __mmAntiBoostBlockAimAngle
    : Number.isFinite(__mmSpikeTickStrikeAimAngle)
      ? __mmSpikeTickStrikeAimAngle
    : Number.isFinite(__mmMultiBreakAimAngle)
      ? __mmMultiBreakAimAngle
    : __mmCleanupActive && Number.isFinite(__mmCleanupAimAngle)
      ? __mmCleanupAimAngle
    : __mmWeaponGrindEnabled &&
        (__mmWeaponGrindHold || __mmActionOwner === "weaponGrind") &&
        Number.isFinite(__mmWeaponGrindAimAngle)
      ? __mmWeaponGrindAimAngle
    : Date.now() < __mmAutoSpikeSpamAimUntil &&
        Number.isFinite(__mmAutoSpikeSpamAimAngle)
      ? __mmAutoSpikeSpamAimAngle
    : __mmOriginalAimDirection.apply(this, arguments);
};
function __mmRawMouseAimDirection() {
  // Read the cursor coordinates directly so X/lockDir cannot freeze this at
  // the pre-automation angle. The normal Ci helper intentionally preserves
  // its old angle while X is enabled.
  const __mmMouseX = Number(On) - Number(De) / 2,
    __mmMouseY = Number(Hn) - Number(Ae) / 2;
  if (Number.isFinite(__mmMouseX) && Number.isFinite(__mmMouseY)) {
    const __mmDirectAngle = Math.atan2(__mmMouseY, __mmMouseX);
    return typeof M.fixTo === "function"
      ? M.fixTo(__mmDirectAngle, 2)
      : __mmDirectAngle;
  }
  let __mmAngle = 0;
  try {
    __mmAngle = Number(__mmOriginalAimDirection());
  } catch (__mmMouseAimError) {}
  // Zero is a valid direction (cursor directly on the positive X axis), so
  // never use a truthiness fallback here.
  return Number.isFinite(__mmAngle) ? __mmAngle : 0;
}
function __mmForcedDirectionStillActive() {
  return !!(
    (__mmTrapAttackActive && Number.isFinite(__mmTrapAimAngle)) ||
    (__mmSecondaryShieldActive && Number.isFinite(__mmSecondaryShieldAngle)) ||
    Number.isFinite(__mmMatThiefAimAngle) ||
    Number.isFinite(__mmMobStealAimAngle) ||
    Number.isFinite(__mmAntiBoostBlockAimAngle) ||
    Number.isFinite(__mmSpikeTickStrikeAimAngle) ||
    Number.isFinite(__mmMultiBreakAimAngle) ||
    (__mmCleanupActive && Number.isFinite(__mmCleanupAimAngle)) ||
    (__mmWeaponGrindEnabled &&
      (__mmWeaponGrindHold || __mmActionOwner === "weaponGrind") &&
      Number.isFinite(__mmWeaponGrindAimAngle)) ||
    (Date.now() < __mmAutoSpikeSpamAimUntil &&
      Number.isFinite(__mmAutoSpikeSpamAimAngle)) ||
    __mmInsta.isActive() ||
    __mmBoostInsta.isActive() ||
    Number.isFinite(__mmBoostSpikeMoveAngle) ||
    __mmInstaSyncPending ||
    __mmInstaSyncFiring
  );
}
function __mmReturnDirectionToMouse() {
  __mmMouseAimReturnTimer = 0;
  if (!v || !v.alive) return;
  if (__mmForcedDirectionStillActive()) {
    __mmMouseAimReturnTimer = setTimeout(
      __mmReturnDirectionToMouse,
      __mmFastCheckMs(),
    );
    return;
  }
  const __mmAngle = __mmRawMouseAimDirection();
  let __mmReturned = !1;
  try {
    // Update the game's cached aim as well as the server. When X is active,
    // Ci returns this cache instead of sampling the cursor on the next frame.
    ((It = __mmAngle),
      (__mmSendingMouseAimReturn = !0),
      O.send("D", __mmAngle),
      (__mmReturned = !0));
  } catch (__mmMouseAimReturnError) {
    // The watchdog will retry after the transport resumes.
    __mmLastForcedDirectionAt = Date.now();
  } finally {
    __mmSendingMouseAimReturn = !1;
  }
  __mmReturned && (__mmLastForcedDirectionAt = 0);
}
function __mmScheduleMouseAimReturn() {
  if (__mmSendingMouseAimReturn) return;
  __mmMouseAimReturnTimer && clearTimeout(__mmMouseAimReturnTimer);
  __mmMouseAimReturnTimer = setTimeout(
    __mmReturnDirectionToMouse,
    __mmServerTickMs(),
  );
}
function __mmObserveForcedDirectionPacket(__mmArgs) {
  if (__mmSendingMouseAimReturn || !__mmArgs) return;
  const __mmPacket = __mmArgs[0];
  if (
    __mmPacket === "F" &&
    __mmArgs[2] != null &&
    Number.isFinite(Number(__mmArgs[2]))
  ) {
    ((__mmLastForcedDirectionAt = Date.now()), __mmScheduleMouseAimReturn());
    return;
  }
  if (
    __mmPacket !== "D" ||
    __mmArgs[1] == null ||
    !Number.isFinite(Number(__mmArgs[1]))
  )
    return;
  const __mmSent = Number(__mmArgs[1]),
    __mmMouse = __mmRawMouseAimDirection(),
    __mmDifference = Math.abs(
      Math.atan2(
        Math.sin(__mmSent - __mmMouse),
        Math.cos(__mmSent - __mmMouse),
      ),
    );
  __mmDifference > 0.001 &&
    ((__mmLastForcedDirectionAt = Date.now()), __mmScheduleMouseAimReturn());
}
// R insta owns one short-lived interaction at a time. It deliberately uses the
// same client actions as normal input and yields to safety/manual automation.
// State transitions are intentionally limited to:
// idle -> validate -> arm -> waitForRange -> executeBurst -> soldier -> cleanup -> idle.
function __mmInstaSafeRestoreHat(__mmFallback) {
  // Bull, Tank and Turret are packet-phase combat hats, never stable restore
  // targets. A late acknowledgement from any of them must not poison the next
  // Insta snapshot and keep that temporary hat equipped after cleanup.
  const __mmCandidates = [
    __mmFallback,
    __mmPendingHat,
    __mmPrimaryClickHat,
    __mmRightClickHat,
    __mmTrapHat,
    __mmMovementGearPreviousHat,
    __mmSoldierPreviousHat,
    __mmLastNormalHat,
  ];
  for (let __mmIndex = 0; __mmIndex < __mmCandidates.length; __mmIndex++) {
    const __mmHat = __mmCandidates[__mmIndex];
    if (!__mmTemporaryCombatHat(__mmHat) && __mmCanEquipHat(__mmHat))
      return __mmHat;
  }
  return 0;
}
// Insta placement validates locally, selects the placeable, and sends one
// placement packet at the solved angle, then immediately put the combo weapon
// back in hand. There is deliberately no acknowledgement wait or F=0 gap.
function __mmInstaPlaceAndReselect(__mmItem, __mmAngle, __mmWeapon) {
  if (
    !v ||
    !v.alive ||
    __mmItem == null ||
    !Number.isFinite(Number(__mmAngle)) ||
    !__mmCanUseBuildItem(__mmItem)
  )
    return !1;
  try {
    const __mmPreviewCandidate = __mmSmartCandidateForAngle(
      __mmItem,
      __mmAngle,
      !0,
    );
    if (__mmPreviewCandidate) {
      ((__mmPreviewCandidate.points = 10),
        (__mmPreviewCandidate.priority = !0),
        __mmSmartSetPlacementPreview(
          [__mmPreviewCandidate],
          [__mmPreviewCandidate],
          "insta placement",
        ));
    }
    (je(__mmItem),
      O.send("F", 1, __mmAngle),
      __mmWeapon != null && je(__mmWeapon, !0));
    return !0;
  } catch (__mmInstaPlacementError) {
    return !1;
  }
}
function __mmInstaPopupLabel(__mmProfile, __mmAutomatic, __mmBetrayal) {
  if (__mmBetrayal) return "Betrayal Insta";
  const __mmLabels = {
    normal: __mmAutomatic ? "Auto Insta" : "Normal Insta",
    reverse: "Reverse Insta",
    oneTick: "One-Tick Insta",
    apple: "Apple Insta",
    bleed: "Bleed Insta",
    knockback: "Knockback Insta",
    trapCatch: "Trap Insta",
    polearmAids: "Polearm Insta",
    velTick: "VelTick Insta",
    autoPush: "Auto-Push Insta",
  };
  return __mmLabels[String(__mmProfile || "normal")] || "Insta";
}
function __mmTargetShieldActive(__mmTarget) {
  if (!__mmTarget || !b || !b.weapons) return !1;
  const __mmWeapon = b.weapons[Number(__mmTarget.weaponIndex)];
  return !!(__mmWeapon && Number(__mmWeapon.shield) > 0);
}
function __mmShieldBypass(__mmAttacker, __mmTarget, __mmOrigin) {
  if (!__mmTargetShieldActive(__mmTarget)) return !0;
  const __mmAttackerX = Number(
      __mmOrigin && __mmOrigin.x != null
        ? __mmOrigin.x
        : __mmAttacker && __mmAttacker.x,
    ),
    __mmAttackerY = Number(
      __mmOrigin && __mmOrigin.y != null
        ? __mmOrigin.y
        : __mmAttacker && __mmAttacker.y,
    ),
    __mmTargetX = Number(__mmTarget.x),
    __mmTargetY = Number(__mmTarget.y),
    __mmFacing = Number(__mmTarget.dir);
  if (
    !Number.isFinite(__mmAttackerX) ||
    !Number.isFinite(__mmAttackerY) ||
    !Number.isFinite(__mmTargetX) ||
    !Number.isFinite(__mmTargetY) ||
    !Number.isFinite(__mmFacing)
  )
    return !1;
  const __mmTowardAttacker = Math.atan2(
      __mmAttackerY - __mmTargetY,
      __mmAttackerX - __mmTargetX,
    ),
    __mmDifference = Math.abs(
      Math.atan2(
        Math.sin(__mmTowardAttacker - __mmFacing),
        Math.cos(__mmTowardAttacker - __mmFacing),
      ),
    ),
    __mmShieldAngle = Math.max(
      0.1,
      Number(y && y.shieldAngle) || Math.PI / 3,
    );
  return __mmDifference > __mmShieldAngle;
}
const __mmInsta = {
  state: "idle",
  timer: 0,
  releaseTimer: 0,
  hatRestoreTimer: 0,
  hatRestoreEpoch: 0,
  targetSid: null,
  targetOptional: !1,
  automatic: !1,
  betrayal: !1,
  snapshot: null,
  primaryWeapon: null,
  pendingSecondaryWeapon: null,
  attackHeld: !1,
  trapHandoff: null,
  postSpikeEnabled: !1,
  postSpikeCandidate: null,
  postSpikeCalculatedAt: 0,
  postSpikeTarget: null,
  profile: "normal",
  profileSource: "R",
  manualHotkey: !1,
  bowUpgradeFollowup: !1,
  popupShown: !1,
  automaticRetryUntil: 0,
  shieldWaitStartedAt: 0,
  isActive() {
    return this.state !== "idle" && this.state !== "cleanup";
  },
  isEmergencyHealth() {
    return !!(
      v &&
      v.alive &&
      Number(v.health) <= Math.max(20, Number(v.maxHealth) * 0.2)
    );
  },
  runtimeReady() {
    return !!(
      typeof v !== "undefined" &&
      v &&
      typeof b !== "undefined" &&
      b &&
      b.weapons &&
      b.list &&
      typeof E !== "undefined" &&
      Array.isArray(E) &&
      typeof Rt === "function" &&
      typeof je === "function" &&
      typeof O !== "undefined" &&
      O &&
      typeof O.send === "function" &&
      typeof Ci === "function" &&
      typeof y !== "undefined" &&
      y
    );
  },
  tick() {
    return __mmServerTickMs();
  },
  schedule(__mmCallback, __mmDelay = this.tick()) {
    this.timer && clearTimeout(this.timer);
    this.timer = setTimeout(() => {
      this.timer = 0;
      __mmCallback();
    }, Math.max(1, Number(__mmDelay) || this.tick()));
  },
  normalStageMs() {
    // Keep fixed 120 ms stages from becoming shorter than the actual server
    // update when a slower server rate is reported.
    return Math.max(120, this.tick());
  },
  reverseProfile() {
    return [
      "reverse",
      "oneTick",
      "apple",
      "bleed",
      "knockback",
      "polearmAids",
    ].includes(this.profile);
  },
  openingDelay() {
    return this.profile === "normal" ? this.normalStageMs() : 1;
  },
  profileStep(__mmTarget, __mmWeapon) {
    if (this.profile !== "oneTick") return this.tick();
    const __mmData = this.weaponData(__mmWeapon),
      __mmProjectile =
        __mmData && __mmData.projectile != null && b.projectiles
          ? b.projectiles[__mmData.projectile]
          : null,
      __mmSpeed = Number(__mmProjectile && __mmProjectile.speed),
      __mmDistance = __mmTarget
        ? Math.max(
            0,
            Math.hypot(__mmTarget.x - v.x, __mmTarget.y - v.y) -
              (Number(__mmTarget.scale) || 35),
          )
        : 0,
      __mmTravel =
        Number.isFinite(__mmSpeed) && __mmSpeed > 0
          ? __mmDistance / __mmSpeed
          : this.tick();
    // Launch the secondary first, then put the melee hit in the following
    // server window. Projectile travel can shorten that window, never extend
    // it beyond one tick where the target could leave melee range.
    return Math.max(8, Math.min(this.tick(), __mmTravel || this.tick()));
  },
  scheduleRelease() {
    this.releaseTimer && clearTimeout(this.releaseTimer);
    this.releaseTimer = setTimeout(() => {
      this.releaseTimer = 0;
      this.releaseAttack();
    }, 25);
  },
  cancelHatRestore() {
    this.hatRestoreTimer && clearTimeout(this.hatRestoreTimer);
    this.hatRestoreTimer = 0;
    this.hatRestoreEpoch += 1;
  },
  scheduleHatRestore(__mmHat) {
    this.cancelHatRestore();
    __mmHat = __mmInstaSafeRestoreHat(__mmHat);
    if (!__mmCanEquipHat(__mmHat)) return;
    const __mmEpoch = this.hatRestoreEpoch,
      __mmSelf = this;
    let __mmAttempts = 0;
    const __mmReassert = function () {
      __mmSelf.hatRestoreTimer = 0;
      if (
        __mmEpoch !== __mmSelf.hatRestoreEpoch ||
        __mmSelf.isActive() ||
        !v ||
        !v.alive
      )
        return;
      if (
        __mmPrimaryHeld ||
        __mmSecondaryHeld ||
        __mmPrimaryClickHat != null ||
        __mmRightClickHat != null ||
        __mmTrapAttackActive ||
        (__mmActionOwner !== "idle" &&
          __mmActionOwner !== "movementGear" &&
          __mmActionOwner !== "soldierGear" &&
          __mmActionOwner !== "weaponRecharge")
      ) {
        __mmAttempts += 1;
        if (__mmAttempts < 12)
          __mmSelf.hatRestoreTimer = setTimeout(
            __mmReassert,
            __mmSelf.tick(),
          );
        return;
      }
      const __mmPendingRestore =
          __mmPendingHat != null &&
          !__mmTemporaryCombatHat(__mmPendingHat) &&
          __mmCanEquipHat(__mmPendingHat)
            ? __mmPendingHat
            : __mmHat,
        __mmTemporaryStillOwned =
          __mmTemporaryCombatHat(v.skinIndex) ||
          __mmTemporaryCombatHat(__mmPendingHat);
      __mmTemporaryStillOwned && __mmEquipHatNow(__mmPendingRestore, !0);
      __mmAttempts += 1;
      if (__mmAttempts < 6)
        __mmSelf.hatRestoreTimer = setTimeout(
          __mmReassert,
          __mmSelf.tick(),
        );
    };
    this.hatRestoreTimer = setTimeout(__mmReassert, this.tick());
  },
  isPriorityConflict() {
    const __mmTrapHandoffAvailable = !!(
      __mmIsTrapped() &&
      (__mmActionOwner === "trapEscape" || __mmTrapAttackActive)
    );
    return !!(
      !v ||
      !v.alive ||
      (!__mmActionCanPreempt("insta") && !__mmTrapHandoffAvailable) ||
      (!this.manualHotkey && (__mmPrimaryHeld || __mmSecondaryHeld)) ||
      (__mmTrapAttackActive && !__mmTrapHandoffAvailable) ||
      __mmBoostBreakHeld ||
      __mmBuildSpamTimer ||
      __mmFoodSpamTimer ||
      Date.now() < __mmAntiInstaUntil ||
      __mmInstaSyncPending ||
      __mmInstaSyncFiring ||
      (this.isEmergencyHealth() && !__mmIsTrapped())
    );
  },
  suspendTrapEscape() {
    if (!__mmIsTrapped() || !__mmTrapEscapeEnabled) return;
    this.trapHandoff = {
      resume: !0,
      weapon:
        __mmTrapWeapon != null ? __mmTrapWeapon : __mmSelectedWeapon(),
      hat:
        __mmTrapHat != null
          ? __mmTrapHat
          : __mmInstaSafeRestoreHat(__mmBushRestoreHat(v.skinIndex)),
    };
    (__mmTrapAttackActive || __mmActionOwner === "trapEscape") &&
      __mmStopTrapAttack();
  },
  capture() {
    const __mmCapturedHat =
      this.trapHandoff && this.trapHandoff.hat != null
        ? this.trapHandoff.hat
        : __mmBushRestoreHat(v.skinIndex);
    this.snapshot = {
      weapon:
        this.trapHandoff && this.trapHandoff.weapon != null
          ? this.trapHandoff.weapon
          : __mmSelectedWeapon(),
      hat: __mmInstaSafeRestoreHat(__mmCapturedHat),
      tail: __mmBushRestoreTail(v.tailIndex),
      primaryHeld: __mmPrimaryHeld,
      secondaryHeld: __mmSecondaryHeld,
      heldPulse: !!__mmHeldAttackTimer,
      movementGear: __mmMovementGearEnabled,
      soldierAuto: __mmSoldierAutoEnabled,
      autoHeal: __mmAutoHealEnabled,
    };
  },
  nearestEnemy() {
    if (__mmLiveStateFresh()) return __mmLiveState.nearestEnemy;
    if (!v || !v.alive || !Array.isArray(E)) return null;
    let __mmClosest = null;
    let __mmClosestDistance = Infinity;
    for (let __mmIndex = 0; __mmIndex < E.length; __mmIndex += 1) {
      const __mmPlayer = E[__mmIndex];
      if (
        !__mmIsEnemyPlayer(__mmPlayer) ||
        !Number.isFinite(Number(__mmPlayer.x)) ||
        !Number.isFinite(Number(__mmPlayer.y))
      )
        continue;
      const __mmDx = __mmPlayer.x - v.x;
      const __mmDy = __mmPlayer.y - v.y;
      const __mmDistance = __mmDx * __mmDx + __mmDy * __mmDy;
      if (__mmDistance < __mmClosestDistance) {
        __mmClosest = __mmPlayer;
        __mmClosestDistance = __mmDistance;
      }
    }
    return __mmClosest;
  },
  target() {
    if (this.targetSid == null) return null;
    let __mmTarget = null;
    try {
      __mmTarget = Rt(this.targetSid);
    } catch (__mmLookupError) {}
    if (!__mmTarget && Array.isArray(E)) {
      for (let __mmIndex = 0; __mmIndex < E.length; __mmIndex += 1) {
        const __mmPlayer = E[__mmIndex];
        if (__mmPlayer && String(__mmPlayer.sid) === String(this.targetSid)) {
          __mmTarget = __mmPlayer;
          break;
        }
      }
    }
    return __mmTarget &&
      String(__mmTarget.sid) === String(this.targetSid) &&
      (__mmIsEnemyPlayer(__mmTarget) ||
        (this.betrayal &&
          __mmTarget !== v &&
          __mmTarget.alive &&
          __mmTarget.visible)) &&
      Number.isFinite(Number(__mmTarget.x)) &&
      Number.isFinite(Number(__mmTarget.y))
      ? __mmTarget
      : null;
  },
  weaponData(__mmWeapon) {
    return b && b.weapons && __mmWeapon != null ? b.weapons[__mmWeapon] : null;
  },
  supportedPrimary() {
    if (!v || !v.alive || !v.weapons) return null;
    const __mmWeapon = v.weapons[0];
    if (
      __mmWeapon !== __mmShortSword &&
      __mmWeapon !== __mmKatana &&
      __mmWeapon !== __mmPolearmWeapon
    )
      return null;
    const __mmData = this.weaponData(__mmWeapon);
    return __mmData &&
      __mmData.projectile == null &&
      __mmWeapon;
  },
  inRange(__mmWeapon, __mmTarget) {
    const __mmData = this.weaponData(__mmWeapon);
    const __mmRange = __mmData && Number(__mmData.range);
    if (
      !v ||
      !__mmTarget ||
      !Number.isFinite(__mmRange) ||
      __mmRange <= 0
    )
      return !1;
    const __mmReach =
      (__mmRange +
        (Number(v.scale) || 0) +
        (Number(__mmTarget.scale) || 0)) *
      __mmFullInstaRangeMultiplier;
    return Math.hypot(__mmTarget.x - v.x, __mmTarget.y - v.y) <= __mmReach;
  },
  canFullBurst(__mmTarget) {
    const __mmPrimary = this.supportedPrimary(),
      __mmSecondary = v && v.weapons && v.weapons[1],
      __mmSecondaryData = this.weaponData(__mmSecondary);
    return !!(
      __mmPrimary != null &&
      __mmTarget &&
      this.inRange(__mmPrimary, __mmTarget) &&
      __mmSecondary != null &&
      __mmSecondary !== __mmPrimary &&
      __mmSecondary !== __mmShieldWeapon &&
      __mmSecondaryData &&
      !__mmSecondaryData.shield
    );
  },
  fullBurstReady(
    __mmTarget,
    __mmProfile = "normal",
    __mmBetrayal = !1,
    __mmIgnoreShield = !1,
  ) {
    if (
      !v ||
      !v.alive ||
      !__mmTarget ||
      !v.skins ||
      !v.skins[7] ||
      (!__mmBetrayal && !__mmIsEnemyPlayer(__mmTarget))
    )
      return !1;
    if (!__mmIgnoreShield && !__mmShieldBypass(v, __mmTarget)) return !1;
    const __mmPrimary = this.supportedPrimary();
    if (
      __mmPrimary == null ||
      !this.inRange(__mmPrimary, __mmTarget) ||
      !__mmWeaponReady(__mmPrimary)
    )
      return !1;
    if (__mmProfile === "velTick" || __mmProfile === "autoPush")
      return !!(
        v.skins[__mmTurretGear] &&
        this.turretReady()
      );
    const __mmSecondary = v.weapons && v.weapons[1],
      __mmSecondaryData = this.weaponData(__mmSecondary);
    if (
      __mmSecondary == null ||
      __mmSecondary === __mmPrimary ||
      __mmSecondary === __mmShieldWeapon ||
      !__mmSecondaryData ||
      __mmSecondaryData.shield ||
      !__mmWeaponReady(__mmSecondary)
    )
      return !1;
    return __mmProfile === "polearmAids"
      ? !!v.skins[40]
      : !!(
          v.skins[__mmTurretGear] &&
          this.turretReady()
        );
  },
  aim(__mmTarget) {
    return __mmTarget
      ? Math.atan2(__mmTarget.y - v.y, __mmTarget.x - v.x)
      : Ci();
  },
  projectileAim(__mmTarget) {
    if (!__mmTarget || !v) return this.aim(__mmTarget);
    const __mmWeaponData = b && b.weapons && b.weapons[__mmCrossbow],
      __mmProjectile =
        __mmWeaponData &&
        b.projectiles &&
        b.projectiles[__mmWeaponData.projectile],
      __mmSpeed = Number(__mmProjectile && __mmProjectile.speed),
      __mmDistance = Math.hypot(__mmTarget.x - v.x, __mmTarget.y - v.y),
      __mmTravelMs =
        (Number.isFinite(__mmSpeed) && __mmSpeed > 0
          ? __mmDistance / __mmSpeed
          : 0) +
        Math.min(55, __mmServerTickMs() * 0.5);
    return __mmSyncAimAngle(__mmTarget, __mmTravelMs);
  },
  launchDelay() {
    const __mmPing = Number(window.pingTime),
      __mmOneWayPing = Number.isFinite(__mmPing)
        ? Math.max(0, __mmPing / 2)
        : 0;
    // The boost pad must reach the server before the Crossbow phase. Aim for the
    // following server phase, compensated by one-way latency, instead of the old
    // 5ms ambush shortcut that could fire before the boost existed.
    return Math.max(
      12,
      Math.min(
        __mmServerTickMs(),
        Math.round(__mmServerTickMs() - Math.min(70, __mmOneWayPing)),
      ),
    );
  },
  damageTail() {
    if (!v || !v.alive) return null;
    if (v.tails && v.tails[__mmCorruptXWings]) return __mmCorruptXWings;
    return (this.snapshot && this.snapshot.tail === 11) || v.tailIndex === 11
      ? 0
      : null;
  },
  preparePostSpike(__mmTarget) {
    if (!this.postSpikeEnabled || !__mmTarget || !v || !v.alive) return null;
    this.postSpikeTarget = {
      x: Number(__mmTarget.x),
      y: Number(__mmTarget.y),
      scale: Number(__mmTarget.scale) || 35,
      sid: __mmTarget.sid,
    };
    const __mmSpike = __mmSpikeItem();
    if (
      __mmSpike == null ||
      __mmHoldingMcGrabby() ||
      !__mmAutoSpikeSpamHasCapacity(__mmSpike)
    )
      return null;
    let __mmCandidate = __mmAutoSpikeSpamCandidate(
      { enemy: __mmTarget, trap: null },
      __mmSpike,
    );
    if (__mmCandidate) __mmCandidate.contactRequired = !0;
    if (!__mmCandidate) {
      const __mmData = b && b.list && b.list[__mmSpike],
        __mmSpikeScale = Number(__mmData && __mmData.scale) || 49,
        __mmPlacementRadius =
          (Number(v.scale) || 35) +
          __mmSpikeScale +
          (Number(__mmData && __mmData.placeOffset) || 0),
        __mmBaseAngle = Math.atan2(
          Number(__mmTarget.y) - Number(v.y),
          Number(__mmTarget.x) - Number(v.x),
        );
      // If a touching slot is impossible, search the entire legal placement
      // ring. Target-facing positions stay first, followed by increasingly
      // wider offsets, so a Hammer Insta still puts down the closest useful
      // spike instead of silently doing nothing.
      for (let __mmStep = 0; __mmStep <= 36 && !__mmCandidate; __mmStep++) {
        const __mmOffset = (__mmStep * Math.PI) / 36,
          __mmSigns = __mmStep === 0 || __mmStep === 36 ? [1] : [1, -1];
        for (
          let __mmSignIndex = 0;
          __mmSignIndex < __mmSigns.length;
          __mmSignIndex++
        ) {
          const __mmAngle = __mmBaseAngle + __mmOffset * __mmSigns[__mmSignIndex],
            __mmX = Number(v.x) + Math.cos(__mmAngle) * __mmPlacementRadius,
            __mmY = Number(v.y) + Math.sin(__mmAngle) * __mmPlacementRadius;
          if (!__mmAutoSpikeSpamPositionClear(__mmX, __mmY, __mmSpikeScale))
            continue;
          __mmCandidate = {
            item: __mmSpike,
            x: __mmX,
            y: __mmY,
            angle: __mmAngle,
            scale: __mmSpikeScale,
            targetSid: __mmTarget.sid,
            contactRequired: !1,
          };
          break;
        }
      }
    }
    if (__mmCandidate) {
      ((__mmCandidate.mode = "hammerInsta"),
        (__mmCandidate.intentReady = !0),
        (this.postSpikeCandidate = __mmCandidate),
        (this.postSpikeCalculatedAt = Date.now()));
    } else {
      ((this.postSpikeCandidate = null), (this.postSpikeCalculatedAt = 0));
    }
    return this.postSpikeCandidate;
  },
  placePostSpike(__mmTarget) {
    if (!this.postSpikeEnabled || !__mmTarget || !v || !v.alive) return !1;
    // Refresh synchronously in the final combo phase. Earlier phases have
    // already warmed the solver, so this adds no timer or acknowledgement wait.
    this.preparePostSpike(__mmTarget);
    const __mmCandidate = this.postSpikeCandidate,
      __mmData =
        __mmCandidate && b && b.list && b.list[__mmCandidate.item];
    if (
      !__mmCandidate ||
      !__mmData ||
      Date.now() - this.postSpikeCalculatedAt > this.normalStageMs() * 2 ||
      !__mmAutoSpikeSpamHasCapacity(__mmCandidate.item)
    )
      return !1;
    const __mmSpikeScale = Number(__mmData.scale) || __mmCandidate.scale || 49,
      __mmPlacementRadius =
        (Number(v.scale) || 35) +
        __mmSpikeScale +
        (Number(__mmData.placeOffset) || 0),
      __mmX = Number(v.x) + Math.cos(__mmCandidate.angle) * __mmPlacementRadius,
      __mmY = Number(v.y) + Math.sin(__mmCandidate.angle) * __mmPlacementRadius,
      __mmTouchRadius =
        (Number(__mmTarget.scale) || 35) + __mmSpikeScale,
      __mmTargetDistance = Math.hypot(
        Number(__mmTarget.x) - __mmX,
        Number(__mmTarget.y) - __mmY,
      );
    if (
      (__mmCandidate.contactRequired &&
        (__mmTargetDistance > __mmTouchRadius + 5 ||
          __mmTargetDistance < __mmTouchRadius - 12)) ||
      !__mmAutoSpikeSpamPositionClear(__mmX, __mmY, __mmSpikeScale)
    )
      return !1;
    try {
      if (
        !__mmInstaPlaceAndReselect(
          __mmCandidate.item,
          __mmCandidate.angle,
          this.primaryWeapon,
        )
      )
        return !1;
      (O.send("D", __mmCandidate.angle),
        __mmAutoSpikeSpamReservations.push({
          item: __mmCandidate.item,
          x: __mmX,
          y: __mmY,
          scale: __mmSpikeScale,
          expiresAt: Date.now() + 650,
        }),
        (__mmAutoSpikeSpamLastAt = Date.now()));
      return !0;
    } catch (__mmHammerInstaSpikeError) {
      return !1;
    }
  },
  context(__mmRequireRange) {
    if (
      (!__mmInstaUiEnabled && !this.automatic) ||
      !this.runtimeReady() ||
      this.isPriorityConflict()
    )
      return null;
    const __mmPrimary = this.supportedPrimary();
    if (__mmPrimary == null) return null;
    const __mmTarget = this.target();
    if (!__mmTarget && !this.targetOptional) return null;
    if (__mmRequireRange && __mmTarget && !this.inRange(__mmPrimary, __mmTarget))
      return null;
    return { primary: __mmPrimary, target: __mmTarget };
  },
  selectDamageGear() {
    if (!v || !v.alive) return;
    // Dispatch both equipment packets from this same local/server-tick phase.
    __mmEquipGearPair(
      v.skins && v.skins[7] ? 7 : null,
      this.damageTail(),
      !0,
    );
  },
  selectSecondaryDamageGear() {
    if (!v || !v.alive) return;
    // Re-send the damage tail in the exact Turret packet phase too. This keeps
    // the secondary stage paired even if the Bull-stage acknowledgement has
    // not reached the client yet.
    const __mmHat =
      this.profile === "polearmAids" && v.skins && v.skins[40]
        ? 40
        : v.skins && v.skins[__mmTurretGear]
          ? __mmTurretGear
          : null;
    (__mmEquipGearPair(
      __mmHat,
      this.damageTail(),
      !0,
    ),
      __mmHat === __mmTurretGear && __mmAssumeTurretGearShot());
  },
  turretReady() {
    return !!(
      v &&
      v.alive &&
      v.skins &&
      v.skins[__mmTurretGear] &&
      __mmTurretCooldownRemaining(v, Date.now()) <= 0
    );
  },
  turretInRange(__mmTarget) {
    if (!v || !__mmTarget) return !1;
    const __mmReach =
      __mmTurretGearRange +
      (Number(v.scale) || 0) +
      (Number(__mmTarget.scale) || 0);
    return Math.hypot(__mmTarget.x - v.x, __mmTarget.y - v.y) <= __mmReach;
  },
  finishTurretPoke() {
    this.state === "turretPoke" && this.cleanup("turret-poke-complete");
  },
  startTurretPoke(__mmTarget) {
    if (
      !this.turretReady() ||
      !__mmTarget ||
      !__mmShieldBypass(v, __mmTarget)
    )
      return !1;
    this.state = "turretPoke";
    this.popupShown = !0;
    __mmShowInstaTypePopup("Turret Poke");
    (__mmEquipHatNow(__mmTurretGear), __mmAssumeTurretGearShot());
    // Keep the game's aim direction on the distant target while Turret Gear
    // is active. Turret Gear fires on its own cooldown; no normal attack is
    // sent in this out-of-melee-range branch.
    try {
      O.send("D", this.aim(__mmTarget));
    } catch (__mmTurretAimError) {}
    // This is a best-effort troll shot: no weapon/loadout or distance gate and
    // no server acknowledgement wait. Restore on the next local server tick.
    this.schedule(() => this.finishTurretPoke());
    return !0;
  },
  start(__mmOptions = {}) {
    if (this.state !== "idle") return !1;
    const __mmRequestedProfile = String(__mmOptions.profile || "normal"),
      __mmAutomatic = !!__mmOptions.automatic,
      __mmManualHotkey = !!__mmOptions.manualHotkey,
      __mmNow = Date.now();
    let __mmPreflightTarget = null;
    try {
      __mmPreflightTarget =
        __mmOptions.targetSid == null
          ? this.nearestEnemy()
          : Rt(__mmOptions.targetSid);
    } catch (__mmPreflightTargetError) {}
    // Revalidate at the one point that can actually claim the Insta. Earlier
    // scanners may have observed a ready weapon a few milliseconds before a
    // swing/reload packet changed it. Failed automatic attempts are briefly
    // latched so 5 ms automation loops cannot spam the start path.
    if (
      __mmAutomatic &&
      (__mmNow < this.automaticRetryUntil ||
        !this.fullBurstReady(
          __mmPreflightTarget,
          __mmRequestedProfile,
          !!__mmOptions.betrayal,
        ))
    ) {
      this.automaticRetryUntil = Math.max(
        this.automaticRetryUntil,
        __mmNow + Math.max(120, this.tick()),
      );
      return !1;
    }
    if (__mmManualHotkey) __mmCancelScheduledSyncInsta();
    else if (
      !__mmOptions.syncScheduled &&
      __mmTryScheduleSharedInsta(__mmOptions)
    )
      return !0;
    this.cancelHatRestore();
    // A real R burst has priority over a scheduled friendly-shot sync and idle
    // reloading, but never steals selection from an emergency action.
    __mmActionOwner === "instaSync" && __mmStopInstaSync();
    __mmActionOwner === "weaponRecharge" && __mmPauseWeaponRecharge(!0);
    this.suspendTrapEscape();
    const __mmHeldAttackSuspended = __mmManualHotkey
      ? __mmSuspendHeldAttackForManualInsta()
      : !1;
    if (
      !__mmActionClaim(
        "insta",
        __mmOptions.betrayal
          ? "betrayal combo"
          : __mmOptions.automatic
            ? "auto target"
            : "R combo",
      )
    ) {
      const __mmResumeTrap = !!(
        this.trapHandoff &&
        this.trapHandoff.resume &&
        v &&
        v.alive &&
        __mmIsTrapped()
      );
      this.trapHandoff = null;
      __mmResumeTrap && __mmBreakTrap();
      __mmHeldAttackSuspended &&
        (__mmPrimaryHeld || __mmSecondaryHeld) &&
        (__mmActionClaim("manualAttack", "resume after blocked R Insta"),
        __mmResumeHeldAttack());
      return !1;
    }
    __mmCancelCombatHatLock(!1);
    this.state = "validate";
    this.targetOptional = !!__mmOptions.targetOptional;
    this.automatic = !!__mmOptions.automatic;
    this.betrayal = !!__mmOptions.betrayal;
    this.manualHotkey = __mmManualHotkey;
    this.bowUpgradeFollowup = !!__mmOptions.bowUpgradeFollowup;
    this.profile = __mmRequestedProfile;
    this.profileSource = String(__mmOptions.profileSource || this.profile);
    this.popupShown = !1;
    if (!this.runtimeReady()) return (this.cleanup("runtime-unavailable"), !1);
    this.capture();
    const __mmRequestedTarget =
      __mmOptions.targetSid == null ? null : Rt(__mmOptions.targetSid),
      __mmTarget =
        __mmRequestedTarget &&
        (__mmIsEnemyPlayer(__mmRequestedTarget) ||
          (this.betrayal &&
            __mmRequestedTarget !== v &&
            __mmRequestedTarget.alive &&
            __mmRequestedTarget.visible))
          ? __mmRequestedTarget
          : this.betrayal
            ? null
            : this.nearestEnemy();
    if (__mmTarget) this.targetSid = __mmTarget.sid;
    this.postSpikeEnabled = !!(
      __mmTarget &&
      v.weapons &&
      Number(v.weapons[1]) === __mmGreatHammer
    );
    this.postSpikeCandidate = null;
    this.postSpikeCalculatedAt = 0;
    this.postSpikeTarget = null;
    this.postSpikeEnabled && this.preparePostSpike(__mmTarget);
    const __mmPrimary = this.supportedPrimary(),
      __mmTargetInPrimaryRange = !!(
        __mmTarget &&
        __mmPrimary != null &&
        this.inRange(__mmPrimary, __mmTarget)
      );
    // Manual R keeps the intentional out-of-range Turret poke, but an in-range
    // full combo does not arm unless every weapon and combat hat is ready.
    if (
      __mmTargetInPrimaryRange &&
      !this.fullBurstReady(
        __mmTarget,
        this.profile,
        this.betrayal,
        !this.automatic,
      )
    )
      return (this.cleanup("kit-not-ready"), !1);
    if (
      !this.automatic &&
      !this.betrayal &&
      __mmInstaUiEnabled &&
      __mmTarget &&
      !this.canFullBurst(__mmTarget) &&
      this.startTurretPoke(__mmTarget)
    )
      return !0;
    const __mmContext = this.context(!1);
    if (!__mmContext) return (this.cleanup("validation-failed"), !1);
    this.primaryWeapon = __mmContext.primary;
    this.preparePostSpike(__mmContext.target);
    this.state = "arm";
    this.arm();
    return !0;
  },
  canAutoStart(__mmIgnoreAutoToggle = !1) {
    if (
      (!__mmIgnoreAutoToggle && !__mmAutoInstaEnabled) ||
      this.state !== "idle" ||
      Date.now() < this.automaticRetryUntil ||
      !this.runtimeReady() ||
      this.isPriorityConflict()
    )
      return !1;
    return this.fullBurstReady(this.nearestEnemy(), "normal", !1);
  },
  arm() {
    const __mmContext = this.context(!1);
    if (!__mmContext) return void this.cleanup("arm-invalid");
    this.primaryWeapon = __mmContext.primary;
    // Do not change gear until the target is actually in reach.
    this.state = "waitForRange";
    this.waitForRange();
  },
  waitForRange() {
    if (this.state !== "waitForRange") return;
    const __mmContext = this.context(!1);
    if (!__mmContext) return void this.cleanup("target-or-state-lost");
    this.primaryWeapon = __mmContext.primary;
    if (__mmContext.target && !this.inRange(__mmContext.primary, __mmContext.target))
      return void (
        this.startTurretPoke(__mmContext.target) ||
          this.cleanup("out-of-range")
      );
    if (__mmContext.target && !__mmShieldBypass(v, __mmContext.target)) {
      this.shieldWaitStartedAt || (this.shieldWaitStartedAt = Date.now());
      if (
        Date.now() - this.shieldWaitStartedAt >
        Math.max(900, this.tick() * 6)
      )
        return void this.cleanup("shield-timeout");
      try {
        (je(__mmContext.primary, !0),
          O.send("D", this.aim(__mmContext.target)));
      } catch (__mmShieldWaitAimError) {}
      return void this.schedule(
        () => this.waitForRange(),
        Math.max(10, Math.min(35, __mmFastCheckMs())),
      );
    }
    this.shieldWaitStartedAt = 0;
    // Use a one-stage setup: aim now, then start Bull + primary
    // after its 120 ms opening delay. The distant Turret poke remains separate.
    this.state = "executeBurst";
    try {
      // Hold main throughout setup instead of switching only when the attack
      // packet is emitted. The combo snapshot still restores the old tool.
      (je(__mmContext.primary, !0),
        O.send("D", this.aim(__mmContext.target)));
    } catch (__mmInstaSetupAimError) {}
    this.schedule(() => this.executeBurst(), this.openingDelay());
  },
  releaseAttack() {
    this.releaseTimer && clearTimeout(this.releaseTimer);
    this.releaseTimer = 0;
    if (!this.attackHeld) return;
    try {
      O && O.send && O.send("F", 0, null);
    } catch (__mmReleaseError) {}
    this.attackHeld = !1;
  },
  sendAttack(__mmItem, __mmIsWeapon, __mmTarget) {
    if (!v || !v.alive || __mmItem == null) return !1;
    this.releaseAttack();
    try {
      const __mmAngle = this.aim(__mmTarget);
      je(__mmItem, !!__mmIsWeapon);
      O.send("F", 1, __mmAngle);
      this.attackHeld = !0;
      return !0;
    } catch (__mmAttackError) {
      this.attackHeld = !1;
      return !1;
    }
  },
  executeBurst() {
    if (this.state !== "executeBurst") return;
    const __mmContext = this.context(!0);
    if (!__mmContext)
      return void this.cleanup("primary-unavailable");
    if (__mmContext.target && !__mmShieldBypass(v, __mmContext.target)) {
      this.state = "waitForRange";
      return void this.waitForRange();
    }
    if (!this.popupShown) {
      this.popupShown = !0;
      __mmShowInstaTypePopup(
        __mmInstaPopupLabel(this.profile, this.automatic, this.betrayal),
      );
    }
    this.preparePostSpike(__mmContext.target);
    if (this.profile === "velTick") {
      if (!this.turretReady())
        return void this.cleanup("veltick-turret-unavailable");
      this.selectSecondaryDamageGear();
      try {
        (O.send("D", this.aim(__mmContext.target)),
          je(__mmContext.primary, !0));
      } catch (__mmVelTickOpeningError) {
        return void this.cleanup("veltick-opening-failed");
      }
      this.schedule(() => this.executeFollowup(), this.tick());
      return;
    }
    if (this.profile === "autoPush") {
      this.selectDamageGear();
      if (!this.sendAttack(__mmContext.primary, !0, __mmContext.target))
        return void this.cleanup("auto-push-primary-send-failed");
      this.scheduleRelease();
      this.schedule(() => this.executeFollowup(), this.tick());
      return;
    }
    if (this.reverseProfile()) {
      const __mmSecondary = this.secondaryFollowup();
      if (
        __mmSecondary == null ||
        !__mmWeaponReady(__mmSecondary) ||
        !this.inRange(__mmSecondary, __mmContext.target)
      )
        return void this.cleanup("reverse-secondary-unavailable");
      this.pendingSecondaryWeapon = __mmSecondary;
      this.selectSecondaryDamageGear();
      if (!this.sendAttack(__mmSecondary, !0, __mmContext.target))
        return void this.cleanup("reverse-secondary-send-failed");
      ((this.pendingSecondaryWeapon = null),
        this.scheduleRelease(),
        this.schedule(
          () => this.executeFollowup(),
          this.profileStep(__mmContext.target, __mmSecondary),
        ));
      return;
    }
    // Combo stage one: Bull + primary, with a short tap instead of a
    // full-tick held attack.
    this.selectDamageGear();
    if (!this.sendAttack(__mmContext.primary, !0, __mmContext.target))
      return void this.cleanup("primary-send-failed");
    this.scheduleRelease();
    this.schedule(() => this.executeFollowup(), this.normalStageMs());
  },
  secondaryFollowup() {
    if (!v || !v.weapons) return null;
    const __mmWeapon = v.weapons[1],
      __mmData = this.weaponData(__mmWeapon);
    return __mmWeapon != null &&
      __mmWeapon !== this.primaryWeapon &&
      __mmWeapon !== __mmShieldWeapon &&
      __mmData &&
      !__mmData.shield
      ? __mmWeapon
      : null;
  },
  executeFollowup() {
    if (this.state !== "executeBurst") return;
    // Combo stage two: release the primary, then switch Turret gear and
    // the secondary in the same phase before firing its 25 ms tap.
    this.releaseAttack();
    // The opening hit may knock the target out of primary melee range. Keep
    // the confirmed target but let the equipped secondary make its own shot.
    const __mmContext = this.context(!1);
    if (!__mmContext) return void this.cleanup("followup-invalid");
    this.preparePostSpike(__mmContext.target);
    if (this.profile === "autoPush") {
      if (!this.turretReady())
        return void this.cleanup("auto-push-turret-unavailable");
      this.selectSecondaryDamageGear();
      try {
        (O.send("D", this.aim(__mmContext.target)),
          je(__mmContext.primary, !0));
      } catch (__mmAutoPushTurretError) {
        return void this.cleanup("auto-push-turret-failed");
      }
      this.schedule(() => this.finishNormalBurst(), this.tick());
      return;
    }
    if (this.profile === "velTick") {
      if (
        !__mmWeaponReady(__mmContext.primary) ||
        !this.inRange(__mmContext.primary, __mmContext.target)
      )
        return void this.cleanup("veltick-primary-unavailable");
      this.selectDamageGear();
      if (!this.sendAttack(__mmContext.primary, !0, __mmContext.target))
        return void this.cleanup("veltick-primary-send-failed");
      (this.scheduleRelease(),
        this.schedule(() => this.finishNormalBurst(), this.tick()));
      return;
    }
    if (this.reverseProfile()) {
      if (
        !__mmWeaponReady(__mmContext.primary) ||
        !this.inRange(__mmContext.primary, __mmContext.target)
      )
        return void this.cleanup("reverse-primary-unavailable");
      this.selectDamageGear();
      if (!this.sendAttack(__mmContext.primary, !0, __mmContext.target))
        return void this.cleanup("reverse-primary-send-failed");
      (this.scheduleRelease(),
        this.schedule(() => this.finishNormalBurst(), this.tick()));
      return;
    }
    const __mmSecondary = this.secondaryFollowup();
    if (
      __mmSecondary == null ||
      !__mmWeaponReady(__mmSecondary) ||
      !this.turretReady()
    )
      return void this.cleanup("secondary-or-turret-unavailable");
    this.pendingSecondaryWeapon = __mmSecondary;
    __mmSmartPlaceUtilityForInsta(__mmContext.target, __mmSecondary);
    this.selectSecondaryDamageGear();
    try {
      O.send("D", this.aim(__mmContext.target));
    } catch (__mmSecondaryAimError) {}
    if (!this.sendAttack(__mmSecondary, !0, __mmContext.target))
      return void this.cleanup("secondary-send-failed");
    ((this.pendingSecondaryWeapon = null),
      this.scheduleRelease(),
      this.schedule(() => this.finishNormalBurst(), this.normalStageMs()));
  },
  finishNormalBurst() {
    if (this.state !== "executeBurst") return;
    this.releaseAttack();
    if (!v || !v.alive || this.primaryWeapon == null)
      return void this.cleanup("finish-context-lost");
    const __mmTarget = this.target() || this.postSpikeTarget;
    __mmTarget && this.placePostSpike(__mmTarget);
    if (this.bowUpgradeFollowup) {
      // The Bow was the normal Insta's secondary shot. Keep Turret Gear, the
      // target direction, and the projectile weapon channel intact; cleanup
      // hands directly to Crossbow instead of visibly restoring Soldier/main.
      this.state = "soldier";
      this.schedule(
        () => this.cleanup("complete"),
        Math.max(4, Math.min(10, __mmFastCheckMs())),
      );
      return;
    }
    // Combo stage three: Soldier and the primary are selected together. Kitty
    // gives that visible settle stage 170 ms before restoring the loadout.
    this.state = "soldier";
    __mmEquipGearPair(
      v.skins && v.skins[6]
        ? 6
        : this.snapshot && this.snapshot.hat,
      this.damageTail(),
      !0,
    );
    je(this.primaryWeapon, !0);
    this.schedule(() => this.cleanup("complete"), Math.max(170, this.tick()));
  },
  cleanup(__mmReason) {
    const __mmSnapshot = this.snapshot,
      __mmCompletedFullInsta = __mmReason === "complete",
      __mmBowFollowupTarget = __mmCompletedFullInsta && this.bowUpgradeFollowup
        ? this.target()
        : null,
      __mmChainBowUpgrade = !!(
        __mmBowFollowupTarget &&
        __mmBowUpgradeInsta.ready(__mmBowFollowupTarget, !0)
      ),
      __mmRestore = __mmActionMayRestore("insta"),
      __mmResumeTrap = !!(
        this.trapHandoff &&
        this.trapHandoff.resume &&
        __mmTrapEscapeEnabled &&
        v &&
        v.alive &&
        __mmIsTrapped()
      );
    this.state = "cleanup";
    this.timer && clearTimeout(this.timer);
    this.timer = 0;
    this.releaseTimer && clearTimeout(this.releaseTimer);
    this.releaseTimer = 0;
    this.releaseAttack();
    __mmCompletedFullInsta &&
      !__mmChainBowUpgrade &&
      __mmSnapshot &&
      __mmPreferWeaponRechargeRestore(__mmSnapshot.weapon);
    const __mmSafeRestoreHat = __mmSnapshot
      ? __mmInstaSafeRestoreHat(__mmSnapshot.hat)
      : __mmInstaSafeRestoreHat(__mmLastNormalHat);
    if (
      !__mmChainBowUpgrade &&
      v &&
      v.alive &&
      __mmSnapshot &&
      __mmRestore
    ) {
      __mmEquipGearPair(__mmSafeRestoreHat, __mmSnapshot.tail, !0);
      this.scheduleHatRestore(__mmSafeRestoreHat);
      __mmSnapshot.weapon != null && __mmRestoreWeapon(__mmSnapshot.weapon);
      (__mmSnapshot.primaryHeld || __mmSnapshot.secondaryHeld) &&
        (__mmPrimaryHeld || __mmSecondaryHeld) &&
        __mmResumeHeldAttack();
    }
    // If a higher-priority safety action preempted the combo, defer instead of
    // abandoning the cleanup. The restore worker waits until that owner yields.
    !__mmChainBowUpgrade &&
      v &&
      v.alive &&
      (!__mmRestore || __mmTemporaryCombatHat(v.skinIndex)) &&
      this.scheduleHatRestore(__mmSafeRestoreHat);
    this.snapshot = null;
    this.targetSid = null;
    this.targetOptional = !1;
    this.automatic = !1;
    this.betrayal = !1;
    this.manualHotkey = !1;
    this.bowUpgradeFollowup = !1;
    this.primaryWeapon = null;
    this.pendingSecondaryWeapon = null;
    this.trapHandoff = null;
    this.postSpikeEnabled = !1;
    this.postSpikeCandidate = null;
    this.postSpikeCalculatedAt = 0;
    this.postSpikeTarget = null;
    this.profile = "normal";
    this.profileSource = "R";
    this.popupShown = !1;
    this.shieldWaitStartedAt = 0;
    this.reason = __mmReason || "cancelled";
    this.state = "idle";
    !__mmCompletedFullInsta &&
      (this.automaticRetryUntil = Math.max(
        this.automaticRetryUntil,
        Date.now() + Math.max(120, this.tick()),
      ));
    __mmActionRelease("insta", this.reason);
    if (__mmChainBowUpgrade) {
      const __mmChained = __mmBowUpgradeInsta.start(
        __mmBowFollowupTarget,
        "normal insta follow-up",
        {
          skipBow: !0,
          restoreTool:
            __mmSnapshot && __mmSnapshot.weapon != null
              ? { item: __mmSnapshot.weapon, weapon: !0 }
              : null,
          restoreHat: __mmSafeRestoreHat,
        },
      );
      if (__mmChained) return;
      // A safety state can appear between the final melee hit and this local
      // handoff. If so, perform the ordinary Insta restore instead of leaving
      // Turret/Soldier or the borrowed tool equipped.
      if (v && v.alive && __mmSnapshot && __mmRestore) {
        (__mmEquipGearPair(__mmSafeRestoreHat, __mmSnapshot.tail, !0),
          this.scheduleHatRestore(__mmSafeRestoreHat),
          __mmSnapshot.weapon != null && __mmRestoreWeapon(__mmSnapshot.weapon));
      }
    }
    __mmCompletedFullInsta && __mmInstaChatEnabled && __mmSendChat("Meow!");
    // These loops were gated while the burst owned gear/selection. Run their
    // normal updates now instead of changing their user-configured toggles.
    if (v && v.alive) {
      __mmResumeTrap && __mmBreakTrap();
      __mmUpdateMovementGear();
      __mmUpdateSoldier();
      __mmUpdateWeaponRecharge();
      __mmAutoHeal();
    }
  },
  cancel(__mmReason) {
    this.cleanup(__mmReason || "cancelled");
  },
};
const __mmBoostInsta = {
  state: "idle",
  timer: 0,
  loop: 0,
  targetSid: null,
  primaryWeapon: null,
  snapshot: null,
  attackHeld: !1,
  aimAngle: null,
  moveAngle: null,
  startedAt: 0,
  ambush: !1,
  manualBush: !1,
  shieldWaitStartedAt: 0,
  isActive() {
    return this.state !== "idle" && this.state !== "cleanup";
  },
  target() {
    if (this.targetSid == null) return null;
    let __mmTarget = null;
    try {
      __mmTarget = Rt(this.targetSid);
    } catch (__mmBoostTargetError) {}
    return __mmIsEnemyPlayer(__mmTarget) ? __mmTarget : null;
  },
  trueMeleeRange(__mmTarget) {
    const __mmData =
      b && b.weapons && this.primaryWeapon != null
        ? b.weapons[this.primaryWeapon]
        : null;
    return __mmData && __mmTarget
      ? (Number(__mmData.range) || 0) +
          (Number(v.scale) || 35) +
          (Number(__mmTarget.scale) || 35)
      : 0;
  },
  aim(__mmTarget) {
    return __mmTarget
      ? Math.atan2(__mmTarget.y - v.y, __mmTarget.x - v.x)
      : Ci();
  },
  setMovement(__mmAngle) {
    if (!Number.isFinite(__mmAngle)) return;
    const __mmDifference =
      this.moveAngle == null
        ? Infinity
        : Math.abs(
            Math.atan2(
              Math.sin(__mmAngle - this.moveAngle),
              Math.cos(__mmAngle - this.moveAngle),
            ),
          );
    if (__mmDifference < 0.035) return;
    ((this.moveAngle = __mmAngle), (Kt = __mmAngle), O.send("9", __mmAngle));
  },
  stopMovement() {
    if (this.moveAngle == null) return;
    ((this.moveAngle = null), (Kt = null), O.send("9", null));
  },
  releaseAttack() {
    if (!this.attackHeld) return;
    (O.send(
      "F",
      0,
      Number.isFinite(this.aimAngle) ? this.aimAngle : null,
    ),
      (this.attackHeld = !1));
  },
  schedule(__mmCallback, __mmDelay = __mmServerTickMs()) {
    this.timer && clearTimeout(this.timer);
    this.timer = setTimeout(() => {
      this.timer = 0;
      __mmCallback();
    }, __mmDelay);
  },
  requirements(__mmTarget, __mmAllowAmbush = !1) {
    const __mmPrimary = __mmInsta.supportedPrimary(),
      __mmPad = __mmBoostPadItem(),
      __mmCrossbowData = b && b.weapons && b.weapons[__mmCrossbow],
      __mmProjectile =
        __mmCrossbowData &&
        b.projectiles &&
        b.projectiles[__mmCrossbowData.projectile],
      __mmMaximumRange =
        Number(__mmProjectile && __mmProjectile.range) || 1200;
    if (
      (!__mmInstaUiEnabled && !__mmAllowAmbush) ||
      !__mmInsta.runtimeReady() ||
      !v ||
      !v.alive ||
      !__mmTarget ||
      __mmPrimary == null ||
      !v.weapons ||
      Number(v.weapons[1]) !== __mmCrossbow ||
      !__mmWeaponReady(__mmPrimary) ||
      !__mmWeaponReady(__mmCrossbow) ||
      !__mmShieldBypass(v, __mmTarget) ||
      !v.skins ||
      !v.skins[7] ||
      !v.skins[__mmTurretGear] ||
      !__mmInsta.turretReady() ||
      __mmPad == null ||
      !__mmCanUseBuildItem(__mmPad) ||
      __mmMaxBuildCount(__mmPad) < 1 ||
      __mmIsTrapped() ||
      __mmPrimaryHeld ||
      __mmSecondaryHeld ||
      __mmTrapAttackActive ||
      __mmBoostBreakHeld ||
      __mmBuildSpamTimer ||
      __mmFoodSpamTimer ||
      Date.now() < __mmAntiInstaUntil ||
      __mmInsta.isEmergencyHealth() ||
      Math.hypot(__mmTarget.x - v.x, __mmTarget.y - v.y) >
        __mmMaximumRange + (Number(v.scale) || 35)
    )
      return null;
    return { primary: __mmPrimary, crossbow: __mmCrossbow, pad: __mmPad };
  },
  start(__mmOptions = {}) {
    if (
      this.state !== "idle" ||
      __mmInsta.isActive() ||
      (__mmOptions.automatic && !__mmAutoInstaEnabled)
    )
      return !1;
    let __mmRequestedTarget = null;
    try {
      __mmRequestedTarget =
        __mmOptions.targetSid == null ? null : Rt(__mmOptions.targetSid);
    } catch (__mmBoostRequestedTargetError) {}
    const __mmTarget = __mmIsEnemyPlayer(__mmRequestedTarget)
        ? __mmRequestedTarget
        : __mmInsta.nearestEnemy(),
      __mmKit = this.requirements(__mmTarget, !!__mmOptions.ambush);
    if (!__mmKit || !__mmActionCanPreempt("boostInsta")) return !1;
    (__mmActionOwner === "instaSync" && __mmStopInstaSync(),
      __mmActionOwner === "weaponRecharge" && __mmPauseWeaponRecharge(!0),
      __mmActionOwner === "matThief" &&
        __mmFinishMatThief("boost insta"),
      __mmActionOwner === "mobSteal" && __mmFinishMobSteal("boost insta"),
      __mmBoostBreakHeld && __mmStopBoostBreak());
    if (!__mmActionClaim("boostInsta", "crossbow boost combo")) return !1;
    __mmCancelCombatHatLock(!1);
    const __mmAngle = this.aim(__mmTarget);
    ((this.ambush = !!__mmOptions.ambush),
      (this.manualBush = !!(__mmOptions.manualBush && this.ambush)),
      (this.state = "boost"),
      (this.targetSid = __mmTarget.sid),
      (this.primaryWeapon = __mmKit.primary),
      (this.snapshot = {
        weapon: __mmSelectedTool(),
        hat: __mmInstaSafeRestoreHat(__mmBushRestoreHat(v.skinIndex)),
        tail: __mmBushRestoreTail(v.tailIndex),
      }),
      (this.startedAt = Date.now()),
      (this.aimAngle = __mmAngle),
      (this.loop = setInterval(() => this.update(), __mmFastCheckMs())));
    __mmShowInstaTypePopup(this.ambush ? "Bush Boost Insta" : "Boost Insta");
    // Snapshot first, then preselect main before any boost/build packet. This
    // keeps the primary loaded through setup while cleanup can still restore
    // whatever tool the player had selected before the Insta.
    (je(__mmKit.primary, !0),
      O.send("D", __mmAngle),
      __mmInstaPlaceAndReselect(__mmKit.pad, __mmAngle, __mmKit.primary),
      this.setMovement(__mmAngle),
      this.schedule(
        () => this.fireCrossbow(),
        this.launchDelay(),
      ));
    this.ambush &&
      !this.manualBush &&
      __mmBushChatEnabled &&
      __mmSendChat("SURPRISE!!!");
    return !0;
  },
  fireCrossbow() {
    if (this.state !== "boost") return;
    const __mmTarget = this.target();
    if (!__mmTarget || !__mmWeaponReady(__mmCrossbow))
      return void this.cleanup("crossbow unavailable");
    if (!__mmShieldBypass(v, __mmTarget)) {
      this.shieldWaitStartedAt || (this.shieldWaitStartedAt = Date.now());
      if (Date.now() - this.shieldWaitStartedAt > 650)
        return void this.cleanup("shield-timeout");
      this.aimAngle = this.aim(__mmTarget);
      O.send("D", this.aimAngle);
      return void this.schedule(
        () => this.fireCrossbow(),
        Math.max(10, Math.min(35, __mmFastCheckMs())),
      );
    }
    this.shieldWaitStartedAt = 0;
    const __mmAngle = this.projectileAim(__mmTarget);
    ((this.state = "crossbow"),
      (this.aimAngle = __mmAngle),
      O.send("D", __mmAngle),
      __mmSmartPlaceUtilityForInsta(__mmTarget, __mmCrossbow),
      __mmEquipGearPair(
        __mmTurretGear,
        __mmInsta.damageTail(),
        !0,
      ),
      __mmAssumeTurretGearShot(),
      je(__mmCrossbow, !0),
      O.send("F", 1, __mmAngle),
      (this.attackHeld = !0),
      this.schedule(() => {
        if (this.state !== "crossbow") return;
        this.releaseAttack();
        ((this.state = "chase"), this.update());
      }));
  },
  update() {
    if (!this.isActive()) return;
    const __mmTarget = this.target();
    if (
      !v ||
      !v.alive ||
      !__mmTarget ||
      Date.now() - this.startedAt > 3200
    )
      return void this.cleanup("target or boost timeout");
    const __mmAngle = this.aim(__mmTarget),
      __mmDistance = Math.hypot(__mmTarget.x - v.x, __mmTarget.y - v.y);
    this.aimAngle = __mmAngle;
    // Boost movement begins before the projectile phase and stays locked to
    // the live target through Crossbow and chase for one seamless approach.
    this.setMovement(__mmAngle);
    if (
      this.state === "chase" &&
      __mmDistance <= this.trueMeleeRange(__mmTarget) &&
      __mmWeaponReady(this.primaryWeapon)
    )
      this.firePrimary(__mmTarget);
  },
  firePrimary(__mmTarget) {
    if (this.state !== "chase" || !__mmTarget) return;
    const __mmAngle = this.aim(__mmTarget);
    // Solve the optional finisher spike before the swing packet so a legal
    // contact/knockback slot and Bull + primary reach the same server phase.
    const __mmSpike =
        !__mmHoldingMcGrabby() && !__mmEmergencyGetawayActive()
          ? __mmSpikeItem()
          : null,
      __mmSpikeCandidates =
        __mmSpike != null &&
        __mmCanUseBuildItem(__mmSpike) &&
        __mmMaxBuildCount(__mmSpike) > 0
          ? __mmBoostSpikePlacementCandidates(__mmTarget, __mmSpike, Date.now())
          : [],
      __mmFinisherSpike = __mmSpikeCandidates.length
        ? __mmSmartBestCombination(__mmSpikeCandidates, 1)[0]
        : null;
    (this.stopMovement(),
      (this.state = "primary"),
      (this.aimAngle = __mmAngle),
      O.send("D", __mmAngle),
      __mmFinisherSpike &&
        __mmSmartPlaceNow(__mmFinisherSpike, __mmSelectedTool()),
      __mmEquipGearPair(7, __mmInsta.damageTail(), !0),
      je(this.primaryWeapon, !0),
      O.send("F", 1, __mmAngle),
      (this.attackHeld = !0),
      this.schedule(() => this.cleanup("complete")));
  },
  cleanup(__mmReason) {
    if (this.state === "idle") return;
    const __mmCompleted = __mmReason === "complete",
      __mmWasAmbush = this.ambush,
      __mmWasManualBush = this.manualBush,
      __mmSnapshot = this.snapshot,
      __mmRestore = __mmActionMayRestore("boostInsta");
    this.state = "cleanup";
    (this.timer && clearTimeout(this.timer),
      (this.timer = 0),
      this.loop && clearInterval(this.loop),
      (this.loop = 0),
      this.releaseAttack(),
      this.stopMovement());
    __mmCompleted &&
      __mmSnapshot &&
      __mmPreferWeaponRechargeRestore(__mmSnapshot.weapon);
    if (__mmRestore && v && v.alive && __mmSnapshot) {
      (__mmEquipGearPair(__mmSnapshot.hat, __mmSnapshot.tail, !0),
        __mmSnapshot.weapon != null && __mmRestoreTool(__mmSnapshot.weapon));
    }
    ((this.targetSid = null),
      (this.primaryWeapon = null),
      (this.snapshot = null),
      (this.aimAngle = null),
      (this.startedAt = 0),
      (this.shieldWaitStartedAt = 0),
      (this.ambush = !1),
      (this.manualBush = !1),
      (this.state = "idle"),
      __mmActionRelease("boostInsta", __mmReason || "cancelled"),
      __mmScheduleMouseAimReturn(),
      typeof Tt === "function" && Tt(),
      __mmCompleted &&
        (!__mmWasAmbush || __mmWasManualBush) &&
        __mmInstaChatEnabled &&
        __mmSendChat("Meow!"),
      v && v.alive &&
        (__mmUpdateMovementGear(),
        __mmUpdateSoldier(),
        __mmUpdateWeaponRecharge(),
        __mmAutoHeal()));
  },
  cancel(__mmReason) {
    this.cleanup(__mmReason || "cancelled");
  },
};
function __mmNearestBetrayalTarget() {
  if (!v || !v.alive || !Array.isArray(E) || __mmTeamKey(v) == null)
    return null;
  let __mmClosest = null,
    __mmClosestDistance = Infinity;
  for (let __mmIndex = 0; __mmIndex < E.length; __mmIndex++) {
    const __mmPlayer = E[__mmIndex];
    if (
      !__mmPlayer ||
      !__mmPlayer.alive ||
      !__mmPlayer.visible ||
      __mmPlayer === v ||
      String(__mmPlayer.sid) === String(v.sid) ||
      !__mmSameTeam(__mmPlayer) ||
      __mmIsFriendPlayer(__mmPlayer) ||
      !Number.isFinite(Number(__mmPlayer.x)) ||
      !Number.isFinite(Number(__mmPlayer.y))
    )
      continue;
    const __mmDistance =
      (__mmPlayer.x - v.x) ** 2 + (__mmPlayer.y - v.y) ** 2;
    if (__mmDistance < __mmClosestDistance)
      ((__mmClosest = __mmPlayer), (__mmClosestDistance = __mmDistance));
  }
  return __mmClosest;
}
function __mmBetrayalInstaReady(__mmTarget) {
  if (
    !__mmInstaUiEnabled ||
    !__mmTarget ||
    __mmInsta.state !== "idle" ||
    !__mmInsta.runtimeReady() ||
    __mmIsTrapped() ||
    __mmPrimaryHeld ||
    __mmSecondaryHeld ||
    __mmTrapAttackActive ||
    __mmBoostBreakHeld ||
    __mmBuildSpamTimer ||
    __mmFoodSpamTimer ||
    Date.now() < __mmAntiInstaUntil ||
    __mmInsta.isEmergencyHealth() ||
    !__mmActionAvailable("insta")
  )
    return !1;
  return __mmInsta.fullBurstReady(__mmTarget, "normal", !0);
}
function __mmStartBetrayalInsta() {
  const __mmTarget = __mmNearestBetrayalTarget();
  if (!__mmTarget) return !1;
  __mmActionOwner === "matThief" &&
    __mmFinishMatThief("betrayal insta");
  __mmActionOwner === "mobSteal" &&
    __mmFinishMobSteal("betrayal insta");
  __mmActionOwner === "instaSync" && __mmStopInstaSync();
  __mmActionOwner === "weaponRecharge" && __mmPauseWeaponRecharge(!0);
  if (!__mmBetrayalInstaReady(__mmTarget)) return !1;
  // Send leave first and deliberately assume success. The betrayal target flag
  // keeps this exact former teammate valid until the combo finishes, avoiding
  // any wait for the server's team-state acknowledgement.
  O.send("N");
  return __mmInsta.start({ targetSid: __mmTarget.sid, betrayal: !0 });
}
function __mmTeamKey(__mmPlayer) {
  if (!__mmPlayer) return null;
  const __mmTeam = __mmPlayer.team;
  return typeof __mmTeam === "number"
    ? __mmTeam > 0
      ? "n:" + __mmTeam
      : null
    : typeof __mmTeam === "string" && __mmTeam.trim()
      ? "s:" + __mmTeam
      : null;
}
function __mmNormalizeFriendName(__mmName) {
  return typeof __mmName === "string"
    ? __mmName.trim().slice(0, 15).toLowerCase()
    : "";
}
function __mmFriendDisplayName(__mmName) {
  return typeof __mmName === "string" ? __mmName.trim().slice(0, 15) : "";
}
function __mmIsFriendPlayer(__mmPlayer) {
  const __mmKey = __mmNormalizeFriendName(__mmPlayer && __mmPlayer.name);
  return !!(
    __mmKey &&
    !__mmSameTeam(__mmPlayer) &&
    __mmFriendNames.has(__mmKey) &&
    !__mmFriendEnemies.has(__mmKey)
  );
}
function __mmDispatchFriendState(__mmType, __mmName) {
  window.dispatchEvent(
    new CustomEvent("MooMooFriendState", {
      detail: { type: __mmType, name: __mmName },
    }),
  );
}
function __mmTeammateByFriendKey(__mmKey) {
  return (
    Array.isArray(E) &&
    E.find(function (__mmPlayer) {
      return (
        __mmNormalizeFriendName(__mmPlayer && __mmPlayer.name) === __mmKey &&
        __mmSameTeam(__mmPlayer)
      );
    })
  );
}
function __mmAddFriend(__mmName, __mmAnnounce) {
  const __mmDisplay = __mmFriendDisplayName(__mmName),
    __mmKey = __mmNormalizeFriendName(__mmDisplay);
  if (!__mmKey) return !1;
  const __mmTeammate = __mmTeammateByFriendKey(__mmKey);
  if (__mmTeammate) {
    __mmFriendPickNotice("Teammates cannot be added as friends");
    return !1;
  }
  (__mmFriendNames.set(__mmKey, __mmDisplay),
    __mmFriendEnemies.delete(__mmKey),
    __mmDispatchFriendState("add", __mmDisplay),
    __mmAnnounce &&
      __mmFriendAddedChatEnabled &&
      __mmSendChat("Added friend, " + __mmDisplay + "!"),
    __mmPublishHudState());
  return !0;
}
function __mmRemoveFriend(__mmName, __mmAnnounce) {
  const __mmKey = __mmNormalizeFriendName(__mmName),
    __mmDisplay =
      __mmFriendNames.get(__mmKey) || __mmFriendDisplayName(__mmName);
  if (!__mmKey || !__mmDisplay) return !1;
  if (__mmTeammateByFriendKey(__mmKey)) {
    __mmFriendPickNotice("Teammates cannot be marked as enemies");
    return !1;
  }
  (__mmFriendNames.delete(__mmKey),
    __mmFriendEnemies.add(__mmKey),
    delete __mmFriendAttackWindows[__mmKey],
    __mmDispatchFriendState("remove", __mmDisplay),
    __mmAnnounce &&
      __mmEnemyMarkedChatEnabled &&
      __mmSendChat(__mmDisplay + " is an enemy!"),
    __mmPublishHudState());
  return !0;
}
function __mmFriendPickNotice(__mmMessage) {
  window.dispatchEvent(
    new CustomEvent("MooMooFriendPickNotice", {
      detail: String(__mmMessage || ""),
    }),
  );
}
function __mmArmFriendPick(__mmMode) {
  if (!v || !v.alive) return !1;
  __mmSyncPickArmed = !1;
  const __mmNext =
    __mmMode === "friend" || __mmMode === "enemy" ? __mmMode : null;
  if (__mmFriendPickMode === __mmNext) {
    (__mmFriendPickMode = null,
      __mmFriendPickNotice("Player selection cancelled"));
    return !1;
  }
  __mmFriendPickMode = __mmNext;
  __mmFriendPickNotice(
    __mmNext === "friend"
      ? "Click a non-teammate to add friend"
      : "Click a non-teammate to mark enemy",
  );
  return !0;
}
function __mmPlayerAtFriendPick(__mmEvent) {
  if (!v || !v.alive || !Array.isArray(E) || !__mmEvent) return null;
  const __mmSurface =
      document.getElementById("gameCanvas") ||
      (__mmEvent.target instanceof Element
        ? __mmEvent.target.closest("#gameCanvas,#touch-controls-fullscreen")
        : null),
    __mmRect =
      __mmSurface && typeof __mmSurface.getBoundingClientRect === "function"
        ? __mmSurface.getBoundingClientRect()
        : null;
  if (!__mmRect || __mmRect.width <= 0 || __mmRect.height <= 0) return null;
  const __mmViewportWidth = Math.max(1, Number(_) || Number(De) || __mmRect.width),
    __mmViewportHeight = Math.max(1, Number(L) || Number(Ae) || __mmRect.height),
    __mmLeft = Number(oe) - __mmViewportWidth / 2,
    __mmTop = Number(ae) - __mmViewportHeight / 2;
  let __mmBest = null,
    __mmBestDistance = Infinity;
  for (let __mmIndex = 0; __mmIndex < E.length; __mmIndex++) {
    const __mmPlayer = E[__mmIndex];
    if (
      !__mmPlayer ||
      !__mmPlayer.alive ||
      !__mmPlayer.visible ||
      __mmPlayer === v ||
      String(__mmPlayer.sid) === String(v.sid)
    )
      continue;
    const __mmPlayerPositions = [
        { x: Number(__mmPlayer.x), y: Number(__mmPlayer.y) },
      ],
      __mmServerX = Number(__mmPlayer.x2),
      __mmServerY = Number(__mmPlayer.y2);
    if (
      __mmPlayer.x2 != null &&
      __mmPlayer.y2 != null &&
      Number.isFinite(__mmServerX) &&
      Number.isFinite(__mmServerY) &&
      (__mmServerX !== Number(__mmPlayer.x) ||
        __mmServerY !== Number(__mmPlayer.y))
    )
      __mmPlayerPositions.push({ x: __mmServerX, y: __mmServerY });
    let __mmDistance = Infinity;
    for (
      let __mmPositionIndex = 0;
      __mmPositionIndex < __mmPlayerPositions.length;
      __mmPositionIndex++
    ) {
      const __mmPosition = __mmPlayerPositions[__mmPositionIndex],
        __mmScreenX =
          __mmRect.left +
          ((__mmPosition.x - __mmLeft) / __mmViewportWidth) *
            __mmRect.width,
        __mmScreenY =
          __mmRect.top +
          ((__mmPosition.y - __mmTop) / __mmViewportHeight) *
            __mmRect.height;
      __mmDistance = Math.min(
        __mmDistance,
        Math.hypot(
          Number(__mmEvent.clientX) - __mmScreenX,
          Number(__mmEvent.clientY) - __mmScreenY,
        ),
      );
    }
    const __mmHitRadius = Math.max(
      30,
      ((Number(__mmPlayer.scale) || 35) / __mmViewportWidth) *
        __mmRect.width +
        24,
    );
    if (__mmDistance <= __mmHitRadius && __mmDistance < __mmBestDistance)
      ((__mmBest = __mmPlayer), (__mmBestDistance = __mmDistance));
  }
  return __mmBest;
}
document.addEventListener(
  "mousedown",
  function (__mmEvent) {
    if (!__mmFriendPickMode || !__mmIsGameClick(__mmEvent)) return;
    (__mmEvent.preventDefault(), __mmEvent.stopImmediatePropagation());
    __mmCleanupActive && __mmStopCleanup("friend selection click", !1);
    const __mmPlayer = __mmPlayerAtFriendPick(__mmEvent);
    if (!__mmPlayer) {
      __mmFriendPickNotice("No player there - click again");
      return;
    }
    const __mmMode = __mmFriendPickMode;
    if (__mmMode === "friend") {
      if (__mmSameTeam(__mmPlayer)) {
        __mmFriendPickNotice(
          "That player is already your teammate - click a non-teammate",
        );
        return;
      }
      __mmFriendPickMode = null;
      (__mmAddFriend(__mmPlayer.name, !0),
        __mmFriendPickNotice("Friend: " + __mmPlayer.name));
    } else {
      if (__mmSameTeam(__mmPlayer)) {
        __mmFriendPickNotice(
          "That player is your teammate - click a non-teammate",
        );
        return;
      }
      __mmFriendPickMode = null;
      (__mmRemoveFriend(__mmPlayer.name, !0),
        __mmFriendPickNotice("Enemy: " + __mmPlayer.name));
    }
  },
  !0,
);
function __mmSyncTargetLabel() {
  return __mmSyncTargetName ||
    (__mmSyncTargetSid == null ? "teammate" : "Player " + __mmSyncTargetSid);
}
function __mmClearSelectedSyncTarget(__mmMessage) {
  ((__mmSyncPickArmed = !1),
    (__mmSyncTargetSid = null),
    (__mmSyncTargetName = ""),
    (__mmSyncTargetExplicit = !1),
    (__mmSyncLeaderEnabled = !1),
    (__mmSyncFollowerEnabled = !1),
    (__mmSyncCombatOnlyEnabled = !1),
    (__mmSyncLeaderState = null),
    (__mmSyncStandLeaderKey = ""),
    (__mmSyncStandAngle = null),
    (__mmSyncArrivedBeside = !1),
    (__mmSyncDirectAttackAt = 0),
    (__mmSyncDirectAttackActive = !1),
    __mmCancelScheduledSyncInsta(),
    __mmStopObservedSyncAttack(!0),
    __mmSyncRestoreCatchupGear(),
    __mmSyncStopFollowMovement(),
    __mmStopTabSync(),
    __mmSetSyncStatus(__mmMessage || "Sync off"),
    __mmPublishHudState());
}
function __mmSelectSyncTarget(__mmPlayer) {
  if (!v || !v.alive || !__mmPlayer || !__mmPlayer.alive) return !1;
  if (!__mmSameTeam(__mmPlayer)) {
    __mmFriendPickNotice("Sync only works with a current teammate");
    return !1;
  }
  if (String(__mmPlayer.sid) === String(__mmSyncTargetSid)) {
    if (!__mmSyncFollowerEnabled || __mmSyncCombatOnlyEnabled) {
      ((__mmSyncPickArmed = !1),
        (__mmSyncTargetName = String(
          __mmPlayer.name || __mmSyncTargetName || "",
        ).trim().slice(0, 15)),
        (__mmSyncTargetExplicit = !0),
        (__mmSyncLeaderEnabled = !0),
        (__mmSyncFollowerEnabled = !0),
        (__mmSyncCombatOnlyEnabled = !1),
        (__mmSyncStandLeaderKey = ""),
        (__mmSyncStandAngle = null),
        (__mmSyncArrivedBeside = !1),
        (__mmSyncDirectAttackAt = 0),
        (__mmSyncDirectAttackActive = !1),
        (__mmSyncSelectionBlockedUntil = 0),
        __mmStopObservedSyncAttack(!0),
        __mmRefreshSelectedSyncTarget(),
        __mmStartTabSync(),
        __mmSetSyncStatus("Syncing… · " + __mmSyncTargetLabel()),
        __mmFriendPickNotice("Reconnected with " + __mmSyncTargetLabel()),
        __mmPublishHudState());
      return !0;
    }
    __mmClearSelectedSyncTarget("Sync disconnected");
    return !0;
  }
  ((__mmSyncPickArmed = !1),
    (__mmSyncTargetSid = __mmPlayer.sid),
    (__mmSyncTargetName = String(__mmPlayer.name || "").trim().slice(0, 15)),
    (__mmSyncTargetExplicit = !0),
    (__mmSyncLeaderEnabled = !0),
    (__mmSyncFollowerEnabled = !0),
    (__mmSyncCombatOnlyEnabled = !1),
    (__mmSyncLeaderState = null),
    (__mmSyncStandLeaderKey = ""),
    (__mmSyncStandAngle = null),
    (__mmSyncArrivedBeside = !1),
    (__mmSyncDirectAttackAt = 0),
    (__mmSyncDirectAttackActive = !1),
    __mmCancelScheduledSyncInsta(),
    __mmStopObservedSyncAttack(!0),
    __mmRefreshSelectedSyncTarget(),
    __mmStartTabSync(),
    __mmSetSyncStatus("Syncing… · " + __mmSyncTargetLabel()),
    __mmFriendPickNotice("Synced with " + __mmSyncTargetLabel()),
    __mmPublishHudState());
  return !0;
}
function __mmArmSyncPick() {
  if (!v || !v.alive) return !1;
  __mmFriendPickMode = null;
  if (__mmSyncPickArmed) {
    ((__mmSyncPickArmed = !1),
      __mmFriendPickNotice("Teammate sync selection cancelled"));
    return !1;
  }
  ((__mmSyncPickArmed = !0),
    __mmFriendPickNotice("Click a teammate to sync"));
  return !0;
}
document.addEventListener(
  "mousedown",
  function (__mmEvent) {
    if (!__mmSyncPickArmed || !__mmIsGameClick(__mmEvent)) return;
    (__mmEvent.preventDefault(), __mmEvent.stopImmediatePropagation());
    __mmCleanupActive && __mmStopCleanup("sync selection click", !1);
    const __mmPlayer = __mmPlayerAtFriendPick(__mmEvent);
    if (!__mmPlayer) {
      __mmFriendPickNotice("No player there - click again");
      return;
    }
    if (!__mmSameTeam(__mmPlayer)) {
      __mmFriendPickNotice("That player is not your teammate - click again");
      return;
    }
    __mmSelectSyncTarget(__mmPlayer);
  },
  !0,
);
window.addEventListener("blur", function () {
  ((__mmFriendPickMode = null), (__mmSyncPickArmed = !1));
});
function __mmReplaceFriends(__mmNames) {
  const __mmPrevious = Array.from(__mmFriendNames.keys()),
    __mmNext = new Map();
  if (Array.isArray(__mmNames)) {
    for (let __mmIndex = 0; __mmIndex < __mmNames.length; __mmIndex++) {
      const __mmDisplay = __mmFriendDisplayName(__mmNames[__mmIndex]),
        __mmKey = __mmNormalizeFriendName(__mmDisplay);
      __mmKey && !__mmNext.has(__mmKey) && __mmNext.set(__mmKey, __mmDisplay);
      if (__mmNext.size >= 30) break;
    }
  }
  __mmFriendNames.clear();
  __mmNext.forEach(function (__mmDisplay, __mmKey) {
    (__mmFriendNames.set(__mmKey, __mmDisplay),
      __mmFriendEnemies.delete(__mmKey));
  });
  for (let __mmIndex = 0; __mmIndex < __mmPrevious.length; __mmIndex++)
    __mmNext.has(__mmPrevious[__mmIndex]) ||
      __mmFriendEnemies.add(__mmPrevious[__mmIndex]);
}
function __mmFriendAttackAimedAtUs(__mmPlayer, __mmWeapon) {
  if (!v || !v.alive || !__mmPlayer || !__mmPlayer.alive) return !1;
  const __mmWeaponId =
      __mmWeapon == null ? __mmPlayer.weaponIndex : Number(__mmWeapon),
    __mmWeaponData = b.weapons && b.weapons[__mmWeaponId],
    __mmAttackAngle = Number(__mmPlayer.dir),
    __mmTargetAngle = Math.atan2(v.y - __mmPlayer.y, v.x - __mmPlayer.x),
    __mmAngleDifference = Math.abs(
      Math.atan2(
        Math.sin(__mmAttackAngle - __mmTargetAngle),
        Math.cos(__mmAttackAngle - __mmTargetAngle),
      ),
    ),
    __mmDistance = Math.hypot(v.x - __mmPlayer.x, v.y - __mmPlayer.y),
    __mmReach = __mmWeaponData
      ? __mmWeaponData.projectile != null
        ? 900
        : (Number(__mmWeaponData.range) || 0) +
          (Number(__mmPlayer.scale) || 35) +
          (Number(v.scale) || 35) +
          45
      : 220;
  return __mmAngleDifference <= 0.72 && __mmDistance <= __mmReach;
}
function __mmObserveFriendAttack(__mmPlayerSid, __mmDidHit, __mmWeapon) {
  const __mmPlayer = Rt(__mmPlayerSid);
  if (!__mmIsFriendPlayer(__mmPlayer)) return;
  const __mmKey = __mmNormalizeFriendName(__mmPlayer.name);
  if (!__mmFriendAttackAimedAtUs(__mmPlayer, __mmWeapon)) return;
  const __mmNow = Date.now(),
    __mmWeaponId =
      __mmWeapon == null ? Number(__mmPlayer.weaponIndex) : Number(__mmWeapon),
    __mmWindow =
      __mmFriendAttackWindows[__mmKey] ||
      (__mmFriendAttackWindows[__mmKey] = {
        lastAt: 0,
        lastWeapon: null,
        lastAimedAt: 0,
        damageStartedAt: 0,
        damage: 0,
      }),
    __mmRapidDistinct =
      __mmWindow.lastAt > 0 &&
      __mmNow - __mmWindow.lastAt <= Math.max(300, __mmServerTickMs() * 3) &&
      __mmWindow.lastWeapon != null &&
      __mmWindow.lastWeapon !== __mmWeaponId &&
      ([__mmShortSword, __mmKatana, __mmPolearmWeapon].includes(__mmWeaponId) ||
        [__mmShortSword, __mmKatana, __mmPolearmWeapon].includes(
          __mmWindow.lastWeapon,
        )),
    __mmInstaPrimary = [
      __mmShortSword,
      __mmKatana,
      __mmPolearmWeapon,
    ].includes(__mmWeaponId),
    __mmInstaGear =
      Number(__mmPlayer.skinIndex) === 7 ||
      Number(__mmPlayer.skinIndex) === __mmTurretGear;
  ((__mmWindow.lastAt = __mmNow),
    (__mmWindow.lastWeapon = __mmWeaponId),
    (__mmWindow.lastAimedAt = __mmNow));
  (__mmRapidDistinct || (__mmInstaPrimary && __mmInstaGear)) &&
    __mmRemoveFriend(__mmPlayer.name, !0);
}
function __mmObserveFriendDamage(__mmDamage) {
  if (!(Number(__mmDamage) > 0) || !v || !v.alive) return;
  const __mmNow = Date.now();
  let __mmBestKey = "",
    __mmBestAt = 0;
  __mmFriendNames.forEach(function (__mmDisplay, __mmKey) {
    const __mmWindow = __mmFriendAttackWindows[__mmKey];
    if (
      __mmWindow &&
      __mmNow - __mmWindow.lastAimedAt <= 850 &&
      __mmWindow.lastAimedAt > __mmBestAt
    )
      ((__mmBestKey = __mmKey), (__mmBestAt = __mmWindow.lastAimedAt));
  });
  if (!__mmBestKey) return;
  const __mmWindow = __mmFriendAttackWindows[__mmBestKey];
  if (
    !__mmWindow.damageStartedAt ||
    __mmNow - __mmWindow.damageStartedAt > 1200
  )
    ((__mmWindow.damageStartedAt = __mmNow), (__mmWindow.damage = 0));
  __mmWindow.damage += Number(__mmDamage);
  __mmWindow.damage > 20 &&
    __mmRemoveFriend(__mmFriendNames.get(__mmBestKey), !0);
}
function __mmSameTeam(__mmPlayer) {
  const __mmOwnTeam = __mmTeamKey(v),
    __mmOtherTeam = __mmTeamKey(__mmPlayer);
  return (
    __mmOwnTeam != null &&
    __mmOtherTeam != null &&
    __mmOwnTeam === __mmOtherTeam
  );
}
function __mmHandleTeamJoinRequest() {
  if (
    (!__mmAutoAcceptTeamRequestsEnabled &&
      !__mmAutoDeclineTeamRequestsEnabled) ||
    !document.body
  )
    return;
  const __mmHolder =
    document.getElementById("noticationDisplay") ||
    document.getElementById("notificationDisplay");
  if (!__mmHolder) return;
  const __mmButtons = Array.from(
    __mmHolder.querySelectorAll(".notifButton"),
  );
  if (__mmButtons.length < 2) return;
  const __mmAccept = __mmAutoAcceptTeamRequestsEnabled,
    __mmButtonPattern = __mmAccept
      ? /(?:8ecc51|e876|check|done|accept)/i
      : /(?:cc5151|e14c|close|clear|decline|reject)/i,
    // Prefer the native icon/color so this survives a button-order change.
    // Current MooMoo still uses Decline first and Accept second as fallback.
    __mmButton =
      __mmButtons.find(function (__mmCandidate) {
        return __mmButtonPattern.test(
          String(__mmCandidate.innerHTML || "") +
            " " +
            String(__mmCandidate.getAttribute("aria-label") || "") +
            " " +
            String(__mmCandidate.title || ""),
        );
      }) || __mmButtons[__mmAccept ? 1 : 0];
  if (
    !__mmButton ||
    __mmHandledTeamRequestButtons.has(__mmButton)
  )
    return;
  __mmHandledTeamRequestButtons.add(__mmButton);
  try {
    if (typeof __mmButton.onclick === "function") {
      // MooMoo's generateElement wraps onclick with checkTrusted(). A normal
      // element.click() produces isTrusted=false and is silently discarded.
      // Calling the already-installed native handler keeps its queue splice
      // and P packet intact; this proxy only satisfies that local UI guard.
      const __mmTrustedEvent = new Proxy(new Event("click"), {
        get: function (__mmTarget, __mmProperty) {
          if (__mmProperty === "isTrusted") return !0;
          const __mmValue = Reflect.get(
            __mmTarget,
            __mmProperty,
            __mmTarget,
          );
          return typeof __mmValue === "function"
            ? __mmValue.bind(__mmTarget)
            : __mmValue;
        },
      });
      __mmButton.onclick.call(__mmButton, __mmTrustedEvent);
    } else if (typeof __mmButton.click === "function") __mmButton.click();
    else throw new Error("team request button has no handler");
    // If a changed client rejected the handler, allow the interval to retry
    // instead of permanently blacklisting the still-visible request.
    setTimeout(function () {
      __mmButton.isConnected &&
        __mmHandledTeamRequestButtons.delete(__mmButton);
    }, 180);
  } catch (__mmTeamRequestClickError) {
    __mmHandledTeamRequestButtons.delete(__mmButton);
  }
}
function __mmStartTeamRequestAutomation() {
  if (__mmTeamRequestObserver || !document.documentElement) return;
  __mmTeamRequestObserver = new MutationObserver(__mmHandleTeamJoinRequest);
  __mmTeamRequestObserver.observe(document.documentElement, {
    childList: !0,
    subtree: !0,
    attributes: !0,
    attributeFilter: ["style"],
  });
  __mmTeamRequestTimer = setInterval(
    __mmHandleTeamJoinRequest,
    __mmFastCheckMs(),
  );
  __mmHandleTeamJoinRequest();
}
function __mmIsEnemyPlayer(__mmPlayer) {
  const __mmFriendKey = __mmNormalizeFriendName(
      __mmPlayer && __mmPlayer.name,
    ),
    __mmBetrayedFriend =
      !!__mmFriendKey && __mmFriendEnemies.has(__mmFriendKey);
  if (
    !__mmPlayer ||
    !__mmPlayer.alive ||
    !__mmPlayer.visible ||
    (Number.isFinite(Number(__mmPlayer.health)) &&
      Number(__mmPlayer.health) <= 0) ||
    !v ||
    !v.alive ||
    __mmPlayer === v ||
    __mmPlayer.sid === v.sid
  )
    return !1;
  // Team membership has absolute precedence over saved friend/enemy state.
  if (__mmSameTeam(__mmPlayer)) return !1;
  if (!__mmBetrayedFriend && __mmIsFriendPlayer(__mmPlayer)) return !1;
  const __mmOwnTeam = __mmTeamKey(v),
    __mmOtherTeam = __mmTeamKey(__mmPlayer);
  if (__mmOwnTeam != null && __mmOtherTeam == null) {
    const __mmSid = String(__mmPlayer.sid),
      __mmNow = Date.now(),
      __mmSeen =
        __mmUnknownTeamSeen[__mmSid] ||
        (__mmUnknownTeamSeen[__mmSid] = __mmNow);
    return __mmNow - __mmSeen >= __mmUnknownTeamGraceMs;
  }
  return !0;
}
function __mmSyncOwnTeamKey() {
  const __mmKey = __mmTeamKey(v);
  return __mmKey == null ? "" : String(__mmKey);
}
function __mmSelectedSyncTargetPlayer() {
  if (__mmSyncTargetSid == null || !v || !v.alive) return null;
  let __mmPlayer = null;
  try {
    __mmPlayer = Rt(__mmSyncTargetSid);
  } catch (__mmSyncTargetLookupError) {}
  return __mmPlayer &&
    __mmPlayer.alive &&
    __mmPlayer.visible &&
    __mmSameTeam(__mmPlayer)
    ? __mmPlayer
    : null;
}
function __mmApplyVisibleSyncTargetState(__mmPlayer) {
  if (!__mmSyncFollowerEnabled || !v || !v.alive || !__mmPlayer) return;
  const __mmBuild = Number(__mmPlayer.buildIndex),
    __mmWeapon = Number(__mmPlayer.weaponIndex),
    __mmHat = Number(__mmPlayer.skinIndex),
    __mmTail = Number(__mmPlayer.tailIndex);
  if (
    __mmSyncCopyBuildsEnabled &&
    Number.isInteger(__mmBuild) &&
    __mmBuild >= 0 &&
    __mmSyncOwnsSelection(__mmBuild, !1) &&
    Number(v.buildIndex) !== __mmBuild
  )
    je(__mmBuild);
  else if (
    __mmSyncCopyWeaponsEnabled &&
    (!Number.isInteger(__mmBuild) || __mmBuild < 0) &&
    Number.isInteger(__mmWeapon) &&
    __mmSyncOwnsSelection(__mmWeapon, !0) &&
    (Number(v.buildIndex) >= 0 || Number(v.weaponIndex) !== __mmWeapon)
  )
    je(__mmWeapon, !0);
  if (!__mmSyncCopyGearEnabled) return;
  if (__mmSyncCatchupActive) {
    (__mmCanEquipHat(__mmHat) || __mmHat === 0) &&
      (__mmSyncCatchupPreviousHat = __mmHat);
    ((v.tails && v.tails[__mmTail]) || __mmTail === 0) &&
      (__mmSyncCatchupPreviousTail = __mmTail);
    return;
  }
  ((__mmCanEquipHat(__mmHat) || __mmHat === 0) &&
      Number(v.skinIndex) !== __mmHat &&
      __mmEquipHatNow(__mmHat),
    ((v.tails && v.tails[__mmTail]) || __mmTail === 0) &&
      Number(v.tailIndex) !== __mmTail &&
      __mmEquipTailNow(__mmTail));
}
function __mmRefreshSelectedSyncTarget() {
  if (__mmSyncTargetSid == null || !v || !v.alive) return null;
  const __mmPlayer = __mmSelectedSyncTargetPlayer(),
    __mmNow = Date.now(),
    __mmPrevious = __mmSyncLeaderState,
    __mmNetworkFresh = !!(
      __mmPrevious &&
      __mmPrevious.kittyPeer &&
      String(__mmPrevious.leaderSid) === String(__mmSyncTargetSid) &&
      __mmNow - Number(__mmPrevious.networkReceivedAt || 0) <= 2500
    );
  if (!__mmPlayer) {
    if (!__mmNetworkFresh)
      __mmSetSyncStatus(
        "Syncing… · " + __mmSyncTargetLabel() + " is out of view",
      );
    return null;
  }
  const __mmDirection = Number(__mmPlayer.dir),
    __mmVelocity = __mmSyncPlayerVelocity(__mmPlayer),
    __mmAimDistance = 1800;
  __mmSyncTargetName = String(
    __mmPlayer.name || __mmSyncTargetName || "",
  ).trim().slice(0, 15);
  __mmSyncLeaderState = {
    ...(__mmNetworkFresh ? __mmPrevious : {}),
    type: "state",
    sender: __mmNetworkFresh
      ? __mmPrevious.sender
      : "visible:" + __mmSyncTargetSid,
    leaderSid: __mmSyncTargetSid,
    x: Number(__mmPlayer.x),
    y: Number(__mmPlayer.y),
    scale: Number(__mmPlayer.scale) || 35,
    vx: __mmVelocity.x,
    vy: __mmVelocity.y,
    weapon: Number(__mmPlayer.weaponIndex),
    build: Number(__mmPlayer.buildIndex),
    hat: Number(__mmPlayer.skinIndex),
    tail: Number(__mmPlayer.tailIndex),
    aimX:
      __mmNetworkFresh && Number.isFinite(Number(__mmPrevious.aimX))
        ? Number(__mmPrevious.aimX)
        : Number(__mmPlayer.x) +
          Math.cos(Number.isFinite(__mmDirection) ? __mmDirection : 0) *
            __mmAimDistance,
    aimY:
      __mmNetworkFresh && Number.isFinite(Number(__mmPrevious.aimY))
        ? Number(__mmPrevious.aimY)
        : Number(__mmPlayer.y) +
          Math.sin(Number.isFinite(__mmDirection) ? __mmDirection : 0) *
            __mmAimDistance,
    receivedAt: __mmNow,
    kittyPeer: __mmNetworkFresh,
    networkReceivedAt: __mmNetworkFresh
      ? __mmPrevious.networkReceivedAt
      : 0,
  };
  __mmWithSyncReplay(function () {
    __mmApplyVisibleSyncTargetState(__mmPlayer);
  });
  return __mmPlayer;
}
function __mmSyncSafeRelayUrl(__mmValue) {
  const __mmRaw = String(__mmValue || "").trim().slice(0, 200);
  if (!__mmRaw) return "";
  try {
    const __mmUrl = new URL(__mmRaw);
    if (__mmUrl.protocol === "wss:") return __mmUrl.href;
    if (
      __mmUrl.protocol === "ws:" &&
      (__mmUrl.hostname === "127.0.0.1" ||
        __mmUrl.hostname === "localhost" ||
        __mmUrl.hostname === "[::1]")
    )
      return __mmUrl.href;
  } catch (__mmRelayUrlError) {}
  return "";
}
function __mmSyncHash(__mmValue) {
  let __mmHash = 2166136261;
  const __mmText = String(__mmValue || "");
  for (let __mmIndex = 0; __mmIndex < __mmText.length; __mmIndex++) {
    (__mmHash ^= __mmText.charCodeAt(__mmIndex),
      (__mmHash = Math.imul(__mmHash, 16777619)));
  }
  return (__mmHash >>> 0).toString(36);
}
function __mmSyncCurrentRelayRoom() {
  const __mmTeam = __mmSyncOwnTeamKey(),
    __mmPhrase = String(__mmSyncRoom || "").trim();
  return __mmTeam && __mmPhrase.length >= 4
    ? "kitty-" +
        __mmSyncHash(
          location.hostname + "|" + __mmTeam + "|" + __mmPhrase,
        )
    : "";
}
function __mmSyncRelayWanted() {
  return !!(
    v &&
    v.alive &&
    __mmSyncSafeRelayUrl(__mmSyncRelayUrl) &&
    __mmSyncCurrentRelayRoom()
  );
}
function __mmSyncRelayConnected() {
  return !!(
    __mmSyncRelaySocket &&
    __mmSyncRelaySocket.readyState === WebSocket.OPEN &&
    __mmSyncRelayRoomKey === __mmSyncCurrentRelayRoom()
  );
}
function __mmSyncServerNow() {
  return Date.now() + __mmSyncRelayClockOffset;
}
function __mmCloseSyncRelay(__mmReconnect) {
  (__mmSyncRelayReconnectTimer && clearTimeout(__mmSyncRelayReconnectTimer),
    (__mmSyncRelayReconnectTimer = 0),
    __mmSyncRelayPingTimer && clearInterval(__mmSyncRelayPingTimer),
    (__mmSyncRelayPingTimer = 0));
  const __mmSocket = __mmSyncRelaySocket;
  __mmSyncRelaySocket = null;
  __mmSyncRelayRoomKey = "";
  if (__mmSocket)
    try {
      ((__mmSocket.onopen = null),
        (__mmSocket.onmessage = null),
        (__mmSocket.onerror = null),
        (__mmSocket.onclose = null),
        __mmSocket.readyState < WebSocket.CLOSING && __mmSocket.close(1000));
    } catch (__mmRelayCloseError) {}
  if (__mmReconnect && __mmSyncRelayWanted())
    __mmSyncRelayReconnectTimer = setTimeout(__mmConnectSyncRelay, 900);
}
function __mmSyncRelayPing() {
  if (!__mmSyncRelayConnected()) return;
  try {
    __mmSyncRelaySocket.send(
      JSON.stringify({ type: "ping", clientAt: Date.now() }),
    );
  } catch (__mmRelayPingError) {}
}
function __mmHandleSyncRelayMessage(__mmRaw) {
  let __mmEnvelope = null;
  try {
    __mmEnvelope = JSON.parse(String(__mmRaw || ""));
  } catch (__mmRelayParseError) {
    return;
  }
  if (!__mmEnvelope || typeof __mmEnvelope !== "object") return;
  if (__mmEnvelope.type === "joined") {
    const __mmServerAt = Number(__mmEnvelope.serverAt);
    Number.isFinite(__mmServerAt) &&
      (__mmSyncRelayClockOffset = __mmServerAt - Date.now());
    (__mmSetSyncStatus(
      __mmSyncTargetSid == null
        ? "Sync off"
        : "Synced · " + __mmSyncTargetLabel() + " · relay ready",
    ),
      __mmSyncRelayPing());
    return;
  }
  if (__mmEnvelope.type === "pong") {
    const __mmClientAt = Number(__mmEnvelope.clientAt),
      __mmServerAt = Number(__mmEnvelope.serverAt),
      __mmNow = Date.now();
    if (Number.isFinite(__mmClientAt) && Number.isFinite(__mmServerAt)) {
      const __mmRtt = Math.max(0, __mmNow - __mmClientAt);
      ((__mmSyncRelayRtt = __mmSyncRelayRtt
        ? __mmSyncRelayRtt * 0.7 + __mmRtt * 0.3
        : __mmRtt),
        (__mmSyncRelayClockOffset =
          __mmSyncRelayClockOffset * 0.7 +
          (__mmServerAt - (__mmClientAt + __mmNow) / 2) * 0.3));
    }
    return;
  }
  if (
    __mmEnvelope.type !== "event" ||
    __mmEnvelope.room !== __mmSyncRelayRoomKey ||
    String(__mmEnvelope.teamKey || "") !== __mmSyncOwnTeamKey() ||
    !__mmEnvelope.payload ||
    typeof __mmEnvelope.payload !== "object"
  )
    return;
  __mmSyncHandleMessage({ data: __mmEnvelope.payload, relay: !0 });
}
function __mmConnectSyncRelay() {
  if (!__mmSyncRelayWanted()) return void __mmCloseSyncRelay(!1);
  const __mmUrl = __mmSyncSafeRelayUrl(__mmSyncRelayUrl),
    __mmRoom = __mmSyncCurrentRelayRoom(),
    __mmNow = Date.now();
  if (
    __mmSyncRelaySocket &&
    __mmSyncRelaySocket._kittyUrl === __mmUrl &&
    __mmSyncRelayRoomKey === __mmRoom &&
    __mmSyncRelaySocket.readyState <= WebSocket.OPEN
  )
    return;
  if (__mmNow - __mmSyncRelayAttemptAt < 700) return;
  (__mmCloseSyncRelay(!1),
    (__mmSyncRelayAttemptAt = __mmNow),
    (__mmSyncRelayRoomKey = __mmRoom));
  let __mmSocket = null;
  try {
    __mmSocket = new WebSocket(__mmUrl);
  } catch (__mmRelayConnectError) {
    (__mmSetSyncStatus("Sync failed · relay URL blocked"),
      __mmCloseSyncRelay(!0));
    return;
  }
  ((__mmSyncRelaySocket = __mmSocket),
    (__mmSocket._kittyUrl = __mmUrl),
    __mmSetSyncStatus("Syncing… · connecting relay"));
  __mmSocket.onopen = function () {
    if (__mmSyncRelaySocket !== __mmSocket) return;
    try {
      __mmSocket.send(
        JSON.stringify({
          type: "join",
          protocol: "kitty-klient-team-sync-v1",
          room: __mmRoom,
          teamKey: __mmSyncOwnTeamKey(),
          clientId: __mmSyncTabId,
        }),
      );
      (__mmSyncRelayPingTimer && clearInterval(__mmSyncRelayPingTimer),
        (__mmSyncRelayPingTimer = setInterval(__mmSyncRelayPing, 5000)));
    } catch (__mmRelayJoinError) {
      __mmCloseSyncRelay(!0);
    }
  };
  __mmSocket.onmessage = function (__mmEvent) {
    __mmSyncRelaySocket === __mmSocket &&
      __mmHandleSyncRelayMessage(__mmEvent.data);
  };
  __mmSocket.onerror = function () {
    __mmSyncRelaySocket === __mmSocket &&
      __mmSetSyncStatus("Sync error · relay unavailable");
  };
  __mmSocket.onclose = function () {
    if (__mmSyncRelaySocket !== __mmSocket) return;
    (__mmSyncFollowerEnabled &&
      (__mmSyncRestoreCatchupGear(), __mmSyncStopFollowMovement()),
      __mmCloseSyncRelay(!1),
      __mmSyncRelayWanted() && __mmSetSyncStatus("Reconnecting…"),
      __mmSyncRelayWanted() &&
        (__mmSyncRelayReconnectTimer = setTimeout(
          __mmConnectSyncRelay,
          1200,
        )));
  };
}
function __mmSyncRelaySend(__mmPacket) {
  if (!__mmSyncRelayConnected()) return !1;
  try {
    const __mmPayload = JSON.stringify({
      type: "publish",
      room: __mmSyncRelayRoomKey,
      teamKey: __mmSyncOwnTeamKey(),
      payload: __mmPacket,
    });
    if (__mmPayload.length > 1800) return !1;
    (__mmSyncRelaySocket.send(__mmPayload), (__mmMetricPackets += 1));
    return !0;
  } catch (__mmRelaySendError) {
    __mmCloseSyncRelay(!0);
    return !1;
  }
}
function __mmSetSyncRelayConfig(__mmKey, __mmValue) {
  if (__mmKey === "syncRelayUrl")
    __mmSyncRelayUrl = String(__mmValue || "").trim().slice(0, 200);
  else if (__mmKey === "syncRoom")
    __mmSyncRoom = String(__mmValue || "").trim().slice(0, 64);
  else return;
  (__mmCloseSyncRelay(!1),
    (__mmSyncRelayClockOffset = 0),
    (__mmSyncRelayRtt = 0),
    __mmStartTabSync(),
    __mmPublishHudState());
}
function __mmWithSyncReplay(__mmCallback) {
  __mmSyncReplayDepth += 1;
  try {
    return __mmCallback();
  } finally {
    __mmSyncReplayDepth = Math.max(0, __mmSyncReplayDepth - 1);
  }
}
function __mmStopObservedSyncAttack(__mmRelease = !0) {
  (__mmSyncObservedAttackReleaseTimer &&
    clearTimeout(__mmSyncObservedAttackReleaseTimer),
    (__mmSyncObservedAttackReleaseTimer = 0));
  if (!__mmSyncObservedAttackHeld) return;
  __mmSyncObservedAttackHeld = !1;
  __mmRelease &&
    v &&
    v.alive &&
    __mmWithSyncReplay(function () {
      O.send("F", 0, Ci());
    });
}
function __mmSyncObservedPlayerSwing(__mmPlayerSid, __mmWeapon) {
  if (
    !__mmSyncCopyAttacksEnabled ||
    (!__mmSyncFollowerEnabled && !__mmSyncCombatOnlyEnabled) ||
    !v ||
    !v.alive ||
    __mmSyncTargetSid == null ||
    String(__mmPlayerSid) !== String(__mmSyncTargetSid)
  )
    return;
  const __mmNow = Date.now();
  if (__mmSyncDirectAttackActive) {
    if (__mmNow - __mmSyncDirectAttackAt < 1200) return;
    __mmSyncDirectAttackActive = !1;
  }
  if (
    __mmNow - __mmSyncDirectAttackAt <
    Math.max(650, __mmServerTickMs() * 6)
  )
    return;
  let __mmPlayer = null;
  try {
    __mmPlayer = Rt(__mmPlayerSid);
  } catch (__mmObservedSyncPlayerError) {}
  if (!__mmPlayer || !__mmPlayer.alive || !__mmSameTeam(__mmPlayer)) return;
  const __mmRemoteWeapon = Number.isInteger(Number(__mmWeapon))
      ? Number(__mmWeapon)
      : Number(__mmPlayer.weaponIndex),
    __mmWeaponId = __mmSyncCombatWeapon(
      __mmRemoteWeapon,
      __mmPlayer,
      __mmPlayerWeaponSlot(__mmPlayer, __mmRemoteWeapon),
    ),
    __mmDirection = Number(__mmPlayer.dir),
    __mmAngle = Number.isFinite(__mmDirection) ? __mmDirection : Ci();
  if (__mmWeaponId == null) return;
  __mmStopObservedSyncAttack(!0);
  __mmWithSyncReplay(function () {
    if (
      Number(v.buildIndex) >= 0 ||
      Number(v.weaponIndex) !== __mmWeaponId
    )
      je(__mmWeaponId, !0);
    (O.send("D", __mmAngle), O.send("F", 1, __mmAngle));
  });
  (__mmSyncObservedAttackHeld = !0),
    (__mmSyncObservedAttackReleaseTimer = setTimeout(function () {
      (__mmSyncObservedAttackReleaseTimer = 0),
        __mmStopObservedSyncAttack(!0);
    }, Math.max(1, __mmServerTickMs())));
}
function __mmSyncPost(__mmMessage) {
  const __mmTeamKey = __mmSyncOwnTeamKey();
  if (
    __mmSyncReplayDepth > 0 ||
    !__mmSyncLeaderEnabled ||
    !v ||
    !v.alive ||
    !__mmTeamKey
  )
    return;
  const __mmPacket = {
    ...__mmMessage,
    sender: __mmSyncTabId,
    packetId: __mmSyncTabId + ":" + (++__mmSyncSequence),
    leaderSid: v.sid,
    teamKey: __mmTeamKey,
    sentAt: Date.now(),
  };
  try {
    __mmSyncChannel && __mmSyncChannel.postMessage(__mmPacket);
  } catch (__mmSyncPostError) {}
  try {
    window.dispatchEvent(
      new CustomEvent("MooMooTabSyncOutbound", {
        detail: JSON.stringify(__mmPacket),
      }),
    );
  } catch (__mmSyncBridgeError) {}
  try {
    window.dispatchEvent(
      new CustomEvent("MooMooKittySyncOutbound", {
        detail: {
          protocol: __mmOpenSyncProtocol,
          client: "kitty-klient",
          clientVersion: "${KITTY_KLIENT_VERSION}",
          packet: { ...__mmPacket },
        },
      }),
    );
  } catch (__mmOpenSyncOutboundError) {}
  __mmSyncRelaySend(__mmPacket);
}
function __mmSyncStatusChatPump() {
  if (
    !__mmSyncStatusChatEnabled ||
    !__mmSyncStatusChatQueue.length ||
    !v ||
    !v.alive
  ) {
    (__mmSyncStatusChatTimer && clearTimeout(__mmSyncStatusChatTimer),
      (__mmSyncStatusChatTimer = 0));
    return;
  }
  const __mmNow = Date.now(),
    __mmCooldown = Math.max(
      550,
      (Number(y && y.chatCooldown) || 500) + 60,
    ),
    __mmDelay = Math.max(
      0,
      __mmSyncStatusChatLastAt + __mmCooldown - __mmNow,
    );
  if (__mmDelay > 0) {
    __mmSyncStatusChatTimer && clearTimeout(__mmSyncStatusChatTimer);
    __mmSyncStatusChatTimer = setTimeout(function () {
      ((__mmSyncStatusChatTimer = 0), __mmSyncStatusChatPump());
    }, __mmDelay);
    return;
  }
  const __mmMessage = __mmSyncStatusChatQueue.shift();
  ((__mmSyncStatusChatLastAt = __mmNow), __mmSendChat(__mmMessage));
  if (__mmSyncStatusChatQueue.length)
    __mmSyncStatusChatTimer = setTimeout(function () {
      ((__mmSyncStatusChatTimer = 0), __mmSyncStatusChatPump());
    }, __mmCooldown);
}
function __mmQueueSyncStatusChat(__mmStatus) {
  const __mmText = String(__mmStatus || ""),
    __mmPhase = /^(?:Syncing|Reconnecting)/i.test(__mmText)
      ? "syncing"
      : /^Synced\b/i.test(__mmText)
        ? "synced"
        : /(?:disconnected|Sync off|stopped)/i.test(__mmText)
          ? "off"
          : null;
  if (!__mmPhase || __mmPhase === __mmSyncStatusChatPhase) return;
  __mmSyncStatusChatPhase = __mmPhase;
  if (!__mmSyncStatusChatEnabled) return;
  const __mmMessage =
    __mmPhase === "syncing"
      ? "Syncing..."
      : __mmPhase === "synced"
        ? "Synced!"
        : "Sync stopped.";
  __mmSyncStatusChatQueue[__mmSyncStatusChatQueue.length - 1] !== __mmMessage &&
    __mmSyncStatusChatQueue.push(__mmMessage);
  __mmSyncStatusChatQueue.length > 3 && __mmSyncStatusChatQueue.shift();
  __mmSyncStatusChatPump();
}
function __mmSetSyncStatus(__mmStatus) {
  if (__mmSyncStatus === __mmStatus) return;
  ((__mmSyncStatus = __mmStatus),
    __mmQueueSyncStatusChat(__mmStatus),
    window.dispatchEvent(
      new CustomEvent("MooMooScrollZoomStatus", {
        detail: __mmStatus,
      }),
    ),
    __mmPublishHudState());
}
function __mmSyncBroadcastState() {
  if (!__mmSyncLeaderEnabled || !v || !v.alive) return;
  const __mmAim = Ci(),
    __mmVelocity = __mmSyncPlayerVelocity(v),
    __mmAimDistance = 1800,
    __mmState = {
    type: "state",
    x: v.x,
    y: v.y,
    scale: Number(v.scale) || 35,
    vx: __mmVelocity.x,
    vy: __mmVelocity.y,
    weapon: Number(v.weaponIndex),
    weapons: Array.isArray(v.weapons) ? v.weapons.slice(0, 2) : [],
    build: Number(v.buildIndex),
    hat: Number(v.skinIndex),
    tail: Number(v.tailIndex),
    combat: __mmSyncLocalCombatActive(),
    aimX: v.x + Math.cos(__mmAim) * __mmAimDistance,
    aimY: v.y + Math.sin(__mmAim) * __mmAimDistance,
  };
  (__mmSyncPost(__mmState),
    // BroadcastChannel is the fast path. This small storage-event fallback
    // still lets a second same-origin tab acquire the leader when a browser
    // has isolated the injected bundle's BroadcastChannel context.
    (() => {
      try {
        localStorage.setItem(
          __mmSyncStorageKey,
          JSON.stringify({
            ...__mmState,
            sender: __mmSyncTabId,
            packetId: __mmSyncTabId + ":" + (++__mmSyncSequence),
            leaderSid: v.sid,
            teamKey: __mmSyncOwnTeamKey(),
            sentAt: Date.now(),
          }),
        );
      } catch (__mmSyncStorageWriteError) {}
    })());
}
function __mmSyncLeaderPlayer(__mmMessage) {
  const __mmState = __mmSyncLeaderState;
  if (
    (!__mmSyncFollowerEnabled && !__mmSyncCombatOnlyEnabled) ||
    !v ||
    !v.alive
  )
    return null;
  // An atomic combat packet can beat the next periodic state packet. If the
  // explicitly selected teammate is already visible, accept that live player
  // immediately instead of dropping the first synced swing.
  if (
    __mmMessage &&
    __mmMessage.leaderSid != null &&
    String(__mmMessage.leaderSid) === String(__mmSyncTargetSid)
  ) {
    let __mmDirectLeader = null;
    try {
      __mmDirectLeader = Rt(__mmMessage.leaderSid);
    } catch (__mmDirectSyncLeaderError) {}
    if (
      __mmDirectLeader &&
      __mmDirectLeader.alive &&
      __mmDirectLeader !== v &&
      __mmSameTeam(__mmDirectLeader)
    )
      return __mmDirectLeader;
  }
  if (
    !__mmState ||
    Date.now() - __mmState.receivedAt > 2500 ||
    (__mmMessage &&
      (__mmMessage.sender !== __mmState.sender ||
        String(__mmMessage.leaderSid) !== String(__mmState.leaderSid)))
  )
    return null;
  const __mmLeader = Rt(__mmState.leaderSid);
  if (
    __mmLeader &&
    __mmLeader.alive &&
    __mmLeader !== v &&
    String(__mmLeader.sid) === String(__mmState.leaderSid)
  )
    return __mmLeader;
  // The player list only includes players the local client currently knows
  // about. Keep following the explicitly enabled local leader while they are
  // off-screen, then switch to their authoritative in-match position as soon
  // as the follower can see them.
  return Number.isFinite(Number(__mmState.x)) &&
    Number.isFinite(Number(__mmState.y))
    ? __mmState
    : null;
}
function __mmSyncStopFollowMovement() {
  ((__mmSyncLastMoveDirection = null), (__mmSyncLastMoveAt = 0));
  if (!__mmSyncMoveActive) return;
  ((__mmSyncMoveActive = !1), (Kt = null), Tt());
}
function __mmSyncMovementStateFresh() {
  if (!__mmSyncLeaderState) return !1;
  const __mmFreshFor = Math.max(
    550,
    Math.min(1200, Number(__mmSyncRelayRtt || 0) * 3 + 300),
  );
  return Date.now() - Number(__mmSyncLeaderState.receivedAt || 0) <= __mmFreshFor;
}
function __mmSyncLocalCombatActive() {
  return !!(
    __mmInsta.isActive() ||
    __mmSyncScheduledInstaTimer ||
    __mmPrimaryHeld ||
    __mmSecondaryHeld ||
    __mmTrapAttackActive ||
    __mmBoostBreakHeld ||
    __mmEnemyWithinCombatRange() ||
    (__mmActionOwner !== "idle" && __mmActionPriority(__mmActionOwner) >= 60)
  );
}
function __mmSyncCombatActive() {
  return !!(
    __mmSyncLocalCombatActive() ||
    Date.now() < __mmSyncLeaderCombatUntil ||
    (__mmSyncFollowerEnabled &&
      __mmSyncMovementStateFresh() &&
      __mmSyncLeaderState &&
      __mmSyncLeaderState.combat)
  );
}
function __mmSyncRestoreCatchupGear() {
  if (!__mmSyncCatchupActive) return;
  const __mmHat = __mmSyncCatchupPreviousHat,
    __mmTail = __mmSyncCatchupPreviousTail;
  ((__mmSyncCatchupActive = !1),
    (__mmSyncCatchupPreviousHat = null),
    (__mmSyncCatchupPreviousTail = null));
  v && v.alive && __mmEquipGearPair(__mmHat, __mmTail, !0);
}
function __mmSyncUseCatchupGear() {
  if (
    !__mmSyncCatchupGearEnabled ||
    !v ||
    !v.alive ||
    __mmSyncCombatActive()
  )
    return void __mmSyncRestoreCatchupGear();
  const __mmPreferredHat = __mmSpeedHat(),
    __mmHat =
      v.skins && v.skins[__mmPreferredHat]
        ? __mmPreferredHat
        : v.skins && v.skins[__mmBoosterHat]
          ? __mmBoosterHat
          : null,
    __mmTail =
      !__mmHasStick() && v.tails && v.tails[11] ? 11 : null;
  if (__mmHat == null && __mmTail == null) return;
  if (!__mmSyncCatchupActive) {
    ((__mmSyncCatchupActive = !0),
      (__mmSyncCatchupPreviousHat = __mmBaseAutomationHat()),
      (__mmSyncCatchupPreviousTail = __mmBushRestoreTail(v.tailIndex)),
      __mmPauseSoldierForBreaking());
  }
  __mmEquipGearPair(
    __mmHat == null ? v.skinIndex : __mmHat,
    __mmTail == null ? v.tailIndex : __mmTail,
  );
}
function __mmSyncStandBesideAngle() {
  const __mmState = __mmSyncLeaderState;
  if (!__mmState || !v) return 0;
  const __mmLeaderKey = String(__mmState.leaderSid),
    __mmAimX = Number(__mmState.aimX),
    __mmAimY = Number(__mmState.aimY),
    __mmLeaderX = Number(__mmState.x),
    __mmLeaderY = Number(__mmState.y);
  if (
    __mmSyncStandLeaderKey !== __mmLeaderKey ||
    !Number.isFinite(__mmSyncStandAngle)
  ) {
    const __mmAimAngle =
        Number.isFinite(__mmAimX) &&
        Number.isFinite(__mmAimY) &&
        Number.isFinite(__mmLeaderX) &&
        Number.isFinite(__mmLeaderY)
          ? Math.atan2(__mmAimY - __mmLeaderY, __mmAimX - __mmLeaderX)
          : 0,
      __mmSideSeed = parseInt(
        __mmSyncHash(String(v.sid) + ":" + __mmLeaderKey),
        36,
      ),
      __mmSide = Number.isFinite(__mmSideSeed) && __mmSideSeed % 2 ? 1 : -1;
    ((__mmSyncStandLeaderKey = __mmLeaderKey),
      (__mmSyncStandAngle = __mmAimAngle + __mmSide * Math.PI / 2));
  }
  return __mmSyncStandAngle;
}
function __mmSyncApplyMoveDirection(__mmDirection) {
  if (!Number.isFinite(__mmDirection) || !v || !v.alive) return !1;
  const __mmNow = Date.now(),
    __mmDirectionDifference = Number.isFinite(__mmSyncLastMoveDirection)
      ? Math.abs(
          Math.atan2(
            Math.sin(__mmDirection - __mmSyncLastMoveDirection),
            Math.cos(__mmDirection - __mmSyncLastMoveDirection),
          ),
        )
      : Infinity;
  if (
    !__mmSyncMoveActive ||
    __mmDirectionDifference >= 0.012 ||
    __mmNow - __mmSyncLastMoveAt >= __mmSyncMoveRefreshMs
  )
    (O.send("9", __mmDirection),
      (__mmSyncLastMoveDirection = __mmDirection),
      (__mmSyncLastMoveAt = __mmNow));
  ((Kt = __mmDirection), (__mmSyncMoveActive = !0));
  return !0;
}
function __mmSyncFollowTick() {
  if (
    !__mmSyncFollowerEnabled ||
    !__mmSyncMovementEnabled ||
    !v ||
    !v.alive
  )
    return (__mmSyncRestoreCatchupGear(), void __mmSyncStopFollowMovement());
  if (!__mmSyncMovementStateFresh())
    return (
      __mmSetSyncStatus(
        "Syncing… · waiting for " + __mmSyncTargetLabel(),
      ),
      __mmSyncRestoreCatchupGear(),
      void __mmSyncStopFollowMovement()
    );
  const __mmLeader = __mmSyncLeaderPlayer();
  if (!__mmLeader)
    return (
      __mmSetSyncStatus(
        "Syncing… · waiting for " + __mmSyncTargetLabel(),
      ),
      __mmSyncRestoreCatchupGear(),
      void __mmSyncStopFollowMovement()
    );
  // Pick one deterministic side when this teammate is acquired and keep it.
  // Predict only a short distance ahead so the follower reacts with the
  // leader instead of visibly trailing or orbiting around old positions.
  const __mmStandAngle = __mmSyncStandBesideAngle(),
    __mmHitboxDistance =
      (Number(v.scale) || 35) +
      (Number(__mmLeader.scale) || 35),
    // Target an extra tolerance outside the requested edge gap. Even if the
    // arrival test stops at its closest legal edge, the configured hitbox gap
    // remains intact rather than being consumed by the stop tolerance.
    __mmStandDistance =
      __mmHitboxDistance + __mmSyncFollowGap + __mmSyncStopTolerance,
    __mmMeasuredVelocity = __mmSyncPlayerVelocity(__mmLeader),
    __mmVelocityX = Number.isFinite(Number(__mmLeader.vx))
      ? Number(__mmLeader.vx)
      : __mmMeasuredVelocity.x,
    __mmVelocityY = Number.isFinite(Number(__mmLeader.vy))
      ? Number(__mmLeader.vy)
      : __mmMeasuredVelocity.y,
    __mmStateAge = Math.max(
      0,
      Date.now() - Number(__mmSyncLeaderState.receivedAt || Date.now()),
    ),
    __mmPredictionMs = Math.min(
      __mmSyncPredictionMs,
      __mmStateAge +
        Math.max(8, __mmFastCheckMs()) +
        Math.min(45, Math.max(0, Number(__mmSyncRelayRtt) || 0) / 2),
    ),
    __mmPredictedLeaderX =
      Number(__mmLeader.x) + __mmVelocityX * __mmPredictionMs,
    __mmPredictedLeaderY =
      Number(__mmLeader.y) + __mmVelocityY * __mmPredictionMs,
    __mmTargetX =
      __mmPredictedLeaderX + Math.cos(__mmStandAngle) * __mmStandDistance,
    __mmTargetY =
      __mmPredictedLeaderY + Math.sin(__mmStandAngle) * __mmStandDistance,
    __mmDx = __mmTargetX - v.x,
    __mmDy = __mmTargetY - v.y,
    __mmDistanceSquared = __mmDx * __mmDx + __mmDy * __mmDy,
    __mmStopDistance = __mmSyncStopTolerance,
    __mmResumeDistance = Math.max(
      __mmStopDistance + 1,
      __mmSyncResumeTolerance,
    ),
    __mmCatchupDistance = __mmSyncCatchupDistance,
    __mmCatchupReleaseDistance = Math.min(
      __mmCatchupDistance - 10,
      __mmSyncCatchupReleaseDistance,
    ),
    __mmLeaderDx = Number(v.x) - Number(__mmLeader.x),
    __mmLeaderDy = Number(v.y) - Number(__mmLeader.y),
    __mmCurrentCenterDistance = Math.hypot(__mmLeaderDx, __mmLeaderDy),
    __mmMinimumCenterDistance = __mmHitboxDistance + __mmSyncFollowGap,
    __mmSafeCenterDistance =
      __mmMinimumCenterDistance + __mmSyncStopTolerance;
  if (__mmSyncCombatActive()) __mmSyncRestoreCatchupGear();
  else if (__mmDistanceSquared >= __mmCatchupDistance * __mmCatchupDistance)
    __mmSyncUseCatchupGear();
  else if (
    __mmSyncCatchupActive &&
    __mmDistanceSquared <=
      __mmCatchupReleaseDistance * __mmCatchupReleaseDistance
  )
    __mmSyncRestoreCatchupGear();
  __mmSetSyncStatus(
    __mmSyncCatchupActive
      ? "Synced · " + __mmSyncTargetLabel() + " · catching up"
      : "Synced · " +
          __mmSyncTargetLabel() +
          (__mmSyncLeaderState && __mmSyncLeaderState.kittyPeer
            ? " · exact"
            : " · visible"),
  );
  // A direct collision guard wins over side positioning. Move radially away
  // until the player edges are separated by the configured minimum gap plus
  // the stopping buffer, then resume the normal deterministic side target.
  if (__mmCurrentCenterDistance < __mmSafeCenterDistance) {
    const __mmAwayDirection =
      __mmCurrentCenterDistance > 0.001
        ? Math.atan2(__mmLeaderDy, __mmLeaderDx)
        : __mmStandAngle;
    (__mmSyncArrivedBeside = !1,
      __mmSyncRestoreCatchupGear(),
      __mmSetSyncStatus(
        "Synced · " +
          __mmSyncTargetLabel() +
          " · spacing " +
          Math.max(
            0,
            Math.round(__mmCurrentCenterDistance - __mmHitboxDistance),
          ) +
          "/" +
          Math.round(__mmSyncFollowGap) +
          "px",
      ),
      __mmSyncApplyMoveDirection(__mmAwayDirection));
    return;
  }
  if (__mmSyncPauseInCombatEnabled && __mmSyncCombatActive())
    return (
      __mmSyncRestoreCatchupGear(),
      __mmSyncStopFollowMovement(),
      void __mmSetSyncStatus(
        "Synced · " + __mmSyncTargetLabel() + " · combat hold",
      )
    );
  if (
    (__mmSyncMoveActive &&
      __mmDistanceSquared <= __mmStopDistance * __mmStopDistance) ||
    (!__mmSyncMoveActive &&
      __mmDistanceSquared <= __mmResumeDistance * __mmResumeDistance)
  ) {
    (__mmSyncArrivedBeside = !0,
      __mmSyncRestoreCatchupGear(),
      __mmSyncStopFollowMovement(),
      __mmSetSyncStatus(
        "Synced · " + __mmSyncTargetLabel() + " · beside",
      ));
    return;
  }
  __mmSyncArrivedBeside = !1;
  __mmSyncApplyMoveDirection(Math.atan2(__mmDy, __mmDx));
}
function __mmSyncFollowFrameTick() {
  __mmSyncFollowFrame = 0;
  if (
    !__mmSyncFollowerEnabled ||
    !__mmSyncMovementEnabled ||
    !v ||
    !v.alive
  )
    return;
  (__mmSyncFollowTick(),
    (__mmSyncFollowFrame = requestAnimationFrame(__mmSyncFollowFrameTick)));
}
function __mmStartSyncFollowFrames() {
  __mmSyncFollowerEnabled &&
    __mmSyncMovementEnabled &&
    !__mmSyncFollowFrame &&
    (__mmSyncFollowFrame = requestAnimationFrame(__mmSyncFollowFrameTick));
}
function __mmStopSyncFollowFrames() {
  (__mmSyncFollowFrame && cancelAnimationFrame(__mmSyncFollowFrame),
    (__mmSyncFollowFrame = 0));
}
document.addEventListener("visibilitychange", function () {
  document.hidden
    ? (__mmStopSyncFollowFrames(), __mmSyncStopFollowMovement())
    : __mmStartSyncFollowFrames();
});
function __mmSyncManualMovementPressed(__mmKey) {
  if (
    !__mmSyncFollowerEnabled ||
    !__mmSyncWasdCombatOnlyEnabled ||
    (__mmKey !== 87 && __mmKey !== 65 && __mmKey !== 83 && __mmKey !== 68)
  )
    return;
  ((__mmSyncFollowerEnabled = !1),
    (__mmSyncCombatOnlyEnabled = !0),
    (__mmSyncStandLeaderKey = ""),
    (__mmSyncStandAngle = null),
    (__mmSyncArrivedBeside = !1),
    __mmSyncRestoreCatchupGear(),
    __mmSyncStopFollowMovement(),
    __mmStartTabSync(),
    __mmSetSyncStatus(
      "Synced · " + __mmSyncTargetLabel() + " · combat only",
    ),
    __mmPublishHudState());
}
function __mmSyncOwnsSelection(__mmItem, __mmIsWeapon) {
  return !!(
    v &&
    v.alive &&
    Number.isFinite(Number(__mmItem)) &&
    (__mmIsWeapon
      ? v.weapons && v.weapons.includes(__mmItem)
      : v.items && v.items.includes(__mmItem))
  );
}
function __mmSyncCombatWeapon(__mmRemoteWeapon, __mmLeader, __mmRemoteSlot) {
  if (!v || !v.alive || !Array.isArray(v.weapons)) return null;
  const __mmRemoteId = Number(__mmRemoteWeapon);
  if (
    Number.isInteger(__mmRemoteId) &&
    v.weapons.some((__mmWeapon) => Number(__mmWeapon) === __mmRemoteId)
  )
    return __mmRemoteId;
  let __mmSlot = Number(__mmRemoteSlot);
  if (!Number.isInteger(__mmSlot) || __mmSlot < 0 || __mmSlot > 1)
    __mmSlot = __mmPlayerWeaponSlot(__mmLeader, __mmRemoteId);
  const __mmLocalWeapon = Number(v.weapons[__mmSlot]);
  return Number.isInteger(__mmLocalWeapon) ? __mmLocalWeapon : null;
}
function __mmSyncPacketFresh(__mmMessage) {
  const __mmPacketId = String(__mmMessage && __mmMessage.packetId || "");
  if (!__mmPacketId) return !0;
  if (__mmSyncSeenPackets[__mmPacketId]) return !1;
  const __mmNow = Date.now();
  __mmSyncSeenPackets[__mmPacketId] = __mmNow;
  if (__mmSyncSequence % 64 === 0)
    for (const __mmSeenId in __mmSyncSeenPackets)
      __mmNow - __mmSyncSeenPackets[__mmSeenId] > 5000 &&
        delete __mmSyncSeenPackets[__mmSeenId];
  return !0;
}
function __mmCancelScheduledSyncInsta() {
  (__mmSyncScheduledInstaTimer &&
    clearTimeout(__mmSyncScheduledInstaTimer),
    (__mmSyncScheduledInstaTimer = 0),
    (__mmSyncScheduledInstaAt = 0));
}
function __mmSyncInstaTargetReady(__mmTarget) {
  if (__mmBowUpgradeInsta.ready(__mmTarget)) return !0;
  if (
    !__mmTarget ||
    !__mmIsEnemyPlayer(__mmTarget) ||
    !__mmInsta.canFullBurst(__mmTarget)
  )
    return !1;
  return __mmInsta.fullBurstReady(__mmTarget, "normal", !1);
}
function __mmScheduleSyncInstaAt(
  __mmExecuteAt,
  __mmTargetSid,
  __mmOptions,
) {
  if (
    !__mmSyncTickCombatEnabled ||
    __mmSyncScheduledInstaTimer ||
    !Number.isFinite(Number(__mmExecuteAt))
  )
    return !1;
  let __mmTarget = null;
  try {
    __mmTarget = Rt(__mmTargetSid);
  } catch (__mmSyncTargetLookupError) {}
  if (!__mmSyncInstaTargetReady(__mmTarget)) return !1;
  const __mmDelay = Math.round(Number(__mmExecuteAt) - __mmSyncServerNow());
  if (__mmDelay < -45 || __mmDelay > 1500) return !1;
  (__mmSyncRestoreCatchupGear(),
    (__mmSyncScheduledInstaAt = Number(__mmExecuteAt)),
    (__mmSyncScheduledInstaTimer = setTimeout(function () {
      ((__mmSyncScheduledInstaTimer = 0),
        (__mmSyncScheduledInstaAt = 0));
      let __mmLiveTarget = null;
      try {
        __mmLiveTarget = Rt(__mmTargetSid);
      } catch (__mmLateSyncTargetLookupError) {}
      if (!__mmSyncInstaTargetReady(__mmLiveTarget)) return;
      if (
        __mmBowUpgradeInsta.ready(__mmLiveTarget) &&
        __mmInsta.fullBurstReady(__mmLiveTarget, "normal", !1, !0)
      )
        __mmInsta.start({
          ...(__mmOptions || {}),
          automatic: !!(__mmOptions && __mmOptions.automatic),
          targetSid: __mmTargetSid,
          syncScheduled: !0,
          profile: "normal",
          profileSource: "Bow Upgrade sync",
          bowUpgradeFollowup: !0,
        });
      else if (__mmBowUpgradeInsta.ready(__mmLiveTarget))
        __mmBowUpgradeInsta.start(__mmLiveTarget, "teammate tick sync");
      else
        __mmInsta.start({
          ...(__mmOptions || {}),
          automatic: !!(__mmOptions && __mmOptions.automatic),
          targetSid: __mmTargetSid,
          syncScheduled: !0,
        });
    }, Math.max(0, __mmDelay))));
  return !0;
}
function __mmTryScheduleSharedInsta(__mmOptions) {
  if (
    !__mmSyncLeaderEnabled ||
    !__mmSyncTickCombatEnabled ||
    !__mmSyncRelayConnected() ||
    (__mmOptions && __mmOptions.betrayal)
  )
    return !1;
  if (__mmSyncScheduledInstaTimer) return !0;
  let __mmTarget = null;
  try {
    __mmTarget =
      __mmOptions && __mmOptions.targetSid != null
        ? Rt(__mmOptions.targetSid)
        : __mmInsta.nearestEnemy();
  } catch (__mmSharedInstaTargetError) {}
  if (!__mmSyncInstaTargetReady(__mmTarget)) return !1;
  const __mmLead = Math.min(
      700,
      Math.max(
        __mmServerTickMs() * 3,
        __mmSyncRelayRtt * 2 + 80,
        250,
      ),
    ),
    __mmExecuteAt = Math.ceil(__mmSyncServerNow() + __mmLead);
  __mmSyncPost({
    type: "instaIntent",
    targetSid: __mmTarget.sid,
    executeAt: __mmExecuteAt,
  });
  return __mmScheduleSyncInstaAt(
    __mmExecuteAt,
    __mmTarget.sid,
    __mmOptions || {},
  );
}
function __mmSyncHandleMessage(__mmEvent) {
  const __mmMessage = __mmEvent && __mmEvent.data;
  if (
    !__mmMessage ||
    __mmMessage.sender === __mmSyncTabId ||
    typeof __mmMessage !== "object" ||
    String(__mmMessage.teamKey || "") !== __mmSyncOwnTeamKey() ||
    !__mmSyncPacketFresh(__mmMessage)
  )
    return;
  if (__mmMessage.type === "syncRequest") {
    if (
      v &&
      v.alive &&
      String(__mmMessage.requestedSid) === String(v.sid)
    ) {
      let __mmRequester = null;
      try {
        __mmRequester = Rt(__mmMessage.leaderSid);
      } catch (__mmSyncRequesterLookupError) {}
      // A request grants this peer our outgoing state; it must never select
      // the requester as our own movement/combat target. Reciprocity is only
      // created by this player explicitly pressing Y and clicking them too.
      if (!__mmRequester || __mmSameTeam(__mmRequester)) {
        const __mmRequesterName = String(
          (__mmRequester && __mmRequester.name) ||
            "Player " + __mmMessage.leaderSid,
        ).trim().slice(0, 15);
        ((__mmSyncLeaderEnabled = !0),
          __mmStartTabSync(),
          __mmSyncBroadcastState(),
          __mmSyncTargetSid == null &&
            __mmSetSyncStatus(__mmRequesterName + " is following you"),
          __mmPublishHudState());
      }
    }
    return;
  }
  if (!__mmSyncFollowerEnabled && !__mmSyncCombatOnlyEnabled) return;
  if (
    __mmSyncTargetSid == null ||
    String(__mmMessage.leaderSid) !== String(__mmSyncTargetSid)
  )
    return;
  if (__mmMessage.type === "state") {
    const __mmLeader = Rt(__mmMessage.leaderSid);
    if (
      v &&
      String(__mmMessage.leaderSid) !== String(v.sid) &&
      Number.isFinite(Number(__mmMessage.x)) &&
      Number.isFinite(Number(__mmMessage.y))
    ) {
      // The role is explicitly enabled in both local tabs. Do not require the
      // leader to be visible before following, otherwise two far-apart spawns
      // can never meet. When visible, the live player object is preferred.
      __mmSyncLeaderState = {
        ...__mmMessage,
        x:
          __mmLeader && __mmLeader.alive ? __mmLeader.x : Number(__mmMessage.x),
        y:
          __mmLeader && __mmLeader.alive ? __mmLeader.y : Number(__mmMessage.y),
        receivedAt: Date.now(),
        kittyPeer: !0,
        networkReceivedAt: Date.now(),
      };
      !__mmSyncFollowerEnabled &&
        __mmSetSyncStatus(
          "Synced · " + __mmSyncTargetLabel() + " · combat linked",
        );
      const __mmBuild = Number(__mmMessage.build),
        __mmWeapon = Number(__mmMessage.weapon),
        __mmHat = Number(__mmMessage.hat),
        __mmTail = Number(__mmMessage.tail);
      __mmWithSyncReplay(function () {
        if (
          __mmSyncCopyBuildsEnabled &&
          Number.isInteger(__mmBuild) &&
          __mmBuild >= 0 &&
          __mmSyncOwnsSelection(__mmBuild, !1) &&
          Number(v.buildIndex) !== __mmBuild
        )
          je(__mmBuild);
        else if (
          __mmSyncCopyWeaponsEnabled &&
          (!Number.isInteger(__mmBuild) || __mmBuild < 0) &&
          Number.isInteger(__mmWeapon) &&
          __mmSyncOwnsSelection(__mmWeapon, !0) &&
          (Number(v.buildIndex) >= 0 || Number(v.weaponIndex) !== __mmWeapon)
        )
          je(__mmWeapon, !0);
        if (!__mmSyncCopyGearEnabled) return;
        if (__mmSyncCatchupActive) {
          (__mmCanEquipHat(__mmHat) || __mmHat === 0) &&
            (__mmSyncCatchupPreviousHat = __mmHat);
          ((v.tails && v.tails[__mmTail]) || __mmTail === 0) &&
            (__mmSyncCatchupPreviousTail = __mmTail);
        } else {
          (__mmCanEquipHat(__mmHat) || __mmHat === 0) &&
            Number(v.skinIndex) !== __mmHat &&
            __mmEquipHatNow(__mmHat);
          ((v.tails && v.tails[__mmTail]) || __mmTail === 0) &&
            Number(v.tailIndex) !== __mmTail &&
            __mmEquipTailNow(__mmTail);
        }
      });
      __mmSyncFollowerEnabled && __mmSyncFollowTick();
    }
    return;
  }
  if (__mmMessage.type === "instaIntent") {
    if (
      !__mmSyncTickCombatEnabled ||
      !__mmSyncLeaderPlayer(__mmMessage)
    )
      return;
    (__mmSyncLeaderCombatUntil = Math.max(
      __mmSyncLeaderCombatUntil,
      Date.now() + 1200,
    ));
    __mmSyncRestoreCatchupGear();
    __mmScheduleSyncInstaAt(
      Number(__mmMessage.executeAt),
      __mmMessage.targetSid,
      { automatic: !0 },
    );
    return;
  }
  const __mmLeader = __mmSyncLeaderPlayer(__mmMessage);
  if (!__mmLeader) return;
  if (__mmMessage.type === "attack" && __mmMessage.state) {
    (__mmSyncLeaderCombatUntil =
      Date.now() + Math.max(500, __mmServerTickMs() * 5));
    __mmSyncRestoreCatchupGear();
  }
  if (__mmMessage.type === "selection") {
    if (
      __mmMessage.isWeapon
        ? !__mmSyncCopyWeaponsEnabled
        : !__mmSyncCopyBuildsEnabled
    )
      return;
    if (!__mmSyncOwnsSelection(__mmMessage.item, !!__mmMessage.isWeapon)) {
      __mmSyncSelectionBlockedUntil = Date.now() + 900;
      return;
    }
    ((__mmSyncSelectionBlockedUntil = 0),
      __mmWithSyncReplay(function () {
        je(__mmMessage.item, !!__mmMessage.isWeapon);
      }));
    return;
  }
  if (__mmMessage.type === "gear") {
    if (!__mmSyncCopyGearEnabled) return;
    __mmWithSyncReplay(function () {
      __mmMessage.tail
        ? __mmEquipTailNow(__mmMessage.item)
        : __mmEquipHatNow(__mmMessage.item);
    });
    return;
  }
  if (__mmMessage.type === "gearPair") {
    if (!__mmSyncCopyGearEnabled) return;
    __mmWithSyncReplay(function () {
      __mmEquipGearPair(__mmMessage.hat, __mmMessage.tail, !0);
    });
    return;
  }
  if (__mmMessage.type === "aim") {
    if (!__mmSyncCopyAimEnabled) return;
    const __mmAimX = Number(__mmMessage.aimX),
      __mmAimY = Number(__mmMessage.aimY);
    if (Number.isFinite(__mmAimX) && Number.isFinite(__mmAimY))
      __mmWithSyncReplay(function () {
        O.send("D", Math.atan2(__mmAimY - v.y, __mmAimX - v.x));
      });
    return;
  }
  if (
    __mmMessage.type !== "attack" ||
    !__mmSyncCopyAttacksEnabled
  )
    return;
  const __mmAimX = Number(__mmMessage.aimX),
    __mmAimY = Number(__mmMessage.aimY),
    __mmAngle =
      __mmSyncCopyAimEnabled &&
      Number.isFinite(__mmAimX) && Number.isFinite(__mmAimY)
        ? Math.atan2(__mmAimY - v.y, __mmAimX - v.x)
        : Ci(),
    __mmCombatWeapon = __mmMessage.state
      ? __mmSyncCombatWeapon(
          __mmMessage.weapon,
          __mmLeader,
          __mmMessage.weaponSlot,
        )
      : null,
    __mmCombatHat = Number(__mmMessage.hat),
    __mmCombatTail = Number(__mmMessage.tail);
  ((__mmSyncDirectAttackAt = Date.now()),
    (__mmSyncDirectAttackActive = !!__mmMessage.state)),
    __mmStopObservedSyncAttack(!1);
  __mmWithSyncReplay(function () {
    // The combat event is atomic: select a compatible local weapon slot and
    // apply the leader's owned gear immediately before the copied attack. This
    // removes the race between separately delivered selection/gear/F packets.
    if (
      __mmMessage.state &&
      __mmSyncCopyWeaponsEnabled &&
      __mmCombatWeapon != null &&
      (Number(v.buildIndex) >= 0 || Number(v.weaponIndex) !== __mmCombatWeapon)
    )
      je(__mmCombatWeapon, !0);
    if (__mmMessage.state && __mmSyncCopyGearEnabled) {
      const __mmHat =
          (__mmCanEquipHat(__mmCombatHat) || __mmCombatHat === 0)
            ? __mmCombatHat
            : null,
        __mmTail =
          ((v.tails && v.tails[__mmCombatTail]) || __mmCombatTail === 0)
            ? __mmCombatTail
            : null;
      (__mmHat != null || __mmTail != null) &&
        __mmEquipGearPair(__mmHat, __mmTail, !0);
    }
    __mmSyncCopyAimEnabled && O.send("D", __mmAngle);
    O.send("F", __mmMessage.state ? 1 : 0, __mmAngle);
  });
}
function __mmReceiveOpenSync(__mmDetail) {
  let __mmEnvelope = __mmDetail;
  try {
    if (typeof __mmEnvelope === "string")
      __mmEnvelope = JSON.parse(__mmEnvelope);
  } catch (__mmOpenSyncParseError) {
    return !1;
  }
  if (!__mmEnvelope || typeof __mmEnvelope !== "object") return !1;
  if (
    __mmEnvelope.protocol &&
    String(__mmEnvelope.protocol) !== __mmOpenSyncProtocol
  )
    return !1;
  const __mmRaw =
    __mmEnvelope.packet && typeof __mmEnvelope.packet === "object"
      ? __mmEnvelope.packet
      : __mmEnvelope.action && typeof __mmEnvelope.action === "object"
        ? __mmEnvelope.action
        : __mmEnvelope;
  if (!__mmRaw || __mmSyncTargetSid == null || !v || !v.alive) return !1;
  const __mmRawType = String(__mmRaw.type || __mmRaw.action || "")
      .trim()
      .toLowerCase(),
    __mmType =
      __mmRawType === "swing" || __mmRawType === "hit"
        ? "attack"
        : __mmRawType === "weapon" || __mmRawType === "select"
          ? "selection"
          : __mmRawType === "hat" || __mmRawType === "tail"
            ? "gear"
            : __mmRawType === "equipment"
              ? "gearPair"
              : __mmRawType === "look" || __mmRawType === "rotate"
                ? "aim"
                : __mmRawType === "gearpair"
                  ? "gearPair"
                  : __mmRawType === "instaintent" || __mmRawType === "insta"
                    ? "instaIntent"
                    : __mmRawType,
    __mmAllowed =
      __mmType === "state" ||
      __mmType === "selection" ||
      __mmType === "gear" ||
      __mmType === "gearPair" ||
      __mmType === "aim" ||
      __mmType === "attack" ||
      __mmType === "instaIntent";
  if (!__mmAllowed) return !1;
  const __mmLeaderSid =
    __mmRaw.leaderSid != null
      ? __mmRaw.leaderSid
      : __mmRaw.playerSid != null
        ? __mmRaw.playerSid
        : __mmSyncTargetSid;
  if (String(__mmLeaderSid) !== String(__mmSyncTargetSid)) return !1;
  let __mmLeader = null;
  try {
    __mmLeader = Rt(__mmLeaderSid);
  } catch (__mmOpenSyncLeaderError) {}
  if (__mmLeader && !__mmSameTeam(__mmLeader)) return !1;
  const __mmSource = String(
      __mmEnvelope.source || __mmEnvelope.client || "other-mod",
    ).replace(/[^a-z0-9_.-]/gi, "").slice(0, 32) || "other-mod",
    __mmSender = "open:" + __mmSource + ":" + String(__mmLeaderSid),
    __mmNow = Date.now(),
    __mmPacket = {
      ...__mmRaw,
      type: __mmType,
      sender: __mmSender,
      packetId:
        __mmSender + ":" + __mmNow + ":" + (++__mmOpenSyncSequence),
      leaderSid: __mmLeaderSid,
      teamKey: __mmSyncOwnTeamKey(),
      sentAt: __mmNow,
    };
  if (__mmType === "selection") {
    __mmPacket.item = Number(
      __mmRaw.item != null ? __mmRaw.item : __mmRaw.weapon,
    );
    __mmPacket.isWeapon =
      __mmRaw.isWeapon == null ? !0 : !!__mmRaw.isWeapon;
  } else if (__mmType === "gear") {
    __mmPacket.item = Number(
      __mmRaw.item != null
        ? __mmRaw.item
        : __mmRawType === "tail"
          ? __mmRaw.tail
          : __mmRaw.hat,
    );
    __mmPacket.tail =
      __mmRawType === "tail" ||
      __mmRaw.tail === !0 ||
      !!__mmRaw.tailSlot;
  } else if (__mmType === "gearPair") {
    __mmPacket.hat = Number(__mmRaw.hat);
    __mmPacket.tail = Number(__mmRaw.tail);
  } else if (__mmType === "attack") {
    __mmPacket.state =
      __mmRaw.state != null
        ? __mmRaw.state ? 1 : 0
        : __mmRaw.down != null
          ? __mmRaw.down ? 1 : 0
          : 1;
  }
  const __mmAngle = Number(
    __mmRaw.angle != null ? __mmRaw.angle : __mmRaw.dir,
  );
  if (
    (__mmType === "aim" || __mmType === "attack") &&
    (!Number.isFinite(Number(__mmPacket.aimX)) ||
      !Number.isFinite(Number(__mmPacket.aimY))) &&
    Number.isFinite(__mmAngle)
  ) {
    const __mmBaseX = Number(
        (__mmLeader && __mmLeader.x) ||
          (__mmSyncLeaderState && __mmSyncLeaderState.x) ||
          v.x,
      ),
      __mmBaseY = Number(
        (__mmLeader && __mmLeader.y) ||
          (__mmSyncLeaderState && __mmSyncLeaderState.y) ||
          v.y,
      );
    ((__mmPacket.aimX = __mmBaseX + Math.cos(__mmAngle) * 1800),
      (__mmPacket.aimY = __mmBaseY + Math.sin(__mmAngle) * 1800));
  }
  const __mmPrevious = __mmSyncLeaderState || {};
  __mmSyncLeaderState = {
    ...__mmPrevious,
    sender: __mmSender,
    leaderSid: __mmLeaderSid,
    x: __mmLeader && __mmLeader.alive
      ? Number(__mmLeader.x)
      : Number(__mmPrevious.x),
    y: __mmLeader && __mmLeader.alive
      ? Number(__mmLeader.y)
      : Number(__mmPrevious.y),
    receivedAt: __mmNow,
    kittyPeer: !0,
    networkReceivedAt: __mmNow,
    openSyncPeer: !0,
  };
  (__mmSetSyncStatus(
    "Synced · " + __mmSyncTargetLabel() + " · mod bridge",
  ),
    __mmSyncHandleMessage({ data: __mmPacket }));
  return !0;
}
function __mmSyncPublishSelection(__mmItem, __mmIsWeapon) {
  __mmSyncPost({
    type: "selection",
    item: __mmItem,
    isWeapon: !!__mmIsWeapon,
  });
}
function __mmSyncPublishGear(__mmItem, __mmTail) {
  __mmSyncPost({ type: "gear", item: __mmItem, tail: !!__mmTail });
}
function __mmSyncPublishGearPair(__mmHat, __mmTail) {
  __mmSyncPost({ type: "gearPair", hat: __mmHat, tail: __mmTail });
}
function __mmSyncObserveSocketSend(__mmArguments) {
  if (!__mmSyncLeaderEnabled || !v || !v.alive) return;
  if (__mmArguments[0] === "c") {
    if (__mmSyncGearPairDispatch) return;
    __mmSyncPublishGear(__mmArguments[2], !!__mmArguments[3]);
    return;
  }
  if (__mmArguments[0] === "D") {
    const __mmDirection = Number(__mmArguments[1]),
      __mmAimDistance = 1800;
    Number.isFinite(__mmDirection) &&
      __mmSyncPost({
        type: "aim",
        aimX: v.x + Math.cos(__mmDirection) * __mmAimDistance,
        aimY: v.y + Math.sin(__mmDirection) * __mmAimDistance,
      });
    return;
  }
  if (__mmArguments[0] !== "F") return;
  const __mmAngle = Number(__mmArguments[2]),
    __mmDirection = Number.isFinite(__mmAngle) ? __mmAngle : Ci(),
    __mmAimDistance = 1800,
    __mmRecentWeapon =
      __mmLastSelectionWasWeapon && Date.now() - __mmLastSelectionAt <= 250
        ? Number(__mmLastSelectionItem)
        : Number(v.weaponIndex),
    __mmWeapon = Number.isInteger(__mmRecentWeapon)
      ? __mmRecentWeapon
      : Number(v.weaponIndex),
    __mmHat =
      __mmPendingHat != null && Date.now() - __mmPendingHatAt <= __mmServerTickMs()
        ? Number(__mmPendingHat)
        : Number(v.skinIndex),
    __mmTail =
      __mmPendingTail != null && Date.now() - __mmPendingTailAt <= __mmServerTickMs()
        ? Number(__mmPendingTail)
        : Number(v.tailIndex);
  __mmSyncPost({
    type: "attack",
    state: __mmArguments[1] ? 1 : 0,
    aimX: v.x + Math.cos(__mmDirection) * __mmAimDistance,
    aimY: v.y + Math.sin(__mmDirection) * __mmAimDistance,
    weapon: __mmWeapon,
    weaponSlot: __mmPlayerWeaponSlot(v, __mmWeapon),
    weapons: Array.isArray(v.weapons) ? v.weapons.slice(0, 2) : [],
    hat: __mmHat,
    tail: __mmTail,
  });
}
function __mmUpdateTabSync() {
  __mmSyncRelayWanted() && !__mmSyncRelayConnected() &&
    __mmConnectSyncRelay();
  __mmSyncTargetSid != null && __mmRefreshSelectedSyncTarget();
  if (
    __mmSyncTargetSid != null &&
    (!__mmSyncLeaderState || !__mmSyncLeaderState.kittyPeer) &&
    Date.now() - __mmSyncRequestLastAt >= 900
  ) {
    ((__mmSyncRequestLastAt = Date.now()),
      __mmSyncPost({
        type: "syncRequest",
        requestedSid: __mmSyncTargetSid,
      }));
  }
  __mmSyncLeaderEnabled && __mmSyncBroadcastState();
  __mmSyncFollowerEnabled && __mmStartSyncFollowFrames();
}
function __mmStartTabSync() {
  (__mmConnectSyncRelay(),
    __mmUpdateTabSync(),
    __mmStartSyncFollowFrames(),
    __mmSyncTimer ||
      (__mmSyncTimer = setInterval(__mmUpdateTabSync, __mmFastCheckMs())));
}
function __mmStopTabSync() {
  if (
    __mmSyncLeaderEnabled ||
    __mmSyncFollowerEnabled ||
    __mmSyncCombatOnlyEnabled ||
    __mmSyncRelayWanted()
  )
    return;
  (__mmSyncTimer && clearInterval(__mmSyncTimer),
    (__mmSyncTimer = 0),
    __mmStopSyncFollowFrames(),
    (__mmSyncLeaderState = null),
    (__mmSyncStandLeaderKey = ""),
    (__mmSyncStandAngle = null),
    (__mmSyncSelectionBlockedUntil = 0),
    (__mmSyncLeaderCombatUntil = 0),
    __mmCancelScheduledSyncInsta(),
    __mmCloseSyncRelay(!1),
    __mmSyncRestoreCatchupGear(),
    __mmSyncStopFollowMovement());
}
__mmSyncChannel && __mmSyncChannel.addEventListener("message", __mmSyncHandleMessage);
window.addEventListener("storage", function (__mmStorageEvent) {
  if (!__mmStorageEvent || __mmStorageEvent.key !== __mmSyncStorageKey) return;
  try {
    __mmStorageEvent.newValue &&
      __mmSyncHandleMessage({ data: JSON.parse(__mmStorageEvent.newValue) });
  } catch (__mmSyncStorageReadError) {}
});
window.addEventListener("MooMooTabSyncInbound", function (__mmSyncBridgeEvent) {
  try {
    typeof __mmSyncBridgeEvent.detail === "string" &&
      __mmSyncHandleMessage({ data: JSON.parse(__mmSyncBridgeEvent.detail) });
  } catch (__mmSyncBridgeReadError) {}
});
window.addEventListener("MooMooKittySyncInbound", function (__mmOpenSyncEvent) {
  __mmReceiveOpenSync(__mmOpenSyncEvent && __mmOpenSyncEvent.detail);
});
window.addEventListener("MooMooModSyncInbound", function (__mmOpenSyncEvent) {
  __mmReceiveOpenSync(__mmOpenSyncEvent && __mmOpenSyncEvent.detail);
});
try {
  const __mmOpenSyncApi =
    window.KittyKlientSync && typeof window.KittyKlientSync === "object"
      ? window.KittyKlientSync
      : {};
  Object.assign(__mmOpenSyncApi, {
    protocol: __mmOpenSyncProtocol,
    apiVersion: 1,
    clientVersion: "${KITTY_KLIENT_VERSION}",
    capabilities: [
      "state",
      "selection",
      "gear",
      "gearPair",
      "aim",
      "attack",
      "instaIntent",
    ],
    receive: __mmReceiveOpenSync,
    getTarget: function () {
      return __mmSyncTargetSid == null
        ? null
        : {
            sid: __mmSyncTargetSid,
            name: __mmSyncTargetName,
            movement: __mmSyncFollowerEnabled,
            combat: __mmSyncFollowerEnabled || __mmSyncCombatOnlyEnabled,
          };
    },
  });
  window.KittyKlientSync = __mmOpenSyncApi;
  window.dispatchEvent(
    new CustomEvent("MooMooKittySyncReady", {
      detail: {
        protocol: __mmOpenSyncProtocol,
        apiVersion: 1,
        clientVersion: "${KITTY_KLIENT_VERSION}",
      },
    }),
  );
} catch (__mmOpenSyncApiError) {}
function __mmDrawPredictionGhost(__mmLeft, __mmTop) {
  if (!__mmPredictionGhostEnabled || !v || !v.alive) return;
  const __mmNow = Date.now();
  if (__mmPredictionLastX == null || __mmPredictionLastY == null) {
    ((__mmPredictionLastX = v.x),
      (__mmPredictionLastY = v.y),
      (__mmPredictionLastAt = __mmNow));
    return;
  }
  const __mmElapsed = Math.max(
      1,
      Math.min(120, __mmNow - __mmPredictionLastAt),
    ),
    __mmPing = Number(window.pingTime),
    __mmLeadMs = Number.isFinite(__mmPing)
      ? Math.max(0, Math.min(1e3, __mmPing * 0.5))
      : 0,
    __mmPredictedX = Math.max(
      0,
      Math.min(
        y.mapScale,
        v.x + ((v.x - __mmPredictionLastX) / __mmElapsed) * __mmLeadMs,
      ),
    ),
    __mmPredictedY = Math.max(
      0,
      Math.min(
        y.mapScale,
        v.y + ((v.y - __mmPredictionLastY) / __mmElapsed) * __mmLeadMs,
      ),
    );
  ((__mmPredictionLastX = v.x),
    (__mmPredictionLastY = v.y),
    (__mmPredictionLastAt = __mmNow));
  const __mmScreenX = __mmPredictedX - __mmLeft,
    __mmScreenY = __mmPredictedY - __mmTop;
  if (
    __mmScreenX < -(v.scale || 35) ||
    __mmScreenX > _ + (v.scale || 35) ||
    __mmScreenY < -(v.scale || 35) ||
    __mmScreenY > L + (v.scale || 35)
  )
    return;
  (k.save(),
    (k.globalAlpha = 0.3),
    k.translate(__mmScreenX, __mmScreenY),
    __mmFpsBoostEnabled
      ? ((k.fillStyle = "rgba(168,85,247,.2)"),
        (k.strokeStyle = "rgba(216,180,254,.72)"),
        (k.lineWidth = 2),
        k.beginPath(),
        k.arc(0, 0, Number(v.scale) || 35, 0, Math.PI * 2),
        k.fill(),
        k.stroke())
      : (k.rotate(Ci() + v.dirPlus), Dl(v, k)),
    k.restore());
}
function __mmDrawEspArrow(
  __mmContext,
  __mmOwnX,
  __mmOwnY,
  __mmTargetX,
  __mmTargetY,
  __mmOwnScale,
  __mmTargetScale,
  __mmColor,
  __mmFriendly,
) {
  const __mmDx = __mmTargetX - __mmOwnX,
    __mmDy = __mmTargetY - __mmOwnY,
    __mmDistance = Math.hypot(__mmDx, __mmDy);
  if (!Number.isFinite(__mmDistance) || __mmDistance < 1) return;
  const __mmUnitX = __mmDx / __mmDistance,
    __mmUnitY = __mmDy / __mmDistance,
    __mmPerpX = -__mmUnitY,
    __mmPerpY = __mmUnitX,
    // Keep the indicator centered in the open space instead of drawing a line
    // from one player all the way to the other. It grows and softens nearby.
    __mmCloseness = 1 - Math.min(1, Math.max(0, (__mmDistance - 75) / 725)),
    __mmSize = 1 + 0.55 * __mmCloseness,
    __mmAlpha = 0.94 - 0.22 * __mmCloseness,
    __mmMidX = (__mmOwnX + __mmTargetX) * 0.5,
    __mmMidY = (__mmOwnY + __mmTargetY) * 0.5,
    __mmDesiredLength = (__mmFriendly ? 70 : 82) * __mmSize,
    __mmArrowLength = Math.max(
      30,
      Math.min(__mmDesiredLength, __mmDistance * 0.55),
    ),
    __mmHalfLength = __mmArrowLength * 0.5,
    __mmHeadLength = Math.min(
      __mmArrowLength * 0.48,
      (__mmFriendly ? 26 : 31) * __mmSize,
    ),
    __mmHeadHalfWidth = (__mmFriendly ? 14 : 18) * __mmSize,
    __mmTailX = __mmMidX - __mmUnitX * __mmHalfLength,
    __mmTailY = __mmMidY - __mmUnitY * __mmHalfLength,
    __mmTipX = __mmMidX + __mmUnitX * __mmHalfLength,
    __mmTipY = __mmMidY + __mmUnitY * __mmHalfLength,
    __mmNeckX = __mmTipX - __mmUnitX * __mmHeadLength,
    __mmNeckY = __mmTipY - __mmUnitY * __mmHeadLength,
    __mmWingTopX = __mmNeckX + __mmPerpX * __mmHeadHalfWidth,
    __mmWingTopY = __mmNeckY + __mmPerpY * __mmHeadHalfWidth,
    __mmWingBottomX = __mmNeckX - __mmPerpX * __mmHeadHalfWidth,
    __mmWingBottomY = __mmNeckY - __mmPerpY * __mmHeadHalfWidth,
    __mmCoreWidth = (__mmFriendly ? 9 : 13) * __mmSize;
  function __mmArrowPath(
    __mmWidth,
    __mmPathAlpha,
    __mmBlur,
    __mmStrokeColor = __mmColor,
  ) {
    (__mmContext.save(),
      (__mmContext.globalAlpha = __mmAlpha * __mmPathAlpha),
      (__mmContext.strokeStyle = __mmStrokeColor),
      (__mmContext.lineWidth = __mmWidth),
      (__mmContext.lineCap = "round"),
      (__mmContext.lineJoin = "round"),
      (__mmContext.shadowColor = __mmStrokeColor),
      (__mmContext.shadowBlur = __mmBlur),
      __mmContext.beginPath(),
      __mmContext.moveTo(__mmTailX, __mmTailY),
      __mmContext.lineTo(__mmNeckX, __mmNeckY),
      __mmContext.moveTo(__mmWingTopX, __mmWingTopY),
      __mmContext.quadraticCurveTo(
        __mmTipX - __mmUnitX * 3,
        __mmTipY - __mmUnitY * 3,
        __mmTipX,
        __mmTipY,
      ),
      __mmContext.quadraticCurveTo(
        __mmTipX - __mmUnitX * 3,
        __mmTipY - __mmUnitY * 3,
        __mmWingBottomX,
        __mmWingBottomY,
      ),
      __mmContext.stroke(),
      __mmContext.restore());
  }
  // Always keep a dark-violet silhouette under the relationship color. It
  // prevents yellow, red, and purple arrows from disappearing into bright
  // snow, pale structures, or the purple-tinted HUD effects.
  __mmFpsBoostEnabled
    ? (__mmArrowPath(
        __mmCoreWidth + 5,
        0.9,
        0,
        "rgba(9,3,16,.96)",
      ),
      __mmArrowPath(__mmCoreWidth, 1, 0))
    : (__mmArrowPath(__mmCoreWidth + 12, 0.32, 18),
      __mmArrowPath(
        __mmCoreWidth + 5,
        0.94,
        2,
        "rgba(9,3,16,.96)",
      ),
      __mmArrowPath(__mmCoreWidth, 1, 8));
}
function __mmDrawNearestEnemyTarget(
  __mmContext,
  __mmEnemy,
  __mmLeft,
  __mmTop,
) {
  if (!__mmEnemy || !__mmIsEnemyPlayer(__mmEnemy)) return;
  const __mmX = Number(__mmEnemy.x) - __mmLeft,
    __mmY = Number(__mmEnemy.y) - __mmTop,
    __mmScale = Math.max(10, Number(__mmEnemy.scale) || 35),
    __mmPhase =
      (typeof performance !== "undefined" ? performance.now() : Date.now()) /
      620,
    __mmRadius = __mmScale + 11 + 1.5 * Math.sin(__mmPhase * 2);
  if (
    !Number.isFinite(__mmX) ||
    !Number.isFinite(__mmY) ||
    __mmX < -__mmRadius * 2 ||
    __mmX > _ + __mmRadius * 2 ||
    __mmY < -__mmRadius * 2 ||
    __mmY > L + __mmRadius * 2
  )
    return;
  (__mmContext.save(),
    (__mmContext.globalAlpha = 0.9),
    (__mmContext.strokeStyle = __mmEnemyColor),
    (__mmContext.fillStyle = __mmEnemyColor),
    (__mmContext.shadowColor = __mmEnemyColor),
    (__mmContext.shadowBlur = __mmFpsBoostEnabled ? 0 : 7),
    (__mmContext.lineWidth = 2.2),
    __mmContext.beginPath(),
    __mmContext.arc(__mmX, __mmY, __mmRadius, 0, Math.PI * 2),
    __mmContext.stroke());
  for (let __mmIndex = 0; __mmIndex < 3; __mmIndex++) {
    const __mmAngle = __mmPhase + (__mmIndex * Math.PI * 2) / 3,
      __mmCos = Math.cos(__mmAngle),
      __mmSin = Math.sin(__mmAngle),
      __mmPerpX = -__mmSin,
      __mmPerpY = __mmCos,
      // Each orbiting arrow points inward at the selected enemy.
      __mmTipRadius = __mmRadius + 2,
      __mmBaseRadius = __mmRadius + 12,
      __mmHalfWidth = 5,
      __mmTipX = __mmX + __mmCos * __mmTipRadius,
      __mmTipY = __mmY + __mmSin * __mmTipRadius,
      __mmBaseX = __mmX + __mmCos * __mmBaseRadius,
      __mmBaseY = __mmY + __mmSin * __mmBaseRadius;
    (__mmContext.beginPath(),
      __mmContext.moveTo(__mmTipX, __mmTipY),
      __mmContext.lineTo(
        __mmBaseX + __mmPerpX * __mmHalfWidth,
        __mmBaseY + __mmPerpY * __mmHalfWidth,
      ),
      __mmContext.lineTo(
        __mmBaseX - __mmPerpX * __mmHalfWidth,
        __mmBaseY - __mmPerpY * __mmHalfWidth,
      ),
      __mmContext.closePath(),
      __mmContext.fill());
  }
  __mmContext.restore();
}
function __mmDrawAestheticEntityMarker(
  __mmContext,
  __mmX,
  __mmY,
  __mmRadius,
  __mmColor,
  __mmDanger,
) {
  if (
    !Number.isFinite(__mmX) ||
    !Number.isFinite(__mmY) ||
    !Number.isFinite(__mmRadius)
  )
    return;
  if (!__mmSmoothVisualsEnabled) {
    (__mmContext.save(),
      (__mmContext.globalAlpha = 0.9),
      (__mmContext.strokeStyle = __mmColor),
      (__mmContext.lineWidth = 2),
      __mmContext.beginPath(),
      __mmContext.arc(__mmX, __mmY, __mmRadius, 0, Math.PI * 2),
      __mmContext.stroke(),
      __mmContext.restore());
    return;
  }
  const __mmNow = performance.now(),
    __mmPulse = __mmDanger ? 1 + Math.sin(__mmNow / 105) * 0.055 : 1,
    __mmOuterRadius = (__mmRadius + (__mmDanger ? 5 : 3)) * __mmPulse;
  (__mmContext.save(),
    (__mmContext.fillStyle = __mmColor),
    (__mmContext.strokeStyle = __mmColor),
    (__mmContext.shadowColor = __mmColor),
    (__mmContext.shadowBlur = __mmFpsBoostEnabled ? 0 : __mmDanger ? 15 : 8),
    (__mmContext.globalAlpha = __mmDanger ? 0.12 : 0.065),
    __mmContext.beginPath(),
    __mmContext.arc(__mmX, __mmY, __mmOuterRadius, 0, Math.PI * 2),
    __mmContext.fill(),
    (__mmContext.globalAlpha = __mmDanger ? 0.92 : 0.78),
    (__mmContext.lineWidth = __mmDanger ? 3 : 2),
    __mmContext.beginPath(),
    __mmContext.arc(__mmX, __mmY, __mmOuterRadius, 0, Math.PI * 2),
    __mmContext.stroke(),
    (__mmContext.shadowBlur = 0),
    (__mmContext.globalAlpha = 0.62),
    (__mmContext.strokeStyle = "rgba(9,3,16,.96)"),
    (__mmContext.lineWidth = 1.35),
    typeof __mmContext.setLineDash === "function" &&
      __mmContext.setLineDash([5, 7]),
    __mmContext.beginPath(),
    __mmContext.arc(
      __mmX,
      __mmY,
      Math.max(5, __mmOuterRadius - 4),
      0,
      Math.PI * 2,
    ),
    __mmContext.stroke(),
    __mmContext.restore());
}
function __mmDrawEsp() {
  if (!v || !v.alive || !k) return;
  try {
    const __mmLeft = oe - _ / 2,
      __mmTop = ae - L / 2;
    __mmDrawPredictionGhost(__mmLeft, __mmTop);
    if (
      (!__mmEspEnabled && !__mmEspLinesEnabled && !__mmEntityDangerEnabled) ||
      !Array.isArray(E) ||
      !Array.isArray(N)
    )
      return;
    const __mmOwnX = v.x - __mmLeft,
      __mmOwnY = v.y - __mmTop;
    (k.save(), (k.globalAlpha = 0.72));
    if (__mmEspLinesEnabled) {
      let __mmArrowCount = 0;
      const __mmArrowLimit = __mmFpsBoostEnabled ? 12 : Infinity;
      for (let __mmIndex = 0; __mmIndex < E.length; __mmIndex++) {
        const __mmPlayer = E[__mmIndex];
        if (
          !__mmPlayer ||
          !__mmPlayer.alive ||
          !__mmPlayer.visible ||
          __mmPlayer === v ||
          __mmPlayer.sid === v.sid
        )
          continue;
        const __mmFriendly =
            __mmIsFriendPlayer(__mmPlayer) || __mmSameTeam(__mmPlayer),
          __mmColor = __mmIsFriendPlayer(__mmPlayer)
            ? __mmFriendColor
            : __mmSameTeam(__mmPlayer)
              ? __mmAllyColor
              : __mmEnemyColor,
          __mmX = __mmPlayer.x - __mmLeft,
          __mmY = __mmPlayer.y - __mmTop;
        __mmDrawEspArrow(
          k,
          __mmOwnX,
          __mmOwnY,
          __mmX,
          __mmY,
          v.scale,
          __mmPlayer.scale,
          __mmColor,
          __mmFriendly,
        );
        if (++__mmArrowCount >= __mmArrowLimit) break;
      }
    }
    if (__mmEspEnabled || __mmEntityDangerEnabled) {
      ((k.lineWidth = 2), (k.globalAlpha = 0.9));
      let __mmPlayerCircleCount = 0;
      const __mmPlayerCircleLimit = __mmFpsBoostEnabled ? 12 : Infinity;
      for (let __mmIndex = 0; __mmIndex < E.length; __mmIndex++) {
        const __mmPlayer = E[__mmIndex];
        if (
          !__mmPlayer ||
          !__mmPlayer.alive ||
          !__mmPlayer.visible ||
          __mmPlayer === v ||
          __mmPlayer.sid === v.sid
        )
          continue;
        const __mmFriendly =
            __mmIsFriendPlayer(__mmPlayer) || __mmSameTeam(__mmPlayer),
          __mmColor = __mmIsFriendPlayer(__mmPlayer)
            ? __mmFriendColor
            : __mmSameTeam(__mmPlayer)
              ? __mmAllyColor
              : __mmEnemyColor,
          __mmDanger = !!(
            __mmEntityDangerEnabled &&
            !__mmFriendly &&
            Math.hypot(__mmPlayer.x - v.x, __mmPlayer.y - v.y) <=
              Math.max(650, __mmCombatRange)
          );
        if (!__mmEspEnabled && !__mmDanger) continue;
        __mmDrawAestheticEntityMarker(
          k,
          __mmPlayer.x - __mmLeft,
          __mmPlayer.y - __mmTop,
          Math.max(10, (__mmPlayer.scale || 35) + 5),
          __mmColor,
          __mmDanger,
        );
        if (++__mmPlayerCircleCount >= __mmPlayerCircleLimit) break;
      }
      let __mmAnimalCircleCount = 0;
      const __mmAnimalCircleLimit = __mmFpsBoostEnabled ? 10 : Infinity;
      for (let __mmIndex = 0; __mmIndex < N.length; __mmIndex++) {
        const __mmAnimal = N[__mmIndex];
        if (!__mmAnimal || !__mmAnimal.active || !__mmAnimal.visible) continue;
        const __mmAnimalDanger = !!(
            __mmEntityDangerEnabled && __mmAnimal.hostile
          ),
          __mmAnimalColor = __mmAnimalDanger ? __mmEnemyColor : "#48df79";
        if (!__mmEspEnabled && !__mmAnimalDanger) continue;
        __mmDrawAestheticEntityMarker(
          k,
          __mmAnimal.x - __mmLeft,
          __mmAnimal.y - __mmTop,
          Math.max(9, (__mmAnimal.scale || 35) + 4),
          __mmAnimalColor,
          __mmAnimalDanger,
        );
        if (++__mmAnimalCircleCount >= __mmAnimalCircleLimit) break;
      }
      __mmEspEnabled &&
        __mmDrawNearestEnemyTarget(k, __mmNearestEnemy(), __mmLeft, __mmTop);
    }
    k.restore();
  } catch (__mmError) {
    try {
      k && k.restore();
    } catch (__mmIgnore) {}
  }
}
function __mmDrawReloadArcs() {
  if (!__mmReloadArcsEnabled || !v || !v.alive || !k) return;
  const __mmLeft = oe - _ / 2,
    __mmTop = ae - L / 2,
    __mmNow = Date.now(),
    __mmEnemy = __mmNearestEnemy(),
    __mmPlayers = __mmEnemy && __mmEnemy !== v ? [v, __mmEnemy] : [v],
    __mmColors = ["#a855f7", "#d8b4fe", "#f0abfc"];
  try {
    k.save();
    for (let __mmIndex = 0; __mmIndex < __mmPlayers.length; __mmIndex++) {
      const __mmPlayer = __mmPlayers[__mmIndex];
      if (
        !__mmPlayer ||
        !__mmPlayer.alive ||
        (__mmPlayer !== v && !__mmPlayer.visible)
      )
        continue;
      const __mmX = Number(__mmPlayer.x) - __mmLeft,
        __mmY = Number(__mmPlayer.y) - __mmTop,
        __mmScale = Math.max(15, Number(__mmPlayer.scale) || 35);
      if (!ts(__mmX, __mmY, __mmScale + 25)) continue;
      const __mmRows = __mmVisualCooldownRows(__mmPlayer, __mmNow);
      for (let __mmRowIndex = 0; __mmRowIndex < __mmRows.length; __mmRowIndex++) {
        const __mmRow = __mmRows[__mmRowIndex],
          __mmSlot = Math.max(0, Math.min(2, Number(__mmRow.slot) || 0)),
          __mmRatio = Math.max(0, Math.min(1, Number(__mmRow.ratio) || 0)),
          __mmRadius = __mmScale + 8 + __mmSlot * 4.5,
          __mmStart = -Math.PI * 0.88,
          __mmSweep = Math.PI * 1.76,
          __mmColor = __mmColors[__mmSlot];
        ((k.shadowBlur = 0),
          (k.globalAlpha = 0.42),
          (k.strokeStyle = "rgba(9,3,16,.96)"),
          (k.lineWidth = 3.8),
          (k.lineCap = "round"),
          k.beginPath(),
          k.arc(__mmX, __mmY, __mmRadius, __mmStart, __mmStart + __mmSweep),
          k.stroke());
        if (__mmRatio <= 0.001) continue;
        ((k.globalAlpha = __mmRatio >= 0.995 ? 0.96 : 0.82),
          (k.strokeStyle = __mmColor),
          (k.shadowColor = __mmColor),
          (k.shadowBlur = __mmFpsBoostEnabled ? 0 : __mmRatio >= 0.995 ? 8 : 4),
          (k.lineWidth = 2.4),
          k.beginPath(),
          k.arc(
            __mmX,
            __mmY,
            __mmRadius,
            __mmStart,
            __mmStart + __mmSweep * __mmRatio,
          ),
          k.stroke());
      }
    }
    k.restore();
  } catch (__mmReloadArcError) {
    try {
      k && k.restore();
    } catch (__mmIgnore) {}
  }
}
const __mmOriginalStructureSprite = Di,
  __mmStructureTintCache = Object.create(null),
  __mmStructureTintImageCache = new WeakMap();
function __mmStructureOwnerSid(__mmObject) {
  if (!__mmObject) return null;
  const __mmOwner = __mmObject.owner;
  if (__mmOwner == null)
    return __mmObject.ownerSid != null
      ? __mmObject.ownerSid
      : __mmObject.ownerSID != null
        ? __mmObject.ownerSID
        : null;
  if (typeof __mmOwner === "object" && __mmOwner.sid != null)
    return __mmOwner.sid;
  if (typeof __mmOwner === "number" || typeof __mmOwner === "string")
    return __mmOwner;
  return __mmObject.ownerSid != null
    ? __mmObject.ownerSid
    : __mmObject.ownerSID != null
      ? __mmObject.ownerSID
      : null;
}
function __mmStructureOwnerPlayer(__mmObject) {
  if (!__mmObject) return null;
  const __mmOwner = __mmObject.owner,
    __mmOwnerSid = __mmStructureOwnerSid(__mmObject);
  if (__mmOwner === v) return v;
  if (__mmOwnerSid != null && typeof Rt === "function") {
    const __mmPlayer = Rt(__mmOwnerSid);
    if (__mmPlayer) return __mmPlayer;
  }
  return typeof __mmOwner === "object" ? __mmOwner : null;
}
function __mmOwnStructure(__mmObject) {
  if (!v || !__mmObject) return !1;
  const __mmOwner = __mmObject.owner,
    __mmOwnerSid = __mmStructureOwnerSid(__mmObject);
  return !!(
    __mmOwner === v ||
    (__mmOwnerSid != null && String(__mmOwnerSid) === String(v.sid))
  );
}
function __mmTintableStructure(__mmObject) {
  const __mmItem = __mmObject && b && b.list && b.list[__mmObject.id];
  // Every server-owned player placeable carries an item id and owner. Keeping
  // this generic covers walls, pads, teleporters, mills, traps, spikes and
  // turrets even when MooMoo changes an item's display name.
  return !!(
    __mmObject &&
    __mmObject.isItem &&
    __mmStructureOwnerSid(__mmObject) != null &&
    __mmItem
  );
}
function __mmFriendlyStructure(__mmObject) {
  if (!v || !__mmObject || __mmStructureOwnerSid(__mmObject) == null) return !1;
  if (__mmOwnStructure(__mmObject)) return !0;
  const __mmOwner = __mmStructureOwnerPlayer(__mmObject);
  if (!__mmOwner) return !1;
  if (__mmSameTeam(__mmOwner)) return !0;
  return __mmIsFriendPlayer(__mmOwner);
}
function __mmStructureRelationship(__mmObject) {
  return __mmOwnStructure(__mmObject)
    ? "own"
    : __mmFriendlyStructure(__mmObject)
      ? "friendly"
      : "enemy";
}
function __mmStructureRelationshipColor(__mmRelationship) {
  return __mmRelationship === "own"
    ? __mmOwnColor
    : __mmRelationship === "friendly"
      ? __mmAllyColor
      : __mmEnemyColor;
}
function __mmTintedStructureSprite(
  __mmObject,
  __mmRelationship,
  __mmProvidedBase,
) {
  const __mmBase = __mmProvidedBase || __mmOriginalStructureSprite(__mmObject),
    __mmKind =
      __mmRelationship === "own"
        ? "own"
        : __mmRelationship === "friendly" || __mmRelationship === !0
          ? "friendly"
          : "enemy",
    __mmColor = __mmStructureRelationshipColor(__mmKind);
  if (!__mmBase || !__mmBase.width || !__mmBase.height) return __mmBase;
  let __mmImageTints =
    typeof __mmBase === "object"
      ? __mmStructureTintImageCache.get(__mmBase)
      : null;
  if (!__mmImageTints && typeof __mmBase === "object") {
    (__mmImageTints = Object.create(null),
      __mmStructureTintImageCache.set(__mmBase, __mmImageTints));
  }
  const __mmTintKind = __mmKind + ":" + __mmColor;
  if (__mmImageTints && __mmImageTints[__mmTintKind])
    return __mmImageTints[__mmTintKind];
  const __mmAssetKey = String(
      __mmBase.currentSrc || __mmBase.src || "native",
    ),
    __mmKey = String(__mmObject.id) + ":" + __mmColor + ":" +
      __mmAssetKey + ":" + __mmBase.width + "x" + __mmBase.height;
  let __mmTinted = __mmStructureTintCache[__mmKey];
  if (__mmTinted) {
    __mmImageTints && (__mmImageTints[__mmTintKind] = __mmTinted);
    return __mmTinted;
  }
  __mmTinted = document.createElement("canvas");
  __mmTinted.width = __mmBase.width;
  __mmTinted.height = __mmBase.height;
  const __mmContext = __mmTinted.getContext("2d");
  (__mmContext.drawImage(__mmBase, 0, 0),
    (__mmContext.globalCompositeOperation = "source-atop"),
    (__mmContext.globalAlpha = __mmKind === "own" ? 0.7 : 0.8),
    (__mmContext.fillStyle = __mmColor),
    __mmContext.fillRect(0, 0, __mmTinted.width, __mmTinted.height),
    (__mmContext.globalCompositeOperation = "source-over"),
    (__mmContext.globalAlpha = 0.34),
    __mmContext.drawImage(__mmBase, 0, 0));
  (__mmStructureTintCache[__mmKey] = __mmTinted,
    __mmImageTints && (__mmImageTints[__mmTintKind] = __mmTinted));
  return __mmTinted;
}
// Tint the official sprite itself instead of painting a second, position-based
// copy over the object. MooMoo's renderer now owns every transform and culling
// decision, so ownership color cannot drift with camera movement or disappear
// behind Kitty's FPS overlay budget.
Di = function (__mmObject) {
  const __mmBase = __mmOriginalStructureSprite.apply(this, arguments);
  if (!v || !v.alive || !__mmTintableStructure(__mmObject)) return __mmBase;
  try {
    return __mmTintedStructureSprite(
      __mmObject,
      __mmStructureRelationship(__mmObject),
      __mmBase,
    );
  } catch (__mmTintError) {
    return __mmBase;
  }
};
const __mmBreakableLabelRange = 950,
  __mmBreakableLabelLimit = 72;
let __mmObjectSnapshotAt = 0,
  __mmObjectSnapshotSource = null,
  __mmObjectSnapshotLength = -1,
  __mmObjectSnapshotCache = {
    all: [],
    breakables: [],
    traps: [],
    spikes: [],
    turrets: [],
    mills: [],
  };
function __mmActiveObjectSnapshot(__mmForce) {
  const __mmSource = Array.isArray(ge) ? ge : null,
    __mmNow = performance.now(),
    __mmRefreshMs = Math.max(40, Math.min(75, __mmFastCheckMs() * 2));
  if (
    !__mmForce &&
    __mmSource === __mmObjectSnapshotSource &&
    (__mmSource ? __mmSource.length : 0) === __mmObjectSnapshotLength &&
    __mmNow - __mmObjectSnapshotAt < __mmRefreshMs
  )
    return __mmObjectSnapshotCache;
  const __mmNext = {
      all: [],
      breakables: [],
      traps: [],
      spikes: [],
      turrets: [],
      mills: [],
    },
    __mmLabelRange = __mmFpsBoostEnabled
      ? Math.min(__mmBreakableLabelRange, 600)
      : __mmBreakableLabelRange,
    __mmLabelLimit = __mmFpsBoostEnabled
      ? Math.min(__mmBreakableLabelLimit, 12)
      : __mmBreakableLabelLimit,
    __mmLabelRangeSquared = __mmLabelRange * __mmLabelRange;
  if (__mmSource)
    for (let __mmIndex = 0; __mmIndex < __mmSource.length; __mmIndex++) {
      const __mmObject = __mmSource[__mmIndex];
      if (!__mmObject || !__mmObject.active) continue;
      __mmNext.all.push(__mmObject);
      const __mmData = b && b.list && b.list[__mmObject.id],
        __mmName = String((__mmData && __mmData.name) || "").toLowerCase();
      __mmObject.trap && __mmNext.traps.push(__mmObject);
      __mmName.includes("spikes") && __mmNext.spikes.push(__mmObject);
      __mmName === "turret" && __mmNext.turrets.push(__mmObject);
      (__mmName === "windmill" ||
        __mmName === "faster windmill" ||
        __mmName === "power mill") &&
        __mmNext.mills.push(__mmObject);
      if (
        v &&
        v.alive &&
        Number.isFinite(Number(__mmObject.health)) &&
        Number(__mmObject.health) > 0
      ) {
        const __mmDx = Number(__mmObject.x) - Number(v.x),
          __mmDy = Number(__mmObject.y) - Number(v.y),
          __mmDistanceSquared = __mmDx * __mmDx + __mmDy * __mmDy;
        Number.isFinite(__mmDistanceSquared) &&
          __mmDistanceSquared <= __mmLabelRangeSquared &&
          __mmNext.breakables.push({
            object: __mmObject,
            distanceSquared: __mmDistanceSquared,
          });
      }
    }
  if (__mmNext.breakables.length > __mmLabelLimit) {
    __mmNext.breakables.sort(
      (__mmFirst, __mmSecond) =>
        __mmFirst.distanceSquared - __mmSecond.distanceSquared,
    );
    __mmNext.breakables.length = __mmLabelLimit;
  }
  ((__mmObjectSnapshotAt = __mmNow),
    (__mmObjectSnapshotSource = __mmSource),
    (__mmObjectSnapshotLength = __mmSource ? __mmSource.length : 0),
    (__mmObjectSnapshotCache = __mmNext));
  return __mmNext;
}
let __mmGroundGridFrameDrawn = !1;
function __mmDrawGroundGrid(__mmLeft, __mmTop) {
  if (
    __mmHudMenuOpen ||
    __mmNativeMenuOpen ||
    !__mmGroundGridEnabled ||
    (document.documentElement &&
      document.documentElement.getAttribute("data-kitty-ground-grid") === "0") ||
    !v ||
    !v.alive ||
    !k
  )
    return;
  const __mmViewLeft = Number.isFinite(Number(__mmLeft))
      ? Number(__mmLeft)
      : Number(oe) - Number(_) / 2,
    __mmViewTop = Number.isFinite(Number(__mmTop))
      ? Number(__mmTop)
      : Number(ae) - Number(L) / 2,
    __mmViewWidth = Math.max(1, Number(_) || k.canvas.width || 1),
    __mmViewHeight = Math.max(1, Number(L) || k.canvas.height || 1),
    __mmMinorStep = 100,
    __mmMajorStep = 500,
    // The game context already maps these world-space viewport units onto the
    // physical canvas. Applying the zoom ratio again double-scaled the grid
    // toward the top-left. One cell of overscan prevents edge gaps and keeps
    // full-screen coverage while the camera moves between grid coordinates.
    __mmOverscan = __mmMinorStep,
    __mmMinWorldX = __mmViewLeft - __mmOverscan,
    __mmMaxWorldX = __mmViewLeft + __mmViewWidth + __mmOverscan,
    __mmMinWorldY = __mmViewTop - __mmOverscan,
    __mmMaxWorldY = __mmViewTop + __mmViewHeight + __mmOverscan,
    __mmMinScreenX = -__mmOverscan,
    __mmMaxScreenX = __mmViewWidth + __mmOverscan,
    __mmMinScreenY = -__mmOverscan,
    __mmMaxScreenY = __mmViewHeight + __mmOverscan;
  const __mmTraceGrid = function (__mmStep, __mmSkipMajor) {
    k.beginPath();
    let __mmWorld = Math.ceil(__mmMinWorldX / __mmStep) * __mmStep;
    for (; __mmWorld <= __mmMaxWorldX; __mmWorld += __mmStep) {
      if (__mmSkipMajor && __mmWorld % __mmMajorStep === 0) continue;
      const __mmScreenX = Math.round(__mmWorld - __mmViewLeft) + 0.5;
      (k.moveTo(__mmScreenX, __mmMinScreenY),
        k.lineTo(__mmScreenX, __mmMaxScreenY));
    }
    __mmWorld = Math.ceil(__mmMinWorldY / __mmStep) * __mmStep;
    for (; __mmWorld <= __mmMaxWorldY; __mmWorld += __mmStep) {
      if (__mmSkipMajor && __mmWorld % __mmMajorStep === 0) continue;
      const __mmScreenY = Math.round(__mmWorld - __mmViewTop) + 0.5;
      (k.moveTo(__mmMinScreenX, __mmScreenY),
        k.lineTo(__mmMaxScreenX, __mmScreenY));
    }
    k.stroke();
  };
  try {
    (k.save(),
      (k.globalAlpha = __mmFpsBoostEnabled ? 0.13 : 0.16),
      (k.strokeStyle = "#6d28d9"),
      (k.lineWidth = 1),
      __mmTraceGrid(__mmMinorStep, !0),
      (k.globalAlpha = __mmFpsBoostEnabled ? 0.22 : 0.28),
      (k.strokeStyle = "#c084fc"),
      (k.lineWidth = 1.5),
      __mmTraceGrid(__mmMajorStep, !1),
      k.restore());
  } catch (__mmGroundGridError) {
    try {
      k.restore();
    } catch (__mmGroundGridRestoreError) {}
  }
}
function __mmDrawAutoSpikeSpamGhost() {
  const __mmGhost = __mmAutoSpikeSpamGhost,
    __mmData = __mmGhost && b && b.list && b.list[__mmGhost.item];
  if (!v || !v.alive || !__mmGhost || !__mmData || !k) return;
  const __mmLeft = oe - _ / 2,
    __mmTop = ae - L / 2,
    __mmX = __mmGhost.x - __mmLeft,
    __mmY = __mmGhost.y - __mmTop;
  if (!ts(__mmX, __mmY, __mmGhost.scale + 12)) return;
  const __mmSprite = __mmTintedStructureSprite(__mmData, "friendly");
  (k.save(),
    (k.globalAlpha = 0.42),
    k.translate(__mmX, __mmY),
    k.rotate(__mmGhost.angle),
    k.drawImage(
      __mmSprite,
      -__mmSprite.width / 2,
      -__mmSprite.height / 2,
    ),
    k.rotate(-__mmGhost.angle),
    (k.globalAlpha = 0.9),
    (k.strokeStyle = "#c084fc"),
    (k.lineWidth = 2),
    k.setLineDash([5, 4]),
    k.beginPath(),
    k.arc(0, 0, __mmGhost.scale + 3, 0, Math.PI * 2),
    k.stroke(),
    k.restore());
}
function __mmBreakableState(__mmObject) {
  if (!__mmObject || !Number.isFinite(Number(__mmObject.health))) return null;
  const __mmBaseHealth = Number(__mmObject.health);
  if (__mmBaseHealth <= 0) return null;
  let __mmState = __mmBreakableHealth.get(__mmObject);
  if (
    !__mmState ||
    String(__mmState.sid) !== String(__mmObject.sid) ||
    __mmState.baseHealth !== __mmBaseHealth
  ) {
    __mmState = {
      sid: __mmObject.sid,
      baseHealth: __mmBaseHealth,
      health: __mmBaseHealth,
    };
    __mmBreakableHealth.set(__mmObject, __mmState);
  }
  return __mmState;
}
function __mmPlayerHatData(__mmPlayer) {
  if (!__mmPlayer || !Array.isArray(Ze)) return null;
  for (let __mmIndex = 0; __mmIndex < Ze.length; __mmIndex++)
    if (Ze[__mmIndex].id === __mmPlayer.skinIndex) return Ze[__mmIndex];
  return null;
}
function __mmToolCooldownDuration(__mmPlayer, __mmWeaponId) {
  const __mmWeapon = b && b.weapons && b.weapons[__mmWeaponId];
  if (!__mmWeapon) return 0;
  const __mmBaseSpeed = Number(__mmWeapon.speed),
    __mmHat = __mmPlayerHatData(__mmPlayer),
    __mmHatSpeed = Number(__mmHat && __mmHat.atkSpd),
    __mmMultiplier = Number.isFinite(__mmHatSpeed) && __mmHatSpeed > 0
      ? __mmHatSpeed
      : 1;
  return Number.isFinite(__mmBaseSpeed) && __mmBaseSpeed > 0
    ? Math.max(1, __mmBaseSpeed * __mmMultiplier)
    : 0;
}
function __mmTurretCooldownDuration(__mmPlayer) {
  const __mmHat = Array.isArray(Ze)
    ? Ze.find(function (__mmEntry) {
        return __mmEntry && Number(__mmEntry.id) === __mmTurretGear;
      })
    : null,
    __mmRate = Number(__mmHat && __mmHat.turret && __mmHat.turret.rate);
  return Number.isFinite(__mmRate) && __mmRate > 0 ? __mmRate : 2500;
}
function __mmCooldownStateForSid(__mmPlayerSid, __mmNow = Date.now()) {
  if (__mmPlayerSid == null) return null;
  const __mmKey = String(__mmPlayerSid);
  return (
    __mmPlayerToolCooldowns[__mmKey] ||
    (__mmPlayerToolCooldowns[__mmKey] = {
      weapons: Object.create(null),
      slots: [null, null],
      turret: null,
      updatedAt: __mmNow,
      advancedAt: __mmNow,
    })
  );
}
function __mmPlayerWeaponSlot(__mmPlayer, __mmWeaponId) {
  const __mmId = Number(__mmWeaponId);
  if (!Number.isInteger(__mmId)) return null;
  if (__mmPlayer && Array.isArray(__mmPlayer.weapons)) {
    if (Number(__mmPlayer.weapons[0]) === __mmId) return 0;
    if (Number(__mmPlayer.weapons[1]) === __mmId) return 1;
  }
  if (__mmPlayer && Number(__mmPlayer.primaryIndex) === __mmId) return 0;
  if (__mmPlayer && Number(__mmPlayer.secondaryIndex) === __mmId) return 1;
  return __mmId >= 9 ? 1 : 0;
}
function __mmProjectileWeapon(__mmPlayer, __mmProjectile) {
  if (!__mmPlayer || !b || !b.weapons) return null;
  const __mmCandidates = [],
    __mmSeen = new Set();
  function __mmAdd(__mmWeaponId) {
    const __mmId = Number(__mmWeaponId),
      __mmData = b.weapons[__mmId];
    if (
      !Number.isInteger(__mmId) ||
      __mmSeen.has(__mmId) ||
      !__mmData ||
      __mmData.projectile == null
    )
      return;
    (__mmSeen.add(__mmId), __mmCandidates.push(__mmId));
  }
  if (
    v &&
    String(__mmPlayer.sid) === String(v.sid) &&
    __mmLastSelectionWasWeapon &&
    Date.now() - __mmLastSelectionAt <= 300
  )
    __mmAdd(__mmLastSelectionItem);
  (__mmAdd(__mmPlayer.weaponIndex),
    Array.isArray(__mmPlayer.weapons) &&
      __mmPlayer.weapons.forEach(__mmAdd),
    __mmAdd(__mmPlayer.primaryIndex),
    __mmAdd(__mmPlayer.secondaryIndex));
  if (!__mmCandidates.length || !b.projectiles) return null;
  const __mmLiveSpeed = Number(__mmProjectile && __mmProjectile.speed),
    __mmLiveDamage = Number(__mmProjectile && __mmProjectile.dmg),
    __mmLiveScale = Number(__mmProjectile && __mmProjectile.scale);
  let __mmBest = __mmCandidates[0],
    __mmBestScore = Infinity;
  for (let __mmIndex = 0; __mmIndex < __mmCandidates.length; __mmIndex++) {
    const __mmWeaponId = __mmCandidates[__mmIndex],
      __mmWeapon = b.weapons[__mmWeaponId],
      __mmData = b.projectiles[__mmWeapon.projectile],
      __mmSpeed = Number(__mmData && __mmData.speed),
      __mmDamage = Number(__mmData && __mmData.dmg),
      __mmScale = Number(__mmData && __mmData.scale);
    let __mmScore = 0,
      __mmEvidence = 0;
    if (Number.isFinite(__mmLiveSpeed) && Number.isFinite(__mmSpeed)) {
      (__mmEvidence++,
        (__mmScore +=
          Math.abs(__mmLiveSpeed - __mmSpeed) /
          Math.max(0.15, Math.abs(__mmSpeed))));
    }
    if (Number.isFinite(__mmLiveDamage) && Number.isFinite(__mmDamage)) {
      (__mmEvidence++,
        (__mmScore +=
          Math.abs(__mmLiveDamage - __mmDamage) /
          Math.max(5, Math.abs(__mmDamage))));
    }
    if (Number.isFinite(__mmLiveScale) && Number.isFinite(__mmScale)) {
      (__mmEvidence++,
        (__mmScore +=
          Math.abs(__mmLiveScale - __mmScale) /
          Math.max(5, Math.abs(__mmScale))));
    }
    __mmEvidence || (__mmScore = Infinity);
    if (__mmScore < __mmBestScore)
      ((__mmBestScore = __mmScore), (__mmBest = __mmWeaponId));
  }
  // A player-owned Turret Gear bullet must not be guessed as their currently
  // held bow or musket. Reject poor projectile-data matches instead.
  return __mmBestScore <= 0.38 ? __mmBest : null;
}
function __mmProjectileIsTurretGearShot(__mmPlayer, __mmProjectile) {
  if (!__mmPlayer || !__mmProjectile || !b || !b.projectiles) return !1;
  const __mmTurretProjectile = b.projectiles[1];
  if (!__mmTurretProjectile) return !1;
  const __mmLiveSpeed = Number(__mmProjectile.speed),
    __mmLiveDamage = Number(__mmProjectile.dmg),
    __mmLiveScale = Number(__mmProjectile.scale),
    __mmSpeed = Number(__mmTurretProjectile.speed),
    __mmDamage = Number(__mmTurretProjectile.dmg),
    __mmScale = Number(__mmTurretProjectile.scale),
    __mmLooksLikeTurret =
      (!Number.isFinite(__mmLiveSpeed) ||
        !Number.isFinite(__mmSpeed) ||
        Math.abs(__mmLiveSpeed - __mmSpeed) <= Math.max(0.08, __mmSpeed * 0.08)) &&
      (!Number.isFinite(__mmLiveDamage) ||
        !Number.isFinite(__mmDamage) ||
        Math.abs(__mmLiveDamage - __mmDamage) <= 1) &&
      (!Number.isFinite(__mmLiveScale) ||
        !Number.isFinite(__mmScale) ||
        Math.abs(__mmLiveScale - __mmScale) <= 2),
    __mmDirectPlayerOwner = __mmProjectilePlayerOwner(__mmProjectile),
    __mmHasTurretEvidence = !!(
      (Number.isFinite(__mmLiveSpeed) && Number.isFinite(__mmSpeed)) ||
      (Number.isFinite(__mmLiveDamage) && Number.isFinite(__mmDamage)) ||
      (Number.isFinite(__mmLiveScale) && Number.isFinite(__mmScale))
    );
  // Projectile type 1 is exclusive to Turret Gear/structures in the current
  // item table. Structure owners were rejected before this helper, so a data
  // match here remains valid even after a fast client has restored its hat.
  return !!(
    __mmHasTurretEvidence &&
    __mmLooksLikeTurret &&
    __mmDirectPlayerOwner &&
    String(__mmDirectPlayerOwner.sid) === String(__mmPlayer.sid)
  );
}
function __mmProjectilePlayerOwner(__mmProjectile) {
  const __mmOwner = __mmProjectile && __mmProjectile.owner;
  if (!__mmOwner || typeof __mmOwner !== "object") return null;
  // Nested owners are structures such as turrets; their shots must not reset
  // a handheld weapon bar on the structure's owner.
  if (__mmOwner.owner && !Array.isArray(__mmOwner.weapons)) return null;
  if (__mmOwner === v) return v;
  if (
    Array.isArray(__mmOwner.weapons) ||
    Number.isInteger(Number(__mmOwner.weaponIndex))
  )
    return __mmOwner;
  if (__mmOwner.sid == null || typeof Rt !== "function") return null;
  try {
    return Rt(__mmOwner.sid) || null;
  } catch (__mmLookupError) {
    return null;
  }
}
function __mmObserveProjectileCooldowns() {
  const __mmNow = Date.now();
  if (
    (!__mmCooldownBarsEnabled && !__mmMusketRechargeEnabled) ||
    !Array.isArray(Ve) ||
    __mmNow - __mmProjectileCooldownLastScanAt < 20
  )
    return;
  __mmProjectileCooldownLastScanAt = __mmNow;
  for (let __mmIndex = 0; __mmIndex < Ve.length; __mmIndex++) {
    const __mmProjectile = Ve[__mmIndex];
    if (!__mmProjectile || typeof __mmProjectile !== "object") continue;
    const __mmPrevious = __mmProjectileCooldownStates.get(__mmProjectile),
      __mmSid = __mmProjectile.sid == null ? "" : String(__mmProjectile.sid),
      __mmRange = Number(__mmProjectile.range),
      __mmNewGeneration = !!(
        __mmProjectile.active &&
        (!__mmPrevious ||
          !__mmPrevious.active ||
          __mmPrevious.sid !== __mmSid ||
          (Number.isFinite(__mmRange) &&
            Number.isFinite(__mmPrevious.range) &&
            __mmRange > __mmPrevious.range + 20))
      );
    __mmProjectileCooldownStates.set(__mmProjectile, {
      active: !!__mmProjectile.active,
      sid: __mmSid,
      range: __mmRange,
    });
    if (!__mmNewGeneration) continue;
    const __mmPlayer = __mmProjectilePlayerOwner(__mmProjectile);
    if (!__mmPlayer || __mmPlayer.sid == null) continue;
    if (__mmProjectileIsTurretGearShot(__mmPlayer, __mmProjectile)) {
      __mmTrackPlayerTurretCooldown(__mmPlayer.sid, "projectile");
      continue;
    }
    const __mmWeapon = __mmProjectileWeapon(__mmPlayer, __mmProjectile);
    __mmWeapon != null &&
      __mmTrackPlayerToolCooldown(__mmPlayer.sid, __mmWeapon, "projectile");
  }
}
function __mmObserveOutgoingProjectileAttack(__mmArguments) {
  if (
    !__mmArguments ||
    __mmArguments[0] !== "F" ||
    Number(__mmArguments[1]) !== 1 ||
    !v ||
    !v.alive ||
    !b ||
    !b.weapons
  )
    return;
  let __mmWeapon = null;
  if (Date.now() - __mmLastSelectionAt <= 180) {
    if (!__mmLastSelectionWasWeapon) return;
    __mmWeapon = Number(__mmLastSelectionItem);
  } else if (Number(v.buildIndex) < 0) {
    __mmWeapon = Number(v.weaponIndex);
  }
  const __mmData = b.weapons[__mmWeapon];
  if (
    !Number.isInteger(__mmWeapon) ||
    !__mmData ||
    __mmData.projectile == null ||
    __mmWeaponIsReloading(__mmWeapon)
  )
    return;
  // Projectile attacks do not consistently emit the melee swing callback.
  // Start the local bar optimistically; the spawned projectile below corrects
  // the timestamp without waiting for a server confirmation round trip.
  __mmTrackPlayerToolCooldown(v.sid, __mmWeapon, "outgoing-projectile");
}
function __mmTrackPlayerToolCooldown(
  __mmPlayerSid,
  __mmWeaponId,
  __mmSource = "swing",
) {
  if (__mmPlayerSid == null) return;
  let __mmPlayer = null;
  try {
    __mmPlayer = Rt(__mmPlayerSid);
  } catch (__mmLookupError) {}
  if (
    !__mmPlayer &&
    v &&
    v.sid != null &&
    String(v.sid) === String(__mmPlayerSid)
  )
    __mmPlayer = v;
  const __mmResolvedWeapon = Number(
      __mmWeaponId == null && __mmPlayer
        ? __mmPlayer.weaponIndex
        : __mmWeaponId,
    ),
    __mmDuration = __mmToolCooldownDuration(
      __mmPlayer,
      __mmResolvedWeapon,
    );
  if (!Number.isInteger(__mmResolvedWeapon) || !__mmDuration) return;
  const __mmKey = String(__mmPlayerSid),
    __mmNow = Date.now(),
    __mmState = __mmCooldownStateForSid(__mmKey, __mmNow);
  __mmAdvancePlayerToolCooldowns(__mmPlayer, __mmNow);
  Array.isArray(__mmState.slots) || (__mmState.slots = [null, null]);
  const __mmSlot = __mmPlayerWeaponSlot(__mmPlayer, __mmResolvedWeapon);
  (__mmSlot === 0 || __mmSlot === 1) &&
    (__mmState.slots[__mmSlot] = __mmResolvedWeapon);
  const __mmExisting = __mmState.weapons[String(__mmResolvedWeapon)];
  const __mmProjectileDedupeWindow = Math.min(
    350,
    Math.max(90, __mmDuration * 0.5),
  );
  if (
    __mmExisting &&
    __mmNow - Number(__mmExisting.startedAt) <= __mmProjectileDedupeWindow &&
    (__mmSource === "projectile" ||
      __mmSource === "outgoing-projectile" ||
      __mmExisting.source === "projectile" ||
      __mmExisting.source === "outgoing-projectile")
  ) {
    ((__mmExisting.source =
      __mmSource === "projectile" ? __mmSource : __mmExisting.source),
      (__mmExisting.liveSeenAt = __mmNow),
      (__mmState.updatedAt = __mmNow));
    return;
  }
  ((__mmState.weapons[String(__mmResolvedWeapon)] = {
    weapon: __mmResolvedWeapon,
    duration: __mmDuration,
    remaining: __mmDuration,
    startedAt: __mmNow,
    readyAt: __mmNow + __mmDuration,
    // Projectile shots begin locally, then reconcile to the spawned object or
    // any live reload value the game exposes for this weapon.
    outgoingAt: __mmSource === "outgoing-projectile" ? __mmNow : 0,
    source: __mmSource,
    liveSeen: !1,
  }),
    (__mmState.updatedAt = __mmNow),
    (__mmState.advancedAt = __mmNow));
}
function __mmTrackPlayerTurretCooldown(
  __mmPlayerSid,
  __mmSource = "attack",
) {
  if (__mmPlayerSid == null) return;
  let __mmPlayer = null;
  try {
    __mmPlayer = Rt(__mmPlayerSid);
  } catch (__mmTurretPlayerLookupError) {}
  if (
    !__mmPlayer &&
    v &&
    v.sid != null &&
    String(v.sid) === String(__mmPlayerSid)
  )
    __mmPlayer = v;
  const __mmNow = Date.now(),
    __mmState = __mmCooldownStateForSid(__mmPlayerSid, __mmNow),
    __mmDuration = __mmTurretCooldownDuration(__mmPlayer),
    __mmExisting = __mmState && __mmState.turret;
  __mmAdvancePlayerToolCooldowns(__mmPlayer, __mmNow);
  if (
    __mmExisting &&
    (Number(__mmExisting.remaining) > 0 ||
      __mmNow - Number(__mmExisting.startedAt) <= 350)
  ) {
    ((__mmExisting.source =
      __mmSource === "projectile" ? "projectile" : __mmExisting.source),
      (__mmExisting.observedAt = __mmNow),
      (__mmState.updatedAt = __mmNow));
    if (v && String(__mmPlayerSid) === String(v.sid))
      __mmTurretReloadUntil = Math.max(
        __mmTurretReloadUntil,
        Number(__mmExisting.readyAt) || 0,
      );
    return;
  }
  __mmState.turret = {
    duration: __mmDuration,
    remaining: __mmDuration,
    startedAt: __mmNow,
    readyAt: __mmNow + __mmDuration,
    observedAt: __mmNow,
    source: __mmSource,
  };
  ((__mmState.updatedAt = __mmNow), (__mmState.advancedAt = __mmNow));
  if (v && String(__mmPlayerSid) === String(v.sid))
    __mmTurretReloadUntil = Math.max(
      __mmTurretReloadUntil,
      __mmNow + __mmDuration,
    );
}
function __mmAdvancePlayerToolCooldowns(__mmPlayer, __mmNow) {
  if (!__mmPlayer || __mmPlayer.sid == null) return null;
  const __mmState = __mmPlayerToolCooldowns[String(__mmPlayer.sid)];
  if (!__mmState) return null;
  const __mmPreviousAt = Number.isFinite(Number(__mmState.advancedAt))
      ? Number(__mmState.advancedAt)
      : Number(__mmState.updatedAt) || __mmNow,
    __mmElapsed = Math.max(0, __mmNow - __mmPreviousAt);
  __mmState.advancedAt = __mmNow;
  if (__mmState.turret && __mmElapsed) {
    const __mmTurretRemaining = Number.isFinite(
      Number(__mmState.turret.remaining),
    )
      ? Number(__mmState.turret.remaining)
      : Math.max(0, Number(__mmState.turret.readyAt) - __mmPreviousAt || 0);
    ((__mmState.turret.remaining = Math.max(
      0,
      __mmTurretRemaining - __mmElapsed,
    )),
      (__mmState.turret.readyAt =
        __mmNow + __mmState.turret.remaining));
  }
  if (!__mmState.weapons) return __mmState;
  // MooMoo only reloads a weapon while that weapon is actually held. Matching
  // that rule prevents a put-away secondary from appearing ready too early.
  const __mmHasAssumedLocalRecharge = !!(
      v &&
      v.sid != null &&
      String(v.sid) === String(__mmPlayer.sid) &&
      __mmWeaponRechargeActiveWeapon != null
    );
  if (
    !__mmElapsed ||
    (Number(__mmPlayer.buildIndex) >= 0 && !__mmHasAssumedLocalRecharge)
  )
    return __mmState;
  const __mmLocalRechargeWeapon = __mmHasAssumedLocalRecharge
      ? Number(__mmWeaponRechargeActiveWeapon)
      : Number(__mmPlayer.weaponIndex),
    __mmWeaponId = __mmLocalRechargeWeapon,
    __mmEntry = __mmState.weapons[String(__mmWeaponId)];
  if (!__mmEntry) return __mmState;
  const __mmRemaining = Number.isFinite(Number(__mmEntry.remaining))
    ? Number(__mmEntry.remaining)
    : Math.max(0, Number(__mmEntry.readyAt) - __mmPreviousAt || 0);
  ((__mmEntry.remaining = Math.max(0, __mmRemaining - __mmElapsed)),
    (__mmEntry.readyAt = __mmNow + __mmEntry.remaining));
  return __mmState;
}
function __mmTurretCooldownRemaining(__mmPlayer, __mmNow = Date.now()) {
  if (!__mmPlayer || __mmPlayer.sid == null) return 0;
  const __mmState = __mmAdvancePlayerToolCooldowns(__mmPlayer, __mmNow),
    __mmTracked = Math.max(
      0,
      Number(__mmState && __mmState.turret && __mmState.turret.remaining) || 0,
    );
  if (v && String(__mmPlayer.sid) === String(v.sid))
    return Math.max(__mmTracked, Math.max(0, __mmTurretReloadUntil - __mmNow));
  return __mmTracked;
}
function __mmReconcileLocalToolCooldown(
  __mmPlayer,
  __mmWeaponId,
  __mmNow,
  __mmKnownState,
) {
  const __mmId = Number(__mmWeaponId),
    __mmIsLocal = !!(
      v &&
      __mmPlayer &&
      v.sid != null &&
      String(v.sid) === String(__mmPlayer.sid)
    );
  let __mmState = __mmKnownState ||
      (__mmPlayer && __mmPlayer.sid != null
        ? __mmPlayerToolCooldowns[String(__mmPlayer.sid)]
        : null),
    __mmEntry =
      __mmState && __mmState.weapons
        ? __mmState.weapons[String(__mmId)]
        : null;
  if (!__mmIsLocal || !Number.isInteger(__mmId))
    return {
      state: __mmState,
      entry: __mmEntry,
      hasLive: !1,
      live: null,
    };
  const __mmReloads = v.reloads,
    __mmHasLive = !!(
      __mmReloads &&
      Object.prototype.hasOwnProperty.call(__mmReloads, __mmId) &&
      Number.isFinite(Number(__mmReloads[__mmId]))
    ),
    __mmLive = __mmHasLive
      ? Math.max(0, Number(__mmReloads[__mmId]))
      : null,
    __mmHeld =
      (Number(v.buildIndex) < 0 && Number(v.weaponIndex) === __mmId) ||
      Number(__mmWeaponRechargeActiveWeapon) === __mmId,
    __mmBaseDuration = __mmToolCooldownDuration(v, __mmId);
  if (__mmHasLive && __mmLive > 0) {
    if (!__mmState) {
      __mmState = __mmCooldownStateForSid(v.sid, __mmNow);
    }
    (__mmState.weapons ||
      (__mmState.weapons = Object.create(null)),
      Array.isArray(__mmState.slots) || (__mmState.slots = [null, null]));
    if (!__mmEntry) {
      __mmEntry = __mmState.weapons[String(__mmId)] = {
        weapon: __mmId,
        duration: Math.max(1, __mmBaseDuration || 0, __mmLive),
        remaining: __mmLive,
        startedAt: __mmNow,
        readyAt: __mmNow + __mmLive,
        outgoingAt: 0,
        liveSeen: !0,
      };
      const __mmSlot = __mmPlayerWeaponSlot(v, __mmId);
      (__mmSlot === 0 || __mmSlot === 1) &&
        (__mmState.slots[__mmSlot] = __mmId);
    } else {
      ((__mmEntry.duration = Math.max(
        1,
        Number(__mmEntry.duration) || 0,
        __mmBaseDuration || 0,
        __mmLive,
      )),
        (__mmEntry.remaining = __mmLive),
        (__mmEntry.readyAt = __mmNow + __mmLive),
        (__mmEntry.liveSeen = !0));
    }
    ((__mmEntry.liveSeenAt = __mmNow),
      (__mmState.updatedAt = __mmNow));
  } else if (
    __mmHasLive &&
    __mmLive === 0 &&
    __mmHeld &&
    __mmEntry &&
    __mmEntry.liveSeen
  ) {
    // Once the game has exposed a positive reload for this shot, its later
    // zero is authoritative. This prevents a prediction (especially Musket's
    // long 1500 ms clock) from keeping the bar partially empty after reload.
    ((__mmEntry.remaining = 0),
      (__mmEntry.readyAt = __mmNow),
      (__mmEntry.outgoingAt = 0));
  }
  return {
    state: __mmState,
    entry: __mmEntry,
    hasLive: __mmHasLive,
    live: __mmLive,
  };
}
function __mmPlayerCooldownRows(__mmPlayer, __mmNow) {
  if (!__mmPlayer || __mmPlayer.sid == null) return [];
  const __mmIsLocal = !!(
      v && String(__mmPlayer.sid) === String(v.sid)
    ),
    __mmState = __mmAdvancePlayerToolCooldowns(__mmPlayer, __mmNow),
    __mmSlots = [null, null];
  function __mmSetSlot(__mmSlot, __mmWeaponId, __mmOverwrite) {
    if (__mmSlot !== 0 && __mmSlot !== 1) return;
    const __mmId = Number(__mmWeaponId);
    if (
      !Number.isInteger(__mmId) ||
      !b ||
      !b.weapons ||
      !b.weapons[__mmId] ||
      (!__mmOverwrite && __mmSlots[__mmSlot] != null)
    )
      return;
    __mmSlots[__mmSlot] = __mmId;
  }
  const __mmInventory = __mmIsLocal && Array.isArray(v.weapons)
    ? v.weapons
    : Array.isArray(__mmPlayer.weapons)
      ? __mmPlayer.weapons
      : null;
  if (__mmInventory) {
    (__mmSetSlot(0, __mmInventory[0], !0),
      __mmSetSlot(1, __mmInventory[1], !0));
  }
  (__mmSetSlot(0, __mmPlayer.primaryIndex, !1),
    __mmSetSlot(1, __mmPlayer.secondaryIndex, !1));
  if (__mmState && Array.isArray(__mmState.slots)) {
    (__mmSetSlot(0, __mmState.slots[0], !1),
      __mmSetSlot(1, __mmState.slots[1], !1));
  }
  const __mmCurrentWeapon = Number(__mmPlayer.weaponIndex);
  __mmSetSlot(
    __mmPlayerWeaponSlot(__mmPlayer, __mmCurrentWeapon),
    __mmCurrentWeapon,
    !1,
  );
  if (__mmState && __mmState.weapons) {
    Object.keys(__mmState.weapons)
      .map(function (__mmKey) {
        return __mmState.weapons[__mmKey];
      })
      .sort(function (__mmA, __mmB) {
        return (__mmB.startedAt || 0) - (__mmA.startedAt || 0);
      })
      .forEach(function (__mmEntry) {
        __mmSetSlot(
          __mmPlayerWeaponSlot(__mmPlayer, __mmEntry.weapon),
          __mmEntry.weapon,
          !1,
        );
      });
  }
  const __mmRows = __mmSlots.reduce(function (__mmRows, __mmWeaponId, __mmSlot) {
    if (__mmWeaponId == null) return __mmRows;
    const __mmReconciled = __mmIsLocal
        ? __mmReconcileLocalToolCooldown(
            __mmPlayer,
            __mmWeaponId,
            __mmNow,
            __mmState,
          )
        : null,
      __mmTracked = __mmReconciled
        ? __mmReconciled.entry
        : __mmState && __mmState.weapons
          ? __mmState.weapons[String(__mmWeaponId)]
          : null,
      __mmTrackedRemaining = Math.max(
        0,
        Number(__mmTracked && __mmTracked.remaining) || 0,
      ),
      __mmRemaining = __mmTrackedRemaining,
      __mmDuration = Math.max(
        1,
        Number(__mmTracked && __mmTracked.duration) ||
          __mmToolCooldownDuration(__mmPlayer, __mmWeaponId) ||
          1,
        __mmRemaining,
      );
    __mmRows.push({
      weapon: __mmWeaponId,
      slot: __mmSlot,
      ratio: Math.max(0, Math.min(1, 1 - __mmRemaining / __mmDuration)),
    });
    return __mmRows;
  }, []);
  const __mmHasTurret = !!(
      (__mmIsLocal && v.skins && v.skins[__mmTurretGear]) ||
      Number(__mmPlayer.skinIndex) === __mmTurretGear ||
      (__mmState && __mmState.turret)
    ),
    __mmTurretEntry = __mmState && __mmState.turret;
  if (__mmHasTurret) {
    const __mmRemaining = __mmTurretCooldownRemaining(__mmPlayer, __mmNow),
      __mmDuration = Math.max(
        1,
        Number(__mmTurretEntry && __mmTurretEntry.duration) ||
          __mmTurretCooldownDuration(__mmPlayer),
        __mmRemaining,
      );
    __mmRows.push({
      weapon: null,
      slot: 2,
      ratio: Math.max(0, Math.min(1, 1 - __mmRemaining / __mmDuration)),
      turret: !0,
    });
  }
  return __mmRows;
}
const __mmVisualCooldownRowsCache = new WeakMap();
function __mmVisualCooldownRows(__mmPlayer, __mmNow) {
  if (!__mmPlayer || typeof __mmPlayer !== "object") return [];
  const __mmCached = __mmVisualCooldownRowsCache.get(__mmPlayer);
  if (__mmCached && Math.abs(__mmNow - __mmCached.at) <= 12)
    return __mmCached.rows;
  const __mmRows = __mmPlayerCooldownRows(__mmPlayer, __mmNow);
  __mmVisualCooldownRowsCache.set(__mmPlayer, {
    at: __mmNow,
    rows: __mmRows,
  });
  return __mmRows;
}
function __mmFillCooldownRoundRect(
  __mmX,
  __mmY,
  __mmWidth,
  __mmHeight,
  __mmRadius,
) {
  if (__mmWidth <= 0 || __mmHeight <= 0) return;
  k.beginPath();
  typeof k.roundRect === "function"
    ? k.roundRect(
        __mmX,
        __mmY,
        __mmWidth,
        __mmHeight,
        Math.min(__mmRadius, __mmWidth / 2, __mmHeight / 2),
      )
    : k.rect(__mmX, __mmY, __mmWidth, __mmHeight);
  k.fill();
}
function __mmDrawPlayerCooldownBars() {
  if (
    !__mmCooldownBarsEnabled ||
    !v ||
    !v.alive ||
    !k ||
    !Array.isArray(E)
  )
    return;
  try {
    const __mmLeft = oe - _ / 2,
      __mmTop = ae - L / 2,
      __mmNow = Date.now();
    k.save();
    let __mmRenderedRemotePlayers = 0;
    // Visit the local player first without allocating a filtered copy of the
    // complete player list on every animation frame.
    for (let __mmIndex = -1; __mmIndex < E.length; __mmIndex++) {
      const __mmPlayer = __mmIndex < 0 ? v : E[__mmIndex],
        __mmIsLocal =
          __mmPlayer === v ||
          (__mmPlayer && String(__mmPlayer.sid) === String(v.sid));
      if (
        !__mmPlayer ||
        !__mmPlayer.alive ||
        (__mmIndex >= 0 && __mmIsLocal) ||
        (!__mmIsLocal && !__mmPlayer.visible)
      )
        continue;
      const __mmX = __mmPlayer.x - __mmLeft,
        __mmY = __mmPlayer.y - __mmTop,
        __mmScale = Number(__mmPlayer.scale) || 35,
        __mmNameOffset = Number(y && y.nameY) || 0,
        __mmHealthHalfWidth = Math.max(
          34,
          Number(y && y.healthBarWidth) || 50,
        ),
        __mmHealthPad = Math.max(
          2,
          Math.min(5, Number(y && y.healthBarPad) || 4),
        ),
        __mmTotalWidth = __mmHealthHalfWidth * 2 + __mmHealthPad * 2,
        __mmGap = 3,
        __mmHeight = 17,
        __mmStartX = Math.round(__mmX - __mmTotalWidth / 2),
        __mmStartY = Math.round(
          __mmY + __mmScale + __mmNameOffset + __mmHeight + 3,
        );
      // Cull and apply the remote budget before reconciling weapon cooldowns;
      // that reconciliation is the costly part of this overlay.
      if (
        __mmStartX > _ + __mmTotalWidth ||
        __mmStartX < -__mmTotalWidth ||
        __mmStartY > L + 20 ||
        __mmStartY < -20
      )
        continue;
      if (
        __mmFpsBoostEnabled &&
        !__mmIsLocal &&
        __mmRenderedRemotePlayers >= 8
      )
        continue;
      const __mmRows = __mmVisualCooldownRows(__mmPlayer, __mmNow);
      if (!__mmRows.length) continue;
      !__mmIsLocal && __mmRenderedRemotePlayers++;
      const __mmBarCount = __mmRows.some((__mmRow) => __mmRow.slot === 2)
          ? 3
          : 2,
        __mmBarWidth =
          (__mmTotalWidth - __mmGap * (__mmBarCount - 1)) / __mmBarCount;
      for (let __mmRow = 0; __mmRow < __mmRows.length; __mmRow++) {
        const __mmSlot =
            __mmRows[__mmRow].slot === 2
              ? 2
              : __mmRows[__mmRow].slot === 1
                ? 1
                : 0,
          __mmBarX =
            __mmStartX + __mmSlot * (__mmBarWidth + __mmGap),
          __mmRatio = __mmRows[__mmRow].ratio,
          __mmInnerX = __mmBarX + __mmHealthPad,
          __mmInnerY = __mmStartY + __mmHealthPad,
          __mmInnerWidth = __mmBarWidth - __mmHealthPad * 2,
          __mmInnerHeight = __mmHeight - __mmHealthPad * 2,
          __mmFillWidth = Math.max(0, __mmInnerWidth * __mmRatio),
          __mmFill =
            __mmSlot === 0
              ? "#a855f7"
              : __mmSlot === 1
                ? "#d8b4fe"
                : "#f0abfc";
        ((k.shadowBlur = 0),
          (k.fillStyle = "rgba(48, 48, 52, 0.96)"),
          __mmFillCooldownRoundRect(
            __mmBarX,
            __mmStartY,
            __mmBarWidth,
            __mmHeight,
            __mmHeight / 2,
          ));
        if (__mmFillWidth > 0) {
          ((k.fillStyle = __mmFill),
            __mmFillCooldownRoundRect(
              __mmInnerX,
              __mmInnerY,
              __mmFillWidth,
              __mmInnerHeight,
              __mmInnerHeight / 2,
            ));
        }
      }
    }
    k.restore();
  } catch (__mmCooldownDrawError) {
    try {
      k && k.restore();
    } catch (__mmIgnore) {}
  }
}
function __mmDrawWeaponXpBar() {
  if (
    !__mmWeaponXpBarEnabled ||
    !v ||
    !v.alive ||
    !k ||
    !y ||
    !Array.isArray(y.weaponVariants) ||
    Number(v.buildIndex) >= 0
  )
    return;
  try {
    const __mmWeapon = Number(v.weaponIndex),
      __mmXp = Math.max(
        0,
        Number(v.weaponXP && v.weaponXP[__mmWeapon]) || 0,
      ),
      __mmThresholds = [];
    if (!Number.isInteger(__mmWeapon) || __mmWeapon < 0) return;
    for (let __mmIndex = 0; __mmIndex < y.weaponVariants.length; __mmIndex++) {
      const __mmThreshold = Number(y.weaponVariants[__mmIndex].xp);
      if (
        Number.isFinite(__mmThreshold) &&
        __mmThreshold > 0 &&
        __mmThresholds.indexOf(__mmThreshold) < 0
      )
        __mmThresholds.push(__mmThreshold);
    }
    __mmThresholds.sort(function (__mmA, __mmB) {
      return __mmA - __mmB;
    });
    if (!__mmThresholds.length) return;
    let __mmPrevious = 0,
      __mmNext = null;
    for (let __mmIndex = 0; __mmIndex < __mmThresholds.length; __mmIndex++) {
      if (__mmXp >= __mmThresholds[__mmIndex])
        __mmPrevious = __mmThresholds[__mmIndex];
      else {
        __mmNext = __mmThresholds[__mmIndex];
        break;
      }
    }
    const __mmMaxed = __mmNext == null,
      __mmRatio = __mmMaxed
        ? 1
        : Math.max(
            0,
            Math.min(1, (__mmXp - __mmPrevious) / (__mmNext - __mmPrevious)),
          ),
      __mmLeft = oe - _ / 2,
      __mmTop = ae - L / 2,
      __mmX = Number(v.x) - __mmLeft,
      __mmY = Number(v.y) - __mmTop,
      __mmScale = Number(v.scale) || 35,
      __mmNameOffset = Number(y.nameY) || 0,
      __mmHealthHalfWidth = Math.max(34, Number(y.healthBarWidth) || 50),
      __mmHealthPad = Math.max(2, Math.min(5, Number(y.healthBarPad) || 4)),
      __mmWidth = __mmHealthHalfWidth * 2 + __mmHealthPad * 2,
      __mmHeight = 11,
      __mmStartX = Math.round(__mmX - __mmWidth / 2),
      __mmStartY = Math.round(__mmY + __mmScale + __mmNameOffset + 41),
      __mmInnerX = __mmStartX + 2,
      __mmInnerY = __mmStartY + 2,
      __mmInnerWidth = __mmWidth - 4,
      __mmLabel = __mmMaxed
        ? "XP " + Math.round(__mmXp) + " · MAX"
        : "XP " + Math.round(__mmXp) + " / " + Math.round(__mmNext);
    if (
      __mmStartX > _ + __mmWidth ||
      __mmStartX < -__mmWidth ||
      __mmStartY > L + 20 ||
      __mmStartY < -20
    )
      return;
    (k.save(),
      (k.shadowBlur = 0),
      (k.fillStyle = "rgba(29,22,36,.96)"),
      __mmFillCooldownRoundRect(
        __mmStartX,
        __mmStartY,
        __mmWidth,
        __mmHeight,
        __mmHeight / 2,
      ));
    if (__mmRatio > 0) {
      ((k.fillStyle = __mmOwnColor),
        __mmFillCooldownRoundRect(
          __mmInnerX,
          __mmInnerY,
          __mmInnerWidth * __mmRatio,
          __mmHeight - 4,
          (__mmHeight - 4) / 2,
        ));
    }
    ((k.fillStyle = "#fff"),
      (k.font = "800 8px ui-monospace,SFMono-Regular,Menlo,monospace"),
      (k.textAlign = "center"),
      (k.textBaseline = "middle"),
      (k.shadowColor = "rgba(0,0,0,.9)"),
      (k.shadowBlur = 2),
      k.fillText(__mmLabel, __mmX, __mmStartY + __mmHeight / 2 + 0.5),
      k.restore());
  } catch (__mmXpDrawError) {
    try {
      k && k.restore();
    } catch (__mmIgnore) {}
  }
}
function __mmTrackWeaponXpResourceGain(
  __mmResource,
  __mmPreviousValue,
  __mmNextValue,
  __mmWeapon,
) {
  if (
    !v ||
    !v.alive ||
    (__mmResource !== "food" &&
      __mmResource !== "wood" &&
      __mmResource !== "stone")
  )
    return;
  const __mmPrevious = Number(__mmPreviousValue),
    __mmNext = Number(__mmNextValue),
    __mmWeaponId = Number(__mmWeapon),
    __mmGain = __mmNext - __mmPrevious;
  if (
    !Number.isFinite(__mmPrevious) ||
    !Number.isFinite(__mmNext) ||
    !Number.isInteger(__mmWeaponId) ||
    __mmWeaponId < 0 ||
    !Number.isFinite(__mmGain) ||
    __mmGain <= 0
  )
    return;
  // The stock client exposes weaponXP but leaves it untouched on resource
  // packets. Weapon-variant progress is the positive food/wood/stone gain
  // attributed to the weapon held when that packet arrived.
  Array.isArray(v.weaponXP) || (v.weaponXP = []);
  v.weaponXP[__mmWeaponId] =
    (Number(v.weaponXP[__mmWeaponId]) || 0) + __mmGain;
}
function __mmRecordCombatDelta(__mmPlayer, __mmPrevious, __mmNext) {
  if (
    !__mmCombatTelemetryEnabled ||
    !__mmTelemetryDamageHealingEnabled ||
    !__mmPlayer
  )
    return;
  const __mmBefore = Number(__mmPrevious),
    __mmAfter = Number(__mmNext),
    __mmDelta = __mmAfter - __mmBefore;
  if (
    !Number.isFinite(__mmBefore) ||
    !Number.isFinite(__mmAfter) ||
    Math.abs(__mmDelta) < 0.01
  )
    return;
  const __mmSid = String(
      __mmPlayer.sid == null ? __mmPlayer.id : __mmPlayer.sid,
    ),
    __mmNow = Date.now(),
    __mmStack =
      __mmCombatDeltaStacks[__mmSid] ||
      (__mmCombatDeltaStacks[__mmSid] = []);
  __mmStack.push({
    value: __mmDelta,
    at: __mmNow,
    expiresAt: __mmNow + 1450,
  });
  __mmStack.length > 6 && __mmStack.splice(0, __mmStack.length - 6);
}
function __mmTelemetryPlayerColor(__mmPlayer) {
  if (!__mmPlayer || __mmPlayer === v) return __mmOwnColor;
  return __mmIsFriendPlayer(__mmPlayer)
    ? __mmFriendColor
    : __mmSameTeam(__mmPlayer)
      ? __mmAllyColor
      : __mmEnemyColor;
}
function __mmTelemetryText(__mmText, __mmX, __mmY, __mmColor, __mmSize = 10) {
  ((k.font =
    "900 " + __mmSize + "px ui-monospace,SFMono-Regular,Menlo,monospace"),
    (k.textAlign = "center"),
    (k.textBaseline = "middle"),
    (k.lineWidth = 3),
    (k.strokeStyle = "rgba(6,3,10,.92)"),
    k.strokeText(__mmText, __mmX, __mmY),
    (k.fillStyle = __mmColor),
    k.fillText(__mmText, __mmX, __mmY));
}
function __mmDrawTelemetryProjectileHits(__mmLeft, __mmTop) {
  if (!__mmTelemetryProjectileHitsEnabled) return;
  const __mmThreat = __mmCombatThreatSnapshot(),
    __mmEntries = __mmThreat && __mmThreat.entries,
    __mmLimit = __mmFpsBoostEnabled ? 6 : 16;
  if (!Array.isArray(__mmEntries)) return;
  let __mmRendered = 0;
  for (let __mmIndex = 0; __mmIndex < __mmEntries.length; __mmIndex++) {
    const __mmEntry = __mmEntries[__mmIndex],
      __mmProjectile = __mmEntry && __mmEntry.source;
    if (
      !__mmEntry ||
      (__mmEntry.type !== "projectile" && __mmEntry.type !== "turret") ||
      !__mmProjectile ||
      !Number.isFinite(__mmEntry.impactMs)
    )
      continue;
    const __mmDirection = Number(__mmProjectile.dir),
      __mmSpeed = Number(__mmProjectile.speed),
      __mmStartX = Number(__mmProjectile.x) - __mmLeft,
      __mmStartY = Number(__mmProjectile.y) - __mmTop,
      __mmImpactWorldX =
        Number(__mmProjectile.x) +
        Math.cos(__mmDirection) * __mmSpeed * __mmEntry.impactMs,
      __mmImpactWorldY =
        Number(__mmProjectile.y) +
        Math.sin(__mmDirection) * __mmSpeed * __mmEntry.impactMs,
      __mmImpactX = __mmImpactWorldX - __mmLeft,
      __mmImpactY = __mmImpactWorldY - __mmTop,
      __mmDamage = Math.max(0, Number(__mmEntry.damage) || 0);
    if (
      !Number.isFinite(__mmDirection) ||
      !Number.isFinite(__mmSpeed) ||
      !Number.isFinite(__mmImpactX) ||
      !Number.isFinite(__mmImpactY) ||
      (!ts(__mmStartX, __mmStartY, 30) &&
        !ts(__mmImpactX, __mmImpactY, 45))
    )
      continue;
    ((k.globalAlpha = 0.78),
      (k.strokeStyle = __mmEnemyColor),
      (k.lineWidth = 1.7),
      k.setLineDash([7, 5]),
      k.beginPath(),
      k.moveTo(__mmStartX, __mmStartY),
      k.lineTo(__mmImpactX, __mmImpactY),
      k.stroke(),
      k.setLineDash([]),
      (k.globalAlpha = 0.95),
      k.beginPath(),
      k.arc(__mmImpactX, __mmImpactY, 7, 0, Math.PI * 2),
      k.stroke());
    __mmTelemetryText(
      "-" + Math.round(__mmDamage) + " · " +
        Math.max(0, Math.round(__mmEntry.impactMs)) + "ms",
      __mmImpactX,
      __mmImpactY - 13,
      __mmEnemyColor,
      9,
    );
    if (++__mmRendered >= __mmLimit) break;
  }
}
function __mmDrawTelemetrySpikeKnockback(__mmLeft, __mmTop) {
  if (!__mmTelemetrySpikeKnockbackEnabled) return;
  const __mmThreat = __mmCombatThreatSnapshot(),
    __mmEntries = __mmThreat && __mmThreat.entries;
  if (!Array.isArray(__mmEntries)) return;
  const __mmStartX = Number(v.x) - __mmLeft,
    __mmStartY = Number(v.y) - __mmTop;
  for (let __mmIndex = 0; __mmIndex < __mmEntries.length; __mmIndex++) {
    const __mmEntry = __mmEntries[__mmIndex],
      __mmSpike = __mmEntry && __mmEntry.spike;
    if (!__mmSpike) continue;
    const __mmX = Number(__mmSpike.x) - __mmLeft,
      __mmY = Number(__mmSpike.y) - __mmTop;
    ((k.globalAlpha = 0.9),
      (k.strokeStyle = "#fb7185"),
      (k.lineWidth = 3),
      k.setLineDash([3, 4]),
      k.beginPath(),
      k.moveTo(__mmStartX, __mmStartY),
      k.lineTo(__mmX, __mmY),
      k.stroke(),
      k.setLineDash([]),
      k.beginPath(),
      k.arc(__mmX, __mmY, __mmThreatObjectScale(__mmSpike) + 7, 0, Math.PI * 2),
      k.stroke());
    __mmTelemetryText(
      "SPIKE -" + Math.round(Number(__mmEntry.spike.damage) || 0),
      __mmX,
      __mmY - __mmThreatObjectScale(__mmSpike) - 13,
      "#fb7185",
      10,
    );
  }
}
function __mmDrawTelemetryActualAim(__mmLeft, __mmTop) {
  if (!__mmTelemetryActualAimEnabled) return;
  const __mmPlayers = [v],
    __mmLimit = __mmFpsBoostEnabled ? 9 : 24;
  if (Array.isArray(E))
    for (let __mmIndex = 0; __mmIndex < E.length; __mmIndex++)
      E[__mmIndex] && E[__mmIndex] !== v && __mmPlayers.push(E[__mmIndex]);
  let __mmRendered = 0;
  for (let __mmIndex = 0; __mmIndex < __mmPlayers.length; __mmIndex++) {
    const __mmPlayer = __mmPlayers[__mmIndex];
    if (
      !__mmPlayer ||
      !__mmPlayer.alive ||
      (__mmPlayer !== v && __mmPlayer.visible === !1)
    )
      continue;
    const __mmDirection = Number.isFinite(Number(__mmPlayer.dir))
        ? Number(__mmPlayer.dir)
        : Number(__mmPlayer.d2),
      __mmWeapon = b && b.weapons && b.weapons[__mmPlayer.weaponIndex],
      __mmReach = Math.max(
        55,
        Math.min(
          320,
          (Number(__mmWeapon && __mmWeapon.range) || 80) +
            (Number(__mmPlayer.scale) || 35),
        ),
      ),
      __mmX = Number(__mmPlayer.x) - __mmLeft,
      __mmY = Number(__mmPlayer.y) - __mmTop,
      __mmEndX = __mmX + Math.cos(__mmDirection) * __mmReach,
      __mmEndY = __mmY + Math.sin(__mmDirection) * __mmReach,
      __mmColor = __mmTelemetryPlayerColor(__mmPlayer);
    if (!Number.isFinite(__mmDirection) || !ts(__mmX, __mmY, __mmReach))
      continue;
    ((k.globalAlpha = __mmPlayer === v ? 0.82 : 0.58),
      (k.strokeStyle = __mmColor),
      (k.lineWidth = __mmPlayer === v ? 2.2 : 1.4),
      k.beginPath(),
      k.moveTo(__mmX, __mmY),
      k.lineTo(__mmEndX, __mmEndY),
      k.stroke(),
      (k.fillStyle = __mmColor),
      k.beginPath(),
      k.arc(__mmEndX, __mmEndY, 3, 0, Math.PI * 2),
      k.fill());
    if (++__mmRendered >= __mmLimit) break;
  }
}
function __mmDrawTelemetryBuildingOwners(__mmLeft, __mmTop) {
  if (!__mmTelemetryBuildingOwnersEnabled) return;
  const __mmBreakables = __mmActiveObjectSnapshot().breakables,
    __mmLimit = __mmFpsBoostEnabled ? 8 : 24;
  let __mmRendered = 0;
  for (let __mmIndex = 0; __mmIndex < __mmBreakables.length; __mmIndex++) {
    const __mmObject = __mmBreakables[__mmIndex].object,
      __mmOwner = __mmStructureOwnerPlayer(__mmObject),
      __mmOwnerSid = __mmStructureOwnerSid(__mmObject);
    if (!__mmObject || __mmOwnerSid == null) continue;
    const __mmName = String(
        (__mmOwner && __mmOwner.name) || "SID " + __mmOwnerSid,
      ).slice(0, 20),
      __mmX = Number(__mmObject.x) - __mmLeft,
      __mmY =
        Number(__mmObject.y) -
        __mmTop +
        __mmThreatObjectScale(__mmObject) +
        13,
      __mmColor = __mmOwnStructure(__mmObject)
        ? __mmOwnColor
        : __mmFriendlyStructure(__mmObject)
          ? __mmAllyColor
          : __mmEnemyColor;
    if (!ts(__mmX, __mmY, 35)) continue;
    __mmTelemetryText(__mmName, __mmX, __mmY, __mmColor, 9);
    if (++__mmRendered >= __mmLimit) break;
  }
}
function __mmDrawTelemetryShame(__mmLeft, __mmTop) {
  if (!__mmTelemetryShameCountEnabled) return;
  const __mmX = Number(v.x) - __mmLeft,
    __mmY =
      Number(v.y) -
      __mmTop +
      (Number(v.scale) || 35) +
      (Number(y && y.nameY) || 0) +
      58;
  __mmTelemetryText(
    "SHAME " + Math.max(0, Math.round(__mmAutoHealShameCount)),
    __mmX,
    __mmY,
    __mmAutoHealShameCount > 0 ? "#facc15" : "#c4b5fd",
    9,
  );
}
function __mmDrawTelemetryDeltas(__mmLeft, __mmTop) {
  if (!__mmTelemetryDamageHealingEnabled) return;
  const __mmNow = Date.now(),
    __mmPlayers = [v];
  if (Array.isArray(E))
    for (let __mmIndex = 0; __mmIndex < E.length; __mmIndex++)
      E[__mmIndex] && E[__mmIndex] !== v && __mmPlayers.push(E[__mmIndex]);
  let __mmRenderedPlayers = 0;
  const __mmLimit = __mmFpsBoostEnabled ? 8 : 20;
  for (let __mmIndex = 0; __mmIndex < __mmPlayers.length; __mmIndex++) {
    const __mmPlayer = __mmPlayers[__mmIndex],
      __mmSid = String(
        __mmPlayer && (__mmPlayer.sid == null ? __mmPlayer.id : __mmPlayer.sid),
      ),
      __mmStack = __mmCombatDeltaStacks[__mmSid];
    if (!__mmPlayer || !Array.isArray(__mmStack)) continue;
    for (let __mmEntry = __mmStack.length - 1; __mmEntry >= 0; __mmEntry--)
      __mmNow >= __mmStack[__mmEntry].expiresAt &&
        __mmStack.splice(__mmEntry, 1);
    if (!__mmStack.length) {
      delete __mmCombatDeltaStacks[__mmSid];
      continue;
    }
    if (__mmPlayer !== v && __mmPlayer.visible === !1) continue;
    const __mmX = Number(__mmPlayer.x) - __mmLeft,
      __mmBaseY =
        Number(__mmPlayer.y) -
        __mmTop -
        (Number(__mmPlayer.scale) || 35) -
        24;
    if (!ts(__mmX, __mmBaseY, 80)) continue;
    for (let __mmEntry = 0; __mmEntry < __mmStack.length; __mmEntry++) {
      const __mmDelta = __mmStack[__mmEntry],
        __mmAge = __mmNow - __mmDelta.at,
        __mmAlpha = Math.max(0, Math.min(1, (__mmDelta.expiresAt - __mmNow) / 350)),
        __mmY = __mmBaseY - __mmEntry * 15 - Math.min(16, __mmAge / 55),
        __mmValue = Number(__mmDelta.value) || 0;
      k.globalAlpha = __mmAlpha;
      __mmTelemetryText(
        (__mmValue > 0 ? "+" : "") + Math.round(__mmValue),
        __mmX,
        __mmY,
        __mmValue > 0 ? "#4ade80" : "#fb7185",
        11,
      );
    }
    if (++__mmRenderedPlayers >= __mmLimit) break;
  }
}
function __mmDrawCombatTelemetry() {
  if (!__mmCombatTelemetryEnabled || !v || !v.alive || !k) return;
  const __mmLeft = oe - _ / 2,
    __mmTop = ae - L / 2;
  try {
    (k.save(),
      __mmDrawTelemetryProjectileHits(__mmLeft, __mmTop),
      __mmDrawTelemetrySpikeKnockback(__mmLeft, __mmTop),
      __mmDrawTelemetryActualAim(__mmLeft, __mmTop),
      __mmDrawTelemetryBuildingOwners(__mmLeft, __mmTop),
      __mmDrawTelemetryShame(__mmLeft, __mmTop),
      __mmDrawTelemetryDeltas(__mmLeft, __mmTop),
      k.restore());
  } catch (__mmTelemetryError) {
    try {
      k && k.restore();
    } catch (__mmIgnore) {}
  }
}
function __mmWeaponStructureDamage(__mmPlayer, __mmWeaponId, __mmObject) {
  if (!__mmPlayer || !b || !b.weapons || !__mmObject) return 0;
  const __mmWeapon = b.weapons[__mmWeaponId];
  if (!__mmWeapon) return 0;
  if (__mmWeapon.projectile != null) {
    const __mmProjectile = b.projectiles && b.projectiles[__mmWeapon.projectile];
    return __mmObject.projDmg && __mmProjectile
      ? Math.max(0, Number(__mmProjectile.dmg) || 0)
      : 0;
  }
  const __mmVariant =
      y && y.weaponVariants && y.weaponVariants[__mmPlayer.weaponVariant],
    __mmVariantMultiplier = Number(__mmVariant && __mmVariant.val) || 1,
    __mmStructureMultiplier = Number(__mmWeapon.sDmg) || 1,
    __mmHat = __mmPlayerHatData(__mmPlayer),
    __mmHatMultiplier = Number(__mmHat && __mmHat.bDmg) || 1;
  return Math.max(
    0,
    (Number(__mmWeapon.dmg) || 0) *
      __mmVariantMultiplier *
      __mmStructureMultiplier *
      __mmHatMultiplier,
  );
}
function __mmCurrentStructureDamage(__mmObject) {
  if (!v || !v.alive || Number(v.buildIndex) >= 0) return 0;
  return __mmWeaponStructureDamage(v, v.weaponIndex, __mmObject);
}
function __mmMatThiefStructureAllowed(__mmObject) {
  if (
    !v ||
    !v.alive ||
    !__mmObject ||
    !__mmObject.active ||
    !__mmObject.isItem ||
    !__mmObject.owner
  )
    return !1;
  const __mmOwnerSid = __mmObject.owner.sid;
  // Teammate structures are intentional targets too, but the local player's
  // own placed structures must never be selected.
  if (
    __mmObject.owner === v ||
    (__mmOwnerSid != null && String(__mmOwnerSid) === String(v.sid))
  )
    return !1;
  const __mmOwnerPlayer =
    __mmOwnerSid != null && typeof Rt === "function"
      ? Rt(__mmOwnerSid)
      : __mmObject.owner;
  if (__mmIsFriendPlayer(__mmOwnerPlayer)) return !1;
  const __mmItem = b && b.list && b.list[__mmObject.id],
    __mmName = String((__mmItem && __mmItem.name) || "").toLowerCase();
  return (
    __mmName === "windmill" ||
    __mmName === "faster windmill" ||
    __mmName === "power mill" ||
    __mmName === "turret" ||
    __mmName === "teleporter"
  );
}
function __mmMatThiefWeaponCandidates() {
  if (!v || !v.alive || !Array.isArray(v.weapons)) return [];
  const __mmWeapons = [],
    __mmSeen = new Set();
  for (let __mmIndex = 0; __mmIndex < v.weapons.length; __mmIndex++) {
    const __mmWeapon = v.weapons[__mmIndex],
      __mmData = b && b.weapons && b.weapons[__mmWeapon];
    if (
      __mmWeapon == null ||
      __mmSeen.has(__mmWeapon) ||
      !__mmData ||
      __mmData.projectile != null ||
      !__mmWeaponReady(__mmWeapon)
    )
      continue;
    (__mmSeen.add(__mmWeapon), __mmWeapons.push(__mmWeapon));
  }
  return __mmWeapons;
}
function __mmMatThiefTargetsForWeapon(__mmWeapon, __mmNow) {
  if (!v || !v.alive) return [];
  const __mmWeaponData = b && b.weapons && b.weapons[__mmWeapon],
    __mmRange = Number(__mmWeaponData && __mmWeaponData.range);
  if (!Number.isFinite(__mmRange) || __mmRange <= 0) return [];
  const __mmTargets = [],
    __mmObjects = __mmActiveObjectSnapshot().all;
  for (let __mmIndex = 0; __mmIndex < __mmObjects.length; __mmIndex++) {
    const __mmObject = __mmObjects[__mmIndex];
    if (!__mmMatThiefStructureAllowed(__mmObject)) continue;
    const __mmReservedUntil = Number(__mmMatThiefReservations.get(__mmObject));
    if (Number.isFinite(__mmReservedUntil) && __mmReservedUntil > __mmNow)
      continue;
    const __mmState = __mmBreakableState(__mmObject),
      __mmDamage = __mmWeaponStructureDamage(v, __mmWeapon, __mmObject);
    if (!__mmState || __mmDamage <= 0 || __mmState.health > __mmDamage + 0.001)
      continue;
    const __mmDx = __mmObject.x - v.x,
      __mmDy = __mmObject.y - v.y,
      __mmDistance = Math.hypot(__mmDx, __mmDy),
      // Match the server gather check: center distance minus structure scale
      // must fit inside the selected weapon's range.
      __mmReach = __mmRange + (Number(__mmObject.scale) || 0);
    if (__mmDistance > __mmReach) continue;
    __mmTargets.push({
      object: __mmObject,
      angle: Math.atan2(__mmDy, __mmDx),
      distance: __mmDistance,
    });
  }
  return __mmTargets;
}
function __mmMatThiefAngleDifference(__mmFirst, __mmSecond) {
  return Math.atan2(
    Math.sin(__mmSecond - __mmFirst),
    Math.cos(__mmSecond - __mmFirst),
  );
}
function __mmMatThiefAimPlan(__mmTargets) {
  if (!__mmTargets.length) return null;
  const __mmGatherAngle = Math.max(0.05, Number(y && y.gatherAngle) || 0.35),
    __mmCandidateAngles = [];
  for (let __mmIndex = 0; __mmIndex < __mmTargets.length; __mmIndex++)
    __mmCandidateAngles.push(__mmTargets[__mmIndex].angle);
  for (let __mmFirst = 0; __mmFirst < __mmTargets.length; __mmFirst++)
    for (
      let __mmSecond = __mmFirst + 1;
      __mmSecond < __mmTargets.length;
      __mmSecond++
    ) {
      const __mmDifference = __mmMatThiefAngleDifference(
        __mmTargets[__mmFirst].angle,
        __mmTargets[__mmSecond].angle,
      );
      Math.abs(__mmDifference) <= 2 * __mmGatherAngle + 0.0001 &&
        __mmCandidateAngles.push(
          __mmTargets[__mmFirst].angle + __mmDifference / 2,
        );
    }
  let __mmBest = null;
  for (
    let __mmAngleIndex = 0;
    __mmAngleIndex < __mmCandidateAngles.length;
    __mmAngleIndex++
  ) {
    const __mmAim = __mmCandidateAngles[__mmAngleIndex],
      __mmCovered = __mmTargets.filter(
        (__mmTarget) =>
          Math.abs(__mmMatThiefAngleDifference(__mmAim, __mmTarget.angle)) <=
          __mmGatherAngle + 0.0001,
      ),
      __mmDistanceScore = __mmCovered.reduce(
        (__mmTotal, __mmTarget) => __mmTotal + __mmTarget.distance,
        0,
      );
    if (
      !__mmBest ||
      __mmCovered.length > __mmBest.targets.length ||
      (__mmCovered.length === __mmBest.targets.length &&
        __mmDistanceScore < __mmBest.distanceScore)
    )
      __mmBest = {
        angle: __mmAim,
        targets: __mmCovered,
        distanceScore: __mmDistanceScore,
      };
  }
  return __mmBest;
}
function __mmMultiBreakAimPlan(
  __mmWeapon,
  __mmPreferredAngle,
  __mmRequiredObject = null,
) {
  if (!__mmMultiTargetBreakEnabled || !v || !v.alive) return null;
  const __mmWeaponData = b && b.weapons && b.weapons[__mmWeapon],
    __mmRange = Number(__mmWeaponData && __mmWeaponData.range),
    __mmGatherAngle = Math.max(0.05, Number(y && y.gatherAngle) || 0.35);
  if (
    !__mmWeaponData ||
    __mmWeaponData.projectile != null ||
    __mmWeaponData.shield ||
    !Number.isFinite(__mmRange) ||
    __mmRange <= 0
  )
    return null;
  const __mmTargets = [],
    __mmObjects = __mmActiveObjectSnapshot().breakables;
  for (let __mmIndex = 0; __mmIndex < __mmObjects.length; __mmIndex++) {
    const __mmObject = __mmObjects[__mmIndex].object,
      __mmState = __mmBreakableState(__mmObject),
      __mmData = __mmObject && b && b.list && b.list[__mmObject.id];
    if (
      !__mmObject ||
      !__mmObject.active ||
      !__mmObject.isItem ||
      !__mmData ||
      !__mmState ||
      !(Number(__mmState.health) > 0)
    )
      continue;
    const __mmDx = Number(__mmObject.x) - Number(v.x),
      __mmDy = Number(__mmObject.y) - Number(v.y),
      __mmDistance = Math.hypot(__mmDx, __mmDy),
      __mmReach = __mmRange + __mmCleanupObjectScale(__mmObject),
      __mmAngle = Math.atan2(__mmDy, __mmDx),
      __mmFromPreferred = Math.abs(
        __mmMatThiefAngleDifference(__mmPreferredAngle, __mmAngle),
      );
    if (
      !Number.isFinite(__mmDistance) ||
      __mmDistance > __mmReach + 8 ||
      (__mmObject !== __mmRequiredObject &&
        __mmFromPreferred > __mmGatherAngle * 2.25)
    )
      continue;
    __mmTargets.push({
      object: __mmObject,
      angle: __mmAngle,
      distance: __mmDistance,
    });
  }
  if (__mmTargets.length < 2) return null;
  __mmTargets.sort(function (__mmA, __mmB) {
    return __mmA.distance - __mmB.distance;
  });
  __mmTargets.length > 18 && (__mmTargets.length = 18);
  const __mmCandidates = [__mmPreferredAngle];
  for (let __mmIndex = 0; __mmIndex < __mmTargets.length; __mmIndex++)
    __mmCandidates.push(__mmTargets[__mmIndex].angle);
  for (let __mmFirst = 0; __mmFirst < __mmTargets.length; __mmFirst++)
    for (
      let __mmSecond = __mmFirst + 1;
      __mmSecond < __mmTargets.length;
      __mmSecond++
    ) {
      const __mmDifference = __mmMatThiefAngleDifference(
        __mmTargets[__mmFirst].angle,
        __mmTargets[__mmSecond].angle,
      );
      if (Math.abs(__mmDifference) <= __mmGatherAngle * 2 + 0.0001)
        __mmCandidates.push(
          __mmTargets[__mmFirst].angle + __mmDifference / 2,
        );
    }
  let __mmBest = null;
  for (let __mmIndex = 0; __mmIndex < __mmCandidates.length; __mmIndex++) {
    const __mmAngle = __mmCandidates[__mmIndex],
      __mmCovered = __mmTargets.filter(function (__mmTarget) {
        return (
          Math.abs(
            __mmMatThiefAngleDifference(__mmAngle, __mmTarget.angle),
          ) <= __mmGatherAngle + 0.0001
        );
      });
    if (
      __mmCovered.length < 2 ||
      (__mmRequiredObject &&
        !__mmCovered.some(function (__mmTarget) {
          return __mmTarget.object === __mmRequiredObject;
        }))
    )
      continue;
    const __mmDeviation = Math.abs(
        __mmMatThiefAngleDifference(__mmPreferredAngle, __mmAngle),
      ),
      __mmDistanceScore = __mmCovered.reduce(function (__mmTotal, __mmTarget) {
        return __mmTotal + __mmTarget.distance;
      }, 0);
    if (
      !__mmBest ||
      __mmCovered.length > __mmBest.targets.length ||
      (__mmCovered.length === __mmBest.targets.length &&
        __mmDeviation < __mmBest.deviation) ||
      (__mmCovered.length === __mmBest.targets.length &&
        __mmDeviation === __mmBest.deviation &&
        __mmDistanceScore < __mmBest.distanceScore)
    )
      __mmBest = {
        angle: __mmAngle,
        targets: __mmCovered,
        deviation: __mmDeviation,
        distanceScore: __mmDistanceScore,
      };
  }
  return __mmBest;
}
function __mmStopMultiBreakAim() {
  const __mmHadAim = Number.isFinite(__mmMultiBreakAimAngle);
  ((__mmMultiBreakAimAngle = null), (__mmMultiBreakTargetCount = 0));
  __mmHadAim && __mmScheduleMouseAimReturn();
}
function __mmUpdateMultiBreakAim() {
  if (
    !__mmMultiTargetBreakEnabled ||
    !v ||
    !v.alive ||
    __mmCleanupActive ||
    __mmTrapAttackActive ||
    __mmInsta.isActive() ||
    __mmBoostInsta.isActive() ||
    __mmActionOwner !== "manualAttack" ||
    (!__mmPrimaryHeld && !__mmSecondaryHeld)
  )
    return void __mmStopMultiBreakAim();
  const __mmWeapon = __mmHeldAttackWeapon();
  if (__mmWeapon == null) return void __mmStopMultiBreakAim();
  const __mmPreferred = __mmRawMouseAimDirection(),
    __mmPlan = __mmMultiBreakAimPlan(__mmWeapon, __mmPreferred);
  if (!__mmPlan) return void __mmStopMultiBreakAim();
  const __mmDifference = Number.isFinite(__mmMultiBreakAimAngle)
    ? Math.abs(
        __mmMatThiefAngleDifference(
          __mmMultiBreakAimAngle,
          __mmPlan.angle,
        ),
      )
    : Infinity;
  ((__mmMultiBreakAimAngle = __mmPlan.angle),
    (__mmMultiBreakTargetCount = __mmPlan.targets.length));
  if (__mmDifference > 0.015) {
    ((It = __mmPlan.angle), O.send("D", __mmPlan.angle));
  }
}
function __mmStartMultiBreak() {
  __mmEnsureOperationPipeline();
}
function __mmStopMultiBreak() {
  (__mmMultiBreakTimer && clearInterval(__mmMultiBreakTimer),
    (__mmMultiBreakTimer = 0),
    __mmStopMultiBreakAim());
}
function __mmMatThiefPlan() {
  const __mmNow = Date.now(),
    __mmWeapons = __mmMatThiefWeaponCandidates(),
    __mmSelected = __mmSelectedWeapon();
  let __mmBest = null;
  for (let __mmIndex = 0; __mmIndex < __mmWeapons.length; __mmIndex++) {
    const __mmWeapon = __mmWeapons[__mmIndex],
      __mmTargets = __mmMatThiefTargetsForWeapon(__mmWeapon, __mmNow),
      __mmAim = __mmMatThiefAimPlan(__mmTargets);
    if (!__mmAim || !__mmAim.targets.length) continue;
    const __mmData = b.weapons[__mmWeapon],
      __mmDamage = __mmWeaponStructureDamage(
        v,
        __mmWeapon,
        __mmAim.targets[0].object,
      ),
      __mmPlan = {
        weapon: __mmWeapon,
        angle: __mmAim.angle,
        targets: __mmAim.targets,
        distanceScore: __mmAim.distanceScore,
        damage: __mmDamage,
        speed: Math.max(50, Number(__mmData.speed) || 400),
      },
      __mmPlanUsesSelected = __mmWeapon === __mmSelected,
      __mmBestUsesSelected = __mmBest && __mmBest.weapon === __mmSelected;
    if (
      !__mmBest ||
      __mmPlan.targets.length > __mmBest.targets.length ||
      (__mmPlan.targets.length === __mmBest.targets.length &&
        __mmPlanUsesSelected &&
        !__mmBestUsesSelected) ||
      (__mmPlan.targets.length === __mmBest.targets.length &&
        __mmPlanUsesSelected === __mmBestUsesSelected &&
        (__mmPlan.distanceScore < __mmBest.distanceScore ||
          (__mmPlan.distanceScore === __mmBest.distanceScore &&
            __mmPlan.damage > __mmBest.damage)))
    )
      __mmBest = __mmPlan;
  }
  return __mmBest;
}
function __mmFinishMatThief(__mmReason) {
  const __mmAim = __mmMatThiefAimAngle,
    __mmReturnAngle = __mmMatThiefReturnAngle,
    __mmTool = __mmMatThiefRestoreTool,
    __mmRestore = __mmActionMayRestore("matThief");
  (__mmMatThiefReleaseTimer && clearTimeout(__mmMatThiefReleaseTimer),
    (__mmMatThiefReleaseTimer = 0),
    __mmMatThiefAttackHeld && O.send("F", 0, __mmAim),
    (__mmMatThiefAttackHeld = !1),
    (__mmMatThiefAimAngle = null),
    (__mmMatThiefReturnAngle = null),
    (__mmMatThiefRestoreTool = null),
    __mmRestore && __mmRestoreTool(__mmTool),
    __mmRestore &&
      Number.isFinite(__mmReturnAngle) &&
      O.send("D", __mmReturnAngle),
    __mmActionRelease("matThief", __mmReason || "last hit complete"));
}
function __mmUpdateMatThief() {
  if (
    !__mmMatThiefEnabled ||
    document.hidden ||
    !v ||
    !v.alive ||
    v.lockMove ||
    __mmMatThiefReleaseTimer ||
    __mmPrimaryHeld ||
    __mmSecondaryHeld ||
    __mmTrapAttackActive ||
    __mmBoostBreakHeld ||
    __mmBuildSpamTimer ||
    __mmFoodSpamTimer ||
    __mmInsta.isActive() ||
    __mmSyncFollowerEnabled ||
    (__mmActionOwner !== "idle" && __mmActionOwner !== "weaponRecharge")
  )
    return;
  const __mmPlan = __mmMatThiefPlan();
  if (!__mmPlan) return;
  __mmActionOwner === "weaponRecharge" && __mmPauseWeaponRecharge(!0);
  if (!__mmActionClaim("matThief", "one-hit structure")) return;
  let __mmReturnAngle;
  try {
    __mmReturnAngle = __mmOriginalAimDirection();
  } catch (__mmAimError) {
    __mmReturnAngle = 0;
  }
  const __mmNow = Date.now(),
    __mmReservationUntil =
      __mmNow + Math.max(__mmPlan.speed, 2 * __mmServerTickMs());
  for (let __mmIndex = 0; __mmIndex < __mmPlan.targets.length; __mmIndex++)
    __mmMatThiefReservations.set(
      __mmPlan.targets[__mmIndex].object,
      __mmReservationUntil,
    );
  ((__mmMatThiefReturnAngle = __mmReturnAngle),
    (__mmMatThiefRestoreTool = __mmSelectedTool()),
    (__mmMatThiefAimAngle = __mmPlan.angle),
    O.send("D", __mmPlan.angle),
    je(__mmPlan.weapon, !0),
    O.send("F", 1, __mmPlan.angle),
    (__mmMatThiefAttackHeld = !0),
    (__mmMatThiefReleaseTimer = setTimeout(function () {
      __mmFinishMatThief("last hit sent");
    }, __mmServerTickMs())));
}
function __mmStartMatThief() {
  __mmEnsureOperationPipeline();
}
function __mmStopMatThief() {
  (__mmMatThiefTimer && clearInterval(__mmMatThiefTimer),
    (__mmMatThiefTimer = 0),
    __mmFinishMatThief("mode disabled"));
}
function __mmMobStealEntityKey(__mmAnimal) {
  if (!__mmAnimal) return null;
  const __mmId =
    __mmAnimal.sid != null
      ? __mmAnimal.sid
      : __mmAnimal.id != null
        ? __mmAnimal.id
        : __mmAnimal.index;
  return __mmId == null ? null : "mob:" + String(__mmId);
}
function __mmMobStealVariantMultiplier(__mmWeapon) {
  const __mmVariants = y && y.weaponVariants,
    __mmXp = Number(v && v.weaponXP && v.weaponXP[__mmWeapon]) || 0;
  if (!Array.isArray(__mmVariants)) return 1;
  for (let __mmIndex = __mmVariants.length - 1; __mmIndex >= 0; __mmIndex--)
    if (__mmXp >= (Number(__mmVariants[__mmIndex].xp) || 0))
      return Number(__mmVariants[__mmIndex].val) || 1;
  return 1;
}
function __mmMobStealTailData(__mmTail) {
  if (typeof pa === "undefined" || !Array.isArray(pa)) return null;
  for (let __mmIndex = 0; __mmIndex < pa.length; __mmIndex++)
    if (Number(pa[__mmIndex].id) === Number(__mmTail)) return pa[__mmIndex];
  return null;
}
function __mmMobStealMonkeyTailActive() {
  if (!v || !v.alive) return !1;
  const __mmPendingFresh = !!(
    __mmPendingTail != null &&
    Date.now() - __mmPendingTailAt <= Math.max(180, __mmServerTickMs() * 2)
  );
  return !!(
    Number(v.tailIndex) === 11 ||
    (__mmPendingFresh && Number(__mmPendingTail) === 11)
  );
}
function __mmMobStealDamage(__mmWeapon, __mmUseBull, __mmStripMonkeyTail) {
  const __mmData = b && b.weapons && b.weapons[__mmWeapon];
  if (!__mmData || __mmData.projectile != null) return 0;
  const __mmHat = __mmUseBull
      ? __mmPlayerHatData({ skinIndex: 7 })
      : __mmPlayerHatData(v),
    __mmTail = __mmStripMonkeyTail
      ? null
      : __mmMobStealTailData(v && v.tailIndex),
    __mmHatMultiplier = Number(__mmHat && __mmHat.dmgMultO) || 1,
    __mmTailMultiplier = Number(__mmTail && __mmTail.dmgMultO) || 1;
  return Math.max(
    0,
    (Number(__mmData.dmg) || 0) *
      __mmMobStealVariantMultiplier(__mmWeapon) *
      __mmHatMultiplier *
      __mmTailMultiplier,
  );
}
function __mmMobStealWeaponCandidates() {
  if (!v || !v.alive || !Array.isArray(v.weapons)) return [];
  const __mmUseBull = !!(
      __mmBullHelmetEnabled && __mmCanEquipHat(7)
    ),
    __mmStripMonkeyTail = __mmMobStealMonkeyTailActive(),
    __mmSelected = __mmSelectedWeapon(),
    __mmCandidates = [],
    __mmSeen = new Set();
  for (let __mmIndex = 0; __mmIndex < v.weapons.length; __mmIndex++) {
    const __mmWeapon = v.weapons[__mmIndex],
      __mmData = b && b.weapons && b.weapons[__mmWeapon],
      __mmRange = Number(__mmData && __mmData.range),
      __mmDamage = __mmMobStealDamage(
        __mmWeapon,
        __mmUseBull,
        __mmStripMonkeyTail,
      );
    if (
      __mmWeapon == null ||
      __mmSeen.has(__mmWeapon) ||
      !__mmData ||
      __mmData.projectile != null ||
      __mmData.shield ||
      !Number.isFinite(__mmRange) ||
      __mmRange <= 0 ||
      __mmDamage <= 0 ||
      !__mmWeaponReady(__mmWeapon)
    )
      continue;
    (__mmSeen.add(__mmWeapon),
      __mmCandidates.push({
        weapon: __mmWeapon,
        range: __mmRange,
        damage: __mmDamage,
        speed: Math.max(50, Number(__mmData.speed) || 400),
        selected: __mmWeapon === __mmSelected,
        useBull: __mmUseBull,
        stripMonkeyTail: __mmStripMonkeyTail,
      }));
  }
  return __mmCandidates;
}
function __mmMobStealPredictPoint(
  __mmEntity,
  __mmKey,
  __mmNow,
  __mmLeadMs,
) {
  const __mmX = Number(__mmEntity && __mmEntity.x),
    __mmY = Number(__mmEntity && __mmEntity.y);
  if (!Number.isFinite(__mmX) || !Number.isFinite(__mmY)) return null;
  const __mmPrevious = __mmMobStealMotion[__mmKey],
    __mmElapsed = __mmPrevious
      ? Math.max(1, Math.min(250, __mmNow - __mmPrevious.at))
      : 0;
  let __mmVelocityX = __mmPrevious
      ? (__mmX - __mmPrevious.x) / __mmElapsed
      : 0,
    __mmVelocityY = __mmPrevious
      ? (__mmY - __mmPrevious.y) / __mmElapsed
      : 0;
  const __mmServerElapsed = Number(__mmEntity.t2) - Number(__mmEntity.t1),
    __mmServerVelocityX =
      (Number(__mmEntity.x2) - Number(__mmEntity.x1)) / __mmServerElapsed,
    __mmServerVelocityY =
      (Number(__mmEntity.y2) - Number(__mmEntity.y1)) / __mmServerElapsed;
  if (
    Number.isFinite(__mmServerVelocityX) &&
    Number.isFinite(__mmServerVelocityY) &&
    __mmServerElapsed > 0 &&
    __mmServerElapsed <= 500
  ) {
    ((__mmVelocityX = __mmPrevious
      ? __mmServerVelocityX * 0.75 + __mmVelocityX * 0.25
      : __mmServerVelocityX),
      (__mmVelocityY = __mmPrevious
        ? __mmServerVelocityY * 0.75 + __mmVelocityY * 0.25
        : __mmServerVelocityY));
  }
  __mmMobStealMotion[__mmKey] = { x: __mmX, y: __mmY, at: __mmNow };
  return {
    x: Math.max(0, Math.min(y.mapScale, __mmX + __mmVelocityX * __mmLeadMs)),
    y: Math.max(0, Math.min(y.mapScale, __mmY + __mmVelocityY * __mmLeadMs)),
  };
}
function __mmMobStealPlan() {
  if (!v || !v.alive || !Array.isArray(N)) return null;
  const __mmWeapons = __mmMobStealWeaponCandidates();
  if (!__mmWeapons.length) return null;
  const __mmNow = Date.now(),
    __mmPing = Number(window.pingTime),
    __mmLeadMs = Math.min(
      300,
      __mmServerTickMs() +
        (Number.isFinite(__mmPing) ? Math.max(0, __mmPing / 2) : 0),
    ),
    __mmSelf = __mmMobStealPredictPoint(
      v,
      "self",
      __mmNow,
      __mmLeadMs,
    ),
    __mmSeen = Object.create(null);
  if (!__mmSelf) return null;
  __mmSeen.self = !0;
  let __mmBest = null;
  for (let __mmIndex = 0; __mmIndex < N.length; __mmIndex++) {
    const __mmAnimal = N[__mmIndex],
      __mmKey = __mmMobStealEntityKey(__mmAnimal);
    if (__mmKey == null) continue;
    __mmSeen[__mmKey] = !0;
    const __mmPrediction = __mmMobStealPredictPoint(
      __mmAnimal,
      __mmKey,
      __mmNow,
      __mmLeadMs,
    );
    if (
      !__mmPrediction ||
      !__mmAnimal ||
      __mmAnimal.active === !1 ||
      __mmAnimal.alive === !1 ||
      !__mmAnimal.visible ||
      !(Number(__mmAnimal.health) > 0) ||
      Number(__mmMobStealReservations[__mmKey]) > __mmNow
    )
      continue;
    for (
      let __mmWeaponIndex = 0;
      __mmWeaponIndex < __mmWeapons.length;
      __mmWeaponIndex++
    ) {
      const __mmWeapon = __mmWeapons[__mmWeaponIndex];
      if (Number(__mmAnimal.health) > __mmWeapon.damage + 0.001) continue;
      const __mmDx = __mmPrediction.x - __mmSelf.x,
        __mmDy = __mmPrediction.y - __mmSelf.y,
        __mmDistance = Math.hypot(__mmDx, __mmDy),
        // Match the server gather hitbox for players and AI targets.
        __mmReach =
          __mmWeapon.range + (Number(__mmAnimal.scale) || 35) * 1.8;
      if (__mmDistance > __mmReach) continue;
      const __mmScore =
        __mmDistance / Math.max(1, __mmReach) +
        (__mmWeapon.selected ? 0 : 0.08);
      if (!__mmBest || __mmScore < __mmBest.score)
        __mmBest = {
          animal: __mmAnimal,
          key: __mmKey,
          weapon: __mmWeapon.weapon,
          damage: __mmWeapon.damage,
          speed: __mmWeapon.speed,
          useBull: __mmWeapon.useBull,
          stripMonkeyTail: __mmWeapon.stripMonkeyTail,
          restoreTail: __mmWeapon.stripMonkeyTail ? 11 : null,
          x: __mmPrediction.x,
          y: __mmPrediction.y,
          angle: Math.atan2(__mmDy, __mmDx),
          score: __mmScore,
        };
    }
  }
  for (const __mmKey in __mmMobStealMotion)
    __mmSeen[__mmKey] || delete __mmMobStealMotion[__mmKey];
  for (const __mmKey in __mmMobStealReservations)
    Number(__mmMobStealReservations[__mmKey]) <= __mmNow &&
      delete __mmMobStealReservations[__mmKey];
  return __mmBest;
}
function __mmFinishMobSteal(__mmReason) {
  const __mmAim = __mmMobStealAimAngle,
    __mmHadAim = Number.isFinite(__mmMobStealAimAngle),
    __mmTool = __mmMobStealRestoreTool,
    __mmHat = __mmMobStealRestoreHat,
    __mmTail = __mmMobStealRestoreTail,
    __mmRestore = __mmActionMayRestore("mobSteal");
  (__mmMobStealStageTimer && clearTimeout(__mmMobStealStageTimer),
    (__mmMobStealStageTimer = 0),
    __mmMobStealReleaseTimer && clearTimeout(__mmMobStealReleaseTimer),
    (__mmMobStealReleaseTimer = 0),
    __mmMobStealAttackHeld && O.send("F", 0, __mmAim),
    (__mmMobStealAttackHeld = !1),
    (__mmMobStealAimAngle = null),
    (__mmMobStealRestoreTool = null),
    (__mmMobStealRestoreHat = null),
    (__mmMobStealRestoreTail = null),
    (__mmMobStealPendingPlan = null),
    __mmRestore && __mmRestoreTool(__mmTool),
    __mmRestore && __mmEquipGearPair(__mmHat, __mmTail, !0),
    __mmActionRelease("mobSteal", __mmReason || "predicted last hit complete"),
    __mmHadAim && __mmScheduleMouseAimReturn(),
    v && v.alive && __mmUpdateWeaponRecharge());
}
function __mmMobStealFirePending() {
  ((__mmMobStealStageTimer = 0));
  const __mmPlan = __mmMobStealPendingPlan;
  if (
    !__mmPlan ||
    !v ||
    !v.alive ||
    __mmActionOwner !== "mobSteal" ||
    __mmEmergencyGetawayActive()
  )
    return void __mmFinishMobSteal("staged mob steal interrupted");
  const __mmAnimal = __mmPlan.animal,
    __mmHealth = Number(__mmAnimal && __mmAnimal.health),
    __mmNow = Date.now(),
    __mmPing = Number(window.pingTime),
    __mmLeadMs =
      __mmServerTickMs() +
      (Number.isFinite(__mmPing) ? Math.max(0, __mmPing / 2) : 0),
    __mmTarget = __mmMobStealPredictPoint(
      __mmAnimal,
      __mmPlan.key,
      __mmNow,
      __mmLeadMs,
    ),
    __mmSelf = __mmMobStealPredictPoint(
      v,
      "self",
      __mmNow,
      __mmLeadMs,
    ),
    __mmWeaponData = b && b.weapons && b.weapons[__mmPlan.weapon];
  if (
    !__mmAnimal ||
    __mmAnimal.active === !1 ||
    __mmAnimal.alive === !1 ||
    !__mmAnimal.visible ||
    !Number.isFinite(__mmHealth) ||
    __mmHealth <= 0 ||
    __mmHealth > __mmPlan.damage + 0.001 ||
    !__mmTarget ||
    !__mmSelf ||
    !__mmWeaponData ||
    !__mmWeaponReady(__mmPlan.weapon)
  )
    return void __mmFinishMobSteal("staged target no longer lethal");
  const __mmDx = __mmTarget.x - __mmSelf.x,
    __mmDy = __mmTarget.y - __mmSelf.y,
    __mmDistance = Math.hypot(__mmDx, __mmDy),
    __mmReach =
      (Number(__mmWeaponData.range) || 0) +
      (Number(__mmAnimal.scale) || 35) * 1.8;
  if (__mmDistance > __mmReach)
    return void __mmFinishMobSteal("staged target left range");
  if (
    __mmPlan.stripMonkeyTail &&
    Number(v.tailIndex) !== 0 &&
    Number(__mmPendingTail) !== 0
  )
    return void __mmFinishMobSteal("monkey tail returned before hit");
  const __mmAngle = Math.atan2(__mmDy, __mmDx);
  ((__mmMobStealAimAngle = __mmAngle),
    O.send("D", __mmAngle),
    je(__mmPlan.weapon, !0),
    __mmPlan.useBull &&
      __mmActivateCombatHat(7, __mmPlan.stripMonkeyTail ? 0 : null),
    O.send("F", 1, __mmAngle),
    (__mmMobStealAttackHeld = !0),
    (__mmMobStealReleaseTimer = setTimeout(function () {
      __mmFinishMobSteal("predicted last hit sent");
    }, Math.max(120, __mmServerTickMs() * 2))));
}
function __mmMobStealEquipBullStage() {
  ((__mmMobStealStageTimer = 0));
  const __mmPlan = __mmMobStealPendingPlan;
  if (
    !__mmPlan ||
    !v ||
    !v.alive ||
    __mmActionOwner !== "mobSteal" ||
    __mmEmergencyGetawayActive()
  )
    return void __mmFinishMobSteal("staged mob steal interrupted");
  // Monkey Tail remains staged early for damage correctness, but Bull itself
  // is deliberately deferred to __mmMobStealFirePending so it shares the
  // weapon's exact packet phase.
  __mmMobStealStageTimer = setTimeout(
    __mmMobStealFirePending,
    __mmServerTickMs() * 2,
  );
}
function __mmStartMobStealAttack(__mmPlan) {
  if (
    !__mmPlan ||
    !v ||
    !v.alive ||
    __mmEmergencyGetawayActive()
  )
    return !1;
  (__mmActionOwner === "weaponRecharge" && __mmPauseWeaponRecharge(!0),
    __mmActionOwner === "matThief" &&
      __mmFinishMatThief("mob steal last hit"));
  if (!__mmActionClaim("mobSteal", "predicted one-hit mob")) return !1;
  const __mmNow = Date.now();
  (__mmMobStealReservations[__mmPlan.key] =
    __mmNow +
      Math.max(__mmPlan.speed, 5 * __mmServerTickMs()),
    (__mmMobStealRestoreTool = __mmSelectedTool()),
    (__mmMobStealRestoreHat = __mmPlan.useBull
      ? __mmInstaSafeRestoreHat(__mmBushRestoreHat(v.skinIndex))
      : null),
    (__mmMobStealRestoreTail = __mmPlan.stripMonkeyTail
      ? __mmBushRestoreTail(__mmPlan.restoreTail)
      : null),
    (__mmMobStealPendingPlan = __mmPlan),
    __mmPlan.stripMonkeyTail && __mmEquipTailNow(0, !0),
    // Do not swing unless the tail-off request was actually emitted or is
    // already active. This prevents Shift escape or another gear lock from
    // allowing a reduced-damage Monkey Tail hit through.
    __mmPlan.stripMonkeyTail &&
      Number(v.tailIndex) !== 0 &&
      Number(__mmPendingTail) !== 0)
    return (
      delete __mmMobStealReservations[__mmPlan.key],
      (__mmMobStealRestoreTool = null),
      (__mmMobStealRestoreHat = null),
      (__mmMobStealRestoreTail = null),
      (__mmMobStealPendingPlan = null),
      __mmActionRelease("mobSteal", "monkey tail removal blocked"),
      !1
    );
  __mmMobStealStageTimer = setTimeout(
    __mmMobStealEquipBullStage,
    __mmServerTickMs(),
  );
  return !0;
}
function __mmUpdateMobSteal() {
  if (
    !__mmMobStealEnabled ||
    document.hidden ||
    !v ||
    !v.alive ||
    v.lockMove ||
    __mmMobStealReleaseTimer ||
    __mmPrimaryHeld ||
    __mmSecondaryHeld ||
    __mmTrapAttackActive ||
    __mmBoostBreakHeld ||
    __mmBuildSpamTimer ||
    __mmFoodSpamTimer ||
    __mmInsta.isActive() ||
    __mmSyncFollowerEnabled ||
    !(
      __mmActionOwner === "idle" ||
      __mmActionOwner === "weaponRecharge" ||
      __mmActionOwner === "matThief"
    )
  )
    return;
  const __mmPlan = __mmMobStealPlan();
  __mmPlan && __mmStartMobStealAttack(__mmPlan);
}
function __mmStartMobSteal() {
  __mmEnsureOperationPipeline();
}
function __mmStopMobSteal() {
  (__mmMobStealTimer && clearInterval(__mmMobStealTimer),
    (__mmMobStealTimer = 0),
    __mmFinishMobSteal("mode disabled"));
}
function __mmRecordPlayerSwing(__mmPlayerSid, __mmWeapon) {
  if (__mmPlayerSid == null) return;
  __mmCombatThreatCalculatedAt = 0;
  __mmTrackPlayerToolCooldown(__mmPlayerSid, __mmWeapon);
  __mmRecentPlayerSwings[String(__mmPlayerSid)] = {
    at: Date.now(),
    weapon: __mmWeapon,
  };
}
function __mmObservedObjectHitDamage(__mmObject, __mmHitAngle) {
  if (!__mmObject || !Array.isArray(E)) return 0;
  const __mmNow = Date.now();
  let __mmBestDamage = 0,
    __mmBestScore = Infinity;
  for (let __mmIndex = 0; __mmIndex < E.length; __mmIndex++) {
    const __mmPlayer = E[__mmIndex],
      __mmRecent =
        __mmPlayer && __mmRecentPlayerSwings[String(__mmPlayer.sid)];
    if (!__mmPlayer || !__mmPlayer.alive || !__mmRecent) continue;
    const __mmAge = __mmNow - __mmRecent.at,
      __mmWeaponId =
        __mmRecent.weapon == null ? __mmPlayer.weaponIndex : __mmRecent.weapon,
      __mmWeapon = b.weapons && b.weapons[__mmWeaponId];
    if (__mmAge < 0 || __mmAge > 900 || !__mmWeapon) continue;
    const __mmDx = __mmObject.x - __mmPlayer.x,
      __mmDy = __mmObject.y - __mmPlayer.y,
      __mmDistance = Math.hypot(__mmDx, __mmDy),
      __mmDirection = Math.atan2(__mmDy, __mmDx),
      __mmAngleDifference = M.getAngleDist(__mmDirection, __mmHitAngle),
      __mmMeleeReach =
        (Number(__mmWeapon.range) || 0) + (Number(__mmObject.scale) || 0) + 16;
    if (
      __mmWeapon.projectile == null &&
      (__mmDistance > __mmMeleeReach || __mmAngleDifference > 0.32)
    )
      continue;
    const __mmDamage = __mmWeaponStructureDamage(
      __mmPlayer,
      __mmWeaponId,
      __mmObject,
    );
    if (!__mmDamage) continue;
    const __mmScore = __mmAge +
      (__mmWeapon.projectile == null ? __mmDistance : 300);
    if (__mmScore < __mmBestScore) {
      ((__mmBestScore = __mmScore), (__mmBestDamage = __mmDamage));
    }
  }
  return __mmBestDamage || __mmCurrentStructureDamage(__mmObject);
}
function __mmObserveObjectHit(__mmAngle, __mmObjectSid) {
  const __mmObject = typeof ns === "function" ? ns(__mmObjectSid) : null,
    __mmState = __mmBreakableState(__mmObject);
  if (!__mmObject || !__mmState) return;
  const __mmDamage = __mmObservedObjectHitDamage(
    __mmObject,
    Number(__mmAngle) || 0,
  );
  if (__mmDamage > 0)
    __mmState.health = Math.max(0, __mmState.health - __mmDamage);
}
function __mmBreakableHitLabel(__mmObject) {
  const __mmState = __mmBreakableState(__mmObject);
  if (!__mmState || !(Number(__mmState.health) > 0)) return null;
  const __mmSignature = [
      Number(__mmState.health).toFixed(3),
      Number(v && v.weaponIndex),
      Number(v && v.skinIndex),
      Number(v && v.tailIndex),
    ].join(":"),
    __mmCached = __mmBreakableLabelCache.get(__mmObject);
  if (__mmCached && __mmCached.signature === __mmSignature)
    return __mmCached.label;
  const __mmDamage = __mmCurrentStructureDamage(__mmObject);
  // A zero-damage tool used to draw an infinity glyph, and a locally
  // destroyed object could briefly draw 0 while waiting for server removal.
  // Both collapse into a stray center dot at normal game scale. Only render
  // actionable, positive hit counts.
  if (!(__mmDamage > 0)) return null;
  const __mmLabel = String(
    Math.max(1, Math.ceil(__mmState.health / __mmDamage)),
  );
  __mmBreakableLabelCache.set(__mmObject, {
    signature: __mmSignature,
    label: __mmLabel,
  });
  return __mmLabel;
}
function __mmDrawBreakableHitCounts() {
  if (!v || !v.alive || !k) return;
  const __mmLeft = oe - _ / 2,
    __mmTop = ae - L / 2,
    __mmBreakables = __mmActiveObjectSnapshot().breakables;
  (k.save(),
    (k.textAlign = "center"),
    (k.textBaseline = "middle"),
    (k.globalAlpha = 0.96),
    (k.shadowColor = "#a855f7"),
    (k.shadowBlur = __mmFpsBoostEnabled ? 0 : 4),
    (k.strokeStyle = "rgba(5,3,9,.92)"),
    (k.lineWidth = 3),
    (k.font = "900 20px Hammersmith One, Arial, sans-serif"),
    (k.fillStyle = "#ffffff"));
  for (let __mmIndex = 0; __mmIndex < __mmBreakables.length; __mmIndex++) {
    const __mmObject = __mmBreakables[__mmIndex].object;
    if (!__mmObject || !__mmObject.active) continue;
    const __mmX = __mmObject.x + __mmObject.xWiggle - __mmLeft,
      __mmY = __mmObject.y + __mmObject.yWiggle - __mmTop;
    if (!ts(__mmX, __mmY, (Number(__mmObject.scale) || 35) + 10)) continue;
    const __mmHits = __mmBreakableHitLabel(__mmObject);
    if (__mmHits == null) continue;
    (k.strokeText(__mmHits, __mmX, __mmY),
      k.fillText(__mmHits, __mmX, __mmY));
  }
  k.restore();
}
function __mmDrawPlacementVisuals() {
  if (!__mmPlacementVisualsEnabled || !v || !v.alive || !k) return;
  const __mmPreview = __mmSmartPlacementPreview,
    __mmNow = performance.now(),
    __mmAge = __mmNow - Number(__mmPreview && __mmPreview.updatedAt);
  if (!__mmPreview || !__mmPreview.updatedAt || __mmAge > 850) return;
  const __mmFade = Math.max(0, Math.min(1, (850 - __mmAge) / 220)),
    __mmLeft = oe - _ / 2,
    __mmTop = ae - L / 2,
    __mmOwnX = Number(v.x) - __mmLeft,
    __mmOwnY = Number(v.y) - __mmTop;
  function __mmDrawSlot(
    __mmCandidate,
    __mmColor,
    __mmAlpha,
    __mmWidth,
    __mmDash,
    __mmFill,
    __mmLabel,
  ) {
    if (!__mmCandidate) return;
    const __mmX = Number(__mmCandidate.x) - __mmLeft,
      __mmY = Number(__mmCandidate.y) - __mmTop,
      __mmScale = Math.max(8, Number(__mmCandidate.scale) || 45);
    if (!ts(__mmX, __mmY, __mmScale + 18)) return;
    (k.save(),
      (k.globalAlpha = __mmAlpha * __mmFade),
      (k.strokeStyle = __mmColor),
      (k.fillStyle = __mmColor),
      (k.lineWidth = __mmWidth),
      (k.shadowColor = __mmColor),
      (k.shadowBlur = __mmFpsBoostEnabled ? 0 : __mmWidth >= 3 ? 8 : 3),
      typeof k.setLineDash === "function" && k.setLineDash(__mmDash || []),
      k.beginPath(),
      k.arc(__mmX, __mmY, __mmScale, 0, Math.PI * 2));
    if (__mmFill) {
      const __mmStrokeAlpha = k.globalAlpha;
      ((k.globalAlpha = __mmStrokeAlpha * 0.2),
        k.fill(),
        (k.globalAlpha = __mmStrokeAlpha));
    }
    k.stroke();
    if (__mmLabel) {
      ((k.shadowBlur = __mmFpsBoostEnabled ? 0 : 5),
        (k.fillStyle = "#ffffff"),
        (k.font = "900 12px Hammersmith One, Arial, sans-serif"),
        (k.textAlign = "center"),
        (k.textBaseline = "middle"),
        k.fillText(__mmLabel, __mmX, __mmY));
    }
    k.restore();
  }
  k.save();
  const __mmSamples = Array.isArray(__mmPreview.samples)
    ? __mmPreview.samples
    : [];
  for (let __mmIndex = 0; __mmIndex < __mmSamples.length; __mmIndex++) {
    const __mmCandidate = __mmSamples[__mmIndex],
      __mmValid = __mmCandidate && __mmCandidate.valid !== !1;
    __mmDrawSlot(
      __mmCandidate,
      __mmValid ? "#8b5cf6" : "#ef4444",
      __mmValid ? 0.16 : 0.2,
      1,
      __mmValid ? [3, 5] : [2, 4],
      !1,
      "",
    );
  }
  const __mmRanked = Array.isArray(__mmPreview.ranked)
    ? __mmPreview.ranked
    : [];
  for (let __mmIndex = __mmRanked.length - 1; __mmIndex >= 0; __mmIndex--) {
    const __mmCandidate = __mmRanked[__mmIndex];
    __mmDrawSlot(
      __mmCandidate,
      __mmCandidate.preplace ? "#38bdf8" : "#c084fc",
      0.34,
      1.6,
      __mmCandidate.preplace ? [7, 4] : [],
      !1,
      "",
    );
  }
  const __mmSelected = Array.isArray(__mmPreview.selected)
    ? __mmPreview.selected
    : [];
  for (let __mmIndex = 0; __mmIndex < __mmSelected.length; __mmIndex++) {
    const __mmCandidate = __mmSelected[__mmIndex],
      __mmX = Number(__mmCandidate.x) - __mmLeft,
      __mmY = Number(__mmCandidate.y) - __mmTop,
      __mmName = String(
        (__mmCandidate.data && __mmCandidate.data.name) || "place",
      ).toLowerCase(),
      __mmKind = __mmCandidate.data && __mmCandidate.data.trap
        ? "T"
        : __mmName.includes("spike")
          ? "S"
          : __mmName.slice(0, 1).toUpperCase(),
      __mmColor = __mmCandidate.preplace ? "#38bdf8" : "#34d399";
    (k.save(),
      (k.globalAlpha = 0.45 * __mmFade),
      (k.strokeStyle = __mmColor),
      (k.lineWidth = 1.4),
      typeof k.setLineDash === "function" && k.setLineDash([5, 5]),
      k.beginPath(),
      k.moveTo(__mmOwnX, __mmOwnY),
      k.lineTo(__mmX, __mmY),
      k.stroke(),
      k.restore());
    __mmDrawSlot(
      __mmCandidate,
      __mmColor,
      0.78,
      3.2,
      __mmCandidate.preplace ? [8, 4] : [],
      !0,
      __mmKind + " " + Number(__mmCandidate.points || 0).toFixed(1),
    );
  }
  k.restore();
}
Ge = function (__mmLayer, __mmLeft, __mmTop) {
  if (!__mmGroundGridFrameDrawn) {
    ((__mmGroundGridFrameDrawn = !0),
      __mmDrawGroundGrid(__mmLeft, __mmTop));
  }
  return __mmOriginalObjectRender.apply(this, arguments);
};
Wl = function (__mmAngle, __mmObjectSid) {
  __mmObserveObjectHit(__mmAngle, __mmObjectSid);
  return __mmOriginalObjectHit.apply(this, arguments);
};
function __mmSmartDepthCeiling() {
  return Math.max(1, Math.min(10, Math.round(Number(__mmSmartDepth) || 1)));
}
function __mmEffectiveSmartDepth() {
  const __mmCeiling = __mmSmartDepthCeiling();
  if (!__mmAdaptiveSmartnessEnabled) return __mmCeiling;
  return Math.max(
    1,
    Math.min(
      __mmCeiling,
      Math.round(Number(__mmAdaptiveSmartDepth) || __mmCeiling),
    ),
  );
}
function __mmAdaptiveSmartnessCombatActive() {
  if (!v || !v.alive) return !1;
  if (
    __mmLiveStateFresh() &&
    __mmLiveState.nearestEnemyDistance <= Math.max(__mmCombatRange, 650)
  )
    return !0;
  if (__mmPrimaryHeld || __mmSecondaryHeld || __mmTrapAttackActive) return !0;
  return (
    __mmActionOwner === "insta" ||
    __mmActionOwner === "instaSync" ||
    __mmActionOwner === "boostInsta" ||
    __mmActionOwner === "spikeTickStrike" ||
    __mmActionOwner === "antiInsta" ||
    __mmActionOwner === "antiBoostBlock" ||
    __mmActionOwner === "shieldDefense" ||
    __mmActionOwner === "autoPushSetup" ||
    __mmActionOwner === "velTickSetup"
  );
}
function __mmPublishAdaptiveSmartness() {
  window.dispatchEvent(
    new CustomEvent("MooMooKittyAdaptiveSmartness", {
      detail: {
        enabled: __mmAdaptiveSmartnessEnabled,
        effective: __mmEffectiveSmartDepth(),
        ceiling: __mmSmartDepthCeiling(),
        fps: Number.isFinite(__mmMetricFps) && __mmMetricFps > 0
          ? __mmMetricFps
          : null,
        combat: __mmAdaptiveCombat,
        reason: __mmAdaptiveSmartnessEnabled
          ? __mmAdaptiveReason
          : "manual ceiling",
      },
    }),
  );
}
function __mmResetAdaptiveSmartness(__mmReason = "sampling") {
  ((__mmAdaptiveSmartDepth = __mmSmartDepthCeiling()),
    (__mmAdaptiveFpsEma =
      Number.isFinite(__mmMetricFps) && __mmMetricFps > 0
        ? __mmMetricFps
        : 60),
    (__mmAdaptiveLowSince = 0),
    (__mmAdaptiveStableSince = 0),
    (__mmAdaptiveLastChangeAt = 0),
    (__mmAdaptiveReason = __mmReason),
    (__mmAdaptiveCombat = !1),
    __mmPublishAdaptiveSmartness());
}
function __mmUpdateAdaptiveSmartness(__mmFps, __mmNow) {
  const __mmCeiling = __mmSmartDepthCeiling();
  if (!__mmAdaptiveSmartnessEnabled) {
    ((__mmAdaptiveSmartDepth = __mmCeiling),
      (__mmAdaptiveReason = "manual ceiling"),
      (__mmAdaptiveCombat = !1),
      __mmPublishAdaptiveSmartness());
    return;
  }
  __mmAdaptiveSmartDepth = Math.max(
    1,
    Math.min(__mmCeiling, Math.round(Number(__mmAdaptiveSmartDepth) || __mmCeiling)),
  );
  if (
    !Number.isFinite(__mmFps) ||
    __mmFps <= 0 ||
    document.hidden ||
    __mmHudMenuOpen ||
    __mmNativeMenuOpen
  ) {
    ((__mmAdaptiveLowSince = 0),
      (__mmAdaptiveStableSince = 0),
      (__mmAdaptiveReason = __mmHudMenuOpen || __mmNativeMenuOpen
        ? "paused while menu open"
        : document.hidden
          ? "paused while hidden"
          : "sampling"),
      __mmPublishAdaptiveSmartness());
    return;
  }
  __mmAdaptiveFpsEma =
    __mmAdaptiveFpsEma > 0
      ? __mmAdaptiveFpsEma * 0.72 + __mmFps * 0.28
      : __mmFps;
  __mmAdaptiveCombat = __mmAdaptiveSmartnessCombatActive();
  const __mmCritical = __mmFps < 28 || __mmAdaptiveFpsEma < 32,
    __mmLow = __mmCritical || __mmFps < 40 || __mmAdaptiveFpsEma < 44,
    __mmStableThreshold = __mmAdaptiveCombat ? 50 : 55,
    __mmStable =
      __mmFps >= __mmStableThreshold &&
      __mmAdaptiveFpsEma >= __mmStableThreshold - 1;
  if (__mmLow) {
    __mmAdaptiveStableSince = 0;
    __mmAdaptiveLowSince || (__mmAdaptiveLowSince = __mmNow);
    const __mmDwell = __mmCritical ? 350 : 1000,
      __mmChangeGap = __mmCritical ? 650 : 1050;
    if (
      __mmAdaptiveSmartDepth > 1 &&
      __mmNow - __mmAdaptiveLowSince >= __mmDwell &&
      __mmNow - __mmAdaptiveLastChangeAt >= __mmChangeGap
    ) {
      __mmAdaptiveSmartDepth = Math.max(
        1,
        __mmAdaptiveSmartDepth - (__mmCritical ? 2 : 1),
      );
      ((__mmAdaptiveLastChangeAt = __mmNow),
        (__mmAdaptiveLowSince = __mmNow),
        (__mmAdaptiveReason = __mmCritical
          ? "critical FPS · depth reduced"
          : "FPS pressure · depth reduced"));
    } else
      __mmAdaptiveReason = __mmAdaptiveSmartDepth > 1
        ? "FPS pressure · watching"
        : "minimum depth · FPS pressure";
  } else if (__mmStable) {
    __mmAdaptiveLowSince = 0;
    __mmAdaptiveStableSince || (__mmAdaptiveStableSince = __mmNow);
    const __mmRecoveryDwell = __mmAdaptiveCombat ? 1000 : 2600,
      __mmRecoveryGap = __mmAdaptiveCombat ? 1200 : 2800;
    if (
      __mmAdaptiveSmartDepth < __mmCeiling &&
      __mmNow - __mmAdaptiveStableSince >= __mmRecoveryDwell &&
      __mmNow - __mmAdaptiveLastChangeAt >= __mmRecoveryGap
    ) {
      __mmAdaptiveSmartDepth += 1;
      ((__mmAdaptiveLastChangeAt = __mmNow),
        (__mmAdaptiveStableSince = __mmNow),
        (__mmAdaptiveReason = __mmAdaptiveCombat
          ? "stable combat · depth raised"
          : "stable FPS · depth raised"));
    } else if (__mmAdaptiveSmartDepth < __mmCeiling)
      __mmAdaptiveReason = __mmAdaptiveCombat
        ? "stable combat · recovering"
        : "stable FPS · recovering";
    else
      __mmAdaptiveReason = __mmAdaptiveCombat
        ? "full depth · stable combat"
        : "full depth · stable FPS";
  } else {
    ((__mmAdaptiveLowSince = 0),
      (__mmAdaptiveStableSince = 0),
      (__mmAdaptiveReason = "holding depth"));
  }
  __mmPublishAdaptiveSmartness();
}
function __mmUpdateMetrics() {
  __mmMetricFrames += 1;
  const __mmNow = performance.now(),
    __mmElapsed = __mmNow - __mmMetricUpdatedAt;
  if (__mmElapsed < 500) return;
  ((__mmMetricFps = __mmMetricFrames * 1000 / __mmElapsed),
    (__mmMetricPps = __mmMetricPacketWindow * 1000 / __mmElapsed),
    (__mmMetricFrames = 0),
    (__mmMetricPacketWindow = 0),
    (__mmMetricUpdatedAt = __mmNow),
    __mmUpdateAdaptiveSmartness(__mmMetricFps, __mmNow),
    window.dispatchEvent(
      new CustomEvent("MooMooKittyMetrics", {
        detail: {
          ping: Number.isFinite(Number(window.pingTime)) ? Number(window.pingTime) : null,
          fps: __mmMetricFps,
          packets: __mmMetricPackets,
          pps: __mmMetricPps,
          smartDepth: __mmEffectiveSmartDepth(),
          smartDepthCeiling: __mmSmartDepthCeiling(),
        },
      }),
    ));
}
function __mmChatPlayer(__mmPlayerSid) {
  try {
    return typeof Rt === "function" ? Rt(__mmPlayerSid) : null;
  } catch (__mmChatPlayerError) {
    return null;
  }
}
function __mmChatRelation(__mmPlayer) {
  if (
    v &&
    __mmPlayer &&
    String(__mmPlayer.sid) === String(v.sid)
  )
    return "self";
  if (__mmPlayer && __mmIsFriendPlayer(__mmPlayer)) return "friend";
  if (__mmPlayer && __mmSameTeam(__mmPlayer)) return "ally";
  return "enemy";
}
function __mmRecordChatMessage(
  __mmPlayerSid,
  __mmRawMessage,
) {
  if (!__mmChatHistoryEnabled) {
    delete __mmChatBubbleStacks[String(__mmPlayerSid)];
    return;
  }
  const __mmPlayer = __mmChatPlayer(__mmPlayerSid),
    __mmMessage = String(
      (__mmPlayer && __mmPlayer.chatMessage) || __mmRawMessage || "",
    ).slice(0, 120),
    __mmNow = performance.now(),
    __mmDuration = Math.max(
      700,
      Number(__mmPlayer && __mmPlayer.chatCountdown) || 3e3,
    ),
    __mmSid = String(__mmPlayerSid);
  let __mmStack = __mmChatBubbleStacks[__mmSid];
  if (!Array.isArray(__mmStack)) __mmStack = [];
  // Native chatMessage remains populated after its bubble has disappeared.
  // Keep only Kitty-owned entries whose independent lifetime is still live so
  // a later message can never resurrect already-faded text.
  __mmStack = __mmStack.filter(function (__mmEntry) {
    return __mmEntry && __mmEntry.expiresAt > __mmNow;
  });
  __mmStack.push({
    text: __mmMessage,
    createdAt: __mmNow,
    expiresAt: __mmNow + __mmDuration,
  });
  __mmStack.length > 3 && __mmStack.splice(0, __mmStack.length - 3);
  __mmChatBubbleStacks[__mmSid] = __mmStack;
  window.dispatchEvent(
    new CustomEvent("MooMooKittyChatMessage", {
      detail: {
        sid: __mmPlayerSid,
        name:
          String((__mmPlayer && __mmPlayer.name) || "").trim() ||
          "Player " + __mmPlayerSid,
        message: __mmMessage,
        relation: __mmChatRelation(__mmPlayer),
        at: Date.now(),
      },
    }),
  );
}
function __mmHideNativeChatBubbles() {
  if (!__mmChatHistoryEnabled || !Array.isArray(E)) return [];
  const __mmHidden = [];
  for (let __mmIndex = 0; __mmIndex < E.length; __mmIndex++) {
    const __mmPlayer = E[__mmIndex],
      __mmCountdown = Number(__mmPlayer && __mmPlayer.chatCountdown);
    if (!__mmPlayer || !__mmPlayer.visible || __mmCountdown <= 0) continue;
    (__mmHidden.push({ player: __mmPlayer, countdown: __mmCountdown }),
      (__mmPlayer.chatCountdown = 0));
  }
  return __mmHidden;
}
function __mmRestoreNativeChatBubbles(__mmHidden) {
  if (!Array.isArray(__mmHidden)) return;
  for (let __mmIndex = 0; __mmIndex < __mmHidden.length; __mmIndex++) {
    const __mmEntry = __mmHidden[__mmIndex];
    __mmEntry.player &&
      (__mmEntry.player.chatCountdown = __mmEntry.countdown);
  }
}
function __mmDrawKittyChatBubble(
  __mmText,
  __mmX,
  __mmY,
  __mmAlpha,
  __mmUpper,
) {
  if (!k || !__mmText || __mmAlpha <= 0) return;
  const __mmFontSize = __mmUpper ? 34 : 31,
    __mmHeight = __mmUpper ? 54 : 49,
    __mmPadding = __mmUpper ? 34 : 28,
    __mmMaxWidth = __mmUpper ? 560 : 520;
  k.save();
  ((k.globalAlpha = Math.min(1, __mmAlpha) * 0.96),
    (k.font =
      "600 " + __mmFontSize + "px Hammersmith One, Arial, sans-serif"),
    (k.textBaseline = "middle"),
    (k.textAlign = "center"));
  const __mmWidthKey = String(__mmUpper ? 1 : 0) + ":" + __mmText;
  let __mmWidth = __mmChatBubbleWidthCache.get(__mmWidthKey);
  if (!Number.isFinite(__mmWidth)) {
    __mmWidth = Math.min(
      __mmMaxWidth,
      k.measureText(__mmText).width + __mmPadding,
    );
    (__mmChatBubbleWidthCache.size >= 180 &&
      __mmChatBubbleWidthCache.clear(),
      __mmChatBubbleWidthCache.set(__mmWidthKey, __mmWidth));
  }
  let __mmFillStyle;
  if (__mmFpsBoostEnabled)
    __mmFillStyle = __mmUpper
      ? "rgba(35,13,55,.88)"
      : "rgba(24,10,38,.88)";
  else {
    const __mmGradient = k.createLinearGradient(
      __mmX - __mmWidth / 2,
      __mmY,
      __mmX + __mmWidth / 2,
      __mmY,
    );
    (__mmGradient.addColorStop(
      0,
      __mmUpper ? "rgba(14,7,23,.88)" : "rgba(8,5,13,.86)",
    ),
      __mmGradient.addColorStop(
        1,
        __mmUpper ? "rgba(58,18,88,.82)" : "rgba(45,15,70,.78)",
      ));
    __mmFillStyle = __mmGradient;
  }
  ((k.shadowColor = "rgba(168,85,247,.72)"),
    (k.shadowBlur = __mmFpsBoostEnabled ? 0 : __mmUpper ? 14 : 12),
    (k.fillStyle = __mmFillStyle),
    k.beginPath());
  typeof k.roundRect === "function"
    ? k.roundRect(
        __mmX - __mmWidth / 2,
        __mmY - __mmHeight / 2,
        __mmWidth,
        __mmHeight,
        __mmUpper ? 10 : 9,
      )
    : k.rect(
        __mmX - __mmWidth / 2,
        __mmY - __mmHeight / 2,
        __mmWidth,
        __mmHeight,
      );
  (k.fill(),
    (k.shadowBlur = __mmFpsBoostEnabled ? 0 : 5),
    (k.strokeStyle = "rgba(216,180,254,.78)"),
    (k.lineWidth = __mmUpper ? 1.5 : 1.25),
    k.stroke(),
    (k.fillStyle = "#ffffff"),
    (k.shadowColor = "#8b5cf6"),
    (k.shadowBlur = __mmFpsBoostEnabled ? 0 : __mmUpper ? 9 : 8),
    k.fillText(
      __mmText,
      __mmX,
      __mmY,
      Math.max(1, __mmWidth - __mmPadding + 4),
    ),
    k.restore());
}
function __mmDrawInterruptedChats() {
  if (!__mmChatHistoryEnabled || !k || !Array.isArray(E)) return;
  const __mmNow = performance.now(),
    __mmLeft = oe - _ / 2,
    __mmTop = ae - L / 2;
  // Expiry bookkeeping does not need animation-frame cadence. The bubbles
  // still animate each frame, while stale-map cleanup runs four times a second.
  if (__mmNow >= __mmChatBubbleCleanupAt) {
    __mmChatBubbleCleanupAt = __mmNow + 250;
    for (const __mmSid in __mmChatBubbleStacks) {
      const __mmStack = __mmChatBubbleStacks[__mmSid];
      if (!Array.isArray(__mmStack)) {
        delete __mmChatBubbleStacks[__mmSid];
        continue;
      }
      for (let __mmIndex = __mmStack.length - 1; __mmIndex >= 0; __mmIndex--)
        __mmNow >= __mmStack[__mmIndex].expiresAt &&
          __mmStack.splice(__mmIndex, 1);
      __mmStack.length || delete __mmChatBubbleStacks[__mmSid];
    }
  }
  let __mmRenderedBubblePlayers = 0;
  const __mmBubblePlayerLimit = __mmFpsBoostEnabled ? 6 : Infinity;
  for (let __mmIndex = 0; __mmIndex < E.length; __mmIndex++) {
    const __mmPlayer = E[__mmIndex];
    if (!__mmPlayer || !__mmPlayer.visible) continue;
    const __mmSid = String(__mmPlayer.sid),
      __mmStack = __mmChatBubbleStacks[__mmSid];
    if (!Array.isArray(__mmStack) || !__mmStack.length) continue;
    const __mmX = Number(__mmPlayer.x) - __mmLeft,
      __mmMainY =
        Number(__mmPlayer.y) -
        (Number(__mmPlayer.scale) || 35) -
        __mmTop -
        104;
    if (!ts(__mmX, __mmMainY, 145)) continue;
    if (++__mmRenderedBubblePlayers > __mmBubblePlayerLimit) break;
    const __mmFirstVisible = Math.max(0, __mmStack.length - 3),
      __mmVisibleCount = __mmStack.length - __mmFirstVisible;
    for (
      let __mmMessageIndex = 0;
      __mmMessageIndex < __mmVisibleCount;
      __mmMessageIndex++
    ) {
      const __mmState = __mmStack[__mmFirstVisible + __mmMessageIndex],
        __mmDistanceFromNewest =
          __mmVisibleCount - 1 - __mmMessageIndex,
        __mmUpper = __mmDistanceFromNewest > 0,
        __mmEnter = Math.min(
          1,
          Math.max(0, (__mmNow - __mmState.createdAt) / 160),
        ),
        __mmRemaining = __mmState.expiresAt - __mmNow,
        __mmAlpha =
          __mmEnter * Math.min(1, Math.max(0, __mmRemaining / 650)),
        __mmY =
          __mmMainY -
          __mmDistanceFromNewest * 66 +
          (1 - __mmEnter) * 9;
      __mmDrawKittyChatBubble(
        __mmState.text,
        __mmX,
        __mmY,
        __mmAlpha,
        __mmUpper,
      );
    }
  }
}
Cl = function () {
  const __mmVisualMenuOpen = __mmHudMenuOpen || __mmNativeMenuOpen,
    __mmHiddenChats = __mmVisualMenuOpen
    ? null
    : __mmHideNativeChatBubbles();
  let __mmResult;
  try {
    ((__mmGroundGridFrameDrawn = !1),
      (__mmResult = __mmOriginalRender.apply(this, arguments)));
  } finally {
    __mmHiddenChats && __mmRestoreNativeChatBubbles(__mmHiddenChats);
  }
  __mmUpdateMetrics();
  if (!__mmVisualMenuOpen) {
    (__mmDrawPlacementVisuals(),
      __mmPlacementVisualsEnabled && __mmDrawAutoSpikeSpamGhost(),
      __mmDrawEsp(),
      __mmDrawReloadArcs(),
      __mmDrawPlayerCooldownBars(),
      __mmDrawWeaponXpBar(),
      __mmDrawCombatTelemetry(),
      __mmDrawBreakableHitCounts(),
      __mmDrawAntiCollisionPopups(),
      __mmDrawInstaTypePopups(),
      __mmDrawClanPingAlerts(),
      __mmDrawInterruptedChats());
  }
  return __mmResult;
};
function __mmDrawClanPingAlerts() {
  if (!v || __mmTeamKey(v) == null) {
    __mmClanPingAlerts.length = 0;
    return;
  }
  if (
    !__mmNotificationTracersEnabled ||
    !k ||
    !v.alive ||
    !__mmClanPingAlerts.length
  )
    return;
  const __mmNow = performance.now(),
    __mmWidth = Math.max(1, Number(_) || Number(k.canvas && k.canvas.width) || 1),
    __mmHeight = Math.max(1, Number(L) || Number(k.canvas && k.canvas.height) || 1),
    __mmLeft = Number(oe) - __mmWidth / 2,
    __mmTop = Number(ae) - __mmHeight / 2,
    __mmMargin = Math.min(58, Math.max(12, Math.min(__mmWidth, __mmHeight) * 0.12)),
    __mmRawSelfX = Number(v.x) - __mmLeft,
    __mmRawSelfY = Number(v.y) - __mmTop,
    __mmSelfX = Number.isFinite(__mmRawSelfX)
      ? Math.max(__mmMargin, Math.min(__mmWidth - __mmMargin, __mmRawSelfX))
      : __mmWidth / 2,
    __mmSelfY = Number.isFinite(__mmRawSelfY)
      ? Math.max(__mmMargin, Math.min(__mmHeight - __mmMargin, __mmRawSelfY))
      : __mmHeight / 2;
  for (
    let __mmIndex = __mmClanPingAlerts.length - 1;
    __mmIndex >= 0;
    __mmIndex--
  ) {
    const __mmAlert = __mmClanPingAlerts[__mmIndex];
    if (__mmNow >= __mmAlert.expiresAt) {
      __mmClanPingAlerts.splice(__mmIndex, 1);
      continue;
    }
    const __mmAge = __mmNow - __mmAlert.startedAt,
      __mmRemaining = __mmAlert.expiresAt - __mmNow,
      __mmAlpha =
        Math.min(1, __mmAge / 110) * Math.min(1, __mmRemaining / 650),
      __mmPulse = 1 + Math.sin(__mmAge / 145) * 0.1,
      __mmTargetX = __mmAlert.x - __mmLeft,
      __mmTargetY = __mmAlert.y - __mmTop,
      __mmDX = __mmTargetX - __mmSelfX,
      __mmDY = __mmTargetY - __mmSelfY,
      __mmDistance = Math.hypot(__mmDX, __mmDY),
      __mmUnitX = __mmDistance > 0.01 ? __mmDX / __mmDistance : 0,
      __mmUnitY = __mmDistance > 0.01 ? __mmDY / __mmDistance : -1;
    let __mmEdgeDistance = Infinity;
    if (__mmUnitX > 0.001)
      __mmEdgeDistance = Math.min(
        __mmEdgeDistance,
        (__mmWidth - __mmMargin - __mmSelfX) / __mmUnitX,
      );
    else if (__mmUnitX < -0.001)
      __mmEdgeDistance = Math.min(
        __mmEdgeDistance,
        (__mmMargin - __mmSelfX) / __mmUnitX,
      );
    if (__mmUnitY > 0.001)
      __mmEdgeDistance = Math.min(
        __mmEdgeDistance,
        (__mmHeight - __mmMargin - __mmSelfY) / __mmUnitY,
      );
    else if (__mmUnitY < -0.001)
      __mmEdgeDistance = Math.min(
        __mmEdgeDistance,
        (__mmMargin - __mmSelfY) / __mmUnitY,
      );
    if (!Number.isFinite(__mmEdgeDistance) || __mmEdgeDistance <= 0)
      __mmEdgeDistance = Math.min(__mmWidth, __mmHeight) * 0.42;
    // Notification tracers live halfway between the local player and the
    // viewport edge along the actual world-space alert bearing. They no
    // longer collapse to the top-center edge when the sender is far away.
    const __mmMarkerDistance = Math.max(82, __mmEdgeDistance * 0.52),
      __mmRawMarkerX = __mmSelfX + __mmUnitX * __mmMarkerDistance,
      __mmRawMarkerY = __mmSelfY + __mmUnitY * __mmMarkerDistance,
      __mmMarkerX = Math.max(
        __mmMargin,
        Math.min(__mmWidth - __mmMargin, __mmRawMarkerX),
      ),
      __mmMarkerY = Math.max(
        __mmMargin,
        Math.min(__mmHeight - __mmMargin, __mmRawMarkerY),
      ),
      __mmArrowX = __mmMarkerX - __mmUnitX * 35,
      __mmArrowY = __mmMarkerY - __mmUnitY * 35,
      __mmAngle = Math.atan2(__mmUnitY, __mmUnitX);
    (k.save(),
      (k.globalAlpha = __mmAlpha),
      (k.lineJoin = "round"),
      (k.lineCap = "round"),
      (k.shadowColor = "#a855f7"),
      (k.shadowBlur = 16),
      (k.strokeStyle = "rgba(9, 5, 15, 0.96)"),
      (k.fillStyle = "#ffffff"),
      (k.lineWidth = 6),
      k.beginPath(),
      k.arc(__mmMarkerX, __mmMarkerY, 19 * __mmPulse, 0, 2 * Math.PI),
      k.stroke(),
      (k.strokeStyle = "#ffffff"),
      (k.lineWidth = 3),
      k.stroke(),
      k.save(),
      k.translate(__mmArrowX, __mmArrowY),
      k.rotate(__mmAngle),
      k.beginPath(),
      k.moveTo(20 * __mmPulse, 0),
      k.lineTo(-11 * __mmPulse, -11 * __mmPulse),
      k.lineTo(-5 * __mmPulse, 0),
      k.lineTo(-11 * __mmPulse, 11 * __mmPulse),
      k.closePath(),
      (k.strokeStyle = "rgba(9, 5, 15, 0.96)"),
      (k.lineWidth = 6),
      k.stroke(),
      k.fill(),
      k.restore(),
      (k.textAlign = "center"),
      (k.textBaseline = "middle"),
      (k.font = "900 " + Math.round(25 * __mmPulse) + "px Hammersmith One"),
      (k.lineWidth = 5),
      k.strokeText("!", __mmMarkerX, __mmMarkerY + 1),
      k.fillText("!", __mmMarkerX, __mmMarkerY + 1),
      k.restore());
  }
}
function __mmDrawAntiCollisionPopups() {
  if (!k || !__mmAntiCollisionPopups.length) return;
  const __mmNow = performance.now(),
    __mmLeft = Number(oe) - Number(_) / 2,
    __mmTop = Number(ae) - Number(L) / 2;
  for (
    let __mmIndex = __mmAntiCollisionPopups.length - 1;
    __mmIndex >= 0;
    __mmIndex--
  ) {
    const __mmPopup = __mmAntiCollisionPopups[__mmIndex],
      __mmAge = __mmNow - __mmPopup.startedAt;
    if (__mmAge >= 850) {
      __mmAntiCollisionPopups.splice(__mmIndex, 1);
      continue;
    }
    const __mmProgress = Math.max(0, Math.min(1, __mmAge / 850)),
      __mmAlpha = Math.min(1, __mmAge / 90) *
        Math.min(1, (850 - __mmAge) / 260),
      __mmPulse = Math.sin(Math.min(1, __mmAge / 180) * Math.PI),
      __mmX = __mmPopup.x - __mmLeft,
      __mmY =
        __mmPopup.y -
        __mmTop -
        __mmPopup.scale -
        18 -
        __mmProgress * 32;
    if (!ts(__mmX, __mmY, 100)) continue;
    (k.save(),
      (k.globalAlpha = __mmAlpha),
      (k.textAlign = "center"),
      (k.textBaseline = "middle"),
      (k.lineJoin = "round"),
      (k.font =
        Math.round(27 + __mmPulse * 8) + "px Hammersmith One"),
      (k.lineWidth = 7),
      (k.strokeStyle = "rgba(8, 5, 13, 0.94)"),
      (k.fillStyle = "#ffffff"),
      (k.shadowColor = "#a855f7"),
      (k.shadowBlur = 13),
      k.strokeText("Stop!", __mmX, __mmY),
      k.fillText("Stop!", __mmX, __mmY),
      k.restore());
  }
}
function __mmShowInstaTypePopup(__mmText) {
  if (!v || !v.alive) return;
  const __mmLabel = String(__mmText || "Insta").trim().slice(0, 32);
  __mmInstaTypePopups.push({
    text: __mmLabel || "Insta",
    x: Number(v.x) || 0,
    y: Number(v.y) || 0,
    scale: Number(v.scale) || 35,
    startedAt: performance.now(),
  });
  __mmInstaTypePopups.length > 4 && __mmInstaTypePopups.shift();
}
function __mmDrawInstaTypePopups() {
  if (!k || !__mmInstaTypePopups.length) return;
  const __mmNow = performance.now(),
    __mmLeft = Number(oe) - Number(_) / 2,
    __mmTop = Number(ae) - Number(L) / 2;
  for (
    let __mmIndex = __mmInstaTypePopups.length - 1;
    __mmIndex >= 0;
    __mmIndex--
  ) {
    const __mmPopup = __mmInstaTypePopups[__mmIndex],
      __mmAge = __mmNow - __mmPopup.startedAt;
    if (__mmAge >= 1050) {
      __mmInstaTypePopups.splice(__mmIndex, 1);
      continue;
    }
    const __mmProgress = Math.max(0, Math.min(1, __mmAge / 1050)),
      __mmAlpha = Math.min(1, __mmAge / 80) *
        Math.min(1, (1050 - __mmAge) / 300),
      __mmPulse = Math.sin(Math.min(1, __mmAge / 190) * Math.PI),
      __mmX = __mmPopup.x - __mmLeft,
      __mmY =
        __mmPopup.y -
        __mmTop -
        __mmPopup.scale -
        27 -
        __mmProgress * 38;
    if (!ts(__mmX, __mmY, 140)) continue;
    (k.save(),
      (k.globalAlpha = __mmAlpha),
      (k.textAlign = "center"),
      (k.textBaseline = "middle"),
      (k.lineJoin = "round"),
      (k.font = Math.round(24 + __mmPulse * 7) + "px Hammersmith One"),
      (k.lineWidth = 7),
      (k.strokeStyle = "rgba(8, 5, 13, 0.95)"),
      (k.fillStyle = "#f5e9ff"),
      (k.shadowColor = "#a855f7"),
      (k.shadowBlur = 15),
      k.strokeText(__mmPopup.text, __mmX, __mmY),
      k.fillText(__mmPopup.text, __mmX, __mmY),
      k.restore());
  }
}
function __mmUpdateMinimapRegions() {
  const __mmMap = document.getElementById("mapDisplay"),
    __mmMapScale = Number(y && y.mapScale),
    __mmSnowTop = Number(y && y.snowBiomeTop),
    __mmRiverWidth = Number(y && y.riverWidth);
  if (
    !__mmMap ||
    !Number.isFinite(__mmMapScale) ||
    __mmMapScale <= 0 ||
    !Number.isFinite(__mmSnowTop) ||
    !Number.isFinite(__mmRiverWidth)
  )
    return;
  if (__mmMinimapRegionElement !== __mmMap) {
    __mmMinimapRegionElement = __mmMap;
    const __mmComputed = getComputedStyle(__mmMap).backgroundImage;
    __mmMinimapRegionBaseImage =
      __mmComputed && __mmComputed !== "none" ? __mmComputed : "";
  }
  const __mmClampPercent = (__mmValue) =>
      Math.max(0, Math.min(100, __mmValue)),
    __mmSnowPercent = __mmClampPercent((__mmSnowTop / __mmMapScale) * 100),
    __mmRiverStart = __mmClampPercent(
      ((__mmMapScale / 2 - __mmRiverWidth / 2) / __mmMapScale) * 100,
    ),
    __mmRiverEnd = __mmClampPercent(
      ((__mmMapScale / 2 + __mmRiverWidth / 2) / __mmMapScale) * 100,
    ),
    // MooMoo's desert mirrors the snow band at the bottom of the world. The
    // previous overlay painted this entire area green and hid the native
    // biome artwork, so give it a distinct, darker high-contrast sand band.
    __mmDesertStart = Math.max(
      __mmRiverEnd,
      __mmClampPercent(
        ((__mmMapScale - __mmSnowTop) / __mmMapScale) * 100,
      ),
    ),
    __mmGradient =
      "linear-gradient(to bottom," +
      "rgba(212,237,255,.88) 0%,rgba(212,237,255,.88) " +
      __mmSnowPercent + "%," +
      "rgba(99,157,75,.86) " + __mmSnowPercent + "%," +
      "rgba(99,157,75,.86) " + __mmRiverStart + "%," +
      "rgba(67,139,194,.9) " + __mmRiverStart + "%," +
      "rgba(67,139,194,.9) " + __mmRiverEnd + "%," +
      "rgba(99,157,75,.86) " + __mmRiverEnd + "%," +
      "rgba(99,157,75,.86) " + __mmDesertStart + "%," +
      "rgba(132,84,38,.96) " + __mmDesertStart + "%," +
      "rgba(103,61,27,.98) 100%)";
  (__mmMap.style.backgroundImage = __mmMinimapRegionBaseImage
      ? __mmGradient + "," + __mmMinimapRegionBaseImage
      : __mmGradient,
    (__mmMap.style.backgroundColor = "#639d4b"),
    (__mmMap.style.backgroundRepeat = "no-repeat"),
    (__mmMap.style.backgroundSize = "100% 100%"));
}
function __mmStartMinimapRegions() {
  __mmUpdateMinimapRegions();
  __mmMinimapRegionTimer ||
    (__mmMinimapRegionTimer = setInterval(__mmUpdateMinimapRegions, 750));
}
function __mmIsPlaceableItem(__mmItem) {
  const __mmData = b && b.list && b.list[__mmItem];
  return !!(__mmData && __mmData.group && __mmData.group.place);
}
function __mmSelectedPlaceableItem() {
  if (!v || !Array.isArray(v.items)) return null;
  // MooMoo reserves inventory slot 5 for the active special/utility build.
  // Read it directly so automatic trap, spike, cleanup, or break routines can
  // never overwrite what H places.
  const __mmSpecialSlotItem = v.items[5];
  if (__mmIsPlaceableItem(__mmSpecialSlotItem)) return __mmSpecialSlotItem;
  const __mmSpecialNames = new Set([
    "turret",
    "teleporter",
    "boost pad",
    "platform",
    "healing pad",
    "blocker",
    "spawn pad",
  ]);
  for (let __mmIndex = 0; __mmIndex < v.items.length; __mmIndex++) {
    const __mmItem = v.items[__mmIndex],
      __mmData = b && b.list && b.list[__mmItem],
      __mmName = String((__mmData && __mmData.name) || "")
        .trim()
        .toLowerCase();
    if (__mmIsPlaceableItem(__mmItem) && __mmSpecialNames.has(__mmName))
      return __mmItem;
  }
  return null;
}
function __mmCanEquipHat(__mmHat) {
  return __mmHat === 0 || !!(v && v.skins && v.skins[__mmHat]);
}
function __mmShiftHeld() {
  return typeof ne !== "undefined" && !!ne[16];
}
function __mmPlayerMoving() {
  return (
    typeof ne !== "undefined" &&
    !!(
      ne[87] ||
      ne[38] ||
      ne[83] ||
      ne[40] ||
      ne[65] ||
      ne[37] ||
      ne[68] ||
      ne[39]
    )
  );
}
function __mmHasStick() {
  return !!(v && v.weapons && v.weapons.includes(8));
}
function __mmAutoPurchaseQueue() {
  const __mmEntries = __mmAutoPurchaseEntries;
  return __mmHasStick()
    ? [
        __mmEntries.monkeyTail,
        __mmEntries.soldier,
        __mmEntries.booster,
        __mmEntries.bull,
        __mmEntries.emp,
        __mmEntries.turret,
        __mmEntries.tank,
        __mmEntries.shadow,
        __mmEntries.angel,
        __mmEntries.blood,
        __mmEntries.corrupt,
      ]
    : [
        __mmEntries.monkeyTail,
        __mmEntries.soldier,
        __mmEntries.bull,
        __mmEntries.booster,
        __mmEntries.emp,
        __mmEntries.turret,
        __mmEntries.tank,
        __mmEntries.shadow,
        __mmEntries.angel,
        __mmEntries.blood,
        __mmEntries.corrupt,
      ];
}
function __mmOwnsAutoPurchaseEntry(__mmEntry) {
  return !!(
    v &&
    __mmEntry &&
    ( __mmEntry.tail
      ? v.tails && v.tails[__mmEntry.id]
      : v.skins && v.skins[__mmEntry.id])
  );
}
function __mmUpdateAutoPurchase() {
  if (
    !__mmAutoPurchaseEnabled ||
    __mmSyncFollowerEnabled ||
    __mmInsta.isActive() ||
    !v ||
    !v.alive
  )
    return;
  if (__mmTrapAttackActive || __mmBoostBreakHeld) return;
  const __mmNow = Date.now(),
    __mmPending = __mmAutoPurchasePending;
  if (__mmPending) {
    if (__mmOwnsAutoPurchaseEntry(__mmPending))
      __mmAutoPurchasePending = null;
    else if (__mmNow - __mmPending.at < Math.max(350, __mmServerTickMs() * 3))
      return;
    else __mmAutoPurchasePending = null;
  }
  const __mmQueue = __mmAutoPurchaseQueue();
  for (let __mmIndex = 0; __mmIndex < __mmQueue.length; __mmIndex++) {
    const __mmEntry = __mmQueue[__mmIndex];
    if (__mmOwnsAutoPurchaseEntry(__mmEntry)) continue;
    // Preserve the requested order: do not spend on a later item until the
    // next missing purchase is affordable.
    if ((Number(v.points) || 0) < __mmEntry.price) return;
    ((__mmAutoPurchasePending = { ...__mmEntry, at: __mmNow }),
      Xn(__mmEntry.id, __mmEntry.tail));
    return;
  }
}
function __mmStartAutoPurchase() {
  __mmEnsureOperationPipeline();
}
function __mmStopAutoPurchase() {
  (__mmAutoPurchaseTimer && clearInterval(__mmAutoPurchaseTimer),
    (__mmAutoPurchaseTimer = 0),
    (__mmAutoPurchasePending = null));
}
function __mmEnemyWithinCombatRange() {
  if (!v || !v.alive) return !1;
  if (__mmLiveStateFresh())
    return __mmLiveState.nearestEnemyDistance <= __mmCombatRange;
  for (let __mmEnemyIndex = 0; __mmEnemyIndex < E.length; __mmEnemyIndex++) {
    const __mmEnemy = E[__mmEnemyIndex];
    if (!__mmIsEnemyPlayer(__mmEnemy)) continue;
    const __mmDx = __mmEnemy.x - v.x,
      __mmDy = __mmEnemy.y - v.y;
    if (__mmDx * __mmDx + __mmDy * __mmDy <= __mmCombatRange * __mmCombatRange)
      return !0;
  }
  return !1;
}
function __mmCombatSafeHat(__mmHat) {
  return Number(__mmHat) === Number(__mmEmpHelmet) &&
    __mmEnemyWithinCombatRange()
    ? v && v.skins && v.skins[6]
      ? 6
      : 0
    : __mmHat;
}
let __mmLastUpgradePacketAt = 0;
const __mmUpgradeOriginalClicks = new WeakMap(),
  __mmUpgradeOriginalDisplays = new WeakMap();
function __mmUpgradeSelection(__mmSelection) {
  const __mmIndex = Number(__mmSelection),
    __mmWeaponCount = b && Array.isArray(b.weapons) ? b.weapons.length : 0;
  if (!Number.isInteger(__mmIndex) || __mmIndex < 0) return null;
  if (__mmIndex < __mmWeaponCount)
    return {
      entry: b.weapons[__mmIndex],
      prerequisite: __mmOriginalWeaponPrerequisites[__mmIndex],
      owned: v && v.weapons,
    };
  const __mmItemIndex = __mmIndex - __mmWeaponCount;
  return {
    entry: b && b.list && b.list[__mmItemIndex],
    prerequisite: __mmOriginalItemPrerequisites[__mmItemIndex],
    owned: v && v.items,
  };
}
function __mmUpgradeServerSafe(__mmSelection) {
  const __mmChoice = __mmUpgradeSelection(__mmSelection);
  if (
    !v ||
    !v.alive ||
    !__mmChoice ||
    !__mmChoice.entry ||
    !(Number(v.upgradePoints) > 0)
  )
    return !1;
  const __mmRequiredAge = Number(__mmChoice.entry.age),
    __mmCurrentUpgradeAge = Number(v.upgrAge);
  if (
    Number.isFinite(__mmRequiredAge) &&
    Number.isFinite(__mmCurrentUpgradeAge) &&
    __mmRequiredAge !== __mmCurrentUpgradeAge
  )
    return !1;
  // Kitty clears prerequisites in MooMoo's item-data module, so a choice
  // rendered by the native same-age screen is intentionally valid.
  if (__mmAllItemsUnlockEnabled && __mmChoice.entry.pre == null) return !0;
  return (
    __mmChoice.prerequisite == null ||
    (Array.isArray(__mmChoice.owned) &&
      __mmChoice.owned.includes(__mmChoice.prerequisite))
  );
}
function __mmUpgradeBlockedNotice(__mmSelection) {
  const __mmDetail =
    Number(__mmSelection) === __mmMusket
      ? "Musket blocked: Crossbow prerequisite missing"
      : "Upgrade blocked: wrong weapon path";
  window.dispatchEvent(
    new CustomEvent("MooMooScrollZoomStatus", {
      detail: __mmDetail,
    }),
  );
}
function __mmAllowUpgradePacket(__mmSelection) {
  if (!__mmUpgradeServerSafe(__mmSelection))
    return (__mmUpgradeBlockedNotice(__mmSelection), !1);
  const __mmNow = Date.now();
  // Suppress a browser double-click, not the next legitimate choice. Send one
  // normal packet and do not chain Katana and Musket in the same frame.
  if (
    __mmNow - __mmLastUpgradePacketAt <
    Math.max(120, __mmServerTickMs())
  )
    return !1;
  return ((__mmLastUpgradePacketAt = __mmNow), !0);
}
function __mmMarkUnsafeUpgradeChoices() {
  if (!b || !Array.isArray(b.weapons) || !Array.isArray(b.list)) return;
  const __mmTotal = b.weapons.length + b.list.length;
  let __mmAvailableCount = 0;
  for (let __mmIndex = 0; __mmIndex < __mmTotal; __mmIndex++) {
    const __mmSafe = __mmUpgradeServerSafe(__mmIndex),
      __mmElement = document.getElementById("upgradeItem" + __mmIndex);
    if (__mmSafe) {
      // Only count options the game's upgrade renderer actually created.
      // Definitions can be age-valid in data while having no clickable DOM
      // entry, which previously left an empty holder/counter visible.
      if (!__mmElement) continue;
      __mmAvailableCount++;
      if (
        __mmElement.getAttribute("data-kitty-upgrade-blocked") === "1"
      ) {
        (__mmElement.removeAttribute("data-kitty-upgrade-blocked"),
          __mmElement.removeAttribute("aria-disabled"),
          __mmElement.removeAttribute("aria-hidden"),
          __mmElement.style.removeProperty("opacity"),
          __mmElement.style.removeProperty("filter"),
          __mmElement.style.removeProperty("cursor"),
          (__mmElement.style.display =
            __mmUpgradeOriginalDisplays.get(__mmElement) || ""),
          __mmUpgradeOriginalDisplays.delete(__mmElement),
          __mmUpgradeOriginalClicks.has(__mmElement) &&
            ((__mmElement.onclick = __mmUpgradeOriginalClicks.get(__mmElement)),
            __mmUpgradeOriginalClicks.delete(__mmElement)),
          __mmElement.title === "Blocked: server prerequisite not met" &&
            __mmElement.removeAttribute("title"));
      }
      continue;
    }
    if (!__mmElement) continue;
    __mmElement.getAttribute("data-kitty-upgrade-blocked") !== "1" &&
      (__mmUpgradeOriginalClicks.set(__mmElement, __mmElement.onclick),
      __mmUpgradeOriginalDisplays.set(__mmElement, __mmElement.style.display));
    // Vanilla never renders a locked branch as a disabled card. Fully remove
    // stale entries that survived an upgrade-screen refresh.
    ((__mmElement.style.display = "none"),
      __mmElement.setAttribute("data-kitty-upgrade-blocked", "1"),
      __mmElement.setAttribute("aria-disabled", "true"),
      __mmElement.setAttribute("aria-hidden", "true"),
      (__mmElement.onclick = function () {
        __mmUpgradeBlockedNotice(__mmIndex);
      }));
  }
  const __mmHideChooser = __mmAvailableCount === 0,
    __mmHolder = document.getElementById("upgradeHolder"),
    __mmCounter = document.getElementById("upgradeCounter");
  for (const __mmChooser of [__mmHolder, __mmCounter]) {
    if (!__mmChooser) continue;
    __mmHideChooser
      ? __mmChooser.setAttribute("data-kitty-no-upgrades", "1")
      : __mmChooser.removeAttribute("data-kitty-no-upgrades");
  }
}
function __mmApplyUpgradeUnlock() {
  const __mmApply = function (__mmEntries, __mmOriginal) {
    if (!Array.isArray(__mmEntries)) return;
    for (let __mmIndex = 0; __mmIndex < __mmEntries.length; __mmIndex++) {
      const __mmEntry = __mmEntries[__mmIndex],
        __mmPrerequisite = __mmOriginal[__mmIndex];
      if (!__mmEntry || __mmPrerequisite == null) continue;
      __mmEntry.pre = __mmAllItemsUnlockEnabled ? null : __mmPrerequisite;
    }
  };
  // Fallback for game builds where the early module-loader signature changes.
  // This still edits the same item-data objects before the chooser is opened.
  (__mmApply(b && b.weapons, __mmOriginalWeaponPrerequisites),
    __mmApply(b && b.list, __mmOriginalItemPrerequisites));
}
function __mmHudState() {
  return {
    autoHeal: __mmAutoHealEnabled,
    soldierAuto: __mmSoldierAutoEnabled,
    movementGear: __mmMovementGearEnabled,
    trapEscape: __mmTrapEscapeEnabled,
    automaticStateRepair: __mmAutomaticStateRepairEnabled,
    keybinds: Object.assign({}, __mmKeybinds),
    autoAcceptTeamRequests: __mmAutoAcceptTeamRequestsEnabled,
    autoDeclineTeamRequests: __mmAutoDeclineTeamRequestsEnabled,
    antiBoostInsta: __mmAntiBoostInstaEnabled,
    antiInsta: __mmAntiInstaEnabled,
    antiCollision: __mmAntiCollisionEnabled,
    antiCollisionPauseCombat: __mmAntiCollisionPauseCombatEnabled,
    shieldDefense: __mmShieldDefenseEnabled,
    placementDefense: __mmPlacementDefenseEnabled,
    antiRetrapPush: __mmAntiRetrapPushEnabled,
    teammateTrapRescue: __mmTeammateTrapRescueEnabled,
    turretSteal: __mmTurretStealEnabled,
    spikeGearCounter: __mmSpikeGearCounterEnabled,
    dashMovement: __mmDashMovementEnabled,
    musketRecharge: __mmMusketRechargeEnabled,
    autoPurchase: __mmAutoPurchaseEnabled,
    matThief: __mmMatThiefEnabled,
    multiTargetBreak: __mmMultiTargetBreakEnabled,
    mobSteal: __mmMobStealEnabled,
    assassinAutomation: __mmAssassinAutomationEnabled,
    spinningWindmills: __mmSpinningWindmillsEnabled,
    forceFullServers: __mmForceFullServersEnabled,
    bushMode: __mmBushModeRequested,
    fpsBoost: __mmFpsBoostEnabled,
    smoothVisuals: __mmSmoothVisualsEnabled,
    reloadArcs: __mmReloadArcsEnabled,
    entityDanger: __mmEntityDangerEnabled,
    notificationTracers: __mmNotificationTracersEnabled,
    groundGrid: __mmGroundGridEnabled,
    esp: __mmEspEnabled,
    espLines: __mmEspLinesEnabled,
    predictionGhost: __mmPredictionGhostEnabled,
    placementVisuals: __mmPlacementVisualsEnabled,
    cooldownBars: __mmCooldownBarsEnabled,
    weaponXpBar: __mmWeaponXpBarEnabled,
    chatHistory: __mmChatHistoryEnabled,
    combatTelemetry: __mmCombatTelemetryEnabled,
    telemetryProjectileHits: __mmTelemetryProjectileHitsEnabled,
    telemetrySpikeKnockback: __mmTelemetrySpikeKnockbackEnabled,
    telemetryActualAim: __mmTelemetryActualAimEnabled,
    telemetryBuildingOwners: __mmTelemetryBuildingOwnersEnabled,
    telemetryShameCount: __mmTelemetryShameCountEnabled,
    telemetryDamageHealing: __mmTelemetryDamageHealingEnabled,
    enemyColor: __mmEnemyColor,
    allyColor: __mmAllyColor,
    friendColor: __mmFriendColor,
    ownColor: __mmOwnColor,
    bullHelmet: __mmBullHelmetEnabled,
    tankRightClick: __mmTankRightClickEnabled,
    instaKill: __mmInstaUiEnabled,
    autoInsta: __mmAutoInstaEnabled,
    autoBowUpgradeInsta: __mmAutoBowUpgradeInstaEnabled,
    reverseInsta: __mmReverseInstaEnabled,
    oneTickInsta: __mmOneTickInstaEnabled,
    appleInsta: __mmAppleInstaEnabled,
    bleedInsta: __mmBleedInstaEnabled,
    knockbackInsta: __mmKnockbackInstaEnabled,
    velTickInsta: __mmVelTickInstaEnabled,
    polearmAids: __mmPolearmAidsEnabled,
    autoPushInsta: __mmAutoPushInstaEnabled,
    boostSpikeKill: __mmBoostSpikeEnabled,
    autoTrapInsta: __mmAutoTrapInstaEnabled,
    autoSpikeInsta: __mmAutoSpikeInstaEnabled,
    autoSpikeSpam: __mmAutoSpikeSpamEnabled,
    autoSpikeKill: __mmAutoSpikeKillEnabled,
    animalTrap: __mmThreatTrapEnabled,
    passiveMobTrap: __mmPassiveMobTrapEnabled,
    bossTeleporter: __mmBossTeleporterEnabled,
    smartAutoPlace: __mmSmartAutoPlaceEnabled,
    smartPreplace: __mmSmartPreplaceEnabled,
    smartMultiPlace: __mmSmartMultiPlaceEnabled,
    smartQuadTraps: __mmSmartQuadTrapsEnabled,
    smartQuadSpikes: __mmSmartQuadSpikesEnabled,
    smartSpikeContact: __mmSmartSpikeContactEnabled,
    smartTrapContact: __mmSmartTrapContactEnabled,
    smartKnockbackChain: __mmSmartKnockbackChainEnabled,
    smartTrapSurround: __mmSmartTrapSurroundEnabled,
    smartAngleDenial: __mmSmartAngleDenialEnabled,
    smartAutoPushWeight: __mmSmartAutoPushWeightEnabled,
    smartAutoReplace: __mmSmartAutoReplaceEnabled,
    smartSpikeSyncPlace: __mmSmartSpikeSyncPlaceEnabled,
    smartAntiBoostPlace: __mmSmartAntiBoostPlaceEnabled,
    smartMovingMills: __mmSmartMovingMillsEnabled,
    smartInstaUtilityPlace: __mmSmartInstaUtilityPlaceEnabled,
    instaSync: __mmInstaSyncEnabled,
    boostBreak: __mmBoostBreakEnabled,
    boostChat: __mmBoostChatEnabled,
    materialReply: __mmMaterialReplyEnabled,
    meowChainInsta: __mmMeowChainInstaEnabled,
    instaChat: __mmInstaChatEnabled,
    bushChat: __mmBushChatEnabled,
    friendAddedChat: __mmFriendAddedChatEnabled,
    enemyMarkedChat: __mmEnemyMarkedChatEnabled,
    cleanupProgressChat: __mmCleanupProgressChatEnabled,
    cleanupCompleteChat: __mmCleanupCompleteChatEnabled,
    modReplyChat: __mmModReplyChatEnabled,
    enemyTrapChat: __mmEnemyTrapChatEnabled,
    friendTrapChat: __mmFriendTrapChatEnabled,
    trapAlertChat: __mmTrapAlertChatEnabled,
    deathHistoryChat: __mmDeathHistoryChatEnabled,
    syncStatusChat: __mmSyncStatusChatEnabled,
    syncMovement: __mmSyncMovementEnabled,
    syncCopyWeapons: __mmSyncCopyWeaponsEnabled,
    syncCopyBuilds: __mmSyncCopyBuildsEnabled,
    syncCopyGear: __mmSyncCopyGearEnabled,
    syncCopyAim: __mmSyncCopyAimEnabled,
    syncCopyAttacks: __mmSyncCopyAttacksEnabled,
    syncCatchupGear: __mmSyncCatchupGearEnabled,
    syncPauseInCombat: __mmSyncPauseInCombatEnabled,
    syncWasdCombatOnly: __mmSyncWasdCombatOnlyEnabled,
    syncTickCombat: __mmSyncTickCombatEnabled,
    syncFollowGap: __mmSyncFollowGap,
    syncStopTolerance: __mmSyncStopTolerance,
    syncResumeTolerance: __mmSyncResumeTolerance,
    syncPredictionMs: __mmSyncPredictionMs,
    syncCatchupDistance: __mmSyncCatchupDistance,
    syncCatchupReleaseDistance: __mmSyncCatchupReleaseDistance,
    syncMoveRefreshMs: __mmSyncMoveRefreshMs,
    syncRelayUrl: __mmSyncRelayUrl,
    syncRoom: __mmSyncRoom,
    syncStatus: __mmSyncStatus,
    syncTargetName: __mmSyncTargetName,
    soldierRange: __mmSoldierRange,
    combatRange: __mmCombatRange,
    gearHoldTicks: __mmGearHoldTicks,
    antiBoostRange: __mmAntiBoostRange,
    antiCollisionRange: __mmAntiCollisionRange,
    reactionMs: __mmReactionMs,
    adaptiveSmartness: __mmAdaptiveSmartnessEnabled,
    smartDepth: __mmSmartDepth,
    smartPlaceAccuracy: __mmSmartPlaceAccuracy,
    smartMaxPlacements: __mmSmartMaxPlacements,
    smartPlaceDelay: __mmSmartPlaceDelay,
    assassinSafeMs: __mmAssassinSafeMs,
    assassinMinHealth: __mmAssassinMinHealth,
    assassinDangerRange: __mmAssassinDangerRange,
    debugPanel: __mmDebugPanelEnabled,
    debugText: __mmRuntimeDebugText(),
    killMessageEnabled: __mmKillMessageEnabled,
    killMessage: __mmKillMessage,
    friendNames: Array.from(__mmFriendNames.values()),
  };
}
function __mmPublishHudState() {
  window.dispatchEvent(
    new CustomEvent("MooMooOPHudState", { detail: __mmHudState() }),
  );
}
function __mmSetAutoHeal(__mmEnabled) {
  ((__mmAutoHealEnabled = !!__mmEnabled),
    !__mmAutoHealEnabled &&
      __mmAutoHealWasHealing &&
      ((__mmAutoHealWasHealing = !1), __mmRestoreAutoHealWeapon()),
    window.dispatchEvent(
      new CustomEvent("MooMooScrollZoomAutoheal", {
        detail: __mmAutoHealEnabled,
      }),
    ),
    __mmPublishHudState());
}
function __mmSetSoldierAuto(__mmEnabled) {
  __mmSoldierAutoEnabled = !!__mmEnabled;
  if (
    !__mmSoldierAutoEnabled &&
    v &&
    v.alive &&
    __mmSoldierPreviousHat != null
  ) {
    const __mmHat = __mmSoldierPreviousHat;
    ((__mmSoldierPreviousHat = null),
      v.skinIndex === 6 && __mmCanEquipHat(__mmHat) && __mmEquipHatNow(__mmHat));
  }
  __mmPublishHudState();
}
function __mmSetMovementGear(__mmEnabled) {
  ((__mmMovementGearEnabled = !!__mmEnabled),
    !__mmMovementGearEnabled &&
      (__mmRestoreMovementGear(), __mmRestoreProximityTail()),
    __mmPublishHudState());
}
function __mmSetHudNumber(__mmKey, __mmValue) {
  const __mmNumber = Number(__mmValue);
  if (!Number.isFinite(__mmNumber)) return;
  if (__mmKey === "soldierRange")
    __mmSoldierRange = Math.max(100, Math.min(1000, __mmNumber));
  else if (__mmKey === "combatRange")
    __mmCombatRange = Math.max(100, Math.min(1000, __mmNumber));
  else if (__mmKey === "gearHoldTicks")
    __mmGearHoldTicks = Math.max(1, Math.min(8, Math.round(__mmNumber)));
  else if (__mmKey === "antiBoostRange")
    __mmAntiBoostRange = Math.max(80, Math.min(500, __mmNumber));
  else if (__mmKey === "antiCollisionRange")
    __mmAntiCollisionRange = Math.max(120, Math.min(500, __mmNumber));
  else if (__mmKey === "reactionMs") {
    __mmReactionMs = Math.max(10, Math.min(100, __mmNumber));
    __mmLiveStateTimer &&
      (clearInterval(__mmLiveStateTimer),
      (__mmLiveStateTimer = 0),
      __mmStartLiveState());
    __mmAntiCollisionTimer &&
      (clearInterval(__mmAntiCollisionTimer),
      (__mmAntiCollisionTimer = 0),
      __mmStartAntiCollision());
  } else if (__mmKey === "smartDepth") {
    const __mmPreviousCeiling = __mmSmartDepthCeiling(),
      __mmNextCeiling = Math.max(1, Math.min(10, Math.round(__mmNumber)));
    __mmSmartDepth = __mmNextCeiling;
    if (
      !__mmAdaptiveSmartnessEnabled ||
      __mmAdaptiveSmartDepth >= __mmPreviousCeiling ||
      __mmAdaptiveSmartDepth > __mmNextCeiling
    )
      __mmAdaptiveSmartDepth = __mmNextCeiling;
    __mmPublishAdaptiveSmartness();
  }
  else if (__mmKey === "smartPlaceAccuracy")
    __mmSmartPlaceAccuracy = Math.max(20, Math.min(180, Math.round(__mmNumber)));
  else if (__mmKey === "smartMaxPlacements")
    __mmSmartMaxPlacements = Math.max(1, Math.min(4, Math.round(__mmNumber)));
  else if (__mmKey === "smartPlaceDelay")
    __mmSmartPlaceDelay = Math.max(0, Math.min(222, Math.round(__mmNumber)));
  else if (__mmKey === "assassinSafeMs")
    __mmAssassinSafeMs = Math.max(500, Math.min(5000, Math.round(__mmNumber)));
  else if (__mmKey === "assassinMinHealth")
    __mmAssassinMinHealth = Math.max(20, Math.min(100, Math.round(__mmNumber)));
  else if (__mmKey === "assassinDangerRange")
    __mmAssassinDangerRange = Math.max(250, Math.min(1200, Math.round(__mmNumber)));
  else if (__mmKey === "syncFollowGap")
    __mmSyncFollowGap = Math.max(2, Math.min(120, Math.round(__mmNumber)));
  else if (__mmKey === "syncStopTolerance")
    __mmSyncStopTolerance = Math.max(
      1,
      Math.min(30, Math.round(__mmNumber)),
    );
  else if (__mmKey === "syncResumeTolerance")
    __mmSyncResumeTolerance = Math.max(
      2,
      Math.min(60, Math.round(__mmNumber)),
    );
  else if (__mmKey === "syncPredictionMs")
    __mmSyncPredictionMs = Math.max(
      0,
      Math.min(300, Math.round(__mmNumber)),
    );
  else if (__mmKey === "syncCatchupDistance")
    __mmSyncCatchupDistance = Math.max(
      100,
      Math.min(1200, Math.round(__mmNumber)),
    );
  else if (__mmKey === "syncCatchupReleaseDistance")
    __mmSyncCatchupReleaseDistance = Math.max(
      50,
      Math.min(800, Math.round(__mmNumber)),
    );
  else if (__mmKey === "syncMoveRefreshMs")
    __mmSyncMoveRefreshMs = Math.max(
      16,
      Math.min(250, Math.round(__mmNumber)),
    );
  else return;
  __mmPublishHudState();
}
function __mmSetHudToggle(__mmKey, __mmValue) {
  const __mmEnabled = !!__mmValue;
  if (__mmKey === "autoHeal") return void __mmSetAutoHeal(__mmEnabled);
  if (__mmKey === "soldierAuto") return void __mmSetSoldierAuto(__mmEnabled);
  if (__mmKey === "movementGear") return void __mmSetMovementGear(__mmEnabled);
  if (__mmKey === "trapEscape")
    ((__mmTrapEscapeEnabled = __mmEnabled),
      __mmEnabled ? __mmStartTrapEscape() : __mmStopTrapEscape());
  else if (__mmKey === "automaticStateRepair")
    ((__mmAutomaticStateRepairEnabled = __mmEnabled),
      __mmEnabled && __mmUpdateAutomaticStateRepair());
  else if (__mmKey === "autoAcceptTeamRequests")
    ((__mmAutoAcceptTeamRequestsEnabled = __mmEnabled),
      __mmEnabled && (__mmAutoDeclineTeamRequestsEnabled = !1),
      __mmHandleTeamJoinRequest());
  else if (__mmKey === "autoDeclineTeamRequests")
    ((__mmAutoDeclineTeamRequestsEnabled = __mmEnabled),
      __mmEnabled && (__mmAutoAcceptTeamRequestsEnabled = !1),
      __mmHandleTeamJoinRequest());
  else if (__mmKey === "antiBoostInsta")
    __mmAntiBoostInstaEnabled = __mmEnabled;
  else if (__mmKey === "antiInsta")
    __mmAntiInstaEnabled = __mmEnabled;
  else if (__mmKey === "antiCollision")
    ((__mmAntiCollisionEnabled = __mmEnabled),
      __mmEnabled
        ? (__mmStartAntiCollision(), __mmUpdateAntiCollision())
        : __mmStopAntiCollision());
  else if (__mmKey === "antiCollisionPauseCombat")
    ((__mmAntiCollisionPauseCombatEnabled = __mmEnabled),
      __mmUpdateAntiCollision());
  else if (__mmKey === "shieldDefense")
    ((__mmShieldDefenseEnabled = __mmEnabled),
      !__mmEnabled && __mmStopShieldDefense("hud disabled"));
  else if (__mmKey === "placementDefense")
    __mmPlacementDefenseEnabled = __mmEnabled;
  else if (__mmKey === "antiRetrapPush")
    __mmAntiRetrapPushEnabled = __mmEnabled;
  else if (__mmKey === "teammateTrapRescue")
    __mmTeammateTrapRescueEnabled = __mmEnabled;
  else if (__mmKey === "turretSteal")
    __mmTurretStealEnabled = __mmEnabled;
  else if (__mmKey === "spikeGearCounter")
    ((__mmSpikeGearCounterEnabled = __mmEnabled),
      !__mmEnabled && __mmResetSpikeGearCounter(!0));
  else if (__mmKey === "dashMovement")
    __mmDashMovementEnabled = __mmEnabled;
  else if (__mmKey === "musketRecharge")
    ((__mmMusketRechargeEnabled = __mmEnabled),
      !__mmEnabled && __mmStopWeaponRecharge(!1));
  else if (__mmKey === "autoPurchase")
    ((__mmAutoPurchaseEnabled = __mmEnabled),
      __mmEnabled ? (__mmStartAutoPurchase(), __mmUpdateAutoPurchase()) : __mmStopAutoPurchase());
  else if (__mmKey === "matThief")
    ((__mmMatThiefEnabled = __mmEnabled),
      __mmEnabled ? (__mmStartMatThief(), __mmUpdateMatThief()) : __mmStopMatThief());
  else if (__mmKey === "multiTargetBreak")
    ((__mmMultiTargetBreakEnabled = __mmEnabled),
      __mmEnabled ? (__mmStartMultiBreak(), __mmUpdateMultiBreakAim()) : __mmStopMultiBreak());
  else if (__mmKey === "mobSteal")
    ((__mmMobStealEnabled = __mmEnabled),
      __mmEnabled ? (__mmStartMobSteal(), __mmUpdateMobSteal()) : __mmStopMobSteal());
  else if (__mmKey === "assassinAutomation")
    ((__mmAssassinAutomationEnabled = __mmEnabled),
      __mmEnabled
        ? (__mmStartAssassinAutomation(), __mmUpdateAssassinAutomation())
        : __mmStopAssassinAutomation());
  else if (__mmKey === "spinningWindmills")
    ((__mmSpinningWindmillsEnabled = __mmEnabled),
      document.documentElement &&
        document.documentElement.setAttribute(
          "data-kitty-spinning-windmills",
          __mmEnabled ? "1" : "0",
        ),
      __mmApplyWindmillRotationState());
  else if (__mmKey === "forceFullServers")
    ((__mmForceFullServersEnabled = __mmEnabled),
      (window.__KittyForceFullServers = __mmEnabled),
      (() => {
        try {
          __mmEnabled
            ? localStorage.setItem("moofoll", "1")
            : localStorage.removeItem("moofoll");
        } catch {}
      })());
  else if (__mmKey === "bushMode")
    return void __mmSetBushMode(__mmEnabled);
  else if (__mmKey === "fpsBoost") {
    __mmFpsBoostEnabled = __mmEnabled;
    document.documentElement &&
      document.documentElement.setAttribute(
        "data-kitty-fps-boost",
        __mmEnabled ? "1" : "0",
      );
    __mmObjectSnapshotAt = 0;
  }
  else if (__mmKey === "smoothVisuals")
    __mmSmoothVisualsEnabled = __mmEnabled;
  else if (__mmKey === "reloadArcs")
    __mmReloadArcsEnabled = __mmEnabled;
  else if (__mmKey === "entityDanger")
    __mmEntityDangerEnabled = __mmEnabled;
  else if (__mmKey === "notificationTracers")
    __mmNotificationTracersEnabled = __mmEnabled;
  else if (__mmKey === "groundGrid") {
    __mmGroundGridEnabled = __mmEnabled;
    __mmGroundGridFrameDrawn = !1;
    document.documentElement &&
      document.documentElement.setAttribute(
        "data-kitty-ground-grid",
        __mmEnabled ? "1" : "0",
      );
  }
  else if (__mmKey === "esp") __mmEspEnabled = __mmEnabled;
  else if (__mmKey === "espLines") __mmEspLinesEnabled = __mmEnabled;
  else if (__mmKey === "predictionGhost")
    __mmPredictionGhostEnabled = __mmEnabled;
  else if (__mmKey === "placementVisuals") {
    __mmPlacementVisualsEnabled = __mmEnabled;
    if (!__mmEnabled) {
      (__mmSmartPreviewSamples.length = 0,
        (__mmSmartPlacementPreview = {
          samples: [],
          ranked: [],
          selected: [],
          reason: "disabled",
          updatedAt: 0,
        }));
    }
  }
  else if (__mmKey === "cooldownBars")
    __mmCooldownBarsEnabled = __mmEnabled;
  else if (__mmKey === "weaponXpBar")
    __mmWeaponXpBarEnabled = __mmEnabled;
  else if (__mmKey === "combatTelemetry")
    ((__mmCombatTelemetryEnabled = __mmEnabled),
      !__mmEnabled &&
        (() => {
          for (const __mmSid in __mmCombatDeltaStacks)
            delete __mmCombatDeltaStacks[__mmSid];
        })());
  else if (__mmKey === "telemetryProjectileHits")
    __mmTelemetryProjectileHitsEnabled = __mmEnabled;
  else if (__mmKey === "telemetrySpikeKnockback")
    __mmTelemetrySpikeKnockbackEnabled = __mmEnabled;
  else if (__mmKey === "telemetryActualAim")
    __mmTelemetryActualAimEnabled = __mmEnabled;
  else if (__mmKey === "telemetryBuildingOwners")
    __mmTelemetryBuildingOwnersEnabled = __mmEnabled;
  else if (__mmKey === "telemetryShameCount")
    __mmTelemetryShameCountEnabled = __mmEnabled;
  else if (__mmKey === "telemetryDamageHealing") {
    __mmTelemetryDamageHealingEnabled = __mmEnabled;
    if (!__mmEnabled)
      for (const __mmSid in __mmCombatDeltaStacks)
        delete __mmCombatDeltaStacks[__mmSid];
  }
  else if (__mmKey === "chatHistory") {
    __mmChatHistoryEnabled = __mmEnabled;
    if (!__mmEnabled) {
      for (const __mmSid in __mmChatBubbleStacks)
        delete __mmChatBubbleStacks[__mmSid];
    }
  }
  else if (__mmKey === "bullHelmet") {
    __mmBullHelmetEnabled = __mmEnabled;
    if (
      !__mmEnabled &&
      v &&
      (__mmPrimaryClickHat != null || __mmPrimaryClickTail != null)
    )
      __mmForceRestoreBullForPrimary();
  } else if (__mmKey === "tankRightClick")
    ((__mmTankRightClickEnabled = __mmEnabled),
      !__mmEnabled &&
        (__mmStopSecondary(), __mmForceRestoreRightClickHat()));
  else if (__mmKey === "instaKill") {
    ((__mmInstaUiEnabled = __mmEnabled),
      !__mmEnabled && __mmInsta.cancel("hud-disabled"));
  }
  else if (__mmKey === "autoInsta") {
    ((__mmAutoInstaEnabled = __mmEnabled),
      !__mmEnabled &&
        __mmInsta.automatic &&
        __mmInsta.cancel("auto-insta-disabled"));
  }
  else if (__mmKey === "autoBowUpgradeInsta") {
    __mmAutoBowUpgradeInstaEnabled = __mmEnabled;
    !__mmEnabled && __mmBowUpgradeInsta.cancel("hud disabled");
  }
  else if (__mmKey === "reverseInsta")
    __mmReverseInstaEnabled = __mmEnabled;
  else if (__mmKey === "oneTickInsta")
    __mmOneTickInstaEnabled = __mmEnabled;
  else if (__mmKey === "appleInsta")
    ((__mmAppleInstaEnabled = __mmEnabled), __mmRefreshKittyInstaLoop());
  else if (__mmKey === "bleedInsta")
    ((__mmBleedInstaEnabled = __mmEnabled), __mmRefreshKittyInstaLoop());
  else if (__mmKey === "knockbackInsta")
    ((__mmKnockbackInstaEnabled = __mmEnabled), __mmRefreshKittyInstaLoop());
  else if (__mmKey === "velTickInsta") {
    __mmVelTickInstaEnabled = __mmEnabled;
    (!__mmEnabled && __mmStopVelTickInsta("hud disabled"),
      __mmRefreshKittyInstaLoop());
  }
  else if (__mmKey === "polearmAids")
    ((__mmPolearmAidsEnabled = __mmEnabled), __mmRefreshKittyInstaLoop());
  else if (__mmKey === "autoPushInsta") {
    __mmAutoPushInstaEnabled = __mmEnabled;
    (!__mmEnabled && __mmStopAutoPushSetup("hud disabled"),
      __mmRefreshKittyInstaLoop());
  }
  else if (__mmKey === "boostSpikeKill") {
    __mmBoostSpikeEnabled = __mmEnabled;
    !__mmEnabled && __mmStopBoostSpike();
  }
  else if (__mmKey === "autoTrapInsta") {
    __mmAutoTrapInstaEnabled = __mmEnabled;
    if (__mmEnabled) (__mmStartAutoTrapInsta(), __mmUpdateAutoTrapInsta());
    else {
      (__mmAutoTrapInstaTimer && clearInterval(__mmAutoTrapInstaTimer),
        (__mmAutoTrapInstaTimer = 0));
      for (const __mmSid in __mmAutoTrapInstaIncidents)
        delete __mmAutoTrapInstaIncidents[__mmSid];
    }
  }
  else if (__mmKey === "autoSpikeInsta")
    ((__mmAutoSpikeInstaEnabled = __mmEnabled),
      __mmEnabled
        ? (__mmStartAutoSpikeInsta(), __mmUpdateAutoSpikeInsta())
        : ((__mmAutoSpikeInstaTimer && clearInterval(__mmAutoSpikeInstaTimer),
          (__mmAutoSpikeInstaTimer = 0),
          __mmStopSpikeTickStrike("hud disabled"))));
  else if (__mmKey === "autoSpikeSpam" || __mmKey === "autoSpikeKill") {
    __mmKey === "autoSpikeSpam"
      ? (__mmAutoSpikeSpamEnabled = __mmEnabled)
      : (__mmAutoSpikeKillEnabled = __mmEnabled);
    if (__mmAutoSpikeSpamEnabled || __mmAutoSpikeKillEnabled)
      (__mmStartAutoSpikeSpam(), __mmUpdateAutoSpikeSpam());
    else {
      (__mmAutoSpikeSpamTimer && clearInterval(__mmAutoSpikeSpamTimer),
        (__mmAutoSpikeSpamTimer = 0),
        __mmResetAutoSpikeSpamIntent(),
        __mmAutoSpikeSpamResetCandidate(!0));
    }
  }
  else if (__mmKey === "animalTrap") {
    __mmThreatTrapEnabled = __mmEnabled;
    if (__mmEnabled) (__mmStartThreatTrap(), __mmPlaceThreatTrap());
    else {
      __mmThreatTrapLastKey = null;
      for (const __mmKey in __mmThreatTrapPlacements)
        delete __mmThreatTrapPlacements[__mmKey];
      !__mmPassiveMobTrapEnabled &&
        !__mmBossTeleporterEnabled &&
        __mmStopThreatTrapLoop();
    }
  }
  else if (__mmKey === "passiveMobTrap") {
    __mmPassiveMobTrapEnabled = __mmEnabled;
    if (__mmEnabled) (__mmStartThreatTrap(), __mmPlaceThreatTrap());
    else {
      __mmThreatTrapLastKey = null;
      for (const __mmKey in __mmThreatTrapPlacements)
        delete __mmThreatTrapPlacements[__mmKey];
      !__mmThreatTrapEnabled &&
        !__mmBossTeleporterEnabled &&
        __mmStopThreatTrapLoop();
    }
  }
  else if (__mmKey === "bossTeleporter") {
    __mmBossTeleporterEnabled = __mmEnabled;
    if (__mmEnabled) (__mmStartThreatTrap(), __mmPlaceThreatTrap());
    else if (!__mmThreatTrapEnabled && !__mmPassiveMobTrapEnabled)
      __mmStopThreatTrapLoop();
  }
  else if (__mmKey === "smartAutoPlace") {
    __mmSmartAutoPlaceEnabled = __mmEnabled;
    if (
      !__mmEnabled &&
      !__mmAutomaticQuadPlacementEnabled() &&
      __mmSmartPreplaceTimers.size
    ) {
      for (const __mmTimer of __mmSmartPreplaceTimers) clearTimeout(__mmTimer);
      (__mmSmartPreplaceTimers.clear(), __mmSmartPreplaceKeys.clear());
    }
    __mmRefreshSmartPlacementLoop();
  }
  else if (__mmKey === "smartPreplace") __mmSmartPreplaceEnabled = __mmEnabled;
  else if (__mmKey === "smartMultiPlace")
    ((__mmSmartMultiPlaceEnabled = __mmEnabled), __mmRefreshSmartPlacementLoop());
  else if (__mmKey === "smartQuadTraps")
    ((__mmSmartQuadTrapsEnabled = __mmEnabled), __mmRefreshSmartPlacementLoop());
  else if (__mmKey === "smartQuadSpikes")
    ((__mmSmartQuadSpikesEnabled = __mmEnabled), __mmRefreshSmartPlacementLoop());
  else if (__mmKey === "smartSpikeContact") __mmSmartSpikeContactEnabled = __mmEnabled;
  else if (__mmKey === "smartTrapContact") __mmSmartTrapContactEnabled = __mmEnabled;
  else if (__mmKey === "smartKnockbackChain") __mmSmartKnockbackChainEnabled = __mmEnabled;
  else if (__mmKey === "smartTrapSurround") __mmSmartTrapSurroundEnabled = __mmEnabled;
  else if (__mmKey === "smartAngleDenial") __mmSmartAngleDenialEnabled = __mmEnabled;
  else if (__mmKey === "smartAutoPushWeight") __mmSmartAutoPushWeightEnabled = __mmEnabled;
  else if (__mmKey === "smartAutoReplace")
    ((__mmSmartAutoReplaceEnabled = __mmEnabled), __mmRefreshSmartPlacementLoop());
  else if (__mmKey === "smartSpikeSyncPlace")
    ((__mmSmartSpikeSyncPlaceEnabled = __mmEnabled), __mmRefreshSmartPlacementLoop());
  else if (__mmKey === "smartAntiBoostPlace")
    ((__mmSmartAntiBoostPlaceEnabled = __mmEnabled), __mmRefreshSmartPlacementLoop());
  else if (__mmKey === "smartMovingMills") {
    __mmSmartMovingMillsEnabled = __mmEnabled;
    if (!__mmEnabled) ((__mmSmartMillX = null), (__mmSmartMillY = null));
    __mmRefreshSmartPlacementLoop();
  }
  else if (__mmKey === "smartInstaUtilityPlace") __mmSmartInstaUtilityPlaceEnabled = __mmEnabled;
  else if (__mmKey === "adaptiveSmartness") {
    if (__mmAdaptiveSmartnessEnabled !== __mmEnabled) {
      __mmAdaptiveSmartnessEnabled = __mmEnabled;
      __mmResetAdaptiveSmartness(__mmEnabled ? "sampling" : "manual ceiling");
    } else __mmPublishAdaptiveSmartness();
  }
  else if (__mmKey === "instaSync") {
    __mmInstaSyncEnabled = __mmEnabled;
    __mmEnabled
      ? __mmStartInstaSync()
      : ((__mmInstaSyncLoopTimer && clearInterval(__mmInstaSyncLoopTimer),
        (__mmInstaSyncLoopTimer = 0),
        __mmStopInstaSync()));
  }
  else if (__mmKey === "boostBreak") {
    ((__mmBoostBreakEnabled = __mmEnabled),
      !__mmEnabled && __mmStopBoostBreak());
  } else if (__mmKey === "boostChat") {
    ((__mmBoostChatEnabled = __mmEnabled), !__mmEnabled && __mmStopBoostChat());
  } else if (__mmKey === "materialReply") {
    __mmMaterialReplyEnabled = __mmEnabled;
  } else if (__mmKey === "meowChainInsta") {
    __mmMeowChainInstaEnabled = __mmEnabled;
  } else if (__mmKey === "instaChat") {
    __mmInstaChatEnabled = __mmEnabled;
  } else if (__mmKey === "bushChat") {
    __mmBushChatEnabled = __mmEnabled;
  } else if (__mmKey === "friendAddedChat") {
    __mmFriendAddedChatEnabled = __mmEnabled;
  } else if (__mmKey === "enemyMarkedChat") {
    __mmEnemyMarkedChatEnabled = __mmEnabled;
  } else if (__mmKey === "cleanupProgressChat") {
    __mmCleanupProgressChatEnabled = __mmEnabled;
  } else if (__mmKey === "cleanupCompleteChat") {
    __mmCleanupCompleteChatEnabled = __mmEnabled;
  } else if (__mmKey === "modReplyChat") {
    __mmModReplyChatEnabled = __mmEnabled;
  } else if (__mmKey === "enemyTrapChat") {
    __mmEnemyTrapChatEnabled = __mmEnabled;
  } else if (__mmKey === "friendTrapChat") {
    __mmFriendTrapChatEnabled = __mmEnabled;
  } else if (__mmKey === "trapAlertChat") {
    __mmTrapAlertChatEnabled = __mmEnabled;
  } else if (__mmKey === "deathHistoryChat") {
    __mmDeathHistoryChatEnabled = __mmEnabled;
  } else if (__mmKey === "syncStatusChat") {
    __mmSyncStatusChatEnabled = __mmEnabled;
    if (!__mmEnabled) {
      (__mmSyncStatusChatTimer && clearTimeout(__mmSyncStatusChatTimer),
        (__mmSyncStatusChatTimer = 0),
        (__mmSyncStatusChatQueue.length = 0));
    } else {
      __mmSyncStatusChatPhase = /^(?:Syncing|Reconnecting)/i.test(
        __mmSyncStatus,
      )
        ? "syncing"
        : /^Synced\b/i.test(__mmSyncStatus)
          ? "synced"
          : "off";
    }
  } else if (__mmKey === "syncMovement") {
    __mmSyncMovementEnabled = __mmEnabled;
    __mmEnabled
      ? __mmStartSyncFollowFrames()
      : (__mmSyncRestoreCatchupGear(), __mmSyncStopFollowMovement());
  } else if (__mmKey === "syncCopyWeapons") {
    __mmSyncCopyWeaponsEnabled = __mmEnabled;
  } else if (__mmKey === "syncCopyBuilds") {
    __mmSyncCopyBuildsEnabled = __mmEnabled;
  } else if (__mmKey === "syncCopyGear") {
    __mmSyncCopyGearEnabled = __mmEnabled;
  } else if (__mmKey === "syncCopyAim") {
    __mmSyncCopyAimEnabled = __mmEnabled;
  } else if (__mmKey === "syncCopyAttacks") {
    __mmSyncCopyAttacksEnabled = __mmEnabled;
    if (!__mmEnabled) {
      (__mmStopObservedSyncAttack(!0),
        __mmSyncDirectAttackActive &&
          v &&
          v.alive &&
          __mmWithSyncReplay(function () {
            O.send("F", 0, Ci());
          }),
        (__mmSyncDirectAttackActive = !1));
    }
  } else if (__mmKey === "syncCatchupGear") {
    __mmSyncCatchupGearEnabled = __mmEnabled;
    !__mmEnabled && __mmSyncRestoreCatchupGear();
  } else if (__mmKey === "syncPauseInCombat") {
    __mmSyncPauseInCombatEnabled = __mmEnabled;
  } else if (__mmKey === "syncWasdCombatOnly") {
    __mmSyncWasdCombatOnlyEnabled = __mmEnabled;
  } else if (__mmKey === "syncTickCombat") {
    __mmSyncTickCombatEnabled = __mmEnabled;
    !__mmEnabled && __mmCancelScheduledSyncInsta();
  } else if (__mmKey === "debugPanel")
    __mmDebugPanelEnabled = __mmEnabled;
  else if (__mmKey === "killMessageEnabled")
    __mmKillMessageEnabled = __mmEnabled;
  else return;
  __mmPublishHudState();
}
function __mmSetHudValue(__mmKey, __mmValue) {
  if (__mmKey === "keybinds") {
    (__mmSetRuntimeBindings(__mmValue), __mmPublishHudState());
    return;
  }
  if (__mmKey === "syncRelayUrl" || __mmKey === "syncRoom")
    return void __mmSetSyncRelayConfig(__mmKey, __mmValue);
  if (
    __mmKey === "enemyColor" ||
    __mmKey === "allyColor" ||
    __mmKey === "friendColor" ||
    __mmKey === "ownColor"
  ) {
    const __mmColor = String(__mmValue || "").trim().toLowerCase();
    if (!/^#[0-9a-f]{6}$/.test(__mmColor)) return;
    if (__mmKey === "enemyColor") __mmEnemyColor = __mmColor;
    else if (__mmKey === "allyColor") __mmAllyColor = __mmColor;
    else if (__mmKey === "friendColor") __mmFriendColor = __mmColor;
    else __mmOwnColor = __mmColor;
    return void __mmPublishHudState();
  }
  if (__mmKey === "killMessage")
    return (
      (__mmKillMessage = String(__mmValue || "").slice(0, 30)),
      void __mmPublishHudState()
    );
  __mmKey === "soldierRange" ||
  __mmKey === "combatRange" ||
  __mmKey === "gearHoldTicks" ||
  __mmKey === "antiBoostRange" ||
  __mmKey === "antiCollisionRange" ||
  __mmKey === "reactionMs" ||
  __mmKey === "smartDepth" ||
  __mmKey === "smartPlaceAccuracy" ||
  __mmKey === "smartMaxPlacements" ||
  __mmKey === "smartPlaceDelay" ||
  __mmKey === "assassinSafeMs" ||
  __mmKey === "assassinMinHealth" ||
  __mmKey === "assassinDangerRange" ||
  __mmKey === "syncFollowGap" ||
  __mmKey === "syncStopTolerance" ||
  __mmKey === "syncResumeTolerance" ||
  __mmKey === "syncPredictionMs" ||
  __mmKey === "syncCatchupDistance" ||
  __mmKey === "syncCatchupReleaseDistance" ||
  __mmKey === "syncMoveRefreshMs"
    ? __mmSetHudNumber(__mmKey, __mmValue)
    : __mmSetHudToggle(__mmKey, __mmValue);
}
function __mmApplyHudSettings(__mmSettings) {
  if (!__mmSettings || typeof __mmSettings !== "object") return;
  Object.prototype.hasOwnProperty.call(__mmSettings, "friendNames") &&
    __mmReplaceFriends(__mmSettings.friendNames);
  const __mmKeys = [
    "autoHeal",
    "soldierAuto",
    "movementGear",
    "trapEscape",
    "automaticStateRepair",
    "keybinds",
    "autoAcceptTeamRequests",
    "autoDeclineTeamRequests",
    "antiBoostInsta",
    "antiInsta",
    "antiCollision",
    "antiCollisionPauseCombat",
    "shieldDefense",
    "placementDefense",
    "antiRetrapPush",
    "teammateTrapRescue",
    "turretSteal",
    "spikeGearCounter",
    "dashMovement",
    "musketRecharge",
    "autoPurchase",
    "matThief",
    "multiTargetBreak",
    "mobSteal",
    "assassinAutomation",
    "spinningWindmills",
    "forceFullServers",
    "bushMode",
    "fpsBoost",
    "smoothVisuals",
    "reloadArcs",
    "entityDanger",
    "notificationTracers",
    "groundGrid",
    "esp",
    "espLines",
    "predictionGhost",
    "placementVisuals",
    "cooldownBars",
    "weaponXpBar",
    "chatHistory",
    "combatTelemetry",
    "telemetryProjectileHits",
    "telemetrySpikeKnockback",
    "telemetryActualAim",
    "telemetryBuildingOwners",
    "telemetryShameCount",
    "telemetryDamageHealing",
    "enemyColor",
    "allyColor",
    "friendColor",
    "ownColor",
    "bullHelmet",
    "tankRightClick",
    "instaKill",
    "autoInsta",
    "autoBowUpgradeInsta",
    "reverseInsta",
    "oneTickInsta",
    "appleInsta",
    "bleedInsta",
    "knockbackInsta",
    "velTickInsta",
    "polearmAids",
    "autoPushInsta",
    "boostSpikeKill",
    "autoTrapInsta",
    "autoSpikeInsta",
    "autoSpikeSpam",
    "autoSpikeKill",
    "animalTrap",
    "passiveMobTrap",
    "bossTeleporter",
    "smartAutoPlace",
    "smartPreplace",
    "smartMultiPlace",
    "smartQuadTraps",
    "smartQuadSpikes",
    "smartSpikeContact",
    "smartTrapContact",
    "smartKnockbackChain",
    "smartTrapSurround",
    "smartAngleDenial",
    "smartAutoPushWeight",
    "smartAutoReplace",
    "smartSpikeSyncPlace",
    "smartAntiBoostPlace",
    "smartMovingMills",
    "smartInstaUtilityPlace",
    "adaptiveSmartness",
    "instaSync",
    "boostBreak",
    "boostChat",
    "materialReply",
    "meowChainInsta",
    "instaChat",
    "bushChat",
    "friendAddedChat",
    "enemyMarkedChat",
    "cleanupProgressChat",
    "cleanupCompleteChat",
    "modReplyChat",
    "enemyTrapChat",
    "friendTrapChat",
    "trapAlertChat",
    "deathHistoryChat",
    "syncStatusChat",
    "syncMovement",
    "syncCopyWeapons",
    "syncCopyBuilds",
    "syncCopyGear",
    "syncCopyAim",
    "syncCopyAttacks",
    "syncCatchupGear",
    "syncPauseInCombat",
    "syncWasdCombatOnly",
    "syncTickCombat",
    "syncFollowGap",
    "syncStopTolerance",
    "syncResumeTolerance",
    "syncPredictionMs",
    "syncCatchupDistance",
    "syncCatchupReleaseDistance",
    "syncMoveRefreshMs",
    "syncRelayUrl",
    "syncRoom",
    "debugPanel",
    "killMessageEnabled",
    "killMessage",
    "soldierRange",
    "combatRange",
    "gearHoldTicks",
    "antiBoostRange",
    "antiCollisionRange",
    "reactionMs",
    "smartDepth",
    "smartPlaceAccuracy",
    "smartMaxPlacements",
    "smartPlaceDelay",
    "assassinSafeMs",
    "assassinMinHealth",
    "assassinDangerRange",
  ];
  for (let __mmIndex = 0; __mmIndex < __mmKeys.length; __mmIndex++) {
    const __mmKey = __mmKeys[__mmIndex];
    Object.prototype.hasOwnProperty.call(__mmSettings, __mmKey) &&
      __mmSetHudValue(__mmKey, __mmSettings[__mmKey]);
  }
  // Hydration can arrive synchronously while the injected client is mounting.
  // Reconcile every placement worker once at the end so a saved ON toggle
  // cannot be displayed without its controller actually running.
  (__mmRefreshSmartPlacementLoop(),
    __mmRefreshKittyInstaLoop(),
    (__mmThreatTrapEnabled ||
      __mmPassiveMobTrapEnabled ||
      __mmBossTeleporterEnabled) &&
      __mmStartThreatTrap(),
    (__mmAutoSpikeSpamEnabled || __mmAutoSpikeKillEnabled) &&
      __mmStartAutoSpikeSpam());
  __mmPublishHudState();
}
function __mmHandleHudCommand(__mmEvent) {
  const __mmCommand = __mmEvent.detail || {};
  if (__mmCommand.type === "hydrate")
    return void __mmApplyHudSettings(__mmCommand.settings);
  if (__mmCommand.type === "set")
    return void __mmSetHudValue(__mmCommand.key, __mmCommand.value);
  if (__mmCommand.type === "friend-add")
    return void __mmAddFriend(__mmCommand.name, !0);
  if (__mmCommand.type === "friend-remove")
    return void __mmRemoveFriend(__mmCommand.name, !0);
  __mmPublishHudState();
}
window.addEventListener("MooMooOPHudCommand", __mmHandleHudCommand);
function __mmCombatHatAntiInstaActive() {
  return !!(
    __mmActionOwner === "antiInsta" ||
    Date.now() < __mmAntiInstaUntil
  );
}
function __mmCombatHatLockActive() {
  return !!(
    __mmCombatHatLockHat != null &&
    Date.now() < __mmCombatHatLockUntil
  );
}
function __mmCombatHatPacketAllowed(__mmHat) {
  // Do not veto later equipment packets at the socket boundary. The Bull/Tank
  // packet is authoritative only for the action phase in which it is
  // sent; higher-priority safety gear and the following combo phase must be
  // free to replace it immediately.
  return !0;
}
function __mmBestPostCombatHat() {
  if (!v || !v.alive) return null;
  if (__mmBushModeEnabled && __mmBushGearOwned()) return __mmBushGear;
  if (__mmMovementGearEnabled) {
    const __mmDesired = __mmDesiredHeldHat();
    if (
      __mmDesired != null &&
      !__mmTemporaryCombatHat(__mmDesired) &&
      (__mmDesired === 0 || (v.skins && v.skins[__mmDesired]))
    )
      return __mmDesired;
  }
  if (__mmSoldierAutoEnabled && v.skins && v.skins[6]) return 6;
  if (
    !__mmTemporaryCombatHat(__mmLastNormalHat) &&
    (__mmLastNormalHat === 0 || (v.skins && v.skins[__mmLastNormalHat]))
  )
    return __mmLastNormalHat;
  if (
    !__mmTemporaryCombatHat(v.skinIndex) &&
    (v.skinIndex === 0 || (v.skins && v.skins[v.skinIndex]))
  )
    return v.skinIndex;
  return 0;
}
function __mmScheduleCombatHatFinish(__mmEpoch = __mmCombatHatLockEpoch) {
  __mmCombatHatLockTimer && clearTimeout(__mmCombatHatLockTimer);
  const __mmDelay = Math.max(
    1,
    __mmCombatHatLockUntil - Date.now(),
  );
  __mmCombatHatLockTimer = setTimeout(function () {
    __mmCombatHatLockTimer = 0;
    __mmFinishCombatHatLock(__mmEpoch);
  }, __mmDelay);
}
function __mmFinishCombatHatLock(__mmEpoch = __mmCombatHatLockEpoch) {
  if (__mmEpoch !== __mmCombatHatLockEpoch) return;
  if (Date.now() < __mmCombatHatLockUntil)
    return void __mmScheduleCombatHatFinish(__mmEpoch);
  const __mmTailRestore = __mmPrimaryClickTail;
  (__mmCombatHatLockTimer && clearTimeout(__mmCombatHatLockTimer),
    (__mmCombatHatLockTimer = 0),
    (__mmCombatHatLockHat = null),
    (__mmCombatHatLockUntil = 0),
    (__mmPrimaryGearStage = __mmPrimaryHeld ? "downtime" : null),
    (__mmSecondaryGearStage = __mmSecondaryHeld ? "downtime" : null),
    (__mmPrimaryClickHat = null),
    (__mmPrimaryClickTail = null),
    (__mmRightClickHat = null));
  // Anti-Insta owns equipment outright. Active Insta stages restore their own
  // snapshot after the last phase, so do not insert a stray downtime packet
  // between Bull/Tank and the next weapon stage.
  if (
    __mmCombatHatAntiInstaActive() ||
    __mmInsta.isActive() ||
    __mmBoostInsta.isActive() ||
    __mmInstaSyncPending ||
    __mmInstaSyncFiring
  )
    return;
  const __mmHat = __mmBestPostCombatHat();
  if (__mmHat != null) {
    __mmCombatHatLockWriting = !0;
    try {
      __mmEquipHatNow(__mmHat, !0, !0);
    } finally {
      __mmCombatHatLockWriting = !1;
    }
  }
  const __mmHeldWeapon = __mmHeldAttackWeapon();
  __mmHeldWeapon != null
    ? __mmUpdateHeldTail(__mmHeldWeapon)
    : __mmTailRestore != null && __mmEquipTailNow(__mmTailRestore, !0);
}
function __mmCancelCombatHatLock(__mmRestoreBest = !0) {
  const __mmBest = v && v.alive ? __mmBestPostCombatHat() : null,
    __mmTailRestore = __mmPrimaryClickTail;
  (__mmCombatHatLockTimer && clearTimeout(__mmCombatHatLockTimer),
    (__mmCombatHatLockTimer = 0),
    (__mmCombatHatLockEpoch += 1),
    (__mmCombatHatLockHat = null),
    (__mmCombatHatLockUntil = 0),
    (__mmPrimaryGearStage = null),
    (__mmSecondaryGearStage = null),
    (__mmPrimaryClickHat = null),
    (__mmPrimaryClickTail = null),
    (__mmRightClickHat = null),
    __mmBest != null &&
      !__mmTemporaryCombatHat(__mmBest) &&
      (__mmLastNormalHat = __mmBest));
  if (!__mmRestoreBest || !v || !v.alive) return;
  (__mmBest != null && __mmEquipHatNow(__mmBest, !0),
    __mmTailRestore != null && __mmEquipTailNow(__mmTailRestore, !0));
}
function __mmActivateCombatHat(__mmHat, __mmTail = null) {
  if (
    !v ||
    !v.alive ||
    __mmCombatHatAntiInstaActive() ||
    (__mmHat !== 0 && !(v.skins && v.skins[__mmHat]))
  )
    return !1;
  const __mmNow = Date.now(),
    __mmEpoch = ++__mmCombatHatLockEpoch;
  (__mmCombatHatLockTimer && clearTimeout(__mmCombatHatLockTimer),
    (__mmCombatHatLockTimer = 0),
    (__mmCombatHatLockHat = __mmHat),
    // Use same-phase equipment: Bull/Tank is sent beside the
    // swing and remains the combat selection for one server action tick only.
    (__mmCombatHatLockUntil = __mmNow + __mmServerTickMs()),
    (__mmCombatHatLockWriting = !0));
  try {
    __mmEquipGearPair(__mmHat, __mmTail, !0, !0);
  } finally {
    __mmCombatHatLockWriting = !1;
  }
  (__mmScheduleCombatHatFinish(__mmEpoch), __mmPublishHudState());
  return !0;
}
function __mmTankGearActive() {
  return !!(v && v.skinIndex === 40);
}
function __mmMovementGearActive() {
  return (
    __mmMovementGearPreviousHat != null || __mmMovementGearPreviousTail != null
  );
}
function __mmTemporaryCombatHat(__mmHat) {
  return (
    [7, 40, __mmTurretGear].includes(Number(__mmHat)) ||
    (__mmSpikeGearCounterEnabled && Number(__mmHat) === 11)
  );
}
function __mmStateRepairGraceMs() {
  return Math.max(80, __mmServerTickMs() * 2);
}
function __mmStateRepairAutomationHoldActive() {
  return !!(
    __mmCleanupAttackHeld ||
    __mmWeaponGrindHold ||
    (__mmTrapAttackActive && __mmTrapAttackHeld) ||
    __mmBoostBreakHeld ||
    __mmMatThiefAttackHeld ||
    __mmMobStealAttackHeld ||
    __mmSpikeTickStrikeHeld ||
    __mmInstaSyncWeaponHeld ||
    __mmSyncDirectAttackActive ||
    __mmSyncObservedAttackHeld ||
    __mmBindingActionHeld("primaryAttack") ||
    __mmBindingActionHeld("clickBoostInsta") ||
    __mmBindingActionHeld("secondaryAttack")
  );
}
function __mmStateRepairCombatActive() {
  return !!(
    __mmCombatHatAntiInstaActive() ||
    __mmCombatHatLockActive() ||
    __mmInsta.isActive() ||
    __mmBoostInsta.isActive() ||
    __mmInstaSyncPending ||
    __mmInstaSyncFiring ||
    __mmTrapAttackActive ||
    __mmBoostBreakHeld ||
    __mmSpikeTickStrikeTimer ||
    __mmAntiBoostBlockTimer ||
    __mmTeammateRescueReleaseTimer ||
    __mmDashMovementReleaseTimer ||
    __mmTurretStealRestoreTimer ||
    __mmSpikeGearCounterTimer ||
    __mmSpikeGearCounterRestoreTimer ||
    __mmStateRepairAutomationHoldActive() ||
    (__mmPhysicalPrimaryDown && __mmPrimaryHeld) ||
    (__mmPhysicalSecondaryDown && __mmSecondaryHeld) ||
    (__mmActionOwner !== "idle" &&
      __mmActionOwner !== "movementGear" &&
      __mmActionOwner !== "soldierGear" &&
      __mmActionOwner !== "weaponRecharge" &&
      Date.now() - __mmActionSince < Math.max(500, 4 * __mmServerTickMs()))
  );
}
function __mmRecordStateRepair(__mmReasons) {
  if (!__mmReasons.length) return !1;
  ((__mmStateRepairLastAt = Date.now()),
    (__mmStateRepairLastReason = __mmReasons.join(" + ")),
    (__mmStateRepairCount += 1));
  __mmPublishHudState();
  return !0;
}
function __mmStateRepairTry(__mmCallback) {
  try {
    __mmCallback();
    return !0;
  } catch (__mmRepairError) {
    return !1;
  }
}
function __mmStateRepairReleaseAttack(__mmAngle) {
  return __mmStateRepairTry(function () {
    O.send("F", 0, Number.isFinite(__mmAngle) ? __mmAngle : null);
  });
}
function __mmRepairBorrowedToolStates(__mmReasons) {
  const __mmOwner = __mmActionOwner;
  if (
    (__mmOwner === "matThief" && !__mmMatThiefReleaseTimer) ||
    (__mmOwner !== "matThief" &&
      (__mmMatThiefAttackHeld ||
        __mmMatThiefRestoreTool != null ||
        Number.isFinite(__mmMatThiefAimAngle)))
  )
    (__mmMatThiefAttackHeld &&
      __mmStateRepairReleaseAttack(__mmMatThiefAimAngle),
      (__mmMatThiefAttackHeld = !1),
      __mmStateRepairTry(function () {
        __mmFinishMatThief("automatic state repair");
      }),
      __mmActionOwner === "matThief" &&
        __mmActionRelease("matThief", "automatic state repair"),
      __mmReasons.push("Mat Thief tool"));
  if (
    (__mmOwner === "mobSteal" &&
      !__mmMobStealStageTimer &&
      !__mmMobStealReleaseTimer) ||
    (__mmOwner !== "mobSteal" &&
      (__mmMobStealAttackHeld ||
        __mmMobStealRestoreTool != null ||
        Number.isFinite(__mmMobStealAimAngle)))
  )
    (__mmMobStealAttackHeld &&
      __mmStateRepairReleaseAttack(__mmMobStealAimAngle),
      (__mmMobStealAttackHeld = !1),
      __mmStateRepairTry(function () {
        __mmFinishMobSteal("automatic state repair");
      }),
      __mmActionOwner === "mobSteal" &&
        __mmActionRelease("mobSteal", "automatic state repair"),
      __mmReasons.push("Mob Steal tool"));
  if (
    (__mmOwner === "instaSync" &&
      !__mmInstaSyncPending &&
      !__mmInstaSyncFiring) ||
    (__mmOwner !== "instaSync" &&
      !__mmInstaSyncPending &&
      !__mmInstaSyncFiring &&
      (__mmInstaSyncWeaponHeld || __mmInstaSyncRestoreTool != null))
  )
    (__mmInstaSyncWeaponHeld && __mmStateRepairReleaseAttack(null),
      (__mmInstaSyncWeaponHeld = !1),
      __mmStateRepairTry(__mmStopInstaSync),
      __mmActionOwner === "instaSync" &&
        __mmActionRelease("instaSync", "automatic state repair"),
      __mmReasons.push("sync tool"));
  if (
    (__mmOwner === "spikeTickStrike" && !__mmSpikeTickStrikeTimer) ||
    (__mmOwner !== "spikeTickStrike" &&
      (__mmSpikeTickStrikeHeld || __mmSpikeTickStrikeTool != null))
  )
    (__mmSpikeTickStrikeHeld &&
      __mmStateRepairReleaseAttack(__mmSpikeTickStrikeAimAngle),
      (__mmSpikeTickStrikeHeld = !1),
      __mmStateRepairTry(function () {
        __mmStopSpikeTickStrike("automatic state repair");
      }),
      __mmActionOwner === "spikeTickStrike" &&
        __mmActionRelease("spikeTickStrike", "automatic state repair"),
      __mmReasons.push("spike strike tool"));
  if (
    (__mmOwner === "antiBoostBlock" && !__mmAntiBoostBlockTimer) ||
    (__mmOwner !== "antiBoostBlock" &&
      __mmAntiBoostBlockTool != null &&
      !__mmAntiBoostBlockTimer)
  )
    (__mmStateRepairTry(function () {
        __mmStopAntiBoostBlock("automatic state repair");
      }),
      __mmActionOwner === "antiBoostBlock" &&
        __mmActionRelease("antiBoostBlock", "automatic state repair"),
      __mmReasons.push("anti-boost tool"));
  if (
    (__mmOwner === "teammateRescue" && !__mmTeammateRescueReleaseTimer) ||
    (__mmOwner !== "teammateRescue" &&
      __mmTeammateRescueRestoreTool != null &&
      !__mmTeammateRescueReleaseTimer)
  )
    (__mmTeammateRescueAngle != null &&
      __mmStateRepairReleaseAttack(__mmTeammateRescueAngle),
      (__mmTeammateRescueAngle = null),
      __mmStateRepairTry(function () {
        __mmStopTeammateRescue("automatic state repair");
      }),
      __mmTeammateRescueRestoreTool != null &&
        __mmActionMayRestore("teammateRescue") &&
        __mmStateRepairTry(function () {
          __mmRestoreTool(__mmTeammateRescueRestoreTool);
        }),
      (__mmTeammateRescueRestoreTool = null),
      __mmActionOwner === "teammateRescue" &&
        __mmActionRelease("teammateRescue", "automatic state repair"),
      __mmReasons.push("rescue tool"));
  if (
    (__mmOwner === "dashMovement" && !__mmDashMovementReleaseTimer) ||
    (__mmOwner !== "dashMovement" &&
      __mmDashMovementRestoreTool != null &&
      !__mmDashMovementReleaseTimer)
  )
    (__mmDashMovementAngle != null &&
      __mmStateRepairReleaseAttack(__mmDashMovementAngle),
      (__mmDashMovementAngle = null),
      __mmStateRepairTry(function () {
        __mmStopDashMovement("automatic state repair");
      }),
      __mmDashMovementRestoreTool != null &&
        __mmActionMayRestore("dashMovement") &&
        __mmStateRepairTry(function () {
          __mmRestoreTool(__mmDashMovementRestoreTool);
        }),
      (__mmDashMovementRestoreTool = null),
      __mmActionOwner === "dashMovement" &&
        __mmActionRelease("dashMovement", "automatic state repair"),
      __mmReasons.push("dash tool"));
  if (
    (__mmOwner === "weaponRecharge" &&
      __mmWeaponRechargeActiveWeapon == null) ||
    (__mmOwner === "idle" &&
      __mmWeaponRechargePreviousTool != null &&
      __mmWeaponRechargeActiveWeapon == null) ||
    (__mmWeaponRechargeHeldLoan &&
      !__mmPrimaryHeld &&
      !__mmSecondaryHeld)
  )
    (__mmStateRepairTry(function () {
        __mmStopWeaponRecharge(!0);
      }),
      (__mmWeaponRechargeHeldLoan = null),
      __mmActionOwner === "weaponRecharge" &&
        __mmActionRelease("weaponRecharge", "automatic state repair"),
      __mmReasons.push("reload tool"));
}
function __mmRepairForcedAimState(__mmReasons) {
  let __mmCleared = !1;
  if (!__mmTrapAttackActive && Number.isFinite(__mmTrapAimAngle))
    ((__mmTrapAimAngle = null), (__mmCleared = !0));
  if (
    (!__mmSecondaryShieldActive || !__mmSecondaryHeld) &&
    Number.isFinite(__mmSecondaryShieldAngle)
  )
    ((__mmSecondaryShieldActive = !1),
      (__mmSecondaryShieldAngle = null),
      (__mmSecondaryShieldAimAt = 0),
      (__mmCleared = !0));
  if (
    Number.isFinite(__mmMultiBreakAimAngle) &&
    (__mmActionOwner !== "manualAttack" ||
      (!__mmPrimaryHeld && !__mmSecondaryHeld))
  )
    (__mmStopMultiBreakAim(), (__mmCleared = !0));
  if (!__mmCleanupActive && Number.isFinite(__mmCleanupAimAngle))
    ((__mmCleanupAimAngle = null), (__mmCleared = !0));
  if (
    (!__mmWeaponGrindEnabled ||
      (!__mmWeaponGrindHold && __mmActionOwner !== "weaponGrind")) &&
    Number.isFinite(__mmWeaponGrindAimAngle)
  )
    ((__mmWeaponGrindAimAngle = null), (__mmCleared = !0));
  if (
    Date.now() >= __mmAutoSpikeSpamAimUntil &&
    Number.isFinite(__mmAutoSpikeSpamAimAngle)
  )
    ((__mmAutoSpikeSpamAimAngle = null), (__mmCleared = !0));
  if (__mmCleared) __mmReasons.push("forced aim");
  if (
    !__mmForcedDirectionStillActive() &&
    (__mmCleared ||
      (__mmLastForcedDirectionAt &&
        Date.now() - __mmLastForcedDirectionAt >= __mmStateRepairGraceMs()))
  )
    __mmScheduleMouseAimReturn();
}
function __mmUpdateAutomaticStateRepair(__mmForce) {
  if (!__mmAutomaticStateRepairEnabled || !v || !v.alive) return !1;
  const __mmNow = Date.now(),
    __mmReasons = [],
    __mmInputSettled =
      __mmForce ||
      __mmNow - __mmPhysicalInputAt >= __mmStateRepairGraceMs();
  if (__mmInputSettled) {
    if (
      __mmPrimaryHeld &&
      !__mmPhysicalPrimaryDown &&
      !__mmBindingActionHeld("primaryAttack") &&
      !__mmBindingActionHeld("clickBoostInsta") &&
      !(__mmCleanupAttackHeld && __mmCleanupMouseButton === 0) &&
      !__mmWeaponGrindHold
    )
      (__mmStateRepairTry(__mmStopPrimaryInput),
        (__mmPrimaryHeld = !1),
        __mmReasons.push("primary hold"));
    if (
      __mmSecondaryHeld &&
      !__mmPhysicalSecondaryDown &&
      !__mmBindingActionHeld("secondaryAttack") &&
      !(__mmCleanupAttackHeld && __mmCleanupMouseButton === 2) &&
      !__mmWeaponGrindHold
    )
      (__mmStateRepairTry(__mmFinishSecondaryInput),
        (__mmSecondaryHeld = !1),
        __mmReasons.push("secondary hold"));
  }
  if (
    __mmInputSettled &&
    (__mmPrimaryAttackDown || __mmSecondaryAttackDown) &&
    !__mmStateRepairAutomationHoldActive() &&
    !(__mmPhysicalPrimaryDown && __mmPrimaryHeld) &&
    !(__mmPhysicalSecondaryDown && __mmSecondaryHeld)
  ) {
    (__mmHeldAttackTimer && clearInterval(__mmHeldAttackTimer),
      (__mmHeldAttackTimer = 0),
      __mmStateRepairReleaseAttack(null),
      (__mmPrimaryAttackDown = !1),
      (__mmSecondaryAttackDown = !1),
      __mmReasons.push("attack release"));
  }
  if (
    __mmInputSettled &&
    __mmActionOwner === "manualAttack" &&
    !__mmPrimaryHeld &&
    !__mmSecondaryHeld &&
    !__mmStateRepairAutomationHoldActive()
  )
    (__mmActionRelease("manualAttack", "automatic state repair"),
      __mmReasons.push("manual owner"));
  __mmRepairBorrowedToolStates(__mmReasons);
  __mmRepairForcedAimState(__mmReasons);
  if (
    __mmCombatHatLockHat != null &&
    __mmNow >= __mmCombatHatLockUntil
  )
    (__mmStateRepairTry(function () {
        __mmFinishCombatHatLock(__mmCombatHatLockEpoch);
      }),
      __mmReasons.push("combat hat timer"));
  if (
    __mmInputSettled &&
    !__mmStateRepairCombatActive() &&
    (__mmPrimaryClickHat != null ||
      __mmPrimaryClickTail != null ||
      __mmRightClickHat != null ||
      __mmPrimaryGearStage != null ||
      __mmSecondaryGearStage != null)
  )
    (__mmCancelCombatHatLock(!1), __mmReasons.push("combat gear stage"));
  if (
    __mmInputSettled &&
    !__mmStateRepairCombatActive() &&
    (__mmTemporaryCombatHat(__mmPendingHat) ||
      (__mmTemporaryCombatHat(v.skinIndex) &&
        !(__mmPendingHat != null &&
          !__mmTemporaryCombatHat(__mmPendingHat) &&
          __mmNow - __mmPendingHatAt <
            Math.max(250, 3 * __mmServerTickMs()))))
  ) {
    const __mmHat = __mmInstaSafeRestoreHat(__mmBestPostCombatHat());
    const __mmNeedsRequest =
      Number(__mmPendingHat) !== Number(__mmHat) ||
      __mmNow - __mmPendingHatAt >= __mmServerTickMs();
    __mmCanEquipHat(__mmHat) &&
      __mmStateRepairTry(function () {
        __mmEquipHatNow(__mmHat, !0);
      });
    __mmNeedsRequest && __mmReasons.push("stray combat hat");
  }
  return __mmRecordStateRepair(__mmReasons);
}
function __mmRecoverStrayCombatHat() {
  if (
    !v ||
    !v.alive ||
    __mmCombatHatLockActive() ||
    __mmCombatHatAntiInstaActive() ||
    __mmInsta.isActive() ||
    __mmBoostInsta.isActive() ||
    __mmPrimaryHeld ||
    __mmSecondaryHeld ||
    __mmTrapAttackActive ||
    __mmBoostBreakHeld ||
    (__mmActionOwner !== "idle" &&
      __mmActionOwner !== "movementGear" &&
      __mmActionOwner !== "soldierGear" &&
      __mmActionOwner !== "weaponRecharge") ||
    (!__mmTemporaryCombatHat(v.skinIndex) &&
      !__mmTemporaryCombatHat(__mmPendingHat))
  )
    return !1;
  const __mmHat = __mmInstaSafeRestoreHat(__mmBestPostCombatHat());
  return __mmCanEquipHat(__mmHat) && __mmEquipHatNow(__mmHat, !0);
}
function __mmRememberNormalHat() {
  v &&
    v.alive &&
    !__mmTemporaryCombatHat(v.skinIndex) &&
    (__mmLastNormalHat = v.skinIndex);
}
function __mmEquipHatNow(
  __mmHat,
  __mmOverridePending,
  __mmCombatHatBypass = !1,
) {
  __mmHat = __mmCombatSafeHat(__mmHat);
  if (
    !v ||
    !v.alive ||
    __mmHat == null ||
    (__mmHat !== 0 && !(v.skins && v.skins[__mmHat])) ||
    (!__mmCombatHatBypass && !__mmCombatHatPacketAllowed(__mmHat))
  )
    return !1;
  const __mmHasConflictingPendingEquip = !!(
    __mmOverridePending &&
    __mmPendingHat != null &&
    __mmPendingHat !== __mmHat
  );
  if (v.skinIndex === __mmHat && !__mmHasConflictingPendingEquip) {
    __mmPendingHat === __mmHat &&
      ((__mmPendingHat = null), (__mmPendingHatAt = 0));
    return !0;
  }
  const __mmNow = Date.now();
  if (
    __mmPendingHat === __mmHat &&
    __mmNow - __mmPendingHatAt < __mmServerTickMs()
  )
    return !0;
  return (
    O.send("c", 0, __mmHat, !1),
    (__mmPendingHat = __mmHat),
    (__mmPendingHatAt = __mmNow),
    !__mmTemporaryCombatHat(__mmHat) && (__mmLastNormalHat = __mmHat),
    !0
  );
}
function __mmEquipTailNow(__mmTail, __mmOverridePending) {
  if (
    !v ||
    !v.alive ||
    __mmTail == null ||
    (__mmTail !== 0 && !(v.tails && v.tails[__mmTail]))
  )
    return !1;
  const __mmHasConflictingPendingEquip = !!(
    __mmOverridePending &&
    __mmPendingTail != null &&
    __mmPendingTail !== __mmTail
  );
  if (v.tailIndex === __mmTail && !__mmHasConflictingPendingEquip) {
    __mmPendingTail === __mmTail &&
      ((__mmPendingTail = null), (__mmPendingTailAt = 0));
    return !0;
  }
  const __mmNow = Date.now();
  if (
    __mmPendingTail === __mmTail &&
    __mmNow - __mmPendingTailAt < __mmServerTickMs()
  )
    return !0;
  return (
    O.send("c", 0, __mmTail, !0),
    (__mmPendingTail = __mmTail),
    (__mmPendingTailAt = __mmNow),
    !0
  );
}
function __mmEquipGearPair(
  __mmHat,
  __mmTail,
  __mmOverridePending,
  __mmCombatHatBypass = !1,
) {
  if (!v || !v.alive) return !1;
  __mmHat = __mmCombatSafeHat(__mmHat);
  const __mmHatValid = !!(
      __mmHat != null &&
      (__mmHat === 0 || (v.skins && v.skins[__mmHat])) &&
      (__mmCombatHatBypass || __mmCombatHatPacketAllowed(__mmHat))
    ),
    __mmTailValid = !!(
      __mmTail != null &&
      (__mmTail === 0 || (v.tails && v.tails[__mmTail]))
    ),
    __mmNow = Date.now(),
    __mmTick = __mmServerTickMs(),
    // Combat/restore pairs must remain pairs even if one side is already the
    // visible value or has an identical request awaiting acknowledgement.
    __mmForcePair = !!(
      __mmOverridePending &&
      __mmHatValid &&
      __mmTailValid
    ),
    __mmHatConflict = !!(
      __mmOverridePending &&
      __mmPendingHat != null &&
      __mmPendingHat !== __mmHat
    ),
    __mmTailConflict = !!(
      __mmOverridePending &&
      __mmPendingTail != null &&
      __mmPendingTail !== __mmTail
    ),
    __mmSendHat = !!(
      __mmHatValid &&
      (__mmForcePair ||
        v.skinIndex !== __mmHat ||
        __mmHatConflict) &&
      (__mmForcePair ||
        __mmPendingHat !== __mmHat ||
        __mmNow - __mmPendingHatAt >= __mmTick)
    ),
    __mmSendTail = !!(
      __mmTailValid &&
      (__mmForcePair ||
        v.tailIndex !== __mmTail ||
        __mmTailConflict) &&
      (__mmForcePair ||
        __mmPendingTail !== __mmTail ||
        __mmNow - __mmPendingTailAt >= __mmTick)
    );
  // Decide both slots first, then emit both socket packets synchronously with
  // the same timestamp. No timer, microtask, acknowledgement, or helper call
  // is allowed between the paired packets.
  const __mmWasPairing = __mmSyncGearPairDispatch;
  __mmSyncGearPairDispatch = !0;
  try {
    (__mmSendHat &&
      (O.send("c", 0, __mmHat, !1),
      (__mmPendingHat = __mmHat),
      (__mmPendingHatAt = __mmNow),
      !__mmTemporaryCombatHat(__mmHat) && (__mmLastNormalHat = __mmHat)),
      __mmSendTail &&
        (O.send("c", 0, __mmTail, !0),
        (__mmPendingTail = __mmTail),
        (__mmPendingTailAt = __mmNow)));
  } finally {
    __mmSyncGearPairDispatch = __mmWasPairing;
  }
  !__mmWasPairing &&
    (__mmHat != null || __mmTail != null) &&
    __mmSyncPublishGearPair(__mmHat, __mmTail);
  return __mmSendHat || __mmSendTail;
}
function __mmSetProximityTail(__mmTail) {
  if (!v || __mmTail == null) return;
  (__mmProximityTailPrevious == null &&
    (__mmProximityTailPrevious = __mmBushRestoreTail(v.tailIndex)),
    __mmEquipTailNow(__mmTail));
}
function __mmRestoreProximityTail() {
  if (__mmProximityTailPrevious == null) return;
  if (!v || !v.alive) return void (__mmProximityTailPrevious = null);
  const __mmTail = __mmProximityTailPrevious;
  ((__mmProximityTailPrevious = null), __mmEquipTailNow(__mmTail));
}
function __mmClearIdleMonkeyTail() {
  if (
    !v ||
    !v.alive ||
    __mmPlayerMoving() ||
    __mmBoostBreakHeld ||
    v.tailIndex !== 11
  )
    return;
  const __mmTail = __mmMovementGearPreviousTail;
  __mmMovementGearPreviousTail = null;
  const __mmRestoreTail =
    __mmTail === 0 || (__mmTail != null && v.tails && v.tails[__mmTail])
      ? __mmTail
      : 0;
  __mmEquipTailNow(__mmRestoreTail);
}
function __mmAnimalInWeaponPath(__mmWeapon) {
  if (
    !v ||
    !v.alive ||
    __mmWeapon == null ||
    Number(__mmWeapon) === 8 ||
    !Array.isArray(N)
  )
    return !1;
  const __mmWeaponData = b && b.weapons && b.weapons[__mmWeapon];
  if (!__mmWeaponData) return !1;
  const __mmAim = Ci(),
    __mmProjectile = __mmWeaponData.projectile != null,
    __mmBaseRange = Number(__mmWeaponData.range) || 0;
  for (let __mmIndex = 0; __mmIndex < N.length; __mmIndex++) {
    const __mmAnimal = N[__mmIndex];
    if (
      !__mmAnimal ||
      __mmAnimal.active === !1 ||
      __mmAnimal.alive === !1 ||
      !__mmAnimal.visible ||
      (Number.isFinite(Number(__mmAnimal.health)) &&
        Number(__mmAnimal.health) <= 0)
    )
      continue;
    const __mmDx = Number(__mmAnimal.x) - Number(v.x),
      __mmDy = Number(__mmAnimal.y) - Number(v.y),
      __mmDistance = Math.hypot(__mmDx, __mmDy),
      __mmAnimalScale = Number(__mmAnimal.scale) || 35,
      __mmReach = __mmProjectile
        ? Math.max(700, __mmBaseRange + __mmAnimalScale)
        : __mmBaseRange +
          (Number(v.scale) || 35) +
          __mmAnimalScale +
          24;
    if (!Number.isFinite(__mmDistance) || __mmDistance > __mmReach) continue;
    const __mmDirection = Math.atan2(__mmDy, __mmDx),
      __mmDifference = Math.abs(
        Math.atan2(
          Math.sin(__mmDirection - __mmAim),
          Math.cos(__mmDirection - __mmAim),
        ),
      ),
      __mmAimWindow = __mmProjectile
        ? Math.max(
            0.12,
            Math.min(
              0.55,
              Math.asin(
                Math.min(0.99, (__mmAnimalScale + 18) / Math.max(1, __mmDistance)),
              ) + 0.08,
            ),
          )
        : Math.max(0.35, Number(y && y.gatherAngle) || 0.35);
    if (__mmDifference <= __mmAimWindow) return !0;
  }
  return !1;
}
function __mmHeldTailRestoreValue() {
  if (!v || !v.alive) return null;
  return __mmMovementGearPreviousTail != null
    ? __mmMovementGearPreviousTail
    : __mmProximityTailPrevious != null
      ? __mmProximityTailPrevious
      : __mmBushRestoreTail(v.tailIndex);
}
function __mmHeldHatRestoreValue() {
  if (!v || !v.alive) return null;
  return __mmMovementGearPreviousHat != null
    ? __mmMovementGearPreviousHat
    : __mmSoldierPreviousHat != null
      ? __mmSoldierPreviousHat
      : __mmBaseAutomationHat();
}
function __mmEffectiveTailIndex() {
  if (!v || !v.alive) return 0;
  return __mmPendingTail != null &&
    Date.now() - __mmPendingTailAt <= Math.max(180, __mmServerTickMs() * 2)
    ? Number(__mmPendingTail)
    : Number(v.tailIndex);
}
function __mmDesiredHeldTail(__mmWeapon) {
  if (!v || !v.alive || !v.tails) return null;
  if (
    Number(__mmWeapon) !== 8 &&
    __mmAnimalInWeaponPath(__mmWeapon)
  )
    return 0;
  if (!__mmMovementGearEnabled) return null;
  const __mmEnemyNearby = __mmEnemyWithinCombatRange(),
    __mmMoving = __mmPlayerMoving();
  if (__mmEnemyNearby) {
    if (__mmMoving && v.tails[__mmShadowWings]) return __mmShadowWings;
    if (!__mmMoving && v.tails[__mmBloodWings]) return __mmBloodWings;
    if (!__mmMoving || (!__mmHasStick() && __mmEffectiveTailIndex() === 11))
      return 0;
    return null;
  }
  if (__mmMoving && v.tails[11]) return 11;
  if (!__mmMoving && v.tails[__mmAngelWings]) return __mmAngelWings;
  return !__mmMoving && __mmEffectiveTailIndex() === 11 ? 0 : null;
}
function __mmRememberHeldTail(__mmTail) {
  if (__mmTail == null || __mmHeldTailPrevious != null) return;
  __mmHeldTailPrevious = __mmHeldTailRestoreValue();
}
function __mmUpdateHeldTail(__mmWeapon) {
  if (!v || !v.alive) return;
  if (__mmPrimaryHeld && __mmPrimaryGearStage === "bull") return;
  const __mmTail = __mmDesiredHeldTail(__mmWeapon);
  if (__mmTail == null) {
    if (__mmHeldTailPrevious == null) return;
    const __mmRestoreTail = __mmHeldTailPrevious;
    __mmHeldTailPrevious = null;
    return void __mmEquipTailNow(__mmRestoreTail, !0);
  }
  (__mmRememberHeldTail(__mmTail), __mmEquipTailNow(__mmTail, !0));
}
function __mmRestoreHeldTail() {
  if (__mmHeldTailPrevious == null) return;
  const __mmTail = __mmHeldTailPrevious;
  ((__mmHeldTailPrevious = null),
    v && v.alive && __mmEquipTailNow(__mmTail, !0));
}
function __mmDesiredHeldHat() {
  if (!v || !v.alive || !__mmMovementGearEnabled) return null;
  __mmInSnowBiome() && __mmBuySnowHat();
  if (__mmEnemyWithinCombatRange())
    return v.skins && v.skins[6] ? 6 : null;
  if (!__mmPlayerMoving())
    return v.skins && v.skins[__mmEmpHelmet]
      ? __mmEmpHelmet
      : v.skins && v.skins[6]
        ? 6
        : null;
  __mmInWater() && __mmBuyFlipperHat();
  const __mmHat = __mmSpeedHat();
  return v.skins && v.skins[__mmHat] ? __mmHat : 0;
}
function __mmRememberHeldHat(__mmHat) {
  if (
    __mmHat == null ||
    __mmHeldHatPrevious != null ||
    __mmPrimaryClickHat != null ||
    __mmRightClickHat != null
  )
    return;
  __mmHeldHatPrevious = __mmHeldHatRestoreValue();
}
function __mmUpdateHeldHat() {
  if (!v || !v.alive) return;
  if (
    (__mmPrimaryHeld && __mmPrimaryGearStage === "bull") ||
    (__mmSecondaryHeld && __mmSecondaryGearStage === "tank")
  )
    return;
  const __mmHat = __mmDesiredHeldHat();
  if (__mmHat == null) {
    if (__mmHeldHatPrevious == null) return;
    const __mmRestoreHat = __mmHeldHatPrevious;
    __mmHeldHatPrevious = null;
    return void __mmEquipHatNow(__mmRestoreHat, !0);
  }
  (__mmRememberHeldHat(__mmHat), __mmEquipHatNow(__mmHat, !0));
}
function __mmRestoreHeldHat() {
  if (__mmHeldHatPrevious == null) return;
  const __mmHat = __mmHeldHatPrevious;
  ((__mmHeldHatPrevious = null),
    v && v.alive && __mmEquipHatNow(__mmHat, !0));
}
function __mmUpdateHeldGear(__mmWeapon) {
  (__mmUpdateHeldHat(), __mmUpdateHeldTail(__mmWeapon));
}
function __mmHeldAttackWeapon() {
  return !v || !v.alive || !v.weapons
    ? null
    : __mmSecondaryHeld
      ? __mmRightClickWeapon()
      : __mmPrimaryHeld
        ? v.weapons[0]
        : null;
}
function __mmSendWeaponAttack(__mmState) {
  O.send("F", __mmState, null);
}
function __mmPulseHeldAttack() {
  const __mmWeapon = __mmHeldAttackWeapon();
  if (__mmWeapon == null) return;
  if (__mmSecondaryHeld) return void __mmPulseSecondaryWeapon();
  if (__mmPrimaryHeld && __mmBullPrimaryAvailable()) {
    return void __mmPulsePrimaryBullWeapon();
  }
  __mmUpdateHeldGear(__mmWeapon);
  if (__mmPrimaryHeld && !__mmPrimaryAttackDown) {
    (je(__mmWeapon, !0),
      __mmSendWeaponAttack(1),
      (__mmPrimaryAttackDown = !0));
  }
}
function __mmStartHeldAttackPulse() {
  __mmPulseHeldAttack();
  if (__mmHeldAttackTimer) return;
  __mmHeldAttackTimer = setInterval(function () {
    __mmHeldAttackWeapon() != null
      ? __mmPulseHeldAttack()
      : __mmStopHeldAttackPulse();
  }, (__mmPrimaryHeld && __mmBullPrimaryAvailable()) ||
    (__mmSecondaryHeld &&
      __mmTankRightClickEnabled &&
      v &&
      v.skins &&
      v.skins[40])
    ? __mmFastCheckMs()
    : __mmServerTickMs());
}
function __mmStopHeldAttackPulse() {
  if (__mmPrimaryHeld || __mmSecondaryHeld) return;
  (__mmHeldAttackTimer &&
    (clearInterval(__mmHeldAttackTimer), (__mmHeldAttackTimer = 0)),
    v && v.alive && __mmSendWeaponAttack(0),
    (__mmPrimaryAttackDown = !1));
}
function __mmResumeHeldAttack() {
  if (
    __mmTrapAttackActive &&
    __mmTrapAttackHeld &&
    __mmTrapAttackHeldWeapon != null
  ) {
    const __mmAngle = Number.isFinite(__mmTrapAimAngle)
      ? __mmTrapAimAngle
      : Ci();
    (je(__mmTrapAttackHeldWeapon, !0),
      O.send("D", __mmAngle),
      O.send("F", 1, __mmAngle));
    return;
  }
  // Food/build/insta actions issue their own F=0. Re-arm the native held
  // attack once after restoring the primary instead of restarting a pulse loop.
  __mmPrimaryHeld && (__mmPrimaryAttackDown = !1);
  __mmSecondaryHeld && (__mmSecondaryAttackDown = !1);
  __mmPulseHeldAttack();
}
function __mmCanEat() {
  if (!v || !v.alive || v.items[0] == null) return !1;
  const __mmFood = b.list[v.items[0]];
  if (!__mmFood || !__mmFood.consume || !__mmFood.req) return !1;
  for (
    let __mmReqIndex = 0;
    __mmReqIndex < __mmFood.req.length;
    __mmReqIndex += 2
  )
    if ((v[__mmFood.req[__mmReqIndex]] || 0) < __mmFood.req[__mmReqIndex + 1])
      return !1;
  return !0;
}
function __mmFoodCharges() {
  if (!__mmCanEat()) return 0;
  const __mmFood = b.list[v.items[0]];
  let __mmCharges = Infinity;
  for (
    let __mmReqIndex = 0;
    __mmReqIndex < __mmFood.req.length;
    __mmReqIndex += 2
  )
    __mmCharges = Math.min(
      __mmCharges,
      Math.floor(
        (v[__mmFood.req[__mmReqIndex]] || 0) / __mmFood.req[__mmReqIndex + 1],
      ),
    );
  return Number.isFinite(__mmCharges) ? Math.max(0, __mmCharges) : 0;
}
function __mmUseFood() {
  if (!__mmCanEat()) return;
  const __mmTool = __mmSelectedTool();
  (je(v.items[0]),
    O.send("F", 1, Ci()),
    O.send("F", 0, Ci()),
    __mmRestoreTool(__mmTool),
    __mmResumeHeldAttack());
}
function __mmUseFoodBurst(__mmCount) {
  const __mmBites = Math.min(Math.max(0, __mmCount | 0), __mmFoodCharges());
  if (!__mmBites) return;
  const __mmFood = v.items[0],
    __mmAngle = Ci(),
    __mmTool = __mmSelectedTool();
  for (let __mmBite = 0; __mmBite < __mmBites; __mmBite++)
    (je(__mmFood), O.send("F", 1, __mmAngle), O.send("F", 0, __mmAngle));
  (__mmRestoreTool(__mmTool), __mmResumeHeldAttack());
}
function __mmAtFullHealth() {
  return v && v.alive && v.health >= v.maxHealth;
}
function __mmSelectedWeapon() {
  return !v || !v.alive
    ? null
    : v.weapons.includes(__mmLastWeapon)
      ? __mmLastWeapon
      : v.weapons.includes(v.weaponIndex)
        ? v.weaponIndex
        : v.weapons[0];
}
function __mmHoldingMcGrabby() {
  return !!(
    v &&
    v.alive &&
    Number(v.buildIndex) < 0 &&
    Number(__mmSelectedWeapon()) === __mmMcGrabby
  );
}
function __mmRestoreWeapon(__mmWeapon) {
  v && v.alive && v.weapons.includes(__mmWeapon) && je(__mmWeapon, !0);
}
function __mmSelectedTool() {
  if (!v || !v.alive) return null;
  const __mmBuild = Number(v.buildIndex);
  if (
    Number.isInteger(__mmBuild) &&
    __mmBuild >= 0 &&
    v.items &&
    v.items.includes(__mmBuild)
  )
    return { item: __mmBuild, weapon: !1 };
  const __mmWeapon = __mmSelectedWeapon();
  return __mmWeapon == null ? null : { item: __mmWeapon, weapon: !0 };
}
function __mmRestoreTool(__mmTool) {
  if (!v || !v.alive || !__mmTool) return;
  __mmTool.weapon
    ? __mmRestoreWeapon(__mmTool.item)
    : v.items && v.items.includes(__mmTool.item) && je(__mmTool.item);
}
const __mmCleanupRadius = 1000,
  __mmCleanupInputKeys = Object.freeze({
    87: !0,
    65: !0,
    83: !0,
    68: !0,
    70: !0,
    86: !0,
    82: !0,
    72: !0,
    90: !0,
  });
function __mmCleanupObjectScale(__mmObject) {
  if (!__mmObject) return 0;
  if (typeof __mmObject.getScale === "function") {
    const __mmScale = Number(__mmObject.getScale(0.6, !!__mmObject.isItem));
    if (Number.isFinite(__mmScale) && __mmScale > 0) return __mmScale;
  }
  return Math.max(
    1,
    Number(__mmObject.blocker) ||
      Number(__mmObject.scale) ||
      Number(b && b.list && b.list[__mmObject.id] && b.list[__mmObject.id].scale) ||
      35,
  );
}
function __mmCleanupIsSpike(__mmObject) {
  const __mmItem = __mmObject && b && b.list && b.list[__mmObject.id],
    __mmName = String((__mmItem && __mmItem.name) || "").toLowerCase();
  return __mmName.includes("spikes");
}
function __mmCleanupStructureAllowed(__mmObject) {
  const __mmData = __mmObject && b && b.list && b.list[__mmObject.id];
  if (
    !__mmCleanupActive ||
    !__mmObject ||
    !__mmObject.active ||
    !__mmObject.isItem ||
    !__mmData ||
    !__mmData.group ||
    !__mmData.group.place
  )
    return !1;
  const __mmState = __mmBreakableState(__mmObject),
    __mmLiveHealth = Number(__mmObject.health),
    __mmHealth = __mmState
      ? Number(__mmState.health)
      : Number.isFinite(__mmLiveHealth)
        ? __mmLiveHealth
        : Number(__mmData.health);
  if (!Number.isFinite(__mmHealth) || __mmHealth <= 0.001) return !1;
  const __mmDx = Number(__mmObject.x) - __mmCleanupOriginX,
    __mmDy = Number(__mmObject.y) - __mmCleanupOriginY;
  return (
    Number.isFinite(__mmDx) &&
    Number.isFinite(__mmDy) &&
    __mmDx * __mmDx + __mmDy * __mmDy <=
      __mmCleanupRadius * __mmCleanupRadius
  );
}
function __mmCleanupSafeDistance(__mmObject) {
  return (
    (Number(v && v.scale) || 35) +
    __mmCleanupObjectScale(__mmObject) +
    (__mmCleanupIsSpike(__mmObject) ? 18 : 8)
  );
}
function __mmCleanupWeaponPlan(__mmObject) {
  if (!v || !v.alive || !Array.isArray(v.weapons)) return null;
  const __mmSafe = __mmCleanupSafeDistance(__mmObject),
    __mmScale = __mmCleanupObjectScale(__mmObject);
  let __mmBest = null;
  for (let __mmIndex = 0; __mmIndex < v.weapons.length; __mmIndex++) {
    const __mmWeapon = v.weapons[__mmIndex],
      __mmData = b && b.weapons && b.weapons[__mmWeapon];
    if (!__mmData || __mmData.projectile != null) continue;
    const __mmDamage = __mmWeaponStructureDamage(v, __mmWeapon, __mmObject),
      __mmRange = Number(__mmData.range) || 0,
      __mmReach = __mmRange + __mmScale - 5,
      __mmSpeed = Math.max(50, Number(__mmData.speed) || 400);
    // Cleanup needs a real standing attack band. A two-pixel band caused the
    // movement controller to cross it every update and reverse repeatedly.
    if (__mmDamage <= 0 || __mmReach < __mmSafe + 10) continue;
    const __mmScore = __mmDamage / __mmSpeed + __mmRange / 1e6;
    if (
      !__mmBest ||
      __mmScore > __mmBest.score ||
      (__mmScore === __mmBest.score && __mmReach > __mmBest.reach)
    )
      __mmBest = {
        weapon: __mmWeapon,
        damage: __mmDamage,
        speed: __mmSpeed,
        reach: __mmReach,
        safe: __mmSafe,
        score: __mmScore,
      };
  }
  return __mmBest;
}
function __mmCleanupHasRemaining() {
  const __mmObjects = __mmActiveObjectSnapshot().all;
  for (let __mmIndex = 0; __mmIndex < __mmObjects.length; __mmIndex++)
    if (__mmCleanupStructureAllowed(__mmObjects[__mmIndex])) return !0;
  return !1;
}
function __mmCleanupNearestTarget(__mmNow) {
  if (!v || !v.alive) return null;
  let __mmBest = null,
    __mmBestDistance = Infinity;
  const __mmObjects = __mmActiveObjectSnapshot().all;
  for (let __mmIndex = 0; __mmIndex < __mmObjects.length; __mmIndex++) {
    const __mmObject = __mmObjects[__mmIndex];
    if (!__mmCleanupStructureAllowed(__mmObject)) continue;
    const __mmReservedUntil = Number(__mmCleanupReservations.get(__mmObject));
    if (Number.isFinite(__mmReservedUntil) && __mmReservedUntil > __mmNow)
      continue;
    const __mmPlan = __mmCleanupWeaponPlan(__mmObject);
    if (!__mmPlan) {
      __mmCleanupReservations.set(__mmObject, __mmNow + 750);
      continue;
    }
    const __mmDistance = Math.hypot(
      Number(__mmObject.x) - Number(v.x),
      Number(__mmObject.y) - Number(v.y),
    );
    if (Number.isFinite(__mmDistance) && __mmDistance < __mmBestDistance)
      ((__mmBestDistance = __mmDistance),
        (__mmBest = { object: __mmObject, plan: __mmPlan }));
  }
  return __mmBest;
}
function __mmCleanupRestoreApproachGear() {
  if (__mmCleanupAttackHeld || __mmSecondaryHeld) return;
  __mmClearSecondaryGearTimer();
  if (__mmRightClickHat != null) {
    __mmForceRestoreRightClickHat();
    return;
  }
  // A Tank request can still be awaiting the next game-state update after the
  // synthetic hold has ended. Override that pending request before walking so
  // cleanup never approaches its next target at Tank speed.
  if (__mmPendingHat === 40 || (v && v.skinIndex === 40)) {
    const __mmHat =
      __mmLastNormalHat === 0 ||
      (v && v.skins && v.skins[__mmLastNormalHat])
        ? __mmLastNormalHat
        : v && v.skins && v.skins[6]
          ? 6
          : 0;
    __mmEquipHatNow(__mmHat, !0);
  }
}
function __mmCleanupSetMovement(__mmAngle) {
  if (!v || !v.alive) {
    ((__mmCleanupMoveAngle = null), (Kt = null));
    return;
  }
  if (!Number.isFinite(__mmAngle)) {
    if (__mmCleanupMoveAngle == null) return;
    ((__mmCleanupMoveAngle = null), (Kt = null), O.send("9", null));
    return;
  }
  __mmCleanupRestoreApproachGear();
  const __mmFixed =
    typeof M.fixTo === "function" ? M.fixTo(__mmAngle, 2) : __mmAngle,
    __mmDifference =
      __mmCleanupMoveAngle == null
        ? Infinity
        : Math.abs(
            Math.atan2(
              Math.sin(__mmFixed - __mmCleanupMoveAngle),
              Math.cos(__mmFixed - __mmCleanupMoveAngle),
            ),
          );
  if (__mmDifference < 0.04) return;
  ((__mmCleanupMoveAngle = __mmFixed),
    (Kt = __mmFixed),
    O.send("9", __mmFixed));
}
function __mmCleanupReleaseAttack() {
  const __mmWasHeld = __mmCleanupAttackHeld,
    __mmMouseButton = __mmCleanupMouseButton;
  if (__mmWasHeld)
    O.send(
      "F",
      0,
      Number.isFinite(__mmCleanupAimAngle) ? __mmCleanupAimAngle : null,
    );
  U = 0;
  if (__mmMouseButton === 0) {
    ((__mmPrimaryHeld = !1),
      (__mmPrimaryAttackDown = !1),
      __mmRestoreBullForPrimary(),
      __mmRestoreHeldHat(),
      __mmRestoreHeldTail());
  } else if (__mmMouseButton === 2) {
    ((__mmSecondaryHeld = !1),
      (__mmSecondaryAttackDown = !1),
      __mmRestoreHeldHat(),
      __mmRestoreHeldTail(),
      __mmRestoreRightClickHat());
  }
  ((__mmCleanupAttackHeld = !1),
    (__mmCleanupMouseButton = null),
    (__mmCleanupAimAngle = null),
    (__mmCleanupWeapon = null));
}
function __mmCleanupMouseButtonForWeapon(__mmWeapon) {
  // Cleanup always behaves as a held right-click, even when its best breaker
  // is the primary weapon. This keeps cleanup on the Tank/Soldier gear path
  // and never borrows the normal left-click/Bull state.
  return 2;
}
function __mmCleanupUpdateSecondaryGear(__mmWeapon, __mmNow) {
  if (
    !__mmTankRightClickEnabled ||
    !v ||
    !v.alive ||
    !v.skins ||
    !v.skins[40]
  )
    return;
  __mmRightClickHat == null &&
    (__mmRightClickHat = __mmInstaSafeRestoreHat(
      __mmBushRestoreHat(v.skinIndex),
    ));
  __mmManualWeaponArming(__mmWeapon, __mmSecondaryManualReadyAt, __mmNow) &&
    __mmEquipTankForSecondary(__mmWeapon, __mmNow);
}
function __mmCleanupUpdateMouseGear(__mmPlan, __mmNow) {
  if (!__mmPlan || !__mmCleanupAttackHeld) return;
  if (__mmCleanupMouseButton === 0) {
    __mmBullPrimaryAvailable() && __mmPulsePrimaryBullWeapon();
    return;
  }
  __mmCleanupMouseButton === 2 &&
    __mmCleanupUpdateSecondaryGear(__mmPlan.weapon, __mmNow);
}
function __mmCleanupBeginMouseHold(__mmPlan, __mmAngle, __mmNow) {
  const __mmMouseButton = __mmCleanupMouseButtonForWeapon(__mmPlan.weapon);
  (__mmCleanupMouseButton = __mmMouseButton,
    (__mmCleanupWeapon = __mmPlan.weapon),
    (__mmCleanupAimAngle = __mmAngle),
    (U = 1),
    O.send("D", __mmAngle),
    je(__mmPlan.weapon, !0));
  if (__mmMouseButton === 0) {
    ((__mmPrimaryHeld = !0),
      (__mmPrimaryAttackDown = !1),
      Number(__mmPrimaryManualWeapon) !== Number(__mmPlan.weapon) &&
        ((__mmPrimaryManualWeapon = Number(__mmPlan.weapon)),
        (__mmPrimaryManualReadyAt = 0)),
      (__mmCleanupAttackHeld = !0),
      __mmPulseHeldAttack());
    return;
  }
  ((__mmSecondaryHeld = !0),
    (__mmSecondaryAttackDown = !0),
    Number(__mmSecondaryManualWeapon) !== Number(__mmPlan.weapon) &&
      ((__mmSecondaryManualWeapon = Number(__mmPlan.weapon)),
      (__mmSecondaryManualReadyAt = 0)),
    (__mmCleanupAttackHeld = !0),
    __mmCleanupUpdateSecondaryGear(__mmPlan.weapon, __mmNow),
    O.send("F", 1, __mmAngle));
}
function __mmCleanupSteeringAngle(__mmDesired, __mmTarget) {
  if (!v || !v.alive) return __mmDesired;
  const __mmOffsets = [0, 0.24, -0.24, 0.48, -0.48, 0.78, -0.78, 1.08, -1.08, 1.57, -1.57],
    __mmPlayerScale = Number(v.scale) || 35,
    __mmStep = 90,
    __mmObjects = __mmActiveObjectSnapshot().all;
  let __mmBestAngle = __mmDesired,
    __mmBestScore = Infinity;
  for (let __mmOffsetIndex = 0; __mmOffsetIndex < __mmOffsets.length; __mmOffsetIndex++) {
    const __mmAngle = __mmDesired + __mmOffsets[__mmOffsetIndex],
      __mmEndX = Number(v.x) + Math.cos(__mmAngle) * __mmStep,
      __mmEndY = Number(v.y) + Math.sin(__mmAngle) * __mmStep;
    let __mmScore = Math.abs(__mmOffsets[__mmOffsetIndex]) * 15;
    for (let __mmIndex = 0; __mmIndex < __mmObjects.length; __mmIndex++) {
      const __mmObject = __mmObjects[__mmIndex];
      if (
        !__mmObject ||
        __mmObject === __mmTarget ||
        !__mmObject.active
      )
        continue;
      const __mmClearance =
          __mmPlayerScale +
          __mmCleanupObjectScale(__mmObject) +
          (__mmCleanupIsSpike(__mmObject) ? 20 : 6),
        __mmDistanceSquared = __mmSegmentDistanceSquared(
          Number(v.x),
          Number(v.y),
          __mmEndX,
          __mmEndY,
          Number(__mmObject.x),
          Number(__mmObject.y),
        );
      if (__mmDistanceSquared < __mmClearance * __mmClearance) {
        const __mmDistance = Math.sqrt(Math.max(0, __mmDistanceSquared));
        __mmScore +=
          1e4 + (__mmClearance - __mmDistance) *
          (__mmCleanupIsSpike(__mmObject) ? 100 : 25);
      }
    }
    if (__mmScore < __mmBestScore)
      ((__mmBestScore = __mmScore), (__mmBestAngle = __mmAngle));
  }
  return __mmBestAngle;
}
function __mmCleanupVelocityToward(__mmObject) {
  if (!v || !__mmObject) return { closing: 0, speed: 0, x: 0, y: 0 };
  let __mmVelocity = __mmPassiveSpikeVelocity(),
    __mmVelocityX = Number(__mmVelocity && __mmVelocity.x) || 0,
    __mmVelocityY = Number(__mmVelocity && __mmVelocity.y) || 0;
  const __mmServerElapsed = Number(v.t2) - Number(v.t1),
    __mmServerVelocityX =
      (Number(v.x2) - Number(v.x1)) / __mmServerElapsed,
    __mmServerVelocityY =
      (Number(v.y2) - Number(v.y1)) / __mmServerElapsed,
    __mmTrackedSpeed = Math.hypot(__mmVelocityX, __mmVelocityY),
    __mmServerSpeed = Math.hypot(__mmServerVelocityX, __mmServerVelocityY);
  if (
    Number.isFinite(__mmServerVelocityX) &&
    Number.isFinite(__mmServerVelocityY) &&
    __mmServerElapsed > 0 &&
    __mmServerElapsed <= 500 &&
    __mmServerSpeed > __mmTrackedSpeed
  )
    ((__mmVelocityX = __mmServerVelocityX),
      (__mmVelocityY = __mmServerVelocityY));
  const __mmDx = Number(__mmObject.x) - Number(v.x),
    __mmDy = Number(__mmObject.y) - Number(v.y),
    __mmDistance = Math.hypot(__mmDx, __mmDy),
    __mmClosing = __mmDistance > 0
      ? (__mmVelocityX * __mmDx + __mmVelocityY * __mmDy) / __mmDistance
      : 0;
  return {
    closing: Number.isFinite(__mmClosing) ? __mmClosing : 0,
    speed: Math.hypot(__mmVelocityX, __mmVelocityY),
    x: __mmVelocityX,
    y: __mmVelocityY,
  };
}
function __mmCleanupProjectedDistance(__mmObject, __mmMotion) {
  if (!v || !__mmObject || !__mmMotion) return Infinity;
  const __mmPing = Number(window.pingTime),
    __mmLeadMs =
      __mmServerTickMs() +
      (Number.isFinite(__mmPing) ? Math.min(100, Math.max(0, __mmPing / 2)) : 0),
    __mmPredictedX = Number(v.x) + __mmMotion.x * __mmLeadMs,
    __mmPredictedY = Number(v.y) + __mmMotion.y * __mmLeadMs;
  return Math.hypot(
    Number(__mmObject.x) - __mmPredictedX,
    Number(__mmObject.y) - __mmPredictedY,
  );
}
function __mmCleanupAttackTarget(
  __mmEntry,
  __mmAngle,
  __mmNow,
  __mmBrakeAngle = null,
) {
  const __mmObject = __mmEntry.object,
    __mmPlan = __mmEntry.plan,
    __mmState = __mmBreakableState(__mmObject),
    __mmData = b && b.list && b.list[__mmObject.id],
    __mmLiveHealth = Number(__mmObject.health),
    __mmHealth = __mmState
      ? Number(__mmState.health)
      : Number.isFinite(__mmLiveHealth)
        ? __mmLiveHealth
        : Number(__mmData && __mmData.health) || 1;
  const __mmMultiBreak = __mmMultiBreakAimPlan(
    __mmPlan.weapon,
    __mmAngle,
    __mmObject,
  );
  __mmMultiBreak && (__mmAngle = __mmMultiBreak.angle);
  __mmCleanupSetMovement(__mmBrakeAngle);
  __mmCleanupAimAngle = __mmAngle;
  if (
    __mmCleanupWeapon !== __mmPlan.weapon ||
    __mmCleanupMouseButton !== __mmCleanupMouseButtonForWeapon(__mmPlan.weapon)
  )
    __mmCleanupReleaseAttack();
  if (!__mmCleanupAttackHeld)
    __mmCleanupBeginMouseHold(__mmPlan, __mmAngle, __mmNow);
  else
    (O.send("D", __mmAngle), __mmCleanupUpdateMouseGear(__mmPlan, __mmNow));
  if (
    __mmCleanupTargetHealth == null ||
    __mmHealth < __mmCleanupTargetHealth - 0.001
  )
    ((__mmCleanupTargetHealth = __mmHealth),
      (__mmCleanupProgressAt = __mmNow));
  const __mmStallMs = Math.max(
    2200,
    __mmPlan.speed *
      (Math.max(1, Math.ceil(__mmHealth / Math.max(1, __mmPlan.damage))) + 2) +
      __mmServerTickMs() * 2,
  );
  if (__mmNow - __mmCleanupProgressAt > __mmStallMs) {
    (__mmCleanupReleaseAttack(),
      __mmCleanupReservations.set(__mmObject, __mmNow + 900),
      (__mmCleanupTarget = null),
      (__mmCleanupApproachStopped = !1),
      (__mmCleanupTargetHealth = null));
  }
}
function __mmUpdateCleanup() {
  if (!__mmCleanupActive) return;
  if (document.hidden || !v || !v.alive)
    return void __mmStopCleanup("runtime unavailable", !1);
  if (__mmActionOwner !== "cleanup")
    return void __mmStopCleanup("action ownership lost", !1);
  const __mmNow = Date.now();
  let __mmEntry = __mmCleanupTarget;
  if (!__mmEntry || !__mmCleanupStructureAllowed(__mmEntry.object)) {
    (__mmCleanupReleaseAttack(),
      (__mmCleanupTarget = null),
      (__mmCleanupApproachStopped = !1),
      (__mmCleanupTargetHealth = null),
      (__mmEntry = __mmCleanupNearestTarget(__mmNow)));
    if (__mmEntry) {
      ((__mmCleanupTarget = __mmEntry),
        (__mmCleanupApproachStopped = !1),
        (__mmCleanupTargetHealth = null),
        (__mmCleanupProgressAt = __mmNow),
        (__mmCleanupEmptySince = 0));
    }
  }
  if (!__mmEntry) {
    ((__mmCleanupApproachStopped = !1),
      __mmCleanupSetMovement(null),
      __mmCleanupReleaseAttack());
    if (__mmCleanupHasRemaining()) {
      __mmCleanupEmptySince = 0;
      return;
    }
    __mmCleanupEmptySince || (__mmCleanupEmptySince = __mmNow);
    if (__mmNow - __mmCleanupEmptySince >= Math.max(650, Number(y && y.chatCooldown) + 100 || 650))
      __mmStopCleanup("radius complete", !0);
    return;
  }
  if (
    __mmCleanupAttackHeld &&
    ((__mmCleanupMouseButton === 0 && !__mmPrimaryHeld) ||
      (__mmCleanupMouseButton === 2 && !__mmSecondaryHeld))
  )
    __mmCleanupReleaseAttack();
  const __mmObject = __mmEntry.object,
    __mmDx = Number(__mmObject.x) - Number(v.x),
    __mmDy = Number(__mmObject.y) - Number(v.y),
    __mmDistance = Math.hypot(__mmDx, __mmDy),
    __mmAngle = Math.atan2(__mmDy, __mmDx),
    __mmSafe = __mmEntry.plan.safe,
    __mmReach = __mmEntry.plan.reach,
    __mmMotion = __mmCleanupVelocityToward(__mmObject),
    __mmProjectedDistance = __mmCleanupProjectedDistance(
      __mmObject,
      __mmMotion,
    ),
    __mmEdgeDistance = __mmSafe + 3,
    __mmStopDistance = Math.min(__mmReach - 5, __mmEdgeDistance + 5),
    __mmResumeDistance = Math.min(__mmReach - 2, __mmStopDistance + 18),
    __mmNeedsBrake =
      __mmMotion.closing > 0.015 &&
      __mmProjectedDistance < __mmEdgeDistance;
  if (!Number.isFinite(__mmDistance)) {
    ((__mmCleanupTarget = null), (__mmCleanupApproachStopped = !1));
    return;
  }
  // Once the hold begins, target validity—not interpolation around the
  // collision edge—owns attack-up. Even if residual movement carries the
  // player slightly inside the edge, keep swinging and brake outward without
  // breaking the continuous hit cycle.
  if (__mmCleanupAttackHeld && __mmDistance <= __mmReach)
    return void __mmCleanupAttackTarget(
      __mmEntry,
      __mmAngle,
      __mmNow,
      __mmNeedsBrake
        ? __mmCleanupSteeringAngle(__mmAngle + Math.PI, __mmObject)
        : null,
    );
  if (__mmNeedsBrake) {
    __mmCleanupApproachStopped = !0;
    if (__mmDistance <= __mmReach)
      return void __mmCleanupAttackTarget(
        __mmEntry,
        __mmAngle,
        __mmNow,
        __mmCleanupSteeringAngle(__mmAngle + Math.PI, __mmObject),
      );
    __mmCleanupReleaseAttack();
    __mmCleanupSetMovement(
      __mmCleanupSteeringAngle(__mmAngle + Math.PI, __mmObject),
    );
    return;
  }
  if (
    __mmProjectedDistance <= __mmStopDistance ||
    (__mmCleanupApproachStopped && __mmDistance <= __mmResumeDistance)
  ) {
    (__mmCleanupApproachStopped = !0), __mmCleanupSetMovement(null);
    if (__mmDistance <= __mmReach)
      return void __mmCleanupAttackTarget(__mmEntry, __mmAngle, __mmNow);
    return;
  }
  __mmCleanupApproachStopped = !1;
  __mmCleanupReleaseAttack();
  __mmCleanupSetMovement(__mmCleanupSteeringAngle(__mmAngle, __mmObject));
}
function __mmCleanupProgressChat() {
  if (!__mmCleanupActive || !__mmCleanupProgressChatEnabled) return;
  // Non-breaking spaces survive chat normalization and keep every animation
  // frame exactly as wide as the three-dot version.
  const __mmLines = [
    "Cleaning.\u00a0\u00a0",
    "Cleaning..\u00a0",
    "Cleaning...",
  ];
  (__mmSendChat(__mmLines[__mmCleanupChatStep % __mmLines.length]),
    (__mmCleanupChatStep += 1));
}
function __mmStartCleanup() {
  if (__mmCleanupActive || document.hidden || !v || !v.alive) return !1;
  (__mmActionOwner === "weaponRecharge" && __mmPauseWeaponRecharge(!0),
    __mmActionOwner === "matThief" && __mmFinishMatThief("cleanup started"),
    __mmActionOwner === "mobSteal" && __mmFinishMobSteal("cleanup started"));
  if (!__mmActionClaim("cleanup", "clearing 1000px radius")) return !1;
  (__mmRestoreMovementGear(),
    (__mmCleanupActive = !0),
    (__mmCleanupOriginX = Number(v.x) || 0),
    (__mmCleanupOriginY = Number(v.y) || 0),
    (__mmCleanupTarget = null),
    (__mmCleanupSavedTool = __mmSelectedTool()),
    (__mmCleanupWeapon = null),
    (__mmCleanupAttackHeld = !1),
    (__mmCleanupMouseButton = null),
    (__mmCleanupAimAngle = null),
    (__mmCleanupMoveAngle = null),
    (__mmCleanupApproachStopped = !1),
    (__mmCleanupTargetHealth = null),
    (__mmCleanupProgressAt = Date.now()),
    (__mmCleanupEmptySince = 0),
    (__mmCleanupChatStep = 0),
    __mmCleanupProgressChat(),
    (__mmCleanupProgressTimer = setInterval(
      __mmCleanupProgressChat,
      Math.max(750, (Number(y && y.chatCooldown) || 500) + 150),
    )),
    __mmEnsureOperationPipeline(),
    __mmUpdateCleanup());
  return !0;
}
function __mmStopCleanup(__mmReason, __mmCompleted) {
  if (!__mmCleanupActive && __mmActionOwner !== "cleanup") return;
  const __mmTool = __mmCleanupSavedTool,
    __mmCanRestore = __mmActionMayRestore("cleanup");
  ((__mmCleanupActive = !1),
    __mmCleanupTimer && clearInterval(__mmCleanupTimer),
    (__mmCleanupTimer = 0),
    __mmCleanupProgressTimer && clearInterval(__mmCleanupProgressTimer),
    (__mmCleanupProgressTimer = 0),
    __mmCleanupSetMovement(null),
    __mmCleanupReleaseAttack(),
    (__mmCleanupTarget = null),
    (__mmCleanupSavedTool = null),
    (__mmCleanupWeapon = null),
    (__mmCleanupAimAngle = null),
    (__mmCleanupApproachStopped = !1),
    (__mmCleanupTargetHealth = null),
    (__mmCleanupEmptySince = 0),
    __mmCanRestore && __mmRestoreTool(__mmTool),
    __mmActionRelease("cleanup", __mmReason || "stopped"),
    __mmScheduleMouseAimReturn(),
    __mmCompleted &&
      __mmCleanupCompleteChatEnabled &&
      __mmSendChat("Nice and tidy!"));
}
function __mmToggleCleanup() {
  return __mmCleanupActive
    ? (__mmStopCleanup("C toggled off", !1), !1)
    : __mmStartCleanup();
}
function __mmCleanupInputKey(__mmKey) {
  if ([87, 65, 83, 68].includes(Number(__mmKey))) {
    __mmVelTickManualUntil = Date.now() + 500;
    __mmAutoPushManualUntil = Date.now() + 500;
    __mmStopVelTickInsta("manual movement");
    __mmStopAutoPushSetup("manual movement");
  }
  __mmCleanupActive &&
    __mmCleanupInputKeys[Number(__mmKey)] &&
    __mmStopCleanup("manual key", !1);
}
document.addEventListener(
  "mousedown",
  function (__mmEvent) {
    if (__mmEvent.isTrusted) {
      __mmVelTickManualUntil = Date.now() + 500;
      __mmAutoPushManualUntil = Date.now() + 500;
      __mmStopVelTickInsta("manual click");
      __mmStopAutoPushSetup("manual click");
    }
    __mmCleanupActive &&
      __mmEvent.isTrusted &&
      __mmStopCleanup("manual click", !1);
  },
  !0,
);
function __mmWeaponGrindResetPlacements() {
  ((__mmWeaponGrindPlaced.turret = 0),
    (__mmWeaponGrindPlaced.teleporter = 0),
    (__mmWeaponGrindSlots.turret.length = 0),
    (__mmWeaponGrindSlots.teleporter.length = 0),
    (__mmWeaponGrindReservations.length = 0),
    (__mmWeaponGrindTargetIndex = 0),
    (__mmWeaponGrindNextAimAt = 0),
    (__mmWeaponGrindLastPlaceAt = 0));
}
function __mmWeaponGrindItem(__mmKind) {
  if (!v || !v.items || !b || !b.list) return null;
  for (let __mmIndex = 0; __mmIndex < v.items.length; __mmIndex++) {
    const __mmItem = v.items[__mmIndex],
      __mmData = b.list[__mmItem];
    if (
      __mmData &&
      String(__mmData.name || "").trim().toLowerCase() === __mmKind
    )
      return __mmItem;
  }
  return null;
}
function __mmWeaponGrindCleanReservations(__mmNow) {
  for (
    let __mmIndex = __mmWeaponGrindReservations.length - 1;
    __mmIndex >= 0;
    __mmIndex--
  )
    __mmWeaponGrindReservations[__mmIndex].expiresAt <= __mmNow &&
      __mmWeaponGrindReservations.splice(__mmIndex, 1);
}
function __mmWeaponGrindObjectOwned(__mmObject) {
  if (!v || !__mmObject || !__mmObject.owner) return !1;
  return !!(
    __mmObject.owner === v ||
    (__mmObject.owner.sid != null &&
      String(__mmObject.owner.sid) === String(v.sid))
  );
}
function __mmWeaponGrindObjectMatches(
  __mmObject,
  __mmSlot,
  __mmKind,
) {
  if (
    !__mmObject ||
    !__mmObject.active ||
    !__mmObject.isItem ||
    !__mmWeaponGrindObjectOwned(__mmObject)
  )
    return !1;
  const __mmData = b && b.list && b.list[__mmObject.id];
  if (
    !__mmData ||
    String(__mmData.name || "").trim().toLowerCase() !== __mmKind
  )
    return !1;
  const __mmTolerance = Math.max(14, Number(__mmSlot.scale) * 0.35);
  return (
    (Number(__mmObject.x) - Number(__mmSlot.x)) ** 2 +
      (Number(__mmObject.y) - Number(__mmSlot.y)) ** 2 <=
    __mmTolerance * __mmTolerance
  );
}
function __mmWeaponGrindRefreshSlots(__mmNow) {
  const __mmClaimed = new Set(),
    __mmKinds = ["turret", "teleporter"],
    __mmConfirmTimeout = Math.max(1400, __mmServerTickMs() * 5),
    __mmObjects = __mmActiveObjectSnapshot().all;
  for (let __mmKindIndex = 0; __mmKindIndex < __mmKinds.length; __mmKindIndex++) {
    const __mmKind = __mmKinds[__mmKindIndex],
      __mmSlots = __mmWeaponGrindSlots[__mmKind];
    for (let __mmSlotIndex = __mmSlots.length - 1; __mmSlotIndex >= 0; __mmSlotIndex--) {
      const __mmSlot = __mmSlots[__mmSlotIndex];
      if (
        __mmSlot.object &&
        !__mmClaimed.has(__mmSlot.object) &&
        __mmWeaponGrindObjectMatches(__mmSlot.object, __mmSlot, __mmKind)
      ) {
        (__mmClaimed.add(__mmSlot.object), (__mmSlot.confirmed = !0));
        continue;
      }
      __mmSlot.object = null;
      for (let __mmObjectIndex = 0; __mmObjectIndex < __mmObjects.length; __mmObjectIndex++) {
        const __mmObject = __mmObjects[__mmObjectIndex];
        if (
          __mmClaimed.has(__mmObject) ||
          !__mmWeaponGrindObjectMatches(__mmObject, __mmSlot, __mmKind)
        )
          continue;
        ((__mmSlot.object = __mmObject),
          (__mmSlot.confirmed = !0),
          __mmClaimed.add(__mmObject));
        break;
      }
      if (
        !__mmSlot.object &&
        (__mmSlot.confirmed || __mmNow - __mmSlot.sentAt > __mmConfirmTimeout)
      ) {
        for (
          let __mmReservationIndex = __mmWeaponGrindReservations.length - 1;
          __mmReservationIndex >= 0;
          __mmReservationIndex--
        )
          __mmWeaponGrindReservations[__mmReservationIndex].slot === __mmSlot &&
            __mmWeaponGrindReservations.splice(__mmReservationIndex, 1);
        __mmSlots.splice(__mmSlotIndex, 1);
      }
    }
    __mmWeaponGrindPlaced[__mmKind] = __mmSlots.length;
  }
}
function __mmWeaponGrindCapacity(__mmItem) {
  const __mmData = b && b.list && b.list[__mmItem];
  if (
    __mmItem == null ||
    !__mmData ||
    !__mmData.group ||
    !__mmCanUseBuildItem(__mmItem)
  )
    return 0;
  const __mmLimit = __mmBuildGroupLimit(__mmData),
    __mmPlaced = Number(v.itemCounts && v.itemCounts[__mmData.group.id]) || 0,
    __mmReserved = __mmWeaponGrindReservations.reduce(function (
      __mmCount,
      __mmEntry,
    ) {
      return __mmCount +
        (__mmEntry.groupId === __mmData.group.id &&
        __mmPlaced <= __mmEntry.placedAtSend
          ? 1
          : 0);
    }, 0),
    __mmSlots = __mmLimit
      ? Math.max(0, __mmLimit - __mmPlaced - __mmReserved)
      : __mmMaxBuildCount(__mmItem);
  return Math.max(0, Math.min(__mmMaxBuildCount(__mmItem), __mmSlots));
}
function __mmWeaponGrindPositionClear(__mmX, __mmY, __mmScale) {
  if (
    !v ||
    __mmX - __mmScale < 0 ||
    __mmY - __mmScale < 0 ||
    __mmX + __mmScale > y.mapScale ||
    __mmY + __mmScale > y.mapScale ||
    (__mmY >= y.mapScale / 2 - y.riverWidth / 2 &&
      __mmY <= y.mapScale / 2 + y.riverWidth / 2)
  )
    return !1;
  const __mmObjects = __mmActiveObjectSnapshot().all;
  for (let __mmIndex = 0; __mmIndex < __mmObjects.length; __mmIndex++) {
    const __mmObject = __mmObjects[__mmIndex];
    if (!__mmObject || !__mmObject.active) continue;
    const __mmMinimum =
      __mmScale + __mmCleanupObjectScale(__mmObject) + 3;
    if (
      (Number(__mmObject.x) - __mmX) ** 2 +
        (Number(__mmObject.y) - __mmY) ** 2 <
      __mmMinimum * __mmMinimum
    )
      return !1;
  }
  for (
    let __mmIndex = 0;
    __mmIndex < __mmWeaponGrindReservations.length;
    __mmIndex++
  ) {
    const __mmEntry = __mmWeaponGrindReservations[__mmIndex],
      __mmMinimum = __mmScale + __mmEntry.scale + 3;
    if (
      (__mmEntry.x - __mmX) ** 2 + (__mmEntry.y - __mmY) ** 2 <
      __mmMinimum * __mmMinimum
    )
      return !1;
  }
  return !0;
}
function __mmWeaponGrindPlacement(__mmKind, __mmItem) {
  if (!v || !v.alive) return null;
  const __mmData = b && b.list && b.list[__mmItem];
  if (!__mmData) return null;
  const __mmScale = Number(__mmData.scale) || 45,
    __mmDistance =
      (Number(v.scale) || 35) +
      __mmScale +
      (Number(__mmData.placeOffset) || 0),
    __mmBase = Number.isFinite(__mmWeaponGrindLayoutAngle)
      ? __mmWeaponGrindLayoutAngle
      : __mmRawMouseAimDirection(),
    __mmOrdinal = __mmWeaponGrindPlaced[__mmKind],
    __mmPreferred =
      __mmKind === "turret"
        ? __mmBase + (__mmOrdinal ? 0.82 : -0.82)
        : __mmBase + Math.PI + (__mmOrdinal ? 0.82 : -0.82),
    __mmStep = Math.PI / 24;
  for (let __mmOffset = 0; __mmOffset < 48; __mmOffset++) {
    const __mmRing = Math.ceil(__mmOffset / 2),
      __mmSign = __mmOffset === 0 || __mmOffset % 2 ? 1 : -1,
      __mmAngle = __mmPreferred + __mmRing * __mmStep * __mmSign,
      __mmX = Number(v.x) + Math.cos(__mmAngle) * __mmDistance,
      __mmY = Number(v.y) + Math.sin(__mmAngle) * __mmDistance;
    if (__mmWeaponGrindPositionClear(__mmX, __mmY, __mmScale))
      return {
        item: __mmItem,
        kind: __mmKind,
        angle: __mmAngle,
        x: __mmX,
        y: __mmY,
        scale: __mmScale,
        groupId: __mmData.group && __mmData.group.id,
      };
  }
  return null;
}
function __mmWeaponGrindReleaseHold() {
  if (!__mmWeaponGrindHold) return;
  (O.send(
    "F",
    0,
    Number.isFinite(__mmWeaponGrindAimAngle) ? __mmWeaponGrindAimAngle : null,
  ),
    (U = 0),
    (__mmSecondaryHeld = !1),
    (__mmSecondaryAttackDown = !1),
    (__mmWeaponGrindHold = !1),
    __mmStopHeldAttackPulse(),
    __mmRestoreHeldHat(),
    __mmRestoreHeldTail(),
    __mmRestoreRightClickHat());
}
function __mmWeaponGrindUpdateAim(__mmNow, __mmForce) {
  if (
    !v ||
    !v.alive ||
    (!__mmForce && __mmNow < __mmWeaponGrindNextAimAt)
  )
    return !1;
  const __mmTargets = __mmWeaponGrindSlots.turret
    .concat(__mmWeaponGrindSlots.teleporter)
    .filter(function (__mmSlot) {
      return !!(__mmSlot && __mmSlot.confirmed && __mmSlot.object);
    });
  let __mmAngle = Number.isFinite(__mmWeaponGrindLayoutAngle)
    ? __mmWeaponGrindLayoutAngle
    : __mmRawMouseAimDirection();
  if (__mmTargets.length) {
    const __mmTarget =
      __mmTargets[__mmWeaponGrindTargetIndex++ % __mmTargets.length];
    __mmAngle = Math.atan2(
      Number(__mmTarget.y) - Number(v.y),
      Number(__mmTarget.x) - Number(v.x),
    );
  }
  const __mmSwingMs = __mmManualWeaponCooldown(
    __mmWeaponGrindWeapon,
    __mmTankRightClickEnabled && v.skins && v.skins[40] ? 40 : null,
  );
  ((__mmWeaponGrindAimAngle = __mmAngle),
    (__mmWeaponGrindNextAimAt =
      __mmNow + Math.max(__mmServerTickMs(), Number(__mmSwingMs) || 0)));
  __mmWeaponGrindHold && O.send("D", __mmAngle);
  return !0;
}
function __mmWeaponGrindBeginHold(__mmNow) {
  if (
    __mmWeaponGrindHold ||
    !v ||
    !v.alive ||
    !v.weapons ||
    !v.weapons.includes(__mmWeaponGrindWeapon)
  )
    return !1;
  (Number.isFinite(__mmWeaponGrindLayoutAngle) ||
      (__mmWeaponGrindLayoutAngle = __mmRawMouseAimDirection()),
    __mmWeaponGrindUpdateAim(__mmNow, !0),
    (U = 1),
    (__mmSecondaryHeld = !0),
    (__mmSecondaryAttackDown = !0),
    je(__mmWeaponGrindWeapon, !0),
    __mmCleanupUpdateSecondaryGear(__mmWeaponGrindWeapon, __mmNow),
    O.send("D", __mmWeaponGrindAimAngle),
    O.send("F", 1, __mmWeaponGrindAimAngle),
    (__mmWeaponGrindHold = !0));
  return !0;
}
function __mmWeaponGrindPlaceOne(__mmNow) {
  const __mmKinds = ["turret", "teleporter"];
  for (let __mmIndex = 0; __mmIndex < __mmKinds.length; __mmIndex++) {
    const __mmKind = __mmKinds[__mmIndex];
    if (__mmWeaponGrindPlaced[__mmKind] >= 2) continue;
    const __mmItem = __mmWeaponGrindItem(__mmKind);
    if (__mmItem == null || __mmWeaponGrindCapacity(__mmItem) < 1) continue;
    const __mmPlacement = __mmWeaponGrindPlacement(__mmKind, __mmItem);
    if (!__mmPlacement) continue;
    const __mmSlot = {
      x: __mmPlacement.x,
      y: __mmPlacement.y,
      scale: __mmPlacement.scale,
      groupId: __mmPlacement.groupId,
      item: __mmPlacement.item,
      sentAt: __mmNow,
      confirmed: !1,
      object: null,
    };
    (__mmWeaponGrindReleaseHold(),
      (__mmWeaponGrindAimAngle = __mmPlacement.angle));
    if (
      !__mmSendAutomaticPlacement(
        __mmPlacement.item,
        __mmPlacement.angle,
        { item: __mmWeaponGrindWeapon, weapon: !0 },
      )
    )
      continue;
    (
      __mmWeaponGrindSlots[__mmKind].push(__mmSlot),
      (__mmWeaponGrindPlaced[__mmKind] =
        __mmWeaponGrindSlots[__mmKind].length),
      (__mmWeaponGrindLastPlaceAt = __mmNow),
      __mmWeaponGrindReservations.push({
        slot: __mmSlot,
        x: __mmPlacement.x,
        y: __mmPlacement.y,
        scale: __mmPlacement.scale,
        groupId: __mmPlacement.groupId,
        placedAtSend:
          Number(
            v.itemCounts && v.itemCounts[__mmPlacement.groupId],
          ) || 0,
        expiresAt: __mmNow + 1200,
      }),
      __mmScheduleMouseAimReturn());
    return !0;
  }
  return !1;
}
function __mmPauseWeaponGrind(__mmReason) {
  (__mmWeaponGrindReleaseHold(),
    __mmActionRelease("weaponGrind", __mmReason || "paused"));
}
function __mmUpdateWeaponGrind() {
  if (!__mmWeaponGrindEnabled)
    return void __mmStopWeaponGrind("disabled");
  if (document.hidden || !v || !v.alive || !Array.isArray(v.weapons)) {
    (__mmPauseWeaponGrind("runtime unavailable"),
      (__mmWeaponGrindWeapon = null),
      (__mmWeaponGrindLifeSid = null),
      __mmWeaponGrindResetPlacements());
    return;
  }
  const __mmLifeSid = String(v.sid);
  if (__mmWeaponGrindLifeSid !== __mmLifeSid) {
    ((__mmWeaponGrindLifeSid = __mmLifeSid),
      (__mmWeaponGrindWeapon = null),
      (__mmWeaponGrindLayoutAngle = __mmRawMouseAimDirection()),
      (__mmWeaponGrindAimAngle = __mmWeaponGrindLayoutAngle),
      __mmWeaponGrindResetPlacements());
  }
  if (!__mmActionAvailable("weaponGrind")) {
    __mmWeaponGrindReleaseHold();
    return;
  }
  // Any outside input path that emitted attack-up must invalidate our local
  // latch too; otherwise the mode would think it was still holding while the
  // server had already stopped the weapon.
  __mmWeaponGrindHold &&
    !__mmSecondaryHeld &&
    __mmWeaponGrindReleaseHold();
  if (!__mmWeaponGrindHold) {
    const __mmSelected = __mmSelectedWeapon();
    v.weapons.includes(__mmSelected) && (__mmWeaponGrindWeapon = __mmSelected);
  }
  if (
    __mmWeaponGrindWeapon == null ||
    !v.weapons.includes(__mmWeaponGrindWeapon) ||
    !__mmActionClaim("weaponGrind", "right-hold weapon grind")
  )
    return;
  const __mmNow = Date.now();
  __mmWeaponGrindCleanReservations(__mmNow);
  __mmWeaponGrindRefreshSlots(__mmNow);
  if (
    __mmNow - __mmWeaponGrindLastPlaceAt >= __mmServerTickMs() &&
    __mmWeaponGrindPlaceOne(__mmNow)
  )
    return;
  if (!__mmWeaponGrindHold) __mmWeaponGrindBeginHold(__mmNow);
  else {
    (U = 1,
      __mmSecondaryHeld || (__mmSecondaryHeld = !0),
      __mmWeaponGrindUpdateAim(__mmNow, !1),
      __mmCleanupUpdateSecondaryGear(__mmWeaponGrindWeapon, __mmNow));
  }
}
function __mmStartWeaponGrind() {
  if (!__mmWeaponGrindEnabled) return;
  ((__mmWeaponGrindLayoutAngle = __mmRawMouseAimDirection()),
    (__mmWeaponGrindAimAngle = __mmWeaponGrindLayoutAngle),
    __mmWeaponGrindResetPlacements(),
    __mmEnsureOperationPipeline());
}
function __mmStopWeaponGrind(__mmReason) {
  (__mmWeaponGrindTimer && clearInterval(__mmWeaponGrindTimer),
    (__mmWeaponGrindTimer = 0),
    __mmPauseWeaponGrind(__mmReason || "stopped"),
    (__mmWeaponGrindWeapon = null),
    (__mmWeaponGrindLayoutAngle = null),
    (__mmWeaponGrindAimAngle = null),
    (__mmWeaponGrindLifeSid = null),
    __mmWeaponGrindResetPlacements(),
    __mmScheduleMouseAimReturn());
}
function __mmDisableWeaponGrind(__mmReason) {
  if (!__mmWeaponGrindEnabled) return;
  ((__mmWeaponGrindEnabled = !1),
    __mmStopWeaponGrind(__mmReason || "disabled"),
    __mmPublishHudState());
}
document.addEventListener(
  "mousedown",
  function (__mmEvent) {
    __mmWeaponGrindEnabled &&
      __mmEvent.isTrusted &&
      __mmIsGameClick(__mmEvent) &&
      __mmDisableWeaponGrind("manual click");
  },
  !0,
);
function __mmWeaponIsReloading(__mmWeapon) {
  if (
    !v ||
    !v.alive ||
    !v.weapons ||
    __mmWeapon == null ||
    !v.weapons.includes(__mmWeapon)
  )
    return !1;
  const __mmNow = Date.now(),
    __mmState = __mmAdvancePlayerToolCooldowns(v, __mmNow),
    __mmReconciled = __mmReconcileLocalToolCooldown(
      v,
      __mmWeapon,
      __mmNow,
      __mmState,
    ),
    __mmTracked = __mmReconciled.entry,
    __mmTrackedRemaining = Math.max(
      0,
      Number(__mmTracked && __mmTracked.remaining) || 0,
    );
  return (
    __mmTrackedRemaining > 0 ||
    (__mmReconciled.hasLive && Number(__mmReconciled.live) > 0)
  );
}
function __mmMusketIsReloading() {
  return __mmWeaponIsReloading(__mmMusket);
}
function __mmTurretGearIsReloading() {
  return !!(
    v &&
    v.alive &&
    __mmTurretCooldownRemaining(v, Date.now()) > 0
  );
}
function __mmAssumeTurretGearShot() {
  // Turret Gear has no exposed reload entry. Reserve its cooldown as soon as
  // Kitty emits the firing gear phase instead of waiting for a server attack
  // acknowledgement; this prevents another automation from immediately
  // launching a second, empty Insta attempt.
  if (!v || !v.alive || !v.skins || !v.skins[__mmTurretGear]) return !1;
  __mmTrackPlayerTurretCooldown(v.sid, "assumed");
  return !0;
}
function __mmTrackTurretGearReload(__mmPlayerSid) {
  let __mmPlayer = null;
  try {
    __mmPlayer = Rt(__mmPlayerSid);
  } catch (__mmTurretAttackLookupError) {}
  if (
    !__mmPlayer &&
    v &&
    String(__mmPlayerSid) === String(v.sid)
  )
    __mmPlayer = v;
  if (!__mmPlayer || Number(__mmPlayer.skinIndex) !== __mmTurretGear) return;
  __mmTrackPlayerTurretCooldown(__mmPlayerSid, "attack");
}
function __mmWeaponRechargeOverridden() {
  return (
    !v ||
    !v.alive ||
    __mmInsta.attackHeld ||
    __mmTrapAttackActive ||
    __mmBoostBreakHeld ||
    __mmBuildSpamTimer ||
    __mmFoodSpamTimer ||
    __mmAutoHealWasHealing ||
    __mmShieldDefenseTimer ||
    !__mmActionAvailable("weaponRecharge")
  );
}
function __mmNextWeaponToRecharge() {
  if (!v || !v.alive || !v.weapons) return null;
  const __mmSeen = new Set(),
    __mmHeldWeapon = __mmHeldAttackWeapon();
  let __mmHeldCooling = null;
  // Inventory order is main first, then secondary/any additional weapons.
  // A weapon under a native hold is already reloading. Let the off-hand borrow
  // that hold first so a continuously swinging main cannot starve it forever.
  for (let __mmIndex = 0; __mmIndex < v.weapons.length; __mmIndex++) {
    const __mmWeapon = v.weapons[__mmIndex];
    if (__mmWeapon == null || __mmSeen.has(__mmWeapon)) continue;
    __mmSeen.add(__mmWeapon);
    if (!__mmWeaponIsReloading(__mmWeapon)) continue;
    if (Number(__mmWeapon) === Number(__mmHeldWeapon)) {
      __mmHeldCooling = __mmWeapon;
      continue;
    }
    return __mmWeapon;
  }
  return __mmHeldCooling;
}
function __mmWeaponRechargeSelected(__mmWeapon) {
  if (!v || !v.alive) return !1;
  if (
    Date.now() - __mmLastSelectionAt <= 180 &&
    __mmLastSelectionWasWeapon &&
    Number(__mmLastSelectionItem) === Number(__mmWeapon)
  )
    return !0;
  return !!(
    Number(v.buildIndex) < 0 &&
    Number(v.weaponIndex) === Number(__mmWeapon)
  );
}
function __mmPreferWeaponRechargeRestore(__mmTool) {
  if (__mmWeaponRechargePreviousTool != null || __mmTool == null) return;
  if (typeof __mmTool === "object" && __mmTool.item != null)
    __mmWeaponRechargePreviousTool = {
      item: Number(__mmTool.item),
      weapon: !!__mmTool.weapon,
    };
  else if (
    v &&
    v.weapons &&
    v.weapons.includes(Number(__mmTool))
  )
    __mmWeaponRechargePreviousTool = {
      item: Number(__mmTool),
      weapon: !0,
    };
}
function __mmWeaponRechargeCurrentTool() {
  if (!v || !v.alive) return null;
  // Selection packets update Kitty's local selection immediately, while the
  // mirrored player fields can trail by a server tick. Insta restores the main
  // and calls this queue in that gap, so trust the just-issued selection first.
  if (Date.now() - __mmLastSelectionAt <= 150) {
    const __mmRecentItem = Number(__mmLastSelectionItem);
    if (
      __mmLastSelectionWasWeapon &&
      v.weapons &&
      v.weapons.includes(__mmRecentItem)
    )
      return { item: __mmRecentItem, weapon: !0 };
    if (
      !__mmLastSelectionWasWeapon &&
      v.items &&
      v.items.includes(__mmRecentItem)
    )
      return { item: __mmRecentItem, weapon: !1 };
  }
  const __mmBuild = Number(v.buildIndex);
  if (
    Number.isInteger(__mmBuild) &&
    __mmBuild >= 0 &&
    v.items &&
    v.items.includes(__mmBuild)
  )
    return { item: __mmBuild, weapon: !1 };
  const __mmWeapon = Number(v.weaponIndex);
  return v.weapons && v.weapons.includes(__mmWeapon)
    ? { item: __mmWeapon, weapon: !0 }
    : __mmSelectedTool();
}
function __mmSelectWeaponForRecharge(__mmWeapon) {
  if (__mmWeaponRechargeSelected(__mmWeapon)) return !0;
  const __mmNow = Date.now();
  if (__mmNow - __mmWeaponRechargeSelectAt >= 25) {
    ((__mmWeaponRechargeSelectAt = __mmNow), je(__mmWeapon, !0));
  }
  return __mmWeaponRechargeSelected(__mmWeapon);
}
function __mmSuspendHeldAttackForRecharge(__mmWeapon) {
  const __mmHeldWeapon = __mmHeldAttackWeapon();
  if (
    __mmHeldWeapon == null ||
    Number(__mmHeldWeapon) === Number(__mmWeapon)
  )
    return !1;
  if (!__mmWeaponRechargeHeldLoan)
    __mmWeaponRechargeHeldLoan = {
      weapon: Number(__mmHeldWeapon),
      primary: !!__mmPrimaryHeld,
      secondary: !!__mmSecondaryHeld,
      attackDown: !!(__mmPrimaryAttackDown || __mmSecondaryAttackDown),
    };
  if (__mmHeldAttackTimer)
    (clearInterval(__mmHeldAttackTimer), (__mmHeldAttackTimer = 0));
  if (__mmPrimaryAttackDown || __mmSecondaryAttackDown)
    __mmSendWeaponAttack(0);
  ((__mmPrimaryAttackDown = !1), (__mmSecondaryAttackDown = !1));
  return !0;
}
function __mmResumeHeldAttackAfterRecharge() {
  const __mmLoan = __mmWeaponRechargeHeldLoan;
  __mmWeaponRechargeHeldLoan = null;
  if (
    !__mmLoan ||
    !v ||
    !v.alive ||
    (!__mmPrimaryHeld && !__mmSecondaryHeld)
  )
    return !1;
  const __mmWeapon = __mmHeldAttackWeapon();
  if (__mmWeapon == null) return !1;
  // Another borrowed action may already have restored the native hold while
  // the reload worker was paused. In that case only retire our loan marker;
  // never emit a second F=1 that could reset timing or latch a fast click.
  if (__mmPrimaryAttackDown || __mmSecondaryAttackDown) {
    __mmHeldAttackTimer || __mmStartHeldAttackPulse();
    return !0;
  }
  ((__mmPrimaryAttackDown = !1),
    (__mmSecondaryAttackDown = !1),
    __mmStartHeldAttackPulse());
  return !0;
}
function __mmPrepareWeaponRechargeSelection(__mmWeapon) {
  const __mmHeldWeapon = __mmHeldAttackWeapon();
  if (
    __mmWeaponRechargeHeldLoan &&
    __mmHeldWeapon != null &&
    Number(__mmHeldWeapon) === Number(__mmWeapon)
  )
    __mmResumeHeldAttackAfterRecharge();
  else
    __mmSuspendHeldAttackForRecharge(__mmWeapon);
}
function __mmPauseWeaponRecharge(__mmRestore) {
  const __mmActive = __mmWeaponRechargeActiveWeapon,
    __mmPrevious = __mmWeaponRechargePreviousTool;
  (__mmRestore &&
    __mmActionMayRestore("weaponRecharge") &&
    __mmActive != null &&
    __mmPrevious != null &&
    __mmWeaponRechargeSelected(__mmActive) &&
    __mmRestoreTool(__mmPrevious),
    (__mmWeaponRechargeActiveWeapon = null),
    (__mmWeaponRechargeSelectAt = 0),
    __mmRestore && __mmResumeHeldAttackAfterRecharge(),
    __mmActionRelease("weaponRecharge", "reload paused"));
}
function __mmStopWeaponRecharge(__mmRestore) {
  const __mmRestoreTarget = __mmWeaponRechargePreviousTool;
  ((__mmWeaponRechargeActiveWeapon = null),
    (__mmWeaponRechargePreviousTool = null),
    (__mmWeaponRechargeSelectAt = 0),
    __mmRestore &&
      __mmRestoreTarget != null &&
      __mmActionMayRestore("weaponRecharge") &&
      __mmRestoreTool(__mmRestoreTarget),
    __mmResumeHeldAttackAfterRecharge(),
    __mmActionRelease("weaponRecharge", "reload queue complete"));
}
function __mmUpdateWeaponRecharge() {
  if (
    !__mmMusketRechargeEnabled ||
    __mmSyncFollowerEnabled ||
    !v ||
    !v.alive ||
    !v.weapons
  )
    return void __mmStopWeaponRecharge(!1);
  const __mmTarget = __mmNextWeaponToRecharge(),
    __mmActive = __mmWeaponRechargeActiveWeapon;
  // Higher-priority actions pause selection but retain the original tool and
  // cooldown queue. A normal held attack is handled as a resumable loan below,
  // so it no longer blocks the off-hand from reloading indefinitely.
  if (__mmWeaponRechargeOverridden()) {
    __mmActive != null && __mmPauseWeaponRecharge(!1);
    return;
  }
  if (__mmTarget == null) return void __mmStopWeaponRecharge(!0);
  if (__mmActive === __mmTarget) {
    __mmPrepareWeaponRechargeSelection(__mmTarget);
    __mmSelectWeaponForRecharge(__mmTarget);
    return;
  }
  // A newly cooling main preempts the secondary. A completed main advances to
  // the secondary immediately in this same scan without clearing queue state.
  if (__mmActive != null) {
    ((__mmWeaponRechargeActiveWeapon = __mmTarget),
      (__mmWeaponRechargeSelectAt = 0),
      __mmPrepareWeaponRechargeSelection(__mmTarget),
      __mmSelectWeaponForRecharge(__mmTarget));
    return;
  }
  if (!__mmActionClaim("weaponRecharge", "idle reload")) return;
  ((__mmWeaponRechargeActiveWeapon = __mmTarget),
    __mmWeaponRechargePreviousTool == null &&
      (__mmWeaponRechargePreviousTool = __mmWeaponRechargeCurrentTool()),
    (__mmWeaponRechargeSelectAt = 0),
    __mmPrepareWeaponRechargeSelection(__mmTarget),
    __mmSelectWeaponForRecharge(__mmTarget));
}
function __mmStartWeaponRecharge() {
  __mmEnsureOperationPipeline();
}
function __mmRestoreAutoHealWeapon() {
  // __mmUseFood restores the selected weapon after each safe food use. Keep
  // this cleanup hook for the HUD toggle and for older event paths.
  __mmAutoHealWeapon = null;
}
function __mmAutoHealFoodValue() {
  if (!v || v.items[0] == null) return 20;
  const __mmFood = b.list[v.items[0]];
  const __mmDescription = String((__mmFood && __mmFood.desc) || "");
  const __mmMatch = __mmDescription.match(/restores\\s+(\\d+)\\s+health/i);
  return __mmMatch ? Math.max(1, Number(__mmMatch[1])) : 20;
}
function __mmObserveAutoHealHealth(__mmHealth) {
  const __mmCurrentHealth = Number(__mmHealth);
  if (!Number.isFinite(__mmCurrentHealth)) return !1;
  const __mmNow = Date.now(),
    __mmHadHealth = __mmAutoHealLastObservedHealth != null,
    __mmTookDamage =
      __mmHadHealth &&
      __mmCurrentHealth < __mmAutoHealLastObservedHealth,
    __mmHealed =
      __mmHadHealth &&
      __mmCurrentHealth > __mmAutoHealLastObservedHealth;
  if (__mmTookDamage)
    ((__mmAutoHealPending = !0),
      (__mmAutoHealBitesRemaining = 0),
      (__mmAutoHealNextBiteAt = 0),
      (__mmAutoHealLastDamageAt = __mmNow));
  // Track manual healing too. Autoheal predicts its own result at send time
  // and clears LastDamageAt there, so its later health packet is not counted
  // twice. This mirrors the server's <=120ms increment / late-heal -2 rule.
  if (__mmHealed && __mmAutoHealLastDamageAt) {
    const __mmElapsed = __mmNow - __mmAutoHealLastDamageAt;
    ((__mmAutoHealShameCount =
      __mmElapsed <= 120
        ? Math.min(8, __mmAutoHealShameCount + 1)
        : Math.max(0, __mmAutoHealShameCount - 2)),
      (__mmAutoHealLastDamageAt = 0));
  }
  // Queue one catch-up heal if the script begins while already injured. Later
  // heals are queued only by actual damage packets, so the 10ms backup loop
  // cannot resend the same burst while the server is processing it.
  if (
    !__mmTookDamage &&
    __mmAutoHealLastObservedHealth == null &&
    v &&
    v.alive &&
    __mmCurrentHealth < v.maxHealth
  )
    ((__mmAutoHealPending = !0),
      (__mmAutoHealBitesRemaining = 0),
      (__mmAutoHealNextBiteAt = 0));
  __mmAutoHealLastObservedHealth = __mmCurrentHealth;
  return __mmTookDamage;
}
function __mmAutoHealRecordFoodAttempt(__mmNow) {
  if (!__mmAutoHealLastDamageAt) return;
  const __mmElapsed = __mmNow - __mmAutoHealLastDamageAt;
  ((__mmAutoHealShameCount =
    __mmElapsed <= 120
      ? Math.min(8, __mmAutoHealShameCount + 1)
      : Math.max(0, __mmAutoHealShameCount - 2)),
    // The server consumes the saved hit timestamp on this food attempt. Clear
    // ours immediately as well; no acknowledgement retry is involved.
    (__mmAutoHealLastDamageAt = 0));
}
function __mmAutoHealSafeAt(__mmEmergency, __mmFoodValue) {
  if (!__mmAutoHealLastDamageAt || __mmAutoHealShameCount < 5)
    return 0;
  const __mmLowHealth =
    v.health <= Math.max(35, Number(__mmFoodValue) || 20);
  // Survival wins over Shame prevention. At non-critical health, 135ms from
  // the received damage packet is deliberately beyond the server's 120ms
  // comparison and turns this heal into a two-point counter reduction.
  return __mmEmergency || __mmLowHealth
    ? 0
    : __mmAutoHealLastDamageAt + 135;
}
function __mmResetAutoHeal() {
  ((__mmAutoHealWasHealing = !1),
    (__mmAutoHealPending = !1),
    (__mmAutoHealBitesRemaining = 0),
    (__mmAutoHealNextBiteAt = 0),
    (__mmAutoHealLastObservedHealth = v && v.alive ? Number(v.health) : null),
    __mmRestoreAutoHealWeapon());
}
function __mmAutoHeal(__mmEmergency) {
  if (!__mmAutoHealEnabled || !v || !v.alive)
    return void __mmResetAutoHeal();
  __mmObserveAutoHealHealth(v.health);
  // The same forecast that drives Anti Insta also removes the Shame delay when
  // damage already in flight would consume the current health. It does not
  // create speculative food retries; an actual damage/health event still owns
  // the heal queue.
  const __mmIncomingThreat = __mmCombatThreatSnapshot();
  __mmEmergency = !!(__mmEmergency || __mmIncomingThreat.urgent);
  // Shame! (hat 45) means the server is rejecting food for its 30-second
  // penalty. Do not burn resources or flood selection/attack packets during it.
  if (Number(v.skinIndex) === 45) {
    ((__mmAutoHealShameCount = 8),
      (__mmAutoHealPending = !1),
      (__mmAutoHealBitesRemaining = 0),
      (__mmAutoHealNextBiteAt = 0));
    return;
  }
  if (v.health >= v.maxHealth || !__mmCanEat()) return void __mmResetAutoHeal();
  if (__mmAutoHealPending) {
    // Calculate the whole refill from the hit packet, then keep sending it on
    // the server tick. This is optimistic (it never waits for a heal reply),
    // but avoids the current server dropping a pile of same-frame F packets.
    const __mmMissingHealth = Math.max(0, v.maxHealth - v.health),
      __mmFoodValue = __mmAutoHealFoodValue(),
      __mmNow = Date.now(),
      __mmSafeAt = __mmAutoHealSafeAt(__mmEmergency, __mmFoodValue);
    ((__mmAutoHealBitesRemaining = Math.min(
      Math.ceil(__mmMissingHealth / __mmFoodValue),
      __mmFoodCharges(),
    )),
      (__mmAutoHealPending = !1),
      (__mmAutoHealNextBiteAt = Math.max(__mmNow, __mmSafeAt || 0)));
  }
  if (!__mmAutoHealBitesRemaining || Date.now() < __mmAutoHealNextBiteAt)
    return;
  // A held mouse attack remains the action owner while food is pulsed between
  // swings. __mmUseFood restores the selected tool and resumes the live held
  // attack immediately, so healing does not require releasing either button.
  const __mmHealingDuringHeldAttack = !!(
      __mmActionOwner === "manualAttack" &&
      (__mmPrimaryHeld || __mmSecondaryHeld)
    ),
    __mmOwnsAction = __mmHealingDuringHeldAttack
      ? !1
      : __mmActionClaim("autoHeal", "food recovery");
  if (
    !__mmOwnsAction &&
    !__mmHealingDuringHeldAttack &&
    !(__mmEmergency && __mmActionOwner === "trapEscape")
  )
    return;
  const __mmFoodSentAt = Date.now();
  ((__mmAutoHealWasHealing = !0),
    __mmAutoHealRecordFoodAttempt(__mmFoodSentAt),
    __mmUseFood(),
    (__mmAutoHealWasHealing = !1),
    (__mmAutoHealBitesRemaining -= 1),
    (__mmAutoHealNextBiteAt =
      Date.now() + Math.max(1, __mmServerTickMs())),
    __mmOwnsAction && __mmActionRelease("autoHeal", "food sent"));
}
function __mmToggleAutoHeal() {
  __mmSetAutoHeal(!__mmAutoHealEnabled);
}
function __mmBushStatus(__mmMessage) {
  window.dispatchEvent(
    new CustomEvent("MooMooScrollZoomStatus", { detail: __mmMessage }),
  );
}
function __mmBushGearOwned() {
  return !!(v && v.skins && v.skins[__mmBushGear]);
}
function __mmClearBushPurchaseWatch() {
  __mmBushPurchaseTimer && clearInterval(__mmBushPurchaseTimer);
  __mmBushPurchaseTimer = 0;
}
function __mmBushRestoreHat(__mmFallback) {
  return Date.now() <= __mmBushRestoreOverrideUntil &&
    __mmBushRestoreOverrideHat != null
    ? __mmBushRestoreOverrideHat
    : __mmFallback;
}
function __mmBushRestoreTail(__mmFallback) {
  return Date.now() <= __mmBushRestoreOverrideUntil &&
    __mmBushRestoreOverrideTail != null
    ? __mmBushRestoreOverrideTail
    : __mmFallback;
}
function __mmBushAllowedMovingTail() {
  if (!v || !v.alive || !v.tails) return 0;
  if (
    (v.tailIndex === __mmShadowWings || v.tailIndex === 11) &&
    v.tails[v.tailIndex]
  )
    return v.tailIndex;
  if (
    (__mmBushPreviousTail === __mmShadowWings ||
      __mmBushPreviousTail === 11) &&
    v.tails[__mmBushPreviousTail]
  )
    return __mmBushPreviousTail;
  if (v.tails[__mmShadowWings]) return __mmShadowWings;
  return v.tails[11] ? 11 : 0;
}
function __mmBushBreaksOnActionOwner(__mmOwner) {
  return (
    __mmOwner === "manualAttack" ||
    __mmOwner === "trapEscape" ||
    __mmOwner === "spikeTickStrike" ||
    __mmOwner === "instaSync" ||
    __mmOwner === "boostBreak" ||
    __mmOwner === "cleanup" ||
    __mmOwner === "weaponGrind" ||
    __mmOwner === "mobSteal" ||
    __mmOwner === "matThief"
  );
}
function __mmUpdateBushMode() {
  if (!__mmBushModeEnabled) return;
  if (!v || !v.alive)
    return void __mmStopBushMode("player unavailable", !1);
  const __mmSwingOwner = __mmBushBreaksOnActionOwner(__mmActionOwner);
  if (
    __mmSwingOwner ||
    __mmPrimaryHeld ||
    __mmSecondaryHeld ||
    __mmTrapAttackActive ||
    __mmInsta.isActive() ||
    __mmBoostInsta.isActive()
  )
    // Combat temporarily owns hats, tails, tools, and aim. Keep Bush mode
    // armed and simply resume concealment on the first idle fast-check.
    return;
  const __mmTarget = __mmInsta.nearestEnemy();
  const __mmPrimary = __mmInsta.supportedPrimary();
  if (
    __mmTarget &&
    __mmPrimary != null &&
    __mmInsta.inRange(__mmPrimary, __mmTarget) &&
    __mmBoostInsta.requirements(__mmTarget, !0) &&
    __mmActionCanPreempt("boostInsta")
  ) {
    const __mmTargetSid = __mmTarget.sid;
    return void __mmBoostInsta.start({
      targetSid: __mmTargetSid,
      ambush: !0,
    });
  }
  const __mmTail = __mmPlayerMoving()
    ? __mmBushAllowedMovingTail()
    : 0;
  if (v.skinIndex !== __mmBushGear || __mmPendingHat !== __mmBushGear)
    __mmEquipHatNow(__mmBushGear, !0);
  if (v.tailIndex !== __mmTail || __mmPendingTail !== __mmTail)
    __mmEquipTailNow(__mmTail, !0);
}
function __mmActivateBushMode() {
  if (!__mmBushModeRequested || __mmBushModeEnabled || !__mmBushGearOwned())
    return !1;
  const __mmSavedHat =
      __mmSoldierPreviousHat != null
        ? __mmSoldierPreviousHat
        : __mmMovementGearPreviousHat != null
          ? __mmMovementGearPreviousHat
          : v.skinIndex,
    __mmSavedTail =
      __mmMovementGearPreviousTail != null
        ? __mmMovementGearPreviousTail
        : __mmProximityTailPrevious != null
            ? __mmProximityTailPrevious
            : v.tailIndex;
  (__mmBushExitRestoreTimer && clearTimeout(__mmBushExitRestoreTimer),
    (__mmBushExitRestoreTimer = 0),
    __mmClearBushPurchaseWatch(),
    (__mmBushRestoreOverrideHat = null),
    (__mmBushRestoreOverrideTail = null),
    (__mmBushRestoreOverrideUntil = 0),
    __mmRestoreMovementGear(),
    __mmRestoreProximityTail(),
    __mmPauseSoldierForBreaking(),
    (__mmBushPreviousHat = __mmSavedHat),
    (__mmBushPreviousTail = __mmSavedTail),
    (__mmBushModeEnabled = !0),
    __mmEnsureOperationPipeline(),
    __mmUpdateBushMode(),
    __mmBushStatus("Bush ambush: armed"),
    __mmPublishHudState());
  return !0;
}
function __mmScheduleBushExitRestore(__mmHat, __mmTail) {
  (__mmBushExitRestoreTimer && clearTimeout(__mmBushExitRestoreTimer),
    (__mmBushExitRestoreTimer = 0));
  const __mmRestoreWhenIdle = function () {
    __mmBushExitRestoreTimer = 0;
    if (__mmBushModeRequested || !v || !v.alive) return;
    if (
      __mmBushBreaksOnActionOwner(__mmActionOwner) ||
      __mmPrimaryHeld ||
      __mmSecondaryHeld ||
      __mmTrapAttackActive ||
      __mmInsta.isActive() ||
      __mmBoostInsta.isActive()
    ) {
      __mmBushExitRestoreTimer = setTimeout(
        __mmRestoreWhenIdle,
        __mmFastCheckMs(),
      );
      return;
    }
    ((__mmBushRestoreOverrideHat = __mmHat),
      (__mmBushRestoreOverrideTail = __mmTail),
      (__mmBushRestoreOverrideUntil = Date.now() + __mmServerTickMs() * 3),
      __mmEquipGearPair(__mmHat, __mmTail, !0));
  };
  __mmRestoreWhenIdle();
}
function __mmStopBushMode(__mmReason, __mmRestore = !0) {
  const __mmWasRequested = __mmBushModeRequested,
    __mmWasEnabled = __mmBushModeEnabled,
    __mmHat = __mmBushPreviousHat,
    __mmTail = __mmBushPreviousTail;
  ((__mmBushModeRequested = !1),
    (__mmBushModeEnabled = !1),
    __mmClearBushPurchaseWatch(),
    __mmBushModeTimer && clearInterval(__mmBushModeTimer),
    (__mmBushModeTimer = 0),
    (__mmBushPreviousHat = null),
    (__mmBushPreviousTail = null));
  if (__mmRestore && __mmWasEnabled && v && v.alive) {
    __mmScheduleBushExitRestore(__mmHat, __mmTail);
  }
  (__mmWasRequested || __mmWasEnabled) &&
    (__mmReason && __mmBushStatus("Bush ambush: " + __mmReason),
    __mmPublishHudState());
}
function __mmWatchBushPurchase() {
  if (__mmBushPurchaseTimer) return;
  const __mmStartedAt = Date.now();
  __mmBushPurchaseTimer = setInterval(function () {
    if (!__mmBushModeRequested)
      return void __mmClearBushPurchaseWatch();
    if (__mmBushGearOwned()) return void __mmActivateBushMode();
    if (!v || !v.alive || Date.now() - __mmStartedAt > 3e3)
      return void __mmStopBushMode("purchase was not accepted", !1);
  }, __mmFastCheckMs());
}
function __mmSetBushMode(__mmEnabled) {
  if (!__mmEnabled) return void __mmStopBushMode("off", !0);
  if (__mmBushModeRequested) return;
  if (
    !v ||
    !v.alive ||
    __mmPrimaryHeld ||
    __mmSecondaryHeld ||
    __mmBushBreaksOnActionOwner(__mmActionOwner)
  )
    return void __mmBushStatus("Bush ambush unavailable");
  __mmBushModeRequested = !0;
  if (__mmBushGearOwned()) return void __mmActivateBushMode();
  if (
    (Number(v.points) || 0) < __mmBushGearPrice ||
    Date.now() - __mmBushPurchaseAt < 500
  )
    return void __mmStopBushMode("needs 3,000 points for Bush Gear", !1);
  ((__mmBushPurchaseAt = Date.now()),
    Xn(__mmBushGear, !1),
    __mmBushStatus("Bush ambush: buying Bush Gear"),
    __mmPublishHudState(),
    __mmWatchBushPurchase());
}
function __mmToggleBushMode() {
  __mmSetBushMode(!__mmBushModeRequested);
}
function __mmHandleBushHotkey() {
  if (__mmBushHotkeyDown) return;
  const __mmActiveElement = document.activeElement,
    __mmActiveTag =
      __mmActiveElement && __mmActiveElement.tagName
        ? __mmActiveElement.tagName.toLowerCase()
        : "";
  if (
    __mmActiveElement &&
    (__mmActiveTag === "input" ||
      __mmActiveTag === "textarea" ||
      __mmActiveElement.isContentEditable)
  )
    return;
  ((__mmBushHotkeyDown = !0), __mmToggleBushMode());
}
const __mmBowUpgradeInsta = {
  active: !1,
  targetSid: null,
  source: "manual",
  restoreTool: null,
  restoreHat: null,
  timers: new Set(),
  stageGap() {
    // Keep the ordered packets in one server-update window without putting
    // upgrade and attack messages in the same transport write.
    return Math.max(4, Math.min(10, Math.round(__mmFastCheckMs() * 0.5)));
  },
  target() {
    let __mmTarget = null;
    try {
      __mmTarget = Rt(this.targetSid);
    } catch (__mmBowUpgradeLookupError) {}
    return __mmIsEnemyPlayer(__mmTarget) ? __mmTarget : null;
  },
  weaponProjectile(__mmWeapon) {
    const __mmWeaponData = b && b.weapons && b.weapons[__mmWeapon];
    return __mmWeaponData && __mmWeaponData.projectile != null
      ? b.projectiles && b.projectiles[__mmWeaponData.projectile]
      : null;
  },
  inRange(__mmTarget) {
    if (!__mmTarget) return !1;
    const __mmDistance = __mmProjectileTravelDistance(v, __mmTarget);
    for (const __mmWeapon of [__mmBow, __mmCrossbow, __mmMusket]) {
      const __mmProjectile = this.weaponProjectile(__mmWeapon),
        __mmRange = Number(__mmProjectile && __mmProjectile.range);
      if (!__mmProjectile || !Number.isFinite(__mmRange) || __mmDistance > __mmRange)
        return !1;
    }
    return !0;
  },
  hasSpecialUpgrade() {
    // The saved-up branch is only meaningful after the player has selected a
    // special deployable (Turret, Teleporter, pad, platform, or blocker).
    return __mmSelectedPlaceableItem() != null;
  },
  ready(__mmTarget, __mmSkipBow = !1) {
    const __mmPoints = Number(v && v.upgradePoints);
    return !!(
      __mmAutoBowUpgradeInstaEnabled &&
      v &&
      v.alive &&
      Array.isArray(v.weapons) &&
      v.weapons.includes(__mmBow) &&
      !v.weapons.includes(__mmCrossbow) &&
      !v.weapons.includes(__mmMusket) &&
      Number.isFinite(__mmPoints) &&
      __mmPoints >= 2 &&
      this.hasSpecialUpgrade() &&
      v.skins &&
      v.skins[__mmTurretGear] &&
      b &&
      b.weapons &&
      b.weapons[__mmCrossbow] &&
      b.weapons[__mmMusket] &&
      (__mmSkipBow || __mmWeaponReady(__mmBow)) &&
      this.inRange(__mmTarget) &&
      !this.active &&
      !__mmPrimaryHeld &&
      !__mmSecondaryHeld &&
      !__mmBoostBreakHeld &&
      (__mmActionCanPreempt("bowUpgradeInsta") ||
        (__mmIsTrapped() &&
          (__mmTrapAttackActive || __mmActionOwner === "trapEscape")))
    );
  },
  aim(__mmWeapon, __mmTarget) {
    const __mmProjectile = this.weaponProjectile(__mmWeapon),
      __mmSpeed = Number(__mmProjectile && __mmProjectile.speed),
      __mmDistance = __mmProjectileTravelDistance(v, __mmTarget),
      __mmTravelMs = Number.isFinite(__mmSpeed) && __mmSpeed > 0
        ? __mmDistance / __mmSpeed
        : 0;
    return __mmSyncAimAngle(__mmTarget, __mmTravelMs);
  },
  schedule(__mmCallback, __mmDelay) {
    const __mmTimer = setTimeout(() => {
      this.timers.delete(__mmTimer);
      __mmCallback();
    }, Math.max(0, Number(__mmDelay) || 0));
    this.timers.add(__mmTimer);
    return __mmTimer;
  },
  clearTimers() {
    for (const __mmTimer of this.timers) clearTimeout(__mmTimer);
    this.timers.clear();
  },
  assumeUpgrade(__mmFrom, __mmTo) {
    if (!v || !v.alive || !Array.isArray(v.weapons)) return !1;
    const __mmSlot = v.weapons.indexOf(__mmFrom);
    if (__mmSlot < 0) return !1;
    v.weapons[__mmSlot] = __mmTo;
    if (Number(v.weaponIndex) === Number(__mmFrom)) v.weaponIndex = __mmTo;
    if (v.reloads) v.reloads[__mmTo] = 0;
    const __mmState = v.sid == null
      ? null
      : __mmPlayerToolCooldowns[String(v.sid)];
    __mmState && __mmState.weapons && delete __mmState.weapons[String(__mmTo)];
    const __mmPoints = Number(v.upgradePoints);
    Number.isFinite(__mmPoints) && (v.upgradePoints = Math.max(0, __mmPoints - 1));
    return !0;
  },
  fire(__mmWeapon) {
    const __mmTarget = this.target();
    if (!this.active || !__mmTarget || !this.inRange(__mmTarget))
      return (this.cancel("target lost"), !1);
    const __mmAngle = this.aim(__mmWeapon, __mmTarget);
    try {
      (je(__mmWeapon, !0),
        O.send("D", __mmAngle),
        O.send("F", 1, __mmAngle),
        O.send("F", 0, __mmAngle));
      return !0;
    } catch (__mmBowUpgradeFireError) {
      return (this.cancel("shot failed"), !1);
    }
  },
  upgradeAndFire(__mmFrom, __mmTo, __mmNext) {
    if (!this.active || !v || !v.alive) return this.cancel("player lost");
    try {
      // Send through the captured native socket method so the ordinary click
      // debounce and Katana/Musket helper cannot split this reserved sequence.
      ((__mmLastUpgradePacketAt = Date.now()),
        __mmOriginalSocketSend.call(O, "H", __mmTo));
    } catch (__mmBowUpgradePacketError) {
      return this.cancel("upgrade packet failed");
    }
    if (!this.assumeUpgrade(__mmFrom, __mmTo) || !this.fire(__mmTo)) return;
    typeof __mmNext === "function" && __mmNext();
  },
  finish() {
    if (!this.active) return;
    const __mmToolRestore = this.restoreTool,
      __mmRestoreHat = this.restoreHat,
      __mmMayRestore = __mmActionMayRestore("bowUpgradeInsta");
    (this.clearTimers(),
      (this.active = !1),
      (this.targetSid = null),
      (this.restoreTool = null),
      (this.restoreHat = null),
      __mmMayRestore &&
        v &&
        v.alive &&
        __mmEquipHatNow(__mmBestPostCombatHat() || __mmRestoreHat, !0),
      __mmMayRestore && __mmToolRestore && __mmRestoreTool(__mmToolRestore),
      __mmActionRelease("bowUpgradeInsta", "three shots sent"),
      __mmScheduleMouseAimReturn(),
      __mmInstaChatEnabled && __mmSendChat("Meow!"));
  },
  cancel(__mmReason) {
    if (!this.active) return !1;
    const __mmToolRestore = this.restoreTool,
      __mmRestoreHat = this.restoreHat,
      __mmMayRestore = __mmActionMayRestore("bowUpgradeInsta");
    (this.clearTimers(),
      (this.active = !1),
      (this.targetSid = null),
      (this.restoreTool = null),
      (this.restoreHat = null),
      __mmMayRestore &&
        v &&
        v.alive &&
        __mmEquipHatNow(__mmBestPostCombatHat() || __mmRestoreHat, !0),
      __mmMayRestore && __mmToolRestore && __mmRestoreTool(__mmToolRestore),
      __mmActionRelease("bowUpgradeInsta", __mmReason || "cancelled"),
      __mmScheduleMouseAimReturn());
    return !1;
  },
  start(__mmRequestedTarget, __mmSource = "manual", __mmOptions = {}) {
    const __mmTarget =
      __mmRequestedTarget && __mmIsEnemyPlayer(__mmRequestedTarget)
        ? __mmRequestedTarget
        : __mmInsta.nearestEnemy();
    const __mmSkipBow = !!__mmOptions.skipBow;
    if (!this.ready(__mmTarget, __mmSkipBow)) return !1;
    (__mmIsTrapped() &&
      (__mmTrapAttackActive || __mmActionOwner === "trapEscape")) &&
      __mmStopTrapAttack();
    __mmActionOwner === "instaSync" && __mmStopInstaSync();
    __mmActionOwner === "weaponRecharge" && __mmPauseWeaponRecharge(!0);
    if (!__mmActionClaim("bowUpgradeInsta", __mmSource + " triple projectile"))
      return !1;
    (__mmCancelCombatHatLock(!1),
      (this.active = !0),
      (this.targetSid = __mmTarget.sid),
      (this.source = __mmSource),
      (this.restoreTool = __mmOptions.restoreTool || __mmSelectedTool()),
      (this.restoreHat = __mmOptions.restoreHat != null
        ? __mmOptions.restoreHat
        : __mmInstaSafeRestoreHat(__mmBushRestoreHat(v.skinIndex))));
    const __mmAngle = this.aim(__mmBow, __mmTarget),
      __mmTurretWasReady = __mmInsta.turretReady(),
      __mmGap = this.stageGap();
    try {
      (O.send("D", __mmAngle),
        __mmEquipHatNow(__mmTurretGear, !0),
        __mmTurretWasReady && __mmAssumeTurretGearShot());
    } catch (__mmBowUpgradeGearError) {
      return this.cancel("Turret Gear failed");
    }
    __mmShowInstaTypePopup(
      __mmSkipBow ? "Bow Upgrade Follow-up" : "Bow Upgrade Insta",
    );
    if (!__mmSkipBow && !this.fire(__mmBow)) return !1;
    this.schedule(() => {
      this.upgradeAndFire(__mmBow, __mmCrossbow, () => {
        this.schedule(() => {
          this.upgradeAndFire(__mmCrossbow, __mmMusket, () => {
            this.schedule(() => this.finish(), __mmServerTickMs());
          });
        }, __mmGap);
      });
    }, __mmGap);
    return !0;
  },
};
function __mmHandleInstaHotkey() {
  const __mmBowUpgradeTarget = __mmInsta.nearestEnemy();
  if (__mmBowUpgradeInsta.ready(__mmBowUpgradeTarget)) {
    const __mmCanLeadWithNormalInsta =
      __mmInsta.supportedPrimary() != null &&
      __mmInsta.fullBurstReady(__mmBowUpgradeTarget, "normal", !1, !0);
    if (
      __mmTryScheduleSharedInsta({
        automatic: !1,
        bowUpgrade: !0,
        targetSid: __mmBowUpgradeTarget.sid,
      })
    )
      return !0;
    if (
      __mmCanLeadWithNormalInsta &&
      __mmInsta.start({
        profile: "normal",
        profileSource: "R + Bow Upgrade",
        manualHotkey: !0,
        targetSid: __mmBowUpgradeTarget.sid,
        bowUpgradeFollowup: !0,
      })
    )
      return !0;
    if (__mmBowUpgradeInsta.start(__mmBowUpgradeTarget, "R")) return !0;
  }
  if (__mmBushModeRequested && __mmBushModeEnabled) {
    const __mmTarget = __mmInsta.nearestEnemy();
    if (
      __mmTarget &&
      __mmBoostInsta.start({
        targetSid: __mmTarget.sid,
        ambush: !0,
        manualBush: !0,
      })
    )
      return !0;
  }
  const __mmProfile = __mmOneTickInstaEnabled
      ? "oneTick"
      : __mmReverseInstaEnabled
        ? "reverse"
        : "normal",
    __mmStarted = __mmInsta.start({
      profile: __mmProfile,
      profileSource: "R",
      manualHotkey: !0,
    });
  if (!__mmStarted)
    __mmBushStatus(
      "R Insta: " + __mmInstaHotkeyBlockReason(__mmProfile),
    );
  return __mmStarted;
}
function __mmInstaHotkeyBlockReason(__mmProfile) {
  if (!__mmInstaUiEnabled) return "disabled in Combat settings";
  if (!__mmInsta.runtimeReady()) return "client is not ready";
  if (!v || !v.alive) return "spawn first";
  const __mmTarget = __mmInsta.nearestEnemy();
  if (!__mmTarget) return "no enemy target";
  const __mmPrimary = __mmInsta.supportedPrimary();
  if (__mmPrimary == null) return "needs Short Sword, Katana, or Polearm";
  if (!__mmInsta.inRange(__mmPrimary, __mmTarget))
    return __mmInsta.turretReady()
      ? "enemy left range"
      : "enemy out of range and Turret Gear is reloading";
  if (!v.skins || !v.skins[7]) return "Bull Helmet not owned";
  if (!__mmWeaponReady(__mmPrimary)) return "main weapon is reloading";
  const __mmSecondary = v.weapons && v.weapons[1],
    __mmSecondaryData = __mmInsta.weaponData(__mmSecondary);
  if (
    __mmSecondary == null ||
    __mmSecondary === __mmPrimary ||
    __mmSecondary === __mmShieldWeapon ||
    !__mmSecondaryData ||
    __mmSecondaryData.shield
  )
    return "usable secondary not equipped";
  if (!__mmWeaponReady(__mmSecondary)) return "secondary is reloading";
  if (!v.skins[__mmTurretGear]) return "Turret Gear not owned";
  if (!__mmInsta.turretReady()) return "Turret Gear is reloading";
  if (!__mmActionCanPreempt("insta"))
    return "busy with " + String(__mmActionOwner || "another action");
  return String(__mmInsta.reason || "kit validation failed");
}
function __mmToggleOneTickInsta() {
  ((__mmOneTickInstaEnabled = !__mmOneTickInstaEnabled),
    __mmBushStatus(
      "One-Tick Insta: " + (__mmOneTickInstaEnabled ? "on" : "off"),
    ),
    __mmPublishHudState());
}
function __mmToggleVelTickInsta() {
  ((__mmVelTickInstaEnabled = !__mmVelTickInstaEnabled),
    !__mmVelTickInstaEnabled && __mmStopVelTickInsta("hotkey disabled"),
    __mmBushStatus(
      "VelTick Insta: " + (__mmVelTickInstaEnabled ? "on" : "off"),
    ),
    __mmPublishHudState());
}
function __mmHandleBushCombatClick(__mmEvent) {
  if (!__mmBushModeRequested || !__mmBushModeEnabled) return !1;
  const __mmTarget = __mmInsta.nearestEnemy(),
    __mmPrimary = __mmInsta.supportedPrimary(),
    __mmCanAmbush = !!(
      __mmTarget &&
      __mmPrimary != null &&
      __mmInsta.inRange(__mmPrimary, __mmTarget) &&
      __mmBoostInsta.requirements(__mmTarget, !0) &&
      __mmActionCanPreempt("boostInsta")
    );
  if (__mmCanAmbush)
    __mmBoostInsta.start({
      targetSid: __mmTarget.sid,
      ambush: !0,
    });
  else __mmUpdateBushMode();
  // A click without a launchable nearby ambush is not a combat action. Keep
  // it away from MooMoo's normal attack path so Bull/Tank cannot replace Bush
  // Gear for a frame and make the armed mode appear to toggle itself off.
  (__mmEvent.preventDefault(), __mmEvent.stopImmediatePropagation());
  return !0;
}
function __mmTemporaryHatOverlay() {
  return (
    !v ||
    !v.alive ||
    __mmBushModeEnabled ||
    __mmSyncFollowerEnabled ||
    __mmPrimaryHeld ||
    __mmSecondaryHeld ||
    __mmTrapAttackActive ||
    __mmBoostBreakHeld ||
    __mmTankGearActive() ||
    __mmPrimaryClickHat != null ||
    __mmRightClickHat != null ||
    __mmTrapHat != null ||
    __mmSoldierPreviousHat != null
  );
}
function __mmInSnowBiome() {
  return !!(
    v &&
    Number.isFinite(Number(v.y)) &&
    y &&
    Number.isFinite(Number(y.snowBiomeTop)) &&
    v.y <= y.snowBiomeTop
  );
}
function __mmInWater() {
  if (
    !v ||
    !y ||
    !Number.isFinite(Number(v.y)) ||
    !Number.isFinite(Number(y.mapScale)) ||
    !Number.isFinite(Number(y.riverWidth))
  )
    return !1;
  const __mmRiverMiddle = y.mapScale / 2,
    __mmRiverHalf = y.riverWidth / 2;
  return (
    v.y >= __mmRiverMiddle - __mmRiverHalf &&
    v.y <= __mmRiverMiddle + __mmRiverHalf
  );
}
function __mmBuyFlipperHat() {
  if (
    !__mmInWater() ||
    !v ||
    !v.alive ||
    (v.skins && v.skins[__mmFlipperHat]) ||
    (v.points || 0) < __mmFlipperHatPrice ||
    Date.now() - __mmFlipperPurchaseAt < 500
  )
    return !1;
  return ((__mmFlipperPurchaseAt = Date.now()), Xn(__mmFlipperHat, !1), !0);
}
function __mmBuySnowHat() {
  if (
    !__mmInSnowBiome() ||
    !v ||
    !v.alive ||
    (v.skins && v.skins[__mmSnowHat]) ||
    (v.points || 0) < __mmSnowHatPrice ||
    Date.now() - __mmSnowPurchaseAt < 500
  )
    return !1;
  return ((__mmSnowPurchaseAt = Date.now()), Xn(__mmSnowHat, !1), !0);
}
function __mmSpeedHat() {
  return __mmInWater()
    ? __mmFlipperHat
    : __mmInSnowBiome()
      ? v && v.skins && v.skins[__mmSnowHat]
        ? __mmSnowHat
        : __mmBoosterHat
      : __mmBoosterHat;
}
function __mmBaseAutomationHat() {
  return __mmTrapHat != null
    ? __mmTrapHat
    : __mmRightClickHat != null
      ? __mmRightClickHat
      : __mmPrimaryClickHat != null
        ? __mmPrimaryClickHat
        : __mmSoldierPreviousHat != null
          ? __mmSoldierPreviousHat
          : v
            ? __mmInstaSafeRestoreHat(__mmBushRestoreHat(v.skinIndex))
            : null;
}
function __mmAssassinGearOwned() {
  return !!(v && v.skins && v.skins[__mmAssassinGear]);
}
function __mmAssassinGearPrice() {
  if (Array.isArray(Ze))
    for (let __mmIndex = 0; __mmIndex < Ze.length; __mmIndex++)
      if (Number(Ze[__mmIndex] && Ze[__mmIndex].id) === __mmAssassinGear)
        return Math.max(0, Number(Ze[__mmIndex].price) || 20000);
  return 20000;
}
function __mmAssassinStationary() {
  if (!v || !v.alive || __mmPlayerMoving()) return !1;
  const __mmElapsed = Number(v.t2) - Number(v.t1),
    __mmVelocityX =
      (Number(v.x2) - Number(v.x1)) / Math.max(1, __mmElapsed),
    __mmVelocityY =
      (Number(v.y2) - Number(v.y1)) / Math.max(1, __mmElapsed);
  return !(
    __mmElapsed > 0 &&
    __mmElapsed <= 500 &&
    Number.isFinite(__mmVelocityX) &&
    Number.isFinite(__mmVelocityY) &&
    Math.hypot(__mmVelocityX, __mmVelocityY) > 0.025
  );
}
function __mmAssassinHostileTurretNearby() {
  if (!v || !v.alive) return !1;
  const __mmTurrets = __mmActiveObjectSnapshot().turrets,
    __mmRangeSquared = __mmAssassinDangerRange * __mmAssassinDangerRange;
  for (let __mmIndex = 0; __mmIndex < __mmTurrets.length; __mmIndex++) {
    const __mmTurret = __mmTurrets[__mmIndex];
    if (!__mmTurret || !__mmTurret.active || __mmFriendlyStructure(__mmTurret))
      continue;
    const __mmDx = Number(__mmTurret.x) - Number(v.x),
      __mmDy = Number(__mmTurret.y) - Number(v.y);
    if (__mmDx * __mmDx + __mmDy * __mmDy <= __mmRangeSquared) return !0;
  }
  return !1;
}
function __mmAssassinEnemyNearby() {
  if (!v || !v.alive) return !0;
  const __mmEnemies = __mmLiveStateFresh() ? __mmLiveState.enemies : E,
    __mmRangeSquared = __mmAssassinDangerRange * __mmAssassinDangerRange;
  if (!Array.isArray(__mmEnemies)) return !1;
  for (let __mmIndex = 0; __mmIndex < __mmEnemies.length; __mmIndex++) {
    const __mmEnemy = __mmEnemies[__mmIndex];
    if (!__mmIsEnemyPlayer(__mmEnemy)) continue;
    const __mmDx = Number(__mmEnemy.x) - Number(v.x),
      __mmDy = Number(__mmEnemy.y) - Number(v.y);
    if (__mmDx * __mmDx + __mmDy * __mmDy <= __mmRangeSquared) return !0;
  }
  return !1;
}
function __mmAssassinSafe() {
  if (!v || !v.alive || !__mmAssassinStationary()) return !1;
  const __mmHealth = Math.max(0, Number(v.health) || 0),
    __mmMaxHealth = Math.max(1, Number(v.maxHealth) || 100),
    __mmThreat = __mmCombatThreatSnapshot();
  return !!(
    (__mmHealth / __mmMaxHealth) * 100 >= __mmAssassinMinHealth &&
    Date.now() >= __mmAssassinCooldownUntil &&
    !__mmAssassinEnemyNearby() &&
    !__mmAssassinHostileTurretNearby() &&
    !__mmIsTrapped() &&
    !__mmPrimaryHeld &&
    !__mmSecondaryHeld &&
    !__mmTrapAttackActive &&
    !__mmBoostBreakHeld &&
    !__mmBuildSpamTimer &&
    !__mmFoodSpamTimer &&
    !__mmInsta.isActive() &&
    !__mmBoostInsta.isActive() &&
    !__mmSyncFollowerEnabled &&
    !__mmBushModeEnabled &&
    !__mmCombatHatLockActive() &&
    (!__mmThreat ||
      (Number(__mmThreat.damage) <= 0 &&
        Number(__mmThreat.potentialDamage) <= 0)) &&
    ["idle", "movementGear", "soldierGear", "weaponRecharge"].includes(
      __mmActionOwner,
    )
  );
}
function __mmRestoreAssassinGear() {
  const __mmRestore = __mmAssassinPreviousHat,
    __mmWasAutomated = __mmAssassinConcealed || __mmRestore != null;
  (__mmWasAutomated &&
      (__mmAssassinCooldownUntil = Math.max(
        __mmAssassinCooldownUntil,
        Date.now() + __mmAssassinSafeMs,
      )),
    (__mmAssassinConcealed = !1),
    (__mmAssassinPreviousHat = null),
    (__mmAssassinSafeSince = 0));
  if (
    __mmWasAutomated &&
    v &&
    v.alive &&
    (Number(v.skinIndex) === __mmAssassinGear ||
      Number(__mmPendingHat) === __mmAssassinGear)
  ) {
    const __mmHat =
      __mmRestore != null &&
      __mmRestore !== __mmAssassinGear &&
      __mmCanEquipHat(__mmRestore)
        ? __mmRestore
        : v.skins && v.skins[6]
          ? 6
          : 0;
    __mmEquipHatNow(__mmHat, !0);
  }
}
function __mmUpdateAssassinAutomation() {
  if (!__mmAssassinAutomationEnabled || document.hidden || !v || !v.alive)
    return void __mmRestoreAssassinGear();
  const __mmNow = Date.now();
  if (!__mmAssassinSafe()) {
    ((__mmAssassinLastUnsafeAt = __mmNow), (__mmAssassinSafeSince = 0));
    return void __mmRestoreAssassinGear();
  }
  __mmAssassinSafeSince || (__mmAssassinSafeSince = __mmNow);
  if (__mmNow - __mmAssassinSafeSince < __mmAssassinSafeMs) return;
  if (!__mmAssassinGearOwned()) {
    if (
      Number(v.points) >= __mmAssassinGearPrice() &&
      __mmNow - __mmAssassinPurchaseAt >= 1000
    )
      ((__mmAssassinPurchaseAt = __mmNow), Xn(__mmAssassinGear, !1));
    return;
  }
  if (!__mmAssassinConcealed) {
    const __mmPrevious = __mmInstaSafeRestoreHat(__mmBaseAutomationHat());
    ((__mmAssassinPreviousHat =
      __mmPrevious === __mmAssassinGear
        ? v.skins && v.skins[6]
          ? 6
          : 0
        : __mmPrevious),
      (__mmAssassinConcealed = !0),
      __mmActionOwner === "weaponRecharge" && __mmPauseWeaponRecharge(!0),
      __mmRestoreMovementGear(),
      __mmPauseSoldierForBreaking());
  }
  if (
    Number(v.skinIndex) !== __mmAssassinGear ||
    Number(__mmPendingHat) !== __mmAssassinGear
  ) {
    const __mmRestoreLastNormal = __mmLastNormalHat;
    (__mmEquipHatNow(__mmAssassinGear, !0),
      (__mmLastNormalHat = __mmRestoreLastNormal));
  }
}
function __mmStartAssassinAutomation() {
  __mmEnsureOperationPipeline();
}
function __mmStopAssassinAutomation() {
  (__mmAssassinTimer && clearInterval(__mmAssassinTimer),
    (__mmAssassinTimer = 0),
    __mmRestoreAssassinGear());
}
function __mmEmergencyGetawayActive() {
  return !1;
}
function __mmRestoreMovementGear(__mmForceNoMonkey) {
  if (!__mmMovementGearActive()) return;
  if (!v || !v.alive)
    return void ((__mmMovementGearPreviousHat = null),
    (__mmMovementGearPreviousTail = null));
  if (
    __mmPrimaryHeld ||
    __mmSecondaryHeld ||
    __mmTrapAttackActive ||
    __mmBoostBreakHeld ||
    __mmTankGearActive()
  )
    return;
  const __mmHat = __mmMovementGearPreviousHat,
    __mmTail =
      __mmForceNoMonkey && !__mmHasStick() ? 0 : __mmMovementGearPreviousTail;
  ((__mmMovementGearPreviousHat = null),
    (__mmMovementGearPreviousTail = null),
    __mmEquipGearPair(__mmHat, __mmTail));
}
function __mmUpdateMovementGear() {
  if (__mmAssassinConcealed) return;
  if (v && v.alive && __mmRecoverStrayCombatHat()) return;
  if (!__mmMovementGearEnabled)
    return void (__mmRestoreMovementGear(),
    __mmRestoreProximityTail(),
    __mmClearIdleMonkeyTail());
  if (!v || !v.alive)
    return void (__mmRestoreMovementGear(), __mmRestoreProximityTail());
  if (__mmCombatHatLockActive()) return;
  if (__mmBushModeEnabled) return;
  if (__mmPrimaryHeld || __mmSecondaryHeld) {
    const __mmHeldWeapon = __mmHeldAttackWeapon();
    __mmHeldWeapon != null && __mmUpdateHeldGear(__mmHeldWeapon);
    return;
  }
  if (!__mmActionAvailable("movementGear")) return;
  if (__mmInsta.isActive()) return;
  // Existing combat actions own their hat and tail until they finish, avoiding
  // tick-by-tick flicker between movement and combat gear.
  if (
    __mmSyncFollowerEnabled ||
    __mmPrimaryHeld ||
    __mmSecondaryHeld ||
    __mmTrapAttackActive ||
    __mmBoostBreakHeld ||
    __mmTankGearActive()
  )
    return;
  __mmInSnowBiome() && __mmBuySnowHat();
  __mmRememberNormalHat();
  const __mmEnemyNearby = __mmEnemyWithinCombatRange(),
    __mmMoving = __mmPlayerMoving();
  if (__mmEnemyNearby) {
    // EMP is strictly an out-of-combat idle hat. Remove it immediately when
    // the combat radius becomes occupied, even if no movement-gear snapshot
    // exists to restore.
    (Number(v.skinIndex) === Number(__mmEmpHelmet) ||
      Number(__mmPendingHat) === Number(__mmEmpHelmet)) &&
      __mmEquipHatNow(v.skins && v.skins[6] ? 6 : 0, !0);
    const __mmTail =
      __mmMoving && v.tails && v.tails[__mmShadowWings]
        ? __mmShadowWings
        : !__mmMoving && v.tails && v.tails[__mmBloodWings]
          ? __mmBloodWings
          : __mmMoving
            ? null
            : 0;
    __mmRestoreMovementGear(!0);
    return __mmTail == null
      ? void __mmRestoreProximityTail()
      : void __mmSetProximityTail(__mmTail);
  }
  __mmRestoreProximityTail();
  if (!__mmMoving && !__mmBoostBreakHeld) {
    if (!(v.skins && v.skins[__mmEmpHelmet])) {
      __mmRestoreMovementGear();
      if (v.tails && v.tails[__mmAngelWings])
        return void __mmEquipTailNow(__mmAngelWings);
      return void __mmClearIdleMonkeyTail();
    }
    if (!__mmMovementGearActive()) {
      ((__mmMovementGearPreviousHat = __mmBaseAutomationHat()),
        (__mmMovementGearPreviousTail = __mmBushRestoreTail(v.tailIndex)),
        __mmPauseSoldierForBreaking());
    }
    const __mmIdleTail =
      v.tails && v.tails[__mmAngelWings]
        ? __mmAngelWings
        : __mmMovementGearPreviousTail;
    // EMP Helmet's anti-turret protection also owns the stationary safe phase.
    // Its paired tail leaves in the same packet tick.
    return void __mmEquipGearPair(__mmEmpHelmet, __mmIdleTail);
  }
  if (__mmTankGearActive()) return;
  if (
    __mmPrimaryHeld ||
    __mmSecondaryHeld ||
    __mmTrapAttackActive ||
    __mmBoostBreakHeld
  )
    return void __mmRestoreMovementGear();
  __mmInWater() && __mmBuyFlipperHat();
  const __mmHat = __mmSpeedHat(),
    __mmHasHat = !!(v.skins && v.skins[__mmHat]),
    __mmHasTail = !!(v.tails && v.tails[11]);
  if (!__mmMovementGearActive()) {
    ((__mmMovementGearPreviousHat = __mmBaseAutomationHat()),
      (__mmMovementGearPreviousTail = __mmBushRestoreTail(v.tailIndex)),
      __mmPauseSoldierForBreaking());
  }
  // Snow uses owned Snow Hat first and Booster Hat while the snow purchase is
  // unavailable or still being acknowledged; do not go bald in that gap.
  __mmEquipGearPair(__mmHasHat ? __mmHat : 0, __mmHasTail ? 11 : null);
}
function __mmStartMovementGear() {
  (__mmEnsureOperationPipeline(), __mmUpdateMovementGear());
}
function __mmUpdatePassiveSpikeMotion() {
  if (!v || !v.alive) {
    __mmPassiveSpikeMotion = null;
    return;
  }
  const __mmNow = Date.now(),
    __mmPrevious = __mmPassiveSpikeMotion,
    __mmElapsed = __mmPrevious
      ? Math.max(1, Math.min(250, __mmNow - __mmPrevious.at))
      : 0,
    __mmSampleVelocityX = __mmElapsed
      ? (Number(v.x) - __mmPrevious.x) / __mmElapsed
      : 0,
    __mmSampleVelocityY = __mmElapsed
      ? (Number(v.y) - __mmPrevious.y) / __mmElapsed
      : 0,
    __mmVelocityX = __mmPrevious && __mmElapsed < 250
      ? __mmSampleVelocityX * 0.72 + __mmPrevious.velocityX * 0.28
      : __mmSampleVelocityX,
    __mmVelocityY = __mmPrevious && __mmElapsed < 250
      ? __mmSampleVelocityY * 0.72 + __mmPrevious.velocityY * 0.28
      : __mmSampleVelocityY;
  __mmPassiveSpikeMotion = {
    x: Number(v.x) || 0,
    y: Number(v.y) || 0,
    at: __mmNow,
    velocityX: Number.isFinite(__mmVelocityX) ? __mmVelocityX : 0,
    velocityY: Number.isFinite(__mmVelocityY) ? __mmVelocityY : 0,
  };
}
function __mmPassiveSpikeVelocity() {
  let __mmVelocityX = Number(
      __mmPassiveSpikeMotion && __mmPassiveSpikeMotion.velocityX,
    ) || 0,
    __mmVelocityY = Number(
      __mmPassiveSpikeMotion && __mmPassiveSpikeMotion.velocityY,
    ) || 0;
  const __mmServerElapsed = Number(v && v.t2) - Number(v && v.t1),
    __mmServerVelocityX =
      (Number(v && v.x2) - Number(v && v.x1)) / __mmServerElapsed,
    __mmServerVelocityY =
      (Number(v && v.y2) - Number(v && v.y1)) / __mmServerElapsed,
    __mmTrackedSpeed = Math.hypot(__mmVelocityX, __mmVelocityY),
    __mmServerSpeed = Math.hypot(__mmServerVelocityX, __mmServerVelocityY);
  if (
    Number.isFinite(__mmServerVelocityX) &&
    Number.isFinite(__mmServerVelocityY) &&
    __mmServerElapsed > 0 &&
    __mmServerElapsed <= 500 &&
    __mmServerSpeed > __mmTrackedSpeed
  )
    ((__mmVelocityX = __mmServerVelocityX),
      (__mmVelocityY = __mmServerVelocityY));
  return { x: __mmVelocityX, y: __mmVelocityY };
}
function __mmPassiveSpikeEnemyNearby() {
  if (
    !v ||
    !v.alive ||
    !Array.isArray(E) ||
    __mmPassiveSpikeEnemyRange <= 0
  )
    return !1;
  const __mmRangeSquared =
    __mmPassiveSpikeEnemyRange * __mmPassiveSpikeEnemyRange;
  for (let __mmIndex = 0; __mmIndex < E.length; __mmIndex++) {
    const __mmPlayer = E[__mmIndex];
    if (!__mmIsEnemyPlayer(__mmPlayer)) continue;
    const __mmDx = __mmPlayer.x - v.x,
      __mmDy = __mmPlayer.y - v.y;
    if (__mmDx * __mmDx + __mmDy * __mmDy <= __mmRangeSquared) return !0;
  }
  return !1;
}
function __mmPassiveSpikeThreat() {
  if (!v || !v.alive) return null;
  const __mmVelocity = __mmPassiveSpikeVelocity(),
    __mmSpeed = Math.hypot(__mmVelocity.x, __mmVelocity.y);
  if (!Number.isFinite(__mmSpeed) || __mmSpeed < 0.01) return null;
  const __mmLeadMs = Math.max(
      150,
      Math.min(280, __mmServerTickMs() * 1.8),
    ),
    __mmCoastDistance = Math.min(95, __mmSpeed * __mmLeadMs),
    __mmEndX = v.x + (__mmVelocity.x / __mmSpeed) * __mmCoastDistance,
    __mmEndY = v.y + (__mmVelocity.y / __mmSpeed) * __mmCoastDistance;
  let __mmBest = null,
    __mmBestDistance = Infinity;
  const __mmSpikes = __mmActiveObjectSnapshot().spikes;
  for (let __mmIndex = 0; __mmIndex < __mmSpikes.length; __mmIndex++) {
    const __mmSpike = __mmSpikes[__mmIndex],
      __mmData = __mmSpike && b && b.list && b.list[__mmSpike.id],
      __mmName = String(__mmData && __mmData.name || "").toLowerCase();
    if (
      !__mmSpike ||
      !__mmSpike.active ||
      !__mmSpike.isItem ||
      !__mmName.includes("spikes") ||
      __mmSpikeOwnedByUsOrAlly(__mmSpike)
    )
      continue;
    const __mmToSpikeX = __mmSpike.x - v.x,
      __mmToSpikeY = __mmSpike.y - v.y,
      __mmToward =
        __mmToSpikeX * __mmVelocity.x +
        __mmToSpikeY * __mmVelocity.y;
    if (__mmToward <= 0) continue;
    const __mmRadius =
        (Number(v.scale) || 35) +
        (Number(__mmSpike.scale) || Number(__mmData.scale) || 45) +
        4,
      __mmPathDistanceSquared = __mmSegmentDistanceSquared(
        v.x,
        v.y,
        __mmEndX,
        __mmEndY,
        __mmSpike.x,
        __mmSpike.y,
      ),
      __mmCenterDistanceSquared =
        __mmToSpikeX * __mmToSpikeX + __mmToSpikeY * __mmToSpikeY;
    if (
      __mmPathDistanceSquared <= __mmRadius * __mmRadius &&
      __mmCenterDistanceSquared < __mmBestDistance
    )
      ((__mmBest = __mmSpike),
        (__mmBestDistance = __mmCenterDistanceSquared));
  }
  return __mmBest;
}
function __mmStopPassiveSpikeCorrection(__mmUserMovementTakingOver) {
  (__mmPassiveSpikePendingTimer &&
    clearTimeout(__mmPassiveSpikePendingTimer),
    (__mmPassiveSpikePendingTimer = 0),
    __mmPassiveSpikeCorrectionTimer &&
      clearTimeout(__mmPassiveSpikeCorrectionTimer),
    (__mmPassiveSpikeCorrectionTimer = 0));
  if (!__mmPassiveSpikeCorrecting) return;
  ((__mmPassiveSpikeCorrecting = !1), (Kt = null));
  __mmUserMovementTakingOver || Tt();
}
function __mmRunPassiveSpikeCorrection() {
  __mmPassiveSpikePendingTimer = 0;
  if (
    !__mmPassiveSpikeAvoidanceEnabled ||
    !v ||
    !v.alive ||
    (typeof ul === "function" && ul() != null) ||
    __mmPassiveSpikeEnemyNearby() ||
    __mmSyncFollowerEnabled ||
    __mmBoostBackingUp ||
    __mmBoostBreakHeld ||
    __mmTrapAttackActive ||
    __mmInsta.isActive() ||
    __mmIsTrapped()
  )
    return;
  const __mmSpike = __mmPassiveSpikeThreat();
  if (!__mmSpike) return;
  const __mmAway = Math.atan2(v.y - __mmSpike.y, v.x - __mmSpike.x),
    __mmDuration = Math.max(75, Math.min(140, __mmServerTickMs()));
  ((__mmPassiveSpikeCorrecting = !0),
    (Kt = __mmAway),
    O.send("9", __mmAway),
    (__mmPassiveSpikeCorrectionTimer = setTimeout(function () {
      __mmStopPassiveSpikeCorrection(!1);
    }, __mmDuration)));
}
function __mmPassiveSpikeMovementPressed() {
  __mmStopPassiveSpikeCorrection(!0);
}
function __mmPassiveSpikeMovementReleased() {
  if (
    !__mmPassiveSpikeAvoidanceEnabled ||
    (typeof ul === "function" && ul() != null)
  )
    return;
  __mmPassiveSpikePendingTimer && clearTimeout(__mmPassiveSpikePendingTimer);
  __mmPassiveSpikePendingTimer = setTimeout(__mmRunPassiveSpikeCorrection, 0);
}
function __mmStartPassiveSpikeAvoidance() {
  if (!__mmPassiveSpikeAvoidanceEnabled || __mmPassiveSpikeMotionTimer) return;
  (__mmUpdatePassiveSpikeMotion(),
    (__mmPassiveSpikeMotionTimer = setInterval(
      __mmUpdatePassiveSpikeMotion,
      Math.max(8, __mmFastCheckMs()),
    )));
}
function __mmStopPassiveSpikeAvoidance() {
  (__mmPassiveSpikeMotionTimer && clearInterval(__mmPassiveSpikeMotionTimer),
    (__mmPassiveSpikeMotionTimer = 0),
    (__mmPassiveSpikeMotion = null),
    __mmStopPassiveSpikeCorrection(!1));
}
function __mmAntiCollisionObjectKey(__mmObject) {
  if (!__mmObject) return null;
  const __mmSid =
    __mmObject.sid != null
      ? __mmObject.sid
      : __mmObject.id != null
        ? __mmObject.id + ":" + Math.round(Number(__mmObject.x) || 0) +
          ":" + Math.round(Number(__mmObject.y) || 0)
        : null;
  return __mmSid == null ? null : String(__mmSid);
}
function __mmAntiCollisionObjectAllowed(__mmObject) {
  if (
    !__mmObject ||
    !__mmObject.active ||
    !__mmObject.isItem ||
    !b ||
    !b.list
  )
    return !1;
  const __mmData = b.list[__mmObject.id],
    __mmName = String((__mmData && __mmData.name) || "").toLowerCase();
  return !!(
    __mmName === "teleporter" ||
    (__mmName.includes("spikes") && !__mmFriendlyStructure(__mmObject))
  );
}
function __mmAntiCollisionInputPointsToward(__mmObject, __mmDirection) {
  if (!v || !__mmObject || !Number.isFinite(Number(__mmDirection))) return !1;
  const __mmDx = Number(__mmObject.x) - Number(v.x),
    __mmDy = Number(__mmObject.y) - Number(v.y);
  return (
    __mmDx * Math.cos(__mmDirection) +
      __mmDy * Math.sin(__mmDirection) >
    0
  );
}
function __mmAntiCollisionDecelDistance(__mmSpeed) {
  // Forecast the full stopping point with MooMoo's 0.993 velocity decay
  // instead of waiting for the player's current hitbox to reach an object.
  // Speed is stored per millisecond, so convert one server tick to travel
  // distance before applying the decay curve.
  const __mmTickMs = Math.max(75, Math.min(140, __mmServerTickMs())),
    __mmDecay = Math.pow(0.993, __mmTickMs);
  let __mmStep = Math.max(0, Number(__mmSpeed) || 0) * __mmTickMs,
    __mmDistance = __mmStep,
    __mmSteps = 0;
  while (__mmStep >= 0.5 && __mmSteps++ < 14) {
    ((__mmStep *= __mmDecay), (__mmDistance += __mmStep));
  }
  return Math.max(0, __mmDistance);
}
function __mmAntiCollisionThreat(__mmDirection, __mmSkipKey) {
  if (!v || !v.alive || !Number.isFinite(Number(__mmDirection))) return null;
  const __mmMotion = __mmPassiveSpikeVelocity(),
    __mmDirectionX = Math.cos(__mmDirection),
    __mmDirectionY = Math.sin(__mmDirection),
    __mmMeasuredX = Number(__mmMotion && __mmMotion.x) || 0,
    __mmMeasuredY = Number(__mmMotion && __mmMotion.y) || 0,
    __mmMeasuredSpeed = Math.min(0.65, Math.hypot(__mmMeasuredX, __mmMeasuredY)),
    __mmMeasuredForward = Math.max(
      0,
      __mmMeasuredX * __mmDirectionX + __mmMeasuredY * __mmDirectionY,
    ),
    // Include a just-pressed movement key even before the first position
    // packet exposes velocity.
    __mmInputSpeed = Math.max(0.19, __mmMeasuredSpeed, __mmMeasuredForward),
    __mmMeasuredDecel = __mmAntiCollisionDecelDistance(__mmMeasuredForward),
    __mmInputDecel = __mmAntiCollisionDecelDistance(__mmInputSpeed),
    __mmPing = Number(window.pingTime),
    __mmReactionMs = Math.max(
      8,
      Math.min(
        38,
        __mmFastCheckMs() +
          (Number.isFinite(__mmPing) ? Math.max(0, __mmPing) * 0.1 : 0),
      ),
    ),
    __mmReactionDistance = __mmInputSpeed * __mmReactionMs,
    __mmBrakingDistance =
      Math.max(__mmMeasuredDecel, __mmInputDecel) + __mmReactionDistance,
    __mmEndX = Number(v.x) + __mmDirectionX * __mmBrakingDistance,
    __mmEndY = Number(v.y) + __mmDirectionY * __mmBrakingDistance,
    __mmRange = Math.max(120, Number(__mmAntiCollisionRange) || 260),
    __mmCombatPaused = __mmAntiCollisionCombatPaused(),
    __mmObjects = __mmActiveObjectSnapshot().all;
  let __mmBest = null,
    __mmBestDistance = Infinity;
  for (let __mmIndex = 0; __mmIndex < __mmObjects.length; __mmIndex++) {
    const __mmObject = __mmObjects[__mmIndex],
      __mmKey = __mmAntiCollisionObjectKey(__mmObject),
      __mmData = __mmObject && b && b.list && b.list[__mmObject.id],
      __mmName = String((__mmData && __mmData.name) || "")
        .trim()
        .toLowerCase(),
      __mmTeleporter = __mmName === "teleporter";
    if (
      !__mmAntiCollisionObjectAllowed(__mmObject) ||
      // Teleporters are always guarded. Only hostile spikes participate in
      // the combat auto-pause, matching the requested safe-gathering behavior.
      (!__mmTeleporter && __mmCombatPaused) ||
      (__mmSkipKey != null && __mmKey === __mmSkipKey)
    )
      continue;
    const __mmDx = Number(__mmObject.x) - Number(v.x),
      __mmDy = Number(__mmObject.y) - Number(v.y),
      __mmCenterDistanceSquared = __mmDx * __mmDx + __mmDy * __mmDy,
      __mmCenterDistance = Math.sqrt(__mmCenterDistanceSquared),
      __mmRawScale = Math.max(
        1,
        Number(__mmObject.scale) ||
          Number(__mmData && __mmData.scale) ||
          __mmCleanupObjectScale(__mmObject),
      ),
      // Use a slightly smaller TP boundary so the player can approach closely,
      // while hostile damaging spikes keep their full scale.
      __mmObjectScale = __mmTeleporter
        ? __mmRawScale * 0.75
        : Math.max(__mmRawScale, __mmCleanupObjectScale(__mmObject)),
      __mmCollisionRadius =
        (Number(v.scale) || 35) + __mmObjectScale,
      __mmCloseRadius = __mmRange + __mmCollisionRadius,
      __mmToward = __mmDx * __mmDirectionX + __mmDy * __mmDirectionY,
      __mmClosingSpeed = Math.max(0, __mmMeasuredForward, __mmInputSpeed),
      __mmBaseGap = __mmTeleporter ? 1.5 : 3,
      __mmStopGap = Math.max(
        __mmBaseGap,
        Math.min(
          __mmRange,
          __mmBaseGap + __mmBrakingDistance,
        ),
      ),
      __mmCurrentGap = __mmCenterDistance - __mmCollisionRadius;
    if (
      __mmCenterDistanceSquared > __mmCloseRadius * __mmCloseRadius ||
      __mmCurrentGap > __mmStopGap ||
      __mmToward <= 0 ||
      !__mmAntiCollisionInputPointsToward(__mmObject, __mmDirection)
    )
      continue;
    const __mmPathDistanceSquared = __mmSegmentDistanceSquared(
      Number(v.x),
      Number(v.y),
      __mmEndX,
      __mmEndY,
      Number(__mmObject.x),
      Number(__mmObject.y),
    ),
      __mmEndDx = __mmEndX - Number(__mmObject.x),
      __mmEndDy = __mmEndY - Number(__mmObject.y),
      __mmEndDistanceSquared = __mmEndDx * __mmEndDx + __mmEndDy * __mmEndDy,
      __mmPredictedIntersection =
        __mmEndDistanceSquared <=
          (__mmCollisionRadius + __mmBaseGap) *
            (__mmCollisionRadius + __mmBaseGap) ||
        __mmPathDistanceSquared <=
          __mmCollisionRadius * __mmCollisionRadius;
    if (
      __mmPredictedIntersection &&
      __mmCenterDistanceSquared < __mmBestDistance
    )
      ((__mmBest = {
        object: __mmObject,
        key: __mmKey,
        scale: __mmObjectScale,
        gap: __mmCurrentGap,
        stopGap: __mmStopGap,
        closingSpeed: __mmClosingSpeed,
        brakingDistance: __mmBrakingDistance,
        teleporter: __mmTeleporter,
      }),
        (__mmBestDistance = __mmCenterDistanceSquared));
  }
  return __mmBest;
}
function __mmAntiCollisionShowStop(__mmThreat) {
  if (!__mmThreat || !__mmThreat.object) return;
  const __mmNow = Date.now();
  if (
    __mmAntiCollisionLastPopupKey === __mmThreat.key &&
    __mmNow - __mmAntiCollisionLastPopupAt < 550
  )
    return;
  ((__mmAntiCollisionLastPopupKey = __mmThreat.key),
    (__mmAntiCollisionLastPopupAt = __mmNow),
    __mmAntiCollisionPopups.push({
      x: Number(__mmThreat.object.x) || 0,
      y: Number(__mmThreat.object.y) || 0,
      scale: Math.max(20, Number(__mmThreat.scale) || 45),
      startedAt: performance.now(),
    }));
  __mmAntiCollisionPopups.length > 5 && __mmAntiCollisionPopups.shift();
}
function __mmAntiCollisionCombatPaused() {
  return !!(
    __mmAntiCollisionPauseCombatEnabled &&
    typeof __mmSyncLocalCombatActive === "function" &&
    __mmSyncLocalCombatActive()
  );
}
function __mmAntiCollisionReleaseBlock(__mmResumeMovement) {
  if (!__mmAntiCollisionBlocked) return;
  ((__mmAntiCollisionBlocked = !1),
    (__mmAntiCollisionBlockedObject = null),
    (__mmAntiCollisionBlockedKey = null),
    (Kt = null));
  __mmResumeMovement && v && v.alive && Tt();
}
function __mmAntiCollisionQuickRightClick(__mmThreat) {
  if (
    !__mmThreat ||
    !__mmThreat.object ||
    !v ||
    !v.alive ||
    __mmAntiCollisionRightClickTimer ||
    __mmPrimaryHeld ||
    __mmSecondaryHeld ||
    __mmTrapAttackActive ||
    __mmBuildSpamTimer ||
    __mmFoodSpamTimer ||
    __mmInsta.isActive()
  )
    return;
  const __mmObject = __mmThreat.object,
    __mmData = b && b.list && b.list[__mmObject.id],
    __mmName = String((__mmData && __mmData.name) || "")
      .trim()
      .toLowerCase();
  if (__mmName !== "teleporter") return;
  if (
    __mmActionOwner !== "idle" &&
    __mmActionOwner !== "movementGear" &&
    __mmActionOwner !== "soldierGear" &&
    __mmActionOwner !== "weaponRecharge"
  )
    return;
  const __mmWeapon = __mmRightClickWeapon();
  if (__mmWeapon == null) return;
  __mmActionOwner === "weaponRecharge" && __mmPauseWeaponRecharge(!0);
  if (!__mmActionClaim("manualAttack", "teleporter guard quick right click"))
    return;
  const __mmTool = __mmSelectedTool(),
    __mmUseTank = !!(
      __mmTankRightClickEnabled &&
      v.skins &&
      v.skins[40]
    ),
    __mmAngle = Math.atan2(
      Number(__mmObject.y) - Number(v.y),
      Number(__mmObject.x) - Number(v.x),
    );
  (__mmUseTank && __mmActivateCombatHat(40),
    je(__mmWeapon, !0),
    O.send("D", __mmAngle),
    __mmSendWeaponAttack(1),
    (__mmAntiCollisionRightClickTimer = setTimeout(function () {
      __mmAntiCollisionRightClickTimer = 0;
      if (v && v.alive) {
        (__mmSendWeaponAttack(0),
          __mmRestoreTool(__mmTool),
          __mmResumeHeldAttack());
      }
      (__mmActionRelease("manualAttack", "teleporter quick click complete"),
        __mmScheduleMouseAimReturn());
    }, Math.max(12, __mmFastCheckMs()))));
}
function __mmAntiCollisionStop(__mmThreat) {
  if (!__mmThreat || !__mmThreat.object) return;
  const __mmNewStop =
    !__mmAntiCollisionBlocked ||
    __mmAntiCollisionBlockedKey !== __mmThreat.key;
  ((__mmAntiCollisionBlocked = !0),
    (__mmAntiCollisionBlockedObject = __mmThreat.object),
    (__mmAntiCollisionBlockedKey = __mmThreat.key),
    (Kt = null),
    O.send("9", null));
  __mmNewStop &&
    (__mmAntiCollisionShowStop(__mmThreat),
    __mmAntiCollisionQuickRightClick(__mmThreat));
}
function __mmUpdateAntiCollision() {
  __mmUpdatePassiveSpikeMotion();
  if (!v || !v.alive) {
    __mmAntiCollisionBlocked && __mmAntiCollisionReleaseBlock(!1);
    return;
  }
  const __mmDirection = typeof ul === "function" ? ul() : null,
    __mmCanGuard = !!(
      __mmAntiCollisionEnabled &&
      !document.hidden
    );
  if (!__mmCanGuard) {
    __mmAntiCollisionBlocked && __mmAntiCollisionReleaseBlock(__mmDirection != null);
    return;
  }
  const __mmNow = Date.now();
  if (
    __mmAntiCollisionBypassArmedKey != null &&
    __mmNow >= __mmAntiCollisionBypassArmedUntil
  )
    ((__mmAntiCollisionBypassArmedKey = null),
      (__mmAntiCollisionBypassArmedUntil = 0));
  if (!Number.isFinite(Number(__mmDirection))) return;
  if (__mmAntiCollisionBlocked) {
    const __mmBlockedData =
        __mmAntiCollisionBlockedObject &&
        b &&
        b.list &&
        b.list[__mmAntiCollisionBlockedObject.id],
      __mmBlockedIsTeleporter =
        String((__mmBlockedData && __mmBlockedData.name) || "")
          .trim()
          .toLowerCase() === "teleporter",
      __mmReleaseForCombat =
        !__mmBlockedIsTeleporter && __mmAntiCollisionCombatPaused();
    if (
      __mmReleaseForCombat ||
      !__mmAntiCollisionBlockedObject ||
      !__mmAntiCollisionBlockedObject.active ||
      !__mmAntiCollisionInputPointsToward(
        __mmAntiCollisionBlockedObject,
        __mmDirection,
      )
      )
      __mmAntiCollisionReleaseBlock(!0);
    else {
      Kt !== null && ((Kt = null), O.send("9", null));
      return;
    }
  }
  let __mmThreat = __mmAntiCollisionThreat(
    __mmDirection,
    __mmAntiCollisionBypassActiveKey,
  );
  if (
    __mmThreat &&
    __mmAntiCollisionBypassArmedKey != null &&
    __mmThreat.key === __mmAntiCollisionBypassArmedKey
  ) {
    ((__mmAntiCollisionBypassActiveKey = __mmThreat.key),
      (__mmAntiCollisionBypassArmedKey = null),
      (__mmAntiCollisionBypassArmedUntil = 0));
    __mmThreat = __mmAntiCollisionThreat(
      __mmDirection,
      __mmAntiCollisionBypassActiveKey,
    );
  }
  __mmThreat && __mmAntiCollisionStop(__mmThreat);
}
function __mmAntiCollisionMovementPressed(__mmKey) {
  __mmSyncManualMovementPressed(__mmKey);
  __mmUpdateAntiCollision();
  Tt();
}
function __mmAntiCollisionMovementReleased() {
  const __mmDirection = typeof ul === "function" ? ul() : null;
  if (__mmDirection == null) {
    if (__mmAntiCollisionBlocked && __mmAntiCollisionBlockedKey != null) {
      ((__mmAntiCollisionBypassArmedKey = __mmAntiCollisionBlockedKey),
        (__mmAntiCollisionBypassArmedUntil = Date.now() + 3000));
    }
    (__mmAntiCollisionReleaseBlock(!1),
      (__mmAntiCollisionBypassActiveKey = null));
  } else {
    __mmUpdateAntiCollision();
  }
  Tt();
}
function __mmStartAntiCollision() {
  (__mmUpdatePassiveSpikeMotion(),
    __mmEnsureOperationPipeline(),
    __mmUpdateAntiCollision());
}
function __mmStopAntiCollision() {
  (__mmAntiCollisionTimer && clearInterval(__mmAntiCollisionTimer),
    (__mmAntiCollisionTimer = 0),
    (__mmAntiCollisionBypassArmedKey = null),
    (__mmAntiCollisionBypassArmedUntil = 0),
    (__mmAntiCollisionBypassActiveKey = null),
    (__mmAntiCollisionPopups.length = 0),
    __mmAntiCollisionReleaseBlock(!0));
}
const __mmOriginalMovementUpdate = Tt;
Tt = function () {
  if (__mmAntiCollisionBlocked) {
    Kt !== null && ((Kt = null), O.send("9", null));
    return;
  }
  return __mmOriginalMovementUpdate.apply(this, arguments);
};
function __mmBoostPadItem() {
  if (!v || !v.items) return null;
  for (let __mmItemIndex = 0; __mmItemIndex < v.items.length; __mmItemIndex++) {
    const __mmItem = v.items[__mmItemIndex],
      __mmData = b.list[__mmItem];
    if (__mmData && __mmData.boostSpeed) return __mmItem;
  }
  return null;
}
function __mmHasPitTrap() {
  if (!v || !v.items) return !1;
  for (let __mmItemIndex = 0; __mmItemIndex < v.items.length; __mmItemIndex++) {
    const __mmData = b.list[v.items[__mmItemIndex]];
    if (__mmData && __mmData.trap) return !0;
  }
  return !1;
}
function __mmIsSandboxServer() {
  const __mmHost =
    typeof location !== "undefined"
      ? String(location.hostname || "").toLowerCase()
      : "";
  return __mmHost === "sandbox.moomoo.io" || !!(y && y.inSandbox);
}
function __mmIsMillBuildData(__mmData) {
  return !!(
    __mmData && /mill/i.test(String(__mmData.name || ""))
  );
}
function __mmBuildGroupLimit(__mmData) {
  const __mmGroup = __mmData && __mmData.group;
  if (!__mmGroup) return 0;
  const __mmNormalLimit = Number(__mmGroup.limit) || 0;
  if (!__mmIsSandboxServer()) return __mmNormalLimit;
  // sandbox.moomoo.io permits 299 mills in the shared mill group. The stock
  // client metadata/canBuild path can still expose the normal seven-mill cap,
  // so use the server's real limit for mills while retaining the published
  // sandbox limit/fallback behavior for every other placeable group.
  if (__mmIsMillBuildData(__mmData)) return 299;
  const __mmSandboxLimit = Number(__mmGroup.sandboxLimit) || 0;
  return __mmSandboxLimit || Math.max(__mmNormalLimit * 3, 99);
}
function __mmCanUseBuildItem(__mmItem) {
  const __mmData = b && b.list && b.list[__mmItem];
  if (!v || !__mmData || !Array.isArray(__mmData.req)) return !1;
  for (
    let __mmReqIndex = 0;
    __mmReqIndex < __mmData.req.length;
    __mmReqIndex += 2
  )
    if ((v[__mmData.req[__mmReqIndex]] || 0) < __mmData.req[__mmReqIndex + 1])
      return !1;
  // MooMoo's own canBuild also enforces the active group limit. Use this check
  // before every place call; relying on material costs alone made
  // Kitty repeatedly select a full spike/trap group and send a rejected hit.
  // The stock sandbox client may keep enforcing the normal seven-mill limit.
  // Material costs were checked above and Kitty's group counter enforces 299,
  // so only bypass that stale native limit for mills on the sandbox hostname.
  if (
    !(__mmIsSandboxServer() && __mmIsMillBuildData(__mmData)) &&
    typeof v.canBuild === "function"
  )
    try {
      if (!v.canBuild(__mmData)) return !1;
    } catch (__mmCanBuildError) {}
  return !0;
}
function __mmSendAutomaticPlacement(
  __mmItem,
  __mmAngle,
  __mmOriginalTool,
  __mmReservedSlot,
) {
  if (
    !v ||
    !v.alive ||
    __mmItem == null ||
    !Number.isFinite(Number(__mmAngle)) ||
    !__mmCanUseBuildItem(__mmItem) ||
    (!__mmReservedSlot && __mmMaxBuildCount(__mmItem) < 1)
  )
    return !1;
  const __mmRestore = __mmOriginalTool || __mmSelectedTool();
  try {
    (je(__mmItem), O.send("F", 1, __mmAngle));
    // End a build by selecting the weapon rather than injecting an
    // F=0 between place and restore. Preserve a manually selected build item
    // with the explicit release path because it has no weapon-select edge.
    __mmRestore && __mmRestore.weapon
      ? __mmRestoreTool(__mmRestore)
      : (O.send("F", 0, __mmAngle),
        __mmRestore && __mmRestoreTool(__mmRestore));
    (__mmResumeHeldAttack(), __mmScheduleMouseAimReturn());
    return !0;
  } catch (__mmAutomaticPlacementError) {
    try {
      (O.send("F", 0, __mmAngle),
        __mmRestore && __mmRestoreTool(__mmRestore),
        __mmResumeHeldAttack(),
        __mmScheduleMouseAimReturn());
    } catch (__mmAutomaticPlacementRestoreError) {}
    return !1;
  }
}
function __mmThreatTrapItem() {
  if (!v || !v.items || !b || !b.list) return null;
  if (__mmThreatTrapEnabled)
    for (let __mmItemIndex = 0; __mmItemIndex < v.items.length; __mmItemIndex++) {
      const __mmItem = v.items[__mmItemIndex],
        __mmData = b.list[__mmItem];
      if (
        __mmData &&
        __mmData.trap &&
        __mmCanUseBuildItem(__mmItem) &&
        __mmMaxBuildCount(__mmItem) > 0
      )
        return __mmItem;
    }
  // A usable pit trap always wins. The animal-defense toggle owns its spike
  // fallback too, while Mc Grabby and emergency getaway continue suppressing
  // automatic spikes.
  if (
    !__mmThreatTrapEnabled ||
    __mmHoldingMcGrabby() ||
    __mmEmergencyGetawayActive()
  )
    return null;
  for (let __mmItemIndex = 0; __mmItemIndex < v.items.length; __mmItemIndex++) {
    const __mmItem = v.items[__mmItemIndex],
      __mmData = b.list[__mmItem];
    if (
      __mmData &&
      typeof __mmData.name === "string" &&
      __mmData.name.toLowerCase().includes("spikes") &&
      __mmCanUseBuildItem(__mmItem) &&
      __mmMaxBuildCount(__mmItem) > 0
    )
      return __mmItem;
  }
  return null;
}
function __mmPassiveMobTrapItem() {
  if (!__mmPassiveMobTrapEnabled || !v || !v.items || !b || !b.list)
    return null;
  for (let __mmItemIndex = 0; __mmItemIndex < v.items.length; __mmItemIndex++) {
    const __mmItem = v.items[__mmItemIndex],
      __mmData = b.list[__mmItem];
    if (
      __mmData &&
      __mmData.trap &&
      __mmCanUseBuildItem(__mmItem) &&
      __mmMaxBuildCount(__mmItem) > 0
    )
      return __mmItem;
  }
  return null;
}
function __mmThreatTeleporterItem() {
  if (!v || !v.items || !b || !b.list) return null;
  for (let __mmItemIndex = 0; __mmItemIndex < v.items.length; __mmItemIndex++) {
    const __mmItem = v.items[__mmItemIndex],
      __mmData = b.list[__mmItem];
    if (
      __mmData &&
      String(__mmData.name || "").toLowerCase() === "teleporter" &&
      __mmCanUseBuildItem(__mmItem) &&
      __mmMaxBuildCount(__mmItem) > 0
    )
      return __mmItem;
  }
  return null;
}
function __mmAntiTrollPredictedPlayer(__mmPlayer, __mmNow) {
  const __mmSid = String(__mmPlayer.sid),
    __mmX = Number(__mmPlayer.x),
    __mmY = Number(__mmPlayer.y);
  let __mmState = __mmAntiTrollMotion[__mmSid];
  if (!__mmState)
    __mmState = __mmAntiTrollMotion[__mmSid] = {
      x: __mmX,
      y: __mmY,
      at: __mmNow,
      vx: 0,
      vy: 0,
    };
  else if (__mmState.x !== __mmX || __mmState.y !== __mmY) {
    const __mmElapsed = Math.max(1, __mmNow - __mmState.at);
    ((__mmState.vx = (__mmX - __mmState.x) / __mmElapsed),
      (__mmState.vy = (__mmY - __mmState.y) / __mmElapsed),
      (__mmState.x = __mmX),
      (__mmState.y = __mmY),
      (__mmState.at = __mmNow));
  }
  const __mmHorizon = Math.min(110, __mmServerTickMs());
  return {
    x: __mmX + __mmState.vx * __mmHorizon,
    y: __mmY + __mmState.vy * __mmHorizon,
  };
}
function __mmAntiTrollPlacement(
  __mmPlacer,
  __mmItem,
  __mmAngle,
  __mmOrigin,
) {
  const __mmData = b && b.list && b.list[__mmItem];
  if (!__mmPlacer || !__mmData || !Number.isFinite(__mmAngle)) return null;
  const __mmScale = Number(__mmData.scale) || 45,
    __mmDistance =
      (Number(__mmPlacer.scale) || 35) +
      __mmScale +
      (Number(__mmData.placeOffset) || 0),
    __mmX = Number(__mmOrigin && __mmOrigin.x),
    __mmY = Number(__mmOrigin && __mmOrigin.y);
  if (!Number.isFinite(__mmX) || !Number.isFinite(__mmY)) return null;
  return {
    x: __mmX + Math.cos(__mmAngle) * __mmDistance,
    y: __mmY + Math.sin(__mmAngle) * __mmDistance,
    angle: __mmAngle,
    scale: __mmScale,
    item: __mmItem,
  };
}
function __mmAntiTrollPositionClear(__mmPlacement, __mmPlacer) {
  if (!__mmPlacement || !y) return !1;
  const __mmScale = __mmPlacement.scale,
    __mmX = __mmPlacement.x,
    __mmY = __mmPlacement.y;
  if (
    __mmX - __mmScale < 0 ||
    __mmY - __mmScale < 0 ||
    __mmX + __mmScale > Number(y.mapScale) ||
    __mmY + __mmScale > Number(y.mapScale) ||
    (__mmPlacement.item !== 18 &&
      __mmY >= y.mapScale / 2 - y.riverWidth / 2 &&
      __mmY <= y.mapScale / 2 + y.riverWidth / 2)
  )
    return !1;
  if (X && typeof X.checkItemLocation === "function")
    try {
      return !!X.checkItemLocation(
        __mmX,
        __mmY,
        __mmScale,
        0.6,
        __mmPlacement.item,
        !1,
        __mmPlacer,
        ge,
      );
    } catch (__mmAntiTrollLocationError) {}
  const __mmObjects = __mmActiveObjectSnapshot().all;
  for (let __mmIndex = 0; __mmIndex < __mmObjects.length; __mmIndex++) {
    const __mmObject = __mmObjects[__mmIndex];
    if (!__mmObject || !__mmObject.active) continue;
    const __mmBlockScale = Number(__mmObject.blocker) ||
      (typeof __mmObject.getScale === "function"
        ? Number(__mmObject.getScale(0.6, __mmObject.isItem))
        : Number(__mmObject.scale)) || 35;
    if (
      Math.hypot(
        Number(__mmObject.x) - __mmX,
        Number(__mmObject.y) - __mmY,
      ) <
      __mmScale + __mmBlockScale
    )
      return !1;
  }
  return !0;
}
function __mmAntiTrollThreat() {
  if (!v || !v.alive || !Array.isArray(E)) return null;
  const __mmNow = Date.now();
  let __mmBest = null,
    __mmBestDistance = Infinity;
  for (let __mmIndex = 0; __mmIndex < E.length; __mmIndex++) {
    const __mmPlayer = E[__mmIndex],
      __mmBuild = Number(__mmPlayer && __mmPlayer.buildIndex),
      __mmData = b && b.list && b.list[__mmBuild];
    if (
      !__mmPlayer ||
      !__mmPlayer.alive ||
      !__mmPlayer.visible ||
      __mmPlayer === v ||
      !__mmSameTeam(__mmPlayer) ||
      !__mmData ||
      String(__mmData.name || "").trim().toLowerCase() !== "teleporter" ||
      !Number.isFinite(Number(__mmPlayer.dir))
    )
      continue;
    const __mmDistance = Math.hypot(
      Number(__mmPlayer.x) - Number(v.x),
      Number(__mmPlayer.y) - Number(v.y),
    );
    if (__mmDistance > 190 || __mmDistance >= __mmBestDistance) continue;
    const __mmPredicted = __mmAntiTrollPredictedPlayer(__mmPlayer, __mmNow),
      __mmTheirPlacement = __mmAntiTrollPlacement(
        __mmPlayer,
        __mmBuild,
        Number(__mmPlayer.dir),
        __mmPredicted,
      ),
      __mmHitboxRange =
        (Number(v.scale) || 35) +
        (Number(__mmTheirPlacement && __mmTheirPlacement.scale) || 45) * 0.55;
    if (
      !__mmTheirPlacement ||
      Math.hypot(
        __mmTheirPlacement.x - Number(v.x),
        __mmTheirPlacement.y - Number(v.y),
      ) > __mmHitboxRange ||
      !__mmAntiTrollPositionClear(__mmTheirPlacement, __mmPlayer)
    )
      continue;
    ((__mmBest = {
      player: __mmPlayer,
      predicted: __mmPredicted,
    }),
      (__mmBestDistance = __mmDistance));
  }
  return __mmBest;
}
function __mmAntiTrollCounterPlan(__mmThreat) {
  const __mmItem = __mmThreatTeleporterItem(),
    __mmData = __mmItem == null ? null : b && b.list && b.list[__mmItem],
    __mmLimit = __mmBuildGroupLimit(__mmData),
    __mmPlaced =
      __mmData && __mmData.group
        ? Number(v.itemCounts && v.itemCounts[__mmData.group.id]) || 0
        : 0;
  if (
    !__mmThreat ||
    __mmItem == null ||
    !__mmCanUseBuildItem(__mmItem) ||
    __mmMaxBuildCount(__mmItem) < 1 ||
    (__mmLimit && __mmPlaced >= __mmLimit)
  )
    return null;
  const __mmAngle = Math.atan2(
      __mmThreat.predicted.y - Number(v.y),
      __mmThreat.predicted.x - Number(v.x),
    ),
    __mmPlacement = __mmAntiTrollPlacement(
      v,
      __mmItem,
      __mmAngle,
      { x: v.x, y: v.y },
    ),
    __mmTouchRange =
      (Number(__mmThreat.player.scale) || 35) +
      (Number(__mmPlacement && __mmPlacement.scale) || 45) * 0.55;
  if (
    !__mmPlacement ||
    Math.hypot(
      __mmPlacement.x - __mmThreat.predicted.x,
      __mmPlacement.y - __mmThreat.predicted.y,
    ) > __mmTouchRange ||
    !__mmAntiTrollPositionClear(__mmPlacement, v)
  )
    return null;
  return __mmPlacement;
}
function __mmUpdateAntiTroll() {
  if (
    !__mmAntiTrollEnabled ||
    document.hidden ||
    !v ||
    !v.alive ||
    v.lockMove ||
    __mmIsTrapped() ||
    __mmInsta.isActive() ||
    __mmBoostInsta.isActive() ||
    __mmTrapAttackActive ||
    __mmBoostBreakHeld ||
    __mmBuildSpamTimer ||
    __mmFoodSpamTimer
  )
    return;
  const __mmThreat = __mmAntiTrollThreat();
  if (!__mmThreat) {
    __mmAntiTrollLatchedSid = null;
    return;
  }
  const __mmSid = String(__mmThreat.player.sid);
  if (
    __mmAntiTrollLatchedSid === __mmSid ||
    Date.now() - __mmAntiTrollLastAt < __mmServerTickMs()
  )
    return;
  const __mmPlan = __mmAntiTrollCounterPlan(__mmThreat);
  if (!__mmPlan) return;
  (__mmActionOwner === "weaponRecharge" && __mmPauseWeaponRecharge(!0),
    __mmActionOwner === "instaSync" && __mmStopInstaSync(),
    __mmActionOwner === "matThief" &&
      __mmFinishMatThief("anti troll"),
    __mmActionOwner === "mobSteal" &&
      __mmFinishMobSteal("anti troll"));
  if (!__mmActionClaim("antiTroll", "teammate teleporter counter")) return;
  const __mmTool = __mmSelectedTool();
  try {
    if (!__mmSendAutomaticPlacement(__mmPlan.item, __mmPlan.angle, __mmTool))
      return;
    (
      (__mmAntiTrollLastAt = Date.now()),
      (__mmAntiTrollLatchedSid = __mmSid),
      __mmScheduleMouseAimReturn());
  } finally {
    (__mmTool != null && __mmRestoreTool(__mmTool),
      __mmResumeHeldAttack(),
      __mmActionRelease("antiTroll", "counter placed"));
  }
}
function __mmStartAntiTroll() {
  (__mmEnsureOperationPipeline(), __mmUpdateAntiTroll());
}
function __mmStopAntiTroll() {
  (__mmAntiTrollTimer && clearInterval(__mmAntiTrollTimer),
    (__mmAntiTrollTimer = 0),
    (__mmAntiTrollLatchedSid = null));
  for (const __mmSid in __mmAntiTrollMotion)
    delete __mmAntiTrollMotion[__mmSid];
  __mmActionRelease("antiTroll", "disabled");
}
function __mmThreatTrapAnimalName(__mmAnimal) {
  return String((__mmAnimal && __mmAnimal.name) || "").trim().toLowerCase();
}
function __mmThreatAnimalIsWolf(__mmAnimal) {
  return __mmThreatTrapAnimalName(__mmAnimal) === "wolf";
}
function __mmThreatItemIsPitTrap(__mmItem) {
  const __mmData = b && b.list && b.list[__mmItem];
  return !!(__mmData && __mmData.trap);
}
function __mmThreatTeleporterAnimalAllowed(__mmAnimal) {
  const __mmName = __mmThreatTrapAnimalName(__mmAnimal);
  return !!(
    __mmAnimal &&
    __mmAnimal.active &&
    __mmAnimal.alive &&
    __mmAnimal.visible &&
    (__mmName === "moostafa" || __mmName === "moofie")
  );
}
function __mmThreatTrapAnimalAllowed(__mmAnimal) {
  if (
    !__mmAnimal ||
    !__mmAnimal.active ||
    !__mmAnimal.alive ||
    !__mmAnimal.visible ||
    !__mmAnimal.hostile
  )
    return !1;
  const __mmName = __mmThreatTrapAnimalName(__mmAnimal);
  return __mmName !== "moostafa" && __mmName !== "moofie";
}
function __mmPassiveMobTrapAnimalAllowed(__mmAnimal) {
  if (
    !__mmAnimal ||
    !__mmAnimal.active ||
    !__mmAnimal.alive ||
    !__mmAnimal.visible ||
    __mmAnimal.hostile
  )
    return !1;
  const __mmName = __mmThreatTrapAnimalName(__mmAnimal);
  return __mmName !== "moostafa" && __mmName !== "moofie";
}
function __mmPassiveMobTrapPrediction(__mmAnimal) {
  const __mmX = Number(__mmAnimal && __mmAnimal.x),
    __mmY = Number(__mmAnimal && __mmAnimal.y),
    __mmElapsed = Number(__mmAnimal && __mmAnimal.t2) -
      Number(__mmAnimal && __mmAnimal.t1),
    __mmVelocityX =
      (Number(__mmAnimal && __mmAnimal.x2) -
        Number(__mmAnimal && __mmAnimal.x1)) /
      __mmElapsed,
    __mmVelocityY =
      (Number(__mmAnimal && __mmAnimal.y2) -
        Number(__mmAnimal && __mmAnimal.y1)) /
      __mmElapsed,
    __mmPing = Number(window.pingTime),
    __mmLead = Math.min(
      150,
      __mmServerTickMs() +
        (Number.isFinite(__mmPing) ? Math.max(0, __mmPing) * 0.5 : 0),
    ),
    __mmUseVelocity = !!(
      Number.isFinite(__mmVelocityX) &&
      Number.isFinite(__mmVelocityY) &&
      __mmElapsed > 0 &&
      __mmElapsed <= 500
    ),
    __mmLeadX = __mmUseVelocity ? __mmVelocityX * __mmLead : 0,
    __mmLeadY = __mmUseVelocity ? __mmVelocityY * __mmLead : 0,
    __mmLeadDistance = Math.hypot(__mmLeadX, __mmLeadY),
    __mmScale = __mmLeadDistance > 24 ? 24 / __mmLeadDistance : 1;
  return {
    x: __mmX + __mmLeadX * __mmScale,
    y: __mmY + __mmLeadY * __mmScale,
  };
}
function __mmThreatTargetKey(__mmTarget) {
  if (!__mmTarget) return null;
  const __mmId =
    __mmTarget.sid != null
      ? __mmTarget.sid
      : __mmTarget.id != null
        ? __mmTarget.id
        : __mmTarget.index != null
          ? __mmTarget.index
          : null;
  return __mmId == null ? null : String(__mmId);
}
function __mmRememberThreatTrap(__mmTarget, __mmItem, __mmAngle) {
  const __mmKey = __mmThreatTargetKey(__mmTarget),
    __mmData = b && b.list && b.list[__mmItem];
  if (!__mmKey || !__mmData || !__mmData.trap || !v) return;
  const __mmPlaceDistance =
      (Number(v.scale) || 35) +
      (Number(__mmData.scale) || 50) +
      (Number(__mmData.placeOffset) || 0),
    __mmCollisionScale = Math.max(
      10,
      (Number(__mmData.scale) || 50) * (Number(__mmData.colDiv) || 1),
    );
  __mmThreatTrapPlacements[__mmKey] = {
    x: v.x + Math.cos(__mmAngle) * __mmPlaceDistance,
    y: v.y + Math.sin(__mmAngle) * __mmPlaceDistance,
    scale: __mmCollisionScale,
    // Keep only a brief acknowledgement bridge; never retain a stale target
    // position after a death or despawn.
    expiresAt: Date.now() + 2500,
  };
}
function __mmThreatAlreadyTrapped(__mmTarget) {
  if (
    !__mmTarget ||
    !Number.isFinite(Number(__mmTarget.x)) ||
    !Number.isFinite(Number(__mmTarget.y))
  )
    return !1;
  const __mmKey = __mmThreatTargetKey(__mmTarget),
    __mmPending = __mmKey && __mmThreatTrapPlacements[__mmKey];
  if (__mmPending) {
    if (Date.now() < Number(__mmPending.expiresAt)) return !0;
    delete __mmThreatTrapPlacements[__mmKey];
  }
  const __mmTraps = __mmActiveTrapObjects();
  for (let __mmIndex = __mmTraps.length - 1; __mmIndex >= 0; __mmIndex--) {
    const __mmTrap = __mmTraps[__mmIndex];
    if (
      __mmTrap &&
      __mmTrap.active &&
      __mmTrap.trap &&
      __mmSpikeHostileToEnemy(__mmTrap, __mmTarget) &&
      __mmServerTrapContact(__mmTarget, __mmTrap)
    )
      return !0;
  }
  return !1;
}
function __mmThreatTrapTarget(__mmTrap, __mmTeleporter, __mmPassiveTrap) {
  if (!v || !v.alive) return null;
  const __mmAnimals = __mmLiveStateFresh() ? __mmLiveState.animals : N;
  let __mmClosest = null,
    __mmClosestDistance = Infinity;
  const __mmConsider = function (
    __mmTarget,
    __mmType,
    __mmItem,
    __mmRange,
    __mmAimPoint,
  ) {
    if (
      !__mmTarget ||
      __mmThreatAlreadyTrapped(__mmTarget) ||
      !Number.isFinite(Number(__mmTarget.x)) ||
      !Number.isFinite(Number(__mmTarget.y))
    )
      return;
    const __mmDistance = Math.hypot(__mmTarget.x - v.x, __mmTarget.y - v.y);
    if (__mmDistance > __mmRange || __mmDistance >= __mmClosestDistance)
      return;
    const __mmId =
      __mmTarget.sid != null
        ? __mmTarget.sid
        : __mmTarget.id != null
          ? __mmTarget.id
          : __mmTarget.index != null
            ? __mmTarget.index
            : Math.round(__mmTarget.x) + ":" + Math.round(__mmTarget.y);
    ((__mmClosest = {
      target: __mmTarget,
      key: __mmType + ":" + __mmId,
      item: __mmItem,
      distance: __mmDistance,
      aimX:
        __mmAimPoint && Number.isFinite(Number(__mmAimPoint.x))
          ? Number(__mmAimPoint.x)
          : Number(__mmTarget.x),
      aimY:
        __mmAimPoint && Number.isFinite(Number(__mmAimPoint.y))
          ? Number(__mmAimPoint.y)
          : Number(__mmTarget.y),
    }),
      (__mmClosestDistance = __mmDistance));
  };
  if (Array.isArray(__mmAnimals))
    for (let __mmIndex = 0; __mmIndex < __mmAnimals.length; __mmIndex++) {
      const __mmAnimal = __mmAnimals[__mmIndex];
      __mmTrap != null &&
        __mmThreatTrapAnimalAllowed(__mmAnimal) &&
        // Wolves are easy melee kills and flee after spike damage. They are
        // still trapped normally whenever the chosen item is a real pit trap.
        (!__mmThreatAnimalIsWolf(__mmAnimal) ||
          __mmThreatItemIsPitTrap(__mmTrap)) &&
        __mmConsider(
          __mmAnimal,
          "animal",
          __mmTrap,
          __mmThreatAnimalRange,
        );
      __mmTeleporter != null &&
        __mmThreatTeleporterAnimalAllowed(__mmAnimal) &&
        __mmConsider(
          __mmAnimal,
          "teleporter",
          __mmTeleporter,
          __mmThreatAnimalRange,
        );
    }
  // Passive trapping is opportunistic. Never let a neutral mob steal this
  // placement phase from hostile-animal defense or a boss Teleporter.
  if (!__mmClosest && __mmPassiveTrap != null && Array.isArray(__mmAnimals))
    for (let __mmIndex = 0; __mmIndex < __mmAnimals.length; __mmIndex++) {
      const __mmAnimal = __mmAnimals[__mmIndex];
      if (!__mmPassiveMobTrapAnimalAllowed(__mmAnimal)) continue;
      __mmConsider(
        __mmAnimal,
        "passive-animal",
        __mmPassiveTrap,
        __mmPassiveMobTrapRange,
        __mmPassiveMobTrapPrediction(__mmAnimal),
      );
    }
  return __mmClosest;
}
function __mmPlaceThreatTrap() {
  if (
    (!__mmThreatTrapEnabled &&
      !__mmPassiveMobTrapEnabled &&
      !__mmBossTeleporterEnabled) ||
    !v ||
    !v.alive ||
    v.lockMove ||
    __mmInsta.isActive() ||
    __mmTrapAttackActive ||
    __mmBoostBreakHeld ||
    __mmBuildSpamTimer ||
    __mmFoodSpamTimer
  )
    return !1;
  const __mmTrap = __mmThreatTrapItem(),
    __mmPassiveTrap = __mmPassiveMobTrapItem(),
    __mmTeleporter = __mmBossTeleporterEnabled
      ? __mmThreatTeleporterItem()
      : null,
    __mmThreat = __mmThreatTrapTarget(
      __mmTrap,
      __mmTeleporter,
      __mmPassiveTrap,
    ),
    __mmNow = Date.now();
  if (
    !__mmThreat ||
    (__mmThreat.key === __mmThreatTrapLastKey &&
      __mmNow - __mmThreatTrapLastAt < __mmThreatTrapCooldownMs)
  )
    return !1;
  // Build placement is angle-based and always occurs at the player's placement
  // radius, so aiming at the threat puts the defensive item between us.
  const __mmAngle = Math.atan2(
      __mmThreat.aimY - v.y,
      __mmThreat.aimX - v.x,
    ),
    __mmPlacement = __mmSmartNearestLegalCandidate(
      __mmThreat.item,
      __mmAngle,
      0.72,
      0.04,
    ),
    __mmTool = __mmSelectedTool();
  if (!__mmPlacement) return !1;
  const __mmPlacementAngle = __mmPlacement.angle;
  ((__mmPlacement.points = 10),
    (__mmPlacement.priority = !0),
    __mmSmartSetPlacementPreview(
      [__mmPlacement],
      [__mmPlacement],
      __mmThreat.key.startsWith("teleporter:")
        ? "boss teleporter"
        : __mmThreat.key.startsWith("passive-animal:")
          ? "passive mob trap"
        : "animal trap",
    ));
  // Only take action ownership after a real, non-cooled-down threat and a
  // currently legal build position both exist.
  if (
    !__mmActionClaim(
      "threatTrap",
      __mmThreat.key.startsWith("passive-animal:")
        ? "nearby passive mob"
        : "nearby hostile animal",
    )
  )
    return !1;
  try {
    if (
      !__mmSendAutomaticPlacement(
        __mmThreat.item,
        __mmPlacementAngle,
        __mmTool,
      )
    )
      throw new Error("automatic placement rejected locally");
    (
      __mmRememberThreatTrap(
        __mmThreat.target,
        __mmThreat.item,
        __mmPlacementAngle,
      ),
      (__mmThreatTrapLastAt = __mmNow),
      (__mmThreatTrapLastKey = __mmThreat.key),
      __mmActionRelease("threatTrap", "placed"));
    return !0;
  } catch (__mmThreatTrapError) {
    return (
      __mmRestoreTool(__mmTool),
      __mmResumeHeldAttack(),
      __mmActionRelease("threatTrap", "placement failed"),
      !1
    );
  }
}
function __mmStartThreatTrap() {
  __mmEnsureOperationPipeline();
}
function __mmStopThreatTrapLoop() {
  (__mmThreatTrapTimer && clearInterval(__mmThreatTrapTimer),
    (__mmThreatTrapTimer = 0));
}
function __mmNearestEnemy() {
  if (!v || !v.alive) return null;
  if (__mmLiveStateFresh()) return __mmLiveState.nearestEnemy;
  let __mmClosest = null,
    __mmClosestDistance = Infinity;
  for (let __mmPlayerIndex = 0; __mmPlayerIndex < E.length; __mmPlayerIndex++) {
    const __mmPlayer = E[__mmPlayerIndex];
    if (!__mmIsEnemyPlayer(__mmPlayer)) continue;
    const __mmDx = __mmPlayer.x - v.x,
      __mmDy = __mmPlayer.y - v.y,
      __mmDistance = __mmDx * __mmDx + __mmDy * __mmDy;
    if (__mmDistance < __mmClosestDistance) {
      ((__mmClosestDistance = __mmDistance), (__mmClosest = __mmPlayer));
    }
  }
  return __mmClosest;
}
function __mmWeaponReady(__mmWeapon) {
  if (!v || !v.alive || __mmWeapon == null) return !1;
  if (__mmWeaponIsReloading(__mmWeapon)) return !1;
  const __mmReload = v.reloads && Number(v.reloads[__mmWeapon]);
  return !Number.isFinite(__mmReload) || __mmReload <= 0;
}
function __mmBoostBreakWeapon() {
  if (!v || !v.weapons) return null;
  if (v.weapons.includes(__mmGreatHammer)) return __mmGreatHammer;
  const __mmMainWeapon = v.weapons[0];
  return __mmMainWeapon === __mmKatana || __mmMainWeapon === __mmPolearmWeapon
    ? __mmMainWeapon
    : null;
}
function __mmCanBoostBreak() {
  const __mmPad = __mmBoostPadItem();
  return !!(
    v &&
    v.alive &&
    v.skins &&
    v.skins[40] &&
    __mmPad != null &&
    !__mmHasPitTrap() &&
    __mmCanUseBuildItem(__mmPad) &&
    __mmBoostBreakWeapon() != null &&
    !__mmInsta.isActive() &&
    !__mmPrimaryHeld &&
    !__mmSecondaryHeld &&
    !__mmTrapAttackActive
  );
}
function __mmBoostBreakWeaponReady() {
  const __mmWeapon = __mmBoostBreakWeapon(),
    __mmReload = v && v.reloads && Number(v.reloads[__mmWeapon]);
  if (__mmWeapon == null || (Number.isFinite(__mmReload) && __mmReload > 0))
    return !1;
  return !(
    __mmBoostBreakCooldownWeapon === __mmWeapon &&
    Date.now() < __mmBoostBreakReadyAt
  );
}
function __mmShuffleBoostChat() {
  __mmBoostChatOrder = __mmBoostChatLines.slice();
  for (
    let __mmIndex = __mmBoostChatOrder.length - 1;
    __mmIndex > 0;
    __mmIndex--
  ) {
    const __mmRandom = Math.floor(Math.random() * (__mmIndex + 1)),
      __mmSwap = __mmBoostChatOrder[__mmIndex];
    ((__mmBoostChatOrder[__mmIndex] = __mmBoostChatOrder[__mmRandom]),
      (__mmBoostChatOrder[__mmRandom] = __mmSwap));
  }
  __mmBoostChatIndex = 0;
}
function __mmSendChat(__mmMessage) {
  typeof on === "function" &&
    typeof __mmMessage === "string" &&
    on(__mmMessage.slice(0, 30));
}
let __mmMaterialReplyLastAt = 0;
function __mmChatMentionsMaterials(__mmMessage) {
  if (typeof __mmMessage !== "string") return !1;
  const __mmWords = __mmMessage
    .toLowerCase()
    .replace(/[@4]/g, "a")
    .replace(/1/g, "i")
    .replace(/3/g, "e")
    .replace(/0/g, "o")
    .replace(/5/g, "s")
    .replace(/7/g, "t")
    .replace(/[^a-z]+/g, " ")
    .trim();
  return /(?:^|\s)(?:mats?|materials?|resources?|res|supplies|wood|stone)(?:\s|$)/.test(
    __mmWords,
  );
}
function __mmReplyToMaterialRequest(__mmPlayerSid, __mmMessage) {
  if (
    !__mmMaterialReplyEnabled ||
    !v ||
    !v.alive ||
    __mmPlayerSid == null ||
    String(__mmPlayerSid) === String(v.sid) ||
    !__mmChatMentionsMaterials(__mmMessage)
  )
    return;
  let __mmPlayer = null;
  try {
    __mmPlayer = Rt(__mmPlayerSid);
  } catch (__mmLookupError) {}
  if (
    !__mmPlayer ||
    (!__mmSameTeam(__mmPlayer) && !__mmIsFriendPlayer(__mmPlayer))
  )
    return;
  const __mmNow = Date.now(),
    __mmCooldown = Math.max(2500, (Number(y && y.chatCooldown) || 500) * 2);
  if (__mmNow - __mmMaterialReplyLastAt < __mmCooldown) return;
  const __mmWood = Math.max(0, Math.floor(Number(v.wood) || 0)),
    __mmStone = Math.max(0, Math.floor(Number(v.stone) || 0));
  ((__mmMaterialReplyLastAt = __mmNow),
    __mmSendChat("Wood " + __mmWood + " Stone " + __mmStone));
}
let __mmModReplyLastAt = 0;
const __mmModReplyText = "kitty klient v${KITTY_KLIENT_VERSION}",
  __mmModReplyCooldownMs = 5000;
function __mmChatMentionsMod(__mmMessage) {
  if (typeof __mmMessage !== "string") return !1;
  const __mmNormalized = __mmMessage
      .toLowerCase()
      .replace(/[@4]/g, "a")
      .replace(/1/g, "i")
      .replace(/3/g, "e")
      .replace(/0/g, "o")
      .replace(/5/g, "s")
      .replace(/7/g, "t"),
    __mmWords = __mmNormalized.replace(/[^a-z]+/g, " ").trim(),
    __mmCompact = __mmNormalized.replace(/[^a-z]+/g, "");
  // Match direct questions and casual accusations without depending on exact
  // phrasing or punctuation. Distinctive compact forms also catch "h a c k"
  // and similarly spaced-out attempts.
  return !!(
    /(?:^|\s)(?:mod(?:s|ded)?|hack(?:s|er|ing|ed)?|hax|client|klient|macro(?:s)?|script(?:s|ed)?|userscript|cheat(?:s|er|ing|ed)?|tampermonkey)(?:\s|$)/.test(
      __mmWords,
    ) ||
    /(?:hack|hax|client|klient|macro|userscript|tampermonkey)/.test(
      __mmCompact,
    )
  );
}
function __mmReplyToModQuestion(__mmPlayerSid, __mmMessage) {
  if (
    !__mmModReplyChatEnabled ||
    !v ||
    !v.alive ||
    __mmPlayerSid === v.sid ||
    !__mmChatMentionsMod(__mmMessage)
  )
    return;
  const __mmNow = Date.now();
  if (__mmNow - __mmModReplyLastAt < __mmModReplyCooldownMs) return;
  ((__mmModReplyLastAt = __mmNow), __mmSendChat(__mmModReplyText));
}
function __mmBoostBreakInputHeld() {
  return __mmBindingActionHeld("boostBreak") || __mmShiftHeld();
}
let __mmMeowChainLastAt = 0;
function __mmTryMeowChainInsta(__mmPlayerSid, __mmMessage) {
  if (
    !__mmMeowChainInstaEnabled ||
    String(__mmMessage || "").trim() !== "Meow!" ||
    !v ||
    !v.alive ||
    String(__mmPlayerSid) === String(v.sid)
  )
    return !1;
  const __mmPlayer = __mmChatPlayer(__mmPlayerSid),
    __mmRecent = __mmRecentPlayerSwings[String(__mmPlayerSid)],
    __mmNow = Date.now();
  if (
    !__mmPlayer ||
    !__mmPlayer.alive ||
    !__mmPlayer.visible ||
    (!__mmSameTeam(__mmPlayer) && !__mmIsFriendPlayer(__mmPlayer)) ||
    !__mmRecent ||
    __mmNow - Number(__mmRecent.at || 0) > 2500 ||
    __mmNow - __mmMeowChainLastAt < 750 ||
    !__mmInsta.canAutoStart(!0)
  )
    return !1;
  const __mmTarget = __mmInsta.nearestEnemy();
  if (!__mmTarget || !__mmInsta.canFullBurst(__mmTarget)) return !1;
  __mmMeowChainLastAt = __mmNow;
  return __mmInsta.start({
    automatic: !0,
    targetSid: __mmTarget.sid,
  });
}
function __mmSendBoostChat() {
  if (!__mmBoostBreakHeld || !__mmBoostBreakInputHeld() || !v || !v.alive) return;
  if (!__mmBoostChatOrder.length) __mmShuffleBoostChat();
  __mmSendChat(
    __mmBoostChatOrder[__mmBoostChatIndex++ % __mmBoostChatOrder.length],
  );
}
function __mmStartBoostChat() {
  if (!__mmBoostChatEnabled || __mmBoostChatTimer) return;
  (__mmShuffleBoostChat(),
    __mmSendBoostChat(),
    (__mmBoostChatTimer = setInterval(
      __mmSendBoostChat,
      Math.max(550, Number(y.chatCooldown) || 500),
    )));
}
function __mmStopBoostChat() {
  (__mmBoostChatTimer &&
    (clearInterval(__mmBoostChatTimer), (__mmBoostChatTimer = 0)),
    __mmShuffleBoostChat());
}
function __mmStartBoostForward(__mmAngle) {
  ((__mmBoostMoveDirection = __mmAngle),
    O.send("9", __mmAngle),
    (Kt = __mmAngle));
}
function __mmFinishBoostBreakGear() {
  if (!v || !v.alive) return;
  const __mmEnemyNearby = __mmEnemyWithinCombatRange(),
    __mmTail =
      !__mmEnemyNearby && v.tails && v.tails[11] && v.tailIndex !== 11
        ? 11
        : __mmEnemyNearby && !__mmHasStick() && v.tailIndex === 11
          ? 0
          : null,
    __mmSpeed = __mmSpeedHat();
  let __mmHat = null;
  if (!__mmEnemyNearby && v.skins && v.skins[__mmSpeed]) __mmHat = __mmSpeed;
  else if (
    __mmBoostTankPreviousHat != null &&
    v.skinIndex === 40 &&
    __mmCanEquipHat(__mmBoostTankPreviousHat)
  )
    __mmHat = __mmBoostTankPreviousHat;
  else if (
    __mmInSnowBiome() &&
    v.skins &&
    v.skins[__mmBoosterHat] &&
    v.skinIndex !== __mmBoosterHat
  )
    __mmHat = __mmBoosterHat;
  __mmEquipGearPair(__mmHat, __mmTail, !0);
}
function __mmSelectBoostBreakWeapon(__mmWeapon) {
  if (!v || !v.weapons || !v.weapons.includes(__mmWeapon)) return !1;
  return ((__mmLastWeapon = __mmWeapon), je(__mmWeapon, !0), !0);
}
function __mmFinishBoostBreakStrike(__mmWeapon, __mmAngle) {
  __mmBoostBreakStrikeTimer = 0;
  const __mmPreviousWeapon = __mmBoostBreakPreviousWeapon,
    __mmDestroyAngle = Math.atan2(
      Math.sin(Number(__mmAngle) + Math.PI),
      Math.cos(Number(__mmAngle) + Math.PI),
    );
  __mmBoostBreakPreviousWeapon = null;
  if (!__mmBoostBreakHeld || !v || !v.alive)
    return void (__mmBoostBreakStriking = !1);
  (__mmSelectBoostBreakWeapon(__mmWeapon) &&
    (__mmTankRightClickEnabled &&
      v.skins &&
      v.skins[40] &&
      __mmActivateCombatHat(40),
    // Packet order is deliberate: face behind, destroy the pad behind the
    // boosted player, release, then restore the original forward aim without
    // changing the forward movement direction.
    O.send("D", __mmDestroyAngle),
    (It = __mmDestroyAngle),
    O.send("F", 1, __mmDestroyAngle),
    O.send("F", 0, __mmDestroyAngle),
    O.send("D", __mmAngle),
    (It = __mmAngle)),
    __mmRestoreWeapon(__mmPreviousWeapon),
    __mmFinishBoostBreakGear(),
    (__mmBoostBreakCooldownWeapon = __mmWeapon),
    (__mmBoostBreakReadyAt =
      Date.now() + Math.max(1, Number(b.weapons[__mmWeapon].speed) || 400)),
    (__mmBoostBreakStriking = !1));
}
function __mmBoostBreakTick() {
  if (__mmBoostBreakStriking) return;
  if (!__mmBoostBreakHeld || !__mmBoostBreakInputHeld() || !__mmCanBoostBreak())
    return void __mmStopBoostBreak();
  if (!__mmBoostBreakWeaponReady()) return;
  const __mmPad = __mmBoostPadItem();
  if (__mmPad == null || !__mmCanUseBuildItem(__mmPad))
    return void __mmStopBoostBreak();
  const __mmWeapon = __mmBoostBreakWeapon();
  if (__mmWeapon == null) return void __mmStopBoostBreak();
  const __mmAngle = Ci(),
    __mmTail =
      !__mmEnemyWithinCombatRange() &&
      v.tails &&
      v.tails[11] &&
      v.tailIndex !== 11
        ? 11
        : null;
  (__mmPauseSoldierForBreaking(),
    __mmBoostTankPreviousHat == null &&
      (__mmBoostTankPreviousHat = __mmInstaSafeRestoreHat(
        __mmBushRestoreHat(v.skinIndex),
      )),
    __mmEquipGearPair(null, __mmTail, !0),
    je(__mmPad),
    O.send("F", 1, __mmAngle),
    O.send("F", 0, __mmAngle),
    __mmStartBoostForward(__mmAngle),
    (__mmBoostBreakPreviousWeapon = __mmSelectedWeapon()),
    (__mmBoostBreakStriking = !0),
    __mmSelectBoostBreakWeapon(__mmWeapon),
    (__mmBoostBreakStrikeTimer = setTimeout(function () {
      __mmFinishBoostBreakStrike(__mmWeapon, __mmAngle);
    }, __mmServerTickMs())));
}
function __mmStartBoostBreak() {
  __mmInsta.isActive() && __mmInsta.cancel("boost-break");
  if (!__mmBoostBreakEnabled || !__mmBoostBreakInputHeld() || !__mmCanBoostBreak())
    return;
  if (!__mmActionClaim("boostBreak", "shift boost-break")) return;
  ((__mmBoostBreakHeld = !0),
    __mmBoostBreakTimer ||
      (__mmBoostBreakTimer = setInterval(
        __mmBoostBreakTick,
        __mmServerTickMs(),
      )),
    __mmStartBoostChat(),
    __mmBoostBreakTick());
}
function __mmStopBoostBreak() {
  const __mmRestore = __mmActionMayRestore("boostBreak");
  ((__mmBoostBreakHeld = !1),
    __mmBoostBreakTimer &&
      (clearInterval(__mmBoostBreakTimer), (__mmBoostBreakTimer = 0)),
    __mmBoostBreakStrikeTimer &&
      (clearTimeout(__mmBoostBreakStrikeTimer),
      (__mmBoostBreakStrikeTimer = 0)),
    (__mmBoostBreakStriking = !1),
    __mmRestore &&
      __mmBoostBreakPreviousWeapon != null &&
      __mmRestoreWeapon(__mmBoostBreakPreviousWeapon),
    (__mmBoostBreakPreviousWeapon = null),
    __mmStopBoostChat(),
    (__mmBoostBreakCooldownWeapon = null),
    (__mmBoostBreakReadyAt = 0));
  if (__mmRestore && v && v.alive && __mmBoostTankPreviousHat != null) {
    const __mmHat = __mmBoostTankPreviousHat;
    ((__mmBoostTankPreviousHat = null),
      v.skinIndex === 40 && __mmCanEquipHat(__mmHat) && __mmEquipHatNow(__mmHat));
  } else __mmBoostTankPreviousHat = null;
  (__mmBoostMoveDirection != null &&
    ((Kt = null), Tt(), (__mmBoostMoveDirection = null)),
    __mmActionRelease("boostBreak", "boost-break complete"),
    __mmUpdateMovementGear());
}
function __mmStartAutoHeal() {
  __mmEnsureOperationPipeline();
}
function __mmUpdateAutoInsta() {
  if (__mmShiftHeld())
    return !!(
      __mmAutoInstaEnabled &&
      __mmBoostInsta.start({ automatic: !0 })
    );
  return !!(
    __mmInsta.canAutoStart() &&
    __mmInsta.start({ automatic: !0 })
  );
}
function __mmStartAutoInsta() {
  // Auto Insta is intentionally input-assisted. The primary mousedown path
  // calls __mmUpdateAutoInsta; proximity by itself never starts a combo.
  __mmAutoInstaTimer && clearInterval(__mmAutoInstaTimer);
  __mmAutoInstaTimer = 0;
}
function __mmKittyPolearmHammerLoadout() {
  return !!(
    v &&
    v.alive &&
    v.weapons &&
    Number(v.weapons[0]) === __mmPolearmWeapon &&
    Number(v.weapons[1]) === __mmGreatHammer
  );
}
function __mmKittyProfileReady(__mmEnemy, __mmProfile) {
  if (
    !v ||
    !v.alive ||
    !__mmIsEnemyPlayer(__mmEnemy) ||
    __mmInsta.state !== "idle" ||
    !__mmInsta.runtimeReady() ||
    __mmInsta.isPriorityConflict() ||
    !v.skins ||
    !v.skins[7]
  )
    return !1;
  const __mmPrimary = __mmInsta.supportedPrimary();
  if (
    __mmPrimary == null ||
    !__mmWeaponReady(__mmPrimary) ||
    !__mmInsta.inRange(__mmPrimary, __mmEnemy)
  )
    return !1;
  if (__mmProfile === "velTick" || __mmProfile === "autoPush")
    return !!(
      v.skins[__mmTurretGear] &&
      __mmInsta.turretReady()
    );
  const __mmSecondary = v.weapons && v.weapons[1],
    __mmSecondaryData = __mmInsta.weaponData(__mmSecondary);
  if (
    __mmSecondary == null ||
    __mmSecondary === __mmPrimary ||
    __mmSecondary === __mmShieldWeapon ||
    !__mmSecondaryData ||
    __mmSecondaryData.shield ||
    !__mmWeaponReady(__mmSecondary) ||
    !__mmInsta.inRange(__mmSecondary, __mmEnemy)
  )
    return !1;
  return __mmProfile === "polearmAids"
    ? !!v.skins[40]
    : !!(
        v.skins[__mmTurretGear] &&
        __mmInsta.turretReady()
      );
}
function __mmStartKittyProfile(__mmProfile, __mmEnemy, __mmReason) {
  const __mmNow = Date.now();
  if (
    !__mmEnemy ||
    __mmNow - __mmKittyInstaLastAt < Math.max(180, __mmServerTickMs() * 2) ||
    !__mmKittyProfileReady(__mmEnemy, __mmProfile)
  )
    return !1;
  (__mmVelTickMoveAngle != null || __mmActionOwner === "velTickSetup") &&
    __mmStopVelTickInsta("launching " + __mmProfile);
  (__mmAutoPushMoveAngle != null || __mmActionOwner === "autoPushSetup") &&
    __mmStopAutoPushSetup("launching " + __mmProfile);
  const __mmStarted = __mmInsta.start({
    automatic: !0,
    targetSid: __mmEnemy.sid,
    profile: __mmProfile,
    profileSource: __mmReason || "Kitty " + __mmProfile,
    // These profiles already choose their own local tick edge. The shared
    // projectile synchronizer must not insert an extra lead delay.
    syncScheduled: !0,
  });
  __mmStarted && (__mmKittyInstaLastAt = __mmNow);
  return __mmStarted;
}
function __mmKittyBleedReady(__mmEnemy) {
  if (!__mmKittyPolearmHammerLoadout() || !__mmEnemy) return !1;
  const __mmPrimaryVariant = __mmMobStealVariantMultiplier(v.weapons[0]),
    __mmSecondaryVariant = __mmMobStealVariantMultiplier(v.weapons[1]);
  // Use this non-Soldier branch only with the high-damage variants.
  // Keep the same gate so Bleed and Apple cannot race each other.
  return !!(
    Number(__mmEnemy.skinIndex) !== 6 &&
    (__mmPrimaryVariant >= 1.18 ||
      (__mmPrimaryVariant > 1 && __mmSecondaryVariant >= 1.18))
  );
}
function __mmKittyKnockbackContact(__mmEnemy, __mmPrediction) {
  if (!__mmEnemy || !__mmPrediction || __mmAutoSpikeSpamTrapForEnemy(__mmEnemy))
    return null;
  const __mmPrimary = v && v.weapons && v.weapons[0],
    __mmData = b && b.weapons && b.weapons[__mmPrimary],
    __mmKnock = Number(__mmData && __mmData.knock),
    __mmPushDistance = Math.min(
      170,
      Math.max(65, (Number.isFinite(__mmKnock) ? __mmKnock : 0.3) * 165),
    ),
    __mmAngle = Math.atan2(__mmEnemy.y - v.y, __mmEnemy.x - v.x),
    __mmStartX = Number(__mmEnemy.x) +
      Number(__mmPrediction.velocityX || 0) * __mmServerTickMs(),
    __mmStartY = Number(__mmEnemy.y) +
      Number(__mmPrediction.velocityY || 0) * __mmServerTickMs(),
    __mmEndX = __mmStartX + Math.cos(__mmAngle) * __mmPushDistance,
    __mmEndY = __mmStartY + Math.sin(__mmAngle) * __mmPushDistance,
    __mmSpikes = __mmAutoSpikeKillAlliedSpikes(__mmEnemy);
  let __mmBest = null;
  for (let __mmIndex = 0; __mmIndex < __mmSpikes.length; __mmIndex++) {
    const __mmEntry = __mmSpikes[__mmIndex],
      __mmSpike = __mmEntry.object,
      __mmRadius =
        (Number(__mmEnemy.scale) || 35) + (Number(__mmEntry.scale) || 49) + 5,
      __mmCurrentDistance = Math.hypot(
        Number(__mmEnemy.x) - Number(__mmSpike.x),
        Number(__mmEnemy.y) - Number(__mmSpike.y),
      ),
      __mmPathDistanceSquared = __mmSegmentDistanceSquared(
        __mmStartX,
        __mmStartY,
        __mmEndX,
        __mmEndY,
        Number(__mmSpike.x),
        Number(__mmSpike.y),
      );
    if (
      __mmCurrentDistance > __mmRadius - 3 &&
      __mmPathDistanceSquared <= __mmRadius * __mmRadius
    ) {
      const __mmEndDistance = Math.hypot(
        __mmEndX - Number(__mmSpike.x),
        __mmEndY - Number(__mmSpike.y),
      );
      if (!__mmBest || __mmEndDistance < __mmBest.distance)
        __mmBest = {
          spike: __mmSpike,
          distance: __mmEndDistance,
          x: __mmEndX,
          y: __mmEndY,
        };
    }
  }
  return __mmBest;
}
function __mmVelTickSetMovement(__mmAngle) {
  if (!v || !v.alive || !Number.isFinite(__mmAngle)) return;
  const __mmDifference =
    __mmVelTickMoveAngle == null
      ? Infinity
      : Math.abs(
          Math.atan2(
            Math.sin(__mmAngle - __mmVelTickMoveAngle),
            Math.cos(__mmAngle - __mmVelTickMoveAngle),
          ),
        );
  if (__mmDifference < 0.035) return;
  ((__mmVelTickMoveAngle = __mmAngle),
    (Kt = __mmAngle),
    O.send("9", __mmAngle));
}
function __mmStopVelTickInsta(__mmReason) {
  if (__mmVelTickMoveAngle != null && O && typeof O.send === "function") {
    try {
      ((Kt = null), O.send("9", null));
    } catch (__mmVelTickStopError) {}
  }
  ((__mmVelTickMoveAngle = null),
    (__mmVelTickTargetSid = null),
    (__mmVelTickStartedAt = 0),
    __mmActionRelease("velTickSetup", __mmReason || "stopped"));
}
function __mmAutoPushSetMovement(__mmAngle) {
  if (!v || !v.alive || !Number.isFinite(__mmAngle)) return;
  const __mmDifference =
    __mmAutoPushMoveAngle == null
      ? Infinity
      : Math.abs(
          Math.atan2(
            Math.sin(__mmAngle - __mmAutoPushMoveAngle),
            Math.cos(__mmAngle - __mmAutoPushMoveAngle),
          ),
        );
  if (__mmDifference < 0.035) return;
  ((__mmAutoPushMoveAngle = __mmAngle),
    (Kt = __mmAngle),
    O.send("9", __mmAngle));
}
function __mmStopAutoPushSetup(__mmReason) {
  if (__mmAutoPushMoveAngle != null && O && typeof O.send === "function") {
    try {
      ((Kt = null), O.send("9", null));
    } catch (__mmAutoPushStopError) {}
  }
  ((__mmAutoPushMoveAngle = null),
    (__mmAutoPushTargetSid = null),
    (__mmAutoPushRoute = []),
    (__mmAutoPushRouteAt = 0),
    (__mmAutoPushRouteGoalX = null),
    (__mmAutoPushRouteGoalY = null),
    (__mmAutoPushRouteTargetSid = null),
    __mmActionRelease("autoPushSetup", __mmReason || "stopped"));
}
function __mmAutoPushAlliedSpike(__mmEnemy, __mmTrap) {
  if (!__mmEnemy || !__mmTrap) return null;
  const __mmSpikes = __mmAutoSpikeKillAlliedSpikes(__mmEnemy),
    __mmTrapScale =
      typeof __mmTrap.getScale === "function"
        ? Number(__mmTrap.getScale()) || Number(__mmTrap.scale) || 50
        : Number(__mmTrap.scale) || 50;
  let __mmBest = null;
  for (let __mmIndex = 0; __mmIndex < __mmSpikes.length; __mmIndex++) {
    const __mmEntry = __mmSpikes[__mmIndex],
      __mmSpike = __mmEntry.object,
      __mmTrapDistance = Math.hypot(
        Number(__mmSpike.x) - Number(__mmTrap.x),
        Number(__mmSpike.y) - Number(__mmTrap.y),
      ),
      __mmEnemyDistance = Math.hypot(
        Number(__mmSpike.x) - Number(__mmEnemy.x),
        Number(__mmSpike.y) - Number(__mmEnemy.y),
      ),
      __mmNearTrap =
        __mmTrapDistance <=
        __mmTrapScale + (Number(__mmEntry.scale) || 49) + 30;
    if (
      __mmNearTrap &&
      (!__mmBest || __mmEnemyDistance < __mmBest.enemyDistance)
    )
      __mmBest = {
        object: __mmSpike,
        scale: Number(__mmEntry.scale) || 49,
        enemyDistance: __mmEnemyDistance,
      };
  }
  return __mmBest;
}
function __mmAutoPushPathObstacles(__mmGoalX, __mmGoalY, __mmTrap) {
  const __mmObjects = __mmActiveObjectSnapshot().all,
    __mmPlayerScale = Number(v && v.scale) || 35,
    __mmCandidates = [];
  for (let __mmIndex = 0; __mmIndex < __mmObjects.length; __mmIndex++) {
    const __mmObject = __mmObjects[__mmIndex];
    if (
      !__mmObject ||
      !__mmObject.active ||
      __mmObject === __mmTrap ||
      __mmObject.ignoreCollision ||
      !Number.isFinite(Number(__mmObject.x)) ||
      !Number.isFinite(Number(__mmObject.y))
    )
      continue;
    const __mmRadius = __mmThreatObjectScale(__mmObject) + __mmPlayerScale + 7,
      __mmCorridorDistance = Math.sqrt(
        __mmSegmentDistanceSquared(
          Number(v.x),
          Number(v.y),
          __mmGoalX,
          __mmGoalY,
          Number(__mmObject.x),
          Number(__mmObject.y),
        ),
      ),
      __mmEndpointDistance = Math.min(
        Math.hypot(Number(__mmObject.x) - Number(v.x), Number(__mmObject.y) - Number(v.y)),
        Math.hypot(Number(__mmObject.x) - __mmGoalX, Number(__mmObject.y) - __mmGoalY),
      );
    if (__mmCorridorDistance > __mmRadius + 210 && __mmEndpointDistance > 300)
      continue;
    __mmCandidates.push({
      x: Number(__mmObject.x),
      y: Number(__mmObject.y),
      radius: __mmRadius,
      score: Math.min(__mmCorridorDistance, __mmEndpointDistance * 0.7),
    });
  }
  __mmCandidates.sort((__mmA, __mmB) => __mmA.score - __mmB.score);
  return __mmCandidates.slice(0, __mmFpsBoostEnabled ? 7 : 11);
}
function __mmAutoPushSegmentClear(__mmA, __mmB, __mmObstacles) {
  for (let __mmIndex = 0; __mmIndex < __mmObstacles.length; __mmIndex++) {
    const __mmObstacle = __mmObstacles[__mmIndex],
      __mmStartDistance = Math.hypot(
        __mmA.x - __mmObstacle.x,
        __mmA.y - __mmObstacle.y,
      ),
      __mmEndDistance = Math.hypot(
        __mmB.x - __mmObstacle.x,
        __mmB.y - __mmObstacle.y,
      ),
      __mmDistanceSquared = __mmSegmentDistanceSquared(
        __mmA.x,
        __mmA.y,
        __mmB.x,
        __mmB.y,
        __mmObstacle.x,
        __mmObstacle.y,
      );
    // The server can leave a player a few pixels inside our conservative
    // padding. Permit only an outward edge from that starting overlap.
    if (
      __mmStartDistance < __mmObstacle.radius &&
      __mmEndDistance > __mmStartDistance &&
      (__mmB.x - __mmA.x) * (__mmA.x - __mmObstacle.x) +
          (__mmB.y - __mmA.y) * (__mmA.y - __mmObstacle.y) >
        0
    )
      continue;
    if (__mmDistanceSquared < (__mmObstacle.radius - 1) ** 2) return !1;
  }
  return !0;
}
function __mmAutoPushSolveRoute(__mmGoalX, __mmGoalY, __mmTrap) {
  const __mmStart = { x: Number(v.x), y: Number(v.y) },
    __mmGoal = { x: __mmGoalX, y: __mmGoalY },
    __mmObstacles = __mmAutoPushPathObstacles(__mmGoalX, __mmGoalY, __mmTrap);
  if (__mmAutoPushSegmentClear(__mmStart, __mmGoal, __mmObstacles))
    return [__mmGoal];
  const __mmNodes = [__mmStart, __mmGoal],
    __mmMapScale = Number(y && y.mapScale) || Infinity;
  for (let __mmObstacleIndex = 0; __mmObstacleIndex < __mmObstacles.length; __mmObstacleIndex++) {
    const __mmObstacle = __mmObstacles[__mmObstacleIndex];
    for (let __mmStep = 0; __mmStep < 8; __mmStep++) {
      const __mmAngle = (__mmStep * Math.PI) / 4,
        __mmClearance = Math.max(6, __mmObstacle.radius * 0.1),
        __mmNode = {
          x:
            __mmObstacle.x +
            Math.cos(__mmAngle) * (__mmObstacle.radius + __mmClearance),
          y:
            __mmObstacle.y +
            Math.sin(__mmAngle) * (__mmObstacle.radius + __mmClearance),
        };
      if (
        __mmNode.x < 8 ||
        __mmNode.y < 8 ||
        __mmNode.x > __mmMapScale - 8 ||
        __mmNode.y > __mmMapScale - 8
      )
        continue;
      let __mmInside = !1;
      for (let __mmOtherIndex = 0; __mmOtherIndex < __mmObstacles.length; __mmOtherIndex++) {
        const __mmOther = __mmObstacles[__mmOtherIndex];
        if (
          Math.hypot(__mmNode.x - __mmOther.x, __mmNode.y - __mmOther.y) <
          __mmOther.radius - 1
        ) {
          __mmInside = !0;
          break;
        }
      }
      !__mmInside && __mmNodes.push(__mmNode);
    }
  }
  const __mmDistance = new Array(__mmNodes.length).fill(Infinity),
    __mmPrevious = new Array(__mmNodes.length).fill(-1),
    __mmVisited = new Array(__mmNodes.length).fill(!1);
  __mmDistance[0] = 0;
  for (let __mmIteration = 0; __mmIteration < __mmNodes.length; __mmIteration++) {
    let __mmCurrent = -1;
    for (let __mmIndex = 0; __mmIndex < __mmNodes.length; __mmIndex++)
      if (
        !__mmVisited[__mmIndex] &&
        (__mmCurrent < 0 || __mmDistance[__mmIndex] < __mmDistance[__mmCurrent])
      )
        __mmCurrent = __mmIndex;
    if (__mmCurrent < 0 || !Number.isFinite(__mmDistance[__mmCurrent])) break;
    if (__mmCurrent === 1) break;
    __mmVisited[__mmCurrent] = !0;
    for (let __mmNext = 1; __mmNext < __mmNodes.length; __mmNext++) {
      if (
        __mmNext === __mmCurrent ||
        __mmVisited[__mmNext] ||
        !__mmAutoPushSegmentClear(
          __mmNodes[__mmCurrent],
          __mmNodes[__mmNext],
          __mmObstacles,
        )
      )
        continue;
      const __mmCandidate =
        __mmDistance[__mmCurrent] +
        Math.hypot(
          __mmNodes[__mmNext].x - __mmNodes[__mmCurrent].x,
          __mmNodes[__mmNext].y - __mmNodes[__mmCurrent].y,
        );
      if (__mmCandidate < __mmDistance[__mmNext]) {
        ((__mmDistance[__mmNext] = __mmCandidate),
          (__mmPrevious[__mmNext] = __mmCurrent));
      }
    }
  }
  if (!Number.isFinite(__mmDistance[1])) return [];
  const __mmRoute = [];
  for (let __mmCursor = 1; __mmCursor > 0; __mmCursor = __mmPrevious[__mmCursor]) {
    if (__mmCursor < 0) return [];
    __mmRoute.unshift(__mmNodes[__mmCursor]);
  }
  return __mmRoute;
}
function __mmAutoPushWaypoint(__mmGoalX, __mmGoalY, __mmEnemy, __mmTrap) {
  const __mmNow = performance.now(),
    __mmGoalMoved =
      __mmAutoPushRouteGoalX == null ||
      Math.hypot(
        __mmGoalX - __mmAutoPushRouteGoalX,
        __mmGoalY - __mmAutoPushRouteGoalY,
      ) > 12,
    __mmTargetChanged =
      String(__mmAutoPushRouteTargetSid) !== String(__mmEnemy.sid);
  if (
    __mmGoalMoved ||
    __mmTargetChanged ||
    !__mmAutoPushRouteAt ||
    __mmNow - __mmAutoPushRouteAt > 75
  ) {
    ((__mmAutoPushRoute = __mmAutoPushSolveRoute(__mmGoalX, __mmGoalY, __mmTrap)),
      (__mmAutoPushRouteAt = __mmNow),
      (__mmAutoPushRouteGoalX = __mmGoalX),
      (__mmAutoPushRouteGoalY = __mmGoalY),
      (__mmAutoPushRouteTargetSid = __mmEnemy.sid));
  }
  while (
    __mmAutoPushRoute.length > 1 &&
    Math.hypot(
      __mmAutoPushRoute[0].x - Number(v.x),
      __mmAutoPushRoute[0].y - Number(v.y),
    ) <= 18
  )
    __mmAutoPushRoute.shift();
  return __mmAutoPushRoute[0] || null;
}
function __mmUpdateAutoPushSetup(__mmEnemy, __mmTrap) {
  const __mmNow = Date.now();
  if (
    !__mmAutoPushInstaEnabled ||
    __mmNow < __mmAutoPushManualUntil ||
    !__mmEnemy ||
    !__mmTrap ||
    !v ||
    !v.alive ||
    __mmIsTrapped() ||
    __mmPrimaryHeld ||
    __mmSecondaryHeld
  ) {
    __mmStopAutoPushSetup("conditions lost");
    return !1;
  }
  const __mmSpike = __mmAutoPushAlliedSpike(__mmEnemy, __mmTrap);
  if (!__mmSpike) {
    __mmStopAutoPushSetup("no allied push spike");
    return !1;
  }
  const __mmTargetToSpike = Math.atan2(
      Number(__mmSpike.object.y) - Number(__mmEnemy.y),
      Number(__mmSpike.object.x) - Number(__mmEnemy.x),
    ),
    __mmStandDistance =
      (Number(v.scale) || 35) + (Number(__mmEnemy.scale) || 35) + 3,
    __mmStandX =
      Number(__mmEnemy.x) - Math.cos(__mmTargetToSpike) * __mmStandDistance,
    __mmStandY =
      Number(__mmEnemy.y) - Math.sin(__mmTargetToSpike) * __mmStandDistance,
    __mmDistanceToStand = Math.hypot(__mmStandX - v.x, __mmStandY - v.y),
    __mmDistanceToEnemy = Math.hypot(__mmEnemy.x - v.x, __mmEnemy.y - v.y),
    __mmContactRadius =
      (Number(__mmEnemy.scale) || 35) + Number(__mmSpike.scale) + 5,
    __mmAlignedDifference = Math.abs(
      Math.atan2(
        Math.sin(
          Math.atan2(__mmEnemy.y - v.y, __mmEnemy.x - v.x) -
            __mmTargetToSpike,
        ),
        Math.cos(
          Math.atan2(__mmEnemy.y - v.y, __mmEnemy.x - v.x) -
            __mmTargetToSpike,
        ),
      ),
    );
  if (!__mmActionClaim("autoPushSetup", "aligning trapped enemy to spike")) {
    __mmStopAutoPushSetup("alignment blocked");
    return !1;
  }
  __mmAutoPushTargetSid = __mmEnemy.sid;
  if (
    __mmSpike.enemyDistance <= __mmContactRadius + 7 &&
    __mmDistanceToEnemy <= __mmStandDistance + 18 &&
    __mmAlignedDifference <= 0.48 &&
    __mmKittyProfileReady(__mmEnemy, "autoPush")
  ) {
    __mmStopAutoPushSetup("push contact reached");
    return __mmStartKittyProfile(
      "autoPush",
      __mmEnemy,
      "trapped enemy pushed into allied spike",
    );
  }
  const __mmWaypoint =
      __mmDistanceToStand > 18
        ? __mmAutoPushWaypoint(__mmStandX, __mmStandY, __mmEnemy, __mmTrap)
        : null,
    __mmMoveAngle =
      __mmDistanceToStand > 18 && __mmWaypoint
        ? Math.atan2(__mmWaypoint.y - v.y, __mmWaypoint.x - v.x)
        : __mmDistanceToStand <= 18
          ? __mmTargetToSpike
          : null;
  if (!Number.isFinite(__mmMoveAngle)) {
    __mmAutoPushMoveAngle != null &&
      ((__mmAutoPushMoveAngle = null), (Kt = null), O.send("9", null));
    return !0;
  }
  __mmAutoPushSetMovement(__mmMoveAngle);
  return !0;
}
function __mmUpdateVelTickInsta(__mmEnemy) {
  const __mmNow = Date.now();
  if (
    !__mmVelTickInstaEnabled ||
    __mmNow < __mmVelTickManualUntil ||
    !__mmEnemy ||
    !v ||
    !v.alive ||
    Number(v.weapons && v.weapons[0]) !== __mmPolearmWeapon ||
    Number(__mmEnemy.skinIndex) === 6 ||
    Number(__mmEnemy.skinIndex) === 22 ||
    __mmAutoSpikeSpamTrapForEnemy(__mmEnemy) ||
    __mmIsTrapped()
  )
    return void __mmStopVelTickInsta("conditions lost");
  const __mmPing = Number(window.pingTime) || 0,
    __mmMinRange =
      __mmPing > 140 ? 230 : __mmPing > 110 ? 210 : __mmPing > 85 ? 190 : 170,
    __mmMaxRange = 245,
    __mmDistance = Math.hypot(__mmEnemy.x - v.x, __mmEnemy.y - v.y),
    __mmAngle = Math.atan2(__mmEnemy.y - v.y, __mmEnemy.x - v.x);
  if (__mmDistance > 300)
    return void __mmStopVelTickInsta("target too far");
  if (!__mmActionClaim("velTickSetup", "Kitty auto spacing"))
    return void __mmStopVelTickInsta("spacing blocked");
  ((__mmVelTickTargetSid = __mmEnemy.sid),
    __mmVelTickStartedAt || (__mmVelTickStartedAt = __mmNow));
  if (__mmDistance > __mmMaxRange)
    return void __mmVelTickSetMovement(__mmAngle);
  if (__mmDistance < __mmMinRange)
    return void __mmVelTickSetMovement(__mmAngle + Math.PI);
  __mmStopVelTickInsta("spacing complete");
  __mmStartKittyProfile("velTick", __mmEnemy, "VelTick range band");
}
function __mmUpdateKittyInstas() {
  if (
    !v ||
    !v.alive ||
    !Array.isArray(E) ||
    __mmInsta.isActive() ||
    __mmBoostInsta.isActive()
  )
    return;
  const __mmAnyEnabled = !!(
    __mmAppleInstaEnabled ||
    __mmBleedInstaEnabled ||
    __mmKnockbackInstaEnabled ||
    __mmVelTickInstaEnabled ||
    __mmPolearmAidsEnabled ||
    __mmAutoPushInstaEnabled
  );
  if (!__mmAnyEnabled) {
    (__mmStopVelTickInsta("Insta automation disabled"),
      __mmStopAutoPushSetup("Insta automation disabled"));
    return;
  }
  const __mmEnemy = __mmNearestEnemy();
  if (!__mmEnemy) {
    (__mmStopVelTickInsta("no target"),
      __mmStopAutoPushSetup("no target"));
    return;
  }
  const __mmNow = Date.now(),
    __mmPrediction = __mmPredictEnemyNextTick(__mmEnemy, __mmNow),
    __mmPolearmHammer = __mmKittyPolearmHammerLoadout(),
    __mmEnemyTrap = __mmAutoSpikeSpamTrapForEnemy(__mmEnemy);
  if (
    __mmPolearmAidsEnabled &&
    __mmPolearmHammer &&
    __mmEnemyTrap &&
    __mmStartKittyProfile(
      "polearmAids",
      __mmEnemy,
      "enemy caught in allied trap",
    )
  )
    return;
  if (
    __mmAutoPushInstaEnabled &&
    __mmEnemyTrap &&
    __mmUpdateAutoPushSetup(__mmEnemy, __mmEnemyTrap)
  )
    return;
  __mmStopAutoPushSetup("no trapped auto-push target");
  if (
    __mmKnockbackInstaEnabled &&
    __mmPolearmHammer &&
    __mmKittyKnockbackContact(__mmEnemy, __mmPrediction) &&
    __mmStartKittyProfile(
      "knockback",
      __mmEnemy,
      "predicted knockback into allied spike",
    )
  )
    return;
  if (
    __mmAppleInstaEnabled &&
    __mmPolearmHammer &&
    Number(__mmEnemy.skinIndex) === 6 &&
    __mmStartKittyProfile("apple", __mmEnemy, "Soldier-hat Apple Insta")
  )
    return;
  if (
    __mmBleedInstaEnabled &&
    __mmKittyBleedReady(__mmEnemy) &&
    __mmStartKittyProfile("bleed", __mmEnemy, "high-variant Bleed Insta")
  )
    return;
  __mmVelTickInstaEnabled
    ? __mmUpdateVelTickInsta(__mmEnemy)
    : __mmStopVelTickInsta("VelTick disabled");
}
function __mmStartKittyInstas() {
  __mmEnsureOperationPipeline();
}
function __mmRefreshKittyInstaLoop() {
  const __mmWanted = !!(
    __mmAppleInstaEnabled ||
    __mmBleedInstaEnabled ||
    __mmKnockbackInstaEnabled ||
    __mmVelTickInstaEnabled ||
    __mmPolearmAidsEnabled ||
    __mmAutoPushInstaEnabled
  );
  if (__mmWanted) return void __mmStartKittyInstas();
  (__mmKittyInstaTimer && clearInterval(__mmKittyInstaTimer),
    (__mmKittyInstaTimer = 0),
    __mmStopVelTickInsta("Insta automation disabled"),
    __mmStopAutoPushSetup("Insta automation disabled"));
}
function __mmAutoTrapInstaTrapForEnemy(__mmEnemy) {
  if (!v || !v.alive || !__mmEnemy) return null;
  let __mmClosest = null,
    __mmClosestDistance = Infinity;
  const __mmTraps = __mmActiveTrapObjects();
  for (let __mmIndex = 0; __mmIndex < __mmTraps.length; __mmIndex++) {
    const __mmTrap = __mmTraps[__mmIndex];
    if (
      !__mmTrap ||
      !__mmTrap.active ||
      !__mmTrap.trap ||
      !__mmOwnStructure(__mmTrap) ||
      !__mmSpikeHostileToEnemy(__mmTrap, __mmEnemy)
    )
      continue;
    const __mmPosition = __mmServerEntityPosition(__mmEnemy),
      __mmDistance = __mmPosition
        ? Math.hypot(__mmPosition.x - __mmTrap.x, __mmPosition.y - __mmTrap.y)
        : Infinity;
    if (
      __mmServerTrapContact(__mmEnemy, __mmTrap) &&
      __mmDistance < __mmClosestDistance
    )
      ((__mmClosest = __mmTrap), (__mmClosestDistance = __mmDistance));
  }
  return __mmClosest;
}
function __mmAutoTrapInstaCloseEnough(__mmEnemy) {
  const __mmPrimary = __mmInsta.supportedPrimary(),
    __mmData = __mmInsta.weaponData(__mmPrimary);
  if (__mmPrimary == null || !__mmData || !v || !__mmEnemy) return !1;
  const __mmReach =
    (Number(__mmData.range) || 0) +
    (Number(v.scale) || 35) +
    (Number(__mmEnemy.scale) || 35) +
    8;
  return (
    Math.hypot(
      Number(__mmEnemy.x) - Number(v.x),
      Number(__mmEnemy.y) - Number(v.y),
    ) <= __mmReach
  );
}
function __mmAutoTrapInstaTrapActive(__mmTrap) {
  if (!__mmTrap || !__mmTrap.active || !__mmTrap.trap) return !1;
  const __mmKey = __mmTrapBuildKey(__mmTrap),
    __mmTraps = __mmActiveTrapObjects();
  for (let __mmIndex = 0; __mmIndex < __mmTraps.length; __mmIndex++) {
    const __mmCurrent = __mmTraps[__mmIndex];
    if (
      __mmCurrent === __mmTrap ||
      (__mmKey != null && __mmTrapBuildKey(__mmCurrent) === __mmKey)
    )
      return !0;
  }
  return !1;
}
function __mmUpdateAutoTrapInsta() {
  const __mmNow = Date.now(),
    __mmSeen = Object.create(null);
  let __mmBest = null;
  if (
    __mmAutoTrapInstaEnabled &&
    !(__mmPolearmAidsEnabled && __mmKittyPolearmHammerLoadout()) &&
    v &&
    v.alive &&
    Array.isArray(E) &&
    !__mmIsTrapped()
  )
    for (let __mmIndex = 0; __mmIndex < E.length; __mmIndex++) {
      const __mmEnemy = E[__mmIndex];
      if (!__mmIsEnemyPlayer(__mmEnemy)) continue;
      const __mmSid = String(__mmEnemy.sid),
        __mmTrap = __mmAutoTrapInstaTrapForEnemy(__mmEnemy);
      let __mmIncident = __mmAutoTrapInstaIncidents[__mmSid];
      __mmSeen[__mmSid] = !0;
      if (__mmTrap) {
        if (!__mmIncident || __mmIncident.trap !== __mmTrap)
          __mmIncident = __mmAutoTrapInstaIncidents[__mmSid] = {
            trap: __mmTrap,
            trapped: !0,
            catchLatched: !1,
            hammerArmed: !1,
            releasedAt: 0,
            releaseLatched: !1,
            lastSeen: __mmNow,
          };
        ((__mmIncident.trap = __mmTrap),
          (__mmIncident.trapped = !0),
          (__mmIncident.lastSeen = __mmNow),
          Number(v.weapons && v.weapons[1]) === __mmGreatHammer &&
            (__mmIncident.hammerArmed = !0));
        // Great Hammer owns the break-edge combo below. Other secondaries
        // preserve the original immediate caught-player Insta behavior.
        if (
          __mmIncident.hammerArmed ||
          __mmIncident.catchLatched ||
          !__mmAutoTrapInstaCloseEnough(__mmEnemy) ||
          !__mmFullInstaReadyFor(__mmEnemy)
        )
          continue;
        const __mmDistance = Math.hypot(
          Number(__mmEnemy.x) - Number(v.x),
          Number(__mmEnemy.y) - Number(v.y),
        );
        if (!__mmBest || __mmDistance < __mmBest.distance)
          __mmBest = {
            enemy: __mmEnemy,
            incident: __mmIncident,
            release: !1,
            distance: __mmDistance,
          };
        continue;
      }
      if (!__mmIncident) continue;
      __mmIncident.lastSeen = __mmNow;
      if (
        __mmIncident.trapped &&
        !__mmAutoTrapInstaTrapActive(__mmIncident.trap)
      ) {
        ((__mmIncident.trapped = !1),
          (__mmIncident.releasedAt = __mmNow));
      }
      const __mmReleaseWindow = Math.max(450, __mmServerTickMs() * 4);
      if (
        !__mmIncident.hammerArmed ||
        __mmIncident.trapped ||
        __mmIncident.releaseLatched ||
        !__mmIncident.releasedAt ||
        __mmNow - __mmIncident.releasedAt > __mmReleaseWindow ||
        Number(v.weapons && v.weapons[1]) !== __mmGreatHammer ||
        !__mmAutoTrapInstaCloseEnough(__mmEnemy) ||
        !__mmFullInstaReadyFor(__mmEnemy)
      )
        continue;
      const __mmDistance = Math.hypot(
        Number(__mmEnemy.x) - Number(v.x),
        Number(__mmEnemy.y) - Number(v.y),
      );
      if (!__mmBest || __mmDistance < __mmBest.distance)
        __mmBest = {
          enemy: __mmEnemy,
          incident: __mmIncident,
          release: !0,
          distance: __mmDistance,
        };
    }
  if (
    __mmBest &&
    __mmInsta.start({
      automatic: !0,
      targetSid: __mmBest.enemy.sid,
      // The server trap-contact update is already the synchronization edge.
      // Always launch locally: relay tick-sync can otherwise add 250–700 ms,
      // which lets another Katana + Musket client complete its Insta first.
      syncScheduled: !0,
      // Keep the normal Katana -> Musket order but skip normal R's deliberate
      // 120 ms setup pause. Follow-up weapon timing remains unchanged.
      profile: __mmBest.release ? "normal" : "trapCatch",
      profileSource: __mmBest.release ? "trap release" : "trap catch",
    })
  )
    __mmBest.release
      ? (__mmBest.incident.releaseLatched = !0)
      : (__mmBest.incident.catchLatched = !0);
  for (const __mmSid in __mmAutoTrapInstaIncidents) {
    const __mmIncident = __mmAutoTrapInstaIncidents[__mmSid];
    const __mmExpiredRelease = !!(
      __mmIncident.releasedAt &&
      __mmNow - __mmIncident.releasedAt >
        Math.max(600, __mmServerTickMs() * 5)
    );
    if (
      (!__mmSeen[__mmSid] && __mmNow - __mmIncident.lastSeen > 300) ||
      __mmExpiredRelease
    )
      delete __mmAutoTrapInstaIncidents[__mmSid];
  }
}
function __mmStartAutoTrapInsta() {
  __mmEnsureOperationPipeline();
}
function __mmSpikeHostileToEnemy(__mmSpike, __mmEnemy) {
  if (!__mmSpike || !__mmEnemy || !__mmSpike.owner) return !0;
  const __mmOwner = __mmSpike.owner,
    __mmOwnerSid = __mmOwner.sid;
  if (
    __mmOwner === __mmEnemy ||
    String(__mmOwnerSid) === String(__mmEnemy.sid)
  )
    return !1;
  const __mmOwnerPlayer = typeof Rt === "function" ? Rt(__mmOwnerSid) : null,
    __mmOwnerTeam = __mmTeamKey(__mmOwnerPlayer || __mmOwner),
    __mmEnemyTeam = __mmTeamKey(__mmEnemy);
  return !(
    __mmOwnerTeam != null &&
    __mmEnemyTeam != null &&
    __mmOwnerTeam === __mmEnemyTeam
  );
}
function __mmPredictEnemyNextTick(__mmEnemy, __mmNow) {
  const __mmSid = String(__mmEnemy.sid),
    __mmPrevious = __mmAutoSpikeInstaMotion[__mmSid],
    __mmSampleElapsed = __mmPrevious
      ? Math.max(1, Math.min(250, __mmNow - __mmPrevious.at))
      : 0;
  let __mmVelocityX = __mmPrevious
      ? (__mmEnemy.x - __mmPrevious.x) / __mmSampleElapsed
      : 0,
    __mmVelocityY = __mmPrevious
      ? (__mmEnemy.y - __mmPrevious.y) / __mmSampleElapsed
      : 0;
  const __mmServerElapsed = Number(__mmEnemy.t2) - Number(__mmEnemy.t1),
    __mmServerVelocityX =
      (Number(__mmEnemy.x2) - Number(__mmEnemy.x1)) / __mmServerElapsed,
    __mmServerVelocityY =
      (Number(__mmEnemy.y2) - Number(__mmEnemy.y1)) / __mmServerElapsed;
  if (
    Number.isFinite(__mmServerVelocityX) &&
    Number.isFinite(__mmServerVelocityY) &&
    __mmServerElapsed > 0 &&
    __mmServerElapsed <= 500
  ) {
    ((__mmVelocityX = __mmPrevious
      ? __mmServerVelocityX * 0.75 + __mmVelocityX * 0.25
      : __mmServerVelocityX),
      (__mmVelocityY = __mmPrevious
        ? __mmServerVelocityY * 0.75 + __mmVelocityY * 0.25
        : __mmServerVelocityY));
  }
  __mmAutoSpikeInstaMotion[__mmSid] = {
    x: __mmEnemy.x,
    y: __mmEnemy.y,
    at: __mmNow,
  };
  const __mmLeadMs = __mmServerTickMs();
  return {
    x: __mmEnemy.x + __mmVelocityX * __mmLeadMs,
    y: __mmEnemy.y + __mmVelocityY * __mmLeadMs,
    velocityX: __mmVelocityX,
    velocityY: __mmVelocityY,
  };
}
function __mmSegmentDistanceSquared(
  __mmStartX,
  __mmStartY,
  __mmEndX,
  __mmEndY,
  __mmPointX,
  __mmPointY,
) {
  const __mmPathX = __mmEndX - __mmStartX,
    __mmPathY = __mmEndY - __mmStartY,
    __mmLengthSquared = __mmPathX * __mmPathX + __mmPathY * __mmPathY;
  if (__mmLengthSquared <= 1e-6)
    return (
      (__mmPointX - __mmStartX) ** 2 + (__mmPointY - __mmStartY) ** 2
    );
  const __mmProgress = Math.max(
      0,
      Math.min(
        1,
        ((__mmPointX - __mmStartX) * __mmPathX +
          (__mmPointY - __mmStartY) * __mmPathY) /
          __mmLengthSquared,
      ),
    ),
    __mmClosestX = __mmStartX + __mmPathX * __mmProgress,
    __mmClosestY = __mmStartY + __mmPathY * __mmProgress;
  return (
    (__mmPointX - __mmClosestX) ** 2 +
    (__mmPointY - __mmClosestY) ** 2
  );
}
function __mmSpikeOwnedByUsOrAlly(__mmSpike) {
  if (!v || !v.alive || !__mmSpike || !__mmSpike.owner) return !1;
  const __mmOwner = __mmSpike.owner,
    __mmOwnerSid = __mmOwner.sid;
  if (
    __mmOwner === v ||
    (__mmOwnerSid != null && String(__mmOwnerSid) === String(v.sid))
  )
    return !0;
  const __mmOwnerPlayer =
    __mmOwnerSid != null && typeof Rt === "function" ? Rt(__mmOwnerSid) : null;
  return __mmSameTeam(__mmOwnerPlayer || __mmOwner);
}
function __mmEnemyWillHitSpikeNextTick(__mmEnemy, __mmPrediction) {
  const __mmSpeedSquared =
    __mmPrediction.velocityX * __mmPrediction.velocityX +
    __mmPrediction.velocityY * __mmPrediction.velocityY;
  if (__mmSpeedSquared <= 1e-6) return null;
  const __mmPing = Number(window.pingTime),
    __mmHorizonMs = Math.min(
      240,
      __mmServerTickMs() * 1.35 +
        (Number.isFinite(__mmPing) ? Math.max(0, __mmPing / 2) : 0),
    ),
    __mmSpikes = __mmActiveObjectSnapshot().spikes;
  let __mmBestContact = null;
  for (let __mmIndex = 0; __mmIndex < __mmSpikes.length; __mmIndex++) {
    const __mmSpike = __mmSpikes[__mmIndex],
      __mmData = __mmSpike && b.list && b.list[__mmSpike.id],
      __mmName = String(__mmData && __mmData.name || "").toLowerCase();
    if (
      !__mmSpike ||
      !__mmSpike.active ||
      !__mmSpike.isItem ||
      !__mmName.includes("spikes") ||
      !__mmSpikeOwnedByUsOrAlly(__mmSpike) ||
      !__mmSpikeHostileToEnemy(__mmSpike, __mmEnemy)
    )
      continue;
    const __mmCollisionRadius =
        (Number(__mmEnemy.scale) || 35) +
        (Number(__mmSpike.scale) || Number(__mmData.scale) || 45) +
        4,
      __mmOffsetX = Number(__mmEnemy.x) - Number(__mmSpike.x),
      __mmOffsetY = Number(__mmEnemy.y) - Number(__mmSpike.y),
      __mmB =
        2 *
        (__mmOffsetX * __mmPrediction.velocityX +
          __mmOffsetY * __mmPrediction.velocityY),
      __mmC =
        __mmOffsetX * __mmOffsetX +
        __mmOffsetY * __mmOffsetY -
        __mmCollisionRadius * __mmCollisionRadius;
    // A spike already touching the target is no longer an upcoming contact,
    // and a target moving away should never retrigger the strike.
    if (__mmC <= 0 || __mmB >= 0) continue;
    const __mmDiscriminant =
      __mmB * __mmB - 4 * __mmSpeedSquared * __mmC;
    if (__mmDiscriminant < 0) continue;
    const __mmEtaMs =
      (-__mmB - Math.sqrt(__mmDiscriminant)) / (2 * __mmSpeedSquared);
    if (
      !Number.isFinite(__mmEtaMs) ||
      __mmEtaMs < 0 ||
      __mmEtaMs > __mmHorizonMs
    )
      continue;
    const __mmContact = {
      spike: __mmSpike,
      etaMs: __mmEtaMs,
      x: Number(__mmEnemy.x) + __mmPrediction.velocityX * __mmEtaMs,
      y: Number(__mmEnemy.y) + __mmPrediction.velocityY * __mmEtaMs,
      velocityX: __mmPrediction.velocityX,
      velocityY: __mmPrediction.velocityY,
      collisionRadius: __mmCollisionRadius,
    };
    if (!__mmBestContact || __mmContact.etaMs < __mmBestContact.etaMs)
      __mmBestContact = __mmContact;
  }
  return __mmBestContact;
}
function __mmSpikeTickPrimary() {
  if (!v || !v.alive || !v.weapons) return null;
  const __mmPrimary = v.weapons[0];
  return __mmPrimary === __mmKatana || __mmPrimary === __mmPolearmWeapon
    ? __mmPrimary
    : null;
}
function __mmSpikeTickSelfPoint(__mmLeadMs) {
  if (!v || !v.alive) return null;
  const __mmElapsed = Number(v.t2) - Number(v.t1),
    __mmVelocityX = (Number(v.x2) - Number(v.x1)) / __mmElapsed,
    __mmVelocityY = (Number(v.y2) - Number(v.y1)) / __mmElapsed,
    __mmUseVelocity = !!(
      Number.isFinite(__mmVelocityX) &&
      Number.isFinite(__mmVelocityY) &&
      __mmElapsed > 0 &&
      __mmElapsed <= 500
    );
  return {
    x: Number(v.x) + (__mmUseVelocity ? __mmVelocityX * __mmLeadMs : 0),
    y: Number(v.y) + (__mmUseVelocity ? __mmVelocityY * __mmLeadMs : 0),
  };
}
function __mmSpikeTickTrueReach(__mmPrimary, __mmEnemy) {
  const __mmData = b && b.weapons && b.weapons[__mmPrimary];
  return __mmData
    ? (Number(__mmData.range) || 0) +
        (Number(__mmEnemy && __mmEnemy.scale) || 35) * 1.8
    : 0;
}
function __mmSpikeTickContactInRange(
  __mmPrimary,
  __mmEnemy,
  __mmContact,
) {
  const __mmSelf = __mmSpikeTickSelfPoint(__mmContact.etaMs),
    __mmReach = __mmSpikeTickTrueReach(__mmPrimary, __mmEnemy);
  return !!(
    __mmSelf &&
    __mmReach > 0 &&
    Math.hypot(__mmContact.x - __mmSelf.x, __mmContact.y - __mmSelf.y) <=
      __mmReach + 8
  );
}
function __mmFullInstaReadyFor(__mmEnemy) {
  if (
    !v ||
    !v.alive ||
    !__mmEnemy ||
    __mmInsta.state !== "idle" ||
    !__mmInsta.runtimeReady() ||
    __mmInsta.isPriorityConflict() ||
    !v.skins ||
    !v.skins[7] ||
    !v.skins[__mmTurretGear] ||
    !__mmInsta.turretReady()
  )
    return !1;
  return __mmInsta.fullBurstReady(__mmEnemy, "normal", !1);
}
function __mmSpikeTickStrikeReady(__mmEnemy, __mmPrediction) {
  if (
    !__mmAutoSpikeInstaEnabled ||
    !v ||
    !v.alive ||
    !__mmEnemy ||
    !__mmPrediction ||
    __mmSpikeTickStrikeTimer ||
    __mmInsta.isActive() ||
    __mmPrimaryHeld ||
    __mmSecondaryHeld ||
    __mmTrapAttackActive ||
    __mmBoostBreakHeld ||
    __mmBuildSpamTimer ||
    __mmFoodSpamTimer ||
    __mmShieldDefenseTimer ||
    __mmIsTrapped() ||
    !(
      __mmActionAvailable("spikeTickStrike") ||
      __mmActionOwner === "weaponRecharge" ||
      __mmActionOwner === "matThief" ||
      __mmActionOwner === "mobSteal" ||
      __mmActionOwner === "instaSync"
    )
  )
    return !1;
  const __mmPrimary = __mmSpikeTickPrimary();
  return !!(
    __mmPrimary != null &&
    __mmWeaponReady(__mmPrimary) &&
    __mmShieldBypass(v, __mmEnemy) &&
    __mmSpikeTickContactInRange(__mmPrimary, __mmEnemy, __mmPrediction)
  );
}
function __mmStopSpikeTickStrike(__mmReason) {
  const __mmTool = __mmSpikeTickStrikeTool,
    __mmHat = __mmSpikeTickStrikeHat,
    __mmTail = __mmSpikeTickStrikeTail,
    __mmHadAim = Number.isFinite(__mmSpikeTickStrikeAimAngle),
    __mmRestore = __mmActionMayRestore("spikeTickStrike");
  (__mmSpikeTickStrikeTimer && clearTimeout(__mmSpikeTickStrikeTimer),
    (__mmSpikeTickStrikeTimer = 0),
    __mmSpikeTickStrikeHeld && O.send("F", 0, __mmSpikeTickStrikeAimAngle),
    (__mmSpikeTickStrikeHeld = !1),
    (__mmSpikeTickStrikeTool = null),
    (__mmSpikeTickStrikeHat = null),
    (__mmSpikeTickStrikeTail = null),
    (__mmSpikeTickStrikeAimAngle = null),
    __mmRestore && __mmEquipGearPair(__mmHat, __mmTail, !0),
    __mmRestore && __mmRestoreTool(__mmTool),
    __mmActionRelease(
      "spikeTickStrike",
      __mmReason || "predicted spike strike complete",
    ),
    __mmHadAim && __mmScheduleMouseAimReturn(),
    v && v.alive && __mmUpdateWeaponRecharge());
}
function __mmFireSpikeTickStrike(
  __mmTargetSid,
  __mmPrimary,
  __mmContact,
  __mmDeadline,
) {
  if (
    !v ||
    !v.alive ||
    __mmActionOwner !== "spikeTickStrike" ||
    __mmSpikeTickPrimary() !== __mmPrimary ||
    !__mmWeaponReady(__mmPrimary)
  )
    return void __mmStopSpikeTickStrike("spike strike context lost");
  let __mmEnemy = null;
  try {
    __mmEnemy = Rt(__mmTargetSid);
  } catch (__mmSpikeTargetError) {}
  if (!__mmIsEnemyPlayer(__mmEnemy))
    return void __mmStopSpikeTickStrike("spike target lost");
  const __mmPing = Number(window.pingTime),
    __mmLeadMs = Number.isFinite(__mmPing)
      ? Math.min(80, Math.max(0, __mmPing / 2))
      : 0,
    __mmTargetX = Number(__mmEnemy.x) + __mmContact.velocityX * __mmLeadMs,
    __mmTargetY = Number(__mmEnemy.y) + __mmContact.velocityY * __mmLeadMs,
    __mmSelf = __mmSpikeTickSelfPoint(__mmLeadMs),
    __mmReach = __mmSpikeTickTrueReach(__mmPrimary, __mmEnemy),
    __mmInRange = !!(
      __mmSelf &&
      Math.hypot(__mmTargetX - __mmSelf.x, __mmTargetY - __mmSelf.y) <=
        __mmReach + 8
    );
  if (!__mmInRange && Date.now() + 5 < __mmDeadline) {
    __mmSpikeTickStrikeTimer = setTimeout(function () {
      __mmFireSpikeTickStrike(
        __mmTargetSid,
        __mmPrimary,
        __mmContact,
        __mmDeadline,
      );
    }, 5);
    return;
  }
  if (!__mmInRange)
    return void __mmStopSpikeTickStrike("spike target missed melee reach");
  const __mmAngle = Math.atan2(
      __mmTargetY - __mmSelf.y,
      __mmTargetX - __mmSelf.x,
    ),
    __mmDamageTail = __mmInsta.damageTail();
  ((__mmSpikeTickStrikeAimAngle = __mmAngle),
    __mmEquipGearPair(
      v.skins && v.skins[7] ? 7 : __mmSpikeTickStrikeHat,
      __mmDamageTail,
      !0,
    ),
    O.send("D", __mmAngle),
    je(__mmPrimary, !0),
    O.send("F", 1, __mmAngle),
    (__mmSpikeTickStrikeHeld = !0),
    (__mmSpikeTickStrikeTimer = setTimeout(function () {
      __mmStopSpikeTickStrike("polearm/katana spike strike complete");
    }, 25)));
}
function __mmStartSpikeTickStrike(__mmEnemy, __mmPrediction) {
  if (!__mmSpikeTickStrikeReady(__mmEnemy, __mmPrediction)) return !1;
  (__mmActionOwner === "instaSync" && __mmStopInstaSync(),
    __mmActionOwner === "weaponRecharge" && __mmPauseWeaponRecharge(!0),
    __mmActionOwner === "matThief" &&
      __mmFinishMatThief("predicted spike strike"),
    __mmActionOwner === "mobSteal" &&
      __mmFinishMobSteal("predicted spike strike"));
  if (!__mmActionClaim("spikeTickStrike", "predicted allied-spike contact"))
    return !1;
  __mmCancelCombatHatLock(!1);
  const __mmPrimary = __mmSpikeTickPrimary(),
    __mmNow = Date.now(),
    __mmPing = Number(window.pingTime),
    __mmOneWayPing = Number.isFinite(__mmPing)
      ? Math.min(100, Math.max(0, __mmPing / 2))
      : 0,
    __mmFireDelay = Math.max(
      0,
      __mmPrediction.etaMs - __mmOneWayPing - 6,
    ),
    __mmDeadline =
      __mmNow + __mmPrediction.etaMs + Math.min(35, __mmOneWayPing),
    __mmSelf = __mmSpikeTickSelfPoint(__mmPrediction.etaMs),
    __mmAngle = Math.atan2(
      __mmPrediction.y - (__mmSelf ? __mmSelf.y : v.y),
      __mmPrediction.x - (__mmSelf ? __mmSelf.x : v.x),
    ),
    __mmDamageTail = __mmInsta.damageTail();
  if (__mmPrimary == null)
    return (__mmActionRelease("spikeTickStrike", "primary unavailable"), !1);
  ((__mmSpikeTickStrikeTool = __mmSelectedTool()),
    (__mmSpikeTickStrikeHat = __mmInstaSafeRestoreHat(
      __mmBushRestoreHat(v.skinIndex),
    )),
    (__mmSpikeTickStrikeTail = __mmBushRestoreTail(v.tailIndex)),
    (__mmSpikeTickStrikeAimAngle = __mmAngle),
    __mmInsta.turretReady() &&
      __mmFireDelay >= 8 &&
      (__mmEquipGearPair(__mmTurretGear, __mmDamageTail, !0),
      __mmAssumeTurretGearShot()),
    O.send("D", __mmAngle),
    (__mmSpikeTickStrikeTimer = setTimeout(function () {
      __mmFireSpikeTickStrike(
        __mmEnemy.sid,
        __mmPrimary,
        __mmPrediction,
        __mmDeadline,
      );
    }, Math.max(1, __mmFireDelay))));
  return !0;
}
function __mmUpdateAutoSpikeInsta() {
  const __mmNow = Date.now(),
    __mmSeen = Object.create(null);
  if (
    (!__mmAutoSpikeInstaEnabled && !__mmAutoPushInstaEnabled) ||
    !v ||
    !v.alive ||
    !Array.isArray(E)
  )
    return;
  let __mmBest = null;
  for (let __mmIndex = 0; __mmIndex < E.length; __mmIndex++) {
    const __mmEnemy = E[__mmIndex];
    if (!__mmIsEnemyPlayer(__mmEnemy)) continue;
    const __mmSid = String(__mmEnemy.sid),
      __mmPrediction = __mmPredictEnemyNextTick(__mmEnemy, __mmNow);
    __mmSeen[__mmSid] = !0;
    const __mmContact = __mmEnemyWillHitSpikeNextTick(
      __mmEnemy,
      __mmPrediction,
    ),
      __mmPushReady = !!(
        __mmContact &&
        __mmAutoPushInstaEnabled &&
        __mmKittyProfileReady(__mmEnemy, "autoPush")
      ),
      __mmStrikeReady = !!(
        __mmContact &&
        __mmAutoSpikeInstaEnabled &&
        __mmSpikeTickStrikeReady(__mmEnemy, __mmContact)
      );
    if (
      __mmContact &&
      (__mmPushReady || __mmStrikeReady) &&
      (!__mmBest || __mmContact.etaMs < __mmBest.contact.etaMs)
    )
      __mmBest = {
        enemy: __mmEnemy,
        contact: __mmContact,
        pushReady: __mmPushReady,
        strikeReady: __mmStrikeReady,
      };
  }
  for (const __mmSid in __mmAutoSpikeInstaMotion)
    __mmSeen[__mmSid] || delete __mmAutoSpikeInstaMotion[__mmSid];
  if (
    __mmBest &&
    __mmNow - __mmAutoSpikeInstaLastAt >= __mmServerTickMs()
  ) {
    const __mmStarted = __mmBest.pushReady
      ? __mmStartKittyProfile(
          "autoPush",
          __mmBest.enemy,
          "predicted allied-spike impact",
        )
      : __mmBest.strikeReady
        ? __mmStartSpikeTickStrike(__mmBest.enemy, __mmBest.contact)
        : !1;
    __mmStarted && (__mmAutoSpikeInstaLastAt = __mmNow);
  }
}
function __mmStartAutoSpikeInsta() {
  __mmEnsureOperationPipeline();
}
function __mmAutoSpikeSpamGhostStillRelevant() {
  const __mmGhost = __mmAutoSpikeSpamGhost;
  if (!__mmGhost || __mmGhost.targetSid == null || !v || !v.alive)
    return !1;
  // Lethal-push previews are recomputed from live health and geometry every
  // scan. Never pin one after the placement packet has been sent.
  if (__mmGhost.mode === "spikeKill") return !1;
  let __mmEnemy = null;
  try {
    __mmEnemy = Rt(__mmGhost.targetSid);
  } catch (__mmLookupError) {}
  return !!(
    __mmIsEnemyPlayer(__mmEnemy) &&
    __mmAutoSpikeSpamTrapForEnemy(__mmEnemy)
  );
}
function __mmAutoSpikeSpamResetCandidate(__mmForceGhostClear) {
  ((__mmForceGhostClear || !__mmAutoSpikeSpamGhostStillRelevant()) &&
    (__mmAutoSpikeSpamGhost = null),
    (__mmAutoSpikeSpamCandidateKey = null),
    (__mmAutoSpikeSpamCandidateSince = 0));
}
function __mmAutoSpikeSpamCleanReservations(__mmNow) {
  for (let __mmIndex = __mmAutoSpikeSpamReservations.length - 1; __mmIndex >= 0; __mmIndex--)
    __mmAutoSpikeSpamReservations[__mmIndex].expiresAt <= __mmNow &&
      __mmAutoSpikeSpamReservations.splice(__mmIndex, 1);
}
function __mmAutoSpikeSpamHasCapacity(__mmSpike) {
  const __mmData = b && b.list && b.list[__mmSpike];
  if (
    __mmSpike == null ||
    !__mmData ||
    !__mmData.group ||
    !__mmCanUseBuildItem(__mmSpike) ||
    __mmMaxBuildCount(__mmSpike) < 1
  )
    return !1;
  // __mmMaxBuildCount already subtracts same-group pending reservations. Do
  // not subtract the whole shared reservation array a second time: traps,
  // mills, and teleporters previously consumed fake spike capacity here.
  return !0;
}
function __mmAutoSpikeSpamTrapForEnemy(__mmEnemy) {
  if (!__mmEnemy) return null;
  let __mmClosest = null,
    __mmClosestDistance = Infinity;
  const __mmTraps = __mmActiveTrapObjects();
  for (let __mmIndex = 0; __mmIndex < __mmTraps.length; __mmIndex++) {
    const __mmTrap = __mmTraps[__mmIndex];
    if (
      !__mmTrap ||
      !__mmTrap.active ||
      !__mmTrap.trap ||
      !__mmSpikeHostileToEnemy(__mmTrap, __mmEnemy)
    )
      continue;
    const __mmPosition = __mmServerEntityPosition(__mmEnemy),
      __mmDistance = __mmPosition
        ? Math.hypot(__mmPosition.x - __mmTrap.x, __mmPosition.y - __mmTrap.y)
        : Infinity;
    if (
      __mmServerTrapContact(__mmEnemy, __mmTrap) &&
      __mmDistance < __mmClosestDistance
    ) {
      ((__mmClosest = __mmTrap), (__mmClosestDistance = __mmDistance));
    }
  }
  return __mmClosest;
}
function __mmAutoSpikeSpamTarget() {
  const __mmTargets = __mmAutoSpikeSpamTargets();
  return __mmTargets.length ? __mmTargets[0] : null;
}
function __mmAutoSpikeSpamTargets() {
  if (!v || !v.alive || !Array.isArray(E)) return [];
  const __mmTargets = [];
  for (let __mmIndex = 0; __mmIndex < E.length; __mmIndex++) {
    const __mmEnemy = E[__mmIndex];
    if (!__mmIsEnemyPlayer(__mmEnemy)) continue;
    const __mmTrap = __mmAutoSpikeSpamTrapForEnemy(__mmEnemy);
    if (!__mmTrap) continue;
    const __mmDistance = Math.hypot(__mmEnemy.x - v.x, __mmEnemy.y - v.y);
    Number.isFinite(__mmDistance) &&
      __mmTargets.push({
        enemy: __mmEnemy,
        trap: __mmTrap,
        distance: __mmDistance,
      });
  }
  __mmTargets.sort(function (__mmLeft, __mmRight) {
    return __mmLeft.distance - __mmRight.distance;
  });
  return __mmTargets;
}
function __mmResetAutoSpikeSpamIntent() {
  ((__mmAutoSpikeSpamIntent.targetSid = null),
    (__mmAutoSpikeSpamIntent.lastX = null),
    (__mmAutoSpikeSpamIntent.lastY = null),
    (__mmAutoSpikeSpamIntent.lastAt = 0),
    (__mmAutoSpikeSpamIntent.score = 0),
    (__mmAutoSpikeSpamIntent.armed = !1));
}
function __mmUpdateAutoSpikeSpamIntent(__mmTarget, __mmNow) {
  if (!v || !v.alive || !__mmTarget || !__mmTarget.enemy) {
    __mmResetAutoSpikeSpamIntent();
    return !1;
  }
  const __mmEnemy = __mmTarget.enemy,
    __mmSid = String(__mmEnemy.sid);
  if (__mmAutoSpikeSpamIntent.targetSid !== __mmSid) {
    ((__mmAutoSpikeSpamIntent.targetSid = __mmSid),
      (__mmAutoSpikeSpamIntent.lastX = Number(v.x)),
      (__mmAutoSpikeSpamIntent.lastY = Number(v.y)),
      (__mmAutoSpikeSpamIntent.lastAt = __mmNow),
      (__mmAutoSpikeSpamIntent.score = 0),
      (__mmAutoSpikeSpamIntent.armed = !1));
  }
  const __mmLastX = Number(__mmAutoSpikeSpamIntent.lastX),
    __mmLastY = Number(__mmAutoSpikeSpamIntent.lastY),
    __mmElapsed = __mmNow - Number(__mmAutoSpikeSpamIntent.lastAt),
    __mmMoveX = Number(v.x) - __mmLastX,
    __mmMoveY = Number(v.y) - __mmLastY,
    __mmMoveDistance = Math.hypot(__mmMoveX, __mmMoveY),
    __mmToEnemyX = Number(__mmEnemy.x) - __mmLastX,
    __mmToEnemyY = Number(__mmEnemy.y) - __mmLastY,
    __mmDistance = Math.hypot(__mmToEnemyX, __mmToEnemyY),
    __mmToward =
      __mmDistance > 1e-6
        ? (__mmMoveX * __mmToEnemyX + __mmMoveY * __mmToEnemyY) /
          __mmDistance
        : 0,
    __mmMovementAngle =
      typeof Kt === "number" && Number.isFinite(Kt) ? Kt : null,
    __mmCommandedToward =
      __mmMovementAngle == null || __mmDistance <= 1e-6
        ? 0
        : Math.cos(
            __mmMovementAngle - Math.atan2(__mmToEnemyY, __mmToEnemyX),
          );
  ((__mmAutoSpikeSpamIntent.lastX = Number(v.x)),
    (__mmAutoSpikeSpamIntent.lastY = Number(v.y)),
    (__mmAutoSpikeSpamIntent.lastAt = __mmNow));
  if (__mmElapsed > 250 || __mmMoveDistance > 60) {
    ((__mmAutoSpikeSpamIntent.score = 0),
      (__mmAutoSpikeSpamIntent.armed = !1));
    return !1;
  }
  if (__mmToward <= -0.25 || __mmCommandedToward <= -0.45) {
    // Retreat is an immediate escape decision. Clear all accumulated forward
    // evidence so a later turn back toward the target must deliberately re-arm.
    ((__mmAutoSpikeSpamIntent.score = 0),
      (__mmAutoSpikeSpamIntent.armed = !1));
    return !1;
  }
  if (__mmToward >= 0.15)
    __mmAutoSpikeSpamIntent.score = Math.min(
      12,
      __mmAutoSpikeSpamIntent.score + __mmToward,
    );
  // A live forward movement command is predictive intent: arm before the next
  // position packet arrives. Physical motion still accumulates as a fallback.
  if (__mmCommandedToward >= 0.55)
    __mmAutoSpikeSpamIntent.score = Math.min(
      12,
      __mmAutoSpikeSpamIntent.score + 1.5,
    );
  if (__mmAutoSpikeSpamIntent.score >= 1.5)
    __mmAutoSpikeSpamIntent.armed = !0;
  return __mmAutoSpikeSpamIntent.armed;
}
function __mmAutoSpikeSpamObjectScale(__mmObject) {
  if (!__mmObject) return 0;
  if (Number(__mmObject.blocker) > 0) return Number(__mmObject.blocker);
  if (typeof __mmObject.getScale === "function") {
    // Match the server's checkItemLocation scale arguments for a normal build.
    const __mmScale = Number(__mmObject.getScale(0.6, !!__mmObject.isItem));
    if (Number.isFinite(__mmScale) && __mmScale > 0) return __mmScale;
  }
  return Number(__mmObject.scale) || 0;
}
function __mmAutoSpikeSpamPositionClear(__mmX, __mmY, __mmSpikeScale) {
  if (
    __mmX - __mmSpikeScale < 0 ||
    __mmY - __mmSpikeScale < 0 ||
    __mmX + __mmSpikeScale > y.mapScale ||
    __mmY + __mmSpikeScale > y.mapScale ||
    (__mmY >= y.mapScale / 2 - y.riverWidth / 2 &&
      __mmY <= y.mapScale / 2 + y.riverWidth / 2)
  )
    return !1;
  const __mmObjects = __mmActiveObjectSnapshot().all;
  for (let __mmIndex = 0; __mmIndex < __mmObjects.length; __mmIndex++) {
    const __mmObject = __mmObjects[__mmIndex];
    if (!__mmObject || !__mmObject.active) continue;
    const __mmObjectScale = __mmAutoSpikeSpamObjectScale(__mmObject),
      // Match the game's collision boundary instead of adding a stricter
      // two-pixel buffer around every nearby structure.
      __mmMinimum = __mmSpikeScale + __mmObjectScale;
    if (
      (__mmObject.x - __mmX) ** 2 + (__mmObject.y - __mmY) ** 2 <
      __mmMinimum * __mmMinimum
    )
      return !1;
  }
  for (let __mmIndex = 0; __mmIndex < __mmAutoSpikeSpamReservations.length; __mmIndex++) {
    const __mmReservation = __mmAutoSpikeSpamReservations[__mmIndex],
      __mmMinimum = __mmSpikeScale + __mmReservation.scale;
    if (
      (__mmReservation.x - __mmX) ** 2 +
        (__mmReservation.y - __mmY) ** 2 <
      __mmMinimum * __mmMinimum
    )
      return !1;
  }
  return !0;
}
function __mmAutoSpikeSpamPredictionLead() {
  const __mmPing = Number(window.pingTime);
  return Math.max(
    10,
    Math.min(
      65,
      __mmServerTickMs() * 0.16 +
        (Number.isFinite(__mmPing) ? Math.max(0, __mmPing) * 0.5 : 0),
    ),
  );
}
function __mmAutoSpikeSpamPredictedEnemy(__mmTarget, __mmNow) {
  const __mmEnemy = __mmTarget && __mmTarget.enemy,
    __mmTrap = __mmTarget && __mmTarget.trap;
  if (!__mmEnemy) return null;
  const __mmKey = String(__mmEnemy.sid),
    __mmPrevious = __mmAutoSpikeSpamMotion[__mmKey],
    __mmMoved = !!(
      __mmPrevious &&
      Math.hypot(
        __mmEnemy.x - __mmPrevious.x,
        __mmEnemy.y - __mmPrevious.y,
      ) > 0.001
    ),
    // Only advance the sample clock when the coordinates actually change.
    // The solver runs every 5 ms, while player coordinates commonly update
    // once per render/server step; advancing it on identical scans creates a
    // false, extremely high velocity on the next real update.
    __mmSampleElapsed = __mmMoved
      ? Math.max(1, Math.min(250, __mmNow - __mmPrevious.sampleAt))
      : 0,
    __mmSampleFresh = !!(
      __mmPrevious &&
      __mmNow - __mmPrevious.sampleAt <= 250
    ),
    __mmSampleVelocityX = __mmMoved
      ? (__mmEnemy.x - __mmPrevious.x) / __mmSampleElapsed
      : __mmSampleFresh
        ? __mmPrevious.sampleVelocityX
        : 0,
    __mmSampleVelocityY = __mmMoved
      ? (__mmEnemy.y - __mmPrevious.y) / __mmSampleElapsed
      : __mmSampleFresh
        ? __mmPrevious.sampleVelocityY
        : 0,
    __mmServerElapsed = Number(__mmEnemy.t2) - Number(__mmEnemy.t1),
    __mmServerVelocityX =
      (Number(__mmEnemy.x2) - Number(__mmEnemy.x1)) / __mmServerElapsed,
    __mmServerVelocityY =
      (Number(__mmEnemy.y2) - Number(__mmEnemy.y1)) / __mmServerElapsed,
    __mmHasServerVelocity = !!(
      Number.isFinite(__mmServerVelocityX) &&
      Number.isFinite(__mmServerVelocityY) &&
      __mmServerElapsed > 0 &&
      __mmServerElapsed <= 500
    );
  let __mmVelocityX = __mmHasServerVelocity
      ? __mmServerVelocityX * 0.68 + __mmSampleVelocityX * 0.32
      : __mmSampleVelocityX,
    __mmVelocityY = __mmHasServerVelocity
      ? __mmServerVelocityY * 0.68 + __mmSampleVelocityY * 0.32
      : __mmSampleVelocityY;
  if (__mmPrevious) {
    ((__mmVelocityX = __mmVelocityX * 0.72 + __mmPrevious.velocityX * 0.28),
      (__mmVelocityY = __mmVelocityY * 0.72 + __mmPrevious.velocityY * 0.28));
  }
  __mmAutoSpikeSpamMotion[__mmKey] = {
    x: __mmMoved || !__mmPrevious ? __mmEnemy.x : __mmPrevious.x,
    y: __mmMoved || !__mmPrevious ? __mmEnemy.y : __mmPrevious.y,
    sampleAt:
      __mmMoved || !__mmPrevious ? __mmNow : __mmPrevious.sampleAt,
    sampleVelocityX: __mmSampleVelocityX,
    sampleVelocityY: __mmSampleVelocityY,
    velocityX: __mmVelocityX,
    velocityY: __mmVelocityY,
  };
  const __mmLeadMs = __mmAutoSpikeSpamPredictionLead(),
    __mmRawLeadX = __mmVelocityX * __mmLeadMs,
    __mmRawLeadY = __mmVelocityY * __mmLeadMs,
    __mmLeadDistance = Math.hypot(__mmRawLeadX, __mmRawLeadY),
    __mmLeadScale = __mmLeadDistance > 14 ? 14 / __mmLeadDistance : 1;
  let __mmX = __mmEnemy.x + __mmRawLeadX * __mmLeadScale,
    __mmY = __mmEnemy.y + __mmRawLeadY * __mmLeadScale;
  if (__mmTrap) {
    const __mmTrapScale =
        typeof __mmTrap.getScale === "function"
          ? Number(__mmTrap.getScale()) || Number(__mmTrap.scale) || 50
          : Number(__mmTrap.scale) || 50,
      __mmLockRadius = (Number(__mmEnemy.scale) || 35) + __mmTrapScale + 14,
      __mmTrapDx = __mmX - __mmTrap.x,
      __mmTrapDy = __mmY - __mmTrap.y,
      __mmTrapDistance = Math.hypot(__mmTrapDx, __mmTrapDy);
    if (__mmTrapDistance > __mmLockRadius && __mmTrapDistance > 0) {
      ((__mmX = __mmTrap.x + (__mmTrapDx / __mmTrapDistance) * __mmLockRadius),
        (__mmY = __mmTrap.y + (__mmTrapDy / __mmTrapDistance) * __mmLockRadius));
    }
  }
  return {
    x: __mmX,
    y: __mmY,
    scale: __mmEnemy.scale,
    sid: __mmEnemy.sid,
  };
}
function __mmAutoSpikeSpamPredictedOrigin() {
  if (!v || !v.alive) return null;
  let __mmVelocityX = Number(
      __mmPassiveSpikeMotion && __mmPassiveSpikeMotion.velocityX,
    ) || 0,
    __mmVelocityY = Number(
      __mmPassiveSpikeMotion && __mmPassiveSpikeMotion.velocityY,
    ) || 0;
  const __mmServerElapsed = Number(v.t2) - Number(v.t1),
    __mmServerVelocityX = (Number(v.x2) - Number(v.x1)) / __mmServerElapsed,
    __mmServerVelocityY = (Number(v.y2) - Number(v.y1)) / __mmServerElapsed;
  if (
    Number.isFinite(__mmServerVelocityX) &&
    Number.isFinite(__mmServerVelocityY) &&
    __mmServerElapsed > 0 &&
    __mmServerElapsed <= 500
  ) {
    ((__mmVelocityX = __mmVelocityX * 0.35 + __mmServerVelocityX * 0.65),
      (__mmVelocityY = __mmVelocityY * 0.35 + __mmServerVelocityY * 0.65));
  }
  const __mmLeadMs = __mmAutoSpikeSpamPredictionLead(),
    __mmLeadX = __mmVelocityX * __mmLeadMs,
    __mmLeadY = __mmVelocityY * __mmLeadMs,
    __mmDistance = Math.hypot(__mmLeadX, __mmLeadY),
    __mmScale = __mmDistance > 10 ? 10 / __mmDistance : 1;
  return {
    x: v.x + __mmLeadX * __mmScale,
    y: v.y + __mmLeadY * __mmScale,
  };
}
function __mmAutoSpikeKillDamage(__mmSpike, __mmFallbackItem) {
  const __mmItem =
      __mmSpike && __mmSpike.id != null
        ? __mmSpike.id
        : __mmFallbackItem,
    __mmData = b && b.list && b.list[__mmItem],
    __mmObjectDamage = Number(__mmSpike && __mmSpike.dmg),
    __mmItemDamage = Number(__mmData && __mmData.dmg);
  if (Number.isFinite(__mmObjectDamage) && __mmObjectDamage > 0)
    return __mmObjectDamage;
  return Number.isFinite(__mmItemDamage) && __mmItemDamage > 0
    ? __mmItemDamage
    : 0;
}
function __mmAutoSpikeKillAlliedSpikes(__mmEnemy) {
  const __mmResult = [],
    __mmSpikes = __mmActiveObjectSnapshot().spikes;
  for (let __mmIndex = 0; __mmIndex < __mmSpikes.length; __mmIndex++) {
    const __mmSpike = __mmSpikes[__mmIndex],
      __mmData = __mmSpike && b && b.list && b.list[__mmSpike.id],
      __mmDamage = __mmAutoSpikeKillDamage(__mmSpike);
    if (
      !__mmSpike ||
      !__mmSpike.active ||
      !__mmSpike.isItem ||
      !__mmData ||
      __mmDamage <= 0 ||
      !__mmSpikeOwnedByUsOrAlly(__mmSpike) ||
      !__mmSpikeHostileToEnemy(__mmSpike, __mmEnemy)
    )
      continue;
    __mmResult.push({
      object: __mmSpike,
      damage: __mmDamage,
      scale: Number(__mmSpike.scale) || Number(__mmData.scale) || 49,
    });
  }
  return __mmResult;
}
function __mmAutoSpikeKillCandidate(__mmSpike) {
  if (
    !__mmAutoSpikeKillEnabled ||
    !v ||
    !v.alive ||
    !Array.isArray(E) ||
    __mmSpike == null
  )
    return null;
  const __mmData = b && b.list && b.list[__mmSpike],
    __mmNewDamage = __mmAutoSpikeKillDamage(null, __mmSpike),
    __mmOrigin = __mmAutoSpikeSpamPredictedOrigin();
  if (!__mmData || __mmNewDamage <= 0 || !__mmOrigin) return null;
  const __mmSpikeScale = Number(__mmData.scale) || 49,
    __mmPlacementRadius =
      (Number(v.scale) || 35) +
      __mmSpikeScale +
      (Number(__mmData.placeOffset) || 0),
    __mmNow = Date.now();
  let __mmBest = null,
    __mmBestScore = Infinity;
  for (let __mmEnemyIndex = 0; __mmEnemyIndex < E.length; __mmEnemyIndex++) {
    const __mmEnemy = E[__mmEnemyIndex],
      __mmHealth = Number(__mmEnemy && __mmEnemy.health),
      __mmEnemySid = String(__mmEnemy && __mmEnemy.sid);
    if (
      !__mmIsEnemyPlayer(__mmEnemy) ||
      !Number.isFinite(__mmHealth) ||
      __mmHealth <= 0 ||
      Number(__mmAutoSpikeKillAssumedUntil[__mmEnemySid]) > __mmNow
    )
      continue;
    delete __mmAutoSpikeKillAssumedUntil[__mmEnemySid];
    const __mmPredicted = __mmAutoSpikeSpamPredictedEnemy(
        { enemy: __mmEnemy, trap: null },
        __mmNow,
      ),
      __mmEnemyScale = Number(__mmPredicted && __mmPredicted.scale) || 35,
      __mmExisting = __mmAutoSpikeKillAlliedSpikes(__mmEnemy).filter(
        function (__mmEntry) {
          return (
            Math.hypot(
              __mmPredicted.x - __mmEntry.object.x,
              __mmPredicted.y - __mmEntry.object.y,
            ) <=
            __mmEnemyScale + __mmEntry.scale + 13
          );
        },
      ),
      __mmContactRadius = __mmEnemyScale + __mmSpikeScale,
      // A slight overlap is what makes the newly-created collision displace
      // the enemy. The resolved point remains exactly tangent to the new spike.
      __mmPlacementTouchRadius = __mmContactRadius - 5,
      __mmTargetDx = __mmPredicted.x - __mmOrigin.x,
      __mmTargetDy = __mmPredicted.y - __mmOrigin.y,
      __mmTargetDistance = Math.hypot(__mmTargetDx, __mmTargetDy);
    if (
      !__mmExisting.length ||
      __mmTargetDistance <= 1e-6 ||
      __mmTargetDistance >
        __mmPlacementRadius + __mmPlacementTouchRadius + 9 ||
      __mmTargetDistance <
        Math.abs(__mmPlacementRadius - __mmPlacementTouchRadius) - 9
    )
      continue;
    const __mmBaseAngle = Math.atan2(__mmTargetDy, __mmTargetDx),
      __mmCosOffset = Math.max(
        -1,
        Math.min(
          1,
          (__mmPlacementRadius * __mmPlacementRadius +
            __mmTargetDistance * __mmTargetDistance -
            __mmPlacementTouchRadius * __mmPlacementTouchRadius) /
            (2 * __mmPlacementRadius * __mmTargetDistance),
        ),
      ),
      __mmIntersectionOffset = Math.acos(__mmCosOffset),
      __mmSeeds = [
        __mmBaseAngle - __mmIntersectionOffset,
        __mmBaseAngle + __mmIntersectionOffset,
      ];
    for (let __mmSeedIndex = 0; __mmSeedIndex < __mmSeeds.length; __mmSeedIndex++) {
      for (let __mmStep = 0; __mmStep <= 96; __mmStep++) {
        const __mmOffset = __mmStep * 0.0025,
          __mmSigns = __mmStep === 0 ? [0] : [-1, 1];
        for (let __mmSignIndex = 0; __mmSignIndex < __mmSigns.length; __mmSignIndex++) {
          const __mmSignedOffset = __mmOffset * __mmSigns[__mmSignIndex],
            __mmAngle = __mmSeeds[__mmSeedIndex] + __mmSignedOffset,
            __mmX =
              __mmOrigin.x + Math.cos(__mmAngle) * __mmPlacementRadius,
            __mmY =
              __mmOrigin.y + Math.sin(__mmAngle) * __mmPlacementRadius;
          const __mmEnemyDx = __mmPredicted.x - __mmX,
            __mmEnemyDy = __mmPredicted.y - __mmY,
            __mmEnemyDistance = Math.hypot(__mmEnemyDx, __mmEnemyDy);
          if (
            __mmEnemyDistance <= 1e-6 ||
            __mmEnemyDistance > __mmContactRadius - 1 ||
            __mmEnemyDistance < __mmContactRadius - 12
          )
            continue;
          if (!__mmAutoSpikeSpamPositionClear(__mmX, __mmY, __mmSpikeScale))
            continue;
          const __mmPushUnitX = __mmEnemyDx / __mmEnemyDistance,
            __mmPushUnitY = __mmEnemyDy / __mmEnemyDistance,
            __mmPushedX = __mmX + __mmPushUnitX * __mmContactRadius,
            __mmPushedY = __mmY + __mmPushUnitY * __mmContactRadius;
          let __mmCombinedDamage = __mmNewDamage,
            __mmContactCount = 0,
            __mmContactDepth = 0;
          for (let __mmExistingIndex = 0; __mmExistingIndex < __mmExisting.length; __mmExistingIndex++) {
            const __mmEntry = __mmExisting[__mmExistingIndex],
              __mmObject = __mmEntry.object,
              __mmBeforeDistance = Math.hypot(
                __mmPredicted.x - __mmObject.x,
                __mmPredicted.y - __mmObject.y,
              ),
              __mmAfterDistance = Math.hypot(
                __mmPushedX - __mmObject.x,
                __mmPushedY - __mmObject.y,
              ),
              __mmExistingTouchRadius = __mmEnemyScale + __mmEntry.scale;
            // It must genuinely push toward the existing spike and finish in
            // contact; proximity alone is not treated as a combo hit.
            if (
              __mmAfterDistance > __mmExistingTouchRadius + 1 ||
              __mmAfterDistance >= __mmBeforeDistance - 0.2
            )
              continue;
            (__mmCombinedDamage += __mmEntry.damage,
              __mmContactCount++,
              (__mmContactDepth +=
                __mmExistingTouchRadius - __mmAfterDistance));
          }
          if (!__mmContactCount || __mmCombinedDamage + 0.001 < __mmHealth)
            continue;
          const __mmScore =
            Math.hypot(__mmEnemy.x - v.x, __mmEnemy.y - v.y) * 0.05 +
            Math.abs(__mmEnemyDistance - __mmPlacementTouchRadius) * 8 +
            Math.abs(__mmSignedOffset) * 2 -
            __mmContactCount * 45 -
            Math.min(30, __mmContactDepth) * 0.5 -
            Math.min(50, __mmCombinedDamage - __mmHealth) * 0.15;
          if (__mmScore >= __mmBestScore) continue;
          ((__mmBestScore = __mmScore),
            (__mmBest = {
              item: __mmSpike,
              x: __mmX,
              y: __mmY,
              angle: __mmAngle,
              scale: __mmSpikeScale,
              targetSid: __mmEnemy.sid,
              mode: "spikeKill",
              combinedDamage: __mmCombinedDamage,
              contactCount: __mmContactCount,
              pushedX: __mmPushedX,
              pushedY: __mmPushedY,
            }));
        }
      }
    }
  }
  return __mmBest;
}
function __mmAutoSpikeSpamRearCandidate(__mmTarget, __mmSpike) {
  if (!__mmTarget || !__mmTarget.enemy || !v || !v.alive) return null;
  const __mmEnemy = __mmTarget.enemy,
    __mmEnemyDistance = Math.hypot(__mmEnemy.x - v.x, __mmEnemy.y - v.y);
  // Rear defense is local combat behavior. Do not build because somebody is
  // trapped elsewhere in the visible world.
  if (__mmEnemyDistance > __mmThreatTrapRange) return null;
  const __mmOrigin = __mmAutoSpikeSpamPredictedOrigin(),
    __mmData = b && b.list && b.list[__mmSpike];
  if (!__mmOrigin || !__mmData) return null;
  const __mmSpikeScale = Number(__mmData.scale) || 49,
    __mmPlacementRadius =
      (Number(v.scale) || 35) +
      __mmSpikeScale +
      (Number(__mmData.placeOffset) || 0),
    __mmFacing = Math.atan2(
      Number(__mmEnemy.y) - __mmOrigin.y,
      Number(__mmEnemy.x) - __mmOrigin.x,
    ),
    __mmRearCenter = __mmFacing + Math.PI,
    __mmMinimumAngularSpacing =
      2 *
        Math.asin(
          Math.min(
            0.999,
            (2 * __mmSpikeScale + 1) / (2 * __mmPlacementRadius),
          ),
        ) +
      0.04,
    __mmRearOffsets = [0];
  // Prefer a tightly packed, non-colliding rear row. Then scan the full rear
  // half-ring in fine steps so obstacles do not turn those preferred slots into
  // a permanent stop. The 5ms controller calls this again for as long as the
  // target remains trapped, so newly legal space is filled automatically.
  for (
    let __mmOffset = __mmMinimumAngularSpacing;
    __mmOffset <= Math.PI / 2 + 0.001;
    __mmOffset += __mmMinimumAngularSpacing
  )
    (__mmRearOffsets.push(-__mmOffset), __mmRearOffsets.push(__mmOffset));
  for (let __mmOffset = 0.04; __mmOffset <= Math.PI / 2; __mmOffset += 0.04)
    (__mmRearOffsets.push(-__mmOffset), __mmRearOffsets.push(__mmOffset));
  for (let __mmIndex = 0; __mmIndex < __mmRearOffsets.length; __mmIndex++) {
    const __mmAngle = __mmRearCenter + __mmRearOffsets[__mmIndex],
      __mmX = __mmOrigin.x + Math.cos(__mmAngle) * __mmPlacementRadius,
      __mmY = __mmOrigin.y + Math.sin(__mmAngle) * __mmPlacementRadius;
    if (!__mmAutoSpikeSpamPositionClear(__mmX, __mmY, __mmSpikeScale)) continue;
    return {
      item: __mmSpike,
      x: __mmX,
      y: __mmY,
      angle: __mmAngle,
      faceAngle: __mmFacing,
      scale: __mmSpikeScale,
      targetSid: __mmEnemy.sid,
      rear: !0,
    };
  }
  return null;
}
function __mmAutoSpikeSpamCandidate(__mmTarget, __mmSpike) {
  if (!__mmTarget || !v) return null;
  const __mmNow = Date.now(),
    __mmEnemy = __mmAutoSpikeSpamPredictedEnemy(__mmTarget, __mmNow),
    __mmOrigin = __mmAutoSpikeSpamPredictedOrigin(),
    __mmData = b.list[__mmSpike],
    __mmSpikeScale = Number(__mmData.scale) || 49,
    __mmPlacementRadius =
      (Number(v.scale) || 35) +
      __mmSpikeScale +
      (Number(__mmData.placeOffset) || 0),
    __mmTouchRadius =
      (Number(__mmEnemy.scale) || 35) + __mmSpikeScale - 2,
    __mmTargetDx = __mmEnemy.x - __mmOrigin.x,
    __mmTargetDy = __mmEnemy.y - __mmOrigin.y,
    __mmTargetDistance = Math.hypot(__mmTargetDx, __mmTargetDy);
  if (
    __mmTargetDistance <= 1e-6 ||
    __mmTargetDistance > __mmPlacementRadius + __mmTouchRadius + 10 ||
    __mmTargetDistance < Math.abs(__mmPlacementRadius - __mmTouchRadius) - 10
  )
    return null;
  const __mmBaseAngle = Math.atan2(__mmTargetDy, __mmTargetDx),
    __mmCosOffset = Math.max(
      -1,
      Math.min(
        1,
        (__mmPlacementRadius * __mmPlacementRadius +
          __mmTargetDistance * __mmTargetDistance -
          __mmTouchRadius * __mmTouchRadius) /
          (2 * __mmPlacementRadius * __mmTargetDistance),
      ),
    ),
    __mmIntersectionOffset = Math.acos(__mmCosOffset),
    __mmSeeds = [
      __mmBaseAngle - __mmIntersectionOffset,
      __mmBaseAngle + __mmIntersectionOffset,
    ];
  let __mmBest = null,
    __mmBestScore = Infinity;
  for (let __mmSeedIndex = 0; __mmSeedIndex < __mmSeeds.length; __mmSeedIndex++) {
    let __mmSeedFound = !1;
    for (let __mmStep = 0; __mmStep <= 140 && !__mmSeedFound; __mmStep++) {
      const __mmOffset = __mmStep * 0.0025,
        __mmSigns = __mmStep === 0 ? [0] : [-1, 1];
      for (
        let __mmSignIndex = 0;
        __mmSignIndex < __mmSigns.length;
        __mmSignIndex++
      ) {
        const __mmSignedOffset = __mmOffset * __mmSigns[__mmSignIndex],
          __mmAngle = __mmSeeds[__mmSeedIndex] + __mmSignedOffset,
          __mmX = __mmOrigin.x + Math.cos(__mmAngle) * __mmPlacementRadius,
          __mmY = __mmOrigin.y + Math.sin(__mmAngle) * __mmPlacementRadius,
          __mmEnemyDistance = Math.hypot(
            __mmX - __mmEnemy.x,
            __mmY - __mmEnemy.y,
          ),
          __mmTouchError = Math.abs(__mmEnemyDistance - __mmTouchRadius);
        if (
          __mmEnemyDistance > __mmTouchRadius + 4 ||
          __mmEnemyDistance < __mmTouchRadius - 9 ||
          !__mmAutoSpikeSpamPositionClear(__mmX, __mmY, __mmSpikeScale)
        )
          continue;
        const __mmScore =
          __mmTouchError * 12 + Math.abs(__mmSignedOffset) * 2;
        if (__mmScore < __mmBestScore) {
          ((__mmBestScore = __mmScore),
            (__mmBest = {
              item: __mmSpike,
              x: __mmX,
              y: __mmY,
              angle: __mmAngle,
              scale: __mmSpikeScale,
              targetSid: __mmEnemy.sid,
            }));
        }
        __mmSeedFound = !0;
      }
    }
  }
  return __mmBest;
}
function __mmAutoSpikeSpamTrappedPlan(__mmSpike) {
  const __mmTargets = __mmAutoSpikeSpamTargets();
  for (let __mmIndex = 0; __mmIndex < __mmTargets.length; __mmIndex++) {
    const __mmTarget = __mmTargets[__mmIndex],
      __mmCandidate =
        __mmAutoSpikeSpamRearCandidate(__mmTarget, __mmSpike) ||
        __mmAutoSpikeSpamCandidate(__mmTarget, __mmSpike);
    if (__mmCandidate)
      return { target: __mmTarget, candidate: __mmCandidate };
  }
  return {
    target: __mmTargets.length ? __mmTargets[0] : null,
    candidate: null,
  };
}
function __mmPlaceAutoSpikeSpam(__mmCandidate, __mmNow) {
  if (
    !__mmCandidate ||
    (__mmCandidate.mode !== "spikeKill" && !__mmCandidate.intentReady) ||
    __mmEmergencyGetawayActive() ||
    __mmHoldingMcGrabby() ||
    !__mmAutoSpikeSpamHasCapacity(__mmCandidate.item) ||
    !__mmActionClaim(
      "spikeSpam",
      __mmCandidate && __mmCandidate.mode === "spikeKill"
        ? "lethal allied-spike push"
        : "trapped enemy edge",
    )
  )
    return !1;
  const __mmTool = __mmSelectedTool();
  try {
    ((__mmAutoSpikeSpamAimAngle = __mmCandidate.angle),
      (__mmAutoSpikeSpamAimUntil = __mmNow + __mmServerTickMs()),
      O.send("D", __mmCandidate.angle));
    if (
      !__mmSendAutomaticPlacement(
        __mmCandidate.item,
        __mmCandidate.angle,
        __mmTool,
      )
    )
      throw new Error("automatic spike placement rejected locally");
    (
      __mmCandidate.mode === "spikeKill" &&
        (__mmAutoSpikeKillAssumedUntil[String(__mmCandidate.targetSid)] =
          __mmNow + Math.max(450, __mmServerTickMs() * 2)),
      __mmAutoSpikeSpamReservations.push({
        item: __mmCandidate.item,
        x: __mmCandidate.x,
        y: __mmCandidate.y,
        scale: __mmCandidate.scale,
        expiresAt: __mmNow + 650,
      }),
      (__mmAutoSpikeSpamLastAt = __mmNow),
      __mmActionRelease("spikeSpam", "spike placed"),
      __mmAutoSpikeSpamResetCandidate());
    return !0;
  } catch (__mmSpikeSpamError) {
    (__mmRestoreTool(__mmTool),
      __mmResumeHeldAttack(),
      __mmActionRelease("spikeSpam", "placement failed"),
      __mmAutoSpikeSpamResetCandidate());
    return !1;
  }
}
function __mmAutoSpikeSpamCanPlaceNow() {
  return !!(
    v &&
    v.alive &&
    !__mmEmergencyGetawayActive() &&
    !v.lockMove &&
    !__mmInsta.isActive() &&
    !__mmBoostInsta.isActive() &&
    !__mmTrapAttackActive &&
    !__mmBoostBreakHeld &&
    !__mmBuildSpamTimer &&
    !__mmFoodSpamTimer &&
    __mmActionCanPreempt("spikeSpam")
  );
}
function __mmUpdateAutoSpikeSpam() {
  const __mmNow = Date.now();
  __mmAutoSpikeSpamCleanReservations(__mmNow);
  if (
    (!__mmAutoSpikeSpamEnabled && !__mmAutoSpikeKillEnabled) ||
    __mmEmergencyGetawayActive() ||
    !v ||
    !v.alive
  ) {
    __mmResetAutoSpikeSpamIntent();
    return void __mmAutoSpikeSpamResetCandidate(!0);
  }
  const __mmSpike = __mmSpikeItem();
  if (!__mmAutoSpikeSpamHasCapacity(__mmSpike))
    return void __mmAutoSpikeSpamResetCandidate();
  // A verified lethal pin wins the same placement tick. Ordinary trapped
  // enemy filling now searches every trapped target by distance until it finds
  // a legal slot, rather than letting one blocked target stall the controller.
  const __mmLethalCandidate =
      __mmAutoSpikeKillEnabled && __mmAutoSpikeKillCandidate(__mmSpike),
    __mmTrappedPlan = __mmAutoSpikeSpamEnabled
      ? __mmAutoSpikeSpamTrappedPlan(__mmSpike)
      : { target: null, candidate: null },
    __mmTarget = __mmTrappedPlan.target,
    __mmIntentReady = __mmUpdateAutoSpikeSpamIntent(__mmTarget, __mmNow),
    __mmCandidate = __mmLethalCandidate || __mmTrappedPlan.candidate;
  if (!__mmCandidate) return void __mmAutoSpikeSpamResetCandidate();
  __mmCandidate.mode !== "spikeKill" &&
    (__mmCandidate.intentReady = __mmIntentReady);
  __mmAutoSpikeSpamGhost = __mmCandidate;
  const __mmKey =
    String(__mmCandidate.targetSid) + ":" +
    Math.round(__mmCandidate.x / 3) + ":" +
    Math.round(__mmCandidate.y / 3);
  if (__mmKey !== __mmAutoSpikeSpamCandidateKey) {
    ((__mmAutoSpikeSpamCandidateKey = __mmKey),
      (__mmAutoSpikeSpamCandidateSince = __mmNow));
  }
  // Previewing is independent from action ownership. Keep drawing the legal
  // non-colliding position while a click, insta, or reload temporarily blocks
  // placement instead of erasing the ghost every 10ms. After placement, the
  // last valid ghost remains pinned until this target is no longer trapped.
  if (!__mmAutoSpikeSpamCanPlaceNow()) return;
  if (
    __mmNow - __mmAutoSpikeSpamLastAt >=
      Math.max(5, Math.min(10, __mmServerTickMs() * 0.08))
  ) {
    __mmActionOwner === "weaponRecharge" && __mmPauseWeaponRecharge(!0);
    __mmActionOwner === "matThief" &&
      __mmFinishMatThief(
        __mmCandidate.mode === "spikeKill"
          ? "lethal spike push priority"
          : "trapped-player spike priority",
      );
    __mmActionOwner === "mobSteal" &&
      __mmFinishMobSteal(
        __mmCandidate.mode === "spikeKill"
          ? "lethal spike push priority"
          : "trapped-player spike priority",
      );
    __mmPlaceAutoSpikeSpam(__mmCandidate, __mmNow);
  }
}
function __mmStartAutoSpikeSpam() {
  __mmEnsureOperationPipeline();
}
function __mmStartFoodSpam() {
  __mmInsta.isActive() && __mmInsta.cancel("food-input");
  if (__mmFoodSpamTimer) return;
  (__mmUseFood(),
    (__mmFoodSpamTimer = setInterval(__mmUseFood, 1e3 / y.serverUpdateRate)));
}
function __mmStopFoodSpam() {
  __mmFoodSpamTimer &&
    (clearInterval(__mmFoodSpamTimer), (__mmFoodSpamTimer = 0));
}
function __mmUseBuild(__mmItemSlot) {
  if (!v || !v.alive) return;
  const __mmWeapon = __mmSelectedWeapon(),
    __mmItem = __mmItemSlot < 0 ? v.buildIndex : v.items[__mmItemSlot];
  if (__mmItem == null || __mmItem <= 0) return;
  (__mmItemSlot >= 0 && je(__mmItem),
    O.send("F", 1, Ci()),
    O.send("F", 0, Ci()),
    __mmRestoreWeapon(__mmWeapon),
    __mmResumeHeldAttack());
}
function __mmDashMovementWeapon(__mmItem) {
  if (!v || !v.alive || !v.weapons || !b || !b.list || !b.weapons)
    return null;
  const __mmItemData = b.list[__mmItem],
    __mmHealth = Math.max(1, Number(__mmItemData && __mmItemData.health) || 1),
    __mmCandidates = [__mmSelectedWeapon(), v.weapons[0], __mmGreatHammer];
  for (let __mmIndex = 0; __mmIndex < __mmCandidates.length; __mmIndex++) {
    const __mmWeapon = __mmCandidates[__mmIndex];
    if (
      __mmWeapon == null ||
      !v.weapons.includes(__mmWeapon) ||
      !__mmWeaponReady(__mmWeapon) ||
      __mmWeaponStructureDamage(v, __mmWeapon, { projDmg: !0 }) + 0.001 <
        __mmHealth
    )
      continue;
    return __mmWeapon;
  }
  return null;
}
function __mmStopDashMovement(__mmReason) {
  const __mmAngle = __mmDashMovementAngle,
    __mmRestore = __mmDashMovementRestoreTool,
    __mmMayRestore = __mmActionMayRestore("dashMovement");
  (__mmDashMovementReleaseTimer && clearTimeout(__mmDashMovementReleaseTimer),
    (__mmDashMovementReleaseTimer = 0),
    __mmAngle != null && v && v.alive && O.send("F", 0, __mmAngle),
    __mmMayRestore && __mmRestore != null && __mmRestoreTool(__mmRestore),
    (__mmDashMovementAngle = null),
    (__mmDashMovementRestoreTool = null),
    __mmActionRelease(
      "dashMovement",
      __mmReason || "dash pad broken",
    ),
    __mmResumeHeldAttack(),
    __mmScheduleMouseAimReturn());
}
function __mmTryDashMovement(__mmItem) {
  const __mmData = b && b.list && b.list[__mmItem];
  if (
    !__mmDashMovementEnabled ||
    __mmDashMovementReleaseTimer ||
    !v ||
    !v.alive ||
    !__mmData ||
    !__mmData.boostSpeed ||
    !v.skins ||
    !v.skins[40] ||
    __mmIsTrapped() ||
    __mmInsta.isActive() ||
    __mmBoostInsta.isActive() ||
    !__mmActionCanPreempt("dashMovement")
  )
    return !1;
  const __mmWeapon = __mmDashMovementWeapon(__mmItem);
  if (__mmWeapon == null || !__mmActionClaim("dashMovement", "manual boost-pad dash"))
    return !1;
  const __mmAngle = Ci(),
    __mmRestore = __mmSelectedTool();
  try {
    (je(__mmItem),
      O.send("F", 1, __mmAngle),
      O.send("F", 0, __mmAngle),
      __mmActivateCombatHat(40),
      je(__mmWeapon, !0),
      O.send("D", __mmAngle),
      O.send("F", 1, __mmAngle),
      (__mmDashMovementAngle = __mmAngle),
      (__mmDashMovementRestoreTool = __mmRestore));
  } catch (__mmDashMovementError) {
    ((__mmDashMovementAngle = __mmAngle),
      (__mmDashMovementRestoreTool = __mmRestore),
      __mmStopDashMovement("dash packet failed"));
    return !1;
  }
  __mmDashMovementReleaseTimer = setTimeout(function () {
    __mmStopDashMovement("dash pad broken");
  }, __mmServerTickMs());
  return !0;
}
function __mmUseBuildItem(__mmItem) {
  if (
    !v ||
    !v.alive ||
    __mmItem == null ||
    __mmItem <= 0 ||
    !__mmCanUseBuildItem(__mmItem)
  )
    return;
  if (__mmTryDashMovement(__mmItem)) return;
  const __mmWeapon = __mmSelectedWeapon();
  (je(__mmItem),
    O.send("F", 1, Ci()),
    O.send("F", 0, Ci()),
    __mmRestoreWeapon(__mmWeapon),
    __mmResumeHeldAttack());
}
function __mmSpikeItem() {
  if (!v || !v.items) return null;
  for (let __mmItemIndex = 0; __mmItemIndex < v.items.length; __mmItemIndex++) {
    const __mmItem = v.items[__mmItemIndex],
      __mmData = b.list[__mmItem];
    if (
      __mmData &&
      typeof __mmData.name === "string" &&
      __mmData.name.indexOf("spikes") !== -1
    )
      return __mmItem;
  }
  return null;
}
function __mmThreatEntityVelocity(__mmEntity) {
  if (!__mmEntity) return { x: 0, y: 0 };
  const __mmElapsed = Number(__mmEntity.t2) - Number(__mmEntity.t1),
    __mmVelocityX =
      (Number(__mmEntity.x2) - Number(__mmEntity.x1)) / __mmElapsed,
    __mmVelocityY =
      (Number(__mmEntity.y2) - Number(__mmEntity.y1)) / __mmElapsed;
  if (
    __mmElapsed > 0 &&
    __mmElapsed <= 500 &&
    Number.isFinite(__mmVelocityX) &&
    Number.isFinite(__mmVelocityY)
  )
    return {
      x: Math.max(-2, Math.min(2, __mmVelocityX)),
      y: Math.max(-2, Math.min(2, __mmVelocityY)),
    };
  return { x: 0, y: 0 };
}
function __mmThreatObjectScale(__mmObject) {
  if (!__mmObject) return 0;
  const __mmRealScale = Number(__mmObject.realScale),
    __mmScale = Number(__mmObject.scale);
  if (Number.isFinite(__mmRealScale) && __mmRealScale > 0)
    return __mmRealScale;
  if (typeof __mmObject.getScale === "function")
    try {
      const __mmComputed = Number(__mmObject.getScale());
      if (Number.isFinite(__mmComputed) && __mmComputed > 0)
        return __mmComputed;
    } catch (__mmScaleError) {}
  return Number.isFinite(__mmScale) && __mmScale > 0 ? __mmScale : 35;
}
function __mmThreatMovingCircleImpact(
  __mmProjectile,
  __mmTarget,
  __mmRadius,
  __mmHorizonMs,
) {
  const __mmX = Number(__mmProjectile && __mmProjectile.x),
    __mmY = Number(__mmProjectile && __mmProjectile.y),
    __mmDirection = Number(__mmProjectile && __mmProjectile.dir),
    __mmSpeed = Number(__mmProjectile && __mmProjectile.speed),
    __mmTargetPosition = __mmServerEntityPosition(__mmTarget),
    __mmVelocity = __mmThreatEntityVelocity(__mmTarget);
  if (
    !__mmTargetPosition ||
    !Number.isFinite(__mmX) ||
    !Number.isFinite(__mmY) ||
    !Number.isFinite(__mmDirection) ||
    !Number.isFinite(__mmSpeed) ||
    __mmSpeed <= 0 ||
    !Number.isFinite(__mmRadius) ||
    __mmRadius <= 0
  )
    return Infinity;
  const __mmRelativeX = __mmX - __mmTargetPosition.x,
    __mmRelativeY = __mmY - __mmTargetPosition.y,
    __mmRelativeVelocityX =
      Math.cos(__mmDirection) * __mmSpeed - __mmVelocity.x,
    __mmRelativeVelocityY =
      Math.sin(__mmDirection) * __mmSpeed - __mmVelocity.y,
    __mmA =
      __mmRelativeVelocityX * __mmRelativeVelocityX +
      __mmRelativeVelocityY * __mmRelativeVelocityY,
    __mmB =
      2 *
      (__mmRelativeX * __mmRelativeVelocityX +
        __mmRelativeY * __mmRelativeVelocityY),
    __mmC =
      __mmRelativeX * __mmRelativeX +
      __mmRelativeY * __mmRelativeY -
      __mmRadius * __mmRadius;
  if (__mmC <= 0) return 0;
  if (__mmA <= 1e-9) return Infinity;
  const __mmDiscriminant = __mmB * __mmB - 4 * __mmA * __mmC;
  if (__mmDiscriminant < 0) return Infinity;
  const __mmImpactMs =
    (-__mmB - Math.sqrt(__mmDiscriminant)) / (2 * __mmA),
    __mmRange = Number(__mmProjectile.range),
    __mmTravel = __mmImpactMs * __mmSpeed;
  return __mmImpactMs >= 0 &&
    __mmImpactMs <= __mmHorizonMs &&
    (!Number.isFinite(__mmRange) || __mmTravel <= __mmRange + __mmRadius)
    ? __mmImpactMs
    : Infinity;
}
function __mmThreatProjectileOwnerChain(__mmProjectile) {
  const __mmOwners = [];
  let __mmOwner = __mmProjectile && __mmProjectile.owner;
  for (let __mmDepth = 0; __mmOwner && __mmDepth < 5; __mmDepth++) {
    if (__mmOwners.includes(__mmOwner)) break;
    (__mmOwners.push(__mmOwner), (__mmOwner = __mmOwner.owner));
  }
  return __mmOwners;
}
function __mmThreatProjectileRootPlayer(__mmProjectile) {
  const __mmOwners = __mmThreatProjectileOwnerChain(__mmProjectile);
  for (let __mmIndex = __mmOwners.length - 1; __mmIndex >= 0; __mmIndex--) {
    const __mmOwner = __mmOwners[__mmIndex];
    if (__mmOwner === v) return v;
    if (
      Array.isArray(__mmOwner.weapons) ||
      Number.isInteger(Number(__mmOwner.weaponIndex))
    )
      return __mmOwner;
    if (__mmOwner.sid != null && typeof Rt === "function")
      try {
        const __mmPlayer = Rt(__mmOwner.sid);
        if (__mmPlayer) return __mmPlayer;
      } catch (__mmOwnerLookupError) {}
  }
  return null;
}
function __mmThreatProjectileFriendly(__mmProjectile) {
  const __mmRootPlayer = __mmThreatProjectileRootPlayer(__mmProjectile);
  return !!(
    __mmRootPlayer &&
    (__mmRootPlayer === v ||
      String(__mmRootPlayer.sid) === String(v && v.sid) ||
      __mmSameTeam(__mmRootPlayer))
  );
}
function __mmThreatProjectileSameSidePlayer(__mmProjectile, __mmPlayer) {
  const __mmOwner = __mmThreatProjectileRootPlayer(__mmProjectile);
  if (!__mmOwner || !__mmPlayer) return !1;
  if (
    __mmOwner === __mmPlayer ||
    String(__mmOwner.sid) === String(__mmPlayer.sid)
  )
    return !0;
  const __mmOwnerTeam = __mmTeamKey(__mmOwner),
    __mmPlayerTeam = __mmTeamKey(__mmPlayer);
  return !!(
    __mmOwnerTeam != null &&
    __mmPlayerTeam != null &&
    __mmOwnerTeam === __mmPlayerTeam
  );
}
function __mmThreatProjectileFromTurret(__mmProjectile) {
  const __mmOwners = __mmThreatProjectileOwnerChain(__mmProjectile);
  for (let __mmIndex = 0; __mmIndex < __mmOwners.length; __mmIndex++) {
    const __mmOwner = __mmOwners[__mmIndex],
      __mmData = __mmOwner && b && b.list && b.list[__mmOwner.id];
    if (String((__mmData && __mmData.name) || "").toLowerCase() === "turret")
      return !0;
  }
  return !1;
}
function __mmThreatProjectileFirstCollision(
  __mmProjectile,
  __mmHorizonMs,
  __mmCollisionObjects,
) {
  if (
    !__mmProjectile ||
    !__mmProjectile.active ||
    __mmThreatProjectileFriendly(__mmProjectile)
  )
    return null;
  const __mmProjectileScale = Math.max(0, Number(__mmProjectile.scale) || 0),
    __mmAvoid = Number(__mmProjectile.avoid),
    __mmOwnerChain = __mmThreatProjectileOwnerChain(__mmProjectile);
  let __mmFirst = null,
    __mmFirstImpactMs = Infinity;
  const __mmConsider = function (
    __mmTarget,
    __mmKind,
    __mmRadius,
    __mmMoving,
  ) {
    if (!__mmTarget || __mmOwnerChain.includes(__mmTarget)) return;
    const __mmImpactMs = __mmThreatMovingCircleImpact(
      __mmProjectile,
      __mmMoving
        ? __mmTarget
        : {
            x: Number(__mmTarget.x),
            y: Number(__mmTarget.y),
          },
      Math.max(1, Number(__mmRadius) || 0) + __mmProjectileScale,
      __mmHorizonMs,
    );
    if (__mmImpactMs >= __mmFirstImpactMs) return;
    ((__mmFirstImpactMs = __mmImpactMs),
      (__mmFirst = {
        target: __mmTarget,
        kind: __mmKind,
        impactMs: __mmImpactMs,
      }));
  };
  const __mmObjects = Array.isArray(__mmCollisionObjects)
    ? __mmCollisionObjects
    : __mmActiveObjectSnapshot().all;
  for (let __mmIndex = 0; __mmIndex < __mmObjects.length; __mmIndex++) {
    const __mmObject = __mmObjects[__mmIndex],
      __mmElevation = Number(__mmObject && __mmObject.elevation);
    if (
      !__mmObject ||
      !__mmObject.active ||
      __mmObject.ignoreCollision ||
      (Number.isFinite(__mmAvoid) &&
        Number.isFinite(__mmElevation) &&
        __mmElevation <= __mmAvoid)
    )
      continue;
    __mmConsider(
      __mmObject,
      "structure",
      __mmThreatObjectScale(__mmObject),
      !1,
    );
  }
  if (Array.isArray(N))
    for (let __mmIndex = 0; __mmIndex < N.length; __mmIndex++) {
      const __mmAnimal = N[__mmIndex];
      if (!__mmAnimal || __mmAnimal.active === !1 || __mmAnimal.visible === !1)
        continue;
      __mmConsider(
        __mmAnimal,
        "animal",
        __mmThreatObjectScale(__mmAnimal),
        !0,
      );
    }
  const __mmPlayers = [];
  v && __mmPlayers.push(v);
  if (Array.isArray(E))
    for (let __mmIndex = 0; __mmIndex < E.length; __mmIndex++)
      E[__mmIndex] && !__mmPlayers.includes(E[__mmIndex]) &&
        __mmPlayers.push(E[__mmIndex]);
  for (let __mmIndex = 0; __mmIndex < __mmPlayers.length; __mmIndex++) {
    const __mmPlayer = __mmPlayers[__mmIndex];
    if (
      !__mmPlayer ||
      !__mmPlayer.alive ||
      (__mmPlayer !== v && __mmPlayer.visible === !1) ||
      __mmThreatProjectileSameSidePlayer(__mmProjectile, __mmPlayer)
    )
      continue;
    __mmConsider(
      __mmPlayer,
      __mmPlayer === v ? "localPlayer" : "player",
      Number(__mmPlayer.scale) || 35,
      !0,
    );
  }
  return __mmFirst;
}
function __mmThreatIncomingDamageMultiplier() {
  const __mmHat = __mmPlayerHatData(v),
    __mmTail = __mmMobStealTailData(v && v.tailIndex),
    __mmHatMultiplier = Number(__mmHat && __mmHat.dmgMult),
    __mmTailMultiplier = Number(__mmTail && __mmTail.dmgMult);
  return (
    (Number.isFinite(__mmHatMultiplier) && __mmHatMultiplier > 0
      ? __mmHatMultiplier
      : 1) *
    (Number.isFinite(__mmTailMultiplier) && __mmTailMultiplier > 0
      ? __mmTailMultiplier
      : 1)
  );
}
function __mmThreatMeleeDamage(__mmPlayer, __mmWeaponId) {
  const __mmWeapon = b && b.weapons && b.weapons[__mmWeaponId];
  if (!__mmWeapon || __mmWeapon.projectile != null) return 0;
  const __mmHat = __mmPlayerHatData(__mmPlayer),
    __mmTail = __mmMobStealTailData(__mmPlayer && __mmPlayer.tailIndex),
    __mmVariant =
      y && y.weaponVariants && y.weaponVariants[__mmPlayer.weaponVariant],
    __mmHatMultiplier = Number(__mmHat && __mmHat.dmgMultO) || 1,
    __mmTailMultiplier = Number(__mmTail && __mmTail.dmgMultO) || 1,
    __mmVariantMultiplier = Number(__mmVariant && __mmVariant.val) || 1;
  return Math.max(
    0,
    (Number(__mmWeapon.dmg) || 0) *
      __mmHatMultiplier *
      __mmTailMultiplier *
      __mmVariantMultiplier *
      __mmThreatIncomingDamageMultiplier(),
  );
}
function __mmThreatHostileSpikeOnSegment(
  __mmStartX,
  __mmStartY,
  __mmEndX,
  __mmEndY,
) {
  const __mmSpikes = __mmActiveObjectSnapshot().spikes,
    __mmPlayerScale = Number(v && v.scale) || 35,
    __mmSegmentX = __mmEndX - __mmStartX,
    __mmSegmentY = __mmEndY - __mmStartY,
    __mmSegmentLengthSquared =
      __mmSegmentX * __mmSegmentX + __mmSegmentY * __mmSegmentY;
  let __mmBest = null;
  for (let __mmIndex = 0; __mmIndex < __mmSpikes.length; __mmIndex++) {
    const __mmSpike = __mmSpikes[__mmIndex],
      __mmData = __mmSpike && b && b.list && b.list[__mmSpike.id],
      __mmDamage = __mmAutoSpikeKillDamage(__mmSpike),
      __mmRadius = __mmPlayerScale + __mmThreatObjectScale(__mmSpike),
      __mmProjection = __mmSegmentLengthSquared > 0
        ? Math.max(
            0,
            Math.min(
              1,
              ((Number(__mmSpike.x) - __mmStartX) * __mmSegmentX +
                (Number(__mmSpike.y) - __mmStartY) * __mmSegmentY) /
                __mmSegmentLengthSquared,
            ),
          )
        : 0,
      __mmClosestX = __mmStartX + __mmSegmentX * __mmProjection,
      __mmClosestY = __mmStartY + __mmSegmentY * __mmProjection,
      __mmDistance = Math.hypot(
        Number(__mmSpike && __mmSpike.x) - __mmClosestX,
        Number(__mmSpike && __mmSpike.y) - __mmClosestY,
      );
    if (
      !__mmSpike ||
      !__mmSpike.active ||
      !__mmData ||
      __mmDamage <= 0 ||
      __mmFriendlyStructure(__mmSpike) ||
      __mmDistance > __mmRadius + 3
    )
      continue;
    if (
      !__mmBest ||
      __mmProjection < __mmBest.projection ||
      (__mmProjection === __mmBest.projection &&
        __mmDamage > __mmBest.damage)
    )
      __mmBest = {
        object: __mmSpike,
        damage: __mmDamage * __mmThreatIncomingDamageMultiplier(),
        projection: __mmProjection,
      };
  }
  return __mmBest;
}
function __mmThreatMeleeEntries(__mmNow, __mmHorizonMs) {
  const __mmEntries = [],
    __mmEnemies = __mmLiveStateFresh() ? __mmLiveState.enemies : E;
  if (!v || !v.alive || !Array.isArray(__mmEnemies)) return __mmEntries;
  for (let __mmIndex = 0; __mmIndex < __mmEnemies.length; __mmIndex++) {
    const __mmEnemy = __mmEnemies[__mmIndex],
      __mmRecent =
        __mmEnemy && __mmRecentPlayerSwings[String(__mmEnemy.sid)],
      __mmAge = __mmRecent ? __mmNow - Number(__mmRecent.at) : Infinity,
      __mmWeaponId = __mmRecent
        ? Number(__mmRecent.weapon)
        : Number(__mmEnemy && __mmEnemy.weaponIndex),
      __mmWeapon = b && b.weapons && b.weapons[__mmWeaponId];
    if (
      !__mmIsEnemyPlayer(__mmEnemy) ||
      !__mmRecent ||
      __mmAge < 0 ||
      __mmAge > Math.max(__mmHorizonMs, __mmServerTickMs() * 1.75) ||
      !__mmWeapon ||
      __mmWeapon.projectile != null ||
      __mmWeapon.shield
    )
      continue;
    const __mmEnemyPosition = __mmServerEntityPosition(__mmEnemy),
      __mmPlayerPosition = __mmServerEntityPosition(v);
    if (!__mmEnemyPosition || !__mmPlayerPosition) continue;
    const __mmTargetAngle = Math.atan2(
        __mmPlayerPosition.y - __mmEnemyPosition.y,
        __mmPlayerPosition.x - __mmEnemyPosition.x,
      ),
      __mmFacing = Number.isFinite(Number(__mmEnemy.dir))
        ? Number(__mmEnemy.dir)
        : Number(__mmEnemy.d2),
      __mmAngleDifference = Number.isFinite(__mmFacing)
        ? Math.abs(
            Math.atan2(
              Math.sin(__mmFacing - __mmTargetAngle),
              Math.cos(__mmFacing - __mmTargetAngle),
            ),
          )
        : 0,
      __mmDistance = Math.hypot(
        __mmPlayerPosition.x - __mmEnemyPosition.x,
        __mmPlayerPosition.y - __mmEnemyPosition.y,
      ),
      __mmReach =
        (Number(__mmWeapon.range) || 0) +
        (Number(__mmEnemy.scale) || 35) +
        (Number(v.scale) || 35) +
        8,
      __mmGatherAngle =
        Math.max(0.25, Number(y && y.gatherAngle) || 0.35) + 0.12;
    if (__mmDistance > __mmReach || __mmAngleDifference > __mmGatherAngle)
      continue;
    const __mmDamage = __mmThreatMeleeDamage(__mmEnemy, __mmWeaponId),
      __mmKnockDistance =
        (0.3 + Math.max(0, Number(__mmWeapon.knock) || 0)) *
        __mmServerTickMs(),
      __mmPushX =
        __mmPlayerPosition.x + Math.cos(__mmTargetAngle) * __mmKnockDistance,
      __mmPushY =
        __mmPlayerPosition.y + Math.sin(__mmTargetAngle) * __mmKnockDistance,
      __mmSpike = __mmThreatHostileSpikeOnSegment(
        __mmPlayerPosition.x,
        __mmPlayerPosition.y,
        __mmPushX,
        __mmPushY,
      );
    if (__mmDamage <= 0) continue;
    __mmEntries.push({
      type: "melee",
      source: __mmEnemy,
      weapon: __mmWeaponId,
      damage: __mmDamage,
      impactMs: Math.max(0, __mmServerTickMs() - __mmAge),
      angle: Math.atan2(
        __mmEnemyPosition.y - __mmPlayerPosition.y,
        __mmEnemyPosition.x - __mmPlayerPosition.x,
      ),
      spike: __mmSpike,
    });
  }
  return __mmEntries;
}
function __mmCombatThreatSnapshot(__mmForce) {
  const __mmNow = Date.now(),
    // Roughly 40-60 forecasts per second still samples between normal
    // render/server updates while keeping object x projectile work bounded.
    __mmCacheMs = Math.max(16, Math.min(25, __mmFastCheckMs()));
  if (
    !__mmForce &&
    __mmCombatThreatCache &&
    __mmNow - __mmCombatThreatCalculatedAt <= __mmCacheMs
  )
    return __mmCombatThreatCache;
  const __mmSnapshot = {
    at: __mmNow,
    horizonMs: 650,
    entries: [],
    damage: 0,
    projectileDamage: 0,
    turretDamage: 0,
    meleeDamage: 0,
    potentialDamage: 0,
    spikeDamage: 0,
    healPotential: 0,
    nearbyEnemies: 0,
    firstImpactMs: Infinity,
    angle: null,
    lethalSpike: null,
    urgent: !1,
    lethal: !1,
  };
  if (!v || !v.alive) {
    ((__mmCombatThreatCalculatedAt = __mmNow),
      (__mmCombatThreatCache = __mmSnapshot));
    return __mmSnapshot;
  }
  const __mmEnemies = __mmLiveStateFresh() ? __mmLiveState.enemies : E;
  if (Array.isArray(__mmEnemies))
    for (let __mmIndex = 0; __mmIndex < __mmEnemies.length; __mmIndex++) {
      const __mmEnemy = __mmEnemies[__mmIndex];
      if (!__mmIsEnemyPlayer(__mmEnemy)) continue;
      const __mmDistance = Math.hypot(__mmEnemy.x - v.x, __mmEnemy.y - v.y);
      if (__mmDistance > Math.max(__mmCombatRange, __mmTurretGearRange))
        continue;
      __mmSnapshot.nearbyEnemies++;
      const __mmWeaponId = Number(__mmEnemy.weaponIndex),
        __mmWeapon = b && b.weapons && b.weapons[__mmWeaponId],
        __mmReach = __mmWeapon
          ? (Number(__mmWeapon.range) || 0) +
            (Number(__mmEnemy.scale) || 35) +
            (Number(v.scale) || 35) +
            65
          : 0,
        __mmFacing = Number.isFinite(Number(__mmEnemy.dir))
          ? Number(__mmEnemy.dir)
          : Number(__mmEnemy.d2),
        __mmToUs = Math.atan2(v.y - __mmEnemy.y, v.x - __mmEnemy.x),
        __mmAngleDifference = Number.isFinite(__mmFacing)
          ? Math.abs(
              Math.atan2(
                Math.sin(__mmFacing - __mmToUs),
                Math.cos(__mmFacing - __mmToUs),
              ),
            )
          : Infinity;
      if (
        __mmWeapon &&
        __mmWeapon.projectile == null &&
        !__mmWeapon.shield &&
        __mmDistance <= __mmReach &&
        __mmAngleDifference <= 0.9
      )
        __mmSnapshot.potentialDamage = Math.max(
          __mmSnapshot.potentialDamage,
          __mmThreatMeleeDamage(__mmEnemy, __mmWeaponId),
        );
    }
  const __mmHasActiveProjectiles =
      Array.isArray(Ve) &&
      Ve.some(function (__mmProjectile) {
        return !!(__mmProjectile && __mmProjectile.active);
      }),
    __mmCollisionObjects = __mmHasActiveProjectiles
      ? __mmActiveObjectSnapshot(!0).all
      : [];
  if (Array.isArray(Ve))
    for (let __mmIndex = 0; __mmIndex < Ve.length; __mmIndex++) {
      const __mmProjectile = Ve[__mmIndex],
        __mmDamageValue = Number(__mmProjectile && __mmProjectile.dmg);
      if (
        !__mmProjectile ||
        !__mmProjectile.active ||
        !Number.isFinite(__mmDamageValue) ||
        __mmDamageValue <= 0
      )
        continue;
      const __mmCollision = __mmThreatProjectileFirstCollision(
        __mmProjectile,
        __mmSnapshot.horizonMs,
        __mmCollisionObjects,
      );
      if (!__mmCollision || __mmCollision.kind !== "localPlayer") continue;
      const __mmDamage =
          __mmDamageValue * __mmThreatIncomingDamageMultiplier(),
        __mmPosition = __mmServerEntityPosition(v),
        __mmDirection = Number(__mmProjectile.dir),
        __mmKnock = Math.max(0, Number(__mmProjectile.knock) || 0),
        __mmPushDistance = __mmKnock * __mmServerTickMs(),
        __mmSpike =
          __mmPosition && __mmPushDistance > 0
            ? __mmThreatHostileSpikeOnSegment(
                __mmPosition.x,
                __mmPosition.y,
                __mmPosition.x + Math.cos(__mmDirection) * __mmPushDistance,
                __mmPosition.y + Math.sin(__mmDirection) * __mmPushDistance,
              )
            : null,
        __mmTurret = __mmThreatProjectileFromTurret(__mmProjectile);
      __mmSnapshot.entries.push({
        type: __mmTurret ? "turret" : "projectile",
        source: __mmProjectile,
        damage: __mmDamage,
        impactMs: __mmCollision.impactMs,
        angle: Math.atan2(
          Number(__mmProjectile.y) - Number(v.y),
          Number(__mmProjectile.x) - Number(v.x),
        ),
        spike: __mmSpike,
      });
    }
  const __mmMeleeEntries = __mmThreatMeleeEntries(
    __mmNow,
    __mmSnapshot.horizonMs,
  );
  for (let __mmIndex = 0; __mmIndex < __mmMeleeEntries.length; __mmIndex++)
    __mmSnapshot.entries.push(__mmMeleeEntries[__mmIndex]);
  let __mmBestSpike = null;
  for (let __mmIndex = 0; __mmIndex < __mmSnapshot.entries.length; __mmIndex++) {
    const __mmEntry = __mmSnapshot.entries[__mmIndex];
    __mmSnapshot.damage += __mmEntry.damage;
    if (__mmEntry.type === "melee")
      __mmSnapshot.meleeDamage += __mmEntry.damage;
    else {
      __mmSnapshot.projectileDamage += __mmEntry.damage;
      __mmEntry.type === "turret" &&
        (__mmSnapshot.turretDamage += __mmEntry.damage);
    }
    if (__mmEntry.impactMs < __mmSnapshot.firstImpactMs)
      ((__mmSnapshot.firstImpactMs = __mmEntry.impactMs),
        (__mmSnapshot.angle = __mmEntry.angle));
    if (
      __mmEntry.spike &&
      (!__mmBestSpike || __mmEntry.spike.damage > __mmBestSpike.damage)
    )
      __mmBestSpike = __mmEntry.spike;
  }
  if (__mmBestSpike) {
    ((__mmSnapshot.spikeDamage = __mmBestSpike.damage),
      (__mmSnapshot.damage += __mmBestSpike.damage),
      (__mmSnapshot.lethalSpike = __mmBestSpike.object));
  }
  const __mmHealth = Math.max(0, Number(v.health) || 0),
    __mmMissingHealth = Math.max(
      0,
      (Number(v.maxHealth) || __mmHealth) - __mmHealth,
    ),
    __mmFoodValue = __mmAutoHealFoodValue(),
    __mmImpactWindows = Number.isFinite(__mmSnapshot.firstImpactMs)
      ? Math.max(
          0,
          Math.floor(__mmSnapshot.firstImpactMs / __mmServerTickMs()),
        )
      : 0,
    __mmFoodChargesAvailable =
      !__mmAutoHealEnabled ||
      Number(v.skinIndex) === 45 ||
      !__mmCanEat() ||
      (!__mmAutoHealPending && __mmAutoHealBitesRemaining <= 0)
        ? 0
        : Math.min(__mmFoodCharges(), __mmImpactWindows);
  __mmSnapshot.healPotential = Math.min(
    __mmMissingHealth,
    __mmFoodChargesAvailable * __mmFoodValue,
  );
  ((__mmSnapshot.urgent = __mmSnapshot.damage + 0.001 >= __mmHealth),
    (__mmSnapshot.lethal =
      __mmSnapshot.damage + 0.001 >=
      __mmHealth + __mmSnapshot.healPotential));
  if (!__mmSnapshot.lethal) __mmSnapshot.lethalSpike = null;
  ((__mmCombatThreatCalculatedAt = __mmNow),
    (__mmCombatThreatCache = __mmSnapshot));
  return __mmSnapshot;
}
function __mmPlacementDefenseItem() {
  if (!v || !v.items || !b || !b.list) return null;
  const __mmRanks = [
    /(?:greater |stone |wood )?wall|blocker/i,
    /platform/i,
    /mill/i,
  ];
  for (let __mmRank = 0; __mmRank < __mmRanks.length; __mmRank++)
    for (let __mmIndex = 0; __mmIndex < v.items.length; __mmIndex++) {
      const __mmItem = v.items[__mmIndex],
        __mmData = b.list[__mmItem];
      if (
        __mmData &&
        __mmRanks[__mmRank].test(String(__mmData.name || "")) &&
        __mmCanUseBuildItem(__mmItem) &&
        __mmMaxBuildCount(__mmItem) > 0
      )
        return __mmItem;
    }
  return null;
}
function __mmUpdatePlacementDefense() {
  if (
    !__mmPlacementDefenseEnabled ||
    !v ||
    !v.alive ||
    __mmIsTrapped() ||
    __mmInsta.isActive() ||
    __mmBoostInsta.isActive() ||
    __mmTrapAttackActive ||
    !__mmActionCanPreempt("placementDefense")
  )
    return;
  const __mmNow = Date.now(),
    __mmThreat = __mmCombatThreatSnapshot(),
    __mmProjectileEntries = __mmThreat.entries.filter(function (__mmEntry) {
      return __mmEntry && __mmEntry.type !== "melee";
    });
  if (!__mmProjectileEntries.length) return;
  __mmProjectileEntries.sort(function (__mmLeft, __mmRight) {
    return Number(__mmLeft.impactMs) - Number(__mmRight.impactMs);
  });
  const __mmIncoming = __mmProjectileEntries[0],
    __mmUrgent =
      __mmThreat.lethal ||
      __mmThreat.projectileDamage + 0.001 >= Number(v.health) ||
      Number(__mmIncoming.impactMs) <= Math.max(180, __mmServerTickMs() * 2.15);
  if (
    !__mmUrgent ||
    !Number.isFinite(Number(__mmIncoming.angle)) ||
    Number(__mmPlacementDefenseHandled.get(__mmIncoming.source)) > __mmNow ||
    __mmNow - __mmPlacementDefenseLastAt < __mmServerTickMs()
  )
    return;
  const __mmItem = __mmPlacementDefenseItem();
  if (__mmItem == null) return;
  const __mmCandidate = __mmSmartNearestLegalCandidate(
    __mmItem,
    Number(__mmIncoming.angle),
    0.52,
    0.04,
  );
  if (
    !__mmCandidate ||
    !__mmActionClaim("placementDefense", "incoming projectile blocker")
  )
    return;
  const __mmRestore = __mmSelectedTool();
  if (
    __mmSendAutomaticPlacement(
      __mmItem,
      __mmCandidate.angle,
      __mmRestore,
    )
  )
    ((__mmPlacementDefenseLastAt = __mmNow),
      __mmIncoming.source &&
        __mmPlacementDefenseHandled.set(__mmIncoming.source, __mmNow + 800));
  __mmActionRelease("placementDefense", "defensive placement sent");
}
function __mmStartPlacementDefense() {
  __mmEnsureOperationPipeline();
}
function __mmTurretStealTarget() {
  if (!v || !v.alive) return null;
  const __mmEntities = [];
  Array.isArray(E) && __mmEntities.push.apply(__mmEntities, E);
  __mmLiveStateFresh() && Array.isArray(__mmLiveState.animals)
    ? __mmEntities.push.apply(__mmEntities, __mmLiveState.animals)
    : typeof N !== "undefined" &&
      Array.isArray(N) &&
      __mmEntities.push.apply(__mmEntities, N);
  let __mmBest = null,
    __mmBestDistance = Infinity;
  for (let __mmIndex = 0; __mmIndex < __mmEntities.length; __mmIndex++) {
    const __mmEntity = __mmEntities[__mmIndex],
      __mmPlayerTarget = Array.isArray(E) && E.includes(__mmEntity),
      __mmHealth = Number(
        __mmEntity &&
          (__mmEntity.health == null
            ? __mmEntity.currentHealth
            : __mmEntity.health),
      );
    if (
      !__mmEntity ||
      __mmEntity === v ||
      __mmEntity.alive === !1 ||
      (__mmPlayerTarget && !__mmIsEnemyPlayer(__mmEntity)) ||
      !Number.isFinite(__mmHealth) ||
      __mmHealth <= 0 ||
      __mmHealth > 25
    )
      continue;
    const __mmDistance = Math.hypot(__mmEntity.x - v.x, __mmEntity.y - v.y);
    if (__mmDistance <= __mmTurretGearRange && __mmDistance < __mmBestDistance)
      ((__mmBest = __mmEntity), (__mmBestDistance = __mmDistance));
  }
  return __mmBest;
}
function __mmUpdateTurretSteal() {
  if (
    !__mmTurretStealEnabled ||
    __mmTurretStealRestoreTimer ||
    !v ||
    !v.alive ||
    !__mmInsta.turretReady() ||
    __mmCombatHatLockActive() ||
    __mmInsta.isActive() ||
    __mmBoostInsta.isActive() ||
    __mmTrapAttackActive ||
    __mmPrimaryHeld ||
    __mmSecondaryHeld ||
    !__mmActionAvailable("turretSteal")
  )
    return;
  const __mmTarget = __mmTurretStealTarget();
  if (!__mmTarget || !__mmActionClaim("turretSteal", "25-health turret finish"))
    return;
  const __mmAngle = Math.atan2(__mmTarget.y - v.y, __mmTarget.x - v.x),
    __mmRestoreHat = __mmBestPostCombatHat();
  try {
    (O.send("D", __mmAngle),
      __mmEquipHatNow(__mmTurretGear, !0),
      __mmAssumeTurretGearShot());
  } catch (__mmTurretStealError) {
    __mmActionRelease("turretSteal", "turret finisher failed");
    return;
  }
  __mmTurretStealRestoreTimer = setTimeout(function () {
    ((__mmTurretStealRestoreTimer = 0),
      __mmActionMayRestore("turretSteal") &&
        v &&
        v.alive &&
        __mmEquipHatNow(__mmBestPostCombatHat() || __mmRestoreHat, !0),
      __mmActionRelease("turretSteal", "turret finisher sent"),
      __mmScheduleMouseAimReturn());
  }, __mmServerTickMs());
}
function __mmStartTurretSteal() {
  __mmEnsureOperationPipeline();
}
function __mmResetSpikeGearCounter(__mmRestore) {
  const __mmTailRestore = __mmSpikeGearCounterPreviousTail;
  (__mmSpikeGearCounterRestoreTimer &&
    clearTimeout(__mmSpikeGearCounterRestoreTimer),
    (__mmSpikeGearCounterRestoreTimer = 0),
    (__mmSpikeGearCounterTargetSid = null),
    (__mmSpikeGearCounterArmedAt = 0),
    (__mmSpikeGearCounterPreviousTail = null));
  if (__mmActionOwner !== "spikeGearCounter") return;
  (__mmRestore &&
    v &&
    v.alive &&
    !__mmCombatHatLockActive() &&
    __mmEquipHatNow(__mmBestPostCombatHat(), !0),
    __mmRestore &&
      __mmTailRestore != null &&
      v &&
      v.alive &&
      __mmEquipTailNow(__mmTailRestore, !0),
    __mmActionRelease("spikeGearCounter", "counter reset"));
}
function __mmUpdateSpikeGearCounter() {
  if (
    !__mmSpikeGearCounterEnabled ||
    !v ||
    !v.alive ||
    !v.skins ||
    !v.skins[11] ||
    !v.skins[7] ||
    !v.tails ||
    !v.tails[__mmCorruptXWings] ||
    __mmIsTrapped() ||
    __mmInsta.isActive() ||
    __mmBoostInsta.isActive() ||
    __mmPrimaryHeld ||
    __mmSecondaryHeld ||
    __mmTrapAttackActive
  )
    return void __mmResetSpikeGearCounter(!0);
  const __mmEnemy = __mmNearestEnemy(),
    __mmPrimary = v.weapons && v.weapons[0],
    __mmPrimaryData = b && b.weapons && b.weapons[__mmPrimary];
  if (!__mmEnemy || __mmPrimary == null || !__mmPrimaryData)
    return void __mmResetSpikeGearCounter(!0);
  const __mmEnemyWeapon =
      b && b.weapons && b.weapons[Number(__mmEnemy.weaponIndex)],
    __mmDistance = Math.hypot(__mmEnemy.x - v.x, __mmEnemy.y - v.y),
    __mmOurReach =
      (Number(__mmPrimaryData.range) || 0) +
      (Number(v.scale) || 35) +
      (Number(__mmEnemy.scale) || 35) +
      8,
    __mmEnemyReach =
      (Number(__mmEnemyWeapon && __mmEnemyWeapon.range) || 0) +
      (Number(v.scale) || 35) +
      (Number(__mmEnemy.scale) || 35) +
      8;
  if (
    !__mmEnemyWeapon ||
    __mmEnemyWeapon.projectile != null ||
    __mmDistance > Math.min(__mmOurReach, __mmEnemyReach) ||
    (Number(__mmEnemy.skinIndex) !== 7 &&
      String(__mmSpikeGearCounterTargetSid) !== String(__mmEnemy.sid))
  )
    return void __mmResetSpikeGearCounter(!0);
  const __mmRecent = __mmRecentPlayerSwings[String(__mmEnemy.sid)],
    __mmSwingAge = __mmRecent ? Date.now() - Number(__mmRecent.at) : Infinity;
  if (
    String(__mmSpikeGearCounterTargetSid) !== String(__mmEnemy.sid) &&
    __mmActionCanPreempt("spikeGearCounter") &&
    __mmActionClaim("spikeGearCounter", "close Bull-primary counter")
  ) {
    ((__mmSpikeGearCounterTargetSid = __mmEnemy.sid),
      (__mmSpikeGearCounterArmedAt = Date.now()),
      (__mmSpikeGearCounterPreviousTail = __mmBushRestoreTail(v.tailIndex)),
      __mmEquipGearPair(11, __mmCorruptXWings, !0));
    return;
  }
  if (
    String(__mmSpikeGearCounterTargetSid) !== String(__mmEnemy.sid) ||
    __mmSwingAge < 0 ||
    __mmSwingAge > __mmServerTickMs() * 1.55 ||
    !__mmWeaponReady(__mmPrimary) ||
    __mmSpikeGearCounterRestoreTimer
  ) {
    Date.now() - __mmSpikeGearCounterArmedAt > 650 &&
      __mmResetSpikeGearCounter(!0);
    return;
  }
  const __mmAngle = Math.atan2(__mmEnemy.y - v.y, __mmEnemy.x - v.x),
    __mmRestore = __mmSelectedTool();
  try {
    (__mmActivateCombatHat(7),
      O.send("D", __mmAngle),
      je(__mmPrimary, !0),
      O.send("F", 1, __mmAngle));
  } catch (__mmSpikeGearCounterError) {
    return void __mmResetSpikeGearCounter(!0);
  }
  __mmSpikeGearCounterRestoreTimer = setTimeout(function () {
    ((__mmSpikeGearCounterRestoreTimer = 0),
      v && v.alive && O.send("F", 0, __mmAngle),
      __mmActionMayRestore("spikeGearCounter") && __mmRestoreTool(__mmRestore),
      __mmResetSpikeGearCounter(!0),
      __mmScheduleMouseAimReturn());
  }, __mmServerTickMs());
}
function __mmStartSpikeGearCounter() {
  __mmEnsureOperationPipeline();
}
function __mmLethalCombatThreat() {
  const __mmThreat = __mmCombatThreatSnapshot();
  return __mmThreat.lethal && __mmThreat.damage > 0
    ? {
        damage: __mmThreat.damage,
        angle: Number.isFinite(__mmThreat.angle) ? __mmThreat.angle : Ci(),
        projectileDamage: __mmThreat.projectileDamage,
        turretDamage: __mmThreat.turretDamage,
        meleeDamage: __mmThreat.meleeDamage,
        spikeDamage: __mmThreat.spikeDamage,
        firstImpactMs: __mmThreat.firstImpactMs,
      }
    : null;
}
function __mmCanUseAntiInsta() {
  return !!(
    __mmAntiInstaEnabled &&
    !__mmEmergencyGetawayActive() &&
    !__mmHoldingMcGrabby() &&
    __mmActionCanPreempt("antiInsta") &&
    v &&
    v.alive &&
    !__mmTrapAttackActive &&
    !__mmBoostBreakHeld &&
    !__mmBuildSpamTimer &&
    !__mmFoodSpamTimer &&
    !__mmShieldDefenseTimer
  );
}
function __mmPlaceAntiInstaSpike(__mmAngle) {
  if (__mmEmergencyGetawayActive() || __mmHoldingMcGrabby()) return !1;
  const __mmSpike = __mmSpikeItem();
  if (__mmSpike == null || !__mmCanUseBuildItem(__mmSpike)) return !1;
  const __mmTool = __mmSelectedTool();
  return __mmSendAutomaticPlacement(__mmSpike, __mmAngle, __mmTool);
}
function __mmUpdateAntiInsta() {
  if (
    !__mmAntiInstaEnabled ||
    __mmEmergencyGetawayActive() ||
    !v ||
    !v.alive ||
    __mmHoldingMcGrabby()
  )
    return;
  const __mmNow = Date.now();
  if (__mmNow - __mmAntiInstaLastAt < 450) return;
  const __mmThreat = __mmLethalCombatThreat();
  if (!__mmThreat) return;
  // One shared forecast covers melee, hostile projectiles, turret bullets and
  // a knockback spike follow-up. Held mouse attacks loan the build channel and
  // are re-armed immediately after the defensive spike.
  __mmInsta.isActive() && __mmInsta.cancel("lethal-combat-threat");
  __mmInstaSyncPending || __mmInstaSyncFiring ? __mmStopInstaSync() : null;
  if (!__mmActionCanPreempt("antiInsta")) return;
  __mmActionOwner === "shieldDefense" &&
    __mmStopShieldDefense("lethal combat priority");
  __mmBoostBreakHeld && __mmStopBoostBreak();
  __mmActionOwner === "weaponRecharge" && __mmPauseWeaponRecharge(!0);
  if (!__mmActionClaim("antiInsta", "lethal combat forecast")) return;
  // Anti Insta is the sole defensive path allowed to break an active manual
  // Bull/Tank lock immediately.
  __mmCancelCombatHatLock(!0);
  if (!__mmCanUseAntiInsta())
    return void __mmActionRelease("antiInsta", "unsafe to place");
  if (!__mmPlaceAntiInstaSpike(__mmThreat.angle))
    return void __mmActionRelease("antiInsta", "no spike");
  ((__mmAntiInstaLastAt = __mmNow),
    (__mmAntiInstaUntil = __mmNow + Math.max(140, __mmServerTickMs())),
    __mmAntiInstaActionTimer && clearTimeout(__mmAntiInstaActionTimer),
    (__mmAntiInstaActionTimer = setTimeout(function () {
      ((__mmAntiInstaActionTimer = 0),
        __mmActionRelease("antiInsta", "threat window complete"));
    }, Math.max(140, __mmServerTickMs()))));
}
function __mmStartAntiInsta() {
  __mmEnsureOperationPipeline();
}
function __mmProjectileTravelDistance(__mmFrom, __mmTarget) {
  return Math.max(
    0,
    Math.hypot(__mmTarget.x - __mmFrom.x, __mmTarget.y - __mmFrom.y) -
      (Number(__mmFrom.scale) || 35) -
      (Number(__mmTarget.scale) || 35),
  );
}
function __mmDirectFriendlyProjectileSource(__mmProjectile) {
  if (!v || !v.alive || !__mmProjectile || !__mmProjectile.owner) return null;
  const __mmOwner = __mmProjectile.owner,
    __mmOwnerSid = __mmOwner.sid;
  // A normal shot from this player should not recursively trigger another
  // sync shot. Personal structures are allowed through the nested owner path.
  if (
    __mmOwner === v ||
    (__mmOwnerSid != null && String(__mmOwnerSid) === String(v.sid))
  )
    return null;
  let __mmOwnerPlayer =
    __mmOwnerSid != null && typeof Rt === "function" ? Rt(__mmOwnerSid) : null;
  if (__mmSameTeam(__mmOwnerPlayer || __mmOwner))
    return __mmOwnerPlayer || __mmOwner;
  const __mmStructureOwner = __mmOwner.owner,
    __mmStructureOwnerSid = __mmStructureOwner && __mmStructureOwner.sid;
  if (!__mmStructureOwner) return null;
  if (String(__mmStructureOwnerSid) === String(v.sid)) return __mmOwner;
  __mmOwnerPlayer =
    __mmStructureOwnerSid != null && typeof Rt === "function"
      ? Rt(__mmStructureOwnerSid)
      : null;
  return __mmSameTeam(__mmOwnerPlayer || __mmStructureOwner)
    ? __mmOwner
    : null;
}
function __mmFriendlyProjectileSource(__mmProjectile) {
  if (!__mmProjectile || !Array.isArray(E)) return null;
  const __mmX = Number(__mmProjectile.x),
    __mmY = Number(__mmProjectile.y),
    __mmDirection = Number(__mmProjectile.dir);
  if (
    !Number.isFinite(__mmX) ||
    !Number.isFinite(__mmY) ||
    !Number.isFinite(__mmDirection)
  )
    return null;
  let __mmClosest = null,
    __mmClosestDistance = Infinity;
  for (let __mmIndex = 0; __mmIndex < E.length; __mmIndex++) {
    const __mmPlayer = E[__mmIndex];
    if (
      !__mmPlayer ||
      !__mmPlayer.alive ||
      !__mmPlayer.visible ||
      !__mmSameTeam(__mmPlayer)
    )
      continue;
    const __mmDx = __mmX - __mmPlayer.x,
      __mmDy = __mmY - __mmPlayer.y,
      __mmDistance = Math.hypot(__mmDx, __mmDy),
      __mmForward =
        __mmDx * Math.cos(__mmDirection) +
        __mmDy * Math.sin(__mmDirection),
      __mmSide = Math.abs(
        __mmDx * Math.sin(__mmDirection) -
          __mmDy * Math.cos(__mmDirection),
      );
    if (
      __mmForward < -35 ||
      __mmSide > 125 ||
      __mmDistance > Math.max(320, (Number(__mmPlayer.scale) || 35) + 180) ||
      __mmDistance >= __mmClosestDistance
    )
      continue;
    ((__mmClosest = __mmPlayer), (__mmClosestDistance = __mmDistance));
  }
  return __mmClosest;
}
function __mmPersonalTurretProjectileSource(__mmProjectile) {
  if (!v || !v.alive || !__mmProjectile) return null;
  const __mmX = Number(__mmProjectile.x),
    __mmY = Number(__mmProjectile.y),
    __mmDirection = Number(__mmProjectile.dir);
  if (
    !Number.isFinite(__mmX) ||
    !Number.isFinite(__mmY) ||
    !Number.isFinite(__mmDirection)
  )
    return null;
  const __mmTurrets = __mmActiveObjectSnapshot().turrets;
  for (let __mmIndex = 0; __mmIndex < __mmTurrets.length; __mmIndex++) {
    const __mmObject = __mmTurrets[__mmIndex],
      __mmItem = __mmObject && b.list[__mmObject.id];
    if (
      !__mmObject ||
      !__mmObject.active ||
      !__mmItem ||
      String(__mmItem.name || "").toLowerCase() !== "turret" ||
      !__mmObject.owner
    )
      continue;
    const __mmOwnerSid = __mmObject.owner.sid,
      __mmOwnerPlayer =
        String(__mmOwnerSid) === String(v.sid)
          ? v
          : typeof Rt === "function"
            ? Rt(__mmOwnerSid)
            : null;
    if (
      String(__mmOwnerSid) !== String(v.sid) &&
      !__mmSameTeam(__mmOwnerPlayer || __mmObject.owner)
    )
      continue;
    const __mmDx = __mmX - __mmObject.x,
      __mmDy = __mmY - __mmObject.y,
      __mmDistance = Math.hypot(__mmDx, __mmDy),
      __mmForward =
        __mmDx * Math.cos(__mmDirection) +
        __mmDy * Math.sin(__mmDirection),
      __mmSide = Math.abs(
        __mmDx * Math.sin(__mmDirection) -
          __mmDy * Math.cos(__mmDirection),
      );
    if (
      __mmForward >= -35 &&
      __mmSide <= Math.max(150, Number(__mmObject.scale) || 0) &&
      __mmDistance <= Math.max(340, (Number(__mmObject.scale) || 45) + 200)
    )
      return __mmObject;
  }
  return null;
}
function __mmSyncPlayerVelocity(__mmPlayer) {
  if (!__mmPlayer) return { x: 0, y: 0 };
  const __mmElapsed = Number(__mmPlayer.t2) - Number(__mmPlayer.t1),
    __mmX =
      (Number(__mmPlayer.x2) - Number(__mmPlayer.x1)) / __mmElapsed,
    __mmY =
      (Number(__mmPlayer.y2) - Number(__mmPlayer.y1)) / __mmElapsed;
  return __mmElapsed > 0 &&
    __mmElapsed <= 500 &&
    Number.isFinite(__mmX) &&
    Number.isFinite(__mmY)
    ? { x: Math.max(-1.5, Math.min(1.5, __mmX)), y: Math.max(-1.5, Math.min(1.5, __mmY)) }
    : { x: 0, y: 0 };
}
function __mmProjectileEnemyTarget(__mmProjectile) {
  const __mmPlayers = __mmLiveStateFresh() ? __mmLiveState.enemies : E;
  if (!__mmProjectile || !Array.isArray(__mmPlayers)) return null;
  const __mmX = Number(__mmProjectile.x),
    __mmY = Number(__mmProjectile.y),
    __mmDirection = Number(__mmProjectile.dir),
    __mmSpeed = Number(__mmProjectile.speed),
    __mmRange = Number(__mmProjectile.range);
  if (
    !Number.isFinite(__mmX) ||
    !Number.isFinite(__mmY) ||
    !Number.isFinite(__mmDirection) ||
    !Number.isFinite(__mmSpeed) ||
    __mmSpeed <= 0
  )
    return null;
  let __mmTarget = null,
    __mmForwardBest = Infinity;
  for (let __mmIndex = 0; __mmIndex < __mmPlayers.length; __mmIndex++) {
    const __mmPlayer = __mmPlayers[__mmIndex];
    if (!__mmIsEnemyPlayer(__mmPlayer)) continue;
    let __mmDx = __mmPlayer.x - __mmX,
      __mmDy = __mmPlayer.y - __mmY,
      __mmForward =
        __mmDx * Math.cos(__mmDirection) +
        __mmDy * Math.sin(__mmDirection);
    const __mmVelocity = __mmSyncPlayerVelocity(__mmPlayer),
      __mmInitialArrival = Math.max(0, __mmForward) / __mmSpeed,
      __mmLead = Math.min(400, __mmInitialArrival);
    (__mmDx += __mmVelocity.x * __mmLead,
      __mmDy += __mmVelocity.y * __mmLead,
      (__mmForward =
        __mmDx * Math.cos(__mmDirection) +
        __mmDy * Math.sin(__mmDirection)));
    const __mmSide = Math.abs(
        __mmDx * Math.sin(__mmDirection) -
          __mmDy * Math.cos(__mmDirection),
      ),
      __mmHitRadius =
        (Number(__mmPlayer.scale) || 35) +
        (Number(__mmProjectile.scale) || 0) +
        18;
    if (
      __mmForward < 0 ||
      __mmSide > __mmHitRadius ||
      (Number.isFinite(__mmRange) && __mmForward > __mmRange + __mmHitRadius) ||
      __mmForward >= __mmForwardBest
    )
      continue;
    ((__mmTarget = __mmPlayer), (__mmForwardBest = __mmForward));
  }
  return __mmTarget
    ? {
        target: __mmTarget,
        arrivalMs: __mmForwardBest / __mmSpeed,
      }
    : null;
}
function __mmSyncProjectileWeapons(__mmTarget) {
  if (!v || !v.alive || !v.weapons || !__mmTarget) return [];
  const __mmDistance = __mmProjectileTravelDistance(v, __mmTarget);
  const __mmShots = [],
    __mmSeen = new Set();
  for (const __mmWeapon of [v.weapons[1], v.weapons[0]]) {
    if (__mmWeapon == null || __mmSeen.has(__mmWeapon)) continue;
    __mmSeen.add(__mmWeapon);
    const __mmWeaponData =
        b.weapons[__mmWeapon],
      __mmProjectile =
        __mmWeaponData && __mmWeaponData.projectile != null
          ? b.projectiles[__mmWeaponData.projectile]
          : null,
      __mmSpeed = __mmProjectile && Number(__mmProjectile.speed),
      __mmRange = __mmProjectile && Number(__mmProjectile.range);
    if (
      !__mmWeaponData ||
      !__mmProjectile ||
      !__mmWeaponReady(__mmWeapon) ||
      !Number.isFinite(__mmSpeed) ||
      __mmSpeed <= 0 ||
      !Number.isFinite(__mmRange) ||
      __mmDistance > __mmRange
    )
      continue;
    __mmShots.push({
      type: "projectile",
      weapon: __mmWeapon,
      // A weapon packet normally lands between server updates. Include half a
      // tick of launch latency so the arrival scheduler does not fire late.
      travelMs:
        Math.min(55, __mmServerTickMs() * 0.5) +
        __mmDistance / __mmSpeed,
    });
  }
  return __mmShots;
}
function __mmSyncTurretShot(__mmTarget) {
  if (
    !v ||
    !v.alive ||
    !__mmTarget ||
    !v.skins ||
    !v.skins[__mmTurretGear] ||
    !__mmInsta.turretReady()
  )
    return null;
  const __mmDistance = __mmProjectileTravelDistance(v, __mmTarget);
  if (__mmDistance > __mmTurretGearRange) return null;
  // Turret shots use the bullet travel profile. Account for one gear-apply
  // tick before its shot can leave the player.
  return {
    type: "turret",
    travelMs: __mmServerTickMs() + __mmDistance / 3.6,
  };
}
function __mmSyncShotsForTarget(__mmTarget) {
  const __mmTurret = __mmSyncTurretShot(__mmTarget);
  return (__mmTurret ? [__mmTurret] : []).concat(
    __mmSyncProjectileWeapons(__mmTarget),
  );
}
function __mmSyncAimAngle(__mmTarget, __mmTravelMs) {
  const __mmVelocity = __mmSyncPlayerVelocity(__mmTarget),
    __mmPing = Number(window.pingTime),
    __mmLead = Math.min(
      450,
      Math.max(0, Number(__mmTravelMs) || 0) +
        (Number.isFinite(__mmPing) ? Math.max(0, __mmPing / 2) : 0),
    ),
    __mmTargetX = __mmTarget.x + __mmVelocity.x * __mmLead,
    __mmTargetY = __mmTarget.y + __mmVelocity.y * __mmLead;
  return Math.atan2(__mmTargetY - v.y, __mmTargetX - v.x);
}
function __mmCanFireInstaSync() {
  return !!(
    __mmInstaSyncEnabled &&
    (__mmActionAvailable("instaSync") ||
      __mmActionOwner === "weaponRecharge" ||
      __mmActionOwner === "matThief" ||
      __mmActionOwner === "mobSteal") &&
    v &&
    v.alive &&
    !__mmInsta.isActive() &&
    !__mmPrimaryHeld &&
    !__mmSecondaryHeld &&
    !__mmTrapAttackActive &&
    !__mmBoostBreakHeld &&
    !__mmBuildSpamTimer &&
    !__mmFoodSpamTimer &&
    !__mmShieldDefenseTimer &&
    !__mmInstaSyncFiring
  );
}
function __mmFinishInstaSync() {
  const __mmTool = __mmInstaSyncRestoreTool,
    __mmHat = __mmInstaSyncRestoreHat,
    __mmRestore = __mmActionMayRestore("instaSync");
  (__mmInstaSyncReleaseTimer && clearTimeout(__mmInstaSyncReleaseTimer),
    (__mmInstaSyncReleaseTimer = 0),
    __mmInstaSyncWeaponHeld && O.send("F", 0, null),
    (__mmInstaSyncWeaponHeld = !1),
    (__mmInstaSyncRestoreTool = null),
    (__mmInstaSyncRestoreHat = null),
    (__mmInstaSyncFiring = !1),
    __mmRestore && __mmHat != null && __mmEquipHatNow(__mmHat),
    __mmRestore && __mmRestoreTool(__mmTool),
    __mmActionRelease("instaSync", "sync shot complete"));
}
function __mmStopInstaSync() {
  (__mmInstaSyncTimer && clearTimeout(__mmInstaSyncTimer),
    (__mmInstaSyncTimer = 0),
    (__mmInstaSyncPending = !1),
    __mmFinishInstaSync());
}
function __mmFireInstaSync(__mmShot, __mmTargetSid) {
  ((__mmInstaSyncTimer = 0), (__mmInstaSyncPending = !1));
  let __mmTarget = null;
  try {
    __mmTarget = Rt(__mmTargetSid);
  } catch (__mmLookupError) {}
  if (!__mmCanFireInstaSync() || !__mmIsEnemyPlayer(__mmTarget))
    return void __mmFinishInstaSync();
  const __mmAngle = __mmSyncAimAngle(__mmTarget, __mmShot.travelMs);
  ((__mmInstaSyncFiring = !0), (__mmInstaSyncLastAt = Date.now()));
  __mmSmartPlaceUtilityForInsta(
    __mmTarget,
    __mmShot.weapon != null ? __mmShot.weapon : v.weapons && v.weapons[0],
  );
  if (__mmShot.type === "turret") {
    ((__mmInstaSyncRestoreHat = __mmInstaSafeRestoreHat(
      __mmBushRestoreHat(v.skinIndex),
    )),
      __mmEquipHatNow(__mmTurretGear),
      __mmAssumeTurretGearShot(),
      O.send("D", __mmAngle),
      (__mmInstaSyncReleaseTimer = setTimeout(
        __mmFinishInstaSync,
        __mmServerTickMs(),
      )));
    return;
  }
  if (
    __mmShot.weapon == null ||
    !__mmWeaponReady(__mmShot.weapon) ||
    !v.weapons.includes(__mmShot.weapon)
  )
    return void __mmFinishInstaSync();
  ((__mmInstaSyncRestoreTool = __mmSelectedTool()),
    je(__mmShot.weapon, !0),
    O.send("D", __mmAngle),
    O.send("F", 1, __mmAngle),
    (__mmInstaSyncWeaponHeld = !0),
    (__mmInstaSyncReleaseTimer = setTimeout(
      __mmFinishInstaSync,
      __mmServerTickMs(),
    )));
}
function __mmScheduleInstaSync(__mmProjectile, __mmTargetInfo) {
  if (
    !__mmCanFireInstaSync() ||
    __mmInstaSyncPending ||
    Date.now() - __mmInstaSyncLastAt < 45
  )
    return !1;
  const __mmShots = __mmSyncShotsForTarget(__mmTargetInfo.target),
    __mmPing = Number(window.pingTime),
    __mmOneWayPing = Number.isFinite(__mmPing) ? Math.max(0, __mmPing / 2) : 0;
  let __mmChoice = null;
  for (let __mmIndex = 0; __mmIndex < __mmShots.length; __mmIndex++) {
    const __mmShot = __mmShots[__mmIndex],
      __mmRawDelay =
        __mmTargetInfo.arrivalMs - __mmShot.travelMs - __mmOneWayPing;
    // Do not schedule a shot that is already meaningfully too late. Among
    // viable shots, prefer the one that can leave soonest for less aim drift.
    if (__mmRawDelay < -35 || __mmRawDelay > 900) continue;
    const __mmDelay = Math.max(0, Math.round(__mmRawDelay));
    if (!__mmChoice || __mmDelay < __mmChoice.delay)
      __mmChoice = { shot: __mmShot, delay: __mmDelay };
  }
  if (!__mmChoice) return !1;
  if (!__mmActionClaim("instaSync", "friendly projectile")) return !1;
  __mmCancelCombatHatLock(!1);
  ((__mmInstaSyncPending = !0),
    __mmChoice.delay <= 1
      ? __mmFireInstaSync(__mmChoice.shot, __mmTargetInfo.target.sid)
      : (__mmInstaSyncTimer = setTimeout(function () {
          __mmFireInstaSync(__mmChoice.shot, __mmTargetInfo.target.sid);
        }, __mmChoice.delay)));
  return !0;
}
function __mmUpdateInstaSync() {
  __mmObserveProjectileCooldowns();
  if (
    (!__mmInstaSyncEnabled && !__mmAutoBowUpgradeInstaEnabled) ||
    __mmInstaSyncPending ||
    __mmInstaSyncFiring ||
    !Array.isArray(Ve)
  )
    return;
  for (let __mmIndex = 0; __mmIndex < Ve.length; __mmIndex++) {
    const __mmProjectile = Ve[__mmIndex];
    if (!__mmProjectile) continue;
    const __mmSid = __mmProjectile.sid,
      __mmRange = Number(__mmProjectile.range),
      __mmPreviousState = __mmInstaSyncProjectileStates.get(__mmProjectile),
      __mmNewGeneration = !!(
        __mmProjectile.active &&
        (!__mmPreviousState ||
          !__mmPreviousState.active ||
          (__mmSid != null && String(__mmSid) !== __mmPreviousState.sid) ||
          (Number.isFinite(__mmRange) &&
            Number.isFinite(__mmPreviousState.range) &&
            __mmRange > __mmPreviousState.range + 20))
      ),
      __mmState = __mmNewGeneration
        ? {
            active: !0,
            handled: !1,
            sid: __mmSid == null ? "" : String(__mmSid),
            range: __mmRange,
          }
        : __mmPreviousState || {
            active: !!__mmProjectile.active,
            handled: !1,
            sid: __mmSid == null ? "" : String(__mmSid),
            range: __mmRange,
          };
    ((__mmState.active = !!__mmProjectile.active),
      (__mmState.range = __mmRange),
      __mmInstaSyncProjectileStates.set(__mmProjectile, __mmState));
    if (!__mmProjectile.active || __mmState.handled) continue;
    if (
      !__mmDirectFriendlyProjectileSource(__mmProjectile) &&
      !__mmFriendlyProjectileSource(__mmProjectile) &&
      !__mmPersonalTurretProjectileSource(__mmProjectile)
    )
      continue;
    const __mmTargetInfo = __mmProjectileEnemyTarget(__mmProjectile);
    if (!__mmTargetInfo) continue;
    if (__mmAutoBowUpgradeInstaEnabled) {
      const __mmBowReady = __mmBowUpgradeInsta.ready(__mmTargetInfo.target),
        __mmMeleeChainReady =
          __mmBowReady &&
          __mmInsta.supportedPrimary() != null &&
          __mmInsta.fullBurstReady(__mmTargetInfo.target, "normal", !1),
        __mmBowSyncStarted = __mmMeleeChainReady
          ? __mmInsta.start({
              automatic: !0,
              targetSid: __mmTargetInfo.target.sid,
              syncScheduled: !0,
              profile: "normal",
              profileSource: "Friendly projectile + Bow Upgrade",
              bowUpgradeFollowup: !0,
            })
          : __mmBowReady &&
            __mmBowUpgradeInsta.start(
              __mmTargetInfo.target,
              "friendly projectile sync",
            );
      if (__mmBowSyncStarted) {
        __mmState.handled = !0;
        return;
      }
    }
    if (__mmScheduleInstaSync(__mmProjectile, __mmTargetInfo)) {
      __mmState.handled = !0;
      return;
    }
  }
}
function __mmStartInstaSync() {
  __mmEnsureOperationPipeline();
}
function __mmMaxBuildCount(__mmItem) {
  const __mmData = b && b.list && b.list[__mmItem];
  if (!v || !__mmData || !Array.isArray(__mmData.req)) return 0;
  let __mmCount = Infinity;
  for (
    let __mmReqIndex = 0;
    __mmReqIndex < __mmData.req.length;
    __mmReqIndex += 2
  )
    __mmCount = Math.min(
      __mmCount,
      Math.floor(
        (v[__mmData.req[__mmReqIndex]] || 0) / __mmData.req[__mmReqIndex + 1],
      ),
    );
  const __mmGroup = __mmData.group,
    __mmGroupId = __mmGroup && __mmGroup.id;
  if (__mmGroupId != null) {
    const __mmLimit = __mmBuildGroupLimit(__mmData),
      __mmPlaced = Number(v.itemCounts && v.itemCounts[__mmGroupId]) || 0;
    let __mmReserved = 0;
    for (
      let __mmReservationIndex = 0;
      __mmReservationIndex < __mmAutoSpikeSpamReservations.length;
      __mmReservationIndex++
    ) {
      const __mmReservation =
          __mmAutoSpikeSpamReservations[__mmReservationIndex],
        __mmReservedData =
          __mmReservation && b.list[__mmReservation.item];
      __mmReservedData &&
        __mmReservedData.group &&
        __mmReservedData.group.id === __mmGroupId &&
        __mmReserved++;
    }
    __mmLimit &&
      (__mmCount = Math.min(
        __mmCount,
        Math.max(0, __mmLimit - __mmPlaced - __mmReserved),
      ));
  }
  return Number.isFinite(__mmCount) ? Math.max(0, __mmCount) : 0;
}
function __mmSmartBuildItem(__mmMatcher) {
  if (!v || !v.items || !b || !b.list) return null;
  for (let __mmIndex = 0; __mmIndex < v.items.length; __mmIndex++) {
    const __mmItem = v.items[__mmIndex],
      __mmData = b.list[__mmItem];
    if (
      __mmData &&
      __mmMatcher(__mmData) &&
      __mmCanUseBuildItem(__mmItem) &&
      __mmMaxBuildCount(__mmItem) > 0
    )
      return __mmItem;
  }
  return null;
}
function __mmSmartPitTrapItem() {
  return __mmSmartBuildItem(function (__mmData) {
    return !!__mmData.trap;
  });
}
function __mmSmartMillItem() {
  return __mmSmartBuildItem(function (__mmData) {
    return /mill/i.test(String(__mmData.name || ""));
  });
}
function __mmSmartNamedItem(__mmName) {
  const __mmNeedle = String(__mmName || "").toLowerCase();
  return __mmSmartBuildItem(function (__mmData) {
    return String(__mmData.name || "").toLowerCase() === __mmNeedle;
  });
}
function __mmSmartBlockingObject(__mmX, __mmY, __mmScale) {
  const __mmObjects = __mmActiveObjectSnapshot().all;
  let __mmClosest = null,
    __mmClosestGap = Infinity;
  for (let __mmIndex = 0; __mmIndex < __mmObjects.length; __mmIndex++) {
    const __mmObject = __mmObjects[__mmIndex];
    if (!__mmObject || !__mmObject.active) continue;
    const __mmObjectScale = __mmAutoSpikeSpamObjectScale(__mmObject),
      __mmGap =
        Math.hypot(
          Number(__mmObject.x) - __mmX,
          Number(__mmObject.y) - __mmY,
        ) -
        (__mmScale + __mmObjectScale);
    if (__mmGap < 0 && __mmGap < __mmClosestGap)
      ((__mmClosest = __mmObject), (__mmClosestGap = __mmGap));
  }
  return __mmClosest;
}
function __mmSmartCollisionResult(__mmItem, __mmX, __mmY, __mmScale) {
  if (
    !y ||
    !Number.isFinite(__mmX) ||
    !Number.isFinite(__mmY) ||
    !Number.isFinite(__mmScale)
  )
    return { clear: !1, reason: "invalid geometry" };
  if (
    __mmX - __mmScale < 0 ||
    __mmY - __mmScale < 0 ||
    __mmX + __mmScale > Number(y.mapScale) ||
    __mmY + __mmScale > Number(y.mapScale)
  )
    return { clear: !1, reason: "map edge" };
  if (
    Number(__mmItem) !== 18 &&
    __mmY >= Number(y.mapScale) / 2 - Number(y.riverWidth) / 2 &&
    __mmY <= Number(y.mapScale) / 2 + Number(y.riverWidth) / 2
  )
    return { clear: !1, reason: "river" };
  for (
    let __mmIndex = 0;
    __mmIndex < __mmAutoSpikeSpamReservations.length;
    __mmIndex++
  ) {
    const __mmReservation = __mmAutoSpikeSpamReservations[__mmIndex];
    if (
      __mmReservation &&
      Math.hypot(
        Number(__mmReservation.x) - __mmX,
        Number(__mmReservation.y) - __mmY,
      ) <
        (Number(__mmReservation.scale) || 0) + __mmScale
    )
      return { clear: !1, reason: "pending placement" };
  }
  if (X && typeof X.checkItemLocation === "function")
    try {
      // The current official client accepts seven arguments. Its seventh is
      // retained for compatibility even though the current implementation
      // ignores it; the old eighth ge argument never belonged here.
      if (
        X.checkItemLocation(
          __mmX,
          __mmY,
          __mmScale,
          0.6,
          __mmItem,
          !1,
          v,
        )
      )
        return { clear: !0, reason: "legal" };
      return { clear: !1, reason: "occupied" };
    } catch (__mmSmartLocationError) {}
  const __mmFallbackBlocker = __mmSmartBlockingObject(
    __mmX,
    __mmY,
    __mmScale,
  );
  if (__mmFallbackBlocker) {
    const __mmFallbackData =
      b && b.list && b.list[__mmFallbackBlocker.id];
    return {
      clear: !1,
      reason: "blocked by " +
        String((__mmFallbackData && __mmFallbackData.name) || "structure"),
    };
  }
  return { clear: !0, reason: "legal fallback" };
}
function __mmSmartPositionClear(__mmItem, __mmX, __mmY, __mmScale) {
  return __mmSmartCollisionResult(
    __mmItem,
    __mmX,
    __mmY,
    __mmScale,
  ).clear;
}
function __mmSmartSetStatus(__mmState, __mmReason, __mmDetails) {
  const __mmInfo = __mmDetails || {},
    __mmNow = Date.now();
  ((__mmSmartPlacementStats.state = String(__mmState || "idle")),
    (__mmSmartPlacementStats.reason = String(__mmReason || "waiting")),
    Number.isFinite(Number(__mmInfo.legal)) &&
      (__mmSmartPlacementStats.legal = Number(__mmInfo.legal)),
    Number.isFinite(Number(__mmInfo.scored)) &&
      (__mmSmartPlacementStats.scored = Number(__mmInfo.scored)),
    Number.isFinite(Number(__mmInfo.blocked)) &&
      (__mmSmartPlacementStats.blocked = Number(__mmInfo.blocked)),
    typeof __mmInfo.itemSummary === "string" &&
      (__mmSmartPlacementStats.itemSummary = __mmInfo.itemSummary),
    (__mmSmartPlacementStats.updatedAt = __mmNow));
  const __mmSignature = [
    __mmSmartPlacementStats.state,
    __mmSmartPlacementStats.reason,
    __mmSmartPlacementStats.legal,
    __mmSmartPlacementStats.scored,
    __mmSmartPlacementStats.sent,
    __mmSmartPlacementStats.itemSummary,
  ].join("|");
  if (
    __mmSignature !== __mmSmartPlacementStats.signature ||
    __mmNow - __mmSmartPlacementStats.broadcastAt >= 250
  ) {
    ((__mmSmartPlacementStats.signature = __mmSignature),
      (__mmSmartPlacementStats.broadcastAt = __mmNow),
      window.dispatchEvent(
        new CustomEvent("MooMooKittyPlacementStatus", {
          detail: {
            state: __mmSmartPlacementStats.state,
            reason: __mmSmartPlacementStats.reason,
            legal: __mmSmartPlacementStats.legal,
            scored: __mmSmartPlacementStats.scored,
            sent: __mmSmartPlacementStats.sent,
            failed: __mmSmartPlacementStats.failed,
            blocked: __mmSmartPlacementStats.blocked,
            itemSummary: __mmSmartPlacementStats.itemSummary,
          },
        }),
      ));
  }
}
function __mmSmartSetPlacementPreview(
  __mmCandidates,
  __mmSelected,
  __mmReason,
) {
  if (!__mmPlacementVisualsEnabled) return;
  const __mmRanked = (Array.isArray(__mmCandidates) ? __mmCandidates : [])
    .filter(function (__mmCandidate) {
      return __mmCandidate && __mmCandidate.valid !== !1 && __mmCandidate.points > 0;
    })
    .slice()
    .sort(function (__mmLeft, __mmRight) {
      return __mmRight.points - __mmLeft.points;
    })
    .slice(0, __mmFpsBoostEnabled ? 8 : 14);
  __mmSmartPlacementPreview = {
    samples: __mmSmartPreviewSamples.slice(
      0,
      __mmFpsBoostEnabled ? 30 : 54,
    ),
    ranked: __mmRanked,
    selected: (Array.isArray(__mmSelected) ? __mmSelected : []).slice(0, 4),
    reason: String(__mmReason || "scanning"),
    updatedAt: performance.now(),
  };
}
function __mmSmartCandidateForAngle(
  __mmItem,
  __mmAngle,
  __mmIncludeBlocked,
) {
  const __mmData = b && b.list && b.list[__mmItem];
  if (!v || !v.alive || !__mmData) return null;
  const __mmPlayerX = v.x2 != null && Number.isFinite(Number(v.x2))
      ? Number(v.x2)
      : Number(v.x),
    __mmPlayerY = v.y2 != null && Number.isFinite(Number(v.y2))
      ? Number(v.y2)
      : Number(v.y),
    __mmScale = Number(__mmData.scale) || 45,
    __mmOffset =
      (Number(v.scale) || 35) +
      __mmScale +
      (Number(__mmData.placeOffset) || 0),
    __mmX = __mmPlayerX + Math.cos(__mmAngle) * __mmOffset,
    __mmY = __mmPlayerY + Math.sin(__mmAngle) * __mmOffset,
    __mmCollision = __mmSmartCollisionResult(
      __mmItem,
      __mmX,
      __mmY,
      __mmScale,
    ),
    __mmValid = __mmCollision.clear;
  if (!__mmValid && !__mmIncludeBlocked) return null;
  return {
    item: __mmItem,
    data: __mmData,
    angle: __mmAngle,
    x: __mmX,
    y: __mmY,
    scale: __mmScale,
    valid: __mmValid,
    blockReason: __mmCollision.reason,
    points: 0,
    preplace: !1,
    priority: !1,
    reasons: [],
  };
}
function __mmSmartNearestLegalCandidate(
  __mmItem,
  __mmPreferredAngle,
  __mmMaxSweep = 0.7,
  __mmStep = 0.045,
) {
  const __mmDirect = __mmSmartCandidateForAngle(
    __mmItem,
    __mmPreferredAngle,
  );
  if (__mmDirect) return __mmDirect;
  const __mmSteps = Math.max(
    1,
    Math.ceil(Math.max(0, Number(__mmMaxSweep) || 0) /
      Math.max(0.015, Number(__mmStep) || 0.045)),
  );
  for (let __mmIndex = 1; __mmIndex <= __mmSteps; __mmIndex++) {
    const __mmOffset = __mmIndex * __mmStep,
      __mmLeft = __mmSmartCandidateForAngle(
        __mmItem,
        __mmPreferredAngle - __mmOffset,
      );
    if (__mmLeft) return __mmLeft;
    const __mmRight = __mmSmartCandidateForAngle(
      __mmItem,
      __mmPreferredAngle + __mmOffset,
    );
    if (__mmRight) return __mmRight;
  }
  return null;
}
function __mmSmartDepthScale() {
  // Five is the compatibility midpoint. Lower values spend less CPU; higher
  // values search wider and lead farther without changing packet cadence.
  return 0.72 + __mmEffectiveSmartDepth() * 0.056;
}
function __mmSmartDepthEnemyLimit() {
  return Math.max(1, Math.min(5, Math.ceil(__mmEffectiveSmartDepth() / 2)));
}
function __mmSmartEnemyPrediction(__mmEnemy, __mmNow) {
  const __mmSid = String(__mmEnemy.sid),
    __mmX = Number(__mmEnemy.x),
    __mmY = Number(__mmEnemy.y),
    __mmState =
      __mmSmartPlacementMotion[__mmSid] ||
      (__mmSmartPlacementMotion[__mmSid] = {
        x: __mmX,
        y: __mmY,
        at: __mmNow,
        vx: 0,
        vy: 0,
      });
  if (__mmState.x !== __mmX || __mmState.y !== __mmY) {
    const __mmElapsed = Math.max(1, Math.min(250, __mmNow - __mmState.at));
    ((__mmState.vx = (__mmX - __mmState.x) / __mmElapsed),
      (__mmState.vy = (__mmY - __mmState.y) / __mmElapsed),
      (__mmState.x = __mmX),
      (__mmState.y = __mmY),
      (__mmState.at = __mmNow));
  }
  const __mmServerElapsed =
      Number(__mmEnemy.t2) - Number(__mmEnemy.t1),
    __mmServerVx =
      (Number(__mmEnemy.x2) - Number(__mmEnemy.x1)) / __mmServerElapsed,
    __mmServerVy =
      (Number(__mmEnemy.y2) - Number(__mmEnemy.y1)) / __mmServerElapsed,
    __mmHasServerVelocity = !!(
      Number.isFinite(__mmServerVx) &&
      Number.isFinite(__mmServerVy) &&
      __mmServerElapsed > 0 &&
      __mmServerElapsed <= 500
    );
  let __mmVelocityX = __mmHasServerVelocity
      ? __mmServerVx * 0.68 + __mmState.vx * 0.32
      : __mmState.vx,
    __mmVelocityY = __mmHasServerVelocity
      ? __mmServerVy * 0.68 + __mmState.vy * 0.32
      : __mmState.vy;
  const __mmVelocityLength = Math.hypot(__mmVelocityX, __mmVelocityY),
    __mmVelocityClamp = __mmVelocityLength > 0.72
      ? 0.72 / __mmVelocityLength
      : 1;
  ((__mmVelocityX *= __mmVelocityClamp),
    (__mmVelocityY *= __mmVelocityClamp));
  const __mmPing = Number(window.pingTime),
    __mmLead =
      (__mmServerTickMs() +
        (Number.isFinite(__mmPing) ? Math.max(0, __mmPing / 2) : 0)) *
      __mmSmartDepthScale(),
    __mmLeadX = __mmVelocityX * __mmLead,
    __mmLeadY = __mmVelocityY * __mmLead,
    __mmLeadDistance = Math.hypot(__mmLeadX, __mmLeadY),
    __mmLeadClamp = __mmLeadDistance > 170 ? 170 / __mmLeadDistance : 1;
  return {
    x: __mmX,
    y: __mmY,
    futureX: __mmX + __mmLeadX * __mmLeadClamp,
    futureY: __mmY + __mmLeadY * __mmLeadClamp,
    vx: __mmVelocityX,
    vy: __mmVelocityY,
    speed: Math.hypot(__mmVelocityX, __mmVelocityY),
  };
}
function __mmSmartFriendlyHazards() {
  const __mmResult = [],
    __mmObjects = __mmActiveObjectSnapshot().all;
  for (let __mmIndex = 0; __mmIndex < __mmObjects.length; __mmIndex++) {
    const __mmObject = __mmObjects[__mmIndex],
      __mmData = __mmObject && b && b.list && b.list[__mmObject.id];
    if (
      !__mmObject ||
      !__mmObject.active ||
      !__mmData ||
      (!__mmData.trap && !__mmData.dmg && !__mmObject.dmg) ||
      !__mmSpikeOwnedByUsOrAlly(__mmObject)
    )
      continue;
    __mmResult.push({
      object: __mmObject,
      trap: !!__mmData.trap,
      spike: !!(__mmData.dmg || __mmObject.dmg),
      scale: Number(__mmObject.scale) || Number(__mmData.scale) || 45,
    });
  }
  return __mmResult;
}
// Predictive enemy placement, knockback, angle grading, and automatic
// placement helpers with Kitty ownership and action-priority safeguards.
function __mmSmartEnemyPlacementPotentials(
  __mmEnemies,
  __mmItem,
  __mmNow,
) {
  const __mmResult = Object.create(null),
    __mmData = b && b.list && b.list[__mmItem];
  if (__mmItem == null || !__mmData) return __mmResult;
  const __mmScale = Number(__mmData.scale) || 45,
    __mmSamples = Math.max(
      10,
      Math.min(
        48,
        Math.round((__mmFpsBoostEnabled ? 18 : 28) * __mmSmartDepthScale()),
      ),
    ),
    __mmEnemyLimit = __mmSmartDepthEnemyLimit();
  for (
    let __mmEnemyIndex = 0;
    __mmEnemyIndex < Math.min(__mmEnemyLimit, __mmEnemies.length);
    __mmEnemyIndex++
  ) {
    const __mmEnemy = __mmEnemies[__mmEnemyIndex],
      __mmPrediction = __mmSmartEnemyPrediction(__mmEnemy, __mmNow),
      __mmRange =
        (Number(__mmEnemy.scale) || 35) +
        __mmScale +
        (Number(__mmData.placeOffset) || 0),
      __mmBase = Math.atan2(v.y - __mmEnemy.y, v.x - __mmEnemy.x),
      __mmPossible = [];
    for (let __mmIndex = 0; __mmIndex < __mmSamples; __mmIndex++) {
      const __mmAngle = __mmBase + (__mmIndex * Math.PI * 2) / __mmSamples,
        __mmX = __mmPrediction.futureX + Math.cos(__mmAngle) * __mmRange,
        __mmY = __mmPrediction.futureY + Math.sin(__mmAngle) * __mmRange;
      __mmSmartPositionClear(__mmItem, __mmX, __mmY, __mmScale) &&
        __mmPossible.push({
          x: __mmX,
          y: __mmY,
          scale: __mmScale,
          angle: __mmAngle,
        });
    }
    __mmResult[String(__mmEnemy.sid)] = {
      possible: __mmPossible,
      placeRange: __mmRange,
      prediction: __mmPrediction,
      trap: __mmAutoSpikeSpamTrapForEnemy(__mmEnemy),
    };
  }
  return __mmResult;
}
function __mmSmartKnockIntoHazard(
  __mmCandidate,
  __mmPrediction,
  __mmEnemyScale,
  __mmHazards,
) {
  const __mmDirection = Math.atan2(
      __mmPrediction.futureY - __mmCandidate.y,
      __mmPrediction.futureX - __mmCandidate.x,
    ),
    __mmEndX = __mmPrediction.futureX + Math.cos(__mmDirection) * 170,
    __mmEndY = __mmPrediction.futureY + Math.sin(__mmDirection) * 170;
  let __mmBest = null,
    __mmBestAlong = Infinity;
  for (
    let __mmHazardIndex = 0;
    __mmHazardIndex < __mmHazards.length;
    __mmHazardIndex++
  ) {
    const __mmHazard = __mmHazards[__mmHazardIndex],
      __mmDx = Number(__mmHazard.object.x) - __mmPrediction.futureX,
      __mmDy = Number(__mmHazard.object.y) - __mmPrediction.futureY,
      __mmAlong =
        __mmDx * Math.cos(__mmDirection) +
        __mmDy * Math.sin(__mmDirection),
      __mmRadius = __mmEnemyScale + __mmHazard.scale + 3;
    if (
      __mmAlong < 0 ||
      __mmAlong > 180 ||
      __mmSegmentDistanceSquared(
        __mmPrediction.futureX,
        __mmPrediction.futureY,
        __mmEndX,
        __mmEndY,
        Number(__mmHazard.object.x),
        Number(__mmHazard.object.y),
      ) >
        __mmRadius * __mmRadius ||
      __mmAlong >= __mmBestAlong
    )
      continue;
    ((__mmBestAlong = __mmAlong),
      (__mmBest = {
        hazard: __mmHazard,
        along: __mmAlong,
        bounce: !!(__mmHazard.spike && __mmAlong >= 50 && __mmAlong <= 150),
      }));
  }
  return __mmBest;
}
function __mmSmartScoreCandidate(
  __mmCandidate,
  __mmEnemies,
  __mmHazards,
  __mmNow,
  __mmEnemyPotentials,
) {
  const __mmIsTrap = !!__mmCandidate.data.trap,
    __mmIsSpike = !!(
      __mmCandidate.data.dmg ||
      /spike/i.test(String(__mmCandidate.data.name || ""))
    );
  for (let __mmIndex = 0; __mmIndex < __mmEnemies.length; __mmIndex++) {
    const __mmEnemy = __mmEnemies[__mmIndex],
      __mmPlacementPotential =
        __mmEnemyPotentials && __mmEnemyPotentials[String(__mmEnemy.sid)],
      __mmPrediction =
        (__mmPlacementPotential && __mmPlacementPotential.prediction) ||
        __mmSmartEnemyPrediction(__mmEnemy, __mmNow),
      __mmEnemyScale = Number(__mmEnemy.scale) || 35,
      __mmCurrentDistance = Math.hypot(
        __mmPrediction.x - __mmCandidate.x,
        __mmPrediction.y - __mmCandidate.y,
      ),
      __mmFutureDistance = Math.hypot(
        __mmPrediction.futureX - __mmCandidate.x,
        __mmPrediction.futureY - __mmCandidate.y,
      ),
      __mmRouteDistance = Math.sqrt(
        __mmSegmentDistanceSquared(
          __mmPrediction.x,
          __mmPrediction.y,
          __mmPrediction.futureX,
          __mmPrediction.futureY,
          __mmCandidate.x,
          __mmCandidate.y,
        ),
      ),
      __mmTouch = __mmEnemyScale + __mmCandidate.scale,
      __mmTrap = __mmPlacementPotential
        ? __mmPlacementPotential.trap
        : __mmAutoSpikeSpamTrapForEnemy(__mmEnemy),
      __mmEnemyDistance = Math.hypot(__mmEnemy.x - v.x, __mmEnemy.y - v.y);
    if (__mmEnemyDistance > 350) continue;
    if (__mmIsSpike && __mmSmartSpikeContactEnabled) {
      if (__mmCurrentDistance <= __mmTouch + 3) {
        ((__mmCandidate.points += 3),
          __mmCandidate.reasons.push("spike contact"));
      } else if (
        __mmSmartPreplaceEnabled &&
        Math.min(__mmFutureDistance, __mmRouteDistance) <= __mmTouch + 5
      ) {
        ((__mmCandidate.points += 3.5),
          (__mmCandidate.preplace = !0),
          (__mmCandidate.priority = !0),
          __mmCandidate.reasons.push("predicted spike contact"));
      }
    }
    if (__mmIsTrap && __mmSmartTrapContactEnabled) {
      if (__mmCurrentDistance <= 235 && !__mmTrap) {
        ((__mmCandidate.points += 1),
          __mmCandidate.reasons.push("trap pressure"));
      }
      if (__mmCurrentDistance <= 20.4) {
        ((__mmCandidate.points += 1),
          (__mmCandidate.priority = !0),
          __mmCandidate.reasons.push("placement denial"));
      }
      if (__mmCurrentDistance <= 50) {
        ((__mmCandidate.points += __mmTrap ? 5 : 3),
          __mmCandidate.reasons.push(__mmTrap ? "retrap" : "trap contact"));
      } else if (
        __mmSmartPreplaceEnabled &&
        Math.min(__mmFutureDistance, __mmRouteDistance) <= 52
      ) {
        ((__mmCandidate.points += 3.5),
          (__mmCandidate.preplace = !0),
          (__mmCandidate.priority = !0),
          __mmCandidate.reasons.push("predicted trap"));
      }
    }
    if (__mmSmartAngleDenialEnabled && __mmCurrentDistance <= 235) {
      let __mmInterceptsPlacement = !1;
      const __mmPossible =
        __mmPlacementPotential && __mmPlacementPotential.possible;
      if (Array.isArray(__mmPossible))
        for (
          let __mmPotentialIndex = 0;
          __mmPotentialIndex < __mmPossible.length;
          __mmPotentialIndex++
        ) {
          const __mmPotential = __mmPossible[__mmPotentialIndex];
          if (
            Math.hypot(
              __mmCandidate.x - __mmPotential.x,
              __mmCandidate.y - __mmPotential.y,
            ) <=
            __mmCandidate.scale + __mmPotential.scale
          ) {
            __mmInterceptsPlacement = !0;
            break;
          }
        }
      if (__mmInterceptsPlacement) {
        ((__mmCandidate.points += 1),
          (__mmCandidate.priority = !0),
          __mmCandidate.reasons.push("enemy-angle block"));
      } else if (
        __mmPlacementPotential &&
        __mmCurrentDistance <= __mmPlacementPotential.placeRange
      ) {
        ((__mmCandidate.points += 0.5),
          __mmCandidate.reasons.push("angle abuse"));
      }
    }
    if (__mmTrap && __mmIsSpike && __mmSmartTrapSurroundEnabled) {
      const __mmTrapDistance = Math.hypot(
          __mmCandidate.x - __mmTrap.x,
          __mmCandidate.y - __mmTrap.y,
        ),
        __mmAwayFromUs = Math.abs(
          Math.atan2(
            Math.sin(
              __mmCandidate.angle -
                Math.atan2(__mmEnemy.y - v.y, __mmEnemy.x - v.x),
            ),
            Math.cos(
              __mmCandidate.angle -
                Math.atan2(__mmEnemy.y - v.y, __mmEnemy.x - v.x),
            ),
          ),
        );
      if (__mmTrapDistance <= 50 + __mmCandidate.scale + 24) {
        ((__mmCandidate.points += 2),
          __mmCandidate.reasons.push("trapped surround"));
        __mmAwayFromUs >= 1.5 && (__mmCandidate.points += 2);
      }
    }
    if (
      __mmIsSpike &&
      __mmSmartKnockbackChainEnabled &&
      __mmCurrentDistance <= __mmTouch + 5
    ) {
      const __mmKnock = __mmSmartKnockIntoHazard(
        __mmCandidate,
        __mmPrediction,
        __mmEnemyScale,
        __mmHazards,
      );
      if (__mmKnock) {
        ((__mmCandidate.points += __mmKnock.hazard.trap
          ? 2.5
          : __mmKnock.bounce
            ? 5
            : 3),
          (__mmCandidate.priority = !0),
          (__mmCandidate.knockInto = __mmKnock),
          __mmCandidate.reasons.push(
            __mmKnock.hazard.trap
              ? "knock into trap"
              : __mmKnock.bounce
                ? "spike bounce chain"
                : "spike chain",
          ));
      }
    }
    if (__mmIsTrap && __mmSmartAutoPushWeightEnabled)
      for (let __mmHazardIndex = 0; __mmHazardIndex < __mmHazards.length; __mmHazardIndex++) {
        const __mmHazard = __mmHazards[__mmHazardIndex];
        if (
          __mmHazard.spike &&
          Math.hypot(
            __mmCandidate.x - __mmHazard.object.x,
            __mmCandidate.y - __mmHazard.object.y,
          ) <=
            __mmCandidate.scale + __mmHazard.scale + 24
        ) {
          ((__mmCandidate.points += 2),
            __mmCandidate.reasons.push("auto-push trap"));
          break;
        }
      }
  }
  if (__mmSmartReplacePoint) {
    const __mmReplaceDistance = Math.hypot(
      __mmCandidate.x - __mmSmartReplacePoint.x,
      __mmCandidate.y - __mmSmartReplacePoint.y,
    );
    if (__mmReplaceDistance <= __mmCandidate.scale + 55) {
      ((__mmCandidate.points += 6),
        (__mmCandidate.priority = !0),
        __mmCandidate.reasons.push("replace"));
      if (
        __mmSmartSpikeSyncPlaceEnabled &&
        __mmSmartReplacePoint.trap &&
        __mmIsSpike
      )
        ((__mmCandidate.points += 5),
          __mmCandidate.reasons.push("spike sync"));
    }
  }
  return __mmCandidate;
}
function __mmSmartPlacementCandidates(
  __mmItem,
  __mmEnemies,
  __mmHazards,
  __mmNow,
  __mmEnemyPotentials,
) {
  if (__mmItem == null) return [];
  const __mmResult = [],
    __mmSamples = Math.max(
      24,
      Math.min(
        360,
        Math.round(__mmSmartPlaceAccuracy * 2 * __mmSmartDepthScale()),
      ),
    ),
    __mmPreviewStride = Math.max(
      1,
      Math.ceil(__mmSamples / (__mmFpsBoostEnabled ? 15 : 27)),
    ),
    __mmBase = __mmEnemies.length
      ? Math.atan2(__mmEnemies[0].y - v.y, __mmEnemies[0].x - v.x)
      : 0;
  for (let __mmIndex = 0; __mmIndex < __mmSamples; __mmIndex++) {
    const __mmAngle = __mmBase + (__mmIndex * Math.PI * 2) / __mmSamples,
      __mmCandidate = __mmSmartCandidateForAngle(
        __mmItem,
        __mmAngle,
        __mmPlacementVisualsEnabled,
      );
    if (
      __mmCandidate &&
      __mmPlacementVisualsEnabled &&
      __mmIndex % __mmPreviewStride === 0
    )
      __mmSmartPreviewSamples.push(__mmCandidate);
    __mmCandidate && __mmCandidate.valid &&
      __mmResult.push(
        __mmSmartScoreCandidate(
          __mmCandidate,
          __mmEnemies,
          __mmHazards,
          __mmNow,
          __mmEnemyPotentials,
        ),
      );
  }
  return __mmResult;
}
function __mmSmartApplyCorePressureFallback(
  __mmCandidates,
  __mmEnemies,
  __mmNow,
) {
  if (
    !__mmCandidates.length ||
    !__mmEnemies.length ||
    __mmCandidates.some(function (__mmCandidate) {
      return __mmCandidate && __mmCandidate.points > 0;
    })
  )
    return !1;
  const __mmEnemy = __mmEnemies[0],
    __mmEnemyDistance = Math.hypot(__mmEnemy.x - v.x, __mmEnemy.y - v.y);
  if (!Number.isFinite(__mmEnemyDistance) || __mmEnemyDistance > 335)
    return !1;
  const __mmPrediction = __mmSmartEnemyPrediction(__mmEnemy, __mmNow),
    __mmEnemyScale = Number(__mmEnemy.scale) || 35;
  let __mmBest = null,
    __mmBestMetric = Infinity;
  for (
    let __mmCandidateIndex = 0;
    __mmCandidateIndex < __mmCandidates.length;
    __mmCandidateIndex++
  ) {
    const __mmCandidate = __mmCandidates[__mmCandidateIndex];
    if (!__mmCandidate || !__mmCandidate.valid) continue;
    const __mmIsTrap = !!__mmCandidate.data.trap,
      __mmIsSpike = !!(
        __mmCandidate.data.dmg ||
        /spike/i.test(String(__mmCandidate.data.name || ""))
      ),
      __mmCurrentDistance = Math.hypot(
        __mmEnemy.x - __mmCandidate.x,
        __mmEnemy.y - __mmCandidate.y,
      ),
      __mmFutureDistance = Math.hypot(
        __mmPrediction.futureX - __mmCandidate.x,
        __mmPrediction.futureY - __mmCandidate.y,
      ),
      __mmRouteDistance = Math.sqrt(
        __mmSegmentDistanceSquared(
          __mmEnemy.x,
          __mmEnemy.y,
          __mmPrediction.futureX,
          __mmPrediction.futureY,
          __mmCandidate.x,
          __mmCandidate.y,
        ),
      ),
      __mmMetric = Math.min(
        __mmCurrentDistance,
        __mmFutureDistance,
        __mmRouteDistance,
      ),
      __mmUseful = __mmIsTrap
        ? __mmMetric <= 255
        : __mmIsSpike &&
          __mmEnemyDistance <= 215 &&
          __mmMetric <= __mmEnemyScale + __mmCandidate.scale + 28;
    if (!__mmUseful || __mmMetric >= __mmBestMetric) continue;
    ((__mmBest = __mmCandidate), (__mmBestMetric = __mmMetric));
  }
  if (!__mmBest) return !1;
  ((__mmBest.points = __mmBest.data.trap ? 1.15 : 1.35),
    (__mmBest.priority = !0),
    // The fallback is already the closest legal pressure slot. Send it on the
    // current placement phase instead of turning a weak prediction into an
    // extra user-configured pre-place delay.
    (__mmBest.preplace = !1),
    __mmBest.reasons.push("core pressure fallback"));
  return !0;
}
function __mmAutomaticQuadPlacementEnabled() {
  return !!(__mmSmartQuadTrapsEnabled || __mmSmartQuadSpikesEnabled);
}
function __mmAutomaticQuadCandidateEnabled(__mmCandidate) {
  const __mmData = __mmCandidate && __mmCandidate.data;
  if (!__mmData) return !1;
  if (__mmData.trap) return __mmSmartQuadTrapsEnabled;
  return !!(
    __mmSmartQuadSpikesEnabled &&
    (__mmData.dmg || /spike/i.test(String(__mmData.name || "")))
  );
}
function __mmSmartQuadTrapCandidates(
  __mmCandidates,
  __mmEnemies,
  __mmNow,
) {
  if (
    !__mmSmartQuadTrapsEnabled ||
    !__mmCandidates.length ||
    !__mmEnemies.length
  )
    return [];
  const __mmEnemy = __mmEnemies[0],
    __mmEnemyDistance = Math.hypot(
      Number(__mmEnemy.x) - Number(v.x),
      Number(__mmEnemy.y) - Number(v.y),
    );
  if (
    !Number.isFinite(__mmEnemyDistance) ||
    __mmEnemyDistance > 450
  )
    return [];
  const __mmPrediction = __mmSmartEnemyPrediction(__mmEnemy, __mmNow);
  const __mmTrapCandidates = [];
  for (
    let __mmCandidateIndex = 0;
    __mmCandidateIndex < __mmCandidates.length;
    __mmCandidateIndex++
  ) {
    const __mmCandidate = __mmCandidates[__mmCandidateIndex];
    if (
      !__mmCandidate ||
      !__mmCandidate.valid ||
      !(__mmCandidate.data && __mmCandidate.data.trap)
    )
      continue;
    const __mmCurrentDistance = Math.hypot(
        Number(__mmEnemy.x) - __mmCandidate.x,
        Number(__mmEnemy.y) - __mmCandidate.y,
      ),
      __mmFutureDistance = Math.hypot(
        __mmPrediction.futureX - __mmCandidate.x,
        __mmPrediction.futureY - __mmCandidate.y,
      ),
      __mmRouteDistance = Math.sqrt(
        __mmSegmentDistanceSquared(
          __mmPrediction.x,
          __mmPrediction.y,
          __mmPrediction.futureX,
          __mmPrediction.futureY,
          __mmCandidate.x,
          __mmCandidate.y,
        ),
      ),
      __mmPressureDistance = Math.min(
        __mmCurrentDistance,
        __mmFutureDistance,
        __mmRouteDistance,
      );
    // Full-place keeps every legal trap in the ranked pool. Direct contact,
    // retrap, pre-place, and angle denial retain their stronger score; empty
    // legal slots receive only a small fill score so they can complete the
    // non-overlapping four-slot pattern after the important angles.
    if (__mmCandidate.points <= 0)
      __mmCandidate.points =
        0.62 + Math.max(0, 450 - __mmPressureDistance) / 2000;
    __mmCandidate.reasons.includes("quad trap fill") ||
      __mmCandidate.reasons.push("quad trap fill");
    __mmTrapCandidates.push(__mmCandidate);
  }
  return __mmTrapCandidates;
}
function __mmSmartQuadSpikeCandidates(
  __mmCandidates,
  __mmEnemies,
  __mmNow,
) {
  if (
    !__mmSmartQuadSpikesEnabled ||
    !__mmCandidates.length ||
    !__mmEnemies.length
  )
    return [];
  const __mmEnemy = __mmEnemies[0],
    __mmEnemyDistance = Math.hypot(
      Number(__mmEnemy.x) - Number(v.x),
      Number(__mmEnemy.y) - Number(v.y),
    );
  if (!Number.isFinite(__mmEnemyDistance) || __mmEnemyDistance > 450) return [];
  const __mmPrediction = __mmSmartEnemyPrediction(__mmEnemy, __mmNow),
    __mmTrap = __mmAutoSpikeSpamTrapForEnemy(__mmEnemy),
    __mmToward = Math.atan2(__mmEnemy.y - v.y, __mmEnemy.x - v.x),
    __mmMovementToward =
      typeof Kt === "number" &&
      Math.abs(Math.atan2(Math.sin(Kt - __mmToward), Math.cos(Kt - __mmToward))) <=
        Math.PI / 3,
    // Require either contact/retrap pressure or an aggressive close-range
    // approach so automatic quad spikes do not waste four structures on passersby.
    __mmAggressive = !!(
      __mmTrap ||
      __mmMovementToward ||
      __mmPrimaryHeld ||
      __mmSecondaryHeld ||
      __mmEnemyDistance <= 175
    ),
    __mmSpikeCandidates = [];
  if (!__mmAggressive) return [];
  for (
    let __mmCandidateIndex = 0;
    __mmCandidateIndex < __mmCandidates.length;
    __mmCandidateIndex++
  ) {
    const __mmCandidate = __mmCandidates[__mmCandidateIndex];
    if (
      !__mmCandidate ||
      !__mmCandidate.valid ||
      !__mmCandidate.data ||
      !(
        __mmCandidate.data.dmg ||
        /spike/i.test(String(__mmCandidate.data.name || ""))
      )
    )
      continue;
    const __mmTouch =
        (Number(__mmEnemy.scale) || 35) + Number(__mmCandidate.scale || 0),
      __mmCurrentDistance = Math.hypot(
        Number(__mmEnemy.x) - __mmCandidate.x,
        Number(__mmEnemy.y) - __mmCandidate.y,
      ),
      __mmFutureDistance = Math.hypot(
        __mmPrediction.futureX - __mmCandidate.x,
        __mmPrediction.futureY - __mmCandidate.y,
      ),
      __mmRouteDistance = Math.sqrt(
        __mmSegmentDistanceSquared(
          __mmPrediction.x,
          __mmPrediction.y,
          __mmPrediction.futureX,
          __mmPrediction.futureY,
          __mmCandidate.x,
          __mmCandidate.y,
        ),
      ),
      __mmPressureDistance = Math.min(
        __mmCurrentDistance,
        __mmFutureDistance,
        __mmRouteDistance,
      );
    if (__mmCandidate.points <= 0 && __mmPressureDistance > __mmTouch + 55)
      continue;
    if (__mmCandidate.points <= 0)
      __mmCandidate.points =
        0.72 + Math.max(0, __mmTouch + 55 - __mmPressureDistance) / 120;
    __mmTrap && (__mmCandidate.points += 1.5);
    __mmCandidate.reasons.includes("quad spike fill") ||
      __mmCandidate.reasons.push("quad spike fill");
    __mmSpikeCandidates.push(__mmCandidate);
  }
  return __mmSpikeCandidates;
}
function __mmManualQuadPlacement(__mmKind) {
  const __mmIsTrap = __mmKind === "trap";
  if (
    !v ||
    !v.alive ||
    (__mmIsTrap ? !__mmSmartQuadTrapsEnabled : !__mmSmartQuadSpikesEnabled) ||
    !__mmActionCanPreempt("smartAutoPlace")
  )
    return !1;
  const __mmItem = __mmIsTrap ? __mmSmartPitTrapItem() : __mmSpikeItem();
  if (
    __mmItem == null ||
    !__mmCanUseBuildItem(__mmItem) ||
    __mmMaxBuildCount(__mmItem) < 1
  )
    return !1;
  const __mmTarget = __mmNearestEnemy(),
    __mmNow = Date.now(),
    __mmEnemies = __mmTarget ? [__mmTarget] : [],
    __mmHazards = __mmSmartFriendlyHazards(),
    __mmPotentials = __mmTarget
      ? __mmSmartEnemyPlacementPotentials(__mmEnemies, __mmItem, __mmNow)
      : Object.create(null),
    __mmPreferred = __mmTarget
      ? Math.atan2(__mmTarget.y - v.y, __mmTarget.x - v.x)
      : __mmRawMouseAimDirection(),
    __mmCandidates = __mmSmartPlacementCandidates(
      __mmItem,
      __mmEnemies,
      __mmHazards,
      __mmNow,
      __mmPotentials,
    );
  for (let __mmIndex = 0; __mmIndex < __mmCandidates.length; __mmIndex++) {
    const __mmCandidate = __mmCandidates[__mmIndex],
      __mmAngleDistance = Math.abs(
        Math.atan2(
          Math.sin(__mmCandidate.angle - __mmPreferred),
          Math.cos(__mmCandidate.angle - __mmPreferred),
        ),
      );
    if (__mmCandidate.points <= 0)
      __mmCandidate.points = 0.55 + (Math.PI - __mmAngleDistance) / (Math.PI * 20);
    __mmCandidate.reasons.push(
      __mmIsTrap ? "manual quad trap" : "manual quad spike",
    );
  }
  const __mmPlaced = __mmSmartPlaceBatch(
    __mmCandidates,
    __mmIsTrap ? "manual quad traps" : "manual quad spikes",
    4,
  );
  __mmPlaced &&
    __mmShowInstaTypePopup(__mmIsTrap ? "Quad Traps" : "Quad Spikes");
  return __mmPlaced > 0;
}
function __mmBoostSpikePlacementCandidates(__mmTarget, __mmSpike, __mmNow) {
  const __mmEnemies = [__mmTarget],
    __mmCandidates = __mmSmartPlacementCandidates(
      __mmSpike,
      __mmEnemies,
      __mmSmartFriendlyHazards(),
      __mmNow,
      __mmSmartEnemyPlacementPotentials(__mmEnemies, __mmSpike, __mmNow),
    ),
    __mmPrediction = __mmSmartEnemyPrediction(__mmTarget, __mmNow),
    __mmBase = Math.atan2(__mmTarget.y - v.y, __mmTarget.x - v.x),
    __mmResult = [];
  for (let __mmIndex = 0; __mmIndex < __mmCandidates.length; __mmIndex++) {
    const __mmCandidate = __mmCandidates[__mmIndex],
      __mmTouch =
        (Number(__mmTarget.scale) || 35) + Number(__mmCandidate.scale || 0),
      __mmPressure = Math.min(
        Math.hypot(__mmTarget.x - __mmCandidate.x, __mmTarget.y - __mmCandidate.y),
        Math.hypot(
          __mmPrediction.futureX - __mmCandidate.x,
          __mmPrediction.futureY - __mmCandidate.y,
        ),
      ),
      __mmRelative = Math.abs(
        Math.atan2(
          Math.sin(__mmCandidate.angle - __mmBase),
          Math.cos(__mmCandidate.angle - __mmBase),
        ),
      ),
      __mmSideDistance = Math.abs(__mmRelative - Math.PI / 2),
      __mmContact = __mmPressure <= __mmTouch + 16,
      __mmSideLane = __mmSideDistance <= 0.24;
    if (!__mmContact && !__mmSideLane && !__mmCandidate.knockInto) continue;
    (__mmCandidate.points +=
      (__mmContact ? 6 : 0) +
      (__mmSideLane ? 3 : 0) +
      (__mmCandidate.knockInto ? 4 : 0),
      __mmCandidate.reasons.push(
        __mmContact ? "boost-spike contact" : "boost-spike side lane",
      ),
      __mmResult.push(__mmCandidate));
  }
  return __mmResult;
}
function __mmBoostSpikeScanMs() {
  return Math.max(8, Math.min(12, __mmFastCheckMs()));
}
function __mmBoostSpikeBurstCooldownMs() {
  // Scan continuously, but keep successful multi-place bursts bounded. At the
  // normal 9 Hz server rate this permits the newly opened lane to be used in
  // about half a tick instead of waiting for the next full 111 ms interval.
  return Math.max(32, Math.min(55, __mmServerTickMs() * 0.48));
}
function __mmBoostSpikeBurst() {
  const __mmNow = Date.now();
  if (
    !__mmBoostSpikeEnabled ||
    !v ||
    !v.alive ||
    __mmInsta.isActive() ||
    __mmBoostInsta.isActive() ||
    __mmIsTrapped() ||
    __mmHoldingMcGrabby() ||
    __mmEmergencyGetawayActive() ||
    __mmNow - __mmBoostSpikeLastAt < __mmBoostSpikeBurstCooldownMs() ||
    !__mmActionCanPreempt("boostSpike")
  )
    return !1;
  const __mmTarget = __mmNearestEnemy(),
    __mmSpike = __mmSpikeItem(),
    __mmPad = __mmBoostPadItem();
  if (
    !__mmTarget ||
    __mmSpike == null ||
    __mmPad == null ||
    !__mmCanUseBuildItem(__mmSpike) ||
    !__mmCanUseBuildItem(__mmPad) ||
    __mmMaxBuildCount(__mmSpike) < 1 ||
    __mmMaxBuildCount(__mmPad) < 1 ||
    Math.hypot(__mmTarget.x - v.x, __mmTarget.y - v.y) > 420 ||
    !__mmActionClaim("boostSpike", "predictive boost-spike")
  )
    return !1;
  const __mmDirection = Math.atan2(__mmTarget.y - v.y, __mmTarget.x - v.x),
    __mmTool = __mmSelectedTool(),
    __mmDistance = Math.hypot(__mmTarget.x - v.x, __mmTarget.y - v.y),
    __mmSpikeLimit = Math.min(
      __mmDistance <= 175 ? 4 : 2,
      __mmMaxBuildCount(__mmSpike),
    ),
    __mmCandidates = __mmBoostSpikePlacementCandidates(
      __mmTarget,
      __mmSpike,
      __mmNow,
    ),
    __mmPadCandidate = __mmSmartNearestLegalCandidate(
      __mmPad,
      __mmDirection,
      0.48,
      0.035,
    ),
    __mmCompatibleCandidates = __mmPadCandidate
      ? __mmCandidates.filter(function (__mmCandidate) {
          return (
            Math.hypot(
              __mmCandidate.x - __mmPadCandidate.x,
              __mmCandidate.y - __mmPadCandidate.y,
            ) >=
            __mmCandidate.scale + __mmPadCandidate.scale
          );
        })
      : [],
    __mmSelected = __mmSmartBestCombination(
      __mmCompatibleCandidates,
      __mmSpikeLimit,
    );
  if (!__mmSelected.length || !__mmPadCandidate) {
    if (Number.isFinite(__mmBoostSpikeMoveAngle)) {
      const __mmTurn = Math.abs(
        Math.atan2(
          Math.sin(__mmDirection - __mmBoostSpikeMoveAngle),
          Math.cos(__mmDirection - __mmBoostSpikeMoveAngle),
        ),
      );
      if (__mmTurn > 0.025) {
        ((__mmBoostSpikeMoveAngle = __mmDirection),
          (Kt = __mmDirection),
          O.send("9", __mmDirection),
          O.send("D", __mmDirection));
      }
    }
    (__mmActionRelease("boostSpike", "no legal boost-spike pattern"),
      __mmSmartSetPlacementPreview(
        __mmCandidates.concat(__mmPadCandidate ? [__mmPadCandidate] : []),
        [],
        "no legal boost-spike pattern",
      ));
    return !1;
  }
  let __mmPlaced = 0;
  (O.send("D", __mmDirection),
    (__mmBoostSpikeMoveAngle = __mmDirection),
    (Kt = __mmDirection),
    O.send("9", __mmDirection));
  for (let __mmIndex = 0; __mmIndex < __mmSelected.length; __mmIndex++)
    __mmSmartPlaceNow(__mmSelected[__mmIndex], __mmTool) && __mmPlaced++;
  if (__mmPadCandidate && __mmSmartPlaceNow(__mmPadCandidate, __mmTool))
    __mmPlaced++;
  (__mmPlaced && (__mmBoostSpikeLastAt = __mmNow),
    __mmSmartSetPlacementPreview(
      __mmCandidates.concat(__mmPadCandidate ? [__mmPadCandidate] : []),
      __mmSelected.concat(__mmPadCandidate ? [__mmPadCandidate] : []),
      "predictive boost-spike",
    ),
    __mmPlaced && __mmShowInstaTypePopup("Boost + Spike"),
    __mmActionRelease("boostSpike", "boost-spike packets sent"),
    __mmScheduleMouseAimReturn());
  return __mmPlaced > 0;
}
function __mmStartBoostSpike() {
  if (!__mmBoostSpikeEnabled || __mmBoostSpikeTimer) return;
  (__mmBoostSpikeBurst(),
    (__mmBoostSpikeTimer = setInterval(
      __mmBoostSpikeBurst,
      __mmBoostSpikeScanMs(),
    )));
}
function __mmStopBoostSpike() {
  (__mmBoostSpikeTimer && clearInterval(__mmBoostSpikeTimer),
    (__mmBoostSpikeTimer = 0),
    (__mmBoostSpikeMoveAngle = null));
  if (__mmActionOwner === "boostSpike")
    __mmActionRelease("boostSpike", "boost-spike released");
  if (v && v.alive) {
    Kt = null;
    typeof Tt === "function" && Tt();
    __mmScheduleMouseAimReturn();
  }
}
function __mmSmartPlaceNow(
  __mmCandidate,
  __mmOriginalTool,
  __mmReservedSlot,
) {
  if (
    !__mmCandidate ||
    !__mmCanUseBuildItem(__mmCandidate.item) ||
    (!__mmReservedSlot && __mmMaxBuildCount(__mmCandidate.item) < 1)
  )
    return !1;
  const __mmFresh = __mmSmartCandidateForAngle(
    __mmCandidate.item,
    __mmCandidate.angle,
  );
  if (!__mmFresh) return !1;
  try {
    if (
      !__mmSendAutomaticPlacement(
        __mmCandidate.item,
        __mmCandidate.angle,
        __mmOriginalTool,
        __mmReservedSlot,
      )
    )
      return !1;
    (
      __mmAutoSpikeSpamReservations.push({
        item: __mmCandidate.item,
        x: __mmFresh.x,
        y: __mmFresh.y,
        scale: __mmFresh.scale,
        expiresAt: Date.now() + 650,
      }),
      (__mmSmartPlacementStats.sent += 1));
    return !0;
  } catch (__mmSmartPlaceError) {
    __mmSmartPlacementStats.failed += 1;
    return !1;
  }
}
// A placement phase is one packet burst, not a sequence of unrelated clicks.
// Select/place each legal entry, then restore the borrowed tool only once after
// the final entry. This keeps the later angles in an automatic quad from being
// interrupted by weapon restore, held-click resume, or another pipeline owner.
function __mmSmartPlaceBurst(__mmCandidates, __mmOriginalTool) {
  if (!Array.isArray(__mmCandidates) || !__mmCandidates.length) return 0;
  const __mmRestore = __mmOriginalTool || __mmSelectedTool(),
    __mmPlaced = [];
  try {
    for (let __mmIndex = 0; __mmIndex < __mmCandidates.length; __mmIndex++) {
      const __mmCandidate = __mmCandidates[__mmIndex];
      if (
        !__mmCandidate ||
        !__mmCanUseBuildItem(__mmCandidate.item) ||
        __mmMaxBuildCount(__mmCandidate.item) < 1
      )
        continue;
      const __mmFresh = __mmSmartCandidateForAngle(
        __mmCandidate.item,
        __mmCandidate.angle,
      );
      if (!__mmFresh) continue;
      (je(__mmCandidate.item), O.send("F", 1, __mmCandidate.angle));
      (__mmAutoSpikeSpamReservations.push({
        item: __mmCandidate.item,
        x: __mmFresh.x,
        y: __mmFresh.y,
        scale: __mmFresh.scale,
        expiresAt: Date.now() + 650,
      }),
        __mmPlaced.push(__mmFresh),
        (__mmSmartPlacementStats.sent += 1));
    }
  } catch (__mmSmartBurstError) {
    __mmSmartPlacementStats.failed += 1;
  } finally {
    try {
      __mmRestore && __mmRestore.weapon
        ? __mmRestoreTool(__mmRestore)
        : (O.send(
            "F",
            0,
            __mmPlaced.length
              ? __mmPlaced[__mmPlaced.length - 1].angle
              : Ci(),
          ),
          __mmRestore && __mmRestoreTool(__mmRestore));
      (__mmResumeHeldAttack(), __mmScheduleMouseAimReturn());
    } catch (__mmSmartBurstRestoreError) {}
  }
  return __mmPlaced.length;
}
function __mmSmartReserveCandidateCost(
  __mmCandidate,
  __mmResourceUse,
  __mmGroupUse,
) {
  const __mmData = __mmCandidate && __mmCandidate.data;
  if (
    !v ||
    !__mmData ||
    !__mmData.req ||
    !Number.isFinite(Number(__mmData.req.length))
  )
    return !1;
  for (
    let __mmReqIndex = 0;
    __mmReqIndex < __mmData.req.length;
    __mmReqIndex += 2
  ) {
    const __mmResource = String(__mmData.req[__mmReqIndex]),
      __mmCost = Number(__mmData.req[__mmReqIndex + 1]) || 0,
      __mmUsed = Number(__mmResourceUse[__mmResource]) || 0;
    if ((Number(v[__mmResource]) || 0) - __mmUsed < __mmCost) return !1;
  }
  const __mmGroup = __mmData.group,
    __mmGroupId = __mmGroup && __mmGroup.id;
  if (__mmGroupId != null) {
    const __mmLimit = __mmBuildGroupLimit(__mmData),
      __mmPlaced = Number(v.itemCounts && v.itemCounts[__mmGroupId]) || 0,
      __mmReserved = Number(__mmGroupUse[String(__mmGroupId)]) || 0;
    if (__mmLimit && __mmPlaced + __mmReserved >= __mmLimit) return !1;
  }
  for (
    let __mmReqIndex = 0;
    __mmReqIndex < __mmData.req.length;
    __mmReqIndex += 2
  ) {
    const __mmResource = String(__mmData.req[__mmReqIndex]),
      __mmCost = Number(__mmData.req[__mmReqIndex + 1]) || 0;
    __mmResourceUse[__mmResource] =
      (Number(__mmResourceUse[__mmResource]) || 0) + __mmCost;
  }
  __mmGroupId != null &&
    (__mmGroupUse[String(__mmGroupId)] =
      (Number(__mmGroupUse[String(__mmGroupId)]) || 0) + 1);
  return !0;
}
function __mmSmartBestCombination(__mmCandidates, __mmLimit) {
  const __mmPool = __mmCandidates
    .filter(function (__mmCandidate) {
      return __mmCandidate && __mmCandidate.points > 0;
    })
    .slice()
    .sort(function (__mmLeft, __mmRight) {
      const __mmPointDifference = __mmRight.points - __mmLeft.points;
      if (__mmPointDifference) return __mmPointDifference;
      if (!!__mmRight.priority !== !!__mmLeft.priority)
        return Number(!!__mmRight.priority) - Number(!!__mmLeft.priority);
      return Number(!!(__mmRight.data && __mmRight.data.trap)) -
        Number(!!(__mmLeft.data && __mmLeft.data.trap));
    }),
    __mmSelected = [],
    __mmResources = Object.create(null),
    __mmGroups = Object.create(null),
    __mmMax = Math.max(1, Math.min(4, Math.round(Number(__mmLimit) || 1)));
  // Full-place scans the complete ranked list and greedily retains the
  // first four non-overlapping builds. Kitty's old 18/24-candidate truncation
  // kept only a tight high-score cluster, so every later candidate overlapped
  // the first and the intended quad trap silently collapsed to one placement.
  for (let __mmIndex = 0; __mmIndex < __mmPool.length; __mmIndex++) {
    const __mmCandidate = __mmPool[__mmIndex];
    if (
      __mmSelected.some(function (__mmPlaced) {
        return (
          Math.hypot(
            __mmPlaced.x - __mmCandidate.x,
            __mmPlaced.y - __mmCandidate.y,
          ) <
          __mmPlaced.scale + __mmCandidate.scale
        );
      })
    )
      continue;
    const __mmNextResources = { ...__mmResources },
      __mmNextGroups = { ...__mmGroups };
    if (
      !__mmSmartReserveCandidateCost(
        __mmCandidate,
        __mmNextResources,
        __mmNextGroups,
      )
    )
      continue;
    for (const __mmResource in __mmNextResources)
      __mmResources[__mmResource] = __mmNextResources[__mmResource];
    for (const __mmGroup in __mmNextGroups)
      __mmGroups[__mmGroup] = __mmNextGroups[__mmGroup];
    __mmSelected.push(__mmCandidate);
    if (__mmSelected.length >= __mmMax) break;
  }
  return __mmSelected;
}
function __mmSmartPlaceBatch(__mmCandidates, __mmReason, __mmForcedLimit) {
  if (!__mmCandidates.length) {
    __mmSmartSetPlacementPreview([], [], __mmReason || "no legal slots");
    __mmSmartSetStatus("blocked", __mmReason || "no legal slots", {
      legal: 0,
      scored: 0,
    });
    return 0;
  }
  if (!__mmActionClaim("smartAutoPlace", __mmReason)) {
    __mmSmartSetStatus(
      "deferred",
      "action owned by " + __mmActionOwner,
      {
        legal: __mmCandidates.length,
        scored: __mmCandidates.filter(function (__mmCandidate) {
          return __mmCandidate.points > 0;
        }).length,
      },
    );
    return 0;
  }
  const __mmTool = __mmSelectedTool(),
    __mmLimit = Number.isFinite(Number(__mmForcedLimit))
      ? Math.max(1, Math.min(4, Math.round(Number(__mmForcedLimit))))
      : __mmSmartMultiPlaceEnabled
        ? __mmSmartMaxPlacements
        : 1;
  __mmCandidates.sort(function (__mmLeft, __mmRight) {
    if (__mmRight.points !== __mmLeft.points)
      return __mmRight.points - __mmLeft.points;
    const __mmLeftTrap = !!__mmLeft.data.trap,
      __mmRightTrap = !!__mmRight.data.trap;
    return Number(__mmRightTrap) - Number(__mmLeftTrap);
  });
  const __mmSelected = __mmSmartBestCombination(__mmCandidates, __mmLimit);
  __mmSmartSetPlacementPreview(__mmCandidates, __mmSelected, __mmReason);
  if (!__mmSelected.length) {
    (__mmActionRelease("smartAutoPlace", "no affordable scored slots"),
      __mmSmartSetStatus("blocked", "no affordable scored slots", {
        legal: __mmCandidates.length,
        scored: __mmCandidates.filter(function (__mmCandidate) {
          return __mmCandidate.points > 0;
        }).length,
      }));
    return 0;
  }
  let __mmPlaced = 0;
  const __mmImmediate = [];
  for (let __mmIndex = 0; __mmIndex < __mmSelected.length; __mmIndex++) {
    const __mmCandidate = __mmSelected[__mmIndex],
      __mmPing = Number(window.pingTime),
      __mmDelay = __mmCandidate.preplace
        ? Math.max(
            0,
            __mmSmartPlaceDelay -
              (Number.isFinite(__mmPing) ? Math.max(0, __mmPing) : 0),
          )
        : 0;
    if (__mmDelay > 0) {
      const __mmPreplaceKey =
        String(__mmCandidate.item) + ":" +
        Math.round(__mmCandidate.x / 3) + ":" +
        Math.round(__mmCandidate.y / 3);
      if (__mmSmartPreplaceKeys.has(__mmPreplaceKey)) continue;
      if (__mmSmartPreplaceTimers.size < 2) {
        const __mmScheduledReservation = {
          item: __mmCandidate.item,
          x: __mmCandidate.x,
          y: __mmCandidate.y,
          scale: __mmCandidate.scale,
          expiresAt: Date.now() + __mmDelay + 650,
          preplaceKey: __mmPreplaceKey,
        };
        __mmAutoSpikeSpamReservations.push(__mmScheduledReservation);
        const __mmTimer = setTimeout(function () {
          (__mmSmartPreplaceTimers.delete(__mmTimer),
            __mmSmartPreplaceKeys.delete(__mmPreplaceKey));
          const __mmReservationIndex =
            __mmAutoSpikeSpamReservations.indexOf(__mmScheduledReservation);
          __mmReservationIndex >= 0 &&
            __mmAutoSpikeSpamReservations.splice(__mmReservationIndex, 1);
          if (
            (!__mmSmartAutoPlaceEnabled &&
              !__mmAutomaticQuadCandidateEnabled(__mmCandidate) &&
              !__mmSmartAutoReplaceEnabled &&
              !__mmSmartSpikeSyncPlaceEnabled) ||
            !__mmActionCanPreempt("smartAutoPlace") ||
            !__mmActionClaim("smartAutoPlace", "predictive pre-place")
          )
            return;
          const __mmCurrentTool = __mmSelectedTool(),
            __mmDidPlace = __mmSmartPlaceNow(
              __mmCandidate,
              __mmCurrentTool,
              !0,
            );
          (__mmDidPlace
            ? __mmSmartSetStatus("sent", "predictive pre-place", {
                legal: 1,
                scored: 1,
              })
            : __mmSmartSetStatus("blocked", "pre-place became illegal", {
                legal: 0,
                scored: 0,
              }),
            __mmActionRelease("smartAutoPlace", "predictive pre-place complete"));
        }, __mmDelay);
        (__mmSmartPreplaceTimers.add(__mmTimer),
          __mmSmartPreplaceKeys.add(__mmPreplaceKey));
        __mmPlaced++;
        continue;
      }
      // Limit delayed priority placements without throwing away the remaining
      // members of a four-slot batch.
      // Once both predictive timers are occupied, send later legal slots now.
      __mmImmediate.push(__mmCandidate);
    } else if (!__mmDelay)
      __mmImmediate.push(__mmCandidate);
  }
  __mmImmediate.length &&
    (__mmPlaced += __mmSmartPlaceBurst(__mmImmediate, __mmTool));
  (__mmActionRelease("smartAutoPlace", __mmReason + " complete"),
    __mmPlaced > 0
      ? ((__mmSmartPlacementLastAt = Date.now()),
        __mmSmartSetStatus("sent", __mmReason, {
          legal: __mmCandidates.length,
          scored: __mmCandidates.filter(function (__mmCandidate) {
            return __mmCandidate.points > 0;
          }).length,
        }))
      : __mmSmartSetStatus("blocked", "selected slots became illegal", {
          legal: __mmCandidates.length,
          scored: __mmSelected.length,
        }));
  return __mmPlaced;
}
function __mmSmartObserveRemovedObjects(__mmNow) {
  if (!v || !v.alive) return;
  if (!__mmSmartAutoReplaceEnabled && !__mmSmartSpikeSyncPlaceEnabled) {
    __mmSmartKnownObjects.clear();
    return;
  }
  if (__mmNow - __mmSmartObjectScanAt < 25) return;
  __mmSmartObjectScanAt = __mmNow;
  const __mmSeen = new Set(),
    __mmObjects = __mmActiveObjectSnapshot(!0).all;
  for (let __mmIndex = 0; __mmIndex < __mmObjects.length; __mmIndex++) {
    const __mmObject = __mmObjects[__mmIndex];
    if (!__mmObject || !__mmObject.active || __mmObject.sid == null) continue;
    const __mmKey = String(__mmObject.sid),
      __mmData = b && b.list && b.list[__mmObject.id];
    __mmSeen.add(__mmKey);
    if (Math.hypot(__mmObject.x - v.x, __mmObject.y - v.y) <= 450)
      __mmSmartKnownObjects.set(__mmKey, {
        x: Number(__mmObject.x),
        y: Number(__mmObject.y),
        scale: Number(__mmObject.scale) || 45,
        trap: !!(__mmData && __mmData.trap),
        seenAt: __mmNow,
      });
  }
  for (const [__mmKey, __mmKnown] of __mmSmartKnownObjects) {
    if (__mmSeen.has(__mmKey)) continue;
    __mmSmartKnownObjects.delete(__mmKey);
    if (
      (!__mmSmartAutoReplaceEnabled &&
        !(__mmSmartSpikeSyncPlaceEnabled && __mmKnown.trap)) ||
      __mmNow - __mmKnown.seenAt > 350 ||
      Math.hypot(__mmKnown.x - v.x, __mmKnown.y - v.y) > 190
    )
      continue;
    const __mmEnemy = __mmNearestEnemy();
    if (!__mmEnemy || Math.hypot(__mmEnemy.x - v.x, __mmEnemy.y - v.y) > 235)
      continue;
    ((__mmSmartReplacePoint = __mmKnown),
      (__mmSmartReplaceUntil = __mmNow + Math.max(250, __mmServerTickMs() * 2)));
  }
}
function __mmSmartUpdateMovingMills(__mmNow) {
  if (!__mmSmartMovingMillsEnabled || !v || !v.alive) return;
  const __mmPlayerX = v.x2 != null && Number.isFinite(Number(v.x2))
      ? Number(v.x2)
      : Number(v.x),
    __mmPlayerY = v.y2 != null && Number.isFinite(Number(v.y2))
      ? Number(v.y2)
      : Number(v.y);
  if (!Number.isFinite(__mmPlayerX) || !Number.isFinite(__mmPlayerY)) return;
  const __mmMill = __mmSmartMillItem();
  if (__mmMill == null) {
    // A missing resource or a temporarily full client-side counter must not
    // switch Automill off. Keep it armed so it resumes on the first usable
    // tick (including sandbox's 299-mill group) without another key press.
    __mmSmartSetStatus("waiting", "auto mills waiting for a buildable mill", {
      legal: 0,
      scored: 0,
      itemSummary: "mill",
    });
    return;
  }
  const __mmData = b && b.list && b.list[__mmMill],
    __mmMillScale = Number(__mmData && __mmData.scale) || 45,
    __mmPlaceDistance =
      (Number(v.scale) || 35) +
      __mmMillScale +
      (Number(__mmData && __mmData.placeOffset) || 0),
    __mmHasMovementDirection =
      typeof Kt === "number" && Number.isFinite(Kt),
    __mmMoved =
      __mmSmartMillX == null || __mmSmartMillY == null
        ? Infinity
        : Math.hypot(
            __mmPlayerX - __mmSmartMillX,
            __mmPlayerY - __mmSmartMillY,
          ),
    // Probe after only a few pixels and let the native collision test decide
    // the exact first legal frame. The anchor is advanced only after a full
    // row is sent, while short reservations suppress duplicate packets.
    __mmProbeDistance = Math.max(4, __mmMillScale * 0.12);
  if (__mmSmartMillX == null || __mmSmartMillY == null) {
    ((__mmSmartMillX = __mmPlayerX), (__mmSmartMillY = __mmPlayerY));
    // Do not choose an arbitrary world angle while standing still. If the
    // movement key is already held, Kt is available and the first row can be
    // emitted immediately; otherwise wait for actual movement.
    if (!__mmHasMovementDirection) return;
  }
  if (
    __mmMoved < __mmProbeDistance ||
    __mmNow - __mmSmartMillLastAt < 4 ||
    !__mmActionCanPreempt("smartAutoPlace")
  )
    return;
  const __mmDirection =
      __mmHasMovementDirection
        ? Kt
        : Math.atan2(
            __mmPlayerY - __mmSmartMillY,
            __mmPlayerX - __mmSmartMillX,
          ),
    __mmBehind = __mmDirection + Math.PI,
    // Derive this offset from the real mill diameter and placement distance.
    // The tiny clearance avoids floating-point overlap between the
    // three candidates while keeping the row tighter than a hardcoded angle.
    __mmSideOffset =
      2 *
      Math.asin(
        Math.min(0.999, (__mmMillScale + 1) / __mmPlaceDistance),
      ),
    __mmAngles = [
      __mmBehind,
      __mmBehind - __mmSideOffset,
      __mmBehind + __mmSideOffset,
    ],
    __mmCandidates = [];
  for (let __mmIndex = 0; __mmIndex < __mmAngles.length; __mmIndex++) {
    const __mmCandidate = __mmSmartCandidateForAngle(__mmMill, __mmAngles[__mmIndex]);
    if (__mmCandidate) ((__mmCandidate.points = 1), __mmCandidates.push(__mmCandidate));
  }
  const __mmTargetCount = Math.min(3, __mmMaxBuildCount(__mmMill));
  // Match the fast clients' one-tick row: do not send a partial pattern merely
  // because one side is still touching the previous row. Retry on the next
  // 10ms placement scan and emit all available row slots together.
  const __mmPlaced =
    __mmTargetCount > 0 && __mmCandidates.length >= __mmTargetCount
      ? __mmSmartPlaceBatch(
          __mmCandidates,
          "fast moving mills",
          __mmTargetCount,
        )
      : 0;
  if (__mmPlaced)
    ((__mmSmartMillX = __mmPlayerX),
      (__mmSmartMillY = __mmPlayerY),
      (__mmSmartMillLastAt = __mmNow));
}
function __mmSmartAntiBoostCandidates(__mmEnemy, __mmNow) {
  if (!__mmSmartAntiBoostPlaceEnabled || !__mmEnemy || __mmInsta.isActive())
    return [];
  const __mmPrediction = __mmSmartEnemyPrediction(__mmEnemy, __mmNow),
    __mmToUsX = v.x - __mmEnemy.x,
    __mmToUsY = v.y - __mmEnemy.y,
    __mmMovingToward =
      __mmPrediction.speed > 0.055 &&
      __mmPrediction.vx * __mmToUsX + __mmPrediction.vy * __mmToUsY > 0;
  if (
    (!__mmMovingToward && !__mmEnemyNearBoostPad(__mmEnemy)) ||
    Math.hypot(__mmToUsX, __mmToUsY) > __mmAntiBoostRange
  )
    return [];
  const __mmDirection = Math.atan2(__mmEnemy.y - v.y, __mmEnemy.x - v.x),
    __mmBlocker = __mmSmartNamedItem("blocker"),
    __mmSpike = __mmHoldingMcGrabby() ? null : __mmSpikeItem(),
    __mmTrap = __mmSmartPitTrapItem(),
    __mmWall = __mmSmartBuildItem(function (__mmData) {
      return /wall/i.test(String(__mmData.name || ""));
    }),
    __mmItem =
      __mmBlocker != null
        ? __mmBlocker
        : __mmSpike != null && __mmCanUseBuildItem(__mmSpike)
          ? __mmSpike
          : __mmTrap != null
            ? __mmTrap
            : __mmWall;
  if (__mmItem == null) return [];
  const __mmRingSamples = Math.max(
      16,
      Math.min(56, Math.round(20 + __mmEffectiveSmartDepth() * 3.2)),
    ),
    __mmAngles =
      __mmItem === __mmSpike
        ? [
            __mmDirection + Math.PI / 2,
            __mmDirection - Math.PI / 2,
            __mmDirection + Math.PI,
          ]
        : Array.from({ length: __mmRingSamples }, function (_, __mmIndex) {
            return (
              __mmDirection +
              (__mmIndex * Math.PI * 2) / __mmRingSamples
            );
          }),
    __mmCandidates = [];
  for (let __mmIndex = 0; __mmIndex < __mmAngles.length; __mmIndex++) {
    const __mmCandidate = __mmSmartCandidateForAngle(__mmItem, __mmAngles[__mmIndex]);
    if (__mmCandidate)
      ((__mmCandidate.points = 20 - __mmIndex * 0.01),
        __mmCandidates.push(__mmCandidate));
  }
  return __mmCandidates;
}
function __mmUpdateSmartPlacement() {
  const __mmNow = Date.now();
  if (!v || !v.alive) {
    __mmSmartSetStatus("waiting", "player not spawned", {
      legal: 0,
      scored: 0,
      itemSummary: "none",
    });
    return;
  }
  ((__mmSmartPreviewSamples.length = 0),
    __mmAutoSpikeSpamCleanReservations(__mmNow),
    __mmSmartObserveRemovedObjects(__mmNow),
    __mmSmartUpdateMovingMills(__mmNow));
  if (__mmNow > __mmSmartReplaceUntil) __mmSmartReplacePoint = null;
  const __mmWanted = !!(
    __mmSmartAutoPlaceEnabled ||
    __mmAutomaticQuadPlacementEnabled() ||
    __mmSmartReplacePoint ||
    __mmSmartAntiBoostPlaceEnabled
  );
  if (!__mmWanted) {
    __mmSmartSetStatus("off", "smart auto place disabled", {
      legal: 0,
      scored: 0,
    });
    return;
  }
  __mmActionOwner === "manualAttack" &&
    !__mmPrimaryHeld &&
    !__mmSecondaryHeld &&
    __mmActionRelease("manualAttack", "stale click state cleared");
  let __mmBusyReason = "";
  if (__mmInsta.isActive()) __mmBusyReason = "Insta active";
  else if (__mmBoostInsta.isActive()) __mmBusyReason = "boost Insta active";
  else if (__mmTrapAttackActive) __mmBusyReason = "trap escape active";
  else if (__mmBoostBreakHeld) __mmBusyReason = "boost break active";
  else if (__mmFoodSpamTimer) __mmBusyReason = "food input held";
  else if (__mmBuildSpamTimer) __mmBusyReason = "manual build held";
  else if (!__mmActionCanPreempt("smartAutoPlace"))
    __mmBusyReason = "action owned by " + __mmActionOwner;
  if (__mmBusyReason) {
    __mmSmartSetStatus("deferred", __mmBusyReason);
    return;
  }
  const __mmEnemies = (__mmLiveStateFresh() ? __mmLiveState.enemies : E)
      .filter(__mmIsEnemyPlayer)
      .sort(function (__mmLeft, __mmRight) {
        const __mmLeftTrapped = !!__mmAutoSpikeSpamTrapForEnemy(__mmLeft),
          __mmRightTrapped = !!__mmAutoSpikeSpamTrapForEnemy(__mmRight);
        if (__mmLeftTrapped !== __mmRightTrapped)
          return __mmLeftTrapped ? -1 : 1;
        return (
          Math.hypot(__mmLeft.x - v.x, __mmLeft.y - v.y) -
          Math.hypot(__mmRight.x - v.x, __mmRight.y - v.y)
        );
      }),
    __mmScanInterval = __mmSmartReplacePoint
      ? 5
      : __mmEnemies.length
        ? Math.max(12, Math.min(25, __mmFastCheckMs()))
        : 60;
  if (
    __mmNow - __mmSmartPlacementCalculatedAt < __mmScanInterval &&
    !__mmSmartReplacePoint
  )
    return;
  ((__mmSmartPlacementCalculatedAt = __mmNow),
    (__mmSmartPlacementStats.scans += 1));
  const __mmCanSend = !!(
    __mmSmartReplacePoint ||
    __mmNow - __mmSmartPlacementLastAt >= __mmServerTickMs()
  );
  let __mmAntiBoost = [];
  for (let __mmIndex = 0; __mmIndex < __mmEnemies.length; __mmIndex++) {
    __mmAntiBoost = __mmSmartAntiBoostCandidates(__mmEnemies[__mmIndex], __mmNow);
    if (__mmAntiBoost.length) break;
  }
  if (__mmAntiBoost.length) {
    if (__mmCanSend)
      __mmSmartPlaceBatch(__mmAntiBoost, "anti-boost fallback");
    else {
      const __mmArmed = __mmSmartBestCombination(
        __mmAntiBoost.slice().sort(function (__mmLeft, __mmRight) {
          return __mmRight.points - __mmLeft.points;
        }),
        __mmSmartMultiPlaceEnabled ? __mmSmartMaxPlacements : 1,
      );
      (__mmSmartSetPlacementPreview(
        __mmAntiBoost,
        __mmArmed,
        "armed for next placement tick",
      ),
        __mmSmartSetStatus("armed", "anti-boost next tick", {
          legal: __mmAntiBoost.length,
          scored: __mmAntiBoost.length,
        }));
    }
    return;
  }
  if (
    !__mmSmartAutoPlaceEnabled &&
    !__mmAutomaticQuadPlacementEnabled() &&
    !__mmSmartReplacePoint
  )
    return;
  if (!__mmEnemies.length && !__mmSmartReplacePoint) {
    (__mmSmartSetPlacementPreview([], [], "waiting for enemy"),
      __mmSmartSetStatus("watching", "waiting for enemy", {
        legal: 0,
        scored: 0,
      }));
    return;
  }
  const __mmNearestPlacementEnemyDistance = __mmEnemies.length
    ? Math.hypot(
        __mmEnemies[0].x - v.x,
        __mmEnemies[0].y - v.y,
      )
    : Infinity;
  if (
    !__mmSmartReplacePoint &&
    __mmNearestPlacementEnemyDistance > 450
  ) {
    (__mmSmartSetPlacementPreview([], [], "enemy outside placement ring"),
      __mmSmartSetStatus(
        "watching",
        "nearest enemy " +
          Math.round(__mmNearestPlacementEnemyDistance) +
          "px away",
        { legal: 0, scored: 0 },
      ));
    return;
  }
  const __mmSpike =
      __mmHoldingMcGrabby() || __mmEmergencyGetawayActive()
        ? null
        : __mmSpikeItem(),
    __mmTrap = __mmSmartPitTrapItem(),
    __mmSpikeReady =
      __mmSpike != null &&
      __mmCanUseBuildItem(__mmSpike) &&
      __mmMaxBuildCount(__mmSpike) > 0,
    __mmTrapReady =
      __mmTrap != null &&
      __mmCanUseBuildItem(__mmTrap) &&
      __mmMaxBuildCount(__mmTrap) > 0,
    __mmItemSummary = [
      __mmSpike == null
        ? __mmHoldingMcGrabby()
          ? "spike suppressed by Mc Grabby"
          : __mmEmergencyGetawayActive()
            ? "spike suppressed by getaway"
          : "no spike"
        : __mmSpikeReady
          ? "spike ready"
          : "spike unavailable",
      __mmTrap == null
        ? "no pit trap"
        : __mmTrapReady
          ? "pit trap ready"
          : "pit trap unavailable",
    ].join(" · "),
    __mmHazards = __mmSmartFriendlyHazards(),
    __mmSpikeEnemyPotentials = __mmSpikeReady
      ? __mmSmartEnemyPlacementPotentials(
          __mmEnemies,
          __mmSpike,
          __mmNow,
        )
      : null,
    __mmTrapEnemyPotentials = __mmTrapReady
      ? __mmSmartEnemyPlacementPotentials(
          __mmEnemies,
          __mmTrap,
          __mmNow,
        )
      : null,
    __mmCandidates = [];
  if (!__mmSpikeReady && !__mmTrapReady) {
    (__mmSmartSetPlacementPreview([], [], __mmItemSummary),
      __mmSmartSetStatus("blocked", "no affordable equipped placeable", {
        legal: 0,
        scored: 0,
        itemSummary: __mmItemSummary,
      }));
    return;
  }
  __mmSpikeReady &&
    __mmCandidates.push(
      ...__mmSmartPlacementCandidates(
        __mmSpike,
        __mmEnemies,
        __mmHazards,
        __mmNow,
        __mmSpikeEnemyPotentials,
      ),
    );
  __mmTrapReady &&
    __mmCandidates.push(
      ...__mmSmartPlacementCandidates(
        __mmTrap,
        __mmEnemies,
        __mmHazards,
        __mmNow,
        __mmTrapEnemyPotentials,
      ),
    );
  __mmSmartAutoPlaceEnabled &&
    __mmSmartApplyCorePressureFallback(
      __mmCandidates,
      __mmEnemies,
      __mmNow,
    );
  const __mmQuadTrapCandidates = __mmSmartQuadTrapCandidates(
      __mmCandidates,
      __mmEnemies,
      __mmNow,
    ),
    __mmQuadSpikeCandidates = __mmSmartQuadSpikeCandidates(
      __mmCandidates,
      __mmEnemies,
      __mmNow,
    ),
    __mmQuadLimit = Math.max(
      1,
      Math.min(4, Number(__mmSmartMaxPlacements) || 4),
    ),
    __mmQuadTrapSelection = __mmQuadTrapCandidates.length
      ? __mmSmartBestCombination(
          __mmQuadTrapCandidates,
          __mmQuadLimit,
        )
      : [],
    __mmQuadSpikeSelection = __mmQuadSpikeCandidates.length
      ? __mmSmartBestCombination(__mmQuadSpikeCandidates, __mmQuadLimit)
      : [],
    __mmNearestIsTrapped = !!(
      __mmEnemies[0] && __mmAutoSpikeSpamTrapForEnemy(__mmEnemies[0])
    ),
    __mmHasSpikeOpportunity = __mmQuadSpikeSelection.some(function (
      __mmCandidate,
    ) {
      return (
        __mmCandidate.priority ||
        __mmCandidate.reasons.some(function (__mmReason) {
          return /(?:contact|trapped surround|knock|spike chain|bounce)/i.test(
            String(__mmReason),
          );
        })
      );
    }),
    __mmUseQuadSpikesFirst =
      (__mmNearestIsTrapped || __mmHasSpikeOpportunity) &&
      __mmQuadSpikeSelection.length > 0;
  if (__mmUseQuadSpikesFirst) {
    __mmSmartSetStatus(
      __mmCanSend ? "ready" : "armed",
      __mmCanSend
        ? __mmNearestIsTrapped
          ? "quad spike trapped surround"
          : "quad spike contact/knockback"
        : "quad spikes armed for next placement tick",
      {
        legal: __mmQuadSpikeCandidates.length,
        scored: __mmQuadSpikeSelection.length,
        itemSummary: __mmItemSummary,
      },
    );
    if (__mmCanSend)
      __mmSmartPlaceBatch(
        __mmQuadSpikeCandidates,
        __mmNearestIsTrapped
          ? "quad spike trapped surround"
          : "quad spike contact/knockback",
        __mmQuadLimit,
      );
    else
      __mmSmartSetPlacementPreview(
        __mmQuadSpikeCandidates,
        __mmQuadSpikeSelection,
        "quad spikes armed for next placement tick",
      );
    return;
  }
  if (__mmQuadTrapSelection.length) {
    __mmSmartSetStatus(
      __mmCanSend ? "ready" : "armed",
      __mmCanSend
        ? "quad trap full-place"
        : "quad traps armed for next placement tick",
      {
        legal: __mmQuadTrapCandidates.length,
        scored: __mmQuadTrapSelection.length,
        itemSummary: __mmItemSummary,
      },
    );
    if (__mmCanSend)
      __mmSmartPlaceBatch(
        __mmQuadTrapCandidates,
        "quad trap full-place",
        __mmQuadLimit,
      );
    else
      __mmSmartSetPlacementPreview(
        __mmQuadTrapCandidates,
        __mmQuadTrapSelection,
        "quad traps armed for next placement tick",
      );
    return;
  }
  if (__mmQuadSpikeSelection.length) {
    __mmSmartSetStatus(
      __mmCanSend ? "ready" : "armed",
      __mmCanSend
        ? "quad spike contact full-place"
        : "quad spikes armed for next placement tick",
      {
        legal: __mmQuadSpikeCandidates.length,
        scored: __mmQuadSpikeSelection.length,
        itemSummary: __mmItemSummary,
      },
    );
    if (__mmCanSend)
      __mmSmartPlaceBatch(
        __mmQuadSpikeCandidates,
        "quad spike contact full-place",
        __mmQuadLimit,
      );
    else
      __mmSmartSetPlacementPreview(
        __mmQuadSpikeCandidates,
        __mmQuadSpikeSelection,
        "quad spikes armed for next placement tick",
      );
    return;
  }
  if (!__mmSmartAutoPlaceEnabled && !__mmSmartReplacePoint) {
    (__mmSmartSetPlacementPreview(
      __mmCandidates,
      [],
      "automatic quads found no useful legal pattern",
    ),
      __mmSmartSetStatus(
        "watching",
        "automatic quads waiting for trap/contact pressure",
        {
          legal: __mmCandidates.length,
          scored: 0,
          itemSummary: __mmItemSummary,
        },
      ));
    return;
  }
  const __mmScored = __mmCandidates.filter(function (__mmCandidate) {
      return __mmCandidate.points > 0;
    }).length,
    __mmBlockedSamples = __mmSmartPreviewSamples.filter(function (__mmCandidate) {
      return __mmCandidate && __mmCandidate.valid === !1;
    }).length,
    __mmReason = __mmSmartReplacePoint
      ? "destroyed-object replace"
      : "smart auto place";
  __mmSmartSetStatus(
    __mmScored ? (__mmCanSend ? "ready" : "armed") : "blocked",
    __mmScored
      ? __mmCanSend
        ? "legal scored slots"
        : "waiting for next placement tick"
      : __mmCandidates.length
        ? "legal ring but no useful intercept"
        : "all sampled slots occupied",
    {
      legal: __mmCandidates.length,
      scored: __mmScored,
      blocked: __mmBlockedSamples,
      itemSummary: __mmItemSummary,
    },
  );
  if (__mmCandidates.length && __mmScored && __mmCanSend)
    __mmSmartPlaceBatch(__mmCandidates, __mmReason);
  else if (__mmCandidates.length && __mmScored) {
    const __mmRanked = __mmCandidates.slice().sort(function (
        __mmLeft,
        __mmRight,
      ) {
        return __mmRight.points - __mmLeft.points;
      }),
      __mmArmed = __mmSmartBestCombination(
        __mmRanked,
        __mmSmartMultiPlaceEnabled ? __mmSmartMaxPlacements : 1,
      );
    __mmSmartSetPlacementPreview(
      __mmCandidates,
      __mmArmed,
      "armed for next placement tick",
    );
  } else
    __mmSmartSetPlacementPreview(
      [],
      [],
      __mmCandidates.length
        ? "legal ring but no useful intercept"
        : "all sampled slots occupied",
    );
  __mmSmartReplacePoint &&
    (__mmCanSend || !__mmCandidates.length) &&
    (__mmSmartReplacePoint = null);
}
function __mmStartSmartPlacement() {
  (__mmEnsureOperationPipeline(), __mmUpdateSmartPlacement());
}
function __mmRefreshSmartPlacementLoop() {
  const __mmWanted = !!(
    __mmSmartAutoPlaceEnabled ||
    __mmAutomaticQuadPlacementEnabled() ||
    __mmSmartAutoReplaceEnabled ||
    __mmSmartSpikeSyncPlaceEnabled ||
    __mmSmartAntiBoostPlaceEnabled ||
    __mmSmartMovingMillsEnabled
  );
  if (__mmWanted) return void __mmStartSmartPlacement();
  (function () {
    for (const __mmTimer of __mmSmartPreplaceTimers) clearTimeout(__mmTimer);
    (__mmSmartPreplaceTimers.clear(), __mmSmartPreplaceKeys.clear());
  })();
  (__mmSmartPlacementTimer && clearInterval(__mmSmartPlacementTimer),
    (__mmSmartPlacementTimer = 0),
    (__mmSmartReplacePoint = null),
    __mmSmartSetStatus("off", "smart auto place disabled", {
      legal: 0,
      scored: 0,
    }));
}
function __mmToggleSmartMovingMills() {
  ((__mmSmartMovingMillsEnabled = !__mmSmartMovingMillsEnabled),
    (__mmSmartMillX = null),
    (__mmSmartMillY = null),
    (__mmSmartMillLastAt = 0),
    __mmRefreshSmartPlacementLoop(),
    __mmBushStatus(
      "auto mills: " + (__mmSmartMovingMillsEnabled ? "on" : "off"),
    ),
    __mmPublishHudState());
}
function __mmEnableSmartMovingMills() {
  if (__mmSmartMovingMillsEnabled) return;
  ((__mmSmartMovingMillsEnabled = !0),
    (__mmSmartMillX = null),
    (__mmSmartMillY = null),
    (__mmSmartMillLastAt = 0),
    __mmRefreshSmartPlacementLoop(),
    __mmBushStatus("auto mills: on"),
    __mmPublishHudState());
}
function __mmSmartPlaceUtilityForInsta(__mmTarget, __mmWeapon) {
  if (
    !__mmSmartInstaUtilityPlaceEnabled ||
    !v ||
    !v.alive ||
    !__mmTarget ||
    Date.now() - __mmSmartUtilityLastAt < __mmServerTickMs()
  )
    return !1;
  const __mmPlatform = __mmSmartNamedItem("platform");
  if (__mmPlatform == null) return !1;
  const __mmAngle = Math.atan2(__mmTarget.y - v.y, __mmTarget.x - v.x),
    __mmCandidate = __mmSmartCandidateForAngle(__mmPlatform, __mmAngle);
  if (!__mmCandidate) return !1;
  const __mmPlaced = __mmInstaPlaceAndReselect(
    __mmPlatform,
    __mmAngle,
    __mmWeapon,
  );
  __mmPlaced && (__mmSmartUtilityLastAt = Date.now());
  return __mmPlaced;
}
function __mmEnemyNearBoostPad(__mmPlayer) {
  if (!__mmPlayer || !__mmPlayer.alive) return !1;
  const __mmGrids = X.getGridArrays(__mmPlayer.x, __mmPlayer.y, 180);
  for (let __mmGridIndex = 0; __mmGridIndex < __mmGrids.length; __mmGridIndex++)
    for (
      let __mmItemIndex = 0;
      __mmItemIndex < __mmGrids[__mmGridIndex].length;
      __mmItemIndex++
    ) {
      const __mmObject = __mmGrids[__mmGridIndex][__mmItemIndex];
      if (!__mmObject.active || !__mmObject.boostSpeed) continue;
      const __mmRange = __mmPlayer.scale + __mmObject.scale + 80,
        __mmDx = __mmPlayer.x - __mmObject.x,
        __mmDy = __mmPlayer.y - __mmObject.y;
      if (__mmDx * __mmDx + __mmDy * __mmDy <= __mmRange * __mmRange) return !0;
    }
  return !1;
}
function __mmAntiBoostAngles(__mmAngle, __mmCount) {
  if (__mmCount <= 1) return [__mmAngle];
  return [__mmAngle - 0.46, __mmAngle + 0.46];
}
function __mmPlaceAntiBoostSpikes(__mmAngle) {
  // Boost-rush defense is the one automatic spike exception while Mc Grabby
  // is selected, matching the anti-boost insta safety path.
  if (
    __mmEmergencyGetawayActive() ||
    (__mmHoldingMcGrabby() && !__mmAntiBoostInstaEnabled)
  )
    return 0;
  const __mmSpike = __mmSpikeItem(),
    __mmCount = Math.min(2, __mmMaxBuildCount(__mmSpike));
  if (__mmSpike == null || __mmCount < 1) return 0;
  const __mmTool = __mmSelectedTool(),
    __mmAngles = __mmAntiBoostAngles(__mmAngle, __mmCount);
  let __mmPlaced = 0;
  for (let __mmIndex = 0; __mmIndex < __mmAngles.length; __mmIndex++) {
    const __mmCandidate = __mmSmartNearestLegalCandidate(
      __mmSpike,
      __mmAngles[__mmIndex],
      0.34,
      0.04,
    );
    if (
      !__mmCandidate ||
      !__mmSendAutomaticPlacement(
        __mmSpike,
        __mmCandidate.angle,
        __mmTool,
      )
    )
      continue;
    (__mmAutoSpikeSpamReservations.push({
      item: __mmSpike,
      x: __mmCandidate.x,
      y: __mmCandidate.y,
      scale: __mmCandidate.scale,
      expiresAt: Date.now() + 650,
    }),
      __mmPlaced++);
  }
  return __mmPlaced;
}
function __mmStopAntiBoostRetreat() {
  (__mmAntiBoostMoveTimer && clearTimeout(__mmAntiBoostMoveTimer),
    (__mmAntiBoostMoveTimer = 0));
  if (!__mmAntiBoostBackingUp) return;
  ((__mmAntiBoostBackingUp = !1), (Kt = null), Tt());
}
function __mmStopAntiBoostBlock(__mmReason) {
  const __mmTool = __mmAntiBoostBlockTool,
    __mmRestore = __mmActionMayRestore("antiBoostBlock");
  (__mmAntiBoostBlockTimer && clearTimeout(__mmAntiBoostBlockTimer),
    (__mmAntiBoostBlockTimer = 0),
    __mmStopAntiBoostRetreat(),
    (__mmAntiBoostBlockTool = null),
    (__mmAntiBoostBlockAimAngle = null),
    __mmRestore && __mmRestoreTool(__mmTool),
    __mmRestore && __mmResumeHeldAttack(),
    __mmActionRelease(
      "antiBoostBlock",
      __mmReason || "boost block complete",
    ));
}
function __mmStartAntiBoostBlock(__mmEnemy) {
  if (
    !__mmAntiBoostEnabled ||
    !v ||
    !v.alive ||
    !__mmEnemy ||
    __mmAntiBoostBlockTimer
  )
    return !1;
  __mmActionOwner === "shieldDefense" &&
    __mmStopShieldDefense("boost block priority");
  if (!__mmActionClaim("antiBoostBlock", "boost-pad rush")) return !1;
  const __mmToward = Math.atan2(__mmEnemy.y - v.y, __mmEnemy.x - v.x),
    __mmAway = __mmToward + Math.PI,
    __mmWindow = Math.max(180, 3 * __mmServerTickMs());
  ((__mmAntiBoostBlockTool = __mmSelectedTool()),
    (__mmAntiBoostBlockAimAngle = __mmToward),
    __mmPlaceAntiBoostSpikes(__mmToward),
    O.send("D", __mmToward),
    O.send("9", __mmAway),
    (Kt = __mmAway),
    (__mmAntiBoostBackingUp = !0),
    v.weapons &&
      v.weapons.includes(__mmShieldWeapon) &&
      je(__mmShieldWeapon, !0),
    (__mmAntiBoostMoveTimer = setTimeout(
      __mmStopAntiBoostRetreat,
      Math.max(120, 2 * __mmServerTickMs()),
    )),
    (__mmAntiBoostBlockTimer = setTimeout(function () {
      __mmStopAntiBoostBlock("boost block complete");
    }, __mmWindow)));
  return !0;
}
function __mmUpdateAntiBoostInsta() {
  // An active burst owns its complete Bull-primary -> Turret-secondary window.
  if (__mmInsta.isActive()) return;
  if (
    !__mmAntiBoostInstaEnabled ||
    __mmEmergencyGetawayActive() ||
    !v ||
    !v.alive ||
    __mmTrapAttackActive ||
    __mmBoostBreakHeld
  )
    return;
  const __mmNow = Date.now();
  for (let __mmPlayerIndex = 0; __mmPlayerIndex < E.length; __mmPlayerIndex++) {
    const __mmEnemy = E[__mmPlayerIndex];
    if (!__mmIsEnemyPlayer(__mmEnemy)) continue;
    const __mmSid = String(__mmEnemy.sid),
      __mmTrail =
        __mmEnemyBoostTrail[__mmSid] ||
        (__mmEnemyBoostTrail[__mmSid] = {
          x: __mmEnemy.x,
          y: __mmEnemy.y,
          time: __mmNow,
          boostAt: 0,
        }),
      __mmDx = __mmEnemy.x - __mmTrail.x,
      __mmDy = __mmEnemy.y - __mmTrail.y,
      __mmToPlayerX = v.x - __mmEnemy.x,
      __mmToPlayerY = v.y - __mmEnemy.y,
      __mmDistance =
        __mmToPlayerX * __mmToPlayerX + __mmToPlayerY * __mmToPlayerY;
    if (__mmEnemyNearBoostPad(__mmEnemy)) __mmTrail.boostAt = __mmNow;
    const __mmFreshBoost = __mmNow - __mmTrail.boostAt <= 700,
      __mmMovingToward =
        __mmDx * __mmDx + __mmDy * __mmDy > 0.25 &&
        __mmDx * __mmToPlayerX + __mmDy * __mmToPlayerY > 0;
    ((__mmTrail.x = __mmEnemy.x),
      (__mmTrail.y = __mmEnemy.y),
      (__mmTrail.time = __mmNow));
    if (
      __mmFreshBoost &&
      __mmDistance <= __mmAntiBoostRange * __mmAntiBoostRange &&
      __mmMovingToward
    ) {
      if (
        __mmAntiBoostInstaEnabled &&
        __mmFullInstaReadyFor(__mmEnemy) &&
        __mmInsta.start({ automatic: !0, targetSid: __mmEnemy.sid })
      ) {
        ((__mmAntiBoostLast = __mmNow), (__mmTrail.boostAt = 0));
        return;
      }
    }
  }
}
function __mmStartAntiBoostInsta() {
  __mmEnsureOperationPipeline();
}
function __mmReloadSpikeTarget() {
  if (!v || !v.alive) return null;
  if (!__mmMusketIsReloading() && !__mmTurretGearIsReloading()) return null;
  const __mmEnemy = __mmNearestEnemy();
  if (!__mmEnemy) return null;
  const __mmDx = __mmEnemy.x - v.x;
  const __mmDy = __mmEnemy.y - v.y;
  const __mmRange = Math.min(220, Math.max(120, __mmCombatRange));
  return __mmDx * __mmDx + __mmDy * __mmDy <= __mmRange * __mmRange
    ? __mmEnemy
    : null;
}
function __mmPlaceReloadSpike(__mmTarget) {
  if (__mmEmergencyGetawayActive() || __mmHoldingMcGrabby()) return !1;
  const __mmSpike = __mmSpikeItem();
  if (
    !__mmTarget ||
    __mmSpike == null ||
    !__mmCanUseBuildItem(__mmSpike)
  )
    return !1;
  const __mmTool = __mmSelectedTool();
  const __mmAngle = Math.atan2(__mmTarget.y - v.y, __mmTarget.x - v.x),
    __mmCandidate = __mmSmartNearestLegalCandidate(
      __mmSpike,
      __mmAngle,
      0.52,
      0.04,
    );
  if (!__mmCandidate) return !1;
  return __mmSendAutomaticPlacement(
    __mmSpike,
    __mmCandidate.angle,
    __mmTool,
  );
}
function __mmUpdateReloadSpike() {
  const __mmReloading = __mmMusketIsReloading() || __mmTurretGearIsReloading();
  if (!__mmReloading) return void (__mmReloadSpikePlaced = !1);
  if (
    !__mmReloadSpikeEnabled ||
    __mmEmergencyGetawayActive() ||
    __mmReloadSpikePlaced ||
    __mmHoldingMcGrabby() ||
    !v ||
    !v.alive ||
    __mmInsta.isActive() ||
    __mmTrapAttackActive ||
    __mmBoostBreakHeld ||
    __mmFoodSpamTimer ||
    __mmAutoHealWasHealing ||
    __mmBuildSpamTimer
  )
    return;
  const __mmTarget = __mmReloadSpikeTarget();
  if (!__mmTarget || !__mmActionClaim("reloadSpike", "reload defense")) return;
  (__mmPlaceReloadSpike(__mmTarget) && (__mmReloadSpikePlaced = !0),
    __mmActionRelease("reloadSpike", "reload defense sent"));
}
function __mmStartReloadSpike() {
  __mmEnsureOperationPipeline();
}
function __mmStopBuildSpam(__mmKey) {
  (!__mmKey || __mmKey == __mmBuildSpamKey) &&
    (__mmBuildSpamTimer && clearInterval(__mmBuildSpamTimer),
    (__mmBuildSpamTimer = 0),
    (__mmBuildSpamKey = 0));
}
function __mmStartBuildSpam(__mmItemSlot, __mmKey) {
  __mmInsta.isActive() && __mmInsta.cancel("build-input");
  if (__mmBuildSpamTimer && __mmBuildSpamKey == __mmKey) return;
  (__mmStopBuildSpam(),
    (__mmBuildSpamKey = __mmKey),
    __mmUseBuild(__mmItemSlot),
    (__mmBuildSpamTimer = setInterval(function () {
      __mmUseBuild(__mmItemSlot);
    }, 1e3 / y.serverUpdateRate)));
}
function __mmStartBuildItemSpam(__mmItem, __mmKey) {
  __mmInsta.isActive() && __mmInsta.cancel("build-input");
  if (__mmBuildSpamTimer && __mmBuildSpamKey == __mmKey) return;
  (__mmStopBuildSpam(),
    (__mmBuildSpamKey = __mmKey),
    __mmUseBuildItem(__mmItem),
    (__mmBuildSpamTimer = setInterval(
      function () {
        __mmUseBuildItem(__mmItem);
      },
      1e3 / Math.max(1, Number(y.serverUpdateRate) || 9),
    )));
}
function __mmStartSelectedBuildSpam(__mmKey) {
  const __mmItem = __mmSelectedPlaceableItem();
  __mmItem != null && __mmStartBuildItemSpam(__mmItem, __mmKey);
}
function __mmWindmillItem() {
  if (!v || !v.items) return null;
  for (let __mmItemIndex = 0; __mmItemIndex < v.items.length; __mmItemIndex++) {
    const __mmItem = v.items[__mmItemIndex],
      __mmData = b.list[__mmItem];
    if (
      __mmData &&
      typeof __mmData.name === "string" &&
      __mmData.name.indexOf("mill") !== -1
    )
      return __mmItem;
  }
  return null;
}
function __mmWindmillData(__mmValue) {
  const __mmName = String(__mmValue && __mmValue.name || "")
    .trim()
    .toLowerCase();
  return !!(
    __mmValue &&
    (__mmName === "windmill" ||
      __mmName === "faster windmill" ||
      __mmName === "power mill")
  );
}
function __mmRememberWindmillTurnSpeed(__mmObject, __mmRemembered) {
  if (!__mmObject || !__mmRemembered) return;
  const __mmProperties = ["turnSpeed", "spinSpeed", "rotationSpeed"];
  for (let __mmIndex = 0; __mmIndex < __mmProperties.length; __mmIndex++) {
    const __mmProperty = __mmProperties[__mmIndex],
      __mmSpeed = Number(__mmObject[__mmProperty]);
    if (
      !Object.prototype.hasOwnProperty.call(__mmRemembered, __mmProperty) &&
      Number.isFinite(__mmSpeed)
    )
      __mmRemembered[__mmProperty] = __mmSpeed;
  }
}
function __mmApplyRememberedWindmillSpeed(
  __mmObject,
  __mmRemembered,
) {
  if (!__mmObject || !__mmRemembered) return;
  for (const __mmProperty in __mmRemembered)
    try {
      __mmObject[__mmProperty] = __mmSpinningWindmillsEnabled
        ? __mmRemembered[__mmProperty]
        : 0;
    } catch (__mmWindmillSpeedWriteError) {}
}
function __mmApplyWindmillRotationState() {
  if (b && Array.isArray(b.list))
    for (let __mmItem = 0; __mmItem < b.list.length; __mmItem++) {
      const __mmData = b.list[__mmItem];
      if (!__mmWindmillData(__mmData)) continue;
      const __mmKey = String(__mmItem),
        __mmRemembered =
          __mmWindmillDataTurnSpeeds[__mmKey] ||
          (__mmWindmillDataTurnSpeeds[__mmKey] = Object.create(null));
      __mmRememberWindmillTurnSpeed(__mmData, __mmRemembered);
      __mmApplyRememberedWindmillSpeed(
        __mmData,
        __mmRemembered,
      );
    }
  const __mmMills = __mmActiveObjectSnapshot(!0).mills;
  for (let __mmIndex = 0; __mmIndex < __mmMills.length; __mmIndex++) {
    const __mmObject = __mmMills[__mmIndex],
      __mmData = __mmObject && b && b.list && b.list[__mmObject.id];
    if (!__mmObject || !__mmObject.active || !__mmWindmillData(__mmData))
      continue;
    let __mmRemembered = __mmWindmillObjectTurnSpeeds.get(__mmObject);
    if (!__mmRemembered) {
      __mmRemembered = Object.create(null);
      __mmWindmillObjectTurnSpeeds.set(__mmObject, __mmRemembered);
    }
    __mmRememberWindmillTurnSpeed(__mmObject, __mmRemembered);
    const __mmDataRemembered =
      __mmWindmillDataTurnSpeeds[String(__mmObject.id)];
    if (__mmDataRemembered)
      for (const __mmProperty in __mmDataRemembered)
        (!Object.prototype.hasOwnProperty.call(
          __mmRemembered,
          __mmProperty,
        ) ||
          (__mmSpinningWindmillsEnabled &&
            __mmRemembered[__mmProperty] === 0 &&
            __mmDataRemembered[__mmProperty] !== 0)) &&
          (__mmRemembered[__mmProperty] =
            __mmDataRemembered[__mmProperty]);
    __mmApplyRememberedWindmillSpeed(__mmObject, __mmRemembered);
  }
}
function __mmStartWindmillHold() {
  if (__mmWindmillHotkeyDown) return;
  ((__mmWindmillHotkeyDown = !0), __mmToggleSmartMovingMills());
}
function __mmStopWindmillHold() {
  __mmWindmillHotkeyDown = !1;
}
function __mmServerEntityPosition(__mmEntity) {
  if (!__mmEntity) return null;
  const __mmServerX = Number(__mmEntity.x2),
    __mmServerY = Number(__mmEntity.y2),
    __mmRenderX = Number(__mmEntity.x),
    __mmRenderY = Number(__mmEntity.y);
  if (
    __mmEntity.x2 != null &&
    __mmEntity.y2 != null &&
    Number.isFinite(__mmServerX) &&
    Number.isFinite(__mmServerY)
  )
    return { x: __mmServerX, y: __mmServerY };
  return Number.isFinite(__mmRenderX) && Number.isFinite(__mmRenderY)
    ? { x: __mmRenderX, y: __mmRenderY }
    : null;
}
function __mmActiveTrapObjects() {
  const __mmTraps = [];
  if (!Array.isArray(ge)) return __mmTraps;
  // Read the live render-object list directly. The general structure snapshot
  // is intentionally cached for FPS, but trap contact must update every scan.
  for (let __mmIndex = ge.length - 1; __mmIndex >= 0; __mmIndex--) {
    const __mmObject = ge[__mmIndex];
    __mmObject && __mmObject.active && __mmObject.trap &&
      __mmTraps.push(__mmObject);
  }
  return __mmTraps;
}
function __mmServerTrapContact(__mmEntity, __mmTrap) {
  const __mmPosition = __mmServerEntityPosition(__mmEntity),
    __mmTrapX = Number(__mmTrap && __mmTrap.x),
    __mmTrapY = Number(__mmTrap && __mmTrap.y);
  if (
    !__mmPosition ||
    !Number.isFinite(__mmTrapX) ||
    !Number.isFinite(__mmTrapY)
  )
    return !1;
  const __mmDx = __mmTrapX - __mmPosition.x,
    __mmDy = __mmTrapY - __mmPosition.y;
  // A player is caught only once its latest server point is within 47px of
  // the active pit-trap center. Render interpolation and player scale do not
  // widen this test, which prevents early and lingering trap incidents.
  return __mmDx * __mmDx + __mmDy * __mmDy <= 47 * 47;
}
function __mmPlayerCenterTouchesEnemyTrap(__mmTrap) {
  if (
    !v ||
    !v.alive ||
    !__mmTrap ||
    !__mmTrap.active ||
    !__mmTrap.trap ||
    __mmFriendlyStructure(__mmTrap)
  )
    return !1;
  return __mmServerTrapContact(v, __mmTrap);
}
function __mmNearestLockingTrap() {
  if (!v || !v.alive) return null;
  let __mmClosest = null,
    __mmClosestDistance = Infinity;
  const __mmSeen = new Set(),
    __mmConsider = function (__mmObject) {
      if (
        !__mmObject ||
        __mmSeen.has(__mmObject) ||
        !__mmObject.active ||
        !__mmObject.trap ||
        __mmFriendlyStructure(__mmObject)
      )
        return;
      __mmSeen.add(__mmObject);
      const __mmPosition = __mmServerEntityPosition(v),
        __mmDistance = __mmPosition
          ? (__mmObject.x - __mmPosition.x) ** 2 +
            (__mmObject.y - __mmPosition.y) ** 2
          : Infinity;
      if (!__mmPlayerCenterTouchesEnemyTrap(__mmObject)) return;
      __mmDistance < __mmClosestDistance &&
        ((__mmClosestDistance = __mmDistance), (__mmClosest = __mmObject));
    };
  try {
    const __mmGrids = X.getGridArrays(v.x, v.y, Math.max(180, v.scale * 5));
    for (let __mmGridIndex = 0; __mmGridIndex < __mmGrids.length; __mmGridIndex++)
      for (
        let __mmItemIndex = 0;
        __mmItemIndex < __mmGrids[__mmGridIndex].length;
        __mmItemIndex++
      )
        __mmConsider(__mmGrids[__mmGridIndex][__mmItemIndex]);
  } catch (__mmTrapGridError) {}
  // Item-grid visibility can lag a trap collision by one update. Scan the
  // render object list too, so the escape routine starts on the first lock tick.
  const __mmTraps = __mmActiveTrapObjects();
  for (let __mmItemIndex = 0; __mmItemIndex < __mmTraps.length; __mmItemIndex++)
    __mmConsider(__mmTraps[__mmItemIndex]);
  return __mmClosest;
}
function __mmFriendlyTrapForPlayer(__mmPlayer) {
  if (!v || !v.alive || !__mmPlayer) return null;
  let __mmClosest = null,
    __mmClosestDistance = Infinity;
  const __mmTraps = __mmActiveTrapObjects();
  for (let __mmIndex = 0; __mmIndex < __mmTraps.length; __mmIndex++) {
    const __mmTrap = __mmTraps[__mmIndex];
    if (
      !__mmTrap ||
      !__mmTrap.active ||
      !__mmTrap.trap ||
      !__mmFriendlyStructure(__mmTrap)
    )
      continue;
    const __mmPosition = __mmServerEntityPosition(__mmPlayer),
      __mmDistance = __mmPosition
        ? Math.hypot(__mmPosition.x - __mmTrap.x, __mmPosition.y - __mmTrap.y)
        : Infinity,
      __mmCaught = __mmServerTrapContact(__mmPlayer, __mmTrap);
    if (__mmCaught && __mmDistance < __mmClosestDistance)
      ((__mmClosest = __mmTrap), (__mmClosestDistance = __mmDistance));
  }
  return __mmClosest;
}
function __mmUpdateFriendlyTrapChat() {
  const __mmNow = Date.now(),
    __mmSeen = Object.create(null);
  let __mmFriendIncident = null,
    __mmEnemyIncident = null;
  if (v && v.alive && Array.isArray(E)) {
    for (let __mmIndex = 0; __mmIndex < E.length; __mmIndex++) {
      const __mmPlayer = E[__mmIndex];
      if (
        !__mmPlayer ||
        !__mmPlayer.alive ||
        __mmPlayer === v ||
        String(__mmPlayer.sid) === String(v.sid) ||
        (Number.isFinite(Number(__mmPlayer.health)) &&
          Number(__mmPlayer.health) <= 0)
      )
        continue;
      const __mmTeammate = __mmSameTeam(__mmPlayer),
        __mmFriend = __mmIsFriendPlayer(__mmPlayer),
        __mmFriendKey = __mmNormalizeFriendName(__mmPlayer.name),
        __mmBetrayed =
          !!__mmFriendKey && __mmFriendEnemies.has(__mmFriendKey),
        __mmEnemy = !__mmTeammate && !__mmFriend &&
          (__mmBetrayed || !__mmSameTeam(__mmPlayer));
      if (!__mmFriend && !__mmEnemy) continue;
      const __mmMessageRange = __mmFriend
        ? __mmFriendTrapChatRange
        : __mmEnemyTrapChatRange;
      if (
        Math.hypot(
          Number(__mmPlayer.x) - Number(v.x),
          Number(__mmPlayer.y) - Number(v.y),
        ) > __mmMessageRange
      )
        continue;
      const __mmTrap = __mmFriendlyTrapForPlayer(__mmPlayer);
      if (!__mmTrap) continue;
      const __mmKind = __mmFriend ? "friend" : "enemy",
        __mmKey = __mmKind + ":" + String(__mmPlayer.sid),
        __mmIncident =
          __mmFriendlyTrapChatIncidents[__mmKey] ||
          (__mmFriendlyTrapChatIncidents[__mmKey] = {
            announced: !1,
            lastSeen: __mmNow,
          });
      ((__mmIncident.lastSeen = __mmNow), (__mmSeen[__mmKey] = !0));
      if (!__mmIncident.announced) {
        const __mmCandidate = {
          key: __mmKey,
          player: __mmPlayer,
          trap: __mmTrap,
        };
        __mmFriend
          ? (__mmFriendIncident || (__mmFriendIncident = __mmCandidate))
          : (__mmEnemyIncident || (__mmEnemyIncident = __mmCandidate));
      }
    }
  }
  for (const __mmKey in __mmFriendlyTrapChatIncidents) {
    const __mmIncident = __mmFriendlyTrapChatIncidents[__mmKey];
    if (!__mmSeen[__mmKey] && __mmNow - __mmIncident.lastSeen > 450)
      delete __mmFriendlyTrapChatIncidents[__mmKey];
  }
  const __mmCandidate =
      (__mmFriendTrapChatEnabled && __mmFriendIncident) ||
      (__mmEnemyTrapChatEnabled && __mmEnemyIncident),
    __mmCooldown = Math.max(
      750,
      (Number(y && y.chatCooldown) || 500) + 150,
    );
  if (
    !__mmCandidate ||
    __mmNow - __mmFriendlyTrapChatLastAt < __mmCooldown
  )
    return;
  const __mmIncident = __mmFriendlyTrapChatIncidents[__mmCandidate.key];
  if (!__mmIncident || __mmIncident.announced) return;
  ((__mmIncident.announced = !0),
    (__mmFriendlyTrapChatLastAt = __mmNow),
    __mmSendChat(
      __mmCandidate.key.startsWith("friend:")
        ? "Uh oh! let me free you!"
        : "Ha, I have you in my trap!",
    ));
}
function __mmStartFriendlyTrapChat() {
  __mmFriendlyTrapChatTimer ||
    ((__mmFriendlyTrapChatTimer = setInterval(
      __mmUpdateFriendlyTrapChat,
      __mmFastCheckMs(),
    )),
    __mmUpdateFriendlyTrapChat());
}
function __mmTrapAngle() {
  const __mmTrap = __mmNearestLockingTrap();
  return __mmTrap == null
    ? null
    : Math.round(100 * Math.atan2(__mmTrap.y - v.y, __mmTrap.x - v.x)) / 100;
}
function __mmTrapBuildKey(__mmTrap) {
  if (!__mmTrap) return null;
  const __mmId =
    __mmTrap.sid != null
      ? __mmTrap.sid
      : __mmTrap.id != null
        ? __mmTrap.id
        : null;
  return __mmId != null
    ? "id:" + __mmId
    : "pos:" + Math.round(__mmTrap.x) + ":" + Math.round(__mmTrap.y);
}
function __mmAffordableBuildItem(__mmMatches) {
  if (!v || !v.items || !b || !b.list) return null;
  for (let __mmIndex = 0; __mmIndex < v.items.length; __mmIndex++) {
    const __mmItem = v.items[__mmIndex],
      __mmData = b.list[__mmItem];
    if (
      __mmData &&
      __mmMatches(__mmData, __mmItem) &&
      __mmCanUseBuildItem(__mmItem) &&
      __mmMaxBuildCount(__mmItem) > 0
    )
      return __mmItem;
  }
  return null;
}
function __mmTrapEmergencyItemKind(__mmItem) {
  const __mmData = b && b.list && b.list[__mmItem],
    __mmName = String((__mmData && __mmData.name) || "").toLowerCase();
  if (!__mmData) return null;
  if (__mmData.trap) return "trap";
  if (__mmName.includes("spikes")) return "spike";
  if (__mmName.includes("mill")) return "windmill";
  return null;
}
function __mmTrapEmergencyItemAvailable(__mmItem) {
  return !!(
    v &&
    Array.isArray(v.items) &&
    __mmItem != null &&
    v.items.includes(__mmItem) &&
    __mmCanUseBuildItem(__mmItem) &&
    __mmMaxBuildCount(__mmItem) > 0
  );
}
function __mmTrapEmergencyHeldPreference() {
  if (!v || !v.alive || !Array.isArray(v.items)) return null;
  const __mmBuild = Number(v.buildIndex);
  return Number.isInteger(__mmBuild) &&
    __mmBuild >= 0 &&
    v.items.includes(__mmBuild) &&
    __mmTrapEmergencyItemKind(__mmBuild)
    ? __mmBuild
    : null;
}
function __mmTrapEmergencySpikePressure(__mmEnemy) {
  if (!v || !v.alive || !__mmEnemy) return !1;
  const __mmDistance = Math.hypot(
    Number(__mmEnemy.x) - Number(v.x),
    Number(__mmEnemy.y) - Number(v.y),
  );
  if (!Number.isFinite(__mmDistance) || __mmDistance > 450) return !1;
  // An enemy already on top of the pin or closing into the next server tick
  // is immediate pressure and earns the two rear spike slots.
  if (__mmAutoSpikeSpamTrapForEnemy(__mmEnemy)) return !0;
  const __mmWeapon = b && b.weapons && b.weapons[Number(__mmEnemy.weaponIndex)],
    __mmEnemyReach =
      (Number(__mmWeapon && __mmWeapon.range) || 0) +
      (Number(__mmEnemy.scale) || 35) +
      (Number(v.scale) || 35) +
      42;
  if (__mmDistance <= Math.max(275, __mmEnemyReach)) return !0;
  const __mmVelocity = __mmSyncPlayerVelocity(__mmEnemy),
    __mmLead = __mmServerTickMs(),
    __mmFutureDistance = Math.hypot(
      Number(__mmEnemy.x) + __mmVelocity.x * __mmLead - Number(v.x),
      Number(__mmEnemy.y) + __mmVelocity.y * __mmLead - Number(v.y),
    );
  return __mmFutureDistance <= 340 && __mmFutureDistance < __mmDistance - 1.5;
}
function __mmTrapEmergencyFallbackItem(
  __mmPreferredItem,
  __mmSpikeOverride,
) {
  const __mmTrap = __mmAffordableBuildItem((__mmData) => !!__mmData.trap),
    __mmWindmill = __mmAffordableBuildItem(
      (__mmData) =>
        typeof __mmData.name === "string" &&
        __mmData.name.toLowerCase().includes("mill"),
    ),
    __mmSpike =
      __mmEmergencyGetawayActive() || __mmHoldingMcGrabby()
        ? null
        : __mmSpikeItem(),
    __mmOrder = __mmSpikeOverride
      ? [__mmSpike, __mmTrap, __mmWindmill]
      : [__mmPreferredItem, __mmTrap, __mmWindmill, __mmSpike],
    __mmSeen = new Set();
  for (let __mmIndex = 0; __mmIndex < __mmOrder.length; __mmIndex++) {
    const __mmItem = __mmOrder[__mmIndex];
    if (__mmItem == null || __mmSeen.has(__mmItem)) continue;
    __mmSeen.add(__mmItem);
    if (
      (__mmEmergencyGetawayActive() || __mmHoldingMcGrabby()) &&
      __mmTrapEmergencyItemKind(__mmItem) === "spike"
    )
      continue;
    if (__mmTrapEmergencyItemAvailable(__mmItem)) return __mmItem;
  }
  const __mmWall = __mmAffordableBuildItem(
    (__mmData) =>
      typeof __mmData.name === "string" && __mmData.name.indexOf("wall") !== -1,
  );
  if (__mmWall != null) return __mmWall;
  const __mmUtilityNames = [
    "turret",
    "teleporter",
    "boost pad",
    "platform",
    "healing pad",
    "blocker",
    "spawn pad",
    "sapling",
    "mine",
  ];
  for (
    let __mmNameIndex = 0;
    __mmNameIndex < __mmUtilityNames.length;
    __mmNameIndex++
  ) {
    const __mmName = __mmUtilityNames[__mmNameIndex],
      __mmItem = __mmAffordableBuildItem(
        (__mmData) => __mmData.name === __mmName,
      );
    if (__mmItem != null) return __mmItem;
  }
  return null;
}
function __mmTrapEmergencyBuildPlan(__mmTrap) {
  if (!v || !v.alive) return [];
  const __mmEnemy = __mmNearestEnemy(),
    __mmThreatAngle =
      __mmEnemy &&
      Math.hypot(Number(__mmEnemy.x) - v.x, Number(__mmEnemy.y) - v.y) <= 450
        ? Math.atan2(Number(__mmEnemy.y) - v.y, Number(__mmEnemy.x) - v.x)
        : Ci(),
    __mmBehind = __mmThreatAngle + Math.PI,
    __mmSpikeOverride = __mmTrapEmergencySpikePressure(__mmEnemy),
    // Trapped-enemy spike contact overrides the current build; otherwise use
    // the current placement type and default to Pit Trap while a weapon is
    // held. Remember that initial preference because the continuous breaker
    // necessarily switches back to a weapon afterward.
    __mmItem = __mmTrapEmergencyFallbackItem(
      __mmTrapBuildPreferredItem,
      __mmSpikeOverride,
    );
  if (__mmItem == null) return [];
  const __mmData = b && b.list && b.list[__mmItem],
    __mmScale = Number(__mmData && __mmData.scale) || 45,
    __mmRadius =
      (Number(v.scale) || 35) +
      __mmScale +
      (Number(__mmData && __mmData.placeOffset) || 0),
    __mmSpacing =
      2 *
        Math.asin(
          Math.min(0.999, (2 * __mmScale + 1) / (2 * __mmRadius)),
        ) +
      0.025,
    __mmCount = Math.min(
      Math.max(0, 2 - __mmTrapBuildPlacedCount),
      __mmMaxBuildCount(__mmItem),
    );
  return __mmCount <= 1
    ? [{ item: __mmItem, angle: __mmBehind }]
    : [
        { item: __mmItem, angle: __mmBehind - __mmSpacing / 2 },
        { item: __mmItem, angle: __mmBehind + __mmSpacing / 2 },
      ];
}
function __mmRememberTrapSpikeReplaceSlot(__mmEntry, __mmTrapKey) {
  if (
    !__mmAutoSpikeReplaceEnabled ||
    !__mmEntry ||
    !v ||
    !v.alive ||
    !b ||
    !b.list
  )
    return;
  const __mmData = b.list[__mmEntry.item];
  if (!__mmData || !__mmData.trap) return;
  const __mmScale = Number(__mmData.scale) || 50,
    __mmDistance =
      (Number(v.scale) || 35) +
      __mmScale +
      (Number(__mmData.placeOffset) || 0);
  __mmTrapSpikeReplaceSlot = {
    trapKey: __mmTrapKey,
    angle: __mmEntry.angle,
    x: Number(v.x) + Math.cos(__mmEntry.angle) * __mmDistance,
    y: Number(v.y) + Math.sin(__mmEntry.angle) * __mmDistance,
    scale: __mmScale,
    rememberedAt: Date.now(),
    seenBlockingTrap: !1,
  };
}
function __mmTrapSpikeReplaceBlocker(__mmSlot) {
  if (!__mmSlot) return null;
  let __mmClosest = null,
    __mmClosestDistance = Infinity;
  const __mmTraps = __mmActiveObjectSnapshot().traps;
  for (let __mmIndex = 0; __mmIndex < __mmTraps.length; __mmIndex++) {
    const __mmObject = __mmTraps[__mmIndex];
    if (
      !__mmObject ||
      !__mmObject.active ||
      !__mmObject.trap ||
      !__mmFriendlyStructure(__mmObject)
    )
      continue;
    const __mmDistance = Math.hypot(
      Number(__mmObject.x) - __mmSlot.x,
      Number(__mmObject.y) - __mmSlot.y,
    );
    if (
      __mmDistance <= Math.max(24, __mmSlot.scale * 0.75) &&
      __mmDistance < __mmClosestDistance
    )
      ((__mmClosest = __mmObject), (__mmClosestDistance = __mmDistance));
  }
  return __mmClosest;
}
function __mmUpdateTrapSpikeReplace(__mmCurrentTrap) {
  const __mmSlot = __mmTrapSpikeReplaceSlot;
  if (
    !__mmAutoSpikeReplaceEnabled ||
    __mmEmergencyGetawayActive() ||
    !__mmSlot ||
    !v ||
    !v.alive ||
    !__mmIsTrapped() ||
    __mmInsta.isActive()
  )
    return;
  if (
    __mmCurrentTrap &&
    __mmSlot.trapKey != null &&
    __mmTrapBuildKey(__mmCurrentTrap) !== __mmSlot.trapKey
  )
    return void (__mmTrapSpikeReplaceSlot = null);
  const __mmBlocker = __mmTrapSpikeReplaceBlocker(__mmSlot);
  if (__mmBlocker) {
    (__mmSlot.seenBlockingTrap = !0,
      (__mmSlot.x = Number(__mmBlocker.x)),
      (__mmSlot.y = Number(__mmBlocker.y)),
      (__mmSlot.scale = Number(__mmBlocker.scale) || __mmSlot.scale));
    return;
  }
  // Wait until the rear trap has genuinely appeared once. This prevents a
  // rejected trap packet from being mistaken for an opened replacement slot.
  if (!__mmSlot.seenBlockingTrap) return;
  const __mmNow = Date.now(),
    __mmSpike = __mmSpikeItem();
  if (
    __mmNow - __mmTrapSpikeReplaceLastAt < __mmFastCheckMs() ||
    __mmHoldingMcGrabby() ||
    !__mmAutoSpikeSpamHasCapacity(__mmSpike)
  )
    return;
  const __mmData = b && b.list && b.list[__mmSpike];
  if (!__mmData) return;
  const __mmAngle = Math.atan2(__mmSlot.y - v.y, __mmSlot.x - v.x),
    __mmScale = Number(__mmData.scale) || 49,
    __mmDistance =
      (Number(v.scale) || 35) +
      __mmScale +
      (Number(__mmData.placeOffset) || 0),
    __mmX = Number(v.x) + Math.cos(__mmAngle) * __mmDistance,
    __mmY = Number(v.y) + Math.sin(__mmAngle) * __mmDistance;
  if (!__mmAutoSpikeSpamPositionClear(__mmX, __mmY, __mmScale)) return;
  const __mmWeapon = __mmTrapAttackHeldWeapon || __mmSelectedWeapon(),
    __mmRestore = __mmWeapon == null
      ? __mmSelectedTool()
      : { item: __mmWeapon, weapon: !0 };
  if (!__mmSendAutomaticPlacement(__mmSpike, __mmAngle, __mmRestore)) return;
  (
    __mmAutoSpikeSpamReservations.push({
      item: __mmSpike,
      x: __mmX,
      y: __mmY,
      scale: __mmScale,
      expiresAt: __mmNow + 650,
    }),
    (__mmTrapSpikeReplaceLastAt = __mmNow),
    (__mmTrapSpikeReplaceSlot = null),
    __mmScheduleMouseAimReturn());
}
function __mmStopTrapBuildEscape(__mmClearAttempt = !0) {
  const __mmWeapon = __mmTrapAttackActive
    ? __mmTrapAttackHeldWeapon || __mmTrapBreakWeapon(__mmCurrentNearbyTrap())
    : __mmTrapBuildWeapon;
  ((__mmTrapBuildTimer && clearTimeout(__mmTrapBuildTimer),
    (__mmTrapBuildTimer = 0),
    (__mmTrapBuildWeapon = null),
    __mmClearAttempt && (__mmTrapBuildAttemptKey = null),
    !__mmIsTrapped() &&
      ((__mmTrapBuildPreferredItem = null),
      (__mmTrapBuildPlacedKey = null),
      (__mmTrapBuildPlacedCount = 0)),
    __mmWeapon != null && __mmRestoreWeapon(__mmWeapon)));
}
function __mmStartTrapBuildEscape(__mmTrap) {
  if (!v || !v.alive || !__mmIsTrapped() || __mmTrapBuildTimer) return;
  const __mmNow = Date.now(),
    __mmTrapKey = __mmTrap ? __mmTrapBuildKey(__mmTrap) : "locked";
  if (__mmTrapKey !== __mmTrapBuildPlacedKey) {
    ((__mmTrapBuildPlacedKey = __mmTrapKey),
      (__mmTrapBuildPlacedCount = 0),
      (__mmTrapBuildPreferredItem = __mmTrapEmergencyHeldPreference()));
  }
  if (
    __mmTrapKey == null ||
    __mmTrapBuildPlacedCount >= 2 ||
    (__mmTrapBuildAttemptKey === __mmTrapKey &&
      __mmNow - __mmTrapBuildLastAt < Math.max(90, __mmServerTickMs()))
  )
    return;
  const __mmPlan = __mmTrapEmergencyBuildPlan(__mmTrap);
  ((__mmTrapBuildAttemptKey = __mmTrapKey),
    (__mmTrapBuildLastAt = __mmNow));
  if (!__mmPlan.length) return;
  const __mmCandidates = [];
  for (let __mmIndex = 0; __mmIndex < __mmPlan.length; __mmIndex++) {
    const __mmEntry = __mmPlan[__mmIndex],
      // A blocked exact rear slot should not permanently disable emergency
      // placement. Search the neighboring rear arc and retry on later ticks.
      __mmCandidate = __mmSmartNearestLegalCandidate(
        __mmEntry.item,
        __mmEntry.angle,
        0.72,
        0.03,
      );
    if (!__mmCandidate) continue;
    __mmCandidate.points = 10 - __mmIndex * 0.01;
    if (
      __mmCandidates.some(function (__mmExisting) {
        return (
          Math.hypot(
            __mmExisting.x - __mmCandidate.x,
            __mmExisting.y - __mmCandidate.y,
          ) <
          __mmExisting.scale + __mmCandidate.scale
        );
      })
    )
      continue;
    __mmCandidates.push(__mmCandidate);
  }
  if (!__mmCandidates.length) return;
  __mmTrapBuildWeapon = __mmSelectedWeapon();
  const __mmRestore =
      __mmTrapBuildWeapon == null
        ? __mmSelectedTool()
        : { item: __mmTrapBuildWeapon, weapon: !0 },
    __mmPlaced = __mmSmartPlaceBurst(__mmCandidates, __mmRestore);
  __mmPlaced > 0 &&
    (__mmTrapBuildPlacedCount = Math.min(
      2,
      __mmTrapBuildPlacedCount + __mmPlaced,
    ));
  if (__mmPlaced > 0)
    for (
      let __mmIndex = 0;
      __mmIndex < Math.min(__mmPlaced, __mmCandidates.length);
      __mmIndex++
    )
      __mmRememberTrapSpikeReplaceSlot(
        __mmCandidates[__mmIndex],
        __mmTrapKey,
      );
  __mmTrapBuildWeapon = null;
}
function __mmEquipTankForTrap() {
  if (!v || !v.alive || !v.skins || !v.skins[40] || __mmRightClickHat != null)
    return !1;
  __mmTrapHat == null && (__mmTrapHat = __mmBestPostCombatHat());
  return __mmActivateCombatHat(40);
}
function __mmEquipTrapDowntimeHat() {
  if (
    !v ||
    !v.alive ||
    __mmTrapHat == null ||
    __mmRightClickHat != null ||
    __mmCombatHatLockActive()
  )
    return;
  const __mmHat = __mmBestPostCombatHat();
  __mmEquipHatNow(__mmHat, !0);
}
function __mmUpdateTrapEscapeGear(__mmWeapon) {
  if (!__mmTrapAttackActive || !v || !v.alive || __mmWeapon == null) return;
  __mmTrapHat == null &&
    (__mmTrapHat = __mmInstaSafeRestoreHat(
      __mmBushRestoreHat(v.skinIndex),
    ));
  if (!v.skins || !v.skins[40] || __mmRightClickHat != null) return;
  const __mmNow = Date.now();
  Number(__mmTrapAttackHeldWeapon) !== Number(__mmWeapon) &&
    (__mmTrapManualReadyAt = 0);
  const __mmSwingReady = __mmManualWeaponArming(
    __mmWeapon,
    __mmTrapManualReadyAt,
    __mmNow,
  );
  if (__mmSwingReady) {
    __mmEquipTankForTrap() &&
      (__mmTrapManualReadyAt =
        __mmNow + __mmManualWeaponCooldown(__mmWeapon, 40));
    return;
  }
  __mmEquipTrapDowntimeHat();
}
function __mmObserveTrapEscapeSwing(__mmPlayerSid, __mmWeapon) {
  const __mmResolvedWeapon =
    __mmWeapon == null ? Number(v && v.weaponIndex) : Number(__mmWeapon);
  if (
    !v ||
    !v.alive ||
    !__mmTrapAttackActive ||
    String(__mmPlayerSid) !== String(v.sid) ||
    (__mmTrapAttackHeldWeapon != null &&
      __mmResolvedWeapon !== Number(__mmTrapAttackHeldWeapon))
  )
    return;
  __mmTrapManualReadyAt =
    Date.now() + __mmManualWeaponCooldown(__mmResolvedWeapon, 40);
}
function __mmCancelTrapHatRestoreTimer() {
  (__mmTrapHatRestoreTimer && clearTimeout(__mmTrapHatRestoreTimer),
    (__mmTrapHatRestoreTimer = 0));
}
function __mmScheduleTrapHatRestore() {
  __mmCancelTrapHatRestoreTimer();
  __mmTrapHatRestoreTimer = setTimeout(function () {
    ((__mmTrapHatRestoreTimer = 0), __mmRestoreTrapHat());
  }, __mmServerTickMs());
}
function __mmRestoreTrapHat() {
  __mmCancelTrapHatRestoreTimer();
  if (__mmTrapHat == null) return;
  if (!v || !v.alive) {
    ((__mmTrapHat = null), (__mmTrapHatRestoreAttempts = 0));
    return;
  }
  if (
    __mmTrapAttackActive ||
    __mmPrimaryHeld ||
    __mmSecondaryHeld ||
    __mmRightClickHat != null ||
    __mmInsta.isActive() ||
    __mmInstaSyncPending ||
    __mmInstaSyncFiring ||
    __mmBoostBreakHeld ||
    __mmCombatHatLockActive() ||
    (__mmActionOwner !== "idle" && __mmActionOwner !== "trapEscape")
  )
    return void __mmScheduleTrapHatRestore();
  const __mmHat = __mmBestPostCombatHat(),
    __mmPendingConflict = !!(
      __mmPendingHat != null &&
      __mmPendingHat !== __mmHat &&
      Date.now() - __mmPendingHatAt < __mmGearHoldMs()
    );
  if (v.skinIndex === __mmHat && !__mmPendingConflict) {
    ((__mmPendingHat === __mmHat &&
      ((__mmPendingHat = null), (__mmPendingHatAt = 0))),
      (__mmTrapHat = null),
      (__mmTrapHatRestoreAttempts = 0));
    return;
  }
  (__mmCanEquipHat(__mmHat) && __mmEquipHatNow(__mmHat, !0),
    (__mmTrapHatRestoreAttempts += 1));
  if (__mmTrapHatRestoreAttempts < 6)
    return void __mmScheduleTrapHatRestore();
  ((__mmTrapHat = null), (__mmTrapHatRestoreAttempts = 0));
}
function __mmStopTrapAttack() {
  const __mmRestore = __mmActionMayRestore("trapEscape"),
    __mmReleaseAngle = Number.isFinite(__mmTrapAimAngle)
      ? __mmTrapAimAngle
      : Ci();
  (__mmTrapResumeTimer && clearTimeout(__mmTrapResumeTimer),
    (__mmTrapResumeTimer = 0),
    __mmStopTrapBuildEscape(),
    __mmTrapAttackHeld && O.send("F", 0, __mmReleaseAngle),
    (__mmTrapAttackHeld = !1),
    (__mmTrapAttackHeldWeapon = null),
    (__mmTrapAttackTargetKey = null),
    (__mmTrapManualReadyAt = 0),
    (__mmTrapWeaponSelectAt = 0),
    __mmTrapAttackActive &&
      ((__mmTrapAttackActive = !1),
      __mmRestore && __mmRestoreWeapon(__mmTrapWeapon),
      (__mmTrapWeapon = null)),
    (__mmTrapAimAngle = null),
    (__mmTrapSpikeReplaceSlot = null),
    __mmRestoreTrapHat(),
    __mmActionRelease("trapEscape", "trap clear"));
}
function __mmPauseSoldierForBreaking() {
  __mmCancelSoldierRestore();
  if (__mmSoldierPreviousHat == null || !v || !v.alive || v.skinIndex !== 6)
    return;
  const __mmPreviousHat = __mmSoldierPreviousHat;
  ((__mmSoldierPreviousHat = null),
    __mmCanEquipHat(__mmPreviousHat) && __mmEquipHatNow(__mmPreviousHat));
}
function __mmTrapWeaponRange(__mmWeapon, __mmTrap) {
  const __mmData = b && b.weapons && b.weapons[__mmWeapon];
  if (!__mmData || __mmData.projectile != null) return 0;
  return (
    (Number(__mmData.range) || 0) +
    (v.scale || 35) +
    (__mmTrap.scale || 35) +
    8
  );
}
function __mmTrapBreakWeapon(__mmTrap) {
  if (!v || !v.weapons || !__mmTrap) return null;
  const __mmCandidates = [
    __mmGreatHammer,
    v.weapons[0],
    v.weapons[1],
  ];
  const __mmDistance = Math.hypot(__mmTrap.x - v.x, __mmTrap.y - v.y);
  for (
    let __mmIndex = 0;
    __mmIndex < __mmCandidates.length;
    __mmIndex += 1
  ) {
    const __mmWeapon = __mmCandidates[__mmIndex];
    if (
      __mmWeapon == null ||
      !v.weapons.includes(__mmWeapon) ||
      __mmDistance > __mmTrapWeaponRange(__mmWeapon, __mmTrap)
    )
      continue;
    return __mmWeapon;
  }
  return null;
}
function __mmTrapEscapeLethalSpike(__mmTrap) {
  if (!v || !v.alive || !__mmTrap || !__mmTrap.active) return null;
  const __mmThreat = __mmCombatThreatSnapshot(),
    // Trap escape is safety critical, so bypass the general FPS snapshot's
    // short cache while caught. This sees a newly placed adjacent spike on the
    // next reaction scan without making normal-world rendering more expensive.
    __mmSpikes = __mmActiveObjectSnapshot(!0).spikes,
    __mmHealth = Math.max(0, Number(v.health) || 0),
    __mmBaseThreatDamage = Math.max(
      0,
      Number(__mmThreat.damage) - Number(__mmThreat.spikeDamage),
    ),
    __mmPotentialDamage = Math.max(
      Number(__mmThreat.potentialDamage) || 0,
      __mmBaseThreatDamage,
    ),
    __mmTrapScale = __mmThreatObjectScale(__mmTrap),
    __mmPlayerScale = Number(v.scale) || 35;
  let __mmBest = null,
    __mmBestScore = Infinity;
  for (let __mmIndex = 0; __mmIndex < __mmSpikes.length; __mmIndex++) {
    const __mmSpike = __mmSpikes[__mmIndex];
    if (!__mmSpike || !__mmSpike.active) continue;
    const __mmDamage =
        __mmAutoSpikeKillDamage(__mmSpike) *
        __mmThreatIncomingDamageMultiplier(),
      __mmSpikeScale = __mmThreatObjectScale(__mmSpike),
      __mmPlayerDistance = Math.hypot(__mmSpike.x - v.x, __mmSpike.y - v.y),
      __mmTrapDistance = Math.hypot(
        __mmSpike.x - __mmTrap.x,
        __mmSpike.y - __mmTrap.y,
      ),
      __mmPredictedLethal =
        __mmSpike === __mmThreat.lethalSpike ||
        __mmPotentialDamage + __mmDamage + 0.001 >= __mmHealth,
      __mmReachableWeapon = __mmTrapBreakWeapon(__mmSpike);
    if (
      __mmDamage <= 0 ||
      __mmFriendlyStructure(__mmSpike) ||
      !__mmPredictedLethal ||
      __mmReachableWeapon == null ||
      __mmPlayerDistance > __mmPlayerScale + __mmSpikeScale + 145 ||
      __mmTrapDistance > __mmTrapScale + __mmSpikeScale + 95
    )
      continue;
    const __mmScore =
      __mmPlayerDistance * 2 +
      __mmTrapDistance -
      __mmDamage * 4 -
      (__mmSpike === __mmThreat.lethalSpike ? 500 : 0);
    if (__mmScore < __mmBestScore)
      ((__mmBestScore = __mmScore), (__mmBest = __mmSpike));
  }
  return __mmBest;
}
function __mmTrapEscapeBreakTarget(__mmTrap) {
  return __mmTrapEscapeLethalSpike(__mmTrap) || __mmTrap;
}
function __mmTryAntiRetrapPush(__mmTrap) {
  if (
    !__mmAntiRetrapPushEnabled ||
    __mmAntiRetrapReleaseTimer ||
    !v ||
    !v.alive ||
    !__mmTrap ||
    !v.weapons ||
    !v.weapons.includes(__mmGreatHammer) ||
    !__mmWeaponReady(__mmGreatHammer) ||
    Date.now() - __mmAntiRetrapLastAt < __mmServerTickMs()
  )
    return !1;
  const __mmTrapState = __mmBreakableState(__mmTrap),
    __mmTrapHealth = Number(
      __mmTrapState ? __mmTrapState.health : __mmTrap.health,
    ),
    __mmHammerDamage = __mmWeaponStructureDamage(
      v,
      __mmGreatHammer,
      __mmTrap,
    ),
    __mmEnemy = __mmNearestEnemy(),
    __mmPrimary = v.weapons[0],
    __mmPrimaryData = b && b.weapons && b.weapons[__mmPrimary];
  if (
    !__mmEnemy ||
    __mmPrimary == null ||
    !__mmPrimaryData ||
    __mmPrimaryData.projectile != null ||
    !__mmWeaponReady(__mmPrimary) ||
    !Number.isFinite(__mmTrapHealth) ||
    __mmTrapHealth > __mmHammerDamage + 0.001
  )
    return !1;
  const __mmDistance = Math.hypot(__mmEnemy.x - v.x, __mmEnemy.y - v.y),
    __mmRange =
      (Number(__mmPrimaryData.range) || 0) +
      (Number(v.scale) || 35) +
      (Number(__mmEnemy.scale) || 35) +
      8;
  if (__mmDistance > __mmRange) return !1;
  const __mmAngle = Math.atan2(__mmEnemy.y - v.y, __mmEnemy.x - v.x);
  try {
    (__mmTrapAttackHeld && O.send("F", 0, __mmTrapAimAngle),
      (__mmTrapAttackHeld = !1),
      (__mmTrapAttackHeldWeapon = null),
      (__mmTrapAttackTargetKey = null),
      __mmInsta.turretReady() &&
        (__mmActivateCombatHat(__mmTurretGear), __mmAssumeTurretGearShot()),
      O.send("D", __mmAngle),
      je(__mmPrimary, !0),
      O.send("F", 1, __mmAngle),
      (__mmAntiRetrapLastAt = Date.now()));
  } catch (__mmAntiRetrapError) {
    return !1;
  }
  __mmAntiRetrapReleaseTimer = setTimeout(function () {
    ((__mmAntiRetrapReleaseTimer = 0),
      v && v.alive && O.send("F", 0, __mmAngle),
      (__mmTrapAttackHeld = !1),
      (__mmTrapAttackHeldWeapon = null),
      (__mmTrapAttackTargetKey = null),
      (__mmTrapWeaponSelectAt = 0),
      __mmBreakTrap());
  }, __mmServerTickMs());
  return !0;
}
function __mmFriendlyPlayerTrapRescueTarget() {
  if (!v || !v.alive || !Array.isArray(E)) return null;
  const __mmTraps = __mmActiveTrapObjects();
  let __mmBest = null,
    __mmBestDistance = Infinity;
  for (let __mmPlayerIndex = 0; __mmPlayerIndex < E.length; __mmPlayerIndex++) {
    const __mmPlayer = E[__mmPlayerIndex];
    if (
      !__mmPlayer ||
      __mmPlayer === v ||
      __mmPlayer.alive === !1 ||
      (!__mmSameTeam(__mmPlayer) && !__mmIsFriendPlayer(__mmPlayer))
    )
      continue;
    for (let __mmTrapIndex = 0; __mmTrapIndex < __mmTraps.length; __mmTrapIndex++) {
      const __mmTrap = __mmTraps[__mmTrapIndex];
      if (!__mmServerTrapContact(__mmPlayer, __mmTrap)) continue;
      const __mmDistance = Math.hypot(__mmTrap.x - v.x, __mmTrap.y - v.y);
      if (
        __mmDistance <= __mmTrapWeaponRange(__mmGreatHammer, __mmTrap) &&
        __mmDistance < __mmBestDistance
      )
        ((__mmBestDistance = __mmDistance),
          (__mmBest = { player: __mmPlayer, trap: __mmTrap }));
    }
  }
  return __mmBest;
}
function __mmStopTeammateRescue(__mmReason) {
  const __mmAngle = __mmTeammateRescueAngle,
    __mmRestore = __mmTeammateRescueRestoreTool,
    __mmMayRestore = __mmActionMayRestore("teammateRescue");
  (__mmTeammateRescueReleaseTimer &&
    clearTimeout(__mmTeammateRescueReleaseTimer),
    (__mmTeammateRescueReleaseTimer = 0),
    __mmAngle != null && v && v.alive && O.send("F", 0, __mmAngle),
    __mmMayRestore && __mmRestore != null && __mmRestoreTool(__mmRestore),
    (__mmTeammateRescueAngle = null),
    (__mmTeammateRescueRestoreTool = null),
    __mmActionRelease(
      "teammateRescue",
      __mmReason || "rescue swing sent",
    ),
    __mmScheduleMouseAimReturn());
}
function __mmUpdateTeammateTrapRescue() {
  if (
    !__mmTeammateTrapRescueEnabled ||
    __mmTeammateRescueReleaseTimer ||
    !v ||
    !v.alive ||
    !v.weapons ||
    !v.weapons.includes(__mmGreatHammer) ||
    !__mmWeaponReady(__mmGreatHammer) ||
    __mmIsTrapped() ||
    __mmInsta.isActive() ||
    __mmBoostInsta.isActive() ||
    __mmPrimaryHeld ||
    __mmSecondaryHeld ||
    Date.now() - __mmTeammateRescueLastAt < __mmServerTickMs() ||
    !__mmActionCanPreempt("teammateRescue")
  )
    return;
  const __mmTarget = __mmFriendlyPlayerTrapRescueTarget();
  if (
    !__mmTarget ||
    !__mmActionClaim("teammateRescue", "friendly player trapped")
  )
    return;
  const __mmAngle = Math.atan2(
      __mmTarget.trap.y - v.y,
      __mmTarget.trap.x - v.x,
    ),
    __mmRestore = __mmSelectedTool();
  try {
    (__mmActivateCombatHat(40),
      O.send("D", __mmAngle),
      je(__mmGreatHammer, !0),
      O.send("F", 1, __mmAngle),
      (__mmTeammateRescueAngle = __mmAngle),
      (__mmTeammateRescueRestoreTool = __mmRestore),
      (__mmTeammateRescueLastAt = Date.now()));
  } catch (__mmTeammateRescueError) {
    ((__mmTeammateRescueAngle = __mmAngle),
      (__mmTeammateRescueRestoreTool = __mmRestore),
      __mmStopTeammateRescue("rescue packet failed"));
    return;
  }
  __mmTeammateRescueReleaseTimer = setTimeout(function () {
    __mmStopTeammateRescue("rescue swing sent");
  }, __mmServerTickMs());
}
function __mmStartTeammateTrapRescue() {
  __mmEnsureOperationPipeline();
}
function __mmBreakTrap() {
  if (
    !__mmTrapEscapeEnabled ||
    !v ||
    !v.alive ||
    !__mmIsTrapped()
  )
    return void __mmStopTrapAttack();
  // The insta owns the same weapon, hat, and aim channels for only a few
  // ticks. Leave the trap interval alive but idle until cleanup hands control
  // back, instead of cancelling the combo on its next fast scan.
  if (__mmInsta.isActive()) return;
  // Being genuinely trapped is still a safety priority; an idle trap-escape
  // interval must not otherwise terminate every R insta burst.
  if (!__mmActionCanPreempt("trapEscape")) return;
  const __mmTrapRestoreHat =
    __mmPrimaryClickHat != null
      ? __mmPrimaryClickHat
      : __mmRightClickHat != null
        ? __mmRightClickHat
        : __mmSoldierPreviousHat != null
          ? __mmSoldierPreviousHat
          : __mmInstaSafeRestoreHat(__mmBushRestoreHat(v.skinIndex));
  if (__mmInsta.isActive()) __mmInsta.cancel("trap-escape");
  (__mmInstaSyncPending || __mmInstaSyncFiring) && __mmStopInstaSync();
  __mmBoostBreakHeld && __mmStopBoostBreak();
  __mmActionOwner === "shieldDefense" && __mmStopShieldDefense("trap priority");
  __mmPrimaryHeld && __mmStopPrimaryInput();
  (__mmPrimaryClickHat != null || __mmPrimaryClickTail != null) &&
    __mmForceRestoreBullForPrimary();
  __mmSecondaryHeld && __mmStopSecondary();
  __mmRightClickHat != null && __mmForceRestoreRightClickHat();
  __mmActionOwner === "weaponRecharge" && __mmPauseWeaponRecharge(!0);
  if (__mmActionOwner === "antiInsta") {
    (__mmAntiInstaActionTimer && clearTimeout(__mmAntiInstaActionTimer),
      (__mmAntiInstaActionTimer = 0),
      __mmActionRelease("antiInsta", "trap priority"));
  }
  if (!__mmActionClaim("trapEscape", "locked pit trap")) return;
  __mmAutoHeal(!0);
  const __mmTrap = __mmCurrentNearbyTrap();
  if (__mmTrap == null) return;
  // Emergency rear placement borrows this trap-escape phase, then restores
  // the breaker before its continuous attack is armed below.
  __mmStartTrapBuildEscape(__mmTrap);
  if (__mmTryAntiRetrapPush(__mmTrap)) return;
  const __mmBreakTarget = __mmTrapEscapeBreakTarget(__mmTrap),
    __mmBreakingSpike = __mmBreakTarget !== __mmTrap,
    __mmTargetKey =
      (__mmBreakingSpike ? "spike:" : "trap:") +
      String(
        __mmBreakTarget.sid == null
          ? __mmBreakTarget.x + ":" + __mmBreakTarget.y
          : __mmBreakTarget.sid,
      ),
    __mmAngle = Math.atan2(
      __mmBreakTarget.y - v.y,
      __mmBreakTarget.x - v.x,
    );
  __mmActionClaim(
    "trapEscape",
    __mmBreakingSpike ? "lethal adjacent spike" : "locked pit trap",
  );
  (__mmTrapAttackActive ||
    (__mmCancelTrapHatRestoreTimer(),
    (__mmTrapHatRestoreAttempts = 0),
    __mmPauseSoldierForBreaking(),
    (__mmTrapAttackActive = !0),
    (__mmTrapWeapon = __mmSelectedWeapon()),
    (__mmTrapHat == null && (__mmTrapHat = __mmTrapRestoreHat))));
  // Lock the normal aim source onto the selected break target. When the lethal
  // spike disappears, the target key changes and the same continuous breaker
  // is re-armed toward the pit without waiting for a fresh input.
  __mmTrapAimAngle = __mmAngle;
  const __mmWeapon = __mmTrapBreakWeapon(__mmBreakTarget);
  if (__mmWeapon == null) return;
  __mmUpdateTrapEscapeGear(__mmWeapon);
  if (
    !__mmTrapAttackHeld ||
    __mmTrapAttackHeldWeapon !== __mmWeapon ||
    __mmTrapAttackTargetKey !== __mmTargetKey
  ) {
    (__mmTrapAttackHeld && O.send("F", 0, __mmAngle),
      je(__mmWeapon, !0),
      O.send("D", __mmAngle),
      O.send("F", 1, __mmAngle),
      (__mmTrapAttackHeld = !0),
      (__mmTrapAttackHeldWeapon = __mmWeapon),
      (__mmTrapAttackTargetKey = __mmTargetKey),
      (__mmTrapWeaponSelectAt = Date.now()));
  } else if (
    (Number(v.buildIndex) >= 0 || Number(v.weaponIndex) !== Number(__mmWeapon)) &&
    Date.now() - __mmTrapWeaponSelectAt >= 25
  )
    ((__mmTrapWeaponSelectAt = Date.now()), je(__mmWeapon, !0));
}
function __mmStartTrapEscape() {
  __mmEnsureOperationPipeline();
}
function __mmQueueTrapEscapeResume(__mmEvent) {
  if (
    (__mmEvent && __mmEvent.isTrusted === !1) ||
    !__mmTrapEscapeEnabled ||
    !v ||
    !v.alive ||
    !__mmIsTrapped()
  )
    return;
  __mmTrapResumeTimer && clearTimeout(__mmTrapResumeTimer);
  __mmTrapResumeTimer = setTimeout(function () {
    __mmTrapResumeTimer = 0;
    if (!__mmTrapEscapeEnabled || !v || !v.alive || !__mmIsTrapped()) return;
    // User input may have emitted attack-up or changed tools after the escape
    // loop set this latch. Invalidate it and issue a fresh continuous hold now
    // that the input event has completely finished propagating.
    ((__mmTrapAttackHeld = !1),
      (__mmTrapAttackHeldWeapon = null),
      (__mmTrapAttackTargetKey = null),
      (__mmTrapWeaponSelectAt = 0),
      __mmBreakTrap());
  }, 0);
}
document.addEventListener("mouseup", __mmQueueTrapEscapeResume, !0);
document.addEventListener("pointerup", __mmQueueTrapEscapeResume, !0);
document.addEventListener("touchend", __mmQueueTrapEscapeResume, !0);
document.addEventListener("keyup", __mmQueueTrapEscapeResume, !0);
function __mmWithinTrapAlertRange(__mmTrap) {
  return __mmPlayerCenterTouchesEnemyTrap(__mmTrap);
}
function __mmUpdateTrapAlert() {
  const __mmNearbyTrap = v && v.alive ? __mmCurrentNearbyTrap() : null;
  // Only the local player's center entering the enemy trap's hitbox counts as
  // caught. A server movement lock alone is intentionally not trap evidence.
  const __mmIncident = !!(
    v &&
    v.alive &&
    __mmWithinTrapAlertRange(__mmNearbyTrap)
  );
  if (__mmIncident) {
    if (!__mmTrapChatIncidentActive) {
      (__mmTrapChatIncidentActive = !0,
        __mmTrapAlertChatEnabled && __mmSendChat("Oh no! A trap!"));
    }
  } else {
    __mmTrapChatIncidentActive = !1;
  }
  const __mmTrapped = __mmIncident;
  let __mmAlert = document.getElementById("kitty-klient-trap-alert");
  if (!__mmAlert && !__mmTrapped) return;
  if (!__mmAlert) {
    if (!document.body) return;
    ((__mmAlert = document.createElement("div")),
      (__mmAlert.id = "kitty-klient-trap-alert"),
      (__mmAlert.setAttribute("role", "status")),
      (__mmAlert.setAttribute("aria-live", "assertive")),
      (__mmAlert.style.cssText =
        "position:fixed;top:18%;left:50%;z-index:2147483647;transform:translate(-50%,-8px);max-width:min(560px,calc(100vw - 30px));box-sizing:border-box;padding:11px 18px;border:1px solid #ffb4b4;border-radius:11px;background:rgba(127,20,28,.92);color:#fff;font:800 18px/1.3 Arial,sans-serif;letter-spacing:.01em;text-align:center;text-shadow:0 0 7px rgba(255,180,180,.7);box-shadow:0 5px 22px rgba(0,0,0,.4),0 0 16px rgba(239,68,68,.28);pointer-events:none;opacity:0;transition:opacity .12s ease,transform .12s ease;"),
      document.body.appendChild(__mmAlert));
  }
  (__mmAlert.textContent = "Oh no! A trap!"),
    (__mmAlert.style.opacity = __mmTrapped ? "1" : "0"),
    (__mmAlert.style.transform = __mmTrapped
      ? "translate(-50%,0)"
      : "translate(-50%,-8px)");
}
function __mmStartTrapAlert() {
  __mmTrapAlertTimer ||
    (__mmTrapAlertTimer = setInterval(__mmUpdateTrapAlert, __mmFastCheckMs()));
}
function __mmStopTrapEscape() {
  (__mmTrapAttackTimer &&
    (clearInterval(__mmTrapAttackTimer), (__mmTrapAttackTimer = 0)),
    __mmStopTrapAttack());
}
function __mmCanAutoSoldier() {
  return (
    __mmSoldierAutoEnabled &&
    !__mmAssassinConcealed &&
    !__mmCombatHatLockActive() &&
    __mmActionAvailable("soldierGear") &&
    v &&
    v.alive &&
    v.skinIndex !== 40 &&
    v.skins &&
    v.skins[6] &&
    !__mmSyncFollowerEnabled &&
    !__mmBushModeEnabled &&
    !__mmInsta.isActive() &&
    !__mmMovementGearActive() &&
    !__mmPlayerMoving() &&
    !__mmPrimaryHeld &&
    !__mmSecondaryHeld &&
    !__mmTrapAttackActive &&
    !__mmBoostBreakHeld &&
    __mmPrimaryClickHat == null &&
    __mmRightClickHat == null
  );
}
function __mmEnemyWithinSoldierRange() {
  if (!v || !v.alive) return !1;
  if (__mmLiveStateFresh())
    return __mmLiveState.nearestEnemyDistance <= __mmSoldierRange;
  for (let __mmPlayerIndex = 0; __mmPlayerIndex < E.length; __mmPlayerIndex++) {
    const __mmPlayer = E[__mmPlayerIndex];
    if (!__mmIsEnemyPlayer(__mmPlayer)) continue;
    const __mmDx = __mmPlayer.x - v.x,
      __mmDy = __mmPlayer.y - v.y;
    if (
      __mmDx * __mmDx + __mmDy * __mmDy <=
      __mmSoldierRange * __mmSoldierRange
    )
      return !0;
  }
  return !1;
}
function __mmCancelSoldierRestore() {
  __mmSoldierRestoreTimer &&
    (clearTimeout(__mmSoldierRestoreTimer), (__mmSoldierRestoreTimer = 0));
}
function __mmEquipSoldier() {
  if (!__mmCanAutoSoldier()) return;
  __mmCancelSoldierRestore();
  if (v.skinIndex !== 6) {
    (__mmSoldierPreviousHat == null &&
      (__mmSoldierPreviousHat = __mmInstaSafeRestoreHat(
        __mmBushRestoreHat(v.skinIndex),
      )),
      __mmEquipHatNow(6));
  }
}
function __mmRestoreSoldier() {
  if (!__mmCanAutoSoldier() || __mmSoldierPreviousHat == null) return;
  const __mmPreviousHat = __mmSoldierPreviousHat;
  __mmSoldierPreviousHat = null;
  v.skinIndex === 6 &&
    __mmPreviousHat !== 6 &&
    __mmCanEquipHat(__mmPreviousHat) &&
    __mmEquipHatNow(__mmPreviousHat);
}
function __mmUpdateSoldier() {
  __mmCanAutoSoldier() && __mmEquipSoldier();
}
function __mmStartSoldierAuto() {
  __mmEnsureOperationPipeline();
}
function __mmTurretGearCanFire(__mmPlayer) {
  return __mmPlayer.skinIndex === __mmTurretGear;
}
function __mmAiEnemySnapshot(__mmPlayer) {
  const __mmDx = __mmPlayer.x - v.x,
    __mmDy = __mmPlayer.y - v.y;
  return {
    distance: Math.round(Math.sqrt(__mmDx * __mmDx + __mmDy * __mmDy)),
    health: Number(__mmPlayer.health) || 0,
    maxHealth: Number(__mmPlayer.maxHealth) || 0,
    weapon: Number(__mmPlayer.weaponIndex) || 0,
    hat: Number(__mmPlayer.skinIndex) || 0,
    tail: Number(__mmPlayer.tailIndex) || 0,
    turretGear: __mmPlayer.skinIndex === __mmTurretGear,
  };
}
function __mmAiContext() {
  if (!v) return { available: !1 };
  const __mmEnemies = [];
  for (let __mmIndex = 0; __mmIndex < E.length; __mmIndex++) {
    const __mmPlayer = E[__mmIndex];
    if (
      !__mmPlayer ||
      !__mmPlayer.alive ||
      __mmPlayer === v ||
      __mmPlayer.sid === v.sid ||
      !__mmIsEnemyPlayer(__mmPlayer)
    )
      continue;
    __mmEnemies.push(__mmAiEnemySnapshot(__mmPlayer));
  }
  __mmEnemies.sort(function (__mmFirst, __mmSecond) {
    return __mmFirst.distance - __mmSecond.distance;
  });
  const __mmAngle = __mmTrapAngle();
  return {
    available: !0,
    modVersion: "3.15.0",
    player: {
      alive: !!v.alive,
      health: Number(v.health) || 0,
      maxHealth: Number(v.maxHealth) || 0,
      gold: Number(v.points) || 0,
      wood: Number(v.wood) || 0,
      food: Number(v.food) || 0,
      stone: Number(v.stone) || 0,
      weapons: Array.isArray(v.weapons) ? v.weapons.slice(0, 4) : [],
      selectedWeapon: __mmSelectedWeapon(),
      hat: Number(v.skinIndex) || 0,
      tail: Number(v.tailIndex) || 0,
      trapped: __mmIsTrapped(),
      foodItem: v.items ? v.items[0] : null,
    },
    nearbyEnemies: __mmEnemies.slice(0, 8),
    nearbyTrap: { detected: __mmAngle != null, angle: __mmAngle },
    features: { autoHeal: __mmAutoHealEnabled, soldierRange: __mmSoldierRange },
  };
}
function __mmPublishAiContext() {
  window.dispatchEvent(
    new CustomEvent("MooMooAIContext", { detail: __mmAiContext() }),
  );
}
window.addEventListener("MooMooAIRequestContext", __mmPublishAiContext);
function __mmCanUseShieldDefense() {
  return (
    __mmShieldDefenseEnabled &&
    __mmActionAvailable("shieldDefense") &&
    v &&
    v.alive &&
    v.weapons.includes(__mmShieldWeapon) &&
    !__mmInsta.isActive() &&
    !__mmPrimaryHeld &&
    !__mmSecondaryHeld &&
    !__mmTrapAttackActive
  );
}
function __mmStopShieldDefense(__mmReason) {
  const __mmWeapon = __mmShieldDefenseWeapon,
    __mmRestore = __mmActionMayRestore("shieldDefense");
  ((__mmShieldDefenseTimer && clearTimeout(__mmShieldDefenseTimer),
    (__mmShieldDefenseTimer = 0),
    (__mmShieldDefenseWeapon = null),
    __mmRestore &&
      !__mmPrimaryHeld &&
      !__mmSecondaryHeld &&
      !__mmTrapAttackActive &&
      __mmWeapon != null &&
      __mmWeapon !== __mmShieldWeapon &&
      __mmRestoreWeapon(__mmWeapon),
    __mmActionRelease("shieldDefense", __mmReason || "defense complete")));
}
function __mmUseShieldDefense(__mmPlayer) {
  if (!__mmCanUseShieldDefense()) return;
  const __mmDistance = (__mmPlayer.x - v.x) ** 2 + (__mmPlayer.y - v.y) ** 2;
  if (__mmDistance > __mmShieldDefenseRange * __mmShieldDefenseRange) return;
  if (!__mmActionClaim("shieldDefense", "polearm defense")) return;
  const __mmWeapon = __mmSelectedWeapon();
  (__mmShieldDefenseTimer && clearTimeout(__mmShieldDefenseTimer),
    __mmShieldDefenseWeapon == null && (__mmShieldDefenseWeapon = __mmWeapon),
    je(__mmShieldWeapon, !0),
    O.send("9", Math.atan2(__mmPlayer.y - v.y, __mmPlayer.x - v.x)),
    (__mmShieldDefenseTimer = setTimeout(function () {
      __mmStopShieldDefense("defense complete");
    }, __mmShieldDefenseMs)));
}
function __mmHandleEnemyPolearmSwing(__mmPlayerSid, __mmWeapon) {
  const __mmPlayer = Rt(__mmPlayerSid);
  if (
    !__mmIsEnemyPlayer(__mmPlayer) ||
    (__mmPlayer.weaponIndex !== __mmPolearmWeapon &&
      __mmWeapon !== __mmPolearmWeapon) ||
    !__mmTurretGearCanFire(__mmPlayer)
  )
    return;
  __mmUseShieldDefense(__mmPlayer);
}
window.addEventListener("blur", __mmStopFoodSpam);
window.addEventListener("blur", function () {
  __mmStopBuildSpam();
});
function __mmIsGameClick(__mmEvent) {
  return (
    __mmEvent.target instanceof Element &&
    __mmEvent.target.closest("#gameCanvas,#touch-controls-fullscreen")
  );
}
function __mmManualWeaponCooldown(__mmWeapon, __mmSwingHat = null) {
  const __mmData = b && b.weapons && b.weapons[__mmWeapon];
  const __mmEffective =
    __mmSwingHat == null
      ? 0
      : __mmToolCooldownDuration({ skinIndex: __mmSwingHat }, __mmWeapon);
  return Math.max(
    __mmServerTickMs(),
    Number(__mmEffective) ||
      Number(__mmData && __mmData.speed) ||
      __mmServerTickMs(),
  );
}
function __mmGearHoldMs() {
  return __mmServerTickMs() * Math.max(
    1,
    Math.min(8, Math.round(Number(__mmGearHoldTicks) || 3)),
  );
}
function __mmBullPrimaryAvailable() {
  return !!(
    __mmBullHelmetEnabled &&
    v &&
    v.alive &&
    v.weapons &&
    v.weapons[0] != null &&
    v.weapons[0] !== 8 &&
    v.skins &&
    v.skins[7] &&
    !__mmSecondaryHeld &&
    __mmRightClickHat == null
  );
}
function __mmPrimaryDamageTail() {
  if (!v || !v.alive) return null;
  if (v.tails && v.tails[__mmCorruptXWings]) {
    __mmPrimaryClickTail == null &&
      (__mmPrimaryClickTail = __mmBushRestoreTail(v.tailIndex));
    return __mmCorruptXWings;
  }
  if (__mmEffectiveTailIndex() === 11) {
    __mmPrimaryClickTail == null &&
      (__mmPrimaryClickTail = __mmBushRestoreTail(v.tailIndex));
    return 0;
  }
  return null;
}
function __mmClearPrimaryGearTimer() {
  (__mmPrimaryGearTimer && clearTimeout(__mmPrimaryGearTimer),
    (__mmPrimaryGearTimer = 0));
}
function __mmSchedulePrimaryGear(__mmCallback) {
  __mmClearPrimaryGearTimer();
  __mmPrimaryGearTimer = setTimeout(function () {
    (__mmPrimaryGearTimer = 0, __mmCallback());
  }, __mmServerTickMs());
}
function __mmManualWeaponArming(__mmWeapon, __mmReadyAt, __mmNow = Date.now()) {
  if (!v || !v.alive || __mmWeapon == null || __mmNow < __mmReadyAt) return !1;
  // A mouse-down is only intent. Both the server reload and Kitty's
  // actual-swing clock must be clear before any swing gear/timer is renewed.
  if (__mmWeaponIsReloading(__mmWeapon)) return !1;
  const __mmReload = v.reloads && Number(v.reloads[__mmWeapon]);
  return !Number.isFinite(__mmReload) || __mmReload <= __mmFastCheckMs();
}
function __mmSecondaryTankLead(__mmWeapon, __mmReadyAt, __mmNow = Date.now()) {
  return __mmManualWeaponArming(__mmWeapon, __mmReadyAt, __mmNow) ? 0 : -1;
}
function __mmEquipBullForPrimary(__mmNow = Date.now()) {
  if (!__mmBullPrimaryAvailable()) return !1;
  const __mmWeapon = v.weapons[0];
  (__mmClearPrimaryGearTimer(),
    (__mmPrimaryGearStage = "bull"),
    __mmPrimaryClickHat == null &&
      (__mmPrimaryClickHat = __mmBestPostCombatHat()),
    // This call and the F=1 press run in the same synchronous packet phase.
    __mmActivateCombatHat(7, __mmPrimaryDamageTail()),
    (__mmPrimaryManualWeapon = __mmWeapon),
    (__mmPrimaryManualReadyAt =
      __mmNow + __mmManualWeaponCooldown(__mmWeapon, 7)));
  return !0;
}
function __mmEquipPrimaryDowntimeHat() {
  if (!v || !v.alive || __mmCombatHatLockActive()) return;
  const __mmHat = __mmBestPostCombatHat(),
    __mmTail = __mmDesiredHeldTail(v.weapons && v.weapons[0]);
  (__mmClearPrimaryGearTimer(),
    (__mmPrimaryGearStage = "downtime"),
    __mmRememberHeldTail(__mmTail),
    __mmEquipGearPair(
      __mmHat,
      __mmTail == null ? __mmPrimaryClickTail : __mmTail,
      !0,
    ));
}
function __mmRestoreBullForPrimary() {
  if (__mmCombatHatLockActive() && Number(__mmCombatHatLockHat) === 7) {
    __mmScheduleCombatHatFinish();
    return;
  }
  if (__mmPrimaryHeld || __mmSecondaryHeld || __mmRightClickHat != null) return;
  if (!v || !v.alive) {
    (__mmClearPrimaryGearTimer(),
      (__mmPrimaryClickHat = null),
      (__mmPrimaryClickTail = null),
      (__mmPrimaryGearStage = null));
    return;
  }
  const __mmHat = __mmBestPostCombatHat(),
    __mmTail = __mmPrimaryClickTail;
  (__mmClearPrimaryGearTimer(),
    (__mmPrimaryClickHat = null),
    (__mmPrimaryClickTail = null),
    (__mmPrimaryGearStage = null),
    __mmEquipGearPair(__mmHat, __mmTail, !0));
}
function __mmForceRestoreBullForPrimary() {
  if (__mmPrimaryClickHat == null && __mmPrimaryClickTail == null) return;
  const __mmHat = __mmBestPostCombatHat(),
    __mmTail = __mmPrimaryClickTail;
  (__mmClearPrimaryGearTimer(),
    (__mmPrimaryClickHat = null),
    (__mmPrimaryClickTail = null),
    (__mmPrimaryGearStage = null),
    v &&
      v.alive &&
      !__mmCombatHatLockActive() &&
      __mmEquipGearPair(__mmHat, __mmTail, !0));
}
function __mmPulsePrimaryBullWeapon() {
  if (!__mmPrimaryHeld || !__mmBullPrimaryAvailable()) return;
  const __mmNow = Date.now(),
    __mmWeapon = v.weapons[0],
    __mmSwinging = __mmManualWeaponArming(
      __mmWeapon,
      __mmPrimaryManualReadyAt,
      __mmNow,
    );
  __mmSwinging && __mmEquipBullForPrimary(__mmNow);
  !__mmSwinging &&
    __mmPrimaryGearStage !== "bull" &&
    __mmUpdateHeldGear(__mmWeapon);
  // Native press-and-hold: never release between weapon cooldowns. The server
  // repeats attacks at the weapon's real speed while this state remains down.
  if (!__mmPrimaryAttackDown) {
    (je(v.weapons[0], !0),
      __mmSendWeaponAttack(1),
      (__mmPrimaryAttackDown = !0));
  }
}
function __mmStartPrimaryInput() {
  if (__mmPrimaryHeld || !v || !v.alive || v.weapons[0] == null) return !1;
  __mmActionOwner === "instaSync" && __mmStopInstaSync();
  __mmActionOwner === "weaponRecharge" && __mmPauseWeaponRecharge(!0);
  if (!__mmActionClaim("manualAttack", "left click")) return !1;
  const __mmWeapon = Number(v.weapons[0]);
  (Number(__mmPrimaryManualWeapon) !== __mmWeapon &&
      ((__mmPrimaryManualWeapon = __mmWeapon),
      (__mmPrimaryManualReadyAt = 0)),
    (__mmPrimaryHeld = !0),
    __mmStartHeldAttackPulse(),
    __mmAtFullHealth() && __mmStopFoodSpam());
  return !0;
}
function __mmStopPrimaryInput() {
  ((__mmPrimaryHeld = !1),
    __mmStopHeldAttackPulse(),
    __mmSecondaryHeld && __mmPulseHeldAttack(),
    __mmRestoreBullForPrimary(),
    __mmRestoreHeldHat(),
    __mmRestoreHeldTail(),
    __mmRestoreTrapHat(),
    !__mmSecondaryHeld && __mmActionRelease("manualAttack", "left click released"));
  (__mmUpdateMovementGear(), __mmUpdateWeaponRecharge());
}
function __mmObservePhysicalMouseButtons(__mmButtons) {
  const __mmPrimary = !!(Number(__mmButtons) & 1),
    __mmSecondary = !!(Number(__mmButtons) & 2);
  if (
    __mmPrimary === __mmPhysicalPrimaryDown &&
    __mmSecondary === __mmPhysicalSecondaryDown
  )
    return;
  ((__mmPhysicalPrimaryDown = __mmPrimary),
    (__mmPhysicalSecondaryDown = __mmSecondary),
    (__mmPhysicalInputAt = Date.now()));
}
function __mmObservePhysicalMouseRelease(__mmEvent) {
  if (__mmEvent && __mmEvent.button === 0)
    __mmPhysicalPrimaryDown = !1;
  if (__mmEvent && __mmEvent.button === 2)
    __mmPhysicalSecondaryDown = !1;
  __mmPhysicalInputAt = Date.now();
}
window.addEventListener("mouseup", __mmObservePhysicalMouseRelease, !0);
window.addEventListener("pointerup", __mmObservePhysicalMouseRelease, !0);
window.addEventListener(
  "pointermove",
  function (__mmEvent) {
    (!__mmEvent.pointerType || __mmEvent.pointerType === "mouse") &&
      __mmObservePhysicalMouseButtons(__mmEvent.buttons);
  },
  !0,
);
window.addEventListener(
  "pointercancel",
  function () {
    ((__mmPhysicalPrimaryDown = !1),
      (__mmPhysicalSecondaryDown = !1),
      (__mmPhysicalInputAt = Date.now()));
  },
  !0,
);
document.addEventListener(
  "mousedown",
  function (__mmEvent) {
    if (!__mmIsGameClick(__mmEvent) || __mmEvent.button !== 0) return;
    if (
      !__mmRuntimeBindingMatches(__mmKeybinds.primaryAttack, __mmEvent, !0) &&
      !__mmRuntimeBindingMatches(__mmKeybinds.clickBoostInsta, __mmEvent, !0)
    )
      return;
    ((__mmPhysicalPrimaryDown = !0), (__mmPhysicalInputAt = Date.now()));
    if (__mmHandleBushCombatClick(__mmEvent)) return;
    if (__mmBoostInsta.isActive()) {
      (__mmEvent.preventDefault(), __mmEvent.stopImmediatePropagation());
      return;
    }
    // Mouse modes are exclusive. Cancel right-click before left becomes active.
    (__mmSecondaryHeld || __mmRightClickHat != null) &&
      (__mmFinishSecondaryInput(), __mmForceRestoreRightClickHat());
    // A real click always wins over the queued R burst; cancel first, then
    // allow this existing input path to proceed normally.
    __mmInsta.isActive() && __mmInsta.cancel("manual-primary");
    __mmActionOwner === "weaponRecharge" && __mmPauseWeaponRecharge(!0);
    if (__mmUpdateAutoInsta()) {
      (__mmEvent.preventDefault(), __mmEvent.stopImmediatePropagation());
      return;
    }
    if (!__mmStartPrimaryInput()) return;
    (__mmEvent.preventDefault(),
      __mmEvent.stopImmediatePropagation(),
      null);
  },
  !0,
);
document.addEventListener(
  "mouseup",
  function (__mmEvent) {
    if (
      __mmCleanupAttackHeld &&
      __mmCleanupMouseButton === 0 &&
      __mmEvent.button === 0
    )
      return;
    if (
      __mmEvent.button !== 0 ||
      !__mmPrimaryHeld ||
      __mmBindingActionHeld("primaryAttack") ||
      __mmBindingActionHeld("clickBoostInsta")
    )
      return;
    (__mmEvent.preventDefault(),
      __mmEvent.stopImmediatePropagation(),
      __mmStopPrimaryInput());
  },
  !0,
);
function __mmSecondaryWeapon() {
  return v && v.alive && v.weapons && v.weapons[1] != null
    ? v.weapons[1]
    : null;
}
function __mmSecondaryWeaponReady() {
  const __mmWeapon = __mmSecondaryWeapon();
  if (__mmWeapon == null) return !1;
  const __mmReload = v.reloads && Number(v.reloads[__mmWeapon]);
  return !Number.isFinite(__mmReload) || __mmReload <= 0;
}
function __mmRightClickAngleDistance(__mmFirst, __mmSecond) {
  return Math.abs(
    Math.atan2(
      Math.sin(Number(__mmFirst) - Number(__mmSecond)),
      Math.cos(Number(__mmFirst) - Number(__mmSecond)),
    ),
  );
}
function __mmRightClickShieldPlan(__mmForce = !1) {
  const __mmNow = Date.now(),
    __mmCacheMs = Math.max(10, Math.min(25, __mmFastCheckMs()));
  if (
    !__mmForce &&
    __mmNow - __mmRightClickShieldPlanAt <= __mmCacheMs
  )
    return __mmRightClickShieldPlanCache;
  (__mmRightClickShieldPlanAt = __mmNow,
    (__mmRightClickShieldPlanCache = null));
  if (
    !__mmShieldDefenseEnabled ||
    !v ||
    !v.alive ||
    !v.weapons ||
    Number(v.weapons[1]) !== __mmShieldWeapon
  )
    return null;
  const __mmThreat = __mmCombatThreatSnapshot(),
    __mmThreatEntries = Array.isArray(__mmThreat && __mmThreat.entries)
      ? __mmThreat.entries.filter(function (__mmEntry) {
          return !!(
            __mmEntry &&
            (__mmEntry.type === "projectile" || __mmEntry.type === "turret") &&
            Number.isFinite(Number(__mmEntry.angle)) &&
            Number.isFinite(Number(__mmEntry.impactMs)) &&
            Number(__mmEntry.impactMs) <= Number(__mmThreat.horizonMs)
          );
        })
      : [],
    __mmEnemies = __mmLiveStateFresh() ? __mmLiveState.enemies : E,
    __mmCandidates = [],
    __mmRangedSources = [];
  let __mmCloseEnemy = null,
    __mmCloseDistance = Infinity;
  if (Array.isArray(__mmEnemies))
    for (let __mmIndex = 0; __mmIndex < __mmEnemies.length; __mmIndex++) {
      const __mmEnemy = __mmEnemies[__mmIndex];
      if (!__mmIsEnemyPlayer(__mmEnemy)) continue;
      const __mmDx = Number(__mmEnemy.x) - Number(v.x),
        __mmDy = Number(__mmEnemy.y) - Number(v.y),
        __mmDistance = Math.hypot(__mmDx, __mmDy),
        __mmWeapon = b && b.weapons && b.weapons[Number(__mmEnemy.weaponIndex)],
        __mmCloseReach = Math.min(
          __mmShieldDefenseRange,
          Math.max(
            145,
            (Number(__mmWeapon && __mmWeapon.range) || 0) +
              (Number(__mmEnemy.scale) || 35) +
              (Number(v.scale) || 35) +
              38,
          ),
        ),
        __mmAngle = Math.atan2(__mmDy, __mmDx);
      if (__mmDistance <= __mmCloseReach && __mmDistance < __mmCloseDistance)
        ((__mmCloseEnemy = {
          angle: __mmAngle,
          distance: __mmDistance,
          reach: __mmCloseReach,
          damage: Math.max(20, __mmThreatMeleeDamage(__mmEnemy, __mmEnemy.weaponIndex)),
        }),
          (__mmCloseDistance = __mmDistance));
      if (!__mmWeapon || __mmWeapon.projectile == null || __mmDistance > 950)
        continue;
      const __mmFacing = Number.isFinite(Number(__mmEnemy.dir))
          ? Number(__mmEnemy.dir)
          : Number(__mmEnemy.d2),
        __mmTowardUs = Math.atan2(-__mmDy, -__mmDx);
      if (
        Number.isFinite(__mmFacing) &&
        __mmRightClickAngleDistance(__mmFacing, __mmTowardUs) <= 0.72
      )
        __mmRangedSources.push({
          angle: __mmAngle,
          damage: Math.max(12, Number(__mmWeapon.dmg) || 0),
          impactMs: Math.max(80, __mmDistance),
        });
    }
  let __mmProjectileDamage = 0,
    __mmSoonestProjectile = Infinity;
  for (let __mmIndex = 0; __mmIndex < __mmThreatEntries.length; __mmIndex++) {
    const __mmEntry = __mmThreatEntries[__mmIndex];
    ((__mmProjectileDamage += Math.max(0, Number(__mmEntry.damage) || 0)),
      (__mmSoonestProjectile = Math.min(
        __mmSoonestProjectile,
        Number(__mmEntry.impactMs),
      )));
  }
  const __mmHealth = Math.max(1, Number(v.health) || 100),
    __mmProjectilePressure = !!(
      __mmThreatEntries.length >= 2 ||
      __mmRangedSources.length >= 2 ||
      __mmProjectileDamage >= Math.max(25, __mmHealth * 0.28) ||
      __mmSoonestProjectile <= Math.max(260, __mmServerTickMs() * 2)
    );
  if (!__mmCloseEnemy && !__mmProjectilePressure) return null;
  __mmCloseEnemy && __mmCandidates.push(__mmCloseEnemy);
  if (__mmProjectilePressure) {
    for (let __mmIndex = 0; __mmIndex < __mmThreatEntries.length; __mmIndex++)
      __mmCandidates.push(__mmThreatEntries[__mmIndex]);
    for (let __mmIndex = 0; __mmIndex < __mmRangedSources.length; __mmIndex++)
      __mmCandidates.push(__mmRangedSources[__mmIndex]);
  }
  const __mmShieldArc = Math.max(
    0.65,
    Number(y && y.shieldAngle) || Math.PI / 3,
  );
  let __mmBestAngle = __mmCandidates[0]
      ? Number(__mmCandidates[0].angle)
      : Ci(),
    __mmBestScore = -Infinity;
  for (let __mmCandidateIndex = 0; __mmCandidateIndex < __mmCandidates.length; __mmCandidateIndex++) {
    const __mmAngle = Number(__mmCandidates[__mmCandidateIndex].angle);
    if (!Number.isFinite(__mmAngle)) continue;
    let __mmScore = 0;
    if (
      __mmCloseEnemy &&
      __mmRightClickAngleDistance(__mmAngle, __mmCloseEnemy.angle) <= __mmShieldArc
    )
      __mmScore +=
        80 +
        Math.max(0, 1 - __mmCloseEnemy.distance / __mmCloseEnemy.reach) * 80 +
        __mmCloseEnemy.damage;
    for (let __mmIndex = 0; __mmIndex < __mmThreatEntries.length; __mmIndex++) {
      const __mmEntry = __mmThreatEntries[__mmIndex];
      if (__mmRightClickAngleDistance(__mmAngle, __mmEntry.angle) > __mmShieldArc)
        continue;
      const __mmUrgency = Math.max(
        0,
        1 - Number(__mmEntry.impactMs) / Math.max(1, Number(__mmThreat.horizonMs)),
      );
      __mmScore += Math.max(1, Number(__mmEntry.damage) || 0) * (1.5 + __mmUrgency);
    }
    for (let __mmIndex = 0; __mmIndex < __mmRangedSources.length; __mmIndex++) {
      const __mmSource = __mmRangedSources[__mmIndex];
      __mmRightClickAngleDistance(__mmAngle, __mmSource.angle) <= __mmShieldArc &&
        (__mmScore += 18 + __mmSource.damage * 0.35);
    }
    if (__mmScore > __mmBestScore)
      ((__mmBestScore = __mmScore), (__mmBestAngle = __mmAngle));
  }
  return (__mmRightClickShieldPlanCache = {
    weapon: __mmShieldWeapon,
    angle: __mmBestAngle,
    closeEnemy: !!__mmCloseEnemy,
    projectileCount: __mmThreatEntries.length,
    rangedCount: __mmRangedSources.length,
  });
}
function __mmRightClickWeapon(
  __mmShieldPlan = __mmRightClickShieldPlan(),
) {
  const __mmPrimary = v && v.alive && v.weapons ? v.weapons[0] : null,
    __mmSecondary = __mmSecondaryWeapon(),
    __mmData =
      __mmSecondary == null ? null : b && b.weapons && b.weapons[__mmSecondary];
  return __mmSecondary == null
    ? __mmPrimary
    : __mmSecondary === __mmShieldWeapon
      ? __mmShieldPlan
        ? __mmShieldWeapon
        : __mmPrimary
    : __mmData && __mmData.projectile != null && __mmPrimary != null
      ? __mmPrimary
      : __mmSecondary;
}
function __mmServerTickMs() {
  return Math.max(
    60,
    Math.ceil(1e3 / Math.max(1, Number(y && y.serverUpdateRate) || 9)),
  );
}
function __mmFastCheckMs() {
  // State detection should react between server updates; action paths retain
  // their separate server-tick rate limits before sending packets.
  return Math.min(
    Math.max(10, Number(__mmReactionMs) || 25),
    __mmServerTickMs(),
  );
}
function __mmEquipTankForSecondary(
  __mmWeapon = __mmRightClickWeapon(),
  __mmNow = Date.now(),
  __mmLeadMs = 0,
) {
  if (
    !__mmTankRightClickEnabled ||
    !v ||
    !v.alive ||
    __mmWeapon == null ||
    !v.skins ||
    !v.skins[40]
  )
    return !1;
  (__mmClearSecondaryGearTimer(),
    (__mmSecondaryGearStage = "tank"),
    __mmRightClickHat == null &&
      (__mmRightClickHat = __mmBestPostCombatHat()),
    // Tank is emitted in the same synchronous phase as the ready weapon swing.
    // The action-phase timer restores the best current hat next server tick.
    __mmActivateCombatHat(40),
    (__mmSecondaryManualWeapon = __mmWeapon),
    (__mmSecondaryManualReadyAt =
      __mmNow +
      __mmManualWeaponCooldown(__mmWeapon, 40) +
      Math.max(0, Number(__mmLeadMs) || 0)));
  return !0;
}
function __mmClearSecondaryGearTimer() {
  (__mmSecondaryGearTimer && clearTimeout(__mmSecondaryGearTimer),
    (__mmSecondaryGearTimer = 0));
}
function __mmInvalidateSecondaryGearTimer() {
  (__mmClearSecondaryGearTimer(), (__mmSecondaryGearEpoch += 1));
}
function __mmClearSecondaryReleaseRestore() {
  (__mmSecondaryReleaseRestoreTimer &&
    clearTimeout(__mmSecondaryReleaseRestoreTimer),
    (__mmSecondaryReleaseRestoreTimer = 0),
    (__mmSecondaryReleaseRestoreHat = null),
    (__mmSecondaryReleaseRestoreAttempts = 0));
}
function __mmScheduleSecondaryReleaseRestore(__mmHat, __mmEpoch) {
  if (__mmCombatHatLockActive() && Number(__mmCombatHatLockHat) === 40)
    __mmScheduleCombatHatFinish();
}
function __mmScheduleSecondaryGear(
  __mmCallback,
  __mmDelay = __mmServerTickMs(),
) {
  __mmClearSecondaryGearTimer();
  const __mmEpoch = __mmSecondaryGearEpoch;
  __mmSecondaryGearTimer = setTimeout(function () {
    __mmSecondaryGearTimer = 0;
    __mmEpoch === __mmSecondaryGearEpoch && __mmCallback();
  }, Math.max(1, Number(__mmDelay) || __mmServerTickMs()));
}
function __mmEquipSecondaryDowntimeHat() {
  if (!v || !v.alive || __mmCombatHatLockActive()) return;
  const __mmHat = __mmBestPostCombatHat(),
    __mmTail = __mmDesiredHeldTail(__mmRightClickWeapon());
  (__mmClearSecondaryGearTimer(),
    (__mmSecondaryGearStage = "downtime"),
    __mmRememberHeldTail(__mmTail),
    __mmEquipGearPair(__mmHat, __mmTail, !0));
}
function __mmRestoreRightClickHat() {
  if (__mmCombatHatLockActive() && Number(__mmCombatHatLockHat) === 40) {
    __mmScheduleCombatHatFinish();
    return;
  }
  if (__mmRightClickHat == null) return void __mmClearSecondaryGearTimer();
  if (__mmSecondaryHeld) return;
  if (!v || !v.alive) {
      (__mmInvalidateSecondaryGearTimer(),
      __mmClearSecondaryReleaseRestore(),
      (__mmRightClickHat = null),
      (__mmSecondaryGearStage = null));
    return;
  }
  const __mmHat = __mmBestPostCombatHat();
  (__mmInvalidateSecondaryGearTimer(),
    (__mmRightClickHat = null),
    (__mmSecondaryGearStage = null),
    __mmEquipHatNow(__mmHat, !0));
}
function __mmForceRestoreRightClickHat() {
  if (__mmRightClickHat == null) return void __mmClearSecondaryGearTimer();
  const __mmHat = __mmBestPostCombatHat();
  (__mmInvalidateSecondaryGearTimer(),
    (__mmRightClickHat = null),
    (__mmSecondaryGearStage = null),
    v &&
      v.alive &&
      !__mmCombatHatLockActive() &&
      __mmEquipHatNow(__mmHat, !0));
}
function __mmPulseSecondaryWeapon() {
  if (!__mmSecondaryHeld) return;
  const __mmShieldPlan = __mmRightClickShieldPlan(),
    __mmWeapon = __mmRightClickWeapon(__mmShieldPlan),
    __mmShieldMode = !!(
      __mmShieldPlan && Number(__mmWeapon) === __mmShieldWeapon
    ),
    __mmUseTank = !!(
      !__mmShieldMode &&
      __mmTankRightClickEnabled &&
      v &&
      v.skins &&
      v.skins[40]
    ),
    __mmNow = Date.now(),
    __mmTankLead = __mmUseTank
      ? __mmSecondaryTankLead(
          __mmWeapon,
          __mmSecondaryManualReadyAt,
          __mmNow,
        )
      : -1;
  if (__mmWeapon == null) return;
  Number(__mmSecondaryManualWeapon) !== Number(__mmWeapon) &&
    ((__mmSecondaryManualWeapon = Number(__mmWeapon)),
    (__mmSecondaryManualReadyAt = 0));
  if (__mmShieldMode) {
    if (
      __mmCombatHatLockActive() &&
      Number(__mmCombatHatLockHat) === 40
    )
      __mmCancelCombatHatLock(!0);
    ((__mmSecondaryShieldActive = !0),
      (__mmSecondaryShieldUsed = !0),
      (__mmSecondaryShieldAngle = Number(__mmShieldPlan.angle)),
      (__mmSecondaryGearStage = "shield"),
      __mmUpdateHeldGear(__mmWeapon),
      je(__mmShieldWeapon, !0));
    if (
      __mmNow - __mmSecondaryShieldAimAt >= __mmFastCheckMs()
    ) {
      ((__mmSecondaryShieldAimAt = __mmNow),
        O.send("D", __mmSecondaryShieldAngle));
    }
  } else {
    if (__mmSecondaryShieldActive) {
      ((__mmSecondaryShieldActive = !1),
        (__mmSecondaryShieldAngle = null),
        (__mmSecondaryShieldAimAt = 0));
      __mmScheduleMouseAimReturn();
    }
    __mmTankLead >= 0
      ? (__mmUpdateHeldTail(__mmWeapon),
        __mmEquipTankForSecondary(__mmWeapon, __mmNow, __mmTankLead))
      : __mmUpdateHeldGear(__mmWeapon);
  }
  // Native press-and-hold is sent once. Gear timing follows the weapon clock
  // without converting the hold into repeated click packets.
  if (!__mmSecondaryAttackDown)
    (je(__mmWeapon, !0),
      __mmShieldMode
        ? O.send("F", 1, __mmSecondaryShieldAngle)
        : __mmSendWeaponAttack(1),
      (__mmSecondaryAttackDown = !0));
}
function __mmObserveHeldGearSwing(__mmPlayerSid, __mmWeapon) {
  if (
    !v ||
    !v.alive ||
    __mmPlayerSid == null ||
    String(__mmPlayerSid) !== String(v.sid)
  )
    return;
  const __mmResolvedWeapon =
      __mmWeapon == null ? Number(v.weaponIndex) : Number(__mmWeapon),
    __mmNow = Date.now();
  if (
    __mmPrimaryHeld &&
    v.weapons &&
    Number(v.weapons[0]) === __mmResolvedWeapon &&
    __mmBullPrimaryAvailable()
  )
    ((__mmPrimaryManualWeapon = __mmResolvedWeapon),
      (__mmPrimaryManualReadyAt =
        __mmNow + __mmManualWeaponCooldown(__mmResolvedWeapon, 7)));
  if (
    __mmSecondaryHeld &&
    Number(__mmSecondaryManualWeapon) === __mmResolvedWeapon &&
    __mmResolvedWeapon !== __mmShieldWeapon &&
    __mmTankRightClickEnabled &&
    v.skins &&
    v.skins[40]
  )
    ((__mmSecondaryManualWeapon = __mmResolvedWeapon),
      (__mmSecondaryManualReadyAt =
        __mmNow + __mmManualWeaponCooldown(__mmResolvedWeapon, 40)));
}
function __mmStopSecondary() {
  const __mmRestoreSelection = __mmSecondaryRestoreWeapon,
    __mmUsedShield = __mmSecondaryShieldUsed,
    __mmMayRestoreWeapon = __mmActionMayRestore("manualAttack");
  ((__mmSecondaryHeld = !1),
    (__mmSecondaryAttackDown = !1),
    (__mmSecondaryShieldActive = !1),
    (__mmSecondaryShieldAngle = null),
    (__mmSecondaryShieldUsed = !1),
    (__mmSecondaryShieldAimAt = 0),
    (__mmSecondaryRestoreWeapon = null),
    (__mmRightClickShieldPlanAt = 0),
    (__mmRightClickShieldPlanCache = null),
    (U = 0),
    __mmStopHeldAttackPulse(),
    __mmPrimaryHeld && __mmPulseHeldAttack(),
    __mmRestoreHeldHat(),
    __mmRestoreHeldTail(),
    __mmRestoreRightClickHat(),
    __mmRestoreTrapHat(),
    !__mmPrimaryHeld && __mmActionRelease("manualAttack", "right click released"));
  if (
    __mmUsedShield &&
    __mmMayRestoreWeapon &&
    v &&
    v.alive &&
    __mmRestoreSelection != null &&
    Number(__mmSelectedWeapon()) === __mmShieldWeapon
  )
    __mmRestoreWeapon(__mmRestoreSelection);
  __mmUsedShield && __mmScheduleMouseAimReturn();
  (__mmUpdateMovementGear(), __mmUpdateWeaponRecharge());
}
function __mmFinishSecondaryInput() {
  (__mmStopSecondary(), __mmRestoreBullForPrimary());
}
function __mmStartConfiguredSecondary(__mmEvent) {
  if (!v || !v.alive) return !1;
  if (__mmHandleBushCombatClick(__mmEvent)) return !0;
  __mmBoostInsta.isActive() && __mmBoostInsta.cancel("manual-secondary");
  __mmInsta.isActive() && __mmInsta.cancel("manual-secondary");
  __mmActionOwner === "instaSync" && __mmStopInstaSync();
  __mmActionOwner === "weaponRecharge" && __mmPauseWeaponRecharge(!0);
  __mmActionOwner === "shieldDefense" &&
    __mmStopShieldDefense("manual right-click handoff");
  const __mmShieldPlan = __mmRightClickShieldPlan(!0),
    __mmPlannedWeapon = __mmRightClickWeapon(__mmShieldPlan);
  if (
    (!__mmTankRightClickEnabled && !__mmShieldPlan) ||
    __mmPlannedWeapon == null
  )
    return (__mmRestoreRightClickHat(), !1);
  (__mmPrimaryHeld || __mmPrimaryClickHat != null) &&
    (__mmStopPrimaryInput(), __mmForceRestoreBullForPrimary());
  if (!__mmActionClaim("manualAttack", "configured secondary")) return !1;
  const __mmWeapon = Number(__mmPlannedWeapon);
  return (
    __mmClearSecondaryReleaseRestore(),
    (__mmSecondaryGearEpoch += 1),
    (U = 1),
    (__mmSecondaryRestoreWeapon = __mmSelectedWeapon()),
    (__mmSecondaryShieldUsed = !1),
    Number(__mmSecondaryManualWeapon) !== __mmWeapon &&
      ((__mmSecondaryManualWeapon = __mmWeapon),
      (__mmSecondaryManualReadyAt = 0)),
    (__mmSecondaryHeld = !0),
    __mmStartHeldAttackPulse(),
    !0
  );
}
document.addEventListener(
  "mousedown",
  function (__mmEvent) {
    if (__mmEvent.button !== 2 || !__mmIsGameClick(__mmEvent))
      return void __mmRestoreRightClickHat();
    if (
      !__mmRuntimeBindingMatches(
        __mmKeybinds.secondaryAttack,
        __mmEvent,
        !0,
      )
    )
      return;
    ((__mmPhysicalSecondaryDown = !0),
      (__mmPhysicalInputAt = Date.now()),
      __mmStartConfiguredSecondary(__mmEvent),
      __mmEvent.preventDefault(),
      __mmEvent.stopImmediatePropagation());
  },
  !0,
);
document.addEventListener(
  "mouseup",
  function (__mmEvent) {
    if (
      (__mmWeaponGrindHold ||
        (__mmCleanupAttackHeld && __mmCleanupMouseButton === 2)) &&
      __mmEvent.button === 2
    )
      return;
    if (
      __mmEvent.button !== 2 ||
      __mmBindingActionHeld("secondaryAttack") ||
      (!__mmSecondaryHeld && __mmRightClickHat == null)
    )
      return;
    (__mmEvent.preventDefault(),
      __mmEvent.stopImmediatePropagation(),
      __mmFinishSecondaryInput());
  },
  !0,
);
function __mmManualSecondaryReleaseBlocked() {
  return !!(
    __mmWeaponGrindHold ||
    (__mmCleanupAttackHeld && __mmCleanupMouseButton === 2)
  );
}
function __mmCaptureManualSecondaryRelease(__mmEvent) {
  if (
    __mmEvent.button !== 2 ||
    __mmBindingActionHeld("secondaryAttack") ||
    __mmManualSecondaryReleaseBlocked() ||
    (!__mmSecondaryHeld &&
      __mmRightClickHat == null &&
      !(!__mmPrimaryHeld && __mmActionOwner === "manualAttack"))
  )
    return;
  __mmFinishSecondaryInput();
}
// Capture releases at window level before the game or another listener can
// consume them. This is especially important for a one-frame right-click,
// where a missed mouseup otherwise leaves Tank and manualAttack latched.
window.addEventListener("pointerup", __mmCaptureManualSecondaryRelease, !0);
window.addEventListener("mouseup", __mmCaptureManualSecondaryRelease, !0);
window.addEventListener(
  "pointermove",
  function (__mmEvent) {
    if (
      (__mmEvent.pointerType === "" || __mmEvent.pointerType === "mouse") &&
      !(__mmEvent.buttons & 2) &&
      !__mmBindingActionHeld("secondaryAttack") &&
      !__mmManualSecondaryReleaseBlocked() &&
      (__mmSecondaryHeld || __mmRightClickHat != null)
    )
      __mmFinishSecondaryInput();
  },
  !0,
);
document.addEventListener(
  "pointerup",
  function (__mmEvent) {
    if (
      __mmEvent.button === 0 &&
      __mmPrimaryHeld &&
      !__mmBindingActionHeld("primaryAttack") &&
      !__mmBindingActionHeld("clickBoostInsta") &&
      !(__mmCleanupAttackHeld && __mmCleanupMouseButton === 0)
    )
      __mmStopPrimaryInput();
    if (
      __mmEvent.button === 2 &&
      !__mmBindingActionHeld("secondaryAttack") &&
      !__mmWeaponGrindHold &&
      !(__mmCleanupAttackHeld && __mmCleanupMouseButton === 2) &&
      (__mmSecondaryHeld || __mmRightClickHat != null)
    )
      __mmFinishSecondaryInput();
  },
  !0,
);
document.addEventListener(
  "pointermove",
  function (__mmEvent) {
    if (__mmEvent.pointerType && __mmEvent.pointerType !== "mouse") return;
    __mmPrimaryHeld &&
      !__mmBindingActionHeld("primaryAttack") &&
      !__mmBindingActionHeld("clickBoostInsta") &&
      !(__mmCleanupAttackHeld && __mmCleanupMouseButton === 0) &&
      !(__mmEvent.buttons & 1) &&
      __mmStopPrimaryInput();
    __mmSecondaryHeld &&
      !__mmBindingActionHeld("secondaryAttack") &&
      !__mmWeaponGrindHold &&
      !(__mmCleanupAttackHeld && __mmCleanupMouseButton === 2) &&
      !(__mmEvent.buttons & 2) &&
      __mmFinishSecondaryInput();
  },
  !0,
);
document.addEventListener(
  "pointercancel",
  function () {
    (!(__mmCleanupAttackHeld && __mmCleanupMouseButton === 0) &&
      __mmStopPrimaryInput(),
      !__mmWeaponGrindHold &&
        !(__mmCleanupAttackHeld && __mmCleanupMouseButton === 2) &&
        __mmFinishSecondaryInput());
  },
  !0,
);
document.addEventListener(
  "contextmenu",
  function (__mmEvent) {
    __mmIsGameClick(__mmEvent) && __mmEvent.preventDefault();
  },
  !0,
);
window.addEventListener("blur", function () {
  ((__mmPhysicalPrimaryDown = !1),
    (__mmPhysicalSecondaryDown = !1),
    (__mmPhysicalInputAt = Date.now()),
    (__mmBushHotkeyDown = !1),
    __mmStopPrimaryInput(),
    __mmStopSecondary(),
    __mmPauseWeaponGrind("window blur"),
    __mmStopCleanup("window blur", !1),
    __mmFinishMatThief("window blur"),
    __mmFinishMobSteal("window blur"),
    __mmStopWindmillHold(),
    __mmStopInstaSync(),
    __mmStopSpikeTickStrike("window blur"),
    __mmStopAntiBoostBlock("window blur"),
    __mmStopBoostSpike(),
    __mmStopVelTickInsta("window blur"),
    __mmStopAutoPushSetup("window blur"),
    __mmInsta.cancel("window-blur"),
    __mmBoostInsta.cancel("window-blur"),
    __mmStopBushMode("window blur", !0),
    __mmRestoreBullForPrimary(),
    __mmRestoreMovementGear());
});
document.addEventListener("visibilitychange", function () {
  document.hidden &&
    ((__mmPhysicalPrimaryDown = !1),
    (__mmPhysicalSecondaryDown = !1),
    (__mmPhysicalInputAt = Date.now()),
    __mmStopPrimaryInput(),
    __mmStopSecondary(),
    __mmPauseWeaponGrind("document hidden"),
    __mmStopCleanup("document hidden", !1),
    __mmFinishMatThief("document hidden"),
    __mmFinishMobSteal("document hidden"),
    __mmStopWindmillHold(),
    __mmStopInstaSync(),
    __mmStopSpikeTickStrike("document hidden"),
    __mmStopAntiBoostBlock("document hidden"),
    __mmStopBoostSpike(),
    __mmStopVelTickInsta("document hidden"),
    __mmStopAutoPushSetup("document hidden"),
      __mmInsta.cancel("document-hidden"),
      __mmBoostInsta.cancel("document-hidden"),
    __mmStopBushMode("document hidden", !0),
    __mmRestoreMovementGear());
});
function __mmSendKillMessage() {
  if (!__mmKillMessageEnabled || !__mmKillMessage || !v || !v.alive) return;
  __mmSendChat(__mmKillMessage);
}
const __mmDeathHistoryTimes = new Map();
function __mmRecordDeathHistory(__mmPlayer) {
  if (!__mmChatHistoryEnabled || !__mmDeathHistoryChatEnabled || !__mmPlayer)
    return;
  const __mmNow = Date.now();
  const __mmSid = __mmPlayer.sid == null ? __mmPlayer.id : __mmPlayer.sid,
    __mmKey = String(__mmSid == null ? __mmPlayer.name || "player" : __mmSid),
    __mmLastAt = Number(__mmDeathHistoryTimes.get(__mmKey)) || 0;
  if (__mmNow - __mmLastAt < 2000) return;
  __mmDeathHistoryTimes.set(__mmKey, __mmNow);
  if (__mmDeathHistoryTimes.size > 80)
    for (const [__mmOldKey, __mmOldAt] of __mmDeathHistoryTimes)
      __mmNow - __mmOldAt > 10000 && __mmDeathHistoryTimes.delete(__mmOldKey);
  const __mmName = String(__mmPlayer.name || "Player").slice(0, 32);
  window.dispatchEvent(
    new CustomEvent("MooMooKittyChatMessage", {
      detail: {
        name: "Death",
        message: __mmName + " died",
        relation: __mmChatRelation(__mmPlayer),
        at: __mmNow,
      },
    }),
  );
}
__mmApplyUpgradeUnlock();
__mmStartLiveState();
__mmStartTabSync();
__mmStartDebugHud();
__mmStartAutoHeal();
__mmStartAutoTrapInsta();
__mmStartAutoInsta();
__mmStartKittyInstas();
__mmStartAutoSpikeInsta();
__mmStartTrapAlert();
__mmStartFriendlyTrapChat();
__mmStartTeamRequestAutomation();
__mmStartTrapEscape();
__mmStartPlacementDefense();
__mmStartTeammateTrapRescue();
__mmStartTurretSteal();
__mmStartSpikeGearCounter();
__mmStartSoldierAuto();
__mmStartMovementGear();
__mmStartMultiBreak();
__mmStartWeaponRecharge();
__mmStartAutoPurchase();
__mmStartMobSteal();
__mmApplyWindmillRotationState();
__mmStartInstaSync();
__mmStartAntiBoostInsta();
__mmStartAntiCollision();
__mmStartThreatTrap();
__mmStartSmartPlacement();
Sl = function () {
  __mmRecordDeathHistory(v);
  const __mmResult = __mmOriginalDeath.apply(this, arguments);
  window.dispatchEvent(new CustomEvent("MooMooKittyLocalDeath"));
  return __mmResult;
};
Xl = function () {
  const __mmResult = __mmOriginalAnimalUpdate.apply(this, arguments);
  __mmMobStealEnabled && __mmUpdateMobSteal();
  return __mmResult;
};
$l = function (__mmPlayerSid, __mmHealth) {
  const __mmHealthPlayer = __mmChatPlayer(__mmPlayerSid),
    __mmObservedPreviousHealth = __mmHealthPlayer
      ? Number(__mmHealthPlayer.health)
      : null,
    __mmPreviousHealth =
      v && __mmPlayerSid === v.sid ? Number(v.health) : null;
  const __mmResult = __mmOriginalHealthUpdate.apply(this, arguments);
  Number.isFinite(__mmObservedPreviousHealth) &&
    Number.isFinite(Number(__mmHealth)) &&
    __mmRecordCombatDelta(
      __mmHealthPlayer ||
        (v && String(__mmPlayerSid) === String(v.sid) ? v : null) ||
        __mmChatPlayer(__mmPlayerSid),
      __mmObservedPreviousHealth,
      Number(__mmHealth),
    );
  Number.isFinite(__mmObservedPreviousHealth) &&
    __mmObservedPreviousHealth > 0 &&
    Number(__mmHealth) <= 0 &&
    __mmRecordDeathHistory(__mmHealthPlayer);
  if (v && __mmPlayerSid === v.sid) {
    __mmCombatThreatCalculatedAt = 0;
    Number.isFinite(__mmPreviousHealth) &&
      Number(__mmHealth) < __mmPreviousHealth &&
      ((__mmAssassinLastDamageAt = Date.now()),
      (__mmAssassinSafeSince = 0));
    Number.isFinite(__mmPreviousHealth) &&
      Number.isFinite(Number(__mmHealth)) &&
      __mmObserveFriendDamage(
        Math.max(0, __mmPreviousHealth - Number(__mmHealth)),
      );
    const __mmTookDamage = __mmObserveAutoHealHealth(__mmHealth);
    __mmTookDamage && __mmDisableWeaponGrind("incoming damage");
    __mmTookDamage &&
      __mmBushModeRequested &&
      __mmStopBushMode("attacked", !0);
    // A confirmed hit always takes priority over a queued insta. Healing is
    // packet-driven, so do it now rather than deferring for combat cleanup.
    __mmInsta.isActive() && __mmTookDamage &&
      __mmInsta.cancel("health-damage");
    __mmAutoHeal();
  }
  return __mmResult;
};
Kl = function (__mmKey, __mmValue, __mmRefresh) {
  const __mmResourceKey = String(__mmKey),
    __mmPreviousKills =
      v && __mmResourceKey === "kills" ? Number(v.kills) || 0 : null,
    __mmPreviousResource =
      v &&
      (__mmResourceKey === "food" ||
        __mmResourceKey === "wood" ||
        __mmResourceKey === "stone")
        ? v[__mmResourceKey]
        : null,
    __mmXpWeapon = v ? v.weaponIndex : null,
    __mmResult = __mmOriginalPlayerStatUpdate.apply(this, arguments);
  return (
    __mmPreviousResource != null &&
      __mmTrackWeaponXpResourceGain(
        __mmResourceKey,
        __mmPreviousResource,
        __mmValue,
        __mmXpWeapon,
      ),
    __mmPreviousKills != null &&
      Number(__mmValue) > __mmPreviousKills &&
      __mmSendKillMessage(),
    __mmResult
  );
};
Un = function () {
  const __mmResult = __mmOriginalUpgradeDisplay.apply(this, arguments);
  (__mmMarkUnsafeUpgradeChoices(), __mmResult);
  return __mmResult;
};
Pl = function (__mmPlayerSid, __mmDidHit, __mmWeapon) {
  __mmObserveHeldGearSwing(__mmPlayerSid, __mmWeapon);
  __mmRecordPlayerSwing(__mmPlayerSid, __mmWeapon);
  __mmSyncObservedPlayerSwing(__mmPlayerSid, __mmWeapon);
  __mmObserveTrapEscapeSwing(__mmPlayerSid, __mmWeapon);
  __mmObserveFriendAttack(__mmPlayerSid, __mmDidHit, __mmWeapon);
  __mmTrackTurretGearReload(__mmPlayerSid);
  __mmHandleEnemyPolearmSwing(__mmPlayerSid, __mmWeapon);
  return __mmOriginalPlayerAttack.apply(this, arguments);
};
dl = function (__mmPlayerSid, __mmMessage) {
  const __mmResult = __mmOriginalChatDisplay.apply(this, arguments);
  (__mmRecordChatMessage(
      __mmPlayerSid,
      __mmMessage,
    ),
    __mmReplyToMaterialRequest(__mmPlayerSid, __mmMessage),
    __mmReplyToModQuestion(__mmPlayerSid, __mmMessage),
    __mmTryMeowChainInsta(__mmPlayerSid, __mmMessage),
    __mmResult);
  return __mmResult;
};
window.__KittyHandleInstaHotkey = __mmHandleInstaHotkey;
window.addEventListener("blur", __mmStopTrapAttack);
__mmStartMinimapRegions();
__mmPublishHudState();
window.__MooMooScrollZoomSetViewport = function (__mmZoomMultiplier) {
  const __mmMultiplier = Math.max(
    0.5,
    Math.min(6.666666666666667, Number(__mmZoomMultiplier) || 1),
  );
  _ = y.maxScreenWidth = __mmZoomBaseWidth * __mmMultiplier;
  L = y.maxScreenHeight = __mmZoomBaseHeight * __mmMultiplier;
  bi();
};
setTimeout(function () {
  window.__MooMooScrollZoomSetViewport(
    window.__MooMooScrollZoomMultiplier || 1,
  );
}, 0);
`;
    }
    function patchedHotkeyCode() {
        // Configured Kitty actions are claimed by the capture dispatcher. The
        // native chain remains available for unclaimed MooMoo keys.
        return "__mmCleanupInputKey(t)," + HOTKEY_MARKER;
}
 
    function patchedFoodHotkeyCode() {
        return "";
    }
 
    function patchedFoodKeyupCode() {
  return "function pl(e){if(v&&v.alive){const t=e.which||e.keyCode||0;";
    }

    function patchedMovementKeydownCode() {
        return "bt[t]?__mmAntiCollisionMovementPressed(t):t==32&&(U=1,ke())";
    }

    function patchedMovementKeyupCode() {
        return "bt[t]?__mmAntiCollisionMovementReleased(t):t==32&&(U=0,ke())";
    }
 
    function wait(milliseconds) {
        return new Promise((resolve) => window.setTimeout(resolve, milliseconds));
    }
 
    function loadOriginalBundle(originalUrl) {
        if (originalBundleLoaded) return;
 
        originalBundleLoaded = true;
        installKittyUpgradeModuleUnlock();
        const fallbackScript = document.createElement("script");
        fallbackScript.type = "module";
        fallbackScript.src = originalUrl;
        (document.head || document.documentElement).appendChild(fallbackScript);
    }
 
    async function fetchBundleSource(originalUrl) {
        let lastError;
 
        for (let attempt = 1; attempt <= BUNDLE_RETRY_LIMIT; attempt += 1) {
            try {
                const response = await fetch(originalUrl, { cache: "force-cache" });
                if (!response.ok) throw new Error(`bundle request failed (${response.status})`);
                return await response.text();
            } catch (error) {
                lastError = error;
                if (attempt < BUNDLE_RETRY_LIMIT) {
                    console.warn(`[MooMoo Scroll Zoom] bundle attempt ${attempt} failed; retrying.`);
                    await wait(BUNDLE_RETRY_DELAY_MS * attempt);
                }
            }
        }
 
        throw lastError || new Error("bundle request failed");
    }
 
    function loadPatchedModule(patchedSource) {
        return new Promise((resolve, reject) => {
            installKittyUpgradeModuleUnlock();
            const blobUrl = URL.createObjectURL(new Blob([patchedSource], { type: "text/javascript" }));
            const patchedScript = document.createElement("script");
            patchedScript.type = "module";
            patchedScript.src = blobUrl;
            patchedScript.onload = () => {
                URL.revokeObjectURL(blobUrl);
                resolve();
            };
            patchedScript.onerror = () => {
                URL.revokeObjectURL(blobUrl);
                patchedScript.remove();
                reject(new Error("patched game bundle could not load"));
            };
            (document.head || document.documentElement).appendChild(patchedScript);
        });
    }

    function waitForDocumentParsed() {
        if (document.readyState !== "loading") return Promise.resolve();
        return new Promise((resolve) => {
            document.addEventListener("DOMContentLoaded", resolve, { once: true });
        });
    }
 
    function findMissingPatchMarkers(source) {
    const markers = [
            ["viewport", VIEWPORT_MARKER],
            ["hotkeys", HOTKEY_MARKER],
            ["food hotkey", FOOD_HOTKEY_MARKER],
            ["food keyup", FOOD_KEYUP_MARKER],
            ["movement keydown", MOVEMENT_KEYDOWN_MARKER],
            ["movement keyup", MOVEMENT_KEYUP_MARKER],
            ["native ground grid", NATIVE_GROUND_GRID_MARKER],
            ["player-stat update", PLAYER_STAT_UPDATE_MARKER],
            ["chat display", CHAT_DISPLAY_MARKER],
            ["insta player lookup", INSTA_PLAYER_LOOKUP_MARKER],
            ["insta player attack", INSTA_PLAYER_ATTACK_MARKER],
            ["full-server direct connect", FORCE_FULL_DIRECT_MARKER],
            ["full-server browser filter", FORCE_FULL_FILTER_MARKER],
            ["full-server automatic filter", FORCE_FULL_AUTO_MARKER],
            ["full-server spawn flag", FORCE_FULL_SPAWN_MARKER]
        ];
        return markers
            .filter(([, marker]) => !source.includes(marker))
            .map(([name]) => name);
    }
 
    async function loadPatchedBundle(originalUrl) {
        try {
            const originalSource = await fetchBundleSource(originalUrl);
            const missingMarkers = findMissingPatchMarkers(originalSource);
            if (missingMarkers.length) {
                throw new Error("the game client changed; missing patch markers: " + missingMarkers.join(", "));
            }
 
            const bundleUrl = new URL(originalUrl, location.href);
            const patchedSource = originalSource
                .replace(VIEWPORT_MARKER, patchedViewportCode())
                .replace(HOTKEY_MARKER, patchedHotkeyCode())
                .replace(FOOD_HOTKEY_MARKER, patchedFoodHotkeyCode())
                .replace(FOOD_KEYUP_MARKER, patchedFoodKeyupCode())
                .replace(MOVEMENT_KEYDOWN_MARKER, patchedMovementKeydownCode())
                .replace(MOVEMENT_KEYUP_MARKER, patchedMovementKeyupCode())
                .replace(NATIVE_GROUND_GRID_MARKER, "")
                .replace(
                    FORCE_FULL_DIRECT_MARKER,
                    '!window.__KittyForceFullServers&&s.playerCount>=s.playerCapacity){this.errorCallback("Server is already full.");return}'
                )
                .replace(
                    FORCE_FULL_FILTER_MARKER,
                    ".filter(function(h){return window.__KittyForceFullServers||h.playerCount<n})"
                )
                .replace(
                    FORCE_FULL_AUTO_MARKER,
                    "e=window.__KittyForceFullServers?e:e.filter(n=>n.playerCount!==n.playerCapacity)"
                )
                .replace(
                    FORCE_FULL_SPAWN_MARKER,
                    "moofoll:window.__KittyForceFullServers||xt"
                )
                .replace(/from"\.\/vendor-[^"]+\.js"/, (specifier) => {
                    const path = specifier.slice(5, -1);
                    return `from"${new URL(path, bundleUrl).href}"`;
                });
            // The site's original module is parser-deferred. Our replacement is
            // dynamically appended, so preserve the same ordering explicitly;
            // otherwise a cached bundle can run before MooMoo's body exists.
            await waitForDocumentParsed();
            let lastError;
            for (let attempt = 1; attempt <= PATCHED_MODULE_RETRY_LIMIT; attempt += 1) {
                try {
                    await loadPatchedModule(patchedSource);
                    return;
                } catch (error) {
                    lastError = error;
                    if (attempt < PATCHED_MODULE_RETRY_LIMIT) {
                        console.warn(`[MooMoo Scroll Zoom] patched bundle attempt ${attempt} failed; retrying.`);
                        await wait(BUNDLE_RETRY_DELAY_MS * attempt);
                    }
                }
            }
 
            throw lastError || new Error("patched game bundle could not load");
        } catch (error) {
            console.error("[MooMoo Scroll Zoom] could not patch the game bundle; loading the original bundle.", error);
            loadOriginalBundle(originalUrl);
        }
    }
 
    function gameBundleUrl(value) {
        if (!value) return null;
        try {
            const url = new URL(String(value), location.href);
            return GAME_BUNDLE.test(url.pathname) ? url.href : null;
        } catch {
            return null;
        }
    }

    function claimGameBundle(script, originalUrl, removeConnected = true) {
        if (gameScriptHijacked || !script || !originalUrl) return false;
        gameScriptHijacked = true;
        restoreBundleInsertionGuards();
        script.type = "application/x-kitty-klient-blocked";
        script.removeAttribute("src");
        if (removeConnected && script.isConnected) script.remove();
        // Start the replacement fetch during the same turn that blocked the
        // original module. No observer/microtask gap is left for it to execute.
        loadPatchedBundle(originalUrl);
        return true;
    }

    function interceptGameBundle(script, removeConnected = true) {
        if (gameScriptHijacked || !script || script.tagName !== "SCRIPT") return false;
        const originalUrl = gameBundleUrl(script.src || script.getAttribute("src"));
        return claimGameBundle(script, originalUrl, removeConnected);
    }

    function installSynchronousBundleGuards() {
        const nodePrototype = Node.prototype;
        const elementPrototype = Element.prototype;
        const scriptPrototype = HTMLScriptElement.prototype;
        const originalAppendChild = nodePrototype.appendChild;
        const originalInsertBefore = nodePrototype.insertBefore;
        const originalReplaceChild = nodePrototype.replaceChild;
        const originalAppend = elementPrototype.append;
        const originalPrepend = elementPrototype.prepend;
        const originalSetAttribute = elementPrototype.setAttribute;
        const originalSrc = Object.getOwnPropertyDescriptor(scriptPrototype, "src");
        let restored = false;

        const restore = () => {
            if (restored) return;
            restored = true;
            nodePrototype.appendChild = originalAppendChild;
            nodePrototype.insertBefore = originalInsertBefore;
            nodePrototype.replaceChild = originalReplaceChild;
            if (originalAppend) elementPrototype.append = originalAppend;
            if (originalPrepend) elementPrototype.prepend = originalPrepend;
            elementPrototype.setAttribute = originalSetAttribute;
            if (originalSrc) Object.defineProperty(scriptPrototype, "src", originalSrc);
        };
        restoreBundleInsertionGuards = restore;

        const captureNode = (node) => {
            if (
                gameScriptHijacked ||
                !node ||
                node.nodeType !== Node.ELEMENT_NODE ||
                node.tagName !== "SCRIPT"
            ) return false;
            const originalUrl = gameBundleUrl(node.src || node.getAttribute("src"));
            return claimGameBundle(node, originalUrl, false);
        };

        nodePrototype.appendChild = function (node) {
            if (captureNode(node)) return node;
            return originalAppendChild.call(this, node);
        };
        nodePrototype.insertBefore = function (node, reference) {
            if (captureNode(node)) return node;
            return originalInsertBefore.call(this, node, reference);
        };
        nodePrototype.replaceChild = function (node, previous) {
            if (captureNode(node)) return previous;
            return originalReplaceChild.call(this, node, previous);
        };
        if (originalAppend) {
            elementPrototype.append = function (...nodes) {
                const remaining = nodes.filter((node) => !captureNode(node));
                if (remaining.length) return originalAppend.apply(this, remaining);
            };
        }
        if (originalPrepend) {
            elementPrototype.prepend = function (...nodes) {
                const remaining = nodes.filter((node) => !captureNode(node));
                if (remaining.length) return originalPrepend.apply(this, remaining);
            };
        }
        elementPrototype.setAttribute = function (name, value) {
            if (
                !gameScriptHijacked &&
                this instanceof HTMLScriptElement &&
                String(name).toLowerCase() === "src"
            ) {
                const originalUrl = gameBundleUrl(value);
                if (claimGameBundle(this, originalUrl, false)) return;
            }
            return originalSetAttribute.call(this, name, value);
        };
        if (originalSrc && originalSrc.get && originalSrc.set) {
            Object.defineProperty(scriptPrototype, "src", {
                configurable: originalSrc.configurable,
                enumerable: originalSrc.enumerable,
                get: originalSrc.get,
                set(value) {
                    if (!gameScriptHijacked) {
                        const originalUrl = gameBundleUrl(value);
                        if (claimGameBundle(this, originalUrl, false)) return;
                    }
                    return originalSrc.set.call(this, value);
                }
            });
        }
    }

})();