MediaWiki:Common.js: Difference between revisions
Jump to navigation
Jump to search
No edit summary |
No edit summary |
||
| Line 2: | Line 2: | ||
(function ($, mw) { | (function ($, mw) { | ||
'use strict'; | 'use strict'; | ||
/* ========================================================= | |||
GLOBAL BASICS | |||
========================================================= */ | |||
function setLogoHref() { | function setLogoHref() { | ||
| Line 11: | Line 15: | ||
function ensureFontAwesome() { | function ensureFontAwesome() { | ||
if ( | if (document.querySelector('link[data-timero-fa]')) return; | ||
var fa = document.createElement('link'); | |||
fa.rel = 'stylesheet'; | |||
fa.href = 'https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.0/css/all.min.css'; | |||
fa.setAttribute('data-timero-fa', '1'); | |||
} | document.head.appendChild(fa); | ||
} | |||
function bindActionButton(el, handler) { | |||
if (!el || el.dataset.timeroBound === '1') return; | |||
el.dataset.timeroBound = '1'; | |||
el.setAttribute('role', 'button'); | |||
el.setAttribute('tabindex', '0'); | |||
el.addEventListener('click', function (e) { | |||
e.preventDefault(); | |||
handler.call(this, e); | |||
}); | |||
el.addEventListener('keydown', function (e) { | |||
if (e.key === 'Enter' || e.key === ' ') { | |||
e.preventDefault(); | |||
handler.call(this, e); | |||
} | |||
}); | |||
} | } | ||
/* ========================= | /* ========================================================= | ||
ROUTES | ROUTES | ||
========================= */ | ========================================================= */ | ||
function resetRoutePill(pill) { | function resetRoutePill(pill) { | ||
| Line 44: | Line 68: | ||
var details = section.querySelectorAll('.route-detail'); | var details = section.querySelectorAll('.route-detail'); | ||
var pills = section.querySelectorAll('.route-pill[data-route]'); | |||
for (var i = 0; i < details.length; i++) { | for (var i = 0; i < details.length; i++) { | ||
details[i].style.display = 'none'; | details[i].style.display = 'none'; | ||
} | } | ||
for (var j = 0; j < pills.length; j++) { | for (var j = 0; j < pills.length; j++) { | ||
resetRoutePill(pills[j]); | resetRoutePill(pills[j]); | ||
| Line 96: | Line 121: | ||
var pills = section.querySelectorAll('.route-pill[data-route]'); | var pills = section.querySelectorAll('.route-pill[data-route]'); | ||
for (var i = 0; i < pills.length; i++) { | for (var i = 0; i < pills.length; i++) { | ||
(function (pill) { | |||
bindActionButton(pill, function () { | |||
expandRoute(this.getAttribute('data-route')); | expandRoute(this.getAttribute('data-route')); | ||
} | }); | ||
}); | })(pills[i]); | ||
} | } | ||
var closeButtons = section.querySelectorAll('.route-close[data-route]'); | var closeButtons = section.querySelectorAll('.route-close[data-route]'); | ||
for (var j = 0; j < closeButtons.length; j++) { | for (var j = 0; j < closeButtons.length; j++) { | ||
(function (closeBtn) { | |||
bindActionButton(closeBtn, function () { | |||
expandRoute(this.getAttribute('data-route')); | expandRoute(this.getAttribute('data-route')); | ||
} | }); | ||
}); | })(closeButtons[j]); | ||
} | } | ||
} | } | ||
/* ========================= | /* ========================================================= | ||
METHODS | METHODS | ||
========================= */ | ========================================================= */ | ||
function resetMethodTab(tab, type) { | function resetMethodTab(tab, type) { | ||
| Line 178: | Line 179: | ||
var panels = section.querySelectorAll('.method-panel'); | var panels = section.querySelectorAll('.method-panel'); | ||
var tabs = section.querySelectorAll('.method-tab[data-method]'); | |||
for (var i = 0; i < panels.length; i++) { | for (var i = 0; i < panels.length; i++) { | ||
panels[i].style.display = 'none'; | panels[i].style.display = 'none'; | ||
} | } | ||
for (var j = 0; j < tabs.length; j++) { | for (var j = 0; j < tabs.length; j++) { | ||
resetMethodTab(tabs[j], tabs[j].getAttribute('data-method')); | resetMethodTab(tabs[j], tabs[j].getAttribute('data-method')); | ||
| Line 206: | Line 208: | ||
var tabs = section.querySelectorAll('.method-tab[data-method]'); | var tabs = section.querySelectorAll('.method-tab[data-method]'); | ||
for (var i = 0; i < tabs.length; i++) { | for (var i = 0; i < tabs.length; i++) { | ||
(function (tab) { | |||
bindActionButton(tab, function () { | |||
switchMethod(this.getAttribute('data-method')); | switchMethod(this.getAttribute('data-method')); | ||
} | }); | ||
}); | })(tabs[i]); | ||
} | } | ||
if (!section.getAttribute('data-open-method')) { | if (!section.getAttribute('data-open-method')) { | ||
switchMethod('grind'); | switchMethod('grind'); | ||
} else { | |||
switchMethod(section.getAttribute('data-open-method')); | |||
} | } | ||
} | } | ||
/* ========================= | /* ========================================================= | ||
CALCULATOR | |||
========================= */ | ========================================================= */ | ||
var calcState = { | var calcState = { | ||
hours: 2, | |||
booster: false, | |||
rate: 70, | |||
label: 'Rota Mid-Game (70M/hr)', | |||
weeklyTarget: 12000 | |||
}; | }; | ||
function formatMillions(value) { | function formatMillions(value) { | ||
var rounded = Math.round(value * 10) / 10; | |||
if (rounded >= 1000) { | |||
var billions = rounded / 1000; | |||
var bText = (Math.round(billions * 10) / 10).toString().replace('.0', '').replace('.', ','); | |||
return bText + 'B z'; | |||
} | |||
var mText = rounded.toString().replace('.0', '').replace('.', ','); | |||
return mText + 'M z'; | |||
} | } | ||
function refreshCalcMethodUI(section) { | |||
if (!section) return; | |||
var labelEl = section.querySelector('#calc-method-label'); | |||
var menuEl = section.querySelector('#calc-method-menu'); | |||
var options = section.querySelectorAll('.calc-method-option'); | |||
if (labelEl) { | |||
labelEl.textContent = calcState.label; | |||
} | |||
for (var i = 0; i < options.length; i++) { | |||
var opt = options[i]; | |||
var isActive = String(opt.getAttribute('data-rate')) === String(calcState.rate); | |||
if (isActive) { | |||
opt.style.background = 'rgba(0,212,255,0.12)'; | |||
opt.style.borderColor = 'rgba(0,212,255,0.25)'; | |||
opt.style.color = '#00d4ff'; | |||
opt.style.fontWeight = '800'; | |||
} else { | |||
opt.style.background = 'rgba(255,255,255,0.03)'; | |||
opt.style.borderColor = 'rgba(255,255,255,0.06)'; | |||
opt.style.color = 'rgba(232,238,248,0.82)'; | |||
opt.style.fontWeight = '700'; | |||
} | |||
} | |||
if ( | if (menuEl) { | ||
menuEl.style.display = section.getAttribute('data-method-menu-open') === '1' ? 'block' : 'none'; | |||
} | } | ||
} | } | ||
window.adjustCalc = function (field, delta) { | |||
if (field !== 'hours') return; | |||
calcState.hours = Math.max(0.5, Math.min(24, calcState.hours + delta)); | |||
updateCalc(); | |||
}; | |||
}; | |||
window.setBooster = function (enabled) { | window.setBooster = function (enabled) { | ||
calcState.booster = !!enabled; | |||
updateCalc(); | |||
}; | }; | ||
window.setCalcMethod = function (rate, label) { | window.setCalcMethod = function (rate, label) { | ||
calcState.rate = parseFloat(rate || '0'); | |||
calcState.label = label || ''; | |||
var section = document.getElementById('calculator-section'); | |||
if (section) { | |||
section.setAttribute('data-method-menu-open', '0'); | |||
} | |||
updateCalc(); | |||
}; | |||
}; | |||
window. | window.toggleCalcMethodMenu = function () { | ||
var section = document.getElementById('calculator-section'); | |||
if (!section) return; | |||
var isOpen = section.getAttribute('data-method-menu-open') === '1'; | |||
section.setAttribute('data-method-menu-open', isOpen ? '0' : '1'); | |||
refreshCalcMethodUI(section); | |||
}; | |||
window.closeCalcMethodMenu = function () { | |||
var section = document.getElementById('calculator-section'); | |||
if (!section) return; | |||
section.setAttribute('data-method-menu-open', '0'); | |||
refreshCalcMethodUI(section); | |||
}; | |||
window.updateCalc = function () { | |||
var section = document.getElementById('calculator-section'); | |||
if (!section) return; | |||
var hoursEl = document.getElementById('calc-hours'); | |||
var resultSession = document.getElementById('result-session'); | |||
var resultDay = document.getElementById('result-day'); | |||
var resultWeek = document.getElementById('result-week'); | |||
var resultPct = document.getElementById('result-pct'); | |||
var resultBar = document.getElementById('result-bar'); | |||
var boostNo = document.getElementById('boost-no'); | |||
var boostYes = document.getElementById('boost-yes'); | |||
var effectiveRate = calcState.booster ? calcState.rate * 1.5 : calcState.rate; | |||
var session = calcState.hours * effectiveRate; | |||
var day = session; | |||
var week = day * 7; | |||
var pct = Math.max(0, Math.min(100, Math.round((week / calcState.weeklyTarget) * 100))); | |||
if (hoursEl) { | |||
hoursEl.textContent = calcState.hours % 1 === 0 ? String(calcState.hours) : String(calcState.hours).replace('.', ','); | |||
} | } | ||
if (resultSession) resultSession.textContent = formatMillions(session); | |||
if (resultDay) resultDay.textContent = formatMillions(day); | |||
if (resultWeek) resultWeek.textContent = formatMillions(week); | |||
if (resultPct) resultPct.textContent = pct + '%'; | |||
if (resultBar) resultBar.style.width = pct + '%'; | |||
if (boostNo && boostYes) { | |||
if (calcState.booster) { | |||
boostNo.style.background = 'rgba(255,255,255,0.04)'; | |||
boostNo.style.borderColor = 'rgba(255,255,255,0.09)'; | |||
boostNo.style.color = 'rgba(122,144,176,0.60)'; | |||
boostNo.style.fontWeight = '700'; | |||
boostYes.style.background = 'rgba(0,212,255,0.15)'; | |||
boostYes.style.borderColor = 'rgba(0,212,255,0.30)'; | |||
boostYes.style.color = '#00d4ff'; | |||
boostYes.style.fontWeight = '800'; | |||
} else { | |||
boostNo.style.background = 'rgba(255,61,90,0.15)'; | |||
boostNo.style.borderColor = 'rgba(255,61,90,0.30)'; | |||
boostNo.style.color = '#ff3d5a'; | |||
boostNo.style.fontWeight = '800'; | |||
boostYes.style.background = 'rgba(255,255,255,0.04)'; | |||
boostYes.style.borderColor = 'rgba(255,255,255,0.09)'; | |||
boostYes.style.color = 'rgba(122,144,176,0.60)'; | |||
boostYes.style.fontWeight = '700'; | |||
} | } | ||
} | |||
refreshCalcMethodUI(section); | |||
}; | |||
function bindCalculator(context) { | |||
var scope = context && context.querySelector ? context : document; | |||
var section = scope.querySelector('#calculator-section') || document.getElementById('calculator-section'); | |||
if (!section) return; | |||
var adjusters = section.querySelectorAll('[data-calc-adjust]'); | |||
for (var i = 0; i < adjusters.length; i++) { | |||
(function (adjuster) { | |||
bindActionButton(adjuster, function (e) { | |||
e.stopPropagation(); | |||
adjustCalc(this.getAttribute('data-calc-adjust'), parseFloat(this.getAttribute('data-delta') || '0')); | |||
}); | |||
})(adjusters[i]); | |||
} | |||
var boosters = section.querySelectorAll('[data-booster]'); | |||
for (var j = 0; j < boosters.length; j++) { | |||
(function (booster) { | |||
bindActionButton(booster, function (e) { | |||
e.stopPropagation(); | |||
setBooster(this.getAttribute('data-booster') === '1'); | |||
}); | |||
})(boosters[j]); | |||
} | |||
} | |||
methodDisplay. | var methodDisplay = section.querySelector('#calc-method-display'); | ||
if (methodDisplay) { | |||
e. | bindActionButton(methodDisplay, function (e) { | ||
e.stopPropagation(); | |||
toggleCalcMethodMenu(); | toggleCalcMethodMenu(); | ||
}); | |||
} | |||
var options = section.querySelectorAll('.calc-method-option'); | |||
for (var k = 0; k < options.length; k++) { | |||
(function (option) { | |||
bindActionButton(option, function (e) { | |||
e.stopPropagation(); | |||
setCalcMethod(this.getAttribute('data-rate'), this.getAttribute('data-label')); | |||
}); | |||
})(options[k]); | |||
} | |||
if (!window.__timeroCalcDocBound) { | |||
window.__timeroCalcDocBound = true; | |||
document.addEventListener('click', function (e) { | |||
var liveSection = document.getElementById('calculator-section'); | |||
if (!liveSection) return; | |||
if (!liveSection.contains(e.target)) { | |||
closeCalcMethodMenu(); | |||
} | |||
}); | |||
} | |||
if (!section.getAttribute('data-method-menu-open')) { | |||
section.setAttribute('data-method-menu-open', '0'); | |||
} | |||
updateCalc(); | |||
} | } | ||
/* ========================================================= | |||
/* ========================= | |||
LOADOUT | LOADOUT | ||
========================= */ | ========================================================= */ | ||
function setLoadoutItemState(item, active) { | function setLoadoutItemState(item, active) { | ||
if (!item) return; | |||
var check = item.querySelector('.li-check'); | var check = item.querySelector('.li-check'); | ||
if (!check) return; | if (!check) return; | ||
| Line 501: | Line 454: | ||
item.style.borderColor = 'rgba(176,108,255,0.24)'; | item.style.borderColor = 'rgba(176,108,255,0.24)'; | ||
item.style.boxShadow = '0 0 0 1px rgba(176,108,255,0.05) inset'; | item.style.boxShadow = '0 0 0 1px rgba(176,108,255,0.05) inset'; | ||
check.style.background = 'rgba(176,108,255,0.16)'; | check.style.background = 'rgba(176,108,255,0.16)'; | ||
check.style.borderColor = 'rgba(176,108,255,0.45)'; | check.style.borderColor = 'rgba(176,108,255,0.45)'; | ||
| Line 510: | Line 464: | ||
item.style.borderColor = 'rgba(255,255,255,0.07)'; | item.style.borderColor = 'rgba(255,255,255,0.07)'; | ||
item.style.boxShadow = 'none'; | item.style.boxShadow = 'none'; | ||
check.style.background = 'rgba(176,108,255,0.04)'; | check.style.background = 'rgba(176,108,255,0.04)'; | ||
check.style.borderColor = 'rgba(176,108,255,0.30)'; | check.style.borderColor = 'rgba(176,108,255,0.30)'; | ||
| Line 541: | Line 496: | ||
window.toggleLoadout = function (element) { | window.toggleLoadout = function (element) { | ||
if (!element) return; | if (!element) return; | ||
var active = !element.classList.contains('is-active'); | var active = !element.classList.contains('is-active'); | ||
setLoadoutItemState(element, active); | setLoadoutItemState(element, active); | ||
| Line 565: | Line 521: | ||
var items = section.querySelectorAll('.loadout-item'); | var items = section.querySelectorAll('.loadout-item'); | ||
for (var i = 0; i < items.length; i++) { | for (var i = 0; i < items.length; i++) { | ||
(function (item) { | |||
setLoadoutItemState(item, item.classList.contains('is-active')); | |||
bindActionButton(item, function () { | |||
toggleLoadout(this); | toggleLoadout(this); | ||
} | }); | ||
}); | })(items[i]); | ||
} | } | ||
var clearBtn = section.querySelector('.loadout-clear'); | var clearBtn = section.querySelector('.loadout-clear'); | ||
if (clearBtn | if (clearBtn) { | ||
bindActionButton(clearBtn, function () { | |||
clearLoadout(); | clearLoadout(); | ||
}); | }); | ||
} | } | ||
| Line 606: | Line 539: | ||
updateLoadoutSummary(); | updateLoadoutSummary(); | ||
} | } | ||
/* ========================================================= | |||
INIT | |||
========================================================= */ | |||
function init(context) { | function init(context) { | ||
Revision as of 17:32, 13 April 2026
/* Any JavaScript here will be loaded for all users on every page load. */
(function ($, mw) {
'use strict';
/* =========================================================
GLOBAL BASICS
========================================================= */
function setLogoHref() {
var logoLink = document.querySelector('#p-logo a');
if (logoLink) {
logoLink.setAttribute('href', 'https://timero.com.br/');
}
}
function ensureFontAwesome() {
if (document.querySelector('link[data-timero-fa]')) return;
var fa = document.createElement('link');
fa.rel = 'stylesheet';
fa.href = 'https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.0/css/all.min.css';
fa.setAttribute('data-timero-fa', '1');
document.head.appendChild(fa);
}
function bindActionButton(el, handler) {
if (!el || el.dataset.timeroBound === '1') return;
el.dataset.timeroBound = '1';
el.setAttribute('role', 'button');
el.setAttribute('tabindex', '0');
el.addEventListener('click', function (e) {
e.preventDefault();
handler.call(this, e);
});
el.addEventListener('keydown', function (e) {
if (e.key === 'Enter' || e.key === ' ') {
e.preventDefault();
handler.call(this, e);
}
});
}
/* =========================================================
ROUTES
========================================================= */
function resetRoutePill(pill) {
if (!pill) return;
pill.style.transform = '';
pill.style.fontWeight = '800';
pill.style.boxShadow = 'none';
pill.style.filter = 'none';
}
function activateRoutePill(pill) {
if (!pill) return;
pill.style.transform = 'translateY(-1px)';
pill.style.fontWeight = '900';
pill.style.boxShadow = '0 0 0 1px rgba(255,255,255,0.05) inset, 0 0 22px rgba(255,255,255,0.05)';
pill.style.filter = 'brightness(1.08)';
}
function closeAllRoutes(section) {
if (!section) return;
var details = section.querySelectorAll('.route-detail');
var pills = section.querySelectorAll('.route-pill[data-route]');
for (var i = 0; i < details.length; i++) {
details[i].style.display = 'none';
}
for (var j = 0; j < pills.length; j++) {
resetRoutePill(pills[j]);
}
section.setAttribute('data-open-route', '');
}
window.expandRoute = function (routeId) {
var section = document.getElementById('routes-section');
if (!section) return;
var target = document.getElementById(routeId);
if (!target) return;
var currentOpen = section.getAttribute('data-open-route');
if (currentOpen === routeId) {
closeAllRoutes(section);
return;
}
closeAllRoutes(section);
target.style.display = 'block';
target.style.animation = 'route-in 0.3s ease both';
section.setAttribute('data-open-route', routeId);
var activePill = document.getElementById('pill-' + routeId);
activateRoutePill(activePill);
if (typeof target.scrollIntoView === 'function') {
setTimeout(function () {
target.scrollIntoView({
behavior: 'smooth',
block: 'nearest'
});
}, 80);
}
};
function bindRouteViewer(context) {
var scope = context && context.querySelector ? context : document;
var section = scope.querySelector('#routes-section') || document.getElementById('routes-section');
if (!section) return;
var pills = section.querySelectorAll('.route-pill[data-route]');
for (var i = 0; i < pills.length; i++) {
(function (pill) {
bindActionButton(pill, function () {
expandRoute(this.getAttribute('data-route'));
});
})(pills[i]);
}
var closeButtons = section.querySelectorAll('.route-close[data-route]');
for (var j = 0; j < closeButtons.length; j++) {
(function (closeBtn) {
bindActionButton(closeBtn, function () {
expandRoute(this.getAttribute('data-route'));
});
})(closeButtons[j]);
}
}
/* =========================================================
METHODS
========================================================= */
function resetMethodTab(tab, type) {
if (!tab) return;
tab.style.background = 'transparent';
tab.style.fontWeight = '700';
if (type === 'grind') tab.style.color = 'rgba(249,197,0,0.60)';
if (type === 'market') tab.style.color = 'rgba(0,212,255,0.60)';
if (type === 'passive') tab.style.color = 'rgba(176,108,255,0.60)';
}
function activateMethodTab(tab, type) {
if (!tab) return;
tab.style.fontWeight = '900';
if (type === 'grind') {
tab.style.background = 'linear-gradient(135deg,rgba(249,197,0,0.18),rgba(249,197,0,0.07))';
tab.style.color = '#f9c500';
}
if (type === 'market') {
tab.style.background = 'linear-gradient(135deg,rgba(0,212,255,0.14),rgba(0,212,255,0.05))';
tab.style.color = '#00d4ff';
}
if (type === 'passive') {
tab.style.background = 'linear-gradient(135deg,rgba(176,108,255,0.14),rgba(176,108,255,0.05))';
tab.style.color = '#b06cff';
}
}
window.switchMethod = function (methodId) {
var section = document.getElementById('methods-section');
if (!section) return;
var panels = section.querySelectorAll('.method-panel');
var tabs = section.querySelectorAll('.method-tab[data-method]');
for (var i = 0; i < panels.length; i++) {
panels[i].style.display = 'none';
}
for (var j = 0; j < tabs.length; j++) {
resetMethodTab(tabs[j], tabs[j].getAttribute('data-method'));
}
var activePanel = document.getElementById('method-' + methodId);
if (activePanel) {
activePanel.style.display = 'grid';
activePanel.style.animation = 'method-in 0.3s ease both';
}
var activeTab = document.getElementById('mtab-' + methodId);
activateMethodTab(activeTab, methodId);
section.setAttribute('data-open-method', methodId);
};
function bindMethodViewer(context) {
var scope = context && context.querySelector ? context : document;
var section = scope.querySelector('#methods-section') || document.getElementById('methods-section');
if (!section) return;
var tabs = section.querySelectorAll('.method-tab[data-method]');
for (var i = 0; i < tabs.length; i++) {
(function (tab) {
bindActionButton(tab, function () {
switchMethod(this.getAttribute('data-method'));
});
})(tabs[i]);
}
if (!section.getAttribute('data-open-method')) {
switchMethod('grind');
} else {
switchMethod(section.getAttribute('data-open-method'));
}
}
/* =========================================================
CALCULATOR
========================================================= */
var calcState = {
hours: 2,
booster: false,
rate: 70,
label: 'Rota Mid-Game (70M/hr)',
weeklyTarget: 12000
};
function formatMillions(value) {
var rounded = Math.round(value * 10) / 10;
if (rounded >= 1000) {
var billions = rounded / 1000;
var bText = (Math.round(billions * 10) / 10).toString().replace('.0', '').replace('.', ',');
return bText + 'B z';
}
var mText = rounded.toString().replace('.0', '').replace('.', ',');
return mText + 'M z';
}
function refreshCalcMethodUI(section) {
if (!section) return;
var labelEl = section.querySelector('#calc-method-label');
var menuEl = section.querySelector('#calc-method-menu');
var options = section.querySelectorAll('.calc-method-option');
if (labelEl) {
labelEl.textContent = calcState.label;
}
for (var i = 0; i < options.length; i++) {
var opt = options[i];
var isActive = String(opt.getAttribute('data-rate')) === String(calcState.rate);
if (isActive) {
opt.style.background = 'rgba(0,212,255,0.12)';
opt.style.borderColor = 'rgba(0,212,255,0.25)';
opt.style.color = '#00d4ff';
opt.style.fontWeight = '800';
} else {
opt.style.background = 'rgba(255,255,255,0.03)';
opt.style.borderColor = 'rgba(255,255,255,0.06)';
opt.style.color = 'rgba(232,238,248,0.82)';
opt.style.fontWeight = '700';
}
}
if (menuEl) {
menuEl.style.display = section.getAttribute('data-method-menu-open') === '1' ? 'block' : 'none';
}
}
window.adjustCalc = function (field, delta) {
if (field !== 'hours') return;
calcState.hours = Math.max(0.5, Math.min(24, calcState.hours + delta));
updateCalc();
};
window.setBooster = function (enabled) {
calcState.booster = !!enabled;
updateCalc();
};
window.setCalcMethod = function (rate, label) {
calcState.rate = parseFloat(rate || '0');
calcState.label = label || '';
var section = document.getElementById('calculator-section');
if (section) {
section.setAttribute('data-method-menu-open', '0');
}
updateCalc();
};
window.toggleCalcMethodMenu = function () {
var section = document.getElementById('calculator-section');
if (!section) return;
var isOpen = section.getAttribute('data-method-menu-open') === '1';
section.setAttribute('data-method-menu-open', isOpen ? '0' : '1');
refreshCalcMethodUI(section);
};
window.closeCalcMethodMenu = function () {
var section = document.getElementById('calculator-section');
if (!section) return;
section.setAttribute('data-method-menu-open', '0');
refreshCalcMethodUI(section);
};
window.updateCalc = function () {
var section = document.getElementById('calculator-section');
if (!section) return;
var hoursEl = document.getElementById('calc-hours');
var resultSession = document.getElementById('result-session');
var resultDay = document.getElementById('result-day');
var resultWeek = document.getElementById('result-week');
var resultPct = document.getElementById('result-pct');
var resultBar = document.getElementById('result-bar');
var boostNo = document.getElementById('boost-no');
var boostYes = document.getElementById('boost-yes');
var effectiveRate = calcState.booster ? calcState.rate * 1.5 : calcState.rate;
var session = calcState.hours * effectiveRate;
var day = session;
var week = day * 7;
var pct = Math.max(0, Math.min(100, Math.round((week / calcState.weeklyTarget) * 100)));
if (hoursEl) {
hoursEl.textContent = calcState.hours % 1 === 0 ? String(calcState.hours) : String(calcState.hours).replace('.', ',');
}
if (resultSession) resultSession.textContent = formatMillions(session);
if (resultDay) resultDay.textContent = formatMillions(day);
if (resultWeek) resultWeek.textContent = formatMillions(week);
if (resultPct) resultPct.textContent = pct + '%';
if (resultBar) resultBar.style.width = pct + '%';
if (boostNo && boostYes) {
if (calcState.booster) {
boostNo.style.background = 'rgba(255,255,255,0.04)';
boostNo.style.borderColor = 'rgba(255,255,255,0.09)';
boostNo.style.color = 'rgba(122,144,176,0.60)';
boostNo.style.fontWeight = '700';
boostYes.style.background = 'rgba(0,212,255,0.15)';
boostYes.style.borderColor = 'rgba(0,212,255,0.30)';
boostYes.style.color = '#00d4ff';
boostYes.style.fontWeight = '800';
} else {
boostNo.style.background = 'rgba(255,61,90,0.15)';
boostNo.style.borderColor = 'rgba(255,61,90,0.30)';
boostNo.style.color = '#ff3d5a';
boostNo.style.fontWeight = '800';
boostYes.style.background = 'rgba(255,255,255,0.04)';
boostYes.style.borderColor = 'rgba(255,255,255,0.09)';
boostYes.style.color = 'rgba(122,144,176,0.60)';
boostYes.style.fontWeight = '700';
}
}
refreshCalcMethodUI(section);
};
function bindCalculator(context) {
var scope = context && context.querySelector ? context : document;
var section = scope.querySelector('#calculator-section') || document.getElementById('calculator-section');
if (!section) return;
var adjusters = section.querySelectorAll('[data-calc-adjust]');
for (var i = 0; i < adjusters.length; i++) {
(function (adjuster) {
bindActionButton(adjuster, function (e) {
e.stopPropagation();
adjustCalc(this.getAttribute('data-calc-adjust'), parseFloat(this.getAttribute('data-delta') || '0'));
});
})(adjusters[i]);
}
var boosters = section.querySelectorAll('[data-booster]');
for (var j = 0; j < boosters.length; j++) {
(function (booster) {
bindActionButton(booster, function (e) {
e.stopPropagation();
setBooster(this.getAttribute('data-booster') === '1');
});
})(boosters[j]);
}
var methodDisplay = section.querySelector('#calc-method-display');
if (methodDisplay) {
bindActionButton(methodDisplay, function (e) {
e.stopPropagation();
toggleCalcMethodMenu();
});
}
var options = section.querySelectorAll('.calc-method-option');
for (var k = 0; k < options.length; k++) {
(function (option) {
bindActionButton(option, function (e) {
e.stopPropagation();
setCalcMethod(this.getAttribute('data-rate'), this.getAttribute('data-label'));
});
})(options[k]);
}
if (!window.__timeroCalcDocBound) {
window.__timeroCalcDocBound = true;
document.addEventListener('click', function (e) {
var liveSection = document.getElementById('calculator-section');
if (!liveSection) return;
if (!liveSection.contains(e.target)) {
closeCalcMethodMenu();
}
});
}
if (!section.getAttribute('data-method-menu-open')) {
section.setAttribute('data-method-menu-open', '0');
}
updateCalc();
}
/* =========================================================
LOADOUT
========================================================= */
function setLoadoutItemState(item, active) {
if (!item) return;
var check = item.querySelector('.li-check');
if (!check) return;
if (active) {
item.classList.add('is-active');
item.style.background = 'rgba(176,108,255,0.08)';
item.style.borderColor = 'rgba(176,108,255,0.24)';
item.style.boxShadow = '0 0 0 1px rgba(176,108,255,0.05) inset';
check.style.background = 'rgba(176,108,255,0.16)';
check.style.borderColor = 'rgba(176,108,255,0.45)';
check.style.color = '#b06cff';
check.innerHTML = '✓';
} else {
item.classList.remove('is-active');
item.style.background = 'rgba(255,255,255,0.03)';
item.style.borderColor = 'rgba(255,255,255,0.07)';
item.style.boxShadow = 'none';
check.style.background = 'rgba(176,108,255,0.04)';
check.style.borderColor = 'rgba(176,108,255,0.30)';
check.style.color = 'transparent';
check.innerHTML = '';
}
}
function updateLoadoutSummary() {
var section = document.getElementById('loadout-section');
if (!section) return;
var items = section.querySelectorAll('.loadout-item');
var total = 0;
var count = 0;
for (var i = 0; i < items.length; i++) {
if (items[i].classList.contains('is-active')) {
total += parseFloat(items[i].getAttribute('data-cost') || '0');
count += 1;
}
}
var totalEl = document.getElementById('loadout-total');
var countEl = document.getElementById('loadout-count');
if (totalEl) totalEl.textContent = total + 'k z';
if (countEl) countEl.textContent = String(count);
}
window.toggleLoadout = function (element) {
if (!element) return;
var active = !element.classList.contains('is-active');
setLoadoutItemState(element, active);
updateLoadoutSummary();
};
window.clearLoadout = function () {
var section = document.getElementById('loadout-section');
if (!section) return;
var items = section.querySelectorAll('.loadout-item');
for (var i = 0; i < items.length; i++) {
setLoadoutItemState(items[i], false);
}
updateLoadoutSummary();
};
function bindLoadout(context) {
var scope = context && context.querySelector ? context : document;
var section = scope.querySelector('#loadout-section') || document.getElementById('loadout-section');
if (!section) return;
var items = section.querySelectorAll('.loadout-item');
for (var i = 0; i < items.length; i++) {
(function (item) {
setLoadoutItemState(item, item.classList.contains('is-active'));
bindActionButton(item, function () {
toggleLoadout(this);
});
})(items[i]);
}
var clearBtn = section.querySelector('.loadout-clear');
if (clearBtn) {
bindActionButton(clearBtn, function () {
clearLoadout();
});
}
updateLoadoutSummary();
}
/* =========================================================
INIT
========================================================= */
function init(context) {
setLogoHref();
ensureFontAwesome();
bindMethodViewer(context || document);
bindRouteViewer(context || document);
bindCalculator(context || document);
bindLoadout(context || document);
}
$(function () {
init(document);
});
if (mw && mw.hook) {
mw.hook('wikipage.content').add(function ($content) {
init(($content && $content[0]) || document);
});
}
})(jQuery, mediaWiki);