Manarion 助手

Manarion 游戏数据计算器

// ==UserScript==
// @name         Manarion helper
// @name:zh-CN   Manarion 助手
// @name:en      Manarion helper
// @namespace    http://tampermonkey.net/
// @version      0.0.4.1
// @description  game Manarion calculation tool with combat/gathering efficiency calculator
// @description:zh-CN  Manarion 游戏数据计算器
// @description:en     game Manarion calculation tool with combat/gathering efficiency calculator
// @author       LemonApostle
// @match        https://manarion.com/*
// @match        https://*.manarion.com/*
// @icon         https://s2.loli.net/2025/05/28/YmWGhwXJVHonOsI.png
// @grant        GM_xmlhttpRequest
// @connect      api.manarion.com
// @run-at       document-end
// @license      MIT
// @homepage     https://greasyfork.org/zh-CN/scripts/546781-manarion-helper
// @supportURL   https://greasyfork.org/zh-CN/scripts/546781-manarion-helper/feedback

// ==/UserScript==

if (window.top !== window) return;

(function() {
    'use strict';

    if (window.top !== window) return;

    function getFullHTMLContent() { return `<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title data-translate-key="title">计算器</title>
    <style>
        /* --- THEME COLORS USING CSS VARIABLES --- */
        :root {
            --bg-gradient-start: #667eea;
            --bg-gradient-end: #764ba2;
            --container-bg: rgba(255, 255, 255, 0.95);
            --card-bg: #ffffff;
            --section-bg: #f8f9fa;
            --input-bg: #f9f9f9;
            --button-gradient-start: #667eea;
            --button-gradient-end: #764ba2;
            --text-color: #333;
            --text-color-light: #666;
            --border-color: #e0e0e0;
            --input-border-color: #ddd;
            --accent-border-color: #667eea;
            --success-bg: #d4edda;
            --success-text: #155724;
            --success-border: #28a745;
            --error-bg: #f8d7da;
            --error-text: #721c24;
            --error-border: #dc3545;
            --note-bg: #e3f2fd;
            --note-text: #1565c0;
            --note-border: #bbdefb;
            --calc-result-bg: #e8f5e8;
            --calc-result-text: #2e7d2e;
            --result-content-bg: #f5f5f5;
        }

        body.dark {
            --bg-gradient-start: oklch(20% .07 262.5);
            --bg-gradient-end: oklch(4.8% .02 262.5);
            --container-bg: oklch(12% .05 262.5 / .95);
            --card-bg: oklch(17.2% .07 262.5);
            --section-bg: oklch(15% .06 262.5);
            --input-bg: oklch(20% .07 262.5);
            --button-gradient-start: oklch(52.5% .23 290);
            --button-gradient-end: oklch(59.8% .26 292);
            --text-color: oklch(98.1% .004 257.1);
            --text-color-light: oklch(67.3% .03 270);
            --border-color: oklch(25% .07 262.5);
            --input-border-color: oklch(30% .07 262.5);
            --accent-border-color: oklch(52.5% .23 290);
            --success-bg: oklch(25% .1 149);
            --success-text: oklch(85% .2 149);
            --success-border: oklch(72.3% .219 149.579);
            --error-bg: oklch(25% .1 27);
            --error-text: oklch(85% .2 27);
            --error-border: oklch(63% .25 27);
            --note-bg: oklch(25% .1 259);
            --note-text: oklch(85% .2 259);
            --note-border: oklch(62.3% .214 259.815);
            --calc-result-bg: oklch(20% .08 149);
            --calc-result-text: oklch(85% .2 149);
            --result-content-bg: oklch(22% .07 262.5);
        }
        /* --- END THEME COLORS --- */

        body {
            font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
            max-width: 1200px;
            margin: 0 auto;
            padding: 20px;
            background: linear-gradient(135deg, var(--bg-gradient-start), var(--bg-gradient-end));
            min-height: 100vh;
            box-sizing: border-box; 
            transition: background-color 0.3s ease;
        }
        
        .container {
            background: var(--container-bg);
            border-radius: 15px;
            padding: 30px;
            box-shadow: 0 10px 30px rgba(0,0,0,0.2);
            transition: background-color 0.3s ease;
        }
        
        h1 {
            color: var(--text-color);
            text-align: center;
            margin-bottom: 30px;
            font-size: 2.5em;
            text-shadow: 2px 2px 4px rgba(0,0,0,0.1);
        }

        .header-buttons {
            display: flex;
            gap: 10px;
        }
        
        .input-section {
            background: var(--section-bg);
            padding: 20px;
            border-radius: 10px;
            margin-bottom: 20px;
            border-left: 4px solid var(--accent-border-color);
            transition: background-color 0.3s ease, border-color 0.3s ease;
        }
        
        .input-group {
            display: flex;
            gap: 10px;
            align-items: center;
            margin-bottom: 15px;
        }
        
        input[type="text"] {
            flex-grow: 1;
            min-width: 0;
            padding: 12px;
            border: 2px solid var(--input-border-color);
            background-color: var(--input-bg);
            color: var(--text-color);
            border-radius: 8px;
            font-size: 16px;
            transition: border-color 0.3s, background-color 0.3s ease;
        }
        
        input[type="text"]:focus {
            outline: none;
            border-color: var(--accent-border-color);
            box-shadow: 0 0 0 3px color-mix(in oklab, var(--accent-border-color) 20%, transparent);
        }
        
        button, .calc-button {
            background: linear-gradient(45deg, var(--button-gradient-start), var(--button-gradient-end));
            color: white;
            border: none;
            border-radius: 8px;
            cursor: pointer;
            font-weight: 600;
            transition: transform 0.2s, box-shadow 0.2s;
            flex-shrink: 0;
        }
        button { padding: 12px 24px; font-size: 16px; }
        .calc-button { padding: 8px 16px; font-size: 14px; }
        
        button:hover, .calc-button:hover {
            transform: translateY(-2px);
            box-shadow: 0 5px 15px color-mix(in oklab, var(--button-gradient-start) 40%, transparent);
        }
        
        button:disabled, .calc-button:disabled {
            background: var(--text-color-light);
            cursor: not-allowed;
            transform: none;
            box-shadow: none;
        }

        .theme-toggle-button {
            background: var(--container-bg);
            color: var(--accent-border-color);
            border: 2px solid var(--accent-border-color);
            padding: 8px;
            border-radius: 50%;
            cursor: pointer;
            font-size: 16px;
            font-weight: 600;
            transition: all 0.3s;
            width: 44px;
            height: 44px;
            display: flex;
            justify-content: center;
            align-items: center;
        }
        .theme-toggle-button:hover {
            background: var(--accent-border-color);
            color: var(--card-bg);
        }

        .usage-note {
            background: var(--note-bg);
            border: 1px solid var(--note-border);
            border-radius: 6px;
            padding: 10px;
            margin-bottom: 15px;
            color: var(--note-text);
            font-size: 14px;
        }

        .calc-input {
            display: flex;
            align-items: center;
            justify-content: space-between;
            margin: 10px 0;
            gap: 15px;
        }

        .calc-input label {
            flex-shrink: 0;
            font-weight: 500;
            color: var(--text-color);
            padding-right: 10px;
        }

        .calc-input .input-controls {
            display: flex;
            align-items: center;
            gap: 10px;
            flex-grow: 1;
            justify-content: flex-end;
        }

        #gatheringType, #gatheringType2 {
            padding: 8px;
            border: 1px solid var(--input-border-color);
            background-color: var(--input-bg);
            color: var(--text-color);
            border-radius: 4px;
            min-width: 120px;
        }
        
        .player-info {
            display: grid;
            grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
            gap: 15px; 
            margin-bottom: 20px;
        }
        
        .info-card {
            background: var(--card-bg);
            border: 1px solid var(--border-color);
            padding: 15px; 
            border-radius: 8px;
            box-shadow: 0 2px 4px rgba(0,0,0,0.05);
            transition: background-color 0.3s ease, border-color 0.3s ease;
        }
        
        .info-card h3 {
            margin: 0 0 10px 0;
            font-size: 1.1em;
            color: var(--text-color);
            border-bottom: 1px solid var(--border-color);
            padding-bottom: 8px;
        }
        
        .stat-row {
            display: flex;
            justify-content: space-between;
            align-items: center;
            margin: 6px 0; 
            gap: 10px;
            padding: 2px 0;
        }
        
        .stat-label {
            font-size: 0.9em;
            color: var(--text-color-light);
            font-weight: 500;
            min-width: 160px; 
            flex-shrink: 0; 
        }
        
        .stat-value {
            font-weight: bold;
            color: var(--text-color);
        }
        
        .stat-input {
            width: 80px;
            padding: 3px 6px;
            border: 1px solid var(--input-border-color);
            background: var(--input-bg);
            color: var(--text-color);
            border-radius: 4px;
            text-align: right;
            font-size: 0.9em;
        }
        
        .stat-input:focus {
            outline: none;
            border-color: var(--accent-border-color);
            background: var(--card-bg);
        }
        
        .error { background-color: var(--error-bg); color: var(--error-text); border-color: var(--error-border); }
        .success { background-color: var(--success-bg); color: var(--success-text); border-color: var(--success-border); }
        .success, .error { padding: 15px; border-radius: 8px; margin: 10px 0; border-left: 4px solid; }

        .calculator-section {
            background: var(--section-bg);
            padding: 20px;
            border-radius: 10px;
            margin-top: 20px;
            border-left: 4px solid var(--success-border);
            transition: background-color 0.3s ease, border-color 0.3s ease;
        }
        
        .calc-result {
            background: var(--calc-result-bg);
            padding: 15px;
            border-radius: 8px;
            margin-top: 15px;
            font-weight: bold;
            color: var(--calc-result-text);
            word-wrap: break-word;
            transition: background-color 0.3s ease, color 0.3s ease;
        }
        
        .result-content-box {
            font-family: monospace;
            background-color: var(--result-content-bg);
            color: inherit;
            padding: 10px;
            border-radius: 5px;
            transition: background-color 0.3s ease, color 0.3s ease;
        }

        @media (max-width: 768px) {
            body { padding: 10px; }
            .container { padding: 15px; }
            h1 { font-size: 1.8em; }
            .header-buttons { margin-left: auto; }
            .container > div:first-child { flex-direction: row; align-items: center; } /* Revert to row for header */
            .input-group { flex-direction: column; align-items: stretch; }
            .calc-input { flex-direction: column; align-items: stretch; gap: 8px; }
            .calc-input label { padding-right: 0; }
            .calc-input .input-controls { flex-direction: column; align-items: stretch; width: 100%; gap: 8px; }
            .calc-button { width: 100%; }
        }

    </style>
</head>
<body>
    <div class="container">
        <div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 30px;">
            <h1 style="margin: 0; flex: 1; text-align: center;" data-translate-key="mainTitle">🏰 Manarion 数据计算器</h1>
            <div class="header-buttons">
                <button id="langToggle" class="theme-toggle-button" onclick="toggleLanguage()" data-translate-key="langToggle" style="min-width: 60px; border-radius: 20px; padding-left: 12px; padding-right: 12px; width: auto;"></button>
                <button id="themeToggle" class="theme-toggle-button" onclick="toggleTheme()">
                    <span id="themeIcon">🌙</span>
                </button>
            </div>
        </div>
        
        <div class="input-section">
            <h3 data-translate-key="getPlayerData">📊 获取玩家数据</h3>
            <div class="input-group">
                <input type="text" id="playerName" data-translate-key="playerNamePlaceholder" placeholder="输入玩家名称或ID" value="LemonApostle">
                <button onclick="fetchPlayerData()" data-translate-key="fetchData">获取数据</button>
            </div>
            <div id="message"></div>
        </div>
        
        <div id="playerData" style="display:none;">
            <div class="player-info">
                <div class="info-card"><h3 data-translate-key="basicInfo">基本信息</h3><div id="basicInfo"></div></div>
                <div class="info-card"><h3 data-translate-key="gatheringBoosts">采集加成</h3><div id="gatheringBoosts"></div></div>
                <div class="info-card"><h3 data-translate-key="codexBoosts">法典加成</h3><div id="codexBoosts"></div></div>
                <div class="info-card"><h3 data-translate-key="otherEquipmentBoosts">其他装备加成</h3><div id="otherEquipmentBoosts"></div></div>
                <div class="info-card"><h3 data-translate-key="farm">农场</h3><div id="farmBoosts"></div></div>
                <div class="info-card"><h3 data-translate-key="marketPrice">市场价格</h3><div id="marketPrice"></div></div>
                <div class="info-card"><h3 data-translate-key="needToSupplement">需要自己补充的内容</h3><div id="needToSupplement"></div></div>
            </div>
        </div>
        
        <div class="calculator-section">
            <h3 data-translate-key="dataCalculator">🧮 数据计算器</h3>
            <div class="usage-note">
                <strong data-translate-key="usageNoteTitle">使用说明:</strong>
                <span data-translate-key="usageNote">填完必要的数据后,先点击"更新数据"按钮,再点击其他计算按钮。</span>
            </div>
            <div class="calc-input">
                <label data-translate-key="getAllCurrentValues">获取当前所有数据:</label>
                <button class="calc-button" onclick="getAllCurrentValues()" data-translate-key="updateData">更新数据</button>
            </div>
            <div class="calc-input">
                <label data-translate-key="calculateCombat">战斗计算:</label>
                <button class="calc-button" onclick="calculateCombatEfficiency()" data-translate-key="calculateCombatEfficiency">计算战斗效率</button>
            </div>
            <div class="calc-input">
                <label data-translate-key="calculateGathering">采集效率计算:</label>
                <div class="input-controls">
                    <select id="gatheringType">
                        <option value="mining" data-translate-key="miningOption">挖矿</option>
                        <option value="fishing" data-translate-key="fishingOption">钓鱼</option>
                        <option value="woodcutting" data-translate-key="woodcuttingOption">伐木</option>
                    </select>
                    <button class="calc-button" onclick="calculateGatheringEfficiency()" data-translate-key="calculateGatheringEfficiency">计算采集效率</button>
                </div>
            </div>
            <div class="calc-input">
                <label data-translate-key="calculateResonance">回响药水最佳等级计算:</label>
                <button class="calc-button" onclick="calculateResonancePotionLevel()" data-translate-key="calculateLevel">计算等级</button>
            </div>
            <div class="calc-input">
                <label data-translate-key="calculateROI">采集投资回报率计算:</label>
                <div class="input-controls">
                    <select id="gatheringType2">
                        <option value="mining" data-translate-key="miningOption">挖矿</option>
                        <option value="fishing" data-translate-key="fishingOption">钓鱼</option>
                        <option value="woodcutting" data-translate-key="woodcuttingOption">伐木</option>
                    </select>
                    <button class="calc-button" onclick="calculateGatheringROI()" data-translate-key="calculateGatheringROI">计算采集投资回报率</button>
                </div>
            </div>
            <div class="calc-input">
                <label data-translate-key="calculateGatherEquip">采集装备替换检测:</label>
                <button class="calc-button" onclick="calculateGatherEquipReplace()" data-translate-key="detectGatherEquip">检测采集装备替换</button>
            </div>
            <div class="calc-input">
                <label data-translate-key="calculateBattleEquip">战斗装备替换检测:</label>
                <button class="calc-button" onclick="calculateBattlerEquipReplace()" data-translate-key="detectBattleEquip">检测战斗装备替换</button>
            </div>
            <div id="calcResults"></div>
        </div>
    </div>

    <script>
let values = null;
let globalPlayerData = null;
let globalMarketData = null;
let currentLanguage = localStorage.getItem('manarion-language') || 'zh';
let currentTheme = localStorage.getItem('manarion-theme') || 'light';

const translations = {
    en: {
        // General UI
        langToggle: "中/EN",
        fetchData: "Get Data",
        updateData: "Update Data",
        playerNamePlaceholder: "Enter player name or ID",
        getPlayerData: "📊 Get Player Data",
        dataCalculator: "🧮 Data Calculator",
        usageNoteTitle: "Instructions:",
        usageNote: "After filling in necessary data, click 'Update Data' first, then other calculation buttons.",
        mainTitle: "🏰 Manarion Data Calculator", 

        // Titles
        basicInfo: "Basic Info",
        gatheringBoosts: "Gathering Boosts",
        codexBoosts: "Codex Boosts",
        otherEquipmentBoosts: "Other Equipment Boosts",
        farm: "Farm",
        marketPrice: "Market Price",
        needToSupplement: "Manual Input",

        // Basic Info Labels
        playerName: "Player Name:",
        currentEnemy: "Current Enemy:",
        battleLevel: "Battle Level:",
        miningLevel: "Mining Level:",
        fishingLevel: "Fishing Level:",
        woodcuttingLevel: "Woodcutting Level:",

        // Gathering Boosts Labels
        mining: "Mining:",
        fishing: "Fishing:",
        woodcutting: "Woodcutting:",
        baseResourceBoost: "Base Resource Amount:",

        // Codex Boosts Labels
        codexManaDust: "Base Mana Dust:",
        codexBaseResource: "Base Resource:",
        codexDropBoost: "Drop Boost:",

        // Other Equipment Boosts Labels
        manaBoost: "Mana Dust:",
        shardBoost: "Elemental Shards:",
        potionBoost: "Potion Boost:",

        // Farm Labels
        harvestGolem: "Harvest Golem:",
        fertilizer: "Fertilizer:",
        farmPlots: "Farm Plots:",
        farmHerbHarvest: "Herb Harvest:",
        farmTax: "Tax:",

        // Market Price Labels
        shardPrice: "Elemental Shards:",
        codexPrice: "Codex:",
        fishPrice: "Fish:",
        woodPrice: "Wood:",
        ironPrice: "Iron:",
        sagerootPrice: "Sageroot:",
        bloomwellPrice: "Bloomwell:",

        // Manual Input Labels
        guildLevel: "Guild Level:",
        guildNexusCrystalLevel: "Nexus Crystal Level:",
        guildManaTax: "Guild Mana Tax:",
        guildResourceTax: "Guild Resource Tax:",
        guildShardTax: "Guild Shard Tax:",
        wisdomPotionLevel: "Wisdom Potion Level:",
        harvestingPotionLevel: "Harvesting Potion Level:",
        resonancePotionLevel: "Resonance Potion Level:",
        
        // Calculator Buttons
        getAllCurrentValues: "Get current data:",
        calculateCombat: "Combat Calculation:",
        calculateCombatEfficiency: "Calculate Combat Efficiency",
        calculateGathering: "Gathering Efficiency:",
        calculateGatheringEfficiency: "Calculate Gathering Efficiency",
        calculateResonance: "Optimal Resonance Potion Level:",
        calculateLevel: "Calculate Level",
        calculateROI: "Gathering ROI:",
        calculateGatheringROI: "Calculate Gathering ROI",
        calculateGatherEquip: "Gathering Equipment Replacement:",
        detectGatherEquip: "Detect Gather Equip Replace",
        calculateBattleEquip: "Battle Equipment Replacement:",
        detectBattleEquip: "Detect Battle Equip Replace",
        
        // Select Options
        miningOption: "Mining",
        fishingOption: "Fishing",
        woodcuttingOption: "Woodcutting",

        // Messages
        enterPlayerNameError: "Please enter a player name",
        fetchingData: "Fetching data...",
        fetchDataError: "Failed to fetch data. Possible reasons: 1. API is temporarily unavailable 2. Player name does not exist 3. Network connection issue",
        fetchSuccess: "Data fetched successfully!",
        showExampleData: "Showing example data",
        loadSavedData: "Loading saved data for user: ",

        // Calculation Results
        currentDataSnapshot: "Current data snapshot. If there are large discrepancies, please check if the content here is correct:",
        basicInfoTitle: "Basic Info:",
        skillLevels: "Skill Levels: Mining \${miningLevel} Fishing \${fishingLevel} Woodcutting \${woodcuttingLevel}",
        gatheringBoostsTitle: "Gathering Boosts:",
        baseResourceAmount: "Base Resource Amount: \${baseResourceAmountTotal}",
        codexBoostsTitle: "Codex Boosts:",
        equipmentBoostsTitle: "Equipment Boosts:",
        farmSystemTitle: "Farm System:",
        herbHarvest: "Herb Harvest: \${farmHerbHarvest}/h, Tax: \${farmTax}/h",
        marketPricesTitle: "Market Prices:",
        manualInputTitle: "Manual Input:",
        guildTaxRates: "Guild Mana Tax: \${guildManaTax}%, Guild Resource Tax: \${guildResonanceTax}%, Guild Shard Tax: \${guildShardTax}%",
        potionLevels: "Wisdom Potion Level: \${wisdomPotionLevel}, Harvesting Potion Level: \${harvestingPotionLevel}",
        manaPerDay: "Mana Dust per day",
        shardRangePerAction: "Shards per action (after tax)",
        shardsPerDay: "Shards per day",
        shardsDailyValue: "Shards daily value",
        sagerootHourlyProduction: "Sageroot hourly production",
        bloomwellHourlyProduction: "Bloomwell hourly production",
        sagerootHourlyConsumption: "Sageroot hourly consumption",
        bloomwellHourlyConsumption: "Bloomwell hourly consumption",
        sagerootNetProduction: "Sageroot net hourly production",
        bloomwellNetProduction: "Bloomwell net hourly production",
        sagerootDailyProfit: "Sageroot daily net profit",
        bloomwellDailyProfit: "Bloomwell daily net profit",
        farmDailyMaintenance: "Farm daily maintenance cost",
        farmDailyValue: "Farm daily value",
        dailyIncome: "Daily income",
        resourcePerAction: "Resource per action:",
        resourcePerDay: "Resource per day:",
        resourcePrice: "Resource price:",
        resourceDailyValue: "Resource daily value:",
        optimalResonanceLevel: "Optimal Resonance Potion Level:",
        comparedToLevel0: "Compared to level 0 potion",
        extraFarmConsumption: "Extra farm consumption:",
        extraIncome: "Extra income:",
        increasedIncome: "Increased income:",
        gatheringROIComparison: "\${gatheringType} Investment ROI Comparison:",
        cost: "Cost:",
        extraDailyProfit: "Extra Daily Profit:",
        investments: {
            research: "Research Boost 3000 levels",
            baseResource: "Base Resource 100 levels",
            codexBase: "Codex Base Resource 5 levels",
            potion: "Potion Boost 5 levels",
            codexDrop: "Codex Drop Rate 5 levels",
            farm: "Farm total 300 levels"
        },
        gatherEquipReplaceTitle: "Gathering Equipment Replacement",
        gatherEquipReplaceDesc: "Check current equipment and harvesting potion level to see if any base resource gear can be replaced with elemental shard gear (calculates for the lowest value item).",
        noBaseResourceEquip: "No base resource equipment found, ending check.",
        currentPotionLevel: "Current potion level:",
        newPotionLevel: "New potion level after replacement:",
        canReplaceGatherEquip: "Current base resource equipment: \${name} can be replaced with elemental shard equipment.",
        baseResourceAmountLost: "Base resource amount from equipment: \${amount}, can be replaced with elemental shard boost \${shardBoost}%",
        manaIncreaseAfterReplace: "Daily mana dust increase after replacement",
        farmCostIncreaseAfterReplace: "Daily farm cost increase after replacement",
        incomeIncreaseAfterReplace: "Daily income increase after replacement",
        cannotReplaceGatherEquip: "It seems replacement is not beneficial with the current potion level and gear. Ending check.",
        battleEquipReplaceTitle: "Battle Equipment Replacement",
        battleEquipReplaceDesc: "Check current equipment and wisdom potion level to see if any experience gear can be replaced with mana dust/elemental shard gear (calculates for the lowest value item).",
        noExpEquip: "No experience boost equipment found, ending check.",
        canReplaceBattleEquipToMana: "Current experience equipment: \${name} can be replaced with mana dust equipment.",
        canReplaceBattleEquipToShard: "Current experience equipment: \${name} can be replaced with elemental shard equipment.",
        cannotReplaceBattleEquip: "It seems replacement is not beneficial with the current potion level and gear. Ending check."
    },
    zh: {
        // General UI
        langToggle: "中/EN",
        fetchData: "获取数据",
        updateData: "更新数据",
        playerNamePlaceholder: "输入玩家名称或ID",
        getPlayerData: "📊 获取玩家数据",
        dataCalculator: "🧮 数据计算器",
        usageNoteTitle: "使用说明:",
        usageNote: "填完必要的数据后,先点击“更新数据”按钮,再点击其他计算按钮。",
        mainTitle: "🏰 Manarion 数据计算器", 

        // Titles
        basicInfo: "基本信息",
        gatheringBoosts: "采集加成",
        codexBoosts: "法典加成",
        otherEquipmentBoosts: "其他装备加成",
        farm: "农场",
        marketPrice: "市场价格",
        needToSupplement: "需要自己补充的内容",

        // Basic Info Labels
        playerName: "玩家名:",
        currentEnemy: "当前敌人:",
        battleLevel: "战斗等级:",
        miningLevel: "挖矿等级:",
        fishingLevel: "钓鱼等级:",
        woodcuttingLevel: "伐木等级:",

        // Gathering Boosts Labels
        mining: "挖矿:",
        fishing: "钓鱼:",
        woodcutting: "伐木:",
        baseResourceBoost: "基础资源量:",

        // Codex Boosts Labels
        codexManaDust: "魔法尘:",
        codexBaseResource: "基础资源量:",
        codexDropBoost: "掉落加成:",

        // Other Equipment Boosts Labels
        manaBoost: "魔法尘:",
        shardBoost: "元素碎片:",
        potionBoost: "药水效果:",

        // Farm Labels
        harvestGolem: "收获傀儡:",
        fertilizer: "肥料:",
        farmPlots: "地块:",
        farmHerbHarvest: "草药收获:",
        farmTax: "税收:",

        // Market Price Labels
        shardPrice: "元素碎片:",
        codexPrice: "法典:",
        fishPrice: "鱼:",
        woodPrice: "木:",
        ironPrice: "铁:",
        sagerootPrice: "智慧之根:",
        bloomwellPrice: "繁茂精华:",

        // Manual Input Labels
        guildLevel: "工会等级:",
        guildNexusCrystalLevel: "连结水晶等级:",
        guildManaTax: "工会魔法尘税率:",
        guildResourceTax: "工会资源税率:",
        guildShardTax: "工会碎片税率:",
        wisdomPotionLevel: "智慧药水等级:",
        harvestingPotionLevel: "收获药水等级:",
        resonancePotionLevel: "回响药水等级:",

        // Calculator Buttons
        getAllCurrentValues: "获取当前所有数据:",
        calculateCombat: "战斗计算:",
        calculateCombatEfficiency: "计算战斗效率",
        calculateGathering: "采集效率计算:",
        calculateGatheringEfficiency: "计算采集效率",
        calculateResonance: "回响药水最佳等级计算:",
        calculateLevel: "计算等级",
        calculateROI: "采集投资回报率计算:",
        calculateGatheringROI: "计算采集投资回报率",
        calculateGatherEquip: "采集装备替换检测:",
        detectGatherEquip: "检测采集装备替换",
        calculateBattleEquip: "战斗装备替换检测:",
        detectBattleEquip: "检测战斗装备替换",

        // Select Options
        miningOption: "挖矿",
        fishingOption: "钓鱼",
        woodcuttingOption: "伐木",

        // Messages
        enterPlayerNameError: "请输入玩家名称",
        fetchingData: "正在获取数据...",
        fetchDataError: "无法获取数据。可能原因:1. API暂时不可用 2. 玩家名称不存在 3. 网络连接问题",
        fetchSuccess: "数据获取成功!",
        showExampleData: "显示示例数据",
        loadSavedData: "加载已保存的数据 用户名: ",

        // Calculation Results
        currentDataSnapshot: "当前数据快照, 如有大出入,请检查这里的内容是否正确:",
        basicInfoTitle: "基础信息:",
        skillLevels: "技能等级: 挖矿\${miningLevel} 钓鱼\${fishingLevel} 伐木\${woodcuttingLevel}",
        gatheringBoostsTitle: "采集加成:",
        baseResourceAmount: "基础资源量: \${baseResourceAmountTotal}",
        codexBoostsTitle: "法典加成:",
        equipmentBoostsTitle: "装备加成:",
        farmSystemTitle: "农场系统:",
        herbHarvest: "草药收获: \${farmHerbHarvest}/h, 税收: \${farmTax}/h",
        marketPricesTitle: "市场价格:",
        manualInputTitle: "手动输入信息:",
        guildTaxRates: "工会魔法尘税率: \${guildManaTax}%, 工会资源税率: \${guildResonanceTax}%, 工会碎片税率: \${guildShardTax}%",
        potionLevels: "智慧药水等级: \${wisdomPotionLevel}, 收获药水等级: \${harvestingPotionLevel}",
        manaPerDay: "魔法尘每天",
        shardRangePerAction: "税后每动作碎片范围",
        shardsPerDay: "碎片每天",
        shardsDailyValue: "碎片每天价值",
        sagerootHourlyProduction: "慧根每小时产出",
        bloomwellHourlyProduction: "繁茂每小时产出",
        sagerootHourlyConsumption: "慧根每小时消耗",
        bloomwellHourlyConsumption: "繁茂每小时消耗",
        sagerootNetProduction: "慧根每小时净产出",
        bloomwellNetProduction: "繁茂每小时净产出",
        sagerootDailyProfit: "慧根每日净利",
        bloomwellDailyProfit: "繁茂每日净利",
        farmDailyMaintenance: "农场每日维护费",
        farmDailyValue: "农场每天价值",
        dailyIncome: "每日收入",
        resourcePerAction: "资源每动作:",
        resourcePerDay: "资源每天:",
        resourcePrice: "资源价格:",
        resourceDailyValue: "资源每天价值:",
        optimalResonanceLevel: "最佳的碎片药水等级:",
        comparedToLevel0: "相对0级药水",
        extraFarmConsumption: "额外的农场消耗量:",
        extraIncome: "额外的收益:",
        increasedIncome: "提升的收益:",
        gatheringROIComparison: "\${gatheringType} 投资回报率对比:",
        cost: "成本:",
        extraDailyProfit: "额外日收益:",
        investments: {
            research: "研究加成3000级",
            baseResource: "基础资源100级",
            codexBase: "法典基础5级",
            potion: "药水加成5级",
            codexDrop: "法典掉落5级",
            farm: "农场总共提升300级"
        },
        gatherEquipReplaceTitle: "采集装备替换说明",
        gatherEquipReplaceDesc: "检查当前身上的装备,目前使用的收获药水等级,计算是否有基础资源装备可以被替换为元素碎片装备(每次只会计算最小数值的装备)",
        noBaseResourceEquip: "当前没有找到基础资源加成装备,结束",
        currentPotionLevel: "当前使用的药水等级:",
        newPotionLevel: "替换后使用的药水等级:",
        canReplaceGatherEquip: "当前基础资源加成装备:\${name} 可以被替换为 elemental shard 装备",
        baseResourceAmountLost: "当前基础资源加成装备基础资源量: \${amount} 可以被替换为元素碎片加成 \${shardBoost}%",
        manaIncreaseAfterReplace: "替换后每日魔法尘增加",
        farmCostIncreaseAfterReplace: "替换后每日农场支出增加",
        incomeIncreaseAfterReplace: "替换后每日收入增加",
        cannotReplaceGatherEquip: "看起来现在的药水等级+基础资源装情况,替换不了呢。结束",
        battleEquipReplaceTitle: "战斗装备替换说明",
        battleEquipReplaceDesc: "检查当前身上的装备,目前使用的智慧药水等级,计算是否有经验装备可以被替换为魔法尘/元素碎片装备(每次只会计算最小数值的装备)",
        noExpEquip: "当前没有找到经验加成装备,结束",
        canReplaceBattleEquipToMana: "当前经验加成装备:\${name} 可以被替换为 mana dust 装备",
        canReplaceBattleEquipToShard: "当前经验加成装备:\${name} 可以被替换为 elemental shard 装备",
        cannotReplaceBattleEquip: "看起来现在的药水等级+经验装情况,替换不了呢。结束"
    }
};

function setLanguage(lang) {
    currentLanguage = lang;
    localStorage.setItem('manarion-language', lang);
    updateUIForLanguage();
    // Re-render data if it exists
    if (globalPlayerData) {
        displayData(globalPlayerData, globalMarketData);
    }
    if (document.getElementById('calcResults').innerHTML.trim() !== '') {
        getAllCurrentValues();
    }
}

function toggleLanguage() {
    const newLang = currentLanguage === 'zh' ? 'en' : 'zh';
    setLanguage(newLang);
}

//#region UI language
function updateUIForLanguage() {
    const t = translations[currentLanguage];
    document.querySelectorAll('[data-translate-key]').forEach(element => {
        const key = element.dataset.translateKey;
        // 确保key存在于翻译对象中
        if (t && t[key]) {
            const translation = t[key];
            
            // 根据元素类型设置不同的属性
            if (element.tagName === 'INPUT') {
                if(element.type === 'button' || element.type === 'submit' || element.type === 'reset') {
                     element.value = translation;
                } else {
                     element.placeholder = translation;
                }
            } else if (element.tagName === 'OPTION') {
                 element.textContent = translation;
            } else if (element.tagName === 'TITLE') {
                element.textContent = translation;
            }
            else {
                // 适用于 <h1>, <button>, <span>, <strong>, <label>, <h3> 等
                element.innerHTML = translation;
            }
        }
    });
}

//#region Theme
function setTheme(theme) {
    localStorage.setItem('manarion-theme', theme);
    currentTheme = theme;

    const themeIcon = document.getElementById('themeIcon');
    if (theme === 'dark') {
        document.body.classList.add('dark');
        if (themeIcon) themeIcon.innerHTML = '☀️'; // Sun icon for switching to light mode
    } else {
        document.body.classList.remove('dark');
        if (themeIcon) themeIcon.innerHTML = '🌙'; // Moon icon for switching to dark mode
    }
}

function toggleTheme() {
    const newTheme = currentTheme === 'light' ? 'dark' : 'light';
    setTheme(newTheme);
}

//#region  global data
function loadGlobalData() {
    try {
        const savedValues = localStorage.getItem('manarion-values');
        const savedPlayerData = localStorage.getItem('manarion-player-data');
        const savedMarketData = localStorage.getItem('manarion-market-data');
        if (savedValues) {
            values = JSON.parse(savedValues);
            console.log('✅ manarion_helper_values LOAD');
            if (values && values.ui) {
                const gatheringType1 = document.getElementById('gatheringType');
                const gatheringType2 = document.getElementById('gatheringType2');
                if (gatheringType1 && values.ui.lastGatheringType) {
                    gatheringType1.value = values.ui.lastGatheringType;
                }
                if (gatheringType2 && values.ui.lastGatheringType2) {
                    gatheringType2.value = values.ui.lastGatheringType2;
                }
            }
        }
        if (savedPlayerData) {
            globalPlayerData = JSON.parse(savedPlayerData);
            const playerNameInput = document.getElementById('playerName');
            if (playerNameInput && globalPlayerData.Name) {
                playerNameInput.value = globalPlayerData.Name;
            }
            console.log('✅ manarion_helper_player_data LOAD');
        }
        if (savedMarketData) {
            globalMarketData = JSON.parse(savedMarketData);
            console.log('✅ manarion_helper_market_data LOAD');
        }
    } catch (error) {
        console.log('❌ manarion_helper_load_data ERROR');
    }
}

function saveGlobalData() {
    try {
        if (values !== null) {
            localStorage.setItem('manarion-values', JSON.stringify(values));
        }
        if (globalPlayerData !== null) {
            localStorage.setItem('manarion-player-data', JSON.stringify(globalPlayerData));
        }
        if (globalMarketData !== null) {
            localStorage.setItem('manarion-market-data', JSON.stringify(globalMarketData));
        }
        console.log('💾 marion_helper_save_data SUCCESS');
    } catch (error) {
        console.log('❌ manarion_helper_save_data ERROR');
    }
}

function removeGlobalData() {
    try {
        localStorage.removeItem('manarion-values');
        localStorage.removeItem('manarion-player-data');
        localStorage.removeItem('manarion-market-data');
        globalMarketData = null;
        globalPlayerData = null;
        values = null;
        console.log('💾 manarion_helper_remove_data SUCCESS');
    } catch (error) {
        console.log('❌ manarion_helper_remove_data ERROR');
    }
}

async function fetchPlayerData() {
    const playerName = document.getElementById('playerName').value.trim();
    let data = null, marketData = null;
    if (!playerName) {
        showMessage(translations[currentLanguage].enterPlayerNameError, 'error');
        return;
    }
    
    showMessage(translations[currentLanguage].fetchingData, 'loading');
    
    try {
        const playerUrl = \`https://api.manarion.com/players/\${encodeURIComponent(playerName)}\`;
        
        data = await window.fetchDataWithGM(playerUrl);
        
    } catch (error) {
        console.error('获取数据失败:', error);
        showExampleData();
        showMessage(translations[currentLanguage].fetchDataError, 'error');
        return;
    }
    
    marketData = await fetchMarketData();
    showMessage(translations[currentLanguage].fetchSuccess, 'success');
    globalPlayerData = data;
    displayData(data, marketData);
    saveGlobalData();
}

async function fetchMarketData() {
    try {
        const marketUrl = 'https://api.manarion.com/market';
        const marketData = await window.fetchDataWithGM(marketUrl);
        globalMarketData = marketData;
        return marketData;
    } catch (error) {
        console.warn('获取市场价格失败:', error);
        return null;
    }
}

// region example data
function showExampleData() {
    const examplePlayerData = {"ID":2582,"Banned":false,"Title":"Scholar","TitleColor":"#b1d852","Name":"LemonApostle","ProfileText":"","Level":2269,"Zone":"blazing_core","Enemy":58000,"MagicType":"water","ActionType":"battle","MiningLevel":636,"FishingLevel":2442,"WoodcuttingLevel":701,"GatherActions":1599128,"Kills":241570,"Deaths":821,"EventActions":138637,"EventPoints":10867920.089814264,"BattleQuestNumber":415,"GatherQuestNumber":903,"BaseBoosts":{"1":1600,"100":100,"101":17,"102":13,"103":16,"105":0,"106":0,"108":85,"11":724583,"124":1800,"130":2600,"131":2600,"132":2600,"133":17,"140":416,"141":27,"142":2,"143":0,"144":0,"145":0,"146":0,"2":1800,"22":13,"23":6,"24":11,"3":19047,"30":1100,"31":69562,"32":500,"4":19112,"40":36000,"41":26000,"42":36000,"43":36000,"44":26000,"45":36000,"46":40000,"47":36000,"48":31000,"49":22000,"5":19194,"50":36000,"6":19246,"69":1,"7":18966,"70":1},"TotalBoosts":{"1":1600,"10":0,"100":299,"101":56,"102":52,"103":55,"105":0,"106":0,"107":0,"108":231,"11":763724,"12":0,"120":4683,"121":1398,"122":0,"123":0,"124":1800,"130":2600,"131":2600,"132":2600,"133":17,"140":416,"141":27,"142":2,"143":0,"144":0,"145":0,"146":0,"2":1800,"21":0,"22":13,"23":6,"24":11,"3":118166.33,"30":1.6534,"31":42.319828,"32":1.297,"4":101749.68000000001,"40":46.6062,"41":25.868000000000002,"42":29.2158,"43":36.0982,"44":16.444000000000003,"45":29.253,"46":24.76,"47":41.803,"48":19.414,"49":31.699399999999997,"5":96850.66,"50":46.2424,"6":101426.94,"60":0,"61":0,"62":0,"63":0,"64":0,"65":0,"66":0,"67":0,"68":0,"69":1,"7":84603.74,"70":1,"71":0,"8":2666813,"80":0,"81":39,"82":0,"83":38,"84":0,"85":0,"86":39,"9":2535942},"SigilBoost":108,"GuildID":86,"LastFatigue":1753980262,"UnfatiguedStreak":492529,"HighestEnemy":58000,"Equipment":{"1":{"ID":5025890,"Name":"Heirloom Staff of Water +16 (3046)","IsEquipped":true,"Level":3046,"Rarity":6,"Slot":1,"Boosts":{"11":21745,"120":562,"3":11089,"40":27909,"41":26178,"5":12022,"6":10837,"8":770006,"81":39},"Quality":0.99403,"UpgradeChance":0.04681,"Infusions":16},"2":{"ID":4951400,"Name":"Heirloom Robes +14 (2492)","IsEquipped":true,"Level":2492,"Rarity":6,"Slot":2,"Boosts":{"101":39,"121":466,"4":8821,"49":22310,"50":22010,"6":8642,"7":9083,"9":108884},"Quality":0.99292,"UpgradeChance":0.04852,"Infusions":14},"3":{"ID":4969542,"Name":"Heirloom Sandals +14 (2163)","IsEquipped":true,"Level":2163,"Rarity":6,"Slot":3,"Boosts":{"103":39,"120":401,"3":7623,"40":18591,"43":18751,"6":8244,"7":9253,"9":85431},"Quality":0.99324,"UpgradeChance":0.04643,"Infusions":14},"4":{"ID":4940806,"Name":"Heirloom Gloves +14 (2149)","IsEquipped":true,"Level":2149,"Rarity":6,"Slot":4,"Boosts":{"102":39,"121":400,"3":7535,"4":7931,"42":19947,"50":18620,"6":7661,"9":90438},"Quality":0.99402,"UpgradeChance":0.04116,"Infusions":14},"5":{"ID":4937498,"Name":"Heirloom Hood +15 (2167)","IsEquipped":true,"Level":2167,"Rarity":6,"Slot":5,"Boosts":{"100":39,"120":388,"3":7516,"43":19540,"47":18825,"5":8153,"6":7681,"9":88907},"Quality":0.99269,"UpgradeChance":0.0501,"Infusions":15},"6":{"ID":5030783,"Name":"Heirloom Cloak +16 (3057)","IsEquipped":true,"Level":3057,"Rarity":6,"Slot":6,"Boosts":{"120":547,"3":10676,"4":10889,"49":27906,"5":10830,"50":27901,"83":38,"9":152982},"Quality":0.99299,"UpgradeChance":0.048,"Infusions":16},"7":{"ID":4954354,"Name":"Heirloom Pendant +14 (2181)","IsEquipped":true,"Level":2181,"Rarity":6,"Slot":7,"Boosts":{"120":418,"3":7997,"4":8307,"45":20203,"47":18226,"7":8001},"Quality":0.99343,"UpgradeChance":0.03895,"Infusions":14},"8":{"ID":4921970,"Name":"Heirloom Ring +14 (2169)","IsEquipped":true,"Level":2169,"Rarity":6,"Slot":8,"Boosts":{"120":364,"4":7639,"40":23101,"47":19511,"5":8689,"7":7923,"86":39},"Quality":0.99264,"UpgradeChance":0.04351,"Infusions":14}}};
    const exampleMarketData = {"Buy":{"10":5100000,"11":4050000,"12":2250000,"13":40410105,"14":33000000,"15":39700001,"16":1902328816,"17":12000000000,"18":6060000009,"19":1402439508,"2":1091,"20":13072500002,"21":13261300010,"22":1800000000,"23":2049999999,"24":1040300000,"25":502000000,"26":2750000000,"27":431000000,"28":800000000,"29":6250000,"3":16000000105,"30":2400006,"31":3300000,"32":7777778,"33":30500009,"34":11250000,"35":6920016671,"36":17220500000,"37":40150000000,"39":25000009,"4":11000009,"40":980000,"41":999500,"44":27500000015,"45":313000000000,"46":796001001,"47":7885373010,"5":12625009,"50":4500000000000,"6":8010009,"7":407,"8":377,"9":387},"Sell":{"10":15000000,"11":37000000,"12":17641798,"13":41550000,"14":39589994,"15":42000000,"16":2000000000,"17":14199000000,"18":25000000000,"19":4257000000,"2":1232,"20":1000000000000,"21":99000000000,"22":4514801227,"23":2305430421,"24":1900000000,"25":790000000,"26":7920000000,"27":633977685,"28":1300000000,"29":21000000,"3":16416671000,"30":10500000,"31":14900000,"32":41250000,"33":74979999,"34":35000000,"35":8035830000,"36":19999999990,"37":57247631000,"39":67320000,"4":69000000,"40":1127114,"41":1000000,"44":38999999999,"45":361000000000,"46":835000000,"47":8612000000,"5":60000000,"50":21900000000000,"6":66000000,"7":503,"8":409,"9":402}};
    let displayExampleData = false;

    if(globalPlayerData == null){
        globalPlayerData = examplePlayerData;
        displayExampleData = true;

    }
    if(globalMarketData == null){
        globalMarketData = exampleMarketData;
        displayExampleData = true;
    }

    displayData(globalPlayerData, globalMarketData);
    
    const t = translations[currentLanguage];
    if(displayExampleData){
        showMessage(t.showExampleData, 'success');
    } else {
        showMessage(t.loadSavedData + globalPlayerData.Name, 'success');
    }

}


function showMessage(message, type) {
    const messageDiv = document.getElementById('message');
    messageDiv.innerHTML = \`<div class="\${type}">\${message}</div>\`;
}

// region show data
function displayData(playerData, marketData) {
    document.getElementById('playerData').style.display = 'block';
    
    const t = translations[currentLanguage];

    document.getElementById('basicInfo').innerHTML = \`
        <div class="stat-row"><span class="stat-label">\${t.playerName}</span> <span class="stat-value">\${playerData.Name}</span></div>
        <div class="stat-row"><span class="stat-label">\${t.currentEnemy}</span> <input type="number" class="stat-input" value="\${playerData.Enemy || 0}" id="currentEnemy"></div>
        <div class="stat-row"><span class="stat-label">\${t.battleLevel}</span> <input type="number" class="stat-input" value="\${playerData.Level || 0}" id="battleLevel"></div>
        <div class="stat-row"><span class="stat-label">\${t.miningLevel}</span> <input type="number" class="stat-input" value="\${playerData.MiningLevel || 0}" id="miningLevel"></div>
        <div class="stat-row"><span class="stat-label">\${t.fishingLevel}</span> <input type="number" class="stat-input" value="\${playerData.FishingLevel || 0}" id="fishingLevel"></div>
        <div class="stat-row"><span class="stat-label">\${t.woodcuttingLevel}</span> <input type="number" class="stat-input" value="\${playerData.WoodcuttingLevel || 0}" id="woodcuttingLevel"></div>
    \`;

    document.getElementById('gatheringBoosts').innerHTML = \`
        <div class="stat-row"><span class="stat-label">\${t.mining}</span> <input type="number" class="stat-input" value="\${((playerData.TotalBoosts['30'] - 1 || 0) * 100).toFixed(2)}" id="miningBoost"><span style="margin-left: 4px;">%</span></div>
        <div class="stat-row"><span class="stat-label">\${t.fishing}</span> <input type="number" class="stat-input" value="\${((playerData.TotalBoosts['31'] - 1 || 0) * 100).toFixed(2)}" id="fishingBoost"><span style="margin-left: 4px;">%</span></div>
        <div class="stat-row"><span class="stat-label">\${t.woodcutting}</span> <input type="number" class="stat-input" value="\${((playerData.TotalBoosts['32'] - 1 || 0) * 100).toFixed(2)}" id="woodcuttingBoost"><span style="margin-left: 4px;">%</span></div>
        <div class="stat-row"><span class="stat-label">\${t.baseResourceBoost}</span> <input type="number" class="stat-input" value="\${((playerData.TotalBoosts['124'] || 0) /100).toFixed(2)}" id="baseResourceBoost"></div>
    \`;
    
    document.getElementById('codexBoosts').innerHTML = \`
        <div class="stat-row"><span class="stat-label">\${t.codexManaDust}</span> <input type="number" class="stat-input" value="\${playerData.TotalBoosts['101'] || 0}" id="codexManaDust"><span style="margin-left: 4px;">%</span></div>
        <div class="stat-row"><span class="stat-label">\${t.codexBaseResource}</span> <input type="number" class="stat-input" value="\${playerData.TotalBoosts['106'] || 0}" id="codexBaseResource"><span style="margin-left: 4px;">%</span></div>
        <div class="stat-row"><span class="stat-label">\${t.codexDropBoost}</span> <input type="number" class="stat-input" value="\${playerData.TotalBoosts['102'] || 0}" id="codexDropBoost"><span style="margin-left: 4px;">%</span></div>
    \`;
    
    document.getElementById('otherEquipmentBoosts').innerHTML = \`
        <div class="stat-row"><span class="stat-label">\${t.manaBoost}</span> <input type="number" class="stat-input" value="\${(playerData.TotalBoosts['121'] || 0)}" id="manaBoost"><span style="margin-left: 4px;">%</span></div>
        <div class="stat-row"><span class="stat-label">\${t.shardBoost}</span> <input type="number" class="stat-input" value="\${playerData.TotalBoosts['122'] || 0}" id="shardBoost"><span style="margin-left: 4px;">%</span></div>
        <div class="stat-row"><span class="stat-label">\${t.potionBoost}</span> <input type="number" class="stat-input" value="\${playerData.TotalBoosts['108'] || 0}" id="potionBoost"><span style="margin-left: 4px;">%</span></div>
    \`;

    document.getElementById('farmBoosts').innerHTML = \`
        <div class="stat-row"><span class="stat-label">\${t.harvestGolem}</span> <input type="number" class="stat-input" value="\${playerData.TotalBoosts['130'] || 0}" id="harvestGolem"></div>
        <div class="stat-row"><span class="stat-label">\${t.fertilizer}</span> <input type="number" class="stat-input" value="\${playerData.TotalBoosts['131'] || 0}" id="fertilizer"></div>
        <div class="stat-row"><span class="stat-label">\${t.farmPlots}</span> <input type="number" class="stat-input" value="\${playerData.TotalBoosts['132'] || 0}" id="farmPlots"></div>
        <div class="stat-row"><span class="stat-label">\${t.farmHerbHarvest}</span> <input type="number" class="stat-input" value="\${(2.5 * (1 + playerData.TotalBoosts['130']/100)**0.9 * (1 + playerData.TotalBoosts['131']/100)**0.9 * (1 + playerData.TotalBoosts['132']/100)**0.9).toFixed(0) || 0}" id="farmHerbHarvest"><span style="margin-left: 4px;">/h</span></div>
        <div class="stat-row"><span class="stat-label">\${t.farmTax}</span> <input type="number" class="stat-input" value="\${(2.5 * (1 + playerData.TotalBoosts['130']/100)**0.9 * (1 + playerData.TotalBoosts['131']/100)**0.9 * (1 + playerData.TotalBoosts['132']/100)**0.9*200000).toFixed(0) || 0}" id="farmTax"><span style="margin-left: 4px;">/h</span></div>
    \`;
    
    document.getElementById('marketPrice').innerHTML = \`
        <div class="stat-row"><span class="stat-label">\${t.shardPrice}</span> <input type="number" class="stat-input" value="\${marketData.Sell['2'] || 0}" id="shardPrice"></div>
        <div class="stat-row"><span class="stat-label">\${t.codexPrice}</span> <input type="number" class="stat-input" value="\${marketData.Sell['3'] || 0}" id="codexPrice"></div>
        <div class="stat-row"><span class="stat-label">\${t.fishPrice}</span> <input type="number" class="stat-input" value="\${marketData.Sell['7'] || 0}" id="fishPrice"></div>
        <div class="stat-row"><span class="stat-label">\${t.woodPrice}</span> <input type="number" class="stat-input" value="\${marketData.Sell['8'] || 0}" id="woodPrice"></div>
        <div class="stat-row"><span class="stat-label">\${t.ironPrice}</span> <input type="number" class="stat-input" value="\${marketData.Sell['9'] || 0}" id="ironPrice"></div>
        <div class="stat-row"><span class="stat-label">\${t.sagerootPrice}</span> <input type="number" class="stat-input" value="\${marketData.Sell['40'] || 0}" id="sagerootPrice"></div>
        <div class="stat-row"><span class="stat-label">\${t.bloomwellPrice}</span> <input type="number" class="stat-input" value="\${marketData.Sell['41'] || 0}" id="bloomwellPrice"></div>
    \`;

    document.getElementById('needToSupplement').innerHTML = \`
        <div class="stat-row"><span class="stat-label">\${t.guildLevel}</span> <input type="number" class="stat-input" value="\${values?.guild?.guildLevel || 100}" id="guildLevel"></div>
        <div class="stat-row"><span class="stat-label">\${t.guildNexusCrystalLevel}</span> <input type="number" class="stat-input" value="\${values?.guild?.guildNexusCrystalLevel || 100}" id="guildNexusCrystalLevel"></div>
        <div class="stat-row"><span class="stat-label">\${t.guildManaTax}</span> <input type="number" class="stat-input" value="\${values?.guild?.guildManaTax || 10}" id="guildManaTax"><span style="margin-left: 4px;">%</span></div>
        <div class="stat-row"><span class="stat-label">\${t.guildResourceTax}</span> <input type="number" class="stat-input" value="\${values?.guild?.guildResonanceTax || 60}" id="guildResourceTax"><span style="margin-left: 4px;">%</span></div>
        <div class="stat-row"><span class="stat-label">\${t.guildShardTax}</span> <input type="number" class="stat-input" value="\${values?.guild?.guildShardTax || 10}" id="guildShardTax"><span style="margin-left: 4px;">%</span></div>
        <div class="stat-row"><span class="stat-label">\${t.wisdomPotionLevel}</span> <input type="number" class="stat-input" value="\${values?.guild?.wisdomPotionLevel || 10}" id="wisdomPotionLevel"></div>
        <div class="stat-row"><span class="stat-label">\${t.harvestingPotionLevel}</span> <input type="number" class="stat-input" value="\${values?.guild?.harvestingPotionLevel || 10}" id="harvestingPotionLevel"></div>
        <div class="stat-row"><span class="stat-label">\${t.resonancePotionLevel}</span> <input type="number" class="stat-input" value="\${values?.guild?.resonancePotionLevel || 10}" id="resonancePotionLevel"></div>
    \`;
}

//#region getvalue
function getAllCurrentValues() {
    values = {
        basic: {
            battleLevel: getValue('battleLevel'),
            currentEnemy: getValue('currentEnemy'),
            miningLevel: getValue('miningLevel'),
            fishingLevel: getValue('fishingLevel'),
            woodcuttingLevel: getValue('woodcuttingLevel')
        },
        gathering: {
            miningBoost: getValue('miningBoost'),
            fishingBoost: getValue('fishingBoost'),
            woodcuttingBoost: getValue('woodcuttingBoost'),
            miningBaseBoost: globalPlayerData.BaseBoosts['30'],
            fishingBaseBoost: globalPlayerData.BaseBoosts['31'],
            woodcuttingBaseBoost: globalPlayerData.BaseBoosts['32'],
            baseResourceAmountTotal: getValue('baseResourceBoost'),
            baseResourceAmountBase: globalPlayerData.BaseBoosts['124']
        },
        codex: {
            codexManaDust: getValue('codexManaDust'),
            codexBaseResource: getValue('codexBaseResource'),
            codexDropBoost: getValue('codexDropBoost'),
            codexBaseResourceBase: globalPlayerData.BaseBoosts['106'],
            codexDropBoostBase: globalPlayerData.BaseBoosts['102']
        },
        equipment: {
            manaBoost: getValue('manaBoost'),
            shardBoost: getValue('shardBoost'),
            potionBoost: getValue('potionBoost'),
            potionBoostBase: globalPlayerData.BaseBoosts['108']
        },
        farm: {
            harvestGolem: getValue('harvestGolem'),
            fertilizer: getValue('fertilizer'),
            farmPlots: getValue('farmPlots'),
            farmHerbHarvest: getValue('farmHerbHarvest'),
            farmTax: getValue('farmTax')
        },
        market: {
            codexPrice: getValue('codexPrice'),
            fishPrice: getValue('fishPrice'),
            woodPrice: getValue('woodPrice'),
            ironPrice: getValue('ironPrice'),
            shardPrice: getValue('shardPrice'),
            sagerootPrice: getValue('sagerootPrice'),
            bloomwellPrice: getValue('bloomwellPrice')
        },
        guild: {
            guildLevel: getValue('guildLevel'),
            guildNexusCrystalLevel: getValue('guildNexusCrystalLevel'),
            guildManaTax: getValue('guildManaTax'),
            guildResonanceTax: getValue('guildResourceTax'),
            guildShardTax: getValue('guildShardTax'),
            wisdomPotionLevel: getValue('wisdomPotionLevel'),
            harvestingPotionLevel: getValue('harvestingPotionLevel'),
            resonancePotionLevel: getValue('resonancePotionLevel')
        }
    };
    
    const t = translations[currentLanguage];
    const skillLevelsText = t.skillLevels
        .replace('\${miningLevel}', values.basic.miningLevel)
        .replace('\${fishingLevel}', values.basic.fishingLevel)
        .replace('\${woodcuttingLevel}', values.basic.woodcuttingLevel);

    document.getElementById('calcResults').innerHTML = \`
        <div class="calc-result">
            <h4>\${t.currentDataSnapshot}</h4>
            <div class="result-content-box">
                <strong>\${t.basicInfoTitle}</strong><br>
                \${t.battleLevel} \${values.basic.battleLevel}, \${t.currentEnemy} \${values.basic.currentEnemy}<br>
                \${skillLevelsText}<br><br>
                
                <strong>\${t.gatheringBoostsTitle}</strong><br>
                \${t.mining} \${values.gathering.miningBoost}%, \${t.fishing} \${values.gathering.fishingBoost}%, \${t.woodcutting} \${values.gathering.woodcuttingBoost}%<br>
                \${t.baseResourceAmount.replace('\${baseResourceAmountTotal}', values.gathering.baseResourceAmountTotal)}<br><br>
                
                <strong>\${t.codexBoostsTitle}</strong><br>
                \${t.codexManaDust} \${values.codex.codexManaDust}%, \${t.codexBaseResource} \${values.codex.codexBaseResource}%, \${t.codexDropBoost} \${values.codex.codexDropBoost}%
                <br><br>
                
                <strong>\${t.equipmentBoostsTitle}</strong><br>
                \${t.manaBoost} \${values.equipment.manaBoost}%, \${t.shardBoost} \${values.equipment.shardBoost}%, \${t.potionBoost} \${values.equipment.potionBoost}%<br><br>
                
                <strong>\${t.farmSystemTitle}</strong><br>
                \${t.harvestGolem} \${values.farm.harvestGolem}, \${t.fertilizer} \${values.farm.fertilizer}, \${t.farmPlots} \${values.farm.farmPlots}<br>
                \${t.herbHarvest.replace('\${farmHerbHarvest}', values.farm.farmHerbHarvest).replace('\${farmTax}', values.farm.farmTax)}<br><br>
                
                <strong>\${t.marketPricesTitle}</strong><br>
                \${t.shardPrice} \${values.market.shardPrice}, \${t.codexPrice} \${values.market.codexPrice} <br>
                \${t.fishPrice} \${values.market.fishPrice}, \${t.woodPrice} \${values.market.woodPrice}, \${t.ironPrice} \${values.market.ironPrice}<br>
                \${t.sagerootPrice} \${values.market.sagerootPrice}, \${t.bloomwellPrice} \${values.market.bloomwellPrice}
                <br><br>
                
                <strong>\${t.manualInputTitle}</strong><br>
                \${t.guildLevel} \${values.guild.guildLevel}, \${t.guildNexusCrystalLevel} \${values.guild.guildNexusCrystalLevel}<br>
                \${t.guildTaxRates.replace('\${guildManaTax}', values.guild.guildManaTax).replace('\${guildResonanceTax}', values.guild.guildResonanceTax).replace('\${guildShardTax}', values.guild.guildShardTax)} <br>
                \${t.potionLevels.replace('\${wisdomPotionLevel}', values.guild.wisdomPotionLevel).replace('\${harvestingPotionLevel}', values.guild.harvestingPotionLevel)}
            </div>
        </div>
    \`;

    saveGlobalData();
}

function getValue(id) {
    const element = document.getElementById(id);
    return element ? (parseFloat(element.value) || 0) : 0;
}

function formatNumber(num) {
    if (num === 0) return '0.00';
    if (isNaN(num) || !isFinite(num)) return 'NaN';
    
    const isNegative = num < 0;
    const absNum = Math.abs(num);
    
    let result;
    if (absNum >= 1e15) {
        result = (absNum / 1e15).toFixed(2) + 'P';
    } else if (absNum >= 1e12) {
        result = (absNum / 1e12).toFixed(2) + 'T';  
    } else if (absNum >= 1e9) {
        result = (absNum / 1e9).toFixed(2) + 'B';   
    } else if (absNum >= 1e6) {
        result = (absNum / 1e6).toFixed(2) + 'M';  
    } else if (absNum >= 1e3) {
        result = (absNum / 1e3).toFixed(2) + 'K'; 
    } else {
        result = absNum.toFixed(2);
    }
    
    return isNegative ? '-' + result : result;
}

//#region shards
function calculateShards(){
    const totalLevel = values.basic.battleLevel*3 + values.basic.miningLevel + values.basic.fishingLevel + values.basic.woodcuttingLevel;
    const MinBaseShard = 100*Math.pow(1+totalLevel/10, 1-0.3*(totalLevel/(totalLevel+20000)));
    const potionShardBoost = 5* (1 + values.equipment.potionBoost/100) * values.guild.resonancePotionLevel;
    const totalShardBoost = values.equipment.shardBoost +  potionShardBoost;
    const minShardPerActionAfterTax = MinBaseShard * (1 + totalShardBoost / 100) * (1 - values.guild.guildShardTax / 100);
    const shardPerActionAfterTax = 1.5 * MinBaseShard * (1 + totalShardBoost / 100) * (1 - values.guild.guildShardTax / 100);
    const shardsPerDayAfterTax = shardPerActionAfterTax * ((1+(values.codex.codexDropBoost/100))*(1/80)*28800);
    const shardDailyValue = shardsPerDayAfterTax * values.market.shardPrice;
    return [shardsPerDayAfterTax, shardDailyValue, minShardPerActionAfterTax];
}

//#region farm
function calculateFarmIncome(){
    //  200k Mana Dust/herb/hr
    const herbsHourHarvestTotal = values.farm.farmHerbHarvest;
    const manaHourConsume = herbsHourHarvestTotal * 200000;
    const sageRootHourHarvest = herbsHourHarvestTotal/2;
    const bloomHourHarvest = herbsHourHarvestTotal/2; 

    const wisdomPotionConsume = values.guild.wisdomPotionLevel * (1+values.guild.wisdomPotionLevel) / 2;
    const harvestingPotionConsume = values.guild.harvestingPotionLevel * (1+values.guild.harvestingPotionLevel) / 2;
    const resonancePotionConsume = values.guild.resonancePotionLevel * (1+values.guild.resonancePotionLevel) / 2;


    const netSageRootGain = sageRootHourHarvest - wisdomPotionConsume - resonancePotionConsume;
    const netBloomGain = bloomHourHarvest - harvestingPotionConsume - resonancePotionConsume;

    const sagePrice = values.market.sagerootPrice;
    const bloomPrice = values.market.bloomwellPrice;
    const sageProfitPerDay = netSageRootGain * sagePrice * 24;
    const bloomProfitPerDay = netBloomGain * bloomPrice * 24;
    const manaConsumePerDay = manaHourConsume * 24;

    return [manaConsumePerDay, sageRootHourHarvest, bloomHourHarvest, (wisdomPotionConsume + resonancePotionConsume), (harvestingPotionConsume + resonancePotionConsume), netSageRootGain, netBloomGain, sageProfitPerDay, bloomProfitPerDay];
}

//#region combat
function calculateCombatEfficiency(display = true){
    const t = translations[currentLanguage];
    const baseMana = 0.0001 * Math.pow((values.basic.currentEnemy+150), 2) + Math.pow((values.basic.currentEnemy+150), 1.2) + 10 * (values.basic.currentEnemy+150);
    const manaPerAction = baseMana * (1 + values.codex.codexManaDust / 100) * (1 + values.equipment.manaBoost / 100);
    const manaPerDay = manaPerAction * 28800;
    const manaPerDayAfterTax = manaPerDay * (1 - values.guild.guildManaTax / 100);
    const [shardPerActionAfterTax, shardDailyValue,minShardPerActionAfterTax] = calculateShards();
    const [manaConsumePerDay, sageRootHourHarvest, bloomHourHarvest, sageRootHourConsume, bloomHourConsume, netSageRootGain, netBloomGain, sageProfitPerDay, bloomProfitPerDay] = calculateFarmIncome();
    const farmProfitPerDay = sageProfitPerDay + bloomProfitPerDay - manaConsumePerDay;

    const profitPerDayTotal = manaPerDayAfterTax + shardDailyValue + farmProfitPerDay;

    if(display){
        document.getElementById('calcResults').innerHTML = \`
            <div class="calc-result">
                <div class="result-content-box">
                    \${t.manaPerDay} \${formatNumber(manaPerDayAfterTax)}<br><br>

                    \${t.shardRangePerAction} \${formatNumber(minShardPerActionAfterTax)} ~ \${formatNumber(2*minShardPerActionAfterTax)}<br>
                    \${t.shardsPerDay} \${formatNumber(shardPerActionAfterTax)}<br>
                    \${t.shardsDailyValue} \${formatNumber(shardDailyValue)}<br><br>

                    \${t.sagerootHourlyProduction} \${formatNumber(sageRootHourHarvest)} \${t.bloomwellHourlyProduction} \${formatNumber(bloomHourHarvest)}<br>
                    \${t.sagerootHourlyConsumption} \${formatNumber(sageRootHourConsume)} \${t.bloomwellHourlyConsumption} \${formatNumber(bloomHourConsume)}<br>
                    \${t.sagerootNetProduction} \${formatNumber(netSageRootGain)} \${t.bloomwellNetProduction} \${formatNumber(netBloomGain)}<br>
                    \${t.sagerootDailyProfit} \${formatNumber(sageProfitPerDay)} \${t.bloomwellDailyProfit} \${formatNumber(bloomProfitPerDay)}<br>
                    \${t.farmDailyMaintenance} \${formatNumber(manaConsumePerDay)}<br>
                    \${t.farmDailyValue} \${formatNumber(farmProfitPerDay)}<br><br>

                    \${t.dailyIncome} \${formatNumber(profitPerDayTotal)}<br>
                </div>
            </div>
        \`;
    }

    return profitPerDayTotal;
}

//#region gathering
function calculateGatheringEfficiency(display = true, gatheringType = null){
    const t = translations[currentLanguage];
    if (display && gatheringType === null) {
        const selectedType = document.getElementById('gatheringType').value;
        if (!values.ui) values.ui = {};
        values.ui.lastGatheringType = selectedType;
    }

    if(gatheringType === null){
        gatheringType = document.getElementById('gatheringType').value;
    }

    let level = 0;

    if (gatheringType === 'woodcutting') {
        level = values.basic.woodcuttingLevel;
    } else if (gatheringType === 'mining') {
        level = values.basic.miningLevel;
    } else if (gatheringType === 'fishing') {
        level = values.basic.fishingLevel;
    }
    const [shardPerActionAfterTax, shardDailyValue,minShardPerActionAfterTax] = calculateShards();

    const potionBaseResource = values.guild.harvestingPotionLevel * 0.1 * (1 + values.equipment.potionBoost/100);
    const baseResource = 1 + level * 0.03 + values.gathering.baseResourceAmountTotal + potionBaseResource; 
    const factor2 = 1 + values.codex.codexBaseResource/100; 
    const factor3 = 1 + values.guild.guildLevel/2/100; 
    const factor4 = 1 + values.gathering[gatheringType + 'Boost'] / 100;

    const resourcePerAction = baseResource * factor2 * factor3 * factor4;
    const resourcePerActionAfterTax = resourcePerAction * (1 - values.guild.guildResonanceTax / 100);
    const resourcePerDayAfterTax = resourcePerActionAfterTax * 28800;
    let resourcePrice = 0;
    if (gatheringType === 'woodcutting') {
        resourcePrice = values.market.woodPrice;
    } else if (gatheringType === 'mining') {
        resourcePrice = values.market.ironPrice;
    } else if (gatheringType === 'fishing') {
        resourcePrice = values.market.fishPrice;
    }
    let resourceProfitPerDay = resourcePerDayAfterTax * resourcePrice;

    const [manaConsumePerDay, sageRootHourHarvest, bloomHourHarvest, sageRootHourConsume, bloomHourConsume, netSageRootGain, netBloomGain, sageProfitPerDay, bloomProfitPerDay] = calculateFarmIncome();
    const farmProfitPerDay = sageProfitPerDay + bloomProfitPerDay - manaConsumePerDay;

    const profitPerDayTotal = resourceProfitPerDay + shardDailyValue + farmProfitPerDay;

    if(display){
        document.getElementById('calcResults').innerHTML = \`
            <div class="calc-result">
                <div class="result-content-box">
                    \${t.resourcePerAction} \${formatNumber(resourcePerActionAfterTax)}<br>
                    \${t.resourcePerDay} \${formatNumber(resourcePerDayAfterTax)}<br>
                    \${t.resourcePrice} \${formatNumber(resourcePrice)}<br>
                    \${t.resourceDailyValue} \${formatNumber(resourceProfitPerDay)}<br><br>
                    
                    \${t.shardRangePerAction} \${formatNumber(minShardPerActionAfterTax)} ~ \${formatNumber(2*minShardPerActionAfterTax)}<br>
                    \${t.shardsPerDay} \${formatNumber(shardPerActionAfterTax)}<br>
                    \${t.shardsDailyValue} \${formatNumber(shardDailyValue)}<br><br>

                    \${t.sagerootHourlyProduction} \${formatNumber(sageRootHourHarvest)} \${t.bloomwellHourlyProduction} \${formatNumber(bloomHourHarvest)}<br>
                    \${t.sagerootHourlyConsumption} \${formatNumber(sageRootHourConsume)} \${t.bloomwellHourlyConsumption} \${formatNumber(bloomHourConsume)}<br>
                    \${t.sagerootNetProduction} \${formatNumber(netSageRootGain)} \${t.bloomwellNetProduction} \${formatNumber(netBloomGain)}<br>
                    \${t.sagerootDailyProfit} \${formatNumber(sageProfitPerDay)} \${t.bloomwellDailyProfit} \${formatNumber(bloomProfitPerDay)}<br>
                    \${t.farmDailyMaintenance} \${formatNumber(manaConsumePerDay)}<br>
                    \${t.farmDailyValue} \${formatNumber(farmProfitPerDay)}<br><br>

                    \${t.dailyIncome} \${formatNumber(profitPerDayTotal)}<br>
                </div>
            </div>
        \`;
    }

    return profitPerDayTotal;
}

//#region ResonanceLevel
function calculateResonancePotionLevel(){
    const t = translations[currentLanguage];
    let resonancePotionLevelX = 0;

    function getResonancePotionConsume(resonancePotionLevelX) {
        const resonancePotionConsume = resonancePotionLevelX * (1+resonancePotionLevelX) / 2;
        const sageRootConsumePerDay = resonancePotionConsume * values.market.sagerootPrice * 24;
        const bloomConsumePerDay = resonancePotionConsume * values.market.bloomwellPrice * 24;
        const farmConsumePerDay = sageRootConsumePerDay + bloomConsumePerDay;
        return farmConsumePerDay;
    }

    function getResonancePotionExtraIncome(resonancePotionLevelX) {
        const totalLevel = values.basic.battleLevel*3 + values.basic.miningLevel + values.basic.fishingLevel + values.basic.woodcuttingLevel;
        const MinBaseShard = 100*Math.pow(1+totalLevel/10, 1-0.3*(totalLevel/(totalLevel+20000)));
        const potionShardBoost = 5* (1 + values.equipment.potionBoost/100) * resonancePotionLevelX;
        const shardPerActionAfterTax = 1.5 * MinBaseShard * (1 + potionShardBoost / 100) * (1 - values.guild.guildShardTax / 100);
        const shardsPerDayAfterTax = shardPerActionAfterTax * ((1+(values.codex.codexDropBoost/100))*(1/80)*28800);
        const shardDailyValue = shardsPerDayAfterTax * values.market.shardPrice;
        return shardDailyValue;
    }

    const totalLevel = values.basic.battleLevel * 3 + values.basic.miningLevel + values.basic.fishingLevel + values.basic.woodcuttingLevel;
    const MinBaseShard = 100 * Math.pow(1 + totalLevel/10, 1 - 0.3 * (totalLevel/(totalLevel + 20000)));
    const A = (values.market.sagerootPrice + values.market.bloomwellPrice) * 24;
    const B = 0.05 * (1 + values.equipment.potionBoost / 100);
    const C = 1.5 * MinBaseShard * (1 - values.guild.guildShardTax / 100) * 
            ((1 + values.codex.codexDropBoost / 100) * (1/80) * 28800) * 
            values.market.shardPrice;
    const optimalLevel = (C * B) / A - 0.5;
    const finalOptimalLevel = Math.max(0, optimalLevel);

    document.getElementById('calcResults').innerHTML = \`
    <div class="calc-result">
        <div class="result-content-box">
            \${t.optimalResonanceLevel} \${finalOptimalLevel.toFixed(2)}<br><br>
            \${t.comparedToLevel0}<br>
            \${t.extraFarmConsumption} \${formatNumber(getResonancePotionConsume(finalOptimalLevel))}/day<br>
            \${t.extraIncome} \${formatNumber(getResonancePotionExtraIncome(finalOptimalLevel))}/day<br>
            \${t.increasedIncome} \${formatNumber(getResonancePotionExtraIncome(finalOptimalLevel)-getResonancePotionConsume(finalOptimalLevel))}<br>
        </div>
    </div>\`;
}

// region Gather ROI
function calculateGatheringROI(){
    const t = translations[currentLanguage];
    const gatheringType = document.getElementById('gatheringType2').value;
    const paths = {
        mining: { base: 'miningBaseBoost', total: 'miningBoost' },
        fishing: { base: 'fishingBaseBoost', total: 'fishingBoost' },
        woodcutting: { base: 'woodcuttingBaseBoost', total: 'woodcuttingBoost' }
    };

    // FIXED
    function calculateResearchBoost(incrementLevel) {
        const path = paths[gatheringType];
        const currentLevel = values.gathering[path.base];
        const oldBoostTotal = values.gathering[path.total];
        const shardsNeed = incrementLevel * (currentLevel + 1 + currentLevel + incrementLevel);
        const priceNeed = shardsNeed * values.market.shardPrice;
        const newBoostTotal = oldBoostTotal + incrementLevel *( 0.02 +  values.guild.guildNexusCrystalLevel * 0.0002);
        // console.log("oldBoostTotal: " + oldBoostTotal + " newBoostTotal: " + newBoostTotal);
        values.gathering[path.total] = newBoostTotal;
        const newProfit = calculateGatheringEfficiency(false,gatheringType);
        values.gathering[path.total] = oldBoostTotal; 
        return [priceNeed, newProfit];
    }

    // no problem
    function calculateBaseResourceAmount(incrementLevel) {
        const currentLevel = values.gathering.baseResourceAmountBase;
        function sumOfSquares(n) {
            return n * (n + 1) * (2 * n + 1) / 6;
        }
        const priceNeed = (sumOfSquares(currentLevel+incrementLevel) - sumOfSquares(currentLevel))*100;
        const oldBaseResourceAmoutTotal = values.gathering.baseResourceAmountTotal;
        values.gathering.baseResourceAmountTotal += incrementLevel/100;
        const newProfit = calculateGatheringEfficiency(false, gatheringType);
        values.gathering.baseResourceAmountTotal = oldBaseResourceAmoutTotal;
        return [priceNeed, newProfit];
    }

    // no problem
    function calculateCodexBaseResource(incrementLevel) {
        const currentLevel = values.codex.codexBaseResourceBase;
        function calculateCost(fromLevel, toLevel) {
            const startValue = fromLevel + 1;
            const endValue = toLevel;
            const n = endValue - startValue + 1; 
            const sum = n * (startValue + endValue) / 2;
            return sum;
        }
        const codexNeed = calculateCost(currentLevel, currentLevel+incrementLevel);
        const priceNeed = codexNeed * values.market.codexPrice;
        const oldCodexBaseResource = values.codex.codexBaseResource;
        values.codex.codexBaseResource += incrementLevel;
        const newProfit = calculateGatheringEfficiency(false, gatheringType);
        values.codex.codexBaseResource = oldCodexBaseResource;
        return [priceNeed, newProfit];
    }

    // no problem
    function calculatePotionBoost(incrementLevel) {
        const currentLevel = values.equipment.potionBoostBase;
        function calculateCost(fromLevel, toLevel) {
            const baseCost = 10000000;
            const growthRate = 1.1;
            return Array.from({ length: toLevel - fromLevel }, (_, i) => fromLevel + i)
                .map(level => Math.floor(baseCost * Math.pow(growthRate, level)))
                .reduce((total, cost) => total + cost, 0);
        }
        const priceNeed = calculateCost(currentLevel, currentLevel+incrementLevel);
        const oldPotionBoost = values.equipment.potionBoost;
        values.equipment.potionBoost += incrementLevel;
        const newProfit = calculateGatheringEfficiency(false, gatheringType);
        values.equipment.potionBoost = oldPotionBoost;
        return [priceNeed, newProfit];
    }


    // no problem
    function calculateCodexDropRate(incrementLevel) {
        const currentLevel = values.codex.codexDropBoostBase;
        function calculateCost(fromLevel, toLevel) {
            const startValue = fromLevel + 1;
            const endValue = toLevel;
            const n = endValue - startValue + 1; 
            const sum = n * (startValue + endValue) / 2;
            return sum;
        }
        const codexNeed = calculateCost(currentLevel, currentLevel+incrementLevel);
        const priceNeed = codexNeed * values.market.codexPrice;
        const oldCodexDropRate = values.codex.codexDropBoost;
        values.codex.codexDropBoost += incrementLevel;
        const newProfit = calculateGatheringEfficiency(false, gatheringType);
        values.codex.codexDropBoost = oldCodexDropRate;
        return [priceNeed, newProfit];
    }
    
    function calculateFarmLevel(incrementLevel) {
        function calculateCost(fromLevel, toLevel) {
            function sumOfSquares(n) {
                return n * (n + 1) * (2 * n + 1) / 6;
            }
            return sumOfSquares(toLevel) - sumOfSquares(fromLevel);
        }

        const currentLevels = {
            harvestGolem: values.farm.harvestGolem,
            fertilizer: values.farm.fertilizer,
            farmPlots: values.farm.farmPlots
        };

        function optimizedAllocation(incrementLevel) {
            const projects = ['harvestGolem', 'fertilizer', 'farmPlots'];
            const levels = [currentLevels.harvestGolem, currentLevels.fertilizer, currentLevels.farmPlots];
            const allocations = [0, 0, 0];

            let remaining = incrementLevel;

            while (remaining > 0) {
                let minLevel = Math.min(...levels);
                let minIndices = [];
                
                for (let i = 0; i < levels.length; i++) {
                    if (levels[i] === minLevel) {
                        minIndices.push(i);
                    }
                }

                let nextHigherLevel = Math.min(...levels.filter(l => l > minLevel));
                if (!isFinite(nextHigherLevel)) {
                    const avgAllocation = Math.floor(remaining / minIndices.length);
                    const extraLevels = remaining % minIndices.length;

                    for (let i = 0; i < minIndices.length; i++) {
                        const idx = minIndices[i];
                        const allocation = avgAllocation + (i < extraLevels ? 1 : 0);
                        allocations[idx] += allocation;
                        levels[idx] += allocation;
                    }
                    remaining = 0;
                } else {
                    const levelGap = nextHigherLevel - minLevel;
                    const totalNeeded = levelGap * minIndices.length;

                    if (totalNeeded <= remaining) {
                        for (const idx of minIndices) {
                            allocations[idx] += levelGap;
                            levels[idx] += levelGap;
                        }
                        remaining -= totalNeeded;
                    } else {
                        const avgAllocation = Math.floor(remaining / minIndices.length);
                        const extraLevels = remaining % minIndices.length;

                        for (let i = 0; i < minIndices.length; i++) {
                            const idx = minIndices[i];
                            const allocation = avgAllocation + (i < extraLevels ? 1 : 0);
                            allocations[idx] += allocation;
                            levels[idx] += allocation;
                        }
                        remaining = 0;
                    }
                }
            }

            return {
                harvestGolem: allocations[0],
                fertilizer: allocations[1],
                farmPlots: allocations[2]
            };
        }

        const allocations = optimizedAllocation(incrementLevel);
        const costs = {
            harvestGolem: calculateCost(currentLevels.harvestGolem, currentLevels.harvestGolem + allocations.harvestGolem),
            fertilizer: calculateCost(currentLevels.fertilizer, currentLevels.fertilizer + allocations.fertilizer),
            farmPlots: calculateCost(currentLevels.farmPlots, currentLevels.farmPlots + allocations.farmPlots)
        };
        const priceNeed = costs.harvestGolem * values.market.ironPrice + costs.fertilizer * values.market.fishPrice + costs.farmPlots * values.market.woodPrice;
        const oldfarmHerbHarvest = values.farm.farmHerbHarvest;
        const newHarvestGolemLevel = currentLevels.harvestGolem + allocations.harvestGolem;
        const newFertilizerLevel = currentLevels.fertilizer + allocations.fertilizer;
        const newFarmPlotsLevel = currentLevels.farmPlots + allocations.farmPlots;
        values.farm.farmHerbHarvest = 2.5 * 
            Math.pow(1 + newHarvestGolemLevel/100, 0.9) * 
            Math.pow(1 + newFertilizerLevel/100, 0.9) * 
            Math.pow(1 + newFarmPlotsLevel/100, 0.9);
        const newProfit = calculateGatheringEfficiency(false, gatheringType);
        values.farm.farmHerbHarvest = oldfarmHerbHarvest;
        return [priceNeed, newProfit];
    }

    const currentProfit = calculateGatheringEfficiency(false, gatheringType);

    const research = calculateResearchBoost(3000);
    const baseResource = calculateBaseResourceAmount(100);
    const codexBase = calculateCodexBaseResource(5);
    const potion = calculatePotionBoost(5);
    const codexDrop = calculateCodexDropRate(5);
    const farm = calculateFarmLevel(300);

    const investments = [
        { name: t.investments.research, cost: research[0], profit: research[1]-currentProfit },
        { name: t.investments.baseResource, cost: baseResource[0], profit: baseResource[1]-currentProfit },
        { name: t.investments.codexBase, cost: codexBase[0], profit: codexBase[1]-currentProfit },
        { name: t.investments.potion, cost: potion[0], profit: potion[1]-currentProfit },
        { name: t.investments.codexDrop, cost: codexDrop[0], profit: codexDrop[1]-currentProfit },
        { name: t.investments.farm, cost: farm[0], profit: farm[1]-currentProfit }
    ];
    
    investments.forEach(item => {
        item.roi = item.cost > 0 ? (item.profit / item.cost * 10000) : 0;
    });
    investments.sort((a, b) => b.roi - a.roi);

    let resultHTML = \`
        <div class="calc-result">
            <div class="result-content-box">
                <strong>\${t.gatheringROIComparison.replace('\${gatheringType}', gatheringType)}</strong><br><br>
    \`;
    
    investments.forEach((item, index) => {
        resultHTML += \`\${index + 1}. \${item.name}<br>\`;
        resultHTML += \`&nbsp;&nbsp;&nbsp;\${t.cost} \${formatNumber(item.cost)} | \${t.extraDailyProfit} \${formatNumber(item.profit)}<br>\`;
        resultHTML += \`&nbsp;&nbsp;&nbsp;ROI: \${item.roi.toFixed(2)}<br><br>\`;
    });
    
    resultHTML += \`</div></div>\`;
    
    document.getElementById('calcResults').innerHTML = resultHTML;

    const selectedType = document.getElementById('gatheringType2').value;
    if (!values.ui) values.ui = {};
    values.ui.lastGatheringType2 = selectedType;
}

// #region GatherEquip
function calculateGatherEquipReplace(){
    const t = translations[currentLanguage];

    function findLowestTypeBoostEquip(playerData) {
        const equipment = playerData.Equipment;
        let lowestEquip = null;
        let lowestBoost = Infinity;
        Object.values(equipment).forEach(item => {
            if (item.Slot == 1) return;
            const boosts = item.Boosts;
            const boostKeys = Object.keys(boosts);
            const lastBoostType = boostKeys[boostKeys.length - 1];
            if (lastBoostType === '124') {
                const infusions = item.Infusions || 0;
                const infusionMultiplier = 1 + (infusions * 0.05);
                const gatherBaseResourceAmout = boosts['124'] * infusionMultiplier / 100;
                if (gatherBaseResourceAmout < lowestBoost) {
                    lowestBoost = gatherBaseResourceAmout;
                    lowestEquip = item;
                }
            }
        });
        return lowestEquip ? lowestEquip: null;
    }

    function calculateHarvestingPotionCost(Level){
        const HarvestingPotionConsume = Level * (1+Level) / 2;
        const bloomwellPrice = values.market.bloomwellPrice;
        return HarvestingPotionConsume*bloomwellPrice*24;
    }

    const lowestEquip =  findLowestTypeBoostEquip(globalPlayerData);

    if (lowestEquip === null) {
        document.getElementById('calcResults').innerHTML = \`
            <div class="calc-result">
                <div class="result-content-box">
                    \${t.gatherEquipReplaceTitle}<br>
                    \${t.gatherEquipReplaceDesc}<br><br>
                    \${t.noBaseResourceEquip}<br>
                </div>
            </div>\`;
        return;
    }

    const baseResourceAmoutLose = lowestEquip.Boosts['124'] * (1 + (lowestEquip.Infusions * 0.05)) / 100;
    const currentHarvestingPotionLevel = values.guild.harvestingPotionLevel;
    function findMinHarvestingPotionLevel(baseResourceAmountLose, currentHarvestingPotionLevel) {
        function potionBaseResource(level) {
            return level * 0.1 * (1 + values.equipment.potionBoost / 100);
        }
        const currentPotionResource = potionBaseResource(currentHarvestingPotionLevel);
        const targetResource = currentPotionResource + baseResourceAmountLose;
        const targetLevel = targetResource / (0.1 * (1 + values.equipment.potionBoost / 100));
        return Math.ceil(targetLevel);
    }
    const minHarvestingPotionLevel = findMinHarvestingPotionLevel(baseResourceAmoutLose, currentHarvestingPotionLevel);

    const oldProfit = calculateGatheringEfficiency(false);
    const OldShardBoost = values.equipment.shardBoost;
    values.equipment.shardBoost += baseResourceAmoutLose*40;
    const newProfit = calculateGatheringEfficiency(false);
    values.equipment.shardBoost = OldShardBoost;

    const potionPriceDiffer = calculateHarvestingPotionCost(minHarvestingPotionLevel) - calculateHarvestingPotionCost(currentHarvestingPotionLevel);
    
    let resultHTML = \`
        <div class="calc-result">
            <div class="result-content-box">
                \${t.gatherEquipReplaceTitle}<br>
                \${t.gatherEquipReplaceDesc}<br>
                \${t.zh === "zh" ? "注意:根据【计算采集效率】按钮前面的框的值决定采集类型" : "Note: The gathering type is determined by the selection box next to the 'Calculate Gathering Efficiency' button."}<br><br>
                \${t.currentPotionLevel} \${currentHarvestingPotionLevel}。\${t.newPotionLevel} \${minHarvestingPotionLevel}<br><br>
    \`;

    if(newProfit - oldProfit > potionPriceDiffer){
        resultHTML += \`
            \${t.canReplaceGatherEquip.replace('\${name}', lowestEquip.Name)}<br>
            \${t.baseResourceAmountLost.replace('\${amount}', baseResourceAmoutLose.toFixed(2)).replace('\${shardBoost}', (baseResourceAmoutLose*40).toFixed(2))}<br>
            \${t.manaIncreaseAfterReplace} \${formatNumber(newProfit - oldProfit)}<br>
            \${t.farmCostIncreaseAfterReplace} \${formatNumber(calculateHarvestingPotionCost(minHarvestingPotionLevel) - calculateHarvestingPotionCost(currentHarvestingPotionLevel))}<br>
            \${t.incomeIncreaseAfterReplace} \${formatNumber((newProfit - oldProfit) - (calculateHarvestingPotionCost(minHarvestingPotionLevel) - calculateHarvestingPotionCost(currentHarvestingPotionLevel)))}<br><br>
        \`;
    } else {
        resultHTML += \`\${t.cannotReplaceGatherEquip}<br>\`;
    }
    
    resultHTML += \`</div></div>\`;
    document.getElementById('calcResults').innerHTML = resultHTML;
}

// #region battlerEquip
function calculateBattlerEquipReplace(){
    const t = translations[currentLanguage];
    const BOOST_TYPES = { 120: "BATTLE_EXPERIENCE_BOOST", 121: "MANA_DUST_BOOST", 122: "ELEMENTAL_SHARD_BOOST", 123: "STAT_DROP" };

    function cheakReplaceEquip(playerData) {
        function findLowestTypeBoostEquip(playerData) {
            const equipment = playerData.Equipment;
            let lowestEquip = null; let lowestBoost = Infinity;
            Object.values(equipment).forEach(item => {
                const boosts = item.Boosts;
                const boostKeys = Object.keys(boosts);
                const lastBoostType = boostKeys[boostKeys.length - 1];
                if (lastBoostType === '120') {
                    const infusions = item.Infusions || 0;
                    const infusionMultiplier = 1 + (infusions * 0.05);
                    const battleExpBoost = boosts['120'] * infusionMultiplier;
                    if (battleExpBoost < lowestBoost) {
                        lowestBoost = battleExpBoost;
                        lowestEquip = item;
                    }
                }
            });
            return lowestEquip ? lowestEquip: null;
        }
        
        function analyzeCurrentEquipment(playerData) {
            const equipment = playerData.Equipment;
            const typeCount = {}; const typeBoosts = {};
            Object.keys(BOOST_TYPES).forEach(type => { typeCount[type] = 0; typeBoosts[type] = 0; });
            Object.values(equipment).forEach(item => {
                const boosts = item.Boosts;
                const infusions = item.Infusions || 0;
                const infusionMultiplier = 1 + (infusions * 0.05);
                const boostKeys = Object.keys(boosts);
                const lastBoostType = boostKeys[boostKeys.length - 1];
                if (BOOST_TYPES[lastBoostType]) {
                    typeCount[lastBoostType]++;
                    let enhancedBoosts = {};
                    Object.entries(boosts).forEach(([boostId, baseValue]) => {
                        if (boostId !== lastBoostType) {
                            const enhancedValue = baseValue * infusionMultiplier;
                            enhancedBoosts[boostId] = enhancedValue;
                        } else {
                            typeBoosts[lastBoostType] += baseValue * infusionMultiplier;
                        }
                    });
                }
            });
            if(typeCount[121] > 1){
                typeBoosts[121] = typeBoosts[121] * (1-(typeCount[121]-1)*0.05);
            }
            return { typeCount, typeBoosts};
        }
        const lowestEquip =  findLowestTypeBoostEquip(playerData);
        
        if (lowestEquip === null) {
            document.getElementById('calcResults').innerHTML = \`
                <div class="calc-result">
                    <div class="result-content-box">
                        \${t.battleEquipReplaceTitle}<br>
                        \${t.battleEquipReplaceDesc}<br><br>
                        \${t.noExpEquip}<br>
                    </div>
                </div>\`;
            return null;
        }

        const EXPLost = lowestEquip.Boosts['120'] * (1 + (lowestEquip.Infusions * 0.05));
        let { typeCount, typeBoosts } = analyzeCurrentEquipment(playerData);

        if(typeCount[121] > 1){ typeBoosts[121] = typeBoosts[121] / (1-(typeCount[121]-1)*0.05); }
        typeBoosts[121] += EXPLost; typeCount[121]++; typeCount[120]--;
        if(typeCount[121] > 1){ typeBoosts[121] = typeBoosts[121] * (1-(typeCount[121]-1)*0.05); }

        const oldProfit = calculateCombatEfficiency(false);
        const OldManaBoost = values.equipment.manaBoost;
        values.equipment.manaBoost = typeBoosts[121];
        let newProfit = calculateCombatEfficiency(false);
        values.equipment.manaBoost = OldManaBoost;

        function findMinTargetLevel(currentWisdomPotionLevel, EXPLost) {
            const potionBoostMultiplier = 1 + values.equipment.potionBoost/100;
            const currentPotionEXP = currentWisdomPotionLevel * 5 * potionBoostMultiplier;
            const minTargetLevel = (EXPLost + currentPotionEXP) / (5 * potionBoostMultiplier);
            return Math.ceil(minTargetLevel);
        }
        function calculateWisdomPotionCost(Level){
            const wisdomPotionConsume = Level * (1+Level) / 2;
            const sageRootPrice = values.market.sagerootPrice;
            return wisdomPotionConsume*sageRootPrice*24;
        }
        const currentWisdomPotionLevel = values.guild.wisdomPotionLevel;
        const targetWisdomPotionLevel = findMinTargetLevel(currentWisdomPotionLevel, EXPLost);

        let resultHTML = \`
            <div class="calc-result">
                <div class="result-content-box">
                    \${t.battleEquipReplaceTitle}<br>
                    \${t.battleEquipReplaceDesc}<br><br>
                    \${t.currentPotionLevel} \${currentWisdomPotionLevel}。\${t.newPotionLevel} \${targetWisdomPotionLevel}<br><br>
        \`;

        let replaceEquip = 0;
        if ((newProfit - oldProfit) > (calculateWisdomPotionCost(targetWisdomPotionLevel) - calculateWisdomPotionCost(currentWisdomPotionLevel))) {
            resultHTML += \`
                \${t.canReplaceBattleEquipToMana.replace('\${name}', lowestEquip.Name)}<br>
                \${t.manaIncreaseAfterReplace} \${formatNumber(newProfit - oldProfit)}<br>
                \${t.farmCostIncreaseAfterReplace} \${formatNumber(calculateWisdomPotionCost(targetWisdomPotionLevel) - calculateWisdomPotionCost(currentWisdomPotionLevel))}<br>
                \${t.incomeIncreaseAfterReplace} \${formatNumber((newProfit - oldProfit) - (calculateWisdomPotionCost(targetWisdomPotionLevel) - calculateWisdomPotionCost(currentWisdomPotionLevel)))}<br><br>
            \`;
            replaceEquip = 1;
        }

        ({ typeCount, typeBoosts } = analyzeCurrentEquipment(globalPlayerData));
        typeBoosts[122] += EXPLost;
        const OldShardBoost = values.equipment.shardBoost;
        values.equipment.shardBoost = typeBoosts[122];
        newProfit = calculateCombatEfficiency(false);
        values.equipment.shardBoost = OldShardBoost;
        if ((newProfit - oldProfit) > (calculateWisdomPotionCost(targetWisdomPotionLevel) - calculateWisdomPotionCost(currentWisdomPotionLevel))) {
            resultHTML += \`
                \${t.canReplaceBattleEquipToShard.replace('\${name}', lowestEquip.Name)}<br>
                \${t.manaIncreaseAfterReplace} \${formatNumber(newProfit - oldProfit)}<br>
                \${t.farmCostIncreaseAfterReplace} \${formatNumber(calculateWisdomPotionCost(targetWisdomPotionLevel) - calculateWisdomPotionCost(currentWisdomPotionLevel))}<br>
                \${t.incomeIncreaseAfterReplace} \${formatNumber((newProfit - oldProfit) - (calculateWisdomPotionCost(targetWisdomPotionLevel) - calculateWisdomPotionCost(currentWisdomPotionLevel)))}<br><br>
            \`;
        } else if(replaceEquip === 0) {
            resultHTML += \`\${t.cannotReplaceBattleEquip}<br>\`;
        }

        resultHTML += \`</div></div>\`;
        document.getElementById('calcResults').innerHTML = resultHTML;
    }

    cheakReplaceEquip(globalPlayerData);
}

window.onload = function() {
    setTheme(currentTheme);
    setLanguage(currentLanguage);
    loadGlobalData();
    showExampleData();
};

window.addEventListener('beforeunload', function() {
    saveGlobalData();
});
</script>
</body>
</html>`; }

    // 按钮点击处理
    function handleButtonClickCalculate() {
        console.log("Button clicked!");
        
        // 检查是否已存在面板
        let panel = document.getElementById('manarion-calculator-panel');
        if (panel) {
            panel.style.display = panel.style.display === 'none' ? 'block' : 'none';
            return;
        }
        
        // 创建浮动面板
        panel = document.createElement('div');
        panel.id = 'manarion-calculator-panel';
        panel.style.cssText = `
            position: fixed;
            top: 50%;
            left: 50%;
            transform: translate(-50%, -50%);
            width: 90%;
            max-width: 1200px;
            height: 80vh;
            background: white;
            border-radius: 15px;
            box-shadow: 0 20px 60px rgba(0,0,0,0.3);
            z-index: 1000000;
            overflow: auto;
        `;
        
        const iframe = document.createElement('iframe');
        iframe.style.cssText = 'width: 100%; height: 100%; border: none; border-radius: 15px;';
        panel.appendChild(iframe);
        
        document.body.appendChild(panel);
        
        const iframeDoc = iframe.contentDocument || iframe.contentWindow.document;
        iframeDoc.open();
        iframeDoc.write(getFullHTMLContent());
        iframeDoc.close();

        iframe.contentWindow.fetchDataWithGM = async function(url) {
            return new Promise((resolve, reject) => {
                GM_xmlhttpRequest({
                    method: 'GET',
                    url: url,
                    headers: {
                        'Accept': 'application/json',
                        'User-Agent': 'Mozilla/5.0'
                    },
                    onload: function(response) {
                        try {
                            resolve(JSON.parse(response.responseText));
                        } catch (e) {
                            reject(e);
                        }
                    },
                    onerror: reject
                });
            });
        };
        
        const closeBtn = document.createElement('button');
        closeBtn.innerHTML = '✕';
        closeBtn.style.cssText = `
            position: absolute;
            top: 10px;
            right: 10px;
            width: 40px;
            height: 40px;
            border-radius: 50%;
            border: none;
            background: #ff4444;
            color: white;
            font-size: 24px;
            cursor: pointer;
            z-index: 1000001;
        `;
        closeBtn.onclick = () => panel.style.display = 'none';
        panel.appendChild(closeBtn);
    }

    function initHelper() {
        createDraggableButton();
    }

    function createDraggableButton() {
        if (document.getElementById('manarion-helper-button')) return;

        const button = document.createElement('div');
        button.id = 'manarion-helper-button';
        button.innerHTML = `
            <svg width="40" height="40" fill="white" viewBox="0 0 24 24">
                <path d="M19 3H5c-1.11 0-2 .9-2 2v14c0 1.1.89 2 2 2h14c1.11 0 2-.9 2-2V5c0-1.1-.89-2-2-2zm-9 14l-5-5 1.41-1.41L10 14.17l7.59-7.59L19 8l-9 9z"/>
            </svg>
        `;

        Object.assign(button.style, {
            position: 'fixed',
            top: '50%',
            right: '20px',
            transform: 'translateY(-50%)',
            width: '80px',
            height: '80px',
            background: 'linear-gradient(135deg, #667eea 0%, #764ba2 100%)',
            borderRadius: '50%',
            display: 'flex',
            alignItems: 'center',
            justifyContent: 'center',
            cursor: 'move',
            boxShadow: '0 8px 25px rgba(0,0,0,0.3)',
            zIndex: '999999',
            transition: 'all 0.3s ease',
            border: '4px solid rgba(255,255,255,0.2)',
            userSelect: 'none'
        });

        // 拖拽功能
        let isDragging = false;
        let hasMoved = false;
        let startX = 0;
        let startY = 0;
        let initialX = 0;
        let initialY = 0;

        button.addEventListener('mousedown', (e) => {
            isDragging = true;
            hasMoved = false;
            startX = e.clientX;
            startY = e.clientY;
            
            const rect = button.getBoundingClientRect();
            initialX = rect.left;
            initialY = rect.top;
            
            button.style.transition = 'none';
            button.style.cursor = 'grabbing';
            e.preventDefault();
        });

        document.addEventListener('mousemove', (e) => {
            if (!isDragging) return;
            
            const deltaX = e.clientX - startX;
            const deltaY = e.clientY - startY;
            
            // 检查是否真的移动了(移动超过5像素才算拖拽)
            if (Math.abs(deltaX) > 5 || Math.abs(deltaY) > 5) {
                hasMoved = true;
            }
            
            if (hasMoved) {
                const newX = initialX + deltaX;
                const newY = initialY + deltaY;
                
                // 限制在窗口内
                const limitedX = Math.max(0, Math.min(newX, window.innerWidth - 80));
                const limitedY = Math.max(0, Math.min(newY, window.innerHeight - 80));
                
                button.style.left = limitedX + 'px';
                button.style.top = limitedY + 'px';
                button.style.right = 'auto';
                button.style.transform = 'none';
            }
        });

        document.addEventListener('mouseup', () => {
            if (isDragging) {
                if (!hasMoved) {
                    handleButtonClickCalculate();
                }
                
                isDragging = false;
                hasMoved = false;
                button.style.transition = 'all 0.3s ease';
                button.style.cursor = 'move';
            }
        });

        // 悬停效果
        button.addEventListener('mouseenter', () => {
            if (!isDragging) {
                button.style.transform = button.style.transform === 'translateY(-50%)' ? 
                    'translateY(-50%) scale(1.1)' : 'scale(1.1)';
                button.style.boxShadow = '0 12px 35px rgba(0,0,0,0.4)';
            }
        });

        button.addEventListener('mouseleave', () => {
            if (!isDragging) {
                button.style.transform = button.style.transform.includes('translateY(-50%)') ? 
                    'translateY(-50%)' : 'none';
                button.style.boxShadow = '0 8px 25px rgba(0,0,0,0.3)';
            }
        });

        document.body.appendChild(button);
        console.log('Manarion Helper Button created!');
    }

    // 初始化
    if (document.readyState === 'loading') {
        document.addEventListener('DOMContentLoaded', initHelper);
    } else {
        setTimeout(initHelper, 1000);
    }

})();