/**
 * Method to determine the language used in the development of the smart contract project, which will be used to determine the correct directories
 * to package the projects.
 * @param workspaceDir {String} workspaceDir A string containing the path to the current active workspace (the workspace of the project the user is packaging).
 * @returns {string} The language used in the development of this smart contract project. Used to package in the correct respective directory.
 */
async function getLanguage(workspaceDir: vscode.WorkspaceFolder): Promise<ChaincodeType> {

    // Is this a Node.js smart contract (JavaScript, TypeScript, etc)?
    const packageJsonFile: string = path.join(workspaceDir.uri.fsPath, 'package.json');
    const packageJsonFileExists: boolean = await fs.pathExists(packageJsonFile);
    if (packageJsonFileExists) {
        return 'node';
    }

    // Is this a Java smart contract (Java, Kotlin, etc)?
    const gradleFile: string = path.join(workspaceDir.uri.fsPath, 'build.gradle');
    const gradleFileExists: boolean = await fs.pathExists(gradleFile);
    const mavenFile: string = path.join(workspaceDir.uri.fsPath, 'pom.xml');
    const mavenFileExists: boolean = await fs.pathExists(mavenFile);
    if (gradleFileExists || mavenFileExists) {
        return 'java';
    }

    // Is this a Go smart contract?
    const goFiles: vscode.Uri[] = await vscode.workspace.findFiles(
        new vscode.RelativePattern(workspaceDir, '**/*.go'),
        null,
        1
    );
    if (goFiles.length > 0) {
        return 'golang';
    }

    // Its not java/node/go contract, so error
    const message: string = `Failed to determine workspace language type, supported languages are JavaScript, TypeScript, Go and Java. Please ensure your contract's root-level directory is open in the Explorer.`;
    throw new Error(message);

}


/**
 * Method to retrieve the package name and version from the projects package.json file, and returns them to be used in the getFinalDirectory() method.
 * @param workspaceDir {String} workspaceDir A string containing the path to the current active workspace (the workspace of the project the user is packaging).
 * @returns {string, string}An object with the workspacePackageName and workspacePackageVersion which will be used in the createPackageDir() method.
 */
async function packageJsonNameAndVersion(workspaceDir: vscode.WorkspaceFolder, overrideName?: string, overrideVersion?: string): Promise<{ workspacePackageName: string, workspacePackageVersion: string }> {

    const workspacePackage: string = path.join(workspaceDir.uri.fsPath, '/package.json');
    const workspacePackageContents: Buffer = await fs.readFile(workspacePackage);
    const workspacePackageObj: any = JSON.parse(workspacePackageContents.toString('utf8'));
    let workspacePackageName: string = workspacePackageObj.name;
    let workspacePackageVersion: string = workspacePackageObj.version;

    if (overrideName) {
        workspacePackageName = overrideName;
    }
    if (overrideVersion) {
        workspacePackageVersion = overrideVersion;
    }

    if (!workspacePackageName || !workspacePackageVersion) {
        const message: string = 'Please enter a package name and/or package version into your package.json';
        throw new Error(message);
    }
    return { workspacePackageName, workspacePackageVersion };
}


/**
 * Method which calls an input box should the project be coded in java, which asks the user for a package name and version
 * (as java projects do not contain a package.json file), and returns an object containing both these values.
 * @returns {string, string} Returns an object with the workspacePackageName and workspacePackageVersion which will be used in the createPackageDir() method
 */
async function javaPackageAndVersion(overrideName?: string, overrideVersion?: string): Promise<{ workspacePackageName: string, workspacePackageVersion: string }> {

    let workspacePackageName: string = overrideName;
    if (!workspacePackageName) {
        workspacePackageName = await UserInputUtil.showInputBox('Enter a name for your Java package'); // Getting the specified name and package from the user
        if (!workspacePackageName) {
            // User has cancelled the input box
            return;
        }
    }
    let workspacePackageVersion: string = overrideVersion;
    if (!workspacePackageVersion) {
        workspacePackageVersion = await UserInputUtil.showInputBox('Enter a version for your Java package'); // Getting the specified name and package from the user
        if (!workspacePackageVersion) {
            // User has cancelled the input box
            return;
        }
    }

    return { workspacePackageName, workspacePackageVersion };
}


/**
 * Method which calls an input box should the project be coded in golang, which asks the user for a package name and version
 * (as golang projects do not contain a package.json file), and returns an object containing both these values.
 * @returns {string, string} Returns an object with the workspacePackageName and workspacePackageVersion which will be used in the createPackageDir() method
 */
async function golangPackageAndVersion(overrideName?: string, overrideVersion?: string): Promise<{ workspacePackageName: string, workspacePackageVersion: string }> {

    let workspacePackageName: string = overrideName;
    if (!workspacePackageName) {
        workspacePackageName = await UserInputUtil.showInputBox('Enter a name for your Go package'); // Getting the specified name and package from the user
        if (!workspacePackageName) {
            // User has cancelled the input box
            return;
        }
    }
    let workspacePackageVersion: string = overrideVersion;
    if (!workspacePackageVersion) {
        workspacePackageVersion = await UserInputUtil.showInputBox('Enter a version for your Go package'); // Getting the specified name and package from the user
        if (!workspacePackageVersion) {
            // User has cancelled the input box
            return;
        }
    }

    return { workspacePackageName, workspacePackageVersion };
}


function checkForProjectErrors(workspaceDir: vscode.WorkspaceFolder): void {
    const collections: [vscode.Uri, vscode.Diagnostic[]][] = vscode.languages.getDiagnostics();
    for (const collection of collections) {
        for (const thing of collection) {
            if (thing instanceof vscode.Uri) {
                const uri: vscode.Uri = thing as vscode.Uri;
                const relativePath: string = path.relative(workspaceDir.uri.fsPath, uri.fsPath);
                if (!relativePath || relativePath.startsWith('..') || path.isAbsolute(relativePath)) {
                    // not in this project must have another project open in the workspace
                    break;
                }
            } else {
                const diagnostics: vscode.Diagnostic[] = thing as vscode.Diagnostic[];
                for (const diagnostic of diagnostics) {
                    // only check for errors
                    if (diagnostic.severity === 0) {
                        throw new Error('Smart contract project has errors please fix them before packaging');
                    }
                }
            }

        }
    }
}


async function buildWorkspace(workspaceDir: vscode.WorkspaceFolder): Promise<void> {

    // Find all of the tasks.
    const tasks: vscode.Task[] = await vscode.tasks.fetchTasks();

    // Then limit the tasks to build tasks that we can actually use.
    const buildTasks: vscode.Task[] = tasks.filter((task: vscode.Task) => {
        if (!task.scope || task.scope === vscode.TaskScope.Global || task.scope === vscode.TaskScope.Workspace) {
            // We don't want unscoped tasks, global tasks, or workspace tasks.
            return false;
        } else if (task.scope.uri.fsPath !== workspaceDir.uri.fsPath) {
            // We only want tasks for our smart contract project.
            return false;
        } else if (task.group !== vscode.TaskGroup.Build) {
            // We only want build tasks.
            return false;
        } else if (task.isBackground) {
            // We only want foreground tasks (not "npm watch").
            return false;
        } else if (task.name.match(/watch/i)) {
            // We don't want anything with "watch" in the name!
            return false;
        } else {
            return true;
        }
    });

    // If we have a set of build tasks, then execute the first one.
    if (buildTasks.length > 0) {
        const buildTask: vscode.Task = buildTasks[0];
        const buildTaskExecution: vscode.TaskExecution = await vscode.tasks.executeTask(buildTask);
        await new Promise((resolve: any): any => {
            const buildTaskListener: vscode.Disposable = vscode.tasks.onDidEndTask((e: vscode.TaskEndEvent) => {
                if (e.execution === buildTaskExecution) {
                    buildTaskListener.dispose();
                    resolve();
                }
            });
        });
    }

}


async (progress: vscode.Progress<{ message: string }>) => {
        progress.report({ message: `Packaging Smart Contract` });
        try {

            // Determine the filename of the new package.
            const pkgFile: string = path.join(resolvedPkgDir, `${properties.workspacePackageName}@${properties.workspacePackageVersion}.cds`);
            const pkgFileExists: boolean = await fs.pathExists(pkgFile);
            if (pkgFileExists) {
                if (language === 'golang') {
                    throw new Error('Package with name and version already exists. Please input a different name or version for your Go project.');
                } else if (language === 'java') {
                    throw new Error('Package with name and version already exists. Please input a different name or version for your Java project.');
                } else {
                    throw new Error('Package with name and version already exists. Please change the name and/or the version of the project in your package.json file.');
                }
            }

            // Determine the path argument.
            let pkgPath: string = workspace.uri.fsPath;
            if (language === 'golang') {

                if (!process.env.GOPATH) {
                    // The path is relative to $GOPATH/src for Go smart contracts.
                    const srcPath: string = path.join(pkgPath, '..', '..', 'src');
                    pkgPath = path.basename(pkgPath);
                    const exists: boolean = await fs.pathExists(srcPath);

                    if (!exists) {
                        // Project path is not under GOPATH.
                        throw new Error('The enviroment variable GOPATH has not been set, and the extension was not able to automatically detect the correct value. You cannot package a Go smart contract without setting the environment variable GOPATH.');
                    } else {
                        process.env.GOPATH = path.join(srcPath, '..');
                    }
                } else {
                    // The path is relative to $GOPATH/src for Go smart contracts.
                    const srcPath: string = path.join(process.env.GOPATH, 'src');
                    pkgPath = path.relative(srcPath, pkgPath);
                    if (!pkgPath || pkgPath.startsWith('..') || path.isAbsolute(pkgPath)) {
                        // Project path is not under GOPATH.
                        throw new Error('The Go smart contract is not a subdirectory of the path specified by the environment variable GOPATH. Please correct the environment variable GOPATH.');
                    }
                }
            }

            // Determine if there is a metadata path.
            const metadataPath: string = path.join(workspace.uri.fsPath, 'META-INF');
            const metadataPathExists: boolean = await fs.pathExists(metadataPath);

            // Create the package. Need to dynamically load the package class
            // from the Fabric SDK to avoid early native module loading.
            const { Package } = await import('fabric-client');
            const pkg: any = await Package.fromDirectory({
                name: properties.workspacePackageName,
                version: properties.workspacePackageVersion,
                path: pkgPath,
                type: language,
                metadataPath: metadataPathExists ? metadataPath : null
            });
            const pkgBuffer: any = await pkg.toBuffer();
            await fs.writeFile(pkgFile, pkgBuffer);

            Reporter.instance().sendTelemetryEvent('packageCommand');

            await vscode.commands.executeCommand(ExtensionCommands.REFRESH_PACKAGES);
            outputAdapter.log(LogType.SUCCESS, `Smart Contract packaged: ${pkgFile}`);

            const fileNames: string[] = pkg.fileNames;

            outputAdapter.log(LogType.INFO, undefined, `${fileNames.length} file(s) packaged:`);
            for (const file of fileNames) {
                outputAdapter.log(LogType.INFO, undefined, `- ${file}`);
            }
            const packageEntry: PackageRegistryEntry = new PackageRegistryEntry();
            packageEntry.name = properties.workspacePackageName;
            packageEntry.version = properties.workspacePackageVersion;
            packageEntry.path = pkgFile;

            return packageEntry;
        } catch (err) {
            outputAdapter.log(LogType.ERROR, err.message, err.toString());
            return;
        }
    }


