ceylon-devkit 0.0.0-stage → 1.0.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 ADDED
@@ -0,0 +1,612 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
3
+ var __getOwnPropNames = Object.getOwnPropertyNames;
4
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
5
+ var __export = (target, all) => {
6
+ for (var name in all)
7
+ __defProp(target, name, { get: all[name], enumerable: true });
8
+ };
9
+ var __copyProps = (to, from, except, desc) => {
10
+ if (from && typeof from === "object" || typeof from === "function") {
11
+ for (let key of __getOwnPropNames(from))
12
+ if (!__hasOwnProp.call(to, key) && key !== except)
13
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
14
+ }
15
+ return to;
16
+ };
17
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
18
+
19
+ // src/index.ts
20
+ var index_exports = {};
21
+ __export(index_exports, {
22
+ SRI_LANKAN_BANKS: () => SRI_LANKAN_BANKS,
23
+ SRI_LANKAN_BRANCHES: () => SRI_LANKAN_BRANCHES,
24
+ SRI_LANKAN_HOLIDAYS: () => SRI_LANKAN_HOLIDAYS,
25
+ addWorkingDays: () => addWorkingDays,
26
+ calculateTax: () => calculateTax,
27
+ findBank: () => findBank,
28
+ findBranch: () => findBranch,
29
+ formatLKR: () => formatLKR,
30
+ getBanks: () => getBanks,
31
+ getBranches: () => getBranches,
32
+ getHoliday: () => getHoliday,
33
+ getWorkingDays: () => getWorkingDays,
34
+ isWeekend: () => isWeekend,
35
+ isWorkingDay: () => isWorkingDay,
36
+ lkrToWords: () => lkrToWords,
37
+ validateTIN: () => validateTIN,
38
+ validateVAT: () => validateVAT
39
+ });
40
+ module.exports = __toCommonJS(index_exports);
41
+
42
+ // src/currency/index.ts
43
+ var EN_ONES = [
44
+ "",
45
+ "One",
46
+ "Two",
47
+ "Three",
48
+ "Four",
49
+ "Five",
50
+ "Six",
51
+ "Seven",
52
+ "Eight",
53
+ "Nine",
54
+ "Ten",
55
+ "Eleven",
56
+ "Twelve",
57
+ "Thirteen",
58
+ "Fourteen",
59
+ "Fifteen",
60
+ "Sixteen",
61
+ "Seventeen",
62
+ "Eighteen",
63
+ "Nineteen"
64
+ ];
65
+ var EN_TENS = [
66
+ "",
67
+ "",
68
+ "Twenty",
69
+ "Thirty",
70
+ "Forty",
71
+ "Fifty",
72
+ "Sixty",
73
+ "Seventy",
74
+ "Eighty",
75
+ "Ninety"
76
+ ];
77
+ function convertThreeDigitEnglish(num) {
78
+ let str = "";
79
+ const hundred = Math.floor(num / 100);
80
+ const remainder = num % 100;
81
+ if (hundred > 0) {
82
+ str += `${EN_ONES[hundred]} Hundred`;
83
+ if (remainder > 0) str += " ";
84
+ }
85
+ if (remainder > 0) {
86
+ if (remainder < 20) {
87
+ str += EN_ONES[remainder];
88
+ } else {
89
+ const ten = Math.floor(remainder / 10);
90
+ const one = remainder % 10;
91
+ str += EN_TENS[ten];
92
+ if (one > 0) str += ` ${EN_ONES[one]}`;
93
+ }
94
+ }
95
+ return str.trim();
96
+ }
97
+ function integerToEnglishWords(num) {
98
+ if (num === 0) return "Zero";
99
+ const parts = [];
100
+ const crores = Math.floor(num / 1e7);
101
+ num %= 1e7;
102
+ if (crores > 0) parts.push(`${integerToEnglishWords(crores)} Crore`);
103
+ const lakhs = Math.floor(num / 1e5);
104
+ num %= 1e5;
105
+ if (lakhs > 0) parts.push(`${convertThreeDigitEnglish(lakhs)} Lakh`);
106
+ const thousands = Math.floor(num / 1e3);
107
+ num %= 1e3;
108
+ if (thousands > 0) parts.push(`${convertThreeDigitEnglish(thousands)} Thousand`);
109
+ if (num > 0) parts.push(convertThreeDigitEnglish(num));
110
+ return parts.join(" ");
111
+ }
112
+ var SI_ONES = [
113
+ "",
114
+ "\u0D91\u0D9A",
115
+ "\u0DAF\u0DD9\u0D9A",
116
+ "\u0DAD\u0DD4\u0DB1",
117
+ "\u0DC4\u0DAD\u0DBB",
118
+ "\u0DB4\u0DC4",
119
+ "\u0DC4\u0DBA",
120
+ "\u0DC4\u0DAD",
121
+ "\u0D85\u0DA7",
122
+ "\u0DB1\u0DC0\u0DBA",
123
+ "\u0DAF\u0DC4\u0DBA",
124
+ "\u0D91\u0D9A\u0DDC\u0DC5\u0DC4",
125
+ "\u0DAF\u0DDC\u0DC5\u0DC4",
126
+ "\u0DAF\u0DC4\u0DAD\u0DD4\u0DB1",
127
+ "\u0DAF\u0DC4\u0DC4\u0DAD\u0DBB",
128
+ "\u0DB4\u0DC4\u0DC5\u0DDC\u0DC0",
129
+ "\u0DAF\u0DC4\u0DC3\u0DBA",
130
+ "\u0DAF\u0DCF\u0DC4\u0DAD",
131
+ "\u0DAF\u0DC4\u0D85\u0DA7",
132
+ "\u0DAF\u0DC4\u0DB1\u0DC0\u0DBA"
133
+ ];
134
+ var SI_ONES_SUFFIX = [
135
+ "",
136
+ "\u0D91\u0D9A\u0DBA\u0DD2",
137
+ "\u0DAF\u0DD9\u0D9A\u0DBA\u0DD2",
138
+ "\u0DAD\u0DD4\u0DB1\u0DBA\u0DD2",
139
+ "\u0DC4\u0DAD\u0DBB\u0DBA\u0DD2",
140
+ "\u0DB4\u0DC4\u0DBA\u0DD2",
141
+ "\u0DC4\u0DBA\u0DBA\u0DD2",
142
+ "\u0DC4\u0DAD\u0DBA\u0DD2",
143
+ "\u0D85\u0DA7\u0DBA\u0DD2",
144
+ "\u0DB1\u0DC0\u0DBA\u0DBA\u0DD2",
145
+ "\u0DAF\u0DC4\u0DBA\u0DBA\u0DD2",
146
+ "\u0D91\u0D9A\u0DDC\u0DC5\u0DC4\u0DBA\u0DD2",
147
+ "\u0DAF\u0DDC\u0DC5\u0DC4\u0DBA\u0DD2",
148
+ "\u0DAF\u0DC4\u0DAD\u0DD4\u0DB1\u0DBA\u0DD2",
149
+ "\u0DAF\u0DC4\u0DC4\u0DAD\u0DBB\u0DBA\u0DD2",
150
+ "\u0DB4\u0DC4\u0DC5\u0DDC\u0DC0\u0DBA\u0DD2",
151
+ "\u0DAF\u0DC4\u0DC3\u0DBA\u0DBA\u0DD2",
152
+ "\u0DAF\u0DCF\u0DC4\u0DAD\u0DBA\u0DD2",
153
+ "\u0DAF\u0DC4\u0D85\u0DA7\u0DBA\u0DD2",
154
+ "\u0DAF\u0DC4\u0DB1\u0DC0\u0DBA\u0DBA\u0DD2"
155
+ ];
156
+ var SI_TENS_PREFIX = [
157
+ "",
158
+ "",
159
+ "\u0DC0\u0DD2\u0DC3\u0DD2",
160
+ "\u0DAD\u0DD2\u0DC3\u0DCA",
161
+ "\u0DC4\u0DAD\u0DC5\u0DD2\u0DC3\u0DCA",
162
+ "\u0DB4\u0DB1\u0DC3\u0DCA",
163
+ "\u0DC4\u0DD0\u0DA7",
164
+ "\u0DC4\u0DD0\u0DAD\u0DCA\u0DAD\u0DD1",
165
+ "\u0D85\u0DC3\u0DD6",
166
+ "\u0D85\u0DB1\u0DD6"
167
+ ];
168
+ var SI_TENS_SUFFIX = [
169
+ "",
170
+ "",
171
+ "\u0DC0\u0DD2\u0DC3\u0DCA\u0DC3\u0DBA\u0DD2",
172
+ "\u0DAD\u0DD2\u0DC4\u0DBA\u0DD2",
173
+ "\u0DC4\u0DAD\u0DC5\u0DD2\u0DC4\u0DBA\u0DD2",
174
+ "\u0DB4\u0DB1\u0DC4\u0DBA\u0DD2",
175
+ "\u0DC4\u0DD0\u0DA7\u0DBA\u0DD2",
176
+ "\u0DC4\u0DD0\u0DAD\u0DCA\u0DAD\u0DD1\u0DC0\u0DBA\u0DD2",
177
+ "\u0D85\u0DC3\u0DD6\u0DC0\u0DBA\u0DD2",
178
+ "\u0D85\u0DB1\u0DD6\u0DC0\u0DBA\u0DD2"
179
+ ];
180
+ var SI_HUNDREDS = [
181
+ "",
182
+ "\u0D91\u0D9A\u0DCA\u0DC3\u0DD2\u0DBA",
183
+ "\u0DAF\u0DD9\u0DC3\u0DD2\u0DBA",
184
+ "\u0DAD\u0DD4\u0DB1\u0DCA\u0DC3\u0DD2\u0DBA",
185
+ "\u0DC4\u0DCF\u0DBB\u0DC3\u0DD2\u0DBA",
186
+ "\u0DB4\u0DB1\u0DCA\u0DC3\u0DD2\u0DBA",
187
+ "\u0DC4\u0DBA\u0DC3\u0DD2\u0DBA",
188
+ "\u0DC4\u0DAD\u0DCA\u0DC3\u0DD2\u0DBA",
189
+ "\u0D85\u0DA7\u0DC3\u0DD2\u0DBA",
190
+ "\u0DB1\u0DB8\u0DC3\u0DD2\u0DBA"
191
+ ];
192
+ function convertThreeDigitSinhala(num, isEnding) {
193
+ let str = "";
194
+ const hundred = Math.floor(num / 100);
195
+ const remainder = num % 100;
196
+ if (hundred > 0) {
197
+ if (remainder === 0 && isEnding) {
198
+ return hundred === 1 ? "\u0DC3\u0DD2\u0DBA\u0DBA\u0DBA\u0DD2" : `${SI_HUNDREDS[hundred]}\u0DBA\u0DD2`;
199
+ } else {
200
+ str += SI_HUNDREDS[hundred];
201
+ if (remainder > 0) str += " ";
202
+ }
203
+ }
204
+ if (remainder > 0) {
205
+ if (remainder < 20) {
206
+ str += isEnding ? SI_ONES_SUFFIX[remainder] : SI_ONES[remainder];
207
+ } else {
208
+ const ten = Math.floor(remainder / 10);
209
+ const one = remainder % 10;
210
+ if (one === 0) {
211
+ str += isEnding ? SI_TENS_SUFFIX[ten] : SI_TENS_PREFIX[ten];
212
+ } else {
213
+ str += `${SI_TENS_PREFIX[ten]} ${isEnding ? SI_ONES_SUFFIX[one] : SI_ONES[one]}`;
214
+ }
215
+ }
216
+ }
217
+ return str.trim();
218
+ }
219
+ function integerToSinhalaWords(num) {
220
+ if (num === 0) return "\u0DB6\u0DD2\u0D82\u0DAF\u0DD4\u0DC0\u0DBA\u0DD2";
221
+ const parts = [];
222
+ const crores = Math.floor(num / 1e7);
223
+ num %= 1e7;
224
+ if (crores > 0) {
225
+ const isEnd = num === 0;
226
+ parts.push(`${convertThreeDigitSinhala(crores, false)} ${isEnd ? "\u0D9A\u0DDD\u0DA7\u0DD2\u0DBA\u0DBA\u0DD2" : "\u0D9A\u0DDD\u0DA7\u0DD2"}`);
227
+ }
228
+ const lakhs = Math.floor(num / 1e5);
229
+ num %= 1e5;
230
+ if (lakhs > 0) {
231
+ const isEnd = num === 0;
232
+ parts.push(`${convertThreeDigitSinhala(lakhs, false)} ${isEnd ? "\u0DBD\u0D9A\u0DCA\u0DC2\u0DBA\u0DBA\u0DD2" : "\u0DBD\u0D9A\u0DCA\u0DC2"}`);
233
+ }
234
+ const thousands = Math.floor(num / 1e3);
235
+ num %= 1e3;
236
+ if (thousands > 0) {
237
+ const isEnd = num === 0;
238
+ if (thousands === 1) {
239
+ parts.push(isEnd ? "\u0D91\u0D9A\u0DCA\u0DAF\u0DC4\u0DC3\u0DBA\u0DD2" : "\u0D91\u0D9A\u0DCA\u0DAF\u0DC4\u0DC3\u0DCA");
240
+ } else {
241
+ parts.push(`${convertThreeDigitSinhala(thousands, false)} ${isEnd ? "\u0DAF\u0DC4\u0DC3\u0DBA\u0DD2" : "\u0DAF\u0DC4\u0DC3\u0DCA"}`);
242
+ }
243
+ }
244
+ if (num > 0) {
245
+ parts.push(convertThreeDigitSinhala(num, true));
246
+ }
247
+ return parts.join(" ").trim();
248
+ }
249
+ function lkrToWords(amount, options) {
250
+ if (isNaN(amount) || amount === null || amount === void 0) {
251
+ return "";
252
+ }
253
+ const lang = (options == null ? void 0 : options.lang) || "en";
254
+ const showOnly = (options == null ? void 0 : options.showOnly) ?? true;
255
+ const chequeFormat = (options == null ? void 0 : options.chequeFormat) ?? false;
256
+ const isNegative = amount < 0;
257
+ const absAmount = Math.abs(amount);
258
+ const rupees = Math.floor(absAmount);
259
+ const cents = Math.round((absAmount - rupees) * 100);
260
+ let result = "";
261
+ if (lang === "en") {
262
+ let rupeesText = "";
263
+ if (rupees === 0 && cents > 0) {
264
+ rupeesText = "";
265
+ } else if (rupees === 1) {
266
+ rupeesText = "One Rupee";
267
+ } else {
268
+ rupeesText = `${integerToEnglishWords(rupees)} Rupees`;
269
+ }
270
+ let centsText = "";
271
+ if (cents > 0) {
272
+ centsText = `${convertThreeDigitEnglish(cents)} Cent${cents === 1 ? "" : "s"}`;
273
+ }
274
+ if (rupeesText && centsText) {
275
+ result = `${rupeesText} and ${centsText}`;
276
+ } else if (rupeesText) {
277
+ result = rupeesText;
278
+ } else if (centsText) {
279
+ result = centsText;
280
+ } else {
281
+ result = "Zero Rupees";
282
+ }
283
+ if (showOnly) result += " Only";
284
+ if (isNegative) result = `Minus ${result}`;
285
+ } else {
286
+ let rupeesText = "";
287
+ if (rupees === 0 && cents > 0) {
288
+ rupeesText = "";
289
+ } else {
290
+ rupeesText = `\u0DBB\u0DD4\u0DB4\u0DD2\u0DBA\u0DBD\u0DCA ${integerToSinhalaWords(rupees)}`;
291
+ }
292
+ let centsText = "";
293
+ if (cents > 0) {
294
+ centsText = `\u0DC1\u0DAD ${convertThreeDigitSinhala(cents, true)}`;
295
+ }
296
+ if (rupeesText && centsText) {
297
+ result = `${rupeesText} ${centsText}`;
298
+ } else if (rupeesText) {
299
+ result = rupeesText;
300
+ } else if (centsText) {
301
+ result = centsText;
302
+ } else {
303
+ result = "\u0DBB\u0DD4\u0DB4\u0DD2\u0DBA\u0DBD\u0DCA \u0DB6\u0DD2\u0D82\u0DAF\u0DD4\u0DC0\u0DBA\u0DD2";
304
+ }
305
+ if (showOnly) result += " \u0DB4\u0DB8\u0DAB\u0DD2";
306
+ if (isNegative) result = `\u0D8D\u0DAB ${result}`;
307
+ }
308
+ if (chequeFormat) {
309
+ result = `*** ${result} ***`;
310
+ }
311
+ return result;
312
+ }
313
+ function formatLKR(amount, options) {
314
+ if (isNaN(amount) || amount === null || amount === void 0) {
315
+ return "";
316
+ }
317
+ const compactLang = (options == null ? void 0 : options.compactLang) ?? "en";
318
+ const defaultPrefix = compactLang === "si" ? "\u0DBB\u0DD4. " : "Rs. ";
319
+ const prefix = (options == null ? void 0 : options.prefix) ?? defaultPrefix;
320
+ const decimals = (options == null ? void 0 : options.decimals) ?? 2;
321
+ const compact = (options == null ? void 0 : options.compact) ?? false;
322
+ const isNegative = amount < 0;
323
+ const absAmount = Math.abs(amount);
324
+ if (compact) {
325
+ if (absAmount >= 1e7) {
326
+ const val = (absAmount / 1e7).toFixed(decimals);
327
+ const unit = compactLang === "si" ? "\u0D9A\u0DDD\u0DA7\u0DD2" : "Crores";
328
+ return `${isNegative ? "-" : ""}${prefix}${val} ${unit}`;
329
+ } else if (absAmount >= 1e5) {
330
+ const val = (absAmount / 1e5).toFixed(decimals);
331
+ const unit = compactLang === "si" ? "\u0DBD\u0D9A\u0DCA\u0DC2" : "Lakhs";
332
+ return `${isNegative ? "-" : ""}${prefix}${val} ${unit}`;
333
+ }
334
+ }
335
+ const formatted = absAmount.toLocaleString("en-US", {
336
+ minimumFractionDigits: decimals,
337
+ maximumFractionDigits: decimals
338
+ });
339
+ return `${isNegative ? "-" : ""}${prefix}${formatted}`;
340
+ }
341
+
342
+ // src/bank/index.ts
343
+ var SRI_LANKAN_BANKS = [
344
+ { code: "7010", name: "Bank of Ceylon", shortName: "BOC", swiftCode: "BCEYLKLX" },
345
+ { code: "7056", name: "Commercial Bank of Ceylon PLC", shortName: "Commercial Bank", swiftCode: "CCEYLKLX" },
346
+ { code: "7083", name: "Hatton National Bank PLC", shortName: "HNB", swiftCode: "HBLILKLX" },
347
+ { code: "7135", name: "People's Bank", shortName: "People's Bank", swiftCode: "PSBKLKLX" },
348
+ { code: "7162", name: "Nations Trust Bank PLC", shortName: "NTB", swiftCode: "NTBLLKLX" },
349
+ { code: "7214", name: "National Development Bank PLC", shortName: "NDB", swiftCode: "NDBLLKLX" },
350
+ { code: "7278", name: "Sampath Bank PLC", shortName: "Sampath Bank", swiftCode: "BSAMLKLX" },
351
+ { code: "7287", name: "Seylan Bank PLC", shortName: "Seylan Bank", swiftCode: "SEYBLKLX" },
352
+ { code: "7302", name: "Pan Asia Banking Corporation PLC", shortName: "Pan Asia Bank", swiftCode: "PABCLLLX" },
353
+ { code: "7311", name: "Union Bank of Colombo PLC", shortName: "Union Bank", swiftCode: "UBCLKLX" },
354
+ { code: "7463", name: "DFCC Bank PLC", shortName: "DFCC", swiftCode: "DFCCLKLX" },
355
+ { code: "7472", name: "Amana Bank PLC", shortName: "Amana Bank", swiftCode: "AMNLKLX" },
356
+ { code: "7481", name: "Cargills Bank Limited", shortName: "Cargills Bank", swiftCode: "CBKLLKLX" },
357
+ { code: "7092", name: "The Hongkong and Shanghai Banking Corporation Ltd", shortName: "HSBC", swiftCode: "HSBCLKLX" },
358
+ { code: "7108", name: "Standard Chartered Bank", shortName: "Standard Chartered", swiftCode: "SCBLLKLX" },
359
+ { code: "7719", name: "National Savings Bank", shortName: "NSB", swiftCode: "NSBLLKLX" },
360
+ { code: "7728", name: "Sanasa Development Bank PLC", shortName: "SDB Bank", swiftCode: "SDBLLKLX" },
361
+ { code: "7746", name: "Regional Development Bank", shortName: "RDB", swiftCode: "RDBLLKLX" }
362
+ ];
363
+ var SRI_LANKAN_BRANCHES = [
364
+ // Commercial Bank
365
+ { code: "001", name: "Colombo Fort / Head Office", bankCode: "7056", district: "Colombo" },
366
+ { code: "002", name: "Kollupitiya", bankCode: "7056", district: "Colombo" },
367
+ { code: "005", name: "Bambalapitiya", bankCode: "7056", district: "Colombo" },
368
+ { code: "010", name: "Kandy", bankCode: "7056", district: "Kandy" },
369
+ { code: "015", name: "Galle", bankCode: "7056", district: "Galle" },
370
+ { code: "020", name: "Kurunegala", bankCode: "7056", district: "Kurunegala" },
371
+ { code: "025", name: "Gampaha", bankCode: "7056", district: "Gampaha" },
372
+ { code: "030", name: "Negombo", bankCode: "7056", district: "Gampaha" },
373
+ { code: "035", name: "Jaffna", bankCode: "7056", district: "Jaffna" },
374
+ { code: "040", name: "Matara", bankCode: "7056", district: "Matara" },
375
+ // Bank of Ceylon
376
+ { code: "001", name: "City Office (Fort)", bankCode: "7010", district: "Colombo" },
377
+ { code: "002", name: "Kollupitiya", bankCode: "7010", district: "Colombo" },
378
+ { code: "010", name: "Kandy Main", bankCode: "7010", district: "Kandy" },
379
+ { code: "015", name: "Galle Fort", bankCode: "7010", district: "Galle" },
380
+ { code: "025", name: "Gampaha Super Grade", bankCode: "7010", district: "Gampaha" },
381
+ // Sampath Bank
382
+ { code: "001", name: "Colombo Fort / Head Office", bankCode: "7278", district: "Colombo" },
383
+ { code: "002", name: "Kollupitiya", bankCode: "7278", district: "Colombo" },
384
+ { code: "003", name: "Kandy", bankCode: "7278", district: "Kandy" },
385
+ { code: "004", name: "Galle", bankCode: "7278", district: "Galle" },
386
+ { code: "008", name: "Negombo", bankCode: "7278", district: "Gampaha" },
387
+ // People's Bank
388
+ { code: "001", name: "Corporate Banking Division (Colombo)", bankCode: "7135", district: "Colombo" },
389
+ { code: "010", name: "Kandy City", bankCode: "7135", district: "Kandy" },
390
+ { code: "015", name: "Galle Fort", bankCode: "7135", district: "Galle" },
391
+ // HNB
392
+ { code: "001", name: "HNB Towers (Head Office)", bankCode: "7083", district: "Colombo" },
393
+ { code: "010", name: "Kandy", bankCode: "7083", district: "Kandy" },
394
+ { code: "015", name: "Galle", bankCode: "7083", district: "Galle" }
395
+ ];
396
+ function getBanks() {
397
+ return SRI_LANKAN_BANKS;
398
+ }
399
+ function findBank(query) {
400
+ if (!query) return void 0;
401
+ const q = query.trim().toLowerCase();
402
+ return SRI_LANKAN_BANKS.find(
403
+ (b) => b.code === q || b.shortName.toLowerCase().includes(q) || b.name.toLowerCase().includes(q)
404
+ );
405
+ }
406
+ function getBranches(bankCode) {
407
+ if (!bankCode) return [];
408
+ const cleanCode = bankCode.trim();
409
+ return SRI_LANKAN_BRANCHES.filter((branch) => branch.bankCode === cleanCode);
410
+ }
411
+ function findBranch(bankCode, query) {
412
+ if (!bankCode || !query) return void 0;
413
+ const cleanBankCode = bankCode.trim();
414
+ const q = query.trim().toLowerCase();
415
+ return SRI_LANKAN_BRANCHES.find(
416
+ (branch) => branch.bankCode === cleanBankCode && (branch.code === q || branch.name.toLowerCase().includes(q))
417
+ );
418
+ }
419
+
420
+ // src/tax/index.ts
421
+ function validateTIN(input) {
422
+ if (input === null || input === void 0) {
423
+ return { isValid: false, error: "TIN cannot be empty." };
424
+ }
425
+ const tinStr = String(input).trim().replace(/[-\s]/g, "");
426
+ if (!/^\d{9}$/.test(tinStr)) {
427
+ return {
428
+ isValid: false,
429
+ error: "Invalid TIN. A Sri Lankan TIN must be exactly 9 numeric digits."
430
+ };
431
+ }
432
+ const formatted = `${tinStr.slice(0, 3)}-${tinStr.slice(3, 6)}-${tinStr.slice(6, 9)}`;
433
+ return {
434
+ isValid: true,
435
+ tin: tinStr,
436
+ formatted
437
+ };
438
+ }
439
+ function validateVAT(input) {
440
+ if (!input || typeof input !== "string") {
441
+ return { isValid: false, error: "VAT number must be a valid string." };
442
+ }
443
+ const clean = input.trim().replace(/\s/g, "");
444
+ const matchWithBranch = clean.match(/^(\d{9})-(\d{4})$/);
445
+ if (matchWithBranch) {
446
+ return {
447
+ isValid: true,
448
+ vatNumber: clean,
449
+ baseTin: matchWithBranch[1],
450
+ branchCode: matchWithBranch[2]
451
+ };
452
+ }
453
+ if (/^\d{9}$/.test(clean)) {
454
+ return {
455
+ isValid: true,
456
+ vatNumber: `${clean}-7000`,
457
+ baseTin: clean,
458
+ branchCode: "7000"
459
+ };
460
+ }
461
+ if (/^\d{13}$/.test(clean)) {
462
+ return {
463
+ isValid: true,
464
+ vatNumber: `${clean.slice(0, 9)}-${clean.slice(9)}`,
465
+ baseTin: clean.slice(0, 9),
466
+ branchCode: clean.slice(9)
467
+ };
468
+ }
469
+ return {
470
+ isValid: false,
471
+ error: "Invalid VAT format. Expected 9 digits with optional 4-digit branch suffix (e.g. 123456789-7000)."
472
+ };
473
+ }
474
+ function calculateTax(options) {
475
+ const {
476
+ amount,
477
+ isInclusive = false,
478
+ vatRate = 18,
479
+ includeSSCL = false,
480
+ ssclRate = 2.5
481
+ } = options;
482
+ const vRate = vatRate / 100;
483
+ const sRate = includeSSCL ? ssclRate / 100 : 0;
484
+ let baseAmount = 0;
485
+ let ssclAmount = 0;
486
+ let vatAmount = 0;
487
+ let totalAmount = 0;
488
+ if (isInclusive) {
489
+ const multiplier = (1 + sRate) * (1 + vRate);
490
+ baseAmount = Number((amount / multiplier).toFixed(2));
491
+ ssclAmount = Number((baseAmount * sRate).toFixed(2));
492
+ vatAmount = Number(((baseAmount + ssclAmount) * vRate).toFixed(2));
493
+ totalAmount = Number(amount.toFixed(2));
494
+ } else {
495
+ baseAmount = Number(amount.toFixed(2));
496
+ ssclAmount = Number((baseAmount * sRate).toFixed(2));
497
+ vatAmount = Number(((baseAmount + ssclAmount) * vRate).toFixed(2));
498
+ totalAmount = Number((baseAmount + ssclAmount + vatAmount).toFixed(2));
499
+ }
500
+ const totalTax = Number((ssclAmount + vatAmount).toFixed(2));
501
+ return {
502
+ baseAmount,
503
+ ssclAmount,
504
+ vatAmount,
505
+ totalTax,
506
+ totalAmount
507
+ };
508
+ }
509
+
510
+ // src/calendar/index.ts
511
+ var SRI_LANKAN_HOLIDAYS = [
512
+ // Fixed annual national holidays
513
+ { date: "2025-01-14", name: "Tamil Thai Pongal Day", categories: ["public", "bank", "mercantile"] },
514
+ { date: "2025-01-13", name: "Duruthu Full Moon Poya Day", categories: ["public", "bank"] },
515
+ { date: "2025-02-04", name: "National Day (Independence Day)", categories: ["public", "bank", "mercantile"] },
516
+ { date: "2025-02-12", name: "Navam Full Moon Poya Day", categories: ["public", "bank"] },
517
+ { date: "2025-02-26", name: "Mahasivarathri Day", categories: ["public", "bank"] },
518
+ { date: "2025-03-13", name: "Medin Full Moon Poya Day", categories: ["public", "bank"] },
519
+ { date: "2025-03-31", name: "Id-Ul-Fitr (Ramazan Festival Day)", categories: ["public", "bank"] },
520
+ { date: "2025-04-12", name: "Bak Full Moon Poya Day", categories: ["public", "bank"] },
521
+ { date: "2025-04-13", name: "Day prior to Sinhala & Tamil New Year Day", categories: ["public", "bank", "mercantile"] },
522
+ { date: "2025-04-14", name: "Sinhala & Tamil New Year Day", categories: ["public", "bank", "mercantile"] },
523
+ { date: "2025-04-18", name: "Good Friday", categories: ["public", "bank"] },
524
+ { date: "2025-05-01", name: "May Day (International Workers' Day)", categories: ["public", "bank", "mercantile"] },
525
+ { date: "2025-05-12", name: "Vesak Full Moon Poya Day", categories: ["public", "bank", "mercantile"] },
526
+ { date: "2025-05-13", name: "Day following Vesak Full Moon Poya Day", categories: ["public", "bank", "mercantile"] },
527
+ { date: "2025-06-10", name: "Poson Full Moon Poya Day", categories: ["public", "bank"] },
528
+ { date: "2025-07-10", name: "Esala Full Moon Poya Day", categories: ["public", "bank"] },
529
+ { date: "2025-08-08", name: "Nikini Full Moon Poya Day", categories: ["public", "bank"] },
530
+ { date: "2025-09-05", name: "Milad-Un-Nabi (Holy Prophet's Birthday)", categories: ["public", "bank", "mercantile"] },
531
+ { date: "2025-09-07", name: "Binara Full Moon Poya Day", categories: ["public", "bank"] },
532
+ { date: "2025-10-06", name: "Vap Full Moon Poya Day", categories: ["public", "bank"] },
533
+ { date: "2025-10-20", name: "Deepavali Festival Day", categories: ["public", "bank"] },
534
+ { date: "2025-11-05", name: "Ill Full Moon Poya Day", categories: ["public", "bank"] },
535
+ { date: "2025-12-04", name: "Unduvap Full Moon Poya Day", categories: ["public", "bank"] },
536
+ { date: "2025-12-25", name: "Christmas Day", categories: ["public", "bank", "mercantile"] }
537
+ ];
538
+ function formatDateString(d) {
539
+ const yyyy = d.getFullYear();
540
+ const mm = String(d.getMonth() + 1).padStart(2, "0");
541
+ const dd = String(d.getDate()).padStart(2, "0");
542
+ return `${yyyy}-${mm}-${dd}`;
543
+ }
544
+ function isWeekend(date, saturdayWorking = false) {
545
+ const day = date.getDay();
546
+ if (day === 0) return true;
547
+ if (day === 6) return !saturdayWorking;
548
+ return false;
549
+ }
550
+ function getHoliday(date) {
551
+ const dateStr = formatDateString(date);
552
+ return SRI_LANKAN_HOLIDAYS.find((h) => h.date === dateStr);
553
+ }
554
+ function isWorkingDay(date, options) {
555
+ const satWorking = (options == null ? void 0 : options.saturdayWorking) ?? false;
556
+ if (isWeekend(date, satWorking)) {
557
+ return false;
558
+ }
559
+ const holiday = getHoliday(date);
560
+ if (!holiday) {
561
+ return true;
562
+ }
563
+ if (options == null ? void 0 : options.mercantileOnly) {
564
+ return !holiday.categories.includes("mercantile");
565
+ }
566
+ return false;
567
+ }
568
+ function getWorkingDays(startDate, endDate, options) {
569
+ if (startDate > endDate) {
570
+ return 0;
571
+ }
572
+ let count = 0;
573
+ const current = new Date(startDate.getTime());
574
+ while (current <= endDate) {
575
+ if (isWorkingDay(current, options)) {
576
+ count++;
577
+ }
578
+ current.setDate(current.getDate() + 1);
579
+ }
580
+ return count;
581
+ }
582
+ function addWorkingDays(startDate, daysToAdd, options) {
583
+ const result = new Date(startDate.getTime());
584
+ let added = 0;
585
+ while (added < daysToAdd) {
586
+ result.setDate(result.getDate() + 1);
587
+ if (isWorkingDay(result, options)) {
588
+ added++;
589
+ }
590
+ }
591
+ return result;
592
+ }
593
+ // Annotate the CommonJS export names for ESM import in node:
594
+ 0 && (module.exports = {
595
+ SRI_LANKAN_BANKS,
596
+ SRI_LANKAN_BRANCHES,
597
+ SRI_LANKAN_HOLIDAYS,
598
+ addWorkingDays,
599
+ calculateTax,
600
+ findBank,
601
+ findBranch,
602
+ formatLKR,
603
+ getBanks,
604
+ getBranches,
605
+ getHoliday,
606
+ getWorkingDays,
607
+ isWeekend,
608
+ isWorkingDay,
609
+ lkrToWords,
610
+ validateTIN,
611
+ validateVAT
612
+ });