port to Angular (incomplete)