Update upload interface and ignore temporary E2E artifacts
Deploy drhider / validate (push) Canceled after 0s
Deploy drhider / validate (push) Canceled after 0s
This commit is contained in:
@@ -3,7 +3,7 @@
|
||||
- НЕЛЬЗЯ менять ЧТО-ЛИБО при вопросе (?, почему, как, где, что) — только ответ словами
|
||||
- НЕЛЬЗЯ спешить — обдумать, проверить, потом отвечать
|
||||
- НЕЛЬЗЯ лезть в /home/naeel/nubes/contracts/ (кроме loadtest)
|
||||
- НЕЛЬЗЯ предполагать — сомневаешься = спроси
|
||||
- НИКОГДА не руководствоваться догадками. Если что-либо неизвестно точно или недоступно — немедленно остановиться и сообщить об этом; не продолжать действие и не выдавать предположение за факт.
|
||||
- НЕЛЬЗЯ грузить внешние CDN/библиотеки на фронтенд — всё в коде
|
||||
|
||||
# ✅ ПОРЯДОК ПРАВКИ
|
||||
|
||||
@@ -26,6 +26,8 @@ dist/
|
||||
# about1500.md
|
||||
*.har
|
||||
chrome-net-export-log.json
|
||||
History/tests/2026-09-15-*.md
|
||||
tests/e2e_mass_processing.py
|
||||
TSTFILES/
|
||||
files/
|
||||
upload-platform/
|
||||
|
||||
+407
-90
@@ -1,5 +1,6 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="ru">
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
@@ -20,127 +21,430 @@
|
||||
--red: #ef4444;
|
||||
--green: #22c55e;
|
||||
}
|
||||
* { box-sizing: border-box; margin: 0; padding: 0; }
|
||||
body { font: 14px system-ui, sans-serif; color: var(--text); background: var(--bg); min-height: 100vh; }
|
||||
.topbar {
|
||||
background: var(--card); border-bottom: 1px solid var(--brand-gray);
|
||||
padding: 0 16px; height: 48px; display: flex; align-items: center; gap: 10px;
|
||||
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
.topbar img { height: 18px; }
|
||||
.topbar .title { font-weight: 600; font-size: 14px; }
|
||||
.topbar .ver { font-weight: 400; color: var(--muted); font-size: 12px; }
|
||||
|
||||
body {
|
||||
font: 14px system-ui, sans-serif;
|
||||
color: var(--text);
|
||||
background: var(--bg);
|
||||
min-height: 100vh;
|
||||
}
|
||||
|
||||
.topbar {
|
||||
background: var(--card);
|
||||
border-bottom: 1px solid var(--brand-gray);
|
||||
padding: 0 16px;
|
||||
height: 48px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.topbar img {
|
||||
height: 18px;
|
||||
}
|
||||
|
||||
.topbar .title {
|
||||
font-weight: 600;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.topbar .ver {
|
||||
font-weight: 400;
|
||||
color: var(--muted);
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.topbar .help {
|
||||
margin-left: auto; cursor: pointer; text-decoration: none; user-select: none;
|
||||
display: inline-flex; align-items: center; justify-content: center;
|
||||
padding: 5px 14px; border-radius: 6px;
|
||||
background: #1d4ed8; color: #fff; font-size: 13px; font-weight: 700; line-height: 1;
|
||||
margin-left: auto;
|
||||
cursor: pointer;
|
||||
text-decoration: none;
|
||||
user-select: none;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 5px 14px;
|
||||
border-radius: 6px;
|
||||
background: #1d4ed8;
|
||||
color: #fff;
|
||||
font-size: 13px;
|
||||
font-weight: 700;
|
||||
line-height: 1;
|
||||
letter-spacing: .06em;
|
||||
box-shadow: 0 1px 3px rgba(0, 0, 0, .25);
|
||||
}
|
||||
.topbar .help:hover { background: #1e40af; color: #fff; }
|
||||
.content { max-width: 820px; margin: 20px auto; padding: 0 12px; }
|
||||
|
||||
.topbar .help:hover {
|
||||
background: #1e40af;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.content {
|
||||
max-width: 820px;
|
||||
margin: 20px auto;
|
||||
padding: 0 12px;
|
||||
}
|
||||
|
||||
.card {
|
||||
background: var(--card); border-radius: 12px;
|
||||
border: 1px solid var(--brand-gray); box-shadow: 0 1px 2px rgba(0,0,0,.04);
|
||||
background: var(--card);
|
||||
border-radius: 12px;
|
||||
border: 1px solid var(--brand-gray);
|
||||
box-shadow: 0 1px 2px rgba(0, 0, 0, .04);
|
||||
}
|
||||
|
||||
.card-header {
|
||||
background: var(--brand-grey-light); padding: 10px 12px;
|
||||
font-weight: 600; font-size: 14px; border-bottom: 1px solid var(--brand-gray);
|
||||
background: var(--brand-grey-light);
|
||||
padding: 10px 12px;
|
||||
font-weight: 600;
|
||||
font-size: 14px;
|
||||
border-bottom: 1px solid var(--brand-gray);
|
||||
}
|
||||
|
||||
.card-body {
|
||||
padding: 12px;
|
||||
}
|
||||
|
||||
.sub {
|
||||
font-size: 12px;
|
||||
color: var(--muted);
|
||||
margin-bottom: 10px;
|
||||
line-height: 1.5;
|
||||
}
|
||||
.card-body { padding: 12px; }
|
||||
.sub { font-size: 12px; color: var(--muted); margin-bottom: 10px; line-height: 1.5; }
|
||||
|
||||
/* FilePicker styling */
|
||||
.file-picker { font-family: inherit; color: var(--text); }
|
||||
.file-picker .fp-toolbar { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 10px; }
|
||||
.file-picker {
|
||||
font-family: inherit;
|
||||
color: var(--text);
|
||||
}
|
||||
|
||||
.file-picker .fp-toolbar {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 8px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.file-picker .fp-toolbar button {
|
||||
height: 32px; border-radius: 6px; padding: 0 12px; font-size: 13px;
|
||||
font-family: inherit; cursor: pointer; border: 1px solid var(--brand-gray);
|
||||
background: var(--card); color: var(--text);
|
||||
display: inline-flex; align-items: center; gap: 5px; font-weight: 500;
|
||||
height: 32px;
|
||||
border-radius: 6px;
|
||||
padding: 0 12px;
|
||||
font-size: 13px;
|
||||
font-family: inherit;
|
||||
cursor: pointer;
|
||||
border: 1px solid var(--brand-gray);
|
||||
background: var(--card);
|
||||
color: var(--text);
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 5px;
|
||||
font-weight: 500;
|
||||
}
|
||||
.file-picker .fp-toolbar button#fp-files-btn { background: #eff6ff; border-color: var(--brand-primary); color: var(--brand-primary); }
|
||||
.file-picker .fp-toolbar button#fp-folder-btn { background: var(--card); }
|
||||
.file-picker .fp-toolbar button#fp-clear-btn { color: var(--muted); border-color: transparent; }
|
||||
.file-picker .fp-toolbar button#fp-clear-btn:hover { color: var(--red); }
|
||||
.file-picker .fp-table-wrap { border: 1px solid var(--brand-gray); border-radius: 8px; overflow: hidden; margin-bottom: 6px; }
|
||||
.file-picker .fp-table { width: 100%; border-collapse: collapse; font-size: 13px; }
|
||||
|
||||
.file-picker .fp-toolbar button#fp-files-btn {
|
||||
background: #eff6ff;
|
||||
border-color: var(--brand-primary);
|
||||
color: var(--brand-primary);
|
||||
}
|
||||
|
||||
.file-picker .fp-toolbar button#fp-folder-btn {
|
||||
background: var(--card);
|
||||
}
|
||||
|
||||
.file-picker .fp-toolbar button#fp-clear-btn {
|
||||
color: var(--muted);
|
||||
border-color: transparent;
|
||||
}
|
||||
|
||||
.file-picker .fp-toolbar button#fp-clear-btn:hover {
|
||||
color: var(--red);
|
||||
}
|
||||
|
||||
.file-picker .fp-table-wrap {
|
||||
border: 1px solid var(--brand-gray);
|
||||
border-radius: 8px;
|
||||
overflow: hidden;
|
||||
margin-bottom: 6px;
|
||||
}
|
||||
|
||||
.file-picker .fp-table {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.file-picker .fp-table th {
|
||||
background: var(--brand-grey-light); text-transform: uppercase; padding: 6px 8px;
|
||||
border-right: 1px solid var(--brand-gray); border-bottom: 1px solid var(--brand-gray);
|
||||
text-align: left; font-weight: 600; font-size: 10px; color: var(--muted);
|
||||
background: var(--brand-grey-light);
|
||||
text-transform: uppercase;
|
||||
padding: 6px 8px;
|
||||
border-right: 1px solid var(--brand-gray);
|
||||
border-bottom: 1px solid var(--brand-gray);
|
||||
text-align: left;
|
||||
font-weight: 600;
|
||||
font-size: 10px;
|
||||
color: var(--muted);
|
||||
}
|
||||
|
||||
.file-picker .fp-table td {
|
||||
padding: 5px 8px; border-right: 1px solid var(--brand-gray); border-bottom: 1px solid var(--brand-gray);
|
||||
padding: 5px 8px;
|
||||
border-right: 1px solid var(--brand-gray);
|
||||
border-bottom: 1px solid var(--brand-gray);
|
||||
}
|
||||
.file-picker .tree-row:hover td { background: rgba(37,99,235,.03); }
|
||||
.file-picker .tree-row.row-current td { background: rgba(37,99,235,.12) !important; color: #1d4ed8; font-weight: 600; }
|
||||
|
||||
.file-picker .tree-row:hover td {
|
||||
background: rgba(37, 99, 235, .03);
|
||||
}
|
||||
|
||||
.file-picker .tree-row.row-current td {
|
||||
background: rgba(37, 99, 235, .12) !important;
|
||||
color: #1d4ed8;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.file-picker .tree-name {
|
||||
display: inline-flex; align-items: center; gap: 6px; border: 0; background: transparent;
|
||||
color: inherit; font: inherit; text-align: left; cursor: pointer;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
border: 0;
|
||||
background: transparent;
|
||||
color: inherit;
|
||||
font: inherit;
|
||||
text-align: left;
|
||||
cursor: pointer;
|
||||
}
|
||||
.file-picker .tree-chevron { display: inline-block; width: 12px; color: var(--muted); font-size: 9px; }
|
||||
.file-picker .fp-status { font-size: 12px; color: var(--muted); margin: 4px 0; }
|
||||
.file-picker .fp-count { display: none; }
|
||||
|
||||
.file-picker .tree-chevron {
|
||||
display: inline-block;
|
||||
width: 12px;
|
||||
color: var(--muted);
|
||||
font-size: 9px;
|
||||
}
|
||||
|
||||
.file-picker .fp-status {
|
||||
font-size: 12px;
|
||||
color: var(--muted);
|
||||
margin: 4px 0;
|
||||
}
|
||||
|
||||
.file-picker .fp-count {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.file-picker .remove-btn {
|
||||
cursor: pointer; color: #f87171; background: none; border: none;
|
||||
padding: 2px 4px; font-size: 14px; line-height: 1;
|
||||
cursor: pointer;
|
||||
color: #f87171;
|
||||
background: none;
|
||||
border: none;
|
||||
padding: 2px 4px;
|
||||
font-size: 14px;
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
.file-picker .remove-btn:hover {
|
||||
color: var(--red);
|
||||
}
|
||||
|
||||
body.busy .file-picker button {
|
||||
pointer-events: none;
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
body.busy .file-picker .remove-btn {
|
||||
display: none;
|
||||
}
|
||||
.file-picker .remove-btn:hover { color: var(--red); }
|
||||
body.busy .file-picker button { pointer-events: none; opacity: 0.5; }
|
||||
body.busy .file-picker .remove-btn { display: none; }
|
||||
|
||||
.footer-bar {
|
||||
margin-top: 10px; display: flex; justify-content: space-between; align-items: center;
|
||||
font-size: 12px; color: var(--muted);
|
||||
margin-top: 10px;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
font-size: 12px;
|
||||
color: var(--muted);
|
||||
}
|
||||
|
||||
.btn {
|
||||
height: 32px; border-radius: 6px; padding: 0 12px; font-size: 13px;
|
||||
font-family: inherit; cursor: pointer; border: 1px solid var(--brand-gray);
|
||||
background: var(--card); color: var(--text);
|
||||
display: inline-flex; align-items: center; gap: 5px;
|
||||
height: 32px;
|
||||
border-radius: 6px;
|
||||
padding: 0 12px;
|
||||
font-size: 13px;
|
||||
font-family: inherit;
|
||||
cursor: pointer;
|
||||
border: 1px solid var(--brand-gray);
|
||||
background: var(--card);
|
||||
color: var(--text);
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 5px;
|
||||
}
|
||||
.btn-primary { background: var(--brand-primary); border-color: var(--brand-primary); color: #fff; }
|
||||
.btn-primary:hover { opacity: .9; }
|
||||
.btn:disabled { opacity: .4; cursor: not-allowed; }
|
||||
.status { margin-top: 10px; padding: 8px 12px; border-radius: 8px; font-size: 13px; display: none; }
|
||||
.status.progress { background: #eff6ff; border: 1px solid var(--brand-primary); color: var(--brand-primary); display: block; }
|
||||
.status.done { background: #f0fdf4; border: 1px solid var(--green); color: #16a34a; display: block; }
|
||||
.status.error { background: #fef2f2; border: 1px solid var(--red); color: #991b1b; display: block; }
|
||||
.dl-btns { display: none; gap: 8px; margin-top: 8px; }
|
||||
.dl-btns.show { display: flex; }
|
||||
|
||||
.btn-primary {
|
||||
background: var(--brand-primary);
|
||||
border-color: var(--brand-primary);
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.btn-primary:hover {
|
||||
opacity: .9;
|
||||
}
|
||||
|
||||
.btn:disabled {
|
||||
opacity: .4;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
.status {
|
||||
margin-top: 10px;
|
||||
padding: 8px 12px;
|
||||
border-radius: 8px;
|
||||
font-size: 13px;
|
||||
display: none;
|
||||
}
|
||||
|
||||
.status.progress {
|
||||
background: #eff6ff;
|
||||
border: 1px solid var(--brand-primary);
|
||||
color: var(--brand-primary);
|
||||
display: block;
|
||||
}
|
||||
|
||||
.status.done {
|
||||
background: #f0fdf4;
|
||||
border: 1px solid var(--green);
|
||||
color: #16a34a;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.status.error {
|
||||
background: #fef2f2;
|
||||
border: 1px solid var(--red);
|
||||
color: #991b1b;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.dl-btns {
|
||||
display: none;
|
||||
gap: 8px;
|
||||
margin-top: 8px;
|
||||
}
|
||||
|
||||
.dl-btns.show {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.stats-block {
|
||||
display: none; margin-top: 12px; padding: 16px;
|
||||
display: none;
|
||||
margin-top: 12px;
|
||||
padding: 16px;
|
||||
background: linear-gradient(135deg, #f0fdf4, #ecfdf5);
|
||||
border: 2px solid var(--green); border-radius: 12px;
|
||||
border: 2px solid var(--green);
|
||||
border-radius: 12px;
|
||||
}
|
||||
.stats-block.show { display: block; }
|
||||
.stats-title { font-size: 16px; font-weight: 700; color: #14532d; margin-bottom: 10px; }
|
||||
.stats-row { display: flex; flex-wrap: wrap; gap: 10px; }
|
||||
|
||||
.stats-block.show {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.stats-title {
|
||||
font-size: 16px;
|
||||
font-weight: 700;
|
||||
color: #14532d;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.stats-row {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.stat-item {
|
||||
flex: 1; min-width: 130px; background: #fff; border: 1px solid #bbf7d0;
|
||||
border-radius: 10px; padding: 10px 12px; text-align: center;
|
||||
flex: 1;
|
||||
min-width: 130px;
|
||||
background: #fff;
|
||||
border: 1px solid #bbf7d0;
|
||||
border-radius: 10px;
|
||||
padding: 10px 12px;
|
||||
text-align: center;
|
||||
}
|
||||
.stat-label { font-size: 12px; text-transform: uppercase; letter-spacing: .04em; color: var(--muted); margin-bottom: 4px; }
|
||||
.stat-value { font-size: 24px; font-weight: 800; color: #166534; }
|
||||
|
||||
.stat-label {
|
||||
font-size: 12px;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: .04em;
|
||||
color: var(--muted);
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
|
||||
.stat-value {
|
||||
font-size: 24px;
|
||||
font-weight: 800;
|
||||
color: #166534;
|
||||
}
|
||||
|
||||
.live-block {
|
||||
display: none; margin-top: 12px; padding: 16px;
|
||||
display: none;
|
||||
margin-top: 12px;
|
||||
padding: 16px;
|
||||
background: linear-gradient(135deg, #eff6ff, #dbeafe);
|
||||
border: 2px solid var(--brand-primary); border-radius: 12px;
|
||||
border: 2px solid var(--brand-primary);
|
||||
border-radius: 12px;
|
||||
}
|
||||
.live-block.show { display: block; }
|
||||
.live-title { font-size: 18px; font-weight: 800; color: #1e40af; margin-bottom: 6px; }
|
||||
.live-file { font-size: 15px; color: #1e3a8a; margin-bottom: 10px; word-break: break-word; }
|
||||
.live-timer { font-size: 40px; font-weight: 800; color: #1d4ed8; line-height: 1.1; }
|
||||
|
||||
.live-block.show {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.live-title {
|
||||
font-size: 18px;
|
||||
font-weight: 800;
|
||||
color: #1e40af;
|
||||
margin-bottom: 6px;
|
||||
}
|
||||
|
||||
.live-file {
|
||||
font-size: 15px;
|
||||
color: #1e3a8a;
|
||||
margin-bottom: 10px;
|
||||
word-break: break-word;
|
||||
}
|
||||
|
||||
.live-timer {
|
||||
font-size: 40px;
|
||||
font-weight: 800;
|
||||
color: #1d4ed8;
|
||||
line-height: 1.1;
|
||||
}
|
||||
|
||||
.live-llm {
|
||||
display: none; margin-top: 8px; padding: 8px 12px; border-radius: 8px;
|
||||
background: #fef3c7; border: 1px solid #f59e0b; color: #92400e;
|
||||
font-size: 18px; font-weight: 700; width: fit-content;
|
||||
display: none;
|
||||
margin-top: 8px;
|
||||
padding: 8px 12px;
|
||||
border-radius: 8px;
|
||||
background: #fef3c7;
|
||||
border: 1px solid #f59e0b;
|
||||
color: #92400e;
|
||||
font-size: 18px;
|
||||
font-weight: 700;
|
||||
width: fit-content;
|
||||
}
|
||||
|
||||
.live-llm.show {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.live-eta {
|
||||
margin-top: 8px;
|
||||
font-size: 14px;
|
||||
color: #1d4ed8;
|
||||
font-weight: 600;
|
||||
}
|
||||
.live-llm.show { display: inline-block; }
|
||||
.live-eta { margin-top: 8px; font-size: 14px; color: #1d4ed8; font-weight: 600; }
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div class="topbar">
|
||||
<img src="/static/logo.svg" alt="Nubes">
|
||||
@@ -155,7 +459,9 @@
|
||||
<p class="sub">
|
||||
Загрузите документы (.docx, .doc, .pdf, .txt, .md, .zip) — получите ZIP с обезличенными копиями.<br>
|
||||
CSV с таблицей замен скачивается отдельно.<br>
|
||||
<span style="color:#c0392b;">Ограничения: один файл не более 50 МБ, суммарно не более 500 МБ. Файлы сверх лимитов помечаются статусом «пропущен» и не участвуют в обфускации. Пустые, повреждённые файлы и сканы без текстового слоя получают статус «не извлечён» — они тоже не попадают в результат.</span><br>
|
||||
<span style="color:#c0392b;">Ограничения: один файл не более 50 МБ, суммарно не более 500 МБ. Файлы сверх
|
||||
лимитов помечаются статусом «пропущен» и не участвуют в обфускации. Пустые, повреждённые файлы и сканы без
|
||||
текстового слоя получают статус «не извлечён» — они тоже не попадают в результат.</span><br>
|
||||
<span style="color:#7d3c98;">⏱ Время обработки каждого файла — ориентировочное (обновляется по факту).</span>
|
||||
</p>
|
||||
|
||||
@@ -612,19 +918,29 @@ window.downloadCsv = downloadCsv;
|
||||
|
||||
fetch('/health').catch(() => { });
|
||||
</script>
|
||||
<div id="helpModal" style="display:none;position:fixed;top:0;left:0;width:100%;height:100%;background:rgba(0,0,0,.5);z-index:999;justify-content:center;align-items:center" onclick="this.style.display='none'">
|
||||
<div style="background:var(--card);border-radius:12px;padding:24px;max-width:420px;box-shadow:0 4px 24px rgba(0,0,0,.15)" onclick="event.stopPropagation()">
|
||||
<div id="helpModal"
|
||||
style="display:none;position:fixed;top:0;left:0;width:100%;height:100%;background:rgba(0,0,0,.5);z-index:999;justify-content:center;align-items:center"
|
||||
onclick="this.style.display='none'">
|
||||
<div
|
||||
style="background:var(--card);border-radius:12px;padding:24px;max-width:420px;box-shadow:0 4px 24px rgba(0,0,0,.15)"
|
||||
onclick="event.stopPropagation()">
|
||||
<h3 style="margin-bottom:12px">DrHider — обфускация документов</h3>
|
||||
<p style="font-size:13px;color:var(--muted);line-height:1.6">
|
||||
Загрузите документы (.docx, .doc, .pdf, .txt, .md, .zip) — получите ZIP-архив с обезличенными копиями.
|
||||
Персональные данные, реквизиты компаний, телефоны, email и другие приватные сведения заменяются на обезличенные коды.
|
||||
Персональные данные, реквизиты компаний, телефоны, email и другие приватные сведения заменяются на обезличенные
|
||||
коды.
|
||||
CSV-файл с таблицей соответствия оригинал→замена скачивается отдельно.
|
||||
</p>
|
||||
<button class="btn" style="margin-top:12px;width:100%" onclick="document.getElementById('helpModal').style.display='none'">Закрыть</button>
|
||||
<button class="btn" style="margin-top:12px;width:100%"
|
||||
onclick="document.getElementById('helpModal').style.display='none'">Закрыть</button>
|
||||
</div>
|
||||
</div>
|
||||
<div id="cancelModal" style="display:none;position:fixed;top:0;left:0;width:100%;height:100%;background:rgba(0,0,0,.5);z-index:999;justify-content:center;align-items:center" onclick="this.style.display='none'">
|
||||
<div style="background:var(--card);border-radius:12px;padding:24px;max-width:440px;box-shadow:0 4px 24px rgba(0,0,0,.15)" onclick="event.stopPropagation()">
|
||||
<div id="cancelModal"
|
||||
style="display:none;position:fixed;top:0;left:0;width:100%;height:100%;background:rgba(0,0,0,.5);z-index:999;justify-content:center;align-items:center"
|
||||
onclick="this.style.display='none'">
|
||||
<div
|
||||
style="background:var(--card);border-radius:12px;padding:24px;max-width:440px;box-shadow:0 4px 24px rgba(0,0,0,.15)"
|
||||
onclick="event.stopPropagation()">
|
||||
<h3 style="margin-bottom:12px">⏹ Остановить обработку?</h3>
|
||||
<p style="font-size:13px;color:var(--muted);line-height:1.6" id="cancelModalText">
|
||||
Будут сохранены: полностью обработанные файлы и таблица замен.
|
||||
@@ -638,4 +954,5 @@ fetch('/health').catch(() => {});
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
Reference in New Issue
Block a user