bekindprofanityfilter 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CONTRIBUTORS.md +106 -0
- package/LICENSE +22 -0
- package/README.md +1015 -0
- package/allprofanity.config.example.json +35 -0
- package/bin/init.js +49 -0
- package/config.schema.json +163 -0
- package/dist/algos/aho-corasick.d.ts +75 -0
- package/dist/algos/aho-corasick.js +238 -0
- package/dist/algos/aho-corasick.js.map +1 -0
- package/dist/algos/bloom-filter.d.ts +103 -0
- package/dist/algos/bloom-filter.js +208 -0
- package/dist/algos/bloom-filter.js.map +1 -0
- package/dist/algos/context-patterns.d.ts +102 -0
- package/dist/algos/context-patterns.js +484 -0
- package/dist/algos/context-patterns.js.map +1 -0
- package/dist/index.d.ts +1332 -0
- package/dist/index.js +2631 -0
- package/dist/index.js.map +1 -0
- package/dist/innocence-scoring.d.ts +23 -0
- package/dist/innocence-scoring.js +118 -0
- package/dist/innocence-scoring.js.map +1 -0
- package/dist/language-detector.d.ts +162 -0
- package/dist/language-detector.js +952 -0
- package/dist/language-detector.js.map +1 -0
- package/dist/language-dicts.d.ts +60 -0
- package/dist/language-dicts.js +2718 -0
- package/dist/language-dicts.js.map +1 -0
- package/dist/languages/arabic-words.d.ts +10 -0
- package/dist/languages/arabic-words.js +1649 -0
- package/dist/languages/arabic-words.js.map +1 -0
- package/dist/languages/bengali-words.d.ts +10 -0
- package/dist/languages/bengali-words.js +1696 -0
- package/dist/languages/bengali-words.js.map +1 -0
- package/dist/languages/brazilian-words.d.ts +10 -0
- package/dist/languages/brazilian-words.js +2122 -0
- package/dist/languages/brazilian-words.js.map +1 -0
- package/dist/languages/chinese-words.d.ts +10 -0
- package/dist/languages/chinese-words.js +2728 -0
- package/dist/languages/chinese-words.js.map +1 -0
- package/dist/languages/english-primary-all-languages.d.ts +23 -0
- package/dist/languages/english-primary-all-languages.js +36894 -0
- package/dist/languages/english-primary-all-languages.js.map +1 -0
- package/dist/languages/english-words.d.ts +5 -0
- package/dist/languages/english-words.js +5156 -0
- package/dist/languages/english-words.js.map +1 -0
- package/dist/languages/french-words.d.ts +10 -0
- package/dist/languages/french-words.js +2326 -0
- package/dist/languages/french-words.js.map +1 -0
- package/dist/languages/german-words.d.ts +10 -0
- package/dist/languages/german-words.js +2633 -0
- package/dist/languages/german-words.js.map +1 -0
- package/dist/languages/hindi-words.d.ts +10 -0
- package/dist/languages/hindi-words.js +2341 -0
- package/dist/languages/hindi-words.js.map +1 -0
- package/dist/languages/innocent-words.d.ts +41 -0
- package/dist/languages/innocent-words.js +109 -0
- package/dist/languages/innocent-words.js.map +1 -0
- package/dist/languages/italian-words.d.ts +10 -0
- package/dist/languages/italian-words.js +2287 -0
- package/dist/languages/italian-words.js.map +1 -0
- package/dist/languages/japanese-words.d.ts +11 -0
- package/dist/languages/japanese-words.js +2557 -0
- package/dist/languages/japanese-words.js.map +1 -0
- package/dist/languages/korean-words.d.ts +10 -0
- package/dist/languages/korean-words.js +2509 -0
- package/dist/languages/korean-words.js.map +1 -0
- package/dist/languages/russian-words.d.ts +10 -0
- package/dist/languages/russian-words.js +2175 -0
- package/dist/languages/russian-words.js.map +1 -0
- package/dist/languages/spanish-words.d.ts +11 -0
- package/dist/languages/spanish-words.js +2536 -0
- package/dist/languages/spanish-words.js.map +1 -0
- package/dist/languages/tamil-words.d.ts +10 -0
- package/dist/languages/tamil-words.js +1722 -0
- package/dist/languages/tamil-words.js.map +1 -0
- package/dist/languages/telugu-words.d.ts +10 -0
- package/dist/languages/telugu-words.js +1739 -0
- package/dist/languages/telugu-words.js.map +1 -0
- package/dist/romanization-detector.d.ts +50 -0
- package/dist/romanization-detector.js +779 -0
- package/dist/romanization-detector.js.map +1 -0
- package/package.json +79 -0
|
@@ -0,0 +1,484 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Universal context patterns for multi-language profanity detection
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* Universal context patterns that work across multiple languages
|
|
6
|
+
*/
|
|
7
|
+
export const UNIVERSAL_CONTEXT_PATTERNS = [
|
|
8
|
+
// === REDUCER PATTERNS ===
|
|
9
|
+
// Negation patterns
|
|
10
|
+
{
|
|
11
|
+
type: "negation",
|
|
12
|
+
pattern: /\b(not|don't|won't|can't|never|ne|pas|nicht|no|नहीं|不|non|niente|нет|nie)\b.{0,30}PROFANE_WORD/i,
|
|
13
|
+
weight: 0.2,
|
|
14
|
+
delta: -2,
|
|
15
|
+
languages: ["*"],
|
|
16
|
+
description: "Negation words that reduce profanity likelihood",
|
|
17
|
+
examples: ["not bad", "don't call me that", "never say that"],
|
|
18
|
+
},
|
|
19
|
+
// Possessive patterns
|
|
20
|
+
{
|
|
21
|
+
type: "possessive",
|
|
22
|
+
pattern: /\b\w+(['s]|du|de|का|की|के|の|del|della|от|od)\s+PROFANE_WORD\b/i,
|
|
23
|
+
weight: 0.4,
|
|
24
|
+
delta: -1,
|
|
25
|
+
languages: ["*"],
|
|
26
|
+
description: "Possessive constructions that may be innocent",
|
|
27
|
+
examples: ["dog's mouth", "cat's ass", "bird's ass"],
|
|
28
|
+
},
|
|
29
|
+
// Article patterns
|
|
30
|
+
{
|
|
31
|
+
type: "article",
|
|
32
|
+
pattern: /\b(the|a|an|le|la|les|un|une|der|die|das|ein|eine|el|la|los|las|il|lo|gli|le)\s+PROFANE_WORD\b/i,
|
|
33
|
+
weight: 0.6,
|
|
34
|
+
delta: -1,
|
|
35
|
+
languages: ["*"],
|
|
36
|
+
description: "Articles that may indicate neutral reference",
|
|
37
|
+
examples: ["the ass of the donkey", "a hell of a time"],
|
|
38
|
+
},
|
|
39
|
+
// Compound word patterns
|
|
40
|
+
{
|
|
41
|
+
type: "compound",
|
|
42
|
+
pattern: /\b(smart|silly|cute|funny|little|big|old|new|good|bad|nice|sweet)\s*[-]?\s*PROFANE_WORD\b/i,
|
|
43
|
+
weight: 0.5,
|
|
44
|
+
delta: -1,
|
|
45
|
+
languages: ["*"],
|
|
46
|
+
description: "Adjective-noun compounds that may be innocent",
|
|
47
|
+
examples: ["smart-ass", "silly ass", "cute little ass"],
|
|
48
|
+
},
|
|
49
|
+
// Proper noun patterns
|
|
50
|
+
{
|
|
51
|
+
type: "proper_noun",
|
|
52
|
+
pattern: /\b[A-Z][a-z]+\s+PROFANE_WORD\b/,
|
|
53
|
+
weight: 0.3,
|
|
54
|
+
delta: -2,
|
|
55
|
+
languages: ["en", "fr", "de", "es", "it"],
|
|
56
|
+
description: "Proper nouns followed by potential profanity",
|
|
57
|
+
examples: ["Hell Michigan", "Ass River"],
|
|
58
|
+
},
|
|
59
|
+
// Quotation patterns
|
|
60
|
+
{
|
|
61
|
+
type: "quotation",
|
|
62
|
+
pattern: /["'«»„"‚'].*PROFANE_WORD.*["'«»„"‚']/i,
|
|
63
|
+
weight: 0.7,
|
|
64
|
+
delta: -2,
|
|
65
|
+
languages: ["*"],
|
|
66
|
+
description: "Quoted text which may be reporting speech",
|
|
67
|
+
examples: ['"Don\'t be an ass"', "'What the hell'"],
|
|
68
|
+
},
|
|
69
|
+
// Medical/anatomical context
|
|
70
|
+
{
|
|
71
|
+
type: "medical",
|
|
72
|
+
pattern: /\b(medical|anatomy|doctor|hospital|clinic|patient|diagnosis|treatment|surgical|clinical)\b.{0,50}PROFANE_WORD/i,
|
|
73
|
+
weight: 0.1,
|
|
74
|
+
delta: -3,
|
|
75
|
+
languages: ["*"],
|
|
76
|
+
description: "Medical contexts where anatomical terms are appropriate",
|
|
77
|
+
examples: [
|
|
78
|
+
"medical examination of the ass",
|
|
79
|
+
"doctor checked the damn thing",
|
|
80
|
+
],
|
|
81
|
+
},
|
|
82
|
+
// Anatomical context
|
|
83
|
+
{
|
|
84
|
+
type: "anatomical",
|
|
85
|
+
pattern: /\b(body|part|muscle|bone|skin|tissue|organ|limb|extremity)\b.{0,30}PROFANE_WORD/i,
|
|
86
|
+
weight: 0.3,
|
|
87
|
+
delta: -2,
|
|
88
|
+
languages: ["*"],
|
|
89
|
+
description: "Anatomical contexts for body parts",
|
|
90
|
+
examples: ["body part called ass", "muscle in the ass"],
|
|
91
|
+
},
|
|
92
|
+
// === BOOSTER PATTERNS ===
|
|
93
|
+
{
|
|
94
|
+
type: "sexual_verb_before",
|
|
95
|
+
pattern: /\b(suck|ride|lick|grab|stroke|jerk|squirt|bang|blow|pound|hump|grind|fondle|grope|spank|thrust|mount|penetrate|finger|fist|step|stomp|foot)\b.{0,10}PROFANE_WORD/i,
|
|
96
|
+
weight: 2.0,
|
|
97
|
+
delta: 3,
|
|
98
|
+
languages: ["*"],
|
|
99
|
+
description: "Sexual verb before target word — confirms profane intent",
|
|
100
|
+
examples: ["suck my cock", "ride that dick", "jerk that dick", "stomp on my"],
|
|
101
|
+
},
|
|
102
|
+
{
|
|
103
|
+
type: "sexual_verb_after",
|
|
104
|
+
pattern: /PROFANE_WORD.{0,10}\b(suck|ride|lick|grab|stroke|jerk|squirt|bang|blow|pound|hump|grind|fondle|grope|spank|thrust|mount|penetrate|finger|fist|step|stomp|foot|sucking|riding|licking|grabbing|stroking|jerking|squirting|banging|blowing|pounding|humping|grinding|fondling|groping|spanking|thrusting|mounting|penetrating|fingering|fisting|stepping|stomping|footing)\b/i,
|
|
105
|
+
weight: 2.0,
|
|
106
|
+
delta: 3,
|
|
107
|
+
languages: ["*"],
|
|
108
|
+
description: "Sexual verb after target word — confirms profane intent",
|
|
109
|
+
examples: ["cock sucking", "dick riding", "ass pounding"],
|
|
110
|
+
},
|
|
111
|
+
{
|
|
112
|
+
type: "compound_slur",
|
|
113
|
+
pattern: /PROFANE_WORD.{0,10}(hole|face|head|wipe|bag|job)\b/i,
|
|
114
|
+
weight: 2.0,
|
|
115
|
+
delta: 3,
|
|
116
|
+
languages: ["*"],
|
|
117
|
+
description: "Compound slur suffix — confirms profane intent (no \\b before suffix to match compounds like 'asshole')",
|
|
118
|
+
examples: ["asshole", "dickhead", "dickface"],
|
|
119
|
+
},
|
|
120
|
+
{
|
|
121
|
+
type: "insult_construction",
|
|
122
|
+
pattern: /\b(piece of|load of|full of)\s.{0,5}PROFANE_WORD/i,
|
|
123
|
+
weight: 1.4,
|
|
124
|
+
delta: 2,
|
|
125
|
+
languages: ["*"],
|
|
126
|
+
description: "Insult construction — likely profane",
|
|
127
|
+
examples: ["piece of ass", "load of cock"],
|
|
128
|
+
},
|
|
129
|
+
{
|
|
130
|
+
type: "direct_address",
|
|
131
|
+
pattern: /\b(you|your|u|ur)\b.{0,10}PROFANE_WORD/i,
|
|
132
|
+
weight: 1.3,
|
|
133
|
+
delta: 1,
|
|
134
|
+
languages: ["*"],
|
|
135
|
+
description: "Direct address — likely insult",
|
|
136
|
+
examples: ["you dick", "your ass"],
|
|
137
|
+
},
|
|
138
|
+
{
|
|
139
|
+
type: "pejorative_adj",
|
|
140
|
+
pattern: /\b(stupid|ugly|fat|dumb|dirty|nasty|filthy)\b.{0,10}PROFANE_WORD/i,
|
|
141
|
+
weight: 1.3,
|
|
142
|
+
delta: 1,
|
|
143
|
+
languages: ["*"],
|
|
144
|
+
description: "Pejorative adjective before target — likely profane",
|
|
145
|
+
examples: ["stupid ass", "fat dick", "dirty cock"],
|
|
146
|
+
},
|
|
147
|
+
];
|
|
148
|
+
/**
|
|
149
|
+
* Language-specific context patterns
|
|
150
|
+
*/
|
|
151
|
+
export const LANGUAGE_SPECIFIC_PATTERNS = {
|
|
152
|
+
en: [
|
|
153
|
+
{
|
|
154
|
+
type: "compound",
|
|
155
|
+
pattern: /\b(jack|dumb|smart|bad|kick)\s*[-]?\s*PROFANE_WORD\b/i,
|
|
156
|
+
weight: 0.4,
|
|
157
|
+
delta: -1,
|
|
158
|
+
languages: ["en"],
|
|
159
|
+
description: "English-specific compound patterns",
|
|
160
|
+
examples: ["jackass", "dumbass", "badass"],
|
|
161
|
+
},
|
|
162
|
+
],
|
|
163
|
+
fr: [
|
|
164
|
+
{
|
|
165
|
+
type: "negation",
|
|
166
|
+
pattern: /\b(ne|n'|pas|point|jamais|rien|personne)\b.{0,30}PROFANE_WORD/i,
|
|
167
|
+
weight: 0.2,
|
|
168
|
+
delta: -2,
|
|
169
|
+
languages: ["fr"],
|
|
170
|
+
description: "French negation patterns",
|
|
171
|
+
examples: ["ne pas dire", "jamais ça"],
|
|
172
|
+
},
|
|
173
|
+
],
|
|
174
|
+
de: [
|
|
175
|
+
{
|
|
176
|
+
type: "compound",
|
|
177
|
+
pattern: /\bPROFANE_WORD(kopf|zeug|ding|sache)\b/i,
|
|
178
|
+
weight: 0.5,
|
|
179
|
+
delta: -1,
|
|
180
|
+
languages: ["de"],
|
|
181
|
+
description: "German compound word patterns",
|
|
182
|
+
examples: ["Scheißzeug", "Arschloch"],
|
|
183
|
+
},
|
|
184
|
+
],
|
|
185
|
+
es: [
|
|
186
|
+
{
|
|
187
|
+
type: "possessive",
|
|
188
|
+
pattern: /\b(el|la|los|las)\s+PROFANE_WORD\s+(de|del|de la)\b/i,
|
|
189
|
+
weight: 0.4,
|
|
190
|
+
delta: -1,
|
|
191
|
+
languages: ["es"],
|
|
192
|
+
description: "Spanish possessive patterns",
|
|
193
|
+
examples: ["el culo de la mesa"],
|
|
194
|
+
},
|
|
195
|
+
],
|
|
196
|
+
};
|
|
197
|
+
/**
|
|
198
|
+
* Word-specific context patterns for disambiguating ambiguous profane words.
|
|
199
|
+
* Keyed by the lowercase profane word.
|
|
200
|
+
*/
|
|
201
|
+
export const WORD_SPECIFIC_PATTERNS = {
|
|
202
|
+
cock: [
|
|
203
|
+
{
|
|
204
|
+
type: "sexual_verb_before",
|
|
205
|
+
pattern: /\b(big|hard|small|my|his)\b.{0,10}PROFANE_WORD/i,
|
|
206
|
+
weight: 1.5,
|
|
207
|
+
delta: 2,
|
|
208
|
+
languages: ["*"],
|
|
209
|
+
description: "Sexual/possessive context for cock",
|
|
210
|
+
examples: ["big cock", "my cock", "his hard cock"],
|
|
211
|
+
},
|
|
212
|
+
{
|
|
213
|
+
type: "compound",
|
|
214
|
+
pattern: /\b(crow|rooster|hen|farm|chicken|dawn|poultry|barnyard)\b.{0,30}PROFANE_WORD/i,
|
|
215
|
+
weight: 0.1,
|
|
216
|
+
delta: -3,
|
|
217
|
+
languages: ["*"],
|
|
218
|
+
description: "Farming/zoological context — cock as rooster",
|
|
219
|
+
examples: ["the cock crowed at dawn", "rooster and cock"],
|
|
220
|
+
},
|
|
221
|
+
{
|
|
222
|
+
type: "compound",
|
|
223
|
+
pattern: /PROFANE_WORD.{0,30}\b(crow|crowed|rooster|hen|farm|chicken|dawn|poultry|barnyard)\b/i,
|
|
224
|
+
weight: 0.1,
|
|
225
|
+
delta: -3,
|
|
226
|
+
languages: ["*"],
|
|
227
|
+
description: "Farming/zoological context after — cock as rooster",
|
|
228
|
+
examples: ["cock crowed at dawn", "cock and hen"],
|
|
229
|
+
},
|
|
230
|
+
],
|
|
231
|
+
ass: [
|
|
232
|
+
{
|
|
233
|
+
type: "pejorative_adj",
|
|
234
|
+
pattern: /\b(fat|kick|dumb|lazy)\b.{0,10}PROFANE_WORD/i,
|
|
235
|
+
weight: 1.4,
|
|
236
|
+
delta: 2,
|
|
237
|
+
languages: ["*"],
|
|
238
|
+
description: "Insult context for ass",
|
|
239
|
+
examples: ["fat ass", "dumb ass", "kick your ass"],
|
|
240
|
+
},
|
|
241
|
+
{
|
|
242
|
+
type: "compound",
|
|
243
|
+
pattern: /\b(donkey|mule|equine|wild|herd|saddle|burro)\b.{0,30}PROFANE_WORD/i,
|
|
244
|
+
weight: 0.1,
|
|
245
|
+
delta: -3,
|
|
246
|
+
languages: ["*"],
|
|
247
|
+
description: "Zoological context — ass as donkey",
|
|
248
|
+
examples: ["wild ass", "the donkey or ass"],
|
|
249
|
+
},
|
|
250
|
+
{
|
|
251
|
+
type: "compound",
|
|
252
|
+
pattern: /PROFANE_WORD.{0,30}\b(donkey|mule|equine|herd|saddle|burro)\b/i,
|
|
253
|
+
weight: 0.1,
|
|
254
|
+
delta: -3,
|
|
255
|
+
languages: ["*"],
|
|
256
|
+
description: "Zoological context after — ass as donkey",
|
|
257
|
+
examples: ["ass is a species of equine"],
|
|
258
|
+
},
|
|
259
|
+
],
|
|
260
|
+
dick: [
|
|
261
|
+
{
|
|
262
|
+
type: "sexual_verb_before",
|
|
263
|
+
pattern: /\b(big|small|my|his)\b.{0,10}PROFANE_WORD/i,
|
|
264
|
+
weight: 1.5,
|
|
265
|
+
delta: 2,
|
|
266
|
+
languages: ["*"],
|
|
267
|
+
description: "Sexual/possessive context for dick",
|
|
268
|
+
examples: ["big dick", "my dick"],
|
|
269
|
+
},
|
|
270
|
+
{
|
|
271
|
+
// Case-sensitive: matches "Dick Cheney" but not "dick cheney"
|
|
272
|
+
// Works because getCertaintyDelta tests against original (non-normalized) text
|
|
273
|
+
type: "proper_noun",
|
|
274
|
+
pattern: /\bDick\s+[A-Z][a-z]+/,
|
|
275
|
+
weight: 0.1,
|
|
276
|
+
delta: -3,
|
|
277
|
+
languages: ["en"],
|
|
278
|
+
description: "Dick as proper name followed by surname",
|
|
279
|
+
examples: ["Dick Cheney", "Dick Van Dyke"],
|
|
280
|
+
},
|
|
281
|
+
],
|
|
282
|
+
};
|
|
283
|
+
/**
|
|
284
|
+
* Context rule generator
|
|
285
|
+
*/
|
|
286
|
+
export class ContextPatternMatcher {
|
|
287
|
+
constructor(languages = ["en"]) {
|
|
288
|
+
this.patterns = [...UNIVERSAL_CONTEXT_PATTERNS];
|
|
289
|
+
this.languagePatterns = new Map();
|
|
290
|
+
// Load language-specific patterns
|
|
291
|
+
for (const lang of languages) {
|
|
292
|
+
if (LANGUAGE_SPECIFIC_PATTERNS[lang]) {
|
|
293
|
+
this.languagePatterns.set(lang, LANGUAGE_SPECIFIC_PATTERNS[lang]);
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
/**
|
|
298
|
+
* Generate context rules for a specific word
|
|
299
|
+
*/
|
|
300
|
+
generateRules(word, languages = ["en"]) {
|
|
301
|
+
const rules = [];
|
|
302
|
+
const allPatterns = [...this.patterns];
|
|
303
|
+
// Add language-specific patterns
|
|
304
|
+
for (const lang of languages) {
|
|
305
|
+
const langPatterns = this.languagePatterns.get(lang) || [];
|
|
306
|
+
allPatterns.push(...langPatterns);
|
|
307
|
+
}
|
|
308
|
+
// Add word-specific patterns
|
|
309
|
+
const wordPatterns = WORD_SPECIFIC_PATTERNS[word.toLowerCase()];
|
|
310
|
+
if (wordPatterns) {
|
|
311
|
+
allPatterns.push(...wordPatterns);
|
|
312
|
+
}
|
|
313
|
+
for (const pattern of allPatterns) {
|
|
314
|
+
// Skip if pattern doesn't apply to any of the specified languages
|
|
315
|
+
if (!pattern.languages.includes("*") &&
|
|
316
|
+
!pattern.languages.some((lang) => languages.includes(lang))) {
|
|
317
|
+
continue;
|
|
318
|
+
}
|
|
319
|
+
// Replace PROFANE_WORD placeholder with actual word
|
|
320
|
+
const regexSource = pattern.pattern.source.replace("PROFANE_WORD", this.escapeRegex(word));
|
|
321
|
+
const regex = new RegExp(regexSource, pattern.pattern.flags);
|
|
322
|
+
let action;
|
|
323
|
+
if (pattern.weight < 0.3) {
|
|
324
|
+
action = "reduce_score";
|
|
325
|
+
}
|
|
326
|
+
else if (pattern.weight > 0.8) {
|
|
327
|
+
action = "increase_score";
|
|
328
|
+
}
|
|
329
|
+
else {
|
|
330
|
+
action = "reduce_score";
|
|
331
|
+
}
|
|
332
|
+
rules.push({
|
|
333
|
+
pattern: regex,
|
|
334
|
+
action,
|
|
335
|
+
weight: pattern.weight,
|
|
336
|
+
delta: pattern.delta,
|
|
337
|
+
priority: this.getPriority(pattern.type),
|
|
338
|
+
});
|
|
339
|
+
}
|
|
340
|
+
return rules.sort((a, b) => a.priority - b.priority);
|
|
341
|
+
}
|
|
342
|
+
/**
|
|
343
|
+
* Get priority for pattern type (reducers before boosters)
|
|
344
|
+
*/
|
|
345
|
+
getPriority(type) {
|
|
346
|
+
const priorities = {
|
|
347
|
+
medical: 1,
|
|
348
|
+
anatomical: 2,
|
|
349
|
+
negation: 3,
|
|
350
|
+
quotation: 4,
|
|
351
|
+
proper_noun: 5,
|
|
352
|
+
possessive: 6,
|
|
353
|
+
article: 7,
|
|
354
|
+
compound: 8,
|
|
355
|
+
// Boosters after reducers
|
|
356
|
+
pejorative_adj: 10,
|
|
357
|
+
direct_address: 11,
|
|
358
|
+
insult_construction: 12,
|
|
359
|
+
compound_slur: 13,
|
|
360
|
+
sexual_verb_before: 14,
|
|
361
|
+
sexual_verb_after: 15,
|
|
362
|
+
};
|
|
363
|
+
return priorities[type] || 9;
|
|
364
|
+
}
|
|
365
|
+
/**
|
|
366
|
+
* Escape regex special characters
|
|
367
|
+
*/
|
|
368
|
+
escapeRegex(str) {
|
|
369
|
+
return str.replace(/[\\^$.*+?()[\]{}|]/g, "\\$&");
|
|
370
|
+
}
|
|
371
|
+
/**
|
|
372
|
+
* Add custom pattern
|
|
373
|
+
*/
|
|
374
|
+
addPattern(pattern) {
|
|
375
|
+
this.patterns.push(pattern);
|
|
376
|
+
}
|
|
377
|
+
/**
|
|
378
|
+
* Add language-specific pattern
|
|
379
|
+
*/
|
|
380
|
+
addLanguagePattern(language, pattern) {
|
|
381
|
+
if (!this.languagePatterns.has(language)) {
|
|
382
|
+
this.languagePatterns.set(language, []);
|
|
383
|
+
}
|
|
384
|
+
this.languagePatterns.get(language).push(pattern);
|
|
385
|
+
}
|
|
386
|
+
/**
|
|
387
|
+
* Get all patterns for debugging
|
|
388
|
+
*/
|
|
389
|
+
getAllPatterns() {
|
|
390
|
+
return {
|
|
391
|
+
universal: [...this.patterns],
|
|
392
|
+
languageSpecific: new Map(this.languagePatterns),
|
|
393
|
+
};
|
|
394
|
+
}
|
|
395
|
+
}
|
|
396
|
+
/**
|
|
397
|
+
* Context analyzer for scoring matches
|
|
398
|
+
*/
|
|
399
|
+
export class ContextAnalyzer {
|
|
400
|
+
constructor(languages = ["en"]) {
|
|
401
|
+
this.contextWindow = 50; // Characters before and after the match
|
|
402
|
+
this.patternMatcher = new ContextPatternMatcher(languages);
|
|
403
|
+
}
|
|
404
|
+
/**
|
|
405
|
+
* Analyze context around a potential profanity match (legacy score-based model)
|
|
406
|
+
*/
|
|
407
|
+
analyzeContext(text, matchStart, matchEnd, word) {
|
|
408
|
+
// Extract context window
|
|
409
|
+
const contextStart = Math.max(0, matchStart - this.contextWindow);
|
|
410
|
+
const contextEnd = Math.min(text.length, matchEnd + this.contextWindow);
|
|
411
|
+
const context = text.substring(contextStart, contextEnd);
|
|
412
|
+
// Get rules for this word
|
|
413
|
+
const rules = this.patternMatcher.generateRules(word);
|
|
414
|
+
let score = 1.0; // Start with full profanity score
|
|
415
|
+
const appliedRules = [];
|
|
416
|
+
// Apply context rules
|
|
417
|
+
for (const rule of rules) {
|
|
418
|
+
const matched = rule.pattern.test(context);
|
|
419
|
+
appliedRules.push({ rule, matched });
|
|
420
|
+
if (matched) {
|
|
421
|
+
if (rule.action === "reduce_score") {
|
|
422
|
+
score *= rule.weight;
|
|
423
|
+
}
|
|
424
|
+
else if (rule.action === "increase_score") {
|
|
425
|
+
score *= 2 - rule.weight; // Increase score
|
|
426
|
+
}
|
|
427
|
+
else if (rule.action === "whitelist") {
|
|
428
|
+
score = 0; // Complete whitelist
|
|
429
|
+
break;
|
|
430
|
+
}
|
|
431
|
+
}
|
|
432
|
+
}
|
|
433
|
+
// Determine confidence based on number of matching rules
|
|
434
|
+
const matchingRules = appliedRules.filter((ar) => ar.matched).length;
|
|
435
|
+
let confidence;
|
|
436
|
+
if (matchingRules === 0) {
|
|
437
|
+
confidence = "high"; // No context rules matched, likely profanity
|
|
438
|
+
}
|
|
439
|
+
else if (matchingRules <= 2) {
|
|
440
|
+
confidence = "medium";
|
|
441
|
+
}
|
|
442
|
+
else {
|
|
443
|
+
confidence = "low"; // Many context rules matched, likely innocent
|
|
444
|
+
}
|
|
445
|
+
return {
|
|
446
|
+
score: Math.max(0, Math.min(1, score)),
|
|
447
|
+
confidence,
|
|
448
|
+
appliedRules,
|
|
449
|
+
context,
|
|
450
|
+
};
|
|
451
|
+
}
|
|
452
|
+
/**
|
|
453
|
+
* Calculate the certainty delta for a word based on surrounding context.
|
|
454
|
+
* Positive delta = booster (more likely profane).
|
|
455
|
+
* Negative delta = reducer (more likely innocent).
|
|
456
|
+
* Returns the sum of all matching pattern deltas.
|
|
457
|
+
*/
|
|
458
|
+
getCertaintyDelta(text, matchStart, matchEnd, word) {
|
|
459
|
+
const contextStart = Math.max(0, matchStart - this.contextWindow);
|
|
460
|
+
const contextEnd = Math.min(text.length, matchEnd + this.contextWindow);
|
|
461
|
+
const context = text.substring(contextStart, contextEnd);
|
|
462
|
+
const rules = this.patternMatcher.generateRules(word);
|
|
463
|
+
let totalDelta = 0;
|
|
464
|
+
for (const rule of rules) {
|
|
465
|
+
if (rule.pattern.test(context)) {
|
|
466
|
+
totalDelta += rule.delta;
|
|
467
|
+
}
|
|
468
|
+
}
|
|
469
|
+
return totalDelta;
|
|
470
|
+
}
|
|
471
|
+
/**
|
|
472
|
+
* Set context window size
|
|
473
|
+
*/
|
|
474
|
+
setContextWindow(size) {
|
|
475
|
+
this.contextWindow = Math.max(10, Math.min(200, size));
|
|
476
|
+
}
|
|
477
|
+
/**
|
|
478
|
+
* Add custom pattern to the analyzer
|
|
479
|
+
*/
|
|
480
|
+
addCustomPattern(pattern) {
|
|
481
|
+
this.patternMatcher.addPattern(pattern);
|
|
482
|
+
}
|
|
483
|
+
}
|
|
484
|
+
//# sourceMappingURL=context-patterns.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"context-patterns.js","sourceRoot":"","sources":["../../src/algos/context-patterns.ts"],"names":[],"mappings":"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"}
|