<html>
<head>
<meta charset="utf-8">
<meta http-equiv="x-dns-prefetch-control" content="on">
<link rel="dns-prefetch" href="//cdn.jsdelivr.net">
<%
    local fs = require "luci.openclash"
    local plugin_version = fs.oc_version()
%>
<script src="/luci-static/resources/openclash/js/oc-icons.js?v=<%=plugin_version%>"></script>
<link rel="dns-prefetch" href="//whois.pconline.com.cn">
<link rel="dns-prefetch" href="//pubstatic.b0.upaiyun.com">
<link rel="dns-prefetch" href="//api.ip.sb">
<link rel="dns-prefetch" href="//api.ipify.org">
<link rel="dns-prefetch" href="//myip.ipip.net">
<link rel="preconnect" href="https://pubstatic.b0.upaiyun.com">
<link rel="preconnect" href="https://whois.pconline.com.cn">
<link rel="preconnect" href="https://api.ip.sb">
<link rel="preconnect" href="https://api.ipify.org">
<link rel="preconnect" href="http://myip.ipip.net">
<meta name="referrer" content="no-referrer">
<meta name="viewport" content="width=device-width,initial-scale=1,user-scalable=no,minimal-ui">
<title>IP 地址查询</title>
</head>

<fieldset class="cbi-section">
    <table width="100%">
        <tr>
            <td>
                <div class="oc">
                    <div class="myip-main-card">
                        <div class="myip-content-grid">
                            <div class="myip-ip-section">
                                <p class="myip-section-title">
                                    <%:IP Address%>
                                    <span class="myip-toolbar">
                                        <svg id="eye-icon" class="myip-icon-btn" width="20" height="20" viewBox="0 0 256 256" fill="none" xmlns="http://www.w3.org/2000/svg" onclick="return privacy_my_ip(this)">
                                            <title><%:Hide IP%></title>
                                            <path id="eye-open" d="M128,56C48,56,16,128,16,128s32,72,112,72,112-72,112-72S208,56,128,56Z" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="12"></path>
                                            <circle id="eye-open-circle" cx="128" cy="128" r="40" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="12"></circle>
                                            <g id="eye-closed" style="display: none;">
                                                <line x1="48" y1="40" x2="208" y2="216" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="12"></line>
                                                <path d="M154.9,157.6A39.6,39.6,0,0,1,128,168a40,40,0,0,1-26.9-69.6" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="12"></path>
                                                <path d="M74,68.6C33.2,89.2,16,128,16,128s32,72,112,72a117.9,117.9,0,0,0,54-12.6" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="12"></path>
                                                <path d="M208.6,169.1C230.4,149.6,240,128,240,128S208,56,128,56a123.9,123.9,0,0,0-20.7,1.7" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="12"></path>
                                                <path d="M135.5,88.7a39.9,39.9,0,0,1,32.3,35.5" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="12"></path>
                                            </g>
                                        </svg>
                                    </span>
                                </p>

                                <div class="myip-ip-list">
                                    <div class="myip-ip-item">
                                        <span class="ip-title">UpaiYun</span>
                                        <div class="myip-ip-result">
                                            <span class="ip-result" id="ip-upaiyun"></span>
                                            <span class="ip-geo" id="ip-upaiyun-geo"></span>
                                        </div>
                                    </div>

                                    <div class="myip-ip-item">
                                        <span class="ip-title">IPIP.NET</span>
                                        <div class="myip-ip-result">
                                            <span class="ip-result" id="ip-ipip"></span>
                                            <span class="ip-geo" id="ip-ipip-geo"></span>
                                        </div>
                                    </div>

                                    <div class="myip-ip-item">
                                        <span class="ip-title">IP.SB</span>
                                        <div class="myip-ip-result">
                                            <span class="ip-result" id="ip-ipsb"></span>
                                            <span class="ip-geo" id="ip-ipsb-geo"></span>
                                        </div>
                                    </div>

                                    <div class="myip-ip-item">
                                        <span class="ip-title">IPIFY</span>
                                        <div class="myip-ip-result">
                                            <span class="ip-result" id="ip-ipify"></span>
                                            <span class="ip-geo" id="ip-ipify-geo"></span>
                                        </div>
                                    </div>
                                </div>
                            </div>

                            <div class="myip-check-section">
                                <p class="myip-section-title">
                                    <%:Access Check%>
                                    <span class="myip-toolbar">
                                        <svg id="mode-icon" class="mode-icon myip-icon-btn" width="22" height="22" viewBox="0 0 48 48" fill="none" xmlns="http://www.w3.org/2000/svg" onclick="return toggle_mode_by_icon(this)">
                                            <title><%:Router Mode%></title>
                                            <rect x="4" y="28" width="40" height="14" rx="2" fill="#2F88FF" stroke="#333" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"/>
                                            <path d="M14 35L22 35" stroke="#FFF" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"/>
                                            <rect x="30" y="33" width="4" height="4" rx="2" fill="#FFF"/>
                                            <path d="M12 28L12 8" stroke="#333" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"/>
                                            <path d="M36 28V8" stroke="#333" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"/>
                                        </svg>
                                        <svg id="data-refresh-icon" class="myip-icon-btn" width="20" height="20" onclick="return refresh_myip(this)">
                                            <title><%:Refresh%></title>
                                            <use href="#oc-icon-refresh"/>
                                        </svg>
                                    </span>
                                </p>

                                <div class="myip-check-list">
                                    <div class="myip-check-item">
                                        <span class="ip-state_title"><%:Baidu Search%></span>
                                        <div class="myip-status-result">
                                            <span id="http-baidu"></span>
                                            <span id="ldtime-baidu"></span>
                                        </div>
                                    </div>

                                    <div class="myip-check-item">
                                        <span class="ip-state_title"><%:NetEase Music%></span>
                                        <div class="myip-status-result">
                                            <span id="http-163"></span>
                                            <span id="ldtime-163"></span>
                                        </div>
                                    </div>

                                    <div class="myip-check-item">
                                        <span class="ip-state_title">GitHub</span>
                                        <div class="myip-status-result">
                                            <span id="http-github"></span>
                                            <span id="ldtime-github"></span>
                                        </div>
                                    </div>

                                    <div class="myip-check-item">
                                        <span class="ip-state_title">YouTube</span>
                                        <div class="myip-status-result">
                                            <span id="http-youtube"></span>
                                            <span id="ldtime-youtube"></span>
                                        </div>
                                    </div>
                                </div>
                            </div>

                            <div class="myip-footer">
                                <p>Powered by <a onclick="return ip_skk()" href="javascript:void(0);">ip.skk.moe</a></p>
                            </div>
                        </div>
                    </div>
                </div>
            </td>
        </tr>
    </table>
