# domain/converters/kind.converter.ts

> 124 lines of code and 15 definitions.

Tree: Site tree
Language: typescript
Layer: processing
Canonical: https://banes-lab.com/anatomy/tree#file-domain-converters-kind-converter-ts
Source text: https://banes-lab.com/assets/sources/source.8fc7e0325781dd986a62b5d745c540ab1bbc7594383a2818edec98d2461c72dc.generated.txt

## Definitions

- `rangeSection` (lexical_declaration, line 86)
- `rangeDiagram` (lexical_declaration, line 77)
- `kindSection` (lexical_declaration, line 66)
- `forceSection` (lexical_declaration, line 115)
- `forceSubsection` (lexical_declaration, line 101)
- `kindSections` (lexical_declaration, line 125, exported)
- `kindSubsection` (lexical_declaration, line 48)
- `HEADER` (lexical_declaration, line 42)
- `SOLID` (lexical_declaration, line 43)
- `RELATION_PREFIX` (lexical_declaration, line 44)
- `UNDERSCORE` (lexical_declaration, line 45)
- `SPACE` (lexical_declaration, line 46)
- `relationNodes` (lexical_declaration, line 78)
- `kindNodes` (lexical_declaration, line 79)
- `edges` (lexical_declaration, line 80)

## Uses

- [domain/converters/ontology.converter.ts](https://banes-lab.com/source/tree/domain/converters/ontology.converter.ts.md)

## Source

```typescript
import {
    CONCERNS_LABEL,
    DISCRIMINATOR_LABEL,
    DISTINGUISHES_LABEL,
    FORCE_INTRO,
    FORCE_TITLE,
    KINDS_IN_RANGE_LABEL,
    KIND_INTRO,
    KIND_TITLE,
    PRINCIPLES_OF_KIND_LABEL,
    RANGE_CAPTION,
    RANGE_INTRO,
    RANGE_SECTION_TITLE,
    SIGNATURES_LABEL,
    TERMS_OF_KIND_LABEL,
} from "#configuration/strings/kind.strings";
import { CONTRACTS_LABEL, PRINCIPLES_LABEL } from "#configuration/strings/ontology.strings";
import {
    FORCE_ANCHOR,
    FORCE_SECTION_ID,
    KIND_ANCHOR,
    KIND_SECTION_ID,
    RANGE_SECTION_ID,
    RELATION_ANCHOR,
} from "#core/ids/ontology.ids";
import type { ForceView, KindView, RelationRangeView } from "#types/ontology.types";
import type { Section, Subsection } from "#types/document.types";
import {
    chips,
    diagram,
    edgeLine,
    glossary,
    labelled,
    linkList,
    node,
    plainList,
    row,
    text,
} from "#domain/converters/ontology.converter";
import { KIND_SECTION_ICON } from "#configuration/icons/ontology.icons";

const HEADER = "flowchart LR";
const SOLID = " --> ";
const RELATION_PREFIX = "relation-";
const UNDERSCORE = "_";
const SPACE = " ";

const kindSubsection = function kindSubsection(kind: KindView): Subsection {
    return {
        blocks: [
            chips([
                labelled(PRINCIPLES_OF_KIND_LABEL, String(kind.principles)),
                labelled(TERMS_OF_KIND_LABEL, String(kind.terms)),
            ]),
            glossary([
                row(DISCRIMINATOR_LABEL, kind.discriminator),
                row(DISTINGUISHES_LABEL, kind.distinguishesFrom),
                row(SIGNATURES_LABEL, plainList(kind.definitionSignatures)),
            ]),
        ],
        id: KIND_ANCHOR + kind.kind,
        title: kind.kind,
    };
};

const kindSection = function kindSection(kinds: readonly KindView[], resolutionNote: string): Section {
    return {
        blocks: [text(resolutionNote)],
        icon: KIND_SECTION_ICON,
        id: KIND_SECTION_ID,
        intro: KIND_INTRO,
        subsections: kinds.map(kindSubsection),
        title: KIND_TITLE,
    };
};

const rangeDiagram = function rangeDiagram(ranges: readonly RelationRangeView[], kinds: readonly KindView[]): string {
    const relationNodes = ranges.map((range) => node(RELATION_PREFIX + range.relation, range.relation));
    const kindNodes = kinds.map((kind) => node(kind.kind, kind.kind));
    const edges = ranges.flatMap((range) =>
        range.kinds.map((kind) => edgeLine(RELATION_PREFIX + range.relation, SOLID, kind.label)),
    );
    return diagram(HEADER, [...relationNodes, ...kindNodes, ...edges]);
};

const rangeSection = function rangeSection(ranges: readonly RelationRangeView[], kinds: readonly KindView[]): Section {
    return {
        blocks: [{ caption: RANGE_CAPTION, kind: "mermaid", text: rangeDiagram(ranges, kinds) }],
        icon: KIND_SECTION_ICON,
        id: RANGE_SECTION_ID,
        intro: RANGE_INTRO,
        subsections: ranges.map((range) => ({
            blocks: [glossary([row(KINDS_IN_RANGE_LABEL, linkList(range.kinds))])],
            id: RELATION_ANCHOR + range.relation,
            title: range.relation,
        })),
        title: RANGE_SECTION_TITLE,
    };
};

const forceSubsection = function forceSubsection(force: ForceView): Subsection {
    return {
        blocks: [
            glossary([
                row(CONTRACTS_LABEL, linkList(force.contracts)),
                row(PRINCIPLES_LABEL, linkList(force.principles)),
                ...(force.concerns.length === 0 ? [] : [row(CONCERNS_LABEL, plainList(force.concerns))]),
            ]),
        ],
        id: FORCE_ANCHOR + force.id,
        title: force.force.replaceAll(UNDERSCORE, SPACE),
    };
};

const forceSection = function forceSection(forces: readonly ForceView[]): Section {
    return {
        icon: KIND_SECTION_ICON,
        id: FORCE_SECTION_ID,
        intro: FORCE_INTRO,
        subsections: forces.map(forceSubsection),
        title: FORCE_TITLE,
    };
};

export const kindSections = function kindSections(
    kinds: readonly KindView[],
    ranges: readonly RelationRangeView[],
    forces: readonly ForceView[],
    resolutionNote: string,
): readonly Section[] {
    return [kindSection(kinds, resolutionNote), rangeSection(ranges, kinds), forceSection(forces)];
};
```
