@getsigil/core 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/dist/sigil.cjs ADDED
@@ -0,0 +1,549 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/sigil.ts
21
+ var sigil_exports = {};
22
+ __export(sigil_exports, {
23
+ Sigil: () => sigil,
24
+ default: () => sigil_default
25
+ });
26
+ module.exports = __toCommonJS(sigil_exports);
27
+ var HEX_COLORS = [
28
+ "#FF0000",
29
+ "#FFFF00",
30
+ "#00FF00",
31
+ "#00FFFF",
32
+ "#0000FF",
33
+ "#FF00FF",
34
+ "#FFFFFF",
35
+ "#000000"
36
+ ];
37
+ var NO_CHILD_ELEMENTS = [
38
+ "INPUT",
39
+ "TEXTAREA",
40
+ "SELECT",
41
+ "IMG",
42
+ "BR",
43
+ "HR",
44
+ "META",
45
+ "LINK",
46
+ "AREA",
47
+ "BASE",
48
+ "COL",
49
+ "EMBED",
50
+ "PARAM",
51
+ "SOURCE",
52
+ "TRACK",
53
+ "WBR"
54
+ ];
55
+ var SigilCore = class {
56
+ constructor() {
57
+ this.config = {
58
+ enabled: true,
59
+ position: "center",
60
+ zIndex: 9999,
61
+ opacity: 1,
62
+ wsPort: 5050
63
+ };
64
+ this.observer = null;
65
+ this.wsConnection = null;
66
+ this.wsReconnectTimer = null;
67
+ this.markedElements = /* @__PURE__ */ new WeakSet();
68
+ this.initialized = false;
69
+ }
70
+ /**
71
+ * Initialize Sigil with configuration
72
+ */
73
+ init(options = {}) {
74
+ if (typeof window !== "undefined") {
75
+ const urlParams = new URLSearchParams(window.location.search);
76
+ const urlWsPort = urlParams.get("sigilWsPort");
77
+ if (urlWsPort) {
78
+ options.wsPort = parseInt(urlWsPort, 10);
79
+ options.opacity = options.opacity ?? 1;
80
+ }
81
+ }
82
+ this.config = { ...this.config, ...options };
83
+ if (!this.config.enabled) return;
84
+ this.injectStyles();
85
+ this.scan();
86
+ this.startObserver();
87
+ this.connectWebSocket();
88
+ this.initialized = true;
89
+ }
90
+ /**
91
+ * Update configuration
92
+ */
93
+ configure(options) {
94
+ this.config = { ...this.config, ...options };
95
+ if (!this.config.enabled) {
96
+ this.stopObserver();
97
+ this.removeAllMarkers();
98
+ } else {
99
+ this.scan();
100
+ this.startObserver();
101
+ }
102
+ }
103
+ /**
104
+ * Scan DOM and add markers to elements with data-sigil-id
105
+ */
106
+ scan(root = document) {
107
+ if (!this.config.enabled) return;
108
+ const elements = root.querySelectorAll("[data-sigil-id]");
109
+ elements.forEach((el) => this.addMarker(el));
110
+ }
111
+ /**
112
+ * Auto-discover interactive elements and add data-sigil-id attributes
113
+ */
114
+ autoDiscover() {
115
+ const selectors = [
116
+ "button",
117
+ "a[href]",
118
+ 'input:not([type="hidden"])',
119
+ "textarea",
120
+ "select",
121
+ '[role="button"]',
122
+ '[role="checkbox"]',
123
+ '[role="textbox"]',
124
+ '[role="combobox"]',
125
+ '[role="switch"]'
126
+ ];
127
+ const allElements = [];
128
+ selectors.forEach((sel) => {
129
+ try {
130
+ document.querySelectorAll(sel).forEach((el) => allElements.push(el));
131
+ } catch {
132
+ }
133
+ });
134
+ const uniqueElements = [...new Set(allElements)].filter((el) => !el.hasAttribute("data-sigil-id"));
135
+ const usedIds = /* @__PURE__ */ new Set();
136
+ document.querySelectorAll("[data-sigil-id]").forEach((el) => {
137
+ usedIds.add(el.getAttribute("data-sigil-id"));
138
+ });
139
+ let counter = 0;
140
+ uniqueElements.forEach((el) => {
141
+ const id = this.generateElementId(el, counter++, usedIds);
142
+ if (id) {
143
+ el.setAttribute("data-sigil-id", id);
144
+ usedIds.add(id);
145
+ }
146
+ });
147
+ console.log(`Sigil: Auto-discovered ${counter} interactive elements`);
148
+ this.scan();
149
+ }
150
+ /**
151
+ * Show all markers
152
+ */
153
+ show() {
154
+ document.querySelectorAll(".sigil-marker").forEach((m) => {
155
+ m.style.opacity = "1";
156
+ });
157
+ }
158
+ /**
159
+ * Hide all markers
160
+ */
161
+ hide() {
162
+ document.querySelectorAll(".sigil-marker").forEach((m) => {
163
+ m.style.opacity = "0";
164
+ });
165
+ }
166
+ /**
167
+ * Clean up and remove all markers
168
+ */
169
+ dispose() {
170
+ this.stopObserver();
171
+ if (this.wsConnection) {
172
+ this.wsConnection.close();
173
+ this.wsConnection = null;
174
+ }
175
+ if (this.wsReconnectTimer) {
176
+ clearInterval(this.wsReconnectTimer);
177
+ this.wsReconnectTimer = null;
178
+ }
179
+ this.removeAllMarkers();
180
+ this.initialized = false;
181
+ }
182
+ /**
183
+ * Check if Sigil is enabled
184
+ */
185
+ isEnabled() {
186
+ return this.config.enabled;
187
+ }
188
+ // ========== Private Methods ==========
189
+ injectStyles() {
190
+ if (document.getElementById("sigil-styles")) return;
191
+ const style = document.createElement("style");
192
+ style.id = "sigil-styles";
193
+ style.textContent = `
194
+ .mud-dialog, .mud-dialog-content, .mud-dialog-actions,
195
+ .modal-content, .modal-body, .modal-footer, .modal-header,
196
+ .rz-dialog, .rz-dialog-content,
197
+ [class*="dialog-content"], [class*="modal-content"], [class*="popup-content"] {
198
+ overflow: visible !important;
199
+ }
200
+ `;
201
+ document.head.appendChild(style);
202
+ }
203
+ async addMarker(element) {
204
+ if (this.markedElements.has(element)) return;
205
+ if (!this.config.enabled) return;
206
+ const markerId = element.getAttribute("data-sigil-id");
207
+ if (!markerId) return;
208
+ this.markedElements.add(element);
209
+ const encoding = await this.encode(markerId);
210
+ const svgContent = this.createMarkerSvg(encoding);
211
+ const marker = document.createElement("div");
212
+ marker.className = "sigil-marker";
213
+ marker.innerHTML = svgContent;
214
+ marker.setAttribute("data-sigil-for", markerId);
215
+ const canHaveChildren = !NO_CHILD_ELEMENTS.includes(element.tagName);
216
+ if (canHaveChildren) {
217
+ const computedStyle = window.getComputedStyle(element);
218
+ if (computedStyle.position === "static") {
219
+ element.style.position = "relative";
220
+ }
221
+ element.style.overflow = "visible";
222
+ const pos = this.getPositionStyles();
223
+ Object.assign(marker.style, {
224
+ position: "absolute",
225
+ ...pos,
226
+ zIndex: this.config.zIndex.toString(),
227
+ opacity: this.config.opacity.toString(),
228
+ pointerEvents: "none",
229
+ lineHeight: "0"
230
+ });
231
+ element.appendChild(marker);
232
+ } else {
233
+ const updatePosition = () => {
234
+ const rect = element.getBoundingClientRect();
235
+ Object.assign(marker.style, {
236
+ position: "fixed",
237
+ top: rect.top + rect.height / 2 - 8 + "px",
238
+ left: rect.left + rect.width / 2 - 8 + "px",
239
+ zIndex: this.config.zIndex.toString(),
240
+ opacity: this.config.opacity.toString(),
241
+ pointerEvents: "none",
242
+ lineHeight: "0"
243
+ });
244
+ };
245
+ updatePosition();
246
+ document.body.appendChild(marker);
247
+ window.addEventListener("scroll", updatePosition, { passive: true });
248
+ window.addEventListener("resize", updatePosition, { passive: true });
249
+ }
250
+ }
251
+ getPositionStyles() {
252
+ const positions = {
253
+ "center": { top: "50%", left: "50%", transform: "translate(-50%, -50%)" },
254
+ "top-left": { top: "0", left: "0" },
255
+ "top-right": { top: "0", right: "0" },
256
+ "bottom-left": { bottom: "0", left: "0" },
257
+ "bottom-right": { bottom: "0", right: "0" }
258
+ };
259
+ return positions[this.config.position] || positions["center"];
260
+ }
261
+ async encode(markerId) {
262
+ const hash = await this.sha256(markerId);
263
+ const borderColor = hash[0] & 7;
264
+ const cellColors = [];
265
+ for (let i = 0; i < 9; i++) {
266
+ const byteIndex = 1 + Math.floor(i * 3 / 8);
267
+ const bitOffset = i * 3 % 8;
268
+ let value;
269
+ if (bitOffset <= 5) {
270
+ value = hash[byteIndex] >> bitOffset & 7;
271
+ } else {
272
+ value = (hash[byteIndex] >> bitOffset | hash[byteIndex + 1] << 8 - bitOffset) & 7;
273
+ }
274
+ cellColors.push(value);
275
+ }
276
+ return { borderColor, cellColors };
277
+ }
278
+ async sha256(message) {
279
+ const msgBuffer = new TextEncoder().encode(message);
280
+ const hashBuffer = await crypto.subtle.digest("SHA-256", msgBuffer);
281
+ return new Uint8Array(hashBuffer);
282
+ }
283
+ createMarkerSvg(encoding) {
284
+ const borderHex = HEX_COLORS[encoding.borderColor];
285
+ let svg = `<svg width="16" height="16" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg" style="image-rendering: pixelated; shape-rendering: crispEdges;">`;
286
+ svg += `<rect x="0" y="0" width="1" height="1" fill="#FF00FF"/>`;
287
+ svg += `<rect x="1" y="0" width="1" height="1" fill="#00FFFF"/>`;
288
+ svg += `<rect x="0" y="1" width="1" height="1" fill="#00FFFF"/>`;
289
+ svg += `<rect x="1" y="1" width="1" height="1" fill="#FF00FF"/>`;
290
+ svg += `<rect x="2" y="0" width="14" height="2" fill="${borderHex}"/>`;
291
+ svg += `<rect x="0" y="2" width="2" height="12" fill="${borderHex}"/>`;
292
+ svg += `<rect x="14" y="2" width="2" height="12" fill="${borderHex}"/>`;
293
+ svg += `<rect x="0" y="14" width="16" height="2" fill="${borderHex}"/>`;
294
+ for (let row = 0; row < 3; row++) {
295
+ for (let col = 0; col < 3; col++) {
296
+ const idx = row * 3 + col;
297
+ const x = 2 + col * 4;
298
+ const y = 2 + row * 4;
299
+ const cellHex = HEX_COLORS[encoding.cellColors[idx]];
300
+ svg += `<rect x="${x}" y="${y}" width="4" height="4" fill="${cellHex}"/>`;
301
+ }
302
+ }
303
+ svg += `</svg>`;
304
+ return svg;
305
+ }
306
+ generateElementId(el, index, usedIds) {
307
+ const tag = el.tagName.toLowerCase();
308
+ const isFormElement = ["input", "textarea", "select", "button"].includes(tag);
309
+ const sanitize = (str) => str.toLowerCase().replace(/\s+/g, "-").replace(/[^a-z0-9-]/g, "").slice(0, 30);
310
+ if (isFormElement) {
311
+ let id2 = el.id;
312
+ if (id2) {
313
+ id2 = sanitize(id2);
314
+ if (!usedIds.has(id2)) return id2;
315
+ id2 = `${tag}-${id2}`;
316
+ if (!usedIds.has(id2)) return id2;
317
+ }
318
+ id2 = el.getAttribute("name") || "";
319
+ if (id2) {
320
+ id2 = sanitize(id2);
321
+ if (!usedIds.has(id2)) return id2;
322
+ id2 = `${tag}-${id2}`;
323
+ if (!usedIds.has(id2)) return id2;
324
+ }
325
+ id2 = el.getAttribute("aria-label") || "";
326
+ if (id2) {
327
+ id2 = sanitize(id2);
328
+ if (!usedIds.has(id2)) return id2;
329
+ }
330
+ id2 = el.getAttribute("placeholder") || "";
331
+ if (id2) {
332
+ id2 = sanitize(id2);
333
+ if (!usedIds.has(id2)) return id2;
334
+ }
335
+ } else {
336
+ let id2 = el.getAttribute("aria-label") || "";
337
+ if (id2) {
338
+ id2 = sanitize(id2);
339
+ if (!usedIds.has(id2)) return id2;
340
+ }
341
+ const text = el.textContent?.trim() || "";
342
+ if (text && text.length <= 30) {
343
+ id2 = sanitize(text);
344
+ if (!usedIds.has(id2)) return id2;
345
+ }
346
+ if (tag === "a") {
347
+ const href = el.getAttribute("href") || "";
348
+ if (href && href !== "#") {
349
+ id2 = sanitize(href.replace(/^[#/]+/, ""));
350
+ if (id2 && !usedIds.has(id2)) return id2;
351
+ }
352
+ }
353
+ }
354
+ let id = `${tag}-${index}`;
355
+ while (usedIds.has(id)) {
356
+ id = `${tag}-${++index}`;
357
+ }
358
+ return id;
359
+ }
360
+ startObserver() {
361
+ if (this.observer) return;
362
+ this.observer = new MutationObserver((mutations) => {
363
+ mutations.forEach((mutation) => {
364
+ mutation.addedNodes.forEach((node) => {
365
+ if (node.nodeType === Node.ELEMENT_NODE) {
366
+ const el = node;
367
+ if (el.hasAttribute?.("data-sigil-id")) {
368
+ this.addMarker(el);
369
+ }
370
+ this.scan(el);
371
+ }
372
+ });
373
+ });
374
+ });
375
+ this.observer.observe(document.body, {
376
+ childList: true,
377
+ subtree: true
378
+ });
379
+ }
380
+ stopObserver() {
381
+ if (this.observer) {
382
+ this.observer.disconnect();
383
+ this.observer = null;
384
+ }
385
+ }
386
+ removeAllMarkers() {
387
+ document.querySelectorAll(".sigil-marker").forEach((m) => m.remove());
388
+ }
389
+ connectWebSocket() {
390
+ if (typeof WebSocket === "undefined") return;
391
+ if (this.wsConnection?.readyState === WebSocket.OPEN) return;
392
+ try {
393
+ this.wsConnection = new WebSocket(`ws://127.0.0.1:${this.config.wsPort}`);
394
+ this.wsConnection.onopen = () => {
395
+ console.log("Sigil: Connected to executor");
396
+ if (this.wsReconnectTimer) {
397
+ clearInterval(this.wsReconnectTimer);
398
+ this.wsReconnectTimer = null;
399
+ }
400
+ };
401
+ this.wsConnection.onmessage = (event) => {
402
+ this.handleWebSocketMessage(event.data);
403
+ };
404
+ this.wsConnection.onclose = () => {
405
+ if (!this.wsReconnectTimer) {
406
+ this.wsReconnectTimer = setInterval(() => this.connectWebSocket(), 2e3);
407
+ }
408
+ };
409
+ this.wsConnection.onerror = () => {
410
+ };
411
+ } catch {
412
+ }
413
+ }
414
+ handleWebSocketMessage(data) {
415
+ const cmd = data.trim();
416
+ const cmdLower = cmd.toLowerCase();
417
+ if (cmdLower === "show") {
418
+ this.show();
419
+ } else if (cmdLower === "hide") {
420
+ this.hide();
421
+ } else if (cmdLower.startsWith("search:")) {
422
+ const markerId = cmd.substring(7);
423
+ const result = this.searchForMarker(markerId);
424
+ this.sendResult(result);
425
+ } else if (cmdLower.startsWith("scrollto:")) {
426
+ const markerId = cmd.substring(9);
427
+ this.scrollToMarker(markerId);
428
+ } else if (cmdLower.startsWith("read:text:")) {
429
+ const markerId = cmd.substring(10);
430
+ const result = this.readTextContent(markerId);
431
+ this.sendResult(result);
432
+ } else if (cmdLower.startsWith("read:value:")) {
433
+ const markerId = cmd.substring(11);
434
+ const result = this.readInputValue(markerId);
435
+ this.sendResult(result);
436
+ } else if (cmdLower.startsWith("select:")) {
437
+ const parts = cmd.substring(7).split(":");
438
+ const markerId = parts[0];
439
+ const optionValue = parts.slice(1).join(":");
440
+ Promise.resolve(this.selectOption(markerId, optionValue)).then((result) => {
441
+ this.sendResult(result);
442
+ });
443
+ } else if (cmdLower.startsWith("check:")) {
444
+ const markerId = cmd.substring(6);
445
+ const result = this.setCheckboxState(markerId, true);
446
+ this.sendResult(result);
447
+ } else if (cmdLower.startsWith("uncheck:")) {
448
+ const markerId = cmd.substring(8);
449
+ const result = this.setCheckboxState(markerId, false);
450
+ this.sendResult(result);
451
+ }
452
+ }
453
+ searchForMarker(markerId) {
454
+ const element = document.querySelector(`[data-sigil-id="${markerId}"]`);
455
+ if (!element) {
456
+ return { found: false, visible: false, markerId };
457
+ }
458
+ const rect = element.getBoundingClientRect();
459
+ const viewportHeight = window.innerHeight;
460
+ const viewportWidth = window.innerWidth;
461
+ const markerBottom = rect.bottom + 16;
462
+ const inViewport = rect.bottom > 0 && markerBottom < viewportHeight && rect.left < viewportWidth && rect.right > 0;
463
+ return {
464
+ found: true,
465
+ visible: inViewport,
466
+ markerId,
467
+ direction: inViewport ? null : this.getDirection(rect, viewportWidth, viewportHeight),
468
+ offsetX: 0,
469
+ offsetY: 0
470
+ };
471
+ }
472
+ getDirection(rect, vw, vh) {
473
+ let dir = "";
474
+ if (rect.bottom < 0) dir = "up";
475
+ else if (rect.bottom + 16 > vh) dir = "down";
476
+ if (rect.right < 0) dir += dir ? "-left" : "left";
477
+ else if (rect.left > vw) dir += dir ? "-right" : "right";
478
+ return dir || "down";
479
+ }
480
+ scrollToMarker(markerId) {
481
+ const element = document.querySelector(`[data-sigil-id="${markerId}"]`);
482
+ if (element) {
483
+ element.scrollIntoView({ behavior: "instant", block: "center" });
484
+ }
485
+ }
486
+ readTextContent(markerId) {
487
+ const element = document.querySelector(`[data-sigil-id="${markerId}"]`);
488
+ if (!element) return { success: false, value: "", error: "Element not found" };
489
+ return { success: true, value: element.textContent?.trim() || "" };
490
+ }
491
+ readInputValue(markerId) {
492
+ const element = document.querySelector(`[data-sigil-id="${markerId}"]`);
493
+ if (!element) return { success: false, value: "", error: "Element not found" };
494
+ const input = element.querySelector("input, textarea, select") || element;
495
+ return { success: true, value: input.value || "" };
496
+ }
497
+ selectOption(markerId, optionValue) {
498
+ const element = document.querySelector(`[data-sigil-id="${markerId}"]`);
499
+ if (!element) return { success: false, error: "Element not found" };
500
+ const select = element.querySelector("select") || element;
501
+ if (select.tagName === "SELECT") {
502
+ const option = Array.from(select.options).find(
503
+ (opt) => opt.value === optionValue || opt.text.trim() === optionValue
504
+ );
505
+ if (option) {
506
+ select.value = option.value;
507
+ select.dispatchEvent(new Event("change", { bubbles: true }));
508
+ return { success: true };
509
+ }
510
+ }
511
+ element.click();
512
+ return new Promise((resolve) => {
513
+ setTimeout(() => {
514
+ const options = document.querySelectorAll('[role="option"], .dropdown-item, li');
515
+ for (const opt of options) {
516
+ if (opt.textContent?.trim() === optionValue) {
517
+ opt.click();
518
+ resolve({ success: true });
519
+ return;
520
+ }
521
+ }
522
+ resolve({ success: false, error: "Option not found" });
523
+ }, 200);
524
+ });
525
+ }
526
+ setCheckboxState(markerId, shouldCheck) {
527
+ const element = document.querySelector(`[data-sigil-id="${markerId}"]`);
528
+ if (!element) return { success: false, error: "Element not found" };
529
+ const checkbox = element.querySelector('input[type="checkbox"]') || element;
530
+ if (checkbox.type === "checkbox" && checkbox.checked !== shouldCheck) {
531
+ checkbox.click();
532
+ }
533
+ return { success: true };
534
+ }
535
+ sendResult(result) {
536
+ if (this.wsConnection?.readyState === WebSocket.OPEN) {
537
+ this.wsConnection.send(JSON.stringify(result));
538
+ }
539
+ }
540
+ };
541
+ var sigil = new SigilCore();
542
+ var sigil_default = sigil;
543
+ if (typeof window !== "undefined") {
544
+ window.Sigil = sigil;
545
+ }
546
+ // Annotate the CommonJS export names for ESM import in node:
547
+ 0 && (module.exports = {
548
+ Sigil
549
+ });
@@ -0,0 +1,83 @@
1
+ /**
2
+ * @getsigil/core - Visual markers for automated UI testing
3
+ * https://usesigil.dev
4
+ */
5
+ interface SigilConfig {
6
+ /** Enable/disable Sigil markers */
7
+ enabled?: boolean;
8
+ /** Marker position: 'center', 'top-left', 'top-right', 'bottom-left', 'bottom-right' */
9
+ position?: 'center' | 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right';
10
+ /** Z-index for markers */
11
+ zIndex?: number;
12
+ /** Marker opacity (0-1) */
13
+ opacity?: number;
14
+ /** WebSocket port for executor communication */
15
+ wsPort?: number;
16
+ }
17
+ interface MarkerEncoding {
18
+ borderColor: number;
19
+ cellColors: number[];
20
+ }
21
+ declare class SigilCore {
22
+ private config;
23
+ private observer;
24
+ private wsConnection;
25
+ private wsReconnectTimer;
26
+ private markedElements;
27
+ private initialized;
28
+ /**
29
+ * Initialize Sigil with configuration
30
+ */
31
+ init(options?: SigilConfig): void;
32
+ /**
33
+ * Update configuration
34
+ */
35
+ configure(options: Partial<SigilConfig>): void;
36
+ /**
37
+ * Scan DOM and add markers to elements with data-sigil-id
38
+ */
39
+ scan(root?: Document | Element): void;
40
+ /**
41
+ * Auto-discover interactive elements and add data-sigil-id attributes
42
+ */
43
+ autoDiscover(): void;
44
+ /**
45
+ * Show all markers
46
+ */
47
+ show(): void;
48
+ /**
49
+ * Hide all markers
50
+ */
51
+ hide(): void;
52
+ /**
53
+ * Clean up and remove all markers
54
+ */
55
+ dispose(): void;
56
+ /**
57
+ * Check if Sigil is enabled
58
+ */
59
+ isEnabled(): boolean;
60
+ private injectStyles;
61
+ private addMarker;
62
+ private getPositionStyles;
63
+ private encode;
64
+ private sha256;
65
+ private createMarkerSvg;
66
+ private generateElementId;
67
+ private startObserver;
68
+ private stopObserver;
69
+ private removeAllMarkers;
70
+ private connectWebSocket;
71
+ private handleWebSocketMessage;
72
+ private searchForMarker;
73
+ private getDirection;
74
+ private scrollToMarker;
75
+ private readTextContent;
76
+ private readInputValue;
77
+ private selectOption;
78
+ private setCheckboxState;
79
+ private sendResult;
80
+ }
81
+ declare const sigil: SigilCore;
82
+
83
+ export { type MarkerEncoding, sigil as Sigil, type SigilConfig, sigil as default };