@indodev/toolkit 0.1.5 → 0.3.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 +91 -183
- package/dist/compare-BIodyGn7.d.cts +991 -0
- package/dist/compare-BIodyGn7.d.ts +991 -0
- package/dist/currency/index.cjs +23 -0
- package/dist/currency/index.cjs.map +1 -1
- package/dist/currency/index.d.cts +367 -3
- package/dist/currency/index.d.ts +367 -3
- package/dist/currency/index.js +21 -1
- package/dist/currency/index.js.map +1 -1
- package/dist/index.cjs +2025 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +110 -3
- package/dist/index.d.ts +110 -3
- package/dist/index.js +1990 -1
- package/dist/index.js.map +1 -1
- package/dist/nik/index.cjs +44 -0
- package/dist/nik/index.cjs.map +1 -1
- package/dist/nik/index.d.cts +44 -1
- package/dist/nik/index.d.ts +44 -1
- package/dist/nik/index.js +41 -1
- package/dist/nik/index.js.map +1 -1
- package/dist/phone/index.cjs +42 -0
- package/dist/phone/index.cjs.map +1 -1
- package/dist/phone/index.d.cts +57 -1
- package/dist/phone/index.d.ts +57 -1
- package/dist/phone/index.js +39 -1
- package/dist/phone/index.js.map +1 -1
- package/dist/text/index.cjs +1726 -0
- package/dist/text/index.cjs.map +1 -0
- package/dist/text/index.d.cts +284 -0
- package/dist/text/index.d.ts +284 -0
- package/dist/text/index.js +1705 -0
- package/dist/text/index.js.map +1 -0
- package/package.json +54 -17
- package/LICENCE +0 -21
- package/dist/words-Dy8iYkbv.d.cts +0 -333
- package/dist/words-Dy8iYkbv.d.ts +0 -333
package/dist/index.js
CHANGED
|
@@ -208,6 +208,46 @@ function maskNIK(nik, options = {}) {
|
|
|
208
208
|
return startPart + char.repeat(maskLength) + endPart;
|
|
209
209
|
}
|
|
210
210
|
|
|
211
|
+
// src/nik/utils.ts
|
|
212
|
+
function getAge(nik, referenceDate = /* @__PURE__ */ new Date()) {
|
|
213
|
+
const info = parseNIK(nik);
|
|
214
|
+
if (!info || !info.birthDate) {
|
|
215
|
+
return null;
|
|
216
|
+
}
|
|
217
|
+
const birthDate = info.birthDate;
|
|
218
|
+
let age = referenceDate.getFullYear() - birthDate.getFullYear();
|
|
219
|
+
const m = referenceDate.getMonth() - birthDate.getMonth();
|
|
220
|
+
if (m < 0 || m === 0 && referenceDate.getDate() < birthDate.getDate()) {
|
|
221
|
+
age--;
|
|
222
|
+
}
|
|
223
|
+
return age;
|
|
224
|
+
}
|
|
225
|
+
function formatBirthDate(nik, options = {
|
|
226
|
+
day: "numeric",
|
|
227
|
+
month: "long",
|
|
228
|
+
year: "numeric"
|
|
229
|
+
}, locale = "id-ID") {
|
|
230
|
+
const info = parseNIK(nik);
|
|
231
|
+
if (!info || !info.birthDate) {
|
|
232
|
+
return null;
|
|
233
|
+
}
|
|
234
|
+
return new Intl.DateTimeFormat(locale, options).format(info.birthDate);
|
|
235
|
+
}
|
|
236
|
+
function isValidForGender(nik, gender) {
|
|
237
|
+
const info = parseNIK(nik);
|
|
238
|
+
if (!info) {
|
|
239
|
+
return false;
|
|
240
|
+
}
|
|
241
|
+
return info.gender === gender;
|
|
242
|
+
}
|
|
243
|
+
function isValidForBirthDate(nik, birthDate) {
|
|
244
|
+
const info = parseNIK(nik);
|
|
245
|
+
if (!info || !info.birthDate) {
|
|
246
|
+
return false;
|
|
247
|
+
}
|
|
248
|
+
return info.birthDate.getFullYear() === birthDate.getFullYear() && info.birthDate.getMonth() === birthDate.getMonth() && info.birthDate.getDate() === birthDate.getDate();
|
|
249
|
+
}
|
|
250
|
+
|
|
211
251
|
// src/phone/constants.ts
|
|
212
252
|
var OPERATOR_PREFIXES = {
|
|
213
253
|
// Telkomsel (Halo, Simpati, by.U)
|
|
@@ -850,6 +890,37 @@ function maskPhoneNumber(phone, options = {}) {
|
|
|
850
890
|
return masked;
|
|
851
891
|
}
|
|
852
892
|
|
|
893
|
+
// src/phone/links.ts
|
|
894
|
+
function generateWALink(phone, message) {
|
|
895
|
+
if (!validatePhoneNumber(phone)) {
|
|
896
|
+
return "";
|
|
897
|
+
}
|
|
898
|
+
const e164 = toE164(phone);
|
|
899
|
+
let link = `https://wa.me/${e164}`;
|
|
900
|
+
if (message) {
|
|
901
|
+
link += `?text=${encodeURIComponent(message)}`;
|
|
902
|
+
}
|
|
903
|
+
return link;
|
|
904
|
+
}
|
|
905
|
+
function generateSmsLink(phone, body) {
|
|
906
|
+
if (!validatePhoneNumber(phone)) {
|
|
907
|
+
return "";
|
|
908
|
+
}
|
|
909
|
+
const e164 = toE164(phone);
|
|
910
|
+
let link = `sms:+${e164}`;
|
|
911
|
+
if (body) {
|
|
912
|
+
link += `?body=${encodeURIComponent(body)}`;
|
|
913
|
+
}
|
|
914
|
+
return link;
|
|
915
|
+
}
|
|
916
|
+
function generateTelLink(phone) {
|
|
917
|
+
if (!validatePhoneNumber(phone)) {
|
|
918
|
+
return "";
|
|
919
|
+
}
|
|
920
|
+
const e164 = toE164(phone);
|
|
921
|
+
return `tel:+${e164}`;
|
|
922
|
+
}
|
|
923
|
+
|
|
853
924
|
// src/phone/parse.ts
|
|
854
925
|
function parsePhoneNumber(phone) {
|
|
855
926
|
if (!validatePhoneNumber(phone)) {
|
|
@@ -898,6 +969,13 @@ function getOperator(phone) {
|
|
|
898
969
|
const prefix = normalized.substring(0, 4);
|
|
899
970
|
return OPERATOR_PREFIXES[prefix] || null;
|
|
900
971
|
}
|
|
972
|
+
function isProvider(phone, providerName) {
|
|
973
|
+
const operator = getOperator(phone);
|
|
974
|
+
if (!operator) {
|
|
975
|
+
return false;
|
|
976
|
+
}
|
|
977
|
+
return operator.toLowerCase() === providerName.toLowerCase();
|
|
978
|
+
}
|
|
901
979
|
function getRegion(phone) {
|
|
902
980
|
if (!phone.startsWith("0")) {
|
|
903
981
|
return null;
|
|
@@ -923,6 +1001,184 @@ function normalizeToNational2(phone) {
|
|
|
923
1001
|
return "";
|
|
924
1002
|
}
|
|
925
1003
|
|
|
1004
|
+
// src/npwp/validate.ts
|
|
1005
|
+
function validateNPWP(npwp) {
|
|
1006
|
+
if (!npwp || typeof npwp !== "string") {
|
|
1007
|
+
return false;
|
|
1008
|
+
}
|
|
1009
|
+
const cleaned = npwp.replace(/[^\d]/g, "");
|
|
1010
|
+
if (cleaned.length !== 15 && cleaned.length !== 16) {
|
|
1011
|
+
return false;
|
|
1012
|
+
}
|
|
1013
|
+
if (!/^\d+$/.test(cleaned)) {
|
|
1014
|
+
return false;
|
|
1015
|
+
}
|
|
1016
|
+
return true;
|
|
1017
|
+
}
|
|
1018
|
+
|
|
1019
|
+
// src/npwp/format.ts
|
|
1020
|
+
function formatNPWP(npwp) {
|
|
1021
|
+
if (!validateNPWP(npwp)) {
|
|
1022
|
+
return npwp;
|
|
1023
|
+
}
|
|
1024
|
+
const cleaned = npwp.replace(/[^\d]/g, "");
|
|
1025
|
+
if (cleaned.length === 15) {
|
|
1026
|
+
return `${cleaned.substring(0, 2)}.${cleaned.substring(
|
|
1027
|
+
2,
|
|
1028
|
+
5
|
|
1029
|
+
)}.${cleaned.substring(5, 8)}.${cleaned.substring(8, 9)}-${cleaned.substring(
|
|
1030
|
+
9,
|
|
1031
|
+
12
|
|
1032
|
+
)}.${cleaned.substring(12, 15)}`;
|
|
1033
|
+
}
|
|
1034
|
+
return cleaned;
|
|
1035
|
+
}
|
|
1036
|
+
function parseNPWP(npwp) {
|
|
1037
|
+
if (!validateNPWP(npwp)) {
|
|
1038
|
+
return null;
|
|
1039
|
+
}
|
|
1040
|
+
const cleaned = npwp.replace(/[^\d]/g, "");
|
|
1041
|
+
const isNikBased = cleaned.length === 16;
|
|
1042
|
+
if (isNikBased) {
|
|
1043
|
+
return {
|
|
1044
|
+
npwp: cleaned,
|
|
1045
|
+
type: cleaned.substring(0, 2),
|
|
1046
|
+
serial: cleaned.substring(2, 8),
|
|
1047
|
+
checksum: cleaned.substring(8, 9),
|
|
1048
|
+
taxOfficeCode: cleaned.substring(9, 12),
|
|
1049
|
+
branchCode: cleaned.substring(12, 16),
|
|
1050
|
+
isNikBased: true
|
|
1051
|
+
};
|
|
1052
|
+
}
|
|
1053
|
+
return {
|
|
1054
|
+
npwp: cleaned,
|
|
1055
|
+
type: cleaned.substring(0, 2),
|
|
1056
|
+
serial: cleaned.substring(2, 8),
|
|
1057
|
+
checksum: cleaned.substring(8, 9),
|
|
1058
|
+
taxOfficeCode: cleaned.substring(9, 12),
|
|
1059
|
+
branchCode: cleaned.substring(12, 15),
|
|
1060
|
+
isNikBased: false
|
|
1061
|
+
};
|
|
1062
|
+
}
|
|
1063
|
+
function maskNPWP(npwp, options) {
|
|
1064
|
+
if (!npwp) return "";
|
|
1065
|
+
const { visibleStart = 2, visibleEnd = 3, maskChar = "*" } = options || {};
|
|
1066
|
+
if (npwp.includes(".") || npwp.includes("-")) {
|
|
1067
|
+
let digitCount = 0;
|
|
1068
|
+
const digitsOnly = npwp.replace(/[^\d]/g, "");
|
|
1069
|
+
const totalDigits = digitsOnly.length;
|
|
1070
|
+
return npwp.split("").map((char) => {
|
|
1071
|
+
if (/\d/.test(char)) {
|
|
1072
|
+
digitCount++;
|
|
1073
|
+
if (digitCount <= visibleStart || digitCount > totalDigits - visibleEnd) {
|
|
1074
|
+
return char;
|
|
1075
|
+
}
|
|
1076
|
+
return maskChar;
|
|
1077
|
+
}
|
|
1078
|
+
return char;
|
|
1079
|
+
}).join("");
|
|
1080
|
+
}
|
|
1081
|
+
const cleaned = npwp.replace(/[^\d]/g, "");
|
|
1082
|
+
if (cleaned.length < visibleStart + visibleEnd) {
|
|
1083
|
+
return cleaned.replace(/./g, maskChar);
|
|
1084
|
+
}
|
|
1085
|
+
const start = cleaned.substring(0, visibleStart);
|
|
1086
|
+
const end = cleaned.substring(cleaned.length - visibleEnd);
|
|
1087
|
+
const middle = maskChar.repeat(cleaned.length - visibleStart - visibleEnd);
|
|
1088
|
+
return `${start}${middle}${end}`;
|
|
1089
|
+
}
|
|
1090
|
+
|
|
1091
|
+
// src/plate/regions.ts
|
|
1092
|
+
var PLATE_REGIONS = {
|
|
1093
|
+
A: "Banten",
|
|
1094
|
+
B: "Jakarta, Depok, Tangerang, Bekasi",
|
|
1095
|
+
D: "Bandung, Cimahi",
|
|
1096
|
+
E: "Cirebon, Indramayu, Majalengka, Kuningan",
|
|
1097
|
+
F: "Bogor, Cianjur, Sukabumi",
|
|
1098
|
+
G: "Pekalongan, Pemalang, Batang, Tegal, Brebes",
|
|
1099
|
+
H: "Semarang, Salatiga, Kendal, Demak",
|
|
1100
|
+
K: "Pati, Kudus, Jepara, Rembang, Blora, Grobogan",
|
|
1101
|
+
L: "Surabaya",
|
|
1102
|
+
M: "Madura",
|
|
1103
|
+
N: "Malang, Probolinggo, Pasuruan, Lumajang, Batu",
|
|
1104
|
+
P: "Besuki, Bondowoso, Situbondo, Jember, Banyuwangi",
|
|
1105
|
+
R: "Banyumas, Cilacap, Purbalinggo, Banjarnegara",
|
|
1106
|
+
S: "Bojonegoro, Tuban, Lamongan, Jombang, Mojokerto",
|
|
1107
|
+
T: "Purwakarta, Subang, Karawang",
|
|
1108
|
+
AA: "Kedu, Magelang, Purworejo, Kebumen, Temanggung, Wonosobo",
|
|
1109
|
+
AB: "Yogyakarta",
|
|
1110
|
+
AD: "Surakarta, Boyolali, Sukoharjo, Karanganyar, Wonogiri, Sragen, Klaten",
|
|
1111
|
+
AE: "Madiun, Ngawi, Magetan, Ponorogo, Pacitan",
|
|
1112
|
+
AG: "Kediri, Blitar, Tulungagung, Nganjuk, Trenggalek",
|
|
1113
|
+
BA: "Sumatera Barat",
|
|
1114
|
+
BB: "Sumatera Utara (Pantai Barat)",
|
|
1115
|
+
BD: "Bengkulu",
|
|
1116
|
+
BE: "Lampung",
|
|
1117
|
+
BG: "Sumatera Selatan",
|
|
1118
|
+
BH: "Jambi",
|
|
1119
|
+
BK: "Sumatera Utara (Pantai Timur)",
|
|
1120
|
+
BL: "Aceh",
|
|
1121
|
+
BM: "Riau",
|
|
1122
|
+
BN: "Kepulauan Bangka Belitung",
|
|
1123
|
+
BP: "Kepulauan Riau",
|
|
1124
|
+
DA: "Kalimantan Selatan",
|
|
1125
|
+
DB: "Sulawesi Utara (Daratan)",
|
|
1126
|
+
DC: "Sulawesi Barat",
|
|
1127
|
+
DD: "Sulawesi Selatan (Selatan)",
|
|
1128
|
+
DE: "Maluku",
|
|
1129
|
+
DF: "Timor Timur (Historical)",
|
|
1130
|
+
DG: "Maluku Utara",
|
|
1131
|
+
DH: "NTT (Timor)",
|
|
1132
|
+
DK: "Bali",
|
|
1133
|
+
DL: "Sulawesi Utara (Kepulauan)",
|
|
1134
|
+
DM: "Gorontalo",
|
|
1135
|
+
DN: "Sulawesi Tengah",
|
|
1136
|
+
DP: "Sulawesi Selatan (Utara)",
|
|
1137
|
+
DR: "NTB (Lombok)",
|
|
1138
|
+
DS: "Papua",
|
|
1139
|
+
DT: "Sulawesi Tenggara",
|
|
1140
|
+
EA: "NTB (Sumbawa)",
|
|
1141
|
+
EB: "NTT (Flores)",
|
|
1142
|
+
ED: "NTT (Sumba)",
|
|
1143
|
+
KB: "Kalimantan Barat",
|
|
1144
|
+
KH: "Kalimantan Tengah",
|
|
1145
|
+
KT: "Kalimantan Timur",
|
|
1146
|
+
KU: "Kalimantan Utara",
|
|
1147
|
+
PA: "Papua",
|
|
1148
|
+
PB: "Papua Barat"
|
|
1149
|
+
};
|
|
1150
|
+
|
|
1151
|
+
// src/plate/utils.ts
|
|
1152
|
+
function validatePlate(plate) {
|
|
1153
|
+
if (!plate || typeof plate !== "string") {
|
|
1154
|
+
return false;
|
|
1155
|
+
}
|
|
1156
|
+
const cleaned = plate.replace(/\s+/g, "").toUpperCase();
|
|
1157
|
+
const regex = /^[A-Z]{1,2}\d{1,4}[A-Z]{1,3}$/;
|
|
1158
|
+
return regex.test(cleaned);
|
|
1159
|
+
}
|
|
1160
|
+
function getRegionFromPlate(plate) {
|
|
1161
|
+
if (!plate || typeof plate !== "string") {
|
|
1162
|
+
return null;
|
|
1163
|
+
}
|
|
1164
|
+
const cleaned = plate.replace(/\s+/g, "").toUpperCase();
|
|
1165
|
+
const match = cleaned.match(/^([A-Z]{1,2})/);
|
|
1166
|
+
if (!match) {
|
|
1167
|
+
return null;
|
|
1168
|
+
}
|
|
1169
|
+
const prefix = match[1];
|
|
1170
|
+
return PLATE_REGIONS[prefix] || null;
|
|
1171
|
+
}
|
|
1172
|
+
function formatPlate(plate) {
|
|
1173
|
+
if (!plate) return "";
|
|
1174
|
+
const cleaned = plate.replace(/\s+/g, "").toUpperCase();
|
|
1175
|
+
const match = cleaned.match(/^([A-Z]{1,2})(\d{1,4})([A-Z]{1,3})$/);
|
|
1176
|
+
if (!match) {
|
|
1177
|
+
return cleaned;
|
|
1178
|
+
}
|
|
1179
|
+
return `${match[1]} ${match[2]} ${match[3]}`;
|
|
1180
|
+
}
|
|
1181
|
+
|
|
926
1182
|
// src/currency/format.ts
|
|
927
1183
|
function formatRupiah(amount, options) {
|
|
928
1184
|
const {
|
|
@@ -1148,6 +1404,1739 @@ function capitalize(str) {
|
|
|
1148
1404
|
return str.charAt(0).toUpperCase() + str.slice(1);
|
|
1149
1405
|
}
|
|
1150
1406
|
|
|
1151
|
-
|
|
1407
|
+
// src/currency/utils.ts
|
|
1408
|
+
function roundToClean(amount, unit = "ribu") {
|
|
1409
|
+
const divisors = {
|
|
1410
|
+
ribu: 1e3,
|
|
1411
|
+
"ratus-ribu": 1e5,
|
|
1412
|
+
juta: 1e6
|
|
1413
|
+
};
|
|
1414
|
+
const divisor = divisors[unit];
|
|
1415
|
+
return Math.round(amount / divisor) * divisor;
|
|
1416
|
+
}
|
|
1417
|
+
function formatAccounting(amount, options) {
|
|
1418
|
+
const isNegative = amount < 0;
|
|
1419
|
+
const formatted = formatRupiah(Math.abs(amount), options);
|
|
1420
|
+
if (isNegative) {
|
|
1421
|
+
return `(${formatted})`;
|
|
1422
|
+
}
|
|
1423
|
+
return formatted;
|
|
1424
|
+
}
|
|
1425
|
+
function calculateTax(amount, rate = 0.11) {
|
|
1426
|
+
return amount * rate;
|
|
1427
|
+
}
|
|
1428
|
+
function addRupiahSymbol(amount) {
|
|
1429
|
+
if (typeof amount === "number") {
|
|
1430
|
+
return `Rp ${amount.toLocaleString("id-ID")}`;
|
|
1431
|
+
}
|
|
1432
|
+
if (amount.trim().startsWith("Rp")) {
|
|
1433
|
+
return amount;
|
|
1434
|
+
}
|
|
1435
|
+
return `Rp ${amount.trim()}`;
|
|
1436
|
+
}
|
|
1437
|
+
|
|
1438
|
+
// src/text/constants.ts
|
|
1439
|
+
var LOWERCASE_WORDS = [
|
|
1440
|
+
// Indonesian prepositions (kata depan)
|
|
1441
|
+
"di",
|
|
1442
|
+
"ke",
|
|
1443
|
+
"dari",
|
|
1444
|
+
"pada",
|
|
1445
|
+
"dalam",
|
|
1446
|
+
"untuk",
|
|
1447
|
+
"dengan",
|
|
1448
|
+
"oleh",
|
|
1449
|
+
"kepada",
|
|
1450
|
+
"terhadap",
|
|
1451
|
+
"tentang",
|
|
1452
|
+
"tanpa",
|
|
1453
|
+
"hingga",
|
|
1454
|
+
"sampai",
|
|
1455
|
+
"sejak",
|
|
1456
|
+
"menuju",
|
|
1457
|
+
"melalui",
|
|
1458
|
+
// Indonesian conjunctions (kata hubung)
|
|
1459
|
+
"dan",
|
|
1460
|
+
"atau",
|
|
1461
|
+
"tetapi",
|
|
1462
|
+
"namun",
|
|
1463
|
+
"serta",
|
|
1464
|
+
"maupun",
|
|
1465
|
+
"melainkan",
|
|
1466
|
+
"sedangkan",
|
|
1467
|
+
// Indonesian articles/particles
|
|
1468
|
+
"yang",
|
|
1469
|
+
"sebagai",
|
|
1470
|
+
"adalah",
|
|
1471
|
+
"ialah",
|
|
1472
|
+
"yaitu",
|
|
1473
|
+
"bahwa",
|
|
1474
|
+
"akan",
|
|
1475
|
+
"telah",
|
|
1476
|
+
"sudah",
|
|
1477
|
+
"belum",
|
|
1478
|
+
// English articles
|
|
1479
|
+
"a",
|
|
1480
|
+
"an",
|
|
1481
|
+
"the",
|
|
1482
|
+
// English conjunctions
|
|
1483
|
+
"and",
|
|
1484
|
+
"or",
|
|
1485
|
+
"but",
|
|
1486
|
+
"nor",
|
|
1487
|
+
"for",
|
|
1488
|
+
"yet",
|
|
1489
|
+
"so",
|
|
1490
|
+
"as",
|
|
1491
|
+
// English prepositions (short ones, < 5 letters)
|
|
1492
|
+
"at",
|
|
1493
|
+
"by",
|
|
1494
|
+
"in",
|
|
1495
|
+
"of",
|
|
1496
|
+
"on",
|
|
1497
|
+
"to",
|
|
1498
|
+
"up",
|
|
1499
|
+
"via",
|
|
1500
|
+
"per",
|
|
1501
|
+
"off",
|
|
1502
|
+
"out"
|
|
1503
|
+
// English prepositions (5+ letters - optional, some style guides capitalize these)
|
|
1504
|
+
// 'about',
|
|
1505
|
+
// 'above',
|
|
1506
|
+
// 'across',
|
|
1507
|
+
// 'after',
|
|
1508
|
+
// 'among',
|
|
1509
|
+
// 'below',
|
|
1510
|
+
// 'under',
|
|
1511
|
+
// 'until',
|
|
1512
|
+
// 'with',
|
|
1513
|
+
];
|
|
1514
|
+
var ACRONYMS = [
|
|
1515
|
+
// Indonesian government & military
|
|
1516
|
+
"DKI",
|
|
1517
|
+
// Daerah Khusus Ibukota
|
|
1518
|
+
"DIY",
|
|
1519
|
+
// Daerah Istimewa Yogyakarta
|
|
1520
|
+
"TNI",
|
|
1521
|
+
// Tentara Nasional Indonesia
|
|
1522
|
+
"POLRI",
|
|
1523
|
+
// Kepolisian Republik Indonesia
|
|
1524
|
+
"ABRI",
|
|
1525
|
+
// Angkatan Bersenjata Republik Indonesia
|
|
1526
|
+
"MPR",
|
|
1527
|
+
// Majelis Permusyawaratan Rakyat
|
|
1528
|
+
"DPR",
|
|
1529
|
+
// Dewan Perwakilan Rakyat
|
|
1530
|
+
"KPK",
|
|
1531
|
+
// Komisi Pemberantasan Korupsi
|
|
1532
|
+
"BIN",
|
|
1533
|
+
// Badan Intelijen Negara
|
|
1534
|
+
// Indonesian business entities
|
|
1535
|
+
"PT",
|
|
1536
|
+
// Perseroan Terbatas
|
|
1537
|
+
"CV",
|
|
1538
|
+
// Commanditaire Vennootschap
|
|
1539
|
+
"UD",
|
|
1540
|
+
// Usaha Dagang
|
|
1541
|
+
"PD",
|
|
1542
|
+
// Perusahaan Daerah
|
|
1543
|
+
"Tbk",
|
|
1544
|
+
// Terbuka (publicly traded)
|
|
1545
|
+
"BUMN",
|
|
1546
|
+
// Badan Usaha Milik Negara
|
|
1547
|
+
"BUMD",
|
|
1548
|
+
// Badan Usaha Milik Daerah
|
|
1549
|
+
// Indonesian banks
|
|
1550
|
+
"BCA",
|
|
1551
|
+
// Bank Central Asia
|
|
1552
|
+
"BRI",
|
|
1553
|
+
// Bank Rakyat Indonesia
|
|
1554
|
+
"BNI",
|
|
1555
|
+
// Bank Negara Indonesia
|
|
1556
|
+
"BTN",
|
|
1557
|
+
// Bank Tabungan Negara
|
|
1558
|
+
"BSI",
|
|
1559
|
+
// Bank Syariah Indonesia
|
|
1560
|
+
"BPD",
|
|
1561
|
+
// Bank Pembangunan Daerah
|
|
1562
|
+
// Indonesian government services
|
|
1563
|
+
"KTP",
|
|
1564
|
+
// Kartu Tanda Penduduk
|
|
1565
|
+
"NIK",
|
|
1566
|
+
// Nomor Induk Kependudukan
|
|
1567
|
+
"NPWP",
|
|
1568
|
+
// Nomor Pokok Wajib Pajak
|
|
1569
|
+
"SIM",
|
|
1570
|
+
// Surat Izin Mengemudi
|
|
1571
|
+
"STNK",
|
|
1572
|
+
// Surat Tanda Nomor Kendaraan
|
|
1573
|
+
"BPJS",
|
|
1574
|
+
// Badan Penyelenggara Jaminan Sosial
|
|
1575
|
+
"KIS",
|
|
1576
|
+
// Kartu Indonesia Sehat
|
|
1577
|
+
"KIP",
|
|
1578
|
+
// Kartu Indonesia Pintar
|
|
1579
|
+
"PKH",
|
|
1580
|
+
// Program Keluarga Harapan
|
|
1581
|
+
// Indonesian utilities & infrastructure
|
|
1582
|
+
"PLN",
|
|
1583
|
+
// Perusahaan Listrik Negara
|
|
1584
|
+
"PDAM",
|
|
1585
|
+
// Perusahaan Daerah Air Minum
|
|
1586
|
+
"PGN",
|
|
1587
|
+
// Perusahaan Gas Negara
|
|
1588
|
+
"KAI",
|
|
1589
|
+
// Kereta Api Indonesia
|
|
1590
|
+
"MRT",
|
|
1591
|
+
// Mass Rapid Transit
|
|
1592
|
+
"LRT",
|
|
1593
|
+
// Light Rail Transit
|
|
1594
|
+
// Indonesian taxes & fees
|
|
1595
|
+
"PBB",
|
|
1596
|
+
// Pajak Bumi dan Bangunan
|
|
1597
|
+
"PPh",
|
|
1598
|
+
// Pajak Penghasilan
|
|
1599
|
+
"PPN",
|
|
1600
|
+
// Pajak Pertambahan Nilai
|
|
1601
|
+
"BPHTB",
|
|
1602
|
+
// Bea Perolehan Hak atas Tanah dan Bangunan
|
|
1603
|
+
// Indonesian education
|
|
1604
|
+
"UI",
|
|
1605
|
+
// Universitas Indonesia
|
|
1606
|
+
"ITB",
|
|
1607
|
+
// Institut Teknologi Bandung
|
|
1608
|
+
"UGM",
|
|
1609
|
+
// Universitas Gadjah Mada
|
|
1610
|
+
"IPB",
|
|
1611
|
+
// Institut Pertanian Bogor
|
|
1612
|
+
"ITS",
|
|
1613
|
+
// Institut Teknologi Sepuluh Nopember
|
|
1614
|
+
"UNPAD",
|
|
1615
|
+
// Universitas Padjadjaran
|
|
1616
|
+
"UNDIP",
|
|
1617
|
+
// Universitas Diponegoro
|
|
1618
|
+
"UNAIR",
|
|
1619
|
+
// Universitas Airlangga
|
|
1620
|
+
"UNS",
|
|
1621
|
+
// Universitas Sebelas Maret
|
|
1622
|
+
// Indonesian degrees (gelar)
|
|
1623
|
+
"S.Pd",
|
|
1624
|
+
// Sarjana Pendidikan
|
|
1625
|
+
"S.H",
|
|
1626
|
+
// Sarjana Hukum
|
|
1627
|
+
"S.E",
|
|
1628
|
+
// Sarjana Ekonomi
|
|
1629
|
+
"S.T",
|
|
1630
|
+
// Sarjana Teknik
|
|
1631
|
+
"S.Kom",
|
|
1632
|
+
// Sarjana Komputer
|
|
1633
|
+
"S.Si",
|
|
1634
|
+
// Sarjana Sains
|
|
1635
|
+
"S.Sos",
|
|
1636
|
+
// Sarjana Sosial
|
|
1637
|
+
"M.Pd",
|
|
1638
|
+
// Magister Pendidikan
|
|
1639
|
+
"M.M",
|
|
1640
|
+
// Magister Manajemen
|
|
1641
|
+
"M.T",
|
|
1642
|
+
// Magister Teknik
|
|
1643
|
+
"M.Kom",
|
|
1644
|
+
// Magister Komputer
|
|
1645
|
+
// Common services
|
|
1646
|
+
"ATM",
|
|
1647
|
+
// Automated Teller Machine
|
|
1648
|
+
"POS",
|
|
1649
|
+
// Point of Sale
|
|
1650
|
+
"SMS",
|
|
1651
|
+
// Short Message Service
|
|
1652
|
+
"GPS",
|
|
1653
|
+
// Global Positioning System
|
|
1654
|
+
"WiFi",
|
|
1655
|
+
// Wireless Fidelity (technically Wi-Fi)
|
|
1656
|
+
"USB",
|
|
1657
|
+
// Universal Serial Bus
|
|
1658
|
+
"PIN",
|
|
1659
|
+
// Personal Identification Number
|
|
1660
|
+
"OTP",
|
|
1661
|
+
// One Time Password
|
|
1662
|
+
"QR",
|
|
1663
|
+
// Quick Response
|
|
1664
|
+
// Technology & IT
|
|
1665
|
+
"IT",
|
|
1666
|
+
// Information Technology
|
|
1667
|
+
"AI",
|
|
1668
|
+
// Artificial Intelligence
|
|
1669
|
+
"ML",
|
|
1670
|
+
// Machine Learning
|
|
1671
|
+
"API",
|
|
1672
|
+
// Application Programming Interface
|
|
1673
|
+
"UI",
|
|
1674
|
+
// User Interface (duplicate with Universitas Indonesia, context matters)
|
|
1675
|
+
"UX",
|
|
1676
|
+
// User Experience
|
|
1677
|
+
"SEO",
|
|
1678
|
+
// Search Engine Optimization
|
|
1679
|
+
"SaaS",
|
|
1680
|
+
// Software as a Service
|
|
1681
|
+
"CRM",
|
|
1682
|
+
// Customer Relationship Management
|
|
1683
|
+
"ERP",
|
|
1684
|
+
// Enterprise Resource Planning
|
|
1685
|
+
// Business titles
|
|
1686
|
+
"CEO",
|
|
1687
|
+
// Chief Executive Officer
|
|
1688
|
+
"CFO",
|
|
1689
|
+
// Chief Financial Officer
|
|
1690
|
+
"CTO",
|
|
1691
|
+
// Chief Technology Officer
|
|
1692
|
+
"COO",
|
|
1693
|
+
// Chief Operating Officer
|
|
1694
|
+
"CMO",
|
|
1695
|
+
// Chief Marketing Officer
|
|
1696
|
+
"HR",
|
|
1697
|
+
// Human Resources
|
|
1698
|
+
"PR",
|
|
1699
|
+
// Public Relations
|
|
1700
|
+
"VP",
|
|
1701
|
+
// Vice President
|
|
1702
|
+
"GM",
|
|
1703
|
+
// General Manager
|
|
1704
|
+
// International organizations
|
|
1705
|
+
"UN",
|
|
1706
|
+
// United Nations
|
|
1707
|
+
"WHO",
|
|
1708
|
+
// World Health Organization
|
|
1709
|
+
"UNESCO",
|
|
1710
|
+
// United Nations Educational, Scientific and Cultural Organization
|
|
1711
|
+
"NATO",
|
|
1712
|
+
// North Atlantic Treaty Organization
|
|
1713
|
+
"ASEAN",
|
|
1714
|
+
// Association of Southeast Asian Nations
|
|
1715
|
+
"APEC",
|
|
1716
|
+
// Asia-Pacific Economic Cooperation
|
|
1717
|
+
"WTO",
|
|
1718
|
+
// World Trade Organization
|
|
1719
|
+
"IMF",
|
|
1720
|
+
// International Monetary Fund
|
|
1721
|
+
// Medical
|
|
1722
|
+
"ICU",
|
|
1723
|
+
// Intensive Care Unit
|
|
1724
|
+
"ER",
|
|
1725
|
+
// Emergency Room
|
|
1726
|
+
"MRI",
|
|
1727
|
+
// Magnetic Resonance Imaging
|
|
1728
|
+
"CT",
|
|
1729
|
+
// Computed Tomography
|
|
1730
|
+
"DNA",
|
|
1731
|
+
// Deoxyribonucleic Acid
|
|
1732
|
+
"RNA",
|
|
1733
|
+
// Ribonucleic Acid
|
|
1734
|
+
"HIV",
|
|
1735
|
+
// Human Immunodeficiency Virus
|
|
1736
|
+
"AIDS",
|
|
1737
|
+
// Acquired Immunodeficiency Syndrome
|
|
1738
|
+
"COVID",
|
|
1739
|
+
// Coronavirus Disease
|
|
1740
|
+
// Measurements & units
|
|
1741
|
+
"KM",
|
|
1742
|
+
// Kilometer
|
|
1743
|
+
"CM",
|
|
1744
|
+
// Centimeter
|
|
1745
|
+
"MM",
|
|
1746
|
+
// Millimeter
|
|
1747
|
+
"KG",
|
|
1748
|
+
// Kilogram
|
|
1749
|
+
"RPM",
|
|
1750
|
+
// Revolutions Per Minute
|
|
1751
|
+
"MPH",
|
|
1752
|
+
// Miles Per Hour
|
|
1753
|
+
"KPH",
|
|
1754
|
+
// Kilometers Per Hour
|
|
1755
|
+
// Finance
|
|
1756
|
+
"IPO",
|
|
1757
|
+
// Initial Public Offering
|
|
1758
|
+
"ATM",
|
|
1759
|
+
// Automated Teller Machine (duplicate)
|
|
1760
|
+
"ROI",
|
|
1761
|
+
// Return on Investment
|
|
1762
|
+
"GDP",
|
|
1763
|
+
// Gross Domestic Product
|
|
1764
|
+
"VAT"
|
|
1765
|
+
// Value Added Tax
|
|
1766
|
+
];
|
|
1767
|
+
var ABBREVIATIONS = {
|
|
1768
|
+
// ========== Address Abbreviations ==========
|
|
1769
|
+
"Jl.": "Jalan",
|
|
1770
|
+
"Gg.": "Gang",
|
|
1771
|
+
"No.": "Nomor",
|
|
1772
|
+
"Kp.": "Kampung",
|
|
1773
|
+
"Ds.": "Desa",
|
|
1774
|
+
"Kel.": "Kelurahan",
|
|
1775
|
+
"Kec.": "Kecamatan",
|
|
1776
|
+
"Kab.": "Kabupaten",
|
|
1777
|
+
Kota: "Kota",
|
|
1778
|
+
"Prov.": "Provinsi",
|
|
1779
|
+
"Prop.": "Provinsi",
|
|
1780
|
+
"Rt.": "Rukun Tetangga",
|
|
1781
|
+
"Rw.": "Rukun Warga",
|
|
1782
|
+
Blok: "Blok",
|
|
1783
|
+
"Komp.": "Kompleks",
|
|
1784
|
+
Perumahan: "Perumahan",
|
|
1785
|
+
"Perum.": "Perumahan",
|
|
1786
|
+
// ========== Academic Titles ==========
|
|
1787
|
+
"Dr.": "Doktor",
|
|
1788
|
+
"Ir.": "Insinyur",
|
|
1789
|
+
"Prof.": "Profesor",
|
|
1790
|
+
"Drs.": "Doktorandus",
|
|
1791
|
+
"Dra.": "Doktoranda",
|
|
1792
|
+
// Bachelor degrees
|
|
1793
|
+
"S.Pd.": "Sarjana Pendidikan",
|
|
1794
|
+
"S.H.": "Sarjana Hukum",
|
|
1795
|
+
"S.E.": "Sarjana Ekonomi",
|
|
1796
|
+
"S.T.": "Sarjana Teknik",
|
|
1797
|
+
"S.Kom.": "Sarjana Komputer",
|
|
1798
|
+
"S.Si.": "Sarjana Sains",
|
|
1799
|
+
"S.Sos.": "Sarjana Sosial",
|
|
1800
|
+
"S.I.Kom.": "Sarjana Ilmu Komunikasi",
|
|
1801
|
+
"S.S.": "Sarjana Sastra",
|
|
1802
|
+
"S.Psi.": "Sarjana Psikologi",
|
|
1803
|
+
"S.Farm.": "Sarjana Farmasi",
|
|
1804
|
+
"S.Ked.": "Sarjana Kedokteran",
|
|
1805
|
+
// Master degrees
|
|
1806
|
+
"M.Sc.": "Master of Science",
|
|
1807
|
+
"M.M.": "Magister Manajemen",
|
|
1808
|
+
"M.Pd.": "Magister Pendidikan",
|
|
1809
|
+
"M.T.": "Magister Teknik",
|
|
1810
|
+
"M.Kom.": "Magister Komputer",
|
|
1811
|
+
"M.Si.": "Magister Sains",
|
|
1812
|
+
"M.H.": "Magister Hukum",
|
|
1813
|
+
"M.A.": "Master of Arts",
|
|
1814
|
+
MBA: "Master of Business Administration",
|
|
1815
|
+
// ========== Honorifics ==========
|
|
1816
|
+
"Bpk.": "Bapak",
|
|
1817
|
+
Ibu: "Ibu",
|
|
1818
|
+
"Sdr.": "Saudara",
|
|
1819
|
+
"Sdri.": "Saudari",
|
|
1820
|
+
"Yth.": "Yang Terhormat",
|
|
1821
|
+
"H.": "Haji",
|
|
1822
|
+
"Hj.": "Hajjah",
|
|
1823
|
+
"Tn.": "Tuan",
|
|
1824
|
+
"Ny.": "Nyonya",
|
|
1825
|
+
"Nn.": "Nona",
|
|
1826
|
+
// ========== Organizations ==========
|
|
1827
|
+
"PT.": "Perseroan Terbatas",
|
|
1828
|
+
"CV.": "Commanditaire Vennootschap",
|
|
1829
|
+
"UD.": "Usaha Dagang",
|
|
1830
|
+
"PD.": "Perusahaan Daerah",
|
|
1831
|
+
"Tbk.": "Terbuka",
|
|
1832
|
+
Koperasi: "Koperasi",
|
|
1833
|
+
Yayasan: "Yayasan",
|
|
1834
|
+
// ========== Common Abbreviations ==========
|
|
1835
|
+
"dst.": "dan seterusnya",
|
|
1836
|
+
"dsb.": "dan sebagainya",
|
|
1837
|
+
"dll.": "dan lain-lain",
|
|
1838
|
+
"dkk.": "dan kawan-kawan",
|
|
1839
|
+
"a.n.": "atas nama",
|
|
1840
|
+
"u.p.": "untuk perhatian",
|
|
1841
|
+
"u.b.": "untuk beliau",
|
|
1842
|
+
"c.q.": "casu quo",
|
|
1843
|
+
"hlm.": "halaman",
|
|
1844
|
+
"tgl.": "tanggal",
|
|
1845
|
+
"bln.": "bulan",
|
|
1846
|
+
"thn.": "tahun",
|
|
1847
|
+
"ttd.": "tertanda",
|
|
1848
|
+
// ========== Contact Information ==========
|
|
1849
|
+
"Tlp.": "Telepon",
|
|
1850
|
+
"Telp.": "Telepon",
|
|
1851
|
+
"HP.": "Handphone",
|
|
1852
|
+
Fax: "Faksimile",
|
|
1853
|
+
Email: "Email",
|
|
1854
|
+
Website: "Website",
|
|
1855
|
+
// ========== Days (Indonesian) ==========
|
|
1856
|
+
"Sen.": "Senin",
|
|
1857
|
+
"Sel.": "Selasa",
|
|
1858
|
+
"Rab.": "Rabu",
|
|
1859
|
+
"Kam.": "Kamis",
|
|
1860
|
+
"Jum.": "Jumat",
|
|
1861
|
+
"Sab.": "Sabtu",
|
|
1862
|
+
"Min.": "Minggu",
|
|
1863
|
+
// ========== Months (Indonesian) ==========
|
|
1864
|
+
"Jan.": "Januari",
|
|
1865
|
+
"Feb.": "Februari",
|
|
1866
|
+
"Mar.": "Maret",
|
|
1867
|
+
"Apr.": "April",
|
|
1868
|
+
Mei: "Mei",
|
|
1869
|
+
"Jun.": "Juni",
|
|
1870
|
+
"Jul.": "Juli",
|
|
1871
|
+
"Agt.": "Agustus",
|
|
1872
|
+
"Sep.": "September",
|
|
1873
|
+
"Okt.": "Oktober",
|
|
1874
|
+
"Nov.": "November",
|
|
1875
|
+
"Des.": "Desember",
|
|
1876
|
+
// ========== Units & Measurements ==========
|
|
1877
|
+
"kg.": "kilogram",
|
|
1878
|
+
"gr.": "gram",
|
|
1879
|
+
"lt.": "liter",
|
|
1880
|
+
"ml.": "mililiter",
|
|
1881
|
+
"km.": "kilometer",
|
|
1882
|
+
"cm.": "sentimeter",
|
|
1883
|
+
"mm.": "milimeter",
|
|
1884
|
+
"m2.": "meter persegi",
|
|
1885
|
+
"m3.": "meter kubik",
|
|
1886
|
+
"ha.": "hektar"
|
|
1887
|
+
};
|
|
1888
|
+
var PROFANITY = [
|
|
1889
|
+
"anjing",
|
|
1890
|
+
"babi",
|
|
1891
|
+
"bangsat",
|
|
1892
|
+
"bajingan",
|
|
1893
|
+
"brengsek",
|
|
1894
|
+
"goblok",
|
|
1895
|
+
"tolol",
|
|
1896
|
+
"idiot",
|
|
1897
|
+
"perek",
|
|
1898
|
+
"jablay",
|
|
1899
|
+
"kontol",
|
|
1900
|
+
"memek",
|
|
1901
|
+
"ngewe",
|
|
1902
|
+
"puki",
|
|
1903
|
+
"jembut",
|
|
1904
|
+
"asu",
|
|
1905
|
+
"itil",
|
|
1906
|
+
"lanjiao",
|
|
1907
|
+
"pantek",
|
|
1908
|
+
"anying",
|
|
1909
|
+
"anjrit"
|
|
1910
|
+
];
|
|
1911
|
+
var STOPWORDS = [
|
|
1912
|
+
"ada",
|
|
1913
|
+
"adalah",
|
|
1914
|
+
"adanya",
|
|
1915
|
+
"adapun",
|
|
1916
|
+
"agak",
|
|
1917
|
+
"agaknya",
|
|
1918
|
+
"agar",
|
|
1919
|
+
"akan",
|
|
1920
|
+
"akankah",
|
|
1921
|
+
"akhir",
|
|
1922
|
+
"akhiri",
|
|
1923
|
+
"akhirnya",
|
|
1924
|
+
"aku",
|
|
1925
|
+
"akulah",
|
|
1926
|
+
"amat",
|
|
1927
|
+
"amatlah",
|
|
1928
|
+
"anda",
|
|
1929
|
+
"andalah",
|
|
1930
|
+
"antar",
|
|
1931
|
+
"antara",
|
|
1932
|
+
"antaranya",
|
|
1933
|
+
"apa",
|
|
1934
|
+
"apaan",
|
|
1935
|
+
"apabila",
|
|
1936
|
+
"apakah",
|
|
1937
|
+
"apalagi",
|
|
1938
|
+
"apatah",
|
|
1939
|
+
"artinya",
|
|
1940
|
+
"asal",
|
|
1941
|
+
"asalkan",
|
|
1942
|
+
"atas",
|
|
1943
|
+
"atau",
|
|
1944
|
+
"ataukah",
|
|
1945
|
+
"ataupun",
|
|
1946
|
+
"awal",
|
|
1947
|
+
"awalnya",
|
|
1948
|
+
"bagai",
|
|
1949
|
+
"bagaikan",
|
|
1950
|
+
"bagaimana",
|
|
1951
|
+
"bagaimanakah",
|
|
1952
|
+
"bagaimanapun",
|
|
1953
|
+
"bagi",
|
|
1954
|
+
"bagian",
|
|
1955
|
+
"bahkan",
|
|
1956
|
+
"bahwa",
|
|
1957
|
+
"bahwasanya",
|
|
1958
|
+
"baik",
|
|
1959
|
+
"bakal",
|
|
1960
|
+
"bakalan",
|
|
1961
|
+
"balik",
|
|
1962
|
+
"banyak",
|
|
1963
|
+
"bapak",
|
|
1964
|
+
"baru",
|
|
1965
|
+
"bawah",
|
|
1966
|
+
"beberapa",
|
|
1967
|
+
"begini",
|
|
1968
|
+
"beginian",
|
|
1969
|
+
"beginikah",
|
|
1970
|
+
"beginilah",
|
|
1971
|
+
"begitu",
|
|
1972
|
+
"begitukah",
|
|
1973
|
+
"begitulah",
|
|
1974
|
+
"begitupun",
|
|
1975
|
+
"bekerja",
|
|
1976
|
+
"belakang",
|
|
1977
|
+
"belakangan",
|
|
1978
|
+
"belum",
|
|
1979
|
+
"belumlah",
|
|
1980
|
+
"benar",
|
|
1981
|
+
"benarkah",
|
|
1982
|
+
"benarlah",
|
|
1983
|
+
"berada",
|
|
1984
|
+
"berakhir",
|
|
1985
|
+
"berakhirlah",
|
|
1986
|
+
"berakhirnya",
|
|
1987
|
+
"berapa",
|
|
1988
|
+
"berapakah",
|
|
1989
|
+
"berapalah",
|
|
1990
|
+
"berapapun",
|
|
1991
|
+
"berarti",
|
|
1992
|
+
"berawal",
|
|
1993
|
+
"berbagai",
|
|
1994
|
+
"berikut",
|
|
1995
|
+
"berikutnya",
|
|
1996
|
+
"berjumlah",
|
|
1997
|
+
"berkali-kali",
|
|
1998
|
+
"berkata",
|
|
1999
|
+
"berkeinginan",
|
|
2000
|
+
"berkenaan",
|
|
2001
|
+
"berlainan",
|
|
2002
|
+
"berlalu",
|
|
2003
|
+
"berlangsung",
|
|
2004
|
+
"berlebihan",
|
|
2005
|
+
"bermacam",
|
|
2006
|
+
"bermacam-macam",
|
|
2007
|
+
"bermaksud",
|
|
2008
|
+
"bermula",
|
|
2009
|
+
"bersama",
|
|
2010
|
+
"bersama-sama",
|
|
2011
|
+
"bersiap",
|
|
2012
|
+
"bersiap-siap",
|
|
2013
|
+
"bertanya",
|
|
2014
|
+
"bertanya-tanya",
|
|
2015
|
+
"berturut",
|
|
2016
|
+
"berturut-turut",
|
|
2017
|
+
"bertutur",
|
|
2018
|
+
"berujar",
|
|
2019
|
+
"berupa",
|
|
2020
|
+
"besar",
|
|
2021
|
+
"betul",
|
|
2022
|
+
"betulkah",
|
|
2023
|
+
"biasa",
|
|
2024
|
+
"biasanya",
|
|
2025
|
+
"bila",
|
|
2026
|
+
"bilakah",
|
|
2027
|
+
"bisa",
|
|
2028
|
+
"bisakah",
|
|
2029
|
+
"boleh",
|
|
2030
|
+
"bolehkah",
|
|
2031
|
+
"bolehlah",
|
|
2032
|
+
"buat",
|
|
2033
|
+
"bukan",
|
|
2034
|
+
"bukankah",
|
|
2035
|
+
"bukanlah",
|
|
2036
|
+
"bukannya",
|
|
2037
|
+
"bulan",
|
|
2038
|
+
"bung",
|
|
2039
|
+
"cara",
|
|
2040
|
+
"caranya",
|
|
2041
|
+
"cukup",
|
|
2042
|
+
"cukupkah",
|
|
2043
|
+
"cukuplah",
|
|
2044
|
+
"cuma",
|
|
2045
|
+
"dahulu",
|
|
2046
|
+
"dalam",
|
|
2047
|
+
"dan",
|
|
2048
|
+
"dapat",
|
|
2049
|
+
"dari",
|
|
2050
|
+
"daripada",
|
|
2051
|
+
"datang",
|
|
2052
|
+
"dekat",
|
|
2053
|
+
"demi",
|
|
2054
|
+
"demikian",
|
|
2055
|
+
"demikianlah",
|
|
2056
|
+
"dengan",
|
|
2057
|
+
"depan",
|
|
2058
|
+
"di",
|
|
2059
|
+
"dia",
|
|
2060
|
+
"diakhiri",
|
|
2061
|
+
"diakhirinya",
|
|
2062
|
+
"dialah",
|
|
2063
|
+
"diantara",
|
|
2064
|
+
"diantaranya",
|
|
2065
|
+
"diberi",
|
|
2066
|
+
"diberikan",
|
|
2067
|
+
"diberikannya",
|
|
2068
|
+
"dibuat",
|
|
2069
|
+
"dibuatnya",
|
|
2070
|
+
"didapat",
|
|
2071
|
+
"didatangkan",
|
|
2072
|
+
"digunakan",
|
|
2073
|
+
"diibaratkan",
|
|
2074
|
+
"diingat",
|
|
2075
|
+
"diingatkan",
|
|
2076
|
+
"diinginkan",
|
|
2077
|
+
"dijawab",
|
|
2078
|
+
"dijelaskan",
|
|
2079
|
+
"dijelaskannya",
|
|
2080
|
+
"dikarenakan",
|
|
2081
|
+
"dikatakan",
|
|
2082
|
+
"dikatakannya",
|
|
2083
|
+
"dikerjakan",
|
|
2084
|
+
"diketahui",
|
|
2085
|
+
"diketahuinya",
|
|
2086
|
+
"dikira",
|
|
2087
|
+
"dilakukan",
|
|
2088
|
+
"dilalui",
|
|
2089
|
+
"dilihat",
|
|
2090
|
+
"dimaksud",
|
|
2091
|
+
"dimaksudkan",
|
|
2092
|
+
"dimaksudkannya",
|
|
2093
|
+
"dimana",
|
|
2094
|
+
"dimanalah",
|
|
2095
|
+
"dimulai",
|
|
2096
|
+
"dimulailah",
|
|
2097
|
+
"dimulainya",
|
|
2098
|
+
"diminta",
|
|
2099
|
+
"dimintai",
|
|
2100
|
+
"dimisalkan",
|
|
2101
|
+
"dimungkinkan",
|
|
2102
|
+
"dini",
|
|
2103
|
+
"dipastikan",
|
|
2104
|
+
"diperbuat",
|
|
2105
|
+
"diperbuatnya",
|
|
2106
|
+
"dipergunakan",
|
|
2107
|
+
"diperkirakan",
|
|
2108
|
+
"diperlihatkan",
|
|
2109
|
+
"diperlukan",
|
|
2110
|
+
"diperlukannya",
|
|
2111
|
+
"dipersoalkan",
|
|
2112
|
+
"dipertanyakan",
|
|
2113
|
+
"dipunyai",
|
|
2114
|
+
"diri",
|
|
2115
|
+
"dirinya",
|
|
2116
|
+
"disampaikan",
|
|
2117
|
+
"disebut",
|
|
2118
|
+
"disebutkan",
|
|
2119
|
+
"disebutkannya",
|
|
2120
|
+
"disini",
|
|
2121
|
+
"disinilah",
|
|
2122
|
+
"disitulah",
|
|
2123
|
+
"diterangkan",
|
|
2124
|
+
"diterangkannya",
|
|
2125
|
+
"diteruskan",
|
|
2126
|
+
"ditujukan",
|
|
2127
|
+
"ditunjuk",
|
|
2128
|
+
"ditunjuki",
|
|
2129
|
+
"ditunjukkan",
|
|
2130
|
+
"ditunjukkannya",
|
|
2131
|
+
"ditunjuknya",
|
|
2132
|
+
"dituturkan",
|
|
2133
|
+
"dituturkannya",
|
|
2134
|
+
"diucapkan",
|
|
2135
|
+
"diucapkannya",
|
|
2136
|
+
"diungkapkan",
|
|
2137
|
+
"dua",
|
|
2138
|
+
"dulu",
|
|
2139
|
+
"empat",
|
|
2140
|
+
"enggak",
|
|
2141
|
+
"enggaknya",
|
|
2142
|
+
"entah",
|
|
2143
|
+
"entahlah",
|
|
2144
|
+
"guna",
|
|
2145
|
+
"gunakan",
|
|
2146
|
+
"hal",
|
|
2147
|
+
"hampir",
|
|
2148
|
+
"hanya",
|
|
2149
|
+
"hanyalah",
|
|
2150
|
+
"hari",
|
|
2151
|
+
"harus",
|
|
2152
|
+
"haruslah",
|
|
2153
|
+
"harusnya",
|
|
2154
|
+
"hendak",
|
|
2155
|
+
"hendaklah",
|
|
2156
|
+
"hendaknya",
|
|
2157
|
+
"hingga",
|
|
2158
|
+
"ia",
|
|
2159
|
+
"ialah",
|
|
2160
|
+
"ibarat",
|
|
2161
|
+
"ibaratkan",
|
|
2162
|
+
"ibaratnya",
|
|
2163
|
+
"ibu",
|
|
2164
|
+
"ikut",
|
|
2165
|
+
"ingat",
|
|
2166
|
+
"ingat-ingat",
|
|
2167
|
+
"ingin",
|
|
2168
|
+
"inginkah",
|
|
2169
|
+
"inginkan",
|
|
2170
|
+
"ini",
|
|
2171
|
+
"inikah",
|
|
2172
|
+
"inilah",
|
|
2173
|
+
"itu",
|
|
2174
|
+
"itukah",
|
|
2175
|
+
"itulah",
|
|
2176
|
+
"jadi",
|
|
2177
|
+
"jadilah",
|
|
2178
|
+
"jadinya",
|
|
2179
|
+
"jangan",
|
|
2180
|
+
"jangankan",
|
|
2181
|
+
"janganlah",
|
|
2182
|
+
"jauh",
|
|
2183
|
+
"jawab",
|
|
2184
|
+
"jawaban",
|
|
2185
|
+
"jawabnya",
|
|
2186
|
+
"jelas",
|
|
2187
|
+
"jelaskan",
|
|
2188
|
+
"jelaslah",
|
|
2189
|
+
"jelasnya",
|
|
2190
|
+
"jika",
|
|
2191
|
+
"jikalau",
|
|
2192
|
+
"juga",
|
|
2193
|
+
"jumlah",
|
|
2194
|
+
"jumlahnya",
|
|
2195
|
+
"justru",
|
|
2196
|
+
"kala",
|
|
2197
|
+
"kalau",
|
|
2198
|
+
"kalaulah",
|
|
2199
|
+
"kalaupun",
|
|
2200
|
+
"kali",
|
|
2201
|
+
"kalian",
|
|
2202
|
+
"kami",
|
|
2203
|
+
"kamilah",
|
|
2204
|
+
"kamu",
|
|
2205
|
+
"kamulah",
|
|
2206
|
+
"kan",
|
|
2207
|
+
"kapan",
|
|
2208
|
+
"kapankah",
|
|
2209
|
+
"kapanpun",
|
|
2210
|
+
"karena",
|
|
2211
|
+
"karenanya",
|
|
2212
|
+
"ke",
|
|
2213
|
+
"keadaan",
|
|
2214
|
+
"kebetulan",
|
|
2215
|
+
"kecil",
|
|
2216
|
+
"kedua",
|
|
2217
|
+
"keduanya",
|
|
2218
|
+
"keinginan",
|
|
2219
|
+
"kelak",
|
|
2220
|
+
"kelihatan",
|
|
2221
|
+
"kelihatannya",
|
|
2222
|
+
"kelima",
|
|
2223
|
+
"keluar",
|
|
2224
|
+
"kembali",
|
|
2225
|
+
"kemudian",
|
|
2226
|
+
"kemungkinan",
|
|
2227
|
+
"kemungkinannya",
|
|
2228
|
+
"kenapa",
|
|
2229
|
+
"kepada",
|
|
2230
|
+
"kepadanya",
|
|
2231
|
+
"kesampaian",
|
|
2232
|
+
"keseluruhan",
|
|
2233
|
+
"keseluruhannya",
|
|
2234
|
+
"keterlaluan",
|
|
2235
|
+
"ketika",
|
|
2236
|
+
"khususnya",
|
|
2237
|
+
"kini",
|
|
2238
|
+
"kinilah",
|
|
2239
|
+
"kira",
|
|
2240
|
+
"kira-kira",
|
|
2241
|
+
"kiranya",
|
|
2242
|
+
"kita",
|
|
2243
|
+
"kitalah",
|
|
2244
|
+
"kok",
|
|
2245
|
+
"kurang",
|
|
2246
|
+
"lagi",
|
|
2247
|
+
"lagian",
|
|
2248
|
+
"lah",
|
|
2249
|
+
"lain",
|
|
2250
|
+
"lainnya",
|
|
2251
|
+
"lalu",
|
|
2252
|
+
"lama",
|
|
2253
|
+
"lamanya",
|
|
2254
|
+
"lanjut",
|
|
2255
|
+
"lanjutnya",
|
|
2256
|
+
"lebih",
|
|
2257
|
+
"lewat",
|
|
2258
|
+
"luar",
|
|
2259
|
+
"macam",
|
|
2260
|
+
"maka",
|
|
2261
|
+
"makanya",
|
|
2262
|
+
"makin",
|
|
2263
|
+
"malah",
|
|
2264
|
+
"malahan",
|
|
2265
|
+
"mampu",
|
|
2266
|
+
"mampukah",
|
|
2267
|
+
"mana",
|
|
2268
|
+
"manakala",
|
|
2269
|
+
"manalagi",
|
|
2270
|
+
"masih",
|
|
2271
|
+
"masihkah",
|
|
2272
|
+
"masing",
|
|
2273
|
+
"masing-masing",
|
|
2274
|
+
"mau",
|
|
2275
|
+
"maupun",
|
|
2276
|
+
"melainkan",
|
|
2277
|
+
"melakukan",
|
|
2278
|
+
"melalui",
|
|
2279
|
+
"melihat",
|
|
2280
|
+
"melihatnya",
|
|
2281
|
+
"memang",
|
|
2282
|
+
"memastikan",
|
|
2283
|
+
"memberi",
|
|
2284
|
+
"memberikan",
|
|
2285
|
+
"membuat",
|
|
2286
|
+
"memerlukan",
|
|
2287
|
+
"memihak",
|
|
2288
|
+
"meminta",
|
|
2289
|
+
"memisalkan",
|
|
2290
|
+
"memperbuat",
|
|
2291
|
+
"mempergunakan",
|
|
2292
|
+
"memperkirakan",
|
|
2293
|
+
"memperlihatkan",
|
|
2294
|
+
"mempersiapkan",
|
|
2295
|
+
"mempersoalkan",
|
|
2296
|
+
"mempertanyakan",
|
|
2297
|
+
"mempunyai",
|
|
2298
|
+
"memulai",
|
|
2299
|
+
"memungkinkan",
|
|
2300
|
+
"memutuskan",
|
|
2301
|
+
"menanti",
|
|
2302
|
+
"menanti-nanti",
|
|
2303
|
+
"menantikan",
|
|
2304
|
+
"menunjuk",
|
|
2305
|
+
"menunjuknya",
|
|
2306
|
+
"menuju",
|
|
2307
|
+
"menurut",
|
|
2308
|
+
"menurutnya",
|
|
2309
|
+
"menurutmu",
|
|
2310
|
+
"menurutku",
|
|
2311
|
+
"menurutnya",
|
|
2312
|
+
"menurut mereka",
|
|
2313
|
+
"menyampaikan",
|
|
2314
|
+
"menyebut",
|
|
2315
|
+
"menyebutkan",
|
|
2316
|
+
"menjelaskan",
|
|
2317
|
+
"menjadi",
|
|
2318
|
+
"menjadikan",
|
|
2319
|
+
"menjalani",
|
|
2320
|
+
"menjelang",
|
|
2321
|
+
"menjawab",
|
|
2322
|
+
"menunjukkan",
|
|
2323
|
+
"menuangkan",
|
|
2324
|
+
"menulis",
|
|
2325
|
+
"menyatakan",
|
|
2326
|
+
"merupakan",
|
|
2327
|
+
"mereka",
|
|
2328
|
+
"merekalah",
|
|
2329
|
+
"meski",
|
|
2330
|
+
"meskipun",
|
|
2331
|
+
"mula",
|
|
2332
|
+
"mulai",
|
|
2333
|
+
"mulailah",
|
|
2334
|
+
"mulanya",
|
|
2335
|
+
"mungkin",
|
|
2336
|
+
"mungkinkah",
|
|
2337
|
+
"nah",
|
|
2338
|
+
"naik",
|
|
2339
|
+
"namun",
|
|
2340
|
+
"nanti",
|
|
2341
|
+
"nantinya",
|
|
2342
|
+
"nyaris",
|
|
2343
|
+
"oleh",
|
|
2344
|
+
"olehnya",
|
|
2345
|
+
"orang",
|
|
2346
|
+
"pada",
|
|
2347
|
+
"padahal",
|
|
2348
|
+
"padanya",
|
|
2349
|
+
"pakai",
|
|
2350
|
+
"paling",
|
|
2351
|
+
"panjang",
|
|
2352
|
+
"pantas",
|
|
2353
|
+
"para",
|
|
2354
|
+
"pasti",
|
|
2355
|
+
"pastilah",
|
|
2356
|
+
"pagi",
|
|
2357
|
+
"per",
|
|
2358
|
+
"pernah",
|
|
2359
|
+
"persoalan",
|
|
2360
|
+
"pertama",
|
|
2361
|
+
"pertama-tama",
|
|
2362
|
+
"perlu",
|
|
2363
|
+
"perlukah",
|
|
2364
|
+
"perlulah",
|
|
2365
|
+
"pernah",
|
|
2366
|
+
"pihak",
|
|
2367
|
+
"pihaknya",
|
|
2368
|
+
"pukul",
|
|
2369
|
+
"pula",
|
|
2370
|
+
"pun",
|
|
2371
|
+
"punya",
|
|
2372
|
+
"rasa",
|
|
2373
|
+
"rasanya",
|
|
2374
|
+
"rata",
|
|
2375
|
+
"rupanya",
|
|
2376
|
+
"saat",
|
|
2377
|
+
"saatnya",
|
|
2378
|
+
"saja",
|
|
2379
|
+
"sajalah",
|
|
2380
|
+
"salam",
|
|
2381
|
+
"saling",
|
|
2382
|
+
"sama",
|
|
2383
|
+
"sama-sama",
|
|
2384
|
+
"sambil",
|
|
2385
|
+
"sampai",
|
|
2386
|
+
"sampai-sampai",
|
|
2387
|
+
"sampaikan",
|
|
2388
|
+
"sana",
|
|
2389
|
+
"sangat",
|
|
2390
|
+
"sangatlah",
|
|
2391
|
+
"satu",
|
|
2392
|
+
"saya",
|
|
2393
|
+
"sayalah",
|
|
2394
|
+
"sayang",
|
|
2395
|
+
"seperti",
|
|
2396
|
+
"seperti-itu",
|
|
2397
|
+
"sepura",
|
|
2398
|
+
"sebab",
|
|
2399
|
+
"sebabnya",
|
|
2400
|
+
"sebagai",
|
|
2401
|
+
"sebagaimana",
|
|
2402
|
+
"sebagainya",
|
|
2403
|
+
"sebagian",
|
|
2404
|
+
"sebaik",
|
|
2405
|
+
"sebaik-baiknya",
|
|
2406
|
+
"sebaiknya",
|
|
2407
|
+
"sebaliknya",
|
|
2408
|
+
"sebanyak",
|
|
2409
|
+
"sebegini",
|
|
2410
|
+
"sebegitu",
|
|
2411
|
+
"sebelum",
|
|
2412
|
+
"sebelumnya",
|
|
2413
|
+
"sebenarnya",
|
|
2414
|
+
"seberapa",
|
|
2415
|
+
"sebesar",
|
|
2416
|
+
"sebetulnya",
|
|
2417
|
+
"sebisanya",
|
|
2418
|
+
"sebuah",
|
|
2419
|
+
"sebut",
|
|
2420
|
+
"sebutkan",
|
|
2421
|
+
"sebutnya",
|
|
2422
|
+
"secara",
|
|
2423
|
+
"secukupnya",
|
|
2424
|
+
"sedang",
|
|
2425
|
+
"sedangkan",
|
|
2426
|
+
"sedikit",
|
|
2427
|
+
"sedikitnya",
|
|
2428
|
+
"sedemikian",
|
|
2429
|
+
"sediakala",
|
|
2430
|
+
"sedikit",
|
|
2431
|
+
"sedikitnya",
|
|
2432
|
+
"segala",
|
|
2433
|
+
"segalanya",
|
|
2434
|
+
"segera",
|
|
2435
|
+
"seharusnya",
|
|
2436
|
+
"sehingga",
|
|
2437
|
+
"seingat",
|
|
2438
|
+
"sejak",
|
|
2439
|
+
"sejauh",
|
|
2440
|
+
"sejenak",
|
|
2441
|
+
"sejumlah",
|
|
2442
|
+
"sekali",
|
|
2443
|
+
"sekali-kali",
|
|
2444
|
+
"sekalian",
|
|
2445
|
+
"sekaligus",
|
|
2446
|
+
"sekalipun",
|
|
2447
|
+
"sekarang",
|
|
2448
|
+
"sekaranglah",
|
|
2449
|
+
"sekecil",
|
|
2450
|
+
"seketika",
|
|
2451
|
+
"sekiranya",
|
|
2452
|
+
"sekitar",
|
|
2453
|
+
"sekitarnya",
|
|
2454
|
+
"sekurang",
|
|
2455
|
+
"sekurangnya",
|
|
2456
|
+
"sela",
|
|
2457
|
+
"selalu",
|
|
2458
|
+
"selama",
|
|
2459
|
+
"selama-lamanya",
|
|
2460
|
+
"selamanya",
|
|
2461
|
+
"selanjutnya",
|
|
2462
|
+
"seluruh",
|
|
2463
|
+
"seluruhnya",
|
|
2464
|
+
"semacam",
|
|
2465
|
+
"semakin",
|
|
2466
|
+
"semampu",
|
|
2467
|
+
"semampunya",
|
|
2468
|
+
"semasa",
|
|
2469
|
+
"semata",
|
|
2470
|
+
"semata-mata",
|
|
2471
|
+
"semaunya",
|
|
2472
|
+
"sementara",
|
|
2473
|
+
"semisal",
|
|
2474
|
+
"semisalnya",
|
|
2475
|
+
"sempat",
|
|
2476
|
+
"semua",
|
|
2477
|
+
"semuanya",
|
|
2478
|
+
"semula",
|
|
2479
|
+
"sendiri",
|
|
2480
|
+
"sendirinya",
|
|
2481
|
+
"seolah",
|
|
2482
|
+
"seolah-olah",
|
|
2483
|
+
"seorang",
|
|
2484
|
+
"sepanjang",
|
|
2485
|
+
"sepantasnya",
|
|
2486
|
+
"sepantasnyalah",
|
|
2487
|
+
"seperempat",
|
|
2488
|
+
"seperti",
|
|
2489
|
+
"sepertinya",
|
|
2490
|
+
"sepihak",
|
|
2491
|
+
"sepuluh",
|
|
2492
|
+
"seratus",
|
|
2493
|
+
"seribu",
|
|
2494
|
+
"sering",
|
|
2495
|
+
"seringnya",
|
|
2496
|
+
"serta",
|
|
2497
|
+
"serupa",
|
|
2498
|
+
"sesaat",
|
|
2499
|
+
"sesama",
|
|
2500
|
+
"sesampai",
|
|
2501
|
+
"sesampainya",
|
|
2502
|
+
"sesegera",
|
|
2503
|
+
"sesekali",
|
|
2504
|
+
"seseorang",
|
|
2505
|
+
"sesuatu",
|
|
2506
|
+
"sesuatunya",
|
|
2507
|
+
"sesudah",
|
|
2508
|
+
"sesudahnya",
|
|
2509
|
+
"setelah",
|
|
2510
|
+
"setempat",
|
|
2511
|
+
"setengah",
|
|
2512
|
+
"seterusnya",
|
|
2513
|
+
"setiap",
|
|
2514
|
+
"setidaknya",
|
|
2515
|
+
"setinggi",
|
|
2516
|
+
"seusai",
|
|
2517
|
+
"sewaktu",
|
|
2518
|
+
"siap",
|
|
2519
|
+
"siapa",
|
|
2520
|
+
"siapakah",
|
|
2521
|
+
"siapapun",
|
|
2522
|
+
"sini",
|
|
2523
|
+
"sinilah",
|
|
2524
|
+
"situ",
|
|
2525
|
+
"situlah",
|
|
2526
|
+
"suatu",
|
|
2527
|
+
"sudah",
|
|
2528
|
+
"sudahkah",
|
|
2529
|
+
"sudahlah",
|
|
2530
|
+
"supaya",
|
|
2531
|
+
"tadi",
|
|
2532
|
+
"tadinya",
|
|
2533
|
+
"tahu",
|
|
2534
|
+
"tak",
|
|
2535
|
+
"tambah",
|
|
2536
|
+
"tambahnya",
|
|
2537
|
+
"tampak",
|
|
2538
|
+
"tampaknya",
|
|
2539
|
+
"tandas",
|
|
2540
|
+
"tandasnya",
|
|
2541
|
+
"tanpa",
|
|
2542
|
+
"tanya",
|
|
2543
|
+
"tanyakan",
|
|
2544
|
+
"tanyanya",
|
|
2545
|
+
"tapi",
|
|
2546
|
+
"tegas",
|
|
2547
|
+
"tegasnya",
|
|
2548
|
+
"telah",
|
|
2549
|
+
"tempat",
|
|
2550
|
+
"tengah",
|
|
2551
|
+
"tentang",
|
|
2552
|
+
"tentu",
|
|
2553
|
+
"tentulah",
|
|
2554
|
+
"tentunya",
|
|
2555
|
+
"tepat",
|
|
2556
|
+
"terakhir",
|
|
2557
|
+
"terasa",
|
|
2558
|
+
"terbanyak",
|
|
2559
|
+
"terdahulu",
|
|
2560
|
+
"terdapat",
|
|
2561
|
+
"terdiri",
|
|
2562
|
+
"terdiri-dari",
|
|
2563
|
+
"terhadap",
|
|
2564
|
+
"terhadapnya",
|
|
2565
|
+
"teringat",
|
|
2566
|
+
"teringat-ingat",
|
|
2567
|
+
"terjadi",
|
|
2568
|
+
"terjadilah",
|
|
2569
|
+
"terjadinya",
|
|
2570
|
+
"terkira",
|
|
2571
|
+
"terlalu",
|
|
2572
|
+
"terlebih",
|
|
2573
|
+
"terlihat",
|
|
2574
|
+
"termasuk",
|
|
2575
|
+
"ternyata",
|
|
2576
|
+
"tersampaikan",
|
|
2577
|
+
"tersebut",
|
|
2578
|
+
"tersebutlah",
|
|
2579
|
+
"tertentu",
|
|
2580
|
+
"tertuju",
|
|
2581
|
+
"terus",
|
|
2582
|
+
"terutama",
|
|
2583
|
+
"tetap",
|
|
2584
|
+
"tetapi",
|
|
2585
|
+
"tiap",
|
|
2586
|
+
"tiba",
|
|
2587
|
+
"tiba-tiba",
|
|
2588
|
+
"tidak",
|
|
2589
|
+
"tidakkah",
|
|
2590
|
+
"tidaklah",
|
|
2591
|
+
"tiga",
|
|
2592
|
+
"tadi",
|
|
2593
|
+
"tadinya",
|
|
2594
|
+
"tinggi",
|
|
2595
|
+
"toh",
|
|
2596
|
+
"tuju",
|
|
2597
|
+
"tunjuk",
|
|
2598
|
+
"turut",
|
|
2599
|
+
"tutur",
|
|
2600
|
+
"tuturnya",
|
|
2601
|
+
"ucap",
|
|
2602
|
+
"ucapnya",
|
|
2603
|
+
"ujar",
|
|
2604
|
+
"ujarnya",
|
|
2605
|
+
"umumnya",
|
|
2606
|
+
"ungkap",
|
|
2607
|
+
"ungkapnya",
|
|
2608
|
+
"untuk",
|
|
2609
|
+
"untaian",
|
|
2610
|
+
"usai",
|
|
2611
|
+
"usah",
|
|
2612
|
+
"waduh",
|
|
2613
|
+
"wah",
|
|
2614
|
+
"wahai",
|
|
2615
|
+
"walau",
|
|
2616
|
+
"walaupun",
|
|
2617
|
+
"wong",
|
|
2618
|
+
"yaitu",
|
|
2619
|
+
"yakin",
|
|
2620
|
+
"yakni",
|
|
2621
|
+
"yang"
|
|
2622
|
+
];
|
|
2623
|
+
|
|
2624
|
+
// src/text/capitalization.ts
|
|
2625
|
+
function capitalize2(text) {
|
|
2626
|
+
if (!text) return text;
|
|
2627
|
+
return text.charAt(0).toUpperCase() + text.slice(1).toLowerCase();
|
|
2628
|
+
}
|
|
2629
|
+
function toTitleCase(text, options) {
|
|
2630
|
+
if (!text) return text;
|
|
2631
|
+
const {
|
|
2632
|
+
preserveAcronyms = true,
|
|
2633
|
+
strict = false,
|
|
2634
|
+
exceptions = []
|
|
2635
|
+
} = options || {};
|
|
2636
|
+
const lowercaseSet = /* @__PURE__ */ new Set([...LOWERCASE_WORDS, ...exceptions]);
|
|
2637
|
+
const acronymSet = new Set(ACRONYMS);
|
|
2638
|
+
const normalized = normalizeSpaces(text);
|
|
2639
|
+
const words = normalized.split(" ");
|
|
2640
|
+
return words.map((word, index) => {
|
|
2641
|
+
if (!word) return word;
|
|
2642
|
+
if (word.includes("-")) {
|
|
2643
|
+
return processHyphenatedWord(word, index === 0, {
|
|
2644
|
+
lowercaseSet,
|
|
2645
|
+
acronymSet,
|
|
2646
|
+
preserveAcronyms,
|
|
2647
|
+
strict
|
|
2648
|
+
});
|
|
2649
|
+
}
|
|
2650
|
+
return processWord(word, index === 0, {
|
|
2651
|
+
lowercaseSet,
|
|
2652
|
+
acronymSet,
|
|
2653
|
+
preserveAcronyms,
|
|
2654
|
+
strict
|
|
2655
|
+
});
|
|
2656
|
+
}).join(" ");
|
|
2657
|
+
}
|
|
2658
|
+
function normalizeSpaces(text) {
|
|
2659
|
+
return text.trim().replace(/\s+/g, " ");
|
|
2660
|
+
}
|
|
2661
|
+
function processWord(word, isFirstWord, context) {
|
|
2662
|
+
const { lowercaseSet, acronymSet, preserveAcronyms, strict } = context;
|
|
2663
|
+
const lowerWord = word.toLowerCase();
|
|
2664
|
+
const upperWord = word.toUpperCase();
|
|
2665
|
+
if (preserveAcronyms && acronymSet.has(upperWord)) {
|
|
2666
|
+
return upperWord;
|
|
2667
|
+
}
|
|
2668
|
+
if (!isFirstWord && lowercaseSet.has(lowerWord)) {
|
|
2669
|
+
return lowerWord;
|
|
2670
|
+
}
|
|
2671
|
+
if (strict) {
|
|
2672
|
+
return capitalizeFirstLetter(lowerWord);
|
|
2673
|
+
}
|
|
2674
|
+
return capitalizeFirstLetter(word.toLowerCase());
|
|
2675
|
+
}
|
|
2676
|
+
function processHyphenatedWord(word, isFirstWord, context) {
|
|
2677
|
+
return word.split("-").map(
|
|
2678
|
+
(part, index) => processWord(part, isFirstWord && index === 0, context)
|
|
2679
|
+
).join("-");
|
|
2680
|
+
}
|
|
2681
|
+
function capitalizeFirstLetter(word) {
|
|
2682
|
+
if (!word) return word;
|
|
2683
|
+
return word.charAt(0).toUpperCase() + word.slice(1);
|
|
2684
|
+
}
|
|
2685
|
+
function toSentenceCase(text) {
|
|
2686
|
+
if (!text) return text;
|
|
2687
|
+
const normalized = text.trim().replace(/\s+/g, " ");
|
|
2688
|
+
let result = "";
|
|
2689
|
+
let shouldCapitalize = true;
|
|
2690
|
+
for (let i = 0; i < normalized.length; i++) {
|
|
2691
|
+
const char = normalized[i];
|
|
2692
|
+
if (shouldCapitalize && /[a-zA-ZÀ-ÿ]/.test(char)) {
|
|
2693
|
+
result += char.toUpperCase();
|
|
2694
|
+
shouldCapitalize = false;
|
|
2695
|
+
} else {
|
|
2696
|
+
result += char.toLowerCase();
|
|
2697
|
+
}
|
|
2698
|
+
if (isSentenceEnd(char)) {
|
|
2699
|
+
shouldCapitalize = true;
|
|
2700
|
+
}
|
|
2701
|
+
if (char === "." && i + 1 < normalized.length) {
|
|
2702
|
+
const nextChar = normalized[i + 1];
|
|
2703
|
+
if (nextChar !== " " && !/[.!?]/.test(nextChar)) {
|
|
2704
|
+
shouldCapitalize = false;
|
|
2705
|
+
}
|
|
2706
|
+
}
|
|
2707
|
+
}
|
|
2708
|
+
return result;
|
|
2709
|
+
}
|
|
2710
|
+
function isSentenceEnd(char) {
|
|
2711
|
+
return char === "." || char === "!" || char === "?";
|
|
2712
|
+
}
|
|
2713
|
+
|
|
2714
|
+
// src/text/slug.ts
|
|
2715
|
+
function slugify(text, options) {
|
|
2716
|
+
if (!text) return "";
|
|
2717
|
+
const {
|
|
2718
|
+
separator = "-",
|
|
2719
|
+
lowercase = true,
|
|
2720
|
+
replacements = {},
|
|
2721
|
+
trim = true
|
|
2722
|
+
} = options || {};
|
|
2723
|
+
let result = text;
|
|
2724
|
+
for (const [search, replace] of Object.entries(replacements)) {
|
|
2725
|
+
result = result.replace(new RegExp(escapeRegex(search), "g"), replace);
|
|
2726
|
+
}
|
|
2727
|
+
result = result.replace(/&/g, " dan ");
|
|
2728
|
+
result = result.replace(/\//g, " atau ");
|
|
2729
|
+
if (lowercase) {
|
|
2730
|
+
result = result.toLowerCase();
|
|
2731
|
+
}
|
|
2732
|
+
result = result.replace(/[.'@éèêëàâäôöûüùïîçñ™®©]/g, "");
|
|
2733
|
+
result = result.replace(/[^\w\s-]+/g, separator);
|
|
2734
|
+
result = result.replace(/\s+/g, separator);
|
|
2735
|
+
if (separator !== "-") {
|
|
2736
|
+
result = result.replace(/-/g, separator);
|
|
2737
|
+
}
|
|
2738
|
+
if (trim) {
|
|
2739
|
+
const separatorRegex = new RegExp(`\\${separator}+`, "g");
|
|
2740
|
+
result = result.replace(separatorRegex, separator);
|
|
2741
|
+
const trimRegex = new RegExp(`^\\${separator}+|\\${separator}+$`, "g");
|
|
2742
|
+
result = result.replace(trimRegex, "");
|
|
2743
|
+
}
|
|
2744
|
+
return result;
|
|
2745
|
+
}
|
|
2746
|
+
function escapeRegex(str) {
|
|
2747
|
+
return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
2748
|
+
}
|
|
2749
|
+
|
|
2750
|
+
// src/text/sanitize.ts
|
|
2751
|
+
function normalizeWhitespace(text) {
|
|
2752
|
+
if (!text) return text;
|
|
2753
|
+
return text.trim().replace(/\s+/g, " ");
|
|
2754
|
+
}
|
|
2755
|
+
function sanitize(text, options) {
|
|
2756
|
+
if (!text) return text;
|
|
2757
|
+
const {
|
|
2758
|
+
removeNewlines = false,
|
|
2759
|
+
removeExtraSpaces = true,
|
|
2760
|
+
removePunctuation = false,
|
|
2761
|
+
allowedChars,
|
|
2762
|
+
trim = true
|
|
2763
|
+
} = options || {};
|
|
2764
|
+
let result = text;
|
|
2765
|
+
if (removeNewlines) {
|
|
2766
|
+
result = result.replace(/[\n\r]/g, " ");
|
|
2767
|
+
}
|
|
2768
|
+
if (removePunctuation) {
|
|
2769
|
+
result = result.replace(/[!"#$%&'()*+,\-./:;<=>?@[\\\]^_`{|}~]/g, "");
|
|
2770
|
+
}
|
|
2771
|
+
if (allowedChars) {
|
|
2772
|
+
const allowedRegex = new RegExp(`[^${allowedChars}]`, "g");
|
|
2773
|
+
result = result.replace(allowedRegex, "");
|
|
2774
|
+
}
|
|
2775
|
+
if (removeExtraSpaces) {
|
|
2776
|
+
if (trim) {
|
|
2777
|
+
if (removeNewlines) {
|
|
2778
|
+
result = result.replace(/\s+/g, " ");
|
|
2779
|
+
} else {
|
|
2780
|
+
result = result.replace(/[ \t]+/g, " ");
|
|
2781
|
+
}
|
|
2782
|
+
} else {
|
|
2783
|
+
const leadingMatch = result.match(/^([ \t]*)/);
|
|
2784
|
+
const trailingMatch = result.match(/([ \t]*)$/);
|
|
2785
|
+
const leading = leadingMatch ? leadingMatch[1] : "";
|
|
2786
|
+
const trailing = trailingMatch ? trailingMatch[1] : "";
|
|
2787
|
+
const middle = result.slice(
|
|
2788
|
+
leading.length,
|
|
2789
|
+
result.length - trailing.length
|
|
2790
|
+
);
|
|
2791
|
+
const normalizedMiddle = removeNewlines ? middle.replace(/\s+/g, " ") : middle.replace(/[ \t]+/g, " ");
|
|
2792
|
+
result = leading + normalizedMiddle + trailing;
|
|
2793
|
+
}
|
|
2794
|
+
}
|
|
2795
|
+
if (trim) {
|
|
2796
|
+
result = result.trim();
|
|
2797
|
+
}
|
|
2798
|
+
return result;
|
|
2799
|
+
}
|
|
2800
|
+
function removeAccents(text) {
|
|
2801
|
+
if (!text) return text;
|
|
2802
|
+
const specialChars = {
|
|
2803
|
+
\u00D8: "O",
|
|
2804
|
+
\u00F8: "o",
|
|
2805
|
+
\u00C6: "AE",
|
|
2806
|
+
\u00E6: "ae",
|
|
2807
|
+
\u00C5: "A",
|
|
2808
|
+
\u00E5: "a",
|
|
2809
|
+
\u0110: "D",
|
|
2810
|
+
\u0111: "d",
|
|
2811
|
+
\u0141: "L",
|
|
2812
|
+
\u0142: "l",
|
|
2813
|
+
\u00DE: "TH",
|
|
2814
|
+
\u00FE: "th",
|
|
2815
|
+
\u00DF: "ss"
|
|
2816
|
+
};
|
|
2817
|
+
let result = text;
|
|
2818
|
+
for (const [accented, plain] of Object.entries(specialChars)) {
|
|
2819
|
+
result = result.replace(new RegExp(accented, "g"), plain);
|
|
2820
|
+
}
|
|
2821
|
+
return result.normalize("NFD").replace(/[\u0300-\u036f]/g, "");
|
|
2822
|
+
}
|
|
2823
|
+
|
|
2824
|
+
// src/text/abbreviation.ts
|
|
2825
|
+
function expandAbbreviation(text, options) {
|
|
2826
|
+
if (!text) return text;
|
|
2827
|
+
const { mode = "all", customMap = {}, preserveCase = false } = options || {};
|
|
2828
|
+
const abbreviationsMap = {
|
|
2829
|
+
...getAbbreviationsByMode(mode),
|
|
2830
|
+
...customMap
|
|
2831
|
+
};
|
|
2832
|
+
let result = text;
|
|
2833
|
+
const sortedAbbrevs = Object.keys(abbreviationsMap).sort(
|
|
2834
|
+
(a, b) => b.length - a.length
|
|
2835
|
+
);
|
|
2836
|
+
for (const abbrev of sortedAbbrevs) {
|
|
2837
|
+
const expansion = abbreviationsMap[abbrev];
|
|
2838
|
+
const startBoundary = /^\w/.test(abbrev) ? "\\b" : "";
|
|
2839
|
+
const endBoundary = /\w$/.test(abbrev) ? "\\b" : "";
|
|
2840
|
+
const regex = new RegExp(
|
|
2841
|
+
`${startBoundary}${escapeRegex2(abbrev)}${endBoundary}`,
|
|
2842
|
+
"gi"
|
|
2843
|
+
);
|
|
2844
|
+
result = result.replace(regex, (match) => {
|
|
2845
|
+
if (!preserveCase) {
|
|
2846
|
+
return expansion;
|
|
2847
|
+
}
|
|
2848
|
+
return matchCase(match, expansion);
|
|
2849
|
+
});
|
|
2850
|
+
}
|
|
2851
|
+
return result;
|
|
2852
|
+
}
|
|
2853
|
+
function getAbbreviationsByMode(mode) {
|
|
2854
|
+
if (mode === "all") {
|
|
2855
|
+
return ABBREVIATIONS;
|
|
2856
|
+
}
|
|
2857
|
+
const filtered = {};
|
|
2858
|
+
const addressAbbrevs = [
|
|
2859
|
+
"Jl.",
|
|
2860
|
+
"Gg.",
|
|
2861
|
+
"No.",
|
|
2862
|
+
"Kp.",
|
|
2863
|
+
"Ds.",
|
|
2864
|
+
"Kel.",
|
|
2865
|
+
"Kec.",
|
|
2866
|
+
"Kab.",
|
|
2867
|
+
"Kota",
|
|
2868
|
+
"Prov.",
|
|
2869
|
+
"Prop.",
|
|
2870
|
+
"Rt.",
|
|
2871
|
+
"Rw.",
|
|
2872
|
+
"Blok",
|
|
2873
|
+
"Komp.",
|
|
2874
|
+
"Perumahan",
|
|
2875
|
+
"Perum."
|
|
2876
|
+
];
|
|
2877
|
+
const titleAbbrevs = [
|
|
2878
|
+
"Dr.",
|
|
2879
|
+
"Ir.",
|
|
2880
|
+
"Prof.",
|
|
2881
|
+
"Drs.",
|
|
2882
|
+
"Dra.",
|
|
2883
|
+
"S.Pd.",
|
|
2884
|
+
"S.H.",
|
|
2885
|
+
"S.E.",
|
|
2886
|
+
"S.T.",
|
|
2887
|
+
"S.Kom.",
|
|
2888
|
+
"S.Si.",
|
|
2889
|
+
"S.Sos.",
|
|
2890
|
+
"S.I.Kom.",
|
|
2891
|
+
"S.S.",
|
|
2892
|
+
"S.Psi.",
|
|
2893
|
+
"S.Farm.",
|
|
2894
|
+
"S.Ked.",
|
|
2895
|
+
"M.Sc.",
|
|
2896
|
+
"M.M.",
|
|
2897
|
+
"M.Pd.",
|
|
2898
|
+
"M.T.",
|
|
2899
|
+
"M.Kom.",
|
|
2900
|
+
"M.Si.",
|
|
2901
|
+
"M.H.",
|
|
2902
|
+
"M.A.",
|
|
2903
|
+
"MBA"
|
|
2904
|
+
];
|
|
2905
|
+
const orgAbbrevs = [
|
|
2906
|
+
"PT.",
|
|
2907
|
+
"CV.",
|
|
2908
|
+
"UD.",
|
|
2909
|
+
"PD.",
|
|
2910
|
+
"Tbk.",
|
|
2911
|
+
"Koperasi",
|
|
2912
|
+
"Yayasan"
|
|
2913
|
+
];
|
|
2914
|
+
for (const [abbrev, expansion] of Object.entries(ABBREVIATIONS)) {
|
|
2915
|
+
if (mode === "address" && addressAbbrevs.includes(abbrev)) {
|
|
2916
|
+
filtered[abbrev] = expansion;
|
|
2917
|
+
} else if (mode === "title" && titleAbbrevs.includes(abbrev)) {
|
|
2918
|
+
filtered[abbrev] = expansion;
|
|
2919
|
+
} else if (mode === "org" && orgAbbrevs.includes(abbrev)) {
|
|
2920
|
+
filtered[abbrev] = expansion;
|
|
2921
|
+
}
|
|
2922
|
+
}
|
|
2923
|
+
return filtered;
|
|
2924
|
+
}
|
|
2925
|
+
function escapeRegex2(str) {
|
|
2926
|
+
return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
2927
|
+
}
|
|
2928
|
+
function matchCase(original, replacement) {
|
|
2929
|
+
if (original === original.toUpperCase()) {
|
|
2930
|
+
return replacement.toUpperCase();
|
|
2931
|
+
}
|
|
2932
|
+
if (original === original.toLowerCase()) {
|
|
2933
|
+
return replacement.toLowerCase();
|
|
2934
|
+
}
|
|
2935
|
+
if (original.charAt(0) === original.charAt(0).toUpperCase()) {
|
|
2936
|
+
return replacement.charAt(0).toUpperCase() + replacement.slice(1).toLowerCase();
|
|
2937
|
+
}
|
|
2938
|
+
return replacement;
|
|
2939
|
+
}
|
|
2940
|
+
function contractAbbreviation(text, options) {
|
|
2941
|
+
if (!text) return text;
|
|
2942
|
+
const { mode = "all" } = options || {};
|
|
2943
|
+
const abbreviationsMap = getAbbreviationsByMode(mode);
|
|
2944
|
+
const reverseMap = {};
|
|
2945
|
+
for (const [abbrev, expansion] of Object.entries(abbreviationsMap)) {
|
|
2946
|
+
reverseMap[expansion] = abbrev;
|
|
2947
|
+
}
|
|
2948
|
+
let result = text;
|
|
2949
|
+
const sortedExpansions = Object.keys(reverseMap).sort(
|
|
2950
|
+
(a, b) => b.length - a.length
|
|
2951
|
+
);
|
|
2952
|
+
for (const expansion of sortedExpansions) {
|
|
2953
|
+
const abbrev = reverseMap[expansion];
|
|
2954
|
+
const regex = new RegExp(`\\b${escapeRegex2(expansion)}\\b`, "gi");
|
|
2955
|
+
result = result.replace(regex, abbrev);
|
|
2956
|
+
}
|
|
2957
|
+
return result;
|
|
2958
|
+
}
|
|
2959
|
+
|
|
2960
|
+
// src/text/filter.ts
|
|
2961
|
+
function profanityFilter(text, mask = "*") {
|
|
2962
|
+
let filtered = text;
|
|
2963
|
+
PROFANITY.forEach((word) => {
|
|
2964
|
+
const regex = new RegExp(`\\b${word}\\b`, "gi");
|
|
2965
|
+
filtered = filtered.replace(regex, mask.repeat(word.length));
|
|
2966
|
+
});
|
|
2967
|
+
return filtered;
|
|
2968
|
+
}
|
|
2969
|
+
function removeStopwords(text) {
|
|
2970
|
+
const words = text.split(/\s+/);
|
|
2971
|
+
const filtered = words.filter(
|
|
2972
|
+
(word) => !STOPWORDS.includes(word.toLowerCase())
|
|
2973
|
+
);
|
|
2974
|
+
return filtered.join(" ");
|
|
2975
|
+
}
|
|
2976
|
+
|
|
2977
|
+
// src/text/normalization.ts
|
|
2978
|
+
var INFORMAL_MAP = {
|
|
2979
|
+
gw: "saya",
|
|
2980
|
+
gua: "saya",
|
|
2981
|
+
lu: "kamu",
|
|
2982
|
+
lo: "kamu",
|
|
2983
|
+
elo: "kamu",
|
|
2984
|
+
lagi: "sedang",
|
|
2985
|
+
gue: "saya",
|
|
2986
|
+
gwe: "saya",
|
|
2987
|
+
gak: "tidak",
|
|
2988
|
+
ga: "tidak",
|
|
2989
|
+
nggak: "tidak",
|
|
2990
|
+
kalo: "kalau",
|
|
2991
|
+
karna: "karena",
|
|
2992
|
+
tapi: "tetapi",
|
|
2993
|
+
udah: "sudah",
|
|
2994
|
+
dah: "sudah",
|
|
2995
|
+
aja: "saja",
|
|
2996
|
+
banget: "sekali",
|
|
2997
|
+
emang: "memang",
|
|
2998
|
+
pake: "pakai",
|
|
2999
|
+
bikin: "membuat",
|
|
3000
|
+
kasih: "memberi",
|
|
3001
|
+
dapet: "dapat",
|
|
3002
|
+
liat: "lihat",
|
|
3003
|
+
ngasih: "memberi",
|
|
3004
|
+
nyari: "mencari",
|
|
3005
|
+
nanya: "bertanya",
|
|
3006
|
+
bilang: "berkata"
|
|
3007
|
+
};
|
|
3008
|
+
function toFormal(text) {
|
|
3009
|
+
const words = text.split(/\s+/);
|
|
3010
|
+
const formalized = words.map((word) => {
|
|
3011
|
+
const lower = word.toLowerCase().replace(/[^\w]/g, "");
|
|
3012
|
+
const formal = INFORMAL_MAP[lower];
|
|
3013
|
+
if (formal) {
|
|
3014
|
+
if (word[0] === word[0].toUpperCase()) {
|
|
3015
|
+
return formal.charAt(0).toUpperCase() + formal.slice(1);
|
|
3016
|
+
}
|
|
3017
|
+
return formal;
|
|
3018
|
+
}
|
|
3019
|
+
return word;
|
|
3020
|
+
});
|
|
3021
|
+
return formalized.join(" ");
|
|
3022
|
+
}
|
|
3023
|
+
function isAlay(text) {
|
|
3024
|
+
if (!text) return false;
|
|
3025
|
+
const alternatingCaps = /([a-z][A-Z][a-z]|[A-Z][a-z][A-Z])/.test(text);
|
|
3026
|
+
const numberSub = /\b\w*[0431572]\w*\b/.test(text);
|
|
3027
|
+
const qSub = /q/i.test(text) && !/u/i.test(text);
|
|
3028
|
+
const excessiveChars = /(.)\1{2,}/.test(text);
|
|
3029
|
+
return alternatingCaps || numberSub || qSub || excessiveChars;
|
|
3030
|
+
}
|
|
3031
|
+
|
|
3032
|
+
// src/text/extract.ts
|
|
3033
|
+
function truncate(text, maxLength, options) {
|
|
3034
|
+
if (!text || maxLength <= 0) {
|
|
3035
|
+
return "";
|
|
3036
|
+
}
|
|
3037
|
+
const { ellipsis = "...", wordBoundary = true } = options || {};
|
|
3038
|
+
if (text.length <= maxLength) {
|
|
3039
|
+
return text;
|
|
3040
|
+
}
|
|
3041
|
+
const availableLength = maxLength - ellipsis.length;
|
|
3042
|
+
if (availableLength <= 0) {
|
|
3043
|
+
return ellipsis.slice(0, maxLength);
|
|
3044
|
+
}
|
|
3045
|
+
let truncated = text.slice(0, availableLength);
|
|
3046
|
+
if (wordBoundary) {
|
|
3047
|
+
const lastSpaceIndex = truncated.lastIndexOf(" ");
|
|
3048
|
+
if (lastSpaceIndex > 0) {
|
|
3049
|
+
truncated = truncated.slice(0, lastSpaceIndex);
|
|
3050
|
+
}
|
|
3051
|
+
}
|
|
3052
|
+
truncated = truncated.trimEnd();
|
|
3053
|
+
return truncated + ellipsis;
|
|
3054
|
+
}
|
|
3055
|
+
function extractWords(text, options) {
|
|
3056
|
+
if (!text || !text.trim()) {
|
|
3057
|
+
return [];
|
|
3058
|
+
}
|
|
3059
|
+
const {
|
|
3060
|
+
minLength = 0,
|
|
3061
|
+
includeHyphenated = true,
|
|
3062
|
+
lowercase = false
|
|
3063
|
+
} = options || {};
|
|
3064
|
+
let cleaned = text;
|
|
3065
|
+
if (includeHyphenated) {
|
|
3066
|
+
cleaned = text.replace(/[^\w\s-]/g, " ");
|
|
3067
|
+
} else {
|
|
3068
|
+
cleaned = text.replace(/[^\w\s]/g, " ");
|
|
3069
|
+
}
|
|
3070
|
+
const words = cleaned.split(/\s+/).map((word) => word.trim()).filter((word) => word.length > 0).filter((word) => !/^-+$/.test(word));
|
|
3071
|
+
let result = words;
|
|
3072
|
+
if (minLength > 0) {
|
|
3073
|
+
result = result.filter((word) => word.length >= minLength);
|
|
3074
|
+
}
|
|
3075
|
+
if (lowercase) {
|
|
3076
|
+
result = result.map((word) => word.toLowerCase());
|
|
3077
|
+
}
|
|
3078
|
+
return result;
|
|
3079
|
+
}
|
|
3080
|
+
|
|
3081
|
+
// src/text/compare.ts
|
|
3082
|
+
function compareStrings(str1, str2, options) {
|
|
3083
|
+
if (str1 === str2) {
|
|
3084
|
+
return true;
|
|
3085
|
+
}
|
|
3086
|
+
const s1 = str1 || "";
|
|
3087
|
+
const s2 = str2 || "";
|
|
3088
|
+
const {
|
|
3089
|
+
caseSensitive = false,
|
|
3090
|
+
ignoreWhitespace = false,
|
|
3091
|
+
ignoreAccents = false
|
|
3092
|
+
} = options || {};
|
|
3093
|
+
let normalized1 = s1;
|
|
3094
|
+
let normalized2 = s2;
|
|
3095
|
+
if (ignoreWhitespace) {
|
|
3096
|
+
normalized1 = normalizeWhitespace(normalized1);
|
|
3097
|
+
normalized2 = normalizeWhitespace(normalized2);
|
|
3098
|
+
}
|
|
3099
|
+
if (ignoreAccents) {
|
|
3100
|
+
normalized1 = removeAccents(normalized1);
|
|
3101
|
+
normalized2 = removeAccents(normalized2);
|
|
3102
|
+
}
|
|
3103
|
+
if (!caseSensitive) {
|
|
3104
|
+
normalized1 = normalized1.toLowerCase();
|
|
3105
|
+
normalized2 = normalized2.toLowerCase();
|
|
3106
|
+
}
|
|
3107
|
+
return normalized1 === normalized2;
|
|
3108
|
+
}
|
|
3109
|
+
function similarity(str1, str2) {
|
|
3110
|
+
if (str1 === str2) return 1;
|
|
3111
|
+
if (str1.length === 0) return str2.length === 0 ? 1 : 0;
|
|
3112
|
+
if (str2.length === 0) return 0;
|
|
3113
|
+
const len1 = str1.length;
|
|
3114
|
+
const len2 = str2.length;
|
|
3115
|
+
let prevRow = Array(len2 + 1).fill(0);
|
|
3116
|
+
let currentRow = Array(len2 + 1).fill(0);
|
|
3117
|
+
for (let j = 0; j <= len2; j++) {
|
|
3118
|
+
prevRow[j] = j;
|
|
3119
|
+
}
|
|
3120
|
+
for (let i = 1; i <= len1; i++) {
|
|
3121
|
+
currentRow[0] = i;
|
|
3122
|
+
for (let j = 1; j <= len2; j++) {
|
|
3123
|
+
const cost = str1[i - 1] === str2[j - 1] ? 0 : 1;
|
|
3124
|
+
currentRow[j] = Math.min(
|
|
3125
|
+
currentRow[j - 1] + 1,
|
|
3126
|
+
// Insertion
|
|
3127
|
+
prevRow[j] + 1,
|
|
3128
|
+
// Deletion
|
|
3129
|
+
prevRow[j - 1] + cost
|
|
3130
|
+
// Substitution
|
|
3131
|
+
);
|
|
3132
|
+
}
|
|
3133
|
+
[prevRow, currentRow] = [currentRow, prevRow];
|
|
3134
|
+
}
|
|
3135
|
+
const distance = prevRow[len2];
|
|
3136
|
+
const maxLength = Math.max(len1, len2);
|
|
3137
|
+
return 1 - distance / maxLength;
|
|
3138
|
+
}
|
|
3139
|
+
|
|
3140
|
+
export { addRupiahSymbol, calculateTax, capitalize2 as capitalize, cleanPhoneNumber, compareStrings, contractAbbreviation, expandAbbreviation, extractWords, formatAccounting, formatBirthDate, formatCompact, formatNIK, formatNPWP, formatPhoneNumber, formatPlate, formatRupiah, generateSmsLink, generateTelLink, generateWALink, getAge, getOperator, getRegionFromPlate, isAlay, isLandlineNumber, isMobileNumber, isProvider, isValidForBirthDate, isValidForGender, maskNIK, maskNPWP, maskPhoneNumber, normalizeWhitespace, parseNIK, parseNPWP, parsePhoneNumber, parseRupiah, profanityFilter, removeAccents, removeStopwords, roundToClean, sanitize, similarity, slugify, toE164, toFormal, toInternational, toNational, toSentenceCase, toTitleCase, toWords, truncate, validateNIK, validateNPWP, validatePhoneNumber, validatePlate };
|
|
1152
3141
|
//# sourceMappingURL=index.js.map
|
|
1153
3142
|
//# sourceMappingURL=index.js.map
|