/
diz
/
stencil
Обзор
Документация
Войти
/
diz
/
stencil
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
master
index.html
261 строка
13 KB
Dmitry
fix: footer date → Aquarius, revert Gerber tabs to original layout
30 июл 2026, 12:14
30 июл 2026, 12:14
9d407a6
Код
Авторство
О чём код?
<!DOCTYPE html> <html lang="ru" class=""> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>SMT Stencil</title> <script src="lib/tailwind.js"></script> <link rel="stylesheet" href="src/style.css"> <link rel="icon" href="src/favicon.svg" type="image/svg+xml"> <script defer src="src/app.js"></script> </head> <body> <!-- ============ HEADER ============ --> <header class="card no-print" style="border-radius:0;border-left:none;border-right:none;border-top:none;padding:.75rem 1.5rem;display:flex;align-items:center;justify-content:space-between;flex-wrap:wrap;gap:.5rem;"> <div style="display:flex;align-items:center;gap:.75rem;"> <svg width="32" height="32" viewBox="0 0 32 32" fill="none"> <rect x="2" y="2" width="28" height="28" rx="6" stroke="currentColor" stroke-width="1.5" fill="none"/> <path d="M8 16h16M16 8v16" stroke="var(--accent)" stroke-width="2" stroke-linecap="round"/> <circle cx="16" cy="16" r="4" stroke="currentColor" stroke-width="1.2" fill="none"/> </svg> <div> <h1 style="font-size:1.1rem;font-weight:700;line-height:1.2;">Валидатор апертур SMT-трафарета</h1> <p style="font-size:.7rem;color:var(--text-secondary);">IPC-7525B/C — Aspect Ratio · Area Ratio · Paste Volume</p> </div> </div> <div style="display:flex;align-items:center;gap:.75rem;"> <span style="font-size:.75rem;color:var(--text-secondary);" id="dateDisplay"></span> <button class="btn btn-sm" onclick="toggleDarkMode()" id="darkToggle" style="padding:.35rem .7rem;"> <span id="darkIcon">🌙</span> </button> </div> </header> <!-- ============ MAIN LAYOUT ============ --> <div style="max-width:1440px;margin:0 auto;padding:.75rem 1rem;display:grid;grid-template-columns:1fr;gap:.75rem;"> <!-- ============ GLOBAL SETTINGS ============ --> <section class="card no-print" id="settingsPanel"> <div style="display:flex;align-items:center;justify-content:space-between;margin-bottom:.75rem;"> <h2 style="font-size:.95rem;font-weight:600;">⚙️ Глобальные настройки трафарета</h2> <button class="btn btn-sm" onclick="toggleSettings()" id="settingsToggle">▲ Свернуть</button> </div> <div id="settingsBody"> <div style="display:grid;grid-template-columns:repeat(auto-fit,minmax(200px,1fr));gap:1rem;"> <div> <label style="font-size:.8rem;font-weight:500;display:block;margin-bottom:.35rem;">Толщина фольги (T)</label> <div style="display:flex;gap:.35rem;flex-wrap:wrap;margin-bottom:.4rem;"> <button class="preset-btn" data-t="80">80</button> <button class="preset-btn" data-t="100">100</button> <button class="preset-btn active" data-t="120">120</button> <button class="preset-btn" data-t="130">130</button> <button class="preset-btn" data-t="150">150</button> <button class="preset-btn" data-t="180">180</button> </div> <div style="display:flex;gap:.5rem;"> <input type="number" id="thicknessInput" value="120" min="10" max="500" step="1" style="width:100px;"> <select id="thicknessUnit"> <option value="um">мкм</option> <option value="mil">mil</option> </select> </div> </div> <div> <label style="font-size:.8rem;font-weight:500;display:block;margin-bottom:.35rem;">Технология изготовления</label> <select id="techSelect"> <option value="laser">Лазерная резка (Laser Cut)</option> <option value="electropolished">Электрополировка (Electropolished)</option> <option value="nano">Нанопокрытие (Nano-coated)</option> </select> <p style="font-size:.7rem;color:var(--text-secondary);margin-top:.3rem;"> Порог Area Ratio: <span id="thresholdDisplay">≥ 0.66</span> </p> </div> <div> <label style="font-size:.8rem;font-weight:500;display:block;margin-bottom:.35rem;">Единицы отображения</label> <select id="displayUnitSelect"> <option value="mm">мм (метрические)</option> <option value="mil">mil (имперские)</option> </select> <p style="font-size:.7rem;color:var(--text-secondary);margin-top:.3rem;"> 1 мм = 39.37 mil </p> </div> </div> </div> </section> <!-- ============ TABS ============ --> <div class="no-print" style="display:flex;border-bottom:2px solid var(--border-color);margin-bottom:0;"> <button class="tab-btn active" data-tab="express">📐 Экспресс-калькулятор</button> <button class="tab-btn" data-tab="gerber">📂 Парсер Gerber (RS-274X)</button> <button class="tab-btn" data-tab="templates">📋 Шаблоны компонентов</button> </div> <!-- ============ TAB CONTENT ============ --> <div class="card" style="border-top-left-radius:0;border-top-right-radius:0;"> <!-- TAB: Express Calculator --> <div class="tab-panel" id="tab-express"> <div style="display:flex;align-items:center;justify-content:space-between;flex-wrap:wrap;gap:.5rem;margin-bottom:.75rem;"> <h3 style="font-size:.9rem;font-weight:600;">🖩 Экспресс-калькулятор апертур</h3> <div style="display:flex;gap:.4rem;"> <button class="btn btn-sm btn-primary" onclick="addExpressRow()">+ Добавить строку</button> <button class="btn btn-sm" onclick="clearExpressRows()">Очистить</button> </div> </div> <div style="overflow-x:auto;"> <table id="expressTable"> <thead> <tr> <th style="width:36px;">#</th> <th>Компонент</th> <th>Форма</th> <th>W (мм)</th> <th>L (мм)</th> <th>D (мм)</th> <th style="width:50px;"></th> </tr> </thead> <tbody id="expressBody"></tbody> </table> </div> <div style="margin-top:.5rem;display:flex;gap:.5rem;flex-wrap:wrap;"> <button class="btn btn-sm" onclick="addExpressPreset('0201')">0201</button> <button class="btn btn-sm" onclick="addExpressPreset('0402')">0402</button> <button class="btn btn-sm" onclick="addExpressPreset('0603')">0603</button> <button class="btn btn-sm" onclick="addExpressPreset('0805')">0805</button> <button class="btn btn-sm" onclick="addExpressPreset('1206')">1206</button> <button class="btn btn-sm" onclick="addExpressPreset('SOT23')">SOT-23</button> <button class="btn btn-sm" onclick="addExpressPreset('SOIC8')">SOIC-8</button> <button class="btn btn-sm" onclick="addExpressPreset('QFP48')">QFP-48</button> <button class="btn btn-sm" onclick="addExpressPreset('BGA')">BGA ⌀</button> <button class="btn btn-sm" onclick="addExpressPreset('QFN')">QFN Thermal Pad</button> </div> </div> <!-- TAB: Gerber Parser --> <div class="tab-panel" id="tab-gerber" style="display:none;"> <div style="display:flex;align-items:center;justify-content:space-between;flex-wrap:wrap;gap:.5rem;margin-bottom:.75rem;"> <h3 style="font-size:.9rem;font-weight:600;">📂 Парсер Gerber RS-274X</h3> <div style="display:flex;gap:.4rem;"> <button class="btn btn-sm btn-primary" onclick="parseGerber()">🔍 Разобрать</button> <button class="btn btn-sm" onclick="clearGerber()">Очистить</button> </div> </div> <div style="display:grid;grid-template-columns:1fr 1fr;gap:.75rem;"> <div> <label style="font-size:.8rem;font-weight:500;display:block;margin-bottom:.35rem;">Вставьте Gerber-данные (RS-274X)</label> <textarea id="gerberInput" rows="12" style="font-family:'Consolas','Courier New',monospace;font-size:.78rem;resize:vertical;width:100%;padding-left:calc(.65rem + 5px);" placeholder="%ADD10C,0.5%*% %ADD11R,0.8X0.4%*% %ADD12O,1.2X0.6%*% ... X1000Y1000D03*"></textarea> </div> <div> <label style="font-size:.8rem;font-weight:500;display:block;margin-bottom:.35rem;">Результат разбора</label> <div id="gerberResult" style="background:var(--bg-primary);border:1px solid var(--border-color);border-radius:.375rem;padding:.5rem;font-size:.78rem;font-family:'Consolas','Courier New',monospace;min-height:200px;max-height:300px;overflow-y:auto;"> Нажмите «Разобрать» для извлечения апертур. </div> </div> </div> </div> <!-- TAB: Templates --> <div class="tab-panel" id="tab-templates" style="display:none;"> <h3 style="font-size:.9rem;font-weight:600;margin-bottom:.75rem;">📋 Шаблоны компонентов SMT</h3> <div style="overflow-x:auto;"> <table> <thead> <tr> <th>Тип</th> <th>W (мм)</th> <th>L (мм)</th> <th>Форма</th> <th>Примечание</th> <th></th> </tr> </thead> <tbody id="templatesBody"></tbody> </table> </div> </div> </div> <!-- ============ RESULTS TABLE ============ --> <section class="card" style="margin-top:.75rem;"> <div style="display:flex;align-items:center;justify-content:space-between;flex-wrap:wrap;gap:.5rem;margin-bottom:.75rem;"> <h2 style="font-size:.95rem;font-weight:600;"> 📊 Результаты проверки апертур <span id="apertureCount" style="font-size:.78rem;font-weight:400;color:var(--text-secondary);margin-left:.5rem;">(0 апертур)</span> </h2> <div style="display:flex;gap:.4rem;"> <button class="btn btn-sm" onclick="exportCSV()">⬇ CSV</button> <button class="btn btn-sm" onclick="window.print()">🖨 Печать / PDF</button> </div> </div> <div style="overflow-x:auto;"> <table id="resultsTable"> <thead> <tr> <th>#</th> <th>Компонент</th> <th>Форма</th> <th>W (мм)</th> <th>L (мм)</th> <th>Aspect Ratio</th> <th>Area Ratio</th> <th>Объём пасты (мм³)</th> <th>Рекомендация</th> </tr> </thead> <tbody id="resultsBody"> <tr><td colspan="9" style="text-align:center;color:var(--text-secondary);padding:2rem;">Загрузка…</td></tr> </tbody> </table> </div> </section> <!-- ============ CANVAS PREVIEW + DETAILS ============ --> <section style="display:grid;grid-template-columns:1fr 1fr;gap:.75rem;margin-top:.75rem;"> <div class="card"> <h3 style="font-size:.9rem;font-weight:600;margin-bottom:.5rem;">👁 2D-визуализация апертуры</h3> <div id="canvasPlaceholder" style="text-align:center;padding:2rem;color:var(--text-secondary);font-size:.85rem;"> Выберите апертуру в таблице для предпросмотра. </div> <canvas id="previewCanvas" width="400" height="280" style="width:100%;height:auto;display:none;border-radius:.375rem;background:var(--bg-primary);"></canvas> <div id="canvasInfo" style="margin-top:.5rem;font-size:.78rem;color:var(--text-secondary);display:none;"></div> </div> <div class="card"> <h3 style="font-size:.9rem;font-weight:600;margin-bottom:.5rem;">📖 Справка IPC-7525</h3> <div style="font-size:.8rem;line-height:1.7;"> <p><strong>Aspect Ratio (AR):</strong> <code>W / T</code></p> <p style="font-size:.75rem;color:var(--text-secondary);">Прямоугольник: AR = min(W,L)/T | Круг: AR = D/T</p> <p style="margin-top:.4rem;"><strong>Area Ratio (AR<sub>a</sub>):</strong></p> <p style="font-size:.75rem;color:var(--text-secondary);">Прямоугольник: (W·L) / (2·T·(W+L))</p> <p style="font-size:.75rem;color:var(--text-secondary);">Круг: D / (4·T)</p> <div style="margin-top:.6rem;display:grid;grid-template-columns:1fr 1fr;gap:.3rem;font-size:.75rem;"> <span><span class="badge-pass">PASS</span> AR ≥ 1.5</span> <span><span class="badge-pass">PASS</span> AreaR ≥ 0.66</span> <span><span class="badge-warn">WARN</span> AreaR 0.55–0.65</span> <span><span class="badge-fail">FAIL</span> AreaR < 0.55</span> </div> <p style="margin-top:.6rem;font-size:.75rem;color:var(--text-secondary);"> Порог Area Ratio снижается до ≥ 0.55 для технологии Nano-coated. Рекомендация: при FAIL уменьшить апертуру (редукция 5–20%) или использовать window-pane для больших площадок. </p> </div> </div> </section> </div><!-- /container --> <!-- ============ FOOTER ============ --> <footer class="no-print" style="text-align:center;padding:1rem;font-size:.72rem;color:var(--text-secondary);border-top:1px solid var(--border-color);margin-top:1rem;"> SMT Stencil Aperture Validator · IPC-7525B/C · Aquarius </footer> </body> </html>