미디어위키:Common.js: 두 판 사이의 차이

편집 요약 없음
편집 요약 없음
 
(같은 사용자의 중간 판 472개는 보이지 않습니다)
1번째 줄: 1번째 줄:
/**
mw.loader.using('mediawiki.util', function () {
* 이 스크립트는 위키백과 전체에 적용됩니다. 고칠 때는 주의해주세요.
  $(function () {
* [[위키백과:위키프로젝트 시스템]] 참고
    // Check if the #timetable-indicator span exists
*
    if (document.getElementById('timetable-indicator')) {
* 스크립트를 넣을 때는 충분한 설명, 출처를 넣어주세요! 이후 관리가 어려워집니다.
 
**/
  const logo = document.querySelector('img.vh-logo');
    logo.src = 'https://w.halv.kr/images/2/27/시각표로고.svg';
      // Create a <style> element
      var style = document.createElement('style');
      style.textContent = `
img.vh-logo {
height: 2rem !important;
}


mw.loader.using( ['mediawiki.util', 'mediawiki.notify', 'jquery.client'], function () {
.mw-page-title-namespace::after {
/* Begin of mw.loader.using callback */
  background-color: #ef4137;
}


/**
:root {
* Map addPortletLink to mw.util
--vh-navbar-bg: #ef4137 !important;
*
* @deprecated: Use mw.util.addPortletLink instead.
*/
mw.log.deprecate( window, 'addPortletLink', mw.util.addPortletLink,
'Use mw.util.addPortletLink instead' );
/**
* Extract a URL parameter from the current URL
*
* @deprecated: Use mw.util.getParamValue with proper escaping
*/
mw.log.deprecate( window, 'getURLParamValue', mw.util.getParamValue, 'Use mw.util.getParamValue instead' );
/**
* Test if an element has a certain class
*
* @deprecated: Use $(element).hasClass() instead.
*/
mw.log.deprecate( window, 'hasClass', function ( element, className ) {
    return $( element ).hasClass( className );
}, 'Use jQuery.hasClass() instead' );
/**
* @source www.mediawiki.org/wiki/Snippets/Load_JS_and_CSS_by_URL
* @rev 5
*/
// CSS
var extraCSS = mw.util.getParamValue( 'withCSS' );
if ( extraCSS ) {
if ( extraCSS.match( /^MediaWiki:[^&<>=%#]*\.css$/ ) ) {
importStylesheet( extraCSS );
} else {
mw.notify( 'Only pages from the MediaWiki namespace are allowed.', { title: 'Invalid withCSS value' } );
}
}
}
// JS
var extraJS = mw.util.getParamValue( 'withJS' );
if ( extraJS ) {
if ( extraJS.match( /^MediaWiki:[^&<>=%#]*\.js$/ ) ) {
importScript( extraJS );
} else {
mw.notify( 'Only pages from the MediaWiki namespace are allowed.', { title: 'Invalid withJS value' } );
}
}


/**
  `;
* Import more specific scripts if necessary
      document.head.appendChild(style);
*/
     }
 
  });
if ( mw.config.get( 'wgNamespaceNumber' ) === 6 ) {
});
     /* file description page scripts */
    importScript( 'MediaWiki:Common.js/file.js' );
}


/* ([[위키백과:관리자 요청/2007년 5월#스크립트 추가 요청]]) */
/** Collapsible tables *********************************************************
*
*  Description: Allows tables to be collapsed, showing only the header. See
*              [[:en:Wikipedia:NavFrame]].
*  Maintainers: [[:en:User:R. Koot]]
*/
var autoCollapse = 2;
var collapseCaption = '숨기기';
var expandCaption = '보이기';


