MediaWiki:Common.js: Difference between revisions
Jump to navigation
Jump to search
Plausible: use site-specific tracking script |
Add Resources Calculator interactive widget JS |
||
| Line 57: | Line 57: | ||
s.onload = function () { plausible.init(); }; | s.onload = function () { plausible.init(); }; | ||
document.head.appendChild(s); | document.head.appendChild(s); | ||
})(); | |||
/* Resources Calculator — interactive widget on Category:Resources Calculator */ | |||
(function () { | |||
var RATES = { | |||
wood_1: { label: 'Wood · Lvl 1 Axe', min: 60, max: 96, unit: 'Wood' }, | |||
wood_2: { label: 'Wood · Lvl 2 Axe', min: 120, max: 192, unit: 'Wood' }, | |||
mine_1: { label: 'Stone/Coal/Metal · Lvl 1 Pickaxe', min: 84, max: 120, unit: 'resources' }, | |||
mine_2: { label: 'Stone/Coal/Metal · Lvl 2 Pickaxe', min: 168, max: 240, unit: 'resources' }, | |||
fish_1: { label: 'Fish · Fishing Rod', min: 2, max: 4, unit: 'Fish' }, | |||
}; | |||
function fmtNum(n) { | |||
if (n >= 1000000) return (n / 1000000).toFixed(2).replace(/\.?0+$/, '') + 'M'; | |||
if (n >= 1000) return (n / 1000).toFixed(1).replace(/\.0$/, '') + 'k'; | |||
return String(Math.round(n * 10) / 10); | |||
} | |||
function fmtDuration(minutes) { | |||
if (!isFinite(minutes) || minutes <= 0) return '—'; | |||
if (minutes < 60) return Math.round(minutes * 10) / 10 + ' minutes'; | |||
var h = minutes / 60; | |||
if (h < 24) return Math.round(h * 10) / 10 + ' hours'; | |||
return Math.round((h / 24) * 10) / 10 + ' days'; | |||
} | |||
function buildCalc(root) { | |||
root.className = 'kin-resource-calc'; | |||
root.innerHTML = | |||
'<div class="kin-rc-card">' + | |||
'<div class="kin-rc-head">Gathering time estimator</div>' + | |||
'<p class="kin-rc-note">Uses midpoint rate: (min + max) ÷ 2 per minute. Does not include travel between nodes or competition.</p>' + | |||
'<div class="kin-rc-fields">' + | |||
'<label class="kin-rc-field"><span>Setup</span><select id="kin-rc-setup"></select></label>' + | |||
'<label class="kin-rc-field"><span>Target amount</span><input id="kin-rc-target" type="number" min="1" step="1" value="1000" /></label>' + | |||
'</div>' + | |||
'<div class="kin-rc-results">' + | |||
'<div class="kin-rc-stat"><span class="kin-rc-stat-label">Rate range</span><strong id="kin-rc-rate">—</strong></div>' + | |||
'<div class="kin-rc-stat"><span class="kin-rc-stat-label">Midpoint rate</span><strong id="kin-rc-mid">—</strong></div>' + | |||
'<div class="kin-rc-stat kin-rc-stat--highlight"><span class="kin-rc-stat-label">Estimated time</span><strong id="kin-rc-time">—</strong></div>' + | |||
'</div>' + | |||
'</div>'; | |||
var setup = root.querySelector('#kin-rc-setup'); | |||
Object.keys(RATES).forEach(function (key) { | |||
var opt = document.createElement('option'); | |||
opt.value = key; | |||
opt.textContent = RATES[key].label; | |||
setup.appendChild(opt); | |||
}); | |||
function update() { | |||
var cfg = RATES[setup.value]; | |||
var target = parseFloat(root.querySelector('#kin-rc-target').value); | |||
var mid = (cfg.min + cfg.max) / 2; | |||
root.querySelector('#kin-rc-rate').textContent = cfg.min + '–' + cfg.max + ' / min'; | |||
root.querySelector('#kin-rc-mid').textContent = mid + ' ' + cfg.unit + ' / min'; | |||
root.querySelector('#kin-rc-time').textContent = (!target || target <= 0) | |||
? 'Enter a target amount' | |||
: fmtDuration(target / mid); | |||
} | |||
setup.addEventListener('change', update); | |||
root.querySelector('#kin-rc-target').addEventListener('input', update); | |||
update(); | |||
} | |||
function init() { | |||
var root = document.getElementById('kin-resource-calc'); | |||
if (root && !root.dataset.ready) { | |||
root.dataset.ready = '1'; | |||
buildCalc(root); | |||
} | |||
} | |||
if (document.readyState === 'loading') { | |||
document.addEventListener('DOMContentLoaded', init); | |||
} else { | |||
init(); | |||
} | |||
})(); | })(); | ||
Revision as of 05:43, 25 June 2026
/* Kintara dashboard sky — drifting geo clouds (matches kintara.com leaderboard backdrop) */
(function () {
function injectKinSky() {
if (document.getElementById('kin-sky-backdrop')) return;
var el = document.createElement('div');
el.id = 'kin-sky-backdrop';
el.setAttribute('aria-hidden', 'true');
el.innerHTML =
'<div class="kin-sky-clouds">' +
'<div class="kin-geo-puff kin-geo-puff--1"><span class="kin-geo-block kin-geo-block--a"></span><span class="kin-geo-block kin-geo-block--b"></span><span class="kin-geo-block kin-geo-block--c"></span></div>' +
'<div class="kin-geo-puff kin-geo-puff--2"><span class="kin-geo-block kin-geo-block--a"></span><span class="kin-geo-block kin-geo-block--b"></span><span class="kin-geo-block kin-geo-block--c"></span><span class="kin-geo-block kin-geo-block--d"></span></div>' +
'<div class="kin-geo-puff kin-geo-puff--3"><span class="kin-geo-block kin-geo-block--a"></span><span class="kin-geo-block kin-geo-block--b"></span><span class="kin-geo-block kin-geo-block--c"></span></div>' +
'<div class="kin-geo-puff kin-geo-puff--4"><span class="kin-geo-block kin-geo-block--a"></span><span class="kin-geo-block kin-geo-block--b"></span><span class="kin-geo-block kin-geo-block--c"></span><span class="kin-geo-block kin-geo-block--d"></span></div>' +
'<div class="kin-geo-puff kin-geo-puff--5"><span class="kin-geo-block kin-geo-block--a"></span><span class="kin-geo-block kin-geo-block--b"></span><span class="kin-geo-block kin-geo-block--c"></span></div>' +
'<div class="kin-geo-puff kin-geo-puff--6"><span class="kin-geo-block kin-geo-block--a"></span><span class="kin-geo-block kin-geo-block--b"></span><span class="kin-geo-block kin-geo-block--c"></span><span class="kin-geo-block kin-geo-block--d"></span></div>' +
'</div>';
document.body.insertBefore(el, document.body.firstChild);
}
if (document.body) injectKinSky();
else document.addEventListener('DOMContentLoaded', injectKinSky);
})();
mw.loader.using('mediawiki.util').then(function () {
if (mw.config.get('wgPageName') === 'Main_Page') {
document.querySelectorAll(
'.kin-promo.discord .pbody a, .kin-promo.xbox .pbody a'
).forEach(function (link) {
link.setAttribute('target', '_blank');
link.setAttribute('rel', 'nofollow noopener noreferrer');
});
}
var tabs = document.querySelector('#p-namespaces ul');
if (tabs && !document.getElementById('ca-kintara-play')) {
var playTab = document.createElement('li');
playTab.id = 'ca-kintara-play';
playTab.className = 'mw-list-item';
playTab.innerHTML =
'<a href="https://kintara.com/" target="_blank" rel="nofollow noopener noreferrer"><span>Play Now</span></a>';
tabs.appendChild(playTab);
}
});
/* Plausible Analytics — privacy-friendly pageviews for kintara.wiki */
(function () {
if (document.querySelector('script[src*="pa-QBNr94JQzRuLvqXz02DEQ.js"]')) return;
window.plausible = window.plausible || function () {
(plausible.q = plausible.q || []).push(arguments);
};
plausible.init = plausible.init || function (i) {
plausible.o = i || {};
};
var s = document.createElement('script');
s.async = true;
s.src = 'https://plausible.io/js/pa-QBNr94JQzRuLvqXz02DEQ.js';
s.onload = function () { plausible.init(); };
document.head.appendChild(s);
})();
/* Resources Calculator — interactive widget on Category:Resources Calculator */
(function () {
var RATES = {
wood_1: { label: 'Wood · Lvl 1 Axe', min: 60, max: 96, unit: 'Wood' },
wood_2: { label: 'Wood · Lvl 2 Axe', min: 120, max: 192, unit: 'Wood' },
mine_1: { label: 'Stone/Coal/Metal · Lvl 1 Pickaxe', min: 84, max: 120, unit: 'resources' },
mine_2: { label: 'Stone/Coal/Metal · Lvl 2 Pickaxe', min: 168, max: 240, unit: 'resources' },
fish_1: { label: 'Fish · Fishing Rod', min: 2, max: 4, unit: 'Fish' },
};
function fmtNum(n) {
if (n >= 1000000) return (n / 1000000).toFixed(2).replace(/\.?0+$/, '') + 'M';
if (n >= 1000) return (n / 1000).toFixed(1).replace(/\.0$/, '') + 'k';
return String(Math.round(n * 10) / 10);
}
function fmtDuration(minutes) {
if (!isFinite(minutes) || minutes <= 0) return '—';
if (minutes < 60) return Math.round(minutes * 10) / 10 + ' minutes';
var h = minutes / 60;
if (h < 24) return Math.round(h * 10) / 10 + ' hours';
return Math.round((h / 24) * 10) / 10 + ' days';
}
function buildCalc(root) {
root.className = 'kin-resource-calc';
root.innerHTML =
'<div class="kin-rc-card">' +
'<div class="kin-rc-head">Gathering time estimator</div>' +
'<p class="kin-rc-note">Uses midpoint rate: (min + max) ÷ 2 per minute. Does not include travel between nodes or competition.</p>' +
'<div class="kin-rc-fields">' +
'<label class="kin-rc-field"><span>Setup</span><select id="kin-rc-setup"></select></label>' +
'<label class="kin-rc-field"><span>Target amount</span><input id="kin-rc-target" type="number" min="1" step="1" value="1000" /></label>' +
'</div>' +
'<div class="kin-rc-results">' +
'<div class="kin-rc-stat"><span class="kin-rc-stat-label">Rate range</span><strong id="kin-rc-rate">—</strong></div>' +
'<div class="kin-rc-stat"><span class="kin-rc-stat-label">Midpoint rate</span><strong id="kin-rc-mid">—</strong></div>' +
'<div class="kin-rc-stat kin-rc-stat--highlight"><span class="kin-rc-stat-label">Estimated time</span><strong id="kin-rc-time">—</strong></div>' +
'</div>' +
'</div>';
var setup = root.querySelector('#kin-rc-setup');
Object.keys(RATES).forEach(function (key) {
var opt = document.createElement('option');
opt.value = key;
opt.textContent = RATES[key].label;
setup.appendChild(opt);
});
function update() {
var cfg = RATES[setup.value];
var target = parseFloat(root.querySelector('#kin-rc-target').value);
var mid = (cfg.min + cfg.max) / 2;
root.querySelector('#kin-rc-rate').textContent = cfg.min + '–' + cfg.max + ' / min';
root.querySelector('#kin-rc-mid').textContent = mid + ' ' + cfg.unit + ' / min';
root.querySelector('#kin-rc-time').textContent = (!target || target <= 0)
? 'Enter a target amount'
: fmtDuration(target / mid);
}
setup.addEventListener('change', update);
root.querySelector('#kin-rc-target').addEventListener('input', update);
update();
}
function init() {
var root = document.getElementById('kin-resource-calc');
if (root && !root.dataset.ready) {
root.dataset.ready = '1';
buildCalc(root);
}
}
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', init);
} else {
init();
}
})();