/**
 * @license
 * Copyright Google LLC All Rights Reserved.
 *
 * Use of this source code is governed by an MIT-style license that can be
 * found in the LICENSE file at https://angular.dev/license
 */

import {
  HashLocationStrategy,
  Location,
  LocationStrategy,
  PathLocationStrategy,
  ViewportScroller,
} from '@angular/common';
import {
  APP_BOOTSTRAP_LISTENER,
  ComponentRef,
  inject,
  Inject,
  InjectionToken,
  ModuleWithProviders,
  NgModule,
  NgZone,
  Optional,
  Provider,
  SkipSelf,
  ɵRuntimeError as RuntimeError,
} from '@angular/core';

import {EmptyOutletComponent} from './components/empty_outlet';
import {RouterLink} from './directives/router_link';
import {RouterLinkActive} from './directives/router_link_active';
import {RouterOutlet} from './directives/router_outlet';
import {RuntimeErrorCode} from './errors';
import {Routes} from './models';
import {NAVIGATION_ERROR_HANDLER, NavigationTransitions} from './navigation_transition';
import {
  getBootstrapListener,
  rootRoute,
  ROUTER_IS_PROVIDED,
  withComponentInputBinding,
  withDebugTracing,
  withDisabledInitialNavigation,
  withEnabledBlockingInitialNavigation,
  withPreloading,
  withViewTransitions,
} from './provide_router';
import {Router} from './router';
import {ExtraOptions, ROUTER_CONFIGURATION} from './router_config';
import {RouterConfigLoader, ROUTES} from './router_config_loader';
import {ChildrenOutletContexts} from './router_outlet_context';
import {ROUTER_SCROLLER, RouterScroller} from './router_scroller';
import {ActivatedRoute} from './router_state';
import {DefaultUrlSerializer, UrlSerializer} from './url_tree';

/**
 * The directives defined in the `RouterModule`.
 */
const ROUTER_DIRECTIVES = [RouterOutlet, RouterLink, RouterLinkActive, EmptyOutletComponent];

/**
 * @docsNotRequired
 */
export const ROUTER_FORROOT_GUARD = new InjectionToken<void>(
  typeof ngDevMode === 'undefined' || ngDevMode
    ? 'router duplicate forRoot guard'
    : 'ROUTER_FORROOT_GUARD',
);

// TODO(atscott): All of these except `ActivatedRoute` are `providedIn: 'root'`. They are only kept
// here to avoid a breaking change whereby the provider order matters based on where the
// `RouterModule`/`RouterTestingModule` is imported. These can/should be removed as a "breaking"
// change in a major version.
export const ROUTER_PROVIDERS: Provider[] = [
  Location,
  {provide: UrlSerializer, useClass: DefaultUrlSerializer},
  Router,
  ChildrenOutletContexts,
  {provide: ActivatedRoute, useFactory: rootRoute, deps: [Router]},
  RouterConfigLoader,
  // Only used to warn when `provideRoutes` is used without `RouterModule` or `provideRouter`. Can
  // be removed when `provideRoutes` is removed.
  typeof ngDevMode === 'undefined' || ngDevMode
    ? {provide: ROUTER_IS_PROVIDED, useValue: true}
    : [],
];

/**
 * @description
 *
 * Adds directives and providers for in-app navigation among views defined in an application.
 * Use the Angular `Router` service to declaratively specify application states and manage state
 * transitions.
 *
 * You can import this NgModule multiple times, once for each lazy-loaded bundle.
 * However, only one `Router` service can be active.
 * To ensure this, there are two ways to register routes when importing this module:
 *
 * * The `forRoot()` method creates an `NgModule` that contains all the directives, the given
 * routes, and the `Router` service itself.
 * * The `forChild()` method creates an `NgModule` that contains all the directives and the given
 * routes, but does not include the `Router` service.
 *
 * @see [Routing and Navigation guide](guide/routing/common-router-tasks) for an
 * overview of how the `Router` service should be used.
 *
 * @publicApi
 */
@NgModule({
  imports: ROUTER_DIRECTIVES,
  exports: ROUTER_DIRECTIVES,
})
export class RouterModule {
  constructor(@Optional() @Inject(ROUTER_FORROOT_GUARD) guard: any) {}

  /**
   * Creates and configures a module with all the router providers and directives.
   * Optionally sets up an application listener to perform an initial navigation.
   *
   * When registering the NgModule at the root, import as follows:
   *
   * ```
   * @NgModule({
   *   imports: [RouterModule.forRoot(ROUTES)]
   * })
   * class MyNgModule {}
   * ```
   *
   * @param routes An array of `Route` objects that define the navigation paths for the application.
   * @param config An `ExtraOptions` configuration object that controls how navigation is performed.
   * @return The new `NgModule`.
   *
   */
  static forRoot(routes: Routes, config?: ExtraOptions): ModuleWithProviders<RouterModule> {
    return {
      ngModule: RouterModule,
      providers: [
        ROUTER_PROVIDERS,
        typeof ngDevMode === 'undefined' || ngDevMode
          ? config?.enableTracing
            ? withDebugTracing().ɵproviders
            : []
          : [],
        {provide: ROUTES, multi: true, useValue: routes},
        {
          provide: ROUTER_FORROOT_GUARD,
          useFactory: provideForRootGuard,
          deps: [[Router, new Optional(), new SkipSelf()]],
        },
        config?.errorHandler
          ? {
              provide: NAVIGATION_ERROR_HANDLER,
              useValue: config.errorHandler,
            }
          : [],
        {provide: ROUTER_CONFIGURATION, useValue: config ? config : {}},
        config?.useHash ? provideHashLocationStrategy() : providePathLocationStrategy(),
        provideRouterScroller(),
        config?.preloadingStrategy ? withPreloading(config.preloadingStrategy).ɵproviders : [],
        config?.initialNavigation ? provideInitialNavigation(config) : [],
        config?.bindToComponentInputs ? withComponentInputBinding().ɵproviders : [],
        config?.enableViewTransitions ? withViewTransitions().ɵproviders : [],
        provideRouterInitializer(),
      ],
    };
  }

  /**
   * Creates a module with all the router directives and a provider registering routes,
   * without creating a new Router service.
   * When registering for submodules and lazy-loaded submodules, create the NgModule as follows:
   *
   * ```
   * @NgModule({
   *   imports: [RouterModule.forChild(ROUTES)]
   * })
   * class MyNgModule {}
   * ```
   *
   * @param routes An array of `Route` objects that define the navigation paths for the submodule.
   * @return The new NgModule.
   *
   */
  static forChild(routes: Routes): ModuleWithProviders<RouterModule> {
    return {
      ngModule: RouterModule,
      providers: [{provide: ROUTES, multi: true, useValue: routes}],
    };
  }
}

/**
 * For internal use by `RouterModule` only. Note that this differs from `withInMemoryRouterScroller`
 * because it reads from the `ExtraOptions` which should not be used in the standalone world.
 */
export function provideRouterScroller(): Provider {
  return {
    provide: ROUTER_SCROLLER,
    useFactory: () => {
      const viewportScroller = inject(ViewportScroller);
      const zone = inject(NgZone);
      const config: ExtraOptions = inject(ROUTER_CONFIGURATION);
      const transitions = inject(NavigationTransitions);
      const urlSerializer = inject(UrlSerializer);
      if (config.scrollOffset) {
        viewportScroller.setOffset(config.scrollOffset);
      }
      return new RouterScroller(urlSerializer, transitions, viewportScroller, zone, config);
    },
  };
}

// Note: For internal use only with `RouterModule`. Standalone setup via `provideRouter` should
// provide hash location directly via `{provide: LocationStrategy, useClass: HashLocationStrategy}`.
function provideHashLocationStrategy(): Provider {
  return {provide: LocationStrategy, useClass: HashLocationStrategy};
}

// Note: For internal use only with `RouterModule`. Standalone setup via `provideRouter` does not
// need this at all because `PathLocationStrategy` is the default factory for `LocationStrategy`.
function providePathLocationStrategy(): Provider {
  return {provide: LocationStrategy, useClass: PathLocationStrategy};
}

export function provideForRootGuard(router: Router): any {
  if ((typeof ngDevMode === 'undefined' || ngDevMode) && router) {
    throw new RuntimeError(
      RuntimeErrorCode.FOR_ROOT_CALLED_TWICE,
      `The Router was provided more than once. This can happen if 'forRoot' is used outside of the root injector.` +
        ` Lazy loaded modules should use RouterModule.forChild() instead.`,
    );
  }
  return 'guarded';
}

// Note: For internal use only with `RouterModule`. Standalone router setup with `provideRouter`
// users call `withXInitialNavigation` directly.
function provideInitialNavigation(config: Pick<ExtraOptions, 'initialNavigation'>): Provider[] {
  return [
    config.initialNavigation === 'disabled' ? withDisabledInitialNavigation().ɵproviders : [],
    config.initialNavigation === 'enabledBlocking'
      ? withEnabledBlockingInitialNavigation().ɵproviders
      : [],
  ];
}

// TO


/**
 * @license
 * Copyright Google LLC All Rights Reserved.
 *
 * Use of this source code is governed by an MIT-style license that can be
 * found in the LICENSE file at https://angular.dev/license
 */

import {EnvironmentInjector, ProviderToken, runInInjectionContext} from '@angular/core';
import {
  concat,
  defer,
  from,
  MonoTypeOperatorFunction,
  Observable,
  of,
  OperatorFunction,
  pipe,
} from 'rxjs';
import {concatMap, first, map, mergeMap, tap} from 'rxjs/operators';

import {ActivationStart, ChildActivationStart, Event} from '../events';
import {
  CanActivateChildFn,
  CanActivateFn,
  CanDeactivateFn,
  GuardResult,
  CanLoadFn,
  CanMatchFn,
  Route,
} from '../models';
import {navigationCancelingError, redirectingNavigationError} from '../navigation_canceling_error';
import {NavigationTransition} from '../navigation_transition';
import {ActivatedRouteSnapshot, RouterStateSnapshot} from '../router_state';
import {isUrlTree, UrlSegment, UrlSerializer, UrlTree} from '../url_tree';
import {wrapIntoObservable} from '../utils/collection';
import {getClosestRouteInjector} from '../utils/config';
import {
  CanActivate,
  CanDeactivate,
  getCanActivateChild,
  getTokenOrFunctionIdentity,
} from '../utils/preactivation';
import {
  isBoolean,
  isCanActivate,
  isCanActivateChild,
  isCanDeactivate,
  isCanLoad,
  isCanMatch,
} from '../utils/type_guards';

import {prioritizedGuardValue} from './prioritized_guard_value';

