@indodev/toolkit 0.3.3 → 0.4.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.
@@ -1,407 +1,103 @@
1
- /**
2
- * Currency module types for Indonesian Rupiah utilities.
3
- *
4
- * @module currency/types
5
- * @packageDocumentation
6
- */
7
- /**
8
- * Options for formatting Rupiah currency.
9
- *
10
- * @example
11
- * Default formatting:
12
- * ```typescript
13
- * const options: RupiahOptions = {
14
- * symbol: true,
15
- * decimal: false,
16
- * separator: '.',
17
- * };
18
- * formatRupiah(1500000, options); // 'Rp 1.500.000'
19
- * ```
20
- *
21
- * @example
22
- * With decimals:
23
- * ```typescript
24
- * const options: RupiahOptions = {
25
- * symbol: true,
26
- * decimal: true,
27
- * precision: 2,
28
- * };
29
- * formatRupiah(1500000.50, options); // 'Rp 1.500.000,50'
30
- * ```
31
- *
32
- * @public
33
- */
34
- interface RupiahOptions {
35
- /**
36
- * Whether to show 'Rp' symbol.
37
- *
38
- * @defaultValue true
39
- */
40
- symbol?: boolean;
41
- /**
42
- * Whether to show decimal places.
43
- *
44
- * @defaultValue false
45
- */
46
- decimal?: boolean;
47
- /**
48
- * Thousands separator character.
49
- *
50
- * @defaultValue '.'
51
- *
52
- * @example
53
- * ```typescript
54
- * '.' // Indonesian standard
55
- * ',' // International standard
56
- * ' ' // Space separator
57
- * ```
58
- */
59
- separator?: string;
60
- /**
61
- * Decimal separator character.
62
- *
63
- * @defaultValue ','
64
- *
65
- * @example
66
- * ```typescript
67
- * ',' // Indonesian standard
68
- * '.' // International standard
69
- * ```
70
- */
71
- decimalSeparator?: string;
72
- /**
73
- * Number of decimal places to show.
74
- *
75
- * @defaultValue 0
76
- */
77
- precision?: number;
78
- /**
79
- * Whether to add space after 'Rp' symbol.
80
- *
81
- * @defaultValue true
82
- *
83
- * @example
84
- * ```typescript
85
- * true // 'Rp 1.500.000'
86
- * false // 'Rp1.500.000'
87
- * ```
88
- */
89
- spaceAfterSymbol?: boolean;
90
- }
91
- /**
92
- * Options for converting numbers to Indonesian words (terbilang).
93
- *
94
- * @example
95
- * Default:
96
- * ```typescript
97
- * toWords(1500000); // 'satu juta lima ratus ribu rupiah'
98
- * ```
99
- *
100
- * @example
101
- * Uppercase:
102
- * ```typescript
103
- * toWords(1500000, { uppercase: true });
104
- * // 'Satu juta lima ratus ribu rupiah'
105
- * ```
106
- *
107
- * @example
108
- * Without currency suffix:
109
- * ```typescript
110
- * toWords(1500000, { withCurrency: false });
111
- * // 'satu juta lima ratus ribu'
112
- * ```
113
- *
114
- * @public
115
- */
116
- interface WordOptions {
117
- /**
118
- * Whether to capitalize the first letter.
119
- *
120
- * @defaultValue false
121
- *
122
- * @example
123
- * ```typescript
124
- * false // 'satu juta'
125
- * true // 'Satu juta'
126
- * ```
127
- */
128
- uppercase?: boolean;
129
- /**
130
- * Whether to add 'rupiah' at the end.
131
- *
132
- * @defaultValue true
133
- *
134
- * @example
135
- * ```typescript
136
- * true // 'satu juta rupiah'
137
- * false // 'satu juta'
138
- * ```
139
- */
140
- withCurrency?: boolean;
141
- }
142
- /**
143
- * Unit for rounding currency amounts.
144
- *
145
- * Common Indonesian currency rounding units:
146
- * - `'ribu'`: Round to thousands (1.000)
147
- * - `'ratus-ribu'`: Round to hundred thousands (100.000)
148
- * - `'juta'`: Round to millions (1.000.000)
149
- *
150
- * @example
151
- * ```typescript
152
- * roundToClean(1234567, 'ribu'); // 1235000
153
- * roundToClean(1234567, 'ratus-ribu'); // 1200000
154
- * roundToClean(1234567, 'juta'); // 1000000
155
- * ```
156
- *
157
- * @public
158
- */
159
- type RoundUnit = 'ribu' | 'ratus-ribu' | 'juta';
160
-
161
- /**
162
- * Currency formatting utilities for Indonesian Rupiah.
163
- *
164
- * @module currency/format
165
- * @packageDocumentation
166
- */
1
+ import { S as SplitOptions } from '../utils-OG1yMaAa.js';
2
+ export { C as CompactOptions, e as RoundUnit, R as RupiahOptions, W as WordOptions, d as addRupiahSymbol, c as calculateTax, b as formatAccounting, a as formatCompact, f as formatRupiah, p as parseRupiah, r as roundToClean, t as toWords } from '../utils-OG1yMaAa.js';
167
3
 