</fieldset>

<script>
    function addTitleOnOverflow() {
        document.querySelectorAll('.ip-result, .ip-geo').forEach(function (span) {
            if (span.scrollWidth > span.clientWidth && localStorage.getItem('privacy_my_ip') !== 'true') {
                span.setAttribute('title', span.textContent);
            } else {
                span.removeAttribute('title');
            }
        });
    }
    function ip_skk()
    {
        url2='https://ip.skk.moe';
        window.open(url2);
    }
    const $$ = document;
    var ip_ipip_ip;
    var ip_ipsb_ip;
    var ip_upaiyun_ip;
    var ip_ipify_ip;
    var refresh_http;
    var refresh_ip;
    $$.getElementById('ip-ipip').innerHTML = '<%:Querying...%>';
    $$.getElementById('ip-ipify').innerHTML = '<%:Querying...%>';
    $$.getElementById('ip-upaiyun').innerHTML = '<%:Querying...%>';
    $$.getElementById('ip-ipsb').innerHTML = '<%:Querying...%>';
    let random = parseInt(Math.random() * 100000000);
    let IP = {
        get: (url, type) =>
            fetch(url, { method: 'GET' }).then((resp) => {
                if (type === 'text')
                    return Promise.all([resp.ok, resp.status, resp.text(), resp.headers]);
                else {
                    return Promise.all([resp.ok, resp.status, resp.json(), resp.headers]);
                }
            }).then(([ok, status, data, headers]) => {
                if (ok) {
                    let json = {
                        ok,
                        status,
                        data,
                        headers
                    }
                    return json;
                } else {
                    throw new Error(JSON.stringify(json.error));
                }
            }).catch(error => {
                throw error;
            }),
        parseIPIpip: (ip, elID) => {
            const v4 = '(?:25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]\\d|\\d)(?:\\.(?:25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]\\d|\\d)){3}';
            const v4Exact = new RegExp(`^${v4}$`);
            const anonymizedIp = (() => {
                if (v4Exact.test(ip)) {
                    const [a, b, c] = ip.split('.');
                    return `${a}.${b}.${c}.0`;
                }
                return ip;
            })();

            fetch(`https://api.ip.sb/geoip/${anonymizedIp}`, {
            referrerPolicy: 'no-referrer-when-downgrade',
            }).then(r => r.json())
            .then(resp => {
                if ( resp.country && resp.country != '' && resp.isp && resp.isp != '' ) {
                    $$.getElementById(elID).innerHTML = resp.country + ' ' + resp.isp;
                }
                else {
                    fetch(`https://qqwry.api.skk.moe/${anonymizedIp}`, {
                    referrerPolicy: 'no-referrer-when-downgrade',
                    }).then(r => r.json())
                    .then(resp => {
                        if ( resp.geo.indexOf('skk.moe') == -1 ) {
                            $$.getElementById(elID).innerHTML = resp.geo;
                        }
                        else {
                            $$.getElementById(elID).innerHTML = 'Unknown';
                        }
                    })
                }
            })
        },
        getPcolIP: () => {
            fetch(`https://whois.pconline.com.cn/ipJson.jsp?z=${random}`)
                .then(response => response.json())
                .then(data => {
                    let pcisp = data.addr.split(' ');
                    if (localStorage.getItem('privacy_my_ip') != 'true') {
                        $$.getElementById('ip-pcol').innerHTML = data.ip;
                    };
                    $$.getElementById('ip-pcol-geo').innerHTML = `${data.pro} ${data.city} ${data.region} ${pcisp[1]}`;
                    addTitleOnOverflow();
                })
        },
        getUpaiIP: () => {
            IP.get(`https://pubstatic.b0.upaiyun.com/?_upnode&z=${random}`, 'json')
                .then(resp => {
                    if (localStorage.getItem('privacy_my_ip') != 'true') {
                        $$.getElementById('ip-upaiyun').innerHTML = resp.data.remote_addr;
                    };
                    $$.getElementById('ip-upaiyun-geo').innerHTML = resp.data.remote_addr_location.country + ' '  + resp.data.remote_addr_location.province + ' '  + resp.data.remote_addr_location.city + ' '  + resp.data.remote_addr_location.isp;
                    addTitleOnOverflow();
                })
        },
        getIpipIP: () => {
            IP.get(`http://myip.ipip.net?z=${random}`, 'text')
            .then(resp => {
                const ipMatch = resp.data.match(/当前 IP：([0-9A-Fa-f:.]+)/);
                const geoMatch = resp.data.match(/来自于：(.+)/);

                if (ipMatch && geoMatch) {
                    if (localStorage.getItem('privacy_my_ip') != 'true') {
                        $$.getElementById('ip-ipip').innerHTML = ipMatch[1];
                    }
                    $$.getElementById('ip-ipip-geo').innerHTML = geoMatch[1].trim();
                    addTitleOnOverflow();
                }
            })
        },
        getIpifyIP: () => {
            IP.get(`https://api.ipify.org/?format=json&z=${random}`, 'json')
            .then(resp => {
                if (localStorage.getItem('privacy_my_ip') != 'true') {
                    $$.getElementById('ip-ipify').innerHTML = resp.data.ip;
                };
                return resp.data.ip;
            })
            .then(ip => {
                IP.parseIPIpip(ip, 'ip-ipify-geo');
                addTitleOnOverflow();
            })
        },
        getIpsbIP: () => {
            fetch(`https://api.ip.sb/geoip?z=${random}`)
                .then(response => response.json())
                .then(data => {
                    if (localStorage.getItem('privacy_my_ip') != 'true') {
                        $$.getElementById('ip-ipsb').innerHTML = data.ip;
                    };
                    $$.getElementById('ip-ipsb-geo').innerHTML = `${data.country} ${data.isp}`;
                    addTitleOnOverflow();
                })
        }
    };

    $$.getElementById('http-baidu').innerHTML = '<span><%:Testing...%></span>';
    $$.getElementById('http-163').innerHTML =  '<span><%:Testing...%></span>';
    $$.getElementById('http-github').innerHTML = '<span><%:Testing...%></span>';
    $$.getElementById('http-youtube').innerHTML = '<span><%:Testing...%></span>';
    let HTTP = {
        checker: (domain, cbElID, cbLoID) => {
            if (use_router_mode) {
                HTTP.checker_router(domain, cbElID, cbLoID);
            } else {
                HTTP.checker_browser(domain, cbElID, cbLoID);
            }
        },
        checker_browser: (domain, cbElID, cbLoID) => {
            let img = new Image;
            let img_start_time = (+new Date());
            let timeout = setTimeout(() => {
                img.onerror = img.onload = null;
                $$.getElementById(cbLoID).style.display = 'none';
                $$.getElementById(cbElID).innerHTML = '<span class="sk-text-error"><%:Access Timed Out%></span>'
            }, 5000);

            img.onerror = () => {
                clearTimeout(timeout);
                $$.getElementById(cbLoID).style.display = 'none';
                $$.getElementById(cbElID).innerHTML = '<span class="sk-text-error"><%:Access Denied%></span>'
            }

            img.onload = () => {
                clearTimeout(timeout);
                let img_load_time = (new Date())- img_start_time;
                if ($$.getElementById(cbLoID).style.display == 'none') {
                    $$.getElementById(cbLoID).style.display = '';
                }
                if (img_load_time <= 500) {
                    $$.getElementById(cbLoID).innerHTML = '<span class="sk-load-success">' + img_load_time + ' ms</span>'
                    $$.getElementById(cbLoID).style.color = '#32b643';
                }
                else if (img_load_time > 500 && img_load_time <= 1000) {
                    $$.getElementById(cbLoID).innerHTML = '<span class="sk-load-success">' + img_load_time + ' ms</span>'
                    $$.getElementById(cbLoID).style.color = 'var(--warning-color)';
                }
                else {
                    $$.getElementById(cbLoID).innerHTML = '<span class="sk-load-success">' + img_load_time + ' ms</span>'
                    $$.getElementById(cbLoID).style.color = '#e85600';
                }
                $$.getElementById(cbElID).innerHTML = '<span class="sk-text-success"><%:Access Normal%></span>'
            }

            img.src = `https://${domain}/favicon.ico?${+(new Date)}`
        },
        checker_router: (domain, cbElID, cbLoID) => {
            let start_time = (+new Date());

            var xhr = new XMLHttpRequest();
            xhr.open('GET', '/cgi-bin/luci/admin/services/openclash/website_check?domain=' + encodeURIComponent(domain), true);
            xhr.timeout = 10000;

            xhr.onreadystatechange = function() {
                if (xhr.readyState === 4) {
                    let response_time = (new Date()) - start_time;

                    if (xhr.status === 200) {
                        try {
                            var response = JSON.parse(xhr.responseText);
                            if (response.success) {
                                if ($$.getElementById(cbLoID).style.display == 'none') {
                                    $$.getElementById(cbLoID).style.display = '';
                                }

                                let load_time = response.response_time || response_time;
                                if (load_time <= 500) {
                                    $$.getElementById(cbLoID).innerHTML = '<span class="sk-load-success">' + load_time + ' ms</span>'
                                    $$.getElementById(cbLoID).style.color = '#32b643';
                                }
                                else if (load_time > 500 && load_time <= 1000) {
                                    $$.getElementById(cbLoID).innerHTML = '<span class="sk-load-success">' + load_time + ' ms</span>'
                                    $$.getElementById(cbLoID).style.color = 'var(--warning-color)';
                                }
                                else {
                                    $$.getElementById(cbLoID).innerHTML = '<span class="sk-load-success">' + load_time + ' ms</span>'
                                    $$.getElementById(cbLoID).style.color = '#e85600';
                                }
                                $$.getElementById(cbElID).innerHTML = '<span class="sk-text-success"><%:Access Normal%></span>'
                            } else {
                                $$.getElementById(cbLoID).style.display = 'none';
                                $$.getElementById(cbElID).innerHTML = '<span class="sk-text-error"><%:Access Denied%></span>'
                            }
                        } catch (e) {
                            $$.getElementById(cbLoID).style.display = 'none';
                            $$.getElementById(cbElID).innerHTML = '<span class="sk-text-error"><%:Access Denied%></span>'
                        }
                    } else {
                        $$.getElementById(cbLoID).style.display = 'none';
                        $$.getElementById(cbElID).innerHTML = '<span class="sk-text-error"><%:Access Denied%></span>'
                    }
                }
            };

            xhr.ontimeout = function() {
                $$.getElementById(cbLoID).style.display = 'none';
                $$.getElementById(cbElID).innerHTML = '<span class="sk-text-error"><%:Access Timed Out%></span>'
            };

            xhr.onerror = function() {
                $$.getElementById(cbLoID).style.display = 'none';
                $$.getElementById(cbElID).innerHTML = '<span class="sk-text-error"><%:Access Denied%></span>'
            };

            xhr.send();
        },
        runcheck: () => {
            HTTP.checker('www.baidu.com', 'http-baidu', 'ldtime-baidu');
            HTTP.checker('s1.music.126.net/style', 'http-163', 'ldtime-163');
            HTTP.checker('github.com', 'http-github', 'ldtime-github');
            HTTP.checker('www.youtube.com', 'http-youtube', 'ldtime-youtube');
        }
    };

    function myip_Load()
    {
        //IP.getPcolIP();
        IP.getUpaiIP();
        IP.getIpipIP();
        IP.getIpifyIP();
        IP.getIpsbIP();
    };

    function show_my_ip() {
        if (localStorage.getItem('privacy_my_ip') == 'true') {
            update_eye_icon(false);
            ip_ipip_ip = $$.getElementById('ip-ipip').innerHTML;
            ip_ipsb_ip = $$.getElementById('ip-ipsb').innerHTML;
            ip_upaiyun_ip = $$.getElementById('ip-upaiyun').innerHTML;
            ip_ipify_ip = $$.getElementById('ip-ipify').innerHTML;
            $$.getElementById('ip-ipip').innerHTML = '***.***.***.***';
            $$.getElementById('ip-ipsb').innerHTML = '***.***.***.***';
            $$.getElementById('ip-upaiyun').innerHTML = '***.***.***.***';
            $$.getElementById('ip-ipify').innerHTML = '***.***.***.***';
            addTitleOnOverflow();
        }
        else {
            if (!refresh_http) {
                refresh_http = setInterval("HTTP.runcheck()", Math.floor(Math.random()*(20-5+1)+5)*1000);
            }
            if (!refresh_ip) {
                if (use_router_mode) {
                    refresh_ip = setInterval("get_router_ip_info()", Math.floor(Math.random()*(40-15+1)+15)*1000);
                } else {
                    refresh_ip = setInterval("myip_Load()", Math.floor(Math.random()*(40-15+1)+15)*1000);
                }
            }
        };
    };

    function update_eye_icon(isOpen) {
        var eyeIcon = document.getElementById('eye-icon');
        var eyeOpen = document.getElementById('eye-open');
        var eyeOpenCircle = document.getElementById('eye-open-circle');
        var eyeClosed = document.getElementById('eye-closed');
        var titleElement = eyeIcon.querySelector('title');

        if (isOpen) {
            eyeOpen.style.display = '';
            eyeOpenCircle.style.display = '';
            eyeClosed.style.display = 'none';
            if (titleElement) titleElement.textContent = '<%:Hide IP%>';
        } else {
            eyeOpen.style.display = 'none';
            eyeOpenCircle.style.display = 'none';
            eyeClosed.style.display = '';
            if (titleElement) titleElement.textContent = '<%:Show IP%>';
        }
    };

    function privacy_my_ip(svgElement) {
        var isCurrentlyOpen = document.getElementById('eye-open').style.display !== 'none';

        if (isCurrentlyOpen) {
            clearInterval(refresh_ip);
            refresh_ip = null;
            localStorage.setItem('privacy_my_ip', 'true');
            update_eye_icon(false);

            ip_ipip_ip = $$.getElementById('ip-ipip').innerHTML;
            ip_ipsb_ip = $$.getElementById('ip-ipsb').innerHTML;
            ip_upaiyun_ip = $$.getElementById('ip-upaiyun').innerHTML;
            ip_ipify_ip = $$.getElementById('ip-ipify').innerHTML;
            $$.getElementById('ip-ipip').innerHTML = '***.***.***.***';
            $$.getElementById('ip-ipsb').innerHTML = '***.***.***.***';
            $$.getElementById('ip-upaiyun').innerHTML = '***.***.***.***';
            $$.getElementById('ip-ipify').innerHTML = '***.***.***.***';
            addTitleOnOverflow();
        } else {
            update_eye_icon(true);
            localStorage.removeItem('privacy_my_ip');

            if (ip_ipip_ip && ip_ipsb_ip && ip_upaiyun_ip && ip_ipify_ip) {
                $$.getElementById('ip-ipip').innerHTML = ip_ipip_ip;
                $$.getElementById('ip-ipsb').innerHTML = ip_ipsb_ip;
                $$.getElementById('ip-upaiyun').innerHTML = ip_upaiyun_ip;
                $$.getElementById('ip-ipify').innerHTML = ip_ipify_ip;
            } else {
                if (use_router_mode) {
                    get_router_ip_info();
                } else {
                    myip_Load();
                }
            }

            if (refresh_ip) {
                clearInterval(refresh_ip);
                refresh_ip = null;
            }
            if (use_router_mode) {
                refresh_ip = setInterval(get_router_ip_info, Math.floor(Math.random() * (40 - 15 + 1) + 15) * 1000);
            } else {
                refresh_ip = setInterval(myip_Load, Math.floor(Math.random() * (40 - 15 + 1) + 15) * 1000);
            }
            addTitleOnOverflow();
        };
    };

    var use_router_mode = true;

    function toggle_mode_by_icon(svgElement) {
        var rect = svgElement.querySelector('rect[fill="#2F88FF"]');
        if (rect && rect.getAttribute('fill') === '#2F88FF') {
            use_router_mode = false;
            localStorage.setItem('myip_check_mode', 'false');
            update_mode_icon();
            clearAllIntervals();
            init_browser_mode();
        } else {
            use_router_mode = true;
            localStorage.setItem('myip_check_mode', 'true');
            update_mode_icon();
            clearAllIntervals();
            init_router_mode();
        }
    }

    function update_mode_icon() {
        var modeIcon = document.getElementById('mode-icon');
        var rect = modeIcon.querySelector('rect[x="4"]');
        var paths = modeIcon.querySelectorAll('path');
        var smallRect = modeIcon.querySelector('rect[x="30"]');
        var titleElement = modeIcon.querySelector('title');

        if (use_router_mode) {
            rect.setAttribute('fill', '#2F88FF');
            rect.setAttribute('stroke', '#333');
            paths[0].setAttribute('stroke', '#FFF');
            paths[1].setAttribute('stroke', '#333');
            paths[2].setAttribute('stroke', '#333');
            smallRect.setAttribute('fill', '#FFF');
            if (titleElement) titleElement.textContent = '<%:Router Mode%>';
        } else {
            rect.setAttribute('fill', '#666');
            rect.setAttribute('stroke', '#999');
            paths[0].setAttribute('stroke', '#CCC');
            paths[1].setAttribute('stroke', '#999');
            paths[2].setAttribute('stroke', '#999');
            smallRect.setAttribute('fill', '#CCC');
            if (titleElement) titleElement.textContent = '<%:Browser Mode%>';
        }
    }

    function init_router_mode() {
        if (refresh_ip) {
            clearInterval(refresh_ip);
            refresh_ip = null;
        }

        if (localStorage.getItem('privacy_my_ip') === 'true') {
            $$.getElementById('ip-ipip').innerHTML = '***.***.***.***';
            $$.getElementById('ip-ipsb').innerHTML = '***.***.***.***';
            $$.getElementById('ip-upaiyun').innerHTML = '***.***.***.***';
            $$.getElementById('ip-ipify').innerHTML = '***.***.***.***';
        }

        get_router_ip_info();
        HTTP.runcheck();

        refresh_http = setInterval("HTTP.runcheck()", Math.floor(Math.random()*(20-5+1)+5)*1000);
        if (localStorage.getItem('privacy_my_ip') !== 'true') {
            refresh_ip = setInterval("get_router_ip_info()", Math.floor(Math.random()*(40-15+1)+15)*1000);
        }
    }

    function init_browser_mode() {
        if (localStorage.getItem('privacy_my_ip') === 'true') {
            $$.getElementById('ip-ipip').innerHTML = '***.***.***.***';
            $$.getElementById('ip-ipsb').innerHTML = '***.***.***.***';
            $$.getElementById('ip-upaiyun').innerHTML = '***.***.***.***';
            $$.getElementById('ip-ipify').innerHTML = '***.***.***.***';
            $$.getElementById('ip-ipip-geo').innerHTML = '';
            $$.getElementById('ip-ipsb-geo').innerHTML = '';
            $$.getElementById('ip-upaiyun-geo').innerHTML = '';
            $$.getElementById('ip-ipify-geo').innerHTML = '';
        } else {
            reset_display();
        }

        myip_Load();
        HTTP.runcheck();

        refresh_http = setInterval("HTTP.runcheck()", Math.floor(Math.random()*(20-5+1)+5)*1000);
        if (localStorage.getItem('privacy_my_ip') !== 'true') {
            refresh_ip = setInterval("myip_Load()", Math.floor(Math.random()*(40-15+1)+15)*1000);
        }
    }

    function get_router_ip_info() {
        var xhr = new XMLHttpRequest();
        xhr.open('GET', '/cgi-bin/luci/admin/services/openclash/myip_check', true);
        xhr.timeout = 15000;

        xhr.onreadystatechange = function() {
            if (xhr.readyState === 4) {
                if (xhr.status === 200) {
                    try {
                        var response = JSON.parse(xhr.responseText);
                        if (response && (response.upaiyun || response.pcol || response.ipsb || response.ipify)) {
                            update_ip_display(response);
                        } else {
                            if (!has_ip_cache()) show_querying_state();
                        }
                    } catch (e) {
                        if (!has_ip_cache()) show_querying_state();
                    }
                } else {
                    if (!has_ip_cache()) show_querying_state();
                }
            }
        };

        xhr.ontimeout = function() {
            if (!has_ip_cache()) show_querying_state();
        };

        xhr.onerror = function() {
            if (!has_ip_cache()) show_querying_state();
        };

        xhr.send();
    }

    function has_ip_cache() {
        const ip_ids = ['ip-ipip', 'ip-ipsb', 'ip-upaiyun', 'ip-ipify'];
        for (let id of ip_ids) {
            let val = document.getElementById(id).innerHTML;
            if (
                val &&
                val !== '<%:Querying...%>' &&
                val !== '***.***.***.***'
            ) {
                return true;
            }
        }
        return false;
    }

    function show_querying_state() {
        if (localStorage.getItem('privacy_my_ip') === 'true') {
            $$.getElementById('ip-ipip').innerHTML = '***.***.***.***';
            $$.getElementById('ip-ipsb').innerHTML = '***.***.***.***';
            $$.getElementById('ip-upaiyun').innerHTML = '***.***.***.***';
            $$.getElementById('ip-ipify').innerHTML = '***.***.***.***';
        } else {
            $$.getElementById('ip-ipip').innerHTML = '<%:Querying...%>';
            $$.getElementById('ip-ipsb').innerHTML = '<%:Querying...%>';
            $$.getElementById('ip-upaiyun').innerHTML = '<%:Querying...%>';
            $$.getElementById('ip-ipify').innerHTML = '<%:Querying...%>';
        }
        $$.getElementById('ip-ipip-geo').innerHTML = '';
        $$.getElementById('ip-ipsb-geo').innerHTML = '';
        $$.getElementById('ip-upaiyun-geo').innerHTML = '';
        $$.getElementById('ip-ipify-geo').innerHTML = '';
    }

    function update_ip_display(data) {
        const ipFields = [
            { id: 'ip-upaiyun', geo: 'ip-upaiyun-geo', key: 'upaiyun' },
            { id: 'ip-ipip', geo: 'ip-ipip-geo', key: 'ipip' },
            { id: 'ip-ipsb', geo: 'ip-ipsb-geo', key: 'ipsb' },
            { id: 'ip-ipify', geo: 'ip-ipify-geo', key: 'ipify' }
        ];

        if (localStorage.getItem('privacy_my_ip') === 'true') {
            ipFields.forEach(f => {
                $$.getElementById(f.id).innerHTML = '***.***.***.***';
            });
        } else {
            ipFields.forEach(f => {
                let ipVal = '';
                if (data[f.key] && data[f.key].ip) {
                    ipVal = data[f.key].ip;
                } else {
                    let curVal = $$.getElementById(f.id).innerHTML;
                    if (curVal && curVal !== '<%:Querying...%>') {
                        ipVal = curVal;
                    } else {
                        ipVal = '<%:Querying...%>';
                    }
                }
                $$.getElementById(f.id).innerHTML = ipVal;

                let geoVal = '';
                if (data[f.key] && data[f.key].geo) {
                    geoVal = data[f.key].geo;
                } else {
                    let curGeo = $$.getElementById(f.geo).innerHTML;
                    if (curGeo && curGeo !== '' && ipVal == curVal && curVal !== '<%:Querying...%>') {
                        geoVal = curGeo;
                    } else {
                        geoVal = '';
                    }
                }
                $$.getElementById(f.geo).innerHTML = geoVal;
            });
        }
        addTitleOnOverflow();
    }

    function reset_display() {
        $$.getElementById('ip-ipip').innerHTML = '<%:Querying...%>';
        $$.getElementById('ip-ipify').innerHTML = '<%:Querying...%>';
        $$.getElementById('ip-upaiyun').innerHTML = '<%:Querying...%>';
        $$.getElementById('ip-ipsb').innerHTML = '<%:Querying...%>';

        $$.getElementById('ip-ipip-geo').innerHTML = '';
        $$.getElementById('ip-ipify-geo').innerHTML = '';
        $$.getElementById('ip-upaiyun-geo').innerHTML = '';
        $$.getElementById('ip-ipsb-geo').innerHTML = '';
    }

    function clearAllIntervals() {
        if (refresh_http) {
            clearInterval(refresh_http);
            refresh_http = null;
        }
        if (refresh_ip) {
            clearInterval(refresh_ip);
            refresh_ip = null;
        }
    }

    function refresh_myip(svgElement) {
        svgElement.style.transform = 'rotate(360deg)';
        setTimeout(function() {
            svgElement.style.transform = '';
        }, 500);

        clearAllIntervals();

        if (use_router_mode) {
            get_router_ip_info();
            HTTP.runcheck();
            refresh_http = setInterval("HTTP.runcheck()", Math.floor(Math.random()*(20-5+1)+5)*1000);
            if (localStorage.getItem('privacy_my_ip') !== 'true') {
                refresh_ip = setInterval("get_router_ip_info()", Math.floor(Math.random()*(40-15+1)+15)*1000);
            }
        } else {
            if (localStorage.getItem('privacy_my_ip') === 'true') {
                $$.getElementById('ip-ipip-geo').innerHTML = '';
                $$.getElementById('ip-ipsb-geo').innerHTML = '';
                $$.getElementById('ip-upaiyun-geo').innerHTML = '';
                $$.getElementById('ip-ipify-geo').innerHTML = '';
                $$.getElementById('ip-ipip').innerHTML = '***.***.***.***';
                $$.getElementById('ip-ipsb').innerHTML = '***.***.***.***';
                $$.getElementById('ip-upaiyun').innerHTML = '***.***.***.***';
                $$.getElementById('ip-ipify').innerHTML = '***.***.***.***';
            }

            myip_Load();
            HTTP.runcheck();

            refresh_http = setInterval("HTTP.runcheck()", Math.floor(Math.random()*(20-5+1)+5)*1000);
            if (localStorage.getItem('privacy_my_ip') !== 'true') {
                refresh_ip = setInterval("myip_Load()", Math.floor(Math.random()*(40-15+1)+15)*1000);
            }
        }

        return false;
    }

    function init_page() {
        var saved_mode = localStorage.getItem('myip_check_mode');
        if (saved_mode === 'true' || saved_mode === null) {
            use_router_mode = true;
            update_mode_icon();
            init_router_mode();
        } else {
            use_router_mode = false;
            update_mode_icon();
            init_browser_mode();
        }

        if (localStorage.getItem('privacy_my_ip') === 'true') {
            update_eye_icon(false);
        } else {
            update_eye_icon(true);
        }
    }

    window.addEventListener('load', function() {
        init_page();
    });

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