window.collapseTable = function ( tableIndex ) {
(function () {
     var Button = document.getElementById( 'collapseButton' + tableIndex );
  function initStickyBorders(wrap) {
     var Table = document.getElementById( 'collapsibleTable' + tableIndex );
     const sticky = wrap.querySelector('#stickyparent');
     if (!sticky) return;


     if ( !Table || !Button ) {
     function updateStickyWidth() {
        return false;
      const w = sticky.getBoundingClientRect().width;
      wrap.style.setProperty('--sticky-w', w + 'px');
     }
     }


     var Rows = Table.rows;
     function updateScrollState() {
    var i;
      const atLeft = wrap.scrollLeft < 5;
 
      wrap.classList.toggle('at-left', atLeft);
    if ( Button.firstChild.data === collapseCaption ) {
      wrap.classList.toggle('scrolled', !atLeft); // ← 추가: 왼쪽이 아니면 '띄우기' 상태
        for ( i = 1; i < Rows.length; i++ ) {
            Rows[i].style.display = 'none';
        }
        Button.firstChild.data = expandCaption;
    } else {
        for ( i = 1; i < Rows.length; i++ ) {
            Rows[i].style.display = Rows[0].style.display;
        }
        Button.firstChild.data = collapseCaption;
     }
     }
};


function createCollapseButtons() {
    updateStickyWidth();
    var tableIndex = 0;
     updateScrollState();
     var NavigationBoxes = {};
    var Tables = document.getElementsByTagName( 'table' );
    var i;


     function handleButtonLink( index, e ) {
     wrap.addEventListener('scroll', updateScrollState, { passive: true });
        window.collapseTable( index );
    window.addEventListener('resize', updateStickyWidth);
        e.preventDefault();
    if (document.fonts && document.fonts.ready) {
      document.fonts.ready.then(updateStickyWidth).catch(function(){});
     }
     }
  }


    for ( i = 0; i < Tables.length; i++ ) {
  document.querySelectorAll('.table-wrap').forEach(initStickyBorders);
        if ( $( Tables[i] ).hasClass( 'collapsible' ) ) {
})();
 
            /* only add button and increment count if there is a header row to work with */
            var HeaderRow = Tables[i].getElementsByTagName( 'tr' )[0];
            if ( !HeaderRow ) continue;
            var Header = HeaderRow.getElementsByTagName( 'th' )[0];
            if ( !Header ) continue;


            NavigationBoxes[ tableIndex ] = Tables[i];
            Tables[i].setAttribute( 'id', 'collapsibleTable' + tableIndex );


            var Button    = document.createElement( 'span' );
            var ButtonLink = document.createElement( 'a' );
            var ButtonText = document.createTextNode( collapseCaption );


            Button.className = 'collapseButton'; /* Styles are declared in Common.css */
(function () {
  function unwrapLibertyTable(wrapper) {
    if (!wrapper || !wrapper.querySelector('.timetable')) return;
    const table = wrapper.querySelector('.timetable');
    wrapper.parentNode.insertBefore(table, wrapper);
    wrapper.remove();
  }


            ButtonLink.style.color = Header.style.color;
  // Remove any that already exist
            ButtonLink.setAttribute( 'id', 'collapseButton' + tableIndex );
  document.querySelectorAll('.liberty-table-wrapper').forEach(unwrapLibertyTable);
            ButtonLink.setAttribute( 'href', '#' );
            $( ButtonLink ).on( 'click', $.proxy( handleButtonLink, ButtonLink, tableIndex ) );
            ButtonLink.appendChild( ButtonText );


            Button.appendChild( document.createTextNode( '[' ) );
  // Watch for new ones being added to the DOM
            Button.appendChild( ButtonLink );
  const observer = new MutationObserver(mutations => {
            Button.appendChild( document.createTextNode( ']' ) );
    mutations.forEach(mutation => {
 
      mutation.addedNodes.forEach(node => {
            Header.insertBefore( Button, Header.firstChild );
        if (!(node instanceof HTMLElement)) return;
            tableIndex++;
        if (node.matches('.liberty-table-wrapper') && node.querySelector('.timetable')) {
          unwrapLibertyTable(node);
        } else if (node.querySelector) {
          // If it's a container, check inside it
          node.querySelectorAll('.liberty-table-wrapper').forEach(unwrapLibertyTable);
         }
         }
     }
      });
     });
  });


    for ( i = 0;  i < tableIndex; i++ ) {
  observer.observe(document.body, {
        if ( $( NavigationBoxes[i] ).hasClass( 'collapsed' ) || ( tableIndex >= autoCollapse && $( NavigationBoxes[i] ).hasClass( 'autocollapse' ) ) ) {
    childList: true,
            window.collapseTable( i );
    subtree: true
        }  
  });
        else if ( $( NavigationBoxes[i] ).hasClass ( 'innercollapse' ) ) {
})();
            var element = NavigationBoxes[i];
            while ((element = element.parentNode)) {
                if ( $( element ).hasClass( 'outercollapse' ) ) {
                    window.collapseTable ( i );
                    break;
                }
            }
        }
    }
}


