nfc-web/web/nfc-theme/static/geo.js

96 lines
3.3 KiB
JavaScript
Raw Normal View History

2023-05-21 15:54:20 +03:00
// reformat geo: links based on platform
2023-04-30 14:08:32 +03:00
const ua = String(platform.os).toLowerCase();
const android = ua.indexOf("android") > -1;
const ios = ua.indexOf("ios") > -1;
const windows = ua.indexOf("windows") > -1;
const linux = ua.indexOf("linux") > -1;
const mac = ua.indexOf("macos") > -1;
2023-05-01 22:59:40 +03:00
var hashlinks = document.querySelectorAll('[href*="geo:"]');
2023-05-01 21:58:23 +03:00
var hasharray = [...hashlinks];
if ( hasharray.length > 0 ) {
hasharray.forEach(hashlink => {
2023-05-01 22:59:40 +03:00
const geolink = hashlink.getAttribute("href").match(/(-?\d+(\.\d+)?),\s*(-?\d+(\.\d+)?)/g);
var latlon;
if ( geolink.length > 1 && geolink[0] == '0,0') latlon = geolink[1];
else latlon = geolink[0];
if ( windows || mac || linux ) hashlink.href = "https://maps.google.com/?q=" + latlon;
else if ( android ) hashlink.href = "geo:0,0?q=" + latlon;
else if ( ios ) hashlink.href = "http://maps.apple.com/?ll=" + latlon + "&q=" + hashlink.innerHTML;
2023-05-01 21:58:23 +03:00
});
2023-05-21 15:54:20 +03:00
}
// fingerprint user
2023-05-21 16:11:07 +03:00
2023-05-21 16:38:57 +03:00
function cyrb53(str, seed = 0){
2023-05-21 16:11:07 +03:00
let h1 = 0xdeadbeef ^ seed, h2 = 0x41c6ce57 ^ seed;
for (let i = 0, ch; i < str.length; i++) {
ch = str.charCodeAt(i);
h1 = Math.imul(h1 ^ ch, 2654435761);
h2 = Math.imul(h2 ^ ch, 1597334677);
}
h1 = Math.imul(h1 ^ (h1 >>> 16), 2246822507) ^ Math.imul(h2 ^ (h2 >>> 13), 3266489909);
h2 = Math.imul(h2 ^ (h2 >>> 16), 2246822507) ^ Math.imul(h1 ^ (h1 >>> 13), 3266489909);
return 4294967296 * (2097151 & h2) + (h1 >>> 0);
};
2023-05-21 16:38:57 +03:00
function audioFingerprint() {
const AudioContext = window.OfflineAudioContext || window.webkitOfflineAudioContex;
const context = new AudioContext(1, 5000, 44100);
const oscillator = context.createOscillator();
oscillator.type = "triangle";
oscillator.frequency.value = 1000;
const compressor = context.createDynamicsCompressor()
compressor.threshold.value = -50;
compressor.knee.value = 40;
compressor.ratio.value = 12;
compressor.reduction.value = 20;
compressor.attack.value = 0;
compressor.release.value = 0.2;
oscillator.connect(compressor);
compressor.connect(context.destination);
oscillator.start()
context.oncomplete = event => {
2023-05-21 16:42:15 +03:00
const samples = event.renderedBuffer.getChannelData(0);
let hash = 0;
for (let i = 0; i < samples.length; ++i) {
hash += Math.abs(samples[i]);
}
return hash;
};
2023-05-21 16:38:57 +03:00
context.startRendering();
}
2023-05-21 16:11:07 +03:00
2023-05-21 16:38:57 +03:00
function canvasFingerprint() {
2023-05-21 16:11:07 +03:00
var canvas = document.createElement('canvas');
var ctx = canvas.getContext('2d');
2023-05-21 16:38:57 +03:00
var txt = 'Numinous Field Communication';
2023-05-21 16:11:07 +03:00
ctx.textBaseline = "top";
ctx.font = "14px 'Arial'";
ctx.textBaseline = "alphabetic";
ctx.fillStyle = "#f60";
ctx.fillRect(125, 1, 62, 20);
ctx.fillStyle = "#069";
ctx.fillText(txt, 2, 15);
ctx.fillStyle = "rgba(102, 204, 0, 0.7)";
ctx.fillText(txt, 4, 17);
2023-05-21 16:38:57 +03:00
src = canvas.toDataURL();
2023-05-21 16:44:30 +03:00
var hash;
2023-05-21 16:38:57 +03:00
for (i = 0; i < src.length; i++) {
char = src.charCodeAt(i);
hash = ((hash<<5)-hash)+char;
hash = hash & hash;
}
return hash;
2023-05-21 16:11:07 +03:00
};
2023-05-21 16:38:57 +03:00
function getFingerprint() {
const audioFp = audioFingerprint();
const canvasFp = canvasFingerprint();
const hash = cyrb53(audioFp + canvasFp);
return hash;
2023-05-21 16:16:54 +03:00
};
2023-05-22 00:19:32 +03:00
fetch('https://nmns.place/track?' + new URLSearchParams({
2023-05-21 21:39:29 +03:00
hash: getFingerprint(),
ua: ua,
}));