@desource/phone-mask-vue 0.2.3 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,17 @@
1
1
  # @desource/phone-mask-vue
2
2
 
3
+ ## 0.3.0
4
+
5
+ ### Minor Changes
6
+
7
+ - React: Design React version of phone-mask library
8
+ - Core: Add geoip reusable service for country detection based on IP address
9
+
10
+ ### Patch Changes
11
+
12
+ - Updated dependencies []:
13
+ - @desource/phone-mask@0.3.0
14
+
3
15
  ## 0.2.3
4
16
 
5
17
  ### Patch Changes
package/LICENSE CHANGED
@@ -1,6 +1,6 @@
1
1
  MIT License
2
2
 
3
- Copyright (c) 2025 DeSource Labs
3
+ Copyright (c) 2026 DeSource Labs
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
package/README.md CHANGED
@@ -541,7 +541,7 @@ const form = reactive({
541
541
 
542
542
  ## 📄 License
543
543
 
544
- [MIT](../../LICENSE) © 2025 DeSource Labs
544
+ [MIT](../../LICENSE) © 2026 DeSource Labs
545
545
 
546
546
  ## 🤝 Contributing
547
547
 
package/dist/index.cjs CHANGED
@@ -2,66 +2,76 @@
2
2
  Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toStringTag]: { value: "Module" } });
3
3
  const vue = require("vue");
