world-map-svg 0.5.0 → 0.5.1

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/README.md CHANGED
@@ -1,194 +1,194 @@
1
- # world-map-svg
2
-
3
- Interactive SVG world map React component with zoom, pan, and country selection.
4
-
5
- ## Installation
6
-
7
- ```bash
8
- npm install world-map-svg
9
- ```
10
-
11
- ## Usage
12
-
13
- ```tsx
14
- import { WorldMap } from 'world-map-svg'
15
- import 'world-map-svg/style.css'
16
-
17
- function App() {
18
- return (
19
- <div style={{ width: '100%', height: '500px' }}>
20
- <WorldMap
21
- countryColor="#093C5D"
22
- />
23
- </div>
24
- )
25
- }
26
- ```
27
-
28
- ## Demo Usage
29
-
30
- ```tsx
31
- import { useState } from 'react'
32
- import { WorldMap } from 'world-map-svg'
33
- import 'world-map-svg/style.css'
34
-
35
- export function MapDemo() {
36
- const [hover, setHover] = useState<{ name: string; x: number; y: number } | null>(null)
37
- const [modal, setModal] = useState<{ code: string; name: string } | null>(null)
38
-
39
- return (
40
- <div style={{ position: 'relative', width: '100%', height: 600 }}>
41
- <WorldMap
42
- onCountryHover={(code, name, x, y) => setHover({ name, x, y })}
43
- onCountryClick={(code, name) => setModal({ code, name })}
44
- />
45
-
46
- {hover && (
47
- <div style={{ position: 'absolute', left: hover.x + 12, top: hover.y + 12 }}>
48
- {hover.name}
49
- </div>
50
- )}
51
-
52
- {modal && (
53
- <div>
54
- <h3>{modal.name}</h3>
55
- <p>{modal.code}</p>
56
- </div>
57
- )}
58
- </div>
59
- )
60
- }
61
- ```
62
-
63
- Hover gets the country name and pointer position. Click gets the country name and code, so your app can open a modal and load any extra data you need.
64
-
65
- ## Full Props Setup
66
-
67
- ```tsx
68
- import { useState } from 'react'
69
- import { WorldMap } from 'world-map-svg'
70
- import 'world-map-svg/style.css'
71
-
72
- export function FullMapSetup() {
73
- const [hover, setHover] = useState<{ name: string; x: number; y: number } | null>(null)
74
- const [selected, setSelected] = useState<{ code: string; name: string } | null>(null)
75
-
76
- return (
77
- <div style={{ position: 'relative', width: '100%', height: 600 }}>
78
- <WorldMap
79
- backgroundColor="#f8fbff"
80
- countryColor="#093C5D"
81
- className="my-map"
82
- showConnections
83
- connectionBase="BD"
84
- connectedCountries={['US', 'IN', 'GB', 'AE']}
85
- onCountryHover={(code, name, x, y) => setHover({ name: `${name} (${code})`, x, y })}
86
- onCountryClick={(code, name) => setSelected({ code, name })}
87
- onConnectionDotHover={(code, name) => {
88
- // Optional: show dot-specific tooltip
89
- console.log('dot hover', code, name)
90
- }}
91
- onConnectionDotClick={(code, name) => {
92
- // Optional: open modal or route to a detail page
93
- console.log('dot click', code, name)
94
- }}
95
- />
96
-
97
- {hover && (
98
- <div style={{ position: 'absolute', left: hover.x + 12, top: hover.y + 12 }}>
99
- {hover.name}
100
- </div>
101
- )}
102
-
103
- {selected && (
104
- <div>
105
- <h3>{selected.name}</h3>
106
- <p>Country code: {selected.code}</p>
107
- </div>
108
- )}
109
- </div>
110
- )
111
- }
112
- ```
113
-
114
- If you pass `onCountryHover` or `onCountryClick`, your app controls the hover/click UI (popover/modal). If you do not pass them, the built-in tooltip behavior is used.
115
-
116
- ### Connection country names
117
-
118
- `connectionBase` and `connectedCountries` accept **ISO 3166-1 alpha-2 codes** (e.g. `BD`, `US`) or **country names** from the bundled map (e.g. `Bangladesh`, `United States`). Matching is case-insensitive and ignores extra whitespace, accents, and most punctuation.
119
-
120
- Common abbreviations also work: `USA`, `UK`, `UAE`, `DRC`, `Brunei`, `Laos`, `Burma`, etc.
121
-
122
- **Coverage:** All **250** countries on the bundled map are supported by ISO code and by their SVG country name (normalization handles accents, spacing, and punctuation). Common abbreviations (`USA`, `UK`, `UAE`, `Brunei`, `Laos`, etc.) are also supported. Run `npm run verify` to validate data integrity before every build.
123
-
124
- ```tsx
125
- <WorldMap
126
- connectionBase="Bangladesh"
127
- connectedCountries={['United States', 'India', 'United Kingdom']}
128
- />
129
- ```
130
-
131
- Use `normalizeCountryName` from the package if you need the same normalization in your app:
132
-
133
- ```tsx
134
- import { normalizeCountryName } from 'world-map-svg'
135
-
136
- normalizeCountryName(" Côte d'Ivoire ") // "cote d ivoire"
137
- ```
138
-
139
- ## Props
140
-
141
- | Prop | Type | Default | Description |
142
- |------|------|---------|-------------|
143
- | `backgroundColor` | `string` | `transparent` | Map background color |
144
- | `countryColor` | `string` | `#093C5D` | Base fill color for countries |
145
- | `svgUrl` | `string` | bundled SVG | Custom SVG URL to override the default world map |
146
- | `showConnections` | `boolean` | `true` | Show carved connection lines |
147
- | `connectionBase` | `string` | `BD` | Hub country — ISO code (e.g. `BD`) or name (e.g. `Bangladesh`) |
148
- | `connectedCountries` | `string[]` | `['US', 'IN']` | Connected endpoints — ISO codes and/or names (e.g. `['United States', 'India']`) |
149
- | `onCountryHover` | `(code, name, x, y) => void` | - | Fires when hovering a country path. Suppresses built-in tooltip. |
150
- | `onCountryClick` | `(code, name, x, y) => void` | - | Fires when clicking a country path. Suppresses built-in click tooltip. |
151
- | `onConnectionDotHover` | `(code, name, x, y) => void` | - | Fires when hovering a connection dot. |
152
- | `onConnectionDotClick` | `(code, name, x, y) => void` | - | Fires when clicking a connection dot. |
153
- | `className` | `string` | - | Additional CSS class for the container |
154
-
155
- ## Development
156
-
157
- ```bash
158
- npm install
159
- npm run dev # Start playground dev server
160
- npm run build # Build library for publishing
161
- npm run lint
162
- ```
163
-
164
- The default SVG map data is bundled with the package. You can override it via the `svgUrl` prop.
165
-
166
- ## Publish Checklist
167
-
168
- 1. Confirm package name availability:
169
-
170
- ```bash
171
- npm view world-map-svg
172
- ```
173
-
174
- If taken, rename to a scoped package in `package.json` (for example `@yourname/world-map-svg`).
175
-
176
- 2. Update package metadata in `package.json`:
177
- - `repository.url`
178
- - `bugs.url`
179
- - `homepage`
180
-
181
- 3. Run release checks:
182
-
183
- ```bash
184
- npm run build
185
- npm run lint
186
- npm pack --dry-run
187
- ```
188
-
189
- 4. Login and publish:
190
-
191
- ```bash
192
- npm login
193
- npm publish --access public
194
- ```
1
+ # world-map-svg
2
+
3
+ Interactive SVG world map React component with zoom, pan, and country selection.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install world-map-svg
9
+ ```
10
+
11
+ ## Usage
12
+
13
+ ```tsx
14
+ import { WorldMap } from 'world-map-svg'
15
+ import 'world-map-svg/style.css'
16
+
17
+ function App() {
18
+ return (
19
+ <div style={{ width: '100%', height: '500px' }}>
20
+ <WorldMap
21
+ countryColor="#093C5D"
22
+ />
23
+ </div>
24
+ )
25
+ }
26
+ ```
27
+
28
+ ## Demo Usage
29
+
30
+ ```tsx
31
+ import { useState } from 'react'
32
+ import { WorldMap } from 'world-map-svg'
33
+ import 'world-map-svg/style.css'
34
+
35
+ export function MapDemo() {
36
+ const [hover, setHover] = useState<{ name: string; x: number; y: number } | null>(null)
37
+ const [modal, setModal] = useState<{ code: string; name: string } | null>(null)
38
+
39
+ return (
40
+ <div style={{ position: 'relative', width: '100%', height: 600 }}>
41
+ <WorldMap
42
+ onCountryHover={(code, name, x, y) => setHover({ name, x, y })}
43
+ onCountryClick={(code, name) => setModal({ code, name })}
44
+ />
45
+
46
+ {hover && (
47
+ <div style={{ position: 'absolute', left: hover.x + 12, top: hover.y + 12 }}>
48
+ {hover.name}
49
+ </div>
50
+ )}
51
+
52
+ {modal && (
53
+ <div>
54
+ <h3>{modal.name}</h3>
55
+ <p>{modal.code}</p>
56
+ </div>
57
+ )}
58
+ </div>
59
+ )
60
+ }
61
+ ```
62
+
63
+ Hover gets the country name and pointer position. Click gets the country name and code, so your app can open a modal and load any extra data you need.
64
+
65
+ ## Full Props Setup
66
+
67
+ ```tsx
68
+ import { useState } from 'react'
69
+ import { WorldMap } from 'world-map-svg'
70
+ import 'world-map-svg/style.css'
71
+
72
+ export function FullMapSetup() {
73
+ const [hover, setHover] = useState<{ name: string; x: number; y: number } | null>(null)
74
+ const [selected, setSelected] = useState<{ code: string; name: string } | null>(null)
75
+
76
+ return (
77
+ <div style={{ position: 'relative', width: '100%', height: 600 }}>
78
+ <WorldMap
79
+ backgroundColor="#f8fbff"
80
+ countryColor="#093C5D"
81
+ className="my-map"
82
+ showConnections
83
+ connectionBase="BD"
84
+ connectedCountries={['US', 'IN', 'GB', 'AE']}
85
+ onCountryHover={(code, name, x, y) => setHover({ name: `${name} (${code})`, x, y })}
86
+ onCountryClick={(code, name) => setSelected({ code, name })}
87
+ onConnectionDotHover={(code, name) => {
88
+ // Optional: show dot-specific tooltip
89
+ console.log('dot hover', code, name)
90
+ }}
91
+ onConnectionDotClick={(code, name) => {
92
+ // Optional: open modal or route to a detail page
93
+ console.log('dot click', code, name)
94
+ }}
95
+ />
96
+
97
+ {hover && (
98
+ <div style={{ position: 'absolute', left: hover.x + 12, top: hover.y + 12 }}>
99
+ {hover.name}
100
+ </div>
101
+ )}
102
+
103
+ {selected && (
104
+ <div>
105
+ <h3>{selected.name}</h3>
106
+ <p>Country code: {selected.code}</p>
107
+ </div>
108
+ )}
109
+ </div>
110
+ )
111
+ }
112
+ ```
113
+
114
+ If you pass `onCountryHover` or `onCountryClick`, your app controls the hover/click UI (popover/modal). If you do not pass them, the built-in tooltip behavior is used.
115
+
116
+ ### Connection country names
117
+
118
+ `connectionBase` and `connectedCountries` accept **ISO 3166-1 alpha-2 codes** (e.g. `BD`, `US`) or **country names** from the bundled map (e.g. `Bangladesh`, `United States`). Matching is case-insensitive and ignores extra whitespace, accents, and most punctuation.
119
+
120
+ Common abbreviations also work: `USA`, `UK`, `UAE`, `DRC`, `Brunei`, `Laos`, `Burma`, etc.
121
+
122
+ **Coverage:** All **250** countries on the bundled map are supported by ISO code and by their SVG country name (normalization handles accents, spacing, and punctuation). Common abbreviations (`USA`, `UK`, `UAE`, `Brunei`, `Laos`, etc.) are also supported. Run `npm run verify` to validate data integrity before every build.
123
+
124
+ ```tsx
125
+ <WorldMap
126
+ connectionBase="Bangladesh"
127
+ connectedCountries={['United States', 'India', 'United Kingdom']}
128
+ />
129
+ ```
130
+
131
+ Use `normalizeCountryName` from the package if you need the same normalization in your app:
132
+
133
+ ```tsx
134
+ import { normalizeCountryName } from 'world-map-svg'
135
+
136
+ normalizeCountryName(" Côte d'Ivoire ") // "cotedivoire"
137
+ ```
138
+
139
+ ## Props
140
+
141
+ | Prop | Type | Default | Description |
142
+ |------|------|---------|-------------|
143
+ | `backgroundColor` | `string` | `transparent` | Map background color |
144
+ | `countryColor` | `string` | `#093C5D` | Base fill color for countries |
145
+ | `svgUrl` | `string` | bundled SVG | Custom SVG URL to override the default world map |
146
+ | `showConnections` | `boolean` | `true` | Show carved connection lines |
147
+ | `connectionBase` | `string` | `BD` | Hub country — ISO code (e.g. `BD`) or name (e.g. `Bangladesh`) |
148
+ | `connectedCountries` | `string[]` | `['US', 'IN']` | Connected endpoints — ISO codes and/or names (e.g. `['United States', 'India']`) |
149
+ | `onCountryHover` | `(code, name, x, y) => void` | - | Fires when hovering a country path. Suppresses built-in tooltip. |
150
+ | `onCountryClick` | `(code, name, x, y) => void` | - | Fires when clicking a country path. Suppresses built-in click tooltip. |
151
+ | `onConnectionDotHover` | `(code, name, x, y) => void` | - | Fires when hovering a connection dot. |
152
+ | `onConnectionDotClick` | `(code, name, x, y) => void` | - | Fires when clicking a connection dot. |
153
+ | `className` | `string` | - | Additional CSS class for the container |
154
+
155
+ ## Development
156
+
157
+ ```bash
158
+ npm install
159
+ npm run dev # Start playground dev server
160
+ npm run build # Build library for publishing
161
+ npm run lint
162
+ ```
163
+
164
+ The default SVG map data is bundled with the package. You can override it via the `svgUrl` prop.
165
+
166
+ ## Publish Checklist
167
+
168
+ 1. Confirm package name availability:
169
+
170
+ ```bash
171
+ npm view world-map-svg
172
+ ```
173
+
174
+ If taken, rename to a scoped package in `package.json` (for example `@yourname/world-map-svg`).
175
+
176
+ 2. Update package metadata in `package.json`:
177
+ - `repository.url`
178
+ - `bugs.url`
179
+ - `homepage`
180
+
181
+ 3. Run release checks:
182
+
183
+ ```bash
184
+ npm run build
185
+ npm run lint
186
+ npm pack --dry-run
187
+ ```
188
+
189
+ 4. Login and publish:
190
+
191
+ ```bash
192
+ npm login
193
+ npm publish --access public
194
+ ```
@@ -1035,4 +1035,4 @@ Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{val
1035
1035
  title="Zimbabwe"
1036
1036
  id="ZW" />
1037
1037
  </svg>
1038
- `,r={AD:{x:479.3,y:331.5},AE:{x:626.4,y:392.9},AF:{x:664.9,y:361.8},AG:{x:301.5,y:413.8},AI:{x:297.9,y:411.2},AL:{x:531.5,y:336.6},AM:{x:601.2,y:340.6},AO:{x:525.1,y:494.6},AR:{x:296.3,y:586.5},AS:{x:1006.2,y:503.2},AT:{x:512.3,y:310.9},AU:{x:856.4,y:568.8},AW:{x:278.5,y:427.7},AX:{x:531.2,y:250.9},AZ:{x:608.4,y:340.3},BA:{x:524.5,y:326.1},BB:{x:307.8,y:425.8},BD:{x:728.4,y:394.8},BE:{x:487.4,y:299},BF:{x:470.5,y:428.5},BG:{x:546.4,y:330.7},BH:{x:616.7,y:387.7},BI:{x:558.8,y:472.4},BJ:{x:481.3,y:436.8},BL:{x:298.5,y:412.2},BN:{x:796.8,y:450.3},BO:{x:296.5,y:509.3},BM:{x:293.1,y:367.5},BQ:{x:290.6,y:421},BR:{x:322.2,y:505.6},BS:{x:262,y:394},BT:{x:728.6,y:383.1},BV:{x:484.5,y:644.8},BW:{x:544.1,y:527},BY:{x:553.3,y:284.1},BZ:{x:226.5,y:414.3},CA:{x:203.1,y:173.2},CC:{x:746.8,y:497.1},CD:{x:535.9,y:474.4},CF:{x:533.6,y:444.3},CG:{x:516.6,y:464.8},CH:{x:497.9,y:314.7},CI:{x:459.3,y:441.8},CK:{x:26.4,y:523.5},CL:{x:228.1,y:582.3},CM:{x:509.6,y:442.2},CN:{x:767.3,y:348.2},CO:{x:270.2,y:451.4},CR:{x:238.5,y:435.9},CU:{x:251.7,y:401.4},CV:{x:407.5,y:417.7},CW:{x:281.4,y:428.6},CX:{x:771.4,y:492.4},CY:{x:568.7,y:358.2},CZ:{x:518.3,y:302},DE:{x:504.2,y:295.3},DJ:{x:594.4,y:429.7},DK:{x:507.5,y:272.2},DM:{x:302.7,y:419.4},DO:{x:278,y:409.6},DZ:{x:479.5,y:380.2},EC:{x:240.7,y:467.9},EG:{x:561.3,y:384.9},EE:{x:545.1,y:259.8},EH:{x:438.7,y:393.1},ER:{x:586.5,y:420},ES:{x:455.5,y:354.7},ET:{x:588.5,y:437.2},FI:{x:548.1,y:218.7},FJ:{x:974.9,y:511.5},FK:{x:308,y:632.6},FM:{x:897.3,y:442.1},FO:{x:455.5,y:241.2},FR:{x:481.6,y:316.1},GA:{x:507.4,y:465.2},GB:{x:465.9,y:274.3},GE:{x:596.5,y:332.3},GD:{x:301.8,y:428.9},GF:{x:325.8,y:451.9},GG:{x:467.7,y:303.5},GH:{x:472,y:440.6},GI:{x:459.9,y:354.7},GL:{x:356.7,y:126.7},GM:{x:431.9,y:425.1},GN:{x:443,y:435},GO:{x:607.6,y:495.4},GP:{x:302.3,y:417.1},GQ:{x:502.6,y:456.3},GR:{x:542.1,y:346.6},GS:{x:384.7,y:654.1},GT:{x:221.7,y:418.3},GU:{x:881.3,y:425.1},GW:{x:432.3,y:429.8},GY:{x:309.5,y:449.3},HK:{x:795.1,y:398.9},HM:{x:681.3,y:638.5},HN:{x:232.8,y:421.3},HR:{x:521.1,y:323.9},HT:{x:269.8,y:408.7},HU:{x:529.6,y:313.2},ID:{x:806.3,y:470},IE:{x:451.9,y:285.6},IL:{x:573.3,y:370.3},IM:{x:462.1,y:281.9},IN:{x:707.1,y:400.5},IO:{x:678.2,y:483.4},IQ:{x:597.4,y:364.2},IR:{x:625.5,y:366.2},IS:{x:421.5,y:221.6},IT:{x:510.1,y:333.2},JE:{x:468.9,y:304.6},JM:{x:258,y:411.5},JO:{x:579.1,y:370.9},JP:{x:853.1,y:356.5},JU:{x:594.9,y:511.2},KE:{x:581.2,y:461.8},KG:{x:684.6,y:336.3},KH:{x:769.5,y:427.6},KI:{x:516.3,y:473.5},KM:{x:598,y:496.3},KN:{x:299,y:414.1},KP:{x:832.8,y:339.4},KR:{x:835.4,y:355.3},XK:{x:533.5,y:331.4},KW:{x:608.2,y:377.3},KY:{x:248.7,y:407.4},KZ:{x:662.8,y:307.5},LA:{x:766.4,y:411.1},LB:{x:575.5,y:362.4},LC:{x:303.8,y:423.8},LI:{x:501.7,y:313.2},LK:{x:701.6,y:440.9},LR:{x:448.4,y:444.9},LS:{x:554.1,y:549.5},LT:{x:541.8,y:277.4},LU:{x:492,y:302.1},LV:{x:544,y:268.8},LY:{x:523.3,y:386.1},MA:{x:454.9,y:369},MC:{x:495.7,y:326.8},MD:{x:554.5,y:314},MG:{x:606.4,y:516.8},ME:{x:529.3,y:330.8},MF:{x:297.9,y:411.6},MH:{x:950,y:439.2},MK:{x:535.9,y:335},ML:{x:463.6,y:412.7},MO:{x:793.5,y:399.3},MM:{x:746.2,y:407.6},MN:{x:766.3,y:313.4},MP:{x:883.2,y:416.3},MQ:{x:303.6,y:421.6},MR:{x:444.2,y:402.6},MS:{x:300.4,y:415.6},MT:{x:515.2,y:355.3},MU:{x:636.4,y:520.6},MV:{x:681,y:452.5},MW:{x:571.1,y:500.3},MX:{x:187.1,y:394.1},MY:{x:782.1,y:451.4},MZ:{x:574.6,y:516.5},NA:{x:526.8,y:529.1},NC:{x:935.3,y:522.5},NE:{x:497.5,y:412.7},NF:{x:946.2,y:547.7},NG:{x:499.2,y:437.4},NI:{x:235.2,y:426.7},NL:{x:489.7,y:291.4},NO:{x:525.1,y:219.1},NP:{x:710.9,y:380.3},NR:{x:943.4,y:464.4},NU:{x:1008.5,y:517.1},NZ:{x:965.7,y:600.7},OM:{x:631.8,y:401.3},PA:{x:250.1,y:439.4},PE:{x:264.4,y:489},PF:{x:71,y:505},PG:{x:891.4,y:481.1},PH:{x:816.7,y:426.1},PK:{x:669.4,y:373.1},PL:{x:528.5,y:292.2},PM:{x:317,y:314.2},PN:{x:114.8,y:533},PR:{x:287.9,y:411.2},PS:{x:572.8,y:369},PT:{x:422.3,y:349.7},PW:{x:847.9,y:447.9},PY:{x:310.9,y:530.3},QA:{x:618.5,y:389.8},RE:{x:630.8,y:523.2},RO:{x:545,y:317.9},RS:{x:533.6,y:325},RU:{x:769.4,y:187.8},RW:{x:558.7,y:468.3},SA:{x:601.5,y:392.4},SB:{x:927.6,y:488.8},SC:{x:630.6,y:476},SD:{x:559.7,y:419},SE:{x:524.4,y:234.6},SG:{x:766.3,y:459.1},SH:{x:446.7,y:496.6},SI:{x:516.8,y:317.4},SJ:{x:509.3,y:121.1},SK:{x:530.2,y:306.9},SL:{x:441.8,y:439.3},SM:{x:509.9,y:326.1},SN:{x:434.3,y:422},SO:{x:604.5,y:448.5},SR:{x:317.7,y:452},SS:{x:558.3,y:440.9},ST:{x:494.4,y:460.5},SV:{x:225.4,y:424.1},SX:{x:297.9,y:411.8},SY:{x:584.5,y:359.1},SZ:{x:563.2,y:539.7},TC:{x:272.9,y:400.5},TD:{x:527.4,y:418.8},TF:{x:646.4,y:616.3},TG:{x:477.3,y:438.8},TH:{x:759.8,y:425.9},TJ:{x:674.8,y:344.9},TK:{x:1003,y:488},TL:{x:827.6,y:487.6},TM:{x:642.1,y:344.3},TN:{x:501.6,y:362.4},TO:{x:995.1,y:519.9},TR:{x:573.8,y:344.4},TT:{x:303.1,y:432.9},TV:{x:973.8,y:483.4},TW:{x:812,y:395.1},TZ:{x:572.8,y:480.8},UA:{x:562.3,y:307.5},UG:{x:565.5,y:459.1},"UM-DQ":{x:25.8,y:464},"UM-FQ":{x:990,y:462.3},"UM-HQ":{x:989.5,y:460.7},"UM-JQ":{x:1009.4,y:415.6},"UM-MQ":{x:987.4,y:380.9},"UM-WQ":{x:942.6,y:408.1},US:{x:143.6,y:291},UY:{x:318.3,y:559},UZ:{x:656.1,y:335.4},VA:{x:509.8,y:333.9},VC:{x:303,y:426.3},VE:{x:288,y:444.9},VG:{x:293.9,y:410.2},VI:{x:293,y:411.8},VN:{x:771.8,y:417.4},VU:{x:947,y:511},WF:{x:988,y:501.7},WS:{x:1002.2,y:501.6},YE:{x:611.1,y:418.6},YT:{x:601.6,y:499},ZA:{x:551.1,y:569},ZM:{x:553,y:500},ZW:{x:556.6,y:517.1}},i={aliases:{usa:`US`,"u s a":`US`,"u s":`US`,"united states of america":`US`,uk:`GB`,"u k":`GB`,"great britain":`GB`,england:`GB`,britain:`GB`,uae:`AE`,drc:`CD`,"dr congo":`CD`,"democratic republic of the congo":`CD`,"republic of the congo":`CG`,congo:`CG`,"congo brazzaville":`CG`,"south korea":`KR`,"republic of korea":`KR`,korea:`KR`,"north korea":`KP`,czechia:`CZ`,"cote d ivoire":`CI`,"ivory coast":`CI`,russia:`RU`,"viet nam":`VN`,brunei:`BN`,laos:`LA`,"lao pdr":`LA`,micronesia:`FM`,"north macedonia":`MK`,macedonia:`MK`,"cabo verde":`CV`,"cape verde":`CV`,eswatini:`SZ`,swaziland:`SZ`,burma:`MM`,palestine:`PS`,"east timor":`TL`,vatican:`VA`,turkiye:`TR`,curacao:`CW`,aland:`AX`,bonaire:`BQ`,"caribbean netherlands":`BQ`,holland:`NL`,"the netherlands":`NL`,"sint maarten":`SX`,"st maarten":`SX`,"saint maarten":`SX`,"saint martin french":`MF`,"saint martin fr":`MF`,taiwan:`TW`,"hong kong":`HK`,macau:`MO`,macao:`MO`,iran:`IR`,syria:`SY`,tanzania:`TZ`,bolivia:`BO`,moldova:`MD`,"virgin islands":`VI`,"us virgin islands":`VI`,"british virgin islands":`VG`,reunion:`RE`,"south sudan":`SS`},disambiguated:{MF:[`Saint-Martin`,`Saint Martin (French part)`],SX:[`Sint Maarten`,`St Maarten`,`Saint Maarten`]}},a=i.aliases,o=i.disambiguated;function s(e){return e.trim().normalize(`NFD`).replace(/[\u0300-\u036f]/g,``).toLowerCase().replace(/[''`]/g,``).replace(/[.,()]/g,` `).replace(/[^a-z0-9\s-]/g,` `).replace(/\s+/g,` `).trim()}function c(e){let t=[];return e.querySelectorAll(`path[id][title]`).forEach(e=>{let n=e.getAttribute(`id`)?.trim().toUpperCase(),r=e.getAttribute(`title`)?.trim();n&&r&&t.push({code:n,name:r})}),t.sort((e,t)=>e.name.localeCompare(t.name))}function l(e){let t=c(e),n=new Map;for(let{code:e,name:r}of t){let t=s(r),i=n.get(t)??[];i.includes(e)||i.push(e),n.set(t,i)}let r=new Map;for(let[e,t]of Object.entries(a))r.set(s(e),t.toUpperCase());for(let[e,t]of Object.entries(o))for(let n of t)r.set(s(n),e.toUpperCase());for(let{code:e,name:i}of t){r.set(s(e),e);let t=s(i);(n.get(t)?.length??0)===1&&r.set(t,e)}return r}function u(e,t){let n=e.trim();return n?t.get(s(n))??null:null}var d=e=>/^#([0-9a-fA-F]{3}){1,2}$/.test(e),f=e=>e.toString(16).padStart(2,`0`),p=(e,t)=>{if(!d(e))return e;let n=e.replace(`#`,``),r=n.length===3?n.split(``).map(e=>e+e).join(``):n,i=parseInt(r,16),a=Math.min(255,Math.max(0,(i>>16&255)+t)),o=Math.min(255,Math.max(0,(i>>8&255)+t)),s=Math.min(255,Math.max(0,(i&255)+t));return`#${f(a)}${f(o)}${f(s)}`};function m(e,t){let n=t.x-e.x,r=t.y-e.y,i=Math.sqrt(n*n+r*r),a=(e.y+t.y)/2,o=Math.max(Math.min(i*.35,220),15),s=e.x+n*.25,c=a-o,l=e.x+n*.75,u=a-o;return`M ${e.x} ${e.y} C ${s},${c} ${l},${u} ${t.x} ${t.y}`}function h({backgroundColor:i,countryColor:a=`#093C5D`,svgUrl:o,className:s,showConnections:c=!0,connectionBase:d=`BD`,connectedCountries:f=[`US`,`IN`],onCountryHover:h,onCountryClick:g,onConnectionDotHover:_,onConnectionDotClick:v}){let[y,b]=(0,e.useState)(``),[x,S]=(0,e.useState)({name:``,x:0,y:0,visible:!1}),[C,w]=(0,e.useState)({name:``,x:0,y:0,visible:!1}),[T,E]=(0,e.useState)(1),[D,O]=(0,e.useState)({x:0,y:0}),[k,A]=(0,e.useState)(!1),j=(0,e.useRef)(null),M=(0,e.useRef)({isPanning:!1,startX:0,startY:0,originX:0,originY:0,moved:!1}),N=(0,e.useMemo)(()=>({hover:p(a,24),selected:p(a,-24),stroke:p(a,-36)}),[a]);(0,e.useEffect)(()=>{let e=!0;return(async()=>{try{let t;if(o){let e=await fetch(o);if(!e.ok)throw Error(`Failed to fetch SVG: ${e.status}`);t=await e.text()}else t=n;if(!e)return;let i=new DOMParser().parseFromString(t,`image/svg+xml`),a=i.querySelector(`svg`);if(!a){b(``);return}if(!a.getAttribute(`viewBox`)){let e=parseFloat(a.getAttribute(`width`)||``),t=parseFloat(a.getAttribute(`height`)||``);Number.isFinite(e)&&Number.isFinite(t)&&a.setAttribute(`viewBox`,`0 0 ${e} ${t}`)}if(a.removeAttribute(`width`),a.removeAttribute(`height`),a.setAttribute(`class`,`map-svg`),a.querySelectorAll(`path[title]`).forEach(e=>{let t=e.getAttribute(`title`)||``;t&&(e.classList.add(`country`),e.setAttribute(`data-name`,t))}),c){let e=l(a),t=u(d,e),n=t?r[t]:void 0;if(t&&n){let o=e=>{let t=i.createElementNS(`http://www.w3.org/2000/svg`,`path`);return t.setAttribute(`d`,e),t.setAttribute(`class`,`connection-line`),t.setAttribute(`fill`,`none`),t},s=e=>a.querySelector(`#${e}`)?.getAttribute(`title`)||e,c=(e,t,n,r,a)=>{let o=i.createElementNS(`http://www.w3.org/2000/svg`,`circle`);return o.setAttribute(`cx`,String(e)),o.setAttribute(`cy`,String(t)),o.setAttribute(`r`,`3`),o.setAttribute(`class`,n),o.setAttribute(`data-country-code`,r),o.setAttribute(`data-country-name`,a),o},l=new Set;for(let i of f){let d=u(i,e);if(!d||d===t)continue;let f=r[d];if(!f)continue;let p=m(f,n);if(a.appendChild(o(p)),!l.has(d)){let e=s(d);a.appendChild(c(f.x,f.y,`connection-dot connection-dot-start`,d,e)),l.add(d)}}if(!l.has(t)){let e=s(t);a.appendChild(c(n.x,n.y,`connection-dot connection-dot-end`,t,e)),l.add(t)}}}b(new XMLSerializer().serializeToString(a))}catch{e&&b(``)}})(),()=>{e=!1}},[o,c,d,f]);let P=e=>!e||!(e instanceof Element)?null:e.closest(`[data-name]`),F=e=>!e||!(e instanceof Element)?null:e.closest(`.connection-dot`),I=e=>{let t=j.current?.getBoundingClientRect();return t?{x:e.clientX-t.left,y:e.clientY-t.top}:{x:0,y:0}},L=()=>{let e=j.current;if(!e)return;let t=e.querySelector(`.country.is-selected`);t&&t.classList.remove(`is-selected`)},R=e=>{if(M.current.isPanning){let t=e.clientX-M.current.startX,n=e.clientY-M.current.startY;O({x:M.current.originX+t,y:M.current.originY+n}),Math.sqrt(t*t+n*n)>5&&(M.current.moved=!0),S(e=>({...e,visible:!1}));return}let t=F(e.target),n=t?.getAttribute(`data-country-code`),r=t?.getAttribute(`data-country-name`);if(n&&r){if(_){let{x:t,y:i}=I(e);_(n,r,t,i)}S(e=>({...e,visible:!1}));return}let i=P(e.target),a=i?.dataset.name;if(!a){S(e=>({...e,visible:!1}));return}let{x:o,y:s}=I(e);if(h){h(i.getAttribute(`id`)||``,a,o,s),S(e=>({...e,visible:!1}));return}S({name:a,x:o,y:s,visible:!0})},z=()=>{S(e=>({...e,visible:!1})),M.current.isPanning=!1,A(!1)},B=e=>{if(M.current.moved){M.current.moved=!1;return}let t=F(e.target),n=t?.getAttribute(`data-country-code`),r=t?.getAttribute(`data-country-name`);if(n&&r){if(v){let{x:t,y:i}=I(e);v(n,r,t,i)}return}let i=P(e.target),a=i?.dataset.name;if(!a){L(),w(e=>({...e,visible:!1}));return}let{x:o,y:s}=I(e);if(g){g(i.getAttribute(`id`)||``,a,o,s),w(e=>({...e,visible:!1}));return}w({name:a,x:o,y:s,visible:!0}),L(),i.classList.add(`is-selected`)},V=e=>{e.preventDefault();let t=e.deltaY>0?-1:1;E(e=>{let n=e+t*.1;return Math.min(3,Math.max(1,Number(n.toFixed(2))))})},H=e=>{if(e.button!==0)return;let t=F(e.target),n=P(e.target);if(t||n){M.current.isPanning=!1,M.current.moved=!1;return}e.currentTarget.setPointerCapture(e.pointerId),M.current.isPanning=!0,M.current.startX=e.clientX,M.current.startY=e.clientY,M.current.originX=D.x,M.current.originY=D.y,M.current.moved=!1,A(!0)},U=()=>{M.current.isPanning=!1,A(!1)},W={"--map-background":i||`transparent`,"--country-fill":a,"--country-hover":N.hover,"--country-selected":N.selected,"--country-stroke":N.stroke},G=[`map-container`,s].filter(Boolean).join(` `);return(0,t.jsxs)(`div`,{className:k?`${G} is-panning`.trim():G,style:W,ref:j,onPointerMove:R,onPointerLeave:z,onPointerDown:H,onPointerUp:U,onClick:B,onWheel:V,role:`img`,"aria-label":`World map with clickable countries`,children:[y?(0,t.jsx)(`div`,{className:`map-viewport`,style:{transform:`translate(${D.x}px, ${D.y}px) scale(${T})`},children:(0,t.jsx)(`div`,{className:`map-svg-wrap`,dangerouslySetInnerHTML:{__html:y}})}):(0,t.jsx)(`div`,{className:`map-loading`,children:`Loading map...`}),x.visible&&(0,t.jsx)(`div`,{className:`map-tooltip`,style:{left:x.x,top:x.y},role:`status`,children:x.name}),C.visible&&(0,t.jsx)(`div`,{className:`map-tooltip is-pinned`,style:{left:C.x,top:C.y},role:`status`,children:C.name})]})}exports.WorldMap=h,exports.default=h,exports.buildCountryLookup=l,exports.listMapCountries=c,exports.normalizeCountryName=s,exports.resolveCountryCode=u;
1038
+ `,r={AD:{x:479.3,y:331.5},AE:{x:626.4,y:392.9},AF:{x:664.9,y:361.8},AG:{x:301.5,y:413.8},AI:{x:297.9,y:411.2},AL:{x:531.5,y:336.6},AM:{x:601.2,y:340.6},AO:{x:525.1,y:494.6},AR:{x:296.3,y:586.5},AS:{x:1006.2,y:503.2},AT:{x:512.3,y:310.9},AU:{x:856.4,y:568.8},AW:{x:278.5,y:427.7},AX:{x:531.2,y:250.9},AZ:{x:608.4,y:340.3},BA:{x:524.5,y:326.1},BB:{x:307.8,y:425.8},BD:{x:728.4,y:394.8},BE:{x:487.4,y:299},BF:{x:470.5,y:428.5},BG:{x:546.4,y:330.7},BH:{x:616.7,y:387.7},BI:{x:558.8,y:472.4},BJ:{x:481.3,y:436.8},BL:{x:298.5,y:412.2},BN:{x:796.8,y:450.3},BO:{x:296.5,y:509.3},BM:{x:293.1,y:367.5},BQ:{x:290.6,y:421},BR:{x:322.2,y:505.6},BS:{x:262,y:394},BT:{x:728.6,y:383.1},BV:{x:484.5,y:644.8},BW:{x:544.1,y:527},BY:{x:553.3,y:284.1},BZ:{x:226.5,y:414.3},CA:{x:203.1,y:173.2},CC:{x:746.8,y:497.1},CD:{x:535.9,y:474.4},CF:{x:533.6,y:444.3},CG:{x:516.6,y:464.8},CH:{x:497.9,y:314.7},CI:{x:459.3,y:441.8},CK:{x:26.4,y:523.5},CL:{x:228.1,y:582.3},CM:{x:509.6,y:442.2},CN:{x:767.3,y:348.2},CO:{x:270.2,y:451.4},CR:{x:238.5,y:435.9},CU:{x:251.7,y:401.4},CV:{x:407.5,y:417.7},CW:{x:281.4,y:428.6},CX:{x:771.4,y:492.4},CY:{x:568.7,y:358.2},CZ:{x:518.3,y:302},DE:{x:504.2,y:295.3},DJ:{x:594.4,y:429.7},DK:{x:507.5,y:272.2},DM:{x:302.7,y:419.4},DO:{x:278,y:409.6},DZ:{x:479.5,y:380.2},EC:{x:240.7,y:467.9},EG:{x:561.3,y:384.9},EE:{x:545.1,y:259.8},EH:{x:438.7,y:393.1},ER:{x:586.5,y:420},ES:{x:455.5,y:354.7},ET:{x:588.5,y:437.2},FI:{x:548.1,y:218.7},FJ:{x:974.9,y:511.5},FK:{x:308,y:632.6},FM:{x:897.3,y:442.1},FO:{x:455.5,y:241.2},FR:{x:481.6,y:316.1},GA:{x:507.4,y:465.2},GB:{x:465.9,y:274.3},GE:{x:596.5,y:332.3},GD:{x:301.8,y:428.9},GF:{x:325.8,y:451.9},GG:{x:467.7,y:303.5},GH:{x:472,y:440.6},GI:{x:459.9,y:354.7},GL:{x:356.7,y:126.7},GM:{x:431.9,y:425.1},GN:{x:443,y:435},GO:{x:607.6,y:495.4},GP:{x:302.3,y:417.1},GQ:{x:502.6,y:456.3},GR:{x:542.1,y:346.6},GS:{x:384.7,y:654.1},GT:{x:221.7,y:418.3},GU:{x:881.3,y:425.1},GW:{x:432.3,y:429.8},GY:{x:309.5,y:449.3},HK:{x:795.1,y:398.9},HM:{x:681.3,y:638.5},HN:{x:232.8,y:421.3},HR:{x:521.1,y:323.9},HT:{x:269.8,y:408.7},HU:{x:529.6,y:313.2},ID:{x:806.3,y:470},IE:{x:451.9,y:285.6},IL:{x:573.3,y:370.3},IM:{x:462.1,y:281.9},IN:{x:707.1,y:400.5},IO:{x:678.2,y:483.4},IQ:{x:597.4,y:364.2},IR:{x:625.5,y:366.2},IS:{x:421.5,y:221.6},IT:{x:510.1,y:333.2},JE:{x:468.9,y:304.6},JM:{x:258,y:411.5},JO:{x:579.1,y:370.9},JP:{x:853.1,y:356.5},JU:{x:594.9,y:511.2},KE:{x:581.2,y:461.8},KG:{x:684.6,y:336.3},KH:{x:769.5,y:427.6},KI:{x:516.3,y:473.5},KM:{x:598,y:496.3},KN:{x:299,y:414.1},KP:{x:832.8,y:339.4},KR:{x:835.4,y:355.3},XK:{x:533.5,y:331.4},KW:{x:608.2,y:377.3},KY:{x:248.7,y:407.4},KZ:{x:662.8,y:307.5},LA:{x:766.4,y:411.1},LB:{x:575.5,y:362.4},LC:{x:303.8,y:423.8},LI:{x:501.7,y:313.2},LK:{x:701.6,y:440.9},LR:{x:448.4,y:444.9},LS:{x:554.1,y:549.5},LT:{x:541.8,y:277.4},LU:{x:492,y:302.1},LV:{x:544,y:268.8},LY:{x:523.3,y:386.1},MA:{x:454.9,y:369},MC:{x:495.7,y:326.8},MD:{x:554.5,y:314},MG:{x:606.4,y:516.8},ME:{x:529.3,y:330.8},MF:{x:297.9,y:411.6},MH:{x:950,y:439.2},MK:{x:535.9,y:335},ML:{x:463.6,y:412.7},MO:{x:793.5,y:399.3},MM:{x:746.2,y:407.6},MN:{x:766.3,y:313.4},MP:{x:883.2,y:416.3},MQ:{x:303.6,y:421.6},MR:{x:444.2,y:402.6},MS:{x:300.4,y:415.6},MT:{x:515.2,y:355.3},MU:{x:636.4,y:520.6},MV:{x:681,y:452.5},MW:{x:571.1,y:500.3},MX:{x:187.1,y:394.1},MY:{x:782.1,y:451.4},MZ:{x:574.6,y:516.5},NA:{x:526.8,y:529.1},NC:{x:935.3,y:522.5},NE:{x:497.5,y:412.7},NF:{x:946.2,y:547.7},NG:{x:499.2,y:437.4},NI:{x:235.2,y:426.7},NL:{x:489.7,y:291.4},NO:{x:525.1,y:219.1},NP:{x:710.9,y:380.3},NR:{x:943.4,y:464.4},NU:{x:1008.5,y:517.1},NZ:{x:965.7,y:600.7},OM:{x:631.8,y:401.3},PA:{x:250.1,y:439.4},PE:{x:264.4,y:489},PF:{x:71,y:505},PG:{x:891.4,y:481.1},PH:{x:816.7,y:426.1},PK:{x:669.4,y:373.1},PL:{x:528.5,y:292.2},PM:{x:317,y:314.2},PN:{x:114.8,y:533},PR:{x:287.9,y:411.2},PS:{x:572.8,y:369},PT:{x:422.3,y:349.7},PW:{x:847.9,y:447.9},PY:{x:310.9,y:530.3},QA:{x:618.5,y:389.8},RE:{x:630.8,y:523.2},RO:{x:545,y:317.9},RS:{x:533.6,y:325},RU:{x:769.4,y:187.8},RW:{x:558.7,y:468.3},SA:{x:601.5,y:392.4},SB:{x:927.6,y:488.8},SC:{x:630.6,y:476},SD:{x:559.7,y:419},SE:{x:524.4,y:234.6},SG:{x:766.3,y:459.1},SH:{x:446.7,y:496.6},SI:{x:516.8,y:317.4},SJ:{x:509.3,y:121.1},SK:{x:530.2,y:306.9},SL:{x:441.8,y:439.3},SM:{x:509.9,y:326.1},SN:{x:434.3,y:422},SO:{x:604.5,y:448.5},SR:{x:317.7,y:452},SS:{x:558.3,y:440.9},ST:{x:494.4,y:460.5},SV:{x:225.4,y:424.1},SX:{x:297.9,y:411.8},SY:{x:584.5,y:359.1},SZ:{x:563.2,y:539.7},TC:{x:272.9,y:400.5},TD:{x:527.4,y:418.8},TF:{x:646.4,y:616.3},TG:{x:477.3,y:438.8},TH:{x:759.8,y:425.9},TJ:{x:674.8,y:344.9},TK:{x:1003,y:488},TL:{x:827.6,y:487.6},TM:{x:642.1,y:344.3},TN:{x:501.6,y:362.4},TO:{x:995.1,y:519.9},TR:{x:573.8,y:344.4},TT:{x:303.1,y:432.9},TV:{x:973.8,y:483.4},TW:{x:812,y:395.1},TZ:{x:572.8,y:480.8},UA:{x:562.3,y:307.5},UG:{x:565.5,y:459.1},"UM-DQ":{x:25.8,y:464},"UM-FQ":{x:990,y:462.3},"UM-HQ":{x:989.5,y:460.7},"UM-JQ":{x:1009.4,y:415.6},"UM-MQ":{x:987.4,y:380.9},"UM-WQ":{x:942.6,y:408.1},US:{x:143.6,y:291},UY:{x:318.3,y:559},UZ:{x:656.1,y:335.4},VA:{x:509.8,y:333.9},VC:{x:303,y:426.3},VE:{x:288,y:444.9},VG:{x:293.9,y:410.2},VI:{x:293,y:411.8},VN:{x:771.8,y:417.4},VU:{x:947,y:511},WF:{x:988,y:501.7},WS:{x:1002.2,y:501.6},YE:{x:611.1,y:418.6},YT:{x:601.6,y:499},ZA:{x:551.1,y:569},ZM:{x:553,y:500},ZW:{x:556.6,y:517.1}},i={aliases:{usa:`US`,unitedstatesofamerica:`US`,uk:`GB`,greatbritain:`GB`,england:`GB`,britain:`GB`,uae:`AE`,drc:`CD`,drcongo:`CD`,democraticrepublicofthecongo:`CD`,republicofthecongo:`CG`,congo:`CG`,congobrazzaville:`CG`,southkorea:`KR`,republicofkorea:`KR`,korea:`KR`,northkorea:`KP`,czechia:`CZ`,cotedivoire:`CI`,ivorycoast:`CI`,russia:`RU`,vietnam:`VN`,brunei:`BN`,laos:`LA`,laopdr:`LA`,micronesia:`FM`,northmacedonia:`MK`,macedonia:`MK`,caboverde:`CV`,capeverde:`CV`,eswatini:`SZ`,swaziland:`SZ`,burma:`MM`,palestine:`PS`,easttimor:`TL`,vatican:`VA`,turkiye:`TR`,curacao:`CW`,aland:`AX`,bonaire:`BQ`,caribbeannetherlands:`BQ`,holland:`NL`,thenetherlands:`NL`,sintmaarten:`SX`,stmaarten:`SX`,saintmaarten:`SX`,saintmartinfrench:`MF`,saintmartinfr:`MF`,taiwan:`TW`,hongkong:`HK`,macau:`MO`,macao:`MO`,iran:`IR`,syria:`SY`,tanzania:`TZ`,bolivia:`BO`,moldova:`MD`,virginislands:`VI`,usvirginislands:`VI`,britishvirginislands:`VG`,reunion:`RE`,southsudan:`SS`},disambiguated:{MF:[`saintmartin`,`saintmartinfrenchpart`],SX:[`sintmaarten`,`stmaarten`,`saintmaarten`]}},a=i.aliases,o=i.disambiguated;function s(e){return e.normalize(`NFD`).replace(/[\u0300-\u036f]/g,``).toLowerCase().replace(/[^a-z0-9]/g,``)}function c(e){let t=[];return e.querySelectorAll(`path[id][title]`).forEach(e=>{let n=e.getAttribute(`id`)?.trim().toUpperCase(),r=e.getAttribute(`title`)?.trim();n&&r&&t.push({code:n,name:r})}),t.sort((e,t)=>e.name.localeCompare(t.name))}function l(e){let t=c(e),n=new Map;for(let{code:e,name:r}of t){let t=s(r),i=n.get(t)??[];i.includes(e)||i.push(e),n.set(t,i)}let r=new Map;for(let[e,t]of Object.entries(a))r.set(s(e),t.toUpperCase());for(let[e,t]of Object.entries(o))for(let n of t)r.set(s(n),e.toUpperCase());for(let{code:e,name:i}of t){r.set(s(e),e);let t=s(i);(n.get(t)?.length??0)===1&&r.set(t,e)}return r}function u(e,t){let n=e.trim();return n?t.get(s(n))??null:null}var d=e=>/^#([0-9a-fA-F]{3}){1,2}$/.test(e),f=e=>e.toString(16).padStart(2,`0`),p=(e,t)=>{if(!d(e))return e;let n=e.replace(`#`,``),r=n.length===3?n.split(``).map(e=>e+e).join(``):n,i=parseInt(r,16),a=Math.min(255,Math.max(0,(i>>16&255)+t)),o=Math.min(255,Math.max(0,(i>>8&255)+t)),s=Math.min(255,Math.max(0,(i&255)+t));return`#${f(a)}${f(o)}${f(s)}`};function m(e,t){let n=t.x-e.x,r=t.y-e.y,i=Math.sqrt(n*n+r*r),a=(e.y+t.y)/2,o=Math.max(Math.min(i*.35,220),15),s=e.x+n*.25,c=a-o,l=e.x+n*.75,u=a-o;return`M ${e.x} ${e.y} C ${s},${c} ${l},${u} ${t.x} ${t.y}`}function h({backgroundColor:i,countryColor:a=`#093C5D`,svgUrl:o,className:s,showConnections:c=!0,connectionBase:d=`BD`,connectedCountries:f=[`US`,`IN`],onCountryHover:h,onCountryClick:g,onConnectionDotHover:_,onConnectionDotClick:v}){let[y,b]=(0,e.useState)(``),[x,S]=(0,e.useState)({name:``,x:0,y:0,visible:!1}),[C,w]=(0,e.useState)({name:``,x:0,y:0,visible:!1}),[T,E]=(0,e.useState)(1),[D,O]=(0,e.useState)({x:0,y:0}),[k,A]=(0,e.useState)(!1),j=(0,e.useRef)(null),M=(0,e.useRef)({isPanning:!1,startX:0,startY:0,originX:0,originY:0,moved:!1}),N=(0,e.useMemo)(()=>({hover:p(a,24),selected:p(a,-24),stroke:p(a,-36)}),[a]);(0,e.useEffect)(()=>{let e=!0;return(async()=>{try{let t;if(o){let e=await fetch(o);if(!e.ok)throw Error(`Failed to fetch SVG: ${e.status}`);t=await e.text()}else t=n;if(!e)return;let i=new DOMParser().parseFromString(t,`image/svg+xml`),a=i.querySelector(`svg`);if(!a){b(``);return}if(!a.getAttribute(`viewBox`)){let e=parseFloat(a.getAttribute(`width`)||``),t=parseFloat(a.getAttribute(`height`)||``);Number.isFinite(e)&&Number.isFinite(t)&&a.setAttribute(`viewBox`,`0 0 ${e} ${t}`)}if(a.removeAttribute(`width`),a.removeAttribute(`height`),a.setAttribute(`class`,`map-svg`),a.querySelectorAll(`path[title]`).forEach(e=>{let t=e.getAttribute(`title`)||``;t&&(e.classList.add(`country`),e.setAttribute(`data-name`,t))}),c){let e=l(a),t=u(d,e),n=t?r[t]:void 0;if(t&&n){let o=e=>{let t=i.createElementNS(`http://www.w3.org/2000/svg`,`path`);return t.setAttribute(`d`,e),t.setAttribute(`class`,`connection-line`),t.setAttribute(`fill`,`none`),t},s=e=>a.querySelector(`#${e}`)?.getAttribute(`title`)||e,c=(e,t,n,r,a)=>{let o=i.createElementNS(`http://www.w3.org/2000/svg`,`circle`);return o.setAttribute(`cx`,String(e)),o.setAttribute(`cy`,String(t)),o.setAttribute(`r`,`3`),o.setAttribute(`class`,n),o.setAttribute(`data-country-code`,r),o.setAttribute(`data-country-name`,a),o},l=new Set;for(let i of f){let d=u(i,e);if(!d||d===t)continue;let f=r[d];if(!f)continue;let p=m(f,n);if(a.appendChild(o(p)),!l.has(d)){let e=s(d);a.appendChild(c(f.x,f.y,`connection-dot connection-dot-start`,d,e)),l.add(d)}}if(!l.has(t)){let e=s(t);a.appendChild(c(n.x,n.y,`connection-dot connection-dot-end`,t,e)),l.add(t)}}}b(new XMLSerializer().serializeToString(a))}catch{e&&b(``)}})(),()=>{e=!1}},[o,c,d,f]);let P=e=>!e||!(e instanceof Element)?null:e.closest(`[data-name]`),F=e=>!e||!(e instanceof Element)?null:e.closest(`.connection-dot`),I=e=>{let t=j.current?.getBoundingClientRect();return t?{x:e.clientX-t.left,y:e.clientY-t.top}:{x:0,y:0}},L=()=>{let e=j.current;if(!e)return;let t=e.querySelector(`.country.is-selected`);t&&t.classList.remove(`is-selected`)},R=e=>{if(M.current.isPanning){let t=e.clientX-M.current.startX,n=e.clientY-M.current.startY;O({x:M.current.originX+t,y:M.current.originY+n}),Math.sqrt(t*t+n*n)>5&&(M.current.moved=!0),S(e=>({...e,visible:!1}));return}let t=F(e.target),n=t?.getAttribute(`data-country-code`),r=t?.getAttribute(`data-country-name`);if(n&&r){if(_){let{x:t,y:i}=I(e);_(n,r,t,i)}S(e=>({...e,visible:!1}));return}let i=P(e.target),a=i?.dataset.name;if(!a){S(e=>({...e,visible:!1}));return}let{x:o,y:s}=I(e);if(h){h(i.getAttribute(`id`)||``,a,o,s),S(e=>({...e,visible:!1}));return}S({name:a,x:o,y:s,visible:!0})},z=()=>{S(e=>({...e,visible:!1})),M.current.isPanning=!1,A(!1)},B=e=>{if(M.current.moved){M.current.moved=!1;return}let t=F(e.target),n=t?.getAttribute(`data-country-code`),r=t?.getAttribute(`data-country-name`);if(n&&r){if(v){let{x:t,y:i}=I(e);v(n,r,t,i)}return}let i=P(e.target),a=i?.dataset.name;if(!a){L(),w(e=>({...e,visible:!1}));return}let{x:o,y:s}=I(e);if(g){g(i.getAttribute(`id`)||``,a,o,s),w(e=>({...e,visible:!1}));return}w({name:a,x:o,y:s,visible:!0}),L(),i.classList.add(`is-selected`)},V=e=>{e.preventDefault();let t=e.deltaY>0?-1:1;E(e=>{let n=e+t*.1;return Math.min(3,Math.max(1,Number(n.toFixed(2))))})},H=e=>{if(e.button!==0)return;let t=F(e.target),n=P(e.target);if(t||n){M.current.isPanning=!1,M.current.moved=!1;return}e.currentTarget.setPointerCapture(e.pointerId),M.current.isPanning=!0,M.current.startX=e.clientX,M.current.startY=e.clientY,M.current.originX=D.x,M.current.originY=D.y,M.current.moved=!1,A(!0)},U=()=>{M.current.isPanning=!1,A(!1)},W={"--map-background":i||`transparent`,"--country-fill":a,"--country-hover":N.hover,"--country-selected":N.selected,"--country-stroke":N.stroke},G=[`map-container`,s].filter(Boolean).join(` `);return(0,t.jsxs)(`div`,{className:k?`${G} is-panning`.trim():G,style:W,ref:j,onPointerMove:R,onPointerLeave:z,onPointerDown:H,onPointerUp:U,onClick:B,onWheel:V,role:`img`,"aria-label":`World map with clickable countries`,children:[y?(0,t.jsx)(`div`,{className:`map-viewport`,style:{transform:`translate(${D.x}px, ${D.y}px) scale(${T})`},children:(0,t.jsx)(`div`,{className:`map-svg-wrap`,dangerouslySetInnerHTML:{__html:y}})}):(0,t.jsx)(`div`,{className:`map-loading`,children:`Loading map...`}),x.visible&&(0,t.jsx)(`div`,{className:`map-tooltip`,style:{left:x.x,top:x.y},role:`status`,children:x.name}),C.visible&&(0,t.jsx)(`div`,{className:`map-tooltip is-pinned`,style:{left:C.x,top:C.y},role:`status`,children:C.name})]})}exports.WorldMap=h,exports.default=h,exports.buildCountryLookup=l,exports.listMapCountries=c,exports.normalizeCountryName=s,exports.resolveCountryCode=u;
@@ -1029,58 +1029,55 @@ var o = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n<!-- Crea
1029
1029
  }, c = {
1030
1030
  aliases: {
1031
1031
  usa: "US",
1032
- "u s a": "US",
1033
- "u s": "US",
1034
- "united states of america": "US",
1032
+ unitedstatesofamerica: "US",
1035
1033
  uk: "GB",
1036
- "u k": "GB",
1037
- "great britain": "GB",
1034
+ greatbritain: "GB",
1038
1035
  england: "GB",
1039
1036
  britain: "GB",
1040
1037
  uae: "AE",
1041
1038
  drc: "CD",
1042
- "dr congo": "CD",
1043
- "democratic republic of the congo": "CD",
1044
- "republic of the congo": "CG",
1039
+ drcongo: "CD",
1040
+ democraticrepublicofthecongo: "CD",
1041
+ republicofthecongo: "CG",
1045
1042
  congo: "CG",
1046
- "congo brazzaville": "CG",
1047
- "south korea": "KR",
1048
- "republic of korea": "KR",
1043
+ congobrazzaville: "CG",
1044
+ southkorea: "KR",
1045
+ republicofkorea: "KR",
1049
1046
  korea: "KR",
1050
- "north korea": "KP",
1047
+ northkorea: "KP",
1051
1048
  czechia: "CZ",
1052
- "cote d ivoire": "CI",
1053
- "ivory coast": "CI",
1049
+ cotedivoire: "CI",
1050
+ ivorycoast: "CI",
1054
1051
  russia: "RU",
1055
- "viet nam": "VN",
1052
+ vietnam: "VN",
1056
1053
  brunei: "BN",
1057
1054
  laos: "LA",
1058
- "lao pdr": "LA",
1055
+ laopdr: "LA",
1059
1056
  micronesia: "FM",
1060
- "north macedonia": "MK",
1057
+ northmacedonia: "MK",
1061
1058
  macedonia: "MK",
1062
- "cabo verde": "CV",
1063
- "cape verde": "CV",
1059
+ caboverde: "CV",
1060
+ capeverde: "CV",
1064
1061
  eswatini: "SZ",
1065
1062
  swaziland: "SZ",
1066
1063
  burma: "MM",
1067
1064
  palestine: "PS",
1068
- "east timor": "TL",
1065
+ easttimor: "TL",
1069
1066
  vatican: "VA",
1070
1067
  turkiye: "TR",
1071
1068
  curacao: "CW",
1072
1069
  aland: "AX",
1073
1070
  bonaire: "BQ",
1074
- "caribbean netherlands": "BQ",
1071
+ caribbeannetherlands: "BQ",
1075
1072
  holland: "NL",
1076
- "the netherlands": "NL",
1077
- "sint maarten": "SX",
1078
- "st maarten": "SX",
1079
- "saint maarten": "SX",
1080
- "saint martin french": "MF",
1081
- "saint martin fr": "MF",
1073
+ thenetherlands: "NL",
1074
+ sintmaarten: "SX",
1075
+ stmaarten: "SX",
1076
+ saintmaarten: "SX",
1077
+ saintmartinfrench: "MF",
1078
+ saintmartinfr: "MF",
1082
1079
  taiwan: "TW",
1083
- "hong kong": "HK",
1080
+ hongkong: "HK",
1084
1081
  macau: "MO",
1085
1082
  macao: "MO",
1086
1083
  iran: "IR",
@@ -1088,23 +1085,23 @@ var o = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n<!-- Crea
1088
1085
  tanzania: "TZ",
1089
1086
  bolivia: "BO",
1090
1087
  moldova: "MD",
1091
- "virgin islands": "VI",
1092
- "us virgin islands": "VI",
1093
- "british virgin islands": "VG",
1088
+ virginislands: "VI",
1089
+ usvirginislands: "VI",
1090
+ britishvirginislands: "VG",
1094
1091
  reunion: "RE",
1095
- "south sudan": "SS"
1092
+ southsudan: "SS"
1096
1093
  },
1097
1094
  disambiguated: {
1098
- MF: ["Saint-Martin", "Saint Martin (French part)"],
1095
+ MF: ["saintmartin", "saintmartinfrenchpart"],
1099
1096
  SX: [
1100
- "Sint Maarten",
1101
- "St Maarten",
1102
- "Saint Maarten"
1097
+ "sintmaarten",
1098
+ "stmaarten",
1099
+ "saintmaarten"
1103
1100
  ]
1104
1101
  }
1105
1102
  }, l = c.aliases, u = c.disambiguated;
1106
1103
  function d(e) {
1107
- return e.trim().normalize("NFD").replace(/[\u0300-\u036f]/g, "").toLowerCase().replace(/[''`]/g, "").replace(/[.,()]/g, " ").replace(/[^a-z0-9\s-]/g, " ").replace(/\s+/g, " ").trim();
1104
+ return e.normalize("NFD").replace(/[\u0300-\u036f]/g, "").toLowerCase().replace(/[^a-z0-9]/g, "");
1108
1105
  }
1109
1106
  function f(e) {
1110
1107
  let t = [];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "world-map-svg",
3
- "version": "0.5.0",
3
+ "version": "0.5.1",
4
4
  "description": "Interactive SVG world map React component",
5
5
  "license": "MIT",
6
6
  "keywords": [