@budiauktioner/buildi-primitives 0.1.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.
Files changed (107) hide show
  1. package/CHANGELOG.md +51 -0
  2. package/LICENSE +21 -0
  3. package/README.md +253 -0
  4. package/THIRD_PARTY_NOTICES.md +52 -0
  5. package/dist/banking/index.cjs +6491 -0
  6. package/dist/banking/index.cjs.map +1 -0
  7. package/dist/banking/index.d.cts +58 -0
  8. package/dist/banking/index.d.ts +58 -0
  9. package/dist/banking/index.js +6464 -0
  10. package/dist/banking/index.js.map +1 -0
  11. package/dist/contact/index.cjs +6678 -0
  12. package/dist/contact/index.cjs.map +1 -0
  13. package/dist/contact/index.d.cts +709 -0
  14. package/dist/contact/index.d.ts +709 -0
  15. package/dist/contact/index.js +6586 -0
  16. package/dist/contact/index.js.map +1 -0
  17. package/dist/country-BhD51LDL.d.cts +433 -0
  18. package/dist/country-p0n0EVQ9.d.ts +433 -0
  19. package/dist/finance/index.cjs +3592 -0
  20. package/dist/finance/index.cjs.map +1 -0
  21. package/dist/finance/index.d.cts +83 -0
  22. package/dist/finance/index.d.ts +83 -0
  23. package/dist/finance/index.js +3584 -0
  24. package/dist/finance/index.js.map +1 -0
  25. package/dist/geography/index.cjs +4227 -0
  26. package/dist/geography/index.cjs.map +1 -0
  27. package/dist/geography/index.d.cts +34 -0
  28. package/dist/geography/index.d.ts +34 -0
  29. package/dist/geography/index.js +4202 -0
  30. package/dist/geography/index.js.map +1 -0
  31. package/dist/index.cjs +14087 -0
  32. package/dist/index.cjs.map +1 -0
  33. package/dist/index.d.cts +75 -0
  34. package/dist/index.d.ts +75 -0
  35. package/dist/index.js +13868 -0
  36. package/dist/index.js.map +1 -0
  37. package/dist/isin-EeVPpNWu.d.ts +39 -0
  38. package/dist/isin-ZlQLBVm8.d.cts +39 -0
  39. package/dist/organization/index.cjs +2376 -0
  40. package/dist/organization/index.cjs.map +1 -0
  41. package/dist/organization/index.d.cts +117 -0
  42. package/dist/organization/index.d.ts +117 -0
  43. package/dist/organization/index.js +2346 -0
  44. package/dist/organization/index.js.map +1 -0
  45. package/dist/person/index.cjs +1144 -0
  46. package/dist/person/index.cjs.map +1 -0
  47. package/dist/person/index.d.cts +60 -0
  48. package/dist/person/index.d.ts +60 -0
  49. package/dist/person/index.js +1125 -0
  50. package/dist/person/index.js.map +1 -0
  51. package/dist/person-full-name-Cmc9Ynuc.d.cts +82 -0
  52. package/dist/person-full-name-D6Hbsab6.d.ts +82 -0
  53. package/dist/phone-number-C24--ggy.d.ts +139 -0
  54. package/dist/phone-number-DZ-YxCQQ.d.cts +139 -0
  55. package/dist/property/index.cjs +487 -0
  56. package/dist/property/index.cjs.map +1 -0
  57. package/dist/property/index.d.cts +56 -0
  58. package/dist/property/index.d.ts +56 -0
  59. package/dist/property/index.js +480 -0
  60. package/dist/property/index.js.map +1 -0
  61. package/dist/sample-data/index.cjs +12310 -0
  62. package/dist/sample-data/index.cjs.map +1 -0
  63. package/dist/sample-data/index.d.cts +260 -0
  64. package/dist/sample-data/index.d.ts +260 -0
  65. package/dist/sample-data/index.js +12302 -0
  66. package/dist/sample-data/index.js.map +1 -0
  67. package/dist/swedish-address-DNC3ftRF.d.cts +297 -0
  68. package/dist/swedish-address-GMzjqgxb.d.ts +297 -0
  69. package/dist/swedish-bank-account-holder-name-BFJ8h1aO.d.cts +45 -0
  70. package/dist/swedish-bank-account-holder-name-CAAru07F.d.ts +45 -0
  71. package/dist/swedish-municipality-DlUS7g7h.d.cts +87 -0
  72. package/dist/swedish-municipality-nDRHYRAd.d.ts +87 -0
  73. package/dist/swedish-organization-name-D7NvERxA.d.cts +33 -0
  74. package/dist/swedish-organization-name-rR0Q836C.d.ts +33 -0
  75. package/dist/swedish-organization-number-Bcj7V_lh.d.cts +130 -0
  76. package/dist/swedish-organization-number-DM8dpXwR.d.ts +130 -0
  77. package/dist/swedish-organization-type-CZOdETwG.d.cts +29 -0
  78. package/dist/swedish-organization-type-CZOdETwG.d.ts +29 -0
  79. package/dist/swedish-personal-identity-number-BiIg4io3.d.ts +149 -0
  80. package/dist/swedish-personal-identity-number-Cp9Coz55.d.cts +149 -0
  81. package/dist/swedish-property-designation-BM-gdd9x.d.ts +46 -0
  82. package/dist/swedish-property-designation-BaHXufqV.d.cts +46 -0
  83. package/dist/swedish-sni-code-Ccsswpni.d.ts +53 -0
  84. package/dist/swedish-sni-code-CuJFyM6l.d.cts +53 -0
  85. package/dist/swedish-swish-number-CL6Gx_h3.d.cts +397 -0
  86. package/dist/swedish-swish-number-DDG3mNDg.d.ts +397 -0
  87. package/dist/text-candidate-qg2bD9PY.d.cts +110 -0
  88. package/dist/text-candidate-qg2bD9PY.d.ts +110 -0
  89. package/dist/text-scanning/index.cjs +10414 -0
  90. package/dist/text-scanning/index.cjs.map +1 -0
  91. package/dist/text-scanning/index.d.cts +153 -0
  92. package/dist/text-scanning/index.d.ts +153 -0
  93. package/dist/text-scanning/index.js +10406 -0
  94. package/dist/text-scanning/index.js.map +1 -0
  95. package/dist/validation/index.cjs +83 -0
  96. package/dist/validation/index.cjs.map +1 -0
  97. package/dist/validation/index.d.cts +63 -0
  98. package/dist/validation/index.d.ts +63 -0
  99. package/dist/validation/index.js +79 -0
  100. package/dist/validation/index.js.map +1 -0
  101. package/dist/web/index.cjs +3994 -0
  102. package/dist/web/index.cjs.map +1 -0
  103. package/dist/web/index.d.cts +203 -0
  104. package/dist/web/index.d.ts +203 -0
  105. package/dist/web/index.js +3987 -0
  106. package/dist/web/index.js.map +1 -0
  107. package/package.json +211 -0
