@sideid/id-profanity-filter 1.12.0 → 1.13.0

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/README.md CHANGED
@@ -8,560 +8,266 @@
8
8
  <a href="https://www.npmjs.com/package/@sideid/id-profanity-filter">
9
9
  <img src="https://img.shields.io/npm/v/@sideid/id-profanity-filter.svg" alt="NPM Version">
10
10
  </a>
11
- <a href="https://www.npmjs.com/package/@sideid/id-profanity-filter">
12
- <img src="https://img.shields.io/npm/dt/@sideid/id-profanity-filter?label=npm&color=%23CB3837" alt="NPM Downloads">
13
- </a>
14
- <a href="https://github.com/SideeID/id-profanity-filter">
15
- <img src="https://img.shields.io/github/languages/code-size/SideeID/id-profanity-filter" alt="GitHub Code Size">
16
- </a>
17
11
  <a href="https://github.com/SideeID/id-profanity-filter">
18
12
  <img src="https://img.shields.io/github/license/SideeID/id-profanity-filter" alt="GitHub License">
19
13
  </a>
20
- <a href="https://github.com/SideeID/id-profanity-filter">
21
- <img src="https://img.shields.io/github/stars/SideeID/id-profanity-filter" alt="GitHub Stars">
22
- </a>
23
- <a href="https://github.com/SideeID/id-profanity-filter">
24
- <img src="https://img.shields.io/github/forks/SideeID/id-profanity-filter" alt="GitHub Forks">
25
- </a>
26
14
  </div>
27
15
 
28
- ## Fitur Utama
16
+ # id-profanity-filter
17
+
18
+ Library JavaScript dan TypeScript untuk mendeteksi, menyensor, dan menganalisis kata kotor dalam bahasa Indonesia serta berbagai bahasa daerah.
29
19
 
30
- - 🔍 **Deteksi Kata Kotor** - Mendeteksi kata-kata kasar/kotor dalam teks Bahasa Indonesia
31
- - ⚠️ **Analisis Konten** - Menganalisis tingkat keparahan dan kategori kata kotor
32
- - 🔒 **Penyensoran** - Menyensor kata-kata kotor dengan berbagai opsi kustomisasi
33
- - 🗺️ **Dukungan Bahasa Daerah** - Mencakup kata-kata dari berbagai daerah di Indonesia (Jawa, Sunda, Batak, dll)
34
- - 🧠 **Deteksi Cerdas** - Mendeteksi variasi ejaan, kata terpisah, dan kesamaan kata
35
- - 🔠 **Deteksi Levenshtein** - Mendeteksi kata kotor yang dimodifikasi dengan typo atau sengaja disamarkan
36
- - 🛡️ **Preset** - Preset filter siap pakai untuk berbagai kebutuhan
37
- - 🔧 **Kustomisasi** - Opsi untuk menambahkan whitelist dan daftar kata kustom
20
+ ## Fitur
21
+
22
+ - Deteksi kata kotor dan umpatan dalam bahasa Indonesia dan dialek daerah (Jawa, Sunda, Batak, Betawi, Minang, Bali, Madura, Aceh)
23
+ - Sensor fleksibel: ganti karakter (`*`, `#`), grawlix acak (`#@$%&!`), sensor penuh, atau pertahankan huruf pertama dan terakhir
24
+ - Deteksi variasi penulisan: leetspeak (`4nj1ng`), kata terpisah (`a-n-j-i-n-g`), dan typo via Levenshtein distance
25
+ - Analisis teks: skor keparahan (0-1), kategorisasi, analisis per kalimat, pencarian konteks sekitar, dan batch analysis
26
+ - Mendukung whitelist kata dan daftar kata kustom (`wordList`)
27
+ - Preset siap pakai: `strict`, `moderate`, `light`, dan `childSafe`
28
+ - Dukungan penuh TypeScript dengan tipe data lengkap
38
29
 
39
30
  ## Instalasi
40
31
 
41
32
  ```bash
42
33
  npm install @sideid/id-profanity-filter
43
34
  # atau
44
- yarn add @sideid/id-profanity-filter
35
+ bun add @sideid/id-profanity-filter
45
36
  # atau
46
37
  pnpm add @sideid/id-profanity-filter
47
38
  ```
48
39
 
49
- ## Penggunaan Dasar
40
+ ## Penggunaan dasar
50
41
 
51
- ### JavaScript / TypeScript
42
+ ### Menggunakan class IDProfanityFilter
52
43
 
