        last = ("Smith", "Johnson", "Williams", "Brown", "Jones", "Garcia", "Miller",
                "Davis", "Rodriguez", "Martinez", "Hernandez", "Lopez", "Gonzalez",
                "Wilson", "Anderson", "Thomas", "Taylor", "Moore", "Jackson", "Martin")
        return f"{self.rng.choice(first)} {self.rng.choice(last)}"

    # ------------------------------------------------------------------ substitution
    def substitute(self, text: str, recipient, generated: GeneratedValues,
                   custom_fields: Optional[dict] = None, extra: Optional[dict] = None) -> SubstitutionResult:
        recipient = recipient or {}
        custom_fields = custom_fields or {}
        extra = extra or {}
        # Accept ORM Recipient objects as well as plain dicts
        if not isinstance(recipient, dict):
            recipient = {c.name: getattr(recipient, c.name, None)
                         for c in recipient.__table__.columns}
        # Normalize: snake_case columns -> CamelCase variables (first_name -> FirstName)
        norm = {}
        for k, v in recipient.items():
            norm[k] = v
            camel = "".join(p.capitalize() for p in str(k).split("_"))
            norm[camel] = v