@@ -0,0 +1,2376 @@
1
+ 'use strict';
2
+
3
+ // src/organization/swedish-organization-type.ts
4
+ var SwedishOrganizationType = /* @__PURE__ */ ((SwedishOrganizationType2) => {
5
+ SwedishOrganizationType2[SwedishOrganizationType2["Unknown"] = 0] = "Unknown";
6
+ SwedishOrganizationType2[SwedishOrganizationType2["Aktiebolag"] = 1] = "Aktiebolag";
7
+ SwedishOrganizationType2[SwedishOrganizationType2["Dodsbo"] = 2] = "Dodsbo";
8
+ SwedishOrganizationType2[SwedishOrganizationType2["HandelsbolagEllerKommanditbolag"] = 10] = "HandelsbolagEllerKommanditbolag";
9
+ SwedishOrganizationType2[SwedishOrganizationType2["Handelsbolag"] = 11] = "Handelsbolag";
10
+ SwedishOrganizationType2[SwedishOrganizationType2["Kommanditbolag"] = 12] = "Kommanditbolag";
11
+ SwedishOrganizationType2[SwedishOrganizationType2["EkonomiskForening"] = 20] = "EkonomiskForening";
12
+ SwedishOrganizationType2[SwedishOrganizationType2["Bostadsrattsforening"] = 21] = "Bostadsrattsforening";
13
+ SwedishOrganizationType2[SwedishOrganizationType2["Samfallighetsforening"] = 22] = "Samfallighetsforening";
14
+ SwedishOrganizationType2[SwedishOrganizationType2["IdeellForening"] = 30] = "IdeellForening";
15
+ SwedishOrganizationType2[SwedishOrganizationType2["Stiftelse"] = 31] = "Stiftelse";
16
+ SwedishOrganizationType2[SwedishOrganizationType2["OffentligSektor"] = 40] = "OffentligSektor";
17
+ SwedishOrganizationType2[SwedishOrganizationType2["Kommun"] = 41] = "Kommun";
18
+ SwedishOrganizationType2[SwedishOrganizationType2["Region"] = 42] = "Region";
19
+ SwedishOrganizationType2[SwedishOrganizationType2["Forsamling"] = 43] = "Forsamling";
20
+ SwedishOrganizationType2[SwedishOrganizationType2["EnkeltBolag"] = 50] = "EnkeltBolag";
21
+ SwedishOrganizationType2[SwedishOrganizationType2["Filial"] = 51] = "Filial";
22
+ SwedishOrganizationType2[SwedishOrganizationType2["Europabolag"] = 52] = "Europabolag";
23
+ SwedishOrganizationType2[SwedishOrganizationType2["EuropeiskEkonomiskIntressegruppering"] = 53] = "EuropeiskEkonomiskIntressegruppering";
24
+ SwedishOrganizationType2[SwedishOrganizationType2["SCEForening"] = 54] = "SCEForening";
25
+ SwedishOrganizationType2[SwedishOrganizationType2["EnskildFirmaEllerPrivatperson"] = 60] = "EnskildFirmaEllerPrivatperson";
26
+ SwedishOrganizationType2[SwedishOrganizationType2["EnskildFirma"] = 61] = "EnskildFirma";
27
+ SwedishOrganizationType2[SwedishOrganizationType2["Privatperson"] = 62] = "Privatperson";
28
+ SwedishOrganizationType2[SwedishOrganizationType2["Other"] = 99] = "Other";
29
+ return SwedishOrganizationType2;
30
+ })(SwedishOrganizationType || {});
31
+
32
+ // src/organization/swedish-organization-identifier-type.ts
33
+ var SwedishOrganizationIdentifierType = /* @__PURE__ */ ((SwedishOrganizationIdentifierType2) => {
34
+ SwedishOrganizationIdentifierType2[SwedishOrganizationIdentifierType2["Unknown"] = 0] = "Unknown";
35
+ SwedishOrganizationIdentifierType2[SwedishOrganizationIdentifierType2["SwedishOrganizationNumber"] = 1] = "SwedishOrganizationNumber";
36
+ SwedishOrganizationIdentifierType2[SwedishOrganizationIdentifierType2["SwedishPersonalIdentityNumber"] = 2] = "SwedishPersonalIdentityNumber";
37
+ SwedishOrganizationIdentifierType2[SwedishOrganizationIdentifierType2["SwedishCoordinationNumber"] = 3] = "SwedishCoordinationNumber";
38
+ SwedishOrganizationIdentifierType2[SwedishOrganizationIdentifierType2["EuVatNumber"] = 10] = "EuVatNumber";
39
+ SwedishOrganizationIdentifierType2[SwedishOrganizationIdentifierType2["DunsNumber"] = 20] = "DunsNumber";
40
+ SwedishOrganizationIdentifierType2[SwedishOrganizationIdentifierType2["LeiCode"] = 30] = "LeiCode";
41
+ return SwedishOrganizationIdentifierType2;
42
+ })(SwedishOrganizationIdentifierType || {});
43
+ var DEFAULT_UI_CULTURE = "sv-SE";
44
+ var state = {
45
+ uiCulture: DEFAULT_UI_CULTURE};
46
+ var PrimitivesDefaults = {
47
+ /**
48
+ * `true` when {@link uiCulture} is Swedish (`sv` or `sv-*`).
49
+ * Types use this to select between localized and English display names.
50
+ */
51
+ get useLocalizedDisplayNames() {
52
+ const lang = state.uiCulture.toLowerCase().split("-")[0];
53
+ return lang === "sv";
54
+ }};
55
+
56
+ // src/internal/input-sanitization.ts
57
+ var FORMAT_OR_NOT_ASSIGNED = /[\p{Cf}\p{Cn}]/u;
58
+ var SPACE_SEPARATOR = /[\p{Zs}\p{Zl}\p{Zp}]/u;
59
+ var CONTROL = /\p{Cc}/u;
60
+ function sanitizeInput(input) {
61
+ let out = "";
62
+ for (const c of input) {
63
+ if (c === "\u2018" || c === "\u2019" || c === "\u201A" || c === "\u201B") {
64
+ out += "'";
65
+ continue;
66
+ }
67
+ if (c === "\u201C" || c === "\u201D" || c === "\u201E" || c === "\u201F" || c === "\xAB" || c === "\xBB") {
68
+ out += '"';
69
+ continue;
70
+ }
71
+ if (FORMAT_OR_NOT_ASSIGNED.test(c)) {
72
+ continue;
73
+ }
74
+ if (CONTROL.test(c)) {
75
+ if (c === " " || c === "\n" || c === "\r") out += " ";
76
+ continue;
77
+ }
78
+ if (SPACE_SEPARATOR.test(c)) {
79
+ out += " ";
80
+ continue;
81
+ }
82
+ out += c;
83
+ }
84
+ return out;
85
+ }
86
+ var WHITESPACE_RUN = /\s+/g;
87
+ function collapseWhitespace(input) {
88
+ if (input == null) return "";
89
+ return sanitizeInput(input).trim().replace(WHITESPACE_RUN, " ");
90
+ }
91
+ function keepDigits(input) {
92
+ let out = "";
93
+ for (let i = 0; i < input.length; i++) {
94
+ const c = input.charCodeAt(i);
95
+ if (c >= 48 && c <= 57) out += input[i];
96
+ }
97
+ return out;
98
+ }
99
+ function keepAsciiAlphanumericUppercase(input) {
100
+ let out = "";
101
+ for (let i = 0; i < input.length; i++) {
102
+ const c = input.charCodeAt(i);
103
+ if (c >= 48 && c <= 57) out += input[i];
104
+ else if (c >= 65 && c <= 90) out += input[i];
105
+ else if (c >= 97 && c <= 122) out += String.fromCharCode(c - 32);
106
+ }
107
+ return out;
108
+ }
109
+
110
+ // src/internal/clock.ts
111
+ var systemClock = {
112
+ now: () => /* @__PURE__ */ new Date()
113
+ };
114
+
115
+ // src/text-scanning/text-candidate-category.ts
116
+ var TextCandidateCategory = {
117
+ PersonalIdentifier: "PersonalIdentifier",
118
+ OrganizationIdentifier: "OrganizationIdentifier"};
119
+
120
+ // src/text-scanning/text-candidate.ts
121
+ var TextCandidate = class {
122
+ /** Zero-based start position in the scanned text. */
123
+ startIndex;
124
+ /** Number of characters in the original matched span. */
125
+ length;
126
+ /** The raw substring from the input text that was matched. */
127
+ originalText;
128
+ /**
129
+ * Short type name, e.g. `EmailAddress` or `SwedishPersonalIdentityNumber`.
130
+ */
131
+ typeName;
132
+ /** Broad category of the matched type. */
133
+ category;
134
+ /** Machine-comparable canonical form of the matched value. */
135
+ normalizedForm;
136
+ /** Human-readable display form of the matched value. */
137
+ formattedForm;
138
+ /**
139
+ * Display form with sensitive content masked (e.g. `990807-****`).
140
+ * Produced by the type's `toMaskedString()` helper.
141
+ */
142
+ maskedForm;
143
+ /** Heuristic confidence level. */
144
+ confidence;
145
+ /** The successfully parsed instance of the matched type. */
146
+ value;
147
+ constructor(opts) {
148
+ this.startIndex = opts.startIndex;
149
+ this.length = opts.length;
150
+ this.originalText = opts.originalText;
151
+ this.typeName = opts.typeName;
152
+ this.category = opts.category;
153
+ this.normalizedForm = opts.normalizedForm;
154
+ this.formattedForm = opts.formattedForm;
155
+ this.maskedForm = opts.maskedForm;
156
+ this.confidence = opts.confidence;
157
+ this.value = opts.value;
158
+ }
159
+ /** Exclusive end position (`startIndex + length`). */
160
+ get endIndex() {
161
+ return this.startIndex + this.length;
162
+ }
163
+ /** Returns `true` if this candidate's span overlaps with `other`. */
164
+ overlaps(other) {
165
+ return this.startIndex < other.endIndex && other.startIndex < this.endIndex;
166
+ }
167
+ /** Returns `true` if this candidate's span fully contains `other`. */
168
+ contains(other) {
169
+ return this.startIndex <= other.startIndex && this.endIndex >= other.endIndex;
170
+ }
171
+ };
172
+
173
+ // src/text-scanning/text-match-confidence.ts
174
+ var TextMatchConfidence = {
175
+ /**
176
+ * Pattern match only. High false-positive risk — the matched text merely
177
+ * fits a syntactic pattern (e.g. a run of digits that happens to be the
178
+ * right length).
179
+ */
180
+ Low: 0,
181
+ /**
182
+ * Strong match with checksum or format-specific validation (e.g. a personal
183
+ * identity number with a valid Luhn check digit and plausible date, or an
184
+ * IBAN with valid MOD-97).
185
+ */
186
+ High: 2
187
+ };
188
+
189
+ // src/validation/validation-error-reason.ts
190
+ var ValidationErrorReason = {
191
+ // --- Common ---
192
+ InputIsEmpty: "InputIsEmpty",
193
+ InputTooLong: "InputTooLong",
194
+ InputTooShort: "InputTooShort",
195
+ InvalidLength: "InvalidLength",
196
+ InvalidFormat: "InvalidFormat",
197
+ InvalidCheckDigit: "InvalidCheckDigit",
198
+ InvalidEntityPattern: "InvalidEntityPattern",
199
+ // --- International / country ---
200
+ UnknownCountryCode: "UnknownCountryCode",
201
+ InvalidCountryPrefix: "InvalidCountryPrefix"};
202
+
203
+ // src/validation/validation-issue.ts
204
+ var ValidationIssue = class {
205
+ reason;
206
+ englishDescription;
207
+ localizedDescription;
208
+ constructor(reason, englishDescription, localizedDescription) {
209
+ this.reason = reason;
210
+ this.englishDescription = englishDescription;
211
+ this.localizedDescription = localizedDescription;
212
+ }
213
+ /**
214
+ * Returns {@link localizedDescription} when
215
+ * {@link PrimitivesDefaults.useLocalizedDisplayNames} is `true`, otherwise
216
+ * {@link englishDescription}.
217
+ */
218
+ get description() {
219
+ return PrimitivesDefaults.useLocalizedDisplayNames ? this.localizedDescription : this.englishDescription;
220
+ }
221
+ };
222
+
223
+ // src/validation/validation-result.ts
224
+ var ValidationResult = class {
225
+ rawInput;
226
+ isValid;
227
+ issues;
228
+ /** @internal — use `validResult` / `invalidResult` factories. */
229
+ constructor(rawInput, isValid, issues) {
230
+ this.rawInput = rawInput ?? null;
231
+ this.isValid = isValid;
232
+ this.issues = Object.freeze([...issues]);
233
+ }
234
+ };
235
+ function validResult(rawInput) {
236
+ return new ValidationResult(rawInput, true, []);
237
+ }
238
+ function invalidResult(rawInput, reasonOrIssues, englishDescription, localizedDescription) {
239
+ if (typeof reasonOrIssues === "string") {
240
+ if (englishDescription === void 0 || localizedDescription === void 0) {
241
+ throw new Error("invalidResult requires both english and localized descriptions");
242
+ }
243
+ return new ValidationResult(rawInput, false, [
244
+ new ValidationIssue(reasonOrIssues, englishDescription, localizedDescription)
245
+ ]);
246
+ }
247
+ return new ValidationResult(rawInput, false, reasonOrIssues);
248
+ }
249
+
250
+ // src/internal/luhn.ts
251
+ function luhnIsValid(digits) {
252
+ if (!digits) return false;
253
+ let sum = 0;
254
+ const len = digits.length;
255
+ for (let i = 0; i < len; i++) {
256
+ const code = digits.charCodeAt(i);
257
+ if (code < 48 || code > 57) return false;
258
+ let d = code - 48;
259
+ if ((len - i) % 2 === 0) {
260
+ d *= 2;
261
+ if (d > 9) d -= 9;
262
+ }
263
+ sum += d;
264
+ }
265
+ return sum % 10 === 0;
266
+ }
267
+
268
+ // src/person/personnummer-parser.ts
269
+ var defaultClock = systemClock;
270
+ var TWELVE = /^(\d{4})(\d{2})(\d{2})(\d{3})(\d)$/;
271
+ var TEN = /^(\d{2})(\d{2})(\d{2})(\d{3})(\d)$/;
272
+ var TEN_WITH_SEP = /^(\d{2})(\d{2})(\d{2})([-+])(\d{3})(\d)$/;
273
+ var TWELVE_WITH_SEP = /^(\d{4})(\d{2})(\d{2})([-+])(\d{3})(\d)$/;
274
+ function parsePin(input, clock = defaultClock) {
275
+ if (!input) return null;
276
+ const cleaned = input.trim();
277
+ if (cleaned.length === 0) return null;
278
+ let year, month, day;
279
+ let individual, check;
280
+ let hadPlus = false;
281
+ let isTwelve = false;
282
+ let m = TWELVE.exec(cleaned);
283
+ if (m) {
284
+ year = +m[1];
285
+ month = +m[2];
286
+ day = +m[3];
287
+ individual = m[4];
288
+ check = m[5];
289
+ isTwelve = true;
290
+ } else if (m = TEN.exec(cleaned)) {
291
+ const yy = +m[1];
292
+ year = inferCenturyForTenDigit(yy, false, clock);
293
+ month = +m[2];
294
+ day = +m[3];
295
+ individual = m[4];
296
+ check = m[5];
297
+ } else if (m = TEN_WITH_SEP.exec(cleaned)) {
298
+ const yy = +m[1];
299
+ hadPlus = m[4] === "+";
300
+ year = inferCenturyForTenDigit(yy, hadPlus, clock);
301
+ month = +m[2];
302
+ day = +m[3];
303
+ individual = m[5];
304
+ check = m[6];
305
+ } else if (m = TWELVE_WITH_SEP.exec(cleaned)) {
306
+ year = +m[1];
307
+ month = +m[2];
308
+ day = +m[3];
309
+ individual = m[5];
310
+ check = m[6];
311
+ if (m[4] === "+") return null;
312
+ } else {
313
+ return null;
314
+ }
315
+ if (month < 1 || month > 12) return null;
316
+ const isCoordination = day >= 60 && day <= 91;
317
+ let realDay;
318
+ let kind;
319
+ if (isCoordination) {
320
+ kind = "coordination";
321
+ realDay = day === 60 ? 0 : day - 60;
322
+ if (realDay !== 0 && !isValidDay(year, month, realDay)) return null;
323
+ } else {
324
+ kind = "personal";
325
+ if (!isValidDay(year, month, day)) return null;
326
+ realDay = day;
327
+ }
328
+ const luhnInput = String(year % 100).padStart(2, "0") + String(month).padStart(2, "0") + String(day).padStart(2, "0") + individual + check;
329
+ if (!luhnIsValid(luhnInput)) return null;
330
+ if (isTwelve && (year < 1800 || year > 2200)) return null;
331
+ return {
332
+ kind,
333
+ year,
334
+ month,
335
+ realDay,
336
+ individual,
337
+ checkDigit: check,
338
+ hadPlusSeparator: hadPlus
339
+ };
340
+ }
341
+ function isValidDay(year, month, day) {
342
+ if (day < 1) return false;
343
+ const dim = daysInMonth(year, month);
344
+ return day <= dim;
345
+ }
346
+ function daysInMonth(year, month) {
347
+ if (month === 2) {
348
+ const leap = year % 4 === 0 && year % 100 !== 0 || year % 400 === 0;
349
+ return leap ? 29 : 28;
350
+ }
351
+ if ([4, 6, 9, 11].includes(month)) return 30;
352
+ return 31;
353
+ }
354
+ function inferCenturyForTenDigit(yy, plusSeparator, clock) {
355
+ const now = clock.now();
356
+ const currentYear = now.getUTCFullYear();
357
+ const currentCentury = Math.floor(currentYear / 100);
358
+ const candidate = currentCentury * 100 + yy;
359
+ let year = candidate;
360
+ if (year > currentYear) year -= 100;
361
+ if (plusSeparator) year -= 100;
362
+ return year;
363
+ }
364
+ function pinTo12Digit(p) {
365
+ const day = p.kind === "coordination" ? p.realDay === 0 ? 60 : p.realDay + 60 : p.realDay;
366
+ return String(p.year).padStart(4, "0") + String(p.month).padStart(2, "0") + String(day).padStart(2, "0") + p.individual + p.checkDigit;
367
+ }
368
+ function pinTo10Digit(p, clock = defaultClock) {
369
+ const day = p.kind === "coordination" ? p.realDay === 0 ? 60 : p.realDay + 60 : p.realDay;
370
+ const yy = String(p.year % 100).padStart(2, "0");
371
+ const sep = ageInYears(p, clock) >= 100 ? "+" : "-";
372
+ return yy + String(p.month).padStart(2, "0") + String(day).padStart(2, "0") + sep + p.individual + p.checkDigit;
373
+ }
374
+ function ageInYears(p, clock) {
375
+ if (p.kind === "coordination" && p.realDay === 0) return 0;
376
+ const now = clock.now();
377
+ const day = p.kind === "coordination" ? p.realDay : p.realDay;
378
+ const birth = new Date(Date.UTC(p.year, p.month - 1, day || 1));
379
+ const ms = now.getTime() - birth.getTime();
380
+ return Math.floor(ms / (365.25 * 24 * 3600 * 1e3));
381
+ }
382
+ function pinGender(p) {
383
+ const d = parseInt(p.individual.charAt(p.individual.length - 1), 10);
384
+ return d % 2 === 0 ? "female" : "male";
385
+ }
386
+ function pinDateOfBirth(p) {
387
+ if (p.kind === "coordination" && p.realDay === 0) return null;
388
+ return new Date(Date.UTC(p.year, p.month - 1, p.realDay));
389
+ }
390
+ function pinAgeInYears(p, clock = defaultClock) {
391
+ if (p.kind === "coordination" && p.realDay === 0) return null;
392
+ return ageInYears(p, clock);
393
+ }
394
+
395
+ // src/person/swedish-personal-identity-number.ts
396
+ var MAX_INPUT_LENGTH = 20;
397
+ var SCAN_PATTERN = /(?<!\d)(\d{6,8})([-+])(\d{4})(?!\d)/g;
398
+ var SwedishPersonalIdentityNumber = class _SwedishPersonalIdentityNumber {
399
+ static typeInfo = Object.freeze({
400
+ englishName: "Personal Identity Number",
401
+ localizedName: "Personnummer",
402
+ emoji: "\u{1FAAA}",
403
+ sources: Object.freeze([
404
+ "https://skatteverket.se/privat/folkbokforing/personnummer.4.3810a01c150939e893f18c29.html",
405
+ "https://sv.wikipedia.org/wiki/Personnummer_i_Sverige",
406
+ "https://en.wikipedia.org/wiki/Luhn_algorithm"
407
+ ])
408
+ });
409
+ _pin;
410
+ _clock;
411
+ constructor(pin, clock) {
412
+ this._pin = pin;
413
+ this._clock = clock;
414
+ }
415
+ get formatted() {
416
+ return pinTo10Digit(this._pin, this._clock);
417
+ }
418
+ get value() {
419
+ return pinTo12Digit(this._pin);
420
+ }
421
+ get dateOfBirthHint() {
422
+ const d = pinDateOfBirth(this._pin);
423
+ if (d === null) throw new Error("Date of birth is unknown.");
424
+ return d;
425
+ }
426
+ get ageHint() {
427
+ const a = pinAgeInYears(this._pin, this._clock);
428
+ if (a === null) throw new Error("Age is unknown.");
429
+ return a;
430
+ }
431
+ get genderHint() {
432
+ return pinGender(this._pin);
433
+ }
434
+ static tryParse(input, options) {
435
+ if (input == null || input.trim() === "") return null;
436
+ const sanitized = sanitizeInput(input).trim();
437
+ if (sanitized.length === 0 || sanitized.length > MAX_INPUT_LENGTH) return null;
438
+ const clock = options?.clock ?? systemClock;
439
+ const pin = parsePin(sanitized, clock);
440
+ if (pin === null) return null;
441
+ if (pin.kind !== "personal") return null;
442
+ return new _SwedishPersonalIdentityNumber(pin, clock);
443
+ }
444
+ static parse(input, options) {
445
+ const r = _SwedishPersonalIdentityNumber.tryParse(input, options);
446
+ if (r === null) throw new Error("Invalid Swedish personal identity number.");
447
+ return r;
448
+ }
449
+ static isValid(input) {
450
+ return _SwedishPersonalIdentityNumber.tryParse(input) !== null;
451
+ }
452
+ static format(input, options) {
453
+ const r = _SwedishPersonalIdentityNumber.tryParse(input, options);
454
+ if (r) return r.formatted;
455
+ if (options?.fallbackToTrimmedInputWhenInvalid && input != null && input.trim() !== "") {
456
+ return input.trim();
457
+ }
458
+ return null;
459
+ }
460
+ static normalize(input, options) {
461
+ const r = _SwedishPersonalIdentityNumber.tryParse(input, options);
462
+ if (r) return r.value;
463
+ if (options?.fallbackToTrimmedInputWhenInvalid && input != null) {
464
+ const t = input.trim();
465
+ return t.length > 0 ? t : null;
466
+ }
467
+ return null;
468
+ }
469
+ static isNormalized(input) {
470
+ return input != null && _SwedishPersonalIdentityNumber.normalize(input) === input;
471
+ }
472
+ static validate(input) {
473
+ if (input == null || input.trim() === "") {
474
+ return invalidResult(
475
+ input,
476
+ ValidationErrorReason.InputIsEmpty,
477
+ "Input is empty or whitespace.",
478
+ "V\xE4rdet \xE4r tomt."
479
+ );
480
+ }
481
+ const sanitized = sanitizeInput(input).trim();
482
+ if (sanitized.length > MAX_INPUT_LENGTH) {
483
+ return invalidResult(
484
+ input,
485
+ ValidationErrorReason.InputTooLong,
486
+ "Input contains too many characters.",
487
+ "V\xE4rdet inneh\xE5ller f\xF6r m\xE5nga tecken."
488
+ );
489
+ }
490
+ const pin = parsePin(sanitized);
491
+ if (pin === null || pin.kind !== "personal") {
492
+ return invalidResult(
493
+ input,
494
+ ValidationErrorReason.InvalidFormat,
495
+ "Invalid personal identity number format.",
496
+ "Ogiltigt format f\xF6r personnummer."
497
+ );
498
+ }
499
+ return validResult(input);
500
+ }
501
+ toNormalizedString() {
502
+ return this.value;
503
+ }
504
+ toString() {
505
+ return this.formatted;
506
+ }
507
+ to10DigitString() {
508
+ return this.formatted;
509
+ }
510
+ to12DigitString() {
511
+ return this.value;
512
+ }
513
+ static findCandidatesInText(text) {
514
+ if (!text) return [];
515
+ const out = [];
516
+ SCAN_PATTERN.lastIndex = 0;
517
+ let m;
518
+ while ((m = SCAN_PATTERN.exec(text)) !== null) {
519
+ const pin = _SwedishPersonalIdentityNumber.tryParse(m[0]);
520
+ if (!pin) continue;
521
+ out.push(
522
+ new TextCandidate({
523
+ startIndex: m.index,
524
+ length: m[0].length,
525
+ originalText: m[0],
526
+ typeName: "SwedishPersonalIdentityNumber",
527
+ category: TextCandidateCategory.PersonalIdentifier,
528
+ normalizedForm: pin.toNormalizedString(),
529
+ formattedForm: pin.toString(),
530
+ maskedForm: maskPersonalIdentityNumber(pin),
531
+ confidence: TextMatchConfidence.High,
532
+ value: pin
533
+ })
534
+ );
535
+ }
536
+ return out;
537
+ }
538
+ equals(other) {
539
+ return other != null && this.value === other.value;
540
+ }
541
+ compareTo(other) {
542
+ if (other == null) return 1;
543
+ return this.value < other.value ? -1 : this.value > other.value ? 1 : 0;
544
+ }
545
+ };
546
+ function maskPersonalIdentityNumber(p, options) {
547
+ const f = p.formatted;
548
+ return f.slice(0, f.length - 4) + "****";
549
+ }
550
+
551
+ // src/person/swedish-coordination-number.ts
552
+ var MAX_INPUT_LENGTH2 = 20;
553
+ var SCAN_PATTERN2 = /(?<!\d)(\d{6,8})([-+])(\d{4})(?!\d)/g;
554
+ var SwedishCoordinationNumber = class _SwedishCoordinationNumber {
555
+ static typeInfo = Object.freeze({
556
+ englishName: "Coordination Number",
557
+ localizedName: "Samordningsnummer",
558
+ emoji: "\u{1F194}",
559
+ sources: Object.freeze([
560
+ "https://skatteverket.se/privat/folkbokforing/samordningsnummer.4.5c281c7015abecc2e201130b.html",
561
+ "https://sv.wikipedia.org/wiki/Samordningsnummer"
562
+ ])
563
+ });
564
+ _pin;
565
+ _clock;
566
+ constructor(pin, clock) {
567
+ this._pin = pin;
568
+ this._clock = clock;
569
+ }
570
+ get formatted() {
571
+ return pinTo10Digit(this._pin, this._clock);
572
+ }
573
+ get value() {
574
+ return pinTo12Digit(this._pin);
575
+ }
576
+ get realDay() {
577
+ return this._pin.realDay;
578
+ }
579
+ get dateOfBirthHint() {
580
+ return pinDateOfBirth(this._pin);
581
+ }
582
+ get ageHint() {
583
+ return pinAgeInYears(this._pin, this._clock);
584
+ }
585
+ get genderHint() {
586
+ return pinGender(this._pin);
587
+ }
588
+ static tryParse(input, options) {
589
+ if (input == null || input.trim() === "") return null;
590
+ const sanitized = sanitizeInput(input).trim();
591
+ if (sanitized.length === 0 || sanitized.length > MAX_INPUT_LENGTH2) return null;
592
+ const clock = options?.clock ?? systemClock;
593
+ const pin = parsePin(sanitized, clock);
594
+ if (pin === null) return null;
595
+ if (pin.kind !== "coordination") return null;
596
+ return new _SwedishCoordinationNumber(pin, clock);
597
+ }
598
+ static parse(input, options) {
599
+ const r = _SwedishCoordinationNumber.tryParse(input, options);
600
+ if (r === null) throw new Error("Invalid Swedish coordination number.");
601
+ return r;
602
+ }
603
+ static isValid(input) {
604
+ return _SwedishCoordinationNumber.tryParse(input) !== null;
605
+ }
606
+ static format(input, options) {
607
+ const r = _SwedishCoordinationNumber.tryParse(input, options);
608
+ if (r) return r.formatted;
609
+ if (options?.fallbackToTrimmedInputWhenInvalid && input != null && input.trim() !== "") {
610
+ return input.trim();
611
+ }
612
+ return null;
613
+ }
614
+ static normalize(input, options) {
615
+ const r = _SwedishCoordinationNumber.tryParse(input, options);
616
+ if (r) return r.value;
617
+ if (options?.fallbackToTrimmedInputWhenInvalid && input != null) {
618
+ const t = input.trim();
619
+ return t.length > 0 ? t : null;
620
+ }
621
+ return null;
622
+ }
623
+ static isNormalized(input) {
624
+ return input != null && _SwedishCoordinationNumber.normalize(input) === input;
625
+ }
626
+ static validate(input) {
627
+ if (input == null || input.trim() === "") {
628
+ return invalidResult(
629
+ input,
630
+ ValidationErrorReason.InputIsEmpty,
631
+ "Input is empty or whitespace.",
632
+ "V\xE4rdet \xE4r tomt."
633
+ );
634
+ }
635
+ const sanitized = sanitizeInput(input).trim();
636
+ if (sanitized.length > MAX_INPUT_LENGTH2) {
637
+ return invalidResult(
638
+ input,
639
+ ValidationErrorReason.InputTooLong,
640
+ "Input contains too many characters.",
641
+ "V\xE4rdet inneh\xE5ller f\xF6r m\xE5nga tecken."
642
+ );
643
+ }
644
+ const pin = parsePin(sanitized);
645
+ if (pin === null || pin.kind !== "coordination") {
646
+ return invalidResult(
647
+ input,
648
+ ValidationErrorReason.InvalidFormat,
649
+ "Invalid coordination number format.",
650
+ "Ogiltigt format f\xF6r samordningsnummer."
651
+ );
652
+ }
653
+ return validResult(input);
654
+ }
655
+ toNormalizedString() {
656
+ return this.value;
657
+ }
658
+ toString() {
659
+ return this.formatted;
660
+ }
661
+ to10DigitString() {
662
+ return this.formatted;
663
+ }
664
+ to12DigitString() {
665
+ return this.value;
666
+ }
667
+ static findCandidatesInText(text) {
668
+ if (!text) return [];
669
+ const out = [];
670
+ SCAN_PATTERN2.lastIndex = 0;
671
+ let m;
672
+ while ((m = SCAN_PATTERN2.exec(text)) !== null) {
673
+ const cn = _SwedishCoordinationNumber.tryParse(m[0]);
674
+ if (!cn) continue;
675
+ out.push(
676
+ new TextCandidate({
677
+ startIndex: m.index,
678
+ length: m[0].length,
679
+ originalText: m[0],
680
+ typeName: "SwedishCoordinationNumber",
681
+ category: TextCandidateCategory.PersonalIdentifier,
682
+ normalizedForm: cn.toNormalizedString(),
683
+ formattedForm: cn.toString(),
684
+ maskedForm: maskCoordinationNumber(cn),
685
+ confidence: TextMatchConfidence.High,
686
+ value: cn
687
+ })
688
+ );
689
+ }
690
+ return out;
691
+ }
692
+ equals(other) {
693
+ return other != null && this.value === other.value;
694
+ }
695
+ compareTo(other) {
696
+ if (other == null) return 1;
697
+ return this.value < other.value ? -1 : this.value > other.value ? 1 : 0;
698
+ }
699
+ };
700
+ function maskCoordinationNumber(c, options) {
701
+ const f = c.formatted;
702
+ return f.slice(0, f.length - 4) + "****";
703
+ }
704
+
705
+ // src/organization/duns-number.ts
706
+ var MAX_INPUT_LENGTH3 = 20;
707
+ var DunsNumber = class _DunsNumber {
708
+ static typeInfo = Object.freeze({
709
+ englishName: "D-U-N-S Number",
710
+ localizedName: "D-U-N-S-nummer",
711
+ emoji: "\u{1F522}",
712
+ sources: Object.freeze([
713
+ "https://www.dnb.com/duns.html",
714
+ "https://en.wikipedia.org/wiki/Data_Universal_Numbering_System"
715
+ ])
716
+ });
717
+ digits;
718
+ constructor(digits) {
719
+ this.digits = digits;
720
+ }
721
+ static tryParse(input) {
722
+ if (input == null || input.trim() === "") return null;
723
+ const digits = keepDigits(sanitizeInput(input));
724
+ if (digits.length > MAX_INPUT_LENGTH3 || digits.length !== 9) return null;
725
+ return new _DunsNumber(digits);
726
+ }
727
+ static parse(input) {
728
+ const r = _DunsNumber.tryParse(input);
729
+ if (r === null) throw new Error("Invalid D-U-N-S number.");
730
+ return r;
731
+ }
732
+ static isValid(input) {
733
+ return _DunsNumber.tryParse(input) !== null;
734
+ }
735
+ static format(input, options) {
736
+ const r = _DunsNumber.tryParse(input);
737
+ if (r) return r.digits;
738
+ if (options?.fallbackToTrimmedInputWhenInvalid && input != null && input.trim() !== "") {
739
+ return input.trim();
740
+ }
741
+ return null;
742
+ }
743
+ static normalize(input, options) {
744
+ return _DunsNumber.format(input, options);
745
+ }
746
+ static isNormalized(input) {
747
+ return input != null && _DunsNumber.normalize(input) === input;
748
+ }
749
+ toNormalizedString() {
750
+ return this.digits;
751
+ }
752
+ toString() {
753
+ return this.digits;
754
+ }
755
+ static findCandidatesInText(text) {
756
+ if (!text) return [];
757
+ const out = [];
758
+ const re = /(?<!\d)\d{9}(?!\d)/g;
759
+ let m;
760
+ while ((m = re.exec(text)) !== null) {
761
+ const r = _DunsNumber.tryParse(m[0]);
762
+ if (!r) continue;
763
+ out.push(
764
+ new TextCandidate({
765
+ startIndex: m.index,
766
+ length: m[0].length,
767
+ originalText: m[0],
768
+ typeName: "DunsNumber",
769
+ category: TextCandidateCategory.OrganizationIdentifier,
770
+ normalizedForm: r.toNormalizedString(),
771
+ formattedForm: r.toString(),
772
+ maskedForm: maskDunsNumber(r),
773
+ confidence: TextMatchConfidence.Low,
774
+ value: r
775
+ })
776
+ );
777
+ }
778
+ return out;
779
+ }
780
+ equals(other) {
781
+ return other != null && this.digits === other.digits;
782
+ }
783
+ compareTo(other) {
784
+ if (other == null) return 1;
785
+ return this.digits < other.digits ? -1 : this.digits > other.digits ? 1 : 0;
786
+ }
787
+ };
788
+ function maskDunsNumber(d) {
789
+ return "*".repeat(d.digits.length);
790
+ }
791
+
792
+ // src/organization/organization-validation-utils.ts
793
+ function isValidIso7064Mod97(input) {
794
+ if (!input) return false;
795
+ let s = "";
796
+ for (const c of input) {
797
+ if (c >= "0" && c <= "9") s += c;
798
+ else if (c >= "A" && c <= "Z") s += String(c.charCodeAt(0) - 55);
799
+ else if (c >= "a" && c <= "z") s += String(c.charCodeAt(0) - 87);
800
+ else return false;
801
+ }
802
+ let mod = 0;
803
+ for (let i = 0; i < s.length; i++) {
804
+ mod = (mod * 10 + (s.charCodeAt(i) - 48)) % 97;
805
+ }
806
+ return mod === 1;
807
+ }
808
+ function cleanSeparators(input) {
809
+ if (!input) return "";
810
+ let out = "";
811
+ for (const c of input) {
812
+ if (c !== " " && c !== "-" && c !== "\xA0") out += c;
813
+ }
814
+ return out;
815
+ }
816
+ function nameContains(haystack, ...needles) {
817
+ if (!haystack) return false;
818
+ for (const n of needles) if (haystack.indexOf(n) >= 0) return true;
819
+ return false;
820
+ }
821
+ function nameContainsStandalone(haystack, ...needles) {
822
+ if (!haystack) return false;
823
+ for (const n of needles) {
824
+ if (haystack === n) return true;
825
+ if (haystack.startsWith(n + " ")) return true;
826
+ if (haystack.endsWith(" " + n)) return true;
827
+ if (haystack.indexOf(" " + n + " ") >= 0) return true;
828
+ }
829
+ return false;
830
+ }
831
+
832
+ // src/organization/swedish-organization-name.ts
833
+ var MAX_INPUT_LENGTH4 = 300;
834
+ var COMPANY_NAME_PATTERN = /^[\p{L}\d\s\-'&.,/:()+]+$/u;
835
+ var ORG_SUFFIX_TOKENS = ["AB", "HB", "KB", "BRF", "HSB", "EF"];
836
+ var ORG_SUFFIX_PHRASES = [
837
+ " EK.F\xD6R.",
838
+ " EK F\xD6R",
839
+ " EKONOMISK F\xD6RENING",
840
+ " IDEELL F\xD6RENING",
841
+ " SAMF\xC4LLIGHETSF\xD6RENING",
842
+ " RIKSF\xD6RBUND"
843
+ ];
844
+ var ORG_PREFIXES = ["STIFTELSEN ", "BRF ", "HSB "];
845
+ var ORG_KEYWORDS = [
846
+ " KOMMUN",
847
+ " REGION",
848
+ " LANDSTING",
849
+ " MYNDIGHET",
850
+ " STIFTELSE",
851
+ " F\xD6RENING"
852
+ ];
853
+ var KNOWN_ABBREVIATIONS = /* @__PURE__ */ new Set(["AB", "HB", "KB", "BRF", "HSB", "EF"]);
854
+ var KNOWN_GOVERNMENT_AGENCIES = /* @__PURE__ */ new Set([
855
+ "SKATTEVERKET",
856
+ "TULLVERKET",
857
+ "KRONOFOGDEN",
858
+ "STATISTISKA CENTRALBYR\xC5N",
859
+ "KRIMINALV\xC5RDEN",
860
+ "MIGRATIONSVERKET",
861
+ "DOMSTOLSVERKET",
862
+ "BROTTSF\xD6REBYGGANDE R\xC5DET",
863
+ "F\xD6RS\xC4KRINGSKASSAN",
864
+ "SOCIALSTYRELSEN",
865
+ "SKOLVERKET",
866
+ "CENTRALA STUDIEST\xD6DSN\xC4MNDEN",
867
+ "UNIVERSITETS- OCH H\xD6GSKOLER\xC5DET",
868
+ "BOLAGSVERKET",
869
+ "TRAFIKVERKET",
870
+ "TRANSPORTSTYRELSEN",
871
+ "TILLV\xC4XTVERKET",
872
+ "PATENT- OCH REGISTRERINGSVERKET",
873
+ "ARBETSF\xD6RMEDLINGEN",
874
+ "ARBETSMILJ\xD6VERKET",
875
+ "NATURV\xC5RDSVERKET",
876
+ "F\xD6RSVARSMAKTEN",
877
+ "POST- OCH TELESTYRELSEN",
878
+ "SJ\xD6FARTSVERKET",
879
+ "RIKSBANKEN",
880
+ "RIKSREVISIONEN",
881
+ "RIKSG\xC4LDEN",
882
+ "RIKSG\xC4LDSKONTORET",
883
+ "EKONOMISTYRNINGSVERKET",
884
+ "JORDBRUKSVERKET",
885
+ "LIVSMEDELSVERKET",
886
+ "LANTM\xC4TERIET",
887
+ "BOVERKET",
888
+ "KONSUMENTVERKET",
889
+ "RIKSARKIVET",
890
+ "KUNGLIGA BIBLIOTEKET",
891
+ "KEMIKALIEINSPEKTIONEN",
892
+ "INTEGRITETSSKYDDSMYNDIGHETEN",
893
+ "ELS\xC4KERHETSVERKET",
894
+ "HAVS- OCH VATTENMYNDIGHETEN",
895
+ "SKOGSSTYRELSEN",
896
+ "VALMYNDIGHETEN",
897
+ "L\xC4NSSTYRELSEN",
898
+ "DATAINSPEKTIONEN",
899
+ "KONKURRENSVERKET",
900
+ "UPPHANDLINGSMYNDIGHETEN"
901
+ ]);
902
+ var SwedishOrganizationName = class _SwedishOrganizationName {
903
+ static typeInfo = Object.freeze({
904
+ englishName: "Organization Name",
905
+ localizedName: "Organisationsnamn",
906
+ emoji: "\u{1F3F7}\uFE0F",
907
+ sources: Object.freeze(["https://bolagsverket.se"])
908
+ });
909
+ value;
910
+ casingNormalizedValue;
911
+ hasOrganizationIndicators;
912
+ inferredSwedishOrganizationType;
913
+ constructor(value, casingNormalized, hasIndicators, inferredType) {
914
+ this.value = value;
915
+ this.casingNormalizedValue = casingNormalized;
916
+ this.hasOrganizationIndicators = hasIndicators;
917
+ this.inferredSwedishOrganizationType = inferredType;
918
+ }
919
+ static tryParse(input) {
920
+ const normalized = collapseWhitespace(input);
921
+ if (normalized.length === 0 || normalized.length > MAX_INPUT_LENGTH4) return null;
922
+ if (!validateName(normalized)) return null;
923
+ const forInference = stripPublSuffix(normalized);
924
+ const hasIndicators = detectOrganizationIndicators(forInference);
925
+ const inferred = inferTypeFromName(forInference);
926
+ const casing = _SwedishOrganizationName.normalizeCasing(normalized);
927
+ return new _SwedishOrganizationName(normalized, casing, hasIndicators, inferred);
928
+ }
929
+ static parse(input) {
930
+ const r = _SwedishOrganizationName.tryParse(input);
931
+ if (r === null) throw new Error("Invalid organization name.");
932
+ return r;
933
+ }
934
+ static isValid(input) {
935
+ return _SwedishOrganizationName.tryParse(input) !== null;
936
+ }
937
+ static isKnownGovernmentAgency(name) {
938
+ if (name == null || name.trim() === "") return false;
939
+ return KNOWN_GOVERNMENT_AGENCIES.has(collapseWhitespace(name).toUpperCase());
940
+ }
941
+ static inferSwedishOrganizationType(name) {
942
+ if (name == null || name.trim() === "") return 0 /* Unknown */;
943
+ return inferTypeFromName(stripPublSuffix(collapseWhitespace(name)));
944
+ }
945
+ static normalizeCasing(name) {
946
+ const letters = [...name].filter((c) => /\p{L}/u.test(c));
947
+ if (letters.length === 0) return name;
948
+ const allLower = letters.every((c) => c === c.toLowerCase());
949
+ const allUpper = letters.every((c) => c === c.toUpperCase());
950
+ if (!allLower && !allUpper) return name;
951
+ return name.split(" ").map((w) => KNOWN_ABBREVIATIONS.has(w.toUpperCase()) ? w.toUpperCase() : capitalizeWord(w)).join(" ");
952
+ }
953
+ static format(input, options) {
954
+ const r = _SwedishOrganizationName.tryParse(input);
955
+ if (r) return r.value;
956
+ if (options?.fallbackToTrimmedInputWhenInvalid && input != null && input.trim() !== "") {
957
+ return input.trim();
958
+ }
959
+ return null;
960
+ }
961
+ static normalize(input, options) {
962
+ return _SwedishOrganizationName.format(input, options);
963
+ }
964
+ static isNormalized(input) {
965
+ return input != null && _SwedishOrganizationName.normalize(input) === input;
966
+ }
967
+ toNormalizedString() {
968
+ return this.value;
969
+ }
970
+ toString() {
971
+ return this.value;
972
+ }
973
+ equals(other) {
974
+ return other != null && this.value === other.value;
975
+ }
976
+ compareTo(other) {
977
+ if (other == null) return 1;
978
+ return this.value < other.value ? -1 : this.value > other.value ? 1 : 0;
979
+ }
980
+ };
981
+ function stripPublSuffix(name) {
982
+ const trimmed = name.trimEnd();
983
+ if (trimmed.toUpperCase().endsWith("(PUBL)")) return trimmed.slice(0, -6).trimEnd();
984
+ return name;
985
+ }
986
+ function validateName(value) {
987
+ if (value.length < 2 || value.length > 200) return false;
988
+ for (const c of value) {
989
+ const code = c.charCodeAt(0);
990
+ if (code < 32 || code === 127) return false;
991
+ }
992
+ return COMPANY_NAME_PATTERN.test(value);
993
+ }
994
+ function detectOrganizationIndicators(collapsed) {
995
+ const upper = collapsed.toUpperCase();
996
+ if (!upper) return false;
997
+ const words = upper.split(" ");
998
+ if (words.length > 0 && ORG_SUFFIX_TOKENS.includes(words[words.length - 1])) return true;
999
+ for (const p of ORG_SUFFIX_PHRASES) if (upper.endsWith(p)) return true;
1000
+ for (const p of ORG_PREFIXES) if (upper.startsWith(p)) return true;
1001
+ for (const k of ORG_KEYWORDS) if (upper.indexOf(k) >= 0) return true;
1002
+ if (KNOWN_GOVERNMENT_AGENCIES.has(upper)) return true;
1003
+ return false;
1004
+ }
1005
+ function inferTypeFromName(collapsed) {
1006
+ const upper = collapsed.toUpperCase();
1007
+ if (!upper) return 0 /* Unknown */;
1008
+ const words = upper.split(" ");
1009
+ const lastWord = words.length > 0 ? words[words.length - 1] : "";
1010
+ if (lastWord === "AB") return 1 /* Aktiebolag */;
1011
+ if (lastWord === "KB" || nameContains(upper, "KOMMANDITBOLAG"))
1012
+ return 12 /* Kommanditbolag */;
1013
+ if (lastWord === "HB" || nameContains(upper, "HANDELSBOLAG"))
1014
+ return 11 /* Handelsbolag */;
1015
+ if (nameContainsStandalone(upper, "BRF") || nameContains(upper, "BOSTADSR\xC4TTSF\xD6RENING", "BOSTADSRATTSFORENING"))
1016
+ return 21 /* Bostadsrattsforening */;
1017
+ if (nameContains(
1018
+ upper,
1019
+ "SAMF\xC4LLIGHETSF\xD6RENING",
1020
+ "SAMFALLIGHETSFORENING",
1021
+ "SAMFALLIGHETSSFORENING",
1022
+ "SAMF\xC4LLIGHET",
1023
+ "SAMFALLIGHET"
1024
+ ))
1025
+ return 22 /* Samfallighetsforening */;
1026
+ if (lastWord === "HSB" || upper.startsWith("HSB "))
1027
+ return 20 /* EkonomiskForening */;
1028
+ if (upper.endsWith(" EK.F\xD6R.") || upper.endsWith(" EK F\xD6R") || nameContains(upper, "EKONOMISK F\xD6RENING"))
1029
+ return 20 /* EkonomiskForening */;
1030
+ if (nameContains(upper, "IDEELL F\xD6RENING")) return 30 /* IdeellForening */;
1031
+ if (upper.startsWith("STIFTELSEN ") || nameContains(upper, "STIFTELSE"))
1032
+ return 31 /* Stiftelse */;
1033
+ if (nameContains(upper, "KOMMUN")) return 41 /* Kommun */;
1034
+ if (nameContains(upper, "REGION", "LANDSTING")) return 42 /* Region */;
1035
+ if (nameContains(upper, "F\xD6RSAMLING", "FORSAMLING")) return 43 /* Forsamling */;
1036
+ if (nameContains(upper, "MYNDIGHET")) return 40 /* OffentligSektor */;
1037
+ if (KNOWN_GOVERNMENT_AGENCIES.has(upper)) return 40 /* OffentligSektor */;
1038
+ if (nameContains(upper, "D\xD6DSBO", "DODSBO")) return 2 /* Dodsbo */;
1039
+ if (lastWord === "EF" || nameContains(upper, "ENSKILD FIRMA"))
1040
+ return 61 /* EnskildFirma */;
1041
+ if (nameContains(upper, "PRIVATPERSON")) return 62 /* Privatperson */;
1042
+ if (nameContainsStandalone(upper, "EUROPABOLAG", "SE-BOLAG"))
1043
+ return 52 /* Europabolag */;
1044
+ if (nameContainsStandalone(upper, "EUROPEISK EKONOMISK INTRESSEGRUPPERING", "EEIG"))
1045
+ return 53 /* EuropeiskEkonomiskIntressegruppering */;
1046
+ if (nameContainsStandalone(upper, "SCE") || nameContains(upper, "EUROPEISK KOOPERATIV F\xD6RENING"))
1047
+ return 54 /* SCEForening */;
1048
+ if (nameContainsStandalone(upper, "FILIAL")) return 51 /* Filial */;
1049
+ if (nameContains(upper, "RIKSF\xD6RBUND", "F\xD6RENING")) return 30 /* IdeellForening */;
1050
+ return 0 /* Unknown */;
1051
+ }
1052
+ function maskSwedishOrganizationName(value) {
1053
+ return value.value.split(" ").filter((part) => part.length > 0).map((part) => part.length <= 1 ? "*" : part[0] + "*".repeat(part.length - 1)).join(" ");
1054
+ }
1055
+ function capitalizeWord(word) {
1056
+ if (!word) return word;
1057
+ const lowered = word.toLocaleLowerCase("sv-SE");
1058
+ return lowered[0].toLocaleUpperCase("sv-SE") + lowered.slice(1);
1059
+ }
1060
+
1061
+ // src/organization/swedish-organization-number.ts
1062
+ var MAX_INPUT_LENGTH5 = 30;
1063
+ var LEGAL_ENTITY_PREFIX = "16";
1064
+ var SwedishOrganizationNumber = class _SwedishOrganizationNumber {
1065
+ static typeInfo = Object.freeze({
1066
+ englishName: "Organization Number",
1067
+ localizedName: "Organisationsnummer",
1068
+ emoji: "\u{1F3E2}",
1069
+ sources: Object.freeze([
1070
+ "https://bolagsverket.se",
1071
+ "https://skatteverket.se/foretag/drivaforetag/startaforetag/organisationsnummer.html",
1072
+ "https://sv.wikipedia.org/wiki/Organisationsnummer"
1073
+ ])
1074
+ });
1075
+ _tenWithDash;
1076
+ _twelveDigits;
1077
+ _isPerson;
1078
+ get isPerson() {
1079
+ return this._isPerson;
1080
+ }
1081
+ constructor(tenWithDash, twelveDigits, isPerson) {
1082
+ this._tenWithDash = tenWithDash;
1083
+ this._twelveDigits = twelveDigits;
1084
+ this._isPerson = isPerson;
1085
+ }
1086
+ static tryParse(input) {
1087
+ if (input == null || input.trim() === "") return null;
1088
+ const sanitized = sanitizeInput(input).trim();
1089
+ if (sanitized.length > MAX_INPUT_LENGTH5) return null;
1090
+ const pin = SwedishPersonalIdentityNumber.tryParse(sanitized);
1091
+ if (pin) {
1092
+ return new _SwedishOrganizationNumber(pin.formatted, pin.value, true);
1093
+ }
1094
+ const cn = SwedishCoordinationNumber.tryParse(sanitized);
1095
+ if (cn) {
1096
+ return new _SwedishOrganizationNumber(cn.formatted, cn.value, true);
1097
+ }
1098
+ const digits = keepDigits(sanitized);
1099
+ if (digits.length === 0) return null;
1100
+ let tenDigits;
1101
+ if (digits.length === 10) tenDigits = digits;
1102
+ else if (digits.length === 12 && digits.startsWith(LEGAL_ENTITY_PREFIX))
1103
+ tenDigits = digits.slice(2);
1104
+ else return null;
1105
+ if (!isLegalEntityPattern(tenDigits)) return null;
1106
+ if (!luhnIsValid(tenDigits)) return null;
1107
+ const tenWithDash = `${tenDigits.slice(0, 6)}-${tenDigits.slice(6)}`;
1108
+ const twelve = LEGAL_ENTITY_PREFIX + tenDigits;
1109
+ return new _SwedishOrganizationNumber(tenWithDash, twelve, false);
1110
+ }
1111
+ static parse(input) {
1112
+ const r = _SwedishOrganizationNumber.tryParse(input);
1113
+ if (r === null) throw new Error("Invalid Swedish organization number.");
1114
+ return r;
1115
+ }
1116
+ static isValid(input) {
1117
+ return _SwedishOrganizationNumber.tryParse(input) !== null;
1118
+ }
1119
+ static format(input, options) {
1120
+ const r = _SwedishOrganizationNumber.tryParse(input);
1121
+ if (r) return r.to10DigitString();
1122
+ if (options?.fallbackToTrimmedInputWhenInvalid && input != null && input.trim() !== "") {
1123
+ return input.trim();
1124
+ }
1125
+ return null;
1126
+ }
1127
+ static normalize(input, options) {
1128
+ const r = _SwedishOrganizationNumber.tryParse(input);
1129
+ if (r) return r.to12DigitString();
1130
+ if (options?.fallbackToTrimmedInputWhenInvalid && input != null) {
1131
+ const t = input.trim();
1132
+ return t.length > 0 ? t : null;
1133
+ }
1134
+ return null;
1135
+ }
1136
+ static isNormalized(input) {
1137
+ return input != null && _SwedishOrganizationNumber.normalize(input) === input;
1138
+ }
1139
+ to10DigitsOnly() {
1140
+ return this._tenWithDash.replace(/[-+]/g, "");
1141
+ }
1142
+ to10DigitString() {
1143
+ return this._tenWithDash;
1144
+ }
1145
+ to12DigitString() {
1146
+ return this._twelveDigits;
1147
+ }
1148
+ toNormalizedString() {
1149
+ return this.to12DigitString();
1150
+ }
1151
+ toString() {
1152
+ return this.to10DigitString();
1153
+ }
1154
+ getSwedishOrganizationTypeHint(name, isPrivatePerson) {
1155
+ let certain;
1156
+ let bestGuess;
1157
+ if (this._isPerson) {
1158
+ certain = 60 /* EnskildFirmaEllerPrivatperson */;
1159
+ if (isPrivatePerson === true) bestGuess = 62 /* Privatperson */;
1160
+ else if (isPrivatePerson === false) bestGuess = 61 /* EnskildFirma */;
1161
+ else {
1162
+ const nameType2 = SwedishOrganizationName.inferSwedishOrganizationType(name ?? null);
1163
+ bestGuess = nameType2 === 61 /* EnskildFirma */ || nameType2 === 62 /* Privatperson */ ? nameType2 : certain;
1164
+ }
1165
+ return { certain, bestGuess };
1166
+ }
1167
+ const first = this.to10DigitsOnly()[0];
1168
+ const nameType = SwedishOrganizationName.inferSwedishOrganizationType(name ?? null);
1169
+ switch (first) {
1170
+ case "1":
1171
+ certain = 2 /* Dodsbo */;
1172
+ bestGuess = certain;
1173
+ break;
1174
+ case "2":
1175
+ certain = 40 /* OffentligSektor */;
1176
+ bestGuess = nameType === 41 /* Kommun */ || nameType === 42 /* Region */ || nameType === 43 /* Forsamling */ ? nameType : certain;
1177
+ break;
1178
+ case "5":
1179
+ certain = 1 /* Aktiebolag */;
1180
+ bestGuess = nameType === 12 /* Kommanditbolag */ ? nameType : certain;
1181
+ break;
1182
+ case "6":
1183
+ certain = 10 /* HandelsbolagEllerKommanditbolag */;
1184
+ bestGuess = nameType === 12 /* Kommanditbolag */ || nameType === 11 /* Handelsbolag */ ? nameType : certain;
1185
+ break;
1186
+ case "7":
1187
+ certain = 20 /* EkonomiskForening */;
1188
+ bestGuess = nameType === 21 /* Bostadsrattsforening */ || nameType === 22 /* Samfallighetsforening */ ? nameType : certain;
1189
+ break;
1190
+ case "8":
1191
+ certain = 30 /* IdeellForening */;
1192
+ bestGuess = nameType === 31 /* Stiftelse */ ? nameType : certain;
1193
+ break;
1194
+ case "9":
1195
+ certain = 10 /* HandelsbolagEllerKommanditbolag */;
1196
+ bestGuess = nameType === 12 /* Kommanditbolag */ || nameType === 11 /* Handelsbolag */ ? nameType : certain;
1197
+ break;
1198
+ default:
1199
+ certain = 99 /* Other */;
1200
+ bestGuess = nameType === 53 /* EuropeiskEkonomiskIntressegruppering */ || nameType === 52 /* Europabolag */ || nameType === 54 /* SCEForening */ || nameType === 51 /* Filial */ ? nameType : certain;
1201
+ break;
1202
+ }
1203
+ return { certain, bestGuess };
1204
+ }
1205
+ static validate(input) {
1206
+ if (input == null || input.trim() === "") {
1207
+ return invalidResult(
1208
+ input,
1209
+ ValidationErrorReason.InputIsEmpty,
1210
+ "Input is empty or whitespace.",
1211
+ "V\xE4rdet \xE4r tomt."
1212
+ );
1213
+ }
1214
+ const sanitized = sanitizeInput(input).trim();
1215
+ if (sanitized.length > MAX_INPUT_LENGTH5) {
1216
+ return invalidResult(
1217
+ input,
1218
+ ValidationErrorReason.InputTooLong,
1219
+ "Input contains too many characters.",
1220
+ "V\xE4rdet inneh\xE5ller f\xF6r m\xE5nga tecken."
1221
+ );
1222
+ }
1223
+ if (SwedishPersonalIdentityNumber.tryParse(sanitized)) return validResult(input);
1224
+ if (SwedishCoordinationNumber.tryParse(sanitized)) return validResult(input);
1225
+ const digits = keepDigits(sanitized);
1226
+ if (digits.length === 0) {
1227
+ return invalidResult(
1228
+ input,
1229
+ ValidationErrorReason.InvalidFormat,
1230
+ "Input contains no digits.",
1231
+ "V\xE4rdet inneh\xE5ller inga siffror."
1232
+ );
1233
+ }
1234
+ if (!(digits.length === 10 || digits.length === 12 && digits.startsWith(LEGAL_ENTITY_PREFIX))) {
1235
+ return invalidResult(
1236
+ input,
1237
+ ValidationErrorReason.InvalidLength,
1238
+ "Organization number must be 10 or 12 digits (12-digit form must start with 16).",
1239
+ "Organisationsnummer m\xE5ste vara 10 eller 12 siffror (12-siffrig form m\xE5ste b\xF6rja med 16)."
1240
+ );
1241
+ }
1242
+ const tenDigits = digits.length === 12 ? digits.slice(2) : digits;
1243
+ if (!isLegalEntityPattern(tenDigits)) {
1244
+ return invalidResult(
1245
+ input,
1246
+ ValidationErrorReason.InvalidEntityPattern,
1247
+ "Number does not match a valid organization type pattern.",
1248
+ "Numret matchar inte ett giltigt organisationstypsm\xF6nster."
1249
+ );
1250
+ }
1251
+ if (!luhnIsValid(tenDigits)) {
1252
+ return invalidResult(
1253
+ input,
1254
+ ValidationErrorReason.InvalidCheckDigit,
1255
+ "Invalid check digit.",
1256
+ "Ogiltig kontrollsiffra."
1257
+ );
1258
+ }
1259
+ return validResult(input);
1260
+ }
1261
+ static findCandidatesInText(text) {
1262
+ if (!text) return [];
1263
+ const out = [];
1264
+ const re = /(?<!\d)(\d{6})-?(\d{4})(?!\d)/g;
1265
+ let m;
1266
+ while ((m = re.exec(text)) !== null) {
1267
+ const r = _SwedishOrganizationNumber.tryParse(m[0]);
1268
+ if (!r || r.isPerson) continue;
1269
+ out.push(
1270
+ new TextCandidate({
1271
+ startIndex: m.index,
1272
+ length: m[0].length,
1273
+ originalText: m[0],
1274
+ typeName: "SwedishOrganizationNumber",
1275
+ category: TextCandidateCategory.OrganizationIdentifier,
1276
+ normalizedForm: r.toNormalizedString(),
1277
+ formattedForm: r.toString(),
1278
+ maskedForm: maskSwedishOrganizationNumber(r),
1279
+ confidence: TextMatchConfidence.High,
1280
+ value: r
1281
+ })
1282
+ );
1283
+ }
1284
+ return out;
1285
+ }
1286
+ equals(other) {
1287
+ return other != null && this._twelveDigits === other._twelveDigits;
1288
+ }
1289
+ compareTo(other) {
1290
+ if (other == null) return 1;
1291
+ return this._twelveDigits < other._twelveDigits ? -1 : this._twelveDigits > other._twelveDigits ? 1 : 0;
1292
+ }
1293
+ };
1294
+ function isLegalEntityPattern(tenDigits) {
1295
+ if (tenDigits.length !== 10) return false;
1296
+ if (tenDigits[0] === "1") return true;
1297
+ const first = tenDigits[0];
1298
+ if (first !== "2" && first !== "3" && first !== "5" && first !== "6" && first !== "7" && first !== "8" && first !== "9")
1299
+ return false;
1300
+ const m1 = tenDigits.charCodeAt(2) - 48;
1301
+ const m2 = tenDigits.charCodeAt(3) - 48;
1302
+ const mm = m1 * 10 + m2;
1303
+ return mm >= 20;
1304
+ }
1305
+ function maskSwedishOrganizationNumber(o, options) {
1306
+ const s = o.to10DigitString();
1307
+ if (o.isPerson) {
1308
+ const sep = s[6];
1309
+ if (options?.maskBirthDate) return "******" + sep + "****";
1310
+ return s.slice(0, 6) + sep + "****";
1311
+ }
1312
+ if (options?.maskOrganizationNumbers) return s.slice(0, 7) + "****";
1313
+ return s;
1314
+ }
1315
+
1316
+ // src/organization/eu-vat-number.ts
1317
+ var MAX_INPUT_LENGTH6 = 30;
1318
+ var COUNTRY_INFO = Object.freeze({
1319
+ AT: { countryCode: "AT", countryName: "Austria" },
1320
+ BE: { countryCode: "BE", countryName: "Belgium" },
1321
+ BG: { countryCode: "BG", countryName: "Bulgaria" },
1322
+ HR: { countryCode: "HR", countryName: "Croatia" },
1323
+ CY: { countryCode: "CY", countryName: "Cyprus" },
1324
+ CZ: { countryCode: "CZ", countryName: "Czech Republic" },
1325
+ DK: { countryCode: "DK", countryName: "Denmark" },
1326
+ EE: { countryCode: "EE", countryName: "Estonia" },
1327
+ FI: { countryCode: "FI", countryName: "Finland" },
1328
+ FR: { countryCode: "FR", countryName: "France" },
1329
+ DE: { countryCode: "DE", countryName: "Germany" },
1330
+ EL: { countryCode: "GR", countryName: "Greece" },
1331
+ GR: { countryCode: "GR", countryName: "Greece" },
1332
+ HU: { countryCode: "HU", countryName: "Hungary" },
1333
+ IE: { countryCode: "IE", countryName: "Ireland" },
1334
+ IT: { countryCode: "IT", countryName: "Italy" },
1335
+ LV: { countryCode: "LV", countryName: "Latvia" },
1336
+ LT: { countryCode: "LT", countryName: "Lithuania" },
1337
+ LU: { countryCode: "LU", countryName: "Luxembourg" },
1338
+ MT: { countryCode: "MT", countryName: "Malta" },
1339
+ NL: { countryCode: "NL", countryName: "Netherlands" },
1340
+ PL: { countryCode: "PL", countryName: "Poland" },
1341
+ PT: { countryCode: "PT", countryName: "Portugal" },
1342
+ RO: { countryCode: "RO", countryName: "Romania" },
1343
+ SK: { countryCode: "SK", countryName: "Slovakia" },
1344
+ SI: { countryCode: "SI", countryName: "Slovenia" },
1345
+ ES: { countryCode: "ES", countryName: "Spain" },
1346
+ SE: { countryCode: "SE", countryName: "Sweden" },
1347
+ GB: { countryCode: "GB", countryName: "United Kingdom" },
1348
+ NO: { countryCode: "NO", countryName: "Norway" },
1349
+ IS: { countryCode: "IS", countryName: "Iceland" },
1350
+ LI: { countryCode: "LI", countryName: "Liechtenstein" },
1351
+ CH: { countryCode: "CH", countryName: "Switzerland" },
1352
+ AL: { countryCode: "AL", countryName: "Albania" },
1353
+ BA: { countryCode: "BA", countryName: "Bosnia and Herzegovina" },
1354
+ BY: { countryCode: "BY", countryName: "Belarus" },
1355
+ MK: { countryCode: "MK", countryName: "North Macedonia" },
1356
+ RS: { countryCode: "RS", countryName: "Serbia" },
1357
+ SM: { countryCode: "SM", countryName: "San Marino" },
1358
+ TR: { countryCode: "TR", countryName: "Turkey" },
1359
+ UA: { countryCode: "UA", countryName: "Ukraine" },
1360
+ RU: { countryCode: "RU", countryName: "Russia" },
1361
+ UZ: { countryCode: "UZ", countryName: "Uzbekistan" },
1362
+ AU: { countryCode: "AU", countryName: "Australia" },
1363
+ CN: { countryCode: "CN", countryName: "China" },
1364
+ HK: { countryCode: "HK", countryName: "Hong Kong" },
1365
+ IN: { countryCode: "IN", countryName: "India" },
1366
+ ID: { countryCode: "ID", countryName: "Indonesia" },
1367
+ IL: { countryCode: "IL", countryName: "Israel" },
1368
+ JP: { countryCode: "JP", countryName: "Japan" },
1369
+ KZ: { countryCode: "KZ", countryName: "Kazakhstan" },
1370
+ NZ: { countryCode: "NZ", countryName: "New Zealand" },
1371
+ PH: { countryCode: "PH", countryName: "Philippines" },
1372
+ SA: { countryCode: "SA", countryName: "Saudi Arabia" },
1373
+ SG: { countryCode: "SG", countryName: "Singapore" },
1374
+ TW: { countryCode: "TW", countryName: "Taiwan" },
1375
+ AR: { countryCode: "AR", countryName: "Argentina" },
1376
+ BZ: { countryCode: "BZ", countryName: "Belize" },
1377
+ BO: { countryCode: "BO", countryName: "Bolivia" },
1378
+ BR: { countryCode: "BR", countryName: "Brazil" },
1379
+ CA: { countryCode: "CA", countryName: "Canada" },
1380
+ CL: { countryCode: "CL", countryName: "Chile" },
1381
+ CO: { countryCode: "CO", countryName: "Colombia" },
1382
+ CR: { countryCode: "CR", countryName: "Costa Rica" },
1383
+ DO: { countryCode: "DO", countryName: "Dominican Republic" },
1384
+ EC: { countryCode: "EC", countryName: "Ecuador" },
1385
+ SV: { countryCode: "SV", countryName: "El Salvador" },
1386
+ GT: { countryCode: "GT", countryName: "Guatemala" },
1387
+ HN: { countryCode: "HN", countryName: "Honduras" },
1388
+ MX: { countryCode: "MX", countryName: "Mexico" },
1389
+ NI: { countryCode: "NI", countryName: "Nicaragua" },
1390
+ PA: { countryCode: "PA", countryName: "Panama" },
1391
+ PY: { countryCode: "PY", countryName: "Paraguay" },
1392
+ PE: { countryCode: "PE", countryName: "Peru" },
1393
+ UY: { countryCode: "UY", countryName: "Uruguay" },
1394
+ US: { countryCode: "US", countryName: "United States" },
1395
+ VE: { countryCode: "VE", countryName: "Venezuela" },
1396
+ NG: { countryCode: "NG", countryName: "Nigeria" }
1397
+ });
1398
+ var EuVatNumber = class _EuVatNumber {
1399
+ static typeInfo = Object.freeze({
1400
+ englishName: "VAT Number",
1401
+ localizedName: "Momsnummer",
1402
+ emoji: "\u{1F4B0}",
1403
+ sources: Object.freeze([
1404
+ "https://ec.europa.eu/taxation_customs/vies/#/vat-validation",
1405
+ "https://en.wikipedia.org/wiki/VAT_identification_number"
1406
+ ])
1407
+ });
1408
+ vatPrefix;
1409
+ countryCode;
1410
+ countryName;
1411
+ body;
1412
+ constructor(vatPrefix, countryCode, countryName, body) {
1413
+ this.vatPrefix = vatPrefix;
1414
+ this.countryCode = countryCode;
1415
+ this.countryName = countryName;
1416
+ this.body = body;
1417
+ }
1418
+ static tryParse(input) {
1419
+ if (input == null || input.trim() === "") return null;
1420
+ const cleaned = cleanSeparators(sanitizeInput(input));
1421
+ if (cleaned.length > MAX_INPUT_LENGTH6 || cleaned.length < 3) return null;
1422
+ const cc = cleaned.slice(0, 2).toUpperCase();
1423
+ if (!/^[A-Z]{2}$/.test(cc)) return null;
1424
+ const info = COUNTRY_INFO[cc];
1425
+ if (!info) return null;
1426
+ const body = cleaned.slice(2).split("").map((c) => {
1427
+ if (!/[A-Za-z0-9]/.test(c)) return null;
1428
+ return c.toUpperCase();
1429
+ });
1430
+ if (body.some((c) => c === null)) return null;
1431
+ const bodyString = body.join("");
1432
+ if (bodyString.length === 0) return null;
1433
+ if (!validateCountryFormat(info.countryCode, bodyString)) return null;
1434
+ return new _EuVatNumber(cc, info.countryCode, info.countryName, bodyString);
1435
+ }
1436
+ static parse(input) {
1437
+ const r = _EuVatNumber.tryParse(input);
1438
+ if (r === null) throw new Error("Invalid VAT number.");
1439
+ return r;
1440
+ }
1441
+ static isValid(input) {
1442
+ return _EuVatNumber.tryParse(input) !== null;
1443
+ }
1444
+ static format(input, options) {
1445
+ const r = _EuVatNumber.tryParse(input);
1446
+ if (r) return r.vatPrefix + r.body;
1447
+ if (options?.fallbackToTrimmedInputWhenInvalid && input != null && input.trim() !== "") {
1448
+ return input.trim();
1449
+ }
1450
+ return null;
1451
+ }
1452
+ static normalize(input, options) {
1453
+ return _EuVatNumber.format(input, options);
1454
+ }
1455
+ static isNormalized(input) {
1456
+ return input != null && _EuVatNumber.normalize(input) === input;
1457
+ }
1458
+ static tryParseForCountry(input, countryCode) {
1459
+ if (countryCode == null || countryCode.trim() === "") return null;
1460
+ const vat = _EuVatNumber.tryParse(input);
1461
+ if (!vat) return null;
1462
+ const normalized = countryCode.toUpperCase();
1463
+ if ((normalized === "EL" || normalized === "GR") && vat.countryCode === "GR") return vat;
1464
+ return vat.countryCode === normalized ? vat : null;
1465
+ }
1466
+ static parseForCountry(input, countryCode) {
1467
+ const r = _EuVatNumber.tryParseForCountry(input, countryCode);
1468
+ if (!r) throw new Error(`Invalid VAT number for country ${countryCode}.`);
1469
+ return r;
1470
+ }
1471
+ static validate(input) {
1472
+ if (input == null || input.trim() === "") {
1473
+ return invalidResult(
1474
+ input,
1475
+ ValidationErrorReason.InputIsEmpty,
1476
+ "Input is empty or whitespace.",
1477
+ "V\xE4rdet \xE4r tomt."
1478
+ );
1479
+ }
1480
+ const cleaned = cleanSeparators(sanitizeInput(input));
1481
+ if (cleaned.length > MAX_INPUT_LENGTH6) {
1482
+ return invalidResult(
1483
+ input,
1484
+ ValidationErrorReason.InputTooLong,
1485
+ "Input contains too many characters.",
1486
+ "V\xE4rdet inneh\xE5ller f\xF6r m\xE5nga tecken."
1487
+ );
1488
+ }
1489
+ if (cleaned.length < 3) {
1490
+ return invalidResult(
1491
+ input,
1492
+ ValidationErrorReason.InputTooShort,
1493
+ "VAT number is too short.",
1494
+ "Momsnumret \xE4r f\xF6r kort."
1495
+ );
1496
+ }
1497
+ const cc = cleaned.slice(0, 2).toUpperCase();
1498
+ if (!/^[A-Z]{2}$/.test(cc)) {
1499
+ return invalidResult(
1500
+ input,
1501
+ ValidationErrorReason.InvalidCountryPrefix,
1502
+ "VAT number must start with a two-letter country code.",
1503
+ "Momsnumret m\xE5ste b\xF6rja med en tv\xE5bokstavig landskod."
1504
+ );
1505
+ }
1506
+ const info = COUNTRY_INFO[cc];
1507
+ if (!info) {
1508
+ return invalidResult(
1509
+ input,
1510
+ ValidationErrorReason.UnknownCountryCode,
1511
+ "Unknown VAT country code.",
1512
+ "Ok\xE4nd momsnummer-landskod."
1513
+ );
1514
+ }
1515
+ let body = "";
1516
+ for (const c of cleaned.slice(2)) {
1517
+ if (!/[A-Za-z0-9]/.test(c)) {
1518
+ return invalidResult(
1519
+ input,
1520
+ ValidationErrorReason.InvalidFormat,
1521
+ "VAT number body contains invalid characters.",
1522
+ "Momsnumrets inneh\xE5ll har ogiltiga tecken."
1523
+ );
1524
+ }
1525
+ body += c.toUpperCase();
1526
+ }
1527
+ if (body.length === 0 || !validateCountryFormat(info.countryCode, body)) {
1528
+ return invalidResult(
1529
+ input,
1530
+ ValidationErrorReason.InvalidFormat,
1531
+ "VAT number format is invalid for the specified country.",
1532
+ "Momsnummerformatet \xE4r ogiltigt f\xF6r det angivna landet."
1533
+ );
1534
+ }
1535
+ return validResult(input);
1536
+ }
1537
+ toNormalizedString() {
1538
+ return this.vatPrefix + this.body;
1539
+ }
1540
+ toString() {
1541
+ return this.vatPrefix + this.body;
1542
+ }
1543
+ static findCandidatesInText(text) {
1544
+ if (!text) return [];
1545
+ const results = [];
1546
+ const re = /(?<![A-Z0-9])[A-Z]{2}[A-Z0-9]{5,14}(?![A-Z0-9])/gu;
1547
+ let match;
1548
+ while ((match = re.exec(text)) !== null) {
1549
+ const vat = _EuVatNumber.tryParse(match[0]);
1550
+ if (!vat) continue;
1551
+ results.push(
1552
+ new TextCandidate({
1553
+ startIndex: match.index,
1554
+ length: match[0].length,
1555
+ originalText: match[0],
1556
+ typeName: "EuVatNumber",
1557
+ category: TextCandidateCategory.OrganizationIdentifier,
1558
+ normalizedForm: vat.toNormalizedString(),
1559
+ formattedForm: vat.toString(),
1560
+ maskedForm: maskEuVatNumber(vat),
1561
+ confidence: TextMatchConfidence.High,
1562
+ value: vat
1563
+ })
1564
+ );
1565
+ }
1566
+ return results;
1567
+ }
1568
+ equals(other) {
1569
+ return other != null && this.vatPrefix === other.vatPrefix && this.body === other.body;
1570
+ }
1571
+ compareTo(other) {
1572
+ if (other == null) return 1;
1573
+ const a = this.toNormalizedString();
1574
+ const b = other.toNormalizedString();
1575
+ return a < b ? -1 : a > b ? 1 : 0;
1576
+ }
1577
+ };
1578
+ function validateCountryFormat(countryCode, body) {
1579
+ switch (countryCode.toUpperCase()) {
1580
+ case "AT":
1581
+ return body.length === 9 && body[0] === "U" && /^\d{8}$/.test(body.slice(1));
1582
+ case "BE":
1583
+ return validateBelgianVat(body);
1584
+ case "BG":
1585
+ return /^\d{9,10}$/.test(body);
1586
+ case "HR":
1587
+ return /^\d{11}$/.test(body) && validateMod1110(body);
1588
+ case "CY":
1589
+ return /^\d{8}[A-Z]$/.test(body);
1590
+ case "CZ":
1591
+ return /^\d{8,10}$/.test(body);
1592
+ case "DK":
1593
+ return /^\d{8}$/.test(body);
1594
+ case "EE":
1595
+ return /^\d{9}$/.test(body);
1596
+ case "FI":
1597
+ return validateFinnishVat(body);
1598
+ case "FR":
1599
+ return /^[A-Z0-9]{2}\d{9}$/.test(body);
1600
+ case "DE":
1601
+ case "GR":
1602
+ return /^\d{9}$/.test(body);
1603
+ case "HU":
1604
+ return /^\d{8}$/.test(body);
1605
+ case "IE":
1606
+ return validateIrishVat(body);
1607
+ case "IT":
1608
+ return /^\d{11}$/.test(body) && luhnIsValid(body);
1609
+ case "LV":
1610
+ return /^\d{11}$/.test(body);
1611
+ case "LT":
1612
+ return /^\d{9}$/.test(body) || /^\d{12}$/.test(body);
1613
+ case "LU":
1614
+ case "MT":
1615
+ return /^\d{8}$/.test(body);
1616
+ case "NL":
1617
+ return /^\d{9}B\d{2}$/.test(body);
1618
+ case "PL":
1619
+ return validatePolishVat(body);
1620
+ case "PT":
1621
+ return /^\d{9}$/.test(body);
1622
+ case "RO":
1623
+ return /^\d{2,10}$/.test(body);
1624
+ case "SK":
1625
+ return validateSlovakVat(body);
1626
+ case "SI":
1627
+ return /^\d{8}$/.test(body);
1628
+ case "ES":
1629
+ return body.length === 9;
1630
+ case "SE":
1631
+ return validateSwedishVat(body);
1632
+ case "GB":
1633
+ return validateUkVat(body);
1634
+ case "NO":
1635
+ return validateNorwegianVat(body);
1636
+ case "CH":
1637
+ return keepDigits(body).length === 9;
1638
+ default:
1639
+ return /\d/.test(body);
1640
+ }
1641
+ }
1642
+ function validateSwedishVat(body) {
1643
+ const digits = keepDigits(body);
1644
+ if (digits.length !== 12 || !digits.endsWith("01")) return false;
1645
+ return SwedishOrganizationNumber.tryParse(digits.slice(0, 10)) !== null;
1646
+ }
1647
+ function validateBelgianVat(body) {
1648
+ const digits = keepDigits(body);
1649
+ if (digits.length !== 10) return false;
1650
+ const baseNumber = parseInt(digits.slice(0, 8), 10);
1651
+ const checkDigits = 97 - baseNumber % 97;
1652
+ return checkDigits === parseInt(digits.slice(8, 10), 10);
1653
+ }
1654
+ function validateFinnishVat(body) {
1655
+ const digits = keepDigits(body);
1656
+ if (digits.length !== 8) return false;
1657
+ const weights = [7, 9, 10, 5, 8, 4, 2];
1658
+ const sum = weights.reduce((acc, weight, i) => acc + (digits.charCodeAt(i) - 48) * weight, 0);
1659
+ const remainder = sum % 11;
1660
+ if (remainder === 1) return false;
1661
+ const checkDigit = remainder === 0 ? 0 : 11 - remainder;
1662
+ return checkDigit === digits.charCodeAt(7) - 48;
1663
+ }
1664
+ function validateIrishVat(body) {
1665
+ if (body.length < 8 || body.length > 9) return false;
1666
+ if (body.length === 8) return /^\d{7}[A-Z]$/.test(body);
1667
+ return /^\d{7}[A-Z]{2}$/.test(body) || /^\d[A-Z]\d{5}[A-Z]$/.test(body);
1668
+ }
1669
+ function validatePolishVat(body) {
1670
+ const digits = keepDigits(body);
1671
+ if (digits.length !== 10) return false;
1672
+ const weights = [6, 5, 7, 2, 3, 4, 5, 6, 7];
1673
+ const sum = weights.reduce((acc, weight, i) => acc + (digits.charCodeAt(i) - 48) * weight, 0);
1674
+ const checkDigit = sum % 11;
1675
+ if (checkDigit === 10) return false;
1676
+ return checkDigit === digits.charCodeAt(9) - 48;
1677
+ }
1678
+ function validateSlovakVat(body) {
1679
+ const digits = keepDigits(body);
1680
+ if (digits.length !== 10) return false;
1681
+ return parseInt(digits, 10) % 11 === 0;
1682
+ }
1683
+ function validateUkVat(body) {
1684
+ const digits = keepDigits(body);
1685
+ if (body.startsWith("GD") || body.startsWith("HA")) return body.length >= 5;
1686
+ return digits.length === 9 || digits.length === 12;
1687
+ }
1688
+ function validateNorwegianVat(body) {
1689
+ const digits = keepDigits(body);
1690
+ if (digits.length !== 9) return false;
1691
+ const weights = [3, 2, 7, 6, 5, 4, 3, 2];
1692
+ const sum = weights.reduce((acc, weight, i) => acc + (digits.charCodeAt(i) - 48) * weight, 0);
1693
+ const remainder = 11 - sum % 11;
1694
+ if (remainder === 10) return false;
1695
+ const checkDigit = remainder === 11 ? 0 : remainder;
1696
+ return checkDigit === digits.charCodeAt(8) - 48;
1697
+ }
1698
+ function validateMod1110(digits) {
1699
+ let checksum = 10;
1700
+ for (let i = 0; i < digits.length - 1; i++) {
1701
+ const digit = digits.charCodeAt(i) - 48;
1702
+ checksum = (checksum + digit) % 10;
1703
+ if (checksum === 0) checksum = 10;
1704
+ checksum = checksum * 2 % 11;
1705
+ }
1706
+ const expectedCheck = (11 - checksum) % 10;
1707
+ const actualCheck = digits.charCodeAt(digits.length - 1) - 48;
1708
+ return expectedCheck === actualCheck;
1709
+ }
1710
+ function maskEuVatNumber(vat, alwaysMask = false) {
1711
+ if (vat.countryCode === "SE") {
1712
+ const body = vat.body;
1713
+ if (body.length >= 10) {
1714
+ const orgPart = body.slice(0, 10);
1715
+ const org = SwedishOrganizationNumber.tryParse(orgPart);
1716
+ if (org && (org.isPerson || alwaysMask)) {
1717
+ const suffix = body.length > 10 ? body.slice(10) : "";
1718
+ return `${vat.vatPrefix}${orgPart.slice(0, 6)}****${suffix}`;
1719
+ }
1720
+ }
1721
+ } else if (alwaysMask) {
1722
+ const visible = Math.min(4, vat.body.length);
1723
+ return `${vat.vatPrefix}${vat.body.slice(0, visible)}${"*".repeat(vat.body.length - visible)}`;
1724
+ }
1725
+ return vat.toString();
1726
+ }
1727
+
1728
+ // src/organization/lei-code.ts
1729
+ var MAX_INPUT_LENGTH7 = 30;
1730
+ var LeiCode = class _LeiCode {
1731
+ static typeInfo = Object.freeze({
1732
+ englishName: "LEI Code",
1733
+ localizedName: "LEI-kod",
1734
+ emoji: "\u{1F3DB}\uFE0F",
1735
+ sources: Object.freeze([
1736
+ "https://www.gleif.org/en/about-lei/iso-17442-the-lei-code-structure/",
1737
+ "https://en.wikipedia.org/wiki/Legal_Entity_Identifier"
1738
+ ])
1739
+ });
1740
+ value;
1741
+ get louPrefix() {
1742
+ return this.value.slice(0, 4);
1743
+ }
1744
+ get reserved() {
1745
+ return this.value.slice(4, 6);
1746
+ }
1747
+ get entitySpecific() {
1748
+ return this.value.slice(6, 18);
1749
+ }
1750
+ get checkDigits() {
1751
+ return this.value.slice(18, 20);
1752
+ }
1753
+ constructor(value) {
1754
+ this.value = value;
1755
+ }
1756
+ static tryParse(input) {
1757
+ if (input == null || input.trim() === "") return null;
1758
+ const source = sanitizeInput(input);
1759
+ let cleaned = "";
1760
+ for (const c of source) {
1761
+ if (/[A-Za-z0-9]/.test(c)) cleaned += c.toUpperCase();
1762
+ }
1763
+ if (cleaned.length > MAX_INPUT_LENGTH7 || cleaned.length !== 20) return null;
1764
+ if (!isValidIso7064Mod97(cleaned)) return null;
1765
+ return new _LeiCode(cleaned);
1766
+ }
1767
+ static parse(input) {
1768
+ const r = _LeiCode.tryParse(input);
1769
+ if (r === null) throw new Error("Invalid LEI code (length or checksum invalid).");
1770
+ return r;
1771
+ }
1772
+ static isValid(input) {
1773
+ return _LeiCode.tryParse(input) !== null;
1774
+ }
1775
+ static format(input, options) {
1776
+ const r = _LeiCode.tryParse(input);
1777
+ if (r) return r.value;
1778
+ if (options?.fallbackToTrimmedInputWhenInvalid && input != null && input.trim() !== "") {
1779
+ return input.trim();
1780
+ }
1781
+ return null;
1782
+ }
1783
+ static normalize(input, options) {
1784
+ return _LeiCode.format(input, options);
1785
+ }
1786
+ static isNormalized(input) {
1787
+ return input != null && _LeiCode.normalize(input) === input;
1788
+ }
1789
+ toNormalizedString() {
1790
+ return this.value;
1791
+ }
1792
+ toString() {
1793
+ return this.value;
1794
+ }
1795
+ static findCandidatesInText(text) {
1796
+ if (!text) return [];
1797
+ const out = [];
1798
+ const re = /(?<![A-Z0-9])[A-Z0-9]{18}\d{2}(?![A-Z0-9])/gu;
1799
+ let m;
1800
+ while ((m = re.exec(text)) !== null) {
1801
+ const r = _LeiCode.tryParse(m[0]);
1802
+ if (!r) continue;
1803
+ out.push(
1804
+ new TextCandidate({
1805
+ startIndex: m.index,
1806
+ length: m[0].length,
1807
+ originalText: m[0],
1808
+ typeName: "LeiCode",
1809
+ category: TextCandidateCategory.OrganizationIdentifier,
1810
+ normalizedForm: r.toNormalizedString(),
1811
+ formattedForm: r.toString(),
1812
+ maskedForm: maskLeiCode(r),
1813
+ confidence: TextMatchConfidence.High,
1814
+ value: r
1815
+ })
1816
+ );
1817
+ }
1818
+ return out;
1819
+ }
1820
+ equals(other) {
1821
+ return other != null && this.value === other.value;
1822
+ }
1823
+ compareTo(other) {
1824
+ if (other == null) return 1;
1825
+ return this.value < other.value ? -1 : this.value > other.value ? 1 : 0;
1826
+ }
1827
+ };
1828
+ function maskLeiCode(l) {
1829
+ const v = l.value;
1830
+ return v.slice(0, 4) + "*".repeat(v.length - 4);
1831
+ }
1832
+
1833
+ // src/organization/organization-extensions.ts
1834
+ function toSwedishOrganizationNumber(value) {
1835
+ if (value instanceof SwedishPersonalIdentityNumber || value instanceof SwedishCoordinationNumber) {
1836
+ return SwedishOrganizationNumber.parse(value.to12DigitString());
1837
+ }
1838
+ if (value.countryCode !== "SE") return null;
1839
+ const digits = keepDigits(value.body);
1840
+ if (digits.length !== 12 || !digits.endsWith("01")) return null;
1841
+ return SwedishOrganizationNumber.tryParse(digits.slice(0, 10));
1842
+ }
1843
+ function toPersonalIdentityNumber(value) {
1844
+ const org = value instanceof EuVatNumber ? toSwedishOrganizationNumber(value) : value;
1845
+ if (!org?.isPerson) return null;
1846
+ return SwedishPersonalIdentityNumber.tryParse(org.to12DigitString());
1847
+ }
1848
+ function toCoordinationNumber(value) {
1849
+ const org = value instanceof EuVatNumber ? toSwedishOrganizationNumber(value) : value;
1850
+ if (!org?.isPerson) return null;
1851
+ return SwedishCoordinationNumber.tryParse(org.to12DigitString());
1852
+ }
1853
+ function toEuVatNumber(value) {
1854
+ const digits = value instanceof SwedishOrganizationNumber ? value.to10DigitsOnly() : keepDigits(value.to10DigitString());
1855
+ return EuVatNumber.parse(`SE${digits}01`);
1856
+ }
1857
+ function getBolagsverketUrl(org) {
1858
+ return new URL(
1859
+ `https://foretagsinfo.bolagsverket.se/sok-foretagsinformation-web/foretag/${org.to10DigitString()}`
1860
+ );
1861
+ }
1862
+ function getAllabolagUrl(org) {
1863
+ return `https://www.allabolag.se/${org.toNormalizedString()}`;
1864
+ }
1865
+ function getAllabolagExternalUrl(org) {
1866
+ return new URL(`https://www.allabolag.se/${org.to10DigitsOnly()}`);
1867
+ }
1868
+ function toViesUrl(vat) {
1869
+ return `https://ec.europa.eu/taxation_customs/vies/#/vat-validation/${vat.toNormalizedString()}`;
1870
+ }
1871
+ function getGleifUrl(lei) {
1872
+ return new URL(`https://search.gleif.org/#/record/${lei.toNormalizedString()}`);
1873
+ }
1874
+ function toGleifUrl(lei) {
1875
+ return `https://search.gleif.org/#/record/${lei.toNormalizedString()}`;
1876
+ }
1877
+
1878
+ // src/organization/swedish-organization-identifier.ts
1879
+ var MAX_INPUT_LENGTH8 = 30;
1880
+ function unknownResult() {
1881
+ return {
1882
+ type: 0 /* Unknown */,
1883
+ organizationTypeHintCertain: 0 /* Unknown */,
1884
+ organizationTypeHintBestGuess: 0 /* Unknown */,
1885
+ normalizedValue: "",
1886
+ swedishOrganizationNumber: null,
1887
+ euVatNumber: null,
1888
+ dunsNumber: null,
1889
+ leiCode: null
1890
+ };
1891
+ }
1892
+ var SwedishOrganizationIdentifierParser = class _SwedishOrganizationIdentifierParser {
1893
+ static tryParse(input, options) {
1894
+ if (input == null || input.trim() === "") return null;
1895
+ const sanitized = sanitizeInput(input).trim();
1896
+ if (sanitized.length > MAX_INPUT_LENGTH8) return null;
1897
+ {
1898
+ const se = tryParseSwedishOrg(sanitized, options);
1899
+ if (se) return se;
1900
+ const vat = tryParseVat(sanitized, options);
1901
+ if (vat) return vat;
1902
+ }
1903
+ const duns = DunsNumber.tryParse(sanitized);
1904
+ if (duns) {
1905
+ return {
1906
+ ...unknownResult(),
1907
+ type: 20 /* DunsNumber */,
1908
+ normalizedValue: duns.digits,
1909
+ dunsNumber: duns
1910
+ };
1911
+ }
1912
+ const lei = LeiCode.tryParse(sanitized);
1913
+ if (lei) {
1914
+ return {
1915
+ ...unknownResult(),
1916
+ type: 30 /* LeiCode */,
1917
+ normalizedValue: lei.value,
1918
+ leiCode: lei
1919
+ };
1920
+ }
1921
+ return null;
1922
+ }
1923
+ static parse(input, options) {
1924
+ const r = _SwedishOrganizationIdentifierParser.tryParse(input, options);
1925
+ if (!r) throw new Error("Could not parse input as a known organization/identity number.");
1926
+ return r;
1927
+ }
1928
+ static tryParseForCountry(input, countryCode, options) {
1929
+ if (input == null || input.trim() === "" || countryCode == null || countryCode.trim() === "") {
1930
+ return null;
1931
+ }
1932
+ const normalizedCountryCode = countryCode.toUpperCase();
1933
+ if (normalizedCountryCode === "SE") {
1934
+ const seOrg = SwedishOrganizationNumber.tryParse(input);
1935
+ if (seOrg) return buildSwedishOrgResult(seOrg, options);
1936
+ }
1937
+ const vat = EuVatNumber.tryParseForCountry(input, normalizedCountryCode);
1938
+ if (vat) return buildVatResult(vat, options);
1939
+ return null;
1940
+ }
1941
+ static parseForCountry(input, countryCode, options) {
1942
+ const r = _SwedishOrganizationIdentifierParser.tryParseForCountry(input, countryCode, options);
1943
+ if (!r) {
1944
+ throw new Error(
1945
+ `Could not parse input as a known organization/identity number for country ${countryCode}.`
1946
+ );
1947
+ }
1948
+ return r;
1949
+ }
1950
+ };
1951
+ function tryParseSwedishOrg(input, options) {
1952
+ const seOrg = SwedishOrganizationNumber.tryParse(input);
1953
+ if (!seOrg) return null;
1954
+ return buildSwedishOrgResult(seOrg, options);
1955
+ }
1956
+ function buildSwedishOrgResult(seOrg, options) {
1957
+ let type = 1 /* SwedishOrganizationNumber */;
1958
+ if (seOrg.isPerson) {
1959
+ const twelve = seOrg.to12DigitString();
1960
+ if (SwedishPersonalIdentityNumber.tryParse(twelve)) {
1961
+ type = 2 /* SwedishPersonalIdentityNumber */;
1962
+ } else if (SwedishCoordinationNumber.tryParse(twelve)) {
1963
+ type = 3 /* SwedishCoordinationNumber */;
1964
+ }
1965
+ }
1966
+ const hint = seOrg.getSwedishOrganizationTypeHint(
1967
+ options?.organizationName ?? null,
1968
+ options?.isPrivatePerson ?? null
1969
+ );
1970
+ return {
1971
+ ...unknownResult(),
1972
+ type,
1973
+ organizationTypeHintCertain: hint.certain,
1974
+ organizationTypeHintBestGuess: hint.bestGuess,
1975
+ normalizedValue: seOrg.to12DigitString(),
1976
+ swedishOrganizationNumber: seOrg
1977
+ };
1978
+ }
1979
+ function tryParseVat(input, options) {
1980
+ const vat = EuVatNumber.tryParse(input);
1981
+ if (!vat) return null;
1982
+ return buildVatResult(vat, options);
1983
+ }
1984
+ function buildVatResult(vat, options) {
1985
+ let certain = 0 /* Unknown */;
1986
+ let bestGuess = 0 /* Unknown */;
1987
+ const seOrg = toSwedishOrganizationNumber(vat);
1988
+ if (seOrg) {
1989
+ const hint = seOrg.getSwedishOrganizationTypeHint(
1990
+ options?.organizationName ?? null,
1991
+ options?.isPrivatePerson ?? null
1992
+ );
1993
+ certain = hint.certain;
1994
+ bestGuess = hint.bestGuess;
1995
+ }
1996
+ return {
1997
+ ...unknownResult(),
1998
+ type: 10 /* EuVatNumber */,
1999
+ organizationTypeHintCertain: certain,
2000
+ organizationTypeHintBestGuess: bestGuess,
2001
+ normalizedValue: vat.countryCode + vat.body,
2002
+ euVatNumber: vat
2003
+ };
2004
+ }
2005
+
2006
+ // src/organization/eu-organization-name.ts
2007
+ var MAX_INPUT_LENGTH9 = 300;
2008
+ var COMPANY_NAME_PATTERN2 = /^[\p{L}\d\s\-'&.,/:()+|"]+$/u;
2009
+ var PIPE_SEPARATOR = /\s*\|+\s*/;
2010
+ var EuOrganizationName = class _EuOrganizationName {
2011
+ static typeInfo = Object.freeze({
2012
+ englishName: "EU Organization Name",
2013
+ localizedName: "Europeiskt organisationsnamn",
2014
+ emoji: "\u{1F1EA}\u{1F1FA}",
2015
+ sources: Object.freeze([
2016
+ "https://ec.europa.eu/taxation_customs/vies/",
2017
+ "https://www.businessregisters.eu/"
2018
+ ])
2019
+ });
2020
+ value;
2021
+ legalName;
2022
+ tradeName;
2023
+ get hasTradeName() {
2024
+ return this.tradeName !== null;
2025
+ }
2026
+ constructor(value, legal, trade) {
2027
+ this.value = value;
2028
+ this.legalName = legal;
2029
+ this.tradeName = trade;
2030
+ }
2031
+ static tryParse(input) {
2032
+ const normalized = collapseWhitespace(input);
2033
+ if (normalized.length === 0 || normalized.length > MAX_INPUT_LENGTH9) return null;
2034
+ if (!validate(normalized)) return null;
2035
+ const [legal, trade] = splitLegalAndTrade(normalized);
2036
+ return new _EuOrganizationName(normalized, legal, trade);
2037
+ }
2038
+ static parse(input) {
2039
+ const r = _EuOrganizationName.tryParse(input);
2040
+ if (r === null) throw new Error("Invalid EU organization name.");
2041
+ return r;
2042
+ }
2043
+ static isValid(input) {
2044
+ return _EuOrganizationName.tryParse(input) !== null;
2045
+ }
2046
+ static format(input, options) {
2047
+ const r = _EuOrganizationName.tryParse(input);
2048
+ if (r) return r.value;
2049
+ if (options?.fallbackToTrimmedInputWhenInvalid && input != null && input.trim() !== "") {
2050
+ return input.trim();
2051
+ }
2052
+ return null;
2053
+ }
2054
+ static normalize(input, options) {
2055
+ return _EuOrganizationName.format(input, options);
2056
+ }
2057
+ static isNormalized(input) {
2058
+ return input != null && _EuOrganizationName.normalize(input) === input;
2059
+ }
2060
+ static trySplitLegalAndTrade(input) {
2061
+ if (input == null || input.trim() === "") return null;
2062
+ const collapsed = collapseWhitespace(input);
2063
+ const [legal, trade] = splitLegalAndTrade(collapsed);
2064
+ return { legalName: legal, tradeName: trade };
2065
+ }
2066
+ toNormalizedString() {
2067
+ return this.value;
2068
+ }
2069
+ toString() {
2070
+ return this.value;
2071
+ }
2072
+ equals(other) {
2073
+ return other != null && this.value === other.value;
2074
+ }
2075
+ compareTo(other) {
2076
+ if (other == null) return 1;
2077
+ return this.value < other.value ? -1 : this.value > other.value ? 1 : 0;
2078
+ }
2079
+ };
2080
+ function maskEuOrganizationName(value) {
2081
+ return value.value.replace(/[\p{L}\d]+/gu, (part) => {
2082
+ if (part.length <= 1) return part;
2083
+ return part[0] + "*".repeat(part.length - 1);
2084
+ });
2085
+ }
2086
+ function splitLegalAndTrade(collapsed) {
2087
+ if (collapsed.indexOf("|") < 0) return [collapsed, null];
2088
+ const parts = collapsed.split(PIPE_SEPARATOR).filter((p) => p.length > 0);
2089
+ if (parts.length < 2) return [collapsed, null];
2090
+ return [parts[0], parts.slice(1).join(" | ")];
2091
+ }
2092
+ function validate(value) {
2093
+ if (value.length < 2 || value.length > 200) return false;
2094
+ for (const c of value) {
2095
+ const code = c.charCodeAt(0);
2096
+ if (code < 32 || code === 127) return false;
2097
+ }
2098
+ return COMPANY_NAME_PATTERN2.test(value);
2099
+ }
2100
+
2101
+ // src/organization/elf-code.ts
2102
+ var CODE_LENGTH = 4;
2103
+ var MAX_INPUT_LENGTH10 = 20;
2104
+ var KNOWN_CODES = /* @__PURE__ */ new Map([
2105
+ ["XTIQ", { englishName: "Limited company", swedishName: "Aktiebolag" }],
2106
+ ["N2GY", { englishName: "General partnership", swedishName: "Handelsbolag" }],
2107
+ ["FR3V", { englishName: "Limited partnership", swedishName: "Kommanditbolag" }],
2108
+ ["V2YH", { englishName: "Economic association", swedishName: "Ekonomisk f\xF6rening" }],
2109
+ ["WJEL", { englishName: "Sole proprietorship", swedishName: "Enskild n\xE4ringsidkare" }],
2110
+ ["CLBQ", { englishName: "Foundation", swedishName: "Stiftelse" }],
2111
+ ["F85L", { englishName: "Non-profit association", swedishName: "Ideell f\xF6rening" }],
2112
+ ["O9FH", { englishName: "Housing cooperative", swedishName: "Bostadsr\xE4ttsf\xF6rening" }],
2113
+ [
2114
+ "H0PO",
2115
+ {
2116
+ englishName: "Cooperative housing association",
2117
+ swedishName: "Kooperativ hyresr\xE4ttsf\xF6rening"
2118
+ }
2119
+ ],
2120
+ ["2HBR", { englishName: "Government entity", swedishName: "Statlig enhet" }],
2121
+ ["EVKQ", { englishName: "Municipality", swedishName: "Kommun" }],
2122
+ ["R7GX", { englishName: "Region", swedishName: "Region" }],
2123
+ ["KQM9", { englishName: "Banking company", swedishName: "Bankaktiebolag" }],
2124
+ ["L5CF", { englishName: "Insurance company", swedishName: "F\xF6rs\xE4kringsaktiebolag" }],
2125
+ ["LRQE", { englishName: "Mutual insurance company", swedishName: "\xD6msesidigt f\xF6rs\xE4kringsbolag" }],
2126
+ [
2127
+ "J4GF",
2128
+ { englishName: "Branch of foreign company", swedishName: "Filial till utl\xE4ndskt f\xF6retag" }
2129
+ ],
2130
+ ["9GQP", { englishName: "European company (SE)", swedishName: "Europabolag" }]
2131
+ ]);
2132
+ var ElfCode = class _ElfCode {
2133
+ static typeInfo = Object.freeze({
2134
+ englishName: "Entity Legal Form Code",
2135
+ localizedName: "Juridisk f\xF6retagsform",
2136
+ emoji: "\u{1F4CB}",
2137
+ sources: Object.freeze([
2138
+ "https://www.gleif.org/en/about-lei/code-lists/iso-20275-entity-legal-forms-code-list",
2139
+ "https://www.iso.org/standard/67462.html"
2140
+ ])
2141
+ });
2142
+ code;
2143
+ englishName;
2144
+ localizedName;
2145
+ get displayName() {
2146
+ const localized = PrimitivesDefaults.useLocalizedDisplayNames ? this.localizedName : this.englishName;
2147
+ return localized ?? this.code;
2148
+ }
2149
+ get isKnown() {
2150
+ return this.englishName !== null;
2151
+ }
2152
+ constructor(code, en, sv) {
2153
+ this.code = code;
2154
+ this.englishName = en;
2155
+ this.localizedName = sv;
2156
+ }
2157
+ static tryParse(input) {
2158
+ if (input == null || input.trim() === "") return null;
2159
+ const cleaned = keepAsciiAlphanumericUppercase(input);
2160
+ if (cleaned.length > MAX_INPUT_LENGTH10 || cleaned.length !== CODE_LENGTH) return null;
2161
+ const known = KNOWN_CODES.get(cleaned);
2162
+ return new _ElfCode(cleaned, known?.englishName ?? null, known?.swedishName ?? null);
2163
+ }
2164
+ static parse(input) {
2165
+ const r = _ElfCode.tryParse(input);
2166
+ if (r === null) {
2167
+ throw new Error("Invalid ELF code (must be exactly 4 alphanumeric characters).");
2168
+ }
2169
+ return r;
2170
+ }
2171
+ static isValid(input) {
2172
+ return _ElfCode.tryParse(input) !== null;
2173
+ }
2174
+ static format(input, options) {
2175
+ const r = _ElfCode.tryParse(input);
2176
+ if (r) return r.displayName;
2177
+ if (options?.fallbackToTrimmedInputWhenInvalid && input != null && input.trim() !== "") {
2178
+ return input.trim();
2179
+ }
2180
+ return null;
2181
+ }
2182
+ static normalize(input, options) {
2183
+ const r = _ElfCode.tryParse(input);
2184
+ if (r) return r.code;
2185
+ if (options?.fallbackToTrimmedInputWhenInvalid && input != null) {
2186
+ const t = input.trim();
2187
+ return t.length > 0 ? t : null;
2188
+ }
2189
+ return null;
2190
+ }
2191
+ static isNormalized(input) {
2192
+ return input != null && _ElfCode.normalize(input) === input;
2193
+ }
2194
+ toNormalizedString() {
2195
+ return this.code;
2196
+ }
2197
+ toString() {
2198
+ return this.displayName;
2199
+ }
2200
+ equals(other) {
2201
+ return other != null && this.code === other.code;
2202
+ }
2203
+ compareTo(other) {
2204
+ if (other == null) return 1;
2205
+ return this.code < other.code ? -1 : this.code > other.code ? 1 : 0;
2206
+ }
2207
+ };
2208
+
2209
+ // src/organization/swedish-cfar-number.ts
2210
+ var MAX_INPUT_LENGTH11 = 20;
2211
+ var SwedishCfarNumber = class _SwedishCfarNumber {
2212
+ static typeInfo = Object.freeze({
2213
+ englishName: "CFAR Number",
2214
+ localizedName: "CFAR-nummer",
2215
+ emoji: "\u{1F3ED}",
2216
+ sources: Object.freeze([
2217
+ "https://www.cfarnrsok.scb.se/",
2218
+ "https://www.scb.se/vara-tjanster/bestall-data-och-statistik/foretagsregistret/variabelbeskrivning/"
2219
+ ])
2220
+ });
2221
+ number;
2222
+ constructor(n) {
2223
+ this.number = n;
2224
+ }
2225
+ static tryParse(input) {
2226
+ if (input == null || input.trim() === "") return null;
2227
+ const digits = keepDigits(sanitizeInput(input));
2228
+ if (digits.length > MAX_INPUT_LENGTH11) return null;
2229
+ if (digits.length !== 8) return null;
2230
+ if (digits === "00000000") return null;
2231
+ return new _SwedishCfarNumber(digits);
2232
+ }
2233
+ static parse(input) {
2234
+ const r = _SwedishCfarNumber.tryParse(input);
2235
+ if (r === null) throw new Error("Invalid CFAR number.");
2236
+ return r;
2237
+ }
2238
+ static isValid(input) {
2239
+ return _SwedishCfarNumber.tryParse(input) !== null;
2240
+ }
2241
+ static format(input, options) {
2242
+ const r = _SwedishCfarNumber.tryParse(input);
2243
+ if (r) return r.number;
2244
+ if (options?.fallbackToTrimmedInputWhenInvalid && input != null && input.trim() !== "") {
2245
+ return input.trim();
2246
+ }
2247
+ return null;
2248
+ }
2249
+ static normalize(input, options) {
2250
+ return _SwedishCfarNumber.format(input, options);
2251
+ }
2252
+ static isNormalized(input) {
2253
+ return input != null && _SwedishCfarNumber.normalize(input) === input;
2254
+ }
2255
+ toNormalizedString() {
2256
+ return this.number;
2257
+ }
2258
+ toString() {
2259
+ return this.number;
2260
+ }
2261
+ equals(other) {
2262
+ return other != null && this.number === other.number;
2263
+ }
2264
+ compareTo(other) {
2265
+ if (other == null) return 1;
2266
+ return this.number < other.number ? -1 : this.number > other.number ? 1 : 0;
2267
+ }
2268
+ };
2269
+ function maskSwedishCfarNumber(c) {
2270
+ return c.number.slice(0, 4) + "****";
2271
+ }
2272
+
2273
+ // src/organization/swedish-sni-code.ts
2274
+ var MAX_INPUT_LENGTH12 = 20;
2275
+ var SwedishSniCode = class _SwedishSniCode {
2276
+ static typeInfo = Object.freeze({
2277
+ englishName: "SNI Code",
2278
+ localizedName: "SNI-kod",
2279
+ emoji: "\u{1F4CA}",
2280
+ sources: Object.freeze([
2281
+ "https://www.scb.se/en/documentation/classifications-and-standards/swedish-standard-industrial-classification-sni/",
2282
+ "https://snisok.scb.se/en"
2283
+ ])
2284
+ });
2285
+ code;
2286
+ formatted;
2287
+ get divisionCode() {
2288
+ return this.code.slice(0, 2);
2289
+ }
2290
+ get groupCode() {
2291
+ return this.code.slice(0, 3);
2292
+ }
2293
+ get subGroupCode() {
2294
+ return this.code.slice(0, 4);
2295
+ }
2296
+ constructor(code, formatted) {
2297
+ this.code = code;
2298
+ this.formatted = formatted;
2299
+ }
2300
+ static tryParse(input) {
2301
+ if (input == null || input.trim() === "") return null;
2302
+ const digits = keepDigits(input);
2303
+ if (digits.length > MAX_INPUT_LENGTH12) return null;
2304
+ if (digits.length !== 5) return null;
2305
+ if (digits === "00000") return null;
2306
+ if (digits.slice(0, 2) === "00") return null;
2307
+ return new _SwedishSniCode(digits, `${digits.slice(0, 2)}.${digits.slice(2)}`);
2308
+ }
2309
+ static parse(input) {
2310
+ const r = _SwedishSniCode.tryParse(input);
2311
+ if (r === null) throw new Error("Invalid SNI code.");
2312
+ return r;
2313
+ }
2314
+ static isValid(input) {
2315
+ return _SwedishSniCode.tryParse(input) !== null;
2316
+ }
2317
+ static format(input, options) {
2318
+ const r = _SwedishSniCode.tryParse(input);
2319
+ if (r) return r.formatted;
2320
+ if (options?.fallbackToTrimmedInputWhenInvalid && input != null && input.trim() !== "") {
2321
+ return input.trim();
2322
+ }
2323
+ return null;
2324
+ }
2325
+ static normalize(input, options) {
2326
+ return _SwedishSniCode.format(input, options);
2327
+ }
2328
+ static isNormalized(input) {
2329
+ return input != null && _SwedishSniCode.normalize(input) === input;
2330
+ }
2331
+ toNormalizedString() {
2332
+ return this.formatted;
2333
+ }
2334
+ toString() {
2335
+ return this.formatted;
2336
+ }
2337
+ equals(other) {
2338
+ return other != null && this.formatted === other.formatted;
2339
+ }
2340
+ compareTo(other) {
2341
+ if (other == null) return 1;
2342
+ return this.formatted < other.formatted ? -1 : this.formatted > other.formatted ? 1 : 0;
2343
+ }
2344
+ };
2345
+
2346
+ exports.DunsNumber = DunsNumber;
2347
+ exports.ElfCode = ElfCode;
2348
+ exports.EuOrganizationName = EuOrganizationName;
2349
+ exports.EuVatNumber = EuVatNumber;
2350
+ exports.LeiCode = LeiCode;
2351
+ exports.SwedishCfarNumber = SwedishCfarNumber;
2352
+ exports.SwedishOrganizationIdentifierParser = SwedishOrganizationIdentifierParser;
2353
+ exports.SwedishOrganizationIdentifierType = SwedishOrganizationIdentifierType;
2354
+ exports.SwedishOrganizationName = SwedishOrganizationName;
2355
+ exports.SwedishOrganizationNumber = SwedishOrganizationNumber;
2356
+ exports.SwedishOrganizationType = SwedishOrganizationType;
2357
+ exports.SwedishSniCode = SwedishSniCode;
2358
+ exports.getAllabolagExternalUrl = getAllabolagExternalUrl;
2359
+ exports.getAllabolagUrl = getAllabolagUrl;
2360
+ exports.getBolagsverketUrl = getBolagsverketUrl;
2361
+ exports.getGleifUrl = getGleifUrl;
2362
+ exports.maskDunsNumber = maskDunsNumber;
2363
+ exports.maskEuOrganizationName = maskEuOrganizationName;
2364
+ exports.maskEuVatNumber = maskEuVatNumber;
2365
+ exports.maskLeiCode = maskLeiCode;
2366
+ exports.maskSwedishCfarNumber = maskSwedishCfarNumber;
2367
+ exports.maskSwedishOrganizationName = maskSwedishOrganizationName;
2368
+ exports.maskSwedishOrganizationNumber = maskSwedishOrganizationNumber;
2369
+ exports.toCoordinationNumber = toCoordinationNumber;
2370
+ exports.toEuVatNumber = toEuVatNumber;
2371
+ exports.toGleifUrl = toGleifUrl;
2372
+ exports.toPersonalIdentityNumber = toPersonalIdentityNumber;
2373
+ exports.toSwedishOrganizationNumber = toSwedishOrganizationNumber;
2374
+ exports.toViesUrl = toViesUrl;
2375
+ //# sourceMappingURL=index.cjs.map
2376
+ //# sourceMappingURL=index.cjs.map