Replace monolithic CLI and web server with route-based Flask API. New routes: api_commands, api_build, api_can, api_monitor, api_ota, api_tunnel. Add honeypot security dashboard with real-time SSE, MITRE ATT&CK mapping, kill chain analysis. New TUI with commander/help modules. Add session management, tunnel proxy core, CAN bus data store. Docker support.
74 lines
2.8 KiB
JavaScript
74 lines
2.8 KiB
JavaScript
/* ESPILON C3PO — Split Pane Resizer
|
|
Handles drag-to-resize for .resizer elements within .split-h and .split-v containers.
|
|
.resizer = vertical bar (col-resize) between siblings in a .split-h
|
|
.resizer-h = horizontal bar (row-resize) between siblings in a .split-v
|
|
*/
|
|
|
|
(function() {
|
|
'use strict';
|
|
|
|
document.addEventListener('DOMContentLoaded', function() {
|
|
document.querySelectorAll('.resizer').forEach(initResizer);
|
|
});
|
|
|
|
function initResizer(handle) {
|
|
var isHorizontal = handle.classList.contains('resizer-h');
|
|
var prev = handle.previousElementSibling;
|
|
var next = handle.nextElementSibling;
|
|
if (!prev || !next) return;
|
|
|
|
handle.addEventListener('mousedown', function(e) {
|
|
e.preventDefault();
|
|
e.stopPropagation();
|
|
startDrag(e, handle, prev, next, isHorizontal);
|
|
});
|
|
}
|
|
|
|
function startDrag(e, handle, prev, next, isHorizontal) {
|
|
var container = handle.parentElement;
|
|
var startPos = isHorizontal ? e.clientY : e.clientX;
|
|
var prevSize = isHorizontal ? prev.getBoundingClientRect().height : prev.getBoundingClientRect().width;
|
|
var nextSize = isHorizontal ? next.getBoundingClientRect().height : next.getBoundingClientRect().width;
|
|
var totalSize = prevSize + nextSize;
|
|
|
|
handle.classList.add('active');
|
|
document.body.style.cursor = isHorizontal ? 'row-resize' : 'col-resize';
|
|
document.body.style.userSelect = 'none';
|
|
|
|
var overlay = document.createElement('div');
|
|
overlay.style.cssText = 'position:fixed;inset:0;z-index:9999;cursor:' + (isHorizontal ? 'row-resize' : 'col-resize');
|
|
document.body.appendChild(overlay);
|
|
|
|
function onMove(ev) {
|
|
var currentPos = isHorizontal ? ev.clientY : ev.clientX;
|
|
var delta = currentPos - startPos;
|
|
var newPrev = Math.max(40, Math.min(totalSize - 40, prevSize + delta));
|
|
var newNext = totalSize - newPrev;
|
|
|
|
if (isHorizontal) {
|
|
prev.style.height = newPrev + 'px';
|
|
prev.style.flex = 'none';
|
|
next.style.height = newNext + 'px';
|
|
next.style.flex = 'none';
|
|
} else {
|
|
prev.style.width = newPrev + 'px';
|
|
prev.style.flex = 'none';
|
|
next.style.width = newNext + 'px';
|
|
next.style.flex = 'none';
|
|
}
|
|
}
|
|
|
|
function onUp() {
|
|
handle.classList.remove('active');
|
|
document.body.style.cursor = '';
|
|
document.body.style.userSelect = '';
|
|
overlay.remove();
|
|
document.removeEventListener('mousemove', onMove);
|
|
document.removeEventListener('mouseup', onUp);
|
|
}
|
|
|
|
document.addEventListener('mousemove', onMove);
|
|
document.addEventListener('mouseup', onUp);
|
|
}
|
|
})();
|