export interface DiagnosticSettings {
    // Use strict inference rules for list expressions?
    strictListInference: boolean;

    // Use strict inference rules for dictionary expressions?
    strictDictionaryInference: boolean;

    // Use strict type rules for parameters assigned default of None?
    strictParameterNoneValue: boolean;

    // Report diagnostics in typeshed files?
    reportTypeshedErrors: DiagnosticLevel;

    // Report missing imports?
    reportMissingImports: DiagnosticLevel;

    // Report missing type stub files?
    reportMissingTypeStubs: DiagnosticLevel;

    // Report cycles in import graph?
    reportImportCycles: DiagnosticLevel;

    // Report imported symbol that is not accessed?
    reportUnusedImport: DiagnosticLevel;

    // Report private class that is not accessed?
    reportUnusedClass: DiagnosticLevel;

    // Report private function or method that is not accessed?
    reportUnusedFunction: DiagnosticLevel;

    // Report variable that is not accessed?
    reportUnusedVariable: DiagnosticLevel;

    // Report attempts to subscript (index) an Optional type?
    reportOptionalSubscript: DiagnosticLevel;

    // Report attempts to access members on a Optional type?
    reportOptionalMemberAccess: DiagnosticLevel;

    // Report attempts to call a Optional type?
    reportOptionalCall: DiagnosticLevel;

    // Report attempts to use an Optional type as an iterable?
    reportOptionalIterable: DiagnosticLevel;

    // Report attempts to use an Optional type in a "with" statement?
    reportOptionalContextManager: DiagnosticLevel;

    // Report attempts to use an Optional type in a binary or unary operation.
    reportOptionalOperand: DiagnosticLevel;

    // Report untyped function decorators that obscure the function type?
    reportUntypedFunctionDecorator: DiagnosticLevel;

    // Report untyped class decorators that obscure the class type?
    reportUntypedClassDecorator: DiagnosticLevel;

    // Report untyped base class that obscure the class type?
    reportUntypedBaseClass: DiagnosticLevel;

    // Report use of untyped namedtuple factory method?
    reportUntypedNamedTuple: DiagnosticLevel;

    // Report usage of private variables and functions outside of
    // the owning class or module?
    reportPrivateUsage: DiagnosticLevel;

    // Report attempts to redefine variables that are in all-caps.
    reportConstantRedefinition: DiagnosticLevel;

    // Report usage of method override that is incomatlble with
    // the base class method of the same name?
    reportIncompatibleMethodOverride: DiagnosticLevel;

    // Report usage of invalid escape sequences in string literals?
    reportInvalidStringEscapeSequence: DiagnosticLevel;

    // Report usage of unknown input or return parameters?
    reportUnknownParameterType: DiagnosticLevel;

    // Report usage of unknown input or return parameters?
    reportUnknownVariableType: DiagnosticLevel;

    // Report usage of unknown input or return parameters?
    reportUnknownMemberType: DiagnosticLevel;

    // Report usage of function call within default value
    // initialization expression?
    reportCallInDefaultInitializer: DiagnosticLevel;
}


export type DiagnosticLevel = 'none' | 'warning' | 'error';


// Finds the best execution environment for a given file path. The
// specified file path should be absolute.
// If no matching execution environment can be found, a default
// execution environment is used.
findExecEnvironment(filePath: string): ExecutionEnvironment {
        let execEnv = this.executionEnvironments.find(env => {
            let envRoot = ensureTrailingDirectorySeparator(
                normalizePath(combinePaths(this.projectRoot, env.root)));
            return filePath.startsWith(envRoot);
        });

        if (!execEnv) {
            execEnv = new ExecutionEnvironment(this.projectRoot,
                this.defaultPythonVersion, this.defaultPythonPlatform);
        }

        return execEnv;
    }


private _convertBoolean(value: any, fieldName: string, defaultValue: boolean): boolean {
        if (value === undefined) {
            return defaultValue;
        } else if (typeof value === 'boolean') {
            return value ? true : false;
        }

        console.log(`Config "${ fieldName }" entry must be true or false.`);
        return defaultValue;
    }


private _convertDiagnosticLevel(value: any, fieldName: string,
            defaultValue: DiagnosticLevel): DiagnosticLevel {

        if (value === undefined) {
            return defaultValue;
        } else if (typeof value === 'boolean') {
            return value ? 'error' : 'none';
        } else if (typeof value === 'string') {
            if (value === 'error' || value === 'warning' || value === 'none') {
                return value;
            }
        }

        console.log(`Config "${ fieldName }" entry must be true, false, "error", "warning" or "none".`);
        return defaultValue;
    }


private _initExecutionEnvironmentFromJson(envObj: any, index: number,
            console: ConsoleInterface): ExecutionEnvironment | undefined {
        try {
            let newExecEnv = new ExecutionEnvironment(this.projectRoot,
                this.defaultPythonVersion, this.defaultPythonPlatform);

            // Validate the root.
            if (envObj.root && typeof envObj.root === 'string') {
                newExecEnv.root = normalizePath(combinePaths(this.projectRoot, envObj.root));
            } else {
                console.log(`Config executionEnvironments index ${ index }: missing root value.`);
            }

            // Validate the extraPaths.
            if (envObj.extraPaths) {
                if (!Array.isArray(envObj.extraPaths)) {
                    console.log(`Config executionEnvironments index ${ index }: extraPaths field must contain an array.`);
                } else {
                    let pathList = envObj.extraPaths as string[];
                    pathList.forEach((path, pathIndex) => {
                        if (typeof path !== 'string') {
                            console.log(`Config executionEnvironments index ${ index }:` +
                                ` extraPaths field ${ pathIndex } must be a string.`);
                        } else {
                            newExecEnv.extraPaths.push(normalizePath(combinePaths(this.projectRoot, path)));
                        }
                    });
                }
            }

            // Validate the pythonVersion.
            if (envObj.pythonVersion) {
                if (typeof envObj.pythonVersion === 'string') {
                    let version = versionFromString(envObj.pythonVersion);
                    if (version) {
                        newExecEnv.pythonVersion = version;
                    } else {
                        console.log(`Config executionEnvironments index ${ index } contains unsupported pythonVersion.`);
                    }
                } else {
                    console.log(`Config executionEnvironments index ${ index } pythonVersion must be a string.`);
                }
            }

            // Validate the pythonPlatform.
            if (envObj.pythonPlatform) {
                if (typeof envObj.root === 'string') {
                    newExecEnv.pythonPlatform = envObj.pythonPlatform;
                } else {
                    console.log(`Config executionEnvironments index ${ index } pythonPlatform must be a string.`);
                }
            }

            // Validate the venv.
            if (envObj.venv) {
                if (typeof envObj.venv === 'string') {
                    newExecEnv.venv = envObj.venv;
                } else {
                    console.log(`Config executionEnvironments index ${ index } venv must be a string.`);
                }
            }

            return newExecEnv;
        } catch {
            console.log(`Config executionEnvironments index ${ index } is not accessible.`);
        }

        return undefined;
    }


