@cognitvs/a11y-widget 0.0.0-stage → 1.0.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 +134 -2
- package/dist/a11y-widget.js +1325 -0
- package/dist/a11y-widget.js.map +1 -0
- package/dist/a11y-widget.umd.cjs +2 -0
- package/dist/a11y-widget.umd.cjs.map +1 -0
- package/dist/features/cursor-magnet.d.ts +24 -0
- package/dist/features/dom-effects.d.ts +11 -0
- package/dist/features/scroll-assist.d.ts +10 -0
- package/dist/features/tts.d.ts +11 -0
- package/dist/features/vlibras.d.ts +7 -0
- package/dist/index.d.ts +5 -0
- package/dist/print_01.png +0 -0
- package/dist/state/store.d.ts +38 -0
- package/dist/types/index.d.ts +37 -0
- package/dist/widget.d.ts +25 -0
- package/package.json +46 -4
|
@@ -0,0 +1,1325 @@
|
|
|
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
|
+
const widgetCss = ':host{--a11y-primary: #0077d4;--a11y-primary-hover: #0066b8;--a11y-primary-light: #eff6ff;--a11y-bg: #ffffff;--a11y-text: #0f172a;--a11y-text-muted: #64748b;--a11y-border: #e2e8f0;--a11y-card-bg: #f8fafc;--a11y-card-hover: #f1f5f9;--a11y-shadow: 0 20px 40px -15px rgba(0, 0, 0, .25);--a11y-radius: 20px;font-family:Segoe UI,-apple-system,BlinkMacSystemFont,Roboto,Helvetica,Arial,sans-serif;font-size:14px;line-height:1.5;box-sizing:border-box}:host([theme="dark"]){--a11y-bg: #0f172a;--a11y-text: #f8fafc;--a11y-text-muted: #94a3b8;--a11y-border: #1e293b;--a11y-card-bg: #1e293b;--a11y-card-hover: #334155;--a11y-shadow: 0 25px 50px -12px rgba(0, 0, 0, .6)}*,*:before,*:after{box-sizing:border-box;margin:0;padding:0}.a11y-top-banner{position:fixed;top:0;left:0;width:100%;z-index:999995;background-color:#0b192c;color:#fff;border-bottom:2px solid var(--a11y-primary);box-shadow:0 10px 25px #0006;padding:10px 20px;display:flex;align-items:center;justify-content:space-between;gap:16px;font-size:14px;transition:opacity .35s cubic-bezier(.16,1,.3,1),transform .35s cubic-bezier(.16,1,.3,1)}.a11y-top-banner.hidden{opacity:0;pointer-events:none;transform:translateY(-100%)}.a11y-banner-content{display:flex;align-items:center;gap:12px}.a11y-banner-icon{width:26px;height:26px;display:inline-flex;align-items:center;justify-content:center;flex-shrink:0;color:var(--a11y-primary)}.a11y-banner-icon svg{width:100%;height:100%}.a11y-banner-text strong{color:var(--a11y-cyan, #44a5dd)}.a11y-banner-close{background:#ffffff1a;border:none;color:#cbd5e1;width:32px;height:32px;border-radius:50%;display:flex;align-items:center;justify-content:center;cursor:pointer;transition:all .2s;font-size:16px;font-weight:700}.a11y-banner-close:hover{background:#ef4444;color:#fff;transform:scale(1.1)}.a11y-widget-root{position:fixed;bottom:20px;right:20px;z-index:999990;display:flex;flex-direction:column;align-items:flex-end;gap:12px;max-width:calc(100vw - 32px);pointer-events:auto}:host([position="bottom-left"]) .a11y-widget-root{right:auto;left:20px;align-items:flex-start}.a11y-panel{background:var(--a11y-bg);color:var(--a11y-text);border:2px solid var(--a11y-primary);border-radius:var(--a11y-radius);box-shadow:var(--a11y-shadow);width:310px;max-height:var(--fab-panel-max-height, calc(100vh - 160px) );overflow-y:auto;overflow-x:hidden;padding:20px;transition:max-height .25s cubic-bezier(.16,1,.3,1),opacity .25s ease,transform .25s ease,padding .25s ease;display:flex;flex-direction:column;gap:18px}.a11y-panel.closed{max-height:0!important;padding-top:0!important;padding-bottom:0!important;border-width:0!important;opacity:0;pointer-events:none;transform:translateY(15px) scale(.95)}.a11y-panel-header{display:flex;align-items:center;justify-content:space-between;border-bottom:1px solid var(--a11y-border);padding-bottom:12px}.a11y-panel-title{font-size:12px;font-weight:900;letter-spacing:.1em;text-transform:uppercase;color:var(--a11y-primary);display:flex;align-items:center;gap:8px}.a11y-panel-title svg{color:var(--a11y-primary);flex-shrink:0}.a11y-profile-select{width:100%;padding:10px 12px;border-radius:12px;border:2px solid var(--a11y-border);background:var(--a11y-card-bg);color:var(--a11y-text);font-weight:700;font-size:13px;cursor:pointer;outline:none;transition:border-color .2s}.a11y-profile-select:focus{border-color:var(--a11y-primary)}.a11y-section-title{font-size:11px;font-weight:800;text-transform:uppercase;letter-spacing:.05em;color:var(--a11y-text-muted);margin-top:8px;margin-bottom:6px}.a11y-btn{width:100%;padding:12px 14px;border-radius:14px;font-size:13px;font-weight:800;cursor:pointer;border:2px solid transparent;background:var(--a11y-card-bg);color:var(--a11y-text);display:flex;align-items:center;justify-content:flex-start;gap:10px;transition:all .2s ease;-webkit-user-select:none;user-select:none}.a11y-btn:hover{background:var(--a11y-card-hover);border-color:#0077d44d}.a11y-btn.active{background:var(--a11y-primary);color:#fff;border-color:var(--a11y-primary);box-shadow:0 4px 14px #0077d459}.a11y-btn-group{display:flex;align-items:center;gap:6px}.a11y-btn-mini{flex:1;padding:8px;border-radius:10px;font-size:12px;font-weight:700;text-align:center;border:1px solid var(--a11y-border);background:var(--a11y-card-bg);color:var(--a11y-text);cursor:pointer;transition:all .15s}.a11y-btn-mini:hover{background:var(--a11y-card-hover)}.a11y-btn-mini.active{background:var(--a11y-primary);color:#fff;border-color:var(--a11y-primary)}.a11y-scale-box{display:flex;align-items:center;gap:8px;background:var(--a11y-card-bg);padding:6px;border-radius:14px;border:1px solid var(--a11y-border)}.a11y-scale-btn{flex:1;padding:8px 12px;font-size:15px;font-weight:900;background:var(--a11y-bg);border:1px solid var(--a11y-border);border-radius:10px;color:var(--a11y-primary);cursor:pointer;transition:all .2s}.a11y-scale-btn:hover{background:var(--a11y-primary);color:#fff}.a11y-scale-val{min-width:48px;text-align:center;font-weight:900;color:var(--a11y-text);font-size:14px}.a11y-reset-btn{background:transparent;border:none;color:var(--a11y-text-muted);font-size:11px;font-weight:700;text-transform:uppercase;letter-spacing:.05em;text-decoration:underline;text-decoration-style:dashed;cursor:pointer;padding:8px 0;text-align:center;width:100%;margin-top:6px;transition:color .2s}.a11y-reset-btn:hover{color:#ef4444}.a11y-fab-wrapper{position:relative;display:flex;align-items:center;justify-content:flex-end}.a11y-fab{width:58px;height:58px;border-radius:50%;border:2px solid var(--a11y-primary);background:var(--a11y-primary);color:#fff;display:flex;align-items:center;justify-content:center;cursor:pointer;box-shadow:0 10px 25px #0077d473;transition:all .25s cubic-bezier(.175,.885,.32,1.275)}.a11y-fab:hover{transform:scale(1.1);box-shadow:0 15px 30px #0077d499}.a11y-fab:active{transform:scale(.95)}.a11y-fab svg{width:34px;height:34px;color:#fff;flex-shrink:0}.a11y-tour-bubble{position:absolute;right:74px;top:50%;transform:translateY(-50%);width:220px;background:#0f172a;border:2px solid var(--a11y-primary);color:#fff;padding:12px 14px;border-radius:16px;box-shadow:0 15px 35px #00000080;display:flex;align-items:center;gap:10px;cursor:pointer;animation:a11yFadeIn .3s ease-out;z-index:100}.a11y-tour-bubble:after{content:"";position:absolute;right:-8px;top:50%;transform:translateY(-50%);border-top:8px solid transparent;border-bottom:8px solid transparent;border-left:8px solid var(--a11y-primary)}.a11y-ping-ring{position:absolute;right:0;width:58px;height:58px;border-radius:50%;background-color:var(--a11y-primary);animation:a11yPing 2s cubic-bezier(0,0,.2,1) infinite;pointer-events:none;opacity:.6}@keyframes a11yPing{75%,to{transform:scale(1.7);opacity:0}}@keyframes a11yFadeIn{0%{opacity:0;transform:translateY(-50%) scale(.9)}to{opacity:1;transform:translateY(-50%) scale(1)}}';
|
|
5
|
+
const globalCss = `html.high-contrast{filter:contrast(160%)!important}html.high-contrast *{border-color:#facc15!important}html.reduce-motion *,html.reduce-motion *:before,html.reduce-motion *:after{animation-duration:.001ms!important;animation-iteration-count:1!important;transition-duration:.001ms!important;scroll-behavior:auto!important}body{transition:padding-top .35s cubic-bezier(.16,1,.3,1)!important}body.a11y-banner-active{padding-top:var(--a11y-top-banner-height, 46px)!important}html.big-cursor,html.big-cursor *{cursor:url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="48" height="48" viewBox="0 0 32 32"><path fill="%23ffffff" stroke="%230077d4" stroke-width="3" stroke-linejoin="round" d="M2 2 L2 28 L9 22 L15 31 L19 29 L12 20 L21 20 Z"/></svg>'),auto!important}html.cursor-hidden,html.cursor-hidden *{cursor:none!important}html.keyboard-focus *:focus,html.keyboard-focus *:focus-visible{outline:4px solid #0077d4!important;outline-offset:3px!important}html.highlight-links a,html.highlight-links button,html.highlight-links [role=button],html.highlight-links input[type=submit],html.highlight-links input[type=button]{outline:2px dashed #0077d4!important;outline-offset:2px!important;background-color:#0077d41f!important}html.dyslexia-mode,html.dyslexia-mode *{font-family:Comic Sans MS,OpenDyslexic,Arial,sans-serif!important;letter-spacing:.08em!important;word-spacing:.16em!important;line-height:1.8!important}html.text-spacing-1 *{letter-spacing:.12em!important;word-spacing:.16em!important;line-height:1.8!important}html.text-spacing-2 *{letter-spacing:.2em!important;word-spacing:.28em!important;line-height:2.2!important}html.daltonism-protanopia{filter:url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg"><filter id="f"><feColorMatrix type="matrix" values="0.567, 0.433, 0, 0, 0 0.558, 0.442, 0, 0, 0 0, 0.242, 0.758, 0, 0 0, 0, 0, 1, 0"/></filter></svg>#f')!important}html.daltonism-deuteranopia{filter:url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg"><filter id="f"><feColorMatrix type="matrix" values="0.625, 0.375, 0, 0, 0 0.7, 0.3, 0, 0, 0 0, 0.3, 0.7, 0, 0 0, 0, 0, 1, 0"/></filter></svg>#f')!important}html.daltonism-tritanopia{filter:url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg"><filter id="f"><feColorMatrix type="matrix" values="0.95, 0.05, 0, 0, 0 0, 0.433, 0.567, 0, 0 0, 0.475, 0.525, 0, 0 0, 0, 0, 1, 0"/></filter></svg>#f')!important}html.daltonism-monochromacy{filter:grayscale(100%)!important}:root{--font-scale: 1}body{font-size:calc(1rem * var(--font-scale, 1))!important}`;
|
|
6
|
+
class A11yStore {
|
|
7
|
+
constructor(prefix = "cognitvs") {
|
|
8
|
+
__publicField(this, "prefix");
|
|
9
|
+
__publicField(this, "state");
|
|
10
|
+
__publicField(this, "listeners", /* @__PURE__ */ new Set());
|
|
11
|
+
this.prefix = prefix;
|
|
12
|
+
this.state = this.loadInitialState();
|
|
13
|
+
}
|
|
14
|
+
getState() {
|
|
15
|
+
return { ...this.state };
|
|
16
|
+
}
|
|
17
|
+
subscribe(listener) {
|
|
18
|
+
this.listeners.add(listener);
|
|
19
|
+
listener(this.getState());
|
|
20
|
+
return () => this.listeners.delete(listener);
|
|
21
|
+
}
|
|
22
|
+
notify() {
|
|
23
|
+
const current = this.getState();
|
|
24
|
+
this.listeners.forEach((fn) => fn(current));
|
|
25
|
+
}
|
|
26
|
+
loadInitialState() {
|
|
27
|
+
const getItem = (key) => {
|
|
28
|
+
try {
|
|
29
|
+
return localStorage.getItem(`${this.prefix}_${key}`);
|
|
30
|
+
} catch {
|
|
31
|
+
return null;
|
|
32
|
+
}
|
|
33
|
+
};
|
|
34
|
+
const fontScale = parseFloat(getItem("font_scale") || "1") || 1;
|
|
35
|
+
const isHighContrast = getItem("high_contrast") === "true";
|
|
36
|
+
const isReduceMotion = getItem("reduce_motion") === "true";
|
|
37
|
+
const isBigCursor = getItem("big_cursor") === "true";
|
|
38
|
+
const isKeyboardFocus = getItem("keyboard_focus") === "true";
|
|
39
|
+
const isHighlightLinks = getItem("highlight_links") === "true";
|
|
40
|
+
const isReadingMaskActive = getItem("reading_mask") === "true";
|
|
41
|
+
const isReadingMaskSmart = getItem("reading_mask_smart") !== "false";
|
|
42
|
+
const isDyslexiaMode = getItem("dyslexia") === "true";
|
|
43
|
+
const textSpacingLevel = parseInt(getItem("text_spacing") || "0", 10) || 0;
|
|
44
|
+
const colorBlindMode = getItem("colorblind") || "none";
|
|
45
|
+
const isScrollAssistActive = getItem("scroll_assist") === "true";
|
|
46
|
+
const isCursorMagnetActive = getItem("magnet_cursor") === "true";
|
|
47
|
+
const cursorMagnetForce = getItem("magnet_force") || "suave";
|
|
48
|
+
const isVLibrasActive = getItem("vlibras") === "true";
|
|
49
|
+
const isTTSActive = getItem("tts") === "true";
|
|
50
|
+
const ttsRate = parseFloat(getItem("tts_rate") || "1") || 1;
|
|
51
|
+
const hasSeenTour = getItem("seen_tour") === "true";
|
|
52
|
+
const bannerDismissed = getItem("banner_dismissed") === "true";
|
|
53
|
+
return {
|
|
54
|
+
isExpanded: false,
|
|
55
|
+
activeProfile: "all",
|
|
56
|
+
fontScale,
|
|
57
|
+
isHighContrast,
|
|
58
|
+
isReadingMaskActive,
|
|
59
|
+
isReadingMaskSmart,
|
|
60
|
+
colorBlindMode,
|
|
61
|
+
isDaltonismMenuOpen: false,
|
|
62
|
+
isTTSActive,
|
|
63
|
+
ttsRate,
|
|
64
|
+
isVLibrasActive,
|
|
65
|
+
isBigCursor,
|
|
66
|
+
isKeyboardFocus,
|
|
67
|
+
isScrollAssistActive,
|
|
68
|
+
isCursorMagnetActive,
|
|
69
|
+
cursorMagnetForce,
|
|
70
|
+
isHighlightLinks,
|
|
71
|
+
isReduceMotion,
|
|
72
|
+
isDyslexiaMode,
|
|
73
|
+
textSpacingLevel,
|
|
74
|
+
showAttentionGrabber: false,
|
|
75
|
+
hasInteracted: hasSeenTour,
|
|
76
|
+
bannerDismissed
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
setStorage(key, value) {
|
|
80
|
+
try {
|
|
81
|
+
localStorage.setItem(`${this.prefix}_${key}`, value);
|
|
82
|
+
} catch (e) {
|
|
83
|
+
console.warn("A11yWidget: falha ao salvar no localStorage", e);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
removeStorage(key) {
|
|
87
|
+
try {
|
|
88
|
+
localStorage.removeItem(`${this.prefix}_${key}`);
|
|
89
|
+
} catch (e) {
|
|
90
|
+
console.warn("A11yWidget: falha ao remover do localStorage", e);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
update(partial) {
|
|
94
|
+
this.state = { ...this.state, ...partial };
|
|
95
|
+
this.notify();
|
|
96
|
+
}
|
|
97
|
+
toggleExpanded() {
|
|
98
|
+
this.update({
|
|
99
|
+
isExpanded: !this.state.isExpanded,
|
|
100
|
+
showAttentionGrabber: false,
|
|
101
|
+
hasInteracted: true
|
|
102
|
+
});
|
|
103
|
+
this.setStorage("seen_tour", "true");
|
|
104
|
+
}
|
|
105
|
+
setActiveProfile(profile) {
|
|
106
|
+
this.update({ activeProfile: profile });
|
|
107
|
+
}
|
|
108
|
+
updateFontScale(delta) {
|
|
109
|
+
const newScale = Math.min(Math.max(parseFloat((this.state.fontScale + delta).toFixed(2)), 0.8), 2);
|
|
110
|
+
this.update({ fontScale: newScale });
|
|
111
|
+
this.setStorage("font_scale", newScale.toString());
|
|
112
|
+
}
|
|
113
|
+
toggleHighContrast() {
|
|
114
|
+
const val = !this.state.isHighContrast;
|
|
115
|
+
this.update({ isHighContrast: val });
|
|
116
|
+
this.setStorage("high_contrast", val.toString());
|
|
117
|
+
}
|
|
118
|
+
toggleReduceMotion() {
|
|
119
|
+
const val = !this.state.isReduceMotion;
|
|
120
|
+
this.update({ isReduceMotion: val });
|
|
121
|
+
this.setStorage("reduce_motion", val.toString());
|
|
122
|
+
}
|
|
123
|
+
toggleBigCursor() {
|
|
124
|
+
const val = !this.state.isBigCursor;
|
|
125
|
+
this.update({ isBigCursor: val });
|
|
126
|
+
this.setStorage("big_cursor", val.toString());
|
|
127
|
+
}
|
|
128
|
+
toggleKeyboardFocus() {
|
|
129
|
+
const val = !this.state.isKeyboardFocus;
|
|
130
|
+
this.update({ isKeyboardFocus: val });
|
|
131
|
+
this.setStorage("keyboard_focus", val.toString());
|
|
132
|
+
}
|
|
133
|
+
toggleHighlightLinks() {
|
|
134
|
+
const val = !this.state.isHighlightLinks;
|
|
135
|
+
this.update({ isHighlightLinks: val });
|
|
136
|
+
this.setStorage("highlight_links", val.toString());
|
|
137
|
+
}
|
|
138
|
+
toggleScrollAssist() {
|
|
139
|
+
const val = !this.state.isScrollAssistActive;
|
|
140
|
+
this.update({ isScrollAssistActive: val });
|
|
141
|
+
this.setStorage("scroll_assist", val.toString());
|
|
142
|
+
}
|
|
143
|
+
toggleCursorMagnet() {
|
|
144
|
+
const val = !this.state.isCursorMagnetActive;
|
|
145
|
+
this.update({ isCursorMagnetActive: val });
|
|
146
|
+
this.setStorage("magnet_cursor", val.toString());
|
|
147
|
+
}
|
|
148
|
+
setCursorMagnetForce(force) {
|
|
149
|
+
this.update({ cursorMagnetForce: force });
|
|
150
|
+
this.setStorage("magnet_force", force);
|
|
151
|
+
}
|
|
152
|
+
toggleReadingMask() {
|
|
153
|
+
const val = !this.state.isReadingMaskActive;
|
|
154
|
+
this.update({ isReadingMaskActive: val });
|
|
155
|
+
this.setStorage("reading_mask", val.toString());
|
|
156
|
+
}
|
|
157
|
+
setReadingMaskSmart(smart) {
|
|
158
|
+
this.update({ isReadingMaskSmart: smart });
|
|
159
|
+
this.setStorage("reading_mask_smart", smart.toString());
|
|
160
|
+
}
|
|
161
|
+
toggleDyslexia() {
|
|
162
|
+
const val = !this.state.isDyslexiaMode;
|
|
163
|
+
this.update({ isDyslexiaMode: val });
|
|
164
|
+
this.setStorage("dyslexia", val.toString());
|
|
165
|
+
}
|
|
166
|
+
setTextSpacing(level) {
|
|
167
|
+
this.update({ textSpacingLevel: level });
|
|
168
|
+
this.setStorage("text_spacing", level.toString());
|
|
169
|
+
}
|
|
170
|
+
setColorBlindMode(mode) {
|
|
171
|
+
this.update({ colorBlindMode: mode, isDaltonismMenuOpen: false });
|
|
172
|
+
this.setStorage("colorblind", mode);
|
|
173
|
+
}
|
|
174
|
+
toggleDaltonismMenu() {
|
|
175
|
+
this.update({ isDaltonismMenuOpen: !this.state.isDaltonismMenuOpen });
|
|
176
|
+
}
|
|
177
|
+
toggleTTS() {
|
|
178
|
+
const val = !this.state.isTTSActive;
|
|
179
|
+
const rate = val ? 1 : this.state.ttsRate;
|
|
180
|
+
this.update({ isTTSActive: val, ttsRate: rate });
|
|
181
|
+
this.setStorage("tts", val.toString());
|
|
182
|
+
if (val) this.setStorage("tts_rate", "1");
|
|
183
|
+
}
|
|
184
|
+
setTTSRate(rate) {
|
|
185
|
+
this.update({ ttsRate: rate });
|
|
186
|
+
this.setStorage("tts_rate", rate.toString());
|
|
187
|
+
}
|
|
188
|
+
toggleVLibras() {
|
|
189
|
+
const val = !this.state.isVLibrasActive;
|
|
190
|
+
this.update({ isVLibrasActive: val });
|
|
191
|
+
this.setStorage("vlibras", val.toString());
|
|
192
|
+
}
|
|
193
|
+
dismissBanner() {
|
|
194
|
+
this.update({ bannerDismissed: true });
|
|
195
|
+
this.setStorage("banner_dismissed", "true");
|
|
196
|
+
}
|
|
197
|
+
resetAll() {
|
|
198
|
+
const keys = [
|
|
199
|
+
"font_scale",
|
|
200
|
+
"high_contrast",
|
|
201
|
+
"reduce_motion",
|
|
202
|
+
"big_cursor",
|
|
203
|
+
"keyboard_focus",
|
|
204
|
+
"highlight_links",
|
|
205
|
+
"reading_mask",
|
|
206
|
+
"reading_mask_smart",
|
|
207
|
+
"dyslexia",
|
|
208
|
+
"text_spacing",
|
|
209
|
+
"colorblind",
|
|
210
|
+
"vlibras",
|
|
211
|
+
"magnet_cursor",
|
|
212
|
+
"magnet_force",
|
|
213
|
+
"tts",
|
|
214
|
+
"tts_rate"
|
|
215
|
+
];
|
|
216
|
+
keys.forEach((k) => this.removeStorage(k));
|
|
217
|
+
this.update({
|
|
218
|
+
fontScale: 1,
|
|
219
|
+
isHighContrast: false,
|
|
220
|
+
isReadingMaskActive: false,
|
|
221
|
+
isReadingMaskSmart: true,
|
|
222
|
+
colorBlindMode: "none",
|
|
223
|
+
isDaltonismMenuOpen: false,
|
|
224
|
+
isTTSActive: false,
|
|
225
|
+
ttsRate: 1,
|
|
226
|
+
isVLibrasActive: false,
|
|
227
|
+
isBigCursor: false,
|
|
228
|
+
isKeyboardFocus: false,
|
|
229
|
+
isScrollAssistActive: false,
|
|
230
|
+
isCursorMagnetActive: false,
|
|
231
|
+
cursorMagnetForce: "suave",
|
|
232
|
+
isHighlightLinks: false,
|
|
233
|
+
isReduceMotion: false,
|
|
234
|
+
isDyslexiaMode: false,
|
|
235
|
+
textSpacingLevel: 0
|
|
236
|
+
});
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
class DomEffectsManager {
|
|
240
|
+
constructor() {
|
|
241
|
+
__publicField(this, "prevClasses", /* @__PURE__ */ new Set());
|
|
242
|
+
__publicField(this, "readingMaskEl", null);
|
|
243
|
+
__publicField(this, "maskFrameId", null);
|
|
244
|
+
__publicField(this, "boundMouseMove", null);
|
|
245
|
+
}
|
|
246
|
+
applyGlobalState(state) {
|
|
247
|
+
const docEl = document.documentElement;
|
|
248
|
+
docEl.style.setProperty("--font-scale", state.fontScale.toString());
|
|
249
|
+
this.syncClass(docEl, "high-contrast", state.isHighContrast);
|
|
250
|
+
this.syncClass(docEl, "reduce-motion", state.isReduceMotion);
|
|
251
|
+
this.syncClass(docEl, "big-cursor", state.isBigCursor);
|
|
252
|
+
this.syncClass(docEl, "keyboard-focus", state.isKeyboardFocus);
|
|
253
|
+
this.syncClass(docEl, "highlight-links", state.isHighlightLinks);
|
|
254
|
+
this.syncClass(docEl, "scroll-assist-active", state.isScrollAssistActive);
|
|
255
|
+
this.syncClass(docEl, "cursor-magnet-active", state.isCursorMagnetActive);
|
|
256
|
+
this.syncClass(docEl, "dyslexia-mode", state.isDyslexiaMode);
|
|
257
|
+
docEl.setAttribute("data-magnet-force", state.cursorMagnetForce);
|
|
258
|
+
docEl.classList.remove("text-spacing-1", "text-spacing-2");
|
|
259
|
+
if (state.textSpacingLevel > 0) {
|
|
260
|
+
docEl.classList.add(`text-spacing-${state.textSpacingLevel}`);
|
|
261
|
+
}
|
|
262
|
+
["protanopia", "deuteranopia", "tritanopia", "monochromacy"].forEach((m) => {
|
|
263
|
+
docEl.classList.remove(`daltonism-${m}`);
|
|
264
|
+
});
|
|
265
|
+
if (state.colorBlindMode !== "none") {
|
|
266
|
+
docEl.classList.add(`daltonism-${state.colorBlindMode}`);
|
|
267
|
+
}
|
|
268
|
+
this.syncReadingMask(state.isReadingMaskActive, state.isReadingMaskSmart);
|
|
269
|
+
}
|
|
270
|
+
syncClass(el, className, active) {
|
|
271
|
+
if (active) {
|
|
272
|
+
el.classList.add(className);
|
|
273
|
+
this.prevClasses.add(className);
|
|
274
|
+
} else {
|
|
275
|
+
el.classList.remove(className);
|
|
276
|
+
this.prevClasses.delete(className);
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
syncReadingMask(active, isSmart) {
|
|
280
|
+
if (!active) {
|
|
281
|
+
if (this.readingMaskEl) {
|
|
282
|
+
this.readingMaskEl.remove();
|
|
283
|
+
this.readingMaskEl = null;
|
|
284
|
+
}
|
|
285
|
+
if (this.boundMouseMove) {
|
|
286
|
+
window.removeEventListener("mousemove", this.boundMouseMove);
|
|
287
|
+
this.boundMouseMove = null;
|
|
288
|
+
}
|
|
289
|
+
if (this.maskFrameId) {
|
|
290
|
+
cancelAnimationFrame(this.maskFrameId);
|
|
291
|
+
this.maskFrameId = null;
|
|
292
|
+
}
|
|
293
|
+
return;
|
|
294
|
+
}
|
|
295
|
+
if (!this.readingMaskEl) {
|
|
296
|
+
this.readingMaskEl = document.createElement("div");
|
|
297
|
+
this.readingMaskEl.id = "cognitvs-a11y-reading-mask";
|
|
298
|
+
this.readingMaskEl.setAttribute("aria-hidden", "true");
|
|
299
|
+
this.readingMaskEl.style.cssText = `
|
|
300
|
+
position: fixed;
|
|
301
|
+
left: 0;
|
|
302
|
+
width: 100vw;
|
|
303
|
+
pointer-events: none;
|
|
304
|
+
z-index: 999998;
|
|
305
|
+
border-top: 2px solid rgba(0, 119, 212, 0.7);
|
|
306
|
+
border-bottom: 2px solid rgba(0, 119, 212, 0.7);
|
|
307
|
+
box-shadow: 0 0 0 9999px rgba(0, 0, 0, 0.7);
|
|
308
|
+
height: var(--mask-height, 140px);
|
|
309
|
+
top: var(--mask-top, calc(50vh - 70px));
|
|
310
|
+
transition: top 0.15s cubic-bezier(0.2, 0, 0, 1), height 0.15s cubic-bezier(0.2, 0, 0, 1);
|
|
311
|
+
`;
|
|
312
|
+
document.body.appendChild(this.readingMaskEl);
|
|
313
|
+
}
|
|
314
|
+
let lastTarget = null;
|
|
315
|
+
if (this.boundMouseMove) {
|
|
316
|
+
window.removeEventListener("mousemove", this.boundMouseMove);
|
|
317
|
+
}
|
|
318
|
+
this.boundMouseMove = (e) => {
|
|
319
|
+
if (this.maskFrameId) cancelAnimationFrame(this.maskFrameId);
|
|
320
|
+
this.maskFrameId = requestAnimationFrame(() => {
|
|
321
|
+
if (isSmart) {
|
|
322
|
+
const target = document.elementFromPoint(e.clientX, e.clientY);
|
|
323
|
+
if (target) {
|
|
324
|
+
const textContainer = target.closest("p, h1, h2, h3, h4, h5, h6, li, blockquote, figcaption, td, th, a, button, label");
|
|
325
|
+
const elToMeasure = textContainer || target;
|
|
326
|
+
const rect = elToMeasure.getBoundingClientRect();
|
|
327
|
+
if (textContainer && rect.height > 10 && rect.height < 500) {
|
|
328
|
+
if (elToMeasure !== lastTarget) {
|
|
329
|
+
lastTarget = elToMeasure;
|
|
330
|
+
const margin = 24;
|
|
331
|
+
const maskHeight = rect.height + margin;
|
|
332
|
+
const topPos = rect.top - margin / 2;
|
|
333
|
+
document.documentElement.style.setProperty("--mask-height", `${maskHeight}px`);
|
|
334
|
+
document.documentElement.style.setProperty("--mask-top", `${topPos}px`);
|
|
335
|
+
}
|
|
336
|
+
return;
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
lastTarget = null;
|
|
341
|
+
document.documentElement.style.setProperty("--mask-height", "140px");
|
|
342
|
+
document.documentElement.style.setProperty("--mask-top", `${e.clientY - 70}px`);
|
|
343
|
+
});
|
|
344
|
+
};
|
|
345
|
+
window.addEventListener("mousemove", this.boundMouseMove, { passive: true });
|
|
346
|
+
}
|
|
347
|
+
destroy() {
|
|
348
|
+
const docEl = document.documentElement;
|
|
349
|
+
this.prevClasses.forEach((c) => docEl.classList.remove(c));
|
|
350
|
+
["protanopia", "deuteranopia", "tritanopia", "monochromacy", "text-spacing-1", "text-spacing-2"].forEach((c) => docEl.classList.remove(c));
|
|
351
|
+
docEl.style.removeProperty("--font-scale");
|
|
352
|
+
docEl.removeAttribute("data-magnet-force");
|
|
353
|
+
this.syncReadingMask(false, false);
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
class TTSController {
|
|
357
|
+
constructor(isWidgetElement) {
|
|
358
|
+
__publicField(this, "active", false);
|
|
359
|
+
__publicField(this, "rate", 1);
|
|
360
|
+
__publicField(this, "boundClickHandler", null);
|
|
361
|
+
__publicField(this, "isWidgetElement");
|
|
362
|
+
this.isWidgetElement = isWidgetElement;
|
|
363
|
+
}
|
|
364
|
+
update(active, rate) {
|
|
365
|
+
this.active = active;
|
|
366
|
+
this.rate = rate;
|
|
367
|
+
if (!active) {
|
|
368
|
+
if (typeof window !== "undefined" && "speechSynthesis" in window) {
|
|
369
|
+
window.speechSynthesis.cancel();
|
|
370
|
+
}
|
|
371
|
+
if (this.boundClickHandler) {
|
|
372
|
+
document.removeEventListener("click", this.boundClickHandler, { capture: true });
|
|
373
|
+
this.boundClickHandler = null;
|
|
374
|
+
}
|
|
375
|
+
return;
|
|
376
|
+
}
|
|
377
|
+
if (!this.boundClickHandler) {
|
|
378
|
+
this.boundClickHandler = this.handleClick.bind(this);
|
|
379
|
+
document.addEventListener("click", this.boundClickHandler, { capture: true });
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
handleClick(e) {
|
|
383
|
+
if (!this.active) return;
|
|
384
|
+
const target = e.target;
|
|
385
|
+
if (!target) return;
|
|
386
|
+
if (this.isWidgetElement(target)) return;
|
|
387
|
+
const invalidTags = [
|
|
388
|
+
"BODY",
|
|
389
|
+
"HTML",
|
|
390
|
+
"MAIN",
|
|
391
|
+
"SECTION",
|
|
392
|
+
"ARTICLE",
|
|
393
|
+
"HEADER",
|
|
394
|
+
"FOOTER",
|
|
395
|
+
"NAV",
|
|
396
|
+
"ASIDE",
|
|
397
|
+
"FORM",
|
|
398
|
+
"UL",
|
|
399
|
+
"OL",
|
|
400
|
+
"TABLE",
|
|
401
|
+
"TBODY",
|
|
402
|
+
"TR"
|
|
403
|
+
];
|
|
404
|
+
if (invalidTags.includes(target.tagName) || target.id === "root") return;
|
|
405
|
+
const blockTags = [
|
|
406
|
+
"DIV",
|
|
407
|
+
"P",
|
|
408
|
+
"H1",
|
|
409
|
+
"H2",
|
|
410
|
+
"H3",
|
|
411
|
+
"H4",
|
|
412
|
+
"H5",
|
|
413
|
+
"H6",
|
|
414
|
+
"UL",
|
|
415
|
+
"OL",
|
|
416
|
+
"LI",
|
|
417
|
+
"SECTION",
|
|
418
|
+
"ARTICLE",
|
|
419
|
+
"IMG",
|
|
420
|
+
"PICTURE",
|
|
421
|
+
"VIDEO",
|
|
422
|
+
"HEADER",
|
|
423
|
+
"FOOTER",
|
|
424
|
+
"NAV",
|
|
425
|
+
"ASIDE",
|
|
426
|
+
"FORM",
|
|
427
|
+
"TABLE",
|
|
428
|
+
"TR",
|
|
429
|
+
"TD",
|
|
430
|
+
"TH",
|
|
431
|
+
"MAIN"
|
|
432
|
+
];
|
|
433
|
+
const hasBlockChildren = Array.from(target.children).some((child) => blockTags.includes(child.tagName));
|
|
434
|
+
if (hasBlockChildren) return;
|
|
435
|
+
const rawText = target.innerText || target.textContent || "";
|
|
436
|
+
const text = rawText.replace(/[\p{Extended_Pictographic}]/gu, "").trim();
|
|
437
|
+
if (text.length > 0 && "speechSynthesis" in window) {
|
|
438
|
+
if (target.closest("a") || target.closest("button")) {
|
|
439
|
+
e.preventDefault();
|
|
440
|
+
e.stopPropagation();
|
|
441
|
+
}
|
|
442
|
+
window.speechSynthesis.cancel();
|
|
443
|
+
const utterance = new SpeechSynthesisUtterance(text);
|
|
444
|
+
utterance.lang = "pt-BR";
|
|
445
|
+
utterance.rate = this.rate;
|
|
446
|
+
const originalHTML = target.innerHTML;
|
|
447
|
+
const originalOutline = target.style.outline;
|
|
448
|
+
const originalOutlineOffset = target.style.outlineOffset;
|
|
449
|
+
const tokens = text.split(/(\s+)/);
|
|
450
|
+
target.innerHTML = "";
|
|
451
|
+
const spanElements = [];
|
|
452
|
+
tokens.forEach((token) => {
|
|
453
|
+
const span = document.createElement("span");
|
|
454
|
+
span.textContent = token;
|
|
455
|
+
span.style.transition = "all 150ms ease-in-out";
|
|
456
|
+
span.style.borderRadius = "2px";
|
|
457
|
+
target.appendChild(span);
|
|
458
|
+
spanElements.push(span);
|
|
459
|
+
});
|
|
460
|
+
target.style.outline = "3px solid #f59e0b";
|
|
461
|
+
target.style.outlineOffset = "2px";
|
|
462
|
+
utterance.onboundary = (ev) => {
|
|
463
|
+
if (ev.name === "word") {
|
|
464
|
+
let charCount = 0;
|
|
465
|
+
for (let i = 0; i < spanElements.length; i++) {
|
|
466
|
+
const spanText = spanElements[i].textContent || "";
|
|
467
|
+
const span = spanElements[i];
|
|
468
|
+
if (charCount <= ev.charIndex && charCount + spanText.length > ev.charIndex && spanText.trim().length > 0) {
|
|
469
|
+
span.style.backgroundColor = "#fef08a";
|
|
470
|
+
span.style.color = "#0f172a";
|
|
471
|
+
span.style.boxShadow = "0 0 0 2px #fef08a";
|
|
472
|
+
} else {
|
|
473
|
+
span.style.backgroundColor = "transparent";
|
|
474
|
+
span.style.color = "inherit";
|
|
475
|
+
span.style.boxShadow = "0 0 0 2px transparent";
|
|
476
|
+
}
|
|
477
|
+
charCount += spanText.length;
|
|
478
|
+
}
|
|
479
|
+
}
|
|
480
|
+
};
|
|
481
|
+
const restoreDOM = () => {
|
|
482
|
+
target.style.outline = originalOutline;
|
|
483
|
+
target.style.outlineOffset = originalOutlineOffset;
|
|
484
|
+
target.innerHTML = originalHTML;
|
|
485
|
+
};
|
|
486
|
+
utterance.onend = restoreDOM;
|
|
487
|
+
utterance.onerror = restoreDOM;
|
|
488
|
+
window.speechSynthesis.speak(utterance);
|
|
489
|
+
}
|
|
490
|
+
}
|
|
491
|
+
destroy() {
|
|
492
|
+
if (this.boundClickHandler) {
|
|
493
|
+
document.removeEventListener("click", this.boundClickHandler, { capture: true });
|
|
494
|
+
this.boundClickHandler = null;
|
|
495
|
+
}
|
|
496
|
+
if (typeof window !== "undefined" && "speechSynthesis" in window) {
|
|
497
|
+
window.speechSynthesis.cancel();
|
|
498
|
+
}
|
|
499
|
+
}
|
|
500
|
+
}
|
|
501
|
+
class CursorMagnetController {
|
|
502
|
+
constructor() {
|
|
503
|
+
__publicField(this, "active", false);
|
|
504
|
+
__publicField(this, "force", "suave");
|
|
505
|
+
__publicField(this, "cursorEl", null);
|
|
506
|
+
__publicField(this, "isMagnetized", false);
|
|
507
|
+
__publicField(this, "targetButton", null);
|
|
508
|
+
__publicField(this, "cachedButtons", []);
|
|
509
|
+
__publicField(this, "lastCacheTime", 0);
|
|
510
|
+
__publicField(this, "isBig", false);
|
|
511
|
+
__publicField(this, "boundMouseMove", null);
|
|
512
|
+
__publicField(this, "boundClick", null);
|
|
513
|
+
__publicField(this, "boundScroll", null);
|
|
514
|
+
}
|
|
515
|
+
update(active, force, isBig) {
|
|
516
|
+
this.active = active;
|
|
517
|
+
this.force = force;
|
|
518
|
+
this.isBig = isBig;
|
|
519
|
+
if (!active) {
|
|
520
|
+
this.teardown();
|
|
521
|
+
return;
|
|
522
|
+
}
|
|
523
|
+
if (!this.boundMouseMove) {
|
|
524
|
+
this.setup();
|
|
525
|
+
}
|
|
526
|
+
}
|
|
527
|
+
setup() {
|
|
528
|
+
this.boundMouseMove = this.handleMouseMove.bind(this);
|
|
529
|
+
this.boundClick = this.handleClick.bind(this);
|
|
530
|
+
this.boundScroll = () => {
|
|
531
|
+
this.lastCacheTime = 0;
|
|
532
|
+
};
|
|
533
|
+
window.addEventListener("mousemove", this.boundMouseMove, { passive: true });
|
|
534
|
+
window.addEventListener("click", this.boundClick, { capture: true });
|
|
535
|
+
window.addEventListener("scroll", this.boundScroll, { passive: true });
|
|
536
|
+
}
|
|
537
|
+
teardown() {
|
|
538
|
+
if (this.boundMouseMove) {
|
|
539
|
+
window.removeEventListener("mousemove", this.boundMouseMove);
|
|
540
|
+
this.boundMouseMove = null;
|
|
541
|
+
}
|
|
542
|
+
if (this.boundClick) {
|
|
543
|
+
window.removeEventListener("click", this.boundClick, { capture: true });
|
|
544
|
+
this.boundClick = null;
|
|
545
|
+
}
|
|
546
|
+
if (this.boundScroll) {
|
|
547
|
+
window.removeEventListener("scroll", this.boundScroll);
|
|
548
|
+
this.boundScroll = null;
|
|
549
|
+
}
|
|
550
|
+
document.documentElement.classList.remove("cursor-hidden");
|
|
551
|
+
this.isMagnetized = false;
|
|
552
|
+
this.targetButton = null;
|
|
553
|
+
if (this.cursorEl) {
|
|
554
|
+
this.cursorEl.remove();
|
|
555
|
+
this.cursorEl = null;
|
|
556
|
+
}
|
|
557
|
+
}
|
|
558
|
+
ensureCursorElement() {
|
|
559
|
+
if (!this.cursorEl) {
|
|
560
|
+
this.cursorEl = document.createElement("div");
|
|
561
|
+
this.cursorEl.id = "cognitvs-a11y-virtual-cursor";
|
|
562
|
+
this.cursorEl.setAttribute("aria-hidden", "true");
|
|
563
|
+
this.cursorEl.style.cssText = `
|
|
564
|
+
position: fixed;
|
|
565
|
+
pointer-events: none;
|
|
566
|
+
z-index: 999999;
|
|
567
|
+
transition: transform 75ms ease;
|
|
568
|
+
transform: translate(-5px, -5px);
|
|
569
|
+
filter: drop-shadow(0 0 10px rgba(0, 119, 212, 0.9));
|
|
570
|
+
`;
|
|
571
|
+
document.body.appendChild(this.cursorEl);
|
|
572
|
+
}
|
|
573
|
+
this.cursorEl.innerHTML = this.isBig ? `<svg xmlns="http://www.w3.org/2000/svg" width="48" height="48" viewBox="0 0 32 32">
|
|
574
|
+
<path fill="#ffffff" stroke="#0077d4" stroke-width="3" stroke-linejoin="round" d="M2 2 L2 28 L9 22 L15 31 L19 29 L12 20 L21 20 Z" />
|
|
575
|
+
</svg>` : `<svg xmlns="http://www.w3.org/2000/svg" width="28" height="28" viewBox="0 0 32 32">
|
|
576
|
+
<path fill="#ffffff" stroke="#0077d4" stroke-width="2.5" stroke-linejoin="round" d="M2 2 L2 28 L9 22 L15 31 L19 29 L12 20 L21 20 Z" />
|
|
577
|
+
</svg>`;
|
|
578
|
+
return this.cursorEl;
|
|
579
|
+
}
|
|
580
|
+
updateButtonCache() {
|
|
581
|
+
const now = Date.now();
|
|
582
|
+
if (now - this.lastCacheTime > 200) {
|
|
583
|
+
const elements = document.querySelectorAll('a, button, [role="button"], input[type="submit"], input[type="button"]');
|
|
584
|
+
this.cachedButtons = Array.from(elements).map((el) => ({
|
|
585
|
+
el,
|
|
586
|
+
rect: el.getBoundingClientRect()
|
|
587
|
+
}));
|
|
588
|
+
this.lastCacheTime = now;
|
|
589
|
+
}
|
|
590
|
+
}
|
|
591
|
+
handleMouseMove(e) {
|
|
592
|
+
if (!this.active) return;
|
|
593
|
+
const ATTRACTION_RADIUS = this.force === "forte" ? 45 : 25;
|
|
594
|
+
const ESCAPE_RADIUS = this.force === "forte" ? 60 : 40;
|
|
595
|
+
this.updateButtonCache();
|
|
596
|
+
const mouseX = e.clientX;
|
|
597
|
+
const mouseY = e.clientY;
|
|
598
|
+
let targetDistance = Infinity;
|
|
599
|
+
let targetCenter = { x: 0, y: 0 };
|
|
600
|
+
let closestDistance = Infinity;
|
|
601
|
+
let closestButton = null;
|
|
602
|
+
let closestCenter = { x: 0, y: 0 };
|
|
603
|
+
for (const { el } of this.cachedButtons) {
|
|
604
|
+
const currentRect = el.getBoundingClientRect();
|
|
605
|
+
const centerX = currentRect.left + currentRect.width / 2;
|
|
606
|
+
const centerY = currentRect.top + currentRect.height / 2;
|
|
607
|
+
const dxEdge = Math.max(currentRect.left - mouseX, 0, mouseX - currentRect.right);
|
|
608
|
+
const dyEdge = Math.max(currentRect.top - mouseY, 0, mouseY - currentRect.bottom);
|
|
609
|
+
const distanceToEdge = Math.sqrt(dxEdge * dxEdge + dyEdge * dyEdge);
|
|
610
|
+
if (distanceToEdge < closestDistance) {
|
|
611
|
+
closestDistance = distanceToEdge;
|
|
612
|
+
closestButton = el;
|
|
613
|
+
closestCenter = { x: centerX, y: centerY };
|
|
614
|
+
}
|
|
615
|
+
if (el === this.targetButton) {
|
|
616
|
+
targetDistance = distanceToEdge;
|
|
617
|
+
targetCenter = { x: centerX, y: centerY };
|
|
618
|
+
}
|
|
619
|
+
}
|
|
620
|
+
if (this.isMagnetized && this.targetButton) {
|
|
621
|
+
if (targetDistance > ESCAPE_RADIUS) {
|
|
622
|
+
this.isMagnetized = false;
|
|
623
|
+
this.targetButton = null;
|
|
624
|
+
document.documentElement.classList.remove("cursor-hidden");
|
|
625
|
+
if (closestDistance < ATTRACTION_RADIUS && closestButton) {
|
|
626
|
+
this.isMagnetized = true;
|
|
627
|
+
this.targetButton = closestButton;
|
|
628
|
+
this.setCursorPos(closestCenter.x, closestCenter.y);
|
|
629
|
+
document.documentElement.classList.add("cursor-hidden");
|
|
630
|
+
} else {
|
|
631
|
+
this.hideVirtualCursor();
|
|
632
|
+
}
|
|
633
|
+
} else {
|
|
634
|
+
this.setCursorPos(targetCenter.x, targetCenter.y);
|
|
635
|
+
}
|
|
636
|
+
} else {
|
|
637
|
+
if (closestDistance < ATTRACTION_RADIUS && closestButton) {
|
|
638
|
+
this.isMagnetized = true;
|
|
639
|
+
this.targetButton = closestButton;
|
|
640
|
+
this.setCursorPos(closestCenter.x, closestCenter.y);
|
|
641
|
+
document.documentElement.classList.add("cursor-hidden");
|
|
642
|
+
} else {
|
|
643
|
+
this.hideVirtualCursor();
|
|
644
|
+
}
|
|
645
|
+
}
|
|
646
|
+
}
|
|
647
|
+
setCursorPos(x, y) {
|
|
648
|
+
const el = this.ensureCursorElement();
|
|
649
|
+
el.style.display = "block";
|
|
650
|
+
el.style.left = `${x}px`;
|
|
651
|
+
el.style.top = `${y}px`;
|
|
652
|
+
}
|
|
653
|
+
hideVirtualCursor() {
|
|
654
|
+
if (this.cursorEl) {
|
|
655
|
+
this.cursorEl.style.display = "none";
|
|
656
|
+
}
|
|
657
|
+
document.documentElement.classList.remove("cursor-hidden");
|
|
658
|
+
}
|
|
659
|
+
handleClick(e) {
|
|
660
|
+
if (!this.active) return;
|
|
661
|
+
this.lastCacheTime = 0;
|
|
662
|
+
if (this.isMagnetized && this.targetButton) {
|
|
663
|
+
if (!this.targetButton.contains(e.target)) {
|
|
664
|
+
e.preventDefault();
|
|
665
|
+
e.stopPropagation();
|
|
666
|
+
this.targetButton.click();
|
|
667
|
+
}
|
|
668
|
+
}
|
|
669
|
+
}
|
|
670
|
+
destroy() {
|
|
671
|
+
this.teardown();
|
|
672
|
+
}
|
|
673
|
+
}
|
|
674
|
+
class ScrollAssistController {
|
|
675
|
+
constructor() {
|
|
676
|
+
__publicField(this, "containerEl", null);
|
|
677
|
+
__publicField(this, "boundScroll", null);
|
|
678
|
+
}
|
|
679
|
+
update(active) {
|
|
680
|
+
if (!active) {
|
|
681
|
+
this.teardown();
|
|
682
|
+
return;
|
|
683
|
+
}
|
|
684
|
+
if (!this.containerEl) {
|
|
685
|
+
this.setup();
|
|
686
|
+
}
|
|
687
|
+
this.checkScrollLimits();
|
|
688
|
+
}
|
|
689
|
+
setup() {
|
|
690
|
+
this.containerEl = document.createElement("div");
|
|
691
|
+
this.containerEl.id = "cognitvs-a11y-scroll-assist";
|
|
692
|
+
this.containerEl.setAttribute("aria-label", "Assistente de Rolagem");
|
|
693
|
+
this.containerEl.style.cssText = `
|
|
694
|
+
position: fixed;
|
|
695
|
+
bottom: 24px;
|
|
696
|
+
left: 24px;
|
|
697
|
+
z-index: 999990;
|
|
698
|
+
display: flex;
|
|
699
|
+
flex-direction: column;
|
|
700
|
+
gap: 12px;
|
|
701
|
+
pointer-events: auto;
|
|
702
|
+
`;
|
|
703
|
+
const upBtn = document.createElement("button");
|
|
704
|
+
upBtn.id = "cognitvs-scroll-up";
|
|
705
|
+
upBtn.setAttribute("aria-label", "Rolar para cima");
|
|
706
|
+
upBtn.title = "Rolar para cima";
|
|
707
|
+
upBtn.innerHTML = `
|
|
708
|
+
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="3" stroke-linecap="round" stroke-linejoin="round">
|
|
709
|
+
<polyline points="18 15 12 9 6 15"></polyline>
|
|
710
|
+
</svg>
|
|
711
|
+
`;
|
|
712
|
+
this.styleButton(upBtn, false);
|
|
713
|
+
upBtn.onclick = () => window.scrollBy({ top: -window.innerHeight * 0.7, behavior: "smooth" });
|
|
714
|
+
const downBtn = document.createElement("button");
|
|
715
|
+
downBtn.id = "cognitvs-scroll-down";
|
|
716
|
+
downBtn.setAttribute("aria-label", "Rolar para baixo");
|
|
717
|
+
downBtn.title = "Rolar para baixo";
|
|
718
|
+
downBtn.innerHTML = `
|
|
719
|
+
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="3" stroke-linecap="round" stroke-linejoin="round">
|
|
720
|
+
<polyline points="6 9 12 15 18 9"></polyline>
|
|
721
|
+
</svg>
|
|
722
|
+
`;
|
|
723
|
+
this.styleButton(downBtn, true);
|
|
724
|
+
downBtn.onclick = () => window.scrollBy({ top: window.innerHeight * 0.7, behavior: "smooth" });
|
|
725
|
+
this.containerEl.appendChild(upBtn);
|
|
726
|
+
this.containerEl.appendChild(downBtn);
|
|
727
|
+
document.body.appendChild(this.containerEl);
|
|
728
|
+
this.boundScroll = this.checkScrollLimits.bind(this);
|
|
729
|
+
window.addEventListener("scroll", this.boundScroll, { passive: true });
|
|
730
|
+
}
|
|
731
|
+
styleButton(btn, isPrimary) {
|
|
732
|
+
btn.style.cssText = `
|
|
733
|
+
width: 52px;
|
|
734
|
+
height: 52px;
|
|
735
|
+
border-radius: 16px;
|
|
736
|
+
border: 2px solid ${isPrimary ? "#0077d4" : "rgba(0, 119, 212, 0.4)"};
|
|
737
|
+
background: ${isPrimary ? "#0077d4" : "#0f172a"};
|
|
738
|
+
color: #ffffff;
|
|
739
|
+
display: flex;
|
|
740
|
+
align-items: center;
|
|
741
|
+
justify-content: center;
|
|
742
|
+
cursor: pointer;
|
|
743
|
+
box-shadow: 0 10px 25px rgba(0, 0, 0, 0.35);
|
|
744
|
+
backdrop-filter: blur(8px);
|
|
745
|
+
transition: all 0.2s ease;
|
|
746
|
+
font-weight: bold;
|
|
747
|
+
`;
|
|
748
|
+
btn.onmouseenter = () => {
|
|
749
|
+
btn.style.transform = "scale(1.08)";
|
|
750
|
+
btn.style.background = isPrimary ? "#0066b8" : "#1e293b";
|
|
751
|
+
};
|
|
752
|
+
btn.onmouseleave = () => {
|
|
753
|
+
btn.style.transform = "scale(1)";
|
|
754
|
+
btn.style.background = isPrimary ? "#0077d4" : "#0f172a";
|
|
755
|
+
};
|
|
756
|
+
}
|
|
757
|
+
checkScrollLimits() {
|
|
758
|
+
if (!this.containerEl) return;
|
|
759
|
+
const isAtTop = window.scrollY < 20;
|
|
760
|
+
const isAtBottom = Math.ceil(window.innerHeight + window.scrollY) >= document.documentElement.scrollHeight - 20;
|
|
761
|
+
const upBtn = this.containerEl.querySelector("#cognitvs-scroll-up");
|
|
762
|
+
const downBtn = this.containerEl.querySelector("#cognitvs-scroll-down");
|
|
763
|
+
if (upBtn) upBtn.style.opacity = isAtTop ? "0.4" : "1";
|
|
764
|
+
if (downBtn) downBtn.style.opacity = isAtBottom ? "0.4" : "1";
|
|
765
|
+
}
|
|
766
|
+
teardown() {
|
|
767
|
+
if (this.boundScroll) {
|
|
768
|
+
window.removeEventListener("scroll", this.boundScroll);
|
|
769
|
+
this.boundScroll = null;
|
|
770
|
+
}
|
|
771
|
+
if (this.containerEl) {
|
|
772
|
+
this.containerEl.remove();
|
|
773
|
+
this.containerEl = null;
|
|
774
|
+
}
|
|
775
|
+
}
|
|
776
|
+
destroy() {
|
|
777
|
+
this.teardown();
|
|
778
|
+
}
|
|
779
|
+
}
|
|
780
|
+
class VLibrasController {
|
|
781
|
+
constructor() {
|
|
782
|
+
__publicField(this, "active", false);
|
|
783
|
+
__publicField(this, "scriptLoaded", false);
|
|
784
|
+
}
|
|
785
|
+
update(active) {
|
|
786
|
+
this.active = active;
|
|
787
|
+
const windowWithLibras = window;
|
|
788
|
+
if (!active) {
|
|
789
|
+
if (typeof windowWithLibras.toggleVLibras === "function") {
|
|
790
|
+
windowWithLibras.toggleVLibras(false);
|
|
791
|
+
}
|
|
792
|
+
return;
|
|
793
|
+
}
|
|
794
|
+
if (this.scriptLoaded && typeof windowWithLibras.toggleVLibras === "function") {
|
|
795
|
+
windowWithLibras.toggleVLibras(true);
|
|
796
|
+
return;
|
|
797
|
+
}
|
|
798
|
+
this.loadVLibras();
|
|
799
|
+
}
|
|
800
|
+
loadVLibras() {
|
|
801
|
+
if (document.getElementById("vlibras-plugin-container")) {
|
|
802
|
+
return;
|
|
803
|
+
}
|
|
804
|
+
const div = document.createElement("div");
|
|
805
|
+
div.id = "vlibras-plugin-container";
|
|
806
|
+
div.innerHTML = `
|
|
807
|
+
<div vw class="enabled">
|
|
808
|
+
<div vw-access-button class="active"></div>
|
|
809
|
+
<div vw-plugin-wrapper>
|
|
810
|
+
<div class="vw-plugin-top-wrapper"></div>
|
|
811
|
+
</div>
|
|
812
|
+
</div>
|
|
813
|
+
`;
|
|
814
|
+
document.body.appendChild(div);
|
|
815
|
+
const script = document.createElement("script");
|
|
816
|
+
script.id = "vlibras-official-script";
|
|
817
|
+
script.src = "https://vlibras.gov.br/app/vlibras-plugin.js";
|
|
818
|
+
script.async = true;
|
|
819
|
+
script.onload = () => {
|
|
820
|
+
this.scriptLoaded = true;
|
|
821
|
+
const win = window;
|
|
822
|
+
if (win.VLibras && win.VLibras.Widget) {
|
|
823
|
+
new win.VLibras.Widget("https://vlibras.gov.br/app");
|
|
824
|
+
}
|
|
825
|
+
};
|
|
826
|
+
document.head.appendChild(script);
|
|
827
|
+
}
|
|
828
|
+
destroy() {
|
|
829
|
+
if (this.active) {
|
|
830
|
+
this.update(false);
|
|
831
|
+
}
|
|
832
|
+
}
|
|
833
|
+
}
|
|
834
|
+
const A11Y_ICON_SVG = (size = 32) => `
|
|
835
|
+
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
|
|
836
|
+
width="${size}" height="${size}" viewBox="0 0 539.7 501.1" aria-hidden="true">
|
|
837
|
+
<!-- Estrutura principal (braços, pernas, arco superior/inferior, texto nós) -->
|
|
838
|
+
<path fill="currentColor" d="M268,276.6c-18.8,28.2-37,55.4-55.3,82.7c-14.9,22.3-29.7,44.6-44.8,66.8c-2.1,3-2.4,4.8,0.3,7.9
|
|
839
|
+
c11.2,13,10.9,32.4-0.1,45.5c-11.3,13.4-30.3,16.7-45.3,7.9c-15-8.8-21.5-27-15.5-43.3c6-16.1,22.6-25.7,39.5-22.6
|
|
840
|
+
c2.9,0.5,4.4,0.1,6.1-2.4c32.7-49.1,65.4-98.1,98.2-147.1c0.6-0.9,1.1-1.9,1.9-3.2c-9.2-1.1-18.1-1.8-26.9-3.2
|
|
841
|
+
c-43.2-6.6-84.4-20-124.9-36c-13.8-5.4-27.3-11.4-40.9-17.3c-2.6-1.1-4.4-1-6.8,0.4c-15.2,8.8-34.2,5.3-45.2-8
|
|
842
|
+
c-11-13.2-11-32.3-0.1-45.6c11-13.3,29.8-16.8,44.8-8.5c15.2,8.4,22.1,26.4,16.3,42.9c-0.9,2.7-1.3,4.1,2,5.5
|
|
843
|
+
c45.8,19.7,92.3,37.1,141.3,47.4c38.9,8.2,77.4,6.5,116.1-0.9c48.7-9.3,95.8-24.1,142.4-40.8c3.9-1.4,3.7-2.5,1.9-5.8
|
|
844
|
+
c-10.2-18.2-2.4-41.3,16.5-49.8c19-8.5,41.4,1.1,48.3,20.7c7,19.9-4.5,41.3-24.9,46.5c-5.9,1.5-11.9,1.6-17.8-0.2
|
|
845
|
+
c-3.1-1-5.6-0.7-8.6,0.4c-48.2,18.1-97.1,33.8-147.7,43.8c-18.3,3.6-36.8,6.3-55.4,7.6c-0.9,1.9,0.7,2.8,1.5,3.9
|
|
846
|
+
c32.8,49.2,65.7,98.3,98.4,147.5c1.8,2.7,3.3,3.2,6.4,2.4c17.2-4.2,34.2,4.3,41.2,20.2c7,15.9,1.5,34.5-13,44.1
|
|
847
|
+
c-14.3,9.5-33.3,7.4-45.3-5c-12-12.4-13.4-31.6-3.1-45.9c1.3-1.9,2.8-3.1,0.9-5.9c-33.8-50.3-67.4-100.7-101.1-151.1
|
|
848
|
+
C268.8,278.1,268.6,277.7,268,276.6z"/>
|
|
849
|
+
<!-- Arco superior -->
|
|
850
|
+
<path fill="currentColor" d="M268.9,0c94.9,3.7,167.9,44.9,217.2,126.7c2.1,3.6,1.5,5.1-2,6.5c-3.4,1.4-6.8,4.9-9.7,4.4
|
|
851
|
+
c-3.1-0.5-4.1-5.6-6-8.7C376.9-21.2,158.6-20.3,68.3,130.7c-2.6,4.3-4.2,5.4-8.7,2.3c-8.6-5.8-9-5.7-3.3-14.3
|
|
852
|
+
C101.9,48.4,166.3,8.8,250,1.1C256.3,0.5,262.6,0.3,268.9,0z"/>
|
|
853
|
+
<!-- Cabeça (anel externo) -->
|
|
854
|
+
<path fill="currentColor" d="M200.5,135.2c0.2-39,31.7-70.4,70.8-70.3c38.9,0.1,70.5,31.8,70.4,70.7c-0.1,39.1-31.8,70.7-71,70.5
|
|
855
|
+
C231.8,206,200.3,174.2,200.5,135.2z M325.1,135.4c-0.1-29.9-24.3-54.1-54-54.1c-29.9,0-54.2,24.6-54.1,54.6
|
|
856
|
+
c0.1,29.7,24.6,53.9,54.4,53.7C301.2,189.5,325.2,165.4,325.1,135.4z"/>
|
|
857
|
+
<!-- Arco lateral esquerdo -->
|
|
858
|
+
<path fill="currentColor" d="M35.1,255.4c2,61.5,23.9,114.7,66.9,158.9c3,3.1,3.4,4.6,0.1,7.7c-8.3,7.9-8.2,8.2-15.9-0.2
|
|
859
|
+
C39,370.2,16.7,309.3,18.9,239.4c0.1-3.1,0.7-4.6,4.2-4.2c3.9,0.4,9.1-1.1,11.6,0.8c2.8,2.2,0.2,7.4,0.5,11.4
|
|
860
|
+
C35.3,250.1,35.1,252.7,35.1,255.4z"/>
|
|
861
|
+
<!-- Arco lateral direito -->
|
|
862
|
+
<path fill="currentColor" d="M518.9,252.8c-1.4,66.4-24.6,123.9-70.4,172.2c-2.7,2.8-4.4,3.1-6.9,0.1c-2.4-2.9-7.5-4.8-7.5-8.1
|
|
863
|
+
c0-2.7,4.3-5.4,6.8-8.1c43.4-48.2,63.8-104.7,61.2-169.5c-0.1-3.4,0.4-4.6,4.1-4.5c12.6,0.1,12.6,0,12.7,12.4
|
|
864
|
+
C518.9,249.2,518.9,251,518.9,252.8z"/>
|
|
865
|
+
<!-- Arco inferior -->
|
|
866
|
+
<path fill="currentColor" d="M268.6,501.1c-28.7,0-56.6-4.9-83.7-14.3c-3.5-1.2-5-2.5-2.9-6.2c1.9-3.3,1.7-8.7,4.8-10
|
|
867
|
+
c2.6-1.1,6.8,1.7,10.2,2.8c51.1,16,101.9,15.1,152.3-3.1c3.8-1.4,5.3-0.9,6.7,3c3.9,11,4.1,10.9-6.9,14.7
|
|
868
|
+
C323.3,496.7,296.3,501.1,268.6,501.1z"/>
|
|
869
|
+
<!-- Nós de destaque (azul ciano — mantido como identidade visual do ícone) -->
|
|
870
|
+
<circle fill="#44A5DD" cx="398" cy="456.5" r="19.3"/>
|
|
871
|
+
<circle fill="#44A5DD" cx="505.1" cy="181.9" r="19.3"/>
|
|
872
|
+
<circle fill="#44A5DD" cx="140.6" cy="456.6" r="19.1"/>
|
|
873
|
+
<circle fill="#44A5DD" cx="35.8" cy="181.8" r="19.2"/>
|
|
874
|
+
<!-- Cabeça (preenchimento interno azul) -->
|
|
875
|
+
<path fill="#44A5DD" d="M325.1,135.4c0.1,30-23.9,54.1-53.7,54.3c-29.8,0.1-54.3-24-54.4-53.7c-0.1-30,24.2-54.6,54.1-54.6
|
|
876
|
+
C300.8,81.4,325,105.6,325.1,135.4z"/>
|
|
877
|
+
</svg>
|
|
878
|
+
`.trim();
|
|
879
|
+
class CognitvsA11yWidget extends HTMLElement {
|
|
880
|
+
constructor() {
|
|
881
|
+
super();
|
|
882
|
+
__publicField(this, "shadow");
|
|
883
|
+
__publicField(this, "store");
|
|
884
|
+
__publicField(this, "domEffects");
|
|
885
|
+
__publicField(this, "tts");
|
|
886
|
+
__publicField(this, "cursorMagnet");
|
|
887
|
+
__publicField(this, "scrollAssist");
|
|
888
|
+
__publicField(this, "vlibras");
|
|
889
|
+
__publicField(this, "unsubscribe", null);
|
|
890
|
+
__publicField(this, "tourTimeoutId", null);
|
|
891
|
+
__publicField(this, "resizeRafId", null);
|
|
892
|
+
__publicField(this, "onViewportChange", () => {
|
|
893
|
+
if (this.resizeRafId) {
|
|
894
|
+
cancelAnimationFrame(this.resizeRafId);
|
|
895
|
+
}
|
|
896
|
+
this.resizeRafId = requestAnimationFrame(() => {
|
|
897
|
+
this.updatePanelDimensions();
|
|
898
|
+
});
|
|
899
|
+
});
|
|
900
|
+
this.shadow = this.attachShadow({ mode: "open" });
|
|
901
|
+
const prefix = this.getAttribute("storage-prefix") || "cognitvs";
|
|
902
|
+
this.store = new A11yStore(prefix);
|
|
903
|
+
this.domEffects = new DomEffectsManager();
|
|
904
|
+
this.tts = new TTSController((node) => this.contains(node) || this.shadow.contains(node));
|
|
905
|
+
this.cursorMagnet = new CursorMagnetController();
|
|
906
|
+
this.scrollAssist = new ScrollAssistController();
|
|
907
|
+
this.vlibras = new VLibrasController();
|
|
908
|
+
}
|
|
909
|
+
static get observedAttributes() {
|
|
910
|
+
return ["theme", "accent-color", "position", "storage-prefix", "show-banner"];
|
|
911
|
+
}
|
|
912
|
+
attributeChangedCallback(name, oldValue, newValue) {
|
|
913
|
+
if (oldValue === newValue) return;
|
|
914
|
+
if (name === "accent-color" && newValue) {
|
|
915
|
+
this.style.setProperty("--a11y-primary", newValue);
|
|
916
|
+
}
|
|
917
|
+
}
|
|
918
|
+
connectedCallback() {
|
|
919
|
+
this.injectGlobalStyles();
|
|
920
|
+
this.renderInitialShadow();
|
|
921
|
+
window.addEventListener("resize", this.onViewportChange, { passive: true });
|
|
922
|
+
window.addEventListener("scroll", this.onViewportChange, { passive: true });
|
|
923
|
+
const state = this.store.getState();
|
|
924
|
+
if (!state.hasInteracted) {
|
|
925
|
+
this.tourTimeoutId = window.setTimeout(() => {
|
|
926
|
+
if (!this.store.getState().isExpanded && !this.store.getState().hasInteracted) {
|
|
927
|
+
this.store.update({ showAttentionGrabber: true });
|
|
928
|
+
}
|
|
929
|
+
}, 3500);
|
|
930
|
+
}
|
|
931
|
+
this.unsubscribe = this.store.subscribe((currState) => {
|
|
932
|
+
this.domEffects.applyGlobalState(currState);
|
|
933
|
+
this.tts.update(currState.isTTSActive, currState.ttsRate);
|
|
934
|
+
this.cursorMagnet.update(currState.isCursorMagnetActive, currState.cursorMagnetForce, currState.isBigCursor);
|
|
935
|
+
this.scrollAssist.update(currState.isScrollAssistActive);
|
|
936
|
+
this.vlibras.update(currState.isVLibrasActive);
|
|
937
|
+
this.updateShadowUI(currState);
|
|
938
|
+
});
|
|
939
|
+
requestAnimationFrame(() => this.updatePanelDimensions());
|
|
940
|
+
setTimeout(() => this.updatePanelDimensions(), 50);
|
|
941
|
+
setTimeout(() => this.updatePanelDimensions(), 250);
|
|
942
|
+
}
|
|
943
|
+
disconnectedCallback() {
|
|
944
|
+
window.removeEventListener("resize", this.onViewportChange);
|
|
945
|
+
window.removeEventListener("scroll", this.onViewportChange);
|
|
946
|
+
if (this.resizeRafId) {
|
|
947
|
+
cancelAnimationFrame(this.resizeRafId);
|
|
948
|
+
}
|
|
949
|
+
document.body.classList.remove("a11y-banner-active");
|
|
950
|
+
if (this.unsubscribe) {
|
|
951
|
+
this.unsubscribe();
|
|
952
|
+
this.unsubscribe = null;
|
|
953
|
+
}
|
|
954
|
+
if (this.tourTimeoutId) {
|
|
955
|
+
clearTimeout(this.tourTimeoutId);
|
|
956
|
+
}
|
|
957
|
+
this.domEffects.destroy();
|
|
958
|
+
this.tts.destroy();
|
|
959
|
+
this.cursorMagnet.destroy();
|
|
960
|
+
this.scrollAssist.destroy();
|
|
961
|
+
this.vlibras.destroy();
|
|
962
|
+
}
|
|
963
|
+
injectGlobalStyles() {
|
|
964
|
+
const styleId = "cognitvs-a11y-global-styles";
|
|
965
|
+
if (!document.getElementById(styleId)) {
|
|
966
|
+
const style = document.createElement("style");
|
|
967
|
+
style.id = styleId;
|
|
968
|
+
style.textContent = globalCss;
|
|
969
|
+
document.head.appendChild(style);
|
|
970
|
+
}
|
|
971
|
+
}
|
|
972
|
+
renderInitialShadow() {
|
|
973
|
+
const showBanner = this.getAttribute("show-banner") !== "false";
|
|
974
|
+
const accent = this.getAttribute("accent-color");
|
|
975
|
+
if (accent) {
|
|
976
|
+
this.style.setProperty("--a11y-primary", accent);
|
|
977
|
+
}
|
|
978
|
+
this.shadow.innerHTML = `
|
|
979
|
+
<style>${widgetCss}</style>
|
|
980
|
+
${showBanner ? `
|
|
981
|
+
<div id="a11y-top-banner" class="a11y-top-banner" role="banner">
|
|
982
|
+
<div class="a11y-banner-content">
|
|
983
|
+
<span class="a11y-banner-icon" aria-hidden="true">
|
|
984
|
+
${A11Y_ICON_SVG(26)}
|
|
985
|
+
</span>
|
|
986
|
+
<p class="a11y-banner-text">
|
|
987
|
+
<strong>Acessibilidade:</strong> Personalize sua navegação clicando no botão no canto da tela.
|
|
988
|
+
</p>
|
|
989
|
+
</div>
|
|
990
|
+
<button id="banner-close-btn" class="a11y-banner-close" aria-label="Dispensar aviso de acessibilidade">✕</button>
|
|
991
|
+
</div>
|
|
992
|
+
` : ""}
|
|
993
|
+
|
|
994
|
+
<div class="a11y-widget-root">
|
|
995
|
+
<!-- Painel Expansível -->
|
|
996
|
+
<div id="a11y-panel" class="a11y-panel closed" role="region" aria-label="Painel de Ferramentas de Acessibilidade">
|
|
997
|
+
<div class="a11y-panel-header">
|
|
998
|
+
<div class="a11y-panel-title">
|
|
999
|
+
${A11Y_ICON_SVG(18)}
|
|
1000
|
+
ACESSIBILIDADE
|
|
1001
|
+
</div>
|
|
1002
|
+
<button id="panel-close-btn" class="a11y-btn-mini" style="flex:0; width:28px; padding:4px;" aria-label="Fechar painel">✕</button>
|
|
1003
|
+
</div>
|
|
1004
|
+
|
|
1005
|
+
<div>
|
|
1006
|
+
<label class="a11y-section-title" for="profile-select">Perfil Assistivo</label>
|
|
1007
|
+
<select id="profile-select" class="a11y-profile-select">
|
|
1008
|
+
<option value="all">Ver Todos os Recursos</option>
|
|
1009
|
+
<option value="vision">👁️ Visão Reduzida</option>
|
|
1010
|
+
<option value="hearing">🧏 Audição / Surdez</option>
|
|
1011
|
+
<option value="motor">🎯 Dificuldade Motora</option>
|
|
1012
|
+
<option value="cognitive">🧠 TDAH e Foco</option>
|
|
1013
|
+
</select>
|
|
1014
|
+
</div>
|
|
1015
|
+
|
|
1016
|
+
<div id="a11y-feature-container"></div>
|
|
1017
|
+
|
|
1018
|
+
<button id="reset-btn" class="a11y-reset-btn">Resetar Preferências</button>
|
|
1019
|
+
</div>
|
|
1020
|
+
|
|
1021
|
+
<!-- Botão Flutuante e Dica -->
|
|
1022
|
+
<div class="a11y-fab-wrapper">
|
|
1023
|
+
<div id="tour-bubble" class="a11y-tour-bubble" style="display: none;">
|
|
1024
|
+
<span style="font-size: 20px;">👋</span>
|
|
1025
|
+
<p style="font-size: 11px; font-weight: bold; line-height: 1.3;">Dificuldade para navegar? Clique aqui!</p>
|
|
1026
|
+
</div>
|
|
1027
|
+
<div id="ping-ring" class="a11y-ping-ring" style="display: none;"></div>
|
|
1028
|
+
|
|
1029
|
+
<button id="fab-btn" class="a11y-fab" aria-label="Abrir recursos de acessibilidade" aria-haspopup="true">
|
|
1030
|
+
${A11Y_ICON_SVG(34)}
|
|
1031
|
+
</button>
|
|
1032
|
+
</div>
|
|
1033
|
+
</div>
|
|
1034
|
+
`;
|
|
1035
|
+
this.bindEvents();
|
|
1036
|
+
}
|
|
1037
|
+
bindEvents() {
|
|
1038
|
+
const fabBtn = this.shadow.querySelector("#fab-btn");
|
|
1039
|
+
const panelCloseBtn = this.shadow.querySelector("#panel-close-btn");
|
|
1040
|
+
const bannerCloseBtn = this.shadow.querySelector("#banner-close-btn");
|
|
1041
|
+
const tourBubble = this.shadow.querySelector("#tour-bubble");
|
|
1042
|
+
const resetBtn = this.shadow.querySelector("#reset-btn");
|
|
1043
|
+
const profileSelect = this.shadow.querySelector("#profile-select");
|
|
1044
|
+
fabBtn == null ? void 0 : fabBtn.addEventListener("click", () => this.store.toggleExpanded());
|
|
1045
|
+
panelCloseBtn == null ? void 0 : panelCloseBtn.addEventListener("click", () => this.store.toggleExpanded());
|
|
1046
|
+
tourBubble == null ? void 0 : tourBubble.addEventListener("click", () => this.store.toggleExpanded());
|
|
1047
|
+
bannerCloseBtn == null ? void 0 : bannerCloseBtn.addEventListener("click", () => this.store.dismissBanner());
|
|
1048
|
+
resetBtn == null ? void 0 : resetBtn.addEventListener("click", () => this.store.resetAll());
|
|
1049
|
+
profileSelect == null ? void 0 : profileSelect.addEventListener("change", (e) => {
|
|
1050
|
+
const val = e.target.value;
|
|
1051
|
+
this.store.setActiveProfile(val);
|
|
1052
|
+
});
|
|
1053
|
+
}
|
|
1054
|
+
updateShadowUI(state) {
|
|
1055
|
+
const banner = this.shadow.querySelector("#a11y-top-banner");
|
|
1056
|
+
if (banner) {
|
|
1057
|
+
if (state.bannerDismissed) {
|
|
1058
|
+
banner.classList.add("hidden");
|
|
1059
|
+
document.body.classList.remove("a11y-banner-active");
|
|
1060
|
+
document.documentElement.style.setProperty("--a11y-top-banner-height", "0px");
|
|
1061
|
+
} else {
|
|
1062
|
+
banner.classList.remove("hidden");
|
|
1063
|
+
document.body.classList.add("a11y-banner-active");
|
|
1064
|
+
}
|
|
1065
|
+
}
|
|
1066
|
+
const panel = this.shadow.querySelector("#a11y-panel");
|
|
1067
|
+
const fab = this.shadow.querySelector("#fab-btn");
|
|
1068
|
+
if (panel) {
|
|
1069
|
+
if (state.isExpanded) {
|
|
1070
|
+
panel.classList.remove("closed");
|
|
1071
|
+
} else {
|
|
1072
|
+
panel.classList.add("closed");
|
|
1073
|
+
}
|
|
1074
|
+
}
|
|
1075
|
+
if (fab) {
|
|
1076
|
+
fab.innerHTML = state.isExpanded ? `<span style="font-size:24px; font-weight:900;">✕</span>` : A11Y_ICON_SVG(34);
|
|
1077
|
+
}
|
|
1078
|
+
const tourBubble = this.shadow.querySelector("#tour-bubble");
|
|
1079
|
+
const pingRing = this.shadow.querySelector("#ping-ring");
|
|
1080
|
+
if (tourBubble) tourBubble.style.display = state.showAttentionGrabber ? "flex" : "none";
|
|
1081
|
+
if (pingRing) pingRing.style.display = state.showAttentionGrabber ? "block" : "none";
|
|
1082
|
+
const profileSelect = this.shadow.querySelector("#profile-select");
|
|
1083
|
+
if (profileSelect && profileSelect.value !== state.activeProfile) {
|
|
1084
|
+
profileSelect.value = state.activeProfile;
|
|
1085
|
+
}
|
|
1086
|
+
this.renderFeatureButtons(state);
|
|
1087
|
+
this.updatePanelDimensions();
|
|
1088
|
+
}
|
|
1089
|
+
updatePanelDimensions() {
|
|
1090
|
+
const panel = this.shadow.querySelector("#a11y-panel");
|
|
1091
|
+
const banner = this.shadow.querySelector("#a11y-top-banner");
|
|
1092
|
+
const root = this.shadow.querySelector(".a11y-widget-root");
|
|
1093
|
+
if (!panel || !root) return;
|
|
1094
|
+
let bannerHeight = 0;
|
|
1095
|
+
const isBannerDismissed = this.store.getState().bannerDismissed;
|
|
1096
|
+
if (banner && !isBannerDismissed) {
|
|
1097
|
+
bannerHeight = banner.getBoundingClientRect().height || banner.offsetHeight || 0;
|
|
1098
|
+
}
|
|
1099
|
+
document.documentElement.style.setProperty("--a11y-top-banner-height", `${bannerHeight}px`);
|
|
1100
|
+
if (bannerHeight > 0) {
|
|
1101
|
+
document.body.classList.add("a11y-banner-active");
|
|
1102
|
+
} else {
|
|
1103
|
+
document.body.classList.remove("a11y-banner-active");
|
|
1104
|
+
}
|
|
1105
|
+
let hostHeaderBottom = 0;
|
|
1106
|
+
const customHeaderH = parseFloat(
|
|
1107
|
+
getComputedStyle(document.documentElement).getPropertyValue("--a11y-header-height") || "0"
|
|
1108
|
+
);
|
|
1109
|
+
if (customHeaderH > 0) {
|
|
1110
|
+
hostHeaderBottom = customHeaderH;
|
|
1111
|
+
} else {
|
|
1112
|
+
const candidates = document.querySelectorAll(
|
|
1113
|
+
'header, nav, [role="banner"], .header, .site-header, .navbar, .top-bar'
|
|
1114
|
+
);
|
|
1115
|
+
for (const el of candidates) {
|
|
1116
|
+
const style = window.getComputedStyle(el);
|
|
1117
|
+
if (style.position === "fixed" || style.position === "sticky") {
|
|
1118
|
+
const rect = el.getBoundingClientRect();
|
|
1119
|
+
if (rect.top <= 10 && rect.bottom > hostHeaderBottom && rect.bottom < window.innerHeight * 0.45) {
|
|
1120
|
+
hostHeaderBottom = rect.bottom;
|
|
1121
|
+
}
|
|
1122
|
+
}
|
|
1123
|
+
}
|
|
1124
|
+
}
|
|
1125
|
+
const rootRect = root.getBoundingClientRect();
|
|
1126
|
+
const bottomDist = Math.max(0, window.innerHeight - rootRect.bottom);
|
|
1127
|
+
const fabWrapper = this.shadow.querySelector(".a11y-fab-wrapper");
|
|
1128
|
+
const fabHeight = fabWrapper ? fabWrapper.offsetHeight : 56;
|
|
1129
|
+
const gap = 12;
|
|
1130
|
+
const PANEL_TOP_MARGIN = 24;
|
|
1131
|
+
const topObstacle = Math.max(bannerHeight, hostHeaderBottom);
|
|
1132
|
+
const totalTopReserved = topObstacle + PANEL_TOP_MARGIN;
|
|
1133
|
+
const availableHeight = window.innerHeight - totalTopReserved - bottomDist - fabHeight - gap;
|
|
1134
|
+
const finalMaxHeight = Math.max(160, Math.floor(availableHeight));
|
|
1135
|
+
panel.style.setProperty("--fab-panel-max-height", `${finalMaxHeight}px`);
|
|
1136
|
+
if (this.store.getState().isExpanded) {
|
|
1137
|
+
panel.style.maxHeight = `${finalMaxHeight}px`;
|
|
1138
|
+
} else {
|
|
1139
|
+
panel.style.maxHeight = "0px";
|
|
1140
|
+
}
|
|
1141
|
+
}
|
|
1142
|
+
renderFeatureButtons(state) {
|
|
1143
|
+
const container = this.shadow.querySelector("#a11y-feature-container");
|
|
1144
|
+
if (!container) return;
|
|
1145
|
+
const p = state.activeProfile;
|
|
1146
|
+
let html = "";
|
|
1147
|
+
if (["all", "vision", "cognitive"].includes(p)) {
|
|
1148
|
+
html += `<div class="a11y-section-title">Ajustes Visuais</div>`;
|
|
1149
|
+
html += `
|
|
1150
|
+
<div class="a11y-scale-box">
|
|
1151
|
+
<button id="btn-scale-down" class="a11y-scale-btn" aria-label="Diminuir texto">A-</button>
|
|
1152
|
+
<span class="a11y-scale-val">${Math.round(state.fontScale * 100)}%</span>
|
|
1153
|
+
<button id="btn-scale-up" class="a11y-scale-btn" aria-label="Aumentar texto">A+</button>
|
|
1154
|
+
</div>
|
|
1155
|
+
`;
|
|
1156
|
+
html += `
|
|
1157
|
+
<button id="btn-contrast" class="a11y-btn ${state.isHighContrast ? "active" : ""}">
|
|
1158
|
+
<span>${state.isHighContrast ? "☀️" : "👁️"}</span>
|
|
1159
|
+
<span>${state.isHighContrast ? "Contraste Ativo" : "Alto Contraste"}</span>
|
|
1160
|
+
</button>
|
|
1161
|
+
`;
|
|
1162
|
+
html += `
|
|
1163
|
+
<div style="display:flex; flex-direction:column; gap:4px; margin-top:4px;">
|
|
1164
|
+
<button id="btn-mask" class="a11y-btn ${state.isReadingMaskActive ? "active" : ""}">
|
|
1165
|
+
<span>${state.isReadingMaskActive ? "📖" : "📏"}</span>
|
|
1166
|
+
<span>${state.isReadingMaskActive ? "Máscara Ativa" : "Máscara de Leitura"}</span>
|
|
1167
|
+
</button>
|
|
1168
|
+
${state.isReadingMaskActive ? `
|
|
1169
|
+
<div class="a11y-btn-group" style="padding-left:4px;">
|
|
1170
|
+
<button id="mask-mode-smart" class="a11y-btn-mini ${state.isReadingMaskSmart ? "active" : ""}">🧠 Inteligente</button>
|
|
1171
|
+
<button id="mask-mode-free" class="a11y-btn-mini ${!state.isReadingMaskSmart ? "active" : ""}">🆓 Livre</button>
|
|
1172
|
+
</div>
|
|
1173
|
+
` : ""}
|
|
1174
|
+
</div>
|
|
1175
|
+
`;
|
|
1176
|
+
html += `
|
|
1177
|
+
<div style="display:flex; flex-direction:column; gap:4px; margin-top:4px;">
|
|
1178
|
+
<label class="a11y-section-title" style="margin:0;">Filtros de Daltonismo</label>
|
|
1179
|
+
<select id="select-daltonism" class="a11y-profile-select">
|
|
1180
|
+
<option value="none" ${state.colorBlindMode === "none" ? "selected" : ""}>Padrão (Desativado)</option>
|
|
1181
|
+
<option value="protanopia" ${state.colorBlindMode === "protanopia" ? "selected" : ""}>Protanopia</option>
|
|
1182
|
+
<option value="deuteranopia" ${state.colorBlindMode === "deuteranopia" ? "selected" : ""}>Deuteranopia</option>
|
|
1183
|
+
<option value="tritanopia" ${state.colorBlindMode === "tritanopia" ? "selected" : ""}>Tritanopia</option>
|
|
1184
|
+
<option value="monochromacy" ${state.colorBlindMode === "monochromacy" ? "selected" : ""}>Monocromia</option>
|
|
1185
|
+
</select>
|
|
1186
|
+
</div>
|
|
1187
|
+
`;
|
|
1188
|
+
}
|
|
1189
|
+
if (["all", "hearing", "cognitive"].includes(p)) {
|
|
1190
|
+
html += `<div class="a11y-section-title">Audição e Leitura</div>`;
|
|
1191
|
+
html += `
|
|
1192
|
+
<div style="display:flex; flex-direction:column; gap:4px;">
|
|
1193
|
+
<button id="btn-tts" class="a11y-btn ${state.isTTSActive ? "active" : ""}">
|
|
1194
|
+
<span>${state.isTTSActive ? "🔊" : "🔈"}</span>
|
|
1195
|
+
<span>${state.isTTSActive ? "Leitor Ativo (Clique no Texto)" : "Leitor de Tela"}</span>
|
|
1196
|
+
</button>
|
|
1197
|
+
${state.isTTSActive ? `
|
|
1198
|
+
<div class="a11y-btn-group">
|
|
1199
|
+
<button id="tts-rate-05" class="a11y-btn-mini ${state.ttsRate === 0.5 ? "active" : ""}">🐢 0.5x</button>
|
|
1200
|
+
<button id="tts-rate-1" class="a11y-btn-mini ${state.ttsRate === 1 ? "active" : ""}">🚶 1.0x</button>
|
|
1201
|
+
<button id="tts-rate-15" class="a11y-btn-mini ${state.ttsRate === 1.5 ? "active" : ""}">🐇 1.5x</button>
|
|
1202
|
+
</div>
|
|
1203
|
+
` : ""}
|
|
1204
|
+
</div>
|
|
1205
|
+
`;
|
|
1206
|
+
html += `
|
|
1207
|
+
<button id="btn-vlibras" class="a11y-btn ${state.isVLibrasActive ? "active" : ""}">
|
|
1208
|
+
<span>${state.isVLibrasActive ? "🤟" : "👐"}</span>
|
|
1209
|
+
<span>${state.isVLibrasActive ? "LIBRAS Ativo" : "Tradutor LIBRAS"}</span>
|
|
1210
|
+
</button>
|
|
1211
|
+
`;
|
|
1212
|
+
}
|
|
1213
|
+
if (["all", "motor", "vision"].includes(p)) {
|
|
1214
|
+
html += `<div class="a11y-section-title">Interação e Mobilidade</div>`;
|
|
1215
|
+
html += `
|
|
1216
|
+
<button id="btn-big-cursor" class="a11y-btn ${state.isBigCursor ? "active" : ""}">
|
|
1217
|
+
<span>${state.isBigCursor ? "↖️" : "🖱️"}</span>
|
|
1218
|
+
<span>${state.isBigCursor ? "Ponteiro Gigante Ativo" : "Ponteiro Gigante"}</span>
|
|
1219
|
+
</button>
|
|
1220
|
+
`;
|
|
1221
|
+
html += `
|
|
1222
|
+
<button id="btn-keyboard-focus" class="a11y-btn ${state.isKeyboardFocus ? "active" : ""}">
|
|
1223
|
+
<span>${state.isKeyboardFocus ? "🎯" : "⌨️"}</span>
|
|
1224
|
+
<span>${state.isKeyboardFocus ? "Foco Teclado Ativo" : "Foco por Teclado"}</span>
|
|
1225
|
+
</button>
|
|
1226
|
+
`;
|
|
1227
|
+
html += `
|
|
1228
|
+
<button id="btn-scroll-assist" class="a11y-btn ${state.isScrollAssistActive ? "active" : ""}">
|
|
1229
|
+
<span>${state.isScrollAssistActive ? "↕️" : "🖱️"}</span>
|
|
1230
|
+
<span>${state.isScrollAssistActive ? "Rolagem Assistida Ativa" : "Rolagem Assistida"}</span>
|
|
1231
|
+
</button>
|
|
1232
|
+
`;
|
|
1233
|
+
html += `
|
|
1234
|
+
<div style="display:flex; flex-direction:column; gap:4px;">
|
|
1235
|
+
<button id="btn-cursor-magnet" class="a11y-btn ${state.isCursorMagnetActive ? "active" : ""}">
|
|
1236
|
+
<span>🧲</span>
|
|
1237
|
+
<span>${state.isCursorMagnetActive ? "Ímã de Cursor Ativo" : "Ímã de Cursor"}</span>
|
|
1238
|
+
</button>
|
|
1239
|
+
${state.isCursorMagnetActive ? `
|
|
1240
|
+
<div class="a11y-btn-group">
|
|
1241
|
+
<button id="magnet-force-suave" class="a11y-btn-mini ${state.cursorMagnetForce === "suave" ? "active" : ""}">🪶 Suave</button>
|
|
1242
|
+
<button id="magnet-force-forte" class="a11y-btn-mini ${state.cursorMagnetForce === "forte" ? "active" : ""}">🧲 Forte</button>
|
|
1243
|
+
</div>
|
|
1244
|
+
` : ""}
|
|
1245
|
+
</div>
|
|
1246
|
+
`;
|
|
1247
|
+
html += `
|
|
1248
|
+
<button id="btn-highlight-links" class="a11y-btn ${state.isHighlightLinks ? "active" : ""}">
|
|
1249
|
+
<span>🔗</span>
|
|
1250
|
+
<span>${state.isHighlightLinks ? "Links Destacados" : "Destacar Links"}</span>
|
|
1251
|
+
</button>
|
|
1252
|
+
`;
|
|
1253
|
+
}
|
|
1254
|
+
if (["all", "cognitive"].includes(p)) {
|
|
1255
|
+
html += `<div class="a11y-section-title">Ajustes Cognitivos</div>`;
|
|
1256
|
+
html += `
|
|
1257
|
+
<button id="btn-reduce-motion" class="a11y-btn ${state.isReduceMotion ? "active" : ""}">
|
|
1258
|
+
<span>${state.isReduceMotion ? "⏸️" : "✨"}</span>
|
|
1259
|
+
<span>${state.isReduceMotion ? "Animações Pausadas" : "Pausar Animações"}</span>
|
|
1260
|
+
</button>
|
|
1261
|
+
`;
|
|
1262
|
+
html += `
|
|
1263
|
+
<button id="btn-dyslexia" class="a11y-btn ${state.isDyslexiaMode ? "active" : ""}">
|
|
1264
|
+
<span>${state.isDyslexiaMode ? "📖" : "🅰️"}</span>
|
|
1265
|
+
<span>${state.isDyslexiaMode ? "Fonte Dislexia Ativa" : "Ajuste para Dislexia"}</span>
|
|
1266
|
+
</button>
|
|
1267
|
+
`;
|
|
1268
|
+
html += `
|
|
1269
|
+
<div style="display:flex; flex-direction:column; gap:4px;">
|
|
1270
|
+
<label class="a11y-section-title" style="margin:0;">Espaçamento de Texto</label>
|
|
1271
|
+
<div class="a11y-btn-group">
|
|
1272
|
+
<button id="spacing-0" class="a11y-btn-mini ${state.textSpacingLevel === 0 ? "active" : ""}">Padrão</button>
|
|
1273
|
+
<button id="spacing-1" class="a11y-btn-mini ${state.textSpacingLevel === 1 ? "active" : ""}">Espaçado</button>
|
|
1274
|
+
<button id="spacing-2" class="a11y-btn-mini ${state.textSpacingLevel === 2 ? "active" : ""}">Largo</button>
|
|
1275
|
+
</div>
|
|
1276
|
+
</div>
|
|
1277
|
+
`;
|
|
1278
|
+
}
|
|
1279
|
+
container.innerHTML = html;
|
|
1280
|
+
this.bindFeatureButtons();
|
|
1281
|
+
}
|
|
1282
|
+
bindFeatureButtons() {
|
|
1283
|
+
var _a;
|
|
1284
|
+
const bind = (id, fn) => {
|
|
1285
|
+
var _a2;
|
|
1286
|
+
(_a2 = this.shadow.querySelector(`#${id}`)) == null ? void 0 : _a2.addEventListener("click", fn);
|
|
1287
|
+
};
|
|
1288
|
+
bind("btn-scale-down", () => this.store.updateFontScale(-0.1));
|
|
1289
|
+
bind("btn-scale-up", () => this.store.updateFontScale(0.1));
|
|
1290
|
+
bind("btn-contrast", () => this.store.toggleHighContrast());
|
|
1291
|
+
bind("btn-mask", () => this.store.toggleReadingMask());
|
|
1292
|
+
bind("mask-mode-smart", () => this.store.setReadingMaskSmart(true));
|
|
1293
|
+
bind("mask-mode-free", () => this.store.setReadingMaskSmart(false));
|
|
1294
|
+
bind("btn-tts", () => this.store.toggleTTS());
|
|
1295
|
+
bind("tts-rate-05", () => this.store.setTTSRate(0.5));
|
|
1296
|
+
bind("tts-rate-1", () => this.store.setTTSRate(1));
|
|
1297
|
+
bind("tts-rate-15", () => this.store.setTTSRate(1.5));
|
|
1298
|
+
bind("btn-vlibras", () => this.store.toggleVLibras());
|
|
1299
|
+
bind("btn-big-cursor", () => this.store.toggleBigCursor());
|
|
1300
|
+
bind("btn-keyboard-focus", () => this.store.toggleKeyboardFocus());
|
|
1301
|
+
bind("btn-scroll-assist", () => this.store.toggleScrollAssist());
|
|
1302
|
+
bind("btn-cursor-magnet", () => this.store.toggleCursorMagnet());
|
|
1303
|
+
bind("magnet-force-suave", () => this.store.setCursorMagnetForce("suave"));
|
|
1304
|
+
bind("magnet-force-forte", () => this.store.setCursorMagnetForce("forte"));
|
|
1305
|
+
bind("btn-highlight-links", () => this.store.toggleHighlightLinks());
|
|
1306
|
+
bind("btn-reduce-motion", () => this.store.toggleReduceMotion());
|
|
1307
|
+
bind("btn-dyslexia", () => this.store.toggleDyslexia());
|
|
1308
|
+
bind("spacing-0", () => this.store.setTextSpacing(0));
|
|
1309
|
+
bind("spacing-1", () => this.store.setTextSpacing(1));
|
|
1310
|
+
bind("spacing-2", () => this.store.setTextSpacing(2));
|
|
1311
|
+
(_a = this.shadow.querySelector("#select-daltonism")) == null ? void 0 : _a.addEventListener("change", (e) => {
|
|
1312
|
+
const val = e.target.value;
|
|
1313
|
+
this.store.setColorBlindMode(val);
|
|
1314
|
+
});
|
|
1315
|
+
}
|
|
1316
|
+
}
|
|
1317
|
+
if (typeof window !== "undefined" && !customElements.get("cognitvs-a11y")) {
|
|
1318
|
+
customElements.define("cognitvs-a11y", CognitvsA11yWidget);
|
|
1319
|
+
}
|
|
1320
|
+
export {
|
|
1321
|
+
A11yStore,
|
|
1322
|
+
CognitvsA11yWidget,
|
|
1323
|
+
CognitvsA11yWidget as default
|
|
1324
|
+
};
|
|
1325
|
+
//# sourceMappingURL=a11y-widget.js.map
|