4
4
  const M = { AC: "+247 #####", AD: ["+376 ### ###", "+376 #### ####"], AE: ["+971 # ### ####", "+971 ## ### ####", "+971 ### ######", "+971 ### # #####"], AF: "+93 ## ### ####", AG: "+1 ###-###-####", AI: "+1 ###-###-####", AL: ["+355 ## ### ###", "+355 ## ### ####", "+355 ### ####", "+355 ### ###", "+355 ### #####"], AM: ["+374 ## ######", "+374 ### ## ###"], AO: "+244 ### ### ###", AR: ["+54 ## ####-####", "+54 # ## ####-####", "+54 ###-###-####"], AS: "+1 ###-###-####", AT: ["+43 # #########", "+43 ### ######"], AU: ["+61 # #### ####", "+61 ### ### ###", "+61 #### ### ###", "+61 ## ### ##"], AW: "+297 ### ####", AX: ["+358 ## #######", "+358 ### ######"], AZ: ["+994 ## ### ## ##", "+994 ### ## ## ##"], BA: ["+387 ## ###-###", "+387 ## ### ###"], BB: "+1 ###-###-####", BD: ["+880 #-#######", "+880 ####-######", "+880 ###-#######"], BE: ["+32 ## ## ## ##", "+32 ### ## ## ##", "+32 ### ## ###"], BF: "+226 ## ## ## ##", BG: ["+359 # ### ###", "+359 ## ### ###", "+359 ### ## ###"], BH: "+973 #### ####", BI: "+257 ## ## ## ##", BJ: ["+229 ## ## ## ## ##", "+229 ## ## ## ##"], BL: "+590 ### ## ## ##", BM: "+1 ###-###-####", BN: "+673 ### ####", BO: ["+591 # #######", "+591 ########", "+591 ### ## ####"], BQ: "+599 ### ####", BR: ["+55 ## ####-####", "+55 ## #####-####", "+55 ### ## ####", "+55 ####-####"], BS: "+1 ###-###-####", BT: ["+975 # ### ###", "+975 ## ## ## ##"], BW: ["+267 ### ####", "+267 ## ### ###", "+267 #### ### ###", "+267 ## #####"], BY: ["+375 ### ##-##-##", "+375 ## ###-##-##", "+375 ### ### ####"], BZ: ["+501 ###-####", "+501 #-###-####-###"], CA: "+1 ###-###-####", CC: ["+61 # #### ####", "+61 ### ### ###", "+61 #### ### ###"], CD: ["+243 ## #####", "+243 ### ### ###"], CF: "+236 ## ## ## ##", CG: ["+242 ## ### ####", "+242 # #### ####"], CH: ["+41 ## ### ## ##", "+41 ### ### ###"], CI: ["+225 ## ## # #####", "+225 ## ## ## ####"], CK: "+682 ## ###", CL: ["+56 ### ### ###", "+56 # #### ####", "+56 ### ### ####", "+56 ## ### ####"], CM: ["+237 # ## ## ## ##", "+237 ## ## ## ##"], CN: ["+86 ## #### ####", "+86 ### #### ####", "+86 ### ### ####", "+86 ########"], CO: ["+57 ### #######", "+57 # ### #######"], CR: ["+506 #### ####", "+506 ###-###-####"], CU: ["+53 # #######", "+53 ### #######"], CV: "+238 ### ## ##", CW: ["+599 # ### ####", "+599 ### ####"], CX: ["+61 # #### ####", "+61 ### ### ###", "+61 #### ### ###"], CY: "+357 ## ######", CZ: "+420 ### ### ###", DE: ["+49 ## ######", "+49 #### #######", "+49 ### ##########", "+49 ### # ######", "+49 ### # ####", "+49 ### #### ####", "+49 ########"], DJ: "+253 ## ## ## ##", DK: "+45 ## ## ## ##", DM: "+1 ###-###-####", DO: "+1 ###-###-####", DZ: ["+213 ## ## ## ##", "+213 ### ## ## ##", "+213 ## ### ## ##"], EC: ["+593 #-###-####", "+593 ## ### ####", "+593 #### ### ####"], EE: ["+372 ### ####", "+372 #### ####", "+372 ## ## ####"], EG: ["+20 # ########", "+20 ## ########", "+20 ### ### ####"], EH: ["+212 # ## ## ## ##", "+212 ##-#######"], ER: "+291 # ### ###", ES: ["+34 ### ## ## ##", "+34 ### ### ###"], ET: "+251 ## ### ####", FI: ["+358 ## #######", "+358 ### ######"], FJ: ["+679 ### ####", "+679 #### ### ####"], FK: "+500 #####", FM: "+691 ### ####", FO: "+298 ######", FR: ["+33 # ## ## ## ##", "+33 ### ## ## ##"], GA: "+241 ## ## ## ##", GB: ["+44 ### ### ####", "+44 #### ######", "+44 ## #### ####"], GD: "+1 ###-###-####", GE: ["+995 ## ### ## ##", "+995 ### ## ## ##", "+995 ### ### ###"], GF: "+594 ### ## ## ##", GG: ["+44 #### ######", "+44 ### ### ####", "+44 ## #### ####"], GH: ["+233 ## ### ####", "+233 ### #####"], GI: ["+350 ### #####", "+350 ########"], GL: "+299 ## ## ##", GM: "+220 ### ####", GN: ["+224 ## ## ## ##", "+224 ### ## ## ##"], GP: "+590 ### ## ## ##", GQ: ["+240 ### ### ###", "+240 ### ######"], GR: ["+30 ## #### ####", "+30 ### ### ####"], GT: ["+502 #### ####", "+502 #### ### ####"], GU: "+1 ###-###-####", GW: ["+245 ### ### ###", "+245 ### ####"], GY: "+592 ### ####", HK: ["+852 #### ####", "+852 ### ### ###", "+852 ### ## ### ###"], HN: ["+504 ####-####", "+504 ###########"], HR: ["+385 # #### ###", "+385 ## ### ####", "+385 ### ### ###", "+385 ## ## ###", "+385 ## ### ###"], HT: "+509 ## ## ####", HU: ["+36 # ### ####", "+36 ## ### ####", "+36 ## ### ###"], ID: ["+62 ## #######", "+62 ###-###-###", "+62 ### #######", "+62 ### # ### ###", "+62 ### ### ####"], IE: ["+353 ## #####", "+353 ## ### ####", "+353 #### ### ###", "+353 ### ### ###"], IL: ["+972 #-###-####", "+972 ##-###-####", "+972 #-###-###-###"], IM: ["+44 #### ######", "+44 ### ### ####", "+44 ## #### ####"], IN: ["+91 ##### #####", "+91 #### ## ####", "+91 #### ### ### ###", "+91 #### ### ####"], IO: "+246 ### ####", IQ: ["+964 # ### ####", "+964 ### ### ####"], IR: ["+98 ## #### ####", "+98 ### ### ####"], IS: "+354 ### ####", IT: ["+39 ## #### ####", "+39 ### ### ####", "+39 ### ### ###"], JE: ["+44 #### ######", "+44 ### ### ####", "+44 ## #### ####"], JM: "+1 ###-###-####", JO: ["+962 # ### ####", "+962 # #### ####", "+962 ### #####", "+962 ## #######"], JP: ["+81 #-####-####", "+81 ##-####-####", "+81 ###-###-###", "+81 ##-###-####"], KE: ["+254 ## #######", "+254 ### ######", "+254 ### ### ###"], KG: ["+996 ### ### ###", "+996 ### ### # ##"], KH: ["+855 ## ### ###", "+855 #### ### ###"], KI: ["+686 #####", "+686 ########"], KM: "+269 ### ## ##", KN: "+1 ###-###-####", KP: ["+850 # ### ####", "+850 ### ### ####"], KR: ["+82 #-###-####", "+82 ##-####-####", "+82 ##-###-####"], KW: ["+965 #### ####", "+965 ### #####", "+965 #### ###"], KY: "+1 ###-###-####", KZ: ["+7 ##### # ## ##", "+7 ### ### ####", "+7 ### ###-##-##"], LA: ["+856 ## ### ###", "+856 ## ## ### ###"], LB: ["+961 # ### ###", "+961 ## ### ###"], LC: "+1 ###-###-####", LI: ["+423 ### ## ##", "+423 ### ### ###"], LK: ["+94 ### ### ###", "+94 ## ### ####"], LR: ["+231 ## ### ###", "+231 ## ### ####"], LS: "+266 #### ####", LT: ["+370 ### #####", "+370 ### ## ###"], LU: ["+352 ## ## ## ##", "+352 ### ### ###", "+352 ### ## ###"], LV: "+371 ## ### ###", LY: "+218 ##-#######", MA: ["+212 # ## ## ## ##", "+212 ##-#######"], MC: ["+377 ## ## ## ##", "+377 # ## ## ## ##"], MD: ["+373 ## ### ###", "+373 ### ## ###", "+373 ### #####"], ME: "+382 ## ### ###", MF: "+590 ### ## ## ##", MG: "+261 ## ## ### ##", MH: "+692 ###-####", MK: ["+389 # ### ####", "+389 ## ### ###", "+389 ### # ## ##"], ML: "+223 ## ## ## ##", MM: ["+95 # ### ###", "+95 # ### ####", "+95 ### ### ####"], MN: "+976 #### ####", MO: ["+853 #### ####", "+853 #### ###"], MP: "+1 ###-###-####", MQ: "+596 ### ## ## ##", MR: "+222 ## ## ## ##", MS: "+1 ###-###-####", MT: "+356 #### ####", MU: ["+230 #### ####", "+230 ### ####"], MV: ["+960 ###-####", "+960 ### ### ####"], MW: ["+265 # ### ###", "+265 ### ## ## ##"], MX: "+52 ### ### ####", MY: ["+60 #-#### ####", "+60 ##-### ####", "+60 #-###-##-####", "+60 ###-### ####"], MZ: ["+258 ## ### ###", "+258 ## ### ####", "+258 ### ### ###"], NA: ["+264 ## ### ###", "+264 ## ### ####", "+264 ### ### ###"], NC: "+687 ##.##.##", NE: ["+227 ## ## ## ##", "+227 ## ### ###"], NF: ["+672 ## ####", "+672 # #####"], NG: ["+234 #### ## ####", "+234 ### ### ####", "+234 ### #### ####"], NI: "+505 #### ####", NL: ["+31 ## ### ####", "+31 # ########", "+31 ### ####", "+31 ## #######"], NO: ["+47 ## ## ## ##", "+47 ### ## ###"], NP: ["+977 #-#######", "+977 ###-#######", "+977 ###########"], NR: "+674 ### ####", NU: ["+683 ####", "+683 ### ####"], NZ: ["+64 # ### ####", "+64 ## ### ####", "+64 ### ### ###"], OM: ["+968 ## ######", "+968 #### ####", "+968 ### #####"], PA: ["+507 ###-####", "+507 ####-####"], PE: ["+51 # #######", "+51 ### ### ###", "+51 ### #####"], PF: ["+689 ## ## ## ##", "+689 ### ## ## ##"], PG: ["+675 ### ####", "+675 #### ####"], PH: ["+63 # #### ####", "+63 ### ### ####", "+63 #### # ### ####"], PK: ["+92 ## ########", "+92 ### #######", "+92 ### ### ##", "+92 #### #####"], PL: ["+48 ## ### ## ##", "+48 ### ### ###"], PM: ["+508 ## ## ##", "+508 ### ## ## ##"], PR: "+1 ###-###-####", PS: ["+970 # ### ####", "+970 ### ### ###", "+970 #### ### ###"], PT: ["+351 ## ### ####", "+351 ### ### ###"], PW: "+680 ### ####", PY: ["+595 ## ### ####", "+595 ### ######", "+595 #### ### ####"], QA: ["+974 #### ####", "+974 ### ####"], RE: "+262 ### ## ## ##", RO: ["+40 ## ### ####", "+40 ### ### ###"], RS: ["+381 ## ######", "+381 ## #######", "+381 ### #####"], RU: "+7 ### ###-##-##", RW: "+250 ### ### ###", SA: ["+966 ## ### ####", "+966 ### ### ####", "+966 #### #####"], SB: ["+677 #####", "+677 ## #####"], SC: ["+248 # ### ###", "+248 #######"], SD: "+249 ## ### ####", SE: ["+46 # ## ## ##", "+46 ## ### ## ##", "+46 ## ## ## ##", "+46 ### ## ## ###"], SG: ["+65 #### ####", "+65 #### ### ####"], SH: "+290 #####", SI: ["+386 # ### ## ##", "+386 ## ### ###", "+386 ## ######", "+386 ### #####"], SJ: ["+47 ## ## ## ##", "+47 ### ## ###"], SK: ["+421 #/### ### ##", "+421 ### ### ###", "+421 #######"], SL: "+232 ## ######", SM: ["+378 #### ######", "+378 ## ## ## ##"], SN: ["+221 ## ### ## ##", "+221 ### ## ## ##"], SO: ["+252 # ######", "+252 # #######"], SR: ["+597 ###-###", "+597 ###-####", "+597 ##-##-##"], SS: "+211 ### ### ###", ST: "+239 ### ####", SV: ["+503 #### ####", "+503 ### ####"], SX: "+1 ###-###-####", SY: ["+963 ## ### ####", "+963 ### ### ###"], SZ: ["+268 #### ####", "+268 ##### ####"], TA: "+290 ####", TC: "+1 ###-###-####", TD: "+235 ## ## ## ##", TG: "+228 ## ## ## ##", TH: ["+66 # ### ####", "+66 ## ### ####", "+66 #### ### ###"], TJ: ["+992 ### ## ####", "+992 ## ### ####"], TK: "+690 ####", TL: ["+670 ### ####", "+670 #### ####"], TM: ["+993 ## ##-##-##", "+993 ## ######"], TN: "+216 ## ### ###", TO: ["+676 ##-###", "+676 ### ####", "+676 #### ###"], TR: ["+90 ### ### ## ##", "+90 ### ### ####"], TT: "+1 ###-###-####", TV: ["+688 ## ###", "+688 ## ####"], TW: ["+886 # #### ####", "+886 ### ### ###", "+886 ## ### ####", "+886 ## #### ####"], TZ: ["+255 ## ### ####", "+255 ### ### ###", "+255 ### ## ####"], UA: ["+380 #### #####", "+380 ## ### ####", "+380 ### ### ###"], UG: ["+256 ## #######", "+256 ### ######"], US: "+1 ###-###-####", UY: ["+598 #### ####", "+598 ## ### ###", "+598 ### ####"], UZ: "+998 ## ### ## ##", VA: ["+39 ## #### ####", "+39 ### ### ####", "+39 ### ### ###"], VC: "+1 ###-###-####", VE: "+58 ###-#######", VG: "+1 ###-###-####", VI: "+1 ###-###-####", VN: ["+84 ### #### ###", "+84 ### ### ###", "+84 #### ######", "+84 ## ### ## ##"], VU: ["+678 #####", "+678 ### ####"], WF: ["+681 ## ## ##", "+681 ### ## ## ##"], WS: ["+685 #####", "+685 ## #####", "+685 ### ###"], XK: ["+383 ## ### ###", "+383 ### #####"], YE: ["+967 # ### ###", "+967 ### ### ###"], YT: "+262 ### ## ## ##", ZA: ["+27 ## ### ####", "+27 ### ### ###"], ZM: ["+260 ### ### ###", "+260 ## #######", "+260 #########"], ZW: ["+263 ## #####", "+263 ## ### ####", "+263 ### ####", "+263 #### ######"] };