168
4
  /**
169
- * Formats a number as Indonesian Rupiah currency.
170
- *
171
- * Provides flexible formatting options including symbol display,
172
- * decimal places, and custom separators.
173
- *
174
- * @param amount - The amount to format
175
- * @param options - Formatting options
176
- * @returns Formatted Rupiah string
177
- *
178
- * @example
179
- * Basic formatting:
180
- * ```typescript
181
- * formatRupiah(1500000); // 'Rp 1.500.000'
182
- * ```
183
- *
184
- * @example
185
- * With decimals:
186
- * ```typescript
187
- * formatRupiah(1500000.50, { decimal: true }); // 'Rp 1.500.000,50'
188
- * ```
189
- *
190
- * @example
191
- * Without symbol:
192
- * ```typescript
193
- * formatRupiah(1500000, { symbol: false }); // '1.500.000'
194
- * ```
195
- *
196
- * @example
197
- * Custom separators:
198
- * ```typescript
199
- * formatRupiah(1500000, { separator: ',' }); // 'Rp 1,500,000'
200
- * ```
5
+ * Invalid split error thrown when split parameters are invalid.
201
6
  *
202
7
  * @public
203
8
  */
204
- declare function formatRupiah(amount: number, options?: RupiahOptions): string;
9
+ declare class InvalidSplitError extends Error {
10
+ constructor(message: string);
11
+ }
205
12
  /**
206
- * Formats a number in compact Indonesian format.
207
- *
208
- * Uses Indonesian units: ribu, juta, miliar, triliun.
209
- * Follows Indonesian grammar rules (e.g., "1 juta" not "1,0 juta").
13
+ * Splits an amount into equal or custom-ratio parts.
210
14
  *
211
- * @param amount - The amount to format
212
- * @returns Compact formatted string
15
+ * @param amount - The amount to split
16
+ * @param parts - Number of parts to split into
17
+ * @param options - Split options (ratios, rounding)
18
+ * @returns Array of split amounts
213
19
  *
214
20
  * @example
215
- * Millions:
21
+ * Equal split:
216
22
  * ```typescript
217
- * formatCompact(1500000); // 'Rp 1,5 juta'
218
- * formatCompact(1000000); // 'Rp 1 juta'
23
+ * splitAmount(1500000, 3); // [500000, 500000, 500000]
219
24
  * ```
220
25
  *
221
26
  * @example
222
- * Thousands:
27
+ * Custom ratios:
223
28
  * ```typescript
224
- * formatCompact(500000); // 'Rp 500 ribu'
29
+ * splitAmount(1000000, 2, { ratios: [70, 30] }); // [700000, 300000]
225
30
  * ```
226
31
  *
227
32
  * @example
228
- * Small numbers:
33
+ * With rounding:
229
34
  * ```typescript
230
- * formatCompact(1500); // 'Rp 1.500'
35
+ * splitAmount(1234567, 3, { roundTo: 'ribu' }); // [412000, 411000, 411000]
231
36
  * ```
232
37
  *
233
38
  * @public
234
39
  */