mw.hook( 'wikipage.content' ).add( createCollapseButtons );


/* ([[위키백과:관리자 요청/2007년 5월#스크립트 추가 요청]]) */
    const gemstoneColors = {
/** Dynamic Navigation Bars (experimental) *************************************
  "흙": "#4b4b4b",        // Coal - Dark gray
*
  "구리": "#c68346",      // Copper - Reddish-brown
*  Description: See [[:en:Wikipedia:NavFrame]].
  "청동": "#547865",      // Bronze - Warm brown
*  Maintainers: UNMAINTAINED
  "은": "#c0c0c0",        // Silver - Metallic silver
*/
  "금": "#efbf04",        // Gold - Golden yellow
  "자수정": "#9966cc",    // Amethyst - Purple
// set up the words in your language
  "터키석": "#069e80",    // Turquoise - Light blue
/* set up the words in your language */
  "가넷": "#9b111e",      // Garnet - Deep red
var NavigationBarHide = '[' + collapseCaption + ']';
  "토파즈": "#f0a641",    // Topaz - Golden orange
var NavigationBarShow = '[' + expandCaption + ']';
  "페리도트": "#81b11f",  // Peridot - Light green
  "에메랄드 I": "#39b647", // Emerald - Bright green
  "에메랄드 II": "#39b647",// Emerald - Bright green (variant)
  "에메랄드 III": "#39b647",// Emerald - Bright green (variant)
  "사파이어 I": "#0f52ba", // Sapphire - Rich blue
  "사파이어 II": "#0f52ba",// Sapphire - Rich blue (variant)
  "사파이어 III": "#0f52ba",// Sapphire - Rich blue (variant)
  "루비 I": "#e0115f",    // Ruby - Vivid red
  "루비 II": "#e0115f",    // Ruby - Vivid red (variant)
  "루비 III": "#e0115f",  // Ruby - Vivid red (variant)
  "다이아몬드 I": "#b9fcff", // Diamond - Pale blue/white
  "다이아몬드 II": "#b9fcff",// Diamond - Pale blue/white (variant)
  "다이아몬드 III": "#b9fcff"
    };


