/**
* Province and territory metadata for the Canada Visualizer
*/
export interface Province {
code: string;
name: { en: string; fr: string };
totalSeats: number;
capital: string;
isMaritime: boolean;
isTerritory: boolean;
}
export const provinces: Record<string, Province> = {
BC: {
code: 'BC',
name: { en: 'British Columbia', fr: 'Colombie-Britannique' },
totalSeats: 43,
capital: 'Victoria',
isMaritime: false,
isTerritory: false,
},
AB: {
code: 'AB',
name: { en: 'Alberta', fr: 'Alberta' },
totalSeats: 37,
capital: 'Edmonton',
isMaritime: false,
isTerritory: false,
},
SK: {
code: 'SK',
name: { en: 'Saskatchewan', fr: 'Saskatchewan' },
totalSeats: 14,
capital: 'Regina',
isMaritime: false,
isTerritory: false,
},
MB: {
code: 'MB',
name: { en: 'Manitoba', fr: 'Manitoba' },
totalSeats: 14,
capital: 'Winnipeg',
isMaritime: false,
isTerritory: false,
},
ON: {
code: 'ON',
name: { en: 'Ontario', fr: 'Ontario' },
totalSeats: 122,
capital: 'Toronto',
isMaritime: false,
isTerritory: false,
},
QC: {
code: 'QC',
name: { en: 'Quebec', fr: 'Québec' },
totalSeats: 78,
capital: 'Quebec City',
isMaritime: false,
isTerritory: false,
},
NB: {
code: 'NB',
name: { en: 'New Brunswick', fr: 'Nouveau-Brunswick' },
totalSeats: 10,
capital: 'Fredericton',
isMaritime: true,
isTerritory: false,
},
NS: {
code: 'NS',
name: { en: 'Nova Scotia', fr: 'Nouvelle-Écosse' },
totalSeats: 11,
capital: 'Halifax',
isMaritime: true,
isTerritory: false,
},
PE: {
code: 'PE',
name: { en: 'Prince Edward Island', fr: 'Île-du-Prince-Édouard' },
totalSeats: 4,
capital: 'Charlottetown',
isMaritime: true,
isTerritory: false,
},
NL: {
code: 'NL',
name: { en: 'Newfoundland and Labrador', fr: 'Terre-Neuve-et-Labrador' },
totalSeats: 7,
capital: "St. John's",
isMaritime: true,
isTerritory: false,
},
YT: {
code: 'YT',
name: { en: 'Yukon', fr: 'Yukon' },
totalSeats: 1,
capital: 'Whitehorse',
isMaritime: false,
isTerritory: true,
},
NT: {
code: 'NT',
name: { en: 'Northwest Territories', fr: 'Territoires du Nord-Ouest' },
totalSeats: 1,
capital: 'Yellowknife',
isMaritime: false,
isTerritory: true,
},
NU: {
code: 'NU',
name: { en: 'Nunavut', fr: 'Nunavut' },
totalSeats: 1,
capital: 'Iqaluit',
isMaritime: false,
isTerritory: true,
},
};
export const provinceCodes = Object.keys(provinces);
export const maritimeProvinces = Object.values(provinces)
.filter(p => p.isMaritime)
.map(p => p.code);
export const territories = Object.values(provinces)
.filter(p => p.isTerritory)
.map(p => p.code);
export function getProvinceName(code: string, locale: 'en' | 'fr'): string {
return provinces[code]?.name[locale] ?? code;
}
export function getExpectedTotalSeats(): number {
return Object.values(provinces).reduce((sum, p) => sum + p.totalSeats, 0);
}
/**
* Label positions for each province/territory
* Coordinates are percentages of the map container (0-100)
* Adjusted to appear at visual centroids of each region
*/
export const provinceLabelPositions: Record<string, { x: number; y: number }> = {
BC: { x: 12, y: 60 },
AB: { x: 23, y: 65 },
SK: { x: 32, y: 68 },
MB: { x: 41, y: 70 },
ON: { x: 57, y: 80 },
QC: { x: 70, y: 75 },
NB: { x: 82, y: 80 },
NS: { x: 86, y: 82 },
PE: { x: 86, y: 78 },
NL: { x: 81, y: 60 },
YT: { x: 11, y: 37 },
NT: { x: 23, y: 42 },
NU: { x: 42, y: 45 },
};
/**
* Short label codes for smaller regions
*/
export const shortLabels: Record<string, string> = {
BC: 'BC',
AB: 'AB',
SK: 'SK',
MB: 'MB',
ON: 'ON',
QC: 'QC',
NB: 'NB',
NS: 'NS',
PE: 'PE',
NL: 'NL',
YT: 'YT',
NT: 'NT',
NU: 'NU',
};