157 lines
9.1 KiB
JavaScript
157 lines
9.1 KiB
JavaScript
(function() {
|
|
function init() {
|
|
const containers = document.querySelectorAll('.hdyc-calc-container');
|
|
if (containers.length === 0) return;
|
|
|
|
containers.forEach(container => {
|
|
const type = container.dataset.hdycType;
|
|
const factor = parseFloat(container.dataset.hdycFactor) || 1;
|
|
const offset = parseFloat(container.dataset.hdycOffset) || 0;
|
|
const in1 = container.querySelector('#input-1');
|
|
const in2 = container.querySelector('#input-2');
|
|
const in3 = container.querySelector('#input-3');
|
|
|
|
if (!in1 || !in2) return;
|
|
|
|
function solve(source) {
|
|
let v1 = parseFloat(in1.value);
|
|
let v2 = parseFloat(in2.value);
|
|
let v3 = in3 ? parseFloat(in3.value) : NaN;
|
|
|
|
if (type === 'standard') {
|
|
if (source === 1) {
|
|
if (!isNaN(v1)) in2.value = parseFloat((v1 * factor + offset).toFixed(6));
|
|
else in2.value = '';
|
|
} else {
|
|
if (!isNaN(v2)) in1.value = parseFloat(((v2 - offset) / factor).toFixed(6));
|
|
else in1.value = '';
|
|
}
|
|
} else if (type === 'inverse') {
|
|
// Logic: v1 * v2 = factor (constant)
|
|
if (source === 1) {
|
|
if (!isNaN(v1) && v1 !== 0) in2.value = parseFloat((factor / v1).toFixed(6));
|
|
else in2.value = '';
|
|
} else {
|
|
if (!isNaN(v2) && v2 !== 0) in1.value = parseFloat((factor / v2).toFixed(6));
|
|
else in1.value = '';
|
|
}
|
|
} else if (type === '3col') {
|
|
// Standard 3-col: v3 = v1 / v2 (e.g. Watts = Amps * Volts -> in3 = in1 / in2? No, usually Watts is in3)
|
|
// Let's look at legacy scripts.
|
|
// grams-to-moles: in3 (moles) = in1 (mass) / in2 (molar mass)
|
|
// watts-to-amps: in3 (amps) = in1 (watts) / in2 (volts)
|
|
if (source === 1 || source === 2) {
|
|
if (!isNaN(v1) && !isNaN(v2) && v2 !== 0) in3.value = parseFloat((v1 / v2).toFixed(6));
|
|
else in3.value = '';
|
|
} else {
|
|
if (!isNaN(v3) && !isNaN(v2)) in1.value = parseFloat((v3 * v2).toFixed(6));
|
|
else in1.value = '';
|
|
}
|
|
} else if (type === '3col-mul') {
|
|
// v3 = v1 * v2 (e.g. Lux to Lumens: Lumens(3) = Lux(1) * Area(2))
|
|
if (source === 1 || source === 2) {
|
|
if (!isNaN(v1) && !isNaN(v2)) in3.value = parseFloat((v1 * v2).toFixed(6));
|
|
else in3.value = '';
|
|
} else {
|
|
if (!isNaN(v3) && !isNaN(v2) && v2 !== 0) in1.value = parseFloat((v3 / v2).toFixed(6));
|
|
else in1.value = '';
|
|
}
|
|
} else if (type === 'dms-dd') {
|
|
// DD to DMS (in1=DD, in2=DMS text)
|
|
if (source === 1) {
|
|
if (!isNaN(v1)) {
|
|
let d = Math.floor(v1); let md = (v1 - d) * 60; let m = Math.floor(md); let sec = ((md - m) * 60).toFixed(2);
|
|
in2.value = `${d}° ${m}' ${sec}"`;
|
|
} else in2.value = '';
|
|
} else {
|
|
let str = in2.value;
|
|
let match = str.match(/(?:([0-9.-]+)\s*°)?\s*(?:([0-9.-]+)\s*')?\s*(?:([0-9.-]+)\s*")?/);
|
|
if (match) {
|
|
let d = parseFloat(match[1]) || 0; let m = parseFloat(match[2]) || 0; let sec = parseFloat(match[3]) || 0;
|
|
if (str.trim().length > 0) in1.value = parseFloat((d + m/60 + sec/3600).toFixed(6));
|
|
else in1.value = '';
|
|
} else in1.value = '';
|
|
}
|
|
} else if (type === 'dd-dms') {
|
|
// DMS to DD inverse?
|
|
// Actually the legacy code for "dms-to-dd" has input-1 as DMS and input-2 as DD.
|
|
// I'll handle based on the ID mapping in the container.
|
|
} else if (type === 'dec-frac') {
|
|
function gcd(a, b) { return b ? gcd(b, a % b) : a; }
|
|
if (source === 1) {
|
|
if (!isNaN(v1)) {
|
|
let len = v1.toString().split('.')[1] ? v1.toString().split('.')[1].length : 0;
|
|
let den = Math.pow(10, len); let num = v1 * den; let div = gcd(num, den);
|
|
in2.value = `${num/div}/${den/div}`;
|
|
} else in2.value = '';
|
|
} else {
|
|
let parts = in2.value.split('/');
|
|
if (parts.length === 2 && !isNaN(parts[0]) && !isNaN(parts[1]) && parts[1] != 0) in1.value = parseFloat((parts[0]/parts[1]).toFixed(6));
|
|
else { let f = parseFloat(parts[0]); if (!isNaN(f)) in1.value = f; else in1.value = ''; }
|
|
}
|
|
} else if (type === 'db-int') {
|
|
if (source === 1) { if (!isNaN(v1)) in2.value = parseFloat((1e-12 * Math.pow(10, v1/10)).toExponential(6)); else in2.value = ''; }
|
|
else { if (!isNaN(v2) && v2 > 0) in1.value = parseFloat((10 * Math.log10(v2 / 1e-12)).toFixed(6)); else in1.value = ''; }
|
|
} else if (type === 'db-spl') {
|
|
if (source === 1) { if (!isNaN(v1)) in2.value = parseFloat((20 * Math.pow(10, v1/20)).toFixed(6)); else in2.value = ''; }
|
|
else { if (!isNaN(v2) && v2 > 0) in1.value = parseFloat((20 * Math.log10(v2 / 20)).toFixed(6)); else in1.value = ''; }
|
|
} else if (type === 'db-v') {
|
|
if (source === 1) { if (!isNaN(v1)) in2.value = parseFloat((1 * Math.pow(10, v1/20)).toFixed(6)); else in2.value = ''; }
|
|
else { if (!isNaN(v2) && v2 > 0) in1.value = parseFloat((20 * Math.log10(v2 / 1)).toFixed(6)); else in1.value = ''; }
|
|
} else if (type === 'db-w') {
|
|
if (source === 1) { if (!isNaN(v1)) in2.value = parseFloat((1 * Math.pow(10, v1/10)).toFixed(6)); else in2.value = ''; }
|
|
else { if (!isNaN(v2) && v2 > 0) in1.value = parseFloat((10 * Math.log10(v2 / 1)).toFixed(6)); else in1.value = ''; }
|
|
} else if (type === 'base') {
|
|
const fromBase = parseInt(container.dataset.hdycFrom) || 10;
|
|
const toBase = parseInt(container.dataset.hdycTo) || 2;
|
|
if (source === 1) {
|
|
try {
|
|
const val = in1.value.trim();
|
|
if (val === '') { in2.value = ''; return; }
|
|
const dec = parseInt(val, fromBase);
|
|
if (!isNaN(dec)) in2.value = dec.toString(toBase).toUpperCase();
|
|
else in2.value = 'Invalid';
|
|
} catch(e) { in2.value = 'Error'; }
|
|
} else {
|
|
try {
|
|
const val = in2.value.trim();
|
|
if (val === '') { in1.value = ''; return; }
|
|
const dec = parseInt(val, toBase);
|
|
if (!isNaN(dec)) in1.value = dec.toString(fromBase).toUpperCase();
|
|
else in1.value = 'Invalid';
|
|
} catch(e) { in1.value = 'Error'; }
|
|
}
|
|
} else if (type === 'text-bin') {
|
|
if (source === 1) {
|
|
in2.value = in1.value.split('').map(char => char.charCodeAt(0).toString(2).padStart(8, '0')).join(' ');
|
|
} else {
|
|
try {
|
|
in1.value = in2.value.split(' ').map(bin => String.fromCharCode(parseInt(bin, 2))).join('');
|
|
} catch(e) { in1.value = 'Error'; }
|
|
}
|
|
} else if (type === 'bin-text') {
|
|
if (source === 1) {
|
|
try {
|
|
in2.value = in1.value.split(' ').map(bin => String.fromCharCode(parseInt(bin, 2))).join('');
|
|
} catch(e) { in2.value = 'Error'; }
|
|
} else {
|
|
in1.value = in2.value.split('').map(char => char.charCodeAt(0).toString(2).padStart(8, '0')).join(' ');
|
|
}
|
|
}
|
|
}
|
|
|
|
in1.addEventListener('input', () => solve(1));
|
|
in2.addEventListener('input', () => solve(2));
|
|
if (in3) in3.addEventListener('input', () => solve(3));
|
|
|
|
const uParams = new URLSearchParams(window.location.search);
|
|
if (uParams.has('v1')) { in1.value = uParams.get('v1'); solve(1); }
|
|
else if (uParams.has('v2')) { in2.value = uParams.get('v2'); solve(2); }
|
|
else if (uParams.has('v3') && in3) { in3.value = uParams.get('v3'); solve(3); }
|
|
});
|
|
}
|
|
|
|
if (document.readyState === 'loading') document.addEventListener('DOMContentLoaded', init);
|
|
else init();
|
|
})();
|