/**
* Shows and hides content and picture (if available) of navigation bars
* Parameters:
*    indexNavigationBar: the index of navigation bar to be toggled
**/
window.toggleNavigationBar = function ( indexNavigationBar, event ) {
    var NavToggle = document.getElementById( 'NavToggle' + indexNavigationBar );
    var NavFrame = document.getElementById( 'NavFrame' + indexNavigationBar );
    var NavChild;


    if ( !NavFrame || !NavToggle ) {
// Function to update background color
        return false;
function updateBackgroundColor() {
    }


    /* if shown now */
  const existing = document.querySelector('span.pjcg-hwijang');
    if ( NavToggle.firstChild.data === NavigationBarHide ) {
const appendafterthis = document.querySelector('.vh-rc');
        for ( NavChild = NavFrame.firstChild; NavChild !== null; NavChild = NavChild.nextSibling ) {
  if (existing) {
            if ( $( NavChild ).hasClass( 'NavContent' ) || $( NavChild ).hasClass( 'NavPic' ) ) {
    const newDiv = document.createElement('div');
                NavChild.style.display = 'none';
    newDiv.className = 'vh-sidebar-section';
            }
    newDiv.setAttribute(
        }
      'style',
     NavToggle.firstChild.data = NavigationBarShow;
      `
      margin-top: 1rem;
      background: url(https://w.halv.kr/images/4/4c/%EC%B2%AD%EA%B4%91%ED%9C%98%EC%9E%A5.png) center no-repeat, light-dark(#fff,#1c1d1f) !important;
      background-size: contain !important;
      height: 14.5rem !important;
      `
     );


     /* if hidden now */
     appendafterthis.insertAdjacentElement('afterend', newDiv);
    } else if ( NavToggle.firstChild.data === NavigationBarShow ) {
  };
        for ( NavChild = NavFrame.firstChild; NavChild !== null; NavChild = NavChild.nextSibling ) {
            if ( $( NavChild ).hasClass( 'NavContent' ) || $( NavChild ).hasClass( 'NavPic' ) ) {
                NavChild.style.display = 'block';
            }
        }
        NavToggle.firstChild.data = NavigationBarHide;
    }


     event.preventDefault();
  const targetElements = document.querySelectorAll('.vh-rc');
};
  targetElements.forEach((el) => {
     el.insertAdjacentHTML(
      'beforebegin',
      `<a href="https://buymeacoffee.com/halv/">
        <div class="vh-sidebar-section" style="
          margin-bottom: 1rem;
          padding: 0;
  height: 90px;
          background: url(https://w.halv.kr/images/b/bd/후원처란.png) center no-repeat, light-dark(#fff,#1c1d1f) !important;
          background-size: contain !important;
        "></div>
      </a>`
    );
  });


/* adds show/hide-button to navigation bars */
  const element = document.getElementById("honorific-level");
function createNavigationBarToggleButton() {
  const leveler = document.getElementById("points-level");
    var indexNavigationBar = 0;
  const childElement = leveler.firstElementChild; // Access the first child of leveler
    var NavFrame;
  const text = element.textContent.trim().replace(/[()]/g, ""); // Remove parentheses
    var NavChild;
    /* iterate over all < div >-elements */
    var divs = document.getElementsByTagName( 'div' );
    for ( var i = 0; (NavFrame = divs[i]); i++ ) {
        /* if found a navigation bar */
        if ( $( NavFrame ).hasClass( 'NavFrame' ) ) {


            indexNavigationBar++;
  // Check if the text matches specific diamond levels and update the child element color
            var NavToggle = document.createElement( 'a' );
  if (text === "다이아몬드 I" || text === "다이아몬드 II" || text === "다이아몬드 III") {
            NavToggle.className = 'NavToggle';
    leveler.style.background = gemstoneColors[text] || "transparent";
            NavToggle.setAttribute( 'id', 'NavToggle' + indexNavigationBar );
    leveler.style.borderColor = "#22636652";
            NavToggle.setAttribute( 'href', '#' );
    if (childElement) {
            $( NavToggle ).on( 'click', $.proxy( window.toggleNavigationBar, window, indexNavigationBar ) );
      childElement.style.color = "#226366cc"; // Set the child element's text color to red
 
    }
            var isCollapsed = $( NavFrame ).hasClass( 'collapsed' );
  } else if (gemstoneColors[text]) {
            /**
    leveler.style.background = gemstoneColors[text];
            * Check if any children are already hidden.  This loop is here for backwards compatibility:
    leveler.style.borderColor = gemstoneColors[text] + "52";
            * the old way of making NavFrames start out collapsed was to manually add style="display:none"
    if (childElement) {
            * to all the NavPic/NavContent elements.  Since this was bad for accessibility (no way to make
      childElement.style.color = ""; // Reset child element's text color
            * the content visible without JavaScript support), the new recommended way is to add the class
    }
            * "collapsed" to the NavFrame itself, just like with collapsible tables.
  } else {
            */
    leveler.style.background = "transparent"; // Default if no match
            for ( NavChild = NavFrame.firstChild; NavChild != null && !isCollapsed; NavChild = NavChild.nextSibling ) {
    leveler.style.borderColor = "";
                if ( $( NavChild ).hasClass( 'NavPic' ) || $( NavChild ).hasClass( 'NavContent' ) ) {
    if (childElement) {
                    if ( NavChild.style.display === 'none' ) {
      childElement.style.color = ""; // Reset child element's text color
                        isCollapsed = true;
                    }
                }
            }
            if ( isCollapsed ) {
                for ( NavChild = NavFrame.firstChild; NavChild != null; NavChild = NavChild.nextSibling ) {
                    if ( $( NavChild ).hasClass( 'NavPic' ) || $( NavChild ).hasClass( 'NavContent' ) ) {
                        NavChild.style.display = 'none';
                    }
                }
            }
            var NavToggleText = document.createTextNode( isCollapsed ? NavigationBarShow : NavigationBarHide );
            NavToggle.appendChild( NavToggleText );
 
            /* Find the NavHead and attach the toggle link (Must be this complicated because Moz's firstChild handling is borked) */
            for( var j = 0; j < NavFrame.childNodes.length; j++ ) {
                if ( $( NavFrame.childNodes[j] ).hasClass( 'NavHead' ) ) {
                    NavToggle.style.color = NavFrame.childNodes[j].style.color;
                    NavFrame.childNodes[j].appendChild( NavToggle );
                }
            }
            NavFrame.setAttribute( 'id', 'NavFrame' + indexNavigationBar );
        }
     }
     }
  }
}
}