53
44
  ```typescript
54
45
  import IDProfanityFilter from '@sideid/id-profanity-filter';
55
46
 
56
- // Buat instance filter
57
47
  const filter = new IDProfanityFilter();
58
-
59
- // Cek apakah teks mengandung kata kotor
60
48
  const teks = 'Dasar anjing kamu, jangan banyak bacot!';
61
- const hasProfanity = filter.isProfane(teks);
62
-
63
- console.log(hasProfanity); // Output: true
64
-
65
- // Filter kata kotor (sensorisasi)
66
- const hasil = filter.filter(teks);
67
- console.log(hasil.filtered); // Output: "Dasar ***** kamu, jangan banyak *****!"
68
- console.log(hasil.censored); // Output: 2 (jumlah kata yang disensor)
69
-
70
- // Analisis konten
71
- const analisis = filter.analyze(teks);
72
- console.log(analisis.severityScore); // Output: 0.65 (contoh skor keparahan)
73
- console.log(analisis.categories); // Output: ["profanity", "insult"]
74
- ```
75
49
 
76
- ### Menggunakan Preset
77
-
78
- ```typescript
79
- import IDProfanityFilter from '@sideid/id-profanity-filter';
80
-
81
- // Buat instance filter dengan preset
82
- const filter = new IDProfanityFilter();
83
- filter.usePreset('strict');
84
-
85
- // Atau dengan opsi tambahan
86
- filter.usePreset('childSafe', {
87
- replaceWith: '#',
88
- useRandomGrawlix: true,
89
- });
90
-
91
- const teks = 'Dasar anjing kamu, jangan banyak bacot!';
92
- const hasil = filter.filter(teks);
93
- console.log(hasil.filtered); // Output: "Dasar #@$%& kamu, jangan banyak $!@#%!"
50
+ // Cek apakah teks mengandung kata kotor
51
+ if (filter.isProfane(teks)) {
52
+ // Sensor kata kotor
53
+ const hasil = filter.filter(teks);
54
+ console.log(hasil.filtered);
55
+ // Output: "Dasar ****** kamu, jangan banyak *****!"
56
+ console.log(hasil.censored);
57
+ // Output: 2
58
+
59
+ // Analisis detail
60
+ const analisis = filter.analyze(teks);
61
+ console.log(analisis.categories);
62
+ // Output: ["profanity", "insult"]
63
+ console.log(analisis.regions);
64
+ // Output: ["general", "jawa"]
65
+ console.log(analisis.severityScore);
66
+ // Output: 0.36
67
+ }
94
68
  ```
95
69
 
96
- ### Utilitas Langsung
70
+ ### Menggunakan fungsi statis (idFilter)
97
71
 
98
- Anda juga dapat menggunakan fungsi utilitas langsung tanpa membuat instance:
72
+ Jika tidak memerlukan konfigurasi instance khusus, gunakan helper `idFilter`:
99
73
 
100
74
  ```typescript
101
75
  import { idFilter } from '@sideid/id-profanity-filter';
102
76
 
103
77
  const teks = 'Dasar anjing kamu, jangan banyak bacot!';
78
+
79
+ // Filter langsung
104
80
  const hasil = idFilter.filter(teks);
105
- console.log(hasil.filtered); // Output: "Dasar ***** kamu, jangan banyak *****!"
81
+ console.log(hasil.filtered);
106
82
 
107
- // Menggunakan preset dengan API fungsi statis
108
- const presetResult = idFilter.filter(
109
- teks,
110
- idFilter.getPresetOptions('moderate'),
111
- );
83
+ // Cek cepat
84
+ console.log(idFilter.isProfane(teks)); // true
112
85
  ```
113
86
 
114
- ## Dokumentasi API
115
-
116
- ### Kelas `IDProfanityFilter`
117
-
118
- #### Konstruktor
87
+ ### Menggunakan preset
119
88
 
