Skip to content

Commit

Permalink
badword.ts
Browse files Browse the repository at this point in the history
  • Loading branch information
LcfherShell authored Oct 13, 2024
1 parent 252a33c commit eb6a82a
Showing 1 changed file with 275 additions and 0 deletions.
275 changes: 275 additions & 0 deletions badword.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,275 @@
function RegexMatch(word: string, regex: RegExp): boolean {
const words = word.trim();
const barisdata: string[] = [];

if (words) {
for (let index = 0; index < words.length; index++) {
const datacocok = barisdata.join("").toLowerCase();

if (datacocok.match(regex)) {
return true;
} else {
let modifiedWord = words[index];

if (modifiedWord.includes("3")) {
modifiedWord = modifiedWord.replace("3", "e");
} else if (modifiedWord.includes("0")) {
modifiedWord = modifiedWord.replace("0", "o");
} else if (modifiedWord.includes("4")) {
modifiedWord = modifiedWord.replace("4", "a");
} else if (modifiedWord.includes("5")) {
modifiedWord = modifiedWord.replace("5", "s");
} else if (modifiedWord.includes("8")) {
modifiedWord = modifiedWord.replace("8", "b");
}

if (datacocok.replace(/1/gi, "i").match(regex) ||
datacocok.replace(/1/gi, "l").match(regex) ||
datacocok.replace(/6/gi, "b").match(regex) ||
datacocok.replace(/6/gi, "g").match(regex)) {
return true;
}
}

barisdata.push(words[index].trim());
}
}

return false;
}

function escapeRegExp(strings: string): string {
const data = strings.trim().toLowerCase().split("|").filter(Boolean);

for (let index = 0; index < data.length; index++) {
const element = data[index];

if (!((element.includes("(") && element.includes(")")) ||
(element.includes("[") && element.includes("]")))) {
data[index] = data[index]
.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')
.replace(/[a4]/g, "[a4]")
.replace(/[s5]/g, "[s5]")
.replace("i", "[i1]")
.replace("l", "[l1]")
.replace(/[o0]/g, "[o0]")
.replace(/[e3]/g, "[e3]")
.replace(/[b8]/g, "[b8]")
.replace(/[kx]/g, "[kx]");
}
}

return new RegExp(data.join("|")).source;
}

function validateInput(type: string, value: string): boolean {
let regex: RegExp;

switch (type) {
case 'email':
regex = /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.(com|net|org|edu|gov|mil|co|info|io|biz|id|us|uk|ca|au|de|fr|es|it|jp|cn|br|in|ru|mx|kr|za|nl|se|no|fi|dk|pl|pt|ar|ch|hk|sg|my|th|vn|ae|at|be|cz|hu|ro|bg|gr|lt|lv|sk|si|ee|cy)(\.[a-zA-Z]{2,})?$/;
break;
case 'phone':
regex = /^(?:\+?(\d{1,3}))?[-. ]?(\(?\d{1,4}?\)?)[-.\s]?(\d{1,4})[-.\s]?(\d{1,4})[-.\s]?(\d{1,9})$/;
break;
case 'url':
regex = /^(https?:\/\/)?(www\.)?([a-zA-Z0-9-]+\.[a-zA-Z]{2,})(\/[^\s]*)?$/;
break;
default:
return false; // Invalid type
}

return regex.test(value);
}

