glossarist 0.4.38 → 0.4.40

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.
Files changed (41) hide show
  1. package/package.json +1 -1
  2. package/src/models/base.ts +18 -1
  3. package/src/models/citation.ts +98 -0
  4. package/src/models/{concept-reference.js → concept-reference.ts} +21 -7
  5. package/src/models/designation-relationship.ts +39 -0
  6. package/src/models/designation.ts +297 -0
  7. package/src/models/figure.ts +110 -0
  8. package/src/models/formula.ts +36 -0
  9. package/src/models/gcr-metadata.ts +118 -0
  10. package/src/models/gcr-statistics.ts +76 -0
  11. package/src/models/hyperedge-colors.ts +87 -0
  12. package/src/models/non-verb-rep.ts +48 -0
  13. package/src/models/non-verbal-entity.ts +65 -0
  14. package/src/models/non-verbal-reference.ts +73 -0
  15. package/src/models/non-verbal-references.ts +29 -0
  16. package/src/models/register.ts +315 -0
  17. package/src/models/registrable.ts +48 -0
  18. package/src/models/{related-concept.js → related-concept.ts} +49 -25
  19. package/src/models/relation-categories.ts +167 -0
  20. package/src/models/{relation-colors.js → relation-colors.ts} +36 -23
  21. package/src/models/section.ts +61 -0
  22. package/src/models/shared-non-verbal-entity.ts +36 -0
  23. package/src/models/table.ts +36 -0
  24. package/src/models/citation.js +0 -68
  25. package/src/models/designation-relationship.js +0 -27
  26. package/src/models/designation.js +0 -213
  27. package/src/models/figure.js +0 -75
  28. package/src/models/formula.js +0 -25
  29. package/src/models/gcr-metadata.js +0 -68
  30. package/src/models/gcr-statistics.js +0 -51
  31. package/src/models/hyperedge-colors.js +0 -71
  32. package/src/models/non-verb-rep.js +0 -33
  33. package/src/models/non-verbal-entity.js +0 -46
  34. package/src/models/non-verbal-reference.js +0 -35
  35. package/src/models/non-verbal-references.js +0 -16
  36. package/src/models/register.js +0 -253
  37. package/src/models/registrable.js +0 -25
  38. package/src/models/relation-categories.js +0 -182
  39. package/src/models/section.js +0 -44
  40. package/src/models/shared-non-verbal-entity.js +0 -28
  41. package/src/models/table.js +0 -25
@@ -6,10 +6,27 @@
6
6
 
7
7
  import { categoryOf, categoryDefinition } from './relation-categories.js';
8
8
 
