@sideid/id-profanity-filter 1.11.0 → 1.11.6
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 +44 -44
- package/.github/workflows/release.yml +62 -0
- package/CONTRIBUTING.md +150 -150
- package/LICENSE +21 -21
- package/README.md +548 -548
- package/dist/index.d.ts +989 -0
- package/dist/index.esm.js +504 -234
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +504 -234
- package/dist/index.js.map +1 -1
- package/dist/types/constants/regions/aceh.d.ts +4 -0
- package/dist/types/constants/regions/bali.d.ts +4 -0
- package/dist/{constants → types/constants}/regions/jawa.d.ts +1 -1
- package/dist/types/index.d.ts +375 -57
- package/dist/types/types/index.d.ts +59 -0
- package/eslint.config.mjs +40 -40
- package/examples/advanced.ts +120 -120
- package/examples/basic.ts +71 -71
- package/examples/custom-list.ts +140 -140
- package/jest.config.mjs +10 -10
- package/package.json +2 -1
- package/prettierrc +6 -6
- package/rollup.config.mjs +40 -35
- package/src/constants/regions/aceh.ts +231 -0
- package/src/constants/regions/bali.ts +168 -0
- package/src/constants/regions/batak.ts +136 -6
- package/src/constants/regions/general.ts +9 -0
- package/src/constants/regions/jawa.ts +367 -229
- package/src/index.ts +15 -15
- package/tsconfig.json +115 -115
- package/.github/workflows/ci.yml +0 -0
- package/dist/constants/categories/index.d.ts +0 -9
- package/dist/constants/regions/index.d.ts +0 -8
- /package/dist/{config → types/config}/options.d.ts +0 -0
- /package/dist/{constants → types/constants}/categories/blasphemy.d.ts +0 -0
- /package/dist/{constants → types/constants}/categories/disgusting.d.ts +0 -0
- /package/dist/{constants → types/constants}/categories/drugs.d.ts +0 -0
- /package/dist/{constants → types/constants}/categories/insult.d.ts +0 -0
- /package/dist/{constants → types/constants}/categories/profanity.d.ts +0 -0
- /package/dist/{constants → types/constants}/categories/sexual.d.ts +0 -0
- /package/dist/{constants → types/constants}/categories/slur.d.ts +0 -0
- /package/dist/{constants → types/constants}/regions/batak.d.ts +0 -0
- /package/dist/{constants → types/constants}/regions/betawi.d.ts +0 -0
- /package/dist/{constants → types/constants}/regions/general.d.ts +0 -0
- /package/dist/{constants → types/constants}/regions/sunda.d.ts +0 -0
- /package/dist/{constants → types/constants}/wordList.d.ts +0 -0
- /package/dist/{core → types/core}/analyzer.d.ts +0 -0
- /package/dist/{core → types/core}/filter.d.ts +0 -0
- /package/dist/{core → types/core}/matcher.d.ts +0 -0
- /package/dist/{utils → types/utils}/ahoCorasick.d.ts +0 -0
- /package/dist/{utils → types/utils}/regexUtils.d.ts +0 -0
- /package/dist/{utils → types/utils}/similarityUtils.d.ts +0 -0
- /package/dist/{utils → types/utils}/stringUtils.d.ts +0 -0
package/README.md
CHANGED
|
@@ -1,548 +1,548 @@
|
|
|
1
|
-
# ID-Profanity-Filter
|
|
2
|
-
|
|
3
|
-

|
|
4
|
-

|
|
5
|
-

