(A: number[], B: number[], P: number[], clamp = true): number => {
    return Vec.dist(P, Vec.nearestPointOnLineSegment(A, B, P, clamp))
  }


(A: number[], B: number[], d: number): number[] => {
    if (Vec.isEqual(A, B)) return A
    return Vec.add(A, Vec.mul(Vec.uni(Vec.sub(B, A)), d))
  }


(A: number[], a: number, d: number): number[] => {
    return [Math.cos(a) * d + A[0], Math.sin(a) * d + A[1]]
  }


(a: number[], n = 4): number[] => {
    return [+a[0].toPrecision(n), +a[1].toPrecision(n)]
  }


(A: number[], B: number[], steps = 6): number[][] => {
    return Array.from(Array(steps)).map((_, i) => {
      const t = i / (steps - 1)
      const k = Math.min(1, 0.5 + Math.abs(0.5 - t))
      return [...Vec.lrp(A, B, t), k]
    })
  }


(_, i) => {
      const t = i / (steps - 1)
      const k = Math.min(1, 0.5 + Math.abs(0.5 - t))
      return [...Vec.lrp(A, B, t), k]
    }


(A: number[], B: number[]) => {
    if (A[0] === B[0]) return NaN
    return (A[1] - B[1]) / (A[0] - B[0])
  }


/**
   * Clamp a value into a range.
   * @param n
   * @param min
   */
static clamp(n: number, min: number): number


static clamp(n: number, min: number, max: number): number


static clamp(n: number, min: number, max?: number): number {
    return Math.max(min, typeof max !== 'undefined' ? Math.min(n, max) : n)
  }


/**
   * Clamp a value into a range.
   * @param n
   * @param min
   */
static clampV(A: number[], min: number): number[]


static clampV(A: number[], min: number, max: number): number[]


static clampV(A: number[], min: number, max?: number): number[] {
    return A.map((n) => (max ? Vec.clamp(n, min, max) : Vec.clamp(n, min)))
  }


/**
   * Cross (for point in polygon)
   *
   */
static cross(x: number[], y: number[], z: number[]): number {
    return (y[0] - x[0]) * (z[1] - x[1]) - (z[0] - x[0]) * (y[1] - x[1])
  }


/**
   * Snap vector to nearest step.
   * @param A
   * @param step
   * @example
   * ```ts
   * Vec.snap([10.5, 28], 10) // [10, 30]
   * ```
   */
static snap(a: number[], step = 1) {
    return [Math.round(a[0] / step) * step, Math.round(a[1] / step) * step]
  }


() => this.fixDirection()


evt => {
      if (!this.isFetching && evt instanceof RouteConfigLoadStart) {
        this.isFetching = true;
      }
      if (evt instanceof NavigationError) {
        this.isFetching = false;
        msg.error(`无法加载${evt.url}路由`, { nzDuration: 1000 * 3 });
        return;
      }
      if (!(evt instanceof NavigationEnd)) {
        return;
      }
      this.isFetching = false;
    }


ev => ev instanceof NavigationEnd


() => {
        this.fixDirection();
      }


@Component({
  selector: 'app-layout',
  template: `
    <ng-container *ngIf="render">
      <app-header></app-header>
      <nz-spin *ngIf="isFetching" class="fetching" nzSpinning></nz-spin>
      <router-outlet></router-outlet>
      <nz-back-top></nz-back-top>
      <theme-btn (themeChange)="themeChange($event)"></theme-btn>
    </ng-container>
  `,
  host: {
    '[attr.id]': `'ng-content'`
  }
})
export class LayoutComponent implements OnDestroy {
  private destroy$ = new Subject<void>();
  isFetching = false;
  render = true;

  constructor(
    private router: Router,
    msg: NzMessageService,
    private settingsSrv: SettingsService,
    private location: Location,
    rtl: RTLService,
    private appSrv: AppService
  ) {
    rtl.change.subscribe(() => this.fixDirection());
    router.events.pipe(takeUntil(this.destroy$)).subscribe(evt => {
      if (!this.isFetching && evt instanceof RouteConfigLoadStart) {
        this.isFetching = true;
      }
      if (evt instanceof NavigationError) {
        this.isFetching = false;
        msg.error(`无法加载${evt.url}路由`, { nzDuration: 1000 * 3 });
        return;
      }
      if (!(evt instanceof NavigationEnd)) {
        return;
      }
      this.isFetching = false;
    });
    router.events
      .pipe(
        takeUntil(this.destroy$),
        filter(ev => ev instanceof NavigationEnd),
        delay(100)
      )
      .subscribe(() => {
        this.fixDirection();
      });
  }

