-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathutmtrack.min.js
More file actions
4 lines (4 loc) · 21.9 KB
/
utmtrack.min.js
File metadata and controls
4 lines (4 loc) · 21.9 KB
1
2
3
4
/**
* UTMTrackJS - 0.9.5 - MIT - https://github.com/gmasson/utmtrackjs
*/
(e=>{"use strict";if(void 0===e||"undefined"==typeof document)return void console.warn("UTMTrackJS: Esta biblioteca só funciona em ambiente de navegador.");if("undefined"==typeof Storage)return void console.warn("UTMTrackJS: localStorage não está disponível neste navegador.");const t=Object.freeze({STORAGE_KEY:"utmtrackjs_last_params",VERSION:"0.9.5",MAX_UTM_LENGTH:500,MAX_KEY_LENGTH:50,MAX_KEYS:50,MAX_PARAMS:50,MAX_STORAGE_SIZE:5e4,MAX_URL_LENGTH:2048,DEFAULT_MAX_DATA_AGE:6048e5,THROTTLE_DELAY:50,ALLOWED_EVENTS:["input","change","focus","blur"],ALLOWED_INPUT_TYPES:["text","hidden","search","url","tel","email"],FORM_ELEMENTS:["input","textarea","select"],CUSTOM_EVENTS:{UTM_CAPTURED:"utmtrackjs:captured",UTM_UPDATED:"utmtrackjs:updated",UTM_REMOVED:"utmtrackjs:removed",CONFIG_CHANGED:"utmtrackjs:configChanged"}}),r=Object.freeze(["utm_source","utm_medium","utm_campaign","utm_term","utm_content","utm_id","utm_source_platform","utm_creative_format","utm_marketing_tactic","gclid","fbclid","msclkid","ttclid","twclid","li_fat_id","sc_campaign","sc_channel","sc_content","sc_medium","sc_outcome","mc_cid","mc_eid","pk_campaign","pk_kwd","pk_medium","pk_source"]),a=(()=>{const e={config:{updateWithLatest:!0,customUtmKeys:null,maxDataAge:t.DEFAULT_MAX_DATA_AGE,loggingEnabled:!0},runtime:{domContentLoadedListenerAdded:!1,urlChangeListenerAdded:!1,lastUrl:"",isInitialized:!1,originalHistory:null,urlListenersBound:!1,eventListeners:new Set}};return Object.seal(e)})();"object"==typeof e.UTMTrackJSConfig&&null!==e.UTMTrackJSConfig&&("boolean"==typeof e.UTMTrackJSConfig.updateWithLatest&&(a.config.updateWithLatest=e.UTMTrackJSConfig.updateWithLatest),"number"!=typeof e.UTMTrackJSConfig.maxDataAge&&!1!==e.UTMTrackJSConfig.maxDataAge||(a.config.maxDataAge=e.UTMTrackJSConfig.maxDataAge),Array.isArray(e.UTMTrackJSConfig.customUtmKeys)&&(a.config.customUtmKeys=e.UTMTrackJSConfig.customUtmKeys));class o extends Error{constructor(e,t="GENERAL"){super(e),this.name="UTMTrackError",this.code=t}}const n={isValidUtmKey(e){if("string"!=typeof e||!e.trim())return!1;const r=e.trim();return!(r.length>t.MAX_KEY_LENGTH)&&/^[a-zA-Z0-9_]+$/.test(r)},sanitizeUtmValue(e){if(null==e)return null;let r=String(e).trim();return r=r.replace(/[^a-zA-Z0-9\-_.\s]/g,""),r=r.replace(/\s+/g," ").trim(),r.length>t.MAX_UTM_LENGTH&&(console.warn(`UTMTrackJS: Valor UTM truncado (máximo: ${t.MAX_UTM_LENGTH} caracteres)`),r=r.substring(0,t.MAX_UTM_LENGTH)),r.length>0?r:null},isValidUtmValue(e){const t=this.sanitizeUtmValue(e);return null!==t&&t.length>0},validateMetadata(t){const r=Date.now(),o=r-31536e7;if("number"!=typeof t._timestamp||isNaN(t._timestamp)||t._timestamp<=0||t._timestamp<o||t._timestamp>r)return console.warn("UTMTrackJS: Timestamp inválido detectado."),!1;if(t._origin&&"string"==typeof t._origin)try{if(new URL(t._origin).origin!==e.location.origin)return console.warn("UTMTrackJS: Origem dos dados não confere. Possível CSRF detectado."),!1}catch(e){return console.warn("UTMTrackJS: Origem inválida nos dados armazenados."),!1}return!(!1!==a.config.maxDataAge&&r-t._timestamp>a.config.maxDataAge)||(console.warn("UTMTrackJS: Dados no localStorage expirados."),!1)},validateStoredData(e){if("object"!=typeof e||null===e||e.constructor!==Object)return console.warn("UTMTrackJS: Estrutura de dados inválida detectada."),!1;if(Object.getPrototypeOf(e)!==Object.prototype)return console.warn("UTMTrackJS: Prototype pollution detectado."),!1;const r=["constructor","__proto__","prototype","valueOf","toString","__defineGetter__","__defineSetter__","__lookupGetter__","__lookupSetter__","hasOwnProperty","isPrototypeOf","propertyIsEnumerable"];for(const t of r)if(e.hasOwnProperty(t)&&!["_timestamp","_data","_origin","_version"].includes(t))return console.warn(`UTMTrackJS: Propriedade perigosa detectada: ${t}`),!1;if("[object Object]"!==Object.prototype.toString.call(e))return console.warn("UTMTrackJS: Objeto suspeito detectado - possível prototype pollution."),!1;if(Object.keys(e).length>t.MAX_KEYS)return console.warn(`UTMTrackJS: Muitas chaves no localStorage (${Object.keys(e).length}, máximo: ${t.MAX_KEYS})`),!1;const a=e._timestamp&&e._data,o=a?e._data:e;if(a&&!this.validateMetadata(e))return!1;if(a&&e._data){if("object"!=typeof e._data||Array.isArray(e._data)||null===e._data)return console.warn("UTMTrackJS: Estrutura de _data inválida."),!1;if(Object.getPrototypeOf(e._data)!==Object.prototype)return console.warn("UTMTrackJS: Prototype pollution detectado nos dados."),!1}for(const[e,r]of Object.entries(o)){if(!this.isValidUtmKey(e)||"string"!=typeof r||r.length>t.MAX_UTM_LENGTH)return console.warn(`UTMTrackJS: Dados inválidos para chave ${e}`),!1;const a=this.sanitizeUtmValue(r);if(!a||a!==r)return console.warn(`UTMTrackJS: Valor comprometido encontrado para chave ${e}`),!1}return!0}},i={info(...e){if(a.config.loggingEnabled)try{console.log(...e)}catch(e){}},warn(...e){if(a.config.loggingEnabled)try{console.warn(...e)}catch(e){}},error(...e){try{console.error(...e)}catch(e){}}},s={_lastSaveTime:0,_saveThrottle:100,_canSave(){const e=Date.now();return!(e-this._lastSaveTime<this._saveThrottle)&&(this._lastSaveTime=e,!0)},getStoredData(){try{const e=localStorage.getItem(t.STORAGE_KEY);if(!e)return null;if("string"!=typeof e||e.length>t.MAX_STORAGE_SIZE)return console.warn("UTMTrackJS: Dados suspeitos no localStorage."),this.cleanup(),null;const r=e.trim().charAt(0),a=e.trim().charAt(e.trim().length-1);if("{"!==r||"}"!==a)return console.warn("UTMTrackJS: Estrutura JSON inválida detectada."),this.cleanup(),null;let o;try{o=JSON.parse(e)}catch(e){return console.warn("UTMTrackJS: Erro ao fazer parse dos dados JSON.",e),this.cleanup(),null}return n.validateStoredData(o)?o._timestamp&&o._data?o._data:o:(console.warn("UTMTrackJS: Dados corrompidos ou inseguros no localStorage. Limpando..."),this.cleanup(),null)}catch(e){return console.error("UTMTrackJS: Erro ao ler do localStorage.",e),this.cleanup(),null}},saveStoredData(r){try{if(!this._canSave())return console.warn("UTMTrackJS: Operação de salvamento muito frequente. Ignorando."),!1;if(!r||"object"!=typeof r||Object.keys(r).length>t.MAX_KEYS)throw new o("Dados inválidos ou muitos dados para salvamento.","INVALID_DATA");const a={_timestamp:Date.now(),_data:r,_origin:e.location.origin,_version:t.VERSION},n=JSON.stringify(a);if(n.length>t.MAX_STORAGE_SIZE)throw new o("Dados muito grandes para salvar no localStorage.","SIZE_LIMIT");return localStorage.setItem(t.STORAGE_KEY,n),!0}catch(e){return console.error("UTMTrackJS: Erro ao salvar no localStorage.",e),!1}},cleanup(){try{localStorage.removeItem(t.STORAGE_KEY)}catch(e){console.error("UTMTrackJS: Erro ao limpar localStorage corrompido.",e)}},getStorageStats(){try{const e=localStorage.getItem(t.STORAGE_KEY);if(!e)return{exists:!1,size:0,sizeInKB:0,percentOfLimit:0};const r=new Blob([e]).size,a=Math.round(r/1024*100)/100;return{exists:!0,size:r,sizeInKB:a,percentOfLimit:Math.round(r/t.MAX_STORAGE_SIZE*100),maxSizeKB:Math.round(t.MAX_STORAGE_SIZE/1024)}}catch(e){return console.error("UTMTrackJS: Erro ao calcular estatísticas de storage.",e),{error:!0}}}},c={getActiveUtmKeys:()=>a.config.customUtmKeys||r,_checkCSPCompliance(){try{new Event("test");return!0}catch(e){return console.warn("UTMTrackJS: CSP pode estar restringindo criação de eventos."),!1}},dispatchSafeEvent(e,r){try{if(!t.ALLOWED_EVENTS.includes(r))return console.warn(`UTMTrackJS: Tipo de evento '${r}' não é permitido.`),!1;if(!this._checkCSPCompliance())return console.warn("UTMTrackJS: CSP restritivo detectado. Pulando criação de evento."),!1;if("function"==typeof Event)e.dispatchEvent(new Event(r,{bubbles:!0}));else{if(!document.createEvent)return console.warn("UTMTrackJS: Não foi possível disparar evento - API de eventos não disponível."),!1;{const t=document.createEvent("HTMLEvents");t.initEvent(r,!0,!1),e.dispatchEvent(t)}}return!0}catch(e){return console.warn("UTMTrackJS: Não foi possível disparar evento:",e),!1}},dispatchCustomEvent(r,a={}){try{if(!Object.values(t.CUSTOM_EVENTS).includes(r))return console.warn(`UTMTrackJS: Tipo de evento customizado '${r}' não é reconhecido.`),!1;if(a&&"object"==typeof a){const e=["constructor","__proto__","prototype"];for(const t of e)a.hasOwnProperty(t)&&(console.warn(`UTMTrackJS: Propriedade perigosa removida do evento: ${t}`),delete a[t]);JSON.stringify(a).length>1e4&&(console.warn("UTMTrackJS: Detail do evento muito grande, limitando..."),a={truncated:!0,originalSize:"too_large"})}const o=new CustomEvent(r,{detail:{timestamp:Date.now(),version:t.VERSION,...a},bubbles:!1,cancelable:!1});return e.dispatchEvent(o),!0}catch(e){return console.warn("UTMTrackJS: Não foi possível disparar evento customizado:",e),!1}},throttle(e,t){let r,a=0;return function(...o){const n=Date.now();n-a>t?(e.apply(this,o),a=n):(clearTimeout(r),r=setTimeout((()=>{e.apply(this,o),a=Date.now()}),t-(n-a)))}}},l={captureAndSave(){try{if("undefined"==typeof URLSearchParams)throw new o("URLSearchParams não está disponível neste navegador.","NO_URL_SEARCH_PARAMS");const r=e.location.href;if(!r||r.length>t.MAX_URL_LENGTH)throw new o("URL inválida ou muito longa.","INVALID_URL");const i=new URLSearchParams(e.location.search),l={};let d=!1,u=0;if(c.getActiveUtmKeys().forEach((e=>{if(u>=t.MAX_PARAMS)console.warn("UTMTrackJS: Muitos parâmetros na URL. Limitando processamento.");else if(i.has(e)){const t=i.get(e);if(t&&"string"==typeof t&&t.length<=1e3){const r=n.sanitizeUtmValue(t);r?(l[e]=r,d=!0,u++):console.warn(`UTMTrackJS: Valor UTM inválido ignorado para ${e}.`)}else console.warn(`UTMTrackJS: Valor UTM muito longo ignorado para ${e}.`)}})),d){const e=s.getStoredData()||{},o=a.config.updateWithLatest?{...e,...l}:0===Object.keys(e).length?l:e;(a.config.updateWithLatest||0===Object.keys(e).length)&&(s.saveStoredData(o),c.dispatchCustomEvent(t.CUSTOM_EVENTS.UTM_CAPTURED,{capturedUtms:l,allUtms:o,url:r}))}}catch(e){console.error("UTMTrackJS: Erro ao capturar ou salvar UTMs.",e)}}},d={populateFromAttributes(){try{document.querySelectorAll("[data-utmtrackjs]").forEach((e=>{try{const t=e.getAttribute("data-utmtrackjs");if(!n.isValidUtmKey(t))return void console.warn("UTMTrackJS: Atributo data-utmtrackjs inválido encontrado:",e);const r=m.getUtm(t);if(!r)return;const a=n.sanitizeUtmValue(r);if(!a)return void console.warn("UTMTrackJS: Valor UTM não é seguro para uso:",r);this.fillElement(e,a)}catch(t){console.warn("UTMTrackJS: Erro ao processar elemento:",e,t)}}))}catch(e){console.error("UTMTrackJS: Erro ao preencher elementos com atributos UTM.",e)}},fillElement(e,r){const a=e.tagName.toLowerCase();if(t.FORM_ELEMENTS.includes(a)){if(!e.disabled&&!e.readOnly){const a=e.type?e.type.toLowerCase():"text";t.ALLOWED_INPUT_TYPES.includes(a)?(e.value=r,c.dispatchSafeEvent(e,"input")):console.warn(`UTMTrackJS: Tipo de input '${a}' não é permitido para preenchimento automático`)}}else e.textContent=r}},u={setup(){if(!a.runtime.urlChangeListenerAdded)try{i.info("UTMTrackJS: Configurando monitoramento de mudanças de URL..."),a.runtime.lastUrl=e.location.href,this.setupHistoryAPIMonitoring(),this.addSafeEventListener("popstate",this.handleUrlChange),this.addSafeEventListener("hashchange",this.handleUrlChange),a.runtime.urlChangeListenerAdded=!0,i.info("UTMTrackJS: Monitoramento de URL configurado com sucesso!")}catch(e){console.error("UTMTrackJS: Erro ao configurar monitoramento de URL.",e)}},addSafeEventListener(t,r){const o=`${t}_${r.name}`;a.runtime.eventListeners.has(o)||(e.addEventListener(t,r),a.runtime.eventListeners.add(o))},removeSafeEventListener(t,r){const o=`${t}_${r.name}`;a.runtime.eventListeners.has(o)&&(e.removeEventListener(t,r),a.runtime.eventListeners.delete(o))},setupHistoryAPIMonitoring(){if(!a.runtime.originalHistory)if("function"==typeof history.pushState&&"function"==typeof history.replaceState){a.runtime.originalHistory={pushState:history.pushState.bind(history),replaceState:history.replaceState.bind(history)};try{let e;const t=function(){clearTimeout(e),e=setTimeout((()=>{try{u.handleUrlChange()}catch(e){console.error("UTMTrackJS: Erro ao processar mudança de histórico:",e)}}),10)},r=(e,r)=>function(...a){try{const r=e.apply(this,a);return t(),r}catch(e){throw console.error(`UTMTrackJS: Erro em ${r}:`,e),e}};history.pushState=r(a.runtime.originalHistory.pushState,"pushState"),history.replaceState=r(a.runtime.originalHistory.replaceState,"replaceState")}catch(e){i.warn("UTMTrackJS: Falha ao envolver History API, restaurando originais.",e),a.runtime.originalHistory=null}}else i.warn("UTMTrackJS: History API não está disponível ou foi comprometida.")},disable(){try{return a.runtime.originalHistory&&("function"==typeof a.runtime.originalHistory.pushState&&(history.pushState=a.runtime.originalHistory.pushState),"function"==typeof a.runtime.originalHistory.replaceState&&(history.replaceState=a.runtime.originalHistory.replaceState),a.runtime.originalHistory=null),this.removeSafeEventListener("popstate",this.handleUrlChange),this.removeSafeEventListener("hashchange",this.handleUrlChange),a.runtime.urlChangeListenerAdded=!1,a.runtime.urlListenersBound=!1,i.info("UTMTrackJS: Monitoramento de URL desativado."),!0}catch(e){return console.error("UTMTrackJS: Erro ao desativar monitoramento de URL.",e),!1}},handleUrlChange:c.throttle((()=>{try{const t=e.location.href;i.info("UTMTrackJS: Detectada mudança de URL de",a.runtime.lastUrl,"para",t),t!==a.runtime.lastUrl&&(a.runtime.lastUrl=t,a.config.updateWithLatest?(i.info("UTMTrackJS: Recapturando UTMs devido à mudança de URL..."),l.captureAndSave(),d.populateFromAttributes(),i.info("UTMTrackJS: UTMs recapturados e elementos atualizados!")):i.info("UTMTrackJS: updateWithLatest está desabilitado, ignorando mudança de URL."))}catch(e){console.error("UTMTrackJS: Erro ao processar mudança de URL.",e)}}),t.THROTTLE_DELAY)},m={getUtm(e){if(!n.isValidUtmKey(e))return console.warn("UTMTrackJS: Chave UTM inválida fornecida para getUtm."),null;const t=s.getStoredData();return t&&t[e]||null},getAllUtms(){const e=s.getStoredData();return e?{...e}:null},removeUtm(e){try{if(void 0===e)return localStorage.removeItem(t.STORAGE_KEY),d.populateFromAttributes(),!0;if(!n.isValidUtmKey(e))return console.warn("UTMTrackJS: Chave UTM inválida fornecida para removeUtm:",e),!1;const r=s.getStoredData();if(!r||!r.hasOwnProperty(e))return!0;const a=r[e];return delete r[e],0===Object.keys(r).length?localStorage.removeItem(t.STORAGE_KEY):s.saveStoredData(r),d.populateFromAttributes(),c.dispatchCustomEvent(t.CUSTOM_EVENTS.UTM_REMOVED,{removedKey:e,removedValue:a,remainingUtms:r}),!0}catch(e){return console.error("UTMTrackJS: Erro ao remover UTM.",e),!1}},setUtm(e,r){try{const a=s.getStoredData()||{};let i={};if("string"==typeof e){if(!n.isValidUtmKey(e)||!n.isValidUtmValue(r))throw new o("Chave ou valor UTM inválido.","INVALID_INPUT");if("object"==typeof r)throw new o("Valor não pode ser objeto ou array.","INVALID_VALUE_TYPE");const t=n.sanitizeUtmValue(r);if(!t)throw new o("Valor inválido após sanitização.","INVALID_VALUE");i[e]=t}else{if("object"!=typeof e||null===e||Array.isArray(e))throw new o("Primeiro parâmetro deve ser uma string ou objeto.","INVALID_PARAMETER_TYPE");for(const[t,r]of Object.entries(e)){if(!n.isValidUtmKey(t)){console.warn(`UTMTrackJS: Ignorando chave inválida ${t}`);continue}if("object"==typeof r){console.warn(`UTMTrackJS: Valor complexo ignorado para chave ${t}`);continue}if(!n.isValidUtmValue(r)){console.warn(`UTMTrackJS: Valor inválido para chave ${t}`);continue}const e=n.sanitizeUtmValue(r);e&&(i[t]=e)}if(0===Object.keys(i).length)throw new o("Nenhuma UTM válida encontrada no objeto fornecido.","NO_VALID_UTMS")}const l={...a,...i};if(Object.keys(l).length>t.MAX_KEYS)throw new o("Quantidade total de chaves excede o limite.","KEY_LIMIT");return s.saveStoredData(l),d.populateFromAttributes(),c.dispatchCustomEvent(t.CUSTOM_EVENTS.UTM_UPDATED,{updatedKeys:Object.keys(i),updatedValues:i,allUtms:l}),!0}catch(e){return console.error("UTMTrackJS: Erro ao definir UTMs.",e),!1}},configure(e){try{if("object"!=typeof e||null===e||Array.isArray(e)||e.constructor!==Object||Object.keys(e).length>10)throw new o("Opções de configuração inválidas.","INVALID_CONFIG");if(e.__proto__!==Object.prototype)throw new o("Prototype pollution detectado nas opções.","PROTOTYPE_POLLUTION");const i=["updateWithLatest","maxDataAge","customUtmKeys","loggingEnabled"],s=Object.keys(e);for(const t of s)i.includes(t)||(console.warn(`UTMTrackJS: Chave de configuração não permitida ignorada: ${t}`),delete e[t]);if(e.hasOwnProperty("updateWithLatest")&&"boolean"==typeof e.updateWithLatest){const t=a.config.updateWithLatest;a.config.updateWithLatest=e.updateWithLatest,a.config.updateWithLatest&&!t&&u.setup(),a.runtime.isInitialized&&d.populateFromAttributes()}if(e.hasOwnProperty("maxDataAge")&&(!1===e.maxDataAge?(a.config.maxDataAge=!1,console.info("UTMTrackJS: Expiração de dados desabilitada.")):"number"==typeof e.maxDataAge&&e.maxDataAge>0&&e.maxDataAge<=31536e6?(a.config.maxDataAge=e.maxDataAge,console.info(`UTMTrackJS: Tempo de expiração definido para ${Math.round(e.maxDataAge/864e5)} dias.`)):console.warn("UTMTrackJS: maxDataAge deve ser um número positivo (em ms) menor que 1 ano ou false.")),e.hasOwnProperty("customUtmKeys"))if(Array.isArray(e.customUtmKeys)){if(e.customUtmKeys.length>100)return console.warn("UTMTrackJS: Muitas chaves personalizadas (máximo: 100)."),!1;const o=e.customUtmKeys.filter((e=>!!n.isValidUtmKey(e)||(console.warn(`UTMTrackJS: Chave UTM personalizada inválida ignorada: ${e}`),!1))),i=[...new Set(o)];if(i.length+r.length>t.MAX_KEYS)return console.warn("UTMTrackJS: Soma de chaves padrão + personalizadas excede limite. Reduza a lista."),!1;a.config.customUtmKeys=i.length>0?i:null}else null===e.customUtmKeys?a.config.customUtmKeys=null:console.warn("UTMTrackJS: customUtmKeys deve ser um array de strings ou null.");return e.hasOwnProperty("loggingEnabled")&&(a.config.loggingEnabled=!!e.loggingEnabled),c.dispatchCustomEvent(t.CUSTOM_EVENTS.CONFIG_CHANGED,{changedOptions:Object.keys(e),newConfig:{updateWithLatest:a.config.updateWithLatest,maxDataAge:a.config.maxDataAge,customUtmKeys:a.config.customUtmKeys,loggingEnabled:a.config.loggingEnabled}}),!0}catch(e){return console.error("UTMTrackJS: Erro ao configurar biblioteca.",e),!1}},addUtmKeys(e){try{const o=Array.isArray(e)?e:[e],i=a.config.customUtmKeys?[...a.config.customUtmKeys]:[...r];let s=0;return o.forEach((e=>{n.isValidUtmKey(e)&&!i.includes(e)?(i.push(e),s++):n.isValidUtmKey(e)||console.warn(`UTMTrackJS: Chave UTM inválida ignorada: ${e}`)})),i.length>t.MAX_KEYS?(console.warn("UTMTrackJS: Limite de chaves excedido. Operação revertida."),!1):s>0&&(a.config.customUtmKeys=i,!0)}catch(e){return console.error("UTMTrackJS: Erro ao adicionar chaves UTM.",e),!1}},removeUtmKeys(e){try{const t=Array.isArray(e)?e:[e],r=c.getActiveUtmKeys(),o=r.filter((e=>!t.includes(e)));return o.length!==r.length&&(a.config.customUtmKeys=o.length>0?o:null,!0)}catch(e){return console.error("UTMTrackJS: Erro ao remover chaves UTM.",e),!1}},getConfig:()=>({updateWithLatest:a.config.updateWithLatest,dataExpirationEnabled:!1!==a.config.maxDataAge,version:t.VERSION,isInitialized:a.runtime.isInitialized,loggingEnabled:a.config.loggingEnabled}),cleanExpiredData(){try{if(!1===a.config.maxDataAge)return!0;const e=localStorage.getItem(t.STORAGE_KEY);if(!e)return!0;const r=JSON.parse(e);if(r._timestamp&&"number"==typeof r._timestamp){const e=Date.now(),o=e-r._timestamp;if(r._timestamp>e||o>a.config.maxDataAge)return localStorage.removeItem(t.STORAGE_KEY),console.info("UTMTrackJS: Dados expirados ou inválidos foram removidos."),!0}return!0}catch(e){return console.error("UTMTrackJS: Erro ao limpar dados expirados.",e),s.cleanup(),!1}},recapture(){try{return l.captureAndSave(),d.populateFromAttributes(),!0}catch(e){return console.error("UTMTrackJS: Erro ao recapturar UTMs.",e),!1}},getDebugInfo(){try{const e=s.getStorageStats(),r=this.getAllUtms(),o=this.getConfig();return{version:t.VERSION,initialized:a.runtime.isInitialized,config:o,storage:e,utms:{count:r?Object.keys(r).length:0,keys:r?Object.keys(r):[],data:r},runtime:{lastUrl:a.runtime.lastUrl,urlMonitoringActive:a.runtime.urlChangeListenerAdded,domListenerAdded:a.runtime.domContentLoadedListenerAdded},limits:{maxKeys:t.MAX_KEYS,maxUtmLength:t.MAX_UTM_LENGTH,maxStorageSize:t.MAX_STORAGE_SIZE},supportedKeys:c.getActiveUtmKeys()}}catch(e){return console.error("UTMTrackJS: Erro ao gerar informações de debug.",e),{error:e.message}}},disableUrlMonitoring:()=>u.disable(),purge(){try{return u.disable(),localStorage.removeItem(t.STORAGE_KEY),a.runtime.isInitialized=!1,a.runtime.lastUrl="",d.populateFromAttributes(),i.info("UTMTrackJS: Purge concluído."),!0}catch(e){return console.error("UTMTrackJS: Erro ao realizar purge.",e),!1}}};({initialize(){if(a.runtime.isInitialized)console.warn("UTMTrackJS: Biblioteca já foi inicializada.");else try{!1!==a.config.maxDataAge&&m.cleanExpiredData();const e=s.getStoredData();!a.config.updateWithLatest&&e&&0!==Object.keys(e).length||l.captureAndSave(),a.config.updateWithLatest&&u.setup(),this.setupAutoPopulation(),a.runtime.isInitialized=!0,i.info("UTMTrackJS: Biblioteca inicializada com sucesso!")}catch(e){console.error("UTMTrackJS: Erro durante a inicialização.",e)}},setupAutoPopulation(){if("loading"===document.readyState){if(!a.runtime.domContentLoadedListenerAdded){const e=()=>{d.populateFromAttributes(),document.removeEventListener("DOMContentLoaded",e)};document.addEventListener("DOMContentLoaded",e),a.runtime.domContentLoadedListenerAdded=!0}}else d.populateFromAttributes()}}).initialize(),e.UTMTrackJS=Object.freeze({getUtm:m.getUtm,setUtm:m.setUtm,getAllUtms:m.getAllUtms,removeUtm:m.removeUtm,configure:m.configure,addUtmKeys:m.addUtmKeys,removeUtmKeys:m.removeUtmKeys,getConfig:m.getConfig,recapture:m.recapture,disableUrlMonitoring:m.disableUrlMonitoring,purge:m.purge,refresh:d.populateFromAttributes,cleanExpiredData:m.cleanExpiredData,getDebugInfo:m.getDebugInfo,getStorageStats:s.getStorageStats,get version(){return t.VERSION},get storageKey(){return t.STORAGE_KEY},get supportedKeys(){return[...r]},get customEvents(){return{...t.CUSTOM_EVENTS}}})})(window);