class FilterBadWord {
protected _text: string;
protected _filt: RegExp;
protected _subfilter: RegExp;
protected __subtxic: [string, string][];
protected _st: boolean;

constructor(text: string = "", customFilter: string = "", customSubFilter: string = "") {
this._text = text;
this._filt = /b[a4][s5]hfu[l1][l1]|k[i1][l1][l1]|fuck[*]?|dr[uo]g[*]?|d[i1]ck[*]?|[a4][s5][s5]|[l1][i1]p|pu[s5][s5]y[*]?|fk/gi;
this._subfilter = /[a4][s5][s5]|[l1][i1]p|pu[s5][s5]y[*]?|[s5]uck[*]?|m[o0]th[e3]r[*]?|m[o0]m[*]?|d[o0]g[*]?|l[o0]w[*]?|s[e3]x[*]?/gi;

if (customFilter.length > 3) {
this._filt = new RegExp(this._filt.source + "|" + escapeRegExp(customFilter), "gi");
}

if (customSubFilter.length > 3) {
this._subfilter = new RegExp(this._subfilter.source + "|" + escapeRegExp(customSubFilter), "gi");
}

this.__subtxic = [];
this._st = false;
}

private getBoundPosition(word: string, position: number): string {
let paragraph = word;

while (position > 0 && paragraph[position] === " ") position--;

position = paragraph.lastIndexOf(" ", position) + 1;
let end = paragraph.indexOf(" ", position);

if (end === -1) {
end = paragraph.length;
}

return paragraph.substring(position, end);
}

private positionStatic(word: string, filters: RegExp): number[] {
const wordlist_ = word.toLowerCase().split(' ');
const positions: number[] = [];

wordlist_.forEach((word, index) => {
const pos = index && wordlist_[index - 1].length + positions.length + 1;

if (word.match(filters) || RegexMatch(word, filters)) {
positions.push(pos);
}
});

return positions;
}

public position(): number[] {
return this.positionStatic(this._text.toString(), this._filt);
}

public get thisToxic(): (string | number)[] | false {
const check = this.position();
const arry: (string | number)[] = [];

if (check.length > 0) {
const word = this._text.toLowerCase();
function before_str(number , key){

return word.substring(number, word.indexOf(key));//nomer dan keyword

};

function after_str(w, spec){
let data =word.substring( word.indexOf(w), spec.length+word.length );
return data.replace(w, "").trim(); //, word.indexOf(spec));
};

for (const index of check) {
const word_s = this.getBoundPosition(this._text.toLowerCase(), index);
const before = word.substring(0, word.indexOf(word_s)).trim().split(" ");
const after = word.substring(word.indexOf(word_s) + word_s.length).trim().split(" ");

// Check before
before.forEach(d => {
if (d.match(this._subfilter)) {
this.__subtxic.push([d, '*'.repeat(d.length)]);
}
});

// Check after
after.forEach(d => {
if (d.match(this._subfilter)) {
this.__subtxic.push([d, '*'.repeat(d.length)]);
}
});

// Add toxic word if found in before or after
if (before.length && before[before.length - 1].match(this._subfilter)) {
arry.push("Toxic", 1, before[before.length - 1]);
return arry;
}

if (after.length && after[0].match(this._subfilter)) {
arry.push("Toxic", 1, after[0]);
return arry;
}

if (after.length > 1 && after[1].match(this._subfilter)) {
arry.push("Toxic", 1, after[1]);
return arry;
}
}

arry.push("Notoxic", 0);
return arry;
}

return false;
}

set thisToxic(key: any) {
throw key;
}

public clean(position: number[]): string {
let words = this._text.split(" ");
const sensor = "*";

position.forEach((number) => {
const getWord = this.getBoundPosition(this._text, number);
words = words.map(word => word.replace(getWord, sensor.repeat(getWord.length)));
});
this.__subtxic.forEach(([oldWord, newWord]) => {
words = words.map(word => {
return !(validateInput("email", word) || validateInput("url", word)) && this._st
? word.replace(oldWord, newWord): word;
});
});
return words.join(" ");
}
}

class filters_badword extends FilterBadWord {
protected _cl: boolean;
protected _st: boolean;

public text_o(text: string): void {
this._text = text.toString();
}

public config(cl: boolean = true, smart: boolean = true, customFilter: string = "", customSubFilter: string = ""): void {
this._cl = cl;
this._st = smart;

if (customFilter.length > 3) {
this._filt = new RegExp(this._filt.source + "|" + escapeRegExp(customFilter), "gi");
}
if (customSubFilter.length > 3) {
this._subfilter = new RegExp(this._subfilter.source + "|" + escapeRegExp(customSubFilter), "gi");
}
}

public get cleans(): string {
if (this._cl) {
if (this.thisToxic){
if (this.thisToxic[1] === 1 && this.thisToxic.length > 2) {
return this.clean(this.position());
};
};
return this.clean(this.position());
};
return this._text.trim();
}

set cleans(value: string) {
throw value;
}
}

export {
/**
* FilterBadWord class: class for filtering bad words
*@param {string} text - The text to filter
*@param {string} customFilter - List of bad words
*@param {string} customSubFilter - List of bad sub words
*/
FilterBadWord,
/**
* filters_badword class: a simpler class to filter bad words
* which uses the FilterBadWord class. To use it you have to call the config function
*/
filters_badword
};

0 comments on commit eb6a82a

Please sign in to comment.