(task: vscode.Task) => {
        if (!task.scope || task.scope === vscode.TaskScope.Global || task.scope === vscode.TaskScope.Workspace) {
            // We don't want unscoped tasks, global tasks, or workspace tasks.
            return false;
        } else if (task.scope.uri.fsPath !== workspaceDir.uri.fsPath) {
            // We only want tasks for our smart contract project.
            return false;
        } else if (task.group !== vscode.TaskGroup.Build) {
            // We only want build tasks.
            return false;
        } else if (task.isBackground) {
            // We only want foreground tasks (not "npm watch").
            return false;
        } else if (task.name.match(/watch/i)) {
            // We don't want anything with "watch" in the name!
            return false;
        } else {
            return true;
        }
    }


(resolve: any): any => {
            const buildTaskListener: vscode.Disposable = vscode.tasks.onDidEndTask((e: vscode.TaskEndEvent) => {
                if (e.execution === buildTaskExecution) {
                    buildTaskListener.dispose();
                    resolve();
                }
            });
        }


(e: vscode.TaskEndEvent) => {
                if (e.execution === buildTaskExecution) {
                    buildTaskListener.dispose();
                    resolve();
                }
            }


({ classes }) => (
    <svg role="presentation"


cx(iconClassNames


() => ({
        popover: {
            display: "flex",
            flexDirection: "column",
        },
    })


function IconUndo(props: Props) {
  return (
    <svg {...props} viewBox="0 0 24 24">
      <path d="M12.466 8c-2.65 0-5.05.99-6.9 2.6l-1.89-1.89c-.63-.63-1.71-.19-1.71.7V15c0 .55.45 1 1 1h5.59c.89 0 1.34-1.08.71-1.71l-1.91-1.91c1.39-1.16 3.16-1.88 5.12-1.88 3.16 0 5.89 1.84 7.19 4.5.27.56.91.84 1.5.64.71-.23 1.07-1.04.75-1.72-1.72-3.5-5.3-5.92-9.45-5.92z" />
    </svg>
  );
}


@Component({
  selector: 'app-footer',
  templateUrl: './footer.component.html',
  styleUrls: ['./footer.component.scss']
})
export class FooterComponent implements OnInit {

  constructor() { }

  ngOnInit(): void {

  }

}


ngOnInit(): void {

  }


export class Bottle extends Material {
  name:string;
  units: number;
  constructor(units:number){
    super(units);
    this.name = 'Bottle';
  }
}


export interface YafeFormDefinition {
	name: string;
	title: string;
	groups: YafeFormGroup[];
}


export interface YafeFormItem {
	itemType: 'section' | 'field';
	name: string;
	condition?: string;
}


export interface YafeFormGroup extends YafeFormItem {
	title?: string;
	items: YafeFormItem[];
}


export interface YafeFieldDefinition extends YafeFormItem {
	type: 'text' | 'select' | 'checkbox';
	subType?: string;
	label: string;
	defaultValue?: string | number | boolean;
	tip?: string;
	description?: string;
	validators: YafeValidator[];
	properties?: [{ [name: string]: string | number | any }]
}


export interface YafeValidator {
	type: 'BuildIn';
	name: 'required';
	errorText?: string;
}


export interface FormFieldComponent {
	definition: YafeFieldDefinition;
	formControl: AbstractControl;
}


export interface FormSectionComponent {
	definition: YafeFormGroup;

}


(_, _1) => true


<T, U>({
    urn,
    useEntityQuery,
    useUpdateQuery,
    entityType,
    getOverrideProperties,
    tabs,
    sidebarSections,
}: Props<T, U>): JSX.Element => {
    const isLineageMode = useIsLineageMode();
    const entityRegistry = useEntityRegistry();
    const history = useHistory();
    const isCompact = React.useContext(CompactContext);
    const tabsWithDefaults = tabs.map((tab) => ({ ...tab, display: { ...defaultTabDisplayConfig, ...tab.display } }));
    const sideBarSectionsWithDefaults = sidebarSections.map((sidebarSection) => ({
        ...sidebarSection,
        display: { ...defaultSidebarSection, ...sidebarSection.display },
    }));

    const routeToTab = useCallback(
        ({
            tabName,
            tabParams,
            method = 'push',
        }: {
            tabName: string;
            tabParams?: Record<string, any>;
            method?: 'push' | 'replace';
        }) => {
            analytics.event({
                type: EventType.EntitySectionViewEvent,
                entityType,
                entityUrn: urn,
                section: tabName.toLowerCase(),
            });
            history[method](getEntityPath(entityType, urn, entityRegistry, false, tabName, tabParams));
        },
        [history, entityType, urn, entityRegistry],
    );

    const { loading, error, data, refetch } = useEntityQuery({
        variables: { urn },
    });

    const maybeUpdateEntity = useUpdateQuery?.({
        onCompleted: () => refetch(),
    });
    let updateEntity;
    if (maybeUpdateEntity) {
        [updateEntity] = maybeUpdateEntity;
    }

    const entityData =
        (data && getDataForEntityType({ data: data[Object.keys(data)[0]], entityType, getOverrideProperties })) || null;

    const lineage = entityData ? entityRegistry.getLineageVizConfig(entityType, entityData) : undefined;

    const autoRenderTabs: EntityTab[] =
        entityData?.autoRenderAspects?.map((aspect) => ({
            name: aspect.renderSpec?.displayName || aspect.aspectName,
            component: () => (
                <DynamicTab
                    renderSpec={aspect.renderSpec}
                    type={aspect.renderSpec?.displayType}
                    payload={aspect.payload}
                />
            ),
            display: {
                visible: () => true,
                enabled: () => true,
            },
        }


(tab) => ({ ...tab, display: { ...defaultTabDisplayConfig, ...tab.display } })


(sidebarSection) => ({
        ...sidebarSection,
        display: { ...defaultSidebarSection, ...sidebarSection.display },
    })


({
            tabName,
            tabParams,
            method = 'push',
        }: {
            tabName: string;
            tabParams?: Record<string, any>;
            method?: 'push' | 'replace';
        }) => {
            analytics.event({
                type: EventType.EntitySectionViewEvent,
                entityType,
                entityUrn: urn,
                section: tabName.toLowerCase(),
            });
            history[method](getEntityPath(entityType, urn, entityRegistry, false, tabName, tabParams));
        }


() => refetch()


(aspect) => ({
            name: aspect.renderSpec?.displayName || aspect.aspectName,
            component: () => (
                <DynamicTab
                    renderSpec={aspect.renderSpec}
                    type={aspect.renderSpec?.displayType}
                    payload={aspect.payload}
                />
            )


() => (
                <DynamicTab
                    renderSpec={aspect.renderSpec}


type Props<T, U> = {
    urn: string;
    entityType: EntityType;
    useEntityQuery: (
        baseOptions: QueryHookOptions<
            T,
            Exact<{
                urn: string;
            }>
        >,
    ) => QueryResult<
        T,
        Exact<{
            urn: string;
        }>
    >;
    useUpdateQuery?: (
        baseOptions?: MutationHookOptions<U, { urn: string; input: GenericEntityUpdate }> | undefined,
    ) => MutationTuple<U, { urn: string; input: GenericEntityUpdate }>;
    getOverrideProperties: (T) => GenericEntityProperties;
    tabs: EntityTab[];
    sidebarSections: EntitySidebarSection[];
};


isLineageMode ? (
                        <LineageExplorer type={entityType} urn={urn} />
                    ) : (
                        <SplitPane
                            split="vertical"
                            minSize={window.innerWidth


async () =>
        await disposeTestDocumentStore(store)


async () => {
        {
            const session = store.openSession();
            const user1 = Object.assign(new User(), {
                name: "Marcin"
            });

            const user2 = Object.assign(new User(), {
                name: "Marcin"
            });

            await session.store(user1, "users/1");
            await session.store(user2, "users/2");
            await session.saveChanges();
        }

        {
            const session = store.openSession();
            const user1 = await session.load("users/1", User);
            const user2 = await session.load("users/2", User);

            assertThat(user1)
                .isNotNull();
            assertThat(user2)
                .isNotNull();
            assertThat(user1 === user2)
                .isFalse();
        }
    }


class User {
    public name: string;
}


geneItem =>
      geneItem.getValue("id") === gene.id ? suggestedGene : geneItem


(store, data) => this.onGeneFollowed(gene, store, data)


(item, index) => {
      const imageUrl = get(item, i => i.image.cropped.url)
      return (
        <LinkContainer key={`gene-search-results-${index}`}


i => i.image.cropped.url


({ term, relayEnvironment, updateFollowCount }) => {
  return (
    <QueryRenderer<GeneSearchResultsQuery>
      environment={relayEnvironment}
      query={graphql`
        query GeneSearchResultsQuery($term: String!) {
          viewer {
            ...GeneSearchResults_viewer
          }
        }
      `}


@track({}, { dispatch: data => Events.postEvent(data) })
class GeneSearchResultsContent extends React.Component<Props, null> {
  private excludedGeneIds: Set<string>
  followCount: number = 0

  constructor(props: Props, context: any) {
    super(props, context)
    this.excludedGeneIds = new Set(
      this.props.viewer.match_gene.map(item => item._id)
    )
  }

  onGeneFollowed(
    gene: Gene,
    store: RecordSourceSelectorProxy,
    data: GeneSearchResultsFollowGeneMutationResponse
  ): void {
    const suggestedGene = store.get(
      data.followGene.gene.similar.edges[0].node.__id
    )
    this.excludedGeneIds.add(suggestedGene.getValue("_id"))

    const suggestedGenesRootField = store.get("client:root:viewer")
    const suggestedGenes = suggestedGenesRootField.getLinkedRecords(
      "match_gene",
      { term: this.props.term }
    )
    const updatedSuggestedGenes = suggestedGenes.map(geneItem =>
      geneItem.getValue("id") === gene.id ? suggestedGene : geneItem
    )

    suggestedGenesRootField.setLinkedRecords(
      updatedSuggestedGenes,
      "match_gene",
      { term: this.props.term }
    )

    this.followCount += 1

    this.props.updateFollowCount(this.followCount)

    this.props.tracking.trackEvent({
      action: "Followed Gene",
      entity_id: gene._id,
      entity_slug: gene.id,
      context_module: "onboarding search",
    })
  }

  followedGene(gene: Gene) {
    this.excludedGeneIds.add(gene._id)

    commitMutation<GeneSearchResultsFollowGeneMutation>(
      this.props.relay.environment,
      {
        mutation: graphql`
          mutation GeneSearchResultsFollowGeneMutation(
            $input: FollowGeneInput!
            $excludedGeneIds: [String]!
          ) {
            followGene(input: $input) {
              gene {
                similar(first: 1, exclude_gene_ids: $excludedGeneIds) {
                  edges {
                    node {
                      id
                      _id
                      __id
                      name
                      image {
                        cropped(width: 100, height: 100) {
                          url
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        `,
        variables: {
          input: {
            gene_id: gene.id,
          },
          excludedGeneIds: Array.from(this.excludedGeneIds),
        },
        updater: (store, data) => this.onGeneFollowed(gene, store, data),
      }
    )
  }

  render() {
    const items = this.props.viewer.match_gene.map((item, index) => {
      const imageUrl = get(item, i => i.image.cropped.url)
      return (
        <LinkContainer key={`gene-search-results-${index}`}>
          <ReplaceTransition
            transitionEnterTimeout={1000}
            transitionLeaveTimeout={400}
          >
            <ItemLink
              href="#"
              item={item}
              key={item.id}
              id={item.id}
              name={item.name}
              image_url={imageUrl}
              onClick={() => this.followedGene(item)}


interface ContainerProps extends FollowProps {
  term: string
}


interface Props extends React.HTMLProps<HTMLAnchorElement>, ContainerProps {
  tracking?: TrackingProp
  relay?: RelayProp
  viewer: GeneSearchResults_viewer
}


type Gene = GeneSearchResults_viewer["match_gene"][0]


onGeneFollowed(
    gene: Gene,
    store: RecordSourceSelectorProxy,
    data: GeneSearchResultsFollowGeneMutationResponse
  ): void {
    const suggestedGene = store.get(
      data.followGene.gene.similar.edges[0].node.__id
    )
    this.excludedGeneIds.add(suggestedGene.getValue("_id"))

    const suggestedGenesRootField = store.get("client:root:viewer")
    const suggestedGenes = suggestedGenesRootField.getLinkedRecords(
      "match_gene",
      { term: this.props.term }
    )
    const updatedSuggestedGenes = suggestedGenes.map(geneItem =>
      geneItem.getValue("id") === gene.id ? suggestedGene : geneItem
    )

    suggestedGenesRootField.setLinkedRecords(
      updatedSuggestedGenes,
      "match_gene",
      { term: this.props.term }
    )

    this.followCount += 1

    this.props.updateFollowCount(this.followCount)

    this.props.tracking.trackEvent({
      action: "Followed Gene",
      entity_id: gene._id,
      entity_slug: gene.id,
      context_module: "onboarding search",
    })
  }


followedGene(gene: Gene) {
    this.excludedGeneIds.add(gene._id)

    commitMutation<GeneSearchResultsFollowGeneMutation>(
      this.props.relay.environment,
      {
        mutation: graphql`
          mutation GeneSearchResultsFollowGeneMutation(
            $input: FollowGeneInput!
            $excludedGeneIds: [String]!
          ) {
            followGene(input: $input) {
              gene {
                similar(first: 1, exclude_gene_ids: $excludedGeneIds) {
                  edges {
                    node {
                      id
                      _id
                      __id
                      name
                      image {
                        cropped(width: 100, height: 100) {
                          url
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        `,
        variables: {
          input: {
            gene_id: gene.id,
          },
          excludedGeneIds: Array.from(this.excludedGeneIds),
        },
        updater: (store, data) => this.onGeneFollowed(gene, store, data),
      }
    )
  }


render() {
    const items = this.props.viewer.match_gene.map((item, index) => {
      const imageUrl = get(item, i => i.image.cropped.url)
      return (
        <LinkContainer key={`gene-search-results-${index}`}>
          <ReplaceTransition
            transitionEnterTimeout={1000}
            transitionLeaveTimeout={400}
          >
            <ItemLink
              href="#"
              item={item}
              key={item.id}
              id={item.id}
              name={item.name}
              image_url={imageUrl}
              onClick={() => this.followedGene(item)}


config => {

            const solarTheme: any = config.variables.solar;

            this.option = Object.assign({}, {
                tooltip: {
                    trigger: 'item',
                    formatter: '{a} <br/>{b} : {c} ({d}%)',
                },
                series: [
                    {
                        name: ' ',
                        clockWise: true,
                        hoverAnimation: false,
                        type: 'pie',
                        center: ['45%', '50%'],
                        radius: solarTheme.radius,
                        data: [
                            {
                                value: this.value,
                                name: ' ',
                                label: {
                                    normal: {
                                        position: 'center',
                                        formatter: '{d}%',
                                        textStyle: {
                                            fontSize: '22',
                                            fontFamily: config.variables.fontSecondary,
                                            fontWeight: '600',
                                            color: config.variables.fgHeading,
                                        },
                                    },
                                },
                                tooltip: {
                                    show: false,
                                },
                                itemStyle: {
                                    normal: {
                                        color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
                                            {
                                                offset: 0,
                                                color: solarTheme.gradientLeft,
                                            },
                                            {
                                                offset: 1,
                                                color: solarTheme.gradientRight,
                                            },
                                        ]),
                                        shadowColor: solarTheme.shadowColor,
                                        shadowBlur: 0,
                                        shadowOffsetX: 0,
                                        shadowOffsetY: 3,
                                    },
                                },
                                hoverAnimation: false,
                            },
                            {
                                value: 100 - this.value,
                                name: ' ',
                                tooltip: {
                                    show: false,
                                },
                                label: {
                                    normal: {
                                        position: 'inner',
                                    },
                                },
                                itemStyle: {
                                    normal: {
                                        color: config.variables.layoutBg,
                                    },
                                },
                            },
                        ],
                    },
                    {
                        name: ' ',
                        clockWise: true,
                        hoverAnimation: false,
                        type: 'pie',
                        center: ['45%', '50%'],
                        radius: solarTheme.radius,
                        data: [
                            {
                                value: this.value,
                                name: ' ',
                                label: {
                                    normal: {
                                        position: 'inner',
                                        show: false,
                                    },
                                },
                                tooltip: {
                                    show: false,
                                },
                                itemStyle: {
                                    normal: {
                                        color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
                                            {
                                                offset: 0,
                                                color: solarTheme.gradientLeft,
                                            },
                                            {
                                                offset: 1,
                                                color: solarTheme.gradientRight,
                                            },
                                        ]),
                                        shadowColor: solarTheme.shadowColor,
                                        shadowBlur: 7,
                                    },
                                },
                                hoverAnimation: false,
                            },
                            {
                                value: 28,
                                name: ' ',
                                tooltip: {
                                    show: false,
                                },
                                label: {
                                    normal: {
                                        position: 'inner',
                                    },
                                },
                                itemStyle: {
                                    normal: {
                                        color: 'none',
                                    },
                                },
                            },
                        ],
                    },
                ],
            });
        }


@Component({
    selector: 'ngx-solar',
    styleUrls: ['./solar.component.scss'],
    template: `
    <nb-card size="xsmall" class="solar-card">
      <nb-card-header>Solar Energy Consumption</nb-card-header>
      <nb-card-body>

6. 421 kWh

out of 8.421 kWh

      </nb-card-body>
    </nb-card>
  `,
})
export class SolarComponent implements AfterViewInit, OnDestroy {

    private value = 0;

    @Input('chartValue')
    set chartValue(value: number) {
        this.value = value;
        if (this.option.series) {
            this.option.series[0].data[0].value = value;
            this.option.series[0].data[1].value = 100 - value;
            this.option.series[1].data[0].value = value;
        }
    }

    option: any = {};
    themeSubscription: any;

    constructor(private theme: NbThemeService) {
    }

    ngAfterViewInit() {
        this.themeSubscription = this.theme.getJsTheme().delay(1).subscribe(config => {

            const solarTheme: any = config.variables.solar;

            this.option = Object.assign({}, {
                tooltip: {
                    trigger: 'item',
                    formatter: '{a}
{b} : {c} ({d}%)',
                },
                series: [
                    {
                        name: ' ',
                        clockWise: true,
                        hoverAnimation: false,
                        type: 'pie',
                        center: ['45%', '50%'],
                        radius: solarTheme.radius,
                        data: [
                            {
                                value: this.value,
                                name: ' ',
                                label: {
                                    normal: {
                                        position: 'center',
                                        formatter: '{d}%',
                                        textStyle: {
                                            fontSize: '22',
                                            fontFamily: config.variables.fontSecondary,
                                            fontWeight: '600',
                                            color: config.variables.fgHeading,
                                        },
                                    },
                                },
                                tooltip: {
                                    show: false,
                                },
                                itemStyle: {
                                    normal: {
                                        color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
                                            {
                                                offset: 0,
                                                color: solarTheme.gradientLeft,
                                            },
                                            {
                                                offset: 1,
                                                color: solarTheme.gradientRight,
                                            },
                                        ]),
                                        shadowColor: solarTheme.shadowColor,
                                        shadowBlur: 0,
                                        shadowOffsetX: 0,
                                        shadowOffsetY: 3,
                                    },
                                },
                                hoverAnimation: false,
                            },
                            {
                                value: 100 - this.value,
                                name: ' ',
                                tooltip: {
                                    show: false,
                                },
                                label: {
                                    normal: {
                                        position: 'inner',
                                    },
                                },
                                itemStyle: {
                                    normal: {
                                        color: config.variables.layoutBg,
                                    },
                                },
                            },
                        ],
                    },
                    {
                        name: ' ',
                        clockWise: true,
                        hoverAnimation: false,
                        type: 'pie',
                        center: ['45%', '50%'],
                        radius: solarTheme.radius,
                        data: [
                            {
                                value: this.value,
                                name: ' ',
                                label: {
                                    normal: {
                                        position: 'inner',
                                        show: false,
                                    },
                                },
                                tooltip: {
                                    show: false,
                                },
                                itemStyle: {
                                    normal: {
                                        color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
                                            {
                                                offset: 0,
                                                color: solarTheme.gradientLeft,
                                            },
                                            {
                                                offset: 1,
                                                color: solarTheme.gradientRight,
                                            },
                                        ]),
                                        shadowColor: solarTheme.shadowColor,
                                        shadowBlur: 7,
                                    },
                                },
                                hoverAnimation: false,
                            },
                            {
                                value: 28,
                                name: ' ',
                                tooltip: {
                                    show: false,
                                },
                                label: {
                                    normal: {
                                        position: 'inner',
                                    },
                                },
                                itemStyle: {
                                    normal: {
                                        color: 'none',
                                    },
                                },
                            },
                        ],
                    },
                ],
            });
        });
    }

    ngOnDestroy() {
        this.themeSubscription.unsubscribe();
    }
}


ngAfterViewInit() {
        this.themeSubscription = this.theme.getJsTheme().delay(1).subscribe(config => {

            const solarTheme: any = config.variables.solar;

            this.option = Object.assign({}, {
                tooltip: {
                    trigger: 'item',
                    formatter: '{a} <br/>{b} : {c} ({d}%)',
                },
                series: [
                    {
                        name: ' ',
                        clockWise: true,
                        hoverAnimation: false,
                        type: 'pie',
                        center: ['45%', '50%'],
                        radius: solarTheme.radius,
                        data: [
                            {
                                value: this.value,
                                name: ' ',
                                label: {
                                    normal: {
                                        position: 'center',
                                        formatter: '{d}%',
                                        textStyle: {
                                            fontSize: '22',
                                            fontFamily: config.variables.fontSecondary,
                                            fontWeight: '600',
                                            color: config.variables.fgHeading,
                                        },
                                    },
                                },
                                tooltip: {
                                    show: false,
                                },
                                itemStyle: {
                                    normal: {
                                        color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
                                            {
                                                offset: 0,
                                                color: solarTheme.gradientLeft,
                                            },
                                            {
                                                offset: 1,
                                                color: solarTheme.gradientRight,
                                            },
                                        ]),
                                        shadowColor: solarTheme.shadowColor,
                                        shadowBlur: 0,
                                        shadowOffsetX: 0,
                                        shadowOffsetY: 3,
                                    },
                                },
                                hoverAnimation: false,
                            },
                            {
                                value: 100 - this.value,
                                name: ' ',
                                tooltip: {
                                    show: false,
                                },
                                label: {
                                    normal: {
                                        position: 'inner',
                                    },
                                },
                                itemStyle: {
                                    normal: {
                                        color: config.variables.layoutBg,
                                    },
                                },
                            },
                        ],
                    },
                    {
                        name: ' ',
                        clockWise: true,
                        hoverAnimation: false,
                        type: 'pie',
                        center: ['45%', '50%'],
                        radius: solarTheme.radius,
                        data: [
                            {
                                value: this.value,
                                name: ' ',
                                label: {
                                    normal: {
                                        position: 'inner',
                                        show: false,
                                    },
                                },
                                tooltip: {
                                    show: false,
                                },
                                itemStyle: {
                                    normal: {
                                        color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
                                            {
                                                offset: 0,
                                                color: solarTheme.gradientLeft,
                                            },
                                            {
                                                offset: 1,
                                                color: solarTheme.gradientRight,
                                            },
                                        ]),
                                        shadowColor: solarTheme.shadowColor,
                                        shadowBlur: 7,
                                    },
                                },
                                hoverAnimation: false,
                            },
                            {
                                value: 28,
                                name: ' ',
                                tooltip: {
                                    show: false,
                                },
                                label: {
                                    normal: {
                                        position: 'inner',
                                    },
                                },
                                itemStyle: {
                                    normal: {
                                        color: 'none',
                                    },
                                },
                            },
                        ],
                    },
                ],
            });
        });
    }


ngOnDestroy() {
        this.themeSubscription.unsubscribe();
    }


(e: React.MouseEvent<HTMLElement>, href: string) => {
										e.preventDefault();
										this.props.history.replace(href);
									}


(e: React.MouseEvent<HTMLElement>, href: string) => {
														e.preventDefault();
														this.props.history.replace(href);
													}


export class ButtonComp extends React.Component<ButtonCompProps.IProps, ButtonCompState.IState> {
	//#region Статические переменные

	public static displayName: string = "ButtonComp";
	public static propTypes: PropTypes.ValidationMap<ButtonCompProps.IProps> = ButtonCompProps.types;
	public static defaultProps: ButtonCompProps.IProps = ButtonCompProps.defaults;

	//#endregion

	//#region Приватные переменные

	//#endregion

	//#region Приватные методы

	/**
	 * Начальное состояние свойств по умолчанию.
	 *
	 * @class ButtonComp
	 * @private
	 */
	private _getInitialState(): ButtonCompState.IState {
		return {
			// Empty
		}
	}

	private _handleClick(event: any) {
		// Empty
	}

	//#endregion

	/**
	 * Конструктор класса.
	 *
	 * @class ButtonComp
	 * @public
	 * @constructor
	 * @param {ButtonCompProps.IProps} props Свойства компонента.
	 */
	public constructor(props?: ButtonCompProps.IProps) {
		super(props);

		this.state = this._getInitialState();
	}

	/**
	 * Отрисовывает компонент.
	 *
	 * @class ButtonComp
	 * @public
	 */
	public render(): JSX.Element {
		return (
			<Layout>

							<Heading {...{
								requirements: {
									htmlTag: HtmlTagTypes.H1,
									align: AlignTransform.toStr(AlignTypes.Left),
									viewStyle: { stylesheet: headingStyles, bem: { block: "heading" } }
								},
								items: [{
									type: Data.Schema.ComponentTypes.Node,
									requirements: {
										content: "Кнопка"
									}
								}]
							}} />

Используется для создания различных типов кнопок.

Смотри: <Hyperlink {...{
								requirements: {
									to: RouteConstants.Home,
									onClick: (e: React.MouseEvent<HTMLElement>, href: string) => {
										e.preventDefault();
										this.props.history.replace(href);
									},
									viewStyle: { stylesheet: linkStyles, bem: { block: "link" } },
								},
								items: [{
									type: Data.Schema.ComponentTypes.Node,
									requirements: {
										content: "Icon"
									}
								}]
							}} />

								<Button {...{
									requirements: {
										htmlTag: HtmlTagTypes.Button,
										onClick: this._handleClick,
										viewStyle: { stylesheet: buttonStyles, bem: { block: "btn", modifiers: ["primary"] }, extracts: "block" }
									},
									items: [{
										type: Data.Schema.ComponentTypes.Node,
										requirements: {
											content: "Block"
										}
									}]
								}} />

{"import { Button } from '@timcowebapps/react.toolkit'"}

							<Heading {...{
								requirements: {
									htmlTag: HtmlTagTypes.H2,
									align: AlignTransform.toStr(AlignTypes.Left),
									viewStyle: { stylesheet: headingStyles, bem: { block: "heading" } }
								},
								items: [{
									type: Data.Schema.ComponentTypes.Node,
									requirements: {
										content: "Схема компонента"
									}
								}]
							}} />

										Свойство
										Тип
										Описание

										uid
										String
										Уникальный идентификатор компонента

										requirements.htmlTag
										Number
										Html тег элемента. Допустимые значения <Hyperlink {...{
												requirements: {
													to: RouteConstants.Home,
													onClick: (e: React.MouseEvent<HTMLElement>, href: string) => {
														e.preventDefault();
														this.props.history.replace(href);
													},
													viewStyle: { stylesheet: linkStyles, bem: { block: "link" } },
												},
												items: [{
													type: Data.Schema.ComponentTypes.Node,
													requirements: {
														content: "HtmlTagTypes"
													}
												}]
											}} /> перечислителя: HtmlTagTypes.Button (по умолчанию), HtmlTagTypes.A

										requirements.onClick
										Function
										Обработчик клика по кнопке

										requirements.value
										String
										Значение

										requirements.viewStyle.stylesheet
										Object
										Карта каскадных стилей

										requirements.viewStyle.bem.block
										String
										Имя блока

										requirements.viewStyle.bem.modifiers
										Array<String>
										Имена модификаторов

			</Layout>
		);
	}
}


//#endregion
//#region Приватные переменные
//#endregion
//#region Приватные методы
/**
	 * Начальное состояние свойств по умолчанию.
	 *
	 * @class ButtonComp
	 * @private
	 */
private _getInitialState(): ButtonCompState.IState {
		return {
			// Empty
		}
	}


private _handleClick(event: any) {
		// Empty
	}


/**
	 * Отрисовывает компонент.
	 *
	 * @class ButtonComp
	 * @public
	 */
public render(): JSX.Element {
		return (
			<Layout>

							<Heading {...{
								requirements: {
									htmlTag: HtmlTagTypes.H1,
									align: AlignTransform.toStr(AlignTypes.Left),
									viewStyle: { stylesheet: headingStyles, bem: { block: "heading" } }
								},
								items: [{
									type: Data.Schema.ComponentTypes.Node,
									requirements: {
										content: "Кнопка"
									}
								}]
							}} />

Используется для создания различных типов кнопок.

Смотри: <Hyperlink {...{
								requirements: {
									to: RouteConstants.Home,
									onClick: (e: React.MouseEvent<HTMLElement>, href: string) => {
										e.preventDefault();
										this.props.history.replace(href);
									},
									viewStyle: { stylesheet: linkStyles, bem: { block: "link" } },
								},
								items: [{
									type: Data.Schema.ComponentTypes.Node,
									requirements: {
										content: "Icon"
									}
								}]
							}} />

								<Button {...{
									requirements: {
										htmlTag: HtmlTagTypes.Button,
										onClick: this._handleClick,
										viewStyle: { stylesheet: buttonStyles, bem: { block: "btn", modifiers: ["primary"] }, extracts: "block" }
									},
									items: [{
										type: Data.Schema.ComponentTypes.Node,
										requirements: {
											content: "Block"
										}
									}]
								}} />

{"import { Button } from '@timcowebapps/react.toolkit'"}

							<Heading {...{
								requirements: {
									htmlTag: HtmlTagTypes.H2,
									align: AlignTransform.toStr(AlignTypes.Left),
									viewStyle: { stylesheet: headingStyles, bem: { block: "heading" } }
								},
								items: [{
									type: Data.Schema.ComponentTypes.Node,
									requirements: {
										content: "Схема компонента"
									}
								}]
							}} />

										Свойство
										Тип
										Описание

										uid
										String
										Уникальный идентификатор компонента

										requirements.htmlTag
										Number
										Html тег элемента. Допустимые значения <Hyperlink {...{
												requirements: {
													to: RouteConstants.Home,
													onClick: (e: React.MouseEvent<HTMLElement>, href: string) => {
														e.preventDefault();
														this.props.history.replace(href);
													},
													viewStyle: { stylesheet: linkStyles, bem: { block: "link" } },
												},
												items: [{
													type: Data.Schema.ComponentTypes.Node,
													requirements: {
														content: "HtmlTagTypes"
													}
												}]
											}} /> перечислителя: HtmlTagTypes.Button (по умолчанию), HtmlTagTypes.A

										requirements.onClick
										Function
										Обработчик клика по кнопке

										requirements.value
										String
										Значение

										requirements.viewStyle.stylesheet
										Object
										Карта каскадных стилей

										requirements.viewStyle.bem.block
										String
										Имя блока

										requirements.viewStyle.bem.modifiers
										Array<String>
										Имена модификаторов

			</Layout>
		);
	}


(plant: PlantsEdge) => {
      /* eslint-disable  no-case-declarations */
      switch (plant.node.parentVegetable.contentfulid.substring(0, 1).toLowerCase()) {
        case 'v':
          let vegetablesInFamilies: { [id: string]: PlantsEdge[] } | undefined = vegetablesByParent[0].subplants.find(
            parentVege => {
              return parentVege[plant.node.parentVegetable.name]
            },
          )
          if (vegetablesInFamilies === undefined) {
            vegetablesInFamilies = {}
            vegetablesInFamilies[plant.node.parentVegetable.name] = []
            vegetablesByParent[0].subplants.push(vegetablesInFamilies)
          }
          vegetablesInFamilies[plant.node.parentVegetable.name].push(plant)

          break
        case 'f':
          let fruitsInFamilies: { [id: string]: PlantsEdge[] } | undefined = vegetablesByParent[1].subplants.find(
            parentVege => {
              return parentVege[plant.node.parentVegetable.name]
            },
          )
          if (fruitsInFamilies === undefined) {
            fruitsInFamilies = {}
            fruitsInFamilies[plant.node.parentVegetable.name] = []
            vegetablesByParent[1].subplants.push(fruitsInFamilies)
          }
          fruitsInFamilies[plant.node.parentVegetable.name].push(plant)
          break
        case 'h':
          let herbsInFamilies: { [id: string]: PlantsEdge[] } | undefined = vegetablesByParent[2].subplants.find(
            parentVege => {
              return parentVege[plant.node.parentVegetable.name]
            },
          )
          if (herbsInFamilies === undefined) {
            herbsInFamilies = {}
            herbsInFamilies[plant.node.parentVegetable.name] = []
            vegetablesByParent[2].subplants.push(herbsInFamilies)
          }
          herbsInFamilies[plant.node.parentVegetable.name].push(plant)
          break
        case 'g':
          let grainsInFamilies: { [id: string]: PlantsEdge[] } | undefined = vegetablesByParent[3].subplants.find(
            parentVege => {
              return parentVege[plant.node.parentVegetable.name]
            },
          )
          if (grainsInFamilies === undefined) {
            grainsInFamilies = {}
            grainsInFamilies[plant.node.parentVegetable.name] = []
            vegetablesByParent[3].subplants.push(grainsInFamilies)
          }
          grainsInFamilies[plant.node.parentVegetable.name].push(plant)
          break
        default:
          return
      }
    }


parentVege => {
              return parentVege[plant.node.parentVegetable.name]
            }


(vegetableParent, vegParentIndex) => {
                return (

                    {vegetableParent.type.toLowerCase() === 'vegetables' && (
                      <ArticleImageParent key={vegParentIndex}>
                        <ArticleInside
                          style={{
                            backgroundImage: `url("//images.ctfassets.net/ce6fbxhy1t51/1ivQJbUcXJJUiHGiL9d4tN/9566fedf02d1c8c22c9dd3b840807c6f/asparagus-raw.jpg")`,
                          }}
                        />
                        <OverlayContainer>
                          <ArticleOverlay key={vegParentIndex}>

sdfdsds

                            <ArticleDescription>sdfdsfd</ArticleDescription>
                          </ArticleOverlay>
                        </OverlayContainer>
                      </ArticleImageParent>


(vegPlant, index) => {
                      return (

                          {Object.keys(vegPlant).map((key, index) => {
                            return (

                                <VegetableGroup>
                                  <VegetableGroupTitle>{key}</VegetableGroupTitle>

                                    {vegPlant[key].map((plant: PlantsEdge, index: number) => {
                                      return (

                                          <LazyLoad
                                            style={{ width: '100%', backgroundColor: '#fefefe' }}
                                            once
                                            offset={100}
                                          >
                                            <picture>
                                              <source
                                                type="image/webp"
                                                srcSet={`${plant.node.bannerImage.file.url}?fm=webp&q=70&w=${Math.round(
                                                  windowWidth,
                                                )}&h=${Math.round(windowWidth)}&fit=fill`}
                                              />
                                              <source
                                                type="image/jpg"
                                                srcSet={`${plant.node.bannerImage.file.url}?fm=jpg&q=70&w=${Math.round(
                                                  windowWidth,
                                                )}&h=${Math.round(windowWidth)}&fit=fill`}
                                              />

                                            </picture>
                                          </LazyLoad>
                                          <VegetableTitle className="center">{plant.node.title}</VegetableTitle>
                                          <PrimaryButton>Learn More</PrimaryButton>

                                      )
                                    }


(key, index) => {
                            return (

                                <VegetableGroup>
                                  <VegetableGroupTitle>{key}</VegetableGroupTitle>

                                    {vegPlant[key].map((plant: PlantsEdge, index: number) => {
                                      return (

                                          <LazyLoad
                                            style={{ width: '100%', backgroundColor: '#fefefe' }}
                                            once
                                            offset={100}
                                          >
                                            <picture>
                                              <source
                                                type="image/webp"
                                                srcSet={`${plant.node.bannerImage.file.url}?fm=webp&q=70&w=${Math.round(
                                                  windowWidth,
                                                )}&h=${Math.round(windowWidth)}&fit=fill`}
                                              />
                                              <source
                                                type="image/jpg"
                                                srcSet={`${plant.node.bannerImage.file.url}?fm=jpg&q=70&w=${Math.round(
                                                  windowWidth,
                                                )}&h=${Math.round(windowWidth)}&fit=fill`}
                                              />

                                            </picture>
                                          </LazyLoad>
                                          <VegetableTitle className="center">{plant.node.title}</VegetableTitle>
                                          <PrimaryButton>Learn More</PrimaryButton>


(plant: PlantsEdge, index: number) => {
                                      return (
                                        <div className="col4" key={index}>
                                          <LazyLoad
                                            style={{ width: '100%', backgroundColor: '#fefefe' }}
                                            once
                                            offset={100}
                                          >
                                            <picture>
                                              <source
                                                type="image/webp"
                                                srcSet={`${plant.node.bannerImage.file.url}?fm=webp&q=70&w=${Math.round(
                                                  windowWidth,
                                                )}&h=${Math.round(windowWidth)}&fit=fill`}


class PlantsIndex extends React.Component<PlantsProps> {
  render() {
    /* eslint-disable  @typescript-eslint/no-var-requires */
    /* eslint-disable  no-undef */
    const contentful = require('contentful')
    const contentfulConfig = require('../../.contentful.json')
    /* eslint-enable  @typescript-eslint/no-var-requires */
    /* eslint-enable  no-undef */

    const posts: PlantsEdge[] = get(this, 'props.data.allContentfulVegetable.edges')
    const vegetablesByParent = [
      {
        type: 'Vegetables',
        subplants: new Array<{ [id: string]: PlantsEdge[] }>(),
      },
      {
        type: 'Fruits',
        subplants: new Array<{ [id: string]: PlantsEdge[] }>(),
      },
      {
        type: 'Herbs',
        subplants: new Array<{ [id: string]: PlantsEdge[] }>(),
      },
      {
        type: 'Grains',
        subplants: new Array<{ [id: string]: PlantsEdge[] }>(),
      },
    ]
    posts.map((plant: PlantsEdge) => {
      /* eslint-disable  no-case-declarations */
      switch (plant.node.parentVegetable.contentfulid.substring(0, 1).toLowerCase()) {
        case 'v':
          let vegetablesInFamilies: { [id: string]: PlantsEdge[] } | undefined = vegetablesByParent[0].subplants.find(
            parentVege => {
              return parentVege[plant.node.parentVegetable.name]
            },
          )
          if (vegetablesInFamilies === undefined) {
            vegetablesInFamilies = {}
            vegetablesInFamilies[plant.node.parentVegetable.name] = []
            vegetablesByParent[0].subplants.push(vegetablesInFamilies)
          }
          vegetablesInFamilies[plant.node.parentVegetable.name].push(plant)

          break
        case 'f':
          let fruitsInFamilies: { [id: string]: PlantsEdge[] } | undefined = vegetablesByParent[1].subplants.find(
            parentVege => {
              return parentVege[plant.node.parentVegetable.name]
            },
          )
          if (fruitsInFamilies === undefined) {
            fruitsInFamilies = {}
            fruitsInFamilies[plant.node.parentVegetable.name] = []
            vegetablesByParent[1].subplants.push(fruitsInFamilies)
          }
          fruitsInFamilies[plant.node.parentVegetable.name].push(plant)
          break
        case 'h':
          let herbsInFamilies: { [id: string]: PlantsEdge[] } | undefined = vegetablesByParent[2].subplants.find(
            parentVege => {
              return parentVege[plant.node.parentVegetable.name]
            },
          )
          if (herbsInFamilies === undefined) {
            herbsInFamilies = {}
            herbsInFamilies[plant.node.parentVegetable.name] = []
            vegetablesByParent[2].subplants.push(herbsInFamilies)
          }
          herbsInFamilies[plant.node.parentVegetable.name].push(plant)
          break
        case 'g':
          let grainsInFamilies: { [id: string]: PlantsEdge[] } | undefined = vegetablesByParent[3].subplants.find(
            parentVege => {
              return parentVege[plant.node.parentVegetable.name]
            },
          )
          if (grainsInFamilies === undefined) {
            grainsInFamilies = {}
            grainsInFamilies[plant.node.parentVegetable.name] = []
            vegetablesByParent[3].subplants.push(grainsInFamilies)
          }
          grainsInFamilies[plant.node.parentVegetable.name].push(plant)
          break
        default:
          return
      }
    })

    const BodyCopy = styled.div`
      column-count: 2;
      column-gap: 40px;
      color: #464646;
      font-size: 1em;
      font-family: 'Roboto', sans-serif;
      line-height: 2em;
      padding-top: 1.875em;
      padding-bottom: 1.875em;
      text-align: justify;
`

    const VideoBackgroundContainer = styled.div`
      position: relative;
      overflow: hidden;
      top: 0;
      left: 0;
      width: 100vw;
      height: 100vh;
`

    const HeroVideo = styled.video`
      position: absolute;
      z-index: 99;
      max-width: 100%;
`

    const ArticleInside = styled.div`
      display: block;
      background-size: cover;
      background-repeat: no-repeat;
      padding-top: 56%;
      -ms-transform: scale(1);
      -moz-transform: scale(1);
      -webkit-transform: scale(1);
      -o-transform: scale(1);
      transform: scale(1);
      -webkit-transition: all 1s;
      -moz-transition: all 1s;
      -o-transition: all 1s;
      transition: all 1s;

      &::before {
        position: absolute;
        content: ' ';
        top: 0;
        left: 0;
        width: 100%;
        height: 100%;
        display: block;
        z-index: 0;
        background-color: rgba(51, 51, 51, 0.25);
      }
`

    const ArticleImageParent = styled.div`
      width: 100%;
      overflow: hidden;
      position: relative;
`

    const ArticleOverlay = styled.div`
      position: absolute;
      z-index: 999;
      bottom: 20px;
      left: 20px;
      width: calc(100% - 40px);
      color: #fff;
`

    const OverlayContainer = styled.div`
      position: absolute;
      width: 100%;
      height: 100%;
      top: 0;
      bottom: 20px;
      overflow: hidden;
`

    const ArticleDescription = styled.div`
      font-family: 'Roboto', sans-serif;
      font-size: 12px;
      font-weight: 300;
      color: #fff;
      height: 100px;
      max-height: 100px;
      display: block;
      padding-top: 20px;
`

    const VegetableGroup = styled.div`
      padding-top: 20px;
      padding-bottom: 40px;
`

    const VegetableGroupTitle = styled.h2`
      font-family: 'Roboto', sans-serif;
      font-size: 1.5em;
      font-weight: 600;
      color: #333;
      display: block;
`

    const VegetableTitle = styled.h2`
      font-family: 'Roboto', sans-serif;
      font-size: 1em;
      font-weight: 300;
      color: #333;
      display: block;
`

    const PrimaryButton = styled.button`
      background-color: #0f9114;
      border: none;
      font-family: 'Roboto', sans-serif;
      font-size: 0.75rem;
      color: #fff;
      text-align: center;
      margin: 20px auto;
      display: block;
      font-weight: 600;
      text-transform: uppercase;
      padding: 15px 25px;
      letter-spacing: 2px;
`
    const windowWidth = typeof window !== 'undefined' ? window.innerWidth : 900
    return (
      <Layout>
        <div style={{ background: '#fff', paddingTop: '250px', position: 'absolute', top: '0', width: '100%' }}


render() {
    /* eslint-disable  @typescript-eslint/no-var-requires */
    /* eslint-disable  no-undef */
    const contentful = require('contentful')
    const contentfulConfig = require('../../.contentful.json')
    /* eslint-enable  @typescript-eslint/no-var-requires */
    /* eslint-enable  no-undef */

    const posts: PlantsEdge[] = get(this, 'props.data.allContentfulVegetable.edges')
    const vegetablesByParent = [
      {
        type: 'Vegetables',
        subplants: new Array<{ [id: string]: PlantsEdge[] }>(),
      },
      {
        type: 'Fruits',
        subplants: new Array<{ [id: string]: PlantsEdge[] }>(),
      },
      {
        type: 'Herbs',
        subplants: new Array<{ [id: string]: PlantsEdge[] }>(),
      },
      {
        type: 'Grains',
        subplants: new Array<{ [id: string]: PlantsEdge[] }>(),
      },
    ]
    posts.map((plant: PlantsEdge) => {
      /* eslint-disable  no-case-declarations */
      switch (plant.node.parentVegetable.contentfulid.substring(0, 1).toLowerCase()) {
        case 'v':
          let vegetablesInFamilies: { [id: string]: PlantsEdge[] } | undefined = vegetablesByParent[0].subplants.find(
            parentVege => {
              return parentVege[plant.node.parentVegetable.name]
            },
          )
          if (vegetablesInFamilies === undefined) {
            vegetablesInFamilies = {}
            vegetablesInFamilies[plant.node.parentVegetable.name] = []
            vegetablesByParent[0].subplants.push(vegetablesInFamilies)
          }
          vegetablesInFamilies[plant.node.parentVegetable.name].push(plant)

          break
        case 'f':
          let fruitsInFamilies: { [id: string]: PlantsEdge[] } | undefined = vegetablesByParent[1].subplants.find(
            parentVege => {
              return parentVege[plant.node.parentVegetable.name]
            },
          )
          if (fruitsInFamilies === undefined) {
            fruitsInFamilies = {}
            fruitsInFamilies[plant.node.parentVegetable.name] = []
            vegetablesByParent[1].subplants.push(fruitsInFamilies)
          }
          fruitsInFamilies[plant.node.parentVegetable.name].push(plant)
          break
        case 'h':
          let herbsInFamilies: { [id: string]: PlantsEdge[] } | undefined = vegetablesByParent[2].subplants.find(
            parentVege => {
              return parentVege[plant.node.parentVegetable.name]
            },
          )
          if (herbsInFamilies === undefined) {
            herbsInFamilies = {}
            herbsInFamilies[plant.node.parentVegetable.name] = []
            vegetablesByParent[2].subplants.push(herbsInFamilies)
          }
          herbsInFamilies[plant.node.parentVegetable.name].push(plant)
          break
        case 'g':
          let grainsInFamilies: { [id: string]: PlantsEdge[] } | undefined = vegetablesByParent[3].subplants.find(
            parentVege => {
              return parentVege[plant.node.parentVegetable.name]
            },
          )
          if (grainsInFamilies === undefined) {
            grainsInFamilies = {}
            grainsInFamilies[plant.node.parentVegetable.name] = []
            vegetablesByParent[3].subplants.push(grainsInFamilies)
          }
          grainsInFamilies[plant.node.parentVegetable.name].push(plant)
          break
        default:
          return
      }
    })

    const BodyCopy = styled.div`
      column-count: 2;
      column-gap: 40px;
      color: #464646;
      font-size: 1em;
      font-family: 'Roboto', sans-serif;
      line-height: 2em;
      padding-top: 1.875em;
      padding-bottom: 1.875em;
      text-align: justify;
`

    const VideoBackgroundContainer = styled.div`
      position: relative;
      overflow: hidden;
      top: 0;
      left: 0;
      width: 100vw;
      height: 100vh;
`

    const HeroVideo = styled.video`
      position: absolute;
      z-index: 99;
      max-width: 100%;
`

    const ArticleInside = styled.div`
      display: block;
      background-size: cover;
      background-repeat: no-repeat;
      padding-top: 56%;
      -ms-transform: scale(1);
      -moz-transform: scale(1);
      -webkit-transform: scale(1);
      -o-transform: scale(1);
      transform: scale(1);
      -webkit-transition: all 1s;
      -moz-transition: all 1s;
      -o-transition: all 1s;
      transition: all 1s;

      &::before {
        position: absolute;
        content: ' ';
        top: 0;
        left: 0;
        width: 100%;
        height: 100%;
        display: block;
        z-index: 0;
        background-color: rgba(51, 51, 51, 0.25);
      }
`

    const ArticleImageParent = styled.div`
      width: 100%;
      overflow: hidden;
      position: relative;
`

    const ArticleOverlay = styled.div`
      position: absolute;
      z-index: 999;
      bottom: 20px;
      left: 20px;
      width: calc(100% - 40px);
      color: #fff;
`

    const OverlayContainer = styled.div`
      position: absolute;
      width: 100%;
      height: 100%;
      top: 0;
      bottom: 20px;
      overflow: hidden;
`

    const ArticleDescription = styled.div`
      font-family: 'Roboto', sans-serif;
      font-size: 12px;
      font-weight: 300;
      color: #fff;
      height: 100px;
      max-height: 100px;
      display: block;
      padding-top: 20px;
`

    const VegetableGroup = styled.div`
      padding-top: 20px;
      padding-bottom: 40px;
`

    const VegetableGroupTitle = styled.h2`
      font-family: 'Roboto', sans-serif;
      font-size: 1.5em;
      font-weight: 600;
      color: #333;
      display: block;
`

    const VegetableTitle = styled.h2`
      font-family: 'Roboto', sans-serif;
      font-size: 1em;
      font-weight: 300;
      color: #333;
      display: block;
`

    const PrimaryButton = styled.button`
      background-color: #0f9114;
      border: none;
      font-family: 'Roboto', sans-serif;
      font-size: 0.75rem;
      color: #fff;
      text-align: center;
      margin: 20px auto;
      display: block;
      font-weight: 600;
      text-transform: uppercase;
      padding: 15px 25px;
      letter-spacing: 2px;
`
    const windowWidth = typeof window !== 'undefined' ? window.innerWidth : 900
    return (
      <Layout>
        <div style={{ background: '#fff', paddingTop: '250px', position: 'absolute', top: '0', width: '100%' }}


async (req: Request, res: Response) =>{
    try {
        const getVideosDetaisUC = new VideoDetailsUC(new VideosDetailsDB())
        const result = await getVideosDetaisUC.execute({videoId: req.params.videoId})

        res.status(200).send(result)
    } catch (error) {
        res.status(400).send(error.message)
    }
}


(props: Props) => {
  return (
    <>
      <Point>

1번

2번

3번

4번

5번

6번

7번

8번

8번

8번

8번

8번

      </Point>
      <Instruction
        show={true}
        items={[
          {
            groupNumber: 0,
            type: 'topLeft',
            selector: '[data-guide="1"]',
            message: '1번 입니다.',
          },
          {
            groupNumber: 0,
            type: 'topRight',
            selector: '[data-guide="2"]',
            message: '2번 입니다.',
          },
          {
            groupNumber: 0,
            type: 'bottomLeft',
            selector: '[data-guide="3"]',
            message: '3번 입니다.',
          },
          {
            groupNumber: 0,
            type: 'bottomRight',
            selector: '[data-guide="4"]',
            message: '4번 입니다.',
          },
          {
            groupNumber: 0,
            type: 'left-to-topLeft',
            selector: '[data-guide="5"]',
            message: '5번 입니다.',
          },
          {
            groupNumber: 0,
            type: 'left-to-topRight',
            selector: '[data-guide="6"]',
            message: '6번 입니다.',
          },
          {
            groupNumber: 0,
            type: 'left-to-bottomLeft',
            selector: '[data-guide="7"]',
            message: '7번 입니다.',
          },
          {
            groupNumber: 0,
            type: 'left-to-bottomRight',
            selector: '[data-guide="8"]',
            message: '8번 입니다.',
          },
          {
            groupNumber: 0,
            type: 'right-to-topLeft',
            selector: '[data-guide="9"]',
            message: '5번 입니다.',
          },
          {
            groupNumber: 0,
            type: 'right-to-topRight',
            selector: '[data-guide="10"]',
            message: '6번 입니다.',
          },
          {
            groupNumber: 0,
            type: 'right-to-bottomLeft',
            selector: '[data-guide="11"]',
            message: '7번 입니다.',
          },
          {
            groupNumber: 0,
            type: 'right-to-bottomRight',
            selector: '[data-guide="12"]',
            message: '8번 입니다.',
          },
        ]}
      />
    </>


@Component({
  selector: 'example-call-control-active',
  template: `
    <md-call-control
      type="microphone-muted"
      ariaLabel="For the Win"
      [active]="true"
      (click)="onClick()"
    ></md-call-control>
  `,
})
export class ExampleCallControlActiveComponent {
  constructor() {}

  onClick() {
    alert('click');
  }
}


onClick() {
    alert('click');
  }


event => event instanceof NavigationEnd


() => this.activatedRoute


route => {
          while (route.firstChild) route = route.firstChild;
          return route;
        }


route => route.outlet === 'primary'


route => route.params


params => this.getNamespace(params)


n => n


@Injectable()
export class NamespaceScope implements INamespaceScope {
  public namespace: Observable<string>;

  constructor(protected activatedRoute: ActivatedRoute, protected router: Router) {
    this.namespace = this.router.events
      .filter(event => event instanceof NavigationEnd)
      .map(() => this.activatedRoute)
      .map(
        route => {
          while (route.firstChild) route = route.firstChild;
          return route;
        })
      .filter(route => route.outlet === 'primary')
      .mergeMap(route => route.params).map(params => this.getNamespace(params)).filter(n => n).distinctUntilChanged();
  }

  protected getNamespace(params) {
    return params['namespace'] || this.getRouteParams('namespace');
  }

  protected getRouteParams(key): any {
    if (
      this.router &&
      this.router.routerState &&
      this.router.routerState.snapshot &&
      this.router.routerState.snapshot.root
    ) {
      return this.findParamsFor(this.router.routerState.snapshot.root, key);
    }
    return null;
  }

  protected findParamsFor(route, key): any {
    let children = route.children;
    for (let child of children) {
      let params = child.params;
      if (params) {
        let answer = params[key];
        if (!answer) {
          answer = this.findParamsFor(child, key);
        }
        if (answer) {
          return answer;
        }
      }
    }
    return null;
  }

  currentNamespace() {
    return this.findParamsFor(this.router.routerState.snapshot.root, "namespace");
  }
}


export interface INamespaceScope {
  namespace: Observable<string>;

  currentNamespace(): string;
}


protected getNamespace(params) {
    return params['namespace'] || this.getRouteParams('namespace');
  }


protected getRouteParams(key): any {
    if (
      this.router &&
      this.router.routerState &&
      this.router.routerState.snapshot &&
      this.router.routerState.snapshot.root
    ) {
      return this.findParamsFor(this.router.routerState.snapshot.root, key);
    }
    return null;
  }


protected findParamsFor(route, key): any {
    let children = route.children;
    for (let child of children) {
      let params = child.params;
      if (params) {
        let answer = params[key];
        if (!answer) {
          answer = this.findParamsFor(child, key);
        }
        if (answer) {
          return answer;
        }
      }
    }
    return null;
  }


currentNamespace() {
    return this.findParamsFor(this.router.routerState.snapshot.root, "namespace");
  }


() => {
  window.blocklet = undefined;
}


() => {
  window.blocklet = {
    prefix: 'https://baidu.com',
  };

  const app = new Request(axios);
  const axiosConfig = {
    baseURL: '',
    timeout: 3000,
  };

  const config = app.handleRequest(axiosConfig);
  expect(config.baseURL).toBe('https://baidu.com');
  expect(config.timeout).toBe(200000);
  expect(app.handleResponse({ data: 100 } as any)).toBe(100);
}


() => {
  window.blocklet = {
    prefix: '',
  };

  const app = new Request(axios);
  const axiosConfig = {
    baseURL: '',
    timeout: 3000,
  };

  const config = app.handleRequest(axiosConfig);
  expect(config.baseURL).toBe('');
  expect(config.timeout).toBe(200000);
  expect(app.handleResponse({ data: 100 } as any)).toBe(100);
}


() => {
  const app = new Request(axios);
  expect(app.handleResponse({ data: 100 } as any)).toBe(100);
}


async () => {
  const app = new Request(axios);
  expect(app.handleRequestError(null)).rejects.toBe(null);
}


async () => {
  const app = new Request(axios);
  const CancelToken = app.getCloseSoure();
  expect(CancelToken.token).not.toBeNull();
}


async () => {
  const app = new Request(axios);
  app.get('http://127.0.0.1', {});
}


async () => {
  const app = new Request(axios);
  app.post('http://127.0.0.1', {});
}


async function submitFile(): Promise<void> {
    const data = new FormData();

    if (!uploadedFiles.length) return;

    data.append('file', uploadedFiles[0].file, uploadedFiles[0].name);

    try {
      await api.post('/transactions/import', data);
      history.push('/');
    } catch (err) {
      console.log(err.response.error);
    }
  }


function handleUpload(files: File[]): void {
    const uploadFiles = files.map((file: File) => ({
      file,
      name: file.name,
      readableSize: filesize(file.size),
    }));

    setUploadedFiles(uploadFiles);
  }


() => {
  const [uploadedFiles, setUploadedFiles] = useState<FileProps[]>([]);
  const history = useHistory();

  async function submitFile(): Promise<void> {
    const data = new FormData();

    if (!uploadedFiles.length) return;

    data.append('file', uploadedFiles[0].file, uploadedFiles[0].name);

    try {
      await api.post('/transactions/import', data);
      history.push('/');
    } catch (err) {
      console.log(err.response.error);
    }
  }

  function handleUpload(files: File[]): void {
    const uploadFiles = files.map((file: File) => ({
      file,
      name: file.name,
      readableSize: filesize(file.size),
    }));

    setUploadedFiles(uploadFiles);
  }

  return (
    <>

      <Container>
        <Title>Importar uma transação</Title>
        <ImportFileContainer>
          <Upload onUpload={handleUpload} />
          {!!uploadedFiles.length && <FileList files={uploadedFiles} />}

              Permitido apenas arquivos CSV

            <button onClick={submitFile} type="button">
              Enviar
            </button>

        </ImportFileContainer>
      </Container>
    </>


(file: File) => ({
      file,
      name: file.name,
      readableSize: filesize(file.size),
    })


interface FileProps {
  file: File;
  name: string;
  readableSize: string;
}


async (request, _, config) => {
  const validator = new Validator(request, inputParameters)

  validateRequest(request)

  const jobRunID = validator.validated.id
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
  const { raceType, date, resultsType, endpoint, ...rest } = validator.validated.data
  const url = `/elections/${date}`

  const params = {
    ...rest,
    level: 'state',
    raceTypeID: raceType,
    format: 'json',
    winner: 'X',
    resultsType: resultsType,
    apikey: config.apiKey,
  }

  const options = { ...config.api, params, url }

  const response = await Requester.request<ResponseSchema>(options)
  validateResponse(response.data)

  const race = response.data.races[0]
  const reportingUnit = getReportingUnit(race.reportingUnits, rest.statePostal)
  const raceWinner = getReportingUnitWinner(reportingUnit)

  response.data.precinctsReporting = reportingUnit.precinctsReporting
  response.data.precinctsReportingPct = reportingUnit.precinctsReportingPct
  response.data.winnerFirstName = raceWinner.first
  response.data.winnerLastName = raceWinner.last
  response.data.winnerVoteCount = raceWinner.voteCount
  response.data.winnerCandidateId = raceWinner.candidateID
  response.data.winnerParty = raceWinner.party
  response.data.candidates = encodeCandidates(reportingUnit.candidates)

  return Requester.success(
    jobRunID,
    Requester.withResult(response, concatenateName(raceWinner)),
    config.verbose,
  )
}


(request: AdapterRequest) => {
  const { statePostal, officeID, raceID } = request.data
  const statePostals = statePostal.split(',')
  if (statePostals.length > 1) {
    throw new AdapterError({
      jobRunID: request.id,
      statusCode: 400,
      message: 'Adapter only supports finding results from a single state',
    })
  }
  if (!officeID && !raceID) {
    throw new AdapterError({
      jobRunID: request.id,
      statusCode: 400,
      message: 'Either officeID or raceID must be present',
    })
  }
}


(response: ResponseSchema) => {
  const races = response.races
  if (races.length === 0) {
    throw Error('We could not find any races')
  }
  if (races.length > 1) {
    throw Error("We don't support finding the winner from multiple races")
  }
}


(reportingUnits: ReportingUnit[], statePostal: string): ReportingUnit => {
  // Response should only contain a national RU if the statePostal is US but will contain both national and state for any other statePostal codes.
  const level = statePostal === 'US' ? 'national' : 'state'
  const reportingUnit = reportingUnits.find((ru) => ru.level === level)
  if (!reportingUnit) {
    throw Error('Cannot find reporting unit')
  }
  return reportingUnit
}


(ru) => ru.level === level


(reportingUnit: ReportingUnit): Candidate => {
  for (const candidate of reportingUnit.candidates) {
    if (candidate.winner === 'X') {
      return candidate
    }
  }
  throw Error('Candidate not found')
}


(candidate: Candidate): string => `${candidate.voteCount},${candidate.last}`


(candidates: Candidate[]): string[] => {
  const encodedCandidates: string[] = []
  const encodedValTypes = ['uint32', 'string', 'string', 'string', 'uint32', 'bool']
  const abiCoder = utils.defaultAbiCoder
  for (const { candidateID, party, first, last, voteCount, winner } of candidates) {
    const encodedCandidate = abiCoder.encode(encodedValTypes, [
      candidateID,
      party,
      first,
      last,
      voteCount,
      !!winner,
    ])
    encodedCandidates.push(encodedCandidate)
  }
  return encodedCandidates
}


interface Candidate {
  first: string
  last: string
  abbrv: string
  party: string
  candidateID: string
  pollID: string
  ballotOrder: number
  polNum: string
  voteCount: number
  winner?: string
}


interface ReportingUnit {
  statePostal: string
  stateName: string
  level: string
  lastUpdated: string
  precinctsReporting: number
  precinctsTotal: number
  precinctsReportingPct: number
  candidates: Candidate[]
}


export interface ResponseSchema {
  precinctsReporting: number
  precinctsReportingPct: number
  winnerFirstName: string
  winnerLastName: string
  winnerVoteCount: number
  winnerCandidateId: string
  winnerParty: string
  candidates: string[]
  electionDate: string
  timestamp: string
  races: {
    test: boolean
    resultsType: string
    raceID: string
    raceType: string
    raceTypeID: string
    offceID: string
    officeName: string
    party: string
    eevp: number
    national: boolean
    reportingUnits: ReportingUnit[]
  }[]
}


/**
 * Creates a check function that transforms a number into its integer part.
 *
 * ```js
 * const check = truncate();
 *
 * check(3.14);
 * // => {
 * //   isOk: true,
 * //   value: 3,
 * // }
 *
 * check(-3.14);
 * // => {
 * //   isOk: true,
 * //   value: -3,
 * // }
 * ```
 *
 * @returns A check function.
 */
export default function truncate(): Check<number> {
  return transform((value) =>
    value < 0 ? Math.ceil(value) : Math.floor(value),
  );
}


(value) =>
    value < 0 ? Math.ceil(value) : Math.floor(value)


export async function findLicense(owner: string, repo: string): Promise<any> {
    const ignored = checkIsIgnored("github", `${owner}/${repo}`);
    const cached = getCachedKeyForGithubRepo(owner, repo);
    if (await ignored) {
        return FOUND_IGNORED_REPO
    }
    const cachedKey = await cached;
    if (cachedKey) {
        console.log("[licenseplate] found key in cache");
        return cachedKey
    } else {
        // Note: We don't run this at the same time as checkIsIgnored
        // (even though both are async and take a bit),
        // to avoid needless requests to the github API
        let key: string = await findKey(owner, repo);
        // Create task to cache this in 2'
        //      (to avoid congestion due to this low prio task
        //       on early page load)
        setTimeout(() => cacheGithubRepos({
            owner: owner,
            repo: repo,
            lKey: key
        }).then(() => console.log(`[licenseplate]: cached ${key} for ${owner}/${repo} `)), 2);
        return key
        // return await getLicenseProperties(key)
    }

}


async function findKey(owner: string, repo: string): Promise<string> {
    const url = `https://api.github.com/repos/${owner}/${repo}`;
    let repoResponse: Response = await fetch(url);
    if (repoResponse.status === 404) {
        return FOUND_NO_REPO // Most likely a private repo
    }
    if (!repoResponse.ok) {
        throw Error(`Get request to "${url}" failed with status code ${repoResponse.status}`)
    }
    let repoInfo = await repoResponse.json();
    if (!repoInfo.license) {
        return FOUND_NO_LICENSE
    }
    // Key is `other` if a license file was found, but license not recognized
    return repoInfo.license.key
}


() => cacheGithubRepos({
            owner: owner,
            repo: repo,
            lKey: key
        }).then(() => console.log(`[licenseplate]: cached ${key} for ${owner}/${repo} `))


() => console.log(`[licenseplate]: cached ${key} for ${owner}/${repo} `)


/**
 * The set of arguments for constructing a VpnConnection resource.
 */
export interface VpnConnectionArgs {
    /**
     * Expected bandwidth in MBPS.
     */
    connectionBandwidth?: pulumi.Input<number>;
    /**
     * The name of the connection.
     */
    connectionName?: pulumi.Input<string>;
    /**
     * DPD timeout in seconds for vpn connection.
     */
    dpdTimeoutSeconds?: pulumi.Input<number>;
    /**
     * EnableBgp flag.
     */
    enableBgp?: pulumi.Input<boolean>;
    /**
     * Enable internet security.
     */
    enableInternetSecurity?: pulumi.Input<boolean>;
    /**
     * EnableBgp flag.
     */
    enableRateLimiting?: pulumi.Input<boolean>;
    /**
     * The name of the gateway.
     */
    gatewayName: pulumi.Input<string>;
    /**
     * Resource ID.
     */
    id?: pulumi.Input<string>;
    /**
     * The IPSec Policies to be considered by this connection.
     */
    ipsecPolicies?: pulumi.Input<pulumi.Input<inputs.network.v20200701.IpsecPolicyArgs>[]>;
    /**
     * The name of the resource that is unique within a resource group. This name can be used to access the resource.
     */
    name?: pulumi.Input<string>;
    /**
     * Id of the connected vpn site.
     */
    remoteVpnSite?: pulumi.Input<inputs.network.v20200701.SubResourceArgs>;
    /**
     * The resource group name of the VpnGateway.
     */
    resourceGroupName: pulumi.Input<string>;
    /**
     * The Routing Configuration indicating the associated and propagated route tables on this connection.
     */
    routingConfiguration?: pulumi.Input<inputs.network.v20200701.RoutingConfigurationArgs>;
    /**
     * Routing weight for vpn connection.
     */
    routingWeight?: pulumi.Input<number>;
    /**
     * SharedKey for the vpn connection.
     */
    sharedKey?: pulumi.Input<string>;
    /**
     * Use local azure ip to initiate connection.
     */
    useLocalAzureIpAddress?: pulumi.Input<boolean>;
    /**
     * Enable policy-based traffic selectors.
     */
    usePolicyBasedTrafficSelectors?: pulumi.Input<boolean>;
    /**
     * Connection protocol used for this connection.
     */
    vpnConnectionProtocolType?: pulumi.Input<string | enums.network.v20200701.VirtualNetworkGatewayConnectionProtocol>;
    /**
     * List of all vpn site link connections to the gateway.
     */
    vpnLinkConnections?: pulumi.Input<pulumi.Input<inputs.network.v20200701.VpnSiteLinkConnectionArgs>[]>;
}


/**
     * Get an existing VpnConnection resource's state with the given name, ID, and optional extra
     * properties used to qualify the lookup.
     *
     * @param name The _unique_ name of the resulting resource.
     * @param id The _unique_ provider ID of the resource to lookup.
     * @param opts Optional settings to control the behavior of the CustomResource.
     */
public static get(name: string, id: pulumi.Input<pulumi.ID>, opts?: pulumi.CustomResourceOptions): VpnConnection {
        return new VpnConnection(name, undefined as any, { ...opts, id: id });
    }


/**
     * Returns true if the given object is an instance of VpnConnection.  This is designed to work even
     * when multiple copies of the Pulumi SDK have been loaded into the same process.
     */
public static isInstance(obj: any): obj is VpnConnection {
        if (obj === undefined || obj === null) {
            return false;
        }
        return obj['__pulumiType'] === VpnConnection.__pulumiType;
    }


export default interface IGuestVoterRepository {
	getByCode(accessCode: string): Promise<IGuestVoterEntity | null>;
	list(createdBy: string): Promise<IGuestVoterEntity[]>
	save(guestVoter: IGuestVoterEntity): Promise<IGuestVoterEntity>;
	exists(email: string): Promise<boolean>;
	validate(accessCode: string): Promise<boolean>;
	invalidateCode(accessCode: string): Promise<void>;
	update(guestVoter: IGuestVoterEntity): Promise<IGuestVoterEntity>;
	delete(guestVoterId: string): Promise<boolean>;
}


choice => {
				if (choice === 0) {
					this._storageService.store(IS_WORKSPACE_SHELL_ALLOWED_STORAGE_KEY, true, StorageScope.WORKSPACE);
				} else {
					this._storageService.store(IS_WORKSPACE_SHELL_ALLOWED_STORAGE_KEY, false, StorageScope.WORKSPACE);
				}
				return TPromise.as(null);
			}