mw.hook( 'wikipage.content' ).add( createNavigationBarToggleButton );


/***** 그림 정보 틀을 자동으로 불러옴 ********
  const head = document.head;
* Adds a link to subpages of current page
* from commons.wikimedia.org
*  Maintainers: [[User:Yonidebest]], [[User:Dschwen]]
*  [[사용자:Kwj2772]]가 수정
*  JSconfig items: bool 'loadAutoInformationTemplate'
*                      (true=enabled (default), false=disabled)
* JSConfig를 사용하지 않도록 수정함. --[[사용자:Klutzy|klutzy]] ([[사용자토론:Klutzy|토론]]) 2009년 9월 27일 (일) 20:33 (KST)
****/
if (mw.config.get('wgCanonicalSpecialPageName') == 'Upload') {
  importScript('MediaWiki:Upload.js');
}


/* 인터랙티브 지도. 영어 위키백과에서 가져옴. -- [[사용자:ChongDae]] 2010년 3월 28일 (일) 02:08 (KST) */
  const link3 = document.createElement('link');
/**
  link3.rel = 'stylesheet';
* WikiMiniAtlas
  link3.href = 'https://fonts.googleapis.com/css2?family=Noto+Sans+KR:wght@100..900&family=Noto+Serif+KR:wght@300;400;500;700;900&family=Hahmlet:wght@300;400;500;700;900&family=Zen+Kaku+Gothic+Antique:wght@300;400;500;700;900&display=swap';
*
* Description: WikiMiniAtlas is a popup click and drag world map.
*              This script causes all of our coordinate links to display the WikiMiniAtlas popup button.
*              The script itself is located on meta because it is used by many projects.
*              See [[Meta:WikiMiniAtlas]] for more information.
* Maintainers: [[User:Dschwen]]
*/
( function () {
    var require_wikiminiatlas = false;
    var coord_filter = /geohack/;
    $( function () {
        $( 'a.external.text' ).each( function( key, link ) {
            if ( link.href && coord_filter.exec( link.href ) ) {
                require_wikiminiatlas = true;
                // break from loop
                return false;
            }
        } );
        if ( $( 'div.kmldata' ).length ) {
            require_wikiminiatlas = true;
        }
        if ( require_wikiminiatlas ) {
            mw.loader.load( '//meta.wikimedia.org/w/index.php?title=MediaWiki:Wikiminiatlas.js&action=raw&ctype=text/javascript' );
        }
    } );
} )();


/**
  const link4 = document.createElement('link');
* Fix for Windows XP Unicode font rendering
  link4.rel = 'stylesheet';
*/
  link4.href = 'https://cdn.jsdelivr.net/gh/orioncactus/pretendard@v1.3.9/dist/web/static/pretendard.min.css';
