├── .gitignore ├── LICENSE ├── README.md ├── backend ├── app.py ├── db.py ├── models │ ├── __init__.py │ ├── al_model.py │ └── huggingface_model.py ├── resources │ ├── __init__.py │ ├── annotation_service.py │ ├── huggingface_service.py │ └── spacy_service.py ├── script │ ├── al_benchmark.py │ ├── mongodb.ipynb │ └── mongodb.py └── test.py ├── doc ├── Introtoal.md ├── asset │ └── project_structure.jpg ├── design_doc.pdf ├── slides_final.pdf ├── slides_interim.pdf ├── slides_introtoal.pdf ├── slides_pitch.pdf └── slidev │ ├── README.md │ ├── global-bottom.vue │ ├── global-top.vue │ ├── netlify.toml │ ├── package-lock.json │ ├── package.json │ ├── public │ ├── al_performance.jpg │ ├── annotation_configuration.png │ ├── annotation_interface.png │ ├── annotation_service.jpg │ ├── annotation_setup.png │ ├── annotation_tool.jpg │ ├── disagree_1.png │ ├── disagree_2.png │ ├── disagree_3.png │ ├── final_ml_lifecycle.jpg │ ├── final_neranno.jpg │ ├── final_nerservice.jpg │ ├── label_definition.png │ ├── ml_workflow.png │ ├── ner_service.png │ ├── take_away.jpg │ ├── vector_content.png │ ├── vector_cover.png │ └── vector_thanks.png │ ├── slides default.md │ ├── slides.md │ ├── slides_archived.md │ ├── slides_interim.md │ └── vercel.json ├── frontend ├── .eslintignore ├── .eslintrc.js ├── .gitignore ├── .postcssrc.js ├── README.md ├── babel.config.js ├── dist │ └── spa │ │ ├── css │ │ ├── 365.95b382cf.css │ │ ├── 458.ee62df10.css │ │ ├── 470.abcad4da.css │ │ ├── 707.d67b164b.css │ │ ├── 839.514ae98d.css │ │ ├── app.31d6cfe0.css │ │ └── vendor.985acc40.css │ │ ├── favicon.ico │ │ ├── fonts │ │ ├── KFOkCnqEu92Fr1MmgVxIIzQ.9391e6e2.woff │ │ ├── KFOlCnqEu92Fr1MmEU9fBBc-.ddd11dab.woff │ │ ├── KFOlCnqEu92Fr1MmSU5fBBc-.877b9231.woff │ │ ├── KFOlCnqEu92Fr1MmWUlfBBc-.0344cc3c.woff │ │ ├── KFOlCnqEu92Fr1MmYUtfBBc-.b555d228.woff │ │ ├── KFOmCnqEu92Fr1Mu4mxM.9b78ea3b.woff │ │ ├── flUhRq6tzZclQEJ-Vdg-IuiaDsNa.7d512ef7.woff │ │ └── flUhRq6tzZclQEJ-Vdg-IuiaDsNcIhQ8tQ.49dcbc98.woff2 │ │ ├── icons │ │ ├── favicon-128x128.png │ │ ├── favicon-16x16.png │ │ ├── favicon-32x32.png │ │ └── favicon-96x96.png │ │ ├── index.html │ │ └── js │ │ ├── 153.981633e8.js │ │ ├── 203.64790f71.js │ │ ├── 325.5cd31c19.js │ │ ├── 365.3663b5cb.js │ │ ├── 400.d083091b.js │ │ ├── 411.a398b765.js │ │ ├── 458.5e571986.js │ │ ├── 470.5463883d.js │ │ ├── 54.be0d8d28.js │ │ ├── 707.97e80e68.js │ │ ├── 78.95a2621f.js │ │ ├── 839.6f88682d.js │ │ ├── 84.668bbfad.js │ │ ├── 846.373cbc5a.js │ │ ├── app.cec7ae74.js │ │ └── vendor.e7c9e87f.js ├── jsconfig.json ├── package-lock.json ├── package.json ├── public │ ├── favicon.ico │ └── icons │ │ ├── favicon-128x128.png │ │ ├── favicon-16x16.png │ │ ├── favicon-32x32.png │ │ └── favicon-96x96.png ├── quasar.conf.js └── src │ ├── App.vue │ ├── assets │ ├── 403.png │ ├── 404.png │ ├── 500.png │ ├── no_data.png │ ├── quasar-logo-vertical.svg │ ├── vectorHorizontal.png │ ├── vectorLogo.png │ └── vectorVertical.png │ ├── boot │ ├── .gitkeep │ └── axios.js │ ├── components │ ├── annotation │ │ └── ner │ │ │ ├── NerAnnotationRender.vue │ │ │ ├── NerConfiguration.vue │ │ │ └── TokenRender.vue │ └── service │ │ └── ner │ │ └── NerServiceRender.vue │ ├── css │ ├── app.scss │ └── quasar.variables.scss │ ├── index.template.html │ ├── layouts │ ├── MainLayout.vue │ └── UserLayout.vue │ ├── pages │ ├── Index.vue │ ├── annotation │ │ └── NerAnnotation.vue │ ├── data │ │ ├── DataDetail.vue │ │ └── DataList.vue │ ├── exception │ │ ├── 403.vue │ │ ├── 404.vue │ │ ├── 500.vue │ │ └── Error404.vue │ ├── model │ │ ├── ModelDetail.vue │ │ └── ModelList.vue │ ├── service │ │ └── NerService.vue │ └── user │ │ ├── Login.vue │ │ ├── Register.vue │ │ └── UserAuth.vue │ ├── router │ ├── index.js │ └── routes.js │ └── store │ ├── index.js │ ├── modules │ ├── annotation │ │ └── ner │ │ │ ├── actions.js │ │ │ ├── getters.js │ │ │ ├── index.js │ │ │ └── mutations.js │ └── service │ │ └── ner │ │ ├── actions.js │ │ ├── getters.js │ │ ├── index.js │ │ └── mutations.js │ └── store-flag.d.ts ├── package-lock.json └── requirement.txt /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | 3 | /backend/log 4 | /backend/tmp 5 | 6 | env/ 7 | __pycache__/ 8 | .ipynb_checkpoints -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 Vector Institute 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. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # DANER 2 | Data Annotation Tool for Named Entity Recognition (DANER) using Active Learning and Transfer Learning. For a quick overview of the project, see [slides](./doc/slides_final.pdf). For more details, see [design_doc](./doc/design_doc.pdf). 3 | 4 | Disclaimer: This project is a demo rather than a fully functional product. We may or not continue this project in the future. 5 | 6 | # Reproducing 7 | 8 | ## Environment 9 | - Backend: Make sure you have all the packages as listed in `requirement.txt`, otherwise you may want to install them using the following command. 10 | 11 | ```bash 12 | # Run at the project root 13 | python -m venv env 14 | source env/bin/activate 15 | pip install -r requirement.txt 16 | ``` 17 | - Frontend: Not necessary. But if you want to build the frontend yourself, you need to install the package using the following command. 18 | 19 | ```bash 20 | cd ./frontend 21 | npm install 22 | ``` 23 | 24 | ## Run DANER 25 | - Run DANER on local machine. 26 | - Run Backend: `python ./backend/app.py` 27 | - Run Frontend 28 | - Method 1: Run directly: Open `./frontend/dist/spa/index.html` in Browser. 29 | - Method 2: Build and Run: Build the frontend: `quasar build` and Method 1. 30 | - Method 3: Run in development mode: `quasar dev`. 31 | 32 | - Run DANER on cluster 33 | - Run Backend on cluster: 34 | - `srun --mem=16G -c 4 --gres=gpu:1 -p interactive --qos=nopreemption --pty bash` 35 | - `python ./backend/app.py` 36 | - Setup Vector [VPN](https://support.vectorinstitute.ai/Vaughan_SSL_VPN_and_JupyterHub) 37 | - Run Frontend in the same way as above. 38 | 39 | - Note 40 | - You may need to modify the baseURL in the GUI. 41 | 42 | # Project Structure 43 | We provide the following figure to better understanding of the project structure and modify the conresponding code to satisfy your personal needs. 44 | 45 | ![project_structure](./doc/asset/project_structure.jpg) -------------------------------------------------------------------------------- /backend/app.py: -------------------------------------------------------------------------------- 1 | from flask import Flask 2 | from flask_restful import Api 3 | from flask_cors import CORS 4 | 5 | # from db import db 6 | 7 | from resources.spacy_service import SpacyService 8 | # from resources.huggingface_service import HuggingFaceService 9 | from resources.annotation_service import AnnotationService, AnnotationServiceScratch 10 | 11 | 12 | app = Flask(__name__) 13 | app.config['MONGOALCHEMY_DATABASE'] = 'myDatabase' 14 | app.config['PROPAGATE_EXCEPTIONS'] = True 15 | app.secret_key = 'neraBackend' 16 | CORS(app, resources={r"/*": {"origins": "*"}}) 17 | api = Api(app) 18 | 19 | 20 | api.add_resource(SpacyService, "/spacy") 21 | # api.add_resource(HuggingFaceService, "/huggingface") 22 | api.add_resource(AnnotationService, "/annotation") 23 | api.add_resource(AnnotationServiceScratch, "/annotation_scratch") 24 | 25 | 26 | if __name__ == '__main__': 27 | # We plan to use database at first, but it turns out to be unnecessary 28 | # db.init_app(app) 29 | app.run(host="0.0.0.0", port=5000, debug=True) 30 | -------------------------------------------------------------------------------- /backend/db.py: -------------------------------------------------------------------------------- 1 | from flask_mongoalchemy import MongoAlchemy 2 | 3 | db = MongoAlchemy() 4 | -------------------------------------------------------------------------------- /backend/models/__init__.py: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /backend/models/huggingface_model.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | from copy import deepcopy 3 | 4 | import spacy 5 | import torch 6 | 7 | use_cuda = torch.cuda.is_available() 8 | DEFAULT_LABEL = ['O', 'B-PER', 'I-PER', 'B-ORG', 9 | 'I-ORG', 'B-LOC', 'I-LOC', 'B-MISC', 'I-MISC'] 10 | BIO_MAP = { 11 | "B": 3, 12 | "I": 1, 13 | "O": 2 14 | } 15 | 16 | nlp = spacy.load("en_core_web_sm") 17 | 18 | 19 | class HFModel(): 20 | def __init__(self, tokenizer, model, label_list=DEFAULT_LABEL): 21 | self.label_list = label_list 22 | self.tokenizer = tokenizer 23 | self.model = model 24 | self.init_weights = deepcopy(self.model.state_dict()) 25 | 26 | if use_cuda: 27 | self.model.cuda() 28 | 29 | def tokenize(self, s): 30 | # Make the tokenization consistent with spacy 31 | if not isinstance(s, List): 32 | ls = [t.text for t in nlp(s) if t.text.strip()] 33 | merge = [(i-1, i+2) 34 | for i, s in enumerate(ls) if i >= 1 and s == '-'] 35 | for t in merge[::-1]: 36 | merged = ''.join(ls[t[0]:t[1]]) 37 | ls[t[0]:t[1]] = [merged] 38 | text = ls 39 | else: 40 | text = s 41 | 42 | # text is a list of raw tokens. 43 | # Get Input to the transformer model and maitain the information about subtoken 44 | inp = self.tokenizer(text, return_tensors="pt", 45 | is_split_into_words=True) 46 | word_ids = inp.word_ids(batch_index=0) 47 | 48 | if use_cuda: 49 | inp = {k: v.to('cuda') for k, v in inp.items()} 50 | 51 | return text, inp, word_ids 52 | 53 | def postprocess(self, text, word_ids, predictions, confidence=0.2): 54 | res = [] 55 | previous_word_idx = None 56 | for word_idx, prediction in zip(word_ids, predictions[0]): 57 | if word_idx is None: 58 | continue 59 | elif word_idx != previous_word_idx: 60 | pred = prediction.argmax(-1).numpy() 61 | if pred != 0: 62 | if prediction[pred] < confidence: 63 | pred = 0 64 | cur_label = self.label_list[pred] 65 | res.append({"token": text[word_idx], "label": "null" if pred == 66 | 0 else cur_label[2:], "iob": BIO_MAP[cur_label[0]]}) 67 | previous_word_idx = word_idx 68 | 69 | return res 70 | 71 | def predict(self, text, confidence=0.2): 72 | # Does not support batch prediction, text can be string or token list 73 | text, inp, word_ids = self.tokenize(text) 74 | pred = self.model(**inp).logits.softmax(-1).cpu() 75 | res = self.postprocess(text, word_ids, pred, confidence=confidence) 76 | return res 77 | -------------------------------------------------------------------------------- /backend/resources/__init__.py: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /backend/resources/annotation_service.py: -------------------------------------------------------------------------------- 1 | from flask_restful import Resource, reqparse 2 | 3 | from models.al_model import ALEngine 4 | 5 | 6 | class AnnotationService(Resource): 7 | parser = reqparse.RequestParser() 8 | parser.add_argument("index", type=int, help="Data Index", required=True) 9 | parser.add_argument("label", type=str, help="label", required=True) 10 | parser.add_argument("annotator", type=str, help="annotator", required=True) 11 | 12 | al_engine = ALEngine( 13 | "elastic/distilbert-base-uncased-finetuned-conll03-english") 14 | 15 | def get(self): 16 | """Get entities for displaCy ENT visualizer.""" 17 | 18 | index, res = self.al_engine.next2label() 19 | 20 | return {"ents": res, "index": index}, 200 21 | 22 | def put(self): 23 | args = AnnotationService.parser.parse_args() 24 | self.al_engine.update_dataset(args.index, args.label, args.annotator) 25 | 26 | return {"index": args.index}, 201 27 | 28 | 29 | class AnnotationServiceScratch(Resource): 30 | parser = reqparse.RequestParser() 31 | parser.add_argument("index", type=int, help="Data Index", required=True) 32 | parser.add_argument("label", type=str, help="label", required=True) 33 | parser.add_argument("annotator", type=str, help="annotator", required=True) 34 | 35 | al_engine = ALEngine('distilbert-base-uncased', need_train=True) 36 | 37 | def get(self): 38 | """Get entities for displaCy ENT visualizer.""" 39 | 40 | index, res = self.al_engine.next2label() 41 | 42 | return {"ents": res, "index": index}, 200 43 | 44 | def put(self): 45 | args = AnnotationService.parser.parse_args() 46 | print(args.index, args.label, args.annotator) 47 | self.al_engine.update_dataset(args.index, args.label, args.annotator) 48 | 49 | return {"index": args.index}, 201 50 | -------------------------------------------------------------------------------- /backend/resources/huggingface_service.py: -------------------------------------------------------------------------------- 1 | from flask_restful import Resource, reqparse 2 | 3 | from transformers import AutoTokenizer, AutoModelForTokenClassification 4 | 5 | from models.huggingface_model import HFModel 6 | 7 | label_list = ['O', 'B-PER', 'I-PER', 'B-ORG', 8 | 'I-ORG', 'B-LOC', 'I-LOC', 'B-MISC', 'I-MISC'] 9 | 10 | 11 | class HuggingFaceService(Resource): 12 | parser = reqparse.RequestParser() 13 | parser.add_argument("text", type=str, help="Text", required=True) 14 | parser.add_argument("model", type=str, help="Model", required=True) 15 | parser.add_argument("mode", type=str, help="Mode", required=True) 16 | 17 | print("Loading...") 18 | hf_tokenizer = AutoTokenizer.from_pretrained('distilbert-base-uncased') 19 | hf_model = AutoModelForTokenClassification.from_pretrained( 20 | 'distilbert-base-uncased', num_labels=len(label_list)) 21 | model = HFModel(hf_tokenizer, hf_model, label_list) 22 | print("Loaded!") 23 | 24 | def put(self): 25 | """Get entities for displaCy ENT visualizer.""" 26 | 27 | args = HuggingFaceService.parser.parse_args() 28 | res = self.model.predict(args.text) 29 | 30 | return {"text": args.text, "ents": res}, 201 31 | -------------------------------------------------------------------------------- /backend/resources/spacy_service.py: -------------------------------------------------------------------------------- 1 | import spacy 2 | from flask_restful import Resource, reqparse 3 | 4 | 5 | class SpacyService(Resource): 6 | parser = reqparse.RequestParser() 7 | parser.add_argument("text", type=str, help="Text", required=True) 8 | parser.add_argument("model", type=str, help="Model", required=True) 9 | parser.add_argument("mode", type=str, help="Mode", required=True) 10 | 11 | print("Loading...") 12 | MODELS = { 13 | "en_core_web_sm": spacy.load("en_core_web_sm"), 14 | # "en_core_web_md": spacy.load("en_core_web_md"), 15 | # "en_core_web_lg": spacy.load("en_core_web_lg"), 16 | # "en_core_web_trf": spacy.load("en_core_web_trf"), 17 | } 18 | 19 | print("Loaded!") 20 | 21 | def put(self): 22 | """Get entities for displaCy ENT visualizer.""" 23 | 24 | args = SpacyService.parser.parse_args() 25 | nlp = self.MODELS[args.model] 26 | 27 | print(args.text) 28 | 29 | doc = nlp(args.text) 30 | if args.mode == 'char': 31 | res = [{"token": ent.text, "start": ent.start_char, "end": ent.end_char, "label": ent.label_} 32 | for ent in doc.ents] 33 | elif args.mode == 'token': 34 | res = [{"token": token.text, "label": token.ent_type_ if token.ent_type_ else 'null', "iob": token.ent_iob} 35 | for token in doc] 36 | 37 | return {"text": doc.text, "ents": res}, 201 38 | -------------------------------------------------------------------------------- /backend/script/al_benchmark.py: -------------------------------------------------------------------------------- 1 | import types 2 | import sys 3 | from copy import deepcopy, copy 4 | from collections import defaultdict 5 | 6 | import json 7 | import scipy 8 | import numpy as np 9 | 10 | import torch 11 | import transformers 12 | 13 | from datasets import load_dataset, load_metric 14 | from transformers import DataCollatorForTokenClassification 15 | from transformers import AutoTokenizer, AutoModelForTokenClassification, TrainingArguments 16 | 17 | 18 | import baal 19 | from baal.active.active_loop import ActiveLearningLoop 20 | from baal.active.dataset import ActiveLearningDataset, ActiveLearningPool 21 | from baal.transformers_trainer_wrapper import BaalTransformersTrainer 22 | from baal.active.heuristics.heuristics import AbstractHeuristic 23 | 24 | use_cuda = torch.cuda.is_available() 25 | 26 | print(use_cuda) 27 | print(transformers.__version__) 28 | print(torch.__version__) 29 | print(baal.__version__) 30 | 31 | 32 | def get_tokenized_dataset(tokenizer): 33 | datasets = load_dataset("conll2003") 34 | label_all_tokens = True 35 | 36 | def tokenize_and_align_labels(examples): 37 | tokenized_inputs = tokenizer( 38 | examples["tokens"], truncation=True, is_split_into_words=True) 39 | 40 | labels = [] 41 | for i, label in enumerate(examples["ner_tags"]): 42 | word_ids = tokenized_inputs.word_ids(batch_index=i) 43 | previous_word_idx = None 44 | label_ids = [] 45 | for word_idx in word_ids: 46 | # Special tokens have a word id that is None. We set the label to -100 so they are automatically 47 | # ignored in the loss function. 48 | if word_idx is None: 49 | label_ids.append(-100) 50 | # We set the label for the first token of each word. 51 | elif word_idx != previous_word_idx: 52 | label_ids.append(label[word_idx]) 53 | # For the other tokens in a word, we set the label to either the current label or -100, depending on 54 | # the label_all_tokens flag. 55 | else: 56 | label_ids.append( 57 | label[word_idx] if label_all_tokens else -100) 58 | previous_word_idx = word_idx 59 | 60 | labels.append(label_ids) 61 | 62 | tokenized_inputs["labels"] = labels 63 | return tokenized_inputs 64 | 65 | tokenized_datasets = datasets.map(tokenize_and_align_labels, batched=True) 66 | tokenized_datasets.set_format( 67 | columns=['input_ids', 'attention_mask', 'labels']) 68 | return tokenized_datasets 69 | 70 | 71 | def compute_metrics(p, details=False): 72 | predictions, labels = p 73 | predictions = np.argmax(predictions, axis=2) 74 | 75 | # Remove ignored index (special tokens) 76 | true_predictions = [ 77 | [label_list[p] for (p, l) in zip(prediction, label) if l != -100] 78 | for prediction, label in zip(predictions, labels) 79 | ] 80 | true_labels = [ 81 | [label_list[l] for (p, l) in zip(prediction, label) if l != -100] 82 | for prediction, label in zip(predictions, labels) 83 | ] 84 | 85 | results = metric.compute( 86 | predictions=true_predictions, references=true_labels) 87 | 88 | if details: 89 | return results 90 | else: 91 | return { 92 | "precision": results["overall_precision"], 93 | "recall": results["overall_recall"], 94 | "f1": results["overall_f1"], 95 | "accuracy": results["overall_accuracy"], 96 | } 97 | 98 | 99 | class HuggingFaceActiveLearningDataset(ActiveLearningDataset): 100 | @property 101 | def pool(self): 102 | """Returns a new Dataset made from unlabelled samples. 103 | Raises: 104 | ValueError if a pool specific attribute cannot be set. 105 | """ 106 | pool_dataset = copy(self._dataset) 107 | 108 | for attr, new_val in self.pool_specifics.items(): 109 | if hasattr(pool_dataset, attr): 110 | setattr(pool_dataset, attr, new_val) 111 | else: 112 | raise ValueError(f"{pool_dataset} doesn't have {attr}") 113 | 114 | pool_dataset = pool_dataset.select( 115 | (~self.labelled).nonzero()[0].reshape([-1])) 116 | ald = ActiveLearningPool( 117 | pool_dataset, make_unlabelled=self.make_unlabelled) 118 | return ald 119 | 120 | 121 | class TokenALActiveLearningLoop(ActiveLearningLoop): 122 | """Object that perform the active learning iteration. 123 | Args: 124 | dataset (ActiveLearningDataset): Dataset with some sample already labelled. 125 | get_probabilities (Function): Dataset -> **kwargs -> 126 | ndarray [n_samples, n_outputs, n_iterations]. 127 | heuristic (Heuristic): Heuristic from baal.active.heuristics. 128 | ndata_to_label (int): Number of sample to label per step. 129 | max_sample (int): Limit the number of sample used (-1 is no limit). 130 | **kwargs: Parameters forwarded to `get_probabilities`. 131 | """ 132 | 133 | def step(self, pool=None) -> bool: 134 | """ 135 | Perform an active learning step. 136 | Args: 137 | pool (iterable): dataset pool indices. 138 | Returns: 139 | boolean, Flag indicating if we continue training. 140 | """ 141 | # High to low 142 | if pool is None: 143 | pool = self.dataset.pool 144 | if len(pool) > 0: 145 | # Limit number of samples 146 | if self.max_sample != -1 and self.max_sample < len(pool): 147 | indices = np.random.choice( 148 | len(pool), self.max_sample, replace=False) 149 | pool = pool.select(pool, indices) 150 | else: 151 | indices = np.arange(len(pool)) 152 | else: 153 | indices = None 154 | 155 | if len(pool) > 0: 156 | probs = self.get_probabilities(pool, **self.kwargs) 157 | if probs is not None and (isinstance(probs, types.GeneratorType) or len(probs) > 0): 158 | to_label = self.heuristic(probs) 159 | if indices is not None: 160 | to_label = indices[np.array(to_label)] 161 | if len(to_label) > 0: 162 | self.dataset.label(to_label[: self.ndata_to_label]) 163 | return True 164 | return False 165 | 166 | 167 | class TokenALTransformersTrainer(BaalTransformersTrainer): 168 | def predict_on_dataset(self, 169 | dataset, 170 | iterations: int = 1, 171 | half: bool = False, 172 | ignore_keys=None): 173 | """ 174 | Use the model to predict on a dataset `iterations` time. 175 | Args: 176 | dataset (Dataset): Dataset to predict on. 177 | iterations (int): Number of iterations per sample. 178 | half (bool): If True use half precision. 179 | ignore_keys (Optional[List[str]]): A list of keys in the output of your model 180 | (if it is a dictionary) that should be ignored when gathering predictions. 181 | Notes: 182 | The "batch" is made of `batch_size` * `iterations` samples. 183 | Returns: 184 | Array [n_samples, n_outputs, ..., n_iterations]. 185 | """ 186 | preds = list(self.predict_on_dataset_generator(dataset=dataset, 187 | iterations=iterations, 188 | half=half, 189 | ignore_keys=ignore_keys)) 190 | 191 | seq_lens = [len(ex['attention_mask']) for ex in dataset] 192 | idx = 0 193 | probs = [] 194 | 195 | for pred in preds: 196 | pred = scipy.special.softmax(pred.squeeze(-1), axis=-1) 197 | for i in range(pred.shape[0]): 198 | seq_len = seq_lens[idx+i] 199 | probs.append(pred[i][:seq_len]) 200 | idx += pred.shape[0] 201 | return probs 202 | 203 | 204 | class MNLP(AbstractHeuristic): 205 | """ 206 | Sort by the highest acquisition function value. 207 | Args: 208 | shuffle_prop (float): Amount of noise to put in the ranking. Helps with selection bias 209 | (default: 0.0). 210 | reduction (Union[str, callable]): function that aggregates the results 211 | (default: 'none`). 212 | References: 213 | https://arxiv.org/abs/1703.02910 214 | """ 215 | 216 | def __init__(self, shuffle_prop=0.0, reduction='none'): 217 | super().__init__( 218 | shuffle_prop=shuffle_prop, reverse=False, reduction=reduction 219 | ) 220 | 221 | def get_ranks(self, predictions): 222 | """ 223 | Compute the score according to the heuristic. 224 | Args: 225 | predictions (ndarray): Array of predictions 226 | Returns: 227 | Array of scores. 228 | """ 229 | scores = [] 230 | for pred in predictions: 231 | scores.append(np.mean(np.log(pred.max(-1)))) 232 | 233 | scores = np.array(scores) 234 | 235 | return self.reorder_indices(scores) 236 | 237 | 238 | class Margin(AbstractHeuristic): 239 | """ 240 | Sort by the highest acquisition function value. 241 | Args: 242 | shuffle_prop (float): Amount of noise to put in the ranking. Helps with selection bias 243 | (default: 0.0). 244 | reduction (Union[str, callable]): function that aggregates the results 245 | (default: 'none`). 246 | References: 247 | https://arxiv.org/abs/1703.02910 248 | """ 249 | 250 | def __init__(self, shuffle_prop=0.0, reduction='none'): 251 | super().__init__( 252 | shuffle_prop=shuffle_prop, reverse=False, reduction=reduction 253 | ) 254 | 255 | def get_ranks(self, predictions): 256 | """ 257 | Compute the score according to the heuristic. 258 | Args: 259 | predictions (ndarray): Array of predictions 260 | Returns: 261 | Array of scores. 262 | """ 263 | scores = [] 264 | for pred in predictions: 265 | scores.append(np.mean(np.log(pred.max(-1)))) 266 | # Todo 267 | 268 | scores = np.array(scores) 269 | 270 | return self.reorder_indices(scores) 271 | 272 | 273 | if __name__ == "__main__": 274 | output_dir = "random" 275 | 276 | tokenizer = AutoTokenizer.from_pretrained('distilbert-base-uncased') 277 | assert isinstance(tokenizer, transformers.PreTrainedTokenizerFast) 278 | tokenized_datasets = get_tokenized_dataset(tokenizer) 279 | label_list = tokenized_datasets["train"].features["ner_tags"].feature.names 280 | 281 | model = AutoModelForTokenClassification.from_pretrained( 282 | 'distilbert-base-uncased', num_labels=len(label_list)) 283 | data_collator = DataCollatorForTokenClassification(tokenizer) 284 | metric = load_metric("seqeval") 285 | heuristic = MNLP(shuffle_prop=0.2) 286 | 287 | if use_cuda: 288 | model.cuda() 289 | init_weights = deepcopy(model.state_dict()) 290 | 291 | active_set = HuggingFaceActiveLearningDataset(tokenized_datasets["train"]) 292 | active_set.label_randomly(250) 293 | 294 | # Initialization for the huggingface trainer 295 | training_args = TrainingArguments( 296 | output_dir='./{}'.format(output_dir), # output directory 297 | max_steps=10, # total # of training steps per AL step 298 | per_device_train_batch_size=32, # batch size per device during training 299 | per_device_eval_batch_size=64, # batch size for evaluation 300 | weight_decay=0.01, # strength of weight decay 301 | logging_dir='./{}'.format(output_dir), # directory for storing logs 302 | ) 303 | 304 | # create the trainer through Baal Wrapper 305 | baal_trainer = TokenALTransformersTrainer(model=model, 306 | args=training_args, 307 | train_dataset=active_set, 308 | tokenizer=tokenizer, 309 | eval_dataset=tokenized_datasets["validation"], 310 | data_collator=data_collator, 311 | compute_metrics=compute_metrics) 312 | 313 | active_loop = TokenALActiveLearningLoop(active_set, 314 | baal_trainer.predict_on_dataset, 315 | heuristic, 250, iterations=1) 316 | 317 | res_dict = defaultdict(list) 318 | res = baal_trainer.evaluate(tokenized_datasets["test"]) 319 | for k, v in res.items(): 320 | res_dict[k].append(v) 321 | res_dict["train_num"].append(len(active_set)) 322 | 323 | res_file = "al_mnlp_250_sh0.2.json" 324 | 325 | with open(res_file, 'w') as jsonfile: 326 | json.dump(res_dict, jsonfile) 327 | 328 | for epoch in range(3): 329 | baal_trainer.train() 330 | res = baal_trainer.evaluate(tokenized_datasets["test"]) 331 | for k, v in res.items(): 332 | res_dict[k].append(v) 333 | res_dict["train_num"].append(len(active_set)) 334 | with open(res_file, 'w') as jsonfile: 335 | json.dump(res_dict, jsonfile) 336 | 337 | print(res_dict) 338 | sys.stdout.flush() 339 | 340 | # active_set.label_randomly(250) 341 | should_continue = active_loop.step() 342 | 343 | # We reset the model weights to relearn from the new train set. 344 | if not should_continue: 345 | break 346 | 347 | baal_trainer.load_state_dict(init_weights) 348 | baal_trainer.lr_scheduler = None 349 | -------------------------------------------------------------------------------- /backend/script/mongodb.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": 1, 6 | "id": "9f8d6f3c-e048-4485-94c8-9e3c4a3bd663", 7 | "metadata": {}, 8 | "outputs": [], 9 | "source": [ 10 | "import hashlib\n", 11 | "import spacy\n", 12 | "from test import User, Dataset, TextExample\n", 13 | "\n", 14 | "nlp = spacy.load(\"en_core_web_sm\")" 15 | ] 16 | }, 17 | { 18 | "cell_type": "code", 19 | "execution_count": 2, 20 | "id": "5991d25a-49ca-4f7d-b990-b0ac169744d6", 21 | "metadata": {}, 22 | "outputs": [], 23 | "source": [ 24 | "luke = User(username='luke',password='122224').save()\n", 25 | "dataset = Dataset(name='testData',created_by=luke).save()\n", 26 | "\n", 27 | "t=\"First look at the new MacBook Pro\"" 28 | ] 29 | }, 30 | { 31 | "cell_type": "code", 32 | "execution_count": 3, 33 | "id": "564d88e2-e90f-4261-8eb8-2cb8f5e0b603", 34 | "metadata": {}, 35 | "outputs": [], 36 | "source": [ 37 | "example = TextExample(text=t,dataset=dataset).save()" 38 | ] 39 | }, 40 | { 41 | "cell_type": "code", 42 | "execution_count": 4, 43 | "id": "6b2f8052-650b-471f-aead-20b57cd77fd0", 44 | "metadata": {}, 45 | "outputs": [], 46 | "source": [ 47 | "doc = nlp(t)" 48 | ] 49 | }, 50 | { 51 | "cell_type": "code", 52 | "execution_count": 5, 53 | "id": "20a5bf93-37bc-4bdf-b1d3-a84ca4dd255a", 54 | "metadata": {}, 55 | "outputs": [ 56 | { 57 | "data": { 58 | "text/plain": [ 59 | "" 60 | ] 61 | }, 62 | "execution_count": 5, 63 | "metadata": {}, 64 | "output_type": "execute_result" 65 | } 66 | ], 67 | "source": [ 68 | "nlp.vocab" 69 | ] 70 | } 71 | ], 72 | "metadata": { 73 | "kernelspec": { 74 | "display_name": "Python 3", 75 | "language": "python", 76 | "name": "python3" 77 | }, 78 | "language_info": { 79 | "codemirror_mode": { 80 | "name": "ipython", 81 | "version": 3 82 | }, 83 | "file_extension": ".py", 84 | "mimetype": "text/x-python", 85 | "name": "python", 86 | "nbconvert_exporter": "python", 87 | "pygments_lexer": "ipython3", 88 | "version": "3.8.10" 89 | } 90 | }, 91 | "nbformat": 4, 92 | "nbformat_minor": 5 93 | } 94 | -------------------------------------------------------------------------------- /backend/script/mongodb.py: -------------------------------------------------------------------------------- 1 | import mongoengine as db 2 | 3 | db.connect(host="mongodb://127.0.0.1:27017/nera_db") 4 | 5 | ANNOTATION_QUALITY = (('H', 'High'), ('M', 'Medium'), ('L', 'Low')) 6 | 7 | 8 | class User(db.Document): 9 | username = db.StringField(max_length=30, required=True, unique=True) 10 | password = db.StringField(default='', max_length=30) 11 | created_at = db.DateTimeField(auto_now_add=True) 12 | 13 | 14 | class Dataset(db.Document): 15 | name = db.StringField(max_length=30, required=True, unique=True) 16 | length = db.IntField(default=0) 17 | created_by = db.ReferenceField(User) 18 | created_at = db.DateTimeField(auto_now_add=True) 19 | 20 | 21 | class Example(db.Document): 22 | # Delete all examples when the dataset is deleted 23 | dataset = db.ReferenceField(Dataset, reverse_delete_rule=db.CASCADE) 24 | hash = db.StringField(max_length=256, unique=True) 25 | 26 | meta = {'allow_inheritance': True} 27 | 28 | 29 | class Token(db.EmbeddedDocument): 30 | id = db.IntField(required=True) 31 | text = db.StringField(required=True, max_length=30) 32 | start = db.IntField(required=True) 33 | end = db.IntField(required=True) 34 | 35 | 36 | class Span(db.EmbeddedDocument): 37 | id = db.IntField(required=True) 38 | text = db.StringField(required=True, max_length=30) 39 | start = db.IntField(required=True) 40 | end = db.IntField(required=True) 41 | token_start = db.IntField(required=True) 42 | token_end = db.IntField(required=True) 43 | label = db.StringField(required=True, max_length=30) 44 | 45 | 46 | class Annotation(db.EmbeddedDocument): 47 | id = db.IntField(required=True) 48 | quality = db.StringField( 49 | required=True, choices=ANNOTATION_QUALITY, max_length=30) 50 | annotator = db.ReferenceField(User) 51 | spans = db.EmbeddedDocumentListField(Span) 52 | 53 | 54 | class TextExample(Example): 55 | text = db.StringField(required=True) 56 | tokens = db.EmbeddedDocumentListField(Token) 57 | annotations = db.EmbeddedDocumentListField(Annotation) 58 | prediction = db.EmbeddedDocumentField(Annotation) 59 | 60 | meta = { 61 | # 100000 Examples, 20 MB 62 | 'max_documents': 100000, 63 | 'max_size': 20000000, 64 | 'indexes': [ 65 | {'fields': ['$text'], 66 | 'default_language': 'english', 67 | 'weights': {'text': 10}} 68 | ] 69 | } 70 | -------------------------------------------------------------------------------- /backend/test.py: -------------------------------------------------------------------------------- 1 | import requests 2 | 3 | BASE = "http://172.17.8.59:5000/" 4 | 5 | text1 = "Geoffrey Everest Hinton (born 6 December 1947) is a British-Canadian cognitive psychologist and computer scientist, most noted for his work on artificial neural networks." 6 | response = requests.put(BASE + "spacy", {'model': 'en_core_web_sm', 7 | 'text': [text1], 8 | 'mode': 'token'}) 9 | res = response.json() 10 | print(res) 11 | 12 | response = requests.put(BASE + "spacy", {'model': 'en_core_web_sm', 13 | 'text': [text1], 14 | 'mode': 'char'}) 15 | res = response.json() 16 | 17 | print(res) 18 | -------------------------------------------------------------------------------- /doc/asset/project_structure.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VectorInstitute/DANER/2b5feadda6c1d35ab7be09277339c490396bc49e/doc/asset/project_structure.jpg -------------------------------------------------------------------------------- /doc/design_doc.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VectorInstitute/DANER/2b5feadda6c1d35ab7be09277339c490396bc49e/doc/design_doc.pdf -------------------------------------------------------------------------------- /doc/slides_final.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VectorInstitute/DANER/2b5feadda6c1d35ab7be09277339c490396bc49e/doc/slides_final.pdf -------------------------------------------------------------------------------- /doc/slides_interim.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VectorInstitute/DANER/2b5feadda6c1d35ab7be09277339c490396bc49e/doc/slides_interim.pdf -------------------------------------------------------------------------------- /doc/slides_introtoal.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VectorInstitute/DANER/2b5feadda6c1d35ab7be09277339c490396bc49e/doc/slides_introtoal.pdf -------------------------------------------------------------------------------- /doc/slides_pitch.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VectorInstitute/DANER/2b5feadda6c1d35ab7be09277339c490396bc49e/doc/slides_pitch.pdf -------------------------------------------------------------------------------- /doc/slidev/README.md: -------------------------------------------------------------------------------- 1 | # Welcome to [Slidev](https://github.com/slidevjs/slidev)! 2 | 3 | To start the slide show: 4 | 5 | - `npm install` 6 | - `npm run dev` 7 | - visit http://localhost:3030 8 | 9 | Edit the [slides.md](./slides.md) to see the changes. 10 | 11 | Learn more about Slidev on [documentations](https://sli.dev/). 12 | -------------------------------------------------------------------------------- /doc/slidev/global-bottom.vue: -------------------------------------------------------------------------------- 1 | 24 | 25 | -------------------------------------------------------------------------------- /doc/slidev/global-top.vue: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /doc/slidev/netlify.toml: -------------------------------------------------------------------------------- 1 | [build.environment] 2 | NODE_VERSION = "14" 3 | 4 | [build] 5 | publish = "dist" 6 | command = "npm run build" 7 | 8 | [[redirects]] 9 | from = "/*" 10 | to = "/index.html" 11 | status = 200 12 | -------------------------------------------------------------------------------- /doc/slidev/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "private": true, 3 | "scripts": { 4 | "dev": "slidev --open", 5 | "build": "slidev build", 6 | "export": "slidev export" 7 | }, 8 | "dependencies": { 9 | "@slidev/cli": "^0.22.1", 10 | "@slidev/theme-default": "*", 11 | "@slidev/theme-seriph": "*" 12 | }, 13 | "name": "interim", 14 | "devDependencies": { 15 | "playwright-chromium": "^1.14.0" 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /doc/slidev/public/al_performance.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VectorInstitute/DANER/2b5feadda6c1d35ab7be09277339c490396bc49e/doc/slidev/public/al_performance.jpg -------------------------------------------------------------------------------- /doc/slidev/public/annotation_configuration.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VectorInstitute/DANER/2b5feadda6c1d35ab7be09277339c490396bc49e/doc/slidev/public/annotation_configuration.png -------------------------------------------------------------------------------- /doc/slidev/public/annotation_interface.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VectorInstitute/DANER/2b5feadda6c1d35ab7be09277339c490396bc49e/doc/slidev/public/annotation_interface.png -------------------------------------------------------------------------------- /doc/slidev/public/annotation_service.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VectorInstitute/DANER/2b5feadda6c1d35ab7be09277339c490396bc49e/doc/slidev/public/annotation_service.jpg -------------------------------------------------------------------------------- /doc/slidev/public/annotation_setup.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VectorInstitute/DANER/2b5feadda6c1d35ab7be09277339c490396bc49e/doc/slidev/public/annotation_setup.png -------------------------------------------------------------------------------- /doc/slidev/public/annotation_tool.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VectorInstitute/DANER/2b5feadda6c1d35ab7be09277339c490396bc49e/doc/slidev/public/annotation_tool.jpg -------------------------------------------------------------------------------- /doc/slidev/public/disagree_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VectorInstitute/DANER/2b5feadda6c1d35ab7be09277339c490396bc49e/doc/slidev/public/disagree_1.png -------------------------------------------------------------------------------- /doc/slidev/public/disagree_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VectorInstitute/DANER/2b5feadda6c1d35ab7be09277339c490396bc49e/doc/slidev/public/disagree_2.png -------------------------------------------------------------------------------- /doc/slidev/public/disagree_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VectorInstitute/DANER/2b5feadda6c1d35ab7be09277339c490396bc49e/doc/slidev/public/disagree_3.png -------------------------------------------------------------------------------- /doc/slidev/public/final_ml_lifecycle.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VectorInstitute/DANER/2b5feadda6c1d35ab7be09277339c490396bc49e/doc/slidev/public/final_ml_lifecycle.jpg -------------------------------------------------------------------------------- /doc/slidev/public/final_neranno.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VectorInstitute/DANER/2b5feadda6c1d35ab7be09277339c490396bc49e/doc/slidev/public/final_neranno.jpg -------------------------------------------------------------------------------- /doc/slidev/public/final_nerservice.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VectorInstitute/DANER/2b5feadda6c1d35ab7be09277339c490396bc49e/doc/slidev/public/final_nerservice.jpg -------------------------------------------------------------------------------- /doc/slidev/public/label_definition.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VectorInstitute/DANER/2b5feadda6c1d35ab7be09277339c490396bc49e/doc/slidev/public/label_definition.png -------------------------------------------------------------------------------- /doc/slidev/public/ml_workflow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VectorInstitute/DANER/2b5feadda6c1d35ab7be09277339c490396bc49e/doc/slidev/public/ml_workflow.png -------------------------------------------------------------------------------- /doc/slidev/public/ner_service.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VectorInstitute/DANER/2b5feadda6c1d35ab7be09277339c490396bc49e/doc/slidev/public/ner_service.png -------------------------------------------------------------------------------- /doc/slidev/public/take_away.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VectorInstitute/DANER/2b5feadda6c1d35ab7be09277339c490396bc49e/doc/slidev/public/take_away.jpg -------------------------------------------------------------------------------- /doc/slidev/public/vector_content.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VectorInstitute/DANER/2b5feadda6c1d35ab7be09277339c490396bc49e/doc/slidev/public/vector_content.png -------------------------------------------------------------------------------- /doc/slidev/public/vector_cover.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VectorInstitute/DANER/2b5feadda6c1d35ab7be09277339c490396bc49e/doc/slidev/public/vector_cover.png -------------------------------------------------------------------------------- /doc/slidev/public/vector_thanks.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VectorInstitute/DANER/2b5feadda6c1d35ab7be09277339c490396bc49e/doc/slidev/public/vector_thanks.png -------------------------------------------------------------------------------- /doc/slidev/slides default.md: -------------------------------------------------------------------------------- 1 | --- 2 | # try also 'default' to start simple 3 | theme: seriph 4 | # random image from a curated Unsplash collection by Anthony 5 | # like them? see https://unsplash.com/collections/94734566/slidev 6 | background: https://source.unsplash.com/collection/94734566/1920x1080 7 | # apply any windi css classes to the current slide 8 | class: 'text-center' 9 | # https://sli.dev/custom/highlighters.html 10 | highlighter: shiki 11 | # some information about the slides, markdown enabled 12 | info: | 13 | ## Slidev Starter Template 14 | Presentation slides for developers. 15 | 16 | Learn more at [Sli.dev](https://sli.dev) 17 | --- 18 | 19 | # Welcome to Slidev 20 | 21 | Presentation slides for developers 22 | 23 |
24 | 25 | Press Space for next page 26 | 27 |
28 | 29 |
30 | 33 | 35 | 36 | 37 |
38 | 39 | 40 | 43 | 44 | --- 45 | 46 | # What is Slidev? 47 | 48 | Slidev is a slides maker and presenter designed for developers, consist of the following features 49 | 50 | - 📝 **Text-based** - focus on the content with Markdown, and then style them later 51 | - 🎨 **Themable** - theme can be shared and used with npm packages 52 | - 🧑‍💻 **Developer Friendly** - code highlighting, live coding with autocompletion 53 | - 🤹 **Interactive** - embedding Vue components to enhance your expressions 54 | - 🎥 **Recording** - built-in recording and camera view 55 | - 📤 **Portable** - export into PDF, PNGs, or even a hostable SPA 56 | - 🛠 **Hackable** - anything possible on a webpage 57 | 58 |
59 |
60 | 61 | Read more about [Why Slidev?](https://sli.dev/guide/why) 62 | 63 | 67 | 68 | 79 | 80 | --- 81 | 82 | # Navigation 83 | 84 | Hover on the bottom-left corner to see the navigation's controls panel, [learn more](https://sli.dev/guide/navigation.html) 85 | 86 | ### Keyboard Shortcuts 87 | 88 | | | | 89 | | --- | --- | 90 | | right / space| next animation or slide | 91 | | left / shiftspace | previous animation or slide | 92 | | up | previous slide | 93 | | down | next slide | 94 | 95 | 96 | 101 |

Here!

102 | 103 | --- 104 | layout: image-right 105 | image: https://source.unsplash.com/collection/94734566/1920x1080 106 | --- 107 | 108 | # Code 109 | 110 | Use code snippets and get the highlighting directly![^1] 111 | 112 | ```ts {all|2|1-6|9|all} 113 | interface User { 114 | id: number 115 | firstName: string 116 | lastName: string 117 | role: string 118 | } 119 | 120 | function updateUser(id: number, update: User) { 121 | const user = getUser(id) 122 | const newUser = {...user, ...update} 123 | saveUser(id, newUser) 124 | } 125 | ``` 126 | 127 | 128 | 129 | [^1]: [Learn More](https://sli.dev/guide/syntax.html#line-highlighting) 130 | 131 | 142 | 143 | --- 144 | 145 | # Components 146 | 147 |
148 |
149 | 150 | You can use Vue components directly inside your slides. 151 | 152 | We have provided a few built-in components like `` and `` that you can use directly. And adding your custom components is also super easy. 153 | 154 | ```html 155 | 156 | ``` 157 | 158 | 159 | 160 | 161 | Check out [the guides](https://sli.dev/builtin/components.html) for more. 162 | 163 |
164 |
165 | 166 | ```html 167 | 168 | ``` 169 | 170 | 171 | 172 |
173 |
174 | 175 | 176 | --- 177 | class: px-20 178 | --- 179 | 180 | # Themes 181 | 182 | Slidev comes with powerful theming support. Themes can provide styles, layouts, components, or even configurations for tools. Switching between themes by just **one edit** in your frontmatter: 183 | 184 |
185 | 186 | ```yaml 187 | --- 188 | theme: default 189 | --- 190 | ``` 191 | 192 | ```yaml 193 | --- 194 | theme: seriph 195 | --- 196 | ``` 197 | 198 | 199 | 200 | 201 | 202 |
203 | 204 | Read more about [How to use a theme](https://sli.dev/themes/use.html) and 205 | check out the [Awesome Themes Gallery](https://sli.dev/themes/gallery.html). 206 | 207 | --- 208 | preload: false 209 | --- 210 | 211 | # Animations 212 | 213 | Animations are powered by [@vueuse/motion](https://motion.vueuse.org/). 214 | 215 | ```html 216 |
220 | Slidev 221 |
222 | ``` 223 | 224 |
225 |
226 | 233 | 240 | 247 |
248 | 249 |
254 | Slidev 255 |
256 |
257 | 258 | 259 | 273 | 274 |
278 | 279 | [Learn More](https://sli.dev/guide/animations.html#motion) 280 | 281 |
282 | 283 | --- 284 | 285 | # LaTeX 286 | 287 | LaTeX is supported out-of-box powered by [KaTeX](https://katex.org/). 288 | 289 |
290 | 291 | Inline $\sqrt{3x-1}+(1+x)^2$ 292 | 293 | Block 294 | $$ 295 | \begin{array}{c} 296 | 297 | \nabla \times \vec{\mathbf{B}} -\, \frac1c\, \frac{\partial\vec{\mathbf{E}}}{\partial t} & 298 | = \frac{4\pi}{c}\vec{\mathbf{j}} \nabla \cdot \vec{\mathbf{E}} & = 4 \pi \rho \\ 299 | 300 | \nabla \times \vec{\mathbf{E}}\, +\, \frac1c\, \frac{\partial\vec{\mathbf{B}}}{\partial t} & = \vec{\mathbf{0}} \\ 301 | 302 | \nabla \cdot \vec{\mathbf{B}} & = 0 303 | 304 | \end{array} 305 | $$ 306 | 307 |
308 | 309 | [Learn more](https://sli.dev/guide/syntax#latex) 310 | 311 | --- 312 | 313 | # Diagrams 314 | 315 | You can create diagrams / graphs from textual descriptions, directly in your Markdown. 316 | 317 |
318 | 319 | ```mermaid {scale: 0.9} 320 | sequenceDiagram 321 | Alice->John: Hello John, how are you? 322 | Note over Alice,John: A typical interaction 323 | ``` 324 | 325 | ```mermaid {theme: 'neutral', scale: 0.8} 326 | graph TD 327 | B[Text] --> C{Decision} 328 | C -->|One| D[Result 1] 329 | C -->|Two| E[Result 2] 330 | ``` 331 | 332 |
333 | 334 | [Learn More](https://sli.dev/guide/syntax.html#diagrams) 335 | 336 | 337 | --- 338 | layout: center 339 | class: text-center 340 | --- 341 | 342 | # Learn More 343 | 344 | [Documentations](https://sli.dev) · [GitHub](https://github.com/slidevjs/slidev) · [Showcases](https://sli.dev/showcases.html) 345 | -------------------------------------------------------------------------------- /doc/slidev/slides_archived.md: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | # Get/Put Annotation 4 | 5 |
6 | 7 |
8 | 9 | - Get Annotation 10 | 11 | - http://127.0.0.1:5000/annotation 12 | 13 | ```python{all} 14 | { 15 | "index": 13606, 16 | "ents": [ 17 | {'token': 'Bowling', 'label': 'null', 'iob': 2, "confidence": 0.06744539737701416}, 18 | {'token': '(', 'label': 'null', 'iob': 2, "confidence": 0.11347659677267075}, 19 | {'token': 'to', 'label': 'null', 'iob': 2, "confidence": 0.152160182595253}, 20 | {'token': 'date', 'label': 'null', 'iob': 2, "confidence": 0.1574113368988037}, 21 | {'token': ')', 'label': 'null', 'iob': 2, "confidence": 0.11822989583015442}, 22 | {'token': ':', 'label': 'null', 'iob': 2, "confidence": 0.13801075518131256}, 23 | {'token': 'Wasim', 'label': 'null', 'iob': 2, "confidence": 0.13231147825717926}, 24 | {'token': 'Akram', 'label': 'null', 'iob': 2, "confidence": 0.16222646832466125}, 25 | {'token': '25-8-61-1', 'label': 'null', 'iob': 2, "confidence": 0.1321057677268982}, 26 | ... 27 | ], 28 | } 29 | ``` 30 | 31 |
32 | 33 |
34 | 35 | - Put Annotation 36 | - http://127.0.0.1:5000/annotation?index={index}&annotator={annotator}&label={label} 37 | 38 | ```python{all} 39 | { 40 | "index": 13606 41 | "annotator": "admin" 42 | "ents": [ 43 | {'token': 'Bowling', 'label': 'MISC', 'iob': 3}, 44 | {'token': '(', 'label': 'null', 'iob': 2}, 45 | {'token': 'to', 'label': 'null', 'iob': 2}, 46 | {'token': 'date', 'label': 'null', 'iob': 2}, 47 | {'token': ')', 'label': 'null', 'iob': 2}, 48 | {'token': ':', 'label': 'null', 'iob': 2}, 49 | {'token': 'Wasim', 'label': 'PER', 'iob': 3}, 50 | {'token': 'Akram', 'label': 'PER', 'iob': 1}, 51 | {'token': '25-8-61-1', 'label': 'null', 'iob': 2}, 52 | ... 53 | } 54 | ``` 55 | 56 |
57 |
58 | 59 | 65 | 66 | 72 | -------------------------------------------------------------------------------- /doc/slidev/slides_interim.md: -------------------------------------------------------------------------------- 1 | --- 2 | theme: seriph 3 | title: Interim Presentation 4 | 5 | highlighter: shiki 6 | 7 | colorSchema: "light" 8 | 9 | info: | 10 | ## Slidev 11 | Vector Summer Internship Project Interim Presentation 12 | 13 | background: vector_cover.png 14 | layout: cover 15 | class: text-center 16 | --- 17 | 18 | # Build a Customized NLP Service 19 | 20 | ## Interim Presentation 21 | 22 | Friday, July 9, 2021 23 | 24 | Presented by: Yongchao Zhou 25 | 26 | --- 27 | 28 | # Motivation 29 | 30 |
31 |
32 | 33 |
Figure 1: Machine Learning Life Cycle
34 |
35 | 36 |
37 | 38 | -
ML Application Life Cycle
39 | 40 | -
Data Collection
41 | -
Data Annotation
42 | -
Model Training & Evaluation
43 | -
Model Deployment
44 | 45 | -
ML Tools
46 | 47 | - Active Learning 48 | - Transfer Learning 49 | 50 |
51 |
52 | 53 | 54 |
55 |
56 |
57 | 58 | 64 | 65 | 72 | 73 | --- 74 | 75 | # NER service 76 | 77 |
78 |
79 | 80 | - Inference API 81 |
82 | 83 | - Graphical User Interface 84 | 85 |
86 | 87 | ```python{all} 88 | >>> import NerModel 89 | >>> model = NerModel(args.model_dir) 90 | >>> model(args.text) 91 | 92 | {'text': 'Geoffrey Everest Hinton (born 6 December 1947) is a British-Canadian cognitive psychologist and computer scientist, most noted for his work on artificial neural networks.', 93 | 'ents': [{'token': 'Geoffrey Everest Hinton', 'start': 0, 'end': 23, 'label': 'PERSON'}, 94 | {'token': '6', 'start': 30, 'end': 31, 'label': 'CARDINAL'}, 95 | {'token': 'December 1947', 'start': 32, 'end': 45, 'label': 'DATE'}, 96 | {'token': 'British', 'start': 52, 'end': 59, 'label': 'NORP'}]} 97 | ``` 98 | 99 |
100 | 101 |
102 | 103 | 104 |
105 |
106 | 107 | 113 | 114 | 117 | 118 | --- 119 | 120 | # How to build a customized NER service? 121 | 122 | - Data Collection -> Data Annotation -> Model Training & Evaluation -> Model Deployment (API/GUI) 123 | 124 |
125 |
126 |
127 | 128 |
129 | ```python {all} 130 | >>> raw_dataset[0] 131 | "Geoffrey Everest Hinton (born 6 December 1947) is a British-Canadian cognitive psychologist and computer scientist, most noted for his work on artificial neural networks." 132 | ``` 133 |
134 | 135 | 136 | 137 |
138 | ```python {all} 139 | >>> train_dataset[0] 140 | {'text': 'Geoffrey Everest Hinton (born 6 December 1947) is a British-Canadian cognitive psychologist and computer scientist, most noted for his work on artificial neural networks.', 141 | 'annotation': [{'token': 'Geoffrey', 'label': 'PERSON', 'iob': 3}, {'token': 'Everest', 'label': 'PERSON', 'iob': 1}, {'token': 'Hinton', 'label': 'PERSON', 'iob': 1}, {'token': '(', 'label': 'null', 'iob': 2}, 142 | {'token': 'born', 'label': 'null', 'iob': 2}, {'token': '6', 'label': 'CARDINAL', 'iob': 3}, {'token': 'December', 'label': 'DATE', 'iob': 3}, {'token': '1947', 'label': 'DATE', 'iob': 1}, 143 | {'token': ')', 'label': 'null', 'iob': 2}, {'token': 'is', 'label': 'null', 'iob': 2}, {'token': 'a', 'label': 'null', 'iob': 2}, {'token': 'British', 'label': 'NORP', 'iob': 3}, 144 | {'token': '-', 'label': 'null', 'iob': 2}, {'token': 'Canadian', 'label': 'null', 'iob': 2}, {'token': 'cognitive', 'label': 'null', 'iob': 2}, {'token': 'psychologist', 'label': 'null', 'iob': 2}, 145 | {'token': 'and', 'label': 'null', 'iob': 2}, {'token': 'computer', 'label': 'null', 'iob': 2}, {'token': 'scientist', 'label': 'null', 'iob': 2}, {'token': ',', 'label': 'null', 'iob': 2}, 146 | {'token': 'most', 'label': 'null', 'iob': 2}, {'token': 'noted', 'label': 'null', 'iob': 2}, {'token': 'for', 'label': 'null', 'iob': 2}, {'token': 'his', 'label': 'null', 'iob': 2}, 147 | {'token': 'work', 'label': 'null', 'iob': 2}, {'token': 'on', 'label': 'null', 'iob': 2}, {'token': 'artificial', 'label': 'null', 'iob': 2}, {'token': 'neural', 'label': 'null', 'iob': 2}, 148 | {'token': 'networks', 'label': 'null', 'iob': 2}, {'token': '.', 'label': 'null', 'iob': 2} 149 | ... ]} 150 | ``` 151 |
152 | 153 | 156 | 157 | --- 158 | 159 | # Annotation Interface 160 | 161 |
162 |
163 | 164 |
165 | 166 |
167 | 168 |
169 | 170 |
171 | 172 | 179 | 180 | 183 | 184 | --- 185 | 186 | # Data Quality Control (In Progress) 187 | 188 |
189 | 190 |
191 | ```python {all|4-6,8,11-13,15} 192 | >>> db.examples[0] 193 | {'text': 'Geoffrey Everest Hinton (born 6 December 1947) is a British-Canadian cognitive psychologist and computer scientist, most noted for his work on artificial neural networks.', 194 | 'annotations': [{ 195 | 'user1':[{'token': 'Geoffrey', 'label': 'PERSON', 'iob': 3}, 196 | {'token': 'Everest', 'label': 'PERSON', 'iob': 1}, 197 | {'token': 'Hinton', 'label': 'PERSON', 'iob': 1}, 198 | {'token': 'born', 'label': 'null', 'iob': 2}, 199 | {'token': '6', 'label': 'CARDINAL', 'iob': 3}, 200 | {'token': 'December', 'label': 'DATE', 'iob': 3}, 201 | ... ], 202 | 'user2':[{'token': 'Geoffrey', 'label': 'null', 'iob': 2}, 203 | {'token': 'Everest', 'label': 'null', 'iob': 2}, 204 | {'token': 'Hinton', 'label': 'null', 'iob': 2}, 205 | {'token': 'born', 'label': 'null', 'iob': 2}, 206 | {'token': '6', 'label': 'DATE', 'iob': 3}, 207 | {'token': 'December', 'label': 'DATE', 'iob': 3}, 208 | ... ]}] 209 | ``` 210 |
211 | 212 |
213 |
214 | 215 | - User 1 216 | 217 | 218 | - User 2 219 | 220 | 221 |
222 | 223 |
224 | 225 | - Disagreement Visualization 226 | - Help needed 227 | 228 |
229 | 230 |
231 | 232 | - Golden Standard 233 | 234 | 235 |
236 | 237 |
238 | 239 |
240 | 241 | 244 | 245 | --- 246 | 247 | # Model Training 248 | 249 | ```python {all|1|2-8|10|12-17|19|all} 250 | from transformers import DistilBertForTokenClassification, Trainer, TrainingArguments 251 | training_args = TrainingArguments( 252 | num_train_epochs=3, # total number of training epochs 253 | per_device_train_batch_size=16, # batch size per device during training 254 | per_device_eval_batch_size=64, # batch size for evaluation 255 | warmup_steps=500, # number of warmup steps for learning rate scheduler 256 | weight_decay=0.01, # strength of weight decay 257 | ) 258 | 259 | model = DistilBertForTokenClassification.from_pretrained('distilbert-base-cased', num_labels=len(unique_tags)) 260 | 261 | trainer = Trainer( 262 | model=model, # the instantiated 🤗 Transformers model to be trained 263 | args=training_args, # training arguments, defined above 264 | train_dataset=train_dataset, # training dataset 265 | eval_dataset=val_dataset # evaluation dataset 266 | ) 267 | 268 | trainer.train() 269 | ``` 270 | 271 | 274 | 275 | --- 276 | 277 | # Model Selection using A/B Test (In progress) 278 | 279 |
280 | 281 | - Prediction from Trained Model 1 282 | 283 | 284 | - Prediction from Trained Model 2 285 | 286 |
287 | 288 |
289 | 290 | - They both make one mistake and have the same accuracy. Which model to choose? 291 | - Let user make the decision. 292 | - E.g. A/B Test with 100 examples. 293 | - Model 1 has 68/100 "likes" and Model 2 has 55/100 "likes" -> Deploy model 1 294 | 295 |
296 | 297 | 300 | 301 | --- 302 | 303 | # Next Steps 304 | 305 | - Functionality 306 | - Complete the data quality control interface 307 | - Model Selection with A/B testing 308 | - Data annotation with active learning 309 | - Experiement 310 | - Benchmark the performance of different active learning algorithm on NER task 311 | - Demo 312 | - Build a customized NER service for a specific domain (Medical Data) 313 | 314 | 317 | -------------------------------------------------------------------------------- /doc/slidev/vercel.json: -------------------------------------------------------------------------------- 1 | { 2 | "rewrites": [ 3 | { "source": "/(.*)", "destination": "/index.html" } 4 | ] 5 | } 6 | -------------------------------------------------------------------------------- /frontend/.eslintignore: -------------------------------------------------------------------------------- 1 | /dist 2 | /src-bex/www 3 | /src-capacitor 4 | /src-cordova 5 | /.quasar 6 | /node_modules 7 | .eslintrc.js 8 | babel.config.js 9 | -------------------------------------------------------------------------------- /frontend/.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | // https://eslint.org/docs/user-guide/configuring#configuration-cascading-and-hierarchy 3 | // This option interrupts the configuration hierarchy at this file 4 | // Remove this if you have an higher level ESLint config file (it usually happens into a monorepos) 5 | root: true, 6 | 7 | parserOptions: { 8 | parser: '@babel/eslint-parser', 9 | ecmaVersion: 2018, // Allows for the parsing of modern ECMAScript features 10 | sourceType: 'module' // Allows for the use of imports 11 | }, 12 | 13 | env: { 14 | browser: true 15 | }, 16 | 17 | // Rules order is important, please avoid shuffling them 18 | extends: [ 19 | // Base ESLint recommended rules 20 | // 'eslint:recommended', 21 | 22 | 23 | // Uncomment any of the lines below to choose desired strictness, 24 | // but leave only one uncommented! 25 | // See https://eslint.vuejs.org/rules/#available-rules 26 | 'plugin:vue/vue3-essential', // Priority A: Essential (Error Prevention) 27 | // 'plugin:vue/vue3-strongly-recommended', // Priority B: Strongly Recommended (Improving Readability) 28 | // 'plugin:vue/vue3-recommended', // Priority C: Recommended (Minimizing Arbitrary Choices and Cognitive Overhead) 29 | 30 | // https://github.com/prettier/eslint-config-prettier#installation 31 | // usage with Prettier, provided by 'eslint-config-prettier'. 32 | 'prettier' 33 | ], 34 | 35 | plugins: [ 36 | // https://eslint.vuejs.org/user-guide/#why-doesn-t-it-work-on-vue-file 37 | // required to lint *.vue files 38 | 'vue', 39 | 40 | // https://github.com/typescript-eslint/typescript-eslint/issues/389#issuecomment-509292674 41 | // Prettier has not been included as plugin to avoid performance impact 42 | // add it as an extension for your IDE 43 | ], 44 | 45 | globals: { 46 | ga: 'readonly', // Google Analytics 47 | cordova: 'readonly', 48 | __statics: 'readonly', 49 | __QUASAR_SSR__: 'readonly', 50 | __QUASAR_SSR_SERVER__: 'readonly', 51 | __QUASAR_SSR_CLIENT__: 'readonly', 52 | __QUASAR_SSR_PWA__: 'readonly', 53 | process: 'readonly', 54 | Capacitor: 'readonly', 55 | chrome: 'readonly' 56 | }, 57 | 58 | // add your custom rules here 59 | rules: { 60 | 'prefer-promise-reject-errors': 'off', 61 | 62 | 63 | // allow debugger during development only 64 | 'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'off' 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /frontend/.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | .thumbs.db 3 | node_modules 4 | 5 | # Quasar core related directories 6 | .quasar 7 | # /dist 8 | 9 | # Cordova related directories and files 10 | /src-cordova/node_modules 11 | /src-cordova/platforms 12 | /src-cordova/plugins 13 | /src-cordova/www 14 | 15 | # Capacitor related directories and files 16 | /src-capacitor/www 17 | /src-capacitor/node_modules 18 | 19 | # BEX related directories and files 20 | /src-bex/www 21 | /src-bex/js/core 22 | 23 | # Log files 24 | npm-debug.log* 25 | yarn-debug.log* 26 | yarn-error.log* 27 | 28 | # Editor directories and files 29 | .idea 30 | *.suo 31 | *.ntvs* 32 | *.njsproj 33 | *.sln 34 | -------------------------------------------------------------------------------- /frontend/.postcssrc.js: -------------------------------------------------------------------------------- 1 | // https://github.com/michael-ciniawsky/postcss-load-config 2 | 3 | module.exports = { 4 | plugins: [ 5 | // to edit target browsers: use "browserslist" field in package.json 6 | require('autoprefixer') 7 | ] 8 | } 9 | -------------------------------------------------------------------------------- /frontend/README.md: -------------------------------------------------------------------------------- 1 | # DANER Frontend 2 | Data Annotation Tool for Named Entity Recognition Task 3 | 4 | ## Install the dependencies 5 | ```bash 6 | npm install 7 | ``` 8 | 9 | ### Start the app in development mode (hot-code reloading, error reporting, etc.) 10 | ```bash 11 | quasar dev 12 | ``` 13 | 14 | ### Lint the files 15 | ```bash 16 | npm run lint 17 | ``` 18 | 19 | ### Build the app for production 20 | ```bash 21 | quasar build 22 | ``` 23 | 24 | ### Customize the configuration 25 | See [Configuring quasar.conf.js](https://v2.quasar.dev/quasar-cli/quasar-conf-js). 26 | -------------------------------------------------------------------------------- /frontend/babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = (api) => { 2 | return { 3 | presets: [ 4 | [ 5 | "@quasar/babel-preset-app", 6 | api.caller((caller) => caller && caller.target === "node") 7 | ? { targets: { node: "current" } } 8 | : {}, 9 | ], 10 | ], 11 | plugins: ["@vue/babel-plugin-jsx"], 12 | }; 13 | }; 14 | -------------------------------------------------------------------------------- /frontend/dist/spa/css/365.95b382cf.css: -------------------------------------------------------------------------------- 1 | .label-entity[data-v-5ef69569]{background:#fff;font-size:.7em;margin:0 0 .15rem .35rem;text-transform:uppercase;vertical-align:middle}.label-entity[data-v-5ef69569],.q-banner[data-v-5ef69569]{border-radius:.35em;box-sizing:border-box;display:inline-block;font-weight:700;line-height:1;padding:.35em}.q-banner[data-v-5ef69569]{margin:.1em}.myContainer[data-v-5420bad4]{margin:auto;max-width:784px}.q-card[data-v-5420bad4]{margin:3em 0} -------------------------------------------------------------------------------- /frontend/dist/spa/css/458.ee62df10.css: -------------------------------------------------------------------------------- 1 | .label-entity[data-v-aab4369a]{background:#fff;font-size:.7em;margin:0 0 .15rem .35rem;padding:.35em;text-transform:uppercase;vertical-align:middle}.label-entity[data-v-aab4369a],.q-banner[data-v-aab4369a]{border-radius:.35em;box-sizing:border-box;display:inline-block;font-weight:700;line-height:1}.q-banner[data-v-aab4369a]{margin:.1em;padding:.2em}.label-entity[data-v-511eeee8]{background:#fff;border-radius:.35em;box-sizing:border-box;display:inline-block;font-size:.7em;font-weight:700;line-height:1;margin:0 0 .15rem .5rem;padding:.35em;text-transform:uppercase;vertical-align:middle}.myContainer[data-v-060cdd2e]{margin:auto;max-width:784px}.q-card[data-v-060cdd2e]{margin:3em 0} -------------------------------------------------------------------------------- /frontend/dist/spa/css/470.abcad4da.css: -------------------------------------------------------------------------------- 1 | @media screen and (min-width:768px){.q-footer{display:none}} -------------------------------------------------------------------------------- /frontend/dist/spa/css/707.d67b164b.css: -------------------------------------------------------------------------------- 1 | .myContainer[data-v-5404722e]{margin:auto;max-width:784px}.q-card[data-v-5404722e]{margin:auto;max-width:768px;width:100%}.lm[data-v-5404722e]{margin:3em 0} -------------------------------------------------------------------------------- /frontend/dist/spa/css/839.514ae98d.css: -------------------------------------------------------------------------------- 1 | .myContainer[data-v-d29d7602]{margin:auto;max-width:784px}.q-card[data-v-d29d7602]{margin:auto;max-width:768px;width:100%}.lm[data-v-d29d7602]{margin:3em 0} -------------------------------------------------------------------------------- /frontend/dist/spa/css/app.31d6cfe0.css: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VectorInstitute/DANER/2b5feadda6c1d35ab7be09277339c490396bc49e/frontend/dist/spa/css/app.31d6cfe0.css -------------------------------------------------------------------------------- /frontend/dist/spa/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VectorInstitute/DANER/2b5feadda6c1d35ab7be09277339c490396bc49e/frontend/dist/spa/favicon.ico -------------------------------------------------------------------------------- /frontend/dist/spa/fonts/KFOkCnqEu92Fr1MmgVxIIzQ.9391e6e2.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VectorInstitute/DANER/2b5feadda6c1d35ab7be09277339c490396bc49e/frontend/dist/spa/fonts/KFOkCnqEu92Fr1MmgVxIIzQ.9391e6e2.woff -------------------------------------------------------------------------------- /frontend/dist/spa/fonts/KFOlCnqEu92Fr1MmEU9fBBc-.ddd11dab.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VectorInstitute/DANER/2b5feadda6c1d35ab7be09277339c490396bc49e/frontend/dist/spa/fonts/KFOlCnqEu92Fr1MmEU9fBBc-.ddd11dab.woff -------------------------------------------------------------------------------- /frontend/dist/spa/fonts/KFOlCnqEu92Fr1MmSU5fBBc-.877b9231.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VectorInstitute/DANER/2b5feadda6c1d35ab7be09277339c490396bc49e/frontend/dist/spa/fonts/KFOlCnqEu92Fr1MmSU5fBBc-.877b9231.woff -------------------------------------------------------------------------------- /frontend/dist/spa/fonts/KFOlCnqEu92Fr1MmWUlfBBc-.0344cc3c.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VectorInstitute/DANER/2b5feadda6c1d35ab7be09277339c490396bc49e/frontend/dist/spa/fonts/KFOlCnqEu92Fr1MmWUlfBBc-.0344cc3c.woff -------------------------------------------------------------------------------- /frontend/dist/spa/fonts/KFOlCnqEu92Fr1MmYUtfBBc-.b555d228.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VectorInstitute/DANER/2b5feadda6c1d35ab7be09277339c490396bc49e/frontend/dist/spa/fonts/KFOlCnqEu92Fr1MmYUtfBBc-.b555d228.woff -------------------------------------------------------------------------------- /frontend/dist/spa/fonts/KFOmCnqEu92Fr1Mu4mxM.9b78ea3b.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VectorInstitute/DANER/2b5feadda6c1d35ab7be09277339c490396bc49e/frontend/dist/spa/fonts/KFOmCnqEu92Fr1Mu4mxM.9b78ea3b.woff -------------------------------------------------------------------------------- /frontend/dist/spa/fonts/flUhRq6tzZclQEJ-Vdg-IuiaDsNa.7d512ef7.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VectorInstitute/DANER/2b5feadda6c1d35ab7be09277339c490396bc49e/frontend/dist/spa/fonts/flUhRq6tzZclQEJ-Vdg-IuiaDsNa.7d512ef7.woff -------------------------------------------------------------------------------- /frontend/dist/spa/fonts/flUhRq6tzZclQEJ-Vdg-IuiaDsNcIhQ8tQ.49dcbc98.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VectorInstitute/DANER/2b5feadda6c1d35ab7be09277339c490396bc49e/frontend/dist/spa/fonts/flUhRq6tzZclQEJ-Vdg-IuiaDsNcIhQ8tQ.49dcbc98.woff2 -------------------------------------------------------------------------------- /frontend/dist/spa/icons/favicon-128x128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VectorInstitute/DANER/2b5feadda6c1d35ab7be09277339c490396bc49e/frontend/dist/spa/icons/favicon-128x128.png -------------------------------------------------------------------------------- /frontend/dist/spa/icons/favicon-16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VectorInstitute/DANER/2b5feadda6c1d35ab7be09277339c490396bc49e/frontend/dist/spa/icons/favicon-16x16.png -------------------------------------------------------------------------------- /frontend/dist/spa/icons/favicon-32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VectorInstitute/DANER/2b5feadda6c1d35ab7be09277339c490396bc49e/frontend/dist/spa/icons/favicon-32x32.png -------------------------------------------------------------------------------- /frontend/dist/spa/icons/favicon-96x96.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VectorInstitute/DANER/2b5feadda6c1d35ab7be09277339c490396bc49e/frontend/dist/spa/icons/favicon-96x96.png -------------------------------------------------------------------------------- /frontend/dist/spa/index.html: -------------------------------------------------------------------------------- 1 | DANER
-------------------------------------------------------------------------------- /frontend/dist/spa/js/153.981633e8.js: -------------------------------------------------------------------------------- 1 | "use strict";(self["webpackChunkDANER"]=self["webpackChunkDANER"]||[]).push([[153],{153:(e,t,n)=>{n.r(t),n.d(t,{default:()=>h});var l=n(3673);const s={class:"fullscreen bg-blue text-white text-center q-pa-md flex flex-center"},o=(0,l.Wm)("div",{style:{"font-size":"30vh"}},"404",-1),c=(0,l.Wm)("div",{class:"text-h2",style:{opacity:"0.4"}},"Oops. Nothing here...",-1);function r(e,t,n,r,a,u){const i=(0,l.up)("q-btn");return(0,l.wg)(),(0,l.j4)("div",s,[(0,l.Wm)("div",null,[o,c,(0,l.Wm)(i,{class:"q-mt-xl",color:"white","text-color":"blue",unelevated:"",to:"/",label:"Go Home","no-caps":""})])])}const a=(0,l.aZ)({name:"Error404"});var u=n(8240),i=n(7518),d=n.n(i);a.render=r;const h=a;d()(a,"components",{QBtn:u.Z})}}]); -------------------------------------------------------------------------------- /frontend/dist/spa/js/203.64790f71.js: -------------------------------------------------------------------------------- 1 | "use strict";(self["webpackChunkDANER"]=self["webpackChunkDANER"]||[]).push([[203],{6203:(a,l,e)=>{e.r(l),e.d(l,{default:()=>x});var t=e(3673);const s=(0,t.Uk)(" Sika Code Design"),n=(0,t.Wm)("div",null,"Sika v1.0.0",-1),m=(0,t.Wm)("div",{class:"q-my-lg"},[(0,t.Wm)("div",{class:"text-center q-mb-sm"},[(0,t.Wm)("span",{class:"inline-block q-mr-sm"},"Sika Design Pro"),(0,t.Wm)("span",{class:"inline-block q-ml-sm"},"Sika Design")])],-1),o={class:"q-pa-sm q-mt-lg row justify-center"},i={class:"col text-center",style:{width:"100%","max-width":"400px"}},r={class:"q-mb-xl"},u={class:"q-ma-sm"},c=(0,t.Wm)("img",{alt:"Sika logo",src:"imgs/logo/sika-logo.png"},null,-1),d=(0,t.Wm)("strong",null,"Sika Design",-1);function p(a,l,e,p,g,W){const w=(0,t.up)("q-toolbar-title"),f=(0,t.up)("q-toolbar"),q=(0,t.up)("q-header"),k=(0,t.up)("q-footer"),v=(0,t.up)("q-avatar"),b=(0,t.up)("router-view"),h=(0,t.up)("q-page-container"),y=(0,t.up)("q-layout");return(0,t.wg)(),(0,t.j4)("div",null,[(0,t.Wm)(y,{view:"hHh LpR fff"},{default:(0,t.w5)((()=>[(0,t.Wm)(q,{class:"bg-white text-primary shadow-1"},{default:(0,t.w5)((()=>[(0,t.Wm)(f,null,{default:(0,t.w5)((()=>[(0,t.Wm)(w,null,{default:(0,t.w5)((()=>[s])),_:1}),n])),_:1})])),_:1}),(0,t.Wm)(k,{class:"bg-white text-blue-grey-4"},{default:(0,t.w5)((()=>[m])),_:1}),(0,t.Wm)(h,null,{default:(0,t.w5)((()=>[(0,t.Wm)("div",o,[(0,t.Wm)("div",i,[(0,t.Wm)("div",r,[(0,t.Wm)("h4",u,[(0,t.Wm)(v,{class:"q-mr-md"},{default:(0,t.w5)((()=>[c])),_:1}),d])]),(0,t.Wm)(b)])])])),_:1})])),_:1})])}const g={name:"UserLayout"};var W=e(9214),w=e(3812),f=e(9570),q=e(3747),k=e(1762),v=e(2652),b=e(5096),h=e(7518),y=e.n(h);g.render=p;const x=g;y()(g,"components",{QLayout:W.Z,QHeader:w.Z,QToolbar:f.Z,QToolbarTitle:q.Z,QFooter:k.Z,QPageContainer:v.Z,QAvatar:b.Z})}}]); -------------------------------------------------------------------------------- /frontend/dist/spa/js/325.5cd31c19.js: -------------------------------------------------------------------------------- 1 | "use strict";(self["webpackChunkDANER"]=self["webpackChunkDANER"]||[]).push([[325],{3325:(n,a,e)=>{e.r(a),e.d(a,{default:()=>r});var t=e(3673);const c=(0,t.HX)("data-v-0d4c8670");(0,t.dD)("data-v-0d4c8670");const d=(0,t.Wm)("p",null,"500",-1);(0,t.Cn)();const s=c(((n,a,e,s,u,l)=>{const o=(0,t.up)("q-page");return(0,t.wg)(),(0,t.j4)(o,null,{default:c((()=>[d])),_:1})})),u={name:""};var l=e(4379),o=e(7518),p=e.n(o);u.render=s,u.__scopeId="data-v-0d4c8670";const r=u;p()(u,"components",{QPage:l.Z})}}]); -------------------------------------------------------------------------------- /frontend/dist/spa/js/365.3663b5cb.js: -------------------------------------------------------------------------------- 1 | "use strict";(self["webpackChunkDANER"]=self["webpackChunkDANER"]||[]).push([[365],{2365:(e,t,l)=>{l.r(t),l.d(t,{default:()=>j});l(71);var n=l(3673),a=l(8880);const o=(0,n.HX)("data-v-5420bad4");(0,n.dD)("data-v-5420bad4");const s={class:"myContainer"},r=(0,n.Wm)("div",{class:"text-h4"},"Named Entity Recognition Service",-1),c={class:"q-ma-md"},u={class:"q-gutter-sm"},i={class:"q-pa-md"},d={class:"q-gutter-md row items-start"};(0,n.Cn)();const m=o(((e,t,l,m,p,v)=>{const g=(0,n.up)("q-card-section"),b=(0,n.up)("q-checkbox"),f=(0,n.up)("q-separator"),x=(0,n.up)("q-btn"),y=(0,n.up)("q-select"),S=(0,n.up)("q-card"),h=(0,n.up)("q-input"),L=(0,n.up)("ner-render"),W=(0,n.up)("q-page");return(0,n.wg)(),(0,n.j4)(W,{padding:""},{default:o((()=>[(0,n.Wm)("div",s,[(0,n.Wm)(S,null,{default:o((()=>[(0,n.Wm)(g,{class:"bg-primary text-white",align:"center"},{default:o((()=>[r])),_:1}),(0,n.Wm)("div",c,[(0,n.Wm)("div",u,[((0,n.wg)(!0),(0,n.j4)(n.HY,null,(0,n.Ko)(m.ALL_ENTS,((e,l)=>((0,n.wg)(),(0,n.j4)(b,{modelValue:m.ents,"onUpdate:modelValue":t[1]||(t[1]=e=>m.ents=e),"keep-color":"",key:l,val:e.val,label:e.label,color:e.color},null,8,["modelValue","val","label","color"])))),128))]),(0,n.Wm)(f),(0,n.Wm)(x,{color:"primary",label:"Select All",onClick:m.onSelectALL},null,8,["onClick"]),(0,n.Wm)(x,{color:"secondary",label:"Default",onClick:m.onSelectDefault,class:"q-ma-md"},null,8,["onClick"]),(0,n.Wm)(x,{color:"primary",label:"Reset",flat:"",onClick:m.onResetLabel,class:"q-ma-md"},null,8,["onClick"])]),(0,n.Wm)("div",i,[(0,n.Wm)("div",d,[(0,n.Wm)(y,{filled:"",modelValue:m.model,"onUpdate:modelValue":t[2]||(t[2]=e=>m.model=e),options:m.ALL_MODELS,label:"Model",style:{width:"250px"}},null,8,["modelValue","options"])])])])),_:1}),(0,n.Wm)(S,null,{default:o((()=>[(0,n.Wm)("form",{onSubmit:t[4]||(t[4]=(0,a.iM)(((...e)=>m.onSubmit&&m.onSubmit(...e)),["prevent","stop"])),onReset:t[5]||(t[5]=(0,a.iM)(((...e)=>m.onReset&&m.onReset(...e)),["prevent","stop"])),class:"q-gutter-md"},[(0,n.Wm)("div",null,[(0,n.Wm)(h,{ref:"textRef",filled:"",type:"textarea",modelValue:m.text,"onUpdate:modelValue":t[3]||(t[3]=e=>m.text=e),hint:"Max characters 1500",counter:"","lazy-rules":"",autogrow:"",rules:m.textRules,"input-style":{"min-height":"100px"}},null,8,["modelValue","rules"])]),(0,n.Wm)("div",null,[(0,n.Wm)(x,{label:"Analyze",type:"submit",color:"primary",class:"q-ma-md"}),(0,n.Wm)(x,{label:"Reset",type:"reset",color:"primary",flat:"",class:"q-ma-md"})])],32)])),_:1}),(0,n.Wm)(L,{nerText:m.text,nerSpans:m.result,ents:m.ents,entStyle:m.ALL_ENTS},null,8,["nerText","nerSpans","ents","entStyle"])])])),_:1})}));var p=l(8825),v=l(1959),g=l(7874),b=l(2323);const f=(0,n.HX)("data-v-5ef69569");(0,n.dD)("data-v-5ef69569");const x={key:0},y={key:1},S={class:"label-entity"},h={key:2};(0,n.Cn)();const L=f(((e,t,l,a,o,s)=>{const r=(0,n.up)("q-banner"),c=(0,n.up)("q-card-section"),u=(0,n.up)("q-card");return l.nerSpans.length>0?((0,n.wg)(),(0,n.j4)(u,{key:0},{default:f((()=>[(0,n.Wm)(c,null,{default:f((()=>[((0,n.wg)(!0),(0,n.j4)(n.HY,null,(0,n.Ko)(a.contentList,((e,t)=>((0,n.wg)(),(0,n.j4)("span",{key:t},["
"===e.text?((0,n.wg)(),(0,n.j4)("p",x)):""!==e.color?((0,n.wg)(),(0,n.j4)("span",y,[(0,n.Wm)(r,{dense:"",style:{background:a.getPaletteColor(e.color)}},{default:f((()=>[(0,n.Uk)((0,b.zw)(e["text"])+" ",1),(0,n.Wm)("span",S,(0,b.zw)(e["label"]),1)])),_:2},1032,["style"])])):((0,n.wg)(),(0,n.j4)("span",h,(0,b.zw)(e["text"]),1))])))),128))])),_:1})])),_:1})):(0,n.kq)("",!0)}));l(7280);var W=l(2156);const k={props:["nerText","nerSpans","ents","entStyle"],setup(e){const{getPaletteColor:t}=W.ZP;let l=null;const a=(0,n.Fl)((()=>{let t=[],n=0;return e.nerSpans.length>0&&(e.nerSpans.forEach((({_:a,start:o,end:s,label:r})=>{const c=e.nerText.slice(o,s),u=e.nerText.slice(n,o).split("\n");u.forEach(((e,l)=>{t.push({text:e,label:"",color:""}),u.length>1&&l!=u.length-1&&t.push({text:"
",label:"",color:""})})),e.ents.includes(r)?(l=e.entStyle.find((({val:e})=>e===r)).color,t.push({text:c,label:r,color:l})):t.push({text:c,label:"",color:""}),n=s})),t.push({text:e.nerText.slice(n,e.nerText.length),label:"",color:""})),t}));return{contentList:a,getPaletteColor:t}}};var q=l(151),N=l(5589),C=l(5607),_=l(7518),w=l.n(_);k.render=L,k.__scopeId="data-v-5ef69569";const R=k;w()(k,"components",{QCard:q.Z,QCardSection:N.Z,QBanner:C.Z});const E={components:{NerRender:R},setup(){const e=(0,p.Z)(),t=(0,g.oR)(),l=t.state.serviceNer.ALL_MODELS,a=t.state.serviceNer.ALL_ENTS,o=(0,v.iH)(null),s=(0,n.Fl)({get:()=>t.state.serviceNer.text,set:e=>{t.commit("serviceNer/updateText",e)}}),r=(0,n.Fl)({get:()=>t.state.serviceNer.ents,set:e=>{t.commit("serviceNer/updateEnts",e)}}),c=(0,n.Fl)({get:()=>t.state.serviceNer.model,set:e=>{t.commit("serviceNer/updateModel",e)}}),u=(0,n.Fl)((()=>t.state.serviceNer.result)),i=[e=>e&&e.length>0||"Please type something to analyze!",e=>e&&e.length<1500||"Text too long"];function d(){r.value=t.getters["serviceNer/getAllEnts"]}function m(){r.value=t.getters["serviceNer/getDefaultEnts"]}function b(){r.value=[]}function f(){o.value.validate(),o.value.hasError?e.notify({color:"negative",message:"No content to analyze"}):e.notify({icon:"done",color:"positive",message:"Send to server for analyze"}),t.dispatch("serviceNer/analyzeText",{textInput:s.value})}function x(){s.value=null,o.value.resetValidation()}return{text:s,textRef:o,textRules:i,result:u,ents:r,model:c,ALL_ENTS:a,ALL_MODELS:l,onSelectALL:d,onSelectDefault:m,onResetLabel:b,onSubmit:f,onReset:x}}};var A=l(4379),T=l(5735),Z=l(5869),D=l(8240),Q=l(5987),V=l(4842);E.render=m,E.__scopeId="data-v-5420bad4";const j=E;w()(E,"components",{QPage:A.Z,QCard:q.Z,QCardSection:N.Z,QCheckbox:T.Z,QSeparator:Z.Z,QBtn:D.Z,QSelect:Q.Z,QInput:V.Z})}}]); -------------------------------------------------------------------------------- /frontend/dist/spa/js/400.d083091b.js: -------------------------------------------------------------------------------- 1 | "use strict";(self["webpackChunkDANER"]=self["webpackChunkDANER"]||[]).push([[400],{3400:(n,e,s)=>{s.r(e),s.d(e,{default:()=>p});var t=s(3673);const u=(0,t.Wm)("p",null,"User Login",-1);function a(n,e,s,a,c,r){const l=(0,t.up)("q-page");return(0,t.wg)(),(0,t.j4)(l,null,{default:(0,t.w5)((()=>[u])),_:1})}const c={name:""};var r=s(4379),l=s(7518),o=s.n(l);c.render=a;const p=c;o()(c,"components",{QPage:r.Z})}}]); -------------------------------------------------------------------------------- /frontend/dist/spa/js/411.a398b765.js: -------------------------------------------------------------------------------- 1 | "use strict";(self["webpackChunkDANER"]=self["webpackChunkDANER"]||[]).push([[411],{1411:(e,a,n)=>{n.r(a),n.d(a,{default:()=>r});var t=n(3673);const d=(0,t.HX)("data-v-d3ebc7d2");(0,t.dD)("data-v-d3ebc7d2");const c=(0,t.Wm)("p",null,"Data Detail",-1);(0,t.Cn)();const s=d(((e,a,n,s,u,l)=>{const o=(0,t.up)("q-page");return(0,t.wg)(),(0,t.j4)(o,null,{default:d((()=>[c])),_:1})})),u={name:""};var l=n(4379),o=n(7518),p=n.n(o);u.render=s,u.__scopeId="data-v-d3ebc7d2";const r=u;p()(u,"components",{QPage:l.Z})}}]); -------------------------------------------------------------------------------- /frontend/dist/spa/js/458.5e571986.js: -------------------------------------------------------------------------------- 1 | "use strict";(self["webpackChunkDANER"]=self["webpackChunkDANER"]||[]).push([[458],{6458:(e,t,n)=>{n.r(t),n.d(t,{default:()=>oe});var o=n(3673);const a=(0,o.HX)("data-v-060cdd2e");(0,o.dD)("data-v-060cdd2e");const l={class:"myContainer"};(0,o.Cn)();const i=a(((e,t,n,i,r,s)=>{const d=(0,o.up)("ner-configuration"),u=(0,o.up)("ner-annotation-render"),c=(0,o.up)("q-page");return(0,o.wg)(),(0,o.j4)(c,{padding:""},{default:a((()=>[(0,o.Wm)("div",l,[(0,o.Wm)(d),i.startAnnotation?((0,o.wg)(),(0,o.j4)(u,{key:0})):(0,o.kq)("",!0)])])),_:1})}));var r=n(8825),s=n(7874);const d=(0,o.HX)("data-v-511eeee8");(0,o.dD)("data-v-511eeee8");const u=(0,o.Wm)("div",{class:"text-h4"},"Annotation",-1),c={class:"q-gutter-sm"};(0,o.Cn)();const m=d(((e,t,n,a,l,i)=>{const r=(0,o.up)("q-card-section"),s=(0,o.up)("q-btn"),m=(0,o.up)("q-radio"),p=(0,o.up)("q-separator"),g=(0,o.up)("token-render"),f=(0,o.up)("q-card");return(0,o.wg)(),(0,o.j4)(f,null,{default:d((()=>[(0,o.Wm)(r,{class:"bg-primary text-white q-pa-sm",align:"center"},{default:d((()=>[u])),_:1}),(0,o.Wm)(r,{class:"flex justify-between"},{default:d((()=>[(0,o.Wm)("div",null,[(0,o.Wm)(s,{dense:"",round:"",color:"primary",icon:"arrow_back",class:"q-ma-sm",onClick:a.retrievePrev},null,8,["onClick"]),(0,o.Wm)(s,{dense:"",round:"",color:"primary",icon:"arrow_forward",class:"q-ma-sm",onClick:a.retrieveNext},null,8,["onClick"])]),(0,o.Wm)("div",null,[(0,o.Wm)(s,{dense:"",round:"",color:"primary",icon:"done",class:"q-ma-sm",onClick:a.onSubmitAnnotation},null,8,["onClick"]),(0,o.Wm)(s,{dense:"",round:"",color:"primary",icon:"close",class:"q-ma-sm",onClick:a.onRejectAnnotation},null,8,["onClick"])])])),_:1}),(0,o.Wm)(r,null,{default:d((()=>[(0,o.Wm)("div",c,[((0,o.wg)(!0),(0,o.j4)(o.HY,null,(0,o.Ko)(a.entList,((e,n)=>((0,o.wg)(),(0,o.j4)(m,{modelValue:a.curEnt,"onUpdate:modelValue":t[1]||(t[1]=e=>a.curEnt=e),"keep-color":"",key:n,val:e.val,label:e.label,color:e.color},null,8,["modelValue","val","label","color"])))),128))])])),_:1}),(0,o.Wm)(p),(0,o.Wm)(r,null,{default:d((()=>[((0,o.wg)(!0),(0,o.j4)(o.HY,null,(0,o.Ko)(a.contentList,((e,t)=>((0,o.wg)(),(0,o.j4)(g,{key:t,id:e.id,token:e,onMousedown:a.handleMouseDown,onMouseup:a.handleMouseUp},null,8,["id","token","onMousedown","onMouseup"])))),128))])),_:1})])),_:1})}));var p=n(2323);const g=(0,o.HX)("data-v-aab4369a");(0,o.dD)("data-v-aab4369a");const f={key:0,class:"label-entity"};(0,o.Cn)();const v=g(((e,t,n,a,l,i)=>{const r=(0,o.up)("q-btn"),s=(0,o.up)("q-banner"),d=(0,o.up)("q-tooltip");return(0,o.wg)(),(0,o.j4)("span",{id:n.id},[""!==n.token.color&&n.token.confidence>=a.conf?((0,o.wg)(),(0,o.j4)(r,{key:0,dense:"",flat:"","no-caps":"",style:{background:a.getColor(n.token)}},{default:g((()=>[(0,o.Uk)((0,p.zw)(n.token.token)+" ",1),""!==n.token.color?((0,o.wg)(),(0,o.j4)("span",f,(0,p.zw)(n.token.label),1)):(0,o.kq)("",!0)])),_:1},8,["style"])):((0,o.wg)(),(0,o.j4)(s,{key:1,dense:""},{default:g((()=>[(0,o.Uk)((0,p.zw)(n.token.token),1)])),_:1})),a.showConfidence?((0,o.wg)(),(0,o.j4)(d,{key:2,offset:[0,4]},{default:g((()=>[(0,o.Uk)((0,p.zw)(n.token.confidence.toFixed(3)),1)])),_:1})):(0,o.kq)("",!0)],8,["id"])}));var k=n(2156);const w={props:["token","id"],setup(){const e=(0,s.oR)(),{getPaletteColor:t}=k.ZP,n=(0,o.Fl)({get:()=>e.state.annotationNer.showConfidence}),a=(0,o.Fl)({get:()=>e.state.annotationNer.autoSuggestStrength/100});function l(e){return""!==e.color?t(e.color):"#fff"}return{conf:a,showConfidence:n,getColor:l}}};var N=n(8240),L=n(5607),S=n(8870),A=n(7518),y=n.n(A);w.render=v,w.__scopeId="data-v-aab4369a";const h=w;y()(w,"components",{QBtn:N.Z,QBanner:L.Z,QTooltip:S.Z});const C={components:{tokenRender:h},setup(){const e=(0,r.Z)(),t=(0,s.oR)(),n=(0,o.Fl)({get:()=>t.state.annotationNer.startIndex,set:e=>{t.commit("annotationNer/updateStartIndex",e)}}),a=(0,o.Fl)({get:()=>t.state.annotationNer.curEnt,set:e=>{t.commit("annotationNer/updateCurEnt",e)}}),l=(0,o.Fl)((()=>t.state.annotationNer.result)),i=(0,o.Fl)((()=>t.getters["annotationNer/getEntList"])),d=(0,o.Fl)((()=>t.getters["annotationNer/getContentList"]));function u(e){const t=e.currentTarget;n.value=t.id}function c(e){const o=e.currentTarget;n.value===o.id?t.commit("annotationNer/toggleLabel",o.id):t.commit("annotationNer/addLabel",{endIndex:o.id}),n.value=null,window.getSelection?window.getSelection().removeAllRanges():document.selection&&document.selection.empty()}function m(){e.notify({position:"top",spinner:!0,message:"Send to backend",timeout:1e3}),t.dispatch("annotationNer/updateDataset")}function p(){t.dispatch("annotationNer/getDataset")}function g(){t.commit("annotationNer/retrieveHistoryPrev")}function f(){t.commit("annotationNer/retrieveHistoryNext")}return{curEnt:a,result:l,entList:i,contentList:d,handleMouseDown:u,handleMouseUp:c,onSubmitAnnotation:m,onRejectAnnotation:p,retrievePrev:g,retrieveNext:f}}};var W=n(151),b=n(5589),q=n(7991),_=n(5869);C.render=m,C.__scopeId="data-v-511eeee8";const V=C;y()(C,"components",{QCard:W.Z,QCardSection:b.Z,QBtn:N.Z,QRadio:q.Z,QSeparator:_.Z});const x=(0,o.Wm)("div",{class:"text-h4"},"Annotation Configuration",-1),Z={class:"row",style:{}},D={class:"col"},E={class:"q-gutter-md row"},j=(0,o.Wm)("br",null,null,-1),F={class:"q-gutter-sm"},Q={class:"col q-ma-sm"},R=(0,o.Uk)(" Confidence Level: 0 "),T=(0,o.Uk)(" 100 "),U={class:"q-gutter-md row"},O={class:"q-gutter-md"},M={class:"q-gutter-md row items-start"},P={key:0,class:"q-mt-md"},z={class:"q-mt-md"};function H(e,t,n,a,l,i){const r=(0,o.up)("q-card-section"),s=(0,o.up)("q-select"),d=(0,o.up)("q-checkbox"),u=(0,o.up)("q-btn"),c=(0,o.up)("q-separator"),m=(0,o.up)("q-toggle"),p=(0,o.up)("q-item-section"),g=(0,o.up)("q-slider"),f=(0,o.up)("q-item"),v=(0,o.up)("q-card");return(0,o.wg)(),(0,o.j4)(v,null,{default:(0,o.w5)((()=>[(0,o.Wm)(r,{class:"bg-primary text-white q-pa-sm",align:"center"},{default:(0,o.w5)((()=>[x])),_:1}),(0,o.Wm)(r,null,{default:(0,o.w5)((()=>[(0,o.Wm)("div",Z,[(0,o.Wm)("div",D,[(0,o.Wm)("div",E,[(0,o.Wm)(s,{filled:"",modelValue:a.dataset,"onUpdate:modelValue":t[1]||(t[1]=e=>a.dataset=e),options:a.ALL_DATASETS,label:"Datasets",style:{width:"150px"}},null,8,["modelValue","options"]),(0,o.Wm)(s,{filled:"",modelValue:a.model,"onUpdate:modelValue":t[2]||(t[2]=e=>a.model=e),options:a.ALL_MODELS,label:"Model",style:{width:"150px"}},null,8,["modelValue","options"])]),j,(0,o.Wm)("div",F,[((0,o.wg)(!0),(0,o.j4)(o.HY,null,(0,o.Ko)(a.ALL_ENTS,((e,n)=>((0,o.wg)(),(0,o.j4)(d,{modelValue:a.ents,"onUpdate:modelValue":t[3]||(t[3]=e=>a.ents=e),"keep-color":"",key:n,val:e.val,label:e.label,color:e.color},null,8,["modelValue","val","label","color"])))),128))]),(0,o.Wm)(u,{color:"primary",label:"Select All",onClick:a.onSelectALL},null,8,["onClick"]),(0,o.Wm)(u,{color:"secondary",label:"Default",onClick:a.onSelectDefault,class:"q-ma-md"},null,8,["onClick"]),(0,o.Wm)(u,{color:"primary",label:"Reset",flat:"",onClick:a.onResetLabel,class:"q-ma-md"},null,8,["onClick"])]),(0,o.Wm)(c,{vertical:""}),(0,o.Wm)("div",Q,[(0,o.Wm)("div",null,[(0,o.Wm)(m,{label:"Auto Suggestion",modelValue:a.showConfidence,"onUpdate:modelValue":t[4]||(t[4]=e=>a.showConfidence=e)},null,8,["modelValue"]),a.showConfidence?((0,o.wg)(),(0,o.j4)(f,{key:0},{default:(0,o.w5)((()=>[(0,o.Wm)(p,{side:""},{default:(0,o.w5)((()=>[R])),_:1}),(0,o.Wm)(p,null,{default:(0,o.w5)((()=>[(0,o.Wm)(g,{modelValue:a.autoSuggestStrength,"onUpdate:modelValue":t[5]||(t[5]=e=>a.autoSuggestStrength=e),min:0,max:100,label:""},null,8,["modelValue"])])),_:1}),(0,o.Wm)(p,{side:""},{default:(0,o.w5)((()=>[T])),_:1})])),_:1})):(0,o.kq)("",!0)]),(0,o.Wm)("div",null,[(0,o.Wm)("div",U,[(0,o.Wm)(m,{label:"Active Learning",modelValue:a.activeLearningOn,"onUpdate:modelValue":t[6]||(t[6]=e=>a.activeLearningOn=e)},null,8,["modelValue"]),a.activeLearningOn?((0,o.wg)(),(0,o.j4)(s,{key:0,filled:"",modelValue:a.al,"onUpdate:modelValue":t[7]||(t[7]=e=>a.al=e),options:a.ALL_ALS,label:"AL Algorithm",style:{width:"150px"}},null,8,["modelValue","options"])):(0,o.kq)("",!0)])]),(0,o.Wm)("div",O,[(0,o.Wm)("div",M,[(0,o.Wm)(u,{color:"primary",label:"start",onClick:a.onStartAnnotation,class:"q-ma-md"},null,8,["onClick"])])]),a.startAnnotation?((0,o.wg)(),(0,o.j4)("div",P,[(0,o.Wm)(c,{horizontal:""}),(0,o.Wm)("div",z,[(0,o.Wm)(m,{label:"Early Phase (Demo Only)",modelValue:a.earlyPhaseOn,"onUpdate:modelValue":t[8]||(t[8]=e=>a.earlyPhaseOn=e)},null,8,["modelValue"])])])):(0,o.kq)("",!0)])])])),_:1})])),_:1})}var I=n(1959);const B={setup(){const e=(0,r.Z)(),t=(0,s.oR)(),n=(0,o.Fl)({get:()=>t.state.annotationNer.earlyPhaseOn,set:e=>{t.commit("annotationNer/updateEarlyPhaseOn",e)}}),a=(0,o.Fl)({get:()=>t.state.annotationNer.activeLearningOn,set:e=>{t.commit("annotationNer/updateActiveLearningOn",e)}}),l=(0,o.Fl)({get:()=>t.state.annotationNer.showConfidence,set:e=>{t.commit("annotationNer/updateShowConfidence",e)}}),i=(0,o.Fl)({get:()=>t.state.annotationNer.autoSuggestStrength,set:e=>{t.commit("annotationNer/updateAutoSuggestStrength",e)}}),d=(0,o.Fl)({get:()=>t.state.annotationNer.tradeoff,set:e=>{t.commit("annotationNer/updateTradeoff",e)}}),u=(0,o.Fl)((()=>t.state.annotationNer.startAnnotation)),c=t.state.annotationNer.ALL_MODELS,m=t.state.annotationNer.ALL_DATASETS,p=t.state.annotationNer.ALL_ALS,g=t.state.annotationNer.ALL_ENTS,f=(0,I.iH)(null),v=(0,o.Fl)({get:()=>t.state.annotationNer.text,set:e=>{t.commit("annotationNer/updateText",e)}}),k=(0,o.Fl)({get:()=>t.state.annotationNer.ents,set:e=>{t.commit("annotationNer/updateEnts",e)}}),w=(0,o.Fl)({get:()=>t.state.annotationNer.model,set:e=>{t.commit("annotationNer/updateModel",e)}}),N=(0,o.Fl)({get:()=>t.state.annotationNer.dataset,set:e=>{t.commit("annotationNer/updateDataset",e)}}),L=(0,o.Fl)({get:()=>t.state.annotationNer.al,set:e=>{t.commit("annotationNer/updateAL",e)}}),S=(0,o.Fl)((()=>t.state.annotationNer.result)),A=[e=>e&&e.length>0||"Please type something to analyze!",e=>e&&e.length<1500||"Text too long"];function y(){k.value=t.getters["annotationNer/getAllEnts"]}function h(){k.value=t.getters["annotationNer/getDefaultEnts"]}function C(){k.value=[]}function W(){t.commit("annotationNer/updateStartAnnotation",!0),t.dispatch("annotationNer/getDataset")}function b(){f.value.validate(),f.value.hasError?e.notify({color:"negative",message:"No content to analyze"}):e.notify({icon:"done",color:"positive",message:"Send to server for analyze"}),t.dispatch("annotationNer/analyzeText",{textInput:v.value})}function q(){v.value=null,f.value.resetValidation()}return{earlyPhaseOn:n,activeLearningOn:a,showConfidence:l,autoSuggestStrength:i,tradeoff:d,text:v,textRef:f,textRules:A,result:S,ents:k,model:w,dataset:N,al:L,startAnnotation:u,ALL_ENTS:g,ALL_MODELS:c,ALL_DATASETS:m,ALL_ALS:p,onSelectALL:y,onSelectDefault:h,onResetLabel:C,onStartAnnotation:W,onSubmit:b,onReset:q}}};var K=n(5987),X=n(5735),Y=n(8886),G=n(3414),J=n(2035),$=n(2064);B.render=H;const ee=B;y()(B,"components",{QCard:W.Z,QCardSection:b.Z,QSelect:K.Z,QCheckbox:X.Z,QBtn:N.Z,QSeparator:_.Z,QToggle:Y.Z,QItem:G.Z,QItemSection:J.Z,QSlider:$.Z});const te={components:{NerAnnotationRender:V,NerConfiguration:ee},setup(){(0,r.Z)();const e=(0,s.oR)(),t=(0,o.Fl)((()=>e.state.annotationNer.startAnnotation));return{startAnnotation:t}}};var ne=n(4379);te.render=i,te.__scopeId="data-v-060cdd2e";const oe=te;y()(te,"components",{QPage:ne.Z,QCard:W.Z})}}]); -------------------------------------------------------------------------------- /frontend/dist/spa/js/470.5463883d.js: -------------------------------------------------------------------------------- 1 | "use strict";(self["webpackChunkDANER"]=self["webpackChunkDANER"]||[]).push([[470],{3470:(e,a,t)=>{t.r(a),t.d(a,{default:()=>j});var l=t(3673),o=t(2323),n=t(8880);const u=(0,l.Uk)(" DANER ");function r(e,a,t,r,i,m){const p=(0,l.up)("q-btn"),s=(0,l.up)("q-toolbar-title"),d=(0,l.up)("q-input"),c=(0,l.up)("q-toolbar"),b=(0,l.up)("q-header"),w=(0,l.up)("q-icon"),f=(0,l.up)("q-item-section"),Z=(0,l.up)("q-item-label"),Q=(0,l.up)("q-item"),g=(0,l.up)("q-separator"),q=(0,l.up)("q-list"),W=(0,l.up)("q-scroll-area"),v=(0,l.up)("q-drawer"),_=(0,l.up)("router-view"),h=(0,l.up)("q-page-container"),k=(0,l.up)("q-route-tab"),L=(0,l.up)("q-tabs"),R=(0,l.up)("q-footer"),y=(0,l.up)("q-layout"),U=(0,l.Q2)("ripple");return(0,l.wg)(),(0,l.j4)(y,{view:"hHh Lpr lff"},{default:(0,l.w5)((()=>[(0,l.Wm)(b,{bordered:"",class:"bg-primary text-white","height-hint":"98"},{default:(0,l.w5)((()=>[(0,l.Wm)(c,null,{default:(0,l.w5)((()=>[(0,l.Wm)(p,{flat:"",dense:"",round:"",icon:"menu","aria-label":"Menu",onClick:e.toggleLeftDrawer},null,8,["onClick"]),(0,l.Wm)(s,null,{default:(0,l.w5)((()=>[u])),_:1}),(0,l.Wm)(d,{standout:"",autogrow:"",modelValue:e.baseURL,"onUpdate:modelValue":a[1]||(a[1]=a=>e.baseURL=a),label:"baseURL",type:"url"},null,8,["modelValue"])])),_:1})])),_:1}),(0,l.Wm)(v,{modelValue:e.leftDrawerOpen,"onUpdate:modelValue":a[2]||(a[2]=a=>e.leftDrawerOpen=a),"show-if-above":"",mini:e.miniState,onMouseover:a[3]||(a[3]=a=>e.miniState=!1),onMouseout:a[4]||(a[4]=a=>e.miniState=!0),"mini-to-overlay":"",width:200,breakpoint:767,bordered:"",class:"bg-grey-1"},{default:(0,l.w5)((()=>[(0,l.Wm)(W,{class:"fit"},{default:(0,l.w5)((()=>[(0,l.Wm)(q,{padding:""},{default:(0,l.w5)((()=>[((0,l.wg)(!0),(0,l.j4)(l.HY,null,(0,l.Ko)(e.navs,(e=>(0,l.wy)(((0,l.wg)(),(0,l.j4)(Q,{key:e.label,to:e.to,exact:"",clickable:""},{default:(0,l.w5)((()=>[(0,l.Wm)(f,{avatar:""},{default:(0,l.w5)((()=>[(0,l.Wm)(w,{name:e.icon},null,8,["name"])])),_:2},1024),(0,l.Wm)(f,null,{default:(0,l.w5)((()=>[(0,l.Wm)(Z,null,{default:(0,l.w5)((()=>[(0,l.Uk)((0,o.zw)(e.label),1)])),_:2},1024)])),_:2},1024)])),_:2},1032,["to"])),[[U]]))),128)),(0,l.Wm)(g,{dark:""})])),_:1})])),_:1})])),_:1},8,["modelValue","mini"]),(0,l.Wm)(h,null,{default:(0,l.w5)((()=>[(0,l.Wm)(n.uT,{mode:"out-in"},{default:(0,l.w5)((()=>[(0,l.Wm)(_)])),_:1})])),_:1}),(0,l.Wm)(R,null,{default:(0,l.w5)((()=>[(0,l.Wm)(L,null,{default:(0,l.w5)((()=>[((0,l.wg)(!0),(0,l.j4)(l.HY,null,(0,l.Ko)(e.navs,(e=>((0,l.wg)(),(0,l.j4)(k,{key:e.label,to:e.to,icon:e.icon,label:e.label},null,8,["to","icon","label"])))),128))])),_:1})])),_:1})])),_:1})}var i=t(1959),m=t(7874);const p=[{label:"Service",icon:"launch",to:"/service"},{label:"Annotation",icon:"touch_app",to:"/annotation"}],s=(0,l.aZ)({name:"MainLayout",setup(){const e=(0,m.oR)(),a=(0,i.iH)(!1),t=(0,i.iH)(!0),o=(0,i.iH)(null),n=[],u=(0,l.Fl)({get:()=>e.state.baseURL,set:a=>{e.commit("updateBaseURL",a)}});return{baseURL:u,navs:p,tabs:n,leftDrawerOpen:a,miniState:t,currentPath:o,toggleLeftDrawer(){a.value=!a.value}}}});var d=t(9214),c=t(3812),b=t(9570),w=t(8240),f=t(3747),Z=t(4842),Q=t(2901),g=t(7704),q=t(7011),W=t(3414),v=t(2035),_=t(4554),h=t(2350),k=t(5869),L=t(2652),R=t(1007),y=t(7547),U=t(8408),D=t(1762),S=t(2770),H=t(6489),T=t(7518),V=t.n(T);s.render=r;const j=s;V()(s,"components",{QLayout:d.Z,QHeader:c.Z,QToolbar:b.Z,QBtn:w.Z,QToolbarTitle:f.Z,QInput:Z.Z,QDrawer:Q.Z,QScrollArea:g.Z,QList:q.Z,QItem:W.Z,QItemSection:v.Z,QIcon:_.Z,QItemLabel:h.Z,QSeparator:k.Z,QPageContainer:L.Z,QPageSticky:R.Z,QTabs:y.Z,QTab:U.Z,QFooter:D.Z,QRouteTab:S.Z}),V()(s,"directives",{Ripple:H.Z})}}]); -------------------------------------------------------------------------------- /frontend/dist/spa/js/54.be0d8d28.js: -------------------------------------------------------------------------------- 1 | "use strict";(self["webpackChunkDANER"]=self["webpackChunkDANER"]||[]).push([[54],{2054:(e,n,a)=>{a.r(n),a.d(n,{default:()=>r});var t=a(3673);const d=(0,t.HX)("data-v-326ed7b0");(0,t.dD)("data-v-326ed7b0");const s=(0,t.Wm)("p",null,"403",-1);(0,t.Cn)();const c=d(((e,n,a,c,u,l)=>{const o=(0,t.up)("q-page");return(0,t.wg)(),(0,t.j4)(o,null,{default:d((()=>[s])),_:1})})),u={name:""};var l=a(4379),o=a(7518),p=a.n(o);u.render=c,u.__scopeId="data-v-326ed7b0";const r=u;p()(u,"components",{QPage:l.Z})}}]); -------------------------------------------------------------------------------- /frontend/dist/spa/js/707.97e80e68.js: -------------------------------------------------------------------------------- 1 | "use strict";(self["webpackChunkDANER"]=self["webpackChunkDANER"]||[]).push([[707],{4707:(e,a,t)=>{t.r(a),t.d(a,{default:()=>D});var l=t(3673),n=t(2323);const s=(0,l.HX)("data-v-5404722e");(0,l.dD)("data-v-5404722e");const r={class:"lm"},o={class:"row items-center no-wrap"},d=(0,l.Wm)("div",{class:"col"},[(0,l.Wm)("div",{class:"text-h6"},"BERT"),(0,l.Wm)("div",{class:"text-subtitle2"},"Dec 12, 2019")],-1),i={class:"col-auto"},c=(0,l.Uk)("Remove Card"),u=(0,l.Uk)("Send Feedback"),m=(0,l.Uk)("Share"),f=(0,l.Uk)("Finetune"),p=(0,l.Uk)("Deploy"),g={class:"row items-center no-wrap"},W=(0,l.Wm)("div",{class:"col"},[(0,l.Wm)("div",{class:"text-h6"},"GPT3"),(0,l.Wm)("div",{class:"text-subtitle2"},"May 28, 2020")],-1),h={class:"col-auto"},b=(0,l.Uk)("Remove Card"),_=(0,l.Uk)("Send Feedback"),v=(0,l.Uk)("Share"),k=(0,l.Uk)("Finetune"),w=(0,l.Uk)("Deploy");(0,l.Cn)();const y=s(((e,a,t,y,T,E)=>{const G=(0,l.up)("q-item-section"),B=(0,l.up)("q-item"),R=(0,l.up)("q-list"),P=(0,l.up)("q-menu"),U=(0,l.up)("q-btn"),q=(0,l.up)("q-card-section"),Q=(0,l.up)("q-separator"),Z=(0,l.up)("q-card-actions"),C=(0,l.up)("q-card"),S=(0,l.up)("q-page");return(0,l.wg)(),(0,l.j4)(S,{padding:""},{default:s((()=>[(0,l.Wm)("div",r,[(0,l.Wm)(C,{bordered:"",class:"my-card"},{default:s((()=>[(0,l.Wm)(q,{class:"bg-primary"},{default:s((()=>[(0,l.Wm)("div",o,[d,(0,l.Wm)("div",i,[(0,l.Wm)(U,{color:"grey-7",round:"",flat:"",icon:"more_vert"},{default:s((()=>[(0,l.Wm)(P,{cover:"","auto-close":""},{default:s((()=>[(0,l.Wm)(R,null,{default:s((()=>[(0,l.Wm)(B,{clickable:""},{default:s((()=>[(0,l.Wm)(G,null,{default:s((()=>[c])),_:1})])),_:1}),(0,l.Wm)(B,{clickable:""},{default:s((()=>[(0,l.Wm)(G,null,{default:s((()=>[u])),_:1})])),_:1}),(0,l.Wm)(B,{clickable:""},{default:s((()=>[(0,l.Wm)(G,null,{default:s((()=>[m])),_:1})])),_:1})])),_:1})])),_:1})])),_:1})])])])),_:1}),(0,l.Wm)(q,{class:"bg-grey-1"},{default:s((()=>[(0,l.Uk)((0,n.zw)(y.bert),1)])),_:1}),(0,l.Wm)(Q),(0,l.Wm)(Z,null,{default:s((()=>[(0,l.Wm)(U,{flat:"","no-caps":""},{default:s((()=>[f])),_:1}),(0,l.Wm)(U,{flat:"","no-caps":""},{default:s((()=>[p])),_:1})])),_:1})])),_:1})]),(0,l.Wm)("div",null,[(0,l.Wm)(C,{bordered:"",class:"my-card"},{default:s((()=>[(0,l.Wm)(q,{class:"bg-secondary"},{default:s((()=>[(0,l.Wm)("div",g,[W,(0,l.Wm)("div",h,[(0,l.Wm)(U,{color:"grey-7",round:"",flat:"",icon:"more_vert"},{default:s((()=>[(0,l.Wm)(P,{cover:"","auto-close":""},{default:s((()=>[(0,l.Wm)(R,null,{default:s((()=>[(0,l.Wm)(B,{clickable:""},{default:s((()=>[(0,l.Wm)(G,null,{default:s((()=>[b])),_:1})])),_:1}),(0,l.Wm)(B,{clickable:""},{default:s((()=>[(0,l.Wm)(G,null,{default:s((()=>[_])),_:1})])),_:1}),(0,l.Wm)(B,{clickable:""},{default:s((()=>[(0,l.Wm)(G,null,{default:s((()=>[v])),_:1})])),_:1})])),_:1})])),_:1})])),_:1})])])])),_:1}),(0,l.Wm)(q,{class:"bg-grey-1"},{default:s((()=>[(0,l.Uk)((0,n.zw)(y.gpt3),1)])),_:1}),(0,l.Wm)(Q),(0,l.Wm)(Z,null,{default:s((()=>[(0,l.Wm)(U,{flat:"","no-caps":""},{default:s((()=>[k])),_:1}),(0,l.Wm)(U,{flat:"","no-caps":""},{default:s((()=>[w])),_:1})])),_:1})])),_:1})])])),_:1})})),T={setup(){return{bert:"Bidirectional Encoder Representations from Transformers (BERT) is a Transformer-based machine learning technique for natural language processing (NLP) pre-training developed by Google. BERT was created and published in 2018 by Jacob Devlin and his colleagues from Google.[1][2] As of 2019, Google has been leveraging BERT to better understand user searches.[3]\n\nThe original English-language BERT has two models:[1] (1) the BERTBASE: 12 Encoders with 12 bidirectional self-attention heads, and (2) the BERTLARGE: 24 Encoders with 16 bidirectional self-attention heads. Both models are pre-trained from unlabeled data extracted from the BooksCorpus[4] with 800M words and English Wikipedia with 2,500M words",gpt3:"Generative Pre-trained Transformer 3 (GPT-3) is an autoregressive language model that uses deep learning to produce human-like text. It is the third-generation language prediction model in the GPT-n series (and the successor to GPT-2) created by OpenAI, a San Francisco-based artificial intelligence research laboratory.[2] GPT-3's full version has a capacity of 175 billion machine learning parameters. GPT-3, which was introduced in May 2020, and was in beta testing as of July 2020,[3] is part of a trend in natural language processing (NLP) systems of pre-trained language representations.[1] Before the release of GPT-3, the largest language model was Microsoft's Turing NLG, introduced in February 2020, with a capacity of 17 billion parameters - less than a tenth of GPT-3's.[4]"}}};var E=t(4379),G=t(151),B=t(5589),R=t(8240),P=t(811),U=t(7011),q=t(3414),Q=t(2035),Z=t(5869),C=t(9367),S=t(7518),A=t.n(S);T.render=y,T.__scopeId="data-v-5404722e";const D=T;A()(T,"components",{QPage:E.Z,QCard:G.Z,QCardSection:B.Z,QBtn:R.Z,QMenu:P.Z,QList:U.Z,QItem:q.Z,QItemSection:Q.Z,QSeparator:Z.Z,QCardActions:C.Z})}}]); -------------------------------------------------------------------------------- /frontend/dist/spa/js/78.95a2621f.js: -------------------------------------------------------------------------------- 1 | "use strict";(self["webpackChunkDANER"]=self["webpackChunkDANER"]||[]).push([[78],{6078:(e,n,t)=>{t.r(n),t.d(n,{default:()=>p});var u=t(3673);const a=(0,u.Wm)("p",null,"Model Detail",-1);function l(e,n,t,l,s,c){const o=(0,u.up)("q-page");return(0,u.wg)(),(0,u.j4)(o,null,{default:(0,u.w5)((()=>[a])),_:1})}const s={name:""};var c=t(4379),o=t(7518),r=t.n(o);s.render=l;const p=s;r()(s,"components",{QPage:c.Z})}}]); -------------------------------------------------------------------------------- /frontend/dist/spa/js/839.6f88682d.js: -------------------------------------------------------------------------------- 1 | "use strict";(self["webpackChunkDANER"]=self["webpackChunkDANER"]||[]).push([[839],{8839:(a,e,t)=>{t.r(e),t.d(e,{default:()=>F});var l=t(3673),d=t(2323);const s=(0,l.HX)("data-v-d29d7602");(0,l.dD)("data-v-d29d7602");const u={class:"lm"},c={class:"row items-center no-wrap"},n=(0,l.Wm)("div",{class:"col"},[(0,l.Wm)("div",{class:"text-h6"},"CONLL 2003"),(0,l.Wm)("div",{class:"text-subtitle2"},"News")],-1),o={class:"col-auto"},m=(0,l.Uk)("Remove Card"),r=(0,l.Uk)("Send Feedback"),i=(0,l.Uk)("Share"),W=(0,l.Uk)("Investigation"),f=(0,l.Uk)("Annoation"),_=(0,l.Uk)("Quality Control"),p={class:"row items-center no-wrap"},k=(0,l.Wm)("div",{class:"col"},[(0,l.Wm)("div",{class:"text-h6"},"GUM-3.1.0"),(0,l.Wm)("div",{class:"text-subtitle2"},"Wiki")],-1),v={class:"col-auto"},b=(0,l.Uk)("Remove Card"),g=(0,l.Uk)("Send Feedback"),U=(0,l.Uk)("Share"),Q=(0,l.Uk)("Investigation"),C=(0,l.Uk)("Annoation"),q=(0,l.Uk)("Quality Control");(0,l.Cn)();const w=s(((a,e,t,w,y,Z)=>{const h=(0,l.up)("q-item-section"),D=(0,l.up)("q-item"),S=(0,l.up)("q-list"),A=(0,l.up)("q-menu"),I=(0,l.up)("q-btn"),x=(0,l.up)("q-card-section"),N=(0,l.up)("q-separator"),R=(0,l.up)("q-card-actions"),L=(0,l.up)("q-card"),z=(0,l.up)("q-page");return(0,l.wg)(),(0,l.j4)(z,{padding:""},{default:s((()=>[(0,l.Wm)("div",u,[(0,l.Wm)(L,{bordered:"",class:"my-card"},{default:s((()=>[(0,l.Wm)(x,{class:"bg-primary"},{default:s((()=>[(0,l.Wm)("div",c,[n,(0,l.Wm)("div",o,[(0,l.Wm)(I,{color:"grey-7",round:"",flat:"",icon:"more_vert"},{default:s((()=>[(0,l.Wm)(A,{cover:"","auto-close":""},{default:s((()=>[(0,l.Wm)(S,null,{default:s((()=>[(0,l.Wm)(D,{clickable:""},{default:s((()=>[(0,l.Wm)(h,null,{default:s((()=>[m])),_:1})])),_:1}),(0,l.Wm)(D,{clickable:""},{default:s((()=>[(0,l.Wm)(h,null,{default:s((()=>[r])),_:1})])),_:1}),(0,l.Wm)(D,{clickable:""},{default:s((()=>[(0,l.Wm)(h,null,{default:s((()=>[i])),_:1})])),_:1})])),_:1})])),_:1})])),_:1})])])])),_:1}),(0,l.Wm)(x,{class:"bg-grey-1"},{default:s((()=>[(0,l.Uk)((0,d.zw)(w.bert),1)])),_:1}),(0,l.Wm)(N),(0,l.Wm)(R,null,{default:s((()=>[(0,l.Wm)(I,{flat:"","no-caps":""},{default:s((()=>[W])),_:1}),(0,l.Wm)(I,{flat:"","no-caps":""},{default:s((()=>[f])),_:1}),(0,l.Wm)(I,{flat:"","no-caps":""},{default:s((()=>[_])),_:1})])),_:1})])),_:1})]),(0,l.Wm)("div",null,[(0,l.Wm)(L,{bordered:"",class:"my-card"},{default:s((()=>[(0,l.Wm)(x,{class:"bg-secondary"},{default:s((()=>[(0,l.Wm)("div",p,[k,(0,l.Wm)("div",v,[(0,l.Wm)(I,{color:"grey-7",round:"",flat:"",icon:"more_vert"},{default:s((()=>[(0,l.Wm)(A,{cover:"","auto-close":""},{default:s((()=>[(0,l.Wm)(S,null,{default:s((()=>[(0,l.Wm)(D,{clickable:""},{default:s((()=>[(0,l.Wm)(h,null,{default:s((()=>[b])),_:1})])),_:1}),(0,l.Wm)(D,{clickable:""},{default:s((()=>[(0,l.Wm)(h,null,{default:s((()=>[g])),_:1})])),_:1}),(0,l.Wm)(D,{clickable:""},{default:s((()=>[(0,l.Wm)(h,null,{default:s((()=>[U])),_:1})])),_:1})])),_:1})])),_:1})])),_:1})])])])),_:1}),(0,l.Wm)(x,{class:"bg-grey-1"},{default:s((()=>[(0,l.Uk)((0,d.zw)(w.gpt3),1)])),_:1}),(0,l.Wm)(N),(0,l.Wm)(R,null,{default:s((()=>[(0,l.Wm)(I,{flat:"","no-caps":""},{default:s((()=>[Q])),_:1}),(0,l.Wm)(I,{flat:"","no-caps":""},{default:s((()=>[C])),_:1}),(0,l.Wm)(I,{flat:"","no-caps":""},{default:s((()=>[q])),_:1})])),_:1})])),_:1})])])),_:1})})),y={setup(){return{bert:"Dataset Details",gpt3:"Dataset Details"}}};var Z=t(4379),h=t(151),D=t(5589),S=t(8240),A=t(811),I=t(7011),x=t(3414),N=t(2035),R=t(5869),L=t(9367),z=t(7518),E=t.n(z);y.render=w,y.__scopeId="data-v-d29d7602";const F=y;E()(y,"components",{QPage:Z.Z,QCard:h.Z,QCardSection:D.Z,QBtn:S.Z,QMenu:A.Z,QList:I.Z,QItem:x.Z,QItemSection:N.Z,QSeparator:R.Z,QCardActions:L.Z})}}]); -------------------------------------------------------------------------------- /frontend/dist/spa/js/84.668bbfad.js: -------------------------------------------------------------------------------- 1 | "use strict";(self["webpackChunkDANER"]=self["webpackChunkDANER"]||[]).push([[84],{7084:(e,n,s)=>{s.r(n),s.d(n,{default:()=>p});var t=s(3673);const u=(0,t.Wm)("p",null,"User Register",-1);function r(e,n,s,r,a,c){const l=(0,t.up)("q-page");return(0,t.wg)(),(0,t.j4)(l,null,{default:(0,t.w5)((()=>[u])),_:1})}const a={name:""};var c=s(4379),l=s(7518),o=s.n(l);a.render=r;const p=a;o()(a,"components",{QPage:c.Z})}}]); -------------------------------------------------------------------------------- /frontend/dist/spa/js/846.373cbc5a.js: -------------------------------------------------------------------------------- 1 | "use strict";(self["webpackChunkDANER"]=self["webpackChunkDANER"]||[]).push([[846],{9846:(a,e,c)=>{c.r(e),c.d(e,{default:()=>r});var n=c(3673);const t=(0,n.HX)("data-v-7caeac50");(0,n.dD)("data-v-7caeac50");const s=(0,n.Wm)("p",null,"404",-1);(0,n.Cn)();const u=t(((a,e,c,u,d,l)=>{const o=(0,n.up)("q-page");return(0,n.wg)(),(0,n.j4)(o,null,{default:t((()=>[s])),_:1})})),d={name:""};var l=c(4379),o=c(7518),p=c.n(o);d.render=u,d.__scopeId="data-v-7caeac50";const r=d;p()(d,"components",{QPage:l.Z})}}]); -------------------------------------------------------------------------------- /frontend/jsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "baseUrl": ".", 4 | "paths": { 5 | "src/*": [ 6 | "src/*" 7 | ], 8 | "app/*": [ 9 | "*" 10 | ], 11 | "components/*": [ 12 | "src/components/*" 13 | ], 14 | "layouts/*": [ 15 | "src/layouts/*" 16 | ], 17 | "pages/*": [ 18 | "src/pages/*" 19 | ], 20 | "assets/*": [ 21 | "src/assets/*" 22 | ], 23 | "boot/*": [ 24 | "src/boot/*" 25 | ], 26 | "vue$": [ 27 | "node_modules/vue/dist/vue.runtime.esm-bundler.js" 28 | ] 29 | } 30 | }, 31 | "exclude": [ 32 | "dist", 33 | ".quasar", 34 | "node_modules" 35 | ] 36 | } 37 | -------------------------------------------------------------------------------- /frontend/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "DANER", 3 | "version": "0.0.1", 4 | "description": "Data Annotation Tool for Name Entity Recognition Task", 5 | "productName": "DANER", 6 | "author": "yongchao97 ", 7 | "private": true, 8 | "scripts": { 9 | "lint": "eslint --ext .js,.vue ./", 10 | "test": "echo \"No test specified\" && exit 0" 11 | }, 12 | "dependencies": { 13 | "@quasar/extras": "^1.0.0", 14 | "axios": "^0.21.1", 15 | "babel-plugin-jsx": "^1.2.0", 16 | "core-js": "^3.6.5", 17 | "quasar": "^2.0.0-beta.1", 18 | "vuex": "^4.0.1" 19 | }, 20 | "devDependencies": { 21 | "@babel/eslint-parser": "^7.13.14", 22 | "@quasar/app": "^3.0.0-beta.1", 23 | "@vue/babel-plugin-jsx": "^1.0.6", 24 | "eslint": "^7.14.0", 25 | "eslint-config-prettier": "^8.1.0", 26 | "eslint-plugin-vue": "^7.0.0", 27 | "eslint-webpack-plugin": "^2.4.0" 28 | }, 29 | "browserslist": [ 30 | "last 10 Chrome versions", 31 | "last 10 Firefox versions", 32 | "last 4 Edge versions", 33 | "last 7 Safari versions", 34 | "last 8 Android versions", 35 | "last 8 ChromeAndroid versions", 36 | "last 8 FirefoxAndroid versions", 37 | "last 10 iOS versions", 38 | "last 5 Opera versions" 39 | ], 40 | "engines": { 41 | "node": ">= 12.22.1", 42 | "npm": ">= 6.13.4", 43 | "yarn": ">= 1.21.1" 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /frontend/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VectorInstitute/DANER/2b5feadda6c1d35ab7be09277339c490396bc49e/frontend/public/favicon.ico -------------------------------------------------------------------------------- /frontend/public/icons/favicon-128x128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VectorInstitute/DANER/2b5feadda6c1d35ab7be09277339c490396bc49e/frontend/public/icons/favicon-128x128.png -------------------------------------------------------------------------------- /frontend/public/icons/favicon-16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VectorInstitute/DANER/2b5feadda6c1d35ab7be09277339c490396bc49e/frontend/public/icons/favicon-16x16.png -------------------------------------------------------------------------------- /frontend/public/icons/favicon-32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VectorInstitute/DANER/2b5feadda6c1d35ab7be09277339c490396bc49e/frontend/public/icons/favicon-32x32.png -------------------------------------------------------------------------------- /frontend/public/icons/favicon-96x96.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VectorInstitute/DANER/2b5feadda6c1d35ab7be09277339c490396bc49e/frontend/public/icons/favicon-96x96.png -------------------------------------------------------------------------------- /frontend/quasar.conf.js: -------------------------------------------------------------------------------- 1 | /* 2 | * This file runs in a Node context (it's NOT transpiled by Babel), so use only 3 | * the ES6 features that are supported by your Node version. https://node.green/ 4 | */ 5 | 6 | // Configuration for your app 7 | // https://v2.quasar.dev/quasar-cli/quasar-conf-js 8 | 9 | /* eslint-env node */ 10 | const ESLintPlugin = require("eslint-webpack-plugin"); 11 | const { configure } = require("quasar/wrappers"); 12 | 13 | module.exports = configure(function (ctx) { 14 | return { 15 | // https://v2.quasar.dev/quasar-cli/supporting-ts 16 | supportTS: false, 17 | 18 | // https://v2.quasar.dev/quasar-cli/prefetch-feature 19 | // preFetch: true, 20 | 21 | // app boot file (/src/boot) 22 | // --> boot files are part of "main.js" 23 | // https://v2.quasar.dev/quasar-cli/boot-files 24 | boot: ["axios"], 25 | 26 | // https://v2.quasar.dev/quasar-cli/quasar-conf-js#Property%3A-css 27 | css: ["app.scss"], 28 | 29 | // https://github.com/quasarframework/quasar/tree/dev/extras 30 | extras: [ 31 | // 'ionicons-v4', 32 | // 'mdi-v5', 33 | // 'fontawesome-v5', 34 | // 'eva-icons', 35 | // 'themify', 36 | // 'line-awesome', 37 | // 'roboto-font-latin-ext', // this or either 'roboto-font', NEVER both! 38 | 39 | "roboto-font", // optional, you are not bound to it 40 | "material-icons", // optional, you are not bound to it 41 | ], 42 | 43 | // Full list of options: https://v2.quasar.dev/quasar-cli/quasar-conf-js#Property%3A-build 44 | build: { 45 | vueRouterMode: "hash", // available values: 'hash', 'history' 46 | 47 | // transpile: false, 48 | 49 | // Add dependencies for transpiling with Babel (Array of string/regex) 50 | // (from node_modules, which are by default not transpiled). 51 | // Applies only if "transpile" is set to true. 52 | // transpileDependencies: [], 53 | 54 | // rtl: true, // https://v2.quasar.dev/options/rtl-support 55 | // preloadChunks: true, 56 | // showProgress: false, 57 | // gzip: true, 58 | // analyze: true, 59 | 60 | // Options below are automatically set depending on the env, set them if you want to override 61 | // extractCSS: false, 62 | 63 | // https://v2.quasar.dev/quasar-cli/handling-webpack 64 | // "chain" is a webpack-chain object https://github.com/neutrinojs/webpack-chain 65 | chainWebpack(chain) { 66 | chain 67 | .plugin("eslint-webpack-plugin") 68 | .use(ESLintPlugin, [{ extensions: ["js", "vue"] }]); 69 | }, 70 | }, 71 | 72 | // Full list of options: https://v2.quasar.dev/quasar-cli/quasar-conf-js#Property%3A-devServer 73 | devServer: { 74 | https: false, 75 | port: 8080, 76 | open: true, // opens browser window automatically 77 | }, 78 | 79 | // https://v2.quasar.dev/quasar-cli/quasar-conf-js#Property%3A-framework 80 | framework: { 81 | config: { 82 | notify: { 83 | /* look at QuasarConfOptions from the API card */ 84 | }, 85 | }, 86 | 87 | iconSet: "material-icons", // Quasar icon set 88 | lang: "en-US", // Quasar language pack 89 | 90 | // For special cases outside of where the auto-import stategy can have an impact 91 | // (like functional components as one of the examples), 92 | // you can manually specify Quasar components/directives to be available everywhere: 93 | // 94 | // components: [], 95 | // directives: [], 96 | 97 | // Quasar plugins 98 | plugins: ["Notify"], 99 | }, 100 | 101 | // animations: 'all', // --- includes all animations 102 | // https://v2.quasar.dev/options/animations 103 | animations: [], 104 | 105 | // https://v2.quasar.dev/quasar-cli/developing-ssr/configuring-ssr 106 | ssr: { 107 | pwa: false, 108 | 109 | // manualStoreHydration: true, 110 | // manualPostHydrationTrigger: true, 111 | 112 | prodPort: 3000, // The default port that the production server should use 113 | // (gets superseded if process.env.PORT is specified at runtime) 114 | 115 | maxAge: 1000 * 60 * 60 * 24 * 30, 116 | // Tell browser when a file from the server should expire from cache (in ms) 117 | 118 | chainWebpackWebserver(chain) { 119 | chain 120 | .plugin("eslint-webpack-plugin") 121 | .use(ESLintPlugin, [{ extensions: ["js"] }]); 122 | }, 123 | 124 | middlewares: [ 125 | ctx.prod ? "compression" : "", 126 | "render", // keep this as last one 127 | ], 128 | }, 129 | 130 | // https://v2.quasar.dev/quasar-cli/developing-pwa/configuring-pwa 131 | pwa: { 132 | workboxPluginMode: "GenerateSW", // 'GenerateSW' or 'InjectManifest' 133 | workboxOptions: {}, // only for GenerateSW 134 | 135 | // for the custom service worker ONLY (/src-pwa/custom-service-worker.[js|ts]) 136 | // if using workbox in InjectManifest mode 137 | chainWebpackCustomSW(chain) { 138 | chain 139 | .plugin("eslint-webpack-plugin") 140 | .use(ESLintPlugin, [{ extensions: ["js"] }]); 141 | }, 142 | 143 | manifest: { 144 | name: `Nera`, 145 | short_name: `Nera`, 146 | description: `Data Annotation Tool for Name Entity Recognition Task`, 147 | display: "standalone", 148 | orientation: "portrait", 149 | background_color: "#ffffff", 150 | theme_color: "#027be3", 151 | icons: [ 152 | { 153 | src: "icons/icon-128x128.png", 154 | sizes: "128x128", 155 | type: "image/png", 156 | }, 157 | { 158 | src: "icons/icon-192x192.png", 159 | sizes: "192x192", 160 | type: "image/png", 161 | }, 162 | { 163 | src: "icons/icon-256x256.png", 164 | sizes: "256x256", 165 | type: "image/png", 166 | }, 167 | { 168 | src: "icons/icon-384x384.png", 169 | sizes: "384x384", 170 | type: "image/png", 171 | }, 172 | { 173 | src: "icons/icon-512x512.png", 174 | sizes: "512x512", 175 | type: "image/png", 176 | }, 177 | ], 178 | }, 179 | }, 180 | 181 | // Full list of options: https://v2.quasar.dev/quasar-cli/developing-cordova-apps/configuring-cordova 182 | cordova: { 183 | // noIosLegacyBuildFlag: true, // uncomment only if you know what you are doing 184 | }, 185 | 186 | // Full list of options: https://v2.quasar.dev/quasar-cli/developing-capacitor-apps/configuring-capacitor 187 | capacitor: { 188 | hideSplashscreen: true, 189 | }, 190 | 191 | // Full list of options: https://v2.quasar.dev/quasar-cli/developing-electron-apps/configuring-electron 192 | electron: { 193 | bundler: "packager", // 'packager' or 'builder' 194 | 195 | packager: { 196 | // https://github.com/electron-userland/electron-packager/blob/master/docs/api.md#options 197 | // OS X / Mac App Store 198 | // appBundleId: '', 199 | // appCategoryType: '', 200 | // osxSign: '', 201 | // protocol: 'myapp://path', 202 | // Windows only 203 | // win32metadata: { ... } 204 | }, 205 | 206 | builder: { 207 | // https://www.electron.build/configuration/configuration 208 | 209 | appId: "nera", 210 | }, 211 | 212 | // "chain" is a webpack-chain object https://github.com/neutrinojs/webpack-chain 213 | chainWebpackMain(chain) { 214 | chain 215 | .plugin("eslint-webpack-plugin") 216 | .use(ESLintPlugin, [{ extensions: ["js"] }]); 217 | }, 218 | 219 | // "chain" is a webpack-chain object https://github.com/neutrinojs/webpack-chain 220 | chainWebpackPreload(chain) { 221 | chain 222 | .plugin("eslint-webpack-plugin") 223 | .use(ESLintPlugin, [{ extensions: ["js"] }]); 224 | }, 225 | }, 226 | }; 227 | }); 228 | -------------------------------------------------------------------------------- /frontend/src/App.vue: -------------------------------------------------------------------------------- 1 | 4 | 11 | -------------------------------------------------------------------------------- /frontend/src/assets/403.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VectorInstitute/DANER/2b5feadda6c1d35ab7be09277339c490396bc49e/frontend/src/assets/403.png -------------------------------------------------------------------------------- /frontend/src/assets/404.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VectorInstitute/DANER/2b5feadda6c1d35ab7be09277339c490396bc49e/frontend/src/assets/404.png -------------------------------------------------------------------------------- /frontend/src/assets/500.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VectorInstitute/DANER/2b5feadda6c1d35ab7be09277339c490396bc49e/frontend/src/assets/500.png -------------------------------------------------------------------------------- /frontend/src/assets/no_data.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VectorInstitute/DANER/2b5feadda6c1d35ab7be09277339c490396bc49e/frontend/src/assets/no_data.png -------------------------------------------------------------------------------- /frontend/src/assets/quasar-logo-vertical.svg: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 8 | 10 | 12 | 14 | 15 | -------------------------------------------------------------------------------- /frontend/src/assets/vectorHorizontal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VectorInstitute/DANER/2b5feadda6c1d35ab7be09277339c490396bc49e/frontend/src/assets/vectorHorizontal.png -------------------------------------------------------------------------------- /frontend/src/assets/vectorLogo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VectorInstitute/DANER/2b5feadda6c1d35ab7be09277339c490396bc49e/frontend/src/assets/vectorLogo.png -------------------------------------------------------------------------------- /frontend/src/assets/vectorVertical.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VectorInstitute/DANER/2b5feadda6c1d35ab7be09277339c490396bc49e/frontend/src/assets/vectorVertical.png -------------------------------------------------------------------------------- /frontend/src/boot/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VectorInstitute/DANER/2b5feadda6c1d35ab7be09277339c490396bc49e/frontend/src/boot/.gitkeep -------------------------------------------------------------------------------- /frontend/src/boot/axios.js: -------------------------------------------------------------------------------- 1 | import { boot } from "quasar/wrappers"; 2 | import axios from "axios"; 3 | 4 | // Be careful when using SSR for cross-request state pollution 5 | // due to creating a Singleton instance here; 6 | // If any client changes this (global) instance, it might be a 7 | // good idea to move this instance creation inside of the 8 | // "export default () => {}" function below (which runs individually 9 | // for each client) 10 | // const api = axios.create({ baseURL: "http://127.0.0.1:5000/" }); 11 | const api = axios.create({ baseURL: "http://172.17.8.59:5000/" }); 12 | 13 | export default boot(({ app }) => { 14 | // for use inside Vue files (Options API) through this.$axios and this.$api 15 | 16 | app.config.globalProperties.$axios = axios; 17 | // ^ ^ ^ this will allow you to use this.$axios (for Vue Options API form) 18 | // so you won't necessarily have to import axios in each vue file 19 | 20 | app.config.globalProperties.$api = api; 21 | // ^ ^ ^ this will allow you to use this.$api (for Vue Options API form) 22 | // so you can easily perform requests against your app's API 23 | }); 24 | 25 | export { axios, api }; 26 | -------------------------------------------------------------------------------- /frontend/src/components/annotation/ner/NerAnnotationRender.vue: -------------------------------------------------------------------------------- 1 | 73 | 74 | 169 | 170 | 186 | -------------------------------------------------------------------------------- /frontend/src/components/annotation/ner/NerConfiguration.vue: -------------------------------------------------------------------------------- 1 | 125 | 126 | 287 | -------------------------------------------------------------------------------- /frontend/src/components/annotation/ner/TokenRender.vue: -------------------------------------------------------------------------------- 1 | 23 | 24 | 58 | 59 | 85 | -------------------------------------------------------------------------------- /frontend/src/components/service/ner/NerServiceRender.vue: -------------------------------------------------------------------------------- 1 | 20 | 21 | 67 | 68 | 95 | -------------------------------------------------------------------------------- /frontend/src/css/app.scss: -------------------------------------------------------------------------------- 1 | // app global css in SCSS form 2 | -------------------------------------------------------------------------------- /frontend/src/css/quasar.variables.scss: -------------------------------------------------------------------------------- 1 | // Quasar SCSS (& Sass) Variables 2 | // -------------------------------------------------- 3 | // To customize the look and feel of this app, you can override 4 | // the Sass/SCSS variables found in Quasar's source Sass/SCSS files. 5 | 6 | // Check documentation for full list of Quasar variables 7 | 8 | // Your own variables (that are declared here) and Quasar's own 9 | // ones will be available out of the box in your .vue/.scss/.sass files 10 | 11 | // It's highly recommended to change the default colors 12 | // to match your app's branding. 13 | // Tip: Use the "Theme Builder" on Quasar's documentation website. 14 | 15 | $primary : #1976D2; 16 | $secondary : #26A69A; 17 | $accent : #9C27B0; 18 | 19 | $dark : #1D1D1D; 20 | 21 | $positive : #21BA45; 22 | $negative : #C10015; 23 | $info : #31CCEC; 24 | $warning : #F2C037; 25 | -------------------------------------------------------------------------------- /frontend/src/index.template.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | <%= productName %> 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 |
21 | 22 | 23 | -------------------------------------------------------------------------------- /frontend/src/layouts/MainLayout.vue: -------------------------------------------------------------------------------- 1 | 118 | 119 | 195 | 196 | 208 | -------------------------------------------------------------------------------- /frontend/src/layouts/UserLayout.vue: -------------------------------------------------------------------------------- 1 | 36 | 37 | 42 | -------------------------------------------------------------------------------- /frontend/src/pages/Index.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 19 | -------------------------------------------------------------------------------- /frontend/src/pages/annotation/NerAnnotation.vue: -------------------------------------------------------------------------------- 1 | 9 | 10 | 31 | 32 | 42 | -------------------------------------------------------------------------------- /frontend/src/pages/data/DataDetail.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 12 | 13 | -------------------------------------------------------------------------------- /frontend/src/pages/data/DataList.vue: -------------------------------------------------------------------------------- 1 | 90 | 91 | 101 | 102 | 117 | -------------------------------------------------------------------------------- /frontend/src/pages/exception/403.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 12 | 13 | -------------------------------------------------------------------------------- /frontend/src/pages/exception/404.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 12 | 13 | -------------------------------------------------------------------------------- /frontend/src/pages/exception/500.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 12 | 13 | -------------------------------------------------------------------------------- /frontend/src/pages/exception/Error404.vue: -------------------------------------------------------------------------------- 1 | 21 | 22 | 29 | -------------------------------------------------------------------------------- /frontend/src/pages/model/ModelDetail.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /frontend/src/pages/model/ModelList.vue: -------------------------------------------------------------------------------- 1 | 88 | 89 | 99 | 100 | 115 | -------------------------------------------------------------------------------- /frontend/src/pages/service/NerService.vue: -------------------------------------------------------------------------------- 1 | 98 | 99 | 194 | 195 | 205 | -------------------------------------------------------------------------------- /frontend/src/pages/user/Login.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /frontend/src/pages/user/Register.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /frontend/src/pages/user/UserAuth.vue: -------------------------------------------------------------------------------- 1 | 26 | 27 | 106 | 107 | -------------------------------------------------------------------------------- /frontend/src/router/index.js: -------------------------------------------------------------------------------- 1 | import { route } from 'quasar/wrappers' 2 | import { createRouter, createMemoryHistory, createWebHistory, createWebHashHistory } from 'vue-router' 3 | import routes from './routes' 4 | 5 | /* 6 | * If not building with SSR mode, you can 7 | * directly export the Router instantiation; 8 | * 9 | * The function below can be async too; either use 10 | * async/await or return a Promise which resolves 11 | * with the Router instance. 12 | */ 13 | 14 | export default route(function (/* { store, ssrContext } */) { 15 | const createHistory = process.env.SERVER 16 | ? createMemoryHistory 17 | : (process.env.VUE_ROUTER_MODE === 'history' ? createWebHistory : createWebHashHistory) 18 | 19 | const Router = createRouter({ 20 | scrollBehavior: () => ({ left: 0, top: 0 }), 21 | routes, 22 | 23 | // Leave this as is and make changes in quasar.conf.js instead! 24 | // quasar.conf.js -> build -> vueRouterMode 25 | // quasar.conf.js -> build -> publicPath 26 | history: createHistory(process.env.MODE === 'ssr' ? void 0 : process.env.VUE_ROUTER_BASE) 27 | }) 28 | 29 | return Router 30 | }) 31 | -------------------------------------------------------------------------------- /frontend/src/router/routes.js: -------------------------------------------------------------------------------- 1 | const routes = [ 2 | // Dashboard 3 | { 4 | path: "/", 5 | redirect: "/service", 6 | }, 7 | 8 | // Machine Learning Model Detail 9 | { 10 | path: "/model", 11 | component: () => import("layouts/MainLayout.vue"), 12 | children: [ 13 | { 14 | path: "", 15 | component: () => import("pages/model/ModelList.vue"), 16 | }, 17 | ], 18 | }, 19 | { 20 | path: "/model/:id", 21 | component: () => import("layouts/MainLayout.vue"), 22 | children: [ 23 | { 24 | path: "", 25 | component: () => import("pages/model/ModelDetail.vue"), 26 | }, 27 | ], 28 | }, 29 | 30 | // Dataset Detail 31 | { 32 | path: "/data", 33 | component: () => import("layouts/MainLayout.vue"), 34 | children: [ 35 | { 36 | path: "", 37 | component: () => import("pages/data/DataList"), 38 | }, 39 | ], 40 | }, 41 | { 42 | path: "/data/:id", 43 | component: () => import("layouts/MainLayout.vue"), 44 | children: [ 45 | { 46 | path: "", 47 | component: () => import("pages/data/DataDetail.vue"), 48 | }, 49 | ], 50 | }, 51 | 52 | // NLP Service 53 | { 54 | path: "/service", 55 | redirect: "/service/ner", 56 | }, 57 | 58 | { 59 | path: "/service/ner", 60 | component: () => import("layouts/MainLayout.vue"), 61 | children: [ 62 | { 63 | path: "", 64 | component: () => import("pages/service/NerService.vue"), 65 | }, 66 | ], 67 | }, 68 | 69 | // Data Annotation Page 70 | { 71 | path: "/annotation", 72 | redirect: "/annotation/ner", 73 | }, 74 | 75 | { 76 | path: "/annotation/ner", 77 | component: () => import("layouts/MainLayout.vue"), 78 | children: [ 79 | { 80 | path: "", 81 | component: () => import("pages/annotation/NerAnnotation.vue"), 82 | }, 83 | ], 84 | }, 85 | 86 | // User 87 | 88 | { 89 | path: "/user/login", 90 | component: () => import("layouts/UserLayout.vue"), 91 | children: [ 92 | { 93 | path: "", 94 | component: () => import("pages/user/Login.vue"), 95 | }, 96 | ], 97 | }, 98 | 99 | { 100 | path: "/user/register", 101 | component: () => import("layouts/UserLayout.vue"), 102 | children: [ 103 | { 104 | path: "", 105 | component: () => import("pages/user/Register.vue"), 106 | }, 107 | ], 108 | }, 109 | 110 | // Exception 111 | { 112 | path: "/exception/403", 113 | component: () => import("layouts/MainLayout.vue"), 114 | children: [ 115 | { 116 | path: "", 117 | component: () => import("pages/exception/403"), 118 | }, 119 | ], 120 | }, 121 | { 122 | path: "/exception/404", 123 | component: () => import("layouts/MainLayout.vue"), 124 | children: [ 125 | { 126 | path: "", 127 | component: () => import("pages/exception/404"), 128 | }, 129 | ], 130 | }, 131 | { 132 | path: "/exception/500", 133 | component: () => import("layouts/MainLayout.vue"), 134 | children: [ 135 | { 136 | path: "", 137 | component: () => import("pages/exception/500"), 138 | }, 139 | ], 140 | }, 141 | 142 | // Always leave this as last one, 143 | // but you can also remove it 144 | { 145 | path: "/:catchAll(.*)*", 146 | component: () => import("pages/exception/Error404.vue"), 147 | }, 148 | ]; 149 | 150 | export default routes; 151 | -------------------------------------------------------------------------------- /frontend/src/store/index.js: -------------------------------------------------------------------------------- 1 | import { store } from "quasar/wrappers"; 2 | import { createStore } from "vuex"; 3 | import { api } from "boot/axios"; 4 | 5 | import serviceNer from "./modules/service/ner/index"; 6 | import annotationNer from "./modules/annotation/ner/index"; 7 | 8 | /* 9 | * If not building with SSR mode, you can 10 | * directly export the Store instantiation; 11 | * 12 | * The function below can be async too; either use 13 | * async/await or return a Promise which resolves 14 | * with the Store instance. 15 | */ 16 | 17 | export default store(function (/* { ssrContext } */) { 18 | const Store = createStore({ 19 | modules: { 20 | serviceNer, 21 | annotationNer, 22 | }, 23 | state() { 24 | return { 25 | baseURL: "http://172.17.8.59:5000", 26 | }; 27 | }, 28 | mutations: { 29 | updateBaseURL(state, payload) { 30 | state.baseURL = payload; 31 | api.defaults.baseURL = payload; 32 | }, 33 | }, 34 | // enable strict mode (adds overhead!) 35 | // for dev mode and --debug builds only 36 | strict: process.env.DEBUGGING, 37 | }); 38 | 39 | return Store; 40 | }); 41 | -------------------------------------------------------------------------------- /frontend/src/store/modules/annotation/ner/actions.js: -------------------------------------------------------------------------------- 1 | import { Notify } from "quasar"; 2 | import { api } from "boot/axios"; 3 | 4 | export default { 5 | async getDataset(context, payload) { 6 | let destination = ""; 7 | if (context.state.earlyPhaseOn) { 8 | destination = "/annotation_scratch"; 9 | } else { 10 | destination = "/annotation"; 11 | } 12 | const response = await api.get(destination); 13 | // console.log(response); 14 | 15 | if (response.status !== 200) { 16 | Notify.create({ 17 | color: "negative", 18 | position: "top", 19 | message: "Loading failed", 20 | icon: "report_problem", 21 | }); 22 | } else { 23 | context.commit("updateResult", response.data["ents"]); 24 | context.commit("updateDataIndex", response.data["index"]); 25 | context.commit("addHistory"); 26 | } 27 | }, 28 | 29 | async updateDataset(context, payload) { 30 | let conf = context.state.autoSuggestStrength / 100; 31 | let validEnt = context.state.ents.concat(["null"]); 32 | let autoEnt = []; 33 | 34 | context.state.result.forEach(({ token, label, iob, confidence }) => { 35 | if (validEnt.includes(label) && confidence >= conf) { 36 | autoEnt.push({ 37 | token: token, 38 | label: label, 39 | iob: iob, 40 | confidence: confidence, 41 | }); 42 | } else { 43 | autoEnt.push({ 44 | token: token, 45 | label: "null", 46 | iob: 2, 47 | confidence: confidence, 48 | }); 49 | } 50 | }); 51 | 52 | const label = JSON.parse(JSON.stringify(context.state.result)); 53 | 54 | const queryData = { 55 | crossdomain: true, 56 | index: context.state.dataIndex, 57 | annotator: context.state.annotator, 58 | label: JSON.stringify(label), 59 | }; 60 | 61 | let destination = ""; 62 | if (context.state.earlyPhaseOn) { 63 | destination = "/annotation_scratch"; 64 | } else { 65 | destination = "/annotation"; 66 | } 67 | const response = await api.put(destination, queryData); 68 | 69 | if (response.status !== 201) { 70 | Notify.create({ 71 | color: "negative", 72 | position: "top", 73 | message: "Loading failed", 74 | icon: "report_problem", 75 | }); 76 | } else { 77 | context.commit("saveHistory"); 78 | context.dispatch("getDataset"); 79 | } 80 | }, 81 | }; 82 | -------------------------------------------------------------------------------- /frontend/src/store/modules/annotation/ner/getters.js: -------------------------------------------------------------------------------- 1 | export default { 2 | getAllEnts(state) { 3 | return state.ALL_ENTS.map((ele) => ele.val); 4 | }, 5 | getDefaultEnts(state) { 6 | return state.DEFAULT_ENTS; 7 | }, 8 | getDefaultModel(state) { 9 | return state.DEFAULT_MODEL; 10 | }, 11 | getEntList(state) { 12 | return state.ALL_ENTS.filter(({ val }) => state.ents.includes(val)); 13 | }, 14 | 15 | getContentList(state) { 16 | let tmpColor = ""; 17 | let tmpLabel = ""; 18 | let childNodes = []; 19 | let entityToken = []; 20 | let entityId = []; 21 | let entconf = []; 22 | 23 | let conf = state.autoSuggestStrength / 100; 24 | const average = (array) => array.reduce((a, b) => a + b) / array.length; 25 | 26 | 27 | if (state.result.length > 0) { 28 | state.result.forEach(({ token, label, iob, confidence }, index) => { 29 | if (state.ents.includes(label) && confidence >= conf) { 30 | if (iob === 3) { 31 | if (entityToken.length > 0) { 32 | childNodes.push({ 33 | token: entityToken.join(" "), 34 | label: tmpLabel, 35 | color: tmpColor, 36 | id: entityId, 37 | confidence: average(entconf), 38 | }); 39 | entityToken = []; 40 | entityId = []; 41 | entconf = []; 42 | } 43 | tmpColor = state.ALL_ENTS.find(({ val }) => val === label).color; 44 | tmpLabel = label; 45 | // console.log(tmpColor); 46 | // console.log(tmpLabel); 47 | } 48 | entityToken.push(token); 49 | entityId.push(index); 50 | entconf.push(confidence); 51 | } else { 52 | if (entityToken.length > 0) { 53 | childNodes.push({ 54 | token: entityToken.join(" "), 55 | label: tmpLabel, 56 | color: tmpColor, 57 | id: entityId, 58 | confidence: average(entconf), 59 | }); 60 | entityToken = []; 61 | entityId = []; 62 | entconf = []; 63 | } 64 | childNodes.push({ 65 | token: token, 66 | label: "", 67 | color: "", 68 | id: index, 69 | confidence: confidence, 70 | }); 71 | } 72 | }); 73 | if (entityToken.length > 0) { 74 | childNodes.push({ 75 | token: entityToken.join(" "), 76 | label: tmpLabel, 77 | color: tmpColor, 78 | id: entityId, 79 | confidence: average(entconf), 80 | }); 81 | entityToken = []; 82 | entityId = []; 83 | entconf = []; 84 | } 85 | } 86 | return childNodes; 87 | }, 88 | }; 89 | -------------------------------------------------------------------------------- /frontend/src/store/modules/annotation/ner/index.js: -------------------------------------------------------------------------------- 1 | import getters from "./getters"; 2 | import mutations from "./mutations"; 3 | import actions from "./actions"; 4 | 5 | export default { 6 | namespaced: true, 7 | state() { 8 | return { 9 | // Glossary: https://github.com/explosion/spaCy/blob/master/spacy/glossary.py 10 | // A small subset of ENTs 11 | ALL_ENTS: [ 12 | { val: "ORG", label: "ORG", color: "cyan-3" }, 13 | { val: "LOC", label: "LOC", color: "orange-4" }, 14 | { val: "PER", label: "PER", color: "pink-3" }, 15 | { val: "MISC", label: "MISC", color: "purple-5" }, 16 | { val: "PRODUCT", label: "PRODUCT", color: "green-4" }, 17 | { val: "DATE", label: "DATE", color: "teal-3" }, 18 | { val: "TIME", label: "TIME", color: "teal-3" }, 19 | { val: "MONEY", label: "MONEY", color: "lime-7" }, 20 | { val: "QUANTITY", label: "QUANTITY", color: "lime-7" }, 21 | ], 22 | 23 | // ALL_ENTS: [ 24 | // { val: "ORG", label: "ORG", color: "cyan-3" }, 25 | // { val: "LOC", label: "LOC", color: "orange-4" }, 26 | // { val: "PERSON", label: "PERSON", color: "pink-3" }, 27 | // { val: "MISC", label: "MISC", color: "purple-5" }, 28 | // { val: "PRODUCT", label: "PRODUCT", color: "green-4" }, 29 | // { val: "GPE", label: "GPE", color: "orange-4" }, 30 | // { val: "NORP", label: "NORP", color: "deep-purple-5" }, 31 | // { val: "FACILITY", label: "FACILITY", color: "cyan-8" }, 32 | // { val: "EVENT", label: "EVENT", color: "indigo-3" }, 33 | // { val: "LAW", label: "LAW", color: "red-3" }, 34 | // { val: "LANGUAGE", label: "LANGUAGE", color: "red-3" }, 35 | // { val: "WORK_OF_ART", label: "ART", color: "purple-3" }, 36 | // { val: "DATE", label: "DATE", color: "teal-3" }, 37 | // { val: "TIME", label: "TIME", color: "teal-3" }, 38 | // { val: "MONEY", label: "MONEY", color: "lime-7" }, 39 | // { val: "QUANTITY", label: "QUANTITY", color: "lime-7" }, 40 | // { val: "ORDINAL", label: "ORDINAL", color: "lime-7" }, 41 | // { val: "CARDINAL", label: "CARDINAL", color: "lime-7" }, 42 | // { val: "PERCENT", label: "PERCENT", color: "lime-7" }, 43 | // ], 44 | ALL_MODELS: [ 45 | "hf_distillbert", 46 | "en_core_web_sm", 47 | "en_core_web_md", 48 | "en_core_web_lg", 49 | "en_core_web_trf", 50 | ], 51 | ALL_DATASETS: [ 52 | "CONLL2003", 53 | ], 54 | ALL_ALS: [ 55 | "MNLP", // Maximum Normalized Log-Probability 56 | "LC" // Least Confidence 57 | ], 58 | 59 | DEFAULT_ENTS: ["ORG", "PER", "LOC", "MISC"], 60 | DEFAULT_MODEL: "hf_distillbert", 61 | 62 | model: "hf_distillbert", 63 | dataset: "CONLL2003", 64 | al: "MNLP", 65 | annotator: "admin", 66 | ents: ["ORG", "PER", "LOC", "MISC"], 67 | earlyPhaseOn: true, 68 | activeLearningOn: false, 69 | showConfidence: false, 70 | startAnnotation: false, 71 | autoSuggestStrength: 20, 72 | tradeoff: 0, 73 | 74 | text: 'Geoffrey Everest Hinton CC FRS FRSC (born 6 December 1947) is a British-Canadian cognitive psychologist and computer scientist, most noted for his work on artificial neural networks. Since 2013, he has divided his time working for Google (Google Brain) and the University of Toronto. \n\nIn 2017, he co-founded and became the Chief Scientific Advisor of the Vector Institute in Toronto. With David Rumelhart and Ronald J. Williams, Hinton was co-author of a highly cited paper published in 1986 that popularized the backpropagation algorithm for training multi-layer neural networks, although they were not the first to propose the approach. Hinton is viewed as a leading figure in the deep learning community. The dramatic image-recognition milestone of the AlexNet designed in collaboration with his students Alex Krizhevsky and Ilya Sutskever for the ImageNet challenge 2012 was a breakthrough in the field of computer vision. \n\nHinton received the 2018 Turing Award, together with Yoshua Bengio and Yann LeCun, for their work on deep learning. They are sometimes referred to as the "Godfathers of AI" and "Godfathers of Deep Learning", and have continued to give public talks together.', 75 | result: [], 76 | 77 | curEnt: "ORG", 78 | startIndex: null, 79 | dataIndex: null, 80 | 81 | historyResult: [], 82 | historyIndex: [], 83 | historyCurInd: -1, 84 | }; 85 | }, 86 | getters, 87 | mutations, 88 | actions, 89 | }; 90 | -------------------------------------------------------------------------------- /frontend/src/store/modules/annotation/ner/mutations.js: -------------------------------------------------------------------------------- 1 | import { Notify } from "quasar"; 2 | 3 | export default { 4 | updateResult(state, payload) { 5 | let autoEnt = []; 6 | let validEnt = state.ents.concat(["null"]); 7 | 8 | payload.forEach(({ token, label, iob, confidence }) => { 9 | if (validEnt.includes(label) && confidence >= 0.2) { 10 | autoEnt.push({ 11 | token: token, 12 | label: label, 13 | iob: iob, 14 | confidence: confidence, 15 | }); 16 | } else { 17 | autoEnt.push({ 18 | token: token, 19 | label: "null", 20 | iob: 2, 21 | confidence: confidence, 22 | }); 23 | } 24 | }); 25 | state.result = autoEnt; 26 | }, 27 | updateCurEnt(state, payload) { 28 | state.curEnt = payload; 29 | }, 30 | updateText(state, payload) { 31 | state.text = payload; 32 | state.result = []; 33 | }, 34 | updateEnts(state, payload) { 35 | state.ents = payload; 36 | }, 37 | updateModel(state, payload) { 38 | state.model = payload; 39 | }, 40 | updateDataset(state, payload) { 41 | state.dataset = payload; 42 | }, 43 | updateAL(state, payload) { 44 | state.al = payload; 45 | }, 46 | updateEarlyPhaseOn(state, payload) { 47 | state.earlyPhaseOn = payload; 48 | }, 49 | updateActiveLearningOn(state, payload) { 50 | state.activeLearningOn = payload; 51 | }, 52 | updateShowConfidence(state, payload) { 53 | state.showConfidence = payload; 54 | }, 55 | updateAutoSuggestStrength(state, payload) { 56 | state.autoSuggestStrength = payload; 57 | }, 58 | updateTradeoff(state, payload) { 59 | state.tradeoff = payload; 60 | }, 61 | updateStartIndex(state, payload) { 62 | state.startIndex = payload; 63 | }, 64 | updateStartAnnotation(state, payload) { 65 | state.startAnnotation = payload; 66 | }, 67 | updateDataIndex(state, payload) { 68 | state.dataIndex = payload; 69 | }, 70 | 71 | addHistory(state, payload) { 72 | state.historyResult.push(JSON.stringify(state.result)); 73 | state.historyIndex.push(state.dataIndex); 74 | state.historyCurInd = state.historyIndex.length - 1; 75 | }, 76 | 77 | saveHistory(state, payload) { 78 | state.historyResult[state.historyCurInd] = JSON.stringify(state.result); 79 | }, 80 | 81 | retrieveHistoryPrev(state, payload) { 82 | const ind = 83 | (state.historyCurInd + state.historyIndex.length - 1) % 84 | state.historyIndex.length; 85 | state.historyResult[state.historyCurInd] = JSON.stringify(state.result); 86 | state.result = JSON.parse(state.historyResult[ind]); 87 | state.dataIndex = state.historyIndex[ind]; 88 | state.historyCurInd = ind; 89 | }, 90 | 91 | retrieveHistoryNext(state, payload) { 92 | const ind = 93 | (state.historyCurInd + state.historyIndex.length + 1) % 94 | state.historyIndex.length; 95 | state.historyResult[state.historyCurInd] = JSON.stringify(state.result); 96 | state.result = JSON.parse(state.historyResult[ind]); 97 | state.dataIndex = state.historyIndex[ind]; 98 | state.historyCurInd = ind; 99 | }, 100 | 101 | toggleLabel(state, payload) { 102 | const idList = payload.split(",").map(Number); 103 | if (idList.length === 1) { 104 | const id = idList; 105 | if (state.result[id]["label"] === "null") { 106 | state.result[id] = { 107 | token: state.result[id]["token"], 108 | confidence: 1.0, 109 | label: state.curEnt, 110 | iob: 3, 111 | }; 112 | } else { 113 | state.result[id] = { 114 | token: state.result[id]["token"], 115 | confidence: state.result[id]["confidence"], 116 | label: "null", 117 | iob: 2, 118 | }; 119 | } 120 | } else { 121 | idList.forEach((id) => { 122 | state.result[id] = { 123 | token: state.result[id]["token"], 124 | confidence: state.result[id]["confidence"], 125 | label: "null", 126 | iob: 2, 127 | }; 128 | }); 129 | } 130 | }, 131 | 132 | addLabel(state, payload) { 133 | const startIndex = parseInt(state.startIndex); 134 | const endIndex = parseInt(payload.endIndex); 135 | 136 | let id = null; 137 | 138 | for (id = startIndex; id <= endIndex; id++) { 139 | if (state.result[id]["iob"] !== 2) { 140 | Notify.create({ 141 | color: "negative", 142 | position: "top", 143 | message: "Invalid selection! Label Overlap!", 144 | icon: "report_problem", 145 | }); 146 | console.log( 147 | "Invalid selection! Label Overlap! ", 148 | `Token: ${state.result[id]["token"]}, Label: ${state.result[id]["label"]}, IOB: ${state.result[id]["iob"]}` 149 | ); 150 | return; 151 | } 152 | } 153 | 154 | for (id = startIndex; id <= endIndex; id++) { 155 | if (id === startIndex) { 156 | state.result[id] = { 157 | token: state.result[id]["token"], 158 | confidence: state.result[id]["confidence"], 159 | label: state.curEnt, 160 | iob: 3, 161 | }; 162 | } else { 163 | state.result[id] = { 164 | token: state.result[id]["token"], 165 | confidence: state.result[id]["confidence"], 166 | label: state.curEnt, 167 | iob: 1, 168 | }; 169 | } 170 | } 171 | }, 172 | }; 173 | -------------------------------------------------------------------------------- /frontend/src/store/modules/service/ner/actions.js: -------------------------------------------------------------------------------- 1 | import { Notify } from "quasar"; 2 | import { api } from "boot/axios"; 3 | 4 | export default { 5 | async analyzeText(context, payload) { 6 | const queryData = { 7 | crossdomain: true, 8 | model: context.state.model, 9 | text: payload.textInput, 10 | mode: "char", 11 | }; 12 | 13 | const response = await api.put("/spacy", queryData); 14 | console.log(response); 15 | 16 | if (response.status !== 201) { 17 | Notify.create({ 18 | color: "negative", 19 | position: "top", 20 | message: "Loading failed", 21 | icon: "report_problem", 22 | }); 23 | } else { 24 | context.commit("updateResult", response.data["ents"]); 25 | } 26 | }, 27 | }; 28 | -------------------------------------------------------------------------------- /frontend/src/store/modules/service/ner/getters.js: -------------------------------------------------------------------------------- 1 | export default { 2 | getAllEnts(state) { 3 | return state.ALL_ENTS.map((ele) => ele.val); 4 | }, 5 | getDefaultEnts(state) { 6 | return state.DEFAULT_ENTS; 7 | }, 8 | getDefaultModel(state) { 9 | return state.DEFAULT_MODEL; 10 | }, 11 | }; 12 | -------------------------------------------------------------------------------- /frontend/src/store/modules/service/ner/index.js: -------------------------------------------------------------------------------- 1 | import getters from "./getters"; 2 | import mutations from "./mutations"; 3 | import actions from "./actions"; 4 | 5 | export default { 6 | namespaced: true, 7 | state() { 8 | return { 9 | // Glossary: https://github.com/explosion/spaCy/blob/master/spacy/glossary.py 10 | ALL_ENTS: [ 11 | { val: "ORG", label: "ORG", color: "cyan-3" }, 12 | { val: "PRODUCT", label: "PRODUCT", color: "green-4" }, 13 | { val: "GPE", label: "GPE", color: "orange-4" }, 14 | { val: "LOC", label: "LOC", color: "orange-4" }, 15 | { val: "PERSON", label: "PERSON", color: "pink-3" }, 16 | { val: "MISC", label: "MISC", color: "purple-5" }, 17 | { val: "NORP", label: "NORP", color: "deep-purple-5" }, 18 | { val: "FACILITY", label: "FACILITY", color: "cyan-8" }, 19 | { val: "EVENT", label: "EVENT", color: "indigo-3" }, 20 | { val: "LAW", label: "LAW", color: "red-3" }, 21 | { val: "LANGUAGE", label: "LANGUAGE", color: "red-3" }, 22 | { val: "WORK_OF_ART", label: "ART", color: "purple-3" }, 23 | { val: "DATE", label: "DATE", color: "teal-3" }, 24 | { val: "TIME", label: "TIME", color: "teal-3" }, 25 | { val: "MONEY", label: "MONEY", color: "lime-7" }, 26 | { val: "QUANTITY", label: "QUANTITY", color: "lime-7" }, 27 | { val: "ORDINAL", label: "ORDINAL", color: "lime-7" }, 28 | { val: "CARDINAL", label: "CARDINAL", color: "lime-7" }, 29 | { val: "PERCENT", label: "PERCENT", color: "lime-7" }, 30 | ], 31 | ALL_MODELS: [ 32 | "en_core_web_sm", 33 | "en_core_web_md", 34 | "en_core_web_lg", 35 | "en_core_web_trf", 36 | ], 37 | 38 | DEFAULT_ENTS: ["ORG", "PERSON", "GPE", "LOC", "PRODUCT"], 39 | DEFAULT_MODEL: "en_core_web_sm", 40 | 41 | model: "en_core_web_sm", 42 | ents:["ORG", "PERSON", "GPE", "LOC", "PRODUCT"], 43 | 44 | text: 'Geoffrey Everest Hinton CC FRS FRSC (born 6 December 1947) is a British-Canadian cognitive psychologist and computer scientist, most noted for his work on artificial neural networks. Since 2013, he has divided his time working for Google (Google Brain) and the University of Toronto. \n\nIn 2017, he co-founded and became the Chief Scientific Advisor of the Vector Institute in Toronto. With David Rumelhart and Ronald J. Williams, Hinton was co-author of a highly cited paper published in 1986 that popularized the backpropagation algorithm for training multi-layer neural networks, although they were not the first to propose the approach. Hinton is viewed as a leading figure in the deep learning community. The dramatic image-recognition milestone of the AlexNet designed in collaboration with his students Alex Krizhevsky and Ilya Sutskever for the ImageNet challenge 2012 was a breakthrough in the field of computer vision. \n\nHinton received the 2018 Turing Award, together with Yoshua Bengio and Yann LeCun, for their work on deep learning. They are sometimes referred to as the "Godfathers of AI" and "Godfathers of Deep Learning", and have continued to give public talks together.', 45 | result: [], 46 | }; 47 | }, 48 | getters, 49 | mutations, 50 | actions, 51 | }; 52 | -------------------------------------------------------------------------------- /frontend/src/store/modules/service/ner/mutations.js: -------------------------------------------------------------------------------- 1 | export default { 2 | updateResult(state, payload) { 3 | state.result = payload; 4 | }, 5 | updateText(state, payload) { 6 | state.text = payload; 7 | state.result = []; 8 | }, 9 | updateEnts(state, payload) { 10 | state.ents = payload; 11 | }, 12 | updateModel(state, payload) { 13 | state.model = payload; 14 | }, 15 | }; 16 | -------------------------------------------------------------------------------- /frontend/src/store/store-flag.d.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable */ 2 | // THIS FEATURE-FLAG FILE IS AUTOGENERATED, 3 | // REMOVAL OR CHANGES WILL CAUSE RELATED TYPES TO STOP WORKING 4 | import "quasar/dist/types/feature-flag"; 5 | 6 | declare module "quasar/dist/types/feature-flag" { 7 | interface QuasarFeatureFlags { 8 | store: true; 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "lockfileVersion": 1 3 | } 4 | -------------------------------------------------------------------------------- /requirement.txt: -------------------------------------------------------------------------------- 1 | torch 2 | torchtext 3 | torchvision 4 | transformers 5 | datasets 6 | seqeval 7 | tqdm 8 | baal 9 | Flask 10 | flask_cors 11 | Flask-RESTful 12 | Flask-MongoAlchemy 13 | 14 | spacy>=3.0 15 | 16 | https://github.com/explosion/spacy-models/releases/download/en_core_web_sm-3.0.0/en_core_web_sm-3.0.0.tar.gz#egg=en_core_web_sm==3.0.0 --------------------------------------------------------------------------------