2025-08-18 20:00:58 +02:00
|
|
|
/**
|
|
|
|
|
* Zalgo Text Generator
|
|
|
|
|
* Generates corrupted/glitched text using Unicode combining characters
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
/* exported ZalgoGenerator */
|
2025-08-18 20:14:45 +02:00
|
|
|
/* eslint-disable-next-line no-unused-vars */
|
2025-08-18 20:00:58 +02:00
|
|
|
|
|
|
|
|
class ZalgoGenerator {
|
|
|
|
|
constructor() {
|
|
|
|
|
// Combining diacritical marks that appear above characters
|
|
|
|
|
this.above = [
|
|
|
|
|
'\u0300',
|
|
|
|
|
'\u0301',
|
|
|
|
|
'\u0302',
|
|
|
|
|
'\u0303',
|
|
|
|
|
'\u0304',
|
|
|
|
|
'\u0305',
|
|
|
|
|
'\u0306',
|
|
|
|
|
'\u0307',
|
|
|
|
|
'\u0308',
|
|
|
|
|
'\u0309',
|
|
|
|
|
'\u030A',
|
|
|
|
|
'\u030B',
|
|
|
|
|
'\u030C',
|
|
|
|
|
'\u030D',
|
|
|
|
|
'\u030E',
|
|
|
|
|
'\u030F',
|
|
|
|
|
'\u0310',
|
|
|
|
|
'\u0311',
|
|
|
|
|
'\u0312',
|
|
|
|
|
'\u0313',
|
|
|
|
|
'\u0314',
|
|
|
|
|
'\u0315',
|
|
|
|
|
'\u0316',
|
|
|
|
|
'\u0317',
|
|
|
|
|
'\u0318',
|
|
|
|
|
'\u0319',
|
|
|
|
|
'\u031A',
|
|
|
|
|
'\u031B',
|
|
|
|
|
'\u031C',
|
|
|
|
|
'\u031D',
|
|
|
|
|
'\u031E',
|
|
|
|
|
'\u031F',
|
|
|
|
|
'\u0320',
|
|
|
|
|
'\u0321',
|
|
|
|
|
'\u0322',
|
|
|
|
|
'\u0323',
|
|
|
|
|
'\u0324',
|
|
|
|
|
'\u0325',
|
|
|
|
|
'\u0326',
|
|
|
|
|
'\u0327',
|
|
|
|
|
'\u0328',
|
|
|
|
|
'\u0329',
|
|
|
|
|
'\u032A',
|
|
|
|
|
'\u032B',
|
|
|
|
|
'\u032C',
|
|
|
|
|
'\u032D',
|
|
|
|
|
'\u032E',
|
|
|
|
|
'\u032F',
|
|
|
|
|
'\u0330',
|
|
|
|
|
'\u0331',
|
|
|
|
|
'\u0332',
|
|
|
|
|
'\u0333',
|
|
|
|
|
'\u0334',
|
|
|
|
|
'\u0335',
|
|
|
|
|
'\u0336',
|
|
|
|
|
'\u0337',
|
|
|
|
|
'\u0338',
|
|
|
|
|
'\u0339',
|
|
|
|
|
'\u033A',
|
|
|
|
|
'\u033B',
|
|
|
|
|
'\u033C',
|
|
|
|
|
'\u033D',
|
|
|
|
|
'\u033E',
|
|
|
|
|
'\u033F',
|
|
|
|
|
'\u0340',
|
|
|
|
|
'\u0341',
|
|
|
|
|
'\u0342',
|
|
|
|
|
'\u0343',
|
|
|
|
|
'\u0344',
|
|
|
|
|
'\u0345',
|
|
|
|
|
'\u0346',
|
|
|
|
|
'\u0347',
|
|
|
|
|
'\u0348',
|
|
|
|
|
'\u0349',
|
|
|
|
|
'\u034A',
|
|
|
|
|
'\u034B',
|
|
|
|
|
'\u034C',
|
|
|
|
|
'\u034D',
|
|
|
|
|
'\u034E',
|
|
|
|
|
'\u034F',
|
|
|
|
|
'\u0350',
|
|
|
|
|
'\u0351',
|
|
|
|
|
'\u0352',
|
|
|
|
|
'\u0353',
|
|
|
|
|
'\u0354',
|
|
|
|
|
'\u0355',
|
|
|
|
|
'\u0356',
|
|
|
|
|
'\u0357',
|
|
|
|
|
'\u0358',
|
|
|
|
|
'\u0359',
|
|
|
|
|
'\u035A',
|
|
|
|
|
'\u035B',
|
|
|
|
|
'\u035C',
|
|
|
|
|
'\u035D',
|
|
|
|
|
'\u035E',
|
|
|
|
|
'\u035F',
|
|
|
|
|
'\u0360',
|
|
|
|
|
'\u0361',
|
|
|
|
|
'\u0362',
|
|
|
|
|
'\u0363',
|
|
|
|
|
'\u0364',
|
|
|
|
|
'\u0365',
|
|
|
|
|
'\u0366',
|
|
|
|
|
'\u0367',
|
|
|
|
|
'\u0368',
|
|
|
|
|
'\u0369',
|
|
|
|
|
'\u036A',
|
|
|
|
|
'\u036B',
|
|
|
|
|
'\u036C',
|
|
|
|
|
'\u036D',
|
|
|
|
|
'\u036E',
|
|
|
|
|
'\u036F',
|
|
|
|
|
];
|
|
|
|
|
|
|
|
|
|
// Combining diacritical marks that appear in the middle
|
|
|
|
|
this.middle = [
|
|
|
|
|
'\u0315',
|
|
|
|
|
'\u031B',
|
|
|
|
|
'\u0340',
|
|
|
|
|
'\u0341',
|
|
|
|
|
'\u0358',
|
|
|
|
|
'\u0321',
|
|
|
|
|
'\u0322',
|
|
|
|
|
'\u0327',
|
|
|
|
|
'\u0328',
|
|
|
|
|
'\u0334',
|
|
|
|
|
'\u0335',
|
|
|
|
|
'\u0336',
|
|
|
|
|
'\u034F',
|
|
|
|
|
'\u035C',
|
|
|
|
|
'\u035D',
|
|
|
|
|
'\u035E',
|
|
|
|
|
'\u035F',
|
|
|
|
|
'\u0360',
|
|
|
|
|
'\u0362',
|
|
|
|
|
'\u0338',
|
|
|
|
|
'\u0337',
|
|
|
|
|
'\u0361',
|
|
|
|
|
'\u0489',
|
|
|
|
|
];
|
|
|
|
|
|
|
|
|
|
// Combining diacritical marks that appear below characters
|
|
|
|
|
this.below = [
|
|
|
|
|
'\u0316',
|
|
|
|
|
'\u0317',
|
|
|
|
|
'\u0318',
|
|
|
|
|
'\u0319',
|
|
|
|
|
'\u031C',
|
|
|
|
|
'\u031D',
|
|
|
|
|
'\u031E',
|
|
|
|
|
'\u031F',
|
|
|
|
|
'\u0320',
|
|
|
|
|
'\u0324',
|
|
|
|
|
'\u0325',
|
|
|
|
|
'\u0326',
|
|
|
|
|
'\u0329',
|
|
|
|
|
'\u032A',
|
|
|
|
|
'\u032B',
|
|
|
|
|
'\u032C',
|
|
|
|
|
'\u032D',
|
|
|
|
|
'\u032E',
|
|
|
|
|
'\u032F',
|
|
|
|
|
'\u0330',
|
|
|
|
|
'\u0331',
|
|
|
|
|
'\u0332',
|
|
|
|
|
'\u0333',
|
|
|
|
|
'\u0339',
|
|
|
|
|
'\u033A',
|
|
|
|
|
'\u033B',
|
|
|
|
|
'\u033C',
|
|
|
|
|
'\u0345',
|
|
|
|
|
'\u0347',
|
|
|
|
|
'\u0348',
|
|
|
|
|
'\u0349',
|
|
|
|
|
'\u034D',
|
|
|
|
|
'\u034E',
|
|
|
|
|
'\u0353',
|
|
|
|
|
'\u0354',
|
|
|
|
|
'\u0355',
|
|
|
|
|
'\u0356',
|
|
|
|
|
'\u0359',
|
|
|
|
|
'\u035A',
|
|
|
|
|
'\u0323',
|
|
|
|
|
];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Get a random character from an array
|
|
|
|
|
*/
|
|
|
|
|
randomChar(array) {
|
|
|
|
|
return array[Math.floor(Math.random() * array.length)];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Generate a specified number of random characters from an array
|
|
|
|
|
*/
|
|
|
|
|
randomChars(array, count) {
|
|
|
|
|
let result = '';
|
|
|
|
|
for (let i = 0; i < count; i++) {
|
|
|
|
|
result += this.randomChar(array);
|
|
|
|
|
}
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Generate zalgo text with specified intensity
|
|
|
|
|
* @param {string} text - The input text to corrupt
|
|
|
|
|
* @param {number} intensity - Corruption intensity (1-10)
|
|
|
|
|
* @returns {string} - The corrupted zalgo text
|
|
|
|
|
*/
|
|
|
|
|
generate(text, intensity = 5) {
|
|
|
|
|
if (!text) return '';
|
|
|
|
|
|
|
|
|
|
// Normalize intensity to 1-10 range
|
|
|
|
|
intensity = Math.max(1, Math.min(10, intensity));
|
|
|
|
|
|
|
|
|
|
let result = '';
|
|
|
|
|
|
|
|
|
|
for (let char of text) {
|
|
|
|
|
result += char;
|
|
|
|
|
|
|
|
|
|
// Skip whitespace and newlines
|
|
|
|
|
if (/\s/.test(char)) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Calculate how many combining characters to add based on intensity
|
|
|
|
|
// Higher intensity = more corruption
|
|
|
|
|
const factor = intensity / 10;
|
|
|
|
|
|
|
|
|
|
// Add characters above (0-3 based on intensity)
|
|
|
|
|
const aboveCount = Math.floor(Math.random() * (4 * factor));
|
|
|
|
|
result += this.randomChars(this.above, aboveCount);
|
|
|
|
|
|
|
|
|
|
// Add characters in middle (0-2 based on intensity)
|
|
|
|
|
const middleCount = Math.floor(Math.random() * (3 * factor));
|
|
|
|
|
result += this.randomChars(this.middle, middleCount);
|
|
|
|
|
|
|
|
|
|
// Add characters below (0-3 based on intensity)
|
|
|
|
|
const belowCount = Math.floor(Math.random() * (4 * factor));
|
|
|
|
|
result += this.randomChars(this.below, belowCount);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Remove zalgo corruption from text
|
|
|
|
|
* @param {string} text - The corrupted text
|
|
|
|
|
* @returns {string} - Clean text without combining characters
|
|
|
|
|
*/
|
|
|
|
|
clean(text) {
|
|
|
|
|
// Remove all combining characters (Unicode category Mn)
|
|
|
|
|
return text.replace(/[\u0300-\u036f\u0489]/g, '');
|
|
|
|
|
}
|
|
|
|
|
}
|