120
89
  ```typescript
121
- constructor(options?: FilterOptions)
122
- ```
123
-
124
- - **options**: Opsi konfigurasi filter (opsional)
125
-
126
- #### Metode
127
-
128
- ##### `filter(text: string): FilterResult`
129
-
130
- Menyensor kata kotor dalam teks.
131
-
132
- - **Hasil**: Objek `FilterResult` dengan properti:
133
- - `filtered`: String teks yang sudah disensor
134
- - `censored`: Jumlah kata yang disensor
135
- - `replacements`: Array berisi detail kata yang disensor
136
-
137
- ##### `isProfane(text: string): boolean`
138
-
139
- Memeriksa apakah teks mengandung kata kotor.
140
-
141
- - **Hasil**: Boolean `true` jika teks mengandung kata kotor, `false` jika tidak
142
-
143
- ##### `analyze(text: string): AnalysisResult`
144
-
145
- Menganalisis teks untuk mendapatkan informasi detail tentang kata kotor yang ditemukan.
146
-
147
- - **Hasil**: Objek `AnalysisResult` dengan properti:
148
- - `hasProfanity`: Apakah teks mengandung kata kotor
149
- - `matches`: Array kata kotor yang ditemukan
150
- - `matchDetails`: Array objek kata kotor dengan metadata
151
- - `categories`: Kategori kata kotor yang ditemukan
152
- - `regions`: Daerah asal kata kotor yang ditemukan
153
- - `severityScore`: Skor keparahan (0-1)
154
- - `similarWords`: Kata-kata yang mirip dengan kata kotor (jika deteksi kesamaan diaktifkan)
155
-
156
- ##### `batchAnalyze(texts: string[])`
157
-
158
- Menganalisis batch teks sekaligus dan memberikan ringkasan.
159
-
160
- - **Hasil**: Objek yang berisi ringkasan analisis
161
-
162
- ##### `analyzeBySentence(text: string)`
163
-
164
- Menganalisis teks per-kalimat.
165
-
166
- - **Hasil**: Array dari hasil analisis per-kalimat
167
-
168
- ##### `analyzeWithContext(text: string, contextWindowSize?: number)`
90
+ import IDProfanityFilter from '@sideid/id-profanity-filter';
169
91
 
170
- Menganalisis teks dengan konteks di sekitar kata kotor.
92
+ const filter = new IDProfanityFilter();
171
93
 
172
- - **Hasil**: Array dari kata kotor dengan konteks di sekitarnya
94
+ // Gunakan preset childSafe dengan grawlix acak
95
+ filter.usePreset('childSafe', { useRandomGrawlix: true });
173
96
 
