MediaWiki:Common.js: mudanças entre as edições

De Farmland
Ir para navegação Ir para pesquisar
Sem resumo de edição
Sem resumo de edição
 
(5 revisões intermediárias pelo mesmo usuário não estão sendo mostradas)
Linha 1: Linha 1:
/* =======================================================
/* =======================================================
   ARVORE HABILIDADE - WIKI EVERLIGHT
   ARVORE DE HABILIDADE
   ======================================================= */
   ======================================================= */
 
document.addEventListener('DOMContentLoaded', function () {
 
     var cards = document.querySelectorAll('.skill-card');
document.addEventListener('DOMContentLoaded', () => {
     cards.forEach(function (card) {
     const cards = document.querySelectorAll('.skill-card');
         card.addEventListener('click', function () {
 
             card.style.filter = 'brightness(1.2)';
     cards.forEach(card => {
             setTimeout(function () { card.style.filter = 'brightness(1)'; }, 150);
         card.addEventListener('click', () => {
            const skillName = card.querySelector('.skill-name').innerText;
            console.log(`Habilidade clicada: ${skillName}`);
           
            // Exemplo de efeito visual simples
             card.style.filter = "brightness(1.2)";
             setTimeout(() => {
                card.style.filter = "brightness(1)";
            }, 150);
         });
         });
     });
     });
Linha 23: Linha 14:


/* =======================================================
/* =======================================================
   BOTAO SUBIR TOPO DA PAGINA
   BOTAO VOLTAR AO TOPO
   ======================================================= */
   ======================================================= */
$(function() {
$(function () {
     var $button = $('<button id="back-to-top" title="Voltar ao Topo">↑ Topo</button>');
     var $button = $('<button id="back-to-top" title="Voltar ao Topo">↑ Topo</button>');
     $('body').append($button);
     $('body').append($button);


     $(window).scroll(function() {
     $(window).scroll(function () {
        // Verifica se a posição atual + altura da janela é maior que o tamanho total - 100px
         if ($(window).scrollTop() + $(window).height() > $(document).height() - 100) {
         if ($(window).scrollTop() + $(window).height() > $(document).height() - 100) {
             $button.fadeIn();
             $button.fadeIn();
Linha 38: Linha 28:
     });
     });


     $button.click(function() {
     $button.click(function () {
         $('html, body').animate({scrollTop: 0}, 'slow');
         $('html, body').animate({ scrollTop: 0 }, 'slow');
         return false;
         return false;
     });
     });
Linha 46: Linha 36:


/* =======================================================
/* =======================================================
   clases testee
   ARVORE DE CLASSES
   ======================================================= */
   ======================================================= */
document.addEventListener('DOMContentLoaded', function() {
document.addEventListener('DOMContentLoaded', function () {
     const cells = document.querySelectorAll('.ragnarok-tree td[class^="evo-"]');
     var cells = document.querySelectorAll('.ragnarok-tree td[class^="evo-"]');


     cells.forEach(cell => {
     cells.forEach(function (cell) {
         // 1. Tornar a célula inteira clicável (redirecionar para o link de texto)
         var link = cell.querySelector('a');
        const link = cell.querySelector('a');
         if (link) {
         if (link) {
             cell.style.cursor = 'pointer';
             cell.style.cursor = 'pointer';
             cell.addEventListener('click', () => { window.location.href = link.href; });
             cell.addEventListener('click', function () { window.location.href = link.href; });
         }
         }


        // 2. Lógica de Hover (Conexão Hierárquica)
         cell.addEventListener('mouseenter', function () {
         cell.addEventListener('mouseenter', function() {
             var familyClass = Array.from(this.classList).find(function (c) { return c.startsWith('evo-'); });
             const familyClass = Array.from(this.classList).find(c => c.startsWith('evo-')); // ex: evo-sw
             if (!familyClass || familyClass === 'evo-all') return;
             if (!familyClass || familyClass === 'evo-all') return;


             const myPos = this.getAttribute('data-pos'); // Pega 0, 1 ou 2
             var myPos   = this.getAttribute('data-pos');
             const isClass1 = this.closest('table').previousElementSibling?.innerText.includes('Classe 1');
             var prevEl  = this.closest('table').previousElementSibling;
             const isClass2 = this.closest('table').previousElementSibling?.innerText.includes('Classe 2');
            var isClass1 = prevEl && prevEl.innerText.includes('Classe 1');
             var isClass2 = prevEl && prevEl.innerText.includes('Classe 2');


             if (isClass1) {
             if (isClass1) {
                // Passou no Espadachim: Acende Cav/Temp e Lorde/Paladino
                 document.querySelectorAll('.' + familyClass).forEach(function (el) {
                 document.querySelectorAll(`.${familyClass}`).forEach(el => el.classList.add('highlight-active'));
                    el.classList.add('highlight-active');
                });
             } else if (isClass2) {
             } else if (isClass2) {
                // Passou no Cavaleiro (pos 0): Acende ele mesmo e o Lorde (pos 0 na Trans)
                 this.classList.add('highlight-active');
                 this.classList.add('highlight-active'); // Acende si mesmo
                 var table3 = document.querySelector('table:nth-of-type(3)');
                 const transRelated = document.querySelector('table:nth-of-type(3)').querySelectorAll(`.${familyClass}`);
                if (table3) {
               
                    table3.querySelectorAll('.' + familyClass).forEach(function (el) {
                // Procura na Transclasse quem tem a mesma posição
                        if (el.getAttribute('data-pos') === myPos) el.classList.add('highlight-active');
                transRelated.forEach(el => {
                     });
                    if(el.getAttribute('data-pos') === myPos) {
                 }
                        el.classList.add('highlight-active');
                     }
                 });
             } else {
             } else {
                // Passou na Trans: Acende apenas ela mesma
                 this.classList.add('highlight-active');
                 this.classList.add('highlight-active');
             }
             }
         });
         });


         cell.addEventListener('mouseleave', function() {
         cell.addEventListener('mouseleave', function () {
             document.querySelectorAll('.highlight-active').forEach(el => el.classList.remove('highlight-active'));
             document.querySelectorAll('.highlight-active').forEach(function (el) {
                el.classList.remove('highlight-active');
            });
         });
         });
     });
     });
});
});


$(document).ready(function() {
    // Evita duplicar se a página recarregar
    if ($('.sidebar-logo').length === 0) {
        var logoHtml = '<div class="sidebar-logo">' +
                      '<a href="/everlight/index.php/Página_principal">' +
                      '<img src="http://78.142.242.9/everlight/images/b/b0/Logo_Quadrada.png" alt="Logo Everlight">' +
                      '</a>' +
                      '</div>';
       
        // Coloca a logo no topo do painel lateral
        $('#mw-panel').prepend(logoHtml);
    }
});




mw.loader.using('mediawiki.util').then(function () {


    const carousel = document.getElementById("farmlandCarousel");
/* =======================================================
  CARROSSEL FARMLAND
  ======================================================= */
mw.hook('wikipage.content').add(function () {


    var carousel = document.getElementById('farmlandCarousel');
     if (!carousel) return;
     if (!carousel) return;


     const container = carousel.querySelector(".carousel-container");
     var wrapper  = carousel.querySelector('.carousel-wrapper');
     const slides = carousel.querySelectorAll(".carousel-slide");
     var container = carousel.querySelector('.carousel-container');
 
     var slides  = carousel.querySelectorAll('.carousel-slide');
    const prev = carousel.querySelector(".left");
     var dotsWrap = carousel.querySelector('.carousel-dots');
    const next = carousel.querySelector(".right");
     var progBar  = carousel.querySelector('.carousel-progress');
 
     var nextBtn = carousel.querySelector('.carousel-arrow.right');
    const dotsContainer = carousel.querySelector(".carousel-dots");
     var prevBtn = carousel.querySelector('.carousel-arrow.left');
 
    let index = 0;
    let interval;
 
    // DOTS
    slides.forEach((slide, i) => {
 
        const dot = document.createElement("span");
 
        dot.className = "carousel-dot";
 
        if (i === 0) {
            dot.classList.add("active");
        }
 
        dot.addEventListener("click", function () {
            index = i;
            updateCarousel();
        });
 
        dotsContainer.appendChild(dot);
    });
 
    const dots = carousel.querySelectorAll(".carousel-dot");
 
    function updateCarousel() {
 
        container.style.transform =
            "translateX(-" + (index * 100) + "%)";
 
        dots.forEach(function(dot) {
            dot.classList.remove("active");
        });
 
        dots[index].classList.add("active");
    }
 
    function nextSlide() {
 
        index++;
 
        if (index >= slides.length) {
            index = 0;
        }
 
        updateCarousel();
    }
 
     function prevSlide() {
 
        index--;
 
        if (index < 0) {
            index = slides.length - 1;
        }
 
        updateCarousel();
    }
 
    next.onclick = nextSlide;
    prev.onclick = prevSlide;
 
    // AUTO PLAY
    function startCarousel() {
 
        interval = setInterval(function () {
            nextSlide();
        }, 4000);
    }
 
    function stopCarousel() {
        clearInterval(interval);
    }
 
    carousel.addEventListener("mouseenter", stopCarousel);
    carousel.addEventListener("mouseleave", startCarousel);
 
    startCarousel();
 
});
 
 
 
 
 
 
mw.loader.using(['jquery'], function () {
   $(function () {
 
    let index = 0;
 
    const container = document.querySelector(".carousel-container");
    const items = document.querySelectorAll(".carousel-slide");
     const total = items.length;
 
    if (!container || total === 0) return;
 
    function updateSlide() {
      container.style.transform = `translateX(-${index * 100}%)`;
    }
 
    // SETA DIREITA
    const right = document.querySelector(".carousel-arrow.right");
    if (right) {
      right.addEventListener("click", () => {
        index++;
        if (index >= total) index = 0;
        updateSlide();
      });
    }
 
    // SETA ESQUERDA
    const left = document.querySelector(".carousel-arrow.left");
    if (left) {
      left.addEventListener("click", () => {
        index--;
        if (index < 0) index = total - 1;
        updateSlide();
      });
    }
 
    // AUTO SLIDE
    setInterval(() => {
      index++;
      if (index >= total) index = 0;
      updateSlide();
    }, 3000);
 
  });
});
 
 
 
 
 
mw.loader.using(['jquery'], function () {
  $(function () {
 
    const wrapper = document.querySelector(".carousel-wrapper");
     const container = document.querySelector(".carousel-container");
    const slides = document.querySelectorAll(".carousel-slide");
    const dotsContainer = document.querySelector(".carousel-dots");
     const nextBtn = document.querySelector(".carousel-arrow.right");
     const prevBtn = document.querySelector(".carousel-arrow.left");


     if (!container || slides.length === 0) return;
     if (!container || slides.length === 0) return;


     let index = 1;
     var DELAY = 3500;
    let interval;
     var total = slides.length;
     let isTransitioning = false;
     var idx  = 1;
 
     var timer, busy = false;
    /* =========================
      CLONAR PARA LOOP INFINITO
    ========================= */
    const firstClone = slides[0].cloneNode(true);
     const lastClone = slides[slides.length - 1].cloneNode(true);
 
     firstClone.classList.add("clone");
    lastClone.classList.add("clone");


    /* Clones para loop infinito sem flash */
    var firstClone = slides[0].cloneNode(true);
    var lastClone  = slides[total - 1].cloneNode(true);
    firstClone.classList.add('clone');
    lastClone.classList.add('clone');
     container.appendChild(firstClone);
     container.appendChild(firstClone);
     container.insertBefore(lastClone, slides[0]);
     container.insertBefore(lastClone, slides[0]);


     const allSlides = document.querySelectorAll(".carousel-slide");
     var allSlides = container.querySelectorAll('.carousel-slide');
 
    /* =========================
      POSIÇÃO INICIAL
    ========================= */
    container.style.transform = `translateX(-${index * 100}%)`;
 
    /* =========================
      CRIAR DOTS
    ========================= */
    const dots = [];
 
    slides.forEach((_, i) => {
      const dot = document.createElement("span");
      dot.classList.add("dot");
      dotsContainer.appendChild(dot);
      dots.push(dot);


      dot.addEventListener("click", () => {
    /* Força layout correto (crítico no MediaWiki) */
        index = i + 1;
    container.style.display    = 'flex';
        updateSlide();
    container.style.transition = 'none';
         resetAuto();
    allSlides.forEach(function (s) {
      });
         s.style.minWidth  = '100%';
        s.style.flexShrink = '0';
     });
     });
    container.style.transform = 'translateX(-' + (idx * 100) + '%)';


     function updateDots() {
     /* Dots */
      dots.forEach(d => d.classList.remove("active"));
    dotsWrap.innerHTML = '';
 
    var dots = [];
      let activeIndex = index - 1;
    for (var i = 0; i < total; i++) {
      if (activeIndex < 0) activeIndex = slides.length - 1;
        var dot = document.createElement('span');
      if (activeIndex >= slides.length) activeIndex = 0;
        dot.className = 'dot';
 
        dotsWrap.appendChild(dot);
      if (dots[activeIndex]) {
        dots.push(dot);
        dots[activeIndex].classList.add("active");
        (function (n) {
      }
            dot.onclick = function () { goTo(n + 1); resetAuto(); };
        })(i);
     }
     }


    /* =========================
     function updateDots() {
      SLIDE UPDATE
         var ai = idx - 1;
    ========================= */
         if (ai < 0) ai = total - 1;
     function updateSlide(animate = true) {
         if (ai >= total) ai = 0;
      if (animate) {
         dots.forEach(function (d, i) {
         container.style.transition = "transform 0.5s ease";
            d.classList.toggle('active', i === ai);
      }
        });
 
      container.style.transform = `translateX(-${index * 100}%)`;
      updateDots();
    }
 
    /* =========================
      LOOP INFINITO SEM FLASH
    ========================= */
    container.addEventListener("transitionend", () => {
      if (allSlides[index].classList.contains("clone")) {
 
        container.style.transition = "none";
 
         if (index === 0) {
          index = slides.length;
         } else if (index === allSlides.length - 1) {
          index = 1;
         }
 
        container.style.transform = `translateX(-${index * 100}%)`;
      }
      isTransitioning = false;
    });
 
    /* =========================
      NEXT / PREV
    ========================= */
    function next() {
      if (isTransitioning) return;
      isTransitioning = true;
      index++;
      updateSlide();
      resetAuto();
     }
     }


     function prev() {
     function goTo(i, animate) {
      if (isTransitioning) return;
        if (busy) return;
      isTransitioning = true;
        busy = true;
      index--;
        idx  = i;
      updateSlide();
        container.style.transition = (animate === false)
      resetAuto();
            ? 'none'
            : 'transform 0.5s cubic-bezier(.4,0,.2,1)';
        container.style.transform = 'translateX(-' + (idx * 100) + '%)';
        updateDots();
     }
     }


     nextBtn?.addEventListener("click", next);
     container.addEventListener('transitionend', function () {
    prevBtn?.addEventListener("click", prev);
        if (allSlides[idx] && allSlides[idx].classList.contains('clone')) {
 
            container.style.transition = 'none';
    /* =========================
            idx = (idx === 0) ? total : 1;
      AUTO SLIDE
            container.style.transform = 'translateX(-' + (idx * 100) + '%)';
    ========================= */
            updateDots();
    function startAuto() {
      interval = setInterval(next, 3000);
    }
 
    function resetAuto() {
      clearInterval(interval);
      startAuto();
    }
 
    /* =========================
      PAUSA NO HOVER
    ========================= */
    wrapper.addEventListener("mouseenter", () => clearInterval(interval));
    wrapper.addEventListener("mouseleave", startAuto);
 
    /* =========================
      SWIPE MOBILE
    ========================= */
    let startX = 0;
    let endX = 0;
 
    wrapper.addEventListener("touchstart", (e) => {
      startX = e.touches[0].clientX;
    });
 
    wrapper.addEventListener("touchmove", (e) => {
      endX = e.touches[0].clientX;
    });
 
    wrapper.addEventListener("touchend", () => {
      const diff = startX - endX;
 
      if (Math.abs(diff) > 50) {
        if (diff > 0) {
          next();
        } else {
          prev();
         }
         }
      }
        busy = false;
     });
     });


     /* =========================
     function next() { goTo(idx + 1); resetAuto(); }
      INICIAR
     function prev() { goTo(idx - 1); resetAuto(); }
    ========================= */
    updateSlide(false);
     startAuto();
    updateDots();


  });
     if (nextBtn) nextBtn.onclick = next;
});
     if (prevBtn) prevBtn.onclick = prev;
 
mw.loader.using(['jquery'], function () {
  $(function () {
 
     const container = document.querySelector(".carousel-container");
    const slides = document.querySelectorAll(".carousel-slide");
    const dotsContainer = document.querySelector(".carousel-dots");
    const wrapper = document.querySelector(".carousel-wrapper");
 
     const nextBtn = document.querySelector(".carousel-arrow.right");
    const prevBtn = document.querySelector(".carousel-arrow.left");
 
    if (!container || slides.length === 0) return;


    let index = 0;
     /* Barra de progresso */
    let interval;
     function startProg() {
 
        if (!progBar) return;
     /* =========================
        progBar.style.transition = 'none';
      DOTS
        progBar.style.width = '0%';
    ========================= */
         setTimeout(function () {
     const dots = [];
            progBar.style.transition = 'width ' + DELAY + 'ms linear';
 
            progBar.style.width = '100%';
    slides.forEach((_, i) => {
        }, 30);
      const dot = document.createElement("span");
      dot.className = "dot";
      dotsContainer.appendChild(dot);
      dots.push(dot);
 
      dot.addEventListener("click", () => {
        index = i;
         update();
        resetAuto();
      });
    });
 
    function updateDots() {
      dots.forEach(d => d.classList.remove("active"));
      if (dots[index]) dots[index].classList.add("active");
     }
     }


    /* =========================
      SLIDE
    ========================= */
    function update() {
      container.style.transform = `translateX(-${index * 100}%)`;
      updateDots();
    }
    /* =========================
      NEXT / PREV
    ========================= */
    function next() {
      index++;
      if (index >= slides.length) index = 0;
      update();
      resetAuto();
    }
    function prev() {
      index--;
      if (index < 0) index = slides.length - 1;
      update();
      resetAuto();
    }
    nextBtn?.addEventListener("click", next);
    prevBtn?.addEventListener("click", prev);
    /* =========================
      AUTOPLAY
    ========================= */
     function startAuto() {
     function startAuto() {
      interval = setInterval(next, 3000);
        timer = setInterval(function () { goTo(idx + 1); startProg(); }, DELAY);
    }
        startProg();
 
    function resetAuto() {
      clearInterval(interval);
      startAuto();
     }
     }


     /* =========================
     function stopAuto() {
      PAUSA NO HOVER
         clearInterval(timer);
    ========================= */
         if (progBar) { progBar.style.transition = 'none'; progBar.style.width = '0%'; }
    wrapper?.addEventListener("mouseenter", () => clearInterval(interval));
    wrapper?.addEventListener("mouseleave", startAuto);
 
    /* =========================
      SWIPE MOBILE
    ========================= */
    let startX = 0;
 
    wrapper?.addEventListener("touchstart", (e) => {
      startX = e.touches[0].clientX;
    });
 
    wrapper?.addEventListener("touchend", (e) => {
      const endX = e.changedTouches[0].clientX;
      const diff = startX - endX;
 
      if (Math.abs(diff) > 50) {
         if (diff > 0) next();
         else prev();
      }
    });
 
    /* =========================
      INIT
    ========================= */
    update();
    startAuto();
 
  });
});
mw.loader.using(['jquery'], function () {
  $(function () {
 
    const container = document.querySelector(".carousel-container");
    const slides = document.querySelectorAll(".carousel-slide");
    const wrapper = document.querySelector(".carousel-wrapper");
    const dotsContainer = document.querySelector(".carousel-dots");
    const nextBtn = document.querySelector(".carousel-arrow.right");
    const prevBtn = document.querySelector(".carousel-arrow.left");
 
    if (!container || slides.length === 0) return;
 
    let index = 0;
    let interval;
 
    /* =========================
      GARANTE LAYOUT CORRETO
    ========================= */
    container.style.display = "flex";
 
    slides.forEach(s => {
      s.style.minWidth = "100%";
      s.style.flexShrink = "0";
    });
 
    /* =========================
      DOTS
    ========================= */
    const dots = [];
 
    slides.forEach((_, i) => {
      const dot = document.createElement("span");
      dot.className = "dot";
      dotsContainer.appendChild(dot);
      dots.push(dot);
 
      dot.addEventListener("click", () => {
        index = i;
        update();
        resetAuto();
      });
    });
 
    function updateDots() {
      dots.forEach(d => d.classList.remove("active"));
      if (dots[index]) dots[index].classList.add("active");
     }
     }


    /* =========================
     function resetAuto() { clearInterval(timer); startAuto(); }
      UPDATE SLIDE (IMPORTANTE)
    ========================= */
     function update() {
      container.style.transform = `translate3d(-${index * 100}%, 0, 0)`;
      updateDots();
    }


     /* =========================
     /* Pausa no hover */
      CONTROLES
     if (wrapper) {
    ========================= */
        wrapper.addEventListener('mouseenter', stopAuto);
     function next() {
        wrapper.addEventListener('mouseleave', startAuto);
      index++;
      if (index >= slides.length) index = 0;
      update();
      resetAuto();
     }
     }


     function prev() {
     /* Swipe mobile */
      index--;
    var startX = 0;
      if (index < 0) index = slides.length - 1;
    if (wrapper) {
      update();
        wrapper.addEventListener('touchstart', function (e) { startX = e.touches[0].clientX; });
      resetAuto();
        wrapper.addEventListener('touchend', function (e) {
            var diff = startX - e.changedTouches[0].clientX;
            if (Math.abs(diff) > 40) { diff > 0 ? next() : prev(); }
        });
     }
     }


     nextBtn?.addEventListener("click", next);
     updateDots();
    prevBtn?.addEventListener("click", prev);
 
    /* =========================
      AUTOPLAY
    ========================= */
    function startAuto() {
      interval = setInterval(next, 3000);
    }
 
    function resetAuto() {
      clearInterval(interval);
      startAuto();
    }
 
    /* =========================
      PAUSA NO HOVER
    ========================= */
    wrapper?.addEventListener("mouseenter", () => clearInterval(interval));
    wrapper?.addEventListener("mouseleave", startAuto);
 
    /* =========================
      SWIPE MOBILE (ROBUSTO)
    ========================= */
    let startX = 0;
 
    wrapper?.addEventListener("touchstart", (e) => {
      startX = e.touches[0].clientX;
    });
 
    wrapper?.addEventListener("touchend", (e) => {
      const endX = e.changedTouches[0].clientX;
      const diff = startX - endX;
 
      if (Math.abs(diff) > 40) {
        diff > 0 ? next() : prev();
      }
    });
 
    /* =========================
      INIT
    ========================= */
    update();
     startAuto();
     startAuto();
  });
});
});
(function () {
  function initCarousel() {
    const container = document.querySelector(".carousel-container");
    const slides = document.querySelectorAll(".carousel-slide");
    const wrapper = document.querySelector(".carousel-wrapper");
    const dotsContainer = document.querySelector(".carousel-dots");
    const nextBtn = document.querySelector(".carousel-arrow.right");
    const prevBtn = document.querySelector(".carousel-arrow.left");
    if (!container || slides.length === 0 || !wrapper) return;
    let index = 0;
    let timer;
    /* =========================
      FORÇA LAYOUT (CRÍTICO MEDIAWIKI)
    ========================= */
    container.style.display = "flex";
    container.style.transition = "transform 0.5s ease";
    slides.forEach(slide => {
      slide.style.minWidth = "100%";
      slide.style.flexShrink = "0";
    });
    /* =========================
      DOTS
    ========================= */
    dotsContainer.innerHTML = "";
    const dots = [];
    slides.forEach((_, i) => {
      const dot = document.createElement("span");
      dot.className = "dot";
      dotsContainer.appendChild(dot);
      dots.push(dot);
      dot.onclick = () => {
        index = i;
        update();
        restart();
      };
    });
    function updateDots() {
      dots.forEach(d => d.classList.remove("active"));
      if (dots[index]) dots[index].classList.add("active");
    }
    /* =========================
      MOVE SLIDE
    ========================= */
    function update() {
      container.style.transform = "translateX(-" + (index * 100) + "%)";
      updateDots();
    }
    /* =========================
      CONTROLES
    ========================= */
    function next() {
      index++;
      if (index >= slides.length) index = 0;
      update();
      restart();
    }
    function prev() {
      index--;
      if (index < 0) index = slides.length - 1;
      update();
      restart();
    }
    if (nextBtn) nextBtn.onclick = next;
    if (prevBtn) prevBtn.onclick = prev;
    /* =========================
      AUTO PLAY
    ========================= */
    function start() {
      timer = setInterval(next, 3000);
    }
    function stop() {
      clearInterval(timer);
    }
    function restart() {
      stop();
      start();
    }
    /* =========================
      PAUSA NO HOVER
    ========================= */
    wrapper.onmouseenter = stop;
    wrapper.onmouseleave = start;
    /* =========================
      SWIPE MOBILE (ROBUSTO)
    ========================= */
    let startX = 0;
    wrapper.ontouchstart = function (e) {
      startX = e.touches[0].clientX;
    };
    wrapper.ontouchend = function (e) {
      let endX = e.changedTouches[0].clientX;
      let diff = startX - endX;
      if (Math.abs(diff) > 50) {
        diff > 0 ? next() : prev();
      }
    };
    /* =========================
      INIT
    ========================= */
    update();
    start();
  }
  /* =========================
    MEDIAWIKI SAFE LOAD
  ========================= */
  if (document.readyState === "loading") {
    document.addEventListener("DOMContentLoaded", initCarousel);
  } else {
    initCarousel();
  }
})();

Edição atual tal como às 21h15min de 16 de maio de 2026

/* =======================================================
   ARVORE DE HABILIDADE
   ======================================================= */
document.addEventListener('DOMContentLoaded', function () {
    var cards = document.querySelectorAll('.skill-card');
    cards.forEach(function (card) {
        card.addEventListener('click', function () {
            card.style.filter = 'brightness(1.2)';
            setTimeout(function () { card.style.filter = 'brightness(1)'; }, 150);
        });
    });
});


/* =======================================================
   BOTAO VOLTAR AO TOPO
   ======================================================= */
$(function () {
    var $button = $('<button id="back-to-top" title="Voltar ao Topo">↑ Topo</button>');
    $('body').append($button);

    $(window).scroll(function () {
        if ($(window).scrollTop() + $(window).height() > $(document).height() - 100) {
            $button.fadeIn();
        } else {
            $button.fadeOut();
        }
    });

    $button.click(function () {
        $('html, body').animate({ scrollTop: 0 }, 'slow');
        return false;
    });
});


/* =======================================================
   ARVORE DE CLASSES
   ======================================================= */
document.addEventListener('DOMContentLoaded', function () {
    var cells = document.querySelectorAll('.ragnarok-tree td[class^="evo-"]');

    cells.forEach(function (cell) {
        var link = cell.querySelector('a');
        if (link) {
            cell.style.cursor = 'pointer';
            cell.addEventListener('click', function () { window.location.href = link.href; });
        }

        cell.addEventListener('mouseenter', function () {
            var familyClass = Array.from(this.classList).find(function (c) { return c.startsWith('evo-'); });
            if (!familyClass || familyClass === 'evo-all') return;

            var myPos    = this.getAttribute('data-pos');
            var prevEl   = this.closest('table').previousElementSibling;
            var isClass1 = prevEl && prevEl.innerText.includes('Classe 1');
            var isClass2 = prevEl && prevEl.innerText.includes('Classe 2');

            if (isClass1) {
                document.querySelectorAll('.' + familyClass).forEach(function (el) {
                    el.classList.add('highlight-active');
                });
            } else if (isClass2) {
                this.classList.add('highlight-active');
                var table3 = document.querySelector('table:nth-of-type(3)');
                if (table3) {
                    table3.querySelectorAll('.' + familyClass).forEach(function (el) {
                        if (el.getAttribute('data-pos') === myPos) el.classList.add('highlight-active');
                    });
                }
            } else {
                this.classList.add('highlight-active');
            }
        });

        cell.addEventListener('mouseleave', function () {
            document.querySelectorAll('.highlight-active').forEach(function (el) {
                el.classList.remove('highlight-active');
            });
        });
    });
});




/* =======================================================
   CARROSSEL FARMLAND
   ======================================================= */
mw.hook('wikipage.content').add(function () {

    var carousel = document.getElementById('farmlandCarousel');
    if (!carousel) return;

    var wrapper  = carousel.querySelector('.carousel-wrapper');
    var container = carousel.querySelector('.carousel-container');
    var slides   = carousel.querySelectorAll('.carousel-slide');
    var dotsWrap = carousel.querySelector('.carousel-dots');
    var progBar  = carousel.querySelector('.carousel-progress');
    var nextBtn  = carousel.querySelector('.carousel-arrow.right');
    var prevBtn  = carousel.querySelector('.carousel-arrow.left');

    if (!container || slides.length === 0) return;

    var DELAY = 3500;
    var total = slides.length;
    var idx   = 1;
    var timer, busy = false;

    /* Clones para loop infinito sem flash */
    var firstClone = slides[0].cloneNode(true);
    var lastClone  = slides[total - 1].cloneNode(true);
    firstClone.classList.add('clone');
    lastClone.classList.add('clone');
    container.appendChild(firstClone);
    container.insertBefore(lastClone, slides[0]);

    var allSlides = container.querySelectorAll('.carousel-slide');

    /* Força layout correto (crítico no MediaWiki) */
    container.style.display    = 'flex';
    container.style.transition = 'none';
    allSlides.forEach(function (s) {
        s.style.minWidth   = '100%';
        s.style.flexShrink = '0';
    });
    container.style.transform = 'translateX(-' + (idx * 100) + '%)';

    /* Dots */
    dotsWrap.innerHTML = '';
    var dots = [];
    for (var i = 0; i < total; i++) {
        var dot = document.createElement('span');
        dot.className = 'dot';
        dotsWrap.appendChild(dot);
        dots.push(dot);
        (function (n) {
            dot.onclick = function () { goTo(n + 1); resetAuto(); };
        })(i);
    }

    function updateDots() {
        var ai = idx - 1;
        if (ai < 0) ai = total - 1;
        if (ai >= total) ai = 0;
        dots.forEach(function (d, i) {
            d.classList.toggle('active', i === ai);
        });
    }

    function goTo(i, animate) {
        if (busy) return;
        busy = true;
        idx  = i;
        container.style.transition = (animate === false)
            ? 'none'
            : 'transform 0.5s cubic-bezier(.4,0,.2,1)';
        container.style.transform = 'translateX(-' + (idx * 100) + '%)';
        updateDots();
    }

    container.addEventListener('transitionend', function () {
        if (allSlides[idx] && allSlides[idx].classList.contains('clone')) {
            container.style.transition = 'none';
            idx = (idx === 0) ? total : 1;
            container.style.transform = 'translateX(-' + (idx * 100) + '%)';
            updateDots();
        }
        busy = false;
    });

    function next() { goTo(idx + 1); resetAuto(); }
    function prev() { goTo(idx - 1); resetAuto(); }

    if (nextBtn) nextBtn.onclick = next;
    if (prevBtn) prevBtn.onclick = prev;

    /* Barra de progresso */
    function startProg() {
        if (!progBar) return;
        progBar.style.transition = 'none';
        progBar.style.width = '0%';
        setTimeout(function () {
            progBar.style.transition = 'width ' + DELAY + 'ms linear';
            progBar.style.width = '100%';
        }, 30);
    }

    function startAuto() {
        timer = setInterval(function () { goTo(idx + 1); startProg(); }, DELAY);
        startProg();
    }

    function stopAuto() {
        clearInterval(timer);
        if (progBar) { progBar.style.transition = 'none'; progBar.style.width = '0%'; }
    }

    function resetAuto() { clearInterval(timer); startAuto(); }

    /* Pausa no hover */
    if (wrapper) {
        wrapper.addEventListener('mouseenter', stopAuto);
        wrapper.addEventListener('mouseleave', startAuto);
    }

    /* Swipe mobile */
    var startX = 0;
    if (wrapper) {
        wrapper.addEventListener('touchstart', function (e) { startX = e.touches[0].clientX; });
        wrapper.addEventListener('touchend', function (e) {
            var diff = startX - e.changedTouches[0].clientX;
            if (Math.abs(diff) > 40) { diff > 0 ? next() : prev(); }
        });
    }

    updateDots();
    startAuto();
});