if ( navigator.appVersion.search(/windows nt 5/i) !== -1 ) {
    mw.util.addCSS( '.IPA { font-family: "Lucida Sans Unicode", "Arial Unicode MS"; } ' +
                '.Unicode { font-family: "Arial Unicode MS", "Lucida Sans Unicode"; } ' );
}


/**
* 편집 안내 ****************************************************
*
* 생존 인물에 대한 편집 안내. 영어 위키백과에서 가져옴 - ChongDae
* Maintainers: [[User:RockMFR]]
*/
function addEditIntro( name ) {
    $( '.mw-editsection, #ca-edit' ).find( 'a' ).each( function ( i, el ) {
        el.href = $( this ).attr( 'href' ) + '&editintro=' + name;
    } );
}


if ( mw.config.get( 'wgNamespaceNumber' ) === 0 ) {
  head.appendChild(link3);
    $( function () {
head.appendChild(link4);
        var cats = mw.config.get('wgCategories');
        if ( !cats ) {
            return;
        }
        if ( $.inArray( '살아있는 사람', cats ) !== -1 || $.inArray( '생사 불명', cats ) !== -1 ) {
            addEditIntro( '틀:BLP_편집_안내' );
        }
    } );
}
/**
*
*
*
*/
function wikilink1() {
location.href='https://jwiki.kr/wiki/index.php/철통같은_믿음으로';
}


/* End of mw.loader.using callback */
function stretchText(el) {
} );
  // 1) target width in px from data-max-width (in rem)
  const maxWidth =
    parseFloat(getComputedStyle(document.documentElement).fontSize) *
    parseFloat(el.dataset.maxWidth);


  // 2) get the child <span> in a Safari-safe way
  const span = (el.querySelector && (el.querySelector(':scope > span') || el.querySelector('span'))) || null;
  if (!span) return;


$(document).ready(function() {
  // 3) ensure predictable measuring
    $('.toggleBtn').click(function() {
  const prev = el.style.transform;
        var targetId = $(this).data('target'); // Get the value of 'data-target'
  el.style.transform = 'translateX(-50%)'; // remove previous scale while measuring
        var growDiv = document.getElementById(targetId);
        $('#' + targetId).toggleClass('collapsed'); // Toggle the 'collapsed' class on the target element


        if (growDiv.clientHeight) {
  const measure = () => {
          // Collapse the div if it's already expanded
    // If fonts aren't ready yet, Safari may report 0
          growDiv.style.height = 0;
    const w = span.scrollWidth || span.getBoundingClientRect().width;
        } else {
     if (!w) return requestAnimationFrame(measure);
          // Measure the height of the content inside the div
          growDiv.style.height = growDiv.scrollHeight + "px";
        }
     });
});


    const scale = maxWidth / w;
    el.style.transformOrigin = 'center center';
    el.style.transform = `translateX(-50%) scaleX(${scale})`;
    el.style.position = 'absolute';
    el.style.position = 'absolute';
  };


  // Wait for fonts/layout in Safari
  if (document.fonts && document.fonts.ready) {
    document.fonts.ready.then(() => requestAnimationFrame(measure));
  } else {
    requestAnimationFrame(measure);
  }
}


// run once and on resize
const runAll = () => document.querySelectorAll('.stretch-text').forEach(stretchText);
runAll();
addEventListener('resize', runAll);


/* DO NOT ADD CODE BELOW THIS LINE */
// Call the function
updateBackgroundColor();
changeTimeColor();

2026년 1월 4일 (일) 19:25 기준 최신판

mw.loader.using('mediawiki.util', function () {
  $(function () {
    // Check if the #timetable-indicator span exists
    if (document.getElementById('timetable-indicator')) {
  
  const logo = document.querySelector('img.vh-logo');
    logo.src = 'https://w.halv.kr/images/2/27/시각표로고.svg';
      // Create a <style> element
      var style = document.createElement('style');
      style.textContent = `
img.vh-logo {
height: 2rem !important;
}

.mw-page-title-namespace::after {
  background-color: #ef4137;
}

:root {
--vh-navbar-bg: #ef4137 !important;
}

  `;
      document.head.appendChild(style);
    }
  });
});


