{"version":3,"sources":["jsdelivr-header.js","/gh/Rock-Candy-Tea/Friend-Circle-Frontend@HEAD/hexo-theme-butterfly/default.js"],"names":[],"mappings":"AAAA;AACA;AACA;AACA;AACA;AACA;AACA,ACNA,SAAS,qBACL,WAAa,CACT,gBAAiB,YAAY,iBAAmB,GAChD,oBAAqB,YAAY,qBAAuB,GACxD,UAAW,YAAY,WAAa,iFAGxC,MAEM,EAAO,SAAS,eAAe,2BACrC,IAAK,EAAM,OACX,EAAK,UAAY,GAEjB,MAAM,EAAe,SAAS,cAAc,OAC5C,EAAa,GAAK,mBAClB,EAAK,YAAY,GAEjB,MAAM,EAAY,SAAS,cAAc,OACzC,EAAU,UAAY,qBACtB,EAAU,GAAK,qBACf,EAAK,YAAY,GAEjB,MAAM,EAAc,SAAS,cAAc,UAC3C,EAAY,GAAK,gBACjB,EAAY,UAAY,OACxB,EAAK,YAAY,GAEjB,MAAM,EAAiB,SAAS,cAAc,OAC9C,EAAe,GAAK,kBACpB,EAAK,YAAY,GAEjB,IAAI,EAAQ,EACR,EAAc,GACd,EAAc,CAAC,EAEnB,SAAS,IACL,OAAO,aAAa,QAAQ,uBAAyB,SACzD,CAMA,SAAS,IACL,OAAO,aAAa,QAAQ,yBAA2B,SAC3D,CAMA,SAAS,IACL,MAA2B,WAApB,IA7CY,gCA6CoC,WAAW,eACtE,CAOA,SAAS,IACL,MAAM,EAAW,sBACX,EAAe,2BACf,EAAY,aAAa,QAAQ,GACjC,GAAM,IAAI,MAAO,UAEvB,GAAI,GAAc,EAAM,EAAY,IAAiB,CACjD,MAAM,EAAa,KAAK,MAAM,aAAa,QAAQ,IACnD,GAAI,EAEA,YADA,EAAgB,EAGxB,CAEA,MAAM,EAAS,IACT,EAAW,EAAO,SAAS,KAAO,EAAS,MAAQ,EAAS,OAElE,MAAM,GACD,KAAK,GAAY,EAAS,QAC1B,KAAK,IACF,aAAa,QAAQ,EAAU,KAAK,UAAU,IAC9C,aAAa,QAAQ,EAAc,EAAI,YACvC,EAAgB,KAEnB,QAAQ,KACL,EAAY,UAAY,QAEpC,CAEA,SAAS,EAAgB,GACrB,EAAc,EAAK,aACnB,EAAc,EAAK,iBAEnB,MAAM,EAAW,IACjB,EAAY,KAAK,CAAC,EAAG,IAAM,EAAE,GAAU,cAAc,EAAE,KAEvD,EAAe,UAAY,gPAAgP,EAAY,0BA2K3R,WACI,MAAM,EAAW,IACX,EAAa,IAEb,EAAY,mHAAmH,EAAY,4GAA4G,EAAY,2GAA2G,EAAY,wJAAmK,YAAX,EAAqB,OAAO,iDAA8D,YAAb,EAAuB,OAAO,8IAE7nB,EAAa,sbAEnB,EAAa,UAAY,EAAY,EAGrC,SAAS,eAAe,0BAA0B,iBAAiB,QAAS,SAAU,GAClF,EAAM,iBACN,GACJ,GAEA,SAAS,eAAe,mBAAmB,iBAAiB,QAAS,KApPzE,IAAqB,IAqPa,YAAb,EAAyB,UAAY,UApPtD,aAAa,QAAQ,qBAAsB,GAsPvC,EAAQ,EACR,EAAU,UAAY,GACtB,EAAgB,CAAE,aAAc,EAAa,iBAAkB,MAGnE,SAAS,eAAe,qBAAqB,iBAAiB,QAAS,KApP3E,IAAuB,IAqPa,YAAf,EAA2B,SAAW,UApPvD,aAAa,QAAQ,uBAAwB,GAQ7C,aAAa,WAAW,uBACxB,aAAa,WAAW,4BA8OpB,EAAQ,EACR,EAAU,UAAY,GACtB,MAIJ,IAGA,QAAQ,UAAU,KAAK,MAiB3B,iBACI,MAAM,EAAc,SAAS,eAAe,gBACtC,EAAc,SAAS,eAAe,gBAE5C,IAAK,IAAgB,EAEjB,YADA,QAAQ,KAAK,WAIjB,IAEI,MAAM,EAAiB,IAAI,QAAQ,CAAC,EAAG,IACnC,WAAW,IAAM,EAAO,IAAI,MAAM,SAAU,MAG1C,EAAa,IACb,EAAgB,EAAW,SAAS,KAAO,EAAa,UAAY,EAAa,YAChF,EAAsB,SAA+B,QAAQ,KAAK,CACrE,QAAQ,IAAI,CACR,MAAM,GAAG,KACT,MAAM,iDAEV,IAGE,QAAyB,EAAqB,OAC9C,QAAsB,EAAsB,OAC5C,EAAe,EAAiB,QAGtC,EAAY,YAAc,IAAI,EAAa,SAG3C,MAAM,EAAkB,EAAa,OAAO,QAAQ,KAAM,IAGtD,IAFqB,EAAc,OAAO,QAAQ,KAAM,KAIxD,EAAY,UAAY,iBACxB,EAAY,MAAQ,WACpB,EAAY,YAAc,aAG1B,EAAY,UAAY,iBACxB,EAAY,MAAQ,WACpB,EAAY,YAAc,SAAS,EAAc,SAEzD,CAAE,MAAO,GAEL,EAAY,YAAc,SAC1B,EAAY,UAAY,gBACxB,EAAY,MAAQ,WACpB,EAAY,YAAc,WAC1B,QAAQ,MAAM,UAAW,EAC7B,CACJ,CAvEQ,IAER,CAjNI,GAEiB,EAAY,MAAM,EAAO,EAAQ,WAAW,qBACpD,QAAQ,IACb,MAAM,EAAO,SAAS,cAAc,OACpC,EAAK,UAAY,OAEjB,MAAM,EAAQ,SAAS,cAAc,OACrC,EAAM,UAAY,aAClB,EAAM,UAAY,EAAQ,MAC1B,EAAM,QAAU,IAAM,OAAO,KAAK,EAAQ,KAAM,UAChD,EAAK,YAAY,GAEjB,MAAM,EAAkB,SAAS,cAAc,OAC/C,EAAgB,UAAY,mBAE5B,MAAM,EAAS,SAAS,cAAc,OACtC,EAAO,UAAY,cACnB,EAAO,MAAQ,EAAQ,OACvB,MAAM,EAAY,SAAS,cAAc,OACzC,EAAU,UAAY,cACtB,EAAU,IAAM,EAAQ,QAAU,WAAW,UAC7C,EAAU,QAAU,IAAM,EAAU,IAAM,WAAW,UACrD,EAAO,YAAY,GACnB,MAAM,EAAa,SAAS,cAAc,QAC1C,EAAW,UAAY,mBACvB,EAAW,UAAY,EAAQ,OAC/B,EAAO,YAAY,GACnB,EAAgB,YAAY,GAE5B,MAAM,EAAmB,SAAS,cAAc,OAEhD,GADA,EAAiB,UAAY,oBACzB,EAAQ,QAAS,CACjB,MAAM,EAAS,06DAIf,IAAI,EAHJ,EAAiB,UAAY,EAC7B,EAAgB,YAAY,GAI5B,MAAM,EAAa,IAEX,IACA,aAAa,GACb,EAAc,MAId,EAAiB,SAEjB,EAAiB,YAAY,EAAiB,QAC9C,EAAiB,OAAS,MAI9B,MAAM,EAAQ,SAAS,cAAc,OAC/B,EAAQ,EAAQ,SAAS,MAAM,KAAK,MAC1C,EAAM,UAAY,gBAClB,EAAM,UAAY,oEAC2B,0CAA+C,mDAAuD,EAAQ,yEAAyE,IAAI,KAAK,EAAQ,oBAAoB,mBAAmB,QAAS,CAAC,MAAO,UAAW,IAAK,YAAY,QAAQ,MAAO,QAAQ,IAAI,KAAK,EAAQ,oBAAoB,mBAAmB,QAAS,CAAC,KAAM,UAAW,OAAQ,UAAW,QAAQ,mBAG9c,EAAM,MAAM,WAAa,SACzB,EAAM,MAAM,SAAW,QACvB,SAAS,KAAK,YAAY,GAG1B,MAAM,EAAS,EAAM,QACf,EAAS,EAAM,QACf,EAAc,OAAO,WACrB,EAAe,OAAO,YAGtB,EAAW,KAAK,IAAI,IAAK,EAAc,IAC7C,EAAM,MAAM,MAAQ,EAAW,KAG/B,MAAM,EAAY,EAAM,wBAClB,EAAa,EAAU,MACvB,EAAc,EAAU,OAG9B,IAAI,EAAO,EAAS,GAChB,EAAM,EAAS,GAGf,EAAO,EAAa,IACpB,EAAO,EAAS,EAAa,IAI7B,EAAM,EAAc,IACpB,EAAM,EAAS,EAAc,IAIjC,EAAO,KAAK,IAAI,GAAI,GACpB,EAAM,KAAK,IAAI,GAAI,GAGnB,EAAM,MAAM,QAAU,SAAS,YAAe,cAAgB,8EAG9D,sBAAsB,KAClB,EAAM,MAAM,UAAY,yBACxB,EAAM,MAAM,QAAU,MAI1B,EAAiB,OAAS,EAG1B,EAAM,iBAAiB,aAAc,KAC7B,IACA,aAAa,GACb,EAAc,QAItB,EAAM,iBAAiB,aAAc,IAGnC,EAAY,KACd,EAAc,WAAW,KACrB,MAAM,EAAQ,EAAiB,OAC3B,IACA,EAAM,MAAM,UAAY,+BACxB,EAAM,MAAM,QAAU,IAEtB,WAAW,KACH,EAAM,YACN,SAAS,KAAK,YAAY,GAE9B,EAAiB,OAAS,MAC3B,MAEP,EAAc,MACf,KAGP,EAAiB,iBAAiB,aAAc,GAChD,EAAiB,iBAAiB,aAAc,EACpD,CACA,EAAK,YAAY,GAEjB,EAAO,QAAU,MAwIzB,SAA4B,EAAQ,EAAQ,GACxC,IAAK,SAAS,eAAe,SAAU,CACnC,MAAM,EAAQ,SAAS,cAAc,OACrC,EAAM,GAAK,QACX,EAAM,UAAY,QAClB,EAAM,UAAY,yLAClB,EAAK,YAAY,EACrB,CAEA,MAAM,EAAQ,SAAS,eAAe,SAChC,EAAyB,SAAS,eAAe,4BACjD,EAAoB,SAAS,eAAe,uBAC5C,EAAsB,SAAS,eAAe,0BAC9C,EAAU,SAAS,eAAe,YAExC,EAAuB,UAAY,GACnC,EAAkB,IAAM,GAAU,WAAW,UAC7C,EAAkB,QAAU,IAAM,EAAkB,IAAM,WAAW,UACrE,EAAQ,IAAM,GAAU,WAAW,UACnC,EAAQ,QAAU,IAAM,EAAQ,IAAM,WAAW,UACjD,EAAoB,UAAY,EAChC,EAAoB,KAAO,IAAI,IAAI,GAAM,OAEzC,MAAM,EAAiB,EAAY,OAAO,GAAW,EAAQ,SAAW,GACxE,EAAe,MAAM,EAAG,GAAG,QAAQ,IAC/B,MAAM,EAAa,SAAS,cAAc,OAC1C,EAAW,UAAY,gBAEvB,MAAM,EAAQ,SAAS,cAAc,KACrC,EAAM,UAAY,sBAClB,EAAM,UAAY,EAAQ,MAC1B,EAAM,KAAO,EAAQ,KACrB,EAAM,OAAS,SACf,EAAW,YAAY,GAEvB,MAAM,EAAO,SAAS,cAAc,OACpC,EAAK,UAAY,qBACjB,EAAK,UAAY,KAAO,EAAQ,QAAQ,UAAU,EAAG,IACrD,EAAW,YAAY,GAEvB,EAAuB,YAAY,KAGvC,EAAM,MAAM,QAAU,QACtB,WAAW,KACP,EAAM,UAAU,IAAI,eACrB,GACP,CAtLY,CAAmB,EAAQ,OAAQ,EAAQ,OAAQ,EAAQ,OAG/D,MAAM,EAAO,SAAS,cAAc,OACpC,EAAK,UAAY,YACjB,EAAK,UAAY,MAAQ,EAAQ,QAAQ,UAAU,EAAG,IACtD,EAAK,YAAY,GAEjB,MAAM,EAAQ,SAAS,cAAc,OACrC,EAAM,UAAY,sBAClB,EAAM,IAAM,EAAQ,QAAU,WAAW,UACzC,EAAM,QAAU,IAAM,EAAM,IAAM,WAAW,UAC7C,EAAK,YAAY,GAEjB,EAAU,YAAY,KAG1B,GAAS,WAAW,oBAChB,GAAS,EAAY,SACrB,EAAY,MAAM,QAAU,OAEpC,CA8CA,SAAS,IACL,MAAM,EAAgB,EAAY,KAAK,MAAM,KAAK,SAAW,EAAY,SAEzE,SAAS,eAAe,iBAAiB,YAAc,EAAc,OACrE,SAAS,eAAe,gBAAgB,YAAc,EAAc,MACpE,SAAS,eAAe,sBAAsB,QAAU,IAAM,OAAO,KAAK,EAAc,KAAM,SAClG,CAwHA,IACA,EAAY,iBAAiB,QAAS,GACtC,OAAO,QAAU,SAAU,GACvB,MAAM,EAAQ,SAAS,eAAe,SAClC,EAAM,SAAW,GAbzB,WACI,MAAM,EAAQ,SAAS,eAAe,SACtC,EAAM,UAAU,OAAO,cACvB,EAAM,iBAAiB,gBAAiB,KACpC,EAAM,MAAM,QAAU,OACtB,EAAK,YAAY,IAClB,CAAE,MAAM,GACf,CAMgC,EAChC,CACJ,CAEA,SAAS,eACL,oBACJ,CAEA,eACA,SAAS,iBAAiB,gBAAiB","file":"/gh/Rock-Candy-Tea/Friend-Circle-Frontend@HEAD/hexo-theme-butterfly/default.js","sourceRoot":"","sourcesContent":["/**\n * Minified by jsDelivr using Terser v5.48.0.\n * Original file: /gh/Rock-Candy-Tea/Friend-Circle-Frontend@HEAD/hexo-theme-butterfly/default.js\n *\n * Do NOT use SRI with dynamically generated files! More information: https://www.jsdelivr.com/using-sri-with-dynamic-files\n */\n","function initialize_fc_lite() {\n    UserConfig = {\n        private_api_url: UserConfig?.private_api_url || \"\",\n        page_turning_number: UserConfig?.page_turning_number || 24,\n        error_img: UserConfig?.error_img || \"https://fastly.jsdelivr.net/gh/Rock-Candy-Tea/Friend-Circle-Frontend/logo.png\"\n    };\n\n    const PUBLIC_API_URL = 'https://fc-example.430070.xyz';\n\n    const root = document.getElementById('friend-circle-container');\n    if (!root) return;\n    root.innerHTML = '';\n\n    const TopContainer = document.createElement('div');\n    TopContainer.id = 'top-fc-container';\n    root.appendChild(TopContainer);\n\n    const container = document.createElement('div');\n    container.className = 'articles-container';\n    container.id = 'articles-container';\n    root.appendChild(container);\n\n    const loadMoreBtn = document.createElement('button');\n    loadMoreBtn.id = 'load-more-btn';\n    loadMoreBtn.innerText = '再来亿点';\n    root.appendChild(loadMoreBtn);\n\n    const statsContainer = document.createElement('div');\n    statsContainer.id = 'stats-container';\n    root.appendChild(statsContainer);\n\n    let start = 0;\n    let allArticles = [];\n    let globalStats = {};\n\n    function getSortRule() {\n        return localStorage.getItem('friend-circle-sort') || 'created';\n    }\n\n    function setSortRule(rule) {\n        localStorage.setItem('friend-circle-sort', rule);\n    }\n\n    function getDataSource() {\n        return localStorage.getItem('friend-circle-source') || 'private';\n    }\n\n    function setDataSource(source) {\n        localStorage.setItem('friend-circle-source', source);\n    }\n\n    function getApiUrl() {\n        return getDataSource() === 'public' ? PUBLIC_API_URL : UserConfig.private_api_url;\n    }\n\n    function clearCache() {\n        localStorage.removeItem('friend-circle-cache');\n        localStorage.removeItem('friend-circle-cache-time');\n    }\n\n    function loadMoreArticles() {\n        const cacheKey = 'friend-circle-cache';\n        const cacheTimeKey = 'friend-circle-cache-time';\n        const cacheTime = localStorage.getItem(cacheTimeKey);\n        const now = new Date().getTime();\n\n        if (cacheTime && (now - cacheTime < 10 * 60 * 1000)) {\n            const cachedData = JSON.parse(localStorage.getItem(cacheKey));\n            if (cachedData) {\n                processArticles(cachedData);\n                return;\n            }\n        }\n\n        const apiUrl = getApiUrl();\n        const finalUrl = apiUrl.endsWith('/') ? apiUrl + 'all' : apiUrl + '/all';\n\n        fetch(finalUrl)\n            .then(response => response.json())\n            .then(data => {\n                localStorage.setItem(cacheKey, JSON.stringify(data));\n                localStorage.setItem(cacheTimeKey, now.toString());\n                processArticles(data);\n            })\n            .finally(() => {\n                loadMoreBtn.innerText = '再来亿点';\n            });\n    }\n\n    function processArticles(data) {\n        allArticles = data.article_data;\n        globalStats = data.statistical_data;\n\n        const sortRule = getSortRule();\n        allArticles.sort((a, b) => b[sortRule].localeCompare(a[sortRule]));\n\n        statsContainer.innerHTML = `<div>Powered by: <a href=\"https://github.com/Rock-Candy-Tea/hexo-circle-of-friends\" target=\"_blank\">Hexo Circle of Friends</a><br></div><div>Designed By: <a href=\"https://www.liushen.fun/\" target=\"_blank\">LiuShen</a><br></div><div>更新时间: ${globalStats.last_updated_time}</div>`;\n\n        initializeTopSection();\n\n        const articles = allArticles.slice(start, start + UserConfig.page_turning_number);\n        articles.forEach(article => {\n            const card = document.createElement('div');\n            card.className = 'card';\n\n            const title = document.createElement('div');\n            title.className = 'card-title';\n            title.innerText = article.title;\n            title.onclick = () => window.open(article.link, '_blank');\n            card.appendChild(title);\n\n            const authorContainer = document.createElement('div');\n            authorContainer.className = 'author-container';\n            \n            const author = document.createElement('div');\n            author.className = 'card-author';\n            author.title = article.author;\n            const authorImg = document.createElement('img');\n            authorImg.className = 'no-lightbox';\n            authorImg.src = article.avatar || UserConfig.error_img;\n            authorImg.onerror = () => authorImg.src = UserConfig.error_img;\n            author.appendChild(authorImg);\n            const authorName = document.createElement('span');\n            authorName.className = 'card-author-name';\n            authorName.innerText = article.author;\n            author.appendChild(authorName);\n            authorContainer.appendChild(author);\n            \n            const summaryIndicator = document.createElement('div');\n            summaryIndicator.className = 'summary-indicator';\n            if (article.summary) {\n                const gptSvg = `<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 640 640\"><path d=\"M260.4 249.8L260.4 201.2C260.4 197.1 261.9 194 265.5 192L363.3 135.7C376.6 128 392.5 124.4 408.9 124.4C470.3 124.4 509.3 172 509.3 222.7C509.3 226.3 509.3 230.4 508.8 234.5L407.3 175.1C401.2 171.5 395 171.5 388.9 175.1L260.4 249.8zM488.7 439.2L488.7 323C488.7 315.8 485.6 310.7 479.5 307.1L351 232.4L393 208.3C396.6 206.3 399.7 206.3 403.2 208.3L501 264.7C529.2 281.1 548.1 315.9 548.1 349.7C548.1 388.6 525.1 424.5 488.7 439.3L488.7 439.3zM230.2 336.8L188.2 312.2C184.6 310.2 183.1 307.1 183.1 303L183.1 190.4C183.1 135.6 225.1 94.1 281.9 94.1C303.4 94.1 323.4 101.3 340.3 114.1L239.4 172.5C233.3 176.1 230.2 181.2 230.2 188.4L230.2 336.9L230.2 336.9zM320.6 389L260.4 355.2L260.4 283.5L320.6 249.7L380.8 283.5L380.8 355.2L320.6 389zM359.3 544.7C337.8 544.7 317.8 537.5 300.9 524.7L401.8 466.3C407.9 462.7 411 457.6 411 450.4L411 301.9L453.5 326.5C457.1 328.5 458.6 331.6 458.6 335.7L458.6 448.3C458.6 503.1 416.1 544.6 359.3 544.6L359.3 544.6zM237.8 430.5L140.1 374.2C111.9 357.8 93 323 93 289.2C93 249.8 116.6 214.4 152.9 199.6L152.9 316.3C152.9 323.5 156 328.6 162.1 332.2L290.1 406.4L248.1 430.5C244.5 432.5 241.4 432.5 237.9 430.5zM232.2 514.5C174.3 514.5 131.8 471 131.8 417.2C131.8 413.1 132.3 409 132.8 404.9L233.7 463.3C239.8 466.9 246 466.9 252.1 463.3L380.6 389.1L380.6 437.7C380.6 441.8 379.1 444.9 375.5 446.9L277.7 503.2C264.4 510.9 248.5 514.5 232.1 514.5L232.1 514.5zM359.2 575.4C421.2 575.4 472.9 531.4 484.6 473C541.9 458.1 578.8 404.4 578.8 349.6C578.8 313.8 563.4 278.9 535.8 253.9C538.4 243.1 539.9 232.4 539.9 221.6C539.9 148.4 480.5 93.6 411.9 93.6C398.1 93.6 384.8 95.6 371.5 100.3C348.5 77.8 316.7 63.4 281.9 63.4C219.9 63.4 168.2 107.4 156.5 165.8C99.2 180.6 62.3 234.4 62.3 289.2C62.3 325 77.7 359.9 105.3 384.9C102.7 395.7 101.2 406.4 101.2 417.2C101.2 490.4 160.6 545.2 229.2 545.2C243 545.2 256.3 543.2 269.6 538.5C292.6 561 324.4 575.4 359.2 575.4z\"/></svg>`;\n                summaryIndicator.innerHTML = gptSvg;\n                authorContainer.appendChild(summaryIndicator);\n\n                let hideTimeout;\n\n                const showPopup = (event) => {\n                    // 清除隐藏定时器\n                    if (hideTimeout) {\n                        clearTimeout(hideTimeout);\n                        hideTimeout = null;\n                    }\n                    \n                    // 如果弹窗已存在，直接返回\n                    if (summaryIndicator._popup) {\n                        // 删掉弹窗\n                        summaryIndicator.removeChild(summaryIndicator._popup);\n                        summaryIndicator._popup = null;\n                    }\n                    \n                    // 创建弹窗元素\n                    const popup = document.createElement('div');\n                    const model = article.ai_model.split('/').pop();\n                    popup.className = 'summary-popup';\n                    popup.innerHTML = `\n                        <div class=\"summary-popup-title\"><span>${gptSvg}文章摘要</span><div class=\"summary-model\">${model}</div></div><div class=\"summary-popup-content\">${article.summary}</div><div class=\"summary-popup-updated-at\">🕙Update at: <span>${new Date(article.summary_updated_at).toLocaleDateString('zh-CN', {month: '2-digit', day: '2-digit'}).replace(/\\//g, '-')} ${new Date(article.summary_updated_at).toLocaleTimeString('zh-CN', {hour: '2-digit', minute: '2-digit', hour12: false})}</span></div>`;\n                    \n                    // 添加到body中，先设置为不可见以便测量\n                    popup.style.visibility = 'hidden';\n                    popup.style.position = 'fixed';\n                    document.body.appendChild(popup);\n                    \n                    // 获取鼠标位置和屏幕尺寸\n                    const mouseX = event.clientX;\n                    const mouseY = event.clientY;\n                    const screenWidth = window.innerWidth;\n                    const screenHeight = window.innerHeight;\n                    \n                    // 计算响应式宽度\n                    const maxWidth = Math.min(400, screenWidth - 40);\n                    popup.style.width = maxWidth + 'px';\n                    \n                    // 获取实际高度\n                    const popupRect = popup.getBoundingClientRect();\n                    const popupWidth = popupRect.width;\n                    const popupHeight = popupRect.height;\n                    \n                    // 计算弹窗位置\n                    let left = mouseX + 10;\n                    let top = mouseY + 10;\n                    \n                    // 检查是否超出右边界，如果是则显示在左侧\n                    if (left + popupWidth > screenWidth) {\n                        left = mouseX - popupWidth - 10;\n                    }\n                    \n                    // 检查是否超出下边界，如果是则显示在上方\n                    if (top + popupHeight > screenHeight) {\n                        top = mouseY - popupHeight - 10;\n                    }\n                    \n                    // 确保不会超出左边界和上边界\n                    left = Math.max(10, left);\n                    top = Math.max(10, top);\n                    \n                    // 设置弹窗最终位置和样式\n                    popup.style.cssText = `left: ${left}px;top: ${top}px;width: ${maxWidth}px;visibility: visible;transform: scale(0.8) translateY(-10px);opacity: 0;`;\n                    \n                    // 添加动画效果\n                    requestAnimationFrame(() => {\n                        popup.style.transform = 'scale(1) translateY(0)';\n                        popup.style.opacity = '1';\n                    });\n                    \n                    // 存储弹窗引用\n                    summaryIndicator._popup = popup;\n                    \n                    // 为弹窗添加鼠标事件\n                    popup.addEventListener('mouseenter', () => {\n                        if (hideTimeout) {\n                            clearTimeout(hideTimeout);\n                            hideTimeout = null;\n                        }\n                    });\n                    \n                    popup.addEventListener('mouseleave', hidePopup);\n                };\n\n                const hidePopup = () => {\n                    hideTimeout = setTimeout(() => {\n                        const popup = summaryIndicator._popup;\n                        if (popup) {\n                            popup.style.transform = 'scale(0.8) translateY(-10px)';\n                            popup.style.opacity = '0';\n                            \n                            setTimeout(() => {\n                                if (popup.parentNode) {\n                                    document.body.removeChild(popup);\n                                }\n                                summaryIndicator._popup = null;\n                            }, 300);\n                        }\n                        hideTimeout = null;\n                    }, 30); // 100ms延迟，给鼠标移动到弹窗的时间\n                };\n\n                summaryIndicator.addEventListener('mouseenter', showPopup);\n                summaryIndicator.addEventListener('mouseleave', hidePopup);\n            }\n            card.appendChild(authorContainer);\n\n            author.onclick = () => {\n                showAuthorArticles(article.author, article.avatar, article.link);\n            };\n\n            const date = document.createElement('div');\n            date.className = 'card-date';\n            date.innerText = \"🗓️\" + article.created.substring(0, 10);\n            card.appendChild(date);\n\n            const bgImg = document.createElement('img');\n            bgImg.className = 'card-bg no-lightbox';\n            bgImg.src = article.avatar || UserConfig.error_img;\n            bgImg.onerror = () => bgImg.src = UserConfig.error_img;\n            card.appendChild(bgImg);\n\n            container.appendChild(card);\n        });\n\n        start += UserConfig.page_turning_number;\n        if (start >= allArticles.length) {\n            loadMoreBtn.style.display = 'none';\n        }\n    }\n\n    // 初始化统计卡片和随机文章结构\n    function initializeTopSection() {\n        const sortRule = getSortRule();\n        const sourceRule = getDataSource();\n\n        const statsCard = `<div class=\"stats-card-container\"><div class=\"stats-card-left\"><div class=\"stats-item\"><div class=\"stats-value\">${globalStats.friends_num}</div><div class=\"stats-label\">订阅</div></div><div class=\"stats-item\"><div class=\"stats-value\">${globalStats.active_num}</div><div class=\"stats-label\">活跃</div></div><div class=\"stats-item\"><div class=\"stats-value\">${globalStats.article_num}</div><div class=\"stats-label\">文章</div></div></div><div class=\"stats-card-right\"><div class=\"stats-controls\"><button id=\"sort-toggle-btn\">${sortRule==='created'?'发布时间':'更新时间'}</button><button id=\"source-toggle-btn\">${sourceRule==='private'?'私有订阅':'公共订阅'}</button></div><div class=\"stats-version\"><span id=\"version-text\">加载中</span><span id=\"version-info\">正在与主机通讯中</span></div></div></div>`;\n\n        const randomCard = `<div class=\"random-container\"><div class=\"random-content-container\"><div class=\"random-content\"><span class=\"random-container-title\">🎣随机钓鱼:</span>钓到了<span class=\"random-author\"id=\"random-author\"></span>的文章:<span class=\"random-title\"id=\"random-title\"></span></div></div><div class=\"random-button-container\"><button id=\"refresh-random-article\">刷新</button><button class=\"random-link-button\"id=\"random-link-button\">看看</button></div></div>`;\n\n        TopContainer.innerHTML = statsCard + randomCard;\n\n        // 绑定事件监听器\n        document.getElementById('refresh-random-article').addEventListener('click', function (event) {\n            event.preventDefault();\n            updateRandomArticle();\n        });\n\n        document.getElementById('sort-toggle-btn').addEventListener('click', () => {\n            const next = sortRule === 'created' ? 'updated' : 'created';\n            setSortRule(next);\n            start = 0;\n            container.innerHTML = '';\n            processArticles({ article_data: allArticles, statistical_data: globalStats });\n        });\n\n        document.getElementById('source-toggle-btn').addEventListener('click', () => {\n            const next = sourceRule === 'private' ? 'public' : 'private';\n            setDataSource(next);\n            clearCache();\n            start = 0;\n            container.innerHTML = '';\n            loadMoreArticles();\n        });\n\n        // 初始化显示第一篇随机文章\n        updateRandomArticle();\n        \n        // 异步检查版本更新，不阻塞主流程\n        Promise.resolve().then(() => {\n            checkVersionUpdate();\n        });\n    }\n\n    // 更新随机文章数据\n    function updateRandomArticle() {\n        const randomArticle = allArticles[Math.floor(Math.random() * allArticles.length)];\n        \n        document.getElementById('random-author').textContent = randomArticle.author;\n        document.getElementById('random-title').textContent = randomArticle.title;\n        document.getElementById('random-link-button').onclick = () => window.open(randomArticle.link, '_blank');\n    }\n\n\n\n    // 异步检查版本更新\n    async function checkVersionUpdate() {\n        const versionText = document.getElementById('version-text');\n        const versionInfo = document.getElementById('version-info');\n        \n        if (!versionText || !versionInfo) {\n            console.warn('版本元素未找到');\n            return;\n        }\n\n        try {\n            // 使用 Promise.all 并行请求，但设置超时避免阻塞\n            const timeoutPromise = new Promise((_, reject) => \n                setTimeout(() => reject(new Error('请求超时')), 5000)\n            );\n\n            const baseApiUrl = getApiUrl();\n            const VersionApiUrl = baseApiUrl.endsWith('/') ? baseApiUrl + 'version' : baseApiUrl + '/version';\n            const [localVersionResponse, latestVersionResponse] = await Promise.race([\n                Promise.all([\n                    fetch(`${VersionApiUrl}`),\n                    fetch('https://fcircle-doc.yyyzyyyz.cn/version.txt')\n                ]),\n                timeoutPromise\n            ]);\n\n            const localVersionData = await localVersionResponse.json();\n            const latestVersion = await latestVersionResponse.text();\n            const localVersion = localVersionData.version;\n            \n            // 更新版本显示 - 显示时加上v前缀\n            versionText.textContent = `v${localVersion.trim()}`;\n            \n            // 标准化版本号进行比较（都去掉v前缀）\n            const normalizedLocal = localVersion.trim().replace(/^v/, '');\n            const normalizedLatest = latestVersion.trim().replace(/^v/, '');\n            \n            if (normalizedLocal === normalizedLatest) {\n                // 最新版 - 绿色\n                versionText.className = 'version-latest';\n                versionText.title = '当前已为最新版本';\n                versionInfo.textContent = '当前已为最新版本';\n            } else {\n                // 有更新 - 橙色\n                versionText.className = 'version-update';\n                versionText.title = `现有新版本可更新`;\n                versionInfo.textContent = `新版本可用:${latestVersion.trim()}`;\n            }\n        } catch (error) {\n            // 获取失败 - 红色\n            versionText.textContent = 'v0.0.0';\n            versionText.className = 'version-error';\n            versionText.title = '版本信息获取失败';\n            versionInfo.textContent = '版本信息获取失败';\n            console.error('版本检查失败:', error);\n        }\n    }\n\n    function showAuthorArticles(author, avatar, link) {\n        if (!document.getElementById('modal')) {\n            const modal = document.createElement('div');\n            modal.id = 'modal';\n            modal.className = 'modal';\n            modal.innerHTML = `<div class=\"modal-content\"><img id=\"modal-author-avatar\"src=\"\"alt=\"\"><a id=\"modal-author-name-link\"></a><div id=\"modal-articles-container\"></div><img id=\"modal-bg\"src=\"\"alt=\"\"></div>`;\n            root.appendChild(modal);\n        }\n\n        const modal = document.getElementById('modal');\n        const modalArticlesContainer = document.getElementById('modal-articles-container');\n        const modalAuthorAvatar = document.getElementById('modal-author-avatar');\n        const modalAuthorNameLink = document.getElementById('modal-author-name-link');\n        const modalBg = document.getElementById('modal-bg');\n\n        modalArticlesContainer.innerHTML = '';\n        modalAuthorAvatar.src = avatar || UserConfig.error_img;\n        modalAuthorAvatar.onerror = () => modalAuthorAvatar.src = UserConfig.error_img;\n        modalBg.src = avatar || UserConfig.error_img;\n        modalBg.onerror = () => modalBg.src = UserConfig.error_img;\n        modalAuthorNameLink.innerText = author;\n        modalAuthorNameLink.href = new URL(link).origin;\n\n        const authorArticles = allArticles.filter(article => article.author === author);\n        authorArticles.slice(0, 4).forEach(article => {\n            const articleDiv = document.createElement('div');\n            articleDiv.className = 'modal-article';\n\n            const title = document.createElement('a');\n            title.className = 'modal-article-title';\n            title.innerText = article.title;\n            title.href = article.link;\n            title.target = '_blank';\n            articleDiv.appendChild(title);\n\n            const date = document.createElement('div');\n            date.className = 'modal-article-date';\n            date.innerText = \"📅\" + article.created.substring(0, 10);\n            articleDiv.appendChild(date);\n\n            modalArticlesContainer.appendChild(articleDiv);\n        });\n\n        modal.style.display = 'block';\n        setTimeout(() => {\n            modal.classList.add('modal-open');\n        }, 10);\n    }\n\n    function hideModal() {\n        const modal = document.getElementById('modal');\n        modal.classList.remove('modal-open');\n        modal.addEventListener('transitionend', () => {\n            modal.style.display = 'none';\n            root.removeChild(modal);\n        }, { once: true });\n    }\n\n    loadMoreArticles();\n    loadMoreBtn.addEventListener('click', loadMoreArticles);\n    window.onclick = function (event) {\n        const modal = document.getElementById('modal');\n        if (event.target === modal) hideModal();\n    };\n}\n\nfunction whenDOMReady() {\n    initialize_fc_lite();\n}\n\nwhenDOMReady();\ndocument.addEventListener(\"pjax:complete\", initialize_fc_lite);\n"]}