174
- ##### `usePreset(presetName: string, additionalOptions?: Partial<FilterOptions>)`
97
+ const hasil = filter.filter('Dasar anjing kamu!');
98
+ console.log(hasil.filtered);
99
+ // Output: "Dasar #@$%& kamu!"
100
+ ```
175
101
 
176
- Menggunakan preset filter yang telah ditentukan.
102
+ ## Dokumentasi API
177
103
 
178
- - **presetName**: Nama preset ('strict', 'moderate', 'light', 'childSafe', dll)
179
- - **additionalOptions**: Opsi tambahan untuk override preset (opsional)
104
+ ### Kelas `IDProfanityFilter`
180
105
 
181
- ##### `setOptions(options: Partial<FilterOptions>)`
106
+ #### `constructor(options?: FilterOptions)`
107
+ Membuat instance filter baru dengan opsi default atau kustom.
182
108
 
183
- Mengubah opsi filter.
109
+ #### `filter(text: string): FilterResult`
110
+ Menyensor kata kotor dalam teks. Mengembalikan objek:
111
+ - `filtered`: string hasil sensor
112
+ - `censored`: jumlah kata yang disensor
113
+ - `replacements`: daftar objek penggantian (`original`, `censored`, `metadata`)
184
114
 
185
- ##### `setWordList(wordList: string[])`
115
+ #### `isProfane(text: string): boolean`
116
+ Mengembalikan `true` jika teks mengandung kata kotor.
186
117
 
187
- Menetapkan daftar kata kustom.
118
+ #### `analyze(text: string): AnalysisResult`
119
+ Menganalisis teks secara menyeluruh. Mengembalikan objek:
120
+ - `hasProfanity`: boolean
121
+ - `matches`: string kata kotor yang cocok
122
+ - `matchDetails`: array objek `ProfanityWord` lengkap
123
+ - `categories`: kategori unik yang ditemukan
124
+ - `regions`: daerah asal kata yang ditemukan
125
+ - `severityScore`: skor keparahan kata (0 - 1)
126
+ - `similarWords`: kata yang mirip (jika `detectSimilarity` aktif)
188
127
 
189
- ##### `addToWhitelist(word: string)`
128
+ #### `batchAnalyze(texts: string[])`
129
+ Menganalisis kumpulan teks sekaligus dan mengembalikan statistik agregat (total kata, teks bersih, rata-rata keparahan, kata paling sering muncul).
190
130
 
191
- Menambahkan kata ke whitelist (akan diabaikan dalam filter).
131
+ #### `analyzeBySentence(text: string)`
132
+ Memecah teks per kalimat dan menganalisis masing-masing kalimat secara independen.
192
133
 
193
- ##### `removeFromWhitelist(word: string)`
134
+ #### `analyzeWithContext(text: string, contextWindowSize: number = 5)`
135
+ Mengambil kata kotor beserta konteks kata-kata di sekitarnya.
194
136
 
195
- Menghapus kata dari whitelist.
137
+ #### `setOptions(options: Partial<FilterOptions>)`
138
+ Memperbarui konfigurasi filter yang sedang berjalan.
196
139
 
197
- ##### `enableIndonesianVariations()`
140
+ #### `resetOptions(options: FilterOptions = {})`
141
+ Mengembalikan konfigurasi filter ke opsi default (dapat ditimpa dengan opsi baru).
198
142
 
199
- Mengaktifkan deteksi variasi ejaan Bahasa Indonesia.
143
+ #### `usePreset(presetName: string, additionalOptions?: Partial<FilterOptions>)`
144
+ Menerapkan preset filter (`strict`, `moderate`, `light`, `childSafe`).
200
145
 
201
- ##### `enableSplitWordDetection()`
146
+ #### `setWordList(wordList: string[])`
147
+ Mengatur daftar kata kustom yang akan digunakan oleh filter.
202
148
 
203
- Mengaktifkan deteksi kata yang dipisah.
149
+ #### `addToWhitelist(word: string)` / `removeFromWhitelist(word: string)`
150
+ Menambahkan atau menghapus kata dari whitelist pengecualian.
204
151
 
205
- ##### `enableSimilarityDetection(threshold: number = 0.8, useLevenshtein: boolean = false, maxLevenshteinDistance: number = 2)`
152
+ #### `enableIndonesianVariations()`
153
+ Mengaktifkan deteksi variasi ejaan bahasa Indonesia (misalnya ejaan lama atau substitusi huruf lazim).
206
154
 
207
- Mengaktifkan deteksi berdasarkan kesamaan kata.
155
+ #### `enableSplitWordDetection()`
156
+ Mengaktifkan deteksi kata yang dipisah dengan spasi atau tanda baca (contoh: `a-n-j-i-n-g`).
208
157
 
209
- - **threshold**: Ambang batas kesamaan (0-1, default: 0.8)
210
- - **useLevenshtein**: Gunakan algoritma Levenshtein untuk deteksi (default: false)
211
- - **maxLevenshteinDistance**: Jarak edit maksimum yang diizinkan (default: 2)
158
+ #### `enableSimilarityDetection(threshold = 0.8, useLevenshtein = false, maxDistance = 2)`
159
+ Mengaktifkan deteksi kemiripan kata untuk menangkap typo atau variasi penulisan.
212
160
 
213
- ##### `enableLevenshteinDetection(threshold: number = 0.8, maxDistance: number = 2)`
161
+ ### Opsi Filter (`FilterOptions`)
214
162
 
215
- Mengaktifkan deteksi berbasis jarak Levenshtein.
163
+ | Properti | Tipe | Default | Deskripsi |
164
+ |---|---|---|---|
165
+ | `replaceWith` | `string` | `'*'` | Karakter pengganti kata yang disensor |
166
+ | `fullWordCensor` | `boolean` | `true` | Sensor seluruh karakter kata |
167
+ | `keepFirstAndLast` | `boolean` | `false` | Pertahankan huruf pertama dan terakhir saat sensor (`a****g`) |
168
+ | `useRandomGrawlix` | `boolean` | `false` | Gunakan karakter simbol acak (`#@$%&!`) |
169
+ | `detectLeetSpeak` | `boolean` | `true` | Deteksi variasi angka/simbol (`b4b1`, `4nj1ng`) |
170
+ | `detectSplit` | `boolean` | `false` | Deteksi kata dengan pemisah (`b-a-b-i`) |
171
+ | `indonesianVariation` | `boolean` | `false` | Deteksi variasi ejaan Indonesia |
172
+ | `detectSimilarity` | `boolean` | `false` | Deteksi kata typo atau mirip |
173
+ | `similarityThreshold` | `number` | `0.8` | Batas minimum kemiripan (0 - 1) |
174
+ | `useLevenshtein` | `boolean` | `false` | Gunakan algoritma Levenshtein distance |
175
+ | `maxLevenshteinDistance` | `number` | `2` | Jarak edit maksimum Levenshtein |
176
+ | `checkSubstring` | `boolean` | `false` | Deteksi kata kotor di dalam substring kata lain |
177
+ | `wordList` | `string[]` | `[]` | Daftar kata kustom (menggantikan daftar bawaan) |
178
+ | `whitelist` | `string[]` | `[]` | Daftar kata yang diabaikan dari filter |
179
+ | `categories` | `ProfanityCategory[]` | - | Filter hanya kategori tertentu |
180
+ | `regions` | `Region[]` | - | Filter hanya daerah tertentu |
181
+ | `severityThreshold` | `number` | `0` | Batas keparahan minimum kata (0 - 1) |
216
182
 
