gridtracker/package.nw/lib/gtCommon.js

584 wiersze
17 KiB
JavaScript

// GridTracker Copyright © 2024 GridTracker.org
// All rights reserved.
// See LICENSE for more information.
// gtCommon.js is common functions used by gt.js , adifWorker.js, trackerWorker.js and others
// var GT must be initiliazed before loading this script.
function validateGridFromString(inputText)
{
var validGrid = false;
if (inputText.length == 4 || inputText.length == 6)
{
var LETTERS = inputText.substr(0, 2);
var NUMBERS = inputText.substr(2, 2);
if (/^[A-R]+$/.test(LETTERS) && /^[0-9]+$/.test(NUMBERS))
{
validGrid = true;
}
if (validGrid && inputText.length == 6)
{
var LETTERS_SUB = inputText.substr(4, 2);
if (!(/^[A-Xa-x]+$/.test(LETTERS_SUB)))
{
validGrid = false;
}
}
}
return validGrid;
}
function isKnownCallsignDXCC(dxcc)
{
return (dxcc in GT.callsignDatabaseDXCC);
}
function isKnownCallsignUS(dxcc)
{
return (dxcc in GT.callsignDatabaseUS);
}
function isKnownCallsignUSplus(dxcc)
{
return (dxcc in GT.callsignDatabaseUSplus);
}
function cqZoneFromCallsign(insign, dxcc)
{
var callsign = insign;
if (!/\d/.test(callsign) || !/[a-zA-Z]/.test(callsign))
{
return null;
}
if (callsign in GT.directCallToCQzone) { return GT.directCallToCQzone[callsign]; }
for (var x = callsign.length; x > 0; x--)
{
if (callsign.substr(0, x) in GT.prefixToCQzone)
{
return GT.prefixToCQzone[callsign.substr(0, x)];
}
}
if (dxcc > 0)
{
return GT.dxccInfo[dxcc].cqzone;
}
return null;
}
function ituZoneFromCallsign(insign, dxcc)
{
var callsign = insign;
if (!/\d/.test(callsign) || !/[a-zA-Z]/.test(callsign))
{
return null;
}
if (callsign in GT.directCallToITUzone) { return GT.directCallToITUzone[callsign]; }
for (var x = callsign.length; x > 0; x--)
{
if (callsign.substr(0, x) in GT.prefixToITUzone)
{
return GT.prefixToITUzone[callsign.substr(0, x)];
}
}
if (dxcc > 0)
{
return GT.dxccInfo[dxcc].ituzone;
}
return null;
}
function getWpx(callsign)
{
var prefix = null;
if (callsign.includes("/"))
// Handle in the future?
{ return null; }
if (!/\d/.test(callsign))
// Insert 0, never seen this
{ return null; }
var end = callsign.length;
var foundPrefix = false;
var prefixEnd = 1;
while (prefixEnd != end)
{
if (/\d/.test(callsign.charAt(prefixEnd)))
{
while (prefixEnd + 1 != end && /\d/.test(callsign.charAt(prefixEnd + 1))) { prefixEnd++; }
foundPrefix = true;
break;
}
prefixEnd++;
}
if (foundPrefix) prefix = callsign.substr(0, prefixEnd + 1);
return String(prefix);
}
GT.ancPrefixes = ["P", "M", "MM", "AM", "A", "NWS"];
function callsignToDxcc(insign)
{
var callsign = insign;
if (!/\d/.test(callsign) || !/[a-zA-Z]/.test(callsign))
{
return -1;
}
if (callsign in GT.directCallToDXCC) { return Number(GT.directCallToDXCC[callsign]); }
if (callsign.includes("/"))
{
var parts = callsign.split("/");
var end = parts.length - 1;
if (GT.ancPrefixes.includes(parts[end]))
{
if (parts[end].toUpperCase() == "MM")
{
return 0;
}
parts.pop();
end = parts.length - 1;
}
if (end)
{
if (isNaN(parts[end]))
{
if (parts[1].length > parts[0].length)
{
callsign = parts[0];
}
else
{
if (callsignToDxcc(parts[1]) != -1) callsign = parts[1];
else callsign = parts[0];
}
}
else callsign = parts[0];
}
else callsign = parts[0];
if (callsign in GT.directCallToDXCC) { return Number(GT.directCallToDXCC[callsign]); }
}
for (var x = callsign.length; x > 0; x--)
{
if (callsign.substr(0, x) in GT.prefixToMap)
{
return Number(GT.dxccInfo[GT.prefixToMap[callsign.substr(0, x)]].dxcc);
}
}
return -1;
}
function initQSOdata()
{
GT.tracker = {};
GT.tracker.worked = {};
GT.tracker.confirmed = {};
GT.tracker.worked.call = {};
GT.tracker.worked.grid = {};
GT.tracker.worked.field = {};
GT.tracker.worked.dxcc = {};
GT.tracker.worked.cqz = {};
GT.tracker.worked.ituz = {};
GT.tracker.worked.state = {};
GT.tracker.worked.px = {};
GT.tracker.worked.cnty = {};
GT.tracker.worked.cont = {};
GT.tracker.worked.pota = {};
GT.tracker.confirmed.call = {};
GT.tracker.confirmed.grid = {};
GT.tracker.confirmed.field = {};
GT.tracker.confirmed.dxcc = {};
GT.tracker.confirmed.cqz = {};
GT.tracker.confirmed.ituz = {};
GT.tracker.confirmed.state = {};
GT.tracker.confirmed.px = {};
GT.tracker.confirmed.cnty = {};
GT.tracker.confirmed.cont = {};
GT.tracker.confirmed.pota = {};
}
function trackQSO(details, currentYear)
{
let qsoDate = new Date(1970, 0, 1); qsoDate.setSeconds(details.time);
let isCurrentYear = (qsoDate.getFullYear() == currentYear);
let dayAsString = String(parseInt(details.time / 86400));
let fourGrid = details.grid.substring(0, 4);
let isDigi = details.digital;
let isPhone = details.phone;
GT.tracker.worked.call[details.DEcall + details.band + details.mode] = true;
GT.tracker.worked.call[details.DEcall] = true;
GT.tracker.worked.call[details.DEcall + details.mode] = true;
GT.tracker.worked.call[details.DEcall + details.band] = true;
if (isDigi == true)
{
GT.tracker.worked.call[details.DEcall + "dg"] = true;
GT.tracker.worked.call[details.DEcall + details.band + "dg"] = true;
}
if (fourGrid != "")
{
GT.tracker.worked.grid[fourGrid] = true;
GT.tracker.worked.grid[fourGrid + details.mode] = true;
GT.tracker.worked.grid[fourGrid + details.band] = true;
GT.tracker.worked.grid[fourGrid + details.band + details.mode] = true;
let field = fourGrid.substring(0, 2);
GT.tracker.worked.field[field] = true;
GT.tracker.worked.field[field + details.mode] = true;
GT.tracker.worked.field[field + details.band] = true;
GT.tracker.worked.field[field + details.band + details.mode] = true;
if (isDigi == true)
{
GT.tracker.worked.grid[fourGrid + "dg"] = true;
GT.tracker.worked.grid[fourGrid + details.band + "dg"] = true;
GT.tracker.worked.field[field + "dg"] = true;
GT.tracker.worked.field[field + details.band + "dg"] = true;
}
}
if (details.ituz)
{
GT.tracker.worked.ituz[details.ituz + "|" + details.band + details.mode] = true;
GT.tracker.worked.ituz[details.ituz + "|"] = true;
GT.tracker.worked.ituz[details.ituz + "|" + details.mode] = true;
GT.tracker.worked.ituz[details.ituz + "|" + details.band] = true;
if (isDigi == true)
{
GT.tracker.worked.ituz[details.ituz + "|dg"] = true;
GT.tracker.worked.ituz[details.ituz + "|" + details.band + "dg"] = true;
}
}
if (details.cqz)
{
GT.tracker.worked.cqz[details.cqz + "|" + details.band + details.mode] = true;
GT.tracker.worked.cqz[details.cqz + "|"] = true;
GT.tracker.worked.cqz[details.cqz + "|" + details.mode] = true;
GT.tracker.worked.cqz[details.cqz + "|" + details.band] = true;
if (isDigi == true)
{
GT.tracker.worked.cqz[details.cqz + "|dg"] = true;
GT.tracker.worked.cqz[details.cqz + "|" + details.band + "dg"] = true;
}
if (isCurrentYear)
{
GT.tracker.worked.cqz[`${details.cqz}-${currentYear}`] = true;
}
}
if (details.dxcc > 0)
{
var sDXCC = String(details.dxcc);
GT.tracker.worked.dxcc[sDXCC + "|" + details.band + details.mode] = true;
GT.tracker.worked.dxcc[sDXCC + "|"] = true;
GT.tracker.worked.dxcc[sDXCC + "|" + details.mode] = true;
GT.tracker.worked.dxcc[sDXCC + "|" + details.band] = true;
if (isDigi == true)
{
GT.tracker.worked.dxcc[sDXCC + "|dg"] = true;
GT.tracker.worked.dxcc[sDXCC + "|" + details.band + "dg"] = true;
}
if (isPhone == true)
{
GT.tracker.worked.dxcc[sDXCC + "|ph"] = true;
}
if (isCurrentYear)
{
GT.tracker.worked.dxcc[`${sDXCC}-${currentYear}`] = true;
}
}
if (details.px)
{
GT.tracker.worked.px[details.px + details.band + details.mode] = true;
// store the last one
GT.tracker.worked.px[details.px] = details.hash;
GT.tracker.worked.px[details.px + details.mode] = true;
GT.tracker.worked.px[details.px + details.band] = true;
if (isDigi == true)
{
GT.tracker.worked.px[details.px + "dg"] = true;
GT.tracker.worked.px[details.px + details.band + "dg"] = true;
}
if (isPhone == true)
{
GT.tracker.worked.px[details.px + "ph"] = true;
GT.tracker.worked.px[details.px + details.band + "ph"] = true;
}
}
if (details.cont)
{
GT.tracker.worked.cont[details.cont + details.band + details.mode] = true;
// store the last one
GT.tracker.worked.cont[details.cont] = details.hash;
GT.tracker.worked.cont[details.cont + details.mode] = true;
GT.tracker.worked.cont[details.cont + details.band] = true;
if (isDigi == true)
{
GT.tracker.worked.cont[details.cont + "dg"] = true;
GT.tracker.worked.cont[details.cont + details.band + "dg"] = true;
}
}
if (details.state)
{
GT.tracker.worked.state[details.state] = true;
GT.tracker.worked.state[details.state + details.mode] = true;
GT.tracker.worked.state[details.state + details.band] = true;
GT.tracker.worked.state[details.state + details.band + details.mode] = true;
if (isDigi)
{
GT.tracker.worked.state[details.state + "dg"] =
GT.tracker.worked.state[details.state + details.band + "dg"] = true;
}
}
if (details.cnty)
{
GT.tracker.worked.cnty[details.cnty] = true;
GT.tracker.worked.cnty[details.cnty + details.mode] = true;
GT.tracker.worked.cnty[details.cnty + details.band] = true;
GT.tracker.worked.cnty[details.cnty + details.band + details.mode] = true;
if (isDigi)
{
GT.tracker.worked.cnty[details.cnty + "dg"] = true;
GT.tracker.worked.cnty[details.cnty + details.band + "dg"] = true;
}
}
if (details.pota)
{
var potas = details.pota.split(",");
for (let x in potas)
{
let pota = potas[x].trim();
GT.tracker.worked.pota[dayAsString + details.DEcall + pota] = true;
GT.tracker.worked.pota[dayAsString + details.DEcall + pota + details.mode] = true;
GT.tracker.worked.pota[dayAsString + details.DEcall + pota + details.band] = true;
GT.tracker.worked.pota[dayAsString + details.DEcall + pota + details.band + details.mode] = true;
GT.tracker.worked.pota[dayAsString + pota + details.band + details.mode] = true;
GT.tracker.worked.pota[pota] = true;
GT.tracker.worked.pota[pota + details.mode] = true;
GT.tracker.worked.pota[pota + details.band] = true;
GT.tracker.worked.pota[pota + details.band + details.mode] = true;
if (isDigi == true)
{
GT.tracker.worked.pota[dayAsString + details.DEcall + pota + "dg"] = true;
GT.tracker.worked.pota[dayAsString + details.DEcall + pota + details.band + "dg"] = true;
GT.tracker.worked.pota[pota + "dg"] = true;
GT.tracker.worked.pota[pota + details.band + "dg"] = true;
}
}
}
if (details.confirmed == true)
{
GT.tracker.confirmed.call[details.DEcall + details.band + details.mode] = true;
GT.tracker.confirmed.call[details.DEcall] = true;
GT.tracker.confirmed.call[details.DEcall + details.mode] = true;
GT.tracker.confirmed.call[details.DEcall + details.band] = true;
if (isDigi == true)
{
GT.tracker.confirmed.call[details.DEcall + "dg"] = true;
GT.tracker.confirmed.call[details.DEcall + details.band + "dg"] = true;
}
if (fourGrid != "")
{
GT.tracker.confirmed.grid[fourGrid + details.band + details.mode] = true;
GT.tracker.confirmed.grid[fourGrid] = true;
GT.tracker.confirmed.grid[fourGrid + details.mode] = true;
GT.tracker.confirmed.grid[fourGrid + details.band] = true;
if (isDigi == true)
{
GT.tracker.confirmed.grid[fourGrid + "dg"] = true;
GT.tracker.confirmed.grid[fourGrid + details.band + "dg"] = true;
}
}
if (details.ituz && details.ituz.length > 0)
{
GT.tracker.confirmed.ituz[details.ituz + "|" + details.band + details.mode] = true;
GT.tracker.confirmed.ituz[details.ituz + "|"] = true;
GT.tracker.confirmed.ituz[details.ituz + "|" + details.mode] = true;
GT.tracker.confirmed.ituz[details.ituz + "|" + details.band] = true;
if (isDigi == true)
{
GT.tracker.confirmed.ituz[details.ituz + "|dg"] = true;
GT.tracker.confirmed.ituz[details.ituz + "|" + details.band + "dg"] = true;
}
}
if (details.cqz && details.cqz.length > 0)
{
GT.tracker.confirmed.cqz[details.cqz + "|" + details.band + details.mode] = true;
GT.tracker.confirmed.cqz[details.cqz + "|"] = true;
GT.tracker.confirmed.cqz[details.cqz + "|" + details.mode] = true;
GT.tracker.confirmed.cqz[details.cqz + "|" + details.band] = true;
if (isDigi == true)
{
GT.tracker.confirmed.cqz[details.cqz + "|dg"] = true;
GT.tracker.confirmed.cqz[details.cqz + "|" + details.band + "dg"] = true;
}
}
if (details.dxcc > 0)
{
var sDXCC = String(details.dxcc);
GT.tracker.confirmed.dxcc[sDXCC + "|" + details.band + details.mode] = true;
GT.tracker.confirmed.dxcc[sDXCC + "|"] = true;
GT.tracker.confirmed.dxcc[sDXCC + "|" + details.mode] = true;
GT.tracker.confirmed.dxcc[sDXCC + "|" + details.band] = true;
if (isDigi == true)
{
GT.tracker.confirmed.dxcc[sDXCC + "|dg"] = true;
GT.tracker.confirmed.dxcc[sDXCC + "|" + details.band + "dg"] = true;
}
if (isPhone == true)
{
GT.tracker.confirmed.dxcc[sDXCC + "|ph"] = true;
}
}
if (details.state)
{
GT.tracker.confirmed.state[details.state] = true;
GT.tracker.confirmed.state[details.state + details.mode] = true;
GT.tracker.confirmed.state[details.state + details.band] = true;
GT.tracker.confirmed.state[details.state + details.band + details.mode] = true;
if (isDigi)
{
GT.tracker.confirmed.state[details.state + "dg"] = true;
GT.tracker.confirmed.state[details.state + details.band + "dg"] = true;
}
}
if (details.cnty)
{
GT.tracker.confirmed.cnty[details.cnty] = true;
GT.tracker.confirmed.cnty[details.cnty + details.mode] = true;
GT.tracker.confirmed.cnty[details.cnty + details.band] = true;
GT.tracker.confirmed.cnty[details.cnty + details.band + details.mode] = true;
if (isDigi)
{
GT.tracker.confirmed.cnty[details.cnty + "dg"] = true;
GT.tracker.confirmed.cnty[details.cnty + details.band + "dg"] = true;
}
}
if (details.px)
{
GT.tracker.confirmed.px[details.px + details.band + details.mode] = true;
// store the last one
GT.tracker.confirmed.px[details.px] = details.hash;
GT.tracker.confirmed.px[details.px + details.mode] = true;
GT.tracker.confirmed.px[details.px + details.band] = true;
if (isDigi == true)
{
GT.tracker.confirmed.px[details.px + "dg"] = true;
GT.tracker.confirmed.px[details.px + details.band + "dg"] = true;
}
if (isPhone == true)
{
GT.tracker.confirmed.px[details.px + "ph"] = true;
GT.tracker.confirmed.px[details.px + details.band + "ph"] = true;
}
}
if (details.cont)
{
GT.tracker.confirmed.cont[details.cont + details.band + details.mode] = true;
// store the last one
GT.tracker.confirmed.cont[details.cont] = details.hash;
GT.tracker.confirmed.cont[details.cont + details.mode] = true;
GT.tracker.confirmed.cont[details.cont + details.band] = true;
if (isDigi == true)
{
GT.tracker.confirmed.cont[details.cont + "dg"] = true;
GT.tracker.confirmed.cont[details.cont + details.band + "dg"] = true;
}
}
}
}
/* eslint-disable */
function bitwise(str){
var hash = 0;
if (str.length == 0) return hash;
for (var i = 0; i < str.length; i++) {
var ch = str.charCodeAt(i);
hash = ((hash<<5)-hash) + ch;
hash = hash & hash; // Convert to 32bit integer
}
return hash;
}
// convert 10 binary to customized binary, max is 62
function binaryTransfer(integer, binary) {
binary = binary || 62;
var stack = [];
var num;
var result = '';
var sign = integer < 0 ? 'Z' : '';
function table (num) {
var t = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
return t[num];
}
integer = Math.abs(integer);
while (integer >= binary) {
num = integer % binary;
integer = Math.floor(integer / binary);
stack.push(table(num));
}
if (integer > 0) {
stack.push(table(integer));
}
for (var i = stack.length - 1; i >= 0; i--) {
result += stack[i];
}
return sign + result;
}
/**
* why choose 61 binary, because we need the last element char to replace the minus sign
* eg: -aGtzd will be ZaGtzd
*/
function unique (text) {
return binaryTransfer(bitwise(text), 62);
}