{"version":3,"sources":["jsdelivr-header.js","/npm/njust-jwc-enhance@1.0.0/enhance.js"],"names":[],"mappings":"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","file":"/npm/njust-jwc-enhance@1.0.0/enhance.js","sourceRoot":"","sourcesContent":["/**\n * Minified by jsDelivr using Terser v5.39.0.\n * Original file: /npm/njust-jwc-enhance@1.0.0/enhance.js\n *\n * Do NOT use SRI with dynamically generated files! More information: https://www.jsdelivr.com/using-sri-with-dynamic-files\n */\n","// ==UserScript==\r\n// @name         南理工教务增强助手\r\n// @namespace    http://tampermonkey.net/\r\n// @version      1.2\r\n// @description  在合适的地方显示课程大纲、选修课类别及选修课学分情况\r\n// @match        202.119.81.112/*\r\n// @match        bkjw.njust.edu.cn/*\r\n// @match        202.119.81.112:9080/*\r\n// @match        202.119.81.113:9080/*\r\n// @grant        GM_xmlhttpRequest\r\n// @connect      jsdelivr.net\r\n// @author       Light\r\n// @license      MIT\r\n// @supportURL   https://github.com/NJUST-OpenLib/NJUST-JWC-Enhance\r\n// ==/UserScript==\r\n\r\n(function () {\r\n    'use strict';\r\n\r\n    const CATEGORY_URL = 'https://fastly.jsdelivr.net/gh/NJUST-OpenLib/NJUST-JWC-Enhance@latest/data/xxk.json';\r\n    const OUTLINE_URL = 'https://fastly.jsdelivr.net/gh/NJUST-OpenLib/NJUST-JWC-Enhance@latest/data/kcdg.json';\r\n\r\n    let courseCategoryMap = {};\r\n    let courseOutlineMap = {};\r\n\r\n    // 统一弹窗样式函数\r\n    function createUnifiedModal(title, content, type = 'info') {\r\n        // 移除可能存在的旧弹窗\r\n        const existingModal = document.getElementById('njustAssistantModal');\r\n        if (existingModal) {\r\n            existingModal.remove();\r\n        }\r\n\r\n        const container = document.createElement('div');\r\n        container.id = 'njustAssistantModal';\r\n\r\n        // 根据类型设置不同的渐变色\r\n        let gradientColor;\r\n        switch (type) {\r\n            case 'warning':\r\n                gradientColor = 'linear-gradient(135deg, #ff6b6b 0%, #ee5a24 100%)';\r\n                break;\r\n            case 'success':\r\n                gradientColor = 'linear-gradient(135deg, #28a745 0%, #20c997 100%)';\r\n                break;\r\n            case 'info':\r\n            default:\r\n                gradientColor = 'linear-gradient(135deg, #667eea 0%, #764ba2 100%)';\r\n                break;\r\n        }\r\n\r\n        container.style.cssText = `\r\n            position: fixed;\r\n            top: 50%;\r\n            left: 50%;\r\n            transform: translate(-50%, -50%);\r\n            background: ${gradientColor};\r\n            border: none;\r\n            border-radius: 15px;\r\n            padding: 0;\r\n            box-shadow: 0 10px 40px rgba(0,0,0,0.3);\r\n            z-index: 10000;\r\n            min-width: 200px;\r\n            max-width: 500px;\r\n            font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;\r\n            overflow: hidden;\r\n            animation: fadeIn 0.3s ease-out;\r\n        `;\r\n\r\n        container.innerHTML = `\r\n            <div id=\"dragHandle\" style=\"\r\n                background: rgba(255,255,255,0.1);\r\n                padding: 15px 20px;\r\n                cursor: move;\r\n                display: flex;\r\n                justify-content: space-between;\r\n                align-items: center;\r\n                border-bottom: 1px solid rgba(255,255,255,0.2);\r\n            \">\r\n                <div style=\"color: white; font-weight: bold; font-size: 18px;\">\r\n                    🎓 ${title}\r\n                </div>\r\n                <span style=\"\r\n                    cursor: pointer;\r\n                    color: rgba(255,255,255,0.8);\r\n                    font-size: 18px;\r\n                    padding: 2px 6px;\r\n                    border-radius: 4px;\r\n                    transition: background-color 0.2s;\r\n                \"\r\n                onclick=\"this.closest('div').parentElement.remove()\"\r\n                onmouseover=\"this.style.backgroundColor='rgba(255,255,255,0.2)'\"\r\n                onmouseout=\"this.style.backgroundColor='transparent'\">✕</span>\r\n            </div>\r\n            <div style=\"\r\n                background: white;\r\n                padding: 25px;\r\n            \">\r\n                ${content}\r\n                <div style=\"\r\n                    margin-top: 20px;\r\n                    padding-top: 15px;\r\n                    border-top: 1px solid #eee;\r\n                    font-size: 12px;\r\n                    color: #666;\r\n                    line-height: 1.4;\r\n                    text-align: center;\r\n                \">\r\n                    <div style=\"margin-bottom: 8px;\">\r\n                        <strong>请查看\r\n                        <a href=\"https://enhance.njust.wiki\" target=\"_blank\" style=\"color: #007bff; text-decoration: none;\">官方网站</a>\r\n                      以获取使用说明</strong> \r\n                        </div>\r\n                    <div style=\"color: #ff6b6b; font-weight: bold; margin-bottom: 5px;\">⚠️ 免责声明</div>\r\n                    <div>本工具仅为学习交流使用，数据仅供参考。</div>\r\n                   <div>请以教务处官网信息为准，使用本工具产生的任何后果均由用户自行承担。</div>\r\n                </div>\r\n            </div>\r\n        `;\r\n\r\n        // 添加CSS动画\r\n        if (!document.getElementById('njustAssistantStyles')) {\r\n            const style = document.createElement('style');\r\n            style.id = 'njustAssistantStyles';\r\n            style.textContent = `\r\n                @keyframes fadeIn {\r\n                    from { opacity: 0; transform: translate(-50%, -50%) scale(0.9); }\r\n                    to { opacity: 1; transform: translate(-50%, -50%) scale(1); }\r\n                }\r\n            `;\r\n            document.head.appendChild(style);\r\n        }\r\n\r\n        // 添加拖动功能\r\n        addDragFunctionality(container);\r\n\r\n        document.body.appendChild(container);\r\n        return container;\r\n    }\r\n\r\n    // 拖动功能\r\n    function addDragFunctionality(container) {\r\n        let isDragging = false;\r\n        let currentX, currentY, initialX, initialY;\r\n        let xOffset = 0, yOffset = 0;\r\n\r\n        const dragHandle = container.querySelector('#dragHandle');\r\n\r\n        function dragStart(e) {\r\n            if (e.type === \"touchstart\") {\r\n                initialX = e.touches[0].clientX - xOffset;\r\n                initialY = e.touches[0].clientY - yOffset;\r\n            } else {\r\n                initialX = e.clientX - xOffset;\r\n                initialY = e.clientY - yOffset;\r\n            }\r\n            if (e.target === dragHandle || dragHandle.contains(e.target)) {\r\n                isDragging = true;\r\n            }\r\n        }\r\n\r\n        function dragEnd(e) {\r\n            initialX = currentX;\r\n            initialY = currentY;\r\n            isDragging = false;\r\n        }\r\n\r\n        function drag(e) {\r\n            if (isDragging) {\r\n                e.preventDefault();\r\n                if (e.type === \"touchmove\") {\r\n                    currentX = e.touches[0].clientX - initialX;\r\n                    currentY = e.touches[0].clientY - initialY;\r\n                } else {\r\n                    currentX = e.clientX - initialX;\r\n                    currentY = e.clientY - initialY;\r\n                }\r\n                xOffset = currentX;\r\n                yOffset = currentY;\r\n                container.style.transform = `translate(${currentX}px, ${currentY}px)`;\r\n            }\r\n        }\r\n\r\n        dragHandle.addEventListener('mousedown', dragStart);\r\n        document.addEventListener('mousemove', drag);\r\n        document.addEventListener('mouseup', dragEnd);\r\n        dragHandle.addEventListener('touchstart', dragStart);\r\n        document.addEventListener('touchmove', drag);\r\n        document.addEventListener('touchend', dragEnd);\r\n    }\r\n\r\n    // 检测强智科技页面\r\n    function checkQiangzhiPage() {\r\n        const currentUrl = window.location.href;\r\n        const pageTitle = document.title;\r\n\r\n        // 检测是否为强智科技页面且无法登录\r\n        if (\r\n            pageTitle.includes('强智科技教务系统概念版')) {\r\n\r\n            const content = `\r\n                <div style=\"text-align: center; font-size: 16px; color: #333; margin-bottom: 20px; line-height: 1.6;\">\r\n                    <div style=\"font-size: 20px; margin-bottom: 15px;\">🚫 该页面无法登录</div>\r\n               \r\n                    <div style=\"margin-top: 10px;\">请转向以下正确的登录页面：</div>\r\n                </div>\r\n                <div style=\"text-align: center; margin: 20px 0;\">\r\n                    <div style=\"margin: 10px 0;\">\r\n                        <a href=\"https://www.njust.edu.cn/\" target=\"_blank\" style=\"\r\n                            display: inline-block;\r\n                            background: #28a745;\r\n                            color: white;\r\n                            padding: 12px 20px;\r\n                            text-decoration: none;\r\n                            border-radius: 8px;\r\n                            margin: 5px;\r\n                            font-weight: bold;\r\n                            transition: background-color 0.2s;\r\n                        \" onmouseover=\"this.style.backgroundColor='#218838'\" onmouseout=\"this.style.backgroundColor='#28a745'\">\r\n                            🏫 智慧理工登录页面\r\n                        </a>\r\n                    </div>\r\n                    <div style=\"margin: 10px 0;\">\r\n                        <a href=\"http://202.119.81.113:8080/\" target=\"_blank\" style=\"\r\n                            display: inline-block;\r\n                            background: #007bff;\r\n                            color: white;\r\n                            padding: 12px 20px;\r\n                            text-decoration: none;\r\n                            border-radius: 8px;\r\n                            margin: 5px;\r\n                            font-weight: bold;\r\n                            transition: background-color 0.2s;\r\n                        \" onmouseover=\"this.style.backgroundColor='#0056b3'\" onmouseout=\"this.style.backgroundColor='#007bff'\">\r\n                            🔗 教务处登录页面\r\n                        </a>\r\n                    </div>\r\n                </div>\r\n                <div style=\"\r\n                    margin-top: 15px;\r\n                    padding: 10px;\r\n                    background: #f8f9fa;\r\n                    border-radius: 6px;\r\n                    font-size: 14px;\r\n                    color: #666;\r\n                    text-align: center;\r\n                \">\r\n                    💡 提示：<br>\r\n                    强智科技教务系统概念版是无法登陆的。<br>\r\n                    请使用上述链接跳转到正确的登录页面，<br>\r\n                    登录后可正常使用教务系统功能<br>\r\n                    验证码区分大小写，大部分情况下均为小写\r\n                </div>\r\n            `;\r\n\r\n            createUnifiedModal('南理工教务增强助手', content, 'warning');\r\n            return true;\r\n        }\r\n        return false;\r\n    }\r\n\r\n    function loadJSON(url) {\r\n        return new Promise((resolve, reject) => {\r\n            GM_xmlhttpRequest({\r\n                method: \"GET\",\r\n                url,\r\n                onload: function (response) {\r\n                    try {\r\n                        const json = JSON.parse(response.responseText);\r\n                        resolve(json);\r\n                    } catch (e) {\r\n                        console.error(`解析 JSON 失败: ${url}`, e);\r\n                        reject(e);\r\n                    }\r\n                },\r\n                onerror: function (err) {\r\n                    console.error(`加载失败: ${url}`, err);\r\n                    reject(err);\r\n                }\r\n            });\r\n        });\r\n    }\r\n\r\n    function buildCourseMaps(categoryList, outlineList) {\r\n        categoryList.forEach(item => {\r\n            if (item.course_code && item.category) {\r\n                courseCategoryMap[item.course_code.trim()] = item.category;\r\n            }\r\n        });\r\n\r\n        outlineList.forEach(item => {\r\n            if (item.course_code && item.id) {\r\n                courseOutlineMap[item.course_code.trim()] = item.id;\r\n            }\r\n        });\r\n    }\r\n\r\n    function createCreditSummaryWindow() {\r\n        // 使用统一的弹窗样式，但保持原有的固定位置和拖动功能\r\n        const container = document.createElement('div');\r\n        container.id = 'creditSummaryWindow';\r\n        container.style.cssText = `\r\n            position: fixed;\r\n            top: 40px;\r\n            right: 40px;\r\n            background: #fff;\r\n            border: 1px solid #e0e0e0;\r\n            border-radius: 14px;\r\n            padding: 0;\r\n            box-shadow: 0 8px 32px rgba(0,0,0,0.13);\r\n            z-index: 9999;\r\n            min-width: 420px;\r\n            max-width: 520px;\r\n            font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;\r\n            overflow: hidden;\r\n        `;\r\n\r\n        container.innerHTML = `\r\n            <div id=\"creditDragHandle\" style=\"\r\n                background: #f5f6fa;\r\n                padding: 14px 22px;\r\n                cursor: move;\r\n                display: flex;\r\n                justify-content: space-between;\r\n                align-items: center;\r\n                border-bottom: 1px solid #e0e0e0;\r\n            \">\r\n                <div style=\"color: #333; font-weight: 600; font-size: 17px; letter-spacing: 1px;\">\r\n                    🎓 南理工教务增强助手\r\n                </div>\r\n                <span style=\"\r\n                    cursor: pointer;\r\n                    color: #888;\r\n                    font-size: 18px;\r\n                    padding: 2px 8px;\r\n                    border-radius: 4px;\r\n                    transition: background-color 0.2s;\r\n                \"\r\n                onclick=\"this.closest('div').parentElement.remove()\"\r\n                onmouseover=\"this.style.backgroundColor='#e0e0e0'\"\r\n                onmouseout=\"this.style.backgroundColor='transparent'\">✕</span>\r\n            </div>\r\n            <div style=\"\r\n                background: #fff;\r\n                padding: 18px 22px 10px 22px;\r\n                max-height: 540px;\r\n                overflow-y: auto;\r\n            \">\r\n                <div id=\"creditSummary\"></div>\r\n                <div style=\"\r\n                    margin-top: 18px;\r\n                    padding-top: 12px;\r\n                    border-top: 1px solid #e0e0e0;\r\n                    font-size: 13px;\r\n                    color: #888;\r\n                    line-height: 1.6;\r\n                    text-align: left;\r\n                \">\r\n                 <div style=\"color: #e67e22; font-weight: 500; margin-bottom: 5px;\">⚠️ 特别声明</div>\r\n                    <div>选修课类别可能发生变化，仅供参考。<br>本工具可能因为教务处改版而不可靠，不对数据准确性负责</div>\r\n                    <div style=\"margin-bottom: 8px;\">\r\n                        <span>请查看 <a href=\"https://enhance.njust.wiki\" target=\"_blank\" style=\"color: #007bff; text-decoration: none;\">南理工教务增强助手官方网站</a> 以获取使用说明</span>\r\n                    </div>\r\n                </div>\r\n            </div>\r\n        `;\r\n\r\n        // 添加拖动功能\r\n        let isDragging = false;\r\n        let currentX, currentY, initialX, initialY;\r\n        let xOffset = 0, yOffset = 0;\r\n\r\n        const dragHandle = container.querySelector('#creditDragHandle');\r\n\r\n        function dragStart(e) {\r\n            if (e.type === \"touchstart\") {\r\n                initialX = e.touches[0].clientX - xOffset;\r\n                initialY = e.touches[0].clientY - yOffset;\r\n            } else {\r\n                initialX = e.clientX - xOffset;\r\n                initialY = e.clientY - yOffset;\r\n            }\r\n            if (e.target === dragHandle || dragHandle.contains(e.target)) {\r\n                isDragging = true;\r\n            }\r\n        }\r\n\r\n        function dragEnd(e) {\r\n            initialX = currentX;\r\n            initialY = currentY;\r\n            isDragging = false;\r\n        }\r\n\r\n        function drag(e) {\r\n            if (isDragging) {\r\n                e.preventDefault();\r\n                if (e.type === \"touchmove\") {\r\n                    currentX = e.touches[0].clientX - initialX;\r\n                    currentY = e.touches[0].clientY - initialY;\r\n                } else {\r\n                    currentX = e.clientX - initialX;\r\n                    currentY = e.clientY - initialY;\r\n                }\r\n                xOffset = currentX;\r\n                yOffset = currentY;\r\n                container.style.transform = `translate(${currentX}px, ${currentY}px)`;\r\n            }\r\n        }\r\n\r\n        dragHandle.addEventListener('mousedown', dragStart);\r\n        document.addEventListener('mousemove', drag);\r\n        document.addEventListener('mouseup', dragEnd);\r\n        dragHandle.addEventListener('touchstart', dragStart);\r\n        document.addEventListener('touchmove', drag);\r\n        document.addEventListener('touchend', dragEnd);\r\n\r\n        document.body.appendChild(container);\r\n        return container;\r\n    }\r\n\r\n    function updateCreditSummary() {\r\n        const creditSummaryDiv = document.getElementById('creditSummary');\r\n        if (!creditSummaryDiv) return;\r\n\r\n        const creditsByType = {}; // 按课程类型（通识教育课等）统计\r\n        const creditsByCategory = {}; // 按选修课类别统计\r\n        const tables = document.querySelectorAll('table');\r\n\r\n        tables.forEach(table => {\r\n            const rows = table.querySelectorAll('tr');\r\n            rows.forEach(row => {\r\n                const tds = row.querySelectorAll('td');\r\n                if (tds.length >= 11) {\r\n                    const courseCode = tds[2].textContent.trim();\r\n                    const credit = parseFloat(tds[6].textContent) || 0;\r\n                    const courseType = tds[10].textContent.trim(); // 课程类型（通识教育课等）\r\n\r\n                    // 从页面上已显示的类别信息中提取选修课类别\r\n                    const categoryDiv = tds[2].querySelector('[data-category-inserted]');\r\n                    let category = null;\r\n                    if (categoryDiv) {\r\n                        // 直接获取文本内容，因为现在只显示类别名称\r\n                        category = categoryDiv.textContent.trim();\r\n                        // 如果文本为空或者不是有效的类别，则设为null\r\n                        if (!category || category.length === 0) {\r\n                            category = null;\r\n                        }\r\n                    }\r\n\r\n                    // 按课程类型统计\r\n                    if (courseType) {\r\n                        if (!creditsByType[courseType]) {\r\n                            creditsByType[courseType] = {\r\n                                credits: 0,\r\n                                count: 0\r\n                            };\r\n                        }\r\n                        creditsByType[courseType].credits += credit;\r\n                        creditsByType[courseType].count += 1;\r\n                    }\r\n\r\n                    // 按选修课类别统计\r\n                    if (category) {\r\n                        if (!creditsByCategory[category]) {\r\n                            creditsByCategory[category] = {\r\n                                credits: 0,\r\n                                count: 0\r\n                            };\r\n                        }\r\n                        creditsByCategory[category].credits += credit;\r\n                        creditsByCategory[category].count += 1;\r\n                    }\r\n                }\r\n            });\r\n        });\r\n\r\n        // 计算总计\r\n        const totalCreditsByType = Object.values(creditsByType).reduce((sum, data) => sum + data.credits, 0);\r\n        const totalCountByType = Object.values(creditsByType).reduce((sum, data) => sum + data.count, 0);\r\n        const totalCreditsByCategory = Object.values(creditsByCategory).reduce((sum, data) => sum + data.credits, 0);\r\n        const totalCountByCategory = Object.values(creditsByCategory).reduce((sum, data) => sum + data.count, 0);\r\n\r\n        // 生成HTML - 表格样式布局\r\n        let summaryHTML = '<div style=\"border-bottom: 1px solid #e0e0e0; margin-bottom: 12px; padding-bottom: 10px;\">';\r\n        summaryHTML += '<div style=\"margin-bottom: 8px; font-size: 15px; color: #222; font-weight: 600; letter-spacing: 0.5px;\">📊 按课程类型统计</div>';\r\n        // 总计行\r\n        summaryHTML += `<div style=\"display: grid; grid-template-columns: 2fr 1fr 1fr; gap: 6px; padding: 2px 0; align-items: center; background: #f7f7fa; border-radius: 4px; padding: 4px 6px; margin-bottom: 4px;\">\r\n            <span style=\"color: #007bff; font-weight: 600; font-size: 13px; text-align: left;\">总计</span>\r\n            <span style=\"font-weight: 600; color: #007bff; font-size: 13px; text-align: left;\">${totalCreditsByType.toFixed(1)} 学分</span>\r\n            <span style=\"color: #007bff; font-weight: 600; font-size: 13px; text-align: left;\">${totalCountByType} 门</span>\r\n        </div>`;\r\n        // 课程类型表格\r\n        summaryHTML += '<div style=\"display: grid; gap: 2px;\">';\r\n        for (const [type, data] of Object.entries(creditsByType)) {\r\n            summaryHTML += `<div style=\"display: grid; grid-template-columns: 2fr 1fr 1fr; gap: 6px; padding: 2px 0; align-items: center;\">\r\n                <span style=\"color: #444; font-weight: 400; font-size: 13px; text-align: left;\">${type}</span>\r\n                <span style=\"font-weight: 400; color: #333; font-size: 13px; text-align: left;\">${data.credits.toFixed(1)} 学分</span>\r\n                <span style=\"color: #888; font-size: 13px; text-align: left;\">${data.count} 门</span>\r\n            </div>`;\r\n        }\r\n        summaryHTML += '</div>';\r\n        summaryHTML += '</div>';\r\n\r\n        if (Object.keys(creditsByCategory).length > 0) {\r\n            summaryHTML += '</div><div style=\"margin-top: 16px;\">';\r\n            summaryHTML += '<div style=\"margin-bottom: 8px; font-size: 15px; color: #222; font-weight: 600; letter-spacing: 0.5px;\">🏷️ 按选修课类别统计</div>';\r\n            // 总计行\r\n            summaryHTML += `<div style=\"display: grid; grid-template-columns: 2fr 1fr 1fr; gap: 6px; padding: 2px 0; align-items: center; background: #f7f7fa; border-radius: 4px; padding: 4px 6px; margin-bottom: 4px;\">\r\n                <span style=\"color: 007bff; font-weight: 600; font-size: 13px; text-align: left;\">总计</span>\r\n                <span style=\"font-weight: 600; color: #007bff; font-size: 13px; text-align: left;\">${totalCreditsByCategory.toFixed(1)} 学分</span>\r\n                <span style=\"color: #007bff; font-weight: 600; font-size: 13px; text-align: left;\">${totalCountByCategory} 门</span>\r\n            </div>`;\r\n            // 选修课类别表格\r\n            summaryHTML += '<div style=\"display: grid; gap: 2px;\">';\r\n            for (const [category, data] of Object.entries(creditsByCategory)) {\r\n                summaryHTML += `<div style=\"display: grid; grid-template-columns: 2fr 1fr 1fr; gap: 6px; padding: 2px 0; align-items: center;\">\r\n                    <span style=\"color: #444; font-weight: 400; font-size: 13px; text-align: left;\">${category}</span>\r\n                    <span style=\"font-weight: 400; color: #333; font-size: 13px; text-align: left;\">${data.credits.toFixed(1)} 学分</span>\r\n                    <span style=\"color: #888; font-size: 13px; text-align: left;\">${data.count} 门</span>\r\n                </div>`;\r\n            }\r\n            summaryHTML += '</div>';\r\n        }\r\n        summaryHTML += '</div>';\r\n\r\n        creditSummaryDiv.innerHTML = summaryHTML || '暂无数据';\r\n    }\r\n\r\n    function processAllTables() {\r\n        const tables = document.querySelectorAll('table');\r\n        const isGradePage = window.location.pathname.includes('/njlgdx/kscj/cjcx_list');\r\n        const isSchedulePage = window.location.pathname.includes('xskb_list.do') &&\r\n                              document.title.includes('学期理论课表');\r\n\r\n        tables.forEach(table => {\r\n            // 如果是课表页面，只处理 id=\"dataList\" 的表格\r\n            if (isSchedulePage && table.id !== 'dataList') {\r\n                return;\r\n            }\r\n\r\n            const rows = table.querySelectorAll('tr');\r\n            rows.forEach(row => {\r\n                const tds = row.querySelectorAll('td');\r\n                if (tds.length < 3) return;\r\n\r\n                let courseCodeTd;\r\n                let courseCode;\r\n\r\n                if (isGradePage) {\r\n                    courseCodeTd = tds[2]; // 成绩页面课程代码在第3列\r\n                    courseCode = courseCodeTd.textContent.trim();\r\n                } else if (isSchedulePage) {\r\n                    courseCodeTd = tds[1]; // 课表页面课程代码在第2列\r\n                    courseCode = courseCodeTd.textContent.trim();\r\n                } else {\r\n                    courseCodeTd = tds[1];\r\n                    const parts = courseCodeTd.innerHTML.split('<br>');\r\n                    if (parts.length === 2) {\r\n                        courseCode = parts[1].trim();\r\n                    } else {\r\n                        return;\r\n                    }\r\n                }\r\n\r\n                // 插入类别\r\n                if (!courseCodeTd.querySelector('[data-category-inserted]')) {\r\n                    const category = courseCategoryMap[courseCode];\r\n                    if (category) {\r\n                        const catDiv = document.createElement('div');\r\n                        catDiv.setAttribute('data-category-inserted', '1');\r\n                        catDiv.style.color = '#28a745';\r\n                        catDiv.style.fontWeight = 'bold';\r\n                        catDiv.style.marginTop = '4px';\r\n                        // 只显示类别名称，不显示前缀\r\n                        catDiv.textContent = category;\r\n                        courseCodeTd.appendChild(catDiv);\r\n                    }\r\n                }\r\n\r\n                // 插入老师说明（来自 title，仅在非成绩页面和非课表页面）\r\n                if (!isGradePage && !isSchedulePage && courseCodeTd.title && !courseCodeTd.querySelector('[data-title-inserted]')) {\r\n                    const titleDiv = document.createElement('div');\r\n                    titleDiv.setAttribute('data-title-inserted', '1');\r\n                    titleDiv.style.color = '#666';\r\n                    titleDiv.style.fontSize = '13   px';\r\n                    titleDiv.style.marginTop = '4px';\r\n                    titleDiv.style.fontStyle = 'italic';\r\n                    titleDiv.textContent = `📌 老师说明：${courseCodeTd.title}`;\r\n                    courseCodeTd.appendChild(titleDiv);\r\n                }\r\n\r\n                // 插入课程大纲链接\r\n                if (!courseCodeTd.querySelector('[data-outline-inserted]')) {\r\n                    const realId = courseOutlineMap[courseCode];\r\n                    const outlineDiv = document.createElement('div');\r\n                    outlineDiv.setAttribute('data-outline-inserted', '1');\r\n                    outlineDiv.style.marginTop = '4px';\r\n\r\n                    if (realId) {\r\n                        const link = document.createElement('a');\r\n                        link.href = `http://202.119.81.112:8080/kcxxAction.do?method=kcdgView&jx02id=${realId}&isentering=0`;\r\n                        link.textContent = '📘 查看课程大纲';\r\n                        link.target = '_blank';\r\n                        link.style.color = '#0077cc';\r\n                        outlineDiv.appendChild(link);\r\n                    } else {\r\n                        outlineDiv.textContent = '❌ 无大纲信息';\r\n                        outlineDiv.style.color = 'gray';\r\n                    }\r\n                    courseCodeTd.appendChild(outlineDiv);\r\n                }\r\n            });\r\n        });\r\n\r\n        // 更新学分统计（仅在成绩页面）\r\n        if (isGradePage) {\r\n            updateCreditSummary();\r\n        }\r\n    }\r\n\r\n    async function init() {\r\n        try {\r\n            // 首先检测强智科技页面\r\n            if (checkQiangzhiPage()) {\r\n                return; // 如果是强智科技页面，显示提示后直接返回\r\n            }\r\n\r\n            const [categoryData, outlineData] = await Promise.all([\r\n                loadJSON(CATEGORY_URL),\r\n                loadJSON(OUTLINE_URL)\r\n            ]);\r\n            buildCourseMaps(categoryData, outlineData);\r\n\r\n            // 如果是成绩页面，创建悬浮窗\r\n            if (window.location.pathname.includes('/njlgdx/kscj/cjcx_list')) {\r\n                createCreditSummaryWindow();\r\n            }\r\n\r\n            processAllTables();\r\n\r\n            const observer = new MutationObserver(() => {\r\n                // 每次页面变化时也检查强智科技页面\r\n                if (!checkQiangzhiPage()) {\r\n                    processAllTables();\r\n                }\r\n            });\r\n            observer.observe(document.body, { childList: true, subtree: true });\r\n\r\n        } catch (err) {\r\n            console.error('初始化失败：', err);\r\n        }\r\n    }\r\n\r\n    setTimeout(init, 1000);\r\n})();"]}