# configuration/strings/graph.strings.ts

> 84 lines of code and 25 definitions.

Tree: Bane's Lab Build Scripts
Language: typescript
Layer: product
Canonical: https://banes-lab.com/anatomy/build-scripts#file-build-scripts-configuration-strings-graph-strings-ts
Source text: https://banes-lab.com/source/build-scripts/configuration/strings/graph.strings.ts.txt

Listed in [configuration/strings](https://banes-lab.com/api/source/build-scripts/configuration/strings.md), after [configuration/strings/folder.strings.ts](https://banes-lab.com/source/build-scripts/configuration/strings/folder.strings.ts.md) and before [configuration/strings/icons.strings.ts](https://banes-lab.com/source/build-scripts/configuration/strings/icons.strings.ts.md).

## Definitions

- `graphLines` (lexical_declaration, line 5, exported)
- `missingPopulation` (lexical_declaration, line 26, exported)
- `graphReportMissing` (lexical_declaration, line 30, exported)
- `graphReportEmpty` (lexical_declaration, line 34, exported)
- `missingReportList` (lexical_declaration, line 38, exported)
- `malformedReportEntries` (lexical_declaration, line 42, exported)
- `sharedNumber` (lexical_declaration, line 46, exported)
- `undeclaredAbsence` (lexical_declaration, line 50, exported)
- `emptyPopulation` (lexical_declaration, line 59, exported)
- `unbalancedPopulation` (lexical_declaration, line 63, exported)
- `unresolvedEvidence` (lexical_declaration, line 83, exported)
- `unknownTargetKind` (lexical_declaration, line 88, exported)
- `duplicateProducer` (lexical_declaration, line 92, exported)
- `{ report, search }` (lexical_declaration, line 6, exported)
- `{ positions }` (lexical_declaration, line 7, exported)
- `POPULATION_NOUNS` (lexical_declaration, line 19, exported)
- `NO_GRAPH_REPORT` (lexical_declaration, line 24, exported)
- `undeclaredRelation` (lexical_declaration, line 67, exported)
- `ambiguousRelation` (lexical_declaration, line 71, exported)
- `unresolvedTarget` (lexical_declaration, line 75, exported)
- `duplicateNode` (lexical_declaration, line 79, exported)
- `named` (lexical_declaration, line 84, exported)
- `uncoveredSection` (lexical_declaration, line 96, exported)
- `tooltipGap` (lexical_declaration, line 100, exported)
- `danglingEdge` (lexical_declaration, line 104, exported)

## Contained in

- [configuration/strings](https://banes-lab.com/anatomy/build-scripts/folder-build-scripts-configuration-strings.md)

## Used by

- [core/converters/graph.link.converter.ts](https://banes-lab.com/source/build-scripts/core/converters/graph.link.converter.ts.md)
- [core/coordinators/graph.coordinator.ts](https://banes-lab.com/source/build-scripts/core/coordinators/graph.coordinator.ts.md)
- [core/loaders/graph.loader.ts](https://banes-lab.com/source/build-scripts/core/loaders/graph.loader.ts.md)
- [core/registries/producer.registry.ts](https://banes-lab.com/source/build-scripts/core/registries/producer.registry.ts.md)
- [core/resolvers/evidence.resolver.ts](https://banes-lab.com/source/build-scripts/core/resolvers/evidence.resolver.ts.md)
- [core/validators/graph.validator.ts](https://banes-lab.com/source/build-scripts/core/validators/graph.validator.ts.md)

## Linked from

- [core/converters](https://banes-lab.com/anatomy/build-scripts/folder-build-scripts-core-converters.md)
- [core/coordinators](https://banes-lab.com/anatomy/build-scripts/folder-build-scripts-core-coordinators.md)
- [core/loaders](https://banes-lab.com/anatomy/build-scripts/folder-build-scripts-core-loaders.md)
- [core/registries](https://banes-lab.com/anatomy/build-scripts/folder-build-scripts-core-registries.md)
- [core/resolvers](https://banes-lab.com/anatomy/build-scripts/folder-build-scripts-core-resolvers.md)
- [core/validators](https://banes-lab.com/anatomy/build-scripts/folder-build-scripts-core-validators.md)

## Source

```typescript
import type { GraphEdge, GraphNode } from "@banes-lab/web/types/graph.types.js";
import type { GraphFiles, GraphLines } from "#types/graph.types";
import type { EvidenceNode } from "@banes-lab/web/types/evidence.types.js";

export const graphLines = function graphLines(lines: GraphLines, files: GraphFiles): string {
    const { report, search } = lines;
    const { positions } = search;
    return [
        `learning: wrote ${String(lines.stops)} stop(s) into ${files.learning}`,
        `tabs: wrote ${String(lines.routes)} tab route(s) into ${files.tabs}`,
        `graph: derived ${String(report.graph.nodes.length)} node(s) and ${String(report.graph.edges.length)} edge(s) from ${String(lines.records)} record(s) into ${files.report}`,
        `graph: found ${String(report.undeclared.length)} undeclared relation(s), ${String(report.ambiguous.length)} ambiguous relation(s), ${String(report.unresolved.length)} unresolved target(s) and ${String(report.dangling.length)} dangling edge(s)`,
        `graph: wrote ${String(lines.chunks)} chunk(s) beside ${files.graph}`,
        `search: wrote ${String(Object.keys(positions.route).length)} route position(s), ${String(Object.keys(positions.links).length)} link position(s), ${String(Object.keys(positions.evidence).length)} evidence position(s) and ${String(search.definitions.length)} definition(s) into ${files.search}`,
        "",
    ].join("\n");
};

export const POPULATION_NOUNS: ReadonlyMap<string, string> = new Map([
    ["node links", "link"],
    ["site numbers", "number"],
]);

export const NO_GRAPH_REPORT = "The build produced no relation graph report.";

export const missingPopulation = function missingPopulation(population: string): string {
    return `graph: the report carries no ${population} population. The records population counts every record the graph reads.`;
};

export const graphReportMissing = function graphReportMissing(report: string): string {
    return `catalog: the relation graph report is missing at ${report}. Run the build's graph step before the catalog.`;
};

export const graphReportEmpty = function graphReportEmpty(report: string): string {
    return `catalog: the relation graph report at ${report} carries no graph. Run the build's graph step again to rewrite it.`;
};

export const missingReportList = function missingReportList(key: string): string {
    return `The relation graph report holds no ${key} list, so none of its entries were checked.`;
};

export const malformedReportEntries = function malformedReportEntries(key: string, count: number): string {
    return `${String(count)} entry(s) in the ${key} list of the relation graph report do not have the shape the check reads, so they were not checked.`;
};

export const sharedNumber = function sharedNumber(number: string, first: string, second: string): string {
    return `The number ${number} is carried by both ${first} and ${second}.`;
};

export const undeclaredAbsence = function undeclaredAbsence(
    count: number,
    kind: string,
    layer: string,
    noun: string,
): string {
    return `${String(count)} ${kind} node(s) in the ${layer} layer have no ${noun}, and EXPECTED_ABSENCES does not declare it. Give them one, or declare the absence with its reason.`;
};

export const emptyPopulation = function emptyPopulation(name: string): string {
    return `The relation graph report read no ${name}.`;
};

export const unbalancedPopulation = function unbalancedPopulation(name: string, sum: number, whole: number): string {
    return `The ${name} parts in the relation graph report add up to ${String(sum)}, and ${String(whole)} were read.`;
};

export const undeclaredRelation = function undeclaredRelation(face: string, relation: string): string {
    return `The ${face} collection stores the relation "${relation}", which neither RELATION_PAIRS nor GRAPH_FIELD_RULES declares.`;
};

export const ambiguousRelation = function ambiguousRelation(face: string, relation: string): string {
    return `The ${face} collection stores the relation "${relation}", which reverses more than one pair in RELATION_PAIRS. Declare the relation it means in GRAPH_FIELD_RULES.`;
};

export const unresolvedTarget = function unresolvedTarget(from: string, label: string, relation: string): string {
    return `The record ${from} names "${label}" in its ${relation} field, and no record has that id. Change the entry to the id of the record it means, or move the text to a field that holds text.`;
};

export const duplicateNode = function duplicateNode(kept: GraphNode, dropped: GraphNode): string {
    return `Two parts of the graph build derive the node ${kept.ref}, as a ${kept.kind} in the ${kept.layer} layer and as a ${dropped.kind} in the ${dropped.layer} layer. Keep one derivation, or give the second node its own ref.`;
};

export const unresolvedEvidence = function unresolvedEvidence(from: string, node: EvidenceNode): string {
    const named = node.kind === "folder" ? node.words.join(" ") : node.name;
    return `graph: the evidence for ${from} names the ${node.kind} "${named}", which no anatomy tree holds, so its evidence edge would be lost. Point the entry at the construct as it is named now, or move ${from} to EVIDENCE_ABSENT with its reason.`;
};

export const unknownTargetKind = function unknownTargetKind(target: string): string {
    return `graph: the reference target ${target} has a kind no graph ref is mapped for. Map the kind in codeTargetRefOf.`;
};

export const duplicateProducer = function duplicateProducer(producer: string): string {
    return `graph: two producer files register the name ${producer}. Rename one of them, because the name keys the producer registry.`;
};

export const uncoveredSection = function uncoveredSection(ref: string): string {
    return `The teaching section ${ref} links no ontology record. Link the record the section teaches.`;
};

export const tooltipGap = function tooltipGap(edge: GraphEdge): string {
    return `The tooltip chunk for ${edge.from} does not carry the ${edge.relation} edge to ${edge.to} that the relation graph holds.`;
};

export const danglingEdge = function danglingEdge(edge: GraphEdge): string {
    return `The edge "${edge.relation}" from ${edge.from} to ${edge.to} names a node the graph does not hold; a rename, a move, a deletion or a layer the graph does not build yet leaves an edge like this.`;
};
```