|
|
6
|
-
|
|
7
|
-
Library JavaScript/TypeScript untuk mendeteksi, menyensor, dan menganalisis kata-kata kotor dalam Bahasa Indonesia dan bahasa daerah.
|
|
8
|
-
|
|
9
|
-
## Fitur Utama
|
|
10
|
-
|
|
11
|
-
- 🔍 **Deteksi Kata Kotor** - Mendeteksi kata-kata kasar/kotor dalam teks Bahasa Indonesia
|
|
12
|
-
- ⚠️ **Analisis Konten** - Menganalisis tingkat keparahan dan kategori kata kotor
|
|
13
|
-
- 🔒 **Penyensoran** - Menyensor kata-kata kotor dengan berbagai opsi kustomisasi
|
|
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
|
|
18
|
-
- 🔧 **Kustomisasi** - Opsi untuk menambahkan whitelist dan daftar kata kustom
|
|
19
|
-
|
|
20
|
-
## Instalasi
|
|
21
|
-
|
|
22
|
-
```bash
|
|
23
|
-
npm install @sideid/id-profanity-filter
|
|
24
|
-
# atau
|
|
25
|
-
yarn add @sideid/id-profanity-filter
|
|
26
|
-
# atau
|
|
27
|
-
pnpm add @sideid/id-profanity-filter
|
|
28
|
-
```
|
|
29
|
-
|
|
30
|
-
## Penggunaan Dasar
|
|
31
|
-
|
|
32
|
-
### JavaScript / TypeScript
|
|
33
|
-
|
|
34
|
-
```typescript
|
|
35
|
-
import IDProfanityFilter from '@sideid/id-profanity-filter';
|
|
36
|
-
|
|
37
|
-
// Buat instance filter
|
|
38
|
-
const filter = new IDProfanityFilter();
|
|
39
|
-
|
|
40
|
-
// Cek apakah teks mengandung kata kotor
|
|
41
|
-
const teks = 'Dasar anjing kamu, jangan banyak bacot!';
|
|
42
|
-
const hasProfanity = filter.isProfane(teks);
|
|
43
|
-
|
|
44
|
-
console.log(hasProfanity); // Output: true
|
|
45
|
-
|
|
46
|
-
// Filter kata kotor (sensorisasi)
|
|
47
|
-
const hasil = filter.filter(teks);
|
|
48
|
-
console.log(hasil.filtered); // Output: "Dasar ***** kamu, jangan banyak *****!"
|
|
49
|
-
console.log(hasil.censored); // Output: 2 (jumlah kata yang disensor)
|
|
50
|
-
|
|
51
|
-
// Analisis konten
|
|
52
|
-
const analisis = filter.analyze(teks);
|
|
53
|
-
console.log(analisis.severityScore); // Output: 0.65 (contoh skor keparahan)
|
|
54
|
-
console.log(analisis.categories); // Output: ["profanity", "insult"]
|
|
55
|
-
```
|
|
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
|
-
|
|
77
|
-
### Utilitas Langsung
|
|
78
|
-
|
|
79
|
-
Anda juga dapat menggunakan fungsi utilitas langsung tanpa membuat instance:
|
|
80
|
-
|
|
81
|
-
```typescript
|
|
82
|
-
import { idFilter } from '@sideid/id-profanity-filter';
|
|
83
|
-
|
|
84
|
-
const teks = 'Dasar anjing kamu, jangan banyak bacot!';
|
|
85
|
-
const hasil = idFilter.filter(teks);
|
|
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
|
-
);
|
|
93
|
-
```
|
|
94
|
-
|
|
95
|
-
## Dokumentasi API
|
|
96
|
-
|
|
97
|
-
### Kelas `IDProfanityFilter`
|
|
98
|
-
|
|
99
|
-
#### Konstruktor
|
|
100
|
-
|
|
101
|
-
```typescript
|
|
102
|
-
constructor(options?: FilterOptions)
|
|
103
|
-
```
|
|
104
|
-
|
|
105
|
-
- **options**: Opsi konfigurasi filter (opsional)
|
|
106
|
-
|
|
107
|
-
#### Metode
|
|
108
|
-
|
|
109
|
-
##### `filter(text: string): FilterResult`
|
|
110
|
-
|
|
111
|
-
Menyensor kata kotor dalam teks.
|
|
112
|
-
|
|
113
|
-
- **Hasil**: Objek `FilterResult` dengan properti:
|
|
114
|
-
- `filtered`: String teks yang sudah disensor
|
|
115
|
-
- `censored`: Jumlah kata yang disensor
|
|
116
|
-
- `replacements`: Array berisi detail kata yang disensor
|
|
117
|
-
|
|
118
|
-
##### `isProfane(text: string): boolean`
|
|
119
|
-
|
|
120
|
-
Memeriksa apakah teks mengandung kata kotor.
|
|
121
|
-
|
|
122
|
-
- **Hasil**: Boolean `true` jika teks mengandung kata kotor, `false` jika tidak
|
|
123
|
-
|
|
124
|
-
##### `analyze(text: string): AnalysisResult`
|
|
125
|
-
|
|
126
|
-
Menganalisis teks untuk mendapatkan informasi detail tentang kata kotor yang ditemukan.
|
|
127
|
-
|
|
128
|
-
- **Hasil**: Objek `AnalysisResult` dengan properti:
|
|
129
|
-
- `hasProfanity`: Apakah teks mengandung kata kotor
|
|
130
|
-
- `matches`: Array kata kotor yang ditemukan
|
|
131
|
-
- `matchDetails`: Array objek kata kotor dengan metadata
|
|
132
|
-
- `categories`: Kategori kata kotor yang ditemukan
|
|
133
|
-
- `regions`: Daerah asal kata kotor yang ditemukan
|
|
134
|
-
- `severityScore`: Skor keparahan (0-1)
|
|
135
|
-
- `similarWords`: Kata-kata yang mirip dengan kata kotor (jika deteksi kesamaan diaktifkan)
|
|
136
|
-
|
|
137
|
-
##### `batchAnalyze(texts: string[])`
|
|
138
|
-
|
|
139
|
-
Menganalisis batch teks sekaligus dan memberikan ringkasan.
|
|
140
|
-
|
|
141
|
-
- **Hasil**: Objek yang berisi ringkasan analisis
|
|
142
|
-
|
|
143
|
-
##### `analyzeBySentence(text: string)`
|
|
144
|
-
|
|
145
|
-
Menganalisis teks per-kalimat.
|
|
146
|
-
|
|
147
|
-
- **Hasil**: Array dari hasil analisis per-kalimat
|
|
148
|
-
|
|
149
|
-
##### `analyzeWithContext(text: string, contextWindowSize?: number)`
|
|
150
|
-
|
|
151
|
-
Menganalisis teks dengan konteks di sekitar kata kotor.
|
|
152
|
-
|
|
153
|
-
- **Hasil**: Array dari kata kotor dengan konteks di sekitarnya
|
|
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
|
-
|
|
162
|
-
##### `setOptions(options: Partial<FilterOptions>)`
|
|
163
|
-
|
|
164
|
-
Mengubah opsi filter.
|
|
165
|
-
|
|
166
|
-
##### `setWordList(wordList: string[])`
|
|
167
|
-
|
|
168
|
-
Menetapkan daftar kata kustom.
|
|
169
|
-
|
|
170
|
-
##### `addToWhitelist(word: string)`
|
|
171
|
-
|
|
172
|
-
Menambahkan kata ke whitelist (akan diabaikan dalam filter).
|
|
173
|
-
|
|
174
|
-
##### `removeFromWhitelist(word: string)`
|
|
175
|
-
|
|
176
|
-
Menghapus kata dari whitelist.
|
|
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
|
-
|
|
201
|
-
### Opsi Filter
|
|
202
|
-
|
|
203
|
-
```typescript
|
|
204
|
-
interface FilterOptions {
|
|
205
|
-
// Opsi dasar
|
|
206
|
-
wordList?: string[]; // List kata yang ingin difilter
|
|
207
|
-
replaceWith?: string; // Karakter pengganti untuk kata yang disensor
|
|
208
|
-
fullWordCensor?: boolean; // Apakah menyensor seluruh kata atau sebagian
|
|
209
|
-
detectLeetSpeak?: boolean; // Deteksi variasi penulisan (mis: a=4, e=3)
|
|
210
|
-
whitelist?: string[]; // Kata-kata yang dikecualikan dari filter
|
|
211
|
-
checkSubstring?: boolean; // Memeriksa substring (lebih ketat)
|
|
212
|
-
categories?: ProfanityCategory[]; // Kategori kata yang difilter
|
|
213
|
-
regions?: Region[]; // Daerah asal kata yang difilter
|
|
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
|
|
225
|
-
}
|
|
226
|
-
```
|
|
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
|
-
|
|
253
|
-
## Contoh Penggunaan Lanjutan
|
|
254
|
-
|
|
255
|
-
### Kustomisasi Opsi Filter
|
|
256
|
-
|
|
257
|
-
```typescript
|
|
258
|
-
const filter = new IDProfanityFilter({
|
|
259
|
-
replaceWith: '#', // Menggunakan # sebagai karakter pengganti
|
|
260
|
-
fullWordCensor: false, // Hanya menyensor sebagian kata
|
|
261
|
-
detectLeetSpeak: true, // Mendeteksi variasi seperti "b4b1" untuk "babi"
|
|
262
|
-
categories: ['sexual', 'slur'], // Hanya filter kategori tertentu
|
|
263
|
-
regions: ['jawa', 'general'], // Hanya filter dari daerah tertentu
|
|
264
|
-
severityThreshold: 0.7, // Hanya filter kata dengan tingkat keparahan ≥ 0.7
|
|
265
|
-
|
|
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
|
|
275
|
-
});
|
|
276
|
-
```
|
|
277
|
-
|
|
278
|
-
### Menggunakan Whitelist
|
|
279
|
-
|
|
280
|
-
```typescript
|
|
281
|
-
const filter = new IDProfanityFilter();
|
|
282
|
-
|
|
283
|
-
// Menambahkan kata ke whitelist (akan diabaikan)
|
|
284
|
-
filter.addToWhitelist('anjing');
|
|
285
|
-
|
|
286
|
-
const teks =
|
|
287
|
-
'Anjing itu hewan peliharaan yang setia, tidak seperti bajingan itu';
|
|
288
|
-
const hasil = filter.filter(teks);
|
|
289
|
-
|
|
290
|
-
console.log(hasil.filtered);
|
|
291
|
-
// Output: "Anjing itu hewan peliharaan yang setia, tidak seperti ******* itu"
|
|
292
|
-
```
|
|
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
|
-
|
|
390
|
-
### Analisis Konten Mendalam
|
|
391
|
-
|
|
392
|
-
```typescript
|
|
393
|
-
const filter = new IDProfanityFilter();
|
|
394
|
-
const teks = 'Dasar anjing sialan! Kamu ini memang bego dan goblok.';
|
|
395
|
-
|
|
396
|
-
// Analisis teks
|
|
397
|
-
const analisis = filter.analyze(teks);
|
|
398
|
-
console.log(analisis);
|
|
399
|
-
|
|
400
|
-
/* Output:
|
|
401
|
-
{
|
|
402
|
-
hasProfanity: true,
|
|
403
|
-
matches: ['anjing', 'sialan', 'bego', 'goblok'],
|
|
404
|
-
matchDetails: [
|
|
405
|
-
{ word: 'anjing', category: 'profanity', region: 'general', severity: 0.7, ... },
|
|
406
|
-
{ word: 'bego', category: 'insult', region: 'general', severity: 0.5, ... },
|
|
407
|
-
...
|
|
408
|
-
],
|
|
409
|
-
categories: ['profanity', 'insult'],
|
|
410
|
-
regions: ['general'],
|
|
411
|
-
severityScore: 0.64
|
|
412
|
-
}
|
|
413
|
-
*/
|
|
414
|
-
```
|
|
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
|
-
|
|
467
|
-
### Analisis Batch
|
|
468
|
-
|
|
469
|
-
```typescript
|
|
470
|
-
const filter = new IDProfanityFilter();
|
|
471
|
-
const komentar = [
|
|
472
|
-
'Film ini sangat bagus, ceritanya menarik sekali!',
|
|
473
|
-
'Dasar goblok, sialan kamu!',
|
|
474
|
-
'Anjing emang filmnya, sampah banget.',
|
|
475
|
-
];
|
|
476
|
-
|
|
477
|
-
const hasil = filter.batchAnalyze(komentar);
|
|
478
|
-
console.log(hasil);
|
|
479
|
-
|
|
480
|
-
/* Output:
|
|
481
|
-
{
|
|
482
|
-
totalTexts: 3,
|
|
483
|
-
profaneTexts: 2,
|
|
484
|
-
cleanTexts: 1,
|
|
485
|
-
averageSeverity: 0.62,
|
|
486
|
-
topCategories: ['profanity', 'insult'],
|
|
487
|
-
topRegions: ['general'],
|
|
488
|
-
mostFrequentWords: [
|
|
489
|
-
{ word: 'anjing', count: 1 },
|
|
490
|
-
{ word: 'goblok', count: 1 },
|
|
491
|
-
{ word: 'sialan', count: 1 },
|
|
492
|
-
{ word: 'sampah', count: 1 }
|
|
493
|
-
]
|
|
494
|
-
}
|
|
495
|
-
*/
|
|
496
|
-
```
|
|
497
|
-
|
|
498
|
-
## Dukungan Regional
|
|
499
|
-
|
|
500
|
-
Library ini mendukung kata-kata kotor dari berbagai daerah di Indonesia:
|
|
501
|
-
|
|
502
|
-
- 🇮🇩 **General** - Kata-kata yang umum di seluruh Indonesia
|
|
503
|
-
- 🏝️ **Jawa** - Kata-kata dari bahasa Jawa
|
|
504
|
-
- 🏞️ **Sunda** - Kata-kata dari bahasa Sunda
|
|
505
|
-
- 🏙️ **Betawi** - Kata-kata dari bahasa Betawi
|
|
506
|
-
- 🌋 **Batak** - Kata-kata dari bahasa Batak
|
|
507
|
-
|
|
508
|
-
## Kategori Kata
|
|
509
|
-
|
|
510
|
-
Kata-kata dikelompokkan berdasarkan kategori:
|
|
511
|
-
|
|
512
|
-
- `sexual`: Kata-kata berbau seksual
|
|
513
|
-
- `insult`: Kata-kata penghinaan
|
|
514
|
-
- `profanity`: Umpatan umum
|
|
515
|
-
- `slur`: Perkataan merendahkan berdasarkan identitas
|
|
516
|
-
- `drugs`: Terkait narkoba
|
|
517
|
-
- `disgusting`: Kata-kata menjijikkan
|
|
518
|
-
- `blasphemy`: Penistaan agama
|
|
519
|
-
|
|
520
|
-
## Berkontribusi
|
|
521
|
-
|
|
522
|
-
Kami sangat menghargai kontribusi Anda! Untuk berkontribusi, silakan lihat [panduan kontribusi](CONTRIBUTING.md).
|
|
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
|
-
|
|
542
|
-
## Lisensi
|
|
543
|
-
|
|
544
|
-
Proyek ini dilisensikan di bawah [MIT License](LICENSE).
|
|
545
|
-
|
|
546
|
-
## Kontak & Dukungan
|
|
547
|
-
|
|
548
|
-
Jika Anda memiliki pertanyaan atau saran, silakan buka issue di repositori GitHub kami.
|
|
1
|
+
# ID-Profanity-Filter
|
|
2
|
+
|
|
3
|
+

