Commit 5a3f2f0d authored by Sylvain Coulange's avatar Sylvain Coulange
Browse files

ajout addstat customColor

parent bafc8a10
......@@ -3,9 +3,15 @@ from django.http import JsonResponse
import re, json, spacy, subprocess
import MeCab
print("Chargement du modèle de français...")
nlpFr = spacy.load('fr_core_news_md')
print("OK")
print("Chargement du modèle de mandarin...")
nlpZh = spacy.load('zh_core_web_md')
print("OK")
print("Chargement du modèle de japonais...")
chasen = MeCab.Tagger("-Ochasen")
print("OK")
def home(request):
updateTimeStr = updateTime()
......@@ -56,6 +62,8 @@ def runSpacy(request):
"text": "\n",
"lemma": "",
"pos": "X",
"saibunrui1": "",
"saibunrui2": "",
"tag": "",
"dep": "",
"shape": ""
......@@ -66,6 +74,8 @@ def runSpacy(request):
"text": token[0],
"lemma": token[2],
"pos": token[3].split('-')[0],
"saibunrui1": token[3].split('-')[1] if len(token[3].split('-'))>1 else "",
"saibunrui2": token[3].split('-')[2] if len(token[3].split('-'))>2 else "",
"tag": " ".join(token[3:]),
"dep": "",
"shape": ""
......
async function addStat(modul, lang=thisPageLang) {
console.log("addStat",modul,lang);
// ON EMBALLE TOUT ÇA
var colis = {
app: "grammachrome",
module: modul,
lang: lang
}
// Paramètres d'envoi
const options = {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(colis)
};
// ENVOI
await fetch('https://phonographe.alem-app.fr/addStat/', options);
}
\ No newline at end of file
......@@ -8,6 +8,8 @@ function runIfSpace() {
}
async function runSpacy() {
addStat("coloriser",thisPageLang);
document.getElementById('outText').innerHTML = "";
document.getElementById('loader').style.display = "block";
......@@ -15,9 +17,7 @@ async function runSpacy() {
var lang = document.getElementById('choixLang').value;
// REMPLACEMENT DES \n PAR ¬ POUR MECAB (JP)
if(lang == "jp"){
inText = inText.replace(/\n/g,'¬')
}
if(lang == "jp") inText = inText.replace(/\n/g,'¬')
// ON EMBALLE TOUT ÇA
var colis = {
......@@ -48,13 +48,32 @@ async function runSpacy() {
var stylesUnderline = "text-decoration: underline; text-decoration-thickness: 6px;";
for (i=0; i<data.outText.length; i++) {
if (pos[data.outText[i].pos].color == '') col = "#ccc";
else col = pos[data.outText[i].pos].color;
if (lang=="jp") {
if (Object.keys(pos).includes(data.outText[i].pos + '' + data.outText[i].saibunrui1)) col = pos[data.outText[i].pos + '' + data.outText[i].saibunrui1].color;
else {
col = "#cccccc"
console.log("MANQUE:",data.outText[i].pos + '' + data.outText[i].saibunrui1)
}
} else if (lang=="zh") {
if (Object.keys(pos).includes(data.outText[i].tag)) col = pos[data.outText[i].tag].color;
else {
col = "#cccccc"
console.log("MANQUE:",data.outText[i].tag + ' ' + data.outText[i].pos)
}
} else {
col = pos[data.outText[i].pos].color;
}
if (lang=="jp") var currentPos = data.outText[i].pos + '' + data.outText[i].saibunrui1;
else if (lang=="zh") var currentPos = data.outText[i].tag;
else var currentPos = data.outText[i].pos;
// Traitement des tags
var tagdef = "";
// Traitement des tags en français
if (lang == "fr") {
taglist = Array.from(data.outText[i].tag.replace(/^\w+__/, '').split('|'))
tags = []
var taglist = Array.from(data.outText[i].tag.replace(/^\w+__/, '').split('|'))
var tags = [];
taglist.forEach((tag) => {
if (tag in tags2def){
tags.push(tags2def[tag].toLowerCase())
......@@ -63,64 +82,72 @@ async function runSpacy() {
}
})
if (data.outText[i].tag == data.outText[i].pos) {
data.outText[i].tag = pos[data.outText[i].pos]['def']
tagdef = pos[data.outText[i].pos]['def']
} else {
data.outText[i].tag = pos[data.outText[i].pos]['def'] + ' : ' + tags.join(', ')
tagdef = pos[data.outText[i].pos]['def'] + ' : ' + tags.join(', ')
}
} else if (lang == "zh") {
if (Object.keys(pos).includes(data.outText[i].tag)) tagdef = pos[data.outText[i].tag]['def']
else tagdef = data.outText[i].tag;
} else if (lang == "jp") {
// console.log(data.outText[i].pos + '・' + data.outText[i].saibunrui1)
// if (Object.keys(pos).includes(data.outText[i].pos + '・' + data.outText[i].saibunrui1)) tagdef = pos[data.outText[i].pos + ' ' + data.outText[i].saibunrui1].def;
// else tagdef = data.outText[i].pos + ' ' + data.outText[i].saibunrui1
tagdef = data.outText[i].pos + ' ' + data.outText[i].saibunrui1 + ' ' + data.outText[i].saibunrui2;
}
// saut de ligne
sdl = data.outText[i].text.split(/[\n¬]+/);
if (sdl.length>1){
if (sdl.length>1) {
for (s=1; s<sdl.length; s++) {
result = result + "<br>";
}
}
// espace
else if (data.outText[i].text == " ") result = result + "<span style='"+ stylesCommuns +"'> </span>";
// bicolores → soulignage
// déterminants prépositionnels (du des...)
else if (data.outText[i].tag.slice(0,7)== "ADP_DET") {
} else if (data.outText[i].text == " ") {
// ESPACE
result = result
+ "<span style='"+ stylesCommuns +"'> </span>";
} else if (data.outText[i].tag.slice(0,7)== "ADP_DET") {
// BICOLORES → soulignage
// déterminants prépositionnels (du des...)
result = result
+ '<span class="token" style="color:'+ pos["DET"].color +';'
+ '<span style="color:'+ pos["DET"].color +';'
+ stylesCommuns
+ stylesUnderline + 'text-decoration-color:' + pos["ADP"].color
+'" title-data="'+ data.outText[i].tag
+'">'+ data.outText[i].text + '</span>';
}
// pronoms adverbiaux (en et y)
else if (data.outText[i].text.toLowerCase() == "en" || data.outText[i].text.toLowerCase() == "y" && data.outText[i].pos == "PRON") {
+ stylesUnderline + 'text-decoration-color:' + pos["ADP"].color +'" '
+'title-data="'+ data.outText[i].tag +'" '
+'class="token pos'+ currentPos +'" '
+'>'+ data.outText[i].text + '</span>';
} else if (data.outText[i].text.toLowerCase() == "en" || data.outText[i].text.toLowerCase() == "y" && data.outText[i].pos == "PRON") {
// pronoms adverbiaux (en et y)
result = result
+ '<span class="token" style="color:'+ pos["PRON"].color +';'
+ '<span style="color:'+ pos["PRON"].color +';'
+ stylesCommuns
+ stylesUnderline + 'text-decoration-color:' + pos["ADV"].color
+'" title-data="'+ data.outText[i].tag
+'">'+ data.outText[i].text + '</span>';
}
// tout le reste
else result = result
+ '<span class="token" style="color:'+ col +';'
+ stylesCommuns
+'" title-data="'+ data.outText[i].tag
+'">'+ data.outText[i].text + '</span>';
+ stylesUnderline + 'text-decoration-color:' + pos["ADV"].color +'" '
+'title-data="'+ data.outText[i].tag +'" '
+'class="token pos'+ currentPos +'" '
+'>'+ data.outText[i].text + '</span>';
} else {
// tout le reste
result = result
+ '<span style="color:'+ col +';'
+ stylesCommuns +'" '
+'title-data="'+ tagdef +'" '
+'class="token pos'+ currentPos +'" '
+'>'+ data.outText[i].text + '</span>';
}
}
document.getElementById('loader').style.display = "none";
document.getElementById('outText').innerHTML = result;
// On relance switchTags() si il était actif
if (tags) {
switchTags();
switchTags();
}
switchTags();
switchTags();
// On remplace les blancs par noir si bg = blanc
if (defaultBg == 'white') {
document.getElementById('outText').innerHTML = document.getElementById('outText').innerHTML.replace(/#fff;/g,'#000;')
document.getElementById('outText').innerHTML = document.getElementById('outText').innerHTML.replace(/#fffff;/g,'#000000;')
}
}
......@@ -163,14 +190,14 @@ function switchTags(){
if (tags) { // Masque les étiquettes morphosyntaxiques
for (i=0; i<tokens.length; i++){
tokens[i].title = '';
tokens[i].classList = "token";
tokens[i].classList.add("token");
}
divBtnTags.classList.remove("btnActive");
} else { // Affiche les étiquettes morphosyntaxiques
for (i=0; i<tokens.length; i++){
tokens[i].title = tokens[i].getAttribute('title-data');
tokens[i].classList = "token tokenborder";
tokens[i].classList.add("token", "tokenborder");
}
divBtnTags.classList.add("btnActive");
}
......
pos = {
var pos = {
"ADJ": { "color":"#980086", "def":"Adjectif"},
"ADP": { "color":"#c00018", "def":"Préposition adverbiale"},
"ADV": { "color":"#3984c6", "def":"Adverbe"},
"AUX": { "color":"#eda01a", "def":"Auxiliaire"},
"CONJ": { "color":"#fff", "def":"Conjonction"},
"CCONJ": { "color":"#fff", "def":"Conjonction de coordination"},
"CONJ": { "color":"#ffffff", "def":"Conjonction"},
"CCONJ": { "color":"#ffffff", "def":"Conjonction de coordination"},
"DET": { "color":"#f3eb20", "def":"Déterminant"},
"INTJ": { "color":"#8a9092", "def":"Interjection"},
"NOUN": { "color":"#00b54a", "def":"Nom"},
"NUM": { "color":"#f3eb20", "def":"Nombre"},
"PART": { "color":"", "def":"Particule"},
"PART": { "color":"#cccccc", "def":"Particule"},
"PRON": { "color":"#a56026", "def":"Pronom"},
"PROPN": { "color":"#a56026", "def":"Nom propre"},
"PUNCT": { "color":"#fff", "def":"Ponctuation"},
"SCONJ": { "color":"#fff", "def":"Conjonction de subordination"},
"SPACE": { "color":"", "def":"Espace"},
"SYM": { "color":"", "def":"Symbole"},
"PUNCT": { "color":"#ffffff", "def":"Ponctuation"},
"SCONJ": { "color":"#ffffff", "def":"Conjonction de subordination"},
"SPACE": { "color":"#cccccc", "def":"Espace"},
"SYM": { "color":"#cccccc", "def":"Symbole"},
"VERB": { "color":"#eda01a", "def":"Verbe"},
"X": { "color":"", "def":"X"},
"X・": { "color":"#cccccc", "def":"X"},
"col_base": { "color":"#555753", "def":""},
"名詞": { "color":"#00b54a", "def":""},
"接頭詞": { "color":"", "def":""},
"動詞": { "color":"#eda01a", "def":""},
"形容詞": { "color":"#980086", "def":""},
"副詞": { "color":"#3984c6", "def":""},
"連体詞": { "color":"", "def":""},
"接続詞": { "color":"#fff", "def":""},
"助詞": { "color":"#f3eb20", "def":""},
"助動詞": { "color":"#eda01a", "def":""},
"感動詞": { "color":"#8a9092", "def":""},
"記号": { "color":"#fff", "def":""},
"フィラー": { "color":"#8a9092", "def":""}
}
\ No newline at end of file
"その他・間投" : { "color":"#8a9092", "def":"その他 間投 (autres interjections)" },
"フィラー・" : { "color":"#8a9092", "def":"フィラー (filler)" },
"副詞・一般" : { "color":"#3984c6", "def":"副詞 一般 (adverbe)" },
"副詞・助詞類接続" : { "color":"#3984c6", "def":"副詞 助詞類接続 (adverbe à particule)" },
"助動詞・" : { "color":"#eda01a", "def":"助動詞 (particule auxiliaire)" },
"助詞・副助詞" : { "color":"#f3eb20", "def":"助詞 副助詞 (particule adverbe)" },
"助詞・接続助詞" : { "color":"#f3eb20", "def":"助詞 接続助詞 (particule conjonctive)" },
"助詞・格助詞" : { "color":"#f3eb20", "def":"助詞 格助詞 (particule de cas)" },
"助詞・連体化" : { "color":"#f3eb20", "def":"助詞 連体化 (particule adjectivale)" },
"助詞・係助詞" : { "color":"#f3eb20", "def":"助詞 係助詞 (particule connective)" },
"助詞・副助詞/並立助詞/終助詞" : { "color":"#f3eb20", "def":"助詞 副助詞/並立助詞/終助詞 (particule divers)" },
"助詞・副詞化" : { "color":"#f3eb20", "def":"助詞 副詞化 (particule adverbiale)" },
"助詞・並立助詞" : { "color":"#f3eb20", "def":"助詞 並立助詞 (parallel marker)" },
"助詞・終助詞" : { "color":"#f3eb20", "def":"助詞 終助詞 (particule de fin de phrase)" },
"動詞・接尾" : { "color":"#eda01a", "def":"動詞 接尾 (suffix verbal)" },
"動詞・自立" : { "color":"#eda01a", "def":"動詞 自立 (racine verbale)" },
"動詞・非自立" : { "color":"#eda01a", "def":"動詞 非自立 (verbe dépendant)" },
"名詞・サ変接続" : { "color":"#00b54a", "def":"名詞 サ変接続 (nom sa-hen)" },
"名詞・ナイ形容詞語幹" : { "color":"#00b54a", "def":"名詞 ナイ形容詞語幹 (nom en -nai)" },
"名詞・一般" : { "color":"#00b54a", "def":"名詞 一般 (nom général)" },
"名詞・代名詞" : { "color":"#a56026", "def":"名詞 代名詞 (pronom)" },
"名詞・副詞可能" : { "color":"#00b54a", "def":"名詞 副詞可能 (nom adverbe)" },
"名詞・動詞非自立的" : { "color":"#00b54a", "def":"名詞 動詞非自立的 (nom verbe-dépendant)" },
"名詞・固有名詞" : { "color":"#00b54a", "def":"名詞 固有名詞 (nom propre)" },
"名詞・引用文字列" : { "color":"#00b54a", "def":"名詞 引用文字列 (nom de citation いわく)" },
"名詞・形容動詞語幹" : { "color":"#00b54a", "def":"名詞 形容動詞語幹 (nom adjectif)" },
"名詞・接尾" : { "color":"#00b54a", "def":"名詞 接尾 (suffixe nominal)" },
"名詞・接続詞的" : { "color":"#00b54a", "def":"名詞 接続詞的 (nom conjonctif「VS」、「対」、「兼」)" },
"名詞・数" : { "color":"#00b54a", "def":"名詞 数 (nom numéral)" },
"名詞・特殊" : { "color":"#00b54a", "def":"名詞 特殊 (nom spécial)" },
"名詞・非自立" : { "color":"#00b54a", "def":"名詞 非自立 (nom dépendant)" },
"形容詞・接尾" : { "color":"#980086", "def":"形容詞 接尾 (suffixe adjectival)" },
"形容詞・自立" : { "color":"#980086", "def":"形容詞 自立 (adjectif indépendant)" },
"形容詞・非自立" : { "color":"#980086", "def":"形容詞 非自立 (adjectif dépendant)" },
"感動詞・" : { "color":"#8a9092", "def":"感動詞 (interjection)" },
"接続詞・" : { "color":"#ffffff", "def":"接続詞 (conjonction)" },
"接続詞・並立助詞" : { "color":"#ffffff", "def":"接続詞 並立助詞 (conjonction parallèle)" },
"接続詞・副詞化" : { "color":"#ffffff", "def":"接続詞 副詞化 (conjonction adverbiale)" },
"接続詞・終助詞" : { "color":"#ffffff", "def":"接続詞 終助詞 (conjonction de fin de phrase)" },
"接頭詞・動詞接続" : { "color":"#ffffff", "def":"接頭詞 動詞接続 (préfixe verbal)" },
"接頭詞・名詞接続" : { "color":"#ffffff", "def":"接頭詞 名詞接続 (préfixe nominal)" },
"接頭詞・形容詞接続" : { "color":"#ffffff", "def":"接頭詞 形容詞接続 (préfixe adjectival)" },
"接頭詞・数接続" : { "color":"#ffffff", "def":"接頭詞 数接続 (préfixe numérique)" },
"記号・アルファベット" : { "color":"#cccccc", "def":"記号 アルファベット (lettre latine)" },
"記号・一般" : { "color":"#cccccc", "def":"記号 一般 (symbole général)" },
"記号・句点" : { "color":"#cccccc", "def":"記号 句点 (point)" },
"記号・括弧閉" : { "color":"#cccccc", "def":"記号 括弧閉 (parenthèse fermante)" },
"記号・括弧開" : { "color":"#cccccc", "def":"記号 括弧開 (parenthèse ouvrante)" },
"記号・空白" : { "color":"#cccccc", "def":"記号 空白 (espace)" },
"記号・読点" : { "color":"#cccccc", "def":"記号 読点 (virgule)" },
"連体詞・" : { "color":"#980086", "def":"連体詞 (adjectif prénominal)" },
"連体詞・係助詞" : { "color":"#980086", "def":"連体詞 係助詞" },
"連体詞・副助詞/並立助詞/終助詞" : { "color":"#980086", "def":"連体詞 副助詞/並立助詞/終助詞" },
"連体詞・特殊" : { "color":"#980086", "def":"連体詞 特殊" },
"VA": { "color":"#eda01a", "def":"Predicative adjective"},
"VC": { "color":"#eda01a", "def":""},
"VE": { "color":"#eda01a", "def":"有 as the main verb"},
"VV": { "color":"#eda01a", "def":"Other verb"},
"NN": { "color":"#00b54a", "def":"Common noun"},
"NR": { "color":"#a56026", "def":"Proper noun"},
"NT": { "color":"#00b54a", "def":"Temporal noun"},
"FW": { "color":"#00b54a", "def":"Foreign words"},
"LC": { "color":"#c00018", "def":"Localizer"},
"PN": { "color":"#a56026", "def":"Pronoun"},
"DT": { "color":"#f3eb20", "def":"Determiner"},
"CD": { "color":"#f3eb20", "def":"Cardinal number "},
"OD": { "color":"#f3eb20", "def":"Ordinal number "},
"M": { "color":"#f3eb20", "def":"Measure word"},
"AD": { "color":"#3984c6", "def":"Adverb"},
"P": { "color":"#c00018", "def":"Preposition excl. 被 and 把"},
"LB": { "color":"#c00018", "def":"被 in long bei-const"},
"SB": { "color":"#c00018", "def":"被 in short bei-const"},
"BA": { "color":"#c00018", "def":"把 in ba-construction"},
"CC": { "color":"#ffffff", "def":"Coordinating conjunction"},
"CS": { "color":"#ffffff", "def":"Subordinating conjunction"},
"DEC": { "color":"#c00018", "def":"的 in a relative-clause"},
"DER": { "color":"#c00018", "def":"得 in V-de const. and V-de-R"},
"DEG": { "color":"#c00018", "def":"Associative 的"},
"DEV": { "color":"#c00018", "def":"地 before VP"},
"AS": { "color":"#eda01a", "def":"Aspect marker"},
"ETC": { "color":"#3984c6", "def":"For words 等, 等等"},
"SP": { "color":"#8a9092", "def":"Sentence-final particle"},
"MSP": { "color":"#8a9092", "def":"Other particle"},
"IJ": { "color":"#8a9092", "def":"Interjection"},
"ON": { "color":"#8a9092", "def":"Onomatopoeia"},
"JJ": { "color":"#cccccc", "def":"Other noun-modifier"},
"PU": { "color":"#cccccc", "def":"Punctuation"}
}
// https://hayashibe.jp/tr/mecab/dictionary/ipadic
// https://www.unixuser.org/~euske/doc/postag/
// Xia2000_The Part-Of-Speech Tagging Guidelines for thePenn Chinese Treebank 3.0.pdf
function setCol(thispos, color) {
pos[thispos].color = color;
if (thispos == "col_base") {
var listunset = document.querySelectorAll('.unset');
for (i=0; i<listunset.length; i++) {
listunset[i].style.color = color;
}
} else {
var listpos = document.querySelectorAll('.pos'+thispos);
for (i=0; i<listpos.length; i++) {
listpos[i].style.color = color;
}
}
console.log("Set color of",thispos,"to",color);
}
function togglePhon(cbid) {
var thisCb = document.getElementById(cbid);
var thispos = cbid.slice(3);
console.log(thisCb.checked, thispos);
var listthispos = document.querySelectorAll('.pos'+thispos);
if (thisCb.checked) {
pos[thispos].color = document.getElementById('colorPicker-'+thispos).value;
for (i=0; i<listthispos.length; i++) {
listthispos[i].style.color = document.getElementById('colorPicker-'+thispos).value;
listthispos[i].classList.remove('unset');
}
} else {
pos[thispos].color = pos["col_base"].color;
for (i=0; i<listthispos.length; i++) {
listthispos[i].style.color = pos["col_base"].color;
listthispos[i].classList.add('unset');
}
}
}
function checkUncheck(thisChecked, classe) {
var cblist = document.querySelectorAll('.'+classe);
console.log("checkAll",thisChecked,classe);
if (!thisChecked) {
for (i=0; i<cblist.length; i++) {
cblist[i].checked = false;
togglePhon(cblist[i].id);
console.log(cblist[i].id);
}
} else {
for (i=0; i<cblist.length; i++) {
cblist[i].checked = true;
togglePhon(cblist[i].id);
console.log(cblist[i].id);
}
}
}
// SAME FOR ALL LANGUAGES :) DO IT ONCE
// GENERATION DES CHECKBOX+COLORPICKER
makeCustom()
function makeCustom() {
custphonList = document.querySelectorAll('.custcol');
for (i=0; i<custphonList.length; i++) {
var thispos = custphonList[i].dataset.pos;
var colpick = ' <input type="color" id="colorPicker-'+thispos+'" class="colorSetting" onchange="setCol(\''+thispos+'\',this.value)" value="'+ pos[thispos].color +'">';
custphonList[i].innerHTML = '<div class="form-check m-1"><input class="form-check-input check-pos" type="checkbox" onchange="togglePhon(this.id)" id="cb-'+thispos+'" checked><label class="form-check-label" for="cb-'+thispos+'">'+pos[thispos].def+colpick+'</label></div>';
}
}
\ No newline at end of file
......@@ -19,4 +19,17 @@ function interface(lang) {
title = langtitleList[i];
title.title = langJson[title.id][lang];
};
if (lang == 'fr') {
document.getElementById('posTable').innerHTML = posTableFr;
makeCustom();
}
if (lang == 'zh') {
document.getElementById('posTable').innerHTML = posTableZh;
makeCustom();
}
if (lang == 'jp') {
document.getElementById('posTable').innerHTML = posTableJp;
makeCustom();
}
}
\ No newline at end of file
var posTableFr = `
<div class="d-flex justify-content-evenly">
<!-- POS -->
<div class="d-flex p-1 m-1" style="background-color:#caf2ca;border:1px solid black; border-radius:5px">
<div class="form-check align-self-center">
<input class="form-check-input" type="checkbox" onchange="checkUncheck(this.checked,'check-pos')" id="checkAll" checked>
</div>
<table style="background-color:white;">
<tbody>
<tr>
<td class="phonTableTd"><div class="custcol" data-pos="ADJ"></div></td>
<td class="phonTableTd"><div class="custcol" data-pos="ADP"></div></td>
<td class="phonTableTd"><div class="custcol" data-pos="ADV"></div></td>
</tr>
<tr>
<td class="phonTableTd"><div class="custcol" data-pos="AUX"></div></td>
<td class="phonTableTd"><div class="custcol" data-pos="CONJ"></div></td>
<td class="phonTableTd"><div class="custcol" data-pos="CCONJ"></div></td>
</tr>
<tr>
<td class="phonTableTd"><div class="custcol" data-pos="DET"></div></td>
<td class="phonTableTd"><div class="custcol" data-pos="INTJ"></div></td>
<td class="phonTableTd"><div class="custcol" data-pos="NOUN"></div></td>
</tr>
<tr>
<td class="phonTableTd"><div class="custcol" data-pos="NUM"></div></td>
<td class="phonTableTd"><div class="custcol" data-pos="PART"></div></td>
<td class="phonTableTd"><div class="custcol" data-pos="PRON"></div></td>
</tr>
<tr>
<td class="phonTableTd"><div class="custcol" data-pos="PROPN"></div></td>
<td class="phonTableTd"><div class="custcol" data-pos="PUNCT"></div></td>
<td class="phonTableTd"><div class="custcol" data-pos="SCONJ"></div></td>
</tr>
<tr>
<td class="phonTableTd"><div class="custcol" data-pos="SPACE"></div></td>
<td class="phonTableTd"><div class="custcol" data-pos="SYM"></div></td>
<td class="phonTableTd"><div class="custcol" data-pos="VERB"></div></td>
</tr>
</tbody>
</table>
</div>
</div>
`
var posTableZh = `
<div class="d-flex justify-content-evenly">
<!-- POS -->
<div class="d-flex p-1 m-1" style="background-color:#caf2ca;border:1px solid black; border-radius:5px">
<div class="form-check align-self-center">
<input class="form-check-input" type="checkbox" onchange="checkUncheck(this.checked,'check-pos')" id="checkAll" checked>
</div>
<table style="background-color:white;">
<tbody>
<tr>
<td class="phonTableTd"><div class="custcol" data-pos="VA"></div></td>
<td class="phonTableTd"><div class="custcol" data-pos="VC"></div></td>
<td class="phonTableTd"><div class="custcol" data-pos="VE"></div></td>
<td class="phonTableTd"><div class="custcol" data-pos="VV"></div></td>
</tr>
<tr>
<td class="phonTableTd"><div class="custcol" data-pos="NN"></div></td>
<td class="phonTableTd"><div class="custcol" data-pos="NR"></div></td>
<td class="phonTableTd"><div class="custcol" data-pos="NT"></div></td>
<td class="phonTableTd"><div class="custcol" data-pos="FW"></div></td>
</tr>
<tr>
<td class="phonTableTd"><div class="custcol" data-pos="LC"></div></td>
<td class="phonTableTd"><div class="custcol" data-pos="PN"></div></td>
<td class="phonTableTd"><div class="custcol" data-pos="DT"></div></td>
<td class="phonTableTd"><div class="custcol" data-pos="CD"></div></td>
</tr>
<tr>
<td class="phonTableTd"><div class="custcol" data-pos="OD"></div></td>
<td class="phonTableTd"><div class="custcol" data-pos="M"></div></td>
<td class="phonTableTd"><div class="custcol" data-pos="AD"></div></td>
<td class="phonTableTd"><div class="custcol" data-pos="P"></div></td>
</tr>
<tr>
<td class="phonTableTd"><div class="custcol" data-pos="LB"></div></td>
<td class="phonTableTd"><div class="custcol" data-pos="SB"></div></td>
<td class="phonTableTd"><div class="custcol" data-pos="BA"></div></td>
<td class="phonTableTd"><div class="custcol" data-pos="CC"></div></td>
</tr>
<tr>
<td class="phonTableTd"><div class="custcol" data-pos="CS"></div></td>
<td class="phonTableTd"><div class="custcol" data-pos="DEC"></div></td>
<td class="phonTableTd"><div class="custcol" data-pos="DER"></div></td>