@react-lgpd-consent/core 0.7.0 → 0.7.2

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
@@ -35,6 +35,219 @@ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require
35
35
  throw Error('Dynamic require of "' + x + '" is not supported');
36
36
  });
37
37
 
38
+ // src/types/advancedTexts.ts
39
+ var EXPANDED_DEFAULT_TEXTS = {
40
+ // Textos adicionais
41
+ confirm: "Confirmar",
42
+ cancel: "Cancelar",
43
+ loading: "Carregando...",
44
+ // Feedback
45
+ feedback: {
46
+ saveSuccess: "Prefer\xEAncias salvas com sucesso!",
47
+ saveError: "Erro ao salvar prefer\xEAncias. Tente novamente.",
48
+ consentUpdated: "Consentimento atualizado.",
49
+ cookiesRejected: "Cookies opcionais rejeitados.",
50
+ settingsReset: "Configura\xE7\xF5es resetadas."
51
+ },
52
+ // Acessibilidade
53
+ accessibility: {
54
+ bannerLabel: "Banner de consentimento de cookies",
55
+ modalLabel: "Modal de prefer\xEAncias de cookies",
56
+ keyboardNavigation: "Use Tab para navegar, Enter para selecionar",
57
+ toggleState: {
58
+ enabled: "Habilitado",
59
+ disabled: "Desabilitado"
60
+ },
61
+ liveRegion: "Regi\xE3o de an\xFAncios din\xE2micos"
62
+ },
63
+ // Categorias
64
+ categories: {
65
+ necessary: {
66
+ name: "Cookies Necess\xE1rios",
67
+ description: "Essenciais para o funcionamento b\xE1sico do site",
68
+ examples: "Sess\xE3o, seguran\xE7a, prefer\xEAncias de idioma"
69
+ },
70
+ analytics: {
71
+ name: "Cookies de Analytics",
72
+ description: "Ajudam a entender como os visitantes usam o site",
73
+ examples: "Google Analytics, contadores de p\xE1gina"
74
+ },
75
+ marketing: {
76
+ name: "Cookies de Marketing",
77
+ description: "Usados para personalizar an\xFAncios e ofertas",
78
+ examples: "Facebook Pixel, Google Ads, remarketing"
79
+ },
80
+ functional: {
81
+ name: "Cookies Funcionais",
82
+ description: "Melhoram a funcionalidade e personaliza\xE7\xE3o",
83
+ examples: "Chat, mapas, v\xEDdeos embarcados"
84
+ },
85
+ performance: {
86
+ name: "Cookies de Performance",
87
+ description: "Coletam informa\xE7\xF5es sobre velocidade e estabilidade",
88
+ examples: "Monitoramento de erro, otimiza\xE7\xE3o de velocidade"
89
+ }
90
+ },
91
+ // Contextos específicos
92
+ contexts: {
93
+ ecommerce: {
94
+ cartAbandonment: "Lembramos dos produtos no seu carrinho",
95
+ personalizedOffers: "Ofertas personalizadas baseadas no seu hist\xF3rico",
96
+ paymentSecurity: "Seguran\xE7a adicional no processo de pagamento",
97
+ productRecommendations: "Sugest\xF5es de produtos relevantes"
98
+ },
99
+ saas: {
100
+ userAnalytics: "An\xE1lise de uso para melhorar funcionalidades",
101
+ performanceMonitoring: "Monitoramento de performance da aplica\xE7\xE3o",
102
+ featureUsage: "Estat\xEDsticas de uso de recursos",
103
+ customerSupport: "Suporte ao cliente mais eficiente"
104
+ },
105
+ government: {
106
+ citizenServices: "Melhoria dos servi\xE7os ao cidad\xE3o",
107
+ dataProtection: "Prote\xE7\xE3o rigorosa dos dados pessoais",
108
+ transparency: "Transpar\xEAncia no uso de dados",
109
+ accessibility: "Recursos de acessibilidade digital"
110
+ },
111
+ education: {
112
+ studentProgress: "Acompanhamento do progresso educacional",
113
+ learningAnalytics: "Analytics para melhorar o aprendizado",
114
+ accessibility: "Recursos educacionais acess\xEDveis",
115
+ parentalConsent: "Consentimento parental quando necess\xE1rio"
116
+ }
117
+ },
118
+ // Variações de tom
119
+ variants: {
120
+ formal: {
121
+ bannerMessage: "Este s\xEDtio eletr\xF4nico utiliza cookies para otimizar a experi\xEAncia de navega\xE7\xE3o.",
122
+ acceptAll: "Concordar com todos os cookies",
123
+ declineAll: "Recusar cookies opcionais",
124
+ modalTitle: "Configura\xE7\xE3o de Cookies"
125
+ },
126
+ casual: {
127
+ bannerMessage: "\u{1F36A} Ei! Usamos cookies para tornar sua experi\xEAncia ainda melhor!",
128
+ acceptAll: "Aceitar tudo",
129
+ declineAll: "S\xF3 o essencial",
130
+ modalTitle: "Seus Cookies"
131
+ },
132
+ concise: {
133
+ bannerMessage: "Usamos cookies. Voc\xEA aceita?",
134
+ acceptAll: "Sim",
135
+ declineAll: "N\xE3o",
136
+ modalTitle: "Cookies"
137
+ },
138
+ detailed: {
139
+ 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.",
140
+ acceptAll: "Aceitar todos os cookies e tecnologias",
141
+ declineAll: "Recusar todos os cookies opcionais",
142
+ modalTitle: "Centro de Prefer\xEAncias de Privacidade"
143
+ }
144
+ },
145
+ // Internacionalização simplificada (apenas textos básicos)
146
+ i18n: {
147
+ en: {
148
+ bannerMessage: "We use cookies to enhance your experience.",
149
+ acceptAll: "Accept All",
150
+ declineAll: "Decline",
151
+ preferences: "Preferences",
152
+ modalTitle: "Cookie Preferences",
153
+ modalIntro: "Customize your cookie preferences below.",
154
+ save: "Save Preferences",
155
+ necessaryAlwaysOn: "Necessary cookies (always active)"
156
+ },
157
+ es: {
158
+ bannerMessage: "Utilizamos cookies para mejorar su experiencia.",
159
+ acceptAll: "Aceptar Todo",
160
+ declineAll: "Rechazar",
161
+ preferences: "Preferencias",
162
+ modalTitle: "Preferencias de Cookies",
163
+ modalIntro: "Personalice sus preferencias de cookies a continuaci\xF3n.",
164
+ save: "Guardar Preferencias",
165
+ necessaryAlwaysOn: "Cookies necess\xE1rias (sempre ativas)"
166
+ },
167
+ fr: {
168
+ bannerMessage: "Nous utilisons des cookies pour am\xE9liorer votre exp\xE9rience.",
169
+ acceptAll: "Tout Accepter",
170
+ declineAll: "Refuser",
171
+ preferences: "Pr\xE9f\xE9rences",
172
+ modalTitle: "Pr\xE9f\xE9rences des Cookies",
173
+ modalIntro: "Personnalisez vos pr\xE9f\xE9rences de cookies ci-dessous.",
174
+ save: "Enregistrer les Pr\xE9f\xE9rences",
175
+ necessaryAlwaysOn: "Cookies n\xE9cessaires (toujours actifs)"
176
+ }
177
+ },
178
+ // Textos técnicos
179
+ technical: {
180
+ sessionCookies: "Cookies de sess\xE3o s\xE3o tempor\xE1rios e expiram quando voc\xEA fecha o navegador.",
181
+ persistentCookies: "Cookies persistentes permanecem no seu dispositivo at\xE9 expirarem ou serem removidos.",
182
+ thirdPartyCookies: "Cookies de terceiros s\xE3o definidos por dom\xEDnios diferentes do site que voc\xEA est\xE1 visitando.",
183
+ browserSettings: "Voc\xEA pode gerenciar cookies nas configura\xE7\xF5es do seu navegador.",
184
+ disablingImpact: "Desabilitar cookies pode afetar a funcionalidade do site."
185
+ },
186
+ // Cookie details
187
+ cookieDetails: {
188
+ tableHeaders: {
189
+ name: "Nome",
190
+ purpose: "Finalidade",
191
+ duration: "Dura\xE7\xE3o",
192
+ provider: "Fornecedor",
193
+ type: "Tipo"
194
+ },
195
+ noCookies: "Nenhum cookie encontrado para esta categoria.",
196
+ toggleDetails: {
197
+ expand: "Ver detalhes",
198
+ collapse: "Ocultar detalhes"
199
+ },
200
+ scriptLabelPrefix: "(script) ",
201
+ scriptPurpose: "Script de integra\xE7\xE3o ativo"
202
+ }
203
+ };
204
+ function resolveTexts(texts, options = {}) {
205
+ const { language = "pt", variant } = options;
206
+ let resolved = { ...texts };
207
+ if (variant && texts.variants?.[variant]) {
208
+ resolved = { ...resolved, ...texts.variants[variant] };
209
+ }
210
+ if (language !== "pt" && texts.i18n?.[language]) {
211
+ resolved = { ...resolved, ...texts.i18n[language] };
212
+ }
213
+ return resolved;
214
+ }
215
+ var TEXT_TEMPLATES = {
216
+ ecommerce: {
217
+ ...EXPANDED_DEFAULT_TEXTS,
218
+ bannerMessage: "Utilizamos cookies para personalizar ofertas e melhorar sua experi\xEAncia de compra.",
219
+ acceptAll: "Aceitar e continuar",
220
+ variants: {
221
+ casual: {
222
+ bannerMessage: "\u{1F6D2} Usamos cookies para encontrar as melhores ofertas para voc\xEA!",
223
+ acceptAll: "Quero ofertas personalizadas!"
224
+ }
225
+ }
226
+ },
227
+ saas: {
228
+ ...EXPANDED_DEFAULT_TEXTS,
229
+ bannerMessage: "Utilizamos cookies para otimizar o desempenho da aplica\xE7\xE3o e sua experi\xEAncia.",
230
+ acceptAll: "Aceitar e otimizar",
231
+ variants: {
232
+ formal: {
233
+ bannerMessage: "Esta aplica\xE7\xE3o utiliza cookies para an\xE1lise de performance e melhoria cont\xEDnua da experi\xEAncia do usu\xE1rio.",
234
+ acceptAll: "Autorizar coleta de dados de uso"
235
+ }
236
+ }
237
+ },
238
+ government: {
239
+ ...EXPANDED_DEFAULT_TEXTS,
240
+ bannerMessage: "Este portal utiliza cookies em conformidade com a LGPD para melhorar os servi\xE7os p\xFAblicos.",
241
+ acceptAll: "Aceitar em conformidade",
242
+ variants: {
243
+ formal: {
244
+ 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.",
245
+ acceptAll: "Concordar com o uso de cookies"
246
+ }
247
+ }
248
+ }
249
+ };
250
+
38
251
  // src/utils/categoryUtils.ts
