() => {
    const { ast } = compileWithStringify(
      `<div>${repeat(
        `<span class="foo"/>`,
        StringifyThresholds.ELEMENT_WITH_BINDING_COUNT
      )}</div>`
    )
    // should have 5 hoisted nodes, but the other 4 should be null
    expect(ast.hoists.length).toBe(5)
    for (let i = 1; i < 5; i++) {
      expect(ast.hoists[i]).toBe(null)
    }
    // should be optimized now
    expect(ast.hoists[0]).toMatchObject({
      type: NodeTypes.JS_CALL_EXPRESSION,
      callee: CREATE_STATIC,
      arguments: [
        JSON.stringify(
          repeat(
            `<span class="foo"></span>`,
            StringifyThresholds.ELEMENT_WITH_BINDING_COUNT
          )
        ),
        '5'
      ]
    })
  }


() => {
    const { ast } = compileWithStringify(
      `

${repeat(
        `<span :class="[{ foo: true }, { bar: true }]">{{ 1 }} + {{ false }}</span>`,
        StringifyThresholds.ELEMENT_WITH_BINDING_COUNT
      )}

`
    )
    expect(ast.hoists.length).toBe(1)
    // should be optimized now
    expect(ast.hoists[0]).toMatchObject({
      type: NodeTypes.JS_CALL_EXPRESSION,
      callee: CREATE_STATIC,
      arguments: [
        JSON.stringify(
          `
${repeat(
            `<span class="foo bar">1 + false</span>`,
            StringifyThresholds.ELEMENT_WITH_BINDING_COUNT
          )}
`
        ),
        '1'
      ]
    })
  }


() => {
    const { ast } = compileWithStringify(
      `

${repeat(
        `<span :class="'foo' + '>ar'">{{ 1 }} + {{ '<' }}</span>` +
          `<span>&</span>`,
        StringifyThresholds.ELEMENT_WITH_BINDING_COUNT
      )}

`
    )
    expect(ast.hoists.length).toBe(1)
    // should be optimized now
    expect(ast.hoists[0]).toMatchObject({
      type: NodeTypes.JS_CALL_EXPRESSION,
      callee: CREATE_STATIC,
      arguments: [
        JSON.stringify(
          `
${repeat(
            `<span class="foo>ar">1 + <</span>` + `<span>&</span>`,
            StringifyThresholds.ELEMENT_WITH_BINDING_COUNT
          )}
`
        ),
        '1'
      ]
    })
  }


() => {
    const { ast } = compile(
      `

${repeat(
        `<span class="foo">foo</span>`,
        StringifyThresholds.ELEMENT_WITH_BINDING_COUNT
      )}

`,
      {
        hoistStatic: true,
        prefixIdentifiers: true,
        transformHoist: stringifyStatic,
        nodeTransforms: [
          node => {
            if (node.type === NodeTypes.ELEMENT && node.tag === 'img') {
              const exp = createSimpleExpression(
                '_imports_0_',
                false,
                node.loc,
                ConstantTypes.CAN_HOIST
              )
              node.props[0] = {
                type: NodeTypes.DIRECTIVE,
                name: 'bind',
                arg: createSimpleExpression('src', true),
                exp,
                modifiers: [],
                loc: node.loc
              }
            }
          }
        ]
      }
    )
    // the expression and the tree are still hoistable
    expect(ast.hoists.length).toBe(1)
    // ...but the hoisted tree should not be stringified
    expect(ast.hoists[0]).toMatchObject({
      // if it's stringified it will be NodeTypes.CALL_EXPRESSION
      type: NodeTypes.VNODE_CALL
    })
  }


node => {
            if (node.type === NodeTypes.ELEMENT && node.tag === 'img') {
              const exp = createSimpleExpression(
                '_imports_0_',
                false,
                node.loc,
                ConstantTypes.CAN_HOIST
              )
              node.props[0] = {
                type: NodeTypes.DIRECTIVE,
                name: 'bind',
                arg: createSimpleExpression('src', true),
                exp,
                modifiers: [],
                loc: node.loc
              }
            }
          }


() => {
    const { ast } = compileWithStringify(
      `

<input indeterminate>${repeat(
        `<span class="foo">foo</span>`,
        StringifyThresholds.ELEMENT_WITH_BINDING_COUNT
      )}

`
    )
    expect(ast.hoists.length).toBe(1)
    expect(ast.hoists[0]).toMatchObject({
      type: NodeTypes.VNODE_CALL // not CALL_EXPRESSION
    })

    const { ast: ast2 } = compileWithStringify(
      `

<input :indeterminate="true">${repeat(
        `<span class="foo">foo</span>`,
        StringifyThresholds.ELEMENT_WITH_BINDING_COUNT
      )}

`
    )
    expect(ast2.hoists.length).toBe(1)
    expect(ast2.hoists[0]).toMatchObject({
      type: NodeTypes.VNODE_CALL // not CALL_EXPRESSION
    })
  }


() => {
    const { ast } = compileWithStringify(
      `

${repeat(
        `<span class="foo">foo</span>`,
        StringifyThresholds.ELEMENT_WITH_BINDING_COUNT
      )}<input indeterminate>

`
    )
    expect(ast.hoists.length).toBe(1)
    expect(ast.hoists[0]).toMatchObject({
      type: NodeTypes.VNODE_CALL // not CALL_EXPRESSION
    })

    const { ast: ast2 } = compileWithStringify(
      `

${repeat(
        `<span class="foo">foo</span>`,
        StringifyThresholds.ELEMENT_WITH_BINDING_COUNT
      )}<input :indeterminate="true">

`
    )
    expect(ast2.hoists.length).toBe(1)
    expect(ast2.hoists[0]).toMatchObject({
      type: NodeTypes.VNODE_CALL // not CALL_EXPRESSION
    })
  }


() => {
    const { ast } = compileWithStringify(
      `

${repeat(
        `<tr class="foo"><td>foo</td></tr>`,
        StringifyThresholds.ELEMENT_WITH_BINDING_COUNT
      )}

`
    )
    expect(ast.hoists.length).toBe(1)
    expect(ast.hoists[0]).toMatchObject({
      type: NodeTypes.VNODE_CALL // not CALL_EXPRESSION
    })
  }


() => {
    const { ast } = compileWithStringify(
      `<foo>${repeat(
        `<div class="foo"></div>`,
        StringifyThresholds.ELEMENT_WITH_BINDING_COUNT
      )}</foo>`
    )
    expect(ast.hoists.length).toBe(
      StringifyThresholds.ELEMENT_WITH_BINDING_COUNT
    )
    ast.hoists.forEach(node => {
      expect(node).toMatchObject({
        type: NodeTypes.VNODE_CALL // not CALL_EXPRESSION
      })
    })

    const { ast: ast2 } = compileWithStringify(
      `<foo><template #foo>${repeat(
        `<div class="foo"></div>`,
        StringifyThresholds.ELEMENT_WITH_BINDING_COUNT
      )}</template></foo>`
    )
    expect(ast2.hoists.length).toBe(
      StringifyThresholds.ELEMENT_WITH_BINDING_COUNT
    )
    ast2.hoists.forEach(node => {
      expect(node).toMatchObject({
        type: NodeTypes.VNODE_CALL // not CALL_EXPRESSION
      })
    })
  }


node => {
      expect(node).toMatchObject({
        type: NodeTypes.VNODE_CALL // not CALL_EXPRESSION
      })
    }


export function getNumberOfRounds(nPlayers: number): number {
    const maxCards = getMaxCards(nPlayers);
    if (52 % nPlayers === 0) {
        return maxCards * 2 - 1;
    }
    return maxCards * 2;
}


export function getNumberOfCards(nPlayers: number, round: number): number {
    const maxCards = getMaxCards(nPlayers);
    if (round <= maxCards) {
        return round;
    }
    if (52 % nPlayers === 0) {
        return maxCards * 2 - round;
    }
    return maxCards * 2 + 1 - round;
}


export function getMaxCards(nPlayers: number): number {
    return Math.floor(52 / nPlayers);
}


export default class ConfigApi {
    _storyStore: StoryStore;
    constructor({ storyStore }: {
        storyStore: StoryStore;
    });
    configure: (loaders: () => void, module: NodeModule, showDeprecationWarning?: boolean) => void;
}


