This commit is contained in:
ivan 2024-02-29 12:07:58 +03:00
commit a93d795449
7 changed files with 2819 additions and 0 deletions

25
LICENSE Normal file
View File

@ -0,0 +1,25 @@
This program is free software; you can redistribute it and/or modify it under the terms of the Do What Thou Wilt License.
Boundless Public License
DO WHAT THOU WILT
TO PUBLIC LICENSE
Version 2.55
Everyone is permitted to copy and distribute verbatim or modified copies of this license document, and changing it in full or in part is allowed without any restrictions.
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. Do what thou wilt shall be the whole of the Law.
DWTWL a license with a single requirement: DO WHAT THOU WILT
The license provides more freedom than any other one (such as GPL or BSD) and does not require saving the license text on copying.
DWTWL an accomplished and eligible license for free text, code and any other symbols (including the software, documentation and artwork).
The license does not contain a "no warranty" clause. DWTWL can be used in countries that do not legally acknowledge the transition to public domain.
Summary:
An author-creator gives their source code to the world for free, without becoming distracted by worldly thinking regarding how and why the others will use it.

7
README.md Normal file
View File

@ -0,0 +1,7 @@
fdb - Forgers database
======
This is the database of forgers saved in CSV format and displayed via javascript on a web page.
Any webserver can be used. To activate the add and edit feature, configure the webserver to use the cgi bash script.
Image files are stored here: https://archive.org/details/forgers

11
cgi-bin/upload.sh Executable file
View File

@ -0,0 +1,11 @@
#!/bin/bash
printf "Content-type: text/plain\n\n"
if [ "$REQUEST_METHOD" = "POST" ]; then
if [ "$CONTENT_LENGTH" -gt 0 ]; then
if [ "$CONTENT_LENGTH" -lt 131072 ]; then
read -n $CONTENT_LENGTH POST_DATA <&0
echo "${POST_DATA//!custom_newline!/$'\n'}" >> ../html/fdb/upload.csv
fi
fi
fi
exit

1783
html/fdb/forgers.csv Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1 @@
Images can be downloaded from here: https://archive.org/details/forgers

992
html/fdb/index.html Normal file
View File