|
|
4
|
+

|
|
5
|
+

|
|
6
|
+
|
|
7
|
+
Library JavaScript/TypeScript untuk mendeteksi, menyensor, dan menganalisis kata-kata kotor dalam Bahasa Indonesia dan bahasa daerah.
|
|
8
|
+
|
|
9
|
+
## Fitur Utama
|
|
10
|
+
|
|
11
|
+
- 🔍 **Deteksi Kata Kotor** - Mendeteksi kata-kata kasar/kotor dalam teks Bahasa Indonesia
|
|
12
|
+
- ⚠️ **Analisis Konten** - Menganalisis tingkat keparahan dan kategori kata kotor
|
|
13
|
+
- 🔒 **Penyensoran** - Menyensor kata-kata kotor dengan berbagai opsi kustomisasi
|
|
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
|
|
18
|
+
- 🔧 **Kustomisasi** - Opsi untuk menambahkan whitelist dan daftar kata kustom
|
|
19
|
+
|
|
20
|
+
## Instalasi
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
npm install @sideid/id-profanity-filter
|
|
24
|
+
# atau
|
|
25
|
+
yarn add @sideid/id-profanity-filter
|
|
26
|
+
# atau
|
|
27
|
+
pnpm add @sideid/id-profanity-filter
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
## Penggunaan Dasar
|
|
31
|
+
|
|
32
|
+
### JavaScript / TypeScript
|
|
33
|
+
|
|
34
|
+
```typescript
|
|
35
|
+
import IDProfanityFilter from '@sideid/id-profanity-filter';
|
|
36
|
+
|
|
37
|
+
// Buat instance filter
|
|
38
|
+
const filter = new IDProfanityFilter();
|
|
39
|
+
|
|
40
|
+
// Cek apakah teks mengandung kata kotor
|
|
41
|
+
const teks = 'Dasar anjing kamu, jangan banyak bacot!';
|
|
42
|
+
const hasProfanity = filter.isProfane(teks);
|
|
43
|
+
|
|
44
|
+
console.log(hasProfanity); // Output: true
|
|
45
|
+
|
|
46
|
+
// Filter kata kotor (sensorisasi)
|
|
47
|
+
const hasil = filter.filter(teks);
|
|
48
|
+
console.log(hasil.filtered); // Output: "Dasar ***** kamu, jangan banyak *****!"
|
|
49
|
+
console.log(hasil.censored); // Output: 2 (jumlah kata yang disensor)
|
|
50
|
+
|
|
51
|
+
// Analisis konten
|
|
52
|
+
const analisis = filter.analyze(teks);
|
|
53
|
+
console.log(analisis.severityScore); // Output: 0.65 (contoh skor keparahan)
|
|
54
|
+
console.log(analisis.categories); // Output: ["profanity", "insult"]
|
|
55
|
+
```
|
|
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
|
+
|
|
77
|
+
### Utilitas Langsung
|
|
78
|
+
|
|
79
|
+
Anda juga dapat menggunakan fungsi utilitas langsung tanpa membuat instance:
|
|
80
|
+
|
|
81
|
+
```typescript
|
|
82
|
+
import { idFilter } from '@sideid/id-profanity-filter';
|
|
83
|
+
|
|
84
|
+
const teks = 'Dasar anjing kamu, jangan banyak bacot!';
|
|
85
|
+
const hasil = idFilter.filter(teks);
|
|
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
|
+
);
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
## Dokumentasi API
|
|
96
|
+
|
|
97
|
+
### Kelas `IDProfanityFilter`
|
|
98
|
+
|
|
99
|
+
#### Konstruktor
|
|
100
|
+
|
|
101
|
+
```typescript
|
|
102
|
+
constructor(options?: FilterOptions)
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
- **options**: Opsi konfigurasi filter (opsional)
|
|
106
|
+
|
|
107
|
+
#### Metode
|
|
108
|
+
|
|
109
|
+
##### `filter(text: string): FilterResult`
|
|
110
|
+
|
|
111
|
+
Menyensor kata kotor dalam teks.
|
|
112
|
+
|
|
113
|
+
- **Hasil**: Objek `FilterResult` dengan properti:
|
|
114
|
+
- `filtered`: String teks yang sudah disensor
|
|
115
|
+
- `censored`: Jumlah kata yang disensor
|
|
116
|
+
- `replacements`: Array berisi detail kata yang disensor
|
|
117
|
+
|
|
118
|
+
##### `isProfane(text: string): boolean`
|
|
119
|
+
|
|
120
|
+
Memeriksa apakah teks mengandung kata kotor.
|
|
121
|
+
|
|
122
|
+
- **Hasil**: Boolean `true` jika teks mengandung kata kotor, `false` jika tidak
|
|
123
|
+
|
|
124
|
+
##### `analyze(text: string): AnalysisResult`
|
|
125
|
+
|
|
126
|
+
Menganalisis teks untuk mendapatkan informasi detail tentang kata kotor yang ditemukan.
|
|
127
|
+
|
|
128
|
+
- **Hasil**: Objek `AnalysisResult` dengan properti:
|
|
129
|
+
- `hasProfanity`: Apakah teks mengandung kata kotor
|
|
130
|
+
- `matches`: Array kata kotor yang ditemukan
|
|
131
|
+
- `matchDetails`: Array objek kata kotor dengan metadata
|
|
132
|
+
- `categories`: Kategori kata kotor yang ditemukan
|
|
133
|
+
- `regions`: Daerah asal kata kotor yang ditemukan
|
|
134
|
+
- `severityScore`: Skor keparahan (0-1)
|
|
135
|
+
- `similarWords`: Kata-kata yang mirip dengan kata kotor (jika deteksi kesamaan diaktifkan)
|
|
136
|
+
|
|
137
|
+
##### `batchAnalyze(texts: string[])`
|
|
138
|
+
|
|
139
|
+
Menganalisis batch teks sekaligus dan memberikan ringkasan.
|
|
140
|
+
|
|
141
|
+
- **Hasil**: Objek yang berisi ringkasan analisis
|
|
142
|
+
|
|
143
|
+
##### `analyzeBySentence(text: string)`
|
|
144
|
+
|
|
145
|
+
Menganalisis teks per-kalimat.
|
|
146
|
+
|
|
147
|
+
- **Hasil**: Array dari hasil analisis per-kalimat
|
|
148
|
+
|
|
149
|
+
##### `analyzeWithContext(text: string, contextWindowSize?: number)`
|
|
150
|
+
|
|
151
|
+
Menganalisis teks dengan konteks di sekitar kata kotor.
|
|
152
|
+
|
|
153
|
+
- **Hasil**: Array dari kata kotor dengan konteks di sekitarnya
|
|
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
|
+
|
|
162
|
+
##### `setOptions(options: Partial<FilterOptions>)`
|
|
163
|
+
|
|
164
|
+
Mengubah opsi filter.
|
|
165
|
+
|
|
166
|
+
##### `setWordList(wordList: string[])`
|
|
167
|
+
|
|
168
|
+
Menetapkan daftar kata kustom.
|
|
169
|
+
|
|
170
|
+
##### `addToWhitelist(word: string)`
|
|
171
|
+
|
|
172
|
+
Menambahkan kata ke whitelist (akan diabaikan dalam filter).
|
|
173
|
+
|
|
174
|
+
##### `removeFromWhitelist(word: string)`
|
|
175
|
+
|
|
176
|
+
Menghapus kata dari whitelist.
|
|
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
|
+
|
|
201
|
+
### Opsi Filter
|
|
202
|
+
|
|
203
|
+
```typescript
|
|
204
|
+
interface FilterOptions {
|
|
205
|
+
// Opsi dasar
|
|
206
|
+
wordList?: string[]; // List kata yang ingin difilter
|
|
207
|
+
replaceWith?: string; // Karakter pengganti untuk kata yang disensor
|
|
208
|
+
fullWordCensor?: boolean; // Apakah menyensor seluruh kata atau sebagian
|
|
209
|
+
detectLeetSpeak?: boolean; // Deteksi variasi penulisan (mis: a=4, e=3)
|
|
210
|
+
whitelist?: string[]; // Kata-kata yang dikecualikan dari filter
|
|
211
|
+
checkSubstring?: boolean; // Memeriksa substring (lebih ketat)
|
|
212
|
+
categories?: ProfanityCategory[]; // Kategori kata yang difilter
|
|
213
|
+
regions?: Region[]; // Daerah asal kata yang difilter
|
|
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
|
|
225
|
+
}
|
|
226
|
+
```
|
|
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
|
+
|
|
253
|
+
## Contoh Penggunaan Lanjutan
|
|
254
|
+
|
|
255
|
+
### Kustomisasi Opsi Filter
|
|
256
|
+
|
|
257
|
+
```typescript
|
|
258
|
+
const filter = new IDProfanityFilter({
|
|
259
|
+
replaceWith: '#', // Menggunakan # sebagai karakter pengganti
|
|
260
|
+
fullWordCensor: false, // Hanya menyensor sebagian kata
|
|
261
|
+
detectLeetSpeak: true, // Mendeteksi variasi seperti "b4b1" untuk "babi"
|
|
262
|
+
categories: ['sexual', 'slur'], // Hanya filter kategori tertentu
|
|
263
|
+
regions: ['jawa', 'general'], // Hanya filter dari daerah tertentu
|
|
264
|
+
severityThreshold: 0.7, // Hanya filter kata dengan tingkat keparahan ≥ 0.7
|
|
265
|
+
|
|
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
|
|
275
|
+
});
|
|
276
|
+
```
|
|
277
|
+
|
|
278
|
+
### Menggunakan Whitelist
|
|
279
|
+
|
|
280
|
+
```typescript
|
|
281
|
+
const filter = new IDProfanityFilter();
|
|
282
|
+
|
|
283
|
+
// Menambahkan kata ke whitelist (akan diabaikan)
|
|
284
|
+
filter.addToWhitelist('anjing');
|
|
285
|
+
|
|
286
|
+
const teks =
|
|
287
|
+
'Anjing itu hewan peliharaan yang setia, tidak seperti bajingan itu';
|
|
288
|
+
const hasil = filter.filter(teks);
|
|
289
|
+
|
|
290
|
+
console.log(hasil.filtered);
|
|
291
|
+
// Output: "Anjing itu hewan peliharaan yang setia, tidak seperti ******* itu"
|
|
292
|
+
```
|
|
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
|
+
|
|
390
|
+
### Analisis Konten Mendalam
|
|
391
|
+
|
|
392
|
+
```typescript
|
|
393
|
+
const filter = new IDProfanityFilter();
|
|
394
|
+
const teks = 'Dasar anjing sialan! Kamu ini memang bego dan goblok.';
|
|
395
|
+
|
|
396
|
+
// Analisis teks
|
|
397
|
+
const analisis = filter.analyze(teks);
|
|
398
|
+
console.log(analisis);
|
|
399
|
+
|
|
400
|
+
/* Output:
|
|
401
|
+
{
|
|
402
|
+
hasProfanity: true,
|
|
403
|
+
matches: ['anjing', 'sialan', 'bego', 'goblok'],
|
|
404
|
+
matchDetails: [
|
|
405
|
+
{ word: 'anjing', category: 'profanity', region: 'general', severity: 0.7, ... },
|
|
406
|
+
{ word: 'bego', category: 'insult', region: 'general', severity: 0.5, ... },
|
|
407
|
+
...
|
|
408
|
+
],
|
|
409
|
+
categories: ['profanity', 'insult'],
|
|
410
|
+
regions: ['general'],
|
|
411
|
+
severityScore: 0.64
|
|
412
|
+
}
|
|
413
|
+
*/
|
|
414
|
+
```
|
|
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
|
+
|
|
467
|
+
### Analisis Batch
|
|
468
|
+
|
|
469
|
+
```typescript
|
|
470
|
+
const filter = new IDProfanityFilter();
|
|
471
|
+
const komentar = [
|
|
472
|
+
'Film ini sangat bagus, ceritanya menarik sekali!',
|
|
473
|
+
'Dasar goblok, sialan kamu!',
|
|
474
|
+
'Anjing emang filmnya, sampah banget.',
|
|
475
|
+
];
|
|
476
|
+
|
|
477
|
+
const hasil = filter.batchAnalyze(komentar);
|
|
478
|
+
console.log(hasil);
|
|
479
|
+
|
|
480
|
+
/* Output:
|
|
481
|
+
{
|
|
482
|
+
totalTexts: 3,
|
|
483
|
+
profaneTexts: 2,
|
|
484
|
+
cleanTexts: 1,
|
|
485
|
+
averageSeverity: 0.62,
|
|
486
|
+
topCategories: ['profanity', 'insult'],
|
|
487
|
+
topRegions: ['general'],
|
|
488
|
+
mostFrequentWords: [
|
|
489
|
+
{ word: 'anjing', count: 1 },
|
|
490
|
+
{ word: 'goblok', count: 1 },
|
|
491
|
+
{ word: 'sialan', count: 1 },
|
|
492
|
+
{ word: 'sampah', count: 1 }
|
|
493
|
+
]
|
|
494
|
+
}
|
|
495
|
+
*/
|
|
496
|
+
```
|
|
497
|
+
|
|
498
|
+
## Dukungan Regional
|
|
499
|
+
|
|
500
|
+
Library ini mendukung kata-kata kotor dari berbagai daerah di Indonesia:
|
|
501
|
+
|
|
502
|
+
- 🇮🇩 **General** - Kata-kata yang umum di seluruh Indonesia
|
|
503
|
+
- 🏝️ **Jawa** - Kata-kata dari bahasa Jawa
|
|
504
|
+
- 🏞️ **Sunda** - Kata-kata dari bahasa Sunda
|
|
505
|
+
- 🏙️ **Betawi** - Kata-kata dari bahasa Betawi
|
|
506
|
+
- 🌋 **Batak** - Kata-kata dari bahasa Batak
|
|
507
|
+
|
|
508
|
+
## Kategori Kata
|
|
509
|
+
|
|
510
|
+
Kata-kata dikelompokkan berdasarkan kategori:
|
|
511
|
+
|
|
512
|
+
- `sexual`: Kata-kata berbau seksual
|
|
513
|
+
- `insult`: Kata-kata penghinaan
|
|
514
|
+
- `profanity`: Umpatan umum
|
|
515
|
+
- `slur`: Perkataan merendahkan berdasarkan identitas
|
|
516
|
+
- `drugs`: Terkait narkoba
|
|
517
|
+
- `disgusting`: Kata-kata menjijikkan
|
|
518
|
+
- `blasphemy`: Penistaan agama
|
|
519
|
+
|
|
520
|
+
## Berkontribusi
|
|
521
|
+
|
|
522
|
+
Kami sangat menghargai kontribusi Anda! Untuk berkontribusi, silakan lihat [panduan kontribusi](CONTRIBUTING.md).
|
|
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
|
+
|
|
542
|
+
## Lisensi
|
|
543
|
+
|
|
544
|
+
Proyek ini dilisensikan di bawah [MIT License](LICENSE).
|
|
545
|
+
|
|
546
|
+
## Kontak & Dukungan
|
|
547
|
+
|
|
548
|
+
Jika Anda memiliki pertanyaan atau saran, silakan buka issue di repositori GitHub kami.
|