Files
Andrei 58f8093689 Rebrand from 'Redirect Intelligence v2' to 'URL Tracker Tool V2' throughout UI
- Updated all component headers and documentation
- Changed navbar and footer branding
- Updated homepage hero badge
- Modified page title in index.html
- Simplified footer text to 'Built with ❤️'
- Consistent V2 capitalization across all references
2025-08-19 19:12:23 +00:00

162 lines
5.1 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// text-polyfill.ts
// Minimal encode/decode for utf-8, utf-16le, ascii, latin1, windows-1252
const WINDOWS_1252_EXTRA = {
0x80: "€", 0x82: "", 0x83: "ƒ", 0x84: "„", 0x85: "…", 0x86: "†",
0x87: "‡", 0x88: "ˆ", 0x89: "‰", 0x8a: "Š", 0x8b: "", 0x8c: "Œ",
0x8e: "Ž", 0x91: "", 0x92: "", 0x93: "“", 0x94: "”", 0x95: "•",
0x96: "", 0x97: "—", 0x98: "˜", 0x99: "™", 0x9a: "š", 0x9b: "",
0x9c: "œ", 0x9e: "ž", 0x9f: "Ÿ",
};
const WINDOWS_1252_REVERSE = {};
for (const [code, char] of Object.entries(WINDOWS_1252_EXTRA)) {
WINDOWS_1252_REVERSE[char] = Number.parseInt(code);
}
/**
* Decode text from binary data
* @param bytes Binary data
* @param encoding Encoding
*/
export function textDecode(bytes, encoding = "utf-8") {
switch (encoding.toLowerCase()) {
case "utf-8":
case "utf8":
if (typeof globalThis.TextDecoder !== "undefined") {
return new globalThis.TextDecoder("utf-8").decode(bytes);
}
return decodeUTF8(bytes);
case "utf-16le":
return decodeUTF16LE(bytes);
case "ascii":
return decodeASCII(bytes);
case "latin1":
case "iso-8859-1":
return decodeLatin1(bytes);
case "windows-1252":
return decodeWindows1252(bytes);
default:
throw new RangeError(`Encoding '${encoding}' not supported`);
}
}
export function textEncode(input = "", encoding = "utf-8") {
switch (encoding.toLowerCase()) {
case "utf-8":
case "utf8":
if (typeof globalThis.TextEncoder !== "undefined") {
return new globalThis.TextEncoder().encode(input);
}
return encodeUTF8(input);
case "utf-16le":
return encodeUTF16LE(input);
case "ascii":
return encodeASCII(input);
case "latin1":
case "iso-8859-1":
return encodeLatin1(input);
case "windows-1252":
return encodeWindows1252(input);
default:
throw new RangeError(`Encoding '${encoding}' not supported`);
}
}
// --- Internal helpers ---
function decodeUTF8(bytes) {
let out = "";
let i = 0;
while (i < bytes.length) {
const b1 = bytes[i++];
if (b1 < 0x80) {
out += String.fromCharCode(b1);
}
else if (b1 < 0xe0) {
const b2 = bytes[i++] & 0x3f;
out += String.fromCharCode(((b1 & 0x1f) << 6) | b2);
}
else if (b1 < 0xf0) {
const b2 = bytes[i++] & 0x3f;
const b3 = bytes[i++] & 0x3f;
out += String.fromCharCode(((b1 & 0x0f) << 12) | (b2 << 6) | b3);
}
else {
const b2 = bytes[i++] & 0x3f;
const b3 = bytes[i++] & 0x3f;
const b4 = bytes[i++] & 0x3f;
let cp = ((b1 & 0x07) << 18) |
(b2 << 12) |
(b3 << 6) |
b4;
cp -= 0x10000;
out += String.fromCharCode(0xd800 + ((cp >> 10) & 0x3ff), 0xdc00 + (cp & 0x3ff));
}
}
return out;
}
function decodeUTF16LE(bytes) {
let out = "";
for (let i = 0; i < bytes.length; i += 2) {
out += String.fromCharCode(bytes[i] | (bytes[i + 1] << 8));
}
return out;
}
function decodeASCII(bytes) {
return String.fromCharCode(...bytes.map((b) => b & 0x7f));
}
function decodeLatin1(bytes) {
return String.fromCharCode(...bytes);
}
function decodeWindows1252(bytes) {
let out = "";
for (const b of bytes) {
if (b >= 0x80 && b <= 0x9f && WINDOWS_1252_EXTRA[b]) {
out += WINDOWS_1252_EXTRA[b];
}
else {
out += String.fromCharCode(b);
}
}
return out;
}
function encodeUTF8(str) {
const out = [];
for (let i = 0; i < str.length; i++) {
const cp = str.charCodeAt(i);
if (cp < 0x80) {
out.push(cp);
}
else if (cp < 0x800) {
out.push(0xc0 | (cp >> 6), 0x80 | (cp & 0x3f));
}
else if (cp < 0x10000) {
out.push(0xe0 | (cp >> 12), 0x80 | ((cp >> 6) & 0x3f), 0x80 | (cp & 0x3f));
}
else {
out.push(0xf0 | (cp >> 18), 0x80 | ((cp >> 12) & 0x3f), 0x80 | ((cp >> 6) & 0x3f), 0x80 | (cp & 0x3f));
}
}
return new Uint8Array(out);
}
function encodeUTF16LE(str) {
const out = new Uint8Array(str.length * 2);
for (let i = 0; i < str.length; i++) {
const code = str.charCodeAt(i);
out[i * 2] = code & 0xff;
out[i * 2 + 1] = code >> 8;
}
return out;
}
function encodeASCII(str) {
return new Uint8Array([...str].map((ch) => ch.charCodeAt(0) & 0x7f));
}
function encodeLatin1(str) {
return new Uint8Array([...str].map((ch) => ch.charCodeAt(0) & 0xff));
}
function encodeWindows1252(str) {
return new Uint8Array([...str].map((ch) => {
const code = ch.charCodeAt(0);
if (code <= 0xff)
return code;
if (WINDOWS_1252_REVERSE[ch] !== undefined)
return WINDOWS_1252_REVERSE[ch];
return 0x3f; // '?'
}));
}