217
- - **threshold**: Ambang batas kesamaan (0-1, default: 0.8)
218
- - **maxDistance**: Jarak edit maksimum yang diizinkan (default: 2)
183
+ ## Contoh penggunaan lanjutan
219
184
 
220
- ### Opsi Filter
185
+ ### Daftar kata kustom
221
186
 
222
187
  ```typescript
223
- interface FilterOptions {
224
- // Opsi dasar
225
- wordList?: string[]; // List kata yang ingin difilter
226
- replaceWith?: string; // Karakter pengganti untuk kata yang disensor
227
- fullWordCensor?: boolean; // Apakah menyensor seluruh kata atau sebagian
228
- detectLeetSpeak?: boolean; // Deteksi variasi penulisan (mis: a=4, e=3)
229
- whitelist?: string[]; // Kata-kata yang dikecualikan dari filter
230
- checkSubstring?: boolean; // Memeriksa substring (lebih ketat)
231
- categories?: ProfanityCategory[]; // Kategori kata yang difilter
232
- regions?: Region[]; // Daerah asal kata yang difilter
233
- severityThreshold?: number; // Tingkat keparahan minimum (0-1)
234
-
235
- // Opsi lanjutan
236
- useRandomGrawlix?: boolean; // Gunakan karakter acak untuk sensor (#@$%&!)
237
- keepFirstAndLast?: boolean; // Simpan huruf pertama dan terakhir (a***g)
238
- indonesianVariation?: boolean; // Deteksi variasi ejaan Bahasa Indonesia
239
- detectSimilarity?: boolean; // Deteksi kata berdasarkan kesamaan
240
- similarityThreshold?: number; // Ambang batas kesamaan (0-1)
241
- detectSplit?: boolean; // Deteksi kata yang dipisah (a-n-j-i-n-g)
242
- useLevenshtein?: boolean; // Gunakan algoritma Levenshtein untuk deteksi kesamaan
243
- maxLevenshteinDistance?: number; // Jarak edit maksimum untuk deteksi Levenshtein
244
- }
245
- ```
246
-
247
- ## Preset Filter
248
-
249
- Library ini menyediakan beberapa preset yang dapat digunakan:
250
-
251
- ### Preset Filter
252
-
253
- - **strict**: Filter paling ketat, mendeteksi semua jenis kata kotor
254
- - **moderate**: Filter tingkat menengah, mengabaikan kata-kata dengan tingkat keparahan rendah
255
- - **light**: Filter ringan, hanya untuk kata-kata paling sensitif
256
- - **childSafe**: Filter untuk konten anak-anak, sangat ketat
257
-
258
- ### Preset Kategori
259
-
260
- - **sexual**: Hanya memfilter kata-kata berbau seksual
261
- - **insults**: Hanya memfilter kata-kata penghinaan
262
- - **profanity**: Hanya memfilter umpatan umum
263
-
264
- ### Preset Regional
265
-
266
- - **general**: Hanya memfilter kata-kata umum di Indonesia
267
- - **jawa**: Hanya memfilter kata-kata dari Jawa
268
- - **sunda**: Hanya memfilter kata-kata dari Sunda
269
- - **betawi**: Hanya memfilter kata-kata dari Betawi
270
- - **batak**: Hanya memfilter kata-kata dari Batak
271
-
272
- ## Contoh Penggunaan Lanjutan
273
-
274
- ### Kustomisasi Opsi Filter
188
+ import IDProfanityFilter from '@sideid/id-profanity-filter';
275
189
 
