mirror of
https://github.com/fsolla/teqo.git
synced 2026-11-14 08:53:11 +00:00
Ship A2 with a static Bahia municipality↔zone map, pure suggestion engine, and form chips that never auto-apply geography.
484 lines
12 KiB
TypeScript
484 lines
12 KiB
TypeScript
/**
|
|
* Official Bahia municipality ↔ TSE electoral zone mapping.
|
|
*
|
|
* Source (TSE open data — Results 2024, detalhe da apuração por município e zona, UF BA):
|
|
* https://dadosabertos.tse.jus.br/dataset/resultados-2024
|
|
* https://cdn.tse.jus.br/estatistica/sead/odsele/detalhe_votacao_munzona/detalhe_votacao_munzona_2024.zip
|
|
* Entry: detalhe_votacao_munzona_2024_BA.csv
|
|
* Download SHA-256: 24e75fcf98a57b2362c33d46eb96b99a4b7070966cfc7f6398e12240e3f679f0
|
|
*
|
|
* Chosen over 2022 result files because TSE rezoning can change municipality↔zone
|
|
* assignments between cycles. 2024 municipal elections are the most recent
|
|
* election-validated BA coverage of all 417 municipalities (extracted 2026-07-18).
|
|
*
|
|
* Municipality spellings follow the canonical application names in bahiaTerritories.
|
|
* TSE variants (Camacan, Dias d'Ávila, Muquém de São Francisco, Santa Teresinha)
|
|
* were reconciled via canonicalizeMunicipalityName. Coverage is independently
|
|
* checked by the official test evidence fixture.
|
|
*/
|
|
|
|
import {
|
|
bahiaIdentityTerritories,
|
|
bahiaMunicipalities,
|
|
citiesForTerritory,
|
|
isBahiaMunicipality,
|
|
type BahiaIdentityTerritory,
|
|
} from '@/lib/bahiaTerritories'
|
|
|
|
export const bahiaMunicipalityTseZones: Readonly<Record<string, readonly number[]>> = {
|
|
'Abaíra': [105],
|
|
'Abaré': [158],
|
|
'Acajutiba': [21],
|
|
'Adustina': [52],
|
|
'Água Fria': [74],
|
|
'Aiquara': [147],
|
|
'Alagoinhas': [163],
|
|
'Alcobaça': [112],
|
|
'Almadina': [135],
|
|
'Amargosa': [36],
|
|
'Amélia Rodrigues': [192],
|
|
'América Dourada': [199],
|
|
'Anagé': [161],
|
|
'Andaraí': [119],
|
|
'Andorinha': [45],
|
|
'Angical': [126],
|
|
'Anguera': [157],
|
|
'Antas': [82],
|
|
'Antônio Cardoso': [143],
|
|
'Antônio Gonçalves': [53],
|
|
'Aporá': [44],
|
|
'Apuarema': [23],
|
|
'Araças': [200],
|
|
'Aracatu': [90],
|
|
'Araci': [123],
|
|
'Aramari': [163],
|
|
'Arataca': [166],
|
|
'Aratuípe': [30],
|
|
'Aurelino Leal': [73],
|
|
'Baianópolis': [126],
|
|
'Baixa Grande': [86],
|
|
'Banzaê': [110],
|
|
'Barra': [77],
|
|
'Barra da Estiva': [169],
|
|
'Barra do Choça': [139],
|
|
'Barra do Mendes': [176],
|
|
'Barra do Rocha': [134],
|
|
'Barreiras': [70, 75],
|
|
'Barro Alto': [174],
|
|
'Barro Preto': [136],
|
|
'Barrocas': [150],
|
|
'Belmonte': [34],
|
|
'Belo Campo': [177],
|
|
'Biritinga': [150],
|
|
'Boa Nova': [59],
|
|
'Boa Vista do Tupim': [42],
|
|
'Bom Jesus da Lapa': [71],
|
|
'Bom Jesus da Serra': [59],
|
|
'Boninal': [105],
|
|
'Bonito': [69],
|
|
'Boquira': [65],
|
|
'Botuporã': [168],
|
|
'Brejões': [36],
|
|
'Brejolândia': [190],
|
|
'Brotas de Macaúbas': [94],
|
|
'Brumado': [90],
|
|
'Buerarema': [166],
|
|
'Buritirama': [77],
|
|
'Caatiba': [201],
|
|
'Cabaceiras do Paraguaçu': [131],
|
|
'Cachoeira': [118],
|
|
'Caculé': [93],
|
|
'Caém': [167],
|
|
'Caetanos': [58],
|
|
'Caetité': [63],
|
|
'Cafarnaum': [55],
|
|
'Cairu': [31],
|
|
'Caldeirão Grande': [115],
|
|
'Camacan': [133],
|
|
'Camaçari': [170, 171],
|
|
'Camamu': [78],
|
|
'Campo Alegre de Lourdes': [67],
|
|
'Campo Formoso': [53],
|
|
'Canápolis': [99],
|
|
'Canarana': [174],
|
|
'Canavieiras': [116],
|
|
'Candeal': [114],
|
|
'Candeias': [127],
|
|
'Candiba': [64],
|
|
'Cândido Sales': [40],
|
|
'Cansanção': [50],
|
|
'Canudos': [83],
|
|
'Capela do Alto Alegre': [196],
|
|
'Capim Grosso': [191],
|
|
'Caraíbas': [161],
|
|
'Caravelas': [112],
|
|
'Cardeal da Silva': [144],
|
|
'Carinhanha': [125],
|
|
'Casa Nova': [66],
|
|
'Castro Alves': [43],
|
|
'Catolândia': [100],
|
|
'Catu': [129],
|
|
'Caturama': [111],
|
|
'Central': [159],
|
|
'Chorrochó': [158],
|
|
'Cícero Dantas': [82],
|
|
'Cipó': [79],
|
|
'Coaraci': [135],
|
|
'Cocos': [61],
|
|
'Conceição da Feira': [108],
|
|
'Conceição do Almeida': [184],
|
|
'Conceição do Coité': [132],
|
|
'Conceição do Jacuípe': [192],
|
|
'Conde': [21],
|
|
'Condeúba': [60],
|
|
'Contendas do Sincorá': [58],
|
|
'Coração de Maria': [130],
|
|
'Cordeiros': [60],
|
|
'Coribe': [61],
|
|
'Coronel João Sá': [52],
|
|
'Correntina': [124],
|
|
'Cotegipe': [98],
|
|
'Cravolândia': [38],
|
|
'Crisópolis': [81],
|
|
'Cristópolis': [126],
|
|
'Cruz das Almas': [142],
|
|
'Curaçá': [85],
|
|
'Dário Meira': [147],
|
|
"Dias d'Ávila": [186],
|
|
'Dom Basílio': [101],
|
|
'Dom Macedo Costa': [202],
|
|
'Elísio Medrado': [107],
|
|
'Encruzilhada': [152],
|
|
'Entre Rios': [144],
|
|
'Érico Cardoso': [111],
|
|
'Esplanada': [21],
|
|
'Euclides da Cunha': [102],
|
|
'Eunápolis': [188, 203],
|
|
'Fátima': [82],
|
|
'Feira da Mata': [125],
|
|
'Feira de Santana': [154, 155, 156, 157],
|
|
'Filadélfia': [149],
|
|
'Firmino Alves': [137],
|
|
'Floresta Azul': [29],
|
|
'Formosa do Rio Preto': [187],
|
|
'Gandu': [151],
|
|
'Gavião': [191],
|
|
'Gentio do Ouro': [68],
|
|
'Glória': [84],
|
|
'Gongogi': [73],
|
|
'Governador Mangabeira': [131],
|
|
'Guajeru': [93],
|
|
'Guanambi': [64],
|
|
'Guaratinga': [189],
|
|
'Heliópolis': [110],
|
|
'Iaçu': [193],
|
|
'Ibiassucê': [93],
|
|
'Ibicaraí': [29],
|
|
'Ibicoara': [169],
|
|
'Ibicuí': [146],
|
|
'Ibipeba': [176],
|
|
'Ibipitanga': [65],
|
|
'Ibiquera': [42],
|
|
'Ibirapitanga': [134],
|
|
'Ibirapuã': [153],
|
|
'Ibirataia': [24],
|
|
'Ibitiara': [88],
|
|
'Ibititá': [104],
|
|
'Ibotirama': [173],
|
|
'Ichu': [132],
|
|
'Igaporã': [168],
|
|
'Igrapiúna': [32],
|
|
'Iguaí': [146],
|
|
'Ilhéus': [25, 26],
|
|
'Inhambupe': [44],
|
|
'Ipecaetá': [143],
|
|
'Ipiaú': [24],
|
|
'Ipirá': [62],
|
|
'Ipupiara': [94],
|
|
'Irajuba': [76],
|
|
'Iramaia': [169],
|
|
'Iraquara': [89],
|
|
'Irará': [74],
|
|
'Irecê': [95],
|
|
'Itabela': [189],
|
|
'Itaberaba': [42],
|
|
'Itabuna': [27, 28],
|
|
'Itacaré': [198],
|
|
'Itaeté': [119],
|
|
'Itagi': [147],
|
|
'Itagibá': [147],
|
|
'Itagimirim': [188],
|
|
'Itaguaçu da Bahia': [68],
|
|
'Itaju do Colônia': [137],
|
|
'Itajuípe': [136],
|
|
'Itamaraju': [172],
|
|
'Itamari': [151],
|
|
'Itambé': [201],
|
|
'Itanagra': [185],
|
|
'Itanhém': [148],
|
|
'Itaparica': [141],
|
|
'Itapé': [27],
|
|
'Itapebi': [188],
|
|
'Itapetinga': [140],
|
|
'Itapicuru': [81],
|
|
'Itapitanga': [135],
|
|
'Itaquara': [76],
|
|
'Itarantim': [138],
|
|
'Itatim': [107],
|
|
'Itiruçu': [37],
|
|
'Itiúba': [149],
|
|
'Itororó': [137],
|
|
'Ituaçu': [58],
|
|
'Ituberá': [32],
|
|
'Iuiú': [175],
|
|
'Jaborandi': [61],
|
|
'Jacaraci': [92],
|
|
'Jacobina': [46],
|
|
'Jaguaquara': [76],
|
|
'Jaguarari': [179],
|
|
'Jaguaripe': [30],
|
|
'Jandaíra': [49],
|
|
'Jequié': [22, 23],
|
|
'Jeremoabo': [51],
|
|
'Jiquiriçá': [109],
|
|
'Jitaúna': [24],
|
|
'João Dourado': [199],
|
|
'Juazeiro': [47, 48],
|
|
'Jucuruçu': [172],
|
|
'Jussara': [159],
|
|
'Jussari': [28],
|
|
'Jussiape': [101],
|
|
'Lafaiete Coutinho': [23],
|
|
'Lagoa Real': [63],
|
|
'Laje': [109],
|
|
'Lajedão': [153],
|
|
'Lajedinho': [87],
|
|
'Lajedo do Tabocal': [37],
|
|
'Lamarão': [160],
|
|
'Lapão': [104],
|
|
'Lauro de Freitas': [180],
|
|
'Lençóis': [89],
|
|
'Licínio de Almeida': [117],
|
|
'Livramento de Nossa Senhora': [101],
|
|
'Luís Eduardo Magalhães': [205],
|
|
'Macajuba': [87],
|
|
'Macarani': [91],
|
|
'Macaúbas': [65],
|
|
'Macururé': [158],
|
|
'Madre de Deus': [162],
|
|
'Maetinga': [161],
|
|
'Maiquinique': [91],
|
|
'Mairi': [86],
|
|
'Malhada': [125],
|
|
'Malhada de Pedras': [90],
|
|
'Manoel Vitorino': [22],
|
|
'Mansidão': [97],
|
|
'Maracás': [37],
|
|
'Maragogipe': [118],
|
|
'Maraú': [78],
|
|
'Marcionílio Souza': [193],
|
|
'Mascote': [133],
|
|
'Mata de São João': [185],
|
|
'Matina': [113],
|
|
'Medeiros Neto': [153],
|
|
'Miguel Calmon': [103],
|
|
'Milagres': [193],
|
|
'Mirangaba': [167],
|
|
'Mirante': [59],
|
|
'Monte Santo': [50],
|
|
'Morpará': [173],
|
|
'Morro do Chapéu': [55],
|
|
'Mortugaba': [92],
|
|
'Mucugê': [119],
|
|
'Mucuri': [35],
|
|
'Mulungu do Morro': [55],
|
|
'Mundo Novo': [54],
|
|
'Muniz Ferreira': [202],
|
|
'Muquém de São Francisco': [98],
|
|
'Muritiba': [131],
|
|
'Mutuípe': [109],
|
|
'Nazaré': [30],
|
|
'Nilo Peçanha': [32],
|
|
'Nordestina': [106],
|
|
'Nova Canaã': [146],
|
|
'Nova Fátima': [196],
|
|
'Nova Ibiá': [151],
|
|
'Nova Itarana': [36],
|
|
'Nova Redenção': [119],
|
|
'Nova Soure': [79],
|
|
'Nova Viçosa': [35],
|
|
'Novo Horizonte': [88],
|
|
'Novo Triunfo': [82],
|
|
'Olindina': [81],
|
|
'Oliveira dos Brejinhos': [94],
|
|
'Ouriçangas': [74],
|
|
'Ourolândia': [167],
|
|
'Palmas de Monte Alto': [175],
|
|
'Palmeiras': [89],
|
|
'Paramirim': [111],
|
|
'Paratinga': [173],
|
|
'Paripiranga': [52],
|
|
'Pau Brasil': [133],
|
|
'Paulo Afonso': [84, 181],
|
|
'Pé de Serra': [114],
|
|
'Pedrão': [130],
|
|
'Pedro Alexandre': [51],
|
|
'Piatã': [105],
|
|
'Pilão Arcado': [195],
|
|
'Pindaí': [117],
|
|
'Pindobaçu': [115],
|
|
'Pintadas': [62],
|
|
'Piraí do Norte': [151],
|
|
'Piripá': [177],
|
|
'Piritiba': [54],
|
|
'Planaltino': [37],
|
|
'Planalto': [139],
|
|
'Poções': [59],
|
|
'Pojuca': [200],
|
|
'Ponto Novo': [149],
|
|
'Porto Seguro': [121, 122],
|
|
'Potiraguá': [138],
|
|
'Prado': [112],
|
|
'Presidente Dutra': [95],
|
|
'Presidente Jânio Quadros': [60],
|
|
'Presidente Tancredo Neves': [197],
|
|
'Queimadas': [106],
|
|
'Quijingue': [102],
|
|
'Quixabeira': [191],
|
|
'Rafael Jambeiro': [43],
|
|
'Remanso': [67],
|
|
'Retirolândia': [196],
|
|
'Riachão das Neves': [182],
|
|
'Riachão do Jacuípe': [114],
|
|
'Riacho de Santana': [113],
|
|
'Ribeira do Amparo': [79],
|
|
'Ribeira do Pombal': [110],
|
|
'Ribeirão do Largo': [152],
|
|
'Rio de Contas': [101],
|
|
'Rio do Antônio': [93],
|
|
'Rio do Pires': [111],
|
|
'Rio Real': [49],
|
|
'Rodelas': [158],
|
|
'Ruy Barbosa': [87],
|
|
'Salinas da Margarida': [30],
|
|
'Salvador': [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19],
|
|
'Santa Bárbara': [160],
|
|
'Santa Brígida': [181],
|
|
'Santa Cruz Cabrália': [121],
|
|
'Santa Cruz da Vitória': [29],
|
|
'Santa Inês': [38],
|
|
'Santa Luzia': [133],
|
|
'Santa Maria da Vitória': [72],
|
|
'Santa Rita de Cássia': [97],
|
|
'Santa Teresinha': [107],
|
|
'Santaluz': [145],
|
|
'Santana': [99],
|
|
'Santanópolis': [74],
|
|
'Santo Amaro': [178],
|
|
'Santo Antônio de Jesus': [56, 202],
|
|
'Santo Estêvão': [143],
|
|
'São Desidério': [100],
|
|
'São Domingos': [120],
|
|
'São Felipe': [184],
|
|
'São Félix': [118],
|
|
'São Félix do Coribe': [72],
|
|
'São Francisco do Conde': [162],
|
|
'São Gabriel': [95],
|
|
'São Gonçalo dos Campos': [108],
|
|
'São José da Vitória': [166],
|
|
'São José do Jacuípe': [191],
|
|
'São Miguel das Matas': [36],
|
|
'São Sebastião do Passé': [128],
|
|
'Sapeaçu': [142],
|
|
'Sátiro Dias': [44],
|
|
'Saubara': [178],
|
|
'Saúde': [115],
|
|
'Seabra': [88],
|
|
'Sebastião Laranjeiras': [175],
|
|
'Senhor do Bonfim': [45],
|
|
'Sento Sé': [96],
|
|
'Serra do Ramalho': [71],
|
|
'Serra Dourada': [190],
|
|
'Serra Preta': [155],
|
|
'Serrinha': [150],
|
|
'Serrolândia': [46],
|
|
'Simões Filho': [33],
|
|
'Sítio do Mato': [71],
|
|
'Sítio do Quinto': [51],
|
|
'Sobradinho': [66],
|
|
'Souto Soares': [174],
|
|
'Tabocas do Brejo Velho': [190],
|
|
'Tanhaçu': [58],
|
|
'Tanque Novo': [168],
|
|
'Tanquinho': [160],
|
|
'Taperoá': [32],
|
|
'Tapiramutá': [54],
|
|
'Teixeira de Freitas': [183],
|
|
'Teodoro Sampaio': [130],
|
|
'Teofilândia': [123],
|
|
'Teolândia': [197],
|
|
'Terra Nova': [128],
|
|
'Tremedal': [177],
|
|
'Tucano': [80],
|
|
'Uauá': [83],
|
|
'Ubaíra': [38],
|
|
'Ubaitaba': [73],
|
|
'Ubatã': [134],
|
|
'Uibaí': [159],
|
|
'Umburanas': [167],
|
|
'Una': [116],
|
|
'Urandi': [117],
|
|
'Uruçuca': [198],
|
|
'Utinga': [69],
|
|
'Valença': [31],
|
|
'Valente': [120],
|
|
'Várzea da Roça': [86],
|
|
'Várzea do Poço': [103],
|
|
'Várzea Nova': [55],
|
|
'Varzedo': [56],
|
|
'Vera Cruz': [141],
|
|
'Vereda': [148],
|
|
'Vitória da Conquista': [39, 40, 41],
|
|
'Wagner': [69],
|
|
'Wanderley': [98],
|
|
'Wenceslau Guimarães': [197],
|
|
'Xique-Xique': [68],
|
|
} as const
|
|
|
|
const emptyZones: readonly number[] = []
|
|
|
|
export const tseZonesForCity = (city: string): readonly number[] => {
|
|
if (!isBahiaMunicipality(city)) return emptyZones
|
|
return bahiaMunicipalityTseZones[city] ?? emptyZones
|
|
}
|
|
|
|
const citiesByZone = new Map<number, string[]>()
|
|
for (const city of bahiaMunicipalities) {
|
|
for (const zone of bahiaMunicipalityTseZones[city] ?? []) {
|
|
const list = citiesByZone.get(zone)
|
|
if (list) list.push(city)
|
|
else citiesByZone.set(zone, [city])
|
|
}
|
|
}
|
|
for (const list of citiesByZone.values()) {
|
|
list.sort((left, right) => left.localeCompare(right, 'pt-BR'))
|
|
}
|
|
|
|
const zonesByTerritory = new Map<string, readonly number[]>()
|
|
for (const territory of bahiaIdentityTerritories) {
|
|
const zones = new Set<number>()
|
|
for (const city of citiesForTerritory(territory)) {
|
|
for (const zone of tseZonesForCity(city)) zones.add(zone)
|
|
}
|
|
zonesByTerritory.set(
|
|
territory,
|
|
[...zones].sort((left, right) => left - right),
|
|
)
|
|
}
|
|
|
|
export const tseZonesForTerritory = (
|
|
territory: BahiaIdentityTerritory,
|
|
): readonly number[] => zonesByTerritory.get(territory) ?? emptyZones
|
|
|
|
export const citiesForTseZone = (zoneNumber: number): readonly string[] =>
|
|
citiesByZone.get(zoneNumber) ?? []
|