Commit c80d23c1 authored by Konstantin Schulz's avatar Konstantin Schulz
Browse files

test module now can send data to backend, refactored the corpus & exercise services

parent f944ecfb
......@@ -16,7 +16,7 @@ export class AppComponent {
private translate: TranslateService,
private config: Config,
private splashScreen: SplashScreen,
public helperService: HelperService,
public helperService: HelperService
) {
platform.ready().then(() => {
// Okay, so the platform is ready and our plugins are available.
......
......@@ -5,7 +5,7 @@ import {TranslateService} from '@ngx-translate/core';
import {CorpusService} from 'src/app/corpus.service';
import {HttpClient} from '@angular/common/http';
import {HelperService} from '../helper.service';
import { ExerciseService } from '../exercise.service';
import {ExerciseService} from '../exercise.service';
/**
* Generated class for the AuthorPage page.
......@@ -27,7 +27,6 @@ export class AuthorPage {
public http: HttpClient,
public exerciseService: ExerciseService) {
this.toggleTreebankAuthors();
this.corpusService.currentCorpus = null;
this.corpusService.isTextRangeCorrect = false;
}
......@@ -57,8 +56,7 @@ export class AuthorPage {
}
restoreLastSetup() {
this.corpusService.restoreLastCorpus();
this.exerciseService.restoreLastURN().then(() => {
this.corpusService.restoreLastCorpus().then(() => {
if (HelperService.isVocabularyCheck) {
this.navCtrl.navigateForward('/vocabulary-check').then();
} else {
......@@ -67,7 +65,7 @@ export class AuthorPage {
}, () => {
});
}
showCorpora(author: Author) {
this.corpusService.currentAuthor = author;
this.navCtrl.navigateForward('/author-detail').then();
......
......@@ -7,19 +7,54 @@ import {HttpClient, HttpErrorResponse} from '@angular/common/http';
import {TranslateService} from '@ngx-translate/core';
import {ToastController} from '@ionic/angular';
import {HelperService} from 'src/app/helper.service';
import {AnnisResponse} from "src/app/models/annisResponse";
import {
CaseTranslations,
CaseValue,
DependencyTranslation,
DependencyValue, ExerciseType, ExerciseTypeTranslation, InstructionsTranslation,
PartOfSpeechTranslation,
PartOfSpeechValue,
Phenomenon
} from "src/app/models/enum";
import {NodeMC} from "src/app/models/nodeMC";
import {LinkMC} from "src/app/models/linkMC";
import {QueryMC} from "src/app/models/queryMC";
import {Exercise} from "src/app/models/exercise";
import {Feedback} from "src/app/models/feedback";
@Injectable({
providedIn: 'root'
})
export class CorpusService {
public corporaUnavailableString: string;
public annisResponse: AnnisResponse;
public availableCorpora: CorpusMC[];
public availableAuthors: Author[];
public corporaUnavailableString: string;
public currentAuthor: Author;
public currentCitations: Citation[] = [];
public currentCorpus: CorpusMC;
public currentText: string = '';
public currentTextRange: TextRange = new TextRange({start: ['', '', ''], end: ['', '', '']});
public currentCitations: Citation[] = [];
public currentUrn: string;
public exercise: Exercise = new Exercise({
type: ExerciseType.cloze,
typeTranslation: '',
queryItems: [new QueryMC({
phenomenon: Phenomenon.partOfSpeech,
values: [PartOfSpeechValue.adjective],
})],
feedback: new Feedback({general: '', incorrect: '', partiallyCorrect: '', correct: ''}),
instructionsTranslation: ''
});
public isTextRangeCorrect = false;
public phenomenonMap: {
[phenomenonName: string]: [
{ [translationsKey: string]: string },
object,
{ [specificValue: string]: number }
]
} = {};
constructor(public translate: TranslateService,
public http: HttpClient,
......@@ -27,8 +62,26 @@ export class CorpusService {
this.translate.get('ERROR_CORPORA_UNAVAILABLE').subscribe(value => this.corporaUnavailableString = value);
this.checkForUpdates().then();
if (HelperService.mostRecentSetup) {
this.restoreLastCorpus();
this.restoreLastCorpus().then();
}
this.initPhenomenonMap();
Object.keys(Phenomenon).forEach((key) => {
if (key !== Phenomenon[Phenomenon.lemma]) {
const translationObject: object = this.phenomenonMap[key][1];
Object.keys(translationObject).forEach((k) => {
if (k.toUpperCase() !== k) {
this.translate.get(translationObject[k]).subscribe(v => this.phenomenonMap[key][0][k] = v);
}
});
}
});
this.getTranslations();
}
adjustQueryValue(query: QueryMC) {
const availableValues = Object.keys(this.phenomenonMap[query.phenomenon][2]);
// when the phenomenon changes, choose a (almost) random value as the default
query.values = [availableValues[Object.keys(availableValues)[0]]];
}
async checkForUpdates() {
......@@ -71,12 +124,65 @@ export class CorpusService {
});
}
getCTStextPassage(urn: string) {
const url = HelperService.config['backendBaseUrl'] + HelperService.config['backendApiRawtextPath'];
return this.http.get(url, {params: {'urn': urn}});
}
getCTSvalidReff(urn: string) {
const config: object = HelperService.config;
const fullUrl: string = config['backendBaseUrl'] + config['backendApiValidReffPath'];
return this.http.get(fullUrl, {params: {'urn': urn}});
}
getText() {
return new Promise((resolve, reject) => {
this.currentText = '';
if (HelperService.isVocabularyCheck) {
resolve();
} else {
HelperService.currentError = null;
HelperService.isLoading = true;
this.getCTStextPassage(this.currentUrn).subscribe((ar: AnnisResponse) => {
HelperService.isLoading = false;
this.processAnnisResponse(ar);
resolve();
}, async (error: HttpErrorResponse) => {
HelperService.isLoading = false;
HelperService.currentError = error;
const toast = await this.toastCtrl.create({
message: HelperService.generalErrorAlertMessage,
duration: 3000,
position: 'top'
});
toast.present().then();
reject();
});
}
});
}
getTranslations() {
this.translate.get('EXERCISE_FEEDBACK_CORRECT_DEFAULT').subscribe(value => this.exercise.feedback.correct = value);
this.translate.get('EXERCISE_FEEDBACK_INCORRECT_DEFAULT').subscribe(value => this.exercise.feedback.incorrect = value);
this.translate.get('EXERCISE_FEEDBACK_PARTIALLY_CORRECT_DEFAULT').subscribe((value) => {
this.exercise.feedback.partiallyCorrect = value;
});
this.translate.get('EXERCISE_FEEDBACK_GENERAL_DEFAULT').subscribe(value => this.exercise.feedback.general = value);
this.translate.get(ExerciseTypeTranslation[ExerciseType.cloze]).subscribe(value => this.exercise.typeTranslation = value);
this.translate.get(InstructionsTranslation[ExerciseType.cloze]).subscribe((value) => {
this.exercise.instructionsTranslation = value;
});
}
initPhenomenonMap() {
// map the different phenomena to their respective Enum for processing and display/translation
this.phenomenonMap[Phenomenon.partOfSpeech] = [{}, PartOfSpeechTranslation, {}];
this.phenomenonMap[Phenomenon.dependency] = [{}, DependencyTranslation, {}];
this.phenomenonMap[Phenomenon.case] = [{}, CaseTranslations, {}];
this.phenomenonMap[Phenomenon.lemma] = [{}, null, {}];
}
isTreebank(corpus: CorpusMC) {
return corpus.source_urn.includes('proiel');
}
......@@ -89,6 +195,49 @@ export class CorpusService {
}
}
processAnnisResponse(ar: AnnisResponse) {
Object.keys(this.phenomenonMap).forEach(key => this.phenomenonMap[key][2] = {});
this.phenomenonMap[Phenomenon.lemma][0] = {};
ar.graph.nodes.forEach((node: NodeMC) => {
let existingValue = this.phenomenonMap[Phenomenon.lemma][2][node.udep_lemma];
this.phenomenonMap[Phenomenon.lemma][2][node.udep_lemma] = (existingValue ? existingValue : 0) + 1;
this.phenomenonMap[Phenomenon.lemma][0][node.udep_lemma] = node.udep_lemma;
if (node.udep_feats) {
const featsParts: string[] = node.udep_feats.split('|');
const casePart: string = featsParts.find(x => x.toLowerCase().includes(Phenomenon[Phenomenon.case]));
if (casePart) {
const caseAbbreviation: string = casePart.split('=')[1];
const caseValue: CaseValue = HelperService.caseMap[caseAbbreviation];
existingValue = this.phenomenonMap[Phenomenon.case][2][caseValue];
this.phenomenonMap[Phenomenon.case][2][caseValue] = (existingValue ? existingValue : 0) + 1;
}
}
const pos: PartOfSpeechValue = HelperService.partOfSpeechMap[node.udep_upostag];
existingValue = this.phenomenonMap[Phenomenon.partOfSpeech][2][pos];
this.phenomenonMap[Phenomenon.partOfSpeech][2][pos] = (existingValue ? existingValue : 0) + 1;
});
// init the display with a (almost) random value
this.exercise.queryItems[0].values = [Object.keys(this.phenomenonMap[Phenomenon.partOfSpeech][2])[0]];
const pointingLinks: LinkMC[] = ar.graph.links.filter(x => x.annis_component_type === 'Pointing');
pointingLinks.forEach((link: LinkMC) => {
const dep: DependencyValue = HelperService.dependencyMap[link.udep_deprel];
if (dep) {
const existingValue = this.phenomenonMap[Phenomenon.dependency][2][dep];
this.phenomenonMap[Phenomenon.dependency][2][dep] = (existingValue ? existingValue : 0) + 1;
}
});
// need to add root dependencies manually because they are tricky to handle
const nodeIds: string[] = ar.graph.nodes.map(x => x.id);
const nodesWithDependencySet: Set<string> = new Set<string>(pointingLinks.map(x => x.target));
const rootNodeIds: string[] = nodeIds.filter(x => !nodesWithDependencySet.has(x));
this.phenomenonMap[Phenomenon.dependency][2][DependencyValue.root] = rootNodeIds.length;
this.adjustQueryValue(this.exercise.queryItems[0]);
this.annisResponse = ar;
this.currentText = ar.graph.nodes.map(x => x.annis_tok).join(' ');
}
private processCorpora(corpusList: CorpusMC[]) {
corpusList.forEach((corpus: CorpusMC) => {
corpus.citations = {};
......@@ -127,8 +276,20 @@ export class CorpusService {
}
restoreLastCorpus() {
this.currentCorpus = HelperService.mostRecentSetup.currentCorpus;
this.currentTextRange = HelperService.mostRecentSetup.currentTextRange;
this.isTextRangeCorrect = true;
return new Promise((resolve, reject) => {
// check if the data is already present
if (this.currentUrn == HelperService.mostRecentSetup.currentUrn && this.currentCorpus == HelperService.mostRecentSetup.currentCorpus && this.currentText) {
return resolve();
}
this.currentCorpus = HelperService.mostRecentSetup.currentCorpus;
this.currentTextRange = HelperService.mostRecentSetup.currentTextRange;
this.isTextRangeCorrect = true;
this.currentUrn = HelperService.mostRecentSetup.currentUrn;
this.getText().then(() => {
return resolve();
}, () => {
return reject();
});
});
}
}
......@@ -32,7 +32,7 @@
<span class="label">
{{ 'EXERCISE_TYPE' | translate }}
</span>
<select [(ngModel)]="exerciseService.exercise.type" name="exerciseType"
<select [(ngModel)]="corpusService.exercise.type" name="exerciseType"
(change)="adjustTranslations()">
<option *ngFor="let key of ObjectKeys(ExerciseType)" [value]=ExerciseType[key]>
{{ ExerciseTypeTranslation[key] | translate }}
......@@ -41,10 +41,10 @@
</label>
</ion-col>
</ion-row>
<ion-row *ngFor="let query of exerciseService.exercise.queryItems; let i = index">
<ion-row *ngFor="let query of corpusService.exercise.queryItems; let i = index">
<ion-col>
<ion-grid [class.matching]="exerciseService.exercise.type === ExerciseType.matching">
<ion-row *ngIf="exerciseService.exercise.type === ExerciseType.matching">
<ion-grid [class.matching]="corpusService.exercise.type === ExerciseType.matching">
<ion-row *ngIf="corpusService.exercise.type === ExerciseType.matching">
<ion-col><h2>{{ (i === 0 ? 'HEAD_WORD' : 'DEPENDENT_WORD') | translate }}</h2>
</ion-col>
</ion-row>
......@@ -53,7 +53,7 @@
<label>
<span class="label">{{ 'QUERY_PHENOMENON' | translate }}</span>
<select [(ngModel)]="query.phenomenon" name="queryPhenomenon"
(change)="exerciseService.adjustQueryValue(query)">
(change)="corpusService.adjustQueryValue(query)">
<option *ngFor="let phenomenon of ObjectKeys(Phenomenon)" [value]=phenomenon>
{{ PhenomenonTranslation[phenomenon] | translate }}
</option>
......@@ -63,14 +63,14 @@
</ion-row>
<ion-row>
<ion-col>
<label *ngIf="exerciseService.exercise.type === ExerciseType.cloze; else matching">
<label *ngIf="corpusService.exercise.type === ExerciseType.cloze; else matching">
<span class="label">
{{ 'QUERY_VALUE' | translate }}
</span>
<select [(ngModel)]="query.values" name="queryValue" multiple>
<option *ngFor="let key of getSortedQueryValues(query)" [value]=key>
{{ exerciseService.phenomenonMap[query.phenomenon][0][key] + " (" +
exerciseService.phenomenonMap[query.phenomenon][2][key] + ")" }}
{{ corpusService.phenomenonMap[query.phenomenon][0][key] + " (" +
corpusService.phenomenonMap[query.phenomenon][2][key] + ")" }}
</option>
</select>
</label>
......@@ -81,8 +81,8 @@
</span>
<select [(ngModel)]="query.values[0]" name="queryValue">
<option *ngFor="let key of getSortedQueryValues(query)" [value]=key>
{{ exerciseService.phenomenonMap[query.phenomenon][0][key] + " (" +
exerciseService.phenomenonMap[query.phenomenon][2][key] + ")" }}
{{ corpusService.phenomenonMap[query.phenomenon][0][key] + " (" +
corpusService.phenomenonMap[query.phenomenon][2][key] + ")" }}
</option>
</select>
</label>
......@@ -93,13 +93,13 @@
</ion-col>
</ion-row>
<ion-row
*ngIf="exerciseService.exercise.type === ExerciseType.kwic; else notKWIC"></ion-row>
*ngIf="corpusService.exercise.type === ExerciseType.kwic; else notKWIC"></ion-row>
<ng-template #notKWIC>
<ion-row>
<ion-col>
<label>
<span class="label">{{ 'INSTRUCTIONS' | translate }}</span>
<input [(ngModel)]="exerciseService.exercise.instructionsTranslation" type="text"
<input [(ngModel)]="corpusService.exercise.instructionsTranslation" type="text"
name="instructionsTranslation"/>
</label>
</ion-col>
......@@ -122,7 +122,7 @@
<ion-col>
<label>
<span>{{ 'EXERCISE_FEEDBACK_GENERAL' | translate }}</span>
<input type="text" [(ngModel)]="exerciseService.exercise.feedback.general"
<input type="text" [(ngModel)]="corpusService.exercise.feedback.general"
name="feedbackGeneral"/>
</label>
</ion-col>
......@@ -131,7 +131,7 @@
<ion-col>
<label>
<span>{{ 'EXERCISE_FEEDBACK_CORRECT' | translate }}</span>
<input type="text" [(ngModel)]="exerciseService.exercise.feedback.correct"
<input type="text" [(ngModel)]="corpusService.exercise.feedback.correct"
name="feedbackCorrect"/>
</label>
</ion-col>
......@@ -140,7 +140,7 @@
<ion-col>
<label>
<span>{{ 'EXERCISE_FEEDBACK_PARTIALLY_CORRECT' | translate }}</span>
<input type="text" [(ngModel)]="exerciseService.exercise.feedback.partiallyCorrect"
<input type="text" [(ngModel)]="corpusService.exercise.feedback.partiallyCorrect"
name="feedbackPartiallyCorrect"/>
</label>
</ion-col>
......@@ -149,7 +149,7 @@
<ion-col>
<label>
<span>{{ 'EXERCISE_FEEDBACK_INCORRECT' | translate }}</span>
<input type="text" [(ngModel)]="exerciseService.exercise.feedback.incorrect"
<input type="text" [(ngModel)]="corpusService.exercise.feedback.incorrect"
name="feedbackIncorrect"/>
</label>
</ion-col>
......
......@@ -44,35 +44,35 @@ export class ExerciseParametersPage {
}
adjustTranslations() {
this.translateService.get(ExerciseTypeTranslation[this.exerciseService.exercise.type]).subscribe(
value => this.exerciseService.exercise.typeTranslation = value);
if ([ExerciseType.cloze, ExerciseType.matching].includes(this.exerciseService.exercise.type)) {
this.translateService.get(InstructionsTranslation[this.exerciseService.exercise.type]).subscribe(
value => this.exerciseService.exercise.instructionsTranslation = value);
this.translateService.get(ExerciseTypeTranslation[this.corpusService.exercise.type]).subscribe(
value => this.corpusService.exercise.typeTranslation = value);
if ([ExerciseType.cloze, ExerciseType.matching].includes(this.corpusService.exercise.type)) {
this.translateService.get(InstructionsTranslation[this.corpusService.exercise.type]).subscribe(
value => this.corpusService.exercise.instructionsTranslation = value);
}
if (this.exerciseService.exercise.type === ExerciseType.matching) {
this.exerciseService.exercise.queryItems = [new QueryMC({
if (this.corpusService.exercise.type === ExerciseType.matching) {
this.corpusService.exercise.queryItems = [new QueryMC({
phenomenon: Phenomenon.partOfSpeech,
values: [Object.keys(this.exerciseService.phenomenonMap[Phenomenon.partOfSpeech][2])[0]],
values: [Object.keys(this.corpusService.phenomenonMap[Phenomenon.partOfSpeech][2])[0]],
}), new QueryMC({
phenomenon: Phenomenon.partOfSpeech,
values: [Object.keys(this.exerciseService.phenomenonMap[Phenomenon.partOfSpeech][2])[0]],
values: [Object.keys(this.corpusService.phenomenonMap[Phenomenon.partOfSpeech][2])[0]],
})];
} else if (this.exerciseService.exercise.queryItems.length > 1) {
this.exerciseService.exercise.queryItems.splice(1, 1);
} else if (this.corpusService.exercise.queryItems.length > 1) {
this.corpusService.exercise.queryItems.splice(1, 1);
}
}
async generateExercise() {
const phenomenon: Phenomenon = this.exerciseService.exercise.queryItems[0].phenomenon;
if (0 < HelperService.config['maxTextLength'] && HelperService.config['maxTextLength'] < this.exerciseService.currentText.length) {
const phenomenon: Phenomenon = this.corpusService.exercise.queryItems[0].phenomenon;
if (0 < HelperService.config['maxTextLength'] && HelperService.config['maxTextLength'] < this.corpusService.currentText.length) {
const toast = await this.toastCtrl.create({
message: this.textTooLongString,
duration: 3000,
position: 'top'
});
toast.present().then();
} else if (phenomenon === Phenomenon.lemma && !this.exerciseService.exercise.queryItems[0].values) {
} else if (phenomenon === Phenomenon.lemma && !this.corpusService.exercise.queryItems[0].values) {
const toast = await this.toastCtrl.create({
message: this.emptyQueryValueString,
duration: 3000,
......@@ -80,20 +80,20 @@ export class ExerciseParametersPage {
});
toast.present().then();
} else {
this.exerciseService.annisResponse.solutions = null;
this.corpusService.annisResponse.solutions = null;
this.getExerciseData();
}
}
private getExerciseData() {
const search_values: string[] = this.exerciseService.exercise.queryItems.map(
const search_values: string[] = this.corpusService.exercise.queryItems.map(
query => query.phenomenon + '=' + query.values.join('|'));
const formData = new FormData();
formData.append('urn', this.exerciseService.currentUrn);
formData.append('urn', this.corpusService.currentUrn);
formData.append('search_values', JSON.stringify(search_values));
HelperService.currentError = null;
HelperService.isLoading = true;
if (this.exerciseService.exercise.type === ExerciseType.kwic) {
if (this.corpusService.exercise.type === ExerciseType.kwic) {
const kwic_url: string = HelperService.config['backendBaseUrl'] + HelperService.config['backendApiKwicPath'];
this.http.post(kwic_url, formData).subscribe((svgString: string) => {
HelperService.isLoading = false;
......@@ -115,20 +115,20 @@ export class ExerciseParametersPage {
const workTitle: string = this.corpusService.currentCorpus.title + ':' + this.corpusService.currentTextRange.start + '-' +
this.corpusService.currentTextRange.end;
formData.append('work_title', workTitle);
formData.append('type', MoodleExerciseType[this.exerciseService.exercise.type]);
formData.append('type_translation', this.exerciseService.exercise.typeTranslation);
formData.append('instructions', this.exerciseService.exercise.instructionsTranslation);
formData.append('correct_feedback', this.exerciseService.exercise.feedback.correct);
formData.append('partially_correct_feedback', this.exerciseService.exercise.feedback.partiallyCorrect);
formData.append('incorrect_feedback', this.exerciseService.exercise.feedback.incorrect);
formData.append('general_feedback', this.exerciseService.exercise.feedback.general);
formData.append('type', MoodleExerciseType[this.corpusService.exercise.type]);
formData.append('type_translation', this.corpusService.exercise.typeTranslation);
formData.append('instructions', this.corpusService.exercise.instructionsTranslation);
formData.append('correct_feedback', this.corpusService.exercise.feedback.correct);
formData.append('partially_correct_feedback', this.corpusService.exercise.feedback.partiallyCorrect);
formData.append('incorrect_feedback', this.corpusService.exercise.feedback.incorrect);
formData.append('general_feedback', this.corpusService.exercise.feedback.general);
formData.append('work_author', this.corpusService.currentCorpus.author);
const url = HelperService.config['backendBaseUrl'] + HelperService.config['backendApiExercisePath'];
this.http.post(url, formData).subscribe((ar: AnnisResponse) => {
HelperService.isLoading = false;
this.exerciseService.annisResponse.exercise_id = ar.exercise_id;
this.exerciseService.annisResponse.uri = ar.uri;
this.exerciseService.annisResponse.solutions = ar.solutions;
this.corpusService.annisResponse.exercise_id = ar.exercise_id;
this.corpusService.annisResponse.uri = ar.uri;
this.corpusService.annisResponse.solutions = ar.solutions;
this.navCtrl.navigateForward('preview').then();
}, async (error: HttpErrorResponse) => {
HelperService.isLoading = false;
......@@ -143,8 +143,8 @@ export class ExerciseParametersPage {
}
getSortedQueryValues(query: QueryMC) {
const targetObject: object = this.exerciseService.phenomenonMap[query.phenomenon][0];
return Object.keys(this.exerciseService.phenomenonMap[query.phenomenon][2]).sort((a, b) => {
const targetObject: object = this.corpusService.phenomenonMap[query.phenomenon][0];
return Object.keys(this.corpusService.phenomenonMap[query.phenomenon][2]).sort((a, b) => {
return a === b ? 0 : (targetObject[a] < targetObject[b] ? -1 : 1);
});
}
......
import {HttpClient, HttpErrorResponse} from '@angular/common/http';
import {HttpClient} from '@angular/common/http';
import {Injectable} from '@angular/core';
import {Exercise} from 'src/app/models/exercise';
import {
CaseTranslations,
CaseValue, DependencyTranslation,
DependencyValue,
ExerciseType,
ExerciseTypeTranslation, InstructionsTranslation, PartOfSpeechTranslation,
PartOfSpeechValue,
Phenomenon
} from 'src/app/models/enum';
import {QueryMC} from 'src/app/models/queryMC';
import {AnnisResponse} from 'src/app/models/annisResponse';
import {ToastController} from '@ionic/angular';
import {Feedback} from 'src/app/models/feedback';
import {LinkMC} from 'src/app/models/linkMC';
import {TranslateService} from '@ngx-translate/core';
import {NodeMC} from 'src/app/models/nodeMC';
import {HelperService} from 'src/app/helper.service';
@Injectable({
providedIn: 'root'
})
export class ExerciseService {
public currentText = '';
public currentUrn: string;
public exercise: Exercise = new Exercise({
type: ExerciseType.cloze,
typeTranslation: '',
queryItems: [new QueryMC({
phenomenon: Phenomenon.partOfSpeech,
values: [PartOfSpeechValue.adjective],
})],
feedback: new Feedback({general: '', incorrect: '', partiallyCorrect: '', correct: ''}),
instructionsTranslation: ''
});
public excludeOOV = false;
public annisResponse: AnnisResponse;
public kwicGraphs: string;
public phenomenonMap: {
[phenomenonName: string]: [
{ [translationsKey: string]: string },
object,
{ [specificValue: string]: number }
]
} = {};
public caseMap: { [rawValue: string]: CaseValue } = {
'Nom': CaseValue.nominative,
'Gen': CaseValue.genitive,
'Dat': CaseValue.dative,
'Acc': CaseValue.accusative,
'Abl': CaseValue.ablative,
'Voc': CaseValue.vocative,
'Loc': CaseValue.locative,
};
public dependencyMap: { [rawValue: string]: DependencyValue } = {
'acl': DependencyValue.adjectivalClause,
'advcl': DependencyValue.adverbialClauseModifier,
'advmod': DependencyValue.adverbialModifier,
'amod': DependencyValue.adjectivalModifier,
'appos': DependencyValue.appositionalModifier,
'aux': DependencyValue.auxiliary,
'aux:pass': DependencyValue.auxiliary,
'case': DependencyValue.caseMarking,
'cc': DependencyValue.coordinatingConjunction,
'ccomp': DependencyValue.clausalComplement,
'clf': DependencyValue.classifier,
'compound': DependencyValue.multiwordExpression,
'conj': DependencyValue.conjunct,
'cop': DependencyValue.copula,
'csubj': DependencyValue.subject,
'csubj:pass': DependencyValue.subject,
'det': DependencyValue.determiner,
'discourse': DependencyValue.discourseElement,
'dislocated': DependencyValue.dislocated,