(function () {
  function initStickyBorders(wrap) {
    const sticky = wrap.querySelector('#stickyparent');
    if (!sticky) return;

    function updateStickyWidth() {
      const w = sticky.getBoundingClientRect().width;
      wrap.style.setProperty('--sticky-w', w + 'px');
    }

    function updateScrollState() {
      const atLeft = wrap.scrollLeft < 5;
      wrap.classList.toggle('at-left', atLeft);
      wrap.classList.toggle('scrolled', !atLeft); // ← 추가: 왼쪽이 아니면 '띄우기' 상태
    }

    updateStickyWidth();
    updateScrollState();

    wrap.addEventListener('scroll', updateScrollState, { passive: true });
    window.addEventListener('resize', updateStickyWidth);
    if (document.fonts && document.fonts.ready) {
      document.fonts.ready.then(updateStickyWidth).catch(function(){});
    }
  }

  document.querySelectorAll('.table-wrap').forEach(initStickyBorders);
})();



(function () {
  function unwrapLibertyTable(wrapper) {
    if (!wrapper || !wrapper.querySelector('.timetable')) return;
    const table = wrapper.querySelector('.timetable');
    wrapper.parentNode.insertBefore(table, wrapper);
    wrapper.remove();
  }

  // Remove any that already exist
  document.querySelectorAll('.liberty-table-wrapper').forEach(unwrapLibertyTable);

  // Watch for new ones being added to the DOM
  const observer = new MutationObserver(mutations => {
    mutations.forEach(mutation => {
      mutation.addedNodes.forEach(node => {
        if (!(node instanceof HTMLElement)) return;
        if (node.matches('.liberty-table-wrapper') && node.querySelector('.timetable')) {
          unwrapLibertyTable(node);
        } else if (node.querySelector) {
          // If it's a container, check inside it
          node.querySelectorAll('.liberty-table-wrapper').forEach(unwrapLibertyTable);
        }
      });
    });
  });

  observer.observe(document.body, {
    childList: true,
    subtree: true
  });
})();


    const gemstoneColors = {
  "흙": "#4b4b4b",         // Coal - Dark gray
  "구리": "#c68346",       // Copper - Reddish-brown
  "청동": "#547865",       // Bronze - Warm brown
  "은": "#c0c0c0",         // Silver - Metallic silver
  "금": "#efbf04",         // Gold - Golden yellow
  "자수정": "#9966cc",     // Amethyst - Purple
  "터키석": "#069e80",     // Turquoise - Light blue
  "가넷": "#9b111e",       // Garnet - Deep red
  "토파즈": "#f0a641",     // Topaz - Golden orange
  "페리도트": "#81b11f",   // Peridot - Light green
  "에메랄드 I": "#39b647", // Emerald - Bright green
  "에메랄드 II": "#39b647",// Emerald - Bright green (variant)
  "에메랄드 III": "#39b647",// Emerald - Bright green (variant)
  "사파이어 I": "#0f52ba", // Sapphire - Rich blue
  "사파이어 II": "#0f52ba",// Sapphire - Rich blue (variant)
  "사파이어 III": "#0f52ba",// Sapphire - Rich blue (variant)
  "루비 I": "#e0115f",     // Ruby - Vivid red
  "루비 II": "#e0115f",    // Ruby - Vivid red (variant)
  "루비 III": "#e0115f",   // Ruby - Vivid red (variant)
  "다이아몬드 I": "#b9fcff", // Diamond - Pale blue/white
  "다이아몬드 II": "#b9fcff",// Diamond - Pale blue/white (variant)
  "다이아몬드 III": "#b9fcff"
    };


