Files
VoCat/web/src/lib/carrier.ts
T
MengMengCode f4aaa3cfdd Implement automatic task management with CRUD operations and UI integration
- Added `automatic_tasks.go` and `automatic_tasks_test.go` for backend logic and testing of automatic tasks.
- Created `automatic_tasks_test.go` to validate task claiming and deletion behavior.
- Developed `AutomaticTasksPage.tsx` for frontend management of automatic tasks, including task creation, editing, and execution.
- Integrated device and eSIM profile selection for task configuration.
- Implemented automatic task scheduling and retry logic in the backend.
2026-08-10 22:15:54 +08:00

70 lines
2.5 KiB
TypeScript

// MCC/MNC → carrier lookup. The offline table combines Android's maintained
// carrier ID database with the legacy global table as a fallback. Refresh it
// with scripts/update-carriers.py; runtime registration never depends on an
// external lookup service.
import table from "./mccmnc.json";
interface MccMncTable {
c: Record<string, string[]>;
i: Record<string, string>;
t: string[];
}
const data = table as unknown as MccMncTable;
const THREE_DIGIT = new Set(data.t);
export interface CarrierInfo {
mcc: string;
mnc: string;
name: string;
iso: string;
}
function imsiDigits(imsi?: string): string {
return String(imsi ?? "").replace(/\D/g, "");
}
// lookupCarrier resolves a SIM's home ("original") carrier from its IMSI. MNC length
// varies by MCC (2 vs 3 digits); North-American/Mexican MCCs are 3-digit-first, the
// rest 2-digit-first, with a fallback to the other length so real carriers resolve.
export function lookupCarrier(imsi?: string): CarrierInfo | null {
const digits = imsiDigits(imsi);
if (digits.length < 5) return null;
const mcc = digits.slice(0, 3);
const order = THREE_DIGIT.has(mcc) ? [3, 2] : [2, 3];
for (const len of order) {
const mnc = digits.slice(3, 3 + len);
const hit = data.c[mcc + mnc];
if (hit) return { mcc, mnc, name: hit[0], iso: hit[1] };
}
return null;
}
// carrierIso returns the alpha-2 country code for the SIM's home carrier, falling
// back to the MCC's country when the exact MNC is not catalogued.
export function carrierIso(imsi?: string): string {
const hit = lookupCarrier(imsi);
if (hit) return hit.iso;
return data.i[imsiDigits(imsi).slice(0, 3)] ?? "";
}
// carrierBrandIso keeps the normal IMSI country flag for branded/MVNO SIMs.
// Lebara UK's Vodafone-NL-hosted 204-04 eSIM is the one known exception: its
// customer-facing country is GB even though AKA must continue using 204-04.
export function carrierBrandIso(spn?: string, imsi?: string): string {
const brand = String(spn ?? "").trim().toLowerCase();
const digits = imsiDigits(imsi);
if (brand.includes("lebara") && digits.startsWith("20404")) return "gb";
return carrierIso(imsi);
}
// flagEmoji converts an alpha-2 country code to its regional-indicator flag emoji.
export function flagEmoji(iso?: string): string {
const s = String(iso ?? "").trim().toUpperCase();
if (s.length !== 2) return "";
const a = s.charCodeAt(0);
const b = s.charCodeAt(1);
if (a < 65 || a > 90 || b < 65 || b > 90) return "";
return String.fromCodePoint(0x1f1e6 + (a - 65)) + String.fromCodePoint(0x1f1e6 + (b - 65));
}