276
- ```typescript
277
190
  const filter = new IDProfanityFilter({
278
- replaceWith: '#', // Menggunakan # sebagai karakter pengganti
279
- fullWordCensor: false, // Hanya menyensor sebagian kata
280
- detectLeetSpeak: true, // Mendeteksi variasi seperti "b4b1" untuk "babi"
281
- categories: ['sexual', 'slur'], // Hanya filter kategori tertentu
282
- regions: ['jawa', 'general'], // Hanya filter dari daerah tertentu
283
- severityThreshold: 0.7, // Hanya filter kata dengan tingkat keparahan ≥ 0.7
284
-
285
- // Opsi lanjutan
286
- useRandomGrawlix: true, // Gunakan #@$%&! sebagai karakter pengganti
287
- keepFirstAndLast: true, // Simpan huruf pertama dan terakhir (a***g)
288
- indonesianVariation: true, // Deteksi variasi ejaan Indonesia
289
- detectSimilarity: true, // Deteksi kata yang mirip
290
- similarityThreshold: 0.8, // Ambang batas kesamaan
291
- detectSplit: true, // Deteksi kata yang dipisah
292
- useLevenshtein: true, // Gunakan algoritma Levenshtein
293
- maxLevenshteinDistance: 2, // Jarak Levenshtein maksimum
191
+ wordList: ['jelek', 'payah', 'curang'],
192
+ replaceWith: '#',
294
193
  });
295
- ```
296
-
297
- ### Menggunakan Whitelist
298
-
299
- ```typescript
300
- const filter = new IDProfanityFilter();
301
-
302
- // Menambahkan kata ke whitelist (akan diabaikan)
303
- filter.addToWhitelist('anjing');
304
194
 
305
- const teks =
306
- 'Anjing itu hewan peliharaan yang setia, tidak seperti bajingan itu';
195
+ const teks = 'Kualitas layanannya sangat jelek dan payah!';
307
196
  const hasil = filter.filter(teks);
308
197
 
309
198
  console.log(hasil.filtered);
310
- // Output: "Anjing itu hewan peliharaan yang setia, tidak seperti ******* itu"
311
- ```
312
-
313
- ### Deteksi Variasi Ejaan dan Kata Terpisah
314
-
315
- ```typescript
316
- // Aktifkan deteksi variasi ejaan dan kata terpisah
317
- const filter = new IDProfanityFilter({
318
- indonesianVariation: true,
319
- detectSplit: true,
320
- detectLeetSpeak: true,
321
- });
322
-
323
- // Uji dengan variasi ejaan
324
- const teks1 = 'Dasar kamu ini sangat bodoh, benar-benar b0d0h dan b-o-d-o-h!';
325
- const hasil1 = filter.filter(teks1);
326
- console.log(hasil1.filtered);
327
- // Output: "Dasar kamu ini sangat *****, benar-benar ***** dan *********!"
328
-
329
- // Uji dengan ejaan Indonesia yang berbeda
330
- const teks2 = 'Dia sangat djail dan djudes dengan temannya';
331
- const hasil2 = filter.filter(teks2);
332
- console.log(hasil2.filtered);
333
- // Output: "Dia sangat ***** dan ****** dengan temannya"
199
+ // Output: "Kualitas layanannya sangat ##### dan #####!"
334
200
  ```
335
201
 
336
- ### Deteksi Berdasarkan Kesamaan (Similarity Detection)
202
+ ### Deteksi typo dan Levenshtein distance
337
203
 
338
204
  ```typescript
339
- // Aktifkan deteksi kesamaan standar
340
- const filter = new IDProfanityFilter();
341
- filter.enableSimilarityDetection(0.75); // Set threshold kesamaan ke 0.75
342
-
343
- const teks = 'Dia benar-benar anjiing dan gooblok!';
344
- const analisis = filter.analyze(teks);
345
-
346
- console.log(analisis.similarWords);
347
- /* Output:
348
- [
349
- { word: "anjiing", original: "anjing", similarity: 0.83 },
350
- { word: "gooblok", original: "goblok", similarity: 0.85 }
351
- ]
352
- */
353
-
354
- const hasil = filter.filter(teks);
355
- console.log(hasil.filtered);
356
- // Output: "Dia benar-benar ****** dan *******!"
357
- ```
358
-
359
- ### Deteksi dengan Algoritma Levenshtein Distance
205
+ import IDProfanityFilter from '@sideid/id-profanity-filter';
360
206
 
361
- ```typescript
362
- // Aktifkan deteksi menggunakan algoritma Levenshtein Distance
363
207
  const filter = new IDProfanityFilter();
364
- filter.enableLevenshteinDetection(0.85, 2);
365
- // Threshold 0.85, maksimal 2 karakter berbeda
208
+ filter.enableLevenshteinDetection(0.8, 2);
366
209
 
367
- const teks = 'Dia benar-benar konntol dan anjiing sekali!';
210
+ const teks = 'Dia benar-benar anjiing sekali!';
368
211
  const hasil = filter.filter(teks);
369
212
 
370
213
  console.log(hasil.filtered);
371
- // Output: "Dia benar-benar ******* dan ****** sekali!"
372
-
373
- // Atau menggunakan opsi langsung:
374
- const filterCustom = new IDProfanityFilter({
375
- detectSimilarity: true,
376
- useLevenshtein: true,
377
- similarityThreshold: 0.85,
378
- maxLevenshteinDistance: 2,
379
- });
380
-
381
- // Mendeteksi typo atau variasi disengaja
382
- const teksVariasi = 'kontool kamu kwontol anjiing';
383
- console.log(filterCustom.filter(teksVariasi).filtered);
384
- // Output: "******* kamu ******* ******"
214
+ // Output: "Dia benar-benar ******* sekali!"
385
215
  ```
