tempest-react-sdk 0.17.0 → 0.19.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/bin/tempest.mjs +445 -35
- package/dist/AC-Brw7ZrEs.cjs +2 -0
- package/dist/AC-Brw7ZrEs.cjs.map +1 -0
- package/dist/AC-DLl3Z4oj.js +12 -0
- package/dist/AC-DLl3Z4oj.js.map +1 -0
- package/dist/AL-DPGoZjht.cjs +2 -0
- package/dist/AL-DPGoZjht.cjs.map +1 -0
- package/dist/AL-gswGaWlj.js +12 -0
- package/dist/AL-gswGaWlj.js.map +1 -0
- package/dist/AM-QN1eL4Tn.js +12 -0
- package/dist/AM-QN1eL4Tn.js.map +1 -0
- package/dist/AM-VqNWvsI-.cjs +2 -0
- package/dist/AM-VqNWvsI-.cjs.map +1 -0
- package/dist/AP-CPvBa_FK.cjs +2 -0
- package/dist/AP-CPvBa_FK.cjs.map +1 -0
- package/dist/AP-CRAbh1js.js +12 -0
- package/dist/AP-CRAbh1js.js.map +1 -0
- package/dist/BA-CKy_HnnV.js +12 -0
- package/dist/BA-CKy_HnnV.js.map +1 -0
- package/dist/BA-DoMQ6slK.cjs +2 -0
- package/dist/BA-DoMQ6slK.cjs.map +1 -0
- package/dist/CE-Ca-XMDFW.js +12 -0
- package/dist/CE-Ca-XMDFW.js.map +1 -0
- package/dist/CE-as-pGPQa.cjs +2 -0
- package/dist/CE-as-pGPQa.cjs.map +1 -0
- package/dist/DF-8kzFoovF.js +12 -0
- package/dist/DF-8kzFoovF.js.map +1 -0
- package/dist/DF-Wr8WNxSX.cjs +2 -0
- package/dist/DF-Wr8WNxSX.cjs.map +1 -0
- package/dist/ES-B4uWNG6s.js +12 -0
- package/dist/ES-B4uWNG6s.js.map +1 -0
- package/dist/ES-wKVjD_TM.cjs +2 -0
- package/dist/ES-wKVjD_TM.cjs.map +1 -0
- package/dist/GO-D4m4rOqy.cjs +2 -0
- package/dist/GO-D4m4rOqy.cjs.map +1 -0
- package/dist/GO-DuaAgIfo.js +12 -0
- package/dist/GO-DuaAgIfo.js.map +1 -0
- package/dist/MA-BmaUZZKe.cjs +2 -0
- package/dist/MA-BmaUZZKe.cjs.map +1 -0
- package/dist/MA-wOyPxG_M.js +12 -0
- package/dist/MA-wOyPxG_M.js.map +1 -0
- package/dist/MG-BYsqJd-S.js +12 -0
- package/dist/MG-BYsqJd-S.js.map +1 -0
- package/dist/MG-BchdfJXp.cjs +2 -0
- package/dist/MG-BchdfJXp.cjs.map +1 -0
- package/dist/MS-DZkgtN_7.js +12 -0
- package/dist/MS-DZkgtN_7.js.map +1 -0
- package/dist/MS-Dz9lDw37.cjs +2 -0
- package/dist/MS-Dz9lDw37.cjs.map +1 -0
- package/dist/MT-BkVchoah.cjs +2 -0
- package/dist/MT-BkVchoah.cjs.map +1 -0
- package/dist/MT-GmMwFWw2.js +12 -0
- package/dist/MT-GmMwFWw2.js.map +1 -0
- package/dist/PA-C2FpT6Ew.cjs +2 -0
- package/dist/PA-C2FpT6Ew.cjs.map +1 -0
- package/dist/PA-DgyDzDFi.js +12 -0
- package/dist/PA-DgyDzDFi.js.map +1 -0
- package/dist/PB-BGkzbQup.cjs +2 -0
- package/dist/PB-BGkzbQup.cjs.map +1 -0
- package/dist/PB-D-6NE6KM.js +12 -0
- package/dist/PB-D-6NE6KM.js.map +1 -0
- package/dist/PE-D8V7gWY-.cjs +2 -0
- package/dist/PE-D8V7gWY-.cjs.map +1 -0
- package/dist/PE-vqm-t7Nh.js +12 -0
- package/dist/PE-vqm-t7Nh.js.map +1 -0
- package/dist/PI-CILuGJlW.js +12 -0
- package/dist/PI-CILuGJlW.js.map +1 -0
- package/dist/PI-dJYCbXQM.cjs +2 -0
- package/dist/PI-dJYCbXQM.cjs.map +1 -0
- package/dist/PR-DN8AV__r.js +12 -0
- package/dist/PR-DN8AV__r.js.map +1 -0
- package/dist/PR-P17oBdNH.cjs +2 -0
- package/dist/PR-P17oBdNH.cjs.map +1 -0
- package/dist/RJ-Bccz05Em.js +12 -0
- package/dist/RJ-Bccz05Em.js.map +1 -0
- package/dist/RJ-Budqx7QP.cjs +2 -0
- package/dist/RJ-Budqx7QP.cjs.map +1 -0
- package/dist/RN-DLcJBxo3.cjs +2 -0
- package/dist/RN-DLcJBxo3.cjs.map +1 -0
- package/dist/RN-DTqFP-Nm.js +12 -0
- package/dist/RN-DTqFP-Nm.js.map +1 -0
- package/dist/RO-BCC54UTU.js +12 -0
- package/dist/RO-BCC54UTU.js.map +1 -0
- package/dist/RO-B_IDyci4.cjs +2 -0
- package/dist/RO-B_IDyci4.cjs.map +1 -0
- package/dist/RR-CDGUEyla.cjs +2 -0
- package/dist/RR-CDGUEyla.cjs.map +1 -0
- package/dist/RR-OCnI_XpU.js +12 -0
- package/dist/RR-OCnI_XpU.js.map +1 -0
- package/dist/RS-DiBeY_u5.cjs +2 -0
- package/dist/RS-DiBeY_u5.cjs.map +1 -0
- package/dist/RS-Dy7gBbbH.js +12 -0
- package/dist/RS-Dy7gBbbH.js.map +1 -0
- package/dist/SC-CEMoj8g2.cjs +2 -0
- package/dist/SC-CEMoj8g2.cjs.map +1 -0
- package/dist/SC-trCqQDXz.js +12 -0
- package/dist/SC-trCqQDXz.js.map +1 -0
- package/dist/SE-DAfFbZcK.cjs +2 -0
- package/dist/SE-DAfFbZcK.cjs.map +1 -0
- package/dist/SE-DBdfSrGk.js +12 -0
- package/dist/SE-DBdfSrGk.js.map +1 -0
- package/dist/SP-Cse4d68i.cjs +2 -0
- package/dist/SP-Cse4d68i.cjs.map +1 -0
- package/dist/SP-qPZjJDOT.js +12 -0
- package/dist/SP-qPZjJDOT.js.map +1 -0
- package/dist/TO-CZtMDVug.js +12 -0
- package/dist/TO-CZtMDVug.js.map +1 -0
- package/dist/TO-Dwi5zIyF.cjs +2 -0
- package/dist/TO-Dwi5zIyF.cjs.map +1 -0
- package/dist/br-centroids--O7-1KXz.cjs +2 -0
- package/dist/br-centroids--O7-1KXz.cjs.map +1 -0
- package/dist/br-centroids-IHN7PIzD.js +10 -0
- package/dist/br-centroids-IHN7PIzD.js.map +1 -0
- package/dist/br-geo-BYynYOwK.cjs +2 -0
- package/dist/br-geo-BYynYOwK.cjs.map +1 -0
- package/dist/br-geo-DFRuvjuU.js +8 -0
- package/dist/br-geo-DFRuvjuU.js.map +1 -0
- package/dist/br.cjs +1 -1
- package/dist/br.cjs.map +1 -1
- package/dist/br.d.ts +356 -6
- package/dist/br.js +825 -348
- package/dist/br.js.map +1 -1
- package/dist/projection-CILVBdpd.cjs +2 -0
- package/dist/projection-CILVBdpd.cjs.map +1 -0
- package/dist/projection-Wnqr_svy.js +215 -0
- package/dist/projection-Wnqr_svy.js.map +1 -0
- package/dist/styles.css +1 -1
- package/dist/tempest-react-sdk.cjs +3 -3
- package/dist/tempest-react-sdk.cjs.map +1 -1
- package/dist/tempest-react-sdk.d.ts +21 -1
- package/dist/tempest-react-sdk.js +2790 -2848
- package/dist/tempest-react-sdk.js.map +1 -1
- package/package.json +2 -1
- package/dist/AC-BQUmmKrw.cjs +0 -2
- package/dist/AC-BQUmmKrw.cjs.map +0 -1
- package/dist/AC-DOvYXax1.js +0 -12
- package/dist/AC-DOvYXax1.js.map +0 -1
- package/dist/AL-DH1wKIxj.js +0 -12
- package/dist/AL-DH1wKIxj.js.map +0 -1
- package/dist/AL-oN2X02DP.cjs +0 -2
- package/dist/AL-oN2X02DP.cjs.map +0 -1
- package/dist/AM-Cn_JOc_u.cjs +0 -2
- package/dist/AM-Cn_JOc_u.cjs.map +0 -1
- package/dist/AM-D-l4ioxq.js +0 -12
- package/dist/AM-D-l4ioxq.js.map +0 -1
- package/dist/AP-B8H3590m.cjs +0 -2
- package/dist/AP-B8H3590m.cjs.map +0 -1
- package/dist/AP-pl_IXUrz.js +0 -12
- package/dist/AP-pl_IXUrz.js.map +0 -1
- package/dist/BA-DsPuESbp.cjs +0 -2
- package/dist/BA-DsPuESbp.cjs.map +0 -1
- package/dist/BA-HvFNaSvC.js +0 -12
- package/dist/BA-HvFNaSvC.js.map +0 -1
- package/dist/CE-BhzlM8v8.cjs +0 -2
- package/dist/CE-BhzlM8v8.cjs.map +0 -1
- package/dist/CE-C4VCDB2_.js +0 -12
- package/dist/CE-C4VCDB2_.js.map +0 -1
- package/dist/DF-CdR_I7qu.cjs +0 -2
- package/dist/DF-CdR_I7qu.cjs.map +0 -1
- package/dist/DF-DCepvNQG.js +0 -12
- package/dist/DF-DCepvNQG.js.map +0 -1
- package/dist/ES-BNECOgN8.js +0 -12
- package/dist/ES-BNECOgN8.js.map +0 -1
- package/dist/ES-CzZdWdcw.cjs +0 -2
- package/dist/ES-CzZdWdcw.cjs.map +0 -1
- package/dist/GO-CTgkFwbh.js +0 -12
- package/dist/GO-CTgkFwbh.js.map +0 -1
- package/dist/GO-VqQUIkMG.cjs +0 -2
- package/dist/GO-VqQUIkMG.cjs.map +0 -1
- package/dist/MA-CwpNlEs4.cjs +0 -2
- package/dist/MA-CwpNlEs4.cjs.map +0 -1
- package/dist/MA-DC3zmbpX.js +0 -12
- package/dist/MA-DC3zmbpX.js.map +0 -1
- package/dist/MG-DLTyPn6U.js +0 -12
- package/dist/MG-DLTyPn6U.js.map +0 -1
- package/dist/MG-P3ePmTdM.cjs +0 -2
- package/dist/MG-P3ePmTdM.cjs.map +0 -1
- package/dist/MS-Crc916be.js +0 -12
- package/dist/MS-Crc916be.js.map +0 -1
- package/dist/MS-MikLSXO-.cjs +0 -2
- package/dist/MS-MikLSXO-.cjs.map +0 -1
- package/dist/MT-BzUTgqTr.cjs +0 -2
- package/dist/MT-BzUTgqTr.cjs.map +0 -1
- package/dist/MT-DEqs4lmz.js +0 -12
- package/dist/MT-DEqs4lmz.js.map +0 -1
- package/dist/PA-BmFg98qS.cjs +0 -2
- package/dist/PA-BmFg98qS.cjs.map +0 -1
- package/dist/PA-DCJkLLiT.js +0 -12
- package/dist/PA-DCJkLLiT.js.map +0 -1
- package/dist/PB-_6qWqUQe.js +0 -12
- package/dist/PB-_6qWqUQe.js.map +0 -1
- package/dist/PB-cCwnP4jh.cjs +0 -2
- package/dist/PB-cCwnP4jh.cjs.map +0 -1
- package/dist/PE-BCeDGzmC.cjs +0 -2
- package/dist/PE-BCeDGzmC.cjs.map +0 -1
- package/dist/PE-DhAJD50w.js +0 -12
- package/dist/PE-DhAJD50w.js.map +0 -1
- package/dist/PI-8mJVmMWn.cjs +0 -2
- package/dist/PI-8mJVmMWn.cjs.map +0 -1
- package/dist/PI-BBpuVgnF.js +0 -12
- package/dist/PI-BBpuVgnF.js.map +0 -1
- package/dist/PR-Ck8PsNQr.cjs +0 -2
- package/dist/PR-Ck8PsNQr.cjs.map +0 -1
- package/dist/PR-DIU_pEzX.js +0 -12
- package/dist/PR-DIU_pEzX.js.map +0 -1
- package/dist/RJ-BM_31L8v.js +0 -12
- package/dist/RJ-BM_31L8v.js.map +0 -1
- package/dist/RJ-RO2nzm45.cjs +0 -2
- package/dist/RJ-RO2nzm45.cjs.map +0 -1
- package/dist/RN-CGDsj5y7.cjs +0 -2
- package/dist/RN-CGDsj5y7.cjs.map +0 -1
- package/dist/RN-Cb6kQMBf.js +0 -12
- package/dist/RN-Cb6kQMBf.js.map +0 -1
- package/dist/RO-DQlMmLkh.js +0 -12
- package/dist/RO-DQlMmLkh.js.map +0 -1
- package/dist/RO-bBzN2q3e.cjs +0 -2
- package/dist/RO-bBzN2q3e.cjs.map +0 -1
- package/dist/RR-27xmMYjp.cjs +0 -2
- package/dist/RR-27xmMYjp.cjs.map +0 -1
- package/dist/RR-DT5Iz7pA.js +0 -12
- package/dist/RR-DT5Iz7pA.js.map +0 -1
- package/dist/RS-Ax08xnx2.cjs +0 -2
- package/dist/RS-Ax08xnx2.cjs.map +0 -1
- package/dist/RS-Be6-eibq.js +0 -12
- package/dist/RS-Be6-eibq.js.map +0 -1
- package/dist/SC-CR4B6n9K.js +0 -12
- package/dist/SC-CR4B6n9K.js.map +0 -1
- package/dist/SC-D7CvUmBl.cjs +0 -2
- package/dist/SC-D7CvUmBl.cjs.map +0 -1
- package/dist/SE-DYnzRCQV.js +0 -12
- package/dist/SE-DYnzRCQV.js.map +0 -1
- package/dist/SE-fXsuEuvK.cjs +0 -2
- package/dist/SE-fXsuEuvK.cjs.map +0 -1
- package/dist/SP-Cks7QGPk.cjs +0 -2
- package/dist/SP-Cks7QGPk.cjs.map +0 -1
- package/dist/SP-D7R54yvO.js +0 -12
- package/dist/SP-D7R54yvO.js.map +0 -1
- package/dist/TO-CWXJNpx2.js +0 -12
- package/dist/TO-CWXJNpx2.js.map +0 -1
- package/dist/TO-DyvJcNhT.cjs +0 -2
- package/dist/TO-DyvJcNhT.cjs.map +0 -1
- package/dist/br-geo-Q_VQpVMX.js +0 -8
- package/dist/br-geo-Q_VQpVMX.js.map +0 -1
- package/dist/br-geo-rADqOFQL.cjs +0 -2
- package/dist/br-geo-rADqOFQL.cjs.map +0 -1
- package/dist/projection-C2VXUKZJ.js +0 -124
- package/dist/projection-C2VXUKZJ.js.map +0 -1
- package/dist/projection-CkMNK7HA.cjs +0 -2
- package/dist/projection-CkMNK7HA.cjs.map +0 -1
package/dist/br.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"br.js","sources":["../src/br/locations.ts","../src/br/state-geo.ts","../src/br/svg-utils.ts","../src/br/BrazilMap.tsx","../src/br/BrazilStateMap.tsx","../src/br/BrazilStateCitySelect.tsx","../src/br/index.ts"],"sourcesContent":["import rawLocations from \"./data/br-locations.json\";\n\n/** The 27 Brazilian federative units (26 states + Federal District). */\nexport type UF =\n | \"AC\"\n | \"AL\"\n | \"AP\"\n | \"AM\"\n | \"BA\"\n | \"CE\"\n | \"DF\"\n | \"ES\"\n | \"GO\"\n | \"MA\"\n | \"MT\"\n | \"MS\"\n | \"MG\"\n | \"PA\"\n | \"PB\"\n | \"PR\"\n | \"PE\"\n | \"PI\"\n | \"RJ\"\n | \"RN\"\n | \"RS\"\n | \"RO\"\n | \"RR\"\n | \"SC\"\n | \"SP\"\n | \"SE\"\n | \"TO\";\n\n/** The five Brazilian macro-regions (IBGE). */\nexport type BrRegion = \"Norte\" | \"Nordeste\" | \"Centro-Oeste\" | \"Sudeste\" | \"Sul\";\n\n/** A federative unit with its display name and city list. */\nexport interface BrazilState {\n /** Two-letter acronym, e.g. `\"SP\"`. */\n uf: UF;\n /** Full name, e.g. `\"São Paulo\"`. */\n name: string;\n /** Macro-region the state belongs to. */\n region: BrRegion;\n /** City names within the state, alphabetically. */\n cities: string[];\n}\n\n/** A `{ value, label }` option, handy for `<Select>` / `<Combobox>`. */\nexport interface Choice {\n value: string;\n label: string;\n}\n\n/** IBGE macro-region of each federative unit. */\nconst REGION_BY_UF: Record<UF, BrRegion> = {\n AC: \"Norte\",\n AP: \"Norte\",\n AM: \"Norte\",\n PA: \"Norte\",\n RO: \"Norte\",\n RR: \"Norte\",\n TO: \"Norte\",\n AL: \"Nordeste\",\n BA: \"Nordeste\",\n CE: \"Nordeste\",\n MA: \"Nordeste\",\n PB: \"Nordeste\",\n PE: \"Nordeste\",\n PI: \"Nordeste\",\n RN: \"Nordeste\",\n SE: \"Nordeste\",\n DF: \"Centro-Oeste\",\n GO: \"Centro-Oeste\",\n MT: \"Centro-Oeste\",\n MS: \"Centro-Oeste\",\n ES: \"Sudeste\",\n MG: \"Sudeste\",\n RJ: \"Sudeste\",\n SP: \"Sudeste\",\n PR: \"Sul\",\n RS: \"Sul\",\n SC: \"Sul\",\n};\n\ninterface RawState {\n sigla: string;\n estado: string;\n cidades: string[];\n}\n\nconst RAW = rawLocations as unknown as { dataLocals: RawState[] };\n\n/** Normalized, frozen list of all 27 states (built once at module load). */\nconst STATES: readonly BrazilState[] = RAW.dataLocals\n .map((entry) => {\n const uf = entry.sigla as UF;\n return {\n uf,\n name: entry.estado,\n region: REGION_BY_UF[uf],\n cities: entry.cidades,\n };\n })\n .sort((a, b) => a.name.localeCompare(b.name, \"pt-BR\"));\n\nconst STATE_BY_UF = new Map<UF, BrazilState>(STATES.map((s) => [s.uf, s]));\n\n/** All 27 federative units, sorted by name. */\nexport function listStates(): readonly BrazilState[] {\n return STATES;\n}\n\n/** Look up a single state by acronym (case-insensitive). Returns `null` if unknown. */\nexport function getState(uf: string): BrazilState | null {\n const normalized = normalizeUf(uf);\n return normalized ? (STATE_BY_UF.get(normalized) ?? null) : null;\n}\n\n/**\n * City names for a federative unit (case-insensitive acronym). Returns an empty\n * array for an unknown UF — \"no matches\" is a valid result, not an error.\n */\nexport function citiesByUf(uf: string): string[] {\n return getState(uf)?.cities ?? [];\n}\n\n/** States belonging to a macro-region. */\nexport function statesByRegion(region: BrRegion): readonly BrazilState[] {\n return STATES.filter((s) => s.region === region);\n}\n\n/** True when `value` is one of the 27 valid acronyms (case-insensitive). */\nexport function isValidUf(value: string): boolean {\n return normalizeUf(value) !== null;\n}\n\n/**\n * Normalize an acronym to canonical uppercase form, or `null` if it is not a\n * valid UF. `\"sp\"` → `\"SP\"`, `\"xx\"` → `null`.\n */\nexport function normalizeUf(value: string): UF | null {\n const upper = value.trim().toUpperCase();\n return (REGION_BY_UF as Record<string, BrRegion>)[upper] ? (upper as UF) : null;\n}\n\n/** True when `city` exists within `uf` (both case-insensitive). */\nexport function isValidCity(uf: string, city: string): boolean {\n const target = city.trim().toLowerCase();\n return citiesByUf(uf).some((c) => c.toLowerCase() === target);\n}\n\n/** `{ value: uf, label: name }` options for every state, for a `<Select>`. */\nexport function ufChoices(): Choice[] {\n return STATES.map((s) => ({ value: s.uf, label: s.name }));\n}\n\n/** `{ value, label }` options for every city in a UF (value === label). */\nexport function cityChoices(uf: string): Choice[] {\n return citiesByUf(uf).map((c) => ({ value: c, label: c }));\n}\n","import type { BrUfGeometry } from \"./br-geo\";\nimport type { UF } from \"./locations\";\n\n/** One municipality feature within a state. */\nexport interface MunicipalityFeature {\n type: \"Feature\";\n properties: {\n /** 7-digit IBGE municipality code. */\n id: string;\n /** Municipality name. */\n name: string;\n };\n geometry: BrUfGeometry;\n}\n\n/** Municipality boundaries for a single federative unit. */\nexport interface StateMunicipalities {\n type: \"FeatureCollection\";\n /** The federative unit these municipalities belong to. */\n uf: UF;\n features: MunicipalityFeature[];\n}\n\ntype GeoModule = { default: StateMunicipalities };\n\n// One explicit dynamic import per UF — each `data/mun/<UF>.json` becomes its own\n// lazy chunk, so `loadStateMunicipalities(\"SP\")` fetches only São Paulo's\n// geometry and the full ~2 MB municipal dataset never lands in one bundle.\nconst LOADERS: Record<UF, () => Promise<GeoModule>> = {\n AC: () => import(\"./data/mun/AC.json\") as unknown as Promise<GeoModule>,\n AL: () => import(\"./data/mun/AL.json\") as unknown as Promise<GeoModule>,\n AP: () => import(\"./data/mun/AP.json\") as unknown as Promise<GeoModule>,\n AM: () => import(\"./data/mun/AM.json\") as unknown as Promise<GeoModule>,\n BA: () => import(\"./data/mun/BA.json\") as unknown as Promise<GeoModule>,\n CE: () => import(\"./data/mun/CE.json\") as unknown as Promise<GeoModule>,\n DF: () => import(\"./data/mun/DF.json\") as unknown as Promise<GeoModule>,\n ES: () => import(\"./data/mun/ES.json\") as unknown as Promise<GeoModule>,\n GO: () => import(\"./data/mun/GO.json\") as unknown as Promise<GeoModule>,\n MA: () => import(\"./data/mun/MA.json\") as unknown as Promise<GeoModule>,\n MT: () => import(\"./data/mun/MT.json\") as unknown as Promise<GeoModule>,\n MS: () => import(\"./data/mun/MS.json\") as unknown as Promise<GeoModule>,\n MG: () => import(\"./data/mun/MG.json\") as unknown as Promise<GeoModule>,\n PA: () => import(\"./data/mun/PA.json\") as unknown as Promise<GeoModule>,\n PB: () => import(\"./data/mun/PB.json\") as unknown as Promise<GeoModule>,\n PR: () => import(\"./data/mun/PR.json\") as unknown as Promise<GeoModule>,\n PE: () => import(\"./data/mun/PE.json\") as unknown as Promise<GeoModule>,\n PI: () => import(\"./data/mun/PI.json\") as unknown as Promise<GeoModule>,\n RJ: () => import(\"./data/mun/RJ.json\") as unknown as Promise<GeoModule>,\n RN: () => import(\"./data/mun/RN.json\") as unknown as Promise<GeoModule>,\n RS: () => import(\"./data/mun/RS.json\") as unknown as Promise<GeoModule>,\n RO: () => import(\"./data/mun/RO.json\") as unknown as Promise<GeoModule>,\n RR: () => import(\"./data/mun/RR.json\") as unknown as Promise<GeoModule>,\n SC: () => import(\"./data/mun/SC.json\") as unknown as Promise<GeoModule>,\n SP: () => import(\"./data/mun/SP.json\") as unknown as Promise<GeoModule>,\n SE: () => import(\"./data/mun/SE.json\") as unknown as Promise<GeoModule>,\n TO: () => import(\"./data/mun/TO.json\") as unknown as Promise<GeoModule>,\n};\n\n/**\n * Lazily load the simplified municipality GeoJSON for a federative unit. Each\n * state's geometry is a separate chunk (~40-70 KB gzip), fetched on demand —\n * the full ~2 MB municipal dataset never lands in one bundle.\n *\n * @param uf - Federative unit acronym (e.g. `\"SP\"`).\n * @returns The municipality collection, or `null` for an unknown UF.\n *\n * @example\n * const sp = await loadStateMunicipalities(\"SP\");\n * sp?.features.length; // 644\n */\nexport async function loadStateMunicipalities(uf: UF): Promise<StateMunicipalities | null> {\n const loader = LOADERS[uf];\n if (!loader) return null;\n const mod = await loader();\n return mod.default ?? (mod as unknown as StateMunicipalities);\n}\n","import type { FittedProjection } from \"@/geo/projection\";\nimport type { GeoBounds } from \"@/geo/types\";\nimport type { BrUfGeometry, Ring } from \"./br-geo\";\n\n/** Iterate every ring of a geometry (Polygon or MultiPolygon). */\nexport function ringsOf(geometry: BrUfGeometry): Ring[] {\n return geometry.type === \"MultiPolygon\"\n ? (geometry.coordinates as Ring[][]).flat()\n : (geometry.coordinates as Ring[]);\n}\n\n/** Bounding box across every coordinate of the given geometries. */\nexport function geometriesBounds(geometries: readonly BrUfGeometry[]): GeoBounds {\n let minLat = 90;\n let maxLat = -90;\n let minLon = 180;\n let maxLon = -180;\n for (const geometry of geometries) {\n for (const ring of ringsOf(geometry)) {\n for (const [lon, lat] of ring) {\n if (lat < minLat) minLat = lat;\n if (lat > maxLat) maxLat = lat;\n if (lon < minLon) minLon = lon;\n if (lon > maxLon) maxLon = lon;\n }\n }\n }\n return { minLatitude: minLat, maxLatitude: maxLat, minLongitude: minLon, maxLongitude: maxLon };\n}\n\n/** Build the SVG `d` path for a geometry (all rings, `evenodd` handles holes). */\nexport function geometryPath(geometry: BrUfGeometry, projection: FittedProjection): string {\n return ringsOf(geometry)\n .map((ring) => {\n const pts = ring.map(([lon, lat]) => {\n const p = projection.project({ latitude: lat, longitude: lon });\n return `${p.x.toFixed(1)},${p.y.toFixed(1)}`;\n });\n return `M${pts.join(\"L\")}Z`;\n })\n .join(\"\");\n}\n\n/** Rough visual centroid of a geometry (mean of its largest ring's points). */\nexport function geometryCentroid(\n geometry: BrUfGeometry,\n projection: FittedProjection,\n): { x: number; y: number } {\n const rings = ringsOf(geometry);\n const outer = rings.reduce((a, b) => (b.length > a.length ? b : a), rings[0] ?? []);\n let sx = 0;\n let sy = 0;\n for (const [lon, lat] of outer) {\n const p = projection.project({ latitude: lat, longitude: lon });\n sx += p.x;\n sy += p.y;\n }\n const n = outer.length || 1;\n return { x: sx / n, y: sy / n };\n}\n\n/** Linearly interpolate between two hex colors, returning an `rgb(...)` string. */\nexport function lerpColor(from: string, to: string, t: number): string {\n const parse = (c: string): [number, number, number] => {\n const hex = c.replace(\"#\", \"\");\n const full =\n hex.length === 3\n ? hex\n .split(\"\")\n .map((ch) => ch + ch)\n .join(\"\")\n : hex;\n return [\n parseInt(full.slice(0, 2), 16),\n parseInt(full.slice(2, 4), 16),\n parseInt(full.slice(4, 6), 16),\n ];\n };\n const [r1, g1, b1] = parse(from);\n const [r2, g2, b2] = parse(to);\n const mix = (a: number, b: number): number => Math.round(a + (b - a) * t);\n return `rgb(${mix(r1, r2)}, ${mix(g1, g2)}, ${mix(b1, b2)})`;\n}\n","import { useEffect, useMemo, useRef, useState, type HTMLAttributes, type ReactNode } from \"react\";\nimport { cn } from \"@/utils/cn\";\nimport { fitProjection } from \"@/geo/projection\";\nimport type { BrUfFeatureCollection } from \"./br-geo\";\nimport type { UF } from \"./locations\";\nimport { geometriesBounds, geometryCentroid, geometryPath, lerpColor } from \"./svg-utils\";\nimport styles from \"./BrazilMap.module.css\";\n\nexport interface BrazilMapProps extends Omit<HTMLAttributes<HTMLDivElement>, \"onSelect\"> {\n /** Currently selected UF(s) — highlighted. Accepts one or many. */\n selected?: UF | readonly UF[] | null;\n /** Fired when a state is clicked. */\n onSelect?: (uf: UF) => void;\n /**\n * Optional choropleth values per UF. When set, each state is tinted between\n * `minColor` and `maxColor` by its value (linear). States without a value\n * use the base surface color.\n */\n values?: Partial<Record<UF, number>>;\n /** Choropleth low-end color. Default: a light primary tint. */\n minColor?: string;\n /** Choropleth high-end color. Default: the primary token. */\n maxColor?: string;\n /** Viewport height in pixels. Default: `440`. */\n height?: number;\n /** Inner padding in pixels. Default: `12`. */\n padding?: number;\n /** Render the UF acronym at each state centroid. Default: `true`. */\n showLabels?: boolean;\n /** Accessible label for the map region. Default: `\"Mapa do Brasil por estado\"`. */\n label?: string;\n /** Custom content when the geometry is still loading. */\n loadingContent?: ReactNode;\n}\n\n/**\n * Clickable choropleth map of Brazil's 27 federative units. Renders the bundled\n * simplified UF GeoJSON as SVG paths — **no external tiles or paid API**. Click\n * a state to fire `onSelect(uf)`; pass `selected` to highlight and `values` to\n * tint states by a metric.\n *\n * The GeoJSON (~36 KB gzip) is loaded lazily, so importing this component does\n * not pull the geometry until it actually mounts.\n *\n * @example\n * const [uf, setUf] = useState<UF | null>(null);\n * <BrazilMap selected={uf} onSelect={setUf} />\n *\n * @example\n * // Choropleth by a metric per state\n * <BrazilMap values={{ SP: 120, RJ: 90, MG: 60 }} />\n */\nexport function BrazilMap({\n selected,\n onSelect,\n values,\n minColor = \"#dbeafe\",\n maxColor = \"#2563eb\",\n height = 440,\n padding = 12,\n showLabels = true,\n label = \"Mapa do Brasil por estado\",\n loadingContent,\n className,\n style,\n ...rest\n}: BrazilMapProps) {\n const containerRef = useRef<HTMLDivElement>(null);\n const [width, setWidth] = useState<number>(600);\n const [collection, setCollection] = useState<BrUfFeatureCollection | null>(null);\n\n useEffect(() => {\n let active = true;\n void import(\"./br-geo\").then((m) => {\n if (active) setCollection(m.BR_UF_GEOJSON);\n });\n return () => {\n active = false;\n };\n }, []);\n\n useEffect(() => {\n const node = containerRef.current;\n if (!node || typeof ResizeObserver === \"undefined\") return;\n const observer = new ResizeObserver((entries) => {\n const measured = entries[0]?.contentRect.width;\n if (measured && measured > 0) setWidth(measured);\n });\n observer.observe(node);\n return () => observer.disconnect();\n }, []);\n\n const selectedSet = useMemo<Set<UF>>(() => {\n if (!selected) return new Set();\n return new Set(Array.isArray(selected) ? selected : [selected as UF]);\n }, [selected]);\n\n const valueRange = useMemo<[number, number] | null>(() => {\n if (!values) return null;\n const nums = Object.values(values).filter((v): v is number => typeof v === \"number\");\n if (nums.length === 0) return null;\n return [Math.min(...nums), Math.max(...nums)];\n }, [values]);\n\n const shapes = useMemo(() => {\n if (!collection) return null;\n const projection = fitProjection(\n geometriesBounds(collection.features.map((f) => f.geometry)),\n width,\n height,\n { padding },\n );\n return collection.features.map((feature) => ({\n uf: feature.properties.uf,\n name: feature.properties.name,\n d: geometryPath(feature.geometry, projection),\n centroid: geometryCentroid(feature.geometry, projection),\n }));\n }, [collection, width, height, padding]);\n\n function fillFor(uf: UF): string | undefined {\n if (!values || !valueRange) return undefined;\n const v = values[uf];\n if (typeof v !== \"number\") return undefined;\n const [min, max] = valueRange;\n const t = max === min ? 1 : (v - min) / (max - min);\n return lerpColor(minColor, maxColor, t);\n }\n\n return (\n <div\n ref={containerRef}\n className={cn(styles.map, className)}\n style={{ height, ...style }}\n role=\"group\"\n aria-label={label}\n {...rest}\n >\n {!shapes ? (\n <div className={styles.loading}>{loadingContent ?? \"Carregando mapa…\"}</div>\n ) : (\n <svg\n className={styles.svg}\n width=\"100%\"\n height={height}\n viewBox={`0 0 ${width} ${height}`}\n preserveAspectRatio=\"xMidYMid meet\"\n >\n {shapes.map((shape) => {\n const isSelected = selectedSet.has(shape.uf);\n return (\n <path\n key={shape.uf}\n className={cn(styles.state, isSelected && styles.selected)}\n d={shape.d}\n fillRule=\"evenodd\"\n fill={isSelected ? undefined : fillFor(shape.uf)}\n data-uf={shape.uf}\n tabIndex={onSelect ? 0 : undefined}\n role={onSelect ? \"button\" : undefined}\n aria-label={shape.name}\n aria-pressed={onSelect ? isSelected : undefined}\n onClick={onSelect ? () => onSelect(shape.uf) : undefined}\n onKeyDown={\n onSelect\n ? (e) => {\n if (e.key === \"Enter\" || e.key === \" \") {\n e.preventDefault();\n onSelect(shape.uf);\n }\n }\n : undefined\n }\n >\n <title>{shape.name}</title>\n </path>\n );\n })}\n\n {showLabels &&\n shapes.map((shape) => (\n <text\n key={`label-${shape.uf}`}\n className={styles.label}\n x={shape.centroid.x}\n y={shape.centroid.y}\n textAnchor=\"middle\"\n dominantBaseline=\"central\"\n >\n {shape.uf}\n </text>\n ))}\n </svg>\n )}\n </div>\n );\n}\n","import { useEffect, useMemo, useRef, useState, type HTMLAttributes, type ReactNode } from \"react\";\nimport { cn } from \"@/utils/cn\";\nimport { fitProjection } from \"@/geo/projection\";\nimport { getState, type UF } from \"./locations\";\nimport { loadStateMunicipalities, type StateMunicipalities } from \"./state-geo\";\nimport { geometriesBounds, geometryCentroid, geometryPath, lerpColor } from \"./svg-utils\";\nimport styles from \"./BrazilMap.module.css\";\n\n/** A municipality identified for selection callbacks. */\nexport interface Municipality {\n /** 7-digit IBGE code. */\n id: string;\n /** Municipality name. */\n name: string;\n}\n\nexport interface BrazilStateMapProps extends Omit<HTMLAttributes<HTMLDivElement>, \"onSelect\"> {\n /** Federative unit to draw (required). */\n uf: UF;\n /** Selected municipality — matched by IBGE `id` or by `name`. Accepts many. */\n selected?: string | readonly string[] | null;\n /** Fired when a municipality is clicked. */\n onSelect?: (municipality: Municipality) => void;\n /**\n * Choropleth values keyed by municipality `id` **or** `name`. When set, each\n * municipality is tinted between `minColor` and `maxColor`.\n */\n values?: Record<string, number>;\n /** Choropleth low-end color. Default: a light primary tint. */\n minColor?: string;\n /** Choropleth high-end color. Default: the primary token. */\n maxColor?: string;\n /** Viewport height in pixels. Default: `440`. */\n height?: number;\n /** Inner padding in pixels. Default: `12`. */\n padding?: number;\n /**\n * Render each municipality name at its centroid. Off by default — a state\n * can have hundreds of municipalities and labels overlap badly.\n */\n showLabels?: boolean;\n /** Accessible label. Default: derived from the state name. */\n label?: string;\n /** Content while the state geometry is loading. */\n loadingContent?: ReactNode;\n}\n\n/**\n * Clickable submap of a single Brazilian state showing **all its\n * municipalities** as SVG paths — no external tiles or paid API. The state's\n * geometry (~40-70 KB gzip) is loaded lazily per UF, so switching states fetches\n * only what is shown.\n *\n * @example\n * const [city, setCity] = useState<string | null>(null);\n * <BrazilStateMap uf=\"SP\" selected={city} onSelect={(m) => setCity(m.name)} />\n *\n * @example\n * // Choropleth of a metric by municipality name\n * <BrazilStateMap uf=\"RJ\" values={{ \"Rio de Janeiro\": 100, Niterói: 40 }} />\n */\nexport function BrazilStateMap({\n uf,\n selected,\n onSelect,\n values,\n minColor = \"#dbeafe\",\n maxColor = \"#2563eb\",\n height = 440,\n padding = 12,\n showLabels = false,\n label,\n loadingContent,\n className,\n style,\n ...rest\n}: BrazilStateMapProps) {\n const containerRef = useRef<HTMLDivElement>(null);\n const [width, setWidth] = useState<number>(600);\n const [collection, setCollection] = useState<StateMunicipalities | null>(null);\n\n useEffect(() => {\n let active = true;\n setCollection(null);\n void loadStateMunicipalities(uf).then((data) => {\n if (active) setCollection(data);\n });\n return () => {\n active = false;\n };\n }, [uf]);\n\n useEffect(() => {\n const node = containerRef.current;\n if (!node || typeof ResizeObserver === \"undefined\") return;\n const observer = new ResizeObserver((entries) => {\n const measured = entries[0]?.contentRect.width;\n if (measured && measured > 0) setWidth(measured);\n });\n observer.observe(node);\n return () => observer.disconnect();\n }, []);\n\n const selectedSet = useMemo<Set<string>>(() => {\n if (!selected) return new Set();\n return new Set(Array.isArray(selected) ? selected : [selected as string]);\n }, [selected]);\n\n const valueRange = useMemo<[number, number] | null>(() => {\n if (!values) return null;\n const nums = Object.values(values).filter((v): v is number => typeof v === \"number\");\n if (nums.length === 0) return null;\n return [Math.min(...nums), Math.max(...nums)];\n }, [values]);\n\n const shapes = useMemo(() => {\n if (!collection) return null;\n const projection = fitProjection(\n geometriesBounds(collection.features.map((f) => f.geometry)),\n width,\n height,\n { padding },\n );\n return collection.features.map((feature) => ({\n id: feature.properties.id,\n name: feature.properties.name,\n d: geometryPath(feature.geometry, projection),\n centroid: geometryCentroid(feature.geometry, projection),\n }));\n }, [collection, width, height, padding]);\n\n function fillFor(id: string, name: string): string | undefined {\n if (!values || !valueRange) return undefined;\n const v = values[id] ?? values[name];\n if (typeof v !== \"number\") return undefined;\n const [min, max] = valueRange;\n const t = max === min ? 1 : (v - min) / (max - min);\n return lerpColor(minColor, maxColor, t);\n }\n\n const resolvedLabel = label ?? `Municípios de ${getState(uf)?.name ?? uf}`;\n\n return (\n <div\n ref={containerRef}\n className={cn(styles.map, className)}\n style={{ height, ...style }}\n role=\"group\"\n aria-label={resolvedLabel}\n {...rest}\n >\n {!shapes ? (\n <div className={styles.loading}>{loadingContent ?? \"Carregando municípios…\"}</div>\n ) : (\n <svg\n className={styles.svg}\n width=\"100%\"\n height={height}\n viewBox={`0 0 ${width} ${height}`}\n preserveAspectRatio=\"xMidYMid meet\"\n >\n {shapes.map((shape) => {\n const isSelected = selectedSet.has(shape.id) || selectedSet.has(shape.name);\n return (\n <path\n key={shape.id}\n className={cn(styles.state, isSelected && styles.selected)}\n d={shape.d}\n fillRule=\"evenodd\"\n fill={isSelected ? undefined : fillFor(shape.id, shape.name)}\n data-city-id={shape.id}\n data-city={shape.name}\n tabIndex={onSelect ? 0 : undefined}\n role={onSelect ? \"button\" : undefined}\n aria-label={shape.name}\n aria-pressed={onSelect ? isSelected : undefined}\n onClick={\n onSelect\n ? () => onSelect({ id: shape.id, name: shape.name })\n : undefined\n }\n onKeyDown={\n onSelect\n ? (e) => {\n if (e.key === \"Enter\" || e.key === \" \") {\n e.preventDefault();\n onSelect({ id: shape.id, name: shape.name });\n }\n }\n : undefined\n }\n >\n <title>{shape.name}</title>\n </path>\n );\n })}\n\n {showLabels &&\n shapes.map((shape) => (\n <text\n key={`label-${shape.id}`}\n className={styles.label}\n x={shape.centroid.x}\n y={shape.centroid.y}\n textAnchor=\"middle\"\n dominantBaseline=\"central\"\n >\n {shape.name}\n </text>\n ))}\n </svg>\n )}\n </div>\n );\n}\n","import { useMemo, useState, type ReactElement } from \"react\";\nimport { Select } from \"@/components/Select\";\nimport { cityChoices, listStates, normalizeUf, type UF } from \"./locations\";\n\n/** Current selection emitted by {@link BrazilStateCitySelect}. */\nexport interface BrazilStateCitySelection {\n /** Selected federative unit, or `null` when none. */\n uf: UF | null;\n /** Selected city, or `null` when none. */\n city: string | null;\n}\n\nexport interface BrazilStateCitySelectProps {\n /** Pre-selected UF (uncontrolled initial value). */\n defaultUf?: UF;\n /** Pre-selected city (uncontrolled initial value). */\n defaultCity?: string;\n /** Fired whenever the state or city changes. */\n onChange?: (selection: BrazilStateCitySelection) => void;\n /** Label for the state select. Default: `\"Estado\"`. */\n stateLabel?: string;\n /** Label for the city select. Default: `\"Cidade\"`. */\n cityLabel?: string;\n /** Placeholder for the state select. Default: `\"Selecione o estado\"`. */\n statePlaceholder?: string;\n /** Placeholder for the city select. Default: `\"Selecione a cidade\"`. */\n cityPlaceholder?: string;\n /** Disable both selects. */\n disabled?: boolean;\n /** Layout of the two selects. Default: `\"row\"`. */\n layout?: \"row\" | \"column\";\n}\n\n/**\n * Cascading Estado → Cidade selector backed by the bundled BR locations data —\n * pick a state and the city list narrows to that UF's municipalities. No\n * network, no external API. Complements {@link BrazilMap} (wire the map's\n * `onSelect` to drive the same UF).\n *\n * @example\n * <BrazilStateCitySelect onChange={({ uf, city }) => console.log(uf, city)} />\n */\nexport function BrazilStateCitySelect({\n defaultUf,\n defaultCity,\n onChange,\n stateLabel = \"Estado\",\n cityLabel = \"Cidade\",\n statePlaceholder = \"Selecione o estado\",\n cityPlaceholder = \"Selecione a cidade\",\n disabled = false,\n layout = \"row\",\n}: BrazilStateCitySelectProps): ReactElement {\n const [uf, setUf] = useState<UF | null>(defaultUf ?? null);\n const [city, setCity] = useState<string | null>(defaultCity ?? null);\n\n const stateOptions = useMemo(\n () => listStates().map((s) => ({ value: s.uf, label: s.name })),\n [],\n );\n const cityOptions = useMemo(() => (uf ? cityChoices(uf) : []), [uf]);\n\n function handleUf(next: string): void {\n const nextUf = normalizeUf(next);\n setUf(nextUf);\n setCity(null);\n onChange?.({ uf: nextUf, city: null });\n }\n\n function handleCity(next: string): void {\n const nextCity = next || null;\n setCity(nextCity);\n onChange?.({ uf, city: nextCity });\n }\n\n return (\n <div\n style={{\n display: \"flex\",\n flexDirection: layout === \"row\" ? \"row\" : \"column\",\n gap: \"var(--tempest-space-3, 12px)\",\n flexWrap: \"wrap\",\n }}\n >\n <Select\n label={stateLabel}\n placeholder={statePlaceholder}\n options={stateOptions}\n value={uf ?? \"\"}\n disabled={disabled}\n onChange={(e) => handleUf(e.target.value)}\n style={{ minWidth: 0 }}\n />\n <Select\n label={cityLabel}\n placeholder={cityPlaceholder}\n options={cityOptions}\n value={city ?? \"\"}\n disabled={disabled || !uf}\n onChange={(e) => handleCity(e.target.value)}\n style={{ minWidth: 0 }}\n />\n </div>\n );\n}\n","// Brazilian locations data (states + cities) — mirrors the `utils/locations`\n// module of tempest-fastapi-sdk.\nexport {\n listStates,\n getState,\n citiesByUf,\n statesByRegion,\n isValidUf,\n normalizeUf,\n isValidCity,\n ufChoices,\n cityChoices,\n} from \"./locations\";\nexport type { UF, BrRegion, BrazilState, Choice } from \"./locations\";\n\n// UF GeoJSON types (the geometry itself is lazy-loaded by BrazilMap).\nimport type { BrUfFeatureCollection } from \"./br-geo\";\nexport type { BrUfFeature, BrUfFeatureCollection, BrUfGeometry, Ring } from \"./br-geo\";\n\n/**\n * Lazily load the bundled simplified UF GeoJSON (~36 KB gzip). Kept out of the\n * synchronous barrel so a data-only import never pulls the geometry.\n */\nexport async function loadBrUfGeoJson(): Promise<BrUfFeatureCollection> {\n const mod = await import(\"./br-geo\");\n return mod.BR_UF_GEOJSON;\n}\n\n// Per-state municipality geometry (lazy, one chunk per UF).\nexport { loadStateMunicipalities } from \"./state-geo\";\nexport type { MunicipalityFeature, StateMunicipalities } from \"./state-geo\";\n\n// Components\nexport { BrazilMap } from \"./BrazilMap\";\nexport type { BrazilMapProps } from \"./BrazilMap\";\nexport { BrazilStateMap } from \"./BrazilStateMap\";\nexport type { BrazilStateMapProps, Municipality } from \"./BrazilStateMap\";\nexport { BrazilStateCitySelect } from \"./BrazilStateCitySelect\";\nexport type { BrazilStateCitySelectProps, BrazilStateCitySelection } from \"./BrazilStateCitySelect\";\n"],"names":["REGION_BY_UF","RAW","rawLocations","STATES","entry","uf","b","STATE_BY_UF","s","listStates","getState","normalized","normalizeUf","citiesByUf","statesByRegion","region","isValidUf","value","upper","isValidCity","city","target","c","ufChoices","cityChoices","LOADERS","loadStateMunicipalities","loader","mod","ringsOf","geometry","geometriesBounds","geometries","minLat","maxLat","minLon","maxLon","ring","lon","lat","geometryPath","projection","p","geometryCentroid","rings","outer","a","sx","sy","n","lerpColor","from","to","t","parse","hex","full","ch","r1","g1","b1","r2","g2","b2","mix","BrazilMap","selected","onSelect","values","minColor","maxColor","height","padding","showLabels","label","loadingContent","className","style","rest","containerRef","useRef","width","setWidth","useState","collection","setCollection","useEffect","active","m","node","observer","entries","measured","selectedSet","useMemo","valueRange","nums","v","shapes","fitProjection","f","feature","fillFor","min","max","jsx","cn","styles","jsxs","shape","isSelected","e","BrazilStateMap","data","id","name","resolvedLabel","BrazilStateCitySelect","defaultUf","defaultCity","onChange","stateLabel","cityLabel","statePlaceholder","cityPlaceholder","disabled","layout","setUf","setCity","stateOptions","cityOptions","handleUf","next","nextUf","handleCity","nextCity","Select","loadBrUfGeoJson"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"br.js","sources":["../src/br/locations.ts","../src/br/state-geo.ts","../src/br/geocode.ts","../src/br/MapMarkers.tsx","../src/br/MapTooltip.tsx","../src/br/regions.ts","../src/br/use-map-zoom.ts","../src/br/svg-utils.ts","../src/br/use-map-hover.ts","../src/br/BrazilMap.tsx","../src/br/BrazilStateMap.tsx","../src/br/BrazilStateCitySelect.tsx","../src/br/MunicipalitySearch.tsx","../src/br/scales.ts","../src/br/MapLegend.tsx","../src/br/index.ts"],"sourcesContent":["import rawLocations from \"./data/br-locations.json\";\n\n/** The 27 Brazilian federative units (26 states + Federal District). */\nexport type UF =\n | \"AC\"\n | \"AL\"\n | \"AP\"\n | \"AM\"\n | \"BA\"\n | \"CE\"\n | \"DF\"\n | \"ES\"\n | \"GO\"\n | \"MA\"\n | \"MT\"\n | \"MS\"\n | \"MG\"\n | \"PA\"\n | \"PB\"\n | \"PR\"\n | \"PE\"\n | \"PI\"\n | \"RJ\"\n | \"RN\"\n | \"RS\"\n | \"RO\"\n | \"RR\"\n | \"SC\"\n | \"SP\"\n | \"SE\"\n | \"TO\";\n\n/** The five Brazilian macro-regions (IBGE). */\nexport type BrRegion = \"Norte\" | \"Nordeste\" | \"Centro-Oeste\" | \"Sudeste\" | \"Sul\";\n\n/** A federative unit with its display name and city list. */\nexport interface BrazilState {\n /** Two-letter acronym, e.g. `\"SP\"`. */\n uf: UF;\n /** Full name, e.g. `\"São Paulo\"`. */\n name: string;\n /** Macro-region the state belongs to. */\n region: BrRegion;\n /** City names within the state, alphabetically. */\n cities: string[];\n}\n\n/** A `{ value, label }` option, handy for `<Select>` / `<Combobox>`. */\nexport interface Choice {\n value: string;\n label: string;\n}\n\n/** IBGE macro-region of each federative unit. */\nconst REGION_BY_UF: Record<UF, BrRegion> = {\n AC: \"Norte\",\n AP: \"Norte\",\n AM: \"Norte\",\n PA: \"Norte\",\n RO: \"Norte\",\n RR: \"Norte\",\n TO: \"Norte\",\n AL: \"Nordeste\",\n BA: \"Nordeste\",\n CE: \"Nordeste\",\n MA: \"Nordeste\",\n PB: \"Nordeste\",\n PE: \"Nordeste\",\n PI: \"Nordeste\",\n RN: \"Nordeste\",\n SE: \"Nordeste\",\n DF: \"Centro-Oeste\",\n GO: \"Centro-Oeste\",\n MT: \"Centro-Oeste\",\n MS: \"Centro-Oeste\",\n ES: \"Sudeste\",\n MG: \"Sudeste\",\n RJ: \"Sudeste\",\n SP: \"Sudeste\",\n PR: \"Sul\",\n RS: \"Sul\",\n SC: \"Sul\",\n};\n\ninterface RawState {\n sigla: string;\n estado: string;\n cidades: string[];\n}\n\nconst RAW = rawLocations as unknown as { dataLocals: RawState[] };\n\n/** Normalized, frozen list of all 27 states (built once at module load). */\nconst STATES: readonly BrazilState[] = RAW.dataLocals\n .map((entry) => {\n const uf = entry.sigla as UF;\n return {\n uf,\n name: entry.estado,\n region: REGION_BY_UF[uf],\n cities: entry.cidades,\n };\n })\n .sort((a, b) => a.name.localeCompare(b.name, \"pt-BR\"));\n\nconst STATE_BY_UF = new Map<UF, BrazilState>(STATES.map((s) => [s.uf, s]));\n\n/** All 27 federative units, sorted by name. */\nexport function listStates(): readonly BrazilState[] {\n return STATES;\n}\n\n/** Look up a single state by acronym (case-insensitive). Returns `null` if unknown. */\nexport function getState(uf: string): BrazilState | null {\n const normalized = normalizeUf(uf);\n return normalized ? (STATE_BY_UF.get(normalized) ?? null) : null;\n}\n\n/**\n * City names for a federative unit (case-insensitive acronym). Returns an empty\n * array for an unknown UF — \"no matches\" is a valid result, not an error.\n */\nexport function citiesByUf(uf: string): string[] {\n return getState(uf)?.cities ?? [];\n}\n\n/** States belonging to a macro-region. */\nexport function statesByRegion(region: BrRegion): readonly BrazilState[] {\n return STATES.filter((s) => s.region === region);\n}\n\n/** True when `value` is one of the 27 valid acronyms (case-insensitive). */\nexport function isValidUf(value: string): boolean {\n return normalizeUf(value) !== null;\n}\n\n/**\n * Normalize an acronym to canonical uppercase form, or `null` if it is not a\n * valid UF. `\"sp\"` → `\"SP\"`, `\"xx\"` → `null`.\n */\nexport function normalizeUf(value: string): UF | null {\n const upper = value.trim().toUpperCase();\n return (REGION_BY_UF as Record<string, BrRegion>)[upper] ? (upper as UF) : null;\n}\n\n/** True when `city` exists within `uf` (both case-insensitive). */\nexport function isValidCity(uf: string, city: string): boolean {\n const target = city.trim().toLowerCase();\n return citiesByUf(uf).some((c) => c.toLowerCase() === target);\n}\n\n/** `{ value: uf, label: name }` options for every state, for a `<Select>`. */\nexport function ufChoices(): Choice[] {\n return STATES.map((s) => ({ value: s.uf, label: s.name }));\n}\n\n/** `{ value, label }` options for every city in a UF (value === label). */\nexport function cityChoices(uf: string): Choice[] {\n return citiesByUf(uf).map((c) => ({ value: c, label: c }));\n}\n","import type { BrUfGeometry } from \"./br-geo\";\nimport type { UF } from \"./locations\";\n\n/** One municipality feature within a state. */\nexport interface MunicipalityFeature {\n type: \"Feature\";\n properties: {\n /** 7-digit IBGE municipality code. */\n id: string;\n /** Municipality name. */\n name: string;\n /** Representative point `[longitude, latitude]` (area-weighted centroid). */\n centroid: [number, number];\n };\n geometry: BrUfGeometry;\n}\n\n/** Municipality boundaries for a single federative unit. */\nexport interface StateMunicipalities {\n type: \"FeatureCollection\";\n /** The federative unit these municipalities belong to. */\n uf: UF;\n features: MunicipalityFeature[];\n}\n\ntype GeoModule = { default: StateMunicipalities };\n\n// One explicit dynamic import per UF — each `data/mun/<UF>.json` becomes its own\n// lazy chunk, so `loadStateMunicipalities(\"SP\")` fetches only São Paulo's\n// geometry and the full ~2 MB municipal dataset never lands in one bundle.\nconst LOADERS: Record<UF, () => Promise<GeoModule>> = {\n AC: () => import(\"./data/mun/AC.json\") as unknown as Promise<GeoModule>,\n AL: () => import(\"./data/mun/AL.json\") as unknown as Promise<GeoModule>,\n AP: () => import(\"./data/mun/AP.json\") as unknown as Promise<GeoModule>,\n AM: () => import(\"./data/mun/AM.json\") as unknown as Promise<GeoModule>,\n BA: () => import(\"./data/mun/BA.json\") as unknown as Promise<GeoModule>,\n CE: () => import(\"./data/mun/CE.json\") as unknown as Promise<GeoModule>,\n DF: () => import(\"./data/mun/DF.json\") as unknown as Promise<GeoModule>,\n ES: () => import(\"./data/mun/ES.json\") as unknown as Promise<GeoModule>,\n GO: () => import(\"./data/mun/GO.json\") as unknown as Promise<GeoModule>,\n MA: () => import(\"./data/mun/MA.json\") as unknown as Promise<GeoModule>,\n MT: () => import(\"./data/mun/MT.json\") as unknown as Promise<GeoModule>,\n MS: () => import(\"./data/mun/MS.json\") as unknown as Promise<GeoModule>,\n MG: () => import(\"./data/mun/MG.json\") as unknown as Promise<GeoModule>,\n PA: () => import(\"./data/mun/PA.json\") as unknown as Promise<GeoModule>,\n PB: () => import(\"./data/mun/PB.json\") as unknown as Promise<GeoModule>,\n PR: () => import(\"./data/mun/PR.json\") as unknown as Promise<GeoModule>,\n PE: () => import(\"./data/mun/PE.json\") as unknown as Promise<GeoModule>,\n PI: () => import(\"./data/mun/PI.json\") as unknown as Promise<GeoModule>,\n RJ: () => import(\"./data/mun/RJ.json\") as unknown as Promise<GeoModule>,\n RN: () => import(\"./data/mun/RN.json\") as unknown as Promise<GeoModule>,\n RS: () => import(\"./data/mun/RS.json\") as unknown as Promise<GeoModule>,\n RO: () => import(\"./data/mun/RO.json\") as unknown as Promise<GeoModule>,\n RR: () => import(\"./data/mun/RR.json\") as unknown as Promise<GeoModule>,\n SC: () => import(\"./data/mun/SC.json\") as unknown as Promise<GeoModule>,\n SP: () => import(\"./data/mun/SP.json\") as unknown as Promise<GeoModule>,\n SE: () => import(\"./data/mun/SE.json\") as unknown as Promise<GeoModule>,\n TO: () => import(\"./data/mun/TO.json\") as unknown as Promise<GeoModule>,\n};\n\n/**\n * Lazily load the simplified municipality GeoJSON for a federative unit. Each\n * state's geometry is a separate chunk (~40-70 KB gzip), fetched on demand —\n * the full ~2 MB municipal dataset never lands in one bundle.\n *\n * @param uf - Federative unit acronym (e.g. `\"SP\"`).\n * @returns The municipality collection, or `null` for an unknown UF.\n *\n * @example\n * const sp = await loadStateMunicipalities(\"SP\");\n * sp?.features.length; // 644\n */\nexport async function loadStateMunicipalities(uf: UF): Promise<StateMunicipalities | null> {\n const loader = LOADERS[uf];\n if (!loader) return null;\n const mod = await loader();\n return mod.default ?? (mod as unknown as StateMunicipalities);\n}\n","import { haversineKm } from \"@/geo/distance\";\nimport type { Coordinate } from \"@/geo/types\";\nimport type { BrUfGeometry, Ring } from \"./br-geo\";\nimport type { UF } from \"./locations\";\nimport { loadStateMunicipalities } from \"./state-geo\";\n\n/** A municipality with its representative coordinate (IBGE centroid). */\nexport interface MunicipalityCentroid {\n /** 7-digit IBGE code. */\n id: string;\n /** Municipality name. */\n name: string;\n /** Federative unit. */\n uf: UF;\n latitude: number;\n longitude: number;\n}\n\n/** {@link MunicipalityCentroid} plus the distance from the query point. */\nexport interface NearestMunicipality extends MunicipalityCentroid {\n /** Great-circle distance from the query coordinate, in kilometers. */\n distanceKm: number;\n}\n\n/** A municipality identified by point-in-polygon (see {@link reverseGeocode}). */\nexport interface ReverseGeocodeResult {\n id: string;\n name: string;\n uf: UF;\n}\n\ninterface RawIndex {\n states: Record<string, [number, number]>;\n municipalities: [string, string, string, number, number][];\n}\n\ninterface CentroidIndex {\n states: Partial<Record<UF, Coordinate>>;\n municipalities: MunicipalityCentroid[];\n}\n\nlet cache: CentroidIndex | null = null;\nlet pending: Promise<CentroidIndex> | null = null;\n\n/** Strip accents and lowercase, for accent-insensitive name matching. */\nfunction normalizeName(value: string): string {\n return value\n .normalize(\"NFD\")\n .replace(/\\p{Diacritic}/gu, \"\")\n .trim()\n .toLowerCase();\n}\n\n/**\n * Lazily load and cache the compact centroid index (~97 KB gzip). Kept out of\n * the synchronous barrel so importing `/br` for data/maps never pulls it — only\n * a geocode call fetches it, and only once.\n */\nasync function loadIndex(): Promise<CentroidIndex> {\n if (cache) return cache;\n if (!pending) {\n pending = import(\"./data/br-centroids.json\").then((mod) => {\n const raw = (mod.default ?? mod) as unknown as RawIndex;\n const states: Partial<Record<UF, Coordinate>> = {};\n for (const [uf, [lon, lat]] of Object.entries(raw.states)) {\n states[uf as UF] = { latitude: lat, longitude: lon };\n }\n cache = {\n states,\n municipalities: raw.municipalities.map(([id, name, uf, lon, lat]) => ({\n id,\n name,\n uf: uf as UF,\n latitude: lat,\n longitude: lon,\n })),\n };\n return cache;\n });\n }\n return pending;\n}\n\n/**\n * Nearest Brazilian municipality to a coordinate by **centroid distance** —\n * fast and geometry-free (only the small centroid index loads). Approximate:\n * near borders or inside large municipalities a neighbor's centroid can be\n * closer. For an exact containing municipality use {@link reverseGeocode}.\n *\n * @param coord - Query coordinate.\n * @returns The nearest municipality with `distanceKm`, or `null` if the index\n * is somehow empty.\n *\n * @example\n * const near = await nearestMunicipality({ latitude: -23.55, longitude: -46.63 });\n * // { id, name, uf: \"SP\", …, distanceKm }\n */\nexport async function nearestMunicipality(coord: Coordinate): Promise<NearestMunicipality | null> {\n const { municipalities } = await loadIndex();\n let best: MunicipalityCentroid | null = null;\n let bestDistance = Infinity;\n for (const m of municipalities) {\n const d = haversineKm(coord, m);\n if (d < bestDistance) {\n bestDistance = d;\n best = m;\n }\n }\n return best ? { ...best, distanceKm: bestDistance } : null;\n}\n\n/**\n * Forward-geocode a municipality by name (accent-insensitive), optionally scoped\n * to a UF. Returns every exact-name match — the same name can occur in several\n * states (e.g. \"Bonito\").\n *\n * @param name - Municipality name.\n * @param uf - Optional UF to restrict the search.\n * @returns Matching municipalities (empty array when none match).\n */\nexport async function geocodeMunicipality(name: string, uf?: UF): Promise<MunicipalityCentroid[]> {\n const { municipalities } = await loadIndex();\n const target = normalizeName(name);\n return municipalities.filter((m) => (!uf || m.uf === uf) && normalizeName(m.name) === target);\n}\n\n/**\n * Substring search over municipality names (accent-insensitive), for\n * autocomplete. Ranked prefix-first, then alphabetically.\n *\n * @param query - Partial name.\n * @param options - `uf` to scope, `limit` (default 20).\n * @returns Ranked matches.\n */\nexport async function searchMunicipalities(\n query: string,\n options: { uf?: UF; limit?: number } = {},\n): Promise<MunicipalityCentroid[]> {\n const { uf, limit = 20 } = options;\n const q = normalizeName(query);\n if (!q) return [];\n const { municipalities } = await loadIndex();\n const hits = municipalities\n .filter((m) => (!uf || m.uf === uf) && normalizeName(m.name).includes(q))\n .sort((a, b) => {\n const ap = normalizeName(a.name).startsWith(q) ? 0 : 1;\n const bp = normalizeName(b.name).startsWith(q) ? 0 : 1;\n return ap - bp || a.name.localeCompare(b.name, \"pt-BR\");\n });\n return hits.slice(0, limit);\n}\n\n/**\n * Centroid of a municipality by IBGE code.\n *\n * @param id - 7-digit IBGE code.\n * @returns The municipality centroid, or `null` if unknown.\n */\nexport async function municipalityCentroid(id: string): Promise<MunicipalityCentroid | null> {\n const { municipalities } = await loadIndex();\n return municipalities.find((m) => m.id === id) ?? null;\n}\n\n/**\n * Centroid of a federative unit.\n *\n * @param uf - Federative unit acronym.\n * @returns The state centroid, or `null` if unknown.\n */\nexport async function stateCentroid(uf: UF): Promise<Coordinate | null> {\n const { states } = await loadIndex();\n return states[uf] ?? null;\n}\n\n/** Ray-casting point-in-ring test (`ring` is `[lon, lat]` pairs). */\nfunction pointInRing(lon: number, lat: number, ring: Ring): boolean {\n let inside = false;\n for (let i = 0, j = ring.length - 1; i < ring.length; j = i, i += 1) {\n const [xi, yi] = ring[i];\n const [xj, yj] = ring[j];\n const intersects = yi > lat !== yj > lat && lon < ((xj - xi) * (lat - yi)) / (yj - yi) + xi;\n if (intersects) inside = !inside;\n }\n return inside;\n}\n\n/** True when the point lies in a polygon's outer ring and not in a hole. */\nfunction pointInPolygon(lon: number, lat: number, rings: Ring[]): boolean {\n if (rings.length === 0 || !pointInRing(lon, lat, rings[0])) return false;\n for (let i = 1; i < rings.length; i += 1) {\n if (pointInRing(lon, lat, rings[i])) return false; // inside a hole\n }\n return true;\n}\n\n/** True when the point lies inside a (multi)polygon geometry. */\nfunction pointInGeometry(lon: number, lat: number, geom: BrUfGeometry): boolean {\n if (geom.type === \"Polygon\") {\n return pointInPolygon(lon, lat, geom.coordinates as Ring[]);\n }\n return (geom.coordinates as Ring[][]).some((poly) => pointInPolygon(lon, lat, poly));\n}\n\n/**\n * Exact reverse-geocode: the municipality whose (simplified) boundary\n * **contains** the coordinate, via point-in-polygon. Loads one state's geometry\n * chunk — pass `uf` when you know it to skip the centroid lookup that picks the\n * candidate state. Boundaries are simplified (~2 km), so points within ~1-2 km\n * of a border may resolve to the neighbor; offshore points return `null`.\n *\n * @param coord - Query coordinate.\n * @param options - `uf` to force the state searched.\n * @returns The containing municipality, or `null` (falls back to the nearest\n * centroid municipality when the point is inside no polygon of the state).\n *\n * @example\n * const here = await reverseGeocode({ latitude: -23.5505, longitude: -46.6333 });\n * // { id: \"3550308\", name: \"São Paulo\", uf: \"SP\" }\n */\nexport async function reverseGeocode(\n coord: Coordinate,\n options: { uf?: UF } = {},\n): Promise<ReverseGeocodeResult | null> {\n const nearest = options.uf ? null : await nearestMunicipality(coord);\n const uf = options.uf ?? nearest?.uf;\n if (!uf) return null;\n\n const state = await loadStateMunicipalities(uf);\n const hit = state?.features.find((f) =>\n pointInGeometry(coord.longitude, coord.latitude, f.geometry),\n );\n if (hit) return { id: hit.properties.id, name: hit.properties.name, uf };\n\n // Point inside no polygon (border/offshore) — fall back to nearest centroid.\n const fallback = nearest ?? (await nearestMunicipality(coord));\n return fallback ? { id: fallback.id, name: fallback.name, uf: fallback.uf } : null;\n}\n","import type { FittedProjection } from \"@/geo/projection\";\nimport type { GeoMarker } from \"@/geo/types\";\nimport styles from \"./BrazilMap.module.css\";\n\nexport interface MapMarkersProps {\n /** Projection used by the host map (markers must share it to line up). */\n projection: FittedProjection;\n /** Pins to plot. */\n markers: readonly GeoMarker[];\n /** Fired when a marker is clicked. */\n onMarkerClick?: (marker: GeoMarker, index: number) => void;\n}\n\n/**\n * SVG overlay of point markers, projected with the host map's projection so\n * they align with its shapes. Each marker carries a native `<title>` (its\n * `label`) and is clickable when `onMarkerClick` is set.\n */\nexport function MapMarkers({ projection, markers, onMarkerClick }: MapMarkersProps) {\n return (\n <g className={styles.markers}>\n {markers.map((marker, index) => {\n const p = projection.project(marker);\n const interactive = Boolean(onMarkerClick);\n return (\n <circle\n key={marker.id ?? index}\n className={styles.marker}\n cx={p.x}\n cy={p.y}\n r={marker.radius ?? 6}\n fill={marker.color ?? \"var(--tempest-primary)\"}\n data-marker-id={marker.id ?? index}\n tabIndex={interactive ? 0 : undefined}\n role={interactive ? \"button\" : undefined}\n aria-label={marker.label}\n onClick={interactive ? () => onMarkerClick?.(marker, index) : undefined}\n onKeyDown={\n interactive\n ? (e) => {\n if (e.key === \"Enter\" || e.key === \" \") {\n e.preventDefault();\n onMarkerClick?.(marker, index);\n }\n }\n : undefined\n }\n >\n {marker.label ? <title>{marker.label}</title> : null}\n </circle>\n );\n })}\n </g>\n );\n}\n","import type { ReactNode } from \"react\";\nimport { cn } from \"@/utils/cn\";\nimport styles from \"./BrazilMap.module.css\";\n\nexport interface MapTooltipProps {\n /** X position in pixels, relative to the map container. */\n x: number;\n /** Y position in pixels, relative to the map container. */\n y: number;\n /** Tooltip body. */\n children: ReactNode;\n className?: string;\n}\n\n/**\n * Floating tooltip anchored near the cursor over a map. Positioned absolutely\n * inside the map container (which is `position: relative`) and non-interactive\n * so it never steals hover from the shapes beneath it.\n */\nexport function MapTooltip({ x, y, children, className }: MapTooltipProps) {\n return (\n <div\n className={cn(styles.tooltip, className)}\n style={{ left: x, top: y }}\n data-testid=\"map-tooltip\"\n aria-hidden\n >\n {children}\n </div>\n );\n}\n","import type { LegendItem } from \"./MapLegend\";\nimport type { BrRegion } from \"./locations\";\n\n/**\n * Categorical, distinguishable colors for the five IBGE macro-regions\n * (Tableau-10 family). Swap for your brand palette if needed.\n */\nexport const REGION_COLORS: Record<BrRegion, string> = {\n Norte: \"#4e79a7\",\n Nordeste: \"#f28e2b\",\n \"Centro-Oeste\": \"#59a14f\",\n Sudeste: \"#e15759\",\n Sul: \"#b07aa1\",\n};\n\n/** Legend entries (swatch + region name) for a region-colored map. */\nexport function regionLegendItems(): LegendItem[] {\n return (Object.keys(REGION_COLORS) as BrRegion[]).map((region) => ({\n color: REGION_COLORS[region],\n label: region,\n }));\n}\n","import { useCallback, useRef, useState, type PointerEvent, type WheelEvent } from \"react\";\n\n/** Pan/zoom transform state. */\nexport interface MapTransform {\n /** Zoom factor (1 = fit). */\n k: number;\n /** X translation in pixels. */\n x: number;\n /** Y translation in pixels. */\n y: number;\n}\n\nconst MIN_K = 1;\nconst MAX_K = 12;\n\nexport interface UseMapZoom {\n /** SVG `transform` string for the content `<g>`. */\n transform: string;\n /** Current zoom factor. */\n zoom: number;\n /** True when panned/zoomed away from the initial fit. */\n isTransformed: boolean;\n /** Reset to the initial fit. */\n reset: () => void;\n /** Handlers to spread on the `<svg>` element. */\n handlers: {\n onWheel?: (e: WheelEvent) => void;\n onPointerDown?: (e: PointerEvent) => void;\n onPointerMove?: (e: PointerEvent) => void;\n onPointerUp?: (e: PointerEvent) => void;\n onPointerLeave?: (e: PointerEvent) => void;\n onDoubleClick?: () => void;\n style?: { cursor: string; touchAction: string };\n };\n}\n\n/**\n * Wheel-zoom (anchored at the cursor) + drag-pan for an SVG map. Returns a\n * `transform` to apply to a content `<g>` and handlers for the `<svg>`. A no-op\n * (identity transform, empty handlers) when `enabled` is false.\n */\nexport function useMapZoom(enabled: boolean): UseMapZoom {\n const [t, setT] = useState<MapTransform>({ k: 1, x: 0, y: 0 });\n const drag = useRef<{ x: number; y: number; ox: number; oy: number } | null>(null);\n\n const reset = useCallback(() => setT({ k: 1, x: 0, y: 0 }), []);\n\n const onWheel = useCallback((e: WheelEvent) => {\n e.preventDefault();\n const rect = e.currentTarget.getBoundingClientRect();\n const cx = e.clientX - rect.left;\n const cy = e.clientY - rect.top;\n setT((prev) => {\n const factor = e.deltaY < 0 ? 1.15 : 1 / 1.15;\n const k = Math.max(MIN_K, Math.min(MAX_K, prev.k * factor));\n const scale = k / prev.k;\n return { k, x: cx - (cx - prev.x) * scale, y: cy - (cy - prev.y) * scale };\n });\n }, []);\n\n const onPointerDown = useCallback((e: PointerEvent) => {\n drag.current = { x: e.clientX, y: e.clientY, ox: 0, oy: 0 };\n e.currentTarget.setPointerCapture?.(e.pointerId);\n }, []);\n\n const onPointerMove = useCallback((e: PointerEvent) => {\n if (!drag.current) return;\n const dx = e.clientX - drag.current.x;\n const dy = e.clientY - drag.current.y;\n drag.current.x = e.clientX;\n drag.current.y = e.clientY;\n setT((prev) => ({ ...prev, x: prev.x + dx, y: prev.y + dy }));\n }, []);\n\n const endDrag = useCallback((e: PointerEvent) => {\n drag.current = null;\n e.currentTarget.releasePointerCapture?.(e.pointerId);\n }, []);\n\n if (!enabled) {\n return {\n transform: \"\",\n zoom: 1,\n isTransformed: false,\n reset,\n handlers: {},\n };\n }\n\n const isTransformed = t.k !== 1 || t.x !== 0 || t.y !== 0;\n return {\n transform: `translate(${t.x} ${t.y}) scale(${t.k})`,\n zoom: t.k,\n isTransformed,\n reset,\n handlers: {\n onWheel,\n onPointerDown,\n onPointerMove,\n onPointerUp: endDrag,\n onPointerLeave: endDrag,\n onDoubleClick: reset,\n style: { cursor: isTransformed ? \"grab\" : \"default\", touchAction: \"none\" },\n },\n };\n}\n","import type { FittedProjection } from \"@/geo/projection\";\nimport type { GeoBounds } from \"@/geo/types\";\nimport type { BrUfGeometry, Ring } from \"./br-geo\";\n\n/** Iterate every ring of a geometry (Polygon or MultiPolygon). */\nexport function ringsOf(geometry: BrUfGeometry): Ring[] {\n return geometry.type === \"MultiPolygon\"\n ? (geometry.coordinates as Ring[][]).flat()\n : (geometry.coordinates as Ring[]);\n}\n\n/** Bounding box across every coordinate of the given geometries. */\nexport function geometriesBounds(geometries: readonly BrUfGeometry[]): GeoBounds {\n let minLat = 90;\n let maxLat = -90;\n let minLon = 180;\n let maxLon = -180;\n for (const geometry of geometries) {\n for (const ring of ringsOf(geometry)) {\n for (const [lon, lat] of ring) {\n if (lat < minLat) minLat = lat;\n if (lat > maxLat) maxLat = lat;\n if (lon < minLon) minLon = lon;\n if (lon > maxLon) maxLon = lon;\n }\n }\n }\n return { minLatitude: minLat, maxLatitude: maxLat, minLongitude: minLon, maxLongitude: maxLon };\n}\n\n/** Build the SVG `d` path for a geometry (all rings, `evenodd` handles holes). */\nexport function geometryPath(geometry: BrUfGeometry, projection: FittedProjection): string {\n return ringsOf(geometry)\n .map((ring) => {\n const pts = ring.map(([lon, lat]) => {\n const p = projection.project({ latitude: lat, longitude: lon });\n return `${p.x.toFixed(1)},${p.y.toFixed(1)}`;\n });\n return `M${pts.join(\"L\")}Z`;\n })\n .join(\"\");\n}\n\n/** Rough visual centroid of a geometry (mean of its largest ring's points). */\nexport function geometryCentroid(\n geometry: BrUfGeometry,\n projection: FittedProjection,\n): { x: number; y: number } {\n const rings = ringsOf(geometry);\n const outer = rings.reduce((a, b) => (b.length > a.length ? b : a), rings[0] ?? []);\n let sx = 0;\n let sy = 0;\n for (const [lon, lat] of outer) {\n const p = projection.project({ latitude: lat, longitude: lon });\n sx += p.x;\n sy += p.y;\n }\n const n = outer.length || 1;\n return { x: sx / n, y: sy / n };\n}\n\n/** Linearly interpolate between two hex colors, returning an `rgb(...)` string. */\nexport function lerpColor(from: string, to: string, t: number): string {\n const parse = (c: string): [number, number, number] => {\n const hex = c.replace(\"#\", \"\");\n const full =\n hex.length === 3\n ? hex\n .split(\"\")\n .map((ch) => ch + ch)\n .join(\"\")\n : hex;\n return [\n parseInt(full.slice(0, 2), 16),\n parseInt(full.slice(2, 4), 16),\n parseInt(full.slice(4, 6), 16),\n ];\n };\n const [r1, g1, b1] = parse(from);\n const [r2, g2, b2] = parse(to);\n const mix = (a: number, b: number): number => Math.round(a + (b - a) * t);\n return `rgb(${mix(r1, r2)}, ${mix(g1, g2)}, ${mix(b1, b2)})`;\n}\n","import { useCallback, useState, type MouseEvent, type RefObject } from \"react\";\n\n/** The currently hovered item plus cursor position within the map container. */\nexport interface MapHover<T> {\n item: T;\n x: number;\n y: number;\n}\n\n/**\n * Track which shape the cursor is over and where, for a floating map tooltip.\n * Positions are computed relative to `containerRef` so the tooltip can be\n * placed with plain `left`/`top` inside the (relatively positioned) container.\n */\nexport function useMapHover<T>(containerRef: RefObject<HTMLDivElement | null>): {\n hover: MapHover<T> | null;\n onMove: (item: T, event: MouseEvent) => void;\n onLeave: () => void;\n} {\n const [hover, setHover] = useState<MapHover<T> | null>(null);\n\n const onMove = useCallback(\n (item: T, event: MouseEvent): void => {\n const rect = containerRef.current?.getBoundingClientRect();\n if (!rect) return;\n setHover({ item, x: event.clientX - rect.left, y: event.clientY - rect.top });\n },\n [containerRef],\n );\n\n const onLeave = useCallback((): void => setHover(null), []);\n\n return { hover, onMove, onLeave };\n}\n","import { useEffect, useMemo, useRef, useState, type HTMLAttributes, type ReactNode } from \"react\";\nimport { cn } from \"@/utils/cn\";\nimport { fitProjection } from \"@/geo/projection\";\nimport type { GeoMarker } from \"@/geo/types\";\nimport type { BrUfFeatureCollection } from \"./br-geo\";\nimport { getState, type UF } from \"./locations\";\nimport { MapMarkers } from \"./MapMarkers\";\nimport { MapTooltip } from \"./MapTooltip\";\nimport { REGION_COLORS } from \"./regions\";\nimport type { ColorScale } from \"./scales\";\nimport { useMapZoom } from \"./use-map-zoom\";\nimport { geometriesBounds, geometryCentroid, geometryPath, lerpColor } from \"./svg-utils\";\nimport { useMapHover } from \"./use-map-hover\";\nimport styles from \"./BrazilMap.module.css\";\n\n/** Data passed to a {@link BrazilMapProps.renderTooltip} callback. */\nexport interface BrazilMapTooltipData {\n uf: UF;\n name: string;\n /** Choropleth value for this UF, if `values` was provided. */\n value?: number;\n}\n\nexport interface BrazilMapProps extends Omit<HTMLAttributes<HTMLDivElement>, \"onSelect\"> {\n /** Currently selected UF(s) — highlighted. Accepts one or many. */\n selected?: UF | readonly UF[] | null;\n /** Fired when a state is clicked. */\n onSelect?: (uf: UF) => void;\n /**\n * Optional choropleth values per UF. When set, each state is tinted between\n * `minColor` and `maxColor` by its value (linear). States without a value\n * use the base surface color.\n */\n values?: Partial<Record<UF, number>>;\n /** Choropleth low-end color (2-color linear ramp). Default: a light primary tint. */\n minColor?: string;\n /** Choropleth high-end color (2-color linear ramp). Default: the primary token. */\n maxColor?: string;\n /**\n * Custom value→color scale (e.g. from `sequentialScale`/`quantizeScale`).\n * Takes precedence over `minColor`/`maxColor`. Pair with a `<MapLegend>`.\n */\n colorScale?: ColorScale;\n /**\n * Tint each state by its macro-region (categorical). Overrides\n * `values`/`colorScale`. Pair with `<MapLegend items={regionLegendItems()} />`.\n */\n colorByRegion?: boolean;\n /** Viewport height in pixels. Default: `440`. */\n height?: number;\n /** Inner padding in pixels. Default: `12`. */\n padding?: number;\n /** Render the UF acronym at each state centroid. Default: `true`. */\n showLabels?: boolean;\n /** Accessible label for the map region. Default: `\"Mapa do Brasil por estado\"`. */\n label?: string;\n /** Custom content when the geometry is still loading. */\n loadingContent?: ReactNode;\n /** Show a floating tooltip (name + region + city count + value) on hover. Default: `true`. */\n showTooltip?: boolean;\n /** Override the default tooltip content. */\n renderTooltip?: (data: BrazilMapTooltipData) => ReactNode;\n /** Point markers to overlay on the map (e.g. capitals, stores). */\n markers?: readonly GeoMarker[];\n /** Fired when a marker is clicked. */\n onMarkerClick?: (marker: GeoMarker, index: number) => void;\n /** Enable wheel-zoom + drag-pan (double-click resets). Default: `false`. */\n zoomable?: boolean;\n}\n\n/**\n * Clickable choropleth map of Brazil's 27 federative units. Renders the bundled\n * simplified UF GeoJSON as SVG paths — **no external tiles or paid API**. Click\n * a state to fire `onSelect(uf)`; pass `selected` to highlight and `values` to\n * tint states by a metric.\n *\n * The GeoJSON (~36 KB gzip) is loaded lazily, so importing this component does\n * not pull the geometry until it actually mounts.\n *\n * @example\n * const [uf, setUf] = useState<UF | null>(null);\n * <BrazilMap selected={uf} onSelect={setUf} />\n *\n * @example\n * // Choropleth by a metric per state\n * <BrazilMap values={{ SP: 120, RJ: 90, MG: 60 }} />\n */\nexport function BrazilMap({\n selected,\n onSelect,\n values,\n minColor = \"#dbeafe\",\n maxColor = \"#2563eb\",\n colorScale,\n colorByRegion = false,\n height = 440,\n padding = 12,\n showLabels = true,\n label = \"Mapa do Brasil por estado\",\n loadingContent,\n showTooltip = true,\n renderTooltip,\n markers,\n onMarkerClick,\n zoomable = false,\n className,\n style,\n ...rest\n}: BrazilMapProps) {\n const containerRef = useRef<HTMLDivElement>(null);\n const [width, setWidth] = useState<number>(600);\n const [collection, setCollection] = useState<BrUfFeatureCollection | null>(null);\n const { hover, onMove, onLeave } = useMapHover<{ uf: UF; name: string }>(containerRef);\n const mapZoom = useMapZoom(zoomable);\n\n useEffect(() => {\n let active = true;\n void import(\"./br-geo\").then((m) => {\n if (active) setCollection(m.BR_UF_GEOJSON);\n });\n return () => {\n active = false;\n };\n }, []);\n\n useEffect(() => {\n const node = containerRef.current;\n if (!node || typeof ResizeObserver === \"undefined\") return;\n const observer = new ResizeObserver((entries) => {\n const measured = entries[0]?.contentRect.width;\n if (measured && measured > 0) setWidth(measured);\n });\n observer.observe(node);\n return () => observer.disconnect();\n }, []);\n\n const selectedSet = useMemo<Set<UF>>(() => {\n if (!selected) return new Set();\n return new Set(Array.isArray(selected) ? selected : [selected as UF]);\n }, [selected]);\n\n const valueRange = useMemo<[number, number] | null>(() => {\n if (!values) return null;\n const nums = Object.values(values).filter((v): v is number => typeof v === \"number\");\n if (nums.length === 0) return null;\n return [Math.min(...nums), Math.max(...nums)];\n }, [values]);\n\n const shapes = useMemo(() => {\n if (!collection) return null;\n const projection = fitProjection(\n geometriesBounds(collection.features.map((f) => f.geometry)),\n width,\n height,\n { padding },\n );\n const items = collection.features.map((feature) => ({\n uf: feature.properties.uf,\n name: feature.properties.name,\n region: feature.properties.region,\n d: geometryPath(feature.geometry, projection),\n centroid: geometryCentroid(feature.geometry, projection),\n }));\n return { projection, items };\n }, [collection, width, height, padding]);\n\n function fillFor(uf: UF): string | undefined {\n const v = values?.[uf];\n if (typeof v !== \"number\") return undefined;\n if (colorScale) return colorScale(v);\n if (!valueRange) return undefined;\n const [min, max] = valueRange;\n const t = max === min ? 1 : (v - min) / (max - min);\n return lerpColor(minColor, maxColor, t);\n }\n\n // Memoized so frequent re-renders (hover tooltip) don't rebuild all 27 paths.\n const stateEls = useMemo(() => {\n if (!shapes) return null;\n return shapes.items.map((shape) => {\n const isSelected = selectedSet.has(shape.uf);\n const fillColor = isSelected\n ? undefined\n : colorByRegion\n ? REGION_COLORS[shape.region]\n : fillFor(shape.uf);\n return (\n <path\n key={shape.uf}\n className={cn(styles.state, isSelected && styles.selected)}\n d={shape.d}\n fillRule=\"evenodd\"\n style={fillColor ? { fill: fillColor } : undefined}\n data-uf={shape.uf}\n tabIndex={onSelect ? 0 : undefined}\n role={onSelect ? \"button\" : undefined}\n aria-label={shape.name}\n aria-pressed={onSelect ? isSelected : undefined}\n onClick={onSelect ? () => onSelect(shape.uf) : undefined}\n onMouseMove={\n showTooltip\n ? (e) => onMove({ uf: shape.uf, name: shape.name }, e)\n : undefined\n }\n onMouseLeave={showTooltip ? onLeave : undefined}\n onKeyDown={\n onSelect\n ? (e) => {\n if (e.key === \"Enter\" || e.key === \" \") {\n e.preventDefault();\n onSelect(shape.uf);\n }\n }\n : undefined\n }\n />\n );\n });\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [\n shapes,\n selectedSet,\n values,\n colorScale,\n colorByRegion,\n minColor,\n maxColor,\n onSelect,\n showTooltip,\n onMove,\n onLeave,\n ]);\n\n return (\n <div\n ref={containerRef}\n className={cn(styles.map, className)}\n style={{ height, ...style }}\n role=\"group\"\n aria-label={label}\n {...rest}\n >\n {!shapes ? (\n <div className={styles.loading}>{loadingContent ?? \"Carregando mapa…\"}</div>\n ) : (\n <svg\n className={styles.svg}\n width=\"100%\"\n height={height}\n viewBox={`0 0 ${width} ${height}`}\n preserveAspectRatio=\"xMidYMid meet\"\n {...mapZoom.handlers}\n >\n <g transform={mapZoom.transform || undefined}>\n {stateEls}\n\n {showLabels &&\n shapes.items.map((shape) => (\n <text\n key={`label-${shape.uf}`}\n className={styles.label}\n x={shape.centroid.x}\n y={shape.centroid.y}\n textAnchor=\"middle\"\n dominantBaseline=\"central\"\n >\n {shape.uf}\n </text>\n ))}\n\n {markers && markers.length > 0 && (\n <MapMarkers\n projection={shapes.projection}\n markers={markers}\n onMarkerClick={onMarkerClick}\n />\n )}\n </g>\n </svg>\n )}\n\n {mapZoom.isTransformed && (\n <button type=\"button\" className={styles.zoomReset} onClick={mapZoom.reset}>\n Reset\n </button>\n )}\n\n {showTooltip && hover && (\n <MapTooltip x={hover.x} y={hover.y}>\n {renderTooltip ? (\n renderTooltip({\n uf: hover.item.uf,\n name: hover.item.name,\n value: values?.[hover.item.uf],\n })\n ) : (\n <DefaultUfTooltip\n uf={hover.item.uf}\n name={hover.item.name}\n value={values?.[hover.item.uf]}\n />\n )}\n </MapTooltip>\n )}\n </div>\n );\n}\n\n/** Default UF tooltip: name (UF) + region + city count + optional value. */\nfunction DefaultUfTooltip({ uf, name, value }: { uf: UF; name: string; value?: number }) {\n const state = getState(uf);\n return (\n <>\n <div className={styles.tooltipTitle}>\n {name} ({uf})\n </div>\n <div className={styles.tooltipMeta}>\n {state ? `${state.region} · ${state.cities.length} cidades` : uf}\n {typeof value === \"number\" ? ` · ${value}` : \"\"}\n </div>\n </>\n );\n}\n","import { useEffect, useMemo, useRef, useState, type HTMLAttributes, type ReactNode } from \"react\";\nimport { cn } from \"@/utils/cn\";\nimport { fitProjection } from \"@/geo/projection\";\nimport type { GeoMarker } from \"@/geo/types\";\nimport { getState, type UF } from \"./locations\";\nimport { MapMarkers } from \"./MapMarkers\";\nimport { MapTooltip } from \"./MapTooltip\";\nimport type { ColorScale } from \"./scales\";\nimport { useMapZoom } from \"./use-map-zoom\";\nimport { loadStateMunicipalities, type StateMunicipalities } from \"./state-geo\";\nimport { geometriesBounds, geometryCentroid, geometryPath, lerpColor } from \"./svg-utils\";\nimport { useMapHover } from \"./use-map-hover\";\nimport styles from \"./BrazilMap.module.css\";\n\n/** A municipality identified for selection callbacks. */\nexport interface Municipality {\n /** 7-digit IBGE code. */\n id: string;\n /** Municipality name. */\n name: string;\n}\n\n/** Data passed to a {@link BrazilStateMapProps.renderTooltip} callback. */\nexport interface BrazilStateMapTooltipData extends Municipality {\n /** Choropleth value for this municipality, if `values` was provided. */\n value?: number;\n}\n\nexport interface BrazilStateMapProps extends Omit<HTMLAttributes<HTMLDivElement>, \"onSelect\"> {\n /** Federative unit to draw (required). */\n uf: UF;\n /** Selected municipality — matched by IBGE `id` or by `name`. Accepts many. */\n selected?: string | readonly string[] | null;\n /** Fired when a municipality is clicked. */\n onSelect?: (municipality: Municipality) => void;\n /**\n * Choropleth values keyed by municipality `id` **or** `name`. When set, each\n * municipality is tinted between `minColor` and `maxColor`.\n */\n values?: Record<string, number>;\n /** Choropleth low-end color (2-color linear ramp). Default: a light primary tint. */\n minColor?: string;\n /** Choropleth high-end color (2-color linear ramp). Default: the primary token. */\n maxColor?: string;\n /**\n * Custom value→color scale (from `sequentialScale`/`quantizeScale`). Takes\n * precedence over `minColor`/`maxColor`. Pair with a `<MapLegend>`.\n */\n colorScale?: ColorScale;\n /** Viewport height in pixels. Default: `440`. */\n height?: number;\n /** Inner padding in pixels. Default: `12`. */\n padding?: number;\n /**\n * Render each municipality name at its centroid. Off by default — a state\n * can have hundreds of municipalities and labels overlap badly.\n */\n showLabels?: boolean;\n /** Accessible label. Default: derived from the state name. */\n label?: string;\n /** Content while the state geometry is loading. */\n loadingContent?: ReactNode;\n /** Show a floating tooltip (name + IBGE code + value) on hover. Default: `true`. */\n showTooltip?: boolean;\n /** Override the default tooltip content. */\n renderTooltip?: (data: BrazilStateMapTooltipData) => ReactNode;\n /** Point markers to overlay on the state (e.g. addresses, POIs). */\n markers?: readonly GeoMarker[];\n /** Fired when a marker is clicked. */\n onMarkerClick?: (marker: GeoMarker, index: number) => void;\n /** Enable wheel-zoom + drag-pan (double-click resets). Default: `false`. */\n zoomable?: boolean;\n}\n\n/**\n * Clickable submap of a single Brazilian state showing **all its\n * municipalities** as SVG paths — no external tiles or paid API. The state's\n * geometry (~40-70 KB gzip) is loaded lazily per UF, so switching states fetches\n * only what is shown.\n *\n * @example\n * const [city, setCity] = useState<string | null>(null);\n * <BrazilStateMap uf=\"SP\" selected={city} onSelect={(m) => setCity(m.name)} />\n *\n * @example\n * // Choropleth of a metric by municipality name\n * <BrazilStateMap uf=\"RJ\" values={{ \"Rio de Janeiro\": 100, Niterói: 40 }} />\n */\nexport function BrazilStateMap({\n uf,\n selected,\n onSelect,\n values,\n minColor = \"#dbeafe\",\n maxColor = \"#2563eb\",\n colorScale,\n height = 440,\n padding = 12,\n showLabels = false,\n label,\n loadingContent,\n showTooltip = true,\n renderTooltip,\n markers,\n onMarkerClick,\n zoomable = false,\n className,\n style,\n ...rest\n}: BrazilStateMapProps) {\n const containerRef = useRef<HTMLDivElement>(null);\n const [width, setWidth] = useState<number>(600);\n const [collection, setCollection] = useState<StateMunicipalities | null>(null);\n const mapZoom = useMapZoom(zoomable);\n const { hover, onMove, onLeave } = useMapHover<Municipality>(containerRef);\n\n useEffect(() => {\n let active = true;\n setCollection(null);\n void loadStateMunicipalities(uf).then((data) => {\n if (active) setCollection(data);\n });\n return () => {\n active = false;\n };\n }, [uf]);\n\n useEffect(() => {\n const node = containerRef.current;\n if (!node || typeof ResizeObserver === \"undefined\") return;\n const observer = new ResizeObserver((entries) => {\n const measured = entries[0]?.contentRect.width;\n if (measured && measured > 0) setWidth(measured);\n });\n observer.observe(node);\n return () => observer.disconnect();\n }, []);\n\n const selectedSet = useMemo<Set<string>>(() => {\n if (!selected) return new Set();\n return new Set(Array.isArray(selected) ? selected : [selected as string]);\n }, [selected]);\n\n const valueRange = useMemo<[number, number] | null>(() => {\n if (!values) return null;\n const nums = Object.values(values).filter((v): v is number => typeof v === \"number\");\n if (nums.length === 0) return null;\n return [Math.min(...nums), Math.max(...nums)];\n }, [values]);\n\n const shapes = useMemo(() => {\n if (!collection) return null;\n const projection = fitProjection(\n geometriesBounds(collection.features.map((f) => f.geometry)),\n width,\n height,\n { padding },\n );\n const items = collection.features.map((feature) => ({\n id: feature.properties.id,\n name: feature.properties.name,\n d: geometryPath(feature.geometry, projection),\n centroid: geometryCentroid(feature.geometry, projection),\n }));\n return { projection, items };\n }, [collection, width, height, padding]);\n\n function fillFor(id: string, name: string): string | undefined {\n const v = values?.[id] ?? values?.[name];\n if (typeof v !== \"number\") return undefined;\n if (colorScale) return colorScale(v);\n if (!valueRange) return undefined;\n const [min, max] = valueRange;\n const t = max === min ? 1 : (v - min) / (max - min);\n return lerpColor(minColor, maxColor, t);\n }\n\n // Memoized so hover re-renders don't rebuild hundreds of municipality paths.\n const cityEls = useMemo(() => {\n if (!shapes) return null;\n return shapes.items.map((shape) => {\n const isSelected = selectedSet.has(shape.id) || selectedSet.has(shape.name);\n const fillColor = isSelected ? undefined : fillFor(shape.id, shape.name);\n return (\n <path\n key={shape.id}\n className={cn(styles.state, isSelected && styles.selected)}\n d={shape.d}\n fillRule=\"evenodd\"\n style={fillColor ? { fill: fillColor } : undefined}\n data-city-id={shape.id}\n data-city={shape.name}\n tabIndex={onSelect ? 0 : undefined}\n role={onSelect ? \"button\" : undefined}\n aria-label={shape.name}\n aria-pressed={onSelect ? isSelected : undefined}\n onClick={\n onSelect ? () => onSelect({ id: shape.id, name: shape.name }) : undefined\n }\n onMouseMove={\n showTooltip\n ? (e) => onMove({ id: shape.id, name: shape.name }, e)\n : undefined\n }\n onMouseLeave={showTooltip ? onLeave : undefined}\n onKeyDown={\n onSelect\n ? (e) => {\n if (e.key === \"Enter\" || e.key === \" \") {\n e.preventDefault();\n onSelect({ id: shape.id, name: shape.name });\n }\n }\n : undefined\n }\n />\n );\n });\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [\n shapes,\n selectedSet,\n values,\n colorScale,\n minColor,\n maxColor,\n onSelect,\n showTooltip,\n onMove,\n onLeave,\n ]);\n\n const resolvedLabel = label ?? `Municípios de ${getState(uf)?.name ?? uf}`;\n\n return (\n <div\n ref={containerRef}\n className={cn(styles.map, className)}\n style={{ height, ...style }}\n role=\"group\"\n aria-label={resolvedLabel}\n {...rest}\n >\n {!shapes ? (\n <div className={styles.loading}>{loadingContent ?? \"Carregando municípios…\"}</div>\n ) : (\n <svg\n className={styles.svg}\n width=\"100%\"\n height={height}\n viewBox={`0 0 ${width} ${height}`}\n preserveAspectRatio=\"xMidYMid meet\"\n {...mapZoom.handlers}\n >\n <g transform={mapZoom.transform || undefined}>\n {cityEls}\n\n {showLabels &&\n shapes.items.map((shape) => (\n <text\n key={`label-${shape.id}`}\n className={styles.label}\n x={shape.centroid.x}\n y={shape.centroid.y}\n textAnchor=\"middle\"\n dominantBaseline=\"central\"\n >\n {shape.name}\n </text>\n ))}\n\n {markers && markers.length > 0 && (\n <MapMarkers\n projection={shapes.projection}\n markers={markers}\n onMarkerClick={onMarkerClick}\n />\n )}\n </g>\n </svg>\n )}\n\n {mapZoom.isTransformed && (\n <button type=\"button\" className={styles.zoomReset} onClick={mapZoom.reset}>\n Reset\n </button>\n )}\n\n {showTooltip && hover && (\n <MapTooltip x={hover.x} y={hover.y}>\n {renderTooltip ? (\n renderTooltip({\n ...hover.item,\n value: values?.[hover.item.id] ?? values?.[hover.item.name],\n })\n ) : (\n <>\n <div className={styles.tooltipTitle}>{hover.item.name}</div>\n <div className={styles.tooltipMeta}>\n IBGE {hover.item.id}\n {(() => {\n const v = values?.[hover.item.id] ?? values?.[hover.item.name];\n return typeof v === \"number\" ? ` · ${v}` : \"\";\n })()}\n </div>\n </>\n )}\n </MapTooltip>\n )}\n </div>\n );\n}\n","import { useMemo, useState, type ReactElement } from \"react\";\nimport { Select } from \"@/components/Select\";\nimport { cityChoices, listStates, normalizeUf, type UF } from \"./locations\";\n\n/** Current selection emitted by {@link BrazilStateCitySelect}. */\nexport interface BrazilStateCitySelection {\n /** Selected federative unit, or `null` when none. */\n uf: UF | null;\n /** Selected city, or `null` when none. */\n city: string | null;\n}\n\nexport interface BrazilStateCitySelectProps {\n /** Pre-selected UF (uncontrolled initial value). */\n defaultUf?: UF;\n /** Pre-selected city (uncontrolled initial value). */\n defaultCity?: string;\n /** Fired whenever the state or city changes. */\n onChange?: (selection: BrazilStateCitySelection) => void;\n /** Label for the state select. Default: `\"Estado\"`. */\n stateLabel?: string;\n /** Label for the city select. Default: `\"Cidade\"`. */\n cityLabel?: string;\n /** Placeholder for the state select. Default: `\"Selecione o estado\"`. */\n statePlaceholder?: string;\n /** Placeholder for the city select. Default: `\"Selecione a cidade\"`. */\n cityPlaceholder?: string;\n /** Disable both selects. */\n disabled?: boolean;\n /** Layout of the two selects. Default: `\"row\"`. */\n layout?: \"row\" | \"column\";\n}\n\n/**\n * Cascading Estado → Cidade selector backed by the bundled BR locations data —\n * pick a state and the city list narrows to that UF's municipalities. No\n * network, no external API. Complements {@link BrazilMap} (wire the map's\n * `onSelect` to drive the same UF).\n *\n * @example\n * <BrazilStateCitySelect onChange={({ uf, city }) => console.log(uf, city)} />\n */\nexport function BrazilStateCitySelect({\n defaultUf,\n defaultCity,\n onChange,\n stateLabel = \"Estado\",\n cityLabel = \"Cidade\",\n statePlaceholder = \"Selecione o estado\",\n cityPlaceholder = \"Selecione a cidade\",\n disabled = false,\n layout = \"row\",\n}: BrazilStateCitySelectProps): ReactElement {\n const [uf, setUf] = useState<UF | null>(defaultUf ?? null);\n const [city, setCity] = useState<string | null>(defaultCity ?? null);\n\n const stateOptions = useMemo(\n () => listStates().map((s) => ({ value: s.uf, label: s.name })),\n [],\n );\n const cityOptions = useMemo(() => (uf ? cityChoices(uf) : []), [uf]);\n\n function handleUf(next: string): void {\n const nextUf = normalizeUf(next);\n setUf(nextUf);\n setCity(null);\n onChange?.({ uf: nextUf, city: null });\n }\n\n function handleCity(next: string): void {\n const nextCity = next || null;\n setCity(nextCity);\n onChange?.({ uf, city: nextCity });\n }\n\n return (\n <div\n style={{\n display: \"flex\",\n flexDirection: layout === \"row\" ? \"row\" : \"column\",\n gap: \"var(--tempest-space-3, 12px)\",\n flexWrap: \"wrap\",\n }}\n >\n <Select\n label={stateLabel}\n placeholder={statePlaceholder}\n options={stateOptions}\n value={uf ?? \"\"}\n disabled={disabled}\n onChange={(e) => handleUf(e.target.value)}\n style={{ minWidth: 0 }}\n />\n <Select\n label={cityLabel}\n placeholder={cityPlaceholder}\n options={cityOptions}\n value={city ?? \"\"}\n disabled={disabled || !uf}\n onChange={(e) => handleCity(e.target.value)}\n style={{ minWidth: 0 }}\n />\n </div>\n );\n}\n","import { useEffect, useId, useRef, useState, type ReactElement } from \"react\";\nimport { Input } from \"@/components/Input\";\nimport { useDebounce } from \"@/hooks\";\nimport { searchMunicipalities, type MunicipalityCentroid } from \"./geocode\";\nimport type { UF } from \"./locations\";\nimport styles from \"./MunicipalitySearch.module.css\";\n\nexport interface MunicipalitySearchProps {\n /** Restrict the search to a single UF. */\n uf?: UF;\n /** Fired when a municipality is picked from the results. */\n onSelect: (municipality: MunicipalityCentroid) => void;\n /** Field label. */\n label?: string;\n /** Input placeholder. Default: `\"Buscar município…\"`. */\n placeholder?: string;\n /** Max results shown. Default: `8`. */\n limit?: number;\n /** Debounce in ms before searching. Default: `250`. */\n debounceMs?: number;\n /** Disable the field. */\n disabled?: boolean;\n}\n\n/**\n * Debounced municipality autocomplete backed by the offline\n * {@link searchMunicipalities} index — no network. Type a partial name, pick a\n * result, and `onSelect` fires with its `{ id, name, uf, latitude, longitude }`.\n * Wire `onSelect` to a `BrazilStateMap` `selected` to highlight it on the map.\n *\n * @example\n * const [uf, setUf] = useState<UF>(\"SP\");\n * const [city, setCity] = useState<string | null>(null);\n * <MunicipalitySearch uf={uf} onSelect={(m) => setCity(m.name)} />\n * <BrazilStateMap uf={uf} selected={city} />\n */\nexport function MunicipalitySearch({\n uf,\n onSelect,\n label,\n placeholder = \"Buscar município…\",\n limit = 8,\n debounceMs = 250,\n disabled = false,\n}: MunicipalitySearchProps): ReactElement {\n const [query, setQuery] = useState<string>(\"\");\n const [results, setResults] = useState<MunicipalityCentroid[]>([]);\n const [open, setOpen] = useState<boolean>(false);\n const debounced = useDebounce(query, debounceMs);\n const listId = useId();\n const blurTimer = useRef<ReturnType<typeof setTimeout> | null>(null);\n\n useEffect(() => {\n let active = true;\n if (!debounced.trim()) {\n setResults([]);\n return;\n }\n void searchMunicipalities(debounced, { uf, limit }).then((hits) => {\n if (active) setResults(hits);\n });\n return () => {\n active = false;\n };\n }, [debounced, uf, limit]);\n\n function choose(municipality: MunicipalityCentroid): void {\n onSelect(municipality);\n setQuery(municipality.name);\n setOpen(false);\n }\n\n return (\n <div className={styles.search}>\n <Input\n label={label}\n value={query}\n placeholder={placeholder}\n disabled={disabled}\n role=\"combobox\"\n aria-expanded={open && results.length > 0}\n aria-controls={listId}\n autoComplete=\"off\"\n onChange={(e) => {\n setQuery(e.target.value);\n setOpen(true);\n }}\n onFocus={() => setOpen(true)}\n onBlur={() => {\n // Delay so a result click registers before the list closes.\n blurTimer.current = setTimeout(() => setOpen(false), 120);\n }}\n />\n {open && results.length > 0 && (\n <ul id={listId} className={styles.results} role=\"listbox\">\n {results.map((m) => (\n <li key={m.id}>\n <button\n type=\"button\"\n role=\"option\"\n aria-selected={false}\n className={styles.result}\n onMouseDown={(e) => e.preventDefault()}\n onClick={() => {\n if (blurTimer.current) clearTimeout(blurTimer.current);\n choose(m);\n }}\n >\n <span>{m.name}</span>\n <span className={styles.uf}>{m.uf}</span>\n </button>\n </li>\n ))}\n </ul>\n )}\n </div>\n );\n}\n","import { lerpColor } from \"./svg-utils\";\n\n/** Maps a numeric value to a CSS color string. */\nexport type ColorScale = (value: number) => string;\n\n/**\n * Sequential, colorblind-safe palettes (ColorBrewer / Viridis families, public\n * domain). Ordered light → dark. Swap for your brand ramp if needed — any\n * ordered list of hex colors works with the scale builders below.\n */\nexport const SEQUENTIAL_BLUES = [\n \"#eff3ff\",\n \"#c6dbef\",\n \"#9ecae1\",\n \"#6baed6\",\n \"#3182bd\",\n \"#08519c\",\n] as const;\n\nexport const SEQUENTIAL_GREENS = [\n \"#edf8e9\",\n \"#c7e9c0\",\n \"#a1d99b\",\n \"#74c476\",\n \"#31a354\",\n \"#006d2c\",\n] as const;\n\nexport const SEQUENTIAL_VIRIDIS = [\n \"#440154\",\n \"#414487\",\n \"#2a788e\",\n \"#22a884\",\n \"#7ad151\",\n \"#fde725\",\n] as const;\n\n/** Diverging palette (red ↔ neutral ↔ blue), for signed metrics. */\nexport const DIVERGING_RDBU = [\n \"#b2182b\",\n \"#ef8a62\",\n \"#fddbc7\",\n \"#d1e5f0\",\n \"#67a9cf\",\n \"#2166ac\",\n] as const;\n\n/**\n * Interpolate a palette at `t ∈ [0, 1]`, blending between the two nearest\n * stops. `t <= 0` → first color, `t >= 1` → last.\n */\nexport function interpolatePalette(palette: readonly string[], t: number): string {\n if (palette.length === 0) return \"#000000\";\n if (palette.length === 1) return palette[0];\n const clamped = Math.max(0, Math.min(1, t));\n const scaled = clamped * (palette.length - 1);\n const i = Math.floor(scaled);\n if (i >= palette.length - 1) return palette[palette.length - 1];\n return lerpColor(palette[i], palette[i + 1], scaled - i);\n}\n\n/**\n * Continuous scale: linearly interpolate `palette` across `[min, max]`.\n *\n * @example\n * const color = sequentialScale(0, 100, SEQUENTIAL_BLUES);\n * <BrazilMap values={data} colorScale={color} />;\n */\nexport function sequentialScale(\n min: number,\n max: number,\n palette: readonly string[] = SEQUENTIAL_BLUES,\n): ColorScale {\n const span = max - min || 1;\n return (value) => interpolatePalette(palette, (value - min) / span);\n}\n\n/**\n * Discrete scale: split `[min, max]` into `palette.length` equal buckets and\n * return the bucket's color (a classic choropleth \"quantize\" scale).\n */\nexport function quantizeScale(\n min: number,\n max: number,\n palette: readonly string[] = SEQUENTIAL_BLUES,\n): ColorScale {\n const span = max - min || 1;\n const n = palette.length;\n return (value) => {\n const idx = Math.min(n - 1, Math.max(0, Math.floor(((value - min) / span) * n)));\n return palette[idx];\n };\n}\n\n/**\n * Threshold scale: `palette[i]` applies to values in\n * `[thresholds[i-1], thresholds[i])`. `palette` must have\n * `thresholds.length + 1` entries.\n *\n * @example\n * const color = thresholdScale([10, 50, 100], SEQUENTIAL_GREENS.slice(0, 4));\n */\nexport function thresholdScale(\n thresholds: readonly number[],\n palette: readonly string[],\n): ColorScale {\n return (value) => {\n let i = 0;\n while (i < thresholds.length && value >= thresholds[i]) i += 1;\n return palette[Math.min(i, palette.length - 1)];\n };\n}\n","import type { HTMLAttributes, ReactNode } from \"react\";\nimport { cn } from \"@/utils/cn\";\nimport { SEQUENTIAL_BLUES } from \"./scales\";\nimport styles from \"./MapLegend.module.css\";\n\n/** A discrete legend entry. */\nexport interface LegendItem {\n color: string;\n label: ReactNode;\n}\n\nexport interface MapLegendProps extends Omit<HTMLAttributes<HTMLDivElement>, \"title\"> {\n /** Legend heading. */\n title?: ReactNode;\n /**\n * Discrete entries (swatch + label). When provided the legend renders in\n * \"steps\" mode; otherwise it renders a continuous gradient from `min`/`max`.\n */\n items?: readonly LegendItem[];\n /** Continuous mode: low end of the domain. */\n min?: number;\n /** Continuous mode: high end of the domain. */\n max?: number;\n /** Continuous mode: palette (light → dark). Default: sequential blues. */\n palette?: readonly string[];\n /** Continuous mode: format the min/mid/max tick labels. */\n format?: (value: number) => string;\n}\n\n/**\n * Legend for a choropleth map. Renders a **continuous gradient** (with\n * min/mid/max ticks) from `min`/`max`/`palette`, or **discrete swatches** when\n * `items` is given. Pair it with a `BrazilMap`/`BrazilStateMap` `colorScale`.\n *\n * @example\n * // Continuous, matching a sequentialScale(0, 100)\n * <MapLegend title=\"Vendas\" min={0} max={100} palette={SEQUENTIAL_BLUES} />\n *\n * @example\n * // Discrete buckets\n * <MapLegend\n * title=\"Faixa\"\n * items={[\n * { color: \"#c6dbef\", label: \"< 10\" },\n * { color: \"#6baed6\", label: \"10–50\" },\n * { color: \"#08519c\", label: \"> 50\" },\n * ]}\n * />\n */\nexport function MapLegend({\n title,\n items,\n min = 0,\n max = 1,\n palette = SEQUENTIAL_BLUES,\n format = (v) => String(Math.round(v)),\n className,\n ...rest\n}: MapLegendProps) {\n return (\n <div className={cn(styles.legend, className)} {...rest}>\n {title != null && <div className={styles.title}>{title}</div>}\n\n {items ? (\n <ul className={styles.items}>\n {items.map((item, i) => (\n <li key={i} className={styles.item}>\n <span className={styles.swatch} style={{ background: item.color }} />\n <span className={styles.itemLabel}>{item.label}</span>\n </li>\n ))}\n </ul>\n ) : (\n <>\n <div\n className={styles.gradient}\n style={{ background: `linear-gradient(to right, ${palette.join(\", \")})` }}\n />\n <div className={styles.ticks}>\n <span>{format(min)}</span>\n <span>{format((min + max) / 2)}</span>\n <span>{format(max)}</span>\n </div>\n </>\n )}\n </div>\n );\n}\n","// Brazilian locations data (states + cities) — mirrors the `utils/locations`\n// module of tempest-fastapi-sdk.\nexport {\n listStates,\n getState,\n citiesByUf,\n statesByRegion,\n isValidUf,\n normalizeUf,\n isValidCity,\n ufChoices,\n cityChoices,\n} from \"./locations\";\nexport type { UF, BrRegion, BrazilState, Choice } from \"./locations\";\n\n// UF GeoJSON types (the geometry itself is lazy-loaded by BrazilMap).\nimport type { BrUfFeatureCollection } from \"./br-geo\";\nexport type { BrUfFeature, BrUfFeatureCollection, BrUfGeometry, Ring } from \"./br-geo\";\n\n/**\n * Lazily load the bundled simplified UF GeoJSON (~36 KB gzip). Kept out of the\n * synchronous barrel so a data-only import never pulls the geometry.\n */\nexport async function loadBrUfGeoJson(): Promise<BrUfFeatureCollection> {\n const mod = await import(\"./br-geo\");\n return mod.BR_UF_GEOJSON;\n}\n\n// Per-state municipality geometry (lazy, one chunk per UF).\nexport { loadStateMunicipalities } from \"./state-geo\";\nexport type { MunicipalityFeature, StateMunicipalities } from \"./state-geo\";\n\n// Offline geocoding (lazy centroid index).\nexport {\n nearestMunicipality,\n reverseGeocode,\n geocodeMunicipality,\n searchMunicipalities,\n municipalityCentroid,\n stateCentroid,\n} from \"./geocode\";\nexport type { MunicipalityCentroid, NearestMunicipality, ReverseGeocodeResult } from \"./geocode\";\n\n// Components\nexport { BrazilMap } from \"./BrazilMap\";\nexport type { BrazilMapProps, BrazilMapTooltipData } from \"./BrazilMap\";\nexport { BrazilStateMap } from \"./BrazilStateMap\";\nexport type {\n BrazilStateMapProps,\n BrazilStateMapTooltipData,\n Municipality,\n} from \"./BrazilStateMap\";\nexport { BrazilStateCitySelect } from \"./BrazilStateCitySelect\";\nexport type { BrazilStateCitySelectProps, BrazilStateCitySelection } from \"./BrazilStateCitySelect\";\nexport { MunicipalitySearch } from \"./MunicipalitySearch\";\nexport type { MunicipalitySearchProps } from \"./MunicipalitySearch\";\nexport type { GeoMarker } from \"@/geo/types\";\nexport { MapMarkers } from \"./MapMarkers\";\nexport type { MapMarkersProps } from \"./MapMarkers\";\nexport { MapLegend } from \"./MapLegend\";\nexport type { MapLegendProps, LegendItem } from \"./MapLegend\";\n\n// Color scales + palettes for choropleths.\nexport {\n interpolatePalette,\n sequentialScale,\n quantizeScale,\n thresholdScale,\n SEQUENTIAL_BLUES,\n SEQUENTIAL_GREENS,\n SEQUENTIAL_VIRIDIS,\n DIVERGING_RDBU,\n} from \"./scales\";\nexport type { ColorScale } from \"./scales\";\nexport { REGION_COLORS, regionLegendItems } from \"./regions\";\n"],"names":["REGION_BY_UF","RAW","rawLocations","STATES","entry","uf","b","STATE_BY_UF","s","listStates","getState","normalized","normalizeUf","citiesByUf","statesByRegion","region","isValidUf","value","upper","isValidCity","city","target","c","ufChoices","cityChoices","LOADERS","loadStateMunicipalities","loader","mod","cache","pending","normalizeName","loadIndex","raw","states","lon","lat","id","name","nearestMunicipality","coord","municipalities","best","bestDistance","m","d","haversineKm","geocodeMunicipality","searchMunicipalities","query","options","limit","q","a","ap","bp","municipalityCentroid","stateCentroid","pointInRing","ring","inside","i","j","xi","yi","xj","yj","pointInPolygon","rings","pointInGeometry","geom","poly","reverseGeocode","nearest","hit","f","fallback","MapMarkers","projection","markers","onMarkerClick","jsx","styles","marker","index","p","interactive","e","MapTooltip","x","y","children","className","cn","REGION_COLORS","regionLegendItems","MIN_K","MAX_K","useMapZoom","enabled","t","setT","useState","drag","useRef","reset","useCallback","onWheel","rect","cx","cy","prev","factor","k","scale","onPointerDown","onPointerMove","dx","dy","endDrag","isTransformed","ringsOf","geometry","geometriesBounds","geometries","minLat","maxLat","minLon","maxLon","geometryPath","geometryCentroid","outer","sx","sy","n","lerpColor","from","to","parse","hex","full","ch","r1","g1","b1","r2","g2","b2","mix","useMapHover","containerRef","hover","setHover","onMove","item","event","onLeave","BrazilMap","selected","onSelect","values","minColor","maxColor","colorScale","colorByRegion","height","padding","showLabels","label","loadingContent","showTooltip","renderTooltip","zoomable","style","rest","width","setWidth","collection","setCollection","mapZoom","useEffect","active","node","observer","entries","measured","selectedSet","useMemo","valueRange","nums","v","shapes","fitProjection","items","feature","fillFor","min","max","stateEls","shape","isSelected","fillColor","jsxs","DefaultUfTooltip","state","Fragment","BrazilStateMap","data","cityEls","resolvedLabel","BrazilStateCitySelect","defaultUf","defaultCity","onChange","stateLabel","cityLabel","statePlaceholder","cityPlaceholder","disabled","layout","setUf","setCity","stateOptions","cityOptions","handleUf","next","nextUf","handleCity","nextCity","Select","MunicipalitySearch","placeholder","debounceMs","setQuery","results","setResults","open","setOpen","debounced","useDebounce","listId","useId","blurTimer","hits","choose","municipality","Input","SEQUENTIAL_BLUES","SEQUENTIAL_GREENS","SEQUENTIAL_VIRIDIS","DIVERGING_RDBU","interpolatePalette","palette","scaled","sequentialScale","span","quantizeScale","idx","thresholdScale","thresholds","MapLegend","title","format","loadBrUfGeoJson"],"mappings":"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"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
"use strict";const a=require("react/jsx-runtime"),x=require("react"),b=require("./cn-CNScIEB4.cjs"),w="tempest_wrapper_iHNUs",P="tempest_label_-OEBL",$="tempest_required_CTss-",q="tempest_field_65yGJ",C="tempest_input_WjT81",E="tempest_sizeSm_cgds6",A="tempest_sizeMd_EPFGy",D="tempest_sizeLg_5Cq8k",K="tempest_hasLeftIcon_xYO-v",v="tempest_hasRightIcon_C7uyr",V="tempest_iconLeft_KrUhI",U="tempest_iconRight_Ssr47",O="tempest_error_VLISa",k="tempest_helper_7Vc-s",F="tempest_errorText_xz4xS",c={wrapper:w,label:P,required:$,field:q,input:C,sizeSm:E,sizeMd:A,sizeLg:D,hasLeftIcon:K,hasRightIcon:v,iconLeft:V,iconRight:U,error:O,helper:k,errorText:F},B=x.forwardRef(function({label:t,helperText:s,error:n,leftIcon:r,rightIcon:i,wrapperClassName:o,className:_,id:M,required:f,size:h="md",...d},g){const L=x.useId(),l=M??L,p=n?`${l}-error`:s?`${l}-helper`:void 0,j=h==="sm"?c.sizeSm:h==="lg"?c.sizeLg:c.sizeMd;return a.jsxs("div",{className:b.cn(c.wrapper,n&&c.error,o),children:[t&&a.jsxs("label",{htmlFor:l,className:c.label,children:[t,f&&a.jsx("span",{className:c.required,children:"*"})]}),a.jsxs("div",{className:c.field,children:[r&&a.jsx("span",{className:c.iconLeft,children:r}),a.jsx("input",{ref:g,id:l,"aria-invalid":!!n,"aria-describedby":p,required:f,className:b.cn(c.input,j,r&&c.hasLeftIcon,i&&c.hasRightIcon,_),...d}),i&&a.jsx("span",{className:c.iconRight,children:i})]}),n?a.jsx("span",{id:`${l}-error`,className:c.errorText,children:n}):s?a.jsx("span",{id:`${l}-helper`,className:c.helper,children:s}):null]})}),H="tempest_wrapper_KS2K3",X="tempest_label_Lmgos",W="tempest_required_PvDVJ",Y="tempest_field_h-wBy",G="tempest_select_cjdcr",J="tempest_caret_MdCao",Q="tempest_error_sw9MU",Z="tempest_helper_frosK",ee="tempest_errorText_-zd6i",u={wrapper:H,label:X,required:W,field:Y,select:G,caret:J,error:Q,helper:Z,errorText:ee},te=x.forwardRef(function({label:t,helperText:s,error:n,options:r,placeholder:i,wrapperClassName:o,className:_,children:M,id:f,required:h,...d},g){const L=x.useId(),l=f??L;return a.jsxs("div",{className:b.cn(u.wrapper,n&&u.error,o),children:[t&&a.jsxs("label",{htmlFor:l,className:u.label,children:[t,h&&a.jsx("span",{className:u.required,children:"*"})]}),a.jsxs("div",{className:u.field,children:[a.jsxs("select",{ref:g,id:l,"aria-invalid":!!n,required:h,className:b.cn(u.select,_),...d,children:[i&&a.jsx("option",{value:"",disabled:!0,hidden:!0,children:i}),r?.map(p=>a.jsx("option",{value:p.value,disabled:p.disabled,children:p.label},p.value)),M]}),a.jsx("span",{className:u.caret,"aria-hidden":!0,children:a.jsx(se,{})})]}),n?a.jsx("span",{className:u.errorText,children:n}):s?a.jsx("span",{className:u.helper,children:s}):null]})});function se(){return a.jsx("svg",{width:"14",height:"14",viewBox:"0 0 24 24",fill:"none",children:a.jsx("path",{d:"M6 9l6 6 6-6",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round"})})}function ne(e,t=300){const[s,n]=x.useState(e);return x.useEffect(()=>{const r=setTimeout(()=>n(e),t);return()=>clearTimeout(r)},[e,t]),s}function R(e){return Number.isFinite(e)&&e>=-90&&e<=90}function y(e){return Number.isFinite(e)&&e>=-180&&e<=180}function ae(e){if(typeof e!="object"||e===null)return!1;const t=e;return typeof t.latitude=="number"&&typeof t.longitude=="number"&&R(t.latitude)&&y(t.longitude)}function T(e){return Math.min(90,Math.max(-90,e))}function re(e){return((e+180)%360+360)%360-180}const z=6371.0088;function m(e){return e*Math.PI/180}function S(e,t){const s=m(e.latitude),n=m(t.latitude),r=m(t.latitude-e.latitude),i=m(t.longitude-e.longitude),o=Math.sin(r/2)**2+Math.cos(s)*Math.cos(n)*Math.sin(i/2)**2;return 2*z*Math.asin(Math.sqrt(o))}function ie(e){let t=0;for(let s=1;s<e.length;s+=1)t+=S(e[s-1],e[s]);return t}function ce(e,t){const s=m(e.latitude),n=m(t.latitude),r=m(t.longitude-e.longitude),i=Math.sin(r)*Math.cos(n),o=Math.cos(s)*Math.sin(n)-Math.sin(s)*Math.cos(n)*Math.cos(r);return(Math.atan2(i,o)*180/Math.PI+360)%360}const N=85.05112878;function I(e){const s=Math.max(-N,Math.min(N,T(e.latitude)))*Math.PI/180,n=(e.longitude+180)/360,r=(1-Math.log(Math.tan(s)+1/Math.cos(s))/Math.PI)/2;return{x:n,y:r}}function oe(e){const t=e.x*360-180,s=Math.PI*(1-2*e.y);return{latitude:Math.atan(Math.sinh(s))*180/Math.PI,longitude:t}}function le(e,t,s,n={}){const{padding:r=16}=n,i=I({latitude:e.maxLatitude,longitude:e.minLongitude}),o=I({latitude:e.minLatitude,longitude:e.maxLongitude}),_=o.x-i.x||Number.EPSILON,M=o.y-i.y||Number.EPSILON,f=Math.max(1,t-r*2),h=Math.max(1,s-r*2),d=Math.min(f/_,h/M),g=r+(f-_*d)/2,L=r+(h-M*d)/2;return{project:p=>{const j=I(p);return{x:g+(j.x-i.x)*d,y:L+(j.y-i.y)*d}},scale:d,width:t,height:s}}exports.EARTH_RADIUS_KM=z;exports.Input=B;exports.MERCATOR_MAX_LATITUDE=N;exports.Select=te;exports.bearingDeg=ce;exports.clampLatitude=T;exports.fitProjection=le;exports.haversineKm=S;exports.isCoordinate=ae;exports.isValidLatitude=R;exports.isValidLongitude=y;exports.normalizeLongitude=re;exports.pathLengthKm=ie;exports.projectMercator=I;exports.toRadians=m;exports.unprojectMercator=oe;exports.useDebounce=ne;
|
|
2
|
+
//# sourceMappingURL=projection-CILVBdpd.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"projection-CILVBdpd.cjs","sources":["../src/components/Input/Input.tsx","../src/components/Select/Select.tsx","../src/hooks/use-debounce.ts","../src/geo/types.ts","../src/geo/distance.ts","../src/geo/projection.ts"],"sourcesContent":["import { forwardRef, useId } from \"react\";\nimport type { InputHTMLAttributes, ReactNode } from \"react\";\nimport { cn } from \"@/utils/cn\";\nimport styles from \"./Input.module.css\";\n\nexport type InputSize = \"sm\" | \"md\" | \"lg\";\n\nexport interface InputProps extends Omit<InputHTMLAttributes<HTMLInputElement>, \"size\"> {\n label?: string;\n helperText?: string;\n error?: string;\n leftIcon?: ReactNode;\n rightIcon?: ReactNode;\n wrapperClassName?: string;\n /** Visual size — drives height, padding and font via density-aware tokens. */\n size?: InputSize;\n}\n\n/**\n * Labelled text input with helper/error slots and optional adornment icons.\n * Forwards refs to the underlying `<input>` for integration with form libraries.\n */\nexport const Input = forwardRef<HTMLInputElement, InputProps>(function Input(\n {\n label,\n helperText,\n error,\n leftIcon,\n rightIcon,\n wrapperClassName,\n className,\n id,\n required,\n size = \"md\",\n ...props\n },\n ref,\n) {\n const generatedId = useId();\n const inputId = id ?? generatedId;\n const describedById = error ? `${inputId}-error` : helperText ? `${inputId}-helper` : undefined;\n const sizeClass = size === \"sm\" ? styles.sizeSm : size === \"lg\" ? styles.sizeLg : styles.sizeMd;\n\n return (\n <div className={cn(styles.wrapper, error && styles.error, wrapperClassName)}>\n {label && (\n <label htmlFor={inputId} className={styles.label}>\n {label}\n {required && <span className={styles.required}>*</span>}\n </label>\n )}\n <div className={styles.field}>\n {leftIcon && <span className={styles.iconLeft}>{leftIcon}</span>}\n <input\n ref={ref}\n id={inputId}\n aria-invalid={!!error}\n aria-describedby={describedById}\n required={required}\n className={cn(\n styles.input,\n sizeClass,\n leftIcon && styles.hasLeftIcon,\n rightIcon && styles.hasRightIcon,\n className,\n )}\n {...props}\n />\n {rightIcon && <span className={styles.iconRight}>{rightIcon}</span>}\n </div>\n {error ? (\n <span id={`${inputId}-error`} className={styles.errorText}>\n {error}\n </span>\n ) : helperText ? (\n <span id={`${inputId}-helper`} className={styles.helper}>\n {helperText}\n </span>\n ) : null}\n </div>\n );\n});\n","import { forwardRef, useId } from \"react\";\nimport type { SelectHTMLAttributes } from \"react\";\nimport { cn } from \"@/utils/cn\";\nimport styles from \"./Select.module.css\";\n\nexport interface SelectOption {\n value: string | number;\n label: string;\n disabled?: boolean;\n}\n\nexport interface SelectProps extends SelectHTMLAttributes<HTMLSelectElement> {\n label?: string;\n helperText?: string;\n error?: string;\n options?: SelectOption[];\n placeholder?: string;\n wrapperClassName?: string;\n}\n\n/**\n * Native `<select>` wrapper with label/helper/error slots. Either provide\n * `options` for a quick render, or pass `<option>` children directly.\n */\nexport const Select = forwardRef<HTMLSelectElement, SelectProps>(function Select(\n {\n label,\n helperText,\n error,\n options,\n placeholder,\n wrapperClassName,\n className,\n children,\n id,\n required,\n ...props\n },\n ref,\n) {\n const generatedId = useId();\n const selectId = id ?? generatedId;\n\n return (\n <div className={cn(styles.wrapper, error && styles.error, wrapperClassName)}>\n {label && (\n <label htmlFor={selectId} className={styles.label}>\n {label}\n {required && <span className={styles.required}>*</span>}\n </label>\n )}\n <div className={styles.field}>\n <select\n ref={ref}\n id={selectId}\n aria-invalid={!!error}\n required={required}\n className={cn(styles.select, className)}\n {...props}\n >\n {placeholder && (\n <option value=\"\" disabled hidden>\n {placeholder}\n </option>\n )}\n {options?.map((opt) => (\n <option key={opt.value} value={opt.value} disabled={opt.disabled}>\n {opt.label}\n </option>\n ))}\n {children}\n </select>\n <span className={styles.caret} aria-hidden>\n <CaretIcon />\n </span>\n </div>\n {error ? (\n <span className={styles.errorText}>{error}</span>\n ) : helperText ? (\n <span className={styles.helper}>{helperText}</span>\n ) : null}\n </div>\n );\n});\n\nfunction CaretIcon() {\n return (\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\">\n <path\n d=\"M6 9l6 6 6-6\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n </svg>\n );\n}\n","import { useEffect, useState } from \"react\";\n\n/**\n * Debounce a fast-changing value. Returns the latest value once `delay` ms\n * have elapsed without further changes.\n *\n * @param value - The value to debounce.\n * @param delay - Delay in milliseconds (default 300).\n * @returns The debounced value.\n */\nexport function useDebounce<T>(value: T, delay = 300): T {\n const [debouncedValue, setDebouncedValue] = useState<T>(value);\n\n useEffect(() => {\n const timer = setTimeout(() => setDebouncedValue(value), delay);\n return () => clearTimeout(timer);\n }, [value, delay]);\n\n return debouncedValue;\n}\n","/**\n * WGS84 geographic coordinate. Mirrors the `Coordinate` schema from\n * `tempest-fastapi-sdk` (`geo/schemas.py`) — `latitude` in `[-90, 90]`,\n * `longitude` in `[-180, 180]`, serialized snake_case on the wire.\n */\nexport interface Coordinate {\n /** WGS84 latitude in degrees, `[-90, 90]`. E.g. `-23.5505`. */\n latitude: number;\n /** WGS84 longitude in degrees, `[-180, 180]`. E.g. `-46.6333`. */\n longitude: number;\n}\n\n/**\n * A pin plotted on a map: a {@link Coordinate} plus optional presentation and\n * an identity used for click callbacks. Shared by `TrajectoryMap` and the\n * Brazil maps' `markers` prop.\n */\nexport interface GeoMarker extends Coordinate {\n /** Stable identity (returned by click handlers). Falls back to the index. */\n id?: string;\n /** Tooltip / accessible label for the pin. */\n label?: string;\n /** Fill color. Defaults to the primary token. */\n color?: string;\n /** Radius in pixels. Default: 6. */\n radius?: number;\n}\n\n/**\n * A single sample in a recorded trajectory: a {@link Coordinate} stamped with\n * the epoch millisecond it was captured, plus the optional accuracy radius\n * reported by the Geolocation API.\n */\nexport interface TrackPoint extends Coordinate {\n /** Capture time in epoch milliseconds (`GeolocationPosition.timestamp`). */\n timestamp: number;\n /** Horizontal accuracy radius in meters, if the device reported one. */\n accuracy?: number;\n}\n\n/**\n * Travel mode. Mirrors the `TravelMode` string enum from `tempest-fastapi-sdk`\n * (`geo/enums.py`) — the on-the-wire value is the raw string.\n */\nexport type TravelMode = \"car\" | \"motorcycle\" | \"bus\";\n\n/**\n * Estimated travel between two coordinates. Mirrors the `TravelEstimate`\n * schema from `tempest-fastapi-sdk` (`geo/schemas.py`), snake_case preserved so\n * a response deserializes straight into this type.\n */\nexport interface TravelEstimate {\n /** Travel mode the estimate was computed for. */\n mode: TravelMode;\n /** Great-circle distance scaled by circuity, in kilometers (`>= 0`). */\n distance_km: number;\n /** Estimated duration in minutes (`>= 0`). */\n duration_minutes: number;\n /** How the estimate was produced. `\"heuristic\"` (offline) or `\"osrm\"`. */\n source: \"heuristic\" | \"osrm\";\n}\n\n/**\n * Axis-aligned geographic bounding box. `min`/`max` follow the same degree\n * ranges as {@link Coordinate}.\n */\nexport interface GeoBounds {\n minLatitude: number;\n maxLatitude: number;\n minLongitude: number;\n maxLongitude: number;\n}\n\n/** True when `value` is a finite latitude in `[-90, 90]`. */\nexport function isValidLatitude(value: number): boolean {\n return Number.isFinite(value) && value >= -90 && value <= 90;\n}\n\n/** True when `value` is a finite longitude in `[-180, 180]`. */\nexport function isValidLongitude(value: number): boolean {\n return Number.isFinite(value) && value >= -180 && value <= 180;\n}\n\n/**\n * Type guard for {@link Coordinate}: an object with finite, in-range\n * `latitude` and `longitude`.\n */\nexport function isCoordinate(value: unknown): value is Coordinate {\n if (typeof value !== \"object\" || value === null) return false;\n const candidate = value as Record<string, unknown>;\n return (\n typeof candidate.latitude === \"number\" &&\n typeof candidate.longitude === \"number\" &&\n isValidLatitude(candidate.latitude) &&\n isValidLongitude(candidate.longitude)\n );\n}\n\n/** Clamp a latitude into the valid `[-90, 90]` range. */\nexport function clampLatitude(latitude: number): number {\n return Math.min(90, Math.max(-90, latitude));\n}\n\n/**\n * Normalize a longitude into the `[-180, 180]` range, wrapping values that\n * cross the antimeridian (e.g. `190` → `-170`).\n */\nexport function normalizeLongitude(longitude: number): number {\n const wrapped = ((((longitude + 180) % 360) + 360) % 360) - 180;\n return wrapped;\n}\n","import type { Coordinate } from \"./types\";\n\n/**\n * Mean Earth radius in kilometers. Same value used by `tempest-fastapi-sdk`\n * (`geo/distance.py`) so client and server distances agree.\n */\nexport const EARTH_RADIUS_KM = 6371.0088;\n\n/** Convert degrees to radians. */\nexport function toRadians(degrees: number): number {\n return (degrees * Math.PI) / 180;\n}\n\n/**\n * Great-circle distance between two coordinates using the haversine formula\n * (spherical Earth). Mirrors `haversine_km` from `tempest-fastapi-sdk`.\n *\n * @param origin - Start coordinate.\n * @param destination - End coordinate.\n * @returns Distance in kilometers (`>= 0`).\n *\n * @example\n * haversineKm(\n * { latitude: -23.5505, longitude: -46.6333 }, // São Paulo\n * { latitude: -22.9068, longitude: -43.1729 }, // Rio de Janeiro\n * ); // ≈ 360.9\n */\nexport function haversineKm(origin: Coordinate, destination: Coordinate): number {\n const lat1 = toRadians(origin.latitude);\n const lat2 = toRadians(destination.latitude);\n const deltaLat = toRadians(destination.latitude - origin.latitude);\n const deltaLon = toRadians(destination.longitude - origin.longitude);\n\n const a =\n Math.sin(deltaLat / 2) ** 2 + Math.cos(lat1) * Math.cos(lat2) * Math.sin(deltaLon / 2) ** 2;\n\n return 2 * EARTH_RADIUS_KM * Math.asin(Math.sqrt(a));\n}\n\n/**\n * Total length of a trajectory: the sum of haversine distances between each\n * consecutive pair of points. Returns `0` for an empty or single-point path.\n *\n * @param points - Ordered coordinates along the path.\n * @returns Cumulative distance in kilometers.\n */\nexport function pathLengthKm(points: readonly Coordinate[]): number {\n let total = 0;\n for (let i = 1; i < points.length; i += 1) {\n total += haversineKm(points[i - 1], points[i]);\n }\n return total;\n}\n\n/**\n * Initial bearing (forward azimuth) from `origin` to `destination`, in degrees\n * clockwise from true north, normalized to `[0, 360)`. Useful for orienting a\n * heading arrow on a trajectory.\n *\n * @param origin - Start coordinate.\n * @param destination - End coordinate.\n * @returns Bearing in degrees, `[0, 360)`.\n */\nexport function bearingDeg(origin: Coordinate, destination: Coordinate): number {\n const lat1 = toRadians(origin.latitude);\n const lat2 = toRadians(destination.latitude);\n const deltaLon = toRadians(destination.longitude - origin.longitude);\n\n const y = Math.sin(deltaLon) * Math.cos(lat2);\n const x =\n Math.cos(lat1) * Math.sin(lat2) - Math.sin(lat1) * Math.cos(lat2) * Math.cos(deltaLon);\n\n const bearing = (Math.atan2(y, x) * 180) / Math.PI;\n return (bearing + 360) % 360;\n}\n","import { clampLatitude } from \"./types\";\nimport type { Coordinate, GeoBounds } from \"./types\";\n\n/**\n * A point projected onto the unit Web Mercator plane. Both axes are in `[0, 1]`\n * — `x` grows east, `y` grows south (screen convention).\n */\nexport interface MercatorPoint {\n x: number;\n y: number;\n}\n\n/** A pixel coordinate inside the plotting viewport. */\nexport interface PixelPoint {\n x: number;\n y: number;\n}\n\n/**\n * Web Mercator (EPSG:3857) latitude clamp. Latitudes beyond this diverge to\n * infinity in the projection, so tile maps cap here.\n */\nexport const MERCATOR_MAX_LATITUDE = 85.05112878;\n\n/**\n * Project a geographic coordinate onto the unit Web Mercator plane. This is the\n * same projection tile servers use, so a self-hosted tile layer and the\n * tile-free SVG plot line up pixel-for-pixel.\n *\n * @param coord - Coordinate to project.\n * @returns `{ x, y }` in `[0, 1]`.\n */\nexport function projectMercator(coord: Coordinate): MercatorPoint {\n const lat = Math.max(\n -MERCATOR_MAX_LATITUDE,\n Math.min(MERCATOR_MAX_LATITUDE, clampLatitude(coord.latitude)),\n );\n const latRad = (lat * Math.PI) / 180;\n const x = (coord.longitude + 180) / 360;\n const y = (1 - Math.log(Math.tan(latRad) + 1 / Math.cos(latRad)) / Math.PI) / 2;\n return { x, y };\n}\n\n/**\n * Inverse of {@link projectMercator}: recover a coordinate from a unit-plane\n * point.\n *\n * @param point - `{ x, y }` in `[0, 1]`.\n * @returns The geographic coordinate.\n */\nexport function unprojectMercator(point: MercatorPoint): Coordinate {\n const longitude = point.x * 360 - 180;\n const n = Math.PI * (1 - 2 * point.y);\n const latitude = (Math.atan(Math.sinh(n)) * 180) / Math.PI;\n return { latitude, longitude };\n}\n\n/** A ready-to-use mapping from coordinates to viewport pixels. */\nexport interface FittedProjection {\n /** Project a coordinate to a pixel inside the viewport. */\n project: (coord: Coordinate) => PixelPoint;\n /** Uniform scale (unit-plane → pixels) actually used, after aspect fit. */\n scale: number;\n /** Viewport width in pixels. */\n width: number;\n /** Viewport height in pixels. */\n height: number;\n}\n\n/** Options for {@link fitProjection}. */\nexport interface FitProjectionOptions {\n /** Inner padding in pixels kept clear on every edge. Default: `16`. */\n padding?: number;\n}\n\n/**\n * Build a projection that fits `bounds` into a `width × height` viewport while\n * preserving aspect ratio (uniform scale, centered). This is what powers the\n * tile-free trajectory plot: project the bounds, scale to the SVG box, keep\n * shapes undistorted.\n *\n * @param bounds - Geographic extent to fit.\n * @param width - Viewport width in pixels.\n * @param height - Viewport height in pixels.\n * @param options - Padding tuning.\n * @returns A {@link FittedProjection} with a `project(coord)` mapper.\n */\nexport function fitProjection(\n bounds: GeoBounds,\n width: number,\n height: number,\n options: FitProjectionOptions = {},\n): FittedProjection {\n const { padding = 16 } = options;\n\n const topLeft = projectMercator({\n latitude: bounds.maxLatitude,\n longitude: bounds.minLongitude,\n });\n const bottomRight = projectMercator({\n latitude: bounds.minLatitude,\n longitude: bounds.maxLongitude,\n });\n\n const spanX = bottomRight.x - topLeft.x || Number.EPSILON;\n const spanY = bottomRight.y - topLeft.y || Number.EPSILON;\n\n const innerWidth = Math.max(1, width - padding * 2);\n const innerHeight = Math.max(1, height - padding * 2);\n\n // Uniform scale keeps the trajectory undistorted; fit the tighter axis.\n const scale = Math.min(innerWidth / spanX, innerHeight / spanY);\n\n // Center the projected content within the padded box.\n const offsetX = padding + (innerWidth - spanX * scale) / 2;\n const offsetY = padding + (innerHeight - spanY * scale) / 2;\n\n const project = (coord: Coordinate): PixelPoint => {\n const projected = projectMercator(coord);\n return {\n x: offsetX + (projected.x - topLeft.x) * scale,\n y: offsetY + (projected.y - topLeft.y) * scale,\n };\n };\n\n return { project, scale, width, height };\n}\n"],"names":["Input","forwardRef","label","helperText","error","leftIcon","rightIcon","wrapperClassName","className","id","required","size","props","ref","generatedId","useId","inputId","describedById","sizeClass","styles","jsxs","cn","jsx","Select","options","placeholder","children","selectId","opt","CaretIcon","useDebounce","value","delay","debouncedValue","setDebouncedValue","useState","useEffect","timer","isValidLatitude","isValidLongitude","isCoordinate","candidate","clampLatitude","latitude","normalizeLongitude","longitude","EARTH_RADIUS_KM","toRadians","degrees","haversineKm","origin","destination","lat1","lat2","deltaLat","deltaLon","a","pathLengthKm","points","total","i","bearingDeg","y","x","MERCATOR_MAX_LATITUDE","projectMercator","coord","latRad","unprojectMercator","point","n","fitProjection","bounds","width","height","padding","topLeft","bottomRight","spanX","spanY","innerWidth","innerHeight","scale","offsetX","offsetY","projected"],"mappings":"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"}
|