@rsconcept/domain 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +55 -0
- package/dist/cctext/index.d.ts +1 -0
- package/dist/cctext/index.js +42 -0
- package/dist/cctext/index.js.map +1 -0
- package/dist/cctext/language-api.d.ts +43 -0
- package/dist/cctext/language-api.js +252 -0
- package/dist/cctext/language-api.js.map +1 -0
- package/dist/cctext/language.d.ts +58 -0
- package/dist/cctext/language.js +44 -0
- package/dist/cctext/language.js.map +1 -0
- package/dist/graph/graph.d.ts +62 -0
- package/dist/graph/graph.js +385 -0
- package/dist/graph/graph.js.map +1 -0
- package/dist/graph/index.d.ts +1 -0
- package/dist/graph/index.js +384 -0
- package/dist/graph/index.js.map +1 -0
- package/dist/index.d.ts +28 -0
- package/dist/index.js +5851 -0
- package/dist/index.js.map +1 -0
- package/dist/library/folder-tree.d.ts +32 -0
- package/dist/library/folder-tree.js +136 -0
- package/dist/library/folder-tree.js.map +1 -0
- package/dist/library/index.d.ts +17 -0
- package/dist/library/index.js +2800 -0
- package/dist/library/index.js.map +1 -0
- package/dist/library/library-api.d.ts +6 -0
- package/dist/library/library-api.js +13 -0
- package/dist/library/library-api.js.map +1 -0
- package/dist/library/library.d.ts +56 -0
- package/dist/library/library.js +23 -0
- package/dist/library/library.js.map +1 -0
- package/dist/library/oss-api.d.ts +47 -0
- package/dist/library/oss-api.js +1105 -0
- package/dist/library/oss-api.js.map +1 -0
- package/dist/library/oss-layout-api.d.ts +36 -0
- package/dist/library/oss-layout-api.js +330 -0
- package/dist/library/oss-layout-api.js.map +1 -0
- package/dist/library/oss-layout.d.ts +25 -0
- package/dist/library/oss-layout.js +1 -0
- package/dist/library/oss-layout.js.map +1 -0
- package/dist/library/oss.d.ts +136 -0
- package/dist/library/oss.js +30 -0
- package/dist/library/oss.js.map +1 -0
- package/dist/library/rsengine.d.ts +116 -0
- package/dist/library/rsengine.js +2604 -0
- package/dist/library/rsengine.js.map +1 -0
- package/dist/library/rsform-api.d.ts +74 -0
- package/dist/library/rsform-api.js +879 -0
- package/dist/library/rsform-api.js.map +1 -0
- package/dist/library/rsform.d.ts +206 -0
- package/dist/library/rsform.js +32 -0
- package/dist/library/rsform.js.map +1 -0
- package/dist/library/rsmodel-api.d.ts +43 -0
- package/dist/library/rsmodel-api.js +836 -0
- package/dist/library/rsmodel-api.js.map +1 -0
- package/dist/library/rsmodel.d.ts +52 -0
- package/dist/library/rsmodel.js +25 -0
- package/dist/library/rsmodel.js.map +1 -0
- package/dist/library/structure-planner.d.ts +33 -0
- package/dist/library/structure-planner.js +481 -0
- package/dist/library/structure-planner.js.map +1 -0
- package/dist/parsing/ast.d.ts +49 -0
- package/dist/parsing/ast.js +93 -0
- package/dist/parsing/ast.js.map +1 -0
- package/dist/parsing/index.d.ts +3 -0
- package/dist/parsing/index.js +141 -0
- package/dist/parsing/index.js.map +1 -0
- package/dist/parsing/lezer-tree.d.ts +13 -0
- package/dist/parsing/lezer-tree.js +50 -0
- package/dist/parsing/lezer-tree.js.map +1 -0
- package/dist/rslang/api.d.ts +53 -0
- package/dist/rslang/api.js +846 -0
- package/dist/rslang/api.js.map +1 -0
- package/dist/rslang/ast-annotations.d.ts +18 -0
- package/dist/rslang/ast-annotations.js +56 -0
- package/dist/rslang/ast-annotations.js.map +1 -0
- package/dist/rslang/error.d.ts +85 -0
- package/dist/rslang/error.js +159 -0
- package/dist/rslang/error.js.map +1 -0
- package/dist/rslang/eval/calculator.d.ts +43 -0
- package/dist/rslang/eval/calculator.js +1639 -0
- package/dist/rslang/eval/calculator.js.map +1 -0
- package/dist/rslang/eval/evaluation-cache.d.ts +36 -0
- package/dist/rslang/eval/evaluation-cache.js +310 -0
- package/dist/rslang/eval/evaluation-cache.js.map +1 -0
- package/dist/rslang/eval/evaluator.d.ts +70 -0
- package/dist/rslang/eval/evaluator.js +1514 -0
- package/dist/rslang/eval/evaluator.js.map +1 -0
- package/dist/rslang/eval/value-api.d.ts +48 -0
- package/dist/rslang/eval/value-api.js +490 -0
- package/dist/rslang/eval/value-api.js.map +1 -0
- package/dist/rslang/eval/value.d.ts +36 -0
- package/dist/rslang/eval/value.js +118 -0
- package/dist/rslang/eval/value.js.map +1 -0
- package/dist/rslang/index.d.ts +17 -0
- package/dist/rslang/index.js +4314 -0
- package/dist/rslang/index.js.map +1 -0
- package/dist/rslang/labels.d.ts +16 -0
- package/dist/rslang/labels.js +315 -0
- package/dist/rslang/labels.js.map +1 -0
- package/dist/rslang/parser/expression-generator.d.ts +10 -0
- package/dist/rslang/parser/expression-generator.js +451 -0
- package/dist/rslang/parser/expression-generator.js.map +1 -0
- package/dist/rslang/parser/normalize.d.ts +11 -0
- package/dist/rslang/parser/normalize.js +507 -0
- package/dist/rslang/parser/normalize.js.map +1 -0
- package/dist/rslang/parser/parser.d.ts +5 -0
- package/dist/rslang/parser/parser.js +24 -0
- package/dist/rslang/parser/parser.js.map +1 -0
- package/dist/rslang/parser/parser.terms.d.ts +42 -0
- package/dist/rslang/parser/parser.terms.js +84 -0
- package/dist/rslang/parser/parser.terms.js.map +1 -0
- package/dist/rslang/parser/syntax-errors.d.ts +11 -0
- package/dist/rslang/parser/syntax-errors.js +403 -0
- package/dist/rslang/parser/syntax-errors.js.map +1 -0
- package/dist/rslang/parser/token.d.ts +79 -0
- package/dist/rslang/parser/token.js +95 -0
- package/dist/rslang/parser/token.js.map +1 -0
- package/dist/rslang/semantic/analyzer.d.ts +39 -0
- package/dist/rslang/semantic/analyzer.js +2604 -0
- package/dist/rslang/semantic/analyzer.js.map +1 -0
- package/dist/rslang/semantic/arguments-extractor.d.ts +42 -0
- package/dist/rslang/semantic/arguments-extractor.js +366 -0
- package/dist/rslang/semantic/arguments-extractor.js.map +1 -0
- package/dist/rslang/semantic/type-auditor.d.ts +73 -0
- package/dist/rslang/semantic/type-auditor.js +1570 -0
- package/dist/rslang/semantic/type-auditor.js.map +1 -0
- package/dist/rslang/semantic/typification-api.d.ts +27 -0
- package/dist/rslang/semantic/typification-api.js +320 -0
- package/dist/rslang/semantic/typification-api.js.map +1 -0
- package/dist/rslang/semantic/typification-parser.d.ts +12 -0
- package/dist/rslang/semantic/typification-parser.js +226 -0
- package/dist/rslang/semantic/typification-parser.js.map +1 -0
- package/dist/rslang/semantic/typification.d.ts +119 -0
- package/dist/rslang/semantic/typification.js +74 -0
- package/dist/rslang/semantic/typification.js.map +1 -0
- package/dist/rslang/semantic/value-auditor.d.ts +43 -0
- package/dist/rslang/semantic/value-auditor.js +523 -0
- package/dist/rslang/semantic/value-auditor.js.map +1 -0
- package/dist/rslang/semantic/value-class.d.ts +10 -0
- package/dist/rslang/semantic/value-class.js +9 -0
- package/dist/rslang/semantic/value-class.js.map +1 -0
- package/dist/rslang/typification-graph.d.ts +33 -0
- package/dist/rslang/typification-graph.js +311 -0
- package/dist/rslang/typification-graph.js.map +1 -0
- package/dist/shared/branded.d.ts +7 -0
- package/dist/shared/branded.js +1 -0
- package/dist/shared/branded.js.map +1 -0
- package/dist/shared/hash.d.ts +6 -0
- package/dist/shared/hash.js +18 -0
- package/dist/shared/hash.js.map +1 -0
- package/dist/shared/index.d.ts +2 -0
- package/dist/shared/index.js +18 -0
- package/dist/shared/index.js.map +1 -0
- package/package.json +184 -0
- package/src/cctext/index.ts +9 -0
- package/src/cctext/language-api.test.ts +149 -0
- package/src/cctext/language-api.ts +285 -0
- package/src/cctext/language.ts +80 -0
- package/src/graph/graph.test.ts +392 -0
- package/src/graph/graph.ts +433 -0
- package/src/graph/index.ts +1 -0
- package/src/index.ts +96 -0
- package/src/library/folder-tree.test.ts +47 -0
- package/src/library/folder-tree.ts +156 -0
- package/src/library/index.ts +46 -0
- package/src/library/library-api.test.ts +32 -0
- package/src/library/library-api.ts +11 -0
- package/src/library/library.ts +61 -0
- package/src/library/oss-api.ts +449 -0
- package/src/library/oss-layout-api.ts +377 -0
- package/src/library/oss-layout.ts +27 -0
- package/src/library/oss.ts +150 -0
- package/src/library/rsengine.ts +593 -0
- package/src/library/rsform-api.ts +533 -0
- package/src/library/rsform.ts +228 -0
- package/src/library/rsmodel-api.ts +340 -0
- package/src/library/rsmodel.ts +50 -0
- package/src/library/structure-planner.ts +143 -0
- package/src/parsing/ast.ts +136 -0
- package/src/parsing/index.ts +15 -0
- package/src/parsing/lezer-tree.ts +69 -0
- package/src/rslang/api.test.ts +116 -0
- package/src/rslang/api.ts +183 -0
- package/src/rslang/ast-annotations.ts +70 -0
- package/src/rslang/error.ts +129 -0
- package/src/rslang/eval/calculator.test.ts +124 -0
- package/src/rslang/eval/calculator.ts +121 -0
- package/src/rslang/eval/evaluation-cache.ts +257 -0
- package/src/rslang/eval/evaluator.test.ts +352 -0
- package/src/rslang/eval/evaluator.ts +935 -0
- package/src/rslang/eval/value-api.test.ts +105 -0
- package/src/rslang/eval/value-api.ts +444 -0
- package/src/rslang/eval/value.ts +102 -0
- package/src/rslang/index.ts +23 -0
- package/src/rslang/labels.ts +191 -0
- package/src/rslang/parser/expression-generator.test.ts +100 -0
- package/src/rslang/parser/expression-generator.ts +466 -0
- package/src/rslang/parser/normalize.test.ts +99 -0
- package/src/rslang/parser/normalize.ts +462 -0
- package/src/rslang/parser/parser.terms.ts +42 -0
- package/src/rslang/parser/parser.test.ts +153 -0
- package/src/rslang/parser/parser.ts +20 -0
- package/src/rslang/parser/rslang.grammar +251 -0
- package/src/rslang/parser/syntax-errors.ts +209 -0
- package/src/rslang/parser/token.ts +106 -0
- package/src/rslang/semantic/analyzer.test.ts +59 -0
- package/src/rslang/semantic/analyzer.ts +179 -0
- package/src/rslang/semantic/arguments-extractor.ts +327 -0
- package/src/rslang/semantic/type-auditor.test.ts +326 -0
- package/src/rslang/semantic/type-auditor.ts +1049 -0
- package/src/rslang/semantic/typification-api.test.ts +46 -0
- package/src/rslang/semantic/typification-api.ts +321 -0
- package/src/rslang/semantic/typification-parser.test.ts +50 -0
- package/src/rslang/semantic/typification-parser.ts +220 -0
- package/src/rslang/semantic/typification.ts +180 -0
- package/src/rslang/semantic/value-auditor.test.ts +206 -0
- package/src/rslang/semantic/value-auditor.ts +332 -0
- package/src/rslang/semantic/value-class.ts +11 -0
- package/src/rslang/typification-graph.ts +155 -0
- package/src/shared/branded.ts +6 -0
- package/src/shared/hash.ts +17 -0
- package/src/shared/index.ts +2 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 IRBorisov and Concept Portal contributors
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
# @rsconcept/domain
|
|
2
|
+
|
|
3
|
+
Shared TypeScript domain layer for the [Concept Portal](https://portal.acconcept.ru) stack.
|
|
4
|
+
|
|
5
|
+
This package implements the formal language **RSLang**, the schema model **RSForm**, the evaluation engine **RSEngine**, the operation-of-schemas model **OSS**, and supporting helpers (graphs, parsing utilities, concept-text grammemes). It is consumed both by the Portal frontend and by [`@rsconcept/rstool`](https://www.npmjs.com/package/@rsconcept/rstool).
|
|
6
|
+
|
|
7
|
+
## Install
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
npm install @rsconcept/domain
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## Subpath exports
|
|
14
|
+
|
|
15
|
+
```ts
|
|
16
|
+
import { RSLangAnalyzer, RSErrorCode } from '@rsconcept/domain/rslang';
|
|
17
|
+
import { CstType, type RSForm } from '@rsconcept/domain/library/rsform';
|
|
18
|
+
import { Graph } from '@rsconcept/domain/graph';
|
|
19
|
+
import { buildTree, type AstNode } from '@rsconcept/domain/parsing';
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
The root entry (`@rsconcept/domain`) re-exports the most common names. Subpath imports are recommended for tree-shaking and to make dependency graphs explicit.
|
|
23
|
+
|
|
24
|
+
## Contents
|
|
25
|
+
|
|
26
|
+
| Subpath | Surface |
|
|
27
|
+
| --------- | ---------------------------------------------------------------------------------------------- |
|
|
28
|
+
| `rslang` | Lezer parser, semantic analyzer, evaluator, calculator, type system, value system, error codes |
|
|
29
|
+
| `library` | `RSForm`, `RSModel`, `RSEngine`, OSS, library item metadata, structure planner |
|
|
30
|
+
| `graph` | Generic directed-graph utilities used for dependency tracking |
|
|
31
|
+
| `parsing` | Lezer AST helpers shared by all parsers |
|
|
32
|
+
| `cctext` | Russian/multilingual grammemes for concept-text references |
|
|
33
|
+
| `shared` | `Branded<T>` types, FNV-1a hash, stub id generation |
|
|
34
|
+
|
|
35
|
+
## Build
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
npm run generate # regenerates Lezer parser from rslang.grammar
|
|
39
|
+
npm run build # produces ./dist via tsup
|
|
40
|
+
npm test # vitest run
|
|
41
|
+
npm run typecheck # tsc --noEmit
|
|
42
|
+
npm run lint # ESLint (TypeScript; same core rules as frontend, no React)
|
|
43
|
+
npm run lintFix # ESLint --fix
|
|
44
|
+
npm run format:check
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
After editing `src/rslang/parser/rslang.grammar`, always run `npm run generate` before committing.
|
|
48
|
+
|
|
49
|
+
## Server-side mirrors
|
|
50
|
+
|
|
51
|
+
Some helpers in this package are duplicated in the Concept Portal Django backend (`api_RSLanguage.py`, `graph.py`, `SemanticInfo.py`). Those Python mirrors implement a narrow subset for ORM-level operations and are maintained separately. Parsing and evaluation only run in TypeScript.
|
|
52
|
+
|
|
53
|
+
## License
|
|
54
|
+
|
|
55
|
+
MIT
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { EntityReference, Grammeme, ReferenceType, SyntacticReference, TermContext, WordForm, supportedGrammemes } from './language.js';
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
// src/cctext/language.ts
|
|
2
|
+
var Grammeme = {
|
|
3
|
+
// Число
|
|
4
|
+
sing: "sing",
|
|
5
|
+
plur: "plur",
|
|
6
|
+
// Падеж
|
|
7
|
+
nomn: "nomn",
|
|
8
|
+
gent: "gent",
|
|
9
|
+
datv: "datv",
|
|
10
|
+
accs: "accs",
|
|
11
|
+
ablt: "ablt",
|
|
12
|
+
loct: "loct"
|
|
13
|
+
};
|
|
14
|
+
var Case = [
|
|
15
|
+
Grammeme.nomn,
|
|
16
|
+
Grammeme.gent,
|
|
17
|
+
Grammeme.datv,
|
|
18
|
+
Grammeme.accs,
|
|
19
|
+
Grammeme.ablt,
|
|
20
|
+
Grammeme.loct
|
|
21
|
+
];
|
|
22
|
+
var Plurality = [Grammeme.sing, Grammeme.plur];
|
|
23
|
+
var supportedGrammemes = [
|
|
24
|
+
Grammeme.sing,
|
|
25
|
+
Grammeme.plur,
|
|
26
|
+
Grammeme.nomn,
|
|
27
|
+
Grammeme.gent,
|
|
28
|
+
Grammeme.datv,
|
|
29
|
+
Grammeme.accs,
|
|
30
|
+
Grammeme.ablt,
|
|
31
|
+
Grammeme.loct
|
|
32
|
+
];
|
|
33
|
+
var ReferenceType = {
|
|
34
|
+
ENTITY: "entity",
|
|
35
|
+
SYNTACTIC: "syntax"
|
|
36
|
+
};
|
|
37
|
+
export {
|
|
38
|
+
Grammeme,
|
|
39
|
+
ReferenceType,
|
|
40
|
+
supportedGrammemes
|
|
41
|
+
};
|
|
42
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/cctext/language.ts"],"sourcesContent":["/**\n * Module: Natural language model declarations.\n */\n\n/** Represents single unit of language Morphology. */\n// prettier-ignore\nexport const Grammeme = {\n // Число\n sing: 'sing', plur: 'plur',\n\n // Падеж\n nomn: 'nomn', gent: 'gent', datv: 'datv',\n accs: 'accs', ablt: 'ablt', loct: 'loct',\n} as const;\nexport type Grammeme = (typeof Grammeme)[keyof typeof Grammeme];\n\n/** Represents case language concept. */\nexport const Case: Grammeme[] = [\n Grammeme.nomn,\n Grammeme.gent,\n Grammeme.datv,\n Grammeme.accs,\n Grammeme.ablt,\n Grammeme.loct\n] as const;\n\n/** Represents plurality language concept. */\nexport const Plurality: Grammeme[] = [Grammeme.sing, Grammeme.plur] as const;\n\n/** Represents specific wordform attached to {@link Grammeme}s. */\nexport interface WordForm {\n text: string;\n grams: Grammeme[];\n}\n\n/** Represents a term available for text reference resolution. */\nexport interface TermContextItem {\n nominal: string;\n forms?: WordForm[];\n}\n\n/** Represents term lookup context keyed by entity alias. */\nexport type TermContext = Record<string, TermContextItem>;\n\n/**\n * Represents list of {@link Grammeme}s available in reference construction.\n */\n// prettier-ignore\nexport const supportedGrammemes = [\n Grammeme.sing, Grammeme.plur,\n Grammeme.nomn, Grammeme.gent, Grammeme.datv,\n Grammeme.accs, Grammeme.ablt, Grammeme.loct,\n] as const;\n\n// ====== Reference resolution =====\n\n/** Represents text reference type. */\nexport const ReferenceType = {\n ENTITY: 'entity',\n SYNTACTIC: 'syntax'\n} as const;\nexport type ReferenceType = (typeof ReferenceType)[keyof typeof ReferenceType];\n\n/** Represents entity reference payload. */\nexport interface EntityReference {\n entity: string;\n tags: Grammeme[];\n}\n\n/** Represents syntactic reference payload. */\nexport interface SyntacticReference {\n offset: number;\n nominal: string;\n}\n\n/** Represents abstract reference data. */\nexport interface IReference {\n type: ReferenceType;\n data: EntityReference | SyntacticReference;\n}\n"],"mappings":";AAMO,IAAM,WAAW;AAAA;AAAA,EAEtB,MAAM;AAAA,EAAQ,MAAM;AAAA;AAAA,EAGpB,MAAM;AAAA,EAAQ,MAAM;AAAA,EAAQ,MAAM;AAAA,EAClC,MAAM;AAAA,EAAQ,MAAM;AAAA,EAAQ,MAAM;AACpC;AAIO,IAAM,OAAmB;AAAA,EAC9B,SAAS;AAAA,EACT,SAAS;AAAA,EACT,SAAS;AAAA,EACT,SAAS;AAAA,EACT,SAAS;AAAA,EACT,SAAS;AACX;AAGO,IAAM,YAAwB,CAAC,SAAS,MAAM,SAAS,IAAI;AAqB3D,IAAM,qBAAqB;AAAA,EAChC,SAAS;AAAA,EAAM,SAAS;AAAA,EACxB,SAAS;AAAA,EAAM,SAAS;AAAA,EAAM,SAAS;AAAA,EACvC,SAAS;AAAA,EAAM,SAAS;AAAA,EAAM,SAAS;AACzC;AAKO,IAAM,gBAAgB;AAAA,EAC3B,QAAQ;AAAA,EACR,WAAW;AACb;","names":[]}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { EntityReference, Grammeme, IReference, SyntacticReference, TermContext, WordForm } from './language.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Module: Natural language model API.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
/** Represents generated lexeme forms. */
|
|
8
|
+
interface Lexeme {
|
|
9
|
+
items: {
|
|
10
|
+
text: string;
|
|
11
|
+
grams: string;
|
|
12
|
+
}[];
|
|
13
|
+
}
|
|
14
|
+
/** Equality comparator for {@link WordForm}. Compares a set of Grammemes attached to wordforms. */
|
|
15
|
+
declare function wordFormEquals(left: WordForm, right: WordForm): boolean;
|
|
16
|
+
/** Transforms {@link Grammeme} enumeration to {@link Grammeme}. */
|
|
17
|
+
declare function parseGrammemes(termForm: string): Grammeme[];
|
|
18
|
+
/** Generates all supported noun forms using nominal text for every form. */
|
|
19
|
+
declare function generateNominalLexeme(data: {
|
|
20
|
+
text: string;
|
|
21
|
+
}): Lexeme;
|
|
22
|
+
/**
|
|
23
|
+
* Extracts {@link EntityReference} from string representation.
|
|
24
|
+
*
|
|
25
|
+
* @param text - Reference text in a valid pattern. Must fit format '\@\{GLOBAL_ID|GRAMMEMES\}'
|
|
26
|
+
*/
|
|
27
|
+
declare function parseEntityReference(text: string): EntityReference;
|
|
28
|
+
/**
|
|
29
|
+
* Extracts {@link SyntacticReference} from string representation.
|
|
30
|
+
*
|
|
31
|
+
* @param text - Reference text in a valid pattern. Must fit format '\@\{OFFSET|NOMINAL_FORM\}'
|
|
32
|
+
*/
|
|
33
|
+
declare function parseSyntacticReference(text: string): SyntacticReference;
|
|
34
|
+
/** Extracts a validated reference from string representation. */
|
|
35
|
+
declare function parseReference(text: string): IReference | null;
|
|
36
|
+
/** Extracts unique entity aliases referenced by text. */
|
|
37
|
+
declare function extractEntities(text: string): string[];
|
|
38
|
+
/** Resolves text references using nominal terms and optional manually edited forms. */
|
|
39
|
+
declare function resolveTextReferences(text: string, context: TermContext): string;
|
|
40
|
+
/** Transforms {@link IReference} to string representation. */
|
|
41
|
+
declare function referenceToString(ref: IReference): string;
|
|
42
|
+
|
|
43
|
+
export { type Lexeme, extractEntities, generateNominalLexeme, parseEntityReference, parseGrammemes, parseReference, parseSyntacticReference, referenceToString, resolveTextReferences, wordFormEquals };
|
|
@@ -0,0 +1,252 @@
|
|
|
1
|
+
// src/cctext/language.ts
|
|
2
|
+
var Grammeme = {
|
|
3
|
+
// Число
|
|
4
|
+
sing: "sing",
|
|
5
|
+
plur: "plur",
|
|
6
|
+
// Падеж
|
|
7
|
+
nomn: "nomn",
|
|
8
|
+
gent: "gent",
|
|
9
|
+
datv: "datv",
|
|
10
|
+
accs: "accs",
|
|
11
|
+
ablt: "ablt",
|
|
12
|
+
loct: "loct"
|
|
13
|
+
};
|
|
14
|
+
var Case = [
|
|
15
|
+
Grammeme.nomn,
|
|
16
|
+
Grammeme.gent,
|
|
17
|
+
Grammeme.datv,
|
|
18
|
+
Grammeme.accs,
|
|
19
|
+
Grammeme.ablt,
|
|
20
|
+
Grammeme.loct
|
|
21
|
+
];
|
|
22
|
+
var Plurality = [Grammeme.sing, Grammeme.plur];
|
|
23
|
+
var supportedGrammemes = [
|
|
24
|
+
Grammeme.sing,
|
|
25
|
+
Grammeme.plur,
|
|
26
|
+
Grammeme.nomn,
|
|
27
|
+
Grammeme.gent,
|
|
28
|
+
Grammeme.datv,
|
|
29
|
+
Grammeme.accs,
|
|
30
|
+
Grammeme.ablt,
|
|
31
|
+
Grammeme.loct
|
|
32
|
+
];
|
|
33
|
+
var ReferenceType = {
|
|
34
|
+
ENTITY: "entity",
|
|
35
|
+
SYNTACTIC: "syntax"
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
// src/cctext/language-api.ts
|
|
39
|
+
var REFERENCE_PATTERN = /@{[^{}]*?}/g;
|
|
40
|
+
var ENTITY_REFERENCE_PATTERN = /@{([^0-9\-][^}|{]*?)\|([^}|{]*?)}/g;
|
|
41
|
+
function wordFormEquals(left, right) {
|
|
42
|
+
if (left.grams.length !== right.grams.length) {
|
|
43
|
+
return false;
|
|
44
|
+
}
|
|
45
|
+
for (let index = 0; index < left.grams.length; ++index) {
|
|
46
|
+
if (left.grams[index] !== right.grams[index]) {
|
|
47
|
+
return false;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
return true;
|
|
51
|
+
}
|
|
52
|
+
function parseGrammemes(termForm) {
|
|
53
|
+
const result = [];
|
|
54
|
+
for (const chunk of termForm.split(",")) {
|
|
55
|
+
const gram = chunk.trim();
|
|
56
|
+
if (gram !== "") {
|
|
57
|
+
result.push(gram);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
return result.sort(grammemeCompare);
|
|
61
|
+
}
|
|
62
|
+
function generateNominalLexeme(data) {
|
|
63
|
+
return {
|
|
64
|
+
items: Plurality.flatMap(
|
|
65
|
+
(plurality) => Case.map((gramCase) => ({
|
|
66
|
+
text: data.text,
|
|
67
|
+
grams: `${plurality},${gramCase}`
|
|
68
|
+
}))
|
|
69
|
+
)
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
function parseEntityReference(text) {
|
|
73
|
+
const ref = parseReference(text);
|
|
74
|
+
if (ref?.type !== ReferenceType.ENTITY) {
|
|
75
|
+
throw new Error(`Invalid entity reference: ${text}`);
|
|
76
|
+
}
|
|
77
|
+
return ref.data;
|
|
78
|
+
}
|
|
79
|
+
function parseSyntacticReference(text) {
|
|
80
|
+
const ref = parseReference(text);
|
|
81
|
+
if (ref?.type !== ReferenceType.SYNTACTIC) {
|
|
82
|
+
throw new Error(`Invalid syntactic reference: ${text}`);
|
|
83
|
+
}
|
|
84
|
+
return ref.data;
|
|
85
|
+
}
|
|
86
|
+
function parseReference(text) {
|
|
87
|
+
if (text.length < 4 || !text.startsWith("@{") || !text.endsWith("}")) {
|
|
88
|
+
return null;
|
|
89
|
+
}
|
|
90
|
+
const blocks = text.slice(2, text.length - 1).split("|").map((block) => block.trim());
|
|
91
|
+
if (blocks.length !== 2 || blocks[0] === "" || blocks[0].startsWith("0")) {
|
|
92
|
+
return null;
|
|
93
|
+
}
|
|
94
|
+
if (blocks[0].startsWith("-") || /^[1-9]/.test(blocks[0])) {
|
|
95
|
+
const offset = Number(blocks[0]);
|
|
96
|
+
if (!Number.isInteger(offset) || offset === 0 || blocks[1] === "") {
|
|
97
|
+
return null;
|
|
98
|
+
}
|
|
99
|
+
return {
|
|
100
|
+
type: ReferenceType.SYNTACTIC,
|
|
101
|
+
data: { offset, nominal: blocks[1] }
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
return {
|
|
105
|
+
type: ReferenceType.ENTITY,
|
|
106
|
+
data: { entity: blocks[0], tags: parseGrammemes(blocks[1].replaceAll(" ", "")) }
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
function extractEntities(text) {
|
|
110
|
+
const result = [];
|
|
111
|
+
for (const segment of text.matchAll(ENTITY_REFERENCE_PATTERN)) {
|
|
112
|
+
const entity = segment[1].trim();
|
|
113
|
+
if (!result.includes(entity)) {
|
|
114
|
+
result.push(entity);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
return result;
|
|
118
|
+
}
|
|
119
|
+
function resolveTextReferences(text, context) {
|
|
120
|
+
const references = parseReferences(text);
|
|
121
|
+
if (references.length === 0) {
|
|
122
|
+
return text;
|
|
123
|
+
}
|
|
124
|
+
for (const ref of references) {
|
|
125
|
+
if (ref.ref.type === ReferenceType.ENTITY) {
|
|
126
|
+
ref.resolved = resolveEntity(ref.ref.data, context);
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
references.forEach((ref, index) => {
|
|
130
|
+
if (ref.ref.type === ReferenceType.SYNTACTIC) {
|
|
131
|
+
ref.resolved = resolveSyntactic(ref.ref.data, index, references);
|
|
132
|
+
}
|
|
133
|
+
});
|
|
134
|
+
let posInput = 0;
|
|
135
|
+
let output = "";
|
|
136
|
+
for (const ref of references) {
|
|
137
|
+
output += text.substring(posInput, ref.posInput.from);
|
|
138
|
+
output += ref.resolved;
|
|
139
|
+
posInput = ref.posInput.to;
|
|
140
|
+
}
|
|
141
|
+
output += text.substring(posInput);
|
|
142
|
+
return output;
|
|
143
|
+
}
|
|
144
|
+
function referenceToString(ref) {
|
|
145
|
+
switch (ref.type) {
|
|
146
|
+
case ReferenceType.ENTITY: {
|
|
147
|
+
const entity = ref.data;
|
|
148
|
+
return `@{${entity.entity}|${entity.tags.join(",")}}`;
|
|
149
|
+
}
|
|
150
|
+
case ReferenceType.SYNTACTIC: {
|
|
151
|
+
const syntactic = ref.data;
|
|
152
|
+
return `@{${syntactic.offset}|${syntactic.nominal}}`;
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
function grammemeCompare(left, right) {
|
|
157
|
+
const indexLeft = Object.values(Grammeme).findIndex((gram) => gram === left);
|
|
158
|
+
const indexRight = Object.values(Grammeme).findIndex((gram) => gram === right);
|
|
159
|
+
if (indexLeft === -1 && indexRight === -1) {
|
|
160
|
+
return left.localeCompare(right);
|
|
161
|
+
} else if (indexLeft === -1 && indexRight !== -1) {
|
|
162
|
+
return 1;
|
|
163
|
+
} else if (indexLeft !== -1 && indexRight === -1) {
|
|
164
|
+
return -1;
|
|
165
|
+
} else {
|
|
166
|
+
return indexLeft - indexRight;
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
function parseReferences(text) {
|
|
170
|
+
const result = [];
|
|
171
|
+
for (const segment of text.matchAll(REFERENCE_PATTERN)) {
|
|
172
|
+
const ref = parseReference(segment[0]);
|
|
173
|
+
if (ref) {
|
|
174
|
+
result.push({
|
|
175
|
+
ref,
|
|
176
|
+
resolved: "",
|
|
177
|
+
posInput: { from: segment.index ?? 0, to: (segment.index ?? 0) + segment[0].length }
|
|
178
|
+
});
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
return result;
|
|
182
|
+
}
|
|
183
|
+
function resolveEntity(ref, context) {
|
|
184
|
+
const entity = context[ref.entity];
|
|
185
|
+
if (!entity) {
|
|
186
|
+
return `!\u041D\u0435\u0438\u0437\u0432\u0435\u0441\u0442\u043D\u0430\u044F \u0441\u0443\u0449\u043D\u043E\u0441\u0442\u044C: ${ref.entity}!`;
|
|
187
|
+
}
|
|
188
|
+
const resolved = getEntityForm(entity, ref.tags);
|
|
189
|
+
return resolved === "" ? `!\u041E\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0443\u0435\u0442 \u0442\u0435\u0440\u043C\u0438\u043D: ${ref.entity}!` : resolved;
|
|
190
|
+
}
|
|
191
|
+
function getEntityForm(entity, grams) {
|
|
192
|
+
if (grams.length === 0) {
|
|
193
|
+
return entity.nominal;
|
|
194
|
+
}
|
|
195
|
+
const manual = entity.forms?.find((form) => matchGrams(grams, form.grams));
|
|
196
|
+
return manual?.text ?? entity.nominal;
|
|
197
|
+
}
|
|
198
|
+
function matchGrams(query, candidate) {
|
|
199
|
+
for (const gram of candidate) {
|
|
200
|
+
if (!query.includes(gram)) {
|
|
201
|
+
return false;
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
return true;
|
|
205
|
+
}
|
|
206
|
+
function resolveSyntactic(ref, index, references) {
|
|
207
|
+
const master = findSyntacticMaster(ref.offset, index, references);
|
|
208
|
+
if (!master) {
|
|
209
|
+
return `!\u041D\u0435\u043A\u043E\u0440\u0440\u0435\u043A\u0442\u043D\u043E\u0435 \u0441\u043C\u0435\u0449\u0435\u043D\u0438\u0435: ${ref.offset}!`;
|
|
210
|
+
}
|
|
211
|
+
return ref.nominal;
|
|
212
|
+
}
|
|
213
|
+
function findSyntacticMaster(offset, index, references) {
|
|
214
|
+
if (offset > 0) {
|
|
215
|
+
let position = index + 1;
|
|
216
|
+
let left = offset;
|
|
217
|
+
while (position < references.length) {
|
|
218
|
+
if (references[position].ref.type === ReferenceType.ENTITY) {
|
|
219
|
+
if (left === 1) {
|
|
220
|
+
return references[position];
|
|
221
|
+
}
|
|
222
|
+
left -= 1;
|
|
223
|
+
}
|
|
224
|
+
position += 1;
|
|
225
|
+
}
|
|
226
|
+
} else {
|
|
227
|
+
let position = index - 1;
|
|
228
|
+
let left = offset;
|
|
229
|
+
while (position >= 0) {
|
|
230
|
+
if (references[position].ref.type === ReferenceType.ENTITY) {
|
|
231
|
+
if (left === -1) {
|
|
232
|
+
return references[position];
|
|
233
|
+
}
|
|
234
|
+
left += 1;
|
|
235
|
+
}
|
|
236
|
+
position -= 1;
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
return void 0;
|
|
240
|
+
}
|
|
241
|
+
export {
|
|
242
|
+
extractEntities,
|
|
243
|
+
generateNominalLexeme,
|
|
244
|
+
parseEntityReference,
|
|
245
|
+
parseGrammemes,
|
|
246
|
+
parseReference,
|
|
247
|
+
parseSyntacticReference,
|
|
248
|
+
referenceToString,
|
|
249
|
+
resolveTextReferences,
|
|
250
|
+
wordFormEquals
|
|
251
|
+
};
|
|
252
|
+
//# sourceMappingURL=language-api.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/cctext/language.ts","../../src/cctext/language-api.ts"],"sourcesContent":["/**\n * Module: Natural language model declarations.\n */\n\n/** Represents single unit of language Morphology. */\n// prettier-ignore\nexport const Grammeme = {\n // Число\n sing: 'sing', plur: 'plur',\n\n // Падеж\n nomn: 'nomn', gent: 'gent', datv: 'datv',\n accs: 'accs', ablt: 'ablt', loct: 'loct',\n} as const;\nexport type Grammeme = (typeof Grammeme)[keyof typeof Grammeme];\n\n/** Represents case language concept. */\nexport const Case: Grammeme[] = [\n Grammeme.nomn,\n Grammeme.gent,\n Grammeme.datv,\n Grammeme.accs,\n Grammeme.ablt,\n Grammeme.loct\n] as const;\n\n/** Represents plurality language concept. */\nexport const Plurality: Grammeme[] = [Grammeme.sing, Grammeme.plur] as const;\n\n/** Represents specific wordform attached to {@link Grammeme}s. */\nexport interface WordForm {\n text: string;\n grams: Grammeme[];\n}\n\n/** Represents a term available for text reference resolution. */\nexport interface TermContextItem {\n nominal: string;\n forms?: WordForm[];\n}\n\n/** Represents term lookup context keyed by entity alias. */\nexport type TermContext = Record<string, TermContextItem>;\n\n/**\n * Represents list of {@link Grammeme}s available in reference construction.\n */\n// prettier-ignore\nexport const supportedGrammemes = [\n Grammeme.sing, Grammeme.plur,\n Grammeme.nomn, Grammeme.gent, Grammeme.datv,\n Grammeme.accs, Grammeme.ablt, Grammeme.loct,\n] as const;\n\n// ====== Reference resolution =====\n\n/** Represents text reference type. */\nexport const ReferenceType = {\n ENTITY: 'entity',\n SYNTACTIC: 'syntax'\n} as const;\nexport type ReferenceType = (typeof ReferenceType)[keyof typeof ReferenceType];\n\n/** Represents entity reference payload. */\nexport interface EntityReference {\n entity: string;\n tags: Grammeme[];\n}\n\n/** Represents syntactic reference payload. */\nexport interface SyntacticReference {\n offset: number;\n nominal: string;\n}\n\n/** Represents abstract reference data. */\nexport interface IReference {\n type: ReferenceType;\n data: EntityReference | SyntacticReference;\n}\n","/**\n * Module: Natural language model API.\n */\n\nimport {\n Case,\n type EntityReference,\n Grammeme,\n type IReference,\n Plurality,\n ReferenceType,\n type SyntacticReference,\n type TermContext,\n type TermContextItem,\n type WordForm\n} from './language';\n\ninterface Position {\n from: number;\n to: number;\n}\n\ninterface ResolvedReference {\n ref: IReference;\n resolved: string;\n posInput: Position;\n}\n\nconst REFERENCE_PATTERN = /@{[^{}]*?}/g;\nconst ENTITY_REFERENCE_PATTERN = /@{([^0-9\\-][^}|{]*?)\\|([^}|{]*?)}/g;\n\n/** Represents generated lexeme forms. */\nexport interface Lexeme {\n items: { text: string; grams: string }[];\n}\n\n/** Equality comparator for {@link WordForm}. Compares a set of Grammemes attached to wordforms. */\nexport function wordFormEquals(left: WordForm, right: WordForm): boolean {\n if (left.grams.length !== right.grams.length) {\n return false;\n }\n for (let index = 0; index < left.grams.length; ++index) {\n if (left.grams[index] !== right.grams[index]) {\n return false;\n }\n }\n return true;\n}\n\n/** Transforms {@link Grammeme} enumeration to {@link Grammeme}. */\nexport function parseGrammemes(termForm: string): Grammeme[] {\n const result: Grammeme[] = [];\n for (const chunk of termForm.split(',')) {\n const gram = chunk.trim();\n if (gram !== '') {\n result.push(gram as Grammeme);\n }\n }\n return result.sort(grammemeCompare);\n}\n\n/** Generates all supported noun forms using nominal text for every form. */\nexport function generateNominalLexeme(data: { text: string }): Lexeme {\n return {\n items: Plurality.flatMap(plurality =>\n Case.map(gramCase => ({\n text: data.text,\n grams: `${plurality},${gramCase}`\n }))\n )\n };\n}\n\n/**\n * Extracts {@link EntityReference} from string representation.\n *\n * @param text - Reference text in a valid pattern. Must fit format '\\@\\{GLOBAL_ID|GRAMMEMES\\}'\n */\nexport function parseEntityReference(text: string): EntityReference {\n const ref = parseReference(text);\n if (ref?.type !== ReferenceType.ENTITY) {\n throw new Error(`Invalid entity reference: ${text}`);\n }\n return ref.data as EntityReference;\n}\n\n/**\n * Extracts {@link SyntacticReference} from string representation.\n *\n * @param text - Reference text in a valid pattern. Must fit format '\\@\\{OFFSET|NOMINAL_FORM\\}'\n */\nexport function parseSyntacticReference(text: string): SyntacticReference {\n const ref = parseReference(text);\n if (ref?.type !== ReferenceType.SYNTACTIC) {\n throw new Error(`Invalid syntactic reference: ${text}`);\n }\n return ref.data as SyntacticReference;\n}\n\n/** Extracts a validated reference from string representation. */\nexport function parseReference(text: string): IReference | null {\n if (text.length < 4 || !text.startsWith('@{') || !text.endsWith('}')) {\n return null;\n }\n\n const blocks = text\n .slice(2, text.length - 1)\n .split('|')\n .map(block => block.trim());\n if (blocks.length !== 2 || blocks[0] === '' || blocks[0].startsWith('0')) {\n return null;\n }\n\n if (blocks[0].startsWith('-') || /^[1-9]/.test(blocks[0])) {\n const offset = Number(blocks[0]);\n if (!Number.isInteger(offset) || offset === 0 || blocks[1] === '') {\n return null;\n }\n return {\n type: ReferenceType.SYNTACTIC,\n data: { offset, nominal: blocks[1] }\n };\n }\n\n return {\n type: ReferenceType.ENTITY,\n data: { entity: blocks[0], tags: parseGrammemes(blocks[1].replaceAll(' ', '')) }\n };\n}\n\n/** Extracts unique entity aliases referenced by text. */\nexport function extractEntities(text: string): string[] {\n const result: string[] = [];\n for (const segment of text.matchAll(ENTITY_REFERENCE_PATTERN)) {\n const entity = segment[1].trim();\n if (!result.includes(entity)) {\n result.push(entity);\n }\n }\n return result;\n}\n\n/** Resolves text references using nominal terms and optional manually edited forms. */\nexport function resolveTextReferences(text: string, context: TermContext): string {\n const references = parseReferences(text);\n if (references.length === 0) {\n return text;\n }\n\n for (const ref of references) {\n if (ref.ref.type === ReferenceType.ENTITY) {\n ref.resolved = resolveEntity(ref.ref.data as EntityReference, context);\n }\n }\n references.forEach((ref, index) => {\n if (ref.ref.type === ReferenceType.SYNTACTIC) {\n ref.resolved = resolveSyntactic(ref.ref.data as SyntacticReference, index, references);\n }\n });\n\n let posInput = 0;\n let output = '';\n for (const ref of references) {\n output += text.substring(posInput, ref.posInput.from);\n output += ref.resolved;\n posInput = ref.posInput.to;\n }\n output += text.substring(posInput);\n return output;\n}\n\n/** Transforms {@link IReference} to string representation. */\nexport function referenceToString(ref: IReference): string {\n switch (ref.type) {\n case ReferenceType.ENTITY: {\n const entity = ref.data as EntityReference;\n return `@{${entity.entity}|${entity.tags.join(',')}}`;\n }\n case ReferenceType.SYNTACTIC: {\n const syntactic = ref.data as SyntacticReference;\n return `@{${syntactic.offset}|${syntactic.nominal}}`;\n }\n }\n}\n\n// ===== Internals =======\n\n/** Compares {@link Grammeme} based on Grammeme enum and alpha order for strings. */\nfunction grammemeCompare(left: Grammeme, right: Grammeme): number {\n const indexLeft = Object.values(Grammeme).findIndex(gram => gram === left);\n const indexRight = Object.values(Grammeme).findIndex(gram => gram === right);\n if (indexLeft === -1 && indexRight === -1) {\n return left.localeCompare(right);\n } else if (indexLeft === -1 && indexRight !== -1) {\n return 1;\n } else if (indexLeft !== -1 && indexRight === -1) {\n return -1;\n } else {\n return indexLeft - indexRight;\n }\n}\n\nfunction parseReferences(text: string): ResolvedReference[] {\n const result: ResolvedReference[] = [];\n for (const segment of text.matchAll(REFERENCE_PATTERN)) {\n const ref = parseReference(segment[0]);\n if (ref) {\n result.push({\n ref,\n resolved: '',\n posInput: { from: segment.index ?? 0, to: (segment.index ?? 0) + segment[0].length }\n });\n }\n }\n return result;\n}\n\nfunction resolveEntity(ref: EntityReference, context: TermContext): string {\n const entity = context[ref.entity];\n if (!entity) {\n return `!Неизвестная сущность: ${ref.entity}!`;\n }\n\n const resolved = getEntityForm(entity, ref.tags);\n return resolved === '' ? `!Отсутствует термин: ${ref.entity}!` : resolved;\n}\n\nfunction getEntityForm(entity: TermContextItem, grams: Grammeme[]): string {\n if (grams.length === 0) {\n return entity.nominal;\n }\n\n const manual = entity.forms?.find(form => matchGrams(grams, form.grams));\n return manual?.text ?? entity.nominal;\n}\n\nfunction matchGrams(query: Grammeme[], candidate: Grammeme[]): boolean {\n for (const gram of candidate) {\n if (!query.includes(gram)) {\n return false;\n }\n }\n return true;\n}\n\nfunction resolveSyntactic(ref: SyntacticReference, index: number, references: ResolvedReference[]): string {\n const master = findSyntacticMaster(ref.offset, index, references);\n if (!master) {\n return `!Некорректное смещение: ${ref.offset}!`;\n }\n return ref.nominal;\n}\n\nfunction findSyntacticMaster(\n offset: number,\n index: number,\n references: ResolvedReference[]\n): ResolvedReference | undefined {\n if (offset > 0) {\n let position = index + 1;\n let left = offset;\n while (position < references.length) {\n if (references[position].ref.type === ReferenceType.ENTITY) {\n if (left === 1) {\n return references[position];\n }\n left -= 1;\n }\n position += 1;\n }\n } else {\n let position = index - 1;\n let left = offset;\n while (position >= 0) {\n if (references[position].ref.type === ReferenceType.ENTITY) {\n if (left === -1) {\n return references[position];\n }\n left += 1;\n }\n position -= 1;\n }\n }\n return undefined;\n}\n"],"mappings":"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","names":[]}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Module: Natural language model declarations.
|
|
3
|
+
*/
|
|
4
|
+
/** Represents single unit of language Morphology. */
|
|
5
|
+
declare const Grammeme: {
|
|
6
|
+
readonly sing: "sing";
|
|
7
|
+
readonly plur: "plur";
|
|
8
|
+
readonly nomn: "nomn";
|
|
9
|
+
readonly gent: "gent";
|
|
10
|
+
readonly datv: "datv";
|
|
11
|
+
readonly accs: "accs";
|
|
12
|
+
readonly ablt: "ablt";
|
|
13
|
+
readonly loct: "loct";
|
|
14
|
+
};
|
|
15
|
+
type Grammeme = (typeof Grammeme)[keyof typeof Grammeme];
|
|
16
|
+
/** Represents case language concept. */
|
|
17
|
+
declare const Case: Grammeme[];
|
|
18
|
+
/** Represents plurality language concept. */
|
|
19
|
+
declare const Plurality: Grammeme[];
|
|
20
|
+
/** Represents specific wordform attached to {@link Grammeme}s. */
|
|
21
|
+
interface WordForm {
|
|
22
|
+
text: string;
|
|
23
|
+
grams: Grammeme[];
|
|
24
|
+
}
|
|
25
|
+
/** Represents a term available for text reference resolution. */
|
|
26
|
+
interface TermContextItem {
|
|
27
|
+
nominal: string;
|
|
28
|
+
forms?: WordForm[];
|
|
29
|
+
}
|
|
30
|
+
/** Represents term lookup context keyed by entity alias. */
|
|
31
|
+
type TermContext = Record<string, TermContextItem>;
|
|
32
|
+
/**
|
|
33
|
+
* Represents list of {@link Grammeme}s available in reference construction.
|
|
34
|
+
*/
|
|
35
|
+
declare const supportedGrammemes: readonly ["sing", "plur", "nomn", "gent", "datv", "accs", "ablt", "loct"];
|
|
36
|
+
/** Represents text reference type. */
|
|
37
|
+
declare const ReferenceType: {
|
|
38
|
+
readonly ENTITY: "entity";
|
|
39
|
+
readonly SYNTACTIC: "syntax";
|
|
40
|
+
};
|
|
41
|
+
type ReferenceType = (typeof ReferenceType)[keyof typeof ReferenceType];
|
|
42
|
+
/** Represents entity reference payload. */
|
|
43
|
+
interface EntityReference {
|
|
44
|
+
entity: string;
|
|
45
|
+
tags: Grammeme[];
|
|
46
|
+
}
|
|
47
|
+
/** Represents syntactic reference payload. */
|
|
48
|
+
interface SyntacticReference {
|
|
49
|
+
offset: number;
|
|
50
|
+
nominal: string;
|
|
51
|
+
}
|
|
52
|
+
/** Represents abstract reference data. */
|
|
53
|
+
interface IReference {
|
|
54
|
+
type: ReferenceType;
|
|
55
|
+
data: EntityReference | SyntacticReference;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
export { Case, type EntityReference, Grammeme, type IReference, Plurality, ReferenceType, type SyntacticReference, type TermContext, type TermContextItem, type WordForm, supportedGrammemes };
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
// src/cctext/language.ts
|
|
2
|
+
var Grammeme = {
|
|
3
|
+
// Число
|
|
4
|
+
sing: "sing",
|
|
5
|
+
plur: "plur",
|
|
6
|
+
// Падеж
|
|
7
|
+
nomn: "nomn",
|
|
8
|
+
gent: "gent",
|
|
9
|
+
datv: "datv",
|
|
10
|
+
accs: "accs",
|
|
11
|
+
ablt: "ablt",
|
|
12
|
+
loct: "loct"
|
|
13
|
+
};
|
|
14
|
+
var Case = [
|
|
15
|
+
Grammeme.nomn,
|
|
16
|
+
Grammeme.gent,
|
|
17
|
+
Grammeme.datv,
|
|
18
|
+
Grammeme.accs,
|
|
19
|
+
Grammeme.ablt,
|
|
20
|
+
Grammeme.loct
|
|
21
|
+
];
|
|
22
|
+
var Plurality = [Grammeme.sing, Grammeme.plur];
|
|
23
|
+
var supportedGrammemes = [
|
|
24
|
+
Grammeme.sing,
|
|
25
|
+
Grammeme.plur,
|
|
26
|
+
Grammeme.nomn,
|
|
27
|
+
Grammeme.gent,
|
|
28
|
+
Grammeme.datv,
|
|
29
|
+
Grammeme.accs,
|
|
30
|
+
Grammeme.ablt,
|
|
31
|
+
Grammeme.loct
|
|
32
|
+
];
|
|
33
|
+
var ReferenceType = {
|
|
34
|
+
ENTITY: "entity",
|
|
35
|
+
SYNTACTIC: "syntax"
|
|
36
|
+
};
|
|
37
|
+
export {
|
|
38
|
+
Case,
|
|
39
|
+
Grammeme,
|
|
40
|
+
Plurality,
|
|
41
|
+
ReferenceType,
|
|
42
|
+
supportedGrammemes
|
|
43
|
+
};
|
|
44
|
+
//# sourceMappingURL=language.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/cctext/language.ts"],"sourcesContent":["/**\n * Module: Natural language model declarations.\n */\n\n/** Represents single unit of language Morphology. */\n// prettier-ignore\nexport const Grammeme = {\n // Число\n sing: 'sing', plur: 'plur',\n\n // Падеж\n nomn: 'nomn', gent: 'gent', datv: 'datv',\n accs: 'accs', ablt: 'ablt', loct: 'loct',\n} as const;\nexport type Grammeme = (typeof Grammeme)[keyof typeof Grammeme];\n\n/** Represents case language concept. */\nexport const Case: Grammeme[] = [\n Grammeme.nomn,\n Grammeme.gent,\n Grammeme.datv,\n Grammeme.accs,\n Grammeme.ablt,\n Grammeme.loct\n] as const;\n\n/** Represents plurality language concept. */\nexport const Plurality: Grammeme[] = [Grammeme.sing, Grammeme.plur] as const;\n\n/** Represents specific wordform attached to {@link Grammeme}s. */\nexport interface WordForm {\n text: string;\n grams: Grammeme[];\n}\n\n/** Represents a term available for text reference resolution. */\nexport interface TermContextItem {\n nominal: string;\n forms?: WordForm[];\n}\n\n/** Represents term lookup context keyed by entity alias. */\nexport type TermContext = Record<string, TermContextItem>;\n\n/**\n * Represents list of {@link Grammeme}s available in reference construction.\n */\n// prettier-ignore\nexport const supportedGrammemes = [\n Grammeme.sing, Grammeme.plur,\n Grammeme.nomn, Grammeme.gent, Grammeme.datv,\n Grammeme.accs, Grammeme.ablt, Grammeme.loct,\n] as const;\n\n// ====== Reference resolution =====\n\n/** Represents text reference type. */\nexport const ReferenceType = {\n ENTITY: 'entity',\n SYNTACTIC: 'syntax'\n} as const;\nexport type ReferenceType = (typeof ReferenceType)[keyof typeof ReferenceType];\n\n/** Represents entity reference payload. */\nexport interface EntityReference {\n entity: string;\n tags: Grammeme[];\n}\n\n/** Represents syntactic reference payload. */\nexport interface SyntacticReference {\n offset: number;\n nominal: string;\n}\n\n/** Represents abstract reference data. */\nexport interface IReference {\n type: ReferenceType;\n data: EntityReference | SyntacticReference;\n}\n"],"mappings":";AAMO,IAAM,WAAW;AAAA;AAAA,EAEtB,MAAM;AAAA,EAAQ,MAAM;AAAA;AAAA,EAGpB,MAAM;AAAA,EAAQ,MAAM;AAAA,EAAQ,MAAM;AAAA,EAClC,MAAM;AAAA,EAAQ,MAAM;AAAA,EAAQ,MAAM;AACpC;AAIO,IAAM,OAAmB;AAAA,EAC9B,SAAS;AAAA,EACT,SAAS;AAAA,EACT,SAAS;AAAA,EACT,SAAS;AAAA,EACT,SAAS;AAAA,EACT,SAAS;AACX;AAGO,IAAM,YAAwB,CAAC,SAAS,MAAM,SAAS,IAAI;AAqB3D,IAAM,qBAAqB;AAAA,EAChC,SAAS;AAAA,EAAM,SAAS;AAAA,EACxB,SAAS;AAAA,EAAM,SAAS;AAAA,EAAM,SAAS;AAAA,EACvC,SAAS;AAAA,EAAM,SAAS;AAAA,EAAM,SAAS;AACzC;AAKO,IAAM,gBAAgB;AAAA,EAC3B,QAAQ;AAAA,EACR,WAAW;AACb;","names":[]}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Module: Custom graph data structure.
|
|
3
|
+
*/
|
|
4
|
+
/** Represents single node of a {@link Graph}, as implemented by storing outgoing and incoming connections. */
|
|
5
|
+
declare class GraphNode<NodeID> {
|
|
6
|
+
/** Unique identifier of the node. */
|
|
7
|
+
id: NodeID;
|
|
8
|
+
/** List of outgoing nodes. */
|
|
9
|
+
outputs: NodeID[];
|
|
10
|
+
/** List of incoming nodes. */
|
|
11
|
+
inputs: NodeID[];
|
|
12
|
+
constructor(id: NodeID);
|
|
13
|
+
clone(): GraphNode<NodeID>;
|
|
14
|
+
addOutput(node: NodeID): void;
|
|
15
|
+
addInput(node: NodeID): void;
|
|
16
|
+
removeInput(target: NodeID): NodeID | null;
|
|
17
|
+
removeOutput(target: NodeID): NodeID | null;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Represents a Graph.
|
|
21
|
+
*
|
|
22
|
+
* This class is optimized for TermGraph use case and not supposed to be used as generic graph implementation.
|
|
23
|
+
*/
|
|
24
|
+
declare class Graph<NodeID = number> {
|
|
25
|
+
/** Map of nodes. */
|
|
26
|
+
nodes: Map<NodeID, GraphNode<NodeID>>;
|
|
27
|
+
constructor(arr?: NodeID[][]);
|
|
28
|
+
clone(): Graph<NodeID>;
|
|
29
|
+
at(target: NodeID): GraphNode<NodeID> | undefined;
|
|
30
|
+
addNode(target: NodeID): GraphNode<NodeID>;
|
|
31
|
+
hasNode(target: NodeID): boolean;
|
|
32
|
+
removeNode(target: NodeID): void;
|
|
33
|
+
foldNode(target: NodeID): void;
|
|
34
|
+
removeIsolated(): GraphNode<NodeID>[];
|
|
35
|
+
addEdge(source: NodeID, destination: NodeID): void;
|
|
36
|
+
removeEdge(source: NodeID, destination: NodeID): void;
|
|
37
|
+
hasEdge(source: NodeID, destination: NodeID): boolean;
|
|
38
|
+
isReachable(source: NodeID, destination: NodeID): boolean;
|
|
39
|
+
rootNodes(): NodeID[];
|
|
40
|
+
expandOutputs(origin: NodeID[]): NodeID[];
|
|
41
|
+
expandInputs(origin: NodeID[]): NodeID[];
|
|
42
|
+
expandAllOutputs(origin: NodeID[]): NodeID[];
|
|
43
|
+
expandAllInputs(origin: NodeID[]): NodeID[];
|
|
44
|
+
maximizePart(origin: NodeID[]): NodeID[];
|
|
45
|
+
topologicalOrder(): NodeID[];
|
|
46
|
+
/**
|
|
47
|
+
* Stably reorders the given node ids so that, for this DAG, no node appears before a transitive
|
|
48
|
+
* successor (edges: source → dependent; {@link GraphNode.outputs} lists dependents).
|
|
49
|
+
*/
|
|
50
|
+
sortStable(target: NodeID[]): NodeID[];
|
|
51
|
+
private buildTransitiveClosureForSort;
|
|
52
|
+
transitiveReduction(): void;
|
|
53
|
+
/**
|
|
54
|
+
* Finds a cycle in the graph.
|
|
55
|
+
*
|
|
56
|
+
* @returns {NodeID[] | null} The cycle if found, otherwise `null`.
|
|
57
|
+
* Uses non-recursive DFS.
|
|
58
|
+
*/
|
|
59
|
+
findCycle(): NodeID[] | null;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
export { Graph, GraphNode };
|