386
216
 
387
- ### Variasi Sensor Kata
217
+ ### Whitelist kontekstual
388
218
 
389
219
  ```typescript
390
- // Sensor standar (asterisk)
391
- const filter1 = new IDProfanityFilter();
392
- console.log(filter1.filter('Dasar anjing kamu!').filtered);
393
- // Output: "Dasar ***** kamu!"
394
-
395
- // Sensor dengan grawlix random
396
- const filter2 = new IDProfanityFilter({ useRandomGrawlix: true });
397
- console.log(filter2.filter('Dasar anjing kamu!').filtered);
398
- // Output: "Dasar #@$%& kamu!"
399
-
400
- // Sensor dengan menyimpan huruf pertama dan terakhir
401
- const filter3 = new IDProfanityFilter({
402
- fullWordCensor: false,
403
- keepFirstAndLast: true,
404
- });
405
- console.log(filter3.filter('Dasar anjing kamu!').filtered);
406
- // Output: "Dasar a***g kamu!"
407
- ```
408
-
409
- ### Analisis Konten Mendalam
220
+ import IDProfanityFilter from '@sideid/id-profanity-filter';
410
221
 
411
- ```typescript
412
222
  const filter = new IDProfanityFilter();
413
- const teks = 'Dasar anjing sialan! Kamu ini memang bego dan goblok.';
414
-
415
- // Analisis teks
416
- const analisis = filter.analyze(teks);
417
- console.log(analisis);
418
-
419
- /* Output:
420
- {
421
- hasProfanity: true,
422
- matches: ['anjing', 'sialan', 'bego', 'goblok'],
423
- matchDetails: [
424
- { word: 'anjing', category: 'profanity', region: 'general', severity: 0.7, ... },
425
- { word: 'bego', category: 'insult', region: 'general', severity: 0.5, ... },
426
- ...
427
- ],
428
- categories: ['profanity', 'insult'],
429
- regions: ['general'],
430
- severityScore: 0.64
431
- }
432
- */
433
- ```
434
-
435
- ### Analisis Konteks
223
+ filter.addToWhitelist('anjing');
436
224
 
437
- ```typescript
438
- const filter = new IDProfanityFilter();
439
- const teks =
440
- 'Saya sangat marah dengan sikapnya, dia benar-benar anjing dan bajingan!';
441
-
442
- // Analisis konteks
443
- const konteks = filter.analyzeWithContext(teks, 3);
444
- console.log(konteks);
445
-
446
- /* Output:
447
- [
448
- {
449
- word: "anjing",
450
- context: "benar-benar anjing dan bajingan",
451
- position: { start: 43, end: 62 }
452
- },
453
- {
454
- word: "bajingan",
455
- context: "anjing dan bajingan!",
456
- position: { start: 54, end: 63 }
457
- }
458
- ]
459
- */
225
+ const teks = 'Anjing peliharaan saya setia sekali.';
226
+ console.log(filter.isProfane(teks)); // false
460
227
  ```
461
228
 
462
- ### Analisis Per-Kalimat
229
+ ### Analisis per kalimat
463
230
 
464
231
  ```typescript
465
- const filter = new IDProfanityFilter();
466
- const teks =
467
- 'Filmnya bagus sekali. Tetapi pemainnya seperti anjing, sangat buruk aktingnya.';
468
-
469
- // Analisis per-kalimat
470
- const kalimat = filter.analyzeBySentence(teks);
471
- console.log(
472
- kalimat.map(
473
- (k) =>
474
- k.sentence + (k.hasProfanity ? ' (Mengandung kata kotor)' : ' (Bersih)'),
475
- ),
476
- );
477
-
478
- /* Output:
479
- [
480
- "Filmnya bagus sekali. (Bersih)",
481
- "Tetapi pemainnya seperti anjing, sangat buruk aktingnya. (Mengandung kata kotor)"
482
- ]
483
- */
484
- ```
485
-
486
- ### Analisis Batch
232
+ import IDProfanityFilter from '@sideid/id-profanity-filter';
487
233
 