  private fixDirection(): void {
    // 修正rtl的query状态
    const direction = this.settingsSrv.layout.direction;
    const path = this.router.url.split(/[?#|?|#]/)[0];
    const urlTree = this.router.parseUrl(this.router.url);
    let fragment = urlTree.fragment;
    if (fragment != null && fragment.length > 0) {
      fragment = `#${fragment}`;
    } else {
      fragment = '';
    }
    this.location.replaceState(path, (direction === RTL ? `?direction=${RTL}` : '') + fragment);
  }

  themeChange(theme: string): void {
    this.appSrv.setTheme(theme as SiteTheme);
  }

  ngOnDestroy(): void {
    const { destroy$ } = this;
    destroy$.next();
    destroy$.complete();
  }
}


private fixDirection(): void {
    // 修正rtl的query状态
    const direction = this.settingsSrv.layout.direction;
    const path = this.router.url.split(/[?#|?|#]/)[0];
    const urlTree = this.router.parseUrl(this.router.url);
    let fragment = urlTree.fragment;
    if (fragment != null && fragment.length > 0) {
      fragment = `#${fragment}`;
    } else {
      fragment = '';
    }
    this.location.replaceState(path, (direction === RTL ? `?direction=${RTL}` : '') + fragment);
  }


themeChange(theme: string): void {
    this.appSrv.setTheme(theme as SiteTheme);
  }


ngOnDestroy(): void {
    const { destroy$ } = this;
    destroy$.next();
    destroy$.complete();
  }


class ConsultaPunto extends Consulta {

    public run(entornos: Array<Entorno>): Array<Entorno> {
        return entornos;
    }
}


public run(entornos: Array<Entorno>): Array<Entorno> {
        return entornos;
    }


() => {
  oldIsTTY = process.stdout.isTTY;
  oldTERM = process.env.TERM;
}


() => {
  process.stdout.isTTY = oldIsTTY;
  process.env.TERM = oldTERM;
  jest.resetModules();
}


() => {
  jest.doMock('is-ci', () => false);
  process.stdout.isTTY = true;
  process.env.TERM = 'xterm-256color';

  const isInteractive = require('../isInteractive').default;
  expect(isInteractive).toBe(true);
}


() => {
  let isInteractive;
  const expectedResult = false;

  // Test with is-ci being true and isTTY false
  jest.doMock('is-ci', () => true);
  process.stdout.isTTY = undefined;
  process.env.TERM = 'xterm-256color';
  isInteractive = require('../isInteractive').default;
  expect(isInteractive).toBe(expectedResult);

  // Test with is-ci being false and isTTY false
  jest.resetModules();
  jest.doMock('is-ci', () => false);
  process.stdout.isTTY = undefined;
  process.env.TERM = 'xterm-256color';
  isInteractive = require('../isInteractive').default;
  expect(isInteractive).toBe(expectedResult);

  // Test with is-ci being true and isTTY true
  jest.resetModules();
  jest.doMock('is-ci', () => true);
  process.stdout.isTTY = true;
  process.env.TERM = 'xterm-256color';
  isInteractive = require('../isInteractive').default;
  expect(isInteractive).toBe(expectedResult);

  // Test with dumb terminal
  jest.resetModules();
  jest.doMock('is-ci', () => false);
  process.stdout.isTTY = undefined;
  process.env.TERM = 'dumb';
  isInteractive = require('../isInteractive').default;
  expect(isInteractive).toBe(expectedResult);
}


export function fromScanAccountEventRaw(
  raw: ScanAccountEventRaw
): ScanAccountEvent {
  switch (raw.type) {
    case "discovered":
      return {
        type: raw.type,
        account: fromAccountRaw(raw.account),
      };

    default:
      throw new Error("unsupported ScanAccountEvent " + raw.type);
  }
}


export function toScanAccountEventRaw(
  e: ScanAccountEvent
): ScanAccountEventRaw {
  switch (e.type) {
    case "discovered":
      return {
        type: e.type,
        account: toAccountRaw(e.account),
      };

    default:
      throw new Error("unsupported ScanAccountEvent " + e.type);
  }
}


(p: Proxy | null | undefined) => {
  if (p && p.getAccountBridge === getAccountBridge) {
    throw new Error(
      "setBridgeProxy can't be called with same bridge functions!"
    );
  }

  proxy = p;
}


(currency: CryptoCurrency): CurrencyBridge =>
  (proxy || impl).getCurrencyBridge(currency)


(
  account: AccountLike,
  parentAccount?: Account | null | undefined
): AccountBridge<any> =>
  (proxy || impl).getAccountBridge(account, parentAccount)


export type Proxy = {
  getAccountBridge: typeof getAccountBridge;
  getCurrencyBridge: typeof getCurrencyBridge;
};


(state: AppState) => state.accounts


(rawAccounts) => {
    if (rawAccounts.data) {
      return rawAccounts.data;
    }
    return [];
  }


(loggedIn, rawAccounts, time) => {
    if (!loggedIn) {
      return false;
    }
    return shouldUpdate(rawAccounts, {
      staleTime: ms.minutes(10),
      now: time,
    });
  }


(accounts) => {
  let restrictions: CashRestriction[] = [];
  accounts.map((account: Account) => {
    account.cash_restrictions.map((cashRestriction: CashRestriction) => {
      restrictions.push(cashRestriction);
      return null;
    });
    return null;
  });
  restrictions = restrictions.sort((a: CashRestriction, b: CashRestriction) =>
    a.account > b.account ? 1 : 0,
  );
  return restrictions;
}


(account: Account) => {
    account.cash_restrictions.map((cashRestriction: CashRestriction) => {
      restrictions.push(cashRestriction);
      return null;
    });
    return null;
  }


(cashRestriction: CashRestriction) => {
      restrictions.push(cashRestriction);
      return null;
    }


(a: CashRestriction, b: CashRestriction) =>
    a.account > b.account ? 1 : 0


(state: AppState) => state.accountBalances


(pathname) => {
  let accountId = null;
  if (pathname && pathname.split('/').length >= 6) {
    accountId = pathname.split('/')[5];
  }
  return accountId;
}


(accountId, allBalances) => {
  let balances = null;
  if (
    accountId &&
    allBalances &&
    allBalances[accountId] &&
    allBalances[accountId].data
  ) {
    balances = allBalances[accountId].data;
  }
  return balances;
}


(state: AppState) =>
  state.accountPositions


(accountId, allPositions) => {
  let positions = null;
  if (
    accountId &&
    allPositions &&
    allPositions[accountId] &&
    allPositions[accountId].data
  ) {
    positions = allPositions[accountId].data;
  }
  return positions;
}


(accountId, allPositions) => {
  let error = false;
  if (
    accountId &&
    allPositions &&
    allPositions[accountId] &&
    allPositions[accountId].lastError
  ) {
    error = true;
  }
  return error;
}


(accounts) => {
    let hiddenAccounts = [];
    hiddenAccounts = accounts.filter((a) => a.portfolio_group === null);
    return hiddenAccounts;
  }


(a) => a.portfolio_group === null


/**
 * Helper component for optional text properties.
 *
 * Accepts same props as Text component,
 * and `component` which may be a string, a function, null or undefined.
 *
 * If it is null or undefined, will render nothing.
 * If it is a function, will call it with props passed to this component.
 * Otherwise, will render a Text with props passed to this component.
 *
 * @example Will render nothing.
 * ```
 * <FalsyText />
 * ```
 *
 * @example Will render red title.
 * ```
 * const Title = () => (
 *   <FalsyText style={{ color: 'red' }} component='Title' />
 * );
 * ```
 *
 * @example Will render image and red title.
 * ```
 * const renderTitle = (props) => (
 *   <React.Fragment>
 *     <Image source={require('../asset.png')}/>
 *     <Text {...props}>Title</Text>
 *   </React.Fragment>
 * );
 *
 * const Title = () => (
 *   <FalsyText
 *     style={{ color: 'red' }}
 *     component={renderTitle}
 *   />
 * );
 * ```
 */
export class FalsyText extends React.Component<FalsyTextProps> {

  public render(): React.ReactElement {
    const { component, ...textProps } = this.props;

    if (!component) {
      return null;
    }

    if (React.isValidElement(component)) {
      return React.cloneElement(component, textProps as TextProps);
    }

    if (typeof component === 'function') {
      return React.createElement(component, textProps as TextProps);
    }

    return (
      <Text {...textProps}>
        {component}
      </Text>
    );
  }
}


export interface FalsyTextProps extends Omit<TextProps, 'children'> {
  component?: RenderProp<TextProps> | React.ReactText;
}


public render(): React.ReactElement {
    const { component, ...textProps } = this.props;

    if (!component) {
      return null;
    }

    if (React.isValidElement(component)) {
      return React.cloneElement(component, textProps as TextProps);
    }

    if (typeof component === 'function') {
      return React.createElement(component, textProps as TextProps);
    }

    return (
      <Text {...textProps}>
        {component}
      </Text>
    );
  }


export function getBrowserFamily(): BrowserFamily {
  const noWebRTC = +!('RTCDataChannel' in window)
  const noPointerEvent = +!('PointerEvent' in window)
  const noAudioBuffer = +!('AudioBuffer' in window)
  const noWebGLSync = +!('noWebGLSync' in window)

  if (noWebRTC + noPointerEvent + noAudioBuffer + noWebGLSync >= 3) {
    return BrowserFamily.TorBrowser
  }

  if (isDesktopSafari()) {
    return BrowserFamily.Safari
  } else if (isGecko()) {
    return BrowserFamily.Firefox
  } else {
    // if (isChromium()) {
    return BrowserFamily.Chrome
  }

  // return BrowserFamily.Unknown
}


/**
   * Cloud Filestore API
   *
   * The Cloud Filestore API is used for creating and managing cloud file
   * servers.
   *
   * @example
   * const {google} = require('googleapis');
   * const file = google.file('v1beta1');
   *
   * @namespace file
   * @type {Function}
   * @version v1beta1
   * @variation v1beta1
   * @param {object=} options Options for File
   */
export class File {
    projects: Resource$Projects;

    constructor(options: GlobalOptions, google?: GoogleConfigurable) {
      context = {_options: options || {}, google};

      this.projects = new Resource$Projects();
    }
  }


export class Resource$Projects {
    locations: Resource$Projects$Locations;
    constructor() {
      this.locations = new Resource$Projects$Locations();
    }
  }


export class Resource$Projects$Locations {
    instances: Resource$Projects$Locations$Instances;
    operations: Resource$Projects$Locations$Operations;
    constructor() {
      this.instances = new Resource$Projects$Locations$Instances();
      this.operations = new Resource$Projects$Locations$Operations();
    }

    /**
     * file.projects.locations.get
     * @desc Gets information about a location.
     * @alias file.projects.locations.get
     * @memberOf! ()
     *
     * @param {object} params Parameters for request
     * @param {string} params.name Resource name for the location.
     * @param {object} [options] Optionally override request options, such as `url`, `method`, and `encoding`.
     * @param {callback} callback The callback that handles the response.
     * @return {object} Request object
     */
    get(params?: Params$Resource$Projects$Locations$Get,
        options?: MethodOptions): GaxiosPromise<Schema$Location>;
    get(params: Params$Resource$Projects$Locations$Get,
        options: MethodOptions|BodyResponseCallback<Schema$Location>,
        callback: BodyResponseCallback<Schema$Location>): void;
    get(params: Params$Resource$Projects$Locations$Get,
        callback: BodyResponseCallback<Schema$Location>): void;
    get(callback: BodyResponseCallback<Schema$Location>): void;
    get(paramsOrCallback?: Params$Resource$Projects$Locations$Get|
        BodyResponseCallback<Schema$Location>,
        optionsOrCallback?: MethodOptions|BodyResponseCallback<Schema$Location>,
        callback?: BodyResponseCallback<Schema$Location>):
        void|GaxiosPromise<Schema$Location> {
      let params =
          (paramsOrCallback || {}) as Params$Resource$Projects$Locations$Get;
      let options = (optionsOrCallback || {}) as MethodOptions;

      if (typeof paramsOrCallback === 'function') {
        callback = paramsOrCallback;
        params = {} as Params$Resource$Projects$Locations$Get;
        options = {};
      }

      if (typeof optionsOrCallback === 'function') {
        callback = optionsOrCallback;
        options = {};
      }

      const rootUrl = options.rootUrl || 'https://file.googleapis.com/';
      const parameters = {
        options: Object.assign(
            {
              url: (rootUrl + '/v1beta1/{+name}').replace(/([^:]\/)\/+/g, '$1'),
              method: 'GET'
            },
            options),
        params,
        requiredParams: ['name'],
        pathParams: ['name'],
        context
      };
      if (callback) {
        createAPIRequest<Schema$Location>(parameters, callback);
      } else {
        return createAPIRequest<Schema$Location>(parameters);
      }
    }

    /**
     * file.projects.locations.list
     * @desc Lists information about the supported locations for this service.
     * @alias file.projects.locations.list
     * @memberOf! ()
     *
     * @param {object} params Parameters for request
     * @param {string=} params.filter The standard list filter.
     * @param {string} params.name The resource that owns the locations collection, if applicable.
     * @param {integer=} params.pageSize The standard list page size.
     * @param {string=} params.pageToken The standard list page token.
     * @param {object} [options] Optionally override request options, such as `url`, `method`, and `encoding`.
     * @param {callback} callback The callback that handles the response.
     * @return {object} Request object
     */
    list(
        params?: Params$Resource$Projects$Locations$List,
        options?: MethodOptions): GaxiosPromise<Schema$ListLocationsResponse>;
    list(
        params: Params$Resource$Projects$Locations$List,
        options: MethodOptions|
        BodyResponseCallback<Schema$ListLocationsResponse>,
        callback: BodyResponseCallback<Schema$ListLocationsResponse>): void;
    list(
        params: Params$Resource$Projects$Locations$List,
        callback: BodyResponseCallback<Schema$ListLocationsResponse>): void;
    list(callback: BodyResponseCallback<Schema$ListLocationsResponse>): void;
    list(
        paramsOrCallback?: Params$Resource$Projects$Locations$List|
        BodyResponseCallback<Schema$ListLocationsResponse>,
        optionsOrCallback?: MethodOptions|
        BodyResponseCallback<Schema$ListLocationsResponse>,
        callback?: BodyResponseCallback<Schema$ListLocationsResponse>):
        void|GaxiosPromise<Schema$ListLocationsResponse> {
      let params =
          (paramsOrCallback || {}) as Params$Resource$Projects$Locations$List;
      let options = (optionsOrCallback || {}) as MethodOptions;

      if (typeof paramsOrCallback === 'function') {
        callback = paramsOrCallback;
        params = {} as Params$Resource$Projects$Locations$List;
        options = {};
      }

      if (typeof optionsOrCallback === 'function') {
        callback = optionsOrCallback;
        options = {};
      }

      const rootUrl = options.rootUrl || 'https://file.googleapis.com/';
      const parameters = {
        options: Object.assign(
            {
              url: (rootUrl + '/v1beta1/{+name}/locations')
                       .replace(/([^:]\/)\/+/g, '$1'),
              method: 'GET'
            },
            options),
        params,
        requiredParams: ['name'],
        pathParams: ['name'],
        context
      };
      if (callback) {
        createAPIRequest<Schema$ListLocationsResponse>(parameters, callback);
      } else {
        return createAPIRequest<Schema$ListLocationsResponse>(parameters);
      }
    }
  }


export interface Options extends GlobalOptions {
    version: 'v1beta1';
  }


interface StandardParameters {
    /**
     * V1 error format.
     */
    '$.xgafv'?: string;
    /**
     * OAuth access token.
     */
    access_token?: string;
    /**
     * Data format for response.
     */
    alt?: string;
    /**
     * JSONP
     */
    callback?: string;
    /**
     * Selector specifying which fields to include in a partial response.
     */
    fields?: string;
    /**
     * API key. Your API key identifies your project and provides you with API
     * access, quota, and reports. Required unless you provide an OAuth 2.0
     * token.
     */
    key?: string;
    /**
     * OAuth 2.0 token for the current user.
     */
    oauth_token?: string;
    /**
     * Returns response with indentations and line breaks.
     */
    prettyPrint?: boolean;
    /**
     * Available to use for quota purposes for server-side applications. Can be
     * any arbitrary string assigned to a user, but should not exceed 40
     * characters.
     */
    quotaUser?: string;
    /**
     * Legacy upload protocol for media (e.g. "media", "multipart").
     */
    uploadType?: string;
    /**
     * Upload protocol for media (e.g. "raw", "multipart").
     */
    upload_protocol?: string;
  }


/**
   * A generic empty message that you can re-use to avoid defining duplicated
   * empty messages in your APIs. A typical example is to use it as the request
   * or the response type of an API method. For instance:      service Foo { rpc
   * Bar(google.protobuf.Empty) returns (google.protobuf.Empty);     }  The JSON
   * representation for `Empty` is empty JSON object `{}`.
   */
export interface Schema$Empty {}


/**
   * File share configuration for the instance.
   */
export interface Schema$FileShareConfig {
    /**
     * File share capacity in gigabytes (GB). Cloud Filestore defines 1 GB as
     * 1024^3 bytes.
     */
    capacityGb?: string;
    /**
     * The name of the file share (must be 16 characters or less).
     */
    name?: string;
  }


/**
   * A Cloud Filestore instance.
   */
export interface Schema$Instance {
    /**
     * Output only. The time when the instance was created.
     */
    createTime?: string;
    /**
     * Optional. A description of the instance (2048 characters or less).
     */
    description?: string;
    /**
     * Server-specified ETag for the instance resource to prevent simultaneous
     * updates from overwriting each other.
     */
    etag?: string;
    /**
     * File system shares on the instance. For this version, only a single file
     * share is supported.
     */
    fileShares?: Schema$FileShareConfig[];
    /**
     * Resource labels to represent user provided metadata.
     */
    labels?: {[key: string]: string;};
    /**
     * Output only. The resource name of the instance, in the format
     * projects/{project_id}/locations/{location_id}/instances/{instance_id}.
     */
    name?: string;
    /**
     * VPC networks to which the instance is connected. For this version, only a
     * single network is supported.
     */
    networks?: Schema$NetworkConfig[];
    /**
     * Output only. The instance state.
     */
    state?: string;
    /**
     * Output only. Additional information about the instance state, if
     * available.
     */
    statusMessage?: string;
    /**
     * The service tier of the instance.
     */
    tier?: string;
  }


/**
   * ListInstancesResponse is the result of ListInstancesRequest.
   */
export interface Schema$ListInstancesResponse {
    /**
     * A list of instances in the project for the specified location.  If the
     * {location} value in the request is "-", the response contains a
     * list of instances from all locations. If any location is unreachable, the
     * response will only return instances in reachable locations and the
     * "unreachable" field will be populated with a list of
     * unreachable locations.
     */
    instances?: Schema$Instance[];
    /**
     * The token you can use to retrieve the next page of results. Not returned
     * if there are no more results in the list.
     */
    nextPageToken?: string;
    /**
     * Locations that could not be reached.
     */
    unreachable?: string[];
  }


/**
   * The response message for Locations.ListLocations.
   */
export interface Schema$ListLocationsResponse {
    /**
     * A list of locations that matches the specified filter in the request.
     */
    locations?: Schema$Location[];
    /**
     * The standard List next-page token.
     */
    nextPageToken?: string;
  }


/**
   * The response message for Operations.ListOperations.
   */
export interface Schema$ListOperationsResponse {
    /**
     * The standard List next-page token.
     */
    nextPageToken?: string;
    /**
     * A list of operations that matches the specified filter in the request.
     */
    operations?: Schema$Operation[];
  }


/**
   * A resource that represents Google Cloud Platform location.
   */
export interface Schema$Location {
    /**
     * The friendly name for this location, typically a nearby city name. For
     * example, "Tokyo".
     */
    displayName?: string;
    /**
     * Cross-service attributes for the location. For example
     * {"cloud.googleapis.com/region": "us-east1"}
     */
    labels?: {[key: string]: string;};
    /**
     * The canonical id for this location. For example: `"us-east1"`.
     */
    locationId?: string;
    /**
     * Service-specific metadata. For example the available capacity at the
     * given location.
     */
    metadata?: {[key: string]: any;};
    /**
     * Resource name for the location, which may vary between implementations.
     * For example: `"projects/example-project/locations/us-east1"`
     */
    name?: string;
  }


/**
   * Network configuration for the instance.
   */
export interface Schema$NetworkConfig {
    /**
     * Output only. IPv4 addresses in the format {octet 1}.{octet 2}.{octet
     * 3}.{octet 4} or IPv6 addresses in the format {block 1}:{block 2}:{block
     * 3}:{block 4}:{block 5}:{block 6}:{block 7}:{block 8}.
     */
    ipAddresses?: string[];
    /**
     * Internet protocol versions for which the instance has IP addresses
     * assigned. For this version, only MODE_IPV4 is supported.
     */
    modes?: string[];
    /**
     * The name of the Google Compute Engine [VPC
     * network](/compute/docs/networks-and-firewalls#networks) to which the
     * instance is connected.
     */
    network?: string;
    /**
     * A /29 CIDR block in one of the [internal IP address
     * ranges](https://www.arin.net/knowledge/address_filters.html) that
     * identifies the range of IP addresses reserved for this instance. For
     * example, 10.0.0.0/29 or 192.168.0.0/29. The range you specify can't
     * overlap with either existing subnets or assigned IP address ranges for
     * other Cloud Filestore instances in the selected VPC network.
     */
    reservedIpRange?: string;
  }


/**
   * This resource represents a long-running operation that is the result of a
   * network API call.
   */
export interface Schema$Operation {
    /**
     * If the value is `false`, it means the operation is still in progress. If
     * `true`, the operation is completed, and either `error` or `response` is
     * available.
     */
    done?: boolean;
    /**
     * The error result of the operation in case of failure or cancellation.
     */
    error?: Schema$Status;
    /**
     * Service-specific metadata associated with the operation.  It typically
     * contains progress information and common metadata such as create time.
     * Some services might not provide such metadata.  Any method that returns a
     * long-running operation should document the metadata type, if any.
     */
    metadata?: {[key: string]: any;};
    /**
     * The server-assigned name, which is only unique within the same service
     * that originally returns it. If you use the default HTTP mapping, the
     * `name` should have the format of `operations/some/unique/name`.
     */
    name?: string;
    /**
     * The normal response of the operation in case of success.  If the original
     * method returns no data on success, such as `Delete`, the response is
     * `google.protobuf.Empty`.  If the original method is standard
     * `Get`/`Create`/`Update`, the response should be the resource.  For other
     * methods, the response should have the type `XxxResponse`, where `Xxx` is
     * the original method name.  For example, if the original method name is
     * `TakeSnapshot()`, the inferred response type is `TakeSnapshotResponse`.
     */
    response?: {[key: string]: any;};
  }


/**
   * Represents the metadata of the long-running operation.
   */
export interface Schema$OperationMetadata {
    /**
     * [Output only] API version used to start the operation.
     */
    apiVersion?: string;
    /**
     * [Output only] Identifies whether the user has requested cancellation of
     * the operation. Operations that have successfully been cancelled have
     * Operation.error value with a google.rpc.Status.code of 1, corresponding
     * to `Code.CANCELLED`.
     */
    cancelRequested?: boolean;
    /**
     * [Output only] The time the operation was created.
     */
    createTime?: string;
    /**
     * [Output only] The time the operation finished running.
     */
    endTime?: string;
    /**
     * [Output only] Human-readable status of the operation, if any.
     */
    statusDetail?: string;
    /**
     * [Output only] Server-defined resource path for the target of the
     * operation.
     */
    target?: string;
    /**
     * [Output only] Name of the verb executed by the operation.
     */
    verb?: string;
  }


/**
   * The `Status` type defines a logical error model that is suitable for
   * different programming environments, including REST APIs and RPC APIs. It is
   * used by [gRPC](https://github.com/grpc). The error model is designed to be:
   * - Simple to use and understand for most users - Flexible enough to meet
   * unexpected needs  # Overview  The `Status` message contains three pieces of
   * data: error code, error message, and error details. The error code should
   * be an enum value of google.rpc.Code, but it may accept additional error
   * codes if needed.  The error message should be a developer-facing English
   * message that helps developers *understand* and *resolve* the error. If a
   * localized user-facing error message is needed, put the localized message in
   * the error details or localize it in the client. The optional error details
   * may contain arbitrary information about the error. There is a predefined
   * set of error detail types in the package `google.rpc` that can be used for
   * common error conditions.  # Language mapping  The `Status` message is the
   * logical representation of the error model, but it is not necessarily the
   * actual wire format. When the `Status` message is exposed in different
   * client libraries and different wire protocols, it can be mapped
   * differently. For example, it will likely be mapped to some exceptions in
   * Java, but more likely mapped to some error codes in C.  # Other uses  The
   * error model and the `Status` message can be used in a variety of
   * environments, either with or without APIs, to provide a consistent
   * developer experience across different environments.  Example uses of this
   * error model include:  - Partial errors. If a service needs to return
   * partial errors to the client,     it may embed the `Status` in the normal
   * response to indicate the partial     errors.  - Workflow errors. A typical
   * workflow has multiple steps. Each step may     have a `Status` message for
   * error reporting.  - Batch operations. If a client uses batch request and
   * batch response, the     `Status` message should be used directly inside
   * batch response, one for     each error sub-response.  - Asynchronous
   * operations. If an API call embeds asynchronous operation     results in its
   * response, the status of those operations should be     represented directly
   * using the `Status` message.  - Logging. If some API errors are stored in
   * logs, the message `Status` could     be used directly after any stripping
   * needed for security/privacy reasons.
   */
export interface Schema$Status {
    /**
     * The status code, which should be an enum value of google.rpc.Code.
     */
    code?: number;
    /**
     * A list of messages that carry the error details.  There is a common set
     * of message types for APIs to use.
     */
    details?: Array<{[key: string]: any;}>;
    /**
     * A developer-facing error message, which should be in English. Any
     * user-facing error message should be localized and sent in the
     * google.rpc.Status.details field, or localized by the client.
     */
    message?: string;
  }


export interface Params$Resource$Projects$Locations$Get extends
      StandardParameters {
    /**
     * Auth client or API Key for the request
     */
    auth?: string|OAuth2Client|JWT|Compute|UserRefreshClient;

    /**
     * Resource name for the location.
     */
    name?: string;
  }


export interface Params$Resource$Projects$Locations$List extends
      StandardParameters {
    /**
     * Auth client or API Key for the request
     */
    auth?: string|OAuth2Client|JWT|Compute|UserRefreshClient;

    /**
     * The standard list filter.
     */
    filter?: string;
    /**
     * The resource that owns the locations collection, if applicable.
     */
    name?: string;
    /**
     * The standard list page size.
     */
    pageSize?: number;
    /**
     * The standard list page token.
     */
    pageToken?: string;
  }


export interface Params$Resource$Projects$Locations$Instances$Create extends
      StandardParameters {
    /**
     * Auth client or API Key for the request
     */
    auth?: string|OAuth2Client|JWT|Compute|UserRefreshClient;

    /**
     * The name of the instance to create. The name must be unique for the
     * specified project and location.
     */
    instanceId?: string;
    /**
     * The instance's project and location, in the format
     * projects/{project_id}/locations/{location}. In Cloud Filestore, locations
     * map to GCP zones, for example **us-west1-b**.
     */
    parent?: string;

    /**
     * Request body metadata
     */
    requestBody?: Schema$Instance;
  }


export interface Params$Resource$Projects$Locations$Instances$Delete extends
      StandardParameters {
    /**
     * Auth client or API Key for the request
     */
    auth?: string|OAuth2Client|JWT|Compute|UserRefreshClient;

    /**
     * The instance resource name, in the format
     * projects/{project_id}/locations/{location}/instances/{instance_id}
     */
    name?: string;
  }


export interface Params$Resource$Projects$Locations$Instances$Get extends
      StandardParameters {
    /**
     * Auth client or API Key for the request
     */
    auth?: string|OAuth2Client|JWT|Compute|UserRefreshClient;

    /**
     * The instance resource name, in the format
     * projects/{project_id}/locations/{location}/instances/{instance_id}.
     */
    name?: string;
  }


export interface Params$Resource$Projects$Locations$Instances$List extends
      StandardParameters {
    /**
     * Auth client or API Key for the request
     */
    auth?: string|OAuth2Client|JWT|Compute|UserRefreshClient;

    /**
     * List filter.
     */
    filter?: string;
    /**
     * Sort results. Supported values are "name", "name desc" or "" (unsorted).
     */
    orderBy?: string;
    /**
     * The maximum number of items to return.
     */
    pageSize?: number;
    /**
     * The next_page_token value to use if there are additional results to
     * retrieve for this list request.
     */
    pageToken?: string;
    /**
     * The project and location for which to retrieve instance information, in
     * the format projects/{project_id}/locations/{location}. In Cloud
     * Filestore, locations map to GCP zones, for example **us-west1-b**. To
     * retrieve instance information for all locations, use "-" for the
     * {location} value.
     */
    parent?: string;
  }


export interface Params$Resource$Projects$Locations$Instances$Patch extends
      StandardParameters {
    /**
     * Auth client or API Key for the request
     */
    auth?: string|OAuth2Client|JWT|Compute|UserRefreshClient;

    /**
     * Output only. The resource name of the instance, in the format
     * projects/{project_id}/locations/{location_id}/instances/{instance_id}.
     */
    name?: string;
    /**
     * Mask of fields to update.  At least one path must be supplied in this
     * field.  The elements of the repeated paths field may only include these
     * fields: "description"
     */
    updateMask?: string;

    /**
     * Request body metadata
     */
    requestBody?: Schema$Instance;
  }


export interface Params$Resource$Projects$Locations$Operations$Cancel extends
      StandardParameters {
    /**
     * Auth client or API Key for the request
     */
    auth?: string|OAuth2Client|JWT|Compute|UserRefreshClient;

    /**
     * The name of the operation resource to be cancelled.
     */
    name?: string;

    /**
     * Request body metadata
     */
    requestBody?: Schema$CancelOperationRequest;
  }


export interface Params$Resource$Projects$Locations$Operations$Delete extends
      StandardParameters {
    /**
     * Auth client or API Key for the request
     */
    auth?: string|OAuth2Client|JWT|Compute|UserRefreshClient;

    /**
     * The name of the operation resource to be deleted.
     */
    name?: string;
  }


export interface Params$Resource$Projects$Locations$Operations$Get extends
      StandardParameters {
    /**
     * Auth client or API Key for the request
     */
    auth?: string|OAuth2Client|JWT|Compute|UserRefreshClient;

    /**
     * The name of the operation resource.
     */
    name?: string;
  }


export interface Params$Resource$Projects$Locations$Operations$List extends
      StandardParameters {
    /**
     * Auth client or API Key for the request
     */
    auth?: string|OAuth2Client|JWT|Compute|UserRefreshClient;

    /**
     * The standard list filter.
     */
    filter?: string;
    /**
     * The name of the operation's parent resource.
     */
    name?: string;
    /**
     * The standard list page size.
     */
    pageSize?: number;
    /**
     * The standard list page token.
     */
    pageToken?: string;
  }


/**
     * file.projects.locations.get
     * @desc Gets information about a location.
     * @alias file.projects.locations.get
     * @memberOf! ()
     *
     * @param {object} params Parameters for request
     * @param {string} params.name Resource name for the location.
     * @param {object} [options] Optionally override request options, such as `url`, `method`, and `encoding`.
     * @param {callback} callback The callback that handles the response.
     * @return {object} Request object
     */
get(params?: Params$Resource$Projects$Locations$Get,
        options?: MethodOptions): GaxiosPromise<Schema$Location>;


get(params: Params$Resource$Projects$Locations$Get,
        options: MethodOptions|BodyResponseCallback<Schema$Location>,
        callback: BodyResponseCallback<Schema$Location>): void;


get(params: Params$Resource$Projects$Locations$Get,
        callback: BodyResponseCallback<Schema$Location>): void;


get(paramsOrCallback?: Params$Resource$Projects$Locations$Get|
        BodyResponseCallback<Schema$Location>,
        optionsOrCallback?: MethodOptions|BodyResponseCallback<Schema$Location>,
        callback?: BodyResponseCallback<Schema$Location>):
        void|GaxiosPromise<Schema$Location> {
      let params =
          (paramsOrCallback || {}) as Params$Resource$Projects$Locations$Get;
      let options = (optionsOrCallback || {}) as MethodOptions;

      if (typeof paramsOrCallback === 'function') {
        callback = paramsOrCallback;
        params = {} as Params$Resource$Projects$Locations$Get;
        options = {};
      }

      if (typeof optionsOrCallback === 'function') {
        callback = optionsOrCallback;
        options = {};
      }

      const rootUrl = options.rootUrl || 'https://file.googleapis.com/';
      const parameters = {
        options: Object.assign(
            {
              url: (rootUrl + '/v1beta1/{+name}').replace(/([^:]\/)\/+/g, '$1'),
              method: 'GET'
            },
            options),
        params,
        requiredParams: ['name'],
        pathParams: ['name'],
        context
      };
      if (callback) {
        createAPIRequest<Schema$Location>(parameters, callback);
      } else {
        return createAPIRequest<Schema$Location>(parameters);
      }
    }


/**
     * file.projects.locations.list
     * @desc Lists information about the supported locations for this service.
     * @alias file.projects.locations.list
     * @memberOf! ()
     *
     * @param {object} params Parameters for request
     * @param {string=} params.filter The standard list filter.
     * @param {string} params.name The resource that owns the locations collection, if applicable.
     * @param {integer=} params.pageSize The standard list page size.
     * @param {string=} params.pageToken The standard list page token.
     * @param {object} [options] Optionally override request options, such as `url`, `method`, and `encoding`.
     * @param {callback} callback The callback that handles the response.
     * @return {object} Request object
     */
list(
        params?: Params$Resource$Projects$Locations$List,
        options?: MethodOptions): GaxiosPromise<Schema$ListLocationsResponse>;


list(
        params: Params$Resource$Projects$Locations$List,
        options: MethodOptions|
        BodyResponseCallback<Schema$ListLocationsResponse>,
        callback: BodyResponseCallback<Schema$ListLocationsResponse>): void;


list(
        params: Params$Resource$Projects$Locations$List,
        callback: BodyResponseCallback<Schema$ListLocationsResponse>): void;


list(
        paramsOrCallback?: Params$Resource$Projects$Locations$List|
        BodyResponseCallback<Schema$ListLocationsResponse>,
        optionsOrCallback?: MethodOptions|
        BodyResponseCallback<Schema$ListLocationsResponse>,
        callback?: BodyResponseCallback<Schema$ListLocationsResponse>):
        void|GaxiosPromise<Schema$ListLocationsResponse> {
      let params =
          (paramsOrCallback || {}) as Params$Resource$Projects$Locations$List;
      let options = (optionsOrCallback || {}) as MethodOptions;

      if (typeof paramsOrCallback === 'function') {
        callback = paramsOrCallback;
        params = {} as Params$Resource$Projects$Locations$List;
        options = {};
      }

      if (typeof optionsOrCallback === 'function') {
        callback = optionsOrCallback;
        options = {};
      }

      const rootUrl = options.rootUrl || 'https://file.googleapis.com/';
      const parameters = {
        options: Object.assign(
            {
              url: (rootUrl + '/v1beta1/{+name}/locations')
                       .replace(/([^:]\/)\/+/g, '$1'),
              method: 'GET'
            },
            options),
        params,
        requiredParams: ['name'],
        pathParams: ['name'],
        context
      };
      if (callback) {
        createAPIRequest<Schema$ListLocationsResponse>(parameters, callback);
      } else {
        return createAPIRequest<Schema$ListLocationsResponse>(parameters);
      }
    }


/**
     * file.projects.locations.instances.create
     * @desc Creates an instance.
     * @alias file.projects.locations.instances.create
     * @memberOf! ()
     *
     * @param {object} params Parameters for request
     * @param {string=} params.instanceId The name of the instance to create. The name must be unique for the specified project and location.
     * @param {string} params.parent The instance's project and location, in the format projects/{project_id}/locations/{location}. In Cloud Filestore, locations map to GCP zones, for example **us-west1-b**.
     * @param {().Instance} params.resource Request body data
     * @param {object} [options] Optionally override request options, such as `url`, `method`, and `encoding`.
     * @param {callback} callback The callback that handles the response.
     * @return {object} Request object
     */
create(
        params?: Params$Resource$Projects$Locations$Instances$Create,
        options?: MethodOptions): GaxiosPromise<Schema$Operation>;


create(
        params: Params$Resource$Projects$Locations$Instances$Create,
        options: MethodOptions|BodyResponseCallback<Schema$Operation>,
        callback: BodyResponseCallback<Schema$Operation>): void;


create(
        params: Params$Resource$Projects$Locations$Instances$Create,
        callback: BodyResponseCallback<Schema$Operation>): void;


create(
        paramsOrCallback?: Params$Resource$Projects$Locations$Instances$Create|
        BodyResponseCallback<Schema$Operation>,
        optionsOrCallback?: MethodOptions|
        BodyResponseCallback<Schema$Operation>,
        callback?: BodyResponseCallback<Schema$Operation>):
        void|GaxiosPromise<Schema$Operation> {
      let params = (paramsOrCallback || {}) as
          Params$Resource$Projects$Locations$Instances$Create;
      let options = (optionsOrCallback || {}) as MethodOptions;

      if (typeof paramsOrCallback === 'function') {
        callback = paramsOrCallback;
        params = {} as Params$Resource$Projects$Locations$Instances$Create;
        options = {};
      }

      if (typeof optionsOrCallback === 'function') {
        callback = optionsOrCallback;
        options = {};
      }

      const rootUrl = options.rootUrl || 'https://file.googleapis.com/';
      const parameters = {
        options: Object.assign(
            {
              url: (rootUrl + '/v1beta1/{+parent}/instances')
                       .replace(/([^:]\/)\/+/g, '$1'),
              method: 'POST'
            },
            options),
        params,
        requiredParams: ['parent'],
        pathParams: ['parent'],
        context
      };
      if (callback) {
        createAPIRequest<Schema$Operation>(parameters, callback);
      } else {
        return createAPIRequest<Schema$Operation>(parameters);
      }
    }


/**
     * file.projects.locations.instances.delete
     * @desc Deletes an instance.
     * @alias file.projects.locations.instances.delete
     * @memberOf! ()
     *
     * @param {object} params Parameters for request
     * @param {string} params.name The instance resource name, in the format projects/{project_id}/locations/{location}/instances/{instance_id}
     * @param {object} [options] Optionally override request options, such as `url`, `method`, and `encoding`.
     * @param {callback} callback The callback that handles the response.
     * @return {object} Request object
     */
delete(
        params?: Params$Resource$Projects$Locations$Instances$Delete,
        options?: MethodOptions): GaxiosPromise<Schema$Operation>;


delete(
        params: Params$Resource$Projects$Locations$Instances$Delete,
        options: MethodOptions|BodyResponseCallback<Schema$Operation>,
        callback: BodyResponseCallback<Schema$Operation>): void;


delete(
        params: Params$Resource$Projects$Locations$Instances$Delete,
        callback: BodyResponseCallback<Schema$Operation>): void;


delete(callback: BodyResponseCallback<Schema$Operation>): void;


delete(
        paramsOrCallback?: Params$Resource$Projects$Locations$Instances$Delete|
        BodyResponseCallback<Schema$Operation>,
        optionsOrCallback?: MethodOptions|
        BodyResponseCallback<Schema$Operation>,
        callback?: BodyResponseCallback<Schema$Operation>):
        void|GaxiosPromise<Schema$Operation> {
      let params = (paramsOrCallback || {}) as
          Params$Resource$Projects$Locations$Instances$Delete;
      let options = (optionsOrCallback || {}) as MethodOptions;

      if (typeof paramsOrCallback === 'function') {
        callback = paramsOrCallback;
        params = {} as Params$Resource$Projects$Locations$Instances$Delete;
        options = {};
      }

      if (typeof optionsOrCallback === 'function') {
        callback = optionsOrCallback;
        options = {};
      }

      const rootUrl = options.rootUrl || 'https://file.googleapis.com/';
      const parameters = {
        options: Object.assign(
            {
              url: (rootUrl + '/v1beta1/{+name}').replace(/([^:]\/)\/+/g, '$1'),
              method: 'DELETE'
            },
            options),
        params,
        requiredParams: ['name'],
        pathParams: ['name'],
        context
      };
      if (callback) {
        createAPIRequest<Schema$Operation>(parameters, callback);
      } else {
        return createAPIRequest<Schema$Operation>(parameters);
      }
    }


/**
     * file.projects.locations.instances.get
     * @desc Gets the details of a specific instance.
     * @alias file.projects.locations.instances.get
     * @memberOf! ()
     *
     * @param {object} params Parameters for request
     * @param {string} params.name The instance resource name, in the format projects/{project_id}/locations/{location}/instances/{instance_id}.
     * @param {object} [options] Optionally override request options, such as `url`, `method`, and `encoding`.
     * @param {callback} callback The callback that handles the response.
     * @return {object} Request object
     */
get(params?: Params$Resource$Projects$Locations$Instances$Get,
        options?: MethodOptions): GaxiosPromise<Schema$Instance>;


get(params: Params$Resource$Projects$Locations$Instances$Get,
        options: MethodOptions|BodyResponseCallback<Schema$Instance>,
        callback: BodyResponseCallback<Schema$Instance>): void;


get(params: Params$Resource$Projects$Locations$Instances$Get,
        callback: BodyResponseCallback<Schema$Instance>): void;


get(callback: BodyResponseCallback<Schema$Instance>): void;


get(paramsOrCallback?: Params$Resource$Projects$Locations$Instances$Get|
        BodyResponseCallback<Schema$Instance>,
        optionsOrCallback?: MethodOptions|BodyResponseCallback<Schema$Instance>,
        callback?: BodyResponseCallback<Schema$Instance>):
        void|GaxiosPromise<Schema$Instance> {
      let params = (paramsOrCallback || {}) as
          Params$Resource$Projects$Locations$Instances$Get;
      let options = (optionsOrCallback || {}) as MethodOptions;

      if (typeof paramsOrCallback === 'function') {
        callback = paramsOrCallback;
        params = {} as Params$Resource$Projects$Locations$Instances$Get;
        options = {};
      }

      if (typeof optionsOrCallback === 'function') {
        callback = optionsOrCallback;
        options = {};
      }

      const rootUrl = options.rootUrl || 'https://file.googleapis.com/';
      const parameters = {
        options: Object.assign(
            {
              url: (rootUrl + '/v1beta1/{+name}').replace(/([^:]\/)\/+/g, '$1'),
              method: 'GET'
            },
            options),
        params,
        requiredParams: ['name'],
        pathParams: ['name'],
        context
      };
      if (callback) {
        createAPIRequest<Schema$Instance>(parameters, callback);
      } else {
        return createAPIRequest<Schema$Instance>(parameters);
      }
    }


/**
     * file.projects.locations.instances.list
     * @desc Lists all instances in a project for either a specified location or
     * for all locations.
     * @alias file.projects.locations.instances.list
     * @memberOf! ()
     *
     * @param {object} params Parameters for request
     * @param {string=} params.filter List filter.
     * @param {string=} params.orderBy Sort results. Supported values are "name", "name desc" or "" (unsorted).
     * @param {integer=} params.pageSize The maximum number of items to return.
     * @param {string=} params.pageToken The next_page_token value to use if there are additional results to retrieve for this list request.
     * @param {string} params.parent The project and location for which to retrieve instance information, in the format projects/{project_id}/locations/{location}. In Cloud Filestore, locations map to GCP zones, for example **us-west1-b**. To retrieve instance information for all locations, use "-" for the {location} value.
     * @param {object} [options] Optionally override request options, such as `url`, `method`, and `encoding`.
     * @param {callback} callback The callback that handles the response.
     * @return {object} Request object
     */
list(
        params?: Params$Resource$Projects$Locations$Instances$List,
        options?: MethodOptions): GaxiosPromise<Schema$ListInstancesResponse>;


list(
        params: Params$Resource$Projects$Locations$Instances$List,
        options: MethodOptions|
        BodyResponseCallback<Schema$ListInstancesResponse>,
        callback: BodyResponseCallback<Schema$ListInstancesResponse>): void;


list(
        params: Params$Resource$Projects$Locations$Instances$List,
        callback: BodyResponseCallback<Schema$ListInstancesResponse>): void;


list(callback: BodyResponseCallback<Schema$ListInstancesResponse>): void;


list(
        paramsOrCallback?: Params$Resource$Projects$Locations$Instances$List|
        BodyResponseCallback<Schema$ListInstancesResponse>,
        optionsOrCallback?: MethodOptions|
        BodyResponseCallback<Schema$ListInstancesResponse>,
        callback?: BodyResponseCallback<Schema$ListInstancesResponse>):
        void|GaxiosPromise<Schema$ListInstancesResponse> {
      let params = (paramsOrCallback || {}) as
          Params$Resource$Projects$Locations$Instances$List;
      let options = (optionsOrCallback || {}) as MethodOptions;

      if (typeof paramsOrCallback === 'function') {
        callback = paramsOrCallback;
        params = {} as Params$Resource$Projects$Locations$Instances$List;
        options = {};
      }

      if (typeof optionsOrCallback === 'function') {
        callback = optionsOrCallback;
        options = {};
      }

      const rootUrl = options.rootUrl || 'https://file.googleapis.com/';
      const parameters = {
        options: Object.assign(
            {
              url: (rootUrl + '/v1beta1/{+parent}/instances')
                       .replace(/([^:]\/)\/+/g, '$1'),
              method: 'GET'
            },
            options),
        params,
        requiredParams: ['parent'],
        pathParams: ['parent'],
        context
      };
      if (callback) {
        createAPIRequest<Schema$ListInstancesResponse>(parameters, callback);
      } else {
        return createAPIRequest<Schema$ListInstancesResponse>(parameters);
      }
    }


/**
     * file.projects.locations.instances.patch
     * @desc Updates the settings of a specific instance.
     * @alias file.projects.locations.instances.patch
     * @memberOf! ()
     *
     * @param {object} params Parameters for request
     * @param {string} params.name Output only. The resource name of the instance, in the format projects/{project_id}/locations/{location_id}/instances/{instance_id}.
     * @param {string=} params.updateMask Mask of fields to update.  At least one path must be supplied in this field.  The elements of the repeated paths field may only include these fields: "description"
     * @param {().Instance} params.resource Request body data
     * @param {object} [options] Optionally override request options, such as `url`, `method`, and `encoding`.
     * @param {callback} callback The callback that handles the response.
     * @return {object} Request object
     */
patch(
        params?: Params$Resource$Projects$Locations$Instances$Patch,
        options?: MethodOptions): GaxiosPromise<Schema$Operation>;


patch(
        params: Params$Resource$Projects$Locations$Instances$Patch,
        options: MethodOptions|BodyResponseCallback<Schema$Operation>,
        callback: BodyResponseCallback<Schema$Operation>): void;


patch(
        params: Params$Resource$Projects$Locations$Instances$Patch,
        callback: BodyResponseCallback<Schema$Operation>): void;


patch(callback: BodyResponseCallback<Schema$Operation>): void;


patch(
        paramsOrCallback?: Params$Resource$Projects$Locations$Instances$Patch|
        BodyResponseCallback<Schema$Operation>,
        optionsOrCallback?: MethodOptions|
        BodyResponseCallback<Schema$Operation>,
        callback?: BodyResponseCallback<Schema$Operation>):
        void|GaxiosPromise<Schema$Operation> {
      let params = (paramsOrCallback || {}) as
          Params$Resource$Projects$Locations$Instances$Patch;
      let options = (optionsOrCallback || {}) as MethodOptions;

      if (typeof paramsOrCallback === 'function') {
        callback = paramsOrCallback;
        params = {} as Params$Resource$Projects$Locations$Instances$Patch;
        options = {};
      }

      if (typeof optionsOrCallback === 'function') {
        callback = optionsOrCallback;
        options = {};
      }

      const rootUrl = options.rootUrl || 'https://file.googleapis.com/';
      const parameters = {
        options: Object.assign(
            {
              url: (rootUrl + '/v1beta1/{+name}').replace(/([^:]\/)\/+/g, '$1'),
              method: 'PATCH'
            },
            options),
        params,
        requiredParams: ['name'],
        pathParams: ['name'],
        context
      };
      if (callback) {
        createAPIRequest<Schema$Operation>(parameters, callback);
      } else {
        return createAPIRequest<Schema$Operation>(parameters);
      }
    }


/**
     * file.projects.locations.operations.cancel
     * @desc Starts asynchronous cancellation on a long-running operation.  The
     * server makes a best effort to cancel the operation, but success is not
     * guaranteed.  If the server doesn't support this method, it returns
     * `google.rpc.Code.UNIMPLEMENTED`.  Clients can use Operations.GetOperation
     * or other methods to check whether the cancellation succeeded or whether
     * the operation completed despite cancellation. On successful cancellation,
     * the operation is not deleted; instead, it becomes an operation with an
     * Operation.error value with a google.rpc.Status.code of 1, corresponding
     * to `Code.CANCELLED`.
     * @alias file.projects.locations.operations.cancel
     * @memberOf! ()
     *
     * @param {object} params Parameters for request
     * @param {string} params.name The name of the operation resource to be cancelled.
     * @param {().CancelOperationRequest} params.resource Request body data
     * @param {object} [options] Optionally override request options, such as `url`, `method`, and `encoding`.
     * @param {callback} callback The callback that handles the response.
     * @return {object} Request object
     */
cancel(
        params?: Params$Resource$Projects$Locations$Operations$Cancel,
        options?: MethodOptions): GaxiosPromise<Schema$Empty>;


cancel(
        params: Params$Resource$Projects$Locations$Operations$Cancel,
        options: MethodOptions|BodyResponseCallback<Schema$Empty>,
        callback: BodyResponseCallback<Schema$Empty>): void;


cancel(
        params: Params$Resource$Projects$Locations$Operations$Cancel,
        callback: BodyResponseCallback<Schema$Empty>): void;


cancel(
        paramsOrCallback?: Params$Resource$Projects$Locations$Operations$Cancel|
        BodyResponseCallback<Schema$Empty>,
        optionsOrCallback?: MethodOptions|BodyResponseCallback<Schema$Empty>,
        callback?: BodyResponseCallback<Schema$Empty>):
        void|GaxiosPromise<Schema$Empty> {
      let params = (paramsOrCallback || {}) as
          Params$Resource$Projects$Locations$Operations$Cancel;
      let options = (optionsOrCallback || {}) as MethodOptions;

      if (typeof paramsOrCallback === 'function') {
        callback = paramsOrCallback;
        params = {} as Params$Resource$Projects$Locations$Operations$Cancel;
        options = {};
      }

      if (typeof optionsOrCallback === 'function') {
        callback = optionsOrCallback;
        options = {};
      }

      const rootUrl = options.rootUrl || 'https://file.googleapis.com/';
      const parameters = {
        options: Object.assign(
            {
              url: (rootUrl + '/v1beta1/{+name}:cancel')
                       .replace(/([^:]\/)\/+/g, '$1'),
              method: 'POST'
            },
            options),
        params,
        requiredParams: ['name'],
        pathParams: ['name'],
        context
      };
      if (callback) {
        createAPIRequest<Schema$Empty>(parameters, callback);
      } else {
        return createAPIRequest<Schema$Empty>(parameters);
      }
    }


/**
     * file.projects.locations.operations.delete
     * @desc Deletes a long-running operation. This method indicates that the
     * client is no longer interested in the operation result. It does not
     * cancel the operation. If the server doesn't support this method, it
     * returns `google.rpc.Code.UNIMPLEMENTED`.
     * @alias file.projects.locations.operations.delete
     * @memberOf! ()
     *
     * @param {object} params Parameters for request
     * @param {string} params.name The name of the operation resource to be deleted.
     * @param {object} [options] Optionally override request options, such as `url`, `method`, and `encoding`.
     * @param {callback} callback The callback that handles the response.
     * @return {object} Request object
     */
delete(
        params?: Params$Resource$Projects$Locations$Operations$Delete,
        options?: MethodOptions): GaxiosPromise<Schema$Empty>;


delete(
        params: Params$Resource$Projects$Locations$Operations$Delete,
        options: MethodOptions|BodyResponseCallback<Schema$Empty>,
        callback: BodyResponseCallback<Schema$Empty>): void;


delete(
        params: Params$Resource$Projects$Locations$Operations$Delete,
        callback: BodyResponseCallback<Schema$Empty>): void;


delete(
        paramsOrCallback?: Params$Resource$Projects$Locations$Operations$Delete|
        BodyResponseCallback<Schema$Empty>,
        optionsOrCallback?: MethodOptions|BodyResponseCallback<Schema$Empty>,
        callback?: BodyResponseCallback<Schema$Empty>):
        void|GaxiosPromise<Schema$Empty> {
      let params = (paramsOrCallback || {}) as
          Params$Resource$Projects$Locations$Operations$Delete;
      let options = (optionsOrCallback || {}) as MethodOptions;

      if (typeof paramsOrCallback === 'function') {
        callback = paramsOrCallback;
        params = {} as Params$Resource$Projects$Locations$Operations$Delete;
        options = {};
      }

      if (typeof optionsOrCallback === 'function') {
        callback = optionsOrCallback;
        options = {};
      }

      const rootUrl = options.rootUrl || 'https://file.googleapis.com/';
      const parameters = {
        options: Object.assign(
            {
              url: (rootUrl + '/v1beta1/{+name}').replace(/([^:]\/)\/+/g, '$1'),
              method: 'DELETE'
            },
            options),
        params,
        requiredParams: ['name'],
        pathParams: ['name'],
        context
      };
      if (callback) {
        createAPIRequest<Schema$Empty>(parameters, callback);
      } else {
        return createAPIRequest<Schema$Empty>(parameters);
      }
    }


/**
     * file.projects.locations.operations.get
     * @desc Gets the latest state of a long-running operation.  Clients can use
     * this method to poll the operation result at intervals as recommended by
     * the API service.
     * @alias file.projects.locations.operations.get
     * @memberOf! ()
     *
     * @param {object} params Parameters for request
     * @param {string} params.name The name of the operation resource.
     * @param {object} [options] Optionally override request options, such as `url`, `method`, and `encoding`.
     * @param {callback} callback The callback that handles the response.
     * @return {object} Request object
     */
get(params?: Params$Resource$Projects$Locations$Operations$Get,
        options?: MethodOptions): GaxiosPromise<Schema$Operation>;


get(params: Params$Resource$Projects$Locations$Operations$Get,
        options: MethodOptions|BodyResponseCallback<Schema$Operation>,
        callback: BodyResponseCallback<Schema$Operation>): void;


get(params: Params$Resource$Projects$Locations$Operations$Get,
        callback: BodyResponseCallback<Schema$Operation>): void;


get(paramsOrCallback?: Params$Resource$Projects$Locations$Operations$Get|
        BodyResponseCallback<Schema$Operation>,
        optionsOrCallback?: MethodOptions|
        BodyResponseCallback<Schema$Operation>,
        callback?: BodyResponseCallback<Schema$Operation>):
        void|GaxiosPromise<Schema$Operation> {
      let params = (paramsOrCallback || {}) as
          Params$Resource$Projects$Locations$Operations$Get;
      let options = (optionsOrCallback || {}) as MethodOptions;

      if (typeof paramsOrCallback === 'function') {
        callback = paramsOrCallback;
        params = {} as Params$Resource$Projects$Locations$Operations$Get;
        options = {};
      }

      if (typeof optionsOrCallback === 'function') {
        callback = optionsOrCallback;
        options = {};
      }

      const rootUrl = options.rootUrl || 'https://file.googleapis.com/';
      const parameters = {
        options: Object.assign(
            {
              url: (rootUrl + '/v1beta1/{+name}').replace(/([^:]\/)\/+/g, '$1'),
              method: 'GET'
            },
            options),
        params,
        requiredParams: ['name'],
        pathParams: ['name'],
        context
      };
      if (callback) {
        createAPIRequest<Schema$Operation>(parameters, callback);
      } else {
        return createAPIRequest<Schema$Operation>(parameters);
      }
    }


/**
     * file.projects.locations.operations.list
     * @desc Lists operations that match the specified filter in the request. If
     * the server doesn't support this method, it returns `UNIMPLEMENTED`. NOTE:
     * the `name` binding allows API services to override the binding to use
     * different resource name schemes, such as `users/x/operations`. To
     * override the binding, API services can add a binding such as
     * `"/v1/{name=users/x}/operations"` to their service configuration. For
     * backwards compatibility, the default name includes the operations
     * collection id, however overriding users must ensure the name binding is
     * the parent resource, without the operations collection id.
     * @alias file.projects.locations.operations.list
     * @memberOf! ()
     *
     * @param {object} params Parameters for request
     * @param {string=} params.filter The standard list filter.
     * @param {string} params.name The name of the operation's parent resource.
     * @param {integer=} params.pageSize The standard list page size.
     * @param {string=} params.pageToken The standard list page token.
     * @param {object} [options] Optionally override request options, such as `url`, `method`, and `encoding`.
     * @param {callback} callback The callback that handles the response.
     * @return {object} Request object
     */
list(
        params?: Params$Resource$Projects$Locations$Operations$List,
        options?: MethodOptions): GaxiosPromise<Schema$ListOperationsResponse>;


list(
        params: Params$Resource$Projects$Locations$Operations$List,
        options: MethodOptions|
        BodyResponseCallback<Schema$ListOperationsResponse>,
        callback: BodyResponseCallback<Schema$ListOperationsResponse>): void;


list(
        params: Params$Resource$Projects$Locations$Operations$List,
        callback: BodyResponseCallback<Schema$ListOperationsResponse>): void;


list(
        paramsOrCallback?: Params$Resource$Projects$Locations$Operations$List|
        BodyResponseCallback<Schema$ListOperationsResponse>,
        optionsOrCallback?: MethodOptions|
        BodyResponseCallback<Schema$ListOperationsResponse>,
        callback?: BodyResponseCallback<Schema$ListOperationsResponse>):
        void|GaxiosPromise<Schema$ListOperationsResponse> {
      let params = (paramsOrCallback || {}) as
          Params$Resource$Projects$Locations$Operations$List;
      let options = (optionsOrCallback || {}) as MethodOptions;

      if (typeof paramsOrCallback === 'function') {
        callback = paramsOrCallback;
        params = {} as Params$Resource$Projects$Locations$Operations$List;
        options = {};
      }

      if (typeof optionsOrCallback === 'function') {
        callback = optionsOrCallback;
        options = {};
      }

      const rootUrl = options.rootUrl || 'https://file.googleapis.com/';
      const parameters = {
        options: Object.assign(
            {
              url: (rootUrl + '/v1beta1/{+name}/operations')
                       .replace(/([^:]\/)\/+/g, '$1'),
              method: 'GET'
            },
            options),
        params,
        requiredParams: ['name'],
        pathParams: ['name'],
        context
      };
      if (callback) {
        createAPIRequest<Schema$ListOperationsResponse>(parameters, callback);
      } else {
        return createAPIRequest<Schema$ListOperationsResponse>(parameters);
      }
    }


export default function (props: GraphDashboardProps) {
  const { storeSources } = props;

  return [
    <LineGraph title="Slow Raft Proposals" sources={storeSources}>
      <Axis label="proposals">
        <Metric name="cr.store.requests.slow.raft" title="Slow Raft Proposals" downsampleMax />
      </Axis>
    </LineGraph>,

    <LineGraph title="Slow DistSender RPCs" sources={storeSources}>
      <Axis label="proposals">
        <Metric name="cr.node.requests.slow.distsender" title="Slow DistSender RPCs" downsampleMax />
      </Axis>
    </LineGraph>,

    <LineGraph title="Slow Lease Acquisitions" sources={storeSources}>
      <Axis label="lease acquisitions">
        <Metric name="cr.store.requests.slow.lease" title="Slow Lease Acquisitions" downsampleMax />
      </Axis>
    </LineGraph>,

    <LineGraph title="Slow Latch Acquisitions" sources={storeSources}>
      <Axis label="latch acquisitions">
        <Metric name="cr.store.requests.slow.latch" title="Slow Latch Acquisitions" downsampleMax />
      </Axis>
    </LineGraph>,
  ];
}


(props: {floating?: boolean; collapsed?: boolean}) => ({
      flexShrink: 0,
      padding: props.floating ? 10 : 0,
      borderBottom: props.collapsed ? 'none' : BORDER,
    })


(props: {floating?: boolean; padded?: boolean}) => ({
      backgroundColor: '#f6f7f9',
      border: props.floating ? BORDER : 'none',
      borderBottom: BORDER,
      borderTopLeftRadius: 2,
      borderTopRightRadius: 2,
      justifyContent: 'space-between',
      lineHeight: '27px',
      fontWeight: 500,
      flexShrink: 0,
      padding: props.padded ? '0 10px' : 0,
      '&:not(:first-child)': {
        borderTop: BORDER,
      },
    })


(props: {floating?: boolean; padded?: boolean}) => ({
      backgroundColor: '#fff',
      border: props.floating ? BORDER : 'none',
      borderBottomLeftRadius: 2,
      borderBottomRightRadius: 2,
      borderTop: 'none',
      flexGrow: 1,
      padding: props.padded ? 10 : 0,
      overflow: 'visible',
    })


() => this.setState({collapsed: !this.state.collapsed})


/**
 * A Panel component.
 */
export default class Panel extends React.Component<
  {
    /**
     * Class name to customise styling.
     */
    className?: string;
    /**
     * Whether this panel is floating from the rest of the UI. ie. if it has
     * margin and a border.
     */
    floating?: boolean;
    /**
     * Whether the panel takes up all the space it can. Equivalent to the following CSS:
     *
     *  height: 100%;
     *  width: 100%;
     */
    grow?: boolean;
    /**
     * Heading for this panel. If this is anything other than a string then no
     * padding is applied to the heading.
     */
    heading: React.ReactNode;
    /**
     * Contents of the panel.
     */
    children?: React.ReactNode;
    /**
     * Whether the panel header and body have padding.
     */
    padded?: boolean;
    /**
     * Whether the panel can be collapsed. Defaults to true
     */
    collapsable: boolean;
    /**
     * Initial state for panel if it is collapsable
     */
    collapsed?: boolean;
    /**
     * Heading for this panel. If this is anything other than a string then no
     * padding is applied to the heading.
     */
    accessory?: React.ReactNode;
  },
  {
    collapsed: boolean;
  }
> {
  static defaultProps: {
    floating: boolean;
    grow: boolean;
    collapsable: boolean;
  } = {
    grow: false,
    floating: true,
    collapsable: true,
  };

  static PanelContainer = styled(FlexColumn)(
    (props: {floating?: boolean; collapsed?: boolean}) => ({
      flexShrink: 0,
      padding: props.floating ? 10 : 0,
      borderBottom: props.collapsed ? 'none' : BORDER,
    }),
  );

  static PanelHeader = styled(FlexBox)(
    (props: {floating?: boolean; padded?: boolean}) => ({
      backgroundColor: '#f6f7f9',
      border: props.floating ? BORDER : 'none',
      borderBottom: BORDER,
      borderTopLeftRadius: 2,
      borderTopRightRadius: 2,
      justifyContent: 'space-between',
      lineHeight: '27px',
      fontWeight: 500,
      flexShrink: 0,
      padding: props.padded ? '0 10px' : 0,
      '&:not(:first-child)': {
        borderTop: BORDER,
      },
    }),
  );

  static PanelBody = styled(FlexColumn)(
    (props: {floating?: boolean; padded?: boolean}) => ({
      backgroundColor: '#fff',
      border: props.floating ? BORDER : 'none',
      borderBottomLeftRadius: 2,
      borderBottomRightRadius: 2,
      borderTop: 'none',
      flexGrow: 1,
      padding: props.padded ? 10 : 0,
      overflow: 'visible',
    }),
  );
  state = {
    collapsed: this.props.collapsed == null ? false : this.props.collapsed,
  };

  onClick = () => this.setState({collapsed: !this.state.collapsed});

  render() {
    const {
      padded,
      children,
      className,
      grow,
      floating,
      heading,
      collapsable,
      accessory,
    } = this.props;
    const {collapsed} = this.state;
    return (
      <Panel.PanelContainer
        className={className}
        floating={floating}
        grow={grow}
        collapsed={collapsed}>
        <Panel.PanelHeader
          floating={floating}
          padded={padded || typeof heading === 'string'}
          onClick={this.onClick}>
          <span>
            {collapsable && (
              <Chevron
                color=


render() {
    const {
      padded,
      children,
      className,
      grow,
      floating,
      heading,
      collapsable,
      accessory,
    } = this.props;
    const {collapsed} = this.state;
    return (
      <Panel.PanelContainer
        className={className}
        floating={floating}
        grow={grow}
        collapsed={collapsed}>
        <Panel.PanelHeader
          floating={floating}
          padded={padded || typeof heading === 'string'}


_type => BoolFieldUpdateOperationsInput


_type => NullableStringFieldUpdateOperationsInput


_type => DateTimeFieldUpdateOperationsInput


_type => StudentUpdateOneWithoutInstructor_screeningInput


@TypeGraphQL.InputType({
  isAbstract: true
})
export class Instructor_screeningUpdateWithoutScreenerInput {
  @TypeGraphQL.Field(_type => BoolFieldUpdateOperationsInput, {
    nullable: true
  })
  success?: BoolFieldUpdateOperationsInput | undefined;

  @TypeGraphQL.Field(_type => NullableStringFieldUpdateOperationsInput, {
    nullable: true
  })
  comment?: NullableStringFieldUpdateOperationsInput | undefined;

  @TypeGraphQL.Field(_type => NullableStringFieldUpdateOperationsInput, {
    nullable: true
  })
  knowsCoronaSchoolFrom?: NullableStringFieldUpdateOperationsInput | undefined;

  @TypeGraphQL.Field(_type => DateTimeFieldUpdateOperationsInput, {
    nullable: true
  })
  createdAt?: DateTimeFieldUpdateOperationsInput | undefined;

  @TypeGraphQL.Field(_type => DateTimeFieldUpdateOperationsInput, {
    nullable: true
  })
  updatedAt?: DateTimeFieldUpdateOperationsInput | undefined;

  @TypeGraphQL.Field(_type => StudentUpdateOneWithoutInstructor_screeningInput, {
    nullable: true
  })
  student?: StudentUpdateOneWithoutInstructor_screeningInput | undefined;
}


v => v.version === this.version


key => !/^_/.test(key)


key => typeof this[key] !== 'function' && typeof this[key] !== 'undefined'


(obj: any, key) => ({...obj, [key]: this[key]})


({ version }) => version === this.version


str => this._logOutput(str)


resolve => {
          this._docker.run(
            this.dockerImage + ` account import ${accountPath}${versionData.generateRuntimeArgs(this)}`,
            newArgs,
            output => this._logOutput(output),
            err => this._logError(err),
            () => resolve(),
          );
        }


output => this._logOutput(output)


err => this._logError(err)


code => this._logClose(code)


() => this._logOutput(`${this.validatorAppContainerName()} closed`)


() => this._logOutput(`${this.netstatContainerName()} closed`)


resolve => {
      if(this._instance) {
        const { exitCode } = this._instance;
        if(typeof exitCode === 'number') {
          resolve();
        } else {
          this._instance.on('exit', () => {
            clearTimeout(timeout);
            setTimeout(() => {
              resolve();
            }, 1000);
          });
          this._instance.kill();
          const timeout = setTimeout(() => {
            this._docker.stop(this.id)
              .then(() => {
                setTimeout(() => {
                  resolve();
                }, 1000);
              })
              .catch(err => {
                this._logError(err);
                resolve();
              });
          }, 30000);
        }
      } else {
        resolve();
      }
    }


() => {
            clearTimeout(timeout);
            setTimeout(() => {
              resolve();
            }, 1000);
          }


() => {
              resolve();
            }


() => {
            this._docker.stop(this.id)
              .then(() => {
                setTimeout(() => {
                  resolve();
                }, 1000);
              })
              .catch(err => {
                this._logError(err);
                resolve();
              });
          }


() => {
                setTimeout(() => {
                  resolve();
                }, 1000);
              }


() => {
                  resolve();
                }


err => {
                this._logError(err);
                resolve();
              }


interface FuseVersionDockerImage extends VersionDockerImage {
  passwordPath: string
  imageValidatorApp: string
  imageNetstat: string
}


static versions(client: string, networkType: string): FuseVersionDockerImage[] {
    client = client || Fuse.clients[0];
    let versions: FuseVersionDockerImage[];
    switch(client) {
      case NodeClient.OPEN_ETHEREUM:
        versions = [
          {
            version: '2.0.2',
            clientVersion: '3.2.6',
            image: 'fusenet/spark-node:2.0.2',
            imageValidatorApp: 'fusenet/spark-validator-app:1.0.0',
            imageNetstat: 'fusenet/spark-netstat:1.0.0',
            dataDir: '/root/data',
            walletDir: '/root/keystore',
            configDir: '/root/config',
            passwordPath: '/root/pass.pwd',
            networks: [NetworkType.TESTNET],
            breaking: false,
            generateRuntimeArgs(data: CryptoNodeData): string {
              return ` --no-warp --config=${path.join(this.configDir, Fuse.configName(data))}`;
            },
          },
          {
            version: '2.0.1',
            clientVersion: '3.2.6',
            image: 'fusenet/spark-node:2.0.1_OE',
            imageValidatorApp: '',
            imageNetstat: '',
            dataDir: '/root/data',
            walletDir: '/root/keystore',
            configDir: '/root/config',
            passwordPath: '/root/pass.pwd',
            networks: [NetworkType.TESTNET],
            breaking: false,
            generateRuntimeArgs(data: CryptoNodeData): string {
              return ` --no-warp --config=${path.join(this.configDir, Fuse.configName(data))} --bootnodes ${testnetBootnodes}`;
            },
          },
          {
            version: '2.0.1',
            clientVersion: '3.2.6',
            image: 'fusenet/node:2.0.1',
            imageValidatorApp: '',
            imageNetstat: '',
            dataDir: '/root/data',
            walletDir: '/root/keystore',
            configDir: '/root/config',
            passwordPath: '/root/pass.pwd',
            networks: [NetworkType.MAINNET],
            breaking: false,
            generateRuntimeArgs(data: CryptoNodeData): string {
              return ` --no-warp --config=${path.join(this.configDir, Fuse.configName(data))}`;
            },
          },
          {
            version: '2.5.13',
            clientVersion: '2.5.13',
            image: 'fusenet/node:1.0.0',
            imageValidatorApp: '',
            imageNetstat: '',
            dataDir: '/root/data',
            walletDir: '/root/keystore',
            configDir: '/root/config',
            passwordPath: '/root/pass.pwd',
            networks: [NetworkType.MAINNET],
            breaking: false,
            generateRuntimeArgs(data: CryptoNodeData): string {
              return ` --config=${path.join(this.configDir, Fuse.configName(data))}`;
            },
          },
        ];
        break;
      default:
        versions = [];
    }
    return filterVersionsByNetworkType(networkType, versions) as FuseVersionDockerImage[];
  }


generateRuntimeArgs(data: CryptoNodeData): string {
              return ` --no-warp --config=${path.join(this.configDir, Fuse.configName(data))}`;
            }


generateRuntimeArgs(data: CryptoNodeData): string {
              return ` --no-warp --config=${path.join(this.configDir, Fuse.configName(data))} --bootnodes ${testnetBootnodes}`;
            }


generateRuntimeArgs(data: CryptoNodeData): string {
              return ` --config=${path.join(this.configDir, Fuse.configName(data))}`;
            }


static generateConfig(client: string|Fuse = Fuse.clients[0], network = NetworkType.MAINNET, peerPort = Fuse.defaultPeerPort[NetworkType.MAINNET], rpcPort = Fuse.defaultRPCPort[NetworkType.MAINNET]): string {
    let baseConfig = coreConfig;
    let address = '';
    if(typeof client !== 'string') { // node was passed in rather than client string
      const node = client;
      client = node.client;
      network = node.network;
      peerPort = node.peerPort;
      rpcPort = node.rpcPort;
      address = node.address;
      if(node.role === Role.VALIDATOR)
        baseConfig = coreValidatorConfig;
    }
    switch(client) {
      case NodeClient.OPEN_ETHEREUM:
        return baseConfig
          .replace('{{address}}', address)
          .replace('{{PEER_PORT}}', peerPort.toString(10))
          .replace(/{{RPC_PORT}}/g, rpcPort.toString(10))
          .trim();
      case NodeClient.PARITY:
        return baseConfig
          .replace('{{PEER_PORT}}', peerPort.toString(10))
          .replace(/{{RPC_PORT}}/g, rpcPort.toString(10))
          .trim();
      default:
        return '';
    }
  }


static configName(data: CryptoNodeData): string {
    return 'config.toml';
  }


toObject(): CryptoNodeData {
    let keys = Object
      .keys(this)
      .filter(key => !/^_/.test(key));
    // @ts-ignore
    keys = keys.filter(key => typeof this[key] !== 'function' && typeof this[key] !== 'undefined');
    // @ts-ignore
    const dataObj = keys.reduce((obj: any, key) => ({...obj, [key]: this[key]}), {});
    return dataObj as CryptoNodeData;
  }


async start(): Promise<ChildProcess[]> {
    const fs = this._fs;
    const versions = Fuse.versions(this.client, this.network);
    const versionData = versions.find(({ version }) => version === this.version) || versions[0];
    if(!versionData)
      throw new Error(`Unknown ${this.ticker} version ${this.version}`);
    const {
      dataDir: containerDataDir,
      walletDir: containerWalletDir,
      configDir: containerConfigDir,
      passwordPath: containerPasswordPath,
    } = versionData;
    let args = [
      '-i',
      '--rm',
      '--memory', this.dockerMem.toString(10) + 'MB',
      '--cpus', this.dockerCPUs.toString(10),
      '--name', this.id,
      '--network', this.dockerNetwork,
      '-p', `${this.rpcPort}:${this.rpcPort}`,
      '-p', `${this.peerPort}:${this.peerPort}/tcp`,
      '-p', `${this.peerPort}:${this.peerPort}/udp`,
      '--entrypoint', '/usr/local/bin/parity',
    ];
    const tmpdir = os.tmpdir();
    const dataDir = this.dataDir || path.join(tmpdir, uuid());
    args = [...args, '-v', `${dataDir}:${containerDataDir}`];
    await fs.ensureDir(dataDir);

    const walletDir = this.walletDir || path.join(tmpdir, uuid());
    args = [...args, '-v', `${walletDir}:${containerWalletDir}`];
    await fs.ensureDir(walletDir);

    const configDir = this.configDir || path.join(tmpdir, uuid());
    await fs.ensureDir(configDir);
    const configPath = path.join(configDir, Fuse.configName(this));
    const configExists = await fs.pathExists(configPath);
    if(!configExists)
      await fs.writeFile(configPath, this.generateConfig(), 'utf8');
    args = [...args, '-v', `${configDir}:${containerConfigDir}`];

    await this._docker.pull(this.dockerImage, str => this._logOutput(str));

    if(this.key) {
      const passwordPath = this.passwordPath || path.join(tmpdir, uuid());
      const passwordFileExists = await fs.pathExists(passwordPath);
      if(!passwordFileExists)
        await fs.writeFile(passwordPath, this.keyPass, 'utf8');
      args = [...args, '-v', `${passwordPath}:${containerPasswordPath}`];
      if((await fs.readdir(walletDir)).length === 0) {
        const keyFilePath = path.join(os.tmpdir(), uuid());
        await fs.writeJson(keyFilePath, this.key);
        const accountPath = `/UTC--${new Date().toISOString().replace(/:/g, '-')}--${this.address}.json`;
        const newArgs = [
          ...args,
          '-v', `${keyFilePath}:${accountPath}`,
        ];
        await new Promise<void>(resolve => {
          this._docker.run(
            this.dockerImage + ` account import ${accountPath}${versionData.generateRuntimeArgs(this)}`,
            newArgs,
            output => this._logOutput(output),
            err => this._logError(err),
            () => resolve(),
          );
        });
        await fs.remove(keyFilePath);
      }
    }

    await this._docker.createNetwork(this.dockerNetwork);
    const instance = this._docker.run(
      this.dockerImage + versionData.generateRuntimeArgs(this),
      args,
      output => this._logOutput(output),
      err => this._logError(err),
      code => this._logClose(code),
    );

    if(this.role === Role.VALIDATOR) {
      await new Promise(resolve => setTimeout(resolve, 1000));
      // start validator app
      const validatorAppArgs = [
        '--rm',
        '-i',
        '--memory', '250m',
        '-v', `${path.resolve(walletDir, '..')}:/config`,
        '-e', 'CONFIG_DIR=/config',
        '-e', `RPC=http://${this.id}:${this.rpcPort}`,
        '--network', this.dockerNetwork,
        '--name', this.validatorAppContainerName(),
      ];
      try {
        const validatorAppExists = await this._docker.containerExists(this.validatorAppContainerName());
        if(!validatorAppExists) {
          this._docker.run(
            versionData.imageValidatorApp,
            validatorAppArgs,
            () => {},
            err => this._logError(err),
            () => this._logOutput(`${this.validatorAppContainerName()} closed`),
          );
        }
      } catch(err) {
        this._logError(err);
      }
      // start netstats
      const netstatConfig = `
        [
          {
            "name"              : "netstat_daemon",
            "script"            : "app.js",
            "log_date_format"   : "YYYY-MM-DD HH:mm Z",
            "merge_logs"        : false,
            "watch"             : false,
            "max_restarts"      : 100,
            "exec_interpreter"  : "node",
            "exec_mode"         : "fork_mode",
            "env":
            {
              "NODE_ENV"        : "production",
              "INSTANCE_NAME"   : "",
              "BRIDGE_VERSION"  : "",
              "ROLE"            : "",
              "FUSE_APP_VERSION": "",
              "PARITY_VERSION"  : "",
              "NETSTATS_VERSION": "",
              "CONTACT_DETAILS" : "",
              "WS_SECRET"       : "see http://forum.ethereum.org/discussion/2112/how-to-add-yourself-to-the-stats-dashboard-its-not-automatic",
              "WS_SERVER"       : "https://health.fuse.io",
              "VERBOSITY"       : 2
            }
          }
        ]`;
      const netstatConfigPath = path.join(tmpdir, uuid());
      await fs.writeJson(netstatConfigPath, JSON.parse(netstatConfig), {spaces: 2});
      const netstatArgs = [
        '--rm',
        '-i',
        '--memory', '250m',
        '--name', this.netstatContainerName(),
        '--network', this.dockerNetwork,
        '--user', 'root',
        '-e', `RPC_HOST=${this.id}`,
        '-e', `RPC_PORT=${this.rpcPort}`,
        '-e', `LISTENING_PORT=${this.peerPort}`,
        '-v', `${netstatConfigPath}:/home/ethnetintel/eth-net-intelligence-api/app.json.example`,
      ];
      try {
        const netstatExists = await this._docker.containerExists(this.netstatContainerName());
        if(!netstatExists) {
          this._docker.run(
            `${versionData.imageNetstat} --instance-name ${this.address} --role validator --parity-version ${versionData.version} --fuseapp-version ${this.validatorAppContainerName().split(':')[1]} --netstats-version ${this.netstatContainerName().split(':')[1]}`,
            netstatArgs,
            () => {},
            err => this._logError(err),
            () => this._logOutput(`${this.netstatContainerName()} closed`),
          );
        }
      } catch(err) {
        this._logError(err);
      }
    }

    this._instance = instance;
    this._instances = [
      instance,
    ];
    return this.instances();
  }


validatorAppContainerName(): string {
    return `${this.id}-validator-app`;
  }


netstatContainerName(): string {
    return `${this.id}-netstat`;
  }


async stop(): Promise<void> {
    if(this.role === Role.VALIDATOR) {
      try {
        await this._docker.kill(this.validatorAppContainerName());
      } catch(err) {
        this._logError(err);
      }
      try {
        await this._docker.kill(this.netstatContainerName());
      } catch(err) {
        this._logError(err);
      }
    }
    await new Promise<void>(resolve => {
      if(this._instance) {
        const { exitCode } = this._instance;
        if(typeof exitCode === 'number') {
          resolve();
        } else {
          this._instance.on('exit', () => {
            clearTimeout(timeout);
            setTimeout(() => {
              resolve();
            }, 1000);
          });
          this._instance.kill();
          const timeout = setTimeout(() => {
            this._docker.stop(this.id)
              .then(() => {
                setTimeout(() => {
                  resolve();
                }, 1000);
              })
              .catch(err => {
                this._logError(err);
                resolve();
              });
          }, 30000);
        }
      } else {
        resolve();
      }
    });
  }


generateConfig(): string {
    return Fuse.generateConfig(this);
  }


createAccount(): void {
    const web3 = new Web3();
    const keyPass = this.keyPass || uuid();
    const { address, privateKey } = web3.eth.accounts.create();
    this.keyPass = keyPass;
    this.address = address;
    this.key = web3.eth.accounts.encrypt(privateKey, keyPass);
  }


async rpcGetBalance(): Promise<string> {
    try {
      const web3 = new Web3(`http://localhost:${this.rpcPort}`);
      return await web3.eth.getBalance(this.address);
    } catch(err) {
      return '';
    }
  }


(prototype, property) => {
    const attributes: IObject<any> = {
        enumerable: true,
        configurable: true,
        get() {
            return this.options[property];
        },
    };
    const setter = camelize(`set ${property}`);
    if (prototype[setter]) {
        attributes.set = function(value) {
            this[setter](value);
        };
    } else {
        attributes.set = function(value) {
            this.options[property] = value;
        };
    }
    Object.defineProperty(prototype, property, attributes);
}


() => {
            options.keyContainer = keyContainer;

            this.setKeyController();
        }


() => {
            options.toggleContinueSelect = toggleContinueSelect;

            this.setKeyEvent();
        }


(rect, i) => {
            const {
                left: rectLeft,
                top: rectTop,
                right: rectRight,
                bottom: rectBottom,
            } = rect;
            const isStart
                = rectLeft <= clientX
                && clientX <= rectRight
                && rectTop <= clientY
                && clientY <= rectBottom;
            const rectSize = (rectRight - rectLeft) * (rectBottom - rectTop);
            const testLeft = Math.max(rectLeft, left);
            const testRight = Math.min(rectRight, right);
            const testTop = Math.max(rectTop, top);
            const testBottom = Math.min(rectBottom, bottom);

            if (selectByClick && isStart) {
                passedTargets.push(targets[i]);
                return;
            }
            if (testRight < testLeft || testBottom < testTop) {
                return;
            }
            const rate = Math.round((testRight - testLeft) * (testBottom - testTop) / rectSize * 100);

            if (rate >= hitRate) {
                passedTargets.push(targets[i]);
            }
        }


({ container, direction }) => {
            this.trigger("scroll", {
                container,
                direction,
            });
        }


({ offsetX, offsetY, inputEvent }) => {
            const datas = inputEvent.datas;
            datas.startX -= offsetX;
            datas.startY -= offsetY;
            datas.selectableRects.forEach(rect => {
                rect.top -= offsetY;
                rect.bottom -= offsetY;
                rect.left -= offsetX;
                rect.right -= offsetX;
            });
            this.dragger.scrollBy(offsetX, offsetY, inputEvent.inputEvent, false);

            inputEvent.distX += offsetX;
            inputEvent.distY += offsetY;
            this.check(inputEvent);
        }


rect => {
                rect.top -= offsetY;
                rect.bottom -= offsetY;
                rect.left -= offsetX;
                rect.right -= offsetX;
            }


target => {
            if (isObject(target)) {
                selectableTargets.push(target);
            } else {
                const elements = [].slice.call(document.querySelectorAll(target));

                elements.forEach(el => {
                    selectableTargets.push(el);
                });
            }
        }


el => {
                    selectableTargets.push(el);
                }


index => list[index]


index => prevList[index]


index => afterList[index]


index => afterPrevList[index]


(e: OnDragEvent, clickedTarget?: Element) => {
        const { datas, clientX, clientY, inputEvent } = e;
        const { continueSelect, selectFromInside, selectByClick } = this.options;
        const selectableTargets = this.getSelectableTargets();
        const selectableRects = selectableTargets.map(target => {
            const rect = target.getBoundingClientRect();
            const { left, top, width, height } = rect;

            return {
                left,
                top,
                right: left + width,
                bottom: top + height,
                width,
                height,
            };
        });
        datas.selectableTargets = selectableTargets;
        datas.selectableRects = selectableRects;
        datas.startSelectedTargets = this.selectedTargets;

        const pointTarget = clickedTarget || document.elementFromPoint(clientX, clientY);
        const hitRect = {
            left: clientX,
            top: clientY,
            right: clientX,
            bottom: clientY,
            width: 0,
            height: 0,
        };
        let firstPassedTargets = this.hitTest(
            hitRect, clientX, clientY, selectableTargets, selectableRects).filter(
                target => target === pointTarget || target.contains(pointTarget),
            );

        const hasInsideTargets = firstPassedTargets.length > 0;
        const isPreventSelect = !selectFromInside && hasInsideTargets;

        if (isPreventSelect && !selectByClick) {
            return false;
        }
        if (!continueSelect) {
            this.selectedTargets = [];
        } else {
            firstPassedTargets = this.getSelectedTargets(firstPassedTargets);
        }
        const type = inputEvent.type;
        const isTrusted = type === "mousedown" || type === "touchstart";
        /**
         * When the drag starts, the dragStart event is called.
         * Call the stop () function if you have a specific element or don't want to raise a select
         * @memberof Selecto
         * @event dragStart
         * @param {OnDragStart} - Parameters for the dragStart event
         * @example
         * import Selecto from "selecto";
         *
         * const selecto = new Selecto({
         *   container: document.body,
         *   selectByClick: true,
         *   selectFromInside: false,
         * });
         *
         * selecto.on("dragStart", e => {
         *   if (e.inputEvent.target.tagName === "SPAN") {
         *     e.stop();
         *   }
         * }).on("select", e => {
         *   e.added.forEach(el => {
         *     el.classList.add("selected");
         *   });
         *   e.removed.forEach(el => {
         *     el.classList.remove("selected");
         *   });
         * });
         */
        const result = isTrusted ? this.trigger("dragStart", e) : true;

        if (!result) {
            return false;
        }
        this.select(firstPassedTargets, hitRect, inputEvent, true);
        datas.startX = clientX;
        datas.startY = clientY;
        datas.selectedTargets = firstPassedTargets;
        this.target.style.cssText
            += `left:0px;top:0px;transform: translate(${clientX}px, ${clientY}px)`;

        if (isPreventSelect && selectByClick) {
            this.onDragEnd(e);
            inputEvent.preventDefault();
            return false;
        } else {
            if (type === "touchstart") {
                inputEvent.preventDefault();
            }
            const { scrollOptions } = this.options;
            if (scrollOptions && scrollOptions.container) {
                this.dragScroll.dragStart(e, scrollOptions);
            }
            return true;
        }
    }


target => {
            const rect = target.getBoundingClientRect();
            const { left, top, width, height } = rect;

            return {
                left,
                top,
                right: left + width,
                bottom: top + height,
                width,
                height,
            };
        }


target => target === pointTarget || target.contains(pointTarget)