235
- declare function formatCompact(amount: number): string;
236
-
237
- /**
238
- * Currency parsing utilities for Indonesian Rupiah.
239
- *
240
- * @module currency/parse
241
- * @packageDocumentation
242
- */
40
+ declare function splitAmount(amount: number, parts: number, options?: SplitOptions): number[];
243
41
  /**
244
- * Parses a formatted Rupiah string back to a number.
245
- *
246
- * Handles multiple formats:
247
- * - Standard: "Rp 1.500.000"
248
- * - No symbol: "1.500.000"
249
- * - With decimals: "Rp 1.500.000,50"
250
- * - Compact: "Rp 1,5 juta", "Rp 500 ribu"
251
- *
252
- * @param formatted - The formatted Rupiah string to parse
253
- * @returns Parsed number, or null if invalid
254
- *
255
- * @example
256
- * Standard format:
257
- * ```typescript
258
- * parseRupiah('Rp 1.500.000'); // 1500000
259
- * ```
260
- *
261
- * @example
262
- * With decimals:
263
- * ```typescript
264
- * parseRupiah('Rp 1.500.000,50'); // 1500000.50
265
- * ```
42
+ * Calculates what percentage a part is of a total.
266
43
  *
267
- * @example
268
- * Compact format:
269
- * ```typescript
270
- * parseRupiah('Rp 1,5 juta'); // 1500000
271
- * parseRupiah('Rp 500 ribu'); // 500000
272
- * ```
44
+ * @param part - The part value
45
+ * @param total - The total value
46
+ * @returns Percentage as number (e.g., 15 for 15%)
273
47
  *
274
48
  * @example
275
- * Invalid input:
276
49
  * ```typescript
277
- * parseRupiah('invalid'); // null
50
+ * percentageOf(150000, 1000000); // 15
51
+ * percentageOf(0, 1000000); // 0
52
+ * percentageOf(100, 0); // 0 (not NaN)
278
53
  * ```
279
54
  *
280
55
  * @public
281
56
  */
282
- declare function parseRupiah(formatted: string): number | null;
283
-
284
- /**
285
- * Convert numbers to Indonesian words (terbilang).
286
- *
287
- * @module currency/words
288
- * @packageDocumentation
289
- */
290
-
57
+ declare function percentageOf(part: number, total: number): number;
291
58
  /**
292
- * Converts a number to Indonesian words (terbilang).
59
+ * Calculates absolute and percentage difference between two amounts.
293
60
  *
294
- * Supports numbers up to trillions (triliun).
295
- * Follows Indonesian language rules for number pronunciation.
296
- *
297
- * Special rules:
298
- * - 1 = "satu" in most cases, but "se-" for 100, 1000
299
- * - 11 = "sebelas" (not "satu belas")
300
- * - 100 = "seratus" (not "satu ratus")
301
- * - 1000 = "seribu" (not "satu ribu")
302
- *
303
- * @param amount - The number to convert
304
- * @param options - Conversion options
305
- * @returns Indonesian words representation
61
+ * @param amount1 - The new/current amount
62
+ * @param amount2 - The original/reference amount
63
+ * @returns Object with absolute difference, percentage, and direction
306
64
  *
307
65
  * @example
308
- * Basic numbers:
309
66
  * ```typescript
310
- * toWords(123); // 'seratus dua puluh tiga rupiah'
311
- * ```
67
+ * difference(1200000, 1000000);
68
+ * // { absolute: 200000, percentage: 20, direction: 'increase' }
312
69
  *
313
- * @example
314
- * Large numbers:
315
- * ```typescript
316
- * toWords(1500000); // 'satu juta lima ratus ribu rupiah'
317
- * ```
318
- *
319
- * @example
320
- * With options:
321
- * ```typescript
322
- * toWords(1500000, { uppercase: true });
323
- * // 'Satu juta lima ratus ribu rupiah'
324
- *
325
- * toWords(1500000, { withCurrency: false });
326
- * // 'satu juta lima ratus ribu'
70
+ * difference(0, 1000000);
71
+ * // { absolute: -1000000, percentage: null, direction: 'decrease' }
327
72
  * ```
328
73
  *
329
74
  * @public
330
75
  */
331
- declare function toWords(amount: number, options?: WordOptions): string;
332
-
333
- /**
334
- * Currency utility functions.
335
- *
336
- * @module currency/utils
337
- * @packageDocumentation
338
- */
76
+ declare function difference(amount1: number, amount2: number): {
77
+ absolute: number;
78
+ percentage: number | null;
79
+ direction: 'increase' | 'decrease' | 'same';
80
+ };
339
81
 
