@sideid/id-profanity-filter 1.9.5 → 1.10.4
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/.eslintrc.js +30 -2
- package/README.md +272 -9
- package/dist/config/options.d.ts +24 -0
- package/dist/constants/categories/index.d.ts +9 -0
- package/dist/constants/regions/index.d.ts +8 -0
- package/dist/constants/wordList.d.ts +1 -1
- package/dist/core/analyzer.d.ts +1 -1
- package/dist/core/filter.d.ts +1 -1
- package/dist/core/matcher.d.ts +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.esm.js +411 -77
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +412 -76
- package/dist/index.js.map +1 -1
- package/dist/types/index.d.ts +2 -0
- package/dist/utils/similarityUtils.d.ts +25 -0
- package/eslint.config.mjs +40 -0
- package/examples/advanced.ts +120 -0
- package/examples/basic.ts +60 -41
- package/examples/custom-list.ts +140 -0
- package/package.json +2 -2
- package/src/config/options.ts +2 -0
- package/src/constants/regions/general.ts +102 -2
- package/src/constants/regions/jawa.ts +10 -0
- package/src/constants/wordList.ts +21 -14
- package/src/core/analyzer.ts +8 -14
- package/src/core/filter.ts +182 -41
- package/src/core/matcher.ts +131 -61
- package/src/index.ts +34 -15
- package/src/types/index.ts +4 -2
- package/src/utils/regexUtils.ts +0 -1
- package/src/utils/similarityUtils.ts +97 -2
- package/test.js +184 -0
- package/src/constants/categories/index.ts +0 -31
- package/src/constants/regions/index.ts +0 -62
package/.eslintrc.js
CHANGED
|
@@ -1,16 +1,44 @@
|
|
|
1
1
|
module.exports = {
|
|
2
2
|
parser: '@typescript-eslint/parser',
|
|
3
|
-
extends: ['plugin:@typescript-eslint/recommended', 'prettier'],
|
|
4
3
|
parserOptions: {
|
|
5
4
|
ecmaVersion: 2020,
|
|
6
5
|
sourceType: 'module',
|
|
6
|
+
project: './tsconfig.json',
|
|
7
7
|
},
|
|
8
|
+
extends: [
|
|
9
|
+
'eslint:recommended',
|
|
10
|
+
'plugin:@typescript-eslint/recommended',
|
|
11
|
+
'prettier', // Disables ESLint rules that might conflict with Prettier
|
|
12
|
+
],
|
|
13
|
+
plugins: ['@typescript-eslint'],
|
|
8
14
|
env: {
|
|
9
15
|
node: true,
|
|
10
16
|
jest: true,
|
|
11
17
|
},
|
|
12
18
|
rules: {
|
|
19
|
+
// Enforce consistent code style
|
|
13
20
|
'@typescript-eslint/explicit-function-return-type': 'off',
|
|
14
|
-
'@typescript-eslint/no-explicit-any': '
|
|
21
|
+
'@typescript-eslint/no-explicit-any': 'warn',
|
|
22
|
+
'@typescript-eslint/no-unused-vars': ['warn', { argsIgnorePattern: '^_' }],
|
|
23
|
+
|
|
24
|
+
// Allow certain TypeScript patterns
|
|
25
|
+
'@typescript-eslint/no-non-null-assertion': 'off',
|
|
26
|
+
|
|
27
|
+
// General ESLint rules
|
|
28
|
+
'no-console': ['warn', { allow: ['warn', 'error'] }],
|
|
29
|
+
'prefer-const': 'warn',
|
|
30
|
+
'no-var': 'error',
|
|
31
|
+
|
|
32
|
+
// Make sure imports are properly sorted
|
|
33
|
+
'sort-imports': [
|
|
34
|
+
'off',
|
|
35
|
+
{
|
|
36
|
+
ignoreCase: false,
|
|
37
|
+
ignoreDeclarationSort: true,
|
|
38
|
+
ignoreMemberSort: false,
|
|
39
|
+
memberSyntaxSortOrder: ['none', 'all', 'multiple', 'single'],
|
|
40
|
+
},
|
|
41
|
+
],
|
|
15
42
|
},
|
|
43
|
+
ignorePatterns: ['dist/', 'node_modules/', '*.js', '*.d.ts'],
|
|
16
44
|
};
|
package/README.md
CHANGED
|
@@ -12,6 +12,9 @@ Library JavaScript/TypeScript untuk mendeteksi, menyensor, dan menganalisis kata
|
|
|
12
12
|
- ⚠️ **Analisis Konten** - Menganalisis tingkat keparahan dan kategori kata kotor
|
|
13
13
|
- 🔒 **Penyensoran** - Menyensor kata-kata kotor dengan berbagai opsi kustomisasi
|
|
14
14
|
- 🗺️ **Dukungan Bahasa Daerah** - Mencakup kata-kata dari berbagai daerah di Indonesia (Jawa, Sunda, Batak, dll)
|
|
15
|
+
- 🧠 **Deteksi Cerdas** - Mendeteksi variasi ejaan, kata terpisah, dan kesamaan kata
|
|
16
|
+
- 🔠 **Deteksi Levenshtein** - Mendeteksi kata kotor yang dimodifikasi dengan typo atau sengaja disamarkan
|
|
17
|
+
- 🛡️ **Preset** - Preset filter siap pakai untuk berbagai kebutuhan
|
|
15
18
|
- 🔧 **Kustomisasi** - Opsi untuk menambahkan whitelist dan daftar kata kustom
|
|
16
19
|
|
|
17
20
|
## Instalasi
|
|
@@ -42,7 +45,7 @@ console.log(hasProfanity); // Output: true
|
|
|
42
45
|
|
|
43
46
|
// Filter kata kotor (sensorisasi)
|
|
44
47
|
const hasil = filter.filter(teks);
|
|
45
|
-
console.log(hasil.filtered); // Output: "Dasar
|
|
48
|
+
console.log(hasil.filtered); // Output: "Dasar ***** kamu, jangan banyak *****!"
|
|
46
49
|
console.log(hasil.censored); // Output: 2 (jumlah kata yang disensor)
|
|
47
50
|
|
|
48
51
|
// Analisis konten
|
|
@@ -51,6 +54,26 @@ console.log(analisis.severityScore); // Output: 0.65 (contoh skor keparahan)
|
|
|
51
54
|
console.log(analisis.categories); // Output: ["profanity", "insult"]
|
|
52
55
|
```
|
|
53
56
|
|
|
57
|
+
### Menggunakan Preset
|
|
58
|
+
|
|
59
|
+
```typescript
|
|
60
|
+
import IDProfanityFilter from '@sideid/id-profanity-filter';
|
|
61
|
+
|
|
62
|
+
// Buat instance filter dengan preset
|
|
63
|
+
const filter = new IDProfanityFilter();
|
|
64
|
+
filter.usePreset('strict');
|
|
65
|
+
|
|
66
|
+
// Atau dengan opsi tambahan
|
|
67
|
+
filter.usePreset('childSafe', {
|
|
68
|
+
replaceWith: '#',
|
|
69
|
+
useRandomGrawlix: true,
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
const teks = 'Dasar anjing kamu, jangan banyak bacot!';
|
|
73
|
+
const hasil = filter.filter(teks);
|
|
74
|
+
console.log(hasil.filtered); // Output: "Dasar #@$%& kamu, jangan banyak $!@#%!"
|
|
75
|
+
```
|
|
76
|
+
|
|
54
77
|
### Utilitas Langsung
|
|
55
78
|
|
|
56
79
|
Anda juga dapat menggunakan fungsi utilitas langsung tanpa membuat instance:
|
|
@@ -60,7 +83,13 @@ import { idFilter } from '@sideid/id-profanity-filter';
|
|
|
60
83
|
|
|
61
84
|
const teks = 'Dasar anjing kamu, jangan banyak bacot!';
|
|
62
85
|
const hasil = idFilter.filter(teks);
|
|
63
|
-
console.log(hasil.filtered); // Output: "Dasar
|
|
86
|
+
console.log(hasil.filtered); // Output: "Dasar ***** kamu, jangan banyak *****!"
|
|
87
|
+
|
|
88
|
+
// Menggunakan preset dengan API fungsi statis
|
|
89
|
+
const presetResult = idFilter.filter(
|
|
90
|
+
teks,
|
|
91
|
+
idFilter.getPresetOptions('moderate'),
|
|
92
|
+
);
|
|
64
93
|
```
|
|
65
94
|
|
|
66
95
|
## Dokumentasi API
|
|
@@ -103,6 +132,7 @@ Menganalisis teks untuk mendapatkan informasi detail tentang kata kotor yang dit
|
|
|
103
132
|
- `categories`: Kategori kata kotor yang ditemukan
|
|
104
133
|
- `regions`: Daerah asal kata kotor yang ditemukan
|
|
105
134
|
- `severityScore`: Skor keparahan (0-1)
|
|
135
|
+
- `similarWords`: Kata-kata yang mirip dengan kata kotor (jika deteksi kesamaan diaktifkan)
|
|
106
136
|
|
|
107
137
|
##### `batchAnalyze(texts: string[])`
|
|
108
138
|
|
|
@@ -122,6 +152,13 @@ Menganalisis teks dengan konteks di sekitar kata kotor.
|
|
|
122
152
|
|
|
123
153
|
- **Hasil**: Array dari kata kotor dengan konteks di sekitarnya
|
|
124
154
|
|
|
155
|
+
##### `usePreset(presetName: string, additionalOptions?: Partial<FilterOptions>)`
|
|
156
|
+
|
|
157
|
+
Menggunakan preset filter yang telah ditentukan.
|
|
158
|
+
|
|
159
|
+
- **presetName**: Nama preset ('strict', 'moderate', 'light', 'childSafe', dll)
|
|
160
|
+
- **additionalOptions**: Opsi tambahan untuk override preset (opsional)
|
|
161
|
+
|
|
125
162
|
##### `setOptions(options: Partial<FilterOptions>)`
|
|
126
163
|
|
|
127
164
|
Mengubah opsi filter.
|
|
@@ -138,10 +175,34 @@ Menambahkan kata ke whitelist (akan diabaikan dalam filter).
|
|
|
138
175
|
|
|
139
176
|
Menghapus kata dari whitelist.
|
|
140
177
|
|
|
178
|
+
##### `enableIndonesianVariations()`
|
|
179
|
+
|
|
180
|
+
Mengaktifkan deteksi variasi ejaan Bahasa Indonesia.
|
|
181
|
+
|
|
182
|
+
##### `enableSplitWordDetection()`
|
|
183
|
+
|
|
184
|
+
Mengaktifkan deteksi kata yang dipisah.
|
|
185
|
+
|
|
186
|
+
##### `enableSimilarityDetection(threshold: number = 0.8, useLevenshtein: boolean = false, maxLevenshteinDistance: number = 2)`
|
|
187
|
+
|
|
188
|
+
Mengaktifkan deteksi berdasarkan kesamaan kata.
|
|
189
|
+
|
|
190
|
+
- **threshold**: Ambang batas kesamaan (0-1, default: 0.8)
|
|
191
|
+
- **useLevenshtein**: Gunakan algoritma Levenshtein untuk deteksi (default: false)
|
|
192
|
+
- **maxLevenshteinDistance**: Jarak edit maksimum yang diizinkan (default: 2)
|
|
193
|
+
|
|
194
|
+
##### `enableLevenshteinDetection(threshold: number = 0.8, maxDistance: number = 2)`
|
|
195
|
+
|
|
196
|
+
Mengaktifkan deteksi berbasis jarak Levenshtein.
|
|
197
|
+
|
|
198
|
+
- **threshold**: Ambang batas kesamaan (0-1, default: 0.8)
|
|
199
|
+
- **maxDistance**: Jarak edit maksimum yang diizinkan (default: 2)
|
|
200
|
+
|
|
141
201
|
### Opsi Filter
|
|
142
202
|
|
|
143
203
|
```typescript
|
|
144
204
|
interface FilterOptions {
|
|
205
|
+
// Opsi dasar
|
|
145
206
|
wordList?: string[]; // List kata yang ingin difilter
|
|
146
207
|
replaceWith?: string; // Karakter pengganti untuk kata yang disensor
|
|
147
208
|
fullWordCensor?: boolean; // Apakah menyensor seluruh kata atau sebagian
|
|
@@ -151,9 +212,44 @@ interface FilterOptions {
|
|
|
151
212
|
categories?: ProfanityCategory[]; // Kategori kata yang difilter
|
|
152
213
|
regions?: Region[]; // Daerah asal kata yang difilter
|
|
153
214
|
severityThreshold?: number; // Tingkat keparahan minimum (0-1)
|
|
215
|
+
|
|
216
|
+
// Opsi lanjutan
|
|
217
|
+
useRandomGrawlix?: boolean; // Gunakan karakter acak untuk sensor (#@$%&!)
|
|
218
|
+
keepFirstAndLast?: boolean; // Simpan huruf pertama dan terakhir (a***g)
|
|
219
|
+
indonesianVariation?: boolean; // Deteksi variasi ejaan Bahasa Indonesia
|
|
220
|
+
detectSimilarity?: boolean; // Deteksi kata berdasarkan kesamaan
|
|
221
|
+
similarityThreshold?: number; // Ambang batas kesamaan (0-1)
|
|
222
|
+
detectSplit?: boolean; // Deteksi kata yang dipisah (a-n-j-i-n-g)
|
|
223
|
+
useLevenshtein?: boolean; // Gunakan algoritma Levenshtein untuk deteksi kesamaan
|
|
224
|
+
maxLevenshteinDistance?: number; // Jarak edit maksimum untuk deteksi Levenshtein
|
|
154
225
|
}
|
|
155
226
|
```
|
|
156
227
|
|
|
228
|
+
## Preset Filter
|
|
229
|
+
|
|
230
|
+
Library ini menyediakan beberapa preset yang dapat digunakan:
|
|
231
|
+
|
|
232
|
+
### Preset Filter
|
|
233
|
+
|
|
234
|
+
- **strict**: Filter paling ketat, mendeteksi semua jenis kata kotor
|
|
235
|
+
- **moderate**: Filter tingkat menengah, mengabaikan kata-kata dengan tingkat keparahan rendah
|
|
236
|
+
- **light**: Filter ringan, hanya untuk kata-kata paling sensitif
|
|
237
|
+
- **childSafe**: Filter untuk konten anak-anak, sangat ketat
|
|
238
|
+
|
|
239
|
+
### Preset Kategori
|
|
240
|
+
|
|
241
|
+
- **sexual**: Hanya memfilter kata-kata berbau seksual
|
|
242
|
+
- **insults**: Hanya memfilter kata-kata penghinaan
|
|
243
|
+
- **profanity**: Hanya memfilter umpatan umum
|
|
244
|
+
|
|
245
|
+
### Preset Regional
|
|
246
|
+
|
|
247
|
+
- **general**: Hanya memfilter kata-kata umum di Indonesia
|
|
248
|
+
- **jawa**: Hanya memfilter kata-kata dari Jawa
|
|
249
|
+
- **sunda**: Hanya memfilter kata-kata dari Sunda
|
|
250
|
+
- **betawi**: Hanya memfilter kata-kata dari Betawi
|
|
251
|
+
- **batak**: Hanya memfilter kata-kata dari Batak
|
|
252
|
+
|
|
157
253
|
## Contoh Penggunaan Lanjutan
|
|
158
254
|
|
|
159
255
|
### Kustomisasi Opsi Filter
|
|
@@ -166,12 +262,16 @@ const filter = new IDProfanityFilter({
|
|
|
166
262
|
categories: ['sexual', 'slur'], // Hanya filter kategori tertentu
|
|
167
263
|
regions: ['jawa', 'general'], // Hanya filter dari daerah tertentu
|
|
168
264
|
severityThreshold: 0.7, // Hanya filter kata dengan tingkat keparahan ≥ 0.7
|
|
169
|
-
});
|
|
170
265
|
|
|
171
|
-
//
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
266
|
+
// Opsi lanjutan
|
|
267
|
+
useRandomGrawlix: true, // Gunakan #@$%&! sebagai karakter pengganti
|
|
268
|
+
keepFirstAndLast: true, // Simpan huruf pertama dan terakhir (a***g)
|
|
269
|
+
indonesianVariation: true, // Deteksi variasi ejaan Indonesia
|
|
270
|
+
detectSimilarity: true, // Deteksi kata yang mirip
|
|
271
|
+
similarityThreshold: 0.8, // Ambang batas kesamaan
|
|
272
|
+
detectSplit: true, // Deteksi kata yang dipisah
|
|
273
|
+
useLevenshtein: true, // Gunakan algoritma Levenshtein
|
|
274
|
+
maxLevenshteinDistance: 2, // Jarak Levenshtein maksimum
|
|
175
275
|
});
|
|
176
276
|
```
|
|
177
277
|
|
|
@@ -191,6 +291,102 @@ console.log(hasil.filtered);
|
|
|
191
291
|
// Output: "Anjing itu hewan peliharaan yang setia, tidak seperti ******* itu"
|
|
192
292
|
```
|
|
193
293
|
|
|
294
|
+
### Deteksi Variasi Ejaan dan Kata Terpisah
|
|
295
|
+
|
|
296
|
+
```typescript
|
|
297
|
+
// Aktifkan deteksi variasi ejaan dan kata terpisah
|
|
298
|
+
const filter = new IDProfanityFilter({
|
|
299
|
+
indonesianVariation: true,
|
|
300
|
+
detectSplit: true,
|
|
301
|
+
detectLeetSpeak: true,
|
|
302
|
+
});
|
|
303
|
+
|
|
304
|
+
// Uji dengan variasi ejaan
|
|
305
|
+
const teks1 = 'Dasar kamu ini sangat bodoh, benar-benar b0d0h dan b-o-d-o-h!';
|
|
306
|
+
const hasil1 = filter.filter(teks1);
|
|
307
|
+
console.log(hasil1.filtered);
|
|
308
|
+
// Output: "Dasar kamu ini sangat *****, benar-benar ***** dan *********!"
|
|
309
|
+
|
|
310
|
+
// Uji dengan ejaan Indonesia yang berbeda
|
|
311
|
+
const teks2 = 'Dia sangat djail dan djudes dengan temannya';
|
|
312
|
+
const hasil2 = filter.filter(teks2);
|
|
313
|
+
console.log(hasil2.filtered);
|
|
314
|
+
// Output: "Dia sangat ***** dan ****** dengan temannya"
|
|
315
|
+
```
|
|
316
|
+
|
|
317
|
+
### Deteksi Berdasarkan Kesamaan (Similarity Detection)
|
|
318
|
+
|
|
319
|
+
```typescript
|
|
320
|
+
// Aktifkan deteksi kesamaan standar
|
|
321
|
+
const filter = new IDProfanityFilter();
|
|
322
|
+
filter.enableSimilarityDetection(0.75); // Set threshold kesamaan ke 0.75
|
|
323
|
+
|
|
324
|
+
const teks = 'Dia benar-benar anjiing dan gooblok!';
|
|
325
|
+
const analisis = filter.analyze(teks);
|
|
326
|
+
|
|
327
|
+
console.log(analisis.similarWords);
|
|
328
|
+
/* Output:
|
|
329
|
+
[
|
|
330
|
+
{ word: "anjiing", original: "anjing", similarity: 0.83 },
|
|
331
|
+
{ word: "gooblok", original: "goblok", similarity: 0.85 }
|
|
332
|
+
]
|
|
333
|
+
*/
|
|
334
|
+
|
|
335
|
+
const hasil = filter.filter(teks);
|
|
336
|
+
console.log(hasil.filtered);
|
|
337
|
+
// Output: "Dia benar-benar ****** dan *******!"
|
|
338
|
+
```
|
|
339
|
+
|
|
340
|
+
### Deteksi dengan Algoritma Levenshtein Distance
|
|
341
|
+
|
|
342
|
+
```typescript
|
|
343
|
+
// Aktifkan deteksi menggunakan algoritma Levenshtein Distance
|
|
344
|
+
const filter = new IDProfanityFilter();
|
|
345
|
+
filter.enableLevenshteinDetection(0.85, 2);
|
|
346
|
+
// Threshold 0.85, maksimal 2 karakter berbeda
|
|
347
|
+
|
|
348
|
+
const teks = 'Dia benar-benar konntol dan anjiing sekali!';
|
|
349
|
+
const hasil = filter.filter(teks);
|
|
350
|
+
|
|
351
|
+
console.log(hasil.filtered);
|
|
352
|
+
// Output: "Dia benar-benar ******* dan ****** sekali!"
|
|
353
|
+
|
|
354
|
+
// Atau menggunakan opsi langsung:
|
|
355
|
+
const filterCustom = new IDProfanityFilter({
|
|
356
|
+
detectSimilarity: true,
|
|
357
|
+
useLevenshtein: true,
|
|
358
|
+
similarityThreshold: 0.85,
|
|
359
|
+
maxLevenshteinDistance: 2,
|
|
360
|
+
});
|
|
361
|
+
|
|
362
|
+
// Mendeteksi typo atau variasi disengaja
|
|
363
|
+
const teksVariasi = 'kontool kamu kwontol anjiing';
|
|
364
|
+
console.log(filterCustom.filter(teksVariasi).filtered);
|
|
365
|
+
// Output: "******* kamu ******* ******"
|
|
366
|
+
```
|
|
367
|
+
|
|
368
|
+
### Variasi Sensor Kata
|
|
369
|
+
|
|
370
|
+
```typescript
|
|
371
|
+
// Sensor standar (asterisk)
|
|
372
|
+
const filter1 = new IDProfanityFilter();
|
|
373
|
+
console.log(filter1.filter('Dasar anjing kamu!').filtered);
|
|
374
|
+
// Output: "Dasar ***** kamu!"
|
|
375
|
+
|
|
376
|
+
// Sensor dengan grawlix random
|
|
377
|
+
const filter2 = new IDProfanityFilter({ useRandomGrawlix: true });
|
|
378
|
+
console.log(filter2.filter('Dasar anjing kamu!').filtered);
|
|
379
|
+
// Output: "Dasar #@$%& kamu!"
|
|
380
|
+
|
|
381
|
+
// Sensor dengan menyimpan huruf pertama dan terakhir
|
|
382
|
+
const filter3 = new IDProfanityFilter({
|
|
383
|
+
fullWordCensor: false,
|
|
384
|
+
keepFirstAndLast: true,
|
|
385
|
+
});
|
|
386
|
+
console.log(filter3.filter('Dasar anjing kamu!').filtered);
|
|
387
|
+
// Output: "Dasar a***g kamu!"
|
|
388
|
+
```
|
|
389
|
+
|
|
194
390
|
### Analisis Konten Mendalam
|
|
195
391
|
|
|
196
392
|
```typescript
|
|
@@ -217,6 +413,57 @@ console.log(analisis);
|
|
|
217
413
|
*/
|
|
218
414
|
```
|
|
219
415
|
|
|
416
|
+
### Analisis Konteks
|
|
417
|
+
|
|
418
|
+
```typescript
|
|
419
|
+
const filter = new IDProfanityFilter();
|
|
420
|
+
const teks =
|
|
421
|
+
'Saya sangat marah dengan sikapnya, dia benar-benar anjing dan bajingan!';
|
|
422
|
+
|
|
423
|
+
// Analisis konteks
|
|
424
|
+
const konteks = filter.analyzeWithContext(teks, 3);
|
|
425
|
+
console.log(konteks);
|
|
426
|
+
|
|
427
|
+
/* Output:
|
|
428
|
+
[
|
|
429
|
+
{
|
|
430
|
+
word: "anjing",
|
|
431
|
+
context: "benar-benar anjing dan bajingan",
|
|
432
|
+
position: { start: 43, end: 62 }
|
|
433
|
+
},
|
|
434
|
+
{
|
|
435
|
+
word: "bajingan",
|
|
436
|
+
context: "anjing dan bajingan!",
|
|
437
|
+
position: { start: 54, end: 63 }
|
|
438
|
+
}
|
|
439
|
+
]
|
|
440
|
+
*/
|
|
441
|
+
```
|
|
442
|
+
|
|
443
|
+
### Analisis Per-Kalimat
|
|
444
|
+
|
|
445
|
+
```typescript
|
|
446
|
+
const filter = new IDProfanityFilter();
|
|
447
|
+
const teks =
|
|
448
|
+
'Filmnya bagus sekali. Tetapi pemainnya seperti anjing, sangat buruk aktingnya.';
|
|
449
|
+
|
|
450
|
+
// Analisis per-kalimat
|
|
451
|
+
const kalimat = filter.analyzeBySentence(teks);
|
|
452
|
+
console.log(
|
|
453
|
+
kalimat.map(
|
|
454
|
+
(k) =>
|
|
455
|
+
k.sentence + (k.hasProfanity ? ' (Mengandung kata kotor)' : ' (Bersih)'),
|
|
456
|
+
),
|
|
457
|
+
);
|
|
458
|
+
|
|
459
|
+
/* Output:
|
|
460
|
+
[
|
|
461
|
+
"Filmnya bagus sekali. (Bersih)",
|
|
462
|
+
"Tetapi pemainnya seperti anjing, sangat buruk aktingnya. (Mengandung kata kotor)"
|
|
463
|
+
]
|
|
464
|
+
*/
|
|
465
|
+
```
|
|
466
|
+
|
|
220
467
|
### Analisis Batch
|
|
221
468
|
|
|
222
469
|
```typescript
|
|
@@ -258,8 +505,6 @@ Library ini mendukung kata-kata kotor dari berbagai daerah di Indonesia:
|
|
|
258
505
|
- 🏙️ **Betawi** - Kata-kata dari bahasa Betawi
|
|
259
506
|
- 🌋 **Batak** - Kata-kata dari bahasa Batak
|
|
260
507
|
|
|
261
|
-
Dan daerah lainnya yang terus bertambah.
|
|
262
|
-
|
|
263
508
|
## Kategori Kata
|
|
264
509
|
|
|
265
510
|
Kata-kata dikelompokkan berdasarkan kategori:
|
|
@@ -276,6 +521,24 @@ Kata-kata dikelompokkan berdasarkan kategori:
|
|
|
276
521
|
|
|
277
522
|
Kami sangat menghargai kontribusi Anda! Untuk berkontribusi, silakan lihat [panduan kontribusi](CONTRIBUTING.md).
|
|
278
523
|
|
|
524
|
+
### Menambahkan Kata Baru
|
|
525
|
+
|
|
526
|
+
Jika Anda ingin menambahkan kata baru ke database, silakan buat pull request dengan mengubah file yang sesuai di `src/constants/categories/` atau `src/constants/regions/`.
|
|
527
|
+
|
|
528
|
+
Format untuk menambahkan kata baru:
|
|
529
|
+
|
|
530
|
+
```json
|
|
531
|
+
{
|
|
532
|
+
"word": "kata_kotor", // Kata yang akan difilter
|
|
533
|
+
"category": "insult", // Kategori kata
|
|
534
|
+
"region": "general", // Daerah asal kata
|
|
535
|
+
"severity": 0.7, // Tingkat keparahan (0-1)
|
|
536
|
+
"aliases": ["k4t4_kotor", "kata_k0t0r"], // Alias atau variasi umum
|
|
537
|
+
"description": "Deskripsi tentang kata", // Penjelasan tentang kata (opsional)
|
|
538
|
+
"context": "Konteks penggunaan kata" // Konteks penggunaan (opsional)
|
|
539
|
+
}
|
|
540
|
+
```
|
|
541
|
+
|
|
279
542
|
## Lisensi
|
|
280
543
|
|
|
281
544
|
Proyek ini dilisensikan di bawah [MIT License](LICENSE).
|
package/dist/config/options.d.ts
CHANGED
|
@@ -17,6 +17,8 @@ export declare const FILTER_PRESETS: {
|
|
|
17
17
|
detectSimilarity?: boolean;
|
|
18
18
|
similarityThreshold?: number;
|
|
19
19
|
detectSplit?: boolean;
|
|
20
|
+
useLevenshtein?: boolean;
|
|
21
|
+
maxLevenshteinDistance?: number;
|
|
20
22
|
};
|
|
21
23
|
moderate: {
|
|
22
24
|
severityThreshold: number;
|
|
@@ -34,6 +36,8 @@ export declare const FILTER_PRESETS: {
|
|
|
34
36
|
detectSimilarity?: boolean;
|
|
35
37
|
similarityThreshold?: number;
|
|
36
38
|
detectSplit?: boolean;
|
|
39
|
+
useLevenshtein?: boolean;
|
|
40
|
+
maxLevenshteinDistance?: number;
|
|
37
41
|
};
|
|
38
42
|
light: {
|
|
39
43
|
severityThreshold: number;
|
|
@@ -51,6 +55,8 @@ export declare const FILTER_PRESETS: {
|
|
|
51
55
|
detectSimilarity?: boolean;
|
|
52
56
|
similarityThreshold?: number;
|
|
53
57
|
detectSplit?: boolean;
|
|
58
|
+
useLevenshtein?: boolean;
|
|
59
|
+
maxLevenshteinDistance?: number;
|
|
54
60
|
};
|
|
55
61
|
childSafe: {
|
|
56
62
|
checkSubstring: boolean;
|
|
@@ -68,6 +74,8 @@ export declare const FILTER_PRESETS: {
|
|
|
68
74
|
detectSimilarity?: boolean;
|
|
69
75
|
similarityThreshold?: number;
|
|
70
76
|
detectSplit?: boolean;
|
|
77
|
+
useLevenshtein?: boolean;
|
|
78
|
+
maxLevenshteinDistance?: number;
|
|
71
79
|
};
|
|
72
80
|
};
|
|
73
81
|
export declare const CATEGORY_PRESETS: {
|
|
@@ -87,6 +95,8 @@ export declare const CATEGORY_PRESETS: {
|
|
|
87
95
|
detectSimilarity?: boolean;
|
|
88
96
|
similarityThreshold?: number;
|
|
89
97
|
detectSplit?: boolean;
|
|
98
|
+
useLevenshtein?: boolean;
|
|
99
|
+
maxLevenshteinDistance?: number;
|
|
90
100
|
};
|
|
91
101
|
insults: {
|
|
92
102
|
categories: ProfanityCategory[];
|
|
@@ -104,6 +114,8 @@ export declare const CATEGORY_PRESETS: {
|
|
|
104
114
|
detectSimilarity?: boolean;
|
|
105
115
|
similarityThreshold?: number;
|
|
106
116
|
detectSplit?: boolean;
|
|
117
|
+
useLevenshtein?: boolean;
|
|
118
|
+
maxLevenshteinDistance?: number;
|
|
107
119
|
};
|
|
108
120
|
profanity: {
|
|
109
121
|
categories: ProfanityCategory[];
|
|
@@ -121,6 +133,8 @@ export declare const CATEGORY_PRESETS: {
|
|
|
121
133
|
detectSimilarity?: boolean;
|
|
122
134
|
similarityThreshold?: number;
|
|
123
135
|
detectSplit?: boolean;
|
|
136
|
+
useLevenshtein?: boolean;
|
|
137
|
+
maxLevenshteinDistance?: number;
|
|
124
138
|
};
|
|
125
139
|
};
|
|
126
140
|
export declare const REGION_PRESETS: {
|
|
@@ -140,6 +154,8 @@ export declare const REGION_PRESETS: {
|
|
|
140
154
|
detectSimilarity?: boolean;
|
|
141
155
|
similarityThreshold?: number;
|
|
142
156
|
detectSplit?: boolean;
|
|
157
|
+
useLevenshtein?: boolean;
|
|
158
|
+
maxLevenshteinDistance?: number;
|
|
143
159
|
};
|
|
144
160
|
jawa: {
|
|
145
161
|
regions: Region[];
|
|
@@ -157,6 +173,8 @@ export declare const REGION_PRESETS: {
|
|
|
157
173
|
detectSimilarity?: boolean;
|
|
158
174
|
similarityThreshold?: number;
|
|
159
175
|
detectSplit?: boolean;
|
|
176
|
+
useLevenshtein?: boolean;
|
|
177
|
+
maxLevenshteinDistance?: number;
|
|
160
178
|
};
|
|
161
179
|
sunda: {
|
|
162
180
|
regions: Region[];
|
|
@@ -174,6 +192,8 @@ export declare const REGION_PRESETS: {
|
|
|
174
192
|
detectSimilarity?: boolean;
|
|
175
193
|
similarityThreshold?: number;
|
|
176
194
|
detectSplit?: boolean;
|
|
195
|
+
useLevenshtein?: boolean;
|
|
196
|
+
maxLevenshteinDistance?: number;
|
|
177
197
|
};
|
|
178
198
|
betawi: {
|
|
179
199
|
regions: Region[];
|
|
@@ -191,6 +211,8 @@ export declare const REGION_PRESETS: {
|
|
|
191
211
|
detectSimilarity?: boolean;
|
|
192
212
|
similarityThreshold?: number;
|
|
193
213
|
detectSplit?: boolean;
|
|
214
|
+
useLevenshtein?: boolean;
|
|
215
|
+
maxLevenshteinDistance?: number;
|
|
194
216
|
};
|
|
195
217
|
batak: {
|
|
196
218
|
regions: Region[];
|
|
@@ -208,6 +230,8 @@ export declare const REGION_PRESETS: {
|
|
|
208
230
|
detectSimilarity?: boolean;
|
|
209
231
|
similarityThreshold?: number;
|
|
210
232
|
detectSplit?: boolean;
|
|
233
|
+
useLevenshtein?: boolean;
|
|
234
|
+
maxLevenshteinDistance?: number;
|
|
211
235
|
};
|
|
212
236
|
};
|
|
213
237
|
export declare const REPLACEMENT_CHARS: {
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { sexual } from './sexual';
|
|
2
|
+
import { insult } from './insult';
|
|
3
|
+
export declare const categories: {
|
|
4
|
+
sexual: import("../..").ProfanityWord[];
|
|
5
|
+
insult: import("../..").ProfanityWord[];
|
|
6
|
+
};
|
|
7
|
+
export { sexual, insult };
|
|
8
|
+
export declare const allCategoryWords: import("../..").ProfanityWord[];
|
|
9
|
+
export default allCategoryWords;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { general } from './general';
|
|
2
|
+
import { jawa } from './jawa';
|
|
3
|
+
import { sunda } from './sunda';
|
|
4
|
+
import { betawi } from './betawi';
|
|
5
|
+
import { batak } from './batak';
|
|
6
|
+
export { general, jawa, sunda, betawi, batak, };
|
|
7
|
+
export declare const allRegionWords: import("../..").ProfanityWord[];
|
|
8
|
+
export default allRegionWords;
|
package/dist/core/analyzer.d.ts
CHANGED
package/dist/core/filter.d.ts
CHANGED
package/dist/core/matcher.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ProfanityWord, ProfanityCategory, Region, FilterOptions } from
|
|
1
|
+
import { ProfanityWord, ProfanityCategory, Region, FilterOptions } from '../types';
|
|
2
2
|
export declare function findProfanity(text: string, options?: FilterOptions): string[];
|
|
3
3
|
/**
|
|
4
4
|
* Mencari kata kotor lengkap dengan metadata
|
package/dist/index.d.ts
CHANGED