// Function to update background color
function updateBackgroundColor() {

  const existing = document.querySelector('span.pjcg-hwijang');
const appendafterthis = document.querySelector('.vh-rc');
  if (existing) {
    const newDiv = document.createElement('div');
    newDiv.className = 'vh-sidebar-section';
    newDiv.setAttribute(
      'style',
      `
      margin-top: 1rem;
      background: url(https://w.halv.kr/images/4/4c/%EC%B2%AD%EA%B4%91%ED%9C%98%EC%9E%A5.png) center no-repeat, light-dark(#fff,#1c1d1f) !important;
      background-size: contain !important;
      height: 14.5rem !important;
      `
    );

    appendafterthis.insertAdjacentElement('afterend', newDiv);
  };

  const targetElements = document.querySelectorAll('.vh-rc');
  targetElements.forEach((el) => {
    el.insertAdjacentHTML(
      'beforebegin',
      `<a href="https://buymeacoffee.com/halv/">
         <div class="vh-sidebar-section" style="
           margin-bottom: 1rem;
           padding: 0;
  height: 90px;
           background: url(https://w.halv.kr/images/b/bd/후원처란.png) center no-repeat, light-dark(#fff,#1c1d1f) !important;
           background-size: contain !important;
         "></div>
       </a>`
    );
  });

  const element = document.getElementById("honorific-level");
  const leveler = document.getElementById("points-level");
  const childElement = leveler.firstElementChild; // Access the first child of leveler
  const text = element.textContent.trim().replace(/[()]/g, ""); // Remove parentheses

  // Check if the text matches specific diamond levels and update the child element color
  if (text === "다이아몬드 I" || text === "다이아몬드 II" || text === "다이아몬드 III") {
    leveler.style.background = gemstoneColors[text] || "transparent";
    leveler.style.borderColor = "#22636652";
    if (childElement) {
      childElement.style.color = "#226366cc"; // Set the child element's text color to red
    }
  } else if (gemstoneColors[text]) {
    leveler.style.background = gemstoneColors[text];
    leveler.style.borderColor = gemstoneColors[text] + "52";
    if (childElement) {
      childElement.style.color = ""; // Reset child element's text color
    }
  } else {
    leveler.style.background = "transparent"; // Default if no match
    leveler.style.borderColor = "";
    if (childElement) {
      childElement.style.color = ""; // Reset child element's text color
    }
  }
}


  const head = document.head;

  const link3 = document.createElement('link');
  link3.rel = 'stylesheet';
  link3.href = 'https://fonts.googleapis.com/css2?family=Noto+Sans+KR:wght@100..900&family=Noto+Serif+KR:wght@300;400;500;700;900&family=Hahmlet:wght@300;400;500;700;900&family=Zen+Kaku+Gothic+Antique:wght@300;400;500;700;900&display=swap';

  const link4 = document.createElement('link');
  link4.rel = 'stylesheet';
  link4.href = 'https://cdn.jsdelivr.net/gh/orioncactus/pretendard@v1.3.9/dist/web/static/pretendard.min.css';


  head.appendChild(link3);
head.appendChild(link4);

function stretchText(el) {
  // 1) target width in px from data-max-width (in rem)
  const maxWidth =
    parseFloat(getComputedStyle(document.documentElement).fontSize) *
    parseFloat(el.dataset.maxWidth);

  // 2) get the child <span> in a Safari-safe way
  const span = (el.querySelector && (el.querySelector(':scope > span') || el.querySelector('span'))) || null;
  if (!span) return;

  // 3) ensure predictable measuring
  const prev = el.style.transform;
  el.style.transform = 'translateX(-50%)'; // remove previous scale while measuring

  const measure = () => {
    // If fonts aren't ready yet, Safari may report 0
    const w = span.scrollWidth || span.getBoundingClientRect().width;
    if (!w) return requestAnimationFrame(measure);

    const scale = maxWidth / w;
    el.style.transformOrigin = 'center center';
    el.style.transform = `translateX(-50%) scaleX(${scale})`;
    el.style.position = 'absolute';
    el.style.position = 'absolute';
  };

  // Wait for fonts/layout in Safari
  if (document.fonts && document.fonts.ready) {
    document.fonts.ready.then(() => requestAnimationFrame(measure));
  } else {
    requestAnimationFrame(measure);
  }
}

// run once and on resize
const runAll = () => document.querySelectorAll('.stretch-text').forEach(stretchText);
runAll();
addEventListener('resize', runAll);

// Call the function
updateBackgroundColor();
changeTimeColor();