WEIGHTS = (7, 3, 1)
def to_val(ch):
    ch = ch.upper()
    if ch == "<": return 0
    if ch.isdigit(): return int(ch)
    return ord(ch) - ord("A") + 10
def check_digit(data): return sum(to_val(c) * WEIGHTS[i % 3] for i, c in enumerate(data)) % 10
def _padded(raw, n): return raw.upper().ljust(n, "<")[:n]
def build_line1(surname, given="", type_code="PV", country="MMR"):
    s = surname.upper().replace(" ", "<")
    g = given.upper().replace(" ", "<") if given else ""
    t = type_code[1] if len(type_code) > 1 and type_code[1] != "<" else "<"
    c = country.upper()[:3]
    id_part = s + "<<" + g if g else s
    return ("P" + t + c + id_part).ljust(44, "<")[:44]
def build_line2(passport_no, birth_date, expiry_date, sex="M", issuing_state="MMR", personal_no=""):
    p = _padded(passport_no, 9)
    b = _padded(birth_date, 6)
    e = _padded(expiry_date, 6)
    n = _padded(personal_no, 14)
    ps = f"{p}{check_digit(p)}"
    bs = f"{b}{check_digit(b)}"
    es = f"{e}{check_digit(e)}"
    ns = n + str(check_digit(n)) if personal_no.strip("<") else n + "<"
    l43 = ps + issuing_state + bs + sex + es + ns
    return l43 + str(check_digit(ps + bs + es + ns))
