scan-engine-dom 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,39 @@
1
+ # Scan Engine DOM
2
+
3
+ DOM helpers for `scan-engine` continuous scanning. This package provides a lightweight overlay renderer and a hit-testing helper for DOM grids.
4
+
5
+ ## Install
6
+
7
+ ```bash
8
+ npm install scan-engine-dom scan-engine
9
+ ```
10
+
11
+ ## Usage
12
+
13
+ ```ts
14
+ import { ContinuousScanner } from 'scan-engine';
15
+ import { ContinuousOverlay, resolveIndexAtPoint } from 'scan-engine-dom';
16
+
17
+ const container = document.querySelector('.grid') as HTMLElement;
18
+ const overlay = new ContinuousOverlay(container);
19
+
20
+ const surface = {
21
+ getItemsCount: () => items.length,
22
+ getColumns: () => cols,
23
+ setFocus: (indices: number[]) => highlight(indices),
24
+ setSelected: (index: number) => flash(index),
25
+ resolveIndexAtPoint: (x: number, y: number) => resolveIndexAtPoint(container, x, y)
26
+ };
27
+
28
+ const scanner = new ContinuousScanner(surface, configProvider, {
29
+ onContinuousUpdate: (state) => overlay.update(state)
30
+ });
31
+
32
+ scanner.start();
33
+ ```
34
+
35
+ Call `overlay.destroy()` when the overlay should be removed (for example, when switching scan modes).
36
+
37
+ ## License
38
+
39
+ MIT
package/dist/index.cjs ADDED
@@ -0,0 +1,281 @@
1
+ 'use strict';
2
+
3
+ var __defProp = Object.defineProperty;
4
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
5
+ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
6
+
7
+ // src/ContinuousOverlay.ts
8
+ var ContinuousOverlay = class {
9
+ constructor(container) {
10
+ this.container = container;
11
+ __publicField(this, "overlay");
12
+ __publicField(this, "hBar");
13
+ __publicField(this, "vBar");
14
+ __publicField(this, "bufferZone");
15
+ __publicField(this, "lockedXBar");
16
+ __publicField(this, "directionIndicator");
17
+ __publicField(this, "directionLine");
18
+ this.overlay = document.createElement("div");
19
+ this.overlay.style.position = "absolute";
20
+ this.overlay.style.top = "0";
21
+ this.overlay.style.left = "0";
22
+ this.overlay.style.width = "100%";
23
+ this.overlay.style.height = "100%";
24
+ this.overlay.style.pointerEvents = "none";
25
+ this.overlay.style.zIndex = "1000";
26
+ this.bufferZone = document.createElement("div");
27
+ this.bufferZone.style.position = "absolute";
28
+ this.bufferZone.style.top = "0";
29
+ this.bufferZone.style.height = "100%";
30
+ this.bufferZone.style.backgroundColor = "rgba(128, 128, 128, 0.4)";
31
+ this.bufferZone.style.borderLeft = "2px solid rgba(128, 128, 128, 0.8)";
32
+ this.bufferZone.style.borderRight = "2px solid rgba(128, 128, 128, 0.8)";
33
+ this.bufferZone.style.pointerEvents = "none";
34
+ this.bufferZone.style.display = "none";
35
+ this.overlay.appendChild(this.bufferZone);
36
+ this.vBar = document.createElement("div");
37
+ this.vBar.style.position = "absolute";
38
+ this.vBar.style.top = "0";
39
+ this.vBar.style.width = "4px";
40
+ this.vBar.style.height = "100%";
41
+ this.vBar.style.backgroundColor = "rgba(255, 0, 0, 0.5)";
42
+ this.vBar.style.borderLeft = "1px solid red";
43
+ this.vBar.style.borderRight = "1px solid red";
44
+ this.vBar.style.display = "none";
45
+ this.overlay.appendChild(this.vBar);
46
+ this.hBar = document.createElement("div");
47
+ this.hBar.style.position = "absolute";
48
+ this.hBar.style.left = "0";
49
+ this.hBar.style.width = "100%";
50
+ this.hBar.style.height = "4px";
51
+ this.hBar.style.backgroundColor = "rgba(255, 0, 0, 0.5)";
52
+ this.hBar.style.borderTop = "1px solid red";
53
+ this.hBar.style.borderBottom = "1px solid red";
54
+ this.hBar.style.display = "none";
55
+ this.overlay.appendChild(this.hBar);
56
+ this.lockedXBar = document.createElement("div");
57
+ this.lockedXBar.style.position = "absolute";
58
+ this.lockedXBar.style.top = "0";
59
+ this.lockedXBar.style.width = "3px";
60
+ this.lockedXBar.style.height = "100%";
61
+ this.lockedXBar.style.backgroundColor = "rgba(0, 255, 0, 0.7)";
62
+ this.lockedXBar.style.borderLeft = "1px solid green";
63
+ this.lockedXBar.style.borderRight = "1px solid green";
64
+ this.lockedXBar.style.display = "none";
65
+ this.overlay.appendChild(this.lockedXBar);
66
+ this.directionIndicator = document.createElement("div");
67
+ this.directionIndicator.style.position = "absolute";
68
+ this.directionIndicator.style.top = "10px";
69
+ this.directionIndicator.style.right = "10px";
70
+ this.directionIndicator.style.width = "80px";
71
+ this.directionIndicator.style.height = "80px";
72
+ this.directionIndicator.style.borderRadius = "50%";
73
+ this.directionIndicator.style.backgroundColor = "rgba(255, 255, 255, 0.9)";
74
+ this.directionIndicator.style.border = "3px solid #333";
75
+ this.directionIndicator.style.display = "none";
76
+ this.directionIndicator.style.pointerEvents = "none";
77
+ this.overlay.appendChild(this.directionIndicator);
78
+ this.directionLine = document.createElement("div");
79
+ this.directionLine.style.position = "absolute";
80
+ this.directionLine.style.height = "2px";
81
+ this.directionLine.style.backgroundColor = "rgba(33, 150, 243, 0.6)";
82
+ this.directionLine.style.transformOrigin = "0 50%";
83
+ this.directionLine.style.display = "none";
84
+ this.directionLine.style.pointerEvents = "none";
85
+ this.directionLine.style.zIndex = "5";
86
+ this.overlay.appendChild(this.directionLine);
87
+ this.container.appendChild(this.overlay);
88
+ }
89
+ destroy() {
90
+ if (this.overlay.parentNode) {
91
+ this.overlay.parentNode.removeChild(this.overlay);
92
+ }
93
+ }
94
+ update(state) {
95
+ if (state.technique === "eight-direction") {
96
+ this.vBar.style.display = "none";
97
+ this.hBar.style.display = "none";
98
+ this.bufferZone.style.display = "none";
99
+ this.lockedXBar.style.display = "none";
100
+ this.directionIndicator.style.display = "block";
101
+ this.directionLine.style.display = "block";
102
+ const angle = state.compassAngle;
103
+ this.directionIndicator.innerHTML = `
104
+ <div style="
105
+ position: absolute;
106
+ top: 50%;
107
+ left: 50%;
108
+ transform: translate(-50%, -50%) rotate(${angle}deg);
109
+ font-size: 24px;
110
+ font-weight: bold;
111
+ color: #2196F3;
112
+ ">\u2191</div>
113
+ <div style="
114
+ position: absolute;
115
+ top: 5px;
116
+ left: 50%;
117
+ transform: translateX(-50%);
118
+ font-size: 12px;
119
+ font-weight: bold;
120
+ ">N</div>
121
+ <div style="
122
+ position: absolute;
123
+ bottom: 5px;
124
+ left: 50%;
125
+ transform: translateX(-50%);
126
+ font-size: 12px;
127
+ font-weight: bold;
128
+ ">S</div>
129
+ <div style="
130
+ position: absolute;
131
+ left: 5px;
132
+ top: 50%;
133
+ transform: translateY(-50%);
134
+ font-size: 12px;
135
+ font-weight: bold;
136
+ ">W</div>
137
+ <div style="
138
+ position: absolute;
139
+ right: 5px;
140
+ top: 50%;
141
+ transform: translateY(-50%);
142
+ font-size: 12px;
143
+ font-weight: bold;
144
+ ">E</div>
145
+ <div style="
146
+ position: absolute;
147
+ bottom: 20px;
148
+ left: 50%;
149
+ transform: translateX(-50%);
150
+ font-size: 10px;
151
+ color: #666;
152
+ ">${state.directionName} (${Math.round(angle)}\xB0)</div>
153
+ `;
154
+ this.directionLine.style.left = `${state.xPos}%`;
155
+ this.directionLine.style.top = `${state.yPos}%`;
156
+ const lineLength = this.calculateLineLength(state.xPos, state.yPos, state.directionDx, state.directionDy);
157
+ this.directionLine.style.width = `${lineLength}%`;
158
+ this.directionLine.style.transformOrigin = "0 50%";
159
+ this.directionLine.style.transform = `rotate(${angle}deg)`;
160
+ this.vBar.style.display = "block";
161
+ this.vBar.style.width = "12px";
162
+ this.vBar.style.height = "12px";
163
+ this.vBar.style.borderRadius = "50%";
164
+ this.vBar.style.backgroundColor = state.state === "moving" ? "#FF5722" : "#2196F3";
165
+ this.vBar.style.border = "2px solid white";
166
+ this.vBar.style.zIndex = "10";
167
+ this.vBar.style.left = `calc(${state.xPos}% - 6px)`;
168
+ this.vBar.style.top = `calc(${state.yPos}% - 6px)`;
169
+ return;
170
+ }
171
+ if (state.technique === "gliding") {
172
+ if (state.state === "x-scanning") {
173
+ this.vBar.style.display = "none";
174
+ this.hBar.style.display = "none";
175
+ this.lockedXBar.style.display = "none";
176
+ this.directionIndicator.style.display = "none";
177
+ this.directionLine.style.display = "none";
178
+ const actualWidth = state.bufferRight - state.bufferLeft;
179
+ this.bufferZone.style.left = `${state.bufferLeft}%`;
180
+ this.bufferZone.style.width = `${actualWidth}%`;
181
+ this.bufferZone.style.height = "100%";
182
+ this.bufferZone.style.top = "0";
183
+ this.bufferZone.style.display = "block";
184
+ } else if (state.state === "x-capturing") {
185
+ this.hBar.style.display = "none";
186
+ this.lockedXBar.style.display = "none";
187
+ this.directionIndicator.style.display = "none";
188
+ this.directionLine.style.display = "none";
189
+ const actualWidth = state.bufferRight - state.bufferLeft;
190
+ this.bufferZone.style.left = `${state.bufferLeft}%`;
191
+ this.bufferZone.style.width = `${actualWidth}%`;
192
+ this.bufferZone.style.height = "100%";
193
+ this.bufferZone.style.top = "0";
194
+ this.bufferZone.style.display = "block";
195
+ const actualXPos = state.bufferLeft + state.fineXPos / 100 * (state.bufferRight - state.bufferLeft);
196
+ this.vBar.style.display = "block";
197
+ this.vBar.style.left = `${actualXPos}%`;
198
+ } else if (state.state === "y-scanning") {
199
+ this.vBar.style.display = "none";
200
+ this.hBar.style.display = "none";
201
+ this.directionIndicator.style.display = "none";
202
+ this.directionLine.style.display = "none";
203
+ this.lockedXBar.style.display = "block";
204
+ this.lockedXBar.style.left = `${state.lockedXPosition}%`;
205
+ const actualHeight = state.bufferBottom - state.bufferTop;
206
+ this.bufferZone.style.left = "0";
207
+ this.bufferZone.style.width = "100%";
208
+ this.bufferZone.style.top = `${state.bufferTop}%`;
209
+ this.bufferZone.style.height = `${actualHeight}%`;
210
+ this.bufferZone.style.display = "block";
211
+ } else if (state.state === "y-capturing") {
212
+ this.vBar.style.display = "none";
213
+ this.directionIndicator.style.display = "none";
214
+ this.directionLine.style.display = "none";
215
+ this.lockedXBar.style.display = "block";
216
+ this.lockedXBar.style.left = `${state.lockedXPosition}%`;
217
+ const actualHeight = state.bufferBottom - state.bufferTop;
218
+ this.bufferZone.style.left = "0";
219
+ this.bufferZone.style.width = "100%";
220
+ this.bufferZone.style.top = `${state.bufferTop}%`;
221
+ this.bufferZone.style.height = `${actualHeight}%`;
222
+ this.bufferZone.style.display = "block";
223
+ const actualYPos = state.bufferTop + state.fineYPos / 100 * (state.bufferBottom - state.bufferTop);
224
+ this.hBar.style.display = "block";
225
+ this.hBar.style.top = `${actualYPos}%`;
226
+ }
227
+ return;
228
+ }
229
+ this.bufferZone.style.display = "none";
230
+ this.lockedXBar.style.display = "none";
231
+ this.directionIndicator.style.display = "none";
232
+ this.directionLine.style.display = "none";
233
+ if (state.state === "x-scan") {
234
+ this.vBar.style.display = "block";
235
+ this.vBar.style.left = `${state.xPos}%`;
236
+ this.hBar.style.display = "none";
237
+ } else if (state.state === "y-scan") {
238
+ this.vBar.style.display = "block";
239
+ this.vBar.style.left = `${state.xPos}%`;
240
+ this.hBar.style.display = "block";
241
+ this.hBar.style.top = `${state.yPos}%`;
242
+ }
243
+ }
244
+ calculateLineLength(x, y, dx, dy) {
245
+ if (dx === 0 && dy === -1) {
246
+ return y;
247
+ } else if (dx === 1 && dy === -1) {
248
+ return Math.min(100 - x, y) * Math.SQRT2;
249
+ } else if (dx === 1 && dy === 0) {
250
+ return 100 - x;
251
+ } else if (dx === 1 && dy === 1) {
252
+ return Math.min(100 - x, 100 - y) * Math.SQRT2;
253
+ } else if (dx === 0 && dy === 1) {
254
+ return 100 - y;
255
+ } else if (dx === -1 && dy === 1) {
256
+ return Math.min(x, 100 - y) * Math.SQRT2;
257
+ } else if (dx === -1 && dy === 0) {
258
+ return x;
259
+ } else if (dx === -1 && dy === -1) {
260
+ return Math.min(x, y) * Math.SQRT2;
261
+ }
262
+ return 50;
263
+ }
264
+ };
265
+ function resolveIndexAtPoint(container, xPercent, yPercent) {
266
+ const rect = container.getBoundingClientRect();
267
+ const clientX = rect.left + xPercent / 100 * rect.width;
268
+ const clientY = rect.top + yPercent / 100 * rect.height;
269
+ const root = container.getRootNode();
270
+ const element = root.elementFromPoint ? root.elementFromPoint(clientX, clientY) : document.elementFromPoint(clientX, clientY);
271
+ if (!element) return null;
272
+ const gridCell = element.closest(".grid-cell");
273
+ if (!gridCell || !gridCell.dataset.index) return null;
274
+ const index = parseInt(gridCell.dataset.index, 10);
275
+ return Number.isNaN(index) ? null : index;
276
+ }
277
+
278
+ exports.ContinuousOverlay = ContinuousOverlay;
279
+ exports.resolveIndexAtPoint = resolveIndexAtPoint;
280
+ //# sourceMappingURL=index.cjs.map
281
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/ContinuousOverlay.ts"],"names":[],"mappings":"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","file":"index.cjs","sourcesContent":["import type { ContinuousUpdate } from 'scan-engine';\n\nexport class ContinuousOverlay {\n private overlay: HTMLElement;\n private hBar: HTMLElement;\n private vBar: HTMLElement;\n private bufferZone: HTMLElement;\n private lockedXBar: HTMLElement;\n private directionIndicator: HTMLElement;\n private directionLine: HTMLElement;\n\n constructor(private container: HTMLElement) {\n this.overlay = document.createElement('div');\n this.overlay.style.position = 'absolute';\n this.overlay.style.top = '0';\n this.overlay.style.left = '0';\n this.overlay.style.width = '100%';\n this.overlay.style.height = '100%';\n this.overlay.style.pointerEvents = 'none';\n this.overlay.style.zIndex = '1000';\n\n this.bufferZone = document.createElement('div');\n this.bufferZone.style.position = 'absolute';\n this.bufferZone.style.top = '0';\n this.bufferZone.style.height = '100%';\n this.bufferZone.style.backgroundColor = 'rgba(128, 128, 128, 0.4)';\n this.bufferZone.style.borderLeft = '2px solid rgba(128, 128, 128, 0.8)';\n this.bufferZone.style.borderRight = '2px solid rgba(128, 128, 128, 0.8)';\n this.bufferZone.style.pointerEvents = 'none';\n this.bufferZone.style.display = 'none';\n this.overlay.appendChild(this.bufferZone);\n\n this.vBar = document.createElement('div');\n this.vBar.style.position = 'absolute';\n this.vBar.style.top = '0';\n this.vBar.style.width = '4px';\n this.vBar.style.height = '100%';\n this.vBar.style.backgroundColor = 'rgba(255, 0, 0, 0.5)';\n this.vBar.style.borderLeft = '1px solid red';\n this.vBar.style.borderRight = '1px solid red';\n this.vBar.style.display = 'none';\n this.overlay.appendChild(this.vBar);\n\n this.hBar = document.createElement('div');\n this.hBar.style.position = 'absolute';\n this.hBar.style.left = '0';\n this.hBar.style.width = '100%';\n this.hBar.style.height = '4px';\n this.hBar.style.backgroundColor = 'rgba(255, 0, 0, 0.5)';\n this.hBar.style.borderTop = '1px solid red';\n this.hBar.style.borderBottom = '1px solid red';\n this.hBar.style.display = 'none';\n this.overlay.appendChild(this.hBar);\n\n this.lockedXBar = document.createElement('div');\n this.lockedXBar.style.position = 'absolute';\n this.lockedXBar.style.top = '0';\n this.lockedXBar.style.width = '3px';\n this.lockedXBar.style.height = '100%';\n this.lockedXBar.style.backgroundColor = 'rgba(0, 255, 0, 0.7)';\n this.lockedXBar.style.borderLeft = '1px solid green';\n this.lockedXBar.style.borderRight = '1px solid green';\n this.lockedXBar.style.display = 'none';\n this.overlay.appendChild(this.lockedXBar);\n\n this.directionIndicator = document.createElement('div');\n this.directionIndicator.style.position = 'absolute';\n this.directionIndicator.style.top = '10px';\n this.directionIndicator.style.right = '10px';\n this.directionIndicator.style.width = '80px';\n this.directionIndicator.style.height = '80px';\n this.directionIndicator.style.borderRadius = '50%';\n this.directionIndicator.style.backgroundColor = 'rgba(255, 255, 255, 0.9)';\n this.directionIndicator.style.border = '3px solid #333';\n this.directionIndicator.style.display = 'none';\n this.directionIndicator.style.pointerEvents = 'none';\n this.overlay.appendChild(this.directionIndicator);\n\n this.directionLine = document.createElement('div');\n this.directionLine.style.position = 'absolute';\n this.directionLine.style.height = '2px';\n this.directionLine.style.backgroundColor = 'rgba(33, 150, 243, 0.6)';\n this.directionLine.style.transformOrigin = '0 50%';\n this.directionLine.style.display = 'none';\n this.directionLine.style.pointerEvents = 'none';\n this.directionLine.style.zIndex = '5';\n this.overlay.appendChild(this.directionLine);\n\n this.container.appendChild(this.overlay);\n }\n\n destroy() {\n if (this.overlay.parentNode) {\n this.overlay.parentNode.removeChild(this.overlay);\n }\n }\n\n update(state: ContinuousUpdate) {\n if (state.technique === 'eight-direction') {\n this.vBar.style.display = 'none';\n this.hBar.style.display = 'none';\n this.bufferZone.style.display = 'none';\n this.lockedXBar.style.display = 'none';\n\n this.directionIndicator.style.display = 'block';\n this.directionLine.style.display = 'block';\n\n const angle = state.compassAngle;\n\n this.directionIndicator.innerHTML = `\n <div style=\"\n position: absolute;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%) rotate(${angle}deg);\n font-size: 24px;\n font-weight: bold;\n color: #2196F3;\n \">↑</div>\n <div style=\"\n position: absolute;\n top: 5px;\n left: 50%;\n transform: translateX(-50%);\n font-size: 12px;\n font-weight: bold;\n \">N</div>\n <div style=\"\n position: absolute;\n bottom: 5px;\n left: 50%;\n transform: translateX(-50%);\n font-size: 12px;\n font-weight: bold;\n \">S</div>\n <div style=\"\n position: absolute;\n left: 5px;\n top: 50%;\n transform: translateY(-50%);\n font-size: 12px;\n font-weight: bold;\n \">W</div>\n <div style=\"\n position: absolute;\n right: 5px;\n top: 50%;\n transform: translateY(-50%);\n font-size: 12px;\n font-weight: bold;\n \">E</div>\n <div style=\"\n position: absolute;\n bottom: 20px;\n left: 50%;\n transform: translateX(-50%);\n font-size: 10px;\n color: #666;\n \">${state.directionName} (${Math.round(angle)}°)</div>\n `;\n\n this.directionLine.style.left = `${state.xPos}%`;\n this.directionLine.style.top = `${state.yPos}%`;\n const lineLength = this.calculateLineLength(state.xPos, state.yPos, state.directionDx, state.directionDy);\n this.directionLine.style.width = `${lineLength}%`;\n this.directionLine.style.transformOrigin = '0 50%';\n this.directionLine.style.transform = `rotate(${angle}deg)`;\n\n this.vBar.style.display = 'block';\n this.vBar.style.width = '12px';\n this.vBar.style.height = '12px';\n this.vBar.style.borderRadius = '50%';\n this.vBar.style.backgroundColor = state.state === 'moving' ? '#FF5722' : '#2196F3';\n this.vBar.style.border = '2px solid white';\n this.vBar.style.zIndex = '10';\n this.vBar.style.left = `calc(${state.xPos}% - 6px)`;\n this.vBar.style.top = `calc(${state.yPos}% - 6px)`;\n return;\n }\n\n if (state.technique === 'gliding') {\n if (state.state === 'x-scanning') {\n this.vBar.style.display = 'none';\n this.hBar.style.display = 'none';\n this.lockedXBar.style.display = 'none';\n this.directionIndicator.style.display = 'none';\n this.directionLine.style.display = 'none';\n\n const actualWidth = state.bufferRight - state.bufferLeft;\n\n this.bufferZone.style.left = `${state.bufferLeft}%`;\n this.bufferZone.style.width = `${actualWidth}%`;\n this.bufferZone.style.height = '100%';\n this.bufferZone.style.top = '0';\n this.bufferZone.style.display = 'block';\n } else if (state.state === 'x-capturing') {\n this.hBar.style.display = 'none';\n this.lockedXBar.style.display = 'none';\n this.directionIndicator.style.display = 'none';\n this.directionLine.style.display = 'none';\n\n const actualWidth = state.bufferRight - state.bufferLeft;\n this.bufferZone.style.left = `${state.bufferLeft}%`;\n this.bufferZone.style.width = `${actualWidth}%`;\n this.bufferZone.style.height = '100%';\n this.bufferZone.style.top = '0';\n this.bufferZone.style.display = 'block';\n\n const actualXPos = state.bufferLeft + (state.fineXPos / 100) * (state.bufferRight - state.bufferLeft);\n this.vBar.style.display = 'block';\n this.vBar.style.left = `${actualXPos}%`;\n } else if (state.state === 'y-scanning') {\n this.vBar.style.display = 'none';\n this.hBar.style.display = 'none';\n this.directionIndicator.style.display = 'none';\n this.directionLine.style.display = 'none';\n\n this.lockedXBar.style.display = 'block';\n this.lockedXBar.style.left = `${state.lockedXPosition}%`;\n\n const actualHeight = state.bufferBottom - state.bufferTop;\n\n this.bufferZone.style.left = '0';\n this.bufferZone.style.width = '100%';\n this.bufferZone.style.top = `${state.bufferTop}%`;\n this.bufferZone.style.height = `${actualHeight}%`;\n this.bufferZone.style.display = 'block';\n } else if (state.state === 'y-capturing') {\n this.vBar.style.display = 'none';\n this.directionIndicator.style.display = 'none';\n this.directionLine.style.display = 'none';\n\n this.lockedXBar.style.display = 'block';\n this.lockedXBar.style.left = `${state.lockedXPosition}%`;\n\n const actualHeight = state.bufferBottom - state.bufferTop;\n this.bufferZone.style.left = '0';\n this.bufferZone.style.width = '100%';\n this.bufferZone.style.top = `${state.bufferTop}%`;\n this.bufferZone.style.height = `${actualHeight}%`;\n this.bufferZone.style.display = 'block';\n\n const actualYPos = state.bufferTop + (state.fineYPos / 100) * (state.bufferBottom - state.bufferTop);\n this.hBar.style.display = 'block';\n this.hBar.style.top = `${actualYPos}%`;\n }\n return;\n }\n\n this.bufferZone.style.display = 'none';\n this.lockedXBar.style.display = 'none';\n this.directionIndicator.style.display = 'none';\n this.directionLine.style.display = 'none';\n\n if (state.state === 'x-scan') {\n this.vBar.style.display = 'block';\n this.vBar.style.left = `${state.xPos}%`;\n this.hBar.style.display = 'none';\n } else if (state.state === 'y-scan') {\n this.vBar.style.display = 'block';\n this.vBar.style.left = `${state.xPos}%`;\n this.hBar.style.display = 'block';\n this.hBar.style.top = `${state.yPos}%`;\n }\n }\n\n private calculateLineLength(x: number, y: number, dx: number, dy: number): number {\n if (dx === 0 && dy === -1) {\n return y;\n } else if (dx === 1 && dy === -1) {\n return Math.min(100 - x, y) * Math.SQRT2;\n } else if (dx === 1 && dy === 0) {\n return 100 - x;\n } else if (dx === 1 && dy === 1) {\n return Math.min(100 - x, 100 - y) * Math.SQRT2;\n } else if (dx === 0 && dy === 1) {\n return 100 - y;\n } else if (dx === -1 && dy === 1) {\n return Math.min(x, 100 - y) * Math.SQRT2;\n } else if (dx === -1 && dy === 0) {\n return x;\n } else if (dx === -1 && dy === -1) {\n return Math.min(x, y) * Math.SQRT2;\n }\n return 50;\n }\n}\n\nexport function resolveIndexAtPoint(container: HTMLElement, xPercent: number, yPercent: number): number | null {\n const rect = container.getBoundingClientRect();\n const clientX = rect.left + (xPercent / 100) * rect.width;\n const clientY = rect.top + (yPercent / 100) * rect.height;\n const root = container.getRootNode() as Document | ShadowRoot;\n const element = root.elementFromPoint ? root.elementFromPoint(clientX, clientY) : document.elementFromPoint(clientX, clientY);\n if (!element) return null;\n const gridCell = (element as HTMLElement).closest('.grid-cell') as HTMLElement | null;\n if (!gridCell || !gridCell.dataset.index) return null;\n const index = parseInt(gridCell.dataset.index, 10);\n return Number.isNaN(index) ? null : index;\n}\n"]}
@@ -0,0 +1,19 @@
1
+ import { ContinuousUpdate } from 'scan-engine';
2
+
3
+ declare class ContinuousOverlay {
4
+ private container;
5
+ private overlay;
6
+ private hBar;
7
+ private vBar;
8
+ private bufferZone;
9
+ private lockedXBar;
10
+ private directionIndicator;
11
+ private directionLine;
12
+ constructor(container: HTMLElement);
13
+ destroy(): void;
14
+ update(state: ContinuousUpdate): void;
15
+ private calculateLineLength;
16
+ }
17
+ declare function resolveIndexAtPoint(container: HTMLElement, xPercent: number, yPercent: number): number | null;
18
+
19
+ export { ContinuousOverlay, resolveIndexAtPoint };
@@ -0,0 +1,19 @@
1
+ import { ContinuousUpdate } from 'scan-engine';
2
+
3
+ declare class ContinuousOverlay {
4
+ private container;
5
+ private overlay;
6
+ private hBar;
7
+ private vBar;
8
+ private bufferZone;
9
+ private lockedXBar;
10
+ private directionIndicator;
11
+ private directionLine;
12
+ constructor(container: HTMLElement);
13
+ destroy(): void;
14
+ update(state: ContinuousUpdate): void;
15
+ private calculateLineLength;
16
+ }
17
+ declare function resolveIndexAtPoint(container: HTMLElement, xPercent: number, yPercent: number): number | null;
18
+
19
+ export { ContinuousOverlay, resolveIndexAtPoint };
package/dist/index.js ADDED
@@ -0,0 +1,278 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
3
+ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
4
+
5
+ // src/ContinuousOverlay.ts
6
+ var ContinuousOverlay = class {
7
+ constructor(container) {
8
+ this.container = container;
9
+ __publicField(this, "overlay");
10
+ __publicField(this, "hBar");
11
+ __publicField(this, "vBar");
12
+ __publicField(this, "bufferZone");
13
+ __publicField(this, "lockedXBar");
14
+ __publicField(this, "directionIndicator");
15
+ __publicField(this, "directionLine");
16
+ this.overlay = document.createElement("div");
17
+ this.overlay.style.position = "absolute";
18
+ this.overlay.style.top = "0";
19
+ this.overlay.style.left = "0";
20
+ this.overlay.style.width = "100%";
21
+ this.overlay.style.height = "100%";
22
+ this.overlay.style.pointerEvents = "none";
23
+ this.overlay.style.zIndex = "1000";
24
+ this.bufferZone = document.createElement("div");
25
+ this.bufferZone.style.position = "absolute";
26
+ this.bufferZone.style.top = "0";
27
+ this.bufferZone.style.height = "100%";
28
+ this.bufferZone.style.backgroundColor = "rgba(128, 128, 128, 0.4)";
29
+ this.bufferZone.style.borderLeft = "2px solid rgba(128, 128, 128, 0.8)";
30
+ this.bufferZone.style.borderRight = "2px solid rgba(128, 128, 128, 0.8)";
31
+ this.bufferZone.style.pointerEvents = "none";
32
+ this.bufferZone.style.display = "none";
33
+ this.overlay.appendChild(this.bufferZone);
34
+ this.vBar = document.createElement("div");
35
+ this.vBar.style.position = "absolute";
36
+ this.vBar.style.top = "0";
37
+ this.vBar.style.width = "4px";
38
+ this.vBar.style.height = "100%";
39
+ this.vBar.style.backgroundColor = "rgba(255, 0, 0, 0.5)";
40
+ this.vBar.style.borderLeft = "1px solid red";
41
+ this.vBar.style.borderRight = "1px solid red";
42
+ this.vBar.style.display = "none";
43
+ this.overlay.appendChild(this.vBar);
44
+ this.hBar = document.createElement("div");
45
+ this.hBar.style.position = "absolute";
46
+ this.hBar.style.left = "0";
47
+ this.hBar.style.width = "100%";
48
+ this.hBar.style.height = "4px";
49
+ this.hBar.style.backgroundColor = "rgba(255, 0, 0, 0.5)";
50
+ this.hBar.style.borderTop = "1px solid red";
51
+ this.hBar.style.borderBottom = "1px solid red";
52
+ this.hBar.style.display = "none";
53
+ this.overlay.appendChild(this.hBar);
54
+ this.lockedXBar = document.createElement("div");
55
+ this.lockedXBar.style.position = "absolute";
56
+ this.lockedXBar.style.top = "0";
57
+ this.lockedXBar.style.width = "3px";
58
+ this.lockedXBar.style.height = "100%";
59
+ this.lockedXBar.style.backgroundColor = "rgba(0, 255, 0, 0.7)";
60
+ this.lockedXBar.style.borderLeft = "1px solid green";
61
+ this.lockedXBar.style.borderRight = "1px solid green";
62
+ this.lockedXBar.style.display = "none";
63
+ this.overlay.appendChild(this.lockedXBar);
64
+ this.directionIndicator = document.createElement("div");
65
+ this.directionIndicator.style.position = "absolute";
66
+ this.directionIndicator.style.top = "10px";
67
+ this.directionIndicator.style.right = "10px";
68
+ this.directionIndicator.style.width = "80px";
69
+ this.directionIndicator.style.height = "80px";
70
+ this.directionIndicator.style.borderRadius = "50%";
71
+ this.directionIndicator.style.backgroundColor = "rgba(255, 255, 255, 0.9)";
72
+ this.directionIndicator.style.border = "3px solid #333";
73
+ this.directionIndicator.style.display = "none";
74
+ this.directionIndicator.style.pointerEvents = "none";
75
+ this.overlay.appendChild(this.directionIndicator);
76
+ this.directionLine = document.createElement("div");
77
+ this.directionLine.style.position = "absolute";
78
+ this.directionLine.style.height = "2px";
79
+ this.directionLine.style.backgroundColor = "rgba(33, 150, 243, 0.6)";
80
+ this.directionLine.style.transformOrigin = "0 50%";
81
+ this.directionLine.style.display = "none";
82
+ this.directionLine.style.pointerEvents = "none";
83
+ this.directionLine.style.zIndex = "5";
84
+ this.overlay.appendChild(this.directionLine);
85
+ this.container.appendChild(this.overlay);
86
+ }
87
+ destroy() {
88
+ if (this.overlay.parentNode) {
89
+ this.overlay.parentNode.removeChild(this.overlay);
90
+ }
91
+ }
92
+ update(state) {
93
+ if (state.technique === "eight-direction") {
94
+ this.vBar.style.display = "none";
95
+ this.hBar.style.display = "none";
96
+ this.bufferZone.style.display = "none";
97
+ this.lockedXBar.style.display = "none";
98
+ this.directionIndicator.style.display = "block";
99
+ this.directionLine.style.display = "block";
100
+ const angle = state.compassAngle;
101
+ this.directionIndicator.innerHTML = `
102
+ <div style="
103
+ position: absolute;
104
+ top: 50%;
105
+ left: 50%;
106
+ transform: translate(-50%, -50%) rotate(${angle}deg);
107
+ font-size: 24px;
108
+ font-weight: bold;
109
+ color: #2196F3;
110
+ ">\u2191</div>
111
+ <div style="
112
+ position: absolute;
113
+ top: 5px;
114
+ left: 50%;
115
+ transform: translateX(-50%);
116
+ font-size: 12px;
117
+ font-weight: bold;
118
+ ">N</div>
119
+ <div style="
120
+ position: absolute;
121
+ bottom: 5px;
122
+ left: 50%;
123
+ transform: translateX(-50%);
124
+ font-size: 12px;
125
+ font-weight: bold;
126
+ ">S</div>
127
+ <div style="
128
+ position: absolute;
129
+ left: 5px;
130
+ top: 50%;
131
+ transform: translateY(-50%);
132
+ font-size: 12px;
133
+ font-weight: bold;
134
+ ">W</div>
135
+ <div style="
136
+ position: absolute;
137
+ right: 5px;
138
+ top: 50%;
139
+ transform: translateY(-50%);
140
+ font-size: 12px;
141
+ font-weight: bold;
142
+ ">E</div>
143
+ <div style="
144
+ position: absolute;
145
+ bottom: 20px;
146
+ left: 50%;
147
+ transform: translateX(-50%);
148
+ font-size: 10px;
149
+ color: #666;
150
+ ">${state.directionName} (${Math.round(angle)}\xB0)</div>
151
+ `;
152
+ this.directionLine.style.left = `${state.xPos}%`;
153
+ this.directionLine.style.top = `${state.yPos}%`;
154
+ const lineLength = this.calculateLineLength(state.xPos, state.yPos, state.directionDx, state.directionDy);
155
+ this.directionLine.style.width = `${lineLength}%`;
156
+ this.directionLine.style.transformOrigin = "0 50%";
157
+ this.directionLine.style.transform = `rotate(${angle}deg)`;
158
+ this.vBar.style.display = "block";
159
+ this.vBar.style.width = "12px";
160
+ this.vBar.style.height = "12px";
161
+ this.vBar.style.borderRadius = "50%";
162
+ this.vBar.style.backgroundColor = state.state === "moving" ? "#FF5722" : "#2196F3";
163
+ this.vBar.style.border = "2px solid white";
164
+ this.vBar.style.zIndex = "10";
165
+ this.vBar.style.left = `calc(${state.xPos}% - 6px)`;
166
+ this.vBar.style.top = `calc(${state.yPos}% - 6px)`;
167
+ return;
168
+ }
169
+ if (state.technique === "gliding") {
170
+ if (state.state === "x-scanning") {
171
+ this.vBar.style.display = "none";
172
+ this.hBar.style.display = "none";
173
+ this.lockedXBar.style.display = "none";
174
+ this.directionIndicator.style.display = "none";
175
+ this.directionLine.style.display = "none";
176
+ const actualWidth = state.bufferRight - state.bufferLeft;
177
+ this.bufferZone.style.left = `${state.bufferLeft}%`;
178
+ this.bufferZone.style.width = `${actualWidth}%`;
179
+ this.bufferZone.style.height = "100%";
180
+ this.bufferZone.style.top = "0";
181
+ this.bufferZone.style.display = "block";
182
+ } else if (state.state === "x-capturing") {
183
+ this.hBar.style.display = "none";
184
+ this.lockedXBar.style.display = "none";
185
+ this.directionIndicator.style.display = "none";
186
+ this.directionLine.style.display = "none";
187
+ const actualWidth = state.bufferRight - state.bufferLeft;
188
+ this.bufferZone.style.left = `${state.bufferLeft}%`;
189
+ this.bufferZone.style.width = `${actualWidth}%`;
190
+ this.bufferZone.style.height = "100%";
191
+ this.bufferZone.style.top = "0";
192
+ this.bufferZone.style.display = "block";
193
+ const actualXPos = state.bufferLeft + state.fineXPos / 100 * (state.bufferRight - state.bufferLeft);
194
+ this.vBar.style.display = "block";
195
+ this.vBar.style.left = `${actualXPos}%`;
196
+ } else if (state.state === "y-scanning") {
197
+ this.vBar.style.display = "none";
198
+ this.hBar.style.display = "none";
199
+ this.directionIndicator.style.display = "none";
200
+ this.directionLine.style.display = "none";
201
+ this.lockedXBar.style.display = "block";
202
+ this.lockedXBar.style.left = `${state.lockedXPosition}%`;
203
+ const actualHeight = state.bufferBottom - state.bufferTop;
204
+ this.bufferZone.style.left = "0";
205
+ this.bufferZone.style.width = "100%";
206
+ this.bufferZone.style.top = `${state.bufferTop}%`;
207
+ this.bufferZone.style.height = `${actualHeight}%`;
208
+ this.bufferZone.style.display = "block";
209
+ } else if (state.state === "y-capturing") {
210
+ this.vBar.style.display = "none";
211
+ this.directionIndicator.style.display = "none";
212
+ this.directionLine.style.display = "none";
213
+ this.lockedXBar.style.display = "block";
214
+ this.lockedXBar.style.left = `${state.lockedXPosition}%`;
215
+ const actualHeight = state.bufferBottom - state.bufferTop;
216
+ this.bufferZone.style.left = "0";
217
+ this.bufferZone.style.width = "100%";
218
+ this.bufferZone.style.top = `${state.bufferTop}%`;
219
+ this.bufferZone.style.height = `${actualHeight}%`;
220
+ this.bufferZone.style.display = "block";
221
+ const actualYPos = state.bufferTop + state.fineYPos / 100 * (state.bufferBottom - state.bufferTop);
222
+ this.hBar.style.display = "block";
223
+ this.hBar.style.top = `${actualYPos}%`;
224
+ }
225
+ return;
226
+ }
227
+ this.bufferZone.style.display = "none";
228
+ this.lockedXBar.style.display = "none";
229
+ this.directionIndicator.style.display = "none";
230
+ this.directionLine.style.display = "none";
231
+ if (state.state === "x-scan") {
232
+ this.vBar.style.display = "block";
233
+ this.vBar.style.left = `${state.xPos}%`;
234
+ this.hBar.style.display = "none";
235
+ } else if (state.state === "y-scan") {
236
+ this.vBar.style.display = "block";
237
+ this.vBar.style.left = `${state.xPos}%`;
238
+ this.hBar.style.display = "block";
239
+ this.hBar.style.top = `${state.yPos}%`;
240
+ }
241
+ }
242
+ calculateLineLength(x, y, dx, dy) {
243
+ if (dx === 0 && dy === -1) {
244
+ return y;
245
+ } else if (dx === 1 && dy === -1) {
246
+ return Math.min(100 - x, y) * Math.SQRT2;
247
+ } else if (dx === 1 && dy === 0) {
248
+ return 100 - x;
249
+ } else if (dx === 1 && dy === 1) {
250
+ return Math.min(100 - x, 100 - y) * Math.SQRT2;
251
+ } else if (dx === 0 && dy === 1) {
252
+ return 100 - y;
253
+ } else if (dx === -1 && dy === 1) {
254
+ return Math.min(x, 100 - y) * Math.SQRT2;
255
+ } else if (dx === -1 && dy === 0) {
256
+ return x;
257
+ } else if (dx === -1 && dy === -1) {
258
+ return Math.min(x, y) * Math.SQRT2;
259
+ }
260
+ return 50;
261
+ }
262
+ };
263
+ function resolveIndexAtPoint(container, xPercent, yPercent) {
264
+ const rect = container.getBoundingClientRect();
265
+ const clientX = rect.left + xPercent / 100 * rect.width;
266
+ const clientY = rect.top + yPercent / 100 * rect.height;
267
+ const root = container.getRootNode();
268
+ const element = root.elementFromPoint ? root.elementFromPoint(clientX, clientY) : document.elementFromPoint(clientX, clientY);
269
+ if (!element) return null;
270
+ const gridCell = element.closest(".grid-cell");
271
+ if (!gridCell || !gridCell.dataset.index) return null;
272
+ const index = parseInt(gridCell.dataset.index, 10);
273
+ return Number.isNaN(index) ? null : index;
274
+ }
275
+
276
+ export { ContinuousOverlay, resolveIndexAtPoint };
277
+ //# sourceMappingURL=index.js.map
278
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/ContinuousOverlay.ts"],"names":[],"mappings":";;;;;AAEO,IAAM,oBAAN,MAAwB;AAAA,EAS7B,YAAoB,SAAA,EAAwB;AAAxB,IAAA,IAAA,CAAA,SAAA,GAAA,SAAA;AARpB,IAAA,aAAA,CAAA,IAAA,EAAQ,SAAA,CAAA;AACR,IAAA,aAAA,CAAA,IAAA,EAAQ,MAAA,CAAA;AACR,IAAA,aAAA,CAAA,IAAA,EAAQ,MAAA,CAAA;AACR,IAAA,aAAA,CAAA,IAAA,EAAQ,YAAA,CAAA;AACR,IAAA,aAAA,CAAA,IAAA,EAAQ,YAAA,CAAA;AACR,IAAA,aAAA,CAAA,IAAA,EAAQ,oBAAA,CAAA;AACR,IAAA,aAAA,CAAA,IAAA,EAAQ,eAAA,CAAA;AAGN,IAAA,IAAA,CAAK,OAAA,GAAU,QAAA,CAAS,aAAA,CAAc,KAAK,CAAA;AAC3C,IAAA,IAAA,CAAK,OAAA,CAAQ,MAAM,QAAA,GAAW,UAAA;AAC9B,IAAA,IAAA,CAAK,OAAA,CAAQ,MAAM,GAAA,GAAM,GAAA;AACzB,IAAA,IAAA,CAAK,OAAA,CAAQ,MAAM,IAAA,GAAO,GAAA;AAC1B,IAAA,IAAA,CAAK,OAAA,CAAQ,MAAM,KAAA,GAAQ,MAAA;AAC3B,IAAA,IAAA,CAAK,OAAA,CAAQ,MAAM,MAAA,GAAS,MAAA;AAC5B,IAAA,IAAA,CAAK,OAAA,CAAQ,MAAM,aAAA,GAAgB,MAAA;AACnC,IAAA,IAAA,CAAK,OAAA,CAAQ,MAAM,MAAA,GAAS,MAAA;AAE5B,IAAA,IAAA,CAAK,UAAA,GAAa,QAAA,CAAS,aAAA,CAAc,KAAK,CAAA;AAC9C,IAAA,IAAA,CAAK,UAAA,CAAW,MAAM,QAAA,GAAW,UAAA;AACjC,IAAA,IAAA,CAAK,UAAA,CAAW,MAAM,GAAA,GAAM,GAAA;AAC5B,IAAA,IAAA,CAAK,UAAA,CAAW,MAAM,MAAA,GAAS,MAAA;AAC/B,IAAA,IAAA,CAAK,UAAA,CAAW,MAAM,eAAA,GAAkB,0BAAA;AACxC,IAAA,IAAA,CAAK,UAAA,CAAW,MAAM,UAAA,GAAa,oCAAA;AACnC,IAAA,IAAA,CAAK,UAAA,CAAW,MAAM,WAAA,GAAc,oCAAA;AACpC,IAAA,IAAA,CAAK,UAAA,CAAW,MAAM,aAAA,GAAgB,MAAA;AACtC,IAAA,IAAA,CAAK,UAAA,CAAW,MAAM,OAAA,GAAU,MAAA;AAChC,IAAA,IAAA,CAAK,OAAA,CAAQ,WAAA,CAAY,IAAA,CAAK,UAAU,CAAA;AAExC,IAAA,IAAA,CAAK,IAAA,GAAO,QAAA,CAAS,aAAA,CAAc,KAAK,CAAA;AACxC,IAAA,IAAA,CAAK,IAAA,CAAK,MAAM,QAAA,GAAW,UAAA;AAC3B,IAAA,IAAA,CAAK,IAAA,CAAK,MAAM,GAAA,GAAM,GAAA;AACtB,IAAA,IAAA,CAAK,IAAA,CAAK,MAAM,KAAA,GAAQ,KAAA;AACxB,IAAA,IAAA,CAAK,IAAA,CAAK,MAAM,MAAA,GAAS,MAAA;AACzB,IAAA,IAAA,CAAK,IAAA,CAAK,MAAM,eAAA,GAAkB,sBAAA;AAClC,IAAA,IAAA,CAAK,IAAA,CAAK,MAAM,UAAA,GAAa,eAAA;AAC7B,IAAA,IAAA,CAAK,IAAA,CAAK,MAAM,WAAA,GAAc,eAAA;AAC9B,IAAA,IAAA,CAAK,IAAA,CAAK,MAAM,OAAA,GAAU,MAAA;AAC1B,IAAA,IAAA,CAAK,OAAA,CAAQ,WAAA,CAAY,IAAA,CAAK,IAAI,CAAA;AAElC,IAAA,IAAA,CAAK,IAAA,GAAO,QAAA,CAAS,aAAA,CAAc,KAAK,CAAA;AACxC,IAAA,IAAA,CAAK,IAAA,CAAK,MAAM,QAAA,GAAW,UAAA;AAC3B,IAAA,IAAA,CAAK,IAAA,CAAK,MAAM,IAAA,GAAO,GAAA;AACvB,IAAA,IAAA,CAAK,IAAA,CAAK,MAAM,KAAA,GAAQ,MAAA;AACxB,IAAA,IAAA,CAAK,IAAA,CAAK,MAAM,MAAA,GAAS,KAAA;AACzB,IAAA,IAAA,CAAK,IAAA,CAAK,MAAM,eAAA,GAAkB,sBAAA;AAClC,IAAA,IAAA,CAAK,IAAA,CAAK,MAAM,SAAA,GAAY,eAAA;AAC5B,IAAA,IAAA,CAAK,IAAA,CAAK,MAAM,YAAA,GAAe,eAAA;AAC/B,IAAA,IAAA,CAAK,IAAA,CAAK,MAAM,OAAA,GAAU,MAAA;AAC1B,IAAA,IAAA,CAAK,OAAA,CAAQ,WAAA,CAAY,IAAA,CAAK,IAAI,CAAA;AAElC,IAAA,IAAA,CAAK,UAAA,GAAa,QAAA,CAAS,aAAA,CAAc,KAAK,CAAA;AAC9C,IAAA,IAAA,CAAK,UAAA,CAAW,MAAM,QAAA,GAAW,UAAA;AACjC,IAAA,IAAA,CAAK,UAAA,CAAW,MAAM,GAAA,GAAM,GAAA;AAC5B,IAAA,IAAA,CAAK,UAAA,CAAW,MAAM,KAAA,GAAQ,KAAA;AAC9B,IAAA,IAAA,CAAK,UAAA,CAAW,MAAM,MAAA,GAAS,MAAA;AAC/B,IAAA,IAAA,CAAK,UAAA,CAAW,MAAM,eAAA,GAAkB,sBAAA;AACxC,IAAA,IAAA,CAAK,UAAA,CAAW,MAAM,UAAA,GAAa,iBAAA;AACnC,IAAA,IAAA,CAAK,UAAA,CAAW,MAAM,WAAA,GAAc,iBAAA;AACpC,IAAA,IAAA,CAAK,UAAA,CAAW,MAAM,OAAA,GAAU,MAAA;AAChC,IAAA,IAAA,CAAK,OAAA,CAAQ,WAAA,CAAY,IAAA,CAAK,UAAU,CAAA;AAExC,IAAA,IAAA,CAAK,kBAAA,GAAqB,QAAA,CAAS,aAAA,CAAc,KAAK,CAAA;AACtD,IAAA,IAAA,CAAK,kBAAA,CAAmB,MAAM,QAAA,GAAW,UAAA;AACzC,IAAA,IAAA,CAAK,kBAAA,CAAmB,MAAM,GAAA,GAAM,MAAA;AACpC,IAAA,IAAA,CAAK,kBAAA,CAAmB,MAAM,KAAA,GAAQ,MAAA;AACtC,IAAA,IAAA,CAAK,kBAAA,CAAmB,MAAM,KAAA,GAAQ,MAAA;AACtC,IAAA,IAAA,CAAK,kBAAA,CAAmB,MAAM,MAAA,GAAS,MAAA;AACvC,IAAA,IAAA,CAAK,kBAAA,CAAmB,MAAM,YAAA,GAAe,KAAA;AAC7C,IAAA,IAAA,CAAK,kBAAA,CAAmB,MAAM,eAAA,GAAkB,0BAAA;AAChD,IAAA,IAAA,CAAK,kBAAA,CAAmB,MAAM,MAAA,GAAS,gBAAA;AACvC,IAAA,IAAA,CAAK,kBAAA,CAAmB,MAAM,OAAA,GAAU,MAAA;AACxC,IAAA,IAAA,CAAK,kBAAA,CAAmB,MAAM,aAAA,GAAgB,MAAA;AAC9C,IAAA,IAAA,CAAK,OAAA,CAAQ,WAAA,CAAY,IAAA,CAAK,kBAAkB,CAAA;AAEhD,IAAA,IAAA,CAAK,aAAA,GAAgB,QAAA,CAAS,aAAA,CAAc,KAAK,CAAA;AACjD,IAAA,IAAA,CAAK,aAAA,CAAc,MAAM,QAAA,GAAW,UAAA;AACpC,IAAA,IAAA,CAAK,aAAA,CAAc,MAAM,MAAA,GAAS,KAAA;AAClC,IAAA,IAAA,CAAK,aAAA,CAAc,MAAM,eAAA,GAAkB,yBAAA;AAC3C,IAAA,IAAA,CAAK,aAAA,CAAc,MAAM,eAAA,GAAkB,OAAA;AAC3C,IAAA,IAAA,CAAK,aAAA,CAAc,MAAM,OAAA,GAAU,MAAA;AACnC,IAAA,IAAA,CAAK,aAAA,CAAc,MAAM,aAAA,GAAgB,MAAA;AACzC,IAAA,IAAA,CAAK,aAAA,CAAc,MAAM,MAAA,GAAS,GAAA;AAClC,IAAA,IAAA,CAAK,OAAA,CAAQ,WAAA,CAAY,IAAA,CAAK,aAAa,CAAA;AAE3C,IAAA,IAAA,CAAK,SAAA,CAAU,WAAA,CAAY,IAAA,CAAK,OAAO,CAAA;AAAA,EACzC;AAAA,EAEA,OAAA,GAAU;AACR,IAAA,IAAI,IAAA,CAAK,QAAQ,UAAA,EAAY;AAC3B,MAAA,IAAA,CAAK,OAAA,CAAQ,UAAA,CAAW,WAAA,CAAY,IAAA,CAAK,OAAO,CAAA;AAAA,IAClD;AAAA,EACF;AAAA,EAEA,OAAO,KAAA,EAAyB;AAC9B,IAAA,IAAI,KAAA,CAAM,cAAc,iBAAA,EAAmB;AACzC,MAAA,IAAA,CAAK,IAAA,CAAK,MAAM,OAAA,GAAU,MAAA;AAC1B,MAAA,IAAA,CAAK,IAAA,CAAK,MAAM,OAAA,GAAU,MAAA;AAC1B,MAAA,IAAA,CAAK,UAAA,CAAW,MAAM,OAAA,GAAU,MAAA;AAChC,MAAA,IAAA,CAAK,UAAA,CAAW,MAAM,OAAA,GAAU,MAAA;AAEhC,MAAA,IAAA,CAAK,kBAAA,CAAmB,MAAM,OAAA,GAAU,OAAA;AACxC,MAAA,IAAA,CAAK,aAAA,CAAc,MAAM,OAAA,GAAU,OAAA;AAEnC,MAAA,MAAM,QAAQ,KAAA,CAAM,YAAA;AAEpB,MAAA,IAAA,CAAK,mBAAmB,SAAA,GAAY;AAAA;AAAA;AAAA;AAAA;AAAA,kDAAA,EAKU,KAAK,CAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,UAAA,EA4C7C,MAAM,aAAa,CAAA,EAAA,EAAK,IAAA,CAAK,KAAA,CAAM,KAAK,CAAC,CAAA;AAAA,MAAA,CAAA;AAG/C,MAAA,IAAA,CAAK,aAAA,CAAc,KAAA,CAAM,IAAA,GAAO,CAAA,EAAG,MAAM,IAAI,CAAA,CAAA,CAAA;AAC7C,MAAA,IAAA,CAAK,aAAA,CAAc,KAAA,CAAM,GAAA,GAAM,CAAA,EAAG,MAAM,IAAI,CAAA,CAAA,CAAA;AAC5C,MAAA,MAAM,UAAA,GAAa,IAAA,CAAK,mBAAA,CAAoB,KAAA,CAAM,IAAA,EAAM,MAAM,IAAA,EAAM,KAAA,CAAM,WAAA,EAAa,KAAA,CAAM,WAAW,CAAA;AACxG,MAAA,IAAA,CAAK,aAAA,CAAc,KAAA,CAAM,KAAA,GAAQ,CAAA,EAAG,UAAU,CAAA,CAAA,CAAA;AAC9C,MAAA,IAAA,CAAK,aAAA,CAAc,MAAM,eAAA,GAAkB,OAAA;AAC3C,MAAA,IAAA,CAAK,aAAA,CAAc,KAAA,CAAM,SAAA,GAAY,CAAA,OAAA,EAAU,KAAK,CAAA,IAAA,CAAA;AAEpD,MAAA,IAAA,CAAK,IAAA,CAAK,MAAM,OAAA,GAAU,OAAA;AAC1B,MAAA,IAAA,CAAK,IAAA,CAAK,MAAM,KAAA,GAAQ,MAAA;AACxB,MAAA,IAAA,CAAK,IAAA,CAAK,MAAM,MAAA,GAAS,MAAA;AACzB,MAAA,IAAA,CAAK,IAAA,CAAK,MAAM,YAAA,GAAe,KAAA;AAC/B,MAAA,IAAA,CAAK,KAAK,KAAA,CAAM,eAAA,GAAkB,KAAA,CAAM,KAAA,KAAU,WAAW,SAAA,GAAY,SAAA;AACzE,MAAA,IAAA,CAAK,IAAA,CAAK,MAAM,MAAA,GAAS,iBAAA;AACzB,MAAA,IAAA,CAAK,IAAA,CAAK,MAAM,MAAA,GAAS,IAAA;AACzB,MAAA,IAAA,CAAK,IAAA,CAAK,KAAA,CAAM,IAAA,GAAO,CAAA,KAAA,EAAQ,MAAM,IAAI,CAAA,QAAA,CAAA;AACzC,MAAA,IAAA,CAAK,IAAA,CAAK,KAAA,CAAM,GAAA,GAAM,CAAA,KAAA,EAAQ,MAAM,IAAI,CAAA,QAAA,CAAA;AACxC,MAAA;AAAA,IACF;AAEA,IAAA,IAAI,KAAA,CAAM,cAAc,SAAA,EAAW;AACjC,MAAA,IAAI,KAAA,CAAM,UAAU,YAAA,EAAc;AAChC,QAAA,IAAA,CAAK,IAAA,CAAK,MAAM,OAAA,GAAU,MAAA;AAC1B,QAAA,IAAA,CAAK,IAAA,CAAK,MAAM,OAAA,GAAU,MAAA;AAC1B,QAAA,IAAA,CAAK,UAAA,CAAW,MAAM,OAAA,GAAU,MAAA;AAChC,QAAA,IAAA,CAAK,kBAAA,CAAmB,MAAM,OAAA,GAAU,MAAA;AACxC,QAAA,IAAA,CAAK,aAAA,CAAc,MAAM,OAAA,GAAU,MAAA;AAEnC,QAAA,MAAM,WAAA,GAAc,KAAA,CAAM,WAAA,GAAc,KAAA,CAAM,UAAA;AAE9C,QAAA,IAAA,CAAK,UAAA,CAAW,KAAA,CAAM,IAAA,GAAO,CAAA,EAAG,MAAM,UAAU,CAAA,CAAA,CAAA;AAChD,QAAA,IAAA,CAAK,UAAA,CAAW,KAAA,CAAM,KAAA,GAAQ,CAAA,EAAG,WAAW,CAAA,CAAA,CAAA;AAC5C,QAAA,IAAA,CAAK,UAAA,CAAW,MAAM,MAAA,GAAS,MAAA;AAC/B,QAAA,IAAA,CAAK,UAAA,CAAW,MAAM,GAAA,GAAM,GAAA;AAC5B,QAAA,IAAA,CAAK,UAAA,CAAW,MAAM,OAAA,GAAU,OAAA;AAAA,MAClC,CAAA,MAAA,IAAW,KAAA,CAAM,KAAA,KAAU,aAAA,EAAe;AACxC,QAAA,IAAA,CAAK,IAAA,CAAK,MAAM,OAAA,GAAU,MAAA;AAC1B,QAAA,IAAA,CAAK,UAAA,CAAW,MAAM,OAAA,GAAU,MAAA;AAChC,QAAA,IAAA,CAAK,kBAAA,CAAmB,MAAM,OAAA,GAAU,MAAA;AACxC,QAAA,IAAA,CAAK,aAAA,CAAc,MAAM,OAAA,GAAU,MAAA;AAEnC,QAAA,MAAM,WAAA,GAAc,KAAA,CAAM,WAAA,GAAc,KAAA,CAAM,UAAA;AAC9C,QAAA,IAAA,CAAK,UAAA,CAAW,KAAA,CAAM,IAAA,GAAO,CAAA,EAAG,MAAM,UAAU,CAAA,CAAA,CAAA;AAChD,QAAA,IAAA,CAAK,UAAA,CAAW,KAAA,CAAM,KAAA,GAAQ,CAAA,EAAG,WAAW,CAAA,CAAA,CAAA;AAC5C,QAAA,IAAA,CAAK,UAAA,CAAW,MAAM,MAAA,GAAS,MAAA;AAC/B,QAAA,IAAA,CAAK,UAAA,CAAW,MAAM,GAAA,GAAM,GAAA;AAC5B,QAAA,IAAA,CAAK,UAAA,CAAW,MAAM,OAAA,GAAU,OAAA;AAEhC,QAAA,MAAM,UAAA,GAAa,MAAM,UAAA,GAAc,KAAA,CAAM,WAAW,GAAA,IAAQ,KAAA,CAAM,cAAc,KAAA,CAAM,UAAA,CAAA;AAC1F,QAAA,IAAA,CAAK,IAAA,CAAK,MAAM,OAAA,GAAU,OAAA;AAC1B,QAAA,IAAA,CAAK,IAAA,CAAK,KAAA,CAAM,IAAA,GAAO,CAAA,EAAG,UAAU,CAAA,CAAA,CAAA;AAAA,MACtC,CAAA,MAAA,IAAW,KAAA,CAAM,KAAA,KAAU,YAAA,EAAc;AACvC,QAAA,IAAA,CAAK,IAAA,CAAK,MAAM,OAAA,GAAU,MAAA;AAC1B,QAAA,IAAA,CAAK,IAAA,CAAK,MAAM,OAAA,GAAU,MAAA;AAC1B,QAAA,IAAA,CAAK,kBAAA,CAAmB,MAAM,OAAA,GAAU,MAAA;AACxC,QAAA,IAAA,CAAK,aAAA,CAAc,MAAM,OAAA,GAAU,MAAA;AAEnC,QAAA,IAAA,CAAK,UAAA,CAAW,MAAM,OAAA,GAAU,OAAA;AAChC,QAAA,IAAA,CAAK,UAAA,CAAW,KAAA,CAAM,IAAA,GAAO,CAAA,EAAG,MAAM,eAAe,CAAA,CAAA,CAAA;AAErD,QAAA,MAAM,YAAA,GAAe,KAAA,CAAM,YAAA,GAAe,KAAA,CAAM,SAAA;AAEhD,QAAA,IAAA,CAAK,UAAA,CAAW,MAAM,IAAA,GAAO,GAAA;AAC7B,QAAA,IAAA,CAAK,UAAA,CAAW,MAAM,KAAA,GAAQ,MAAA;AAC9B,QAAA,IAAA,CAAK,UAAA,CAAW,KAAA,CAAM,GAAA,GAAM,CAAA,EAAG,MAAM,SAAS,CAAA,CAAA,CAAA;AAC9C,QAAA,IAAA,CAAK,UAAA,CAAW,KAAA,CAAM,MAAA,GAAS,CAAA,EAAG,YAAY,CAAA,CAAA,CAAA;AAC9C,QAAA,IAAA,CAAK,UAAA,CAAW,MAAM,OAAA,GAAU,OAAA;AAAA,MAClC,CAAA,MAAA,IAAW,KAAA,CAAM,KAAA,KAAU,aAAA,EAAe;AACxC,QAAA,IAAA,CAAK,IAAA,CAAK,MAAM,OAAA,GAAU,MAAA;AAC1B,QAAA,IAAA,CAAK,kBAAA,CAAmB,MAAM,OAAA,GAAU,MAAA;AACxC,QAAA,IAAA,CAAK,aAAA,CAAc,MAAM,OAAA,GAAU,MAAA;AAEnC,QAAA,IAAA,CAAK,UAAA,CAAW,MAAM,OAAA,GAAU,OAAA;AAChC,QAAA,IAAA,CAAK,UAAA,CAAW,KAAA,CAAM,IAAA,GAAO,CAAA,EAAG,MAAM,eAAe,CAAA,CAAA,CAAA;AAErD,QAAA,MAAM,YAAA,GAAe,KAAA,CAAM,YAAA,GAAe,KAAA,CAAM,SAAA;AAChD,QAAA,IAAA,CAAK,UAAA,CAAW,MAAM,IAAA,GAAO,GAAA;AAC7B,QAAA,IAAA,CAAK,UAAA,CAAW,MAAM,KAAA,GAAQ,MAAA;AAC9B,QAAA,IAAA,CAAK,UAAA,CAAW,KAAA,CAAM,GAAA,GAAM,CAAA,EAAG,MAAM,SAAS,CAAA,CAAA,CAAA;AAC9C,QAAA,IAAA,CAAK,UAAA,CAAW,KAAA,CAAM,MAAA,GAAS,CAAA,EAAG,YAAY,CAAA,CAAA,CAAA;AAC9C,QAAA,IAAA,CAAK,UAAA,CAAW,MAAM,OAAA,GAAU,OAAA;AAEhC,QAAA,MAAM,UAAA,GAAa,MAAM,SAAA,GAAa,KAAA,CAAM,WAAW,GAAA,IAAQ,KAAA,CAAM,eAAe,KAAA,CAAM,SAAA,CAAA;AAC1F,QAAA,IAAA,CAAK,IAAA,CAAK,MAAM,OAAA,GAAU,OAAA;AAC1B,QAAA,IAAA,CAAK,IAAA,CAAK,KAAA,CAAM,GAAA,GAAM,CAAA,EAAG,UAAU,CAAA,CAAA,CAAA;AAAA,MACrC;AACA,MAAA;AAAA,IACF;AAEA,IAAA,IAAA,CAAK,UAAA,CAAW,MAAM,OAAA,GAAU,MAAA;AAChC,IAAA,IAAA,CAAK,UAAA,CAAW,MAAM,OAAA,GAAU,MAAA;AAChC,IAAA,IAAA,CAAK,kBAAA,CAAmB,MAAM,OAAA,GAAU,MAAA;AACxC,IAAA,IAAA,CAAK,aAAA,CAAc,MAAM,OAAA,GAAU,MAAA;AAEnC,IAAA,IAAI,KAAA,CAAM,UAAU,QAAA,EAAU;AAC5B,MAAA,IAAA,CAAK,IAAA,CAAK,MAAM,OAAA,GAAU,OAAA;AAC1B,MAAA,IAAA,CAAK,IAAA,CAAK,KAAA,CAAM,IAAA,GAAO,CAAA,EAAG,MAAM,IAAI,CAAA,CAAA,CAAA;AACpC,MAAA,IAAA,CAAK,IAAA,CAAK,MAAM,OAAA,GAAU,MAAA;AAAA,IAC5B,CAAA,MAAA,IAAW,KAAA,CAAM,KAAA,KAAU,QAAA,EAAU;AACnC,MAAA,IAAA,CAAK,IAAA,CAAK,MAAM,OAAA,GAAU,OAAA;AAC1B,MAAA,IAAA,CAAK,IAAA,CAAK,KAAA,CAAM,IAAA,GAAO,CAAA,EAAG,MAAM,IAAI,CAAA,CAAA,CAAA;AACpC,MAAA,IAAA,CAAK,IAAA,CAAK,MAAM,OAAA,GAAU,OAAA;AAC1B,MAAA,IAAA,CAAK,IAAA,CAAK,KAAA,CAAM,GAAA,GAAM,CAAA,EAAG,MAAM,IAAI,CAAA,CAAA,CAAA;AAAA,IACrC;AAAA,EACF;AAAA,EAEQ,mBAAA,CAAoB,CAAA,EAAW,CAAA,EAAW,EAAA,EAAY,EAAA,EAAoB;AAChF,IAAA,IAAI,EAAA,KAAO,CAAA,IAAK,EAAA,KAAO,EAAA,EAAI;AACzB,MAAA,OAAO,CAAA;AAAA,IACT,CAAA,MAAA,IAAW,EAAA,KAAO,CAAA,IAAK,EAAA,KAAO,EAAA,EAAI;AAChC,MAAA,OAAO,KAAK,GAAA,CAAI,GAAA,GAAM,CAAA,EAAG,CAAC,IAAI,IAAA,CAAK,KAAA;AAAA,IACrC,CAAA,MAAA,IAAW,EAAA,KAAO,CAAA,IAAK,EAAA,KAAO,CAAA,EAAG;AAC/B,MAAA,OAAO,GAAA,GAAM,CAAA;AAAA,IACf,CAAA,MAAA,IAAW,EAAA,KAAO,CAAA,IAAK,EAAA,KAAO,CAAA,EAAG;AAC/B,MAAA,OAAO,KAAK,GAAA,CAAI,GAAA,GAAM,GAAG,GAAA,GAAM,CAAC,IAAI,IAAA,CAAK,KAAA;AAAA,IAC3C,CAAA,MAAA,IAAW,EAAA,KAAO,CAAA,IAAK,EAAA,KAAO,CAAA,EAAG;AAC/B,MAAA,OAAO,GAAA,GAAM,CAAA;AAAA,IACf,CAAA,MAAA,IAAW,EAAA,KAAO,EAAA,IAAM,EAAA,KAAO,CAAA,EAAG;AAChC,MAAA,OAAO,KAAK,GAAA,CAAI,CAAA,EAAG,GAAA,GAAM,CAAC,IAAI,IAAA,CAAK,KAAA;AAAA,IACrC,CAAA,MAAA,IAAW,EAAA,KAAO,EAAA,IAAM,EAAA,KAAO,CAAA,EAAG;AAChC,MAAA,OAAO,CAAA;AAAA,IACT,CAAA,MAAA,IAAW,EAAA,KAAO,EAAA,IAAM,EAAA,KAAO,EAAA,EAAI;AACjC,MAAA,OAAO,IAAA,CAAK,GAAA,CAAI,CAAA,EAAG,CAAC,IAAI,IAAA,CAAK,KAAA;AAAA,IAC/B;AACA,IAAA,OAAO,EAAA;AAAA,EACT;AACF;AAEO,SAAS,mBAAA,CAAoB,SAAA,EAAwB,QAAA,EAAkB,QAAA,EAAiC;AAC7G,EAAA,MAAM,IAAA,GAAO,UAAU,qBAAA,EAAsB;AAC7C,EAAA,MAAM,OAAA,GAAU,IAAA,CAAK,IAAA,GAAQ,QAAA,GAAW,MAAO,IAAA,CAAK,KAAA;AACpD,EAAA,MAAM,OAAA,GAAU,IAAA,CAAK,GAAA,GAAO,QAAA,GAAW,MAAO,IAAA,CAAK,MAAA;AACnD,EAAA,MAAM,IAAA,GAAO,UAAU,WAAA,EAAY;AACnC,EAAA,MAAM,OAAA,GAAU,IAAA,CAAK,gBAAA,GAAmB,IAAA,CAAK,gBAAA,CAAiB,OAAA,EAAS,OAAO,CAAA,GAAI,QAAA,CAAS,gBAAA,CAAiB,OAAA,EAAS,OAAO,CAAA;AAC5H,EAAA,IAAI,CAAC,SAAS,OAAO,IAAA;AACrB,EAAA,MAAM,QAAA,GAAY,OAAA,CAAwB,OAAA,CAAQ,YAAY,CAAA;AAC9D,EAAA,IAAI,CAAC,QAAA,IAAY,CAAC,QAAA,CAAS,OAAA,CAAQ,OAAO,OAAO,IAAA;AACjD,EAAA,MAAM,KAAA,GAAQ,QAAA,CAAS,QAAA,CAAS,OAAA,CAAQ,OAAO,EAAE,CAAA;AACjD,EAAA,OAAO,MAAA,CAAO,KAAA,CAAM,KAAK,CAAA,GAAI,IAAA,GAAO,KAAA;AACtC","file":"index.js","sourcesContent":["import type { ContinuousUpdate } from 'scan-engine';\n\nexport class ContinuousOverlay {\n private overlay: HTMLElement;\n private hBar: HTMLElement;\n private vBar: HTMLElement;\n private bufferZone: HTMLElement;\n private lockedXBar: HTMLElement;\n private directionIndicator: HTMLElement;\n private directionLine: HTMLElement;\n\n constructor(private container: HTMLElement) {\n this.overlay = document.createElement('div');\n this.overlay.style.position = 'absolute';\n this.overlay.style.top = '0';\n this.overlay.style.left = '0';\n this.overlay.style.width = '100%';\n this.overlay.style.height = '100%';\n this.overlay.style.pointerEvents = 'none';\n this.overlay.style.zIndex = '1000';\n\n this.bufferZone = document.createElement('div');\n this.bufferZone.style.position = 'absolute';\n this.bufferZone.style.top = '0';\n this.bufferZone.style.height = '100%';\n this.bufferZone.style.backgroundColor = 'rgba(128, 128, 128, 0.4)';\n this.bufferZone.style.borderLeft = '2px solid rgba(128, 128, 128, 0.8)';\n this.bufferZone.style.borderRight = '2px solid rgba(128, 128, 128, 0.8)';\n this.bufferZone.style.pointerEvents = 'none';\n this.bufferZone.style.display = 'none';\n this.overlay.appendChild(this.bufferZone);\n\n this.vBar = document.createElement('div');\n this.vBar.style.position = 'absolute';\n this.vBar.style.top = '0';\n this.vBar.style.width = '4px';\n this.vBar.style.height = '100%';\n this.vBar.style.backgroundColor = 'rgba(255, 0, 0, 0.5)';\n this.vBar.style.borderLeft = '1px solid red';\n this.vBar.style.borderRight = '1px solid red';\n this.vBar.style.display = 'none';\n this.overlay.appendChild(this.vBar);\n\n this.hBar = document.createElement('div');\n this.hBar.style.position = 'absolute';\n this.hBar.style.left = '0';\n this.hBar.style.width = '100%';\n this.hBar.style.height = '4px';\n this.hBar.style.backgroundColor = 'rgba(255, 0, 0, 0.5)';\n this.hBar.style.borderTop = '1px solid red';\n this.hBar.style.borderBottom = '1px solid red';\n this.hBar.style.display = 'none';\n this.overlay.appendChild(this.hBar);\n\n this.lockedXBar = document.createElement('div');\n this.lockedXBar.style.position = 'absolute';\n this.lockedXBar.style.top = '0';\n this.lockedXBar.style.width = '3px';\n this.lockedXBar.style.height = '100%';\n this.lockedXBar.style.backgroundColor = 'rgba(0, 255, 0, 0.7)';\n this.lockedXBar.style.borderLeft = '1px solid green';\n this.lockedXBar.style.borderRight = '1px solid green';\n this.lockedXBar.style.display = 'none';\n this.overlay.appendChild(this.lockedXBar);\n\n this.directionIndicator = document.createElement('div');\n this.directionIndicator.style.position = 'absolute';\n this.directionIndicator.style.top = '10px';\n this.directionIndicator.style.right = '10px';\n this.directionIndicator.style.width = '80px';\n this.directionIndicator.style.height = '80px';\n this.directionIndicator.style.borderRadius = '50%';\n this.directionIndicator.style.backgroundColor = 'rgba(255, 255, 255, 0.9)';\n this.directionIndicator.style.border = '3px solid #333';\n this.directionIndicator.style.display = 'none';\n this.directionIndicator.style.pointerEvents = 'none';\n this.overlay.appendChild(this.directionIndicator);\n\n this.directionLine = document.createElement('div');\n this.directionLine.style.position = 'absolute';\n this.directionLine.style.height = '2px';\n this.directionLine.style.backgroundColor = 'rgba(33, 150, 243, 0.6)';\n this.directionLine.style.transformOrigin = '0 50%';\n this.directionLine.style.display = 'none';\n this.directionLine.style.pointerEvents = 'none';\n this.directionLine.style.zIndex = '5';\n this.overlay.appendChild(this.directionLine);\n\n this.container.appendChild(this.overlay);\n }\n\n destroy() {\n if (this.overlay.parentNode) {\n this.overlay.parentNode.removeChild(this.overlay);\n }\n }\n\n update(state: ContinuousUpdate) {\n if (state.technique === 'eight-direction') {\n this.vBar.style.display = 'none';\n this.hBar.style.display = 'none';\n this.bufferZone.style.display = 'none';\n this.lockedXBar.style.display = 'none';\n\n this.directionIndicator.style.display = 'block';\n this.directionLine.style.display = 'block';\n\n const angle = state.compassAngle;\n\n this.directionIndicator.innerHTML = `\n <div style=\"\n position: absolute;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%) rotate(${angle}deg);\n font-size: 24px;\n font-weight: bold;\n color: #2196F3;\n \">↑</div>\n <div style=\"\n position: absolute;\n top: 5px;\n left: 50%;\n transform: translateX(-50%);\n font-size: 12px;\n font-weight: bold;\n \">N</div>\n <div style=\"\n position: absolute;\n bottom: 5px;\n left: 50%;\n transform: translateX(-50%);\n font-size: 12px;\n font-weight: bold;\n \">S</div>\n <div style=\"\n position: absolute;\n left: 5px;\n top: 50%;\n transform: translateY(-50%);\n font-size: 12px;\n font-weight: bold;\n \">W</div>\n <div style=\"\n position: absolute;\n right: 5px;\n top: 50%;\n transform: translateY(-50%);\n font-size: 12px;\n font-weight: bold;\n \">E</div>\n <div style=\"\n position: absolute;\n bottom: 20px;\n left: 50%;\n transform: translateX(-50%);\n font-size: 10px;\n color: #666;\n \">${state.directionName} (${Math.round(angle)}°)</div>\n `;\n\n this.directionLine.style.left = `${state.xPos}%`;\n this.directionLine.style.top = `${state.yPos}%`;\n const lineLength = this.calculateLineLength(state.xPos, state.yPos, state.directionDx, state.directionDy);\n this.directionLine.style.width = `${lineLength}%`;\n this.directionLine.style.transformOrigin = '0 50%';\n this.directionLine.style.transform = `rotate(${angle}deg)`;\n\n this.vBar.style.display = 'block';\n this.vBar.style.width = '12px';\n this.vBar.style.height = '12px';\n this.vBar.style.borderRadius = '50%';\n this.vBar.style.backgroundColor = state.state === 'moving' ? '#FF5722' : '#2196F3';\n this.vBar.style.border = '2px solid white';\n this.vBar.style.zIndex = '10';\n this.vBar.style.left = `calc(${state.xPos}% - 6px)`;\n this.vBar.style.top = `calc(${state.yPos}% - 6px)`;\n return;\n }\n\n if (state.technique === 'gliding') {\n if (state.state === 'x-scanning') {\n this.vBar.style.display = 'none';\n this.hBar.style.display = 'none';\n this.lockedXBar.style.display = 'none';\n this.directionIndicator.style.display = 'none';\n this.directionLine.style.display = 'none';\n\n const actualWidth = state.bufferRight - state.bufferLeft;\n\n this.bufferZone.style.left = `${state.bufferLeft}%`;\n this.bufferZone.style.width = `${actualWidth}%`;\n this.bufferZone.style.height = '100%';\n this.bufferZone.style.top = '0';\n this.bufferZone.style.display = 'block';\n } else if (state.state === 'x-capturing') {\n this.hBar.style.display = 'none';\n this.lockedXBar.style.display = 'none';\n this.directionIndicator.style.display = 'none';\n this.directionLine.style.display = 'none';\n\n const actualWidth = state.bufferRight - state.bufferLeft;\n this.bufferZone.style.left = `${state.bufferLeft}%`;\n this.bufferZone.style.width = `${actualWidth}%`;\n this.bufferZone.style.height = '100%';\n this.bufferZone.style.top = '0';\n this.bufferZone.style.display = 'block';\n\n const actualXPos = state.bufferLeft + (state.fineXPos / 100) * (state.bufferRight - state.bufferLeft);\n this.vBar.style.display = 'block';\n this.vBar.style.left = `${actualXPos}%`;\n } else if (state.state === 'y-scanning') {\n this.vBar.style.display = 'none';\n this.hBar.style.display = 'none';\n this.directionIndicator.style.display = 'none';\n this.directionLine.style.display = 'none';\n\n this.lockedXBar.style.display = 'block';\n this.lockedXBar.style.left = `${state.lockedXPosition}%`;\n\n const actualHeight = state.bufferBottom - state.bufferTop;\n\n this.bufferZone.style.left = '0';\n this.bufferZone.style.width = '100%';\n this.bufferZone.style.top = `${state.bufferTop}%`;\n this.bufferZone.style.height = `${actualHeight}%`;\n this.bufferZone.style.display = 'block';\n } else if (state.state === 'y-capturing') {\n this.vBar.style.display = 'none';\n this.directionIndicator.style.display = 'none';\n this.directionLine.style.display = 'none';\n\n this.lockedXBar.style.display = 'block';\n this.lockedXBar.style.left = `${state.lockedXPosition}%`;\n\n const actualHeight = state.bufferBottom - state.bufferTop;\n this.bufferZone.style.left = '0';\n this.bufferZone.style.width = '100%';\n this.bufferZone.style.top = `${state.bufferTop}%`;\n this.bufferZone.style.height = `${actualHeight}%`;\n this.bufferZone.style.display = 'block';\n\n const actualYPos = state.bufferTop + (state.fineYPos / 100) * (state.bufferBottom - state.bufferTop);\n this.hBar.style.display = 'block';\n this.hBar.style.top = `${actualYPos}%`;\n }\n return;\n }\n\n this.bufferZone.style.display = 'none';\n this.lockedXBar.style.display = 'none';\n this.directionIndicator.style.display = 'none';\n this.directionLine.style.display = 'none';\n\n if (state.state === 'x-scan') {\n this.vBar.style.display = 'block';\n this.vBar.style.left = `${state.xPos}%`;\n this.hBar.style.display = 'none';\n } else if (state.state === 'y-scan') {\n this.vBar.style.display = 'block';\n this.vBar.style.left = `${state.xPos}%`;\n this.hBar.style.display = 'block';\n this.hBar.style.top = `${state.yPos}%`;\n }\n }\n\n private calculateLineLength(x: number, y: number, dx: number, dy: number): number {\n if (dx === 0 && dy === -1) {\n return y;\n } else if (dx === 1 && dy === -1) {\n return Math.min(100 - x, y) * Math.SQRT2;\n } else if (dx === 1 && dy === 0) {\n return 100 - x;\n } else if (dx === 1 && dy === 1) {\n return Math.min(100 - x, 100 - y) * Math.SQRT2;\n } else if (dx === 0 && dy === 1) {\n return 100 - y;\n } else if (dx === -1 && dy === 1) {\n return Math.min(x, 100 - y) * Math.SQRT2;\n } else if (dx === -1 && dy === 0) {\n return x;\n } else if (dx === -1 && dy === -1) {\n return Math.min(x, y) * Math.SQRT2;\n }\n return 50;\n }\n}\n\nexport function resolveIndexAtPoint(container: HTMLElement, xPercent: number, yPercent: number): number | null {\n const rect = container.getBoundingClientRect();\n const clientX = rect.left + (xPercent / 100) * rect.width;\n const clientY = rect.top + (yPercent / 100) * rect.height;\n const root = container.getRootNode() as Document | ShadowRoot;\n const element = root.elementFromPoint ? root.elementFromPoint(clientX, clientY) : document.elementFromPoint(clientX, clientY);\n if (!element) return null;\n const gridCell = (element as HTMLElement).closest('.grid-cell') as HTMLElement | null;\n if (!gridCell || !gridCell.dataset.index) return null;\n const index = parseInt(gridCell.dataset.index, 10);\n return Number.isNaN(index) ? null : index;\n}\n"]}
package/package.json ADDED
@@ -0,0 +1,26 @@
1
+ {
2
+ "name": "scan-engine-dom",
3
+ "version": "0.1.0",
4
+ "description": "DOM helpers for scan-engine (continuous scan overlays and hit-testing).",
5
+ "type": "module",
6
+ "main": "dist/index.cjs",
7
+ "module": "dist/index.js",
8
+ "types": "dist/index.d.ts",
9
+ "exports": {
10
+ ".": {
11
+ "types": "./dist/index.d.ts",
12
+ "import": "./dist/index.js",
13
+ "require": "./dist/index.cjs"
14
+ }
15
+ },
16
+ "files": [
17
+ "dist"
18
+ ],
19
+ "sideEffects": false,
20
+ "scripts": {
21
+ "build": "tsup"
22
+ },
23
+ "dependencies": {
24
+ "scan-engine": "^0.1.0"
25
+ }
26
+ }