340
82
  /**
341
- * Rounds a number to a clean currency amount.
342
- *
343
- * Common use case: displaying approximate prices or budgets
344
- * in clean, rounded numbers.
345
- *
346
- * @param amount - The amount to round
347
- * @param unit - The unit to round to (default: 'ribu')
348
- * @returns Rounded amount
83
+ * Validates whether a string is a valid Rupiah format.
349
84
  *
350
- * @example
351
- * Round to thousands:
352
- * ```typescript
353
- * roundToClean(1234567, 'ribu'); // 1235000
354
- * ```
85
+ * Accepts standard, compact, and negative formats.
355
86
  *
356
- * @example
357
- * Round to hundred thousands:
358
- * ```typescript
359
- * roundToClean(1234567, 'ratus-ribu'); // 1200000
360
- * ```
87
+ * @param formatted - The string to validate
88
+ * @returns `true` if valid Rupiah format, `false` otherwise
361
89
  *
362
90
  * @example
363
- * Round to millions:
364
91
  * ```typescript
365
- * roundToClean(1234567, 'juta'); // 1000000
92
+ * validateRupiah('Rp 1.500.000'); // true
93
+ * validateRupiah('1.500.000'); // true
94
+ * validateRupiah('Rp 1,5 juta'); // true
95
+ * validateRupiah('abc'); // false
96
+ * validateRupiah(''); // false
366
97
  * ```
367
98
  *
368
99
  * @public
369
100
  */
370
- declare function roundToClean(amount: number, unit?: RoundUnit): number;
371
- /**
372
- * Formats a number as Indonesian Rupiah in accounting style.
373
- * Negative numbers are wrapped in parentheses.
374
- *
375
- * @param amount - The amount to format
376
- * @param options - Formatting options
377
- * @returns Formatted accounting string
378
- *
379
- * @example
380
- * ```typescript
381
- * formatAccounting(-1500000); // '(Rp 1.500.000)'
382
- * ```
383
- */
384
- declare function formatAccounting(amount: number, options?: RupiahOptions): string;
385
- /**
386
- * Calculates tax (PPN) for a given amount.
387
- *
388
- * @param amount - The base amount
389
- * @param rate - The tax rate (default: 0.11 for 11%)
390
- * @returns The calculated tax amount
391
- *
392
- * @example
393
- * ```typescript
394
- * calculateTax(1000000); // 110000
395
- * ```
396
- */
397
- declare function calculateTax(amount: number, rate?: number): number;
398
- /**
399
- * Helper to ensure a string or number has the 'Rp ' prefix.
400
- * If already prefixed, it returns the input as is.
401
- *
402
- * @param amount - The amount or formatted string
403
- * @returns String with Rupiah prefix
404
- */
405
- declare function addRupiahSymbol(amount: string | number): string;
101
+ declare function validateRupiah(formatted: string): boolean;
406
102
 
407
- export { type RoundUnit, type RupiahOptions, type WordOptions, addRupiahSymbol, calculateTax, formatAccounting, formatCompact, formatRupiah, parseRupiah, roundToClean, toWords };
103
+ export { InvalidSplitError, SplitOptions, difference, percentageOf, splitAmount, validateRupiah };
@@ -8,7 +8,7 @@ function formatRupiah(amount, options) {
8
8
  spaceAfterSymbol = true
9
9
  } = options || {};
10
10
  const precision = options?.precision !== void 0 ? options.precision : decimal ? 2 : 0;
11
- const isNegative = amount < 0;
11
+ const isNegative = amount < 0 && amount !== 0;
12
12
  const absAmount = Math.abs(amount);
13
13
  let result;
14
14
  if (decimal) {
@@ -26,17 +26,21 @@ function formatRupiah(amount, options) {
26
26
  const intAmount = Math.floor(absAmount);
27
27
  result = intAmount.toString().replace(/\B(?=(\d{3})+(?!\d))/g, separator);
28
28
  }
29
- if (isNegative) {
30
- result = `-${result}`;
31
- }
32
29
  if (symbol) {
33
30
  const space = spaceAfterSymbol ? " " : "";
34
- result = `Rp${space}${result}`;
31
+ if (isNegative) {
32
+ result = `-Rp${space}${result}`;
33
+ } else {
34
+ result = `Rp${space}${result}`;
35
+ }
36
+ } else if (isNegative) {
37
+ result = `-${result}`;
35
38
  }
36
39
  return result;
37
40
  }