export function checkGuards(
  injector: EnvironmentInjector,
  forwardEvent?: (evt: Event) => void,
): MonoTypeOperatorFunction<NavigationTransition> {
  return mergeMap((t) => {
    const {
      targetSnapshot,
      currentSnapshot,
      guards: {canActivateChecks, canDeactivateChecks},
    } = t;
    if (canDeactivateChecks.length === 0 && canActivateChecks.length === 0) {
      return of({...t, guardsResult: true});
    }

    return runCanDeactivateChecks(
      canDeactivateChecks,
      targetSnapshot!,
      currentSnapshot,
      injector,
    ).pipe(
      mergeMap((canDeactivate) => {
        return canDeactivate && isBoolean(canDeactivate)
          ? runCanActivateChecks(targetSnapshot!, canActivateChecks, injector, forwardEvent)
          : of(canDeactivate);
      }),
      map((guardsResult) => ({...t, guardsResult})),
    );
  });
}

function runCanDeactivateChecks(
  checks: CanDeactivate[],
  futureRSS: RouterStateSnapshot,
  currRSS: RouterStateSnapshot,
  injector: EnvironmentInjector,
) {
  return from(checks).pipe(
    mergeMap((check) =>
      runCanDeactivate(check.component, check.route, currRSS, futureRSS, injector),
    ),
    first((result) => {
      return result !== true;
    }, true),
  );
}

function runCanActivateChecks(
  futureSnapshot: RouterStateSnapshot,
  checks: CanActivate[],
  injector: EnvironmentInjector,
  forwardEvent?: (evt: Event) => void,
) {
  return from(checks).pipe(
    concatMap((check: CanActivate) => {
      return concat(
        fireChildActivationStart(check.route.parent, forwardEvent),
        fireActivationStart(check.route, forwardEvent),
        runCanActivateChild(futureSnapshot, check.path, injector),
        runCanActivate(futureSnapshot, check.route, injector),
      );
    }),
    first((result) => {
      return result !== true;
    }, true),
  );
}

/**
 * This should fire off `ActivationStart` events for each route being activated at this
 * level.
 * In other words, if you're activating `a` and `b` below, `path` will contain the
 * `ActivatedRouteSnapshot`s for both and we will fire `ActivationStart` for both. Always
 * return
 * `true` so checks continue to run.
 */
function fireActivationStart(
  snapshot: ActivatedRouteSnapshot | null,
  forwardEvent?: (evt: Event) => void,
): Observable<boolean> {
  if (snapshot !== null && forwardEvent) {
    forwardEvent(new ActivationStart(snapshot));
  }
  return of(true);
}

/**
 * This should fire off `ChildActivationStart` events for each route being activated at this
 * level.
 * In other words, if you're activating `a` and `b` below, `path` will contain the
 * `ActivatedRouteSnapshot`s for both and we will fire `ChildActivationStart` for both. Always
 * return
 * `true` so checks continue to run.
 */
function fireChildActivationStart(
  snapshot: ActivatedRouteSnapshot | null,
  forwardEvent?: (evt: Event) => void,
): Observable<boolean> {
  if (snapshot !== null && forwardEvent) {
    forwardEvent(new ChildActivationStart(snapshot));
  }
  return of(true);
}

function runCanActivate(
  futureRSS: RouterStateSnapshot,
  futureARS: ActivatedRouteSnapshot,
  injector: EnvironmentInjector,
): Observable<GuardResult> {
  const canActivate = futureARS.routeConfig ? futureARS.routeConfig.canActivate : null;
  if (!canActivate || canActivate.length === 0) return of(true);

  const canActivateObservables = canActivate.map(
    (canActivate: CanActivateFn | ProviderToken<unknown>) => {
      return defer(() => {
        const closestInjector = getClosestRouteInjector(futureARS) ?? injector;
        const guard = getTokenOrFunctionIdentity<CanActivate>(canActivate, closestInjector);
        const guardVal = isCanActivate(guard)
          ? guard.canActivate(futureARS, futureRSS)
          : runInInjectionContext(closestInjector, () =>
              (guard as CanActivateFn)(futureARS, futureRSS),
            );
        return wrapIntoObservable(guardVal).pipe(first());
      });
    },
  );
  return of(canActivateObservables).pipe(prioritizedGuardValue());
}

function runCanActivateChild(
  futureRSS: RouterStateSnapshot,
  path: ActivatedRouteSnapshot[],
  injector: EnvironmentInjector,
): Observable<GuardResult> {
  const futureARS = path[path.length - 1];

  const canActivateChildGuards = path
    .slice(0, path.length - 1)
    .reverse()
    .map((p) => getCanActivateChild(p))
    .filter((_) => _ !== null);

  const canActivateChildGuardsMapped = canActivateChildGuards.map((d: any) => {
    return defer(() => {
      const guardsMapped = d.guards.map(
        (canActivateChild: CanActivateChildFn | ProviderToken<unknown>) => {
          const closestInjector = getClosestRouteInjector(d.node) ?? injector;
          const guard = getTokenOrFunctionIdentity<{canActivateChild: CanActivateChildFn}>(
            canActivateChild,
            closestInjector,
          );
          const guardVal = isCanActivateChild(guard)
            ? guard.canActivateChild(futureARS, futureRSS)
            : runInInjectionContext(closestInjector, () =>
                (guard as CanActivateChildFn)(futureARS, futureRSS),
              );
          return wrapIntoObservable(guardVal).pipe(first());
        },
      );
      return of(guardsMapped).pipe(prioritizedGuardValue());
    });
  });
  return of(canActivateChildGuardsMapped).pipe(prioritizedGuardValue());
}

function runCanDeactivate(
  component: Object | null,
  currARS: ActivatedRouteSnapshot,
  currRSS: RouterStateSnapshot,
  futureRSS: RouterStateSnapshot,
  injector: EnvironmentInjector,
): Observable<GuardResult> {
  const canDeactivate = currARS && currARS.routeConfig ? currARS.routeConfig.canDeactivate : null;
  if (!canDeactivate || canDeactivate.length === 0) return of(true);
  const canDeactivateObservables = canDeactivate.map((c: any) => {
    const closestInjector = getClosestRouteInjector(currARS) ?? injector;
    const guard = getTokenOrFunctionIdentity<any>(c, closestInjector);
    const guardVal = isCanDeactivate(guard)
      ? guard.canDeactivate(component, currARS, currRSS, futureRSS)
      : runInInjectionContext(closestInjector, () =>
          (guard as CanDeactivateFn<any>)(component, currARS, currRSS, futureRSS),
        );
    return wrapIntoObservable(guardVal).pipe(first());
  });
  return of(canDeactivateObservables).pipe(prioritizedGuardValue());
}


/**
 * @license
 * Copyright Google LLC All Rights Reserved.
 *
 * Use of this source code is governed by an MIT-style license that can be
 * found in the LICENSE file at https://angular.dev/license
 */

import {Observable} from 'rxjs';
import {filter, map, take} from 'rxjs/operators';

import {
  Event,
  NavigationCancel,
  NavigationCancellationCode,
  NavigationEnd,
  NavigationError,
  NavigationSkipped,
} from '../events';

enum NavigationResult {
  COMPLETE,
  FAILED,
  REDIRECTING,
}

/**
 * Performs the given action once the router finishes its next/current navigation.
 *
 * The navigation is considered complete under the following conditions:
 * - `NavigationCancel` event emits and the code is not `NavigationCancellationCode.Redirect` or
 * `NavigationCancellationCode.SupersededByNewNavigation`. In these cases, the
 * redirecting/superseding navigation must finish.
 * - `NavigationError`, `NavigationEnd`, or `NavigationSkipped` event emits
 */
export function afterNextNavigation(router: {events: Observable<Event>}, action: () => void) {
  router.events
    .pipe(
      filter(
        (e): e is NavigationEnd | NavigationCancel | NavigationError | NavigationSkipped =>
          e instanceof NavigationEnd ||
          e instanceof NavigationCancel ||
          e instanceof NavigationError ||
          e instanceof NavigationSkipped,
      ),
      map((e) => {
        if (e instanceof NavigationEnd || e instanceof NavigationSkipped) {
          return NavigationResult.COMPLETE;
        }
        const redirecting =
          e instanceof NavigationCancel
            ? e.code === NavigationCancellationCode.Redirect ||
              e.code === NavigationCancellationCode.SupersededByNewNavigation
            : false;
        return redirecting ? NavigationResult.REDIRECTING : NavigationResult.FAILED;
      }),
      filter(
        (result): result is NavigationResult.COMPLETE | NavigationResult.FAILED =>
          result !== NavigationResult.REDIRECTING,
      ),
      take(1),
    )
    .subscribe(() => {
      action();
    });
}


# Saved Responses for Angular's Issue Tracker

This doc collects canned responses that the Angular team can use to close issues that fall into the
listed resolution categories.