@ -0,0 +1,992 @@
<!DOCTYPE html>
<!-- fdb - Forgers database
source code: https://gitlab.com/zlax/fdb
media files: https://archive.org/details/forgers -->
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<!-- no cache: beta mode without version control -->
<meta http-equiv="Cache-control" content="no-cache, must-revalidate">
<!-- no cache. https://stackoverflow.com/a/32427 -->
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>fdb</title>
<!--
Background image: Old paper texture background, simple design (ID: 6130364) by Teddy
https://www.rawpixel.com/image/6130364/old-paper-texture-background-simple-design
Font: Truetypewriter PolyglOTT by Sam_T
https://fonts-online.ru/fonts/truetypewriter-polyglott
-->
<style type="text/css">
@font-face {
font-family: "PolyglOTT";
src: url("PolyglOTT.ttf") format("truetype");
}
html {
font: inherit;
font-size: 1.2em;
}
.bodybg {
background: url(background.jpg) repeat-y;
font-family: "PolyglOTT";
}
.darkbody {
background: #2e3235;
font-family: 'Ubuntu', sans-serif;
color: #c0c3c5;
}
.card {
box-sizing: border-box;
height: 100vh;
display: block;
max-width: 30%;
min-width: 444px;
height: 99vh;
}
.cardfloatright { float: right; }
.cardfloatleft { float: left; }
.cardchild {
margin-bottom: 0.25em;
margin-right: 0.25em;
margin-top: 0.1em;
height: 33vh;
font-size: 19px;
border: #888 3px dotted;
border-radius: 0.6em;
padding: 0.5em;
backdrop-filter: brightness(90%);
}
.description {
height: 29vh;
overflow-y: scroll;
}
.images {
height: 57vh;
overflow-y: scroll;
}
.images img { width: 100%; }
.article {
box-sizing: border-box;
padding: 0.25em;
height: 98vh;
overflow-y: scroll;
}
.title {
font-size: 25px;
}
.buttons { display: inline-block; }
.buttonsparent {
display: flex;
justify-content: center;
align-items: center;
}
.popup {
overflow-y: scroll;
margin: 0 1em 1em 0;
max-width: 93%;
border: #888 3px groove;
border-radius: 0.5em;
padding: 1em;
backdrop-filter: blur(25px) brightness(25%) contrast(75%) grayscale(25%);
position: absolute;
top: 10%;
right: 0;
bottom: 5%;
left: 0;
margin: auto;
visibility: hidden;
}
.popup-dossier { background: url(background.jpg) repeat-y; }
.popup-simple { background: #ddd; }
.popupvisible { visibility: visible; }
.navresult { cursor: pointer; }
summary { cursor:pointer; }
fieldset { border-radius: 0.25em; }
textarea { width: 100%; }
details > div > div { display: inline-block; }
</style>
<script type="text/javascript">
const version = "0.01.01";
const ffilename = "forgers.csv";
var lang = window.navigator ? (window.navigator.systemLanguage ||
window.navigator.language || window.navigator.userLanguage) : "ru";
lang = lang.substr(0, 2).toLowerCase();
if (lang != "ru") lang = "en";
var current = 0;
var farray = [];
var sortedarray = [];
var URIanchor = decodeURI(window.location.hash).slice(1).split('_').join(' ');
var popupstatus = "hidden";
// Default local settings
if (localStorage.getItem('csearch') == null) localStorage.setItem('csearch', 'wiki');
if (localStorage.getItem('cimages') == null) localStorage.setItem('cimages', 'imgur');
if (localStorage.getItem('csort') == null) localStorage.setItem('csort', 'added');
if (localStorage.getItem('cstyle') == null) localStorage.setItem('cstyle', 'dossier');
// Detecting a mobile browser
window.mobileCheck = function() { // https://stackoverflow.com/a/11381730
var check = false;
(function(a){if(/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino/i.test(a)||/1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test(a.substr(0,4))) check = true;})(navigator.userAgent||navigator.vendor||window.opera);
return check;
};
if (localStorage.getItem('cinterface') == null) {
if (window.mobileCheck()) localStorage.setItem('cinterface', 'center');
else localStorage.setItem('cinterface', 'left');
}
// Array of titles and labels for settings pop-up
const settings = [];
settings[0] = {title: "search", rulegend: "Поиск по умолчанию",
enlegend: "Default search", rulabel: "Wikipedia, DuckDuckGo, Google, Yandex",
enlabel: "Wikipedia, DuckDuckGo, Google, Yandex", type: "wiki, duckduckgo, google, yandex"};
settings[1] = {title: "images", rulegend: "Изображения",
enlegend: "Images", rulabel: "Локальные, Imgur",
enlabel: "Local, Imgur", type: "local, imgur"};
settings[2] = {title: "interface", rulegend: "Интерфейс",
enlegend: "Interface", rulabel: "Левый, Правый, По центру",
enlabel: "Left, Right, Center", type: "left, right, center"};
settings[3] = {title: "sort", rulegend: "Сортировка",
enlegend: "Sorting", rulabel: "По мере наполнения, По алфавиту, Хронологически, По стране",
enlabel: "As added, Alphabetically, Chronologically, By country", type: "added, alpha, chrono, country"};
settings[4] = {title: "style", rulegend: "Стиль",
enlegend: "Style", rulabel: "Досье, Тёмный, Простой HTML",
enlabel: "Dossier, Dark, Simple HTML", type: "dossier, dark, simple"};
// Another titles and labels
const labels = {};
labels.header = ["База данных фальсификаторов", "Forgers database"];
labels.settings = ["Параметры", "Settings"];
labels.database = ["База данных", "Database"];
labels.edit = ["Изменить", "Edit"];
labels.add = ["Добавить", "Add"];
labels.download = ["Загрузить", "Download"];
labels.search = ["Поиск", "Search"];
labels.mention = ["Упоминается в", "Mentioned in"];
labels.navigation = ["Навигация", "Navigation"];
labels.all = ["Все", "All"];
labels.editinfo = ["Отправленная Вами информация будет отредактирована вручную перед пополнением базы данных. Проверьте правила форматирования полей, выбрав изменение существующей записи или загрузив всю базу данных в CSV-файле.", "The information you send will be manually edited before the database is updated. Check the field formatting rules by selecting to modify an existing record or by loading the entire database in a CSV file."];
labels.send = ["Отправить", "Send"];
labels.cancel = ["Отменить", "Cancel"];
// CSV columns of farray
const runame = 0; // Имя
const enname = 1; // Name
const ruarticle = 2; // Статья
const enarticle = 3; // Article
const links = 4; // Ссылки / Links
const knownas = 5; // Также известный как / Also known as
const years = 6; // Годы активности / Activity years
const ruactivity = 7; // Направление деятельности
const enactivity = 8; // Area of activity
const rulocations = 9; // Места пребывания
const enlocations = 10; // Locations
const ruregions = 11; // Связанные регионы
const enregions = 12; // Related regions
const rurelated = 13; // Связанные персоны и организации
const enrelated = 14; // Related persons and organisations
const rusupported = 15; // Аутентичность подделок поддерживали
const ensupported = 16; // Authenticity of fakes supported by
const ruexposedby = 17; // Разоблачали
const enexposedby = 18; // Exposed by
const ruattributed = 19; // Атрибутированные авторы
const enattributed = 20; // Attributed authors
const runotable = 21; // Примечательные подделки
const ennotable = 22; // Notable forgeries
const rukept = 23; // Хранятся
const enkept = 24; // Kept
const images = 25; // Изображения / Images
const imagesalt = 26; // Изображения альт. / Images alt.
// Parsing CSV data into an array
function parseCSV(str) { // https://stackoverflow.com/a/14991797
var arr = [];
var quote = false; // `true` means we`re inside a quoted field
// Iterate over each character, keep track of current row and column (of the returned array)
for (var row = 0, col = 0, c = 0; c < str.length; c++) {
var cc = str[c], nc = str[c+1]; // Current character, next character
arr[row] = arr[row] || []; // Create a new row if necessary
arr[row][col] = arr[row][col] || ''; // Create a new column (start with empty string) if necessary
// If the current character is a quotation mark, and we're inside a
// quoted field, and the next character is also a quotation mark,
// add a quotation mark to the current column and skip the next character
if (cc == '"' && quote && nc == '"') { arr[row][col] += cc; ++c; continue; }
// If it's just one quotation mark, begin/end quoted field
if (cc == '"') { quote = !quote; continue; }
// If it's a comma and we're not in a quoted field, move on to the next column
if (cc == ',' && !quote) { ++col; continue; }
// If it's a newline (CRLF) and we're not in a quoted field, skip the next character
// and move on to the next row and move to column 0 of that new row
if (cc == '\r' && nc == '\n' && !quote) { ++row; col = 0; ++c; continue; }
// If it's a newline (LF or CR) and we're not in a quoted field,
// move on to the next row and move to column 0 of that new row
if (cc == '\n' && !quote) { ++row; col = 0; continue; }
if (cc == '\r' && !quote) { ++row; col = 0; continue; }
// Otherwise, append the current character to the current column
arr[row][col] += cc;
}
return arr;
}
// Reading CSV file to a string variable
function readCSV(file, callback) {
var csvfile = new XMLHttpRequest();
csvfile.open("GET", file, true);
csvfile.onreadystatechange = function () {
if(csvfile.readyState === 4) {
if(csvfile.status === 200 || csvfile.status == 0)
callback(csvfile.responseText);
}
}
csvfile.send(null);
}
// Splitting a string to an array with specific delimiter
function strToArr(value, delimiter) {
switch(delimiter) {
case "cm":
var array = value.split(", ");
break;
case "nl":
var array = value.split(/\r?\n/);
break;
}
return array;
}
// Converting array elements to a string by type
function arrToStr(array, type) {
var resultstr = "";
switch(type) {
case "wiki":
array.forEach(function(item, i, arr) {
if (i > 0) resultstr += ", ";
resultstr += '<a href="https://' + lang + '.wikipedia.org/w/index.php?search='
+ item.split(' ').join('+') + '" target="_blank">';
resultstr += item + "</a>";
});
break;
case "duckduckgo":
array.forEach(function(item, i, arr) {
if (i > 0) resultstr += ", ";
resultstr += '<a href="https://duckduckgo.com/?q='
+ item.split(' ').join('+') + '" target="_blank">';
resultstr += item + "</a>";
});
break;
case "google":
array.forEach(function(item, i, arr) {
if (i > 0) resultstr += ", ";
resultstr += '<a href="https://www.google.com/search?q='
+ item.split(' ').join('+') + '" target="_blank">';
resultstr += item + "</a>";
});
break;
case "yandex":
array.forEach(function(item, i, arr) {
if (i > 0) resultstr += ", ";
resultstr += '<a href="https://yandex.com/search/?text='
+ item.split(' ').join('+') + '" target="_blank">';
resultstr += item + "</a>";
});
break;
case "url":
array.forEach(function(item, i, arr) {
if (i > 1) resultstr += ", ";
if (i > 0) resultstr += '<a href="' + item + '" target="_blank">['
+ i + ']</a>';
});
break;
default:
array.forEach(function(item, i, arr) {
if (i > 0) resultstr += ", ";
resultstr += item;
});
break;
}
return resultstr;
}
// Show article by sorted ID
function showArticle(sortedid) {
id = sortedarray[sortedid].id;
var linksarr = strToArr(farray[id][links],"nl");
var c = ": ";
var result = '<div class="title" align="center">'
+ '<a href="' + linksarr[0] + '" target="_blank">';
var anchname;
var st = localStorage.getItem('csearch');
switch(lang) {
case "ru":
anchname = farray[id][runame];
result += farray[id][runame] + "</a></div>";
if (localStorage.getItem('cinterface') != 'center')
result += '<div class="description" tabindex="2">';
else
result += '<div>';
if (strToArr(farray[id][knownas],"cm")[0] != "")
result += strToArr(farray[0][knownas], "nl")[0] + c + arrToStr(strToArr(farray[id][knownas],"cm")) + "<br>";
if (strToArr(farray[id][ruactivity],"cm")[0] != "")
result += farray[0][ruactivity] + c + arrToStr(strToArr(farray[id][ruactivity],"cm")) + "<br>";
if (farray[id][years] != "")
result += strToArr(farray[0][years], "nl")[0] + c + farray[id][years] + "<br>";
if (strToArr(farray[id][rurelated],"cm")[0] != "")
result += farray[0][rurelated] + c + arrToStr(strToArr(farray[id][rurelated],"cm"), st) + "<br>";
if (strToArr(farray[id][ruregions],"cm")[0] != "")
result += farray[0][ruregions] + c + arrToStr(strToArr(farray[id][ruregions],"cm")) + "<br>";
if (strToArr(farray[id][rulocations],"cm")[0] != "")
result += farray[0][rulocations] + c + arrToStr(strToArr(farray[id][rulocations],"cm")) + "<br>";
if (strToArr(farray[id][rusupported],"cm")[0] != "")
result += farray[0][rusupported] + c + arrToStr(strToArr(farray[id][rusupported],"cm"), st) + "<br>";
if (strToArr(farray[id][ruexposedby],"cm")[0] != "")
result += farray[0][ruexposedby] + c + arrToStr(strToArr(farray[id][ruexposedby],"cm"), st) + "<br>";
if (strToArr(farray[id][ruattributed],"cm")[0] != "")
result += farray[0][ruattributed] + c + arrToStr(strToArr(farray[id][ruattributed],"cm"), st) + "<br>";
if (strToArr(farray[id][runotable],"cm")[0] != "")
result += farray[0][runotable] + c + arrToStr(strToArr(farray[id][runotable],"cm"), st) + "<br>";
if (strToArr(farray[id][rukept],"cm")[0] != "")
result += farray[0][rukept] + c + arrToStr(strToArr(farray[id][rukept],"cm"), st) + "<br>";
if (strToArr(farray[id][links], "nl").length > 1)
result += strToArr(farray[0][links], "nl")[0] + c + arrToStr(strToArr(farray[id][links],"nl"), "url") + "</div>";
document.getElementById("fcard").innerHTML = result;
result = farray[id][ruarticle].replace(/(?:\r\n|\r|\n)/g, '<br><br>');
break;
default:
anchname = farray[id][enname];
result += farray[id][enname] + "</a></div>";
if (localStorage.getItem('cinterface') != 'center')
result += '<div class="description" tabindex="2">';
else
result += '<div>';
if (strToArr(farray[id][knownas],"cm")[0] != "")
result += strToArr(farray[0][knownas], "nl")[1] + c + arrToStr(strToArr(farray[id][knownas],"cm")) + "<br>";
if (strToArr(farray[id][enactivity],"cm")[0] != "")
result += farray[0][enactivity] + c + arrToStr(strToArr(farray[id][enactivity],"cm")) + "<br>";
if (farray[id][years] != "")
result += strToArr(farray[0][years], "nl")[1] + c + farray[id][years] + "<br>";
if (strToArr(farray[id][enrelated],"cm")[0] != "")
result += farray[0][enrelated] + c + arrToStr(strToArr(farray[id][enrelated],"cm"), st) + "<br>";
if (strToArr(farray[id][enregions],"cm")[0] != "")
result += farray[0][enregions] + c + arrToStr(strToArr(farray[id][enregions],"cm")) + "<br>";
if (strToArr(farray[id][enlocations],"cm")[0] != "")
result += farray[0][enlocations] + c + arrToStr(strToArr(farray[id][enlocations],"cm")) + "<br>";
if (strToArr(farray[id][ensupported],"cm")[0] != "")
result += farray[0][ensupported] + c + arrToStr(strToArr(farray[id][ensupported],"cm"), st) + "<br>";
if (strToArr(farray[id][enexposedby],"cm")[0] != "")
result += farray[0][enexposedby] + c + arrToStr(strToArr(farray[id][enexposedby],"cm"), st) + "<br>";
if (strToArr(farray[id][enattributed],"cm")[0] != "")
result += farray[0][enattributed] + c + arrToStr(strToArr(farray[id][enattributed],"cm"), st) + "<br>";
if (strToArr(farray[id][ennotable],"cm")[0] != "")
result += farray[0][ennotable] + c + arrToStr(strToArr(farray[id][ennotable],"cm"), st) + "<br>";
if (strToArr(farray[id][enkept],"cm")[0] != "")
result += farray[0][enkept] + c + arrToStr(strToArr(farray[id][enkept],"cm"), st) + "<br>";
if (strToArr(farray[id][links], "nl").length > 1)
result += strToArr(farray[0][links], "nl")[1] + c + arrToStr(strToArr(farray[id][links],"nl"), "url") + "</div>";
document.getElementById("fcard").innerHTML = result;
result = farray[id][enarticle].replace(/(?:\r\n|\r|\n)/g, '<br><br>');
break;
}
document.getElementById("farticle").innerHTML = result;
window.location.hash = "#" + anchname.split(' ').join('_');
result = '<div align=center>';
switch (localStorage.getItem('cimages')) {
case "local":
var localimg = strToArr(farray[id][imagesalt],"nl");
if (!localimg[0] == "")
for (url in localimg) result += '<a href="images/' + localimg[url]
+ '" target="_blank"><img src="images/' + localimg[url] + '"></a><br>';
break;
case "imgur":
var imgurimg = strToArr(farray[id][images],"nl");
if (!imgurimg[0] == "")
for (url in imgurimg) result += '<a href="' + imgurimg[url]
+ '" target="_blank"><img src="' + imgurimg[url] + '"></a><br>';
break;
}
result += "</div>";
document.getElementById("fimages").innerHTML = result;
}
// Changing the current article
function currentArticle(id, type) {
var arrsize = sortedarray.length;
var sortedid = id;
switch(type) {
case "back":
if (sortedid > 0) sortedid = sortedid - 1;
else sortedid = arrsize - 1;
break;
case "forward":
if (sortedid == arrsize - 1) sortedid = 0;
else sortedid = sortedid + 1;
break;
case "farrayid":
sortedarray.forEach(function(item, i, arr) {
if (item.id == id) sortedid = i;
});
break;
}
current = sortedid;
showArticle(current);
}
// Filling the settings page
function fillSettings() {
const searchtypes = new Map([ ['wiki', '0'], ['duckduckgo', '1'], ['google', '2'], ['yandex', '3'] ]);
var searchradio = document.querySelectorAll("[name='searchtype']");
searchradio[searchtypes.get(localStorage.getItem('csearch'))].checked=true;
const imagestypes = new Map([ ['local', '0'], ['imgur', '1'] ]);
var imagesradio = document.querySelectorAll("[name='imagestype']");
imagesradio[imagestypes.get(localStorage.getItem('cimages'))].checked=true;
const intertypes = new Map([ ['left', '0'], ['right', '1'], ['center', '2'] ]);
var intradio = document.querySelectorAll("[name='interfacetype']");
intradio[intertypes.get(localStorage.getItem('cinterface'))].checked=true;
const sorttypes = new Map([ ['added', '0'], ['alpha', '1'], ['chrono', '2'], ['country', '3'] ]);
var sortradio = document.querySelectorAll("[name='sorttype']");
sortradio[sorttypes.get(localStorage.getItem('csort'))].checked=true;
const styletypes = new Map([ ['dossier', '0'], ['dark', '1'], ['simple', '2'] ]);
var styleradio = document.querySelectorAll("[name='styletype']");
styleradio[styletypes.get(localStorage.getItem('cstyle'))].checked=true;
}
// Changing the value of settings
function changeSettings(sett) {
switch (sett) {
case "wiki": case "duckduckgo": case "google": case "yandex":
localStorage.setItem('csearch', sett);
break;
case "local": case "imgur":
localStorage.setItem('cimages', sett);
currentStyle();
break;
case "left": case "right": case "center":
localStorage.setItem('cinterface', sett);
makeScreen();
currentInterface();
break;
case "added": case "alpha": case "chrono": case "country":
localStorage.setItem('csort', sett);
currentSorting();
break;
case "dossier": case "dark": case "simple":
localStorage.setItem('cstyle', sett);
currentStyle();
break;
}
currentLanguage();
}
// Checking the status of the pop-up menu
function checkPopup(event) {
if (!document.getElementById('fullpopup').contains(event.target)
&& !document.getElementById('butts').contains(event.target))
showPopup("hide");
}
// Show pop-up menu by type
function showPopup(type) {
var fpop = document.getElementById("fullpopup").classList;
if (type == "hide") {
fpop.remove("popupvisible");
document.removeEventListener('click', checkPopup);
popupstatus = "hidden";
document.getElementById('farticle').focus();
} else if (type == "settings") {
if (popupstatus == "settings" || popupstatus == "hidden") fpop.toggle("popupvisible");
if (fpop.contains("popupvisible")) {
document.addEventListener('click', checkPopup);
document.getElementById("searchnavtab").hidden=true;
document.getElementById("editaddtab").hidden=true;
document.getElementById("settingstab").hidden=false;
popupstatus = "settings";
} else {
document.removeEventListener('click', checkPopup);
popupstatus = "hidden";
}
} else if (type == "searchnav") {
if (popupstatus == "searchnav" || popupstatus == "hidden") fpop.toggle("popupvisible");
if (fpop.contains("popupvisible")) {
document.addEventListener('click', checkPopup);
document.getElementById("searchnavtab").hidden=false;
document.getElementById("editaddtab").hidden=true;
document.getElementById("settingstab").hidden=true;
popupstatus = "searchnav";
document.getElementById('searchbar').focus();
} else {
document.removeEventListener('click', checkPopup);
popupstatus = "hidden";
}
} else if (type == "edit" || type == "add") {
if (fpop.contains("popupvisible")) {
document.addEventListener('click', checkPopup);
document.getElementById("searchnavtab").hidden=true;
document.getElementById("editaddtab").hidden=false;
document.getElementById("settingstab").hidden=true;
popupstatus = "settings";
fillEdit(type);
} else {
document.removeEventListener('click', checkPopup);
popupstatus = "hidden";
}
}
}
// Changing the current interface
function currentInterface() {
var ccard = document.getElementById("card").classList;
switch (localStorage.getItem('cinterface')) {
case "left":
ccard.add("cardfloatleft");
ccard.remove("cardfloatright");
break;
case "right":
ccard.add("cardfloatright");
ccard.remove("cardfloatleft");
break;
case "center":
ccard.remove("cardfloatright");
ccard.remove("cardfloatleft");
break;
}
}
// Changing the current style
function currentStyle() {
var body = document.getElementById("mainbody").classList;
var popup = document.getElementById("fullpopup").classList;
switch (localStorage.getItem('cstyle')) {
case "dossier":
body.remove("darkbody");
body.add("bodybg");
popup.add("popup-dossier");
popup.remove("popup-simple");
break;
case "dark":
body.remove("bodybg");
body.add("darkbody");
popup.remove("popup-dossier");
popup.remove("popup-simple");
break;
case "simple":
body.remove("bodybg");
body.remove("darkbody");
popup.remove("popup-dossier");
popup.add("popup-simple");
break;
}
}
// Changing the current language
function currentLanguage(type) {
switch(lang) {
case "ru":
if (type == "change") {
lang = "en";
document.getElementById("langbutt").value = "рус";
} else document.getElementById("langbutt").value = "eng";
showArticle(current);
break;
case "en":
if (type == "change") {
lang = "ru";
document.getElementById("langbutt").value = "eng";
} else document.getElementById("langbutt").value = "рус";
showArticle(current);
break;
}
makePopup(popupstatus);
currentSorting();
}
// Changing the current sorting
function currentSorting() {
switch (localStorage.getItem('csort')) {
case "added":
cid = sortedarray[current].id;
sortedarray.sort((a, b) => a.id > b.id ? 1 : -1);
for (var i = 0; i < sortedarray.length; i++)
if (cid == sortedarray[i].id) current = i;
break;
case "alpha":
cid = sortedarray[current].id;
if (lang == 'ru') sortedarray.sort((a, b) => a.rusurname.toUpperCase() > b.rusurname.toUpperCase() ? 1 : -1);
else sortedarray.sort((a, b) => a.ensurname.toUpperCase() > b.ensurname.toUpperCase() ? 1 : -1);
for (var i = 0; i < sortedarray.length; i++)
if (cid == sortedarray[i].id) current = i;
break;
case "chrono":
cid = sortedarray[current].id;
sortedarray.sort((a, b) => a.chrono > b.chrono ? 1 : -1);
for (var i = 0; i < sortedarray.length; i++)
if (cid == sortedarray[i].id) current = i;
break;
case "country":
cid = sortedarray[current].id;
if (lang == 'ru') sortedarray.sort(function(a,b) {
if (a.rulocation < b.rulocation) return -1; if (a.rulocation > b.rulocation) return 1;
if (a.rusurname < b.rusurname) return -1; if (a.rusurname > b.rusurname) return 1; return 0;
});
else sortedarray.sort(function(a,b) {
if (a.enlocation < b.enlocation) return -1; if (a.enlocation > b.enlocation) return 1;
if (a.ensurname < b.ensurname) return -1; if (a.ensurname > b.ensurname) return 1; return 0;
});
for (var i = 0; i < sortedarray.length; i++)
if (cid == sortedarray[i].id) current = i;
break;
}
}
// Forming the main screen
function makeScreen() {
if (localStorage.getItem('cinterface') != 'center')
var dataf = '<div id="card" class="card">';
else
var dataf = '<div id="card">';
var buttons = '<div class="buttonsparent"><div id="butts" class="buttons">'
+ '<input type="button" onclick="currentArticle(current, ' + "'back'" + ');" value="<" style="font-size: 1em;"/>'
+ '<input type="button" onclick="showPopup(' + "'searchnav'" + ');" value="&#128269;" style="font-size: 1em;"/>'
+ '<input type="button" onclick="showPopup(' + "'settings'" + ');" value="&#128295;" style="font-size: 1em;"/>'
+ '<input type="button" id="langbutt" onclick="currentLanguage(' + "'change'" + ');" value="" style="font-size: 1em;"/>'
+ '<input type="button" onclick="currentArticle(current, ' + "'forward'" + ');" value=">" style="font-size: 1em;"/>'
+ '</div></div>';
if (localStorage.getItem('cinterface') != 'center')
dataf += buttons + '<div id="fcard" class="cardchild"></div>';
else
dataf += buttons + '<div id="fcard"></div>';
if (localStorage.getItem('cinterface') != 'center')
dataf += '<div id="fimages" class="images" align="center" tabindex="3"></div>';
dataf += '</div>';
if (localStorage.getItem('cinterface') != 'center')
dataf += '<div id="farticle" class="article" tabindex="1"></div>';
else
dataf += '<br><div id="farticle"></div>';
if (localStorage.getItem('cinterface') == 'center')
dataf += '<div id="fimages" align="center"></div>';
document.getElementById('datafields').innerHTML = dataf;
}
// Forming the pop-up screen
function makePopup(tab) {
// tab type current, hidden, settings
var dataf = '<p align="center">' + labels.header[runame] + ' - fdb'
+ version + ' - ' + labels.header[enname] + '</p>';
dataf += '<div id="searchnavtab"><fieldset id="searchtab"><legend>'
+ ( (lang == "ru") ? labels.search[runame] : labels.search[enname] )
+ ':</legend>';
dataf += '<form style="text-align: center">';
dataf += '<input id="searchbar" onkeyup="checkSearch();" type="text" name="search" placeholder="'
+ ( (lang == "ru") ? labels.search[runame] : labels.search[enname] ) + '">';
dataf += '</form>';
dataf += '<div id="searchresult"></div>';
dataf += '</fieldset>';
dataf += '<fieldset id="navigationtab"><legend>'
+ ( (lang == "ru") ? labels.navigation[runame] : labels.navigation[enname] )
+ ':</legend>';
dataf += '<div id="navigationresult"></div>';
dataf += '</fieldset></div>';
dataf += '<div id="settingstab"><fieldset><legend>'
+ ( (lang == "ru") ? labels.settings[runame] : labels.settings[enname] )
+ ':</legend>';
dataf += '<form>';
dataf += '<fieldset style="text-align: center"><legend>'
+ ( (lang == "ru") ? labels.database[runame] : labels.database[enname] )
+ ':</legend>';
dataf += '<input type="button" id="edit" onclick="showPopup(' + "'edit'" + ')" value="'
+ ( (lang == "ru") ? labels.edit[runame] : labels.edit[enname] )
+ '" style="font-size: 1em;"> ';
dataf += '<input type="button" id="add" onclick="showPopup(' + "'add'" + ')" value="'
+ ( (lang == "ru") ? labels.add[runame] : labels.add[enname] )
+ '" style="font-size: 1em;"> ';
dataf += '<button type="submit" onclick="window.open(' + "'"
+ ffilename + "'" + ');" style="font-size: 1em;">'
+ ( (lang == "ru") ? labels.download[runame] : labels.download[enname] )
+ '</button>';
dataf += '</fieldset>';
settings.forEach(function(item, i, arr) {
var types = strToArr(item.type, "cm")
dataf += '<fieldset>';
dataf += '<legend>' + ( (lang == "ru") ? item.rulegend : item.enlegend ) + ':</legend>';
dataf += '<div>';
types.forEach(function(itemtype, j, arrtype) {
dataf += '<input type="radio" id="' + item.title + 'set' + j
+ '" name ="' + item.title + 'type" value="' + itemtype
+ '" onchange="changeSettings(' + "'" + itemtype + "'"
+ ');">';
dataf += '<label for="' + item.title + 'set' + j + '">'
+ ( (lang == "ru") ? strToArr(item.rulabel, "cm")[j] : strToArr(item.enlabel, "cm")[j] )
+ '</label>';
});
dataf += '</div>';
dataf += '</fieldset>';
});
dataf += '</form>';
dataf += '</fieldset></div>';
dataf += '<div id="editaddtab"></div>';
document.getElementById('fullpopup').innerHTML = dataf;
fillSettings();
fillNavigation();
switch(tab) {
case "settings":
document.getElementById("settingstab").hidden=false;
document.getElementById("searchnavtab").hidden=true;
document.getElementById("editaddtab").hidden=true;
break;
case "searchnav":
document.getElementById("searchnavtab").hidden=false;
document.getElementById("settingstab").hidden=true;
document.getElementById("editaddtab").hidden=true;
break;
}
}
// Search
function checkSearch() {
var query = document.getElementById('searchbar').value.toLowerCase();
var resultname = [];
var resultmention = [];
var resultstring = "";
if (query.length > 2) {
sortedarray.forEach(function(item, i, arr) {
var searchname = [runame, enname, knownas];
searchname.forEach(function(searchitem, j, searcharr) {
if (farray[item.id][searchitem].toLowerCase().includes(query)) resultname.push(i);
});
});
var resultnameset = [...new Set(resultname)];
if (resultnameset.length > 0) {
resultstring = '<div id="resultname">';
resultnameset.forEach(function(item, i, arr) {
if (i > 0) resultstring += '; ';
var langname = (lang == "ru") ? farray[sortedarray[item].id][runame] : farray[sortedarray[item].id][enname];
resultstring += '<a href=".#' + langname.split(' ').join('_')
+ '" onclick="currentArticle(' + sortedarray[item].id + ', '
+ "'farrayid'" + '); showPopup(' + "'hide'" + ')">'
+ langname + '</a>';
if (farray[item][knownas]) resultstring += ' ('
+ farray[sortedarray[item].id][knownas] + ')';
});
resultstring += '</div><br>';
}
sortedarray.forEach(function(item, i, arr) {
var searchmention = [rulocations, enlocations, ruregions, enregions,
ruactivity, enactivity, rurelated, enrelated, rusupported,
ensupported, ruexposedby, enexposedby, ruattributed,
enattributed, runotable, ennotable, rukept, enkept,
ruarticle, enarticle];
searchmention.forEach(function(searchitem, j, searcharr) {
if (farray[item.id][searchitem].toLowerCase().includes(query)) resultmention.push(i);
});
});
var resultmentionset = [...new Set(resultmention)];
if (resultmentionset.length > 0) {
resultstring += '<div id="resultmention">';
var resultmentionsetfiltered = resultmentionset.reduce( (arr, item) => {
if (!resultnameset.includes(item)) arr.push(item);
return arr;} , []);
if ( resultmentionsetfiltered.length > 0 ) {
resultstring += ( (lang == "ru") ? labels.mention[runame] : labels.mention[enname] )
+ ': ';
resultmentionsetfiltered.forEach(function(item, i, arr) {
if (i > 0) resultstring += '; ';
var langmention = (lang == "ru") ? farray[sortedarray[item].id][runame] : farray[sortedarray[item].id][enname];
resultstring += '<a href=".#' + langmention.split(' ').join('_')
+ '" onclick="currentArticle(' + sortedarray[item].id + ', '
+ "'farrayid'" + '); showPopup(' + "'hide'" + ')">'
+ langmention + '</a>';
});
}
resultstring += '</div>';
}
document.getElementById('searchresult').innerHTML = resultstring;
}
}
// Generating navigation array
function makeNavarray(column) {
var allelements = [];
farray.forEach(function(item, i, arr) {
if (i > 0) {
if (item[column])
strToArr(item[column], "cm").forEach(function(element, j, elarr) {
allelements.push(element);
});
}
});
var resultarray = {};
for (var i = 0; i < allelements.length; ++i) {
var el = allelements[i];
if (resultarray[el] != undefined)
++resultarray[el];
else
resultarray[el] = 1;
}
var sortedresult = {};
Object.keys(resultarray).sort().forEach(function(key) { sortedresult[key] = resultarray[key]; });
return sortedresult;
}
// Expanding the element of navigation
function navExpand(navelement) {
const divelement = document.getElementById(navelement);
var type = navelement.split('_')[0];
var element = navelement.slice(2).split('_').join(' ').trim();
var resultstring = element + ": ";
var expandedelements = [];
sortedarray.forEach(function(item, i, arr) {
if (strToArr(farray[item.id][type], "cm").includes(element)) {
expandedelements.push(item.id);
}
});
expandedelements.forEach(function(item, i, arr) {
if (i > 0) resultstring += ', ';
var name = (lang == "ru") ? farray[item][runame] : farray[item][enname];
resultstring += '<a href=".#' + name.split(' ').join('_')
+ '" onclick="currentArticle(' + item + ', '
+ "'farrayid'" + ');">' + name + '</a>';
});
divelement.innerHTML = resultstring;
divelement.classList.remove("navresult");
}
// Navigation
function fillNavigation(navbar) {
switch (navbar) {
case "activity":
var type = (lang == "ru") ? ruactivity : enactivity;
break;
case "locations":
var type = (lang == "ru") ? rulocations : enlocations;
break;
case "regions":
var type = (lang == "ru") ? ruregions : enregions;
break;
case "attributed":
var type = (lang == "ru") ? ruattributed : enattributed;
break;
case "kept":
var type = (lang == "ru") ? rukept : enkept;
break;
}
switch (navbar) {
case "activity":
case "locations":
case "regions":
case "attributed":
case "kept":
var mentionsarray = makeNavarray(type);
var resultstring = "";
var i = 0;
for (var key in mentionsarray) {
if (i > 0) resultstring += '; '; i++;
resultstring += '<div class="navresult" onclick="navExpand('
+ "'" + type + '_' + key.split(' ').join('_')
+ "'" + ')" id="' + type + '_'
+ key.split(' ').join('_') + '">' + key + ' ('
+ mentionsarray[key] + ')</div>';
}
document.getElementById('nav' + navbar).innerHTML = resultstring;
break;
case "all":
var resultstring = "";
sortedarray.forEach(function(item, i, arr) {
if (i > 0) resultstring += '; ';
var name = (lang == "ru") ? farray[item.id][runame] : farray[item.id][enname];
resultstring += '<a href=".#' + name.split(' ').join('_')
+ '" onclick="currentArticle(' + item.id + ', '
+ "'farrayid'" + '); showPopup(' + "'hide'"
+ ')">' + name + '</a>';
});
document.getElementById('navall').innerHTML = resultstring;
break;
default:
var navresult = '<details><summary onclick="fillNavigation(' + "'all'" + ');">'
+ ( (lang == "ru") ? labels.all[runame] : labels.all[enname] )
+ '</summary>' + '<div id="navall"></div></details>';
navresult += '<details><summary onclick="fillNavigation(' + "'activity'" + ');">'
+ ( (lang == "ru") ? farray[0][ruactivity] : farray[0][enactivity] )
+ '</summary>' + '<div id="navactivity"></div></details>';
navresult += '<details><summary onclick="fillNavigation(' + "'locations'" + ');">'
+ ( (lang == "ru") ? farray[0][rulocations] : farray[0][enlocations] )
+ '</summary>' + '<div id="navlocations"></div></details>';
navresult += '<details><summary onclick="fillNavigation(' + "'regions'" + ');">'
+ ( (lang == "ru") ? farray[0][ruregions] : farray[0][enregions] )
+ '</summary>' + '<div id="navregions"></div></details>';
navresult += '<details><summary onclick="fillNavigation(' + "'attributed'" + ');">'
+ ( (lang == "ru") ? farray[0][ruattributed] : farray[0][enattributed] )
+ '</summary>' + '<div id="navattributed"></div></details>';
navresult += '<details><summary onclick="fillNavigation(' + "'kept'" + ');">'
+ ( (lang == "ru") ? farray[0][rukept] : farray[0][enkept] )
+ '</summary>' + '<div id="navkept"></div></details>';
document.getElementById('navigationresult').innerHTML = navresult;
break;
}
}
// Edit/add entry
function fillEdit(type) {
var resultform = '<fieldset><legend>';
if (type == "edit") resultform += (lang == "ru") ? labels.edit[runame] : labels.edit[enname];
else resultform += (lang == "ru") ? labels.add[runame] : labels.add[enname];
resultform += '</legend>';
resultform += '<p>' + ((lang == "ru") ? labels.editinfo[runame] : labels.editinfo[enname]) + '</p>';
resultform += '<form>';
for (var i = 0; i < farray[0].length; i++) {
resultform += farray[0][i] + ':<br>';
resultform += '<textarea id="editadd' + i + '" rows="'
+ ( (i == ruarticle || i == enarticle) ? 10 : 2 )
+ '" placeholder="' + farray[0][i] + '">';
if (type == "edit") resultform += farray[sortedarray[current].id][i];
resultform += '</textarea><br>';
}
resultform += '<p align="right"><input type="button" value="'
+ ((lang == "ru") ? labels.send[runame] : labels.send[enname])
+ '" onclick="sendEntry()"> <input type="button" value="'
+ ((lang == "ru") ? labels.cancel[runame] : labels.cancel[enname])
+ '" onclick="showPopup(' + "'settings'" + ')"></p>';
resultform += '</form></fieldset>';
document.getElementById('editaddtab').innerHTML = resultform;
}
// Send data to the bash cgi script
function sendEntry() {
var csvrow = [];
for (var i = 0; i < farray[0].length; i++) {
var csvcell = document.getElementById('editadd' + i).value;
if (csvcell.includes('"')) csvcell = csvcell.replaceAll('"', '""');
if (csvcell.includes('"') || csvcell.includes(',') || (/\r|\n/.exec(csvcell))) csvcell = '"' + csvcell + '"';
csvrow.push(csvcell);
}
var csvdata = csvrow.join(",");
xmlhttp=new XMLHttpRequest();
xmlhttp.open('POST','../cgi-bin/upload.sh',true);
var newline = '!custom_newline!';
var content = csvdata.replace(/\n/g, newline);
xmlhttp.send(content);
alert('ok');
showPopup('settings');
}
// Keyboard event listener
document.addEventListener("keydown", function(e) {
if ( e.keyCode == 27 ) showPopup("hide"); // Esc
if ( e.keyCode == 112 ) showPopup("settings"); // F1
if ( e.keyCode == 113 ) showPopup("searchnav"); // F2
if ( e.keyCode == 37 ) currentArticle(current, "back"); // Left
if ( e.keyCode == 39 ) currentArticle(current, "forward"); // Right
});
// Execution after page loading
document.addEventListener("DOMContentLoaded", function(){
// Full forgers array reading from file
readCSV(ffilename, (csv) => {
farray = parseCSV(csv);
// Generating default sorted forgers array
for (var i = 1; i < farray.length; i++) {
sortedarray[i-1] = {};
sortedarray[i-1].id = i;
sortedarray[i-1].rusurname = farray[i][runame].split(" ").pop();
sortedarray[i-1].ensurname = farray[i][enname].split(" ").pop();
sortedarray[i-1].chrono = farray[i][years].split('-')[0];
sortedarray[i-1].rulocation = farray[i][rulocations].split('-')[0];
sortedarray[i-1].enlocation = farray[i][enlocations].split('-')[0];
}
// Anchor link check
if (window.location.hash.slice(0,1) == "#") {
// Checking for name matches
for (var i = 0; i < sortedarray.length; i++) {
// English checking
if (farray[sortedarray[i].id][enname] == URIanchor ) {
lang = "en";
current = i;
break;
}
// Russian checking
if (farray[sortedarray[i].id][runame] == URIanchor ) {
lang = "ru";
current = i;
break;
}
}
}
makeScreen(); currentInterface(); currentStyle(); changeSettings();
document.getElementById('farticle').focus();
})
});
</script>
</head>
<body id="mainbody">
<div id="mainscreen">
<div id="datafields" class="page"></div>
<div id="fullpopup" class="popup"></div>
</div>
</body>
</html>

0
html/fdb/upload.csv Normal file
View File