488
- ```typescript
489
234
  const filter = new IDProfanityFilter();
490
- const komentar = [
491
- 'Film ini sangat bagus, ceritanya menarik sekali!',
492
- 'Dasar goblok, sialan kamu!',
493
- 'Anjing emang filmnya, sampah banget.',
494
- ];
495
-
496
- const hasil = filter.batchAnalyze(komentar);
497
- console.log(hasil);
498
-
499
- /* Output:
500
- {
501
- totalTexts: 3,
502
- profaneTexts: 2,
503
- cleanTexts: 1,
504
- averageSeverity: 0.62,
505
- topCategories: ['profanity', 'insult'],
506
- topRegions: ['general'],
507
- mostFrequentWords: [
508
- { word: 'anjing', count: 1 },
509
- { word: 'goblok', count: 1 },
510
- { word: 'sialan', count: 1 },
511
- { word: 'sampah', count: 1 }
512
- ]
513
- }
514
- */
515
- ```
516
-
517
- ## Dukungan Regional
518
-
519
- Library ini mendukung kata-kata kotor dari berbagai daerah di Indonesia:
520
-
521
- - 🇮🇩 **General** - Kata-kata yang umum di seluruh Indonesia
522
- - 🏝️ **Jawa** - Kata-kata dari bahasa Jawa
523
- - 🏞️ **Sunda** - Kata-kata dari bahasa Sunda
524
- - 🏙️ **Betawi** - Kata-kata dari bahasa Betawi
525
- - 🌋 **Batak** - Kata-kata dari bahasa Batak
526
-
527
- ## Kategori Kata
235
+ const teks = 'Filmnya bagus sekali. Tapi pemainnya seperti anjing, aktingnya buruk.';
528
236
 
529
- Kata-kata dikelompokkan berdasarkan kategori:
530
-
531
- - `sexual`: Kata-kata berbau seksual
532
- - `insult`: Kata-kata penghinaan
533
- - `profanity`: Umpatan umum
534
- - `slur`: Perkataan merendahkan berdasarkan identitas
535
- - `drugs`: Terkait narkoba
536
- - `disgusting`: Kata-kata menjijikkan
537
- - `blasphemy`: Penistaan agama
538
-
539
- ## Berkontribusi
237
+ const hasilKalimat = filter.analyzeBySentence(teks);
238
+ hasilKalimat.forEach((item) => {
239
+ console.log(`${item.sentence} -> ${item.hasProfanity ? 'Kotor' : 'Bersih'}`);
240
+ });
241
+ // "Filmnya bagus sekali." -> Bersih
242
+ // "Tapi pemainnya seperti anjing, aktingnya buruk." -> Kotor
243
+ ```
540
244
 
541
- Kami sangat menghargai kontribusi Anda! Untuk berkontribusi, silakan lihat [panduan kontribusi](CONTRIBUTING.md).
245
+ ## Cakupan daerah dan kategori
542
246
 
543
- ### Menambahkan Kata Baru
247
+ ### Bahasa daerah
248
+ - `general`: Bahasa Indonesia umum
249
+ - `jawa`: Bahasa Jawa
250
+ - `sunda`: Bahasa Sunda
251
+ - `betawi`: Dialek Betawi
252
+ - `batak`: Bahasa Batak
253
+ - `minang`: Bahasa Minang
254
+ - `bali`: Bahasa Bali
255
+ - `madura`: Bahasa Madura
256
+ - `aceh`: Bahasa Aceh
544
257
 
545
- 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/`.
258
+ ### Kategori kata
259
+ - `sexual`: Istilah atau aktivitas seksual vulgar
260
+ - `insult`: Penghinaan atau caci maki
261
+ - `profanity`: Umpatan kasar umum
262
+ - `slur`: Kata merendahkan SARA / identitas
263
+ - `drugs`: Istilah obat-obatan terlarang
264
+ - `disgusting`: Kata jorok atau menjijikkan
265
+ - `blasphemy`: Umpatan penistaan agama
546
266
 
547
- Format untuk menambahkan kata baru:
267
+ ## Kontribusi
548
268
 
549
- ```json
550
- {
551
- "word": "kata_kotor", // Kata yang akan difilter
552
- "category": "insult", // Kategori kata
553
- "region": "general", // Daerah asal kata
554
- "severity": 0.7, // Tingkat keparahan (0-1)
555
- "aliases": ["k4t4_kotor", "kata_k0t0r"], // Alias atau variasi umum
556
- "description": "Deskripsi tentang kata", // Penjelasan tentang kata (opsional)
557
- "context": "Konteks penggunaan kata" // Konteks penggunaan (opsional)
558
- }
559
- ```
269
+ Panduan untuk menambahkan kata baru atau mengembangkan library dapat dilihat di [CONTRIBUTING.md](CONTRIBUTING.md).
560
270
 
561
271
  ## Lisensi
562
272
 
563
- Proyek ini dilisensikan di bawah [MIT License](LICENSE).
564
-
565
- ## Kontak & Dukungan
566
-
567
- Jika Anda memiliki pertanyaan atau saran, silakan buka issue di repositori GitHub kami.
273
+ Proyek ini menggunakan lisensi [MIT](LICENSE).