({breadcrumbHeight, className}) => {
  const location = useLocation();
  const pathnames = location.pathname.slice(1).split('/');

  return (
    <div className={clsx('Breadcrumb', className)}>
      {pathnames.map((pathname, index) => {
        const isLastIndex = index === pathnames.length - 1;
        // developer
        if (index === 0) {
          return (
            <BreadcrumbSection
              isSectionSelected={isLastIndex}
              hasItems={false}
              hasPrecedingArrowIcon={false}
              key={pathname}
              title={PATHNAME_TO_TITLE_MAPPING[pathname]}
              titleLink={`/${pathname}`}
            />
          );
        }

        // whitepaper
        if (index === 1) {
          return (
            <BreadcrumbSection
              isItemsInSamePage={false}
              isSectionSelected={isLastIndex}
              items={PATHNAME_TO_DROPDOWN_SELECTIONS[pathname]}
              hasItems
              hasPrecedingArrowIcon
              hasPrecedingArrowIcon992px
              key={pathname}
              title={PATHNAME_TO_TITLE_MAPPING[pathname]}
              titleLink={`/developer/${pathname}`}
            />


(pathname, index) => {
        const isLastIndex = index === pathnames.length - 1;
        // developer
        if (index === 0) {
          return (
            <BreadcrumbSection
              isSectionSelected={isLastIndex}
              hasItems={false}
              hasPrecedingArrowIcon={false}
              key={pathname}
              title={PATHNAME_TO_TITLE_MAPPING[pathname]}
              titleLink={`/${pathname}`}
            />


type Props = {
  className?: string;
  breadcrumbHeight: number;
};


clsx('Breadcrumb', className)


export async function watchGraphQLTypes(): Promise<void> {
    await new Promise<never>((resolve, reject) => {
        gulp.watch(GRAPHQL_SCHEMA_PATH, graphQLTypes).on('error', reject)
    })
}


/** Generates the TypeScript types for the GraphQL schema */
export async function graphQLTypes(): Promise<void> {
    const schemaStr = await readFile(GRAPHQL_SCHEMA_PATH, 'utf8')
    const schema = buildSchema(schemaStr)
    const result = (await graphql(schema, introspectionQuery)) as { data: IntrospectionQuery }

    const formatOptions = (await resolveConfig(__dirname, { config: __dirname + '/../prettier.config.js' }))!
    const typings =
        'export type ID = string\n\n' +
        generateNamespace(
            '',
            result,
            {
                typeMap: {
                    ...DEFAULT_TYPE_MAP,
                    ID: 'ID',
                },
            },
            {
                generateNamespace: (name: string, interfaces: string) => interfaces,
                interfaceBuilder: (name: string, body: string) =>
                    'export ' + DEFAULT_OPTIONS.interfaceBuilder(name, body),
                enumTypeBuilder: (name: string, values: string) =>
                    'export ' + DEFAULT_OPTIONS.enumTypeBuilder(name, values),
                typeBuilder: (name: string, body: string) => 'export ' + DEFAULT_OPTIONS.typeBuilder(name, body),
                wrapList: (type: string) => `${type}[]`,
                postProcessor: (code: string) => format(code, { ...formatOptions, parser: 'typescript' }),
            }
        )
    await writeFile(__dirname + '/src/graphqlschema.ts', typings)
}


/**
 * Generates the TypeScript types for the JSON schemas.
 */
export async function schema(): Promise<void> {
    const outputDir = path.join(__dirname, '..', 'web', 'src', 'schema')
    await mkdirp(outputDir)
    const schemaDir = path.join(__dirname, '..', 'schema')
    await Promise.all(
        ['json-schema-draft-07', 'settings', 'site', 'extension'].map(async file => {
            let schema = await readFile(path.join(schemaDir, `${file}.schema.json`), 'utf8')
            // HACK: Rewrite absolute $refs to be relative. They need to be absolute for Monaco to resolve them
            // when the schema is in a oneOf (to be merged with extension schemas).
            schema = schema.replace(
                /https:\/\/sourcegraph\.com\/v1\/settings\.schema\.json#\/definitions\//g,
                '#/definitions/'
            )

            const types = await compileJSONSchema(JSON.parse(schema), 'settings.schema', {
                cwd: schemaDir,
                $refOptions: {
                    resolve: {
                        draftV7resolver,
                        // there should be no reason to make network calls during this process,
                        // and if there are we've broken env for offline devs/increased dev startup time
                        http: false,
                    } as $RefParser.Options['resolve'],
                },
            })
            await writeFile(path.join(outputDir, `${file}.schema.d.ts`), types)
        })
    )
}


export async function watchSchema(): Promise<void> {
    await new Promise<never>((_resolve, reject) => {
        gulp.watch(__dirname + '/../schema/*.schema.json', schema).on('error', reject)
    })
}


(resolve, reject) => {
        gulp.watch(GRAPHQL_SCHEMA_PATH, graphQLTypes).on('error', reject)
    }


(name: string, interfaces: string) => interfaces


(name: string, body: string) =>
                    'export ' + DEFAULT_OPTIONS.interfaceBuilder(name, body)


(name: string, values: string) =>
                    'export ' + DEFAULT_OPTIONS.enumTypeBuilder(name, values)


(name: string, body: string) => 'export ' + DEFAULT_OPTIONS.typeBuilder(name, body)


(type: string) => `${type}[]`


(code: string) => format(code, { ...formatOptions, parser: 'typescript' })


async file => {
            let schema = await readFile(path.join(schemaDir, `${file}.schema.json`), 'utf8')
            // HACK: Rewrite absolute $refs to be relative. They need to be absolute for Monaco to resolve them
            // when the schema is in a oneOf (to be merged with extension schemas).
            schema = schema.replace(
                /https:\/\/sourcegraph\.com\/v1\/settings\.schema\.json#\/definitions\//g,
                '#/definitions/'
            )

            const types = await compileJSONSchema(JSON.parse(schema), 'settings.schema', {
                cwd: schemaDir,
                $refOptions: {
                    resolve: {
                        draftV7resolver,
                        // there should be no reason to make network calls during this process,
                        // and if there are we've broken env for offline devs/increased dev startup time
                        http: false,
                    } as $RefParser.Options['resolve'],
                },
            })
            await writeFile(path.join(outputDir, `${file}.schema.d.ts`), types)
        }


(_resolve, reject) => {
        gulp.watch(__dirname + '/../schema/*.schema.json', schema).on('error', reject)
    }


/**
 * Structure for sdt.
 */
export class SDTSection {
    // table_id: number;
    // section_syntax_indicator: number;
    section_length: number;
    // transport_stream_id: number;
    // version_number: number;
    // current_next_indicator: number;
    // section_number: number;
    // last_section_number: number;
    // original_network_id: number;
    service_table: Array<M2TS.SDTServiceItem>;

    constructor(buffer: Uint8Array) {
        // program_map_section  0x02
        // this.table_id = buffer[0];

        // this.section_syntax_indicator = buffer[1] >> 7;

        // this.reserved_0 = (buffer[1] >> 4) & 0x3;

        // the number of bytes of the section
        // starting immediately following the section_length field, and including the CRC.
        this.section_length = ((buffer[1] & 0x0f) << 8) | buffer[2];

        // This is a 16-bit field which serves as a label for identification of the TS,
        // about which the SDT informs, from any other multiplex within the delivery system
        // this.transport_stream_id = (buffer[3] << 8) | buffer[4];

        // // this.reserved_1 = buffer[5] >> 6;

        // this.version_number = (buffer[5] >> 1) & 0x1f;

        // this.current_next_indicator = buffer[5] & 0x01;

        // The section_number of the first section in the sub_table shall be "0x00".
        // The section_number shall be incremented by 1 with each additional section
        // with the same table_id, transport_stream_id, and original_network_id.
        // this.section_number = buffer[6];

        // This 8-bit field specifies the number of the last section
        // (that is, the section with the highest section_number) of the sub_table of which this section is part
        // this.last_section_number = buffer[7];

        // This field gives the label identifying the network_id of the originating delivery system.
        // this.original_network_id = (buffer[8] << 8) | buffer[9];

        // this.reserved_2 = buffer[10];

        // section_length - (following the section_length field length) - crc32Length
        let sv_len = this.section_length - 8 - 4; // 8: bytes followed by section_length, 4: crc32

        this.service_table = [];
        let i = 0;

        while (i < sv_len) {
            let j = 0;
            let service: M2TS.SDTServiceItem = {
                service_id: (buffer[11] << 8) | buffer[12],
                // EIT_schedule_flag: buffer[13] & 0x02,
                // EIT_present_following_flag: buffer[13] & 0x01,
                // running_status: buffer[14] >> 5,
                // free_CA_mode: (buffer[14] >> 4) & 0x01,
                descriptors_loop_length: ((buffer[14] & 0x0f) << 8) | buffer[15],
                provider_name: '',
                name: ''
            };

            while (j < service.descriptors_loop_length) {
                let start = 16 + j;
                let descriptor_tag = buffer[start];
                let descriptor_length = buffer[start + 1];

                switch (descriptor_tag) {
                    case 0x48: // service_descriptor
                        {
                            // let service_type = buffer[start + 2];
                            let service_provider_name = [];
                            let service_provider_name_length = buffer[start + 3];
                            let k = 0,
                                l = 0,
                                nextPos = start + 4;

                            for (k = 0; k < service_provider_name_length; k++) {
                                service_provider_name.push(String.fromCharCode(buffer[nextPos]));
                                nextPos += 1;
                            }

                            service.provider_name = service_provider_name.join('');

                            let service_name = [];
                            let service_name_length = buffer[nextPos];
                            nextPos += 1;

                            for (l = 0; l < service_name_length; l++) {
                                service_name.push(String.fromCharCode(buffer[nextPos]));
                                nextPos += 1;
                            }

                            service.name = service_name.join('');
                        }
                        break;
                    default:
                        logger.warn(`sdt section unhandled descriptor_tag ${descriptor_tag}`);
                }

                j += 2 + descriptor_length;
            }

            this.service_table.push(service);

            i += 5 + service.descriptors_loop_length;
        }
    }
}


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


export default class Shields extends React.PureComponent<Props, State> {
  constructor (props: Props) {
    super(props)
    this.state = { isBlockedListOpen: false }
  }

  get favicon (): string {
    const { url } = this.props.shieldsPanelTabData
    return getFavicon(url)
  }

  get isShieldsEnabled (): boolean {
    const { braveShields } = this.props.shieldsPanelTabData
    return isShieldsEnabled(braveShields)
  }

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

  render () {
    const { shieldsPanelTabData, persistentData, toggleAdvancedView, actions } = this.props
    const { isBlockedListOpen } = this.state

    if (!shieldsPanelTabData) {
      return null
    }

    return (
      <ShieldsPanel data-test-id='brave-shields-panel' style={{ width: '370px' }}


interface Props {
  actions: {
    shieldsToggled: ShieldsToggled
    reportBrokenSite: ReportBrokenSite
    blockAdsTrackers: BlockAdsTrackers
    httpsEverywhereToggled: HttpsEverywhereToggled
    blockJavaScript: BlockJavaScript
    blockFingerprinting: BlockFingerprinting
    blockCookies: BlockCookies
    allowScriptOriginsOnce: AllowScriptOriginsOnce
    setScriptBlockedCurrentState: SetScriptBlockedCurrentState
    setGroupedScriptsBlockedCurrentState: SetGroupedScriptsBlockedCurrentState
    setAllScriptsBlockedCurrentState: SetAllScriptsBlockedCurrentState
    setFinalScriptsBlockedState: SetFinalScriptsBlockedState
    setAdvancedViewFirstAccess: SetAdvancedViewFirstAccess
  }
  shieldsPanelTabData: Tab
  persistentData: PersistentData
  toggleAdvancedView: () => void
}


interface State {
  isBlockedListOpen: boolean
}


render () {
    const { shieldsPanelTabData, persistentData, toggleAdvancedView, actions } = this.props
    const { isBlockedListOpen } = this.state

    if (!shieldsPanelTabData) {
      return null
    }

    return (
      <ShieldsPanel data-test-id='brave-shields-panel' style={{ width: '370px' }}


export class Game_CommonEvent {
    private _commonEventId: number;
    private _interpreter: Game_Interpreter;

    public constructor(
        commonEventId: number,
        gameLoadInput?: Game_CommonEvent_OnLoad
    ) {
        this._commonEventId = commonEventId;
        this.refresh();

        if (gameLoadInput) {
            this._commonEventId = gameLoadInput._commonEventId;
            this._interpreter = new Game_Interpreter(
                gameLoadInput._interpreter
            );
        }
    }

    public event() {
        return $dataCommonEvents[this._commonEventId];
    }

    public list() {
        return this.event().list;
    }

    public refresh() {
        if (this.isActive()) {
            if (!this._interpreter) {
                this._interpreter = new Game_Interpreter();
            }
        } else {
            this._interpreter = null;
        }
    }

    public isActive() {
        const event = this.event();
        return event.trigger === 2 && $gameSwitches.value(event.switchId);
    }

    public update() {
        if (this._interpreter) {
            if (!this._interpreter.isRunning()) {
                this._interpreter.setup(this.list());
            }
            this._interpreter.update();
        }
    }
}


export interface Game_CommonEvent_OnLoad {
    _commonEventId: number;
    _interpreter: Game_Interpreter_OnLoad;
}


public event() {
        return $dataCommonEvents[this._commonEventId];
    }


public list() {
        return this.event().list;
    }


public refresh() {
        if (this.isActive()) {
            if (!this._interpreter) {
                this._interpreter = new Game_Interpreter();
            }
        } else {
            this._interpreter = null;
        }
    }


public isActive() {
        const event = this.event();
        return event.trigger === 2 && $gameSwitches.value(event.switchId);
    }


public update() {
        if (this._interpreter) {
            if (!this._interpreter.isRunning()) {
                this._interpreter.setup(this.list());
            }
            this._interpreter.update();
        }
    }


p => {
  return (
    <Switch>
      <Route path={makePath(PORTFOLIO)} component={PortfolioView} />
      <Route path={makePath(MARKETS)} component={MarketsView} />
      <Route path={makePath(MARKET)} component={MarketView} />
      <Redirect to={makePath(MARKETS)} />
    </Switch>


makePath(PORTFOLIO)


id => {
      return (
        <ChartCardContainer
          expanded={!this.state.hiddenCharts.has(id)}


() => {
                this.setState({ hiddenCharts: new Set() });
              }


c => hiddenCharts.add(c)


export default class ChartCollection extends React.PureComponent<ChartCollectionProps, ChartCollectionState> {
  private prevFilters: CollectionItemFilterObject[];
  private prevSorts: CollectionItemSortObject[];

  constructor(props: ChartCollectionProps) {
    super(props);
    this.state = {
      hiddenCharts: new Set(),
    };

    this.toggleExpandChart = this.toggleExpandChart.bind(this);

    this.prevFilters = [];
    this.prevSorts = [];
  }

  render() {
    const charts = this.props.chartIds.map(id => {
      return (
        <ChartCardContainer
          expanded={!this.state.hiddenCharts.has(id)}
          key={id}
          id={id}
          toggleExpandChart={this.toggleExpandChart}
        />
      );
    });

    const reloadButtonStyle = classnames({
      reloading: !_.isUndefined(this.state.runId) && !this.props.finishedRunIds.has(this.state.runId),
    });

    return (

        <div styleName="controls"


export interface ChartCollectionStoreProps {
  chartIds: string[];
  finishedRunIds: Set<number>;
}


export interface ChartCollectionDispatchProps {
  reloadCharts: (runId: number) => void;
  addEmptyChart: () => void;
  setChartFilters: (filters: CollectionItemFilterObject[]) => void;
  setChartSorts: (sorts: CollectionItemSortObject[]) => void;
}


export interface ChartCollectionOwnProps {}


export interface ChartCollectionProps
  extends ChartCollectionStoreProps,
    ChartCollectionDispatchProps,
    ChartCollectionOwnProps {}


export interface ChartCollectionState {
  runId?: number;
  hiddenCharts: Set<string>;
}


render() {
    const charts = this.props.chartIds.map(id => {
      return (
        <ChartCardContainer
          expanded={!this.state.hiddenCharts.has(id)}
          key={id}
          id={id}
          toggleExpandChart={this.toggleExpandChart}
        />
      );
    }


return (

        <div styleName="controls"


data => {
            console.log(data);
            this.emprendimientos$ = data;
            this.temp = data;
            this.rows = data;
          }


@Component({
    selector: 'app-dashboard2',
    templateUrl: './dashboard2.component.html',
    styleUrls: ['./dashboard2.component.scss']
})

export class Dashboard2Component implements OnInit {
    nombre$;
    emprendimientos$;
    @ViewChild(DatatableComponent) table: DatatableComponent;
    emprendimiento$;
    rows = [];
    columns = [{name: 'nombre'},{name: 'descripcion'}];
    temp = [];
    constructor(private emprendimientoService: EmprendimientoService) {

    }
    ngOnInit(): void {
        this.nombre$ = localStorage.getItem('nombre');
        this.emprendimientoService.obtenerEmprendimientos()
        .subscribe(
          data => {
            console.log(data);
            this.emprendimientos$ = data;
            this.temp = data;
            this.rows = data;
          },
          error => {}
        );
    }

    updateFilter(event) {
        //this.piarescolarItem = null;
        const val = event.target.value.toLowerCase();

        // filter our data
        const temp = this.temp.filter(function (d) {
            return d.nombre.toString().toLowerCase().indexOf(val) !== -1 || !val;
        });

        // update the rows
        this.rows = temp;
        // Whenever the filter changes, always go back to the first page
        this.table.offset = 0;
    }

}


export interface Chart {
    type: ChartType;
    data: Chartist.IChartistData;
    options?: any;
    responsiveOptions?: any;
    events?: ChartEvent;
}


ngOnInit(): void {
        this.nombre$ = localStorage.getItem('nombre');
        this.emprendimientoService.obtenerEmprendimientos()
        .subscribe(
          data => {
            console.log(data);
            this.emprendimientos$ = data;
            this.temp = data;
            this.rows = data;
          },
          error => {}
        );
    }


updateFilter(event) {
        //this.piarescolarItem = null;
        const val = event.target.value.toLowerCase();

        // filter our data
        const temp = this.temp.filter(function (d) {
            return d.nombre.toString().toLowerCase().indexOf(val) !== -1 || !val;
        });

        // update the rows
        this.rows = temp;
        // Whenever the filter changes, always go back to the first page
        this.table.offset = 0;
    }


export default function getFieldValue<Data extends DataType>(
  fields: FieldsObject<Data>,
  { type, name, options, checked, value }: Ref,
): FieldValue {
  if (isRadioInput(type)) {
    const fieldValue = fields[name];
    if (!fieldValue) throw new Error(`Expected ${name} field is missing`);

    return getRadioValue(fieldValue.options).value;
  }

  if (type === 'select-multiple') return getMultipleSelectValue(options);

  if (isCheckBox(type)) return checked ? value || checked : false;

  return value;
}


/**
 * Describes a contract consumable by Truffle, possibly including deployed instances on networks
 */
export interface ContractObject {
  /**
   * Name used to identify the contract
   */
  contractName?: string;
  abi: Abi;
  metadata?: Metadata;
  /**
   * Bytecode sent as contract-creation transaction data, with unresolved link references
   */
  bytecode?: string;
  /**
   * On-chain deployed contract bytecode, with unresolved link references
   */
  deployedBytecode?: string;
  /**
   * Source mapping for contract-creation transaction data bytecode
   */
  sourceMap?: string;
  /**
   * Source mapping for contract bytecode
   */
  deployedSourceMap?: string;
  source?: Source;
  sourcePath?: SourcePath;
  ast?: Ast;
  legacyAST?: LegacyAst;
  compiler?: {
    name?: string;
    version?: string;
    [k: string]: any;
  };
  networks?: {
    [k: string]: NetworkObject;
  };
  schemaVersion?: SchemaVersion;
  updatedAt?: string;
  networkType?: string;
  devdoc?: NatSpec;
  userdoc?: NatSpec;
  immutableReferences?: ImmutableReferences;
  generatedSources?: GeneratedSources;
  deployedGeneratedSources?: GeneratedSources;
  db?: {
    /**
     * Reference to @truffle/db canonical ID object for correlation purposes
     *
     * This interface was referenced by `undefined`'s JSON-Schema definition
     * via the `patternProperty` "^[a-zA-Z0-9]+$".
     */
    [k: string]: {
      id?: string;
      [k: string]: any;
    };
  };
  /**
   * This interface was referenced by `ContractObject`'s JSON-Schema definition
   * via the `patternProperty` "^x-".
   */
  [k: string]:
    | string
    | boolean
    | number
    | {
        [k: string]: any;
      }
    | any[];
}


export interface Ast {
  [k: string]: any;
}


export interface LegacyAst {
  [k: string]: any;
}


/**
 * This interface was referenced by `undefined`'s JSON-Schema definition
 * via the `patternProperty` "^[a-zA-Z0-9]+$".
 */
export interface NetworkObject {
  /**
   * This interface was referenced by `undefined`'s JSON-Schema definition
   * via the `patternProperty` "^[a-zA-Z_][a-zA-Z0-9_]*$".
   */
  address?: string;
  transactionHash?: string;
  events?: {
    /**
     * This interface was referenced by `undefined`'s JSON-Schema definition
     * via the `patternProperty` "^0x[a-fA-F0-9]{64}$".
     */
    [k: string]: {
      type: "event";
      name: string;
      inputs: {
        [k: string]: any;
      }[];
      anonymous: boolean;
    };
  };
  links?: {
    /**
     * This interface was referenced by `undefined`'s JSON-Schema definition
     * via the `patternProperty` "^[a-zA-Z_][a-zA-Z0-9_]*$".
     */
    [k: string]: string;
  };
  db?: {
    /**
     * Reference to @truffle/db canonical ID object for correlation purposes
     *
     * This interface was referenced by `undefined`'s JSON-Schema definition
     * via the `patternProperty` "^[a-zA-Z0-9]+$".
     */
    [k: string]: {
      id?: string;
      [k: string]: any;
    };
  };
}


export interface NatSpec {
  [k: string]: any;
}


export interface ImmutableReferences {
  /**
   * This interface was referenced by `ImmutableReferences`'s JSON-Schema definition
   * via the `patternProperty` "[1-9][0-9]*".
   */
  [k: string]: {
    start?: number;
    length?: number;
  }[];
}


/* tslint:disable */
/**
 * This file was automatically generated by json-schema-to-typescript.
 * DO NOT MODIFY IT BY HAND. Instead, modify the source JSONSchema file,
 * and run `yarn prepare` inside your local packages/contract-schema
 *
 * @module @truffle/contract-schema/spec
 */
/** */
/**
 * Interface description returned by compiler for source
 */
export type Abi = (
  | {
      type: "event";
      name: string;
      inputs: {
        [k: string]: any;
      }[];
      anonymous: boolean;
    }
  | (
      | {
          [k: string]: any;
        }
      | {
          [k: string]: any;
        }
    )
  | (
      | {
          [k: string]: any;
        }
      | {
          [k: string]: any;
        }
    )
  | {
      type: "receive";
      stateMutability: "payable";
    }
  | (
      | {
          [k: string]: any;
        }
      | {
          [k: string]: any;
        }
    )
)[];


export type Metadata = string;


export type Source = string;


export type SourcePath = string;


export type SchemaVersion = string;


export type GeneratedSources = {
  id?: number;
  language?: string;
  name?: string;
  contents?: string;
  ast?: {
    [k: string]: any;
  };
}[];


export function productRatingFlow(mobile?: string) {
  cy.server();
  createProductQuery('productQuery');
  createProductSortQuery('topRated', 'query-topRated');

  clickSearchIcon();
  const productName = 'DSC-N1';
  cy.get('cx-searchbox input').type(`${productName}{enter}`);

  cy.get(resultsTitle).should('contain', `17 results for "${productName}"`);

  cy.get(productSelector).should(
    'have.length',
    PRODUCT_LISTING.PRODUCTS_PER_PAGE
  );

  verifyProductSearch(
    '@productQuery',
    '@query-topRated',
    PRODUCT_LISTING.SORTING_TYPES.BY_TOP_RATED
  );

  // Navigate to previous page
  cy.get('.page-item:first-of-type .page-link:first').click();
  cy.wait('@query-topRated');

  cy.get('.page-item.active > .page-link').should('contain', '1');

  assertFirstProduct();

  // Filter by category
  cy.get('.cx-facet-header')
    .contains('Category')
    .parents('.cx-facet-group')
    .within(() => {
      cy.get('.cx-facet-checkbox')
        .first()
        .click({ force: true });
    });

  cy.wait('@productQuery');

  cy.get(resultsTitle).should('contain', '16 results for "DSC-N1"');
  assertFirstProduct();

  if (mobile) {
    cy.get(
      `cx-product-facet-navigation ${mobile} .cx-facet-filter-pill .close:first`
    ).click();
  } else {
    cy.get(
      'cx-product-facet-navigation .cx-facet-filter-pill .close:first'
    ).click();
  }
  cy.wait('@productQuery');

  cy.get(resultsTitle).should('contain', '17 results for "DSC-N1"');

  // Select product and read all the tabs on product details page
  cy.get('cx-product-list-item:first .cx-product-name').click();
  cy.get(tabsHeaderList)
    .eq(0)
    .should('contain', 'Product Details');
  cy.get(tabsHeaderList)
    .eq(1)
    .should('contain', 'Specs');
  cy.get(tabsHeaderList)
    .eq(2)
    .should('contain', 'Reviews');
  cy.get(tabsHeaderList)
    .eq(3)
    .should('contain', 'Shipping');
}


() => {
      cy.get('.cx-facet-checkbox')
        .first()
        .click({ force: true });
    }


@Component({
    templateUrl: './scrollpaneldemo.html',
    styles: [`
        .custombar1 .ui-scrollpanel-wrapper {
            border-right: 9px solid #f4f4f4;
        }

        .custombar1 .ui-scrollpanel-bar {
            background-color: #1976d2;
            opacity: 1;
            transition: background-color .3s;
        }

        .custombar1 .ui-scrollpanel-bar:hover {
            background-color: #135ba1;
        }

        .custombar2 .ui-scrollpanel-wrapper {
            border-right: 9px solid #757575;
            border-bottom: 9px solid #757575;
        }

        .custombar2 .ui-scrollpanel-bar {
            background-color: #68C77D;
            border-radius: 0;
            opacity: 1;
            transition: background-color .3s;
        }

        .custombar2:hover .ui-scrollpanel-bar {
            background-color: #46A55A;
        }
    `],
    encapsulation: ViewEncapsulation.None
})
export class ScrollPanelDemo {

}


class UserRepository implements IUserRepository {
    private repository: Repository<User>;

    constructor() {
        this.repository = getRepository(User);
    }

    async create({
        name,
        email,
        password,
        id_info,
    }: ICreateUserDTO): Promise<void> {
        const user = this.repository.create({
            name,
            email,
            password,
            id_info,
        });
        await this.repository.save(user);
    }

    async findByEmail(email: string): Promise<User> {
        const user = await this.repository.findOne({ email });

        return user;
    }

    async findById(id: string): Promise<User> {
        const user = await this.repository.findOne(id);
        return user;
    }

    async softDelete(id: string): Promise<void> {
        await this.repository.softDelete(id);
    }
}


async create({
        name,
        email,
        password,
        id_info,
    }: ICreateUserDTO): Promise<void> {
        const user = this.repository.create({
            name,
            email,
            password,
            id_info,
        });
        await this.repository.save(user);
    }


async findByEmail(email: string): Promise<User> {
        const user = await this.repository.findOne({ email });

        return user;
    }


async findById(id: string): Promise<User> {
        const user = await this.repository.findOne(id);
        return user;
    }


async softDelete(id: string): Promise<void> {
        await this.repository.softDelete(id);
    }


/**
 * Handle various kinds of attributes and make them conform to JSX.
 * - {x}   --->    x={x}
 * - x="{..}"   --->    x={..}
 * - lowercase DOM attributes
 * - multi-value handling
 */
export function handleAttribute(htmlx: string, str: MagicString, attr: Node, parent: Node): void {
    let transformedFromDirectiveOrNamespace = false;

    //if we are on an "element" we are case insensitive, lowercase to match our JSX
    if (parent.type == 'Element') {
        const sapperLinkActions = ['sapper:prefetch', 'sapper:noscroll'];
        //skip Attribute shorthand, that is handled below
        if (
            (attr.value !== true &&
                !(
                    attr.value.length &&
                    attr.value.length == 1 &&
                    attr.value[0].type == 'AttributeShorthand'
                )) ||
            sapperLinkActions.includes(attr.name)
        ) {
            let name = attr.name;
            if (!svgAttributes.find((x) => x == name)) {
                name = name.toLowerCase();
            }

            //strip ":" from out attribute name and uppercase the next letter to convert to jsx attribute
            const colonIndex = name.indexOf(':');
            if (colonIndex >= 0) {
                const parts = name.split(':');
                name = parts[0] + parts[1][0].toUpperCase() + parts[1].substring(1);
            }

            str.overwrite(attr.start, attr.start + attr.name.length, name);

            transformedFromDirectiveOrNamespace = true;
        }
    }

    //we are a bare attribute
    if (attr.value === true) {
        if (
            parent.type === 'Element' &&
            !transformedFromDirectiveOrNamespace &&
            parent.name !== '!DOCTYPE'
        ) {
            str.overwrite(attr.start, attr.end, attr.name.toLowerCase());
        }
        return;
    }

    if (attr.value.length == 0) return; //wut?
    //handle single value
    if (attr.value.length == 1) {
        const attrVal = attr.value[0];

        if (attr.name == 'slot') {
            str.remove(attr.start, attr.end);
            return;
        }

        if (attrVal.type == 'AttributeShorthand') {
            let attrName = attrVal.expression.name;
            if (parent.type == 'Element') {
                // eslint-disable-next-line max-len
                attrName = svgAttributes.find((a) => a == attrName)
                    ? attrName
                    : attrName.toLowerCase();
            }

            str.appendRight(attr.start, `${attrName}=`);
            return;
        }

        const equals = htmlx.lastIndexOf('=', attrVal.start);
        if (attrVal.type == 'Text') {
            const endsWithQuote =
                htmlx.lastIndexOf('"', attrVal.end) === attrVal.end - 1 ||
                htmlx.lastIndexOf("'", attrVal.end) === attrVal.end - 1;
            const needsQuotes = attrVal.end == attr.end && !endsWithQuote;

            const hasBrackets =
                htmlx.lastIndexOf('}', attrVal.end) === attrVal.end - 1 ||
                htmlx.lastIndexOf('}"', attrVal.end) === attrVal.end - 1 ||
                htmlx.lastIndexOf("}'", attrVal.end) === attrVal.end - 1;
            const needsNumberConversion =
                !hasBrackets &&
                parent.type === 'Element' &&
                numberOnlyAttributes.has(attr.name.toLowerCase()) &&
                !isNaN(attrVal.data);

            if (needsNumberConversion) {
                if (needsQuotes) {
                    str.prependRight(equals + 1, '{');
                    str.appendLeft(attr.end, '}');
                } else {
                    str.overwrite(equals + 1, equals + 2, '{');
                    str.overwrite(attr.end - 1, attr.end, '}');
                }
            } else if (needsQuotes) {
                str.prependRight(equals + 1, '"');
                str.appendLeft(attr.end, '"');
            }
            return;
        }

        if (attrVal.type == 'MustacheTag') {
            //if the end doesn't line up, we are wrapped in quotes
            if (attrVal.end != attr.end) {
                str.remove(attrVal.start - 1, attrVal.start);
                str.remove(attr.end - 1, attr.end);
            }
            return;
        }
        return;
    }

    // we have multiple attribute values, so we build a string out of them.
    // technically the user can do something funky like attr="text "{value} or even attr=text{value}
    // so instead of trying to maintain a nice sourcemap with prepends etc, we just overwrite the whole thing

    const equals = htmlx.lastIndexOf('=', attr.value[0].start);
    str.overwrite(equals, attr.value[0].start, '={`');

    for (const n of attr.value) {
        if (n.type == 'MustacheTag') {
            str.appendRight(n.start, '$');
        }
    }

    if (htmlx[attr.end - 1] == '"') {
        str.overwrite(attr.end - 1, attr.end, '`}');
    } else {
        str.appendLeft(attr.end, '`}');
    }
}


(x) => x == name


(a) => a == attrName


() => {
  harness.browser.i18n();

  it('should get country name for DK', () => {
    expect(countryService.getName('DK')).toBe('Denmark');
  });

  it('should get country name for UA', () => {
    expect(countryService.getName('UA')).toBe('Ukraine');
  });

  it('should get country name given mixed case "Ua"', () => {
    expect(countryService.getName('Ua')).toBe('Ukraine');
  });
}


() => {
    expect(countryService.getName('DK')).toBe('Denmark');
  }


() => {
    expect(countryService.getName('UA')).toBe('Ukraine');
  }


() => {
    expect(countryService.getName('Ua')).toBe('Ukraine');
  }


() => {
  test('returns empty string as invalid date', () => {
    expect(getMaybeDate('').isValid()).toBe(false);
  });

  test('returns string with empty spaces as invalid date', () => {
    expect(getMaybeDate('  ').isValid()).toBe(false);
  });

  test('returns string date time as valid date', () => {
    expect(getMaybeDate('2019-05-28T23:05:28.405Z').isValid()).toBe(true);
  });

  test('returns string date time as the date we expect', () => {
    expect(getMaybeDate('2019-05-28T23:05:28.405Z').toISOString()).toBe('2019-05-28T23:05:28.405Z');
  });

  test('returns plain string number as epoch as valid date', () => {
    expect(getMaybeDate('1559084770612').isValid()).toBe(true);
  });

  test('returns plain string number as the date we expect', () => {
    expect(
      getMaybeDate('1559084770612')
        .toDate()
        .toISOString()
    ).toBe('2019-05-28T23:06:10.612Z');
  });

  test('returns plain number as epoch as valid date', () => {
    expect(getMaybeDate(1559084770612).isValid()).toBe(true);
  });

  test('returns plain number as epoch as the date we expect', () => {
    expect(
      getMaybeDate(1559084770612)
        .toDate()
        .toISOString()
    ).toBe('2019-05-28T23:06:10.612Z');
  });

  test('returns a short date time string as an epoch (sadly) so this is ambiguous', () => {
    expect(
      getMaybeDate('20190101')
        .toDate()
        .toISOString()
    ).toBe('1970-01-01T05:36:30.101Z');
  });
}


() => {
    expect(getMaybeDate('').isValid()).toBe(false);
  }


() => {
    expect(getMaybeDate('  ').isValid()).toBe(false);
  }


() => {
    expect(getMaybeDate('2019-05-28T23:05:28.405Z').isValid()).toBe(true);
  }


() => {
    expect(getMaybeDate('2019-05-28T23:05:28.405Z').toISOString()).toBe('2019-05-28T23:05:28.405Z');
  }


() => {
    expect(getMaybeDate('1559084770612').isValid()).toBe(true);
  }


() => {
    expect(
      getMaybeDate('1559084770612')
        .toDate()
        .toISOString()
    ).toBe('2019-05-28T23:06:10.612Z');
  }


() => {
    expect(getMaybeDate(1559084770612).isValid()).toBe(true);
  }


() => {
    expect(
      getMaybeDate(1559084770612)
        .toDate()
        .toISOString()
    ).toBe('2019-05-28T23:06:10.612Z');
  }


() => {
    expect(
      getMaybeDate('20190101')
        .toDate()
        .toISOString()
    ).toBe('1970-01-01T05:36:30.101Z');
  }


function lineTrim(p1: Coords, p2: Coords, space: number = 0) {
  var line = { p1: new Coords(), p2: new Coords() };
  if (p1.x < p2.x) {
    line.p1.x = space;
    line.p2.x = (p2.x - p1.x) + space;
  } else {
    line.p2.x = space;
    line.p1.x = (p1.x - p2.x) + space;
  }

  if (p1.y < p2.y) {
    line.p1.y = space;
    line.p2.y = (p2.y - p1.y) + space;
  } else {
    line.p2.y = space;
    line.p1.y = (p1.y - p2.y) + space;
  }
  return line;
}


/// <reference path="../../bower_components/polymer-ts/polymer-ts.d.ts"/>
class Coords {
  constructor(public x: number = 0, public y: number = 0) {
  }
  getCenteredBy(p1: Coords, space: number = 0) {
    var p2 = new Coords(this.x, this.y);
    p2.x = p2.x - p1.x + space;
    p2.y = p2.y - p1.y + space;
    return p2;
  }
  moveToDir(dir: String, angulation: number) {
    var point: Coords;
    if (dir == "left") {
      point = new Coords(this.x - angulation, this.y);
    } else if (dir == "up") {
      point = new Coords(this.x, this.y - angulation);
    } else if (dir == "down") {
      point = new Coords(this.x, this.y + angulation);
    } else {
      point = new Coords(this.x + angulation, this.y);
    }
    return point;
  }

  between(point: Coords):Coords {
    var b = new Coords();
    b.x = (this.x + point.x) / 2.0;
    b.y = (this.y + point.y) / 2.0;
    return b;
  }
}


class Curve {
  start: Coords;
  p1: Coords;
  p2: Coords;
  middle: Coords;
  p3: Coords;
  p4: Coords;
  end: Coords;
  label1: Coords;
  label2: Coords;
  advanced: boolean;

  constructor() {
    this.start = new Coords();
    this.p1 = new Coords();
    this.middle = new Coords();
    this.p2 = new Coords();
    this.end = new Coords();
    this.label1 = new Coords();
    this.label2 = new Coords();
  }

  toString() {
    var str: String;

    if(this.advanced) {
      str = "M" + this.start.x + "," + this.start.y + " C";
      str += this.p1.x + "," + this.p1.y + " ";
      str += this.p2.x + "," + this.p2.y + " ";
      str += this.middle.x + "," + this.middle.y + " M";
      str += this.middle.x + "," + this.middle.y + " C";
      str += this.p3.x + "," + this.p3.y + " ";
      str += this.p4.x + "," + this.p4.y + " ";
      str += this.end.x + "," + this.end.y + " ";
    } else {
      str = "M" + this.start.x + "," + this.start.y + " C";
      str += this.p1.x + "," + this.p1.y + " ";
      str += this.p1.x + "," + this.p1.y + " ";
      str += this.middle.x + "," + this.middle.y + " S";
      str += this.p4.x + "," + this.p4.y + " ";
      str += this.end.x + "," + this.end.y + " ";
    }
    return str;
  }
}


@component('connection-view')
class ConnectionView extends polymer.Base {
  static space = 100;
  static angulation = 50;

  @property({ type: Number })
  x1: number;

  @property({ type: Number })
  y1: number;

  @property({ type: String })
  dir1: string;

  @property({ type: Number })
  x2: number;

  @property({ type: Number })
  y2: number;

  @property({ type: String })
  dir2: string;

  @property({ type: String, notify: true })
  name: String;

  @property({ type: String, notify: true})
  car1: String;

  @property({ type: String, notify: true})
  car2: String;

  @property({computed: 'x1, y1, x2, y2, dir1, dir2'})
  frame(x1, y1, x2, y2, dir1, dir2): Coords {
    var frameCors = new Coords();
    var frame = this.$.frame;
    var svg = this.$.svg;

    if (x1 < x2) {
      frameCors.x = (x1 - ConnectionView.space);
    } else {
      frameCors.x = (x2 - ConnectionView.space);
    }
    frame.style.left = frameCors.x + "px";

    if (y1 < y2) {
      frameCors.y = (y1 - ConnectionView.space);
    } else {
      frameCors.y = (y2 - ConnectionView.space);
    }

    frame.style.top = frameCors.y + "px";

    svg.setAttribute("width", (Math.abs(x1 - x2) + 2 * ConnectionView.space) + "px");
    svg.setAttribute("height", (Math.abs(y1 - y2) + 2 * ConnectionView.space) + "px");

    return frameCors;
  }

  @property({computed: 'x1, y1, x2, y2, dir1, dir2'})
  curve(x1, y1, x2, y2, dir1, dir2): Curve {
    var curve = new Curve();
    var diagonal = lineTrim(new Coords(x1, y1), new Coords(x2, y2), ConnectionView.space);
    curve.start = diagonal.p1;
    curve.end = diagonal.p2;

    curve.advanced = (dir1 == "left" && dir2 == "down");

    if(curve.advanced) {
      curve.p1 = curve.start.moveToDir(dir1, ConnectionView.angulation);
      curve.p4 = curve.end.moveToDir(dir2, ConnectionView.angulation);

      var distanceX = curve.p4.x - curve.p1.x;
      var distanceY = curve.p4.y - curve.p1.y;

      var control1 = curve.p1.moveToDir(dir2, distanceY);
      var control2 = curve.p4.moveToDir(dir1, distanceX);
      var corner = control1.between(control2);

      var C = Math.sqrt(distanceX * distanceX + distanceY * distanceY);

      var c = ConnectionView.angulation * 2.0;

      if(c > C/2) {
        c = C/2;
      }

      var sinc = 1;
      var sina = distanceX / C;
      var sinb = distanceY / C;

      var a = c * (sina / sinc);
      var b = c * (sinb / sinc);

      var moveX = a;
      var moveY = b;

      curve.p2 = corner.moveToDir(dir2, -moveY);
      curve.p3 = corner.moveToDir(dir1, -moveX);

      curve.middle = curve.p2.between(curve.p3);
    } else {
      curve.p1 = curve.start.moveToDir(dir1, ConnectionView.angulation);
      curve.p4 = curve.end.moveToDir(dir2, ConnectionView.angulation);

      curve.middle.x = (curve.p1.x + curve.p4.x) / 2.0;
      curve.middle.y = (curve.p1.y + curve.p4.y) / 2.0;
    }

    curve.label1 = curve.start.moveToDir(dir1, 5);
    curve.label2 = curve.end.moveToDir(dir2, 5);

    return curve;
  }

  @property({computed: 'curve, frame'})
  middle(curve, frame): Coords {
    var middle = new Coords();
    middle.x = frame.x + curve.middle.x;
    middle.y = frame.y + curve.middle.y;
    return middle;
  }

  @property({computed: 'curve'})
  curveString(curve): string {
    return curve.toString();
  }

  handleDelete(e) {
    this.fire("delete");
  }
}


getCenteredBy(p1: Coords, space: number = 0) {
    var p2 = new Coords(this.x, this.y);
    p2.x = p2.x - p1.x + space;
    p2.y = p2.y - p1.y + space;
    return p2;
  }


moveToDir(dir: String, angulation: number) {
    var point: Coords;
    if (dir == "left") {
      point = new Coords(this.x - angulation, this.y);
    } else if (dir == "up") {
      point = new Coords(this.x, this.y - angulation);
    } else if (dir == "down") {
      point = new Coords(this.x, this.y + angulation);
    } else {
      point = new Coords(this.x + angulation, this.y);
    }
    return point;
  }


between(point: Coords):Coords {
    var b = new Coords();
    b.x = (this.x + point.x) / 2.0;
    b.y = (this.y + point.y) / 2.0;
    return b;
  }


toString() {
    var str: String;

    if(this.advanced) {
      str = "M" + this.start.x + "," + this.start.y + " C";
      str += this.p1.x + "," + this.p1.y + " ";
      str += this.p2.x + "," + this.p2.y + " ";
      str += this.middle.x + "," + this.middle.y + " M";
      str += this.middle.x + "," + this.middle.y + " C";
      str += this.p3.x + "," + this.p3.y + " ";
      str += this.p4.x + "," + this.p4.y + " ";
      str += this.end.x + "," + this.end.y + " ";
    } else {
      str = "M" + this.start.x + "," + this.start.y + " C";
      str += this.p1.x + "," + this.p1.y + " ";
      str += this.p1.x + "," + this.p1.y + " ";
      str += this.middle.x + "," + this.middle.y + " S";
      str += this.p4.x + "," + this.p4.y + " ";
      str += this.end.x + "," + this.end.y + " ";
    }
    return str;
  }


@property({computed: 'x1, y1, x2, y2, dir1, dir2'})
  frame(x1, y1, x2, y2, dir1, dir2): Coords {
    var frameCors = new Coords();
    var frame = this.$.frame;
    var svg = this.$.svg;

    if (x1 < x2) {
      frameCors.x = (x1 - ConnectionView.space);
    } else {
      frameCors.x = (x2 - ConnectionView.space);
    }
    frame.style.left = frameCors.x + "px";

    if (y1 < y2) {
      frameCors.y = (y1 - ConnectionView.space);
    } else {
      frameCors.y = (y2 - ConnectionView.space);
    }

    frame.style.top = frameCors.y + "px";

    svg.setAttribute("width", (Math.abs(x1 - x2) + 2 * ConnectionView.space) + "px");
    svg.setAttribute("height", (Math.abs(y1 - y2) + 2 * ConnectionView.space) + "px");

    return frameCors;
  }


@property({computed: 'x1, y1, x2, y2, dir1, dir2'})
  curve(x1, y1, x2, y2, dir1, dir2): Curve {
    var curve = new Curve();
    var diagonal = lineTrim(new Coords(x1, y1), new Coords(x2, y2), ConnectionView.space);
    curve.start = diagonal.p1;
    curve.end = diagonal.p2;

    curve.advanced = (dir1 == "left" && dir2 == "down");

    if(curve.advanced) {
      curve.p1 = curve.start.moveToDir(dir1, ConnectionView.angulation);
      curve.p4 = curve.end.moveToDir(dir2, ConnectionView.angulation);

      var distanceX = curve.p4.x - curve.p1.x;
      var distanceY = curve.p4.y - curve.p1.y;

      var control1 = curve.p1.moveToDir(dir2, distanceY);
      var control2 = curve.p4.moveToDir(dir1, distanceX);
      var corner = control1.between(control2);

      var C = Math.sqrt(distanceX * distanceX + distanceY * distanceY);

      var c = ConnectionView.angulation * 2.0;

      if(c > C/2) {
        c = C/2;
      }

      var sinc = 1;
      var sina = distanceX / C;
      var sinb = distanceY / C;

      var a = c * (sina / sinc);
      var b = c * (sinb / sinc);

      var moveX = a;
      var moveY = b;

      curve.p2 = corner.moveToDir(dir2, -moveY);
      curve.p3 = corner.moveToDir(dir1, -moveX);

      curve.middle = curve.p2.between(curve.p3);
    } else {
      curve.p1 = curve.start.moveToDir(dir1, ConnectionView.angulation);
      curve.p4 = curve.end.moveToDir(dir2, ConnectionView.angulation);

      curve.middle.x = (curve.p1.x + curve.p4.x) / 2.0;
      curve.middle.y = (curve.p1.y + curve.p4.y) / 2.0;
    }

    curve.label1 = curve.start.moveToDir(dir1, 5);
    curve.label2 = curve.end.moveToDir(dir2, 5);

    return curve;
  }


@property({computed: 'curve, frame'})
  middle(curve, frame): Coords {
    var middle = new Coords();
    middle.x = frame.x + curve.middle.x;
    middle.y = frame.y + curve.middle.y;
    return middle;
  }


@property({computed: 'curve'})
  curveString(curve): string {
    return curve.toString();
  }


handleDelete(e) {
    this.fire("delete");
  }


function loadCasesAssignedList() {
                if (self.personId()) {
                    _casesAssignedList.queryString = "filter.AssignedToId=" + self.personId();
                    _casesAssignedList.load();
                }
            }


function loadCasesReportedList() {
                if (self.personId()) {
                    _casesReportedList.queryString = "filter.ReportedById=" + self.personId();
                    _casesReportedList.load();
                }
            }


() => {
            for (var i = 0; i < this.titleValues.length; i++) {
                if (this.titleValues[i].id == this.title()) {
                    return this.titleValues[i].value;
                }
            }
            return null;
        }


() => {
            for (var i = 0; i < this.genderValues.length; i++) {
                if (this.genderValues[i].id == this.gender()) {
                    return this.genderValues[i].value;
                }
            }
            return null;
        }


(autoSave?: boolean | null): Case => {
            var newItem = new Case();
            if (typeof(autoSave) == 'boolean'){
                newItem.coalesceConfig.autoSaveEnabled(autoSave);
            }
            newItem.parent = this;
            newItem.parentCollection = this.casesAssigned;
            newItem.isExpanded(true);
            newItem.assignedToId(this.personId());
            this.casesAssigned.push(newItem);
            return newItem;
        }


(autoSave?: boolean | null): Case => {
            var newItem = new Case();
            if (typeof(autoSave) == 'boolean'){
                newItem.coalesceConfig.autoSaveEnabled(autoSave);
            }
            newItem.parent = this;
            newItem.parentCollection = this.casesReported;
            newItem.isExpanded(true);
            newItem.reportedById(this.personId());
            this.casesReported.push(newItem);
            return newItem;
        }


() => this.coalesceConfig.baseViewUrl() + '/Case/Table?filter.assignedToId=' + this.personId()


() => this.coalesceConfig.baseViewUrl() + '/Case/Table?filter.reportedById=' + this.personId()


(name: string | null, callback?: (result: ViewModels.Person) => void, reload: boolean = true): JQueryPromise<any> => {
                return this.invokeWithData({ id: this.parent[this.parent.primaryKeyName](), name: name }, callback, reload);
            }


(args = this.args, callback?: (result: ViewModels.Person) => void, reload: boolean = true): JQueryPromise<any> => {
                return this.invoke(args.name(), callback, reload);
            }


(callback?: (result: ViewModels.Person) => void, reload: boolean = true): JQueryPromise<any> | undefined => {
                var $promptVal: string | null = null;
                $promptVal = prompt('Name');
                if ($promptVal === null) return;
                var name: string = $promptVal;
                return this.invoke(name, callback, reload);
            }


(data: Coalesce.ItemResult, callback?: (result: ViewModels.Person) => void, reload: boolean = true) => {
                if (!this.result()) {
                    this.result(new ViewModels.Person(data.object));
                } else {
                    this.result().loadFromDto(data.object);
                }
                this.parent.loadFromDto(data.object, true)
                if (typeof(callback) == 'function') {
                    callback(this.result());
                }
            }


(callback?: (result: void) => void, reload: boolean = true): JQueryPromise<any> => {
                return this.invokeWithData({ id: this.parent[this.parent.primaryKeyName]() }, callback, reload);
            }


(data: Coalesce.ItemResult, callback?: (result: void) => void, reload: boolean = true) => {
                this.result(data.object);
                if (reload) {
                    var result = this.result();
                    this.parent.load(null, typeof(callback) == 'function' ? () => callback(result) : undefined);
                } else if (typeof(callback) == 'function') {
                    callback(this.result());
                }
            }


() => callback(result)


(callback?: (result: string) => void, reload: boolean = true): JQueryPromise<any> => {
                return this.invokeWithData({ id: this.parent[this.parent.primaryKeyName](),  }, callback, reload);
            }


(data: Coalesce.ItemResult, callback?: (result: string) => void, reload: boolean = true) => {
                this.result(data.object);
                if (reload) {
                    var result = this.result();
                    this.parent.load(null, typeof(callback) == 'function' ? () => callback(result) : undefined);
                } else if (typeof(callback) == 'function') {
                    callback(this.result());
                }
            }


(firstName: string | null, title: number | null, callback?: (result: ViewModels.Person) => void, reload: boolean = true): JQueryPromise<any> => {
                return this.invokeWithData({ id: this.parent[this.parent.primaryKeyName](), firstName: firstName, title: title }, callback, reload);
            }


(args = this.args, callback?: (result: ViewModels.Person) => void, reload: boolean = true): JQueryPromise<any> => {
                return this.invoke(args.firstName(), args.title(), callback, reload);
            }


(callback?: (result: ViewModels.Person) => void, reload: boolean = true): JQueryPromise<any> | undefined => {
                var $promptVal: string | null = null;
                $promptVal = prompt('First Name');
                if ($promptVal === null) return;
                var firstName: string = $promptVal;
                $promptVal = prompt('Title');
                if ($promptVal === null) return;
                var title: number = parseInt($promptVal);
                return this.invoke(firstName, title, callback, reload);
            }


(person: ViewModels.Person | null, callback?: (result: ViewModels.Person) => void, reload: boolean = true): JQueryPromise<any> => {
                return this.invokeWithData({ person: person ? person.saveToDto() : null }, callback, reload);
            }


(args = this.args, callback?: (result: ViewModels.Person) => void, reload: boolean = true): JQueryPromise<any> => {
                return this.invoke(args.person(), callback, reload);
            }


(callback?: (result: ViewModels.Person) => void, reload: boolean = true): JQueryPromise<any> | undefined => {
                var $promptVal: string | null = null;
                var person: null = null;
                return this.invoke(person, callback, reload);
            }


(data: any, force: boolean = false, allowCollectionDeletes: boolean = true): void => {
            if (!data || (!force && this.isLoading())) return;
            this.isLoading(true);
            // Set the ID
            this.myId = data.personId;
            this.personId(data.personId);
            // Load the lists of other objects
            if (data.casesAssigned != null) {
                // Merge the incoming array
                Coalesce.KnockoutUtilities.RebuildArray(this.casesAssigned, data.casesAssigned, 'caseKey', Case, this, allowCollectionDeletes);
            }
            if (data.casesReported != null) {
                // Merge the incoming array
                Coalesce.KnockoutUtilities.RebuildArray(this.casesReported, data.casesReported, 'caseKey', Case, this, allowCollectionDeletes);
            }
            if (data.arbitraryCollectionOfStrings != null) {
                this.arbitraryCollectionOfStrings(data.arbitraryCollectionOfStrings);
            }
            if (!data.personStats) {
                this.personStats(null);
            } else {
                if (!this.personStats()){
                    this.personStats(new PersonStats(data.personStats, this));
                } else {
                    this.personStats()!.loadFromDto(data.personStats);
                }
            }
            if (!data.company) {
                if (data.companyId != this.companyId()) {
                    this.company(null);
                }
            } else {
                if (!this.company()){
                    this.company(new Company(data.company, this));
                } else {
                    this.company()!.loadFromDto(data.company);
                }
                if (this.parent instanceof Company && this.parent !== this.company() && this.parent.companyId() == this.company()!.companyId())
                {
                    this.parent.loadFromDto(data.company, undefined, false);
                }
            }

            // The rest of the objects are loaded now.
            this.title(data.title);
            this.firstName(data.firstName);
            this.lastName(data.lastName);
            this.email(data.email);
            this.gender(data.gender);
            if (data.birthDate == null) this.birthDate(null);
            else if (this.birthDate() == null || this.birthDate()!.valueOf() != new Date(data.birthDate).getTime()){
                this.birthDate(moment(new Date(data.birthDate)));
            }
            if (data.lastBath == null) this.lastBath(null);
            else if (this.lastBath() == null || this.lastBath()!.valueOf() != new Date(data.lastBath).getTime()){
                this.lastBath(moment(new Date(data.lastBath)));
            }
            if (data.nextUpgrade == null) this.nextUpgrade(null);
            else if (this.nextUpgrade() == null || this.nextUpgrade()!.valueOf() != new Date(data.nextUpgrade).getTime()){
                this.nextUpgrade(moment(new Date(data.nextUpgrade)));
            }
            this.name(data.name);
            this.companyId(data.companyId);
            this.arbitraryCollectionOfStrings(data.arbitraryCollectionOfStrings);
            if (this.coalesceConfig.onLoadFromDto()){
                this.coalesceConfig.onLoadFromDto()(this as any);
            }
            this.isLoading(false);
            this.isDirty(false);
            if (this.coalesceConfig.validateOnLoadFromDto()) this.validate();
        }


(): any => {
            var dto: any = {};
            dto.personId = this.personId();

            dto.title = this.title();
            dto.firstName = this.firstName();
            dto.lastName = this.lastName();
            dto.email = this.email();
            dto.gender = this.gender();
            if (!this.birthDate()) dto.birthDate = null;
            else dto.birthDate = this.birthDate()!.format('YYYY-MM-DDTHH:mm:ss');
            if (!this.lastBath()) dto.lastBath = null;
            else dto.lastBath = this.lastBath()!.format('YYYY-MM-DDTHH:mm:ss');
            if (!this.nextUpgrade()) dto.nextUpgrade = null;
            else dto.nextUpgrade = this.nextUpgrade()!.format('YYYY-MM-DDTHH:mm:ssZZ');
            dto.companyId = this.companyId();
            if (!dto.companyId && this.company()) {
                dto.companyId = this.company()!.companyId();
            }
            dto.arbitraryCollectionOfStrings = this.arbitraryCollectionOfStrings();

            return dto;
        }


(callback?: () => void): void => {
            var loadingCount = 0;
            // See if this.company needs to be loaded.
            if (this.company() == null && this.companyId() != null) {
                loadingCount++;
                var companyObj = new Company();
                companyObj.load(this.companyId(), () => {
                    loadingCount--;
                    this.company(companyObj);
                    if (loadingCount == 0 && typeof(callback) == "function") { callback(); }
                });
            }
            if (loadingCount == 0 && typeof(callback) == "function") { callback(); }
        }


() => {
                    loadingCount--;
                    this.company(companyObj);
                    if (loadingCount == 0 && typeof(callback) == "function") { callback(); }
                }


export enum TitleEnum {
            Mr = 0,
            Ms = 1,
            Mrs = 2,
            Miss = 4,
        }


export enum GenderEnum {
            NonSpecified = 0,
            Male = 1,
            Female = 2,
        }


public setupValidation(): void {
            if (this.errors !== null) return;
            this.errors = ko.validation.group([
                this.firstName.extend({ minLength: 2, maxLength: 75 }),
                this.lastName.extend({ minLength: 3, maxLength: 100 }),
                this.birthDate.extend({ moment: { unix: true } }),
                this.lastBath.extend({ moment: { unix: true } }),
                this.nextUpgrade.extend({ moment: { unix: true } }),
                this.companyId.extend({ required: {params: true, message: "Company is required."} }),
            ]);
            this.warnings = ko.validation.group([
            ]);
        }


({
  profile: {
    name,
    username,
    biography,
    github,
    twitter,
    linkedin,
    picture,
    cover
  }
}: HeaderProps) => {
  return (

        <Image
          src={cover.url}
          placeholder="blur"
          blurDataURL={cover.url}
          layout="fill"
          objectFit="cover"
          alt="Cover picture"
          priority
        />

              <Image
                src={picture.url}
                className="transition-all duration-300 ease-in"
                placeholder="blur"
                blurDataURL={picture.url}
                layout="fill"
                objectFit="cover"
                alt={name}
                priority
              />

                <Button className="bg-medium-state-blue text-white hover:border-medium-state-blue-dark hover:bg-medium-state-blue-dark">
                  Resume
                </Button>

            {name}

              @{username}

              {biography}

                <Link href={github}>

                    <GitHubIcon className="h-6 w-6 text-white" />

                </Link>

                <Link href={twitter}>

                    <TwitterIcon className="h-6 w-6 text-white" />

                </Link>

                <Link href={linkedin}>

                    <LinkedinIcon className="h-6 w-6 text-white" />

                </Link>


type HeaderProps = {
  profile: Profile;
};


products => {
      this.products = products;
    }


@Component({
  selector: 'app-product-read',
  templateUrl: './product-read.component.html',
  styleUrls: ['./product-read.component.css']
})
export class ProductReadComponent implements OnInit {

  products: Product[];
  displayedColumns = ['id', 'name', 'price', 'action'];

  constructor(private productService: ProductService) { }

  ngOnInit(): void {
    this.productService.read().subscribe(products => {
      this.products = products;
    });
  }

}


ngOnInit(): void {
    this.productService.read().subscribe(products => {
      this.products = products;
    });
  }


(accessToken: string, refreshToken: string, user: User, verified: VerifyCallback) => {
        console.log("[OAuth2Strategy] applied, accessToken: " + accessToken + " and user: " + JSON.stringify(user));
        verified(undefined, user, { accessToken: accessToken });
    }


export class IfStatement extends Statement {
    readonly kind:string
    readonly begin:Lex
    readonly end:Lex
    readonly boolExp:Expression
    readonly trueStatement:Statement
    readonly falseStatement?:Statement
    constructor(begin:Lex, end:Lex, boolExp:Expression, trueStatement:Statement, falseStatement?:Statement){
        super()
        this.kind = 'If'
        this.begin = begin
        this.end = end
        this.boolExp = boolExp
        this.trueStatement = trueStatement
        this.falseStatement = falseStatement
    }
}


() => {
      TestBed.configureTestingModule({
         imports: [FormsModule, ReactiveFormsModule, StLabelModule, StClickOutsideModule],
         declarations: [StTagInputComponent],
         schemas: [NO_ERRORS_SCHEMA]
      })
         .overrideComponent(StTagInputComponent, {
            set: { changeDetection: ChangeDetectionStrategy.Default }
         })
         .compileComponents();  // compile template and css
   }


() => {
      fixture = TestBed.createComponent(StTagInputComponent);
      comp = fixture.componentInstance;
   }


() => {
      (fixture.elementRef.nativeElement as HTMLElement).id = null;
      fixture.detectChanges();

      expect(comp.label).toBeNull();
      expect(comp.placeholder).toBeNull();
      expect(comp.tooltip).toBeNull();
      expect(comp.errorMessage).toBeNull();
      expect(comp.withAutocomplete).toBeFalsy();
      expect(comp.autocompleteList).toEqual([]);

      expect(comp.innerInputContent).toEqual('');
      expect(comp.items).toEqual([]);
      expect(comp.expandedMenu).toBeFalsy();

      expect(comp.hasLabel).toBeFalsy();
      expect(comp.hasFocus).toBeFalsy();
      expect(comp.showError()).toBeFalsy();
      expect(comp.hasPlaceholder).toBeFalsy();
      expect(comp.hasAutocomplete).toBeFalsy();
      expect(comp.disableValue).toBeNull('');
      expect(comp.isValidInput).toBeTruthy();
      expect(comp.tagSelected).toBeNull();
      expect(comp.selectId).toBeNull();
      expect(comp.inputId).toBeNull();
      expect(comp.labelId).toBeNull();
      expect(comp.tagId).toBeNull();
      expect(comp.listId).toBeNull();
   }


() => {
      const id: string = 'test-id';
      (fixture.elementRef.nativeElement as HTMLElement).id = id;
      comp.label = 'Test Label';
      comp.items = _cloneDeep(simpleTags);
      fixture.detectChanges();

      const label: HTMLElement = fixture.debugElement.query(By.css('.st-label')).nativeElement;
      const tag: HTMLElement = fixture.debugElement.query(By.css('.tag-item')).nativeElement;
      const input: HTMLElement = fixture.debugElement.query(By.css('.inner-input')).nativeElement;
      const list: HTMLElement = fixture.debugElement.query(By.css('st-dropdown-menu')).nativeElement;

      expect(comp.selectId).toEqual(id);

      expect(comp.labelId).toEqual(`${id}-label`);
      expect(label.getAttribute('id')).toEqual(`${id}-label`);

      expect(comp.inputId).toEqual(`${id}-input`);
      expect(input.getAttribute('id')).toEqual(`${id}-input`);

      expect(comp.tagId).toEqual(`${id}-tag-`);
      expect(tag.getAttribute('id')).toContain(`${id}-tag-`);

      expect(comp.listId).toEqual(`${id}-autocomplete`);
      expect(list.getAttribute('id')).toContain(`${id}-autocomplete`);
   }


() => {
      fixture.detectChanges();
      let label: DebugElement = fixture.debugElement.query(By.css('.st-label'));
      expect(label).toBeNull();
      expect(comp.hasLabel).toBeFalsy();
   }


() => {
      comp.label = 'test label';
      comp.tooltip = 'Test help';
      fixture.detectChanges();

      const label: DebugElement = fixture.debugElement.query(By.css('.st-label'));

      expect(comp.hasLabel).toBeTruthy();
      expect(label).toBeDefined();
      expect(label.nativeElement).toBeDefined();
      expect((label.nativeElement as HTMLLabelElement).textContent).toEqual(comp.label);
      expect((label.nativeElement as HTMLLabelElement).title).toEqual(comp.tooltip);
   }


() => {
      comp.placeholder = 'Test help';
      fixture.detectChanges();

      expect(comp.hasPlaceholder).toBeTruthy();
   }


() => {
      comp.placeholder = 'Test help';
      comp.items = _cloneDeep(simpleTags);
      fixture.detectChanges();

      expect(comp.hasPlaceholder).toBeFalsy();
   }


() => {
      comp.placeholder = 'Test help';
      const id: string = 'test-id';
      (fixture.elementRef.nativeElement as HTMLElement).id = id;
      comp.label = 'Test';
      fixture.detectChanges();

      const input: HTMLInputElement = fixture.debugElement.query(By.css('.inner-input')).nativeElement;
      spyOn(input, 'focus');

      expect(comp.hasPlaceholder).toBeTruthy();
      expect(comp.hasFocus).toBeFalsy();
      expect(input.focus).not.toHaveBeenCalled();

      const container: HTMLLabelElement = fixture.debugElement.query(By.css('.st-input')).nativeElement;
      container.click();
      fixture.detectChanges();

      expect(comp.hasPlaceholder).toBeFalsy();
      expect(comp.hasFocus).toBeTruthy();
      expect(input.focus).toHaveBeenCalled();
   }


() => {
      const id: string = 'test-id';
      (fixture.elementRef.nativeElement as HTMLElement).id = id;
      comp.label = 'Test';
      comp.items = _cloneDeep(simpleTags);
      fixture.detectChanges();

      expect(comp.hasFocus).toBeFalsy();
      expect(comp.tagSelected).toBeNull();

      const tag: HTMLElement = fixture.debugElement.query(By.css('.tag-item')).nativeElement;
      tag.focus();
      fixture.detectChanges();
      expect(comp.hasFocus).toBeTruthy();
      expect(comp.tagSelected).toBeDefined();
   }


() => {
      const id: string = 'test-id';
      (fixture.elementRef.nativeElement as HTMLElement).id = id;
      comp.label = 'Test';
      comp.items = _cloneDeep(simpleTags);
      fixture.detectChanges();

      const tag: HTMLElement = fixture.debugElement.query(By.css('.tag-item')).nativeElement;
      const container: HTMLLabelElement = fixture.debugElement.query(By.css('.st-input')).nativeElement;
      spyOn(tag, 'click');
      spyOn(container, 'click');

      expect(tag.click).not.toHaveBeenCalled();
      expect(container.click).not.toHaveBeenCalled();

      tag.click();
      comp.onTagClick(new Event('ClickEvent'), 0);
      fixture.detectChanges();
      expect(tag.click).toHaveBeenCalled();
      expect(container.click).not.toHaveBeenCalled();
   }


() => {
      const id: string = 'test-id';
      (fixture.elementRef.nativeElement as HTMLElement).id = id;
      comp.label = 'Test';
      comp.items = _cloneDeep(simpleTags);
      fixture.detectChanges();

      expect(comp.hasFocus).toBeFalsy();
      expect(comp.tagSelected).toBeNull();
      expect(comp.items.length).toEqual(simpleTags.length);

      const tag: DebugElement = fixture.debugElement.query(By.css('.tag-item'));
      tag.nativeElement.focus();
      tag.triggerEventHandler('keydown', {
         keyCode: 46, preventDefault: () => {
         }
      });
      fixture.detectChanges();

      expect(comp.hasFocus).toBeTruthy();
      expect(comp.tagSelected).toBeNull();
      expect(comp.items.length).toEqual(simpleTags.length - 1);

      const newTag: DebugElement = fixture.debugElement.query(By.css('.tag-item'));
      newTag.nativeElement.focus();
      newTag.triggerEventHandler('keydown', {
         keyCode: 8, preventDefault: () => {
         }
      });
      fixture.detectChanges();

      expect(comp.hasFocus).toBeTruthy();
      expect(comp.tagSelected).toBeNull();
      expect(comp.items.length).toEqual(simpleTags.length - 2);
   }


() => {
      it('if input tag is disabled, remove button is not displayed and tag can not be removed', () => {
         comp.items = _cloneDeep(simpleTags);
         comp.disabled = true;
         fixture.detectChanges();

         expect(fixture.nativeElement.querySelector('.icon-cross.remove-tag-button')).toBeNull();
      });

      it('if input tag is not disabled, remove button is displayed and tag is removed when user clicks on it', () => {
         comp.items = _cloneDeep(simpleTags);
         comp.disabled = false;
         fixture.detectChanges();

         const removeButtons = fixture.nativeElement.querySelectorAll('.icon-cross.remove-tag-button');

         expect(removeButtons.length).toBe(simpleTags.length);

         removeButtons[1].click();
         fixture.detectChanges();

         expect(comp.items.length).toBe(simpleTags.length - 1);
         expect(comp.items[1]).toEqual(simpleTags[2]);
         expect(fixture.nativeElement.querySelectorAll('.icon-cross.remove-tag-button').length).toBe(simpleTags.length - 1);
      });
   }


() => {
         comp.items = _cloneDeep(simpleTags);
         comp.disabled = true;
         fixture.detectChanges();

         expect(fixture.nativeElement.querySelector('.icon-cross.remove-tag-button')).toBeNull();
      }


() => {
         comp.items = _cloneDeep(simpleTags);
         comp.disabled = false;
         fixture.detectChanges();

         const removeButtons = fixture.nativeElement.querySelectorAll('.icon-cross.remove-tag-button');

         expect(removeButtons.length).toBe(simpleTags.length);

         removeButtons[1].click();
         fixture.detectChanges();

         expect(comp.items.length).toBe(simpleTags.length - 1);
         expect(comp.items[1]).toEqual(simpleTags[2]);
         expect(fixture.nativeElement.querySelectorAll('.icon-cross.remove-tag-button').length).toBe(simpleTags.length - 1);
      }


() => {
      const id: string = 'test-id';
      (fixture.elementRef.nativeElement as HTMLElement).id = id;
      comp.label = 'Test';
      comp.innerInputContent = 'New Tag';
      fixture.detectChanges();

      expect(comp.items.length).toEqual(0);
      expect(comp.innerInputContent).not.toEqual('');
      expect(comp.isValidInput).toBeTruthy();

      const input: DebugElement = fixture.debugElement.query(By.css('.inner-input'));
      input.triggerEventHandler('keydown', {
         keyCode: 188, preventDefault: () => {
         }
      });
      fixture.detectChanges();

      expect(comp.items.length).toEqual(1);
      expect(comp.isValidInput).toBeTruthy();
      expect(comp.innerInputContent).toEqual('');

      comp.innerInputContent = 'New Tag 2';
      input.triggerEventHandler('keydown', {
         keyCode: 13, preventDefault: () => {
         }
      });
      fixture.detectChanges();

      expect(comp.items.length).toEqual(2);
      expect(comp.isValidInput).toBeTruthy();
      expect(comp.innerInputContent).toEqual('');

      comp.innerInputContent = 'New Tag 3';
      input.triggerEventHandler('keydown', {
         keyCode: 9, preventDefault: () => {
         }
      });
      fixture.detectChanges();

      expect(comp.items.length).toEqual(3);
      expect(comp.isValidInput).toBeTruthy();
      expect(comp.innerInputContent).toEqual('');
   }


() => {
      const id: string = 'test-id';
      (fixture.elementRef.nativeElement as HTMLElement).id = id;
      comp.label = 'Test';
      comp.items = _cloneDeep(simpleTags);
      fixture.detectChanges();

      expect(comp.items.length).toEqual(simpleTags.length);
      expect(comp.isValidInput).toBeTruthy();

      comp.innerInputContent = simpleTags[0];
      const input: DebugElement = fixture.debugElement.query(By.css('.inner-input'));
      input.triggerEventHandler('keydown', {
         keyCode: 188, preventDefault: () => {
         }
      });
      fixture.detectChanges();

      expect(comp.items.length).toEqual(simpleTags.length);
      expect(comp.isValidInput).toBeFalsy();

      comp.innerInputContent = simpleTags[1];
      input.triggerEventHandler('keydown', {
         keyCode: 13, preventDefault: () => {
         }
      });
      fixture.detectChanges();

      expect(comp.items.length).toEqual(simpleTags.length);
      expect(comp.isValidInput).toBeFalsy();

      comp.innerInputContent = simpleTags[2];
      input.triggerEventHandler('keydown', {
         keyCode: 9, preventDefault: () => {
         }
      });
      fixture.detectChanges();

      expect(comp.items.length).toEqual(simpleTags.length);
      expect(comp.isValidInput).toBeTruthy();
      expect(comp.innerInputContent).toEqual('');
   }


() => {
      const id: string = 'test-id';
      (fixture.elementRef.nativeElement as HTMLElement).id = id;
      comp.label = 'Test';
      comp.innerInputContent = 'New Tag';
      comp.items = _cloneDeep(simpleTags);
      fixture.detectChanges();

      expect(comp.items.length).toEqual(simpleTags.length);
      expect(comp.innerInputContent).not.toEqual('');

      const input: HTMLElement = fixture.debugElement.query(By.css('.inner-input')).nativeElement;
      input.focus();
      fixture.detectChanges();

      const tag: HTMLElement = fixture.debugElement.query(By.css('.tag-item')).nativeElement;
      tag.focus();
      fixture.detectChanges();

      expect(comp.items.length).toEqual(simpleTags.length + 1);
      expect(comp.innerInputContent).toEqual('');
   }


() => {
      const id: string = 'test-id';
      (fixture.elementRef.nativeElement as HTMLElement).id = id;
      comp.label = 'Test';
      comp.innerInputContent = 'New Tag';
      fixture.detectChanges();

      expect(comp.innerInputContent).not.toEqual('');

      const input: DebugElement = fixture.debugElement.query(By.css('.inner-input'));
      input.triggerEventHandler('keydown', {
         keyCode: 46, preventDefault: () => {
         }
      });
      fixture.detectChanges();

      expect(comp.innerInputContent).toEqual('');
   }


() => {
      const id: string = 'test-id';
      (fixture.elementRef.nativeElement as HTMLElement).id = id;
      comp.label = 'Test';
      comp.innerInputContent = 'New Tag';
      fixture.detectChanges();

      expect(comp.hasFocus).toBeFalsy();
      expect(comp.innerInputContent).not.toBe('');

      const container: HTMLLabelElement = fixture.debugElement.query(By.css('.st-input')).nativeElement;
      container.click();
      const input: DebugElement = fixture.debugElement.query(By.css('.inner-input'));
      input.triggerEventHandler('keydown', {
         keyCode: 9, preventDefault: () => {
         }
      });
      fixture.detectChanges();

      expect(comp.hasFocus).toBeTruthy();
      expect(comp.innerInputContent).toEqual('');
      comp.innerInputContent = 'New Tag';

      input.triggerEventHandler('keydown', {
         keyCode: 9, preventDefault: () => {
         }
      });
      fixture.detectChanges();

      expect(comp.innerInputContent).toBe('');
   }


() => {
      const id: string = 'test-id';
      (fixture.elementRef.nativeElement as HTMLElement).id = id;
      comp.label = 'Test';
      comp.placeholder = 'Test help';

      comp.setDisabledState(true);
      fixture.detectChanges();

      expect(comp.disableValue).toEqual('');

      const input: HTMLInputElement = fixture.debugElement.query(By.css('.inner-input')).nativeElement;
      spyOn(input, 'focus');

      expect(comp.hasPlaceholder).toBeTruthy();
      expect(comp.hasFocus).toBeFalsy();
      expect(input.focus).not.toHaveBeenCalled();

      const container: HTMLLabelElement = fixture.debugElement.query(By.css('.st-input')).nativeElement;
      container.click();
      fixture.detectChanges();

      expect(comp.hasPlaceholder).toBeTruthy();
      expect(comp.hasFocus).toBeFalsy();
      expect(input.focus).not.toHaveBeenCalled();
   }


() => {
      const id: string = 'test-id';
      (fixture.elementRef.nativeElement as HTMLElement).id = id;
      comp.label = 'Test';
      comp.items = _cloneDeep(simpleTags);

      comp.setDisabledState(true);
      fixture.detectChanges();

      expect(comp.disableValue).toEqual('');
      expect(comp.hasFocus).toBeFalsy();
      expect(comp.tagSelected).toBeNull();

      const tag: HTMLElement = fixture.debugElement.query(By.css('.tag-item')).nativeElement;
      tag.focus();
      fixture.detectChanges();

      expect(comp.hasFocus).toBeFalsy();
      expect(comp.tagSelected).toBeNull();
   }


() => {
      comp.isPristine = true;
      comp.errorMessage = 'This is a fake error message';
      fixture.detectChanges();

      expect(fixture.nativeElement.querySelector('.st-input-error-message')).toBeNull();
      expect(fixture.nativeElement.querySelector('.st-tag-input__input').classList).not.toContain('error');
   }


() => {
      comp.isPristine = false;
      comp.errorMessage = 'This is a fake error message';
      fixture.detectChanges();

      expect(fixture.nativeElement.querySelector('.st-input-error-message')).not.toBeNull();
      expect(fixture.nativeElement.querySelector('.st-tag-input__input').classList).toContain('error');
   }


() => {
      comp.forceValidations = true;
      comp.errorMessage = 'This is a fake error message';

      fixture.detectChanges();
      expect(fixture.nativeElement.innerHTML).toContain('This is a fake error message');
   }


() => {
      comp.forceValidations = false;
      comp.errorMessage = 'This is a fake error message';

      fixture.detectChanges();

      expect(fixture.nativeElement.innerHTML).not.toContain('This is a fake error message');
   }


() => {
      it('Should display autocomplete list with autocomplete if it is active and after user has typed the required number of characters', () => {
         const id: string = 'test-id';
         (fixture.elementRef.nativeElement as HTMLElement).id = id;
         comp.label = 'Test';
         comp.autocompleteList = [{ value: '1', label: '1' }, { value: '2', label: '2' }];
         comp.withAutocomplete = true;
         fixture.detectChanges();

         expect(comp.expandedMenu).toBeFalsy();
         expect(comp.hasAutocomplete).toBeFalsy();

         comp.autocompleteList = [{ value: 'first', label: 'first' }, { value: 'second', label: 'second' },
            { value: 'thrid', label: 'thrid' }, { value: 'fourth', label: 'fourth' }, {
               value: 'fifth',
               label: 'fifth'
            }];

         comp.charsToShowAutocompleteList = 3;
         comp.onInputText('fo');
         fixture.detectChanges();

         expect(comp.expandedMenu).toBeFalsy();
         expect(comp.hasAutocomplete).toBeFalsy();

         comp.onInputText('fourth');
         fixture.detectChanges();

         expect(comp.expandedMenu).toBeTruthy();
         expect(comp.hasAutocomplete).toBeTruthy();

         comp.onInputText('');
         fixture.detectChanges();

         expect(comp.expandedMenu).toBeFalsy();
         expect(comp.hasAutocomplete).toBeFalsy();
      });

      it('Should add tag from autocomplete list ', () => {
         const id: string = 'test-id';
         (fixture.elementRef.nativeElement as HTMLElement).id = id;
         comp.label = 'Test';
         comp.autocompleteList = [{ value: '1', label: '1' }, { value: '2', label: '2' }];
         comp.withAutocomplete = true;
         comp.items = _cloneDeep(simpleTags);
         fixture.detectChanges();

         expect(comp.items.length).toEqual(simpleTags.length);

         comp.onListSelect(<StDropDownMenuItem> comp.autocompleteList[0]);
         fixture.detectChanges();

         expect(comp.items.length).toEqual(simpleTags.length + 1);
         expect(comp.items[comp.items.length - 1]).toEqual('1');
      });

      it('Should add tag when click outside with autocomplete list ', () => {
         const id: string = 'test-id';
         (fixture.elementRef.nativeElement as HTMLElement).id = id;
         comp.label = 'Test';
         comp.autocompleteList = [{ value: '1', label: '1' }, { value: '2', label: '2' }];
         comp.withAutocomplete = true;
         comp.items = _cloneDeep(simpleTags);
         fixture.detectChanges();

         expect(comp.items.length).toEqual(simpleTags.length);
         expect(comp.expandedMenu).toBeFalsy();
         expect(comp.hasAutocomplete).toBeFalsy();

         comp.onInputText('New Tag');
         fixture.detectChanges();

         expect(comp.expandedMenu).toBeTruthy();
         expect(comp.hasAutocomplete).toBeTruthy();

         let div = document.createElement('div');
         document.body.appendChild(div);
         div.click();
         fixture.detectChanges();

         expect(comp.items.length).toEqual(simpleTags.length + 1);
         expect(comp.items[comp.items.length - 1]).toEqual('New Tag');
         expect(comp.expandedMenu).toBeFalsy();
         expect(comp.hasAutocomplete).toBeFalsy();
      });

      it('If number of chars before displaying the autocomplete list is 0, when user searches a text and adds a tag, ' +
         'input event is emitted to force to display the autocomplete list reset', () => {
         comp.charsToShowAutocompleteList = 0;
         comp.withAutocomplete = true;
         comp.innerInputContent = 'aa';
         fixture.detectChanges();

         const input: DebugElement = fixture.debugElement.query(By.css('.inner-input'));
         spyOn(comp.newElementInput.nativeElement, 'dispatchEvent').and.callThrough();

         input.triggerEventHandler('keydown', {
            keyCode: 188, preventDefault: () => {
            }
         });
         fixture.detectChanges();

         const inputEvent = comp.newElementInput.nativeElement.dispatchEvent.calls.mostRecent().args[0];
         expect(comp.newElementInput.nativeElement.innerText).toEqual('');
         expect(comp.newElementInput.nativeElement.dispatchEvent).toHaveBeenCalled();
         expect(inputEvent.data).toEqual('');
         expect(inputEvent.bubbles).toEqual(true);
      });

      it('If number of chars before displaying the autocomplete list is 0, when user clicks on input tag ' +
         'input event is emitted to force to display the autocomplete list reset', () => {
         comp.charsToShowAutocompleteList = 0;
         comp.withAutocomplete = true;
         comp.innerInputContent = 'aa';
         fixture.detectChanges();

         spyOn(comp.newElementInput.nativeElement, 'dispatchEvent').and.callThrough();
         fixture.nativeElement.querySelector('.st-tag-input__text.inner-input').click();
         fixture.detectChanges();

         expect(comp.newElementInput.nativeElement.dispatchEvent).toHaveBeenCalled();
         const inputEvent = comp.newElementInput.nativeElement.dispatchEvent.calls.mostRecent().args[0];
         expect(comp.newElementInput.nativeElement.innerText).toEqual('');
         expect(inputEvent.data).toEqual('');
         expect(inputEvent.bubbles).toEqual(true);
      });
   }


() => {
         const id: string = 'test-id';
         (fixture.elementRef.nativeElement as HTMLElement).id = id;
         comp.label = 'Test';
         comp.autocompleteList = [{ value: '1', label: '1' }, { value: '2', label: '2' }];
         comp.withAutocomplete = true;
         fixture.detectChanges();

         expect(comp.expandedMenu).toBeFalsy();
         expect(comp.hasAutocomplete).toBeFalsy();

         comp.autocompleteList = [{ value: 'first', label: 'first' }, { value: 'second', label: 'second' },
            { value: 'thrid', label: 'thrid' }, { value: 'fourth', label: 'fourth' }, {
               value: 'fifth',
               label: 'fifth'
            }];

         comp.charsToShowAutocompleteList = 3;
         comp.onInputText('fo');
         fixture.detectChanges();

         expect(comp.expandedMenu).toBeFalsy();
         expect(comp.hasAutocomplete).toBeFalsy();

         comp.onInputText('fourth');
         fixture.detectChanges();

         expect(comp.expandedMenu).toBeTruthy();
         expect(comp.hasAutocomplete).toBeTruthy();

         comp.onInputText('');
         fixture.detectChanges();

         expect(comp.expandedMenu).toBeFalsy();
         expect(comp.hasAutocomplete).toBeFalsy();
      }


() => {
         const id: string = 'test-id';
         (fixture.elementRef.nativeElement as HTMLElement).id = id;
         comp.label = 'Test';
         comp.autocompleteList = [{ value: '1', label: '1' }, { value: '2', label: '2' }];
         comp.withAutocomplete = true;
         comp.items = _cloneDeep(simpleTags);
         fixture.detectChanges();

         expect(comp.items.length).toEqual(simpleTags.length);

         comp.onListSelect(<StDropDownMenuItem> comp.autocompleteList[0]);
         fixture.detectChanges();

         expect(comp.items.length).toEqual(simpleTags.length + 1);
         expect(comp.items[comp.items.length - 1]).toEqual('1');
      }


() => {
         const id: string = 'test-id';
         (fixture.elementRef.nativeElement as HTMLElement).id = id;
         comp.label = 'Test';
         comp.autocompleteList = [{ value: '1', label: '1' }, { value: '2', label: '2' }];
         comp.withAutocomplete = true;
         comp.items = _cloneDeep(simpleTags);
         fixture.detectChanges();

         expect(comp.items.length).toEqual(simpleTags.length);
         expect(comp.expandedMenu).toBeFalsy();
         expect(comp.hasAutocomplete).toBeFalsy();

         comp.onInputText('New Tag');
         fixture.detectChanges();

         expect(comp.expandedMenu).toBeTruthy();
         expect(comp.hasAutocomplete).toBeTruthy();

         let div = document.createElement('div');
         document.body.appendChild(div);
         div.click();
         fixture.detectChanges();

         expect(comp.items.length).toEqual(simpleTags.length + 1);
         expect(comp.items[comp.items.length - 1]).toEqual('New Tag');
         expect(comp.expandedMenu).toBeFalsy();
         expect(comp.hasAutocomplete).toBeFalsy();
      }


() => {
         comp.charsToShowAutocompleteList = 0;
         comp.withAutocomplete = true;
         comp.innerInputContent = 'aa';
         fixture.detectChanges();

         const input: DebugElement = fixture.debugElement.query(By.css('.inner-input'));
         spyOn(comp.newElementInput.nativeElement, 'dispatchEvent').and.callThrough();

         input.triggerEventHandler('keydown', {
            keyCode: 188, preventDefault: () => {
            }
         });
         fixture.detectChanges();

         const inputEvent = comp.newElementInput.nativeElement.dispatchEvent.calls.mostRecent().args[0];
         expect(comp.newElementInput.nativeElement.innerText).toEqual('');
         expect(comp.newElementInput.nativeElement.dispatchEvent).toHaveBeenCalled();
         expect(inputEvent.data).toEqual('');
         expect(inputEvent.bubbles).toEqual(true);
      }


() => {
         comp.charsToShowAutocompleteList = 0;
         comp.withAutocomplete = true;
         comp.innerInputContent = 'aa';
         fixture.detectChanges();

         spyOn(comp.newElementInput.nativeElement, 'dispatchEvent').and.callThrough();
         fixture.nativeElement.querySelector('.st-tag-input__text.inner-input').click();
         fixture.detectChanges();

         expect(comp.newElementInput.nativeElement.dispatchEvent).toHaveBeenCalled();
         const inputEvent = comp.newElementInput.nativeElement.dispatchEvent.calls.mostRecent().args[0];
         expect(comp.newElementInput.nativeElement.innerText).toEqual('');
         expect(inputEvent.data).toEqual('');
         expect(inputEvent.bubbles).toEqual(true);
      }


() => {

      it('by default, it allows free text', () => {
         expect(comp.allowFreeText).toBeTruthy();
      });

      it('if it allows free text, user can clicks on input an types something', () => {
         comp.allowFreeText = true;
         comp.items = [];
         fixture.detectChanges();

         comp.innerInputContent = 'fake value';
         const input = fixture.debugElement.query(By.css('.st-tag-input__text.inner-input'));
         const enterKeyDownEventObj = {
            keyCode: 13, preventDefault: () => {
            }
         };
         input.triggerEventHandler('keydown', enterKeyDownEventObj);

         expect(comp.items[comp.items.length - 1]).toEqual('fake value');

         comp.allowFreeText = false;
         comp.items = [];

         fixture.detectChanges();

         input.triggerEventHandler('keydown', enterKeyDownEventObj);
         fixture.detectChanges();

         expect(comp.items.length).toBe(0);
      });
   }


() => {
         expect(comp.allowFreeText).toBeTruthy();
      }