5
- const t$1 = /^[a-z]{2}$/i, countryCodeEmoji = (o) => {
6
- if (!t$1.test(o)) {
7
- const t2 = typeof o;
8
- throw new TypeError(`cc argument must be an ISO 3166-1 alpha-2 string, but got '${"string" === t2 ? o : t2}' instead.`);
5
+ const t$1 = /^[a-z]{2}$/i, countryCodeEmoji = (o2) => {
6
+ if (!t$1.test(o2)) {
7
+ const t2 = typeof o2;
8
+ throw new TypeError(`cc argument must be an ISO 3166-1 alpha-2 string, but got '${"string" === t2 ? o2 : t2}' instead.`);
9
9
  }
10
- const e = [...o.toUpperCase()].map((t2) => (t2.codePointAt(0) ?? 0) + 127397);
11
- return String.fromCodePoint(...e);
10
+ const e2 = [...o2.toUpperCase()].map((t2) => (t2.codePointAt(0) ?? 0) + 127397);
11
+ return String.fromCodePoint(...e2);
12
12
  };
13
- const t = Object.entries(M), divideMask = (e) => e.split(/ (.*)/s);
14
- function getCodeAndMask(e) {
13
+ const t = Object.entries(M), divideMask = (e2) => e2.split(/ (.*)/s);
14
+ function getCodeAndMask(e2) {
15
15
  let n = "", t2 = "";
16
- if (Array.isArray(e)) {
17
- const o = [];
18
- for (const t3 of e) {
19
- const [e2, s] = divideMask(t3);
20
- n || (n = e2), o.push(s);
16
+ if (Array.isArray(e2)) {
17
+ const o2 = [];
18
+ for (const t3 of e2) {
19
+ const [e3, s2] = divideMask(t3);
20
+ n || (n = e3), o2.push(s2);
21
21
  }
22
- t2 = o;
22
+ t2 = o2;
23
23
  } else {
24
- const [o, s] = divideMask(e);
25
- n = o, t2 = s;
24
+ const [o2, s2] = divideMask(e2);
25
+ n = o2, t2 = s2;
26
26
  }
27
27
  return [n, t2];
28
28
  }
29
- t.map(([e, n]) => ({ id: e, mask: n }));
30
- t.reduce((e, [n, t2]) => {
31
- const [o, s] = getCodeAndMask(t2);
32
- return e[n] = { code: o, mask: s }, e;
29
+ t.map(([e2, n]) => ({ id: e2, mask: n }));
30
+ t.reduce((e2, [n, t2]) => {
31
+ const [o2, s2] = getCodeAndMask(t2);
32
+ return e2[n] = { code: o2, mask: s2 }, e2;
33
33
  }, {});
34
- t.map(([e, n]) => {
35
- const [t2, o] = getCodeAndMask(n);
36
- return { id: e, code: t2, mask: o };
34
+ t.map(([e2, n]) => {
35
+ const [t2, o2] = getCodeAndMask(n);
36
+ return { id: e2, code: t2, mask: o2 };
37
37
  });
38
- t.reduce((e, [t2, o]) => {
39
- const [s, a] = getCodeAndMask(o);
40
- return e[t2] = { code: s, mask: a, flag: countryCodeEmoji(t2) }, e;
38
+ t.reduce((e2, [t2, o2]) => {
39
+ const [s2, a] = getCodeAndMask(o2);
40
+ return e2[t2] = { code: s2, mask: a, flag: countryCodeEmoji(t2) }, e2;
41
41
  }, {});
42
- t.map(([e, t2]) => {
43
- const [o, s] = getCodeAndMask(t2);
44
- return { id: e, code: o, mask: s, flag: countryCodeEmoji(e) };
42
+ t.map(([e2, t2]) => {
43
+ const [o2, s2] = getCodeAndMask(t2);
44
+ return { id: e2, code: o2, mask: s2, flag: countryCodeEmoji(e2) };
45
45
  });
46
- const MasksFullMap = (e) => {
47
- const o = new Intl.DisplayNames([e], { type: "region" });
48
- return t.reduce((e2, [t2, s]) => {
49
- const [a, r] = getCodeAndMask(s), d = o.of(t2) ?? "";
50
- return e2[t2] = { code: a, mask: r, name: d, flag: countryCodeEmoji(t2) }, e2;
46
+ const MasksFullMap = (e2) => {
47
+ const o2 = new Intl.DisplayNames([e2], { type: "region" });
48
+ return t.reduce((e3, [t2, s2]) => {
49
+ const [a, r] = getCodeAndMask(s2), d = o2.of(t2) ?? "";
50
+ return e3[t2] = { code: a, mask: r, name: d, flag: countryCodeEmoji(t2) }, e3;
51
51
  }, {});
52
- }, MasksFull = (e) => {
53
- const o = new Intl.DisplayNames([e], { type: "region" });
54
- return t.map(([e2, t2]) => {
55
- const [s, a] = getCodeAndMask(t2);
56
- return { id: e2, code: s, mask: a, name: o.of(e2) ?? "", flag: countryCodeEmoji(e2) };
52
+ }, MasksFull = (e2) => {
53
+ const o2 = new Intl.DisplayNames([e2], { type: "region" });
54
+ return t.map(([e3, t2]) => {
55
+ const [s2, a] = getCodeAndMask(t2);
56
+ return { id: e3, code: s2, mask: a, name: o2.of(e3) ?? "", flag: countryCodeEmoji(e3) };
57
57
  });
58
- }, m = t.reduce((e, [t2, o]) => {
59
- const [s, a] = getCodeAndMask(o), r = new Intl.DisplayNames(["en"], { type: "region" });
60
- return e[t2] = { code: s, mask: a, name: r.of(t2) ?? "", flag: countryCodeEmoji(t2) }, e;
61
- }, {}), i = t.map(([e, t2]) => {
62
- const [o, s] = getCodeAndMask(t2);
63
- return { id: e, code: o, mask: s, name: new Intl.DisplayNames(["en"], { type: "region" }).of(e) ?? "", flag: countryCodeEmoji(e) };
58
+ }, m = t.reduce((e2, [t2, o2]) => {
59
+ const [s2, a] = getCodeAndMask(o2), r = new Intl.DisplayNames(["en"], { type: "region" });
60
+ return e2[t2] = { code: s2, mask: a, name: r.of(t2) ?? "", flag: countryCodeEmoji(t2) }, e2;
61
+ }, {}), i = t.map(([e2, t2]) => {
62
+ const [o2, s2] = getCodeAndMask(t2);
63
+ return { id: e2, code: o2, mask: s2, name: new Intl.DisplayNames(["en"], { type: "region" }).of(e2) ?? "", flag: countryCodeEmoji(e2) };
64
64
  }), g = countryCodeEmoji;
65
+ function getNavigatorLang() {
66
+ return "undefined" != typeof navigator && navigator.language || "en";
67
+ }
68
+ function getMasksFullMapByLocale(e2) {
69
+ return e2.toLowerCase().startsWith("en") ? m : MasksFullMap(e2);
70
+ }
71
+ function getCountry(t2, n) {
72
+ const e2 = getMasksFullMapByLocale(n), r = t2.toUpperCase();
73
+ return r in e2 ? { id: r, ...e2[r] } : { id: "US", ...e2.US };
74
+ }
65
75
  function toArray(t2) {
66
76
  return Array.isArray(t2) ? t2 : [t2];
67
77
  }
@@ -73,35 +83,60 @@ function removeCountryCodePrefix(t2) {
73
83
  }
74
84
  function pickMaskVariant(t2, n) {
75
85
  if (1 === t2.length) return t2[0];
76
- const r = t2.map((t3) => ({ mask: t3, count: countPlaceholders(t3) })), e = r.filter((t3) => t3.count >= n).sort((t3, n2) => t3.count - n2.count);
77
- if (e.length > 0) return e[0].mask;
78
- const o = r.sort((t3, n2) => n2.count - t3.count)[0];
79
- return o ? o.mask : t2[0];
86
+ const e2 = t2.map((t3) => ({ mask: t3, count: countPlaceholders(t3) })), r = e2.filter((t3) => t3.count >= n).sort((t3, n2) => t3.count - n2.count);
87
+ if (r.length > 0) return r[0].mask;
88
+ const o2 = e2.sort((t3, n2) => n2.count - t3.count)[0];
89
+ return o2 ? o2.mask : t2[0];
80
90
  }
81
91
  function formatDigitsWithMap(t2, n) {
82
- let r = "";
83
- const e = [];
84
- let o = 0;
85
- const c = n.length, a = t2.length;
86
- for (let i2 = 0; i2 < a; i2++) {
87
- const a2 = t2[i2];
88
- if ("#" === a2) {
89
- if (!(o < c)) break;
90
- r += n[o], e.push(o), o++;
92
+ let e2 = "";
93
+ const r = [];
94
+ let o2 = 0;
95
+ const a = n.length, i2 = t2.length;
96
+ for (let u = 0; u < i2; u++) {
97
+ const i3 = t2[u];
98
+ if ("#" === i3) {
99
+ if (!(o2 < a)) break;
100
+ e2 += n[o2], r.push(o2), o2++;
91
101
  } else {
92
- const n2 = -1 !== t2.indexOf("#", i2 + 1) && o < c;
93
- (r.length > 0 || n2) && (r += a2, e.push(-1));
102
+ const n2 = -1 !== t2.indexOf("#", u + 1) && o2 < a;
103
+ (e2.length > 0 || n2) && (e2 += i3, r.push(-1));
94
104
  }
95
105
  }
96
- return { display: r, map: e };
106
+ return { display: e2, map: r };
107
+ }
108
+ const o = "https://ipapi.co/json/", e = 1500, p = "@desource/phone-mask:geo", s = 864e5;
109
+ async function detectCountryFromGeoIP(e$1 = o, r = e) {
110
+ const c = new AbortController(), n = setTimeout(() => c.abort(), r);
111
+ try {
112
+ const t2 = await fetch(e$1, { signal: c.signal, headers: { Accept: "application/json" } });
113
+ if (clearTimeout(n), !t2.ok) return null;
114
+ const o2 = await t2.json();
115
+ return (o2.country || o2.country_code || o2.countryCode || o2.country_code2 || "").toString().toUpperCase() || null;
116
+ } catch {
117
+ return clearTimeout(n), null;
118
+ }
119
+ }
120
+ async function detectByGeoIp(t2) {
121
+ try {
122
+ const o3 = localStorage.getItem(p);
123
+ if (o3) {
124
+ const c = JSON.parse(o3), n = Date.now() - c.ts > s;
125
+ if (!n && c.country_code && t2(c.country_code)) return c.country_code.toUpperCase();
126
+ n && localStorage.removeItem(p);
127
+ }
128
+ } catch {
129
+ }
130
+ const o2 = await detectCountryFromGeoIP();
131
+ if (o2 && t2(o2)) {
132
+ try {
133
+ localStorage.setItem(p, JSON.stringify({ country_code: o2, ts: Date.now() }));
134
+ } catch {
135
+ }
136
+ return o2;
137
+ }
138
+ return null;
97
139
  }
98
- const CACHE_KEY = "@desource/phone-mask:geo";
99
- const CACHE_EXPIRY_MS = 24 * 60 * 6e4;
100
- const GEO_IP_TIMEOUT = 1500;
101
- const GEO_IP_URL = "https://ipapi.co/json/";
102
- const Delimiters = [" ", "-", "(", ")"];
103
- const NavigationKeys = ["ArrowLeft", "ArrowRight", "ArrowUp", "ArrowDown", "Home", "End", "Tab"];
104
- const InvalidPattern = /[^\d\s\-()]/;
105
140
  const emptyCountry = { id: "", code: "", mask: "", flag: "", name: "" };
106
141
  function useCountrySelector(usedLocale) {
107
142
  const isEnLocale = vue.computed(() => usedLocale.value.toLowerCase().startsWith("en"));
@@ -175,7 +210,7 @@ function useCountrySelector(usedLocale) {
175
210
  };
176
211
  const detectFromLocale = () => {
177
212
  try {
178
- const lang = navigator.language || "";
213
+ const lang = getNavigatorLang();
179
214
  try {
180
215
  const loc = new Intl.Locale(lang);
181
216
  if (loc.region && hasCountry(loc.region)) return loc.region.toUpperCase();
@@ -187,46 +222,6 @@ function useCountrySelector(usedLocale) {
187
222
  }
188
223
  return null;
189
224
  };
190
- const detectByGeoIp = async () => {
191
- try {
192
- const cached = localStorage.getItem(CACHE_KEY);
193
- if (cached) {
194
- const parsed = JSON.parse(cached);
195
- const isExpired = Date.now() - parsed.ts > CACHE_EXPIRY_MS;
196
- if (!isExpired && parsed.country_code && hasCountry(parsed.country_code)) {
197
- return parsed.country_code.toUpperCase();
198
- }
199
- if (isExpired) {
200
- localStorage.removeItem(CACHE_KEY);
201
- }
202
- }
203
- } catch {
204
- }
205
- const controller = new AbortController();
206
- const timeoutId = setTimeout(() => controller.abort(), GEO_IP_TIMEOUT);
207
- try {
208
- const res = await fetch(GEO_IP_URL, {
209
- signal: controller.signal,
210
- headers: { Accept: "application/json" }
211
- });
212
- if (!res.ok) {
213
- return null;
214
- }
215
- const json = await res.json();
216
- const code = (json.country || json.country_code || json.countryCode || json.country_code2 || "").toString().toUpperCase();
217
- if (code && hasCountry(code)) {
218
- try {
219
- localStorage.setItem(CACHE_KEY, JSON.stringify({ country_code: code, ts: Date.now() }));
220
- } catch {
221
- }
222
- return code;
223
- }
224
- } catch {
225
- } finally {
226
- clearTimeout(timeoutId);
227
- }
228
- return null;
229
- };
230
225
  const selectInitialCountry = (id, emitFn) => {
231
226
  const previousId = selectedId.value;
232
227
  selectedId.value = id;
@@ -239,7 +234,7 @@ function useCountrySelector(usedLocale) {
239
234
  return;
240
235
  }
241
236
  if (!detect) return;
242
- const geo = await detectByGeoIp();
237
+ const geo = await detectByGeoIp(hasCountry);
243
238
  if (geo) {
244
239
  selectInitialCountry(geo, emitFn);
245
240
  return;
@@ -335,6 +330,9 @@ function getSelection(el) {
335
330
  if (!el) return [0, 0];
336
331
  return [el.selectionStart ?? 0, el.selectionEnd ?? 0];
337
332
  }
333
+ const Delimiters = [" ", "-", "(", ")"];
334
+ const NavigationKeys = ["ArrowLeft", "ArrowRight", "ArrowUp", "ArrowDown", "Home", "End", "Tab"];
335
+ const InvalidPattern = /[^\d\s\-()]/;
338
336
  function useMask(selected, telRef) {
339
337
  const digits = vue.ref("");
340
338
  const displayValue = vue.ref("");
@@ -365,17 +363,17 @@ function useMask(selected, telRef) {
365
363
  if (startIdx >= endIdx) return;
366
364
  digits.value = digits.value.slice(0, startIdx) + digits.value.slice(endIdx);
367
365
  };
368
- const handleBeforeInput = (e) => {
369
- const el = e.target;
366
+ const handleBeforeInput = (e2) => {
367
+ const el = e2.target;
370
368
  if (!el) return;
371
- const data = e.data;
372
- if (e.inputType !== "insertText" || !data) return;
369
+ const data = e2.data;
370
+ if (e2.inputType !== "insertText" || !data) return;
373
371
  if (InvalidPattern.test(data) || data === " " && el.value.endsWith(" ")) {
374
- e.preventDefault();
372
+ e2.preventDefault();
375
373
  }
376
374
  };
377
- const handleInput = (e) => {
378
- const el = e.target;
375
+ const handleInput = (e2) => {
376
+ const el = e2.target;
379
377
  if (!el) return;
380
378
  const newDigits = extractDigits(el.value, maxDigits.value);
381
379
  showValidationHint.value = false;
@@ -393,13 +391,13 @@ function useMask(selected, telRef) {
393
391
  setCaretToDigitPosition(digits.value.length);
394
392
  });
395
393
  };
396
- const handleKeydownInternal = (e) => {
397
- const el = telRef.value ?? e.target;
394
+ const handleKeydownInternal = (e2) => {
395
+ const el = telRef.value ?? e2.target;
398
396
  if (!el) return;
399
- if (e.ctrlKey || e.metaKey || e.altKey || NavigationKeys.includes(e.key)) return;
397
+ if (e2.ctrlKey || e2.metaKey || e2.altKey || NavigationKeys.includes(e2.key)) return;
400
398
  const [selStart, selEnd] = getSelection(el);
401
- if (e.key === "Backspace") {
402
- e.preventDefault();
399
+ if (e2.key === "Backspace") {
400
+ e2.preventDefault();
403
401
  if (selStart !== selEnd) {
404
402
  const range = formatter.value.getDigitRange(digits.value, selStart, selEnd);
405
403
  if (range) {
@@ -428,8 +426,8 @@ function useMask(selected, telRef) {
428
426
  }
429
427
  return;
430
428
  }
431
- if (e.key === "Delete") {
432
- e.preventDefault();
429
+ if (e2.key === "Delete") {
430
+ e2.preventDefault();
433
431
  if (selStart !== selEnd) {
434
432
  const range = formatter.value.getDigitRange(digits.value, selStart, selEnd);
435
433
  if (range) {
@@ -451,30 +449,30 @@ function useMask(selected, telRef) {
451
449
  }
452
450
  return;
453
451
  }
454
- if (/^[0-9]$/.test(e.key)) {
452
+ if (/^[0-9]$/.test(e2.key)) {
455
453
  if (digits.value.length >= maxDigits.value) {
456
- e.preventDefault();
454
+ e2.preventDefault();
457
455
  }
458
456
  return;
459
457
  }
460
- if (e.key.length === 1) {
461
- e.preventDefault();
458
+ if (e2.key.length === 1) {
459
+ e2.preventDefault();
462
460
  }
463
461
  };
464
- const handleKeydown = (e) => {
462
+ const handleKeydown = (e2) => {
465
463
  showValidationHint.value = false;
466
464
  if (validationTimer.value) {
467
465
  clearTimeout(validationTimer.value);
468
466
  }
469
- handleKeydownInternal(e);
467
+ handleKeydownInternal(e2);
470
468
  if (validationTimer.value) clearTimeout(validationTimer.value);
471
469
  validationTimer.value = setTimeout(() => {
472
470
  if (!isComplete.value && !isEmpty.value) showValidationHint.value = true;
473
471
  }, 300);
474
472
  };
475
- const handlePaste = (e) => {
476
- e.preventDefault();
477
- const text = e.clipboardData?.getData("text") || "";
473
+ const handlePaste = (e2) => {
474
+ e2.preventDefault();
475
+ const text = e2.clipboardData?.getData("text") || "";
478
476
  const pastedDigits = extractDigits(text, maxDigits.value);
479
477
  if (pastedDigits.length === 0) return;
480
478
  const el = telRef.value;
@@ -665,11 +663,7 @@ const _sfc_main = /* @__PURE__ */ vue.defineComponent({
665
663
  const liveRef = vue.useTemplateRef("liveRef");
666
664
  const dropdownRef = vue.useTemplateRef("dropdownRef");
667
665
  const usedLocale = vue.computed(() => {
668
- if (props.locale) return props.locale;
669
- if (typeof navigator !== "undefined") {
670
- return navigator.language || "en";
671
- }
672
- return "en";
666
+ return props.locale || getNavigatorLang();
673
667
  });
674
668
  const dropdownStyle = vue.shallowRef({});
675
669
  const countrySelector = useCountrySelector(usedLocale);
@@ -726,30 +720,30 @@ const _sfc_main = /* @__PURE__ */ vue.defineComponent({
726
720
  digits: digits.value
727
721
  });
728
722
  };
729
- const onInput = async (e) => {
723
+ const onInput = async (e2) => {
730
724
  if (inactive.value) return;
731
- mask.handleInput(e);
725
+ mask.handleInput(e2);
732
726
  await vue.nextTick();
733
727
  emitModelUpdate();
734
728
  };
735
- const onKeydown = async (e) => {
729
+ const onKeydown = async (e2) => {
736
730
  if (inactive.value) return;
737
- mask.handleKeydown(e);
731
+ mask.handleKeydown(e2);
738
732
  await vue.nextTick();
739
733
  emitModelUpdate();
740
734
  };
741
- const onPaste = async (e) => {
735
+ const onPaste = async (e2) => {
742
736
  if (inactive.value) return;
743
- mask.handlePaste(e);
737
+ mask.handlePaste(e2);
744
738
  await vue.nextTick();
745
739
  emitModelUpdate();
746
740
  };
747
- const onFocus = (e) => {
741
+ const onFocus = (e2) => {
748
742
  mask.handleFocus();
749
743
  dropdownOpened.value = false;
750
- emit("focus", e);
744
+ emit("focus", e2);
751
745
  };
752
- const onBlur = (e) => emit("blur", e);
746
+ const onBlur = (e2) => emit("blur", e2);
753
747
  const onSelectCountry = async (countryId) => {
754
748
  countrySelector.selectCountry(countryId);
755
749
  emit("country-change", selected.value);
@@ -775,8 +769,8 @@ const _sfc_main = /* @__PURE__ */ vue.defineComponent({
775
769
  await vue.nextTick();
776
770
  telRef.value?.focus();
777
771
  };
778
- const positionDropdown = (e) => {
779
- if (e?.type === "scroll" && e.target && dropdownRef.value?.contains(e.target)) return;
772
+ const positionDropdown = (e2) => {
773
+ if (e2?.type === "scroll" && e2.target && dropdownRef.value?.contains(e2.target)) return;
780
774
  const root = rootRef.value;
781
775
  if (!root) return;
782
776
  const rect = root.getBoundingClientRect();
@@ -1118,42 +1112,7 @@ const _export_sfc = (sfc, props) => {
1118
1112
  }
1119
1113
  return target;
1120
1114
  };
1121
- const PhoneInput = /* @__PURE__ */ _export_sfc(_sfc_main, [["__scopeId", "data-v-95467f81"]]);
1122
- function getNavigatorLang() {
1123
- if (typeof navigator !== "undefined") {
1124
- return navigator.language || "";
1125
- }
1126
- return "";
1127
- }
1128
- function getCountry(countryCode, locale) {
1129
- const isEn = locale.toLowerCase().startsWith("en");
1130
- const countriesMap = isEn ? m : MasksFullMap(locale);
1131
- const id = countryCode.toUpperCase();
1132
- const found = countriesMap[id];
1133
- return found ? { id, ...found } : null;
1134
- }
1135
- function getDefaultCountry(locale) {
1136
- const isEn = locale.toLowerCase().startsWith("en");
1137
- const countries = isEn ? m : MasksFullMap(locale);
1138
- return { id: "US", ...countries.US };
1139
- }
1140
- async function detectCountryFromGeoIP() {
1141
- try {
1142
- const controller = new AbortController();
1143
- const timeoutId = setTimeout(() => controller.abort(), GEO_IP_TIMEOUT);
1144
- const res = await fetch(GEO_IP_URL, {
1145
- signal: controller.signal,
1146
- headers: { Accept: "application/json" }
1147
- });
1148
- clearTimeout(timeoutId);
1149
- if (!res.ok) return null;
1150
- const json = await res.json();
1151
- const code = (json.country || json.country_code || json.countryCode || json.country_code2 || "").toString().toUpperCase();
1152
- return code || null;
1153
- } catch {
1154
- return null;
1155
- }
1156
- }
1115
+ const PhoneInput = /* @__PURE__ */ _export_sfc(_sfc_main, [["__scopeId", "data-v-755b15ee"]]);
1157
1116
  function detectCountryFromLocale() {
1158
1117
  try {
1159
1118
  const lang = getNavigatorLang();
@@ -1176,24 +1135,24 @@ async function initState(binding) {
1176
1135
  } else if (typeof value === "object" && value !== null) {
1177
1136
  options = value;
1178
1137
  }
1179
- const locale = options.locale || getNavigatorLang() || "en";
1180
- let country = null;
1138
+ const locale = options.locale || getNavigatorLang();
1139
+ let country;
1181
1140
  if (options.country) {
1182
1141
  country = getCountry(options.country, locale);
1183
1142
  } else if (options.detect) {
1184
1143
  const geoCountry = await detectCountryFromGeoIP();
1185
1144
  if (geoCountry) {
1186
1145
  country = getCountry(geoCountry, locale);
1187
- }
1188
- if (!country) {
1146
+ } else {
1189
1147
  const localeCountry = detectCountryFromLocale();
1190
1148
  if (localeCountry) {
1191
1149
  country = getCountry(localeCountry, locale);
1150
+ } else {
1151
+ country = getCountry("US", locale);
1192
1152
  }
1193
1153
  }
1194
- }
1195
- if (!country) {
1196
- country = getDefaultCountry(locale);
1154
+ } else {
1155
+ country = getCountry("US", locale);
1197
1156
  }
1198
1157
  return {
1199
1158
  country,
@@ -1216,17 +1175,17 @@ function updateDisplay(el, state) {
1216
1175
  }
1217
1176
  }
1218
1177
  function createBeforeInputHandler(el) {
1219
- return (e) => {
1220
- const data = e.data;
1221
- if (e.inputType !== "insertText" || !data) return;
1178
+ return (e2) => {
1179
+ const data = e2.data;
1180
+ if (e2.inputType !== "insertText" || !data) return;
1222
1181
  if (InvalidPattern.test(data) || data === " " && el.value.endsWith(" ")) {
1223
- e.preventDefault();
1182
+ e2.preventDefault();
1224
1183
  }
1225
1184
  };
1226
1185
  }
1227
1186
  function createInputHandler(el, state) {
1228
- return (e) => {
1229
- const target = e.target;
1187
+ return (e2) => {
1188
+ const target = e2.target;
1230
1189
  if (!target) return;
1231
1190
  const raw = target.value || "";
1232
1191
  const maxDigits = state.formatter.getMaxDigits();
@@ -1239,11 +1198,11 @@ function createInputHandler(el, state) {
1239
1198
  };
1240
1199
  }
1241
1200
  function createKeydownHandler(el, state) {
1242
- return (e) => {
1243
- if (e.ctrlKey || e.metaKey || e.altKey || NavigationKeys.includes(e.key)) return;
1201
+ return (e2) => {
1202
+ if (e2.ctrlKey || e2.metaKey || e2.altKey || NavigationKeys.includes(e2.key)) return;
1244
1203
  const [selStart, selEnd] = getSelection(el);
1245
- if (e.key === "Backspace") {
1246
- e.preventDefault();
1204
+ if (e2.key === "Backspace") {
1205
+ e2.preventDefault();
1247
1206
  if (selStart !== selEnd) {
1248
1207
  const range = state.formatter.getDigitRange(state.digits, selStart, selEnd);
1249
1208
  if (range) {
@@ -1278,8 +1237,8 @@ function createKeydownHandler(el, state) {
1278
1237
  }
1279
1238
  return;
1280
1239
  }
1281
- if (e.key === "Delete") {
1282
- e.preventDefault();
1240
+ if (e2.key === "Delete") {
1241
+ e2.preventDefault();
1283
1242
  if (selStart !== selEnd) {
1284
1243
  const range = state.formatter.getDigitRange(state.digits, selStart, selEnd);
1285
1244
  if (range) {
@@ -1307,21 +1266,21 @@ function createKeydownHandler(el, state) {
1307
1266
  }
1308
1267
  return;
1309
1268
  }
1310
- if (/^[0-9]$/.test(e.key)) {
1269
+ if (/^[0-9]$/.test(e2.key)) {
1311
1270
  if (state.digits.length >= state.formatter.getMaxDigits()) {
1312
- e.preventDefault();
1271
+ e2.preventDefault();
1313
1272
  }
1314
1273
  return;
1315
1274
  }
1316
- if (e.key.length === 1) {
1317
- e.preventDefault();
1275
+ if (e2.key.length === 1) {
1276
+ e2.preventDefault();
1318
1277
  }
1319
1278
  };
1320
1279
  }
1321
1280
  function createPasteHandler(el, state) {
1322
- return (e) => {
1323
- e.preventDefault();
1324
- const text = e.clipboardData?.getData("text") || "";
1281
+ return (e2) => {
1282
+ e2.preventDefault();
1283
+ const text = e2.clipboardData?.getData("text") || "";
1325
1284
  const maxDigits = state.formatter.getMaxDigits();
1326
1285
  const pastedDigits = extractDigits(text, maxDigits);
1327
1286
  if (pastedDigits.length === 0) return;
@@ -1355,7 +1314,6 @@ function createPasteHandler(el, state) {
1355
1314
  }
1356
1315
  async function updateCountry(el, state, newCountryCode) {
1357
1316
  const newCountry = getCountry(newCountryCode, state.locale);
1358
- if (!newCountry) return;
1359
1317
  state.country = newCountry;
1360
1318
  state.formatter = createPhoneFormatter(newCountry);
1361
1319
  el.placeholder = state.formatter.getPlaceholder();