38
- function formatCompact(amount) {
39
- const isNegative = amount < 0;
41
+ function formatCompact(amount, options) {
42
+ const { symbol = true, spaceAfterSymbol = true } = options || {};
43
+ const isNegative = amount < 0 && amount !== 0;
40
44
  const abs = Math.abs(amount);
41
45
  let result;
42
46
  if (abs >= 1e12) {
@@ -52,10 +56,17 @@ function formatCompact(amount) {
52
56
  } else {
53
57
  result = abs.toString();
54
58
  }
55
- if (isNegative) {
59
+ if (symbol) {
60
+ const space = spaceAfterSymbol ? " " : "";
61
+ if (isNegative) {
62
+ result = `-Rp${space}${result}`;
63
+ } else {
64
+ result = `Rp${space}${result}`;
65
+ }
66
+ } else if (isNegative) {
56
67
  result = `-${result}`;
57
68
  }
58
- return `Rp ${result}`;
69
+ return result;
59
70
  }
60
71
  function formatCompactValue(value, unit) {
61
72
  const rounded = Math.round(value * 10) / 10;
@@ -152,20 +163,42 @@ var TENS = [
152
163
  "sembilan puluh"
153
164
  ];
154
165
  function toWords(amount, options) {
155
- const { uppercase = false, withCurrency = true } = options || {};
166
+ const {
167
+ uppercase = false,
168
+ withCurrency = true,
169
+ withDecimals = false
170
+ } = options || {};
156
171
  if (amount === 0) {
157
172
  let result = "nol";
158
173
  if (withCurrency) result += " rupiah";
159
174
  return uppercase ? capitalize(result) : result;
160
175
  }
161
176
  const isNegative = amount < 0;
162
- const absAmount = Math.floor(Math.abs(amount));
177
+ const absAmount = Math.abs(amount);
178
+ const intPart = Math.floor(absAmount);
179
+ let words = convertInteger(intPart);
180
+ if (isNegative) {
181
+ words = "minus " + words;
182
+ }
183
+ if (withCurrency) {
184
+ words += " rupiah";
185
+ }
186
+ if (withDecimals) {
187
+ const decimalPart = Math.round((absAmount - intPart) * 100);
188
+ if (decimalPart > 0) {
189
+ words += " koma " + convertDecimal(decimalPart);
190
+ }
191
+ }
192
+ return uppercase ? capitalize(words) : words;
193
+ }
194
+ function convertInteger(num) {
195
+ if (num === 0) return "nol";
163
196
  let words = "";
164
- const triliun = Math.floor(absAmount / 1e12);
165
- const miliar = Math.floor(absAmount % 1e12 / 1e9);
166
- const juta = Math.floor(absAmount % 1e9 / 1e6);
167
- const ribu = Math.floor(absAmount % 1e6 / 1e3);
168
- const sisa = absAmount % 1e3;
197
+ const triliun = Math.floor(num / 1e12);
198
+ const miliar = Math.floor(num % 1e12 / 1e9);
199
+ const juta = Math.floor(num % 1e9 / 1e6);
200
+ const ribu = Math.floor(num % 1e6 / 1e3);
201
+ const sisa = num % 1e3;
169
202
  if (triliun > 0) {
170
203
  words += convertGroup(triliun) + " triliun";
171
204
  }
@@ -185,13 +218,19 @@ function toWords(amount, options) {
185
218
  if (words) words += " ";
186
219
  words += convertGroup(sisa);
187
220
  }
188
- if (isNegative) {
189
- words = "minus " + words;
190
- }
191
- if (withCurrency) {
192
- words += " rupiah";
221
+ return words;
222
+ }
223
+ function convertDecimal(num) {
224
+ if (num === 0) return "";
225
+ if (num < 10) return BASIC_NUMBERS[num];
226
+ if (num < 20) return TEENS[num - 10];
227
+ const tens = Math.floor(num / 10);
228
+ const ones = num % 10;
229
+ let result = TENS[tens];
230
+ if (ones > 0) {
231
+ result += " " + BASIC_NUMBERS[ones];
193
232
  }
194
- return uppercase ? capitalize(words) : words;
233
+ return result;
195
234
  }
196
235
  function convertGroup(num) {
197
236
  if (num === 0) return "";
@@ -241,19 +280,108 @@ function formatAccounting(amount, options) {
241
280
  }
242
281
  return formatted;
243
282
  }
244
- function calculateTax(amount, rate = 0.11) {
283
+ function calculateTax(amount, rate) {
245
284
  return amount * rate;
246
285
  }
247
286
  function addRupiahSymbol(amount) {
248
287
  if (typeof amount === "number") {
249
- return `Rp ${amount.toLocaleString("id-ID")}`;
288
+ const formatted = amount.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ".");
289
+ return `Rp ${formatted}`;
250
290
  }
251
291
  if (amount.trim().startsWith("Rp")) {
252
- return amount;
292
+ return amount.trim();
253
293
  }
254
294
  return `Rp ${amount.trim()}`;
255
295
  }
256
296
 
257
- export { addRupiahSymbol, calculateTax, formatAccounting, formatCompact, formatRupiah, parseRupiah, roundToClean, toWords };
297
+ // src/currency/calc.ts
298
+ var InvalidSplitError = class extends Error {
299
+ constructor(message) {
300
+ super(message);
301
+ this.name = "InvalidSplitError";
302
+ }
303
+ };
304
+ function splitAmount(amount, parts, options) {
305
+ if (parts < 1) {
306
+ throw new InvalidSplitError("Parts must be at least 1");
307
+ }
308
+ if (parts === 1) {
309
+ return [amount];
310
+ }
311
+ const { ratios, roundTo } = options || {};
312
+ if (ratios) {
313
+ if (ratios.length !== parts) {
314
+ throw new InvalidSplitError(
315
+ `Ratios length (${ratios.length}) must match parts count (${parts})`
316
+ );
317
+ }
318
+ const sum = ratios.reduce((a, b) => a + b, 0);
319
+ if (Math.abs(sum - 100) > 0.01) {
320
+ throw new InvalidSplitError(`Ratios must sum to 100 (got ${sum})`);
321
+ }
322
+ let result2 = ratios.map((r) => amount * (r / 100));
323
+ if (roundTo) {
324
+ result2 = result2.map((v) => roundToClean2(v, roundTo));
325
+ }
326
+ return result2;
327
+ }
328
+ const base = Math.floor(amount / parts);
329
+ const remainder = amount - base * parts;
330
+ const result = [];
331
+ for (let i = 0; i < parts; i++) {
332
+ result.push(base + (i < remainder ? 1 : 0));
333
+ }
334
+ if (roundTo) {
335
+ return result.map((v) => roundToClean2(v, roundTo));
336
+ }
337
+ return result;
338
+ }
339
+ function percentageOf(part, total) {
340
+ if (total === 0) return 0;
341
+ return part / total * 100;
342
+ }
343
+ function difference(amount1, amount2) {
344
+ const absolute = amount1 - amount2;
345
+ let percentage;
346
+ if (amount2 === 0) {
347
+ percentage = amount1 === 0 ? 0 : null;
348
+ } else {
349
+ percentage = absolute / amount2 * 100;
350
+ }
351
+ const direction = absolute > 0 ? "increase" : absolute < 0 ? "decrease" : "same";
352
+ return { absolute, percentage, direction };
353
+ }
354
+ function roundToClean2(amount, unit) {
355
+ const divisors = {
356
+ ribu: 1e3,
357
+ "ratus-ribu": 1e5,
358
+ juta: 1e6
359
+ };
360
+ return Math.round(amount / divisors[unit]) * divisors[unit];
361
+ }
362
+
363
+ // src/currency/validate.ts
364
+ function validateRupiah(formatted) {
365
+ if (!formatted || typeof formatted !== "string") {
366
+ return false;
367
+ }
368
+ const trimmed = formatted.trim();
369
+ if (!trimmed) return false;
370
+ const compactUnits = ["triliun", "miliar", "juta", "ribu"];
371
+ for (const unit of compactUnits) {
372
+ if (trimmed.toLowerCase().includes(unit)) {
373
+ return /-?\d+[,.]?\d*\s*(ribu|juta|miliar|triliun)/i.test(trimmed);
374
+ }
375
+ }
376
+ let cleaned = trimmed.replace(/^(-?\s*)?Rp\s*/i, "");
377
+ cleaned = cleaned.replace(/^\s*-/, "");
378
+ cleaned = cleaned.trim();
379
+ if (!cleaned) return false;
380
+ if (!/^[0-9.,]+$/.test(cleaned)) return false;
381
+ if (!/\d/.test(cleaned)) return false;
382
+ return true;
383
+ }
384
+
385
+ export { InvalidSplitError, addRupiahSymbol, calculateTax, difference, formatAccounting, formatCompact, formatRupiah, parseRupiah, percentageOf, roundToClean, splitAmount, toWords, validateRupiah };
258
386
  //# sourceMappingURL=index.js.map
259
387
  //# sourceMappingURL=index.js.map