9
- // One { light, dark } pair per category. Keeping these in glossarist-js
10
- // lets the defaults ship with the library; consumers only need to
11
- // customize when they want to deviate.
12
- export const RELATION_COLOR_DEFAULTS = Object.freeze({
9
+ export interface ColorPair {
10
+ light: string;
11
+ dark: string;
12
+ }
13
+
14
+ export interface RelationColorPalette {
15
+ byCategory: Readonly<Record<string, ColorPair>>;
16
+ byType: Readonly<Record<string, ColorPair>>;
17
+ }
18
+
19
+ export interface ResolveRelationColorOptions {
20
+ overrides?: Partial<RelationColorPalette>;
21
+ mode?: 'light' | 'dark';
22
+ }
23
+
24
+ /**
25
+ * One { light, dark } pair per category. Keeping these in glossarist-js
26
+ * lets the defaults ship with the library; consumers only need to
27
+ * customize when they want to deviate.
28
+ */
29
+ export const RELATION_COLOR_DEFAULTS: RelationColorPalette = Object.freeze({
13
30
  byCategory: Object.freeze({
14
31
  lifecycle: { light: '#B43A2E', dark: '#F87171' },
15
32
  hierarchical: { light: '#1F6FEB', dark: '#6EA8FE' },
@@ -19,39 +36,32 @@ export const RELATION_COLOR_DEFAULTS = Object.freeze({
19
36
  lexical: { light: '#D97706', dark: '#FBBF24' },
20
37
  mapping: { light: '#2563EB', dark: '#93BBFD' },
21
38
  definitional: { light: '#65A30D', dark: '#A3E635' },
22
- }),
23
-
24
- // Per-type overrides. Use the same { light, dark } shape. Keys are
25
- // relationship-type local names. Empty by default — consumers may
26
- // populate this through `overrides.byType` at call time.
27
- byType: Object.freeze({}),
39
+ }) as Readonly<Record<string, ColorPair>>,
40
+ byType: Object.freeze({}) as Readonly<Record<string, ColorPair>>,
28
41
  });
29
42
 
30
43
  /**
31
- * Resolves the color for a relationship type.
32
- *
33
- * Resolution order:
44
+ * Resolves the color for a relationship type. Resolution order:
34
45
  * 1. overrides.byType[type]
35
46
  * 2. RELATION_COLOR_DEFAULTS.byType[type]
36
47
  * 3. overrides.byCategory[category]
37
48
  * 4. RELATION_COLOR_DEFAULTS.byCategory[category]
38
49
  * 5. null (uncategorized or unrecognized type)
39
- *
40
- * @param {string} type - relationship type local name
41
- * @param {{ overrides?: { byType?: object, byCategory?: object }, mode?: 'light'|'dark' }} [options]
42
- * @returns {string | null}
43
50
  */
44
- export function resolveRelationColor(type, options = {}) {
51
+ export function resolveRelationColor(
52
+ type: string,
53
+ options: ResolveRelationColorOptions = {},
54
+ ): string | null {
45
55
  const mode = options.mode ?? 'light';
46
56
  const overrides = options.overrides ?? {};
47
-
48
57
  const typeOverride = overrides.byType?.[type] ?? RELATION_COLOR_DEFAULTS.byType[type];
49
58
  if (typeOverride) return pickMode(typeOverride, mode);
50
59
 
51
60
  const category = categoryOf(type);
52
61
  if (!category) return null;
53
62
 
54
- const categoryOverride = overrides.byCategory?.[category] ?? RELATION_COLOR_DEFAULTS.byCategory[category];
63
+ const categoryOverride =
64
+ overrides.byCategory?.[category] ?? RELATION_COLOR_DEFAULTS.byCategory[category];
55
65
  if (!categoryOverride) return null;
56
66
 
57
67
  return pickMode(categoryOverride, mode);
@@ -61,16 +71,19 @@ export function resolveRelationColor(type, options = {}) {
61
71
  * Returns the { light, dark } pair for a category, merging overrides
62
72
  * over defaults. Useful for UIs that want to render a legend.
63
73
  */
64
- export function categoryColorPair(categoryKey, overrides = {}) {
74
+ export function categoryColorPair(
75
+ categoryKey: string,
76
+ overrides: { byCategory?: Record<string, Partial<ColorPair>> } = {},
77
+ ): ColorPair | null {
65
78
  const def = categoryDefinition(categoryKey);
66
79
  if (!def) return null;
67
80
  const fromOverride = overrides.byCategory?.[categoryKey];
68
81
  const fromDefault = RELATION_COLOR_DEFAULTS.byCategory[categoryKey];
69
82
  if (!fromDefault && !fromOverride) return null;
70
- return { ...(fromDefault ?? {}), ...(fromOverride ?? {}) };
83
+ return { ...(fromDefault ?? { light: '', dark: '' }), ...(fromOverride ?? {}) } as ColorPair;
71
84
  }
72
85
 
73
- function pickMode(pair, mode) {
86
+ function pickMode(pair: ColorPair | string | null, mode: 'light' | 'dark'): string | null {
74
87
  if (pair == null) return null;
75
88
  if (typeof pair === 'string') return pair;
76
89
  return pair[mode] ?? pair.light ?? pair.dark ?? null;
@@ -0,0 +1,61 @@
1
+ import { GlossaristModel } from './base.js';
2
+ import type { LocalizedString } from './generic-member.js';
3
+
4
+ export const ORDERING_METHODS: ReadonlyArray<string> = Object.freeze([
5
+ 'systematic',
6
+ 'mixed',
7
+ 'alphabetical',
8
+ ]);
9
+
10
+ export type OrderingMethod = string;
11
+
12
+ export interface SectionJson {
13
+ id?: string | null;
14
+ names?: LocalizedString;
15
+ ordering?: OrderingMethod | null;
16
+ children?: ReadonlyArray<SectionJson | Section>;
17
+ }
18
+
19
+ export class Section extends GlossaristModel {
20
+ readonly id: string | null;
21
+ readonly names: LocalizedString;
22
+ readonly ordering: OrderingMethod | null;
23
+ readonly children: ReadonlyArray<Section>;
24
+
25
+ constructor(data: SectionJson = {}) {
26
+ super();
27
+ this.id = data.id ?? null;
28
+ this.names = (data.names as LocalizedString) ?? {};
29
+ this.ordering = data.ordering ?? null;
30
+ this.children = (data.children ?? []).map((c) =>
31
+ c instanceof Section ? c : new Section(c as SectionJson),
32
+ );
33
+ }
34
+
35
+ name(lang: string): string | null {
36
+ return this.names[lang] ?? this.names['eng'] ?? null;
37
+ }
38
+
39
+ descendantById(id: string): Section | null {
40
+ for (const child of this.children) {
41
+ if (child.id === id) return child;
42
+ const found = child.descendantById(id);
43
+ if (found) return found;
44
+ }
45
+ return null;
46
+ }
47
+
48
+ override toJSON(): SectionJson {
49
+ const obj: SectionJson = { id: this.id };
50
+ if (Object.keys(this.names).length > 0) obj.names = { ...this.names };
51
+ if (this.ordering != null) obj.ordering = this.ordering;
52
+ if (this.children.length > 0) {
53
+ obj.children = this.children.map((c) => c.toJSON());
54
+ }
55
+ return obj;
56
+ }
57
+
58
+ static override fromJSON(data: SectionJson): Section {
59
+ return new Section(data);
60
+ }
61
+ }
@@ -0,0 +1,36 @@
1
+ import { NonVerbalEntity } from './non-verbal-entity.js';
2
+ import type { NonVerbalEntityJson } from './non-verbal-entity.js';
3
+
4
+ export interface SharedNonVerbalEntityJson extends NonVerbalEntityJson {
5
+ id?: string | null;
6
+ identifier?: string | null;
7
+ }
8
+
9
+ export class SharedNonVerbalEntity extends NonVerbalEntity {
10
+ readonly id: string | null;
11
+ readonly identifier: string | null;
12
+
13
+ constructor(data: SharedNonVerbalEntityJson = {}) {
14
+ super(data);
15
+ this.id = data.id ?? null;
16
+ this.identifier = data.identifier ?? null;
17
+ }
18
+
19
+ override findById(targetId: string): this | null {
20
+ return this.id === targetId ? this : null;
21
+ }
22
+ override allIds(): string[] {
23
+ return this.id != null ? [this.id] : [];
24
+ }
25
+
26
+ override toJSON(): SharedNonVerbalEntityJson {
27
+ const obj = super.toJSON() as SharedNonVerbalEntityJson;
28
+ if (this.id != null) obj.id = this.id;
29
+ if (this.identifier != null) obj.identifier = this.identifier;
30
+ return obj;
31
+ }
32
+
33
+ static override fromJSON(data: SharedNonVerbalEntityJson): SharedNonVerbalEntity {
34
+ return SharedNonVerbalEntity.fromData(data);
35
+ }
36
+ }
@@ -0,0 +1,36 @@
1
+ import { SharedNonVerbalEntity } from './shared-non-verbal-entity.js';
2
+ import type { SharedNonVerbalEntityJson } from './shared-non-verbal-entity.js';
3
+ import { NonVerbalEntity } from './non-verbal-entity.js';
4
+
5
+ export interface TableJson extends SharedNonVerbalEntityJson {
6
+ content?: string | null;
7
+ format?: string | null;
8
+ }
9
+
10
+ export class Table extends SharedNonVerbalEntity {
11
+ readonly content: string | null;
12
+ readonly format: string | null;
13
+
14
+ constructor(data: TableJson = {}) {
15
+ super(data);
16
+ this.content = data.content ?? null;
17
+ this.format = data.format ?? null;
18
+ }
19
+
20
+ override rdfClass(): string {
21
+ return 'Table';
22
+ }
23
+
24
+ override toJSON(): TableJson {
25
+ const obj = super.toJSON() as TableJson;
26
+ if (this.content != null) obj.content = this.content;
27
+ if (this.format != null) obj.format = this.format;
28
+ return obj;
29
+ }
30
+
31
+ static override fromJSON(data: TableJson): Table {
32
+ return new Table(data);
33
+ }
34
+ }
35
+
36
+ NonVerbalEntity.register('table', Table);
@@ -1,68 +0,0 @@
1
- import { GlossaristModel } from './base.js';
2
- import { Locality } from './locality.js';
3
-
4
- export class Citation extends GlossaristModel {
5
- constructor(data = {}) {
6
- super();
7
- const d = data ?? {};
8
-
9
- this.ref = d.ref
10
- ? (d.ref instanceof Citation.Ref ? d.ref : new Citation.Ref(d.ref))
11
- : null;
12
-
13
- this.locality = d.locality
14
- ? (d.locality instanceof Locality ? d.locality : new Locality(d.locality))
15
- : null;
16
- this.link = d.link ?? null;
17
- this.original = d.original ?? null;
18
- this.customLocality = d.custom_locality ?? d.customLocality ?? null;
19
- }
20
-
21
- toString() {
22
- if (this.ref) return this.ref.toString();
23
- return '';
24
- }
25
-
26
- toJSON() {
27
- const obj = {};
28
- if (this.ref != null) obj.ref = this.ref.toJSON();
29
- if (this.locality != null) obj.locality = this.locality.toJSON();
30
- if (this.link != null) obj.link = this.link;
31
- if (this.original != null) obj.original = this.original;
32
- if (this.customLocality != null) obj.custom_locality = this.customLocality;
33
- return obj;
34
- }
35
-
36
- static fromJSON(data) {
37
- return new Citation(data);
38
- }
39
- }
40
-
41
- Citation.Ref = class Ref extends GlossaristModel {
42
- constructor(data = {}) {
43
- super();
44
- const d = data ?? {};
45
- this.source = d.source ?? null;
46
- this.id = d.id ?? null;
47
- this.version = d.version ?? null;
48
- }
49
-
50
- toString() {
51
- const parts = [];
52
- if (this.source) parts.push(this.source);
53
- if (this.id) parts.push(this.id);
54
- return parts.join(' ');
55
- }
56
-
57
- toJSON() {
58
- const obj = {};
59
- if (this.source != null) obj.source = this.source;
60
- if (this.id != null) obj.id = this.id;
61
- if (this.version != null) obj.version = this.version;
62
- return obj;
63
- }
64
-
65
- static fromJSON(data) {
66
- return new Citation.Ref(data);
67
- }
68
- };
@@ -1,27 +0,0 @@
1
- import { GlossaristModel } from './base.js';
2
-
3
- export const DESIGNATION_RELATIONSHIP_TYPES = Object.freeze([
4
- // TBX (ISO 30042) / ISO 12620 term-level relationships
5
- 'abbreviated_form_for', 'short_form_for',
6
- ]);
7
-
8
- export class DesignationRelationship extends GlossaristModel {
9
- constructor(data = {}) {
10
- super();
11
- this.type = data.type ?? null;
12
- this.content = data.content ?? null;
13
- this.target = data.target ?? null;
14
- }
15
-
16
- toJSON() {
17
- const obj = {};
18
- if (this.type != null) obj.type = this.type;
19
- if (this.content != null) obj.content = this.content;
20
- if (this.target != null) obj.target = this.target;
21
- return obj;
22
- }
23
-
24
- static fromJSON(data) {
25
- return new DesignationRelationship(data);
26
- }
27
- }
@@ -1,213 +0,0 @@
1
- import { RegistrableModel } from './registrable.js';
2
- import { ConceptSource } from './concept-source.js';
3
- import { Pronunciation } from './pronunciation.js';
4
- import { GrammarInfo } from './grammar-info.js';
5
- import { RelatedConcept } from './related-concept.js';
6
- import { DesignationRelationship, DESIGNATION_RELATIONSHIP_TYPES } from './designation-relationship.js';
7
-
8
- // Maps a normative-status local-name to the matching SKOS/SKOS-XL label
9
- // predicate local-name. Lives on the model so a new status requires a
10
- // single edit here, not edits in every emitter.
11
- const SKOS_LABEL_BY_NORMATIVE_STATUS = Object.freeze({
12
- preferred: 'prefLabel',
13
- deprecated: 'hiddenLabel',
14
- admitted: 'altLabel',
15
- deprecated_: 'altLabel',
16
- });
17
-
18
- export class Designation extends RegistrableModel {
19
- constructor(data = {}) {
20
- super();
21
- this.designation = data.designation ?? '';
22
- this.type = data.type ?? 'expression';
23
- this.normativeStatus = data.normative_status ?? null;
24
- this.absent = data.absent ?? null;
25
- this.fieldOfApplication = data.field_of_application ?? null;
26
- this.usageInfo = data.usage_info ?? null;
27
- this.geographicalArea = data.geographical_area ?? null;
28
- this.language = data.language ?? null;
29
- this.script = data.script ?? null;
30
- this.system = data.system ?? null;
31
- this.international = data.international ?? null;
32
- this.termType = data.term_type ?? null;
33
- this.pronunciations = (data.pronunciation ?? []).map(
34
- p => p instanceof Pronunciation ? p : new Pronunciation(p)
35
- );
36
- this.sources = (data.sources ?? []).map(
37
- s => s instanceof ConceptSource ? s : new ConceptSource(s)
38
- );
39
- this.related = (data.related ?? []).map(
40
- r => (r instanceof DesignationRelationship || r instanceof RelatedConcept)
41
- ? r
42
- : DESIGNATION_RELATIONSHIP_TYPES.includes(r.type)
43
- ? DesignationRelationship.fromJSON(r)
44
- : RelatedConcept.fromJSON(r)
45
- );
46
- }
47
-
48
- toJSON() {
49
- const obj = { type: this.type, designation: this.designation };
50
- if (this.normativeStatus != null) obj.normative_status = this.normativeStatus;
51
- if (this.absent != null) obj.absent = this.absent;
52
- if (this.fieldOfApplication != null) obj.field_of_application = this.fieldOfApplication;
53
- if (this.usageInfo != null) obj.usage_info = this.usageInfo;
54
- if (this.geographicalArea != null) obj.geographical_area = this.geographicalArea;
55
- if (this.language != null) obj.language = this.language;
56
- if (this.script != null) obj.script = this.script;
57
- if (this.system != null) obj.system = this.system;
58
- if (this.international != null) obj.international = this.international;
59
- if (this.termType != null) obj.term_type = this.termType;
60
- if (this.pronunciations.length > 0) obj.pronunciation = this.pronunciations.map(p => p.toJSON());
61
- if (this.sources.length > 0) obj.sources = this.sources.map(s => s.toJSON());
62
- if (this.related.length > 0) obj.related = this.related.map(r => r.toJSON());
63
- return obj;
64
- }
65
-
66
- // RDF class local-name for this designation subtype. Override in
67
- // subclasses that map to a different ontology class.
68
- rdfClass() {
69
- return 'Expression';
70
- }
71
-
72
- // SKOS label predicate URI (skos:prefLabel / skos:altLabel / skos:hiddenLabel)
73
- // appropriate for this designation's normative status. Falls back to
74
- // skos:altLabel for unknown statuses.
75
- skosLabelPredicate(skosNs) {
76
- const label = this._skosLabelLocalName();
77
- return `${skosNs}${label}`;
78
- }
79
-
80
- // SKOS-XL label predicate URI (skosxl:prefLabel / etc.).
81
- skosxlLabelPredicate(skosxlNs) {
82
- const label = this._skosLabelLocalName();
83
- return `${skosxlNs}${label}`;
84
- }
85
-
86
- _skosLabelLocalName() {
87
- const status = String(this.normativeStatus ?? '')
88
- .split(/[/#]/)
89
- .pop()
90
- .trim();
91
- return SKOS_LABEL_BY_NORMATIVE_STATUS[status] ?? 'altLabel';
92
- }
93
-
94
- // Static identity works on a model instance OR its plain JSON form.
95
- // The diff layer uses this so that patch-side identity (computed on
96
- // plain JSON from toJSON) matches diff-side identity (computed on
97
- // model instances).
98
- static identityOf(value) {
99
- const v = value ?? {};
100
- const type = v.type ?? 'expression';
101
- const text = String(v.designation ?? '').toLowerCase().trim();
102
- return `${type}|${text}`;
103
- }
104
-
105
- identity() {
106
- return Designation.identityOf(this);
107
- }
108
-
109
- static fromJSON(data) {
110
- return Designation.fromData(data);
111
- }
112
- }
113
-
114
- export class Expression extends Designation {
115
- constructor(data = {}) {
116
- super(data);
117
- this.prefix = data.prefix ?? null;
118
- this.grammarInfo = (data.grammar_info ?? []).map(
119
- g => g instanceof GrammarInfo ? g : new GrammarInfo(g)
120
- );
121
- }
122
-
123
- toJSON() {
124
- const obj = super.toJSON();
125
- if (this.prefix != null) obj.prefix = this.prefix;
126
- if (this.grammarInfo.length > 0) obj.grammar_info = this.grammarInfo.map(g => g.toJSON());
127
- return obj;
128
- }
129
-
130
- static fromJSON(data) { return new Expression(data); }
131
- }
132
-
133
- Designation.register('expression', Expression);
134
-
135
- export class Abbreviation extends Expression {
136
- constructor(data = {}) {
137
- super(data);
138
- this.acronym = data.acronym ?? false;
139
- this.initialism = data.initialism ?? false;
140
- this.truncation = data.truncation ?? false;
141
- }
142
-
143
- rdfClass() {
144
- return 'Abbreviation';
145
- }
146
-
147
- toJSON() {
148
- const obj = super.toJSON();
149
- if (this.acronym) obj.acronym = true;
150
- if (this.initialism) obj.initialism = true;
151
- if (this.truncation) obj.truncation = true;
152
- return obj;
153
- }
154
-
155
- static fromJSON(data) { return new Abbreviation(data); }
156
- }
157
-
158
- Designation.register('abbreviation', Abbreviation);
159
-
160
- export class Symbol extends Designation {
161
- rdfClass() {
162
- return 'Symbol';
163
- }
164
-
165
- static fromJSON(data) { return new Symbol(data); }
166
- }
167
-
168
- Designation.register('symbol', Symbol);
169
-
170
- export class LetterSymbol extends Symbol {
171
- constructor(data = {}) {
172
- super(data);
173
- this.text = data.text ?? null;
174
- }
175
-
176
- rdfClass() {
177
- return 'LetterSymbol';
178
- }
179
-
180
- toJSON() {
181
- const obj = super.toJSON();
182
- if (this.text != null) obj.text = this.text;
183
- return obj;
184
- }
185
-
186
- static fromJSON(data) { return new LetterSymbol(data); }
187
- }
188
-
189
- Designation.register('letter_symbol', LetterSymbol);
190
-
191
- export class GraphicalSymbol extends Symbol {
192
- constructor(data = {}) {
193
- super(data);
194
- this.text = data.text ?? null;
195
- this.image = data.image ?? null;
196
- }
197
-
198
- rdfClass() {
199
- return 'GraphicalSymbol';
200
- }
201
-
202
- toJSON() {
203
- const obj = super.toJSON();
204
- if (this.text != null) obj.text = this.text;
205
- if (this.image != null) obj.image = this.image;
206
- return obj;
207
- }
208
-
209
- static fromJSON(data) { return new GraphicalSymbol(data); }
210
- }
211
-
212
- Designation.register('graphical symbol', GraphicalSymbol);
213
- Designation.register('graphical_symbol', GraphicalSymbol);
@@ -1,75 +0,0 @@
1
- import { SharedNonVerbalEntity } from './shared-non-verbal-entity.js';
2
- import { NonVerbalEntity } from './non-verbal-entity.js';
3
-
4
- export class FigureImage {
5
- constructor(data = {}) {
6
- this.src = data.src ?? null;
7
- this.format = data.format ?? null;
8
- this.role = data.role ?? null;
9
- this.width = data.width ?? null;
10
- this.height = data.height ?? null;
11
- this.scale = data.scale ?? null;
12
- }
13
-
14
- toJSON() {
15
- const obj = {};
16
- if (this.src != null) obj.src = this.src;
17
- if (this.format != null) obj.format = this.format;
18
- if (this.role != null) obj.role = this.role;
19
- if (this.width != null) obj.width = this.width;
20
- if (this.height != null) obj.height = this.height;
21
- if (this.scale != null) obj.scale = this.scale;
22
- return obj;
23
- }
24
-
25
- static fromJSON(data) { return new FigureImage(data); }
26
- }
27
-
28
- export class Figure extends SharedNonVerbalEntity {
29
- constructor(data = {}) {
30
- super(data);
31
- this._rawImages = data.images ?? [];
32
- this._rawSubfigures = data.subfigures ?? [];
33
- this._images = null;
34
- this._subfigures = null;
35
- }
36
-
37
- rdfClass() {
38
- return 'Figure';
39
- }
40
-
41
- get images() {
42
- return this._lazy('_images', '_rawImages',
43
- i => i instanceof FigureImage ? i : new FigureImage(i));
44
- }
45
-
46
- get subfigures() {
47
- return this._lazy('_subfigures', '_rawSubfigures',
48
- s => s instanceof Figure ? s : new Figure(s));
49
- }
50
-
51
- findById(targetId) {
52
- if (this.id === targetId) return this;
53
- for (const sub of this.subfigures) {
54
- const found = sub.findById(targetId);
55
- if (found) return found;
56
- }
57
- return null;
58
- }
59
-
60
- allIds() {
61
- const ids = this.id != null ? [this.id] : [];
62
- return [...ids, ...this.subfigures.flatMap(s => s.allIds())];
63
- }
64
-
65
- toJSON() {
66
- const obj = super.toJSON();
67
- this._serialize(obj, 'images', '_images', '_rawImages');
68
- this._serialize(obj, 'subfigures', '_subfigures', '_rawSubfigures');
69
- return obj;
70
- }
71
-
72
- static fromJSON(data) { return new Figure(data); }
73
- }
74
-
75
- NonVerbalEntity.register('figure', Figure);
@@ -1,25 +0,0 @@
1
- import { SharedNonVerbalEntity } from './shared-non-verbal-entity.js';
2
- import { NonVerbalEntity } from './non-verbal-entity.js';
3
-
4
- export class Formula extends SharedNonVerbalEntity {
5
- constructor(data = {}) {
6
- super(data);
7
- this.expression = data.expression ?? null;
8
- this.notation = data.notation ?? null;
9
- }
10
-
11
- rdfClass() {
12
- return 'Formula';
13
- }
14
-
15
- toJSON() {
16
- const obj = super.toJSON();
17
- if (this.expression != null) obj.expression = this.expression;
18
- if (this.notation != null) obj.notation = this.notation;
19
- return obj;
20
- }
21
-
22
- static fromJSON(data) { return new Formula(data); }
23
- }
24
-
25
- NonVerbalEntity.register('formula', Formula);