(förval:


(förvalt:


async function wrappedClose() {
    if (inMainOpenFinWindow()) {
      await closeOtherWindows()
    }

    if (close) {
      close()
    }
  }


({
  close,
  minimize,
  maximize,
  popIn,
}) => {
  async function wrappedClose() {
    if (inMainOpenFinWindow()) {
      await closeOtherWindows()
    }

    if (close) {
      close()
    }
  }

  return (
    <ControlsWrapper>
      {minimize && (
        <Control
          accent="aware"
          onClick={minimize}
          data-qa="openfin-chrome__minimize"
        >
          <MinimizeIcon />
        </Control>


export interface Props {
  close?: () => void
  minimize?: () => void
  maximize?: () => void
  popIn?: () => void
}


() => {
  let planner: PlannerPage;
  let c = new support.Constants();

  beforeAll(async () => {
    await support.desktopTestSetup();
    planner = new PlannerPage(browser.baseUrl);
    await planner.openInBrowser();
    await planner.waitUntilUrlContains('typegroup');
  });

  beforeEach(async () => {
    await planner.ready();
    await planner.workItemList.overlay.untilHidden();
  });

  afterEach(async () => {
    await planner.resetState();
  });

  it('should open quickpreview and apply label', async () => {
    await planner.workItemList.clickWorkItem(c.workItemTitle2);
    await planner.quickPreview.addLabel(c.label2);
    expect(await planner.quickPreview.getLabels()).toContain(c.label2);
  });

  it('should open quickpreview and create new label', async () => {
    let workitemname = {'title': 'test labels'};
    await planner.createWorkItem(workitemname);
    await planner.workItemList.clickWorkItem(workitemname.title);
    await planner.quickPreview.createNewLabel(c.newLabel);
    expect(await planner.quickPreview.getLabels()).toContain(c.newLabel);
  });

  it('should open quickpreview and create new label using Enter Key', async () => {
    let workitemname = {'title': 'text labels'};
    let newLabel = 'Enter Key Label';
    await planner.createWorkItem(workitemname);
    await planner.workItemList.clickWorkItem(workitemname.title);
    await planner.quickPreview.createNewLabel(newLabel, true);
    expect(await planner.quickPreview.getLabels()).toContain(newLabel);
  });

  it('should link a workitem', async () => {
    let workitemname = {'title': 'link test'},
      linkType = 'blocks',
      searchWorkItem = '3 - Workitem_Title_4',
      workItemTitle17 = 'Workitem_Title_4';
    await planner.createWorkItem(workitemname);
    await planner.workItemList.clickWorkItem(workitemname.title);
    await planner.quickPreview.addLink(linkType, searchWorkItem, workItemTitle17);
    await planner.quickPreview.linklistItem.untilTextIsPresent(workItemTitle17);
    expect(await planner.quickPreview.getLinkedItems()).toContain(workItemTitle17);
  });

  it('should open quick preview and edit the title', async () => {
    let title = await planner.createUniqueWorkItem();
    await planner.workItemList.clickWorkItem(title);
    await planner.quickPreview.updateTitle(c.editWorkItemTitle1);
    expect(await planner.quickPreview.titleInput.getAttribute('value')).toBe('Title Text "<0>"');
  });

  it('description box should not be open for wis', async () => {
    let workitemname = {'title': 'quickpreview test'};
    await planner.createWorkItem(workitemname);
    await planner.workItemList.clickWorkItem(workitemname.title);
    await planner.quickPreview.openDescriptionBox();
    expect(await planner.quickPreview.isSaveButtonDisplayed()).toBeTruthy();

    // Open another WI(Note: the description box is still in edit mode)
    await planner.workItemList.clickWorkItem(c.workItemTitle2);
    // The description box should not be in edit mode
    expect(await planner.quickPreview.isSaveButtonDisplayed()).toBeFalsy();
  });

  it('should close assignee dropdown when clicked outside', async () => {
    await planner.workItemList.clickWorkItem(c.workItemTitle2);
    await planner.quickPreview.assigneeDropdown.clickWhenReady();
    expect(await planner.quickPreview.assigneeDropdownMenu.getAttribute('className')).toContain('show');
    await planner.quickPreview.titleInput.clickWhenReady();
    expect(await planner.quickPreview.assigneeDropdownMenu.getAttribute('className')).not.toContain('show');
  });
}


async () => {
    await support.desktopTestSetup();
    planner = new PlannerPage(browser.baseUrl);
    await planner.openInBrowser();
    await planner.waitUntilUrlContains('typegroup');
  }


async () => {
    await planner.ready();
    await planner.workItemList.overlay.untilHidden();
  }


async () => {
    await planner.resetState();
  }


async () => {
    await planner.workItemList.clickWorkItem(c.workItemTitle2);
    await planner.quickPreview.addLabel(c.label2);
    expect(await planner.quickPreview.getLabels()).toContain(c.label2);
  }


async () => {
    let workitemname = {'title': 'test labels'};
    await planner.createWorkItem(workitemname);
    await planner.workItemList.clickWorkItem(workitemname.title);
    await planner.quickPreview.createNewLabel(c.newLabel);
    expect(await planner.quickPreview.getLabels()).toContain(c.newLabel);
  }


async () => {
    let workitemname = {'title': 'text labels'};
    let newLabel = 'Enter Key Label';
    await planner.createWorkItem(workitemname);
    await planner.workItemList.clickWorkItem(workitemname.title);
    await planner.quickPreview.createNewLabel(newLabel, true);
    expect(await planner.quickPreview.getLabels()).toContain(newLabel);
  }


async () => {
    let workitemname = {'title': 'link test'},
      linkType = 'blocks',
      searchWorkItem = '3 - Workitem_Title_4',
      workItemTitle17 = 'Workitem_Title_4';
    await planner.createWorkItem(workitemname);
    await planner.workItemList.clickWorkItem(workitemname.title);
    await planner.quickPreview.addLink(linkType, searchWorkItem, workItemTitle17);
    await planner.quickPreview.linklistItem.untilTextIsPresent(workItemTitle17);
    expect(await planner.quickPreview.getLinkedItems()).toContain(workItemTitle17);
  }


async () => {
    let title = await planner.createUniqueWorkItem();
    await planner.workItemList.clickWorkItem(title);
    await planner.quickPreview.updateTitle(c.editWorkItemTitle1);
    expect(await planner.quickPreview.titleInput.getAttribute('value')).toBe('Title Text "<0>"');
  }


async () => {
    let workitemname = {'title': 'quickpreview test'};
    await planner.createWorkItem(workitemname);
    await planner.workItemList.clickWorkItem(workitemname.title);
    await planner.quickPreview.openDescriptionBox();
    expect(await planner.quickPreview.isSaveButtonDisplayed()).toBeTruthy();

    // Open another WI(Note: the description box is still in edit mode)
    await planner.workItemList.clickWorkItem(c.workItemTitle2);
    // The description box should not be in edit mode
    expect(await planner.quickPreview.isSaveButtonDisplayed()).toBeFalsy();
  }


async () => {
    await planner.workItemList.clickWorkItem(c.workItemTitle2);
    await planner.quickPreview.assigneeDropdown.clickWhenReady();
    expect(await planner.quickPreview.assigneeDropdownMenu.getAttribute('className')).toContain('show');
    await planner.quickPreview.titleInput.clickWhenReady();
    expect(await planner.quickPreview.assigneeDropdownMenu.getAttribute('className')).not.toContain('show');
  }


/**
 * ## Example Usage
 *
 * ```typescript
 * import * as pulumi from "@pulumi/pulumi";
 * import * as snowflake from "@pulumi/snowflake";
 *
 * const current = pulumi.output(snowflake.getExternalFunctions({
 *     database: "MYDB",
 *     schema: "MYSCHEMA",
 * }));
 * ```
 */
export function getExternalFunctions(args: GetExternalFunctionsArgs, opts?: pulumi.InvokeOptions): Promise<GetExternalFunctionsResult> {
    if (!opts) {
        opts = {}
    }

    if (!opts.version) {
        opts.version = utilities.getVersion();
    }
    return pulumi.runtime.invoke("snowflake:index/getExternalFunctions:getExternalFunctions", {
        "database": args.database,
        "schema": args.schema,
    }, opts);
}


export function getExternalFunctionsOutput(args: GetExternalFunctionsOutputArgs, opts?: pulumi.InvokeOptions): pulumi.Output<GetExternalFunctionsResult> {
    return pulumi.output(args).apply(a => getExternalFunctions(a, opts))
}


a => getExternalFunctions(a, opts)


/**
 * A collection of arguments for invoking getExternalFunctions.
 */
export interface GetExternalFunctionsArgs {
    /**
     * The database from which to return the schemas from.
     */
    database: string;
    /**
     * The schema from which to return the external functions from.
     */
    schema: string;
}


/**
 * A collection of values returned by getExternalFunctions.
 */
export interface GetExternalFunctionsResult {
    /**
     * The database from which to return the schemas from.
     */
    readonly database: string;
    /**
     * The external functions in the schema
     */
    readonly externalFunctions: outputs.GetExternalFunctionsExternalFunction[];
    /**
     * The provider-assigned unique ID for this managed resource.
     */
    readonly id: string;
    /**
     * The schema from which to return the external functions from.
     */
    readonly schema: string;
}


/**
 * A collection of arguments for invoking getExternalFunctions.
 */
export interface GetExternalFunctionsOutputArgs {
    /**
     * The database from which to return the schemas from.
     */
    database: pulumi.Input<string>;
    /**
     * The schema from which to return the external functions from.
     */
    schema: pulumi.Input<string>;
}


() => {
    this.performHighlight(this.highlight);
  }


(element: HTMLGuxListItemElement, index: number) => {
      if (index !== this.selectedIndex) {
        element.setAttribute('tabindex', '-1');
      } else {
        element.setAttribute('tabindex', '0');
        element.focus();
        setTimeout(() => {
          this.value = element.value;
        });
      }
    }


() => {
          this.value = element.value;
        }


(element: HTMLGuxTextHighlightElement) => {
      element.highlight = value;
    }


@Component({
  styleUrl: 'gux-list.less',
  tag: 'gux-list'
})
export class GuxList {
  @Element()
  root: HTMLElement;

  /**
   * The current selection in the list.
   */
  @Prop()
  value: any;

  /**
   * The highlight value
   */
  @Prop()
  highlight: string;

  /**
   * The currently selected index.
   */
  @State()
  selectedIndex: number = -1;

  /**
   * Triggered when the list's selection is changed.
   */
  @Event()
  changed: EventEmitter<any>;

  /**
   * Using a mutation observer because component loading order is not quite right.
   * In this case we are attempting to update a component that updates a component.
   * What ends up happening is that there is no hook to make sure all components have loaded.
   * When the DOM load order gets fixed we should be able to remove this logic.
   * https://github.com/ionic-team/stencil/issues/1261
   */
  private observer: MutationObserver = new MutationObserver(() => {
    this.performHighlight(this.highlight);
  });

  emitChanged(value: any) {
    this.changed.emit(value);
  }

  @Listen('selected')
  itemSelected(ev: CustomEvent<any>) {
    if (!ev.detail) {
      return;
    }

    this.value = ev.detail;
  }

  @Watch('value')
  valueHandler(newValue) {
    this.emitChanged(newValue);
  }

  /*
   * Sets focus to the fist item in the list.
   */
  @Method()
  async setFocusOnFirstItem(): Promise<void> {
    this.selectedIndex = 0;
    this.updateTabIndexes();
  }

  /*
   * Sets focus to the last item in the list.
   */
  @Method()
  async setFocusOnLastItem(): Promise<void> {
    const filteredList = this.root.querySelectorAll(validChildren);
    this.selectedIndex = filteredList.length - 1;
    this.updateTabIndexes();
  }

  /**
   * Returns whether the last item in the list is selected.
   */
  @Method()
  async isLastItemSelected(): Promise<boolean> {
    const filteredList = this.root.querySelectorAll(validChildren);
    return this.selectedIndex === filteredList.length - 1;
  }

  /**
   * Returns whether the first item in the list is selected.
   */
  @Method()
  async isFirstItemSelected(): Promise<boolean> {
    return this.selectedIndex <= 0;
  }

  componentWillLoad(): void {
    trackComponent(this.root);
  }

  /**
   * Once the component is loaded
   */
  componentDidLoad() {
    this.performHighlight(this.highlight);
    this.observer.observe(this.root, { childList: true, subtree: true });
  }

  disconnectedCallback(): void {
    this.observer.disconnect();
  }

  render() {
    this.performHighlight(this.highlight);
    this.updateTabIndexes();
    return (
      <div
        class="gux-list-items-container"
        role="list"
        tabindex={0}
        onKeyDown={e => this.onKeyDown(e)}
      >
        <slot />
      </div>
    );
  }

  private onKeyDown(event: KeyboardEvent): void {
    const validKeys = [KeyCode.Up, KeyCode.Down, KeyCode.End, KeyCode.Home];
    const key = event.keyCode;
    if (validKeys.indexOf(key) === -1) {
      return;
    }

    const filteredList = this.root.querySelectorAll(validChildren);

    let newIndex = -1;
    switch (key) {
      case KeyCode.Up:
        if (this.selectedIndex) {
          newIndex = this.selectedIndex - 1;
          event.stopPropagation();
        }
        break;
      case KeyCode.Home:
        if (this.selectedIndex) {
          newIndex = 0;
        }
        break;
      case KeyCode.Down:
        if (this.selectedIndex !== filteredList.length - 1) {
          newIndex = this.selectedIndex + 1;
          event.stopPropagation();
        }
        break;
      case KeyCode.End:
        if (this.selectedIndex !== filteredList.length - 1) {
          newIndex = filteredList.length - 1;
        }
        break;
    }

    if (newIndex !== -1) {
      this.selectedIndex = newIndex;
    }
  }

  private updateTabIndexes(): void {
    const children = this.root.querySelectorAll(validChildren);

    if (!children || this.selectedIndex === -1) {
      return;
    }

    children.forEach((element: HTMLGuxListItemElement, index: number) => {
      if (index !== this.selectedIndex) {
        element.setAttribute('tabindex', '-1');
      } else {
        element.setAttribute('tabindex', '0');
        element.focus();
        setTimeout(() => {
          this.value = element.value;
        });
      }
    });
  }

  private performHighlight(value: string): void {
    const items = this.root.querySelectorAll('gux-text-highlight');

    if (!items) {
      return;
    }

    items.forEach((element: HTMLGuxTextHighlightElement) => {
      element.highlight = value;
    });
  }
}


emitChanged(value: any) {
    this.changed.emit(value);
  }


@Listen('selected')
  itemSelected(ev: CustomEvent<any>) {
    if (!ev.detail) {
      return;
    }

    this.value = ev.detail;
  }


@Watch('value')
  valueHandler(newValue) {
    this.emitChanged(newValue);
  }


/*
   * Sets focus to the fist item in the list.
   */
@Method()
  async setFocusOnFirstItem(): Promise<void> {
    this.selectedIndex = 0;
    this.updateTabIndexes();
  }


/*
   * Sets focus to the last item in the list.
   */
@Method()
  async setFocusOnLastItem(): Promise<void> {
    const filteredList = this.root.querySelectorAll(validChildren);
    this.selectedIndex = filteredList.length - 1;
    this.updateTabIndexes();
  }


/**
   * Returns whether the last item in the list is selected.
   */
@Method()
  async isLastItemSelected(): Promise<boolean> {
    const filteredList = this.root.querySelectorAll(validChildren);
    return this.selectedIndex === filteredList.length - 1;
  }


/**
   * Returns whether the first item in the list is selected.
   */
@Method()
  async isFirstItemSelected(): Promise<boolean> {
    return this.selectedIndex <= 0;
  }


componentWillLoad(): void {
    trackComponent(this.root);
  }


/**
   * Once the component is loaded
   */
componentDidLoad() {
    this.performHighlight(this.highlight);
    this.observer.observe(this.root, { childList: true, subtree: true });
  }


disconnectedCallback(): void {
    this.observer.disconnect();
  }


render() {
    this.performHighlight(this.highlight);
    this.updateTabIndexes();
    return (
      <div
        class="gux-list-items-container"
        role="list"
        tabindex={0}
        onKeyDown={e => this.onKeyDown(e)}
      >
        <slot />
      </div>
    );
  }


private onKeyDown(event: KeyboardEvent): void {
    const validKeys = [KeyCode.Up, KeyCode.Down, KeyCode.End, KeyCode.Home];
    const key = event.keyCode;
    if (validKeys.indexOf(key) === -1) {
      return;
    }

    const filteredList = this.root.querySelectorAll(validChildren);

    let newIndex = -1;
    switch (key) {
      case KeyCode.Up:
        if (this.selectedIndex) {
          newIndex = this.selectedIndex - 1;
          event.stopPropagation();
        }
        break;
      case KeyCode.Home:
        if (this.selectedIndex) {
          newIndex = 0;
        }
        break;
      case KeyCode.Down:
        if (this.selectedIndex !== filteredList.length - 1) {
          newIndex = this.selectedIndex + 1;
          event.stopPropagation();
        }
        break;
      case KeyCode.End:
        if (this.selectedIndex !== filteredList.length - 1) {
          newIndex = filteredList.length - 1;
        }
        break;
    }

    if (newIndex !== -1) {
      this.selectedIndex = newIndex;
    }
  }


private updateTabIndexes(): void {
    const children = this.root.querySelectorAll(validChildren);

    if (!children || this.selectedIndex === -1) {
      return;
    }

    children.forEach((element: HTMLGuxListItemElement, index: number) => {
      if (index !== this.selectedIndex) {
        element.setAttribute('tabindex', '-1');
      } else {
        element.setAttribute('tabindex', '0');
        element.focus();
        setTimeout(() => {
          this.value = element.value;
        });
      }
    });
  }


private performHighlight(value: string): void {
    const items = this.root.querySelectorAll('gux-text-highlight');

    if (!items) {
      return;
    }

    items.forEach((element: HTMLGuxTextHighlightElement) => {
      element.highlight = value;
    });
  }


() => {
  it('should return the "displayName" property first, if it exists', () => {
    TestComp.displayName = 'ReturningTheDisplayName';

    expect(getCompName(TestComp)).to.equal('ReturningTheDisplayName');
  });

  it('should return the "name" property, if displayName does not exist', () => {
    expect(getCompName(DefaultNameComp)).to.equal('DefaultNameComp');
  });

  it('should return an empty string if the component has no name', () => {
    expect(getCompName(() =>
why has my creator cursed me with a nameless existence
)).to.equal('');
  });
}


() => {
    TestComp.displayName = 'ReturningTheDisplayName';

    expect(getCompName(TestComp)).to.equal('ReturningTheDisplayName');
  }


() => {
    expect(getCompName(DefaultNameComp)).to.equal('DefaultNameComp');
  }


() => {
    expect(getCompName(() =>
why has my creator cursed me with a nameless existence
)).to.equal('');
  }


() => <h1>why


(response) => {
                    return response.body.result.response;
                }


export class GetBatchDetailsHandler implements ApiRequestHandler<CourseBatchDetailsRequest, Batch> {
    public readonly GET_BATCH_DETAILS_ENDPOINT = '/batch/read/';

    constructor(private apiService: ApiService,
                private courseServiceConfig: CourseServiceConfig) {
    }

    public handle(request: CourseBatchDetailsRequest): Observable<Batch> {
        const apiRequest: Request = new Request.Builder()
            .withType(HttpRequestType.GET)
            .withPath(this.courseServiceConfig.apiPath + this.GET_BATCH_DETAILS_ENDPOINT + request.batchId)
            .withBearerToken(true)
            .withUserToken(true)
            .build();

        return this.apiService.fetch<{ result: { response: Batch } }>(apiRequest)
            .pipe(
                map((response) => {
                    return response.body.result.response;
                })
            );
    }
}


public handle(request: CourseBatchDetailsRequest): Observable<Batch> {
        const apiRequest: Request = new Request.Builder()
            .withType(HttpRequestType.GET)
            .withPath(this.courseServiceConfig.apiPath + this.GET_BATCH_DETAILS_ENDPOINT + request.batchId)
            .withBearerToken(true)
            .withUserToken(true)
            .build();

        return this.apiService.fetch<{ result: { response: Batch } }>(apiRequest)
            .pipe(
                map((response) => {
                    return response.body.result.response;
                })
            );
    }


t => {
  const sandbox: any = vm.createContext({});

  const { get, getA }: any = vm.runInContext(
    `
var a = 1;

function get(){
  var a = 2; // function have it's own scope
  return a;
}

function getA(){
  return a;
}

module.exports = {get: get, getA: getA};
  `,
    sandbox
  );
  t.deepEqual(get(), 2);
  t.deepEqual(getA(), 1);
}


t => {
  const sandbox: any = vm.createContext({});

  const { get, getA }: any = vm.runInContext(
    `
var a = 1;

function get(){
  let a = 2; // function have it's own scope
  return a;
}

function getA(){
  return a;
}

module.exports = {get: get, getA: getA};
  `,
    sandbox
  );
  t.deepEqual(get(), 2);
  t.deepEqual(getA(), 1);
}


t => {
  const sandbox: any = vm.createContext({});

  const { get, getA }: any = vm.runInContext(
    `
var a = 1;

function get(){
  const a = 2; // function have it's own scope
  return a;
}

function getA(){
  return a;
}

module.exports = {get: get, getA: getA};
  `,
    sandbox
  );
  t.deepEqual(get(), 2);
  t.deepEqual(getA(), 1);
}


t => {
  const sandbox: any = vm.createContext({});

  const { get, getA }: any = vm.runInContext(
    `
var a = 1;

function get(){
  var a = 2;
  var a = 3;
  return a;
}

function getA(){
  return a;
}

module.exports = {get: get, getA: getA};
  `,
    sandbox
  );
  t.deepEqual(get(), 3);
  t.deepEqual(getA(), 1);
}


t => {
  const sandbox: any = vm.createContext({});

  const { get }: any = vm.runInContext(
    `
var a = 1;

function get(){
  let a = 2;
  var a = 3;
  return a;
}

module.exports = {get: get};
  `,
    sandbox
  );
  t.throws(function() {
    get();
  }, ErrDuplicateDeclard("a").message);
}


t => {
  const sandbox: any = vm.createContext({});

  const { get }: any = vm.runInContext(
    `
var a = 1;

function get(){
  const a = 2;
  var a = 3;
  return a;
}

module.exports = {get: get};
  `,
    sandbox
  );
  t.throws(function() {
    get();
  }, ErrDuplicateDeclard("a").message);
}


() => {
  describe('Unit tests', () => {
    const scope = nock('https://hybris.example.com');

    it('Gravity points down!', () => {
      expect(true).to.equal(true);
    });

    describe('Validation', () => {
      it('Validation should return error if \'id\' is missing', async () => {
        const { errorOutput } = await validateGetProductById({});
        expect(errorOutput).to.be.ok.and.to.haveOwnProperty('message').that.equals('Parameter \'id\' is missing.');
      });

      it('Validation should return a valid Input if all the inputs are ok', async () => {
        const { errorOutput, parameters } = await validateGetProductById({ id: '269524' });
        expect(errorOutput).to.not.exist;
        expect(parameters).to.be.ok.and.to.haveOwnProperty('id').that.equals('269524');
      });
    });

    describe('Service', () => {
      it('Function should return something', async () => {
        scope.get('/rest/v2/electronics/products/280916')
          .query({ lang: 'en', fields: 'FULL' })
          .reply(200, product280916);
        const { response } = await getProductById(validInput);
        const { statusCode } = response;
        expect(response).not.to.be.null;
        expect(response).not.to.be.undefined;
        expect(statusCode).to.be.equals(200);
      });

      it('Response should be 400 if validation brings errorOutput', async () => {
        const { response } = await getProductById(invalidInput);
        expect(response.error).to.be.deep.equal({
          cause: {
            message: 'missing-property',
          },
          message: 'Parameter \'id\' is missing.',
          name: 'MissingPropertyError',
        });
      });

      it('Response should be 404 if no product exists', async () => {
        scope.get('/rest/v2/electronics/products/280916').query({ fields: 'FULL', lang: 'en' })
          .reply(400, productNotFoundExample);
        const { response } = await getProductById(validInput);
        expect(response.error).to.be.deep.equal({
          cause: {
            message: 'UnknownIdentifierError',
          },
          message: 'Product with code \'21345\' not found!',
          name: 'CommerceServiceResourceNotFoundError',
        });
      });

      it('Response should have status code 200 and the should be equal to the mock', async () => {
        scope.get('/rest/v2/electronics/products/280916').query({ fields: 'FULL', lang: 'en' })
          .reply(200, product280916);
        const { response } = await getProductById(validInput);
        const { statusCode } = response;
        expect(statusCode).to.be.equals(200);
        expect(response.body).to.shallowDeepEqual(expectedProductMock);
      });

      it('Response should contain a body with a product name in german if the product exists with the id', async () => {
        scope.get('/rest/v2/electronics/products/280916').query({ fields: 'FULL', lang: 'de' })
          .reply(200, product280916de);
        const { response } = await getProductById(validInputGerman);
        expect(response.body).to.shallowDeepEqual(expectedProductMockDe);
      });

      it('Response should contain assets coming from external source', async () => {
        scope.get('/rest/v2/electronics/products/280916').query({ fields: 'FULL', lang: 'de' })
          .reply(200, product280916de);
        validInputGerman.settings.CT_ASSETS_HOST = 'https://external.asset.com';
        const { response } = await getProductById(validInputGerman);
        expect(response.body).to.shallowDeepEqual(expectedProductMockExternalAssets);
      });
    });
  });
}


() => {
    const scope = nock('https://hybris.example.com');

    it('Gravity points down!', () => {
      expect(true).to.equal(true);
    });

    describe('Validation', () => {
      it('Validation should return error if \'id\' is missing', async () => {
        const { errorOutput } = await validateGetProductById({});
        expect(errorOutput).to.be.ok.and.to.haveOwnProperty('message').that.equals('Parameter \'id\' is missing.');
      });

      it('Validation should return a valid Input if all the inputs are ok', async () => {
        const { errorOutput, parameters } = await validateGetProductById({ id: '269524' });
        expect(errorOutput).to.not.exist;
        expect(parameters).to.be.ok.and.to.haveOwnProperty('id').that.equals('269524');
      });
    });

    describe('Service', () => {
      it('Function should return something', async () => {
        scope.get('/rest/v2/electronics/products/280916')
          .query({ lang: 'en', fields: 'FULL' })
          .reply(200, product280916);
        const { response } = await getProductById(validInput);
        const { statusCode } = response;
        expect(response).not.to.be.null;
        expect(response).not.to.be.undefined;
        expect(statusCode).to.be.equals(200);
      });

      it('Response should be 400 if validation brings errorOutput', async () => {
        const { response } = await getProductById(invalidInput);
        expect(response.error).to.be.deep.equal({
          cause: {
            message: 'missing-property',
          },
          message: 'Parameter \'id\' is missing.',
          name: 'MissingPropertyError',
        });
      });

      it('Response should be 404 if no product exists', async () => {
        scope.get('/rest/v2/electronics/products/280916').query({ fields: 'FULL', lang: 'en' })
          .reply(400, productNotFoundExample);
        const { response } = await getProductById(validInput);
        expect(response.error).to.be.deep.equal({
          cause: {
            message: 'UnknownIdentifierError',
          },
          message: 'Product with code \'21345\' not found!',
          name: 'CommerceServiceResourceNotFoundError',
        });
      });

      it('Response should have status code 200 and the should be equal to the mock', async () => {
        scope.get('/rest/v2/electronics/products/280916').query({ fields: 'FULL', lang: 'en' })
          .reply(200, product280916);
        const { response } = await getProductById(validInput);
        const { statusCode } = response;
        expect(statusCode).to.be.equals(200);
        expect(response.body).to.shallowDeepEqual(expectedProductMock);
      });

      it('Response should contain a body with a product name in german if the product exists with the id', async () => {
        scope.get('/rest/v2/electronics/products/280916').query({ fields: 'FULL', lang: 'de' })
          .reply(200, product280916de);
        const { response } = await getProductById(validInputGerman);
        expect(response.body).to.shallowDeepEqual(expectedProductMockDe);
      });

      it('Response should contain assets coming from external source', async () => {
        scope.get('/rest/v2/electronics/products/280916').query({ fields: 'FULL', lang: 'de' })
          .reply(200, product280916de);
        validInputGerman.settings.CT_ASSETS_HOST = 'https://external.asset.com';
        const { response } = await getProductById(validInputGerman);
        expect(response.body).to.shallowDeepEqual(expectedProductMockExternalAssets);
      });
    });
  }


() => {
      expect(true).to.equal(true);
    }


() => {
      it('Validation should return error if \'id\' is missing', async () => {
        const { errorOutput } = await validateGetProductById({});
        expect(errorOutput).to.be.ok.and.to.haveOwnProperty('message').that.equals('Parameter \'id\' is missing.');
      });

      it('Validation should return a valid Input if all the inputs are ok', async () => {
        const { errorOutput, parameters } = await validateGetProductById({ id: '269524' });
        expect(errorOutput).to.not.exist;
        expect(parameters).to.be.ok.and.to.haveOwnProperty('id').that.equals('269524');
      });
    }


async () => {
        const { errorOutput } = await validateGetProductById({});
        expect(errorOutput).to.be.ok.and.to.haveOwnProperty('message').that.equals('Parameter \'id\' is missing.');
      }


async () => {
        const { errorOutput, parameters } = await validateGetProductById({ id: '269524' });
        expect(errorOutput).to.not.exist;
        expect(parameters).to.be.ok.and.to.haveOwnProperty('id').that.equals('269524');
      }


() => {
      it('Function should return something', async () => {
        scope.get('/rest/v2/electronics/products/280916')
          .query({ lang: 'en', fields: 'FULL' })
          .reply(200, product280916);
        const { response } = await getProductById(validInput);
        const { statusCode } = response;
        expect(response).not.to.be.null;
        expect(response).not.to.be.undefined;
        expect(statusCode).to.be.equals(200);
      });

      it('Response should be 400 if validation brings errorOutput', async () => {
        const { response } = await getProductById(invalidInput);
        expect(response.error).to.be.deep.equal({
          cause: {
            message: 'missing-property',
          },
          message: 'Parameter \'id\' is missing.',
          name: 'MissingPropertyError',
        });
      });

      it('Response should be 404 if no product exists', async () => {
        scope.get('/rest/v2/electronics/products/280916').query({ fields: 'FULL', lang: 'en' })
          .reply(400, productNotFoundExample);
        const { response } = await getProductById(validInput);
        expect(response.error).to.be.deep.equal({
          cause: {
            message: 'UnknownIdentifierError',
          },
          message: 'Product with code \'21345\' not found!',
          name: 'CommerceServiceResourceNotFoundError',
        });
      });

      it('Response should have status code 200 and the should be equal to the mock', async () => {
        scope.get('/rest/v2/electronics/products/280916').query({ fields: 'FULL', lang: 'en' })
          .reply(200, product280916);
        const { response } = await getProductById(validInput);
        const { statusCode } = response;
        expect(statusCode).to.be.equals(200);
        expect(response.body).to.shallowDeepEqual(expectedProductMock);
      });

      it('Response should contain a body with a product name in german if the product exists with the id', async () => {
        scope.get('/rest/v2/electronics/products/280916').query({ fields: 'FULL', lang: 'de' })
          .reply(200, product280916de);
        const { response } = await getProductById(validInputGerman);
        expect(response.body).to.shallowDeepEqual(expectedProductMockDe);
      });

      it('Response should contain assets coming from external source', async () => {
        scope.get('/rest/v2/electronics/products/280916').query({ fields: 'FULL', lang: 'de' })
          .reply(200, product280916de);
        validInputGerman.settings.CT_ASSETS_HOST = 'https://external.asset.com';
        const { response } = await getProductById(validInputGerman);
        expect(response.body).to.shallowDeepEqual(expectedProductMockExternalAssets);
      });
    }


async () => {
        scope.get('/rest/v2/electronics/products/280916')
          .query({ lang: 'en', fields: 'FULL' })
          .reply(200, product280916);
        const { response } = await getProductById(validInput);
        const { statusCode } = response;
        expect(response).not.to.be.null;
        expect(response).not.to.be.undefined;
        expect(statusCode).to.be.equals(200);
      }


async () => {
        const { response } = await getProductById(invalidInput);
        expect(response.error).to.be.deep.equal({
          cause: {
            message: 'missing-property',
          },
          message: 'Parameter \'id\' is missing.',
          name: 'MissingPropertyError',
        });
      }


async () => {
        scope.get('/rest/v2/electronics/products/280916').query({ fields: 'FULL', lang: 'en' })
          .reply(400, productNotFoundExample);
        const { response } = await getProductById(validInput);
        expect(response.error).to.be.deep.equal({
          cause: {
            message: 'UnknownIdentifierError',
          },
          message: 'Product with code \'21345\' not found!',
          name: 'CommerceServiceResourceNotFoundError',
        });
      }


async () => {
        scope.get('/rest/v2/electronics/products/280916').query({ fields: 'FULL', lang: 'en' })
          .reply(200, product280916);
        const { response } = await getProductById(validInput);
        const { statusCode } = response;
        expect(statusCode).to.be.equals(200);
        expect(response.body).to.shallowDeepEqual(expectedProductMock);
      }


async () => {
        scope.get('/rest/v2/electronics/products/280916').query({ fields: 'FULL', lang: 'de' })
          .reply(200, product280916de);
        const { response } = await getProductById(validInputGerman);
        expect(response.body).to.shallowDeepEqual(expectedProductMockDe);
      }


async () => {
        scope.get('/rest/v2/electronics/products/280916').query({ fields: 'FULL', lang: 'de' })
          .reply(200, product280916de);
        validInputGerman.settings.CT_ASSETS_HOST = 'https://external.asset.com';
        const { response } = await getProductById(validInputGerman);
        expect(response.body).to.shallowDeepEqual(expectedProductMockExternalAssets);
      }


(ref) => ref.scanGroupType === 'deep-scan'


(a, b) => a + b.nodes.length


@injectable()
export class Runner {
    constructor(
        @inject(ScanMetadataConfig) private readonly scanMetadataConfig: ScanMetadataConfig,
        @inject(OnDemandPageScanRunResultProvider) private readonly onDemandPageScanRunResultProvider: OnDemandPageScanRunResultProvider,
        @inject(WebsiteScanResultProvider) protected readonly websiteScanResultProvider: WebsiteScanResultProvider,
        @inject(PageScanProcessor) private readonly pageScanProcessor: PageScanProcessor,
        @inject(ReportWriter) protected readonly reportWriter: ReportWriter,
        @inject(ReportGenerator) private readonly reportGenerator: ReportGenerator,
        @inject(CombinedScanResultProcessor) private readonly combinedScanResultProcessor: CombinedScanResultProcessor,
        @inject(ScanNotificationProcessor) protected readonly scanNotificationProcessor: ScanNotificationProcessor,
        @inject(ScanRunnerTelemetryManager) private readonly telemetryManager: ScanRunnerTelemetryManager,
        @inject(ServiceConfiguration) protected readonly serviceConfig: ServiceConfiguration,
        @inject(GlobalLogger) private readonly logger: GlobalLogger,
    ) {}

    public async run(): Promise<void> {
        const scanMetadata = this.scanMetadataConfig.getConfig();
        // decode URL back from docker parameter encoding
        scanMetadata.url = decodeURI(scanMetadata.url);

        this.logger.setCommonProperties({ scanId: scanMetadata.id, url: scanMetadata.url });
        this.logger.logInfo('Starting page scan task.');

        const pageScanResult = await this.updateScanRunState(scanMetadata.id);
        if (pageScanResult === undefined) {
            return;
        }

        this.telemetryManager.trackScanStarted(scanMetadata.id);
        try {
            const axeScanResults = await this.pageScanProcessor.scan(scanMetadata, pageScanResult);
            await this.processScanResult(axeScanResults, pageScanResult);
        } catch (error) {
            const errorMessage = System.serializeError(error);
            this.setRunResult(pageScanResult, 'failed', errorMessage);

            this.logger.logError(`The scanner failed to scan a page.`, { error: errorMessage });
            this.telemetryManager.trackScanTaskFailed();
        } finally {
            this.telemetryManager.trackScanCompleted();
        }

        const websiteScanResult = await this.updateScanResult(scanMetadata, pageScanResult);
        await this.scanNotificationProcessor.sendScanCompletionNotification(scanMetadata, pageScanResult, websiteScanResult);

        this.logger.logInfo('Page scan task completed.');
    }

    private async updateScanRunState(scanId: string): Promise<OnDemandPageScanResult> {
        this.logger.logInfo(`Updating page scan run state to 'running'.`);
        const partialPageScanResult: Partial<OnDemandPageScanResult> = {
            id: scanId,
            run: {
                state: 'running',
                timestamp: new Date().toJSON(),
                error: null,
            },
            scanResult: null,
            reports: null,
        };
        const response = await this.onDemandPageScanRunResultProvider.tryUpdateScanRun(partialPageScanResult);
        if (!response.succeeded) {
            this.logger.logWarn(
                `Update page scan run state to 'running' failed due to merge conflict with other process. Exiting page scan task.`,
            );

            return undefined;
        }

        return response.result;
    }

    private async processScanResult(axeScanResults: AxeScanResults, pageScanResult: OnDemandPageScanResult): Promise<AxeScanResults> {
        if (_.isNil(axeScanResults.error)) {
            this.setRunResult(pageScanResult, 'completed');
            pageScanResult.scanResult = this.getScanStatus(axeScanResults);
            pageScanResult.reports = await this.generateScanReports(axeScanResults);
            if (axeScanResults.scannedUrl !== undefined) {
                pageScanResult.scannedUrl = axeScanResults.scannedUrl;
            }

            await this.combinedScanResultProcessor.generateCombinedScanResults(axeScanResults, pageScanResult);
        } else {
            this.setRunResult(pageScanResult, 'failed', axeScanResults.error);

            this.logger.logError('Browser has failed to scan a page.', { error: JSON.stringify(axeScanResults.error) });
            this.telemetryManager.trackBrowserScanFailed();
        }

        pageScanResult.run.pageTitle = axeScanResults.pageTitle;
        pageScanResult.run.pageResponseCode = axeScanResults.pageResponseCode;

        return axeScanResults.error ? undefined : axeScanResults;
    }

    private async updateScanResult(
        scanMetadata: ScanMetadata,
        pageScanResult: Partial<OnDemandPageScanResult>,
    ): Promise<WebsiteScanResult> {
        await this.onDemandPageScanRunResultProvider.updateScanRun(pageScanResult);

        const websiteScanRef = pageScanResult.websiteScanRefs?.find((ref) => ref.scanGroupType === 'deep-scan');
        if (websiteScanRef) {
            const scanConfig = await this.serviceConfig.getConfigValue('scanConfig');
            const runState =
                pageScanResult.run.state === 'completed' || pageScanResult.run.retryCount >= scanConfig.maxFailedScanRetryCount
                    ? pageScanResult.run.state
                    : undefined;

            const updatedWebsiteScanResult: Partial<WebsiteScanResult> = {
                id: websiteScanRef.id,
                pageScans: [
                    {
                        scanId: scanMetadata.id,
                        url: scanMetadata.url,
                        scanState: pageScanResult.scanResult?.state,
                        runState,
                        timestamp: new Date().toJSON(),
                    },
                ],
            };

            return this.websiteScanResultProvider.mergeOrCreate(scanMetadata.id, updatedWebsiteScanResult, true);
        }

        return undefined;
    }

    private async generateScanReports(axeResults: AxeScanResults): Promise<OnDemandPageScanReport[]> {
        this.logger.logInfo(`Generating reports from scan results.`);
        const reports = this.reportGenerator.generateReports(axeResults);

        return this.reportWriter.writeBatch(reports);
    }

    private setRunResult(pageScanResult: OnDemandPageScanResult, state: OnDemandPageScanRunState, error?: string | ScanError): void {
        pageScanResult.run = {
            ...pageScanResult.run,
            state,
            timestamp: new Date().toJSON(),
            error: _.isString(error) ? error.substring(0, 2048) : error,
        };
    }

    private getScanStatus(axeResults: AxeScanResults): OnDemandScanResult {
        if (axeResults?.results?.violations !== undefined && axeResults.results.violations.length > 0) {
            return {
                state: 'fail',
                issueCount: axeResults.results.violations.reduce((a, b) => a + b.nodes.length, 0),
            };
        } else {
            return {
                state: 'pass',
            };
        }
    }
}


public async run(): Promise<void> {
        const scanMetadata = this.scanMetadataConfig.getConfig();
        // decode URL back from docker parameter encoding
        scanMetadata.url = decodeURI(scanMetadata.url);

        this.logger.setCommonProperties({ scanId: scanMetadata.id, url: scanMetadata.url });
        this.logger.logInfo('Starting page scan task.');

        const pageScanResult = await this.updateScanRunState(scanMetadata.id);
        if (pageScanResult === undefined) {
            return;
        }

        this.telemetryManager.trackScanStarted(scanMetadata.id);
        try {
            const axeScanResults = await this.pageScanProcessor.scan(scanMetadata, pageScanResult);
            await this.processScanResult(axeScanResults, pageScanResult);
        } catch (error) {
            const errorMessage = System.serializeError(error);
            this.setRunResult(pageScanResult, 'failed', errorMessage);

            this.logger.logError(`The scanner failed to scan a page.`, { error: errorMessage });
            this.telemetryManager.trackScanTaskFailed();
        } finally {
            this.telemetryManager.trackScanCompleted();
        }

        const websiteScanResult = await this.updateScanResult(scanMetadata, pageScanResult);
        await this.scanNotificationProcessor.sendScanCompletionNotification(scanMetadata, pageScanResult, websiteScanResult);

        this.logger.logInfo('Page scan task completed.');
    }


private async updateScanRunState(scanId: string): Promise<OnDemandPageScanResult> {
        this.logger.logInfo(`Updating page scan run state to 'running'.`);
        const partialPageScanResult: Partial<OnDemandPageScanResult> = {
            id: scanId,
            run: {
                state: 'running',
                timestamp: new Date().toJSON(),
                error: null,
            },
            scanResult: null,
            reports: null,
        };
        const response = await this.onDemandPageScanRunResultProvider.tryUpdateScanRun(partialPageScanResult);
        if (!response.succeeded) {
            this.logger.logWarn(
                `Update page scan run state to 'running' failed due to merge conflict with other process. Exiting page scan task.`,
            );

            return undefined;
        }

        return response.result;
    }


private async processScanResult(axeScanResults: AxeScanResults, pageScanResult: OnDemandPageScanResult): Promise<AxeScanResults> {
        if (_.isNil(axeScanResults.error)) {
            this.setRunResult(pageScanResult, 'completed');
            pageScanResult.scanResult = this.getScanStatus(axeScanResults);
            pageScanResult.reports = await this.generateScanReports(axeScanResults);
            if (axeScanResults.scannedUrl !== undefined) {
                pageScanResult.scannedUrl = axeScanResults.scannedUrl;
            }

            await this.combinedScanResultProcessor.generateCombinedScanResults(axeScanResults, pageScanResult);
        } else {
            this.setRunResult(pageScanResult, 'failed', axeScanResults.error);

            this.logger.logError('Browser has failed to scan a page.', { error: JSON.stringify(axeScanResults.error) });
            this.telemetryManager.trackBrowserScanFailed();
        }

        pageScanResult.run.pageTitle = axeScanResults.pageTitle;
        pageScanResult.run.pageResponseCode = axeScanResults.pageResponseCode;

        return axeScanResults.error ? undefined : axeScanResults;
    }


private async updateScanResult(
        scanMetadata: ScanMetadata,
        pageScanResult: Partial<OnDemandPageScanResult>,
    ): Promise<WebsiteScanResult> {
        await this.onDemandPageScanRunResultProvider.updateScanRun(pageScanResult);

        const websiteScanRef = pageScanResult.websiteScanRefs?.find((ref) => ref.scanGroupType === 'deep-scan');
        if (websiteScanRef) {
            const scanConfig = await this.serviceConfig.getConfigValue('scanConfig');
            const runState =
                pageScanResult.run.state === 'completed' || pageScanResult.run.retryCount >= scanConfig.maxFailedScanRetryCount
                    ? pageScanResult.run.state
                    : undefined;

            const updatedWebsiteScanResult: Partial<WebsiteScanResult> = {
                id: websiteScanRef.id,
                pageScans: [
                    {
                        scanId: scanMetadata.id,
                        url: scanMetadata.url,
                        scanState: pageScanResult.scanResult?.state,
                        runState,
                        timestamp: new Date().toJSON(),
                    },
                ],
            };

            return this.websiteScanResultProvider.mergeOrCreate(scanMetadata.id, updatedWebsiteScanResult, true);
        }

        return undefined;
    }


private async generateScanReports(axeResults: AxeScanResults): Promise<OnDemandPageScanReport[]> {
        this.logger.logInfo(`Generating reports from scan results.`);
        const reports = this.reportGenerator.generateReports(axeResults);

        return this.reportWriter.writeBatch(reports);
    }


private setRunResult(pageScanResult: OnDemandPageScanResult, state: OnDemandPageScanRunState, error?: string | ScanError): void {
        pageScanResult.run = {
            ...pageScanResult.run,
            state,
            timestamp: new Date().toJSON(),
            error: _.isString(error) ? error.substring(0, 2048) : error,
        };
    }


private getScanStatus(axeResults: AxeScanResults): OnDemandScanResult {
        if (axeResults?.results?.violations !== undefined && axeResults.results.violations.length > 0) {
            return {
                state: 'fail',
                issueCount: axeResults.results.violations.reduce((a, b) => a + b.nodes.length, 0),
            };
        } else {
            return {
                state: 'pass',
            };
        }
    }


// now
interface LoDashStatic {
        /**
         * Gets the number of milliseconds that have elapsed since the Unix epoch (1 January 1970 00:00:00 UTC).
         *
         * @return The number of milliseconds.
         */
        now(): number;
    }


interface LoDashImplicitWrapper<TValue> {
        /**
         * @see _.now
         */
        now(): number;
    }


interface LoDashExplicitWrapper<TValue> {
        /**
         * @see _.now
         */
        now(): LoDashExplicitWrapper<number>;
    }


export function nonMaxSuppressionV3(args: {
  inputs: NonMaxSuppressionV3Inputs,
  backend: WebGPUBackend,
  attrs: NonMaxSuppressionV3Attrs
}) {
  console.warn(
      'tf.nonMaxSuppression() in webgpu locks the UI thread. ' +
      'Call tf.nonMaxSuppressionAsync() instead');

  const {inputs, backend, attrs} = args;
  const {boxes, scores} = inputs;
  const {maxOutputSize, iouThreshold, scoreThreshold} = attrs;

  const boxesVals = backend.readSync(boxes.dataId) as TypedArray;
  const scoresVals = backend.readSync(scores.dataId) as TypedArray;

  const {selectedIndices} = kernel_impls.nonMaxSuppressionV3Impl(
      boxesVals, scoresVals, maxOutputSize, iouThreshold, scoreThreshold);

  return backend.makeTensorInfo(
      [selectedIndices.length], 'int32', new Int32Array(selectedIndices));
}


export declare abstract class Wordlist {
    readonly locale: string;
    constructor(locale: string);
    abstract getWord(index: number): string;
    abstract getWordIndex(word: string): number;
    split(mnemonic: string): Array<string>;
    join(words: Array<string>): string;
    static check(wordlist: Wordlist): string;
    static register(lang: Wordlist, name?: string): void;
}


abstract getWord(index: number): string;


abstract getWordIndex(word: string): number;


split(mnemonic: string): Array<string>;


join(words: Array<string>): string;


static check(wordlist: Wordlist): string;


static register(lang: Wordlist, name?: string): void;


export function resetPlatform() {
  if (win && typeof win.close === 'function') {
    win.close();
  }

  hostRefs.clear();
  styles.clear();
  plt.$flags$ = 0;
  Object.keys(Context).forEach(key => delete Context[key]);

  if (plt.$orgLocNodes$ != null) {
    plt.$orgLocNodes$.clear();
    plt.$orgLocNodes$ = undefined;
  }

  win.location.href = plt.$resourcesUrl$ = `http://testing.stenciljs.com/`;

  resetTaskQueue();
  stopAutoApplyChanges();

  cstrs.clear();
}


export function stopAutoApplyChanges() {
  isAutoApplyingChanges = false;
  if (autoApplyTimer) {
    clearTimeout(autoApplyTimer);
    autoApplyTimer = undefined;
  }
}


export async function startAutoApplyChanges() {
  isAutoApplyingChanges = true;
  flushAll().then(() => {
    if (isAutoApplyingChanges) {
      autoApplyTimer = setTimeout(() => {
        startAutoApplyChanges();
      }, 100);
    }
  });
}


export function registerContext(context: any) {
  if (context) {
    Object.assign(Context, context);
  }
}


(h) => h()


(h) => requestAnimationFrame(h)


(el, eventName, listener, opts) => el.addEventListener(eventName, listener, opts)


(el, eventName, listener, opts) => el.removeEventListener(eventName, listener, opts)


key => delete Context[key]


() => {
    if (isAutoApplyingChanges) {
      autoApplyTimer = setTimeout(() => {
        startAutoApplyChanges();
      }, 100);
    }
  }


() => {
        startAutoApplyChanges();
      }


(elm: d.RuntimeRef) => {
  return hostRefs.get(elm);
}


(lazyInstance: any, hostRef: d.HostRef) => {
  if (lazyInstance == null || lazyInstance.constructor == null) {
    throw new Error(`Invalid component constructor`);
  }

  if (hostRef == null) {
    console.warn('Use newSpecPage() to instanciate component instances.')
    const Cstr = lazyInstance.constructor as d.ComponentTestingConstructor;
    const tagName = (Cstr.COMPILER_META && Cstr.COMPILER_META.tagName) ? Cstr.COMPILER_META.tagName : 'div';
    const elm = document.createElement(tagName);
    registerHost(elm, {$flags$: 0, $tagName$: tagName});
    hostRef = getHostRef(elm);
  }

  hostRef.$lazyInstance$ = lazyInstance;
  return hostRefs.set(lazyInstance, hostRef);
}


(elm: d.HostElement, cmpMeta: d.ComponentRuntimeMeta) => {
  const hostRef: d.HostRef = {
    $flags$: 0,
    $hostElement$: elm,
    $cmpMeta$: cmpMeta,
    $instanceValues$: new Map(),
    $renderCount$: 0
  };
  hostRef.$onInstancePromise$ = new Promise(r => hostRef.$onInstanceResolve$ = r);
  hostRef.$onReadyPromise$ = new Promise(r => hostRef.$onReadyResolve$ = r);
  elm['s-p'] = [];
  elm['s-rc'] = [];
  hostRefs.set(elm, hostRef);
}


r => hostRef.$onInstanceResolve$ = r


r => hostRef.$onReadyResolve$ = r


(Cstrs: d.ComponentTestingConstructor[]) => {
  Cstrs.forEach(Cstr => {
    cstrs.set(Cstr.COMPILER_META.tagName, Cstr);
  });
}


Cstr => {
    cstrs.set(Cstr.COMPILER_META.tagName, Cstr);
  }


(elm: any, memberName: string) => {
  if (elm != null) {
    if (memberName in elm) {
      return true;
    }
    const nodeName = elm.nodeName;
    if (nodeName) {
      const cstr = cstrs.get(nodeName.toLowerCase());
      if (cstr != null && cstr.COMPILER_META != null && cstr.COMPILER_META.properties != null) {
        return cstr.COMPILER_META.properties.some(p => p.name === memberName);
      }
    }
  }
  return false;
}


p => p.name === memberName


(_: string) => { return; }


({ variables: v, props: p, theme: { siteVariables } }): ICSSInJSStyle => ({
    ':focus-visible': {
      backgroundColor: v.focusBackgroundColor,

      ':hover': {
        backgroundColor: v.hoverBackgroundColor,
      },
    },

    ':hover': {
      backgroundColor: v.hoverBackgroundColor,

      // TODO: consider creating dedicated method for border styles on hover
      ...getBorderFocusStyles({ siteVariables })[':focus-visible'],
    },
  })


async (t) => {
  port = await getPort()
  srv = await start({
    port,
  })
  const client = connect({ port })
  await client.updateSchema({
    languages: ['en', 'de'],
    types: {
      sport: {
        prefix: 'sp',
        fields: {
          title: {
            type: 'text',
            search: { type: ['TEXT-LANGUAGE-SUG'] },
          },
        },
      },
      category: {
        prefix: 'ca',
        fields: {
          title: {
            type: 'text',
            search: { type: ['TEXT-LANGUAGE-SUG'] },
          },
        },
      },
      match: {
        prefix: 'ma',
        fields: {
          title: {
            type: 'text',
            search: { type: ['TEXT-LANGUAGE-SUG'] },
          },
          published: {
            type: 'boolean',
            search: { type: ['TAG'] },
          },
        },
      },
    },
  })
  await client.destroy()
}


async (t) => {
  const client = connect({ port })
  await client.delete('root')
  await client.destroy()
  await srv.destroy()
  await t.connectionsAreEmpty()
}


async (t) => {
  const client = connect({ port }, { loglevel: 'info' })

  await client.set({
    $language: 'en',
    $id: 'sp1',
    title: 'sport nice',
    children: [
      {
        $id: 'ca1',
        title: 'Highlights',
        name: 'highlights',
        children: [
          {
            $id: 'ma1',
            title: 'match 1',
            published: true,
          },
          {
            $id: 'ma2',
            title: 'match 2',
            published: true,
          },
          {
            $id: 'ma3',
            title: 'match 3',
            published: false,
          },
        ],
      },
    ],
  })

  t.deepEqualIgnoreOrder(
    await client.get({
      $id: 'sp1',
      $language: 'en',
      component: {
        $value: 'Highlights',
      },
      children: {
        type: true,
        title: true,
        id: true,
        $list: {
          $find: {
            $traverse: 'children',
            $find: {
              $traverse: 'children',
              $filter: [
                {
                  $field: 'published',
                  $operator: '=',
                  $value: true,
                },
              ],
            },
            $filter: [
              {
                $value: 'category',
                $field: 'type',
                $operator: '=',
              },
              {
                $value: 'highlights',
                $field: 'name',
                $operator: '=',
              },
            ],
          },
          $limit: 3,
        },
        date: true,
        video: true,
      },
      title: {
        $value: 'Bla bla',
      },
    }),
    {
      component: 'Highlights',
      title: 'Bla bla',
      children: [
        { id: 'ma1', type: 'match', title: 'match 1' },
        { id: 'ma2', type: 'match', title: 'match 2' },
      ],
    }
  )
  t.pass()

  await client.delete('root')
  await client.destroy()
}


() => {
  it('should return the are you still working page page', async () => {
    const res = await request(app).get(PageUrls.STILL_WORKING);
    expect(res.type).toStrictEqual('text/html');
    expect(res.status).toStrictEqual(200);
  });
}


async () => {
    const res = await request(app).get(PageUrls.STILL_WORKING);
    expect(res.type).toStrictEqual('text/html');
    expect(res.status).toStrictEqual(200);
  }


() => {
  test('should return the employment details - job title page when Still working for them button is selected', async () => {
    await request(app)
      .post(PageUrls.STILL_WORKING)
      .send({ isStillWorking: StillWorking.WORKING })
      .expect(res => {
        expect(res.status).toStrictEqual(302);
        expect(res.header['location']).toStrictEqual(PageUrls.JOB_TITLE);
      });
  });
  test('should return the employment details - job title page when notice period button is selected', async () => {
    await request(app)
      .post(PageUrls.STILL_WORKING)
      .send({ isStillWorking: StillWorking.NOTICE })
      .expect(res => {
        expect(res.status).toStrictEqual(302);
        expect(res.header['location']).toStrictEqual(PageUrls.JOB_TITLE);
      });
  });
  test('should return the employment details - job title page when no longer working button is selected', async () => {
    await request(app)
      .post(PageUrls.STILL_WORKING)
      .send({ isStillWorking: StillWorking.NOTICE })
      .expect(res => {
        expect(res.status).toStrictEqual(302);
        expect(res.header['location']).toStrictEqual(PageUrls.JOB_TITLE);
      });
  });
}


async () => {
    await request(app)
      .post(PageUrls.STILL_WORKING)
      .send({ isStillWorking: StillWorking.WORKING })
      .expect(res => {
        expect(res.status).toStrictEqual(302);
        expect(res.header['location']).toStrictEqual(PageUrls.JOB_TITLE);
      });
  }


res => {
        expect(res.status).toStrictEqual(302);
        expect(res.header['location']).toStrictEqual(PageUrls.JOB_TITLE);
      }


async () => {
    await request(app)
      .post(PageUrls.STILL_WORKING)
      .send({ isStillWorking: StillWorking.NOTICE })
      .expect(res => {
        expect(res.status).toStrictEqual(302);
        expect(res.header['location']).toStrictEqual(PageUrls.JOB_TITLE);
      });
  }


// 每个entity的信息
export interface TableListItem {
  key: number;
  robotId?: number;
  entityName?: string;
  slotDataType?: string;
  disabled?: boolean;
}


// 分页
export interface TableListPagination {
  total: number;
  pageSize: number;
  current: number;
}


// 从后端返回的值，进行组装。
export interface TableListData {
  list: TableListItem[];
  pagination: Partial<TableListPagination>;
}


// 查询功能。
export interface TableListParams {
  entityName: string;
  robotId: number;
  pageSize: number;
  currentPage: number;
}


@NgModule({
  imports: [
    BrowserAnimationsModule,
    FormsModule,
    ReactiveFormsModule,
    HttpClientModule,
    ComponentsModule,
    QuicklinkModule,
    RouterModule.forRoot([],{
      preloadingStrategy: QuicklinkStrategy
    }),
    AppRoutingModule,
    NgbModule,
    ToastrModule.forRoot()
  ],
  declarations: [
    AppComponent,
    AdminLayoutComponent

  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }


c => c.tag.has(PLAYER_SENSOR_TAG)


(args: CollisionCallbackArgs): void => {
    const {
      other: { entity: other },
    } = args
    if (other.hasComponent('PickupTarget')) {
      pickupTarget.add(other)
    }
  }


() => {
    if (input.buttonIsPressed(Button.A)) {
        lightfollower.readLightfollower(DigitalPin.C17)
    } else {
        lightfollower.readLightfollower(DigitalPin.C19)
    }
}


() => {
  it('returns the correct action type', () => {
    expect(messengerConnect().type).toEqual(MESSENGER_CONNECT);
  });
}


() => {
    expect(messengerConnect().type).toEqual(MESSENGER_CONNECT);
  }


() => {
  it('returns the correct action type', () => {
    expect(messengerConnected().type).toEqual(MESSENGER_CONNECTED);
  });
}


() => {
    expect(messengerConnected().type).toEqual(MESSENGER_CONNECTED);
  }


() => {
  it('returns the correct action type', () => {
    expect(messengerDisconnect().type).toEqual(MESSENGER_DISCONNECT);
  });
}


() => {
    expect(messengerDisconnect().type).toEqual(MESSENGER_DISCONNECT);
  }


() => {
  it('returns the correct action type', () => {
    expect(messengerDisconnected().type).toEqual(MESSENGER_DISCONNECTED);
  });
}


() => {
    expect(messengerDisconnected().type).toEqual(MESSENGER_DISCONNECTED);
  }


() => {
  it('returns the correct action type', () => {
    expect(messengerGetOnline([alex]).type).toEqual(MESSENGER_GET_ONLINE);
  });

  it('returns the correct online', () => {
    expect(messengerGetOnline([alex]).online).toEqual([alex]);
  });
}


() => {
    expect(messengerGetOnline([alex]).type).toEqual(MESSENGER_GET_ONLINE);
  }


() => {
    expect(messengerGetOnline([alex]).online).toEqual([alex]);
  }


() => {
  it('returns the correct action type', () => {
    expect(messengerShowOnline(alex).type).toEqual(MESSENGER_SHOW_ONLINE);
  });

  it('returns the correct user', () => {
    expect(messengerShowOnline(alex).user).toEqual(alex);
  });
}


() => {
    expect(messengerShowOnline(alex).type).toEqual(MESSENGER_SHOW_ONLINE);
  }


() => {
    expect(messengerShowOnline(alex).user).toEqual(alex);
  }


() => {
  it('returns the correct action type', () => {
    expect(messengerShowOffline(alex).type).toEqual(MESSENGER_SHOW_OFFLINE);
  });

  it('returns the correct user', () => {
    expect(messengerShowOffline(alex).user).toEqual(alex);
  });
}


() => {
    expect(messengerShowOffline(alex).type).toEqual(MESSENGER_SHOW_OFFLINE);
  }


() => {
    expect(messengerShowOffline(alex).user).toEqual(alex);
  }


() => {
  it('returns the correct action type', () => {
    expect(messengerChangeChannel('5067').type)
      .toEqual(MESSENGER_CHANGE_CHANNEL);
  });

  it('returns the correct channel', () => {
    expect(messengerChangeChannel('5067').channel).toEqual('5067');
  });
}


() => {
    expect(messengerChangeChannel('5067').type)
      .toEqual(MESSENGER_CHANGE_CHANNEL);
  }


() => {
    expect(messengerChangeChannel('5067').channel).toEqual('5067');
  }


() => {
  it('returns the correct action type', () => {
    expect(messengerChangedChannel([aaron, alex], '5067').type)
      .toEqual(MESSENGER_CHANGED_CHANNEL);
  });

  it('returns the correct users', () => {
    expect(messengerChangedChannel([aaron, alex], '5067').users)
      .toEqual([aaron, alex]);
  });

  it('returns the correct channel', () => {
    expect(messengerChangedChannel([aaron, alex], '5067').channel)
      .toEqual('5067');
  });
}


() => {
    expect(messengerChangedChannel([aaron, alex], '5067').type)
      .toEqual(MESSENGER_CHANGED_CHANNEL);
  }


() => {
    expect(messengerChangedChannel([aaron, alex], '5067').users)
      .toEqual([aaron, alex]);
  }


() => {
    expect(messengerChangedChannel([aaron, alex], '5067').channel)
      .toEqual('5067');
  }


() => {
  it('returns the correct action type', () => {
    expect(messengerRejoinedChannel([aaron, alex], '5067').type)
      .toEqual(MESSENGER_REJOINED_CHANNEL);
  });

  it('returns the correct users', () => {
    expect(messengerRejoinedChannel([aaron, alex], '5067').users)
      .toEqual([aaron, alex]);
  });

  it('returns the correct channel', () => {
    expect(messengerRejoinedChannel([aaron, alex], '5067').channel)
      .toEqual('5067');
  });
}


() => {
    expect(messengerRejoinedChannel([aaron, alex], '5067').type)
      .toEqual(MESSENGER_REJOINED_CHANNEL);
  }


() => {
    expect(messengerRejoinedChannel([aaron, alex], '5067').users)
      .toEqual([aaron, alex]);
  }


() => {
    expect(messengerRejoinedChannel([aaron, alex], '5067').channel)
      .toEqual('5067');
  }


() => {
  it('returns the correct action type', () => {
    expect(messengerJoinedUser(alex).type).toEqual(MESSENGER_JOINED_USER);
  });

  it('returns the correct user', () => {
    expect(messengerJoinedUser(alex).user).toEqual(alex);
  });
}


() => {
    expect(messengerJoinedUser(alex).type).toEqual(MESSENGER_JOINED_USER);
  }


() => {
    expect(messengerJoinedUser(alex).user).toEqual(alex);
  }


() => {
  it('returns the correct action type', () => {
    expect(messengerLeftUser(alex).type).toEqual(MESSENGER_LEFT_USER);
  });

  it('returns the correct user', () => {
    expect(messengerLeftUser(alex).user).toEqual(alex);
  });
}


() => {
    expect(messengerLeftUser(alex).type).toEqual(MESSENGER_LEFT_USER);
  }


() => {
    expect(messengerLeftUser(alex).user).toEqual(alex);
  }


() => {
  it('returns the correct action type', () => {
    expect(messengerSendMessage('howdy').type).toEqual(MESSENGER_SEND_MESSAGE);
  });

  it('returns the correct text', () => {
    expect(messengerSendMessage('howdy').text).toEqual('howdy');
  });
}


() => {
    expect(messengerSendMessage('howdy').type).toEqual(MESSENGER_SEND_MESSAGE);
  }


() => {
    expect(messengerSendMessage('howdy').text).toEqual('howdy');
  }


() => {
  it('returns the correct action type', () => {
    expect(messengerReceivedMessage(message).type)
      .toEqual(MESSENGER_RECEIVED_MESSAGE);
  });

  it('returns the correct message', () => {
    const actual = messengerReceivedMessage(message).message;
    const expected = message;

    expect(actual.kind).toEqual(expected.kind);
    expect(actual.id).toEqual(expected.id);
    expect(actual.text).toEqual(expected.text);
    expect(actual.room).toEqual(expected.room);
    expect(actual.user).toEqual(expected.user);
  });
}


() => {
    expect(messengerReceivedMessage(message).type)
      .toEqual(MESSENGER_RECEIVED_MESSAGE);
  }


() => {
    const actual = messengerReceivedMessage(message).message;
    const expected = message;

    expect(actual.kind).toEqual(expected.kind);
    expect(actual.id).toEqual(expected.id);
    expect(actual.text).toEqual(expected.text);
    expect(actual.room).toEqual(expected.room);
    expect(actual.user).toEqual(expected.user);
  }


() => {
  it('returns the correct action type', () => {
    expect(messengerSendWhisper('How are you?', 'John').type)
      .toEqual(MESSENGER_SEND_WHISPER);
  });

  it('returns the correct text', () => {
    expect(messengerSendWhisper('How are you?', 'John').text)
      .toEqual('How are you?');
  });

  it('returns the correct to', () => {
    expect(messengerSendWhisper('How are you?', 'John').to).toEqual('John');
  });
}


() => {
    expect(messengerSendWhisper('How are you?', 'John').type)
      .toEqual(MESSENGER_SEND_WHISPER);
  }


() => {
    expect(messengerSendWhisper('How are you?', 'John').text)
      .toEqual('How are you?');
  }


() => {
    expect(messengerSendWhisper('How are you?', 'John').to).toEqual('John');
  }


() => {
  it('returns the correct action type', () => {
    expect(messengerReceivedWhisper(whisper).type)
      .toEqual(MESSENGER_RECEIVED_WHISPER);
  });

  it('returns the correct ', () => {
    const actual = messengerReceivedWhisper(whisper).whisper;
    const expected = whisper;

    expect(actual.kind).toEqual(expected.kind);
    expect(actual.id).toEqual(expected.id);
    expect(actual.text).toEqual(expected.text);
    expect(actual.to).toEqual(expected.to);
    expect(actual.user).toEqual(expected.user);
  });
}


() => {
    expect(messengerReceivedWhisper(whisper).type)
      .toEqual(MESSENGER_RECEIVED_WHISPER);
  }


() => {
    const actual = messengerReceivedWhisper(whisper).whisper;
    const expected = whisper;

    expect(actual.kind).toEqual(expected.kind);
    expect(actual.id).toEqual(expected.id);
    expect(actual.text).toEqual(expected.text);
    expect(actual.to).toEqual(expected.to);
    expect(actual.user).toEqual(expected.user);
  }


() => {
  it('returns the correct action type', () => {
    expect(messengerFailedWhisper("User not found.").type)
      .toEqual(MESSENGER_FAILED_WHISPER);
  });

  it('returns the correct feedback', () => {
    expect(messengerFailedWhisper("User not found.").feedback)
      .toEqual("User not found.");
  });
}


() => {
    expect(messengerFailedWhisper("User not found.").type)
      .toEqual(MESSENGER_FAILED_WHISPER);
  }


() => {
    expect(messengerFailedWhisper("User not found.").feedback)
      .toEqual("User not found.");
  }


async (req: Request, res: Response) => {
  const { id } = req.body;

  // Delete task
  const tasks = await deleteTaskService(id);

  return res.status(200).json(tasks);
}


export function getI18nSource(key: string) {
  const store = useStore();
  const SysI18nSource = store.state.sysI18nSource.sysI18nSource
  if (!SysI18nSource || SysI18nSource[key] == undefined) {
    return key
  } else {
    return SysI18nSource[key]
  }
}


function swapBack(): void {
            lilsquare.classList.remove("dark-square");
            lilsquare.classList.add("medium-square");
        }


(distance: number) => {
            // Save for debugging
            // console.log(distance);
        }


(distance: number) => {
            // Save for debugging
            // console.log('entered');
        }


(distance: number) => {
            // Save for debugging
            // console.log('exited');
        }


(ref: HTMLElement): void => {
            this[name] = ref;
        }


(e: React.MouseEvent<any>): void => {
        const highlighter: HTMLElement = document.getElementById("highlighter");
        const circle: HTMLElement = e.currentTarget.querySelector(".ui-circle");
        const slide: AnimateTo = new AnimateTo(highlighter, { y: e.currentTarget.offsetTop - 87 }, { duration: 250 });
        const bounceKeyframes: AnimationKeyFrame[] = [
            { transform: "scale(1)" },
            { transform: "scale(2.2)", offset: .35 },
            { transform: "scale(2)", offset: .55 },
            { transform: "scale(0.9)", offset: .93 },
            { transform: "scale(1)" }
        ];

        const circleAnimation: AnimateTo = new AnimateTo(circle, {}, { duration: 500, easing: cubicBezier("fastInOut") });
        circleAnimation.addKeyframes(bounceKeyframes);
        circleAnimation.play();
        slide.play();
    }


(e: React.MouseEvent<any>): void => {
        const bar: HTMLElement = e.currentTarget.querySelector(".bar-fill");
        const diamond: HTMLElement = e.currentTarget.querySelector("#diamond");
        const checkmark: HTMLElement = e.currentTarget.querySelector("#doSvg1");

        const diamondFrames: AnimationKeyFrame[] = [
            { transform: "scale(1)" },
            { transform: "scale(1.6)", offset: 0.75 },
            { transform: "scale(0.95)", offset: 0.78 },
            { transform: "scale(1.05)", offset: 0.81 },
            { transform: "scale(0.97)", offset: 0.83 },
            { transform: "scale(1)", offset: 0.85 },
            { transform: "scale(1)"}
        ];

        const doSvgFrames: AnimationKeyFrame[] = [
            { transform: "scale(0)" },
            { transform: "scale(1.1)", offset: .9 },
            { transform: "scale(1)" }
        ];

        const barAnimation: AnimateTo = new AnimateTo(bar, { scale: [138, 1], transformOrigin: "0 0"}, { duration: 5000 });
        const diamondAnimation: AnimateTo = new AnimateTo(diamond, { transformOrigin: "50% 100%" }, { duration: 5000 });
        const doAnimation: AnimateTo = new AnimateTo(
            checkmark,
            { transformOrigin: "50% 100%" },
            { fill: "both", delay: 4650, duration: 250 }
        );

        doAnimation.addKeyframes(doSvgFrames);
        diamondAnimation.addKeyframes(diamondFrames);

        new AnimateGroup([
            barAnimation,
            diamondAnimation,
            doAnimation
        ]).play();
    }


(e: React.MouseEvent<any>): void => {
        const darkSquare: HTMLElement = e.currentTarget.querySelector(".dark-square");
        const mediumSquare: HTMLElement = e.currentTarget.querySelector(".medium-square");
        const lightSquare: HTMLElement = e.currentTarget.querySelector(".light-square");

        const fadeOptions: IAnimateOptions = { opacity: 0 };
        const fadeEffect: AnimationEffectTiming = { duration: 100 };

        const slideOptions: IAnimateOptions = { x: 180 };
        const slideEffect: AnimationEffectTiming = {
            duration: 300,
            fill: "backwards" as AnimationEffectTimingFillMode,
            easing: cubicBezier("easeOut")
        };

        new AnimateGroup([
            new AnimateFrom(darkSquare, fadeOptions, fadeEffect),
            new AnimateFrom(darkSquare, slideOptions, slideEffect),
            new AnimateFrom(mediumSquare, fadeOptions, fadeEffect),
            new AnimateFrom(mediumSquare, slideOptions, Object.assign({}, slideEffect, { delay: 40 })),
            new AnimateFrom(lightSquare, fadeOptions, fadeEffect),
            new AnimateFrom(lightSquare, slideOptions, Object.assign({}, slideEffect, { delay: 80 })),
        ]).play();
   }


(e: React.MouseEvent<any>): void => {
        const lilsquare: HTMLElement = e.currentTarget;
        const filler: HTMLElement = (lilsquare.parentNode as HTMLElement).querySelector(".size-fill");
        const fillAnimation: AnimateTo =
            new AnimateTo(filler, { scale: 1, transformOrigin: " 0 0" }, { duration: 250, easing: cubicBezier("easeOutSmooth") });

        fillAnimation.play();
        lilsquare.classList.add("dark-square");
        lilsquare.classList.remove("medium-square");

        function swapBack(): void {
            lilsquare.classList.remove("dark-square");
            lilsquare.classList.add("medium-square");
        }

        window.setTimeout((): void => {
            fillAnimation.reverse();
            swapBack();
        }, 2750);
    }


(): void => {
            fillAnimation.reverse();
            swapBack();
        }


(e: React.MouseEvent<any>): void => {
        const lilcircle: HTMLElement = e.currentTarget.querySelector(".circle-small");
        const bigcircle: HTMLElement = e.currentTarget.querySelector(".circle-large");

        new AnimateGroup([
            new AnimateTo(lilcircle, { x: 200 }, { duration: 3000 }),
            new AnimateTo(lilcircle, { bottom: 260 }, { duration: 3000, easing: cubicBezier("fastInOut") }),
            new AnimateTo(bigcircle, { y: -200 }, { duration: 3000, easing: cubicBezier("fastInOut") })
        ]).play();
    }


(e: React.MouseEvent<any>): void => {
        const square: HTMLElement = e.currentTarget.querySelector(".medium-square");
        new AnimateFrom(square, { opacity: 0, x: 60 }, { duration: 250, easing: cubicBezier("easeOut") }).play();
    }


(e: React.MouseEvent<any>): void => {
        const row1: HTMLElement = e.currentTarget.querySelector(".row1");
        const row2: HTMLElement = e.currentTarget.querySelector(".row2");
        const row3: HTMLElement = e.currentTarget.querySelector(".row3");

        const fadeInOptions: IAnimateOptions = { opacity: 1 };
        const fadeOutOptions: IAnimateOptions = { opacity: 0 };
        const fadeInEffect: AnimationEffectTiming = {
            duration: 350,
            easing: cubicBezier("fastInOut")
        };
        const fadeOutEffect: AnimationEffectTiming = {
            delay: 4000,
            easing: cubicBezier("easeOut")
        };

        const sequence: AnimateSequence = new AnimateSequence([
            new AnimateTo(row1, fadeInOptions, fadeInEffect),
            new AnimateTo(row2, fadeInOptions, fadeInEffect),
            new AnimateTo(row3, fadeInOptions, fadeInEffect)
        ]);

        sequence.onFinish = (): void => {
            sequence.onFinish = sequence.pause.bind(sequence);

            window.setTimeout(sequence.reverse.bind(sequence), 3000);
        };

        sequence.play();
    }


(): void => {
            sequence.onFinish = sequence.pause.bind(sequence);

            window.setTimeout(sequence.reverse.bind(sequence), 3000);
        }


(e: React.MouseEvent<any>): void => {
        const square1: HTMLElement = e.currentTarget.querySelector("#fourSquare1");
        const square2: HTMLElement = e.currentTarget.querySelector("#fourSquare2");
        const square3: HTMLElement = e.currentTarget.querySelector("#fourSquare3");
        const square4: HTMLElement = e.currentTarget.querySelector("#fourSquare4");
        const fadeKeyFrames: AnimationKeyFrame[] = [
            { opacity: 1 },
            { opacity: 0, offset: 0.4 },
            { opacity: 0, offset: 0.8 },
            { opacity: 1 }
        ];

        const slideOptions: IAnimateOptions = { y: -100 };
        const slideEffect: AnimationEffectTiming = { duration: 750, easing: cubicBezier("fastInOut") };
        const square1Animation: AnimateTo = new AnimateTo(square1, slideOptions, slideEffect);
        const square2Animation: AnimateTo = new AnimateTo(square2, slideOptions, slideEffect);
        const square3Animation: AnimateTo = new AnimateTo(square3, slideOptions, slideEffect);
        const square4Animation: AnimateTo = new AnimateTo(square4, slideOptions, slideEffect);

        square1Animation.addKeyframes(fadeKeyFrames);
        square2Animation.addKeyframes(fadeKeyFrames);
        square2Animation.effectTiming.delay = 100;
        square3Animation.addKeyframes(fadeKeyFrames);
        square3Animation.effectTiming.delay = 200;
        square4Animation.addKeyframes(fadeKeyFrames);
        square4Animation.effectTiming.delay = 2000;

        const group: AnimateGroup = new AnimateGroup([
            square1Animation,
            square2Animation,
            square3Animation,
            square4Animation
        ]);

        group.play();

        window.setTimeout(() => {
            group.reverse();
        }, 3000);
    }


() => {
            group.reverse();
        }


public componentDidMount(): void {
        const overlapping: HTMLElement = document.getElementById("overlapping");
        const scrollTrigger: ScrollTrigger = new ScrollTrigger();
        const viewEnterTrigger: ViewEnterTrigger = new ViewEnterTrigger();
        const viewExitTrigger: ViewExitTrigger = new ViewExitTrigger();

        const lightSquare: HTMLElement = overlapping.querySelector(".light-square");
        const mediumSquare: HTMLElement = overlapping.querySelector(".medium-square");

        const effects: AnimationEffectTiming = {
            duration: 750,
            iterations: Infinity,
            direction: "alternate",
            easing: cubicBezier("fastInOut")
        };

        new AnimateTo(lightSquare as HTMLElement, {
            scale: 2.27, transformOrigin: "0 50%"
        }, effects).play();

        new AnimateTo(mediumSquare as HTMLElement, {
            scale: 2.27, transformOrigin: "100% 50%"
        }, Object.assign({}, effects, { delay: 750 })).play();

        scrollTrigger.subscribe(this.scrollElement, (distance: number) => {
            // Save for debugging
            // console.log(distance);
        });
        viewEnterTrigger.subscribe(this.scrollElement, (distance: number) => {
            // Save for debugging
            // console.log('entered');
        });

        viewExitTrigger.subscribe(this.scrollElement, (distance: number) => {
            // Save for debugging
            // console.log('exited');
        });
    }


public render(): JSX.Element {
        return (

                        {this.generateUIBox("circle1")}
                        {this.generateUIBox("circle2")}

                            01234567

        );
    }


private generateUIBox(id: string): JSX.Element {
        return (

        );
    }


private setRef(name: string): (ref: HTMLElement) => void {
        return (ref: HTMLElement): void => {
            this[name] = ref;
        };
    }


function expectPageModelLoadedEventFired() {
        expect(PathUtils.dispatchGlobalCustomEvent).toHaveBeenCalled();
        expect(PathUtils.dispatchGlobalCustomEvent).toHaveBeenCalledWith(EventType.PAGE_MODEL_LOADED, PAGE_MODEL_LOAD_EVENT_OPTIONS);
    }


function assertAsyncModelFetched() {
        expectPageModelLoadedEventFired();

        return ModelManager.getData().then((data) => {
            assert.deepEqual(data, PAGE_MODEL, 'data should be correct');
        });
    }


function mockTheFetch(path: any, data: any) {
        fetchMock.mockIf(path, () => {
           return Promise.resolve({
               body: JSON.stringify(data)
           });
        });
    }


(data) => {
            assert.deepEqual(data, PAGE_MODEL, 'data should be correct');
        }


() => {
           return Promise.resolve({
               body: JSON.stringify(data)
           });
        }


() => {
        metaProps = {};
        metaProps[MetaProperty.PAGE_MODEL_ROOT_URL] = PAGE_MODEL_URL;
        pathName = PAGE_PATH;

        when(ModelClientMock.fetch(anyString())).thenReturn(Promise.resolve(PAGE_MODEL));
        when(ModelClientMock.fetch(PAGE_MODEL_URL)).thenReturn(Promise.resolve(PAGE_MODEL));
        when(ModelClientMock.fetch(CHILD_MODEL_URL)).thenReturn(Promise.resolve(content_test_page_root_child0000_child0010));
        modelClient = instance(ModelClientMock);
        jest.spyOn(PathUtils, 'getMetaPropertyValue').mockImplementation((val) => metaProps[val]);
        jest.spyOn(PathUtils, 'dispatchGlobalCustomEvent');
        jest.spyOn(PathUtils, 'getCurrentOrVanityPathname').mockImplementation(() => pathName);
        mockTheFetch(PAGE_MODEL_URL, PAGE_MODEL);
    }


(val) => metaProps[val]


() => pathName


() => {
        reset(ModelClientMock);
        pathName = '';
    }


() => {
        describe('Initialization without config object ->', () => {
            it('should NOT fetch remote data on initialization when the model is provided', () => {
                return ModelManager.initialize({ model: PAGE_MODEL }).then((data) => {
                    expectPageModelLoadedEventFired();
                    expect(data).toEqual(PAGE_MODEL);
                    assert.deepEqual(data, PAGE_MODEL, 'data should be correct');
                });
            });

            it('should fetch remote data on initialization - root path as meta property', () => {
                metaProps[MetaProperty.PAGE_MODEL_ROOT_URL] = PAGE_MODEL_URL;

                return ModelManager.initialize().then((data) => {
                    expectPageModelLoadedEventFired();
                    assert.deepEqual(data, PAGE_MODEL, 'data should be correct');
                });
            });

            it('should fetch remote data on initialization - root path as currentPathname', () => {
                pathName = PAGE_MODEL_URL;

                return ModelManager.initialize().then((data) => {
                    expectPageModelLoadedEventFired();
                    assert.deepEqual(data, PAGE_MODEL, 'data should be correct');
                });
            });

            it('should fetch remote data on initialization - root path as a parameter', () => {
                return ModelManager.initialize(PAGE_PATH).then((data) => {
                    expectPageModelLoadedEventFired();
                    assert.deepEqual(data, PAGE_MODEL, 'data should be correct');
                });
            });
        });

        it('should fetch remote data on initialization', () => {
            return ModelManager.initialize({ path: PAGE_PATH, modelClient: modelClient }).then((data) => {
                verify(modelClient.fetch(anyString()));
                assert.deepEqual(data, PAGE_MODEL, 'data should be correct');
            });
        });

        it('should fail when initialized on non-browser with invlid config', () => {
            pathName = '';

            // disable console.error within the test
            jest.spyOn(console, 'error').mockImplementation();

            //simulate non browser for the test
            const windowSpy = jest.spyOn(global, 'window', 'get');

            windowSpy.mockImplementation();

            try {
                ModelManager.initialize();
            } catch (err) {
                assert.strictEqual(err.name, 'Error');
            }
        });

        it('should throw error when initialized without model url', () => {
            metaProps = {};
            pathName = '';
            try {
                ModelManager.initialize();
            } catch (err) {
                assert.strictEqual(err.name, 'Error');
            }
        });

        it('should throw error when initialized with invalid model url', () => {
            try {
                ModelManager.initialize({ path: '?abc' });
            } catch (err) {
                assert.strictEqual(err.name, 'Error');
            }
        });

        it('should not make concurrent server calls on duplicate request', () => {
            return ModelManager.initialize({ path: PAGE_PATH, model: PAGE_MODEL, modelClient: modelClient }).then(() => {
                expectPageModelLoadedEventFired();
                pathName = '/content/test/duplicate/request';

                when(ModelClientMock.fetch(pathName)).thenReturn(new Promise((resolve) => {
                    setTimeout(() => resolve(PAGE_MODEL), 200);
                }));

                const promises: any[] = [];

                promises.push(ModelManager._fetchData(pathName));
                promises.push(ModelManager._fetchData(pathName));
                promises.push(ModelManager._fetchData(pathName));

                return Promise.all(promises).then(() => {
                    for (let i = 0; i < promises.length - 1; ++i) {
                        assert.equal(promises[i], promises[i + 1]);
                    }
                });
            });
        });

        describe('when the request is for an asynchronous subpage -- ', () => {
            beforeEach(() => {
                pathName = '/content/test/pageNotInModel';
                metaProps[MetaProperty.PAGE_MODEL_ROOT_URL] = '/content/test';
            });

            it('should fetch data twice on initialization', () => {
                return ModelManager.initialize({ path: PAGE_PATH, modelClient: modelClient }).then((data) => {
                    expectPageModelLoadedEventFired();
                    verify(ModelClientMock.fetch(anyString())).times(2);
                    assert.deepEqual(data, PAGE_MODEL, 'data should be correct');
                });
            });
        });

        it('should not fetch data on initialization', () => {
            return ModelManager.initialize({ path: PAGE_PATH, model: PAGE_MODEL, modelClient: modelClient }).then((data) => {
                expectPageModelLoadedEventFired();
                // verify(ModelClientMock.fetch(anyString())).never();
                assert.deepEqual(data, PAGE_MODEL, 'data should be correct');
            });
        });

        it('should not fetch data', () => {
            return ModelManager.initialize({ path: PAGE_PATH, model: PAGE_MODEL, modelClient: modelClient }).then(() => {
                expectPageModelLoadedEventFired();

                return ModelManager.getData(CHILD_PATH).then((data) => {
                    verify(ModelClientMock.fetch(CHILD_MODEL_URL)).never();
                    assert.deepEqual(data, content_test_page_root_child0000_child0010, 'data should be correct');
                });
            });
        });

        it('should fetch all the data', () => {
            return ModelManager.initialize({ path: PAGE_PATH, model: PAGE_MODEL, modelClient: modelClient }).then(() => {
                expectPageModelLoadedEventFired();

                return ModelManager.getData().then((data) => {
                    verify(ModelClientMock.fetch(CHILD_MODEL_URL)).never();
                    assert.deepEqual(data, PAGE_MODEL, 'data should be correct');
                });
            });
        });

        it('should fetch data if forced', () => {
            return ModelManager.initialize({ path: PAGE_PATH, model: PAGE_MODEL, modelClient: modelClient }).then(() => {
                expectPageModelLoadedEventFired();

                return ModelManager.getData({ path: CHILD_PATH, forceReload: true }).then((data) => {
                    verify(ModelClientMock.fetch(anyString())).times(1);
                    assert.deepEqual(data, content_test_page_root_child0000_child0010, 'data should be correct');
                });
            });
        });
    }