wa-dev-tools/public/editor.html
2026-03-21 22:06:15 +03:00

273 lines
30 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!DOCTYPE html>
<html lang="ru" class="dark">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Editor — images.wadevelop.ru</title>
<link href="/vendor/fonts.css" rel="stylesheet">
<link rel="stylesheet" href="/editor.css">
</head>
<body>
<!-- Sidebar -->
<nav class="sidebar">
<div class="sidebar-logo">WA</div>
<div class="sidebar-nav">
<a href="/" class="sidebar-link" title="Главная"><svg width="22" height="22" fill="none" stroke="currentColor" viewBox="0 0 24 24" stroke-width="1.5"><path stroke-linecap="round" stroke-linejoin="round" d="M2.25 12l8.954-8.955c.44-.439 1.152-.439 1.591 0L21.75 12M4.5 9.75v10.125c0 .621.504 1.125 1.125 1.125H9.75v-4.875c0-.621.504-1.125 1.125-1.125h2.25c.621 0 1.125.504 1.125 1.125V21h4.125c.621 0 1.125-.504 1.125-1.125V9.75M8.25 21h8.25"/></svg></a>
<a href="/compress" class="sidebar-link" title="Картинки"><svg width="22" height="22" fill="none" stroke="currentColor" viewBox="0 0 24 24" stroke-width="1.5"><path stroke-linecap="round" stroke-linejoin="round" d="M2.25 15.75l5.159-5.159a2.25 2.25 0 013.182 0l5.159 5.159m-1.5-1.5l1.409-1.409a2.25 2.25 0 013.182 0l2.909 2.909M3.75 21h16.5A2.25 2.25 0 0023.25 18.75V5.25A2.25 2.25 0 0021 3H3.75A2.25 2.25 0 001.5 5.25v13.5A2.25 2.25 0 003.75 21z"/></svg></a>
<a href="/md" class="sidebar-link" title="Markdown"><svg width="22" height="22" fill="none" stroke="currentColor" viewBox="0 0 24 24" stroke-width="1.5"><path stroke-linecap="round" stroke-linejoin="round" d="M19.5 14.25v-2.625a3.375 3.375 0 00-3.375-3.375h-1.5A1.125 1.125 0 0113.5 7.125v-1.5a3.375 3.375 0 00-3.375-3.375H8.25m0 12.75h7.5m-7.5 3H12M10.5 2.25H5.625c-.621 0-1.125.504-1.125 1.125v17.25c0 .621.504 1.125 1.125 1.125h12.75c.621 0 1.125-.504 1.125-1.125V11.25a9 9 0 00-9-9z"/></svg></a>
<a href="/placeholder" class="sidebar-link" title="Placeholder"><svg width="22" height="22" fill="none" stroke="currentColor" viewBox="0 0 24 24" stroke-width="1.5"><path stroke-linecap="round" stroke-linejoin="round" d="M9.75 3.104v5.714a2.25 2.25 0 01-.659 1.591L5 14.5M9.75 3.104c-.251.023-.501.05-.75.082m.75-.082a24.301 24.301 0 014.5 0m0 0v5.714a2.25 2.25 0 00.659 1.591L19 14.5M14.25 3.104c.251.023.501.05.75.082M19 14.5l-2.47 2.47a2.25 2.25 0 01-1.59.659H9.06a2.25 2.25 0 01-1.591-.659L5 14.5m14 0V17a2.25 2.25 0 01-2.25 2.25H7.25A2.25 2.25 0 015 17v-2.5"/></svg></a>
<a href="/parser" class="sidebar-link" title="Parser"><svg width="22" height="22" fill="none" stroke="currentColor" viewBox="0 0 24 24" stroke-width="1.5"><path stroke-linecap="round" stroke-linejoin="round" d="M13.19 8.688a4.5 4.5 0 011.242 7.244l-4.5 4.5a4.5 4.5 0 01-6.364-6.364l1.757-1.757m9.86-2.06a4.5 4.5 0 00-6.364-6.364L6.257 6.514a4.5 4.5 0 001.242 7.244"/></svg></a>
<a href="/password" class="sidebar-link" title="Password"><svg width="22" height="22" fill="none" stroke="currentColor" viewBox="0 0 24 24" stroke-width="1.5"><path stroke-linecap="round" stroke-linejoin="round" d="M15.75 5.25a3 3 0 013 3m3 0a6 6 0 01-7.029 5.912c-.563-.097-1.159.026-1.563.43L10.5 17.25H8.25v2.25H6v2.25H2.25v-2.818c0-.597.237-1.17.659-1.591l6.499-6.499c.404-.404.527-1 .43-1.563A6 6 0 1121.75 8.25z"/></svg></a>
<a href="/sanitizer" class="sidebar-link" title="Sanitizer"><svg width="22" height="22" fill="none" stroke="currentColor" viewBox="0 0 24 24" stroke-width="1.5"><path stroke-linecap="round" stroke-linejoin="round" d="M9 12.75L11.25 15 15 9.75m-3-7.036A11.959 11.959 0 013.598 6 11.99 11.99 0 003 9.749c0 5.592 3.824 10.29 9 11.623 5.176-1.332 9-6.03 9-11.622 0-1.31-.21-2.571-.598-3.751h-.152c-3.196 0-6.1-1.248-8.25-3.285z"/></svg></a>
<a href="/converter" class="sidebar-link" title="Converter"><svg width="22" height="22" fill="none" stroke="currentColor" viewBox="0 0 24 24" stroke-width="1.5"><path stroke-linecap="round" stroke-linejoin="round" d="M7.5 21L3 16.5m0 0L7.5 12M3 16.5h13.5m0-13.5L21 7.5m0 0L16.5 12M21 7.5H7.5"/></svg></a>
<a href="/formatter" class="sidebar-link" title="Formatter"><svg width="22" height="22" fill="none" stroke="currentColor" viewBox="0 0 24 24" stroke-width="1.5"><path stroke-linecap="round" stroke-linejoin="round" d="M17.25 6.75L22.5 12l-5.25 5.25m-10.5 0L1.5 12l5.25-5.25m7.5-3l-4.5 16.5"/></svg></a>
<a href="/editor" class="sidebar-link active" title="Editor"><svg width="22" height="22" fill="none" stroke="currentColor" viewBox="0 0 24 24" stroke-width="1.5"><path stroke-linecap="round" stroke-linejoin="round" d="M16.862 4.487l1.687-1.688a1.875 1.875 0 112.652 2.652L10.582 16.07a4.5 4.5 0 01-1.897 1.13L6 18l.8-2.685a4.5 4.5 0 011.13-1.897l8.932-8.931zm0 0L19.5 7.125M18 14v4.75A2.25 2.25 0 0115.75 21H5.25A2.25 2.25 0 013 18.75V8.25A2.25 2.25 0 015.25 6H10"/></svg></a>
<a href="/httpclient" class="sidebar-link" title="HTTP Client">
<svg width="22" height="22" fill="none" stroke="currentColor" viewBox="0 0 24 24" stroke-width="1.5"><path stroke-linecap="round" stroke-linejoin="round" d="M6 12L3.269 3.126A59.768 59.768 0 0121.485 12 59.77 59.77 0 013.27 20.876L5.999 12zm0 0h7.5"/></svg>
</a>
<a href="/redirects" class="sidebar-link" title="Redirect Analyzer">
<svg width="22" height="22" fill="none" stroke="currentColor" viewBox="0 0 24 24" stroke-width="1.5"><path stroke-linecap="round" stroke-linejoin="round" d="M13.5 6H5.25A2.25 2.25 0 003 8.25v10.5A2.25 2.25 0 005.25 21h10.5A2.25 2.25 0 0018 18.75V10.5m-10.5 6L21 3m0 0h-5.25M21 3v5.25"/></svg>
</a>
<a href="/svgeditor" class="sidebar-link" title="SVG Редактор">
<svg width="22" height="22" fill="none" stroke="currentColor" viewBox="0 0 24 24" stroke-width="1.5"><path stroke-linecap="round" stroke-linejoin="round" d="M9.53 16.122a3 3 0 00-5.78 1.128 2.25 2.25 0 01-2.4 2.245 4.5 4.5 0 008.4-2.245c0-.399-.078-.78-.22-1.128zm0 0a15.998 15.998 0 003.388-1.62m-5.043-.025a15.994 15.994 0 011.622-3.395m3.42 3.42a15.995 15.995 0 004.764-4.648l3.876-5.814a1.151 1.151 0 00-1.597-1.597L14.146 6.32a15.996 15.996 0 00-4.649 4.763m3.42 3.42a6.776 6.776 0 00-3.42-3.42"/></svg>
</a>
</div>
</nav>
<!-- Editor -->
<div class="editor-wrap">
<!-- Toolbar -->
<div class="toolbar">
<div class="toolbar-group">
<button class="tb" id="btnOpen" title="Open (Ctrl+O)"><svg fill="none" stroke="currentColor" viewBox="0 0 24 24" stroke-width="1.5"><path stroke-linecap="round" stroke-linejoin="round" d="M3.75 9.776c.112-.017.227-.026.344-.026h15.812c.117 0 .232.009.344.026m-16.5 0a2.25 2.25 0 00-1.883 2.542l.857 6a2.25 2.25 0 002.227 1.932H19.05a2.25 2.25 0 002.227-1.932l.857-6a2.25 2.25 0 00-1.883-2.542m-16.5 0V6A2.25 2.25 0 016 3.75h3.879a1.5 1.5 0 011.06.44l2.122 2.12a1.5 1.5 0 001.06.44H18A2.25 2.25 0 0120.25 9v.776"/></svg></button>
<button class="tb" id="btnExport" title="Export (Ctrl+S)" disabled><svg fill="none" stroke="currentColor" viewBox="0 0 24 24" stroke-width="1.5"><path stroke-linecap="round" stroke-linejoin="round" d="M3 16.5v2.25A2.25 2.25 0 005.25 21h13.5A2.25 2.25 0 0021 18.75V16.5M16.5 12L12 16.5m0 0L7.5 12m4.5 4.5V3"/></svg></button>
</div>
<div class="toolbar-sep"></div>
<!-- Drawing tools -->
<div class="toolbar-group" id="toolsGroup">
<button class="tb" data-tool="select" title="Выделение (V)" disabled><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5"><path stroke-linecap="round" stroke-linejoin="round" d="M3 3l7.07 16.97 2.51-7.39 7.39-2.51L3 3z"/><path stroke-linecap="round" stroke-linejoin="round" d="M13 13l6 6"/></svg></button>
<button class="tb" data-tool="crop" title="Вырезать (C)" disabled><svg fill="none" stroke="currentColor" viewBox="0 0 24 24" stroke-width="1.5"><path stroke-linecap="round" stroke-linejoin="round" d="M7.5 3.75H6A2.25 2.25 0 003.75 6v1.5M16.5 3.75H18A2.25 2.25 0 0120.25 6v1.5m0 9V18A2.25 2.25 0 0118 20.25h-1.5m-9 0H6A2.25 2.25 0 013.75 18v-1.5"/></svg></button>
<button class="tb" data-tool="brush" title="Кисть (B)" disabled><svg fill="none" stroke="currentColor" viewBox="0 0 24 24" stroke-width="1.5"><path stroke-linecap="round" stroke-linejoin="round" d="M9.53 16.122a3 3 0 00-5.78 1.128 2.25 2.25 0 01-2.4 2.245 4.5 4.5 0 008.4-2.245c0-.399-.078-.78-.22-1.128zm0 0a15.998 15.998 0 003.388-1.62m-5.043-.025a15.994 15.994 0 011.622-3.395m3.42 3.42a15.995 15.995 0 004.764-4.648l3.876-5.814a1.151 1.151 0 00-1.597-1.597L14.146 6.32a15.996 15.996 0 00-4.649 4.763m3.42 3.42a6.776 6.776 0 00-3.42-3.42"/></svg></button>
<button class="tb" data-tool="eraser" title="Ластик (E)" disabled><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5"><path stroke-linecap="round" stroke-linejoin="round" d="M5.505 14.706L10.293 19.5H14.5m-9-4.794l8.5-8.5a2 2 0 012.828 0l2.466 2.466a2 2 0 010 2.828l-8.5 8.5H6.706a2 2 0 01-1.414-.586l-1.2-1.2a2 2 0 010-2.828z"/><path stroke-linecap="round" d="M8 21h12"/></svg></button>
<button class="tb" data-tool="line" title="Линия (L)" disabled><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5"><line x1="5" y1="19" x2="19" y2="5" stroke-linecap="round"/></svg></button>
<button class="tb" data-tool="rect" title="Прямоугольник (U)" disabled><svg fill="none" stroke="currentColor" viewBox="0 0 24 24" stroke-width="1.5"><rect x="3" y="3" width="18" height="18" rx="2" stroke-linecap="round" stroke-linejoin="round"/></svg></button>
<button class="tb" data-tool="circle" title="Круг (O)" disabled><svg fill="none" stroke="currentColor" viewBox="0 0 24 24" stroke-width="1.5"><ellipse cx="12" cy="12" rx="9" ry="9"/></svg></button>
<button class="tb" data-tool="arrow" title="Стрелка (A)" disabled><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5"><path stroke-linecap="round" stroke-linejoin="round" d="M4.5 19.5l15-15m0 0H8.25m11.25 0v11.25"/></svg></button>
<button class="tb" data-tool="text" title="Текст (T)" disabled>
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5">
<path d="M12.2,19.6V4H6.9L5.8,5V4.4l0.9-0.8h11.8l0.6,0.8V5l-0.8-1h-5.7v15.6H12.2z"/>
</svg></button>
<button class="tb" data-tool="eyedropper" title="Пипетка (I)" disabled><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5">
<path d="M20.9,6c0-0.6-0.2-1.2-0.7-1.7c-0.4-0.4-1-0.7-1.7-0.7c-0.6,0-1.2,0.2-1.7,0.7l-3,3l-1.2-1.2c0,0-0.1,0-0.2,0
c0,0,0,0.1,0,0.2l1.2,1.2l-7.8,7.8c-0.4,0.4-0.7,1-0.7,1.7c0,0.6,0.2,1.1,0.6,1.6l-2.3,2.3c0,0,0,0.1,0,0.2c0,0,0.1,0,0.1,0
s0.1,0,0.1,0L6,18.7c0.4,0.4,1,0.6,1.6,0.6c0.6,0,1.2-0.2,1.7-0.7l7.8-7.8l1.2,1.2c0,0,0.1,0,0.1,0s0.1,0,0.1,0c0,0,0-0.1,0-0.2
l-1.2-1.2l3-3C20.6,7.3,20.9,6.7,20.9,6z M9.1,18.5c-0.8,0.8-2.2,0.8-3,0c-0.4-0.4-0.6-0.9-0.6-1.5c0-0.6,0.2-1.1,0.6-1.5l7.8-7.8
l3,3L9.1,18.5z M20,7.5l-3,3l-3-3l3-3c0.4-0.4,0.9-0.6,1.5-0.6c0.6,0,1.1,0.2,1.5,0.6c0.4,0.4,0.6,0.9,0.6,1.5
C20.6,6.6,20.4,7.1,20,7.5C20,7.5,20,7.5,20,7.5z"/>
</svg></button>
<button class="tb" data-tool="fill" title="Заливка (G)" disabled><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5"> <path d="M20.5,19.5c0,1.3-1,2.3-2.3,2.3c-1.3,0-2.3-1-2.3-2.3c0-1.3,2.1-4.5,2.3-4.5C18.4,15,20.5,18.2,20.5,19.5z"/>
<path d="M10.4,5L10.4,5L7.4,1.9L7.2,2.1l3,3l-6.8,6.8c-0.4,0.4-0.7,1-0.7,1.6s0.2,1.2,0.7,1.6L8.3,20c0.4,0.4,1,0.7,1.6,0.7
c0.6,0,1.2-0.2,1.6-0.7l6.9-6.9L10.4,5z M3,13.5c0-0.5,0.2-1.1,0.6-1.5l6.8-6.8l7.7,7.7l-4,4H5.7h0L3.6,15C3.2,14.6,3,14,3,13.5z"
/>
</svg></button>
<button class="tb" data-tool="clone" title="Штамп (S)" disabled><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5"><path stroke-linecap="round" stroke-linejoin="round" d="M15.75 17.25v3.375c0 .621-.504 1.125-1.125 1.125h-9.75a1.125 1.125 0 01-1.125-1.125V7.875c0-.621.504-1.125 1.125-1.125H6.75"/><path stroke-linecap="round" stroke-linejoin="round" d="M8.25 3h9.75a1.125 1.125 0 011.125 1.125v9.75c0 .621-.504 1.125-1.125 1.125H8.25a1.125 1.125 0 01-1.125-1.125v-9.75c0-.621.504-1.125 1.125-1.125z"/></svg></button>
<button class="tb" data-tool="lasso" title="Лассо (W)" disabled><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5"><path stroke-linecap="round" stroke-linejoin="round" stroke-dasharray="3 2" d="M12 4c-2 1.5-5 2-7 5s-1 6 1 8 5 2 8 1 5-4 5-7-2-6-5-7"/><path stroke-linecap="round" stroke-linejoin="round" d="M12 4c1 1 3 2 3 4"/></svg></button>
</div>
<div class="toolbar-sep"></div>
<!-- Transform -->
<div class="toolbar-group">
<button class="tb" id="btnRotCCW" title="Повернуть CCW" disabled><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5"><path stroke-linecap="round" stroke-linejoin="round" d="M9 15L3 9m0 0l6-6M3 9h12a6 6 0 010 12h-3"/></svg></button>
<button class="tb" id="btnRotCW" title="Повернуть CW" disabled><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5"><path stroke-linecap="round" stroke-linejoin="round" d="M15 15l6-6m0 0l-6-6m6 6H9a6 6 0 000 12h3"/></svg></button>
<button class="tb" id="btnFlipH" title="Flip H" disabled><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5"><path stroke-linecap="round" stroke-linejoin="round" d="M7.5 21L3 16.5m0 0L7.5 12M3 16.5h13.5m0-13.5L21 7.5m0 0L16.5 12M21 7.5H7.5"/></svg></button>
<button class="tb" id="btnFlipV" title="Flip V" disabled><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5"><path stroke-linecap="round" stroke-linejoin="round" d="M3 7.5L7.5 3m0 0L12 7.5M7.5 3v13.5m13.5 0L16.5 21m0 0L12 16.5m4.5 4.5V7.5"/></svg></button>
<button class="tb" id="btnResize" title="Resize" disabled><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5"><path stroke-linecap="round" stroke-linejoin="round" d="M3.75 3.75v4.5m0-4.5h4.5m-4.5 0L9 9M3.75 20.25v-4.5m0 4.5h4.5m-4.5 0L9 15M20.25 3.75h-4.5m4.5 0v4.5m0-4.5L15 9m5.25 11.25h-4.5m4.5 0v-4.5m0 4.5L15 15"/></svg></button>
<button class="tb" id="btnAdjust" title="Adjustments" disabled><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5"><path stroke-linecap="round" stroke-linejoin="round" d="M10.5 6h9.75M10.5 6a1.5 1.5 0 11-3 0m3 0a1.5 1.5 0 10-3 0M3.75 6H7.5m3 12h9.75m-9.75 0a1.5 1.5 0 01-3 0m3 0a1.5 1.5 0 00-3 0m-3.75 0H7.5m9-6h3.75m-3.75 0a1.5 1.5 0 01-3 0m3 0a1.5 1.5 0 00-3 0m-9.75 0h9.75"/></svg></button>
<button class="tb" id="btnBlur" title="Размытие" disabled><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5"><circle cx="12" cy="12" r="9" stroke-dasharray="3 2"/><circle cx="12" cy="12" r="5" opacity=".5"/><circle cx="12" cy="12" r="2" opacity=".3"/></svg></button>
<button class="tb" id="btnSharpen" title="Резкость" disabled><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5"><path stroke-linecap="round" stroke-linejoin="round" d="M12 3l2.5 6.5L21 12l-6.5 2.5L12 21l-2.5-6.5L3 12l6.5-2.5L12 3z"/></svg></button>
</div>
<div class="toolbar-sep"></div>
<!-- Filters -->
<div class="toolbar-group" id="filtersGroup">
<button class="tb" id="btnGrayscale" title="Ч/Б" disabled>
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5"><circle cx="12" cy="12" r="9"/><path d="M12 3v18" stroke-width="1.5"/><path d="M12 3a9 9 0 010 18" fill="currentColor" opacity=".35"/></svg>
</button>
<button class="tb" id="btnSepia" title="Сепия" disabled>
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5"><rect x="3" y="5" width="18" height="14" rx="2"/><circle cx="8.5" cy="10.5" r="2"/><path stroke-linecap="round" stroke-linejoin="round" d="M21 15l-5-5-4 4-3-2-4 4"/></svg>
</button>
<button class="tb" id="btnInvert" title="Инверсия" disabled>
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5"><rect x="3" y="3" width="18" height="18" rx="2"/><path d="M12 3v18" stroke-width="1"/><rect x="3" y="3" width="9" height="18" fill="currentColor" opacity=".5" rx="2"/></svg>
</button>
<button class="tb" id="btnAutoLevels" title="Авто-уровни" disabled>
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5"><path stroke-linecap="round" stroke-linejoin="round" d="M3 18h2m0 0a2 2 0 104 0m-4 0a2 2 0 114 0m0 0h12M3 12h6m0 0a2 2 0 104 0m-4 0a2 2 0 114 0m0 0h8M3 6h10m0 0a2 2 0 104 0m-4 0a2 2 0 114 0m0 0h4"/></svg>
</button>
</div>
<div class="toolbar-sep"></div>
<!-- Undo/Redo -->
<div class="toolbar-group">
<button class="tb" id="btnUndo" title="Undo (Ctrl+Z)" disabled><svg fill="none" stroke="currentColor" viewBox="0 0 24 24" stroke-width="1.5"><path stroke-linecap="round" stroke-linejoin="round" d="M9 15L3 9m0 0l6-6M3 9h12a6 6 0 010 12h-3"/></svg></button>
<button class="tb" id="btnRedo" title="Redo (Ctrl+Shift+Z)" disabled><svg fill="none" stroke="currentColor" viewBox="0 0 24 24" stroke-width="1.5"><path stroke-linecap="round" stroke-linejoin="round" d="M15 15l6-6m0 0l-6-6m6 6H9a6 6 0 000 12h3"/></svg></button>
</div>
<!-- Right side: color + zoom -->
<div class="toolbar-right">
<button class="tb" id="btnLayers" title="Слои"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5"><path stroke-linecap="round" stroke-linejoin="round" d="M12 2.25l9.75 5.25L12 12.75 2.25 7.5 12 2.25z"/><path stroke-linecap="round" stroke-linejoin="round" d="M2.25 12l9.75 5.25L21.75 12"/><path stroke-linecap="round" stroke-linejoin="round" d="M2.25 16.5l9.75 5.25 9.75-5.25"/></svg></button>
<div class="toolbar-sep"></div>
<div class="color-swatch" id="colorSwatch" title="Color">
<input type="color" id="colorPicker" value="#0054e6">
</div>
<div class="toolbar-sep"></div>
<button class="tb" id="btnZoomOut" title="Zoom Out"><svg fill="none" stroke="currentColor" viewBox="0 0 24 24" stroke-width="1.5"><path stroke-linecap="round" stroke-linejoin="round" d="M21 21l-5.197-5.197m0 0A7.5 7.5 0 105.196 5.196a7.5 7.5 0 0010.607 10.607zM13.5 10.5h-6"/></svg></button>
<span id="zoomLabel" style="font-family:'JetBrains Mono',monospace;font-size:11px;color:var(--text-muted);min-width:40px;text-align:center">100%</span>
<button class="tb" id="btnZoomIn" title="Zoom In"><svg fill="none" stroke="currentColor" viewBox="0 0 24 24" stroke-width="1.5"><path stroke-linecap="round" stroke-linejoin="round" d="M21 21l-5.197-5.197m0 0A7.5 7.5 0 105.196 5.196a7.5 7.5 0 0010.607 10.607zM10.5 7.5v6m3-3h-6"/></svg></button>
<button class="tb" id="btnFit" title="Fit (Ctrl+0)"><svg fill="none" stroke="currentColor" viewBox="0 0 24 24" stroke-width="1.5"><path stroke-linecap="round" stroke-linejoin="round" d="M3.75 3.75v4.5m0-4.5h4.5m9 0h4.5v4.5m0 9v4.5h-4.5m-9 0H3.75v-4.5"/></svg></button>
</div>
</div>
<!-- Tool Options (context-sensitive) -->
<div class="tool-options" id="toolOptions"></div>
<!-- Tab Bar -->
<div class="tab-bar" id="tabBar"></div>
<!-- Viewport -->
<div class="viewport" id="viewport">
<div class="viewport-checker"></div>
<div class="canvas-container" id="canvasContainer">
<canvas id="canvasMain"></canvas>
<canvas id="canvasOverlay"></canvas>
</div>
<canvas id="canvasUI" style="position:absolute;inset:0;z-index:5;pointer-events:none"></canvas>
<!-- Drop zone -->
<div class="dropzone" id="dropzone">
<div class="dropzone-icon">
<svg fill="none" stroke="currentColor" viewBox="0 0 24 24" stroke-width="1.5"><path stroke-linecap="round" stroke-linejoin="round" d="M2.25 15.75l5.159-5.159a2.25 2.25 0 013.182 0l5.159 5.159m-1.5-1.5l1.409-1.409a2.25 2.25 0 013.182 0l2.909 2.909M3.75 21h16.5A2.25 2.25 0 0023.25 18.75V5.25A2.25 2.25 0 0021 3H3.75A2.25 2.25 0 001.5 5.25v13.5A2.25 2.25 0 003.75 21z"/></svg>
</div>
<div class="dropzone-text">Перетащите изображение, вставьте из буфера или нажмите</div>
<div class="dropzone-hint">Ctrl+O / Ctrl+V / Drag & Drop</div>
</div>
<!-- Text overlay — contenteditable inline editor -->
<div class="text-overlay" id="textOverlay">
<div id="textArea" class="text-editor" contenteditable="true" spellcheck="false" role="textbox" aria-multiline="true"></div>
</div>
<!-- Layer Panel -->
<div class="layer-panel" id="layerPanel">
<div class="layer-panel-header">
<span>Слои</span>
<div class="layer-panel-actions">
<button class="lpa-btn" id="lpAdd" title="Новый слой (Ctrl+Shift+N)">+</button>
<button class="lpa-btn" id="lpDel" title="Удалить слой">&times;</button>
<button class="lpa-btn" id="lpMerge" title="Объединить вниз (Ctrl+E)">&darr;</button>
<button class="lpa-btn" id="lpFlatten" title="Свести всё (Ctrl+Shift+E)">F</button>
</div>
</div>
<div class="layer-list" id="layerList"></div>
<div class="layer-props" id="layerProps">
<div class="lp-row">
<label>Режим</label>
<select id="lpBlend">
<option value="source-over">Normal</option>
<option value="multiply">Multiply</option>
<option value="screen">Screen</option>
<option value="overlay">Overlay</option>
<option value="darken">Darken</option>
<option value="lighten">Lighten</option>
<option value="color-dodge">Color Dodge</option>
<option value="color-burn">Color Burn</option>
<option value="hard-light">Hard Light</option>
<option value="soft-light">Soft Light</option>
<option value="difference">Difference</option>
<option value="exclusion">Exclusion</option>
<option value="hue">Hue</option>
<option value="saturation">Saturation</option>
<option value="color">Color</option>
<option value="luminosity">Luminosity</option>
</select>
</div>
<div class="lp-row">
<label>Прозр.</label>
<input type="range" id="lpOpacity" min="0" max="100" value="100">
<span id="lpOpacityVal">100%</span>
</div>
</div>
</div>
</div>
<!-- Status Bar -->
<div class="statusbar">
<span id="statusDims">Нет изображения</span>
<span id="statusZoom">100%</span>
<span id="statusCursor">0, 0</span>
<span id="statusHistory"></span>
<span id="statusLayer"></span>
</div>
</div>
<!-- Export Modal -->
<div class="modal-overlay" id="exportModal">
<div class="modal">
<h3>Экспорт</h3>
<div class="modal-row">
<label>Имя файла</label>
<input type="text" id="exportName" value="image">
</div>
<div class="modal-row">
<label>Формат</label>
<select id="exportFormat">
<option value="png">PNG</option>
<option value="jpeg">JPEG</option>
<option value="webp">WebP</option>
</select>
</div>
<div class="modal-row" id="qualityRow">
<label>Качество</label>
<input type="range" id="exportQuality" min="1" max="100" value="92">
<span id="exportQualityVal" style="font-family:'JetBrains Mono',monospace;font-size:11px;color:var(--text-muted);width:30px;text-align:right">92</span>
</div>
<div class="modal-warning" id="exportWarning">Изображение содержит прозрачность. JPEG заменит её белым фоном.</div>
<div class="modal-actions">
<button id="exportCancel">Отмена</button>
<button id="exportConfirm" class="primary">Скачать</button>
</div>
</div>
</div>
<!-- Context Menu -->
<div class="ctx-menu" id="ctxMenu">
<div class="ctx-item" data-action="undo"><svg fill="none" stroke="currentColor" viewBox="0 0 24 24" stroke-width="1.5"><path stroke-linecap="round" stroke-linejoin="round" d="M9 15L3 9m0 0l6-6M3 9h12a6 6 0 010 12h-3"/></svg>Отменить<span class="ctx-shortcut">Ctrl+Z</span></div>
<div class="ctx-item" data-action="redo"><svg fill="none" stroke="currentColor" viewBox="0 0 24 24" stroke-width="1.5"><path stroke-linecap="round" stroke-linejoin="round" d="M15 15l6-6m0 0l-6-6m6 6H9a6 6 0 000 12h3"/></svg>Повторить<span class="ctx-shortcut">Ctrl+Shift+Z</span></div>
<div class="ctx-sep"></div>
<div class="ctx-item" data-action="crop-sel"><svg fill="none" stroke="currentColor" viewBox="0 0 24 24" stroke-width="1.5"><path stroke-linecap="round" stroke-linejoin="round" d="M7.5 3.75H6A2.25 2.25 0 003.75 6v1.5M16.5 3.75H18A2.25 2.25 0 0120.25 6v1.5m0 9V18A2.25 2.25 0 0118 20.25h-1.5m-9 0H6A2.25 2.25 0 013.75 18v-1.5"/></svg>Обрезать по выделению</div>
<div class="ctx-sep"></div>
<div class="ctx-item" data-action="resize"><svg fill="none" stroke="currentColor" viewBox="0 0 24 24" stroke-width="1.5"><path stroke-linecap="round" stroke-linejoin="round" d="M3.75 3.75v4.5m0-4.5h4.5m-4.5 0L9 9M3.75 20.25v-4.5m0 4.5h4.5m-4.5 0L9 15M20.25 3.75h-4.5m4.5 0v4.5m0-4.5L15 9m5.25 11.25h-4.5m4.5 0v-4.5m0 4.5L15 15"/></svg>Изменить размер...</div>
<div class="ctx-item" data-action="rot-cw"><svg fill="none" stroke="currentColor" viewBox="0 0 24 24" stroke-width="1.5"><path stroke-linecap="round" stroke-linejoin="round" d="M15 15l6-6m0 0l-6-6m6 6H9a6 6 0 000 12h3"/></svg>Повернуть 90° вправо</div>
<div class="ctx-item" data-action="rot-ccw"><svg fill="none" stroke="currentColor" viewBox="0 0 24 24" stroke-width="1.5"><path stroke-linecap="round" stroke-linejoin="round" d="M9 15L3 9m0 0l6-6M3 9h12a6 6 0 010 12h-3"/></svg>Повернуть 90° влево</div>
<div class="ctx-item" data-action="flip-h"><svg fill="none" stroke="currentColor" viewBox="0 0 24 24" stroke-width="1.5"><path stroke-linecap="round" stroke-linejoin="round" d="M7.5 21L3 16.5m0 0L7.5 12M3 16.5h13.5m0-13.5L21 7.5m0 0L16.5 12M21 7.5H7.5"/></svg>Отразить по горизонтали</div>
<div class="ctx-item" data-action="flip-v"><svg fill="none" stroke="currentColor" viewBox="0 0 24 24" stroke-width="1.5"><path stroke-linecap="round" stroke-linejoin="round" d="M3 7.5L7.5 3m0 0L12 7.5M7.5 3v13.5m13.5 0L16.5 21m0 0L12 16.5m4.5 4.5V7.5"/></svg>Отразить по вертикали</div>
<div class="ctx-sep"></div>
<div class="ctx-item" data-action="fit"><svg fill="none" stroke="currentColor" viewBox="0 0 24 24" stroke-width="1.5"><path stroke-linecap="round" stroke-linejoin="round" d="M3.75 3.75v4.5m0-4.5h4.5m9 0h4.5v4.5m0 9v4.5h-4.5m-9 0H3.75v-4.5"/></svg>Вписать в экран<span class="ctx-shortcut">Ctrl+0</span></div>
<div class="ctx-item" data-action="zoom100"><svg fill="none" stroke="currentColor" viewBox="0 0 24 24" stroke-width="1.5"><path stroke-linecap="round" stroke-linejoin="round" d="M21 21l-5.197-5.197m0 0A7.5 7.5 0 105.196 5.196a7.5 7.5 0 0010.607 10.607zM10.5 7.5v6m3-3h-6"/></svg>Масштаб 100%<span class="ctx-shortcut">Ctrl+1</span></div>
<div class="ctx-sep"></div>
<div class="ctx-item" data-action="copy"><svg fill="none" stroke="currentColor" viewBox="0 0 24 24" stroke-width="1.5"><path stroke-linecap="round" stroke-linejoin="round" d="M15.666 3.888A2.25 2.25 0 0013.5 2.25h-3c-1.03 0-1.9.693-2.166 1.638m7.332 0c.055.194.084.4.084.612v0a.75.75 0 01-.75.75H9.75a.75.75 0 01-.75-.75v0c0-.212.03-.418.084-.612m7.332 0c.646.049 1.288.11 1.927.184 1.1.128 1.907 1.077 1.907 2.185V19.5a2.25 2.25 0 01-2.25 2.25H6.75A2.25 2.25 0 014.5 19.5V6.257c0-1.108.806-2.057 1.907-2.185a48.208 48.208 0 011.927-.184"/></svg>Копировать в буфер</div>
<div class="ctx-item" data-action="paste"><svg fill="none" stroke="currentColor" viewBox="0 0 24 24" stroke-width="1.5"><path stroke-linecap="round" stroke-linejoin="round" d="M19.5 14.25v-2.625a3.375 3.375 0 00-3.375-3.375h-1.5A1.125 1.125 0 0113.5 7.125v-1.5a3.375 3.375 0 00-3.375-3.375H8.25m3.75 9v6m3-3H9m1.5-12H5.625c-.621 0-1.125.504-1.125 1.125v17.25c0 .621.504 1.125 1.125 1.125h12.75c.621 0 1.125-.504 1.125-1.125V11.25a9 9 0 00-9-9z"/></svg>Вставить из буфера<span class="ctx-shortcut">Ctrl+V</span></div>
<div class="ctx-sep"></div>
<div class="ctx-item" data-action="export"><svg fill="none" stroke="currentColor" viewBox="0 0 24 24" stroke-width="1.5"><path stroke-linecap="round" stroke-linejoin="round" d="M3 16.5v2.25A2.25 2.25 0 005.25 21h13.5A2.25 2.25 0 0021 18.75V16.5M16.5 12L12 16.5m0 0L7.5 12m4.5 4.5V3"/></svg>Экспорт...<span class="ctx-shortcut">Ctrl+S</span></div>
</div>
<!-- Hidden file input -->
<input type="file" id="fileInput" accept="image/*" style="display:none">
<script src="/editor.js" defer></script>
</body>
</html>