39
252
  function createProjectPreferences(config, defaultValue = false) {
40
253
  const preferences = {
@@ -333,6 +546,7 @@ function setDebugLogging(enabled, level = 2 /* INFO */) {
333
546
  // src/utils/cookieUtils.ts
334
547
  var DEFAULT_STORAGE_NAMESPACE = "lgpd-consent";
335
548
  var DEFAULT_STORAGE_VERSION = "1";
549
+ var DEFAULT_MAX_AGE_SECONDS = 365 * 24 * 60 * 60;
336
550
  function buildConsentStorageKey(options) {
337
551
  const namespaceRaw = options?.namespace?.trim() || DEFAULT_STORAGE_NAMESPACE;
338
552
  const versionRaw = options?.version?.trim() || DEFAULT_STORAGE_VERSION;
@@ -342,16 +556,36 @@ function buildConsentStorageKey(options) {
342
556
  }
343
557
  var DEFAULT_COOKIE_OPTS = {
344
558
  name: "cookieConsent",
559
+ maxAge: DEFAULT_MAX_AGE_SECONDS,
345
560
  maxAgeDays: 365,
346
561
  sameSite: "Lax",
347
- secure: globalThis.window === void 0 ? false : globalThis.window.location.protocol === "https:",
562
+ secure: false,
348
563
  path: "/",
349
564
  domain: void 0
350
565
  };
566
+ function resolveCookieOptions(opts) {
567
+ const currentWindow = globalThis.window;
568
+ const currentLocation = globalThis.location;
569
+ const protocols = [currentWindow?.location?.protocol, currentLocation?.protocol].filter(
570
+ Boolean
571
+ );
572
+ const forceHttps = globalThis.__LGPD_FORCE_HTTPS__ === true;
573
+ const isHttps = forceHttps || protocols.includes("https:");
574
+ const maxAgeSecondsFromDays = typeof opts?.maxAgeDays === "number" ? Math.max(0, opts.maxAgeDays * 24 * 60 * 60) : null;
575
+ const maxAgeSeconds = typeof opts?.maxAge === "number" ? Math.max(0, opts.maxAge) : maxAgeSecondsFromDays ?? DEFAULT_MAX_AGE_SECONDS;
576
+ return {
577
+ name: opts?.name ?? DEFAULT_COOKIE_OPTS.name,
578
+ maxAge: maxAgeSeconds,
579
+ sameSite: opts?.sameSite ?? DEFAULT_COOKIE_OPTS.sameSite ?? "Lax",
580
+ secure: typeof opts?.secure === "boolean" ? opts.secure : isHttps ? true : DEFAULT_COOKIE_OPTS.secure,
581
+ path: opts?.path ?? DEFAULT_COOKIE_OPTS.path ?? "/",
582
+ domain: opts?.domain ?? DEFAULT_COOKIE_OPTS.domain ?? void 0
583
+ };
584
+ }
351
585
  var COOKIE_SCHEMA_VERSION = "1.0";
352
586
  function readConsentCookie(name = DEFAULT_COOKIE_OPTS.name) {
353
587
  logger.debug("Reading consent cookie", { name });
354
- if (typeof document === "undefined") {
588
+ if (globalThis.document === void 0) {
355
589
  logger.debug("Cookie read skipped: server-side environment");
356
590
  return null;
357
591
  }
@@ -363,6 +597,10 @@ function readConsentCookie(name = DEFAULT_COOKIE_OPTS.name) {
363
597
  try {
364
598
  const data = JSON.parse(raw);
365
599
  logger.cookieOperation("read", name, data);
600
+ if (!data || typeof data !== "object") {
601
+ logger.warn("Consent cookie malformed: payload is not an object");
602
+ return null;
603
+ }
366
604
  if (!data.version) {
367
605
  logger.debug("Migrating legacy cookie format");
368
606
  return migrateLegacyCookie(data);
@@ -371,7 +609,11 @@ function readConsentCookie(name = DEFAULT_COOKIE_OPTS.name) {
371
609
  logger.warn(`Cookie version mismatch: ${data.version} != ${COOKIE_SCHEMA_VERSION}`);
372
610
  return null;
373
611
  }
374
- return data;
612
+ const preferences = data && typeof data.preferences === "object" ? data.preferences : { necessary: true };
613
+ return {
614
+ ...data,
615
+ preferences: ensureNecessaryAlwaysOn(preferences)
616
+ };
375
617
  } catch (error) {
376
618
  logger.error("Error parsing consent cookie", error);
377
619
  return null;
@@ -394,12 +636,12 @@ function migrateLegacyCookie(legacyData) {
394
636
  }
395
637
  }
396
638
  function writeConsentCookie(state, config, opts, source = "banner") {
397
- if (typeof document === "undefined") {
639
+ if (globalThis.document === void 0 || globalThis.window === void 0 || globalThis.__LGPD_SSR__ === true) {
398
640
  logger.debug("Cookie write skipped: server-side environment");
399
641
  return;
400
642
  }
401
643
  const now = (/* @__PURE__ */ new Date()).toISOString();
402
- const o = { ...DEFAULT_COOKIE_OPTS, ...opts };
644
+ const o = resolveCookieOptions(opts);
403
645
  const preferences = ensureNecessaryAlwaysOn(state.preferences);
404
646
  const cookieData = {
405
647
  version: COOKIE_SCHEMA_VERSION,
@@ -411,8 +653,9 @@ function writeConsentCookie(state, config, opts, source = "banner") {
411
653
  projectConfig: config
412
654
  };
413
655
  logger.cookieOperation("write", o.name, cookieData);
656
+ const expires = new Date(Date.now() + o.maxAge * 1e3);
414
657
  Cookies__default.default.set(o.name, JSON.stringify(cookieData), {
415
- expires: o.maxAgeDays,
658
+ expires,
416
659
  sameSite: o.sameSite,
417
660
  secure: o.secure,
418
661
  path: o.path,
@@ -442,36 +685,48 @@ function createConsentAuditEntry(state, params) {
442
685
  };
443
686
  }
444
687
  function removeConsentCookie(opts) {
445
- if (typeof document === "undefined") {
688
+ if (globalThis.document === void 0) {
446
689
  logger.debug("Cookie removal skipped: server-side environment");
447
690
  return;
448
691
  }
449
- const o = { ...DEFAULT_COOKIE_OPTS, ...opts };
692
+ const o = resolveCookieOptions(opts);
450
693
  logger.cookieOperation("delete", o.name);
451
694
  Cookies__default.default.remove(o.name, { path: o.path, domain: o.domain });
452
695
  logger.info("Consent cookie removed");
453
696
  }
454
697
 
455
698
  // src/utils/dataLayerEvents.ts
456
- var LIBRARY_VERSION = "0.7.0";
699
+ var LIBRARY_VERSION = "0.7.2";
457
700
  function ensureDataLayer() {
458
- var _a;
459
- if (globalThis.window === void 0) return;
460
- (_a = globalThis.window).dataLayer ?? (_a.dataLayer = []);
701
+ const currentWindow = globalThis.window;
702
+ if (!currentWindow) return;
703
+ const currentLayer = currentWindow.dataLayer;
704
+ if (currentLayer == null) {
705
+ currentWindow.dataLayer = [];
706
+ return;
707
+ }
708
+ if (typeof currentLayer.push !== "function") {
709
+ const env = globalThis.process?.env?.NODE_ENV ?? "production";
710
+ if (env !== "production") {
711
+ console.warn("[LGPD-CONSENT] dataLayer presente mas sem push; eventos n\xE3o ser\xE3o registrados.");
712
+ }
713
+ }
461
714
  }
462
715
  function pushConsentInitializedEvent(categories) {
463
- if (globalThis.window === void 0) return;
464
716
  ensureDataLayer();
465
717
  const event = {
466
718
  event: "consent_initialized",
467
719
  consent_version: LIBRARY_VERSION,
468
720
  timestamp: (/* @__PURE__ */ new Date()).toISOString(),
469
- categories
721
+ categories,
722
+ preferences: categories
470
723
  };
471
- globalThis.window.dataLayer?.push(event);
724
+ const layer = globalThis.window?.dataLayer;
725
+ if (layer && typeof layer.push === "function") {
726
+ layer.push(event);
727
+ }
472
728
  }
473
729
  function pushConsentUpdatedEvent(categories, origin, previousCategories) {
474
- if (globalThis.window === void 0) return;
475
730
  ensureDataLayer();
476
731
  const changedCategories = previousCategories ? Object.keys(categories).filter((key) => categories[key] !== previousCategories[key]) : [];
477
732
  const event = {
@@ -480,9 +735,13 @@ function pushConsentUpdatedEvent(categories, origin, previousCategories) {
480
735
  timestamp: (/* @__PURE__ */ new Date()).toISOString(),
481
736
  origin,
482
737
  categories,
738
+ preferences: categories,
483
739
  changed_categories: changedCategories
484
740
  };
485
- globalThis.window.dataLayer?.push(event);
741
+ const layer = globalThis.window?.dataLayer;
742
+ if (layer && typeof layer.push === "function") {
743
+ layer.push(event);
744
+ }
486
745
  }
487
746
  function useDataLayerEvents() {
488
747
  return {
@@ -812,7 +1071,7 @@ function analyzeDeveloperConfiguration(config) {
812
1071
  const gt = globalThis;
813
1072
  const implied = (gt.__LGPD_REQUIRED_CATEGORIES__ || []).filter(Boolean);
814
1073
  implied.forEach((id) => {
815
- if (!guidance.activeCategoriesInfo.find((c) => c.id === id)) {
1074
+ if (!guidance.activeCategoriesInfo.some((c) => c.id === id)) {
816
1075
  const info = NAMES[id];
817
1076
  if (info) {
818
1077
  guidance.activeCategoriesInfo.push({
@@ -852,6 +1111,27 @@ function analyzeDeveloperConfiguration(config) {
852
1111
  'Apenas cookies necess\xE1rios est\xE3o configurados. Para compliance LGPD, considere adicionar categorias como "analytics" ou "functional" conforme uso real.',
853
1112
  "compliance"
854
1113
  );
1114
+ } else {
1115
+ addMessage(
1116
+ "info",
1117
+ "Cookies n\xE3o necess\xE1rios devem iniciar desativados e exigir consentimento expresso, sem pr\xE9-sele\xE7\xE3o e sem consentimento t\xE1cito.",
1118
+ "consent"
1119
+ );
1120
+ addMessage(
1121
+ "info",
1122
+ "Ofere\xE7a op\xE7\xF5es claras de aceitar, rejeitar e gerenciar prefer\xEAncias com o mesmo destaque, al\xE9m de revoga\xE7\xE3o simples e gratuita.",
1123
+ "consent"
1124
+ );
1125
+ addMessage(
1126
+ "info",
1127
+ "Informe finalidades espec\xEDficas, per\xEDodo de reten\xE7\xE3o e compartilhamento com terceiros em pol\xEDtica/aviso de cookies.",
1128
+ "transparency"
1129
+ );
1130
+ addMessage(
1131
+ "info",
1132
+ "Disponibilize mecanismo pr\xF3prio de gerenciamento de cookies; configura\xE7\xF5es do navegador s\xE3o apenas complementares.",
1133
+ "transparency"
1134
+ );
855
1135
  }
856
1136
  if (totalToggleable > 5) {
857
1137
  addMessage(
@@ -876,7 +1156,7 @@ function getComplianceScoreColor(score) {
876
1156
  function logComplianceScore(prefix, score) {
877
1157
  const color = getComplianceScoreColor(score);
878
1158
  console.log(
879
- `%c${prefix} Score de Conformidade LGPD: ${score}/100`,
1159
+ `%c${prefix} Score de Conformidade LGPD (orientativo): ${score}/100`,
880
1160
  `color: ${color}; font-weight: bold; font-size: 14px;`
881
1161
  );
882
1162
  }
@@ -971,7 +1251,7 @@ function logServerSideIfAvailable(guidance) {
971
1251
  }
972
1252
  function logDeveloperGuidance(guidance, disableGuidanceProp, config) {
973
1253
  const gt = globalThis;
974
- const nodeEnv = typeof gt.process !== "undefined" ? gt.process?.env?.NODE_ENV : void 0;
1254
+ const nodeEnv = gt.process ? gt.process?.env?.NODE_ENV : void 0;
975
1255
  const isProd = nodeEnv === "production" || gt.__LGPD_PRODUCTION__ === true;
976
1256
  if (isProd || disableGuidanceProp) return;
977
1257
  const guidanceHash = getGuidanceHash(guidance);
@@ -1029,11 +1309,21 @@ function logDeveloperGuidance(guidance, disableGuidanceProp, config) {
1029
1309
  "color: #9c27b0;",
1030
1310
  "color: #7b1fa2;"
1031
1311
  );
1312
+ console.info(
1313
+ `%c${PREFIX}%c Evite consentimento t\xE1cito e op\xE7\xF5es pr\xE9-selecionadas`,
1314
+ "color: #9c27b0;",
1315
+ "color: #7b1fa2;"
1316
+ );
1032
1317
  console.info(
1033
1318
  `%c${PREFIX}%c Documente pol\xEDticas claras por categoria`,
1034
1319
  "color: #9c27b0;",
1035
1320
  "color: #7b1fa2;"
1036
1321
  );
1322
+ console.info(
1323
+ `%c${PREFIX}%c Informe finalidades, reten\xE7\xE3o e revoga\xE7\xE3o simples e gratuita`,
1324
+ "color: #9c27b0;",
1325
+ "color: #7b1fa2;"
1326
+ );
1037
1327
  console.info(
1038
1328
  `%c${PREFIX}%c Registre consentimento com data/hora/origem`,
1039
1329
  "color: #9c27b0;",
@@ -1045,7 +1335,9 @@ function logDeveloperGuidance(guidance, disableGuidanceProp, config) {
1045
1335
  function useDeveloperGuidance(config, disableGuidanceProp, guidanceConfig) {
1046
1336
  const guidance = React4__namespace.default.useMemo(() => analyzeDeveloperConfiguration(config), [config]);
1047
1337
  React4__namespace.default.useEffect(() => {
1048
- if (!disableGuidanceProp) logDeveloperGuidance(guidance, disableGuidanceProp, guidanceConfig);
1338
+ if (globalThis.window !== void 0 && !disableGuidanceProp) {
1339
+ logDeveloperGuidance(guidance, disableGuidanceProp, guidanceConfig);
1340
+ }
1049
1341
  }, [guidance, disableGuidanceProp, guidanceConfig]);
1050
1342
  return guidance;
1051
1343
  }
@@ -1089,58 +1381,8 @@ var GUIDANCE_PRESETS = {
1089
1381
  };
1090
1382
 
1091
1383
  // src/utils/peerDepsCheck.ts
1092
- function detectMultipleReactInstances() {
1093
- if (globalThis.window === void 0) return false;
1094
- try {
1095
- const reactSymbols = Object.getOwnPropertySymbols(globalThis.window).map(String).filter((name) => name.includes("react"));
1096
- if (reactSymbols.length > 1) {
1097
- return true;
1098
- }
1099
- const ReactModule = window.React;
1100
- if (ReactModule && Array.isArray(ReactModule)) {
1101
- return true;
1102
- }
1103
- const hasMultipleVersions = window.__REACT_DEVTOOLS_GLOBAL_HOOK__?.renderers?.size > 1;
1104
- return hasMultipleVersions || false;
1105
- } catch {
1106
- return false;
1107
- }
1108
- }
1109
- function getPackageVersion(packageName) {
1110
- if (globalThis.window === void 0) return null;
1111
- try {
1112
- const pkg = window[packageName];
1113
- if (pkg?.version) return pkg.version;
1114
- const React6 = window.React;
1115
- if (packageName === "react" && React6?.version) {
1116
- return React6.version;
1117
- }
1118
- return null;
1119
- } catch {
1120
- return null;
1121
- }
1122
- }
1123
- function isVersionInRange(version, minMajor, maxMajor) {
1124
- const major = Number.parseInt(version.split(".")[0], 10);
1125
- return major >= minMajor && major <= maxMajor;
1126
- }
1127
- function checkPeerDeps(options = {}) {
1128
- const { skipInProduction = true, logWarnings = true } = options;
1129
- const result = {
1130
- ok: true,
1131
- warnings: [],
1132
- errors: []
1133
- };
1134
- const isProduction = typeof process !== "undefined" && process.env?.NODE_ENV === "production";
1135
- if (skipInProduction && isProduction) {
1136
- return result;
1137
- }
1138
- if (globalThis.window === void 0) {
1139
- return result;
1140
- }
1141
- if (detectMultipleReactInstances()) {
1142
- result.ok = false;
1143
- const errorMsg = `
1384
+ var MESSAGES_PT_BR = {
1385
+ MULTIPLE_REACT_INSTANCES: `
1144
1386
  \u2554\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2557
1145
1387
  \u2551 \u26A0\uFE0F ERRO: M\xFAltiplas inst\xE2ncias de React detectadas \u2551
1146
1388
  \u255A\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u255D
@@ -1202,22 +1444,13 @@ function checkPeerDeps(options = {}) {
1202
1444
  https://github.com/lucianoedipo/react-lgpd-consent/blob/main/TROUBLESHOOTING.md#multiple-react-instances
1203
1445
 
1204
1446
  \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500
1205
- `;
1206
- result.errors.push(errorMsg);
1207
- if (logWarnings) {
1208
- console.error(errorMsg);
1209
- }
1210
- }
1211
- const reactVersion = getPackageVersion("react");
1212
- if (reactVersion) {
1213
- if (!isVersionInRange(reactVersion, 18, 19)) {
1214
- result.ok = false;
1215
- const errorMsg = `
1447
+ `,
1448
+ UNSUPPORTED_REACT_VERSION: (version) => `
1216
1449
  \u2554\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2557
1217
1450
  \u2551 \u26A0\uFE0F AVISO: Vers\xE3o do React n\xE3o suportada \u2551
1218
1451
  \u255A\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u255D
1219
1452
 
1220
- \u{1F4E6} Vers\xE3o detectada: React ${reactVersion}
1453
+ \u{1F4E6} Vers\xE3o detectada: React ${version}
1221
1454
  \u2705 Vers\xF5es suportadas: React 18.x ou 19.x
1222
1455
 
1223
1456
  \u{1F50D} O react-lgpd-consent requer React 18.2.0+ ou React 19.x
@@ -1235,27 +1468,13 @@ function checkPeerDeps(options = {}) {
1235
1468
  https://github.com/lucianoedipo/react-lgpd-consent/blob/main/TROUBLESHOOTING.md#react-version
1236
1469
 
1237
1470
  \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500
1238
- `;
1239
- result.errors.push(errorMsg);
1240
- if (logWarnings) {
1241
- console.error(errorMsg);
1242
- }
1243
- }
1244
- }
1245
- const muiVersion = window["@mui/material"]?.version;
1246
- if (muiVersion) {
1247
- if (!isVersionInRange(muiVersion, 5, 7)) {
1248
- result.warnings.push(
1249
- `MUI vers\xE3o ${muiVersion} detectada. Vers\xF5es suportadas: 5.15.0+, 6.x ou 7.x. Alguns componentes podem n\xE3o funcionar corretamente.`
1250
- );
1251
- if (logWarnings) {
1252
- logger.warn(
1253
- `
1471
+ `,
1472
+ UNSUPPORTED_MUI_VERSION: (version) => `
1254
1473
  \u2554\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2557
1255
1474
  \u2551 \u26A0\uFE0F AVISO: Vers\xE3o do Material-UI fora do range recomendado \u2551
1256
1475
  \u255A\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u255D
1257
1476
 
1258
- \u{1F4E6} Vers\xE3o detectada: @mui/material ${muiVersion}
1477
+ \u{1F4E6} Vers\xE3o detectada: @mui/material ${version}
1259
1478
  \u2705 Vers\xF5es suportadas: 5.15.0+, 6.x, 7.x
1260
1479
 
1261
1480
  \u{1F50D} Componentes de UI (@react-lgpd-consent/mui) podem apresentar problemas.
@@ -1273,8 +1492,230 @@ function checkPeerDeps(options = {}) {
1273
1492
  https://github.com/lucianoedipo/react-lgpd-consent/blob/main/TROUBLESHOOTING.md#mui-version
1274
1493
 
1275
1494
  \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500
1276
- `
1277
- );
1495
+ `,
1496
+ MUI_OUT_OF_RANGE: (version) => `MUI vers\xE3o ${version} detectada. Vers\xF5es suportadas: 5.15.0+, 6.x ou 7.x. Alguns componentes podem n\xE3o funcionar corretamente.`
1497
+ };
1498
+ var MESSAGES_EN = {
1499
+ MULTIPLE_REACT_INSTANCES: `
1500
+ \u2554\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2557
1501
+ \u2551 \u26A0\uFE0F ERROR: Multiple React instances detected \u2551
1502
+ \u255A\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u255D
1503
+
1504
+ \u{1F534} Problem:
1505
+ Your project is loading more than one copy of React, causing the error:
1506
+ "Invalid hook call. Hooks can only be called inside of the body of a
1507
+ function component."
1508
+
1509
+ \u{1F50D} Probable cause:
1510
+ \u2022 pnpm/Yarn PnP without proper peer dependency hoisting
1511
+ \u2022 node_modules with duplicate React (classic npm/yarn)
1512
+ \u2022 Webpack/Vite with multiple resolutions of the same package
1513
+
1514
+ \u2705 Solutions:
1515
+
1516
+ \u{1F4E6} PNPM (RECOMMENDED):
1517
+ Add to root package.json:
1518
+ {
1519
+ "pnpm": {
1520
+ "overrides": {
1521
+ "react": "$react",
1522
+ "react-dom": "$react-dom"
1523
+ }
1524
+ }
1525
+ }
1526
+ Run: pnpm install
1527
+
1528
+ \u{1F4E6} NPM/Yarn:
1529
+ Add to root package.json:
1530
+ {
1531
+ "overrides": {
1532
+ "react": "^18.2.0 || ^19.0.0",
1533
+ "react-dom": "^18.2.0 || ^19.0.0"
1534
+ }
1535
+ }
1536
+ Run: npm install (or yarn install)
1537
+
1538
+ \u{1F527} Webpack:
1539
+ Add to webpack.config.js:
1540
+ module.exports = {
1541
+ resolve: {
1542
+ alias: {
1543
+ react: path.resolve('./node_modules/react'),
1544
+ 'react-dom': path.resolve('./node_modules/react-dom'),
1545
+ }
1546
+ }
1547
+ }
1548
+
1549
+ \u26A1 Vite:
1550
+ Add to vite.config.js:
1551
+ export default {
1552
+ resolve: {
1553
+ dedupe: ['react', 'react-dom']
1554
+ }
1555
+ }
1556
+
1557
+ \u{1F4DA} Documentation:
1558
+ https://github.com/lucianoedipo/react-lgpd-consent/blob/main/TROUBLESHOOTING.md#multiple-react-instances
1559
+
1560
+ \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500
1561
+ `,
1562
+ UNSUPPORTED_REACT_VERSION: (version) => `
1563
+ \u2554\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2557
1564
+ \u2551 \u26A0\uFE0F WARNING: Unsupported React version \u2551
1565
+ \u255A\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u255D
1566
+
1567
+ \u{1F4E6} Detected version: React ${version}
1568
+ \u2705 Supported versions: React 18.x or 19.x
1569
+
1570
+ \u{1F50D} react-lgpd-consent requires React 18.2.0+ or React 19.x
1571
+
1572
+ \u2705 Solution:
1573
+ Update React to a supported version:
1574
+
1575
+ npm install react@^18.2.0 react-dom@^18.2.0
1576
+
1577
+ or
1578
+
1579
+ npm install react@^19.0.0 react-dom@^19.0.0
1580
+
1581
+ \u{1F4DA} Documentation:
1582
+ https://github.com/lucianoedipo/react-lgpd-consent/blob/main/TROUBLESHOOTING.md#react-version
1583
+
1584
+ \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500
1585
+ `,
1586
+ UNSUPPORTED_MUI_VERSION: (version) => `
1587
+ \u2554\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2557
1588
+ \u2551 \u26A0\uFE0F WARNING: Material-UI version out of recommended range \u2551
1589
+ \u255A\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u255D
1590
+
1591
+ \u{1F4E6} Detected version: @mui/material ${version}
1592
+ \u2705 Supported versions: 5.15.0+, 6.x, 7.x
1593
+
1594
+ \u{1F50D} UI components (@react-lgpd-consent/mui) may have issues.
1595
+
1596
+ \u2705 Solution:
1597
+ Update MUI to a supported version:
1598
+
1599
+ npm install @mui/material@^7.0.0 @emotion/react @emotion/styled
1600
+
1601
+ or keep 5.15.0+:
1602
+
1603
+ npm install @mui/material@^5.15.0 @emotion/react @emotion/styled
1604
+
1605
+ \u{1F4DA} Documentation:
1606
+ https://github.com/lucianoedipo/react-lgpd-consent/blob/main/TROUBLESHOOTING.md#mui-version
1607
+
1608
+ \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500
1609
+ `,
1610
+ MUI_OUT_OF_RANGE: (version) => `MUI version ${version} detected. Supported versions: 5.15.0+, 6.x or 7.x. Some components may not work properly.`
1611
+ };
1612
+ var MESSAGES_BY_LOCALE = {
1613
+ "pt-BR": MESSAGES_PT_BR,
1614
+ en: MESSAGES_EN
1615
+ };
1616
+ var currentLocale = "pt-BR";
1617
+ var customMessages = {};
1618
+ function setPeerDepsLocale(locale) {
1619
+ currentLocale = locale;
1620
+ }
1621
+ function getPeerDepsLocale() {
1622
+ return currentLocale;
1623
+ }
1624
+ function setPeerDepsMessages(messages) {
1625
+ customMessages = { ...customMessages, ...messages };
1626
+ }
1627
+ function resetPeerDepsMessages() {
1628
+ customMessages = {};
1629
+ }
1630
+ function getMessages() {
1631
+ const baseMessages = MESSAGES_BY_LOCALE[currentLocale];
1632
+ if (Object.keys(customMessages).length === 0) {
1633
+ return baseMessages;
1634
+ }
1635
+ return {
1636
+ MULTIPLE_REACT_INSTANCES: customMessages.MULTIPLE_REACT_INSTANCES ?? baseMessages.MULTIPLE_REACT_INSTANCES,
1637
+ UNSUPPORTED_REACT_VERSION: customMessages.UNSUPPORTED_REACT_VERSION ?? baseMessages.UNSUPPORTED_REACT_VERSION,
1638
+ UNSUPPORTED_MUI_VERSION: customMessages.UNSUPPORTED_MUI_VERSION ?? baseMessages.UNSUPPORTED_MUI_VERSION,
1639
+ MUI_OUT_OF_RANGE: customMessages.MUI_OUT_OF_RANGE ?? baseMessages.MUI_OUT_OF_RANGE
1640
+ };
1641
+ }
1642
+ function detectMultipleReactInstances() {
1643
+ const currentWindow = globalThis.window;
1644
+ if (currentWindow === void 0) return false;
1645
+ try {
1646
+ const reactSymbols = Object.getOwnPropertySymbols(currentWindow).map(String).filter((name) => name.includes("react"));
1647
+ if (reactSymbols.length > 1) {
1648
+ return true;
1649
+ }
1650
+ const ReactModule = currentWindow.React;
1651
+ if (ReactModule && Array.isArray(ReactModule)) {
1652
+ return true;
1653
+ }
1654
+ const hasMultipleVersions = (currentWindow.__REACT_DEVTOOLS_GLOBAL_HOOK__?.renderers?.size ?? 0) > 1;
1655
+ return hasMultipleVersions || false;
1656
+ } catch {
1657
+ return false;
1658
+ }
1659
+ }
1660
+ function getPackageVersion(packageName) {
1661
+ const currentWindow = globalThis.window;
1662
+ if (currentWindow === void 0) return null;
1663
+ try {
1664
+ const pkg = currentWindow[packageName];
1665
+ if (pkg?.version) return pkg.version;
1666
+ const React6 = currentWindow.React;
1667
+ if (packageName === "react" && React6?.version) {
1668
+ return React6.version;
1669
+ }
1670
+ return null;
1671
+ } catch {
1672
+ return null;
1673
+ }
1674
+ }
1675
+ function isVersionInRange(version, minMajor, maxMajor) {
1676
+ const major = Number.parseInt(version.split(".")[0], 10);
1677
+ return major >= minMajor && major <= maxMajor;
1678
+ }
1679
+ function checkPeerDeps(options = {}) {
1680
+ const { skipInProduction = true, logWarnings = true } = options;
1681
+ const result = {
1682
+ ok: true,
1683
+ warnings: [],
1684
+ errors: []
1685
+ };
1686
+ const isProduction = typeof process !== "undefined" && process.env?.NODE_ENV === "production";
1687
+ if (skipInProduction && isProduction) {
1688
+ return result;
1689
+ }
1690
+ const currentWindow = globalThis.window;
1691
+ if (currentWindow === void 0) {
1692
+ return result;
1693
+ }
1694
+ const messages = getMessages();
1695
+ if (detectMultipleReactInstances()) {
1696
+ result.ok = false;
1697
+ result.errors.push(messages.MULTIPLE_REACT_INSTANCES);
1698
+ if (logWarnings) {
1699
+ console.error(messages.MULTIPLE_REACT_INSTANCES);
1700
+ }
1701
+ }
1702
+ const reactVersion = getPackageVersion("react");
1703
+ if (reactVersion) {
1704
+ if (!isVersionInRange(reactVersion, 18, 19)) {
1705
+ result.ok = false;
1706
+ const errorMsg = messages.UNSUPPORTED_REACT_VERSION(reactVersion);
1707
+ result.errors.push(errorMsg);
1708
+ if (logWarnings) {
1709
+ console.error(errorMsg);
1710
+ }
1711
+ }
1712
+ }
1713
+ const muiVersion = currentWindow["@mui/material"]?.version;
1714
+ if (muiVersion) {
1715
+ if (!isVersionInRange(muiVersion, 5, 7)) {
1716
+ result.warnings.push(messages.MUI_OUT_OF_RANGE(muiVersion));
1717
+ if (logWarnings) {
1718
+ logger.warn(messages.UNSUPPORTED_MUI_VERSION(muiVersion));
1278
1719
  }
1279
1720
  }
1280
1721
  }
@@ -1399,10 +1840,11 @@ function validateConsentProviderProps(props) {
1399
1840
 
1400
1841
  // src/utils/cookieDiscovery.ts
1401
1842
  function discoverRuntimeCookies() {
1402
- if (typeof document === "undefined" || !document.cookie) return [];
1843
+ const currentDocument = globalThis.document;
1844
+ if (currentDocument === void 0 || !currentDocument.cookie) return [];
1403
1845
  const names = Array.from(
1404
1846
  new Set(
1405
- document.cookie.split(";").map((s) => s.trim()).filter(Boolean).map((s) => s.split("=")[0])
1847
+ currentDocument.cookie.split(";").map((s) => s.trim()).filter(Boolean).map((s) => s.split("=")[0])
1406
1848
  )
1407
1849
  );
1408
1850
  const list = names.map((name) => ({ name }));
@@ -1413,27 +1855,34 @@ function discoverRuntimeCookies() {
1413
1855
  }
1414
1856
  return list;
1415
1857
  }
1858
+ function tryDecode(val) {
1859
+ try {
1860
+ return decodeURIComponent(val);
1861
+ } catch {
1862
+ return val;
1863
+ }
1864
+ }
1865
+ function isConsentJson(val) {
1866
+ if (!val.startsWith("{")) return false;
1867
+ try {
1868
+ const obj = JSON.parse(val);
1869
+ return obj && typeof obj === "object" && "preferences" in obj && "version" in obj;
1870
+ } catch {
1871
+ return false;
1872
+ }
1873
+ }
1416
1874
  function detectConsentCookieName() {
1417
- if (typeof document === "undefined" || !document.cookie) return null;
1875
+ const currentDocument = globalThis.document;
1876
+ if (currentDocument === void 0 || !currentDocument.cookie) return null;
1418
1877
  try {
1419
- const pairs = document.cookie.split(";").map((s) => s.trim()).filter(Boolean);
1878
+ const pairs = currentDocument.cookie.split(";").map((s) => s.trim()).filter(Boolean);
1420
1879
  for (const p of pairs) {
1421
1880
  const [name, ...rest] = p.split("=");
1422
1881
  const raw = rest.join("=");
1423
1882
  if (!raw) continue;
1424
- let val = raw;
1425
- try {
1426
- val = decodeURIComponent(raw);
1427
- } catch {
1428
- }
1429
- if (val.startsWith("{")) {
1430
- try {
1431
- const obj = JSON.parse(val);
1432
- if (obj && typeof obj === "object" && "preferences" in obj && "version" in obj) {
1433
- return name;
1434
- }
1435
- } catch {
1436
- }
1883
+ const val = tryDecode(raw);
1884
+ if (isConsentJson(val)) {
1885
+ return name;
1437
1886
  }
1438
1887
  }
1439
1888
  } catch {
@@ -1475,15 +1924,6 @@ function CategoriesProvider({
1475
1924
  disableDiscoveryLog
1476
1925
  }) {
1477
1926
  const [impliedVersion, setImpliedVersion] = React4__namespace.useState(0);
1478
- React4__namespace.useEffect(() => {
1479
- const handler = () => setImpliedVersion((v) => v + 1);
1480
- if (typeof window !== "undefined" && typeof window.addEventListener === "function") {
1481
- window.addEventListener("lgpd:requiredCategories", handler);
1482
- return () => window.removeEventListener("lgpd:requiredCategories", handler);
1483
- }
1484
- return () => {
1485
- };
1486
- }, []);
1487
1927
  const contextValue = React4__namespace.useMemo(() => {
1488
1928
  const finalConfig = config || DEFAULT_PROJECT_CATEGORIES;
1489
1929
  const guidance = analyzeDeveloperConfiguration(config);
@@ -1495,35 +1935,47 @@ function CategoriesProvider({
1495
1935
  allCategories: guidance.activeCategoriesInfo
1496
1936
  };
1497
1937
  }, [config, impliedVersion]);
1938
+ React4__namespace.useEffect(() => {
1939
+ const currentWindow = globalThis.window;
1940
+ if (!currentWindow || typeof currentWindow.addEventListener !== "function") return;
1941
+ const handler = () => {
1942
+ setImpliedVersion((current) => current + 1);
1943
+ };
1944
+ currentWindow.addEventListener("lgpd:requiredCategories", handler);
1945
+ return () => {
1946
+ currentWindow.removeEventListener("lgpd:requiredCategories", handler);
1947
+ };
1948
+ }, []);
1498
1949
  React4__namespace.useEffect(() => {
1499
1950
  logDeveloperGuidance(contextValue.guidance, disableDeveloperGuidance);
1500
1951
  }, [contextValue.guidance, disableDeveloperGuidance]);
1501
1952
  React4__namespace.useEffect(() => {
1502
1953
  try {
1503
1954
  const gt = globalThis;
1504
- const env = typeof gt.process !== "undefined" ? gt.process?.env?.NODE_ENV : void 0;
1955
+ const env = gt.process?.env?.NODE_ENV;
1505
1956
  const isDev2 = env === "development";
1506
- if (!isDev2 || gt.__LGPD_DISCOVERY_LOGGED__ === true || disableDiscoveryLog) return;
1507
- const discovered = discoverRuntimeCookies();
1508
- const consentName = detectConsentCookieName() || DEFAULT_COOKIE_OPTS.name;
1509
- const PREFIX = "[\u{1F36A} LGPD-CONSENT]";
1510
- if (typeof console !== "undefined") {
1511
- try {
1512
- console.group(`${PREFIX} \u{1F50E} Descoberta de cookies (experimental)`);
1513
- const names = Array.from(
1514
- new Set([consentName, ...discovered.map((d) => d.name)].filter(Boolean))
1515
- );
1516
- const rows = names.map((n) => ({ Cookie: n }));
1517
- if (typeof console.table === "function") console.table(rows);
1518
- else console.log(rows);
1519
- console.info(
1520
- `${PREFIX} \u2139\uFE0F Estes nomes s\xE3o detectados em tempo de execu\xE7\xE3o. Ajuste ou categorize via APIs de override se necess\xE1rio.`
1521
- );
1522
- console.groupEnd();
1523
- } catch {
1957
+ if (isDev2 && gt.__LGPD_DISCOVERY_LOGGED__ !== true && !disableDiscoveryLog) {
1958
+ const discovered = discoverRuntimeCookies();
1959
+ const consentName = detectConsentCookieName() || DEFAULT_COOKIE_OPTS.name;
1960
+ const PREFIX = "[\u{1F36A} LGPD-CONSENT]";
1961
+ if (typeof console !== "undefined") {
1962
+ try {
1963
+ console.group(`${PREFIX} \u{1F50E} Descoberta de cookies (experimental)`);
1964
+ const names = Array.from(
1965
+ new Set([consentName, ...discovered.map((d) => d.name)].filter(Boolean))
1966
+ );
1967
+ const rows = names.map((n) => ({ Cookie: n }));
1968
+ if (typeof console.table === "function") console.table(rows);
1969
+ else console.log(rows);
1970
+ console.info(
1971
+ `${PREFIX} \u2139\uFE0F Estes nomes s\xE3o detectados em tempo de execu\xE7\xE3o. Ajuste ou categorize via APIs de override se necess\xE1rio.`
1972
+ );
1973
+ console.groupEnd();
1974
+ } catch {
1975
+ }
1524
1976
  }
1977
+ gt.__LGPD_DISCOVERY_LOGGED__ = true;
1525
1978
  }
1526
- gt.__LGPD_DISCOVERY_LOGGED__ = true;
1527
1979
  } catch {
1528
1980
  }
1529
1981
  }, [disableDiscoveryLog]);
@@ -1573,7 +2025,7 @@ function createFullConsentState(consented, preferences, source, projectConfig, i
1573
2025
  isModalOpen
1574
2026
  };
1575
2027
  }
1576
- var DEFAULT_TEXTS = {
2028
+ var BASE_TEXTS = {
1577
2029
  // Textos básicos
1578
2030
  bannerMessage: "Utilizamos cookies para melhorar sua experi\xEAncia.",
1579
2031
  acceptAll: "Aceitar todos",
@@ -1610,6 +2062,10 @@ var DEFAULT_TEXTS = {
1610
2062
  transferCountries: void 0
1611
2063
  // Exibido se definido
1612
2064
  };
2065
+ var DEFAULT_TEXTS = {
2066
+ ...BASE_TEXTS,
2067
+ ...EXPANDED_DEFAULT_TEXTS
2068
+ };
1613
2069
  function reducer(state, action) {
1614
2070
  logger.consentState(action.type, state);
1615
2071
  switch (action.type) {
@@ -1693,6 +2149,8 @@ function ConsentProvider({
1693
2149
  initialState,
1694
2150
  categories,
1695
2151
  texts: textsProp,
2152
+ language,
2153
+ textVariant,
1696
2154
  designTokens,
1697
2155
  PreferencesModalComponent,
1698
2156
  preferencesModalProps = {},
@@ -1717,7 +2175,11 @@ function ConsentProvider({
1717
2175
  onConsentChange,
1718
2176
  onAuditLog
1719
2177
  }) {
1720
- const texts = React4__namespace.useMemo(() => ({ ...DEFAULT_TEXTS, ...textsProp ?? {} }), [textsProp]);
2178
+ const mergedTexts = React4__namespace.useMemo(() => ({ ...DEFAULT_TEXTS, ...textsProp ?? {} }), [textsProp]);
2179
+ const texts = React4__namespace.useMemo(
2180
+ () => resolveTexts(mergedTexts, { language, variant: textVariant }),
2181
+ [mergedTexts, language, textVariant]
2182
+ );
1721
2183
  const cookie = React4__namespace.useMemo(() => {
1722
2184
  const base = { ...DEFAULT_COOKIE_OPTS, ...cookieOpts ?? {} };
1723
2185
  base.name = cookieOpts?.name ?? buildConsentStorageKey({
@@ -1730,6 +2192,13 @@ function ConsentProvider({
1730
2192
  return base;
1731
2193
  }, [cookieOpts, storage?.domain, storage?.namespace, storage?.version]);
1732
2194
  const consentVersion = storage?.version?.trim() || "1";
2195
+ React4__namespace.useEffect(() => {
2196
+ try {
2197
+ ;
2198
+ globalThis.__LGPD_CONSENT_COOKIE__ = cookie.name;
2199
+ } catch {
2200
+ }
2201
+ }, [cookie.name]);
1733
2202
  const finalCategoriesConfig = React4__namespace.useMemo(() => {
1734
2203
  const isProd = typeof process !== "undefined" && process.env?.NODE_ENV === "production";
1735
2204
  if (!categories) return DEFAULT_PROJECT_CATEGORIES;
@@ -2092,51 +2561,100 @@ function ConsentGate(props) {
2092
2561
 
2093
2562
  // src/utils/scriptLoader.ts
2094
2563
  var LOADING_SCRIPTS = /* @__PURE__ */ new Map();
2095
- function loadScript(id, src, category = null, attrs = {}, nonce) {
2096
- if (typeof document === "undefined") return Promise.resolve();
2097
- if (document.getElementById(id)) return Promise.resolve();
2564
+ var DEFAULT_POLL_INTERVAL = 100;
2565
+ function resolveCookieNames(preferred) {
2566
+ const inferred = globalThis.__LGPD_CONSENT_COOKIE__ ?? null;
2567
+ const names = [preferred, inferred, "cookieConsent", "lgpd-consent__v1"].filter(
2568
+ Boolean
2569
+ );
2570
+ return Array.from(new Set(names));
2571
+ }
2572
+ function parseConsentFromCookie(names) {
2573
+ const raw = document.cookie;
2574
+ if (!raw) return null;
2575
+ const cookies = raw.split("; ").reduce((acc, part) => {
2576
+ const [k, ...rest] = part.split("=");
2577
+ acc[k] = rest.join("=");
2578
+ return acc;
2579
+ }, {});
2580
+ for (const name of names) {
2581
+ const value = cookies[name];
2582
+ if (!value) continue;
2583
+ try {
2584
+ const parsed = JSON.parse(decodeURIComponent(value));
2585
+ if (!parsed.consented || parsed.isModalOpen) continue;
2586
+ return parsed;
2587
+ } catch {
2588
+ continue;
2589
+ }
2590
+ }
2591
+ return null;
2592
+ }
2593
+ function hasCategoryConsent(snapshot, category) {
2594
+ if (!snapshot.consented || snapshot.isModalOpen) return false;
2595
+ if (category === null) return true;
2596
+ return Boolean(snapshot.preferences?.[category]);
2597
+ }
2598
+ function loadScript(id, src, category = null, attrs = {}, nonce, options) {
2599
+ const currentDocument = globalThis.document;
2600
+ if (!src || currentDocument === void 0) return Promise.resolve();
2601
+ if (currentDocument.getElementById(id)) return Promise.resolve();
2098
2602
  const existingPromise = LOADING_SCRIPTS.get(id);
2099
2603
  if (existingPromise) return existingPromise;
2604
+ const pollInterval = options?.pollIntervalMs ?? DEFAULT_POLL_INTERVAL;
2605
+ const names = resolveCookieNames(options?.cookieName);
2606
+ const mergedAttrs = { ...attrs };
2100
2607
  const promise = new Promise((resolve, reject) => {
2608
+ const inject = () => {
2609
+ const s = currentDocument.createElement("script");
2610
+ s.id = id;
2611
+ s.src = src;
2612
+ s.async = mergedAttrs.async !== "false";
2613
+ const scriptNonce = mergedAttrs.nonce || nonce;
2614
+ if (scriptNonce) {
2615
+ s.nonce = scriptNonce;
2616
+ mergedAttrs.nonce = scriptNonce;
2617
+ }
2618
+ for (const [k, v] of Object.entries(mergedAttrs)) s.setAttribute(k, v);
2619
+ s.onload = () => {
2620
+ LOADING_SCRIPTS.delete(id);
2621
+ resolve();
2622
+ };
2623
+ s.onerror = () => {
2624
+ LOADING_SCRIPTS.delete(id);
2625
+ reject(new Error(`Failed to load script: ${src}`));
2626
+ };
2627
+ currentDocument.body.appendChild(s);
2628
+ };
2629
+ const snapshot = options?.consentSnapshot;
2630
+ const skipChecks = options?.skipConsentCheck === true;
2631
+ if (skipChecks) {
2632
+ inject();
2633
+ return;
2634
+ }
2635
+ if (snapshot) {
2636
+ if (!hasCategoryConsent(snapshot, category)) {
2637
+ reject(
2638
+ new Error(
2639
+ `Consent not granted for category '${category ?? "none"}' when attempting to load ${id}`
2640
+ )
2641
+ );
2642
+ return;
2643
+ }
2644
+ inject();
2645
+ return;
2646
+ }
2101
2647
  const checkConsent = () => {
2102
- const consentCookie = document.cookie.split("; ").find((row) => row.startsWith("cookieConsent="))?.split("=")[1];
2103
- if (!consentCookie) {
2104
- setTimeout(checkConsent, 100);
2648
+ const consent = parseConsentFromCookie(names);
2649
+ if (!consent) {
2650
+ setTimeout(checkConsent, pollInterval);
2105
2651
  return;
2106
2652
  }
2107
- try {
2108
- const consent = JSON.parse(decodeURIComponent(consentCookie));
2109
- if (!consent.consented || consent.isModalOpen) {
2110
- setTimeout(checkConsent, 100);
2111
- return;
2112
- }
2113
- if (category && !consent.preferences[category]) {
2114
- setTimeout(checkConsent, 100);
2115
- return;
2116
- }
2117
- const s = document.createElement("script");
2118
- s.id = id;
2119
- s.src = src;
2120
- s.async = true;
2121
- const mergedAttrs = { ...attrs };
2122
- const scriptNonce = mergedAttrs.nonce || nonce;
2123
- if (scriptNonce) {
2124
- s.nonce = scriptNonce;
2125
- mergedAttrs.nonce = scriptNonce;
2126
- }
2127
- for (const [k, v] of Object.entries(mergedAttrs)) s.setAttribute(k, v);
2128
- s.onload = () => {
2129
- LOADING_SCRIPTS.delete(id);
2130
- resolve();
2131
- };
2132
- s.onerror = () => {
2133
- LOADING_SCRIPTS.delete(id);
2134
- reject(new Error(`Failed to load script: ${src}`));
2135
- };
2136
- document.body.appendChild(s);
2137
- } catch {
2138
- setTimeout(checkConsent, 100);
2653
+ if (!hasCategoryConsent(consent, category)) {
2654
+ setTimeout(checkConsent, pollInterval);
2655
+ return;
2139
2656
  }
2657
+ inject();
2140
2658
  };
2141
2659
  checkConsent();
2142
2660
  });
@@ -2300,14 +2818,107 @@ function validateNecessaryClassification(integrations, enabledCategories) {
2300
2818
  }
2301
2819
 
2302
2820
  // src/utils/ConsentScriptLoader.tsx
2821
+ var scriptRegistry = /* @__PURE__ */ new Map();
2822
+ var queueListeners = /* @__PURE__ */ new Set();
2823
+ function notifyQueue() {
2824
+ queueListeners.forEach((listener) => {
2825
+ try {
2826
+ listener();
2827
+ } catch {
2828
+ }
2829
+ });
2830
+ }
2831
+ function subscribeQueue(listener) {
2832
+ queueListeners.add(listener);
2833
+ return () => {
2834
+ queueListeners.delete(listener);
2835
+ };
2836
+ }
2837
+ function createInternalScript(def) {
2838
+ return {
2839
+ ...def,
2840
+ status: "pending",
2841
+ lastAllowed: false,
2842
+ registeredAt: Date.now(),
2843
+ token: Date.now() + Math.random(),
2844
+ priority: def.priority ?? 0,
2845
+ allowReload: def.allowReload ?? false,
2846
+ onConsentUpdate: def.onConsentUpdate
2847
+ };
2848
+ }
2849
+ function registerScript(def) {
2850
+ const entry = createInternalScript(def);
2851
+ scriptRegistry.set(def.id, entry);
2852
+ notifyQueue();
2853
+ return () => {
2854
+ const current = scriptRegistry.get(def.id);
2855
+ if (current && current.token === entry.token) {
2856
+ scriptRegistry.delete(def.id);
2857
+ notifyQueue();
2858
+ }
2859
+ };
2860
+ }
2861
+ function getExecutableScripts(consent) {
2862
+ const allowedScripts = [];
2863
+ scriptRegistry.forEach((script) => {
2864
+ const categoryAllowed = script.category === "necessary" || consent.consented && Boolean(consent.preferences?.[script.category]);
2865
+ if (!categoryAllowed) {
2866
+ script.lastAllowed = false;
2867
+ return;
2868
+ }
2869
+ if (script.status === "running") return;
2870
+ if (script.status === "executed" && !script.allowReload) return;
2871
+ if (script.status === "executed" && script.allowReload && script.lastAllowed) return;
2872
+ script.lastAllowed = true;
2873
+ allowedScripts.push(script);
2874
+ });
2875
+ return allowedScripts.sort((a, b) => {
2876
+ if (a.category === "necessary" && b.category !== "necessary") return -1;
2877
+ if (b.category === "necessary" && a.category !== "necessary") return 1;
2878
+ if (a.category !== b.category) return a.category.localeCompare(b.category);
2879
+ if (a.priority !== b.priority) return (b.priority ?? 0) - (a.priority ?? 0);
2880
+ return a.registeredAt - b.registeredAt;
2881
+ });
2882
+ }
2883
+ async function processQueue(consent, devLogging) {
2884
+ const scripts = getExecutableScripts(consent);
2885
+ let order = 0;
2886
+ for (const script of scripts) {
2887
+ order += 1;
2888
+ script.status = "running";
2889
+ if (devLogging) {
2890
+ logger.info("[ConsentScriptLoader] executando script", {
2891
+ id: script.id,
2892
+ category: script.category,
2893
+ priority: script.priority ?? 0,
2894
+ order
2895
+ });
2896
+ }
2897
+ try {
2898
+ await Promise.resolve(script.execute());
2899
+ } catch (error) {
2900
+ logger.error(`\u274C Failed to execute script ${script.id}`, error);
2901
+ } finally {
2902
+ script.status = "executed";
2903
+ if (script.onConsentUpdate) {
2904
+ script.onConsentUpdate(consent);
2905
+ }
2906
+ }
2907
+ }
2908
+ }
2303
2909
  function ConsentScriptLoader({
2304
2910
  integrations,
2305
2911
  reloadOnChange = false,
2306
2912
  nonce
2307
2913
  }) {
2308
2914
  const { preferences, consented } = useConsent();
2915
+ const isHydrated = useConsentHydration();
2309
2916
  const categories = useCategories();
2310
- const loadedScripts = React4__namespace.useRef(/* @__PURE__ */ new Set());
2917
+ const [queueVersion, bumpQueueVersion] = React4__namespace.useState(0);
2918
+ React4__namespace.useEffect(() => {
2919
+ const unsubscribe = subscribeQueue(() => bumpQueueVersion((v) => v + 1));
2920
+ return unsubscribe;
2921
+ }, []);
2311
2922
  React4__namespace.useEffect(() => {
2312
2923
  try {
2313
2924
  const ids = (integrations || []).map((i) => i.id);
@@ -2368,15 +2979,44 @@ function ConsentScriptLoader({
2368
2979
  console.groupEnd();
2369
2980
  }
2370
2981
  }, [integrations, categories]);
2982
+ const processedIntegrationsRef = React4__namespace.useRef(/* @__PURE__ */ new Map());
2371
2983
  React4__namespace.useEffect(() => {
2372
- if (!consented) return;
2373
- const timeoutId = setTimeout(async () => {
2374
- for (const integration of integrations) {
2375
- const shouldLoad = preferences[integration.category];
2376
- const alreadyLoaded = loadedScripts.current.has(integration.id);
2377
- if (shouldLoad && (!alreadyLoaded || reloadOnChange)) {
2378
- try {
2379
- const mergedAttrs = integration.attrs ?? {};
2984
+ const cleanups = [];
2985
+ const currentIds = /* @__PURE__ */ new Set();
2986
+ integrations.forEach((integration) => {
2987
+ currentIds.add(integration.id);
2988
+ const structuralHash = JSON.stringify({
2989
+ category: integration.category,
2990
+ src: integration.src,
2991
+ priority: integration.priority,
2992
+ hasBootstrap: Boolean(integration.bootstrap),
2993
+ hasInit: Boolean(integration.init),
2994
+ hasOnConsentUpdate: Boolean(integration.onConsentUpdate)
2995
+ });
2996
+ const existingHash = processedIntegrationsRef.current.get(integration.id);
2997
+ if (existingHash === structuralHash && scriptRegistry.has(integration.id)) {
2998
+ return;
2999
+ }
3000
+ processedIntegrationsRef.current.set(integration.id, structuralHash);
3001
+ if (integration.bootstrap) {
3002
+ cleanups.push(
3003
+ registerScript({
3004
+ id: `${integration.id}__bootstrap`,
3005
+ category: "necessary",
3006
+ priority: (integration.priority ?? 0) + 1e3,
3007
+ execute: integration.bootstrap
3008
+ })
3009
+ );
3010
+ }
3011
+ cleanups.push(
3012
+ registerScript({
3013
+ id: integration.id,
3014
+ category: integration.category,
3015
+ priority: integration.priority,
3016
+ allowReload: reloadOnChange,
3017
+ onConsentUpdate: integration.onConsentUpdate,
3018
+ execute: async () => {
3019
+ const mergedAttrs = integration.attrs ? { ...integration.attrs } : {};
2380
3020
  const scriptNonce = integration.nonce ?? nonce;
2381
3021
  if (scriptNonce && !mergedAttrs.nonce) mergedAttrs.nonce = scriptNonce;
2382
3022
  await loadScript(
@@ -2384,26 +3024,54 @@ function ConsentScriptLoader({
2384
3024
  integration.src,
2385
3025
  integration.category,
2386
3026
  mergedAttrs,
2387
- scriptNonce
3027
+ scriptNonce,
3028
+ { skipConsentCheck: true }
2388
3029
  );
2389
3030
  if (integration.init) {
2390
3031
  integration.init();
2391
3032
  }
2392
- loadedScripts.current.add(integration.id);
2393
- } catch (error) {
2394
- logger.error(`\u274C Failed to load script: ${integration.id}`, error);
2395
3033
  }
3034
+ })
3035
+ );
3036
+ });
3037
+ processedIntegrationsRef.current.forEach((_, id) => {
3038
+ if (!currentIds.has(id)) {
3039
+ processedIntegrationsRef.current.delete(id);
3040
+ const script = scriptRegistry.get(id);
3041
+ if (script) {
3042
+ scriptRegistry.delete(id);
3043
+ }
3044
+ const bootstrapScript = scriptRegistry.get(`${id}__bootstrap`);
3045
+ if (bootstrapScript) {
3046
+ scriptRegistry.delete(`${id}__bootstrap`);
2396
3047
  }
2397
3048
  }
2398
- }, 0);
2399
- return () => clearTimeout(timeoutId);
2400
- }, [preferences, consented, integrations, reloadOnChange, nonce]);
3049
+ });
3050
+ return () => cleanups.forEach((fn) => fn());
3051
+ }, [integrations, reloadOnChange, nonce]);
3052
+ React4__namespace.useEffect(() => {
3053
+ if (!isHydrated) return;
3054
+ void processQueue({ consented, preferences }, process.env.NODE_ENV !== "production");
3055
+ }, [consented, preferences, isHydrated, queueVersion]);
3056
+ React4__namespace.useEffect(() => {
3057
+ if (!isHydrated) return;
3058
+ scriptRegistry.forEach((script) => {
3059
+ if (script.status !== "executed") return;
3060
+ if (typeof script.onConsentUpdate !== "function") return;
3061
+ script.onConsentUpdate({ consented, preferences });
3062
+ });
3063
+ }, [consented, preferences, isHydrated]);
2401
3064
  return null;
2402
3065
  }
2403
3066
  function useConsentScriptLoader() {
2404
3067
  const { preferences, consented } = useConsent();
3068
+ const isHydrated = useConsentHydration();
2405
3069
  return React4__namespace.useCallback(
2406
3070
  async (integration, nonce) => {
3071
+ if (!isHydrated) {
3072
+ logger.warn(`\u26A0\uFE0F Cannot load script ${integration.id}: Consent not hydrated yet`);
3073
+ return false;
3074
+ }
2407
3075
  if (!consented) {
2408
3076
  logger.warn(`\u26A0\uFE0F Cannot load script ${integration.id}: No consent given`);
2409
3077
  return false;
@@ -2424,7 +3092,11 @@ function useConsentScriptLoader() {
2424
3092
  integration.src,
2425
3093
  integration.category,
2426
3094
  mergedAttrs,
2427
- scriptNonce
3095
+ scriptNonce,
3096
+ {
3097
+ consentSnapshot: { consented, preferences },
3098
+ skipConsentCheck: true
3099
+ }
2428
3100
  );
2429
3101
  if (integration.init) {
2430
3102
  integration.init();
@@ -2435,16 +3107,129 @@ function useConsentScriptLoader() {
2435
3107
  return false;
2436
3108
  }
2437
3109
  },
2438
- [preferences, consented]
3110
+ [preferences, consented, isHydrated]
2439
3111
  );
2440
3112
  }
2441
3113
 
2442
3114
  // src/utils/scriptIntegrations.ts
3115
+ function createSuggestedIntegration(config) {
3116
+ const suggested = suggestCategoryForScript(config.id)[0] ?? "analytics";
3117
+ const category = resolveCategory(suggested, config.category);
3118
+ const { category: _ignored, ...rest } = config;
3119
+ return { ...rest, category };
3120
+ }
3121
+ var resolveCategory = (fallback, override) => {
3122
+ if (typeof override === "string" && override.trim().length > 0) return override.trim();
3123
+ return fallback;
3124
+ };
3125
+ var isDevEnv = () => {
3126
+ const env = typeof globalThis !== "undefined" ? globalThis.process?.env?.NODE_ENV : void 0;
3127
+ return env !== "production";
3128
+ };
3129
+ var resolveRequiredString = (value, field, integrationId) => {
3130
+ if (typeof value !== "string" || value.trim().length === 0) {
3131
+ if (isDevEnv()) {
3132
+ console.error(
3133
+ `[LGPD-CONSENT] Config inv\xE1lida: integra\xE7\xE3o "${integrationId}" requer "${field}".`
3134
+ );
3135
+ }
3136
+ return null;
3137
+ }
3138
+ return value.trim();
3139
+ };
3140
+ function buildConsentModeSignals(preferences) {
3141
+ const analytics = preferences.analytics ? "granted" : "denied";
3142
+ const marketing = preferences.marketing ? "granted" : "denied";
3143
+ return {
3144
+ ad_storage: marketing,
3145
+ ad_user_data: marketing,
3146
+ ad_personalization: marketing,
3147
+ analytics_storage: analytics
3148
+ };
3149
+ }
3150
+ function pushToLayer(entry, dataLayerName) {
3151
+ const currentWindow = globalThis.window;
3152
+ if (currentWindow === void 0) return;
3153
+ const registry = currentWindow;
3154
+ const name = dataLayerName ?? "dataLayer";
3155
+ const layer = registry[name] ?? [];
3156
+ registry[name] = layer;
3157
+ layer.push(entry);
3158
+ }
3159
+ function ensureGtag(dataLayerName = "dataLayer") {
3160
+ const currentWindow = globalThis.window;
3161
+ if (currentWindow === void 0) return null;
3162
+ const w = currentWindow;
3163
+ const registry = w;
3164
+ const layer = registry[dataLayerName] ?? [];
3165
+ registry[dataLayerName] = layer;
3166
+ if (typeof w.gtag !== "function") {
3167
+ const gtag = (...args) => {
3168
+ layer.push(args);
3169
+ };
3170
+ w.gtag = gtag;
3171
+ }
3172
+ return w.gtag;
3173
+ }
3174
+ function applyDefaultConsentMode(dataLayerName) {
3175
+ const payload = buildConsentModeSignals({
3176
+ analytics: false,
3177
+ marketing: false
3178
+ });
3179
+ const gtag = ensureGtag(dataLayerName);
3180
+ if (gtag) {
3181
+ gtag("consent", "default", payload);
3182
+ }
3183
+ pushToLayer(["consent", "default", payload], dataLayerName);
3184
+ }
3185
+ function applyConsentModeUpdate(preferences, dataLayerName) {
3186
+ const payload = buildConsentModeSignals(preferences);
3187
+ const gtag = ensureGtag(dataLayerName);
3188
+ if (gtag) {
3189
+ gtag("consent", "update", payload);
3190
+ }
3191
+ pushToLayer(["consent", "update", payload], dataLayerName);
3192
+ }
2443
3193
  function createGoogleAnalyticsIntegration(config) {
2444
- const src = config.scriptUrl ?? `https://www.googletagmanager.com/gtag/js?id=${config.measurementId}`;
3194
+ const category = resolveCategory("analytics", config.category);
3195
+ const measurementId = resolveRequiredString(
3196
+ config.measurementId,
3197
+ "measurementId",
3198
+ "google-analytics"
3199
+ );
3200
+ if (!measurementId) {
3201
+ return {
3202
+ id: "google-analytics",
3203
+ category,
3204
+ src: "",
3205
+ cookies: ["_ga", "_ga_*", "_gid"],
3206
+ cookiesInfo: [
3207
+ {
3208
+ name: "_ga",
3209
+ purpose: "Identifica\xE7\xE3o \xFAnica de visitantes para an\xE1lise de tr\xE1fego",
3210
+ duration: "2 anos",
3211
+ provider: "Google Analytics"
3212
+ },
3213
+ {
3214
+ name: "_ga_*",
3215
+ purpose: "Rastreamento de sess\xF5es e eventos espec\xEDficos do stream GA4",
3216
+ duration: "2 anos",
3217
+ provider: "Google Analytics"
3218
+ },
3219
+ {
3220
+ name: "_gid",
3221
+ purpose: "Distin\xE7\xE3o de visitantes \xFAnicos em per\xEDodo de 24h",
3222
+ duration: "24 horas",
3223
+ provider: "Google Analytics"
3224
+ }
3225
+ ],
3226
+ attrs: { async: "true" }
3227
+ };
3228
+ }
3229
+ const src = config.scriptUrl ?? `https://www.googletagmanager.com/gtag/js?id=${measurementId}`;
2445
3230
  return {
2446
3231
  id: "google-analytics",
2447
- category: "analytics",
3232
+ category,
2448
3233
  src,
2449
3234
  cookies: ["_ga", "_ga_*", "_gid"],
2450
3235
  cookiesInfo: [
@@ -2467,32 +3252,49 @@ function createGoogleAnalyticsIntegration(config) {
2467
3252
  provider: "Google Analytics"
2468
3253
  }
2469
3254
  ],
3255
+ bootstrap: () => {
3256
+ applyDefaultConsentMode();
3257
+ },
3258
+ onConsentUpdate: ({ preferences }) => {
3259
+ applyConsentModeUpdate(preferences);
3260
+ },
2470
3261
  init: () => {
2471
- if (globalThis.window !== void 0) {
2472
- const w = window;
2473
- w.dataLayer = w.dataLayer ?? [];
2474
- const gtag = (...args) => {
2475
- w.dataLayer.push(...args);
2476
- };
2477
- w.gtag = gtag;
2478
- gtag("js", /* @__PURE__ */ new Date());
2479
- gtag("config", config.measurementId, config.config ?? {});
2480
- }
3262
+ const gtag = ensureGtag();
3263
+ if (!gtag) return;
3264
+ gtag("js", /* @__PURE__ */ new Date());
3265
+ gtag("config", measurementId, config.config ?? {});
2481
3266
  },
2482
3267
  attrs: { async: "true" }
2483
3268
  };
2484
3269
  }
2485
3270
  function createGoogleTagManagerIntegration(config) {
2486
- const src = config.scriptUrl ?? `https://www.googletagmanager.com/gtm.js?id=${config.containerId}`;
3271
+ const category = resolveCategory("analytics", config.category);
3272
+ const containerId = resolveRequiredString(config.containerId, "containerId", "google-tag-manager");
3273
+ if (!containerId) {
3274
+ return {
3275
+ id: "google-tag-manager",
3276
+ category,
3277
+ src: "",
3278
+ cookies: ["_gcl_au"]
3279
+ };
3280
+ }
3281
+ const src = config.scriptUrl ?? `https://www.googletagmanager.com/gtm.js?id=${containerId}`;
2487
3282
  return {
2488
3283
  id: "google-tag-manager",
2489
- category: "analytics",
3284
+ category,
2490
3285
  src,
2491
3286
  cookies: ["_gcl_au"],
3287
+ bootstrap: () => {
3288
+ applyDefaultConsentMode(config.dataLayerName);
3289
+ },
3290
+ onConsentUpdate: ({ preferences }) => {
3291
+ applyConsentModeUpdate(preferences, config.dataLayerName);
3292
+ },
2492
3293
  init: () => {
2493
- if (globalThis.window !== void 0) {
3294
+ const currentWindow = globalThis.window;
3295
+ if (currentWindow !== void 0) {
2494
3296
  const dataLayerName = config.dataLayerName || "dataLayer";
2495
- const w = window;
3297
+ const w = currentWindow;
2496
3298
  const layer = w[dataLayerName] ?? [];
2497
3299
  w[dataLayerName] = layer;
2498
3300
  layer.push({ "gtm.start": Date.now(), event: "gtm.js" });
@@ -2501,20 +3303,31 @@ function createGoogleTagManagerIntegration(config) {
2501
3303
  };
2502
3304
  }
2503
3305
  function createUserWayIntegration(config) {
3306
+ const category = resolveCategory("functional", config.category);
3307
+ const accountId = resolveRequiredString(config.accountId, "accountId", "userway");
3308
+ if (!accountId) {
3309
+ return {
3310
+ id: "userway",
3311
+ category,
3312
+ src: "",
3313
+ cookies: ["_userway_*"]
3314
+ };
3315
+ }
2504
3316
  const src = config.scriptUrl ?? "https://cdn.userway.org/widget.js";
2505
3317
  return {
2506
3318
  id: "userway",
2507
- category: "functional",
3319
+ category,
2508
3320
  src,
2509
3321
  cookies: ["_userway_*"],
2510
3322
  init: () => {
2511
- if (globalThis.window !== void 0) {
2512
- const w = window;
3323
+ const currentWindow = globalThis.window;
3324
+ if (currentWindow !== void 0) {
3325
+ const w = currentWindow;
2513
3326
  w.UserWayWidgetApp = w.UserWayWidgetApp || {};
2514
- w.UserWayWidgetApp.accountId = config.accountId;
3327
+ w.UserWayWidgetApp.accountId = accountId;
2515
3328
  }
2516
3329
  },
2517
- attrs: { "data-account": config.accountId }
3330
+ attrs: { "data-account": accountId }
2518
3331
  };
2519
3332
  }
2520
3333
  var COMMON_INTEGRATIONS = {
@@ -2523,15 +3336,26 @@ var COMMON_INTEGRATIONS = {
2523
3336
  userway: createUserWayIntegration
2524
3337
  };
2525
3338
  function createFacebookPixelIntegration(config) {
3339
+ const category = resolveCategory("marketing", config.category);
3340
+ const pixelId = resolveRequiredString(config.pixelId, "pixelId", "facebook-pixel");
3341
+ if (!pixelId) {
3342
+ return {
3343
+ id: "facebook-pixel",
3344
+ category,
3345
+ src: "",
3346
+ cookies: ["_fbp", "fr"]
3347
+ };
3348
+ }
2526
3349
  const src = config.scriptUrl ?? "https://connect.facebook.net/en_US/fbevents.js";
2527
3350
  return {
2528
3351
  id: "facebook-pixel",
2529
- category: "marketing",
3352
+ category,
2530
3353
  src,
2531
3354
  cookies: ["_fbp", "fr"],
2532
3355
  init: () => {
2533
- if (globalThis.window !== void 0) {
2534
- const w = window;
3356
+ const currentWindow = globalThis.window;
3357
+ if (currentWindow !== void 0) {
3358
+ const w = currentWindow;
2535
3359
  if (!w.fbq) {
2536
3360
  const fbq = (...args) => {
2537
3361
  if (w.fbq && typeof w.fbq.callMethod === "function") {
@@ -2544,18 +3368,34 @@ function createFacebookPixelIntegration(config) {
2544
3368
  fbq.loaded = true;
2545
3369
  w.fbq = fbq;
2546
3370
  }
2547
- w.fbq("init", config.pixelId, config.advancedMatching ?? {});
3371
+ w.fbq("init", pixelId, config.advancedMatching ?? {});
2548
3372
  if (config.autoTrack !== false) w.fbq("track", "PageView");
2549
3373
  }
2550
3374
  }
2551
3375
  };
2552
3376
  }
2553
3377
  function createHotjarIntegration(config) {
3378
+ const category = resolveCategory("analytics", config.category);
3379
+ const siteId = resolveRequiredString(config.siteId, "siteId", "hotjar");
2554
3380
  const v = config.version ?? 6;
2555
- const src = config.scriptUrl ?? `https://static.hotjar.com/c/hotjar-${config.siteId}.js?sv=${v}`;
3381
+ if (!siteId) {
3382
+ return {
3383
+ id: "hotjar",
3384
+ category,
3385
+ src: "",
3386
+ cookies: [
3387
+ "_hjSession_*",
3388
+ "_hjSessionUser_*",
3389
+ "_hjFirstSeen",
3390
+ "_hjIncludedInSessionSample",
3391
+ "_hjAbsoluteSessionInProgress"
3392
+ ]
3393
+ };
3394
+ }
3395
+ const src = config.scriptUrl ?? `https://static.hotjar.com/c/hotjar-${siteId}.js?sv=${v}`;
2556
3396
  return {
2557
3397
  id: "hotjar",
2558
- category: "analytics",
3398
+ category,
2559
3399
  src,
2560
3400
  cookies: [
2561
3401
  "_hjSession_*",
@@ -2597,9 +3437,10 @@ function createHotjarIntegration(config) {
2597
3437
  }
2598
3438
  ],
2599
3439
  init: () => {
2600
- if (globalThis.window !== void 0) {
2601
- const w = window;
2602
- w._hjSettings = { hjid: config.siteId, hjsv: v };
3440
+ const currentWindow = globalThis.window;
3441
+ if (currentWindow !== void 0) {
3442
+ const w = currentWindow;
3443
+ w._hjSettings = { hjid: siteId, hjsv: v };
2603
3444
  if (!w.hj) {
2604
3445
  const hj = (...args) => {
2605
3446
  hj.q = hj.q || [];
@@ -2608,17 +3449,35 @@ function createHotjarIntegration(config) {
2608
3449
  w.hj = hj;
2609
3450
  }
2610
3451
  if (config.debug && typeof console !== "undefined" && typeof console.info === "function") {
2611
- console.info("[Hotjar] initialized with siteId", config.siteId);
3452
+ console.info("[Hotjar] initialized with siteId", siteId);
2612
3453
  }
2613
3454
  }
2614
3455
  }
2615
3456
  };
2616
3457
  }
2617
3458
  function createMixpanelIntegration(config) {
3459
+ const category = resolveCategory("analytics", config.category);
3460
+ const token = resolveRequiredString(config.token, "token", "mixpanel");
3461
+ if (!token) {
3462
+ return {
3463
+ id: "mixpanel",
3464
+ category,
3465
+ src: "",
3466
+ cookies: ["mp_*"],
3467
+ cookiesInfo: [
3468
+ {
3469
+ name: "mp_*",
3470
+ purpose: "Rastreamento de eventos e propriedades do usu\xE1rio para analytics",
3471
+ duration: "1 ano",
3472
+ provider: "Mixpanel"
3473
+ }
3474
+ ]
3475
+ };
3476
+ }
2618
3477
  const src = config.scriptUrl ?? "https://cdn.mxpnl.com/libs/mixpanel-2-latest.min.js";
2619
3478
  return {
2620
3479
  id: "mixpanel",
2621
- category: "analytics",
3480
+ category,
2622
3481
  src,
2623
3482
  cookies: ["mp_*"],
2624
3483
  cookiesInfo: [
@@ -2630,12 +3489,13 @@ function createMixpanelIntegration(config) {
2630
3489
  }
2631
3490
  ],
2632
3491
  init: () => {
2633
- if (globalThis.window !== void 0) {
2634
- const w = window;
3492
+ const currentWindow = globalThis.window;
3493
+ if (currentWindow !== void 0) {
3494
+ const w = currentWindow;
2635
3495
  w.mixpanel = w.mixpanel || { init: () => void 0 };
2636
3496
  if (w.mixpanel && typeof w.mixpanel.init === "function") {
2637
3497
  try {
2638
- w.mixpanel.init(config.token, config.config ?? {}, config.api_host);
3498
+ w.mixpanel.init(token, config.config ?? {}, config.api_host);
2639
3499
  } catch (error) {
2640
3500
  if (typeof console !== "undefined" && typeof console.warn === "function") {
2641
3501
  console.warn("[Mixpanel] Failed to initialize:", error);
@@ -2647,15 +3507,26 @@ function createMixpanelIntegration(config) {
2647
3507
  };
2648
3508
  }
2649
3509
  function createClarityIntegration(config) {
2650
- const src = config.scriptUrl ?? `https://www.clarity.ms/tag/${config.projectId}`;
3510
+ const category = resolveCategory("analytics", config.category);
3511
+ const projectId = resolveRequiredString(config.projectId, "projectId", "clarity");
3512
+ if (!projectId) {
3513
+ return {
3514
+ id: "clarity",
3515
+ category,
3516
+ src: "",
3517
+ cookies: ["_clck", "_clsk", "CLID", "ANONCHK", "MR", "MUID", "SM"]
3518
+ };
3519
+ }
3520
+ const src = config.scriptUrl ?? `https://www.clarity.ms/tag/${projectId}`;
2651
3521
  return {
2652
3522
  id: "clarity",
2653
- category: "analytics",
3523
+ category,
2654
3524
  src,
2655
3525
  cookies: ["_clck", "_clsk", "CLID", "ANONCHK", "MR", "MUID", "SM"],
2656
3526
  init: () => {
2657
- if (globalThis.window !== void 0 && typeof config.upload !== "undefined") {
2658
- const w = window;
3527
+ const currentWindow = globalThis.window;
3528
+ if (currentWindow !== void 0 && typeof config.upload !== "undefined") {
3529
+ const w = currentWindow;
2659
3530
  if (typeof w.clarity === "function") {
2660
3531
  try {
2661
3532
  w.clarity("set", "upload", config.upload);
@@ -2670,18 +3541,29 @@ function createClarityIntegration(config) {
2670
3541
  };
2671
3542
  }
2672
3543
  function createIntercomIntegration(config) {
2673
- const src = config.scriptUrl ?? `https://widget.intercom.io/widget/${config.app_id}`;
3544
+ const category = resolveCategory("functional", config.category);
3545
+ const appId = resolveRequiredString(config.app_id, "app_id", "intercom");
3546
+ if (!appId) {
3547
+ return {
3548
+ id: "intercom",
3549
+ category,
3550
+ src: "",
3551
+ cookies: ["intercom-id-*", "intercom-session-*"]
3552
+ };
3553
+ }
3554
+ const src = config.scriptUrl ?? `https://widget.intercom.io/widget/${appId}`;
2674
3555
  return {
2675
3556
  id: "intercom",
2676
- category: "functional",
3557
+ category,
2677
3558
  src,
2678
3559
  cookies: ["intercom-id-*", "intercom-session-*"],
2679
3560
  init: () => {
2680
- if (globalThis.window !== void 0) {
2681
- const w = window;
3561
+ const currentWindow = globalThis.window;
3562
+ if (currentWindow !== void 0) {
3563
+ const w = currentWindow;
2682
3564
  if (typeof w.Intercom === "function") {
2683
3565
  try {
2684
- w.Intercom("boot", { app_id: config.app_id });
3566
+ w.Intercom("boot", { app_id: appId });
2685
3567
  } catch (error) {
2686
3568
  if (typeof console !== "undefined" && typeof console.warn === "function") {
2687
3569
  console.warn("[Intercom] Failed to boot:", error);
@@ -2693,18 +3575,29 @@ function createIntercomIntegration(config) {
2693
3575
  };
2694
3576
  }
2695
3577
  function createZendeskChatIntegration(config) {
2696
- const src = config.scriptUrl ?? `https://static.zdassets.com/ekr/snippet.js?key=${config.key}`;
3578
+ const category = resolveCategory("functional", config.category);
3579
+ const key = resolveRequiredString(config.key, "key", "zendesk-chat");
3580
+ if (!key) {
3581
+ return {
3582
+ id: "zendesk-chat",
3583
+ category,
3584
+ src: "",
3585
+ cookies: ["__zlcmid", "_zendesk_shared_session"]
3586
+ };
3587
+ }
3588
+ const src = config.scriptUrl ?? `https://static.zdassets.com/ekr/snippet.js?key=${key}`;
2697
3589
  return {
2698
3590
  id: "zendesk-chat",
2699
- category: "functional",
3591
+ category,
2700
3592
  src,
2701
3593
  cookies: ["__zlcmid", "_zendesk_shared_session"],
2702
3594
  init: () => {
2703
- if (globalThis.window !== void 0) {
2704
- const w = window;
3595
+ const currentWindow = globalThis.window;
3596
+ if (currentWindow !== void 0) {
3597
+ const w = currentWindow;
2705
3598
  if (typeof w.zE === "function") {
2706
3599
  try {
2707
- w.zE("webWidget", "identify", { key: config.key });
3600
+ w.zE("webWidget", "identify", { key });
2708
3601
  } catch (error) {
2709
3602
  if (typeof console !== "undefined" && typeof console.warn === "function") {
2710
3603
  console.warn("[Zendesk] Failed to identify:", error);
@@ -2826,217 +3719,6 @@ function createAnpdCategoriesConfig(options = {}) {
2826
3719
  };
2827
3720
  }
2828
3721
 
2829
- // src/types/advancedTexts.ts
2830
- var EXPANDED_DEFAULT_TEXTS = {
2831
- // Textos adicionais
2832
- confirm: "Confirmar",
2833
- cancel: "Cancelar",
2834
- loading: "Carregando...",
2835
- // Feedback
2836
- feedback: {
2837
- saveSuccess: "Prefer\xEAncias salvas com sucesso!",
2838
- saveError: "Erro ao salvar prefer\xEAncias. Tente novamente.",
2839
- consentUpdated: "Consentimento atualizado.",
2840
- cookiesRejected: "Cookies opcionais rejeitados.",
2841
- settingsReset: "Configura\xE7\xF5es resetadas."
2842
- },
2843
- // Acessibilidade
2844
- accessibility: {
2845
- bannerLabel: "Banner de consentimento de cookies",
2846
- modalLabel: "Modal de prefer\xEAncias de cookies",
2847
- keyboardNavigation: "Use Tab para navegar, Enter para selecionar",
2848
- toggleState: {
2849
- enabled: "Habilitado",
2850
- disabled: "Desabilitado"
2851
- },
2852
- liveRegion: "Regi\xE3o de an\xFAncios din\xE2micos"
2853
- },
2854
- // Categorias
2855
- categories: {
2856
- necessary: {
2857
- name: "Cookies Necess\xE1rios",
2858
- description: "Essenciais para o funcionamento b\xE1sico do site",
2859
- examples: "Sess\xE3o, seguran\xE7a, prefer\xEAncias de idioma"
2860
- },
2861
- analytics: {
2862
- name: "Cookies de Analytics",
2863
- description: "Ajudam a entender como os visitantes usam o site",
2864
- examples: "Google Analytics, contadores de p\xE1gina"
2865
- },
2866
- marketing: {
2867
- name: "Cookies de Marketing",
2868
- description: "Usados para personalizar an\xFAncios e ofertas",
2869
- examples: "Facebook Pixel, Google Ads, remarketing"
2870
- },
2871
- functional: {
2872
- name: "Cookies Funcionais",
2873
- description: "Melhoram a funcionalidade e personaliza\xE7\xE3o",
2874
- examples: "Chat, mapas, v\xEDdeos embarcados"
2875
- },
2876
- performance: {
2877
- name: "Cookies de Performance",
2878
- description: "Coletam informa\xE7\xF5es sobre velocidade e estabilidade",
2879
- examples: "Monitoramento de erro, otimiza\xE7\xE3o de velocidade"
2880
- }
2881
- },
2882
- // Contextos específicos
2883
- contexts: {
2884
- ecommerce: {
2885
- cartAbandonment: "Lembramos dos produtos no seu carrinho",
2886
- personalizedOffers: "Ofertas personalizadas baseadas no seu hist\xF3rico",
2887
- paymentSecurity: "Seguran\xE7a adicional no processo de pagamento",
2888
- productRecommendations: "Sugest\xF5es de produtos relevantes"
2889
- },
2890
- saas: {
2891
- userAnalytics: "An\xE1lise de uso para melhorar funcionalidades",
2892
- performanceMonitoring: "Monitoramento de performance da aplica\xE7\xE3o",
2893
- featureUsage: "Estat\xEDsticas de uso de recursos",
2894
- customerSupport: "Suporte ao cliente mais eficiente"
2895
- },
2896
- government: {
2897
- citizenServices: "Melhoria dos servi\xE7os ao cidad\xE3o",
2898
- dataProtection: "Prote\xE7\xE3o rigorosa dos dados pessoais",
2899
- transparency: "Transpar\xEAncia no uso de dados",
2900
- accessibility: "Recursos de acessibilidade digital"
2901
- },
2902
- education: {
2903
- studentProgress: "Acompanhamento do progresso educacional",
2904
- learningAnalytics: "Analytics para melhorar o aprendizado",
2905
- accessibility: "Recursos educacionais acess\xEDveis",
2906
- parentalConsent: "Consentimento parental quando necess\xE1rio"
2907
- }
2908
- },
2909
- // Variações de tom
2910
- variants: {
2911
- formal: {
2912
- bannerMessage: "Este s\xEDtio eletr\xF4nico utiliza cookies para otimizar a experi\xEAncia de navega\xE7\xE3o.",
2913
- acceptAll: "Concordar com todos os cookies",
2914
- declineAll: "Recusar cookies opcionais",
2915
- modalTitle: "Configura\xE7\xE3o de Cookies"
2916
- },
2917
- casual: {
2918
- bannerMessage: "\u{1F36A} Ei! Usamos cookies para tornar sua experi\xEAncia ainda melhor!",
2919
- acceptAll: "Aceitar tudo",
2920
- declineAll: "S\xF3 o essencial",
2921
- modalTitle: "Seus Cookies"
2922
- },
2923
- concise: {
2924
- bannerMessage: "Usamos cookies. Voc\xEA aceita?",
2925
- acceptAll: "Sim",
2926
- declineAll: "N\xE3o",
2927
- modalTitle: "Cookies"
2928
- },
2929
- detailed: {
2930
- 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.",
2931
- acceptAll: "Aceitar todos os cookies e tecnologias",
2932
- declineAll: "Recusar todos os cookies opcionais",
2933
- modalTitle: "Centro de Prefer\xEAncias de Privacidade"
2934
- }
2935
- },
2936
- // Internacionalização simplificada (apenas textos básicos)
2937
- i18n: {
2938
- en: {
2939
- bannerMessage: "We use cookies to enhance your experience.",
2940
- acceptAll: "Accept All",
2941
- declineAll: "Decline",
2942
- preferences: "Preferences",
2943
- modalTitle: "Cookie Preferences",
2944
- modalIntro: "Customize your cookie preferences below.",
2945
- save: "Save Preferences",
2946
- necessaryAlwaysOn: "Necessary cookies (always active)"
2947
- },
2948
- es: {
2949
- bannerMessage: "Utilizamos cookies para mejorar su experiencia.",
2950
- acceptAll: "Aceptar Todo",
2951
- declineAll: "Rechazar",
2952
- preferences: "Preferencias",
2953
- modalTitle: "Preferencias de Cookies",
2954
- modalIntro: "Personalice sus preferencias de cookies a continuaci\xF3n.",
2955
- save: "Guardar Preferencias",
2956
- necessaryAlwaysOn: "Cookies necess\xE1rias (sempre ativas)"
2957
- },
2958
- fr: {
2959
- bannerMessage: "Nous utilisons des cookies pour am\xE9liorer votre exp\xE9rience.",
2960
- acceptAll: "Tout Accepter",
2961
- declineAll: "Refuser",
2962
- preferences: "Pr\xE9f\xE9rences",
2963
- modalTitle: "Pr\xE9f\xE9rences des Cookies",
2964
- modalIntro: "Personnalisez vos pr\xE9f\xE9rences de cookies ci-dessous.",
2965
- save: "Enregistrer les Pr\xE9f\xE9rences",
2966
- necessaryAlwaysOn: "Cookies n\xE9cessaires (toujours actifs)"
2967
- }
2968
- },
2969
- // Textos técnicos
2970
- technical: {
2971
- sessionCookies: "Cookies de sess\xE3o s\xE3o tempor\xE1rios e expiram quando voc\xEA fecha o navegador.",
2972
- persistentCookies: "Cookies persistentes permanecem no seu dispositivo at\xE9 expirarem ou serem removidos.",
2973
- thirdPartyCookies: "Cookies de terceiros s\xE3o definidos por dom\xEDnios diferentes do site que voc\xEA est\xE1 visitando.",
2974
- browserSettings: "Voc\xEA pode gerenciar cookies nas configura\xE7\xF5es do seu navegador.",
2975
- disablingImpact: "Desabilitar cookies pode afetar a funcionalidade do site."
2976
- },
2977
- // Cookie details
2978
- cookieDetails: {
2979
- tableHeaders: {
2980
- name: "Nome",
2981
- purpose: "Finalidade",
2982
- duration: "Dura\xE7\xE3o",
2983
- provider: "Fornecedor",
2984
- type: "Tipo"
2985
- },
2986
- noCookies: "Nenhum cookie encontrado para esta categoria.",
2987
- toggleDetails: {
2988
- expand: "Ver detalhes",
2989
- collapse: "Ocultar detalhes"
2990
- }
2991
- }
2992
- };
2993
- function resolveTexts(texts, options = {}) {
2994
- const { language = "pt", variant } = options;
2995
- let resolved = { ...texts };
2996
- if (variant && texts.variants?.[variant]) {
2997
- resolved = { ...resolved, ...texts.variants[variant] };
2998
- }
2999
- if (language !== "pt" && texts.i18n?.[language]) {
3000
- resolved = { ...resolved, ...texts.i18n[language] };
3001
- }
3002
- return resolved;
3003
- }
3004
- var TEXT_TEMPLATES = {
3005
- ecommerce: {
3006
- ...EXPANDED_DEFAULT_TEXTS,
3007
- bannerMessage: "Utilizamos cookies para personalizar ofertas e melhorar sua experi\xEAncia de compra.",
3008
- acceptAll: "Aceitar e continuar",
3009
- variants: {
3010
- casual: {
3011
- bannerMessage: "\u{1F6D2} Usamos cookies para encontrar as melhores ofertas para voc\xEA!",
3012
- acceptAll: "Quero ofertas personalizadas!"
3013
- }
3014
- }
3015
- },
3016
- saas: {
3017
- ...EXPANDED_DEFAULT_TEXTS,
3018
- bannerMessage: "Utilizamos cookies para otimizar o desempenho da aplica\xE7\xE3o e sua experi\xEAncia.",
3019
- acceptAll: "Aceitar e otimizar",
3020
- variants: {
3021
- formal: {
3022
- bannerMessage: "Esta aplica\xE7\xE3o utiliza cookies para an\xE1lise de performance e melhoria cont\xEDnua da experi\xEAncia do usu\xE1rio.",
3023
- acceptAll: "Autorizar coleta de dados de uso"
3024
- }
3025
- }
3026
- },
3027
- government: {
3028
- ...EXPANDED_DEFAULT_TEXTS,
3029
- bannerMessage: "Este portal utiliza cookies em conformidade com a LGPD para melhorar os servi\xE7os p\xFAblicos.",
3030
- acceptAll: "Aceitar em conformidade",
3031
- variants: {
3032
- formal: {
3033
- 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.",
3034
- acceptAll: "Concordar com o uso de cookies"
3035
- }
3036
- }
3037
- }
3038
- };
3039
-
3040
3722
  exports.ANPD_CATEGORY_PRESETS = ANPD_CATEGORY_PRESETS;
3041
3723
  exports.COMMON_INTEGRATIONS = COMMON_INTEGRATIONS;
3042
3724
  exports.ConsentGate = ConsentGate;
@@ -3068,6 +3750,7 @@ exports.createIntercomIntegration = createIntercomIntegration;
3068
3750
  exports.createMixpanelIntegration = createMixpanelIntegration;
3069
3751
  exports.createProjectPreferences = createProjectPreferences;
3070
3752
  exports.createSaaSIntegrations = createSaaSIntegrations;
3753
+ exports.createSuggestedIntegration = createSuggestedIntegration;
3071
3754
  exports.createUserWayIntegration = createUserWayIntegration;
3072
3755
  exports.createZendeskChatIntegration = createZendeskChatIntegration;
3073
3756
  exports.defaultTexts = defaultTexts;
@@ -3077,17 +3760,22 @@ exports.ensureNecessaryAlwaysOn = ensureNecessaryAlwaysOn;
3077
3760
  exports.extractCategoriesFromIntegrations = extractCategoriesFromIntegrations;
3078
3761
  exports.getAllProjectCategories = getAllProjectCategories;
3079
3762
  exports.getCookiesInfoForCategory = getCookiesInfoForCategory;
3763
+ exports.getPeerDepsLocale = getPeerDepsLocale;
3080
3764
  exports.loadScript = loadScript;
3081
3765
  exports.logDeveloperGuidance = logDeveloperGuidance;
3082
3766
  exports.logger = logger;
3083
3767
  exports.openPreferencesModal = openPreferencesModal;
3084
3768
  exports.pushConsentInitializedEvent = pushConsentInitializedEvent;
3085
3769
  exports.pushConsentUpdatedEvent = pushConsentUpdatedEvent;
3770
+ exports.registerScript = registerScript;
3771
+ exports.resetPeerDepsMessages = resetPeerDepsMessages;
3086
3772
  exports.resolveTexts = resolveTexts;
3087
3773
  exports.runPeerDepsCheck = runPeerDepsCheck;
3088
3774
  exports.setCookieCatalogOverrides = setCookieCatalogOverrides;
3089
3775
  exports.setCookieCategoryOverrides = setCookieCategoryOverrides;
3090
3776
  exports.setDebugLogging = setDebugLogging;
3777
+ exports.setPeerDepsLocale = setPeerDepsLocale;
3778
+ exports.setPeerDepsMessages = setPeerDepsMessages;
3091
3779
  exports.suggestCategoryForScript = suggestCategoryForScript;
3092
3780
  exports.useCategories = useCategories;
3093
3781
  exports.useCategoryStatus = useCategoryStatus;