Since GitHub currently doesn't allow us to have a repository-wide or organization-wide list
of [saved replies](https://help.github.com/articles/working-with-saved-replies/), these replies need
to be maintained by individual team members. Since the responses can be modified in the future, all
responses are versioned to simplify the process of keeping the responses up to date.

## Angular: Already Fixed (v3)

```
Thanks for reporting this issue. Luckily it has already been fixed in one of the recent releases. Please update to the most recent version to resolve the problem.

If after upgrade the problem still exists in your application please [open a new issue](https://github.com/angular/angular/issues/new/choose) and follow the instructions in the issue template.
```

## Angular: Don't Understand (v3)

```
I'm sorry but we don't understand the problem you are reporting.

If the problem still exists in your application, please [open a new issue](https://github.com/angular/angular/issues/new/choose) and follow the instructions in the issue template.
```

## Angular: Can't reproduce (v2)

```
I'm sorry but we can't reproduce the problem you are reporting. We require that reported issues have a minimal reproduction that showcases the problem.

If the problem still exists in your application, please [open a new issue](https://github.com/angular/angular/issues/new/choose) and follow the instructions in the issue template that include info on how to create a reproduction using our template.
```

## Angular: Duplicate (v2)

```
Thanks for reporting this issue. However this issue is a duplicate of an existing issue #ISSUE_NUMBER. Please subscribe to that issue for future updates.
```

## Angular: Insufficient Information Provided (v2)

```
Thanks for reporting this issue. However, you didn't provide sufficient information for us to understand and reproduce the problem. Please check out [our submission guidelines](https://github.com/angular/angular/blob/main/CONTRIBUTING.md#submit-issue) to understand why we can't act on issues that are lacking important information.

If the problem still exists in your application, please [open a new issue](https://github.com/angular/angular/issues/new/choose) and follow the instructions in the issue template.

```

## Angular: Issue Outside of Angular (v2)

```
I'm sorry but this issue is not caused by Angular. Please contact the author(s) of project PROJECT_NAME or file issue on their issue tracker.
```

## Angular: Behaving as Expected (v1)

```
It appears this behaves as expected. If you still feel there is an issue, please provide further details in a new issue.
```

## Angular: Non-reproducible (v2)

```
I'm sorry but we can't reproduce the problem following the instructions you provided.

If the problem still exists in your application please [open a new issue](https://github.com/angular/angular/issues/new/choose) and follow the instructions in the issue template.
```

## Angular: Obsolete (v2)

```
Thanks for reporting this issue. This issue is now obsolete due to changes in the recent releases. Please update to the most recent Angular version.

If the problem still exists in your application, please [open a new issue](https://github.com/angular/angular/issues/new/choose) and follow the instructions in the issue template.
```

## Angular: Support Request (v1)

```
Hello, we reviewed this issue and determined that it doesn't fall into the bug report or feature request category. This issue tracker is not suitable for support requests, please repost your issue on [StackOverflow](https://stackoverflow.com/) using tag `angular`.

If you are wondering why we don't resolve support issues via the issue tracker, please [check out this explanation](https://github.com/angular/angular/blob/main/CONTRIBUTING.md#question).
```

## Angular: Commit Header

```
It looks like you need to update your commit header to match our requirements. This is different from the PR title. To update the commit header, use the command `git commit --amend` and update the header there.

Once you've finished that update, you will need to force push using `git push [origin name] [branch name] --force`. That should address this.
```

## Angular: Rebase and Squash

```
Please rebase and squash your commits. To do this, make sure to `git fetch upstream` to get the latest changes from the angular repository. Then in your branch run `git rebase upstream/main -i` to do an interactive rebase. This should allow you to fixup or drop any unnecessary commits. After you finish the rebase, force push using `git push [origin name] [branch name] --force`.
```


## Releasing APIs before they're fully stable

The Angular team may occasionally seek to release a feature or API without immediately
including this API in Angular's normal support and deprecation category. You can use
one of two labels on such APIs: Developer Preview and Experimental. APIs tagged this way
are not subject to Angular's breaking change and deprecation policy.

Use the sections below to decide whether a pre-stable tag makes sense.

### Developer Preview

Use "Developer Preview" when:
* The team has relatively high confidence the API will ship as stable.
* The team needs additional community feedback before fully committing to an exact API shape.
* The API may undergo only minor, superficial changes. This can include changes like renaming
  or reordering parameters, but should not include significant conceptual or structural changes.

### Experimental

Use "Experimental" when:
* The team has low-to-medium confidence that the API should exist at all.
* The team needs additional community feedback before deciding to move forward with the API at all.
* The API may undergo significant conceptual or structural changes.
* The API relies on a not-yet-standardized platform feature.


# Angular Branching and Versioning: A Practical Guide

This guide explains how the Angular team manages branches and how those branches relate to
merging PRs and publishing releases. Before reading, you should understand
[Semantic Versioning](https://semver.org/#semantic-versioning-200).

## Distribution tags on npm

Angular's branching relates directly to versions published on npm. We will reference these [npm
distribution tags](https://docs.npmjs.com/cli/v6/commands/npm-dist-tag#purpose) throughout:

| Tag    | Description                                                                       |
|--------|-----------------------------------------------------------------------------------|
| latest | The most recent stable version.                                                   |
| next   | The most recent pre-release version of Angular for testing. May not always exist. |
| v*-lts | The most recent LTS release for the specified version, such as `v9-lts`.          |

## Branch naming

Angular's main branch is `main`. This branch always represents the absolute latest changes. The
code on `main` always represents a pre-release version, often published with the `next` tag on npm.

For each minor and major version increment, a new branch is created. These branches use a naming
scheme matching `\d+\.\d+\.x` and receive subsequent patch changes for that version range. For
example, the `10.2.x` branch represents the latest patch changes for subsequent releases starting
with `10.2.`. The version tagged on npm as `latest` will always correspond to such a branch,
referred to as the **active patch branch**.

## Major releases lifecycle

Angular releases a major version roughly every six months. Following a major release, we move
through a consistent lifecycle to the next major release, and repeat. At a high level, this
process proceeds as follows:

* A major release occurs. The `main` branch now represents the next minor version.
* Six weeks later, a minor release occurs. The `main` branch now represents the next minor
  version.
* Six weeks later, a second minor release occurs. The `main` branch now represents the next major
  version.
* Three months later, a major release occurs and the process repeats.

### Example
* Angular publishes `11.0.0`. At this point in time, the `main` branch represents `11.1.0`.
* Six weeks later, we publish `11.1.0` and `main` represents `11.2.0`.
* Six weeks later, we publish `11.2.0` and `main` represents `12.0.0`.
* Three months later, this cycle repeats with the publication of `12.0.0`.

### Feature freeze and release candidates

Before publishing minor and major versions as `latest` on npm, they go through a feature freeze and
a release candidate (RC) phase.

**Feature freeze** means that `main` is forked into a branch for a specific version, with no
additional features permitted before releasing as `latest` to npm. This branch becomes the **active
RC branch**. Upon branching, the `main` branch increments to the next minor or major pre-release
version. One week after feature freeze, the first RC is published with the `next` tag on npm from
the active RC branch. Patch bug fixes continue to merge into `main`, the active RC branch, and
the active patch branch during this entire period.

One to three weeks after publishing the first RC, the active RC branch is published as `latest` on
npm and the branch becomes the active patch branch. At this point there is no active RC branch until
the next minor or major release.

## Targeting pull requests

Every pull request has a **base branch**:

![Screenshot of a GitHub PR with the base branch highlighted](./images/pr-base-branch-screenshot.png)

This base branch represents the latest branch that will receive the change. Most pull requests
should specify `main`. However, some changes will explicitly use an earlier branch, such as
`11.1.x`, in order to patch an older version. Specific GitHub labels, described below, control the
additional branches into which a pull request will be cherry-picked.

### Labelling pull requests

There are five labels that target PRs to versions:

| Label         | Description                                                                 |
|---------------|-----------------------------------------------------------------------------|
| target: major | A change that includes a backwards-incompatible behavior or API change.     |
| target: minor | A change that introduces a new, backwards-compatible functionality.         |
| target: patch | A backwards-compatible bug fix.                                             |
| target: rc    | A change that should be explicitly included in an active release candidate. |
| target: lts   | A critical security or browser compatibility fix for LTS releases.          |

Every PR must have exactly one `target: *` label. Angular's dev tooling will merge the pull request
into its base branch and then cherry-pick the commits to the appropriate branches based on the
specified target label.

The vast majority of pull requests will target `major`, `minor`, or `patch` based on the contents of
the code change. In rare cases, a pull request will specify `target: rc` or `target: lts` to
explicitly target a special branch.

Breaking changes, marked with `target: major`, can only be merged when `main` represents the next
major version.

### Pull request examples

| I want to...                                                | Target branch           | Target label | Your change will land in...                                                                                |
| ----------------------------------------------------------- | ----------------------- | ------------ | -------------------------------------------------------------------------------------------------------------------------- |
| Make a non-breaking bug fix                                 | `main`                  | `patch`      | `main`, the active patch branch, and the active RC branch if there is one                                                  |
| Introduce a new feature                                     | `main`                  | `minor`      | `main` (any time)                                                                                |
| Make a breaking change                                      | `main`                  | `major`      | `main` (only when `main` represents the next major version)                                                                |
| Make a critical security fix                                | `main`                  | `lts`        | `main`, the active patch branch, the active RC branch if there is one, and all branches for versions within the LTS window |
| Bump the version of an RC                                   | the active RC branch    | `rc`         | The active RC branch                                                                                |
| Fix an RC bug for a major release feature                   | `main`                  | `rc`         | `main` and the active RC branch                                                                                |
| Backport a bug fix to the `latest` npm version during an RC | the active patch branch | `patch`      | the active patch branch only                                                                                |


# Building and Testing Angular

This document describes how to set up your development environment to build and test Angular.
It also explains the basic mechanics of using `git`, `node`, and `yarn`.

* [Prerequisite Software](#prerequisite-software)
* [Getting the Sources](#getting-the-sources)
* [Installing NPM Modules](#installing-npm-modules)
* [Building](#building)
* [Running Tests Locally](#running-tests-locally)
* [Formatting your Source Code](#formatting-your-source-code)
* [Linting/verifying your Source Code](#lintingverifying-your-source-code)
* [Publishing Snapshot Builds](#publishing-snapshot-builds)
* [Bazel Support](#bazel-support)

See the [contribution guidelines](https://github.com/angular/angular/blob/main/CONTRIBUTING.md)
if you'd like to contribute to Angular.

## Prerequisite Software

Before you can build and test Angular, you must install and configure the
following on your development machine:

* [Git](https://git-scm.com/) and/or the [**GitHub app**](https://desktop.github.com/) (for Mac and
  Windows);
  [GitHub's Guide to Installing Git](https://help.github.com/articles/set-up-git) is a good source
  of information.\
  **Windows Users**: Git Bash or an equivalent shell is required\
  *Windows Powershell and cmd shells are not
  supported [#46780](https://github.com/angular/angular/issues/46780) so some commands might fail*

* [Node.js](https://nodejs.org), (version specified in [`.nvmrc`](../.nvmrc)) which is used to run a
  development web server,
  run tests, and generate distributable files.
  `.nvmrc` is read by [nvm](https://github.com/nvm-sh/nvm) commands like `nvm install`
  and `nvm use`.

* [Yarn](https://yarnpkg.com) (version specified in the engines field
  of [`package.json`](../package.json)) which is used to install dependencies.

* On Windows: [MSYS2](https://www.msys2.org/) which is used by Bazel. Follow
  the [instructions](https://bazel.build/install/windows#installing-compilers-and-language-runtimes)

## Getting the Sources

Fork and clone the Angular repository:

1. Login to your GitHub account or create one by following the instructions given
   [here](https://github.com/signup/free).
2. [Fork](https://help.github.com/forking) the [main Angular
   repository](https://github.com/angular/angular).
3. Clone your fork of the Angular repository and define an `upstream` remote pointing back to
   the Angular repository that you forked in the first place.

```shell
# Clone your GitHub repository:
git clone git@github.com:<github username>/angular.git

# Go to the Angular directory:
cd angular

# Add the main Angular repository as an upstream remote to your repository:
git remote add upstream https://github.com/angular/angular.git
```

## Installing NPM Modules

Next, install the JavaScript modules needed to build and test Angular:

```shell
# Install Angular project dependencies (package.json)
yarn install
```

## Building

To build Angular run:

```shell
yarn build
```

* Results are put in the `dist/packages-dist` folder.

## Running Tests Locally

Bazel is used as the primary tool for building and testing Angular.

To see how to run and debug Angular tests locally please refer to the
Bazel [Testing Angular](./building-with-bazel.md#testing-angular) section.

Note that you should execute all test suites before submitting a PR to
GitHub (`yarn test //packages/...`).

However, affected tests will be executed on our CI infrastructure. So if you forgot to run some
affected tests which would fail, GitHub will indicate the error state and present you the failures.

PRs can only be merged if the code is formatted properly and all tests are passing.

### Testing changes against a local library/project

Often for developers the best way to ensure the changes they have made work as expected is to run
use changes in another library or project. To do this developers can build Angular locally, and
using `yarn link` build a local project with the created artifacts.

This can be done by running:

```sh
yarn ng-dev misc build-and-link <path-to-local-project-root>
```

### Building and serving a project

#### Cache

When making changes to Angular packages and testing in a local library/project you need to
run `ng cache disable` to disable the Angular CLI disk cache. If you are making changes that are not
reflected in your locally served library/project, verify if you
have [CLI Cache](https://angular.io/guide/workspace-config#cache-options) disabled.

#### Invoking the Angular CLI

The Angular CLI needs to be invoked using
Node.js [`--preserve-symlinks`](https://nodejs.org/api/cli.html#--preserve-symlinks) flag. Otherwise
the symbolic links will be resolved using their real path which causes node module resolution to
fail.

```sh
node --preserve-symlinks --preserve-symlinks-main node_modules/@angular/cli/lib/init.js serve
```

## Formatting your source code

Angular uses [prettier](https://clang.llvm.org/docs/ClangFormat.html) to format the source code.
If the source code is not properly formatted, the CI will fail and the PR cannot be merged.

You can automatically format your code by running:

- `yarn ng-dev format changed [shaOrRef]`: format only files changed since the provided
  sha/ref. `shaOrRef` defaults to `main`.
- `yarn ng-dev format all`: format _all_ source code
- `yarn ng-dev format files <files..>`: format only provided files

## Linting/verifying your Source Code

You can check that your code is properly formatted and adheres to coding style by running:

``` shell
$ yarn lint
```

## Publishing Snapshot Builds

When a build of any branch on the upstream fork angular/angular is green on CI, it
automatically publishes build artifacts to repositories in the Angular org. For example,
the `@angular/core` package is published to https://github.com/angular/core-builds.

You may find that your un-merged change needs some validation from external participants.
Rather than requiring them to pull your Pull Request and build Angular locally, they can depend on
snapshots of the Angular packages created based on the code in the Pull Request.

### Publishing to GitHub Repos

You can also manually publish `*-builds` snapshots just like our CI build does for upstream
builds. Before being able to publish the packages, you need to build them locally by running the
`yarn build` command.

First time, you need to create the GitHub repositories:

``` shell
$ export TOKEN=[get one from https://github.com/settings/tokens]
$ CREATE_REPOS=1 ./scripts/ci/publish-build-artifacts.sh [GitHub username]
```

For subsequent snapshots, just run:

``` shell
$ ./scripts/ci/publish-build-artifacts.sh [GitHub username]
```

The script will publish the build snapshot to a branch with the same name as your current branch,
and create it if it doesn't exist.

## Bazel Support

### IDEs

#### VS Code

1. Install [Bazel](https://marketplace.visualstudio.com/items?itemName=BazelBuild.vscode-bazel)
   extension for VS Code.

#### WebStorm / IntelliJ

1. Install the [Bazel](https://plugins.jetbrains.com/plugin/8609-bazel) plugin
2. You can find the settings under `Preferences->Other Settings->Bazel Settings`

It will automatically recognize `*.bazel` and `*.bzl` files.

### Remote Build Execution and Remote Caching

Bazel builds in the Angular repository use a shared cache. When a build occurs, a hash of the inputs
is computed
and checked against available outputs in the shared cache. If an output is found, it is used as the
output for the
build action rather than performing the build locally.

> Remote Build Execution requires authentication as a google.com account.

#### --config=remote flag

The `--config=remote` flag can be added to enable remote execution of builds.


import { AfterViewInit } from '@angular/core';
import { ChangeDetectorRef } from '@angular/core';
import { ElementRef } from '@angular/core';
import { EventEmitter } from '@angular/core';
import * as i0 from '@angular/core';
import { InjectionToken } from '@angular/core';
import { Injector } from '@angular/core';
import { ModuleWithProviders } from '@angular/core';
import { Observable } from 'rxjs';
import { OnChanges } from '@angular/core';
import { OnDestroy } from '@angular/core';
import { OnInit } from '@angular/core';
import { Renderer2 } from '@angular/core';
import { SimpleChanges } from '@angular/core';
import { Version } from '@angular/core';

// @public
export abstract class AbstractControl<TValue = any, TRawValue extends TValue = TValue> {
    constructor(validators: ValidatorFn | ValidatorFn[] | null, asyncValidators: AsyncValidatorFn | AsyncValidatorFn[] | null);
    addAsyncValidators(validators: AsyncValidatorFn | AsyncValidatorFn[]): void;
    addValidators(validators: ValidatorFn | ValidatorFn[]): void;
    get asyncValidator(): AsyncValidatorFn | null;
    set asyncValidator(asyncValidatorFn: AsyncValidatorFn | null);
    clearAsyncValidators(): void;
    clearValidators(): void;
    get dirty(): boolean;
    disable(opts?: {
        onlySelf?: boolean;
        emitEvent?: boolean;
    }): void;
    get disabled(): boolean;
    enable(opts?: {
        onlySelf?: boolean;
        emitEvent?: boolean;
    }): void;
    get enabled(): boolean;
    readonly errors: ValidationErrors | null;
    readonly events: Observable<ControlEvent<TValue>>;
    get<P extends string | readonly (string | number)[]>(path: P): AbstractControl<ɵGetProperty<TRawValue, P>> | null;
    get<P extends string | Array<string | number>>(path: P): AbstractControl<ɵGetProperty<TRawValue, P>> | null;
    getError(errorCode: string, path?: Array<string | number> | string): any;
    getRawValue(): any;
    hasAsyncValidator(validator: AsyncValidatorFn): boolean;
    hasError(errorCode: string, path?: Array<string | number> | string): boolean;
    hasValidator(validator: ValidatorFn): boolean;
    get invalid(): boolean;
    markAllAsTouched(opts?: {
        emitEvent?: boolean;
    }): void;
    markAsDirty(opts?: {
        onlySelf?: boolean;
        emitEvent?: boolean;
    }): void;
    markAsPending(opts?: {
        onlySelf?: boolean;
        emitEvent?: boolean;
    }): void;
    markAsPristine(opts?: {
        onlySelf?: boolean;
        emitEvent?: boolean;
    }): void;
    markAsTouched(opts?: {
        onlySelf?: boolean;
        emitEvent?: boolean;
    }): void;
    markAsUntouched(opts?: {
        onlySelf?: boolean;
        emitEvent?: boolean;
    }): void;
    get parent(): FormGroup | FormArray | null;
    abstract patchValue(value: TValue, options?: Object): void;
    get pending(): boolean;
    get pristine(): boolean;
    removeAsyncValidators(validators: AsyncValidatorFn | AsyncValidatorFn[]): void;
    removeValidators(validators: ValidatorFn | ValidatorFn[]): void;
    abstract reset(value?: TValue, options?: Object): void;
    get root(): AbstractControl;
    setAsyncValidators(validators: AsyncValidatorFn | AsyncValidatorFn[] | null): void;
    setErrors(errors: ValidationErrors | null, opts?: {
        emitEvent?: boolean;
    }): void;
    setParent(parent: FormGroup | FormArray | null): void;
    setValidators(validators: ValidatorFn | ValidatorFn[] | null): void;
    abstract setValue(value: TRawValue, options?: Object): void;
    get status(): FormControlStatus;
    readonly statusChanges: Observable<FormControlStatus>;
    get touched(): boolean;
    get untouched(): boolean;
    get updateOn(): FormHooks;
    updateValueAndValidity(opts?: {
        onlySelf?: boolean;
        emitEvent?: boolean;
    }): void;
    get valid(): boolean;
    get validator(): ValidatorFn | null;
    set validator(validatorFn: ValidatorFn | null);
    readonly value: TValue;
    readonly valueChanges: Observable<TValue>;
}

// @public
export abstract class AbstractControlDirective {
    get asyncValidator(): AsyncValidatorFn | null;
    abstract get control(): AbstractControl | null;
    get dirty(): boolean | null;
    get disabled(): boolean | null;
    get enabled(): boolean | null;
    get errors(): ValidationErrors | null;
    getError(errorCode: string, path?: Array<string | number> | string): any;
    hasError(errorCode: string, path?: Array<string | number> | string): boolean;
    get invalid(): boolean | null;
    get path(): string[] | null;
    get pending(): boolean | null;
    get pristine(): boolean | null;
    reset(value?: any): void;
    get status(): string | null;
    get statusChanges(): Observable<any> | null;
    get touched(): boolean | null;
    get untouched(): boolean | null;
    get valid(): boolean | null;
    get validator(): ValidatorFn | null;
    get value(): any;
    get valueChanges(): Observable<any> | null;
}

// @public
export interface AbstractControlOptions {
    asyncValidators?: AsyncValidatorFn | AsyncValidatorFn[] | null;
    updateOn?: 'change' | 'blur' | 'submit';
    validators?: ValidatorFn | ValidatorFn[] | null;
}

// @public
export class AbstractFormGroupDirective extends ControlContainer implements OnInit, OnDestroy {
    get control(): FormGroup;
    get formDirective(): Form | null;
    // (undocumented)
    ngOnDestroy(): void;
    // (undocumented)
    ngOnInit(): void;
    get path(): string[];
    // (undocumented)
    static ɵdir: i0.ɵɵDirectiveDeclaration<AbstractFormGroupDirective, never, never, {}, {}, never, never, false, never>;
    // (undocumented)
    static ɵfac: i0.ɵɵFactoryDeclaration<AbstractFormGroupDirective, never>;
}

// @public
export interface AsyncValidator extends Validator {
    validate(control: AbstractControl): Promise<ValidationErrors | null> | Observable<ValidationErrors | null>;
}

// @public
export interface AsyncValidatorFn {
    // (undocumented)
    (control: AbstractControl): Promise<ValidationErrors | null> | Observable<ValidationErrors | null>;
}

// @public
export class CheckboxControlValueAccessor extends BuiltInControlValueAccessor implements ControlValueAccessor {
    writeValue(value: any): void;
    // (undocumented)
    static ɵdir: i0.ɵɵDirectiveDeclaration<CheckboxControlValueAccessor, "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]", never, {}, {}, never, never, false, never>;
    // (undocumented)
    static ɵfac: i0.ɵɵFactoryDeclaration<CheckboxControlValueAccessor, never>;
}

// @public
export class CheckboxRequiredValidator extends RequiredValidator {
    // (undocumented)
    static ɵdir: i0.ɵɵDirectiveDeclaration<CheckboxRequiredValidator, "input[type=checkbox][required][formControlName],input[type=checkbox][required][formControl],input[type=checkbox][required][ngModel]", never, {}, {}, never, never, false, never>;
    // (undocumented)
    static ɵfac: i0.ɵɵFactoryDeclaration<CheckboxRequiredValidator, never>;
}

// @public
export const COMPOSITION_BUFFER_MODE: InjectionToken<boolean>;

// @public
export type ControlConfig<T> = [
T | FormControlState<T>,
(ValidatorFn | ValidatorFn[])?,
(AsyncValidatorFn | AsyncValidatorFn[])?
];

// @public
export abstract class ControlContainer extends AbstractControlDirective {
    get formDirective(): Form | null;
    name: string | number | null;
    get path(): string[] | null;
}

// @public
export abstract class ControlEvent<T = any> {
    abstract readonly source: AbstractControl<unknown>;
}

// @public
export interface ControlValueAccessor {
    registerOnChange(fn: any): void;
    registerOnTouched(fn: any): void;
    setDisabledState?(isDisabled: boolean): void;
    writeValue(obj: any): void;
}

// @public
export class DefaultValueAccessor extends BaseControlValueAccessor implements ControlValueAccessor {
    constructor(renderer: Renderer2, elementRef: ElementRef, _compositionMode: boolean);
    writeValue(value: any): void;
    // (undocumented)
    static ɵdir: i0.ɵɵDirectiveDeclaration<DefaultValueAccessor, "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]", never, {}, {}, never, never, false, never>;
    // (undocumented)
    static ɵfac: i0.ɵɵFactoryDeclaration<DefaultValueAccessor, [null, null, { optional: true; }]>;
}

// @public
export class EmailValidator extends AbstractValidatorDirective {
    email: boolean | string;
    // (undocumented)
    enabled(input: boolean): boolean;
    //


## API Report File for "@angular/core_rxjs-interop"

> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/).

```ts

import { DestroyRef } from '@angular/core';
import { Injector } from '@angular/core';
import { MonoTypeOperatorFunction } from 'rxjs';
import { Observable } from 'rxjs';
import { OutputOptions } from '@angular/core';
import { OutputRef } from '@angular/core';
import { ResourceLoaderParams } from '@angular/core';
import { ResourceOptions } from '@angular/core';
import { ResourceRef } from '@angular/core';
import { Signal } from '@angular/core';
import { Subscribable } from 'rxjs';
import { ValueEqualityFn } from '@angular/core/primitives/signals';

// @public
export function outputFromObservable<T>(observable: Observable<T>, opts?: OutputOptions): OutputRef<T>;

// @public
export function outputToObservable<T>(ref: OutputRef<T>): Observable<T>;

// @public
export function pendingUntilEvent<T>(injector?: Injector): MonoTypeOperatorFunction<T>;

// @public
export function rxResource<T, R>(opts: RxResourceOptions<T, R>): ResourceRef<T>;

// @public
export interface RxResourceOptions<T, R> extends Omit<ResourceOptions<T, R>, 'loader'> {
    // (undocumented)
    loader: (params: ResourceLoaderParams<R>) => Observable<T>;
}

// @public
export function takeUntilDestroyed<T>(destroyRef?: DestroyRef): MonoTypeOperatorFunction<T>;

// @public
export function toObservable<T>(source: Signal<T>, options?: ToObservableOptions): Observable<T>;

// @public
export interface ToObservableOptions {
    injector?: Injector;
}

// @public (undocumented)
export function toSignal<T>(source: Observable<T> | Subscribable<T>): Signal<T | undefined>;

// @public (undocumented)
export function toSignal<T>(source: Observable<T> | Subscribable<T>, options: NoInfer<ToSignalOptions<T | undefined>> & {
    initialValue?: undefined;
    requireSync?: false;
}): Signal<T | undefined>;

// @public (undocumented)
export function toSignal<T>(source: Observable<T> | Subscribable<T>, options: NoInfer<ToSignalOptions<T | null>> & {
    initialValue?: null;
    requireSync?: false;
}): Signal<T | null>;

// @public (undocumented)
export function toSignal<T>(source: Observable<T> | Subscribable<T>, options: NoInfer<ToSignalOptions<T>> & {
    initialValue?: undefined;
    requireSync: true;
}): Signal<T>;

// @public (undocumented)
export function toSignal<T, const U extends T>(source: Observable<T> | Subscribable<T>, options: NoInfer<ToSignalOptions<T | U>> & {
    initialValue: U;
    requireSync?: false;
}): Signal<T | U>;

// @public
export interface ToSignalOptions<T> {
    equal?: ValueEqualityFn<T>;
    initialValue?: unknown;
    injector?: Injector;
    manualCleanup?: boolean;
    rejectErrors?: boolean;
    requireSync?: boolean;
}

// (No @packageDocumentation comment for this package)

```


d: string, url: string, options: {
        body?: any;
        headers?: HttpHeaders | {
            [header: string]: string | string[];
        };
        context?: HttpContext;
        reportProgress?: boolean;
        observe: 'events';
        params?: HttpParams | {
            [param: string]: string | number | boolean | ReadonlyArray<string | number | boolean>;
        };
        responseType?: 'json';
        withCredentials?: boolean;
        transferCache?: {
            includeHeaders?: string[];
        } | boolean;
    }): Observable<HttpEvent<any>>;
    request<R>(method: string, url: string, options: {
        body?: any;
        headers?: HttpHeaders | {
            [header: string]: string | string[];
        };
        context?: HttpContext;
        reportProgress?: boolean;
        observe: 'events';
        params?: HttpParams | {
            [param: string]: string | number | boolean | ReadonlyArray<string | number | boolean>;
        };
        responseType?: 'json';
        withCredentials?: boolean;
        transferCache?: {
            includeHeaders?: string[];
        } | boolean;
    }): Observable<HttpEvent<R>>;
    request(method: string, url: string, options: {
        body?: any;
        headers?: HttpHeaders | {
            [header: string]: string | string[];
        };
        observe: 'response';
        context?: HttpContext;
        params?: HttpParams | {
            [param: string]: string | number | boolean | ReadonlyArray<string | number | boolean>;
        };
        reportProgress?: boolean;
        responseType: 'arraybuffer';
        withCredentials?: boolean;
        transferCache?: {
            includeHeaders?: string[];
        } | boolean;
    }): Observable<HttpResponse<ArrayBuffer>>;
    request(method: string, url: string, options: {
        body?: any;
        headers?: HttpHeaders | {
            [header: string]: string | string[];
        };
        observe: 'response';
        context?: HttpContext;
        params?: HttpParams | {
            [param: string]: string | number | boolean | ReadonlyArray<string | number | boolean>;
        };
        reportProgress?: boolean;
        responseType: 'blob';
        withCredentials?: boolean;
        transferCache?: {
            includeHeaders?: string[];
        } | boolean;
    }): Observable<HttpResponse<Blob>>;
    request(method: string, url: string, options: {
        body?: any;
        headers?: HttpHeaders | {
            [header: string]: string | string[];
        };
        observe: 'response';
        context?: HttpContext;
        params?: HttpParams | {
            [param: string]: string | number | boolean | ReadonlyArray<string | number | boolean>;
        };
        reportProgress?: boolean;
        responseType: 'text';
        withCredentials?: boolean;
        transferCache?: {
            includeHeaders?: string[];
        } | boolean;
    }): Observable<HttpResponse<string>>;
    request(method: string, url: string, options: {
        body?: any;
        headers?: HttpHeaders | {
            [header: string]: string | string[];
        };
        context?: HttpContext;
        reportProgress?: boolean;
        observe: 'response';
        params?: HttpParams | {
            [param: string]: string | number | boolean | ReadonlyArray<string | number | boolean>;
        };
        responseType?: 'json';
        withCredentials?: boolean;
    }): Observable<HttpResponse<Object>>;
    request<R>(method: string, url: string, options: {
        body?: any;
        headers?: HttpHeaders | {
            [header: string]: string | string[];
        };
        context?: HttpContext;
        reportProgress?: boolean;
        observe: 'response';
        params?: HttpParams | {
            [param: string]: string | number | boolean | ReadonlyArray<string | number | boolean>;
        };
        responseType?: 'json';
        withCredentials?: boolean;
        transferCache?: {
            includeHeaders?: string[];
        } | boolean;
    }): Observable<HttpResponse<R>>;
    request(method: string, url: string, options?: {
        body?: any;
        headers?: HttpHeaders | {
            [header: string]: string | string[];
        };
        context?: HttpContext;
        observe?: 'body';
        params?: HttpParams | {
            [param: string]: string | number | boolean | ReadonlyArray<string | number | boolean>;
        };
        responseType?: 'json';
        reportProgress?: boolean;
        withCredentials?: boolean;
        transferCache?: {
            includeHeaders?: string[];
        } | boolean;
    }): Observable<Object>;
    request<R>(method: string, url: string, options?: {
        body?: any;
        headers?: HttpHeaders | {
            [header: string]: string | string[];
        };
        context?: HttpContext;
        observe?: 'body';
        params?: HttpParams | {
            [param: string]: string | number | boolean | ReadonlyArray<string | number | boolean>;
        };
        responseType?: 'json';
        reportProgress?: boolean;
        withCredentials?: boolean;
        transferCache?: {
            includeHeaders?: string[];
        } | boolean;
    }): Observable<R>;
    request(method: string, url: string, options?: {
        body?: any;
        headers?: HttpHeaders | {
            [header: string]: string | string[];
        };
        context?: HttpContext;
        params?: HttpParams | {
            [param: string]: string | number | boolean | ReadonlyArray<string | number | boolean>;
        };
        observe?: 'body' | 'events' | 'response';
        reportProgress?: boolean;
        responseType?: 'arraybuffer' | 'blob' | 'json' | 'text';
        withCredentials?: boolean;
        transferCache?: {
            includeHeaders?: string[];
        } | boolean;
    }): Observable<any>;
    // (undocumented)
    static ɵfac: i0.ɵɵFactoryDeclaration<HttpClient, never>;
    // (undocumented)
    static ɵprov: i0.ɵɵInjectableDeclaration<HttpClient>;
}

// @public @deprecated
export class HttpClientJsonpModule {
    // (undocumented)
    static ɵfac: i0.ɵɵFactoryDeclaration<HttpClientJsonpModule, never>;
    // (undocumented)
    static ɵinj: i0.ɵɵInjectorDeclaration<HttpClientJsonpModule>;
    // (undocumented)
    static ɵmod: i0.ɵɵNgModuleDeclaration<HttpClientJsonpModule, never, never, never>;
}

// @public @deprecated
export class HttpClientModule {
    // (undocumented)
    static ɵfac: i0.ɵɵFactoryDeclaration<HttpClientModule, never>;
    // (undocumented)
    static ɵinj: i0.ɵɵInjectorDeclaration<HttpClientModule>;
    // (undocumented)
    static ɵmod: i0.ɵɵNgModuleDeclaration<HttpClientModule, never, never, never>;
}

// @public @deprecated
export class HttpClientXsrfModule {
    static disable(): ModuleWithProviders<HttpClientXsrfModule>;
    static withOptions(options?: {
        cookieName?: string;
        headerName?: string;
    }): ModuleWithProviders<HttpClientXsrfModule>;
    // (undocumented)
    static ɵfac: i0.ɵɵFactoryDeclaration<HttpClientXsrfModule, never>;
    // (undocumented)
    static ɵinj: i0.ɵɵInjectorDeclaration<HttpClientXsrfModule>;
    // (undocumented)
    static ɵmod: i0.ɵɵNgModuleDeclaration<HttpClientXsrfModule, never, never, never>;
}

// @public
export class HttpContext {
    delete(token: HttpContextToken<unknown>): HttpContext;
    get<T>(token: HttpContextToken<T>): T;
    has(token: HttpContextToken<unknown>): boolean;
    // (undocumented)
    keys(): IterableIterator<HttpContextToken<unknown>>;
    set<T>(token: HttpContextToken<T>, value: T): HttpContext;
}

// @public
export class HttpContextToken<T> {
    constructor(defaultValue: () => T);
    // (undocumented)
    readonly defaultValue: () => T;
}

// @public
export interface HttpDownloadProgressEvent extends HttpProgressEvent {
    partialText?: string;
    // (undocumented)
    type: HttpEventType.DownloadProgress;
}

// @public
export class HttpErrorResponse extends HttpResponseBase implements Error {
    constructor(init: {
        error?: any;
        headers?: HttpHeaders;
        status?: number;
        statusText?: string;
        url?: string;
    });
    // (undocumented)
    readonly error: any | null;
    // (undocumented)
    readonly message: string;
    // (undocumented)
    readonly name = "HttpErrorResponse";
    readonly ok = false;
}

// @public
export type HttpEvent<T> = HttpSentEvent | HttpHeaderResponse | HttpResponse<T> | HttpProgressEvent | HttpUserEvent<T>;

// @public
export enum HttpEventType {
    DownloadProgress = 3,
    Response = 4,
    ResponseHeader = 2,
    Sent = 0,
    UploadProgress = 1,
    User = 5
}

// @public
export interface HttpFeature<KindT extends HttpFeatureKind> {
    // (undocumented)
    ɵkind: KindT;
    // (undocumented)
    ɵproviders: Provider[];
}

// @public
export enum HttpFeatureKind {
    // (undocumented)
    CustomXsrfConfiguration = 2,
    // (undocumented)
    Fetch = 6,
    // (undocumented)


## API Report File for "@angular/platform-browser_animations"

> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/).

```ts

import { ANIMATION_MODULE_TYPE } from '@angular/core';
import * as i0 from '@angular/core';
import * as i1 from '@angular/platform-browser';
import { ModuleWithProviders } from '@angular/core';
import { Provider } from '@angular/core';

export { ANIMATION_MODULE_TYPE }

// @public
export class BrowserAnimationsModule {
    static withConfig(config: BrowserAnimationsModuleConfig): ModuleWithProviders<BrowserAnimationsModule>;
    // (undocumented)
    static ɵfac: i0.ɵɵFactoryDeclaration<BrowserAnimationsModule, never>;
    // (undocumented)
    static ɵinj: i0.ɵɵInjectorDeclaration<BrowserAnimationsModule>;
    // (undocumented)
    static ɵmod: i0.ɵɵNgModuleDeclaration<BrowserAnimationsModule, never, never, [typeof i1.BrowserModule]>;
}

// @public
export interface BrowserAnimationsModuleConfig {
    disableAnimations?: boolean;
}

// @public
export class NoopAnimationsModule {
    // (undocumented)
    static ɵfac: i0.ɵɵFactoryDeclaration<NoopAnimationsModule, never>;
    // (undocumented)
    static ɵinj: i0.ɵɵInjectorDeclaration<NoopAnimationsModule>;
    // (undocumented)
    static ɵmod: i0.ɵɵNgModuleDeclaration<NoopAnimationsModule, never, never, [typeof i1.BrowserModule]>;
}

// @public
export function provideAnimations(): Provider[];

// @public
export function provideNoopAnimations(): Provider[];

// (No @packageDocumentation comment for this package)

```


/**
 * @license
 * Copyright Google LLC All Rights Reserved.
 *
 * Use of this source code is governed by an MIT-style license that can be
 * found in the LICENSE file at https://angular.dev/license
 */
import {NgModule} from '@angular/core';
import {platformBrowserDynamic} from '@angular/platform-browser-dynamic';
import {BrowserAnimationsModule} from '@angular/platform-browser/animations';

import {AnimateApp} from './app/animate-app';

@NgModule({declarations: [AnimateApp], bootstrap: [AnimateApp], imports: [BrowserAnimationsModule]})
export class ExampleModule {}

platformBrowserDynamic().bootstrapModule(ExampleModule);


<!DOCTYPE html>
<html>
  <head>
    <title>Order Management</title>
    <style>
      .warning {
        background-color: yellow;
      }
    </style>
  </head>

  <body>
    <order-management-app> Loading... </order-management-app>

    <script src="/angular/packages/zone.js/bundles/zone.umd.js"></script>
    <script src="/app_bundle.js"></script>
  </body>
</html>


/**
 * @license
 * Copyright Google LLC All Rights Reserved.
 *
 * Use of this source code is governed by an MIT-style license that can be
 * found in the LICENSE file at https://angular.dev/license
 */

import {Component, NgModule} from '@angular/core';
import {BrowserModule} from '@angular/platform-browser';
import {platformBrowserDynamic} from '@angular/platform-browser-dynamic';

@Component({
  selector: 'async-app',
  template: `

      {{ val1 }}
      <button class="action" (click)="increment()">Increment</button>

      {{ val2 }}
      <button class="action" (click)="delayedIncrement()">Delayed Increment</button>
      <button class="cancel" *ngIf="timeoutId != null" (click)="cancelDelayedIncrement()">
        Cancel
      </button>

      {{ val3 }}
      <button class="action" (click)="multiDelayedIncrements(10)">10 Delayed Increments</button>
      <button
        class="cancel"
        *ngIf="multiTimeoutId != null"
        (click)="cancelMultiDelayedIncrements()"
      >
        Cancel
      </button>

      {{ val4 }}
      <button class="action" (click)="periodicIncrement()">Periodic Increment</button>
      <button class="cancel" *ngIf="intervalId != null" (click)="cancelPeriodicIncrement()">
        Cancel
      </button>

  `,
  standalone: false,
})
class AsyncApplication {
  val1: number = 0;
  val2: number = 0;
  val3: number = 0;
  val4: number = 0;
  timeoutId: any = null;
  multiTimeoutId: any = null;
  intervalId: any = null;

  increment(): void {
    this.val1++;
  }

  delayedIncrement(): void {
    this.cancelDelayedIncrement();
    this.timeoutId = setTimeout(() => {
      this.val2++;
      this.timeoutId = null;
    }, 2000);
  }

  multiDelayedIncrements(i: number): void {
    this.cancelMultiDelayedIncrements();

    const self = this;
    function helper(_i: number) {
      if (_i <= 0) {
        self.multiTimeoutId = null;
        return;
      }

      self.multiTimeoutId = setTimeout(() => {
        self.val3++;
        helper(_i - 1);
      }, 500);
    }
    helper(i);
  }

  periodicIncrement(): void {
    this.cancelPeriodicIncrement();
    this.intervalId = setInterval(() => this.val4++, 2000);
  }

  cancelDelayedIncrement(): void {
    if (this.timeoutId != null) {
      clearTimeout(this.timeoutId);
      this.timeoutId = null;
    }
  }

  cancelMultiDelayedIncrements(): void {
    if (this.multiTimeoutId != null) {
      clearTimeout(this.multiTimeoutId);
      this.multiTimeoutId = null;
    }
  }

  cancelPeriodicIncrement(): void {
    if (this.intervalId != null) {
      clearInterval(this.intervalId);
      this.intervalId = null;
    }
  }
}

@NgModule({
  declarations: [AsyncApplication],
  bootstrap: [AsyncApplication],
  imports: [BrowserModule],
})
class ExampleModule {}

platformBrowserDynamic().bootstrapModule(ExampleModule);


/**
 * @license
 * Copyright Google LLC All Rights Reserved.
 *
 * Use of this source code is governed by an MIT-style license that can be
 * found in the LICENSE file at https://angular.dev/license
 */

import {Component, Injectable, NgModule} from '@angular/core';
import {FormsModule} from '@angular/forms';
import {BrowserModule} from '@angular/platform-browser';
import {platformBrowserDynamic} from '@angular/platform-browser-dynamic';

/**
 * You can find the AngularJS implementation of this example here:
 * https://github.com/wardbell/ng1DataBinding
 */

// ---- model

let _nextId = 1;
class Person {
  personId: number;
  mom: Person;
  dad: Person;
  friends: Person[];

  constructor(
    public firstName: string,
    public lastName: string,
    public yearOfBirth: number,
  ) {
    this.personId = _nextId++;
    this.firstName = firstName;
    this.lastName = lastName;
    this.mom = null;
    this.dad = null;
    this.friends = [];
    this.personId = _nextId++;
  }

  get age(): number {
    return 2015 - this.yearOfBirth;
  }
  get fullName(): string {
    return `${this.firstName} ${this.lastName}`;
  }
  get friendNames(): string {
    return this.friends.map((f) => f.fullName).join(', ');
  }
}

// ---- services

@Injectable()
export class DataService {
  currentPerson: Person;
  persons: Person[];

  constructor() {
    this.persons = [
      new Person('Victor', 'Savkin', 1930),
      new Person('Igor', 'Minar', 1920),
      new Person('John', 'Papa', 1910),
      new Person('Nancy', 'Duarte', 1910),
      new Person('Jack', 'Papa', 1910),
      new Person('Jill', 'Papa', 1910),
      new Person('Ward', 'Bell', 1910),
      new Person('Robert', 'Bell', 1910),
      new Person('Tracy', 'Ward', 1910),
      new Person('Dan', 'Wahlin', 1910),
    ];

    this.persons[0].friends = [0, 1, 2, 6, 9].map((_) => this.persons[_]);
    this.persons[1].friends = [0, 2, 6, 9].map((_) => this.persons[_]);
    this.persons[2].friends = [0, 1, 6, 9].map((_) => this.persons[_]);
    this.persons[6].friends = [0, 1, 2, 9].map((_) => this.persons[_]);
    this.persons[9].friends = [0, 1, 2, 6].map((_) => this.persons[_]);

    this.persons[2].mom = this.persons[5];
    this.persons[2].dad = this.persons[4];
    this.persons[6].mom = this.persons[8];
    this.persons[6].dad = this.persons[7];

    this.currentPerson = this.persons[0];
  }
}

// ---- components

@Component({
  selector: 'full-name-cmp',
  template: `

Edit Full Name

      <form>

            First:
            <input
              [(ngModel)]="person.firstName"
              type="text"
              placeholder="First name"
              name="firstName"
            />

            Last:
            <input
              [(ngModel)]="person.lastName"
              type="text"
              placeholder="Last name"
              name="lastName"
            />

          {{ person.fullName }}

      </form>

  `,
  standalone: false,
})
export class FullNameComponent {
  constructor(private _service: DataService) {}
  get person(): Person {
    return this._service.currentPerson;
  }
}

@Component({
  selector: 'person-detail-cmp',
  template: `

{{ person.fullName }}

      <form>

          First:
            <input
              [(ngModel)]="person.firstName"
              type="text"
              placeholder="First name"
              name="firstName"
          />

          Last:
            <input
              [(ngModel)]="person.lastName"
              type="text"
              placeholder="Last name"
              name="lastName"
          />

          Year of birth:
            <input
              [(ngModel)]="person.yearOfBirth"
              type="number"
              placeholder="Year of birth"
              name="yearOfBirth"
          />
          Age: {{ person.age }}

          Mom:
          <input
            [(ngModel)]="person.mom.firstName"
            type="text"
            placeholder="Mom's first name"
            name="momFirstName"
          />
          <input
            [(ngModel)]="person.mom.lastName"
            type="text"
            placeholder="Mom's last name"
            name="momLastName"
          />
          {{ person.mom.fullName }}

          Dad:
          <input
            [(ngModel)]="person.dad.firstName"
            type="text"
            placeholder="Dad's first name"
            name="dasFirstName"
          />
          <input
            [(ngModel)]="person.dad.lastName"
            type="text"
            placeholder="Dad's last name"
            name="dadLastName"
          />
          {{ person.dad.fullName }}

 0">
          Friends:
          {{ person.friendNames }}

      </form>

  `,
  standalone: false,
})
export class PersonsDetailComponent {
  constructor(private _service: DataService) {}
  get person(): Person {
    return this._service.currentPerson;
  }
}

@Component({
  selector: 'persons-cmp',
  template: `

FullName Demo

          {{ person.fullName }}

      <person-detail-cmp></person-detail-cmp>

  `,
  standalone: false,
})
export class PersonsComponent {
  persons: Person[];

  constructor(private _service: DataService) {
    this.persons = _service.persons;
  }

  select(person: Person): void {
    this._service.currentPerson = person;
  }
}

@Component({
  selector: 'person-management-app',
  viewProviders: [DataService],
  template: `
    <button (click)="switchToEditName()">Edit Full Name</button>
    <button (click)="switchToPersonList()">Person Array</button>

    <full-name-cmp *ngIf="mode == 'editName'"></full-name-cmp>
    <persons-cmp *ngIf="mode == 'personList'"></persons-cmp>
  `,
  standalone: false,
})
export class PersonManagementApplication {
  mode: string;

  switchToEditName(): void {
    this.mode = 'editName';
  }
  switchToPersonList(): void {
    this.mode = 'personList';
  }
}

@NgModule({
  bootstrap: [PersonManagementApplication],
  declarations: [
    PersonManagementApplication,
    FullNameComponent,
    PersonsComponent,
    PersonsDetailComponent,
  ],
  imports: [BrowserModule, FormsModule],
})
export class ExampleModule {}

platformBrowserDynamic().bootstrapModule(ExampleModule);


/**
 * @license
 * Copyright Google LLC All Rights Reserved.
 *
 * Use of this source code is governed by an MIT-style license that can be
 * found in the LICENSE file at https://angular.dev/license
 */

import {HttpClientModule} from '@angular/common/http';
import {NgModule} from '@angular/core';
import {BrowserModule} from '@angular/platform-browser';
import {platformBrowserDynamic} from '@angular/platform-browser-dynamic';

import {HttpCmp} from './app/http_comp';

@NgModule({
  declarations: [HttpCmp],
  bootstrap: [HttpCmp],
  imports: [BrowserModule, HttpClientModule],
})
export class ExampleModule {}

platformBrowserDynamic().bootstrapModule(ExampleModule);


<!DOCTYPE html>
<html>
  <title>Routing Example</title>
  <link rel="stylesheet" type="text/css" href="./css/gumby.css" />
  <link rel="stylesheet" type="text/css" href="./css/app.css" />
  <base href="/" />

  <body>
    <inbox-app> Loading... </inbox-app>
  </body>

  <script src="/angular/packages/zone.js/bundles/zone.umd.js"></script>
  <script type="module" src="bundles/main.js"></script>
</html>


/**
 * @license
 * Copyright Google LLC All Rights Reserved.
 *
 * Use of this source code is governed by an MIT-style license that can be
 * found in the LICENSE file at https://angular.io/license
 */

import {mergeApplicationConfig, ApplicationConfig} from '@angular/core';
import {provideServerRendering} from '@angular/platform-server';
import {appConfig} from './app.config';

const serverConfig: ApplicationConfig = {
  providers: [provideServerRendering()],
};

export const config = mergeApplicationConfig(appConfig, serverConfig);


/**
 * @license
 * Copyright Google LLC All Rights Reserved.
 *
 * Use of this source code is governed by an MIT-style license that can be
 * found in the LICENSE file at https://angular.io/license
 */

import {Component} from '@angular/core';
import {testData} from '../../test-data';

@Component({
  selector: 'app-root',
  standalone: true,
  template: `

        @for(entry of data; track $index) {

          {{ entry.id }}
          {{ entry.name }}

        }

  `,
})
export class AppComponent {
  data = testData();
  onClick() {}
}


/**
 * @license
 * Copyright Google LLC All Rights Reserved.
 *
 * Use of this source code is governed by an MIT-style license that can be
 * found in the LICENSE file at https://angular.dev/license
 */

import {Component, Input} from '@angular/core';
import {DomSanitizer, SafeStyle} from '@angular/platform-browser';

import {TableCell} from '../util';

let trustedEmptyColor: SafeStyle;
let trustedGreyColor: SafeStyle;

@Component({
  standalone: true,
  selector: 'app',
  template: `

        @for (row of data; track $index) {

          @for (cell of row; track $index) {

            @if (condition) {

            Cell }

          }

        }

  `,
})
export class AppComponent {
  @Input() data: TableCell[][] = [];

  condition = true;

  constructor(sanitizer: DomSanitizer) {
    trustedEmptyColor = sanitizer.bypassSecurityTrustStyle('white');
    trustedGreyColor = sanitizer.bypassSecurityTrustStyle('grey');
  }

  getColor(row: number) {
    return row % 2 ? trustedEmptyColor : trustedGreyColor;
  }
}


/**
 * @license
 * Copyright Google LLC All Rights Reserved.
 *
 * Use of this source code is governed by an MIT-style license that can be
 * found in the LICENSE file at https://angular.dev/license
 */

import {Component, Input} from '@angular/core';
import {DomSanitizer, SafeStyle} from '@angular/platform-browser';

import {TableCell} from '../util';

let trustedEmptyColor: SafeStyle;
let trustedGreyColor: SafeStyle;

@Component({
  standalone: true,
  selector: 'app',
  template: `

        @for (row of data; track $index) {

          @for (cell of row; track $index) {

            @defer (when condition; on immediate) {

            Cell }

          }

        }

  `,
})
export class AppComponent {
  @Input() data: TableCell[][] = [];

  condition = true;

  constructor(sanitizer: DomSanitizer) {
    trustedEmptyColor = sanitizer.bypassSecurityTrustStyle('white');
    trustedGreyColor = sanitizer.bypassSecurityTrustStyle('grey');
  }

  getColor(row: number) {
    return row % 2 ? trustedEmptyColor : trustedGreyColor;
  }
}


<!DOCTYPE html>
<html>
  <head>
    <!-- Prevent the browser from requesting any favicon. -->
    <link rel="icon" href="data:," />
  </head>

  <body>
    <div>
      <app-component>Loading...</app-component>
    </div>

    <script src="/angular/packages/zone.js/bundles/zone.umd.js"></script>
    <script src="/bundle.debug.min.js"></script>
  </body>
</html>


/// <reference path='fourslash.ts' />

// @noImplicitAny: true

// @Filename: /a.ts
////import fs = require("fs");
////fs;

verify.codeFixAvailable([{
    description: "Install '@types/node'",
    commands: [{
        type: "install package",
        file: "/a.ts",
        packageName: "@types/node",
    }],
}]);


// @target: es2017
export async function get(): Promise<[]> {
  let emails = [];
  return emails;
}


export interface ReactSelectProps<TValue = OptionValues> extends React.Props<ReactSelectClass<TValue>> {
    /**
     * text to display when `allowCreate` is true.
     * @default 'Add "{label}"?'
     */
    addLabelText?: string;
    /**
     * renders a custom drop-down arrow to be shown in the right-hand side of the select.
     * @default undefined
     */
    arrowRenderer?: ArrowRendererHandler | null;
    /**
     * blurs the input element after a selection has been made. Handy for lowering the keyboard on mobile devices.
     * @default false
     */
    autoBlur?: boolean;
    /**
     * autofocus the component on mount
     * @deprecated. Use autoFocus instead
     * @default false
     */
    autofocus?: boolean;
    /**
     * autofocus the component on mount
     * @default false
     */
    autoFocus?: boolean;
    /**
     *  If enabled, the input will expand as the length of its value increases
     */
    autosize?: boolean;
    /**
     * whether pressing backspace removes the last item when there is no input value
     * @default true
     */
    backspaceRemoves?: boolean;
    /**
     * Message to use for screenreaders to press backspace to remove the current item
     * {label} is replaced with the item label
     * @default "Press backspace to remove..."
     */
    backspaceToRemoveMessage?: string;
    /**
     * CSS className for the outer element
     */
    className?: string;
    /**
     * Prefix prepended to element default className if no className is defined
     */
    classNamePrefix?: string;
    /**
     * title for the "clear" control when `multi` is true
     * @default "Clear all"
     */
    clearAllText?: string;
    /**
     * Renders a custom clear to be shown in the right-hand side of the select when clearable true
     * @default undefined
     */
    clearRenderer?: ClearRendererHandler;
    /**
     * title for the "clear" control
     * @default "Clear value"
     */
    clearValueText?: string;
    /**
     * whether to close the menu when a value is selected
     * @default true
     */
    closeOnSelect?: boolean;
    /**
     * whether it is possible to reset value. if enabled, an X button will appear at the right side.
     * @default true
     */
    clearable?: boolean;
    /**
     * whether backspace removes an item if there is no text input
     * @default true
     */
    deleteRemoves?: boolean;
    /**
     * delimiter to use to join multiple values
     * @default ","
     */
    delimiter?: string;
    /**
     * whether the Select is disabled or not
     * @default false
     */
    disabled?: boolean;
    /**
     * whether escape clears the value when the menu is closed
     * @default true
     */
    escapeClearsValue?: boolean;
    /**
     * method to filter a single option
     */
    filterOption?: FilterOptionHandler<TValue>;
    /**
     * method to filter the options array
     */
    filterOptions?: FilterOptionsHandler<TValue>;
    /**
     * id for the underlying HTML input element
     * @default undefined
     */
    id?: string;
    /**
     * whether to strip diacritics when filtering
     * @default true
     */
    ignoreAccents?: boolean;
    /**
     * whether to perform case-insensitive filtering
     * @default true
     */
    ignoreCase?: boolean;
    /**
     * custom attributes for the Input (in the Select-control) e.g: {'data-foo': 'bar'}
     * @default {}
     */
    inputProps?: { [key: string]: any };
    /**
     * renders a custom input
     */
    inputRenderer?: InputRendererHandler;
    /**
     * allows for synchronization of component id's on server and client.
     * @see https://github.com/JedWatson/react-select/pull/1105
     */
    instanceId?: string;
    /**
     * whether the Select is loading externally or not (such as options being loaded).
     * if true, a loading spinner will be shown at the right side.
     * @default false
     */
    isLoading?: boolean;
    /**
     * (legacy mode) joins multiple values into a single form field with the delimiter
     * @default false
     */
    joinValues?: boolean;
    /**
     * the option property to use for the label
     * @default "label"
     */
    labelKey?: string;
    /**
     * (any, start) match the start or entire string when filtering
     * @default "any"
     */
    matchPos?: string;
    /**
     * (any, label, value) which option property to filter on
     * @default "any"
     */
    matchProp?: string;
    /**
     * buffer of px between the base of the dropdown and the viewport to shift if menu doesnt fit in viewport
     * @default 0
     */
    menuBuffer?: number;
    /**
     * optional style to apply to the menu container
     */
    menuContainerStyle?: React.CSSProperties;
    /**
     * renders a custom menu with options
     */
    menuRenderer?: MenuRendererHandler<TValue>;
    /**
     * optional style to apply to the menu
     */
    menuStyle?: React.CSSProperties;
    /**
     * multi-value input
     * @default false
     */
    multi?: boolean;
    /**
     * field name, for hidden `<input>` tag
     */
    name?: string;
    /**
     * placeholder displayed when there are no matching search results or a falsy value to hide it
     * @default "No results found"
     */
    noResultsText?: string | JSX.Element;
    /**
     * onBlur handler: function (event) {}
     */
    onBlur?: OnBlurHandler;
    /**
     * whether to clear input on blur or not
     * @default true
     */
    onBlurResetsInput?: boolean;
    /**
     * whether the input value should be reset when options are selected.
     * Also input value will be set to empty if 'onSelectResetsInput=true' and
     * Select will get new value that not equal previous value.
     * @default true
     */
    onSelectResetsInput?: boolean;
    /**
     * whether to clear input when closing the menu through the arrow
     * @default true
     */
    onCloseResetsInput?: boolean;
    /**
     * onChange handler: function (newValue) {}
     */
    onChange?: OnChangeHandler<TValue>;
    /**
     * fires when the menu is closed
     */
    onClose?: OnCloseHandler;
    /**
     * onFocus handler: function (event) {}
     */
    onFocus?: OnFocusHandler;
    /**
     * onInputChange handler: function (inputValue) {}
     */
    onInputChange?: OnInputChangeHandler;
    /**
     * onInputKeyDown handler: function (keyboardEvent) {}
     */
    onInputKeyDown?: OnInputKeyDownHandler;
    /**
     * fires when the menu is scrolled to the bottom; can be used to paginate options
     */
    onMenuScrollToBottom?: OnMenuScrollToBottomHandler;
    /**
     * fires when the menu is opened
     */
    onOpen?: OnOpenHandler;
    /**
     * boolean to enable opening dropdown when focused
     * @default false
     */
    openOnClick?: boolean;
    /**
     * open the options menu when the input gets focus (requires searchable = true)
     * @default true
     */
    openOnFocus?: boolean;
    /**
     * className to add to each option component
     */
    optionClassName?: string;
    /**
     * option component to render in dropdown
     */
    optionComponent?: OptionComponentType<TValue>;
    /**
     * function which returns a custom way to render the options in the menu
     */
    optionRenderer?: OptionRendererHandler<TValue>;
    /**
     * array of Select options
     * @default false
     */
    options?: Options<TValue>;
    /**
     * number of options to jump when using page up/down keys
     * @default 5
     */
    pageSize?: number;
    /**
     * field placeholder, displayed when there's no value
     * @default "Select..."
     */
    placeholder?: string | JSX.Element;
    /**
     * whether the selected option is removed from the dropdown on multi selects
     * @default true
     */
    removeSelected?: boolean;
    /**
     * applies HTML5 required attribute when needed
     * @default false
     */
    required?: boolean;
    /**
     * value to use when you clear the control
     */
    resetValue?: any;
    /**
     * use react-select in right-to-left direction
     * @default false
     */
    rtl?: boolean;
    /**
     * whether the viewport will shift to display the entire menu when engaged
     * @default true
     */
    scrollMenuIntoView?: boolean;
    /**
     * whether to enable searching feature or not
     * @default true;
     */
    searchable?: boolean;
    /**
     * whether to select the currently focused value when the  [tab]  key is pressed
     */
    tabSelectsValue?: boolean;
    /**
     * initial field value
     */
    value?: Option<TValue> | Options<TValue> | string | string[] | number | number[] | boolean;
    /**
     * the option property to use for the value
     * @default "value"


declare let cond: any;

// OK: One or other operand is possibly nullish
const test1 = (cond ? undefined : 32) ?? "possibly reached";

// Not OK: Both operands nullish
const test2 = (cond ? undefined : null) ?? "always reached";

// Not OK: Both operands non-nullish
const test3 = (cond ? 132 : 17) ?? "unreachable";

// Parens
const test4 = (cond ? (undefined) : (17)) ?? 42;

// Should be OK (special case)
if (!!true) {

}

// Should be OK (special cases)
while (0) { }
while (1) { }
while (true) { }
while (false) { }

const p5 = {} ?? null;
const p6 = 0 > 1 ?? null;
const p7 = null ?? null;
const p8 = (class foo { }) && null;
const p9 = (class foo { }) || null;

// Outer expression tests
while ({} as any) { }
while ({} satisfies unknown) { }
while ((<any>({}))) { }
while ((({}))) { }

// Should be OK
console.log((cond || undefined) && 1 / cond);

function foo(this: Object | undefined) {
    // Should be OK
    return this ?? 0;
}


// @noImplicitAny: true
let additional = [];
for (const subcomponent of [1, 2, 3]) {
    additional = [...additional, subcomponent];
}


// @strict: true

export interface Predicate<A> {
    (a: A): boolean
}

interface Left<E> {
    readonly _tag: 'Left'
    readonly left: E
}

interface Right<A> {
    readonly _tag: 'Right'
    readonly right: A
}

type Either<E, A> = Left<E> | Right<A>;

interface Refinement<A, B extends A> {
    (a: A): a is B
}

declare const filter: {
    <A, B extends A>(refinement: Refinement<A, B>): (as: ReadonlyArray<A>) => ReadonlyArray<B>
    <A>(predicate: Predicate<A>): <B extends A>(bs: ReadonlyArray<B>) => ReadonlyArray<B>
    <A>(predicate: Predicate<A>): (as: ReadonlyArray<A>) => ReadonlyArray<A>
};

declare function pipe<A, B>(a: A, ab: (a: A) => B): B;
declare function exists<A>(predicate: Predicate<A>): <E>(ma: Either<E, A>) => boolean;

declare const es: Either<string, number>[];
const x = pipe(es, filter(exists((n) => n > 0)))


// @strict: true

declare const o1: undefined | { b: string };
o1?.b;

declare const o2: undefined | { b: { c: string } };
o2?.b.c;

declare const o3: { b: undefined | { c: string } };
o3.b?.c;

declare const o4: { b?: { c: { d?: { e: string } } } };
o4.b?.c.d?.e;

declare const o5: { b?(): { c: { d?: { e: string } } } };
o5.b?.().c.d?.e;

// GH#33744
declare const o6: <T>() => undefined | ({ x: number });
o6<number>()?.x;

// GH#34109
o1?.b ? 1 : 0;

// GH#36031
o2?.b!.c;
o2?.b!.c!;


Promise.resolve().then(v => null);
>Promise.resolve().then(v => null) : Promise<any>
>                                  : ^^^^^^^^^^^^
>Promise.resolve().then : <TResult1 = void, TResult2 = never>(onfulfilled?: (value: void) => TResult1 | PromiseLike<TResult1>, onrejected?: (reason: any) => TResult2 | PromiseLike<TResult2>) => Promise<TResult1 | TResult2>
>                       : ^        ^^^^^^^^^        ^^^^^^^^^^           ^^^^     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^          ^^^^      ^^   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>Promise.resolve() : Promise<void>
>                  : ^^^^^^^^^^^^^
>Promise.resolve : { (): Promise<void>; <T>(value: T): Promise<Awaited<T>>; <T>(value: T | PromiseLike<T>): Promise<Awaited<T>>; }
>                : ^^^^^^             ^^^ ^^     ^^ ^^^                   ^^^ ^^     ^^                  ^^^                   ^^^
>Promise : PromiseConstructor
>        : ^^^^^^^^^^^^^^^^^^
>resolve : { (): Promise<void>; <T>(value: T): Promise<Awaited<T>>; <T>(value: T | PromiseLike<T>): Promise<Awaited<T>>; }
>        : ^^^^^^             ^^^ ^^     ^^ ^^^                   ^^^ ^^     ^^                  ^^^                   ^^^
>then : <TResult1 = void, TResult2 = never>(onfulfilled?: (value: void) => TResult1 | PromiseLike<TResult1>, onrejected?: (reason: any) => TResult2 | PromiseLike<TResult2>) => Promise<TResult1 | TResult2>
>     : ^        ^^^^^^^^^        ^^^^^^^^^^           ^^^^     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^          ^^^^      ^^   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>v => null : (v: void) => any
>          : ^ ^^^^^^^^^^^^^^
>v : void
>  : ^^^^


privateNameJsPrototype.js(3,3): error TS18016: Private identifiers are not allowed outside class bodies.
privateNameJsPrototype.js(4,3): error TS18016: Private identifiers are not allowed outside class bodies.
privateNameJsPrototype.js(5,7): error TS18016: Private identifiers are not allowed outside class bodies.
privateNameJsPrototype.js(5,7): error TS18028: Private identifiers are only available when targeting ECMAScript 2015 and higher.
privateNameJsPrototype.js(9,3): error TS18016: Private identifiers are not allowed outside class bodies.
privateNameJsPrototype.js(10,3): error TS18016: Private identifiers are not allowed outside class bodies.
privateNameJsPrototype.js(11,7): error TS18016: Private identifiers are not allowed outside class bodies.
privateNameJsPrototype.js(11,7): error TS18028: Private identifiers are only available when targeting ECMAScript 2015 and higher.
privateNameJsPrototype.js(15,10): error TS2339: Property '#z' does not exist on type 'C'.

==== privateNameJsPrototype.js (9 errors) ====
    function A() { }
    A.prototype = {
      #x: 1,         // Error
      ~~
!!! error TS18016: Private identifiers are not allowed outside class bodies.
      #m() {},       // Error
      ~~
!!! error TS18016: Private identifiers are not allowed outside class bodies.
      get #p() { return "" } // Error
          ~~
!!! error TS18016: Private identifiers are not allowed outside class bodies.
          ~~
!!! error TS18028: Private identifiers are only available when targeting ECMAScript 2015 and higher.
    }
    class B { }
    B.prototype = {
      #y: 2,         // Error
      ~~
!!! error TS18016: Private identifiers are not allowed outside class bodies.
      #m() {},       // Error
      ~~
!!! error TS18016: Private identifiers are not allowed outside class bodies.
      get #p() { return "" } // Error
          ~~
!!! error TS18016: Private identifiers are not allowed outside class bodies.
          ~~
!!! error TS18028: Private identifiers are only available when targeting ECMAScript 2015 and higher.
    }
    class C {
      constructor() {
        this.#z = 3;
             ~~
!!! error TS2339: Property '#z' does not exist on type 'C'.
      }
    }