react-lgpd-consent 0.3.7 → 0.4.1

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/index.cjs CHANGED
@@ -30,185 +30,266 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
30
30
  ));
31
31
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
32
32
 
33
- // src/utils/developerGuidance.ts
34
- function analyzeDeveloperConfiguration(config) {
35
- const guidance = {
36
- warnings: [],
37
- suggestions: [],
38
- activeCategoriesInfo: [],
39
- usingDefaults: !config
40
- };
41
- const finalConfig = config || DEFAULT_PROJECT_CATEGORIES;
42
- if (!config) {
43
- guidance.warnings.push(
44
- 'LGPD-CONSENT: Nenhuma configura\xE7\xE3o de categorias especificada. Usando padr\xE3o: necessary + analytics. Para produ\xE7\xE3o, recomenda-se especificar explicitamente as categorias via prop "categories".'
45
- );
46
- }
47
- guidance.activeCategoriesInfo.push({
48
- id: "necessary",
49
- name: "Cookies Necess\xE1rios",
50
- description: "Essenciais para funcionamento b\xE1sico do site",
51
- essential: true,
52
- uiRequired: false
53
- });
54
- const enabledCategories = finalConfig.enabledCategories || [];
55
- const categoryNames = {
56
- analytics: {
57
- name: "Cookies Anal\xEDticos",
58
- description: "Medem uso e performance do site"
59
- },
60
- functional: {
61
- name: "Cookies Funcionais",
62
- description: "Melhoram experi\xEAncia e funcionalidades"
63
- },
64
- marketing: {
65
- name: "Cookies de Marketing",
66
- description: "Publicidade direcionada e campanhas"
67
- },
68
- social: {
69
- name: "Cookies de Redes Sociais",
70
- description: "Integra\xE7\xE3o com plataformas sociais"
71
- },
72
- personalization: {
73
- name: "Cookies de Personaliza\xE7\xE3o",
74
- description: "Adaptam conte\xFAdo \xE0s prefer\xEAncias do usu\xE1rio"
33
+ // src/utils/cookieRegistry.ts
34
+ function setCookieCatalogOverrides(overrides) {
35
+ COOKIE_CATALOG_OVERRIDES = {
36
+ byCategory: { ...COOKIE_CATALOG_OVERRIDES.byCategory || {}, ...overrides.byCategory || {} },
37
+ byIntegration: {
38
+ ...COOKIE_CATALOG_OVERRIDES.byIntegration || {},
39
+ ...overrides.byIntegration || {}
75
40
  }
76
41
  };
77
- enabledCategories.forEach((categoryId) => {
78
- const categoryInfo = categoryNames[categoryId];
79
- if (categoryInfo) {
80
- guidance.activeCategoriesInfo.push({
81
- id: categoryId,
82
- name: categoryInfo.name,
83
- description: categoryInfo.description,
84
- essential: false,
85
- uiRequired: true
86
- });
87
- }
88
- });
89
- const totalToggleable = guidance.activeCategoriesInfo.filter((c) => c.uiRequired).length;
90
- if (totalToggleable === 0) {
91
- guidance.suggestions.push(
92
- 'Apenas cookies necess\xE1rios est\xE3o configurados. Para compliance completo LGPD, considere adicionar categorias como "analytics" ou "functional" conforme uso real.'
93
- );
94
- }
95
- if (totalToggleable > 5) {
96
- guidance.warnings.push(
97
- `${totalToggleable} categorias opcionais detectadas. UI com muitas op\xE7\xF5es pode prejudicar experi\xEAncia do usu\xE1rio. Considere agrupar categorias similares.`
98
- );
99
- }
100
- return guidance;
101
42
  }
102
- function logDeveloperGuidance(guidance, disableGuidanceProp) {
103
- const gt = globalThis;
104
- const nodeEnv = typeof gt.process !== "undefined" ? gt.process?.env?.NODE_ENV : void 0;
105
- const isProd = nodeEnv === "production" || gt.__LGPD_PRODUCTION__ === true;
106
- const isDisabled = !!disableGuidanceProp || gt.__LGPD_DISABLE_GUIDANCE__ === true;
107
- if (isProd || isDisabled) return;
108
- const PREFIX = "[\u{1F36A} LGPD-CONSENT]";
109
- if (guidance.warnings.length > 0) {
110
- console.group(`${PREFIX} \u26A0\uFE0F Avisos de Configura\xE7\xE3o`);
111
- guidance.warnings.forEach((msg) => console.warn(`${PREFIX} ${msg}`));
112
- console.groupEnd();
113
- }
114
- if (guidance.suggestions.length > 0) {
115
- console.group(`${PREFIX} \u{1F4A1} Sugest\xF5es`);
116
- guidance.suggestions.forEach((msg) => console.info(`${PREFIX} ${msg}`));
117
- console.groupEnd();
118
- }
119
- if (guidance.usingDefaults) {
120
- console.warn(
121
- `${PREFIX} \u{1F4CB} Usando configura\xE7\xE3o padr\xE3o. Para personalizar, use a prop "categories" no ConsentProvider.`
122
- );
123
- }
124
- const rows = guidance.activeCategoriesInfo.map((cat) => ({
125
- ID: cat.id,
126
- Nome: cat.name,
127
- "Toggle UI?": cat.uiRequired ? "\u2705 SIM" : "\u274C N\xC3O (sempre ativo)",
128
- "Essencial?": cat.essential ? "\u{1F512} SIM" : "\u2699\uFE0F N\xC3O"
129
- }));
130
- if (typeof console.table === "function") {
131
- console.group(`${PREFIX} \u{1F527} Categorias Ativas (para UI customizada)`);
132
- console.table(rows);
133
- console.info(`${PREFIX} \u2139\uFE0F Use estes dados para criar componentes customizados adequados.`);
134
- console.groupEnd();
135
- } else {
136
- console.log(`${PREFIX} \u{1F527} Categorias Ativas (para UI customizada)`, rows);
137
- console.info(`${PREFIX} \u2139\uFE0F Use estes dados para criar componentes customizados adequados.`);
138
- }
43
+ function setCookieCategoryOverrides(map) {
44
+ COOKIE_CATEGORY_OVERRIDES = { ...COOKIE_CATEGORY_OVERRIDES, ...map };
139
45
  }
140
- function useDeveloperGuidance(config, disableGuidanceProp) {
141
- const guidance = import_react.default.useMemo(() => {
142
- return analyzeDeveloperConfiguration(config);
143
- }, [config]);
144
- import_react.default.useEffect(() => {
145
- if (!disableGuidanceProp) {
146
- logDeveloperGuidance(guidance, disableGuidanceProp);
46
+ function matchPattern(name, pattern) {
47
+ if (pattern.endsWith("*")) return name.startsWith(pattern.slice(0, -1));
48
+ return name === pattern;
49
+ }
50
+ function getCookiesInfoForCategory(categoryId, usedIntegrations) {
51
+ const result = [];
52
+ usedIntegrations.forEach((id) => {
53
+ const defaultCat = INTEGRATION_DEFAULT_CATEGORY[id];
54
+ const defaults = COOKIE_INFO_BY_INTEGRATION[id] || [];
55
+ const list = COOKIE_CATALOG_OVERRIDES.byIntegration?.[id] || defaults;
56
+ list.forEach((desc) => {
57
+ const overrideCat = Object.entries(COOKIE_CATEGORY_OVERRIDES).find(
58
+ ([pattern]) => matchPattern(desc.name, pattern)
59
+ )?.[1];
60
+ const finalCat = overrideCat ?? defaultCat;
61
+ if (finalCat === categoryId && !result.find((d) => d.name === desc.name)) result.push(desc);
62
+ });
63
+ });
64
+ const catOverride = COOKIE_CATALOG_OVERRIDES.byCategory?.[categoryId];
65
+ if (catOverride) {
66
+ catOverride.forEach((d) => {
67
+ const idx = result.findIndex((x) => x.name === d.name);
68
+ if (idx >= 0) result[idx] = d;
69
+ else result.push(d);
70
+ });
71
+ }
72
+ if (categoryId === "necessary") {
73
+ if (!result.find((d) => d.name === "cookieConsent")) {
74
+ result.push({
75
+ name: "cookieConsent",
76
+ purpose: "Armazena suas prefer\xEAncias de consentimento",
77
+ duration: "365 dias",
78
+ provider: "Este site"
79
+ });
147
80
  }
148
- }, [guidance, disableGuidanceProp]);
149
- return guidance;
81
+ }
82
+ return result;
150
83
  }
151
- var import_react, DEFAULT_PROJECT_CATEGORIES;
152
- var init_developerGuidance = __esm({
153
- "src/utils/developerGuidance.ts"() {
84
+ var COOKIE_PATTERNS_BY_CATEGORY, COOKIE_INFO_BY_INTEGRATION, INTEGRATION_DEFAULT_CATEGORY, COOKIE_CATALOG_OVERRIDES, COOKIE_CATEGORY_OVERRIDES;
85
+ var init_cookieRegistry = __esm({
86
+ "src/utils/cookieRegistry.ts"() {
154
87
  "use strict";
155
- import_react = __toESM(require("react"), 1);
156
- DEFAULT_PROJECT_CATEGORIES = {
157
- enabledCategories: ["analytics"]
88
+ COOKIE_PATTERNS_BY_CATEGORY = {
89
+ necessary: ["cookieConsent"],
90
+ analytics: ["_ga", "_ga_*", "_gid", "_gcl_au", "_hj*", "mp_*", "_clck", "_clsk"],
91
+ functional: ["intercom-*", "__zlcmid", "_zendesk_shared_session", "_userway_*"],
92
+ marketing: ["_fbp", "fr"],
93
+ social: [],
94
+ personalization: []
95
+ };
96
+ COOKIE_INFO_BY_INTEGRATION = {
97
+ "google-analytics": [
98
+ {
99
+ name: "_ga",
100
+ purpose: "Identifica\xE7\xE3o \xFAnica de visitantes para an\xE1lise de tr\xE1fego",
101
+ duration: "2 anos",
102
+ provider: "Google Analytics"
103
+ },
104
+ {
105
+ name: "_ga_*",
106
+ purpose: "Rastreamento de sess\xF5es e eventos espec\xEDficos do stream GA4",
107
+ duration: "2 anos",
108
+ provider: "Google Analytics"
109
+ },
110
+ {
111
+ name: "_gid",
112
+ purpose: "Distin\xE7\xE3o de visitantes \xFAnicos em per\xEDodo de 24h",
113
+ duration: "24 horas",
114
+ provider: "Google Analytics"
115
+ }
116
+ ],
117
+ "google-tag-manager": [
118
+ {
119
+ name: "_gcl_au",
120
+ purpose: "Rastreamento de convers\xF5es de an\xFAncios",
121
+ duration: "90 dias",
122
+ provider: "Google"
123
+ }
124
+ ],
125
+ hotjar: [
126
+ {
127
+ name: "_hjSession_*",
128
+ purpose: "Rastreamento de sess\xE3o",
129
+ duration: "30 minutos",
130
+ provider: "Hotjar"
131
+ },
132
+ {
133
+ name: "_hjSessionUser_*",
134
+ purpose: "Persist\xEAncia de usu\xE1rio entre sess\xF5es",
135
+ duration: "365 dias",
136
+ provider: "Hotjar"
137
+ },
138
+ {
139
+ name: "_hjFirstSeen",
140
+ purpose: "Detec\xE7\xE3o da primeira visita do usu\xE1rio",
141
+ duration: "Sess\xE3o",
142
+ provider: "Hotjar"
143
+ }
144
+ ],
145
+ mixpanel: [
146
+ {
147
+ name: "mp_*",
148
+ purpose: "Rastreamento de eventos e propriedades do usu\xE1rio para analytics",
149
+ duration: "1 ano",
150
+ provider: "Mixpanel"
151
+ }
152
+ ],
153
+ clarity: [
154
+ {
155
+ name: "_clck",
156
+ purpose: "Identificador de usu\xE1rio",
157
+ duration: "365 dias",
158
+ provider: "Microsoft"
159
+ },
160
+ { name: "_clsk", purpose: "Rastreamento de sess\xE3o", duration: "1 dia", provider: "Microsoft" }
161
+ ],
162
+ intercom: [
163
+ {
164
+ name: "intercom-id-*",
165
+ purpose: "Identificador do usu\xE1rio",
166
+ duration: "9 meses",
167
+ provider: "Intercom"
168
+ },
169
+ {
170
+ name: "intercom-session-*",
171
+ purpose: "Gerenciamento de sess\xE3o",
172
+ duration: "1 semana",
173
+ provider: "Intercom"
174
+ }
175
+ ],
176
+ "zendesk-chat": [
177
+ {
178
+ name: "__zlcmid",
179
+ purpose: "Identificador de sess\xE3o de chat",
180
+ duration: "1 ano",
181
+ provider: "Zendesk"
182
+ },
183
+ {
184
+ name: "_zendesk_shared_session",
185
+ purpose: "Gerenciamento de sess\xE3o",
186
+ duration: "Sess\xE3o",
187
+ provider: "Zendesk"
188
+ }
189
+ ],
190
+ userway: [
191
+ {
192
+ name: "_userway_*",
193
+ purpose: "Prefer\xEAncias de acessibilidade",
194
+ duration: "1 ano",
195
+ provider: "UserWay"
196
+ }
197
+ ],
198
+ "facebook-pixel": [
199
+ { name: "_fbp", purpose: "Rastreamento de an\xFAncios", duration: "90 dias", provider: "Meta" },
200
+ { name: "fr", purpose: "Direcionamento de an\xFAncios", duration: "90 dias", provider: "Meta" }
201
+ ]
158
202
  };
203
+ INTEGRATION_DEFAULT_CATEGORY = {
204
+ "google-analytics": "analytics",
205
+ "google-tag-manager": "analytics",
206
+ hotjar: "analytics",
207
+ mixpanel: "analytics",
208
+ clarity: "analytics",
209
+ intercom: "functional",
210
+ "zendesk-chat": "functional",
211
+ userway: "functional",
212
+ "facebook-pixel": "marketing"
213
+ };
214
+ COOKIE_CATALOG_OVERRIDES = {};
215
+ COOKIE_CATEGORY_OVERRIDES = {};
159
216
  }
160
217
  });
161
218
 
162
- // src/context/CategoriesContext.tsx
163
- function CategoriesProvider({
164
- children,
165
- config,
166
- disableDeveloperGuidance
167
- }) {
168
- const contextValue = React2.useMemo(() => {
169
- const finalConfig = config || DEFAULT_PROJECT_CATEGORIES;
170
- const guidance = analyzeDeveloperConfiguration(config);
171
- const toggleableCategories = guidance.activeCategoriesInfo.filter((cat) => cat.uiRequired);
172
- return {
173
- config: finalConfig,
174
- guidance,
175
- toggleableCategories,
176
- allCategories: guidance.activeCategoriesInfo
177
- };
178
- }, [config]);
179
- React2.useEffect(() => {
180
- logDeveloperGuidance(contextValue.guidance, disableDeveloperGuidance);
181
- }, [contextValue.guidance, disableDeveloperGuidance]);
182
- return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(CategoriesContext.Provider, { value: contextValue, children });
219
+ // src/utils/cookieDiscovery.ts
220
+ function discoverRuntimeCookies() {
221
+ if (typeof document === "undefined" || !document.cookie) return [];
222
+ const names = Array.from(
223
+ new Set(
224
+ document.cookie.split(";").map((s) => s.trim()).filter(Boolean).map((s) => s.split("=")[0])
225
+ )
226
+ );
227
+ const list = names.map((name) => ({ name }));
228
+ try {
229
+ ;
230
+ globalThis.__LGPD_DISCOVERED_COOKIES__ = list;
231
+ } catch {
232
+ }
233
+ return list;
183
234
  }
184
- function useCategories() {
185
- const context = React2.useContext(CategoriesContext);
186
- if (!context) {
187
- throw new Error(
188
- "useCategories deve ser usado dentro de CategoriesProvider. Certifique-se de que o ConsentProvider est\xE1 envolvendo seu componente."
189
- );
235
+ function detectConsentCookieName() {
236
+ if (typeof document === "undefined" || !document.cookie) return null;
237
+ try {
238
+ const pairs = document.cookie.split(";").map((s) => s.trim()).filter(Boolean);
239
+ for (const p of pairs) {
240
+ const [name, ...rest] = p.split("=");
241
+ const raw = rest.join("=");
242
+ if (!raw) continue;
243
+ let val = raw;
244
+ try {
245
+ val = decodeURIComponent(raw);
246
+ } catch {
247
+ }
248
+ if (val.startsWith("{")) {
249
+ try {
250
+ const obj = JSON.parse(val);
251
+ if (obj && typeof obj === "object" && "preferences" in obj && "version" in obj) {
252
+ return name;
253
+ }
254
+ } catch {
255
+ }
256
+ }
257
+ }
258
+ } catch {
190
259
  }
191
- return context;
260
+ return null;
192
261
  }
193
- function useCategoryStatus(categoryId) {
194
- const { allCategories } = useCategories();
195
- const category = allCategories.find((cat) => cat.id === categoryId);
196
- return {
197
- isActive: !!category,
198
- isEssential: category?.essential || false,
199
- needsToggle: category?.uiRequired || false,
200
- name: category?.name,
201
- description: category?.description
202
- };
262
+ function categorizeDiscoveredCookies(discovered, registerOverrides = false) {
263
+ const list = discovered || globalThis.__LGPD_DISCOVERED_COOKIES__ || [];
264
+ const out = {};
265
+ function matchPattern2(name, pattern) {
266
+ if (pattern.endsWith("*")) return name.startsWith(pattern.slice(0, -1));
267
+ return name === pattern;
268
+ }
269
+ list.filter((d) => d.name && d.name !== "cookieConsent").forEach((d) => {
270
+ let assigned = null;
271
+ Object.keys(COOKIE_PATTERNS_BY_CATEGORY).forEach((cat2) => {
272
+ if (assigned) return;
273
+ const patterns = COOKIE_PATTERNS_BY_CATEGORY[cat2] || [];
274
+ if (patterns.some((p) => matchPattern2(d.name, p))) assigned = cat2;
275
+ });
276
+ const cat = assigned || "analytics";
277
+ out[cat] = out[cat] || [];
278
+ if (!out[cat].find((x) => x.name === d.name)) out[cat].push(d);
279
+ });
280
+ if (registerOverrides) {
281
+ const byCategory = {};
282
+ Object.entries(out).forEach(([cat, cookies]) => {
283
+ byCategory[cat] = cookies;
284
+ });
285
+ setCookieCatalogOverrides({ byCategory });
286
+ }
287
+ return out;
203
288
  }
204
- var React2, import_jsx_runtime, CategoriesContext;
205
- var init_CategoriesContext = __esm({
206
- "src/context/CategoriesContext.tsx"() {
289
+ var init_cookieDiscovery = __esm({
290
+ "src/utils/cookieDiscovery.ts"() {
207
291
  "use strict";
208
- React2 = __toESM(require("react"), 1);
209
- init_developerGuidance();
210
- import_jsx_runtime = require("react/jsx-runtime");
211
- CategoriesContext = React2.createContext(null);
292
+ init_cookieRegistry();
212
293
  }
213
294
  });
214
295
 
@@ -493,6 +574,497 @@ var init_cookieUtils = __esm({
493
574
  }
494
575
  });
495
576
 
577
+ // src/utils/developerGuidance.ts
578
+ function calculateComplianceScore(guidance) {
579
+ let score = 0;
580
+ const maxScore = 100;
581
+ if (!guidance.usingDefaults) score += 30;
582
+ const totalCategories = guidance.activeCategoriesInfo.length;
583
+ const toggleableCategories = guidance.activeCategoriesInfo.filter((c) => c.uiRequired).length;
584
+ if (totalCategories > 1) score += 20;
585
+ if (toggleableCategories >= 2 && toggleableCategories <= 4) score += 25;
586
+ const criticalWarnings = guidance.messages.filter((m) => m.severity === "error").length;
587
+ const warnings = guidance.messages.filter((m) => m.severity === "warning").length;
588
+ if (criticalWarnings === 0) score += 15;
589
+ if (warnings === 0) score += 10;
590
+ return Math.min(score, maxScore);
591
+ }
592
+ function analyzeDeveloperConfiguration(config) {
593
+ const guidance = {
594
+ warnings: [],
595
+ suggestions: [],
596
+ messages: [],
597
+ activeCategoriesInfo: [],
598
+ usingDefaults: !config,
599
+ complianceScore: 0
600
+ };
601
+ const addMessage = (severity, message, category, actionable = true) => {
602
+ const guidanceMessage = { severity, message, category, actionable };
603
+ guidance.messages.push(guidanceMessage);
604
+ if (severity === "warning" || severity === "error") {
605
+ guidance.warnings.push(message);
606
+ } else {
607
+ guidance.suggestions.push(message);
608
+ }
609
+ };
610
+ const finalConfig = config || DEFAULT_PROJECT_CATEGORIES;
611
+ if (!config) {
612
+ addMessage(
613
+ "warning",
614
+ 'LGPD-CONSENT: Nenhuma configura\xE7\xE3o de categorias especificada. Usando padr\xE3o: necessary + analytics. Para produ\xE7\xE3o, especifique explicitamente as categorias via prop "categories".',
615
+ "configuration"
616
+ );
617
+ }
618
+ guidance.activeCategoriesInfo.push({
619
+ id: "necessary",
620
+ name: "Cookies Necess\xE1rios",
621
+ description: "Essenciais para funcionamento b\xE1sico do site",
622
+ essential: true,
623
+ uiRequired: false,
624
+ cookies: COOKIE_PATTERNS_BY_CATEGORY["necessary"]
625
+ });
626
+ const enabled = finalConfig.enabledCategories || [];
627
+ const NAMES = {
628
+ analytics: { name: "Cookies Anal\xEDticos", description: "Medem uso e performance do site" },
629
+ functional: {
630
+ name: "Cookies Funcionais",
631
+ description: "Melhoram experi\xEAncia e funcionalidades"
632
+ },
633
+ marketing: { name: "Cookies de Marketing", description: "Publicidade direcionada e campanhas" },
634
+ social: { name: "Cookies de Redes Sociais", description: "Integra\xE7\xE3o com plataformas sociais" },
635
+ personalization: { name: "Cookies de Personaliza\xE7\xE3o", description: "Adapta\xE7\xE3o de conte\xFAdo" }
636
+ };
637
+ enabled.forEach((id) => {
638
+ const info = NAMES[id];
639
+ if (info) {
640
+ guidance.activeCategoriesInfo.push({
641
+ id,
642
+ name: info.name,
643
+ description: info.description,
644
+ essential: false,
645
+ uiRequired: true,
646
+ cookies: COOKIE_PATTERNS_BY_CATEGORY[id]
647
+ });
648
+ }
649
+ });
650
+ const custom = finalConfig.customCategories || [];
651
+ custom.forEach((cat) => {
652
+ if (!cat?.id || cat.id === "necessary") return;
653
+ guidance.activeCategoriesInfo.push({
654
+ id: cat.id,
655
+ name: cat.name,
656
+ description: cat.description,
657
+ essential: !!cat.essential,
658
+ uiRequired: !cat.essential,
659
+ cookies: cat.cookies
660
+ });
661
+ });
662
+ try {
663
+ const gt = globalThis;
664
+ const implied = (gt.__LGPD_REQUIRED_CATEGORIES__ || []).filter(Boolean);
665
+ implied.forEach((id) => {
666
+ if (!guidance.activeCategoriesInfo.find((c) => c.id === id)) {
667
+ const info = NAMES[id];
668
+ if (info) {
669
+ guidance.activeCategoriesInfo.push({
670
+ id,
671
+ name: info.name,
672
+ description: info.description,
673
+ essential: false,
674
+ uiRequired: true,
675
+ cookies: COOKIE_PATTERNS_BY_CATEGORY[id]
676
+ });
677
+ if (!enabled.includes(id)) {
678
+ addMessage(
679
+ "info",
680
+ `Integra\xE7\xF5es detectadas requerem a categoria '${id}'. Adicione-a em categories.enabledCategories.`,
681
+ "integration"
682
+ );
683
+ }
684
+ }
685
+ }
686
+ });
687
+ } catch {
688
+ }
689
+ try {
690
+ const gt2 = globalThis;
691
+ const used = gt2.__LGPD_USED_INTEGRATIONS__ || [];
692
+ guidance.activeCategoriesInfo = guidance.activeCategoriesInfo.map((c) => {
693
+ const info = getCookiesInfoForCategory(c.id, used);
694
+ const names = Array.from(/* @__PURE__ */ new Set([...c.cookies || [], ...info.map((d) => d.name)]));
695
+ return { ...c, cookies: names };
696
+ });
697
+ } catch {
698
+ }
699
+ const totalToggleable = guidance.activeCategoriesInfo.filter((c) => c.uiRequired).length;
700
+ if (totalToggleable === 0) {
701
+ addMessage(
702
+ "info",
703
+ 'Apenas cookies necess\xE1rios est\xE3o configurados. Para compliance LGPD, considere adicionar categorias como "analytics" ou "functional" conforme uso real.',
704
+ "compliance"
705
+ );
706
+ }
707
+ if (totalToggleable > 5) {
708
+ addMessage(
709
+ "warning",
710
+ `${totalToggleable} categorias opcionais detectadas. UI com muitas op\xE7\xF5es pode prejudicar a experi\xEAncia. Considere agrupar categorias similares.`,
711
+ "usability"
712
+ );
713
+ }
714
+ guidance.complianceScore = calculateComplianceScore(guidance);
715
+ return guidance;
716
+ }
717
+ function getComplianceScoreColor(score) {
718
+ if (score >= 80) return "#4caf50";
719
+ if (score >= 60) return "#ff9800";
720
+ return "#f44336";
721
+ }
722
+ function logComplianceScore(prefix, score) {
723
+ const color = getComplianceScoreColor(score);
724
+ console.log(
725
+ `%c${prefix} Score de Conformidade LGPD: ${score}/100`,
726
+ `color: ${color}; font-weight: bold; font-size: 14px;`
727
+ );
728
+ }
729
+ function logMessagesByType(prefix, messages, type, config) {
730
+ const filteredMessages = messages.filter((m) => m.severity === type);
731
+ if (filteredMessages.length === 0) return false;
732
+ const typeConfig = {
733
+ error: {
734
+ show: config.showWarnings,
735
+ title: "Erros Cr\xEDticos",
736
+ color: "#d32f2f",
737
+ method: console.error
738
+ },
739
+ warning: {
740
+ show: config.showWarnings,
741
+ title: "Avisos de Configura\xE7\xE3o",
742
+ color: "#f57c00",
743
+ method: console.warn
744
+ },
745
+ info: {
746
+ show: config.showSuggestions,
747
+ title: "Sugest\xF5es",
748
+ color: "#2196f3",
749
+ method: console.info
750
+ }
751
+ };
752
+ const typeSettings = typeConfig[type];
753
+ if (!typeSettings.show) return false;
754
+ console.group(
755
+ `%c${prefix} ${typeSettings.title}`,
756
+ `color: ${typeSettings.color}; font-weight: bold;`
757
+ );
758
+ filteredMessages.forEach(
759
+ (msg) => typeSettings.method(
760
+ `%c${prefix}%c ${msg.message}`,
761
+ `color: ${typeSettings.color};`,
762
+ "color: #333;"
763
+ )
764
+ );
765
+ console.groupEnd();
766
+ return true;
767
+ }
768
+ function getGuidanceHash(guidance) {
769
+ const sortedWarnings = [...guidance.warnings].sort((a, b) => a.localeCompare(b));
770
+ const sortedSuggestions = [...guidance.suggestions].sort(
771
+ (a, b) => a.localeCompare(b)
772
+ );
773
+ const sortedCategories = guidance.activeCategoriesInfo.map((c) => c.id).sort((a, b) => a.localeCompare(b));
774
+ return JSON.stringify({
775
+ warnings: sortedWarnings,
776
+ suggestions: sortedSuggestions,
777
+ categories: sortedCategories,
778
+ usingDefaults: guidance.usingDefaults
779
+ });
780
+ }
781
+ function logIntroOnce() {
782
+ if (SESSION_LOGGED.intro) return;
783
+ SESSION_LOGGED.intro = true;
784
+ console.log(
785
+ `%c\u{1F36A} LGPD-CONSENT %c- Sistema de Consentimento Ativo`,
786
+ "background: #4caf50; color: white; padding: 4px 8px; border-radius: 4px; font-weight: bold;",
787
+ "color: #2e7d32; font-weight: 500;"
788
+ );
789
+ }
790
+ function logServerSideIfAvailable(guidance) {
791
+ try {
792
+ const gt = globalThis;
793
+ if (gt.process?.stdout?.write) {
794
+ const prefix = "\x1B[36m[LGPD-CONSENT]\x1B[0m";
795
+ const warnings = guidance.warnings.length;
796
+ const suggestions = guidance.suggestions.length;
797
+ const stdout = gt.process.stdout;
798
+ if (warnings > 0 || suggestions > 0) {
799
+ stdout.write(`${prefix} \u{1F527} Config: ${warnings} avisos, ${suggestions} sugest\xF5es
800
+ `);
801
+ if (warnings > 0) {
802
+ guidance.warnings.forEach((w) => {
803
+ stdout.write(`${prefix} \x1B[33m\u26A0\uFE0F ${w}\x1B[0m
804
+ `);
805
+ });
806
+ }
807
+ if (suggestions > 0) {
808
+ guidance.suggestions.forEach((s) => {
809
+ stdout.write(`${prefix} \x1B[36m\u{1F4A1} ${s}\x1B[0m
810
+ `);
811
+ });
812
+ }
813
+ }
814
+ }
815
+ } catch {
816
+ }
817
+ }
818
+ function logDeveloperGuidance(guidance, disableGuidanceProp, config) {
819
+ const gt = globalThis;
820
+ const nodeEnv = typeof gt.process !== "undefined" ? gt.process?.env?.NODE_ENV : void 0;
821
+ const isProd = nodeEnv === "production" || gt.__LGPD_PRODUCTION__ === true;
822
+ if (isProd || disableGuidanceProp) return;
823
+ const guidanceHash = getGuidanceHash(guidance);
824
+ if (GUIDANCE_CACHE.has(guidanceHash)) return;
825
+ GUIDANCE_CACHE.add(guidanceHash);
826
+ logServerSideIfAvailable(guidance);
827
+ const guidanceConfig = {
828
+ showWarnings: true,
829
+ showSuggestions: true,
830
+ showCategoriesTable: true,
831
+ showBestPractices: true,
832
+ showComplianceScore: true,
833
+ minimumSeverity: "info",
834
+ ...config
835
+ };
836
+ if (guidanceConfig.messageProcessor) {
837
+ guidanceConfig.messageProcessor(guidance.messages);
838
+ return;
839
+ }
840
+ logIntroOnce();
841
+ const PREFIX = "\u{1F36A}";
842
+ let hasImportantInfo = false;
843
+ const filteredMessages = guidance.messages.filter((msg) => {
844
+ const severityLevels = { info: 0, warning: 1, error: 2 };
845
+ const minLevel = severityLevels[guidanceConfig.minimumSeverity || "info"];
846
+ const msgLevel = severityLevels[msg.severity];
847
+ return msgLevel >= minLevel;
848
+ });
849
+ hasImportantInfo = logMessagesByType(PREFIX, filteredMessages, "error", guidanceConfig) || hasImportantInfo;
850
+ hasImportantInfo = logMessagesByType(PREFIX, filteredMessages, "warning", guidanceConfig) || hasImportantInfo;
851
+ if (hasImportantInfo || guidance.usingDefaults) {
852
+ hasImportantInfo = logMessagesByType(PREFIX, filteredMessages, "info", guidanceConfig) || hasImportantInfo;
853
+ }
854
+ if (guidanceConfig.showComplianceScore && guidance.complianceScore !== void 0) {
855
+ logComplianceScore(PREFIX, guidance.complianceScore);
856
+ }
857
+ if (guidanceConfig.showCategoriesTable && (hasImportantInfo || guidance.usingDefaults)) {
858
+ const rows = guidance.activeCategoriesInfo.map((cat) => ({
859
+ "\u{1F4CA} Categoria": cat.id,
860
+ "\u{1F3F7}\uFE0F Nome": cat.name,
861
+ "\u{1F39B}\uFE0F UI": cat.uiRequired ? "\u2705" : "\u{1F512}",
862
+ "\u{1F36A} Cookies": (cat.cookies || []).slice(0, 3).join(", ") + (cat.cookies && cat.cookies.length > 3 ? ` (+${cat.cookies.length - 3})` : "")
863
+ }));
864
+ if (typeof console.table === "function") {
865
+ console.group(`%c${PREFIX} Configura\xE7\xE3o Ativa`, "color: #4caf50; font-weight: bold;");
866
+ console.table(rows);
867
+ console.groupEnd();
868
+ }
869
+ }
870
+ if (!SESSION_LOGGED.bestPractices && hasImportantInfo) {
871
+ SESSION_LOGGED.bestPractices = true;
872
+ console.group(`%c${PREFIX} LGPD - Boas Pr\xE1ticas`, "color: #9c27b0; font-weight: bold;");
873
+ console.info(
874
+ `%c${PREFIX}%c Necessary: sempre ativo \u2022 Demais: opt-out por padr\xE3o`,
875
+ "color: #9c27b0;",
876
+ "color: #7b1fa2;"
877
+ );
878
+ console.info(
879
+ `%c${PREFIX}%c Documente pol\xEDticas claras por categoria`,
880
+ "color: #9c27b0;",
881
+ "color: #7b1fa2;"
882
+ );
883
+ console.info(
884
+ `%c${PREFIX}%c Registre consentimento com data/hora/origem`,
885
+ "color: #9c27b0;",
886
+ "color: #7b1fa2;"
887
+ );
888
+ console.groupEnd();
889
+ }
890
+ }
891
+ function useDeveloperGuidance(config, disableGuidanceProp, guidanceConfig) {
892
+ const guidance = import_react.default.useMemo(() => analyzeDeveloperConfiguration(config), [config]);
893
+ import_react.default.useEffect(() => {
894
+ if (!disableGuidanceProp) logDeveloperGuidance(guidance, disableGuidanceProp, guidanceConfig);
895
+ }, [guidance, disableGuidanceProp, guidanceConfig]);
896
+ return guidance;
897
+ }
898
+ var import_react, DEFAULT_PROJECT_CATEGORIES, GUIDANCE_CACHE, SESSION_LOGGED, GUIDANCE_PRESETS;
899
+ var init_developerGuidance = __esm({
900
+ "src/utils/developerGuidance.ts"() {
901
+ "use strict";
902
+ import_react = __toESM(require("react"), 1);
903
+ init_cookieRegistry();
904
+ DEFAULT_PROJECT_CATEGORIES = {
905
+ enabledCategories: ["analytics"]
906
+ };
907
+ GUIDANCE_CACHE = /* @__PURE__ */ new Set();
908
+ SESSION_LOGGED = {
909
+ intro: false,
910
+ bestPractices: false
911
+ };
912
+ GUIDANCE_PRESETS = {
913
+ /** Configuração completa para desenvolvimento */
914
+ development: {
915
+ showWarnings: true,
916
+ showSuggestions: true,
917
+ showCategoriesTable: true,
918
+ showBestPractices: true,
919
+ showComplianceScore: true,
920
+ minimumSeverity: "info"
921
+ },
922
+ /** Configuração silenciosa para produção */
923
+ production: {
924
+ showWarnings: false,
925
+ showSuggestions: false,
926
+ showCategoriesTable: false,
927
+ showBestPractices: false,
928
+ showComplianceScore: false,
929
+ minimumSeverity: "error"
930
+ },
931
+ /** Apenas erros críticos */
932
+ minimal: {
933
+ showWarnings: true,
934
+ showSuggestions: false,
935
+ showCategoriesTable: false,
936
+ showBestPractices: false,
937
+ showComplianceScore: false,
938
+ minimumSeverity: "error"
939
+ },
940
+ /** Focado em conformidade LGPD */
941
+ compliance: {
942
+ showWarnings: true,
943
+ showSuggestions: true,
944
+ showCategoriesTable: true,
945
+ showBestPractices: true,
946
+ showComplianceScore: true,
947
+ minimumSeverity: "warning"
948
+ }
949
+ };
950
+ }
951
+ });
952
+
953
+ // src/context/CategoriesContext.tsx
954
+ function CategoriesProvider({
955
+ children,
956
+ config,
957
+ disableDeveloperGuidance,
958
+ disableDiscoveryLog
959
+ }) {
960
+ const [impliedVersion, setImpliedVersion] = React2.useState(0);
961
+ React2.useEffect(() => {
962
+ const handler = () => setImpliedVersion((v) => v + 1);
963
+ if (typeof window !== "undefined" && typeof window.addEventListener === "function") {
964
+ window.addEventListener("lgpd:requiredCategories", handler);
965
+ return () => window.removeEventListener("lgpd:requiredCategories", handler);
966
+ }
967
+ return () => {
968
+ };
969
+ }, []);
970
+ const contextValue = React2.useMemo(() => {
971
+ const finalConfig = config || DEFAULT_PROJECT_CATEGORIES;
972
+ const guidance = analyzeDeveloperConfiguration(config);
973
+ const toggleableCategories = guidance.activeCategoriesInfo.filter((cat) => cat.uiRequired);
974
+ return {
975
+ config: finalConfig,
976
+ guidance,
977
+ toggleableCategories,
978
+ allCategories: guidance.activeCategoriesInfo
979
+ };
980
+ }, [config, impliedVersion]);
981
+ React2.useEffect(() => {
982
+ logDeveloperGuidance(contextValue.guidance, disableDeveloperGuidance);
983
+ }, [contextValue.guidance, disableDeveloperGuidance]);
984
+ React2.useEffect(() => {
985
+ try {
986
+ const gt = globalThis;
987
+ const env = typeof gt.process !== "undefined" ? gt.process?.env?.NODE_ENV : void 0;
988
+ const isDev = env === "development";
989
+ if (!isDev || gt.__LGPD_DISCOVERY_LOGGED__ === true || disableDiscoveryLog) return;
990
+ const discovered = discoverRuntimeCookies();
991
+ const consentName = detectConsentCookieName() || DEFAULT_COOKIE_OPTS.name;
992
+ const PREFIX = "[\u{1F36A} LGPD-CONSENT]";
993
+ if (typeof console !== "undefined") {
994
+ try {
995
+ console.group(`${PREFIX} \u{1F50E} Descoberta de cookies (experimental)`);
996
+ const names = Array.from(
997
+ new Set([consentName, ...discovered.map((d) => d.name)].filter(Boolean))
998
+ );
999
+ const rows = names.map((n) => ({ Cookie: n }));
1000
+ if (typeof console.table === "function") console.table(rows);
1001
+ else console.log(rows);
1002
+ console.info(
1003
+ `${PREFIX} \u2139\uFE0F Estes nomes s\xE3o detectados em tempo de execu\xE7\xE3o. Ajuste ou categorize via APIs de override se necess\xE1rio.`
1004
+ );
1005
+ console.groupEnd();
1006
+ } catch {
1007
+ }
1008
+ }
1009
+ gt.__LGPD_DISCOVERY_LOGGED__ = true;
1010
+ } catch {
1011
+ }
1012
+ }, [disableDiscoveryLog]);
1013
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(CategoriesContext.Provider, { value: contextValue, children });
1014
+ }
1015
+ function useCategories() {
1016
+ const context = React2.useContext(CategoriesContext);
1017
+ if (!context) {
1018
+ throw new Error(
1019
+ "useCategories deve ser usado dentro de CategoriesProvider. Certifique-se de que o ConsentProvider est\xE1 envolvendo seu componente."
1020
+ );
1021
+ }
1022
+ return context;
1023
+ }
1024
+ function useCategoryStatus(categoryId) {
1025
+ const { allCategories } = useCategories();
1026
+ const category = allCategories.find((cat) => cat.id === categoryId);
1027
+ return {
1028
+ isActive: !!category,
1029
+ isEssential: category?.essential || false,
1030
+ needsToggle: category?.uiRequired || false,
1031
+ name: category?.name,
1032
+ description: category?.description
1033
+ };
1034
+ }
1035
+ var React2, import_jsx_runtime, CategoriesContext;
1036
+ var init_CategoriesContext = __esm({
1037
+ "src/context/CategoriesContext.tsx"() {
1038
+ "use strict";
1039
+ React2 = __toESM(require("react"), 1);
1040
+ init_cookieDiscovery();
1041
+ init_cookieUtils();
1042
+ init_developerGuidance();
1043
+ import_jsx_runtime = require("react/jsx-runtime");
1044
+ CategoriesContext = React2.createContext(null);
1045
+ }
1046
+ });
1047
+
1048
+ // src/context/DesignContext.tsx
1049
+ function DesignProvider({
1050
+ tokens,
1051
+ children
1052
+ }) {
1053
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(DesignContext.Provider, { value: tokens, children });
1054
+ }
1055
+ function useDesignTokens() {
1056
+ return React3.useContext(DesignContext);
1057
+ }
1058
+ var React3, import_jsx_runtime2, DesignContext;
1059
+ var init_DesignContext = __esm({
1060
+ "src/context/DesignContext.tsx"() {
1061
+ "use strict";
1062
+ React3 = __toESM(require("react"), 1);
1063
+ import_jsx_runtime2 = require("react/jsx-runtime");
1064
+ DesignContext = React3.createContext(void 0);
1065
+ }
1066
+ });
1067
+
496
1068
  // src/utils/categoryUtils.ts
497
1069
  function createProjectPreferences(config, defaultValue = false) {
498
1070
  const preferences = {
@@ -505,6 +1077,12 @@ function createProjectPreferences(config, defaultValue = false) {
505
1077
  preferences[category] = defaultValue;
506
1078
  }
507
1079
  });
1080
+ const customCategories = config?.customCategories || [];
1081
+ customCategories.forEach((cat) => {
1082
+ if (cat.id && cat.id !== "necessary") {
1083
+ preferences[cat.id] = defaultValue;
1084
+ }
1085
+ });
508
1086
  return preferences;
509
1087
  }
510
1088
  function validateProjectPreferences(preferences, config) {
@@ -518,6 +1096,13 @@ function validateProjectPreferences(preferences, config) {
518
1096
  validPreferences[category] = preferences[category];
519
1097
  }
520
1098
  });
1099
+ const customCategories = config?.customCategories || [];
1100
+ customCategories.forEach((cat) => {
1101
+ const id = cat.id;
1102
+ if (id && id !== "necessary" && preferences[id] !== void 0) {
1103
+ validPreferences[id] = preferences[id];
1104
+ }
1105
+ });
521
1106
  return validPreferences;
522
1107
  }
523
1108
  function getAllProjectCategories(config) {
@@ -535,6 +1120,12 @@ function getAllProjectCategories(config) {
535
1120
  allCategories.push(getDefaultCategoryDefinition(category));
536
1121
  }
537
1122
  });
1123
+ const customCategories = config?.customCategories || [];
1124
+ customCategories.forEach((cat) => {
1125
+ if (cat.id && cat.id !== "necessary") {
1126
+ allCategories.push({ ...cat, essential: !!cat.essential });
1127
+ }
1128
+ });
538
1129
  return allCategories;
539
1130
  }
540
1131
  function getDefaultCategoryDefinition(category) {
@@ -567,40 +1158,20 @@ function getDefaultCategoryDefinition(category) {
567
1158
  id: "social",
568
1159
  name: "Redes Sociais",
569
1160
  description: "Cookies para integra\xE7\xE3o com redes sociais e compartilhamento",
570
- essential: false
571
- },
572
- personalization: {
573
- id: "personalization",
574
- name: "Personaliza\xE7\xE3o",
575
- description: "Cookies para personaliza\xE7\xE3o de conte\xFAdo e experi\xEAncia",
576
- essential: false
577
- }
578
- };
579
- return definitions[category];
580
- }
581
- var init_categoryUtils = __esm({
582
- "src/utils/categoryUtils.ts"() {
583
- "use strict";
584
- }
585
- });
586
-
587
- // src/context/DesignContext.tsx
588
- function DesignProvider({
589
- tokens,
590
- children
591
- }) {
592
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(DesignContext.Provider, { value: tokens, children });
593
- }
594
- function useDesignTokens() {
595
- return React3.useContext(DesignContext);
1161
+ essential: false
1162
+ },
1163
+ personalization: {
1164
+ id: "personalization",
1165
+ name: "Personaliza\xE7\xE3o",
1166
+ description: "Cookies para personaliza\xE7\xE3o de conte\xFAdo e experi\xEAncia",
1167
+ essential: false
1168
+ }
1169
+ };
1170
+ return definitions[category];
596
1171
  }
597
- var React3, import_jsx_runtime2, DesignContext;
598
- var init_DesignContext = __esm({
599
- "src/context/DesignContext.tsx"() {
1172
+ var init_categoryUtils = __esm({
1173
+ "src/utils/categoryUtils.ts"() {
600
1174
  "use strict";
601
- React3 = __toESM(require("react"), 1);
602
- import_jsx_runtime2 = require("react/jsx-runtime");
603
- DesignContext = React3.createContext(void 0);
604
1175
  }
605
1176
  });
606
1177
 
@@ -678,6 +1249,7 @@ var init_Branding = __esm({
678
1249
  // src/components/CookieBanner.tsx
679
1250
  function CookieBanner({
680
1251
  policyLinkUrl,
1252
+ termsLinkUrl,
681
1253
  debug,
682
1254
  blocking = true,
683
1255
  hideBranding = false,
@@ -697,15 +1269,15 @@ function CookieBanner({
697
1269
  hideBranding
698
1270
  });
699
1271
  if (!open) return null;
700
- const bannerStyle = {
1272
+ const bannerStyle = (theme) => ({
701
1273
  p: designTokens?.spacing?.padding?.banner ?? 2,
702
1274
  maxWidth: 720,
703
1275
  mx: "auto",
704
- backgroundColor: designTokens?.colors?.background,
705
- color: designTokens?.colors?.text,
1276
+ backgroundColor: designTokens?.colors?.background ?? theme.palette.background?.paper,
1277
+ color: designTokens?.colors?.text ?? theme.palette.text?.primary,
706
1278
  borderRadius: designTokens?.spacing?.borderRadius?.banner,
707
1279
  fontFamily: designTokens?.typography?.fontFamily
708
- };
1280
+ });
709
1281
  const bannerContent = /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_Paper.default, { elevation: 3, sx: bannerStyle, ...PaperProps, children: /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_Stack.default, { spacing: 1, children: [
710
1282
  /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_Typography2.default, { variant: "body2", sx: { fontSize: designTokens?.typography?.fontSize?.banner }, children: [
711
1283
  texts.bannerMessage,
@@ -771,27 +1343,51 @@ function CookieBanner({
771
1343
  width: designTokens?.layout?.width?.desktop ?? "100%",
772
1344
  p: 2
773
1345
  };
774
- let backdropColor = "rgba(0, 0, 0, 0.4)";
775
1346
  const backdropToken = designTokens?.layout?.backdrop;
776
- if (backdropToken === false) {
777
- backdropColor = "transparent";
778
- } else if (typeof backdropToken === "string") {
779
- backdropColor = backdropToken;
780
- }
781
- if (blocking) {
1347
+ const resolveBackdropColor = (theme) => {
1348
+ if (backdropToken === false) return "transparent";
1349
+ if (typeof backdropToken === "string") {
1350
+ if (backdropToken.toLowerCase() === "auto") {
1351
+ const isDark2 = theme?.palette?.mode === "dark";
1352
+ return isDark2 ? "rgba(255, 255, 255, 0.12)" : "rgba(0, 0, 0, 0.4)";
1353
+ }
1354
+ return backdropToken;
1355
+ }
1356
+ const isDark = theme?.palette?.mode === "dark";
1357
+ return isDark ? "rgba(255, 255, 255, 0.12)" : "rgba(0, 0, 0, 0.4)";
1358
+ };
1359
+ const isSafeRoute = (() => {
1360
+ try {
1361
+ if (typeof window === "undefined") return false;
1362
+ const current = new URL(window.location.href);
1363
+ const safeUrls = [policyLinkUrl, termsLinkUrl].filter(Boolean);
1364
+ return safeUrls.some((u) => {
1365
+ try {
1366
+ const target = new URL(u, current.origin);
1367
+ return target.pathname === current.pathname;
1368
+ } catch {
1369
+ return false;
1370
+ }
1371
+ });
1372
+ } catch {
1373
+ return false;
1374
+ }
1375
+ })();
1376
+ const effectiveBlocking = blocking && !isSafeRoute;
1377
+ if (effectiveBlocking) {
782
1378
  return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_jsx_runtime4.Fragment, { children: [
783
1379
  /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
784
1380
  import_Box.default,
785
1381
  {
786
- sx: {
1382
+ sx: (theme) => ({
787
1383
  position: "fixed",
788
1384
  top: 0,
789
1385
  left: 0,
790
1386
  right: 0,
791
1387
  bottom: 0,
792
- backgroundColor: backdropColor,
1388
+ backgroundColor: resolveBackdropColor(theme),
793
1389
  zIndex: 1299
794
- }
1390
+ })
795
1391
  }
796
1392
  ),
797
1393
  /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_Box.default, { sx: positionStyle, children: bannerContent })
@@ -1023,7 +1619,9 @@ function ConsentProvider({
1023
1619
  onPreferencesSaved,
1024
1620
  cookie: cookieOpts,
1025
1621
  disableDeveloperGuidance,
1026
- children
1622
+ guidanceConfig,
1623
+ children,
1624
+ disableDiscoveryLog
1027
1625
  }) {
1028
1626
  const texts = React4.useMemo(() => ({ ...DEFAULT_TEXTS, ...textsProp ?? {} }), [textsProp]);
1029
1627
  const cookie = React4.useMemo(
@@ -1035,7 +1633,15 @@ function ConsentProvider({
1035
1633
  if (categories) return categories;
1036
1634
  return DEFAULT_PROJECT_CATEGORIES;
1037
1635
  }, [categories]);
1038
- useDeveloperGuidance(finalCategoriesConfig, disableDeveloperGuidance);
1636
+ useDeveloperGuidance(finalCategoriesConfig, disableDeveloperGuidance, guidanceConfig);
1637
+ React4.useEffect(() => {
1638
+ const isProd = typeof process !== "undefined" && process.env?.NODE_ENV === "production";
1639
+ if (!isProd && PreferencesModalComponent) {
1640
+ console.info(
1641
+ "[LGPD-CONSENT] Dica: seu PreferencesModal \xE9 customizado. Garanta exibir os detalhes dos cookies por categoria (nome, finalidade, dura\xE7\xE3o) usando as APIs setCookieCatalogOverrides / setCookieCategoryOverrides e getCookiesInfoForCategory. Consulte QUICKSTART e INTEGRACOES.md."
1642
+ );
1643
+ }
1644
+ }, [PreferencesModalComponent]);
1039
1645
  const boot = React4.useMemo(() => {
1040
1646
  if (initialState) return { ...initialState, isModalOpen: false };
1041
1647
  return createFullConsentState(
@@ -1119,6 +1725,7 @@ function ConsentProvider({
1119
1725
  {
1120
1726
  config: finalCategoriesConfig,
1121
1727
  disableDeveloperGuidance,
1728
+ disableDiscoveryLog,
1122
1729
  children: [
1123
1730
  children,
1124
1731
  /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(React4.Suspense, { fallback: null, children: PreferencesModalComponent ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
@@ -1208,19 +1815,19 @@ function useConsentTextsInternal() {
1208
1815
  function useConsentHydrationInternal() {
1209
1816
  return React4.useContext(HydrationCtx);
1210
1817
  }
1211
- var React4, import_styles2, import_jsx_runtime6, PreferencesModal, DEFAULT_TEXTS, StateCtx, ActionsCtx, TextsCtx, HydrationCtx, defaultTexts;
1818
+ var import_styles2, React4, import_jsx_runtime6, PreferencesModal, DEFAULT_TEXTS, StateCtx, ActionsCtx, TextsCtx, HydrationCtx, defaultTexts;
1212
1819
  var init_ConsentContext = __esm({
1213
1820
  "src/context/ConsentContext.tsx"() {
1214
1821
  "use strict";
1215
- React4 = __toESM(require("react"), 1);
1216
1822
  import_styles2 = require("@mui/material/styles");
1217
- init_cookieUtils();
1823
+ React4 = __toESM(require("react"), 1);
1218
1824
  init_categoryUtils();
1219
- init_CategoriesContext();
1220
- init_DesignContext();
1221
- init_developerGuidance();
1825
+ init_cookieUtils();
1222
1826
  init_useConsent();
1827
+ init_developerGuidance();
1223
1828
  init_logger();
1829
+ init_CategoriesContext();
1830
+ init_DesignContext();
1224
1831
  init_CookieBanner();
1225
1832
  init_FloatingPreferencesButton();
1226
1833
  import_jsx_runtime6 = require("react/jsx-runtime");
@@ -1297,25 +1904,30 @@ function useConsentTexts() {
1297
1904
  function useConsentHydration() {
1298
1905
  return useConsentHydrationInternal();
1299
1906
  }
1907
+ function _registerGlobalOpenPreferences(openPreferences) {
1908
+ globalOpenPreferences = openPreferences;
1909
+ }
1910
+ function _unregisterGlobalOpenPreferences() {
1911
+ globalOpenPreferences = null;
1912
+ }
1300
1913
  function useOpenPreferencesModal() {
1301
- const { openPreferences } = useConsent();
1302
- return openPreferences;
1914
+ const actions = useConsentActionsInternal();
1915
+ if (!actions) {
1916
+ throw new Error(
1917
+ "[LGPD-CONSENT] useOpenPreferencesModal deve ser usado dentro do ConsentProvider. Envolva seu componente com <ConsentProvider>."
1918
+ );
1919
+ }
1920
+ return actions.openPreferences;
1303
1921
  }
1304
1922
  function openPreferencesModal() {
1305
1923
  if (globalOpenPreferences) {
1306
1924
  globalOpenPreferences();
1307
1925
  } else {
1308
1926
  logger.warn(
1309
- "openPreferencesModal: ConsentProvider n\xE3o foi inicializado ou n\xE3o est\xE1 dispon\xEDvel."
1927
+ "openPreferencesModal called but no ConsentProvider is mounted. Make sure ConsentProvider is rendered before calling this function."
1310
1928
  );
1311
1929
  }
1312
1930
  }
1313
- function _registerGlobalOpenPreferences(openPreferences) {
1314
- globalOpenPreferences = openPreferences;
1315
- }
1316
- function _unregisterGlobalOpenPreferences() {
1317
- globalOpenPreferences = null;
1318
- }
1319
1931
  var globalOpenPreferences;
1320
1932
  var init_useConsent = __esm({
1321
1933
  "src/hooks/useConsent.ts"() {
@@ -1338,7 +1950,7 @@ function PreferencesModal2({
1338
1950
  const { preferences, setPreferences, closePreferences, isModalOpen } = useConsent();
1339
1951
  const texts = useConsentTexts();
1340
1952
  const designTokens = useDesignTokens();
1341
- const { toggleableCategories } = useCategories();
1953
+ const { toggleableCategories, allCategories } = useCategories();
1342
1954
  const [tempPreferences, setTempPreferences] = (0, import_react2.useState)(() => {
1343
1955
  const initialPrefs = { necessary: true };
1344
1956
  toggleableCategories.forEach((category) => {
@@ -1363,43 +1975,126 @@ function PreferencesModal2({
1363
1975
  setTempPreferences(preferences);
1364
1976
  closePreferences();
1365
1977
  };
1978
+ const modalTitleSx = (theme) => ({
1979
+ fontSize: designTokens?.typography?.fontSize?.modal ?? void 0,
1980
+ color: designTokens?.colors?.text ?? theme.palette.text.primary
1981
+ });
1982
+ const modalContentSx = (theme) => ({
1983
+ p: designTokens?.spacing?.padding?.modal ?? void 0,
1984
+ backgroundColor: designTokens?.colors?.background ?? theme.palette.background.paper,
1985
+ color: designTokens?.colors?.text ?? theme.palette.text.primary
1986
+ });
1366
1987
  return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_Dialog.default, { "aria-labelledby": "cookie-pref-title", open, onClose: handleCancel, ...DialogProps2, children: [
1367
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
1368
- import_DialogTitle.default,
1369
- {
1370
- id: "cookie-pref-title",
1371
- sx: { fontSize: designTokens?.typography?.fontSize?.modal ?? void 0 },
1372
- children: texts.modalTitle
1373
- }
1374
- ),
1375
- /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_DialogContent.default, { dividers: true, sx: { p: designTokens?.spacing?.padding?.modal ?? void 0 }, children: [
1988
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_DialogTitle.default, { id: "cookie-pref-title", sx: modalTitleSx, children: texts.modalTitle }),
1989
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_DialogContent.default, { dividers: true, sx: modalContentSx, children: [
1376
1990
  /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
1377
1991
  import_Typography3.default,
1378
1992
  {
1379
1993
  variant: "body2",
1380
- sx: { mb: 2, fontSize: designTokens?.typography?.fontSize?.modal ?? void 0 },
1994
+ sx: (theme) => ({
1995
+ mb: 2,
1996
+ fontSize: designTokens?.typography?.fontSize?.modal ?? void 0,
1997
+ color: designTokens?.colors?.text ?? theme.palette.text.primary
1998
+ }),
1381
1999
  children: texts.modalIntro
1382
2000
  }
1383
2001
  ),
1384
2002
  /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_FormGroup.default, { children: [
1385
- toggleableCategories.map((category) => /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
1386
- import_FormControlLabel.default,
1387
- {
1388
- control: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
1389
- import_Switch.default,
2003
+ toggleableCategories.map((category) => {
2004
+ const full = allCategories.find((c) => c.id === category.id);
2005
+ const namesFromGuidance = full?.cookies ?? [];
2006
+ const used = globalThis.__LGPD_USED_INTEGRATIONS__ || [];
2007
+ const descriptors = getCookiesInfoForCategory(category.id, used);
2008
+ const enrichedDescriptors = descriptors.map((desc) => {
2009
+ if (desc.purpose && desc.duration && desc.provider) {
2010
+ return desc;
2011
+ }
2012
+ return {
2013
+ name: desc.name,
2014
+ purpose: desc.purpose || "-",
2015
+ duration: desc.duration || "-",
2016
+ provider: desc.provider || "-"
2017
+ };
2018
+ });
2019
+ const merged = [
2020
+ ...enrichedDescriptors,
2021
+ ...namesFromGuidance.filter((n) => !enrichedDescriptors.find((d) => d.name === n)).map((n) => ({ name: n, purpose: "-", duration: "-", provider: "-" }))
2022
+ ];
2023
+ let mergedFinal = merged;
2024
+ try {
2025
+ if (merged.length === 0) {
2026
+ const gmap = globalThis.__LGPD_INTEGRATIONS_MAP__ || {};
2027
+ const scriptRows = Object.entries(gmap).filter(([, cat]) => cat === category.id).map(([id]) => ({
2028
+ name: `(script) ${id}`,
2029
+ purpose: "Script de integra\xE7\xE3o ativo",
2030
+ duration: "-",
2031
+ provider: "-"
2032
+ }));
2033
+ if (scriptRows.length > 0) mergedFinal = scriptRows;
2034
+ }
2035
+ } catch {
2036
+ }
2037
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_Box2.default, { sx: { mb: 1 }, children: [
2038
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
2039
+ import_FormControlLabel.default,
1390
2040
  {
1391
- checked: tempPreferences[category.id] ?? false,
1392
- onChange: (e) => setTempPreferences((prev) => ({
1393
- ...prev,
1394
- [category.id]: e.target.checked
1395
- }))
2041
+ control: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
2042
+ import_Switch.default,
2043
+ {
2044
+ checked: tempPreferences[category.id] ?? false,
2045
+ onChange: (e) => setTempPreferences((prev) => ({
2046
+ ...prev,
2047
+ [category.id]: e.target.checked
2048
+ }))
2049
+ }
2050
+ ),
2051
+ label: `${category.name} - ${category.description}`
1396
2052
  }
1397
2053
  ),
1398
- label: `${category.name} - ${category.description}`
1399
- },
1400
- category.id
1401
- )),
1402
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_FormControlLabel.default, { control: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_Switch.default, { checked: true, disabled: true }), label: texts.necessaryAlwaysOn })
2054
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("details", { style: { marginLeft: 48 }, children: [
2055
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("summary", { children: "Ver detalhes" }),
2056
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_Box2.default, { sx: { mt: 1 }, children: /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("table", { style: { width: "100%", borderCollapse: "collapse" }, children: [
2057
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("thead", { children: /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("tr", { children: [
2058
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("th", { style: { textAlign: "left" }, children: "Cookie" }),
2059
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("th", { style: { textAlign: "left" }, children: "Finalidade" }),
2060
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("th", { style: { textAlign: "left" }, children: "Dura\xE7\xE3o" }),
2061
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("th", { style: { textAlign: "left" }, children: "Fornecedor" })
2062
+ ] }) }),
2063
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("tbody", { children: mergedFinal.map((d, idx) => /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("tr", { children: [
2064
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("td", { children: d.name }),
2065
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("td", { children: d.purpose }),
2066
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("td", { children: d.duration }),
2067
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("td", { children: d.provider })
2068
+ ] }, d.name + idx)) })
2069
+ ] }) })
2070
+ ] })
2071
+ ] }, category.id);
2072
+ }),
2073
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_FormControlLabel.default, { control: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_Switch.default, { checked: true, disabled: true }), label: texts.necessaryAlwaysOn }),
2074
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("details", { style: { marginLeft: 48 }, children: [
2075
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("summary", { children: "Ver detalhes" }),
2076
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_Box2.default, { sx: { mt: 1 }, children: /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("table", { style: { width: "100%", borderCollapse: "collapse" }, children: [
2077
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("thead", { children: /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("tr", { children: [
2078
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("th", { style: { textAlign: "left" }, children: "Cookie" }),
2079
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("th", { style: { textAlign: "left" }, children: "Finalidade" }),
2080
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("th", { style: { textAlign: "left" }, children: "Dura\xE7\xE3o" }),
2081
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("th", { style: { textAlign: "left" }, children: "Fornecedor" })
2082
+ ] }) }),
2083
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("tbody", { children: (() => {
2084
+ const used = globalThis.__LGPD_USED_INTEGRATIONS__ || [];
2085
+ const necessaryCookies = getCookiesInfoForCategory(
2086
+ "necessary",
2087
+ used
2088
+ );
2089
+ return necessaryCookies.map((d, idx) => /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("tr", { children: [
2090
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("td", { children: d.name }),
2091
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("td", { children: d.purpose || "-" }),
2092
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("td", { children: d.duration || "-" }),
2093
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("td", { children: d.provider || "-" })
2094
+ ] }, d.name + idx));
2095
+ })() })
2096
+ ] }) })
2097
+ ] })
1403
2098
  ] })
1404
2099
  ] }),
1405
2100
  /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_DialogActions.default, { children: [
@@ -1409,10 +2104,11 @@ function PreferencesModal2({
1409
2104
  !hideBranding && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Branding, { variant: "modal" })
1410
2105
  ] });
1411
2106
  }
1412
- var import_Button2, import_Dialog, import_DialogActions, import_DialogContent, import_DialogTitle, import_FormControlLabel, import_FormGroup, import_Switch, import_Typography3, import_react2, import_jsx_runtime7;
2107
+ var import_Box2, import_Button2, import_Dialog, import_DialogActions, import_DialogContent, import_DialogTitle, import_FormControlLabel, import_FormGroup, import_Switch, import_Typography3, import_react2, import_jsx_runtime7;
1413
2108
  var init_PreferencesModal = __esm({
1414
2109
  "src/components/PreferencesModal.tsx"() {
1415
2110
  "use strict";
2111
+ import_Box2 = __toESM(require("@mui/material/Box"), 1);
1416
2112
  import_Button2 = __toESM(require("@mui/material/Button"), 1);
1417
2113
  import_Dialog = __toESM(require("@mui/material/Dialog"), 1);
1418
2114
  import_DialogActions = __toESM(require("@mui/material/DialogActions"), 1);
@@ -1424,8 +2120,9 @@ var init_PreferencesModal = __esm({
1424
2120
  import_Typography3 = __toESM(require("@mui/material/Typography"), 1);
1425
2121
  import_react2 = require("react");
1426
2122
  init_CategoriesContext();
1427
- init_useConsent();
1428
2123
  init_DesignContext();
2124
+ init_useConsent();
2125
+ init_cookieRegistry();
1429
2126
  init_Branding();
1430
2127
  import_jsx_runtime7 = require("react/jsx-runtime");
1431
2128
  }
@@ -1440,28 +2137,56 @@ __export(index_exports, {
1440
2137
  ConsentScriptLoader: () => ConsentScriptLoader,
1441
2138
  CookieBanner: () => CookieBanner,
1442
2139
  DEFAULT_PROJECT_CATEGORIES: () => DEFAULT_PROJECT_CATEGORIES,
2140
+ EXPANDED_DEFAULT_TEXTS: () => EXPANDED_DEFAULT_TEXTS,
1443
2141
  FloatingPreferencesButton: () => FloatingPreferencesButton,
2142
+ GUIDANCE_PRESETS: () => GUIDANCE_PRESETS,
2143
+ INTEGRATION_TEMPLATES: () => INTEGRATION_TEMPLATES,
1444
2144
  LogLevel: () => LogLevel,
1445
2145
  PreferencesModal: () => PreferencesModal2,
2146
+ TEXT_TEMPLATES: () => TEXT_TEMPLATES,
1446
2147
  analyzeDeveloperConfiguration: () => analyzeDeveloperConfiguration,
2148
+ analyzeIntegrationCategories: () => analyzeIntegrationCategories,
2149
+ autoConfigureCategories: () => autoConfigureCategories,
2150
+ categorizeDiscoveredCookies: () => categorizeDiscoveredCookies,
2151
+ createClarityIntegration: () => createClarityIntegration,
2152
+ createCorporateIntegrations: () => createCorporateIntegrations,
1447
2153
  createDefaultConsentTheme: () => createDefaultConsentTheme,
2154
+ createECommerceIntegrations: () => createECommerceIntegrations,
2155
+ createFacebookPixelIntegration: () => createFacebookPixelIntegration,
1448
2156
  createGoogleAnalyticsIntegration: () => createGoogleAnalyticsIntegration,
1449
2157
  createGoogleTagManagerIntegration: () => createGoogleTagManagerIntegration,
2158
+ createHotjarIntegration: () => createHotjarIntegration,
2159
+ createIntercomIntegration: () => createIntercomIntegration,
2160
+ createMixpanelIntegration: () => createMixpanelIntegration,
1450
2161
  createProjectPreferences: () => createProjectPreferences,
2162
+ createSaaSIntegrations: () => createSaaSIntegrations,
1451
2163
  createUserWayIntegration: () => createUserWayIntegration,
2164
+ createZendeskChatIntegration: () => createZendeskChatIntegration,
1452
2165
  defaultConsentTheme: () => defaultConsentTheme,
1453
2166
  defaultTexts: () => defaultTexts,
2167
+ detectConsentCookieName: () => detectConsentCookieName,
2168
+ discoverRuntimeCookies: () => discoverRuntimeCookies,
2169
+ extractCategoriesFromIntegrations: () => extractCategoriesFromIntegrations,
1454
2170
  getAllProjectCategories: () => getAllProjectCategories,
2171
+ getCookiesInfoForCategory: () => getCookiesInfoForCategory,
1455
2172
  loadScript: () => loadScript,
2173
+ logDeveloperGuidance: () => logDeveloperGuidance,
1456
2174
  openPreferencesModal: () => openPreferencesModal,
2175
+ resolveTexts: () => resolveTexts,
2176
+ setCookieCatalogOverrides: () => setCookieCatalogOverrides,
2177
+ setCookieCategoryOverrides: () => setCookieCategoryOverrides,
1457
2178
  setDebugLogging: () => setDebugLogging,
2179
+ suggestCategoryForScript: () => suggestCategoryForScript,
1458
2180
  useCategories: () => useCategories,
1459
2181
  useCategoryStatus: () => useCategoryStatus,
1460
2182
  useConsent: () => useConsent,
1461
2183
  useConsentHydration: () => useConsentHydration,
1462
2184
  useConsentScriptLoader: () => useConsentScriptLoader,
1463
2185
  useConsentTexts: () => useConsentTexts,
2186
+ useDeveloperGuidance: () => useDeveloperGuidance,
1464
2187
  useOpenPreferencesModal: () => useOpenPreferencesModal,
2188
+ validateIntegrationCategories: () => validateIntegrationCategories,
2189
+ validateNecessaryClassification: () => validateNecessaryClassification,
1465
2190
  validateProjectPreferences: () => validateProjectPreferences
1466
2191
  });
1467
2192
  module.exports = __toCommonJS(index_exports);
@@ -1516,6 +2241,9 @@ function loadScript(id, src, category = null, attrs = {}) {
1516
2241
  });
1517
2242
  }
1518
2243
 
2244
+ // src/index.ts
2245
+ init_cookieDiscovery();
2246
+
1519
2247
  // src/utils/theme.ts
1520
2248
  var import_styles3 = require("@mui/material/styles");
1521
2249
  function createDefaultConsentTheme() {
@@ -1589,14 +2317,233 @@ var defaultConsentTheme = () => createDefaultConsentTheme();
1589
2317
 
1590
2318
  // src/utils/ConsentScriptLoader.tsx
1591
2319
  var React5 = __toESM(require("react"), 1);
2320
+ init_CategoriesContext();
1592
2321
  init_useConsent();
2322
+
2323
+ // src/utils/autoConfigureCategories.ts
2324
+ var FORBIDDEN_NECESSARY_SCRIPTS = /* @__PURE__ */ new Set([
2325
+ // Analytics & Performance
2326
+ "google-analytics",
2327
+ "google-tag-manager",
2328
+ "hotjar",
2329
+ "mixpanel",
2330
+ "clarity",
2331
+ "amplitude",
2332
+ "segment",
2333
+ // Marketing & Advertising
2334
+ "facebook-pixel",
2335
+ "twitter-pixel",
2336
+ "linkedin-insight",
2337
+ "pinterest-tag",
2338
+ "snapchat-pixel",
2339
+ "tiktok-pixel",
2340
+ "reddit-pixel",
2341
+ // Communication & Support
2342
+ "intercom",
2343
+ "zendesk-chat",
2344
+ "drift",
2345
+ "crisp",
2346
+ "freshchat",
2347
+ // A/B Testing & Optimization
2348
+ "optimizely",
2349
+ "vwo",
2350
+ "google-optimize",
2351
+ "unbounce",
2352
+ // Social & Content
2353
+ "youtube-embed",
2354
+ "vimeo-embed",
2355
+ "twitter-widget",
2356
+ "facebook-widget",
2357
+ "instagram-widget",
2358
+ // Accessibility (exceto scripts críticos)
2359
+ "userway"
2360
+ ]);
2361
+ function analyzeIntegrationCategories(integrations) {
2362
+ const categoryMap = {};
2363
+ integrations.forEach((integration) => {
2364
+ const category = integration.category;
2365
+ if (!categoryMap[category]) {
2366
+ categoryMap[category] = [];
2367
+ }
2368
+ categoryMap[category].push(integration.id);
2369
+ });
2370
+ return categoryMap;
2371
+ }
2372
+ function autoConfigureCategories(originalConfig, integrations, options = {}) {
2373
+ const { warningOnly = false, silent = false } = options;
2374
+ const config = originalConfig || { enabledCategories: ["analytics"] };
2375
+ const categoryIntegrations = analyzeIntegrationCategories(integrations);
2376
+ const requiredCategories = Object.keys(categoryIntegrations);
2377
+ const currentCategories = new Set(config.enabledCategories || []);
2378
+ const missingCategories = requiredCategories.filter((cat) => !currentCategories.has(cat));
2379
+ let adjustedConfig = { ...config };
2380
+ let autoEnabledCategories = [];
2381
+ if (missingCategories.length > 0) {
2382
+ if (warningOnly) {
2383
+ if (!silent) {
2384
+ logMissingCategoriesWarning(missingCategories, categoryIntegrations);
2385
+ }
2386
+ } else {
2387
+ autoEnabledCategories = [...missingCategories];
2388
+ adjustedConfig = {
2389
+ ...config,
2390
+ enabledCategories: [...currentCategories, ...missingCategories]
2391
+ };
2392
+ if (!silent) {
2393
+ logAutoEnabledCategories(autoEnabledCategories, categoryIntegrations);
2394
+ }
2395
+ }
2396
+ }
2397
+ return {
2398
+ originalConfig: config,
2399
+ adjustedConfig,
2400
+ autoEnabledCategories,
2401
+ missingCategories,
2402
+ wasAdjusted: autoEnabledCategories.length > 0,
2403
+ categoryIntegrations
2404
+ };
2405
+ }
2406
+ function logMissingCategoriesWarning(missingCategories, categoryIntegrations) {
2407
+ const isDev = process.env.NODE_ENV !== "production";
2408
+ if (!isDev) return;
2409
+ const PREFIX = "[\u{1F36A} LGPD-CONSENT AUTO-CONFIG]";
2410
+ console.group(`${PREFIX} \u26A0\uFE0F Categorias Requeridas N\xE3o Habilitadas`);
2411
+ missingCategories.forEach((category) => {
2412
+ const integrations = categoryIntegrations[category] || [];
2413
+ console.warn(
2414
+ `${PREFIX} Categoria '${category}' requerida por integra\xE7\xF5es: ${integrations.join(", ")}`
2415
+ );
2416
+ });
2417
+ const categoriesCode = missingCategories.map((c) => `'${c}'`).join(", ");
2418
+ console.warn(
2419
+ `${PREFIX} Para corrigir, adicione estas categorias ao ConsentProvider:`,
2420
+ `categories={{ enabledCategories: [...existingCategories, ${categoriesCode}] }}`
2421
+ );
2422
+ console.groupEnd();
2423
+ }
2424
+ function logAutoEnabledCategories(autoEnabledCategories, categoryIntegrations) {
2425
+ const isDev = process.env.NODE_ENV !== "production";
2426
+ if (!isDev) return;
2427
+ const PREFIX = "[\u{1F36A} LGPD-CONSENT AUTO-CONFIG]";
2428
+ console.group(`${PREFIX} \u2705 Categorias Auto-Habilitadas`);
2429
+ autoEnabledCategories.forEach((category) => {
2430
+ const integrations = categoryIntegrations[category] || [];
2431
+ console.info(
2432
+ `${PREFIX} Categoria '${category}' auto-habilitada para integra\xE7\xF5es: ${integrations.join(", ")}`
2433
+ );
2434
+ });
2435
+ console.info(`${PREFIX} \u{1F4A1} Essas categorias foram automaticamente adicionadas \xE0 configura\xE7\xE3o.`);
2436
+ console.info(`${PREFIX} \u{1F527} Para controle manual, especifique explicitamente no ConsentProvider.`);
2437
+ console.groupEnd();
2438
+ }
2439
+ function validateIntegrationCategories(integrations, enabledCategories) {
2440
+ const requiredCategories = integrations.map((i) => i.category);
2441
+ const enabledSet = new Set(enabledCategories);
2442
+ return requiredCategories.every((category) => enabledSet.has(category));
2443
+ }
2444
+ function extractCategoriesFromIntegrations(integrations) {
2445
+ const categories = /* @__PURE__ */ new Set();
2446
+ integrations.forEach((integration) => {
2447
+ categories.add(integration.category);
2448
+ });
2449
+ return Array.from(categories);
2450
+ }
2451
+ function validateNecessaryClassification(integrations, enabledCategories) {
2452
+ const warnings = [];
2453
+ const hasNecessaryCategory = enabledCategories.includes("necessary");
2454
+ if (!hasNecessaryCategory) {
2455
+ return warnings;
2456
+ }
2457
+ const problematicIntegrations = integrations.filter(
2458
+ (integration) => integration.category === "necessary" && FORBIDDEN_NECESSARY_SCRIPTS.has(integration.id)
2459
+ );
2460
+ if (problematicIntegrations.length > 0) {
2461
+ warnings.push(
2462
+ `\u26A0\uFE0F ATEN\xC7\xC3O GDPR/LGPD: As seguintes integra\xE7\xF5es NUNCA devem ser classificadas como 'necessary':`
2463
+ );
2464
+ problematicIntegrations.forEach((integration) => {
2465
+ warnings.push(
2466
+ ` \u2022 '${integration.id}' (categoria: ${integration.category}) - Requer consentimento expl\xEDcito`
2467
+ );
2468
+ });
2469
+ warnings.push(
2470
+ `\u{1F4A1} Scripts 'necessary' executam SEM consentimento e podem resultar em multas.`,
2471
+ `\u{1F4DA} Apenas scripts de seguran\xE7a, autentica\xE7\xE3o ou core do site se qualificam.`,
2472
+ `\u{1F527} Mova estes scripts para categorias apropriadas (analytics, marketing, etc.)`
2473
+ );
2474
+ }
2475
+ return warnings;
2476
+ }
2477
+
2478
+ // src/utils/ConsentScriptLoader.tsx
1593
2479
  init_logger();
1594
2480
  function ConsentScriptLoader({
1595
2481
  integrations,
1596
2482
  reloadOnChange = false
1597
2483
  }) {
1598
2484
  const { preferences, consented } = useConsent();
2485
+ const categories = useCategories();
1599
2486
  const loadedScripts = React5.useRef(/* @__PURE__ */ new Set());
2487
+ React5.useEffect(() => {
2488
+ try {
2489
+ const ids = (integrations || []).map((i) => i.id);
2490
+ const gt = globalThis;
2491
+ const current = Array.isArray(gt.__LGPD_USED_INTEGRATIONS__) ? gt.__LGPD_USED_INTEGRATIONS__ : [];
2492
+ const merged = Array.from(/* @__PURE__ */ new Set([...current, ...ids]));
2493
+ gt.__LGPD_USED_INTEGRATIONS__ = merged;
2494
+ try {
2495
+ const gmap = globalThis;
2496
+ const map = gmap.__LGPD_INTEGRATIONS_MAP__ || {};
2497
+ (integrations || []).forEach((i) => {
2498
+ map[i.id] = i.category;
2499
+ });
2500
+ gmap.__LGPD_INTEGRATIONS_MAP__ = map;
2501
+ } catch {
2502
+ }
2503
+ } catch {
2504
+ }
2505
+ }, [integrations]);
2506
+ React5.useEffect(() => {
2507
+ try {
2508
+ const required = Array.from(new Set((integrations || []).map((i) => i.category))).filter(
2509
+ Boolean
2510
+ );
2511
+ const gt = globalThis;
2512
+ const current = Array.isArray(gt.__LGPD_REQUIRED_CATEGORIES__) ? gt.__LGPD_REQUIRED_CATEGORIES__ : [];
2513
+ const merged = Array.from(/* @__PURE__ */ new Set([...current, ...required]));
2514
+ gt.__LGPD_REQUIRED_CATEGORIES__ = merged;
2515
+ if (typeof window !== "undefined" && typeof window.dispatchEvent === "function") {
2516
+ window.dispatchEvent(new CustomEvent("lgpd:requiredCategories"));
2517
+ }
2518
+ } catch {
2519
+ }
2520
+ }, [integrations]);
2521
+ React5.useEffect(() => {
2522
+ const isDev = process.env.NODE_ENV !== "production";
2523
+ if (!isDev || integrations.length === 0) return;
2524
+ const enabledCategories = categories.allCategories.map((cat) => cat.id);
2525
+ const isValid = validateIntegrationCategories(integrations, enabledCategories);
2526
+ if (!isValid) {
2527
+ autoConfigureCategories({ enabledCategories }, integrations, {
2528
+ warningOnly: true,
2529
+ silent: false
2530
+ });
2531
+ }
2532
+ const necessaryWarnings = validateNecessaryClassification(integrations, enabledCategories);
2533
+ if (necessaryWarnings.length > 0) {
2534
+ console.group("\u{1F6A8} [LGPD-CONSENT] VALIDA\xC7\xC3O DE COMPLIANCE");
2535
+ necessaryWarnings.forEach((warning) => {
2536
+ if (warning.startsWith("\u26A0\uFE0F")) {
2537
+ console.error(warning);
2538
+ } else if (warning.startsWith("\u{1F4A1}") || warning.startsWith("\u{1F4DA}") || warning.startsWith("\u{1F527}")) {
2539
+ console.warn(warning);
2540
+ } else {
2541
+ console.log(warning);
2542
+ }
2543
+ });
2544
+ console.groupEnd();
2545
+ }
2546
+ }, [integrations, categories]);
1600
2547
  React5.useEffect(() => {
1601
2548
  if (!consented) return;
1602
2549
  integrations.forEach(async (integration) => {
@@ -1649,10 +2596,32 @@ function useConsentScriptLoader() {
1649
2596
 
1650
2597
  // src/utils/scriptIntegrations.ts
1651
2598
  function createGoogleAnalyticsIntegration(config) {
2599
+ const src = config.scriptUrl ?? `https://www.googletagmanager.com/gtag/js?id=${config.measurementId}`;
1652
2600
  return {
1653
2601
  id: "google-analytics",
1654
2602
  category: "analytics",
1655
- src: `https://www.googletagmanager.com/gtag/js?id=${config.measurementId}`,
2603
+ src,
2604
+ cookies: ["_ga", "_ga_*", "_gid"],
2605
+ cookiesInfo: [
2606
+ {
2607
+ name: "_ga",
2608
+ purpose: "Identifica\xE7\xE3o \xFAnica de visitantes para an\xE1lise de tr\xE1fego",
2609
+ duration: "2 anos",
2610
+ provider: "Google Analytics"
2611
+ },
2612
+ {
2613
+ name: "_ga_*",
2614
+ purpose: "Rastreamento de sess\xF5es e eventos espec\xEDficos do stream GA4",
2615
+ duration: "2 anos",
2616
+ provider: "Google Analytics"
2617
+ },
2618
+ {
2619
+ name: "_gid",
2620
+ purpose: "Distin\xE7\xE3o de visitantes \xFAnicos em per\xEDodo de 24h",
2621
+ duration: "24 horas",
2622
+ provider: "Google Analytics"
2623
+ }
2624
+ ],
1656
2625
  init: () => {
1657
2626
  if (typeof window !== "undefined") {
1658
2627
  const w = window;
@@ -1669,29 +2638,30 @@ function createGoogleAnalyticsIntegration(config) {
1669
2638
  };
1670
2639
  }
1671
2640
  function createGoogleTagManagerIntegration(config) {
2641
+ const src = config.scriptUrl ?? `https://www.googletagmanager.com/gtm.js?id=${config.containerId}`;
1672
2642
  return {
1673
2643
  id: "google-tag-manager",
1674
2644
  category: "analytics",
1675
- src: `https://www.googletagmanager.com/gtm.js?id=${config.containerId}`,
2645
+ src,
2646
+ cookies: ["_gcl_au"],
1676
2647
  init: () => {
1677
2648
  if (typeof window !== "undefined") {
1678
2649
  const dataLayerName = config.dataLayerName || "dataLayer";
1679
2650
  const w = window;
1680
2651
  const layer = w[dataLayerName] ?? [];
1681
2652
  w[dataLayerName] = layer;
1682
- layer.push({
1683
- "gtm.start": (/* @__PURE__ */ new Date()).getTime(),
1684
- event: "gtm.js"
1685
- });
2653
+ layer.push({ "gtm.start": (/* @__PURE__ */ new Date()).getTime(), event: "gtm.js" });
1686
2654
  }
1687
2655
  }
1688
2656
  };
1689
2657
  }
1690
2658
  function createUserWayIntegration(config) {
2659
+ const src = config.scriptUrl ?? "https://cdn.userway.org/widget.js";
1691
2660
  return {
1692
2661
  id: "userway",
1693
2662
  category: "functional",
1694
- src: "https://cdn.userway.org/widget.js",
2663
+ src,
2664
+ cookies: ["_userway_*"],
1695
2665
  init: () => {
1696
2666
  if (typeof window !== "undefined") {
1697
2667
  const w = window;
@@ -1707,10 +2677,463 @@ var COMMON_INTEGRATIONS = {
1707
2677
  googleTagManager: createGoogleTagManagerIntegration,
1708
2678
  userway: createUserWayIntegration
1709
2679
  };
2680
+ function createFacebookPixelIntegration(config) {
2681
+ const src = config.scriptUrl ?? "https://connect.facebook.net/en_US/fbevents.js";
2682
+ return {
2683
+ id: "facebook-pixel",
2684
+ category: "marketing",
2685
+ src,
2686
+ cookies: ["_fbp", "fr"],
2687
+ init: () => {
2688
+ if (typeof window !== "undefined") {
2689
+ const w = window;
2690
+ if (!w.fbq) {
2691
+ const fbq = (...args) => {
2692
+ if (w.fbq && typeof w.fbq.callMethod === "function") {
2693
+ w.fbq.callMethod(...args);
2694
+ } else {
2695
+ fbq.queue = fbq.queue || [];
2696
+ fbq.queue.push(args);
2697
+ }
2698
+ };
2699
+ fbq.loaded = true;
2700
+ w.fbq = fbq;
2701
+ }
2702
+ w.fbq("init", config.pixelId, config.advancedMatching ?? {});
2703
+ if (config.autoTrack !== false) w.fbq("track", "PageView");
2704
+ }
2705
+ }
2706
+ };
2707
+ }
2708
+ function createHotjarIntegration(config) {
2709
+ const v = config.version ?? 6;
2710
+ const src = config.scriptUrl ?? `https://static.hotjar.com/c/hotjar-${config.siteId}.js?sv=${v}`;
2711
+ return {
2712
+ id: "hotjar",
2713
+ category: "analytics",
2714
+ src,
2715
+ cookies: [
2716
+ "_hjSession_*",
2717
+ "_hjSessionUser_*",
2718
+ "_hjFirstSeen",
2719
+ "_hjIncludedInSessionSample",
2720
+ "_hjAbsoluteSessionInProgress"
2721
+ ],
2722
+ cookiesInfo: [
2723
+ {
2724
+ name: "_hjSession_*",
2725
+ purpose: "Identifica\xE7\xE3o \xFAnica da sess\xE3o de grava\xE7\xE3o e heatmaps",
2726
+ duration: "30 minutos",
2727
+ provider: "Hotjar"
2728
+ },
2729
+ {
2730
+ name: "_hjSessionUser_*",
2731
+ purpose: "Identifica\xE7\xE3o persistente do usu\xE1rio entre sess\xF5es",
2732
+ duration: "365 dias",
2733
+ provider: "Hotjar"
2734
+ },
2735
+ {
2736
+ name: "_hjFirstSeen",
2737
+ purpose: "Detec\xE7\xE3o de primeira visita do usu\xE1rio ao site",
2738
+ duration: "Sess\xE3o",
2739
+ provider: "Hotjar"
2740
+ },
2741
+ {
2742
+ name: "_hjIncludedInSessionSample",
2743
+ purpose: "Indica se a sess\xE3o est\xE1 inclu\xEDda na amostra de grava\xE7\xE3o",
2744
+ duration: "30 minutos",
2745
+ provider: "Hotjar"
2746
+ },
2747
+ {
2748
+ name: "_hjAbsoluteSessionInProgress",
2749
+ purpose: "Detecta se uma sess\xE3o absoluta est\xE1 em progresso",
2750
+ duration: "30 minutos",
2751
+ provider: "Hotjar"
2752
+ }
2753
+ ],
2754
+ init: () => {
2755
+ if (typeof window !== "undefined") {
2756
+ const w = window;
2757
+ w._hjSettings = { hjid: config.siteId, hjsv: v };
2758
+ if (!w.hj) {
2759
+ const hj = (...args) => {
2760
+ hj.q = hj.q || [];
2761
+ hj.q.push(args);
2762
+ };
2763
+ w.hj = hj;
2764
+ }
2765
+ if (config.debug && typeof console !== "undefined" && typeof console.info === "function") {
2766
+ console.info("[Hotjar] initialized with siteId", config.siteId);
2767
+ }
2768
+ }
2769
+ }
2770
+ };
2771
+ }
2772
+ function createMixpanelIntegration(config) {
2773
+ const src = config.scriptUrl ?? "https://cdn.mxpnl.com/libs/mixpanel-2-latest.min.js";
2774
+ return {
2775
+ id: "mixpanel",
2776
+ category: "analytics",
2777
+ src,
2778
+ cookies: ["mp_*"],
2779
+ cookiesInfo: [
2780
+ {
2781
+ name: "mp_*",
2782
+ purpose: "Rastreamento de eventos e propriedades do usu\xE1rio para analytics",
2783
+ duration: "1 ano",
2784
+ provider: "Mixpanel"
2785
+ }
2786
+ ],
2787
+ init: () => {
2788
+ if (typeof window !== "undefined") {
2789
+ const w = window;
2790
+ w.mixpanel = w.mixpanel || { init: () => void 0 };
2791
+ if (w.mixpanel && typeof w.mixpanel.init === "function") {
2792
+ try {
2793
+ w.mixpanel.init(config.token, config.config ?? {}, config.api_host);
2794
+ } catch (error) {
2795
+ if (typeof console !== "undefined" && typeof console.warn === "function") {
2796
+ console.warn("[Mixpanel] Failed to initialize:", error);
2797
+ }
2798
+ }
2799
+ }
2800
+ }
2801
+ }
2802
+ };
2803
+ }
2804
+ function createClarityIntegration(config) {
2805
+ const src = config.scriptUrl ?? `https://www.clarity.ms/tag/${config.projectId}`;
2806
+ return {
2807
+ id: "clarity",
2808
+ category: "analytics",
2809
+ src,
2810
+ cookies: ["_clck", "_clsk", "CLID", "ANONCHK", "MR", "MUID", "SM"],
2811
+ init: () => {
2812
+ if (typeof window !== "undefined" && typeof config.upload !== "undefined") {
2813
+ const w = window;
2814
+ if (typeof w.clarity === "function") {
2815
+ try {
2816
+ w.clarity("set", "upload", config.upload);
2817
+ } catch (error) {
2818
+ if (typeof console !== "undefined" && typeof console.warn === "function") {
2819
+ console.warn("[Clarity] Failed to configure upload setting:", error);
2820
+ }
2821
+ }
2822
+ }
2823
+ }
2824
+ }
2825
+ };
2826
+ }
2827
+ function createIntercomIntegration(config) {
2828
+ const src = config.scriptUrl ?? `https://widget.intercom.io/widget/${config.app_id}`;
2829
+ return {
2830
+ id: "intercom",
2831
+ category: "functional",
2832
+ src,
2833
+ cookies: ["intercom-id-*", "intercom-session-*"],
2834
+ init: () => {
2835
+ if (typeof window !== "undefined") {
2836
+ const w = window;
2837
+ if (typeof w.Intercom === "function") {
2838
+ try {
2839
+ w.Intercom("boot", { app_id: config.app_id });
2840
+ } catch (error) {
2841
+ if (typeof console !== "undefined" && typeof console.warn === "function") {
2842
+ console.warn("[Intercom] Failed to boot:", error);
2843
+ }
2844
+ }
2845
+ }
2846
+ }
2847
+ }
2848
+ };
2849
+ }
2850
+ function createZendeskChatIntegration(config) {
2851
+ const src = config.scriptUrl ?? `https://static.zdassets.com/ekr/snippet.js?key=${config.key}`;
2852
+ return {
2853
+ id: "zendesk-chat",
2854
+ category: "functional",
2855
+ src,
2856
+ cookies: ["__zlcmid", "_zendesk_shared_session"],
2857
+ init: () => {
2858
+ if (typeof window !== "undefined") {
2859
+ const w = window;
2860
+ if (typeof w.zE === "function") {
2861
+ try {
2862
+ w.zE("webWidget", "identify", { key: config.key });
2863
+ } catch (error) {
2864
+ if (typeof console !== "undefined" && typeof console.warn === "function") {
2865
+ console.warn("[Zendesk] Failed to identify:", error);
2866
+ }
2867
+ }
2868
+ }
2869
+ }
2870
+ }
2871
+ };
2872
+ }
2873
+ function createECommerceIntegrations(cfg) {
2874
+ const list = [];
2875
+ if (cfg.googleAnalytics) list.push(createGoogleAnalyticsIntegration(cfg.googleAnalytics));
2876
+ if (cfg.facebookPixel) list.push(createFacebookPixelIntegration(cfg.facebookPixel));
2877
+ if (cfg.hotjar) list.push(createHotjarIntegration(cfg.hotjar));
2878
+ if (cfg.userway) list.push(createUserWayIntegration(cfg.userway));
2879
+ return list;
2880
+ }
2881
+ function createSaaSIntegrations(cfg) {
2882
+ const list = [];
2883
+ if (cfg.googleAnalytics) list.push(createGoogleAnalyticsIntegration(cfg.googleAnalytics));
2884
+ if (cfg.mixpanel) list.push(createMixpanelIntegration(cfg.mixpanel));
2885
+ if (cfg.intercom) list.push(createIntercomIntegration(cfg.intercom));
2886
+ if (cfg.hotjar) list.push(createHotjarIntegration(cfg.hotjar));
2887
+ return list;
2888
+ }
2889
+ function createCorporateIntegrations(cfg) {
2890
+ const list = [];
2891
+ if (cfg.googleAnalytics) list.push(createGoogleAnalyticsIntegration(cfg.googleAnalytics));
2892
+ if (cfg.clarity) list.push(createClarityIntegration(cfg.clarity));
2893
+ if (cfg.zendesk) list.push(createZendeskChatIntegration(cfg.zendesk));
2894
+ if (cfg.userway) list.push(createUserWayIntegration(cfg.userway));
2895
+ return list;
2896
+ }
2897
+ var INTEGRATION_TEMPLATES = {
2898
+ ecommerce: {
2899
+ essential: ["google-analytics", "facebook-pixel"],
2900
+ optional: ["hotjar", "userway"],
2901
+ categories: ["analytics", "marketing", "functional"]
2902
+ },
2903
+ saas: {
2904
+ essential: ["google-analytics", "mixpanel"],
2905
+ optional: ["intercom", "hotjar"],
2906
+ categories: ["analytics", "functional"]
2907
+ },
2908
+ corporate: {
2909
+ essential: ["google-analytics"],
2910
+ optional: ["userway", "zendesk-chat", "clarity"],
2911
+ categories: ["analytics", "functional"]
2912
+ }
2913
+ };
2914
+ function suggestCategoryForScript(name) {
2915
+ const n = name.toLowerCase();
2916
+ if (n.includes("facebook") || n.includes("pixel") || n.includes("ads")) return ["marketing"];
2917
+ if (n.includes("hotjar") || n.includes("mixpanel") || n.includes("clarity")) return ["analytics"];
2918
+ if (n.includes("intercom") || n.includes("zendesk") || n.includes("chat")) return ["functional"];
2919
+ return ["analytics"];
2920
+ }
2921
+
2922
+ // src/types/advancedTexts.ts
2923
+ var EXPANDED_DEFAULT_TEXTS = {
2924
+ // Textos adicionais
2925
+ confirm: "Confirmar",
2926
+ cancel: "Cancelar",
2927
+ loading: "Carregando...",
2928
+ // Feedback
2929
+ feedback: {
2930
+ saveSuccess: "Prefer\xEAncias salvas com sucesso!",
2931
+ saveError: "Erro ao salvar prefer\xEAncias. Tente novamente.",
2932
+ consentUpdated: "Consentimento atualizado.",
2933
+ cookiesRejected: "Cookies opcionais rejeitados.",
2934
+ settingsReset: "Configura\xE7\xF5es resetadas."
2935
+ },
2936
+ // Acessibilidade
2937
+ accessibility: {
2938
+ bannerLabel: "Banner de consentimento de cookies",
2939
+ modalLabel: "Modal de prefer\xEAncias de cookies",
2940
+ keyboardNavigation: "Use Tab para navegar, Enter para selecionar",
2941
+ toggleState: {
2942
+ enabled: "Habilitado",
2943
+ disabled: "Desabilitado"
2944
+ },
2945
+ liveRegion: "Regi\xE3o de an\xFAncios din\xE2micos"
2946
+ },
2947
+ // Categorias
2948
+ categories: {
2949
+ necessary: {
2950
+ name: "Cookies Necess\xE1rios",
2951
+ description: "Essenciais para o funcionamento b\xE1sico do site",
2952
+ examples: "Sess\xE3o, seguran\xE7a, prefer\xEAncias de idioma"
2953
+ },
2954
+ analytics: {
2955
+ name: "Cookies de Analytics",
2956
+ description: "Ajudam a entender como os visitantes usam o site",
2957
+ examples: "Google Analytics, contadores de p\xE1gina"
2958
+ },
2959
+ marketing: {
2960
+ name: "Cookies de Marketing",
2961
+ description: "Usados para personalizar an\xFAncios e ofertas",
2962
+ examples: "Facebook Pixel, Google Ads, remarketing"
2963
+ },
2964
+ functional: {
2965
+ name: "Cookies Funcionais",
2966
+ description: "Melhoram a funcionalidade e personaliza\xE7\xE3o",
2967
+ examples: "Chat, mapas, v\xEDdeos embarcados"
2968
+ },
2969
+ performance: {
2970
+ name: "Cookies de Performance",
2971
+ description: "Coletam informa\xE7\xF5es sobre velocidade e estabilidade",
2972
+ examples: "Monitoramento de erro, otimiza\xE7\xE3o de velocidade"
2973
+ }
2974
+ },
2975
+ // Contextos específicos
2976
+ contexts: {
2977
+ ecommerce: {
2978
+ cartAbandonment: "Lembramos dos produtos no seu carrinho",
2979
+ personalizedOffers: "Ofertas personalizadas baseadas no seu hist\xF3rico",
2980
+ paymentSecurity: "Seguran\xE7a adicional no processo de pagamento",
2981
+ productRecommendations: "Sugest\xF5es de produtos relevantes"
2982
+ },
2983
+ saas: {
2984
+ userAnalytics: "An\xE1lise de uso para melhorar funcionalidades",
2985
+ performanceMonitoring: "Monitoramento de performance da aplica\xE7\xE3o",
2986
+ featureUsage: "Estat\xEDsticas de uso de recursos",
2987
+ customerSupport: "Suporte ao cliente mais eficiente"
2988
+ },
2989
+ government: {
2990
+ citizenServices: "Melhoria dos servi\xE7os ao cidad\xE3o",
2991
+ dataProtection: "Prote\xE7\xE3o rigorosa dos dados pessoais",
2992
+ transparency: "Transpar\xEAncia no uso de dados",
2993
+ accessibility: "Recursos de acessibilidade digital"
2994
+ },
2995
+ education: {
2996
+ studentProgress: "Acompanhamento do progresso educacional",
2997
+ learningAnalytics: "Analytics para melhorar o aprendizado",
2998
+ accessibility: "Recursos educacionais acess\xEDveis",
2999
+ parentalConsent: "Consentimento parental quando necess\xE1rio"
3000
+ }
3001
+ },
3002
+ // Variações de tom
3003
+ variants: {
3004
+ formal: {
3005
+ bannerMessage: "Este s\xEDtio eletr\xF4nico utiliza cookies para otimizar a experi\xEAncia de navega\xE7\xE3o.",
3006
+ acceptAll: "Concordar com todos os cookies",
3007
+ declineAll: "Recusar cookies opcionais",
3008
+ modalTitle: "Configura\xE7\xE3o de Cookies"
3009
+ },
3010
+ casual: {
3011
+ bannerMessage: "\u{1F36A} Ei! Usamos cookies para tornar sua experi\xEAncia ainda melhor!",
3012
+ acceptAll: "Aceitar tudo",
3013
+ declineAll: "S\xF3 o essencial",
3014
+ modalTitle: "Seus Cookies"
3015
+ },
3016
+ concise: {
3017
+ bannerMessage: "Usamos cookies. Voc\xEA aceita?",
3018
+ acceptAll: "Sim",
3019
+ declineAll: "N\xE3o",
3020
+ modalTitle: "Cookies"
3021
+ },
3022
+ detailed: {
3023
+ bannerMessage: "Utilizamos cookies e tecnologias similares para melhorar sua experi\xEAncia de navega\xE7\xE3o, personalizar conte\xFAdo, analisar tr\xE1fego e oferecer funcionalidades de redes sociais.",
3024
+ acceptAll: "Aceitar todos os cookies e tecnologias",
3025
+ declineAll: "Recusar todos os cookies opcionais",
3026
+ modalTitle: "Centro de Prefer\xEAncias de Privacidade"
3027
+ }
3028
+ },
3029
+ // Internacionalização simplificada (apenas textos básicos)
3030
+ i18n: {
3031
+ en: {
3032
+ bannerMessage: "We use cookies to enhance your experience.",
3033
+ acceptAll: "Accept All",
3034
+ declineAll: "Decline",
3035
+ preferences: "Preferences",
3036
+ modalTitle: "Cookie Preferences",
3037
+ modalIntro: "Customize your cookie preferences below.",
3038
+ save: "Save Preferences",
3039
+ necessaryAlwaysOn: "Necessary cookies (always active)"
3040
+ },
3041
+ es: {
3042
+ bannerMessage: "Utilizamos cookies para mejorar su experiencia.",
3043
+ acceptAll: "Aceptar Todo",
3044
+ declineAll: "Rechazar",
3045
+ preferences: "Preferencias",
3046
+ modalTitle: "Preferencias de Cookies",
3047
+ modalIntro: "Personalice sus preferencias de cookies a continuaci\xF3n.",
3048
+ save: "Guardar Preferencias",
3049
+ necessaryAlwaysOn: "Cookies necess\xE1rias (sempre ativas)"
3050
+ },
3051
+ fr: {
3052
+ bannerMessage: "Nous utilisons des cookies pour am\xE9liorer votre exp\xE9rience.",
3053
+ acceptAll: "Tout Accepter",
3054
+ declineAll: "Refuser",
3055
+ preferences: "Pr\xE9f\xE9rences",
3056
+ modalTitle: "Pr\xE9f\xE9rences des Cookies",
3057
+ modalIntro: "Personnalisez vos pr\xE9f\xE9rences de cookies ci-dessous.",
3058
+ save: "Enregistrer les Pr\xE9f\xE9rences",
3059
+ necessaryAlwaysOn: "Cookies n\xE9cessaires (toujours actifs)"
3060
+ }
3061
+ },
3062
+ // Textos técnicos
3063
+ technical: {
3064
+ sessionCookies: "Cookies de sess\xE3o s\xE3o tempor\xE1rios e expiram quando voc\xEA fecha o navegador.",
3065
+ persistentCookies: "Cookies persistentes permanecem no seu dispositivo at\xE9 expirarem ou serem removidos.",
3066
+ thirdPartyCookies: "Cookies de terceiros s\xE3o definidos por dom\xEDnios diferentes do site que voc\xEA est\xE1 visitando.",
3067
+ browserSettings: "Voc\xEA pode gerenciar cookies nas configura\xE7\xF5es do seu navegador.",
3068
+ disablingImpact: "Desabilitar cookies pode afetar a funcionalidade do site."
3069
+ },
3070
+ // Cookie details
3071
+ cookieDetails: {
3072
+ tableHeaders: {
3073
+ name: "Nome",
3074
+ purpose: "Finalidade",
3075
+ duration: "Dura\xE7\xE3o",
3076
+ provider: "Fornecedor",
3077
+ type: "Tipo"
3078
+ },
3079
+ noCookies: "Nenhum cookie encontrado para esta categoria.",
3080
+ toggleDetails: {
3081
+ expand: "Ver detalhes",
3082
+ collapse: "Ocultar detalhes"
3083
+ }
3084
+ }
3085
+ };
3086
+ function resolveTexts(texts, options = {}) {
3087
+ const { language = "pt", variant } = options;
3088
+ let resolved = { ...texts };
3089
+ if (variant && texts.variants?.[variant]) {
3090
+ resolved = { ...resolved, ...texts.variants[variant] };
3091
+ }
3092
+ if (language !== "pt" && texts.i18n?.[language]) {
3093
+ resolved = { ...resolved, ...texts.i18n[language] };
3094
+ }
3095
+ return resolved;
3096
+ }
3097
+ var TEXT_TEMPLATES = {
3098
+ ecommerce: {
3099
+ ...EXPANDED_DEFAULT_TEXTS,
3100
+ bannerMessage: "Utilizamos cookies para personalizar ofertas e melhorar sua experi\xEAncia de compra.",
3101
+ acceptAll: "Aceitar e continuar",
3102
+ variants: {
3103
+ casual: {
3104
+ bannerMessage: "\u{1F6D2} Usamos cookies para encontrar as melhores ofertas para voc\xEA!",
3105
+ acceptAll: "Quero ofertas personalizadas!"
3106
+ }
3107
+ }
3108
+ },
3109
+ saas: {
3110
+ ...EXPANDED_DEFAULT_TEXTS,
3111
+ bannerMessage: "Utilizamos cookies para otimizar o desempenho da aplica\xE7\xE3o e sua experi\xEAncia.",
3112
+ acceptAll: "Aceitar e otimizar",
3113
+ variants: {
3114
+ formal: {
3115
+ bannerMessage: "Esta aplica\xE7\xE3o utiliza cookies para an\xE1lise de performance e melhoria cont\xEDnua da experi\xEAncia do usu\xE1rio.",
3116
+ acceptAll: "Autorizar coleta de dados de uso"
3117
+ }
3118
+ }
3119
+ },
3120
+ government: {
3121
+ ...EXPANDED_DEFAULT_TEXTS,
3122
+ bannerMessage: "Este portal utiliza cookies em conformidade com a LGPD para melhorar os servi\xE7os p\xFAblicos.",
3123
+ acceptAll: "Aceitar em conformidade",
3124
+ variants: {
3125
+ formal: {
3126
+ bannerMessage: "Este s\xEDtio eletr\xF4nico do governo utiliza cookies estritamente necess\xE1rios e opcionais, em conformidade com a Lei Geral de Prote\xE7\xE3o de Dados.",
3127
+ acceptAll: "Concordar com o uso de cookies"
3128
+ }
3129
+ }
3130
+ }
3131
+ };
1710
3132
 
1711
3133
  // src/index.ts
1712
3134
  init_developerGuidance();
1713
3135
  init_logger();
3136
+ init_cookieRegistry();
1714
3137
  init_CookieBanner();
1715
3138
  init_FloatingPreferencesButton();
1716
3139
  init_ConsentContext();
@@ -1723,27 +3146,55 @@ init_categoryUtils();
1723
3146
  ConsentScriptLoader,
1724
3147
  CookieBanner,
1725
3148
  DEFAULT_PROJECT_CATEGORIES,
3149
+ EXPANDED_DEFAULT_TEXTS,
1726
3150
  FloatingPreferencesButton,
3151
+ GUIDANCE_PRESETS,
3152
+ INTEGRATION_TEMPLATES,
1727
3153
  LogLevel,
1728
3154
  PreferencesModal,
3155
+ TEXT_TEMPLATES,
1729
3156
  analyzeDeveloperConfiguration,
3157
+ analyzeIntegrationCategories,
3158
+ autoConfigureCategories,
3159
+ categorizeDiscoveredCookies,
3160
+ createClarityIntegration,
3161
+ createCorporateIntegrations,
1730
3162
  createDefaultConsentTheme,
3163
+ createECommerceIntegrations,
3164
+ createFacebookPixelIntegration,
1731
3165
  createGoogleAnalyticsIntegration,
1732
3166
  createGoogleTagManagerIntegration,
3167
+ createHotjarIntegration,
3168
+ createIntercomIntegration,
3169
+ createMixpanelIntegration,
1733
3170
  createProjectPreferences,
3171
+ createSaaSIntegrations,
1734
3172
  createUserWayIntegration,
3173
+ createZendeskChatIntegration,
1735
3174
  defaultConsentTheme,
1736
3175
  defaultTexts,
3176
+ detectConsentCookieName,
3177
+ discoverRuntimeCookies,
3178
+ extractCategoriesFromIntegrations,
1737
3179
  getAllProjectCategories,
3180
+ getCookiesInfoForCategory,
1738
3181
  loadScript,
3182
+ logDeveloperGuidance,
1739
3183
  openPreferencesModal,
3184
+ resolveTexts,
3185
+ setCookieCatalogOverrides,
3186
+ setCookieCategoryOverrides,
1740
3187
  setDebugLogging,
3188
+ suggestCategoryForScript,
1741
3189
  useCategories,
1742
3190
  useCategoryStatus,
1743
3191
  useConsent,
1744
3192
  useConsentHydration,
1745
3193
  useConsentScriptLoader,
1746
3194
  useConsentTexts,
3195
+ useDeveloperGuidance,
1747
3196
  useOpenPreferencesModal,
3197
+ validateIntegrationCategories,
3198
+ validateNecessaryClassification,
1748
3199
  validateProjectPreferences
1749
3200
  });