```python
def scan_source(line: str) -> list[list[str]]:
    tokens = []
    i = 0
    while i < len(line):
        if line[i].isspace():
            i += 1
        elif line[i].isdigit():
            start = i
            while i + 1 < len(line) and line[i + 1].isdigit():
                i += 1
            tokens.append(['num', line[start:i + 1]])
        elif line[i].isalpha() or line[i] == '_':
            start = i
            while i + 1 < len(line) and (line[i + 1].isalnum() or line[i + 1] == '_'):
                i += 1
            token = line[start:i + 1]
            if token in ['==', '!=', '<=', '>=', '&&', '||']:
                tokens.append(['op', token])
            else:
                tokens.append(['id', token])
        elif line[i] == '=' or line[i] == '<' or line[i] == '>' or line[i] == '+' or line[i] == '-' or line[i] == '*' or line[i] == '/' or line[i] == '(' or line[i] == ')':
            tokens.append(['op', line[i]])
        else:
            raise ValueError(f"Invalid character: {line[i]}")
        i += 1
    return tokens
```