@indodev/toolkit 0.2.0 → 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/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,37 @@ function capitalize(str) {
1148
1404
  return str.charAt(0).toUpperCase() + str.slice(1);
1149
1405
  }
1150
1406
 
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
+
1151
1438
  // src/text/constants.ts
1152
1439
  var LOWERCASE_WORDS = [
1153
1440
  // Indonesian prepositions (kata depan)
@@ -1598,6 +1885,741 @@ var ABBREVIATIONS = {
1598
1885
  "m3.": "meter kubik",
1599
1886
  "ha.": "hektar"
1600
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
+ ];
1601
2623
 
1602
2624
  // src/text/capitalization.ts
1603
2625
  function capitalize2(text) {
@@ -1935,6 +2957,78 @@ function contractAbbreviation(text, options) {
1935
2957
  return result;
1936
2958
  }
1937
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
+
1938
3032
  // src/text/extract.ts
1939
3033
  function truncate(text, maxLength, options) {
1940
3034
  if (!text || maxLength <= 0) {
@@ -2043,6 +3137,6 @@ function similarity(str1, str2) {
2043
3137
  return 1 - distance / maxLength;
2044
3138
  }
2045
3139
 
2046
- export { capitalize2 as capitalize, cleanPhoneNumber, compareStrings, contractAbbreviation, expandAbbreviation, extractWords, formatCompact, formatNIK, formatPhoneNumber, formatRupiah, getOperator, isLandlineNumber, isMobileNumber, maskNIK, maskPhoneNumber, normalizeWhitespace, parseNIK, parsePhoneNumber, parseRupiah, removeAccents, sanitize, similarity, slugify, toE164, toInternational, toNational, toSentenceCase, toTitleCase, toWords, truncate, validateNIK, validatePhoneNumber };
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 };
2047
3141
  //# sourceMappingURL=index.js.map
2048
3142
  //# sourceMappingURL=index.js.map